18b57c86886020cf0a5331823be4789ee558764e2Georgia Kouveli// Copyright 2017, VIXL authors 288c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois// All rights reserved. 388c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois// 488c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois// Redistribution and use in source and binary forms, with or without 588c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois// modification, are permitted provided that the following conditions are met: 688c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois// 788c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois// * Redistributions of source code must retain the above copyright notice, 888c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois// this list of conditions and the following disclaimer. 988c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois// * Redistributions in binary form must reproduce the above copyright notice, 1088c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois// this list of conditions and the following disclaimer in the documentation 1188c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois// and/or other materials provided with the distribution. 1288c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois// * Neither the name of ARM Limited nor the names of its contributors may be 1388c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois// used to endorse or promote products derived from this software without 1488c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois// specific prior written permission. 1588c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois// 1688c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS CONTRIBUTORS "AS IS" AND 1788c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois// ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED 1888c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois// WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE 1988c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois// DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE 2088c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois// FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 2188c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois// DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR 2288c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois// SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER 2388c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois// CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, 2488c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois// OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 2588c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 2688c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois 27d3832965c62a8ad461b9ea9eb0994ca6b0a3da2cAlexandre Rames#ifndef VIXL_AARCH32_INSTRUCTIONS_AARCH32_H_ 28d3832965c62a8ad461b9ea9eb0994ca6b0a3da2cAlexandre Rames#define VIXL_AARCH32_INSTRUCTIONS_AARCH32_H_ 2988c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois 3078973f258039f6e96eba85f1b5ecdb14b3c51dbbPierre Langloisextern "C" { 3188c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois#include <stdint.h> 3278973f258039f6e96eba85f1b5ecdb14b3c51dbbPierre Langlois} 3378973f258039f6e96eba85f1b5ecdb14b3c51dbbPierre Langlois 3488c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois#include <algorithm> 3578973f258039f6e96eba85f1b5ecdb14b3c51dbbPierre Langlois#include <ostream> 3678973f258039f6e96eba85f1b5ecdb14b3c51dbbPierre Langlois 373e1b899f48c1328ac748b1f5fa78f417f7ec6581Vincent Belliard#include "code-buffer-vixl.h" 381bce007699e07bd855b7d194ca93fa5504a73edaPierre Langlois#include "utils-vixl.h" 39d3832965c62a8ad461b9ea9eb0994ca6b0a3da2cAlexandre Rames#include "aarch32/constants-aarch32.h" 4088c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois 4188c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois#ifdef __arm__ 4288c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois#define HARDFLOAT __attribute__((noinline, pcs("aapcs-vfp"))) 4388c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois#else 4488c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois#define HARDFLOAT __attribute__((noinline)) 4588c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois#endif 4688c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois 4788c46b84df005638546de5e4e965bdcc31352f48Pierre Langloisnamespace vixl { 4888c46b84df005638546de5e4e965bdcc31352f48Pierre Langloisnamespace aarch32 { 4988c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois 5088c46b84df005638546de5e4e965bdcc31352f48Pierre Langloisclass Operand; 5188c46b84df005638546de5e4e965bdcc31352f48Pierre Langloisclass SOperand; 5288c46b84df005638546de5e4e965bdcc31352f48Pierre Langloisclass DOperand; 5388c46b84df005638546de5e4e965bdcc31352f48Pierre Langloisclass QOperand; 5488c46b84df005638546de5e4e965bdcc31352f48Pierre Langloisclass MemOperand; 5588c46b84df005638546de5e4e965bdcc31352f48Pierre Langloisclass AlignedMemOperand; 5688c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois 5788c46b84df005638546de5e4e965bdcc31352f48Pierre Langloisenum AddrMode { Offset = 0, PreIndex = 1, PostIndex = 2 }; 5888c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois 5988c46b84df005638546de5e4e965bdcc31352f48Pierre Langloisclass CPURegister { 6088c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois public: 6188c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois enum RegisterType { 6288c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois kNoRegister = 0, 6388c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois kRRegister = 1, 6488c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois kSRegister = 2, 6588c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois kDRegister = 3, 6688c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois kQRegister = 4 6788c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois }; 6888c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois 6988c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois private: 7088c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois static const int kCodeBits = 5; 7188c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois static const int kTypeBits = 4; 7288c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois static const int kSizeBits = 8; 7388c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois static const int kCodeShift = 0; 7488c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois static const int kTypeShift = kCodeShift + kCodeBits; 7588c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois static const int kSizeShift = kTypeShift + kTypeBits; 7688c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois static const uint32_t kCodeMask = ((1 << kCodeBits) - 1) << kCodeShift; 7788c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois static const uint32_t kTypeMask = ((1 << kTypeBits) - 1) << kTypeShift; 7888c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois static const uint32_t kSizeMask = ((1 << kSizeBits) - 1) << kSizeShift; 7988c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois uint32_t value_; 8088c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois 8188c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois public: 8288c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois CPURegister(RegisterType type, uint32_t code, int size) 8388c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois : value_((type << kTypeShift) | (code << kCodeShift) | 8488c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois (size << kSizeShift)) { 8588c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois#ifdef VIXL_DEBUG 8688c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois switch (type) { 8788c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois case kNoRegister: 8888c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois break; 8988c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois case kRRegister: 9088c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois VIXL_ASSERT(code < kNumberOfRegisters); 9188c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois VIXL_ASSERT(size == kRegSizeInBits); 9288c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois break; 9388c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois case kSRegister: 9488c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois VIXL_ASSERT(code < kNumberOfSRegisters); 9588c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois VIXL_ASSERT(size == kSRegSizeInBits); 9688c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois break; 9788c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois case kDRegister: 9888c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois VIXL_ASSERT(code < kMaxNumberOfDRegisters); 9988c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois VIXL_ASSERT(size == kDRegSizeInBits); 10088c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois break; 10188c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois case kQRegister: 10288c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois VIXL_ASSERT(code < kNumberOfQRegisters); 10388c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois VIXL_ASSERT(size == kQRegSizeInBits); 10488c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois break; 10588c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois default: 10688c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois VIXL_UNREACHABLE(); 10788c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois break; 10888c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois } 10988c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois#endif 11088c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois } 11188c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois RegisterType GetType() const { 11288c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois return static_cast<RegisterType>((value_ & kTypeMask) >> kTypeShift); 11388c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois } 114f678618ae35a43dab65455f446c3de324994c204Vincent Belliard bool IsRegister() const { return GetType() == kRRegister; } 115f678618ae35a43dab65455f446c3de324994c204Vincent Belliard bool IsS() const { return GetType() == kSRegister; } 116f678618ae35a43dab65455f446c3de324994c204Vincent Belliard bool IsD() const { return GetType() == kDRegister; } 117f678618ae35a43dab65455f446c3de324994c204Vincent Belliard bool IsQ() const { return GetType() == kQRegister; } 118f678618ae35a43dab65455f446c3de324994c204Vincent Belliard bool IsVRegister() const { return IsS() || IsD() || IsQ(); } 119f678618ae35a43dab65455f446c3de324994c204Vincent Belliard bool IsFPRegister() const { return IsS() || IsD(); } 12088c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois uint32_t GetCode() const { return (value_ & kCodeMask) >> kCodeShift; } 12188c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois uint32_t GetReg() const { return value_; } 12288c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois int GetSizeInBits() const { return (value_ & kSizeMask) >> kSizeShift; } 12388c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois int GetRegSizeInBytes() const { 12488c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois return (GetType() == kNoRegister) ? 0 : (GetSizeInBits() / 8); 12588c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois } 12688c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois bool Is64Bits() const { return GetSizeInBits() == 64; } 12788c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois bool Is128Bits() const { return GetSizeInBits() == 128; } 12888c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois bool IsSameFormat(CPURegister reg) { 12988c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois return (value_ & ~kCodeMask) == (reg.value_ & ~kCodeMask); 13088c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois } 13188c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois bool Is(CPURegister ref) const { return GetReg() == ref.GetReg(); } 13288c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois bool IsValid() const { return GetType() != kNoRegister; } 13388c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois}; 13488c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois 13588c46b84df005638546de5e4e965bdcc31352f48Pierre Langloisclass Register : public CPURegister { 13688c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois public: 13788c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois Register() : CPURegister(kNoRegister, 0, kRegSizeInBits) {} 13888c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois explicit Register(uint32_t code) 13988c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois : CPURegister(kRRegister, code % kNumberOfRegisters, kRegSizeInBits) { 14088c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois VIXL_ASSERT(GetCode() < kNumberOfRegisters); 14188c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois } 14288c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois bool Is(Register ref) const { return GetCode() == ref.GetCode(); } 14388c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois bool IsLow() const { return GetCode() < kNumberOfT32LowRegisters; } 14488c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois bool IsLR() const { return GetCode() == kLrCode; } 14588c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois bool IsPC() const { return GetCode() == kPcCode; } 14688c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois bool IsSP() const { return GetCode() == kSpCode; } 14788c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois}; 14888c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois 14988c46b84df005638546de5e4e965bdcc31352f48Pierre Langloisstd::ostream& operator<<(std::ostream& os, const Register reg); 15088c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois 151adbb4a746d2d90dd2920a8e0b7cd2397e93d17b9Vincent Belliardclass RegisterOrAPSR_nzcv { 152adbb4a746d2d90dd2920a8e0b7cd2397e93d17b9Vincent Belliard uint32_t code_; 153adbb4a746d2d90dd2920a8e0b7cd2397e93d17b9Vincent Belliard 15488c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois public: 155adbb4a746d2d90dd2920a8e0b7cd2397e93d17b9Vincent Belliard explicit RegisterOrAPSR_nzcv(uint32_t code) : code_(code) { 156adbb4a746d2d90dd2920a8e0b7cd2397e93d17b9Vincent Belliard VIXL_ASSERT(code_ < kNumberOfRegisters); 157adbb4a746d2d90dd2920a8e0b7cd2397e93d17b9Vincent Belliard } 158adbb4a746d2d90dd2920a8e0b7cd2397e93d17b9Vincent Belliard bool IsAPSR_nzcv() const { return code_ == kPcCode; } 159adbb4a746d2d90dd2920a8e0b7cd2397e93d17b9Vincent Belliard uint32_t GetCode() const { return code_; } 160adbb4a746d2d90dd2920a8e0b7cd2397e93d17b9Vincent Belliard Register AsRegister() const { 161adbb4a746d2d90dd2920a8e0b7cd2397e93d17b9Vincent Belliard VIXL_ASSERT(!IsAPSR_nzcv()); 162adbb4a746d2d90dd2920a8e0b7cd2397e93d17b9Vincent Belliard return Register(code_); 163adbb4a746d2d90dd2920a8e0b7cd2397e93d17b9Vincent Belliard } 16488c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois}; 16588c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois 1665d85018e08776bbf182bcb36edf6fbb764023a5fVincent Belliardconst RegisterOrAPSR_nzcv APSR_nzcv(kPcCode); 1675d85018e08776bbf182bcb36edf6fbb764023a5fVincent Belliard 16888c46b84df005638546de5e4e965bdcc31352f48Pierre Langloisinline std::ostream& operator<<(std::ostream& os, 16988c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois const RegisterOrAPSR_nzcv reg) { 170adbb4a746d2d90dd2920a8e0b7cd2397e93d17b9Vincent Belliard if (reg.IsAPSR_nzcv()) return os << "APSR_nzcv"; 171adbb4a746d2d90dd2920a8e0b7cd2397e93d17b9Vincent Belliard return os << reg.AsRegister(); 17288c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois} 17388c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois 17488c46b84df005638546de5e4e965bdcc31352f48Pierre Langloisclass SRegister; 17588c46b84df005638546de5e4e965bdcc31352f48Pierre Langloisclass DRegister; 17688c46b84df005638546de5e4e965bdcc31352f48Pierre Langloisclass QRegister; 17788c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois 17888c46b84df005638546de5e4e965bdcc31352f48Pierre Langloisclass VRegister : public CPURegister { 17988c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois public: 18088c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois VRegister() : CPURegister(kNoRegister, 0, 0) {} 18188c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois VRegister(RegisterType type, uint32_t code, int size) 18288c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois : CPURegister(type, code, size) {} 18388c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois 18488c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois SRegister S() const; 18588c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois DRegister D() const; 18688c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois QRegister Q() const; 18788c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois}; 18888c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois 18988c46b84df005638546de5e4e965bdcc31352f48Pierre Langloisclass SRegister : public VRegister { 19088c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois public: 19188c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois SRegister() : VRegister(kNoRegister, 0, kSRegSizeInBits) {} 19288c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois explicit SRegister(uint32_t code) 19388c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois : VRegister(kSRegister, code, kSRegSizeInBits) {} 19488c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois uint32_t Encode(int single_bit_field, int four_bit_field_lowest_bit) const { 19588c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois if (four_bit_field_lowest_bit == 0) { 19688c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois return ((GetCode() & 0x1) << single_bit_field) | 19788c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois ((GetCode() & 0x1e) >> 1); 19888c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois } 19988c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois return ((GetCode() & 0x1) << single_bit_field) | 20088c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois ((GetCode() & 0x1e) << (four_bit_field_lowest_bit - 1)); 20188c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois } 20288c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois}; 20388c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois 20488c46b84df005638546de5e4e965bdcc31352f48Pierre Langloisinline unsigned ExtractSRegister(uint32_t instr, 20588c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois int single_bit_field, 20688c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois int four_bit_field_lowest_bit) { 20788c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois VIXL_ASSERT(single_bit_field > 0); 20888c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois if (four_bit_field_lowest_bit == 0) { 20988c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois return ((instr << 1) & 0x1e) | ((instr >> single_bit_field) & 0x1); 21088c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois } 21188c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois return ((instr >> (four_bit_field_lowest_bit - 1)) & 0x1e) | 21288c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois ((instr >> single_bit_field) & 0x1); 21388c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois} 21488c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois 21588c46b84df005638546de5e4e965bdcc31352f48Pierre Langloisinline std::ostream& operator<<(std::ostream& os, const SRegister reg) { 21688c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois return os << "s" << reg.GetCode(); 21788c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois} 21888c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois 21988c46b84df005638546de5e4e965bdcc31352f48Pierre Langloisclass DRegister : public VRegister { 22088c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois public: 22188c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois DRegister() : VRegister(kNoRegister, 0, kDRegSizeInBits) {} 22288c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois explicit DRegister(uint32_t code) 22388c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois : VRegister(kDRegister, code, kDRegSizeInBits) {} 22497a5640aedb2d193ff27b9e7324a2412ed502a59Vincent Belliard SRegister GetLane(uint32_t lane) const { 22597a5640aedb2d193ff27b9e7324a2412ed502a59Vincent Belliard uint32_t lane_count = kDRegSizeInBits / kSRegSizeInBits; 22697a5640aedb2d193ff27b9e7324a2412ed502a59Vincent Belliard VIXL_ASSERT(lane < lane_count); 22797a5640aedb2d193ff27b9e7324a2412ed502a59Vincent Belliard VIXL_ASSERT(GetCode() * lane_count < kNumberOfSRegisters); 22897a5640aedb2d193ff27b9e7324a2412ed502a59Vincent Belliard return SRegister(GetCode() * lane_count + lane); 22997a5640aedb2d193ff27b9e7324a2412ed502a59Vincent Belliard } 23088c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois uint32_t Encode(int single_bit_field, int four_bit_field_lowest_bit) const { 23188c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois VIXL_ASSERT(single_bit_field >= 4); 23288c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois return ((GetCode() & 0x10) << (single_bit_field - 4)) | 23388c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois ((GetCode() & 0xf) << four_bit_field_lowest_bit); 23488c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois } 23588c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois}; 23688c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois 23788c46b84df005638546de5e4e965bdcc31352f48Pierre Langloisinline unsigned ExtractDRegister(uint32_t instr, 23888c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois int single_bit_field, 23988c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois int four_bit_field_lowest_bit) { 24088c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois VIXL_ASSERT(single_bit_field >= 4); 24188c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois return ((instr >> (single_bit_field - 4)) & 0x10) | 24288c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois ((instr >> four_bit_field_lowest_bit) & 0xf); 24388c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois} 24488c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois 24588c46b84df005638546de5e4e965bdcc31352f48Pierre Langloisinline std::ostream& operator<<(std::ostream& os, const DRegister reg) { 24688c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois return os << "d" << reg.GetCode(); 24788c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois} 24888c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois 24988c46b84df005638546de5e4e965bdcc31352f48Pierre Langloisenum DataTypeType { 25088c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois kDataTypeS = 0x100, 25188c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois kDataTypeU = 0x200, 25288c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois kDataTypeF = 0x300, 25388c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois kDataTypeI = 0x400, 25488c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois kDataTypeP = 0x500, 25588c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois kDataTypeUntyped = 0x600 25688c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois}; 25788c46b84df005638546de5e4e965bdcc31352f48Pierre Langloisconst int kDataTypeSizeMask = 0x0ff; 25888c46b84df005638546de5e4e965bdcc31352f48Pierre Langloisconst int kDataTypeTypeMask = 0x100; 25988c46b84df005638546de5e4e965bdcc31352f48Pierre Langloisenum DataTypeValue { 26088c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois kDataTypeValueInvalid = 0x000, 26188c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois kDataTypeValueNone = 0x001, // value used when dt is ignored. 26288c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois S8 = kDataTypeS | 8, 26388c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois S16 = kDataTypeS | 16, 26488c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois S32 = kDataTypeS | 32, 26588c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois S64 = kDataTypeS | 64, 26688c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois U8 = kDataTypeU | 8, 26788c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois U16 = kDataTypeU | 16, 26888c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois U32 = kDataTypeU | 32, 26988c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois U64 = kDataTypeU | 64, 27088c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois F16 = kDataTypeF | 16, 27188c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois F32 = kDataTypeF | 32, 27288c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois F64 = kDataTypeF | 64, 27388c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois I8 = kDataTypeI | 8, 27488c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois I16 = kDataTypeI | 16, 27588c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois I32 = kDataTypeI | 32, 27688c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois I64 = kDataTypeI | 64, 27788c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois P8 = kDataTypeP | 8, 27888c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois P64 = kDataTypeP | 64, 27988c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois Untyped8 = kDataTypeUntyped | 8, 28088c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois Untyped16 = kDataTypeUntyped | 16, 28188c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois Untyped32 = kDataTypeUntyped | 32, 28288c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois Untyped64 = kDataTypeUntyped | 64 28388c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois}; 28488c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois 28588c46b84df005638546de5e4e965bdcc31352f48Pierre Langloisclass DataType { 28688c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois DataTypeValue value_; 28788c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois 28888c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois public: 2890cec43d2696e745b8c031930dec336db5c58ac52Pierre Langlois explicit DataType(uint32_t size) 29088c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois : value_(static_cast<DataTypeValue>(kDataTypeUntyped | size)) { 29188c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois VIXL_ASSERT((size == 8) || (size == 16) || (size == 32) || (size == 64)); 29288c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois } 2930cec43d2696e745b8c031930dec336db5c58ac52Pierre Langlois // Users should be able to use "S8", "S6" and so forth to instantiate this 2940cec43d2696e745b8c031930dec336db5c58ac52Pierre Langlois // class. 2950cec43d2696e745b8c031930dec336db5c58ac52Pierre Langlois DataType(DataTypeValue value) : value_(value) {} // NOLINT(runtime/explicit) 29688c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois DataTypeValue GetValue() const { return value_; } 29788c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois DataTypeType GetType() const { 29888c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois return static_cast<DataTypeType>(value_ & kDataTypeTypeMask); 29988c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois } 30088c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois uint32_t GetSize() const { return value_ & kDataTypeSizeMask; } 30188c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois bool IsSize(uint32_t size) const { 30288c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois return (value_ & kDataTypeSizeMask) == size; 30388c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois } 30488c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois const char* GetName() const; 3058be27ed0d22c239a0608ab5c7fad5c61a9fec17fVincent Belliard bool Is(DataType type) const { return value_ == type.value_; } 30688c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois bool Is(DataTypeValue value) const { return value_ == value; } 30788c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois bool Is(DataTypeType type) const { return GetType() == type; } 30888c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois bool IsNoneOr(DataTypeValue value) const { 30988c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois return (value_ == value) || (value_ == kDataTypeValueNone); 31088c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois } 31188c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois bool Is(DataTypeType type, uint32_t size) const { 31288c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois return value_ == static_cast<DataTypeValue>(type | size); 31388c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois } 31488c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois bool IsNoneOr(DataTypeType type, uint32_t size) const { 31588c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois return Is(type, size) || Is(kDataTypeValueNone); 31688c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois } 31788c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois}; 31888c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois 31988c46b84df005638546de5e4e965bdcc31352f48Pierre Langloisinline std::ostream& operator<<(std::ostream& os, DataType dt) { 32088c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois return os << dt.GetName(); 32188c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois} 32288c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois 32388c46b84df005638546de5e4e965bdcc31352f48Pierre Langloisclass DRegisterLane : public DRegister { 32488c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois uint32_t lane_; 32588c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois 32688c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois public: 32788c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois DRegisterLane(DRegister reg, uint32_t lane) 32888c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois : DRegister(reg.GetCode()), lane_(lane) {} 32988c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois DRegisterLane(uint32_t code, uint32_t lane) : DRegister(code), lane_(lane) {} 33088c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois uint32_t GetLane() const { return lane_; } 33188c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois uint32_t EncodeX(DataType dt, 33288c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois int single_bit_field, 33388c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois int four_bit_field_lowest_bit) const { 33488c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois VIXL_ASSERT(single_bit_field >= 4); 33588c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois uint32_t value = lane_ << ((dt.GetSize() == 16) ? 3 : 4) | GetCode(); 33688c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois return ((value & 0x10) << (single_bit_field - 4)) | 33788c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois ((value & 0xf) << four_bit_field_lowest_bit); 33888c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois } 33988c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois}; 34088c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois 34188c46b84df005638546de5e4e965bdcc31352f48Pierre Langloisinline unsigned ExtractDRegisterAndLane(uint32_t instr, 34288c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois DataType dt, 34388c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois int single_bit_field, 34488c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois int four_bit_field_lowest_bit, 34588c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois int* lane) { 34688c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois VIXL_ASSERT(single_bit_field >= 4); 34788c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois uint32_t value = ((instr >> (single_bit_field - 4)) & 0x10) | 34888c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois ((instr >> four_bit_field_lowest_bit) & 0xf); 34988c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois if (dt.GetSize() == 16) { 35088c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois *lane = value >> 3; 35188c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois return value & 0x7; 35288c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois } 35388c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois *lane = value >> 4; 35488c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois return value & 0xf; 35588c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois} 35688c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois 35788c46b84df005638546de5e4e965bdcc31352f48Pierre Langloisinline std::ostream& operator<<(std::ostream& os, const DRegisterLane lane) { 35888c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois os << "d" << lane.GetCode() << "["; 35988c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois if (lane.GetLane() == static_cast<uint32_t>(-1)) return os << "??]"; 36088c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois return os << lane.GetLane() << "]"; 36188c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois} 36288c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois 36388c46b84df005638546de5e4e965bdcc31352f48Pierre Langloisclass QRegister : public VRegister { 36488c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois public: 36588c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois QRegister() : VRegister(kNoRegister, 0, kQRegSizeInBits) {} 36688c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois explicit QRegister(uint32_t code) 36788c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois : VRegister(kQRegister, code, kQRegSizeInBits) {} 36888c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois uint32_t Encode(int offset) { return GetCode() << offset; } 36997a5640aedb2d193ff27b9e7324a2412ed502a59Vincent Belliard DRegister GetDLane(uint32_t lane) const { 37097a5640aedb2d193ff27b9e7324a2412ed502a59Vincent Belliard uint32_t lane_count = kQRegSizeInBits / kDRegSizeInBits; 37197a5640aedb2d193ff27b9e7324a2412ed502a59Vincent Belliard VIXL_ASSERT(lane < lane_count); 37297a5640aedb2d193ff27b9e7324a2412ed502a59Vincent Belliard return DRegister(GetCode() * lane_count + lane); 37397a5640aedb2d193ff27b9e7324a2412ed502a59Vincent Belliard } 37488c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois DRegister GetLowDRegister() const { return DRegister(GetCode() * 2); } 37588c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois DRegister GetHighDRegister() const { return DRegister(1 + GetCode() * 2); } 37697a5640aedb2d193ff27b9e7324a2412ed502a59Vincent Belliard SRegister GetSLane(uint32_t lane) const { 37797a5640aedb2d193ff27b9e7324a2412ed502a59Vincent Belliard uint32_t lane_count = kQRegSizeInBits / kSRegSizeInBits; 37897a5640aedb2d193ff27b9e7324a2412ed502a59Vincent Belliard VIXL_ASSERT(lane < lane_count); 37997a5640aedb2d193ff27b9e7324a2412ed502a59Vincent Belliard VIXL_ASSERT(GetCode() * lane_count < kNumberOfSRegisters); 38097a5640aedb2d193ff27b9e7324a2412ed502a59Vincent Belliard return SRegister(GetCode() * lane_count + lane); 38197a5640aedb2d193ff27b9e7324a2412ed502a59Vincent Belliard } 38288c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois uint32_t Encode(int single_bit_field, int four_bit_field_lowest_bit) { 38388c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois // Encode "code * 2". 38488c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois VIXL_ASSERT(single_bit_field >= 3); 38588c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois return ((GetCode() & 0x8) << (single_bit_field - 3)) | 38688c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois ((GetCode() & 0x7) << (four_bit_field_lowest_bit + 1)); 38788c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois } 38888c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois}; 38988c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois 39088c46b84df005638546de5e4e965bdcc31352f48Pierre Langloisinline unsigned ExtractQRegister(uint32_t instr, 39188c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois int single_bit_field, 39288c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois int four_bit_field_lowest_bit) { 39388c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois VIXL_ASSERT(single_bit_field >= 3); 39488c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois return ((instr >> (single_bit_field - 3)) & 0x8) | 39588c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois ((instr >> (four_bit_field_lowest_bit + 1)) & 0x7); 39688c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois} 39788c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois 39888c46b84df005638546de5e4e965bdcc31352f48Pierre Langloisinline std::ostream& operator<<(std::ostream& os, const QRegister reg) { 39988c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois return os << "q" << reg.GetCode(); 40088c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois} 40188c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois 40288c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois// clang-format off 4031107e04f82d4809214ff6592b3727298dee1fe45Alexandre Rames#define AARCH32_REGISTER_CODE_LIST(R) \ 40488c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois R(0) R(1) R(2) R(3) R(4) R(5) R(6) R(7) \ 40588c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois R(8) R(9) R(10) R(11) R(12) R(13) R(14) R(15) 40688c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois// clang-format on 40788c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois#define DEFINE_REGISTER(N) const Register r##N(N); 4081107e04f82d4809214ff6592b3727298dee1fe45Alexandre RamesAARCH32_REGISTER_CODE_LIST(DEFINE_REGISTER) 40988c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois#undef DEFINE_REGISTER 4101107e04f82d4809214ff6592b3727298dee1fe45Alexandre Rames#undef AARCH32_REGISTER_CODE_LIST 41188c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois 41288c46b84df005638546de5e4e965bdcc31352f48Pierre Langloisenum RegNum { kIPRegNum = 12, kSPRegNum = 13, kLRRegNum = 14, kPCRegNum = 15 }; 41388c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois 41488c46b84df005638546de5e4e965bdcc31352f48Pierre Langloisconst Register ip(kIPRegNum); 41588c46b84df005638546de5e4e965bdcc31352f48Pierre Langloisconst Register sp(kSPRegNum); 41688c46b84df005638546de5e4e965bdcc31352f48Pierre Langloisconst Register pc(kPCRegNum); 41788c46b84df005638546de5e4e965bdcc31352f48Pierre Langloisconst Register lr(kLRRegNum); 41888c46b84df005638546de5e4e965bdcc31352f48Pierre Langloisconst Register NoReg; 41988c46b84df005638546de5e4e965bdcc31352f48Pierre Langloisconst VRegister NoVReg; 42088c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois 42188c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois// clang-format off 42288c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois#define SREGISTER_CODE_LIST(R) \ 42388c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois R(0) R(1) R(2) R(3) R(4) R(5) R(6) R(7) \ 42488c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois R(8) R(9) R(10) R(11) R(12) R(13) R(14) R(15) \ 42588c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois R(16) R(17) R(18) R(19) R(20) R(21) R(22) R(23) \ 42688c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois R(24) R(25) R(26) R(27) R(28) R(29) R(30) R(31) 42788c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois// clang-format on 42888c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois#define DEFINE_REGISTER(N) const SRegister s##N(N); 42988c46b84df005638546de5e4e965bdcc31352f48Pierre LangloisSREGISTER_CODE_LIST(DEFINE_REGISTER) 43088c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois#undef DEFINE_REGISTER 43188c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois#undef SREGISTER_CODE_LIST 43288c46b84df005638546de5e4e965bdcc31352f48Pierre Langloisconst SRegister NoSReg; 43388c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois 43488c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois// clang-format off 43588c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois#define DREGISTER_CODE_LIST(R) \ 43688c46b84df005638546de5e4e965bdcc31352f48Pierre LangloisR(0) R(1) R(2) R(3) R(4) R(5) R(6) R(7) \ 43788c46b84df005638546de5e4e965bdcc31352f48Pierre LangloisR(8) R(9) R(10) R(11) R(12) R(13) R(14) R(15) \ 43888c46b84df005638546de5e4e965bdcc31352f48Pierre LangloisR(16) R(17) R(18) R(19) R(20) R(21) R(22) R(23) \ 43988c46b84df005638546de5e4e965bdcc31352f48Pierre LangloisR(24) R(25) R(26) R(27) R(28) R(29) R(30) R(31) 44088c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois// clang-format on 44188c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois#define DEFINE_REGISTER(N) const DRegister d##N(N); 44288c46b84df005638546de5e4e965bdcc31352f48Pierre LangloisDREGISTER_CODE_LIST(DEFINE_REGISTER) 44388c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois#undef DEFINE_REGISTER 44488c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois#undef DREGISTER_CODE_LIST 44588c46b84df005638546de5e4e965bdcc31352f48Pierre Langloisconst DRegister NoDReg; 44688c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois 44788c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois// clang-format off 44888c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois#define QREGISTER_CODE_LIST(R) \ 44988c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois R(0) R(1) R(2) R(3) R(4) R(5) R(6) R(7) \ 45088c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois R(8) R(9) R(10) R(11) R(12) R(13) R(14) R(15) 45188c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois// clang-format on 45288c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois#define DEFINE_REGISTER(N) const QRegister q##N(N); 45388c46b84df005638546de5e4e965bdcc31352f48Pierre LangloisQREGISTER_CODE_LIST(DEFINE_REGISTER) 45488c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois#undef DEFINE_REGISTER 45588c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois#undef QREGISTER_CODE_LIST 45688c46b84df005638546de5e4e965bdcc31352f48Pierre Langloisconst QRegister NoQReg; 45788c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois 45888c46b84df005638546de5e4e965bdcc31352f48Pierre Langloisclass RegisterList { 45988c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois public: 46088c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois RegisterList() : list_(0) {} 46160241a544be0ebf48347789bf0ec268414364627Vincent Belliard RegisterList(Register reg) // NOLINT(runtime/explicit) 46260241a544be0ebf48347789bf0ec268414364627Vincent Belliard : list_(RegisterToList(reg)) {} 46388c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois RegisterList(Register reg1, Register reg2) 46488c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois : list_(RegisterToList(reg1) | RegisterToList(reg2)) {} 46588c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois RegisterList(Register reg1, Register reg2, Register reg3) 46688c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois : list_(RegisterToList(reg1) | RegisterToList(reg2) | 46788c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois RegisterToList(reg3)) {} 46888c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois RegisterList(Register reg1, Register reg2, Register reg3, Register reg4) 46988c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois : list_(RegisterToList(reg1) | RegisterToList(reg2) | 47088c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois RegisterToList(reg3) | RegisterToList(reg4)) {} 47188c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois explicit RegisterList(uint32_t list) : list_(list) {} 47288c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois uint32_t GetList() const { return list_; } 47388c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois void SetList(uint32_t list) { list_ = list; } 47488c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois bool Includes(const Register& reg) const { 47588c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois return (list_ & RegisterToList(reg)) != 0; 47688c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois } 47788c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois void Combine(const RegisterList& other) { list_ |= other.GetList(); } 47888c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois void Combine(const Register& reg) { list_ |= RegisterToList(reg); } 47988c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois void Remove(const RegisterList& other) { list_ &= ~other.GetList(); } 48088c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois void Remove(const Register& reg) { list_ &= ~RegisterToList(reg); } 48188c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois bool Overlaps(const RegisterList& other) const { 48288c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois return (list_ & other.list_) != 0; 48388c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois } 48488c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois bool IsR0toR7orPC() const { 48588c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois // True if all the registers from the list are not from r8-r14. 48688c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois return (list_ & 0x7f00) == 0; 48788c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois } 48888c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois bool IsR0toR7orLR() const { 48988c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois // True if all the registers from the list are not from r8-r13 nor from r15. 49088c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois return (list_ & 0xbf00) == 0; 49188c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois } 49288c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois Register GetFirstAvailableRegister() const; 49388c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois bool IsEmpty() const { return list_ == 0; } 49488c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois static RegisterList Union(const RegisterList& list_1, 49588c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois const RegisterList& list_2) { 49688c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois return RegisterList(list_1.list_ | list_2.list_); 49788c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois } 49888c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois static RegisterList Union(const RegisterList& list_1, 49988c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois const RegisterList& list_2, 50088c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois const RegisterList& list_3) { 50188c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois return Union(list_1, Union(list_2, list_3)); 50288c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois } 50388c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois static RegisterList Union(const RegisterList& list_1, 50488c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois const RegisterList& list_2, 50588c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois const RegisterList& list_3, 50688c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois const RegisterList& list_4) { 50788c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois return Union(Union(list_1, list_2), Union(list_3, list_4)); 50888c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois } 50988c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois static RegisterList Intersection(const RegisterList& list_1, 51088c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois const RegisterList& list_2) { 51188c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois return RegisterList(list_1.list_ & list_2.list_); 51288c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois } 51388c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois static RegisterList Intersection(const RegisterList& list_1, 51488c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois const RegisterList& list_2, 51588c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois const RegisterList& list_3) { 51688c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois return Intersection(list_1, Intersection(list_2, list_3)); 51788c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois } 51888c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois static RegisterList Intersection(const RegisterList& list_1, 51988c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois const RegisterList& list_2, 52088c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois const RegisterList& list_3, 52188c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois const RegisterList& list_4) { 52288c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois return Intersection(Intersection(list_1, list_2), 52388c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois Intersection(list_3, list_4)); 52488c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois } 52588c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois 52688c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois private: 52788c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois static uint32_t RegisterToList(Register reg) { 52888c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois if (reg.GetType() == CPURegister::kNoRegister) { 52988c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois return 0; 53088c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois } else { 53188c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois return UINT32_C(1) << reg.GetCode(); 53288c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois } 53388c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois } 53488c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois 53588c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois // Bitfield representation of all registers in the list 53688c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois // (1 for r0, 2 for r1, 4 for r2, ...). 53788c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois uint32_t list_; 53888c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois}; 53988c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois 54088c46b84df005638546de5e4e965bdcc31352f48Pierre Langloisinline uint32_t GetRegisterListEncoding(const RegisterList& registers, 54188c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois int first, 54288c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois int count) { 54388c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois return (registers.GetList() >> first) & ((1 << count) - 1); 54488c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois} 54588c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois 54688c46b84df005638546de5e4e965bdcc31352f48Pierre Langloisstd::ostream& operator<<(std::ostream& os, RegisterList registers); 54788c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois 54888c46b84df005638546de5e4e965bdcc31352f48Pierre Langloisclass VRegisterList { 54988c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois public: 55088c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois VRegisterList() : list_(0) {} 55188c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois explicit VRegisterList(VRegister reg) : list_(RegisterToList(reg)) {} 55288c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois VRegisterList(VRegister reg1, VRegister reg2) 55388c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois : list_(RegisterToList(reg1) | RegisterToList(reg2)) {} 55488c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois VRegisterList(VRegister reg1, VRegister reg2, VRegister reg3) 55588c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois : list_(RegisterToList(reg1) | RegisterToList(reg2) | 55688c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois RegisterToList(reg3)) {} 55788c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois VRegisterList(VRegister reg1, VRegister reg2, VRegister reg3, VRegister reg4) 55888c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois : list_(RegisterToList(reg1) | RegisterToList(reg2) | 55988c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois RegisterToList(reg3) | RegisterToList(reg4)) {} 56088c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois explicit VRegisterList(uint64_t list) : list_(list) {} 56188c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois uint64_t GetList() const { return list_; } 56288c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois void SetList(uint64_t list) { list_ = list; } 563e6c6319611916b73b227075c7a7c2f76bec50745Jacob Bramley // Because differently-sized V registers overlap with one another, there is no 564e6c6319611916b73b227075c7a7c2f76bec50745Jacob Bramley // way to implement a single 'Includes' function in a way that is unsurprising 565e6c6319611916b73b227075c7a7c2f76bec50745Jacob Bramley // for all existing uses. 566e6c6319611916b73b227075c7a7c2f76bec50745Jacob Bramley bool IncludesAllOf(const VRegister& reg) const { 567e6c6319611916b73b227075c7a7c2f76bec50745Jacob Bramley return (list_ & RegisterToList(reg)) == RegisterToList(reg); 568e6c6319611916b73b227075c7a7c2f76bec50745Jacob Bramley } 569e6c6319611916b73b227075c7a7c2f76bec50745Jacob Bramley bool IncludesAliasOf(const VRegister& reg) const { 57088c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois return (list_ & RegisterToList(reg)) != 0; 57188c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois } 57288c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois void Combine(const VRegisterList& other) { list_ |= other.GetList(); } 57388c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois void Combine(const VRegister& reg) { list_ |= RegisterToList(reg); } 57488c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois void Remove(const VRegisterList& other) { list_ &= ~other.GetList(); } 57588c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois void Remove(const VRegister& reg) { list_ &= ~RegisterToList(reg); } 57688c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois bool Overlaps(const VRegisterList& other) const { 57788c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois return (list_ & other.list_) != 0; 57888c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois } 57988c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois QRegister GetFirstAvailableQRegister() const; 58088c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois DRegister GetFirstAvailableDRegister() const; 58188c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois SRegister GetFirstAvailableSRegister() const; 58288c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois bool IsEmpty() const { return list_ == 0; } 58388c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois static VRegisterList Union(const VRegisterList& list_1, 58488c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois const VRegisterList& list_2) { 58588c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois return VRegisterList(list_1.list_ | list_2.list_); 58688c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois } 58788c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois static VRegisterList Union(const VRegisterList& list_1, 58888c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois const VRegisterList& list_2, 58988c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois const VRegisterList& list_3) { 59088c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois return Union(list_1, Union(list_2, list_3)); 59188c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois } 59288c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois static VRegisterList Union(const VRegisterList& list_1, 59388c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois const VRegisterList& list_2, 59488c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois const VRegisterList& list_3, 59588c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois const VRegisterList& list_4) { 59688c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois return Union(Union(list_1, list_2), Union(list_3, list_4)); 59788c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois } 59888c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois static VRegisterList Intersection(const VRegisterList& list_1, 59988c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois const VRegisterList& list_2) { 60088c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois return VRegisterList(list_1.list_ & list_2.list_); 60188c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois } 60288c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois static VRegisterList Intersection(const VRegisterList& list_1, 60388c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois const VRegisterList& list_2, 60488c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois const VRegisterList& list_3) { 60588c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois return Intersection(list_1, Intersection(list_2, list_3)); 60688c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois } 60788c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois static VRegisterList Intersection(const VRegisterList& list_1, 60888c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois const VRegisterList& list_2, 60988c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois const VRegisterList& list_3, 61088c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois const VRegisterList& list_4) { 61188c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois return Intersection(Intersection(list_1, list_2), 61288c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois Intersection(list_3, list_4)); 61388c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois } 61488c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois 61588c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois private: 61688c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois static uint64_t RegisterToList(VRegister reg) { 61788c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois if (reg.GetType() == CPURegister::kNoRegister) { 61888c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois return 0; 61988c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois } else { 62088c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois switch (reg.GetSizeInBits()) { 62188c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois case kQRegSizeInBits: 62288c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois return UINT64_C(0xf) << (reg.GetCode() * 4); 62388c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois case kDRegSizeInBits: 62488c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois return UINT64_C(0x3) << (reg.GetCode() * 2); 62588c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois case kSRegSizeInBits: 62688c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois return UINT64_C(0x1) << reg.GetCode(); 62788c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois default: 62888c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois VIXL_UNREACHABLE(); 62988c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois return 0; 63088c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois } 63188c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois } 63288c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois } 63388c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois 63488c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois // Bitfield representation of all registers in the list. 63588c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois // (0x3 for d0, 0xc0 for d1, 0x30 for d2, ...). We have one, two or four bits 63688c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois // per register according to their size. This way we can make sure that we 637e6c6319611916b73b227075c7a7c2f76bec50745Jacob Bramley // account for overlapping registers. 638e6c6319611916b73b227075c7a7c2f76bec50745Jacob Bramley // A register is wholly included in this list only if all of its bits are set. 639e6c6319611916b73b227075c7a7c2f76bec50745Jacob Bramley // A register is aliased by the list if at least one of its bits are set. 640e6c6319611916b73b227075c7a7c2f76bec50745Jacob Bramley // The IncludesAllOf and IncludesAliasOf helpers are provided to make this 641e6c6319611916b73b227075c7a7c2f76bec50745Jacob Bramley // distinction clear. 64288c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois uint64_t list_; 64388c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois}; 64488c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois 64588c46b84df005638546de5e4e965bdcc31352f48Pierre Langloisclass SRegisterList { 64671bca307f4e94afdbc753e02c101b042cd218b4aPierre Langlois SRegister first_; 64771bca307f4e94afdbc753e02c101b042cd218b4aPierre Langlois int length_; 64888c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois 64988c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois public: 65071bca307f4e94afdbc753e02c101b042cd218b4aPierre Langlois explicit SRegisterList(SRegister reg) : first_(reg.GetCode()), length_(1) {} 65171bca307f4e94afdbc753e02c101b042cd218b4aPierre Langlois SRegisterList(SRegister first, int length) 65271bca307f4e94afdbc753e02c101b042cd218b4aPierre Langlois : first_(first.GetCode()), length_(length) { 65371bca307f4e94afdbc753e02c101b042cd218b4aPierre Langlois VIXL_ASSERT(length >= 0); 65488c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois } 65529f71f91fc1282d12fd2d5eb87eec8cf0147f043Jacob Bramley SRegister GetSRegister(int n) const { 65629f71f91fc1282d12fd2d5eb87eec8cf0147f043Jacob Bramley VIXL_ASSERT(n >= 0); 65729f71f91fc1282d12fd2d5eb87eec8cf0147f043Jacob Bramley VIXL_ASSERT(n < length_); 65829f71f91fc1282d12fd2d5eb87eec8cf0147f043Jacob Bramley return SRegister((first_.GetCode() + n) % kNumberOfSRegisters); 65971bca307f4e94afdbc753e02c101b042cd218b4aPierre Langlois } 66029f71f91fc1282d12fd2d5eb87eec8cf0147f043Jacob Bramley const SRegister& GetFirstSRegister() const { return first_; } 66129f71f91fc1282d12fd2d5eb87eec8cf0147f043Jacob Bramley SRegister GetLastSRegister() const { return GetSRegister(length_ - 1); } 66271bca307f4e94afdbc753e02c101b042cd218b4aPierre Langlois int GetLength() const { return length_; } 66388c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois}; 66488c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois 66588c46b84df005638546de5e4e965bdcc31352f48Pierre Langloisstd::ostream& operator<<(std::ostream& os, SRegisterList registers); 66688c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois 66788c46b84df005638546de5e4e965bdcc31352f48Pierre Langloisclass DRegisterList { 66871bca307f4e94afdbc753e02c101b042cd218b4aPierre Langlois DRegister first_; 66971bca307f4e94afdbc753e02c101b042cd218b4aPierre Langlois int length_; 67088c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois 67188c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois public: 67271bca307f4e94afdbc753e02c101b042cd218b4aPierre Langlois explicit DRegisterList(DRegister reg) : first_(reg.GetCode()), length_(1) {} 67371bca307f4e94afdbc753e02c101b042cd218b4aPierre Langlois DRegisterList(DRegister first, int length) 67471bca307f4e94afdbc753e02c101b042cd218b4aPierre Langlois : first_(first.GetCode()), length_(length) { 67571bca307f4e94afdbc753e02c101b042cd218b4aPierre Langlois VIXL_ASSERT(length >= 0); 67688c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois } 67729f71f91fc1282d12fd2d5eb87eec8cf0147f043Jacob Bramley DRegister GetDRegister(int n) const { 67829f71f91fc1282d12fd2d5eb87eec8cf0147f043Jacob Bramley VIXL_ASSERT(n >= 0); 67929f71f91fc1282d12fd2d5eb87eec8cf0147f043Jacob Bramley VIXL_ASSERT(n < length_); 68029f71f91fc1282d12fd2d5eb87eec8cf0147f043Jacob Bramley return DRegister((first_.GetCode() + n) % kMaxNumberOfDRegisters); 68171bca307f4e94afdbc753e02c101b042cd218b4aPierre Langlois } 68229f71f91fc1282d12fd2d5eb87eec8cf0147f043Jacob Bramley const DRegister& GetFirstDRegister() const { return first_; } 68329f71f91fc1282d12fd2d5eb87eec8cf0147f043Jacob Bramley DRegister GetLastDRegister() const { return GetDRegister(length_ - 1); } 68471bca307f4e94afdbc753e02c101b042cd218b4aPierre Langlois int GetLength() const { return length_; } 68588c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois}; 68688c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois 68788c46b84df005638546de5e4e965bdcc31352f48Pierre Langloisstd::ostream& operator<<(std::ostream& os, DRegisterList registers); 68888c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois 68988c46b84df005638546de5e4e965bdcc31352f48Pierre Langloisenum SpacingType { kSingle, kDouble }; 69088c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois 69188c46b84df005638546de5e4e965bdcc31352f48Pierre Langloisenum TransferType { kMultipleLanes, kOneLane, kAllLanes }; 69288c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois 69388c46b84df005638546de5e4e965bdcc31352f48Pierre Langloisclass NeonRegisterList { 69429f71f91fc1282d12fd2d5eb87eec8cf0147f043Jacob Bramley DRegister first_; 69588c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois SpacingType spacing_; 69688c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois TransferType type_; 69788c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois int lane_; 69829f71f91fc1282d12fd2d5eb87eec8cf0147f043Jacob Bramley int length_; 69988c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois 70088c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois public: 70188c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois NeonRegisterList(DRegister reg, TransferType type) 70288c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois : first_(reg.GetCode()), 70388c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois spacing_(kSingle), 70488c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois type_(type), 70529f71f91fc1282d12fd2d5eb87eec8cf0147f043Jacob Bramley lane_(-1), 70629f71f91fc1282d12fd2d5eb87eec8cf0147f043Jacob Bramley length_(1) { 70788c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois VIXL_ASSERT(type_ != kOneLane); 70888c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois } 70988c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois NeonRegisterList(DRegister reg, int lane) 71088c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois : first_(reg.GetCode()), 71188c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois spacing_(kSingle), 71288c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois type_(kOneLane), 71329f71f91fc1282d12fd2d5eb87eec8cf0147f043Jacob Bramley lane_(lane), 71429f71f91fc1282d12fd2d5eb87eec8cf0147f043Jacob Bramley length_(1) { 71536fb1cec5777b87c8c6236dc1cdb9941abc58eadVincent Belliard VIXL_ASSERT((lane_ >= 0) && (lane_ < 8)); 71688c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois } 71788c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois NeonRegisterList(DRegister first, 71888c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois DRegister last, 71988c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois SpacingType spacing, 72088c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois TransferType type) 72129f71f91fc1282d12fd2d5eb87eec8cf0147f043Jacob Bramley : first_(first.GetCode()), spacing_(spacing), type_(type), lane_(-1) { 72229f71f91fc1282d12fd2d5eb87eec8cf0147f043Jacob Bramley VIXL_ASSERT(type != kOneLane); 72329f71f91fc1282d12fd2d5eb87eec8cf0147f043Jacob Bramley VIXL_ASSERT(first.GetCode() <= last.GetCode()); 72429f71f91fc1282d12fd2d5eb87eec8cf0147f043Jacob Bramley 72529f71f91fc1282d12fd2d5eb87eec8cf0147f043Jacob Bramley int range = last.GetCode() - first.GetCode(); 72629f71f91fc1282d12fd2d5eb87eec8cf0147f043Jacob Bramley VIXL_ASSERT(IsSingleSpaced() || IsMultiple(range, 2)); 72729f71f91fc1282d12fd2d5eb87eec8cf0147f043Jacob Bramley length_ = (IsDoubleSpaced() ? (range / 2) : range) + 1; 72829f71f91fc1282d12fd2d5eb87eec8cf0147f043Jacob Bramley 72929f71f91fc1282d12fd2d5eb87eec8cf0147f043Jacob Bramley VIXL_ASSERT(length_ <= 4); 73088c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois } 73188c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois NeonRegisterList(DRegister first, 73288c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois DRegister last, 73388c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois SpacingType spacing, 73488c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois int lane) 73588c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois : first_(first.GetCode()), 73688c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois spacing_(spacing), 73788c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois type_(kOneLane), 73888c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois lane_(lane) { 73936fb1cec5777b87c8c6236dc1cdb9941abc58eadVincent Belliard VIXL_ASSERT((lane >= 0) && (lane < 8)); 74029f71f91fc1282d12fd2d5eb87eec8cf0147f043Jacob Bramley VIXL_ASSERT(first.GetCode() <= last.GetCode()); 74129f71f91fc1282d12fd2d5eb87eec8cf0147f043Jacob Bramley 74229f71f91fc1282d12fd2d5eb87eec8cf0147f043Jacob Bramley int range = last.GetCode() - first.GetCode(); 74329f71f91fc1282d12fd2d5eb87eec8cf0147f043Jacob Bramley VIXL_ASSERT(IsSingleSpaced() || IsMultiple(range, 2)); 74429f71f91fc1282d12fd2d5eb87eec8cf0147f043Jacob Bramley length_ = (IsDoubleSpaced() ? (range / 2) : range) + 1; 74529f71f91fc1282d12fd2d5eb87eec8cf0147f043Jacob Bramley 74629f71f91fc1282d12fd2d5eb87eec8cf0147f043Jacob Bramley VIXL_ASSERT(length_ <= 4); 74788c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois } 74829f71f91fc1282d12fd2d5eb87eec8cf0147f043Jacob Bramley DRegister GetDRegister(int n) const { 74929f71f91fc1282d12fd2d5eb87eec8cf0147f043Jacob Bramley VIXL_ASSERT(n >= 0); 75029f71f91fc1282d12fd2d5eb87eec8cf0147f043Jacob Bramley VIXL_ASSERT(n < length_); 75129f71f91fc1282d12fd2d5eb87eec8cf0147f043Jacob Bramley unsigned code = first_.GetCode() + (IsDoubleSpaced() ? (2 * n) : n); 75229f71f91fc1282d12fd2d5eb87eec8cf0147f043Jacob Bramley VIXL_ASSERT(code < kMaxNumberOfDRegisters); 75329f71f91fc1282d12fd2d5eb87eec8cf0147f043Jacob Bramley return DRegister(code); 75488c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois } 75529f71f91fc1282d12fd2d5eb87eec8cf0147f043Jacob Bramley const DRegister& GetFirstDRegister() const { return first_; } 75629f71f91fc1282d12fd2d5eb87eec8cf0147f043Jacob Bramley DRegister GetLastDRegister() const { return GetDRegister(length_ - 1); } 75729f71f91fc1282d12fd2d5eb87eec8cf0147f043Jacob Bramley int GetLength() const { return length_; } 75888c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois bool IsSingleSpaced() const { return spacing_ == kSingle; } 75988c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois bool IsDoubleSpaced() const { return spacing_ == kDouble; } 76088c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois bool IsTransferAllLanes() const { return type_ == kAllLanes; } 76188c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois bool IsTransferOneLane() const { return type_ == kOneLane; } 76288c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois bool IsTransferMultipleLanes() const { return type_ == kMultipleLanes; } 76388c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois int GetTransferLane() const { return lane_; } 76488c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois}; 76588c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois 76688c46b84df005638546de5e4e965bdcc31352f48Pierre Langloisstd::ostream& operator<<(std::ostream& os, NeonRegisterList registers); 76788c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois 76888c46b84df005638546de5e4e965bdcc31352f48Pierre Langloisenum SpecialRegisterType { APSR = 0, CPSR = 0, SPSR = 1 }; 76988c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois 77088c46b84df005638546de5e4e965bdcc31352f48Pierre Langloisclass SpecialRegister { 77188c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois uint32_t reg_; 77288c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois 77388c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois public: 77488c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois explicit SpecialRegister(uint32_t reg) : reg_(reg) {} 77560241a544be0ebf48347789bf0ec268414364627Vincent Belliard SpecialRegister(SpecialRegisterType reg) // NOLINT(runtime/explicit) 77660241a544be0ebf48347789bf0ec268414364627Vincent Belliard : reg_(reg) {} 77788c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois uint32_t GetReg() const { return reg_; } 77888c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois const char* GetName() const; 77988c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois bool Is(SpecialRegister value) const { return reg_ == value.reg_; } 78088c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois bool Is(uint32_t value) const { return reg_ == value; } 78188c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois bool IsNot(uint32_t value) const { return reg_ != value; } 78288c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois}; 78388c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois 78488c46b84df005638546de5e4e965bdcc31352f48Pierre Langloisinline std::ostream& operator<<(std::ostream& os, SpecialRegister reg) { 78588c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois return os << reg.GetName(); 78688c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois} 78788c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois 78888c46b84df005638546de5e4e965bdcc31352f48Pierre Langloisenum BankedRegisterType { 78988c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois R8_usr = 0x00, 79088c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois R9_usr = 0x01, 79188c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois R10_usr = 0x02, 79288c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois R11_usr = 0x03, 79388c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois R12_usr = 0x04, 79488c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois SP_usr = 0x05, 79588c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois LR_usr = 0x06, 79688c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois R8_fiq = 0x08, 79788c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois R9_fiq = 0x09, 79888c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois R10_fiq = 0x0a, 79988c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois R11_fiq = 0x0b, 80088c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois R12_fiq = 0x0c, 80188c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois SP_fiq = 0x0d, 80288c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois LR_fiq = 0x0e, 80388c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois LR_irq = 0x10, 80488c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois SP_irq = 0x11, 80588c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois LR_svc = 0x12, 80688c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois SP_svc = 0x13, 80788c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois LR_abt = 0x14, 80888c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois SP_abt = 0x15, 80988c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois LR_und = 0x16, 81088c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois SP_und = 0x17, 81188c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois LR_mon = 0x1c, 81288c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois SP_mon = 0x1d, 81388c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois ELR_hyp = 0x1e, 81488c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois SP_hyp = 0x1f, 81588c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois SPSR_fiq = 0x2e, 81688c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois SPSR_irq = 0x30, 81788c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois SPSR_svc = 0x32, 81888c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois SPSR_abt = 0x34, 81988c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois SPSR_und = 0x36, 82088c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois SPSR_mon = 0x3c, 82188c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois SPSR_hyp = 0x3e 82288c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois}; 82388c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois 82488c46b84df005638546de5e4e965bdcc31352f48Pierre Langloisclass BankedRegister { 82588c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois uint32_t reg_; 82688c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois 82788c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois public: 82888c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois explicit BankedRegister(unsigned reg) : reg_(reg) {} 82960241a544be0ebf48347789bf0ec268414364627Vincent Belliard BankedRegister(BankedRegisterType reg) // NOLINT(runtime/explicit) 83060241a544be0ebf48347789bf0ec268414364627Vincent Belliard : reg_(reg) {} 83188c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois uint32_t GetCode() const { return reg_; } 83288c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois const char* GetName() const; 83388c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois}; 83488c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois 83588c46b84df005638546de5e4e965bdcc31352f48Pierre Langloisinline std::ostream& operator<<(std::ostream& os, BankedRegister reg) { 83688c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois return os << reg.GetName(); 83788c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois} 83888c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois 83988c46b84df005638546de5e4e965bdcc31352f48Pierre Langloisenum MaskedSpecialRegisterType { 84088c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois APSR_nzcvq = 0x08, 84188c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois APSR_g = 0x04, 84288c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois APSR_nzcvqg = 0x0c, 84388c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois CPSR_c = 0x01, 84488c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois CPSR_x = 0x02, 84588c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois CPSR_xc = 0x03, 84688c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois CPSR_s = APSR_g, 84788c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois CPSR_sc = 0x05, 84888c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois CPSR_sx = 0x06, 84988c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois CPSR_sxc = 0x07, 85088c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois CPSR_f = APSR_nzcvq, 85188c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois CPSR_fc = 0x09, 85288c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois CPSR_fx = 0x0a, 85388c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois CPSR_fxc = 0x0b, 85488c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois CPSR_fs = APSR_nzcvqg, 85588c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois CPSR_fsc = 0x0d, 85688c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois CPSR_fsx = 0x0e, 85788c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois CPSR_fsxc = 0x0f, 85888c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois SPSR_c = 0x11, 85988c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois SPSR_x = 0x12, 86088c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois SPSR_xc = 0x13, 86188c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois SPSR_s = 0x14, 86288c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois SPSR_sc = 0x15, 86388c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois SPSR_sx = 0x16, 86488c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois SPSR_sxc = 0x17, 86588c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois SPSR_f = 0x18, 86688c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois SPSR_fc = 0x19, 86788c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois SPSR_fx = 0x1a, 86888c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois SPSR_fxc = 0x1b, 86988c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois SPSR_fs = 0x1c, 87088c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois SPSR_fsc = 0x1d, 87188c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois SPSR_fsx = 0x1e, 87288c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois SPSR_fsxc = 0x1f 87388c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois}; 87488c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois 87588c46b84df005638546de5e4e965bdcc31352f48Pierre Langloisclass MaskedSpecialRegister { 87688c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois uint32_t reg_; 87788c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois 87888c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois public: 87988c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois explicit MaskedSpecialRegister(uint32_t reg) : reg_(reg) { 88088c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois VIXL_ASSERT(reg <= SPSR_fsxc); 88188c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois } 88260241a544be0ebf48347789bf0ec268414364627Vincent Belliard MaskedSpecialRegister( 88360241a544be0ebf48347789bf0ec268414364627Vincent Belliard MaskedSpecialRegisterType reg) // NOLINT(runtime/explicit) 88488c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois : reg_(reg) {} 88588c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois uint32_t GetReg() const { return reg_; } 88688c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois const char* GetName() const; 88788c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois bool Is(MaskedSpecialRegister value) const { return reg_ == value.reg_; } 88888c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois bool Is(uint32_t value) const { return reg_ == value; } 88988c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois bool IsNot(uint32_t value) const { return reg_ != value; } 89088c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois}; 89188c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois 89288c46b84df005638546de5e4e965bdcc31352f48Pierre Langloisinline std::ostream& operator<<(std::ostream& os, MaskedSpecialRegister reg) { 89388c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois return os << reg.GetName(); 89488c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois} 89588c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois 89688c46b84df005638546de5e4e965bdcc31352f48Pierre Langloisenum SpecialFPRegisterType { 89788c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois FPSID = 0x0, 89888c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois FPSCR = 0x1, 89988c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois MVFR2 = 0x5, 90088c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois MVFR1 = 0x6, 90188c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois MVFR0 = 0x7, 90288c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois FPEXC = 0x8 90388c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois}; 90488c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois 90588c46b84df005638546de5e4e965bdcc31352f48Pierre Langloisclass SpecialFPRegister { 90688c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois uint32_t reg_; 90788c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois 90888c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois public: 90988c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois explicit SpecialFPRegister(uint32_t reg) : reg_(reg) { 91088c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois#ifdef VIXL_DEBUG 91188c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois switch (reg) { 91288c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois case FPSID: 91388c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois case FPSCR: 91488c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois case MVFR2: 91588c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois case MVFR1: 91688c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois case MVFR0: 91788c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois case FPEXC: 91888c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois break; 91988c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois default: 92088c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois VIXL_UNREACHABLE(); 92188c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois } 92288c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois#endif 92388c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois } 92460241a544be0ebf48347789bf0ec268414364627Vincent Belliard SpecialFPRegister(SpecialFPRegisterType reg) // NOLINT(runtime/explicit) 92560241a544be0ebf48347789bf0ec268414364627Vincent Belliard : reg_(reg) {} 92688c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois uint32_t GetReg() const { return reg_; } 92788c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois const char* GetName() const; 92888c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois bool Is(SpecialFPRegister value) const { return reg_ == value.reg_; } 92988c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois bool Is(uint32_t value) const { return reg_ == value; } 93088c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois bool IsNot(uint32_t value) const { return reg_ != value; } 93188c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois}; 93288c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois 93388c46b84df005638546de5e4e965bdcc31352f48Pierre Langloisinline std::ostream& operator<<(std::ostream& os, SpecialFPRegister reg) { 93488c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois return os << reg.GetName(); 93588c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois} 93688c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois 93788c46b84df005638546de5e4e965bdcc31352f48Pierre Langloisclass CRegister { 93888c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois uint32_t code_; 93988c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois 94088c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois public: 94188c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois explicit CRegister(uint32_t code) : code_(code) { 94288c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois VIXL_ASSERT(code < kNumberOfRegisters); 94388c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois } 94488c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois uint32_t GetCode() const { return code_; } 94588c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois bool Is(CRegister value) const { return code_ == value.code_; } 94688c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois}; 94788c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois 94888c46b84df005638546de5e4e965bdcc31352f48Pierre Langloisinline std::ostream& operator<<(std::ostream& os, const CRegister reg) { 94988c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois return os << "c" << reg.GetCode(); 95088c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois} 95188c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois 95288c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois// clang-format off 95388c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois#define CREGISTER_CODE_LIST(R) \ 95488c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois R(0) R(1) R(2) R(3) R(4) R(5) R(6) R(7) \ 95588c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois R(8) R(9) R(10) R(11) R(12) R(13) R(14) R(15) 95688c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois// clang-format on 95788c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois#define DEFINE_CREGISTER(N) const CRegister c##N(N); 95888c46b84df005638546de5e4e965bdcc31352f48Pierre LangloisCREGISTER_CODE_LIST(DEFINE_CREGISTER) 95988c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois 96088c46b84df005638546de5e4e965bdcc31352f48Pierre Langloisenum CoprocessorName { p10 = 10, p11 = 11, p14 = 14, p15 = 15 }; 96188c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois 96288c46b84df005638546de5e4e965bdcc31352f48Pierre Langloisclass Coprocessor { 96388c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois uint32_t coproc_; 96488c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois 96588c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois public: 96688c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois explicit Coprocessor(uint32_t coproc) : coproc_(coproc) {} 96760241a544be0ebf48347789bf0ec268414364627Vincent Belliard Coprocessor(CoprocessorName coproc) // NOLINT(runtime/explicit) 96888c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois : coproc_(static_cast<uint32_t>(coproc)) {} 96988c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois bool Is(Coprocessor coproc) const { return coproc_ == coproc.coproc_; } 97088c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois bool Is(CoprocessorName coproc) const { return coproc_ == coproc; } 97188c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois uint32_t GetCoprocessor() const { return coproc_; } 97288c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois}; 97388c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois 97488c46b84df005638546de5e4e965bdcc31352f48Pierre Langloisinline std::ostream& operator<<(std::ostream& os, Coprocessor coproc) { 97588c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois return os << "p" << coproc.GetCoprocessor(); 97688c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois} 97788c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois 97888c46b84df005638546de5e4e965bdcc31352f48Pierre Langloisenum ConditionType { 97988c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois eq = 0, 98088c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois ne = 1, 98188c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois cs = 2, 98288c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois cc = 3, 98388c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois mi = 4, 98488c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois pl = 5, 98588c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois vs = 6, 98688c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois vc = 7, 98788c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois hi = 8, 98888c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois ls = 9, 98988c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois ge = 10, 99088c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois lt = 11, 99188c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois gt = 12, 99288c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois le = 13, 99388c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois al = 14, 99488c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois hs = cs, 99588c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois lo = cc 99688c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois}; 99788c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois 99888c46b84df005638546de5e4e965bdcc31352f48Pierre Langloisclass Condition { 99988c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois uint32_t condition_; 100088c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois static const uint32_t kNever = 15; 100188c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois static const uint32_t kMask = 0xf; 1002fad350715bbb9f13ea85c84da4e6095dfee3cd15Vincent Belliard static const uint32_t kNone = 0x10 | al; 100388c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois 100488c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois public: 1005fad350715bbb9f13ea85c84da4e6095dfee3cd15Vincent Belliard static const Condition None() { return Condition(kNone); } 10063d39ef94252724f0348bffc86b6c1f98265b4537Vincent Belliard static const Condition Never() { return Condition(kNever); } 100788c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois explicit Condition(uint32_t condition) : condition_(condition) { 100888c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois VIXL_ASSERT(condition <= kNone); 100988c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois } 10100cec43d2696e745b8c031930dec336db5c58ac52Pierre Langlois // Users should be able to use "eq", "ne" and so forth to instantiate this 10110cec43d2696e745b8c031930dec336db5c58ac52Pierre Langlois // class. 101260241a544be0ebf48347789bf0ec268414364627Vincent Belliard Condition(ConditionType condition) // NOLINT(runtime/explicit) 101360241a544be0ebf48347789bf0ec268414364627Vincent Belliard : condition_(condition) {} 101488c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois uint32_t GetCondition() const { return condition_ & kMask; } 101588c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois bool IsNone() const { return condition_ == kNone; } 101688c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois const char* GetName() const; 101788c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois bool Is(Condition value) const { return condition_ == value.condition_; } 101888c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois bool Is(uint32_t value) const { return condition_ == value; } 101988c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois bool IsNot(uint32_t value) const { return condition_ != value; } 102088c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois bool IsNever() const { return condition_ == kNever; } 102188c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois bool IsNotNever() const { return condition_ != kNever; } 102288c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois Condition Negate() const { 102388c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois VIXL_ASSERT(IsNot(al) && IsNot(kNever)); 102488c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois return Condition(condition_ ^ 1); 102588c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois } 102688c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois}; 102788c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois 102888c46b84df005638546de5e4e965bdcc31352f48Pierre Langloisinline std::ostream& operator<<(std::ostream& os, Condition condition) { 102988c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois return os << condition.GetName(); 103088c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois} 103188c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois 103288c46b84df005638546de5e4e965bdcc31352f48Pierre Langloisenum SignType { plus, minus }; 103388c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois 103488c46b84df005638546de5e4e965bdcc31352f48Pierre Langloisclass Sign { 103588c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois public: 103688c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois Sign() : sign_(plus) {} 103760241a544be0ebf48347789bf0ec268414364627Vincent Belliard Sign(SignType sign) : sign_(sign) {} // NOLINT(runtime/explicit) 103888c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois const char* GetName() const { return (IsPlus() ? "" : "-"); } 103988c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois bool IsPlus() const { return sign_ == plus; } 104088c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois bool IsMinus() const { return sign_ == minus; } 104188c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois int32_t ApplyTo(uint32_t value) { return IsPlus() ? value : -value; } 104288c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois 104388c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois private: 104488c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois SignType sign_; 104588c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois}; 104688c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois 104788c46b84df005638546de5e4e965bdcc31352f48Pierre Langloisinline std::ostream& operator<<(std::ostream& os, Sign sign) { 104888c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois return os << sign.GetName(); 104988c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois} 105088c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois 105188c46b84df005638546de5e4e965bdcc31352f48Pierre Langloisenum ShiftType { LSL = 0x0, LSR = 0x1, ASR = 0x2, ROR = 0x3, RRX = 0x4 }; 105288c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois 105388c46b84df005638546de5e4e965bdcc31352f48Pierre Langloisclass Shift { 105488c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois public: 105588c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois Shift() : shift_(LSL) {} 105660241a544be0ebf48347789bf0ec268414364627Vincent Belliard Shift(ShiftType shift) : shift_(shift) {} // NOLINT(runtime/explicit) 105788c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois explicit Shift(uint32_t shift) : shift_(static_cast<ShiftType>(shift)) {} 105888c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois const Shift& GetShift() const { return *this; } 105988c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois ShiftType GetType() const { return shift_; } 106088c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois uint32_t GetValue() const { return shift_; } 106188c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois const char* GetName() const; 106288c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois bool IsLSL() const { return shift_ == LSL; } 106388c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois bool IsLSR() const { return shift_ == LSR; } 106488c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois bool IsASR() const { return shift_ == ASR; } 106588c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois bool IsROR() const { return shift_ == ROR; } 106688c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois bool IsRRX() const { return shift_ == RRX; } 106788c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois bool Is(Shift value) const { return shift_ == value.shift_; } 106888c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois bool IsNot(Shift value) const { return shift_ != value.shift_; } 106988c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois bool IsValidAmount(uint32_t amount) const; 107088c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois static const Shift NoShift; 107188c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois 107288c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois protected: 107388c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois void SetType(ShiftType s) { shift_ = s; } 107488c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois 107588c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois private: 107688c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois ShiftType shift_; 107788c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois}; 107888c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois 107988c46b84df005638546de5e4e965bdcc31352f48Pierre Langloisinline std::ostream& operator<<(std::ostream& os, Shift shift) { 108088c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois return os << shift.GetName(); 108188c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois} 108288c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois 108388c46b84df005638546de5e4e965bdcc31352f48Pierre Langloisclass ImmediateShiftOperand : public Shift { 108488c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois public: 108588c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois // Constructor used for assembly. 108688c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois ImmediateShiftOperand(Shift shift, uint32_t amount) 108788c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois : Shift(shift), amount_(amount) { 108888c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois#ifdef VIXL_DEBUG 108988c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois switch (shift.GetType()) { 109088c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois case LSL: 109188c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois VIXL_ASSERT(amount <= 31); 109288c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois break; 109388c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois case ROR: 109488c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois VIXL_ASSERT(amount > 0); 109588c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois VIXL_ASSERT(amount <= 31); 109688c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois break; 109788c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois case LSR: 109888c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois case ASR: 109988c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois VIXL_ASSERT(amount > 0); 110088c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois VIXL_ASSERT(amount <= 32); 110188c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois break; 110288c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois case RRX: 110388c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois VIXL_ASSERT(amount == 0); 110488c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois break; 110588c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois default: 110688c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois VIXL_UNREACHABLE(); 110788c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois break; 110888c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois } 110988c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois#endif 111088c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois } 111188c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois // Constructor used for disassembly. 111288c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois ImmediateShiftOperand(int shift, int amount); 111388c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois uint32_t GetAmount() const { return amount_; } 111488c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois bool Is(const ImmediateShiftOperand& rhs) const { 111588c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois return amount_ == (rhs.amount_) && Shift::Is(*this); 111688c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois } 111788c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois 111888c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois private: 111988c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois uint32_t amount_; 112088c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois}; 112188c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois 112288c46b84df005638546de5e4e965bdcc31352f48Pierre Langloisinline std::ostream& operator<<(std::ostream& os, 112388c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois ImmediateShiftOperand const& shift_operand) { 112488c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois if (shift_operand.IsLSL() && shift_operand.GetAmount() == 0) return os; 112588c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois if (shift_operand.IsRRX()) return os << ", rrx"; 112688c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois return os << ", " << shift_operand.GetName() << " #" 112788c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois << shift_operand.GetAmount(); 112888c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois} 112988c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois 113088c46b84df005638546de5e4e965bdcc31352f48Pierre Langloisclass RegisterShiftOperand : public Shift { 113188c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois public: 113288c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois RegisterShiftOperand(ShiftType shift, Register shift_register) 113388c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois : Shift(shift), shift_register_(shift_register) { 113488c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois VIXL_ASSERT(!IsRRX() && shift_register_.IsValid()); 113588c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois } 113688c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois const Register GetShiftRegister() const { return shift_register_; } 113788c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois bool Is(const RegisterShiftOperand& rhs) const { 113888c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois return shift_register_.Is(rhs.shift_register_) && Shift::Is(*this); 113988c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois } 114088c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois 114188c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois private: 114288c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois Register shift_register_; 114388c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois}; 114488c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois 114588c46b84df005638546de5e4e965bdcc31352f48Pierre Langloisinline std::ostream& operator<<(std::ostream& s, 114688c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois const RegisterShiftOperand& shift_operand) { 114788c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois return s << shift_operand.GetName() << " " 114888c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois << shift_operand.GetShiftRegister(); 114988c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois} 115088c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois 115188c46b84df005638546de5e4e965bdcc31352f48Pierre Langloisenum EncodingSizeType { Best, Narrow, Wide }; 115288c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois 115388c46b84df005638546de5e4e965bdcc31352f48Pierre Langloisclass EncodingSize { 115488c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois uint32_t size_; 115588c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois 115688c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois public: 115788c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois explicit EncodingSize(uint32_t size) : size_(size) {} 115860241a544be0ebf48347789bf0ec268414364627Vincent Belliard EncodingSize(EncodingSizeType size) // NOLINT(runtime/explicit) 115960241a544be0ebf48347789bf0ec268414364627Vincent Belliard : size_(size) {} 116088c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois uint32_t GetSize() const { return size_; } 116188c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois const char* GetName() const; 116288c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois bool IsBest() const { return size_ == Best; } 116388c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois bool IsNarrow() const { return size_ == Narrow; } 116488c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois bool IsWide() const { return size_ == Wide; } 116588c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois}; 116688c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois 116788c46b84df005638546de5e4e965bdcc31352f48Pierre Langloisinline std::ostream& operator<<(std::ostream& os, EncodingSize size) { 116888c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois return os << size.GetName(); 116988c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois} 117088c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois 117188c46b84df005638546de5e4e965bdcc31352f48Pierre Langloisenum WriteBackValue { NO_WRITE_BACK, WRITE_BACK }; 117288c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois 117388c46b84df005638546de5e4e965bdcc31352f48Pierre Langloisclass WriteBack { 117488c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois WriteBackValue value_; 117588c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois 117688c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois public: 117760241a544be0ebf48347789bf0ec268414364627Vincent Belliard WriteBack(WriteBackValue value) // NOLINT(runtime/explicit) 117860241a544be0ebf48347789bf0ec268414364627Vincent Belliard : value_(value) {} 117988c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois explicit WriteBack(int value) 118088c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois : value_((value == 0) ? NO_WRITE_BACK : WRITE_BACK) {} 118188c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois uint32_t GetWriteBackUint32() const { return (value_ == WRITE_BACK) ? 1 : 0; } 118288c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois bool DoesWriteBack() const { return value_ == WRITE_BACK; } 118388c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois}; 118488c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois 118588c46b84df005638546de5e4e965bdcc31352f48Pierre Langloisinline std::ostream& operator<<(std::ostream& os, WriteBack write_back) { 118688c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois if (write_back.DoesWriteBack()) return os << "!"; 118788c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois return os; 118888c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois} 118988c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois 119088c46b84df005638546de5e4e965bdcc31352f48Pierre Langloisclass EncodingValue { 119188c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois bool valid_; 119288c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois uint32_t encoding_value_; 119388c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois 119488c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois public: 119588c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois EncodingValue() { 119688c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois valid_ = false; 119788c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois encoding_value_ = 0; 119888c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois } 119988c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois bool IsValid() const { return valid_; } 120088c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois uint32_t GetEncodingValue() const { return encoding_value_; } 120188c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois void SetEncodingValue(uint32_t encoding_value) { 120288c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois valid_ = true; 120388c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois encoding_value_ = encoding_value; 120488c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois } 120588c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois}; 120688c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois 120788c46b84df005638546de5e4e965bdcc31352f48Pierre Langloisclass EncodingValueAndImmediate : public EncodingValue { 120888c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois uint32_t encoded_immediate_; 120988c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois 121088c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois public: 121188c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois EncodingValueAndImmediate() { encoded_immediate_ = 0; } 121288c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois uint32_t GetEncodedImmediate() const { return encoded_immediate_; } 121388c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois void SetEncodedImmediate(uint32_t encoded_immediate) { 121488c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois encoded_immediate_ = encoded_immediate; 121588c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois } 121688c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois}; 121788c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois 121888c46b84df005638546de5e4e965bdcc31352f48Pierre Langloisclass ImmediateT32 : public EncodingValue { 121988c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois public: 122088c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois explicit ImmediateT32(uint32_t imm); 122188c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois static bool IsImmediateT32(uint32_t imm); 122288c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois static uint32_t Decode(uint32_t value); 122388c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois}; 122488c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois 122588c46b84df005638546de5e4e965bdcc31352f48Pierre Langloisclass ImmediateA32 : public EncodingValue { 122688c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois public: 122788c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois explicit ImmediateA32(uint32_t imm); 122888c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois static bool IsImmediateA32(uint32_t imm); 122988c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois static uint32_t Decode(uint32_t value); 123088c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois}; 123188c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois 123288c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois// Return the encoding value of a shift type. 123388c46b84df005638546de5e4e965bdcc31352f48Pierre Langloisuint32_t TypeEncodingValue(Shift shift); 123488c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois// Return the encoding value for a shift amount depending on the shift type. 123588c46b84df005638546de5e4e965bdcc31352f48Pierre Langloisuint32_t AmountEncodingValue(Shift shift, uint32_t amount); 123688c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois 123788c46b84df005638546de5e4e965bdcc31352f48Pierre Langloisenum MemoryBarrierType { 123888c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois OSHLD = 0x1, 123988c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois OSHST = 0x2, 124088c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois OSH = 0x3, 124188c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois NSHLD = 0x5, 124288c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois NSHST = 0x6, 124388c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois NSH = 0x7, 124488c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois ISHLD = 0x9, 124588c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois ISHST = 0xa, 124688c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois ISH = 0xb, 124788c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois LD = 0xd, 124888c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois ST = 0xe, 124988c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois SY = 0xf 125088c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois}; 125188c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois 125288c46b84df005638546de5e4e965bdcc31352f48Pierre Langloisclass MemoryBarrier { 125388c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois MemoryBarrierType type_; 125488c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois 125588c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois public: 125660241a544be0ebf48347789bf0ec268414364627Vincent Belliard MemoryBarrier(MemoryBarrierType type) // NOLINT(runtime/explicit) 125760241a544be0ebf48347789bf0ec268414364627Vincent Belliard : type_(type) {} 125860241a544be0ebf48347789bf0ec268414364627Vincent Belliard MemoryBarrier(uint32_t type) // NOLINT(runtime/explicit) 125988c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois : type_(static_cast<MemoryBarrierType>(type)) { 126088c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois VIXL_ASSERT((type & 0x3) != 0); 126188c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois } 126288c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois MemoryBarrierType GetType() const { return type_; } 126388c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois const char* GetName() const; 126488c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois}; 126588c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois 126688c46b84df005638546de5e4e965bdcc31352f48Pierre Langloisinline std::ostream& operator<<(std::ostream& os, MemoryBarrier option) { 126788c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois return os << option.GetName(); 126888c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois} 126988c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois 127088c46b84df005638546de5e4e965bdcc31352f48Pierre Langloisenum InterruptFlagsType { 127188c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois F = 0x1, 127288c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois I = 0x2, 127388c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois IF = 0x3, 127488c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois A = 0x4, 127588c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois AF = 0x5, 127688c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois AI = 0x6, 127788c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois AIF = 0x7 127888c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois}; 127988c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois 128088c46b84df005638546de5e4e965bdcc31352f48Pierre Langloisclass InterruptFlags { 128188c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois InterruptFlagsType type_; 128288c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois 128388c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois public: 128460241a544be0ebf48347789bf0ec268414364627Vincent Belliard InterruptFlags(InterruptFlagsType type) // NOLINT(runtime/explicit) 128560241a544be0ebf48347789bf0ec268414364627Vincent Belliard : type_(type) {} 128660241a544be0ebf48347789bf0ec268414364627Vincent Belliard InterruptFlags(uint32_t type) // NOLINT(runtime/explicit) 128788c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois : type_(static_cast<InterruptFlagsType>(type)) { 128888c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois VIXL_ASSERT(type <= 7); 128988c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois } 129088c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois InterruptFlagsType GetType() const { return type_; } 129188c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois const char* GetName() const; 129288c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois}; 129388c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois 129488c46b84df005638546de5e4e965bdcc31352f48Pierre Langloisinline std::ostream& operator<<(std::ostream& os, InterruptFlags option) { 129588c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois return os << option.GetName(); 129688c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois} 129788c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois 129888c46b84df005638546de5e4e965bdcc31352f48Pierre Langloisenum EndiannessType { LE = 0, BE = 1 }; 129988c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois 130088c46b84df005638546de5e4e965bdcc31352f48Pierre Langloisclass Endianness { 130188c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois EndiannessType type_; 130288c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois 130388c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois public: 130460241a544be0ebf48347789bf0ec268414364627Vincent Belliard Endianness(EndiannessType type) : type_(type) {} // NOLINT(runtime/explicit) 130560241a544be0ebf48347789bf0ec268414364627Vincent Belliard Endianness(uint32_t type) // NOLINT(runtime/explicit) 130688c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois : type_(static_cast<EndiannessType>(type)) { 130788c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois VIXL_ASSERT(type <= 1); 130888c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois } 130988c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois EndiannessType GetType() const { return type_; } 131088c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois const char* GetName() const; 131188c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois}; 131288c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois 131388c46b84df005638546de5e4e965bdcc31352f48Pierre Langloisinline std::ostream& operator<<(std::ostream& os, Endianness endian_specifier) { 131488c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois return os << endian_specifier.GetName(); 131588c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois} 131688c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois 131788c46b84df005638546de5e4e965bdcc31352f48Pierre Langloisenum AlignmentType { 131888c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois k16BitAlign = 0, 131988c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois k32BitAlign = 1, 132088c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois k64BitAlign = 2, 132188c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois k128BitAlign = 3, 132288c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois k256BitAlign = 4, 132388c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois kNoAlignment = 5, 132488c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois kBadAlignment = 6 132588c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois}; 132688c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois 132788c46b84df005638546de5e4e965bdcc31352f48Pierre Langloisclass Alignment { 132888c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois AlignmentType align_; 132988c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois 133088c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois public: 133188c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois Alignment(AlignmentType align) // NOLINT(runtime/explicit) 133288c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois : align_(align) {} 133388c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois Alignment(uint32_t align) // NOLINT(runtime/explicit) 133488c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois : align_(static_cast<AlignmentType>(align)) { 133588c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois VIXL_ASSERT(align <= static_cast<uint32_t>(k256BitAlign)); 133688c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois } 133788c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois AlignmentType GetType() const { return align_; } 133888c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois bool Is(AlignmentType type) { return align_ == type; } 133988c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois}; 134088c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois 134188c46b84df005638546de5e4e965bdcc31352f48Pierre Langloisinline std::ostream& operator<<(std::ostream& os, Alignment align) { 134288c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois if (align.GetType() == kBadAlignment) return os << " :??"; 134388c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois if (align.GetType() == kNoAlignment) return os; 134488c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois return os << " :" << (0x10 << static_cast<uint32_t>(align.GetType())); 134588c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois} 134688c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois 13478b57c86886020cf0a5331823be4789ee558764e2Georgia Kouveli// Structure containing information on forward references. 13488b57c86886020cf0a5331823be4789ee558764e2Georgia Kouvelistruct ReferenceInfo { 13498b57c86886020cf0a5331823be4789ee558764e2Georgia Kouveli int size; 13508b57c86886020cf0a5331823be4789ee558764e2Georgia Kouveli int min_offset; 13518b57c86886020cf0a5331823be4789ee558764e2Georgia Kouveli int max_offset; 13528b57c86886020cf0a5331823be4789ee558764e2Georgia Kouveli int alignment; // As a power of two. 13538b57c86886020cf0a5331823be4789ee558764e2Georgia Kouveli enum { kAlignPc, kDontAlignPc } pc_needs_aligning; 135488c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois}; 135588c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois 135688c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois} // namespace aarch32 135788c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois} // namespace vixl 135888c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois 1359d3832965c62a8ad461b9ea9eb0994ca6b0a3da2cAlexandre Rames#endif // VIXL_AARCH32_INSTRUCTIONS_AARCH32_H_ 1360