1f5a24546072ecdbbd6372c85c42157e01e913561titzer@chromium.org// Copyright 2013 the V8 project authors. All rights reserved. 23484964a86451e86dcf04be9bd8c0d76ee04f081rossberg@chromium.org// Use of this source code is governed by a BSD-style license that can be 33484964a86451e86dcf04be9bd8c0d76ee04f081rossberg@chromium.org// found in the LICENSE file. 4f5a24546072ecdbbd6372c85c42157e01e913561titzer@chromium.org 5196eb601290dc49c3754da728dc58700dff2de1bmachenbach@chromium.org#include "src/v8.h" 6f5a24546072ecdbbd6372c85c42157e01e913561titzer@chromium.org 7fa0c3c69b9d632e5730bdd9c745c375beef5e54dmachenbach@chromium.org#if V8_TARGET_ARCH_ARM64 8f5a24546072ecdbbd6372c85c42157e01e913561titzer@chromium.org 9fa0c3c69b9d632e5730bdd9c745c375beef5e54dmachenbach@chromium.org#define ARM64_DEFINE_FP_STATICS 10f5a24546072ecdbbd6372c85c42157e01e913561titzer@chromium.org 11196eb601290dc49c3754da728dc58700dff2de1bmachenbach@chromium.org#include "src/arm64/assembler-arm64-inl.h" 124b0feeef5d01dbc2948080b4f69daa37e1083461machenbach@chromium.org#include "src/arm64/instructions-arm64.h" 13f5a24546072ecdbbd6372c85c42157e01e913561titzer@chromium.org 14f5a24546072ecdbbd6372c85c42157e01e913561titzer@chromium.orgnamespace v8 { 15f5a24546072ecdbbd6372c85c42157e01e913561titzer@chromium.orgnamespace internal { 16f5a24546072ecdbbd6372c85c42157e01e913561titzer@chromium.org 17f5a24546072ecdbbd6372c85c42157e01e913561titzer@chromium.org 18f5a24546072ecdbbd6372c85c42157e01e913561titzer@chromium.orgbool Instruction::IsLoad() const { 19f5a24546072ecdbbd6372c85c42157e01e913561titzer@chromium.org if (Mask(LoadStoreAnyFMask) != LoadStoreAnyFixed) { 20f5a24546072ecdbbd6372c85c42157e01e913561titzer@chromium.org return false; 21f5a24546072ecdbbd6372c85c42157e01e913561titzer@chromium.org } 22f5a24546072ecdbbd6372c85c42157e01e913561titzer@chromium.org 23f5a24546072ecdbbd6372c85c42157e01e913561titzer@chromium.org if (Mask(LoadStorePairAnyFMask) == LoadStorePairAnyFixed) { 24f5a24546072ecdbbd6372c85c42157e01e913561titzer@chromium.org return Mask(LoadStorePairLBit) != 0; 25f5a24546072ecdbbd6372c85c42157e01e913561titzer@chromium.org } else { 26f5a24546072ecdbbd6372c85c42157e01e913561titzer@chromium.org LoadStoreOp op = static_cast<LoadStoreOp>(Mask(LoadStoreOpMask)); 27f5a24546072ecdbbd6372c85c42157e01e913561titzer@chromium.org switch (op) { 28f5a24546072ecdbbd6372c85c42157e01e913561titzer@chromium.org case LDRB_w: 29f5a24546072ecdbbd6372c85c42157e01e913561titzer@chromium.org case LDRH_w: 30f5a24546072ecdbbd6372c85c42157e01e913561titzer@chromium.org case LDR_w: 31f5a24546072ecdbbd6372c85c42157e01e913561titzer@chromium.org case LDR_x: 32f5a24546072ecdbbd6372c85c42157e01e913561titzer@chromium.org case LDRSB_w: 33f5a24546072ecdbbd6372c85c42157e01e913561titzer@chromium.org case LDRSB_x: 34f5a24546072ecdbbd6372c85c42157e01e913561titzer@chromium.org case LDRSH_w: 35f5a24546072ecdbbd6372c85c42157e01e913561titzer@chromium.org case LDRSH_x: 36f5a24546072ecdbbd6372c85c42157e01e913561titzer@chromium.org case LDRSW_x: 37f5a24546072ecdbbd6372c85c42157e01e913561titzer@chromium.org case LDR_s: 38f5a24546072ecdbbd6372c85c42157e01e913561titzer@chromium.org case LDR_d: return true; 39f5a24546072ecdbbd6372c85c42157e01e913561titzer@chromium.org default: return false; 40f5a24546072ecdbbd6372c85c42157e01e913561titzer@chromium.org } 41f5a24546072ecdbbd6372c85c42157e01e913561titzer@chromium.org } 42f5a24546072ecdbbd6372c85c42157e01e913561titzer@chromium.org} 43f5a24546072ecdbbd6372c85c42157e01e913561titzer@chromium.org 44f5a24546072ecdbbd6372c85c42157e01e913561titzer@chromium.org 45f5a24546072ecdbbd6372c85c42157e01e913561titzer@chromium.orgbool Instruction::IsStore() const { 46f5a24546072ecdbbd6372c85c42157e01e913561titzer@chromium.org if (Mask(LoadStoreAnyFMask) != LoadStoreAnyFixed) { 47f5a24546072ecdbbd6372c85c42157e01e913561titzer@chromium.org return false; 48f5a24546072ecdbbd6372c85c42157e01e913561titzer@chromium.org } 49f5a24546072ecdbbd6372c85c42157e01e913561titzer@chromium.org 50f5a24546072ecdbbd6372c85c42157e01e913561titzer@chromium.org if (Mask(LoadStorePairAnyFMask) == LoadStorePairAnyFixed) { 51f5a24546072ecdbbd6372c85c42157e01e913561titzer@chromium.org return Mask(LoadStorePairLBit) == 0; 52f5a24546072ecdbbd6372c85c42157e01e913561titzer@chromium.org } else { 53f5a24546072ecdbbd6372c85c42157e01e913561titzer@chromium.org LoadStoreOp op = static_cast<LoadStoreOp>(Mask(LoadStoreOpMask)); 54f5a24546072ecdbbd6372c85c42157e01e913561titzer@chromium.org switch (op) { 55f5a24546072ecdbbd6372c85c42157e01e913561titzer@chromium.org case STRB_w: 56f5a24546072ecdbbd6372c85c42157e01e913561titzer@chromium.org case STRH_w: 57f5a24546072ecdbbd6372c85c42157e01e913561titzer@chromium.org case STR_w: 58f5a24546072ecdbbd6372c85c42157e01e913561titzer@chromium.org case STR_x: 59f5a24546072ecdbbd6372c85c42157e01e913561titzer@chromium.org case STR_s: 60f5a24546072ecdbbd6372c85c42157e01e913561titzer@chromium.org case STR_d: return true; 61f5a24546072ecdbbd6372c85c42157e01e913561titzer@chromium.org default: return false; 62f5a24546072ecdbbd6372c85c42157e01e913561titzer@chromium.org } 63f5a24546072ecdbbd6372c85c42157e01e913561titzer@chromium.org } 64f5a24546072ecdbbd6372c85c42157e01e913561titzer@chromium.org} 65f5a24546072ecdbbd6372c85c42157e01e913561titzer@chromium.org 66f5a24546072ecdbbd6372c85c42157e01e913561titzer@chromium.org 67f5a24546072ecdbbd6372c85c42157e01e913561titzer@chromium.orgstatic uint64_t RotateRight(uint64_t value, 68f5a24546072ecdbbd6372c85c42157e01e913561titzer@chromium.org unsigned int rotate, 69f5a24546072ecdbbd6372c85c42157e01e913561titzer@chromium.org unsigned int width) { 70e3c177a423baa3c30225c4e422b6f6c76d38b951machenbach@chromium.org DCHECK(width <= 64); 71f5a24546072ecdbbd6372c85c42157e01e913561titzer@chromium.org rotate &= 63; 72f5a24546072ecdbbd6372c85c42157e01e913561titzer@chromium.org return ((value & ((1UL << rotate) - 1UL)) << (width - rotate)) | 73f5a24546072ecdbbd6372c85c42157e01e913561titzer@chromium.org (value >> rotate); 74f5a24546072ecdbbd6372c85c42157e01e913561titzer@chromium.org} 75f5a24546072ecdbbd6372c85c42157e01e913561titzer@chromium.org 76f5a24546072ecdbbd6372c85c42157e01e913561titzer@chromium.org 77f5a24546072ecdbbd6372c85c42157e01e913561titzer@chromium.orgstatic uint64_t RepeatBitsAcrossReg(unsigned reg_size, 78f5a24546072ecdbbd6372c85c42157e01e913561titzer@chromium.org uint64_t value, 79f5a24546072ecdbbd6372c85c42157e01e913561titzer@chromium.org unsigned width) { 80e3c177a423baa3c30225c4e422b6f6c76d38b951machenbach@chromium.org DCHECK((width == 2) || (width == 4) || (width == 8) || (width == 16) || 81f5a24546072ecdbbd6372c85c42157e01e913561titzer@chromium.org (width == 32)); 82e3c177a423baa3c30225c4e422b6f6c76d38b951machenbach@chromium.org DCHECK((reg_size == kWRegSizeInBits) || (reg_size == kXRegSizeInBits)); 83f5a24546072ecdbbd6372c85c42157e01e913561titzer@chromium.org uint64_t result = value & ((1UL << width) - 1UL); 84f5a24546072ecdbbd6372c85c42157e01e913561titzer@chromium.org for (unsigned i = width; i < reg_size; i *= 2) { 85f5a24546072ecdbbd6372c85c42157e01e913561titzer@chromium.org result |= (result << i); 86f5a24546072ecdbbd6372c85c42157e01e913561titzer@chromium.org } 87f5a24546072ecdbbd6372c85c42157e01e913561titzer@chromium.org return result; 88f5a24546072ecdbbd6372c85c42157e01e913561titzer@chromium.org} 89f5a24546072ecdbbd6372c85c42157e01e913561titzer@chromium.org 90f5a24546072ecdbbd6372c85c42157e01e913561titzer@chromium.org 91f5a24546072ecdbbd6372c85c42157e01e913561titzer@chromium.org// Logical immediates can't encode zero, so a return value of zero is used to 92f5a24546072ecdbbd6372c85c42157e01e913561titzer@chromium.org// indicate a failure case. Specifically, where the constraints on imm_s are not 93f5a24546072ecdbbd6372c85c42157e01e913561titzer@chromium.org// met. 94f5a24546072ecdbbd6372c85c42157e01e913561titzer@chromium.orguint64_t Instruction::ImmLogical() { 9597b98c9169c85693801d4d59089450695ad82e2dmachenbach@chromium.org unsigned reg_size = SixtyFourBits() ? kXRegSizeInBits : kWRegSizeInBits; 96f5a24546072ecdbbd6372c85c42157e01e913561titzer@chromium.org int64_t n = BitN(); 97f5a24546072ecdbbd6372c85c42157e01e913561titzer@chromium.org int64_t imm_s = ImmSetBits(); 98f5a24546072ecdbbd6372c85c42157e01e913561titzer@chromium.org int64_t imm_r = ImmRotate(); 99f5a24546072ecdbbd6372c85c42157e01e913561titzer@chromium.org 100f5a24546072ecdbbd6372c85c42157e01e913561titzer@chromium.org // An integer is constructed from the n, imm_s and imm_r bits according to 101f5a24546072ecdbbd6372c85c42157e01e913561titzer@chromium.org // the following table: 102f5a24546072ecdbbd6372c85c42157e01e913561titzer@chromium.org // 103f5a24546072ecdbbd6372c85c42157e01e913561titzer@chromium.org // N imms immr size S R 104f5a24546072ecdbbd6372c85c42157e01e913561titzer@chromium.org // 1 ssssss rrrrrr 64 UInt(ssssss) UInt(rrrrrr) 105f5a24546072ecdbbd6372c85c42157e01e913561titzer@chromium.org // 0 0sssss xrrrrr 32 UInt(sssss) UInt(rrrrr) 106f5a24546072ecdbbd6372c85c42157e01e913561titzer@chromium.org // 0 10ssss xxrrrr 16 UInt(ssss) UInt(rrrr) 107f5a24546072ecdbbd6372c85c42157e01e913561titzer@chromium.org // 0 110sss xxxrrr 8 UInt(sss) UInt(rrr) 108f5a24546072ecdbbd6372c85c42157e01e913561titzer@chromium.org // 0 1110ss xxxxrr 4 UInt(ss) UInt(rr) 109f5a24546072ecdbbd6372c85c42157e01e913561titzer@chromium.org // 0 11110s xxxxxr 2 UInt(s) UInt(r) 110f5a24546072ecdbbd6372c85c42157e01e913561titzer@chromium.org // (s bits must not be all set) 111f5a24546072ecdbbd6372c85c42157e01e913561titzer@chromium.org // 112f5a24546072ecdbbd6372c85c42157e01e913561titzer@chromium.org // A pattern is constructed of size bits, where the least significant S+1 113f5a24546072ecdbbd6372c85c42157e01e913561titzer@chromium.org // bits are set. The pattern is rotated right by R, and repeated across a 114f5a24546072ecdbbd6372c85c42157e01e913561titzer@chromium.org // 32 or 64-bit value, depending on destination register width. 115f5a24546072ecdbbd6372c85c42157e01e913561titzer@chromium.org // 116f5a24546072ecdbbd6372c85c42157e01e913561titzer@chromium.org 117f5a24546072ecdbbd6372c85c42157e01e913561titzer@chromium.org if (n == 1) { 118f5a24546072ecdbbd6372c85c42157e01e913561titzer@chromium.org if (imm_s == 0x3F) { 119f5a24546072ecdbbd6372c85c42157e01e913561titzer@chromium.org return 0; 120f5a24546072ecdbbd6372c85c42157e01e913561titzer@chromium.org } 121f5a24546072ecdbbd6372c85c42157e01e913561titzer@chromium.org uint64_t bits = (1UL << (imm_s + 1)) - 1; 122f5a24546072ecdbbd6372c85c42157e01e913561titzer@chromium.org return RotateRight(bits, imm_r, 64); 123f5a24546072ecdbbd6372c85c42157e01e913561titzer@chromium.org } else { 124f5a24546072ecdbbd6372c85c42157e01e913561titzer@chromium.org if ((imm_s >> 1) == 0x1F) { 125f5a24546072ecdbbd6372c85c42157e01e913561titzer@chromium.org return 0; 126f5a24546072ecdbbd6372c85c42157e01e913561titzer@chromium.org } 127f5a24546072ecdbbd6372c85c42157e01e913561titzer@chromium.org for (int width = 0x20; width >= 0x2; width >>= 1) { 128f5a24546072ecdbbd6372c85c42157e01e913561titzer@chromium.org if ((imm_s & width) == 0) { 129f5a24546072ecdbbd6372c85c42157e01e913561titzer@chromium.org int mask = width - 1; 130f5a24546072ecdbbd6372c85c42157e01e913561titzer@chromium.org if ((imm_s & mask) == mask) { 131f5a24546072ecdbbd6372c85c42157e01e913561titzer@chromium.org return 0; 132f5a24546072ecdbbd6372c85c42157e01e913561titzer@chromium.org } 133f5a24546072ecdbbd6372c85c42157e01e913561titzer@chromium.org uint64_t bits = (1UL << ((imm_s & mask) + 1)) - 1; 134f5a24546072ecdbbd6372c85c42157e01e913561titzer@chromium.org return RepeatBitsAcrossReg(reg_size, 135f5a24546072ecdbbd6372c85c42157e01e913561titzer@chromium.org RotateRight(bits, imm_r & mask, width), 136f5a24546072ecdbbd6372c85c42157e01e913561titzer@chromium.org width); 137f5a24546072ecdbbd6372c85c42157e01e913561titzer@chromium.org } 138f5a24546072ecdbbd6372c85c42157e01e913561titzer@chromium.org } 139f5a24546072ecdbbd6372c85c42157e01e913561titzer@chromium.org } 140f5a24546072ecdbbd6372c85c42157e01e913561titzer@chromium.org UNREACHABLE(); 141f5a24546072ecdbbd6372c85c42157e01e913561titzer@chromium.org return 0; 142f5a24546072ecdbbd6372c85c42157e01e913561titzer@chromium.org} 143f5a24546072ecdbbd6372c85c42157e01e913561titzer@chromium.org 144f5a24546072ecdbbd6372c85c42157e01e913561titzer@chromium.org 145f5a24546072ecdbbd6372c85c42157e01e913561titzer@chromium.orgfloat Instruction::ImmFP32() { 146f5a24546072ecdbbd6372c85c42157e01e913561titzer@chromium.org // ImmFP: abcdefgh (8 bits) 147f5a24546072ecdbbd6372c85c42157e01e913561titzer@chromium.org // Single: aBbb.bbbc.defg.h000.0000.0000.0000.0000 (32 bits) 148f5a24546072ecdbbd6372c85c42157e01e913561titzer@chromium.org // where B is b ^ 1 149f5a24546072ecdbbd6372c85c42157e01e913561titzer@chromium.org uint32_t bits = ImmFP(); 150f5a24546072ecdbbd6372c85c42157e01e913561titzer@chromium.org uint32_t bit7 = (bits >> 7) & 0x1; 151f5a24546072ecdbbd6372c85c42157e01e913561titzer@chromium.org uint32_t bit6 = (bits >> 6) & 0x1; 152f5a24546072ecdbbd6372c85c42157e01e913561titzer@chromium.org uint32_t bit5_to_0 = bits & 0x3f; 153f5a24546072ecdbbd6372c85c42157e01e913561titzer@chromium.org uint32_t result = (bit7 << 31) | ((32 - bit6) << 25) | (bit5_to_0 << 19); 154f5a24546072ecdbbd6372c85c42157e01e913561titzer@chromium.org 155f5a24546072ecdbbd6372c85c42157e01e913561titzer@chromium.org return rawbits_to_float(result); 156f5a24546072ecdbbd6372c85c42157e01e913561titzer@chromium.org} 157f5a24546072ecdbbd6372c85c42157e01e913561titzer@chromium.org 158f5a24546072ecdbbd6372c85c42157e01e913561titzer@chromium.org 159f5a24546072ecdbbd6372c85c42157e01e913561titzer@chromium.orgdouble Instruction::ImmFP64() { 160f5a24546072ecdbbd6372c85c42157e01e913561titzer@chromium.org // ImmFP: abcdefgh (8 bits) 161f5a24546072ecdbbd6372c85c42157e01e913561titzer@chromium.org // Double: aBbb.bbbb.bbcd.efgh.0000.0000.0000.0000 162f5a24546072ecdbbd6372c85c42157e01e913561titzer@chromium.org // 0000.0000.0000.0000.0000.0000.0000.0000 (64 bits) 163f5a24546072ecdbbd6372c85c42157e01e913561titzer@chromium.org // where B is b ^ 1 164f5a24546072ecdbbd6372c85c42157e01e913561titzer@chromium.org uint32_t bits = ImmFP(); 165f5a24546072ecdbbd6372c85c42157e01e913561titzer@chromium.org uint64_t bit7 = (bits >> 7) & 0x1; 166f5a24546072ecdbbd6372c85c42157e01e913561titzer@chromium.org uint64_t bit6 = (bits >> 6) & 0x1; 167f5a24546072ecdbbd6372c85c42157e01e913561titzer@chromium.org uint64_t bit5_to_0 = bits & 0x3f; 168f5a24546072ecdbbd6372c85c42157e01e913561titzer@chromium.org uint64_t result = (bit7 << 63) | ((256 - bit6) << 54) | (bit5_to_0 << 48); 169f5a24546072ecdbbd6372c85c42157e01e913561titzer@chromium.org 170f5a24546072ecdbbd6372c85c42157e01e913561titzer@chromium.org return rawbits_to_double(result); 171f5a24546072ecdbbd6372c85c42157e01e913561titzer@chromium.org} 172f5a24546072ecdbbd6372c85c42157e01e913561titzer@chromium.org 173f5a24546072ecdbbd6372c85c42157e01e913561titzer@chromium.org 174f5a24546072ecdbbd6372c85c42157e01e913561titzer@chromium.orgLSDataSize CalcLSPairDataSize(LoadStorePairOp op) { 175f5a24546072ecdbbd6372c85c42157e01e913561titzer@chromium.org switch (op) { 176f5a24546072ecdbbd6372c85c42157e01e913561titzer@chromium.org case STP_x: 177f5a24546072ecdbbd6372c85c42157e01e913561titzer@chromium.org case LDP_x: 178f5a24546072ecdbbd6372c85c42157e01e913561titzer@chromium.org case STP_d: 179f5a24546072ecdbbd6372c85c42157e01e913561titzer@chromium.org case LDP_d: return LSDoubleWord; 180f5a24546072ecdbbd6372c85c42157e01e913561titzer@chromium.org default: return LSWord; 181f5a24546072ecdbbd6372c85c42157e01e913561titzer@chromium.org } 182f5a24546072ecdbbd6372c85c42157e01e913561titzer@chromium.org} 183f5a24546072ecdbbd6372c85c42157e01e913561titzer@chromium.org 184f5a24546072ecdbbd6372c85c42157e01e913561titzer@chromium.org 1856313e220249748eb26e1ddcee2bbe857fef03b42machenbach@chromium.orgint64_t Instruction::ImmPCOffset() { 1866313e220249748eb26e1ddcee2bbe857fef03b42machenbach@chromium.org int64_t offset; 187f5a24546072ecdbbd6372c85c42157e01e913561titzer@chromium.org if (IsPCRelAddressing()) { 188f5a24546072ecdbbd6372c85c42157e01e913561titzer@chromium.org // PC-relative addressing. Only ADR is supported. 189f5a24546072ecdbbd6372c85c42157e01e913561titzer@chromium.org offset = ImmPCRel(); 190f5a24546072ecdbbd6372c85c42157e01e913561titzer@chromium.org } else if (BranchType() != UnknownBranchType) { 191f5a24546072ecdbbd6372c85c42157e01e913561titzer@chromium.org // All PC-relative branches. 192f5a24546072ecdbbd6372c85c42157e01e913561titzer@chromium.org // Relative branch offsets are instruction-size-aligned. 193f5a24546072ecdbbd6372c85c42157e01e913561titzer@chromium.org offset = ImmBranch() << kInstructionSizeLog2; 194f5a24546072ecdbbd6372c85c42157e01e913561titzer@chromium.org } else { 195f5a24546072ecdbbd6372c85c42157e01e913561titzer@chromium.org // Load literal (offset from PC). 196e3c177a423baa3c30225c4e422b6f6c76d38b951machenbach@chromium.org DCHECK(IsLdrLiteral()); 197f5a24546072ecdbbd6372c85c42157e01e913561titzer@chromium.org // The offset is always shifted by 2 bits, even for loads to 64-bits 198f5a24546072ecdbbd6372c85c42157e01e913561titzer@chromium.org // registers. 199f5a24546072ecdbbd6372c85c42157e01e913561titzer@chromium.org offset = ImmLLiteral() << kInstructionSizeLog2; 200f5a24546072ecdbbd6372c85c42157e01e913561titzer@chromium.org } 201f5a24546072ecdbbd6372c85c42157e01e913561titzer@chromium.org return offset; 202f5a24546072ecdbbd6372c85c42157e01e913561titzer@chromium.org} 203f5a24546072ecdbbd6372c85c42157e01e913561titzer@chromium.org 204f5a24546072ecdbbd6372c85c42157e01e913561titzer@chromium.org 205f5a24546072ecdbbd6372c85c42157e01e913561titzer@chromium.orgInstruction* Instruction::ImmPCOffsetTarget() { 2064452a490cca1fd780af6b2a4ca946c5d0fd108bamachenbach@chromium.org return InstructionAtOffset(ImmPCOffset()); 207f5a24546072ecdbbd6372c85c42157e01e913561titzer@chromium.org} 208f5a24546072ecdbbd6372c85c42157e01e913561titzer@chromium.org 209f5a24546072ecdbbd6372c85c42157e01e913561titzer@chromium.org 210f5a24546072ecdbbd6372c85c42157e01e913561titzer@chromium.orgbool Instruction::IsValidImmPCOffset(ImmBranchType branch_type, 211f5a24546072ecdbbd6372c85c42157e01e913561titzer@chromium.org int32_t offset) { 212f5a24546072ecdbbd6372c85c42157e01e913561titzer@chromium.org return is_intn(offset, ImmBranchRangeBitwidth(branch_type)); 213f5a24546072ecdbbd6372c85c42157e01e913561titzer@chromium.org} 214f5a24546072ecdbbd6372c85c42157e01e913561titzer@chromium.org 215f5a24546072ecdbbd6372c85c42157e01e913561titzer@chromium.org 216f5a24546072ecdbbd6372c85c42157e01e913561titzer@chromium.orgbool Instruction::IsTargetInImmPCOffsetRange(Instruction* target) { 2174452a490cca1fd780af6b2a4ca946c5d0fd108bamachenbach@chromium.org return IsValidImmPCOffset(BranchType(), DistanceTo(target)); 218f5a24546072ecdbbd6372c85c42157e01e913561titzer@chromium.org} 219f5a24546072ecdbbd6372c85c42157e01e913561titzer@chromium.org 220f5a24546072ecdbbd6372c85c42157e01e913561titzer@chromium.org 221f5a24546072ecdbbd6372c85c42157e01e913561titzer@chromium.orgvoid Instruction::SetImmPCOffsetTarget(Instruction* target) { 222f5a24546072ecdbbd6372c85c42157e01e913561titzer@chromium.org if (IsPCRelAddressing()) { 223f5a24546072ecdbbd6372c85c42157e01e913561titzer@chromium.org SetPCRelImmTarget(target); 224f5a24546072ecdbbd6372c85c42157e01e913561titzer@chromium.org } else if (BranchType() != UnknownBranchType) { 225f5a24546072ecdbbd6372c85c42157e01e913561titzer@chromium.org SetBranchImmTarget(target); 226f5a24546072ecdbbd6372c85c42157e01e913561titzer@chromium.org } else { 227f5a24546072ecdbbd6372c85c42157e01e913561titzer@chromium.org SetImmLLiteral(target); 228f5a24546072ecdbbd6372c85c42157e01e913561titzer@chromium.org } 229f5a24546072ecdbbd6372c85c42157e01e913561titzer@chromium.org} 230f5a24546072ecdbbd6372c85c42157e01e913561titzer@chromium.org 231f5a24546072ecdbbd6372c85c42157e01e913561titzer@chromium.org 232f5a24546072ecdbbd6372c85c42157e01e913561titzer@chromium.orgvoid Instruction::SetPCRelImmTarget(Instruction* target) { 233f5a24546072ecdbbd6372c85c42157e01e913561titzer@chromium.org // ADRP is not supported, so 'this' must point to an ADR instruction. 234e3c177a423baa3c30225c4e422b6f6c76d38b951machenbach@chromium.org DCHECK(IsAdr()); 235f5a24546072ecdbbd6372c85c42157e01e913561titzer@chromium.org 236d0bddc653152f270a27fe32d5d7b0f5c0fa3b00cmachenbach@chromium.org ptrdiff_t target_offset = DistanceTo(target); 2379e41f9ecf5042292a9efcb36e264b37621199553machenbach@chromium.org Instr imm; 2389e41f9ecf5042292a9efcb36e264b37621199553machenbach@chromium.org if (Instruction::IsValidPCRelOffset(target_offset)) { 2399e41f9ecf5042292a9efcb36e264b37621199553machenbach@chromium.org imm = Assembler::ImmPCRelAddress(target_offset); 2409e41f9ecf5042292a9efcb36e264b37621199553machenbach@chromium.org SetInstructionBits(Mask(~ImmPCRel_mask) | imm); 2419e41f9ecf5042292a9efcb36e264b37621199553machenbach@chromium.org } else { 2429e41f9ecf5042292a9efcb36e264b37621199553machenbach@chromium.org PatchingAssembler patcher(this, 2439e41f9ecf5042292a9efcb36e264b37621199553machenbach@chromium.org PatchingAssembler::kAdrFarPatchableNInstrs); 244d0bddc653152f270a27fe32d5d7b0f5c0fa3b00cmachenbach@chromium.org patcher.PatchAdrFar(target_offset); 2459e41f9ecf5042292a9efcb36e264b37621199553machenbach@chromium.org } 246f5a24546072ecdbbd6372c85c42157e01e913561titzer@chromium.org} 247f5a24546072ecdbbd6372c85c42157e01e913561titzer@chromium.org 248f5a24546072ecdbbd6372c85c42157e01e913561titzer@chromium.org 249f5a24546072ecdbbd6372c85c42157e01e913561titzer@chromium.orgvoid Instruction::SetBranchImmTarget(Instruction* target) { 250e3c177a423baa3c30225c4e422b6f6c76d38b951machenbach@chromium.org DCHECK(IsAligned(DistanceTo(target), kInstructionSize)); 251f5a24546072ecdbbd6372c85c42157e01e913561titzer@chromium.org Instr branch_imm = 0; 252f5a24546072ecdbbd6372c85c42157e01e913561titzer@chromium.org uint32_t imm_mask = 0; 2534452a490cca1fd780af6b2a4ca946c5d0fd108bamachenbach@chromium.org ptrdiff_t offset = DistanceTo(target) >> kInstructionSizeLog2; 254f5a24546072ecdbbd6372c85c42157e01e913561titzer@chromium.org switch (BranchType()) { 255f5a24546072ecdbbd6372c85c42157e01e913561titzer@chromium.org case CondBranchType: { 256f5a24546072ecdbbd6372c85c42157e01e913561titzer@chromium.org branch_imm = Assembler::ImmCondBranch(offset); 257f5a24546072ecdbbd6372c85c42157e01e913561titzer@chromium.org imm_mask = ImmCondBranch_mask; 258f5a24546072ecdbbd6372c85c42157e01e913561titzer@chromium.org break; 259f5a24546072ecdbbd6372c85c42157e01e913561titzer@chromium.org } 260f5a24546072ecdbbd6372c85c42157e01e913561titzer@chromium.org case UncondBranchType: { 261f5a24546072ecdbbd6372c85c42157e01e913561titzer@chromium.org branch_imm = Assembler::ImmUncondBranch(offset); 262f5a24546072ecdbbd6372c85c42157e01e913561titzer@chromium.org imm_mask = ImmUncondBranch_mask; 263f5a24546072ecdbbd6372c85c42157e01e913561titzer@chromium.org break; 264f5a24546072ecdbbd6372c85c42157e01e913561titzer@chromium.org } 265f5a24546072ecdbbd6372c85c42157e01e913561titzer@chromium.org case CompareBranchType: { 266f5a24546072ecdbbd6372c85c42157e01e913561titzer@chromium.org branch_imm = Assembler::ImmCmpBranch(offset); 267f5a24546072ecdbbd6372c85c42157e01e913561titzer@chromium.org imm_mask = ImmCmpBranch_mask; 268f5a24546072ecdbbd6372c85c42157e01e913561titzer@chromium.org break; 269f5a24546072ecdbbd6372c85c42157e01e913561titzer@chromium.org } 270f5a24546072ecdbbd6372c85c42157e01e913561titzer@chromium.org case TestBranchType: { 271f5a24546072ecdbbd6372c85c42157e01e913561titzer@chromium.org branch_imm = Assembler::ImmTestBranch(offset); 272f5a24546072ecdbbd6372c85c42157e01e913561titzer@chromium.org imm_mask = ImmTestBranch_mask; 273f5a24546072ecdbbd6372c85c42157e01e913561titzer@chromium.org break; 274f5a24546072ecdbbd6372c85c42157e01e913561titzer@chromium.org } 275f5a24546072ecdbbd6372c85c42157e01e913561titzer@chromium.org default: UNREACHABLE(); 276f5a24546072ecdbbd6372c85c42157e01e913561titzer@chromium.org } 277f5a24546072ecdbbd6372c85c42157e01e913561titzer@chromium.org SetInstructionBits(Mask(~imm_mask) | branch_imm); 278f5a24546072ecdbbd6372c85c42157e01e913561titzer@chromium.org} 279f5a24546072ecdbbd6372c85c42157e01e913561titzer@chromium.org 280f5a24546072ecdbbd6372c85c42157e01e913561titzer@chromium.org 281f5a24546072ecdbbd6372c85c42157e01e913561titzer@chromium.orgvoid Instruction::SetImmLLiteral(Instruction* source) { 282e3c177a423baa3c30225c4e422b6f6c76d38b951machenbach@chromium.org DCHECK(IsAligned(DistanceTo(source), kInstructionSize)); 283e7a6d372100022f492c88886898add6a51e66977machenbach@chromium.org ptrdiff_t offset = DistanceTo(source) >> kLoadLiteralScaleLog2; 284f5a24546072ecdbbd6372c85c42157e01e913561titzer@chromium.org Instr imm = Assembler::ImmLLiteral(offset); 285f5a24546072ecdbbd6372c85c42157e01e913561titzer@chromium.org Instr mask = ImmLLiteral_mask; 286f5a24546072ecdbbd6372c85c42157e01e913561titzer@chromium.org 287f5a24546072ecdbbd6372c85c42157e01e913561titzer@chromium.org SetInstructionBits(Mask(~mask) | imm); 288f5a24546072ecdbbd6372c85c42157e01e913561titzer@chromium.org} 289f5a24546072ecdbbd6372c85c42157e01e913561titzer@chromium.org 290f5a24546072ecdbbd6372c85c42157e01e913561titzer@chromium.org 291f5a24546072ecdbbd6372c85c42157e01e913561titzer@chromium.org// TODO(jbramley): We can't put this inline in the class because things like 292f5a24546072ecdbbd6372c85c42157e01e913561titzer@chromium.org// xzr and Register are not defined in that header. Consider adding 293fa0c3c69b9d632e5730bdd9c745c375beef5e54dmachenbach@chromium.org// instructions-arm64-inl.h to work around this. 294f5a24546072ecdbbd6372c85c42157e01e913561titzer@chromium.orgbool InstructionSequence::IsInlineData() const { 295f5a24546072ecdbbd6372c85c42157e01e913561titzer@chromium.org // Inline data is encoded as a single movz instruction which writes to xzr 296f5a24546072ecdbbd6372c85c42157e01e913561titzer@chromium.org // (x31). 297f5a24546072ecdbbd6372c85c42157e01e913561titzer@chromium.org return IsMovz() && SixtyFourBits() && (Rd() == xzr.code()); 298f5a24546072ecdbbd6372c85c42157e01e913561titzer@chromium.org // TODO(all): If we extend ::InlineData() to support bigger data, we need 299f5a24546072ecdbbd6372c85c42157e01e913561titzer@chromium.org // to update this method too. 300f5a24546072ecdbbd6372c85c42157e01e913561titzer@chromium.org} 301f5a24546072ecdbbd6372c85c42157e01e913561titzer@chromium.org 302f5a24546072ecdbbd6372c85c42157e01e913561titzer@chromium.org 303f5a24546072ecdbbd6372c85c42157e01e913561titzer@chromium.org// TODO(jbramley): We can't put this inline in the class because things like 304f5a24546072ecdbbd6372c85c42157e01e913561titzer@chromium.org// xzr and Register are not defined in that header. Consider adding 305fa0c3c69b9d632e5730bdd9c745c375beef5e54dmachenbach@chromium.org// instructions-arm64-inl.h to work around this. 306f5a24546072ecdbbd6372c85c42157e01e913561titzer@chromium.orguint64_t InstructionSequence::InlineData() const { 307e3c177a423baa3c30225c4e422b6f6c76d38b951machenbach@chromium.org DCHECK(IsInlineData()); 308f5a24546072ecdbbd6372c85c42157e01e913561titzer@chromium.org uint64_t payload = ImmMoveWide(); 309f5a24546072ecdbbd6372c85c42157e01e913561titzer@chromium.org // TODO(all): If we extend ::InlineData() to support bigger data, we need 310f5a24546072ecdbbd6372c85c42157e01e913561titzer@chromium.org // to update this method too. 311f5a24546072ecdbbd6372c85c42157e01e913561titzer@chromium.org return payload; 312f5a24546072ecdbbd6372c85c42157e01e913561titzer@chromium.org} 313f5a24546072ecdbbd6372c85c42157e01e913561titzer@chromium.org 314f5a24546072ecdbbd6372c85c42157e01e913561titzer@chromium.org 315f5a24546072ecdbbd6372c85c42157e01e913561titzer@chromium.org} } // namespace v8::internal 316f5a24546072ecdbbd6372c85c42157e01e913561titzer@chromium.org 317fa0c3c69b9d632e5730bdd9c745c375beef5e54dmachenbach@chromium.org#endif // V8_TARGET_ARCH_ARM64 318