13233d2f30cad1f77ff9f43fcbee12f182b18f6b6mstarzinger@chromium.org// Copyright 2012 the V8 project authors. All rights reserved. 23484964a86451e86dcf04be9bd8c0d76ee04f081rossberg@chromium.org// Use of this source code is governed by a BSD-style license that can be 33484964a86451e86dcf04be9bd8c0d76ee04f081rossberg@chromium.org// found in the LICENSE file. 47516f05132429850aa326421ed3e25f23b4c071blrn@chromium.org 5196eb601290dc49c3754da728dc58700dff2de1bmachenbach@chromium.org#include "src/v8.h" 67516f05132429850aa326421ed3e25f23b4c071blrn@chromium.org 793a47f4837f2137c8d8349250fd8e91da3108126jkummerow@chromium.org#if V8_TARGET_ARCH_MIPS 87516f05132429850aa326421ed3e25f23b4c071blrn@chromium.org 9196eb601290dc49c3754da728dc58700dff2de1bmachenbach@chromium.org#include "src/code-stubs.h" 104b0feeef5d01dbc2948080b4f69daa37e1083461machenbach@chromium.org#include "src/log.h" 11196eb601290dc49c3754da728dc58700dff2de1bmachenbach@chromium.org#include "src/macro-assembler.h" 12196eb601290dc49c3754da728dc58700dff2de1bmachenbach@chromium.org#include "src/regexp-macro-assembler.h" 134b0feeef5d01dbc2948080b4f69daa37e1083461machenbach@chromium.org#include "src/regexp-stack.h" 144b0feeef5d01dbc2948080b4f69daa37e1083461machenbach@chromium.org#include "src/unicode.h" 154b0feeef5d01dbc2948080b4f69daa37e1083461machenbach@chromium.org 16196eb601290dc49c3754da728dc58700dff2de1bmachenbach@chromium.org#include "src/mips/regexp-macro-assembler-mips.h" 177516f05132429850aa326421ed3e25f23b4c071blrn@chromium.org 187516f05132429850aa326421ed3e25f23b4c071blrn@chromium.orgnamespace v8 { 197516f05132429850aa326421ed3e25f23b4c071blrn@chromium.orgnamespace internal { 207516f05132429850aa326421ed3e25f23b4c071blrn@chromium.org 217516f05132429850aa326421ed3e25f23b4c071blrn@chromium.org#ifndef V8_INTERPRETED_REGEXP 227516f05132429850aa326421ed3e25f23b4c071blrn@chromium.org/* 237516f05132429850aa326421ed3e25f23b4c071blrn@chromium.org * This assembler uses the following register assignment convention 24777db6f4249aa13ebf060a0d290d34936a41eb75jkummerow@chromium.org * - t7 : Temporarily stores the index of capture start after a matching pass 25777db6f4249aa13ebf060a0d290d34936a41eb75jkummerow@chromium.org * for a global regexp. 267516f05132429850aa326421ed3e25f23b4c071blrn@chromium.org * - t1 : Pointer to current code object (Code*) including heap object tag. 277516f05132429850aa326421ed3e25f23b4c071blrn@chromium.org * - t2 : Current position in input, as negative offset from end of string. 287516f05132429850aa326421ed3e25f23b4c071blrn@chromium.org * Please notice that this is the byte offset, not the character offset! 297516f05132429850aa326421ed3e25f23b4c071blrn@chromium.org * - t3 : Currently loaded character. Must be loaded using 307516f05132429850aa326421ed3e25f23b4c071blrn@chromium.org * LoadCurrentCharacter before using any of the dispatch methods. 31777db6f4249aa13ebf060a0d290d34936a41eb75jkummerow@chromium.org * - t4 : Points to tip of backtrack stack 327516f05132429850aa326421ed3e25f23b4c071blrn@chromium.org * - t5 : Unused. 337516f05132429850aa326421ed3e25f23b4c071blrn@chromium.org * - t6 : End of input (points to byte after last character in input). 347516f05132429850aa326421ed3e25f23b4c071blrn@chromium.org * - fp : Frame pointer. Used to access arguments, local variables and 357516f05132429850aa326421ed3e25f23b4c071blrn@chromium.org * RegExp registers. 36777db6f4249aa13ebf060a0d290d34936a41eb75jkummerow@chromium.org * - sp : Points to tip of C stack. 377516f05132429850aa326421ed3e25f23b4c071blrn@chromium.org * 387516f05132429850aa326421ed3e25f23b4c071blrn@chromium.org * The remaining registers are free for computations. 397516f05132429850aa326421ed3e25f23b4c071blrn@chromium.org * Each call to a public method should retain this convention. 40c53e10d01c5495df3896b9d318910b58688c6929kmillikin@chromium.org * 417516f05132429850aa326421ed3e25f23b4c071blrn@chromium.org * The stack will have the following structure: 42c53e10d01c5495df3896b9d318910b58688c6929kmillikin@chromium.org * 43777db6f4249aa13ebf060a0d290d34936a41eb75jkummerow@chromium.org * - fp[64] Isolate* isolate (address of the current isolate) 44777db6f4249aa13ebf060a0d290d34936a41eb75jkummerow@chromium.org * - fp[60] direct_call (if 1, direct call from JavaScript code, 45c53e10d01c5495df3896b9d318910b58688c6929kmillikin@chromium.org * if 0, call through the runtime system). 46777db6f4249aa13ebf060a0d290d34936a41eb75jkummerow@chromium.org * - fp[56] stack_area_base (High end of the memory area to use as 47c53e10d01c5495df3896b9d318910b58688c6929kmillikin@chromium.org * backtracking stack). 48777db6f4249aa13ebf060a0d290d34936a41eb75jkummerow@chromium.org * - fp[52] capture array size (may fit multiple sets of matches) 49c53e10d01c5495df3896b9d318910b58688c6929kmillikin@chromium.org * - fp[48] int* capture_array (int[num_saved_registers_], for output). 50c53e10d01c5495df3896b9d318910b58688c6929kmillikin@chromium.org * - fp[44] secondary link/return address used by native call. 51c53e10d01c5495df3896b9d318910b58688c6929kmillikin@chromium.org * --- sp when called --- 52777db6f4249aa13ebf060a0d290d34936a41eb75jkummerow@chromium.org * - fp[40] return address (lr). 53777db6f4249aa13ebf060a0d290d34936a41eb75jkummerow@chromium.org * - fp[36] old frame pointer (r11). 54c53e10d01c5495df3896b9d318910b58688c6929kmillikin@chromium.org * - fp[0..32] backup of registers s0..s7. 55c53e10d01c5495df3896b9d318910b58688c6929kmillikin@chromium.org * --- frame pointer ---- 56777db6f4249aa13ebf060a0d290d34936a41eb75jkummerow@chromium.org * - fp[-4] end of input (address of end of string). 57777db6f4249aa13ebf060a0d290d34936a41eb75jkummerow@chromium.org * - fp[-8] start of input (address of first character in string). 58c53e10d01c5495df3896b9d318910b58688c6929kmillikin@chromium.org * - fp[-12] start index (character index of start). 59c53e10d01c5495df3896b9d318910b58688c6929kmillikin@chromium.org * - fp[-16] void* input_string (location of a handle containing the string). 60777db6f4249aa13ebf060a0d290d34936a41eb75jkummerow@chromium.org * - fp[-20] success counter (only for global regexps to count matches). 61777db6f4249aa13ebf060a0d290d34936a41eb75jkummerow@chromium.org * - fp[-24] Offset of location before start of input (effectively character 62c53e10d01c5495df3896b9d318910b58688c6929kmillikin@chromium.org * position -1). Used to initialize capture registers to a 63c53e10d01c5495df3896b9d318910b58688c6929kmillikin@chromium.org * non-position. 64777db6f4249aa13ebf060a0d290d34936a41eb75jkummerow@chromium.org * - fp[-28] At start (if 1, we are starting at the start of the 65c53e10d01c5495df3896b9d318910b58688c6929kmillikin@chromium.org * string, otherwise 0) 66777db6f4249aa13ebf060a0d290d34936a41eb75jkummerow@chromium.org * - fp[-32] register 0 (Only positions must be stored in the first 67c53e10d01c5495df3896b9d318910b58688c6929kmillikin@chromium.org * - register 1 num_saved_registers_ registers) 68c53e10d01c5495df3896b9d318910b58688c6929kmillikin@chromium.org * - ... 69c53e10d01c5495df3896b9d318910b58688c6929kmillikin@chromium.org * - register num_registers-1 70c53e10d01c5495df3896b9d318910b58688c6929kmillikin@chromium.org * --- sp --- 717516f05132429850aa326421ed3e25f23b4c071blrn@chromium.org * 727516f05132429850aa326421ed3e25f23b4c071blrn@chromium.org * The first num_saved_registers_ registers are initialized to point to 737516f05132429850aa326421ed3e25f23b4c071blrn@chromium.org * "character -1" in the string (i.e., char_size() bytes before the first 747516f05132429850aa326421ed3e25f23b4c071blrn@chromium.org * character of the string). The remaining registers start out as garbage. 757516f05132429850aa326421ed3e25f23b4c071blrn@chromium.org * 767516f05132429850aa326421ed3e25f23b4c071blrn@chromium.org * The data up to the return address must be placed there by the calling 77c53e10d01c5495df3896b9d318910b58688c6929kmillikin@chromium.org * code and the remaining arguments are passed in registers, e.g. by calling the 78c53e10d01c5495df3896b9d318910b58688c6929kmillikin@chromium.org * code entry as cast to a function with the signature: 797516f05132429850aa326421ed3e25f23b4c071blrn@chromium.org * int (*match)(String* input_string, 807516f05132429850aa326421ed3e25f23b4c071blrn@chromium.org * int start_index, 817516f05132429850aa326421ed3e25f23b4c071blrn@chromium.org * Address start, 827516f05132429850aa326421ed3e25f23b4c071blrn@chromium.org * Address end, 83c53e10d01c5495df3896b9d318910b58688c6929kmillikin@chromium.org * Address secondary_return_address, // Only used by native call. 847516f05132429850aa326421ed3e25f23b4c071blrn@chromium.org * int* capture_output_array, 857516f05132429850aa326421ed3e25f23b4c071blrn@chromium.org * byte* stack_area_base, 86c53e10d01c5495df3896b9d318910b58688c6929kmillikin@chromium.org * bool direct_call = false) 877516f05132429850aa326421ed3e25f23b4c071blrn@chromium.org * The call is performed by NativeRegExpMacroAssembler::Execute() 88c53e10d01c5495df3896b9d318910b58688c6929kmillikin@chromium.org * (in regexp-macro-assembler.cc) via the CALL_GENERATED_REGEXP_CODE macro 89c53e10d01c5495df3896b9d318910b58688c6929kmillikin@chromium.org * in mips/simulator-mips.h. 90c53e10d01c5495df3896b9d318910b58688c6929kmillikin@chromium.org * When calling as a non-direct call (i.e., from C++ code), the return address 91c53e10d01c5495df3896b9d318910b58688c6929kmillikin@chromium.org * area is overwritten with the ra register by the RegExp code. When doing a 92c53e10d01c5495df3896b9d318910b58688c6929kmillikin@chromium.org * direct call from generated code, the return address is placed there by 93c53e10d01c5495df3896b9d318910b58688c6929kmillikin@chromium.org * the calling code, as in a normal exit frame. 947516f05132429850aa326421ed3e25f23b4c071blrn@chromium.org */ 957516f05132429850aa326421ed3e25f23b4c071blrn@chromium.org 967516f05132429850aa326421ed3e25f23b4c071blrn@chromium.org#define __ ACCESS_MASM(masm_) 977516f05132429850aa326421ed3e25f23b4c071blrn@chromium.org 987516f05132429850aa326421ed3e25f23b4c071blrn@chromium.orgRegExpMacroAssemblerMIPS::RegExpMacroAssemblerMIPS( 997516f05132429850aa326421ed3e25f23b4c071blrn@chromium.org Mode mode, 1007028c05c1c71b9d5c5fe1bca01f2461d17a2dda7mmassi@chromium.org int registers_to_save, 1017028c05c1c71b9d5c5fe1bca01f2461d17a2dda7mmassi@chromium.org Zone* zone) 1027028c05c1c71b9d5c5fe1bca01f2461d17a2dda7mmassi@chromium.org : NativeRegExpMacroAssembler(zone), 1031fd77d58ca66b2711f09cdea32c0c2d1a01b3ae5danno@chromium.org masm_(new MacroAssembler(zone->isolate(), NULL, kRegExpCodeSize)), 1047516f05132429850aa326421ed3e25f23b4c071blrn@chromium.org mode_(mode), 1057516f05132429850aa326421ed3e25f23b4c071blrn@chromium.org num_registers_(registers_to_save), 1067516f05132429850aa326421ed3e25f23b4c071blrn@chromium.org num_saved_registers_(registers_to_save), 1077516f05132429850aa326421ed3e25f23b4c071blrn@chromium.org entry_label_(), 1087516f05132429850aa326421ed3e25f23b4c071blrn@chromium.org start_label_(), 1097516f05132429850aa326421ed3e25f23b4c071blrn@chromium.org success_label_(), 1107516f05132429850aa326421ed3e25f23b4c071blrn@chromium.org backtrack_label_(), 111c53e10d01c5495df3896b9d318910b58688c6929kmillikin@chromium.org exit_label_(), 112c53e10d01c5495df3896b9d318910b58688c6929kmillikin@chromium.org internal_failure_label_() { 113e3c177a423baa3c30225c4e422b6f6c76d38b951machenbach@chromium.org DCHECK_EQ(0, registers_to_save % 2); 1147516f05132429850aa326421ed3e25f23b4c071blrn@chromium.org __ jmp(&entry_label_); // We'll write the entry code later. 115c53e10d01c5495df3896b9d318910b58688c6929kmillikin@chromium.org // If the code gets too big or corrupted, an internal exception will be 116c53e10d01c5495df3896b9d318910b58688c6929kmillikin@chromium.org // raised, and we will exit right away. 117c53e10d01c5495df3896b9d318910b58688c6929kmillikin@chromium.org __ bind(&internal_failure_label_); 118c53e10d01c5495df3896b9d318910b58688c6929kmillikin@chromium.org __ li(v0, Operand(FAILURE)); 119c53e10d01c5495df3896b9d318910b58688c6929kmillikin@chromium.org __ Ret(); 1207516f05132429850aa326421ed3e25f23b4c071blrn@chromium.org __ bind(&start_label_); // And then continue from here. 1217516f05132429850aa326421ed3e25f23b4c071blrn@chromium.org} 1227516f05132429850aa326421ed3e25f23b4c071blrn@chromium.org 1237516f05132429850aa326421ed3e25f23b4c071blrn@chromium.org 1247516f05132429850aa326421ed3e25f23b4c071blrn@chromium.orgRegExpMacroAssemblerMIPS::~RegExpMacroAssemblerMIPS() { 1257516f05132429850aa326421ed3e25f23b4c071blrn@chromium.org delete masm_; 1267516f05132429850aa326421ed3e25f23b4c071blrn@chromium.org // Unuse labels in case we throw away the assembler without calling GetCode. 1277516f05132429850aa326421ed3e25f23b4c071blrn@chromium.org entry_label_.Unuse(); 1287516f05132429850aa326421ed3e25f23b4c071blrn@chromium.org start_label_.Unuse(); 1297516f05132429850aa326421ed3e25f23b4c071blrn@chromium.org success_label_.Unuse(); 1307516f05132429850aa326421ed3e25f23b4c071blrn@chromium.org backtrack_label_.Unuse(); 1317516f05132429850aa326421ed3e25f23b4c071blrn@chromium.org exit_label_.Unuse(); 1327516f05132429850aa326421ed3e25f23b4c071blrn@chromium.org check_preempt_label_.Unuse(); 1337516f05132429850aa326421ed3e25f23b4c071blrn@chromium.org stack_overflow_label_.Unuse(); 134c53e10d01c5495df3896b9d318910b58688c6929kmillikin@chromium.org internal_failure_label_.Unuse(); 1357516f05132429850aa326421ed3e25f23b4c071blrn@chromium.org} 1367516f05132429850aa326421ed3e25f23b4c071blrn@chromium.org 1377516f05132429850aa326421ed3e25f23b4c071blrn@chromium.org 1387516f05132429850aa326421ed3e25f23b4c071blrn@chromium.orgint RegExpMacroAssemblerMIPS::stack_limit_slack() { 1397516f05132429850aa326421ed3e25f23b4c071blrn@chromium.org return RegExpStack::kStackLimitSlack; 1407516f05132429850aa326421ed3e25f23b4c071blrn@chromium.org} 1417516f05132429850aa326421ed3e25f23b4c071blrn@chromium.org 1427516f05132429850aa326421ed3e25f23b4c071blrn@chromium.org 1437516f05132429850aa326421ed3e25f23b4c071blrn@chromium.orgvoid RegExpMacroAssemblerMIPS::AdvanceCurrentPosition(int by) { 144c53e10d01c5495df3896b9d318910b58688c6929kmillikin@chromium.org if (by != 0) { 145c53e10d01c5495df3896b9d318910b58688c6929kmillikin@chromium.org __ Addu(current_input_offset(), 14628faa982749c4aa9c090939453dea14bb118f613jkummerow@chromium.org current_input_offset(), Operand(by * char_size())); 147c53e10d01c5495df3896b9d318910b58688c6929kmillikin@chromium.org } 1487516f05132429850aa326421ed3e25f23b4c071blrn@chromium.org} 1497516f05132429850aa326421ed3e25f23b4c071blrn@chromium.org 1507516f05132429850aa326421ed3e25f23b4c071blrn@chromium.org 1517516f05132429850aa326421ed3e25f23b4c071blrn@chromium.orgvoid RegExpMacroAssemblerMIPS::AdvanceRegister(int reg, int by) { 152e3c177a423baa3c30225c4e422b6f6c76d38b951machenbach@chromium.org DCHECK(reg >= 0); 153e3c177a423baa3c30225c4e422b6f6c76d38b951machenbach@chromium.org DCHECK(reg < num_registers_); 154c53e10d01c5495df3896b9d318910b58688c6929kmillikin@chromium.org if (by != 0) { 155c53e10d01c5495df3896b9d318910b58688c6929kmillikin@chromium.org __ lw(a0, register_location(reg)); 156c53e10d01c5495df3896b9d318910b58688c6929kmillikin@chromium.org __ Addu(a0, a0, Operand(by)); 157c53e10d01c5495df3896b9d318910b58688c6929kmillikin@chromium.org __ sw(a0, register_location(reg)); 158c53e10d01c5495df3896b9d318910b58688c6929kmillikin@chromium.org } 1597516f05132429850aa326421ed3e25f23b4c071blrn@chromium.org} 1607516f05132429850aa326421ed3e25f23b4c071blrn@chromium.org 1617516f05132429850aa326421ed3e25f23b4c071blrn@chromium.org 1627516f05132429850aa326421ed3e25f23b4c071blrn@chromium.orgvoid RegExpMacroAssemblerMIPS::Backtrack() { 163c53e10d01c5495df3896b9d318910b58688c6929kmillikin@chromium.org CheckPreemption(); 164c53e10d01c5495df3896b9d318910b58688c6929kmillikin@chromium.org // Pop Code* offset from backtrack stack, add Code* and jump to location. 165c53e10d01c5495df3896b9d318910b58688c6929kmillikin@chromium.org Pop(a0); 166c53e10d01c5495df3896b9d318910b58688c6929kmillikin@chromium.org __ Addu(a0, a0, code_pointer()); 1676db8871df97e7137d11f956af3c772f4f8370761sgjesse@chromium.org __ Jump(a0); 1687516f05132429850aa326421ed3e25f23b4c071blrn@chromium.org} 1697516f05132429850aa326421ed3e25f23b4c071blrn@chromium.org 1707516f05132429850aa326421ed3e25f23b4c071blrn@chromium.org 1717516f05132429850aa326421ed3e25f23b4c071blrn@chromium.orgvoid RegExpMacroAssemblerMIPS::Bind(Label* label) { 172c53e10d01c5495df3896b9d318910b58688c6929kmillikin@chromium.org __ bind(label); 1737516f05132429850aa326421ed3e25f23b4c071blrn@chromium.org} 1747516f05132429850aa326421ed3e25f23b4c071blrn@chromium.org 1757516f05132429850aa326421ed3e25f23b4c071blrn@chromium.org 1767516f05132429850aa326421ed3e25f23b4c071blrn@chromium.orgvoid RegExpMacroAssemblerMIPS::CheckCharacter(uint32_t c, Label* on_equal) { 177c53e10d01c5495df3896b9d318910b58688c6929kmillikin@chromium.org BranchOrBacktrack(on_equal, eq, current_character(), Operand(c)); 1787516f05132429850aa326421ed3e25f23b4c071blrn@chromium.org} 1797516f05132429850aa326421ed3e25f23b4c071blrn@chromium.org 1807516f05132429850aa326421ed3e25f23b4c071blrn@chromium.org 1817516f05132429850aa326421ed3e25f23b4c071blrn@chromium.orgvoid RegExpMacroAssemblerMIPS::CheckCharacterGT(uc16 limit, Label* on_greater) { 182c53e10d01c5495df3896b9d318910b58688c6929kmillikin@chromium.org BranchOrBacktrack(on_greater, gt, current_character(), Operand(limit)); 1837516f05132429850aa326421ed3e25f23b4c071blrn@chromium.org} 1847516f05132429850aa326421ed3e25f23b4c071blrn@chromium.org 1857516f05132429850aa326421ed3e25f23b4c071blrn@chromium.org 1867516f05132429850aa326421ed3e25f23b4c071blrn@chromium.orgvoid RegExpMacroAssemblerMIPS::CheckAtStart(Label* on_at_start) { 187c53e10d01c5495df3896b9d318910b58688c6929kmillikin@chromium.org Label not_at_start; 188c53e10d01c5495df3896b9d318910b58688c6929kmillikin@chromium.org // Did we start the match at the start of the string at all? 189777db6f4249aa13ebf060a0d290d34936a41eb75jkummerow@chromium.org __ lw(a0, MemOperand(frame_pointer(), kStartIndex)); 190777db6f4249aa13ebf060a0d290d34936a41eb75jkummerow@chromium.org BranchOrBacktrack(¬_at_start, ne, a0, Operand(zero_reg)); 191c53e10d01c5495df3896b9d318910b58688c6929kmillikin@chromium.org 192c53e10d01c5495df3896b9d318910b58688c6929kmillikin@chromium.org // If we did, are we still at the start of the input? 193c53e10d01c5495df3896b9d318910b58688c6929kmillikin@chromium.org __ lw(a1, MemOperand(frame_pointer(), kInputStart)); 194c53e10d01c5495df3896b9d318910b58688c6929kmillikin@chromium.org __ Addu(a0, end_of_input_address(), Operand(current_input_offset())); 195c53e10d01c5495df3896b9d318910b58688c6929kmillikin@chromium.org BranchOrBacktrack(on_at_start, eq, a0, Operand(a1)); 196c53e10d01c5495df3896b9d318910b58688c6929kmillikin@chromium.org __ bind(¬_at_start); 1977516f05132429850aa326421ed3e25f23b4c071blrn@chromium.org} 1987516f05132429850aa326421ed3e25f23b4c071blrn@chromium.org 1997516f05132429850aa326421ed3e25f23b4c071blrn@chromium.org 2007516f05132429850aa326421ed3e25f23b4c071blrn@chromium.orgvoid RegExpMacroAssemblerMIPS::CheckNotAtStart(Label* on_not_at_start) { 201c53e10d01c5495df3896b9d318910b58688c6929kmillikin@chromium.org // Did we start the match at the start of the string at all? 202777db6f4249aa13ebf060a0d290d34936a41eb75jkummerow@chromium.org __ lw(a0, MemOperand(frame_pointer(), kStartIndex)); 203777db6f4249aa13ebf060a0d290d34936a41eb75jkummerow@chromium.org BranchOrBacktrack(on_not_at_start, ne, a0, Operand(zero_reg)); 204c53e10d01c5495df3896b9d318910b58688c6929kmillikin@chromium.org // If we did, are we still at the start of the input? 205c53e10d01c5495df3896b9d318910b58688c6929kmillikin@chromium.org __ lw(a1, MemOperand(frame_pointer(), kInputStart)); 206c53e10d01c5495df3896b9d318910b58688c6929kmillikin@chromium.org __ Addu(a0, end_of_input_address(), Operand(current_input_offset())); 207c53e10d01c5495df3896b9d318910b58688c6929kmillikin@chromium.org BranchOrBacktrack(on_not_at_start, ne, a0, Operand(a1)); 2087516f05132429850aa326421ed3e25f23b4c071blrn@chromium.org} 2097516f05132429850aa326421ed3e25f23b4c071blrn@chromium.org 2107516f05132429850aa326421ed3e25f23b4c071blrn@chromium.org 2117516f05132429850aa326421ed3e25f23b4c071blrn@chromium.orgvoid RegExpMacroAssemblerMIPS::CheckCharacterLT(uc16 limit, Label* on_less) { 212c53e10d01c5495df3896b9d318910b58688c6929kmillikin@chromium.org BranchOrBacktrack(on_less, lt, current_character(), Operand(limit)); 2137516f05132429850aa326421ed3e25f23b4c071blrn@chromium.org} 2147516f05132429850aa326421ed3e25f23b4c071blrn@chromium.org 2157516f05132429850aa326421ed3e25f23b4c071blrn@chromium.org 2167516f05132429850aa326421ed3e25f23b4c071blrn@chromium.orgvoid RegExpMacroAssemblerMIPS::CheckGreedyLoop(Label* on_equal) { 217c53e10d01c5495df3896b9d318910b58688c6929kmillikin@chromium.org Label backtrack_non_equal; 218c53e10d01c5495df3896b9d318910b58688c6929kmillikin@chromium.org __ lw(a0, MemOperand(backtrack_stackpointer(), 0)); 219c53e10d01c5495df3896b9d318910b58688c6929kmillikin@chromium.org __ Branch(&backtrack_non_equal, ne, current_input_offset(), Operand(a0)); 220c53e10d01c5495df3896b9d318910b58688c6929kmillikin@chromium.org __ Addu(backtrack_stackpointer(), 221c53e10d01c5495df3896b9d318910b58688c6929kmillikin@chromium.org backtrack_stackpointer(), 222c53e10d01c5495df3896b9d318910b58688c6929kmillikin@chromium.org Operand(kPointerSize)); 223c53e10d01c5495df3896b9d318910b58688c6929kmillikin@chromium.org __ bind(&backtrack_non_equal); 224c53e10d01c5495df3896b9d318910b58688c6929kmillikin@chromium.org BranchOrBacktrack(on_equal, eq, current_input_offset(), Operand(a0)); 2257516f05132429850aa326421ed3e25f23b4c071blrn@chromium.org} 2267516f05132429850aa326421ed3e25f23b4c071blrn@chromium.org 2277516f05132429850aa326421ed3e25f23b4c071blrn@chromium.org 2287516f05132429850aa326421ed3e25f23b4c071blrn@chromium.orgvoid RegExpMacroAssemblerMIPS::CheckNotBackReferenceIgnoreCase( 2297516f05132429850aa326421ed3e25f23b4c071blrn@chromium.org int start_reg, 2307516f05132429850aa326421ed3e25f23b4c071blrn@chromium.org Label* on_no_match) { 231c53e10d01c5495df3896b9d318910b58688c6929kmillikin@chromium.org Label fallthrough; 232c53e10d01c5495df3896b9d318910b58688c6929kmillikin@chromium.org __ lw(a0, register_location(start_reg)); // Index of start of capture. 233c53e10d01c5495df3896b9d318910b58688c6929kmillikin@chromium.org __ lw(a1, register_location(start_reg + 1)); // Index of end of capture. 234c53e10d01c5495df3896b9d318910b58688c6929kmillikin@chromium.org __ Subu(a1, a1, a0); // Length of capture. 235c53e10d01c5495df3896b9d318910b58688c6929kmillikin@chromium.org 236c53e10d01c5495df3896b9d318910b58688c6929kmillikin@chromium.org // If length is zero, either the capture is empty or it is not participating. 237c53e10d01c5495df3896b9d318910b58688c6929kmillikin@chromium.org // In either case succeed immediately. 238c53e10d01c5495df3896b9d318910b58688c6929kmillikin@chromium.org __ Branch(&fallthrough, eq, a1, Operand(zero_reg)); 239c53e10d01c5495df3896b9d318910b58688c6929kmillikin@chromium.org 240c53e10d01c5495df3896b9d318910b58688c6929kmillikin@chromium.org __ Addu(t5, a1, current_input_offset()); 241c53e10d01c5495df3896b9d318910b58688c6929kmillikin@chromium.org // Check that there are enough characters left in the input. 242c53e10d01c5495df3896b9d318910b58688c6929kmillikin@chromium.org BranchOrBacktrack(on_no_match, gt, t5, Operand(zero_reg)); 243c53e10d01c5495df3896b9d318910b58688c6929kmillikin@chromium.org 2442c81ceb7f1e1ccf5f304be0646f4c1375941a7f2machenbach@chromium.org if (mode_ == LATIN1) { 245c53e10d01c5495df3896b9d318910b58688c6929kmillikin@chromium.org Label success; 246c53e10d01c5495df3896b9d318910b58688c6929kmillikin@chromium.org Label fail; 247c53e10d01c5495df3896b9d318910b58688c6929kmillikin@chromium.org Label loop_check; 248c53e10d01c5495df3896b9d318910b58688c6929kmillikin@chromium.org 249c53e10d01c5495df3896b9d318910b58688c6929kmillikin@chromium.org // a0 - offset of start of capture. 250c53e10d01c5495df3896b9d318910b58688c6929kmillikin@chromium.org // a1 - length of capture. 251c53e10d01c5495df3896b9d318910b58688c6929kmillikin@chromium.org __ Addu(a0, a0, Operand(end_of_input_address())); 252c53e10d01c5495df3896b9d318910b58688c6929kmillikin@chromium.org __ Addu(a2, end_of_input_address(), Operand(current_input_offset())); 253c53e10d01c5495df3896b9d318910b58688c6929kmillikin@chromium.org __ Addu(a1, a0, Operand(a1)); 254c53e10d01c5495df3896b9d318910b58688c6929kmillikin@chromium.org 255c53e10d01c5495df3896b9d318910b58688c6929kmillikin@chromium.org // a0 - Address of start of capture. 256c53e10d01c5495df3896b9d318910b58688c6929kmillikin@chromium.org // a1 - Address of end of capture. 257c53e10d01c5495df3896b9d318910b58688c6929kmillikin@chromium.org // a2 - Address of current input position. 258c53e10d01c5495df3896b9d318910b58688c6929kmillikin@chromium.org 259c53e10d01c5495df3896b9d318910b58688c6929kmillikin@chromium.org Label loop; 260c53e10d01c5495df3896b9d318910b58688c6929kmillikin@chromium.org __ bind(&loop); 261c53e10d01c5495df3896b9d318910b58688c6929kmillikin@chromium.org __ lbu(a3, MemOperand(a0, 0)); 262c53e10d01c5495df3896b9d318910b58688c6929kmillikin@chromium.org __ addiu(a0, a0, char_size()); 263c53e10d01c5495df3896b9d318910b58688c6929kmillikin@chromium.org __ lbu(t0, MemOperand(a2, 0)); 264c53e10d01c5495df3896b9d318910b58688c6929kmillikin@chromium.org __ addiu(a2, a2, char_size()); 265c53e10d01c5495df3896b9d318910b58688c6929kmillikin@chromium.org 266c53e10d01c5495df3896b9d318910b58688c6929kmillikin@chromium.org __ Branch(&loop_check, eq, t0, Operand(a3)); 267c53e10d01c5495df3896b9d318910b58688c6929kmillikin@chromium.org 268c53e10d01c5495df3896b9d318910b58688c6929kmillikin@chromium.org // Mismatch, try case-insensitive match (converting letters to lower-case). 269c53e10d01c5495df3896b9d318910b58688c6929kmillikin@chromium.org __ Or(a3, a3, Operand(0x20)); // Convert capture character to lower-case. 270c53e10d01c5495df3896b9d318910b58688c6929kmillikin@chromium.org __ Or(t0, t0, Operand(0x20)); // Also convert input character. 271c53e10d01c5495df3896b9d318910b58688c6929kmillikin@chromium.org __ Branch(&fail, ne, t0, Operand(a3)); 272c53e10d01c5495df3896b9d318910b58688c6929kmillikin@chromium.org __ Subu(a3, a3, Operand('a')); 27346a2a51ad190697e0f62c3060ce02a9de5820a07yangguo@chromium.org __ Branch(&loop_check, ls, a3, Operand('z' - 'a')); 27446a2a51ad190697e0f62c3060ce02a9de5820a07yangguo@chromium.org // Latin-1: Check for values in range [224,254] but not 247. 27546a2a51ad190697e0f62c3060ce02a9de5820a07yangguo@chromium.org __ Subu(a3, a3, Operand(224 - 'a')); 27646a2a51ad190697e0f62c3060ce02a9de5820a07yangguo@chromium.org // Weren't Latin-1 letters. 27746a2a51ad190697e0f62c3060ce02a9de5820a07yangguo@chromium.org __ Branch(&fail, hi, a3, Operand(254 - 224)); 27846a2a51ad190697e0f62c3060ce02a9de5820a07yangguo@chromium.org // Check for 247. 27946a2a51ad190697e0f62c3060ce02a9de5820a07yangguo@chromium.org __ Branch(&fail, eq, a3, Operand(247 - 224)); 280c53e10d01c5495df3896b9d318910b58688c6929kmillikin@chromium.org 281c53e10d01c5495df3896b9d318910b58688c6929kmillikin@chromium.org __ bind(&loop_check); 282c53e10d01c5495df3896b9d318910b58688c6929kmillikin@chromium.org __ Branch(&loop, lt, a0, Operand(a1)); 283c53e10d01c5495df3896b9d318910b58688c6929kmillikin@chromium.org __ jmp(&success); 284c53e10d01c5495df3896b9d318910b58688c6929kmillikin@chromium.org 285c53e10d01c5495df3896b9d318910b58688c6929kmillikin@chromium.org __ bind(&fail); 286c53e10d01c5495df3896b9d318910b58688c6929kmillikin@chromium.org GoTo(on_no_match); 287c53e10d01c5495df3896b9d318910b58688c6929kmillikin@chromium.org 288c53e10d01c5495df3896b9d318910b58688c6929kmillikin@chromium.org __ bind(&success); 289c53e10d01c5495df3896b9d318910b58688c6929kmillikin@chromium.org // Compute new value of character position after the matched part. 290c53e10d01c5495df3896b9d318910b58688c6929kmillikin@chromium.org __ Subu(current_input_offset(), a2, end_of_input_address()); 291c53e10d01c5495df3896b9d318910b58688c6929kmillikin@chromium.org } else { 292e3c177a423baa3c30225c4e422b6f6c76d38b951machenbach@chromium.org DCHECK(mode_ == UC16); 293c53e10d01c5495df3896b9d318910b58688c6929kmillikin@chromium.org // Put regexp engine registers on stack. 294c53e10d01c5495df3896b9d318910b58688c6929kmillikin@chromium.org RegList regexp_registers_to_retain = current_input_offset().bit() | 295c53e10d01c5495df3896b9d318910b58688c6929kmillikin@chromium.org current_character().bit() | backtrack_stackpointer().bit(); 296c53e10d01c5495df3896b9d318910b58688c6929kmillikin@chromium.org __ MultiPush(regexp_registers_to_retain); 297c53e10d01c5495df3896b9d318910b58688c6929kmillikin@chromium.org 298c53e10d01c5495df3896b9d318910b58688c6929kmillikin@chromium.org int argument_count = 4; 299c53e10d01c5495df3896b9d318910b58688c6929kmillikin@chromium.org __ PrepareCallCFunction(argument_count, a2); 300c53e10d01c5495df3896b9d318910b58688c6929kmillikin@chromium.org 301c53e10d01c5495df3896b9d318910b58688c6929kmillikin@chromium.org // a0 - offset of start of capture. 302c53e10d01c5495df3896b9d318910b58688c6929kmillikin@chromium.org // a1 - length of capture. 303c53e10d01c5495df3896b9d318910b58688c6929kmillikin@chromium.org 304c53e10d01c5495df3896b9d318910b58688c6929kmillikin@chromium.org // Put arguments into arguments registers. 305c53e10d01c5495df3896b9d318910b58688c6929kmillikin@chromium.org // Parameters are 306c53e10d01c5495df3896b9d318910b58688c6929kmillikin@chromium.org // a0: Address byte_offset1 - Address captured substring's start. 307c53e10d01c5495df3896b9d318910b58688c6929kmillikin@chromium.org // a1: Address byte_offset2 - Address of current character position. 308c53e10d01c5495df3896b9d318910b58688c6929kmillikin@chromium.org // a2: size_t byte_length - length of capture in bytes(!). 309c53e10d01c5495df3896b9d318910b58688c6929kmillikin@chromium.org // a3: Isolate* isolate. 310c53e10d01c5495df3896b9d318910b58688c6929kmillikin@chromium.org 311c53e10d01c5495df3896b9d318910b58688c6929kmillikin@chromium.org // Address of start of capture. 312c53e10d01c5495df3896b9d318910b58688c6929kmillikin@chromium.org __ Addu(a0, a0, Operand(end_of_input_address())); 313c53e10d01c5495df3896b9d318910b58688c6929kmillikin@chromium.org // Length of capture. 314c53e10d01c5495df3896b9d318910b58688c6929kmillikin@chromium.org __ mov(a2, a1); 315c53e10d01c5495df3896b9d318910b58688c6929kmillikin@chromium.org // Save length in callee-save register for use on return. 316c53e10d01c5495df3896b9d318910b58688c6929kmillikin@chromium.org __ mov(s3, a1); 317c53e10d01c5495df3896b9d318910b58688c6929kmillikin@chromium.org // Address of current input position. 318c53e10d01c5495df3896b9d318910b58688c6929kmillikin@chromium.org __ Addu(a1, current_input_offset(), Operand(end_of_input_address())); 319c53e10d01c5495df3896b9d318910b58688c6929kmillikin@chromium.org // Isolate. 32032d7dbafe29be06cec1edd36c31fbe2865c799f4ulan@chromium.org __ li(a3, Operand(ExternalReference::isolate_address(masm_->isolate()))); 321c53e10d01c5495df3896b9d318910b58688c6929kmillikin@chromium.org 322c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com { 323c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com AllowExternalCallThatCantCauseGC scope(masm_); 324c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com ExternalReference function = 325c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com ExternalReference::re_case_insensitive_compare_uc16(masm_->isolate()); 326c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com __ CallCFunction(function, argument_count); 327c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com } 328c53e10d01c5495df3896b9d318910b58688c6929kmillikin@chromium.org 329c53e10d01c5495df3896b9d318910b58688c6929kmillikin@chromium.org // Restore regexp engine registers. 330c53e10d01c5495df3896b9d318910b58688c6929kmillikin@chromium.org __ MultiPop(regexp_registers_to_retain); 33188aa058bdadfa79ae2836d12d6dd2d1c28aa490cdanno@chromium.org __ li(code_pointer(), Operand(masm_->CodeObject()), CONSTANT_SIZE); 332c53e10d01c5495df3896b9d318910b58688c6929kmillikin@chromium.org __ lw(end_of_input_address(), MemOperand(frame_pointer(), kInputEnd)); 333c53e10d01c5495df3896b9d318910b58688c6929kmillikin@chromium.org 334c53e10d01c5495df3896b9d318910b58688c6929kmillikin@chromium.org // Check if function returned non-zero for success or zero for failure. 335c53e10d01c5495df3896b9d318910b58688c6929kmillikin@chromium.org BranchOrBacktrack(on_no_match, eq, v0, Operand(zero_reg)); 336c53e10d01c5495df3896b9d318910b58688c6929kmillikin@chromium.org // On success, increment position by length of capture. 337c53e10d01c5495df3896b9d318910b58688c6929kmillikin@chromium.org __ Addu(current_input_offset(), current_input_offset(), Operand(s3)); 338c53e10d01c5495df3896b9d318910b58688c6929kmillikin@chromium.org } 339c53e10d01c5495df3896b9d318910b58688c6929kmillikin@chromium.org 340c53e10d01c5495df3896b9d318910b58688c6929kmillikin@chromium.org __ bind(&fallthrough); 3417516f05132429850aa326421ed3e25f23b4c071blrn@chromium.org} 3427516f05132429850aa326421ed3e25f23b4c071blrn@chromium.org 3437516f05132429850aa326421ed3e25f23b4c071blrn@chromium.org 3447516f05132429850aa326421ed3e25f23b4c071blrn@chromium.orgvoid RegExpMacroAssemblerMIPS::CheckNotBackReference( 3457516f05132429850aa326421ed3e25f23b4c071blrn@chromium.org int start_reg, 3467516f05132429850aa326421ed3e25f23b4c071blrn@chromium.org Label* on_no_match) { 347c53e10d01c5495df3896b9d318910b58688c6929kmillikin@chromium.org Label fallthrough; 348c53e10d01c5495df3896b9d318910b58688c6929kmillikin@chromium.org Label success; 349c53e10d01c5495df3896b9d318910b58688c6929kmillikin@chromium.org 350c53e10d01c5495df3896b9d318910b58688c6929kmillikin@chromium.org // Find length of back-referenced capture. 351c53e10d01c5495df3896b9d318910b58688c6929kmillikin@chromium.org __ lw(a0, register_location(start_reg)); 352c53e10d01c5495df3896b9d318910b58688c6929kmillikin@chromium.org __ lw(a1, register_location(start_reg + 1)); 353c53e10d01c5495df3896b9d318910b58688c6929kmillikin@chromium.org __ Subu(a1, a1, a0); // Length to check. 354c53e10d01c5495df3896b9d318910b58688c6929kmillikin@chromium.org // Succeed on empty capture (including no capture). 355c53e10d01c5495df3896b9d318910b58688c6929kmillikin@chromium.org __ Branch(&fallthrough, eq, a1, Operand(zero_reg)); 356c53e10d01c5495df3896b9d318910b58688c6929kmillikin@chromium.org 357c53e10d01c5495df3896b9d318910b58688c6929kmillikin@chromium.org __ Addu(t5, a1, current_input_offset()); 358c53e10d01c5495df3896b9d318910b58688c6929kmillikin@chromium.org // Check that there are enough characters left in the input. 359c53e10d01c5495df3896b9d318910b58688c6929kmillikin@chromium.org BranchOrBacktrack(on_no_match, gt, t5, Operand(zero_reg)); 360c53e10d01c5495df3896b9d318910b58688c6929kmillikin@chromium.org 361c53e10d01c5495df3896b9d318910b58688c6929kmillikin@chromium.org // Compute pointers to match string and capture string. 362c53e10d01c5495df3896b9d318910b58688c6929kmillikin@chromium.org __ Addu(a0, a0, Operand(end_of_input_address())); 363c53e10d01c5495df3896b9d318910b58688c6929kmillikin@chromium.org __ Addu(a2, end_of_input_address(), Operand(current_input_offset())); 364c53e10d01c5495df3896b9d318910b58688c6929kmillikin@chromium.org __ Addu(a1, a1, Operand(a0)); 365c53e10d01c5495df3896b9d318910b58688c6929kmillikin@chromium.org 366c53e10d01c5495df3896b9d318910b58688c6929kmillikin@chromium.org Label loop; 367c53e10d01c5495df3896b9d318910b58688c6929kmillikin@chromium.org __ bind(&loop); 3682c81ceb7f1e1ccf5f304be0646f4c1375941a7f2machenbach@chromium.org if (mode_ == LATIN1) { 369c53e10d01c5495df3896b9d318910b58688c6929kmillikin@chromium.org __ lbu(a3, MemOperand(a0, 0)); 370c53e10d01c5495df3896b9d318910b58688c6929kmillikin@chromium.org __ addiu(a0, a0, char_size()); 371c53e10d01c5495df3896b9d318910b58688c6929kmillikin@chromium.org __ lbu(t0, MemOperand(a2, 0)); 372c53e10d01c5495df3896b9d318910b58688c6929kmillikin@chromium.org __ addiu(a2, a2, char_size()); 373c53e10d01c5495df3896b9d318910b58688c6929kmillikin@chromium.org } else { 374e3c177a423baa3c30225c4e422b6f6c76d38b951machenbach@chromium.org DCHECK(mode_ == UC16); 375c53e10d01c5495df3896b9d318910b58688c6929kmillikin@chromium.org __ lhu(a3, MemOperand(a0, 0)); 376c53e10d01c5495df3896b9d318910b58688c6929kmillikin@chromium.org __ addiu(a0, a0, char_size()); 377c53e10d01c5495df3896b9d318910b58688c6929kmillikin@chromium.org __ lhu(t0, MemOperand(a2, 0)); 378c53e10d01c5495df3896b9d318910b58688c6929kmillikin@chromium.org __ addiu(a2, a2, char_size()); 379c53e10d01c5495df3896b9d318910b58688c6929kmillikin@chromium.org } 380c53e10d01c5495df3896b9d318910b58688c6929kmillikin@chromium.org BranchOrBacktrack(on_no_match, ne, a3, Operand(t0)); 381c53e10d01c5495df3896b9d318910b58688c6929kmillikin@chromium.org __ Branch(&loop, lt, a0, Operand(a1)); 382c53e10d01c5495df3896b9d318910b58688c6929kmillikin@chromium.org 383c53e10d01c5495df3896b9d318910b58688c6929kmillikin@chromium.org // Move current character position to position after match. 384c53e10d01c5495df3896b9d318910b58688c6929kmillikin@chromium.org __ Subu(current_input_offset(), a2, end_of_input_address()); 385c53e10d01c5495df3896b9d318910b58688c6929kmillikin@chromium.org __ bind(&fallthrough); 3867516f05132429850aa326421ed3e25f23b4c071blrn@chromium.org} 3877516f05132429850aa326421ed3e25f23b4c071blrn@chromium.org 3887516f05132429850aa326421ed3e25f23b4c071blrn@chromium.org 3897516f05132429850aa326421ed3e25f23b4c071blrn@chromium.orgvoid RegExpMacroAssemblerMIPS::CheckNotCharacter(uint32_t c, 39028faa982749c4aa9c090939453dea14bb118f613jkummerow@chromium.org Label* on_not_equal) { 391c53e10d01c5495df3896b9d318910b58688c6929kmillikin@chromium.org BranchOrBacktrack(on_not_equal, ne, current_character(), Operand(c)); 3927516f05132429850aa326421ed3e25f23b4c071blrn@chromium.org} 3937516f05132429850aa326421ed3e25f23b4c071blrn@chromium.org 3947516f05132429850aa326421ed3e25f23b4c071blrn@chromium.org 3957516f05132429850aa326421ed3e25f23b4c071blrn@chromium.orgvoid RegExpMacroAssemblerMIPS::CheckCharacterAfterAnd(uint32_t c, 39628faa982749c4aa9c090939453dea14bb118f613jkummerow@chromium.org uint32_t mask, 39728faa982749c4aa9c090939453dea14bb118f613jkummerow@chromium.org Label* on_equal) { 398c53e10d01c5495df3896b9d318910b58688c6929kmillikin@chromium.org __ And(a0, current_character(), Operand(mask)); 39928faa982749c4aa9c090939453dea14bb118f613jkummerow@chromium.org Operand rhs = (c == 0) ? Operand(zero_reg) : Operand(c); 40028faa982749c4aa9c090939453dea14bb118f613jkummerow@chromium.org BranchOrBacktrack(on_equal, eq, a0, rhs); 4017516f05132429850aa326421ed3e25f23b4c071blrn@chromium.org} 4027516f05132429850aa326421ed3e25f23b4c071blrn@chromium.org 4037516f05132429850aa326421ed3e25f23b4c071blrn@chromium.org 4047516f05132429850aa326421ed3e25f23b4c071blrn@chromium.orgvoid RegExpMacroAssemblerMIPS::CheckNotCharacterAfterAnd(uint32_t c, 40528faa982749c4aa9c090939453dea14bb118f613jkummerow@chromium.org uint32_t mask, 40628faa982749c4aa9c090939453dea14bb118f613jkummerow@chromium.org Label* on_not_equal) { 407c53e10d01c5495df3896b9d318910b58688c6929kmillikin@chromium.org __ And(a0, current_character(), Operand(mask)); 40828faa982749c4aa9c090939453dea14bb118f613jkummerow@chromium.org Operand rhs = (c == 0) ? Operand(zero_reg) : Operand(c); 40928faa982749c4aa9c090939453dea14bb118f613jkummerow@chromium.org BranchOrBacktrack(on_not_equal, ne, a0, rhs); 4107516f05132429850aa326421ed3e25f23b4c071blrn@chromium.org} 4117516f05132429850aa326421ed3e25f23b4c071blrn@chromium.org 4127516f05132429850aa326421ed3e25f23b4c071blrn@chromium.org 4137516f05132429850aa326421ed3e25f23b4c071blrn@chromium.orgvoid RegExpMacroAssemblerMIPS::CheckNotCharacterAfterMinusAnd( 4147516f05132429850aa326421ed3e25f23b4c071blrn@chromium.org uc16 c, 4157516f05132429850aa326421ed3e25f23b4c071blrn@chromium.org uc16 minus, 4167516f05132429850aa326421ed3e25f23b4c071blrn@chromium.org uc16 mask, 4177516f05132429850aa326421ed3e25f23b4c071blrn@chromium.org Label* on_not_equal) { 418e3c177a423baa3c30225c4e422b6f6c76d38b951machenbach@chromium.org DCHECK(minus < String::kMaxUtf16CodeUnit); 419ed49e965b5cafa35395084dbfb79f4e07930f10ferik.corry@gmail.com __ Subu(a0, current_character(), Operand(minus)); 420ed49e965b5cafa35395084dbfb79f4e07930f10ferik.corry@gmail.com __ And(a0, a0, Operand(mask)); 421ed49e965b5cafa35395084dbfb79f4e07930f10ferik.corry@gmail.com BranchOrBacktrack(on_not_equal, ne, a0, Operand(c)); 4227516f05132429850aa326421ed3e25f23b4c071blrn@chromium.org} 4237516f05132429850aa326421ed3e25f23b4c071blrn@chromium.org 4247516f05132429850aa326421ed3e25f23b4c071blrn@chromium.org 4257d10be581a91ab5eefa1139ff0b86c64ac8f6e59fschneider@chromium.orgvoid RegExpMacroAssemblerMIPS::CheckCharacterInRange( 4267d10be581a91ab5eefa1139ff0b86c64ac8f6e59fschneider@chromium.org uc16 from, 4277d10be581a91ab5eefa1139ff0b86c64ac8f6e59fschneider@chromium.org uc16 to, 4287d10be581a91ab5eefa1139ff0b86c64ac8f6e59fschneider@chromium.org Label* on_in_range) { 4297d10be581a91ab5eefa1139ff0b86c64ac8f6e59fschneider@chromium.org __ Subu(a0, current_character(), Operand(from)); 4307d10be581a91ab5eefa1139ff0b86c64ac8f6e59fschneider@chromium.org // Unsigned lower-or-same condition. 4317d10be581a91ab5eefa1139ff0b86c64ac8f6e59fschneider@chromium.org BranchOrBacktrack(on_in_range, ls, a0, Operand(to - from)); 4327d10be581a91ab5eefa1139ff0b86c64ac8f6e59fschneider@chromium.org} 4337d10be581a91ab5eefa1139ff0b86c64ac8f6e59fschneider@chromium.org 4347d10be581a91ab5eefa1139ff0b86c64ac8f6e59fschneider@chromium.org 4357d10be581a91ab5eefa1139ff0b86c64ac8f6e59fschneider@chromium.orgvoid RegExpMacroAssemblerMIPS::CheckCharacterNotInRange( 4367d10be581a91ab5eefa1139ff0b86c64ac8f6e59fschneider@chromium.org uc16 from, 4377d10be581a91ab5eefa1139ff0b86c64ac8f6e59fschneider@chromium.org uc16 to, 4387d10be581a91ab5eefa1139ff0b86c64ac8f6e59fschneider@chromium.org Label* on_not_in_range) { 4397d10be581a91ab5eefa1139ff0b86c64ac8f6e59fschneider@chromium.org __ Subu(a0, current_character(), Operand(from)); 4407d10be581a91ab5eefa1139ff0b86c64ac8f6e59fschneider@chromium.org // Unsigned higher condition. 4417d10be581a91ab5eefa1139ff0b86c64ac8f6e59fschneider@chromium.org BranchOrBacktrack(on_not_in_range, hi, a0, Operand(to - from)); 4427d10be581a91ab5eefa1139ff0b86c64ac8f6e59fschneider@chromium.org} 4437d10be581a91ab5eefa1139ff0b86c64ac8f6e59fschneider@chromium.org 4447d10be581a91ab5eefa1139ff0b86c64ac8f6e59fschneider@chromium.org 4457d10be581a91ab5eefa1139ff0b86c64ac8f6e59fschneider@chromium.orgvoid RegExpMacroAssemblerMIPS::CheckBitInTable( 4467d10be581a91ab5eefa1139ff0b86c64ac8f6e59fschneider@chromium.org Handle<ByteArray> table, 4477d10be581a91ab5eefa1139ff0b86c64ac8f6e59fschneider@chromium.org Label* on_bit_set) { 4487d10be581a91ab5eefa1139ff0b86c64ac8f6e59fschneider@chromium.org __ li(a0, Operand(table)); 4492c81ceb7f1e1ccf5f304be0646f4c1375941a7f2machenbach@chromium.org if (mode_ != LATIN1 || kTableMask != String::kMaxOneByteCharCode) { 4507d10be581a91ab5eefa1139ff0b86c64ac8f6e59fschneider@chromium.org __ And(a1, current_character(), Operand(kTableSize - 1)); 4517d10be581a91ab5eefa1139ff0b86c64ac8f6e59fschneider@chromium.org __ Addu(a0, a0, a1); 4527d10be581a91ab5eefa1139ff0b86c64ac8f6e59fschneider@chromium.org } else { 4537d10be581a91ab5eefa1139ff0b86c64ac8f6e59fschneider@chromium.org __ Addu(a0, a0, current_character()); 4547d10be581a91ab5eefa1139ff0b86c64ac8f6e59fschneider@chromium.org } 4557d10be581a91ab5eefa1139ff0b86c64ac8f6e59fschneider@chromium.org 4567d10be581a91ab5eefa1139ff0b86c64ac8f6e59fschneider@chromium.org __ lbu(a0, FieldMemOperand(a0, ByteArray::kHeaderSize)); 4577d10be581a91ab5eefa1139ff0b86c64ac8f6e59fschneider@chromium.org BranchOrBacktrack(on_bit_set, ne, a0, Operand(zero_reg)); 4587d10be581a91ab5eefa1139ff0b86c64ac8f6e59fschneider@chromium.org} 4597d10be581a91ab5eefa1139ff0b86c64ac8f6e59fschneider@chromium.org 4607d10be581a91ab5eefa1139ff0b86c64ac8f6e59fschneider@chromium.org 4617516f05132429850aa326421ed3e25f23b4c071blrn@chromium.orgbool RegExpMacroAssemblerMIPS::CheckSpecialCharacterClass(uc16 type, 46228faa982749c4aa9c090939453dea14bb118f613jkummerow@chromium.org Label* on_no_match) { 463c53e10d01c5495df3896b9d318910b58688c6929kmillikin@chromium.org // Range checks (c in min..max) are generally implemented by an unsigned 464c53e10d01c5495df3896b9d318910b58688c6929kmillikin@chromium.org // (c - min) <= (max - min) check. 465c53e10d01c5495df3896b9d318910b58688c6929kmillikin@chromium.org switch (type) { 466c53e10d01c5495df3896b9d318910b58688c6929kmillikin@chromium.org case 's': 467c53e10d01c5495df3896b9d318910b58688c6929kmillikin@chromium.org // Match space-characters. 4682c81ceb7f1e1ccf5f304be0646f4c1375941a7f2machenbach@chromium.org if (mode_ == LATIN1) { 4696e196bfaf0e555d0c835390bb6ebc0a74484491dulan@chromium.org // One byte space characters are '\t'..'\r', ' ' and \u00a0. 470c53e10d01c5495df3896b9d318910b58688c6929kmillikin@chromium.org Label success; 471c53e10d01c5495df3896b9d318910b58688c6929kmillikin@chromium.org __ Branch(&success, eq, current_character(), Operand(' ')); 472c53e10d01c5495df3896b9d318910b58688c6929kmillikin@chromium.org // Check range 0x09..0x0d. 473c53e10d01c5495df3896b9d318910b58688c6929kmillikin@chromium.org __ Subu(a0, current_character(), Operand('\t')); 4746e196bfaf0e555d0c835390bb6ebc0a74484491dulan@chromium.org __ Branch(&success, ls, a0, Operand('\r' - '\t')); 4756e196bfaf0e555d0c835390bb6ebc0a74484491dulan@chromium.org // \u00a0 (NBSP). 4766e196bfaf0e555d0c835390bb6ebc0a74484491dulan@chromium.org BranchOrBacktrack(on_no_match, ne, a0, Operand(0x00a0 - '\t')); 477c53e10d01c5495df3896b9d318910b58688c6929kmillikin@chromium.org __ bind(&success); 478c53e10d01c5495df3896b9d318910b58688c6929kmillikin@chromium.org return true; 479c53e10d01c5495df3896b9d318910b58688c6929kmillikin@chromium.org } 480c53e10d01c5495df3896b9d318910b58688c6929kmillikin@chromium.org return false; 481c53e10d01c5495df3896b9d318910b58688c6929kmillikin@chromium.org case 'S': 4826e196bfaf0e555d0c835390bb6ebc0a74484491dulan@chromium.org // The emitted code for generic character classes is good enough. 483c53e10d01c5495df3896b9d318910b58688c6929kmillikin@chromium.org return false; 484c53e10d01c5495df3896b9d318910b58688c6929kmillikin@chromium.org case 'd': 4852c81ceb7f1e1ccf5f304be0646f4c1375941a7f2machenbach@chromium.org // Match Latin1 digits ('0'..'9'). 486c53e10d01c5495df3896b9d318910b58688c6929kmillikin@chromium.org __ Subu(a0, current_character(), Operand('0')); 487c53e10d01c5495df3896b9d318910b58688c6929kmillikin@chromium.org BranchOrBacktrack(on_no_match, hi, a0, Operand('9' - '0')); 488c53e10d01c5495df3896b9d318910b58688c6929kmillikin@chromium.org return true; 489c53e10d01c5495df3896b9d318910b58688c6929kmillikin@chromium.org case 'D': 4902c81ceb7f1e1ccf5f304be0646f4c1375941a7f2machenbach@chromium.org // Match non Latin1-digits. 491c53e10d01c5495df3896b9d318910b58688c6929kmillikin@chromium.org __ Subu(a0, current_character(), Operand('0')); 492c53e10d01c5495df3896b9d318910b58688c6929kmillikin@chromium.org BranchOrBacktrack(on_no_match, ls, a0, Operand('9' - '0')); 493c53e10d01c5495df3896b9d318910b58688c6929kmillikin@chromium.org return true; 494c53e10d01c5495df3896b9d318910b58688c6929kmillikin@chromium.org case '.': { 495c53e10d01c5495df3896b9d318910b58688c6929kmillikin@chromium.org // Match non-newlines (not 0x0a('\n'), 0x0d('\r'), 0x2028 and 0x2029). 496c53e10d01c5495df3896b9d318910b58688c6929kmillikin@chromium.org __ Xor(a0, current_character(), Operand(0x01)); 497c53e10d01c5495df3896b9d318910b58688c6929kmillikin@chromium.org // See if current character is '\n'^1 or '\r'^1, i.e., 0x0b or 0x0c. 498c53e10d01c5495df3896b9d318910b58688c6929kmillikin@chromium.org __ Subu(a0, a0, Operand(0x0b)); 499c53e10d01c5495df3896b9d318910b58688c6929kmillikin@chromium.org BranchOrBacktrack(on_no_match, ls, a0, Operand(0x0c - 0x0b)); 500c53e10d01c5495df3896b9d318910b58688c6929kmillikin@chromium.org if (mode_ == UC16) { 501c53e10d01c5495df3896b9d318910b58688c6929kmillikin@chromium.org // Compare original value to 0x2028 and 0x2029, using the already 502c53e10d01c5495df3896b9d318910b58688c6929kmillikin@chromium.org // computed (current_char ^ 0x01 - 0x0b). I.e., check for 503c53e10d01c5495df3896b9d318910b58688c6929kmillikin@chromium.org // 0x201d (0x2028 - 0x0b) or 0x201e. 504c53e10d01c5495df3896b9d318910b58688c6929kmillikin@chromium.org __ Subu(a0, a0, Operand(0x2028 - 0x0b)); 505c53e10d01c5495df3896b9d318910b58688c6929kmillikin@chromium.org BranchOrBacktrack(on_no_match, ls, a0, Operand(1)); 506c53e10d01c5495df3896b9d318910b58688c6929kmillikin@chromium.org } 507c53e10d01c5495df3896b9d318910b58688c6929kmillikin@chromium.org return true; 508c53e10d01c5495df3896b9d318910b58688c6929kmillikin@chromium.org } 509c53e10d01c5495df3896b9d318910b58688c6929kmillikin@chromium.org case 'n': { 510c53e10d01c5495df3896b9d318910b58688c6929kmillikin@chromium.org // Match newlines (0x0a('\n'), 0x0d('\r'), 0x2028 and 0x2029). 511c53e10d01c5495df3896b9d318910b58688c6929kmillikin@chromium.org __ Xor(a0, current_character(), Operand(0x01)); 512c53e10d01c5495df3896b9d318910b58688c6929kmillikin@chromium.org // See if current character is '\n'^1 or '\r'^1, i.e., 0x0b or 0x0c. 513c53e10d01c5495df3896b9d318910b58688c6929kmillikin@chromium.org __ Subu(a0, a0, Operand(0x0b)); 5142c81ceb7f1e1ccf5f304be0646f4c1375941a7f2machenbach@chromium.org if (mode_ == LATIN1) { 515c53e10d01c5495df3896b9d318910b58688c6929kmillikin@chromium.org BranchOrBacktrack(on_no_match, hi, a0, Operand(0x0c - 0x0b)); 516c53e10d01c5495df3896b9d318910b58688c6929kmillikin@chromium.org } else { 517c53e10d01c5495df3896b9d318910b58688c6929kmillikin@chromium.org Label done; 518c53e10d01c5495df3896b9d318910b58688c6929kmillikin@chromium.org BranchOrBacktrack(&done, ls, a0, Operand(0x0c - 0x0b)); 519c53e10d01c5495df3896b9d318910b58688c6929kmillikin@chromium.org // Compare original value to 0x2028 and 0x2029, using the already 520c53e10d01c5495df3896b9d318910b58688c6929kmillikin@chromium.org // computed (current_char ^ 0x01 - 0x0b). I.e., check for 521c53e10d01c5495df3896b9d318910b58688c6929kmillikin@chromium.org // 0x201d (0x2028 - 0x0b) or 0x201e. 522c53e10d01c5495df3896b9d318910b58688c6929kmillikin@chromium.org __ Subu(a0, a0, Operand(0x2028 - 0x0b)); 523c53e10d01c5495df3896b9d318910b58688c6929kmillikin@chromium.org BranchOrBacktrack(on_no_match, hi, a0, Operand(1)); 524c53e10d01c5495df3896b9d318910b58688c6929kmillikin@chromium.org __ bind(&done); 525c53e10d01c5495df3896b9d318910b58688c6929kmillikin@chromium.org } 526c53e10d01c5495df3896b9d318910b58688c6929kmillikin@chromium.org return true; 527c53e10d01c5495df3896b9d318910b58688c6929kmillikin@chromium.org } 528c53e10d01c5495df3896b9d318910b58688c6929kmillikin@chromium.org case 'w': { 5292c81ceb7f1e1ccf5f304be0646f4c1375941a7f2machenbach@chromium.org if (mode_ != LATIN1) { 5302c81ceb7f1e1ccf5f304be0646f4c1375941a7f2machenbach@chromium.org // Table is 256 entries, so all Latin1 characters can be tested. 531c53e10d01c5495df3896b9d318910b58688c6929kmillikin@chromium.org BranchOrBacktrack(on_no_match, hi, current_character(), Operand('z')); 532c53e10d01c5495df3896b9d318910b58688c6929kmillikin@chromium.org } 533c53e10d01c5495df3896b9d318910b58688c6929kmillikin@chromium.org ExternalReference map = ExternalReference::re_word_character_map(); 534c53e10d01c5495df3896b9d318910b58688c6929kmillikin@chromium.org __ li(a0, Operand(map)); 535c53e10d01c5495df3896b9d318910b58688c6929kmillikin@chromium.org __ Addu(a0, a0, current_character()); 536c53e10d01c5495df3896b9d318910b58688c6929kmillikin@chromium.org __ lbu(a0, MemOperand(a0, 0)); 537c53e10d01c5495df3896b9d318910b58688c6929kmillikin@chromium.org BranchOrBacktrack(on_no_match, eq, a0, Operand(zero_reg)); 538c53e10d01c5495df3896b9d318910b58688c6929kmillikin@chromium.org return true; 539c53e10d01c5495df3896b9d318910b58688c6929kmillikin@chromium.org } 540c53e10d01c5495df3896b9d318910b58688c6929kmillikin@chromium.org case 'W': { 541c53e10d01c5495df3896b9d318910b58688c6929kmillikin@chromium.org Label done; 5422c81ceb7f1e1ccf5f304be0646f4c1375941a7f2machenbach@chromium.org if (mode_ != LATIN1) { 5432c81ceb7f1e1ccf5f304be0646f4c1375941a7f2machenbach@chromium.org // Table is 256 entries, so all Latin1 characters can be tested. 544c53e10d01c5495df3896b9d318910b58688c6929kmillikin@chromium.org __ Branch(&done, hi, current_character(), Operand('z')); 545c53e10d01c5495df3896b9d318910b58688c6929kmillikin@chromium.org } 546c53e10d01c5495df3896b9d318910b58688c6929kmillikin@chromium.org ExternalReference map = ExternalReference::re_word_character_map(); 547c53e10d01c5495df3896b9d318910b58688c6929kmillikin@chromium.org __ li(a0, Operand(map)); 548c53e10d01c5495df3896b9d318910b58688c6929kmillikin@chromium.org __ Addu(a0, a0, current_character()); 549c53e10d01c5495df3896b9d318910b58688c6929kmillikin@chromium.org __ lbu(a0, MemOperand(a0, 0)); 550c53e10d01c5495df3896b9d318910b58688c6929kmillikin@chromium.org BranchOrBacktrack(on_no_match, ne, a0, Operand(zero_reg)); 5512c81ceb7f1e1ccf5f304be0646f4c1375941a7f2machenbach@chromium.org if (mode_ != LATIN1) { 552c53e10d01c5495df3896b9d318910b58688c6929kmillikin@chromium.org __ bind(&done); 553c53e10d01c5495df3896b9d318910b58688c6929kmillikin@chromium.org } 554c53e10d01c5495df3896b9d318910b58688c6929kmillikin@chromium.org return true; 555c53e10d01c5495df3896b9d318910b58688c6929kmillikin@chromium.org } 556c53e10d01c5495df3896b9d318910b58688c6929kmillikin@chromium.org case '*': 557c53e10d01c5495df3896b9d318910b58688c6929kmillikin@chromium.org // Match any character. 558c53e10d01c5495df3896b9d318910b58688c6929kmillikin@chromium.org return true; 559c53e10d01c5495df3896b9d318910b58688c6929kmillikin@chromium.org // No custom implementation (yet): s(UC16), S(UC16). 560c53e10d01c5495df3896b9d318910b58688c6929kmillikin@chromium.org default: 561c53e10d01c5495df3896b9d318910b58688c6929kmillikin@chromium.org return false; 562c53e10d01c5495df3896b9d318910b58688c6929kmillikin@chromium.org } 5637516f05132429850aa326421ed3e25f23b4c071blrn@chromium.org} 5647516f05132429850aa326421ed3e25f23b4c071blrn@chromium.org 5657516f05132429850aa326421ed3e25f23b4c071blrn@chromium.org 5667516f05132429850aa326421ed3e25f23b4c071blrn@chromium.orgvoid RegExpMacroAssemblerMIPS::Fail() { 567c53e10d01c5495df3896b9d318910b58688c6929kmillikin@chromium.org __ li(v0, Operand(FAILURE)); 568c53e10d01c5495df3896b9d318910b58688c6929kmillikin@chromium.org __ jmp(&exit_label_); 5697516f05132429850aa326421ed3e25f23b4c071blrn@chromium.org} 5707516f05132429850aa326421ed3e25f23b4c071blrn@chromium.org 5717516f05132429850aa326421ed3e25f23b4c071blrn@chromium.org 57283a4728861129dc263ded92157f3e6389f851f19karlklose@chromium.orgHandle<HeapObject> RegExpMacroAssemblerMIPS::GetCode(Handle<String> source) { 573777db6f4249aa13ebf060a0d290d34936a41eb75jkummerow@chromium.org Label return_v0; 574c53e10d01c5495df3896b9d318910b58688c6929kmillikin@chromium.org if (masm_->has_exception()) { 575c53e10d01c5495df3896b9d318910b58688c6929kmillikin@chromium.org // If the code gets corrupted due to long regular expressions and lack of 576c53e10d01c5495df3896b9d318910b58688c6929kmillikin@chromium.org // space on trampolines, an internal exception flag is set. If this case 577c53e10d01c5495df3896b9d318910b58688c6929kmillikin@chromium.org // is detected, we will jump into exit sequence right away. 578c53e10d01c5495df3896b9d318910b58688c6929kmillikin@chromium.org __ bind_to(&entry_label_, internal_failure_label_.pos()); 579c53e10d01c5495df3896b9d318910b58688c6929kmillikin@chromium.org } else { 580c53e10d01c5495df3896b9d318910b58688c6929kmillikin@chromium.org // Finalize code - write the entry point code now we know how many 581c53e10d01c5495df3896b9d318910b58688c6929kmillikin@chromium.org // registers we need. 582c53e10d01c5495df3896b9d318910b58688c6929kmillikin@chromium.org 583c53e10d01c5495df3896b9d318910b58688c6929kmillikin@chromium.org // Entry code: 584c53e10d01c5495df3896b9d318910b58688c6929kmillikin@chromium.org __ bind(&entry_label_); 585c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com 586c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com // Tell the system that we have a stack frame. Because the type is MANUAL, 587c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com // no is generated. 588c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com FrameScope scope(masm_, StackFrame::MANUAL); 589c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com 590c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com // Actually emit code to start a new stack frame. 591c53e10d01c5495df3896b9d318910b58688c6929kmillikin@chromium.org // Push arguments 592c53e10d01c5495df3896b9d318910b58688c6929kmillikin@chromium.org // Save callee-save registers. 593c53e10d01c5495df3896b9d318910b58688c6929kmillikin@chromium.org // Start new stack frame. 594c53e10d01c5495df3896b9d318910b58688c6929kmillikin@chromium.org // Store link register in existing stack-cell. 595c53e10d01c5495df3896b9d318910b58688c6929kmillikin@chromium.org // Order here should correspond to order of offset constants in header file. 596c53e10d01c5495df3896b9d318910b58688c6929kmillikin@chromium.org RegList registers_to_retain = s0.bit() | s1.bit() | s2.bit() | 597c53e10d01c5495df3896b9d318910b58688c6929kmillikin@chromium.org s3.bit() | s4.bit() | s5.bit() | s6.bit() | s7.bit() | fp.bit(); 598c53e10d01c5495df3896b9d318910b58688c6929kmillikin@chromium.org RegList argument_registers = a0.bit() | a1.bit() | a2.bit() | a3.bit(); 599c53e10d01c5495df3896b9d318910b58688c6929kmillikin@chromium.org __ MultiPush(argument_registers | registers_to_retain | ra.bit()); 600c53e10d01c5495df3896b9d318910b58688c6929kmillikin@chromium.org // Set frame pointer in space for it if this is not a direct call 601c53e10d01c5495df3896b9d318910b58688c6929kmillikin@chromium.org // from generated code. 602c53e10d01c5495df3896b9d318910b58688c6929kmillikin@chromium.org __ Addu(frame_pointer(), sp, Operand(4 * kPointerSize)); 603777db6f4249aa13ebf060a0d290d34936a41eb75jkummerow@chromium.org __ mov(a0, zero_reg); 604777db6f4249aa13ebf060a0d290d34936a41eb75jkummerow@chromium.org __ push(a0); // Make room for success counter and initialize it to 0. 605c53e10d01c5495df3896b9d318910b58688c6929kmillikin@chromium.org __ push(a0); // Make room for "position - 1" constant (value irrelevant). 606c53e10d01c5495df3896b9d318910b58688c6929kmillikin@chromium.org 607c53e10d01c5495df3896b9d318910b58688c6929kmillikin@chromium.org // Check if we have space on the stack for registers. 608c53e10d01c5495df3896b9d318910b58688c6929kmillikin@chromium.org Label stack_limit_hit; 609c53e10d01c5495df3896b9d318910b58688c6929kmillikin@chromium.org Label stack_ok; 610c53e10d01c5495df3896b9d318910b58688c6929kmillikin@chromium.org 611c53e10d01c5495df3896b9d318910b58688c6929kmillikin@chromium.org ExternalReference stack_limit = 612c53e10d01c5495df3896b9d318910b58688c6929kmillikin@chromium.org ExternalReference::address_of_stack_limit(masm_->isolate()); 613c53e10d01c5495df3896b9d318910b58688c6929kmillikin@chromium.org __ li(a0, Operand(stack_limit)); 614c53e10d01c5495df3896b9d318910b58688c6929kmillikin@chromium.org __ lw(a0, MemOperand(a0)); 615c53e10d01c5495df3896b9d318910b58688c6929kmillikin@chromium.org __ Subu(a0, sp, a0); 616c53e10d01c5495df3896b9d318910b58688c6929kmillikin@chromium.org // Handle it if the stack pointer is already below the stack limit. 617c53e10d01c5495df3896b9d318910b58688c6929kmillikin@chromium.org __ Branch(&stack_limit_hit, le, a0, Operand(zero_reg)); 618c53e10d01c5495df3896b9d318910b58688c6929kmillikin@chromium.org // Check if there is room for the variable number of registers above 619c53e10d01c5495df3896b9d318910b58688c6929kmillikin@chromium.org // the stack limit. 620c53e10d01c5495df3896b9d318910b58688c6929kmillikin@chromium.org __ Branch(&stack_ok, hs, a0, Operand(num_registers_ * kPointerSize)); 621c53e10d01c5495df3896b9d318910b58688c6929kmillikin@chromium.org // Exit with OutOfMemory exception. There is not enough space on the stack 622c53e10d01c5495df3896b9d318910b58688c6929kmillikin@chromium.org // for our working registers. 623c53e10d01c5495df3896b9d318910b58688c6929kmillikin@chromium.org __ li(v0, Operand(EXCEPTION)); 624777db6f4249aa13ebf060a0d290d34936a41eb75jkummerow@chromium.org __ jmp(&return_v0); 625c53e10d01c5495df3896b9d318910b58688c6929kmillikin@chromium.org 626c53e10d01c5495df3896b9d318910b58688c6929kmillikin@chromium.org __ bind(&stack_limit_hit); 627c53e10d01c5495df3896b9d318910b58688c6929kmillikin@chromium.org CallCheckStackGuardState(a0); 628c53e10d01c5495df3896b9d318910b58688c6929kmillikin@chromium.org // If returned value is non-zero, we exit with the returned value as result. 629777db6f4249aa13ebf060a0d290d34936a41eb75jkummerow@chromium.org __ Branch(&return_v0, ne, v0, Operand(zero_reg)); 630c53e10d01c5495df3896b9d318910b58688c6929kmillikin@chromium.org 631c53e10d01c5495df3896b9d318910b58688c6929kmillikin@chromium.org __ bind(&stack_ok); 632c53e10d01c5495df3896b9d318910b58688c6929kmillikin@chromium.org // Allocate space on stack for registers. 633c53e10d01c5495df3896b9d318910b58688c6929kmillikin@chromium.org __ Subu(sp, sp, Operand(num_registers_ * kPointerSize)); 634c53e10d01c5495df3896b9d318910b58688c6929kmillikin@chromium.org // Load string end. 635c53e10d01c5495df3896b9d318910b58688c6929kmillikin@chromium.org __ lw(end_of_input_address(), MemOperand(frame_pointer(), kInputEnd)); 636c53e10d01c5495df3896b9d318910b58688c6929kmillikin@chromium.org // Load input start. 637c53e10d01c5495df3896b9d318910b58688c6929kmillikin@chromium.org __ lw(a0, MemOperand(frame_pointer(), kInputStart)); 638c53e10d01c5495df3896b9d318910b58688c6929kmillikin@chromium.org // Find negative length (offset of start relative to end). 639c53e10d01c5495df3896b9d318910b58688c6929kmillikin@chromium.org __ Subu(current_input_offset(), a0, end_of_input_address()); 640c53e10d01c5495df3896b9d318910b58688c6929kmillikin@chromium.org // Set a0 to address of char before start of the input string 641c53e10d01c5495df3896b9d318910b58688c6929kmillikin@chromium.org // (effectively string position -1). 642c53e10d01c5495df3896b9d318910b58688c6929kmillikin@chromium.org __ lw(a1, MemOperand(frame_pointer(), kStartIndex)); 643c53e10d01c5495df3896b9d318910b58688c6929kmillikin@chromium.org __ Subu(a0, current_input_offset(), Operand(char_size())); 644c53e10d01c5495df3896b9d318910b58688c6929kmillikin@chromium.org __ sll(t5, a1, (mode_ == UC16) ? 1 : 0); 645c53e10d01c5495df3896b9d318910b58688c6929kmillikin@chromium.org __ Subu(a0, a0, t5); 646c53e10d01c5495df3896b9d318910b58688c6929kmillikin@chromium.org // Store this value in a local variable, for use when clearing 647c53e10d01c5495df3896b9d318910b58688c6929kmillikin@chromium.org // position registers. 648c53e10d01c5495df3896b9d318910b58688c6929kmillikin@chromium.org __ sw(a0, MemOperand(frame_pointer(), kInputStartMinusOne)); 649c53e10d01c5495df3896b9d318910b58688c6929kmillikin@chromium.org 650777db6f4249aa13ebf060a0d290d34936a41eb75jkummerow@chromium.org // Initialize code pointer register 651777db6f4249aa13ebf060a0d290d34936a41eb75jkummerow@chromium.org __ li(code_pointer(), Operand(masm_->CodeObject()), CONSTANT_SIZE); 652777db6f4249aa13ebf060a0d290d34936a41eb75jkummerow@chromium.org 653777db6f4249aa13ebf060a0d290d34936a41eb75jkummerow@chromium.org Label load_char_start_regexp, start_regexp; 654777db6f4249aa13ebf060a0d290d34936a41eb75jkummerow@chromium.org // Load newline if index is at start, previous character otherwise. 655777db6f4249aa13ebf060a0d290d34936a41eb75jkummerow@chromium.org __ Branch(&load_char_start_regexp, ne, a1, Operand(zero_reg)); 656777db6f4249aa13ebf060a0d290d34936a41eb75jkummerow@chromium.org __ li(current_character(), Operand('\n')); 657777db6f4249aa13ebf060a0d290d34936a41eb75jkummerow@chromium.org __ jmp(&start_regexp); 658777db6f4249aa13ebf060a0d290d34936a41eb75jkummerow@chromium.org 659777db6f4249aa13ebf060a0d290d34936a41eb75jkummerow@chromium.org // Global regexp restarts matching here. 660777db6f4249aa13ebf060a0d290d34936a41eb75jkummerow@chromium.org __ bind(&load_char_start_regexp); 661777db6f4249aa13ebf060a0d290d34936a41eb75jkummerow@chromium.org // Load previous char as initial value of current character register. 662777db6f4249aa13ebf060a0d290d34936a41eb75jkummerow@chromium.org LoadCurrentCharacterUnchecked(-1, 1); 663777db6f4249aa13ebf060a0d290d34936a41eb75jkummerow@chromium.org __ bind(&start_regexp); 664c53e10d01c5495df3896b9d318910b58688c6929kmillikin@chromium.org 665777db6f4249aa13ebf060a0d290d34936a41eb75jkummerow@chromium.org // Initialize on-stack registers. 666c53e10d01c5495df3896b9d318910b58688c6929kmillikin@chromium.org if (num_saved_registers_ > 0) { // Always is, if generated from a regexp. 667c53e10d01c5495df3896b9d318910b58688c6929kmillikin@chromium.org // Fill saved registers with initial value = start offset - 1. 668777db6f4249aa13ebf060a0d290d34936a41eb75jkummerow@chromium.org if (num_saved_registers_ > 8) { 669777db6f4249aa13ebf060a0d290d34936a41eb75jkummerow@chromium.org // Address of register 0. 670777db6f4249aa13ebf060a0d290d34936a41eb75jkummerow@chromium.org __ Addu(a1, frame_pointer(), Operand(kRegisterZero)); 671777db6f4249aa13ebf060a0d290d34936a41eb75jkummerow@chromium.org __ li(a2, Operand(num_saved_registers_)); 672777db6f4249aa13ebf060a0d290d34936a41eb75jkummerow@chromium.org Label init_loop; 673777db6f4249aa13ebf060a0d290d34936a41eb75jkummerow@chromium.org __ bind(&init_loop); 674777db6f4249aa13ebf060a0d290d34936a41eb75jkummerow@chromium.org __ sw(a0, MemOperand(a1)); 675777db6f4249aa13ebf060a0d290d34936a41eb75jkummerow@chromium.org __ Addu(a1, a1, Operand(-kPointerSize)); 676777db6f4249aa13ebf060a0d290d34936a41eb75jkummerow@chromium.org __ Subu(a2, a2, Operand(1)); 677777db6f4249aa13ebf060a0d290d34936a41eb75jkummerow@chromium.org __ Branch(&init_loop, ne, a2, Operand(zero_reg)); 678777db6f4249aa13ebf060a0d290d34936a41eb75jkummerow@chromium.org } else { 679777db6f4249aa13ebf060a0d290d34936a41eb75jkummerow@chromium.org for (int i = 0; i < num_saved_registers_; i++) { 680777db6f4249aa13ebf060a0d290d34936a41eb75jkummerow@chromium.org __ sw(a0, register_location(i)); 681777db6f4249aa13ebf060a0d290d34936a41eb75jkummerow@chromium.org } 682777db6f4249aa13ebf060a0d290d34936a41eb75jkummerow@chromium.org } 683c53e10d01c5495df3896b9d318910b58688c6929kmillikin@chromium.org } 684c53e10d01c5495df3896b9d318910b58688c6929kmillikin@chromium.org 685c53e10d01c5495df3896b9d318910b58688c6929kmillikin@chromium.org // Initialize backtrack stack pointer. 686c53e10d01c5495df3896b9d318910b58688c6929kmillikin@chromium.org __ lw(backtrack_stackpointer(), MemOperand(frame_pointer(), kStackHighEnd)); 687777db6f4249aa13ebf060a0d290d34936a41eb75jkummerow@chromium.org 688c53e10d01c5495df3896b9d318910b58688c6929kmillikin@chromium.org __ jmp(&start_label_); 689c53e10d01c5495df3896b9d318910b58688c6929kmillikin@chromium.org 690c53e10d01c5495df3896b9d318910b58688c6929kmillikin@chromium.org 691c53e10d01c5495df3896b9d318910b58688c6929kmillikin@chromium.org // Exit code: 692c53e10d01c5495df3896b9d318910b58688c6929kmillikin@chromium.org if (success_label_.is_linked()) { 693c53e10d01c5495df3896b9d318910b58688c6929kmillikin@chromium.org // Save captures when successful. 694c53e10d01c5495df3896b9d318910b58688c6929kmillikin@chromium.org __ bind(&success_label_); 695c53e10d01c5495df3896b9d318910b58688c6929kmillikin@chromium.org if (num_saved_registers_ > 0) { 696c53e10d01c5495df3896b9d318910b58688c6929kmillikin@chromium.org // Copy captures to output. 697c53e10d01c5495df3896b9d318910b58688c6929kmillikin@chromium.org __ lw(a1, MemOperand(frame_pointer(), kInputStart)); 698c53e10d01c5495df3896b9d318910b58688c6929kmillikin@chromium.org __ lw(a0, MemOperand(frame_pointer(), kRegisterOutput)); 699c53e10d01c5495df3896b9d318910b58688c6929kmillikin@chromium.org __ lw(a2, MemOperand(frame_pointer(), kStartIndex)); 700c53e10d01c5495df3896b9d318910b58688c6929kmillikin@chromium.org __ Subu(a1, end_of_input_address(), a1); 701c53e10d01c5495df3896b9d318910b58688c6929kmillikin@chromium.org // a1 is length of input in bytes. 702c53e10d01c5495df3896b9d318910b58688c6929kmillikin@chromium.org if (mode_ == UC16) { 703c53e10d01c5495df3896b9d318910b58688c6929kmillikin@chromium.org __ srl(a1, a1, 1); 704c53e10d01c5495df3896b9d318910b58688c6929kmillikin@chromium.org } 705c53e10d01c5495df3896b9d318910b58688c6929kmillikin@chromium.org // a1 is length of input in characters. 706c53e10d01c5495df3896b9d318910b58688c6929kmillikin@chromium.org __ Addu(a1, a1, Operand(a2)); 707c53e10d01c5495df3896b9d318910b58688c6929kmillikin@chromium.org // a1 is length of string in characters. 708c53e10d01c5495df3896b9d318910b58688c6929kmillikin@chromium.org 709e3c177a423baa3c30225c4e422b6f6c76d38b951machenbach@chromium.org DCHECK_EQ(0, num_saved_registers_ % 2); 710c53e10d01c5495df3896b9d318910b58688c6929kmillikin@chromium.org // Always an even number of capture registers. This allows us to 711c53e10d01c5495df3896b9d318910b58688c6929kmillikin@chromium.org // unroll the loop once to add an operation between a load of a register 712c53e10d01c5495df3896b9d318910b58688c6929kmillikin@chromium.org // and the following use of that register. 713c53e10d01c5495df3896b9d318910b58688c6929kmillikin@chromium.org for (int i = 0; i < num_saved_registers_; i += 2) { 714c53e10d01c5495df3896b9d318910b58688c6929kmillikin@chromium.org __ lw(a2, register_location(i)); 715c53e10d01c5495df3896b9d318910b58688c6929kmillikin@chromium.org __ lw(a3, register_location(i + 1)); 7167028c05c1c71b9d5c5fe1bca01f2461d17a2dda7mmassi@chromium.org if (i == 0 && global_with_zero_length_check()) { 717777db6f4249aa13ebf060a0d290d34936a41eb75jkummerow@chromium.org // Keep capture start in a4 for the zero-length check later. 718777db6f4249aa13ebf060a0d290d34936a41eb75jkummerow@chromium.org __ mov(t7, a2); 719777db6f4249aa13ebf060a0d290d34936a41eb75jkummerow@chromium.org } 720c53e10d01c5495df3896b9d318910b58688c6929kmillikin@chromium.org if (mode_ == UC16) { 721c53e10d01c5495df3896b9d318910b58688c6929kmillikin@chromium.org __ sra(a2, a2, 1); 722c53e10d01c5495df3896b9d318910b58688c6929kmillikin@chromium.org __ Addu(a2, a2, a1); 723c53e10d01c5495df3896b9d318910b58688c6929kmillikin@chromium.org __ sra(a3, a3, 1); 724c53e10d01c5495df3896b9d318910b58688c6929kmillikin@chromium.org __ Addu(a3, a3, a1); 725c53e10d01c5495df3896b9d318910b58688c6929kmillikin@chromium.org } else { 726c53e10d01c5495df3896b9d318910b58688c6929kmillikin@chromium.org __ Addu(a2, a1, Operand(a2)); 727c53e10d01c5495df3896b9d318910b58688c6929kmillikin@chromium.org __ Addu(a3, a1, Operand(a3)); 728c53e10d01c5495df3896b9d318910b58688c6929kmillikin@chromium.org } 729c53e10d01c5495df3896b9d318910b58688c6929kmillikin@chromium.org __ sw(a2, MemOperand(a0)); 730c53e10d01c5495df3896b9d318910b58688c6929kmillikin@chromium.org __ Addu(a0, a0, kPointerSize); 731c53e10d01c5495df3896b9d318910b58688c6929kmillikin@chromium.org __ sw(a3, MemOperand(a0)); 732c53e10d01c5495df3896b9d318910b58688c6929kmillikin@chromium.org __ Addu(a0, a0, kPointerSize); 733c53e10d01c5495df3896b9d318910b58688c6929kmillikin@chromium.org } 734c53e10d01c5495df3896b9d318910b58688c6929kmillikin@chromium.org } 735777db6f4249aa13ebf060a0d290d34936a41eb75jkummerow@chromium.org 736777db6f4249aa13ebf060a0d290d34936a41eb75jkummerow@chromium.org if (global()) { 737777db6f4249aa13ebf060a0d290d34936a41eb75jkummerow@chromium.org // Restart matching if the regular expression is flagged as global. 738777db6f4249aa13ebf060a0d290d34936a41eb75jkummerow@chromium.org __ lw(a0, MemOperand(frame_pointer(), kSuccessfulCaptures)); 739777db6f4249aa13ebf060a0d290d34936a41eb75jkummerow@chromium.org __ lw(a1, MemOperand(frame_pointer(), kNumOutputRegisters)); 740777db6f4249aa13ebf060a0d290d34936a41eb75jkummerow@chromium.org __ lw(a2, MemOperand(frame_pointer(), kRegisterOutput)); 741777db6f4249aa13ebf060a0d290d34936a41eb75jkummerow@chromium.org // Increment success counter. 742777db6f4249aa13ebf060a0d290d34936a41eb75jkummerow@chromium.org __ Addu(a0, a0, 1); 743777db6f4249aa13ebf060a0d290d34936a41eb75jkummerow@chromium.org __ sw(a0, MemOperand(frame_pointer(), kSuccessfulCaptures)); 744777db6f4249aa13ebf060a0d290d34936a41eb75jkummerow@chromium.org // Capture results have been stored, so the number of remaining global 745777db6f4249aa13ebf060a0d290d34936a41eb75jkummerow@chromium.org // output registers is reduced by the number of stored captures. 746777db6f4249aa13ebf060a0d290d34936a41eb75jkummerow@chromium.org __ Subu(a1, a1, num_saved_registers_); 747777db6f4249aa13ebf060a0d290d34936a41eb75jkummerow@chromium.org // Check whether we have enough room for another set of capture results. 748777db6f4249aa13ebf060a0d290d34936a41eb75jkummerow@chromium.org __ mov(v0, a0); 749777db6f4249aa13ebf060a0d290d34936a41eb75jkummerow@chromium.org __ Branch(&return_v0, lt, a1, Operand(num_saved_registers_)); 750777db6f4249aa13ebf060a0d290d34936a41eb75jkummerow@chromium.org 751777db6f4249aa13ebf060a0d290d34936a41eb75jkummerow@chromium.org __ sw(a1, MemOperand(frame_pointer(), kNumOutputRegisters)); 752777db6f4249aa13ebf060a0d290d34936a41eb75jkummerow@chromium.org // Advance the location for output. 753777db6f4249aa13ebf060a0d290d34936a41eb75jkummerow@chromium.org __ Addu(a2, a2, num_saved_registers_ * kPointerSize); 754777db6f4249aa13ebf060a0d290d34936a41eb75jkummerow@chromium.org __ sw(a2, MemOperand(frame_pointer(), kRegisterOutput)); 755777db6f4249aa13ebf060a0d290d34936a41eb75jkummerow@chromium.org 756777db6f4249aa13ebf060a0d290d34936a41eb75jkummerow@chromium.org // Prepare a0 to initialize registers with its value in the next run. 757777db6f4249aa13ebf060a0d290d34936a41eb75jkummerow@chromium.org __ lw(a0, MemOperand(frame_pointer(), kInputStartMinusOne)); 7587028c05c1c71b9d5c5fe1bca01f2461d17a2dda7mmassi@chromium.org 7597028c05c1c71b9d5c5fe1bca01f2461d17a2dda7mmassi@chromium.org if (global_with_zero_length_check()) { 7607028c05c1c71b9d5c5fe1bca01f2461d17a2dda7mmassi@chromium.org // Special case for zero-length matches. 7617028c05c1c71b9d5c5fe1bca01f2461d17a2dda7mmassi@chromium.org // t7: capture start index 7627028c05c1c71b9d5c5fe1bca01f2461d17a2dda7mmassi@chromium.org // Not a zero-length match, restart. 7637028c05c1c71b9d5c5fe1bca01f2461d17a2dda7mmassi@chromium.org __ Branch( 7647028c05c1c71b9d5c5fe1bca01f2461d17a2dda7mmassi@chromium.org &load_char_start_regexp, ne, current_input_offset(), Operand(t7)); 7657028c05c1c71b9d5c5fe1bca01f2461d17a2dda7mmassi@chromium.org // Offset from the end is zero if we already reached the end. 7667028c05c1c71b9d5c5fe1bca01f2461d17a2dda7mmassi@chromium.org __ Branch(&exit_label_, eq, current_input_offset(), 7677028c05c1c71b9d5c5fe1bca01f2461d17a2dda7mmassi@chromium.org Operand(zero_reg)); 7687028c05c1c71b9d5c5fe1bca01f2461d17a2dda7mmassi@chromium.org // Advance current position after a zero-length match. 7697028c05c1c71b9d5c5fe1bca01f2461d17a2dda7mmassi@chromium.org __ Addu(current_input_offset(), 7707028c05c1c71b9d5c5fe1bca01f2461d17a2dda7mmassi@chromium.org current_input_offset(), 7717028c05c1c71b9d5c5fe1bca01f2461d17a2dda7mmassi@chromium.org Operand((mode_ == UC16) ? 2 : 1)); 7727028c05c1c71b9d5c5fe1bca01f2461d17a2dda7mmassi@chromium.org } 7737028c05c1c71b9d5c5fe1bca01f2461d17a2dda7mmassi@chromium.org 774777db6f4249aa13ebf060a0d290d34936a41eb75jkummerow@chromium.org __ Branch(&load_char_start_regexp); 775777db6f4249aa13ebf060a0d290d34936a41eb75jkummerow@chromium.org } else { 776777db6f4249aa13ebf060a0d290d34936a41eb75jkummerow@chromium.org __ li(v0, Operand(SUCCESS)); 777777db6f4249aa13ebf060a0d290d34936a41eb75jkummerow@chromium.org } 778c53e10d01c5495df3896b9d318910b58688c6929kmillikin@chromium.org } 779c53e10d01c5495df3896b9d318910b58688c6929kmillikin@chromium.org // Exit and return v0. 780c53e10d01c5495df3896b9d318910b58688c6929kmillikin@chromium.org __ bind(&exit_label_); 781777db6f4249aa13ebf060a0d290d34936a41eb75jkummerow@chromium.org if (global()) { 782777db6f4249aa13ebf060a0d290d34936a41eb75jkummerow@chromium.org __ lw(v0, MemOperand(frame_pointer(), kSuccessfulCaptures)); 783777db6f4249aa13ebf060a0d290d34936a41eb75jkummerow@chromium.org } 784777db6f4249aa13ebf060a0d290d34936a41eb75jkummerow@chromium.org 785777db6f4249aa13ebf060a0d290d34936a41eb75jkummerow@chromium.org __ bind(&return_v0); 786c53e10d01c5495df3896b9d318910b58688c6929kmillikin@chromium.org // Skip sp past regexp registers and local variables.. 787c53e10d01c5495df3896b9d318910b58688c6929kmillikin@chromium.org __ mov(sp, frame_pointer()); 788c53e10d01c5495df3896b9d318910b58688c6929kmillikin@chromium.org // Restore registers s0..s7 and return (restoring ra to pc). 789c53e10d01c5495df3896b9d318910b58688c6929kmillikin@chromium.org __ MultiPop(registers_to_retain | ra.bit()); 790c53e10d01c5495df3896b9d318910b58688c6929kmillikin@chromium.org __ Ret(); 791c53e10d01c5495df3896b9d318910b58688c6929kmillikin@chromium.org 792c53e10d01c5495df3896b9d318910b58688c6929kmillikin@chromium.org // Backtrack code (branch target for conditional backtracks). 793c53e10d01c5495df3896b9d318910b58688c6929kmillikin@chromium.org if (backtrack_label_.is_linked()) { 794c53e10d01c5495df3896b9d318910b58688c6929kmillikin@chromium.org __ bind(&backtrack_label_); 795c53e10d01c5495df3896b9d318910b58688c6929kmillikin@chromium.org Backtrack(); 796c53e10d01c5495df3896b9d318910b58688c6929kmillikin@chromium.org } 797c53e10d01c5495df3896b9d318910b58688c6929kmillikin@chromium.org 798c53e10d01c5495df3896b9d318910b58688c6929kmillikin@chromium.org Label exit_with_exception; 799c53e10d01c5495df3896b9d318910b58688c6929kmillikin@chromium.org 800c53e10d01c5495df3896b9d318910b58688c6929kmillikin@chromium.org // Preempt-code. 801c53e10d01c5495df3896b9d318910b58688c6929kmillikin@chromium.org if (check_preempt_label_.is_linked()) { 802c53e10d01c5495df3896b9d318910b58688c6929kmillikin@chromium.org SafeCallTarget(&check_preempt_label_); 803c53e10d01c5495df3896b9d318910b58688c6929kmillikin@chromium.org // Put regexp engine registers on stack. 804c53e10d01c5495df3896b9d318910b58688c6929kmillikin@chromium.org RegList regexp_registers_to_retain = current_input_offset().bit() | 805c53e10d01c5495df3896b9d318910b58688c6929kmillikin@chromium.org current_character().bit() | backtrack_stackpointer().bit(); 806c53e10d01c5495df3896b9d318910b58688c6929kmillikin@chromium.org __ MultiPush(regexp_registers_to_retain); 807c53e10d01c5495df3896b9d318910b58688c6929kmillikin@chromium.org CallCheckStackGuardState(a0); 808c53e10d01c5495df3896b9d318910b58688c6929kmillikin@chromium.org __ MultiPop(regexp_registers_to_retain); 809c53e10d01c5495df3896b9d318910b58688c6929kmillikin@chromium.org // If returning non-zero, we should end execution with the given 810c53e10d01c5495df3896b9d318910b58688c6929kmillikin@chromium.org // result as return value. 811777db6f4249aa13ebf060a0d290d34936a41eb75jkummerow@chromium.org __ Branch(&return_v0, ne, v0, Operand(zero_reg)); 812c53e10d01c5495df3896b9d318910b58688c6929kmillikin@chromium.org 813c53e10d01c5495df3896b9d318910b58688c6929kmillikin@chromium.org // String might have moved: Reload end of string from frame. 814c53e10d01c5495df3896b9d318910b58688c6929kmillikin@chromium.org __ lw(end_of_input_address(), MemOperand(frame_pointer(), kInputEnd)); 81588aa058bdadfa79ae2836d12d6dd2d1c28aa490cdanno@chromium.org __ li(code_pointer(), Operand(masm_->CodeObject()), CONSTANT_SIZE); 816c53e10d01c5495df3896b9d318910b58688c6929kmillikin@chromium.org SafeReturn(); 817c53e10d01c5495df3896b9d318910b58688c6929kmillikin@chromium.org } 818c53e10d01c5495df3896b9d318910b58688c6929kmillikin@chromium.org 819c53e10d01c5495df3896b9d318910b58688c6929kmillikin@chromium.org // Backtrack stack overflow code. 820c53e10d01c5495df3896b9d318910b58688c6929kmillikin@chromium.org if (stack_overflow_label_.is_linked()) { 821c53e10d01c5495df3896b9d318910b58688c6929kmillikin@chromium.org SafeCallTarget(&stack_overflow_label_); 822c53e10d01c5495df3896b9d318910b58688c6929kmillikin@chromium.org // Reached if the backtrack-stack limit has been hit. 823c53e10d01c5495df3896b9d318910b58688c6929kmillikin@chromium.org // Put regexp engine registers on stack first. 824c53e10d01c5495df3896b9d318910b58688c6929kmillikin@chromium.org RegList regexp_registers = current_input_offset().bit() | 825c53e10d01c5495df3896b9d318910b58688c6929kmillikin@chromium.org current_character().bit(); 826c53e10d01c5495df3896b9d318910b58688c6929kmillikin@chromium.org __ MultiPush(regexp_registers); 827c53e10d01c5495df3896b9d318910b58688c6929kmillikin@chromium.org Label grow_failed; 828c53e10d01c5495df3896b9d318910b58688c6929kmillikin@chromium.org // Call GrowStack(backtrack_stackpointer(), &stack_base) 829c53e10d01c5495df3896b9d318910b58688c6929kmillikin@chromium.org static const int num_arguments = 3; 830c53e10d01c5495df3896b9d318910b58688c6929kmillikin@chromium.org __ PrepareCallCFunction(num_arguments, a0); 831c53e10d01c5495df3896b9d318910b58688c6929kmillikin@chromium.org __ mov(a0, backtrack_stackpointer()); 832c53e10d01c5495df3896b9d318910b58688c6929kmillikin@chromium.org __ Addu(a1, frame_pointer(), Operand(kStackHighEnd)); 83332d7dbafe29be06cec1edd36c31fbe2865c799f4ulan@chromium.org __ li(a2, Operand(ExternalReference::isolate_address(masm_->isolate()))); 834c53e10d01c5495df3896b9d318910b58688c6929kmillikin@chromium.org ExternalReference grow_stack = 835c53e10d01c5495df3896b9d318910b58688c6929kmillikin@chromium.org ExternalReference::re_grow_stack(masm_->isolate()); 836c53e10d01c5495df3896b9d318910b58688c6929kmillikin@chromium.org __ CallCFunction(grow_stack, num_arguments); 837c53e10d01c5495df3896b9d318910b58688c6929kmillikin@chromium.org // Restore regexp registers. 838c53e10d01c5495df3896b9d318910b58688c6929kmillikin@chromium.org __ MultiPop(regexp_registers); 839c53e10d01c5495df3896b9d318910b58688c6929kmillikin@chromium.org // If return NULL, we have failed to grow the stack, and 840c53e10d01c5495df3896b9d318910b58688c6929kmillikin@chromium.org // must exit with a stack-overflow exception. 841c53e10d01c5495df3896b9d318910b58688c6929kmillikin@chromium.org __ Branch(&exit_with_exception, eq, v0, Operand(zero_reg)); 842c53e10d01c5495df3896b9d318910b58688c6929kmillikin@chromium.org // Otherwise use return value as new stack pointer. 843c53e10d01c5495df3896b9d318910b58688c6929kmillikin@chromium.org __ mov(backtrack_stackpointer(), v0); 844c53e10d01c5495df3896b9d318910b58688c6929kmillikin@chromium.org // Restore saved registers and continue. 84588aa058bdadfa79ae2836d12d6dd2d1c28aa490cdanno@chromium.org __ li(code_pointer(), Operand(masm_->CodeObject()), CONSTANT_SIZE); 846c53e10d01c5495df3896b9d318910b58688c6929kmillikin@chromium.org __ lw(end_of_input_address(), MemOperand(frame_pointer(), kInputEnd)); 847c53e10d01c5495df3896b9d318910b58688c6929kmillikin@chromium.org SafeReturn(); 848c53e10d01c5495df3896b9d318910b58688c6929kmillikin@chromium.org } 849c53e10d01c5495df3896b9d318910b58688c6929kmillikin@chromium.org 850c53e10d01c5495df3896b9d318910b58688c6929kmillikin@chromium.org if (exit_with_exception.is_linked()) { 851c53e10d01c5495df3896b9d318910b58688c6929kmillikin@chromium.org // If any of the code above needed to exit with an exception. 852c53e10d01c5495df3896b9d318910b58688c6929kmillikin@chromium.org __ bind(&exit_with_exception); 853c53e10d01c5495df3896b9d318910b58688c6929kmillikin@chromium.org // Exit with Result EXCEPTION(-1) to signal thrown exception. 854c53e10d01c5495df3896b9d318910b58688c6929kmillikin@chromium.org __ li(v0, Operand(EXCEPTION)); 855777db6f4249aa13ebf060a0d290d34936a41eb75jkummerow@chromium.org __ jmp(&return_v0); 856c53e10d01c5495df3896b9d318910b58688c6929kmillikin@chromium.org } 857c53e10d01c5495df3896b9d318910b58688c6929kmillikin@chromium.org } 858c53e10d01c5495df3896b9d318910b58688c6929kmillikin@chromium.org 859c53e10d01c5495df3896b9d318910b58688c6929kmillikin@chromium.org CodeDesc code_desc; 860c53e10d01c5495df3896b9d318910b58688c6929kmillikin@chromium.org masm_->GetCode(&code_desc); 861d4be0f0c0edfc0a0b46e745055c3dc497c0ffcb5verwaest@chromium.org Handle<Code> code = isolate()->factory()->NewCode( 862d4be0f0c0edfc0a0b46e745055c3dc497c0ffcb5verwaest@chromium.org code_desc, Code::ComputeFlags(Code::REGEXP), masm_->CodeObject()); 863e97852de34e44a479f092bd2449134e707cd9cf1dslomov@chromium.org LOG(masm_->isolate(), RegExpCodeCreateEvent(*code, *source)); 864c53e10d01c5495df3896b9d318910b58688c6929kmillikin@chromium.org return Handle<HeapObject>::cast(code); 8657516f05132429850aa326421ed3e25f23b4c071blrn@chromium.org} 8667516f05132429850aa326421ed3e25f23b4c071blrn@chromium.org 8677516f05132429850aa326421ed3e25f23b4c071blrn@chromium.org 8687516f05132429850aa326421ed3e25f23b4c071blrn@chromium.orgvoid RegExpMacroAssemblerMIPS::GoTo(Label* to) { 869c53e10d01c5495df3896b9d318910b58688c6929kmillikin@chromium.org if (to == NULL) { 870c53e10d01c5495df3896b9d318910b58688c6929kmillikin@chromium.org Backtrack(); 871c53e10d01c5495df3896b9d318910b58688c6929kmillikin@chromium.org return; 872c53e10d01c5495df3896b9d318910b58688c6929kmillikin@chromium.org } 873c53e10d01c5495df3896b9d318910b58688c6929kmillikin@chromium.org __ jmp(to); 874c53e10d01c5495df3896b9d318910b58688c6929kmillikin@chromium.org return; 8757516f05132429850aa326421ed3e25f23b4c071blrn@chromium.org} 8767516f05132429850aa326421ed3e25f23b4c071blrn@chromium.org 8777516f05132429850aa326421ed3e25f23b4c071blrn@chromium.org 8787516f05132429850aa326421ed3e25f23b4c071blrn@chromium.orgvoid RegExpMacroAssemblerMIPS::IfRegisterGE(int reg, 87928faa982749c4aa9c090939453dea14bb118f613jkummerow@chromium.org int comparand, 88028faa982749c4aa9c090939453dea14bb118f613jkummerow@chromium.org Label* if_ge) { 8817516f05132429850aa326421ed3e25f23b4c071blrn@chromium.org __ lw(a0, register_location(reg)); 8827516f05132429850aa326421ed3e25f23b4c071blrn@chromium.org BranchOrBacktrack(if_ge, ge, a0, Operand(comparand)); 8837516f05132429850aa326421ed3e25f23b4c071blrn@chromium.org} 8847516f05132429850aa326421ed3e25f23b4c071blrn@chromium.org 8857516f05132429850aa326421ed3e25f23b4c071blrn@chromium.org 8867516f05132429850aa326421ed3e25f23b4c071blrn@chromium.orgvoid RegExpMacroAssemblerMIPS::IfRegisterLT(int reg, 88728faa982749c4aa9c090939453dea14bb118f613jkummerow@chromium.org int comparand, 88828faa982749c4aa9c090939453dea14bb118f613jkummerow@chromium.org Label* if_lt) { 889c53e10d01c5495df3896b9d318910b58688c6929kmillikin@chromium.org __ lw(a0, register_location(reg)); 890c53e10d01c5495df3896b9d318910b58688c6929kmillikin@chromium.org BranchOrBacktrack(if_lt, lt, a0, Operand(comparand)); 8917516f05132429850aa326421ed3e25f23b4c071blrn@chromium.org} 8927516f05132429850aa326421ed3e25f23b4c071blrn@chromium.org 8937516f05132429850aa326421ed3e25f23b4c071blrn@chromium.org 8947516f05132429850aa326421ed3e25f23b4c071blrn@chromium.orgvoid RegExpMacroAssemblerMIPS::IfRegisterEqPos(int reg, 89528faa982749c4aa9c090939453dea14bb118f613jkummerow@chromium.org Label* if_eq) { 896c53e10d01c5495df3896b9d318910b58688c6929kmillikin@chromium.org __ lw(a0, register_location(reg)); 897c53e10d01c5495df3896b9d318910b58688c6929kmillikin@chromium.org BranchOrBacktrack(if_eq, eq, a0, Operand(current_input_offset())); 8987516f05132429850aa326421ed3e25f23b4c071blrn@chromium.org} 8997516f05132429850aa326421ed3e25f23b4c071blrn@chromium.org 9007516f05132429850aa326421ed3e25f23b4c071blrn@chromium.org 9017516f05132429850aa326421ed3e25f23b4c071blrn@chromium.orgRegExpMacroAssembler::IrregexpImplementation 9027516f05132429850aa326421ed3e25f23b4c071blrn@chromium.org RegExpMacroAssemblerMIPS::Implementation() { 9037516f05132429850aa326421ed3e25f23b4c071blrn@chromium.org return kMIPSImplementation; 9047516f05132429850aa326421ed3e25f23b4c071blrn@chromium.org} 9057516f05132429850aa326421ed3e25f23b4c071blrn@chromium.org 9067516f05132429850aa326421ed3e25f23b4c071blrn@chromium.org 9077516f05132429850aa326421ed3e25f23b4c071blrn@chromium.orgvoid RegExpMacroAssemblerMIPS::LoadCurrentCharacter(int cp_offset, 90828faa982749c4aa9c090939453dea14bb118f613jkummerow@chromium.org Label* on_end_of_input, 90928faa982749c4aa9c090939453dea14bb118f613jkummerow@chromium.org bool check_bounds, 91028faa982749c4aa9c090939453dea14bb118f613jkummerow@chromium.org int characters) { 911e3c177a423baa3c30225c4e422b6f6c76d38b951machenbach@chromium.org DCHECK(cp_offset >= -1); // ^ and \b can look behind one character. 912e3c177a423baa3c30225c4e422b6f6c76d38b951machenbach@chromium.org DCHECK(cp_offset < (1<<30)); // Be sane! (And ensure negation works). 913c53e10d01c5495df3896b9d318910b58688c6929kmillikin@chromium.org if (check_bounds) { 914c53e10d01c5495df3896b9d318910b58688c6929kmillikin@chromium.org CheckPosition(cp_offset + characters - 1, on_end_of_input); 915c53e10d01c5495df3896b9d318910b58688c6929kmillikin@chromium.org } 916c53e10d01c5495df3896b9d318910b58688c6929kmillikin@chromium.org LoadCurrentCharacterUnchecked(cp_offset, characters); 9177516f05132429850aa326421ed3e25f23b4c071blrn@chromium.org} 9187516f05132429850aa326421ed3e25f23b4c071blrn@chromium.org 9197516f05132429850aa326421ed3e25f23b4c071blrn@chromium.org 9207516f05132429850aa326421ed3e25f23b4c071blrn@chromium.orgvoid RegExpMacroAssemblerMIPS::PopCurrentPosition() { 921c53e10d01c5495df3896b9d318910b58688c6929kmillikin@chromium.org Pop(current_input_offset()); 9227516f05132429850aa326421ed3e25f23b4c071blrn@chromium.org} 9237516f05132429850aa326421ed3e25f23b4c071blrn@chromium.org 9247516f05132429850aa326421ed3e25f23b4c071blrn@chromium.org 9257516f05132429850aa326421ed3e25f23b4c071blrn@chromium.orgvoid RegExpMacroAssemblerMIPS::PopRegister(int register_index) { 926c53e10d01c5495df3896b9d318910b58688c6929kmillikin@chromium.org Pop(a0); 927c53e10d01c5495df3896b9d318910b58688c6929kmillikin@chromium.org __ sw(a0, register_location(register_index)); 9287516f05132429850aa326421ed3e25f23b4c071blrn@chromium.org} 9297516f05132429850aa326421ed3e25f23b4c071blrn@chromium.org 9307516f05132429850aa326421ed3e25f23b4c071blrn@chromium.org 9317516f05132429850aa326421ed3e25f23b4c071blrn@chromium.orgvoid RegExpMacroAssemblerMIPS::PushBacktrack(Label* label) { 932c53e10d01c5495df3896b9d318910b58688c6929kmillikin@chromium.org if (label->is_bound()) { 933c53e10d01c5495df3896b9d318910b58688c6929kmillikin@chromium.org int target = label->pos(); 934c53e10d01c5495df3896b9d318910b58688c6929kmillikin@chromium.org __ li(a0, Operand(target + Code::kHeaderSize - kHeapObjectTag)); 935c53e10d01c5495df3896b9d318910b58688c6929kmillikin@chromium.org } else { 9367bd87f0fe09b5d7c12de8f1db0bdb759dc4130acjkummerow@chromium.org Assembler::BlockTrampolinePoolScope block_trampoline_pool(masm_); 937c53e10d01c5495df3896b9d318910b58688c6929kmillikin@chromium.org Label after_constant; 938c53e10d01c5495df3896b9d318910b58688c6929kmillikin@chromium.org __ Branch(&after_constant); 939c53e10d01c5495df3896b9d318910b58688c6929kmillikin@chromium.org int offset = masm_->pc_offset(); 940c53e10d01c5495df3896b9d318910b58688c6929kmillikin@chromium.org int cp_offset = offset + Code::kHeaderSize - kHeapObjectTag; 941c53e10d01c5495df3896b9d318910b58688c6929kmillikin@chromium.org __ emit(0); 942c53e10d01c5495df3896b9d318910b58688c6929kmillikin@chromium.org masm_->label_at_put(label, offset); 943c53e10d01c5495df3896b9d318910b58688c6929kmillikin@chromium.org __ bind(&after_constant); 944c53e10d01c5495df3896b9d318910b58688c6929kmillikin@chromium.org if (is_int16(cp_offset)) { 945c53e10d01c5495df3896b9d318910b58688c6929kmillikin@chromium.org __ lw(a0, MemOperand(code_pointer(), cp_offset)); 946c53e10d01c5495df3896b9d318910b58688c6929kmillikin@chromium.org } else { 947c53e10d01c5495df3896b9d318910b58688c6929kmillikin@chromium.org __ Addu(a0, code_pointer(), cp_offset); 948c53e10d01c5495df3896b9d318910b58688c6929kmillikin@chromium.org __ lw(a0, MemOperand(a0, 0)); 949c53e10d01c5495df3896b9d318910b58688c6929kmillikin@chromium.org } 950c53e10d01c5495df3896b9d318910b58688c6929kmillikin@chromium.org } 951c53e10d01c5495df3896b9d318910b58688c6929kmillikin@chromium.org Push(a0); 952c53e10d01c5495df3896b9d318910b58688c6929kmillikin@chromium.org CheckStackLimit(); 9537516f05132429850aa326421ed3e25f23b4c071blrn@chromium.org} 9547516f05132429850aa326421ed3e25f23b4c071blrn@chromium.org 9557516f05132429850aa326421ed3e25f23b4c071blrn@chromium.org 9567516f05132429850aa326421ed3e25f23b4c071blrn@chromium.orgvoid RegExpMacroAssemblerMIPS::PushCurrentPosition() { 9577516f05132429850aa326421ed3e25f23b4c071blrn@chromium.org Push(current_input_offset()); 9587516f05132429850aa326421ed3e25f23b4c071blrn@chromium.org} 9597516f05132429850aa326421ed3e25f23b4c071blrn@chromium.org 9607516f05132429850aa326421ed3e25f23b4c071blrn@chromium.org 9617516f05132429850aa326421ed3e25f23b4c071blrn@chromium.orgvoid RegExpMacroAssemblerMIPS::PushRegister(int register_index, 96228faa982749c4aa9c090939453dea14bb118f613jkummerow@chromium.org StackCheckFlag check_stack_limit) { 963c53e10d01c5495df3896b9d318910b58688c6929kmillikin@chromium.org __ lw(a0, register_location(register_index)); 964c53e10d01c5495df3896b9d318910b58688c6929kmillikin@chromium.org Push(a0); 965c53e10d01c5495df3896b9d318910b58688c6929kmillikin@chromium.org if (check_stack_limit) CheckStackLimit(); 9667516f05132429850aa326421ed3e25f23b4c071blrn@chromium.org} 9677516f05132429850aa326421ed3e25f23b4c071blrn@chromium.org 9687516f05132429850aa326421ed3e25f23b4c071blrn@chromium.org 9697516f05132429850aa326421ed3e25f23b4c071blrn@chromium.orgvoid RegExpMacroAssemblerMIPS::ReadCurrentPositionFromRegister(int reg) { 970c53e10d01c5495df3896b9d318910b58688c6929kmillikin@chromium.org __ lw(current_input_offset(), register_location(reg)); 9717516f05132429850aa326421ed3e25f23b4c071blrn@chromium.org} 9727516f05132429850aa326421ed3e25f23b4c071blrn@chromium.org 9737516f05132429850aa326421ed3e25f23b4c071blrn@chromium.org 9747516f05132429850aa326421ed3e25f23b4c071blrn@chromium.orgvoid RegExpMacroAssemblerMIPS::ReadStackPointerFromRegister(int reg) { 975c53e10d01c5495df3896b9d318910b58688c6929kmillikin@chromium.org __ lw(backtrack_stackpointer(), register_location(reg)); 976c53e10d01c5495df3896b9d318910b58688c6929kmillikin@chromium.org __ lw(a0, MemOperand(frame_pointer(), kStackHighEnd)); 977c53e10d01c5495df3896b9d318910b58688c6929kmillikin@chromium.org __ Addu(backtrack_stackpointer(), backtrack_stackpointer(), Operand(a0)); 9787516f05132429850aa326421ed3e25f23b4c071blrn@chromium.org} 9797516f05132429850aa326421ed3e25f23b4c071blrn@chromium.org 9807516f05132429850aa326421ed3e25f23b4c071blrn@chromium.org 9817516f05132429850aa326421ed3e25f23b4c071blrn@chromium.orgvoid RegExpMacroAssemblerMIPS::SetCurrentPositionFromEnd(int by) { 982c53e10d01c5495df3896b9d318910b58688c6929kmillikin@chromium.org Label after_position; 983c53e10d01c5495df3896b9d318910b58688c6929kmillikin@chromium.org __ Branch(&after_position, 984c53e10d01c5495df3896b9d318910b58688c6929kmillikin@chromium.org ge, 985c53e10d01c5495df3896b9d318910b58688c6929kmillikin@chromium.org current_input_offset(), 986c53e10d01c5495df3896b9d318910b58688c6929kmillikin@chromium.org Operand(-by * char_size())); 987c53e10d01c5495df3896b9d318910b58688c6929kmillikin@chromium.org __ li(current_input_offset(), -by * char_size()); 988c53e10d01c5495df3896b9d318910b58688c6929kmillikin@chromium.org // On RegExp code entry (where this operation is used), the character before 989c53e10d01c5495df3896b9d318910b58688c6929kmillikin@chromium.org // the current position is expected to be already loaded. 990c53e10d01c5495df3896b9d318910b58688c6929kmillikin@chromium.org // We have advanced the position, so it's safe to read backwards. 991c53e10d01c5495df3896b9d318910b58688c6929kmillikin@chromium.org LoadCurrentCharacterUnchecked(-1, 1); 992c53e10d01c5495df3896b9d318910b58688c6929kmillikin@chromium.org __ bind(&after_position); 9937516f05132429850aa326421ed3e25f23b4c071blrn@chromium.org} 9947516f05132429850aa326421ed3e25f23b4c071blrn@chromium.org 9957516f05132429850aa326421ed3e25f23b4c071blrn@chromium.org 9967516f05132429850aa326421ed3e25f23b4c071blrn@chromium.orgvoid RegExpMacroAssemblerMIPS::SetRegister(int register_index, int to) { 997e3c177a423baa3c30225c4e422b6f6c76d38b951machenbach@chromium.org DCHECK(register_index >= num_saved_registers_); // Reserved for positions! 998c53e10d01c5495df3896b9d318910b58688c6929kmillikin@chromium.org __ li(a0, Operand(to)); 999c53e10d01c5495df3896b9d318910b58688c6929kmillikin@chromium.org __ sw(a0, register_location(register_index)); 10007516f05132429850aa326421ed3e25f23b4c071blrn@chromium.org} 10017516f05132429850aa326421ed3e25f23b4c071blrn@chromium.org 10027516f05132429850aa326421ed3e25f23b4c071blrn@chromium.org 1003777db6f4249aa13ebf060a0d290d34936a41eb75jkummerow@chromium.orgbool RegExpMacroAssemblerMIPS::Succeed() { 1004c53e10d01c5495df3896b9d318910b58688c6929kmillikin@chromium.org __ jmp(&success_label_); 1005777db6f4249aa13ebf060a0d290d34936a41eb75jkummerow@chromium.org return global(); 10067516f05132429850aa326421ed3e25f23b4c071blrn@chromium.org} 10077516f05132429850aa326421ed3e25f23b4c071blrn@chromium.org 10087516f05132429850aa326421ed3e25f23b4c071blrn@chromium.org 10097516f05132429850aa326421ed3e25f23b4c071blrn@chromium.orgvoid RegExpMacroAssemblerMIPS::WriteCurrentPositionToRegister(int reg, 101028faa982749c4aa9c090939453dea14bb118f613jkummerow@chromium.org int cp_offset) { 1011c53e10d01c5495df3896b9d318910b58688c6929kmillikin@chromium.org if (cp_offset == 0) { 1012c53e10d01c5495df3896b9d318910b58688c6929kmillikin@chromium.org __ sw(current_input_offset(), register_location(reg)); 1013c53e10d01c5495df3896b9d318910b58688c6929kmillikin@chromium.org } else { 1014c53e10d01c5495df3896b9d318910b58688c6929kmillikin@chromium.org __ Addu(a0, current_input_offset(), Operand(cp_offset * char_size())); 1015c53e10d01c5495df3896b9d318910b58688c6929kmillikin@chromium.org __ sw(a0, register_location(reg)); 1016c53e10d01c5495df3896b9d318910b58688c6929kmillikin@chromium.org } 10177516f05132429850aa326421ed3e25f23b4c071blrn@chromium.org} 10187516f05132429850aa326421ed3e25f23b4c071blrn@chromium.org 10197516f05132429850aa326421ed3e25f23b4c071blrn@chromium.org 10207516f05132429850aa326421ed3e25f23b4c071blrn@chromium.orgvoid RegExpMacroAssemblerMIPS::ClearRegisters(int reg_from, int reg_to) { 1021e3c177a423baa3c30225c4e422b6f6c76d38b951machenbach@chromium.org DCHECK(reg_from <= reg_to); 1022c53e10d01c5495df3896b9d318910b58688c6929kmillikin@chromium.org __ lw(a0, MemOperand(frame_pointer(), kInputStartMinusOne)); 1023c53e10d01c5495df3896b9d318910b58688c6929kmillikin@chromium.org for (int reg = reg_from; reg <= reg_to; reg++) { 1024c53e10d01c5495df3896b9d318910b58688c6929kmillikin@chromium.org __ sw(a0, register_location(reg)); 1025c53e10d01c5495df3896b9d318910b58688c6929kmillikin@chromium.org } 10267516f05132429850aa326421ed3e25f23b4c071blrn@chromium.org} 10277516f05132429850aa326421ed3e25f23b4c071blrn@chromium.org 10287516f05132429850aa326421ed3e25f23b4c071blrn@chromium.org 10297516f05132429850aa326421ed3e25f23b4c071blrn@chromium.orgvoid RegExpMacroAssemblerMIPS::WriteStackPointerToRegister(int reg) { 1030c53e10d01c5495df3896b9d318910b58688c6929kmillikin@chromium.org __ lw(a1, MemOperand(frame_pointer(), kStackHighEnd)); 1031c53e10d01c5495df3896b9d318910b58688c6929kmillikin@chromium.org __ Subu(a0, backtrack_stackpointer(), a1); 1032c53e10d01c5495df3896b9d318910b58688c6929kmillikin@chromium.org __ sw(a0, register_location(reg)); 10337516f05132429850aa326421ed3e25f23b4c071blrn@chromium.org} 10347516f05132429850aa326421ed3e25f23b4c071blrn@chromium.org 10357516f05132429850aa326421ed3e25f23b4c071blrn@chromium.org 103689e18f5599cb4cd462cb1ed324addd7388fb4d60rossberg@chromium.orgbool RegExpMacroAssemblerMIPS::CanReadUnaligned() { 103789e18f5599cb4cd462cb1ed324addd7388fb4d60rossberg@chromium.org return false; 103889e18f5599cb4cd462cb1ed324addd7388fb4d60rossberg@chromium.org} 103989e18f5599cb4cd462cb1ed324addd7388fb4d60rossberg@chromium.org 104089e18f5599cb4cd462cb1ed324addd7388fb4d60rossberg@chromium.org 10417516f05132429850aa326421ed3e25f23b4c071blrn@chromium.org// Private methods: 10427516f05132429850aa326421ed3e25f23b4c071blrn@chromium.org 10437516f05132429850aa326421ed3e25f23b4c071blrn@chromium.orgvoid RegExpMacroAssemblerMIPS::CallCheckStackGuardState(Register scratch) { 10445de0074a922429f5e0ec2cf140c2d2989bf88140yangguo@chromium.org int stack_alignment = base::OS::ActivationFrameAlignment(); 10453d079fe881245e49c7ba803b54b4fe6d4b46113cmachenbach@chromium.org 10463d079fe881245e49c7ba803b54b4fe6d4b46113cmachenbach@chromium.org // Align the stack pointer and save the original sp value on the stack. 10473d079fe881245e49c7ba803b54b4fe6d4b46113cmachenbach@chromium.org __ mov(scratch, sp); 10483d079fe881245e49c7ba803b54b4fe6d4b46113cmachenbach@chromium.org __ Subu(sp, sp, Operand(kPointerSize)); 104921d700eedcdd6570eff22ece724b63a5eefe78cbmachenbach@chromium.org DCHECK(base::bits::IsPowerOfTwo32(stack_alignment)); 10503d079fe881245e49c7ba803b54b4fe6d4b46113cmachenbach@chromium.org __ And(sp, sp, Operand(-stack_alignment)); 10513d079fe881245e49c7ba803b54b4fe6d4b46113cmachenbach@chromium.org __ sw(scratch, MemOperand(sp)); 10523d079fe881245e49c7ba803b54b4fe6d4b46113cmachenbach@chromium.org 1053c53e10d01c5495df3896b9d318910b58688c6929kmillikin@chromium.org __ mov(a2, frame_pointer()); 1054c53e10d01c5495df3896b9d318910b58688c6929kmillikin@chromium.org // Code* of self. 105588aa058bdadfa79ae2836d12d6dd2d1c28aa490cdanno@chromium.org __ li(a1, Operand(masm_->CodeObject()), CONSTANT_SIZE); 10563d079fe881245e49c7ba803b54b4fe6d4b46113cmachenbach@chromium.org 10573d079fe881245e49c7ba803b54b4fe6d4b46113cmachenbach@chromium.org // We need to make room for the return address on the stack. 1058e3c177a423baa3c30225c4e422b6f6c76d38b951machenbach@chromium.org DCHECK(IsAligned(stack_alignment, kPointerSize)); 10593d079fe881245e49c7ba803b54b4fe6d4b46113cmachenbach@chromium.org __ Subu(sp, sp, Operand(stack_alignment)); 10603d079fe881245e49c7ba803b54b4fe6d4b46113cmachenbach@chromium.org 10613d079fe881245e49c7ba803b54b4fe6d4b46113cmachenbach@chromium.org // Stack pointer now points to cell where return address is to be written. 10623d079fe881245e49c7ba803b54b4fe6d4b46113cmachenbach@chromium.org // Arguments are in registers, meaning we teat the return address as 10633d079fe881245e49c7ba803b54b4fe6d4b46113cmachenbach@chromium.org // argument 5. Since DirectCEntryStub will handleallocating space for the C 10643d079fe881245e49c7ba803b54b4fe6d4b46113cmachenbach@chromium.org // argument slots, we don't need to care about that here. This is how the 10653d079fe881245e49c7ba803b54b4fe6d4b46113cmachenbach@chromium.org // stack will look (sp meaning the value of sp at this moment): 10663d079fe881245e49c7ba803b54b4fe6d4b46113cmachenbach@chromium.org // [sp + 3] - empty slot if needed for alignment. 10673d079fe881245e49c7ba803b54b4fe6d4b46113cmachenbach@chromium.org // [sp + 2] - saved sp. 10683d079fe881245e49c7ba803b54b4fe6d4b46113cmachenbach@chromium.org // [sp + 1] - second word reserved for return value. 10693d079fe881245e49c7ba803b54b4fe6d4b46113cmachenbach@chromium.org // [sp + 0] - first word reserved for return value. 10703d079fe881245e49c7ba803b54b4fe6d4b46113cmachenbach@chromium.org 10713d079fe881245e49c7ba803b54b4fe6d4b46113cmachenbach@chromium.org // a0 will point to the return address, placed by DirectCEntry. 10723d079fe881245e49c7ba803b54b4fe6d4b46113cmachenbach@chromium.org __ mov(a0, sp); 10733d079fe881245e49c7ba803b54b4fe6d4b46113cmachenbach@chromium.org 1074c53e10d01c5495df3896b9d318910b58688c6929kmillikin@chromium.org ExternalReference stack_guard_check = 1075c53e10d01c5495df3896b9d318910b58688c6929kmillikin@chromium.org ExternalReference::re_check_stack_guard_state(masm_->isolate()); 10763d079fe881245e49c7ba803b54b4fe6d4b46113cmachenbach@chromium.org __ li(t9, Operand(stack_guard_check)); 1077f2f0489407bbb5e50d16ae791442df29513b53b5machenbach@chromium.org DirectCEntryStub stub(isolate()); 10783d079fe881245e49c7ba803b54b4fe6d4b46113cmachenbach@chromium.org stub.GenerateCall(masm_, t9); 10793d079fe881245e49c7ba803b54b4fe6d4b46113cmachenbach@chromium.org 10803d079fe881245e49c7ba803b54b4fe6d4b46113cmachenbach@chromium.org // DirectCEntryStub allocated space for the C argument slots so we have to 10813d079fe881245e49c7ba803b54b4fe6d4b46113cmachenbach@chromium.org // drop them with the return address from the stack with loading saved sp. 10823d079fe881245e49c7ba803b54b4fe6d4b46113cmachenbach@chromium.org // At this point stack must look: 10833d079fe881245e49c7ba803b54b4fe6d4b46113cmachenbach@chromium.org // [sp + 7] - empty slot if needed for alignment. 10843d079fe881245e49c7ba803b54b4fe6d4b46113cmachenbach@chromium.org // [sp + 6] - saved sp. 10853d079fe881245e49c7ba803b54b4fe6d4b46113cmachenbach@chromium.org // [sp + 5] - second word reserved for return value. 10863d079fe881245e49c7ba803b54b4fe6d4b46113cmachenbach@chromium.org // [sp + 4] - first word reserved for return value. 10873d079fe881245e49c7ba803b54b4fe6d4b46113cmachenbach@chromium.org // [sp + 3] - C argument slot. 10883d079fe881245e49c7ba803b54b4fe6d4b46113cmachenbach@chromium.org // [sp + 2] - C argument slot. 10893d079fe881245e49c7ba803b54b4fe6d4b46113cmachenbach@chromium.org // [sp + 1] - C argument slot. 10903d079fe881245e49c7ba803b54b4fe6d4b46113cmachenbach@chromium.org // [sp + 0] - C argument slot. 10913d079fe881245e49c7ba803b54b4fe6d4b46113cmachenbach@chromium.org __ lw(sp, MemOperand(sp, stack_alignment + kCArgsSlotsSize)); 10923d079fe881245e49c7ba803b54b4fe6d4b46113cmachenbach@chromium.org 10933d079fe881245e49c7ba803b54b4fe6d4b46113cmachenbach@chromium.org __ li(code_pointer(), Operand(masm_->CodeObject())); 10947516f05132429850aa326421ed3e25f23b4c071blrn@chromium.org} 10957516f05132429850aa326421ed3e25f23b4c071blrn@chromium.org 10967516f05132429850aa326421ed3e25f23b4c071blrn@chromium.org 10977516f05132429850aa326421ed3e25f23b4c071blrn@chromium.org// Helper function for reading a value out of a stack frame. 10987516f05132429850aa326421ed3e25f23b4c071blrn@chromium.orgtemplate <typename T> 10997516f05132429850aa326421ed3e25f23b4c071blrn@chromium.orgstatic T& frame_entry(Address re_frame, int frame_offset) { 11007516f05132429850aa326421ed3e25f23b4c071blrn@chromium.org return reinterpret_cast<T&>(Memory::int32_at(re_frame + frame_offset)); 11017516f05132429850aa326421ed3e25f23b4c071blrn@chromium.org} 11027516f05132429850aa326421ed3e25f23b4c071blrn@chromium.org 11037516f05132429850aa326421ed3e25f23b4c071blrn@chromium.org 11047516f05132429850aa326421ed3e25f23b4c071blrn@chromium.orgint RegExpMacroAssemblerMIPS::CheckStackGuardState(Address* return_address, 1105c53e10d01c5495df3896b9d318910b58688c6929kmillikin@chromium.org Code* re_code, 1106c53e10d01c5495df3896b9d318910b58688c6929kmillikin@chromium.org Address re_frame) { 1107c53e10d01c5495df3896b9d318910b58688c6929kmillikin@chromium.org Isolate* isolate = frame_entry<Isolate*>(re_frame, kIsolate); 11083ee7a7ed19002e4a0efbf6cdb2a201f21763a80adanno@chromium.org StackLimitCheck check(isolate); 11093ee7a7ed19002e4a0efbf6cdb2a201f21763a80adanno@chromium.org if (check.JsHasOverflowed()) { 1110c53e10d01c5495df3896b9d318910b58688c6929kmillikin@chromium.org isolate->StackOverflow(); 1111c53e10d01c5495df3896b9d318910b58688c6929kmillikin@chromium.org return EXCEPTION; 1112c53e10d01c5495df3896b9d318910b58688c6929kmillikin@chromium.org } 1113c53e10d01c5495df3896b9d318910b58688c6929kmillikin@chromium.org 1114c53e10d01c5495df3896b9d318910b58688c6929kmillikin@chromium.org // If not real stack overflow the stack guard was used to interrupt 1115c53e10d01c5495df3896b9d318910b58688c6929kmillikin@chromium.org // execution for another purpose. 1116c53e10d01c5495df3896b9d318910b58688c6929kmillikin@chromium.org 1117c53e10d01c5495df3896b9d318910b58688c6929kmillikin@chromium.org // If this is a direct call from JavaScript retry the RegExp forcing the call 1118c53e10d01c5495df3896b9d318910b58688c6929kmillikin@chromium.org // through the runtime system. Currently the direct call cannot handle a GC. 1119c53e10d01c5495df3896b9d318910b58688c6929kmillikin@chromium.org if (frame_entry<int>(re_frame, kDirectCall) == 1) { 1120c53e10d01c5495df3896b9d318910b58688c6929kmillikin@chromium.org return RETRY; 1121c53e10d01c5495df3896b9d318910b58688c6929kmillikin@chromium.org } 1122c53e10d01c5495df3896b9d318910b58688c6929kmillikin@chromium.org 1123c53e10d01c5495df3896b9d318910b58688c6929kmillikin@chromium.org // Prepare for possible GC. 11244668a2c7a746d01b382f23aa32e163701e3075f8ricow@chromium.org HandleScope handles(isolate); 1125c53e10d01c5495df3896b9d318910b58688c6929kmillikin@chromium.org Handle<Code> code_handle(re_code); 1126c53e10d01c5495df3896b9d318910b58688c6929kmillikin@chromium.org 1127c53e10d01c5495df3896b9d318910b58688c6929kmillikin@chromium.org Handle<String> subject(frame_entry<String*>(re_frame, kInputString)); 1128c53e10d01c5495df3896b9d318910b58688c6929kmillikin@chromium.org // Current string. 11292c81ceb7f1e1ccf5f304be0646f4c1375941a7f2machenbach@chromium.org bool is_one_byte = subject->IsOneByteRepresentationUnderneath(); 1130c53e10d01c5495df3896b9d318910b58688c6929kmillikin@chromium.org 1131e3c177a423baa3c30225c4e422b6f6c76d38b951machenbach@chromium.org DCHECK(re_code->instruction_start() <= *return_address); 1132e3c177a423baa3c30225c4e422b6f6c76d38b951machenbach@chromium.org DCHECK(*return_address <= 1133c53e10d01c5495df3896b9d318910b58688c6929kmillikin@chromium.org re_code->instruction_start() + re_code->instruction_size()); 1134c53e10d01c5495df3896b9d318910b58688c6929kmillikin@chromium.org 11353c3c8d733702cb2b41471efa5eead1faf5b5711bmachenbach@chromium.org Object* result = isolate->stack_guard()->HandleInterrupts(); 1136c53e10d01c5495df3896b9d318910b58688c6929kmillikin@chromium.org 1137c53e10d01c5495df3896b9d318910b58688c6929kmillikin@chromium.org if (*code_handle != re_code) { // Return address no longer valid. 113880c42ed5ace766a3a02b30a53a25e5e81e234723yangguo@chromium.org int delta = code_handle->address() - re_code->address(); 1139c53e10d01c5495df3896b9d318910b58688c6929kmillikin@chromium.org // Overwrite the return address on the stack. 1140c53e10d01c5495df3896b9d318910b58688c6929kmillikin@chromium.org *return_address += delta; 1141c53e10d01c5495df3896b9d318910b58688c6929kmillikin@chromium.org } 1142c53e10d01c5495df3896b9d318910b58688c6929kmillikin@chromium.org 1143c53e10d01c5495df3896b9d318910b58688c6929kmillikin@chromium.org if (result->IsException()) { 1144c53e10d01c5495df3896b9d318910b58688c6929kmillikin@chromium.org return EXCEPTION; 1145c53e10d01c5495df3896b9d318910b58688c6929kmillikin@chromium.org } 1146c53e10d01c5495df3896b9d318910b58688c6929kmillikin@chromium.org 11474668a2c7a746d01b382f23aa32e163701e3075f8ricow@chromium.org Handle<String> subject_tmp = subject; 11484668a2c7a746d01b382f23aa32e163701e3075f8ricow@chromium.org int slice_offset = 0; 11494668a2c7a746d01b382f23aa32e163701e3075f8ricow@chromium.org 11504668a2c7a746d01b382f23aa32e163701e3075f8ricow@chromium.org // Extract the underlying string and the slice offset. 11514668a2c7a746d01b382f23aa32e163701e3075f8ricow@chromium.org if (StringShape(*subject_tmp).IsCons()) { 11524668a2c7a746d01b382f23aa32e163701e3075f8ricow@chromium.org subject_tmp = Handle<String>(ConsString::cast(*subject_tmp)->first()); 11534668a2c7a746d01b382f23aa32e163701e3075f8ricow@chromium.org } else if (StringShape(*subject_tmp).IsSliced()) { 11544668a2c7a746d01b382f23aa32e163701e3075f8ricow@chromium.org SlicedString* slice = SlicedString::cast(*subject_tmp); 11554668a2c7a746d01b382f23aa32e163701e3075f8ricow@chromium.org subject_tmp = Handle<String>(slice->parent()); 11564668a2c7a746d01b382f23aa32e163701e3075f8ricow@chromium.org slice_offset = slice->offset(); 11574668a2c7a746d01b382f23aa32e163701e3075f8ricow@chromium.org } 11584668a2c7a746d01b382f23aa32e163701e3075f8ricow@chromium.org 1159c53e10d01c5495df3896b9d318910b58688c6929kmillikin@chromium.org // String might have changed. 11602c81ceb7f1e1ccf5f304be0646f4c1375941a7f2machenbach@chromium.org if (subject_tmp->IsOneByteRepresentation() != is_one_byte) { 11612c81ceb7f1e1ccf5f304be0646f4c1375941a7f2machenbach@chromium.org // If we changed between an Latin1 and an UC16 string, the specialized 1162c53e10d01c5495df3896b9d318910b58688c6929kmillikin@chromium.org // code cannot be used, and we need to restart regexp matching from 1163c53e10d01c5495df3896b9d318910b58688c6929kmillikin@chromium.org // scratch (including, potentially, compiling a new version of the code). 1164c53e10d01c5495df3896b9d318910b58688c6929kmillikin@chromium.org return RETRY; 1165c53e10d01c5495df3896b9d318910b58688c6929kmillikin@chromium.org } 1166c53e10d01c5495df3896b9d318910b58688c6929kmillikin@chromium.org 1167c53e10d01c5495df3896b9d318910b58688c6929kmillikin@chromium.org // Otherwise, the content of the string might have moved. It must still 1168c53e10d01c5495df3896b9d318910b58688c6929kmillikin@chromium.org // be a sequential or external string with the same content. 1169c53e10d01c5495df3896b9d318910b58688c6929kmillikin@chromium.org // Update the start and end pointers in the stack frame to the current 1170c53e10d01c5495df3896b9d318910b58688c6929kmillikin@chromium.org // location (whether it has actually moved or not). 1171e3c177a423baa3c30225c4e422b6f6c76d38b951machenbach@chromium.org DCHECK(StringShape(*subject_tmp).IsSequential() || 11724668a2c7a746d01b382f23aa32e163701e3075f8ricow@chromium.org StringShape(*subject_tmp).IsExternal()); 1173c53e10d01c5495df3896b9d318910b58688c6929kmillikin@chromium.org 1174c53e10d01c5495df3896b9d318910b58688c6929kmillikin@chromium.org // The original start address of the characters to match. 1175c53e10d01c5495df3896b9d318910b58688c6929kmillikin@chromium.org const byte* start_address = frame_entry<const byte*>(re_frame, kInputStart); 1176c53e10d01c5495df3896b9d318910b58688c6929kmillikin@chromium.org 1177c53e10d01c5495df3896b9d318910b58688c6929kmillikin@chromium.org // Find the current start address of the same character at the current string 1178c53e10d01c5495df3896b9d318910b58688c6929kmillikin@chromium.org // position. 1179c53e10d01c5495df3896b9d318910b58688c6929kmillikin@chromium.org int start_index = frame_entry<int>(re_frame, kStartIndex); 11804668a2c7a746d01b382f23aa32e163701e3075f8ricow@chromium.org const byte* new_address = StringCharacterPosition(*subject_tmp, 11814668a2c7a746d01b382f23aa32e163701e3075f8ricow@chromium.org start_index + slice_offset); 1182c53e10d01c5495df3896b9d318910b58688c6929kmillikin@chromium.org 1183c53e10d01c5495df3896b9d318910b58688c6929kmillikin@chromium.org if (start_address != new_address) { 1184c53e10d01c5495df3896b9d318910b58688c6929kmillikin@chromium.org // If there is a difference, update the object pointer and start and end 1185c53e10d01c5495df3896b9d318910b58688c6929kmillikin@chromium.org // addresses in the RegExp stack frame to match the new value. 1186c53e10d01c5495df3896b9d318910b58688c6929kmillikin@chromium.org const byte* end_address = frame_entry<const byte* >(re_frame, kInputEnd); 11874668a2c7a746d01b382f23aa32e163701e3075f8ricow@chromium.org int byte_length = static_cast<int>(end_address - start_address); 1188c53e10d01c5495df3896b9d318910b58688c6929kmillikin@chromium.org frame_entry<const String*>(re_frame, kInputString) = *subject; 1189c53e10d01c5495df3896b9d318910b58688c6929kmillikin@chromium.org frame_entry<const byte*>(re_frame, kInputStart) = new_address; 1190c53e10d01c5495df3896b9d318910b58688c6929kmillikin@chromium.org frame_entry<const byte*>(re_frame, kInputEnd) = new_address + byte_length; 1191394dbcf9009cf5203b6d85e8b515fcff072040f3erik.corry@gmail.com } else if (frame_entry<const String*>(re_frame, kInputString) != *subject) { 1192394dbcf9009cf5203b6d85e8b515fcff072040f3erik.corry@gmail.com // Subject string might have been a ConsString that underwent 1193394dbcf9009cf5203b6d85e8b515fcff072040f3erik.corry@gmail.com // short-circuiting during GC. That will not change start_address but 1194394dbcf9009cf5203b6d85e8b515fcff072040f3erik.corry@gmail.com // will change pointer inside the subject handle. 1195394dbcf9009cf5203b6d85e8b515fcff072040f3erik.corry@gmail.com frame_entry<const String*>(re_frame, kInputString) = *subject; 1196c53e10d01c5495df3896b9d318910b58688c6929kmillikin@chromium.org } 1197c53e10d01c5495df3896b9d318910b58688c6929kmillikin@chromium.org 11987516f05132429850aa326421ed3e25f23b4c071blrn@chromium.org return 0; 11997516f05132429850aa326421ed3e25f23b4c071blrn@chromium.org} 12007516f05132429850aa326421ed3e25f23b4c071blrn@chromium.org 12017516f05132429850aa326421ed3e25f23b4c071blrn@chromium.org 12027516f05132429850aa326421ed3e25f23b4c071blrn@chromium.orgMemOperand RegExpMacroAssemblerMIPS::register_location(int register_index) { 1203e3c177a423baa3c30225c4e422b6f6c76d38b951machenbach@chromium.org DCHECK(register_index < (1<<30)); 1204c53e10d01c5495df3896b9d318910b58688c6929kmillikin@chromium.org if (num_registers_ <= register_index) { 1205c53e10d01c5495df3896b9d318910b58688c6929kmillikin@chromium.org num_registers_ = register_index + 1; 1206c53e10d01c5495df3896b9d318910b58688c6929kmillikin@chromium.org } 1207c53e10d01c5495df3896b9d318910b58688c6929kmillikin@chromium.org return MemOperand(frame_pointer(), 1208c53e10d01c5495df3896b9d318910b58688c6929kmillikin@chromium.org kRegisterZero - register_index * kPointerSize); 12097516f05132429850aa326421ed3e25f23b4c071blrn@chromium.org} 12107516f05132429850aa326421ed3e25f23b4c071blrn@chromium.org 12117516f05132429850aa326421ed3e25f23b4c071blrn@chromium.org 12127516f05132429850aa326421ed3e25f23b4c071blrn@chromium.orgvoid RegExpMacroAssemblerMIPS::CheckPosition(int cp_offset, 121328faa982749c4aa9c090939453dea14bb118f613jkummerow@chromium.org Label* on_outside_input) { 1214c53e10d01c5495df3896b9d318910b58688c6929kmillikin@chromium.org BranchOrBacktrack(on_outside_input, 1215c53e10d01c5495df3896b9d318910b58688c6929kmillikin@chromium.org ge, 1216c53e10d01c5495df3896b9d318910b58688c6929kmillikin@chromium.org current_input_offset(), 1217c53e10d01c5495df3896b9d318910b58688c6929kmillikin@chromium.org Operand(-cp_offset * char_size())); 12187516f05132429850aa326421ed3e25f23b4c071blrn@chromium.org} 12197516f05132429850aa326421ed3e25f23b4c071blrn@chromium.org 12207516f05132429850aa326421ed3e25f23b4c071blrn@chromium.org 12217516f05132429850aa326421ed3e25f23b4c071blrn@chromium.orgvoid RegExpMacroAssemblerMIPS::BranchOrBacktrack(Label* to, 12227516f05132429850aa326421ed3e25f23b4c071blrn@chromium.org Condition condition, 12237516f05132429850aa326421ed3e25f23b4c071blrn@chromium.org Register rs, 12247516f05132429850aa326421ed3e25f23b4c071blrn@chromium.org const Operand& rt) { 1225c53e10d01c5495df3896b9d318910b58688c6929kmillikin@chromium.org if (condition == al) { // Unconditional. 1226c53e10d01c5495df3896b9d318910b58688c6929kmillikin@chromium.org if (to == NULL) { 1227c53e10d01c5495df3896b9d318910b58688c6929kmillikin@chromium.org Backtrack(); 1228c53e10d01c5495df3896b9d318910b58688c6929kmillikin@chromium.org return; 1229c53e10d01c5495df3896b9d318910b58688c6929kmillikin@chromium.org } 1230c53e10d01c5495df3896b9d318910b58688c6929kmillikin@chromium.org __ jmp(to); 1231c53e10d01c5495df3896b9d318910b58688c6929kmillikin@chromium.org return; 1232c53e10d01c5495df3896b9d318910b58688c6929kmillikin@chromium.org } 1233c53e10d01c5495df3896b9d318910b58688c6929kmillikin@chromium.org if (to == NULL) { 1234c53e10d01c5495df3896b9d318910b58688c6929kmillikin@chromium.org __ Branch(&backtrack_label_, condition, rs, rt); 1235c53e10d01c5495df3896b9d318910b58688c6929kmillikin@chromium.org return; 1236c53e10d01c5495df3896b9d318910b58688c6929kmillikin@chromium.org } 1237c53e10d01c5495df3896b9d318910b58688c6929kmillikin@chromium.org __ Branch(to, condition, rs, rt); 12387516f05132429850aa326421ed3e25f23b4c071blrn@chromium.org} 12397516f05132429850aa326421ed3e25f23b4c071blrn@chromium.org 12407516f05132429850aa326421ed3e25f23b4c071blrn@chromium.org 124128faa982749c4aa9c090939453dea14bb118f613jkummerow@chromium.orgvoid RegExpMacroAssemblerMIPS::SafeCall(Label* to, 124228faa982749c4aa9c090939453dea14bb118f613jkummerow@chromium.org Condition cond, 124328faa982749c4aa9c090939453dea14bb118f613jkummerow@chromium.org Register rs, 124428faa982749c4aa9c090939453dea14bb118f613jkummerow@chromium.org const Operand& rt) { 1245c53e10d01c5495df3896b9d318910b58688c6929kmillikin@chromium.org __ BranchAndLink(to, cond, rs, rt); 12467516f05132429850aa326421ed3e25f23b4c071blrn@chromium.org} 12477516f05132429850aa326421ed3e25f23b4c071blrn@chromium.org 12487516f05132429850aa326421ed3e25f23b4c071blrn@chromium.org 12497516f05132429850aa326421ed3e25f23b4c071blrn@chromium.orgvoid RegExpMacroAssemblerMIPS::SafeReturn() { 1250c53e10d01c5495df3896b9d318910b58688c6929kmillikin@chromium.org __ pop(ra); 1251c53e10d01c5495df3896b9d318910b58688c6929kmillikin@chromium.org __ Addu(t5, ra, Operand(masm_->CodeObject())); 1252c53e10d01c5495df3896b9d318910b58688c6929kmillikin@chromium.org __ Jump(t5); 12537516f05132429850aa326421ed3e25f23b4c071blrn@chromium.org} 12547516f05132429850aa326421ed3e25f23b4c071blrn@chromium.org 12557516f05132429850aa326421ed3e25f23b4c071blrn@chromium.org 12567516f05132429850aa326421ed3e25f23b4c071blrn@chromium.orgvoid RegExpMacroAssemblerMIPS::SafeCallTarget(Label* name) { 1257c53e10d01c5495df3896b9d318910b58688c6929kmillikin@chromium.org __ bind(name); 1258c53e10d01c5495df3896b9d318910b58688c6929kmillikin@chromium.org __ Subu(ra, ra, Operand(masm_->CodeObject())); 1259c53e10d01c5495df3896b9d318910b58688c6929kmillikin@chromium.org __ push(ra); 12607516f05132429850aa326421ed3e25f23b4c071blrn@chromium.org} 12617516f05132429850aa326421ed3e25f23b4c071blrn@chromium.org 12627516f05132429850aa326421ed3e25f23b4c071blrn@chromium.org 12637516f05132429850aa326421ed3e25f23b4c071blrn@chromium.orgvoid RegExpMacroAssemblerMIPS::Push(Register source) { 1264e3c177a423baa3c30225c4e422b6f6c76d38b951machenbach@chromium.org DCHECK(!source.is(backtrack_stackpointer())); 1265c53e10d01c5495df3896b9d318910b58688c6929kmillikin@chromium.org __ Addu(backtrack_stackpointer(), 1266c53e10d01c5495df3896b9d318910b58688c6929kmillikin@chromium.org backtrack_stackpointer(), 1267c53e10d01c5495df3896b9d318910b58688c6929kmillikin@chromium.org Operand(-kPointerSize)); 1268c53e10d01c5495df3896b9d318910b58688c6929kmillikin@chromium.org __ sw(source, MemOperand(backtrack_stackpointer())); 12697516f05132429850aa326421ed3e25f23b4c071blrn@chromium.org} 12707516f05132429850aa326421ed3e25f23b4c071blrn@chromium.org 12717516f05132429850aa326421ed3e25f23b4c071blrn@chromium.org 12727516f05132429850aa326421ed3e25f23b4c071blrn@chromium.orgvoid RegExpMacroAssemblerMIPS::Pop(Register target) { 1273e3c177a423baa3c30225c4e422b6f6c76d38b951machenbach@chromium.org DCHECK(!target.is(backtrack_stackpointer())); 1274c53e10d01c5495df3896b9d318910b58688c6929kmillikin@chromium.org __ lw(target, MemOperand(backtrack_stackpointer())); 1275c53e10d01c5495df3896b9d318910b58688c6929kmillikin@chromium.org __ Addu(backtrack_stackpointer(), backtrack_stackpointer(), kPointerSize); 12767516f05132429850aa326421ed3e25f23b4c071blrn@chromium.org} 12777516f05132429850aa326421ed3e25f23b4c071blrn@chromium.org 12787516f05132429850aa326421ed3e25f23b4c071blrn@chromium.org 12797516f05132429850aa326421ed3e25f23b4c071blrn@chromium.orgvoid RegExpMacroAssemblerMIPS::CheckPreemption() { 1280c53e10d01c5495df3896b9d318910b58688c6929kmillikin@chromium.org // Check for preemption. 1281c53e10d01c5495df3896b9d318910b58688c6929kmillikin@chromium.org ExternalReference stack_limit = 1282c53e10d01c5495df3896b9d318910b58688c6929kmillikin@chromium.org ExternalReference::address_of_stack_limit(masm_->isolate()); 1283c53e10d01c5495df3896b9d318910b58688c6929kmillikin@chromium.org __ li(a0, Operand(stack_limit)); 1284c53e10d01c5495df3896b9d318910b58688c6929kmillikin@chromium.org __ lw(a0, MemOperand(a0)); 1285c53e10d01c5495df3896b9d318910b58688c6929kmillikin@chromium.org SafeCall(&check_preempt_label_, ls, sp, Operand(a0)); 12867516f05132429850aa326421ed3e25f23b4c071blrn@chromium.org} 12877516f05132429850aa326421ed3e25f23b4c071blrn@chromium.org 12887516f05132429850aa326421ed3e25f23b4c071blrn@chromium.org 12897516f05132429850aa326421ed3e25f23b4c071blrn@chromium.orgvoid RegExpMacroAssemblerMIPS::CheckStackLimit() { 1290c53e10d01c5495df3896b9d318910b58688c6929kmillikin@chromium.org ExternalReference stack_limit = 1291c53e10d01c5495df3896b9d318910b58688c6929kmillikin@chromium.org ExternalReference::address_of_regexp_stack_limit(masm_->isolate()); 1292c53e10d01c5495df3896b9d318910b58688c6929kmillikin@chromium.org 1293c53e10d01c5495df3896b9d318910b58688c6929kmillikin@chromium.org __ li(a0, Operand(stack_limit)); 1294c53e10d01c5495df3896b9d318910b58688c6929kmillikin@chromium.org __ lw(a0, MemOperand(a0)); 1295c53e10d01c5495df3896b9d318910b58688c6929kmillikin@chromium.org SafeCall(&stack_overflow_label_, ls, backtrack_stackpointer(), Operand(a0)); 12967516f05132429850aa326421ed3e25f23b4c071blrn@chromium.org} 12977516f05132429850aa326421ed3e25f23b4c071blrn@chromium.org 12987516f05132429850aa326421ed3e25f23b4c071blrn@chromium.org 12997516f05132429850aa326421ed3e25f23b4c071blrn@chromium.orgvoid RegExpMacroAssemblerMIPS::LoadCurrentCharacterUnchecked(int cp_offset, 130028faa982749c4aa9c090939453dea14bb118f613jkummerow@chromium.org int characters) { 1301c53e10d01c5495df3896b9d318910b58688c6929kmillikin@chromium.org Register offset = current_input_offset(); 1302c53e10d01c5495df3896b9d318910b58688c6929kmillikin@chromium.org if (cp_offset != 0) { 1303777db6f4249aa13ebf060a0d290d34936a41eb75jkummerow@chromium.org // t7 is not being used to store the capture start index at this point. 1304777db6f4249aa13ebf060a0d290d34936a41eb75jkummerow@chromium.org __ Addu(t7, current_input_offset(), Operand(cp_offset * char_size())); 1305777db6f4249aa13ebf060a0d290d34936a41eb75jkummerow@chromium.org offset = t7; 1306c53e10d01c5495df3896b9d318910b58688c6929kmillikin@chromium.org } 1307c53e10d01c5495df3896b9d318910b58688c6929kmillikin@chromium.org // We assume that we cannot do unaligned loads on MIPS, so this function 1308c53e10d01c5495df3896b9d318910b58688c6929kmillikin@chromium.org // must only be used to load a single character at a time. 1309e3c177a423baa3c30225c4e422b6f6c76d38b951machenbach@chromium.org DCHECK(characters == 1); 1310c53e10d01c5495df3896b9d318910b58688c6929kmillikin@chromium.org __ Addu(t5, end_of_input_address(), Operand(offset)); 13112c81ceb7f1e1ccf5f304be0646f4c1375941a7f2machenbach@chromium.org if (mode_ == LATIN1) { 1312c53e10d01c5495df3896b9d318910b58688c6929kmillikin@chromium.org __ lbu(current_character(), MemOperand(t5, 0)); 1313c53e10d01c5495df3896b9d318910b58688c6929kmillikin@chromium.org } else { 1314e3c177a423baa3c30225c4e422b6f6c76d38b951machenbach@chromium.org DCHECK(mode_ == UC16); 1315c53e10d01c5495df3896b9d318910b58688c6929kmillikin@chromium.org __ lhu(current_character(), MemOperand(t5, 0)); 1316c53e10d01c5495df3896b9d318910b58688c6929kmillikin@chromium.org } 13177516f05132429850aa326421ed3e25f23b4c071blrn@chromium.org} 13187516f05132429850aa326421ed3e25f23b4c071blrn@chromium.org 13197516f05132429850aa326421ed3e25f23b4c071blrn@chromium.org 13207516f05132429850aa326421ed3e25f23b4c071blrn@chromium.org#undef __ 13217516f05132429850aa326421ed3e25f23b4c071blrn@chromium.org 13227516f05132429850aa326421ed3e25f23b4c071blrn@chromium.org#endif // V8_INTERPRETED_REGEXP 13237516f05132429850aa326421ed3e25f23b4c071blrn@chromium.org 13247516f05132429850aa326421ed3e25f23b4c071blrn@chromium.org}} // namespace v8::internal 13257516f05132429850aa326421ed3e25f23b4c071blrn@chromium.org 13267516f05132429850aa326421ed3e25f23b4c071blrn@chromium.org#endif // V8_TARGET_ARCH_MIPS 1327