// Copyright 2015, ARM Limited // All rights reserved. // // Redistribution and use in source and binary forms, with or without // modification, are permitted provided that the following conditions are met: // // * Redistributions of source code must retain the above copyright notice, // this list of conditions and the following disclaimer. // * Redistributions in binary form must reproduce the above copyright notice, // this list of conditions and the following disclaimer in the documentation // and/or other materials provided with the distribution. // * Neither the name of ARM Limited nor the names of its contributors may be // used to endorse or promote products derived from this software without // specific prior written permission. // // THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS CONTRIBUTORS "AS IS" AND // ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED // WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE // DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE // FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL // DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR // SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER // CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, // OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE // OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
#include"jit/arm64/vixl/Instructions-vixl.h"
#include"jit/arm64/vixl/Assembler-vixl.h"
namespace vixl {
static uint64_t RepeatBitsAcrossReg(unsigned reg_size,
uint64_t value, unsigned width) {
VIXL_ASSERT((width == 2) || (width == 4) || (width == 8) || (width == 16) ||
(width == 32));
VIXL_ASSERT((reg_size == kWRegSize) || (reg_size == kXRegSize));
uint64_t result = value & ((UINT64_C(1) << width) - 1); for (unsigned i = width; i < reg_size; i *= 2) {
result |= (result << i);
} return result;
}
if (Mask(LoadStorePairAnyFMask) == LoadStorePairAnyFixed) { return Mask(LoadStorePairLBit) != 0;
} else {
LoadStoreOp op = static_cast<LoadStoreOp>(Mask(LoadStoreMask)); switch (op) { case LDRB_w: case LDRH_w: case LDR_w: case LDR_x: case LDRSB_w: case LDRSB_x: case LDRSH_w: case LDRSH_x: case LDRSW_x: case LDR_b: case LDR_h: case LDR_s: case LDR_d: case LDR_q: returntrue; default: returnfalse;
}
}
}
if (Mask(LoadStorePairAnyFMask) == LoadStorePairAnyFixed) { return Mask(LoadStorePairLBit) == 0;
} else {
LoadStoreOp op = static_cast<LoadStoreOp>(Mask(LoadStoreMask)); switch (op) { case STRB_w: case STRH_w: case STR_w: case STR_x: case STR_b: case STR_h: case STR_s: case STR_d: case STR_q: returntrue; default: returnfalse;
}
}
}
// Logical immediates can't encode zero, so a return value of zero is used to // indicate a failure case. Specifically, where the constraints on imm_s are // not met.
uint64_t Instruction::ImmLogical() const { unsigned reg_size = SixtyFourBits() ? kXRegSize : kWRegSize;
int32_t n = BitN();
int32_t imm_s = ImmSetBits();
int32_t imm_r = ImmRotate();
// An integer is constructed from the n, imm_s and imm_r bits according to // the following table: // // N imms immr size S R // 1 ssssss rrrrrr 64 UInt(ssssss) UInt(rrrrrr) // 0 0sssss xrrrrr 32 UInt(sssss) UInt(rrrrr) // 0 10ssss xxrrrr 16 UInt(ssss) UInt(rrrr) // 0 110sss xxxrrr 8 UInt(sss) UInt(rrr) // 0 1110ss xxxxrr 4 UInt(ss) UInt(rr) // 0 11110s xxxxxr 2 UInt(s) UInt(r) // (s bits must not be all set) // // A pattern is constructed of size bits, where the least significant S+1 // bits are set. The pattern is rotated right by R, and repeated across a // 32 or 64-bit value, depending on destination register width. //
ImmBranchRangeType Instruction::ImmBranchTypeToRange(ImmBranchType branch_type)
{ switch (branch_type) { case UncondBranchType: return UncondBranchRangeType; case CondBranchType: case CompareBranchType: return CondBranchRangeType; case TestBranchType: return TestBranchRangeType; default: return UnknownBranchRangeType;
}
}
int32_t Instruction::ImmBranchMaxForwardOffset(ImmBranchRangeType range_type)
{ // Branches encode a pc-relative two's complement number of 32-bit // instructions. Compute the number of bytes corresponding to the largest // positive number of instructions that can be encoded. switch(range_type) { case TestBranchRangeType: return ((1 << ImmTestBranch_width) - 1) / 2 * kInstructionSize; case CondBranchRangeType: return ((1 << ImmCondBranch_width) - 1) / 2 * kInstructionSize; case UncondBranchRangeType: return ((1 << ImmUncondBranch_width) - 1) / 2 * kInstructionSize; default:
VIXL_UNREACHABLE(); return 0;
}
}
VectorFormat VectorFormatFillQ(const VectorFormat vform) { switch (vform) { case kFormatB: case kFormat8B: case kFormat16B: return kFormat16B; case kFormatH: case kFormat4H: case kFormat8H: return kFormat8H; case kFormatS: case kFormat2S: case kFormat4S: return kFormat4S; case kFormatD: case kFormat1D: case kFormat2D: return kFormat2D; default: VIXL_UNREACHABLE(); return kFormatUndefined;
}
}
VectorFormat VectorFormatHalfWidthDoubleLanes(const VectorFormat vform) { switch (vform) { case kFormat4H: return kFormat8B; case kFormat8H: return kFormat16B; case kFormat2S: return kFormat4H; case kFormat4S: return kFormat8H; case kFormat1D: return kFormat2S; case kFormat2D: return kFormat4S; default: VIXL_UNREACHABLE(); return kFormatUndefined;
}
}
unsigned LaneSizeInBitsFromFormat(VectorFormat vform) {
VIXL_ASSERT(vform != kFormatUndefined); switch (vform) { case kFormatB: case kFormat8B: case kFormat16B: return 8; case kFormatH: case kFormat4H: case kFormat8H: return 16; case kFormatS: case kFormat2S: case kFormat4S: return 32; case kFormatD: case kFormat1D: case kFormat2D: return 64; default: VIXL_UNREACHABLE(); return 0;
}
}
int LaneSizeInBytesFromFormat(VectorFormat vform) { return LaneSizeInBitsFromFormat(vform) / 8;
}
int LaneSizeInBytesLog2FromFormat(VectorFormat vform) {
VIXL_ASSERT(vform != kFormatUndefined); switch (vform) { case kFormatB: case kFormat8B: case kFormat16B: return 0; case kFormatH: case kFormat4H: case kFormat8H: return 1; case kFormatS: case kFormat2S: case kFormat4S: return 2; case kFormatD: case kFormat1D: case kFormat2D: return 3; default: VIXL_UNREACHABLE(); return 0;
}
}
int LaneCountFromFormat(VectorFormat vform) {
VIXL_ASSERT(vform != kFormatUndefined); switch (vform) { case kFormat16B: return 16; case kFormat8B: case kFormat8H: return 8; case kFormat4H: case kFormat4S: return 4; case kFormat2S: case kFormat2D: return 2; case kFormat1D: case kFormatB: case kFormatH: case kFormatS: case kFormatD: return 1; default: VIXL_UNREACHABLE(); return 0;
}
}
int MaxLaneCountFromFormat(VectorFormat vform) {
VIXL_ASSERT(vform != kFormatUndefined); switch (vform) { case kFormatB: case kFormat8B: case kFormat16B: return 16; case kFormatH: case kFormat4H: case kFormat8H: return 8; case kFormatS: case kFormat2S: case kFormat4S: return 4; case kFormatD: case kFormat1D: case kFormat2D: return 2; default: VIXL_UNREACHABLE(); return 0;
}
}
// Does 'vform' indicate a vector format or a scalar format? bool IsVectorFormat(VectorFormat vform) {
VIXL_ASSERT(vform != kFormatUndefined); switch (vform) { case kFormatB: case kFormatH: case kFormatS: case kFormatD: returnfalse; default: returntrue;
}
}
Die Informationen auf dieser Webseite wurden
nach bestem Wissen sorgfältig zusammengestellt. Es wird jedoch weder Vollständigkeit, noch Richtigkeit,
noch Qualität der bereit gestellten Informationen zugesichert.
Bemerkung:
Die farbliche Syntaxdarstellung und die Messung sind noch experimentell.