// Copyright 2006-2010 the V8 project authors. All rights reserved. // Redistribution and use in source and binary forms, with or without // modification, are permitted provided that the following conditions are // met: // // * Redistributions of source code must retain the above copyright // notice, this list of conditions and the following disclaimer. // * Redistributions in binary form must reproduce the above // copyright notice, this list of conditions and the following // disclaimer in the documentation and/or other materials provided // with the distribution. // * Neither the name of Google Inc. nor the names of its // contributors may be used to endorse or promote products derived // from this software without specific prior written permission. // // THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS // "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT // LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR // A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT // OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, // SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT // LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, // DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY // THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT // (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE // OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. #include "v8.h" #if defined(V8_TARGET_ARCH_MIPS) #include "unicode.h" #include "log.h" #include "code-stubs.h" #include "regexp-stack.h" #include "macro-assembler.h" #include "regexp-macro-assembler.h" #include "mips/regexp-macro-assembler-mips.h" namespace v8 { namespace internal { #ifndef V8_INTERPRETED_REGEXP /* * This assembler uses the following register assignment convention * - t1 : Pointer to current code object (Code*) including heap object tag. * - t2 : Current position in input, as negative offset from end of string. * Please notice that this is the byte offset, not the character offset! * - t3 : Currently loaded character. Must be loaded using * LoadCurrentCharacter before using any of the dispatch methods. * - t4 : points to tip of backtrack stack * - t5 : Unused. * - t6 : End of input (points to byte after last character in input). * - fp : Frame pointer. Used to access arguments, local variables and * RegExp registers. * - sp : points to tip of C stack. * * The remaining registers are free for computations. * * Each call to a public method should retain this convention. * The stack will have the following structure: * - direct_call (if 1, direct call from JavaScript code, if 0 call * through the runtime system) * - stack_area_base (High end of the memory area to use as * backtracking stack) * - int* capture_array (int[num_saved_registers_], for output). * - stack frame header (16 bytes in size) * --- sp when called --- * - link address * - backup of registers s0..s7 * - end of input (Address of end of string) * - start of input (Address of first character in string) * - start index (character index of start) * --- frame pointer ---- * - void* input_string (location of a handle containing the string) * - Offset of location before start of input (effectively character * position -1). Used to initialize capture registers to a non-position. * - At start (if 1, we are starting at the start of the * string, otherwise 0) * - register 0 (Only positions must be stored in the first * - register 1 num_saved_registers_ registers) * - ... * - register num_registers-1 * --- sp --- * * The first num_saved_registers_ registers are initialized to point to * "character -1" in the string (i.e., char_size() bytes before the first * character of the string). The remaining registers start out as garbage. * * The data up to the return address must be placed there by the calling * code, by calling the code entry as cast to a function with the signature: * int (*match)(String* input_string, * int start_index, * Address start, * Address end, * int* capture_output_array, * bool at_start, * byte* stack_area_base, * bool direct_call) * The call is performed by NativeRegExpMacroAssembler::Execute() * (in regexp-macro-assembler.cc). */ #define __ ACCESS_MASM(masm_) RegExpMacroAssemblerMIPS::RegExpMacroAssemblerMIPS( Mode mode, int registers_to_save) : masm_(new MacroAssembler(NULL, kRegExpCodeSize)), mode_(mode), num_registers_(registers_to_save), num_saved_registers_(registers_to_save), entry_label_(), start_label_(), success_label_(), backtrack_label_(), exit_label_() { ASSERT_EQ(0, registers_to_save % 2); __ jmp(&entry_label_); // We'll write the entry code later. __ bind(&start_label_); // And then continue from here. } RegExpMacroAssemblerMIPS::~RegExpMacroAssemblerMIPS() { delete masm_; // Unuse labels in case we throw away the assembler without calling GetCode. entry_label_.Unuse(); start_label_.Unuse(); success_label_.Unuse(); backtrack_label_.Unuse(); exit_label_.Unuse(); check_preempt_label_.Unuse(); stack_overflow_label_.Unuse(); } int RegExpMacroAssemblerMIPS::stack_limit_slack() { return RegExpStack::kStackLimitSlack; } void RegExpMacroAssemblerMIPS::AdvanceCurrentPosition(int by) { UNIMPLEMENTED_MIPS(); } void RegExpMacroAssemblerMIPS::AdvanceRegister(int reg, int by) { UNIMPLEMENTED_MIPS(); } void RegExpMacroAssemblerMIPS::Backtrack() { UNIMPLEMENTED_MIPS(); } void RegExpMacroAssemblerMIPS::Bind(Label* label) { UNIMPLEMENTED_MIPS(); } void RegExpMacroAssemblerMIPS::CheckCharacter(uint32_t c, Label* on_equal) { UNIMPLEMENTED_MIPS(); } void RegExpMacroAssemblerMIPS::CheckCharacterGT(uc16 limit, Label* on_greater) { UNIMPLEMENTED_MIPS(); } void RegExpMacroAssemblerMIPS::CheckAtStart(Label* on_at_start) { UNIMPLEMENTED_MIPS(); } void RegExpMacroAssemblerMIPS::CheckNotAtStart(Label* on_not_at_start) { UNIMPLEMENTED_MIPS(); } void RegExpMacroAssemblerMIPS::CheckCharacterLT(uc16 limit, Label* on_less) { UNIMPLEMENTED_MIPS(); } void RegExpMacroAssemblerMIPS::CheckCharacters(Vector str, int cp_offset, Label* on_failure, bool check_end_of_string) { UNIMPLEMENTED_MIPS(); } void RegExpMacroAssemblerMIPS::CheckGreedyLoop(Label* on_equal) { UNIMPLEMENTED_MIPS(); } void RegExpMacroAssemblerMIPS::CheckNotBackReferenceIgnoreCase( int start_reg, Label* on_no_match) { UNIMPLEMENTED_MIPS(); } void RegExpMacroAssemblerMIPS::CheckNotBackReference( int start_reg, Label* on_no_match) { UNIMPLEMENTED_MIPS(); } void RegExpMacroAssemblerMIPS::CheckNotRegistersEqual(int reg1, int reg2, Label* on_not_equal) { UNIMPLEMENTED_MIPS(); } void RegExpMacroAssemblerMIPS::CheckNotCharacter(uint32_t c, Label* on_not_equal) { UNIMPLEMENTED_MIPS(); } void RegExpMacroAssemblerMIPS::CheckCharacterAfterAnd(uint32_t c, uint32_t mask, Label* on_equal) { UNIMPLEMENTED_MIPS(); } void RegExpMacroAssemblerMIPS::CheckNotCharacterAfterAnd(uint32_t c, uint32_t mask, Label* on_not_equal) { UNIMPLEMENTED_MIPS(); } void RegExpMacroAssemblerMIPS::CheckNotCharacterAfterMinusAnd( uc16 c, uc16 minus, uc16 mask, Label* on_not_equal) { UNIMPLEMENTED_MIPS(); } bool RegExpMacroAssemblerMIPS::CheckSpecialCharacterClass(uc16 type, Label* on_no_match) { UNIMPLEMENTED_MIPS(); return false; } void RegExpMacroAssemblerMIPS::Fail() { UNIMPLEMENTED_MIPS(); } Handle RegExpMacroAssemblerMIPS::GetCode(Handle source) { UNIMPLEMENTED_MIPS(); return Handle::null(); } void RegExpMacroAssemblerMIPS::GoTo(Label* to) { UNIMPLEMENTED_MIPS(); } void RegExpMacroAssemblerMIPS::IfRegisterGE(int reg, int comparand, Label* if_ge) { __ lw(a0, register_location(reg)); BranchOrBacktrack(if_ge, ge, a0, Operand(comparand)); } void RegExpMacroAssemblerMIPS::IfRegisterLT(int reg, int comparand, Label* if_lt) { UNIMPLEMENTED_MIPS(); } void RegExpMacroAssemblerMIPS::IfRegisterEqPos(int reg, Label* if_eq) { UNIMPLEMENTED_MIPS(); } RegExpMacroAssembler::IrregexpImplementation RegExpMacroAssemblerMIPS::Implementation() { return kMIPSImplementation; } void RegExpMacroAssemblerMIPS::LoadCurrentCharacter(int cp_offset, Label* on_end_of_input, bool check_bounds, int characters) { UNIMPLEMENTED_MIPS(); } void RegExpMacroAssemblerMIPS::PopCurrentPosition() { UNIMPLEMENTED_MIPS(); } void RegExpMacroAssemblerMIPS::PopRegister(int register_index) { UNIMPLEMENTED_MIPS(); } void RegExpMacroAssemblerMIPS::PushBacktrack(Label* label) { UNIMPLEMENTED_MIPS(); } void RegExpMacroAssemblerMIPS::PushCurrentPosition() { Push(current_input_offset()); } void RegExpMacroAssemblerMIPS::PushRegister(int register_index, StackCheckFlag check_stack_limit) { UNIMPLEMENTED_MIPS(); } void RegExpMacroAssemblerMIPS::ReadCurrentPositionFromRegister(int reg) { UNIMPLEMENTED_MIPS(); } void RegExpMacroAssemblerMIPS::ReadStackPointerFromRegister(int reg) { UNIMPLEMENTED_MIPS(); } void RegExpMacroAssemblerMIPS::SetCurrentPositionFromEnd(int by) { UNIMPLEMENTED_MIPS(); } void RegExpMacroAssemblerMIPS::SetRegister(int register_index, int to) { UNIMPLEMENTED_MIPS(); } void RegExpMacroAssemblerMIPS::Succeed() { UNIMPLEMENTED_MIPS(); } void RegExpMacroAssemblerMIPS::WriteCurrentPositionToRegister(int reg, int cp_offset) { UNIMPLEMENTED_MIPS(); } void RegExpMacroAssemblerMIPS::ClearRegisters(int reg_from, int reg_to) { UNIMPLEMENTED_MIPS(); } void RegExpMacroAssemblerMIPS::WriteStackPointerToRegister(int reg) { UNIMPLEMENTED_MIPS(); } // Private methods: void RegExpMacroAssemblerMIPS::CallCheckStackGuardState(Register scratch) { UNIMPLEMENTED_MIPS(); } // Helper function for reading a value out of a stack frame. template static T& frame_entry(Address re_frame, int frame_offset) { return reinterpret_cast(Memory::int32_at(re_frame + frame_offset)); } int RegExpMacroAssemblerMIPS::CheckStackGuardState(Address* return_address, Code* re_code, Address re_frame) { UNIMPLEMENTED_MIPS(); return 0; } MemOperand RegExpMacroAssemblerMIPS::register_location(int register_index) { UNIMPLEMENTED_MIPS(); return MemOperand(zero_reg, 0); } void RegExpMacroAssemblerMIPS::CheckPosition(int cp_offset, Label* on_outside_input) { UNIMPLEMENTED_MIPS(); } void RegExpMacroAssemblerMIPS::BranchOrBacktrack(Label* to, Condition condition, Register rs, const Operand& rt) { UNIMPLEMENTED_MIPS(); } void RegExpMacroAssemblerMIPS::SafeCall(Label* to, Condition cond, Register rs, const Operand& rt) { UNIMPLEMENTED_MIPS(); } void RegExpMacroAssemblerMIPS::SafeReturn() { UNIMPLEMENTED_MIPS(); } void RegExpMacroAssemblerMIPS::SafeCallTarget(Label* name) { UNIMPLEMENTED_MIPS(); } void RegExpMacroAssemblerMIPS::Push(Register source) { UNIMPLEMENTED_MIPS(); } void RegExpMacroAssemblerMIPS::Pop(Register target) { UNIMPLEMENTED_MIPS(); } void RegExpMacroAssemblerMIPS::CheckPreemption() { UNIMPLEMENTED_MIPS(); } void RegExpMacroAssemblerMIPS::CheckStackLimit() { UNIMPLEMENTED_MIPS(); } void RegExpMacroAssemblerMIPS::CallCFunctionUsingStub( ExternalReference function, int num_arguments) { UNIMPLEMENTED_MIPS(); } void RegExpMacroAssemblerMIPS::LoadCurrentCharacterUnchecked(int cp_offset, int characters) { UNIMPLEMENTED_MIPS(); } void RegExpCEntryStub::Generate(MacroAssembler* masm_) { UNIMPLEMENTED_MIPS(); } #undef __ #endif // V8_INTERPRETED_REGEXP }} // namespace v8::internal #endif // V8_TARGET_ARCH_MIPS