diff options
Diffstat (limited to 'chromium/v8/src/x64/regexp-macro-assembler-x64.cc')
-rw-r--r-- | chromium/v8/src/x64/regexp-macro-assembler-x64.cc | 402 |
1 files changed, 199 insertions, 203 deletions
diff --git a/chromium/v8/src/x64/regexp-macro-assembler-x64.cc b/chromium/v8/src/x64/regexp-macro-assembler-x64.cc index 3e65a68b831..a8c1cb47a7f 100644 --- a/chromium/v8/src/x64/regexp-macro-assembler-x64.cc +++ b/chromium/v8/src/x64/regexp-macro-assembler-x64.cc @@ -1,42 +1,19 @@ // Copyright 2012 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" +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +#include "src/v8.h" #if V8_TARGET_ARCH_X64 -#include "cpu-profiler.h" -#include "serialize.h" -#include "unicode.h" -#include "log.h" -#include "regexp-stack.h" -#include "macro-assembler.h" -#include "regexp-macro-assembler.h" -#include "x64/regexp-macro-assembler-x64.h" +#include "src/cpu-profiler.h" +#include "src/serialize.h" +#include "src/unicode.h" +#include "src/log.h" +#include "src/regexp-stack.h" +#include "src/macro-assembler.h" +#include "src/regexp-macro-assembler.h" +#include "src/x64/regexp-macro-assembler-x64.h" namespace v8 { namespace internal { @@ -166,7 +143,7 @@ void RegExpMacroAssemblerX64::AdvanceRegister(int reg, int by) { ASSERT(reg >= 0); ASSERT(reg < num_registers_); if (by != 0) { - __ addq(register_location(reg), Immediate(by)); + __ addp(register_location(reg), Immediate(by)); } } @@ -175,7 +152,7 @@ void RegExpMacroAssemblerX64::Backtrack() { CheckPreemption(); // Pop Code* offset from backtrack stack, add Code* and jump to location. Pop(rbx); - __ addq(rbx, code_object_pointer()); + __ addp(rbx, code_object_pointer()); __ jmp(rbx); } @@ -203,8 +180,8 @@ void RegExpMacroAssemblerX64::CheckAtStart(Label* on_at_start) { __ cmpl(Operand(rbp, kStartIndex), Immediate(0)); BranchOrBacktrack(not_equal, ¬_at_start); // If we did, are we still at the start of the input? - __ lea(rax, Operand(rsi, rdi, times_1, 0)); - __ cmpq(rax, Operand(rbp, kInputStart)); + __ leap(rax, Operand(rsi, rdi, times_1, 0)); + __ cmpp(rax, Operand(rbp, kInputStart)); BranchOrBacktrack(equal, on_at_start); __ bind(¬_at_start); } @@ -215,8 +192,8 @@ void RegExpMacroAssemblerX64::CheckNotAtStart(Label* on_not_at_start) { __ cmpl(Operand(rbp, kStartIndex), Immediate(0)); BranchOrBacktrack(not_equal, on_not_at_start); // If we did, are we still at the start of the input? - __ lea(rax, Operand(rsi, rdi, times_1, 0)); - __ cmpq(rax, Operand(rbp, kInputStart)); + __ leap(rax, Operand(rsi, rdi, times_1, 0)); + __ cmpp(rax, Operand(rbp, kInputStart)); BranchOrBacktrack(not_equal, on_not_at_start); } @@ -241,9 +218,9 @@ void RegExpMacroAssemblerX64::CheckNotBackReferenceIgnoreCase( int start_reg, Label* on_no_match) { Label fallthrough; - __ movq(rdx, register_location(start_reg)); // Offset of start of capture - __ movq(rbx, register_location(start_reg + 1)); // Offset of end of capture - __ subq(rbx, rdx); // Length of capture. + ReadPositionFromRegister(rdx, start_reg); // Offset of start of capture + ReadPositionFromRegister(rbx, start_reg + 1); // Offset of end of capture + __ subp(rbx, rdx); // Length of capture. // ----------------------- // rdx = Start offset of capture. @@ -273,9 +250,9 @@ void RegExpMacroAssemblerX64::CheckNotBackReferenceIgnoreCase( on_no_match = &backtrack_label_; } - __ lea(r9, Operand(rsi, rdx, times_1, 0)); - __ lea(r11, Operand(rsi, rdi, times_1, 0)); - __ addq(rbx, r9); // End of capture + __ leap(r9, Operand(rsi, rdx, times_1, 0)); + __ leap(r11, Operand(rsi, rdi, times_1, 0)); + __ addp(rbx, r9); // End of capture // --------------------- // r11 - current input character address // r9 - current capture character address @@ -293,8 +270,8 @@ void RegExpMacroAssemblerX64::CheckNotBackReferenceIgnoreCase( // Mismatch, try case-insensitive match (converting letters to lower-case). // I.e., if or-ing with 0x20 makes values equal and in range 'a'-'z', it's // a match. - __ or_(rax, Immediate(0x20)); // Convert match character to lower-case. - __ or_(rdx, Immediate(0x20)); // Convert capture character to lower-case. + __ orp(rax, Immediate(0x20)); // Convert match character to lower-case. + __ orp(rdx, Immediate(0x20)); // Convert capture character to lower-case. __ cmpb(rax, rdx); __ j(not_equal, on_no_match); // Definitely not equal. __ subb(rax, Immediate('a')); @@ -308,24 +285,24 @@ void RegExpMacroAssemblerX64::CheckNotBackReferenceIgnoreCase( __ j(equal, on_no_match); __ bind(&loop_increment); // Increment pointers into match and capture strings. - __ addq(r11, Immediate(1)); - __ addq(r9, Immediate(1)); + __ addp(r11, Immediate(1)); + __ addp(r9, Immediate(1)); // Compare to end of capture, and loop if not done. - __ cmpq(r9, rbx); + __ cmpp(r9, rbx); __ j(below, &loop); // Compute new value of character position after the matched part. - __ movq(rdi, r11); + __ movp(rdi, r11); __ subq(rdi, rsi); } else { ASSERT(mode_ == UC16); // Save important/volatile registers before calling C function. #ifndef _WIN64 // Caller save on Linux and callee save in Windows. - __ push(rsi); - __ push(rdi); + __ pushq(rsi); + __ pushq(rdi); #endif - __ push(backtrack_stackpointer()); + __ pushq(backtrack_stackpointer()); static const int num_arguments = 4; __ PrepareCallCFunction(num_arguments); @@ -337,22 +314,22 @@ void RegExpMacroAssemblerX64::CheckNotBackReferenceIgnoreCase( // Isolate* isolate #ifdef _WIN64 // Compute and set byte_offset1 (start of capture). - __ lea(rcx, Operand(rsi, rdx, times_1, 0)); + __ leap(rcx, Operand(rsi, rdx, times_1, 0)); // Set byte_offset2. - __ lea(rdx, Operand(rsi, rdi, times_1, 0)); + __ leap(rdx, Operand(rsi, rdi, times_1, 0)); // Set byte_length. - __ movq(r8, rbx); + __ movp(r8, rbx); // Isolate. __ LoadAddress(r9, ExternalReference::isolate_address(isolate())); #else // AMD64 calling convention // Compute byte_offset2 (current position = rsi+rdi). - __ lea(rax, Operand(rsi, rdi, times_1, 0)); + __ leap(rax, Operand(rsi, rdi, times_1, 0)); // Compute and set byte_offset1 (start of capture). - __ lea(rdi, Operand(rsi, rdx, times_1, 0)); + __ leap(rdi, Operand(rsi, rdx, times_1, 0)); // Set byte_offset2. - __ movq(rsi, rax); + __ movp(rsi, rax); // Set byte_length. - __ movq(rdx, rbx); + __ movp(rdx, rbx); // Isolate. __ LoadAddress(rcx, ExternalReference::isolate_address(isolate())); #endif @@ -367,14 +344,14 @@ void RegExpMacroAssemblerX64::CheckNotBackReferenceIgnoreCase( // Restore original values before reacting on result value. __ Move(code_object_pointer(), masm_.CodeObject()); - __ pop(backtrack_stackpointer()); + __ popq(backtrack_stackpointer()); #ifndef _WIN64 - __ pop(rdi); - __ pop(rsi); + __ popq(rdi); + __ popq(rsi); #endif // Check if function returned non-zero for success or zero for failure. - __ testq(rax, rax); + __ testp(rax, rax); BranchOrBacktrack(zero, on_no_match); // On success, increment position by length of capture. // Requires that rbx is callee save (true for both Win64 and AMD64 ABIs). @@ -390,9 +367,9 @@ void RegExpMacroAssemblerX64::CheckNotBackReference( Label fallthrough; // Find length of back-referenced capture. - __ movq(rdx, register_location(start_reg)); - __ movq(rax, register_location(start_reg + 1)); - __ subq(rax, rdx); // Length to check. + ReadPositionFromRegister(rdx, start_reg); // Offset of start of capture + ReadPositionFromRegister(rax, start_reg + 1); // Offset of end of capture + __ subp(rax, rdx); // Length to check. // Fail on partial or illegal capture (start of capture after end of capture). // This must not happen (no back-reference can reference a capture that wasn't @@ -412,9 +389,9 @@ void RegExpMacroAssemblerX64::CheckNotBackReference( BranchOrBacktrack(greater, on_no_match); // Compute pointers to match string and capture string - __ lea(rbx, Operand(rsi, rdi, times_1, 0)); // Start of match. - __ addq(rdx, rsi); // Start of capture. - __ lea(r9, Operand(rdx, rax, times_1, 0)); // End of capture + __ leap(rbx, Operand(rsi, rdi, times_1, 0)); // Start of match. + __ addp(rdx, rsi); // Start of capture. + __ leap(r9, Operand(rdx, rax, times_1, 0)); // End of capture // ----------------------- // rbx - current capture character address. @@ -433,15 +410,15 @@ void RegExpMacroAssemblerX64::CheckNotBackReference( } BranchOrBacktrack(not_equal, on_no_match); // Increment pointers into capture and match string. - __ addq(rbx, Immediate(char_size())); - __ addq(rdx, Immediate(char_size())); + __ addp(rbx, Immediate(char_size())); + __ addp(rdx, Immediate(char_size())); // Check if we have reached end of match area. - __ cmpq(rdx, r9); + __ cmpp(rdx, r9); __ j(below, &loop); // Success. // Set current character position to position after match. - __ movq(rdi, rbx); + __ movp(rdi, rbx); __ subq(rdi, rsi); __ bind(&fallthrough); @@ -462,7 +439,7 @@ void RegExpMacroAssemblerX64::CheckCharacterAfterAnd(uint32_t c, __ testl(current_character(), Immediate(mask)); } else { __ movl(rax, Immediate(mask)); - __ and_(rax, current_character()); + __ andp(rax, current_character()); __ cmpl(rax, Immediate(c)); } BranchOrBacktrack(equal, on_equal); @@ -476,7 +453,7 @@ void RegExpMacroAssemblerX64::CheckNotCharacterAfterAnd(uint32_t c, __ testl(current_character(), Immediate(mask)); } else { __ movl(rax, Immediate(mask)); - __ and_(rax, current_character()); + __ andp(rax, current_character()); __ cmpl(rax, Immediate(c)); } BranchOrBacktrack(not_equal, on_not_equal); @@ -489,8 +466,8 @@ void RegExpMacroAssemblerX64::CheckNotCharacterAfterMinusAnd( uc16 mask, Label* on_not_equal) { ASSERT(minus < String::kMaxUtf16CodeUnit); - __ lea(rax, Operand(current_character(), -minus)); - __ and_(rax, Immediate(mask)); + __ leap(rax, Operand(current_character(), -minus)); + __ andp(rax, Immediate(mask)); __ cmpl(rax, Immediate(c)); BranchOrBacktrack(not_equal, on_not_equal); } @@ -522,8 +499,8 @@ void RegExpMacroAssemblerX64::CheckBitInTable( __ Move(rax, table); Register index = current_character(); if (mode_ != ASCII || kTableMask != String::kMaxOneByteCharCode) { - __ movq(rbx, current_character()); - __ and_(rbx, Immediate(kTableMask)); + __ movp(rbx, current_character()); + __ andp(rbx, Immediate(kTableMask)); index = rbx; } __ cmpb(FieldOperand(rax, index, times_1, ByteArray::kHeaderSize), @@ -536,7 +513,7 @@ bool RegExpMacroAssemblerX64::CheckSpecialCharacterClass(uc16 type, Label* on_no_match) { // Range checks (c in min..max) are generally implemented by an unsigned // (c - min) <= (max - min) check, using the sequence: - // lea(rax, Operand(current_character(), -min)) or sub(rax, Immediate(min)) + // leap(rax, Operand(current_character(), -min)) or sub(rax, Immediate(min)) // cmp(rax, Immediate(max - min)) switch (type) { case 's': @@ -547,7 +524,7 @@ bool RegExpMacroAssemblerX64::CheckSpecialCharacterClass(uc16 type, __ cmpl(current_character(), Immediate(' ')); __ j(equal, &success, Label::kNear); // Check range 0x09..0x0d - __ lea(rax, Operand(current_character(), -'\t')); + __ leap(rax, Operand(current_character(), -'\t')); __ cmpl(rax, Immediate('\r' - '\t')); __ j(below_equal, &success, Label::kNear); // \u00a0 (NBSP). @@ -562,20 +539,20 @@ bool RegExpMacroAssemblerX64::CheckSpecialCharacterClass(uc16 type, return false; case 'd': // Match ASCII digits ('0'..'9') - __ lea(rax, Operand(current_character(), -'0')); + __ leap(rax, Operand(current_character(), -'0')); __ cmpl(rax, Immediate('9' - '0')); BranchOrBacktrack(above, on_no_match); return true; case 'D': // Match non ASCII-digits - __ lea(rax, Operand(current_character(), -'0')); + __ leap(rax, Operand(current_character(), -'0')); __ cmpl(rax, Immediate('9' - '0')); BranchOrBacktrack(below_equal, on_no_match); return true; case '.': { // Match non-newlines (not 0x0a('\n'), 0x0d('\r'), 0x2028 and 0x2029) __ movl(rax, current_character()); - __ xor_(rax, Immediate(0x01)); + __ xorp(rax, Immediate(0x01)); // See if current character is '\n'^1 or '\r'^1, i.e., 0x0b or 0x0c __ subl(rax, Immediate(0x0b)); __ cmpl(rax, Immediate(0x0c - 0x0b)); @@ -593,7 +570,7 @@ bool RegExpMacroAssemblerX64::CheckSpecialCharacterClass(uc16 type, case 'n': { // Match newlines (0x0a('\n'), 0x0d('\r'), 0x2028 and 0x2029) __ movl(rax, current_character()); - __ xor_(rax, Immediate(0x01)); + __ xorp(rax, Immediate(0x01)); // See if current character is '\n'^1 or '\r'^1, i.e., 0x0b or 0x0c __ subl(rax, Immediate(0x0b)); __ cmpl(rax, Immediate(0x0c - 0x0b)); @@ -674,8 +651,8 @@ Handle<HeapObject> RegExpMacroAssemblerX64::GetCode(Handle<String> source) { FrameScope scope(&masm_, StackFrame::MANUAL); // Actually emit code to start a new stack frame. - __ push(rbp); - __ movq(rbp, rsp); + __ pushq(rbp); + __ movp(rbp, rsp); // Save parameters and callee-save registers. Order here should correspond // to order of kBackup_ebx etc. #ifdef _WIN64 @@ -686,30 +663,30 @@ Handle<HeapObject> RegExpMacroAssemblerX64::GetCode(Handle<String> source) { __ movq(Operand(rbp, kInputStart), r8); __ movq(Operand(rbp, kInputEnd), r9); // Callee-save on Win64. - __ push(rsi); - __ push(rdi); - __ push(rbx); + __ pushq(rsi); + __ pushq(rdi); + __ pushq(rbx); #else // GCC passes arguments in rdi, rsi, rdx, rcx, r8, r9 (and then on stack). // Push register parameters on stack for reference. - ASSERT_EQ(kInputString, -1 * kPointerSize); - ASSERT_EQ(kStartIndex, -2 * kPointerSize); - ASSERT_EQ(kInputStart, -3 * kPointerSize); - ASSERT_EQ(kInputEnd, -4 * kPointerSize); - ASSERT_EQ(kRegisterOutput, -5 * kPointerSize); - ASSERT_EQ(kNumOutputRegisters, -6 * kPointerSize); - __ push(rdi); - __ push(rsi); - __ push(rdx); - __ push(rcx); - __ push(r8); - __ push(r9); - - __ push(rbx); // Callee-save + ASSERT_EQ(kInputString, -1 * kRegisterSize); + ASSERT_EQ(kStartIndex, -2 * kRegisterSize); + ASSERT_EQ(kInputStart, -3 * kRegisterSize); + ASSERT_EQ(kInputEnd, -4 * kRegisterSize); + ASSERT_EQ(kRegisterOutput, -5 * kRegisterSize); + ASSERT_EQ(kNumOutputRegisters, -6 * kRegisterSize); + __ pushq(rdi); + __ pushq(rsi); + __ pushq(rdx); + __ pushq(rcx); + __ pushq(r8); + __ pushq(r9); + + __ pushq(rbx); // Callee-save #endif - __ push(Immediate(0)); // Number of successful matches in a global regexp. - __ push(Immediate(0)); // Make room for "input start - 1" constant. + __ Push(Immediate(0)); // Number of successful matches in a global regexp. + __ Push(Immediate(0)); // Make room for "input start - 1" constant. // Check if we have space on the stack for registers. Label stack_limit_hit; @@ -717,14 +694,14 @@ Handle<HeapObject> RegExpMacroAssemblerX64::GetCode(Handle<String> source) { ExternalReference stack_limit = ExternalReference::address_of_stack_limit(isolate()); - __ movq(rcx, rsp); + __ movp(rcx, rsp); __ Move(kScratchRegister, stack_limit); - __ subq(rcx, Operand(kScratchRegister, 0)); + __ subp(rcx, Operand(kScratchRegister, 0)); // Handle it if the stack pointer is already below the stack limit. __ j(below_equal, &stack_limit_hit); // Check if there is room for the variable number of registers above // the stack limit. - __ cmpq(rcx, Immediate(num_registers_ * kPointerSize)); + __ cmpp(rcx, Immediate(num_registers_ * kPointerSize)); __ j(above_equal, &stack_ok); // Exit with OutOfMemory exception. There is not enough space on the stack // for our working registers. @@ -734,32 +711,32 @@ Handle<HeapObject> RegExpMacroAssemblerX64::GetCode(Handle<String> source) { __ bind(&stack_limit_hit); __ Move(code_object_pointer(), masm_.CodeObject()); CallCheckStackGuardState(); // Preserves no registers beside rbp and rsp. - __ testq(rax, rax); + __ testp(rax, rax); // If returned value is non-zero, we exit with the returned value as result. __ j(not_zero, &return_rax); __ bind(&stack_ok); // Allocate space on stack for registers. - __ subq(rsp, Immediate(num_registers_ * kPointerSize)); + __ subp(rsp, Immediate(num_registers_ * kPointerSize)); // Load string length. - __ movq(rsi, Operand(rbp, kInputEnd)); + __ movp(rsi, Operand(rbp, kInputEnd)); // Load input position. - __ movq(rdi, Operand(rbp, kInputStart)); + __ movp(rdi, Operand(rbp, kInputStart)); // Set up rdi to be negative offset from string end. __ subq(rdi, rsi); // Set rax to address of char before start of the string // (effectively string position -1). - __ movq(rbx, Operand(rbp, kStartIndex)); - __ neg(rbx); + __ movp(rbx, Operand(rbp, kStartIndex)); + __ negq(rbx); if (mode_ == UC16) { - __ lea(rax, Operand(rdi, rbx, times_2, -char_size())); + __ leap(rax, Operand(rdi, rbx, times_2, -char_size())); } else { - __ lea(rax, Operand(rdi, rbx, times_1, -char_size())); + __ leap(rax, Operand(rdi, rbx, times_1, -char_size())); } // Store this value in a local variable, for use when clearing // position registers. - __ movq(Operand(rbp, kInputStartMinusOne), rax); + __ movp(Operand(rbp, kInputStartMinusOne), rax); #if V8_OS_WIN // Ensure that we have written to each stack page, in order. Skipping a page @@ -769,7 +746,7 @@ Handle<HeapObject> RegExpMacroAssemblerX64::GetCode(Handle<String> source) { for (int i = num_saved_registers_ + kRegistersPerPage - 1; i < num_registers_; i += kRegistersPerPage) { - __ movq(register_location(i), rax); // One write every page. + __ movp(register_location(i), rax); // One write every page. } #endif // V8_OS_WIN @@ -798,20 +775,20 @@ Handle<HeapObject> RegExpMacroAssemblerX64::GetCode(Handle<String> source) { __ Set(rcx, kRegisterZero); Label init_loop; __ bind(&init_loop); - __ movq(Operand(rbp, rcx, times_1, 0), rax); + __ movp(Operand(rbp, rcx, times_1, 0), rax); __ subq(rcx, Immediate(kPointerSize)); __ cmpq(rcx, Immediate(kRegisterZero - num_saved_registers_ * kPointerSize)); __ j(greater, &init_loop); } else { // Unroll the loop. for (int i = 0; i < num_saved_registers_; i++) { - __ movq(register_location(i), rax); + __ movp(register_location(i), rax); } } } // Initialize backtrack stack pointer. - __ movq(backtrack_stackpointer(), Operand(rbp, kStackHighEnd)); + __ movp(backtrack_stackpointer(), Operand(rbp, kStackHighEnd)); __ jmp(&start_label_); @@ -821,24 +798,24 @@ Handle<HeapObject> RegExpMacroAssemblerX64::GetCode(Handle<String> source) { __ bind(&success_label_); if (num_saved_registers_ > 0) { // copy captures to output - __ movq(rdx, Operand(rbp, kStartIndex)); - __ movq(rbx, Operand(rbp, kRegisterOutput)); - __ movq(rcx, Operand(rbp, kInputEnd)); - __ subq(rcx, Operand(rbp, kInputStart)); + __ movp(rdx, Operand(rbp, kStartIndex)); + __ movp(rbx, Operand(rbp, kRegisterOutput)); + __ movp(rcx, Operand(rbp, kInputEnd)); + __ subp(rcx, Operand(rbp, kInputStart)); if (mode_ == UC16) { - __ lea(rcx, Operand(rcx, rdx, times_2, 0)); + __ leap(rcx, Operand(rcx, rdx, times_2, 0)); } else { - __ addq(rcx, rdx); + __ addp(rcx, rdx); } for (int i = 0; i < num_saved_registers_; i++) { - __ movq(rax, register_location(i)); + __ movp(rax, register_location(i)); if (i == 0 && global_with_zero_length_check()) { // Keep capture start in rdx for the zero-length check later. - __ movq(rdx, rax); + __ movp(rdx, rax); } - __ addq(rax, rcx); // Convert to index from start, not end. + __ addp(rax, rcx); // Convert to index from start, not end. if (mode_ == UC16) { - __ sar(rax, Immediate(1)); // Convert byte index to character index. + __ sarp(rax, Immediate(1)); // Convert byte index to character index. } __ movl(Operand(rbx, i * kIntSize), rax); } @@ -847,31 +824,31 @@ Handle<HeapObject> RegExpMacroAssemblerX64::GetCode(Handle<String> source) { if (global()) { // Restart matching if the regular expression is flagged as global. // Increment success counter. - __ incq(Operand(rbp, kSuccessfulCaptures)); + __ incp(Operand(rbp, kSuccessfulCaptures)); // Capture results have been stored, so the number of remaining global // output registers is reduced by the number of stored captures. __ movsxlq(rcx, Operand(rbp, kNumOutputRegisters)); - __ subq(rcx, Immediate(num_saved_registers_)); + __ subp(rcx, Immediate(num_saved_registers_)); // Check whether we have enough room for another set of capture results. - __ cmpq(rcx, Immediate(num_saved_registers_)); + __ cmpp(rcx, Immediate(num_saved_registers_)); __ j(less, &exit_label_); - __ movq(Operand(rbp, kNumOutputRegisters), rcx); + __ movp(Operand(rbp, kNumOutputRegisters), rcx); // Advance the location for output. - __ addq(Operand(rbp, kRegisterOutput), + __ addp(Operand(rbp, kRegisterOutput), Immediate(num_saved_registers_ * kIntSize)); // Prepare rax to initialize registers with its value in the next run. - __ movq(rax, Operand(rbp, kInputStartMinusOne)); + __ movp(rax, Operand(rbp, kInputStartMinusOne)); if (global_with_zero_length_check()) { // Special case for zero-length matches. // rdx: capture start index - __ cmpq(rdi, rdx); + __ cmpp(rdi, rdx); // Not a zero-length match, restart. __ j(not_equal, &load_char_start_regexp); // rdi (offset from the end) is zero if we already reached the end. - __ testq(rdi, rdi); + __ testp(rdi, rdi); __ j(zero, &exit_label_, Label::kNear); // Advance current position after a zero-length match. if (mode_ == UC16) { @@ -883,32 +860,32 @@ Handle<HeapObject> RegExpMacroAssemblerX64::GetCode(Handle<String> source) { __ jmp(&load_char_start_regexp); } else { - __ movq(rax, Immediate(SUCCESS)); + __ movp(rax, Immediate(SUCCESS)); } } __ bind(&exit_label_); if (global()) { // Return the number of successful captures. - __ movq(rax, Operand(rbp, kSuccessfulCaptures)); + __ movp(rax, Operand(rbp, kSuccessfulCaptures)); } __ bind(&return_rax); #ifdef _WIN64 // Restore callee save registers. - __ lea(rsp, Operand(rbp, kLastCalleeSaveRegister)); - __ pop(rbx); - __ pop(rdi); - __ pop(rsi); + __ leap(rsp, Operand(rbp, kLastCalleeSaveRegister)); + __ popq(rbx); + __ popq(rdi); + __ popq(rsi); // Stack now at rbp. #else // Restore callee save register. - __ movq(rbx, Operand(rbp, kBackup_rbx)); + __ movp(rbx, Operand(rbp, kBackup_rbx)); // Skip rsp to rbp. - __ movq(rsp, rbp); + __ movp(rsp, rbp); #endif // Exit function frame, restore previous one. - __ pop(rbp); + __ popq(rbp); __ ret(0); // Backtrack code (branch target for conditional backtracks). @@ -923,21 +900,21 @@ Handle<HeapObject> RegExpMacroAssemblerX64::GetCode(Handle<String> source) { if (check_preempt_label_.is_linked()) { SafeCallTarget(&check_preempt_label_); - __ push(backtrack_stackpointer()); - __ push(rdi); + __ pushq(backtrack_stackpointer()); + __ pushq(rdi); CallCheckStackGuardState(); - __ testq(rax, rax); + __ testp(rax, rax); // If returning non-zero, we should end execution with the given // result as return value. __ j(not_zero, &return_rax); // Restore registers. __ Move(code_object_pointer(), masm_.CodeObject()); - __ pop(rdi); - __ pop(backtrack_stackpointer()); + __ popq(rdi); + __ popq(backtrack_stackpointer()); // String might have moved: Reload esi from frame. - __ movq(rsi, Operand(rbp, kInputEnd)); + __ movp(rsi, Operand(rbp, kInputEnd)); SafeReturn(); } @@ -950,8 +927,8 @@ Handle<HeapObject> RegExpMacroAssemblerX64::GetCode(Handle<String> source) { // Save registers before calling C function #ifndef _WIN64 // Callee-save in Microsoft 64-bit ABI, but not in AMD64 ABI. - __ push(rsi); - __ push(rdi); + __ pushq(rsi); + __ pushq(rdi); #endif // Call GrowStack(backtrack_stackpointer()) @@ -960,12 +937,12 @@ Handle<HeapObject> RegExpMacroAssemblerX64::GetCode(Handle<String> source) { #ifdef _WIN64 // Microsoft passes parameters in rcx, rdx, r8. // First argument, backtrack stackpointer, is already in rcx. - __ lea(rdx, Operand(rbp, kStackHighEnd)); // Second argument + __ leap(rdx, Operand(rbp, kStackHighEnd)); // Second argument __ LoadAddress(r8, ExternalReference::isolate_address(isolate())); #else // AMD64 ABI passes parameters in rdi, rsi, rdx. - __ movq(rdi, backtrack_stackpointer()); // First argument. - __ lea(rsi, Operand(rbp, kStackHighEnd)); // Second argument. + __ movp(rdi, backtrack_stackpointer()); // First argument. + __ leap(rsi, Operand(rbp, kStackHighEnd)); // Second argument. __ LoadAddress(rdx, ExternalReference::isolate_address(isolate())); #endif ExternalReference grow_stack = @@ -973,15 +950,15 @@ Handle<HeapObject> RegExpMacroAssemblerX64::GetCode(Handle<String> source) { __ CallCFunction(grow_stack, num_arguments); // If return NULL, we have failed to grow the stack, and // must exit with a stack-overflow exception. - __ testq(rax, rax); + __ testp(rax, rax); __ j(equal, &exit_with_exception); // Otherwise use return value as new stack pointer. - __ movq(backtrack_stackpointer(), rax); + __ movp(backtrack_stackpointer(), rax); // Restore saved registers and continue. __ Move(code_object_pointer(), masm_.CodeObject()); #ifndef _WIN64 - __ pop(rdi); - __ pop(rsi); + __ popq(rdi); + __ popq(rsi); #endif SafeReturn(); } @@ -1015,7 +992,7 @@ void RegExpMacroAssemblerX64::GoTo(Label* to) { void RegExpMacroAssemblerX64::IfRegisterGE(int reg, int comparand, Label* if_ge) { - __ cmpq(register_location(reg), Immediate(comparand)); + __ cmpp(register_location(reg), Immediate(comparand)); BranchOrBacktrack(greater_equal, if_ge); } @@ -1023,14 +1000,14 @@ void RegExpMacroAssemblerX64::IfRegisterGE(int reg, void RegExpMacroAssemblerX64::IfRegisterLT(int reg, int comparand, Label* if_lt) { - __ cmpq(register_location(reg), Immediate(comparand)); + __ cmpp(register_location(reg), Immediate(comparand)); BranchOrBacktrack(less, if_lt); } void RegExpMacroAssemblerX64::IfRegisterEqPos(int reg, Label* if_eq) { - __ cmpq(rdi, register_location(reg)); + __ cmpp(rdi, register_location(reg)); BranchOrBacktrack(equal, if_eq); } @@ -1061,7 +1038,7 @@ void RegExpMacroAssemblerX64::PopCurrentPosition() { void RegExpMacroAssemblerX64::PopRegister(int register_index) { Pop(rax); - __ movq(register_location(register_index), rax); + __ movp(register_location(register_index), rax); } @@ -1078,26 +1055,44 @@ void RegExpMacroAssemblerX64::PushCurrentPosition() { void RegExpMacroAssemblerX64::PushRegister(int register_index, StackCheckFlag check_stack_limit) { - __ movq(rax, register_location(register_index)); + __ movp(rax, register_location(register_index)); Push(rax); if (check_stack_limit) CheckStackLimit(); } +STATIC_ASSERT(kPointerSize == kInt64Size || kPointerSize == kInt32Size); + + void RegExpMacroAssemblerX64::ReadCurrentPositionFromRegister(int reg) { - __ movq(rdi, register_location(reg)); + if (kPointerSize == kInt64Size) { + __ movq(rdi, register_location(reg)); + } else { + // Need sign extension for x32 as rdi might be used as an index register. + __ movsxlq(rdi, register_location(reg)); + } +} + + +void RegExpMacroAssemblerX64::ReadPositionFromRegister(Register dst, int reg) { + if (kPointerSize == kInt64Size) { + __ movq(dst, register_location(reg)); + } else { + // Need sign extension for x32 as dst might be used as an index register. + __ movsxlq(dst, register_location(reg)); + } } void RegExpMacroAssemblerX64::ReadStackPointerFromRegister(int reg) { - __ movq(backtrack_stackpointer(), register_location(reg)); - __ addq(backtrack_stackpointer(), Operand(rbp, kStackHighEnd)); + __ movp(backtrack_stackpointer(), register_location(reg)); + __ addp(backtrack_stackpointer(), Operand(rbp, kStackHighEnd)); } void RegExpMacroAssemblerX64::SetCurrentPositionFromEnd(int by) { Label after_position; - __ cmpq(rdi, Immediate(-by * char_size())); + __ cmpp(rdi, Immediate(-by * char_size())); __ j(greater_equal, &after_position, Label::kNear); __ movq(rdi, Immediate(-by * char_size())); // On RegExp code entry (where this operation is used), the character before @@ -1110,7 +1105,7 @@ void RegExpMacroAssemblerX64::SetCurrentPositionFromEnd(int by) { void RegExpMacroAssemblerX64::SetRegister(int register_index, int to) { ASSERT(register_index >= num_saved_registers_); // Reserved for positions! - __ movq(register_location(register_index), Immediate(to)); + __ movp(register_location(register_index), Immediate(to)); } @@ -1123,27 +1118,27 @@ bool RegExpMacroAssemblerX64::Succeed() { void RegExpMacroAssemblerX64::WriteCurrentPositionToRegister(int reg, int cp_offset) { if (cp_offset == 0) { - __ movq(register_location(reg), rdi); + __ movp(register_location(reg), rdi); } else { - __ lea(rax, Operand(rdi, cp_offset * char_size())); - __ movq(register_location(reg), rax); + __ leap(rax, Operand(rdi, cp_offset * char_size())); + __ movp(register_location(reg), rax); } } void RegExpMacroAssemblerX64::ClearRegisters(int reg_from, int reg_to) { ASSERT(reg_from <= reg_to); - __ movq(rax, Operand(rbp, kInputStartMinusOne)); + __ movp(rax, Operand(rbp, kInputStartMinusOne)); for (int reg = reg_from; reg <= reg_to; reg++) { - __ movq(register_location(reg), rax); + __ movp(register_location(reg), rax); } } void RegExpMacroAssemblerX64::WriteStackPointerToRegister(int reg) { - __ movq(rax, backtrack_stackpointer()); - __ subq(rax, Operand(rbp, kStackHighEnd)); - __ movq(register_location(reg), rax); + __ movp(rax, backtrack_stackpointer()); + __ subp(rax, Operand(rbp, kStackHighEnd)); + __ movp(register_location(reg), rax); } @@ -1156,20 +1151,20 @@ void RegExpMacroAssemblerX64::CallCheckStackGuardState() { __ PrepareCallCFunction(num_arguments); #ifdef _WIN64 // Second argument: Code* of self. (Do this before overwriting r8). - __ movq(rdx, code_object_pointer()); + __ movp(rdx, code_object_pointer()); // Third argument: RegExp code frame pointer. - __ movq(r8, rbp); + __ movp(r8, rbp); // First argument: Next address on the stack (will be address of // return address). - __ lea(rcx, Operand(rsp, -kPointerSize)); + __ leap(rcx, Operand(rsp, -kPointerSize)); #else // Third argument: RegExp code frame pointer. - __ movq(rdx, rbp); + __ movp(rdx, rbp); // Second argument: Code* of self. - __ movq(rsi, code_object_pointer()); + __ movp(rsi, code_object_pointer()); // First argument: Next address on the stack (will be address of // return address). - __ lea(rdi, Operand(rsp, -kPointerSize)); + __ leap(rdi, Operand(rsp, -kRegisterSize)); #endif ExternalReference stack_check = ExternalReference::re_check_stack_guard_state(isolate()); @@ -1188,7 +1183,8 @@ int RegExpMacroAssemblerX64::CheckStackGuardState(Address* return_address, Code* re_code, Address re_frame) { Isolate* isolate = frame_entry<Isolate*>(re_frame, kIsolate); - if (isolate->stack_guard()->IsStackOverflow()) { + StackLimitCheck check(isolate); + if (check.JsHasOverflowed()) { isolate->StackOverflow(); return EXCEPTION; } @@ -1215,7 +1211,7 @@ int RegExpMacroAssemblerX64::CheckStackGuardState(Address* return_address, ASSERT(*return_address <= re_code->instruction_start() + re_code->instruction_size()); - MaybeObject* result = Execution::HandleStackGuardInterrupt(isolate); + Object* result = isolate->stack_guard()->HandleInterrupts(); if (*code_handle != re_code) { // Return address no longer valid intptr_t delta = code_handle->address() - re_code->address(); @@ -1323,12 +1319,12 @@ void RegExpMacroAssemblerX64::SafeCall(Label* to) { void RegExpMacroAssemblerX64::SafeCallTarget(Label* label) { __ bind(label); - __ subq(Operand(rsp, 0), code_object_pointer()); + __ subp(Operand(rsp, 0), code_object_pointer()); } void RegExpMacroAssemblerX64::SafeReturn() { - __ addq(Operand(rsp, 0), code_object_pointer()); + __ addp(Operand(rsp, 0), code_object_pointer()); __ ret(0); } @@ -1336,14 +1332,14 @@ void RegExpMacroAssemblerX64::SafeReturn() { void RegExpMacroAssemblerX64::Push(Register source) { ASSERT(!source.is(backtrack_stackpointer())); // Notice: This updates flags, unlike normal Push. - __ subq(backtrack_stackpointer(), Immediate(kIntSize)); + __ subp(backtrack_stackpointer(), Immediate(kIntSize)); __ movl(Operand(backtrack_stackpointer(), 0), source); } void RegExpMacroAssemblerX64::Push(Immediate value) { // Notice: This updates flags, unlike normal Push. - __ subq(backtrack_stackpointer(), Immediate(kIntSize)); + __ subp(backtrack_stackpointer(), Immediate(kIntSize)); __ movl(Operand(backtrack_stackpointer(), 0), value); } @@ -1367,7 +1363,7 @@ void RegExpMacroAssemblerX64::FixupCodeRelativePositions() { void RegExpMacroAssemblerX64::Push(Label* backtrack_target) { - __ subq(backtrack_stackpointer(), Immediate(kIntSize)); + __ subp(backtrack_stackpointer(), Immediate(kIntSize)); __ movl(Operand(backtrack_stackpointer(), 0), backtrack_target); MarkPositionForCodeRelativeFixup(); } @@ -1377,12 +1373,12 @@ void RegExpMacroAssemblerX64::Pop(Register target) { ASSERT(!target.is(backtrack_stackpointer())); __ movsxlq(target, Operand(backtrack_stackpointer(), 0)); // Notice: This updates flags, unlike normal Pop. - __ addq(backtrack_stackpointer(), Immediate(kIntSize)); + __ addp(backtrack_stackpointer(), Immediate(kIntSize)); } void RegExpMacroAssemblerX64::Drop() { - __ addq(backtrack_stackpointer(), Immediate(kIntSize)); + __ addp(backtrack_stackpointer(), Immediate(kIntSize)); } @@ -1392,7 +1388,7 @@ void RegExpMacroAssemblerX64::CheckPreemption() { ExternalReference stack_limit = ExternalReference::address_of_stack_limit(isolate()); __ load_rax(stack_limit); - __ cmpq(rsp, rax); + __ cmpp(rsp, rax); __ j(above, &no_preempt); SafeCall(&check_preempt_label_); @@ -1406,7 +1402,7 @@ void RegExpMacroAssemblerX64::CheckStackLimit() { ExternalReference stack_limit = ExternalReference::address_of_regexp_stack_limit(isolate()); __ load_rax(stack_limit); - __ cmpq(backtrack_stackpointer(), rax); + __ cmpp(backtrack_stackpointer(), rax); __ j(above, &no_stack_overflow); SafeCall(&stack_overflow_label_); |