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

Side by Side Diff: src/arm64/regexp-macro-assembler-arm64.cc

Issue 207823003: Rename A64 port to ARM64 port (Closed) Base URL: https://v8.googlecode.com/svn/branches/bleeding_edge
Patch Set: retry Created 6 years, 9 months 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 unified diff | Download patch | Annotate | Revision Log
« no previous file with comments | « src/arm64/regexp-macro-assembler-arm64.h ('k') | src/arm64/simulator-arm64.h » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
1 // Copyright 2013 the V8 project authors. All rights reserved. 1 // Copyright 2013 the V8 project authors. All rights reserved.
2 // Redistribution and use in source and binary forms, with or without 2 // Redistribution and use in source and binary forms, with or without
3 // modification, are permitted provided that the following conditions are 3 // modification, are permitted provided that the following conditions are
4 // met: 4 // met:
5 // 5 //
6 // * Redistributions of source code must retain the above copyright 6 // * Redistributions of source code must retain the above copyright
7 // notice, this list of conditions and the following disclaimer. 7 // notice, this list of conditions and the following disclaimer.
8 // * Redistributions in binary form must reproduce the above 8 // * Redistributions in binary form must reproduce the above
9 // copyright notice, this list of conditions and the following 9 // copyright notice, this list of conditions and the following
10 // disclaimer in the documentation and/or other materials provided 10 // disclaimer in the documentation and/or other materials provided
11 // with the distribution. 11 // with the distribution.
12 // * Neither the name of Google Inc. nor the names of its 12 // * Neither the name of Google Inc. nor the names of its
13 // contributors may be used to endorse or promote products derived 13 // contributors may be used to endorse or promote products derived
14 // from this software without specific prior written permission. 14 // from this software without specific prior written permission.
15 // 15 //
16 // THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 16 // THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
17 // "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 17 // "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
18 // LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR 18 // LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
19 // A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT 19 // A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
20 // OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, 20 // OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
21 // SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT 21 // SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
22 // LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 22 // LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
23 // DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 23 // DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
24 // THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 24 // THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
25 // (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 25 // (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
26 // OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 26 // OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
27 27
28 #include "v8.h" 28 #include "v8.h"
29 29
30 #if V8_TARGET_ARCH_A64 30 #if V8_TARGET_ARCH_ARM64
31 31
32 #include "cpu-profiler.h" 32 #include "cpu-profiler.h"
33 #include "unicode.h" 33 #include "unicode.h"
34 #include "log.h" 34 #include "log.h"
35 #include "code-stubs.h" 35 #include "code-stubs.h"
36 #include "regexp-stack.h" 36 #include "regexp-stack.h"
37 #include "macro-assembler.h" 37 #include "macro-assembler.h"
38 #include "regexp-macro-assembler.h" 38 #include "regexp-macro-assembler.h"
39 #include "a64/regexp-macro-assembler-a64.h" 39 #include "arm64/regexp-macro-assembler-arm64.h"
40 40
41 namespace v8 { 41 namespace v8 {
42 namespace internal { 42 namespace internal {
43 43
44 #ifndef V8_INTERPRETED_REGEXP 44 #ifndef V8_INTERPRETED_REGEXP
45 /* 45 /*
46 * This assembler uses the following register assignment convention: 46 * This assembler uses the following register assignment convention:
47 * - w19 : Used to temporarely store a value before a call to C code. 47 * - w19 : Used to temporarely store a value before a call to C code.
48 * See CheckNotBackReferenceIgnoreCase. 48 * See CheckNotBackReferenceIgnoreCase.
49 * - x20 : Pointer to the current code object (Code*), 49 * - x20 : Pointer to the current code object (Code*),
(...skipping 67 matching lines...) Expand 10 before | Expand all | Expand 10 after
117 * Address input_start, 117 * Address input_start,
118 * Address input_end, 118 * Address input_end,
119 * int* output, 119 * int* output,
120 * int output_size, 120 * int output_size,
121 * Address stack_base, 121 * Address stack_base,
122 * bool direct_call = false, 122 * bool direct_call = false,
123 * Address secondary_return_address, // Only used by native call. 123 * Address secondary_return_address, // Only used by native call.
124 * Isolate* isolate) 124 * Isolate* isolate)
125 * The call is performed by NativeRegExpMacroAssembler::Execute() 125 * The call is performed by NativeRegExpMacroAssembler::Execute()
126 * (in regexp-macro-assembler.cc) via the CALL_GENERATED_REGEXP_CODE macro 126 * (in regexp-macro-assembler.cc) via the CALL_GENERATED_REGEXP_CODE macro
127 * in a64/simulator-a64.h. 127 * in arm64/simulator-arm64.h.
128 * When calling as a non-direct call (i.e., from C++ code), the return address 128 * When calling as a non-direct call (i.e., from C++ code), the return address
129 * area is overwritten with the LR register by the RegExp code. When doing a 129 * area is overwritten with the LR register by the RegExp code. When doing a
130 * direct call from generated code, the return address is placed there by 130 * direct call from generated code, the return address is placed there by
131 * the calling code, as in a normal exit frame. 131 * the calling code, as in a normal exit frame.
132 */ 132 */
133 133
134 #define __ ACCESS_MASM(masm_) 134 #define __ ACCESS_MASM(masm_)
135 135
136 RegExpMacroAssemblerA64::RegExpMacroAssemblerA64( 136 RegExpMacroAssemblerARM64::RegExpMacroAssemblerARM64(
137 Mode mode, 137 Mode mode,
138 int registers_to_save, 138 int registers_to_save,
139 Zone* zone) 139 Zone* zone)
140 : NativeRegExpMacroAssembler(zone), 140 : NativeRegExpMacroAssembler(zone),
141 masm_(new MacroAssembler(zone->isolate(), NULL, kRegExpCodeSize)), 141 masm_(new MacroAssembler(zone->isolate(), NULL, kRegExpCodeSize)),
142 mode_(mode), 142 mode_(mode),
143 num_registers_(registers_to_save), 143 num_registers_(registers_to_save),
144 num_saved_registers_(registers_to_save), 144 num_saved_registers_(registers_to_save),
145 entry_label_(), 145 entry_label_(),
146 start_label_(), 146 start_label_(),
147 success_label_(), 147 success_label_(),
148 backtrack_label_(), 148 backtrack_label_(),
149 exit_label_() { 149 exit_label_() {
150 __ SetStackPointer(csp); 150 __ SetStackPointer(csp);
151 ASSERT_EQ(0, registers_to_save % 2); 151 ASSERT_EQ(0, registers_to_save % 2);
152 // We can cache at most 16 W registers in x0-x7. 152 // We can cache at most 16 W registers in x0-x7.
153 STATIC_ASSERT(kNumCachedRegisters <= 16); 153 STATIC_ASSERT(kNumCachedRegisters <= 16);
154 STATIC_ASSERT((kNumCachedRegisters % 2) == 0); 154 STATIC_ASSERT((kNumCachedRegisters % 2) == 0);
155 __ B(&entry_label_); // We'll write the entry code later. 155 __ B(&entry_label_); // We'll write the entry code later.
156 __ Bind(&start_label_); // And then continue from here. 156 __ Bind(&start_label_); // And then continue from here.
157 } 157 }
158 158
159 159
160 RegExpMacroAssemblerA64::~RegExpMacroAssemblerA64() { 160 RegExpMacroAssemblerARM64::~RegExpMacroAssemblerARM64() {
161 delete masm_; 161 delete masm_;
162 // Unuse labels in case we throw away the assembler without calling GetCode. 162 // Unuse labels in case we throw away the assembler without calling GetCode.
163 entry_label_.Unuse(); 163 entry_label_.Unuse();
164 start_label_.Unuse(); 164 start_label_.Unuse();
165 success_label_.Unuse(); 165 success_label_.Unuse();
166 backtrack_label_.Unuse(); 166 backtrack_label_.Unuse();
167 exit_label_.Unuse(); 167 exit_label_.Unuse();
168 check_preempt_label_.Unuse(); 168 check_preempt_label_.Unuse();
169 stack_overflow_label_.Unuse(); 169 stack_overflow_label_.Unuse();
170 } 170 }
171 171
172 int RegExpMacroAssemblerA64::stack_limit_slack() { 172 int RegExpMacroAssemblerARM64::stack_limit_slack() {
173 return RegExpStack::kStackLimitSlack; 173 return RegExpStack::kStackLimitSlack;
174 } 174 }
175 175
176 176
177 void RegExpMacroAssemblerA64::AdvanceCurrentPosition(int by) { 177 void RegExpMacroAssemblerARM64::AdvanceCurrentPosition(int by) {
178 if (by != 0) { 178 if (by != 0) {
179 __ Add(current_input_offset(), 179 __ Add(current_input_offset(),
180 current_input_offset(), by * char_size()); 180 current_input_offset(), by * char_size());
181 } 181 }
182 } 182 }
183 183
184 184
185 void RegExpMacroAssemblerA64::AdvanceRegister(int reg, int by) { 185 void RegExpMacroAssemblerARM64::AdvanceRegister(int reg, int by) {
186 ASSERT((reg >= 0) && (reg < num_registers_)); 186 ASSERT((reg >= 0) && (reg < num_registers_));
187 if (by != 0) { 187 if (by != 0) {
188 Register to_advance; 188 Register to_advance;
189 RegisterState register_state = GetRegisterState(reg); 189 RegisterState register_state = GetRegisterState(reg);
190 switch (register_state) { 190 switch (register_state) {
191 case STACKED: 191 case STACKED:
192 __ Ldr(w10, register_location(reg)); 192 __ Ldr(w10, register_location(reg));
193 __ Add(w10, w10, by); 193 __ Add(w10, w10, by);
194 __ Str(w10, register_location(reg)); 194 __ Str(w10, register_location(reg));
195 break; 195 break;
196 case CACHED_LSW: 196 case CACHED_LSW:
197 to_advance = GetCachedRegister(reg); 197 to_advance = GetCachedRegister(reg);
198 __ Add(to_advance, to_advance, by); 198 __ Add(to_advance, to_advance, by);
199 break; 199 break;
200 case CACHED_MSW: 200 case CACHED_MSW:
201 to_advance = GetCachedRegister(reg); 201 to_advance = GetCachedRegister(reg);
202 __ Add(to_advance, to_advance, 202 __ Add(to_advance, to_advance,
203 static_cast<int64_t>(by) << kWRegSizeInBits); 203 static_cast<int64_t>(by) << kWRegSizeInBits);
204 break; 204 break;
205 default: 205 default:
206 UNREACHABLE(); 206 UNREACHABLE();
207 break; 207 break;
208 } 208 }
209 } 209 }
210 } 210 }
211 211
212 212
213 void RegExpMacroAssemblerA64::Backtrack() { 213 void RegExpMacroAssemblerARM64::Backtrack() {
214 CheckPreemption(); 214 CheckPreemption();
215 Pop(w10); 215 Pop(w10);
216 __ Add(x10, code_pointer(), Operand(w10, UXTW)); 216 __ Add(x10, code_pointer(), Operand(w10, UXTW));
217 __ Br(x10); 217 __ Br(x10);
218 } 218 }
219 219
220 220
221 void RegExpMacroAssemblerA64::Bind(Label* label) { 221 void RegExpMacroAssemblerARM64::Bind(Label* label) {
222 __ Bind(label); 222 __ Bind(label);
223 } 223 }
224 224
225 225
226 void RegExpMacroAssemblerA64::CheckCharacter(uint32_t c, Label* on_equal) { 226 void RegExpMacroAssemblerARM64::CheckCharacter(uint32_t c, Label* on_equal) {
227 CompareAndBranchOrBacktrack(current_character(), c, eq, on_equal); 227 CompareAndBranchOrBacktrack(current_character(), c, eq, on_equal);
228 } 228 }
229 229
230 230
231 void RegExpMacroAssemblerA64::CheckCharacterGT(uc16 limit, Label* on_greater) { 231 void RegExpMacroAssemblerARM64::CheckCharacterGT(uc16 limit,
232 Label* on_greater) {
232 CompareAndBranchOrBacktrack(current_character(), limit, hi, on_greater); 233 CompareAndBranchOrBacktrack(current_character(), limit, hi, on_greater);
233 } 234 }
234 235
235 236
236 void RegExpMacroAssemblerA64::CheckAtStart(Label* on_at_start) { 237 void RegExpMacroAssemblerARM64::CheckAtStart(Label* on_at_start) {
237 Label not_at_start; 238 Label not_at_start;
238 // Did we start the match at the start of the input string? 239 // Did we start the match at the start of the input string?
239 CompareAndBranchOrBacktrack(start_offset(), 0, ne, &not_at_start); 240 CompareAndBranchOrBacktrack(start_offset(), 0, ne, &not_at_start);
240 // If we did, are we still at the start of the input string? 241 // If we did, are we still at the start of the input string?
241 __ Add(x10, input_end(), Operand(current_input_offset(), SXTW)); 242 __ Add(x10, input_end(), Operand(current_input_offset(), SXTW));
242 __ Cmp(x10, input_start()); 243 __ Cmp(x10, input_start());
243 BranchOrBacktrack(eq, on_at_start); 244 BranchOrBacktrack(eq, on_at_start);
244 __ Bind(&not_at_start); 245 __ Bind(&not_at_start);
245 } 246 }
246 247
247 248
248 void RegExpMacroAssemblerA64::CheckNotAtStart(Label* on_not_at_start) { 249 void RegExpMacroAssemblerARM64::CheckNotAtStart(Label* on_not_at_start) {
249 // Did we start the match at the start of the input string? 250 // Did we start the match at the start of the input string?
250 CompareAndBranchOrBacktrack(start_offset(), 0, ne, on_not_at_start); 251 CompareAndBranchOrBacktrack(start_offset(), 0, ne, on_not_at_start);
251 // If we did, are we still at the start of the input string? 252 // If we did, are we still at the start of the input string?
252 __ Add(x10, input_end(), Operand(current_input_offset(), SXTW)); 253 __ Add(x10, input_end(), Operand(current_input_offset(), SXTW));
253 __ Cmp(x10, input_start()); 254 __ Cmp(x10, input_start());
254 BranchOrBacktrack(ne, on_not_at_start); 255 BranchOrBacktrack(ne, on_not_at_start);
255 } 256 }
256 257
257 258
258 void RegExpMacroAssemblerA64::CheckCharacterLT(uc16 limit, Label* on_less) { 259 void RegExpMacroAssemblerARM64::CheckCharacterLT(uc16 limit, Label* on_less) {
259 CompareAndBranchOrBacktrack(current_character(), limit, lo, on_less); 260 CompareAndBranchOrBacktrack(current_character(), limit, lo, on_less);
260 } 261 }
261 262
262 263
263 void RegExpMacroAssemblerA64::CheckCharacters(Vector<const uc16> str, 264 void RegExpMacroAssemblerARM64::CheckCharacters(Vector<const uc16> str,
264 int cp_offset, 265 int cp_offset,
265 Label* on_failure, 266 Label* on_failure,
266 bool check_end_of_string) { 267 bool check_end_of_string) {
267 // This method is only ever called from the cctests. 268 // This method is only ever called from the cctests.
268 269
269 if (check_end_of_string) { 270 if (check_end_of_string) {
270 // Is last character of required match inside string. 271 // Is last character of required match inside string.
271 CheckPosition(cp_offset + str.length() - 1, on_failure); 272 CheckPosition(cp_offset + str.length() - 1, on_failure);
272 } 273 }
273 274
(...skipping 11 matching lines...) Expand all
285 __ Ldrb(w10, MemOperand(characters_address, 1, PostIndex)); 286 __ Ldrb(w10, MemOperand(characters_address, 1, PostIndex));
286 ASSERT(str[i] <= String::kMaxOneByteCharCode); 287 ASSERT(str[i] <= String::kMaxOneByteCharCode);
287 } else { 288 } else {
288 __ Ldrh(w10, MemOperand(characters_address, 2, PostIndex)); 289 __ Ldrh(w10, MemOperand(characters_address, 2, PostIndex));
289 } 290 }
290 CompareAndBranchOrBacktrack(w10, str[i], ne, on_failure); 291 CompareAndBranchOrBacktrack(w10, str[i], ne, on_failure);
291 } 292 }
292 } 293 }
293 294
294 295
295 void RegExpMacroAssemblerA64::CheckGreedyLoop(Label* on_equal) { 296 void RegExpMacroAssemblerARM64::CheckGreedyLoop(Label* on_equal) {
296 __ Ldr(w10, MemOperand(backtrack_stackpointer())); 297 __ Ldr(w10, MemOperand(backtrack_stackpointer()));
297 __ Cmp(current_input_offset(), w10); 298 __ Cmp(current_input_offset(), w10);
298 __ Cset(x11, eq); 299 __ Cset(x11, eq);
299 __ Add(backtrack_stackpointer(), 300 __ Add(backtrack_stackpointer(),
300 backtrack_stackpointer(), Operand(x11, LSL, kWRegSizeLog2)); 301 backtrack_stackpointer(), Operand(x11, LSL, kWRegSizeLog2));
301 BranchOrBacktrack(eq, on_equal); 302 BranchOrBacktrack(eq, on_equal);
302 } 303 }
303 304
304 void RegExpMacroAssemblerA64::CheckNotBackReferenceIgnoreCase( 305 void RegExpMacroAssemblerARM64::CheckNotBackReferenceIgnoreCase(
305 int start_reg, 306 int start_reg,
306 Label* on_no_match) { 307 Label* on_no_match) {
307 Label fallthrough; 308 Label fallthrough;
308 309
309 Register capture_start_offset = w10; 310 Register capture_start_offset = w10;
310 // Save the capture length in a callee-saved register so it will 311 // Save the capture length in a callee-saved register so it will
311 // be preserved if we call a C helper. 312 // be preserved if we call a C helper.
312 Register capture_length = w19; 313 Register capture_length = w19;
313 ASSERT(kCalleeSaved.IncludesAliasOf(capture_length)); 314 ASSERT(kCalleeSaved.IncludesAliasOf(capture_length));
314 315
(...skipping 106 matching lines...) Expand 10 before | Expand all | Expand 10 after
421 CompareAndBranchOrBacktrack(x0, 0, eq, on_no_match); 422 CompareAndBranchOrBacktrack(x0, 0, eq, on_no_match);
422 // On success, increment position by length of capture. 423 // On success, increment position by length of capture.
423 __ Add(current_input_offset(), current_input_offset(), capture_length); 424 __ Add(current_input_offset(), current_input_offset(), capture_length);
424 // Reset the cached registers. 425 // Reset the cached registers.
425 __ PopCPURegList(cached_registers); 426 __ PopCPURegList(cached_registers);
426 } 427 }
427 428
428 __ Bind(&fallthrough); 429 __ Bind(&fallthrough);
429 } 430 }
430 431
431 void RegExpMacroAssemblerA64::CheckNotBackReference( 432 void RegExpMacroAssemblerARM64::CheckNotBackReference(
432 int start_reg, 433 int start_reg,
433 Label* on_no_match) { 434 Label* on_no_match) {
434 Label fallthrough; 435 Label fallthrough;
435 436
436 Register capture_start_address = x12; 437 Register capture_start_address = x12;
437 Register capture_end_address = x13; 438 Register capture_end_address = x13;
438 Register current_position_address = x14; 439 Register current_position_address = x14;
439 Register capture_length = w15; 440 Register capture_length = w15;
440 441
441 // Find length of back-referenced capture. 442 // Find length of back-referenced capture.
(...skipping 41 matching lines...) Expand 10 before | Expand all | Expand 10 after
483 if (masm_->emit_debug_code()) { 484 if (masm_->emit_debug_code()) {
484 __ Cmp(current_input_offset().X(), Operand(current_input_offset(), SXTW)); 485 __ Cmp(current_input_offset().X(), Operand(current_input_offset(), SXTW));
485 __ Ccmp(current_input_offset(), 0, NoFlag, eq); 486 __ Ccmp(current_input_offset(), 0, NoFlag, eq);
486 // The current input offset should be <= 0, and fit in a W register. 487 // The current input offset should be <= 0, and fit in a W register.
487 __ Check(le, kOffsetOutOfRange); 488 __ Check(le, kOffsetOutOfRange);
488 } 489 }
489 __ Bind(&fallthrough); 490 __ Bind(&fallthrough);
490 } 491 }
491 492
492 493
493 void RegExpMacroAssemblerA64::CheckNotCharacter(unsigned c, 494 void RegExpMacroAssemblerARM64::CheckNotCharacter(unsigned c,
494 Label* on_not_equal) { 495 Label* on_not_equal) {
495 CompareAndBranchOrBacktrack(current_character(), c, ne, on_not_equal); 496 CompareAndBranchOrBacktrack(current_character(), c, ne, on_not_equal);
496 } 497 }
497 498
498 499
499 void RegExpMacroAssemblerA64::CheckCharacterAfterAnd(uint32_t c, 500 void RegExpMacroAssemblerARM64::CheckCharacterAfterAnd(uint32_t c,
500 uint32_t mask, 501 uint32_t mask,
501 Label* on_equal) { 502 Label* on_equal) {
502 __ And(w10, current_character(), mask); 503 __ And(w10, current_character(), mask);
503 CompareAndBranchOrBacktrack(w10, c, eq, on_equal); 504 CompareAndBranchOrBacktrack(w10, c, eq, on_equal);
504 } 505 }
505 506
506 507
507 void RegExpMacroAssemblerA64::CheckNotCharacterAfterAnd(unsigned c, 508 void RegExpMacroAssemblerARM64::CheckNotCharacterAfterAnd(unsigned c,
508 unsigned mask, 509 unsigned mask,
509 Label* on_not_equal) { 510 Label* on_not_equal) {
510 __ And(w10, current_character(), mask); 511 __ And(w10, current_character(), mask);
511 CompareAndBranchOrBacktrack(w10, c, ne, on_not_equal); 512 CompareAndBranchOrBacktrack(w10, c, ne, on_not_equal);
512 } 513 }
513 514
514 515
515 void RegExpMacroAssemblerA64::CheckNotCharacterAfterMinusAnd( 516 void RegExpMacroAssemblerARM64::CheckNotCharacterAfterMinusAnd(
516 uc16 c, 517 uc16 c,
517 uc16 minus, 518 uc16 minus,
518 uc16 mask, 519 uc16 mask,
519 Label* on_not_equal) { 520 Label* on_not_equal) {
520 ASSERT(minus < String::kMaxUtf16CodeUnit); 521 ASSERT(minus < String::kMaxUtf16CodeUnit);
521 __ Sub(w10, current_character(), minus); 522 __ Sub(w10, current_character(), minus);
522 __ And(w10, w10, mask); 523 __ And(w10, w10, mask);
523 CompareAndBranchOrBacktrack(w10, c, ne, on_not_equal); 524 CompareAndBranchOrBacktrack(w10, c, ne, on_not_equal);
524 } 525 }
525 526
526 527
527 void RegExpMacroAssemblerA64::CheckCharacterInRange( 528 void RegExpMacroAssemblerARM64::CheckCharacterInRange(
528 uc16 from, 529 uc16 from,
529 uc16 to, 530 uc16 to,
530 Label* on_in_range) { 531 Label* on_in_range) {
531 __ Sub(w10, current_character(), from); 532 __ Sub(w10, current_character(), from);
532 // Unsigned lower-or-same condition. 533 // Unsigned lower-or-same condition.
533 CompareAndBranchOrBacktrack(w10, to - from, ls, on_in_range); 534 CompareAndBranchOrBacktrack(w10, to - from, ls, on_in_range);
534 } 535 }
535 536
536 537
537 void RegExpMacroAssemblerA64::CheckCharacterNotInRange( 538 void RegExpMacroAssemblerARM64::CheckCharacterNotInRange(
538 uc16 from, 539 uc16 from,
539 uc16 to, 540 uc16 to,
540 Label* on_not_in_range) { 541 Label* on_not_in_range) {
541 __ Sub(w10, current_character(), from); 542 __ Sub(w10, current_character(), from);
542 // Unsigned higher condition. 543 // Unsigned higher condition.
543 CompareAndBranchOrBacktrack(w10, to - from, hi, on_not_in_range); 544 CompareAndBranchOrBacktrack(w10, to - from, hi, on_not_in_range);
544 } 545 }
545 546
546 547
547 void RegExpMacroAssemblerA64::CheckBitInTable( 548 void RegExpMacroAssemblerARM64::CheckBitInTable(
548 Handle<ByteArray> table, 549 Handle<ByteArray> table,
549 Label* on_bit_set) { 550 Label* on_bit_set) {
550 __ Mov(x11, Operand(table)); 551 __ Mov(x11, Operand(table));
551 if ((mode_ != ASCII) || (kTableMask != String::kMaxOneByteCharCode)) { 552 if ((mode_ != ASCII) || (kTableMask != String::kMaxOneByteCharCode)) {
552 __ And(w10, current_character(), kTableMask); 553 __ And(w10, current_character(), kTableMask);
553 __ Add(w10, w10, ByteArray::kHeaderSize - kHeapObjectTag); 554 __ Add(w10, w10, ByteArray::kHeaderSize - kHeapObjectTag);
554 } else { 555 } else {
555 __ Add(w10, current_character(), ByteArray::kHeaderSize - kHeapObjectTag); 556 __ Add(w10, current_character(), ByteArray::kHeaderSize - kHeapObjectTag);
556 } 557 }
557 __ Ldrb(w11, MemOperand(x11, w10, UXTW)); 558 __ Ldrb(w11, MemOperand(x11, w10, UXTW));
558 CompareAndBranchOrBacktrack(w11, 0, ne, on_bit_set); 559 CompareAndBranchOrBacktrack(w11, 0, ne, on_bit_set);
559 } 560 }
560 561
561 562
562 bool RegExpMacroAssemblerA64::CheckSpecialCharacterClass(uc16 type, 563 bool RegExpMacroAssemblerARM64::CheckSpecialCharacterClass(uc16 type,
563 Label* on_no_match) { 564 Label* on_no_match) {
564 // Range checks (c in min..max) are generally implemented by an unsigned 565 // Range checks (c in min..max) are generally implemented by an unsigned
565 // (c - min) <= (max - min) check 566 // (c - min) <= (max - min) check
566 switch (type) { 567 switch (type) {
567 case 's': 568 case 's':
568 // Match space-characters 569 // Match space-characters
569 if (mode_ == ASCII) { 570 if (mode_ == ASCII) {
570 // One byte space characters are '\t'..'\r', ' ' and \u00a0. 571 // One byte space characters are '\t'..'\r', ' ' and \u00a0.
571 Label success; 572 Label success;
572 // Check for ' ' or 0x00a0. 573 // Check for ' ' or 0x00a0.
573 __ Cmp(current_character(), ' '); 574 __ Cmp(current_character(), ' ');
(...skipping 82 matching lines...) Expand 10 before | Expand all | Expand 10 after
656 case '*': 657 case '*':
657 // Match any character. 658 // Match any character.
658 return true; 659 return true;
659 // No custom implementation (yet): s(UC16), S(UC16). 660 // No custom implementation (yet): s(UC16), S(UC16).
660 default: 661 default:
661 return false; 662 return false;
662 } 663 }
663 } 664 }
664 665
665 666
666 void RegExpMacroAssemblerA64::Fail() { 667 void RegExpMacroAssemblerARM64::Fail() {
667 __ Mov(w0, FAILURE); 668 __ Mov(w0, FAILURE);
668 __ B(&exit_label_); 669 __ B(&exit_label_);
669 } 670 }
670 671
671 672
672 Handle<HeapObject> RegExpMacroAssemblerA64::GetCode(Handle<String> source) { 673 Handle<HeapObject> RegExpMacroAssemblerARM64::GetCode(Handle<String> source) {
673 Label return_w0; 674 Label return_w0;
674 // Finalize code - write the entry point code now we know how many 675 // Finalize code - write the entry point code now we know how many
675 // registers we need. 676 // registers we need.
676 677
677 // Entry code: 678 // Entry code:
678 __ Bind(&entry_label_); 679 __ Bind(&entry_label_);
679 680
680 // Arguments on entry: 681 // Arguments on entry:
681 // x0: String* input 682 // x0: String* input
682 // x1: int start_offset 683 // x1: int start_offset
(...skipping 375 matching lines...) Expand 10 before | Expand all | Expand 10 after
1058 1059
1059 CodeDesc code_desc; 1060 CodeDesc code_desc;
1060 masm_->GetCode(&code_desc); 1061 masm_->GetCode(&code_desc);
1061 Handle<Code> code = isolate()->factory()->NewCode( 1062 Handle<Code> code = isolate()->factory()->NewCode(
1062 code_desc, Code::ComputeFlags(Code::REGEXP), masm_->CodeObject()); 1063 code_desc, Code::ComputeFlags(Code::REGEXP), masm_->CodeObject());
1063 PROFILE(masm_->isolate(), RegExpCodeCreateEvent(*code, *source)); 1064 PROFILE(masm_->isolate(), RegExpCodeCreateEvent(*code, *source));
1064 return Handle<HeapObject>::cast(code); 1065 return Handle<HeapObject>::cast(code);
1065 } 1066 }
1066 1067
1067 1068
1068 void RegExpMacroAssemblerA64::GoTo(Label* to) { 1069 void RegExpMacroAssemblerARM64::GoTo(Label* to) {
1069 BranchOrBacktrack(al, to); 1070 BranchOrBacktrack(al, to);
1070 } 1071 }
1071 1072
1072 void RegExpMacroAssemblerA64::IfRegisterGE(int reg, 1073 void RegExpMacroAssemblerARM64::IfRegisterGE(int reg, int comparand,
1073 int comparand, 1074 Label* if_ge) {
1074 Label* if_ge) {
1075 Register to_compare = GetRegister(reg, w10); 1075 Register to_compare = GetRegister(reg, w10);
1076 CompareAndBranchOrBacktrack(to_compare, comparand, ge, if_ge); 1076 CompareAndBranchOrBacktrack(to_compare, comparand, ge, if_ge);
1077 } 1077 }
1078 1078
1079 1079
1080 void RegExpMacroAssemblerA64::IfRegisterLT(int reg, 1080 void RegExpMacroAssemblerARM64::IfRegisterLT(int reg, int comparand,
1081 int comparand, 1081 Label* if_lt) {
1082 Label* if_lt) {
1083 Register to_compare = GetRegister(reg, w10); 1082 Register to_compare = GetRegister(reg, w10);
1084 CompareAndBranchOrBacktrack(to_compare, comparand, lt, if_lt); 1083 CompareAndBranchOrBacktrack(to_compare, comparand, lt, if_lt);
1085 } 1084 }
1086 1085
1087 1086
1088 void RegExpMacroAssemblerA64::IfRegisterEqPos(int reg, 1087 void RegExpMacroAssemblerARM64::IfRegisterEqPos(int reg, Label* if_eq) {
1089 Label* if_eq) {
1090 Register to_compare = GetRegister(reg, w10); 1088 Register to_compare = GetRegister(reg, w10);
1091 __ Cmp(to_compare, current_input_offset()); 1089 __ Cmp(to_compare, current_input_offset());
1092 BranchOrBacktrack(eq, if_eq); 1090 BranchOrBacktrack(eq, if_eq);
1093 } 1091 }
1094 1092
1095 RegExpMacroAssembler::IrregexpImplementation 1093 RegExpMacroAssembler::IrregexpImplementation
1096 RegExpMacroAssemblerA64::Implementation() { 1094 RegExpMacroAssemblerARM64::Implementation() {
1097 return kA64Implementation; 1095 return kARM64Implementation;
1098 } 1096 }
1099 1097
1100 1098
1101 void RegExpMacroAssemblerA64::LoadCurrentCharacter(int cp_offset, 1099 void RegExpMacroAssemblerARM64::LoadCurrentCharacter(int cp_offset,
1102 Label* on_end_of_input, 1100 Label* on_end_of_input,
1103 bool check_bounds, 1101 bool check_bounds,
1104 int characters) { 1102 int characters) {
1105 // TODO(pielan): Make sure long strings are caught before this, and not 1103 // TODO(pielan): Make sure long strings are caught before this, and not
1106 // just asserted in debug mode. 1104 // just asserted in debug mode.
1107 ASSERT(cp_offset >= -1); // ^ and \b can look behind one character. 1105 ASSERT(cp_offset >= -1); // ^ and \b can look behind one character.
1108 // Be sane! (And ensure that an int32_t can be used to index the string) 1106 // Be sane! (And ensure that an int32_t can be used to index the string)
1109 ASSERT(cp_offset < (1<<30)); 1107 ASSERT(cp_offset < (1<<30));
1110 if (check_bounds) { 1108 if (check_bounds) {
1111 CheckPosition(cp_offset + characters - 1, on_end_of_input); 1109 CheckPosition(cp_offset + characters - 1, on_end_of_input);
1112 } 1110 }
1113 LoadCurrentCharacterUnchecked(cp_offset, characters); 1111 LoadCurrentCharacterUnchecked(cp_offset, characters);
1114 } 1112 }
1115 1113
1116 1114
1117 void RegExpMacroAssemblerA64::PopCurrentPosition() { 1115 void RegExpMacroAssemblerARM64::PopCurrentPosition() {
1118 Pop(current_input_offset()); 1116 Pop(current_input_offset());
1119 } 1117 }
1120 1118
1121 1119
1122 void RegExpMacroAssemblerA64::PopRegister(int register_index) { 1120 void RegExpMacroAssemblerARM64::PopRegister(int register_index) {
1123 Pop(w10); 1121 Pop(w10);
1124 StoreRegister(register_index, w10); 1122 StoreRegister(register_index, w10);
1125 } 1123 }
1126 1124
1127 1125
1128 void RegExpMacroAssemblerA64::PushBacktrack(Label* label) { 1126 void RegExpMacroAssemblerARM64::PushBacktrack(Label* label) {
1129 if (label->is_bound()) { 1127 if (label->is_bound()) {
1130 int target = label->pos(); 1128 int target = label->pos();
1131 __ Mov(w10, target + Code::kHeaderSize - kHeapObjectTag); 1129 __ Mov(w10, target + Code::kHeaderSize - kHeapObjectTag);
1132 } else { 1130 } else {
1133 __ Adr(x10, label); 1131 __ Adr(x10, label);
1134 __ Sub(x10, x10, code_pointer()); 1132 __ Sub(x10, x10, code_pointer());
1135 if (masm_->emit_debug_code()) { 1133 if (masm_->emit_debug_code()) {
1136 __ Cmp(x10, kWRegMask); 1134 __ Cmp(x10, kWRegMask);
1137 // The code offset has to fit in a W register. 1135 // The code offset has to fit in a W register.
1138 __ Check(ls, kOffsetOutOfRange); 1136 __ Check(ls, kOffsetOutOfRange);
1139 } 1137 }
1140 } 1138 }
1141 Push(w10); 1139 Push(w10);
1142 CheckStackLimit(); 1140 CheckStackLimit();
1143 } 1141 }
1144 1142
1145 1143
1146 void RegExpMacroAssemblerA64::PushCurrentPosition() { 1144 void RegExpMacroAssemblerARM64::PushCurrentPosition() {
1147 Push(current_input_offset()); 1145 Push(current_input_offset());
1148 } 1146 }
1149 1147
1150 1148
1151 void RegExpMacroAssemblerA64::PushRegister(int register_index, 1149 void RegExpMacroAssemblerARM64::PushRegister(int register_index,
1152 StackCheckFlag check_stack_limit) { 1150 StackCheckFlag check_stack_limit) {
1153 Register to_push = GetRegister(register_index, w10); 1151 Register to_push = GetRegister(register_index, w10);
1154 Push(to_push); 1152 Push(to_push);
1155 if (check_stack_limit) CheckStackLimit(); 1153 if (check_stack_limit) CheckStackLimit();
1156 } 1154 }
1157 1155
1158 1156
1159 void RegExpMacroAssemblerA64::ReadCurrentPositionFromRegister(int reg) { 1157 void RegExpMacroAssemblerARM64::ReadCurrentPositionFromRegister(int reg) {
1160 Register cached_register; 1158 Register cached_register;
1161 RegisterState register_state = GetRegisterState(reg); 1159 RegisterState register_state = GetRegisterState(reg);
1162 switch (register_state) { 1160 switch (register_state) {
1163 case STACKED: 1161 case STACKED:
1164 __ Ldr(current_input_offset(), register_location(reg)); 1162 __ Ldr(current_input_offset(), register_location(reg));
1165 break; 1163 break;
1166 case CACHED_LSW: 1164 case CACHED_LSW:
1167 cached_register = GetCachedRegister(reg); 1165 cached_register = GetCachedRegister(reg);
1168 __ Mov(current_input_offset(), cached_register.W()); 1166 __ Mov(current_input_offset(), cached_register.W());
1169 break; 1167 break;
1170 case CACHED_MSW: 1168 case CACHED_MSW:
1171 cached_register = GetCachedRegister(reg); 1169 cached_register = GetCachedRegister(reg);
1172 __ Lsr(current_input_offset().X(), cached_register, kWRegSizeInBits); 1170 __ Lsr(current_input_offset().X(), cached_register, kWRegSizeInBits);
1173 break; 1171 break;
1174 default: 1172 default:
1175 UNREACHABLE(); 1173 UNREACHABLE();
1176 break; 1174 break;
1177 } 1175 }
1178 } 1176 }
1179 1177
1180 1178
1181 void RegExpMacroAssemblerA64::ReadStackPointerFromRegister(int reg) { 1179 void RegExpMacroAssemblerARM64::ReadStackPointerFromRegister(int reg) {
1182 Register read_from = GetRegister(reg, w10); 1180 Register read_from = GetRegister(reg, w10);
1183 __ Ldr(x11, MemOperand(frame_pointer(), kStackBase)); 1181 __ Ldr(x11, MemOperand(frame_pointer(), kStackBase));
1184 __ Add(backtrack_stackpointer(), x11, Operand(read_from, SXTW)); 1182 __ Add(backtrack_stackpointer(), x11, Operand(read_from, SXTW));
1185 } 1183 }
1186 1184
1187 1185
1188 void RegExpMacroAssemblerA64::SetCurrentPositionFromEnd(int by) { 1186 void RegExpMacroAssemblerARM64::SetCurrentPositionFromEnd(int by) {
1189 Label after_position; 1187 Label after_position;
1190 __ Cmp(current_input_offset(), -by * char_size()); 1188 __ Cmp(current_input_offset(), -by * char_size());
1191 __ B(ge, &after_position); 1189 __ B(ge, &after_position);
1192 __ Mov(current_input_offset(), -by * char_size()); 1190 __ Mov(current_input_offset(), -by * char_size());
1193 // On RegExp code entry (where this operation is used), the character before 1191 // On RegExp code entry (where this operation is used), the character before
1194 // the current position is expected to be already loaded. 1192 // the current position is expected to be already loaded.
1195 // We have advanced the position, so it's safe to read backwards. 1193 // We have advanced the position, so it's safe to read backwards.
1196 LoadCurrentCharacterUnchecked(-1, 1); 1194 LoadCurrentCharacterUnchecked(-1, 1);
1197 __ Bind(&after_position); 1195 __ Bind(&after_position);
1198 } 1196 }
1199 1197
1200 1198
1201 void RegExpMacroAssemblerA64::SetRegister(int register_index, int to) { 1199 void RegExpMacroAssemblerARM64::SetRegister(int register_index, int to) {
1202 ASSERT(register_index >= num_saved_registers_); // Reserved for positions! 1200 ASSERT(register_index >= num_saved_registers_); // Reserved for positions!
1203 Register set_to = wzr; 1201 Register set_to = wzr;
1204 if (to != 0) { 1202 if (to != 0) {
1205 set_to = w10; 1203 set_to = w10;
1206 __ Mov(set_to, to); 1204 __ Mov(set_to, to);
1207 } 1205 }
1208 StoreRegister(register_index, set_to); 1206 StoreRegister(register_index, set_to);
1209 } 1207 }
1210 1208
1211 1209
1212 bool RegExpMacroAssemblerA64::Succeed() { 1210 bool RegExpMacroAssemblerARM64::Succeed() {
1213 __ B(&success_label_); 1211 __ B(&success_label_);
1214 return global(); 1212 return global();
1215 } 1213 }
1216 1214
1217 1215
1218 void RegExpMacroAssemblerA64::WriteCurrentPositionToRegister(int reg, 1216 void RegExpMacroAssemblerARM64::WriteCurrentPositionToRegister(int reg,
1219 int cp_offset) { 1217 int cp_offset) {
1220 Register position = current_input_offset(); 1218 Register position = current_input_offset();
1221 if (cp_offset != 0) { 1219 if (cp_offset != 0) {
1222 position = w10; 1220 position = w10;
1223 __ Add(position, current_input_offset(), cp_offset * char_size()); 1221 __ Add(position, current_input_offset(), cp_offset * char_size());
1224 } 1222 }
1225 StoreRegister(reg, position); 1223 StoreRegister(reg, position);
1226 } 1224 }
1227 1225
1228 1226
1229 void RegExpMacroAssemblerA64::ClearRegisters(int reg_from, int reg_to) { 1227 void RegExpMacroAssemblerARM64::ClearRegisters(int reg_from, int reg_to) {
1230 ASSERT(reg_from <= reg_to); 1228 ASSERT(reg_from <= reg_to);
1231 int num_registers = reg_to - reg_from + 1; 1229 int num_registers = reg_to - reg_from + 1;
1232 1230
1233 // If the first capture register is cached in a hardware register but not 1231 // If the first capture register is cached in a hardware register but not
1234 // aligned on a 64-bit one, we need to clear the first one specifically. 1232 // aligned on a 64-bit one, we need to clear the first one specifically.
1235 if ((reg_from < kNumCachedRegisters) && ((reg_from % 2) != 0)) { 1233 if ((reg_from < kNumCachedRegisters) && ((reg_from % 2) != 0)) {
1236 StoreRegister(reg_from, non_position_value()); 1234 StoreRegister(reg_from, non_position_value());
1237 num_registers--; 1235 num_registers--;
1238 reg_from++; 1236 reg_from++;
1239 } 1237 }
(...skipping 40 matching lines...) Expand 10 before | Expand all | Expand 10 after
1280 for (int i = reg_from; i <= reg_to; i += 2) { 1278 for (int i = reg_from; i <= reg_to; i += 2) {
1281 __ Str(twice_non_position_value(), 1279 __ Str(twice_non_position_value(),
1282 MemOperand(frame_pointer(), base_offset)); 1280 MemOperand(frame_pointer(), base_offset));
1283 base_offset -= kWRegSize * 2; 1281 base_offset -= kWRegSize * 2;
1284 } 1282 }
1285 } 1283 }
1286 } 1284 }
1287 } 1285 }
1288 1286
1289 1287
1290 void RegExpMacroAssemblerA64::WriteStackPointerToRegister(int reg) { 1288 void RegExpMacroAssemblerARM64::WriteStackPointerToRegister(int reg) {
1291 __ Ldr(x10, MemOperand(frame_pointer(), kStackBase)); 1289 __ Ldr(x10, MemOperand(frame_pointer(), kStackBase));
1292 __ Sub(x10, backtrack_stackpointer(), x10); 1290 __ Sub(x10, backtrack_stackpointer(), x10);
1293 if (masm_->emit_debug_code()) { 1291 if (masm_->emit_debug_code()) {
1294 __ Cmp(x10, Operand(w10, SXTW)); 1292 __ Cmp(x10, Operand(w10, SXTW));
1295 // The stack offset needs to fit in a W register. 1293 // The stack offset needs to fit in a W register.
1296 __ Check(eq, kOffsetOutOfRange); 1294 __ Check(eq, kOffsetOutOfRange);
1297 } 1295 }
1298 StoreRegister(reg, w10); 1296 StoreRegister(reg, w10);
1299 } 1297 }
1300 1298
1301 1299
1302 // Helper function for reading a value out of a stack frame. 1300 // Helper function for reading a value out of a stack frame.
1303 template <typename T> 1301 template <typename T>
1304 static T& frame_entry(Address re_frame, int frame_offset) { 1302 static T& frame_entry(Address re_frame, int frame_offset) {
1305 return *reinterpret_cast<T*>(re_frame + frame_offset); 1303 return *reinterpret_cast<T*>(re_frame + frame_offset);
1306 } 1304 }
1307 1305
1308 1306
1309 int RegExpMacroAssemblerA64::CheckStackGuardState(Address* return_address, 1307 int RegExpMacroAssemblerARM64::CheckStackGuardState(Address* return_address,
1310 Code* re_code, 1308 Code* re_code,
1311 Address re_frame, 1309 Address re_frame,
1312 int start_offset, 1310 int start_offset,
1313 const byte** input_start, 1311 const byte** input_start,
1314 const byte** input_end) { 1312 const byte** input_end) {
1315 Isolate* isolate = frame_entry<Isolate*>(re_frame, kIsolate); 1313 Isolate* isolate = frame_entry<Isolate*>(re_frame, kIsolate);
1316 if (isolate->stack_guard()->IsStackOverflow()) { 1314 if (isolate->stack_guard()->IsStackOverflow()) {
1317 isolate->StackOverflow(); 1315 isolate->StackOverflow();
1318 return EXCEPTION; 1316 return EXCEPTION;
1319 } 1317 }
(...skipping 79 matching lines...) Expand 10 before | Expand all | Expand 10 after
1399 // Subject string might have been a ConsString that underwent 1397 // Subject string might have been a ConsString that underwent
1400 // short-circuiting during GC. That will not change start_address but 1398 // short-circuiting during GC. That will not change start_address but
1401 // will change pointer inside the subject handle. 1399 // will change pointer inside the subject handle.
1402 frame_entry<const String*>(re_frame, kInput) = *subject; 1400 frame_entry<const String*>(re_frame, kInput) = *subject;
1403 } 1401 }
1404 1402
1405 return 0; 1403 return 0;
1406 } 1404 }
1407 1405
1408 1406
1409 void RegExpMacroAssemblerA64::CheckPosition(int cp_offset, 1407 void RegExpMacroAssemblerARM64::CheckPosition(int cp_offset,
1410 Label* on_outside_input) { 1408 Label* on_outside_input) {
1411 CompareAndBranchOrBacktrack(current_input_offset(), 1409 CompareAndBranchOrBacktrack(current_input_offset(),
1412 -cp_offset * char_size(), 1410 -cp_offset * char_size(),
1413 ge, 1411 ge,
1414 on_outside_input); 1412 on_outside_input);
1415 } 1413 }
1416 1414
1417 1415
1418 bool RegExpMacroAssemblerA64::CanReadUnaligned() { 1416 bool RegExpMacroAssemblerARM64::CanReadUnaligned() {
1419 // TODO(pielan): See whether or not we should disable unaligned accesses. 1417 // TODO(pielan): See whether or not we should disable unaligned accesses.
1420 return !slow_safe(); 1418 return !slow_safe();
1421 } 1419 }
1422 1420
1423 1421
1424 // Private methods: 1422 // Private methods:
1425 1423
1426 void RegExpMacroAssemblerA64::CallCheckStackGuardState(Register scratch) { 1424 void RegExpMacroAssemblerARM64::CallCheckStackGuardState(Register scratch) {
1427 // Allocate space on the stack to store the return address. The 1425 // Allocate space on the stack to store the return address. The
1428 // CheckStackGuardState C++ function will override it if the code 1426 // CheckStackGuardState C++ function will override it if the code
1429 // moved. Allocate extra space for 2 arguments passed by pointers. 1427 // moved. Allocate extra space for 2 arguments passed by pointers.
1430 // AAPCS64 requires the stack to be 16 byte aligned. 1428 // AAPCS64 requires the stack to be 16 byte aligned.
1431 int alignment = masm_->ActivationFrameAlignment(); 1429 int alignment = masm_->ActivationFrameAlignment();
1432 ASSERT_EQ(alignment % 16, 0); 1430 ASSERT_EQ(alignment % 16, 0);
1433 int align_mask = (alignment / kXRegSize) - 1; 1431 int align_mask = (alignment / kXRegSize) - 1;
1434 int xreg_to_claim = (3 + align_mask) & ~align_mask; 1432 int xreg_to_claim = (3 + align_mask) & ~align_mask;
1435 1433
1436 ASSERT(csp.Is(__ StackPointer())); 1434 ASSERT(csp.Is(__ StackPointer()));
(...skipping 26 matching lines...) Expand all
1463 __ Peek(input_start(), kPointerSize); 1461 __ Peek(input_start(), kPointerSize);
1464 __ Peek(input_end(), 2 * kPointerSize); 1462 __ Peek(input_end(), 2 * kPointerSize);
1465 1463
1466 ASSERT(csp.Is(__ StackPointer())); 1464 ASSERT(csp.Is(__ StackPointer()));
1467 __ Drop(xreg_to_claim); 1465 __ Drop(xreg_to_claim);
1468 1466
1469 // Reload the Code pointer. 1467 // Reload the Code pointer.
1470 __ Mov(code_pointer(), Operand(masm_->CodeObject())); 1468 __ Mov(code_pointer(), Operand(masm_->CodeObject()));
1471 } 1469 }
1472 1470
1473 void RegExpMacroAssemblerA64::BranchOrBacktrack(Condition condition, 1471 void RegExpMacroAssemblerARM64::BranchOrBacktrack(Condition condition,
1474 Label* to) { 1472 Label* to) {
1475 if (condition == al) { // Unconditional. 1473 if (condition == al) { // Unconditional.
1476 if (to == NULL) { 1474 if (to == NULL) {
1477 Backtrack(); 1475 Backtrack();
1478 return; 1476 return;
1479 } 1477 }
1480 __ B(to); 1478 __ B(to);
1481 return; 1479 return;
1482 } 1480 }
1483 if (to == NULL) { 1481 if (to == NULL) {
1484 to = &backtrack_label_; 1482 to = &backtrack_label_;
1485 } 1483 }
1486 // TODO(ulan): do direct jump when jump distance is known and fits in imm19. 1484 // TODO(ulan): do direct jump when jump distance is known and fits in imm19.
1487 Condition inverted_condition = InvertCondition(condition); 1485 Condition inverted_condition = InvertCondition(condition);
1488 Label no_branch; 1486 Label no_branch;
1489 __ B(inverted_condition, &no_branch); 1487 __ B(inverted_condition, &no_branch);
1490 __ B(to); 1488 __ B(to);
1491 __ Bind(&no_branch); 1489 __ Bind(&no_branch);
1492 } 1490 }
1493 1491
1494 void RegExpMacroAssemblerA64::CompareAndBranchOrBacktrack(Register reg, 1492 void RegExpMacroAssemblerARM64::CompareAndBranchOrBacktrack(Register reg,
1495 int immediate, 1493 int immediate,
1496 Condition condition, 1494 Condition condition,
1497 Label* to) { 1495 Label* to) {
1498 if ((immediate == 0) && ((condition == eq) || (condition == ne))) { 1496 if ((immediate == 0) && ((condition == eq) || (condition == ne))) {
1499 if (to == NULL) { 1497 if (to == NULL) {
1500 to = &backtrack_label_; 1498 to = &backtrack_label_;
1501 } 1499 }
1502 // TODO(ulan): do direct jump when jump distance is known and fits in imm19. 1500 // TODO(ulan): do direct jump when jump distance is known and fits in imm19.
1503 Label no_branch; 1501 Label no_branch;
1504 if (condition == eq) { 1502 if (condition == eq) {
1505 __ Cbnz(reg, &no_branch); 1503 __ Cbnz(reg, &no_branch);
1506 } else { 1504 } else {
1507 __ Cbz(reg, &no_branch); 1505 __ Cbz(reg, &no_branch);
1508 } 1506 }
1509 __ B(to); 1507 __ B(to);
1510 __ Bind(&no_branch); 1508 __ Bind(&no_branch);
1511 } else { 1509 } else {
1512 __ Cmp(reg, immediate); 1510 __ Cmp(reg, immediate);
1513 BranchOrBacktrack(condition, to); 1511 BranchOrBacktrack(condition, to);
1514 } 1512 }
1515 } 1513 }
1516 1514
1517 1515
1518 void RegExpMacroAssemblerA64::CheckPreemption() { 1516 void RegExpMacroAssemblerARM64::CheckPreemption() {
1519 // Check for preemption. 1517 // Check for preemption.
1520 ExternalReference stack_limit = 1518 ExternalReference stack_limit =
1521 ExternalReference::address_of_stack_limit(isolate()); 1519 ExternalReference::address_of_stack_limit(isolate());
1522 __ Mov(x10, stack_limit); 1520 __ Mov(x10, stack_limit);
1523 __ Ldr(x10, MemOperand(x10)); 1521 __ Ldr(x10, MemOperand(x10));
1524 ASSERT(csp.Is(__ StackPointer())); 1522 ASSERT(csp.Is(__ StackPointer()));
1525 __ Cmp(csp, x10); 1523 __ Cmp(csp, x10);
1526 CallIf(&check_preempt_label_, ls); 1524 CallIf(&check_preempt_label_, ls);
1527 } 1525 }
1528 1526
1529 1527
1530 void RegExpMacroAssemblerA64::CheckStackLimit() { 1528 void RegExpMacroAssemblerARM64::CheckStackLimit() {
1531 ExternalReference stack_limit = 1529 ExternalReference stack_limit =
1532 ExternalReference::address_of_regexp_stack_limit(isolate()); 1530 ExternalReference::address_of_regexp_stack_limit(isolate());
1533 __ Mov(x10, stack_limit); 1531 __ Mov(x10, stack_limit);
1534 __ Ldr(x10, MemOperand(x10)); 1532 __ Ldr(x10, MemOperand(x10));
1535 __ Cmp(backtrack_stackpointer(), x10); 1533 __ Cmp(backtrack_stackpointer(), x10);
1536 CallIf(&stack_overflow_label_, ls); 1534 CallIf(&stack_overflow_label_, ls);
1537 } 1535 }
1538 1536
1539 1537
1540 void RegExpMacroAssemblerA64::Push(Register source) { 1538 void RegExpMacroAssemblerARM64::Push(Register source) {
1541 ASSERT(source.Is32Bits()); 1539 ASSERT(source.Is32Bits());
1542 ASSERT(!source.is(backtrack_stackpointer())); 1540 ASSERT(!source.is(backtrack_stackpointer()));
1543 __ Str(source, 1541 __ Str(source,
1544 MemOperand(backtrack_stackpointer(), 1542 MemOperand(backtrack_stackpointer(),
1545 -static_cast<int>(kWRegSize), 1543 -static_cast<int>(kWRegSize),
1546 PreIndex)); 1544 PreIndex));
1547 } 1545 }
1548 1546
1549 1547
1550 void RegExpMacroAssemblerA64::Pop(Register target) { 1548 void RegExpMacroAssemblerARM64::Pop(Register target) {
1551 ASSERT(target.Is32Bits()); 1549 ASSERT(target.Is32Bits());
1552 ASSERT(!target.is(backtrack_stackpointer())); 1550 ASSERT(!target.is(backtrack_stackpointer()));
1553 __ Ldr(target, 1551 __ Ldr(target,
1554 MemOperand(backtrack_stackpointer(), kWRegSize, PostIndex)); 1552 MemOperand(backtrack_stackpointer(), kWRegSize, PostIndex));
1555 } 1553 }
1556 1554
1557 1555
1558 Register RegExpMacroAssemblerA64::GetCachedRegister(int register_index) { 1556 Register RegExpMacroAssemblerARM64::GetCachedRegister(int register_index) {
1559 ASSERT(register_index < kNumCachedRegisters); 1557 ASSERT(register_index < kNumCachedRegisters);
1560 return Register::Create(register_index / 2, kXRegSizeInBits); 1558 return Register::Create(register_index / 2, kXRegSizeInBits);
1561 } 1559 }
1562 1560
1563 1561
1564 Register RegExpMacroAssemblerA64::GetRegister(int register_index, 1562 Register RegExpMacroAssemblerARM64::GetRegister(int register_index,
1565 Register maybe_result) { 1563 Register maybe_result) {
1566 ASSERT(maybe_result.Is32Bits()); 1564 ASSERT(maybe_result.Is32Bits());
1567 ASSERT(register_index >= 0); 1565 ASSERT(register_index >= 0);
1568 if (num_registers_ <= register_index) { 1566 if (num_registers_ <= register_index) {
1569 num_registers_ = register_index + 1; 1567 num_registers_ = register_index + 1;
1570 } 1568 }
1571 Register result; 1569 Register result;
1572 RegisterState register_state = GetRegisterState(register_index); 1570 RegisterState register_state = GetRegisterState(register_index);
1573 switch (register_state) { 1571 switch (register_state) {
1574 case STACKED: 1572 case STACKED:
1575 __ Ldr(maybe_result, register_location(register_index)); 1573 __ Ldr(maybe_result, register_location(register_index));
1576 result = maybe_result; 1574 result = maybe_result;
1577 break; 1575 break;
1578 case CACHED_LSW: 1576 case CACHED_LSW:
1579 result = GetCachedRegister(register_index).W(); 1577 result = GetCachedRegister(register_index).W();
1580 break; 1578 break;
1581 case CACHED_MSW: 1579 case CACHED_MSW:
1582 __ Lsr(maybe_result.X(), GetCachedRegister(register_index), 1580 __ Lsr(maybe_result.X(), GetCachedRegister(register_index),
1583 kWRegSizeInBits); 1581 kWRegSizeInBits);
1584 result = maybe_result; 1582 result = maybe_result;
1585 break; 1583 break;
1586 default: 1584 default:
1587 UNREACHABLE(); 1585 UNREACHABLE();
1588 break; 1586 break;
1589 } 1587 }
1590 ASSERT(result.Is32Bits()); 1588 ASSERT(result.Is32Bits());
1591 return result; 1589 return result;
1592 } 1590 }
1593 1591
1594 1592
1595 void RegExpMacroAssemblerA64::StoreRegister(int register_index, 1593 void RegExpMacroAssemblerARM64::StoreRegister(int register_index,
1596 Register source) { 1594 Register source) {
1597 ASSERT(source.Is32Bits()); 1595 ASSERT(source.Is32Bits());
1598 ASSERT(register_index >= 0); 1596 ASSERT(register_index >= 0);
1599 if (num_registers_ <= register_index) { 1597 if (num_registers_ <= register_index) {
1600 num_registers_ = register_index + 1; 1598 num_registers_ = register_index + 1;
1601 } 1599 }
1602 1600
1603 Register cached_register; 1601 Register cached_register;
1604 RegisterState register_state = GetRegisterState(register_index); 1602 RegisterState register_state = GetRegisterState(register_index);
1605 switch (register_state) { 1603 switch (register_state) {
1606 case STACKED: 1604 case STACKED:
1607 __ Str(source, register_location(register_index)); 1605 __ Str(source, register_location(register_index));
1608 break; 1606 break;
1609 case CACHED_LSW: 1607 case CACHED_LSW:
1610 cached_register = GetCachedRegister(register_index); 1608 cached_register = GetCachedRegister(register_index);
1611 if (!source.Is(cached_register.W())) { 1609 if (!source.Is(cached_register.W())) {
1612 __ Bfi(cached_register, source.X(), 0, kWRegSizeInBits); 1610 __ Bfi(cached_register, source.X(), 0, kWRegSizeInBits);
1613 } 1611 }
1614 break; 1612 break;
1615 case CACHED_MSW: 1613 case CACHED_MSW:
1616 cached_register = GetCachedRegister(register_index); 1614 cached_register = GetCachedRegister(register_index);
1617 __ Bfi(cached_register, source.X(), kWRegSizeInBits, kWRegSizeInBits); 1615 __ Bfi(cached_register, source.X(), kWRegSizeInBits, kWRegSizeInBits);
1618 break; 1616 break;
1619 default: 1617 default:
1620 UNREACHABLE(); 1618 UNREACHABLE();
1621 break; 1619 break;
1622 } 1620 }
1623 } 1621 }
1624 1622
1625 1623
1626 void RegExpMacroAssemblerA64::CallIf(Label* to, Condition condition) { 1624 void RegExpMacroAssemblerARM64::CallIf(Label* to, Condition condition) {
1627 Label skip_call; 1625 Label skip_call;
1628 if (condition != al) __ B(&skip_call, InvertCondition(condition)); 1626 if (condition != al) __ B(&skip_call, InvertCondition(condition));
1629 __ Bl(to); 1627 __ Bl(to);
1630 __ Bind(&skip_call); 1628 __ Bind(&skip_call);
1631 } 1629 }
1632 1630
1633 1631
1634 void RegExpMacroAssemblerA64::RestoreLinkRegister() { 1632 void RegExpMacroAssemblerARM64::RestoreLinkRegister() {
1635 ASSERT(csp.Is(__ StackPointer())); 1633 ASSERT(csp.Is(__ StackPointer()));
1636 __ Pop(lr, xzr); 1634 __ Pop(lr, xzr);
1637 __ Add(lr, lr, Operand(masm_->CodeObject())); 1635 __ Add(lr, lr, Operand(masm_->CodeObject()));
1638 } 1636 }
1639 1637
1640 1638
1641 void RegExpMacroAssemblerA64::SaveLinkRegister() { 1639 void RegExpMacroAssemblerARM64::SaveLinkRegister() {
1642 ASSERT(csp.Is(__ StackPointer())); 1640 ASSERT(csp.Is(__ StackPointer()));
1643 __ Sub(lr, lr, Operand(masm_->CodeObject())); 1641 __ Sub(lr, lr, Operand(masm_->CodeObject()));
1644 __ Push(xzr, lr); 1642 __ Push(xzr, lr);
1645 } 1643 }
1646 1644
1647 1645
1648 MemOperand RegExpMacroAssemblerA64::register_location(int register_index) { 1646 MemOperand RegExpMacroAssemblerARM64::register_location(int register_index) {
1649 ASSERT(register_index < (1<<30)); 1647 ASSERT(register_index < (1<<30));
1650 ASSERT(register_index >= kNumCachedRegisters); 1648 ASSERT(register_index >= kNumCachedRegisters);
1651 if (num_registers_ <= register_index) { 1649 if (num_registers_ <= register_index) {
1652 num_registers_ = register_index + 1; 1650 num_registers_ = register_index + 1;
1653 } 1651 }
1654 register_index -= kNumCachedRegisters; 1652 register_index -= kNumCachedRegisters;
1655 int offset = kFirstRegisterOnStack - register_index * kWRegSize; 1653 int offset = kFirstRegisterOnStack - register_index * kWRegSize;
1656 return MemOperand(frame_pointer(), offset); 1654 return MemOperand(frame_pointer(), offset);
1657 } 1655 }
1658 1656
1659 MemOperand RegExpMacroAssemblerA64::capture_location(int register_index, 1657 MemOperand RegExpMacroAssemblerARM64::capture_location(int register_index,
1660 Register scratch) { 1658 Register scratch) {
1661 ASSERT(register_index < (1<<30)); 1659 ASSERT(register_index < (1<<30));
1662 ASSERT(register_index < num_saved_registers_); 1660 ASSERT(register_index < num_saved_registers_);
1663 ASSERT(register_index >= kNumCachedRegisters); 1661 ASSERT(register_index >= kNumCachedRegisters);
1664 ASSERT_EQ(register_index % 2, 0); 1662 ASSERT_EQ(register_index % 2, 0);
1665 register_index -= kNumCachedRegisters; 1663 register_index -= kNumCachedRegisters;
1666 int offset = kFirstCaptureOnStack - register_index * kWRegSize; 1664 int offset = kFirstCaptureOnStack - register_index * kWRegSize;
1667 // capture_location is used with Stp instructions to load/store 2 registers. 1665 // capture_location is used with Stp instructions to load/store 2 registers.
1668 // The immediate field in the encoding is limited to 7 bits (signed). 1666 // The immediate field in the encoding is limited to 7 bits (signed).
1669 if (is_int7(offset)) { 1667 if (is_int7(offset)) {
1670 return MemOperand(frame_pointer(), offset); 1668 return MemOperand(frame_pointer(), offset);
1671 } else { 1669 } else {
1672 __ Add(scratch, frame_pointer(), offset); 1670 __ Add(scratch, frame_pointer(), offset);
1673 return MemOperand(scratch); 1671 return MemOperand(scratch);
1674 } 1672 }
1675 } 1673 }
1676 1674
1677 void RegExpMacroAssemblerA64::LoadCurrentCharacterUnchecked(int cp_offset, 1675 void RegExpMacroAssemblerARM64::LoadCurrentCharacterUnchecked(int cp_offset,
1678 int characters) { 1676 int characters) {
1679 Register offset = current_input_offset(); 1677 Register offset = current_input_offset();
1680 1678
1681 // The ldr, str, ldrh, strh instructions can do unaligned accesses, if the CPU 1679 // The ldr, str, ldrh, strh instructions can do unaligned accesses, if the CPU
1682 // and the operating system running on the target allow it. 1680 // and the operating system running on the target allow it.
1683 // If unaligned load/stores are not supported then this function must only 1681 // If unaligned load/stores are not supported then this function must only
1684 // be used to load a single character at a time. 1682 // be used to load a single character at a time.
1685 1683
1686 // ARMv8 supports unaligned accesses but V8 or the kernel can decide to 1684 // ARMv8 supports unaligned accesses but V8 or the kernel can decide to
1687 // disable it. 1685 // disable it.
1688 // TODO(pielan): See whether or not we should disable unaligned accesses. 1686 // TODO(pielan): See whether or not we should disable unaligned accesses.
(...skipping 31 matching lines...) Expand 10 before | Expand all | Expand 10 after
1720 ASSERT(characters == 1); 1718 ASSERT(characters == 1);
1721 __ Ldrh(current_character(), MemOperand(input_end(), offset, SXTW)); 1719 __ Ldrh(current_character(), MemOperand(input_end(), offset, SXTW));
1722 } 1720 }
1723 } 1721 }
1724 } 1722 }
1725 1723
1726 #endif // V8_INTERPRETED_REGEXP 1724 #endif // V8_INTERPRETED_REGEXP
1727 1725
1728 }} // namespace v8::internal 1726 }} // namespace v8::internal
1729 1727
1730 #endif // V8_TARGET_ARCH_A64 1728 #endif // V8_TARGET_ARCH_ARM64
OLDNEW
« no previous file with comments | « src/arm64/regexp-macro-assembler-arm64.h ('k') | src/arm64/simulator-arm64.h » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698