instructions-aarch32.h revision fad350715bbb9f13ea85c84da4e6095dfee3cd15
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 15388c46b84df005638546de5e4e965bdcc31352f48Pierre Langloisclass RegisterOrAPSR_nzcv : public Register { 15488c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois public: 15588c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois explicit RegisterOrAPSR_nzcv(uint32_t code) : Register(code) {} 15688c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois}; 15788c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois 15888c46b84df005638546de5e4e965bdcc31352f48Pierre Langloisinline std::ostream& operator<<(std::ostream& os, 15988c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois const RegisterOrAPSR_nzcv reg) { 16088c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois if (reg.IsPC()) return os << "APSR_nzcv"; 16188c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois return os << Register(reg.GetCode()); 16288c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois} 16388c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois 16488c46b84df005638546de5e4e965bdcc31352f48Pierre Langloisclass SRegister; 16588c46b84df005638546de5e4e965bdcc31352f48Pierre Langloisclass DRegister; 16688c46b84df005638546de5e4e965bdcc31352f48Pierre Langloisclass QRegister; 16788c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois 16888c46b84df005638546de5e4e965bdcc31352f48Pierre Langloisclass VRegister : public CPURegister { 16988c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois public: 17088c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois VRegister() : CPURegister(kNoRegister, 0, 0) {} 17188c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois VRegister(RegisterType type, uint32_t code, int size) 17288c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois : CPURegister(type, code, size) {} 17388c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois 17488c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois SRegister S() const; 17588c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois DRegister D() const; 17688c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois QRegister Q() const; 17788c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois}; 17888c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois 17988c46b84df005638546de5e4e965bdcc31352f48Pierre Langloisclass SRegister : public VRegister { 18088c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois public: 18188c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois SRegister() : VRegister(kNoRegister, 0, kSRegSizeInBits) {} 18288c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois explicit SRegister(uint32_t code) 18388c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois : VRegister(kSRegister, code, kSRegSizeInBits) {} 18488c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois uint32_t Encode(int single_bit_field, int four_bit_field_lowest_bit) const { 18588c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois if (four_bit_field_lowest_bit == 0) { 18688c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois return ((GetCode() & 0x1) << single_bit_field) | 18788c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois ((GetCode() & 0x1e) >> 1); 18888c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois } 18988c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois return ((GetCode() & 0x1) << single_bit_field) | 19088c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois ((GetCode() & 0x1e) << (four_bit_field_lowest_bit - 1)); 19188c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois } 19288c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois}; 19388c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois 19488c46b84df005638546de5e4e965bdcc31352f48Pierre Langloisinline unsigned ExtractSRegister(uint32_t instr, 19588c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois int single_bit_field, 19688c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois int four_bit_field_lowest_bit) { 19788c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois VIXL_ASSERT(single_bit_field > 0); 19888c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois if (four_bit_field_lowest_bit == 0) { 19988c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois return ((instr << 1) & 0x1e) | ((instr >> single_bit_field) & 0x1); 20088c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois } 20188c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois return ((instr >> (four_bit_field_lowest_bit - 1)) & 0x1e) | 20288c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois ((instr >> single_bit_field) & 0x1); 20388c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois} 20488c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois 20588c46b84df005638546de5e4e965bdcc31352f48Pierre Langloisinline std::ostream& operator<<(std::ostream& os, const SRegister reg) { 20688c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois return os << "s" << reg.GetCode(); 20788c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois} 20888c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois 20988c46b84df005638546de5e4e965bdcc31352f48Pierre Langloisclass DRegister : public VRegister { 21088c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois public: 21188c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois DRegister() : VRegister(kNoRegister, 0, kDRegSizeInBits) {} 21288c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois explicit DRegister(uint32_t code) 21388c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois : VRegister(kDRegister, code, kDRegSizeInBits) {} 21497a5640aedb2d193ff27b9e7324a2412ed502a59Vincent Belliard SRegister GetLane(uint32_t lane) const { 21597a5640aedb2d193ff27b9e7324a2412ed502a59Vincent Belliard uint32_t lane_count = kDRegSizeInBits / kSRegSizeInBits; 21697a5640aedb2d193ff27b9e7324a2412ed502a59Vincent Belliard VIXL_ASSERT(lane < lane_count); 21797a5640aedb2d193ff27b9e7324a2412ed502a59Vincent Belliard VIXL_ASSERT(GetCode() * lane_count < kNumberOfSRegisters); 21897a5640aedb2d193ff27b9e7324a2412ed502a59Vincent Belliard return SRegister(GetCode() * lane_count + lane); 21997a5640aedb2d193ff27b9e7324a2412ed502a59Vincent Belliard } 22088c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois uint32_t Encode(int single_bit_field, int four_bit_field_lowest_bit) const { 22188c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois VIXL_ASSERT(single_bit_field >= 4); 22288c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois return ((GetCode() & 0x10) << (single_bit_field - 4)) | 22388c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois ((GetCode() & 0xf) << four_bit_field_lowest_bit); 22488c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois } 22588c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois}; 22688c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois 22788c46b84df005638546de5e4e965bdcc31352f48Pierre Langloisinline unsigned ExtractDRegister(uint32_t instr, 22888c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois int single_bit_field, 22988c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois int four_bit_field_lowest_bit) { 23088c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois VIXL_ASSERT(single_bit_field >= 4); 23188c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois return ((instr >> (single_bit_field - 4)) & 0x10) | 23288c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois ((instr >> four_bit_field_lowest_bit) & 0xf); 23388c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois} 23488c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois 23588c46b84df005638546de5e4e965bdcc31352f48Pierre Langloisinline std::ostream& operator<<(std::ostream& os, const DRegister reg) { 23688c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois return os << "d" << reg.GetCode(); 23788c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois} 23888c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois 23988c46b84df005638546de5e4e965bdcc31352f48Pierre Langloisenum DataTypeType { 24088c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois kDataTypeS = 0x100, 24188c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois kDataTypeU = 0x200, 24288c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois kDataTypeF = 0x300, 24388c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois kDataTypeI = 0x400, 24488c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois kDataTypeP = 0x500, 24588c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois kDataTypeUntyped = 0x600 24688c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois}; 24788c46b84df005638546de5e4e965bdcc31352f48Pierre Langloisconst int kDataTypeSizeMask = 0x0ff; 24888c46b84df005638546de5e4e965bdcc31352f48Pierre Langloisconst int kDataTypeTypeMask = 0x100; 24988c46b84df005638546de5e4e965bdcc31352f48Pierre Langloisenum DataTypeValue { 25088c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois kDataTypeValueInvalid = 0x000, 25188c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois kDataTypeValueNone = 0x001, // value used when dt is ignored. 25288c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois S8 = kDataTypeS | 8, 25388c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois S16 = kDataTypeS | 16, 25488c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois S32 = kDataTypeS | 32, 25588c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois S64 = kDataTypeS | 64, 25688c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois U8 = kDataTypeU | 8, 25788c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois U16 = kDataTypeU | 16, 25888c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois U32 = kDataTypeU | 32, 25988c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois U64 = kDataTypeU | 64, 26088c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois F16 = kDataTypeF | 16, 26188c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois F32 = kDataTypeF | 32, 26288c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois F64 = kDataTypeF | 64, 26388c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois I8 = kDataTypeI | 8, 26488c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois I16 = kDataTypeI | 16, 26588c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois I32 = kDataTypeI | 32, 26688c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois I64 = kDataTypeI | 64, 26788c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois P8 = kDataTypeP | 8, 26888c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois P64 = kDataTypeP | 64, 26988c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois Untyped8 = kDataTypeUntyped | 8, 27088c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois Untyped16 = kDataTypeUntyped | 16, 27188c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois Untyped32 = kDataTypeUntyped | 32, 27288c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois Untyped64 = kDataTypeUntyped | 64 27388c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois}; 27488c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois 27588c46b84df005638546de5e4e965bdcc31352f48Pierre Langloisclass DataType { 27688c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois DataTypeValue value_; 27788c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois 27888c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois public: 27988c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois DataType(DataTypeValue value) : value_(value) {} // NOLINT 28088c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois DataType(uint32_t size) // NOLINT 28188c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois : value_(static_cast<DataTypeValue>(kDataTypeUntyped | size)) { 28288c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois VIXL_ASSERT((size == 8) || (size == 16) || (size == 32) || (size == 64)); 28388c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois } 28488c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois DataTypeValue GetValue() const { return value_; } 28588c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois DataTypeType GetType() const { 28688c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois return static_cast<DataTypeType>(value_ & kDataTypeTypeMask); 28788c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois } 28888c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois uint32_t GetSize() const { return value_ & kDataTypeSizeMask; } 28988c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois bool IsSize(uint32_t size) const { 29088c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois return (value_ & kDataTypeSizeMask) == size; 29188c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois } 29288c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois const char* GetName() const; 29388c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois bool Is(DataTypeValue value) const { return value_ == value; } 29488c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois bool Is(DataTypeType type) const { return GetType() == type; } 29588c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois bool IsNoneOr(DataTypeValue value) const { 29688c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois return (value_ == value) || (value_ == kDataTypeValueNone); 29788c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois } 29888c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois bool Is(DataTypeType type, uint32_t size) const { 29988c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois return value_ == static_cast<DataTypeValue>(type | size); 30088c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois } 30188c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois bool IsNoneOr(DataTypeType type, uint32_t size) const { 30288c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois return Is(type, size) || Is(kDataTypeValueNone); 30388c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois } 30488c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois}; 30588c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois 30688c46b84df005638546de5e4e965bdcc31352f48Pierre Langloisinline std::ostream& operator<<(std::ostream& os, DataType dt) { 30788c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois return os << dt.GetName(); 30888c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois} 30988c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois 31088c46b84df005638546de5e4e965bdcc31352f48Pierre Langloisclass DRegisterLane : public DRegister { 31188c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois uint32_t lane_; 31288c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois 31388c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois public: 31488c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois DRegisterLane(DRegister reg, uint32_t lane) 31588c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois : DRegister(reg.GetCode()), lane_(lane) {} 31688c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois DRegisterLane(uint32_t code, uint32_t lane) : DRegister(code), lane_(lane) {} 31788c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois uint32_t GetLane() const { return lane_; } 31888c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois uint32_t EncodeX(DataType dt, 31988c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois int single_bit_field, 32088c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois int four_bit_field_lowest_bit) const { 32188c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois VIXL_ASSERT(single_bit_field >= 4); 32288c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois uint32_t value = lane_ << ((dt.GetSize() == 16) ? 3 : 4) | GetCode(); 32388c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois return ((value & 0x10) << (single_bit_field - 4)) | 32488c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois ((value & 0xf) << four_bit_field_lowest_bit); 32588c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois } 32688c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois}; 32788c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois 32888c46b84df005638546de5e4e965bdcc31352f48Pierre Langloisinline unsigned ExtractDRegisterAndLane(uint32_t instr, 32988c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois DataType dt, 33088c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois int single_bit_field, 33188c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois int four_bit_field_lowest_bit, 33288c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois int* lane) { 33388c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois VIXL_ASSERT(single_bit_field >= 4); 33488c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois uint32_t value = ((instr >> (single_bit_field - 4)) & 0x10) | 33588c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois ((instr >> four_bit_field_lowest_bit) & 0xf); 33688c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois if (dt.GetSize() == 16) { 33788c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois *lane = value >> 3; 33888c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois return value & 0x7; 33988c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois } 34088c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois *lane = value >> 4; 34188c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois return value & 0xf; 34288c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois} 34388c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois 34488c46b84df005638546de5e4e965bdcc31352f48Pierre Langloisinline std::ostream& operator<<(std::ostream& os, const DRegisterLane lane) { 34588c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois os << "d" << lane.GetCode() << "["; 34688c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois if (lane.GetLane() == static_cast<uint32_t>(-1)) return os << "??]"; 34788c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois return os << lane.GetLane() << "]"; 34888c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois} 34988c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois 35088c46b84df005638546de5e4e965bdcc31352f48Pierre Langloisclass QRegister : public VRegister { 35188c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois public: 35288c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois QRegister() : VRegister(kNoRegister, 0, kQRegSizeInBits) {} 35388c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois explicit QRegister(uint32_t code) 35488c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois : VRegister(kQRegister, code, kQRegSizeInBits) {} 35588c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois uint32_t Encode(int offset) { return GetCode() << offset; } 35697a5640aedb2d193ff27b9e7324a2412ed502a59Vincent Belliard DRegister GetDLane(uint32_t lane) const { 35797a5640aedb2d193ff27b9e7324a2412ed502a59Vincent Belliard uint32_t lane_count = kQRegSizeInBits / kDRegSizeInBits; 35897a5640aedb2d193ff27b9e7324a2412ed502a59Vincent Belliard VIXL_ASSERT(lane < lane_count); 35997a5640aedb2d193ff27b9e7324a2412ed502a59Vincent Belliard return DRegister(GetCode() * lane_count + lane); 36097a5640aedb2d193ff27b9e7324a2412ed502a59Vincent Belliard } 36188c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois DRegister GetLowDRegister() const { return DRegister(GetCode() * 2); } 36288c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois DRegister GetHighDRegister() const { return DRegister(1 + GetCode() * 2); } 36397a5640aedb2d193ff27b9e7324a2412ed502a59Vincent Belliard SRegister GetSLane(uint32_t lane) const { 36497a5640aedb2d193ff27b9e7324a2412ed502a59Vincent Belliard uint32_t lane_count = kQRegSizeInBits / kSRegSizeInBits; 36597a5640aedb2d193ff27b9e7324a2412ed502a59Vincent Belliard VIXL_ASSERT(lane < lane_count); 36697a5640aedb2d193ff27b9e7324a2412ed502a59Vincent Belliard VIXL_ASSERT(GetCode() * lane_count < kNumberOfSRegisters); 36797a5640aedb2d193ff27b9e7324a2412ed502a59Vincent Belliard return SRegister(GetCode() * lane_count + lane); 36897a5640aedb2d193ff27b9e7324a2412ed502a59Vincent Belliard } 36988c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois uint32_t Encode(int single_bit_field, int four_bit_field_lowest_bit) { 37088c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois // Encode "code * 2". 37188c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois VIXL_ASSERT(single_bit_field >= 3); 37288c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois return ((GetCode() & 0x8) << (single_bit_field - 3)) | 37388c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois ((GetCode() & 0x7) << (four_bit_field_lowest_bit + 1)); 37488c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois } 37588c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois}; 37688c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois 37788c46b84df005638546de5e4e965bdcc31352f48Pierre Langloisinline unsigned ExtractQRegister(uint32_t instr, 37888c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois int single_bit_field, 37988c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois int four_bit_field_lowest_bit) { 38088c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois VIXL_ASSERT(single_bit_field >= 3); 38188c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois return ((instr >> (single_bit_field - 3)) & 0x8) | 38288c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois ((instr >> (four_bit_field_lowest_bit + 1)) & 0x7); 38388c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois} 38488c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois 38588c46b84df005638546de5e4e965bdcc31352f48Pierre Langloisinline std::ostream& operator<<(std::ostream& os, const QRegister reg) { 38688c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois return os << "q" << reg.GetCode(); 38788c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois} 38888c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois 38988c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois// clang-format off 3901107e04f82d4809214ff6592b3727298dee1fe45Alexandre Rames#define AARCH32_REGISTER_CODE_LIST(R) \ 39188c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois R(0) R(1) R(2) R(3) R(4) R(5) R(6) R(7) \ 39288c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois R(8) R(9) R(10) R(11) R(12) R(13) R(14) R(15) 39388c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois// clang-format on 39488c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois#define DEFINE_REGISTER(N) const Register r##N(N); 3951107e04f82d4809214ff6592b3727298dee1fe45Alexandre RamesAARCH32_REGISTER_CODE_LIST(DEFINE_REGISTER) 39688c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois#undef DEFINE_REGISTER 3971107e04f82d4809214ff6592b3727298dee1fe45Alexandre Rames#undef AARCH32_REGISTER_CODE_LIST 39888c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois 39988c46b84df005638546de5e4e965bdcc31352f48Pierre Langloisenum RegNum { kIPRegNum = 12, kSPRegNum = 13, kLRRegNum = 14, kPCRegNum = 15 }; 40088c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois 40188c46b84df005638546de5e4e965bdcc31352f48Pierre Langloisconst Register ip(kIPRegNum); 40288c46b84df005638546de5e4e965bdcc31352f48Pierre Langloisconst Register sp(kSPRegNum); 40388c46b84df005638546de5e4e965bdcc31352f48Pierre Langloisconst Register pc(kPCRegNum); 40488c46b84df005638546de5e4e965bdcc31352f48Pierre Langloisconst Register lr(kLRRegNum); 40588c46b84df005638546de5e4e965bdcc31352f48Pierre Langloisconst Register NoReg; 40688c46b84df005638546de5e4e965bdcc31352f48Pierre Langloisconst VRegister NoVReg; 40788c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois 40888c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois// clang-format off 40988c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois#define SREGISTER_CODE_LIST(R) \ 41088c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois R(0) R(1) R(2) R(3) R(4) R(5) R(6) R(7) \ 41188c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois R(8) R(9) R(10) R(11) R(12) R(13) R(14) R(15) \ 41288c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois R(16) R(17) R(18) R(19) R(20) R(21) R(22) R(23) \ 41388c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois R(24) R(25) R(26) R(27) R(28) R(29) R(30) R(31) 41488c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois// clang-format on 41588c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois#define DEFINE_REGISTER(N) const SRegister s##N(N); 41688c46b84df005638546de5e4e965bdcc31352f48Pierre LangloisSREGISTER_CODE_LIST(DEFINE_REGISTER) 41788c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois#undef DEFINE_REGISTER 41888c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois#undef SREGISTER_CODE_LIST 41988c46b84df005638546de5e4e965bdcc31352f48Pierre Langloisconst SRegister NoSReg; 42088c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois 42188c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois// clang-format off 42288c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois#define DREGISTER_CODE_LIST(R) \ 42388c46b84df005638546de5e4e965bdcc31352f48Pierre LangloisR(0) R(1) R(2) R(3) R(4) R(5) R(6) R(7) \ 42488c46b84df005638546de5e4e965bdcc31352f48Pierre LangloisR(8) R(9) R(10) R(11) R(12) R(13) R(14) R(15) \ 42588c46b84df005638546de5e4e965bdcc31352f48Pierre LangloisR(16) R(17) R(18) R(19) R(20) R(21) R(22) R(23) \ 42688c46b84df005638546de5e4e965bdcc31352f48Pierre LangloisR(24) R(25) R(26) R(27) R(28) R(29) R(30) R(31) 42788c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois// clang-format on 42888c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois#define DEFINE_REGISTER(N) const DRegister d##N(N); 42988c46b84df005638546de5e4e965bdcc31352f48Pierre LangloisDREGISTER_CODE_LIST(DEFINE_REGISTER) 43088c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois#undef DEFINE_REGISTER 43188c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois#undef DREGISTER_CODE_LIST 43288c46b84df005638546de5e4e965bdcc31352f48Pierre Langloisconst DRegister NoDReg; 43388c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois 43488c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois// clang-format off 43588c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois#define QREGISTER_CODE_LIST(R) \ 43688c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois R(0) R(1) R(2) R(3) R(4) R(5) R(6) R(7) \ 43788c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois R(8) R(9) R(10) R(11) R(12) R(13) R(14) R(15) 43888c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois// clang-format on 43988c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois#define DEFINE_REGISTER(N) const QRegister q##N(N); 44088c46b84df005638546de5e4e965bdcc31352f48Pierre LangloisQREGISTER_CODE_LIST(DEFINE_REGISTER) 44188c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois#undef DEFINE_REGISTER 44288c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois#undef QREGISTER_CODE_LIST 44388c46b84df005638546de5e4e965bdcc31352f48Pierre Langloisconst QRegister NoQReg; 44488c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois 44588c46b84df005638546de5e4e965bdcc31352f48Pierre Langloisclass RegisterList { 44688c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois public: 44788c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois RegisterList() : list_(0) {} 44888c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois RegisterList(Register reg) : list_(RegisterToList(reg)) {} // NOLINT 44988c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois RegisterList(Register reg1, Register reg2) 45088c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois : list_(RegisterToList(reg1) | RegisterToList(reg2)) {} 45188c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois RegisterList(Register reg1, Register reg2, Register reg3) 45288c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois : list_(RegisterToList(reg1) | RegisterToList(reg2) | 45388c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois RegisterToList(reg3)) {} 45488c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois RegisterList(Register reg1, Register reg2, Register reg3, Register reg4) 45588c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois : list_(RegisterToList(reg1) | RegisterToList(reg2) | 45688c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois RegisterToList(reg3) | RegisterToList(reg4)) {} 45788c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois explicit RegisterList(uint32_t list) : list_(list) {} 45888c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois uint32_t GetList() const { return list_; } 45988c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois void SetList(uint32_t list) { list_ = list; } 46088c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois bool Includes(const Register& reg) const { 46188c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois return (list_ & RegisterToList(reg)) != 0; 46288c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois } 46388c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois void Combine(const RegisterList& other) { list_ |= other.GetList(); } 46488c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois void Combine(const Register& reg) { list_ |= RegisterToList(reg); } 46588c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois void Remove(const RegisterList& other) { list_ &= ~other.GetList(); } 46688c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois void Remove(const Register& reg) { list_ &= ~RegisterToList(reg); } 46788c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois bool Overlaps(const RegisterList& other) const { 46888c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois return (list_ & other.list_) != 0; 46988c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois } 47088c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois bool IsR0toR7orPC() const { 47188c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois // True if all the registers from the list are not from r8-r14. 47288c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois return (list_ & 0x7f00) == 0; 47388c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois } 47488c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois bool IsR0toR7orLR() const { 47588c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois // True if all the registers from the list are not from r8-r13 nor from r15. 47688c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois return (list_ & 0xbf00) == 0; 47788c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois } 47888c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois Register GetFirstAvailableRegister() const; 47988c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois bool IsEmpty() const { return list_ == 0; } 48088c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois static RegisterList Union(const RegisterList& list_1, 48188c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois const RegisterList& list_2) { 48288c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois return RegisterList(list_1.list_ | list_2.list_); 48388c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois } 48488c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois static RegisterList Union(const RegisterList& list_1, 48588c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois const RegisterList& list_2, 48688c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois const RegisterList& list_3) { 48788c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois return Union(list_1, Union(list_2, list_3)); 48888c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois } 48988c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois static RegisterList Union(const RegisterList& list_1, 49088c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois const RegisterList& list_2, 49188c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois const RegisterList& list_3, 49288c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois const RegisterList& list_4) { 49388c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois return Union(Union(list_1, list_2), Union(list_3, list_4)); 49488c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois } 49588c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois static RegisterList Intersection(const RegisterList& list_1, 49688c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois const RegisterList& list_2) { 49788c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois return RegisterList(list_1.list_ & list_2.list_); 49888c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois } 49988c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois static RegisterList Intersection(const RegisterList& list_1, 50088c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois const RegisterList& list_2, 50188c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois const RegisterList& list_3) { 50288c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois return Intersection(list_1, Intersection(list_2, list_3)); 50388c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois } 50488c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois static RegisterList Intersection(const RegisterList& list_1, 50588c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois const RegisterList& list_2, 50688c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois const RegisterList& list_3, 50788c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois const RegisterList& list_4) { 50888c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois return Intersection(Intersection(list_1, list_2), 50988c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois Intersection(list_3, list_4)); 51088c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois } 51188c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois 51288c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois private: 51388c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois static uint32_t RegisterToList(Register reg) { 51488c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois if (reg.GetType() == CPURegister::kNoRegister) { 51588c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois return 0; 51688c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois } else { 51788c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois return UINT32_C(1) << reg.GetCode(); 51888c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois } 51988c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois } 52088c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois 52188c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois // Bitfield representation of all registers in the list 52288c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois // (1 for r0, 2 for r1, 4 for r2, ...). 52388c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois uint32_t list_; 52488c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois}; 52588c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois 52688c46b84df005638546de5e4e965bdcc31352f48Pierre Langloisinline uint32_t GetRegisterListEncoding(const RegisterList& registers, 52788c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois int first, 52888c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois int count) { 52988c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois return (registers.GetList() >> first) & ((1 << count) - 1); 53088c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois} 53188c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois 53288c46b84df005638546de5e4e965bdcc31352f48Pierre Langloisstd::ostream& operator<<(std::ostream& os, RegisterList registers); 53388c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois 53488c46b84df005638546de5e4e965bdcc31352f48Pierre Langloisclass VRegisterList { 53588c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois public: 53688c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois VRegisterList() : list_(0) {} 53788c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois explicit VRegisterList(VRegister reg) : list_(RegisterToList(reg)) {} 53888c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois VRegisterList(VRegister reg1, VRegister reg2) 53988c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois : list_(RegisterToList(reg1) | RegisterToList(reg2)) {} 54088c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois VRegisterList(VRegister reg1, VRegister reg2, VRegister reg3) 54188c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois : list_(RegisterToList(reg1) | RegisterToList(reg2) | 54288c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois RegisterToList(reg3)) {} 54388c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois VRegisterList(VRegister reg1, VRegister reg2, VRegister reg3, VRegister reg4) 54488c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois : list_(RegisterToList(reg1) | RegisterToList(reg2) | 54588c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois RegisterToList(reg3) | RegisterToList(reg4)) {} 54688c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois explicit VRegisterList(uint64_t list) : list_(list) {} 54788c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois uint64_t GetList() const { return list_; } 54888c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois void SetList(uint64_t list) { list_ = list; } 54988c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois bool Includes(const VRegister& reg) const { 55088c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois return (list_ & RegisterToList(reg)) != 0; 55188c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois } 55288c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois void Combine(const VRegisterList& other) { list_ |= other.GetList(); } 55388c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois void Combine(const VRegister& reg) { list_ |= RegisterToList(reg); } 55488c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois void Remove(const VRegisterList& other) { list_ &= ~other.GetList(); } 55588c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois void Remove(const VRegister& reg) { list_ &= ~RegisterToList(reg); } 55688c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois bool Overlaps(const VRegisterList& other) const { 55788c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois return (list_ & other.list_) != 0; 55888c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois } 55988c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois QRegister GetFirstAvailableQRegister() const; 56088c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois DRegister GetFirstAvailableDRegister() const; 56188c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois SRegister GetFirstAvailableSRegister() const; 56288c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois bool IsEmpty() const { return list_ == 0; } 56388c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois static VRegisterList Union(const VRegisterList& list_1, 56488c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois const VRegisterList& list_2) { 56588c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois return VRegisterList(list_1.list_ | list_2.list_); 56688c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois } 56788c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois static VRegisterList Union(const VRegisterList& list_1, 56888c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois const VRegisterList& list_2, 56988c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois const VRegisterList& list_3) { 57088c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois return Union(list_1, Union(list_2, list_3)); 57188c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois } 57288c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois static VRegisterList Union(const VRegisterList& list_1, 57388c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois const VRegisterList& list_2, 57488c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois const VRegisterList& list_3, 57588c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois const VRegisterList& list_4) { 57688c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois return Union(Union(list_1, list_2), Union(list_3, list_4)); 57788c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois } 57888c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois static VRegisterList Intersection(const VRegisterList& list_1, 57988c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois const VRegisterList& list_2) { 58088c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois return VRegisterList(list_1.list_ & list_2.list_); 58188c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois } 58288c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois static VRegisterList Intersection(const VRegisterList& list_1, 58388c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois const VRegisterList& list_2, 58488c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois const VRegisterList& list_3) { 58588c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois return Intersection(list_1, Intersection(list_2, list_3)); 58688c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois } 58788c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois static VRegisterList Intersection(const VRegisterList& list_1, 58888c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois const VRegisterList& list_2, 58988c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois const VRegisterList& list_3, 59088c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois const VRegisterList& list_4) { 59188c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois return Intersection(Intersection(list_1, list_2), 59288c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois Intersection(list_3, list_4)); 59388c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois } 59488c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois 59588c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois private: 59688c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois static uint64_t RegisterToList(VRegister reg) { 59788c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois if (reg.GetType() == CPURegister::kNoRegister) { 59888c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois return 0; 59988c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois } else { 60088c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois switch (reg.GetSizeInBits()) { 60188c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois case kQRegSizeInBits: 60288c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois return UINT64_C(0xf) << (reg.GetCode() * 4); 60388c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois case kDRegSizeInBits: 60488c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois return UINT64_C(0x3) << (reg.GetCode() * 2); 60588c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois case kSRegSizeInBits: 60688c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois return UINT64_C(0x1) << reg.GetCode(); 60788c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois default: 60888c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois VIXL_UNREACHABLE(); 60988c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois return 0; 61088c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois } 61188c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois } 61288c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois } 61388c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois 61488c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois // Bitfield representation of all registers in the list. 61588c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois // (0x3 for d0, 0xc0 for d1, 0x30 for d2, ...). We have one, two or four bits 61688c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois // per register according to their size. This way we can make sure that we 61788c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois // account for overlapping registers. A register is included in this list if 61888c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois // any of its bits are set. For example, adding s3 to the list implies d1 and 61988c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois // q0. 62088c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois uint64_t list_; 62188c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois}; 62288c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois 62388c46b84df005638546de5e4e965bdcc31352f48Pierre Langloisclass SRegisterList { 62471bca307f4e94afdbc753e02c101b042cd218b4aPierre Langlois SRegister first_; 62571bca307f4e94afdbc753e02c101b042cd218b4aPierre Langlois int length_; 62688c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois 62788c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois public: 62871bca307f4e94afdbc753e02c101b042cd218b4aPierre Langlois explicit SRegisterList(SRegister reg) : first_(reg.GetCode()), length_(1) {} 62971bca307f4e94afdbc753e02c101b042cd218b4aPierre Langlois SRegisterList(SRegister first, int length) 63071bca307f4e94afdbc753e02c101b042cd218b4aPierre Langlois : first_(first.GetCode()), length_(length) { 63171bca307f4e94afdbc753e02c101b042cd218b4aPierre Langlois VIXL_ASSERT(length >= 0); 63288c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois } 63388c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois const SRegister& GetFirstSRegister() const { return first_; } 63471bca307f4e94afdbc753e02c101b042cd218b4aPierre Langlois const SRegister GetLastSRegister() const { 635260c6b6a014af9932f308fa53b82fb2ada3acba8Vincent Belliard return SRegister((first_.GetCode() + length_ - 1) % kNumberOfSRegisters); 63671bca307f4e94afdbc753e02c101b042cd218b4aPierre Langlois } 63771bca307f4e94afdbc753e02c101b042cd218b4aPierre Langlois int GetLength() const { return length_; } 63888c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois}; 63988c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois 64088c46b84df005638546de5e4e965bdcc31352f48Pierre Langloisstd::ostream& operator<<(std::ostream& os, SRegisterList registers); 64188c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois 64288c46b84df005638546de5e4e965bdcc31352f48Pierre Langloisclass DRegisterList { 64371bca307f4e94afdbc753e02c101b042cd218b4aPierre Langlois DRegister first_; 64471bca307f4e94afdbc753e02c101b042cd218b4aPierre Langlois int length_; 64588c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois 64688c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois public: 64771bca307f4e94afdbc753e02c101b042cd218b4aPierre Langlois explicit DRegisterList(DRegister reg) : first_(reg.GetCode()), length_(1) {} 64871bca307f4e94afdbc753e02c101b042cd218b4aPierre Langlois DRegisterList(DRegister first, int length) 64971bca307f4e94afdbc753e02c101b042cd218b4aPierre Langlois : first_(first.GetCode()), length_(length) { 65071bca307f4e94afdbc753e02c101b042cd218b4aPierre Langlois VIXL_ASSERT(length >= 0); 65188c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois } 65288c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois const DRegister& GetFirstDRegister() const { return first_; } 65371bca307f4e94afdbc753e02c101b042cd218b4aPierre Langlois const DRegister GetLastDRegister() const { 654260c6b6a014af9932f308fa53b82fb2ada3acba8Vincent Belliard return DRegister((first_.GetCode() + length_ - 1) % kMaxNumberOfDRegisters); 65571bca307f4e94afdbc753e02c101b042cd218b4aPierre Langlois } 65671bca307f4e94afdbc753e02c101b042cd218b4aPierre Langlois int GetLength() const { return length_; } 65788c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois}; 65888c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois 65988c46b84df005638546de5e4e965bdcc31352f48Pierre Langloisstd::ostream& operator<<(std::ostream& os, DRegisterList registers); 66088c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois 66188c46b84df005638546de5e4e965bdcc31352f48Pierre Langloisenum SpacingType { kSingle, kDouble }; 66288c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois 66388c46b84df005638546de5e4e965bdcc31352f48Pierre Langloisenum TransferType { kMultipleLanes, kOneLane, kAllLanes }; 66488c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois 66588c46b84df005638546de5e4e965bdcc31352f48Pierre Langloisclass NeonRegisterList { 66688c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois DRegister first_, last_; 66788c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois SpacingType spacing_; 66888c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois TransferType type_; 66988c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois int lane_; 67088c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois 67188c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois public: 67288c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois NeonRegisterList(DRegister reg, TransferType type) 67388c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois : first_(reg.GetCode()), 67488c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois last_(reg.GetCode()), 67588c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois spacing_(kSingle), 67688c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois type_(type), 67788c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois lane_(-1) { 67888c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois VIXL_ASSERT(type_ != kOneLane); 67988c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois } 68088c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois NeonRegisterList(DRegister reg, int lane) 68188c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois : first_(reg.GetCode()), 68288c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois last_(reg.GetCode()), 68388c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois spacing_(kSingle), 68488c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois type_(kOneLane), 68588c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois lane_(lane) { 68688c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois VIXL_ASSERT((lane_ >= 0) && (lane_ < 4)); 68788c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois } 68888c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois NeonRegisterList(DRegister first, 68988c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois DRegister last, 69088c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois SpacingType spacing, 69188c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois TransferType type) 69288c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois : first_(first.GetCode()), 69388c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois last_(last.GetCode()), 69488c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois spacing_(spacing), 69588c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois type_(type), 69688c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois lane_(-1) { 69788c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois VIXL_ASSERT(type_ != kOneLane); 69888c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois VIXL_ASSERT(first_.GetCode() <= last_.GetCode()); 69988c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois VIXL_ASSERT(GetLength() <= 4); 70088c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois VIXL_ASSERT((spacing_ == kSingle) || 70188c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois (((last_.GetCode() - first_.GetCode()) & 1) == 0)); 70288c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois } 70388c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois NeonRegisterList(DRegister first, 70488c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois DRegister last, 70588c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois SpacingType spacing, 70688c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois int lane) 70788c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois : first_(first.GetCode()), 70888c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois last_(last.GetCode()), 70988c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois spacing_(spacing), 71088c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois type_(kOneLane), 71188c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois lane_(lane) { 71288c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois VIXL_ASSERT((lane_ >= 0) && (lane_ < 4)); 71388c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois VIXL_ASSERT(first_.GetCode() <= last_.GetCode()); 71488c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois VIXL_ASSERT(GetLength() <= 4); 71588c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois VIXL_ASSERT((spacing_ == kSingle) || 71688c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois (((last_.GetCode() - first_.GetCode()) & 1) == 0)); 71788c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois } 71888c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois const DRegister& GetFirstDRegister() const { return first_; } 71988c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois const DRegister& GetLastDRegister() const { return last_; } 72088c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois uint32_t GetLength() const { 72188c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois uint32_t length = 72288c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois (last_.GetCode() - first_.GetCode()) % kMaxNumberOfDRegisters; 72388c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois if (spacing_ == kDouble) length /= 2; 72488c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois return 1 + length; 72588c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois } 72688c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois bool IsSingleSpaced() const { return spacing_ == kSingle; } 72788c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois bool IsDoubleSpaced() const { return spacing_ == kDouble; } 72888c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois bool IsTransferAllLanes() const { return type_ == kAllLanes; } 72988c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois bool IsTransferOneLane() const { return type_ == kOneLane; } 73088c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois bool IsTransferMultipleLanes() const { return type_ == kMultipleLanes; } 73188c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois int GetTransferLane() const { return lane_; } 73288c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois}; 73388c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois 73488c46b84df005638546de5e4e965bdcc31352f48Pierre Langloisstd::ostream& operator<<(std::ostream& os, NeonRegisterList registers); 73588c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois 73688c46b84df005638546de5e4e965bdcc31352f48Pierre Langloisenum SpecialRegisterType { APSR = 0, CPSR = 0, SPSR = 1 }; 73788c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois 73888c46b84df005638546de5e4e965bdcc31352f48Pierre Langloisclass SpecialRegister { 73988c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois uint32_t reg_; 74088c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois 74188c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois public: 74288c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois explicit SpecialRegister(uint32_t reg) : reg_(reg) {} 74388c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois SpecialRegister(SpecialRegisterType reg) : reg_(reg) {} // NOLINT 74488c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois uint32_t GetReg() const { return reg_; } 74588c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois const char* GetName() const; 74688c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois bool Is(SpecialRegister value) const { return reg_ == value.reg_; } 74788c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois bool Is(uint32_t value) const { return reg_ == value; } 74888c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois bool IsNot(uint32_t value) const { return reg_ != value; } 74988c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois}; 75088c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois 75188c46b84df005638546de5e4e965bdcc31352f48Pierre Langloisinline std::ostream& operator<<(std::ostream& os, SpecialRegister reg) { 75288c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois return os << reg.GetName(); 75388c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois} 75488c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois 75588c46b84df005638546de5e4e965bdcc31352f48Pierre Langloisenum BankedRegisterType { 75688c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois R8_usr = 0x00, 75788c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois R9_usr = 0x01, 75888c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois R10_usr = 0x02, 75988c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois R11_usr = 0x03, 76088c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois R12_usr = 0x04, 76188c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois SP_usr = 0x05, 76288c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois LR_usr = 0x06, 76388c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois R8_fiq = 0x08, 76488c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois R9_fiq = 0x09, 76588c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois R10_fiq = 0x0a, 76688c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois R11_fiq = 0x0b, 76788c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois R12_fiq = 0x0c, 76888c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois SP_fiq = 0x0d, 76988c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois LR_fiq = 0x0e, 77088c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois LR_irq = 0x10, 77188c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois SP_irq = 0x11, 77288c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois LR_svc = 0x12, 77388c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois SP_svc = 0x13, 77488c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois LR_abt = 0x14, 77588c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois SP_abt = 0x15, 77688c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois LR_und = 0x16, 77788c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois SP_und = 0x17, 77888c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois LR_mon = 0x1c, 77988c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois SP_mon = 0x1d, 78088c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois ELR_hyp = 0x1e, 78188c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois SP_hyp = 0x1f, 78288c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois SPSR_fiq = 0x2e, 78388c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois SPSR_irq = 0x30, 78488c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois SPSR_svc = 0x32, 78588c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois SPSR_abt = 0x34, 78688c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois SPSR_und = 0x36, 78788c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois SPSR_mon = 0x3c, 78888c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois SPSR_hyp = 0x3e 78988c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois}; 79088c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois 79188c46b84df005638546de5e4e965bdcc31352f48Pierre Langloisclass BankedRegister { 79288c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois uint32_t reg_; 79388c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois 79488c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois public: 79588c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois explicit BankedRegister(unsigned reg) : reg_(reg) {} 79688c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois BankedRegister(BankedRegisterType reg) : reg_(reg) {} // NOLINT 79788c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois uint32_t GetCode() const { return reg_; } 79888c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois const char* GetName() const; 79988c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois}; 80088c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois 80188c46b84df005638546de5e4e965bdcc31352f48Pierre Langloisinline std::ostream& operator<<(std::ostream& os, BankedRegister reg) { 80288c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois return os << reg.GetName(); 80388c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois} 80488c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois 80588c46b84df005638546de5e4e965bdcc31352f48Pierre Langloisenum MaskedSpecialRegisterType { 80688c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois APSR_nzcvq = 0x08, 80788c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois APSR_g = 0x04, 80888c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois APSR_nzcvqg = 0x0c, 80988c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois CPSR_c = 0x01, 81088c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois CPSR_x = 0x02, 81188c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois CPSR_xc = 0x03, 81288c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois CPSR_s = APSR_g, 81388c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois CPSR_sc = 0x05, 81488c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois CPSR_sx = 0x06, 81588c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois CPSR_sxc = 0x07, 81688c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois CPSR_f = APSR_nzcvq, 81788c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois CPSR_fc = 0x09, 81888c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois CPSR_fx = 0x0a, 81988c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois CPSR_fxc = 0x0b, 82088c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois CPSR_fs = APSR_nzcvqg, 82188c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois CPSR_fsc = 0x0d, 82288c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois CPSR_fsx = 0x0e, 82388c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois CPSR_fsxc = 0x0f, 82488c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois SPSR_c = 0x11, 82588c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois SPSR_x = 0x12, 82688c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois SPSR_xc = 0x13, 82788c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois SPSR_s = 0x14, 82888c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois SPSR_sc = 0x15, 82988c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois SPSR_sx = 0x16, 83088c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois SPSR_sxc = 0x17, 83188c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois SPSR_f = 0x18, 83288c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois SPSR_fc = 0x19, 83388c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois SPSR_fx = 0x1a, 83488c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois SPSR_fxc = 0x1b, 83588c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois SPSR_fs = 0x1c, 83688c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois SPSR_fsc = 0x1d, 83788c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois SPSR_fsx = 0x1e, 83888c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois SPSR_fsxc = 0x1f 83988c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois}; 84088c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois 84188c46b84df005638546de5e4e965bdcc31352f48Pierre Langloisclass MaskedSpecialRegister { 84288c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois uint32_t reg_; 84388c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois 84488c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois public: 84588c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois explicit MaskedSpecialRegister(uint32_t reg) : reg_(reg) { 84688c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois VIXL_ASSERT(reg <= SPSR_fsxc); 84788c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois } 84888c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois MaskedSpecialRegister(MaskedSpecialRegisterType reg) // NOLINT 84988c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois : reg_(reg) {} 85088c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois uint32_t GetReg() const { return reg_; } 85188c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois const char* GetName() const; 85288c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois bool Is(MaskedSpecialRegister value) const { return reg_ == value.reg_; } 85388c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois bool Is(uint32_t value) const { return reg_ == value; } 85488c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois bool IsNot(uint32_t value) const { return reg_ != value; } 85588c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois}; 85688c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois 85788c46b84df005638546de5e4e965bdcc31352f48Pierre Langloisinline std::ostream& operator<<(std::ostream& os, MaskedSpecialRegister reg) { 85888c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois return os << reg.GetName(); 85988c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois} 86088c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois 86188c46b84df005638546de5e4e965bdcc31352f48Pierre Langloisenum SpecialFPRegisterType { 86288c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois FPSID = 0x0, 86388c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois FPSCR = 0x1, 86488c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois MVFR2 = 0x5, 86588c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois MVFR1 = 0x6, 86688c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois MVFR0 = 0x7, 86788c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois FPEXC = 0x8 86888c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois}; 86988c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois 87088c46b84df005638546de5e4e965bdcc31352f48Pierre Langloisclass SpecialFPRegister { 87188c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois uint32_t reg_; 87288c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois 87388c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois public: 87488c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois explicit SpecialFPRegister(uint32_t reg) : reg_(reg) { 87588c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois#ifdef VIXL_DEBUG 87688c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois switch (reg) { 87788c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois case FPSID: 87888c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois case FPSCR: 87988c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois case MVFR2: 88088c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois case MVFR1: 88188c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois case MVFR0: 88288c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois case FPEXC: 88388c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois break; 88488c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois default: 88588c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois VIXL_UNREACHABLE(); 88688c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois } 88788c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois#endif 88888c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois } 88988c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois SpecialFPRegister(SpecialFPRegisterType reg) : reg_(reg) {} // NOLINT 89088c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois uint32_t GetReg() const { return reg_; } 89188c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois const char* GetName() const; 89288c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois bool Is(SpecialFPRegister value) const { return reg_ == value.reg_; } 89388c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois bool Is(uint32_t value) const { return reg_ == value; } 89488c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois bool IsNot(uint32_t value) const { return reg_ != value; } 89588c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois}; 89688c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois 89788c46b84df005638546de5e4e965bdcc31352f48Pierre Langloisinline std::ostream& operator<<(std::ostream& os, SpecialFPRegister reg) { 89888c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois return os << reg.GetName(); 89988c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois} 90088c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois 90188c46b84df005638546de5e4e965bdcc31352f48Pierre Langloisclass CRegister { 90288c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois uint32_t code_; 90388c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois 90488c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois public: 90588c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois explicit CRegister(uint32_t code) : code_(code) { 90688c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois VIXL_ASSERT(code < kNumberOfRegisters); 90788c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois } 90888c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois uint32_t GetCode() const { return code_; } 90988c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois bool Is(CRegister value) const { return code_ == value.code_; } 91088c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois}; 91188c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois 91288c46b84df005638546de5e4e965bdcc31352f48Pierre Langloisinline std::ostream& operator<<(std::ostream& os, const CRegister reg) { 91388c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois return os << "c" << reg.GetCode(); 91488c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois} 91588c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois 91688c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois// clang-format off 91788c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois#define CREGISTER_CODE_LIST(R) \ 91888c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois R(0) R(1) R(2) R(3) R(4) R(5) R(6) R(7) \ 91988c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois R(8) R(9) R(10) R(11) R(12) R(13) R(14) R(15) 92088c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois// clang-format on 92188c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois#define DEFINE_CREGISTER(N) const CRegister c##N(N); 92288c46b84df005638546de5e4e965bdcc31352f48Pierre LangloisCREGISTER_CODE_LIST(DEFINE_CREGISTER) 92388c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois 92488c46b84df005638546de5e4e965bdcc31352f48Pierre Langloisenum CoprocessorName { p10 = 10, p11 = 11, p14 = 14, p15 = 15 }; 92588c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois 92688c46b84df005638546de5e4e965bdcc31352f48Pierre Langloisclass Coprocessor { 92788c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois uint32_t coproc_; 92888c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois 92988c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois public: 93088c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois explicit Coprocessor(uint32_t coproc) : coproc_(coproc) {} 93188c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois Coprocessor(CoprocessorName coproc) // NOLINT 93288c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois : coproc_(static_cast<uint32_t>(coproc)) {} 93388c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois bool Is(Coprocessor coproc) const { return coproc_ == coproc.coproc_; } 93488c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois bool Is(CoprocessorName coproc) const { return coproc_ == coproc; } 93588c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois uint32_t GetCoprocessor() const { return coproc_; } 93688c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois}; 93788c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois 93888c46b84df005638546de5e4e965bdcc31352f48Pierre Langloisinline std::ostream& operator<<(std::ostream& os, Coprocessor coproc) { 93988c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois return os << "p" << coproc.GetCoprocessor(); 94088c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois} 94188c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois 94288c46b84df005638546de5e4e965bdcc31352f48Pierre Langloisenum ConditionType { 94388c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois eq = 0, 94488c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois ne = 1, 94588c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois cs = 2, 94688c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois cc = 3, 94788c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois mi = 4, 94888c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois pl = 5, 94988c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois vs = 6, 95088c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois vc = 7, 95188c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois hi = 8, 95288c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois ls = 9, 95388c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois ge = 10, 95488c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois lt = 11, 95588c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois gt = 12, 95688c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois le = 13, 95788c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois al = 14, 95888c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois hs = cs, 95988c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois lo = cc 96088c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois}; 96188c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois 96288c46b84df005638546de5e4e965bdcc31352f48Pierre Langloisclass Condition { 96388c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois uint32_t condition_; 96488c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois static const uint32_t kNever = 15; 96588c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois static const uint32_t kMask = 0xf; 966fad350715bbb9f13ea85c84da4e6095dfee3cd15Vincent Belliard static const uint32_t kNone = 0x10 | al; 96788c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois 96888c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois public: 969fad350715bbb9f13ea85c84da4e6095dfee3cd15Vincent Belliard static const Condition None() { return Condition(kNone); } 97088c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois explicit Condition(uint32_t condition) : condition_(condition) { 97188c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois VIXL_ASSERT(condition <= kNone); 97288c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois } 97388c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois Condition(ConditionType condition) : condition_(condition) {} // NOLINT 97488c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois uint32_t GetCondition() const { return condition_ & kMask; } 97588c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois bool IsNone() const { return condition_ == kNone; } 97688c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois const char* GetName() const; 97788c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois bool Is(Condition value) const { return condition_ == value.condition_; } 97888c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois bool Is(uint32_t value) const { return condition_ == value; } 97988c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois bool IsNot(uint32_t value) const { return condition_ != value; } 98088c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois bool IsNever() const { return condition_ == kNever; } 98188c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois bool IsNotNever() const { return condition_ != kNever; } 98288c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois Condition Negate() const { 98388c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois VIXL_ASSERT(IsNot(al) && IsNot(kNever)); 98488c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois return Condition(condition_ ^ 1); 98588c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois } 98688c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois}; 98788c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois 98888c46b84df005638546de5e4e965bdcc31352f48Pierre Langloisinline std::ostream& operator<<(std::ostream& os, Condition condition) { 98988c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois return os << condition.GetName(); 99088c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois} 99188c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois 99288c46b84df005638546de5e4e965bdcc31352f48Pierre Langloisenum SignType { plus, minus }; 99388c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois 99488c46b84df005638546de5e4e965bdcc31352f48Pierre Langloisclass Sign { 99588c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois public: 99688c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois Sign() : sign_(plus) {} 99788c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois Sign(SignType sign) : sign_(sign) {} // NOLINT 99888c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois const char* GetName() const { return (IsPlus() ? "" : "-"); } 99988c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois bool IsPlus() const { return sign_ == plus; } 100088c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois bool IsMinus() const { return sign_ == minus; } 100188c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois int32_t ApplyTo(uint32_t value) { return IsPlus() ? value : -value; } 100288c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois 100388c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois private: 100488c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois SignType sign_; 100588c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois}; 100688c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois 100788c46b84df005638546de5e4e965bdcc31352f48Pierre Langloisinline std::ostream& operator<<(std::ostream& os, Sign sign) { 100888c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois return os << sign.GetName(); 100988c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois} 101088c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois 101188c46b84df005638546de5e4e965bdcc31352f48Pierre Langloisenum ShiftType { LSL = 0x0, LSR = 0x1, ASR = 0x2, ROR = 0x3, RRX = 0x4 }; 101288c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois 101388c46b84df005638546de5e4e965bdcc31352f48Pierre Langloisclass Shift { 101488c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois public: 101588c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois Shift() : shift_(LSL) {} 101688c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois Shift(ShiftType shift) : shift_(shift) {} // NOLINT 101788c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois explicit Shift(uint32_t shift) : shift_(static_cast<ShiftType>(shift)) {} 101888c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois const Shift& GetShift() const { return *this; } 101988c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois ShiftType GetType() const { return shift_; } 102088c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois uint32_t GetValue() const { return shift_; } 102188c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois const char* GetName() const; 102288c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois bool IsLSL() const { return shift_ == LSL; } 102388c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois bool IsLSR() const { return shift_ == LSR; } 102488c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois bool IsASR() const { return shift_ == ASR; } 102588c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois bool IsROR() const { return shift_ == ROR; } 102688c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois bool IsRRX() const { return shift_ == RRX; } 102788c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois bool Is(Shift value) const { return shift_ == value.shift_; } 102888c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois bool IsNot(Shift value) const { return shift_ != value.shift_; } 102988c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois bool IsValidAmount(uint32_t amount) const; 103088c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois static const Shift NoShift; 103188c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois 103288c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois protected: 103388c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois void SetType(ShiftType s) { shift_ = s; } 103488c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois 103588c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois private: 103688c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois ShiftType shift_; 103788c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois}; 103888c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois 103988c46b84df005638546de5e4e965bdcc31352f48Pierre Langloisinline std::ostream& operator<<(std::ostream& os, Shift shift) { 104088c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois return os << shift.GetName(); 104188c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois} 104288c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois 104388c46b84df005638546de5e4e965bdcc31352f48Pierre Langloisclass ImmediateShiftOperand : public Shift { 104488c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois public: 104588c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois // Constructor used for assembly. 104688c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois ImmediateShiftOperand(Shift shift, uint32_t amount) 104788c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois : Shift(shift), amount_(amount) { 104888c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois#ifdef VIXL_DEBUG 104988c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois switch (shift.GetType()) { 105088c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois case LSL: 105188c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois VIXL_ASSERT(amount <= 31); 105288c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois break; 105388c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois case ROR: 105488c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois VIXL_ASSERT(amount > 0); 105588c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois VIXL_ASSERT(amount <= 31); 105688c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois break; 105788c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois case LSR: 105888c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois case ASR: 105988c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois VIXL_ASSERT(amount > 0); 106088c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois VIXL_ASSERT(amount <= 32); 106188c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois break; 106288c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois case RRX: 106388c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois VIXL_ASSERT(amount == 0); 106488c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois break; 106588c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois default: 106688c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois VIXL_UNREACHABLE(); 106788c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois break; 106888c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois } 106988c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois#endif 107088c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois } 107188c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois // Constructor used for disassembly. 107288c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois ImmediateShiftOperand(int shift, int amount); 107388c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois uint32_t GetAmount() const { return amount_; } 107488c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois bool Is(const ImmediateShiftOperand& rhs) const { 107588c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois return amount_ == (rhs.amount_) && Shift::Is(*this); 107688c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois } 107788c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois 107888c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois private: 107988c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois uint32_t amount_; 108088c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois}; 108188c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois 108288c46b84df005638546de5e4e965bdcc31352f48Pierre Langloisinline std::ostream& operator<<(std::ostream& os, 108388c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois ImmediateShiftOperand const& shift_operand) { 108488c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois if (shift_operand.IsLSL() && shift_operand.GetAmount() == 0) return os; 108588c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois if (shift_operand.IsRRX()) return os << ", rrx"; 108688c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois return os << ", " << shift_operand.GetName() << " #" 108788c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois << shift_operand.GetAmount(); 108888c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois} 108988c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois 109088c46b84df005638546de5e4e965bdcc31352f48Pierre Langloisclass RegisterShiftOperand : public Shift { 109188c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois public: 109288c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois RegisterShiftOperand(ShiftType shift, Register shift_register) 109388c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois : Shift(shift), shift_register_(shift_register) { 109488c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois VIXL_ASSERT(!IsRRX() && shift_register_.IsValid()); 109588c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois } 109688c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois const Register GetShiftRegister() const { return shift_register_; } 109788c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois bool Is(const RegisterShiftOperand& rhs) const { 109888c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois return shift_register_.Is(rhs.shift_register_) && Shift::Is(*this); 109988c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois } 110088c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois 110188c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois private: 110288c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois Register shift_register_; 110388c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois}; 110488c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois 110588c46b84df005638546de5e4e965bdcc31352f48Pierre Langloisinline std::ostream& operator<<(std::ostream& s, 110688c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois const RegisterShiftOperand& shift_operand) { 110788c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois return s << shift_operand.GetName() << " " 110888c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois << shift_operand.GetShiftRegister(); 110988c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois} 111088c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois 111188c46b84df005638546de5e4e965bdcc31352f48Pierre Langloisenum EncodingSizeType { Best, Narrow, Wide }; 111288c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois 111388c46b84df005638546de5e4e965bdcc31352f48Pierre Langloisclass EncodingSize { 111488c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois uint32_t size_; 111588c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois 111688c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois public: 111788c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois explicit EncodingSize(uint32_t size) : size_(size) {} 111888c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois EncodingSize(EncodingSizeType size) : size_(size) {} // NOLINT 111988c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois uint32_t GetSize() const { return size_; } 112088c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois const char* GetName() const; 112188c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois bool IsBest() const { return size_ == Best; } 112288c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois bool IsNarrow() const { return size_ == Narrow; } 112388c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois bool IsWide() const { return size_ == Wide; } 112488c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois}; 112588c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois 112688c46b84df005638546de5e4e965bdcc31352f48Pierre Langloisinline std::ostream& operator<<(std::ostream& os, EncodingSize size) { 112788c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois return os << size.GetName(); 112888c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois} 112988c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois 113088c46b84df005638546de5e4e965bdcc31352f48Pierre Langloisenum WriteBackValue { NO_WRITE_BACK, WRITE_BACK }; 113188c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois 113288c46b84df005638546de5e4e965bdcc31352f48Pierre Langloisclass WriteBack { 113388c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois WriteBackValue value_; 113488c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois 113588c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois public: 113688c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois WriteBack(WriteBackValue value) : value_(value) {} // NOLINT 113788c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois explicit WriteBack(int value) 113888c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois : value_((value == 0) ? NO_WRITE_BACK : WRITE_BACK) {} 113988c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois uint32_t GetWriteBackUint32() const { return (value_ == WRITE_BACK) ? 1 : 0; } 114088c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois bool DoesWriteBack() const { return value_ == WRITE_BACK; } 114188c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois}; 114288c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois 114388c46b84df005638546de5e4e965bdcc31352f48Pierre Langloisinline std::ostream& operator<<(std::ostream& os, WriteBack write_back) { 114488c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois if (write_back.DoesWriteBack()) return os << "!"; 114588c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois return os; 114688c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois} 114788c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois 114888c46b84df005638546de5e4e965bdcc31352f48Pierre Langloisclass EncodingValue { 114988c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois bool valid_; 115088c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois uint32_t encoding_value_; 115188c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois 115288c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois public: 115388c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois EncodingValue() { 115488c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois valid_ = false; 115588c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois encoding_value_ = 0; 115688c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois } 115788c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois bool IsValid() const { return valid_; } 115888c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois uint32_t GetEncodingValue() const { return encoding_value_; } 115988c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois void SetEncodingValue(uint32_t encoding_value) { 116088c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois valid_ = true; 116188c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois encoding_value_ = encoding_value; 116288c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois } 116388c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois}; 116488c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois 116588c46b84df005638546de5e4e965bdcc31352f48Pierre Langloisclass EncodingValueAndImmediate : public EncodingValue { 116688c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois uint32_t encoded_immediate_; 116788c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois 116888c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois public: 116988c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois EncodingValueAndImmediate() { encoded_immediate_ = 0; } 117088c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois uint32_t GetEncodedImmediate() const { return encoded_immediate_; } 117188c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois void SetEncodedImmediate(uint32_t encoded_immediate) { 117288c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois encoded_immediate_ = encoded_immediate; 117388c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois } 117488c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois}; 117588c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois 117688c46b84df005638546de5e4e965bdcc31352f48Pierre Langloisclass ImmediateT32 : public EncodingValue { 117788c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois public: 117888c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois explicit ImmediateT32(uint32_t imm); 117988c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois static bool IsImmediateT32(uint32_t imm); 118088c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois static uint32_t Decode(uint32_t value); 118188c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois}; 118288c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois 118388c46b84df005638546de5e4e965bdcc31352f48Pierre Langloisclass ImmediateA32 : public EncodingValue { 118488c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois public: 118588c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois explicit ImmediateA32(uint32_t imm); 118688c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois static bool IsImmediateA32(uint32_t imm); 118788c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois static uint32_t Decode(uint32_t value); 118888c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois}; 118988c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois 119088c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois// Return the encoding value of a shift type. 119188c46b84df005638546de5e4e965bdcc31352f48Pierre Langloisuint32_t TypeEncodingValue(Shift shift); 119288c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois// Return the encoding value for a shift amount depending on the shift type. 119388c46b84df005638546de5e4e965bdcc31352f48Pierre Langloisuint32_t AmountEncodingValue(Shift shift, uint32_t amount); 119488c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois 119588c46b84df005638546de5e4e965bdcc31352f48Pierre Langloisenum MemoryBarrierType { 119688c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois OSHLD = 0x1, 119788c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois OSHST = 0x2, 119888c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois OSH = 0x3, 119988c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois NSHLD = 0x5, 120088c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois NSHST = 0x6, 120188c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois NSH = 0x7, 120288c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois ISHLD = 0x9, 120388c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois ISHST = 0xa, 120488c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois ISH = 0xb, 120588c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois LD = 0xd, 120688c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois ST = 0xe, 120788c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois SY = 0xf 120888c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois}; 120988c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois 121088c46b84df005638546de5e4e965bdcc31352f48Pierre Langloisclass MemoryBarrier { 121188c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois MemoryBarrierType type_; 121288c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois 121388c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois public: 121488c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois MemoryBarrier(MemoryBarrierType type) : type_(type) {} // NOLINT 121588c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois MemoryBarrier(uint32_t type) // NOLINT 121688c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois : type_(static_cast<MemoryBarrierType>(type)) { 121788c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois VIXL_ASSERT((type & 0x3) != 0); 121888c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois } 121988c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois MemoryBarrierType GetType() const { return type_; } 122088c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois const char* GetName() const; 122188c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois}; 122288c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois 122388c46b84df005638546de5e4e965bdcc31352f48Pierre Langloisinline std::ostream& operator<<(std::ostream& os, MemoryBarrier option) { 122488c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois return os << option.GetName(); 122588c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois} 122688c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois 122788c46b84df005638546de5e4e965bdcc31352f48Pierre Langloisenum InterruptFlagsType { 122888c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois F = 0x1, 122988c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois I = 0x2, 123088c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois IF = 0x3, 123188c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois A = 0x4, 123288c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois AF = 0x5, 123388c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois AI = 0x6, 123488c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois AIF = 0x7 123588c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois}; 123688c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois 123788c46b84df005638546de5e4e965bdcc31352f48Pierre Langloisclass InterruptFlags { 123888c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois InterruptFlagsType type_; 123988c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois 124088c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois public: 124188c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois InterruptFlags(InterruptFlagsType type) : type_(type) {} // NOLINT 124288c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois InterruptFlags(uint32_t type) // NOLINT 124388c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois : type_(static_cast<InterruptFlagsType>(type)) { 124488c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois VIXL_ASSERT(type <= 7); 124588c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois } 124688c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois InterruptFlagsType GetType() const { return type_; } 124788c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois const char* GetName() const; 124888c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois}; 124988c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois 125088c46b84df005638546de5e4e965bdcc31352f48Pierre Langloisinline std::ostream& operator<<(std::ostream& os, InterruptFlags option) { 125188c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois return os << option.GetName(); 125288c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois} 125388c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois 125488c46b84df005638546de5e4e965bdcc31352f48Pierre Langloisenum EndiannessType { LE = 0, BE = 1 }; 125588c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois 125688c46b84df005638546de5e4e965bdcc31352f48Pierre Langloisclass Endianness { 125788c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois EndiannessType type_; 125888c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois 125988c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois public: 126088c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois Endianness(EndiannessType type) : type_(type) {} // NOLINT 126188c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois Endianness(uint32_t type) // NOLINT 126288c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois : type_(static_cast<EndiannessType>(type)) { 126388c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois VIXL_ASSERT(type <= 1); 126488c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois } 126588c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois EndiannessType GetType() const { return type_; } 126688c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois const char* GetName() const; 126788c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois}; 126888c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois 126988c46b84df005638546de5e4e965bdcc31352f48Pierre Langloisinline std::ostream& operator<<(std::ostream& os, Endianness endian_specifier) { 127088c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois return os << endian_specifier.GetName(); 127188c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois} 127288c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois 127388c46b84df005638546de5e4e965bdcc31352f48Pierre Langloisenum AlignmentType { 127488c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois k16BitAlign = 0, 127588c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois k32BitAlign = 1, 127688c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois k64BitAlign = 2, 127788c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois k128BitAlign = 3, 127888c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois k256BitAlign = 4, 127988c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois kNoAlignment = 5, 128088c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois kBadAlignment = 6 128188c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois}; 128288c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois 128388c46b84df005638546de5e4e965bdcc31352f48Pierre Langloisclass Alignment { 128488c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois AlignmentType align_; 128588c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois 128688c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois public: 128788c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois Alignment(AlignmentType align) // NOLINT(runtime/explicit) 128888c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois : align_(align) {} 128988c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois Alignment(uint32_t align) // NOLINT(runtime/explicit) 129088c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois : align_(static_cast<AlignmentType>(align)) { 129188c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois VIXL_ASSERT(align <= static_cast<uint32_t>(k256BitAlign)); 129288c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois } 129388c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois AlignmentType GetType() const { return align_; } 129488c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois bool Is(AlignmentType type) { return align_ == type; } 129588c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois}; 129688c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois 129788c46b84df005638546de5e4e965bdcc31352f48Pierre Langloisinline std::ostream& operator<<(std::ostream& os, Alignment align) { 129888c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois if (align.GetType() == kBadAlignment) return os << " :??"; 129988c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois if (align.GetType() == kNoAlignment) return os; 130088c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois return os << " :" << (0x10 << static_cast<uint32_t>(align.GetType())); 130188c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois} 130288c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois 130388c46b84df005638546de5e4e965bdcc31352f48Pierre Langloisclass RawLiteral : public Label { 130488c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois public: 130551d1cccb2cbb843c41a586fbedad00ded8f0d6a0Vincent Belliard enum PlacementPolicy { kPlacedWhenUsed, kManuallyPlaced }; 130651d1cccb2cbb843c41a586fbedad00ded8f0d6a0Vincent Belliard 130788c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois enum DeletionPolicy { 130888c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois kDeletedOnPlacementByPool, 130988c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois kDeletedOnPoolDestruction, 131088c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois kManuallyDeleted 131188c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois }; 131288c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois 131388c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois public: 131488c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois RawLiteral(const void* addr, 131588c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois size_t size, 131651d1cccb2cbb843c41a586fbedad00ded8f0d6a0Vincent Belliard PlacementPolicy placement_policy = kPlacedWhenUsed, 131788c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois DeletionPolicy deletion_policy = kManuallyDeleted) 131888c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois : addr_(addr), 131988c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois size_(size), 132088c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois position_(kMaxOffset), 132151d1cccb2cbb843c41a586fbedad00ded8f0d6a0Vincent Belliard manually_placed_(placement_policy == kManuallyPlaced), 132251d1cccb2cbb843c41a586fbedad00ded8f0d6a0Vincent Belliard deletion_policy_(deletion_policy) {} 132351d1cccb2cbb843c41a586fbedad00ded8f0d6a0Vincent Belliard RawLiteral(const void* addr, size_t size, DeletionPolicy deletion_policy) 132451d1cccb2cbb843c41a586fbedad00ded8f0d6a0Vincent Belliard : addr_(addr), 132551d1cccb2cbb843c41a586fbedad00ded8f0d6a0Vincent Belliard size_(size), 132651d1cccb2cbb843c41a586fbedad00ded8f0d6a0Vincent Belliard position_(kMaxOffset), 132751d1cccb2cbb843c41a586fbedad00ded8f0d6a0Vincent Belliard manually_placed_(false), 132888c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois deletion_policy_(deletion_policy) {} 132988c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois ~RawLiteral() {} 133051d1cccb2cbb843c41a586fbedad00ded8f0d6a0Vincent Belliard const void* GetDataAddress() const { return addr_; } 133188c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois size_t GetSize() const { return size_; } 133288c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois size_t GetAlignedSize() const { return (size_ + 3) & ~0x3; } 133388c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois 133488c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois Offset GetPositionInPool() const { return position_; } 133588c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois void SetPositionInPool(Offset position_in_pool) { 133688c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois // Assumed that the literal has not already been added to 133788c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois // the pool. 133888c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois VIXL_ASSERT(position_ == Label::kMaxOffset); 133988c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois position_ = position_in_pool; 134088c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois } 134188c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois 134251d1cccb2cbb843c41a586fbedad00ded8f0d6a0Vincent Belliard bool IsManuallyPlaced() const { return manually_placed_; } 134351d1cccb2cbb843c41a586fbedad00ded8f0d6a0Vincent Belliard DeletionPolicy GetDeletionPolicy() const { return deletion_policy_; } 134451d1cccb2cbb843c41a586fbedad00ded8f0d6a0Vincent Belliard 134588c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois private: 134688c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois // Data address before it's moved into the code buffer. 134788c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois const void* const addr_; 134888c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois // Data size before it's moved into the code buffer. 134988c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois const size_t size_; 135088c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois // Position in the pool, if not in a pool: Label::kMaxOffset. 135188c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois Offset position_; 135251d1cccb2cbb843c41a586fbedad00ded8f0d6a0Vincent Belliard // When this flag is true, the label will be placed manually. 135351d1cccb2cbb843c41a586fbedad00ded8f0d6a0Vincent Belliard bool manually_placed_; 135488c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois // When is the literal to be removed from the memory 135588c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois // Can be delete'd when: 135688c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois // moved into the code buffer: kDeletedOnPlacementByPool 135788c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois // the pool is delete'd: kDeletedOnPoolDestruction 135888c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois // or left to the application: kManuallyDeleted. 135988c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois DeletionPolicy deletion_policy_; 136088c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois}; 136188c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois 136288c46b84df005638546de5e4e965bdcc31352f48Pierre Langloistemplate <typename T> 136388c46b84df005638546de5e4e965bdcc31352f48Pierre Langloisclass Literal : public RawLiteral { 136488c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois public: 136588c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois explicit Literal(const T& value, 136651d1cccb2cbb843c41a586fbedad00ded8f0d6a0Vincent Belliard PlacementPolicy placement_policy = kPlacedWhenUsed, 136788c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois DeletionPolicy deletion_policy = kManuallyDeleted) 136851d1cccb2cbb843c41a586fbedad00ded8f0d6a0Vincent Belliard : RawLiteral(&value_, sizeof(T), placement_policy, deletion_policy), 136951d1cccb2cbb843c41a586fbedad00ded8f0d6a0Vincent Belliard value_(value) {} 137051d1cccb2cbb843c41a586fbedad00ded8f0d6a0Vincent Belliard explicit Literal(const T& value, DeletionPolicy deletion_policy) 137188c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois : RawLiteral(&value_, sizeof(T), deletion_policy), value_(value) {} 13723e1b899f48c1328ac748b1f5fa78f417f7ec6581Vincent Belliard void UpdateValue(const T& value, CodeBuffer* buffer) { 13733e1b899f48c1328ac748b1f5fa78f417f7ec6581Vincent Belliard value_ = value; 13743e1b899f48c1328ac748b1f5fa78f417f7ec6581Vincent Belliard if (IsBound()) { 13753e1b899f48c1328ac748b1f5fa78f417f7ec6581Vincent Belliard buffer->UpdateData(GetLocation(), GetDataAddress(), GetSize()); 13763e1b899f48c1328ac748b1f5fa78f417f7ec6581Vincent Belliard } 13773e1b899f48c1328ac748b1f5fa78f417f7ec6581Vincent Belliard } 137888c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois 137988c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois private: 138088c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois T value_; 138188c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois}; 138288c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois 138325e3987b3b684df88edc8069d60b483b95587be5Pierre Langloisclass StringLiteral : public RawLiteral { 138488c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois public: 138525e3987b3b684df88edc8069d60b483b95587be5Pierre Langlois explicit StringLiteral(const char* str, 138625e3987b3b684df88edc8069d60b483b95587be5Pierre Langlois PlacementPolicy placement_policy = kPlacedWhenUsed, 138725e3987b3b684df88edc8069d60b483b95587be5Pierre Langlois DeletionPolicy deletion_policy = kManuallyDeleted) 138851d1cccb2cbb843c41a586fbedad00ded8f0d6a0Vincent Belliard : RawLiteral(str, strlen(str) + 1, placement_policy, deletion_policy) {} 138925e3987b3b684df88edc8069d60b483b95587be5Pierre Langlois explicit StringLiteral(const char* str, DeletionPolicy deletion_policy) 139088c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois : RawLiteral(str, strlen(str) + 1, deletion_policy) {} 139188c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois}; 139288c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois 139388c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois} // namespace aarch32 139488c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois} // namespace vixl 139588c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois 1396d3832965c62a8ad461b9ea9eb0994ca6b0a3da2cAlexandre Rames#endif // VIXL_AARCH32_INSTRUCTIONS_AARCH32_H_ 1397