115613d0b07bac19e341905ff374c930420b3b9c8mstarzinger@chromium.org// Copyright 2012 the V8 project authors. All rights reserved. 29a4089a092cad9ff23b6416b92cd5d818dc101d1mads.s.ager@gmail.com// Redistribution and use in source and binary forms, with or without 39a4089a092cad9ff23b6416b92cd5d818dc101d1mads.s.ager@gmail.com// modification, are permitted provided that the following conditions are 49a4089a092cad9ff23b6416b92cd5d818dc101d1mads.s.ager@gmail.com// met: 59a4089a092cad9ff23b6416b92cd5d818dc101d1mads.s.ager@gmail.com// 69a4089a092cad9ff23b6416b92cd5d818dc101d1mads.s.ager@gmail.com// * Redistributions of source code must retain the above copyright 79a4089a092cad9ff23b6416b92cd5d818dc101d1mads.s.ager@gmail.com// notice, this list of conditions and the following disclaimer. 89a4089a092cad9ff23b6416b92cd5d818dc101d1mads.s.ager@gmail.com// * Redistributions in binary form must reproduce the above 99a4089a092cad9ff23b6416b92cd5d818dc101d1mads.s.ager@gmail.com// copyright notice, this list of conditions and the following 109a4089a092cad9ff23b6416b92cd5d818dc101d1mads.s.ager@gmail.com// disclaimer in the documentation and/or other materials provided 119a4089a092cad9ff23b6416b92cd5d818dc101d1mads.s.ager@gmail.com// with the distribution. 129a4089a092cad9ff23b6416b92cd5d818dc101d1mads.s.ager@gmail.com// * Neither the name of Google Inc. nor the names of its 139a4089a092cad9ff23b6416b92cd5d818dc101d1mads.s.ager@gmail.com// contributors may be used to endorse or promote products derived 149a4089a092cad9ff23b6416b92cd5d818dc101d1mads.s.ager@gmail.com// from this software without specific prior written permission. 159a4089a092cad9ff23b6416b92cd5d818dc101d1mads.s.ager@gmail.com// 169a4089a092cad9ff23b6416b92cd5d818dc101d1mads.s.ager@gmail.com// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 179a4089a092cad9ff23b6416b92cd5d818dc101d1mads.s.ager@gmail.com// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 189a4089a092cad9ff23b6416b92cd5d818dc101d1mads.s.ager@gmail.com// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR 199a4089a092cad9ff23b6416b92cd5d818dc101d1mads.s.ager@gmail.com// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT 209a4089a092cad9ff23b6416b92cd5d818dc101d1mads.s.ager@gmail.com// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, 219a4089a092cad9ff23b6416b92cd5d818dc101d1mads.s.ager@gmail.com// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT 229a4089a092cad9ff23b6416b92cd5d818dc101d1mads.s.ager@gmail.com// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 239a4089a092cad9ff23b6416b92cd5d818dc101d1mads.s.ager@gmail.com// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 249a4089a092cad9ff23b6416b92cd5d818dc101d1mads.s.ager@gmail.com// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 259a4089a092cad9ff23b6416b92cd5d818dc101d1mads.s.ager@gmail.com// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 269a4089a092cad9ff23b6416b92cd5d818dc101d1mads.s.ager@gmail.com// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 279a4089a092cad9ff23b6416b92cd5d818dc101d1mads.s.ager@gmail.com 28a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org#include "v8.h" 299dfbea4c7d423c7bc1db94425cb78e7f7cf41f78erik.corry@gmail.com 3093a47f4837f2137c8d8349250fd8e91da3108126jkummerow@chromium.org#if V8_TARGET_ARCH_ARM 319dfbea4c7d423c7bc1db94425cb78e7f7cf41f78erik.corry@gmail.com 32c1789eecd43bf9c5497636592bf14fa754d04c89machenbach@chromium.org#include "cpu-profiler.h" 3318ad94b919217ffbcd2d3159eeb5f8c588761c47ager@chromium.org#include "unicode.h" 3418ad94b919217ffbcd2d3159eeb5f8c588761c47ager@chromium.org#include "log.h" 353811b436bf328d2ace6fe79ce99aeda71f9f06d3ager@chromium.org#include "code-stubs.h" 3618ad94b919217ffbcd2d3159eeb5f8c588761c47ager@chromium.org#include "regexp-stack.h" 3718ad94b919217ffbcd2d3159eeb5f8c588761c47ager@chromium.org#include "macro-assembler.h" 38a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org#include "regexp-macro-assembler.h" 393a37e9b96c768f6b5b6b09542e1cb1a1ece7a022ager@chromium.org#include "arm/regexp-macro-assembler-arm.h" 409a4089a092cad9ff23b6416b92cd5d818dc101d1mads.s.ager@gmail.com 4171affb54842da76b24f0bb3184e9f0960523f89dkasperl@chromium.orgnamespace v8 { 4271affb54842da76b24f0bb3184e9f0960523f89dkasperl@chromium.orgnamespace internal { 43a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org 44c9c80823e038328f2e1060d7feef0762a50adf06ricow@chromium.org#ifndef V8_INTERPRETED_REGEXP 4518ad94b919217ffbcd2d3159eeb5f8c588761c47ager@chromium.org/* 4618ad94b919217ffbcd2d3159eeb5f8c588761c47ager@chromium.org * This assembler uses the following register assignment convention 4715613d0b07bac19e341905ff374c930420b3b9c8mstarzinger@chromium.org * - r4 : Temporarily stores the index of capture start after a matching pass 4815613d0b07bac19e341905ff374c930420b3b9c8mstarzinger@chromium.org * for a global regexp. 4918ad94b919217ffbcd2d3159eeb5f8c588761c47ager@chromium.org * - r5 : Pointer to current code object (Code*) including heap object tag. 5018ad94b919217ffbcd2d3159eeb5f8c588761c47ager@chromium.org * - r6 : Current position in input, as negative offset from end of string. 5118ad94b919217ffbcd2d3159eeb5f8c588761c47ager@chromium.org * Please notice that this is the byte offset, not the character offset! 5218ad94b919217ffbcd2d3159eeb5f8c588761c47ager@chromium.org * - r7 : Currently loaded character. Must be loaded using 5318ad94b919217ffbcd2d3159eeb5f8c588761c47ager@chromium.org * LoadCurrentCharacter before using any of the dispatch methods. 5415613d0b07bac19e341905ff374c930420b3b9c8mstarzinger@chromium.org * - r8 : Points to tip of backtrack stack 5518ad94b919217ffbcd2d3159eeb5f8c588761c47ager@chromium.org * - r9 : Unused, might be used by C code and expected unchanged. 5618ad94b919217ffbcd2d3159eeb5f8c588761c47ager@chromium.org * - r10 : End of input (points to byte after last character in input). 5718ad94b919217ffbcd2d3159eeb5f8c588761c47ager@chromium.org * - r11 : Frame pointer. Used to access arguments, local variables and 5818ad94b919217ffbcd2d3159eeb5f8c588761c47ager@chromium.org * RegExp registers. 5918ad94b919217ffbcd2d3159eeb5f8c588761c47ager@chromium.org * - r12 : IP register, used by assembler. Very volatile. 6015613d0b07bac19e341905ff374c930420b3b9c8mstarzinger@chromium.org * - r13/sp : Points to tip of C stack. 6118ad94b919217ffbcd2d3159eeb5f8c588761c47ager@chromium.org * 6218ad94b919217ffbcd2d3159eeb5f8c588761c47ager@chromium.org * The remaining registers are free for computations. 6318ad94b919217ffbcd2d3159eeb5f8c588761c47ager@chromium.org * Each call to a public method should retain this convention. 6449edbdf52640c88918f8e6638ab4965819eb1dfekmillikin@chromium.org * 6518ad94b919217ffbcd2d3159eeb5f8c588761c47ager@chromium.org * The stack will have the following structure: 6615613d0b07bac19e341905ff374c930420b3b9c8mstarzinger@chromium.org * - fp[56] Isolate* isolate (address of the current isolate) 6715613d0b07bac19e341905ff374c930420b3b9c8mstarzinger@chromium.org * - fp[52] direct_call (if 1, direct call from JavaScript code, 6815613d0b07bac19e341905ff374c930420b3b9c8mstarzinger@chromium.org * if 0, call through the runtime system). 6915613d0b07bac19e341905ff374c930420b3b9c8mstarzinger@chromium.org * - fp[48] stack_area_base (high end of the memory area to use as 7015613d0b07bac19e341905ff374c930420b3b9c8mstarzinger@chromium.org * backtracking stack). 7115613d0b07bac19e341905ff374c930420b3b9c8mstarzinger@chromium.org * - fp[44] capture array size (may fit multiple sets of matches) 7249edbdf52640c88918f8e6638ab4965819eb1dfekmillikin@chromium.org * - fp[40] int* capture_array (int[num_saved_registers_], for output). 7349edbdf52640c88918f8e6638ab4965819eb1dfekmillikin@chromium.org * - fp[36] secondary link/return address used by native call. 7449edbdf52640c88918f8e6638ab4965819eb1dfekmillikin@chromium.org * --- sp when called --- 7515613d0b07bac19e341905ff374c930420b3b9c8mstarzinger@chromium.org * - fp[32] return address (lr). 7615613d0b07bac19e341905ff374c930420b3b9c8mstarzinger@chromium.org * - fp[28] old frame pointer (r11). 7749edbdf52640c88918f8e6638ab4965819eb1dfekmillikin@chromium.org * - fp[0..24] backup of registers r4..r10. 7849edbdf52640c88918f8e6638ab4965819eb1dfekmillikin@chromium.org * --- frame pointer ---- 7915613d0b07bac19e341905ff374c930420b3b9c8mstarzinger@chromium.org * - fp[-4] end of input (address of end of string). 8015613d0b07bac19e341905ff374c930420b3b9c8mstarzinger@chromium.org * - fp[-8] start of input (address of first character in string). 8149edbdf52640c88918f8e6638ab4965819eb1dfekmillikin@chromium.org * - fp[-12] start index (character index of start). 8249edbdf52640c88918f8e6638ab4965819eb1dfekmillikin@chromium.org * - fp[-16] void* input_string (location of a handle containing the string). 8315613d0b07bac19e341905ff374c930420b3b9c8mstarzinger@chromium.org * - fp[-20] success counter (only for global regexps to count matches). 8415613d0b07bac19e341905ff374c930420b3b9c8mstarzinger@chromium.org * - fp[-24] Offset of location before start of input (effectively character 8549edbdf52640c88918f8e6638ab4965819eb1dfekmillikin@chromium.org * position -1). Used to initialize capture registers to a 8649edbdf52640c88918f8e6638ab4965819eb1dfekmillikin@chromium.org * non-position. 8715613d0b07bac19e341905ff374c930420b3b9c8mstarzinger@chromium.org * - fp[-28] At start (if 1, we are starting at the start of the 8849edbdf52640c88918f8e6638ab4965819eb1dfekmillikin@chromium.org * string, otherwise 0) 8915613d0b07bac19e341905ff374c930420b3b9c8mstarzinger@chromium.org * - fp[-32] register 0 (Only positions must be stored in the first 9049edbdf52640c88918f8e6638ab4965819eb1dfekmillikin@chromium.org * - register 1 num_saved_registers_ registers) 9149edbdf52640c88918f8e6638ab4965819eb1dfekmillikin@chromium.org * - ... 9249edbdf52640c88918f8e6638ab4965819eb1dfekmillikin@chromium.org * - register num_registers-1 9349edbdf52640c88918f8e6638ab4965819eb1dfekmillikin@chromium.org * --- sp --- 9418ad94b919217ffbcd2d3159eeb5f8c588761c47ager@chromium.org * 9518ad94b919217ffbcd2d3159eeb5f8c588761c47ager@chromium.org * The first num_saved_registers_ registers are initialized to point to 9618ad94b919217ffbcd2d3159eeb5f8c588761c47ager@chromium.org * "character -1" in the string (i.e., char_size() bytes before the first 9718ad94b919217ffbcd2d3159eeb5f8c588761c47ager@chromium.org * character of the string). The remaining registers start out as garbage. 9818ad94b919217ffbcd2d3159eeb5f8c588761c47ager@chromium.org * 9918ad94b919217ffbcd2d3159eeb5f8c588761c47ager@chromium.org * The data up to the return address must be placed there by the calling 10049edbdf52640c88918f8e6638ab4965819eb1dfekmillikin@chromium.org * code and the remaining arguments are passed in registers, e.g. by calling the 10149edbdf52640c88918f8e6638ab4965819eb1dfekmillikin@chromium.org * code entry as cast to a function with the signature: 10218ad94b919217ffbcd2d3159eeb5f8c588761c47ager@chromium.org * int (*match)(String* input_string, 1030c20e676f8a0209982ff89e5a9c707771748a585fschneider@chromium.org * int start_index, 10418ad94b919217ffbcd2d3159eeb5f8c588761c47ager@chromium.org * Address start, 10518ad94b919217ffbcd2d3159eeb5f8c588761c47ager@chromium.org * Address end, 10649edbdf52640c88918f8e6638ab4965819eb1dfekmillikin@chromium.org * Address secondary_return_address, // Only used by native call. 10718ad94b919217ffbcd2d3159eeb5f8c588761c47ager@chromium.org * int* capture_output_array, 1080c20e676f8a0209982ff89e5a9c707771748a585fschneider@chromium.org * byte* stack_area_base, 10949edbdf52640c88918f8e6638ab4965819eb1dfekmillikin@chromium.org * bool direct_call = false) 11018ad94b919217ffbcd2d3159eeb5f8c588761c47ager@chromium.org * The call is performed by NativeRegExpMacroAssembler::Execute() 11149edbdf52640c88918f8e6638ab4965819eb1dfekmillikin@chromium.org * (in regexp-macro-assembler.cc) via the CALL_GENERATED_REGEXP_CODE macro 11249edbdf52640c88918f8e6638ab4965819eb1dfekmillikin@chromium.org * in arm/simulator-arm.h. 11349edbdf52640c88918f8e6638ab4965819eb1dfekmillikin@chromium.org * When calling as a non-direct call (i.e., from C++ code), the return address 11449edbdf52640c88918f8e6638ab4965819eb1dfekmillikin@chromium.org * area is overwritten with the LR register by the RegExp code. When doing a 11549edbdf52640c88918f8e6638ab4965819eb1dfekmillikin@chromium.org * direct call from generated code, the return address is placed there by 11649edbdf52640c88918f8e6638ab4965819eb1dfekmillikin@chromium.org * the calling code, as in a normal exit frame. 11718ad94b919217ffbcd2d3159eeb5f8c588761c47ager@chromium.org */ 11818ad94b919217ffbcd2d3159eeb5f8c588761c47ager@chromium.org 11918ad94b919217ffbcd2d3159eeb5f8c588761c47ager@chromium.org#define __ ACCESS_MASM(masm_) 12018ad94b919217ffbcd2d3159eeb5f8c588761c47ager@chromium.org 12118ad94b919217ffbcd2d3159eeb5f8c588761c47ager@chromium.orgRegExpMacroAssemblerARM::RegExpMacroAssemblerARM( 12218ad94b919217ffbcd2d3159eeb5f8c588761c47ager@chromium.org Mode mode, 1237028c05c1c71b9d5c5fe1bca01f2461d17a2dda7mmassi@chromium.org int registers_to_save, 1247028c05c1c71b9d5c5fe1bca01f2461d17a2dda7mmassi@chromium.org Zone* zone) 1257028c05c1c71b9d5c5fe1bca01f2461d17a2dda7mmassi@chromium.org : NativeRegExpMacroAssembler(zone), 1261fd77d58ca66b2711f09cdea32c0c2d1a01b3ae5danno@chromium.org masm_(new MacroAssembler(zone->isolate(), NULL, kRegExpCodeSize)), 12718ad94b919217ffbcd2d3159eeb5f8c588761c47ager@chromium.org mode_(mode), 12818ad94b919217ffbcd2d3159eeb5f8c588761c47ager@chromium.org num_registers_(registers_to_save), 12918ad94b919217ffbcd2d3159eeb5f8c588761c47ager@chromium.org num_saved_registers_(registers_to_save), 13018ad94b919217ffbcd2d3159eeb5f8c588761c47ager@chromium.org entry_label_(), 13118ad94b919217ffbcd2d3159eeb5f8c588761c47ager@chromium.org start_label_(), 13218ad94b919217ffbcd2d3159eeb5f8c588761c47ager@chromium.org success_label_(), 13318ad94b919217ffbcd2d3159eeb5f8c588761c47ager@chromium.org backtrack_label_(), 13418ad94b919217ffbcd2d3159eeb5f8c588761c47ager@chromium.org exit_label_() { 13518ad94b919217ffbcd2d3159eeb5f8c588761c47ager@chromium.org ASSERT_EQ(0, registers_to_save % 2); 13618ad94b919217ffbcd2d3159eeb5f8c588761c47ager@chromium.org __ jmp(&entry_label_); // We'll write the entry code later. 13718ad94b919217ffbcd2d3159eeb5f8c588761c47ager@chromium.org __ bind(&start_label_); // And then continue from here. 138a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org} 139a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org 140a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org 14118ad94b919217ffbcd2d3159eeb5f8c588761c47ager@chromium.orgRegExpMacroAssemblerARM::~RegExpMacroAssemblerARM() { 14218ad94b919217ffbcd2d3159eeb5f8c588761c47ager@chromium.org delete masm_; 14318ad94b919217ffbcd2d3159eeb5f8c588761c47ager@chromium.org // Unuse labels in case we throw away the assembler without calling GetCode. 14418ad94b919217ffbcd2d3159eeb5f8c588761c47ager@chromium.org entry_label_.Unuse(); 14518ad94b919217ffbcd2d3159eeb5f8c588761c47ager@chromium.org start_label_.Unuse(); 14618ad94b919217ffbcd2d3159eeb5f8c588761c47ager@chromium.org success_label_.Unuse(); 14718ad94b919217ffbcd2d3159eeb5f8c588761c47ager@chromium.org backtrack_label_.Unuse(); 14818ad94b919217ffbcd2d3159eeb5f8c588761c47ager@chromium.org exit_label_.Unuse(); 14918ad94b919217ffbcd2d3159eeb5f8c588761c47ager@chromium.org check_preempt_label_.Unuse(); 15018ad94b919217ffbcd2d3159eeb5f8c588761c47ager@chromium.org stack_overflow_label_.Unuse(); 15118ad94b919217ffbcd2d3159eeb5f8c588761c47ager@chromium.org} 15218ad94b919217ffbcd2d3159eeb5f8c588761c47ager@chromium.org 15318ad94b919217ffbcd2d3159eeb5f8c588761c47ager@chromium.org 15418ad94b919217ffbcd2d3159eeb5f8c588761c47ager@chromium.orgint RegExpMacroAssemblerARM::stack_limit_slack() { 15518ad94b919217ffbcd2d3159eeb5f8c588761c47ager@chromium.org return RegExpStack::kStackLimitSlack; 15618ad94b919217ffbcd2d3159eeb5f8c588761c47ager@chromium.org} 15718ad94b919217ffbcd2d3159eeb5f8c588761c47ager@chromium.org 15818ad94b919217ffbcd2d3159eeb5f8c588761c47ager@chromium.org 15918ad94b919217ffbcd2d3159eeb5f8c588761c47ager@chromium.orgvoid RegExpMacroAssemblerARM::AdvanceCurrentPosition(int by) { 16018ad94b919217ffbcd2d3159eeb5f8c588761c47ager@chromium.org if (by != 0) { 16118ad94b919217ffbcd2d3159eeb5f8c588761c47ager@chromium.org __ add(current_input_offset(), 16218ad94b919217ffbcd2d3159eeb5f8c588761c47ager@chromium.org current_input_offset(), Operand(by * char_size())); 16318ad94b919217ffbcd2d3159eeb5f8c588761c47ager@chromium.org } 16418ad94b919217ffbcd2d3159eeb5f8c588761c47ager@chromium.org} 16518ad94b919217ffbcd2d3159eeb5f8c588761c47ager@chromium.org 16618ad94b919217ffbcd2d3159eeb5f8c588761c47ager@chromium.org 16718ad94b919217ffbcd2d3159eeb5f8c588761c47ager@chromium.orgvoid RegExpMacroAssemblerARM::AdvanceRegister(int reg, int by) { 16818ad94b919217ffbcd2d3159eeb5f8c588761c47ager@chromium.org ASSERT(reg >= 0); 16918ad94b919217ffbcd2d3159eeb5f8c588761c47ager@chromium.org ASSERT(reg < num_registers_); 17018ad94b919217ffbcd2d3159eeb5f8c588761c47ager@chromium.org if (by != 0) { 17118ad94b919217ffbcd2d3159eeb5f8c588761c47ager@chromium.org __ ldr(r0, register_location(reg)); 17218ad94b919217ffbcd2d3159eeb5f8c588761c47ager@chromium.org __ add(r0, r0, Operand(by)); 17318ad94b919217ffbcd2d3159eeb5f8c588761c47ager@chromium.org __ str(r0, register_location(reg)); 17418ad94b919217ffbcd2d3159eeb5f8c588761c47ager@chromium.org } 17518ad94b919217ffbcd2d3159eeb5f8c588761c47ager@chromium.org} 17618ad94b919217ffbcd2d3159eeb5f8c588761c47ager@chromium.org 17718ad94b919217ffbcd2d3159eeb5f8c588761c47ager@chromium.org 17818ad94b919217ffbcd2d3159eeb5f8c588761c47ager@chromium.orgvoid RegExpMacroAssemblerARM::Backtrack() { 17918ad94b919217ffbcd2d3159eeb5f8c588761c47ager@chromium.org CheckPreemption(); 18018ad94b919217ffbcd2d3159eeb5f8c588761c47ager@chromium.org // Pop Code* offset from backtrack stack, add Code* and jump to location. 18118ad94b919217ffbcd2d3159eeb5f8c588761c47ager@chromium.org Pop(r0); 182357bf65ed5309ac3a2c4bf20b6ce7770488787c2ager@chromium.org __ add(pc, r0, Operand(code_pointer())); 18318ad94b919217ffbcd2d3159eeb5f8c588761c47ager@chromium.org} 18418ad94b919217ffbcd2d3159eeb5f8c588761c47ager@chromium.org 18518ad94b919217ffbcd2d3159eeb5f8c588761c47ager@chromium.org 18618ad94b919217ffbcd2d3159eeb5f8c588761c47ager@chromium.orgvoid RegExpMacroAssemblerARM::Bind(Label* label) { 18718ad94b919217ffbcd2d3159eeb5f8c588761c47ager@chromium.org __ bind(label); 18818ad94b919217ffbcd2d3159eeb5f8c588761c47ager@chromium.org} 18918ad94b919217ffbcd2d3159eeb5f8c588761c47ager@chromium.org 19018ad94b919217ffbcd2d3159eeb5f8c588761c47ager@chromium.org 19118ad94b919217ffbcd2d3159eeb5f8c588761c47ager@chromium.orgvoid RegExpMacroAssemblerARM::CheckCharacter(uint32_t c, Label* on_equal) { 19218ad94b919217ffbcd2d3159eeb5f8c588761c47ager@chromium.org __ cmp(current_character(), Operand(c)); 19318ad94b919217ffbcd2d3159eeb5f8c588761c47ager@chromium.org BranchOrBacktrack(eq, on_equal); 19418ad94b919217ffbcd2d3159eeb5f8c588761c47ager@chromium.org} 19518ad94b919217ffbcd2d3159eeb5f8c588761c47ager@chromium.org 19618ad94b919217ffbcd2d3159eeb5f8c588761c47ager@chromium.org 19718ad94b919217ffbcd2d3159eeb5f8c588761c47ager@chromium.orgvoid RegExpMacroAssemblerARM::CheckCharacterGT(uc16 limit, Label* on_greater) { 19818ad94b919217ffbcd2d3159eeb5f8c588761c47ager@chromium.org __ cmp(current_character(), Operand(limit)); 19918ad94b919217ffbcd2d3159eeb5f8c588761c47ager@chromium.org BranchOrBacktrack(gt, on_greater); 20018ad94b919217ffbcd2d3159eeb5f8c588761c47ager@chromium.org} 20118ad94b919217ffbcd2d3159eeb5f8c588761c47ager@chromium.org 20218ad94b919217ffbcd2d3159eeb5f8c588761c47ager@chromium.org 20318ad94b919217ffbcd2d3159eeb5f8c588761c47ager@chromium.orgvoid RegExpMacroAssemblerARM::CheckAtStart(Label* on_at_start) { 20418ad94b919217ffbcd2d3159eeb5f8c588761c47ager@chromium.org Label not_at_start; 20518ad94b919217ffbcd2d3159eeb5f8c588761c47ager@chromium.org // Did we start the match at the start of the string at all? 20615613d0b07bac19e341905ff374c930420b3b9c8mstarzinger@chromium.org __ ldr(r0, MemOperand(frame_pointer(), kStartIndex)); 20759297c735ad2a41156ae9c723a39ff259ad061e0jkummerow@chromium.org __ cmp(r0, Operand::Zero()); 20815613d0b07bac19e341905ff374c930420b3b9c8mstarzinger@chromium.org BranchOrBacktrack(ne, ¬_at_start); 20918ad94b919217ffbcd2d3159eeb5f8c588761c47ager@chromium.org 21018ad94b919217ffbcd2d3159eeb5f8c588761c47ager@chromium.org // If we did, are we still at the start of the input? 21118ad94b919217ffbcd2d3159eeb5f8c588761c47ager@chromium.org __ ldr(r1, MemOperand(frame_pointer(), kInputStart)); 21218ad94b919217ffbcd2d3159eeb5f8c588761c47ager@chromium.org __ add(r0, end_of_input_address(), Operand(current_input_offset())); 21318ad94b919217ffbcd2d3159eeb5f8c588761c47ager@chromium.org __ cmp(r0, r1); 21418ad94b919217ffbcd2d3159eeb5f8c588761c47ager@chromium.org BranchOrBacktrack(eq, on_at_start); 21518ad94b919217ffbcd2d3159eeb5f8c588761c47ager@chromium.org __ bind(¬_at_start); 21618ad94b919217ffbcd2d3159eeb5f8c588761c47ager@chromium.org} 21718ad94b919217ffbcd2d3159eeb5f8c588761c47ager@chromium.org 21818ad94b919217ffbcd2d3159eeb5f8c588761c47ager@chromium.org 21918ad94b919217ffbcd2d3159eeb5f8c588761c47ager@chromium.orgvoid RegExpMacroAssemblerARM::CheckNotAtStart(Label* on_not_at_start) { 22018ad94b919217ffbcd2d3159eeb5f8c588761c47ager@chromium.org // Did we start the match at the start of the string at all? 22115613d0b07bac19e341905ff374c930420b3b9c8mstarzinger@chromium.org __ ldr(r0, MemOperand(frame_pointer(), kStartIndex)); 22259297c735ad2a41156ae9c723a39ff259ad061e0jkummerow@chromium.org __ cmp(r0, Operand::Zero()); 22315613d0b07bac19e341905ff374c930420b3b9c8mstarzinger@chromium.org BranchOrBacktrack(ne, on_not_at_start); 22418ad94b919217ffbcd2d3159eeb5f8c588761c47ager@chromium.org // If we did, are we still at the start of the input? 22518ad94b919217ffbcd2d3159eeb5f8c588761c47ager@chromium.org __ ldr(r1, MemOperand(frame_pointer(), kInputStart)); 22618ad94b919217ffbcd2d3159eeb5f8c588761c47ager@chromium.org __ add(r0, end_of_input_address(), Operand(current_input_offset())); 22718ad94b919217ffbcd2d3159eeb5f8c588761c47ager@chromium.org __ cmp(r0, r1); 22818ad94b919217ffbcd2d3159eeb5f8c588761c47ager@chromium.org BranchOrBacktrack(ne, on_not_at_start); 22918ad94b919217ffbcd2d3159eeb5f8c588761c47ager@chromium.org} 23018ad94b919217ffbcd2d3159eeb5f8c588761c47ager@chromium.org 23118ad94b919217ffbcd2d3159eeb5f8c588761c47ager@chromium.org 23218ad94b919217ffbcd2d3159eeb5f8c588761c47ager@chromium.orgvoid RegExpMacroAssemblerARM::CheckCharacterLT(uc16 limit, Label* on_less) { 23318ad94b919217ffbcd2d3159eeb5f8c588761c47ager@chromium.org __ cmp(current_character(), Operand(limit)); 23418ad94b919217ffbcd2d3159eeb5f8c588761c47ager@chromium.org BranchOrBacktrack(lt, on_less); 23518ad94b919217ffbcd2d3159eeb5f8c588761c47ager@chromium.org} 23618ad94b919217ffbcd2d3159eeb5f8c588761c47ager@chromium.org 23718ad94b919217ffbcd2d3159eeb5f8c588761c47ager@chromium.org 23818ad94b919217ffbcd2d3159eeb5f8c588761c47ager@chromium.orgvoid RegExpMacroAssemblerARM::CheckGreedyLoop(Label* on_equal) { 23918ad94b919217ffbcd2d3159eeb5f8c588761c47ager@chromium.org __ ldr(r0, MemOperand(backtrack_stackpointer(), 0)); 24018ad94b919217ffbcd2d3159eeb5f8c588761c47ager@chromium.org __ cmp(current_input_offset(), r0); 24118ad94b919217ffbcd2d3159eeb5f8c588761c47ager@chromium.org __ add(backtrack_stackpointer(), 24218ad94b919217ffbcd2d3159eeb5f8c588761c47ager@chromium.org backtrack_stackpointer(), Operand(kPointerSize), LeaveCC, eq); 24318ad94b919217ffbcd2d3159eeb5f8c588761c47ager@chromium.org BranchOrBacktrack(eq, on_equal); 24418ad94b919217ffbcd2d3159eeb5f8c588761c47ager@chromium.org} 24518ad94b919217ffbcd2d3159eeb5f8c588761c47ager@chromium.org 24618ad94b919217ffbcd2d3159eeb5f8c588761c47ager@chromium.org 24718ad94b919217ffbcd2d3159eeb5f8c588761c47ager@chromium.orgvoid RegExpMacroAssemblerARM::CheckNotBackReferenceIgnoreCase( 24818ad94b919217ffbcd2d3159eeb5f8c588761c47ager@chromium.org int start_reg, 24918ad94b919217ffbcd2d3159eeb5f8c588761c47ager@chromium.org Label* on_no_match) { 25018ad94b919217ffbcd2d3159eeb5f8c588761c47ager@chromium.org Label fallthrough; 25118ad94b919217ffbcd2d3159eeb5f8c588761c47ager@chromium.org __ ldr(r0, register_location(start_reg)); // Index of start of capture 25218ad94b919217ffbcd2d3159eeb5f8c588761c47ager@chromium.org __ ldr(r1, register_location(start_reg + 1)); // Index of end of capture 25318ad94b919217ffbcd2d3159eeb5f8c588761c47ager@chromium.org __ sub(r1, r1, r0, SetCC); // Length of capture. 25418ad94b919217ffbcd2d3159eeb5f8c588761c47ager@chromium.org 25518ad94b919217ffbcd2d3159eeb5f8c588761c47ager@chromium.org // If length is zero, either the capture is empty or it is not participating. 25618ad94b919217ffbcd2d3159eeb5f8c588761c47ager@chromium.org // In either case succeed immediately. 25718ad94b919217ffbcd2d3159eeb5f8c588761c47ager@chromium.org __ b(eq, &fallthrough); 25818ad94b919217ffbcd2d3159eeb5f8c588761c47ager@chromium.org 25918ad94b919217ffbcd2d3159eeb5f8c588761c47ager@chromium.org // Check that there are enough characters left in the input. 26018ad94b919217ffbcd2d3159eeb5f8c588761c47ager@chromium.org __ cmn(r1, Operand(current_input_offset())); 26118ad94b919217ffbcd2d3159eeb5f8c588761c47ager@chromium.org BranchOrBacktrack(gt, on_no_match); 26218ad94b919217ffbcd2d3159eeb5f8c588761c47ager@chromium.org 26318ad94b919217ffbcd2d3159eeb5f8c588761c47ager@chromium.org if (mode_ == ASCII) { 26418ad94b919217ffbcd2d3159eeb5f8c588761c47ager@chromium.org Label success; 26518ad94b919217ffbcd2d3159eeb5f8c588761c47ager@chromium.org Label fail; 26618ad94b919217ffbcd2d3159eeb5f8c588761c47ager@chromium.org Label loop_check; 26718ad94b919217ffbcd2d3159eeb5f8c588761c47ager@chromium.org 26818ad94b919217ffbcd2d3159eeb5f8c588761c47ager@chromium.org // r0 - offset of start of capture 26918ad94b919217ffbcd2d3159eeb5f8c588761c47ager@chromium.org // r1 - length of capture 27018ad94b919217ffbcd2d3159eeb5f8c588761c47ager@chromium.org __ add(r0, r0, Operand(end_of_input_address())); 27118ad94b919217ffbcd2d3159eeb5f8c588761c47ager@chromium.org __ add(r2, end_of_input_address(), Operand(current_input_offset())); 27218ad94b919217ffbcd2d3159eeb5f8c588761c47ager@chromium.org __ add(r1, r0, Operand(r1)); 27318ad94b919217ffbcd2d3159eeb5f8c588761c47ager@chromium.org 27418ad94b919217ffbcd2d3159eeb5f8c588761c47ager@chromium.org // r0 - Address of start of capture. 27518ad94b919217ffbcd2d3159eeb5f8c588761c47ager@chromium.org // r1 - Address of end of capture 27618ad94b919217ffbcd2d3159eeb5f8c588761c47ager@chromium.org // r2 - Address of current input position. 27718ad94b919217ffbcd2d3159eeb5f8c588761c47ager@chromium.org 27818ad94b919217ffbcd2d3159eeb5f8c588761c47ager@chromium.org Label loop; 27918ad94b919217ffbcd2d3159eeb5f8c588761c47ager@chromium.org __ bind(&loop); 28018ad94b919217ffbcd2d3159eeb5f8c588761c47ager@chromium.org __ ldrb(r3, MemOperand(r0, char_size(), PostIndex)); 28118ad94b919217ffbcd2d3159eeb5f8c588761c47ager@chromium.org __ ldrb(r4, MemOperand(r2, char_size(), PostIndex)); 28218ad94b919217ffbcd2d3159eeb5f8c588761c47ager@chromium.org __ cmp(r4, r3); 28318ad94b919217ffbcd2d3159eeb5f8c588761c47ager@chromium.org __ b(eq, &loop_check); 28418ad94b919217ffbcd2d3159eeb5f8c588761c47ager@chromium.org 28518ad94b919217ffbcd2d3159eeb5f8c588761c47ager@chromium.org // Mismatch, try case-insensitive match (converting letters to lower-case). 28618ad94b919217ffbcd2d3159eeb5f8c588761c47ager@chromium.org __ orr(r3, r3, Operand(0x20)); // Convert capture character to lower-case. 28718ad94b919217ffbcd2d3159eeb5f8c588761c47ager@chromium.org __ orr(r4, r4, Operand(0x20)); // Also convert input character. 28818ad94b919217ffbcd2d3159eeb5f8c588761c47ager@chromium.org __ cmp(r4, r3); 28918ad94b919217ffbcd2d3159eeb5f8c588761c47ager@chromium.org __ b(ne, &fail); 29018ad94b919217ffbcd2d3159eeb5f8c588761c47ager@chromium.org __ sub(r3, r3, Operand('a')); 29118ad94b919217ffbcd2d3159eeb5f8c588761c47ager@chromium.org __ cmp(r3, Operand('z' - 'a')); // Is r3 a lowercase letter? 29259297c735ad2a41156ae9c723a39ff259ad061e0jkummerow@chromium.org __ b(ls, &loop_check); // In range 'a'-'z'. 29359297c735ad2a41156ae9c723a39ff259ad061e0jkummerow@chromium.org // Latin-1: Check for values in range [224,254] but not 247. 29459297c735ad2a41156ae9c723a39ff259ad061e0jkummerow@chromium.org __ sub(r3, r3, Operand(224 - 'a')); 29559297c735ad2a41156ae9c723a39ff259ad061e0jkummerow@chromium.org __ cmp(r3, Operand(254 - 224)); 29659297c735ad2a41156ae9c723a39ff259ad061e0jkummerow@chromium.org __ b(hi, &fail); // Weren't Latin-1 letters. 29759297c735ad2a41156ae9c723a39ff259ad061e0jkummerow@chromium.org __ cmp(r3, Operand(247 - 224)); // Check for 247. 29859297c735ad2a41156ae9c723a39ff259ad061e0jkummerow@chromium.org __ b(eq, &fail); 29918ad94b919217ffbcd2d3159eeb5f8c588761c47ager@chromium.org 30018ad94b919217ffbcd2d3159eeb5f8c588761c47ager@chromium.org __ bind(&loop_check); 30118ad94b919217ffbcd2d3159eeb5f8c588761c47ager@chromium.org __ cmp(r0, r1); 30218ad94b919217ffbcd2d3159eeb5f8c588761c47ager@chromium.org __ b(lt, &loop); 30318ad94b919217ffbcd2d3159eeb5f8c588761c47ager@chromium.org __ jmp(&success); 30418ad94b919217ffbcd2d3159eeb5f8c588761c47ager@chromium.org 30518ad94b919217ffbcd2d3159eeb5f8c588761c47ager@chromium.org __ bind(&fail); 30618ad94b919217ffbcd2d3159eeb5f8c588761c47ager@chromium.org BranchOrBacktrack(al, on_no_match); 30718ad94b919217ffbcd2d3159eeb5f8c588761c47ager@chromium.org 30818ad94b919217ffbcd2d3159eeb5f8c588761c47ager@chromium.org __ bind(&success); 30918ad94b919217ffbcd2d3159eeb5f8c588761c47ager@chromium.org // Compute new value of character position after the matched part. 31018ad94b919217ffbcd2d3159eeb5f8c588761c47ager@chromium.org __ sub(current_input_offset(), r2, end_of_input_address()); 31118ad94b919217ffbcd2d3159eeb5f8c588761c47ager@chromium.org } else { 31218ad94b919217ffbcd2d3159eeb5f8c588761c47ager@chromium.org ASSERT(mode_ == UC16); 313c36ce6e8979bbbd43539f0a0effc87ea20dd65cckmillikin@chromium.org int argument_count = 4; 314357bf65ed5309ac3a2c4bf20b6ce7770488787c2ager@chromium.org __ PrepareCallCFunction(argument_count, r2); 31518ad94b919217ffbcd2d3159eeb5f8c588761c47ager@chromium.org 31618ad94b919217ffbcd2d3159eeb5f8c588761c47ager@chromium.org // r0 - offset of start of capture 31718ad94b919217ffbcd2d3159eeb5f8c588761c47ager@chromium.org // r1 - length of capture 31818ad94b919217ffbcd2d3159eeb5f8c588761c47ager@chromium.org 31918ad94b919217ffbcd2d3159eeb5f8c588761c47ager@chromium.org // Put arguments into arguments registers. 32018ad94b919217ffbcd2d3159eeb5f8c588761c47ager@chromium.org // Parameters are 32118ad94b919217ffbcd2d3159eeb5f8c588761c47ager@chromium.org // r0: Address byte_offset1 - Address captured substring's start. 32218ad94b919217ffbcd2d3159eeb5f8c588761c47ager@chromium.org // r1: Address byte_offset2 - Address of current character position. 32318ad94b919217ffbcd2d3159eeb5f8c588761c47ager@chromium.org // r2: size_t byte_length - length of capture in bytes(!) 324c36ce6e8979bbbd43539f0a0effc87ea20dd65cckmillikin@chromium.org // r3: Isolate* isolate 32518ad94b919217ffbcd2d3159eeb5f8c588761c47ager@chromium.org 32618ad94b919217ffbcd2d3159eeb5f8c588761c47ager@chromium.org // Address of start of capture. 32718ad94b919217ffbcd2d3159eeb5f8c588761c47ager@chromium.org __ add(r0, r0, Operand(end_of_input_address())); 32818ad94b919217ffbcd2d3159eeb5f8c588761c47ager@chromium.org // Length of capture. 32918ad94b919217ffbcd2d3159eeb5f8c588761c47ager@chromium.org __ mov(r2, Operand(r1)); 33018ad94b919217ffbcd2d3159eeb5f8c588761c47ager@chromium.org // Save length in callee-save register for use on return. 33118ad94b919217ffbcd2d3159eeb5f8c588761c47ager@chromium.org __ mov(r4, Operand(r1)); 33218ad94b919217ffbcd2d3159eeb5f8c588761c47ager@chromium.org // Address of current input position. 33318ad94b919217ffbcd2d3159eeb5f8c588761c47ager@chromium.org __ add(r1, current_input_offset(), Operand(end_of_input_address())); 334c36ce6e8979bbbd43539f0a0effc87ea20dd65cckmillikin@chromium.org // Isolate. 33532d7dbafe29be06cec1edd36c31fbe2865c799f4ulan@chromium.org __ mov(r3, Operand(ExternalReference::isolate_address(isolate()))); 33618ad94b919217ffbcd2d3159eeb5f8c588761c47ager@chromium.org 337c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com { 338c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com AllowExternalCallThatCantCauseGC scope(masm_); 339c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com ExternalReference function = 34032d7dbafe29be06cec1edd36c31fbe2865c799f4ulan@chromium.org ExternalReference::re_case_insensitive_compare_uc16(isolate()); 341c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com __ CallCFunction(function, argument_count); 342c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com } 34318ad94b919217ffbcd2d3159eeb5f8c588761c47ager@chromium.org 34418ad94b919217ffbcd2d3159eeb5f8c588761c47ager@chromium.org // Check if function returned non-zero for success or zero for failure. 34559297c735ad2a41156ae9c723a39ff259ad061e0jkummerow@chromium.org __ cmp(r0, Operand::Zero()); 34618ad94b919217ffbcd2d3159eeb5f8c588761c47ager@chromium.org BranchOrBacktrack(eq, on_no_match); 34718ad94b919217ffbcd2d3159eeb5f8c588761c47ager@chromium.org // On success, increment position by length of capture. 34818ad94b919217ffbcd2d3159eeb5f8c588761c47ager@chromium.org __ add(current_input_offset(), current_input_offset(), Operand(r4)); 34918ad94b919217ffbcd2d3159eeb5f8c588761c47ager@chromium.org } 35018ad94b919217ffbcd2d3159eeb5f8c588761c47ager@chromium.org 35118ad94b919217ffbcd2d3159eeb5f8c588761c47ager@chromium.org __ bind(&fallthrough); 35218ad94b919217ffbcd2d3159eeb5f8c588761c47ager@chromium.org} 35318ad94b919217ffbcd2d3159eeb5f8c588761c47ager@chromium.org 35418ad94b919217ffbcd2d3159eeb5f8c588761c47ager@chromium.org 35518ad94b919217ffbcd2d3159eeb5f8c588761c47ager@chromium.orgvoid RegExpMacroAssemblerARM::CheckNotBackReference( 35618ad94b919217ffbcd2d3159eeb5f8c588761c47ager@chromium.org int start_reg, 35718ad94b919217ffbcd2d3159eeb5f8c588761c47ager@chromium.org Label* on_no_match) { 35818ad94b919217ffbcd2d3159eeb5f8c588761c47ager@chromium.org Label fallthrough; 35918ad94b919217ffbcd2d3159eeb5f8c588761c47ager@chromium.org Label success; 36018ad94b919217ffbcd2d3159eeb5f8c588761c47ager@chromium.org 36118ad94b919217ffbcd2d3159eeb5f8c588761c47ager@chromium.org // Find length of back-referenced capture. 36218ad94b919217ffbcd2d3159eeb5f8c588761c47ager@chromium.org __ ldr(r0, register_location(start_reg)); 36318ad94b919217ffbcd2d3159eeb5f8c588761c47ager@chromium.org __ ldr(r1, register_location(start_reg + 1)); 36418ad94b919217ffbcd2d3159eeb5f8c588761c47ager@chromium.org __ sub(r1, r1, r0, SetCC); // Length to check. 36518ad94b919217ffbcd2d3159eeb5f8c588761c47ager@chromium.org // Succeed on empty capture (including no capture). 36618ad94b919217ffbcd2d3159eeb5f8c588761c47ager@chromium.org __ b(eq, &fallthrough); 36718ad94b919217ffbcd2d3159eeb5f8c588761c47ager@chromium.org 36818ad94b919217ffbcd2d3159eeb5f8c588761c47ager@chromium.org // Check that there are enough characters left in the input. 36918ad94b919217ffbcd2d3159eeb5f8c588761c47ager@chromium.org __ cmn(r1, Operand(current_input_offset())); 37018ad94b919217ffbcd2d3159eeb5f8c588761c47ager@chromium.org BranchOrBacktrack(gt, on_no_match); 37118ad94b919217ffbcd2d3159eeb5f8c588761c47ager@chromium.org 37218ad94b919217ffbcd2d3159eeb5f8c588761c47ager@chromium.org // Compute pointers to match string and capture string 37318ad94b919217ffbcd2d3159eeb5f8c588761c47ager@chromium.org __ add(r0, r0, Operand(end_of_input_address())); 37418ad94b919217ffbcd2d3159eeb5f8c588761c47ager@chromium.org __ add(r2, end_of_input_address(), Operand(current_input_offset())); 37518ad94b919217ffbcd2d3159eeb5f8c588761c47ager@chromium.org __ add(r1, r1, Operand(r0)); 37618ad94b919217ffbcd2d3159eeb5f8c588761c47ager@chromium.org 37718ad94b919217ffbcd2d3159eeb5f8c588761c47ager@chromium.org Label loop; 37818ad94b919217ffbcd2d3159eeb5f8c588761c47ager@chromium.org __ bind(&loop); 37918ad94b919217ffbcd2d3159eeb5f8c588761c47ager@chromium.org if (mode_ == ASCII) { 38018ad94b919217ffbcd2d3159eeb5f8c588761c47ager@chromium.org __ ldrb(r3, MemOperand(r0, char_size(), PostIndex)); 38118ad94b919217ffbcd2d3159eeb5f8c588761c47ager@chromium.org __ ldrb(r4, MemOperand(r2, char_size(), PostIndex)); 38218ad94b919217ffbcd2d3159eeb5f8c588761c47ager@chromium.org } else { 38318ad94b919217ffbcd2d3159eeb5f8c588761c47ager@chromium.org ASSERT(mode_ == UC16); 38418ad94b919217ffbcd2d3159eeb5f8c588761c47ager@chromium.org __ ldrh(r3, MemOperand(r0, char_size(), PostIndex)); 38518ad94b919217ffbcd2d3159eeb5f8c588761c47ager@chromium.org __ ldrh(r4, MemOperand(r2, char_size(), PostIndex)); 38618ad94b919217ffbcd2d3159eeb5f8c588761c47ager@chromium.org } 38718ad94b919217ffbcd2d3159eeb5f8c588761c47ager@chromium.org __ cmp(r3, r4); 38818ad94b919217ffbcd2d3159eeb5f8c588761c47ager@chromium.org BranchOrBacktrack(ne, on_no_match); 38918ad94b919217ffbcd2d3159eeb5f8c588761c47ager@chromium.org __ cmp(r0, r1); 39018ad94b919217ffbcd2d3159eeb5f8c588761c47ager@chromium.org __ b(lt, &loop); 39118ad94b919217ffbcd2d3159eeb5f8c588761c47ager@chromium.org 39218ad94b919217ffbcd2d3159eeb5f8c588761c47ager@chromium.org // Move current character position to position after match. 39318ad94b919217ffbcd2d3159eeb5f8c588761c47ager@chromium.org __ sub(current_input_offset(), r2, end_of_input_address()); 39418ad94b919217ffbcd2d3159eeb5f8c588761c47ager@chromium.org __ bind(&fallthrough); 39518ad94b919217ffbcd2d3159eeb5f8c588761c47ager@chromium.org} 39618ad94b919217ffbcd2d3159eeb5f8c588761c47ager@chromium.org 39718ad94b919217ffbcd2d3159eeb5f8c588761c47ager@chromium.org 398c6c5718277d4047fad1e034396228ce15571b5a4sgjesse@chromium.orgvoid RegExpMacroAssemblerARM::CheckNotCharacter(unsigned c, 39918ad94b919217ffbcd2d3159eeb5f8c588761c47ager@chromium.org Label* on_not_equal) { 40018ad94b919217ffbcd2d3159eeb5f8c588761c47ager@chromium.org __ cmp(current_character(), Operand(c)); 40118ad94b919217ffbcd2d3159eeb5f8c588761c47ager@chromium.org BranchOrBacktrack(ne, on_not_equal); 40218ad94b919217ffbcd2d3159eeb5f8c588761c47ager@chromium.org} 40318ad94b919217ffbcd2d3159eeb5f8c588761c47ager@chromium.org 40418ad94b919217ffbcd2d3159eeb5f8c588761c47ager@chromium.org 40518ad94b919217ffbcd2d3159eeb5f8c588761c47ager@chromium.orgvoid RegExpMacroAssemblerARM::CheckCharacterAfterAnd(uint32_t c, 40618ad94b919217ffbcd2d3159eeb5f8c588761c47ager@chromium.org uint32_t mask, 40718ad94b919217ffbcd2d3159eeb5f8c588761c47ager@chromium.org Label* on_equal) { 4087d10be581a91ab5eefa1139ff0b86c64ac8f6e59fschneider@chromium.org if (c == 0) { 4097d10be581a91ab5eefa1139ff0b86c64ac8f6e59fschneider@chromium.org __ tst(current_character(), Operand(mask)); 4107d10be581a91ab5eefa1139ff0b86c64ac8f6e59fschneider@chromium.org } else { 4117d10be581a91ab5eefa1139ff0b86c64ac8f6e59fschneider@chromium.org __ and_(r0, current_character(), Operand(mask)); 4127d10be581a91ab5eefa1139ff0b86c64ac8f6e59fschneider@chromium.org __ cmp(r0, Operand(c)); 4137d10be581a91ab5eefa1139ff0b86c64ac8f6e59fschneider@chromium.org } 41418ad94b919217ffbcd2d3159eeb5f8c588761c47ager@chromium.org BranchOrBacktrack(eq, on_equal); 41518ad94b919217ffbcd2d3159eeb5f8c588761c47ager@chromium.org} 41618ad94b919217ffbcd2d3159eeb5f8c588761c47ager@chromium.org 41718ad94b919217ffbcd2d3159eeb5f8c588761c47ager@chromium.org 418c6c5718277d4047fad1e034396228ce15571b5a4sgjesse@chromium.orgvoid RegExpMacroAssemblerARM::CheckNotCharacterAfterAnd(unsigned c, 419c6c5718277d4047fad1e034396228ce15571b5a4sgjesse@chromium.org unsigned mask, 42018ad94b919217ffbcd2d3159eeb5f8c588761c47ager@chromium.org Label* on_not_equal) { 4217d10be581a91ab5eefa1139ff0b86c64ac8f6e59fschneider@chromium.org if (c == 0) { 4227d10be581a91ab5eefa1139ff0b86c64ac8f6e59fschneider@chromium.org __ tst(current_character(), Operand(mask)); 4237d10be581a91ab5eefa1139ff0b86c64ac8f6e59fschneider@chromium.org } else { 4247d10be581a91ab5eefa1139ff0b86c64ac8f6e59fschneider@chromium.org __ and_(r0, current_character(), Operand(mask)); 4257d10be581a91ab5eefa1139ff0b86c64ac8f6e59fschneider@chromium.org __ cmp(r0, Operand(c)); 4267d10be581a91ab5eefa1139ff0b86c64ac8f6e59fschneider@chromium.org } 42718ad94b919217ffbcd2d3159eeb5f8c588761c47ager@chromium.org BranchOrBacktrack(ne, on_not_equal); 42818ad94b919217ffbcd2d3159eeb5f8c588761c47ager@chromium.org} 42918ad94b919217ffbcd2d3159eeb5f8c588761c47ager@chromium.org 43018ad94b919217ffbcd2d3159eeb5f8c588761c47ager@chromium.org 43118ad94b919217ffbcd2d3159eeb5f8c588761c47ager@chromium.orgvoid RegExpMacroAssemblerARM::CheckNotCharacterAfterMinusAnd( 43218ad94b919217ffbcd2d3159eeb5f8c588761c47ager@chromium.org uc16 c, 43318ad94b919217ffbcd2d3159eeb5f8c588761c47ager@chromium.org uc16 minus, 43418ad94b919217ffbcd2d3159eeb5f8c588761c47ager@chromium.org uc16 mask, 43518ad94b919217ffbcd2d3159eeb5f8c588761c47ager@chromium.org Label* on_not_equal) { 436154ff99473e866f5eb00a44045e27866a7fdce29yangguo@chromium.org ASSERT(minus < String::kMaxUtf16CodeUnit); 43718ad94b919217ffbcd2d3159eeb5f8c588761c47ager@chromium.org __ sub(r0, current_character(), Operand(minus)); 43818ad94b919217ffbcd2d3159eeb5f8c588761c47ager@chromium.org __ and_(r0, r0, Operand(mask)); 43918ad94b919217ffbcd2d3159eeb5f8c588761c47ager@chromium.org __ cmp(r0, Operand(c)); 44018ad94b919217ffbcd2d3159eeb5f8c588761c47ager@chromium.org BranchOrBacktrack(ne, on_not_equal); 44118ad94b919217ffbcd2d3159eeb5f8c588761c47ager@chromium.org} 44218ad94b919217ffbcd2d3159eeb5f8c588761c47ager@chromium.org 44318ad94b919217ffbcd2d3159eeb5f8c588761c47ager@chromium.org 4441456e708d277e725ca42a03463af16fe471c9210jkummerow@chromium.orgvoid RegExpMacroAssemblerARM::CheckCharacterInRange( 4451456e708d277e725ca42a03463af16fe471c9210jkummerow@chromium.org uc16 from, 4461456e708d277e725ca42a03463af16fe471c9210jkummerow@chromium.org uc16 to, 4471456e708d277e725ca42a03463af16fe471c9210jkummerow@chromium.org Label* on_in_range) { 4481456e708d277e725ca42a03463af16fe471c9210jkummerow@chromium.org __ sub(r0, current_character(), Operand(from)); 4491456e708d277e725ca42a03463af16fe471c9210jkummerow@chromium.org __ cmp(r0, Operand(to - from)); 4501456e708d277e725ca42a03463af16fe471c9210jkummerow@chromium.org BranchOrBacktrack(ls, on_in_range); // Unsigned lower-or-same condition. 4511456e708d277e725ca42a03463af16fe471c9210jkummerow@chromium.org} 4521456e708d277e725ca42a03463af16fe471c9210jkummerow@chromium.org 4531456e708d277e725ca42a03463af16fe471c9210jkummerow@chromium.org 4541456e708d277e725ca42a03463af16fe471c9210jkummerow@chromium.orgvoid RegExpMacroAssemblerARM::CheckCharacterNotInRange( 4551456e708d277e725ca42a03463af16fe471c9210jkummerow@chromium.org uc16 from, 4561456e708d277e725ca42a03463af16fe471c9210jkummerow@chromium.org uc16 to, 4571456e708d277e725ca42a03463af16fe471c9210jkummerow@chromium.org Label* on_not_in_range) { 4581456e708d277e725ca42a03463af16fe471c9210jkummerow@chromium.org __ sub(r0, current_character(), Operand(from)); 4591456e708d277e725ca42a03463af16fe471c9210jkummerow@chromium.org __ cmp(r0, Operand(to - from)); 4601456e708d277e725ca42a03463af16fe471c9210jkummerow@chromium.org BranchOrBacktrack(hi, on_not_in_range); // Unsigned higher condition. 4611456e708d277e725ca42a03463af16fe471c9210jkummerow@chromium.org} 4621456e708d277e725ca42a03463af16fe471c9210jkummerow@chromium.org 4631456e708d277e725ca42a03463af16fe471c9210jkummerow@chromium.org 4641456e708d277e725ca42a03463af16fe471c9210jkummerow@chromium.orgvoid RegExpMacroAssemblerARM::CheckBitInTable( 4651456e708d277e725ca42a03463af16fe471c9210jkummerow@chromium.org Handle<ByteArray> table, 4661456e708d277e725ca42a03463af16fe471c9210jkummerow@chromium.org Label* on_bit_set) { 4671456e708d277e725ca42a03463af16fe471c9210jkummerow@chromium.org __ mov(r0, Operand(table)); 46859297c735ad2a41156ae9c723a39ff259ad061e0jkummerow@chromium.org if (mode_ != ASCII || kTableMask != String::kMaxOneByteCharCode) { 4691456e708d277e725ca42a03463af16fe471c9210jkummerow@chromium.org __ and_(r1, current_character(), Operand(kTableSize - 1)); 4701456e708d277e725ca42a03463af16fe471c9210jkummerow@chromium.org __ add(r1, r1, Operand(ByteArray::kHeaderSize - kHeapObjectTag)); 4711456e708d277e725ca42a03463af16fe471c9210jkummerow@chromium.org } else { 4721456e708d277e725ca42a03463af16fe471c9210jkummerow@chromium.org __ add(r1, 4731456e708d277e725ca42a03463af16fe471c9210jkummerow@chromium.org current_character(), 4741456e708d277e725ca42a03463af16fe471c9210jkummerow@chromium.org Operand(ByteArray::kHeaderSize - kHeapObjectTag)); 4751456e708d277e725ca42a03463af16fe471c9210jkummerow@chromium.org } 4761456e708d277e725ca42a03463af16fe471c9210jkummerow@chromium.org __ ldrb(r0, MemOperand(r0, r1)); 47759297c735ad2a41156ae9c723a39ff259ad061e0jkummerow@chromium.org __ cmp(r0, Operand::Zero()); 4781456e708d277e725ca42a03463af16fe471c9210jkummerow@chromium.org BranchOrBacktrack(ne, on_bit_set); 4791456e708d277e725ca42a03463af16fe471c9210jkummerow@chromium.org} 4801456e708d277e725ca42a03463af16fe471c9210jkummerow@chromium.org 4811456e708d277e725ca42a03463af16fe471c9210jkummerow@chromium.org 48218ad94b919217ffbcd2d3159eeb5f8c588761c47ager@chromium.orgbool RegExpMacroAssemblerARM::CheckSpecialCharacterClass(uc16 type, 48318ad94b919217ffbcd2d3159eeb5f8c588761c47ager@chromium.org Label* on_no_match) { 48418ad94b919217ffbcd2d3159eeb5f8c588761c47ager@chromium.org // Range checks (c in min..max) are generally implemented by an unsigned 48518ad94b919217ffbcd2d3159eeb5f8c588761c47ager@chromium.org // (c - min) <= (max - min) check 48618ad94b919217ffbcd2d3159eeb5f8c588761c47ager@chromium.org switch (type) { 48718ad94b919217ffbcd2d3159eeb5f8c588761c47ager@chromium.org case 's': 48818ad94b919217ffbcd2d3159eeb5f8c588761c47ager@chromium.org // Match space-characters 48918ad94b919217ffbcd2d3159eeb5f8c588761c47ager@chromium.org if (mode_ == ASCII) { 4906e196bfaf0e555d0c835390bb6ebc0a74484491dulan@chromium.org // One byte space characters are '\t'..'\r', ' ' and \u00a0. 49118ad94b919217ffbcd2d3159eeb5f8c588761c47ager@chromium.org Label success; 49218ad94b919217ffbcd2d3159eeb5f8c588761c47ager@chromium.org __ cmp(current_character(), Operand(' ')); 49318ad94b919217ffbcd2d3159eeb5f8c588761c47ager@chromium.org __ b(eq, &success); 49418ad94b919217ffbcd2d3159eeb5f8c588761c47ager@chromium.org // Check range 0x09..0x0d 49518ad94b919217ffbcd2d3159eeb5f8c588761c47ager@chromium.org __ sub(r0, current_character(), Operand('\t')); 49618ad94b919217ffbcd2d3159eeb5f8c588761c47ager@chromium.org __ cmp(r0, Operand('\r' - '\t')); 4976e196bfaf0e555d0c835390bb6ebc0a74484491dulan@chromium.org __ b(ls, &success); 4986e196bfaf0e555d0c835390bb6ebc0a74484491dulan@chromium.org // \u00a0 (NBSP). 4996e196bfaf0e555d0c835390bb6ebc0a74484491dulan@chromium.org __ cmp(r0, Operand(0x00a0 - '\t')); 5006e196bfaf0e555d0c835390bb6ebc0a74484491dulan@chromium.org BranchOrBacktrack(ne, on_no_match); 50118ad94b919217ffbcd2d3159eeb5f8c588761c47ager@chromium.org __ bind(&success); 50218ad94b919217ffbcd2d3159eeb5f8c588761c47ager@chromium.org return true; 50318ad94b919217ffbcd2d3159eeb5f8c588761c47ager@chromium.org } 50418ad94b919217ffbcd2d3159eeb5f8c588761c47ager@chromium.org return false; 50518ad94b919217ffbcd2d3159eeb5f8c588761c47ager@chromium.org case 'S': 5066e196bfaf0e555d0c835390bb6ebc0a74484491dulan@chromium.org // The emitted code for generic character classes is good enough. 50718ad94b919217ffbcd2d3159eeb5f8c588761c47ager@chromium.org return false; 50818ad94b919217ffbcd2d3159eeb5f8c588761c47ager@chromium.org case 'd': 50918ad94b919217ffbcd2d3159eeb5f8c588761c47ager@chromium.org // Match ASCII digits ('0'..'9') 51018ad94b919217ffbcd2d3159eeb5f8c588761c47ager@chromium.org __ sub(r0, current_character(), Operand('0')); 511dfe53073738bbf16023d96fce5118358a1037fd3ulan@chromium.org __ cmp(r0, Operand('9' - '0')); 51218ad94b919217ffbcd2d3159eeb5f8c588761c47ager@chromium.org BranchOrBacktrack(hi, on_no_match); 51318ad94b919217ffbcd2d3159eeb5f8c588761c47ager@chromium.org return true; 51418ad94b919217ffbcd2d3159eeb5f8c588761c47ager@chromium.org case 'D': 51518ad94b919217ffbcd2d3159eeb5f8c588761c47ager@chromium.org // Match non ASCII-digits 51618ad94b919217ffbcd2d3159eeb5f8c588761c47ager@chromium.org __ sub(r0, current_character(), Operand('0')); 51718ad94b919217ffbcd2d3159eeb5f8c588761c47ager@chromium.org __ cmp(r0, Operand('9' - '0')); 51818ad94b919217ffbcd2d3159eeb5f8c588761c47ager@chromium.org BranchOrBacktrack(ls, on_no_match); 51918ad94b919217ffbcd2d3159eeb5f8c588761c47ager@chromium.org return true; 52018ad94b919217ffbcd2d3159eeb5f8c588761c47ager@chromium.org case '.': { 52118ad94b919217ffbcd2d3159eeb5f8c588761c47ager@chromium.org // Match non-newlines (not 0x0a('\n'), 0x0d('\r'), 0x2028 and 0x2029) 52218ad94b919217ffbcd2d3159eeb5f8c588761c47ager@chromium.org __ eor(r0, current_character(), Operand(0x01)); 52318ad94b919217ffbcd2d3159eeb5f8c588761c47ager@chromium.org // See if current character is '\n'^1 or '\r'^1, i.e., 0x0b or 0x0c 52418ad94b919217ffbcd2d3159eeb5f8c588761c47ager@chromium.org __ sub(r0, r0, Operand(0x0b)); 52518ad94b919217ffbcd2d3159eeb5f8c588761c47ager@chromium.org __ cmp(r0, Operand(0x0c - 0x0b)); 52618ad94b919217ffbcd2d3159eeb5f8c588761c47ager@chromium.org BranchOrBacktrack(ls, on_no_match); 52718ad94b919217ffbcd2d3159eeb5f8c588761c47ager@chromium.org if (mode_ == UC16) { 52818ad94b919217ffbcd2d3159eeb5f8c588761c47ager@chromium.org // Compare original value to 0x2028 and 0x2029, using the already 52918ad94b919217ffbcd2d3159eeb5f8c588761c47ager@chromium.org // computed (current_char ^ 0x01 - 0x0b). I.e., check for 53018ad94b919217ffbcd2d3159eeb5f8c588761c47ager@chromium.org // 0x201d (0x2028 - 0x0b) or 0x201e. 53118ad94b919217ffbcd2d3159eeb5f8c588761c47ager@chromium.org __ sub(r0, r0, Operand(0x2028 - 0x0b)); 53218ad94b919217ffbcd2d3159eeb5f8c588761c47ager@chromium.org __ cmp(r0, Operand(1)); 53318ad94b919217ffbcd2d3159eeb5f8c588761c47ager@chromium.org BranchOrBacktrack(ls, on_no_match); 53418ad94b919217ffbcd2d3159eeb5f8c588761c47ager@chromium.org } 53518ad94b919217ffbcd2d3159eeb5f8c588761c47ager@chromium.org return true; 53618ad94b919217ffbcd2d3159eeb5f8c588761c47ager@chromium.org } 5370c20e676f8a0209982ff89e5a9c707771748a585fschneider@chromium.org case 'n': { 538b302e56e5b70c4504faa2adf4ec3efb64a9d3e38sgjesse@chromium.org // Match newlines (0x0a('\n'), 0x0d('\r'), 0x2028 and 0x2029) 539b302e56e5b70c4504faa2adf4ec3efb64a9d3e38sgjesse@chromium.org __ eor(r0, current_character(), Operand(0x01)); 540b302e56e5b70c4504faa2adf4ec3efb64a9d3e38sgjesse@chromium.org // See if current character is '\n'^1 or '\r'^1, i.e., 0x0b or 0x0c 541b302e56e5b70c4504faa2adf4ec3efb64a9d3e38sgjesse@chromium.org __ sub(r0, r0, Operand(0x0b)); 542b302e56e5b70c4504faa2adf4ec3efb64a9d3e38sgjesse@chromium.org __ cmp(r0, Operand(0x0c - 0x0b)); 543b302e56e5b70c4504faa2adf4ec3efb64a9d3e38sgjesse@chromium.org if (mode_ == ASCII) { 544b302e56e5b70c4504faa2adf4ec3efb64a9d3e38sgjesse@chromium.org BranchOrBacktrack(hi, on_no_match); 545b302e56e5b70c4504faa2adf4ec3efb64a9d3e38sgjesse@chromium.org } else { 546b302e56e5b70c4504faa2adf4ec3efb64a9d3e38sgjesse@chromium.org Label done; 547b302e56e5b70c4504faa2adf4ec3efb64a9d3e38sgjesse@chromium.org __ b(ls, &done); 548b302e56e5b70c4504faa2adf4ec3efb64a9d3e38sgjesse@chromium.org // Compare original value to 0x2028 and 0x2029, using the already 549b302e56e5b70c4504faa2adf4ec3efb64a9d3e38sgjesse@chromium.org // computed (current_char ^ 0x01 - 0x0b). I.e., check for 550b302e56e5b70c4504faa2adf4ec3efb64a9d3e38sgjesse@chromium.org // 0x201d (0x2028 - 0x0b) or 0x201e. 551b302e56e5b70c4504faa2adf4ec3efb64a9d3e38sgjesse@chromium.org __ sub(r0, r0, Operand(0x2028 - 0x0b)); 552b302e56e5b70c4504faa2adf4ec3efb64a9d3e38sgjesse@chromium.org __ cmp(r0, Operand(1)); 553b302e56e5b70c4504faa2adf4ec3efb64a9d3e38sgjesse@chromium.org BranchOrBacktrack(hi, on_no_match); 554b302e56e5b70c4504faa2adf4ec3efb64a9d3e38sgjesse@chromium.org __ bind(&done); 5550c20e676f8a0209982ff89e5a9c707771748a585fschneider@chromium.org } 556b302e56e5b70c4504faa2adf4ec3efb64a9d3e38sgjesse@chromium.org return true; 557b302e56e5b70c4504faa2adf4ec3efb64a9d3e38sgjesse@chromium.org } 5580c20e676f8a0209982ff89e5a9c707771748a585fschneider@chromium.org case 'w': { 559b302e56e5b70c4504faa2adf4ec3efb64a9d3e38sgjesse@chromium.org if (mode_ != ASCII) { 560b302e56e5b70c4504faa2adf4ec3efb64a9d3e38sgjesse@chromium.org // Table is 128 entries, so all ASCII characters can be tested. 561b302e56e5b70c4504faa2adf4ec3efb64a9d3e38sgjesse@chromium.org __ cmp(current_character(), Operand('z')); 562b302e56e5b70c4504faa2adf4ec3efb64a9d3e38sgjesse@chromium.org BranchOrBacktrack(hi, on_no_match); 563b302e56e5b70c4504faa2adf4ec3efb64a9d3e38sgjesse@chromium.org } 564b302e56e5b70c4504faa2adf4ec3efb64a9d3e38sgjesse@chromium.org ExternalReference map = ExternalReference::re_word_character_map(); 565b302e56e5b70c4504faa2adf4ec3efb64a9d3e38sgjesse@chromium.org __ mov(r0, Operand(map)); 566b302e56e5b70c4504faa2adf4ec3efb64a9d3e38sgjesse@chromium.org __ ldrb(r0, MemOperand(r0, current_character())); 56759297c735ad2a41156ae9c723a39ff259ad061e0jkummerow@chromium.org __ cmp(r0, Operand::Zero()); 568b302e56e5b70c4504faa2adf4ec3efb64a9d3e38sgjesse@chromium.org BranchOrBacktrack(eq, on_no_match); 5690c20e676f8a0209982ff89e5a9c707771748a585fschneider@chromium.org return true; 5700c20e676f8a0209982ff89e5a9c707771748a585fschneider@chromium.org } 5710c20e676f8a0209982ff89e5a9c707771748a585fschneider@chromium.org case 'W': { 572b302e56e5b70c4504faa2adf4ec3efb64a9d3e38sgjesse@chromium.org Label done; 573b302e56e5b70c4504faa2adf4ec3efb64a9d3e38sgjesse@chromium.org if (mode_ != ASCII) { 574b302e56e5b70c4504faa2adf4ec3efb64a9d3e38sgjesse@chromium.org // Table is 128 entries, so all ASCII characters can be tested. 575b302e56e5b70c4504faa2adf4ec3efb64a9d3e38sgjesse@chromium.org __ cmp(current_character(), Operand('z')); 576b302e56e5b70c4504faa2adf4ec3efb64a9d3e38sgjesse@chromium.org __ b(hi, &done); 577b302e56e5b70c4504faa2adf4ec3efb64a9d3e38sgjesse@chromium.org } 578b302e56e5b70c4504faa2adf4ec3efb64a9d3e38sgjesse@chromium.org ExternalReference map = ExternalReference::re_word_character_map(); 579b302e56e5b70c4504faa2adf4ec3efb64a9d3e38sgjesse@chromium.org __ mov(r0, Operand(map)); 580b302e56e5b70c4504faa2adf4ec3efb64a9d3e38sgjesse@chromium.org __ ldrb(r0, MemOperand(r0, current_character())); 58159297c735ad2a41156ae9c723a39ff259ad061e0jkummerow@chromium.org __ cmp(r0, Operand::Zero()); 582b302e56e5b70c4504faa2adf4ec3efb64a9d3e38sgjesse@chromium.org BranchOrBacktrack(ne, on_no_match); 583b302e56e5b70c4504faa2adf4ec3efb64a9d3e38sgjesse@chromium.org if (mode_ != ASCII) { 584b302e56e5b70c4504faa2adf4ec3efb64a9d3e38sgjesse@chromium.org __ bind(&done); 585b302e56e5b70c4504faa2adf4ec3efb64a9d3e38sgjesse@chromium.org } 5860c20e676f8a0209982ff89e5a9c707771748a585fschneider@chromium.org return true; 5870c20e676f8a0209982ff89e5a9c707771748a585fschneider@chromium.org } 58818ad94b919217ffbcd2d3159eeb5f8c588761c47ager@chromium.org case '*': 58918ad94b919217ffbcd2d3159eeb5f8c588761c47ager@chromium.org // Match any character. 59018ad94b919217ffbcd2d3159eeb5f8c588761c47ager@chromium.org return true; 5910c20e676f8a0209982ff89e5a9c707771748a585fschneider@chromium.org // No custom implementation (yet): s(UC16), S(UC16). 59218ad94b919217ffbcd2d3159eeb5f8c588761c47ager@chromium.org default: 59318ad94b919217ffbcd2d3159eeb5f8c588761c47ager@chromium.org return false; 59418ad94b919217ffbcd2d3159eeb5f8c588761c47ager@chromium.org } 59518ad94b919217ffbcd2d3159eeb5f8c588761c47ager@chromium.org} 59618ad94b919217ffbcd2d3159eeb5f8c588761c47ager@chromium.org 59718ad94b919217ffbcd2d3159eeb5f8c588761c47ager@chromium.org 59818ad94b919217ffbcd2d3159eeb5f8c588761c47ager@chromium.orgvoid RegExpMacroAssemblerARM::Fail() { 59918ad94b919217ffbcd2d3159eeb5f8c588761c47ager@chromium.org __ mov(r0, Operand(FAILURE)); 60018ad94b919217ffbcd2d3159eeb5f8c588761c47ager@chromium.org __ jmp(&exit_label_); 60118ad94b919217ffbcd2d3159eeb5f8c588761c47ager@chromium.org} 60218ad94b919217ffbcd2d3159eeb5f8c588761c47ager@chromium.org 60318ad94b919217ffbcd2d3159eeb5f8c588761c47ager@chromium.org 60483a4728861129dc263ded92157f3e6389f851f19karlklose@chromium.orgHandle<HeapObject> RegExpMacroAssemblerARM::GetCode(Handle<String> source) { 60515613d0b07bac19e341905ff374c930420b3b9c8mstarzinger@chromium.org Label return_r0; 60618ad94b919217ffbcd2d3159eeb5f8c588761c47ager@chromium.org // Finalize code - write the entry point code now we know how many 60718ad94b919217ffbcd2d3159eeb5f8c588761c47ager@chromium.org // registers we need. 60818ad94b919217ffbcd2d3159eeb5f8c588761c47ager@chromium.org 60918ad94b919217ffbcd2d3159eeb5f8c588761c47ager@chromium.org // Entry code: 61018ad94b919217ffbcd2d3159eeb5f8c588761c47ager@chromium.org __ bind(&entry_label_); 611c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com 612c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com // Tell the system that we have a stack frame. Because the type is MANUAL, no 613c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com // is generated. 614c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com FrameScope scope(masm_, StackFrame::MANUAL); 615c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com 616c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com // Actually emit code to start a new stack frame. 61718ad94b919217ffbcd2d3159eeb5f8c588761c47ager@chromium.org // Push arguments 61818ad94b919217ffbcd2d3159eeb5f8c588761c47ager@chromium.org // Save callee-save registers. 61918ad94b919217ffbcd2d3159eeb5f8c588761c47ager@chromium.org // Start new stack frame. 62049edbdf52640c88918f8e6638ab4965819eb1dfekmillikin@chromium.org // Store link register in existing stack-cell. 62118ad94b919217ffbcd2d3159eeb5f8c588761c47ager@chromium.org // Order here should correspond to order of offset constants in header file. 62218ad94b919217ffbcd2d3159eeb5f8c588761c47ager@chromium.org RegList registers_to_retain = r4.bit() | r5.bit() | r6.bit() | 62318ad94b919217ffbcd2d3159eeb5f8c588761c47ager@chromium.org r7.bit() | r8.bit() | r9.bit() | r10.bit() | fp.bit(); 62418ad94b919217ffbcd2d3159eeb5f8c588761c47ager@chromium.org RegList argument_registers = r0.bit() | r1.bit() | r2.bit() | r3.bit(); 62518ad94b919217ffbcd2d3159eeb5f8c588761c47ager@chromium.org __ stm(db_w, sp, argument_registers | registers_to_retain | lr.bit()); 62649edbdf52640c88918f8e6638ab4965819eb1dfekmillikin@chromium.org // Set frame pointer in space for it if this is not a direct call 62749edbdf52640c88918f8e6638ab4965819eb1dfekmillikin@chromium.org // from generated code. 62818ad94b919217ffbcd2d3159eeb5f8c588761c47ager@chromium.org __ add(frame_pointer(), sp, Operand(4 * kPointerSize)); 62959297c735ad2a41156ae9c723a39ff259ad061e0jkummerow@chromium.org __ mov(r0, Operand::Zero()); 63015613d0b07bac19e341905ff374c930420b3b9c8mstarzinger@chromium.org __ push(r0); // Make room for success counter and initialize it to 0. 63118ad94b919217ffbcd2d3159eeb5f8c588761c47ager@chromium.org __ push(r0); // Make room for "position - 1" constant (value is irrelevant). 63218ad94b919217ffbcd2d3159eeb5f8c588761c47ager@chromium.org // Check if we have space on the stack for registers. 63318ad94b919217ffbcd2d3159eeb5f8c588761c47ager@chromium.org Label stack_limit_hit; 63418ad94b919217ffbcd2d3159eeb5f8c588761c47ager@chromium.org Label stack_ok; 63518ad94b919217ffbcd2d3159eeb5f8c588761c47ager@chromium.org 636c4c927273ae2b690c4a015b4640a2a469c9a1a69ager@chromium.org ExternalReference stack_limit = 63732d7dbafe29be06cec1edd36c31fbe2865c799f4ulan@chromium.org ExternalReference::address_of_stack_limit(isolate()); 638c4c927273ae2b690c4a015b4640a2a469c9a1a69ager@chromium.org __ mov(r0, Operand(stack_limit)); 63918ad94b919217ffbcd2d3159eeb5f8c588761c47ager@chromium.org __ ldr(r0, MemOperand(r0)); 64018ad94b919217ffbcd2d3159eeb5f8c588761c47ager@chromium.org __ sub(r0, sp, r0, SetCC); 64118ad94b919217ffbcd2d3159eeb5f8c588761c47ager@chromium.org // Handle it if the stack pointer is already below the stack limit. 64218ad94b919217ffbcd2d3159eeb5f8c588761c47ager@chromium.org __ b(ls, &stack_limit_hit); 64318ad94b919217ffbcd2d3159eeb5f8c588761c47ager@chromium.org // Check if there is room for the variable number of registers above 64418ad94b919217ffbcd2d3159eeb5f8c588761c47ager@chromium.org // the stack limit. 64518ad94b919217ffbcd2d3159eeb5f8c588761c47ager@chromium.org __ cmp(r0, Operand(num_registers_ * kPointerSize)); 64618ad94b919217ffbcd2d3159eeb5f8c588761c47ager@chromium.org __ b(hs, &stack_ok); 64718ad94b919217ffbcd2d3159eeb5f8c588761c47ager@chromium.org // Exit with OutOfMemory exception. There is not enough space on the stack 64818ad94b919217ffbcd2d3159eeb5f8c588761c47ager@chromium.org // for our working registers. 64918ad94b919217ffbcd2d3159eeb5f8c588761c47ager@chromium.org __ mov(r0, Operand(EXCEPTION)); 65015613d0b07bac19e341905ff374c930420b3b9c8mstarzinger@chromium.org __ jmp(&return_r0); 65118ad94b919217ffbcd2d3159eeb5f8c588761c47ager@chromium.org 65218ad94b919217ffbcd2d3159eeb5f8c588761c47ager@chromium.org __ bind(&stack_limit_hit); 65318ad94b919217ffbcd2d3159eeb5f8c588761c47ager@chromium.org CallCheckStackGuardState(r0); 65459297c735ad2a41156ae9c723a39ff259ad061e0jkummerow@chromium.org __ cmp(r0, Operand::Zero()); 65518ad94b919217ffbcd2d3159eeb5f8c588761c47ager@chromium.org // If returned value is non-zero, we exit with the returned value as result. 65615613d0b07bac19e341905ff374c930420b3b9c8mstarzinger@chromium.org __ b(ne, &return_r0); 65718ad94b919217ffbcd2d3159eeb5f8c588761c47ager@chromium.org 65818ad94b919217ffbcd2d3159eeb5f8c588761c47ager@chromium.org __ bind(&stack_ok); 65918ad94b919217ffbcd2d3159eeb5f8c588761c47ager@chromium.org 66018ad94b919217ffbcd2d3159eeb5f8c588761c47ager@chromium.org // Allocate space on stack for registers. 66118ad94b919217ffbcd2d3159eeb5f8c588761c47ager@chromium.org __ sub(sp, sp, Operand(num_registers_ * kPointerSize)); 66218ad94b919217ffbcd2d3159eeb5f8c588761c47ager@chromium.org // Load string end. 66318ad94b919217ffbcd2d3159eeb5f8c588761c47ager@chromium.org __ ldr(end_of_input_address(), MemOperand(frame_pointer(), kInputEnd)); 66418ad94b919217ffbcd2d3159eeb5f8c588761c47ager@chromium.org // Load input start. 66518ad94b919217ffbcd2d3159eeb5f8c588761c47ager@chromium.org __ ldr(r0, MemOperand(frame_pointer(), kInputStart)); 66618ad94b919217ffbcd2d3159eeb5f8c588761c47ager@chromium.org // Find negative length (offset of start relative to end). 66718ad94b919217ffbcd2d3159eeb5f8c588761c47ager@chromium.org __ sub(current_input_offset(), r0, end_of_input_address()); 668cec079d8ed1f0920a0ea3dc9a3e81966013287c1whesse@chromium.org // Set r0 to address of char before start of the input string 66918ad94b919217ffbcd2d3159eeb5f8c588761c47ager@chromium.org // (effectively string position -1). 670cec079d8ed1f0920a0ea3dc9a3e81966013287c1whesse@chromium.org __ ldr(r1, MemOperand(frame_pointer(), kStartIndex)); 67118ad94b919217ffbcd2d3159eeb5f8c588761c47ager@chromium.org __ sub(r0, current_input_offset(), Operand(char_size())); 672cec079d8ed1f0920a0ea3dc9a3e81966013287c1whesse@chromium.org __ sub(r0, r0, Operand(r1, LSL, (mode_ == UC16) ? 1 : 0)); 67318ad94b919217ffbcd2d3159eeb5f8c588761c47ager@chromium.org // Store this value in a local variable, for use when clearing 67418ad94b919217ffbcd2d3159eeb5f8c588761c47ager@chromium.org // position registers. 67518ad94b919217ffbcd2d3159eeb5f8c588761c47ager@chromium.org __ str(r0, MemOperand(frame_pointer(), kInputStartMinusOne)); 676b302e56e5b70c4504faa2adf4ec3efb64a9d3e38sgjesse@chromium.org 67715613d0b07bac19e341905ff374c930420b3b9c8mstarzinger@chromium.org // Initialize code pointer register 67815613d0b07bac19e341905ff374c930420b3b9c8mstarzinger@chromium.org __ mov(code_pointer(), Operand(masm_->CodeObject())); 67915613d0b07bac19e341905ff374c930420b3b9c8mstarzinger@chromium.org 68015613d0b07bac19e341905ff374c930420b3b9c8mstarzinger@chromium.org Label load_char_start_regexp, start_regexp; 68115613d0b07bac19e341905ff374c930420b3b9c8mstarzinger@chromium.org // Load newline if index is at start, previous character otherwise. 68259297c735ad2a41156ae9c723a39ff259ad061e0jkummerow@chromium.org __ cmp(r1, Operand::Zero()); 68315613d0b07bac19e341905ff374c930420b3b9c8mstarzinger@chromium.org __ b(ne, &load_char_start_regexp); 68415613d0b07bac19e341905ff374c930420b3b9c8mstarzinger@chromium.org __ mov(current_character(), Operand('\n'), LeaveCC, eq); 68515613d0b07bac19e341905ff374c930420b3b9c8mstarzinger@chromium.org __ jmp(&start_regexp); 68615613d0b07bac19e341905ff374c930420b3b9c8mstarzinger@chromium.org 68715613d0b07bac19e341905ff374c930420b3b9c8mstarzinger@chromium.org // Global regexp restarts matching here. 68815613d0b07bac19e341905ff374c930420b3b9c8mstarzinger@chromium.org __ bind(&load_char_start_regexp); 68915613d0b07bac19e341905ff374c930420b3b9c8mstarzinger@chromium.org // Load previous char as initial value of current character register. 69015613d0b07bac19e341905ff374c930420b3b9c8mstarzinger@chromium.org LoadCurrentCharacterUnchecked(-1, 1); 69115613d0b07bac19e341905ff374c930420b3b9c8mstarzinger@chromium.org __ bind(&start_regexp); 692b302e56e5b70c4504faa2adf4ec3efb64a9d3e38sgjesse@chromium.org 69315613d0b07bac19e341905ff374c930420b3b9c8mstarzinger@chromium.org // Initialize on-stack registers. 69418ad94b919217ffbcd2d3159eeb5f8c588761c47ager@chromium.org if (num_saved_registers_ > 0) { // Always is, if generated from a regexp. 69518ad94b919217ffbcd2d3159eeb5f8c588761c47ager@chromium.org // Fill saved registers with initial value = start offset - 1 69615613d0b07bac19e341905ff374c930420b3b9c8mstarzinger@chromium.org if (num_saved_registers_ > 8) { 69715613d0b07bac19e341905ff374c930420b3b9c8mstarzinger@chromium.org // Address of register 0. 69815613d0b07bac19e341905ff374c930420b3b9c8mstarzinger@chromium.org __ add(r1, frame_pointer(), Operand(kRegisterZero)); 69915613d0b07bac19e341905ff374c930420b3b9c8mstarzinger@chromium.org __ mov(r2, Operand(num_saved_registers_)); 70015613d0b07bac19e341905ff374c930420b3b9c8mstarzinger@chromium.org Label init_loop; 70115613d0b07bac19e341905ff374c930420b3b9c8mstarzinger@chromium.org __ bind(&init_loop); 70215613d0b07bac19e341905ff374c930420b3b9c8mstarzinger@chromium.org __ str(r0, MemOperand(r1, kPointerSize, NegPostIndex)); 70315613d0b07bac19e341905ff374c930420b3b9c8mstarzinger@chromium.org __ sub(r2, r2, Operand(1), SetCC); 70415613d0b07bac19e341905ff374c930420b3b9c8mstarzinger@chromium.org __ b(ne, &init_loop); 70515613d0b07bac19e341905ff374c930420b3b9c8mstarzinger@chromium.org } else { 70615613d0b07bac19e341905ff374c930420b3b9c8mstarzinger@chromium.org for (int i = 0; i < num_saved_registers_; i++) { 70715613d0b07bac19e341905ff374c930420b3b9c8mstarzinger@chromium.org __ str(r0, register_location(i)); 70815613d0b07bac19e341905ff374c930420b3b9c8mstarzinger@chromium.org } 70915613d0b07bac19e341905ff374c930420b3b9c8mstarzinger@chromium.org } 71018ad94b919217ffbcd2d3159eeb5f8c588761c47ager@chromium.org } 71118ad94b919217ffbcd2d3159eeb5f8c588761c47ager@chromium.org 71218ad94b919217ffbcd2d3159eeb5f8c588761c47ager@chromium.org // Initialize backtrack stack pointer. 71318ad94b919217ffbcd2d3159eeb5f8c588761c47ager@chromium.org __ ldr(backtrack_stackpointer(), MemOperand(frame_pointer(), kStackHighEnd)); 71418ad94b919217ffbcd2d3159eeb5f8c588761c47ager@chromium.org 71515613d0b07bac19e341905ff374c930420b3b9c8mstarzinger@chromium.org __ jmp(&start_label_); 71618ad94b919217ffbcd2d3159eeb5f8c588761c47ager@chromium.org 71718ad94b919217ffbcd2d3159eeb5f8c588761c47ager@chromium.org // Exit code: 71818ad94b919217ffbcd2d3159eeb5f8c588761c47ager@chromium.org if (success_label_.is_linked()) { 71918ad94b919217ffbcd2d3159eeb5f8c588761c47ager@chromium.org // Save captures when successful. 72018ad94b919217ffbcd2d3159eeb5f8c588761c47ager@chromium.org __ bind(&success_label_); 72118ad94b919217ffbcd2d3159eeb5f8c588761c47ager@chromium.org if (num_saved_registers_ > 0) { 72218ad94b919217ffbcd2d3159eeb5f8c588761c47ager@chromium.org // copy captures to output 72318ad94b919217ffbcd2d3159eeb5f8c588761c47ager@chromium.org __ ldr(r1, MemOperand(frame_pointer(), kInputStart)); 72418ad94b919217ffbcd2d3159eeb5f8c588761c47ager@chromium.org __ ldr(r0, MemOperand(frame_pointer(), kRegisterOutput)); 725cec079d8ed1f0920a0ea3dc9a3e81966013287c1whesse@chromium.org __ ldr(r2, MemOperand(frame_pointer(), kStartIndex)); 72618ad94b919217ffbcd2d3159eeb5f8c588761c47ager@chromium.org __ sub(r1, end_of_input_address(), r1); 72718ad94b919217ffbcd2d3159eeb5f8c588761c47ager@chromium.org // r1 is length of input in bytes. 72818ad94b919217ffbcd2d3159eeb5f8c588761c47ager@chromium.org if (mode_ == UC16) { 72918ad94b919217ffbcd2d3159eeb5f8c588761c47ager@chromium.org __ mov(r1, Operand(r1, LSR, 1)); 73018ad94b919217ffbcd2d3159eeb5f8c588761c47ager@chromium.org } 73118ad94b919217ffbcd2d3159eeb5f8c588761c47ager@chromium.org // r1 is length of input in characters. 732cec079d8ed1f0920a0ea3dc9a3e81966013287c1whesse@chromium.org __ add(r1, r1, Operand(r2)); 733cec079d8ed1f0920a0ea3dc9a3e81966013287c1whesse@chromium.org // r1 is length of string in characters. 73418ad94b919217ffbcd2d3159eeb5f8c588761c47ager@chromium.org 73518ad94b919217ffbcd2d3159eeb5f8c588761c47ager@chromium.org ASSERT_EQ(0, num_saved_registers_ % 2); 73618ad94b919217ffbcd2d3159eeb5f8c588761c47ager@chromium.org // Always an even number of capture registers. This allows us to 73718ad94b919217ffbcd2d3159eeb5f8c588761c47ager@chromium.org // unroll the loop once to add an operation between a load of a register 73818ad94b919217ffbcd2d3159eeb5f8c588761c47ager@chromium.org // and the following use of that register. 73918ad94b919217ffbcd2d3159eeb5f8c588761c47ager@chromium.org for (int i = 0; i < num_saved_registers_; i += 2) { 74018ad94b919217ffbcd2d3159eeb5f8c588761c47ager@chromium.org __ ldr(r2, register_location(i)); 74118ad94b919217ffbcd2d3159eeb5f8c588761c47ager@chromium.org __ ldr(r3, register_location(i + 1)); 742400388edd471bd4d4a97b21c52c1024cd1cc5708rossberg@chromium.org if (i == 0 && global_with_zero_length_check()) { 74315613d0b07bac19e341905ff374c930420b3b9c8mstarzinger@chromium.org // Keep capture start in r4 for the zero-length check later. 74415613d0b07bac19e341905ff374c930420b3b9c8mstarzinger@chromium.org __ mov(r4, r2); 74515613d0b07bac19e341905ff374c930420b3b9c8mstarzinger@chromium.org } 74618ad94b919217ffbcd2d3159eeb5f8c588761c47ager@chromium.org if (mode_ == UC16) { 74718ad94b919217ffbcd2d3159eeb5f8c588761c47ager@chromium.org __ add(r2, r1, Operand(r2, ASR, 1)); 74818ad94b919217ffbcd2d3159eeb5f8c588761c47ager@chromium.org __ add(r3, r1, Operand(r3, ASR, 1)); 74918ad94b919217ffbcd2d3159eeb5f8c588761c47ager@chromium.org } else { 75018ad94b919217ffbcd2d3159eeb5f8c588761c47ager@chromium.org __ add(r2, r1, Operand(r2)); 75118ad94b919217ffbcd2d3159eeb5f8c588761c47ager@chromium.org __ add(r3, r1, Operand(r3)); 75218ad94b919217ffbcd2d3159eeb5f8c588761c47ager@chromium.org } 75318ad94b919217ffbcd2d3159eeb5f8c588761c47ager@chromium.org __ str(r2, MemOperand(r0, kPointerSize, PostIndex)); 75418ad94b919217ffbcd2d3159eeb5f8c588761c47ager@chromium.org __ str(r3, MemOperand(r0, kPointerSize, PostIndex)); 75518ad94b919217ffbcd2d3159eeb5f8c588761c47ager@chromium.org } 75618ad94b919217ffbcd2d3159eeb5f8c588761c47ager@chromium.org } 75715613d0b07bac19e341905ff374c930420b3b9c8mstarzinger@chromium.org 75815613d0b07bac19e341905ff374c930420b3b9c8mstarzinger@chromium.org if (global()) { 75915613d0b07bac19e341905ff374c930420b3b9c8mstarzinger@chromium.org // Restart matching if the regular expression is flagged as global. 76015613d0b07bac19e341905ff374c930420b3b9c8mstarzinger@chromium.org __ ldr(r0, MemOperand(frame_pointer(), kSuccessfulCaptures)); 76115613d0b07bac19e341905ff374c930420b3b9c8mstarzinger@chromium.org __ ldr(r1, MemOperand(frame_pointer(), kNumOutputRegisters)); 76215613d0b07bac19e341905ff374c930420b3b9c8mstarzinger@chromium.org __ ldr(r2, MemOperand(frame_pointer(), kRegisterOutput)); 76315613d0b07bac19e341905ff374c930420b3b9c8mstarzinger@chromium.org // Increment success counter. 76415613d0b07bac19e341905ff374c930420b3b9c8mstarzinger@chromium.org __ add(r0, r0, Operand(1)); 76515613d0b07bac19e341905ff374c930420b3b9c8mstarzinger@chromium.org __ str(r0, MemOperand(frame_pointer(), kSuccessfulCaptures)); 76615613d0b07bac19e341905ff374c930420b3b9c8mstarzinger@chromium.org // Capture results have been stored, so the number of remaining global 76715613d0b07bac19e341905ff374c930420b3b9c8mstarzinger@chromium.org // output registers is reduced by the number of stored captures. 76815613d0b07bac19e341905ff374c930420b3b9c8mstarzinger@chromium.org __ sub(r1, r1, Operand(num_saved_registers_)); 76915613d0b07bac19e341905ff374c930420b3b9c8mstarzinger@chromium.org // Check whether we have enough room for another set of capture results. 77015613d0b07bac19e341905ff374c930420b3b9c8mstarzinger@chromium.org __ cmp(r1, Operand(num_saved_registers_)); 77115613d0b07bac19e341905ff374c930420b3b9c8mstarzinger@chromium.org __ b(lt, &return_r0); 77215613d0b07bac19e341905ff374c930420b3b9c8mstarzinger@chromium.org 77315613d0b07bac19e341905ff374c930420b3b9c8mstarzinger@chromium.org __ str(r1, MemOperand(frame_pointer(), kNumOutputRegisters)); 77415613d0b07bac19e341905ff374c930420b3b9c8mstarzinger@chromium.org // Advance the location for output. 77515613d0b07bac19e341905ff374c930420b3b9c8mstarzinger@chromium.org __ add(r2, r2, Operand(num_saved_registers_ * kPointerSize)); 77615613d0b07bac19e341905ff374c930420b3b9c8mstarzinger@chromium.org __ str(r2, MemOperand(frame_pointer(), kRegisterOutput)); 77715613d0b07bac19e341905ff374c930420b3b9c8mstarzinger@chromium.org 77815613d0b07bac19e341905ff374c930420b3b9c8mstarzinger@chromium.org // Prepare r0 to initialize registers with its value in the next run. 77915613d0b07bac19e341905ff374c930420b3b9c8mstarzinger@chromium.org __ ldr(r0, MemOperand(frame_pointer(), kInputStartMinusOne)); 780400388edd471bd4d4a97b21c52c1024cd1cc5708rossberg@chromium.org 781400388edd471bd4d4a97b21c52c1024cd1cc5708rossberg@chromium.org if (global_with_zero_length_check()) { 782400388edd471bd4d4a97b21c52c1024cd1cc5708rossberg@chromium.org // Special case for zero-length matches. 783400388edd471bd4d4a97b21c52c1024cd1cc5708rossberg@chromium.org // r4: capture start index 784400388edd471bd4d4a97b21c52c1024cd1cc5708rossberg@chromium.org __ cmp(current_input_offset(), r4); 785400388edd471bd4d4a97b21c52c1024cd1cc5708rossberg@chromium.org // Not a zero-length match, restart. 786400388edd471bd4d4a97b21c52c1024cd1cc5708rossberg@chromium.org __ b(ne, &load_char_start_regexp); 787400388edd471bd4d4a97b21c52c1024cd1cc5708rossberg@chromium.org // Offset from the end is zero if we already reached the end. 78859297c735ad2a41156ae9c723a39ff259ad061e0jkummerow@chromium.org __ cmp(current_input_offset(), Operand::Zero()); 789400388edd471bd4d4a97b21c52c1024cd1cc5708rossberg@chromium.org __ b(eq, &exit_label_); 790400388edd471bd4d4a97b21c52c1024cd1cc5708rossberg@chromium.org // Advance current position after a zero-length match. 791400388edd471bd4d4a97b21c52c1024cd1cc5708rossberg@chromium.org __ add(current_input_offset(), 792400388edd471bd4d4a97b21c52c1024cd1cc5708rossberg@chromium.org current_input_offset(), 793400388edd471bd4d4a97b21c52c1024cd1cc5708rossberg@chromium.org Operand((mode_ == UC16) ? 2 : 1)); 794400388edd471bd4d4a97b21c52c1024cd1cc5708rossberg@chromium.org } 795400388edd471bd4d4a97b21c52c1024cd1cc5708rossberg@chromium.org 79615613d0b07bac19e341905ff374c930420b3b9c8mstarzinger@chromium.org __ b(&load_char_start_regexp); 79715613d0b07bac19e341905ff374c930420b3b9c8mstarzinger@chromium.org } else { 79815613d0b07bac19e341905ff374c930420b3b9c8mstarzinger@chromium.org __ mov(r0, Operand(SUCCESS)); 79915613d0b07bac19e341905ff374c930420b3b9c8mstarzinger@chromium.org } 80018ad94b919217ffbcd2d3159eeb5f8c588761c47ager@chromium.org } 80115613d0b07bac19e341905ff374c930420b3b9c8mstarzinger@chromium.org 80218ad94b919217ffbcd2d3159eeb5f8c588761c47ager@chromium.org // Exit and return r0 80318ad94b919217ffbcd2d3159eeb5f8c588761c47ager@chromium.org __ bind(&exit_label_); 80415613d0b07bac19e341905ff374c930420b3b9c8mstarzinger@chromium.org if (global()) { 80515613d0b07bac19e341905ff374c930420b3b9c8mstarzinger@chromium.org __ ldr(r0, MemOperand(frame_pointer(), kSuccessfulCaptures)); 80615613d0b07bac19e341905ff374c930420b3b9c8mstarzinger@chromium.org } 80715613d0b07bac19e341905ff374c930420b3b9c8mstarzinger@chromium.org 80815613d0b07bac19e341905ff374c930420b3b9c8mstarzinger@chromium.org __ bind(&return_r0); 80918ad94b919217ffbcd2d3159eeb5f8c588761c47ager@chromium.org // Skip sp past regexp registers and local variables.. 81018ad94b919217ffbcd2d3159eeb5f8c588761c47ager@chromium.org __ mov(sp, frame_pointer()); 81118ad94b919217ffbcd2d3159eeb5f8c588761c47ager@chromium.org // Restore registers r4..r11 and return (restoring lr to pc). 81218ad94b919217ffbcd2d3159eeb5f8c588761c47ager@chromium.org __ ldm(ia_w, sp, registers_to_retain | pc.bit()); 81318ad94b919217ffbcd2d3159eeb5f8c588761c47ager@chromium.org 81418ad94b919217ffbcd2d3159eeb5f8c588761c47ager@chromium.org // Backtrack code (branch target for conditional backtracks). 81518ad94b919217ffbcd2d3159eeb5f8c588761c47ager@chromium.org if (backtrack_label_.is_linked()) { 81618ad94b919217ffbcd2d3159eeb5f8c588761c47ager@chromium.org __ bind(&backtrack_label_); 81718ad94b919217ffbcd2d3159eeb5f8c588761c47ager@chromium.org Backtrack(); 81818ad94b919217ffbcd2d3159eeb5f8c588761c47ager@chromium.org } 81918ad94b919217ffbcd2d3159eeb5f8c588761c47ager@chromium.org 82018ad94b919217ffbcd2d3159eeb5f8c588761c47ager@chromium.org Label exit_with_exception; 82118ad94b919217ffbcd2d3159eeb5f8c588761c47ager@chromium.org 82218ad94b919217ffbcd2d3159eeb5f8c588761c47ager@chromium.org // Preempt-code 82318ad94b919217ffbcd2d3159eeb5f8c588761c47ager@chromium.org if (check_preempt_label_.is_linked()) { 82418ad94b919217ffbcd2d3159eeb5f8c588761c47ager@chromium.org SafeCallTarget(&check_preempt_label_); 82518ad94b919217ffbcd2d3159eeb5f8c588761c47ager@chromium.org 82618ad94b919217ffbcd2d3159eeb5f8c588761c47ager@chromium.org CallCheckStackGuardState(r0); 82759297c735ad2a41156ae9c723a39ff259ad061e0jkummerow@chromium.org __ cmp(r0, Operand::Zero()); 82818ad94b919217ffbcd2d3159eeb5f8c588761c47ager@chromium.org // If returning non-zero, we should end execution with the given 82918ad94b919217ffbcd2d3159eeb5f8c588761c47ager@chromium.org // result as return value. 83015613d0b07bac19e341905ff374c930420b3b9c8mstarzinger@chromium.org __ b(ne, &return_r0); 83118ad94b919217ffbcd2d3159eeb5f8c588761c47ager@chromium.org 83218ad94b919217ffbcd2d3159eeb5f8c588761c47ager@chromium.org // String might have moved: Reload end of string from frame. 83318ad94b919217ffbcd2d3159eeb5f8c588761c47ager@chromium.org __ ldr(end_of_input_address(), MemOperand(frame_pointer(), kInputEnd)); 83418ad94b919217ffbcd2d3159eeb5f8c588761c47ager@chromium.org SafeReturn(); 83518ad94b919217ffbcd2d3159eeb5f8c588761c47ager@chromium.org } 83618ad94b919217ffbcd2d3159eeb5f8c588761c47ager@chromium.org 83718ad94b919217ffbcd2d3159eeb5f8c588761c47ager@chromium.org // Backtrack stack overflow code. 83818ad94b919217ffbcd2d3159eeb5f8c588761c47ager@chromium.org if (stack_overflow_label_.is_linked()) { 83918ad94b919217ffbcd2d3159eeb5f8c588761c47ager@chromium.org SafeCallTarget(&stack_overflow_label_); 84018ad94b919217ffbcd2d3159eeb5f8c588761c47ager@chromium.org // Reached if the backtrack-stack limit has been hit. 84118ad94b919217ffbcd2d3159eeb5f8c588761c47ager@chromium.org Label grow_failed; 84218ad94b919217ffbcd2d3159eeb5f8c588761c47ager@chromium.org 84349edbdf52640c88918f8e6638ab4965819eb1dfekmillikin@chromium.org // Call GrowStack(backtrack_stackpointer(), &stack_base) 844c36ce6e8979bbbd43539f0a0effc87ea20dd65cckmillikin@chromium.org static const int num_arguments = 3; 845357bf65ed5309ac3a2c4bf20b6ce7770488787c2ager@chromium.org __ PrepareCallCFunction(num_arguments, r0); 84618ad94b919217ffbcd2d3159eeb5f8c588761c47ager@chromium.org __ mov(r0, backtrack_stackpointer()); 84718ad94b919217ffbcd2d3159eeb5f8c588761c47ager@chromium.org __ add(r1, frame_pointer(), Operand(kStackHighEnd)); 84832d7dbafe29be06cec1edd36c31fbe2865c799f4ulan@chromium.org __ mov(r2, Operand(ExternalReference::isolate_address(isolate()))); 84918ad94b919217ffbcd2d3159eeb5f8c588761c47ager@chromium.org ExternalReference grow_stack = 85032d7dbafe29be06cec1edd36c31fbe2865c799f4ulan@chromium.org ExternalReference::re_grow_stack(isolate()); 851357bf65ed5309ac3a2c4bf20b6ce7770488787c2ager@chromium.org __ CallCFunction(grow_stack, num_arguments); 85218ad94b919217ffbcd2d3159eeb5f8c588761c47ager@chromium.org // If return NULL, we have failed to grow the stack, and 85318ad94b919217ffbcd2d3159eeb5f8c588761c47ager@chromium.org // must exit with a stack-overflow exception. 85459297c735ad2a41156ae9c723a39ff259ad061e0jkummerow@chromium.org __ cmp(r0, Operand::Zero()); 85518ad94b919217ffbcd2d3159eeb5f8c588761c47ager@chromium.org __ b(eq, &exit_with_exception); 85618ad94b919217ffbcd2d3159eeb5f8c588761c47ager@chromium.org // Otherwise use return value as new stack pointer. 85718ad94b919217ffbcd2d3159eeb5f8c588761c47ager@chromium.org __ mov(backtrack_stackpointer(), r0); 85818ad94b919217ffbcd2d3159eeb5f8c588761c47ager@chromium.org // Restore saved registers and continue. 85918ad94b919217ffbcd2d3159eeb5f8c588761c47ager@chromium.org SafeReturn(); 86018ad94b919217ffbcd2d3159eeb5f8c588761c47ager@chromium.org } 86118ad94b919217ffbcd2d3159eeb5f8c588761c47ager@chromium.org 86218ad94b919217ffbcd2d3159eeb5f8c588761c47ager@chromium.org if (exit_with_exception.is_linked()) { 86318ad94b919217ffbcd2d3159eeb5f8c588761c47ager@chromium.org // If any of the code above needed to exit with an exception. 86418ad94b919217ffbcd2d3159eeb5f8c588761c47ager@chromium.org __ bind(&exit_with_exception); 86518ad94b919217ffbcd2d3159eeb5f8c588761c47ager@chromium.org // Exit with Result EXCEPTION(-1) to signal thrown exception. 86618ad94b919217ffbcd2d3159eeb5f8c588761c47ager@chromium.org __ mov(r0, Operand(EXCEPTION)); 86715613d0b07bac19e341905ff374c930420b3b9c8mstarzinger@chromium.org __ jmp(&return_r0); 86818ad94b919217ffbcd2d3159eeb5f8c588761c47ager@chromium.org } 86918ad94b919217ffbcd2d3159eeb5f8c588761c47ager@chromium.org 87018ad94b919217ffbcd2d3159eeb5f8c588761c47ager@chromium.org CodeDesc code_desc; 87118ad94b919217ffbcd2d3159eeb5f8c588761c47ager@chromium.org masm_->GetCode(&code_desc); 872d4be0f0c0edfc0a0b46e745055c3dc497c0ffcb5verwaest@chromium.org Handle<Code> code = isolate()->factory()->NewCode( 873d4be0f0c0edfc0a0b46e745055c3dc497c0ffcb5verwaest@chromium.org code_desc, Code::ComputeFlags(Code::REGEXP), masm_->CodeObject()); 874e97852de34e44a479f092bd2449134e707cd9cf1dslomov@chromium.org PROFILE(masm_->isolate(), RegExpCodeCreateEvent(*code, *source)); 87583a4728861129dc263ded92157f3e6389f851f19karlklose@chromium.org return Handle<HeapObject>::cast(code); 87618ad94b919217ffbcd2d3159eeb5f8c588761c47ager@chromium.org} 87718ad94b919217ffbcd2d3159eeb5f8c588761c47ager@chromium.org 87818ad94b919217ffbcd2d3159eeb5f8c588761c47ager@chromium.org 87918ad94b919217ffbcd2d3159eeb5f8c588761c47ager@chromium.orgvoid RegExpMacroAssemblerARM::GoTo(Label* to) { 88018ad94b919217ffbcd2d3159eeb5f8c588761c47ager@chromium.org BranchOrBacktrack(al, to); 88118ad94b919217ffbcd2d3159eeb5f8c588761c47ager@chromium.org} 88218ad94b919217ffbcd2d3159eeb5f8c588761c47ager@chromium.org 88318ad94b919217ffbcd2d3159eeb5f8c588761c47ager@chromium.org 88418ad94b919217ffbcd2d3159eeb5f8c588761c47ager@chromium.orgvoid RegExpMacroAssemblerARM::IfRegisterGE(int reg, 88518ad94b919217ffbcd2d3159eeb5f8c588761c47ager@chromium.org int comparand, 88618ad94b919217ffbcd2d3159eeb5f8c588761c47ager@chromium.org Label* if_ge) { 88718ad94b919217ffbcd2d3159eeb5f8c588761c47ager@chromium.org __ ldr(r0, register_location(reg)); 88818ad94b919217ffbcd2d3159eeb5f8c588761c47ager@chromium.org __ cmp(r0, Operand(comparand)); 88918ad94b919217ffbcd2d3159eeb5f8c588761c47ager@chromium.org BranchOrBacktrack(ge, if_ge); 89018ad94b919217ffbcd2d3159eeb5f8c588761c47ager@chromium.org} 89118ad94b919217ffbcd2d3159eeb5f8c588761c47ager@chromium.org 89218ad94b919217ffbcd2d3159eeb5f8c588761c47ager@chromium.org 89318ad94b919217ffbcd2d3159eeb5f8c588761c47ager@chromium.orgvoid RegExpMacroAssemblerARM::IfRegisterLT(int reg, 89418ad94b919217ffbcd2d3159eeb5f8c588761c47ager@chromium.org int comparand, 89518ad94b919217ffbcd2d3159eeb5f8c588761c47ager@chromium.org Label* if_lt) { 89618ad94b919217ffbcd2d3159eeb5f8c588761c47ager@chromium.org __ ldr(r0, register_location(reg)); 89718ad94b919217ffbcd2d3159eeb5f8c588761c47ager@chromium.org __ cmp(r0, Operand(comparand)); 89818ad94b919217ffbcd2d3159eeb5f8c588761c47ager@chromium.org BranchOrBacktrack(lt, if_lt); 89918ad94b919217ffbcd2d3159eeb5f8c588761c47ager@chromium.org} 900a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org 9019a4089a092cad9ff23b6416b92cd5d818dc101d1mads.s.ager@gmail.com 90218ad94b919217ffbcd2d3159eeb5f8c588761c47ager@chromium.orgvoid RegExpMacroAssemblerARM::IfRegisterEqPos(int reg, 90318ad94b919217ffbcd2d3159eeb5f8c588761c47ager@chromium.org Label* if_eq) { 90418ad94b919217ffbcd2d3159eeb5f8c588761c47ager@chromium.org __ ldr(r0, register_location(reg)); 90518ad94b919217ffbcd2d3159eeb5f8c588761c47ager@chromium.org __ cmp(r0, Operand(current_input_offset())); 90618ad94b919217ffbcd2d3159eeb5f8c588761c47ager@chromium.org BranchOrBacktrack(eq, if_eq); 90718ad94b919217ffbcd2d3159eeb5f8c588761c47ager@chromium.org} 90818ad94b919217ffbcd2d3159eeb5f8c588761c47ager@chromium.org 90918ad94b919217ffbcd2d3159eeb5f8c588761c47ager@chromium.org 91018ad94b919217ffbcd2d3159eeb5f8c588761c47ager@chromium.orgRegExpMacroAssembler::IrregexpImplementation 91118ad94b919217ffbcd2d3159eeb5f8c588761c47ager@chromium.org RegExpMacroAssemblerARM::Implementation() { 91218ad94b919217ffbcd2d3159eeb5f8c588761c47ager@chromium.org return kARMImplementation; 91318ad94b919217ffbcd2d3159eeb5f8c588761c47ager@chromium.org} 91418ad94b919217ffbcd2d3159eeb5f8c588761c47ager@chromium.org 91518ad94b919217ffbcd2d3159eeb5f8c588761c47ager@chromium.org 91618ad94b919217ffbcd2d3159eeb5f8c588761c47ager@chromium.orgvoid RegExpMacroAssemblerARM::LoadCurrentCharacter(int cp_offset, 91718ad94b919217ffbcd2d3159eeb5f8c588761c47ager@chromium.org Label* on_end_of_input, 91818ad94b919217ffbcd2d3159eeb5f8c588761c47ager@chromium.org bool check_bounds, 91918ad94b919217ffbcd2d3159eeb5f8c588761c47ager@chromium.org int characters) { 92018ad94b919217ffbcd2d3159eeb5f8c588761c47ager@chromium.org ASSERT(cp_offset >= -1); // ^ and \b can look behind one character. 92118ad94b919217ffbcd2d3159eeb5f8c588761c47ager@chromium.org ASSERT(cp_offset < (1<<30)); // Be sane! (And ensure negation works) 92218ad94b919217ffbcd2d3159eeb5f8c588761c47ager@chromium.org if (check_bounds) { 92318ad94b919217ffbcd2d3159eeb5f8c588761c47ager@chromium.org CheckPosition(cp_offset + characters - 1, on_end_of_input); 92418ad94b919217ffbcd2d3159eeb5f8c588761c47ager@chromium.org } 92518ad94b919217ffbcd2d3159eeb5f8c588761c47ager@chromium.org LoadCurrentCharacterUnchecked(cp_offset, characters); 92618ad94b919217ffbcd2d3159eeb5f8c588761c47ager@chromium.org} 92718ad94b919217ffbcd2d3159eeb5f8c588761c47ager@chromium.org 92818ad94b919217ffbcd2d3159eeb5f8c588761c47ager@chromium.org 92918ad94b919217ffbcd2d3159eeb5f8c588761c47ager@chromium.orgvoid RegExpMacroAssemblerARM::PopCurrentPosition() { 93018ad94b919217ffbcd2d3159eeb5f8c588761c47ager@chromium.org Pop(current_input_offset()); 93118ad94b919217ffbcd2d3159eeb5f8c588761c47ager@chromium.org} 93218ad94b919217ffbcd2d3159eeb5f8c588761c47ager@chromium.org 93318ad94b919217ffbcd2d3159eeb5f8c588761c47ager@chromium.org 93418ad94b919217ffbcd2d3159eeb5f8c588761c47ager@chromium.orgvoid RegExpMacroAssemblerARM::PopRegister(int register_index) { 93518ad94b919217ffbcd2d3159eeb5f8c588761c47ager@chromium.org Pop(r0); 93618ad94b919217ffbcd2d3159eeb5f8c588761c47ager@chromium.org __ str(r0, register_location(register_index)); 93718ad94b919217ffbcd2d3159eeb5f8c588761c47ager@chromium.org} 93818ad94b919217ffbcd2d3159eeb5f8c588761c47ager@chromium.org 93918ad94b919217ffbcd2d3159eeb5f8c588761c47ager@chromium.org 94018ad94b919217ffbcd2d3159eeb5f8c588761c47ager@chromium.orgvoid RegExpMacroAssemblerARM::PushBacktrack(Label* label) { 9414a35c5a501e5b966f895ddea8e19c3ca232cb23fdslomov@chromium.org __ mov_label_offset(r0, label); 94218ad94b919217ffbcd2d3159eeb5f8c588761c47ager@chromium.org Push(r0); 94318ad94b919217ffbcd2d3159eeb5f8c588761c47ager@chromium.org CheckStackLimit(); 94418ad94b919217ffbcd2d3159eeb5f8c588761c47ager@chromium.org} 94518ad94b919217ffbcd2d3159eeb5f8c588761c47ager@chromium.org 94618ad94b919217ffbcd2d3159eeb5f8c588761c47ager@chromium.org 94718ad94b919217ffbcd2d3159eeb5f8c588761c47ager@chromium.orgvoid RegExpMacroAssemblerARM::PushCurrentPosition() { 94818ad94b919217ffbcd2d3159eeb5f8c588761c47ager@chromium.org Push(current_input_offset()); 94918ad94b919217ffbcd2d3159eeb5f8c588761c47ager@chromium.org} 95018ad94b919217ffbcd2d3159eeb5f8c588761c47ager@chromium.org 95118ad94b919217ffbcd2d3159eeb5f8c588761c47ager@chromium.org 95218ad94b919217ffbcd2d3159eeb5f8c588761c47ager@chromium.orgvoid RegExpMacroAssemblerARM::PushRegister(int register_index, 95318ad94b919217ffbcd2d3159eeb5f8c588761c47ager@chromium.org StackCheckFlag check_stack_limit) { 95418ad94b919217ffbcd2d3159eeb5f8c588761c47ager@chromium.org __ ldr(r0, register_location(register_index)); 95518ad94b919217ffbcd2d3159eeb5f8c588761c47ager@chromium.org Push(r0); 95618ad94b919217ffbcd2d3159eeb5f8c588761c47ager@chromium.org if (check_stack_limit) CheckStackLimit(); 95718ad94b919217ffbcd2d3159eeb5f8c588761c47ager@chromium.org} 95818ad94b919217ffbcd2d3159eeb5f8c588761c47ager@chromium.org 95918ad94b919217ffbcd2d3159eeb5f8c588761c47ager@chromium.org 96018ad94b919217ffbcd2d3159eeb5f8c588761c47ager@chromium.orgvoid RegExpMacroAssemblerARM::ReadCurrentPositionFromRegister(int reg) { 96118ad94b919217ffbcd2d3159eeb5f8c588761c47ager@chromium.org __ ldr(current_input_offset(), register_location(reg)); 96218ad94b919217ffbcd2d3159eeb5f8c588761c47ager@chromium.org} 96318ad94b919217ffbcd2d3159eeb5f8c588761c47ager@chromium.org 96418ad94b919217ffbcd2d3159eeb5f8c588761c47ager@chromium.org 96518ad94b919217ffbcd2d3159eeb5f8c588761c47ager@chromium.orgvoid RegExpMacroAssemblerARM::ReadStackPointerFromRegister(int reg) { 96618ad94b919217ffbcd2d3159eeb5f8c588761c47ager@chromium.org __ ldr(backtrack_stackpointer(), register_location(reg)); 96718ad94b919217ffbcd2d3159eeb5f8c588761c47ager@chromium.org __ ldr(r0, MemOperand(frame_pointer(), kStackHighEnd)); 96818ad94b919217ffbcd2d3159eeb5f8c588761c47ager@chromium.org __ add(backtrack_stackpointer(), backtrack_stackpointer(), Operand(r0)); 96918ad94b919217ffbcd2d3159eeb5f8c588761c47ager@chromium.org} 97018ad94b919217ffbcd2d3159eeb5f8c588761c47ager@chromium.org 97118ad94b919217ffbcd2d3159eeb5f8c588761c47ager@chromium.org 9724a5224e84636d192e82f288bfab0d308bdae5c37whesse@chromium.orgvoid RegExpMacroAssemblerARM::SetCurrentPositionFromEnd(int by) { 9734a5224e84636d192e82f288bfab0d308bdae5c37whesse@chromium.org Label after_position; 9744a5224e84636d192e82f288bfab0d308bdae5c37whesse@chromium.org __ cmp(current_input_offset(), Operand(-by * char_size())); 9754a5224e84636d192e82f288bfab0d308bdae5c37whesse@chromium.org __ b(ge, &after_position); 9764a5224e84636d192e82f288bfab0d308bdae5c37whesse@chromium.org __ mov(current_input_offset(), Operand(-by * char_size())); 9774a5224e84636d192e82f288bfab0d308bdae5c37whesse@chromium.org // On RegExp code entry (where this operation is used), the character before 9784a5224e84636d192e82f288bfab0d308bdae5c37whesse@chromium.org // the current position is expected to be already loaded. 9794a5224e84636d192e82f288bfab0d308bdae5c37whesse@chromium.org // We have advanced the position, so it's safe to read backwards. 9804a5224e84636d192e82f288bfab0d308bdae5c37whesse@chromium.org LoadCurrentCharacterUnchecked(-1, 1); 9814a5224e84636d192e82f288bfab0d308bdae5c37whesse@chromium.org __ bind(&after_position); 9824a5224e84636d192e82f288bfab0d308bdae5c37whesse@chromium.org} 9834a5224e84636d192e82f288bfab0d308bdae5c37whesse@chromium.org 9844a5224e84636d192e82f288bfab0d308bdae5c37whesse@chromium.org 98518ad94b919217ffbcd2d3159eeb5f8c588761c47ager@chromium.orgvoid RegExpMacroAssemblerARM::SetRegister(int register_index, int to) { 98618ad94b919217ffbcd2d3159eeb5f8c588761c47ager@chromium.org ASSERT(register_index >= num_saved_registers_); // Reserved for positions! 98718ad94b919217ffbcd2d3159eeb5f8c588761c47ager@chromium.org __ mov(r0, Operand(to)); 98818ad94b919217ffbcd2d3159eeb5f8c588761c47ager@chromium.org __ str(r0, register_location(register_index)); 98918ad94b919217ffbcd2d3159eeb5f8c588761c47ager@chromium.org} 99018ad94b919217ffbcd2d3159eeb5f8c588761c47ager@chromium.org 99118ad94b919217ffbcd2d3159eeb5f8c588761c47ager@chromium.org 99215613d0b07bac19e341905ff374c930420b3b9c8mstarzinger@chromium.orgbool RegExpMacroAssemblerARM::Succeed() { 99318ad94b919217ffbcd2d3159eeb5f8c588761c47ager@chromium.org __ jmp(&success_label_); 99415613d0b07bac19e341905ff374c930420b3b9c8mstarzinger@chromium.org return global(); 99518ad94b919217ffbcd2d3159eeb5f8c588761c47ager@chromium.org} 99618ad94b919217ffbcd2d3159eeb5f8c588761c47ager@chromium.org 99718ad94b919217ffbcd2d3159eeb5f8c588761c47ager@chromium.org 99818ad94b919217ffbcd2d3159eeb5f8c588761c47ager@chromium.orgvoid RegExpMacroAssemblerARM::WriteCurrentPositionToRegister(int reg, 99918ad94b919217ffbcd2d3159eeb5f8c588761c47ager@chromium.org int cp_offset) { 100018ad94b919217ffbcd2d3159eeb5f8c588761c47ager@chromium.org if (cp_offset == 0) { 100118ad94b919217ffbcd2d3159eeb5f8c588761c47ager@chromium.org __ str(current_input_offset(), register_location(reg)); 100218ad94b919217ffbcd2d3159eeb5f8c588761c47ager@chromium.org } else { 100318ad94b919217ffbcd2d3159eeb5f8c588761c47ager@chromium.org __ add(r0, current_input_offset(), Operand(cp_offset * char_size())); 100418ad94b919217ffbcd2d3159eeb5f8c588761c47ager@chromium.org __ str(r0, register_location(reg)); 100518ad94b919217ffbcd2d3159eeb5f8c588761c47ager@chromium.org } 100618ad94b919217ffbcd2d3159eeb5f8c588761c47ager@chromium.org} 100718ad94b919217ffbcd2d3159eeb5f8c588761c47ager@chromium.org 100818ad94b919217ffbcd2d3159eeb5f8c588761c47ager@chromium.org 100918ad94b919217ffbcd2d3159eeb5f8c588761c47ager@chromium.orgvoid RegExpMacroAssemblerARM::ClearRegisters(int reg_from, int reg_to) { 101018ad94b919217ffbcd2d3159eeb5f8c588761c47ager@chromium.org ASSERT(reg_from <= reg_to); 101118ad94b919217ffbcd2d3159eeb5f8c588761c47ager@chromium.org __ ldr(r0, MemOperand(frame_pointer(), kInputStartMinusOne)); 101218ad94b919217ffbcd2d3159eeb5f8c588761c47ager@chromium.org for (int reg = reg_from; reg <= reg_to; reg++) { 101318ad94b919217ffbcd2d3159eeb5f8c588761c47ager@chromium.org __ str(r0, register_location(reg)); 101418ad94b919217ffbcd2d3159eeb5f8c588761c47ager@chromium.org } 101518ad94b919217ffbcd2d3159eeb5f8c588761c47ager@chromium.org} 101618ad94b919217ffbcd2d3159eeb5f8c588761c47ager@chromium.org 101718ad94b919217ffbcd2d3159eeb5f8c588761c47ager@chromium.org 101818ad94b919217ffbcd2d3159eeb5f8c588761c47ager@chromium.orgvoid RegExpMacroAssemblerARM::WriteStackPointerToRegister(int reg) { 101918ad94b919217ffbcd2d3159eeb5f8c588761c47ager@chromium.org __ ldr(r1, MemOperand(frame_pointer(), kStackHighEnd)); 102018ad94b919217ffbcd2d3159eeb5f8c588761c47ager@chromium.org __ sub(r0, backtrack_stackpointer(), r1); 102118ad94b919217ffbcd2d3159eeb5f8c588761c47ager@chromium.org __ str(r0, register_location(reg)); 102218ad94b919217ffbcd2d3159eeb5f8c588761c47ager@chromium.org} 102318ad94b919217ffbcd2d3159eeb5f8c588761c47ager@chromium.org 102418ad94b919217ffbcd2d3159eeb5f8c588761c47ager@chromium.org 102518ad94b919217ffbcd2d3159eeb5f8c588761c47ager@chromium.org// Private methods: 102618ad94b919217ffbcd2d3159eeb5f8c588761c47ager@chromium.org 102718ad94b919217ffbcd2d3159eeb5f8c588761c47ager@chromium.orgvoid RegExpMacroAssemblerARM::CallCheckStackGuardState(Register scratch) { 1028c5d4971574b7a205fa0e788d8121dc79485e5e67hpayer@chromium.org __ PrepareCallCFunction(3, scratch); 1029c5d4971574b7a205fa0e788d8121dc79485e5e67hpayer@chromium.org 103018ad94b919217ffbcd2d3159eeb5f8c588761c47ager@chromium.org // RegExp code frame pointer. 103118ad94b919217ffbcd2d3159eeb5f8c588761c47ager@chromium.org __ mov(r2, frame_pointer()); 103218ad94b919217ffbcd2d3159eeb5f8c588761c47ager@chromium.org // Code* of self. 103318ad94b919217ffbcd2d3159eeb5f8c588761c47ager@chromium.org __ mov(r1, Operand(masm_->CodeObject())); 1034c5d4971574b7a205fa0e788d8121dc79485e5e67hpayer@chromium.org 1035c5d4971574b7a205fa0e788d8121dc79485e5e67hpayer@chromium.org // We need to make room for the return address on the stack. 1036c5d4971574b7a205fa0e788d8121dc79485e5e67hpayer@chromium.org int stack_alignment = OS::ActivationFrameAlignment(); 1037c5d4971574b7a205fa0e788d8121dc79485e5e67hpayer@chromium.org ASSERT(IsAligned(stack_alignment, kPointerSize)); 1038c5d4971574b7a205fa0e788d8121dc79485e5e67hpayer@chromium.org __ sub(sp, sp, Operand(stack_alignment)); 1039c5d4971574b7a205fa0e788d8121dc79485e5e67hpayer@chromium.org 1040c5d4971574b7a205fa0e788d8121dc79485e5e67hpayer@chromium.org // r0 will point to the return address, placed by DirectCEntry. 1041c5d4971574b7a205fa0e788d8121dc79485e5e67hpayer@chromium.org __ mov(r0, sp); 1042c5d4971574b7a205fa0e788d8121dc79485e5e67hpayer@chromium.org 104318ad94b919217ffbcd2d3159eeb5f8c588761c47ager@chromium.org ExternalReference stack_guard_check = 104432d7dbafe29be06cec1edd36c31fbe2865c799f4ulan@chromium.org ExternalReference::re_check_stack_guard_state(isolate()); 1045c5d4971574b7a205fa0e788d8121dc79485e5e67hpayer@chromium.org __ mov(ip, Operand(stack_guard_check)); 1046c5d4971574b7a205fa0e788d8121dc79485e5e67hpayer@chromium.org DirectCEntryStub stub; 1047c5d4971574b7a205fa0e788d8121dc79485e5e67hpayer@chromium.org stub.GenerateCall(masm_, ip); 1048c5d4971574b7a205fa0e788d8121dc79485e5e67hpayer@chromium.org 1049c5d4971574b7a205fa0e788d8121dc79485e5e67hpayer@chromium.org // Drop the return address from the stack. 1050c5d4971574b7a205fa0e788d8121dc79485e5e67hpayer@chromium.org __ add(sp, sp, Operand(stack_alignment)); 1051c5d4971574b7a205fa0e788d8121dc79485e5e67hpayer@chromium.org 1052c5d4971574b7a205fa0e788d8121dc79485e5e67hpayer@chromium.org ASSERT(stack_alignment != 0); 1053c5d4971574b7a205fa0e788d8121dc79485e5e67hpayer@chromium.org __ ldr(sp, MemOperand(sp, 0)); 1054c5d4971574b7a205fa0e788d8121dc79485e5e67hpayer@chromium.org 1055c5d4971574b7a205fa0e788d8121dc79485e5e67hpayer@chromium.org __ mov(code_pointer(), Operand(masm_->CodeObject())); 105618ad94b919217ffbcd2d3159eeb5f8c588761c47ager@chromium.org} 105718ad94b919217ffbcd2d3159eeb5f8c588761c47ager@chromium.org 105818ad94b919217ffbcd2d3159eeb5f8c588761c47ager@chromium.org 105918ad94b919217ffbcd2d3159eeb5f8c588761c47ager@chromium.org// Helper function for reading a value out of a stack frame. 106018ad94b919217ffbcd2d3159eeb5f8c588761c47ager@chromium.orgtemplate <typename T> 106118ad94b919217ffbcd2d3159eeb5f8c588761c47ager@chromium.orgstatic T& frame_entry(Address re_frame, int frame_offset) { 106218ad94b919217ffbcd2d3159eeb5f8c588761c47ager@chromium.org return reinterpret_cast<T&>(Memory::int32_at(re_frame + frame_offset)); 106318ad94b919217ffbcd2d3159eeb5f8c588761c47ager@chromium.org} 106418ad94b919217ffbcd2d3159eeb5f8c588761c47ager@chromium.org 106518ad94b919217ffbcd2d3159eeb5f8c588761c47ager@chromium.org 106618ad94b919217ffbcd2d3159eeb5f8c588761c47ager@chromium.orgint RegExpMacroAssemblerARM::CheckStackGuardState(Address* return_address, 106718ad94b919217ffbcd2d3159eeb5f8c588761c47ager@chromium.org Code* re_code, 106818ad94b919217ffbcd2d3159eeb5f8c588761c47ager@chromium.org Address re_frame) { 1069ea88ce93dcb41a9200ec8747ae7642a5db1f4ce7sgjesse@chromium.org Isolate* isolate = frame_entry<Isolate*>(re_frame, kIsolate); 1070ea88ce93dcb41a9200ec8747ae7642a5db1f4ce7sgjesse@chromium.org if (isolate->stack_guard()->IsStackOverflow()) { 1071ea88ce93dcb41a9200ec8747ae7642a5db1f4ce7sgjesse@chromium.org isolate->StackOverflow(); 107218ad94b919217ffbcd2d3159eeb5f8c588761c47ager@chromium.org return EXCEPTION; 107318ad94b919217ffbcd2d3159eeb5f8c588761c47ager@chromium.org } 107418ad94b919217ffbcd2d3159eeb5f8c588761c47ager@chromium.org 107518ad94b919217ffbcd2d3159eeb5f8c588761c47ager@chromium.org // If not real stack overflow the stack guard was used to interrupt 107618ad94b919217ffbcd2d3159eeb5f8c588761c47ager@chromium.org // execution for another purpose. 107718ad94b919217ffbcd2d3159eeb5f8c588761c47ager@chromium.org 1078c9c80823e038328f2e1060d7feef0762a50adf06ricow@chromium.org // If this is a direct call from JavaScript retry the RegExp forcing the call 1079c9c80823e038328f2e1060d7feef0762a50adf06ricow@chromium.org // through the runtime system. Currently the direct call cannot handle a GC. 1080c9c80823e038328f2e1060d7feef0762a50adf06ricow@chromium.org if (frame_entry<int>(re_frame, kDirectCall) == 1) { 1081c9c80823e038328f2e1060d7feef0762a50adf06ricow@chromium.org return RETRY; 1082c9c80823e038328f2e1060d7feef0762a50adf06ricow@chromium.org } 1083c9c80823e038328f2e1060d7feef0762a50adf06ricow@chromium.org 108418ad94b919217ffbcd2d3159eeb5f8c588761c47ager@chromium.org // Prepare for possible GC. 10854668a2c7a746d01b382f23aa32e163701e3075f8ricow@chromium.org HandleScope handles(isolate); 108618ad94b919217ffbcd2d3159eeb5f8c588761c47ager@chromium.org Handle<Code> code_handle(re_code); 108718ad94b919217ffbcd2d3159eeb5f8c588761c47ager@chromium.org 108818ad94b919217ffbcd2d3159eeb5f8c588761c47ager@chromium.org Handle<String> subject(frame_entry<String*>(re_frame, kInputString)); 10894668a2c7a746d01b382f23aa32e163701e3075f8ricow@chromium.org 109018ad94b919217ffbcd2d3159eeb5f8c588761c47ager@chromium.org // Current string. 10918e8d8825f97138de12985f8e0d3163074dff5258ulan@chromium.org bool is_ascii = subject->IsOneByteRepresentationUnderneath(); 109218ad94b919217ffbcd2d3159eeb5f8c588761c47ager@chromium.org 109318ad94b919217ffbcd2d3159eeb5f8c588761c47ager@chromium.org ASSERT(re_code->instruction_start() <= *return_address); 109418ad94b919217ffbcd2d3159eeb5f8c588761c47ager@chromium.org ASSERT(*return_address <= 109518ad94b919217ffbcd2d3159eeb5f8c588761c47ager@chromium.org re_code->instruction_start() + re_code->instruction_size()); 109618ad94b919217ffbcd2d3159eeb5f8c588761c47ager@chromium.org 1097812308e1488cd8261e4dbbda1d8022642d522b9bulan@chromium.org MaybeObject* result = Execution::HandleStackGuardInterrupt(isolate); 109818ad94b919217ffbcd2d3159eeb5f8c588761c47ager@chromium.org 109918ad94b919217ffbcd2d3159eeb5f8c588761c47ager@chromium.org if (*code_handle != re_code) { // Return address no longer valid 110080c42ed5ace766a3a02b30a53a25e5e81e234723yangguo@chromium.org int delta = code_handle->address() - re_code->address(); 110118ad94b919217ffbcd2d3159eeb5f8c588761c47ager@chromium.org // Overwrite the return address on the stack. 110218ad94b919217ffbcd2d3159eeb5f8c588761c47ager@chromium.org *return_address += delta; 110318ad94b919217ffbcd2d3159eeb5f8c588761c47ager@chromium.org } 110418ad94b919217ffbcd2d3159eeb5f8c588761c47ager@chromium.org 110518ad94b919217ffbcd2d3159eeb5f8c588761c47ager@chromium.org if (result->IsException()) { 110618ad94b919217ffbcd2d3159eeb5f8c588761c47ager@chromium.org return EXCEPTION; 110718ad94b919217ffbcd2d3159eeb5f8c588761c47ager@chromium.org } 110818ad94b919217ffbcd2d3159eeb5f8c588761c47ager@chromium.org 11094668a2c7a746d01b382f23aa32e163701e3075f8ricow@chromium.org Handle<String> subject_tmp = subject; 11104668a2c7a746d01b382f23aa32e163701e3075f8ricow@chromium.org int slice_offset = 0; 11114668a2c7a746d01b382f23aa32e163701e3075f8ricow@chromium.org 11124668a2c7a746d01b382f23aa32e163701e3075f8ricow@chromium.org // Extract the underlying string and the slice offset. 11134668a2c7a746d01b382f23aa32e163701e3075f8ricow@chromium.org if (StringShape(*subject_tmp).IsCons()) { 11144668a2c7a746d01b382f23aa32e163701e3075f8ricow@chromium.org subject_tmp = Handle<String>(ConsString::cast(*subject_tmp)->first()); 11154668a2c7a746d01b382f23aa32e163701e3075f8ricow@chromium.org } else if (StringShape(*subject_tmp).IsSliced()) { 11164668a2c7a746d01b382f23aa32e163701e3075f8ricow@chromium.org SlicedString* slice = SlicedString::cast(*subject_tmp); 11174668a2c7a746d01b382f23aa32e163701e3075f8ricow@chromium.org subject_tmp = Handle<String>(slice->parent()); 11184668a2c7a746d01b382f23aa32e163701e3075f8ricow@chromium.org slice_offset = slice->offset(); 11194668a2c7a746d01b382f23aa32e163701e3075f8ricow@chromium.org } 11204668a2c7a746d01b382f23aa32e163701e3075f8ricow@chromium.org 112118ad94b919217ffbcd2d3159eeb5f8c588761c47ager@chromium.org // String might have changed. 11228e8d8825f97138de12985f8e0d3163074dff5258ulan@chromium.org if (subject_tmp->IsOneByteRepresentation() != is_ascii) { 112318ad94b919217ffbcd2d3159eeb5f8c588761c47ager@chromium.org // If we changed between an ASCII and an UC16 string, the specialized 112418ad94b919217ffbcd2d3159eeb5f8c588761c47ager@chromium.org // code cannot be used, and we need to restart regexp matching from 112518ad94b919217ffbcd2d3159eeb5f8c588761c47ager@chromium.org // scratch (including, potentially, compiling a new version of the code). 112618ad94b919217ffbcd2d3159eeb5f8c588761c47ager@chromium.org return RETRY; 112718ad94b919217ffbcd2d3159eeb5f8c588761c47ager@chromium.org } 112818ad94b919217ffbcd2d3159eeb5f8c588761c47ager@chromium.org 112918ad94b919217ffbcd2d3159eeb5f8c588761c47ager@chromium.org // Otherwise, the content of the string might have moved. It must still 113018ad94b919217ffbcd2d3159eeb5f8c588761c47ager@chromium.org // be a sequential or external string with the same content. 113118ad94b919217ffbcd2d3159eeb5f8c588761c47ager@chromium.org // Update the start and end pointers in the stack frame to the current 113218ad94b919217ffbcd2d3159eeb5f8c588761c47ager@chromium.org // location (whether it has actually moved or not). 11334668a2c7a746d01b382f23aa32e163701e3075f8ricow@chromium.org ASSERT(StringShape(*subject_tmp).IsSequential() || 11344668a2c7a746d01b382f23aa32e163701e3075f8ricow@chromium.org StringShape(*subject_tmp).IsExternal()); 113518ad94b919217ffbcd2d3159eeb5f8c588761c47ager@chromium.org 113618ad94b919217ffbcd2d3159eeb5f8c588761c47ager@chromium.org // The original start address of the characters to match. 113718ad94b919217ffbcd2d3159eeb5f8c588761c47ager@chromium.org const byte* start_address = frame_entry<const byte*>(re_frame, kInputStart); 113818ad94b919217ffbcd2d3159eeb5f8c588761c47ager@chromium.org 113918ad94b919217ffbcd2d3159eeb5f8c588761c47ager@chromium.org // Find the current start address of the same character at the current string 114018ad94b919217ffbcd2d3159eeb5f8c588761c47ager@chromium.org // position. 114118ad94b919217ffbcd2d3159eeb5f8c588761c47ager@chromium.org int start_index = frame_entry<int>(re_frame, kStartIndex); 11424668a2c7a746d01b382f23aa32e163701e3075f8ricow@chromium.org const byte* new_address = StringCharacterPosition(*subject_tmp, 11434668a2c7a746d01b382f23aa32e163701e3075f8ricow@chromium.org start_index + slice_offset); 114418ad94b919217ffbcd2d3159eeb5f8c588761c47ager@chromium.org 114518ad94b919217ffbcd2d3159eeb5f8c588761c47ager@chromium.org if (start_address != new_address) { 114618ad94b919217ffbcd2d3159eeb5f8c588761c47ager@chromium.org // If there is a difference, update the object pointer and start and end 114718ad94b919217ffbcd2d3159eeb5f8c588761c47ager@chromium.org // addresses in the RegExp stack frame to match the new value. 114818ad94b919217ffbcd2d3159eeb5f8c588761c47ager@chromium.org const byte* end_address = frame_entry<const byte* >(re_frame, kInputEnd); 11494668a2c7a746d01b382f23aa32e163701e3075f8ricow@chromium.org int byte_length = static_cast<int>(end_address - start_address); 115018ad94b919217ffbcd2d3159eeb5f8c588761c47ager@chromium.org frame_entry<const String*>(re_frame, kInputString) = *subject; 115118ad94b919217ffbcd2d3159eeb5f8c588761c47ager@chromium.org frame_entry<const byte*>(re_frame, kInputStart) = new_address; 115218ad94b919217ffbcd2d3159eeb5f8c588761c47ager@chromium.org frame_entry<const byte*>(re_frame, kInputEnd) = new_address + byte_length; 1153394dbcf9009cf5203b6d85e8b515fcff072040f3erik.corry@gmail.com } else if (frame_entry<const String*>(re_frame, kInputString) != *subject) { 1154394dbcf9009cf5203b6d85e8b515fcff072040f3erik.corry@gmail.com // Subject string might have been a ConsString that underwent 1155394dbcf9009cf5203b6d85e8b515fcff072040f3erik.corry@gmail.com // short-circuiting during GC. That will not change start_address but 1156394dbcf9009cf5203b6d85e8b515fcff072040f3erik.corry@gmail.com // will change pointer inside the subject handle. 1157394dbcf9009cf5203b6d85e8b515fcff072040f3erik.corry@gmail.com frame_entry<const String*>(re_frame, kInputString) = *subject; 115818ad94b919217ffbcd2d3159eeb5f8c588761c47ager@chromium.org } 115918ad94b919217ffbcd2d3159eeb5f8c588761c47ager@chromium.org 116018ad94b919217ffbcd2d3159eeb5f8c588761c47ager@chromium.org return 0; 116118ad94b919217ffbcd2d3159eeb5f8c588761c47ager@chromium.org} 116218ad94b919217ffbcd2d3159eeb5f8c588761c47ager@chromium.org 116318ad94b919217ffbcd2d3159eeb5f8c588761c47ager@chromium.org 116418ad94b919217ffbcd2d3159eeb5f8c588761c47ager@chromium.orgMemOperand RegExpMacroAssemblerARM::register_location(int register_index) { 116518ad94b919217ffbcd2d3159eeb5f8c588761c47ager@chromium.org ASSERT(register_index < (1<<30)); 116618ad94b919217ffbcd2d3159eeb5f8c588761c47ager@chromium.org if (num_registers_ <= register_index) { 116718ad94b919217ffbcd2d3159eeb5f8c588761c47ager@chromium.org num_registers_ = register_index + 1; 116818ad94b919217ffbcd2d3159eeb5f8c588761c47ager@chromium.org } 116918ad94b919217ffbcd2d3159eeb5f8c588761c47ager@chromium.org return MemOperand(frame_pointer(), 117018ad94b919217ffbcd2d3159eeb5f8c588761c47ager@chromium.org kRegisterZero - register_index * kPointerSize); 117118ad94b919217ffbcd2d3159eeb5f8c588761c47ager@chromium.org} 117218ad94b919217ffbcd2d3159eeb5f8c588761c47ager@chromium.org 117318ad94b919217ffbcd2d3159eeb5f8c588761c47ager@chromium.org 117418ad94b919217ffbcd2d3159eeb5f8c588761c47ager@chromium.orgvoid RegExpMacroAssemblerARM::CheckPosition(int cp_offset, 117518ad94b919217ffbcd2d3159eeb5f8c588761c47ager@chromium.org Label* on_outside_input) { 117618ad94b919217ffbcd2d3159eeb5f8c588761c47ager@chromium.org __ cmp(current_input_offset(), Operand(-cp_offset * char_size())); 117718ad94b919217ffbcd2d3159eeb5f8c588761c47ager@chromium.org BranchOrBacktrack(ge, on_outside_input); 117818ad94b919217ffbcd2d3159eeb5f8c588761c47ager@chromium.org} 117918ad94b919217ffbcd2d3159eeb5f8c588761c47ager@chromium.org 118018ad94b919217ffbcd2d3159eeb5f8c588761c47ager@chromium.org 118118ad94b919217ffbcd2d3159eeb5f8c588761c47ager@chromium.orgvoid RegExpMacroAssemblerARM::BranchOrBacktrack(Condition condition, 118218ad94b919217ffbcd2d3159eeb5f8c588761c47ager@chromium.org Label* to) { 118318ad94b919217ffbcd2d3159eeb5f8c588761c47ager@chromium.org if (condition == al) { // Unconditional. 118418ad94b919217ffbcd2d3159eeb5f8c588761c47ager@chromium.org if (to == NULL) { 118518ad94b919217ffbcd2d3159eeb5f8c588761c47ager@chromium.org Backtrack(); 118618ad94b919217ffbcd2d3159eeb5f8c588761c47ager@chromium.org return; 118718ad94b919217ffbcd2d3159eeb5f8c588761c47ager@chromium.org } 118818ad94b919217ffbcd2d3159eeb5f8c588761c47ager@chromium.org __ jmp(to); 118918ad94b919217ffbcd2d3159eeb5f8c588761c47ager@chromium.org return; 119018ad94b919217ffbcd2d3159eeb5f8c588761c47ager@chromium.org } 119118ad94b919217ffbcd2d3159eeb5f8c588761c47ager@chromium.org if (to == NULL) { 119218ad94b919217ffbcd2d3159eeb5f8c588761c47ager@chromium.org __ b(condition, &backtrack_label_); 119318ad94b919217ffbcd2d3159eeb5f8c588761c47ager@chromium.org return; 119418ad94b919217ffbcd2d3159eeb5f8c588761c47ager@chromium.org } 119518ad94b919217ffbcd2d3159eeb5f8c588761c47ager@chromium.org __ b(condition, to); 119618ad94b919217ffbcd2d3159eeb5f8c588761c47ager@chromium.org} 119718ad94b919217ffbcd2d3159eeb5f8c588761c47ager@chromium.org 119818ad94b919217ffbcd2d3159eeb5f8c588761c47ager@chromium.org 119918ad94b919217ffbcd2d3159eeb5f8c588761c47ager@chromium.orgvoid RegExpMacroAssemblerARM::SafeCall(Label* to, Condition cond) { 120018ad94b919217ffbcd2d3159eeb5f8c588761c47ager@chromium.org __ bl(to, cond); 120118ad94b919217ffbcd2d3159eeb5f8c588761c47ager@chromium.org} 120218ad94b919217ffbcd2d3159eeb5f8c588761c47ager@chromium.org 120318ad94b919217ffbcd2d3159eeb5f8c588761c47ager@chromium.org 120418ad94b919217ffbcd2d3159eeb5f8c588761c47ager@chromium.orgvoid RegExpMacroAssemblerARM::SafeReturn() { 120518ad94b919217ffbcd2d3159eeb5f8c588761c47ager@chromium.org __ pop(lr); 120618ad94b919217ffbcd2d3159eeb5f8c588761c47ager@chromium.org __ add(pc, lr, Operand(masm_->CodeObject())); 120718ad94b919217ffbcd2d3159eeb5f8c588761c47ager@chromium.org} 120818ad94b919217ffbcd2d3159eeb5f8c588761c47ager@chromium.org 120918ad94b919217ffbcd2d3159eeb5f8c588761c47ager@chromium.org 121018ad94b919217ffbcd2d3159eeb5f8c588761c47ager@chromium.orgvoid RegExpMacroAssemblerARM::SafeCallTarget(Label* name) { 121118ad94b919217ffbcd2d3159eeb5f8c588761c47ager@chromium.org __ bind(name); 121218ad94b919217ffbcd2d3159eeb5f8c588761c47ager@chromium.org __ sub(lr, lr, Operand(masm_->CodeObject())); 121318ad94b919217ffbcd2d3159eeb5f8c588761c47ager@chromium.org __ push(lr); 121418ad94b919217ffbcd2d3159eeb5f8c588761c47ager@chromium.org} 121518ad94b919217ffbcd2d3159eeb5f8c588761c47ager@chromium.org 121618ad94b919217ffbcd2d3159eeb5f8c588761c47ager@chromium.org 121718ad94b919217ffbcd2d3159eeb5f8c588761c47ager@chromium.orgvoid RegExpMacroAssemblerARM::Push(Register source) { 121818ad94b919217ffbcd2d3159eeb5f8c588761c47ager@chromium.org ASSERT(!source.is(backtrack_stackpointer())); 121918ad94b919217ffbcd2d3159eeb5f8c588761c47ager@chromium.org __ str(source, 122018ad94b919217ffbcd2d3159eeb5f8c588761c47ager@chromium.org MemOperand(backtrack_stackpointer(), kPointerSize, NegPreIndex)); 122118ad94b919217ffbcd2d3159eeb5f8c588761c47ager@chromium.org} 122218ad94b919217ffbcd2d3159eeb5f8c588761c47ager@chromium.org 122318ad94b919217ffbcd2d3159eeb5f8c588761c47ager@chromium.org 122418ad94b919217ffbcd2d3159eeb5f8c588761c47ager@chromium.orgvoid RegExpMacroAssemblerARM::Pop(Register target) { 122518ad94b919217ffbcd2d3159eeb5f8c588761c47ager@chromium.org ASSERT(!target.is(backtrack_stackpointer())); 122618ad94b919217ffbcd2d3159eeb5f8c588761c47ager@chromium.org __ ldr(target, 122718ad94b919217ffbcd2d3159eeb5f8c588761c47ager@chromium.org MemOperand(backtrack_stackpointer(), kPointerSize, PostIndex)); 122818ad94b919217ffbcd2d3159eeb5f8c588761c47ager@chromium.org} 122918ad94b919217ffbcd2d3159eeb5f8c588761c47ager@chromium.org 123018ad94b919217ffbcd2d3159eeb5f8c588761c47ager@chromium.org 123118ad94b919217ffbcd2d3159eeb5f8c588761c47ager@chromium.orgvoid RegExpMacroAssemblerARM::CheckPreemption() { 123218ad94b919217ffbcd2d3159eeb5f8c588761c47ager@chromium.org // Check for preemption. 1233c4c927273ae2b690c4a015b4640a2a469c9a1a69ager@chromium.org ExternalReference stack_limit = 123432d7dbafe29be06cec1edd36c31fbe2865c799f4ulan@chromium.org ExternalReference::address_of_stack_limit(isolate()); 1235c4c927273ae2b690c4a015b4640a2a469c9a1a69ager@chromium.org __ mov(r0, Operand(stack_limit)); 123618ad94b919217ffbcd2d3159eeb5f8c588761c47ager@chromium.org __ ldr(r0, MemOperand(r0)); 123718ad94b919217ffbcd2d3159eeb5f8c588761c47ager@chromium.org __ cmp(sp, r0); 123818ad94b919217ffbcd2d3159eeb5f8c588761c47ager@chromium.org SafeCall(&check_preempt_label_, ls); 123918ad94b919217ffbcd2d3159eeb5f8c588761c47ager@chromium.org} 124018ad94b919217ffbcd2d3159eeb5f8c588761c47ager@chromium.org 124118ad94b919217ffbcd2d3159eeb5f8c588761c47ager@chromium.org 124218ad94b919217ffbcd2d3159eeb5f8c588761c47ager@chromium.orgvoid RegExpMacroAssemblerARM::CheckStackLimit() { 12433811b436bf328d2ace6fe79ce99aeda71f9f06d3ager@chromium.org ExternalReference stack_limit = 124432d7dbafe29be06cec1edd36c31fbe2865c799f4ulan@chromium.org ExternalReference::address_of_regexp_stack_limit(isolate()); 12453811b436bf328d2ace6fe79ce99aeda71f9f06d3ager@chromium.org __ mov(r0, Operand(stack_limit)); 12463811b436bf328d2ace6fe79ce99aeda71f9f06d3ager@chromium.org __ ldr(r0, MemOperand(r0)); 12473811b436bf328d2ace6fe79ce99aeda71f9f06d3ager@chromium.org __ cmp(backtrack_stackpointer(), Operand(r0)); 12483811b436bf328d2ace6fe79ce99aeda71f9f06d3ager@chromium.org SafeCall(&stack_overflow_label_, ls); 124918ad94b919217ffbcd2d3159eeb5f8c588761c47ager@chromium.org} 125018ad94b919217ffbcd2d3159eeb5f8c588761c47ager@chromium.org 125118ad94b919217ffbcd2d3159eeb5f8c588761c47ager@chromium.org 125289e18f5599cb4cd462cb1ed324addd7388fb4d60rossberg@chromium.orgbool RegExpMacroAssemblerARM::CanReadUnaligned() { 125389e18f5599cb4cd462cb1ed324addd7388fb4d60rossberg@chromium.org return CpuFeatures::IsSupported(UNALIGNED_ACCESSES) && !slow_safe(); 125489e18f5599cb4cd462cb1ed324addd7388fb4d60rossberg@chromium.org} 125589e18f5599cb4cd462cb1ed324addd7388fb4d60rossberg@chromium.org 125689e18f5599cb4cd462cb1ed324addd7388fb4d60rossberg@chromium.org 125718ad94b919217ffbcd2d3159eeb5f8c588761c47ager@chromium.orgvoid RegExpMacroAssemblerARM::LoadCurrentCharacterUnchecked(int cp_offset, 125818ad94b919217ffbcd2d3159eeb5f8c588761c47ager@chromium.org int characters) { 125918ad94b919217ffbcd2d3159eeb5f8c588761c47ager@chromium.org Register offset = current_input_offset(); 126018ad94b919217ffbcd2d3159eeb5f8c588761c47ager@chromium.org if (cp_offset != 0) { 126115613d0b07bac19e341905ff374c930420b3b9c8mstarzinger@chromium.org // r4 is not being used to store the capture start index at this point. 126215613d0b07bac19e341905ff374c930420b3b9c8mstarzinger@chromium.org __ add(r4, current_input_offset(), Operand(cp_offset * char_size())); 126315613d0b07bac19e341905ff374c930420b3b9c8mstarzinger@chromium.org offset = r4; 126418ad94b919217ffbcd2d3159eeb5f8c588761c47ager@chromium.org } 1265720dc0bc17114e33b9b2177fcb6726bda9cabd62sgjesse@chromium.org // The ldr, str, ldrh, strh instructions can do unaligned accesses, if the CPU 1266720dc0bc17114e33b9b2177fcb6726bda9cabd62sgjesse@chromium.org // and the operating system running on the target allow it. 1267720dc0bc17114e33b9b2177fcb6726bda9cabd62sgjesse@chromium.org // If unaligned load/stores are not supported then this function must only 1268720dc0bc17114e33b9b2177fcb6726bda9cabd62sgjesse@chromium.org // be used to load a single character at a time. 126989e18f5599cb4cd462cb1ed324addd7388fb4d60rossberg@chromium.org if (!CanReadUnaligned()) { 127089e18f5599cb4cd462cb1ed324addd7388fb4d60rossberg@chromium.org ASSERT(characters == 1); 127189e18f5599cb4cd462cb1ed324addd7388fb4d60rossberg@chromium.org } 1272720dc0bc17114e33b9b2177fcb6726bda9cabd62sgjesse@chromium.org 127318ad94b919217ffbcd2d3159eeb5f8c588761c47ager@chromium.org if (mode_ == ASCII) { 1274720dc0bc17114e33b9b2177fcb6726bda9cabd62sgjesse@chromium.org if (characters == 4) { 1275720dc0bc17114e33b9b2177fcb6726bda9cabd62sgjesse@chromium.org __ ldr(current_character(), MemOperand(end_of_input_address(), offset)); 1276720dc0bc17114e33b9b2177fcb6726bda9cabd62sgjesse@chromium.org } else if (characters == 2) { 1277720dc0bc17114e33b9b2177fcb6726bda9cabd62sgjesse@chromium.org __ ldrh(current_character(), MemOperand(end_of_input_address(), offset)); 1278720dc0bc17114e33b9b2177fcb6726bda9cabd62sgjesse@chromium.org } else { 1279720dc0bc17114e33b9b2177fcb6726bda9cabd62sgjesse@chromium.org ASSERT(characters == 1); 1280720dc0bc17114e33b9b2177fcb6726bda9cabd62sgjesse@chromium.org __ ldrb(current_character(), MemOperand(end_of_input_address(), offset)); 1281720dc0bc17114e33b9b2177fcb6726bda9cabd62sgjesse@chromium.org } 128218ad94b919217ffbcd2d3159eeb5f8c588761c47ager@chromium.org } else { 128318ad94b919217ffbcd2d3159eeb5f8c588761c47ager@chromium.org ASSERT(mode_ == UC16); 1284720dc0bc17114e33b9b2177fcb6726bda9cabd62sgjesse@chromium.org if (characters == 2) { 1285720dc0bc17114e33b9b2177fcb6726bda9cabd62sgjesse@chromium.org __ ldr(current_character(), MemOperand(end_of_input_address(), offset)); 1286720dc0bc17114e33b9b2177fcb6726bda9cabd62sgjesse@chromium.org } else { 1287720dc0bc17114e33b9b2177fcb6726bda9cabd62sgjesse@chromium.org ASSERT(characters == 1); 1288720dc0bc17114e33b9b2177fcb6726bda9cabd62sgjesse@chromium.org __ ldrh(current_character(), MemOperand(end_of_input_address(), offset)); 1289720dc0bc17114e33b9b2177fcb6726bda9cabd62sgjesse@chromium.org } 129018ad94b919217ffbcd2d3159eeb5f8c588761c47ager@chromium.org } 129118ad94b919217ffbcd2d3159eeb5f8c588761c47ager@chromium.org} 129218ad94b919217ffbcd2d3159eeb5f8c588761c47ager@chromium.org 129318ad94b919217ffbcd2d3159eeb5f8c588761c47ager@chromium.org 129418ad94b919217ffbcd2d3159eeb5f8c588761c47ager@chromium.org#undef __ 129518ad94b919217ffbcd2d3159eeb5f8c588761c47ager@chromium.org 1296c9c80823e038328f2e1060d7feef0762a50adf06ricow@chromium.org#endif // V8_INTERPRETED_REGEXP 129718ad94b919217ffbcd2d3159eeb5f8c588761c47ager@chromium.org 129818ad94b919217ffbcd2d3159eeb5f8c588761c47ager@chromium.org}} // namespace v8::internal 12999dfbea4c7d423c7bc1db94425cb78e7f7cf41f78erik.corry@gmail.com 13009dfbea4c7d423c7bc1db94425cb78e7f7cf41f78erik.corry@gmail.com#endif // V8_TARGET_ARCH_ARM 1301