// Copyright 2013 the V8 project authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.

#if V8_TARGET_ARCH_ARM64

#include "src/regexp/arm64/regexp-macro-assembler-arm64.h"

#include "src/arm64/macro-assembler-arm64-inl.h"
#include "src/code-stubs.h"
#include "src/log.h"
#include "src/macro-assembler.h"
#include "src/objects-inl.h"
#include "src/regexp/regexp-macro-assembler.h"
#include "src/regexp/regexp-stack.h"
#include "src/unicode.h"

namespace v8 {
namespace internal {

#ifndef V8_INTERPRETED_REGEXP
/*
 * This assembler uses the following register assignment convention:
 * - w19     : Used to temporarely store a value before a call to C code.
 *             See CheckNotBackReferenceIgnoreCase.
 * - x20     : Pointer to the current code object (Code*),
 *             it includes the heap object tag.
 * - w21     : Current position in input, as negative offset from
 *             the end of the string. Please notice that this is
 *             the byte offset, not the character offset!
 * - w22     : Currently loaded character. Must be loaded using
 *             LoadCurrentCharacter before using any of the dispatch methods.
 * - x23     : Points to tip of backtrack stack.
 * - w24     : Position of the first character minus one: non_position_value.
 *             Used to initialize capture registers.
 * - x25     : Address at the end of the input string: input_end.
 *             Points to byte after last character in input.
 * - x26     : Address at the start of the input string: input_start.
 * - w27     : Where to start in the input string.
 * - x28     : Output array pointer.
 * - x29/fp  : Frame pointer. Used to access arguments, local variables and
 *             RegExp registers.
 * - x16/x17 : IP registers, used by assembler. Very volatile.
 * - csp     : Points to tip of C stack.
 *
 * - x0-x7   : Used as a cache to store 32 bit capture registers. These
 *             registers need to be retained every time a call to C code
 *             is done.
 *
 * The remaining registers are free for computations.
 * Each call to a public method should retain this convention.
 *
 * The stack will have the following structure:
 *
 *  Location    Name               Description
 *              (as referred to in
 *              the code)
 *
 *  - fp[96]   isolate            Address of the current isolate.
 *  ^^^ csp when called ^^^
 *  - fp[88]    lr                 Return from the RegExp code.
 *  - fp[80]    r29                Old frame pointer (CalleeSaved).
 *  - fp[0..72] r19-r28            Backup of CalleeSaved registers.
 *  - fp[-8]    direct_call        1 => Direct call from JavaScript code.
 *                                 0 => Call through the runtime system.
 *  - fp[-16]   stack_base         High end of the memory area to use as
 *                                 the backtracking stack.
 *  - fp[-24]   output_size        Output may fit multiple sets of matches.
 *  - fp[-32]   input              Handle containing the input string.
 *  - fp[-40]   success_counter
 *  ^^^^^^^^^^^^^ From here and downwards we store 32 bit values ^^^^^^^^^^^^^
 *  - fp[-44]   register N         Capture registers initialized with
 *  - fp[-48]   register N + 1     non_position_value.
 *              ...                The first kNumCachedRegisters (N) registers
 *              ...                are cached in x0 to x7.
 *              ...                Only positions must be stored in the first
 *  -           ...                num_saved_registers_ registers.
 *  -           ...
 *  -           register N + num_registers - 1
 *  ^^^^^^^^^ csp ^^^^^^^^^
 *
 * The first num_saved_registers_ registers are initialized to point to
 * "character -1" in the string (i.e., char_size() bytes before the first
 * character of the string). The remaining registers start out as garbage.
 *
 * The data up to the return address must be placed there by the calling
 * code and the remaining arguments are passed in registers, e.g. by calling the
 * code entry as cast to a function with the signature:
 * int (*match)(String* input_string,
 *              int start_index,
 *              Address start,
 *              Address end,
 *              int* capture_output_array,
 *              int num_capture_registers,
 *              byte* stack_area_base,
 *              bool direct_call = false,
 *              Isolate* isolate);
 * The call is performed by NativeRegExpMacroAssembler::Execute()
 * (in regexp-macro-assembler.cc) via the GeneratedCode wrapper.
 */

#define __ ACCESS_MASM(masm_)

RegExpMacroAssemblerARM64::RegExpMacroAssemblerARM64(Isolate* isolate,
                                                     Zone* zone, Mode mode,
                                                     int registers_to_save)
    : NativeRegExpMacroAssembler(isolate, zone),
      masm_(new MacroAssembler(isolate, nullptr, kRegExpCodeSize,
                               CodeObjectRequired::kYes)),
      mode_(mode),
      num_registers_(registers_to_save),
      num_saved_registers_(registers_to_save),
      entry_label_(),
      start_label_(),
      success_label_(),
      backtrack_label_(),
      exit_label_() {
  DCHECK_EQ(0, registers_to_save % 2);
  // We can cache at most 16 W registers in x0-x7.
  STATIC_ASSERT(kNumCachedRegisters <= 16);
  STATIC_ASSERT((kNumCachedRegisters % 2) == 0);
  __ B(&entry_label_);   // We'll write the entry code later.
  __ Bind(&start_label_);  // And then continue from here.
}


RegExpMacroAssemblerARM64::~RegExpMacroAssemblerARM64() {
  delete masm_;
  // Unuse labels in case we throw away the assembler without calling GetCode.
  entry_label_.Unuse();
  start_label_.Unuse();
  success_label_.Unuse();
  backtrack_label_.Unuse();
  exit_label_.Unuse();
  check_preempt_label_.Unuse();
  stack_overflow_label_.Unuse();
}

int RegExpMacroAssemblerARM64::stack_limit_slack()  {
  return RegExpStack::kStackLimitSlack;
}


void RegExpMacroAssemblerARM64::AdvanceCurrentPosition(int by) {
  if (by != 0) {
    __ Add(current_input_offset(),
           current_input_offset(), by * char_size());
  }
}


void RegExpMacroAssemblerARM64::AdvanceRegister(int reg, int by) {
  DCHECK((reg >= 0) && (reg < num_registers_));
  if (by != 0) {
    RegisterState register_state = GetRegisterState(reg);
    switch (register_state) {
      case STACKED:
        __ Ldr(w10, register_location(reg));
        __ Add(w10, w10, by);
        __ Str(w10, register_location(reg));
        break;
      case CACHED_LSW: {
        Register to_advance = GetCachedRegister(reg);
        __ Add(to_advance, to_advance, by);
        break;
      }
      case CACHED_MSW: {
        Register to_advance = GetCachedRegister(reg);
        __ Add(to_advance, to_advance,
               static_cast<int64_t>(by) << kWRegSizeInBits);
        break;
      }
      default:
        UNREACHABLE();
        break;
    }
  }
}


void RegExpMacroAssemblerARM64::Backtrack() {
  CheckPreemption();
  Pop(w10);
  __ Add(x10, code_pointer(), Operand(w10, UXTW));
  __ Br(x10);
}


void RegExpMacroAssemblerARM64::Bind(Label* label) {
  __ Bind(label);
}


void RegExpMacroAssemblerARM64::CheckCharacter(uint32_t c, Label* on_equal) {
  CompareAndBranchOrBacktrack(current_character(), c, eq, on_equal);
}


void RegExpMacroAssemblerARM64::CheckCharacterGT(uc16 limit,
                                                 Label* on_greater) {
  CompareAndBranchOrBacktrack(current_character(), limit, hi, on_greater);
}


void RegExpMacroAssemblerARM64::CheckAtStart(Label* on_at_start) {
  __ Add(w10, current_input_offset(), Operand(-char_size()));
  __ Cmp(w10, string_start_minus_one());
  BranchOrBacktrack(eq, on_at_start);
}


void RegExpMacroAssemblerARM64::CheckNotAtStart(int cp_offset,
                                                Label* on_not_at_start) {
  __ Add(w10, current_input_offset(),
         Operand(-char_size() + cp_offset * char_size()));
  __ Cmp(w10, string_start_minus_one());
  BranchOrBacktrack(ne, on_not_at_start);
}


void RegExpMacroAssemblerARM64::CheckCharacterLT(uc16 limit, Label* on_less) {
  CompareAndBranchOrBacktrack(current_character(), limit, lo, on_less);
}


void RegExpMacroAssemblerARM64::CheckCharacters(Vector<const uc16> str,
                                              int cp_offset,
                                              Label* on_failure,
                                              bool check_end_of_string) {
  // This method is only ever called from the cctests.

  if (check_end_of_string) {
    // Is last character of required match inside string.
    CheckPosition(cp_offset + str.length() - 1, on_failure);
  }

  Register characters_address = x11;

  __ Add(characters_address,
         input_end(),
         Operand(current_input_offset(), SXTW));
  if (cp_offset != 0) {
    __ Add(characters_address, characters_address, cp_offset * char_size());
  }

  for (int i = 0; i < str.length(); i++) {
    if (mode_ == LATIN1) {
      __ Ldrb(w10, MemOperand(characters_address, 1, PostIndex));
      DCHECK_GE(String::kMaxOneByteCharCode, str[i]);
    } else {
      __ Ldrh(w10, MemOperand(characters_address, 2, PostIndex));
    }
    CompareAndBranchOrBacktrack(w10, str[i], ne, on_failure);
  }
}


void RegExpMacroAssemblerARM64::CheckGreedyLoop(Label* on_equal) {
  __ Ldr(w10, MemOperand(backtrack_stackpointer()));
  __ Cmp(current_input_offset(), w10);
  __ Cset(x11, eq);
  __ Add(backtrack_stackpointer(),
         backtrack_stackpointer(), Operand(x11, LSL, kWRegSizeLog2));
  BranchOrBacktrack(eq, on_equal);
}


void RegExpMacroAssemblerARM64::CheckNotBackReferenceIgnoreCase(
    int start_reg, bool read_backward, bool unicode, Label* on_no_match) {
  Label fallthrough;

  Register capture_start_offset = w10;
  // Save the capture length in a callee-saved register so it will
  // be preserved if we call a C helper.
  Register capture_length = w19;
  DCHECK(kCalleeSaved.IncludesAliasOf(capture_length));

  // Find length of back-referenced capture.
  DCHECK_EQ(0, start_reg % 2);
  if (start_reg < kNumCachedRegisters) {
    __ Mov(capture_start_offset.X(), GetCachedRegister(start_reg));
    __ Lsr(x11, GetCachedRegister(start_reg), kWRegSizeInBits);
  } else {
    __ Ldp(w11, capture_start_offset, capture_location(start_reg, x10));
  }
  __ Sub(capture_length, w11, capture_start_offset);  // Length to check.

  // At this point, the capture registers are either both set or both cleared.
  // If the capture length is zero, then the capture is either empty or cleared.
  // Fall through in both cases.
  __ CompareAndBranch(capture_length, Operand(0), eq, &fallthrough);

  // Check that there are enough characters left in the input.
  if (read_backward) {
    __ Add(w12, string_start_minus_one(), capture_length);
    __ Cmp(current_input_offset(), w12);
    BranchOrBacktrack(le, on_no_match);
  } else {
    __ Cmn(capture_length, current_input_offset());
    BranchOrBacktrack(gt, on_no_match);
  }

  if (mode_ == LATIN1) {
    Label success;
    Label fail;
    Label loop_check;

    Register capture_start_address = x12;
    Register capture_end_addresss = x13;
    Register current_position_address = x14;

    __ Add(capture_start_address,
           input_end(),
           Operand(capture_start_offset, SXTW));
    __ Add(capture_end_addresss,
           capture_start_address,
           Operand(capture_length, SXTW));
    __ Add(current_position_address,
           input_end(),
           Operand(current_input_offset(), SXTW));
    if (read_backward) {
      // Offset by length when matching backwards.
      __ Sub(current_position_address, current_position_address,
             Operand(capture_length, SXTW));
    }

    Label loop;
    __ Bind(&loop);
    __ Ldrb(w10, MemOperand(capture_start_address, 1, PostIndex));
    __ Ldrb(w11, MemOperand(current_position_address, 1, PostIndex));
    __ Cmp(w10, w11);
    __ B(eq, &loop_check);

    // Mismatch, try case-insensitive match (converting letters to lower-case).
    __ Orr(w10, w10, 0x20);  // Convert capture character to lower-case.
    __ Orr(w11, w11, 0x20);  // Also convert input character.
    __ Cmp(w11, w10);
    __ B(ne, &fail);
    __ Sub(w10, w10, 'a');
    __ Cmp(w10, 'z' - 'a');  // Is w10 a lowercase letter?
    __ B(ls, &loop_check);  // In range 'a'-'z'.
    // Latin-1: Check for values in range [224,254] but not 247.
    __ Sub(w10, w10, 224 - 'a');
    __ Cmp(w10, 254 - 224);
    __ Ccmp(w10, 247 - 224, ZFlag, ls);  // Check for 247.
    __ B(eq, &fail);  // Weren't Latin-1 letters.

    __ Bind(&loop_check);
    __ Cmp(capture_start_address, capture_end_addresss);
    __ B(lt, &loop);
    __ B(&success);

    __ Bind(&fail);
    BranchOrBacktrack(al, on_no_match);

    __ Bind(&success);
    // Compute new value of character position after the matched part.
    __ Sub(current_input_offset().X(), current_position_address, input_end());
    if (read_backward) {
      __ Sub(current_input_offset().X(), current_input_offset().X(),
             Operand(capture_length, SXTW));
    }
    if (masm_->emit_debug_code()) {
      __ Cmp(current_input_offset().X(), Operand(current_input_offset(), SXTW));
      __ Ccmp(current_input_offset(), 0, NoFlag, eq);
      // The current input offset should be <= 0, and fit in a W register.
      __ Check(le, AbortReason::kOffsetOutOfRange);
    }
  } else {
    DCHECK(mode_ == UC16);
    int argument_count = 4;

    // The cached registers need to be retained.
    CPURegList cached_registers(CPURegister::kRegister, kXRegSizeInBits, 0, 7);
    DCHECK_EQ(kNumCachedRegisters, cached_registers.Count() * 2);
    __ PushCPURegList(cached_registers);

    // Put arguments into arguments registers.
    // Parameters are
    //   x0: Address byte_offset1 - Address captured substring's start.
    //   x1: Address byte_offset2 - Address of current character position.
    //   w2: size_t byte_length - length of capture in bytes(!)
    //   x3: Isolate* isolate or 0 if unicode flag

    // Address of start of capture.
    __ Add(x0, input_end(), Operand(capture_start_offset, SXTW));
    // Length of capture.
    __ Mov(w2, capture_length);
    // Address of current input position.
    __ Add(x1, input_end(), Operand(current_input_offset(), SXTW));
    if (read_backward) {
      __ Sub(x1, x1, Operand(capture_length, SXTW));
    }
    // Isolate.
#ifdef V8_INTL_SUPPORT
    if (unicode) {
      __ Mov(x3, Operand(0));
    } else  // NOLINT
#endif      // V8_INTL_SUPPORT
    {
      __ Mov(x3, ExternalReference::isolate_address(isolate()));
    }

    {
      AllowExternalCallThatCantCauseGC scope(masm_);
      ExternalReference function =
          ExternalReference::re_case_insensitive_compare_uc16(isolate());
      __ CallCFunction(function, argument_count);
    }

    // Check if function returned non-zero for success or zero for failure.
    // x0 is one of the registers used as a cache so it must be tested before
    // the cache is restored.
    __ Cmp(x0, 0);
    __ PopCPURegList(cached_registers);
    BranchOrBacktrack(eq, on_no_match);

    // On success, advance position by length of capture.
    if (read_backward) {
      __ Sub(current_input_offset(), current_input_offset(), capture_length);
    } else {
      __ Add(current_input_offset(), current_input_offset(), capture_length);
    }
  }

  __ Bind(&fallthrough);
}

void RegExpMacroAssemblerARM64::CheckNotBackReference(int start_reg,
                                                      bool read_backward,
                                                      Label* on_no_match) {
  Label fallthrough;

  Register capture_start_address = x12;
  Register capture_end_address = x13;
  Register current_position_address = x14;
  Register capture_length = w15;

  // Find length of back-referenced capture.
  DCHECK_EQ(0, start_reg % 2);
  if (start_reg < kNumCachedRegisters) {
    __ Mov(x10, GetCachedRegister(start_reg));
    __ Lsr(x11, GetCachedRegister(start_reg), kWRegSizeInBits);
  } else {
    __ Ldp(w11, w10, capture_location(start_reg, x10));
  }
  __ Sub(capture_length, w11, w10);  // Length to check.

  // At this point, the capture registers are either both set or both cleared.
  // If the capture length is zero, then the capture is either empty or cleared.
  // Fall through in both cases.
  __ CompareAndBranch(capture_length, Operand(0), eq, &fallthrough);

  // Check that there are enough characters left in the input.
  if (read_backward) {
    __ Add(w12, string_start_minus_one(), capture_length);
    __ Cmp(current_input_offset(), w12);
    BranchOrBacktrack(le, on_no_match);
  } else {
    __ Cmn(capture_length, current_input_offset());
    BranchOrBacktrack(gt, on_no_match);
  }

  // Compute pointers to match string and capture string
  __ Add(capture_start_address, input_end(), Operand(w10, SXTW));
  __ Add(capture_end_address,
         capture_start_address,
         Operand(capture_length, SXTW));
  __ Add(current_position_address,
         input_end(),
         Operand(current_input_offset(), SXTW));
  if (read_backward) {
    // Offset by length when matching backwards.
    __ Sub(current_position_address, current_position_address,
           Operand(capture_length, SXTW));
  }

  Label loop;
  __ Bind(&loop);
  if (mode_ == LATIN1) {
    __ Ldrb(w10, MemOperand(capture_start_address, 1, PostIndex));
    __ Ldrb(w11, MemOperand(current_position_address, 1, PostIndex));
  } else {
    DCHECK(mode_ == UC16);
    __ Ldrh(w10, MemOperand(capture_start_address, 2, PostIndex));
    __ Ldrh(w11, MemOperand(current_position_address, 2, PostIndex));
  }
  __ Cmp(w10, w11);
  BranchOrBacktrack(ne, on_no_match);
  __ Cmp(capture_start_address, capture_end_address);
  __ B(lt, &loop);

  // Move current character position to position after match.
  __ Sub(current_input_offset().X(), current_position_address, input_end());
  if (read_backward) {
    __ Sub(current_input_offset().X(), current_input_offset().X(),
           Operand(capture_length, SXTW));
  }

  if (masm_->emit_debug_code()) {
    __ Cmp(current_input_offset().X(), Operand(current_input_offset(), SXTW));
    __ Ccmp(current_input_offset(), 0, NoFlag, eq);
    // The current input offset should be <= 0, and fit in a W register.
    __ Check(le, AbortReason::kOffsetOutOfRange);
  }
  __ Bind(&fallthrough);
}


void RegExpMacroAssemblerARM64::CheckNotCharacter(unsigned c,
                                                  Label* on_not_equal) {
  CompareAndBranchOrBacktrack(current_character(), c, ne, on_not_equal);
}


void RegExpMacroAssemblerARM64::CheckCharacterAfterAnd(uint32_t c,
                                                       uint32_t mask,
                                                       Label* on_equal) {
  __ And(w10, current_character(), mask);
  CompareAndBranchOrBacktrack(w10, c, eq, on_equal);
}


void RegExpMacroAssemblerARM64::CheckNotCharacterAfterAnd(unsigned c,
                                                          unsigned mask,
                                                          Label* on_not_equal) {
  __ And(w10, current_character(), mask);
  CompareAndBranchOrBacktrack(w10, c, ne, on_not_equal);
}


void RegExpMacroAssemblerARM64::CheckNotCharacterAfterMinusAnd(
    uc16 c,
    uc16 minus,
    uc16 mask,
    Label* on_not_equal) {
  DCHECK_GT(String::kMaxUtf16CodeUnit, minus);
  __ Sub(w10, current_character(), minus);
  __ And(w10, w10, mask);
  CompareAndBranchOrBacktrack(w10, c, ne, on_not_equal);
}


void RegExpMacroAssemblerARM64::CheckCharacterInRange(
    uc16 from,
    uc16 to,
    Label* on_in_range) {
  __ Sub(w10, current_character(), from);
  // Unsigned lower-or-same condition.
  CompareAndBranchOrBacktrack(w10, to - from, ls, on_in_range);
}


void RegExpMacroAssemblerARM64::CheckCharacterNotInRange(
    uc16 from,
    uc16 to,
    Label* on_not_in_range) {
  __ Sub(w10, current_character(), from);
  // Unsigned higher condition.
  CompareAndBranchOrBacktrack(w10, to - from, hi, on_not_in_range);
}


void RegExpMacroAssemblerARM64::CheckBitInTable(
    Handle<ByteArray> table,
    Label* on_bit_set) {
  __ Mov(x11, Operand(table));
  if ((mode_ != LATIN1) || (kTableMask != String::kMaxOneByteCharCode)) {
    __ And(w10, current_character(), kTableMask);
    __ Add(w10, w10, ByteArray::kHeaderSize - kHeapObjectTag);
  } else {
    __ Add(w10, current_character(), ByteArray::kHeaderSize - kHeapObjectTag);
  }
  __ Ldrb(w11, MemOperand(x11, w10, UXTW));
  CompareAndBranchOrBacktrack(w11, 0, ne, on_bit_set);
}


bool RegExpMacroAssemblerARM64::CheckSpecialCharacterClass(uc16 type,
                                                           Label* on_no_match) {
  // Range checks (c in min..max) are generally implemented by an unsigned
  // (c - min) <= (max - min) check
  switch (type) {
  case 's':
    // Match space-characters
    if (mode_ == LATIN1) {
      // One byte space characters are '\t'..'\r', ' ' and \u00a0.
      Label success;
      // Check for ' ' or 0x00A0.
      __ Cmp(current_character(), ' ');
      __ Ccmp(current_character(), 0x00A0, ZFlag, ne);
      __ B(eq, &success);
      // Check range 0x09..0x0D.
      __ Sub(w10, current_character(), '\t');
      CompareAndBranchOrBacktrack(w10, '\r' - '\t', hi, on_no_match);
      __ Bind(&success);
      return true;
    }
    return false;
  case 'S':
    // The emitted code for generic character classes is good enough.
    return false;
  case 'd':
    // Match ASCII digits ('0'..'9').
    __ Sub(w10, current_character(), '0');
    CompareAndBranchOrBacktrack(w10, '9' - '0', hi, on_no_match);
    return true;
  case 'D':
    // Match ASCII non-digits.
    __ Sub(w10, current_character(), '0');
    CompareAndBranchOrBacktrack(w10, '9' - '0', ls, on_no_match);
    return true;
  case '.': {
    // Match non-newlines (not 0x0A('\n'), 0x0D('\r'), 0x2028 and 0x2029)
    // Here we emit the conditional branch only once at the end to make branch
    // prediction more efficient, even though we could branch out of here
    // as soon as a character matches.
    __ Cmp(current_character(), 0x0A);
    __ Ccmp(current_character(), 0x0D, ZFlag, ne);
    if (mode_ == UC16) {
      __ Sub(w10, current_character(), 0x2028);
      // If the Z flag was set we clear the flags to force a branch.
      __ Ccmp(w10, 0x2029 - 0x2028, NoFlag, ne);
      // ls -> !((C==1) && (Z==0))
      BranchOrBacktrack(ls, on_no_match);
    } else {
      BranchOrBacktrack(eq, on_no_match);
    }
    return true;
  }
  case 'n': {
    // Match newlines (0x0A('\n'), 0x0D('\r'), 0x2028 and 0x2029)
    // We have to check all 4 newline characters before emitting
    // the conditional branch.
    __ Cmp(current_character(), 0x0A);
    __ Ccmp(current_character(), 0x0D, ZFlag, ne);
    if (mode_ == UC16) {
      __ Sub(w10, current_character(), 0x2028);
      // If the Z flag was set we clear the flags to force a fall-through.
      __ Ccmp(w10, 0x2029 - 0x2028, NoFlag, ne);
      // hi -> (C==1) && (Z==0)
      BranchOrBacktrack(hi, on_no_match);
    } else {
      BranchOrBacktrack(ne, on_no_match);
    }
    return true;
  }
  case 'w': {
    if (mode_ != LATIN1) {
      // Table is 256 entries, so all Latin1 characters can be tested.
      CompareAndBranchOrBacktrack(current_character(), 'z', hi, on_no_match);
    }
    ExternalReference map = ExternalReference::re_word_character_map();
    __ Mov(x10, map);
    __ Ldrb(w10, MemOperand(x10, current_character(), UXTW));
    CompareAndBranchOrBacktrack(w10, 0, eq, on_no_match);
    return true;
  }
  case 'W': {
    Label done;
    if (mode_ != LATIN1) {
      // Table is 256 entries, so all Latin1 characters can be tested.
      __ Cmp(current_character(), 'z');
      __ B(hi, &done);
    }
    ExternalReference map = ExternalReference::re_word_character_map();
    __ Mov(x10, map);
    __ Ldrb(w10, MemOperand(x10, current_character(), UXTW));
    CompareAndBranchOrBacktrack(w10, 0, ne, on_no_match);
    __ Bind(&done);
    return true;
  }
  case '*':
    // Match any character.
    return true;
  // No custom implementation (yet): s(UC16), S(UC16).
  default:
    return false;
  }
}


void RegExpMacroAssemblerARM64::Fail() {
  __ Mov(w0, FAILURE);
  __ B(&exit_label_);
}


Handle<HeapObject> RegExpMacroAssemblerARM64::GetCode(Handle<String> source) {
  Label return_w0;
  // Finalize code - write the entry point code now we know how many
  // registers we need.

  // Entry code:
  __ Bind(&entry_label_);

  // Arguments on entry:
  // x0:  String*  input
  // x1:  int      start_offset
  // x2:  byte*    input_start
  // x3:  byte*    input_end
  // x4:  int*     output array
  // x5:  int      output array size
  // x6:  Address  stack_base
  // x7:  int      direct_call

  // The stack pointer should be csp on entry.
  //  csp[8]:  address of the current isolate
  //  csp[0]:  secondary link/return address used by native call

  // Tell the system that we have a stack frame.  Because the type is MANUAL, no
  // code is generated.
  FrameScope scope(masm_, StackFrame::MANUAL);

  // Push registers on the stack, only push the argument registers that we need.
  CPURegList argument_registers(x0, x5, x6, x7);

  CPURegList registers_to_retain = kCalleeSaved;
  DCHECK_EQ(11, kCalleeSaved.Count());
  registers_to_retain.Combine(lr);

  DCHECK(csp.Is(__ StackPointer()));
  __ PushCPURegList(registers_to_retain);
  __ PushCPURegList(argument_registers);

  // Set frame pointer in place.
  __ Add(frame_pointer(), csp, argument_registers.Count() * kPointerSize);

  // Initialize callee-saved registers.
  __ Mov(start_offset(), w1);
  __ Mov(input_start(), x2);
  __ Mov(input_end(), x3);
  __ Mov(output_array(), x4);

  // Set the number of registers we will need to allocate, that is:
  //   - success_counter (X register)
  //   - (num_registers_ - kNumCachedRegisters) (W registers)
  int num_wreg_to_allocate = num_registers_ - kNumCachedRegisters;
  // Do not allocate registers on the stack if they can all be cached.
  if (num_wreg_to_allocate < 0) { num_wreg_to_allocate = 0; }
  // Make room for the success_counter.
  num_wreg_to_allocate += 2;

  // Make sure the stack alignment will be respected.
  int alignment = masm_->ActivationFrameAlignment();
  DCHECK_EQ(alignment % 16, 0);
  int align_mask = (alignment / kWRegSize) - 1;
  num_wreg_to_allocate = (num_wreg_to_allocate + align_mask) & ~align_mask;

  // Check if we have space on the stack.
  Label stack_limit_hit;
  Label stack_ok;

  ExternalReference stack_limit =
      ExternalReference::address_of_stack_limit(isolate());
  __ Mov(x10, stack_limit);
  __ Ldr(x10, MemOperand(x10));
  __ Subs(x10, csp, x10);

  // Handle it if the stack pointer is already below the stack limit.
  __ B(ls, &stack_limit_hit);

  // Check if there is room for the variable number of registers above
  // the stack limit.
  __ Cmp(x10, num_wreg_to_allocate * kWRegSize);
  __ B(hs, &stack_ok);

  // Exit with OutOfMemory exception. There is not enough space on the stack
  // for our working registers.
  __ Mov(w0, EXCEPTION);
  __ B(&return_w0);

  __ Bind(&stack_limit_hit);
  CallCheckStackGuardState(x10);
  // If returned value is non-zero, we exit with the returned value as result.
  __ Cbnz(w0, &return_w0);

  __ Bind(&stack_ok);

  // Allocate space on stack.
  __ Claim(num_wreg_to_allocate, kWRegSize);

  // Initialize success_counter with 0.
  __ Str(wzr, MemOperand(frame_pointer(), kSuccessCounter));

  // Find negative length (offset of start relative to end).
  __ Sub(x10, input_start(), input_end());
  if (masm_->emit_debug_code()) {
    // Check that the size of the input string chars is in range.
    __ Neg(x11, x10);
    __ Cmp(x11, SeqTwoByteString::kMaxCharsSize);
    __ Check(ls, AbortReason::kInputStringTooLong);
  }
  __ Mov(current_input_offset(), w10);

  // The non-position value is used as a clearing value for the
  // capture registers, it corresponds to the position of the first character
  // minus one.
  __ Sub(string_start_minus_one(), current_input_offset(), char_size());
  __ Sub(string_start_minus_one(), string_start_minus_one(),
         Operand(start_offset(), LSL, (mode_ == UC16) ? 1 : 0));
  // We can store this value twice in an X register for initializing
  // on-stack registers later.
  __ Orr(twice_non_position_value(), string_start_minus_one().X(),
         Operand(string_start_minus_one().X(), LSL, kWRegSizeInBits));

  // Initialize code pointer register.
  __ Mov(code_pointer(), Operand(masm_->CodeObject()));

  Label load_char_start_regexp, start_regexp;
  // Load newline if index is at start, previous character otherwise.
  __ Cbnz(start_offset(), &load_char_start_regexp);
  __ Mov(current_character(), '\n');
  __ B(&start_regexp);

  // Global regexp restarts matching here.
  __ Bind(&load_char_start_regexp);
  // Load previous char as initial value of current character register.
  LoadCurrentCharacterUnchecked(-1, 1);
  __ Bind(&start_regexp);
  // Initialize on-stack registers.
  if (num_saved_registers_ > 0) {
    ClearRegisters(0, num_saved_registers_ - 1);
  }

  // Initialize backtrack stack pointer.
  __ Ldr(backtrack_stackpointer(), MemOperand(frame_pointer(), kStackBase));

  // Execute
  __ B(&start_label_);

  if (backtrack_label_.is_linked()) {
    __ Bind(&backtrack_label_);
    Backtrack();
  }

  if (success_label_.is_linked()) {
    Register first_capture_start = w15;

    // Save captures when successful.
    __ Bind(&success_label_);

    if (num_saved_registers_ > 0) {
      // V8 expects the output to be an int32_t array.
      Register capture_start = w12;
      Register capture_end = w13;
      Register input_length = w14;

      // Copy captures to output.

      // Get string length.
      __ Sub(x10, input_end(), input_start());
      if (masm_->emit_debug_code()) {
        // Check that the size of the input string chars is in range.
        __ Cmp(x10, SeqTwoByteString::kMaxCharsSize);
        __ Check(ls, AbortReason::kInputStringTooLong);
      }
      // input_start has a start_offset offset on entry. We need to include
      // it when computing the length of the whole string.
      if (mode_ == UC16) {
        __ Add(input_length, start_offset(), Operand(w10, LSR, 1));
      } else {
        __ Add(input_length, start_offset(), w10);
      }

      // Copy the results to the output array from the cached registers first.
      for (int i = 0;
           (i < num_saved_registers_) && (i < kNumCachedRegisters);
           i += 2) {
        __ Mov(capture_start.X(), GetCachedRegister(i));
        __ Lsr(capture_end.X(), capture_start.X(), kWRegSizeInBits);
        if ((i == 0) && global_with_zero_length_check()) {
          // Keep capture start for the zero-length check later.
          __ Mov(first_capture_start, capture_start);
        }
        // Offsets need to be relative to the start of the string.
        if (mode_ == UC16) {
          __ Add(capture_start, input_length, Operand(capture_start, ASR, 1));
          __ Add(capture_end, input_length, Operand(capture_end, ASR, 1));
        } else {
          __ Add(capture_start, input_length, capture_start);
          __ Add(capture_end, input_length, capture_end);
        }
        // The output pointer advances for a possible global match.
        __ Stp(capture_start,
               capture_end,
               MemOperand(output_array(), kPointerSize, PostIndex));
      }

      // Only carry on if there are more than kNumCachedRegisters capture
      // registers.
      int num_registers_left_on_stack =
          num_saved_registers_ - kNumCachedRegisters;
      if (num_registers_left_on_stack > 0) {
        Register base = x10;
        // There are always an even number of capture registers. A couple of
        // registers determine one match with two offsets.
        DCHECK_EQ(0, num_registers_left_on_stack % 2);
        __ Add(base, frame_pointer(), kFirstCaptureOnStack);

        // We can unroll the loop here, we should not unroll for less than 2
        // registers.
        STATIC_ASSERT(kNumRegistersToUnroll > 2);
        if (num_registers_left_on_stack <= kNumRegistersToUnroll) {
          for (int i = 0; i < num_registers_left_on_stack / 2; i++) {
            __ Ldp(capture_end,
                   capture_start,
                   MemOperand(base, -kPointerSize, PostIndex));
            if ((i == 0) && global_with_zero_length_check()) {
              // Keep capture start for the zero-length check later.
              __ Mov(first_capture_start, capture_start);
            }
            // Offsets need to be relative to the start of the string.
            if (mode_ == UC16) {
              __ Add(capture_start,
                     input_length,
                     Operand(capture_start, ASR, 1));
              __ Add(capture_end, input_length, Operand(capture_end, ASR, 1));
            } else {
              __ Add(capture_start, input_length, capture_start);
              __ Add(capture_end, input_length, capture_end);
            }
            // The output pointer advances for a possible global match.
            __ Stp(capture_start,
                   capture_end,
                   MemOperand(output_array(), kPointerSize, PostIndex));
          }
        } else {
          Label loop, start;
          __ Mov(x11, num_registers_left_on_stack);

          __ Ldp(capture_end,
                 capture_start,
                 MemOperand(base, -kPointerSize, PostIndex));
          if (global_with_zero_length_check()) {
            __ Mov(first_capture_start, capture_start);
          }
          __ B(&start);

          __ Bind(&loop);
          __ Ldp(capture_end,
                 capture_start,
                 MemOperand(base, -kPointerSize, PostIndex));
          __ Bind(&start);
          if (mode_ == UC16) {
            __ Add(capture_start, input_length, Operand(capture_start, ASR, 1));
            __ Add(capture_end, input_length, Operand(capture_end, ASR, 1));
          } else {
            __ Add(capture_start, input_length, capture_start);
            __ Add(capture_end, input_length, capture_end);
          }
          // The output pointer advances for a possible global match.
          __ Stp(capture_start,
                 capture_end,
                 MemOperand(output_array(), kPointerSize, PostIndex));
          __ Sub(x11, x11, 2);
          __ Cbnz(x11, &loop);
        }
      }
    }

    if (global()) {
      Register success_counter = w0;
      Register output_size = x10;
      // Restart matching if the regular expression is flagged as global.

      // Increment success counter.
      __ Ldr(success_counter, MemOperand(frame_pointer(), kSuccessCounter));
      __ Add(success_counter, success_counter, 1);
      __ Str(success_counter, MemOperand(frame_pointer(), kSuccessCounter));

      // Capture results have been stored, so the number of remaining global
      // output registers is reduced by the number of stored captures.
      __ Ldr(output_size, MemOperand(frame_pointer(), kOutputSize));
      __ Sub(output_size, output_size, num_saved_registers_);
      // Check whether we have enough room for another set of capture results.
      __ Cmp(output_size, num_saved_registers_);
      __ B(lt, &return_w0);

      // The output pointer is already set to the next field in the output
      // array.
      // Update output size on the frame before we restart matching.
      __ Str(output_size, MemOperand(frame_pointer(), kOutputSize));

      if (global_with_zero_length_check()) {
        // Special case for zero-length matches.
        __ Cmp(current_input_offset(), first_capture_start);
        // Not a zero-length match, restart.
        __ B(ne, &load_char_start_regexp);
        // Offset from the end is zero if we already reached the end.
        __ Cbz(current_input_offset(), &return_w0);
        // Advance current position after a zero-length match.
        Label advance;
        __ bind(&advance);
        __ Add(current_input_offset(),
               current_input_offset(),
               Operand((mode_ == UC16) ? 2 : 1));
        if (global_unicode()) CheckNotInSurrogatePair(0, &advance);
      }

      __ B(&load_char_start_regexp);
    } else {
      __ Mov(w0, SUCCESS);
    }
  }

  if (exit_label_.is_linked()) {
    // Exit and return w0
    __ Bind(&exit_label_);
    if (global()) {
      __ Ldr(w0, MemOperand(frame_pointer(), kSuccessCounter));
    }
  }

  __ Bind(&return_w0);

  // Set stack pointer back to first register to retain
  DCHECK(csp.Is(__ StackPointer()));
  __ Mov(csp, fp);
  __ AssertStackConsistency();

  // Restore registers.
  __ PopCPURegList(registers_to_retain);

  __ Ret();

  Label exit_with_exception;
  // Registers x0 to x7 are used to store the first captures, they need to be
  // retained over calls to C++ code.
  CPURegList cached_registers(CPURegister::kRegister, kXRegSizeInBits, 0, 7);
  DCHECK_EQ(kNumCachedRegisters, cached_registers.Count() * 2);

  if (check_preempt_label_.is_linked()) {
    __ Bind(&check_preempt_label_);
    SaveLinkRegister();
    // The cached registers need to be retained.
    __ PushCPURegList(cached_registers);
    CallCheckStackGuardState(x10);
    // Returning from the regexp code restores the stack (csp <- fp)
    // so we don't need to drop the link register from it before exiting.
    __ Cbnz(w0, &return_w0);
    // Reset the cached registers.
    __ PopCPURegList(cached_registers);
    RestoreLinkRegister();
    __ Ret();
  }

  if (stack_overflow_label_.is_linked()) {
    __ Bind(&stack_overflow_label_);
    SaveLinkRegister();
    // The cached registers need to be retained.
    __ PushCPURegList(cached_registers);
    // Call GrowStack(backtrack_stackpointer(), &stack_base)
    __ Mov(x2, ExternalReference::isolate_address(isolate()));
    __ Add(x1, frame_pointer(), kStackBase);
    __ Mov(x0, backtrack_stackpointer());
    ExternalReference grow_stack =
        ExternalReference::re_grow_stack(isolate());
    __ CallCFunction(grow_stack, 3);
    // If return nullptr, we have failed to grow the stack, and
    // must exit with a stack-overflow exception.
    // Returning from the regexp code restores the stack (csp <- fp)
    // so we don't need to drop the link register from it before exiting.
    __ Cbz(w0, &exit_with_exception);
    // Otherwise use return value as new stack pointer.
    __ Mov(backtrack_stackpointer(), x0);
    // Reset the cached registers.
    __ PopCPURegList(cached_registers);
    RestoreLinkRegister();
    __ Ret();
  }

  if (exit_with_exception.is_linked()) {
    __ Bind(&exit_with_exception);
    __ Mov(w0, EXCEPTION);
    __ B(&return_w0);
  }

  CodeDesc code_desc;
  masm_->GetCode(isolate(), &code_desc);
  Handle<Code> code = isolate()->factory()->NewCode(code_desc, Code::REGEXP,
                                                    masm_->CodeObject());
  PROFILE(masm_->isolate(),
          RegExpCodeCreateEvent(AbstractCode::cast(*code), *source));
  return Handle<HeapObject>::cast(code);
}


void RegExpMacroAssemblerARM64::GoTo(Label* to) {
  BranchOrBacktrack(al, to);
}

void RegExpMacroAssemblerARM64::IfRegisterGE(int reg, int comparand,
                                             Label* if_ge) {
  Register to_compare = GetRegister(reg, w10);
  CompareAndBranchOrBacktrack(to_compare, comparand, ge, if_ge);
}


void RegExpMacroAssemblerARM64::IfRegisterLT(int reg, int comparand,
                                             Label* if_lt) {
  Register to_compare = GetRegister(reg, w10);
  CompareAndBranchOrBacktrack(to_compare, comparand, lt, if_lt);
}


void RegExpMacroAssemblerARM64::IfRegisterEqPos(int reg, Label* if_eq) {
  Register to_compare = GetRegister(reg, w10);
  __ Cmp(to_compare, current_input_offset());
  BranchOrBacktrack(eq, if_eq);
}

RegExpMacroAssembler::IrregexpImplementation
    RegExpMacroAssemblerARM64::Implementation() {
  return kARM64Implementation;
}


void RegExpMacroAssemblerARM64::LoadCurrentCharacter(int cp_offset,
                                                     Label* on_end_of_input,
                                                     bool check_bounds,
                                                     int characters) {
  // TODO(pielan): Make sure long strings are caught before this, and not
  // just asserted in debug mode.
  // Be sane! (And ensure that an int32_t can be used to index the string)
  DCHECK(cp_offset < (1<<30));
  if (check_bounds) {
    if (cp_offset >= 0) {
      CheckPosition(cp_offset + characters - 1, on_end_of_input);
    } else {
      CheckPosition(cp_offset, on_end_of_input);
    }
  }
  LoadCurrentCharacterUnchecked(cp_offset, characters);
}


void RegExpMacroAssemblerARM64::PopCurrentPosition() {
  Pop(current_input_offset());
}


void RegExpMacroAssemblerARM64::PopRegister(int register_index) {
  Pop(w10);
  StoreRegister(register_index, w10);
}


void RegExpMacroAssemblerARM64::PushBacktrack(Label* label) {
  if (label->is_bound()) {
    int target = label->pos();
    __ Mov(w10, target + Code::kHeaderSize - kHeapObjectTag);
  } else {
    __ Adr(x10, label, MacroAssembler::kAdrFar);
    __ Sub(x10, x10, code_pointer());
    if (masm_->emit_debug_code()) {
      __ Cmp(x10, kWRegMask);
      // The code offset has to fit in a W register.
      __ Check(ls, AbortReason::kOffsetOutOfRange);
    }
  }
  Push(w10);
  CheckStackLimit();
}


void RegExpMacroAssemblerARM64::PushCurrentPosition() {
  Push(current_input_offset());
}


void RegExpMacroAssemblerARM64::PushRegister(int register_index,
                                             StackCheckFlag check_stack_limit) {
  Register to_push = GetRegister(register_index, w10);
  Push(to_push);
  if (check_stack_limit) CheckStackLimit();
}


void RegExpMacroAssemblerARM64::ReadCurrentPositionFromRegister(int reg) {
  RegisterState register_state = GetRegisterState(reg);
  switch (register_state) {
    case STACKED:
      __ Ldr(current_input_offset(), register_location(reg));
      break;
    case CACHED_LSW:
      __ Mov(current_input_offset(), GetCachedRegister(reg).W());
      break;
    case CACHED_MSW:
      __ Lsr(current_input_offset().X(), GetCachedRegister(reg),
             kWRegSizeInBits);
      break;
    default:
      UNREACHABLE();
      break;
  }
}


void RegExpMacroAssemblerARM64::ReadStackPointerFromRegister(int reg) {
  Register read_from = GetRegister(reg, w10);
  __ Ldr(x11, MemOperand(frame_pointer(), kStackBase));
  __ Add(backtrack_stackpointer(), x11, Operand(read_from, SXTW));
}


void RegExpMacroAssemblerARM64::SetCurrentPositionFromEnd(int by) {
  Label after_position;
  __ Cmp(current_input_offset(), -by * char_size());
  __ B(ge, &after_position);
  __ Mov(current_input_offset(), -by * char_size());
  // On RegExp code entry (where this operation is used), the character before
  // the current position is expected to be already loaded.
  // We have advanced the position, so it's safe to read backwards.
  LoadCurrentCharacterUnchecked(-1, 1);
  __ Bind(&after_position);
}


void RegExpMacroAssemblerARM64::SetRegister(int register_index, int to) {
  DCHECK(register_index >= num_saved_registers_);  // Reserved for positions!
  Register set_to = wzr;
  if (to != 0) {
    set_to = w10;
    __ Mov(set_to, to);
  }
  StoreRegister(register_index, set_to);
}


bool RegExpMacroAssemblerARM64::Succeed() {
  __ B(&success_label_);
  return global();
}


void RegExpMacroAssemblerARM64::WriteCurrentPositionToRegister(int reg,
                                                               int cp_offset) {
  Register position = current_input_offset();
  if (cp_offset != 0) {
    position = w10;
    __ Add(position, current_input_offset(), cp_offset * char_size());
  }
  StoreRegister(reg, position);
}


void RegExpMacroAssemblerARM64::ClearRegisters(int reg_from, int reg_to) {
  DCHECK(reg_from <= reg_to);
  int num_registers = reg_to - reg_from + 1;

  // If the first capture register is cached in a hardware register but not
  // aligned on a 64-bit one, we need to clear the first one specifically.
  if ((reg_from < kNumCachedRegisters) && ((reg_from % 2) != 0)) {
    StoreRegister(reg_from, string_start_minus_one());
    num_registers--;
    reg_from++;
  }

  // Clear cached registers in pairs as far as possible.
  while ((num_registers >= 2) && (reg_from < kNumCachedRegisters)) {
    DCHECK(GetRegisterState(reg_from) == CACHED_LSW);
    __ Mov(GetCachedRegister(reg_from), twice_non_position_value());
    reg_from += 2;
    num_registers -= 2;
  }

  if ((num_registers % 2) == 1) {
    StoreRegister(reg_from, string_start_minus_one());
    num_registers--;
    reg_from++;
  }

  if (num_registers > 0) {
    // If there are some remaining registers, they are stored on the stack.
    DCHECK_LE(kNumCachedRegisters, reg_from);

    // Move down the indexes of the registers on stack to get the correct offset
    // in memory.
    reg_from -= kNumCachedRegisters;
    reg_to -= kNumCachedRegisters;
    // We should not unroll the loop for less than 2 registers.
    STATIC_ASSERT(kNumRegistersToUnroll > 2);
    // We position the base pointer to (reg_from + 1).
    int base_offset = kFirstRegisterOnStack -
        kWRegSize - (kWRegSize * reg_from);
    if (num_registers > kNumRegistersToUnroll) {
      Register base = x10;
      __ Add(base, frame_pointer(), base_offset);

      Label loop;
      __ Mov(x11, num_registers);
      __ Bind(&loop);
      __ Str(twice_non_position_value(),
             MemOperand(base, -kPointerSize, PostIndex));
      __ Sub(x11, x11, 2);
      __ Cbnz(x11, &loop);
    } else {
      for (int i = reg_from; i <= reg_to; i += 2) {
        __ Str(twice_non_position_value(),
               MemOperand(frame_pointer(), base_offset));
        base_offset -= kWRegSize * 2;
      }
    }
  }
}


void RegExpMacroAssemblerARM64::WriteStackPointerToRegister(int reg) {
  __ Ldr(x10, MemOperand(frame_pointer(), kStackBase));
  __ Sub(x10, backtrack_stackpointer(), x10);
  if (masm_->emit_debug_code()) {
    __ Cmp(x10, Operand(w10, SXTW));
    // The stack offset needs to fit in a W register.
    __ Check(eq, AbortReason::kOffsetOutOfRange);
  }
  StoreRegister(reg, w10);
}


// Helper function for reading a value out of a stack frame.
template <typename T>
static T& frame_entry(Address re_frame, int frame_offset) {
  return *reinterpret_cast<T*>(re_frame + frame_offset);
}


template <typename T>
static T* frame_entry_address(Address re_frame, int frame_offset) {
  return reinterpret_cast<T*>(re_frame + frame_offset);
}


int RegExpMacroAssemblerARM64::CheckStackGuardState(
    Address* return_address, Code* re_code, Address re_frame, int start_index,
    const byte** input_start, const byte** input_end) {
  return NativeRegExpMacroAssembler::CheckStackGuardState(
      frame_entry<Isolate*>(re_frame, kIsolate), start_index,
      frame_entry<int>(re_frame, kDirectCall) == 1, return_address, re_code,
      frame_entry_address<String*>(re_frame, kInput), input_start, input_end);
}


void RegExpMacroAssemblerARM64::CheckPosition(int cp_offset,
                                              Label* on_outside_input) {
  if (cp_offset >= 0) {
    CompareAndBranchOrBacktrack(current_input_offset(),
                                -cp_offset * char_size(), ge, on_outside_input);
  } else {
    __ Add(w12, current_input_offset(), Operand(cp_offset * char_size()));
    __ Cmp(w12, string_start_minus_one());
    BranchOrBacktrack(le, on_outside_input);
  }
}


// Private methods:

void RegExpMacroAssemblerARM64::CallCheckStackGuardState(Register scratch) {
  // Allocate space on the stack to store the return address. The
  // CheckStackGuardState C++ function will override it if the code
  // moved. Allocate extra space for 2 arguments passed by pointers.
  // AAPCS64 requires the stack to be 16 byte aligned.
  int alignment = masm_->ActivationFrameAlignment();
  DCHECK_EQ(alignment % 16, 0);
  int align_mask = (alignment / kXRegSize) - 1;
  int xreg_to_claim = (3 + align_mask) & ~align_mask;

  DCHECK(csp.Is(__ StackPointer()));
  __ Claim(xreg_to_claim);

  // CheckStackGuardState needs the end and start addresses of the input string.
  __ Poke(input_end(), 2 * kPointerSize);
  __ Add(x5, csp, 2 * kPointerSize);
  __ Poke(input_start(), kPointerSize);
  __ Add(x4, csp, kPointerSize);

  __ Mov(w3, start_offset());
  // RegExp code frame pointer.
  __ Mov(x2, frame_pointer());
  // Code* of self.
  __ Mov(x1, Operand(masm_->CodeObject()));

  // We need to pass a pointer to the return address as first argument.
  // The DirectCEntry stub will place the return address on the stack before
  // calling so the stack pointer will point to it.
  __ Mov(x0, csp);

  ExternalReference check_stack_guard_state =
      ExternalReference::re_check_stack_guard_state(isolate());
  __ Mov(scratch, check_stack_guard_state);
  DirectCEntryStub stub(isolate());
  stub.GenerateCall(masm_, scratch);

  // The input string may have been moved in memory, we need to reload it.
  __ Peek(input_start(), kPointerSize);
  __ Peek(input_end(), 2 * kPointerSize);

  DCHECK(csp.Is(__ StackPointer()));
  __ Drop(xreg_to_claim);

  // Reload the Code pointer.
  __ Mov(code_pointer(), Operand(masm_->CodeObject()));
}

void RegExpMacroAssemblerARM64::BranchOrBacktrack(Condition condition,
                                                  Label* to) {
  if (condition == al) {  // Unconditional.
    if (to == nullptr) {
      Backtrack();
      return;
    }
    __ B(to);
    return;
  }
  if (to == nullptr) {
    to = &backtrack_label_;
  }
  __ B(condition, to);
}

void RegExpMacroAssemblerARM64::CompareAndBranchOrBacktrack(Register reg,
                                                            int immediate,
                                                            Condition condition,
                                                            Label* to) {
  if ((immediate == 0) && ((condition == eq) || (condition == ne))) {
    if (to == nullptr) {
      to = &backtrack_label_;
    }
    if (condition == eq) {
      __ Cbz(reg, to);
    } else {
      __ Cbnz(reg, to);
    }
  } else {
    __ Cmp(reg, immediate);
    BranchOrBacktrack(condition, to);
  }
}


void RegExpMacroAssemblerARM64::CheckPreemption() {
  // Check for preemption.
  ExternalReference stack_limit =
      ExternalReference::address_of_stack_limit(isolate());
  __ Mov(x10, stack_limit);
  __ Ldr(x10, MemOperand(x10));
  DCHECK(csp.Is(__ StackPointer()));
  __ Cmp(csp, x10);
  CallIf(&check_preempt_label_, ls);
}


void RegExpMacroAssemblerARM64::CheckStackLimit() {
  ExternalReference stack_limit =
      ExternalReference::address_of_regexp_stack_limit(isolate());
  __ Mov(x10, stack_limit);
  __ Ldr(x10, MemOperand(x10));
  __ Cmp(backtrack_stackpointer(), x10);
  CallIf(&stack_overflow_label_, ls);
}


void RegExpMacroAssemblerARM64::Push(Register source) {
  DCHECK(source.Is32Bits());
  DCHECK(!source.is(backtrack_stackpointer()));
  __ Str(source,
         MemOperand(backtrack_stackpointer(),
                    -static_cast<int>(kWRegSize),
                    PreIndex));
}


void RegExpMacroAssemblerARM64::Pop(Register target) {
  DCHECK(target.Is32Bits());
  DCHECK(!target.is(backtrack_stackpointer()));
  __ Ldr(target,
         MemOperand(backtrack_stackpointer(), kWRegSize, PostIndex));
}


Register RegExpMacroAssemblerARM64::GetCachedRegister(int register_index) {
  DCHECK_GT(kNumCachedRegisters, register_index);
  return Register::Create(register_index / 2, kXRegSizeInBits);
}


Register RegExpMacroAssemblerARM64::GetRegister(int register_index,
                                                Register maybe_result) {
  DCHECK(maybe_result.Is32Bits());
  DCHECK_LE(0, register_index);
  if (num_registers_ <= register_index) {
    num_registers_ = register_index + 1;
  }
  Register result = NoReg;
  RegisterState register_state = GetRegisterState(register_index);
  switch (register_state) {
    case STACKED:
      __ Ldr(maybe_result, register_location(register_index));
      result = maybe_result;
      break;
    case CACHED_LSW:
      result = GetCachedRegister(register_index).W();
      break;
    case CACHED_MSW:
      __ Lsr(maybe_result.X(), GetCachedRegister(register_index),
             kWRegSizeInBits);
      result = maybe_result;
      break;
    default:
      UNREACHABLE();
      break;
  }
  DCHECK(result.Is32Bits());
  return result;
}


void RegExpMacroAssemblerARM64::StoreRegister(int register_index,
                                              Register source) {
  DCHECK(source.Is32Bits());
  DCHECK_LE(0, register_index);
  if (num_registers_ <= register_index) {
    num_registers_ = register_index + 1;
  }

  RegisterState register_state = GetRegisterState(register_index);
  switch (register_state) {
    case STACKED:
      __ Str(source, register_location(register_index));
      break;
    case CACHED_LSW: {
      Register cached_register = GetCachedRegister(register_index);
      if (!source.Is(cached_register.W())) {
        __ Bfi(cached_register, source.X(), 0, kWRegSizeInBits);
      }
      break;
    }
    case CACHED_MSW: {
      Register cached_register = GetCachedRegister(register_index);
      __ Bfi(cached_register, source.X(), kWRegSizeInBits, kWRegSizeInBits);
      break;
    }
    default:
      UNREACHABLE();
      break;
  }
}


void RegExpMacroAssemblerARM64::CallIf(Label* to, Condition condition) {
  Label skip_call;
  if (condition != al) __ B(&skip_call, NegateCondition(condition));
  __ Bl(to);
  __ Bind(&skip_call);
}


void RegExpMacroAssemblerARM64::RestoreLinkRegister() {
  DCHECK(csp.Is(__ StackPointer()));
  __ Pop(lr, xzr);
  __ Add(lr, lr, Operand(masm_->CodeObject()));
}


void RegExpMacroAssemblerARM64::SaveLinkRegister() {
  DCHECK(csp.Is(__ StackPointer()));
  __ Sub(lr, lr, Operand(masm_->CodeObject()));
  __ Push(xzr, lr);
}


MemOperand RegExpMacroAssemblerARM64::register_location(int register_index) {
  DCHECK(register_index < (1<<30));
  DCHECK_LE(kNumCachedRegisters, register_index);
  if (num_registers_ <= register_index) {
    num_registers_ = register_index + 1;
  }
  register_index -= kNumCachedRegisters;
  int offset = kFirstRegisterOnStack - register_index * kWRegSize;
  return MemOperand(frame_pointer(), offset);
}

MemOperand RegExpMacroAssemblerARM64::capture_location(int register_index,
                                                     Register scratch) {
  DCHECK(register_index < (1<<30));
  DCHECK(register_index < num_saved_registers_);
  DCHECK_LE(kNumCachedRegisters, register_index);
  DCHECK_EQ(register_index % 2, 0);
  register_index -= kNumCachedRegisters;
  int offset = kFirstCaptureOnStack - register_index * kWRegSize;
  // capture_location is used with Stp instructions to load/store 2 registers.
  // The immediate field in the encoding is limited to 7 bits (signed).
  if (is_int7(offset)) {
    return MemOperand(frame_pointer(), offset);
  } else {
    __ Add(scratch, frame_pointer(), offset);
    return MemOperand(scratch);
  }
}

void RegExpMacroAssemblerARM64::LoadCurrentCharacterUnchecked(int cp_offset,
                                                              int characters) {
  Register offset = current_input_offset();

  // The ldr, str, ldrh, strh instructions can do unaligned accesses, if the CPU
  // and the operating system running on the target allow it.
  // If unaligned load/stores are not supported then this function must only
  // be used to load a single character at a time.

  // ARMv8 supports unaligned accesses but V8 or the kernel can decide to
  // disable it.
  // TODO(pielan): See whether or not we should disable unaligned accesses.
  if (!CanReadUnaligned()) {
    DCHECK_EQ(1, characters);
  }

  if (cp_offset != 0) {
    if (masm_->emit_debug_code()) {
      __ Mov(x10, cp_offset * char_size());
      __ Add(x10, x10, Operand(current_input_offset(), SXTW));
      __ Cmp(x10, Operand(w10, SXTW));
      // The offset needs to fit in a W register.
      __ Check(eq, AbortReason::kOffsetOutOfRange);
    } else {
      __ Add(w10, current_input_offset(), cp_offset * char_size());
    }
    offset = w10;
  }

  if (mode_ == LATIN1) {
    if (characters == 4) {
      __ Ldr(current_character(), MemOperand(input_end(), offset, SXTW));
    } else if (characters == 2) {
      __ Ldrh(current_character(), MemOperand(input_end(), offset, SXTW));
    } else {
      DCHECK_EQ(1, characters);
      __ Ldrb(current_character(), MemOperand(input_end(), offset, SXTW));
    }
  } else {
    DCHECK(mode_ == UC16);
    if (characters == 2) {
      __ Ldr(current_character(), MemOperand(input_end(), offset, SXTW));
    } else {
      DCHECK_EQ(1, characters);
      __ Ldrh(current_character(), MemOperand(input_end(), offset, SXTW));
    }
  }
}

#endif  // V8_INTERPRETED_REGEXP

}  // namespace internal
}  // namespace v8

#undef __

#endif  // V8_TARGET_ARCH_ARM64
