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 1088c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois// notice, this list of conditions and the following disclaimer in the 1188c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois// documentation and/or other materials provided with the distribution. 1288c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois// * Neither the name of ARM Limited nor the names of its contributors may 1388c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois// be used to endorse or promote products derived from this software 1488c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois// without 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 1888c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois// IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 1988c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois// ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE 2088c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois// LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR 2188c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois// CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF 2288c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois// SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS 2388c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois// INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN 2488c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois// CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) 2588c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois// ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE 2688c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois// POSSIBILITY OF SUCH DAMAGE. 2788c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois 28989663e3cb7be8ac458d71f8e8d99afd29b13a39Pierre Langlois#ifndef VIXL_AARCH32_OPERANDS_AARCH32_H_ 29989663e3cb7be8ac458d71f8e8d99afd29b13a39Pierre Langlois#define VIXL_AARCH32_OPERANDS_AARCH32_H_ 3088c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois 31d3832965c62a8ad461b9ea9eb0994ca6b0a3da2cAlexandre Rames#include "aarch32/instructions-aarch32.h" 3288c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois 3388c46b84df005638546de5e4e965bdcc31352f48Pierre Langloisnamespace vixl { 3488c46b84df005638546de5e4e965bdcc31352f48Pierre Langloisnamespace aarch32 { 3588c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois 3688c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois// Operand represents generic set of arguments to pass to an instruction. 3788c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois// 3888c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois// Usage: <instr> <Rd> , <Operand> 3988c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois// 4088c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois// where <instr> is the instruction to use (e.g., Mov(), Rsb(), etc.) 4188c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois// <Rd> is the destination register 4288c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois// <Operand> is the rest of the arguments to the instruction 4388c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois// 4488c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois// <Operand> can be one of: 4588c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois// 4688c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois// #<imm> - an unsigned 32-bit immediate value 4788c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois// <Rm>, <shift> <#amount> - immediate shifted register 4888c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois// <Rm>, <shift> <Rs> - register shifted register 4988c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois// 5088c46b84df005638546de5e4e965bdcc31352f48Pierre Langloisclass Operand { 5188c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois public: 5288c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois // { #<immediate> } 5388c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois // where <immediate> is uint32_t. 5488c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois // This is allowed to be an implicit constructor because Operand is 5588c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois // a wrapper class that doesn't normally perform any type conversion. 5660241a544be0ebf48347789bf0ec268414364627Vincent Belliard Operand(uint32_t immediate) // NOLINT(runtime/explicit) 5788c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois : imm_(immediate), 5888c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois rm_(NoReg), 5988c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois shift_(LSL), 6088c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois amount_(0), 6188c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois rs_(NoReg) {} 6260241a544be0ebf48347789bf0ec268414364627Vincent Belliard Operand(int32_t immediate) // NOLINT(runtime/explicit) 63f5348cedd702124c90fc75e75d0195e2e485c620Pierre Langlois : imm_(immediate), 64f5348cedd702124c90fc75e75d0195e2e485c620Pierre Langlois rm_(NoReg), 65f5348cedd702124c90fc75e75d0195e2e485c620Pierre Langlois shift_(LSL), 66f5348cedd702124c90fc75e75d0195e2e485c620Pierre Langlois amount_(0), 67f5348cedd702124c90fc75e75d0195e2e485c620Pierre Langlois rs_(NoReg) {} 6888c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois 6988c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois // rm 7088c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois // where rm is the base register 7188c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois // This is allowed to be an implicit constructor because Operand is 7288c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois // a wrapper class that doesn't normally perform any type conversion. 7360241a544be0ebf48347789bf0ec268414364627Vincent Belliard Operand(Register rm) // NOLINT(runtime/explicit) 7488c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois : imm_(0), 7588c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois rm_(rm), 7688c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois shift_(LSL), 7788c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois amount_(0), 7888c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois rs_(NoReg) { 7988c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois VIXL_ASSERT(rm_.IsValid()); 8088c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois } 8188c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois 8288c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois // rm, <shift> 8388c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois // where rm is the base register, and 8488c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois // <shift> is RRX 8588c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois Operand(Register rm, Shift shift) 8688c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois : imm_(0), rm_(rm), shift_(shift), amount_(0), rs_(NoReg) { 8788c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois VIXL_ASSERT(rm_.IsValid()); 8888c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois VIXL_ASSERT(shift_.IsRRX()); 8988c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois } 9088c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois 9188c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois // rm, <shift> #<amount> 9288c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois // where rm is the base register, and 9388c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois // <shift> is one of {LSL, LSR, ASR, ROR}, and 9488c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois // <amount> is uint6_t. 9588c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois Operand(Register rm, Shift shift, uint32_t amount) 9688c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois : imm_(0), rm_(rm), shift_(shift), amount_(amount), rs_(NoReg) { 9788c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois VIXL_ASSERT(rm_.IsValid()); 9888c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois VIXL_ASSERT(!shift_.IsRRX()); 9988c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois#ifdef VIXL_DEBUG 10088c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois switch (shift_.GetType()) { 10188c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois case LSL: 10288c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois VIXL_ASSERT(amount_ <= 31); 10388c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois break; 10488c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois case ROR: 10588c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois VIXL_ASSERT(amount_ <= 31); 10688c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois break; 10788c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois case LSR: 10888c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois case ASR: 10988c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois VIXL_ASSERT(amount_ <= 32); 11088c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois break; 11188c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois case RRX: 11288c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois default: 11388c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois VIXL_UNREACHABLE(); 11488c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois break; 11588c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois } 11688c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois#endif 11788c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois } 11888c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois 11988c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois // rm, <shift> rs 12088c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois // where rm is the base register, and 12188c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois // <shift> is one of {LSL, LSR, ASR, ROR}, and 12288c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois // rs is the shifted register 12388c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois Operand(Register rm, Shift shift, Register rs) 12488c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois : imm_(0), rm_(rm), shift_(shift), amount_(0), rs_(rs) { 12588c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois VIXL_ASSERT(rm_.IsValid() && rs_.IsValid()); 12688c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois VIXL_ASSERT(!shift_.IsRRX()); 12788c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois } 12888c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois 129f5348cedd702124c90fc75e75d0195e2e485c620Pierre Langlois // Factory methods creating operands from any integral or pointer type. The 130f5348cedd702124c90fc75e75d0195e2e485c620Pierre Langlois // source must fit into 32 bits. 131f5348cedd702124c90fc75e75d0195e2e485c620Pierre Langlois template <typename T> 132f5348cedd702124c90fc75e75d0195e2e485c620Pierre Langlois static Operand From(T immediate) { 133f5348cedd702124c90fc75e75d0195e2e485c620Pierre Langlois#if __cplusplus >= 201103L 134f5348cedd702124c90fc75e75d0195e2e485c620Pierre Langlois VIXL_STATIC_ASSERT_MESSAGE(std::is_integral<T>::value, 135f5348cedd702124c90fc75e75d0195e2e485c620Pierre Langlois "An integral type is required to build an " 136f5348cedd702124c90fc75e75d0195e2e485c620Pierre Langlois "immediate operand."); 137f5348cedd702124c90fc75e75d0195e2e485c620Pierre Langlois#endif 138efe0c1f222c9b2da15755b221ee0fa232939ce80Pierre Langlois // Allow both a signed or unsigned 32 bit integer to be passed, but store it 139efe0c1f222c9b2da15755b221ee0fa232939ce80Pierre Langlois // as a uint32_t. The signedness information will be lost. We have to add a 140efe0c1f222c9b2da15755b221ee0fa232939ce80Pierre Langlois // static_cast to make sure the compiler does not complain about implicit 64 141efe0c1f222c9b2da15755b221ee0fa232939ce80Pierre Langlois // to 32 narrowing. It's perfectly acceptable for the user to pass a 64-bit 142efe0c1f222c9b2da15755b221ee0fa232939ce80Pierre Langlois // value, as long as it can be encoded in 32 bits. 143efe0c1f222c9b2da15755b221ee0fa232939ce80Pierre Langlois VIXL_ASSERT(IsInt32(immediate) || IsUint32(immediate)); 144f5348cedd702124c90fc75e75d0195e2e485c620Pierre Langlois return Operand(static_cast<uint32_t>(immediate)); 145f5348cedd702124c90fc75e75d0195e2e485c620Pierre Langlois } 146f5348cedd702124c90fc75e75d0195e2e485c620Pierre Langlois 147f5348cedd702124c90fc75e75d0195e2e485c620Pierre Langlois template <typename T> 148f5348cedd702124c90fc75e75d0195e2e485c620Pierre Langlois static Operand From(T* address) { 149f5348cedd702124c90fc75e75d0195e2e485c620Pierre Langlois uintptr_t address_as_integral = reinterpret_cast<uintptr_t>(address); 150f5348cedd702124c90fc75e75d0195e2e485c620Pierre Langlois VIXL_ASSERT(IsUint32(address_as_integral)); 151f5348cedd702124c90fc75e75d0195e2e485c620Pierre Langlois return Operand(static_cast<uint32_t>(address_as_integral)); 152f5348cedd702124c90fc75e75d0195e2e485c620Pierre Langlois } 153f5348cedd702124c90fc75e75d0195e2e485c620Pierre Langlois 15488c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois bool IsImmediate() const { return !rm_.IsValid(); } 15588c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois 15688c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois bool IsPlainRegister() const { 15788c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois return rm_.IsValid() && !shift_.IsRRX() && !rs_.IsValid() && (amount_ == 0); 15888c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois } 15988c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois 16088c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois bool IsImmediateShiftedRegister() const { 16188c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois return rm_.IsValid() && !rs_.IsValid(); 16288c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois } 16388c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois 16488c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois bool IsRegisterShiftedRegister() const { 16588c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois return rm_.IsValid() && rs_.IsValid(); 16688c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois } 16788c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois 16888c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois uint32_t GetImmediate() const { 16988c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois VIXL_ASSERT(IsImmediate()); 17088c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois return imm_; 17188c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois } 17288c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois 1732ec1f7562e90ebd295989c1323d59161a23dadfcMartyn Capewell int32_t GetSignedImmediate() const { 1742ec1f7562e90ebd295989c1323d59161a23dadfcMartyn Capewell VIXL_ASSERT(IsImmediate()); 1752ec1f7562e90ebd295989c1323d59161a23dadfcMartyn Capewell int32_t result; 1762ec1f7562e90ebd295989c1323d59161a23dadfcMartyn Capewell memcpy(&result, &imm_, sizeof(result)); 1772ec1f7562e90ebd295989c1323d59161a23dadfcMartyn Capewell return result; 1782ec1f7562e90ebd295989c1323d59161a23dadfcMartyn Capewell } 1792ec1f7562e90ebd295989c1323d59161a23dadfcMartyn Capewell 18088c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois Register GetBaseRegister() const { 18188c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois VIXL_ASSERT(IsImmediateShiftedRegister() || IsRegisterShiftedRegister()); 18288c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois return rm_; 18388c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois } 18488c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois 18588c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois Shift GetShift() const { 18688c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois VIXL_ASSERT(IsImmediateShiftedRegister() || IsRegisterShiftedRegister()); 18788c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois return shift_; 18888c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois } 18988c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois 19088c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois uint32_t GetShiftAmount() const { 19188c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois VIXL_ASSERT(IsImmediateShiftedRegister()); 19288c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois return amount_; 19388c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois } 19488c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois 19588c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois Register GetShiftRegister() const { 19688c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois VIXL_ASSERT(IsRegisterShiftedRegister()); 19788c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois return rs_; 19888c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois } 19988c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois 20088c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois uint32_t GetTypeEncodingValue() const { 20188c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois return shift_.IsRRX() ? kRRXEncodedValue : shift_.GetValue(); 20288c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois } 20388c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois 20488c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois private: 205f5348cedd702124c90fc75e75d0195e2e485c620Pierre Langlois// Forbid implicitely creating operands around types that cannot be encoded 206f5348cedd702124c90fc75e75d0195e2e485c620Pierre Langlois// into a uint32_t without loss. 207f5348cedd702124c90fc75e75d0195e2e485c620Pierre Langlois#if __cplusplus >= 201103L 20860241a544be0ebf48347789bf0ec268414364627Vincent Belliard Operand(int64_t) = delete; // NOLINT(runtime/explicit) 20960241a544be0ebf48347789bf0ec268414364627Vincent Belliard Operand(uint64_t) = delete; // NOLINT(runtime/explicit) 21060241a544be0ebf48347789bf0ec268414364627Vincent Belliard Operand(float) = delete; // NOLINT(runtime/explicit) 21160241a544be0ebf48347789bf0ec268414364627Vincent Belliard Operand(double) = delete; // NOLINT(runtime/explicit) 212f5348cedd702124c90fc75e75d0195e2e485c620Pierre Langlois#else 21334ecc5b8b9af49df5727cfc357db1fddc674cb44Jacob Bramley VIXL_NO_RETURN_IN_DEBUG_MODE Operand(int64_t) { // NOLINT(runtime/explicit) 214f5348cedd702124c90fc75e75d0195e2e485c620Pierre Langlois VIXL_UNREACHABLE(); 215f5348cedd702124c90fc75e75d0195e2e485c620Pierre Langlois } 21634ecc5b8b9af49df5727cfc357db1fddc674cb44Jacob Bramley VIXL_NO_RETURN_IN_DEBUG_MODE Operand(uint64_t) { // NOLINT(runtime/explicit) 217f5348cedd702124c90fc75e75d0195e2e485c620Pierre Langlois VIXL_UNREACHABLE(); 218f5348cedd702124c90fc75e75d0195e2e485c620Pierre Langlois } 21934ecc5b8b9af49df5727cfc357db1fddc674cb44Jacob Bramley VIXL_NO_RETURN_IN_DEBUG_MODE Operand(float) { // NOLINT 220f5348cedd702124c90fc75e75d0195e2e485c620Pierre Langlois VIXL_UNREACHABLE(); 221f5348cedd702124c90fc75e75d0195e2e485c620Pierre Langlois } 22234ecc5b8b9af49df5727cfc357db1fddc674cb44Jacob Bramley VIXL_NO_RETURN_IN_DEBUG_MODE Operand(double) { // NOLINT 223f5348cedd702124c90fc75e75d0195e2e485c620Pierre Langlois VIXL_UNREACHABLE(); 224f5348cedd702124c90fc75e75d0195e2e485c620Pierre Langlois } 225f5348cedd702124c90fc75e75d0195e2e485c620Pierre Langlois#endif 226f5348cedd702124c90fc75e75d0195e2e485c620Pierre Langlois 22788c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois uint32_t imm_; 22888c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois Register rm_; 22988c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois Shift shift_; 23088c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois uint32_t amount_; 23188c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois Register rs_; 23288c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois}; 23388c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois 23488c46b84df005638546de5e4e965bdcc31352f48Pierre Langloisstd::ostream& operator<<(std::ostream& os, const Operand& operand); 23588c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois 23688c46b84df005638546de5e4e965bdcc31352f48Pierre Langloisclass NeonImmediate { 23788c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois template <typename T> 23888c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois struct DataTypeIdentity { 23988c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois T data_type_; 24088c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois }; 24188c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois 24288c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois public: 24388c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois // { #<immediate> } 24488c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois // where <immediate> is 32 bit number. 24588c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois // This is allowed to be an implicit constructor because NeonImmediate is 24688c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois // a wrapper class that doesn't normally perform any type conversion. 24760241a544be0ebf48347789bf0ec268414364627Vincent Belliard NeonImmediate(uint32_t immediate) // NOLINT(runtime/explicit) 24888c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois : imm_(immediate), 24988c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois immediate_type_(I32) {} 25060241a544be0ebf48347789bf0ec268414364627Vincent Belliard NeonImmediate(int immediate) // NOLINT(runtime/explicit) 25188c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois : imm_(immediate), 25288c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois immediate_type_(I32) {} 25388c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois 25488c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois // { #<immediate> } 25588c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois // where <immediate> is a 64 bit number 25688c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois // This is allowed to be an implicit constructor because NeonImmediate is 25788c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois // a wrapper class that doesn't normally perform any type conversion. 25860241a544be0ebf48347789bf0ec268414364627Vincent Belliard NeonImmediate(int64_t immediate) // NOLINT(runtime/explicit) 25988c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois : imm_(immediate), 26088c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois immediate_type_(I64) {} 26160241a544be0ebf48347789bf0ec268414364627Vincent Belliard NeonImmediate(uint64_t immediate) // NOLINT(runtime/explicit) 26288c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois : imm_(immediate), 26388c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois immediate_type_(I64) {} 26488c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois 26588c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois // { #<immediate> } 26688c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois // where <immediate> is a non zero floating point number which can be encoded 26788c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois // as an 8 bit floating point (checked by the constructor). 26888c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois // This is allowed to be an implicit constructor because NeonImmediate is 26988c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois // a wrapper class that doesn't normally perform any type conversion. 27060241a544be0ebf48347789bf0ec268414364627Vincent Belliard NeonImmediate(float immediate) // NOLINT(runtime/explicit) 27188c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois : imm_(immediate), 27288c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois immediate_type_(F32) {} 27360241a544be0ebf48347789bf0ec268414364627Vincent Belliard NeonImmediate(double immediate) // NOLINT(runtime/explicit) 27488c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois : imm_(immediate), 27588c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois immediate_type_(F64) {} 27688c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois 27788c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois NeonImmediate(const NeonImmediate& src) 27888c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois : imm_(src.imm_), immediate_type_(src.immediate_type_) {} 27988c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois 28088c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois template <typename T> 28188c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois T GetImmediate() const { 28288c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois return GetImmediate(DataTypeIdentity<T>()); 28388c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois } 28488c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois 28588c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois template <typename T> 28688c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois T GetImmediate(const DataTypeIdentity<T>&) const { 28788c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois VIXL_ASSERT(sizeof(T) <= sizeof(uint32_t)); 28888c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois VIXL_ASSERT(CanConvert<T>()); 28988c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois if (immediate_type_.Is(I64)) 29088c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois return static_cast<T>(imm_.u64_ & static_cast<T>(-1)); 29188c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois if (immediate_type_.Is(F64) || immediate_type_.Is(F32)) return 0; 29288c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois return static_cast<T>(imm_.u32_ & static_cast<T>(-1)); 29388c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois } 29488c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois 29588c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois uint64_t GetImmediate(const DataTypeIdentity<uint64_t>&) const { 29688c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois VIXL_ASSERT(CanConvert<uint64_t>()); 29788c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois if (immediate_type_.Is(I32)) return imm_.u32_; 29888c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois if (immediate_type_.Is(F64) || immediate_type_.Is(F32)) return 0; 29988c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois return imm_.u64_; 30088c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois } 30188c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois float GetImmediate(const DataTypeIdentity<float>&) const { 30288c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois VIXL_ASSERT(CanConvert<float>()); 30388c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois if (immediate_type_.Is(F64)) return static_cast<float>(imm_.d_); 30488c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois return imm_.f_; 30588c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois } 30688c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois double GetImmediate(const DataTypeIdentity<double>&) const { 30788c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois VIXL_ASSERT(CanConvert<double>()); 30888c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois if (immediate_type_.Is(F32)) return static_cast<double>(imm_.f_); 30988c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois return imm_.d_; 31088c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois } 31188c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois 31288c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois bool IsInteger32() const { return immediate_type_.Is(I32); } 31388c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois bool IsInteger64() const { return immediate_type_.Is(I64); } 31488c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois bool IsInteger() const { return IsInteger32() | IsInteger64(); } 31588c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois bool IsFloat() const { return immediate_type_.Is(F32); } 31688c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois bool IsDouble() const { return immediate_type_.Is(F64); } 31788c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois 31888c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois template <typename T> 31988c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois bool CanConvert() const { 32088c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois return CanConvert(DataTypeIdentity<T>()); 32188c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois } 32288c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois 32388c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois template <typename T> 32488c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois bool CanConvert(const DataTypeIdentity<T>&) const { 32588c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois VIXL_ASSERT(sizeof(T) < sizeof(uint32_t)); 32688c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois return (immediate_type_.Is(I32) && ((imm_.u32_ >> (8 * sizeof(T))) == 0)) || 32788c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois (immediate_type_.Is(I64) && ((imm_.u64_ >> (8 * sizeof(T))) == 0)) || 32888c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois (immediate_type_.Is(F32) && (imm_.f_ == 0.0f)) || 32988c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois (immediate_type_.Is(F64) && (imm_.d_ == 0.0)); 33088c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois } 33188c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois bool CanConvert(const DataTypeIdentity<uint32_t>&) const { 33288c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois return immediate_type_.Is(I32) || 33388c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois (immediate_type_.Is(I64) && ((imm_.u64_ >> 32) == 0)) || 33488c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois (immediate_type_.Is(F32) && (imm_.f_ == 0.0f)) || 33588c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois (immediate_type_.Is(F64) && (imm_.d_ == 0.0)); 33688c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois } 33788c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois bool CanConvert(const DataTypeIdentity<uint64_t>&) const { 33888c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois return IsInteger() || CanConvert<uint32_t>(); 33988c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois } 34088c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois bool CanConvert(const DataTypeIdentity<float>&) const { 34188c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois return IsFloat() || IsDouble(); 34288c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois } 34388c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois bool CanConvert(const DataTypeIdentity<double>&) const { 34488c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois return IsFloat() || IsDouble(); 34588c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois } 34688c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois friend std::ostream& operator<<(std::ostream& os, 34788c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois const NeonImmediate& operand); 34888c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois 34988c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois private: 35088c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois union NeonImmediateType { 35188c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois uint64_t u64_; 35288c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois double d_; 35388c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois uint32_t u32_; 35488c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois float f_; 35588c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois NeonImmediateType(uint64_t u) : u64_(u) {} 35688c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois NeonImmediateType(int64_t u) : u64_(u) {} 35788c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois NeonImmediateType(uint32_t u) : u32_(u) {} 35888c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois NeonImmediateType(int32_t u) : u32_(u) {} 35988c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois NeonImmediateType(double d) : d_(d) {} 36088c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois NeonImmediateType(float f) : f_(f) {} 36188c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois NeonImmediateType(const NeonImmediateType& ref) : u64_(ref.u64_) {} 36288c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois } imm_; 36388c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois 36488c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois DataType immediate_type_; 36588c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois}; 36688c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois 36788c46b84df005638546de5e4e965bdcc31352f48Pierre Langloisstd::ostream& operator<<(std::ostream& os, const NeonImmediate& operand); 36888c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois 36988c46b84df005638546de5e4e965bdcc31352f48Pierre Langloisclass NeonOperand { 37088c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois public: 37160241a544be0ebf48347789bf0ec268414364627Vincent Belliard NeonOperand(int32_t immediate) // NOLINT(runtime/explicit) 37288c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois : imm_(immediate), 37388c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois rm_(NoDReg) {} 37460241a544be0ebf48347789bf0ec268414364627Vincent Belliard NeonOperand(uint32_t immediate) // NOLINT(runtime/explicit) 37588c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois : imm_(immediate), 37688c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois rm_(NoDReg) {} 37760241a544be0ebf48347789bf0ec268414364627Vincent Belliard NeonOperand(int64_t immediate) // NOLINT(runtime/explicit) 37888c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois : imm_(immediate), 37988c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois rm_(NoDReg) {} 38060241a544be0ebf48347789bf0ec268414364627Vincent Belliard NeonOperand(uint64_t immediate) // NOLINT(runtime/explicit) 38188c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois : imm_(immediate), 38288c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois rm_(NoDReg) {} 38360241a544be0ebf48347789bf0ec268414364627Vincent Belliard NeonOperand(float immediate) // NOLINT(runtime/explicit) 38488c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois : imm_(immediate), 38588c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois rm_(NoDReg) {} 38660241a544be0ebf48347789bf0ec268414364627Vincent Belliard NeonOperand(double immediate) // NOLINT(runtime/explicit) 38788c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois : imm_(immediate), 38888c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois rm_(NoDReg) {} 38960241a544be0ebf48347789bf0ec268414364627Vincent Belliard NeonOperand(const NeonImmediate& imm) // NOLINT(runtime/explicit) 39088c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois : imm_(imm), 39188c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois rm_(NoDReg) {} 392cf4d2842eb8d63c621d7003e240ec094a357cad0Jacob Bramley NeonOperand(const VRegister& rm) // NOLINT(runtime/explicit) 39388c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois : imm_(0), 39488c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois rm_(rm) { 39588c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois VIXL_ASSERT(rm_.IsValid()); 39688c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois } 39788c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois 39888c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois bool IsImmediate() const { return !rm_.IsValid(); } 39988c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois bool IsRegister() const { return rm_.IsValid(); } 40088c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois 40188c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois const NeonImmediate& GetNeonImmediate() const { return imm_; } 40288c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois 403cf4d2842eb8d63c621d7003e240ec094a357cad0Jacob Bramley VRegister GetRegister() const { 404cf4d2842eb8d63c621d7003e240ec094a357cad0Jacob Bramley VIXL_ASSERT(IsRegister()); 405cf4d2842eb8d63c621d7003e240ec094a357cad0Jacob Bramley return rm_; 406cf4d2842eb8d63c621d7003e240ec094a357cad0Jacob Bramley } 407cf4d2842eb8d63c621d7003e240ec094a357cad0Jacob Bramley 40888c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois protected: 40988c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois NeonImmediate imm_; 410cf4d2842eb8d63c621d7003e240ec094a357cad0Jacob Bramley VRegister rm_; 41188c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois}; 41288c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois 41388c46b84df005638546de5e4e965bdcc31352f48Pierre Langloisstd::ostream& operator<<(std::ostream& os, const NeonOperand& operand); 41488c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois 41588c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois// SOperand represents either an immediate or a SRegister. 41688c46b84df005638546de5e4e965bdcc31352f48Pierre Langloisclass SOperand : public NeonOperand { 41788c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois public: 41888c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois // #<immediate> 41988c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois // where <immediate> is 32bit int 42088c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois // This is allowed to be an implicit constructor because SOperand is 42188c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois // a wrapper class that doesn't normally perform any type conversion. 42260241a544be0ebf48347789bf0ec268414364627Vincent Belliard SOperand(int32_t immediate) // NOLINT(runtime/explicit) 42388c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois : NeonOperand(immediate) {} 42460241a544be0ebf48347789bf0ec268414364627Vincent Belliard SOperand(uint32_t immediate) // NOLINT(runtime/explicit) 42588c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois : NeonOperand(immediate) {} 42688c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois // #<immediate> 42788c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois // where <immediate> is 32bit float 42860241a544be0ebf48347789bf0ec268414364627Vincent Belliard SOperand(float immediate) // NOLINT(runtime/explicit) 42988c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois : NeonOperand(immediate) {} 43088c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois 43188c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois SOperand(const NeonImmediate& imm) // NOLINT(runtime/explicit) 43288c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois : NeonOperand(imm) {} 43388c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois 43488c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois // rm 43588c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois // This is allowed to be an implicit constructor because SOperand is 43688c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois // a wrapper class that doesn't normally perform any type conversion. 43760241a544be0ebf48347789bf0ec268414364627Vincent Belliard SOperand(SRegister rm) // NOLINT(runtime/explicit) 43888c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois : NeonOperand(rm) {} 43988c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois SRegister GetRegister() const { 44088c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois VIXL_ASSERT(IsRegister() && (rm_.GetType() == CPURegister::kSRegister)); 44188c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois return SRegister(rm_.GetCode()); 44288c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois } 44388c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois}; 44488c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois 44588c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois// DOperand represents either an immediate or a DRegister. 44688c46b84df005638546de5e4e965bdcc31352f48Pierre Langloisstd::ostream& operator<<(std::ostream& os, const SOperand& operand); 44788c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois 44888c46b84df005638546de5e4e965bdcc31352f48Pierre Langloisclass DOperand : public NeonOperand { 44988c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois public: 45088c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois // #<immediate> 45188c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois // where <immediate> is uint32_t. 45288c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois // This is allowed to be an implicit constructor because DOperand is 45388c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois // a wrapper class that doesn't normally perform any type conversion. 45460241a544be0ebf48347789bf0ec268414364627Vincent Belliard DOperand(int32_t immediate) // NOLINT(runtime/explicit) 45588c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois : NeonOperand(immediate) {} 45660241a544be0ebf48347789bf0ec268414364627Vincent Belliard DOperand(uint32_t immediate) // NOLINT(runtime/explicit) 45788c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois : NeonOperand(immediate) {} 45860241a544be0ebf48347789bf0ec268414364627Vincent Belliard DOperand(int64_t immediate) // NOLINT(runtime/explicit) 45988c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois : NeonOperand(immediate) {} 46060241a544be0ebf48347789bf0ec268414364627Vincent Belliard DOperand(uint64_t immediate) // NOLINT(runtime/explicit) 46188c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois : NeonOperand(immediate) {} 46288c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois 46388c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois // #<immediate> 46488c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois // where <immediate> is a non zero floating point number which can be encoded 46588c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois // as an 8 bit floating point (checked by the constructor). 46688c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois // This is allowed to be an implicit constructor because DOperand is 46788c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois // a wrapper class that doesn't normally perform any type conversion. 46860241a544be0ebf48347789bf0ec268414364627Vincent Belliard DOperand(float immediate) // NOLINT(runtime/explicit) 46988c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois : NeonOperand(immediate) {} 47060241a544be0ebf48347789bf0ec268414364627Vincent Belliard DOperand(double immediate) // NOLINT(runtime/explicit) 47188c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois : NeonOperand(immediate) {} 47288c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois 47388c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois DOperand(const NeonImmediate& imm) // NOLINT(runtime/explicit) 47488c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois : NeonOperand(imm) {} 47588c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois // rm 47688c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois // This is allowed to be an implicit constructor because DOperand is 47788c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois // a wrapper class that doesn't normally perform any type conversion. 47860241a544be0ebf48347789bf0ec268414364627Vincent Belliard DOperand(DRegister rm) // NOLINT(runtime/explicit) 47988c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois : NeonOperand(rm) {} 48088c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois 48188c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois DRegister GetRegister() const { 48288c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois VIXL_ASSERT(IsRegister() && (rm_.GetType() == CPURegister::kDRegister)); 48388c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois return DRegister(rm_.GetCode()); 48488c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois } 48588c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois}; 48688c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois 48788c46b84df005638546de5e4e965bdcc31352f48Pierre Langloisstd::ostream& operator<<(std::ostream& os, const DOperand& operand); 48888c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois 48988c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois// QOperand represents either an immediate or a QRegister. 49088c46b84df005638546de5e4e965bdcc31352f48Pierre Langloisclass QOperand : public NeonOperand { 49188c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois public: 49288c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois // #<immediate> 49388c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois // where <immediate> is uint32_t. 49488c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois // This is allowed to be an implicit constructor because QOperand is 49588c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois // a wrapper class that doesn't normally perform any type conversion. 49660241a544be0ebf48347789bf0ec268414364627Vincent Belliard QOperand(int32_t immediate) // NOLINT(runtime/explicit) 49788c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois : NeonOperand(immediate) {} 49860241a544be0ebf48347789bf0ec268414364627Vincent Belliard QOperand(uint32_t immediate) // NOLINT(runtime/explicit) 49988c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois : NeonOperand(immediate) {} 50060241a544be0ebf48347789bf0ec268414364627Vincent Belliard QOperand(int64_t immediate) // NOLINT(runtime/explicit) 50188c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois : NeonOperand(immediate) {} 50260241a544be0ebf48347789bf0ec268414364627Vincent Belliard QOperand(uint64_t immediate) // NOLINT(runtime/explicit) 50388c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois : NeonOperand(immediate) {} 50460241a544be0ebf48347789bf0ec268414364627Vincent Belliard QOperand(float immediate) // NOLINT(runtime/explicit) 50588c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois : NeonOperand(immediate) {} 50660241a544be0ebf48347789bf0ec268414364627Vincent Belliard QOperand(double immediate) // NOLINT(runtime/explicit) 50788c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois : NeonOperand(immediate) {} 50888c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois 50988c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois QOperand(const NeonImmediate& imm) // NOLINT(runtime/explicit) 51088c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois : NeonOperand(imm) {} 51188c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois 51288c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois // rm 51388c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois // This is allowed to be an implicit constructor because QOperand is 51488c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois // a wrapper class that doesn't normally perform any type conversion. 51560241a544be0ebf48347789bf0ec268414364627Vincent Belliard QOperand(QRegister rm) // NOLINT(runtime/explicit) 51688c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois : NeonOperand(rm) { 51788c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois VIXL_ASSERT(rm_.IsValid()); 51888c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois } 51988c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois 52088c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois QRegister GetRegister() const { 52188c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois VIXL_ASSERT(IsRegister() && (rm_.GetType() == CPURegister::kQRegister)); 52288c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois return QRegister(rm_.GetCode()); 52388c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois } 52488c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois}; 52588c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois 52688c46b84df005638546de5e4e965bdcc31352f48Pierre Langloisstd::ostream& operator<<(std::ostream& os, const QOperand& operand); 52788c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois 52888c46b84df005638546de5e4e965bdcc31352f48Pierre Langloisclass ImmediateVFP : public EncodingValue { 52988c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois template <typename T> 53088c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois struct FloatType { 53188c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois typedef T base_type; 53288c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois }; 53388c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois 53488c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois public: 53588c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois explicit ImmediateVFP(const NeonImmediate& neon_imm) { 53688c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois if (neon_imm.IsFloat()) { 53788c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois const float imm = neon_imm.GetImmediate<float>(); 53888c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois if (VFP::IsImmFP32(imm)) { 53988c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois SetEncodingValue(VFP::FP32ToImm8(imm)); 54088c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois } 54188c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois } else if (neon_imm.IsDouble()) { 54288c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois const double imm = neon_imm.GetImmediate<double>(); 54388c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois if (VFP::IsImmFP64(imm)) { 54488c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois SetEncodingValue(VFP::FP32ToImm8(imm)); 54588c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois } 54688c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois } 54788c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois } 54888c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois 54988c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois template <typename T> 55088c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois static T Decode(uint32_t v) { 55188c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois return Decode(v, FloatType<T>()); 55288c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois } 55388c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois 55488c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois static float Decode(uint32_t imm8, const FloatType<float>&) { 55588c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois return VFP::Imm8ToFP32(imm8); 55688c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois } 55788c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois 55888c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois static double Decode(uint32_t imm8, const FloatType<double>&) { 55988c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois return VFP::Imm8ToFP64(imm8); 56088c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois } 56188c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois}; 56288c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois 56388c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois 56488c46b84df005638546de5e4e965bdcc31352f48Pierre Langloisclass ImmediateVbic : public EncodingValueAndImmediate { 56588c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois public: 56688c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois ImmediateVbic(DataType dt, const NeonImmediate& neon_imm); 56788c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois static DataType DecodeDt(uint32_t cmode); 56888c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois static NeonImmediate DecodeImmediate(uint32_t cmode, uint32_t immediate); 56988c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois}; 57088c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois 57188c46b84df005638546de5e4e965bdcc31352f48Pierre Langloisclass ImmediateVand : public ImmediateVbic { 57288c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois public: 57388c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois ImmediateVand(DataType dt, const NeonImmediate neon_imm) 57488c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois : ImmediateVbic(dt, neon_imm) { 57588c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois if (IsValid()) { 57688c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois SetEncodedImmediate(~GetEncodedImmediate() & 0xff); 57788c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois } 57888c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois } 57988c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois}; 58088c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois 58188c46b84df005638546de5e4e965bdcc31352f48Pierre Langloisclass ImmediateVmov : public EncodingValueAndImmediate { 58288c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois public: 58388c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois ImmediateVmov(DataType dt, const NeonImmediate& neon_imm); 58488c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois static DataType DecodeDt(uint32_t cmode); 58588c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois static NeonImmediate DecodeImmediate(uint32_t cmode, uint32_t immediate); 58688c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois}; 58788c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois 58888c46b84df005638546de5e4e965bdcc31352f48Pierre Langloisclass ImmediateVmvn : public EncodingValueAndImmediate { 58988c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois public: 59088c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois ImmediateVmvn(DataType dt, const NeonImmediate& neon_imm); 59188c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois static DataType DecodeDt(uint32_t cmode); 59288c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois static NeonImmediate DecodeImmediate(uint32_t cmode, uint32_t immediate); 59388c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois}; 59488c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois 59588c46b84df005638546de5e4e965bdcc31352f48Pierre Langloisclass ImmediateVorr : public EncodingValueAndImmediate { 59688c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois public: 59788c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois ImmediateVorr(DataType dt, const NeonImmediate& neon_imm); 59888c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois static DataType DecodeDt(uint32_t cmode); 59988c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois static NeonImmediate DecodeImmediate(uint32_t cmode, uint32_t immediate); 60088c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois}; 60188c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois 60288c46b84df005638546de5e4e965bdcc31352f48Pierre Langloisclass ImmediateVorn : public ImmediateVorr { 60388c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois public: 60488c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois ImmediateVorn(DataType dt, const NeonImmediate& neon_imm) 60588c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois : ImmediateVorr(dt, neon_imm) { 60688c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois if (IsValid()) { 60788c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois SetEncodedImmediate(~GetEncodedImmediate() & 0xff); 60888c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois } 60988c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois } 61088c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois}; 61188c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois 61288c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois// MemOperand represents the addressing mode of a load or store instruction. 61388c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois// 61488c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois// Usage: <instr> <Rt> , <MemOperand> 61588c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois// 61688c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois// where <instr> is the instruction to use (e.g., Ldr(), Str(), etc.), 61788c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois// <Rt> is general purpose register to be transferred, 61888c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois// <MemOperand> is the rest of the arguments to the instruction 61988c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois// 62088c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois// <MemOperand> can be in one of 3 addressing modes: 62188c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois// 62288c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois// [ <Rn>, <offset> ] == offset addressing 62388c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois// [ <Rn>, <offset> ]! == pre-indexed addressing 62488c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois// [ <Rn> ], <offset> == post-indexed addressing 62588c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois// 62688c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois// where <offset> can be one of: 62788c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois// - an immediate constant, such as <imm8>, <imm12> 62888c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois// - an index register <Rm> 62988c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois// - a shifted index register <Rm>, <shift> #<amount> 63088c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois// 63188c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois// The index register may have an associated {+/-} sign, 63288c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois// which if ommitted, defaults to + . 63388c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois// 6347f24bc630745306bf9be3881b510e00bbbf19ae3Vincent Belliard// We have two constructors for the offset: 6357f24bc630745306bf9be3881b510e00bbbf19ae3Vincent Belliard// 6367f24bc630745306bf9be3881b510e00bbbf19ae3Vincent Belliard// One with a signed value offset parameter. The value of sign_ is 6377f24bc630745306bf9be3881b510e00bbbf19ae3Vincent Belliard// "sign_of(constructor's offset parameter) and the value of offset_ is 6387f24bc630745306bf9be3881b510e00bbbf19ae3Vincent Belliard// "constructor's offset parameter". 6397f24bc630745306bf9be3881b510e00bbbf19ae3Vincent Belliard// 6407f24bc630745306bf9be3881b510e00bbbf19ae3Vincent Belliard// The other with a sign and a positive value offset parameters. The value of 6417f24bc630745306bf9be3881b510e00bbbf19ae3Vincent Belliard// sign_ is "constructor's sign parameter" and the value of offset_ is 6427f24bc630745306bf9be3881b510e00bbbf19ae3Vincent Belliard// "constructor's sign parameter * constructor's offset parameter". 6437f24bc630745306bf9be3881b510e00bbbf19ae3Vincent Belliard// 6447f24bc630745306bf9be3881b510e00bbbf19ae3Vincent Belliard// The value of offset_ reflects the effective offset. For an offset_ of 0, 6457f24bc630745306bf9be3881b510e00bbbf19ae3Vincent Belliard// sign_ can be positive or negative. Otherwise, sign_ always agrees with 6467f24bc630745306bf9be3881b510e00bbbf19ae3Vincent Belliard// the sign of offset_. 64788c46b84df005638546de5e4e965bdcc31352f48Pierre Langloisclass MemOperand { 64888c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois public: 64988c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois // rn 65088c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois // where rn is the general purpose base register only 651024aa58e9d83147f57a2509cf115b9fc9d260477Alexandre Rames explicit MemOperand(Register rn, AddrMode addrmode = Offset) 65288c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois : rn_(rn), 65388c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois offset_(0), 65488c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois sign_(plus), 65588c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois rm_(NoReg), 65688c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois shift_(LSL), 65788c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois shift_amount_(0), 65888c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois addrmode_(addrmode | kMemOperandRegisterOnly) { 65988c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois VIXL_ASSERT(rn_.IsValid()); 66088c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois } 66188c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois 66288c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois // rn, #<imm> 66388c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois // where rn is the general purpose base register, 66488c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois // <imm> is a 32-bit offset to add to rn 66588c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois // 66688c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois // Note: if rn is PC, then this form is equivalent to a "label" 66788c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois // Note: the second constructor allow minus zero (-0). 66888c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois MemOperand(Register rn, int32_t offset, AddrMode addrmode = Offset) 66988c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois : rn_(rn), 67088c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois offset_(offset), 67188c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois sign_((offset < 0) ? minus : plus), 67288c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois rm_(NoReg), 67388c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois shift_(LSL), 67488c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois shift_amount_(0), 67588c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois addrmode_(addrmode) { 67688c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois VIXL_ASSERT(rn_.IsValid()); 67788c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois } 67888c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois MemOperand(Register rn, Sign sign, int32_t offset, AddrMode addrmode = Offset) 67988c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois : rn_(rn), 68088c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois offset_(sign.IsPlus() ? offset : -offset), 68188c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois sign_(sign), 68288c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois rm_(NoReg), 68388c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois shift_(LSL), 68488c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois shift_amount_(0), 68588c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois addrmode_(addrmode) { 68688c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois VIXL_ASSERT(rn_.IsValid()); 68788c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois // With this constructor, the sign must only be specified by "sign". 68888c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois VIXL_ASSERT(offset >= 0); 68988c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois } 69088c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois 69188c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois // rn, {+/-}rm 69288c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois // where rn is the general purpose base register, 69388c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois // {+/-} is the sign of the index register, 69488c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois // rm is the general purpose index register, 69588c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois MemOperand(Register rn, Sign sign, Register rm, AddrMode addrmode = Offset) 69688c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois : rn_(rn), 69788c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois offset_(0), 69888c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois sign_(sign), 69988c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois rm_(rm), 70088c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois shift_(LSL), 70188c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois shift_amount_(0), 70288c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois addrmode_(addrmode) { 70388c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois VIXL_ASSERT(rn_.IsValid() && rm_.IsValid()); 70488c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois } 70588c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois 70688c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois // rn, rm 70788c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois // where rn is the general purpose base register, 70888c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois // rm is the general purpose index register, 70988c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois MemOperand(Register rn, Register rm, AddrMode addrmode = Offset) 71088c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois : rn_(rn), 71188c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois offset_(0), 71288c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois sign_(plus), 71388c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois rm_(rm), 71488c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois shift_(LSL), 71588c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois shift_amount_(0), 71688c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois addrmode_(addrmode) { 71788c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois VIXL_ASSERT(rn_.IsValid() && rm_.IsValid()); 71888c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois } 71988c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois 72088c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois // rn, {+/-}rm, <shift> 72188c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois // where rn is the general purpose base register, 72288c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois // {+/-} is the sign of the index register, 72388c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois // rm is the general purpose index register, 72488c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois // <shift> is RRX, applied to value from rm 72588c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois MemOperand(Register rn, 72688c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois Sign sign, 72788c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois Register rm, 72888c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois Shift shift, 72988c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois AddrMode addrmode = Offset) 73088c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois : rn_(rn), 73188c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois offset_(0), 73288c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois sign_(sign), 73388c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois rm_(rm), 73488c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois shift_(shift), 73588c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois shift_amount_(0), 73688c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois addrmode_(addrmode) { 73788c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois VIXL_ASSERT(rn_.IsValid() && rm_.IsValid()); 73888c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois VIXL_ASSERT(shift_.IsRRX()); 73988c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois } 74088c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois 74188c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois // rn, rm, <shift> 74288c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois // where rn is the general purpose base register, 74388c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois // rm is the general purpose index register, 74488c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois // <shift> is RRX, applied to value from rm 74588c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois MemOperand(Register rn, Register rm, Shift shift, AddrMode addrmode = Offset) 74688c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois : rn_(rn), 74788c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois offset_(0), 74888c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois sign_(plus), 74988c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois rm_(rm), 75088c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois shift_(shift), 75188c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois shift_amount_(0), 75288c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois addrmode_(addrmode) { 75388c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois VIXL_ASSERT(rn_.IsValid() && rm_.IsValid()); 75488c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois VIXL_ASSERT(shift_.IsRRX()); 75588c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois } 75688c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois 75788c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois // rn, {+/-}rm, <shift> #<amount> 75888c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois // where rn is the general purpose base register, 75988c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois // {+/-} is the sign of the index register, 76088c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois // rm is the general purpose index register, 76188c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois // <shift> is one of {LSL, LSR, ASR, ROR}, applied to value from rm 76288c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois // <shift_amount> is optional size to apply to value from rm 76388c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois MemOperand(Register rn, 76488c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois Sign sign, 76588c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois Register rm, 76688c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois Shift shift, 76788c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois uint32_t shift_amount, 76888c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois AddrMode addrmode = Offset) 76988c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois : rn_(rn), 77088c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois offset_(0), 77188c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois sign_(sign), 77288c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois rm_(rm), 77388c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois shift_(shift), 77488c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois shift_amount_(shift_amount), 77588c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois addrmode_(addrmode) { 77688c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois VIXL_ASSERT(rn_.IsValid() && rm_.IsValid()); 77788c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois CheckShift(); 77888c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois } 77988c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois 78088c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois // rn, rm, <shift> #<amount> 78188c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois // where rn is the general purpose base register, 78288c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois // rm is the general purpose index register, 78388c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois // <shift> is one of {LSL, LSR, ASR, ROR}, applied to value from rm 78488c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois // <shift_amount> is optional size to apply to value from rm 78588c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois MemOperand(Register rn, 78688c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois Register rm, 78788c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois Shift shift, 78888c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois uint32_t shift_amount, 78988c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois AddrMode addrmode = Offset) 79088c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois : rn_(rn), 79188c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois offset_(0), 79288c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois sign_(plus), 79388c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois rm_(rm), 79488c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois shift_(shift), 79588c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois shift_amount_(shift_amount), 79688c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois addrmode_(addrmode) { 79788c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois VIXL_ASSERT(rn_.IsValid() && rm_.IsValid()); 79888c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois CheckShift(); 79988c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois } 80088c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois 80188c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois Register GetBaseRegister() const { return rn_; } 80288c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois int32_t GetOffsetImmediate() const { return offset_; } 80388c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois bool IsOffsetImmediateWithinRange(int min, 80488c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois int max, 80588c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois int multiple_of = 1) const { 80688c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois return (offset_ >= min) && (offset_ <= max) && 80788c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois ((offset_ % multiple_of) == 0); 80888c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois } 80988c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois Sign GetSign() const { return sign_; } 81088c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois Register GetOffsetRegister() const { return rm_; } 81188c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois Shift GetShift() const { return shift_; } 81288c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois unsigned GetShiftAmount() const { return shift_amount_; } 81388c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois AddrMode GetAddrMode() const { 81488c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois return static_cast<AddrMode>(addrmode_ & kMemOperandAddrModeMask); 81588c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois } 81688c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois bool IsRegisterOnly() const { 81788c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois return (addrmode_ & kMemOperandRegisterOnly) != 0; 81888c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois } 81988c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois 82088c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois bool IsImmediate() const { return !rm_.IsValid(); } 82188c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois bool IsImmediateZero() const { return !rm_.IsValid() && (offset_ == 0); } 82288c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois bool IsPlainRegister() const { 82388c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois return rm_.IsValid() && shift_.IsLSL() && (shift_amount_ == 0); 82488c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois } 82588c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois bool IsShiftedRegister() const { return rm_.IsValid(); } 82688c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois bool IsImmediateOffset() const { 82788c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois return (GetAddrMode() == Offset) && !rm_.IsValid(); 82888c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois } 82988c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois bool IsImmediateZeroOffset() const { 83088c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois return (GetAddrMode() == Offset) && !rm_.IsValid() && (offset_ == 0); 83188c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois } 83288c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois bool IsRegisterOffset() const { 83388c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois return (GetAddrMode() == Offset) && rm_.IsValid() && shift_.IsLSL() && 83488c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois (shift_amount_ == 0); 83588c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois } 83688c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois bool IsShiftedRegisterOffset() const { 83788c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois return (GetAddrMode() == Offset) && rm_.IsValid(); 83888c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois } 83988c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois uint32_t GetTypeEncodingValue() const { 84088c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois return shift_.IsRRX() ? kRRXEncodedValue : shift_.GetValue(); 84188c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois } 84288c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois bool IsOffset() const { return GetAddrMode() == Offset; } 84388c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois bool IsPreIndex() const { return GetAddrMode() == PreIndex; } 84488c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois bool IsPostIndex() const { return GetAddrMode() == PostIndex; } 84588c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois bool IsShiftValid() const { return shift_.IsValidAmount(shift_amount_); } 84688c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois 84788c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois private: 84888c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois static const int kMemOperandRegisterOnly = 0x1000; 84988c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois static const int kMemOperandAddrModeMask = 0xfff; 85088c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois void CheckShift() { 85188c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois#ifdef VIXL_DEBUG 85288c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois // Disallow any zero shift other than RRX #0 and LSL #0 . 85388c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois if ((shift_amount_ == 0) && shift_.IsRRX()) return; 85488c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois if ((shift_amount_ == 0) && !shift_.IsLSL()) { 85588c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois VIXL_ABORT_WITH_MSG( 85688c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois "A shift by 0 is only accepted in " 857028fb0566f6af6d839d34ccfec754ba394510302Jacob Bramley "the case of lsl and will be treated as " 858028fb0566f6af6d839d34ccfec754ba394510302Jacob Bramley "no shift.\n"); 85988c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois } 86088c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois switch (shift_.GetType()) { 86188c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois case LSL: 86288c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois VIXL_ASSERT(shift_amount_ <= 31); 86388c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois break; 86488c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois case ROR: 86588c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois VIXL_ASSERT(shift_amount_ <= 31); 86688c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois break; 86788c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois case LSR: 86888c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois case ASR: 86988c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois VIXL_ASSERT(shift_amount_ <= 32); 87088c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois break; 87188c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois case RRX: 87288c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois default: 87388c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois VIXL_UNREACHABLE(); 87488c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois break; 87588c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois } 87688c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois#endif 87788c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois } 87888c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois Register rn_; 87988c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois int32_t offset_; 88088c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois Sign sign_; 88188c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois Register rm_; 88288c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois Shift shift_; 88388c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois uint32_t shift_amount_; 88488c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois uint32_t addrmode_; 88588c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois}; 88688c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois 88788c46b84df005638546de5e4e965bdcc31352f48Pierre Langloisstd::ostream& operator<<(std::ostream& os, const MemOperand& operand); 88888c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois 88988c46b84df005638546de5e4e965bdcc31352f48Pierre Langloisclass AlignedMemOperand : public MemOperand { 89088c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois public: 89188c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois AlignedMemOperand(Register rn, Alignment align, AddrMode addrmode = Offset) 89288c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois : MemOperand(rn, addrmode), align_(align) { 89388c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois VIXL_ASSERT(addrmode != PreIndex); 89488c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois } 89588c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois 89688c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois AlignedMemOperand(Register rn, 89788c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois Alignment align, 89888c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois Register rm, 89988c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois AddrMode addrmode) 90088c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois : MemOperand(rn, rm, addrmode), align_(align) { 90188c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois VIXL_ASSERT(addrmode != PreIndex); 90288c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois } 90388c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois 90488c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois Alignment GetAlignment() const { return align_; } 90588c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois 90688c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois private: 90788c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois Alignment align_; 90888c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois}; 90988c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois 91088c46b84df005638546de5e4e965bdcc31352f48Pierre Langloisstd::ostream& operator<<(std::ostream& os, const AlignedMemOperand& operand); 91188c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois 91288c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois} // namespace aarch32 91388c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois} // namespace vixl 91488c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois 915989663e3cb7be8ac458d71f8e8d99afd29b13a39Pierre Langlois#endif // VIXL_AARCH32_OPERANDS_AARCH32_H_ 916