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