1b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch// Copyright 2012 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_MIPS64 6b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 7014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch#include "src/regexp/mips64/regexp-macro-assembler-mips64.h" 8014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch 9b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch#include "src/code-stubs.h" 10b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch#include "src/log.h" 11b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch#include "src/macro-assembler.h" 12014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch#include "src/regexp/regexp-macro-assembler.h" 13014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch#include "src/regexp/regexp-stack.h" 14b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch#include "src/unicode.h" 15b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 16b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdochnamespace v8 { 17b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdochnamespace internal { 18b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 19b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch#ifndef V8_INTERPRETED_REGEXP 20b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch/* 21b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch * This assembler uses the following register assignment convention 22b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch * - t3 : Temporarily stores the index of capture start after a matching pass 23b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch * for a global regexp. 24b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch * - a5 : Pointer to current code object (Code*) including heap object tag. 25b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch * - a6 : Current position in input, as negative offset from end of string. 26b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch * Please notice that this is the byte offset, not the character offset! 27b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch * - a7 : Currently loaded character. Must be loaded using 28b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch * LoadCurrentCharacter before using any of the dispatch methods. 29b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch * - t0 : Points to tip of backtrack stack 30b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch * - t1 : Unused. 31b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch * - t2 : End of input (points to byte after last character in input). 32b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch * - fp : Frame pointer. Used to access arguments, local variables and 33b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch * RegExp registers. 34b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch * - sp : Points to tip of C stack. 35b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch * 36b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch * The remaining registers are free for computations. 37b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch * Each call to a public method should retain this convention. 38b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch * 39b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch * TODO(plind): O32 documented here with intent of having single 32/64 codebase 40b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch * in the future. 41b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch * 42b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch * The O32 stack will have the following structure: 43b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch * 44b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch * - fp[76] Isolate* isolate (address of the current isolate) 45b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch * - fp[72] direct_call (if 1, direct call from JavaScript code, 46b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch * if 0, call through the runtime system). 47b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch * - fp[68] stack_area_base (High end of the memory area to use as 48b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch * backtracking stack). 49b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch * - fp[64] capture array size (may fit multiple sets of matches) 50b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch * - fp[60] int* capture_array (int[num_saved_registers_], for output). 51b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch * - fp[44..59] MIPS O32 four argument slots 52b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch * - fp[40] secondary link/return address used by native call. 53b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch * --- sp when called --- 54b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch * - fp[36] return address (lr). 55b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch * - fp[32] old frame pointer (r11). 56b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch * - fp[0..31] backup of registers s0..s7. 57b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch * --- frame pointer ---- 58b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch * - fp[-4] end of input (address of end of string). 59b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch * - fp[-8] start of input (address of first character in string). 60b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch * - fp[-12] start index (character index of start). 61b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch * - fp[-16] void* input_string (location of a handle containing the string). 62b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch * - fp[-20] success counter (only for global regexps to count matches). 63b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch * - fp[-24] Offset of location before start of input (effectively character 64014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch * string start - 1). Used to initialize capture registers to a 65b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch * non-position. 66b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch * - fp[-28] At start (if 1, we are starting at the start of the 67b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch * string, otherwise 0) 68b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch * - fp[-32] register 0 (Only positions must be stored in the first 69b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch * - register 1 num_saved_registers_ registers) 70b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch * - ... 71b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch * - register num_registers-1 72b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch * --- sp --- 73b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch * 74b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch * 75b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch * The N64 stack will have the following structure: 76b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch * 77b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch * - fp[88] Isolate* isolate (address of the current isolate) kIsolate 78b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch * - fp[80] secondary link/return address used by exit frame on native call. kSecondaryReturnAddress 79b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch kStackFrameHeader 80b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch * --- sp when called --- 81b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch * - fp[72] ra Return from RegExp code (ra). kReturnAddress 82b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch * - fp[64] s9, old-fp Old fp, callee saved(s9). 83b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch * - fp[0..63] s0..s7 Callee-saved registers s0..s7. 84b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch * --- frame pointer ---- 85b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch * - fp[-8] direct_call (1 = direct call from JS, 0 = from runtime) kDirectCall 86b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch * - fp[-16] stack_base (Top of backtracking stack). kStackHighEnd 87b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch * - fp[-24] capture array size (may fit multiple sets of matches) kNumOutputRegisters 88b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch * - fp[-32] int* capture_array (int[num_saved_registers_], for output). kRegisterOutput 89b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch * - fp[-40] end of input (address of end of string). kInputEnd 90b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch * - fp[-48] start of input (address of first character in string). kInputStart 91b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch * - fp[-56] start index (character index of start). kStartIndex 92b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch * - fp[-64] void* input_string (location of a handle containing the string). kInputString 93b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch * - fp[-72] success counter (only for global regexps to count matches). kSuccessfulCaptures 94014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch * - fp[-80] Offset of location before start of input (effectively character kStringStartMinusOne 95b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch * position -1). Used to initialize capture registers to a 96b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch * non-position. 97b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch * --------- The following output registers are 32-bit values. --------- 98b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch * - fp[-88] register 0 (Only positions must be stored in the first kRegisterZero 99b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch * - register 1 num_saved_registers_ registers) 100b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch * - ... 101b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch * - register num_registers-1 102b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch * --- sp --- 103b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch * 104b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch * The first num_saved_registers_ registers are initialized to point to 105b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch * "character -1" in the string (i.e., char_size() bytes before the first 106b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch * character of the string). The remaining registers start out as garbage. 107b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch * 108b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch * The data up to the return address must be placed there by the calling 109b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch * code and the remaining arguments are passed in registers, e.g. by calling the 110b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch * code entry as cast to a function with the signature: 111b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch * int (*match)(String* input_string, 112b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch * int start_index, 113b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch * Address start, 114b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch * Address end, 115b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch * Address secondary_return_address, // Only used by native call. 116b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch * int* capture_output_array, 117b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch * byte* stack_area_base, 118b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch * bool direct_call = false, 119b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch * void* return_address, 120b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch * Isolate* isolate); 121b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch * The call is performed by NativeRegExpMacroAssembler::Execute() 122b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch * (in regexp-macro-assembler.cc) via the CALL_GENERATED_REGEXP_CODE macro 123b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch * in mips/simulator-mips.h. 124b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch * When calling as a non-direct call (i.e., from C++ code), the return address 125b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch * area is overwritten with the ra register by the RegExp code. When doing a 126b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch * direct call from generated code, the return address is placed there by 127b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch * the calling code, as in a normal exit frame. 128b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch */ 129b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 130b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch#define __ ACCESS_MASM(masm_) 131b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 132014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben MurdochRegExpMacroAssemblerMIPS::RegExpMacroAssemblerMIPS(Isolate* isolate, Zone* zone, 133014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch Mode mode, 134014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch int registers_to_save) 135014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch : NativeRegExpMacroAssembler(isolate, zone), 136014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch masm_(new MacroAssembler(isolate, NULL, kRegExpCodeSize, 137014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch CodeObjectRequired::kYes)), 138b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch mode_(mode), 139b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch num_registers_(registers_to_save), 140b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch num_saved_registers_(registers_to_save), 141b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch entry_label_(), 142b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch start_label_(), 143b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch success_label_(), 144b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch backtrack_label_(), 145b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch exit_label_(), 146b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch internal_failure_label_() { 147b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch DCHECK_EQ(0, registers_to_save % 2); 148b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch __ jmp(&entry_label_); // We'll write the entry code later. 149b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // If the code gets too big or corrupted, an internal exception will be 150b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // raised, and we will exit right away. 151b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch __ bind(&internal_failure_label_); 152b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch __ li(v0, Operand(FAILURE)); 153b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch __ Ret(); 154b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch __ bind(&start_label_); // And then continue from here. 155b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch} 156b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 157b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 158b8a8cc1952d61a2f3a2568848933943a543b5d3eBen MurdochRegExpMacroAssemblerMIPS::~RegExpMacroAssemblerMIPS() { 159b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch delete masm_; 160b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // Unuse labels in case we throw away the assembler without calling GetCode. 161b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch entry_label_.Unuse(); 162b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch start_label_.Unuse(); 163b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch success_label_.Unuse(); 164b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch backtrack_label_.Unuse(); 165b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch exit_label_.Unuse(); 166b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch check_preempt_label_.Unuse(); 167b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch stack_overflow_label_.Unuse(); 168b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch internal_failure_label_.Unuse(); 169b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch} 170b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 171b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 172b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdochint RegExpMacroAssemblerMIPS::stack_limit_slack() { 173b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch return RegExpStack::kStackLimitSlack; 174b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch} 175b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 176b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 177b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdochvoid RegExpMacroAssemblerMIPS::AdvanceCurrentPosition(int by) { 178b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch if (by != 0) { 179b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch __ Daddu(current_input_offset(), 180b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch current_input_offset(), Operand(by * char_size())); 181b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch } 182b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch} 183b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 184b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 185b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdochvoid RegExpMacroAssemblerMIPS::AdvanceRegister(int reg, int by) { 186b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch DCHECK(reg >= 0); 187b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch DCHECK(reg < num_registers_); 188b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch if (by != 0) { 189b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch __ ld(a0, register_location(reg)); 190b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch __ Daddu(a0, a0, Operand(by)); 191b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch __ sd(a0, register_location(reg)); 192b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch } 193b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch} 194b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 195b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 196b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdochvoid RegExpMacroAssemblerMIPS::Backtrack() { 197b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch CheckPreemption(); 198b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // Pop Code* offset from backtrack stack, add Code* and jump to location. 199b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch Pop(a0); 200b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch __ Daddu(a0, a0, code_pointer()); 201b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch __ Jump(a0); 202b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch} 203b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 204b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 205b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdochvoid RegExpMacroAssemblerMIPS::Bind(Label* label) { 206b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch __ bind(label); 207b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch} 208b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 209b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 210b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdochvoid RegExpMacroAssemblerMIPS::CheckCharacter(uint32_t c, Label* on_equal) { 211b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch BranchOrBacktrack(on_equal, eq, current_character(), Operand(c)); 212b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch} 213b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 214b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 215b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdochvoid RegExpMacroAssemblerMIPS::CheckCharacterGT(uc16 limit, Label* on_greater) { 216b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch BranchOrBacktrack(on_greater, gt, current_character(), Operand(limit)); 217b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch} 218b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 219b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 220b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdochvoid RegExpMacroAssemblerMIPS::CheckAtStart(Label* on_at_start) { 221014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch __ ld(a1, MemOperand(frame_pointer(), kStringStartMinusOne)); 222014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch __ Daddu(a0, current_input_offset(), Operand(-char_size())); 223b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch BranchOrBacktrack(on_at_start, eq, a0, Operand(a1)); 224b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch} 225b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 226b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 227014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdochvoid RegExpMacroAssemblerMIPS::CheckNotAtStart(int cp_offset, 228014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch Label* on_not_at_start) { 229014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch __ ld(a1, MemOperand(frame_pointer(), kStringStartMinusOne)); 230014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch __ Daddu(a0, current_input_offset(), 231014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch Operand(-char_size() + cp_offset * char_size())); 232b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch BranchOrBacktrack(on_not_at_start, ne, a0, Operand(a1)); 233b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch} 234b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 235b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 236b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdochvoid RegExpMacroAssemblerMIPS::CheckCharacterLT(uc16 limit, Label* on_less) { 237b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch BranchOrBacktrack(on_less, lt, current_character(), Operand(limit)); 238b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch} 239b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 240b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 241b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdochvoid RegExpMacroAssemblerMIPS::CheckGreedyLoop(Label* on_equal) { 242b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch Label backtrack_non_equal; 243b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch __ lw(a0, MemOperand(backtrack_stackpointer(), 0)); 244b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch __ Branch(&backtrack_non_equal, ne, current_input_offset(), Operand(a0)); 245b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch __ Daddu(backtrack_stackpointer(), 246b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch backtrack_stackpointer(), 247b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch Operand(kIntSize)); 248b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch __ bind(&backtrack_non_equal); 249b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch BranchOrBacktrack(on_equal, eq, current_input_offset(), Operand(a0)); 250b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch} 251b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 252b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 253b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdochvoid RegExpMacroAssemblerMIPS::CheckNotBackReferenceIgnoreCase( 254109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch int start_reg, bool read_backward, bool unicode, Label* on_no_match) { 255b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch Label fallthrough; 256b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch __ ld(a0, register_location(start_reg)); // Index of start of capture. 257b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch __ ld(a1, register_location(start_reg + 1)); // Index of end of capture. 258b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch __ Dsubu(a1, a1, a0); // Length of capture. 259b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 260014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch // At this point, the capture registers are either both set or both cleared. 261014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch // If the capture length is zero, then the capture is either empty or cleared. 262014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch // Fall through in both cases. 263b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch __ Branch(&fallthrough, eq, a1, Operand(zero_reg)); 264b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 265014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch if (read_backward) { 266014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch __ ld(t1, MemOperand(frame_pointer(), kStringStartMinusOne)); 267014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch __ Daddu(t1, t1, a1); 268014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch BranchOrBacktrack(on_no_match, le, current_input_offset(), Operand(t1)); 269014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch } else { 270014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch __ Daddu(t1, a1, current_input_offset()); 271014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch // Check that there are enough characters left in the input. 272014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch BranchOrBacktrack(on_no_match, gt, t1, Operand(zero_reg)); 273014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch } 274b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 275b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch if (mode_ == LATIN1) { 276b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch Label success; 277b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch Label fail; 278b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch Label loop_check; 279b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 280b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // a0 - offset of start of capture. 281b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // a1 - length of capture. 282b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch __ Daddu(a0, a0, Operand(end_of_input_address())); 283b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch __ Daddu(a2, end_of_input_address(), Operand(current_input_offset())); 284014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch if (read_backward) { 285014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch __ Dsubu(a2, a2, Operand(a1)); 286014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch } 287b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch __ Daddu(a1, a0, Operand(a1)); 288b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 289b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // a0 - Address of start of capture. 290b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // a1 - Address of end of capture. 291b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // a2 - Address of current input position. 292b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 293b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch Label loop; 294b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch __ bind(&loop); 295b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch __ lbu(a3, MemOperand(a0, 0)); 296b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch __ daddiu(a0, a0, char_size()); 297b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch __ lbu(a4, MemOperand(a2, 0)); 298b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch __ daddiu(a2, a2, char_size()); 299b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 300b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch __ Branch(&loop_check, eq, a4, Operand(a3)); 301b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 302b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // Mismatch, try case-insensitive match (converting letters to lower-case). 303b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch __ Or(a3, a3, Operand(0x20)); // Convert capture character to lower-case. 304b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch __ Or(a4, a4, Operand(0x20)); // Also convert input character. 305b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch __ Branch(&fail, ne, a4, Operand(a3)); 306b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch __ Dsubu(a3, a3, Operand('a')); 307b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch __ Branch(&loop_check, ls, a3, Operand('z' - 'a')); 308b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // Latin-1: Check for values in range [224,254] but not 247. 309b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch __ Dsubu(a3, a3, Operand(224 - 'a')); 310b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // Weren't Latin-1 letters. 311b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch __ Branch(&fail, hi, a3, Operand(254 - 224)); 312b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // Check for 247. 313b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch __ Branch(&fail, eq, a3, Operand(247 - 224)); 314b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 315b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch __ bind(&loop_check); 316b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch __ Branch(&loop, lt, a0, Operand(a1)); 317b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch __ jmp(&success); 318b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 319b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch __ bind(&fail); 320b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch GoTo(on_no_match); 321b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 322b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch __ bind(&success); 323b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // Compute new value of character position after the matched part. 324b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch __ Dsubu(current_input_offset(), a2, end_of_input_address()); 325014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch if (read_backward) { 326014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch __ ld(t1, register_location(start_reg)); // Index of start of capture. 327014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch __ ld(a2, register_location(start_reg + 1)); // Index of end of capture. 328014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch __ Daddu(current_input_offset(), current_input_offset(), Operand(t1)); 329014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch __ Dsubu(current_input_offset(), current_input_offset(), Operand(a2)); 330014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch } 331b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch } else { 332b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch DCHECK(mode_ == UC16); 333b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // Put regexp engine registers on stack. 334b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch RegList regexp_registers_to_retain = current_input_offset().bit() | 335b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch current_character().bit() | backtrack_stackpointer().bit(); 336b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch __ MultiPush(regexp_registers_to_retain); 337b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 338b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch int argument_count = 4; 339b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch __ PrepareCallCFunction(argument_count, a2); 340b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 341b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // a0 - offset of start of capture. 342b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // a1 - length of capture. 343b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 344b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // Put arguments into arguments registers. 345b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // Parameters are 346b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // a0: Address byte_offset1 - Address captured substring's start. 347b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // a1: Address byte_offset2 - Address of current character position. 348b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // a2: size_t byte_length - length of capture in bytes(!). 349109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch // a3: Isolate* isolate or 0 if unicode flag. 350b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 351b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // Address of start of capture. 352b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch __ Daddu(a0, a0, Operand(end_of_input_address())); 353b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // Length of capture. 354b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch __ mov(a2, a1); 355b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // Save length in callee-save register for use on return. 356b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch __ mov(s3, a1); 357b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // Address of current input position. 358b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch __ Daddu(a1, current_input_offset(), Operand(end_of_input_address())); 359014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch if (read_backward) { 360014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch __ Dsubu(a1, a1, Operand(s3)); 361014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch } 362b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // Isolate. 363109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch#ifdef V8_I18N_SUPPORT 364109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch if (unicode) { 365109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch __ mov(a3, zero_reg); 366109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch } else // NOLINT 367109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch#endif // V8_I18N_SUPPORT 368109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch { 369109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch __ li(a3, Operand(ExternalReference::isolate_address(masm_->isolate()))); 370109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch } 371b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 372b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch { 373b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch AllowExternalCallThatCantCauseGC scope(masm_); 374b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch ExternalReference function = 375b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch ExternalReference::re_case_insensitive_compare_uc16(masm_->isolate()); 376b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch __ CallCFunction(function, argument_count); 377b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch } 378b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 379b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // Restore regexp engine registers. 380b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch __ MultiPop(regexp_registers_to_retain); 381b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch __ li(code_pointer(), Operand(masm_->CodeObject()), CONSTANT_SIZE); 382b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch __ ld(end_of_input_address(), MemOperand(frame_pointer(), kInputEnd)); 383b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 384b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // Check if function returned non-zero for success or zero for failure. 385b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch BranchOrBacktrack(on_no_match, eq, v0, Operand(zero_reg)); 386b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // On success, increment position by length of capture. 387014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch if (read_backward) { 388014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch __ Dsubu(current_input_offset(), current_input_offset(), Operand(s3)); 389014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch } else { 390014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch __ Daddu(current_input_offset(), current_input_offset(), Operand(s3)); 391014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch } 392b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch } 393b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 394b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch __ bind(&fallthrough); 395b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch} 396b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 397b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 398014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdochvoid RegExpMacroAssemblerMIPS::CheckNotBackReference(int start_reg, 399014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch bool read_backward, 400014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch Label* on_no_match) { 401b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch Label fallthrough; 402b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch Label success; 403b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 404b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // Find length of back-referenced capture. 405b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch __ ld(a0, register_location(start_reg)); 406b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch __ ld(a1, register_location(start_reg + 1)); 407b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch __ Dsubu(a1, a1, a0); // Length to check. 408014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch 409014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch // At this point, the capture registers are either both set or both cleared. 410014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch // If the capture length is zero, then the capture is either empty or cleared. 411014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch // Fall through in both cases. 412b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch __ Branch(&fallthrough, eq, a1, Operand(zero_reg)); 413b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 414014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch if (read_backward) { 415014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch __ ld(t1, MemOperand(frame_pointer(), kStringStartMinusOne)); 416014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch __ Daddu(t1, t1, a1); 417014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch BranchOrBacktrack(on_no_match, le, current_input_offset(), Operand(t1)); 418014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch } else { 419014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch __ Daddu(t1, a1, current_input_offset()); 420014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch // Check that there are enough characters left in the input. 421014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch BranchOrBacktrack(on_no_match, gt, t1, Operand(zero_reg)); 422014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch } 423b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 424b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // Compute pointers to match string and capture string. 425b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch __ Daddu(a0, a0, Operand(end_of_input_address())); 426b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch __ Daddu(a2, end_of_input_address(), Operand(current_input_offset())); 427014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch if (read_backward) { 428014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch __ Dsubu(a2, a2, Operand(a1)); 429014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch } 430b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch __ Daddu(a1, a1, Operand(a0)); 431b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 432b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch Label loop; 433b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch __ bind(&loop); 434b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch if (mode_ == LATIN1) { 435b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch __ lbu(a3, MemOperand(a0, 0)); 436b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch __ daddiu(a0, a0, char_size()); 437b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch __ lbu(a4, MemOperand(a2, 0)); 438b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch __ daddiu(a2, a2, char_size()); 439b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch } else { 440b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch DCHECK(mode_ == UC16); 441b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch __ lhu(a3, MemOperand(a0, 0)); 442b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch __ daddiu(a0, a0, char_size()); 443b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch __ lhu(a4, MemOperand(a2, 0)); 444b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch __ daddiu(a2, a2, char_size()); 445b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch } 446b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch BranchOrBacktrack(on_no_match, ne, a3, Operand(a4)); 447b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch __ Branch(&loop, lt, a0, Operand(a1)); 448b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 449b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // Move current character position to position after match. 450b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch __ Dsubu(current_input_offset(), a2, end_of_input_address()); 451014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch if (read_backward) { 452014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch __ ld(t1, register_location(start_reg)); // Index of start of capture. 453014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch __ ld(a2, register_location(start_reg + 1)); // Index of end of capture. 454014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch __ Daddu(current_input_offset(), current_input_offset(), Operand(t1)); 455014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch __ Dsubu(current_input_offset(), current_input_offset(), Operand(a2)); 456014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch } 457b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch __ bind(&fallthrough); 458b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch} 459b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 460b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 461b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdochvoid RegExpMacroAssemblerMIPS::CheckNotCharacter(uint32_t c, 462b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch Label* on_not_equal) { 463b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch BranchOrBacktrack(on_not_equal, ne, current_character(), Operand(c)); 464b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch} 465b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 466b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 467b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdochvoid RegExpMacroAssemblerMIPS::CheckCharacterAfterAnd(uint32_t c, 468b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch uint32_t mask, 469b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch Label* on_equal) { 470b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch __ And(a0, current_character(), Operand(mask)); 471b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch Operand rhs = (c == 0) ? Operand(zero_reg) : Operand(c); 472b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch BranchOrBacktrack(on_equal, eq, a0, rhs); 473b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch} 474b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 475b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 476b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdochvoid RegExpMacroAssemblerMIPS::CheckNotCharacterAfterAnd(uint32_t c, 477b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch uint32_t mask, 478b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch Label* on_not_equal) { 479b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch __ And(a0, current_character(), Operand(mask)); 480b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch Operand rhs = (c == 0) ? Operand(zero_reg) : Operand(c); 481b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch BranchOrBacktrack(on_not_equal, ne, a0, rhs); 482b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch} 483b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 484b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 485b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdochvoid RegExpMacroAssemblerMIPS::CheckNotCharacterAfterMinusAnd( 486b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch uc16 c, 487b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch uc16 minus, 488b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch uc16 mask, 489b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch Label* on_not_equal) { 490b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch DCHECK(minus < String::kMaxUtf16CodeUnit); 491b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch __ Dsubu(a0, current_character(), Operand(minus)); 492b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch __ And(a0, a0, Operand(mask)); 493b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch BranchOrBacktrack(on_not_equal, ne, a0, Operand(c)); 494b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch} 495b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 496b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 497b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdochvoid RegExpMacroAssemblerMIPS::CheckCharacterInRange( 498b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch uc16 from, 499b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch uc16 to, 500b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch Label* on_in_range) { 501b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch __ Dsubu(a0, current_character(), Operand(from)); 502b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // Unsigned lower-or-same condition. 503b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch BranchOrBacktrack(on_in_range, ls, a0, Operand(to - from)); 504b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch} 505b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 506b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 507b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdochvoid RegExpMacroAssemblerMIPS::CheckCharacterNotInRange( 508b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch uc16 from, 509b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch uc16 to, 510b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch Label* on_not_in_range) { 511b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch __ Dsubu(a0, current_character(), Operand(from)); 512b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // Unsigned higher condition. 513b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch BranchOrBacktrack(on_not_in_range, hi, a0, Operand(to - from)); 514b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch} 515b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 516b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 517b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdochvoid RegExpMacroAssemblerMIPS::CheckBitInTable( 518b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch Handle<ByteArray> table, 519b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch Label* on_bit_set) { 520b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch __ li(a0, Operand(table)); 521b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch if (mode_ != LATIN1 || kTableMask != String::kMaxOneByteCharCode) { 522b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch __ And(a1, current_character(), Operand(kTableSize - 1)); 523b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch __ Daddu(a0, a0, a1); 524b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch } else { 525b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch __ Daddu(a0, a0, current_character()); 526b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch } 527b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 528b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch __ lbu(a0, FieldMemOperand(a0, ByteArray::kHeaderSize)); 529b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch BranchOrBacktrack(on_bit_set, ne, a0, Operand(zero_reg)); 530b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch} 531b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 532b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 533b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdochbool RegExpMacroAssemblerMIPS::CheckSpecialCharacterClass(uc16 type, 534b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch Label* on_no_match) { 535b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // Range checks (c in min..max) are generally implemented by an unsigned 536b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // (c - min) <= (max - min) check. 537b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch switch (type) { 538b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch case 's': 539b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // Match space-characters. 540b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch if (mode_ == LATIN1) { 541b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // One byte space characters are '\t'..'\r', ' ' and \u00a0. 542b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch Label success; 543b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch __ Branch(&success, eq, current_character(), Operand(' ')); 544b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // Check range 0x09..0x0d. 545b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch __ Dsubu(a0, current_character(), Operand('\t')); 546b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch __ Branch(&success, ls, a0, Operand('\r' - '\t')); 547b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // \u00a0 (NBSP). 548b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch BranchOrBacktrack(on_no_match, ne, a0, Operand(0x00a0 - '\t')); 549b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch __ bind(&success); 550b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch return true; 551b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch } 552b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch return false; 553b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch case 'S': 554b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // The emitted code for generic character classes is good enough. 555b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch return false; 556b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch case 'd': 557b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // Match Latin1 digits ('0'..'9'). 558b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch __ Dsubu(a0, current_character(), Operand('0')); 559b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch BranchOrBacktrack(on_no_match, hi, a0, Operand('9' - '0')); 560b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch return true; 561b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch case 'D': 562b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // Match non Latin1-digits. 563b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch __ Dsubu(a0, current_character(), Operand('0')); 564b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch BranchOrBacktrack(on_no_match, ls, a0, Operand('9' - '0')); 565b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch return true; 566b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch case '.': { 567b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // Match non-newlines (not 0x0a('\n'), 0x0d('\r'), 0x2028 and 0x2029). 568b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch __ Xor(a0, current_character(), Operand(0x01)); 569b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // See if current character is '\n'^1 or '\r'^1, i.e., 0x0b or 0x0c. 570b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch __ Dsubu(a0, a0, Operand(0x0b)); 571b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch BranchOrBacktrack(on_no_match, ls, a0, Operand(0x0c - 0x0b)); 572b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch if (mode_ == UC16) { 573b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // Compare original value to 0x2028 and 0x2029, using the already 574b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // computed (current_char ^ 0x01 - 0x0b). I.e., check for 575b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // 0x201d (0x2028 - 0x0b) or 0x201e. 576b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch __ Dsubu(a0, a0, Operand(0x2028 - 0x0b)); 577b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch BranchOrBacktrack(on_no_match, ls, a0, Operand(1)); 578b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch } 579b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch return true; 580b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch } 581b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch case 'n': { 582b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // Match newlines (0x0a('\n'), 0x0d('\r'), 0x2028 and 0x2029). 583b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch __ Xor(a0, current_character(), Operand(0x01)); 584b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // See if current character is '\n'^1 or '\r'^1, i.e., 0x0b or 0x0c. 585b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch __ Dsubu(a0, a0, Operand(0x0b)); 586b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch if (mode_ == LATIN1) { 587b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch BranchOrBacktrack(on_no_match, hi, a0, Operand(0x0c - 0x0b)); 588b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch } else { 589b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch Label done; 590b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch BranchOrBacktrack(&done, ls, a0, Operand(0x0c - 0x0b)); 591b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // Compare original value to 0x2028 and 0x2029, using the already 592b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // computed (current_char ^ 0x01 - 0x0b). I.e., check for 593b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // 0x201d (0x2028 - 0x0b) or 0x201e. 594b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch __ Dsubu(a0, a0, Operand(0x2028 - 0x0b)); 595b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch BranchOrBacktrack(on_no_match, hi, a0, Operand(1)); 596b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch __ bind(&done); 597b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch } 598b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch return true; 599b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch } 600b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch case 'w': { 601b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch if (mode_ != LATIN1) { 602b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // Table is 256 entries, so all Latin1 characters can be tested. 603b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch BranchOrBacktrack(on_no_match, hi, current_character(), Operand('z')); 604b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch } 605b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch ExternalReference map = ExternalReference::re_word_character_map(); 606b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch __ li(a0, Operand(map)); 607b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch __ Daddu(a0, a0, current_character()); 608b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch __ lbu(a0, MemOperand(a0, 0)); 609b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch BranchOrBacktrack(on_no_match, eq, a0, Operand(zero_reg)); 610b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch return true; 611b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch } 612b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch case 'W': { 613b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch Label done; 614b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch if (mode_ != LATIN1) { 615b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // Table is 256 entries, so all Latin1 characters can be tested. 616b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch __ Branch(&done, hi, current_character(), Operand('z')); 617b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch } 618b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch ExternalReference map = ExternalReference::re_word_character_map(); 619b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch __ li(a0, Operand(map)); 620b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch __ Daddu(a0, a0, current_character()); 621b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch __ lbu(a0, MemOperand(a0, 0)); 622b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch BranchOrBacktrack(on_no_match, ne, a0, Operand(zero_reg)); 623b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch if (mode_ != LATIN1) { 624b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch __ bind(&done); 625b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch } 626b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch return true; 627b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch } 628b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch case '*': 629b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // Match any character. 630b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch return true; 631b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // No custom implementation (yet): s(UC16), S(UC16). 632b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch default: 633b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch return false; 634b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch } 635b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch} 636b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 637b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 638b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdochvoid RegExpMacroAssemblerMIPS::Fail() { 639b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch __ li(v0, Operand(FAILURE)); 640b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch __ jmp(&exit_label_); 641b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch} 642b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 643b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 644b8a8cc1952d61a2f3a2568848933943a543b5d3eBen MurdochHandle<HeapObject> RegExpMacroAssemblerMIPS::GetCode(Handle<String> source) { 645b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch Label return_v0; 646b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch if (masm_->has_exception()) { 647b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // If the code gets corrupted due to long regular expressions and lack of 648b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // space on trampolines, an internal exception flag is set. If this case 649b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // is detected, we will jump into exit sequence right away. 650b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch __ bind_to(&entry_label_, internal_failure_label_.pos()); 651b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch } else { 652b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // Finalize code - write the entry point code now we know how many 653b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // registers we need. 654b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 655b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // Entry code: 656b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch __ bind(&entry_label_); 657b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 658b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // Tell the system that we have a stack frame. Because the type is MANUAL, 659b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // no is generated. 660b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch FrameScope scope(masm_, StackFrame::MANUAL); 661b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 662b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // Actually emit code to start a new stack frame. 663b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // Push arguments 664b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // Save callee-save registers. 665b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // Start new stack frame. 666b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // Store link register in existing stack-cell. 667b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // Order here should correspond to order of offset constants in header file. 668b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // TODO(plind): we save s0..s7, but ONLY use s3 here - use the regs 669b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // or dont save. 670b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch RegList registers_to_retain = s0.bit() | s1.bit() | s2.bit() | 671b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch s3.bit() | s4.bit() | s5.bit() | s6.bit() | s7.bit() | fp.bit(); 672b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch RegList argument_registers = a0.bit() | a1.bit() | a2.bit() | a3.bit(); 673b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 674109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch argument_registers |= a4.bit() | a5.bit() | a6.bit() | a7.bit(); 675b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 676b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch __ MultiPush(argument_registers | registers_to_retain | ra.bit()); 677b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // Set frame pointer in space for it if this is not a direct call 678b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // from generated code. 679b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // TODO(plind): this 8 is the # of argument regs, should have definition. 680b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch __ Daddu(frame_pointer(), sp, Operand(8 * kPointerSize)); 681b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch __ mov(a0, zero_reg); 682b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch __ push(a0); // Make room for success counter and initialize it to 0. 683014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch __ push(a0); // Make room for "string start - 1" constant. 684b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 685b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // Check if we have space on the stack for registers. 686b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch Label stack_limit_hit; 687b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch Label stack_ok; 688b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 689b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch ExternalReference stack_limit = 690b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch ExternalReference::address_of_stack_limit(masm_->isolate()); 691b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch __ li(a0, Operand(stack_limit)); 692b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch __ ld(a0, MemOperand(a0)); 693b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch __ Dsubu(a0, sp, a0); 694b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // Handle it if the stack pointer is already below the stack limit. 695b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch __ Branch(&stack_limit_hit, le, a0, Operand(zero_reg)); 696b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // Check if there is room for the variable number of registers above 697b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // the stack limit. 698b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch __ Branch(&stack_ok, hs, a0, Operand(num_registers_ * kPointerSize)); 699b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // Exit with OutOfMemory exception. There is not enough space on the stack 700b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // for our working registers. 701b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch __ li(v0, Operand(EXCEPTION)); 702b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch __ jmp(&return_v0); 703b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 704b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch __ bind(&stack_limit_hit); 705b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch CallCheckStackGuardState(a0); 706b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // If returned value is non-zero, we exit with the returned value as result. 707b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch __ Branch(&return_v0, ne, v0, Operand(zero_reg)); 708b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 709b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch __ bind(&stack_ok); 710b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // Allocate space on stack for registers. 711b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch __ Dsubu(sp, sp, Operand(num_registers_ * kPointerSize)); 712b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // Load string end. 713b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch __ ld(end_of_input_address(), MemOperand(frame_pointer(), kInputEnd)); 714b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // Load input start. 715b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch __ ld(a0, MemOperand(frame_pointer(), kInputStart)); 716b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // Find negative length (offset of start relative to end). 717b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch __ Dsubu(current_input_offset(), a0, end_of_input_address()); 718b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // Set a0 to address of char before start of the input string 719b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // (effectively string position -1). 720b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch __ ld(a1, MemOperand(frame_pointer(), kStartIndex)); 721b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch __ Dsubu(a0, current_input_offset(), Operand(char_size())); 722b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch __ dsll(t1, a1, (mode_ == UC16) ? 1 : 0); 723b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch __ Dsubu(a0, a0, t1); 724b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // Store this value in a local variable, for use when clearing 725b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // position registers. 726014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch __ sd(a0, MemOperand(frame_pointer(), kStringStartMinusOne)); 727b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 728b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // Initialize code pointer register 729b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch __ li(code_pointer(), Operand(masm_->CodeObject()), CONSTANT_SIZE); 730b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 731b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch Label load_char_start_regexp, start_regexp; 732b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // Load newline if index is at start, previous character otherwise. 733b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch __ Branch(&load_char_start_regexp, ne, a1, Operand(zero_reg)); 734b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch __ li(current_character(), Operand('\n')); 735b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch __ jmp(&start_regexp); 736b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 737b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // Global regexp restarts matching here. 738b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch __ bind(&load_char_start_regexp); 739b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // Load previous char as initial value of current character register. 740b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch LoadCurrentCharacterUnchecked(-1, 1); 741b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch __ bind(&start_regexp); 742b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 743b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // Initialize on-stack registers. 744b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch if (num_saved_registers_ > 0) { // Always is, if generated from a regexp. 745b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // Fill saved registers with initial value = start offset - 1. 746b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch if (num_saved_registers_ > 8) { 747b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // Address of register 0. 748b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch __ Daddu(a1, frame_pointer(), Operand(kRegisterZero)); 749b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch __ li(a2, Operand(num_saved_registers_)); 750b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch Label init_loop; 751b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch __ bind(&init_loop); 752b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch __ sd(a0, MemOperand(a1)); 753b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch __ Daddu(a1, a1, Operand(-kPointerSize)); 754b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch __ Dsubu(a2, a2, Operand(1)); 755b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch __ Branch(&init_loop, ne, a2, Operand(zero_reg)); 756b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch } else { 757b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch for (int i = 0; i < num_saved_registers_; i++) { 758b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch __ sd(a0, register_location(i)); 759b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch } 760b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch } 761b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch } 762b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 763b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // Initialize backtrack stack pointer. 764b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch __ ld(backtrack_stackpointer(), MemOperand(frame_pointer(), kStackHighEnd)); 765b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 766b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch __ jmp(&start_label_); 767b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 768b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 769b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // Exit code: 770b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch if (success_label_.is_linked()) { 771b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // Save captures when successful. 772b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch __ bind(&success_label_); 773b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch if (num_saved_registers_ > 0) { 774b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // Copy captures to output. 775b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch __ ld(a1, MemOperand(frame_pointer(), kInputStart)); 776b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch __ ld(a0, MemOperand(frame_pointer(), kRegisterOutput)); 777b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch __ ld(a2, MemOperand(frame_pointer(), kStartIndex)); 778b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch __ Dsubu(a1, end_of_input_address(), a1); 779b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // a1 is length of input in bytes. 780b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch if (mode_ == UC16) { 781b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch __ dsrl(a1, a1, 1); 782b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch } 783b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // a1 is length of input in characters. 784b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch __ Daddu(a1, a1, Operand(a2)); 785b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // a1 is length of string in characters. 786b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 787b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch DCHECK_EQ(0, num_saved_registers_ % 2); 788b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // Always an even number of capture registers. This allows us to 789b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // unroll the loop once to add an operation between a load of a register 790b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // and the following use of that register. 791b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch for (int i = 0; i < num_saved_registers_; i += 2) { 792b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch __ ld(a2, register_location(i)); 793b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch __ ld(a3, register_location(i + 1)); 794b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch if (i == 0 && global_with_zero_length_check()) { 795b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // Keep capture start in a4 for the zero-length check later. 796b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch __ mov(t3, a2); 797b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch } 798b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch if (mode_ == UC16) { 799b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch __ dsra(a2, a2, 1); 800b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch __ Daddu(a2, a2, a1); 801b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch __ dsra(a3, a3, 1); 802b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch __ Daddu(a3, a3, a1); 803b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch } else { 804b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch __ Daddu(a2, a1, Operand(a2)); 805b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch __ Daddu(a3, a1, Operand(a3)); 806b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch } 807b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // V8 expects the output to be an int32_t array. 808b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch __ sw(a2, MemOperand(a0)); 809b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch __ Daddu(a0, a0, kIntSize); 810b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch __ sw(a3, MemOperand(a0)); 811b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch __ Daddu(a0, a0, kIntSize); 812b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch } 813b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch } 814b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 815b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch if (global()) { 816b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // Restart matching if the regular expression is flagged as global. 817b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch __ ld(a0, MemOperand(frame_pointer(), kSuccessfulCaptures)); 818014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch __ ld(a1, MemOperand(frame_pointer(), kNumOutputRegisters)); 819b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch __ ld(a2, MemOperand(frame_pointer(), kRegisterOutput)); 820b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // Increment success counter. 821b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch __ Daddu(a0, a0, 1); 822b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch __ sd(a0, MemOperand(frame_pointer(), kSuccessfulCaptures)); 823b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // Capture results have been stored, so the number of remaining global 824b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // output registers is reduced by the number of stored captures. 825b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch __ Dsubu(a1, a1, num_saved_registers_); 826b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // Check whether we have enough room for another set of capture results. 827b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch __ mov(v0, a0); 828b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch __ Branch(&return_v0, lt, a1, Operand(num_saved_registers_)); 829b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 830b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch __ sd(a1, MemOperand(frame_pointer(), kNumOutputRegisters)); 831b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // Advance the location for output. 832b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch __ Daddu(a2, a2, num_saved_registers_ * kIntSize); 833b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch __ sd(a2, MemOperand(frame_pointer(), kRegisterOutput)); 834b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 835b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // Prepare a0 to initialize registers with its value in the next run. 836014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch __ ld(a0, MemOperand(frame_pointer(), kStringStartMinusOne)); 837b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 838b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch if (global_with_zero_length_check()) { 839b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // Special case for zero-length matches. 840b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // t3: capture start index 841b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // Not a zero-length match, restart. 842b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch __ Branch( 843b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch &load_char_start_regexp, ne, current_input_offset(), Operand(t3)); 844b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // Offset from the end is zero if we already reached the end. 845b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch __ Branch(&exit_label_, eq, current_input_offset(), 846b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch Operand(zero_reg)); 847b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // Advance current position after a zero-length match. 848109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch Label advance; 849109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch __ bind(&advance); 850b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch __ Daddu(current_input_offset(), 851b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch current_input_offset(), 852b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch Operand((mode_ == UC16) ? 2 : 1)); 853109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch if (global_unicode()) CheckNotInSurrogatePair(0, &advance); 854b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch } 855b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 856b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch __ Branch(&load_char_start_regexp); 857b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch } else { 858b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch __ li(v0, Operand(SUCCESS)); 859b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch } 860b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch } 861b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // Exit and return v0. 862b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch __ bind(&exit_label_); 863b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch if (global()) { 864b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch __ ld(v0, MemOperand(frame_pointer(), kSuccessfulCaptures)); 865b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch } 866b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 867b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch __ bind(&return_v0); 868b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // Skip sp past regexp registers and local variables.. 869b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch __ mov(sp, frame_pointer()); 870b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // Restore registers s0..s7 and return (restoring ra to pc). 871b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch __ MultiPop(registers_to_retain | ra.bit()); 872b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch __ Ret(); 873b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 874b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // Backtrack code (branch target for conditional backtracks). 875b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch if (backtrack_label_.is_linked()) { 876b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch __ bind(&backtrack_label_); 877b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch Backtrack(); 878b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch } 879b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 880b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch Label exit_with_exception; 881b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 882b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // Preempt-code. 883b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch if (check_preempt_label_.is_linked()) { 884b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch SafeCallTarget(&check_preempt_label_); 885b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // Put regexp engine registers on stack. 886b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch RegList regexp_registers_to_retain = current_input_offset().bit() | 887b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch current_character().bit() | backtrack_stackpointer().bit(); 888b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch __ MultiPush(regexp_registers_to_retain); 889b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch CallCheckStackGuardState(a0); 890b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch __ MultiPop(regexp_registers_to_retain); 891b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // If returning non-zero, we should end execution with the given 892b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // result as return value. 893b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch __ Branch(&return_v0, ne, v0, Operand(zero_reg)); 894b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 895b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // String might have moved: Reload end of string from frame. 896b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch __ ld(end_of_input_address(), MemOperand(frame_pointer(), kInputEnd)); 897b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch __ li(code_pointer(), Operand(masm_->CodeObject()), CONSTANT_SIZE); 898b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch SafeReturn(); 899b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch } 900b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 901b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // Backtrack stack overflow code. 902b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch if (stack_overflow_label_.is_linked()) { 903b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch SafeCallTarget(&stack_overflow_label_); 904b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // Reached if the backtrack-stack limit has been hit. 905b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // Put regexp engine registers on stack first. 906b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch RegList regexp_registers = current_input_offset().bit() | 907b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch current_character().bit(); 908b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch __ MultiPush(regexp_registers); 909b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch Label grow_failed; 910b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // Call GrowStack(backtrack_stackpointer(), &stack_base) 911b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch static const int num_arguments = 3; 912b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch __ PrepareCallCFunction(num_arguments, a0); 913b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch __ mov(a0, backtrack_stackpointer()); 914b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch __ Daddu(a1, frame_pointer(), Operand(kStackHighEnd)); 915b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch __ li(a2, Operand(ExternalReference::isolate_address(masm_->isolate()))); 916b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch ExternalReference grow_stack = 917b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch ExternalReference::re_grow_stack(masm_->isolate()); 918b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch __ CallCFunction(grow_stack, num_arguments); 919b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // Restore regexp registers. 920b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch __ MultiPop(regexp_registers); 921b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // If return NULL, we have failed to grow the stack, and 922b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // must exit with a stack-overflow exception. 923b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch __ Branch(&exit_with_exception, eq, v0, Operand(zero_reg)); 924b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // Otherwise use return value as new stack pointer. 925b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch __ mov(backtrack_stackpointer(), v0); 926b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // Restore saved registers and continue. 927b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch __ li(code_pointer(), Operand(masm_->CodeObject()), CONSTANT_SIZE); 928b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch __ ld(end_of_input_address(), MemOperand(frame_pointer(), kInputEnd)); 929b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch SafeReturn(); 930b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch } 931b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 932b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch if (exit_with_exception.is_linked()) { 933b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // If any of the code above needed to exit with an exception. 934b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch __ bind(&exit_with_exception); 935b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // Exit with Result EXCEPTION(-1) to signal thrown exception. 936b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch __ li(v0, Operand(EXCEPTION)); 937b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch __ jmp(&return_v0); 938b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch } 939b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch } 940b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 941b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch CodeDesc code_desc; 942b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch masm_->GetCode(&code_desc); 943b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch Handle<Code> code = isolate()->factory()->NewCode( 944b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch code_desc, Code::ComputeFlags(Code::REGEXP), masm_->CodeObject()); 9453b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch LOG(masm_->isolate(), 9463b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch RegExpCodeCreateEvent(AbstractCode::cast(*code), *source)); 947b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch return Handle<HeapObject>::cast(code); 948b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch} 949b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 950b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 951b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdochvoid RegExpMacroAssemblerMIPS::GoTo(Label* to) { 952b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch if (to == NULL) { 953b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch Backtrack(); 954b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch return; 955b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch } 956b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch __ jmp(to); 957b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch return; 958b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch} 959b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 960b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 961b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdochvoid RegExpMacroAssemblerMIPS::IfRegisterGE(int reg, 962b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch int comparand, 963b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch Label* if_ge) { 964b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch __ ld(a0, register_location(reg)); 965b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch BranchOrBacktrack(if_ge, ge, a0, Operand(comparand)); 966b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch} 967b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 968b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 969b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdochvoid RegExpMacroAssemblerMIPS::IfRegisterLT(int reg, 970b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch int comparand, 971b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch Label* if_lt) { 972b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch __ ld(a0, register_location(reg)); 973b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch BranchOrBacktrack(if_lt, lt, a0, Operand(comparand)); 974b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch} 975b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 976b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 977b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdochvoid RegExpMacroAssemblerMIPS::IfRegisterEqPos(int reg, 978b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch Label* if_eq) { 979b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch __ ld(a0, register_location(reg)); 980b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch BranchOrBacktrack(if_eq, eq, a0, Operand(current_input_offset())); 981b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch} 982b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 983b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 984b8a8cc1952d61a2f3a2568848933943a543b5d3eBen MurdochRegExpMacroAssembler::IrregexpImplementation 985b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch RegExpMacroAssemblerMIPS::Implementation() { 986b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch return kMIPSImplementation; 987b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch} 988b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 989b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 990b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdochvoid RegExpMacroAssemblerMIPS::LoadCurrentCharacter(int cp_offset, 991b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch Label* on_end_of_input, 992b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch bool check_bounds, 993b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch int characters) { 994b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch DCHECK(cp_offset < (1<<30)); // Be sane! (And ensure negation works). 995b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch if (check_bounds) { 996014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch if (cp_offset >= 0) { 997014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch CheckPosition(cp_offset + characters - 1, on_end_of_input); 998014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch } else { 999014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch CheckPosition(cp_offset, on_end_of_input); 1000014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch } 1001b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch } 1002b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch LoadCurrentCharacterUnchecked(cp_offset, characters); 1003b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch} 1004b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 1005b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 1006b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdochvoid RegExpMacroAssemblerMIPS::PopCurrentPosition() { 1007b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch Pop(current_input_offset()); 1008b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch} 1009b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 1010b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 1011b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdochvoid RegExpMacroAssemblerMIPS::PopRegister(int register_index) { 1012b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch Pop(a0); 1013b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch __ sd(a0, register_location(register_index)); 1014b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch} 1015b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 1016b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 1017b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdochvoid RegExpMacroAssemblerMIPS::PushBacktrack(Label* label) { 1018b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch if (label->is_bound()) { 1019b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch int target = label->pos(); 1020b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch __ li(a0, Operand(target + Code::kHeaderSize - kHeapObjectTag)); 1021b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch } else { 1022b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch Assembler::BlockTrampolinePoolScope block_trampoline_pool(masm_); 1023b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch Label after_constant; 1024b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch __ Branch(&after_constant); 1025b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch int offset = masm_->pc_offset(); 1026b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch int cp_offset = offset + Code::kHeaderSize - kHeapObjectTag; 1027b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch __ emit(0); 1028b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch masm_->label_at_put(label, offset); 1029b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch __ bind(&after_constant); 1030b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch if (is_int16(cp_offset)) { 1031b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch __ lwu(a0, MemOperand(code_pointer(), cp_offset)); 1032b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch } else { 1033b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch __ Daddu(a0, code_pointer(), cp_offset); 1034b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch __ lwu(a0, MemOperand(a0, 0)); 1035b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch } 1036b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch } 1037b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch Push(a0); 1038b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch CheckStackLimit(); 1039b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch} 1040b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 1041b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 1042b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdochvoid RegExpMacroAssemblerMIPS::PushCurrentPosition() { 1043b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch Push(current_input_offset()); 1044b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch} 1045b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 1046b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 1047b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdochvoid RegExpMacroAssemblerMIPS::PushRegister(int register_index, 1048b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch StackCheckFlag check_stack_limit) { 1049b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch __ ld(a0, register_location(register_index)); 1050b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch Push(a0); 1051b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch if (check_stack_limit) CheckStackLimit(); 1052b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch} 1053b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 1054b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 1055b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdochvoid RegExpMacroAssemblerMIPS::ReadCurrentPositionFromRegister(int reg) { 1056b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch __ ld(current_input_offset(), register_location(reg)); 1057b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch} 1058b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 1059b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 1060b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdochvoid RegExpMacroAssemblerMIPS::ReadStackPointerFromRegister(int reg) { 1061b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch __ ld(backtrack_stackpointer(), register_location(reg)); 1062b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch __ ld(a0, MemOperand(frame_pointer(), kStackHighEnd)); 1063b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch __ Daddu(backtrack_stackpointer(), backtrack_stackpointer(), Operand(a0)); 1064b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch} 1065b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 1066b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 1067b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdochvoid RegExpMacroAssemblerMIPS::SetCurrentPositionFromEnd(int by) { 1068b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch Label after_position; 1069b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch __ Branch(&after_position, 1070b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch ge, 1071b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch current_input_offset(), 1072b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch Operand(-by * char_size())); 1073b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch __ li(current_input_offset(), -by * char_size()); 1074b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // On RegExp code entry (where this operation is used), the character before 1075b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // the current position is expected to be already loaded. 1076b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // We have advanced the position, so it's safe to read backwards. 1077b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch LoadCurrentCharacterUnchecked(-1, 1); 1078b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch __ bind(&after_position); 1079b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch} 1080b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 1081b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 1082b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdochvoid RegExpMacroAssemblerMIPS::SetRegister(int register_index, int to) { 1083b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch DCHECK(register_index >= num_saved_registers_); // Reserved for positions! 1084b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch __ li(a0, Operand(to)); 1085b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch __ sd(a0, register_location(register_index)); 1086b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch} 1087b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 1088b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 1089b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdochbool RegExpMacroAssemblerMIPS::Succeed() { 1090b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch __ jmp(&success_label_); 1091b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch return global(); 1092b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch} 1093b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 1094b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 1095b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdochvoid RegExpMacroAssemblerMIPS::WriteCurrentPositionToRegister(int reg, 1096b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch int cp_offset) { 1097b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch if (cp_offset == 0) { 1098b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch __ sd(current_input_offset(), register_location(reg)); 1099b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch } else { 1100b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch __ Daddu(a0, current_input_offset(), Operand(cp_offset * char_size())); 1101b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch __ sd(a0, register_location(reg)); 1102b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch } 1103b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch} 1104b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 1105b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 1106b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdochvoid RegExpMacroAssemblerMIPS::ClearRegisters(int reg_from, int reg_to) { 1107b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch DCHECK(reg_from <= reg_to); 1108014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch __ ld(a0, MemOperand(frame_pointer(), kStringStartMinusOne)); 1109b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch for (int reg = reg_from; reg <= reg_to; reg++) { 1110b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch __ sd(a0, register_location(reg)); 1111b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch } 1112b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch} 1113b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 1114b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 1115b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdochvoid RegExpMacroAssemblerMIPS::WriteStackPointerToRegister(int reg) { 1116b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch __ ld(a1, MemOperand(frame_pointer(), kStackHighEnd)); 1117b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch __ Dsubu(a0, backtrack_stackpointer(), a1); 1118b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch __ sd(a0, register_location(reg)); 1119b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch} 1120b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 1121b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 1122b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdochbool RegExpMacroAssemblerMIPS::CanReadUnaligned() { 1123b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch return false; 1124b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch} 1125b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 1126b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 1127b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch// Private methods: 1128b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 1129b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdochvoid RegExpMacroAssemblerMIPS::CallCheckStackGuardState(Register scratch) { 1130b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch int stack_alignment = base::OS::ActivationFrameAlignment(); 1131b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 1132b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // Align the stack pointer and save the original sp value on the stack. 1133b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch __ mov(scratch, sp); 1134b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch __ Dsubu(sp, sp, Operand(kPointerSize)); 1135b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch DCHECK(base::bits::IsPowerOfTwo32(stack_alignment)); 1136b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch __ And(sp, sp, Operand(-stack_alignment)); 1137b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch __ sd(scratch, MemOperand(sp)); 1138b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 1139b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch __ mov(a2, frame_pointer()); 1140b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // Code* of self. 1141b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch __ li(a1, Operand(masm_->CodeObject()), CONSTANT_SIZE); 1142b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 1143b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // We need to make room for the return address on the stack. 1144b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch DCHECK(IsAligned(stack_alignment, kPointerSize)); 1145b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch __ Dsubu(sp, sp, Operand(stack_alignment)); 1146b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 1147b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // Stack pointer now points to cell where return address is to be written. 1148b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // Arguments are in registers, meaning we teat the return address as 1149b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // argument 5. Since DirectCEntryStub will handleallocating space for the C 1150b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // argument slots, we don't need to care about that here. This is how the 1151b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // stack will look (sp meaning the value of sp at this moment): 1152b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // [sp + 3] - empty slot if needed for alignment. 1153b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // [sp + 2] - saved sp. 1154b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // [sp + 1] - second word reserved for return value. 1155b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // [sp + 0] - first word reserved for return value. 1156b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 1157b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // a0 will point to the return address, placed by DirectCEntry. 1158b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch __ mov(a0, sp); 1159b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 1160b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch ExternalReference stack_guard_check = 1161b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch ExternalReference::re_check_stack_guard_state(masm_->isolate()); 1162b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch __ li(t9, Operand(stack_guard_check)); 1163b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch DirectCEntryStub stub(isolate()); 1164b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch stub.GenerateCall(masm_, t9); 1165b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 1166b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // DirectCEntryStub allocated space for the C argument slots so we have to 1167b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // drop them with the return address from the stack with loading saved sp. 1168b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // At this point stack must look: 1169b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // [sp + 7] - empty slot if needed for alignment. 1170b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // [sp + 6] - saved sp. 1171b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // [sp + 5] - second word reserved for return value. 1172b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // [sp + 4] - first word reserved for return value. 1173b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // [sp + 3] - C argument slot. 1174b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // [sp + 2] - C argument slot. 1175b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // [sp + 1] - C argument slot. 1176b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // [sp + 0] - C argument slot. 1177b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch __ ld(sp, MemOperand(sp, stack_alignment + kCArgsSlotsSize)); 1178b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 1179b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch __ li(code_pointer(), Operand(masm_->CodeObject())); 1180b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch} 1181b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 1182b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 1183b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch// Helper function for reading a value out of a stack frame. 1184b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdochtemplate <typename T> 1185b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdochstatic T& frame_entry(Address re_frame, int frame_offset) { 1186b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch return reinterpret_cast<T&>(Memory::int32_at(re_frame + frame_offset)); 1187b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch} 1188b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 1189b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 1190014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdochtemplate <typename T> 1191014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdochstatic T* frame_entry_address(Address re_frame, int frame_offset) { 1192014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch return reinterpret_cast<T*>(re_frame + frame_offset); 1193014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch} 1194b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 1195b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 1196014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdochint64_t RegExpMacroAssemblerMIPS::CheckStackGuardState(Address* return_address, 1197014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch Code* re_code, 1198014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch Address re_frame) { 1199014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch return NativeRegExpMacroAssembler::CheckStackGuardState( 1200014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch frame_entry<Isolate*>(re_frame, kIsolate), 1201014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch static_cast<int>(frame_entry<int64_t>(re_frame, kStartIndex)), 1202014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch frame_entry<int64_t>(re_frame, kDirectCall) == 1, return_address, re_code, 1203014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch frame_entry_address<String*>(re_frame, kInputString), 1204014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch frame_entry_address<const byte*>(re_frame, kInputStart), 1205014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch frame_entry_address<const byte*>(re_frame, kInputEnd)); 1206b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch} 1207b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 1208b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 1209b8a8cc1952d61a2f3a2568848933943a543b5d3eBen MurdochMemOperand RegExpMacroAssemblerMIPS::register_location(int register_index) { 1210b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch DCHECK(register_index < (1<<30)); 1211b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch if (num_registers_ <= register_index) { 1212b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch num_registers_ = register_index + 1; 1213b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch } 1214b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch return MemOperand(frame_pointer(), 1215b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch kRegisterZero - register_index * kPointerSize); 1216b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch} 1217b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 1218b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 1219b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdochvoid RegExpMacroAssemblerMIPS::CheckPosition(int cp_offset, 1220b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch Label* on_outside_input) { 1221014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch if (cp_offset >= 0) { 1222014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch BranchOrBacktrack(on_outside_input, ge, current_input_offset(), 1223014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch Operand(-cp_offset * char_size())); 1224014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch } else { 1225014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch __ ld(a1, MemOperand(frame_pointer(), kStringStartMinusOne)); 1226014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch __ Daddu(a0, current_input_offset(), Operand(cp_offset * char_size())); 1227014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch BranchOrBacktrack(on_outside_input, le, a0, Operand(a1)); 1228014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch } 1229b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch} 1230b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 1231b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 1232b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdochvoid RegExpMacroAssemblerMIPS::BranchOrBacktrack(Label* to, 1233b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch Condition condition, 1234b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch Register rs, 1235b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch const Operand& rt) { 1236b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch if (condition == al) { // Unconditional. 1237b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch if (to == NULL) { 1238b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch Backtrack(); 1239b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch return; 1240b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch } 1241b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch __ jmp(to); 1242b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch return; 1243b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch } 1244b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch if (to == NULL) { 1245b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch __ Branch(&backtrack_label_, condition, rs, rt); 1246b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch return; 1247b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch } 1248b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch __ Branch(to, condition, rs, rt); 1249b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch} 1250b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 1251b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 1252b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdochvoid RegExpMacroAssemblerMIPS::SafeCall(Label* to, 1253b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch Condition cond, 1254b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch Register rs, 1255b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch const Operand& rt) { 1256b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch __ BranchAndLink(to, cond, rs, rt); 1257b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch} 1258b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 1259b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 1260b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdochvoid RegExpMacroAssemblerMIPS::SafeReturn() { 1261b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch __ pop(ra); 1262b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch __ Daddu(t1, ra, Operand(masm_->CodeObject())); 1263b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch __ Jump(t1); 1264b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch} 1265b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 1266b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 1267b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdochvoid RegExpMacroAssemblerMIPS::SafeCallTarget(Label* name) { 1268b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch __ bind(name); 1269b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch __ Dsubu(ra, ra, Operand(masm_->CodeObject())); 1270b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch __ push(ra); 1271b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch} 1272b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 1273b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 1274b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdochvoid RegExpMacroAssemblerMIPS::Push(Register source) { 1275b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch DCHECK(!source.is(backtrack_stackpointer())); 1276b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch __ Daddu(backtrack_stackpointer(), 1277b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch backtrack_stackpointer(), 1278b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch Operand(-kIntSize)); 1279b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch __ sw(source, MemOperand(backtrack_stackpointer())); 1280b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch} 1281b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 1282b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 1283b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdochvoid RegExpMacroAssemblerMIPS::Pop(Register target) { 1284b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch DCHECK(!target.is(backtrack_stackpointer())); 1285b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch __ lw(target, MemOperand(backtrack_stackpointer())); 1286b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch __ Daddu(backtrack_stackpointer(), backtrack_stackpointer(), kIntSize); 1287b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch} 1288b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 1289b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 1290b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdochvoid RegExpMacroAssemblerMIPS::CheckPreemption() { 1291b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // Check for preemption. 1292b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch ExternalReference stack_limit = 1293b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch ExternalReference::address_of_stack_limit(masm_->isolate()); 1294b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch __ li(a0, Operand(stack_limit)); 1295b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch __ ld(a0, MemOperand(a0)); 1296b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch SafeCall(&check_preempt_label_, ls, sp, Operand(a0)); 1297b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch} 1298b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 1299b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 1300b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdochvoid RegExpMacroAssemblerMIPS::CheckStackLimit() { 1301b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch ExternalReference stack_limit = 1302b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch ExternalReference::address_of_regexp_stack_limit(masm_->isolate()); 1303b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 1304b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch __ li(a0, Operand(stack_limit)); 1305b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch __ ld(a0, MemOperand(a0)); 1306b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch SafeCall(&stack_overflow_label_, ls, backtrack_stackpointer(), Operand(a0)); 1307b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch} 1308b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 1309b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 1310b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdochvoid RegExpMacroAssemblerMIPS::LoadCurrentCharacterUnchecked(int cp_offset, 1311b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch int characters) { 1312b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch Register offset = current_input_offset(); 1313b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch if (cp_offset != 0) { 1314b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // t3 is not being used to store the capture start index at this point. 1315b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch __ Daddu(t3, current_input_offset(), Operand(cp_offset * char_size())); 1316b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch offset = t3; 1317b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch } 1318b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // We assume that we cannot do unaligned loads on MIPS, so this function 1319b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // must only be used to load a single character at a time. 1320b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch DCHECK(characters == 1); 1321b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch __ Daddu(t1, end_of_input_address(), Operand(offset)); 1322b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch if (mode_ == LATIN1) { 1323b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch __ lbu(current_character(), MemOperand(t1, 0)); 1324b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch } else { 1325b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch DCHECK(mode_ == UC16); 1326b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch __ lhu(current_character(), MemOperand(t1, 0)); 1327b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch } 1328b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch} 1329b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 1330b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch#undef __ 1331b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 1332b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch#endif // V8_INTERPRETED_REGEXP 1333b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 1334014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch} // namespace internal 1335014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch} // namespace v8 1336b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 1337b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch#endif // V8_TARGET_ARCH_MIPS64 1338