instructions-aarch32.h revision adbb4a746d2d90dd2920a8e0b7cd2397e93d17b9
1b78f13911bfe6eda303e91ef215c87a165aae8aeAlexandre Rames// Copyright 2015, 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 3788c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois#include "utils-vixl.h" 383e1b899f48c1328ac748b1f5fa78f417f7ec6581Vincent Belliard#include "code-buffer-vixl.h" 39d3832965c62a8ad461b9ea9eb0994ca6b0a3da2cAlexandre Rames#include "aarch32/constants-aarch32.h" 40d3832965c62a8ad461b9ea9eb0994ca6b0a3da2cAlexandre Rames#include "aarch32/label-aarch32.h" 4188c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois 4288c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois#ifdef __arm__ 4388c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois#define HARDFLOAT __attribute__((noinline, pcs("aapcs-vfp"))) 4488c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois#else 4588c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois#define HARDFLOAT __attribute__((noinline)) 4688c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois#endif 4788c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois 4888c46b84df005638546de5e4e965bdcc31352f48Pierre Langloisnamespace vixl { 4988c46b84df005638546de5e4e965bdcc31352f48Pierre Langloisnamespace aarch32 { 5088c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois 5188c46b84df005638546de5e4e965bdcc31352f48Pierre Langloisclass Operand; 5288c46b84df005638546de5e4e965bdcc31352f48Pierre Langloisclass SOperand; 5388c46b84df005638546de5e4e965bdcc31352f48Pierre Langloisclass DOperand; 5488c46b84df005638546de5e4e965bdcc31352f48Pierre Langloisclass QOperand; 5588c46b84df005638546de5e4e965bdcc31352f48Pierre Langloisclass MemOperand; 5688c46b84df005638546de5e4e965bdcc31352f48Pierre Langloisclass AlignedMemOperand; 5788c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois 5888c46b84df005638546de5e4e965bdcc31352f48Pierre Langloisenum AddrMode { Offset = 0, PreIndex = 1, PostIndex = 2 }; 5910dae1a549308bddc1931f29754d6a4459f70c9bJacob Bramleyenum InstructionSet { A32, T32 }; 6088c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois 6188c46b84df005638546de5e4e965bdcc31352f48Pierre Langloisclass CPURegister { 6288c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois public: 6388c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois enum RegisterType { 6488c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois kNoRegister = 0, 6588c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois kRRegister = 1, 6688c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois kSRegister = 2, 6788c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois kDRegister = 3, 6888c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois kQRegister = 4 6988c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois }; 7088c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois 7188c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois private: 7288c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois static const int kCodeBits = 5; 7388c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois static const int kTypeBits = 4; 7488c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois static const int kSizeBits = 8; 7588c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois static const int kCodeShift = 0; 7688c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois static const int kTypeShift = kCodeShift + kCodeBits; 7788c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois static const int kSizeShift = kTypeShift + kTypeBits; 7888c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois static const uint32_t kCodeMask = ((1 << kCodeBits) - 1) << kCodeShift; 7988c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois static const uint32_t kTypeMask = ((1 << kTypeBits) - 1) << kTypeShift; 8088c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois static const uint32_t kSizeMask = ((1 << kSizeBits) - 1) << kSizeShift; 8188c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois uint32_t value_; 8288c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois 8388c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois public: 8488c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois CPURegister(RegisterType type, uint32_t code, int size) 8588c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois : value_((type << kTypeShift) | (code << kCodeShift) | 8688c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois (size << kSizeShift)) { 8788c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois#ifdef VIXL_DEBUG 8888c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois switch (type) { 8988c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois case kNoRegister: 9088c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois break; 9188c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois case kRRegister: 9288c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois VIXL_ASSERT(code < kNumberOfRegisters); 9388c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois VIXL_ASSERT(size == kRegSizeInBits); 9488c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois break; 9588c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois case kSRegister: 9688c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois VIXL_ASSERT(code < kNumberOfSRegisters); 9788c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois VIXL_ASSERT(size == kSRegSizeInBits); 9888c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois break; 9988c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois case kDRegister: 10088c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois VIXL_ASSERT(code < kMaxNumberOfDRegisters); 10188c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois VIXL_ASSERT(size == kDRegSizeInBits); 10288c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois break; 10388c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois case kQRegister: 10488c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois VIXL_ASSERT(code < kNumberOfQRegisters); 10588c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois VIXL_ASSERT(size == kQRegSizeInBits); 10688c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois break; 10788c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois default: 10888c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois VIXL_UNREACHABLE(); 10988c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois break; 11088c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois } 11188c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois#endif 11288c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois } 11388c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois RegisterType GetType() const { 11488c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois return static_cast<RegisterType>((value_ & kTypeMask) >> kTypeShift); 11588c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois } 116f678618ae35a43dab65455f446c3de324994c204Vincent Belliard bool IsRegister() const { return GetType() == kRRegister; } 117f678618ae35a43dab65455f446c3de324994c204Vincent Belliard bool IsS() const { return GetType() == kSRegister; } 118f678618ae35a43dab65455f446c3de324994c204Vincent Belliard bool IsD() const { return GetType() == kDRegister; } 119f678618ae35a43dab65455f446c3de324994c204Vincent Belliard bool IsQ() const { return GetType() == kQRegister; } 120f678618ae35a43dab65455f446c3de324994c204Vincent Belliard bool IsVRegister() const { return IsS() || IsD() || IsQ(); } 121f678618ae35a43dab65455f446c3de324994c204Vincent Belliard bool IsFPRegister() const { return IsS() || IsD(); } 12288c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois uint32_t GetCode() const { return (value_ & kCodeMask) >> kCodeShift; } 12388c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois uint32_t GetReg() const { return value_; } 12488c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois int GetSizeInBits() const { return (value_ & kSizeMask) >> kSizeShift; } 12588c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois int GetRegSizeInBytes() const { 12688c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois return (GetType() == kNoRegister) ? 0 : (GetSizeInBits() / 8); 12788c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois } 12888c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois bool Is64Bits() const { return GetSizeInBits() == 64; } 12988c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois bool Is128Bits() const { return GetSizeInBits() == 128; } 13088c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois bool IsSameFormat(CPURegister reg) { 13188c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois return (value_ & ~kCodeMask) == (reg.value_ & ~kCodeMask); 13288c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois } 13388c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois bool Is(CPURegister ref) const { return GetReg() == ref.GetReg(); } 13488c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois bool IsValid() const { return GetType() != kNoRegister; } 13588c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois}; 13688c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois 13788c46b84df005638546de5e4e965bdcc31352f48Pierre Langloisclass Register : public CPURegister { 13888c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois public: 13988c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois Register() : CPURegister(kNoRegister, 0, kRegSizeInBits) {} 14088c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois explicit Register(uint32_t code) 14188c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois : CPURegister(kRRegister, code % kNumberOfRegisters, kRegSizeInBits) { 14288c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois VIXL_ASSERT(GetCode() < kNumberOfRegisters); 14388c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois } 14488c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois bool Is(Register ref) const { return GetCode() == ref.GetCode(); } 14588c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois bool IsLow() const { return GetCode() < kNumberOfT32LowRegisters; } 14688c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois bool IsLR() const { return GetCode() == kLrCode; } 14788c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois bool IsPC() const { return GetCode() == kPcCode; } 14888c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois bool IsSP() const { return GetCode() == kSpCode; } 14988c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois}; 15088c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois 15188c46b84df005638546de5e4e965bdcc31352f48Pierre Langloisstd::ostream& operator<<(std::ostream& os, const Register reg); 15288c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois 153adbb4a746d2d90dd2920a8e0b7cd2397e93d17b9Vincent Belliardclass RegisterOrAPSR_nzcv { 154adbb4a746d2d90dd2920a8e0b7cd2397e93d17b9Vincent Belliard uint32_t code_; 155adbb4a746d2d90dd2920a8e0b7cd2397e93d17b9Vincent Belliard 15688c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois public: 157adbb4a746d2d90dd2920a8e0b7cd2397e93d17b9Vincent Belliard explicit RegisterOrAPSR_nzcv(uint32_t code) : code_(code) { 158adbb4a746d2d90dd2920a8e0b7cd2397e93d17b9Vincent Belliard VIXL_ASSERT(code_ < kNumberOfRegisters); 159adbb4a746d2d90dd2920a8e0b7cd2397e93d17b9Vincent Belliard } 160adbb4a746d2d90dd2920a8e0b7cd2397e93d17b9Vincent Belliard bool IsAPSR_nzcv() const { return code_ == kPcCode; } 161adbb4a746d2d90dd2920a8e0b7cd2397e93d17b9Vincent Belliard uint32_t GetCode() const { return code_; } 162adbb4a746d2d90dd2920a8e0b7cd2397e93d17b9Vincent Belliard Register AsRegister() const { 163adbb4a746d2d90dd2920a8e0b7cd2397e93d17b9Vincent Belliard VIXL_ASSERT(!IsAPSR_nzcv()); 164adbb4a746d2d90dd2920a8e0b7cd2397e93d17b9Vincent Belliard return Register(code_); 165adbb4a746d2d90dd2920a8e0b7cd2397e93d17b9Vincent Belliard } 16688c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois}; 16788c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois 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: 28960241a544be0ebf48347789bf0ec268414364627Vincent Belliard DataType(DataTypeValue value) : value_(value) {} // NOLINT(runtime/explicit) 29060241a544be0ebf48347789bf0ec268414364627Vincent Belliard DataType(uint32_t size) // NOLINT(runtime/explicit) 29188c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois : value_(static_cast<DataTypeValue>(kDataTypeUntyped | size)) { 29288c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois VIXL_ASSERT((size == 8) || (size == 16) || (size == 32) || (size == 64)); 29388c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois } 29488c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois DataTypeValue GetValue() const { return value_; } 29588c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois DataTypeType GetType() const { 29688c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois return static_cast<DataTypeType>(value_ & kDataTypeTypeMask); 29788c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois } 29888c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois uint32_t GetSize() const { return value_ & kDataTypeSizeMask; } 29988c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois bool IsSize(uint32_t size) const { 30088c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois return (value_ & kDataTypeSizeMask) == size; 30188c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois } 30288c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois const char* GetName() const; 30388c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois bool Is(DataTypeValue value) const { return value_ == value; } 30488c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois bool Is(DataTypeType type) const { return GetType() == type; } 30588c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois bool IsNoneOr(DataTypeValue value) const { 30688c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois return (value_ == value) || (value_ == kDataTypeValueNone); 30788c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois } 30888c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois bool Is(DataTypeType type, uint32_t size) const { 30988c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois return value_ == static_cast<DataTypeValue>(type | size); 31088c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois } 31188c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois bool IsNoneOr(DataTypeType type, uint32_t size) const { 31288c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois return Is(type, size) || Is(kDataTypeValueNone); 31388c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois } 31488c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois}; 31588c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois 31688c46b84df005638546de5e4e965bdcc31352f48Pierre Langloisinline std::ostream& operator<<(std::ostream& os, DataType dt) { 31788c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois return os << dt.GetName(); 31888c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois} 31988c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois 32088c46b84df005638546de5e4e965bdcc31352f48Pierre Langloisclass DRegisterLane : public DRegister { 32188c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois uint32_t lane_; 32288c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois 32388c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois public: 32488c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois DRegisterLane(DRegister reg, uint32_t lane) 32588c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois : DRegister(reg.GetCode()), lane_(lane) {} 32688c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois DRegisterLane(uint32_t code, uint32_t lane) : DRegister(code), lane_(lane) {} 32788c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois uint32_t GetLane() const { return lane_; } 32888c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois uint32_t EncodeX(DataType dt, 32988c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois int single_bit_field, 33088c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois int four_bit_field_lowest_bit) const { 33188c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois VIXL_ASSERT(single_bit_field >= 4); 33288c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois uint32_t value = lane_ << ((dt.GetSize() == 16) ? 3 : 4) | GetCode(); 33388c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois return ((value & 0x10) << (single_bit_field - 4)) | 33488c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois ((value & 0xf) << four_bit_field_lowest_bit); 33588c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois } 33688c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois}; 33788c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois 33888c46b84df005638546de5e4e965bdcc31352f48Pierre Langloisinline unsigned ExtractDRegisterAndLane(uint32_t instr, 33988c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois DataType dt, 34088c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois int single_bit_field, 34188c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois int four_bit_field_lowest_bit, 34288c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois int* lane) { 34388c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois VIXL_ASSERT(single_bit_field >= 4); 34488c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois uint32_t value = ((instr >> (single_bit_field - 4)) & 0x10) | 34588c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois ((instr >> four_bit_field_lowest_bit) & 0xf); 34688c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois if (dt.GetSize() == 16) { 34788c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois *lane = value >> 3; 34888c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois return value & 0x7; 34988c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois } 35088c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois *lane = value >> 4; 35188c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois return value & 0xf; 35288c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois} 35388c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois 35488c46b84df005638546de5e4e965bdcc31352f48Pierre Langloisinline std::ostream& operator<<(std::ostream& os, const DRegisterLane lane) { 35588c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois os << "d" << lane.GetCode() << "["; 35688c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois if (lane.GetLane() == static_cast<uint32_t>(-1)) return os << "??]"; 35788c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois return os << lane.GetLane() << "]"; 35888c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois} 35988c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois 36088c46b84df005638546de5e4e965bdcc31352f48Pierre Langloisclass QRegister : public VRegister { 36188c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois public: 36288c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois QRegister() : VRegister(kNoRegister, 0, kQRegSizeInBits) {} 36388c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois explicit QRegister(uint32_t code) 36488c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois : VRegister(kQRegister, code, kQRegSizeInBits) {} 36588c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois uint32_t Encode(int offset) { return GetCode() << offset; } 36697a5640aedb2d193ff27b9e7324a2412ed502a59Vincent Belliard DRegister GetDLane(uint32_t lane) const { 36797a5640aedb2d193ff27b9e7324a2412ed502a59Vincent Belliard uint32_t lane_count = kQRegSizeInBits / kDRegSizeInBits; 36897a5640aedb2d193ff27b9e7324a2412ed502a59Vincent Belliard VIXL_ASSERT(lane < lane_count); 36997a5640aedb2d193ff27b9e7324a2412ed502a59Vincent Belliard return DRegister(GetCode() * lane_count + lane); 37097a5640aedb2d193ff27b9e7324a2412ed502a59Vincent Belliard } 37188c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois DRegister GetLowDRegister() const { return DRegister(GetCode() * 2); } 37288c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois DRegister GetHighDRegister() const { return DRegister(1 + GetCode() * 2); } 37397a5640aedb2d193ff27b9e7324a2412ed502a59Vincent Belliard SRegister GetSLane(uint32_t lane) const { 37497a5640aedb2d193ff27b9e7324a2412ed502a59Vincent Belliard uint32_t lane_count = kQRegSizeInBits / kSRegSizeInBits; 37597a5640aedb2d193ff27b9e7324a2412ed502a59Vincent Belliard VIXL_ASSERT(lane < lane_count); 37697a5640aedb2d193ff27b9e7324a2412ed502a59Vincent Belliard VIXL_ASSERT(GetCode() * lane_count < kNumberOfSRegisters); 37797a5640aedb2d193ff27b9e7324a2412ed502a59Vincent Belliard return SRegister(GetCode() * lane_count + lane); 37897a5640aedb2d193ff27b9e7324a2412ed502a59Vincent Belliard } 37988c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois uint32_t Encode(int single_bit_field, int four_bit_field_lowest_bit) { 38088c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois // Encode "code * 2". 38188c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois VIXL_ASSERT(single_bit_field >= 3); 38288c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois return ((GetCode() & 0x8) << (single_bit_field - 3)) | 38388c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois ((GetCode() & 0x7) << (four_bit_field_lowest_bit + 1)); 38488c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois } 38588c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois}; 38688c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois 38788c46b84df005638546de5e4e965bdcc31352f48Pierre Langloisinline unsigned ExtractQRegister(uint32_t instr, 38888c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois int single_bit_field, 38988c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois int four_bit_field_lowest_bit) { 39088c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois VIXL_ASSERT(single_bit_field >= 3); 39188c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois return ((instr >> (single_bit_field - 3)) & 0x8) | 39288c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois ((instr >> (four_bit_field_lowest_bit + 1)) & 0x7); 39388c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois} 39488c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois 39588c46b84df005638546de5e4e965bdcc31352f48Pierre Langloisinline std::ostream& operator<<(std::ostream& os, const QRegister reg) { 39688c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois return os << "q" << reg.GetCode(); 39788c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois} 39888c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois 39988c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois// clang-format off 4001107e04f82d4809214ff6592b3727298dee1fe45Alexandre Rames#define AARCH32_REGISTER_CODE_LIST(R) \ 40188c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois R(0) R(1) R(2) R(3) R(4) R(5) R(6) R(7) \ 40288c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois R(8) R(9) R(10) R(11) R(12) R(13) R(14) R(15) 40388c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois// clang-format on 40488c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois#define DEFINE_REGISTER(N) const Register r##N(N); 4051107e04f82d4809214ff6592b3727298dee1fe45Alexandre RamesAARCH32_REGISTER_CODE_LIST(DEFINE_REGISTER) 40688c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois#undef DEFINE_REGISTER 4071107e04f82d4809214ff6592b3727298dee1fe45Alexandre Rames#undef AARCH32_REGISTER_CODE_LIST 40888c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois 40988c46b84df005638546de5e4e965bdcc31352f48Pierre Langloisenum RegNum { kIPRegNum = 12, kSPRegNum = 13, kLRRegNum = 14, kPCRegNum = 15 }; 41088c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois 41188c46b84df005638546de5e4e965bdcc31352f48Pierre Langloisconst Register ip(kIPRegNum); 41288c46b84df005638546de5e4e965bdcc31352f48Pierre Langloisconst Register sp(kSPRegNum); 41388c46b84df005638546de5e4e965bdcc31352f48Pierre Langloisconst Register pc(kPCRegNum); 41488c46b84df005638546de5e4e965bdcc31352f48Pierre Langloisconst Register lr(kLRRegNum); 41588c46b84df005638546de5e4e965bdcc31352f48Pierre Langloisconst Register NoReg; 41688c46b84df005638546de5e4e965bdcc31352f48Pierre Langloisconst VRegister NoVReg; 41788c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois 41888c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois// clang-format off 41988c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois#define SREGISTER_CODE_LIST(R) \ 42088c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois R(0) R(1) R(2) R(3) R(4) R(5) R(6) R(7) \ 42188c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois R(8) R(9) R(10) R(11) R(12) R(13) R(14) R(15) \ 42288c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois R(16) R(17) R(18) R(19) R(20) R(21) R(22) R(23) \ 42388c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois R(24) R(25) R(26) R(27) R(28) R(29) R(30) R(31) 42488c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois// clang-format on 42588c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois#define DEFINE_REGISTER(N) const SRegister s##N(N); 42688c46b84df005638546de5e4e965bdcc31352f48Pierre LangloisSREGISTER_CODE_LIST(DEFINE_REGISTER) 42788c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois#undef DEFINE_REGISTER 42888c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois#undef SREGISTER_CODE_LIST 42988c46b84df005638546de5e4e965bdcc31352f48Pierre Langloisconst SRegister NoSReg; 43088c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois 43188c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois// clang-format off 43288c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois#define DREGISTER_CODE_LIST(R) \ 43388c46b84df005638546de5e4e965bdcc31352f48Pierre LangloisR(0) R(1) R(2) R(3) R(4) R(5) R(6) R(7) \ 43488c46b84df005638546de5e4e965bdcc31352f48Pierre LangloisR(8) R(9) R(10) R(11) R(12) R(13) R(14) R(15) \ 43588c46b84df005638546de5e4e965bdcc31352f48Pierre LangloisR(16) R(17) R(18) R(19) R(20) R(21) R(22) R(23) \ 43688c46b84df005638546de5e4e965bdcc31352f48Pierre LangloisR(24) R(25) R(26) R(27) R(28) R(29) R(30) R(31) 43788c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois// clang-format on 43888c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois#define DEFINE_REGISTER(N) const DRegister d##N(N); 43988c46b84df005638546de5e4e965bdcc31352f48Pierre LangloisDREGISTER_CODE_LIST(DEFINE_REGISTER) 44088c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois#undef DEFINE_REGISTER 44188c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois#undef DREGISTER_CODE_LIST 44288c46b84df005638546de5e4e965bdcc31352f48Pierre Langloisconst DRegister NoDReg; 44388c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois 44488c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois// clang-format off 44588c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois#define QREGISTER_CODE_LIST(R) \ 44688c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois R(0) R(1) R(2) R(3) R(4) R(5) R(6) R(7) \ 44788c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois R(8) R(9) R(10) R(11) R(12) R(13) R(14) R(15) 44888c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois// clang-format on 44988c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois#define DEFINE_REGISTER(N) const QRegister q##N(N); 45088c46b84df005638546de5e4e965bdcc31352f48Pierre LangloisQREGISTER_CODE_LIST(DEFINE_REGISTER) 45188c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois#undef DEFINE_REGISTER 45288c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois#undef QREGISTER_CODE_LIST 45388c46b84df005638546de5e4e965bdcc31352f48Pierre Langloisconst QRegister NoQReg; 45488c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois 45588c46b84df005638546de5e4e965bdcc31352f48Pierre Langloisclass RegisterList { 45688c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois public: 45788c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois RegisterList() : list_(0) {} 45860241a544be0ebf48347789bf0ec268414364627Vincent Belliard RegisterList(Register reg) // NOLINT(runtime/explicit) 45960241a544be0ebf48347789bf0ec268414364627Vincent Belliard : list_(RegisterToList(reg)) {} 46088c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois RegisterList(Register reg1, Register reg2) 46188c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois : list_(RegisterToList(reg1) | RegisterToList(reg2)) {} 46288c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois RegisterList(Register reg1, Register reg2, Register reg3) 46388c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois : list_(RegisterToList(reg1) | RegisterToList(reg2) | 46488c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois RegisterToList(reg3)) {} 46588c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois RegisterList(Register reg1, Register reg2, Register reg3, Register reg4) 46688c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois : list_(RegisterToList(reg1) | RegisterToList(reg2) | 46788c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois RegisterToList(reg3) | RegisterToList(reg4)) {} 46888c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois explicit RegisterList(uint32_t list) : list_(list) {} 46988c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois uint32_t GetList() const { return list_; } 47088c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois void SetList(uint32_t list) { list_ = list; } 47188c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois bool Includes(const Register& reg) const { 47288c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois return (list_ & RegisterToList(reg)) != 0; 47388c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois } 47488c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois void Combine(const RegisterList& other) { list_ |= other.GetList(); } 47588c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois void Combine(const Register& reg) { list_ |= RegisterToList(reg); } 47688c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois void Remove(const RegisterList& other) { list_ &= ~other.GetList(); } 47788c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois void Remove(const Register& reg) { list_ &= ~RegisterToList(reg); } 47888c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois bool Overlaps(const RegisterList& other) const { 47988c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois return (list_ & other.list_) != 0; 48088c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois } 48188c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois bool IsR0toR7orPC() const { 48288c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois // True if all the registers from the list are not from r8-r14. 48388c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois return (list_ & 0x7f00) == 0; 48488c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois } 48588c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois bool IsR0toR7orLR() const { 48688c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois // True if all the registers from the list are not from r8-r13 nor from r15. 48788c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois return (list_ & 0xbf00) == 0; 48888c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois } 48988c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois Register GetFirstAvailableRegister() const; 49088c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois bool IsEmpty() const { return list_ == 0; } 49188c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois static RegisterList Union(const RegisterList& list_1, 49288c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois const RegisterList& list_2) { 49388c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois return RegisterList(list_1.list_ | list_2.list_); 49488c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois } 49588c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois static RegisterList Union(const RegisterList& list_1, 49688c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois const RegisterList& list_2, 49788c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois const RegisterList& list_3) { 49888c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois return Union(list_1, Union(list_2, list_3)); 49988c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois } 50088c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois static RegisterList Union(const RegisterList& list_1, 50188c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois const RegisterList& list_2, 50288c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois const RegisterList& list_3, 50388c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois const RegisterList& list_4) { 50488c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois return Union(Union(list_1, list_2), Union(list_3, list_4)); 50588c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois } 50688c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois static RegisterList Intersection(const RegisterList& list_1, 50788c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois const RegisterList& list_2) { 50888c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois return RegisterList(list_1.list_ & list_2.list_); 50988c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois } 51088c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois static RegisterList Intersection(const RegisterList& list_1, 51188c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois const RegisterList& list_2, 51288c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois const RegisterList& list_3) { 51388c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois return Intersection(list_1, Intersection(list_2, list_3)); 51488c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois } 51588c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois static RegisterList Intersection(const RegisterList& list_1, 51688c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois const RegisterList& list_2, 51788c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois const RegisterList& list_3, 51888c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois const RegisterList& list_4) { 51988c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois return Intersection(Intersection(list_1, list_2), 52088c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois Intersection(list_3, list_4)); 52188c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois } 52288c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois 52388c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois private: 52488c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois static uint32_t RegisterToList(Register reg) { 52588c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois if (reg.GetType() == CPURegister::kNoRegister) { 52688c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois return 0; 52788c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois } else { 52888c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois return UINT32_C(1) << reg.GetCode(); 52988c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois } 53088c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois } 53188c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois 53288c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois // Bitfield representation of all registers in the list 53388c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois // (1 for r0, 2 for r1, 4 for r2, ...). 53488c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois uint32_t list_; 53588c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois}; 53688c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois 53788c46b84df005638546de5e4e965bdcc31352f48Pierre Langloisinline uint32_t GetRegisterListEncoding(const RegisterList& registers, 53888c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois int first, 53988c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois int count) { 54088c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois return (registers.GetList() >> first) & ((1 << count) - 1); 54188c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois} 54288c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois 54388c46b84df005638546de5e4e965bdcc31352f48Pierre Langloisstd::ostream& operator<<(std::ostream& os, RegisterList registers); 54488c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois 54588c46b84df005638546de5e4e965bdcc31352f48Pierre Langloisclass VRegisterList { 54688c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois public: 54788c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois VRegisterList() : list_(0) {} 54888c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois explicit VRegisterList(VRegister reg) : list_(RegisterToList(reg)) {} 54988c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois VRegisterList(VRegister reg1, VRegister reg2) 55088c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois : list_(RegisterToList(reg1) | RegisterToList(reg2)) {} 55188c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois VRegisterList(VRegister reg1, VRegister reg2, VRegister reg3) 55288c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois : list_(RegisterToList(reg1) | RegisterToList(reg2) | 55388c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois RegisterToList(reg3)) {} 55488c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois VRegisterList(VRegister reg1, VRegister reg2, VRegister reg3, VRegister reg4) 55588c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois : list_(RegisterToList(reg1) | RegisterToList(reg2) | 55688c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois RegisterToList(reg3) | RegisterToList(reg4)) {} 55788c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois explicit VRegisterList(uint64_t list) : list_(list) {} 55888c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois uint64_t GetList() const { return list_; } 55988c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois void SetList(uint64_t list) { list_ = list; } 560e6c6319611916b73b227075c7a7c2f76bec50745Jacob Bramley // Because differently-sized V registers overlap with one another, there is no 561e6c6319611916b73b227075c7a7c2f76bec50745Jacob Bramley // way to implement a single 'Includes' function in a way that is unsurprising 562e6c6319611916b73b227075c7a7c2f76bec50745Jacob Bramley // for all existing uses. 563e6c6319611916b73b227075c7a7c2f76bec50745Jacob Bramley bool IncludesAllOf(const VRegister& reg) const { 564e6c6319611916b73b227075c7a7c2f76bec50745Jacob Bramley return (list_ & RegisterToList(reg)) == RegisterToList(reg); 565e6c6319611916b73b227075c7a7c2f76bec50745Jacob Bramley } 566e6c6319611916b73b227075c7a7c2f76bec50745Jacob Bramley bool IncludesAliasOf(const VRegister& reg) const { 56788c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois return (list_ & RegisterToList(reg)) != 0; 56888c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois } 56988c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois void Combine(const VRegisterList& other) { list_ |= other.GetList(); } 57088c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois void Combine(const VRegister& reg) { list_ |= RegisterToList(reg); } 57188c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois void Remove(const VRegisterList& other) { list_ &= ~other.GetList(); } 57288c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois void Remove(const VRegister& reg) { list_ &= ~RegisterToList(reg); } 57388c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois bool Overlaps(const VRegisterList& other) const { 57488c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois return (list_ & other.list_) != 0; 57588c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois } 57688c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois QRegister GetFirstAvailableQRegister() const; 57788c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois DRegister GetFirstAvailableDRegister() const; 57888c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois SRegister GetFirstAvailableSRegister() const; 57988c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois bool IsEmpty() const { return list_ == 0; } 58088c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois static VRegisterList Union(const VRegisterList& list_1, 58188c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois const VRegisterList& list_2) { 58288c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois return VRegisterList(list_1.list_ | list_2.list_); 58388c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois } 58488c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois static VRegisterList Union(const VRegisterList& list_1, 58588c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois const VRegisterList& list_2, 58688c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois const VRegisterList& list_3) { 58788c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois return Union(list_1, Union(list_2, list_3)); 58888c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois } 58988c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois static VRegisterList Union(const VRegisterList& list_1, 59088c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois const VRegisterList& list_2, 59188c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois const VRegisterList& list_3, 59288c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois const VRegisterList& list_4) { 59388c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois return Union(Union(list_1, list_2), Union(list_3, list_4)); 59488c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois } 59588c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois static VRegisterList Intersection(const VRegisterList& list_1, 59688c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois const VRegisterList& list_2) { 59788c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois return VRegisterList(list_1.list_ & list_2.list_); 59888c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois } 59988c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois static VRegisterList Intersection(const VRegisterList& list_1, 60088c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois const VRegisterList& list_2, 60188c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois const VRegisterList& list_3) { 60288c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois return Intersection(list_1, Intersection(list_2, list_3)); 60388c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois } 60488c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois static VRegisterList Intersection(const VRegisterList& list_1, 60588c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois const VRegisterList& list_2, 60688c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois const VRegisterList& list_3, 60788c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois const VRegisterList& list_4) { 60888c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois return Intersection(Intersection(list_1, list_2), 60988c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois Intersection(list_3, list_4)); 61088c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois } 61188c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois 61288c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois private: 61388c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois static uint64_t RegisterToList(VRegister reg) { 61488c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois if (reg.GetType() == CPURegister::kNoRegister) { 61588c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois return 0; 61688c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois } else { 61788c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois switch (reg.GetSizeInBits()) { 61888c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois case kQRegSizeInBits: 61988c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois return UINT64_C(0xf) << (reg.GetCode() * 4); 62088c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois case kDRegSizeInBits: 62188c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois return UINT64_C(0x3) << (reg.GetCode() * 2); 62288c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois case kSRegSizeInBits: 62388c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois return UINT64_C(0x1) << reg.GetCode(); 62488c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois default: 62588c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois VIXL_UNREACHABLE(); 62688c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois return 0; 62788c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois } 62888c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois } 62988c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois } 63088c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois 63188c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois // Bitfield representation of all registers in the list. 63288c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois // (0x3 for d0, 0xc0 for d1, 0x30 for d2, ...). We have one, two or four bits 63388c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois // per register according to their size. This way we can make sure that we 634e6c6319611916b73b227075c7a7c2f76bec50745Jacob Bramley // account for overlapping registers. 635e6c6319611916b73b227075c7a7c2f76bec50745Jacob Bramley // A register is wholly included in this list only if all of its bits are set. 636e6c6319611916b73b227075c7a7c2f76bec50745Jacob Bramley // A register is aliased by the list if at least one of its bits are set. 637e6c6319611916b73b227075c7a7c2f76bec50745Jacob Bramley // The IncludesAllOf and IncludesAliasOf helpers are provided to make this 638e6c6319611916b73b227075c7a7c2f76bec50745Jacob Bramley // distinction clear. 63988c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois uint64_t list_; 64088c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois}; 64188c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois 64288c46b84df005638546de5e4e965bdcc31352f48Pierre Langloisclass SRegisterList { 64371bca307f4e94afdbc753e02c101b042cd218b4aPierre Langlois SRegister first_; 64471bca307f4e94afdbc753e02c101b042cd218b4aPierre Langlois int length_; 64588c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois 64688c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois public: 64771bca307f4e94afdbc753e02c101b042cd218b4aPierre Langlois explicit SRegisterList(SRegister reg) : first_(reg.GetCode()), length_(1) {} 64871bca307f4e94afdbc753e02c101b042cd218b4aPierre Langlois SRegisterList(SRegister first, int length) 64971bca307f4e94afdbc753e02c101b042cd218b4aPierre Langlois : first_(first.GetCode()), length_(length) { 65071bca307f4e94afdbc753e02c101b042cd218b4aPierre Langlois VIXL_ASSERT(length >= 0); 65188c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois } 65229f71f91fc1282d12fd2d5eb87eec8cf0147f043Jacob Bramley SRegister GetSRegister(int n) const { 65329f71f91fc1282d12fd2d5eb87eec8cf0147f043Jacob Bramley VIXL_ASSERT(n >= 0); 65429f71f91fc1282d12fd2d5eb87eec8cf0147f043Jacob Bramley VIXL_ASSERT(n < length_); 65529f71f91fc1282d12fd2d5eb87eec8cf0147f043Jacob Bramley return SRegister((first_.GetCode() + n) % kNumberOfSRegisters); 65671bca307f4e94afdbc753e02c101b042cd218b4aPierre Langlois } 65729f71f91fc1282d12fd2d5eb87eec8cf0147f043Jacob Bramley const SRegister& GetFirstSRegister() const { return first_; } 65829f71f91fc1282d12fd2d5eb87eec8cf0147f043Jacob Bramley SRegister GetLastSRegister() const { return GetSRegister(length_ - 1); } 65971bca307f4e94afdbc753e02c101b042cd218b4aPierre Langlois int GetLength() const { return length_; } 66088c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois}; 66188c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois 66288c46b84df005638546de5e4e965bdcc31352f48Pierre Langloisstd::ostream& operator<<(std::ostream& os, SRegisterList registers); 66388c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois 66488c46b84df005638546de5e4e965bdcc31352f48Pierre Langloisclass DRegisterList { 66571bca307f4e94afdbc753e02c101b042cd218b4aPierre Langlois DRegister first_; 66671bca307f4e94afdbc753e02c101b042cd218b4aPierre Langlois int length_; 66788c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois 66888c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois public: 66971bca307f4e94afdbc753e02c101b042cd218b4aPierre Langlois explicit DRegisterList(DRegister reg) : first_(reg.GetCode()), length_(1) {} 67071bca307f4e94afdbc753e02c101b042cd218b4aPierre Langlois DRegisterList(DRegister first, int length) 67171bca307f4e94afdbc753e02c101b042cd218b4aPierre Langlois : first_(first.GetCode()), length_(length) { 67271bca307f4e94afdbc753e02c101b042cd218b4aPierre Langlois VIXL_ASSERT(length >= 0); 67388c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois } 67429f71f91fc1282d12fd2d5eb87eec8cf0147f043Jacob Bramley DRegister GetDRegister(int n) const { 67529f71f91fc1282d12fd2d5eb87eec8cf0147f043Jacob Bramley VIXL_ASSERT(n >= 0); 67629f71f91fc1282d12fd2d5eb87eec8cf0147f043Jacob Bramley VIXL_ASSERT(n < length_); 67729f71f91fc1282d12fd2d5eb87eec8cf0147f043Jacob Bramley return DRegister((first_.GetCode() + n) % kMaxNumberOfDRegisters); 67871bca307f4e94afdbc753e02c101b042cd218b4aPierre Langlois } 67929f71f91fc1282d12fd2d5eb87eec8cf0147f043Jacob Bramley const DRegister& GetFirstDRegister() const { return first_; } 68029f71f91fc1282d12fd2d5eb87eec8cf0147f043Jacob Bramley DRegister GetLastDRegister() const { return GetDRegister(length_ - 1); } 68171bca307f4e94afdbc753e02c101b042cd218b4aPierre Langlois int GetLength() const { return length_; } 68288c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois}; 68388c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois 68488c46b84df005638546de5e4e965bdcc31352f48Pierre Langloisstd::ostream& operator<<(std::ostream& os, DRegisterList registers); 68588c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois 68688c46b84df005638546de5e4e965bdcc31352f48Pierre Langloisenum SpacingType { kSingle, kDouble }; 68788c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois 68888c46b84df005638546de5e4e965bdcc31352f48Pierre Langloisenum TransferType { kMultipleLanes, kOneLane, kAllLanes }; 68988c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois 69088c46b84df005638546de5e4e965bdcc31352f48Pierre Langloisclass NeonRegisterList { 69129f71f91fc1282d12fd2d5eb87eec8cf0147f043Jacob Bramley DRegister first_; 69288c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois SpacingType spacing_; 69388c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois TransferType type_; 69488c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois int lane_; 69529f71f91fc1282d12fd2d5eb87eec8cf0147f043Jacob Bramley int length_; 69688c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois 69788c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois public: 69888c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois NeonRegisterList(DRegister reg, TransferType type) 69988c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois : first_(reg.GetCode()), 70088c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois spacing_(kSingle), 70188c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois type_(type), 70229f71f91fc1282d12fd2d5eb87eec8cf0147f043Jacob Bramley lane_(-1), 70329f71f91fc1282d12fd2d5eb87eec8cf0147f043Jacob Bramley length_(1) { 70488c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois VIXL_ASSERT(type_ != kOneLane); 70588c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois } 70688c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois NeonRegisterList(DRegister reg, int lane) 70788c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois : first_(reg.GetCode()), 70888c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois spacing_(kSingle), 70988c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois type_(kOneLane), 71029f71f91fc1282d12fd2d5eb87eec8cf0147f043Jacob Bramley lane_(lane), 71129f71f91fc1282d12fd2d5eb87eec8cf0147f043Jacob Bramley length_(1) { 71288c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois VIXL_ASSERT((lane_ >= 0) && (lane_ < 4)); 71388c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois } 71488c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois NeonRegisterList(DRegister first, 71588c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois DRegister last, 71688c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois SpacingType spacing, 71788c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois TransferType type) 71829f71f91fc1282d12fd2d5eb87eec8cf0147f043Jacob Bramley : first_(first.GetCode()), spacing_(spacing), type_(type), lane_(-1) { 71929f71f91fc1282d12fd2d5eb87eec8cf0147f043Jacob Bramley VIXL_ASSERT(type != kOneLane); 72029f71f91fc1282d12fd2d5eb87eec8cf0147f043Jacob Bramley VIXL_ASSERT(first.GetCode() <= last.GetCode()); 72129f71f91fc1282d12fd2d5eb87eec8cf0147f043Jacob Bramley 72229f71f91fc1282d12fd2d5eb87eec8cf0147f043Jacob Bramley int range = last.GetCode() - first.GetCode(); 72329f71f91fc1282d12fd2d5eb87eec8cf0147f043Jacob Bramley VIXL_ASSERT(IsSingleSpaced() || IsMultiple(range, 2)); 72429f71f91fc1282d12fd2d5eb87eec8cf0147f043Jacob Bramley length_ = (IsDoubleSpaced() ? (range / 2) : range) + 1; 72529f71f91fc1282d12fd2d5eb87eec8cf0147f043Jacob Bramley 72629f71f91fc1282d12fd2d5eb87eec8cf0147f043Jacob Bramley VIXL_ASSERT(length_ <= 4); 72788c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois } 72888c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois NeonRegisterList(DRegister first, 72988c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois DRegister last, 73088c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois SpacingType spacing, 73188c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois int lane) 73288c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois : first_(first.GetCode()), 73388c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois spacing_(spacing), 73488c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois type_(kOneLane), 73588c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois lane_(lane) { 73629f71f91fc1282d12fd2d5eb87eec8cf0147f043Jacob Bramley VIXL_ASSERT((lane >= 0) && (lane < 4)); 73729f71f91fc1282d12fd2d5eb87eec8cf0147f043Jacob Bramley VIXL_ASSERT(first.GetCode() <= last.GetCode()); 73829f71f91fc1282d12fd2d5eb87eec8cf0147f043Jacob Bramley 73929f71f91fc1282d12fd2d5eb87eec8cf0147f043Jacob Bramley int range = last.GetCode() - first.GetCode(); 74029f71f91fc1282d12fd2d5eb87eec8cf0147f043Jacob Bramley VIXL_ASSERT(IsSingleSpaced() || IsMultiple(range, 2)); 74129f71f91fc1282d12fd2d5eb87eec8cf0147f043Jacob Bramley length_ = (IsDoubleSpaced() ? (range / 2) : range) + 1; 74229f71f91fc1282d12fd2d5eb87eec8cf0147f043Jacob Bramley 74329f71f91fc1282d12fd2d5eb87eec8cf0147f043Jacob Bramley VIXL_ASSERT(length_ <= 4); 74488c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois } 74529f71f91fc1282d12fd2d5eb87eec8cf0147f043Jacob Bramley DRegister GetDRegister(int n) const { 74629f71f91fc1282d12fd2d5eb87eec8cf0147f043Jacob Bramley VIXL_ASSERT(n >= 0); 74729f71f91fc1282d12fd2d5eb87eec8cf0147f043Jacob Bramley VIXL_ASSERT(n < length_); 74829f71f91fc1282d12fd2d5eb87eec8cf0147f043Jacob Bramley unsigned code = first_.GetCode() + (IsDoubleSpaced() ? (2 * n) : n); 74929f71f91fc1282d12fd2d5eb87eec8cf0147f043Jacob Bramley VIXL_ASSERT(code < kMaxNumberOfDRegisters); 75029f71f91fc1282d12fd2d5eb87eec8cf0147f043Jacob Bramley return DRegister(code); 75188c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois } 75229f71f91fc1282d12fd2d5eb87eec8cf0147f043Jacob Bramley const DRegister& GetFirstDRegister() const { return first_; } 75329f71f91fc1282d12fd2d5eb87eec8cf0147f043Jacob Bramley DRegister GetLastDRegister() const { return GetDRegister(length_ - 1); } 75429f71f91fc1282d12fd2d5eb87eec8cf0147f043Jacob Bramley int GetLength() const { return length_; } 75588c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois bool IsSingleSpaced() const { return spacing_ == kSingle; } 75688c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois bool IsDoubleSpaced() const { return spacing_ == kDouble; } 75788c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois bool IsTransferAllLanes() const { return type_ == kAllLanes; } 75888c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois bool IsTransferOneLane() const { return type_ == kOneLane; } 75988c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois bool IsTransferMultipleLanes() const { return type_ == kMultipleLanes; } 76088c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois int GetTransferLane() const { return lane_; } 76188c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois}; 76288c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois 76388c46b84df005638546de5e4e965bdcc31352f48Pierre Langloisstd::ostream& operator<<(std::ostream& os, NeonRegisterList registers); 76488c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois 76588c46b84df005638546de5e4e965bdcc31352f48Pierre Langloisenum SpecialRegisterType { APSR = 0, CPSR = 0, SPSR = 1 }; 76688c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois 76788c46b84df005638546de5e4e965bdcc31352f48Pierre Langloisclass SpecialRegister { 76888c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois uint32_t reg_; 76988c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois 77088c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois public: 77188c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois explicit SpecialRegister(uint32_t reg) : reg_(reg) {} 77260241a544be0ebf48347789bf0ec268414364627Vincent Belliard SpecialRegister(SpecialRegisterType reg) // NOLINT(runtime/explicit) 77360241a544be0ebf48347789bf0ec268414364627Vincent Belliard : reg_(reg) {} 77488c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois uint32_t GetReg() const { return reg_; } 77588c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois const char* GetName() const; 77688c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois bool Is(SpecialRegister value) const { return reg_ == value.reg_; } 77788c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois bool Is(uint32_t value) const { return reg_ == value; } 77888c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois bool IsNot(uint32_t value) const { return reg_ != value; } 77988c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois}; 78088c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois 78188c46b84df005638546de5e4e965bdcc31352f48Pierre Langloisinline std::ostream& operator<<(std::ostream& os, SpecialRegister reg) { 78288c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois return os << reg.GetName(); 78388c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois} 78488c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois 78588c46b84df005638546de5e4e965bdcc31352f48Pierre Langloisenum BankedRegisterType { 78688c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois R8_usr = 0x00, 78788c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois R9_usr = 0x01, 78888c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois R10_usr = 0x02, 78988c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois R11_usr = 0x03, 79088c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois R12_usr = 0x04, 79188c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois SP_usr = 0x05, 79288c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois LR_usr = 0x06, 79388c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois R8_fiq = 0x08, 79488c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois R9_fiq = 0x09, 79588c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois R10_fiq = 0x0a, 79688c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois R11_fiq = 0x0b, 79788c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois R12_fiq = 0x0c, 79888c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois SP_fiq = 0x0d, 79988c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois LR_fiq = 0x0e, 80088c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois LR_irq = 0x10, 80188c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois SP_irq = 0x11, 80288c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois LR_svc = 0x12, 80388c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois SP_svc = 0x13, 80488c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois LR_abt = 0x14, 80588c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois SP_abt = 0x15, 80688c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois LR_und = 0x16, 80788c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois SP_und = 0x17, 80888c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois LR_mon = 0x1c, 80988c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois SP_mon = 0x1d, 81088c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois ELR_hyp = 0x1e, 81188c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois SP_hyp = 0x1f, 81288c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois SPSR_fiq = 0x2e, 81388c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois SPSR_irq = 0x30, 81488c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois SPSR_svc = 0x32, 81588c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois SPSR_abt = 0x34, 81688c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois SPSR_und = 0x36, 81788c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois SPSR_mon = 0x3c, 81888c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois SPSR_hyp = 0x3e 81988c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois}; 82088c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois 82188c46b84df005638546de5e4e965bdcc31352f48Pierre Langloisclass BankedRegister { 82288c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois uint32_t reg_; 82388c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois 82488c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois public: 82588c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois explicit BankedRegister(unsigned reg) : reg_(reg) {} 82660241a544be0ebf48347789bf0ec268414364627Vincent Belliard BankedRegister(BankedRegisterType reg) // NOLINT(runtime/explicit) 82760241a544be0ebf48347789bf0ec268414364627Vincent Belliard : reg_(reg) {} 82888c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois uint32_t GetCode() const { return reg_; } 82988c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois const char* GetName() const; 83088c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois}; 83188c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois 83288c46b84df005638546de5e4e965bdcc31352f48Pierre Langloisinline std::ostream& operator<<(std::ostream& os, BankedRegister reg) { 83388c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois return os << reg.GetName(); 83488c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois} 83588c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois 83688c46b84df005638546de5e4e965bdcc31352f48Pierre Langloisenum MaskedSpecialRegisterType { 83788c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois APSR_nzcvq = 0x08, 83888c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois APSR_g = 0x04, 83988c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois APSR_nzcvqg = 0x0c, 84088c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois CPSR_c = 0x01, 84188c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois CPSR_x = 0x02, 84288c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois CPSR_xc = 0x03, 84388c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois CPSR_s = APSR_g, 84488c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois CPSR_sc = 0x05, 84588c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois CPSR_sx = 0x06, 84688c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois CPSR_sxc = 0x07, 84788c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois CPSR_f = APSR_nzcvq, 84888c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois CPSR_fc = 0x09, 84988c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois CPSR_fx = 0x0a, 85088c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois CPSR_fxc = 0x0b, 85188c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois CPSR_fs = APSR_nzcvqg, 85288c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois CPSR_fsc = 0x0d, 85388c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois CPSR_fsx = 0x0e, 85488c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois CPSR_fsxc = 0x0f, 85588c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois SPSR_c = 0x11, 85688c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois SPSR_x = 0x12, 85788c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois SPSR_xc = 0x13, 85888c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois SPSR_s = 0x14, 85988c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois SPSR_sc = 0x15, 86088c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois SPSR_sx = 0x16, 86188c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois SPSR_sxc = 0x17, 86288c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois SPSR_f = 0x18, 86388c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois SPSR_fc = 0x19, 86488c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois SPSR_fx = 0x1a, 86588c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois SPSR_fxc = 0x1b, 86688c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois SPSR_fs = 0x1c, 86788c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois SPSR_fsc = 0x1d, 86888c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois SPSR_fsx = 0x1e, 86988c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois SPSR_fsxc = 0x1f 87088c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois}; 87188c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois 87288c46b84df005638546de5e4e965bdcc31352f48Pierre Langloisclass MaskedSpecialRegister { 87388c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois uint32_t reg_; 87488c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois 87588c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois public: 87688c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois explicit MaskedSpecialRegister(uint32_t reg) : reg_(reg) { 87788c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois VIXL_ASSERT(reg <= SPSR_fsxc); 87888c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois } 87960241a544be0ebf48347789bf0ec268414364627Vincent Belliard MaskedSpecialRegister( 88060241a544be0ebf48347789bf0ec268414364627Vincent Belliard MaskedSpecialRegisterType reg) // NOLINT(runtime/explicit) 88188c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois : reg_(reg) {} 88288c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois uint32_t GetReg() const { return reg_; } 88388c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois const char* GetName() const; 88488c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois bool Is(MaskedSpecialRegister value) const { return reg_ == value.reg_; } 88588c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois bool Is(uint32_t value) const { return reg_ == value; } 88688c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois bool IsNot(uint32_t value) const { return reg_ != value; } 88788c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois}; 88888c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois 88988c46b84df005638546de5e4e965bdcc31352f48Pierre Langloisinline std::ostream& operator<<(std::ostream& os, MaskedSpecialRegister reg) { 89088c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois return os << reg.GetName(); 89188c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois} 89288c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois 89388c46b84df005638546de5e4e965bdcc31352f48Pierre Langloisenum SpecialFPRegisterType { 89488c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois FPSID = 0x0, 89588c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois FPSCR = 0x1, 89688c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois MVFR2 = 0x5, 89788c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois MVFR1 = 0x6, 89888c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois MVFR0 = 0x7, 89988c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois FPEXC = 0x8 90088c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois}; 90188c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois 90288c46b84df005638546de5e4e965bdcc31352f48Pierre Langloisclass SpecialFPRegister { 90388c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois uint32_t reg_; 90488c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois 90588c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois public: 90688c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois explicit SpecialFPRegister(uint32_t reg) : reg_(reg) { 90788c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois#ifdef VIXL_DEBUG 90888c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois switch (reg) { 90988c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois case FPSID: 91088c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois case FPSCR: 91188c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois case MVFR2: 91288c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois case MVFR1: 91388c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois case MVFR0: 91488c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois case FPEXC: 91588c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois break; 91688c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois default: 91788c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois VIXL_UNREACHABLE(); 91888c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois } 91988c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois#endif 92088c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois } 92160241a544be0ebf48347789bf0ec268414364627Vincent Belliard SpecialFPRegister(SpecialFPRegisterType reg) // NOLINT(runtime/explicit) 92260241a544be0ebf48347789bf0ec268414364627Vincent Belliard : reg_(reg) {} 92388c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois uint32_t GetReg() const { return reg_; } 92488c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois const char* GetName() const; 92588c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois bool Is(SpecialFPRegister value) const { return reg_ == value.reg_; } 92688c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois bool Is(uint32_t value) const { return reg_ == value; } 92788c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois bool IsNot(uint32_t value) const { return reg_ != value; } 92888c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois}; 92988c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois 93088c46b84df005638546de5e4e965bdcc31352f48Pierre Langloisinline std::ostream& operator<<(std::ostream& os, SpecialFPRegister reg) { 93188c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois return os << reg.GetName(); 93288c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois} 93388c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois 93488c46b84df005638546de5e4e965bdcc31352f48Pierre Langloisclass CRegister { 93588c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois uint32_t code_; 93688c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois 93788c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois public: 93888c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois explicit CRegister(uint32_t code) : code_(code) { 93988c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois VIXL_ASSERT(code < kNumberOfRegisters); 94088c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois } 94188c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois uint32_t GetCode() const { return code_; } 94288c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois bool Is(CRegister value) const { return code_ == value.code_; } 94388c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois}; 94488c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois 94588c46b84df005638546de5e4e965bdcc31352f48Pierre Langloisinline std::ostream& operator<<(std::ostream& os, const CRegister reg) { 94688c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois return os << "c" << reg.GetCode(); 94788c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois} 94888c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois 94988c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois// clang-format off 95088c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois#define CREGISTER_CODE_LIST(R) \ 95188c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois R(0) R(1) R(2) R(3) R(4) R(5) R(6) R(7) \ 95288c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois R(8) R(9) R(10) R(11) R(12) R(13) R(14) R(15) 95388c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois// clang-format on 95488c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois#define DEFINE_CREGISTER(N) const CRegister c##N(N); 95588c46b84df005638546de5e4e965bdcc31352f48Pierre LangloisCREGISTER_CODE_LIST(DEFINE_CREGISTER) 95688c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois 95788c46b84df005638546de5e4e965bdcc31352f48Pierre Langloisenum CoprocessorName { p10 = 10, p11 = 11, p14 = 14, p15 = 15 }; 95888c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois 95988c46b84df005638546de5e4e965bdcc31352f48Pierre Langloisclass Coprocessor { 96088c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois uint32_t coproc_; 96188c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois 96288c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois public: 96388c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois explicit Coprocessor(uint32_t coproc) : coproc_(coproc) {} 96460241a544be0ebf48347789bf0ec268414364627Vincent Belliard Coprocessor(CoprocessorName coproc) // NOLINT(runtime/explicit) 96588c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois : coproc_(static_cast<uint32_t>(coproc)) {} 96688c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois bool Is(Coprocessor coproc) const { return coproc_ == coproc.coproc_; } 96788c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois bool Is(CoprocessorName coproc) const { return coproc_ == coproc; } 96888c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois uint32_t GetCoprocessor() const { return coproc_; } 96988c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois}; 97088c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois 97188c46b84df005638546de5e4e965bdcc31352f48Pierre Langloisinline std::ostream& operator<<(std::ostream& os, Coprocessor coproc) { 97288c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois return os << "p" << coproc.GetCoprocessor(); 97388c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois} 97488c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois 97588c46b84df005638546de5e4e965bdcc31352f48Pierre Langloisenum ConditionType { 97688c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois eq = 0, 97788c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois ne = 1, 97888c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois cs = 2, 97988c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois cc = 3, 98088c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois mi = 4, 98188c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois pl = 5, 98288c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois vs = 6, 98388c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois vc = 7, 98488c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois hi = 8, 98588c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois ls = 9, 98688c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois ge = 10, 98788c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois lt = 11, 98888c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois gt = 12, 98988c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois le = 13, 99088c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois al = 14, 99188c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois hs = cs, 99288c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois lo = cc 99388c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois}; 99488c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois 99588c46b84df005638546de5e4e965bdcc31352f48Pierre Langloisclass Condition { 99688c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois uint32_t condition_; 99788c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois static const uint32_t kNever = 15; 99888c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois static const uint32_t kMask = 0xf; 999fad350715bbb9f13ea85c84da4e6095dfee3cd15Vincent Belliard static const uint32_t kNone = 0x10 | al; 100088c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois 100188c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois public: 1002fad350715bbb9f13ea85c84da4e6095dfee3cd15Vincent Belliard static const Condition None() { return Condition(kNone); } 100388c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois explicit Condition(uint32_t condition) : condition_(condition) { 100488c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois VIXL_ASSERT(condition <= kNone); 100588c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois } 100660241a544be0ebf48347789bf0ec268414364627Vincent Belliard Condition(ConditionType condition) // NOLINT(runtime/explicit) 100760241a544be0ebf48347789bf0ec268414364627Vincent Belliard : condition_(condition) {} 100888c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois uint32_t GetCondition() const { return condition_ & kMask; } 100988c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois bool IsNone() const { return condition_ == kNone; } 101088c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois const char* GetName() const; 101188c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois bool Is(Condition value) const { return condition_ == value.condition_; } 101288c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois bool Is(uint32_t value) const { return condition_ == value; } 101388c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois bool IsNot(uint32_t value) const { return condition_ != value; } 101488c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois bool IsNever() const { return condition_ == kNever; } 101588c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois bool IsNotNever() const { return condition_ != kNever; } 101688c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois Condition Negate() const { 101788c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois VIXL_ASSERT(IsNot(al) && IsNot(kNever)); 101888c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois return Condition(condition_ ^ 1); 101988c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois } 102088c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois}; 102188c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois 102288c46b84df005638546de5e4e965bdcc31352f48Pierre Langloisinline std::ostream& operator<<(std::ostream& os, Condition condition) { 102388c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois return os << condition.GetName(); 102488c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois} 102588c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois 102688c46b84df005638546de5e4e965bdcc31352f48Pierre Langloisenum SignType { plus, minus }; 102788c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois 102888c46b84df005638546de5e4e965bdcc31352f48Pierre Langloisclass Sign { 102988c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois public: 103088c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois Sign() : sign_(plus) {} 103160241a544be0ebf48347789bf0ec268414364627Vincent Belliard Sign(SignType sign) : sign_(sign) {} // NOLINT(runtime/explicit) 103288c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois const char* GetName() const { return (IsPlus() ? "" : "-"); } 103388c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois bool IsPlus() const { return sign_ == plus; } 103488c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois bool IsMinus() const { return sign_ == minus; } 103588c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois int32_t ApplyTo(uint32_t value) { return IsPlus() ? value : -value; } 103688c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois 103788c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois private: 103888c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois SignType sign_; 103988c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois}; 104088c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois 104188c46b84df005638546de5e4e965bdcc31352f48Pierre Langloisinline std::ostream& operator<<(std::ostream& os, Sign sign) { 104288c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois return os << sign.GetName(); 104388c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois} 104488c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois 104588c46b84df005638546de5e4e965bdcc31352f48Pierre Langloisenum ShiftType { LSL = 0x0, LSR = 0x1, ASR = 0x2, ROR = 0x3, RRX = 0x4 }; 104688c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois 104788c46b84df005638546de5e4e965bdcc31352f48Pierre Langloisclass Shift { 104888c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois public: 104988c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois Shift() : shift_(LSL) {} 105060241a544be0ebf48347789bf0ec268414364627Vincent Belliard Shift(ShiftType shift) : shift_(shift) {} // NOLINT(runtime/explicit) 105188c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois explicit Shift(uint32_t shift) : shift_(static_cast<ShiftType>(shift)) {} 105288c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois const Shift& GetShift() const { return *this; } 105388c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois ShiftType GetType() const { return shift_; } 105488c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois uint32_t GetValue() const { return shift_; } 105588c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois const char* GetName() const; 105688c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois bool IsLSL() const { return shift_ == LSL; } 105788c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois bool IsLSR() const { return shift_ == LSR; } 105888c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois bool IsASR() const { return shift_ == ASR; } 105988c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois bool IsROR() const { return shift_ == ROR; } 106088c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois bool IsRRX() const { return shift_ == RRX; } 106188c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois bool Is(Shift value) const { return shift_ == value.shift_; } 106288c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois bool IsNot(Shift value) const { return shift_ != value.shift_; } 106388c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois bool IsValidAmount(uint32_t amount) const; 106488c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois static const Shift NoShift; 106588c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois 106688c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois protected: 106788c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois void SetType(ShiftType s) { shift_ = s; } 106888c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois 106988c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois private: 107088c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois ShiftType shift_; 107188c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois}; 107288c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois 107388c46b84df005638546de5e4e965bdcc31352f48Pierre Langloisinline std::ostream& operator<<(std::ostream& os, Shift shift) { 107488c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois return os << shift.GetName(); 107588c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois} 107688c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois 107788c46b84df005638546de5e4e965bdcc31352f48Pierre Langloisclass ImmediateShiftOperand : public Shift { 107888c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois public: 107988c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois // Constructor used for assembly. 108088c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois ImmediateShiftOperand(Shift shift, uint32_t amount) 108188c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois : Shift(shift), amount_(amount) { 108288c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois#ifdef VIXL_DEBUG 108388c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois switch (shift.GetType()) { 108488c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois case LSL: 108588c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois VIXL_ASSERT(amount <= 31); 108688c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois break; 108788c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois case ROR: 108888c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois VIXL_ASSERT(amount > 0); 108988c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois VIXL_ASSERT(amount <= 31); 109088c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois break; 109188c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois case LSR: 109288c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois case ASR: 109388c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois VIXL_ASSERT(amount > 0); 109488c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois VIXL_ASSERT(amount <= 32); 109588c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois break; 109688c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois case RRX: 109788c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois VIXL_ASSERT(amount == 0); 109888c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois break; 109988c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois default: 110088c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois VIXL_UNREACHABLE(); 110188c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois break; 110288c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois } 110388c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois#endif 110488c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois } 110588c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois // Constructor used for disassembly. 110688c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois ImmediateShiftOperand(int shift, int amount); 110788c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois uint32_t GetAmount() const { return amount_; } 110888c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois bool Is(const ImmediateShiftOperand& rhs) const { 110988c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois return amount_ == (rhs.amount_) && Shift::Is(*this); 111088c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois } 111188c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois 111288c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois private: 111388c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois uint32_t amount_; 111488c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois}; 111588c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois 111688c46b84df005638546de5e4e965bdcc31352f48Pierre Langloisinline std::ostream& operator<<(std::ostream& os, 111788c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois ImmediateShiftOperand const& shift_operand) { 111888c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois if (shift_operand.IsLSL() && shift_operand.GetAmount() == 0) return os; 111988c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois if (shift_operand.IsRRX()) return os << ", rrx"; 112088c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois return os << ", " << shift_operand.GetName() << " #" 112188c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois << shift_operand.GetAmount(); 112288c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois} 112388c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois 112488c46b84df005638546de5e4e965bdcc31352f48Pierre Langloisclass RegisterShiftOperand : public Shift { 112588c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois public: 112688c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois RegisterShiftOperand(ShiftType shift, Register shift_register) 112788c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois : Shift(shift), shift_register_(shift_register) { 112888c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois VIXL_ASSERT(!IsRRX() && shift_register_.IsValid()); 112988c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois } 113088c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois const Register GetShiftRegister() const { return shift_register_; } 113188c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois bool Is(const RegisterShiftOperand& rhs) const { 113288c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois return shift_register_.Is(rhs.shift_register_) && Shift::Is(*this); 113388c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois } 113488c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois 113588c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois private: 113688c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois Register shift_register_; 113788c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois}; 113888c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois 113988c46b84df005638546de5e4e965bdcc31352f48Pierre Langloisinline std::ostream& operator<<(std::ostream& s, 114088c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois const RegisterShiftOperand& shift_operand) { 114188c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois return s << shift_operand.GetName() << " " 114288c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois << shift_operand.GetShiftRegister(); 114388c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois} 114488c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois 114588c46b84df005638546de5e4e965bdcc31352f48Pierre Langloisenum EncodingSizeType { Best, Narrow, Wide }; 114688c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois 114788c46b84df005638546de5e4e965bdcc31352f48Pierre Langloisclass EncodingSize { 114888c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois uint32_t size_; 114988c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois 115088c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois public: 115188c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois explicit EncodingSize(uint32_t size) : size_(size) {} 115260241a544be0ebf48347789bf0ec268414364627Vincent Belliard EncodingSize(EncodingSizeType size) // NOLINT(runtime/explicit) 115360241a544be0ebf48347789bf0ec268414364627Vincent Belliard : size_(size) {} 115488c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois uint32_t GetSize() const { return size_; } 115588c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois const char* GetName() const; 115688c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois bool IsBest() const { return size_ == Best; } 115788c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois bool IsNarrow() const { return size_ == Narrow; } 115888c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois bool IsWide() const { return size_ == Wide; } 115988c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois}; 116088c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois 116188c46b84df005638546de5e4e965bdcc31352f48Pierre Langloisinline std::ostream& operator<<(std::ostream& os, EncodingSize size) { 116288c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois return os << size.GetName(); 116388c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois} 116488c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois 116588c46b84df005638546de5e4e965bdcc31352f48Pierre Langloisenum WriteBackValue { NO_WRITE_BACK, WRITE_BACK }; 116688c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois 116788c46b84df005638546de5e4e965bdcc31352f48Pierre Langloisclass WriteBack { 116888c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois WriteBackValue value_; 116988c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois 117088c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois public: 117160241a544be0ebf48347789bf0ec268414364627Vincent Belliard WriteBack(WriteBackValue value) // NOLINT(runtime/explicit) 117260241a544be0ebf48347789bf0ec268414364627Vincent Belliard : value_(value) {} 117388c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois explicit WriteBack(int value) 117488c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois : value_((value == 0) ? NO_WRITE_BACK : WRITE_BACK) {} 117588c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois uint32_t GetWriteBackUint32() const { return (value_ == WRITE_BACK) ? 1 : 0; } 117688c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois bool DoesWriteBack() const { return value_ == WRITE_BACK; } 117788c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois}; 117888c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois 117988c46b84df005638546de5e4e965bdcc31352f48Pierre Langloisinline std::ostream& operator<<(std::ostream& os, WriteBack write_back) { 118088c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois if (write_back.DoesWriteBack()) return os << "!"; 118188c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois return os; 118288c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois} 118388c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois 118488c46b84df005638546de5e4e965bdcc31352f48Pierre Langloisclass EncodingValue { 118588c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois bool valid_; 118688c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois uint32_t encoding_value_; 118788c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois 118888c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois public: 118988c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois EncodingValue() { 119088c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois valid_ = false; 119188c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois encoding_value_ = 0; 119288c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois } 119388c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois bool IsValid() const { return valid_; } 119488c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois uint32_t GetEncodingValue() const { return encoding_value_; } 119588c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois void SetEncodingValue(uint32_t encoding_value) { 119688c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois valid_ = true; 119788c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois encoding_value_ = encoding_value; 119888c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois } 119988c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois}; 120088c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois 120188c46b84df005638546de5e4e965bdcc31352f48Pierre Langloisclass EncodingValueAndImmediate : public EncodingValue { 120288c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois uint32_t encoded_immediate_; 120388c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois 120488c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois public: 120588c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois EncodingValueAndImmediate() { encoded_immediate_ = 0; } 120688c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois uint32_t GetEncodedImmediate() const { return encoded_immediate_; } 120788c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois void SetEncodedImmediate(uint32_t encoded_immediate) { 120888c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois encoded_immediate_ = encoded_immediate; 120988c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois } 121088c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois}; 121188c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois 121288c46b84df005638546de5e4e965bdcc31352f48Pierre Langloisclass ImmediateT32 : public EncodingValue { 121388c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois public: 121488c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois explicit ImmediateT32(uint32_t imm); 121588c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois static bool IsImmediateT32(uint32_t imm); 121688c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois static uint32_t Decode(uint32_t value); 121788c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois}; 121888c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois 121988c46b84df005638546de5e4e965bdcc31352f48Pierre Langloisclass ImmediateA32 : public EncodingValue { 122088c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois public: 122188c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois explicit ImmediateA32(uint32_t imm); 122288c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois static bool IsImmediateA32(uint32_t imm); 122388c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois static uint32_t Decode(uint32_t value); 122488c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois}; 122588c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois 122688c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois// Return the encoding value of a shift type. 122788c46b84df005638546de5e4e965bdcc31352f48Pierre Langloisuint32_t TypeEncodingValue(Shift shift); 122888c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois// Return the encoding value for a shift amount depending on the shift type. 122988c46b84df005638546de5e4e965bdcc31352f48Pierre Langloisuint32_t AmountEncodingValue(Shift shift, uint32_t amount); 123088c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois 123188c46b84df005638546de5e4e965bdcc31352f48Pierre Langloisenum MemoryBarrierType { 123288c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois OSHLD = 0x1, 123388c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois OSHST = 0x2, 123488c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois OSH = 0x3, 123588c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois NSHLD = 0x5, 123688c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois NSHST = 0x6, 123788c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois NSH = 0x7, 123888c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois ISHLD = 0x9, 123988c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois ISHST = 0xa, 124088c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois ISH = 0xb, 124188c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois LD = 0xd, 124288c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois ST = 0xe, 124388c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois SY = 0xf 124488c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois}; 124588c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois 124688c46b84df005638546de5e4e965bdcc31352f48Pierre Langloisclass MemoryBarrier { 124788c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois MemoryBarrierType type_; 124888c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois 124988c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois public: 125060241a544be0ebf48347789bf0ec268414364627Vincent Belliard MemoryBarrier(MemoryBarrierType type) // NOLINT(runtime/explicit) 125160241a544be0ebf48347789bf0ec268414364627Vincent Belliard : type_(type) {} 125260241a544be0ebf48347789bf0ec268414364627Vincent Belliard MemoryBarrier(uint32_t type) // NOLINT(runtime/explicit) 125388c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois : type_(static_cast<MemoryBarrierType>(type)) { 125488c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois VIXL_ASSERT((type & 0x3) != 0); 125588c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois } 125688c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois MemoryBarrierType GetType() const { return type_; } 125788c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois const char* GetName() const; 125888c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois}; 125988c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois 126088c46b84df005638546de5e4e965bdcc31352f48Pierre Langloisinline std::ostream& operator<<(std::ostream& os, MemoryBarrier option) { 126188c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois return os << option.GetName(); 126288c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois} 126388c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois 126488c46b84df005638546de5e4e965bdcc31352f48Pierre Langloisenum InterruptFlagsType { 126588c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois F = 0x1, 126688c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois I = 0x2, 126788c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois IF = 0x3, 126888c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois A = 0x4, 126988c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois AF = 0x5, 127088c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois AI = 0x6, 127188c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois AIF = 0x7 127288c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois}; 127388c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois 127488c46b84df005638546de5e4e965bdcc31352f48Pierre Langloisclass InterruptFlags { 127588c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois InterruptFlagsType type_; 127688c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois 127788c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois public: 127860241a544be0ebf48347789bf0ec268414364627Vincent Belliard InterruptFlags(InterruptFlagsType type) // NOLINT(runtime/explicit) 127960241a544be0ebf48347789bf0ec268414364627Vincent Belliard : type_(type) {} 128060241a544be0ebf48347789bf0ec268414364627Vincent Belliard InterruptFlags(uint32_t type) // NOLINT(runtime/explicit) 128188c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois : type_(static_cast<InterruptFlagsType>(type)) { 128288c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois VIXL_ASSERT(type <= 7); 128388c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois } 128488c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois InterruptFlagsType GetType() const { return type_; } 128588c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois const char* GetName() const; 128688c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois}; 128788c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois 128888c46b84df005638546de5e4e965bdcc31352f48Pierre Langloisinline std::ostream& operator<<(std::ostream& os, InterruptFlags option) { 128988c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois return os << option.GetName(); 129088c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois} 129188c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois 129288c46b84df005638546de5e4e965bdcc31352f48Pierre Langloisenum EndiannessType { LE = 0, BE = 1 }; 129388c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois 129488c46b84df005638546de5e4e965bdcc31352f48Pierre Langloisclass Endianness { 129588c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois EndiannessType type_; 129688c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois 129788c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois public: 129860241a544be0ebf48347789bf0ec268414364627Vincent Belliard Endianness(EndiannessType type) : type_(type) {} // NOLINT(runtime/explicit) 129960241a544be0ebf48347789bf0ec268414364627Vincent Belliard Endianness(uint32_t type) // NOLINT(runtime/explicit) 130088c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois : type_(static_cast<EndiannessType>(type)) { 130188c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois VIXL_ASSERT(type <= 1); 130288c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois } 130388c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois EndiannessType GetType() const { return type_; } 130488c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois const char* GetName() const; 130588c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois}; 130688c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois 130788c46b84df005638546de5e4e965bdcc31352f48Pierre Langloisinline std::ostream& operator<<(std::ostream& os, Endianness endian_specifier) { 130888c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois return os << endian_specifier.GetName(); 130988c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois} 131088c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois 131188c46b84df005638546de5e4e965bdcc31352f48Pierre Langloisenum AlignmentType { 131288c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois k16BitAlign = 0, 131388c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois k32BitAlign = 1, 131488c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois k64BitAlign = 2, 131588c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois k128BitAlign = 3, 131688c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois k256BitAlign = 4, 131788c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois kNoAlignment = 5, 131888c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois kBadAlignment = 6 131988c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois}; 132088c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois 132188c46b84df005638546de5e4e965bdcc31352f48Pierre Langloisclass Alignment { 132288c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois AlignmentType align_; 132388c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois 132488c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois public: 132588c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois Alignment(AlignmentType align) // NOLINT(runtime/explicit) 132688c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois : align_(align) {} 132788c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois Alignment(uint32_t align) // NOLINT(runtime/explicit) 132888c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois : align_(static_cast<AlignmentType>(align)) { 132988c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois VIXL_ASSERT(align <= static_cast<uint32_t>(k256BitAlign)); 133088c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois } 133188c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois AlignmentType GetType() const { return align_; } 133288c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois bool Is(AlignmentType type) { return align_ == type; } 133388c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois}; 133488c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois 133588c46b84df005638546de5e4e965bdcc31352f48Pierre Langloisinline std::ostream& operator<<(std::ostream& os, Alignment align) { 133688c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois if (align.GetType() == kBadAlignment) return os << " :??"; 133788c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois if (align.GetType() == kNoAlignment) return os; 133888c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois return os << " :" << (0x10 << static_cast<uint32_t>(align.GetType())); 133988c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois} 134088c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois 134188c46b84df005638546de5e4e965bdcc31352f48Pierre Langloisclass RawLiteral : public Label { 134288c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois public: 134351d1cccb2cbb843c41a586fbedad00ded8f0d6a0Vincent Belliard enum PlacementPolicy { kPlacedWhenUsed, kManuallyPlaced }; 134451d1cccb2cbb843c41a586fbedad00ded8f0d6a0Vincent Belliard 134588c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois enum DeletionPolicy { 134688c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois kDeletedOnPlacementByPool, 134788c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois kDeletedOnPoolDestruction, 134888c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois kManuallyDeleted 134988c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois }; 135088c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois 135188c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois public: 135288c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois RawLiteral(const void* addr, 135388c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois size_t size, 135451d1cccb2cbb843c41a586fbedad00ded8f0d6a0Vincent Belliard PlacementPolicy placement_policy = kPlacedWhenUsed, 135588c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois DeletionPolicy deletion_policy = kManuallyDeleted) 135688c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois : addr_(addr), 135788c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois size_(size), 135888c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois position_(kMaxOffset), 135951d1cccb2cbb843c41a586fbedad00ded8f0d6a0Vincent Belliard manually_placed_(placement_policy == kManuallyPlaced), 136051d1cccb2cbb843c41a586fbedad00ded8f0d6a0Vincent Belliard deletion_policy_(deletion_policy) {} 136151d1cccb2cbb843c41a586fbedad00ded8f0d6a0Vincent Belliard RawLiteral(const void* addr, size_t size, DeletionPolicy deletion_policy) 136251d1cccb2cbb843c41a586fbedad00ded8f0d6a0Vincent Belliard : addr_(addr), 136351d1cccb2cbb843c41a586fbedad00ded8f0d6a0Vincent Belliard size_(size), 136451d1cccb2cbb843c41a586fbedad00ded8f0d6a0Vincent Belliard position_(kMaxOffset), 136551d1cccb2cbb843c41a586fbedad00ded8f0d6a0Vincent Belliard manually_placed_(false), 136688c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois deletion_policy_(deletion_policy) {} 136788c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois ~RawLiteral() {} 136851d1cccb2cbb843c41a586fbedad00ded8f0d6a0Vincent Belliard const void* GetDataAddress() const { return addr_; } 136988c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois size_t GetSize() const { return size_; } 137088c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois size_t GetAlignedSize() const { return (size_ + 3) & ~0x3; } 137188c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois 137288c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois Offset GetPositionInPool() const { return position_; } 137388c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois void SetPositionInPool(Offset position_in_pool) { 137488c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois // Assumed that the literal has not already been added to 137588c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois // the pool. 137688c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois VIXL_ASSERT(position_ == Label::kMaxOffset); 137788c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois position_ = position_in_pool; 137888c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois } 137988c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois 138051d1cccb2cbb843c41a586fbedad00ded8f0d6a0Vincent Belliard bool IsManuallyPlaced() const { return manually_placed_; } 138151d1cccb2cbb843c41a586fbedad00ded8f0d6a0Vincent Belliard DeletionPolicy GetDeletionPolicy() const { return deletion_policy_; } 138251d1cccb2cbb843c41a586fbedad00ded8f0d6a0Vincent Belliard 138388c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois private: 138488c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois // Data address before it's moved into the code buffer. 138588c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois const void* const addr_; 138688c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois // Data size before it's moved into the code buffer. 138788c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois const size_t size_; 138888c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois // Position in the pool, if not in a pool: Label::kMaxOffset. 138988c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois Offset position_; 139051d1cccb2cbb843c41a586fbedad00ded8f0d6a0Vincent Belliard // When this flag is true, the label will be placed manually. 139151d1cccb2cbb843c41a586fbedad00ded8f0d6a0Vincent Belliard bool manually_placed_; 139288c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois // When is the literal to be removed from the memory 139388c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois // Can be delete'd when: 139488c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois // moved into the code buffer: kDeletedOnPlacementByPool 139588c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois // the pool is delete'd: kDeletedOnPoolDestruction 139688c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois // or left to the application: kManuallyDeleted. 139788c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois DeletionPolicy deletion_policy_; 139888c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois}; 139988c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois 140088c46b84df005638546de5e4e965bdcc31352f48Pierre Langloistemplate <typename T> 140188c46b84df005638546de5e4e965bdcc31352f48Pierre Langloisclass Literal : public RawLiteral { 140288c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois public: 140388c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois explicit Literal(const T& value, 140451d1cccb2cbb843c41a586fbedad00ded8f0d6a0Vincent Belliard PlacementPolicy placement_policy = kPlacedWhenUsed, 140588c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois DeletionPolicy deletion_policy = kManuallyDeleted) 140651d1cccb2cbb843c41a586fbedad00ded8f0d6a0Vincent Belliard : RawLiteral(&value_, sizeof(T), placement_policy, deletion_policy), 140751d1cccb2cbb843c41a586fbedad00ded8f0d6a0Vincent Belliard value_(value) {} 140851d1cccb2cbb843c41a586fbedad00ded8f0d6a0Vincent Belliard explicit Literal(const T& value, DeletionPolicy deletion_policy) 140988c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois : RawLiteral(&value_, sizeof(T), deletion_policy), value_(value) {} 14103e1b899f48c1328ac748b1f5fa78f417f7ec6581Vincent Belliard void UpdateValue(const T& value, CodeBuffer* buffer) { 14113e1b899f48c1328ac748b1f5fa78f417f7ec6581Vincent Belliard value_ = value; 14123e1b899f48c1328ac748b1f5fa78f417f7ec6581Vincent Belliard if (IsBound()) { 14133e1b899f48c1328ac748b1f5fa78f417f7ec6581Vincent Belliard buffer->UpdateData(GetLocation(), GetDataAddress(), GetSize()); 14143e1b899f48c1328ac748b1f5fa78f417f7ec6581Vincent Belliard } 14153e1b899f48c1328ac748b1f5fa78f417f7ec6581Vincent Belliard } 141688c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois 141788c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois private: 141888c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois T value_; 141988c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois}; 142088c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois 142125e3987b3b684df88edc8069d60b483b95587be5Pierre Langloisclass StringLiteral : public RawLiteral { 142288c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois public: 142325e3987b3b684df88edc8069d60b483b95587be5Pierre Langlois explicit StringLiteral(const char* str, 142425e3987b3b684df88edc8069d60b483b95587be5Pierre Langlois PlacementPolicy placement_policy = kPlacedWhenUsed, 142525e3987b3b684df88edc8069d60b483b95587be5Pierre Langlois DeletionPolicy deletion_policy = kManuallyDeleted) 142651d1cccb2cbb843c41a586fbedad00ded8f0d6a0Vincent Belliard : RawLiteral(str, strlen(str) + 1, placement_policy, deletion_policy) {} 142725e3987b3b684df88edc8069d60b483b95587be5Pierre Langlois explicit StringLiteral(const char* str, DeletionPolicy deletion_policy) 142888c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois : RawLiteral(str, strlen(str) + 1, deletion_policy) {} 142988c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois}; 143088c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois 143188c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois} // namespace aarch32 143288c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois} // namespace vixl 143388c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois 1434d3832965c62a8ad461b9ea9eb0994ca6b0a3da2cAlexandre Rames#endif // VIXL_AARCH32_INSTRUCTIONS_AARCH32_H_ 1435