Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(628)

Unified Diff: regexp2000/src/regexp-macro-assembler-ia32.cc

Issue 10942: Start IA32 implemenetation of regexp2k (Closed)
Patch Set: Addressed review comments Created 12 years, 1 month ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View side-by-side diff with in-line comments
Download patch
« no previous file with comments | « regexp2000/src/regexp-macro-assembler-ia32.h ('k') | no next file » | no next file with comments »
Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
Index: regexp2000/src/regexp-macro-assembler-ia32.cc
diff --git a/regexp2000/src/regexp-macro-assembler-ia32.cc b/regexp2000/src/regexp-macro-assembler-ia32.cc
new file mode 100644
index 0000000000000000000000000000000000000000..126bf48d56b1504cc7a2c30caca2a6eecac87438
--- /dev/null
+++ b/regexp2000/src/regexp-macro-assembler-ia32.cc
@@ -0,0 +1,437 @@
+// Copyright 2008 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"
+#include "regexp-macro-assembler-ia32.h"
+
+namespace v8 { namespace internal {
+
+/*
+ * This assembler uses the following register assignment convention
+ * - edx : current character, or kEndOfInput if current position is not
+ * inside string. The kEndOfInput value is greater than 0xffff,
+ * so any tests that don't check whether the current position
+ * is inside the correct range should retain bits above the
+ * 15th in their computations, and fail if the value is too
+ * great.
+ * - edi : current position in input.
+ * - esi : end of input (points to byte after last character in input).
+ * - ebp : points to the location above the registers on the stack,
+ * as if by the "enter <register_count>" opcode.
+ * - esp : points to tip of backtracking stack.
+ *
+ * The registers eax, ebx and eax are free to use for computations.
+ *
+ * Each call to a public method should retain this convention.
+ * The stack is expected to have the following structure (tentative):
+ *
+ * - pointer to array where captures can be stored
+ * - end of input
+ * - start of input
+ * - return address
+ * ebp-> - old ebp
+ * - register 0 ebp[-4]
+ * - register 1 ebp[-8]
+ * - ...
+ *
+ * The data before ebp must be placed there by the calling code.
+ */
+
+RegExpMacroAssemblerIA32::RegExpMacroAssemblerIA32()
+ : masm_(new MacroAssembler(NULL, kRegExpCodeSize)),
+ constants_(kRegExpConstantsSize),
+ num_registers_(0),
+ ignore_case(false) {}
+
+
+RegExpMacroAssemblerIA32::~RegExpMacroAssemblerIA32() {
+ delete masm_;
+}
+
+
+#define __ masm_->
+
+void RegExpMacroAssemblerIA32::AdvanceCurrentPosition(int by) {
+ __ add(edi, by * sizeof(SubjectChar));
+ __ cmp(edi, esi);
+ Label inside_string;
+ Backtrack();
+
+ __ bind(&inside_string);
+ ReadChar(edx, 0);
+}
+
+
+void RegExpMacroAssemblerIA32::AdvanceRegister(int reg, int by) {
+ ASSERT(reg >= 0);
+ ASSERT(reg < num_registers);
+ __ add(register_location(reg), by);
+}
+
+
+void RegExpMacroAssemblerIA32::Backtrack() {
+ __ ret();
+}
+
+
+void RegExpMacroAssemblerIA32::Bind(Label* label) {
+ __ bind(label);
+}
+
+
+void RegExpMacroAssemblerIA32::CheckBitmap(uc16 start,
+ Label* bitmap,
+ Label* on_zero) {
+ ReadCurrentChar(eax);
+ __ sub(eax, start);
+ __ cmp(eax, 64); // FIXME: 64 = length_of_bitmap_in_bits.
+ BranchOrBacktrack(greater_equal, on_zero);
+ __ mov(ebx, eax);
+ __ shr(ebx, 3);
+ // TODO: Where is the bitmap stored? Pass the bitmap as argument instead.
+ // __ mov(ecx, position_of_bitmap);
+ __ movzx_b(ebx, Operand(ecx, ebx, times_1, 0));
+ __ and_(eax, (1<<3)-1);
+ __ bt(ebx, eax);
+ __ j(greater_equal, on_zero); // Aka. jump on carry set.
+}
+
+
+void RegExpMacroAssemblerIA32::CheckCharacterClass(RegExpCharacterClass *cclass,
+ Label* on_failure) {
+ UNREACHABLE(); // Not implemented.
+}
+
+
+void RegExpMacroAssemblerIA32::CheckCharacters(Vector<uc16> str,
+ Label* on_failure) {
+ if (sizeof(SubjectChar) == 1) {
+ for (int i = 0; i < str.length(); i++) {
+ if (str[i] > String::kMaxAsciiCharCode) {
+ __ jmp(on_failure);
+ return;
+ }
+ }
+ }
+ int byte_length = str.length() * sizeof(SubjectChar);
+ __ mov(ebx, edi);
+ __ add(ebx, byte_length);
+ __ cmp(ebx, esi);
+ BranchOrBacktrack(greater_equal, on_failure);
+
+ if (str.length() <= kMaxInlineStringTests || ignore_case()) {
+ // TODO: make proper loop if str.length is large but ignore_case is true;
+ for(int i = 0; i < str.length(); i++) {
+ ReadChar(eax, i);
+ if (ignore_case()) {
+ Canonicalize(eax);
+ }
+ __ cmp(eax, str[i]);
+ BranchOrBacktrack(not_equal, on_failure);
+ }
+ add(edi, byte_length);
+ } else {
+ int offset;
+ ArraySlice<SubjectChar> constant_buffer =
+ constants_.GetBuffer<SubjectChar>(str.length());
+ for (int i = 0; i < str.length(); i++) {
+ constant_buffer[i] = str[i];
+ }
+ __ mov(ebx, esi);
+ LoadConstantBufferAddress(esi, constant_buffer);
+ __ mov(ecx, str.length());
+ if (sizeof(SubjectChar) == 1) {
+ __ rep_cmpsb();
+ } else {
+ ASSERT(sizeof(SubjectChar)==2);
+ __ rep_cmpsw();
+ }
+ __ mov(esi, ebx);
+ BranchOrBacktrack(not_equal, on_failure);
+ }
+};
+
+
+void RegExpMacroAssemblerIA32::CheckCurrentPosition(int register_index,
+ Label* on_equal) {
+ __ cmp(register_location(register_index), edi);
+ BranchOrBacktrack(equal, on_equal);
+}
+
+
+void RegExpMacroAssemblerIA32::DispatchHalfNibbleMap(
+ uc16 start,
+ Label* half_nibble_map,
+ const Vector<Label*>& destinations) {
+
+ if (sizeof(SubjectChar) == 1 && start > String::kMaxAsciiCharCode) {
+ return;
+ }
+
+ Label fallthrough;
+
+ ReadCurrentChar(eax);
+ __ sub(eax, start);
+ __ cmp(eax, 64); // FIXME: 64 = size of map in bytes. Found somehow??
+ __ j(greater_equal, &fallthrough);
+
+ __ mov(ebx, eax);
+ __ shr(eax, 2);
+ __ movzx_b(eax, Operand(ecx, eax)); // FIXME: ecx holds address of map
+ Label got_nybble;
+ Label high_bits;
+ __ and_(ebx, 0x03);
+ __ shr(eax, ebx);
+
+ Label second_bit_set, case_3, case_1;
+ __ test(eax, 2);
+ __ j(not_equal, &second_bit_set);
+ __ test(eax, 1);
+ __ j(not_equal, &case_1);
+ // Case 0:
+ __ jmp(&destinations[0]);
+ __ bind(&case_1);
+ // Case 1:
+ __ jmp(&destinations[1]);
+ __ bind(&second_bit_set);
+ __ test(eax, 1);
+ __ j(not_equal, &case_3);
+ // Case 2
+ __ jmp(&destinations[2]);
+ __ bind(&case_3);
+ // Case 3:
+ __ jmp(&destinations[3]);
+
+ __ bind(&fallthrough);
+}
+
+
+void RegExpMacroAssemblerIA32::DispatchByteMap(
+ uc16 start,
+ Label* byte_map,
+ const Vector<Label*>& destinations) {
+
+ if (sizeof(SubjectChar) == 1 && start > String::kMaxAsciiCharCode) {
+ return;
+ }
+
+ Label fallthrough;
+
+ ReadCurrentChar(eax);
+ __ sub(eax, start);
+ __ cmp(eax, 64); // FIXME: 64 = size of map. Found somehow??
+ __ j(greater_equal, &fallthrough);
+
+ __ movzx_b(eax, Operand(ecx, eax)); // FIXME: ecx must hold address of map
+ // jump table: jump to destinations[eax];
+
+ __ bind(&fallthrough);
+}
+
+void RegExpMacroAssemblerIA32::DispatchHighByteMap(
+ byte start,
+ Label* byte_map,
+ const Vector<Label*>& destinations) {
+ Label fallthrough;
+ ReadCurrentChar(eax);
+ __ shr(eax, 8);
+ __ sub(eax, start);
+ __ cmp(eax, destinations.length() - start);
+ __ j(greater_equal, &fallthrough);
+
+ // TODO jumptable: jump to destinations[eax]
+ __ bind(&fallthrough);
+}
+
+
+void RegExpMacroAssemblerIA32::EmitOrLink(Label* label) {
+ UNREACHABLE(); // Has no use.
+}
+
+
+void RegExpMacroAssemblerIA32::Fail() {
+ Exit(false);
+}
+
+Handle<Object> RegExpMacroAssemblerIA32::GetCode() {
+ // something
+ return Handle();
+}
+
+
+void RegExpMacroAssemblerIA32::GoTo(Label &to) {
+ __ jmp(to);
+}
+
+
+void RegExpMacroAssemblerIA32::IfRegisterGE(int reg,
+ int comparand,
+ Label* if_ge) {
+ __ cmp(register_location(reg), comparand);
+ BranchOrBacktrack(greater_equal, if_ge);
+}
+
+
+void RegExpMacroAssemblerIA32::IfRegisterLT(int reg,
+ int comparand,
+ Label* if_lt) {
+ __ cmp(register_location(reg), comparand);
+ BranchOrBacktrack(less, if_lt);
+}
+
+
+Re2kImplementation RegExpMacroAssemblerIA32::Implementation() {
+ return kIA32Implementation;
+}
+
+
+void RegExpMacroAssemblerIA32::PopCurrentPosition() {
+ __ pop(edi);
+ ReadChar(edx, 0);
+}
+
+
+void RegExpMacroAssemblerIA32::PopRegister(int register_index) {
+ __ pop(register_location(register_index));
+}
+
+
+void RegExpMacroAssemblerIA32::PushBacktrack(Label* label) {
+ Label cont;
+ __ call(&cont);
+ __ jmp(label);
+ __ bind(&cont);
+}
+
+
+void RegExpMacroAssemblerIA32::PushCurrentPosition() {
+ __ push(edi);
+}
+
+
+void RegExpMacroAssemblerIA32::PushRegister(int register_index) {
+ __ push(register_location(register_index));
+}
+
+
+void RegExpMacroAssemblerIA32::SetRegister(int register_index, int to) {
+ __ mov(register_location(register_index), to);
+}
+
+
+void RegExpMacroAssemblerIA32::Succeed() {
+ Exit(true);
+}
+
+void RegExpMacroAssemblerIA32::WriteCurrentPositionToRegister() {
+ __ mov(register_location(register_index), edi);
+}
+
+// Custom :
+
+void RegExpMacroAssemblerIA32::Initialize(int num_registers, bool ignore_case) {
+ num_registers_ = num_registers;
+ ignore_case_ = ignore_case;
+ __ enter(num_registers * sizeof(uint32_t));
+}
+
+
+Operand RegExpMacroAssemblerIA32::register_location(int register_index) {
+ ASSERT(register_index < (1<<30));
+ return Operand(ebp, -((register_index + 1) * sizeof(uint32_t)));
+}
+
+
+void RegExpMacroAssemblerIA32::BranchOrBacktrack(Condition condition,
+ Label* to) {
+ if (condition < 0) { // No condition
+ if (to == NULL) {
+ Backtrack();
+ return;
+ }
+ __ jmp(to);
+ return;
+ } else if (to == NULL) {
+ Label skip;
+ __ j(NegateCondition(condition), &skip);
+ Backtrack();
+ __ bind(&skip);
+ return;
+ }
+ __ j(condition, to);
+}
+
+
+void RegExpMacroAssemblerIA32::Canonicalize(Register reg) {
+ if (sizeof(SubjectChar) == 1) {
+ Label end;
+ __ cmp(reg, 'a');
+ __ j(below, &end);
+ __ cmp(reg, 'z');
+ __ j(above, &end);
+ __ sub(reg, 'a' - 'A');
+ __ bind(&end);
+ return;
+ }
+ ASSERT(sizeof(SubjectChar) == 2);
+ // TODO: Use some tables.
+}
+
+
+void RegExpMacroAssemblerIA32::Exit(bool success) {
+ if (success) {
+ // Copy captures to output capture array.
+ }
+ __ leave();
+ __ mov(eax, success ? 1 : 0);
+ __ ret();
+}
+
+
+void RegExpMacroAssemblerIA32::ReadChar(Register destination, int offset) {
+ if (sizeof(SubjectChar) == 1) {
+ __ movzx_b(destination, Operand(edi, offset));
+ return;
+ }
+ ASSERT(sizeof(SubjectChar) == 2);
+ __ movzx_w(destination, Operand(edi, offset * 2));
+}
+
+
+void RegExpMacroAssemblerIA32::ReadCurrentChar(Register destination) {
+ mov(destination, edx);
+}
+
+
+template <typename T>
+void LoadConstantBufferAddress(Register reg, ArraySlice<T>& buffer) {
+ __ mov(reg, buffer.array());
+ __ add(reg, buffer.base_offset());
+}
+
+#undef __
+}}
« no previous file with comments | « regexp2000/src/regexp-macro-assembler-ia32.h ('k') | no next file » | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698