1b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch// Copyright 2013 the V8 project authors. All rights reserved.
2b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch// Use of this source code is governed by a BSD-style license that can be
3b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch// found in the LICENSE file.
4b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
5b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch#if V8_TARGET_ARCH_ARM64
6b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
7014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch#include "src/crankshaft/arm64/delayed-masm-arm64.h"
8014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch#include "src/crankshaft/arm64/lithium-codegen-arm64.h"
9b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
10b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdochnamespace v8 {
11b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdochnamespace internal {
12b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
13b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch#define __ ACCESS_MASM(masm_)
14b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
15b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
16b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdochvoid DelayedMasm::StackSlotMove(LOperand* src, LOperand* dst) {
17958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier  DCHECK((src->IsStackSlot() && dst->IsStackSlot()) ||
18958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier         (src->IsDoubleStackSlot() && dst->IsDoubleStackSlot()));
19b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  MemOperand src_operand = cgen_->ToMemOperand(src);
20b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  MemOperand dst_operand = cgen_->ToMemOperand(dst);
21b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  if (pending_ == kStackSlotMove) {
22b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    DCHECK(pending_pc_ == masm_->pc_offset());
23b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    UseScratchRegisterScope scope(masm_);
24b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    DoubleRegister temp1 = scope.AcquireD();
25b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    DoubleRegister temp2 = scope.AcquireD();
26b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    switch (MemOperand::AreConsistentForPair(pending_address_src_,
27b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch                                             src_operand)) {
28b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch      case MemOperand::kNotPair:
29b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch        __ Ldr(temp1, pending_address_src_);
30b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch        __ Ldr(temp2, src_operand);
31b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch        break;
32b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch      case MemOperand::kPairAB:
33b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch        __ Ldp(temp1, temp2, pending_address_src_);
34b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch        break;
35b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch      case MemOperand::kPairBA:
36b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch        __ Ldp(temp2, temp1, src_operand);
37b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch        break;
38b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    }
39b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    switch (MemOperand::AreConsistentForPair(pending_address_dst_,
40b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch                                             dst_operand)) {
41b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch      case MemOperand::kNotPair:
42b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch        __ Str(temp1, pending_address_dst_);
43b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch        __ Str(temp2, dst_operand);
44b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch        break;
45b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch      case MemOperand::kPairAB:
46b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch        __ Stp(temp1, temp2, pending_address_dst_);
47b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch        break;
48b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch      case MemOperand::kPairBA:
49b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch        __ Stp(temp2, temp1, dst_operand);
50b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch        break;
51b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    }
52b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    ResetPending();
53b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    return;
54b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  }
55b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
56b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  EmitPending();
57b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  pending_ = kStackSlotMove;
58b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  pending_address_src_ = src_operand;
59b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  pending_address_dst_ = dst_operand;
60b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch#ifdef DEBUG
61b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  pending_pc_ = masm_->pc_offset();
62b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch#endif
63b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch}
64b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
65b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
66b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdochvoid DelayedMasm::StoreConstant(uint64_t value, const MemOperand& operand) {
67b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  DCHECK(!scratch_register_acquired_);
68b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  if ((pending_ == kStoreConstant) && (value == pending_value_)) {
69b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    MemOperand::PairResult result =
70b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch        MemOperand::AreConsistentForPair(pending_address_dst_, operand);
71b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    if (result != MemOperand::kNotPair) {
72b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch      const MemOperand& dst =
73b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch          (result == MemOperand::kPairAB) ?
74b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch              pending_address_dst_ :
75b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch              operand;
76b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch      DCHECK(pending_pc_ == masm_->pc_offset());
77b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch      if (pending_value_ == 0) {
78b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch        __ Stp(xzr, xzr, dst);
79b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch      } else {
80b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch        SetSavedValue(pending_value_);
81b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch        __ Stp(ScratchRegister(), ScratchRegister(), dst);
82b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch      }
83b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch      ResetPending();
84b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch      return;
85b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    }
86b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  }
87b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
88b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  EmitPending();
89b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  pending_ = kStoreConstant;
90b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  pending_address_dst_ = operand;
91b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  pending_value_ = value;
92b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch#ifdef DEBUG
93b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  pending_pc_ = masm_->pc_offset();
94b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch#endif
95b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch}
96b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
97b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
98b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdochvoid DelayedMasm::Load(const CPURegister& rd, const MemOperand& operand) {
99b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  if ((pending_ == kLoad) &&
100b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch      pending_register_.IsSameSizeAndType(rd)) {
101b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    switch (MemOperand::AreConsistentForPair(pending_address_src_, operand)) {
102b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch      case MemOperand::kNotPair:
103b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch        break;
104b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch      case MemOperand::kPairAB:
105b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch        DCHECK(pending_pc_ == masm_->pc_offset());
106b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch        DCHECK(!IsScratchRegister(pending_register_) ||
107b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch               scratch_register_acquired_);
108b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch        DCHECK(!IsScratchRegister(rd) || scratch_register_acquired_);
109b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch        __ Ldp(pending_register_, rd, pending_address_src_);
110b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch        ResetPending();
111b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch        return;
112b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch      case MemOperand::kPairBA:
113b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch        DCHECK(pending_pc_ == masm_->pc_offset());
114b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch        DCHECK(!IsScratchRegister(pending_register_) ||
115b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch               scratch_register_acquired_);
116b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch        DCHECK(!IsScratchRegister(rd) || scratch_register_acquired_);
117b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch        __ Ldp(rd, pending_register_, operand);
118b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch        ResetPending();
119b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch        return;
120b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    }
121b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  }
122b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
123b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  EmitPending();
124b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  pending_ = kLoad;
125b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  pending_register_ = rd;
126b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  pending_address_src_ = operand;
127b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch#ifdef DEBUG
128b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  pending_pc_ = masm_->pc_offset();
129b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch#endif
130b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch}
131b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
132b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
133b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdochvoid DelayedMasm::Store(const CPURegister& rd, const MemOperand& operand) {
134b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  if ((pending_ == kStore) &&
135b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch      pending_register_.IsSameSizeAndType(rd)) {
136b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    switch (MemOperand::AreConsistentForPair(pending_address_dst_, operand)) {
137b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch      case MemOperand::kNotPair:
138b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch        break;
139b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch      case MemOperand::kPairAB:
140b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch        DCHECK(pending_pc_ == masm_->pc_offset());
141b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch        __ Stp(pending_register_, rd, pending_address_dst_);
142b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch        ResetPending();
143b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch        return;
144b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch      case MemOperand::kPairBA:
145b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch        DCHECK(pending_pc_ == masm_->pc_offset());
146b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch        __ Stp(rd, pending_register_, operand);
147b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch        ResetPending();
148b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch        return;
149b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    }
150b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  }
151b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
152b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  EmitPending();
153b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  pending_ = kStore;
154b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  pending_register_ = rd;
155b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  pending_address_dst_ = operand;
156b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch#ifdef DEBUG
157b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  pending_pc_ = masm_->pc_offset();
158b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch#endif
159b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch}
160b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
161b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
162b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdochvoid DelayedMasm::EmitPending() {
163b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  DCHECK((pending_ == kNone) || (pending_pc_ == masm_->pc_offset()));
164b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  switch (pending_) {
165b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    case kNone:
166b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch      return;
167b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    case kStoreConstant:
168b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch      if (pending_value_ == 0) {
169b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch        __ Str(xzr, pending_address_dst_);
170b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch      } else {
171b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch        SetSavedValue(pending_value_);
172b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch        __ Str(ScratchRegister(), pending_address_dst_);
173b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch      }
174b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch      break;
175b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    case kLoad:
176b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch      DCHECK(!IsScratchRegister(pending_register_) ||
177b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch              scratch_register_acquired_);
178b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch      __ Ldr(pending_register_, pending_address_src_);
179b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch      break;
180b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    case kStore:
181b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch      __ Str(pending_register_, pending_address_dst_);
182b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch      break;
183b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    case kStackSlotMove: {
184b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch      UseScratchRegisterScope scope(masm_);
185b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch      DoubleRegister temp = scope.AcquireD();
186b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch      __ Ldr(temp, pending_address_src_);
187b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch      __ Str(temp, pending_address_dst_);
188b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch      break;
189b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    }
190b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  }
191b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  ResetPending();
192b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch}
193b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
194014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch}  // namespace internal
195014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch}  // namespace v8
196b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
197b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch#endif  // V8_TARGET_ARCH_ARM64
198