// 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<const uc16> 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<HeapObject> RegExpMacroAssemblerMIPS::GetCode(Handle<String> source) {
UNIMPLEMENTED_MIPS();
return Handle<HeapObject>::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 <typename T>
static T& frame_entry(Address re_frame, int frame_offset) {
return reinterpret_cast<T&>(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