OLD | NEW |
1 // Copyright 2012 the V8 project authors. All rights reserved. | 1 // Copyright 2012 the V8 project authors. All rights reserved. |
2 // Use of this source code is governed by a BSD-style license that can be | 2 // Use of this source code is governed by a BSD-style license that can be |
3 // found in the LICENSE file. | 3 // found in the LICENSE file. |
4 | 4 |
5 #if V8_TARGET_ARCH_MIPS64 | 5 #if V8_TARGET_ARCH_MIPS64 |
6 | 6 |
7 #include "src/regexp/mips64/regexp-macro-assembler-mips64.h" | 7 #include "src/regexp/mips64/regexp-macro-assembler-mips64.h" |
8 | 8 |
9 #include "src/code-stubs.h" | 9 #include "src/code-stubs.h" |
10 #include "src/log.h" | 10 #include "src/log.h" |
(...skipping 168 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
179 __ Daddu(current_input_offset(), | 179 __ Daddu(current_input_offset(), |
180 current_input_offset(), Operand(by * char_size())); | 180 current_input_offset(), Operand(by * char_size())); |
181 } | 181 } |
182 } | 182 } |
183 | 183 |
184 | 184 |
185 void RegExpMacroAssemblerMIPS::AdvanceRegister(int reg, int by) { | 185 void RegExpMacroAssemblerMIPS::AdvanceRegister(int reg, int by) { |
186 DCHECK(reg >= 0); | 186 DCHECK(reg >= 0); |
187 DCHECK(reg < num_registers_); | 187 DCHECK(reg < num_registers_); |
188 if (by != 0) { | 188 if (by != 0) { |
189 __ ld(a0, register_location(reg)); | 189 __ Ld(a0, register_location(reg)); |
190 __ Daddu(a0, a0, Operand(by)); | 190 __ Daddu(a0, a0, Operand(by)); |
191 __ sd(a0, register_location(reg)); | 191 __ Sd(a0, register_location(reg)); |
192 } | 192 } |
193 } | 193 } |
194 | 194 |
195 | 195 |
196 void RegExpMacroAssemblerMIPS::Backtrack() { | 196 void RegExpMacroAssemblerMIPS::Backtrack() { |
197 CheckPreemption(); | 197 CheckPreemption(); |
198 // Pop Code* offset from backtrack stack, add Code* and jump to location. | 198 // Pop Code* offset from backtrack stack, add Code* and jump to location. |
199 Pop(a0); | 199 Pop(a0); |
200 __ Daddu(a0, a0, code_pointer()); | 200 __ Daddu(a0, a0, code_pointer()); |
201 __ Jump(a0); | 201 __ Jump(a0); |
202 } | 202 } |
203 | 203 |
204 | 204 |
205 void RegExpMacroAssemblerMIPS::Bind(Label* label) { | 205 void RegExpMacroAssemblerMIPS::Bind(Label* label) { |
206 __ bind(label); | 206 __ bind(label); |
207 } | 207 } |
208 | 208 |
209 | 209 |
210 void RegExpMacroAssemblerMIPS::CheckCharacter(uint32_t c, Label* on_equal) { | 210 void RegExpMacroAssemblerMIPS::CheckCharacter(uint32_t c, Label* on_equal) { |
211 BranchOrBacktrack(on_equal, eq, current_character(), Operand(c)); | 211 BranchOrBacktrack(on_equal, eq, current_character(), Operand(c)); |
212 } | 212 } |
213 | 213 |
214 | 214 |
215 void RegExpMacroAssemblerMIPS::CheckCharacterGT(uc16 limit, Label* on_greater) { | 215 void RegExpMacroAssemblerMIPS::CheckCharacterGT(uc16 limit, Label* on_greater) { |
216 BranchOrBacktrack(on_greater, gt, current_character(), Operand(limit)); | 216 BranchOrBacktrack(on_greater, gt, current_character(), Operand(limit)); |
217 } | 217 } |
218 | 218 |
219 | 219 |
220 void RegExpMacroAssemblerMIPS::CheckAtStart(Label* on_at_start) { | 220 void RegExpMacroAssemblerMIPS::CheckAtStart(Label* on_at_start) { |
221 __ ld(a1, MemOperand(frame_pointer(), kStringStartMinusOne)); | 221 __ Ld(a1, MemOperand(frame_pointer(), kStringStartMinusOne)); |
222 __ Daddu(a0, current_input_offset(), Operand(-char_size())); | 222 __ Daddu(a0, current_input_offset(), Operand(-char_size())); |
223 BranchOrBacktrack(on_at_start, eq, a0, Operand(a1)); | 223 BranchOrBacktrack(on_at_start, eq, a0, Operand(a1)); |
224 } | 224 } |
225 | 225 |
226 | 226 |
227 void RegExpMacroAssemblerMIPS::CheckNotAtStart(int cp_offset, | 227 void RegExpMacroAssemblerMIPS::CheckNotAtStart(int cp_offset, |
228 Label* on_not_at_start) { | 228 Label* on_not_at_start) { |
229 __ ld(a1, MemOperand(frame_pointer(), kStringStartMinusOne)); | 229 __ Ld(a1, MemOperand(frame_pointer(), kStringStartMinusOne)); |
230 __ Daddu(a0, current_input_offset(), | 230 __ Daddu(a0, current_input_offset(), |
231 Operand(-char_size() + cp_offset * char_size())); | 231 Operand(-char_size() + cp_offset * char_size())); |
232 BranchOrBacktrack(on_not_at_start, ne, a0, Operand(a1)); | 232 BranchOrBacktrack(on_not_at_start, ne, a0, Operand(a1)); |
233 } | 233 } |
234 | 234 |
235 | 235 |
236 void RegExpMacroAssemblerMIPS::CheckCharacterLT(uc16 limit, Label* on_less) { | 236 void RegExpMacroAssemblerMIPS::CheckCharacterLT(uc16 limit, Label* on_less) { |
237 BranchOrBacktrack(on_less, lt, current_character(), Operand(limit)); | 237 BranchOrBacktrack(on_less, lt, current_character(), Operand(limit)); |
238 } | 238 } |
239 | 239 |
240 | 240 |
241 void RegExpMacroAssemblerMIPS::CheckGreedyLoop(Label* on_equal) { | 241 void RegExpMacroAssemblerMIPS::CheckGreedyLoop(Label* on_equal) { |
242 Label backtrack_non_equal; | 242 Label backtrack_non_equal; |
243 __ lw(a0, MemOperand(backtrack_stackpointer(), 0)); | 243 __ Lw(a0, MemOperand(backtrack_stackpointer(), 0)); |
244 __ Branch(&backtrack_non_equal, ne, current_input_offset(), Operand(a0)); | 244 __ Branch(&backtrack_non_equal, ne, current_input_offset(), Operand(a0)); |
245 __ Daddu(backtrack_stackpointer(), | 245 __ Daddu(backtrack_stackpointer(), |
246 backtrack_stackpointer(), | 246 backtrack_stackpointer(), |
247 Operand(kIntSize)); | 247 Operand(kIntSize)); |
248 __ bind(&backtrack_non_equal); | 248 __ bind(&backtrack_non_equal); |
249 BranchOrBacktrack(on_equal, eq, current_input_offset(), Operand(a0)); | 249 BranchOrBacktrack(on_equal, eq, current_input_offset(), Operand(a0)); |
250 } | 250 } |
251 | 251 |
252 | 252 |
253 void RegExpMacroAssemblerMIPS::CheckNotBackReferenceIgnoreCase( | 253 void RegExpMacroAssemblerMIPS::CheckNotBackReferenceIgnoreCase( |
254 int start_reg, bool read_backward, bool unicode, Label* on_no_match) { | 254 int start_reg, bool read_backward, bool unicode, Label* on_no_match) { |
255 Label fallthrough; | 255 Label fallthrough; |
256 __ ld(a0, register_location(start_reg)); // Index of start of capture. | 256 __ Ld(a0, register_location(start_reg)); // Index of start of capture. |
257 __ ld(a1, register_location(start_reg + 1)); // Index of end of capture. | 257 __ Ld(a1, register_location(start_reg + 1)); // Index of end of capture. |
258 __ Dsubu(a1, a1, a0); // Length of capture. | 258 __ Dsubu(a1, a1, a0); // Length of capture. |
259 | 259 |
260 // At this point, the capture registers are either both set or both cleared. | 260 // At this point, the capture registers are either both set or both cleared. |
261 // If the capture length is zero, then the capture is either empty or cleared. | 261 // If the capture length is zero, then the capture is either empty or cleared. |
262 // Fall through in both cases. | 262 // Fall through in both cases. |
263 __ Branch(&fallthrough, eq, a1, Operand(zero_reg)); | 263 __ Branch(&fallthrough, eq, a1, Operand(zero_reg)); |
264 | 264 |
265 if (read_backward) { | 265 if (read_backward) { |
266 __ ld(t1, MemOperand(frame_pointer(), kStringStartMinusOne)); | 266 __ Ld(t1, MemOperand(frame_pointer(), kStringStartMinusOne)); |
267 __ Daddu(t1, t1, a1); | 267 __ Daddu(t1, t1, a1); |
268 BranchOrBacktrack(on_no_match, le, current_input_offset(), Operand(t1)); | 268 BranchOrBacktrack(on_no_match, le, current_input_offset(), Operand(t1)); |
269 } else { | 269 } else { |
270 __ Daddu(t1, a1, current_input_offset()); | 270 __ Daddu(t1, a1, current_input_offset()); |
271 // Check that there are enough characters left in the input. | 271 // Check that there are enough characters left in the input. |
272 BranchOrBacktrack(on_no_match, gt, t1, Operand(zero_reg)); | 272 BranchOrBacktrack(on_no_match, gt, t1, Operand(zero_reg)); |
273 } | 273 } |
274 | 274 |
275 if (mode_ == LATIN1) { | 275 if (mode_ == LATIN1) { |
276 Label success; | 276 Label success; |
277 Label fail; | 277 Label fail; |
278 Label loop_check; | 278 Label loop_check; |
279 | 279 |
280 // a0 - offset of start of capture. | 280 // a0 - offset of start of capture. |
281 // a1 - length of capture. | 281 // a1 - length of capture. |
282 __ Daddu(a0, a0, Operand(end_of_input_address())); | 282 __ Daddu(a0, a0, Operand(end_of_input_address())); |
283 __ Daddu(a2, end_of_input_address(), Operand(current_input_offset())); | 283 __ Daddu(a2, end_of_input_address(), Operand(current_input_offset())); |
284 if (read_backward) { | 284 if (read_backward) { |
285 __ Dsubu(a2, a2, Operand(a1)); | 285 __ Dsubu(a2, a2, Operand(a1)); |
286 } | 286 } |
287 __ Daddu(a1, a0, Operand(a1)); | 287 __ Daddu(a1, a0, Operand(a1)); |
288 | 288 |
289 // a0 - Address of start of capture. | 289 // a0 - Address of start of capture. |
290 // a1 - Address of end of capture. | 290 // a1 - Address of end of capture. |
291 // a2 - Address of current input position. | 291 // a2 - Address of current input position. |
292 | 292 |
293 Label loop; | 293 Label loop; |
294 __ bind(&loop); | 294 __ bind(&loop); |
295 __ lbu(a3, MemOperand(a0, 0)); | 295 __ Lbu(a3, MemOperand(a0, 0)); |
296 __ daddiu(a0, a0, char_size()); | 296 __ daddiu(a0, a0, char_size()); |
297 __ lbu(a4, MemOperand(a2, 0)); | 297 __ Lbu(a4, MemOperand(a2, 0)); |
298 __ daddiu(a2, a2, char_size()); | 298 __ daddiu(a2, a2, char_size()); |
299 | 299 |
300 __ Branch(&loop_check, eq, a4, Operand(a3)); | 300 __ Branch(&loop_check, eq, a4, Operand(a3)); |
301 | 301 |
302 // Mismatch, try case-insensitive match (converting letters to lower-case). | 302 // Mismatch, try case-insensitive match (converting letters to lower-case). |
303 __ Or(a3, a3, Operand(0x20)); // Convert capture character to lower-case. | 303 __ Or(a3, a3, Operand(0x20)); // Convert capture character to lower-case. |
304 __ Or(a4, a4, Operand(0x20)); // Also convert input character. | 304 __ Or(a4, a4, Operand(0x20)); // Also convert input character. |
305 __ Branch(&fail, ne, a4, Operand(a3)); | 305 __ Branch(&fail, ne, a4, Operand(a3)); |
306 __ Dsubu(a3, a3, Operand('a')); | 306 __ Dsubu(a3, a3, Operand('a')); |
307 __ Branch(&loop_check, ls, a3, Operand('z' - 'a')); | 307 __ Branch(&loop_check, ls, a3, Operand('z' - 'a')); |
308 // Latin-1: Check for values in range [224,254] but not 247. | 308 // Latin-1: Check for values in range [224,254] but not 247. |
309 __ Dsubu(a3, a3, Operand(224 - 'a')); | 309 __ Dsubu(a3, a3, Operand(224 - 'a')); |
310 // Weren't Latin-1 letters. | 310 // Weren't Latin-1 letters. |
311 __ Branch(&fail, hi, a3, Operand(254 - 224)); | 311 __ Branch(&fail, hi, a3, Operand(254 - 224)); |
312 // Check for 247. | 312 // Check for 247. |
313 __ Branch(&fail, eq, a3, Operand(247 - 224)); | 313 __ Branch(&fail, eq, a3, Operand(247 - 224)); |
314 | 314 |
315 __ bind(&loop_check); | 315 __ bind(&loop_check); |
316 __ Branch(&loop, lt, a0, Operand(a1)); | 316 __ Branch(&loop, lt, a0, Operand(a1)); |
317 __ jmp(&success); | 317 __ jmp(&success); |
318 | 318 |
319 __ bind(&fail); | 319 __ bind(&fail); |
320 GoTo(on_no_match); | 320 GoTo(on_no_match); |
321 | 321 |
322 __ bind(&success); | 322 __ bind(&success); |
323 // Compute new value of character position after the matched part. | 323 // Compute new value of character position after the matched part. |
324 __ Dsubu(current_input_offset(), a2, end_of_input_address()); | 324 __ Dsubu(current_input_offset(), a2, end_of_input_address()); |
325 if (read_backward) { | 325 if (read_backward) { |
326 __ ld(t1, register_location(start_reg)); // Index of start of capture. | 326 __ Ld(t1, register_location(start_reg)); // Index of start of capture. |
327 __ ld(a2, register_location(start_reg + 1)); // Index of end of capture. | 327 __ Ld(a2, register_location(start_reg + 1)); // Index of end of capture. |
328 __ Daddu(current_input_offset(), current_input_offset(), Operand(t1)); | 328 __ Daddu(current_input_offset(), current_input_offset(), Operand(t1)); |
329 __ Dsubu(current_input_offset(), current_input_offset(), Operand(a2)); | 329 __ Dsubu(current_input_offset(), current_input_offset(), Operand(a2)); |
330 } | 330 } |
331 } else { | 331 } else { |
332 DCHECK(mode_ == UC16); | 332 DCHECK(mode_ == UC16); |
333 // Put regexp engine registers on stack. | 333 // Put regexp engine registers on stack. |
334 RegList regexp_registers_to_retain = current_input_offset().bit() | | 334 RegList regexp_registers_to_retain = current_input_offset().bit() | |
335 current_character().bit() | backtrack_stackpointer().bit(); | 335 current_character().bit() | backtrack_stackpointer().bit(); |
336 __ MultiPush(regexp_registers_to_retain); | 336 __ MultiPush(regexp_registers_to_retain); |
337 | 337 |
(...skipping 34 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
372 { | 372 { |
373 AllowExternalCallThatCantCauseGC scope(masm_); | 373 AllowExternalCallThatCantCauseGC scope(masm_); |
374 ExternalReference function = | 374 ExternalReference function = |
375 ExternalReference::re_case_insensitive_compare_uc16(masm_->isolate()); | 375 ExternalReference::re_case_insensitive_compare_uc16(masm_->isolate()); |
376 __ CallCFunction(function, argument_count); | 376 __ CallCFunction(function, argument_count); |
377 } | 377 } |
378 | 378 |
379 // Restore regexp engine registers. | 379 // Restore regexp engine registers. |
380 __ MultiPop(regexp_registers_to_retain); | 380 __ MultiPop(regexp_registers_to_retain); |
381 __ li(code_pointer(), Operand(masm_->CodeObject()), CONSTANT_SIZE); | 381 __ li(code_pointer(), Operand(masm_->CodeObject()), CONSTANT_SIZE); |
382 __ ld(end_of_input_address(), MemOperand(frame_pointer(), kInputEnd)); | 382 __ Ld(end_of_input_address(), MemOperand(frame_pointer(), kInputEnd)); |
383 | 383 |
384 // Check if function returned non-zero for success or zero for failure. | 384 // Check if function returned non-zero for success or zero for failure. |
385 BranchOrBacktrack(on_no_match, eq, v0, Operand(zero_reg)); | 385 BranchOrBacktrack(on_no_match, eq, v0, Operand(zero_reg)); |
386 // On success, increment position by length of capture. | 386 // On success, increment position by length of capture. |
387 if (read_backward) { | 387 if (read_backward) { |
388 __ Dsubu(current_input_offset(), current_input_offset(), Operand(s3)); | 388 __ Dsubu(current_input_offset(), current_input_offset(), Operand(s3)); |
389 } else { | 389 } else { |
390 __ Daddu(current_input_offset(), current_input_offset(), Operand(s3)); | 390 __ Daddu(current_input_offset(), current_input_offset(), Operand(s3)); |
391 } | 391 } |
392 } | 392 } |
393 | 393 |
394 __ bind(&fallthrough); | 394 __ bind(&fallthrough); |
395 } | 395 } |
396 | 396 |
397 | 397 |
398 void RegExpMacroAssemblerMIPS::CheckNotBackReference(int start_reg, | 398 void RegExpMacroAssemblerMIPS::CheckNotBackReference(int start_reg, |
399 bool read_backward, | 399 bool read_backward, |
400 Label* on_no_match) { | 400 Label* on_no_match) { |
401 Label fallthrough; | 401 Label fallthrough; |
402 Label success; | 402 Label success; |
403 | 403 |
404 // Find length of back-referenced capture. | 404 // Find length of back-referenced capture. |
405 __ ld(a0, register_location(start_reg)); | 405 __ Ld(a0, register_location(start_reg)); |
406 __ ld(a1, register_location(start_reg + 1)); | 406 __ Ld(a1, register_location(start_reg + 1)); |
407 __ Dsubu(a1, a1, a0); // Length to check. | 407 __ Dsubu(a1, a1, a0); // Length to check. |
408 | 408 |
409 // At this point, the capture registers are either both set or both cleared. | 409 // At this point, the capture registers are either both set or both cleared. |
410 // If the capture length is zero, then the capture is either empty or cleared. | 410 // If the capture length is zero, then the capture is either empty or cleared. |
411 // Fall through in both cases. | 411 // Fall through in both cases. |
412 __ Branch(&fallthrough, eq, a1, Operand(zero_reg)); | 412 __ Branch(&fallthrough, eq, a1, Operand(zero_reg)); |
413 | 413 |
414 if (read_backward) { | 414 if (read_backward) { |
415 __ ld(t1, MemOperand(frame_pointer(), kStringStartMinusOne)); | 415 __ Ld(t1, MemOperand(frame_pointer(), kStringStartMinusOne)); |
416 __ Daddu(t1, t1, a1); | 416 __ Daddu(t1, t1, a1); |
417 BranchOrBacktrack(on_no_match, le, current_input_offset(), Operand(t1)); | 417 BranchOrBacktrack(on_no_match, le, current_input_offset(), Operand(t1)); |
418 } else { | 418 } else { |
419 __ Daddu(t1, a1, current_input_offset()); | 419 __ Daddu(t1, a1, current_input_offset()); |
420 // Check that there are enough characters left in the input. | 420 // Check that there are enough characters left in the input. |
421 BranchOrBacktrack(on_no_match, gt, t1, Operand(zero_reg)); | 421 BranchOrBacktrack(on_no_match, gt, t1, Operand(zero_reg)); |
422 } | 422 } |
423 | 423 |
424 // Compute pointers to match string and capture string. | 424 // Compute pointers to match string and capture string. |
425 __ Daddu(a0, a0, Operand(end_of_input_address())); | 425 __ Daddu(a0, a0, Operand(end_of_input_address())); |
426 __ Daddu(a2, end_of_input_address(), Operand(current_input_offset())); | 426 __ Daddu(a2, end_of_input_address(), Operand(current_input_offset())); |
427 if (read_backward) { | 427 if (read_backward) { |
428 __ Dsubu(a2, a2, Operand(a1)); | 428 __ Dsubu(a2, a2, Operand(a1)); |
429 } | 429 } |
430 __ Daddu(a1, a1, Operand(a0)); | 430 __ Daddu(a1, a1, Operand(a0)); |
431 | 431 |
432 Label loop; | 432 Label loop; |
433 __ bind(&loop); | 433 __ bind(&loop); |
434 if (mode_ == LATIN1) { | 434 if (mode_ == LATIN1) { |
435 __ lbu(a3, MemOperand(a0, 0)); | 435 __ Lbu(a3, MemOperand(a0, 0)); |
436 __ daddiu(a0, a0, char_size()); | 436 __ daddiu(a0, a0, char_size()); |
437 __ lbu(a4, MemOperand(a2, 0)); | 437 __ Lbu(a4, MemOperand(a2, 0)); |
438 __ daddiu(a2, a2, char_size()); | 438 __ daddiu(a2, a2, char_size()); |
439 } else { | 439 } else { |
440 DCHECK(mode_ == UC16); | 440 DCHECK(mode_ == UC16); |
441 __ lhu(a3, MemOperand(a0, 0)); | 441 __ Lhu(a3, MemOperand(a0, 0)); |
442 __ daddiu(a0, a0, char_size()); | 442 __ daddiu(a0, a0, char_size()); |
443 __ lhu(a4, MemOperand(a2, 0)); | 443 __ Lhu(a4, MemOperand(a2, 0)); |
444 __ daddiu(a2, a2, char_size()); | 444 __ daddiu(a2, a2, char_size()); |
445 } | 445 } |
446 BranchOrBacktrack(on_no_match, ne, a3, Operand(a4)); | 446 BranchOrBacktrack(on_no_match, ne, a3, Operand(a4)); |
447 __ Branch(&loop, lt, a0, Operand(a1)); | 447 __ Branch(&loop, lt, a0, Operand(a1)); |
448 | 448 |
449 // Move current character position to position after match. | 449 // Move current character position to position after match. |
450 __ Dsubu(current_input_offset(), a2, end_of_input_address()); | 450 __ Dsubu(current_input_offset(), a2, end_of_input_address()); |
451 if (read_backward) { | 451 if (read_backward) { |
452 __ ld(t1, register_location(start_reg)); // Index of start of capture. | 452 __ Ld(t1, register_location(start_reg)); // Index of start of capture. |
453 __ ld(a2, register_location(start_reg + 1)); // Index of end of capture. | 453 __ Ld(a2, register_location(start_reg + 1)); // Index of end of capture. |
454 __ Daddu(current_input_offset(), current_input_offset(), Operand(t1)); | 454 __ Daddu(current_input_offset(), current_input_offset(), Operand(t1)); |
455 __ Dsubu(current_input_offset(), current_input_offset(), Operand(a2)); | 455 __ Dsubu(current_input_offset(), current_input_offset(), Operand(a2)); |
456 } | 456 } |
457 __ bind(&fallthrough); | 457 __ bind(&fallthrough); |
458 } | 458 } |
459 | 459 |
460 | 460 |
461 void RegExpMacroAssemblerMIPS::CheckNotCharacter(uint32_t c, | 461 void RegExpMacroAssemblerMIPS::CheckNotCharacter(uint32_t c, |
462 Label* on_not_equal) { | 462 Label* on_not_equal) { |
463 BranchOrBacktrack(on_not_equal, ne, current_character(), Operand(c)); | 463 BranchOrBacktrack(on_not_equal, ne, current_character(), Operand(c)); |
(...skipping 54 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
518 Handle<ByteArray> table, | 518 Handle<ByteArray> table, |
519 Label* on_bit_set) { | 519 Label* on_bit_set) { |
520 __ li(a0, Operand(table)); | 520 __ li(a0, Operand(table)); |
521 if (mode_ != LATIN1 || kTableMask != String::kMaxOneByteCharCode) { | 521 if (mode_ != LATIN1 || kTableMask != String::kMaxOneByteCharCode) { |
522 __ And(a1, current_character(), Operand(kTableSize - 1)); | 522 __ And(a1, current_character(), Operand(kTableSize - 1)); |
523 __ Daddu(a0, a0, a1); | 523 __ Daddu(a0, a0, a1); |
524 } else { | 524 } else { |
525 __ Daddu(a0, a0, current_character()); | 525 __ Daddu(a0, a0, current_character()); |
526 } | 526 } |
527 | 527 |
528 __ lbu(a0, FieldMemOperand(a0, ByteArray::kHeaderSize)); | 528 __ Lbu(a0, FieldMemOperand(a0, ByteArray::kHeaderSize)); |
529 BranchOrBacktrack(on_bit_set, ne, a0, Operand(zero_reg)); | 529 BranchOrBacktrack(on_bit_set, ne, a0, Operand(zero_reg)); |
530 } | 530 } |
531 | 531 |
532 | 532 |
533 bool RegExpMacroAssemblerMIPS::CheckSpecialCharacterClass(uc16 type, | 533 bool RegExpMacroAssemblerMIPS::CheckSpecialCharacterClass(uc16 type, |
534 Label* on_no_match) { | 534 Label* on_no_match) { |
535 // Range checks (c in min..max) are generally implemented by an unsigned | 535 // Range checks (c in min..max) are generally implemented by an unsigned |
536 // (c - min) <= (max - min) check. | 536 // (c - min) <= (max - min) check. |
537 switch (type) { | 537 switch (type) { |
538 case 's': | 538 case 's': |
(...skipping 59 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
598 return true; | 598 return true; |
599 } | 599 } |
600 case 'w': { | 600 case 'w': { |
601 if (mode_ != LATIN1) { | 601 if (mode_ != LATIN1) { |
602 // Table is 256 entries, so all Latin1 characters can be tested. | 602 // Table is 256 entries, so all Latin1 characters can be tested. |
603 BranchOrBacktrack(on_no_match, hi, current_character(), Operand('z')); | 603 BranchOrBacktrack(on_no_match, hi, current_character(), Operand('z')); |
604 } | 604 } |
605 ExternalReference map = ExternalReference::re_word_character_map(); | 605 ExternalReference map = ExternalReference::re_word_character_map(); |
606 __ li(a0, Operand(map)); | 606 __ li(a0, Operand(map)); |
607 __ Daddu(a0, a0, current_character()); | 607 __ Daddu(a0, a0, current_character()); |
608 __ lbu(a0, MemOperand(a0, 0)); | 608 __ Lbu(a0, MemOperand(a0, 0)); |
609 BranchOrBacktrack(on_no_match, eq, a0, Operand(zero_reg)); | 609 BranchOrBacktrack(on_no_match, eq, a0, Operand(zero_reg)); |
610 return true; | 610 return true; |
611 } | 611 } |
612 case 'W': { | 612 case 'W': { |
613 Label done; | 613 Label done; |
614 if (mode_ != LATIN1) { | 614 if (mode_ != LATIN1) { |
615 // Table is 256 entries, so all Latin1 characters can be tested. | 615 // Table is 256 entries, so all Latin1 characters can be tested. |
616 __ Branch(&done, hi, current_character(), Operand('z')); | 616 __ Branch(&done, hi, current_character(), Operand('z')); |
617 } | 617 } |
618 ExternalReference map = ExternalReference::re_word_character_map(); | 618 ExternalReference map = ExternalReference::re_word_character_map(); |
619 __ li(a0, Operand(map)); | 619 __ li(a0, Operand(map)); |
620 __ Daddu(a0, a0, current_character()); | 620 __ Daddu(a0, a0, current_character()); |
621 __ lbu(a0, MemOperand(a0, 0)); | 621 __ Lbu(a0, MemOperand(a0, 0)); |
622 BranchOrBacktrack(on_no_match, ne, a0, Operand(zero_reg)); | 622 BranchOrBacktrack(on_no_match, ne, a0, Operand(zero_reg)); |
623 if (mode_ != LATIN1) { | 623 if (mode_ != LATIN1) { |
624 __ bind(&done); | 624 __ bind(&done); |
625 } | 625 } |
626 return true; | 626 return true; |
627 } | 627 } |
628 case '*': | 628 case '*': |
629 // Match any character. | 629 // Match any character. |
630 return true; | 630 return true; |
631 // No custom implementation (yet): s(UC16), S(UC16). | 631 // No custom implementation (yet): s(UC16), S(UC16). |
(...skipping 50 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
682 __ push(a0); // Make room for success counter and initialize it to 0. | 682 __ push(a0); // Make room for success counter and initialize it to 0. |
683 __ push(a0); // Make room for "string start - 1" constant. | 683 __ push(a0); // Make room for "string start - 1" constant. |
684 | 684 |
685 // Check if we have space on the stack for registers. | 685 // Check if we have space on the stack for registers. |
686 Label stack_limit_hit; | 686 Label stack_limit_hit; |
687 Label stack_ok; | 687 Label stack_ok; |
688 | 688 |
689 ExternalReference stack_limit = | 689 ExternalReference stack_limit = |
690 ExternalReference::address_of_stack_limit(masm_->isolate()); | 690 ExternalReference::address_of_stack_limit(masm_->isolate()); |
691 __ li(a0, Operand(stack_limit)); | 691 __ li(a0, Operand(stack_limit)); |
692 __ ld(a0, MemOperand(a0)); | 692 __ Ld(a0, MemOperand(a0)); |
693 __ Dsubu(a0, sp, a0); | 693 __ Dsubu(a0, sp, a0); |
694 // Handle it if the stack pointer is already below the stack limit. | 694 // Handle it if the stack pointer is already below the stack limit. |
695 __ Branch(&stack_limit_hit, le, a0, Operand(zero_reg)); | 695 __ Branch(&stack_limit_hit, le, a0, Operand(zero_reg)); |
696 // Check if there is room for the variable number of registers above | 696 // Check if there is room for the variable number of registers above |
697 // the stack limit. | 697 // the stack limit. |
698 __ Branch(&stack_ok, hs, a0, Operand(num_registers_ * kPointerSize)); | 698 __ Branch(&stack_ok, hs, a0, Operand(num_registers_ * kPointerSize)); |
699 // Exit with OutOfMemory exception. There is not enough space on the stack | 699 // Exit with OutOfMemory exception. There is not enough space on the stack |
700 // for our working registers. | 700 // for our working registers. |
701 __ li(v0, Operand(EXCEPTION)); | 701 __ li(v0, Operand(EXCEPTION)); |
702 __ jmp(&return_v0); | 702 __ jmp(&return_v0); |
703 | 703 |
704 __ bind(&stack_limit_hit); | 704 __ bind(&stack_limit_hit); |
705 CallCheckStackGuardState(a0); | 705 CallCheckStackGuardState(a0); |
706 // If returned value is non-zero, we exit with the returned value as result. | 706 // If returned value is non-zero, we exit with the returned value as result. |
707 __ Branch(&return_v0, ne, v0, Operand(zero_reg)); | 707 __ Branch(&return_v0, ne, v0, Operand(zero_reg)); |
708 | 708 |
709 __ bind(&stack_ok); | 709 __ bind(&stack_ok); |
710 // Allocate space on stack for registers. | 710 // Allocate space on stack for registers. |
711 __ Dsubu(sp, sp, Operand(num_registers_ * kPointerSize)); | 711 __ Dsubu(sp, sp, Operand(num_registers_ * kPointerSize)); |
712 // Load string end. | 712 // Load string end. |
713 __ ld(end_of_input_address(), MemOperand(frame_pointer(), kInputEnd)); | 713 __ Ld(end_of_input_address(), MemOperand(frame_pointer(), kInputEnd)); |
714 // Load input start. | 714 // Load input start. |
715 __ ld(a0, MemOperand(frame_pointer(), kInputStart)); | 715 __ Ld(a0, MemOperand(frame_pointer(), kInputStart)); |
716 // Find negative length (offset of start relative to end). | 716 // Find negative length (offset of start relative to end). |
717 __ Dsubu(current_input_offset(), a0, end_of_input_address()); | 717 __ Dsubu(current_input_offset(), a0, end_of_input_address()); |
718 // Set a0 to address of char before start of the input string | 718 // Set a0 to address of char before start of the input string |
719 // (effectively string position -1). | 719 // (effectively string position -1). |
720 __ ld(a1, MemOperand(frame_pointer(), kStartIndex)); | 720 __ Ld(a1, MemOperand(frame_pointer(), kStartIndex)); |
721 __ Dsubu(a0, current_input_offset(), Operand(char_size())); | 721 __ Dsubu(a0, current_input_offset(), Operand(char_size())); |
722 __ dsll(t1, a1, (mode_ == UC16) ? 1 : 0); | 722 __ dsll(t1, a1, (mode_ == UC16) ? 1 : 0); |
723 __ Dsubu(a0, a0, t1); | 723 __ Dsubu(a0, a0, t1); |
724 // Store this value in a local variable, for use when clearing | 724 // Store this value in a local variable, for use when clearing |
725 // position registers. | 725 // position registers. |
726 __ sd(a0, MemOperand(frame_pointer(), kStringStartMinusOne)); | 726 __ Sd(a0, MemOperand(frame_pointer(), kStringStartMinusOne)); |
727 | 727 |
728 // Initialize code pointer register | 728 // Initialize code pointer register |
729 __ li(code_pointer(), Operand(masm_->CodeObject()), CONSTANT_SIZE); | 729 __ li(code_pointer(), Operand(masm_->CodeObject()), CONSTANT_SIZE); |
730 | 730 |
731 Label load_char_start_regexp, start_regexp; | 731 Label load_char_start_regexp, start_regexp; |
732 // Load newline if index is at start, previous character otherwise. | 732 // Load newline if index is at start, previous character otherwise. |
733 __ Branch(&load_char_start_regexp, ne, a1, Operand(zero_reg)); | 733 __ Branch(&load_char_start_regexp, ne, a1, Operand(zero_reg)); |
734 __ li(current_character(), Operand('\n')); | 734 __ li(current_character(), Operand('\n')); |
735 __ jmp(&start_regexp); | 735 __ jmp(&start_regexp); |
736 | 736 |
737 // Global regexp restarts matching here. | 737 // Global regexp restarts matching here. |
738 __ bind(&load_char_start_regexp); | 738 __ bind(&load_char_start_regexp); |
739 // Load previous char as initial value of current character register. | 739 // Load previous char as initial value of current character register. |
740 LoadCurrentCharacterUnchecked(-1, 1); | 740 LoadCurrentCharacterUnchecked(-1, 1); |
741 __ bind(&start_regexp); | 741 __ bind(&start_regexp); |
742 | 742 |
743 // Initialize on-stack registers. | 743 // Initialize on-stack registers. |
744 if (num_saved_registers_ > 0) { // Always is, if generated from a regexp. | 744 if (num_saved_registers_ > 0) { // Always is, if generated from a regexp. |
745 // Fill saved registers with initial value = start offset - 1. | 745 // Fill saved registers with initial value = start offset - 1. |
746 if (num_saved_registers_ > 8) { | 746 if (num_saved_registers_ > 8) { |
747 // Address of register 0. | 747 // Address of register 0. |
748 __ Daddu(a1, frame_pointer(), Operand(kRegisterZero)); | 748 __ Daddu(a1, frame_pointer(), Operand(kRegisterZero)); |
749 __ li(a2, Operand(num_saved_registers_)); | 749 __ li(a2, Operand(num_saved_registers_)); |
750 Label init_loop; | 750 Label init_loop; |
751 __ bind(&init_loop); | 751 __ bind(&init_loop); |
752 __ sd(a0, MemOperand(a1)); | 752 __ Sd(a0, MemOperand(a1)); |
753 __ Daddu(a1, a1, Operand(-kPointerSize)); | 753 __ Daddu(a1, a1, Operand(-kPointerSize)); |
754 __ Dsubu(a2, a2, Operand(1)); | 754 __ Dsubu(a2, a2, Operand(1)); |
755 __ Branch(&init_loop, ne, a2, Operand(zero_reg)); | 755 __ Branch(&init_loop, ne, a2, Operand(zero_reg)); |
756 } else { | 756 } else { |
757 for (int i = 0; i < num_saved_registers_; i++) { | 757 for (int i = 0; i < num_saved_registers_; i++) { |
758 __ sd(a0, register_location(i)); | 758 __ Sd(a0, register_location(i)); |
759 } | 759 } |
760 } | 760 } |
761 } | 761 } |
762 | 762 |
763 // Initialize backtrack stack pointer. | 763 // Initialize backtrack stack pointer. |
764 __ ld(backtrack_stackpointer(), MemOperand(frame_pointer(), kStackHighEnd)); | 764 __ Ld(backtrack_stackpointer(), MemOperand(frame_pointer(), kStackHighEnd)); |
765 | 765 |
766 __ jmp(&start_label_); | 766 __ jmp(&start_label_); |
767 | 767 |
768 | 768 |
769 // Exit code: | 769 // Exit code: |
770 if (success_label_.is_linked()) { | 770 if (success_label_.is_linked()) { |
771 // Save captures when successful. | 771 // Save captures when successful. |
772 __ bind(&success_label_); | 772 __ bind(&success_label_); |
773 if (num_saved_registers_ > 0) { | 773 if (num_saved_registers_ > 0) { |
774 // Copy captures to output. | 774 // Copy captures to output. |
775 __ ld(a1, MemOperand(frame_pointer(), kInputStart)); | 775 __ Ld(a1, MemOperand(frame_pointer(), kInputStart)); |
776 __ ld(a0, MemOperand(frame_pointer(), kRegisterOutput)); | 776 __ Ld(a0, MemOperand(frame_pointer(), kRegisterOutput)); |
777 __ ld(a2, MemOperand(frame_pointer(), kStartIndex)); | 777 __ Ld(a2, MemOperand(frame_pointer(), kStartIndex)); |
778 __ Dsubu(a1, end_of_input_address(), a1); | 778 __ Dsubu(a1, end_of_input_address(), a1); |
779 // a1 is length of input in bytes. | 779 // a1 is length of input in bytes. |
780 if (mode_ == UC16) { | 780 if (mode_ == UC16) { |
781 __ dsrl(a1, a1, 1); | 781 __ dsrl(a1, a1, 1); |
782 } | 782 } |
783 // a1 is length of input in characters. | 783 // a1 is length of input in characters. |
784 __ Daddu(a1, a1, Operand(a2)); | 784 __ Daddu(a1, a1, Operand(a2)); |
785 // a1 is length of string in characters. | 785 // a1 is length of string in characters. |
786 | 786 |
787 DCHECK_EQ(0, num_saved_registers_ % 2); | 787 DCHECK_EQ(0, num_saved_registers_ % 2); |
788 // Always an even number of capture registers. This allows us to | 788 // Always an even number of capture registers. This allows us to |
789 // unroll the loop once to add an operation between a load of a register | 789 // unroll the loop once to add an operation between a load of a register |
790 // and the following use of that register. | 790 // and the following use of that register. |
791 for (int i = 0; i < num_saved_registers_; i += 2) { | 791 for (int i = 0; i < num_saved_registers_; i += 2) { |
792 __ ld(a2, register_location(i)); | 792 __ Ld(a2, register_location(i)); |
793 __ ld(a3, register_location(i + 1)); | 793 __ Ld(a3, register_location(i + 1)); |
794 if (i == 0 && global_with_zero_length_check()) { | 794 if (i == 0 && global_with_zero_length_check()) { |
795 // Keep capture start in a4 for the zero-length check later. | 795 // Keep capture start in a4 for the zero-length check later. |
796 __ mov(t3, a2); | 796 __ mov(t3, a2); |
797 } | 797 } |
798 if (mode_ == UC16) { | 798 if (mode_ == UC16) { |
799 __ dsra(a2, a2, 1); | 799 __ dsra(a2, a2, 1); |
800 __ Daddu(a2, a2, a1); | 800 __ Daddu(a2, a2, a1); |
801 __ dsra(a3, a3, 1); | 801 __ dsra(a3, a3, 1); |
802 __ Daddu(a3, a3, a1); | 802 __ Daddu(a3, a3, a1); |
803 } else { | 803 } else { |
804 __ Daddu(a2, a1, Operand(a2)); | 804 __ Daddu(a2, a1, Operand(a2)); |
805 __ Daddu(a3, a1, Operand(a3)); | 805 __ Daddu(a3, a1, Operand(a3)); |
806 } | 806 } |
807 // V8 expects the output to be an int32_t array. | 807 // V8 expects the output to be an int32_t array. |
808 __ sw(a2, MemOperand(a0)); | 808 __ Sw(a2, MemOperand(a0)); |
809 __ Daddu(a0, a0, kIntSize); | 809 __ Daddu(a0, a0, kIntSize); |
810 __ sw(a3, MemOperand(a0)); | 810 __ Sw(a3, MemOperand(a0)); |
811 __ Daddu(a0, a0, kIntSize); | 811 __ Daddu(a0, a0, kIntSize); |
812 } | 812 } |
813 } | 813 } |
814 | 814 |
815 if (global()) { | 815 if (global()) { |
816 // Restart matching if the regular expression is flagged as global. | 816 // Restart matching if the regular expression is flagged as global. |
817 __ ld(a0, MemOperand(frame_pointer(), kSuccessfulCaptures)); | 817 __ Ld(a0, MemOperand(frame_pointer(), kSuccessfulCaptures)); |
818 __ ld(a1, MemOperand(frame_pointer(), kNumOutputRegisters)); | 818 __ Ld(a1, MemOperand(frame_pointer(), kNumOutputRegisters)); |
819 __ ld(a2, MemOperand(frame_pointer(), kRegisterOutput)); | 819 __ Ld(a2, MemOperand(frame_pointer(), kRegisterOutput)); |
820 // Increment success counter. | 820 // Increment success counter. |
821 __ Daddu(a0, a0, 1); | 821 __ Daddu(a0, a0, 1); |
822 __ sd(a0, MemOperand(frame_pointer(), kSuccessfulCaptures)); | 822 __ Sd(a0, MemOperand(frame_pointer(), kSuccessfulCaptures)); |
823 // Capture results have been stored, so the number of remaining global | 823 // Capture results have been stored, so the number of remaining global |
824 // output registers is reduced by the number of stored captures. | 824 // output registers is reduced by the number of stored captures. |
825 __ Dsubu(a1, a1, num_saved_registers_); | 825 __ Dsubu(a1, a1, num_saved_registers_); |
826 // Check whether we have enough room for another set of capture results. | 826 // Check whether we have enough room for another set of capture results. |
827 __ mov(v0, a0); | 827 __ mov(v0, a0); |
828 __ Branch(&return_v0, lt, a1, Operand(num_saved_registers_)); | 828 __ Branch(&return_v0, lt, a1, Operand(num_saved_registers_)); |
829 | 829 |
830 __ sd(a1, MemOperand(frame_pointer(), kNumOutputRegisters)); | 830 __ Sd(a1, MemOperand(frame_pointer(), kNumOutputRegisters)); |
831 // Advance the location for output. | 831 // Advance the location for output. |
832 __ Daddu(a2, a2, num_saved_registers_ * kIntSize); | 832 __ Daddu(a2, a2, num_saved_registers_ * kIntSize); |
833 __ sd(a2, MemOperand(frame_pointer(), kRegisterOutput)); | 833 __ Sd(a2, MemOperand(frame_pointer(), kRegisterOutput)); |
834 | 834 |
835 // Prepare a0 to initialize registers with its value in the next run. | 835 // Prepare a0 to initialize registers with its value in the next run. |
836 __ ld(a0, MemOperand(frame_pointer(), kStringStartMinusOne)); | 836 __ Ld(a0, MemOperand(frame_pointer(), kStringStartMinusOne)); |
837 | 837 |
838 if (global_with_zero_length_check()) { | 838 if (global_with_zero_length_check()) { |
839 // Special case for zero-length matches. | 839 // Special case for zero-length matches. |
840 // t3: capture start index | 840 // t3: capture start index |
841 // Not a zero-length match, restart. | 841 // Not a zero-length match, restart. |
842 __ Branch( | 842 __ Branch( |
843 &load_char_start_regexp, ne, current_input_offset(), Operand(t3)); | 843 &load_char_start_regexp, ne, current_input_offset(), Operand(t3)); |
844 // Offset from the end is zero if we already reached the end. | 844 // Offset from the end is zero if we already reached the end. |
845 __ Branch(&exit_label_, eq, current_input_offset(), | 845 __ Branch(&exit_label_, eq, current_input_offset(), |
846 Operand(zero_reg)); | 846 Operand(zero_reg)); |
847 // Advance current position after a zero-length match. | 847 // Advance current position after a zero-length match. |
848 Label advance; | 848 Label advance; |
849 __ bind(&advance); | 849 __ bind(&advance); |
850 __ Daddu(current_input_offset(), | 850 __ Daddu(current_input_offset(), |
851 current_input_offset(), | 851 current_input_offset(), |
852 Operand((mode_ == UC16) ? 2 : 1)); | 852 Operand((mode_ == UC16) ? 2 : 1)); |
853 if (global_unicode()) CheckNotInSurrogatePair(0, &advance); | 853 if (global_unicode()) CheckNotInSurrogatePair(0, &advance); |
854 } | 854 } |
855 | 855 |
856 __ Branch(&load_char_start_regexp); | 856 __ Branch(&load_char_start_regexp); |
857 } else { | 857 } else { |
858 __ li(v0, Operand(SUCCESS)); | 858 __ li(v0, Operand(SUCCESS)); |
859 } | 859 } |
860 } | 860 } |
861 // Exit and return v0. | 861 // Exit and return v0. |
862 __ bind(&exit_label_); | 862 __ bind(&exit_label_); |
863 if (global()) { | 863 if (global()) { |
864 __ ld(v0, MemOperand(frame_pointer(), kSuccessfulCaptures)); | 864 __ Ld(v0, MemOperand(frame_pointer(), kSuccessfulCaptures)); |
865 } | 865 } |
866 | 866 |
867 __ bind(&return_v0); | 867 __ bind(&return_v0); |
868 // Skip sp past regexp registers and local variables.. | 868 // Skip sp past regexp registers and local variables.. |
869 __ mov(sp, frame_pointer()); | 869 __ mov(sp, frame_pointer()); |
870 // Restore registers s0..s7 and return (restoring ra to pc). | 870 // Restore registers s0..s7 and return (restoring ra to pc). |
871 __ MultiPop(registers_to_retain | ra.bit()); | 871 __ MultiPop(registers_to_retain | ra.bit()); |
872 __ Ret(); | 872 __ Ret(); |
873 | 873 |
874 // Backtrack code (branch target for conditional backtracks). | 874 // Backtrack code (branch target for conditional backtracks). |
(...skipping 11 matching lines...) Expand all Loading... |
886 RegList regexp_registers_to_retain = current_input_offset().bit() | | 886 RegList regexp_registers_to_retain = current_input_offset().bit() | |
887 current_character().bit() | backtrack_stackpointer().bit(); | 887 current_character().bit() | backtrack_stackpointer().bit(); |
888 __ MultiPush(regexp_registers_to_retain); | 888 __ MultiPush(regexp_registers_to_retain); |
889 CallCheckStackGuardState(a0); | 889 CallCheckStackGuardState(a0); |
890 __ MultiPop(regexp_registers_to_retain); | 890 __ MultiPop(regexp_registers_to_retain); |
891 // If returning non-zero, we should end execution with the given | 891 // If returning non-zero, we should end execution with the given |
892 // result as return value. | 892 // result as return value. |
893 __ Branch(&return_v0, ne, v0, Operand(zero_reg)); | 893 __ Branch(&return_v0, ne, v0, Operand(zero_reg)); |
894 | 894 |
895 // String might have moved: Reload end of string from frame. | 895 // String might have moved: Reload end of string from frame. |
896 __ ld(end_of_input_address(), MemOperand(frame_pointer(), kInputEnd)); | 896 __ Ld(end_of_input_address(), MemOperand(frame_pointer(), kInputEnd)); |
897 __ li(code_pointer(), Operand(masm_->CodeObject()), CONSTANT_SIZE); | 897 __ li(code_pointer(), Operand(masm_->CodeObject()), CONSTANT_SIZE); |
898 SafeReturn(); | 898 SafeReturn(); |
899 } | 899 } |
900 | 900 |
901 // Backtrack stack overflow code. | 901 // Backtrack stack overflow code. |
902 if (stack_overflow_label_.is_linked()) { | 902 if (stack_overflow_label_.is_linked()) { |
903 SafeCallTarget(&stack_overflow_label_); | 903 SafeCallTarget(&stack_overflow_label_); |
904 // Reached if the backtrack-stack limit has been hit. | 904 // Reached if the backtrack-stack limit has been hit. |
905 // Put regexp engine registers on stack first. | 905 // Put regexp engine registers on stack first. |
906 RegList regexp_registers = current_input_offset().bit() | | 906 RegList regexp_registers = current_input_offset().bit() | |
(...skipping 11 matching lines...) Expand all Loading... |
918 __ CallCFunction(grow_stack, num_arguments); | 918 __ CallCFunction(grow_stack, num_arguments); |
919 // Restore regexp registers. | 919 // Restore regexp registers. |
920 __ MultiPop(regexp_registers); | 920 __ MultiPop(regexp_registers); |
921 // If return NULL, we have failed to grow the stack, and | 921 // If return NULL, we have failed to grow the stack, and |
922 // must exit with a stack-overflow exception. | 922 // must exit with a stack-overflow exception. |
923 __ Branch(&exit_with_exception, eq, v0, Operand(zero_reg)); | 923 __ Branch(&exit_with_exception, eq, v0, Operand(zero_reg)); |
924 // Otherwise use return value as new stack pointer. | 924 // Otherwise use return value as new stack pointer. |
925 __ mov(backtrack_stackpointer(), v0); | 925 __ mov(backtrack_stackpointer(), v0); |
926 // Restore saved registers and continue. | 926 // Restore saved registers and continue. |
927 __ li(code_pointer(), Operand(masm_->CodeObject()), CONSTANT_SIZE); | 927 __ li(code_pointer(), Operand(masm_->CodeObject()), CONSTANT_SIZE); |
928 __ ld(end_of_input_address(), MemOperand(frame_pointer(), kInputEnd)); | 928 __ Ld(end_of_input_address(), MemOperand(frame_pointer(), kInputEnd)); |
929 SafeReturn(); | 929 SafeReturn(); |
930 } | 930 } |
931 | 931 |
932 if (exit_with_exception.is_linked()) { | 932 if (exit_with_exception.is_linked()) { |
933 // If any of the code above needed to exit with an exception. | 933 // If any of the code above needed to exit with an exception. |
934 __ bind(&exit_with_exception); | 934 __ bind(&exit_with_exception); |
935 // Exit with Result EXCEPTION(-1) to signal thrown exception. | 935 // Exit with Result EXCEPTION(-1) to signal thrown exception. |
936 __ li(v0, Operand(EXCEPTION)); | 936 __ li(v0, Operand(EXCEPTION)); |
937 __ jmp(&return_v0); | 937 __ jmp(&return_v0); |
938 } | 938 } |
(...skipping 15 matching lines...) Expand all Loading... |
954 return; | 954 return; |
955 } | 955 } |
956 __ jmp(to); | 956 __ jmp(to); |
957 return; | 957 return; |
958 } | 958 } |
959 | 959 |
960 | 960 |
961 void RegExpMacroAssemblerMIPS::IfRegisterGE(int reg, | 961 void RegExpMacroAssemblerMIPS::IfRegisterGE(int reg, |
962 int comparand, | 962 int comparand, |
963 Label* if_ge) { | 963 Label* if_ge) { |
964 __ ld(a0, register_location(reg)); | 964 __ Ld(a0, register_location(reg)); |
965 BranchOrBacktrack(if_ge, ge, a0, Operand(comparand)); | 965 BranchOrBacktrack(if_ge, ge, a0, Operand(comparand)); |
966 } | 966 } |
967 | 967 |
968 | 968 |
969 void RegExpMacroAssemblerMIPS::IfRegisterLT(int reg, | 969 void RegExpMacroAssemblerMIPS::IfRegisterLT(int reg, |
970 int comparand, | 970 int comparand, |
971 Label* if_lt) { | 971 Label* if_lt) { |
972 __ ld(a0, register_location(reg)); | 972 __ Ld(a0, register_location(reg)); |
973 BranchOrBacktrack(if_lt, lt, a0, Operand(comparand)); | 973 BranchOrBacktrack(if_lt, lt, a0, Operand(comparand)); |
974 } | 974 } |
975 | 975 |
976 | 976 |
977 void RegExpMacroAssemblerMIPS::IfRegisterEqPos(int reg, | 977 void RegExpMacroAssemblerMIPS::IfRegisterEqPos(int reg, |
978 Label* if_eq) { | 978 Label* if_eq) { |
979 __ ld(a0, register_location(reg)); | 979 __ Ld(a0, register_location(reg)); |
980 BranchOrBacktrack(if_eq, eq, a0, Operand(current_input_offset())); | 980 BranchOrBacktrack(if_eq, eq, a0, Operand(current_input_offset())); |
981 } | 981 } |
982 | 982 |
983 | 983 |
984 RegExpMacroAssembler::IrregexpImplementation | 984 RegExpMacroAssembler::IrregexpImplementation |
985 RegExpMacroAssemblerMIPS::Implementation() { | 985 RegExpMacroAssemblerMIPS::Implementation() { |
986 return kMIPSImplementation; | 986 return kMIPSImplementation; |
987 } | 987 } |
988 | 988 |
989 | 989 |
(...skipping 13 matching lines...) Expand all Loading... |
1003 } | 1003 } |
1004 | 1004 |
1005 | 1005 |
1006 void RegExpMacroAssemblerMIPS::PopCurrentPosition() { | 1006 void RegExpMacroAssemblerMIPS::PopCurrentPosition() { |
1007 Pop(current_input_offset()); | 1007 Pop(current_input_offset()); |
1008 } | 1008 } |
1009 | 1009 |
1010 | 1010 |
1011 void RegExpMacroAssemblerMIPS::PopRegister(int register_index) { | 1011 void RegExpMacroAssemblerMIPS::PopRegister(int register_index) { |
1012 Pop(a0); | 1012 Pop(a0); |
1013 __ sd(a0, register_location(register_index)); | 1013 __ Sd(a0, register_location(register_index)); |
1014 } | 1014 } |
1015 | 1015 |
1016 | 1016 |
1017 void RegExpMacroAssemblerMIPS::PushBacktrack(Label* label) { | 1017 void RegExpMacroAssemblerMIPS::PushBacktrack(Label* label) { |
1018 if (label->is_bound()) { | 1018 if (label->is_bound()) { |
1019 int target = label->pos(); | 1019 int target = label->pos(); |
1020 __ li(a0, Operand(target + Code::kHeaderSize - kHeapObjectTag)); | 1020 __ li(a0, Operand(target + Code::kHeaderSize - kHeapObjectTag)); |
1021 } else { | 1021 } else { |
1022 Assembler::BlockTrampolinePoolScope block_trampoline_pool(masm_); | 1022 Assembler::BlockTrampolinePoolScope block_trampoline_pool(masm_); |
1023 Label after_constant; | 1023 Label after_constant; |
1024 __ Branch(&after_constant); | 1024 __ Branch(&after_constant); |
1025 int offset = masm_->pc_offset(); | 1025 int offset = masm_->pc_offset(); |
1026 int cp_offset = offset + Code::kHeaderSize - kHeapObjectTag; | 1026 int cp_offset = offset + Code::kHeaderSize - kHeapObjectTag; |
1027 __ emit(0); | 1027 __ emit(0); |
1028 masm_->label_at_put(label, offset); | 1028 masm_->label_at_put(label, offset); |
1029 __ bind(&after_constant); | 1029 __ bind(&after_constant); |
1030 if (is_int16(cp_offset)) { | 1030 if (is_int16(cp_offset)) { |
1031 __ lwu(a0, MemOperand(code_pointer(), cp_offset)); | 1031 __ Lwu(a0, MemOperand(code_pointer(), cp_offset)); |
1032 } else { | 1032 } else { |
1033 __ Daddu(a0, code_pointer(), cp_offset); | 1033 __ Daddu(a0, code_pointer(), cp_offset); |
1034 __ lwu(a0, MemOperand(a0, 0)); | 1034 __ Lwu(a0, MemOperand(a0, 0)); |
1035 } | 1035 } |
1036 } | 1036 } |
1037 Push(a0); | 1037 Push(a0); |
1038 CheckStackLimit(); | 1038 CheckStackLimit(); |
1039 } | 1039 } |
1040 | 1040 |
1041 | 1041 |
1042 void RegExpMacroAssemblerMIPS::PushCurrentPosition() { | 1042 void RegExpMacroAssemblerMIPS::PushCurrentPosition() { |
1043 Push(current_input_offset()); | 1043 Push(current_input_offset()); |
1044 } | 1044 } |
1045 | 1045 |
1046 | 1046 |
1047 void RegExpMacroAssemblerMIPS::PushRegister(int register_index, | 1047 void RegExpMacroAssemblerMIPS::PushRegister(int register_index, |
1048 StackCheckFlag check_stack_limit) { | 1048 StackCheckFlag check_stack_limit) { |
1049 __ ld(a0, register_location(register_index)); | 1049 __ Ld(a0, register_location(register_index)); |
1050 Push(a0); | 1050 Push(a0); |
1051 if (check_stack_limit) CheckStackLimit(); | 1051 if (check_stack_limit) CheckStackLimit(); |
1052 } | 1052 } |
1053 | 1053 |
1054 | 1054 |
1055 void RegExpMacroAssemblerMIPS::ReadCurrentPositionFromRegister(int reg) { | 1055 void RegExpMacroAssemblerMIPS::ReadCurrentPositionFromRegister(int reg) { |
1056 __ ld(current_input_offset(), register_location(reg)); | 1056 __ Ld(current_input_offset(), register_location(reg)); |
1057 } | 1057 } |
1058 | 1058 |
1059 | 1059 |
1060 void RegExpMacroAssemblerMIPS::ReadStackPointerFromRegister(int reg) { | 1060 void RegExpMacroAssemblerMIPS::ReadStackPointerFromRegister(int reg) { |
1061 __ ld(backtrack_stackpointer(), register_location(reg)); | 1061 __ Ld(backtrack_stackpointer(), register_location(reg)); |
1062 __ ld(a0, MemOperand(frame_pointer(), kStackHighEnd)); | 1062 __ Ld(a0, MemOperand(frame_pointer(), kStackHighEnd)); |
1063 __ Daddu(backtrack_stackpointer(), backtrack_stackpointer(), Operand(a0)); | 1063 __ Daddu(backtrack_stackpointer(), backtrack_stackpointer(), Operand(a0)); |
1064 } | 1064 } |
1065 | 1065 |
1066 | 1066 |
1067 void RegExpMacroAssemblerMIPS::SetCurrentPositionFromEnd(int by) { | 1067 void RegExpMacroAssemblerMIPS::SetCurrentPositionFromEnd(int by) { |
1068 Label after_position; | 1068 Label after_position; |
1069 __ Branch(&after_position, | 1069 __ Branch(&after_position, |
1070 ge, | 1070 ge, |
1071 current_input_offset(), | 1071 current_input_offset(), |
1072 Operand(-by * char_size())); | 1072 Operand(-by * char_size())); |
1073 __ li(current_input_offset(), -by * char_size()); | 1073 __ li(current_input_offset(), -by * char_size()); |
1074 // On RegExp code entry (where this operation is used), the character before | 1074 // On RegExp code entry (where this operation is used), the character before |
1075 // the current position is expected to be already loaded. | 1075 // the current position is expected to be already loaded. |
1076 // We have advanced the position, so it's safe to read backwards. | 1076 // We have advanced the position, so it's safe to read backwards. |
1077 LoadCurrentCharacterUnchecked(-1, 1); | 1077 LoadCurrentCharacterUnchecked(-1, 1); |
1078 __ bind(&after_position); | 1078 __ bind(&after_position); |
1079 } | 1079 } |
1080 | 1080 |
1081 | 1081 |
1082 void RegExpMacroAssemblerMIPS::SetRegister(int register_index, int to) { | 1082 void RegExpMacroAssemblerMIPS::SetRegister(int register_index, int to) { |
1083 DCHECK(register_index >= num_saved_registers_); // Reserved for positions! | 1083 DCHECK(register_index >= num_saved_registers_); // Reserved for positions! |
1084 __ li(a0, Operand(to)); | 1084 __ li(a0, Operand(to)); |
1085 __ sd(a0, register_location(register_index)); | 1085 __ Sd(a0, register_location(register_index)); |
1086 } | 1086 } |
1087 | 1087 |
1088 | 1088 |
1089 bool RegExpMacroAssemblerMIPS::Succeed() { | 1089 bool RegExpMacroAssemblerMIPS::Succeed() { |
1090 __ jmp(&success_label_); | 1090 __ jmp(&success_label_); |
1091 return global(); | 1091 return global(); |
1092 } | 1092 } |
1093 | 1093 |
1094 | 1094 |
1095 void RegExpMacroAssemblerMIPS::WriteCurrentPositionToRegister(int reg, | 1095 void RegExpMacroAssemblerMIPS::WriteCurrentPositionToRegister(int reg, |
1096 int cp_offset) { | 1096 int cp_offset) { |
1097 if (cp_offset == 0) { | 1097 if (cp_offset == 0) { |
1098 __ sd(current_input_offset(), register_location(reg)); | 1098 __ Sd(current_input_offset(), register_location(reg)); |
1099 } else { | 1099 } else { |
1100 __ Daddu(a0, current_input_offset(), Operand(cp_offset * char_size())); | 1100 __ Daddu(a0, current_input_offset(), Operand(cp_offset * char_size())); |
1101 __ sd(a0, register_location(reg)); | 1101 __ Sd(a0, register_location(reg)); |
1102 } | 1102 } |
1103 } | 1103 } |
1104 | 1104 |
1105 | 1105 |
1106 void RegExpMacroAssemblerMIPS::ClearRegisters(int reg_from, int reg_to) { | 1106 void RegExpMacroAssemblerMIPS::ClearRegisters(int reg_from, int reg_to) { |
1107 DCHECK(reg_from <= reg_to); | 1107 DCHECK(reg_from <= reg_to); |
1108 __ ld(a0, MemOperand(frame_pointer(), kStringStartMinusOne)); | 1108 __ Ld(a0, MemOperand(frame_pointer(), kStringStartMinusOne)); |
1109 for (int reg = reg_from; reg <= reg_to; reg++) { | 1109 for (int reg = reg_from; reg <= reg_to; reg++) { |
1110 __ sd(a0, register_location(reg)); | 1110 __ Sd(a0, register_location(reg)); |
1111 } | 1111 } |
1112 } | 1112 } |
1113 | 1113 |
1114 | 1114 |
1115 void RegExpMacroAssemblerMIPS::WriteStackPointerToRegister(int reg) { | 1115 void RegExpMacroAssemblerMIPS::WriteStackPointerToRegister(int reg) { |
1116 __ ld(a1, MemOperand(frame_pointer(), kStackHighEnd)); | 1116 __ Ld(a1, MemOperand(frame_pointer(), kStackHighEnd)); |
1117 __ Dsubu(a0, backtrack_stackpointer(), a1); | 1117 __ Dsubu(a0, backtrack_stackpointer(), a1); |
1118 __ sd(a0, register_location(reg)); | 1118 __ Sd(a0, register_location(reg)); |
1119 } | 1119 } |
1120 | 1120 |
1121 | 1121 |
1122 bool RegExpMacroAssemblerMIPS::CanReadUnaligned() { | 1122 bool RegExpMacroAssemblerMIPS::CanReadUnaligned() { |
1123 return false; | 1123 return false; |
1124 } | 1124 } |
1125 | 1125 |
1126 | 1126 |
1127 // Private methods: | 1127 // Private methods: |
1128 | 1128 |
1129 void RegExpMacroAssemblerMIPS::CallCheckStackGuardState(Register scratch) { | 1129 void RegExpMacroAssemblerMIPS::CallCheckStackGuardState(Register scratch) { |
1130 int stack_alignment = base::OS::ActivationFrameAlignment(); | 1130 int stack_alignment = base::OS::ActivationFrameAlignment(); |
1131 | 1131 |
1132 // Align the stack pointer and save the original sp value on the stack. | 1132 // Align the stack pointer and save the original sp value on the stack. |
1133 __ mov(scratch, sp); | 1133 __ mov(scratch, sp); |
1134 __ Dsubu(sp, sp, Operand(kPointerSize)); | 1134 __ Dsubu(sp, sp, Operand(kPointerSize)); |
1135 DCHECK(base::bits::IsPowerOfTwo32(stack_alignment)); | 1135 DCHECK(base::bits::IsPowerOfTwo32(stack_alignment)); |
1136 __ And(sp, sp, Operand(-stack_alignment)); | 1136 __ And(sp, sp, Operand(-stack_alignment)); |
1137 __ sd(scratch, MemOperand(sp)); | 1137 __ Sd(scratch, MemOperand(sp)); |
1138 | 1138 |
1139 __ mov(a2, frame_pointer()); | 1139 __ mov(a2, frame_pointer()); |
1140 // Code* of self. | 1140 // Code* of self. |
1141 __ li(a1, Operand(masm_->CodeObject()), CONSTANT_SIZE); | 1141 __ li(a1, Operand(masm_->CodeObject()), CONSTANT_SIZE); |
1142 | 1142 |
1143 // We need to make room for the return address on the stack. | 1143 // We need to make room for the return address on the stack. |
1144 DCHECK(IsAligned(stack_alignment, kPointerSize)); | 1144 DCHECK(IsAligned(stack_alignment, kPointerSize)); |
1145 __ Dsubu(sp, sp, Operand(stack_alignment)); | 1145 __ Dsubu(sp, sp, Operand(stack_alignment)); |
1146 | 1146 |
1147 // Stack pointer now points to cell where return address is to be written. | 1147 // Stack pointer now points to cell where return address is to be written. |
(...skipping 19 matching lines...) Expand all Loading... |
1167 // drop them with the return address from the stack with loading saved sp. | 1167 // drop them with the return address from the stack with loading saved sp. |
1168 // At this point stack must look: | 1168 // At this point stack must look: |
1169 // [sp + 7] - empty slot if needed for alignment. | 1169 // [sp + 7] - empty slot if needed for alignment. |
1170 // [sp + 6] - saved sp. | 1170 // [sp + 6] - saved sp. |
1171 // [sp + 5] - second word reserved for return value. | 1171 // [sp + 5] - second word reserved for return value. |
1172 // [sp + 4] - first word reserved for return value. | 1172 // [sp + 4] - first word reserved for return value. |
1173 // [sp + 3] - C argument slot. | 1173 // [sp + 3] - C argument slot. |
1174 // [sp + 2] - C argument slot. | 1174 // [sp + 2] - C argument slot. |
1175 // [sp + 1] - C argument slot. | 1175 // [sp + 1] - C argument slot. |
1176 // [sp + 0] - C argument slot. | 1176 // [sp + 0] - C argument slot. |
1177 __ ld(sp, MemOperand(sp, stack_alignment + kCArgsSlotsSize)); | 1177 __ Ld(sp, MemOperand(sp, stack_alignment + kCArgsSlotsSize)); |
1178 | 1178 |
1179 __ li(code_pointer(), Operand(masm_->CodeObject())); | 1179 __ li(code_pointer(), Operand(masm_->CodeObject())); |
1180 } | 1180 } |
1181 | 1181 |
1182 | 1182 |
1183 // Helper function for reading a value out of a stack frame. | 1183 // Helper function for reading a value out of a stack frame. |
1184 template <typename T> | 1184 template <typename T> |
1185 static T& frame_entry(Address re_frame, int frame_offset) { | 1185 static T& frame_entry(Address re_frame, int frame_offset) { |
1186 return reinterpret_cast<T&>(Memory::int32_at(re_frame + frame_offset)); | 1186 return reinterpret_cast<T&>(Memory::int32_at(re_frame + frame_offset)); |
1187 } | 1187 } |
(...skipping 27 matching lines...) Expand all Loading... |
1215 kRegisterZero - register_index * kPointerSize); | 1215 kRegisterZero - register_index * kPointerSize); |
1216 } | 1216 } |
1217 | 1217 |
1218 | 1218 |
1219 void RegExpMacroAssemblerMIPS::CheckPosition(int cp_offset, | 1219 void RegExpMacroAssemblerMIPS::CheckPosition(int cp_offset, |
1220 Label* on_outside_input) { | 1220 Label* on_outside_input) { |
1221 if (cp_offset >= 0) { | 1221 if (cp_offset >= 0) { |
1222 BranchOrBacktrack(on_outside_input, ge, current_input_offset(), | 1222 BranchOrBacktrack(on_outside_input, ge, current_input_offset(), |
1223 Operand(-cp_offset * char_size())); | 1223 Operand(-cp_offset * char_size())); |
1224 } else { | 1224 } else { |
1225 __ ld(a1, MemOperand(frame_pointer(), kStringStartMinusOne)); | 1225 __ Ld(a1, MemOperand(frame_pointer(), kStringStartMinusOne)); |
1226 __ Daddu(a0, current_input_offset(), Operand(cp_offset * char_size())); | 1226 __ Daddu(a0, current_input_offset(), Operand(cp_offset * char_size())); |
1227 BranchOrBacktrack(on_outside_input, le, a0, Operand(a1)); | 1227 BranchOrBacktrack(on_outside_input, le, a0, Operand(a1)); |
1228 } | 1228 } |
1229 } | 1229 } |
1230 | 1230 |
1231 | 1231 |
1232 void RegExpMacroAssemblerMIPS::BranchOrBacktrack(Label* to, | 1232 void RegExpMacroAssemblerMIPS::BranchOrBacktrack(Label* to, |
1233 Condition condition, | 1233 Condition condition, |
1234 Register rs, | 1234 Register rs, |
1235 const Operand& rt) { | 1235 const Operand& rt) { |
(...skipping 33 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1269 __ Dsubu(ra, ra, Operand(masm_->CodeObject())); | 1269 __ Dsubu(ra, ra, Operand(masm_->CodeObject())); |
1270 __ push(ra); | 1270 __ push(ra); |
1271 } | 1271 } |
1272 | 1272 |
1273 | 1273 |
1274 void RegExpMacroAssemblerMIPS::Push(Register source) { | 1274 void RegExpMacroAssemblerMIPS::Push(Register source) { |
1275 DCHECK(!source.is(backtrack_stackpointer())); | 1275 DCHECK(!source.is(backtrack_stackpointer())); |
1276 __ Daddu(backtrack_stackpointer(), | 1276 __ Daddu(backtrack_stackpointer(), |
1277 backtrack_stackpointer(), | 1277 backtrack_stackpointer(), |
1278 Operand(-kIntSize)); | 1278 Operand(-kIntSize)); |
1279 __ sw(source, MemOperand(backtrack_stackpointer())); | 1279 __ Sw(source, MemOperand(backtrack_stackpointer())); |
1280 } | 1280 } |
1281 | 1281 |
1282 | 1282 |
1283 void RegExpMacroAssemblerMIPS::Pop(Register target) { | 1283 void RegExpMacroAssemblerMIPS::Pop(Register target) { |
1284 DCHECK(!target.is(backtrack_stackpointer())); | 1284 DCHECK(!target.is(backtrack_stackpointer())); |
1285 __ lw(target, MemOperand(backtrack_stackpointer())); | 1285 __ Lw(target, MemOperand(backtrack_stackpointer())); |
1286 __ Daddu(backtrack_stackpointer(), backtrack_stackpointer(), kIntSize); | 1286 __ Daddu(backtrack_stackpointer(), backtrack_stackpointer(), kIntSize); |
1287 } | 1287 } |
1288 | 1288 |
1289 | 1289 |
1290 void RegExpMacroAssemblerMIPS::CheckPreemption() { | 1290 void RegExpMacroAssemblerMIPS::CheckPreemption() { |
1291 // Check for preemption. | 1291 // Check for preemption. |
1292 ExternalReference stack_limit = | 1292 ExternalReference stack_limit = |
1293 ExternalReference::address_of_stack_limit(masm_->isolate()); | 1293 ExternalReference::address_of_stack_limit(masm_->isolate()); |
1294 __ li(a0, Operand(stack_limit)); | 1294 __ li(a0, Operand(stack_limit)); |
1295 __ ld(a0, MemOperand(a0)); | 1295 __ Ld(a0, MemOperand(a0)); |
1296 SafeCall(&check_preempt_label_, ls, sp, Operand(a0)); | 1296 SafeCall(&check_preempt_label_, ls, sp, Operand(a0)); |
1297 } | 1297 } |
1298 | 1298 |
1299 | 1299 |
1300 void RegExpMacroAssemblerMIPS::CheckStackLimit() { | 1300 void RegExpMacroAssemblerMIPS::CheckStackLimit() { |
1301 ExternalReference stack_limit = | 1301 ExternalReference stack_limit = |
1302 ExternalReference::address_of_regexp_stack_limit(masm_->isolate()); | 1302 ExternalReference::address_of_regexp_stack_limit(masm_->isolate()); |
1303 | 1303 |
1304 __ li(a0, Operand(stack_limit)); | 1304 __ li(a0, Operand(stack_limit)); |
1305 __ ld(a0, MemOperand(a0)); | 1305 __ Ld(a0, MemOperand(a0)); |
1306 SafeCall(&stack_overflow_label_, ls, backtrack_stackpointer(), Operand(a0)); | 1306 SafeCall(&stack_overflow_label_, ls, backtrack_stackpointer(), Operand(a0)); |
1307 } | 1307 } |
1308 | 1308 |
1309 | 1309 |
1310 void RegExpMacroAssemblerMIPS::LoadCurrentCharacterUnchecked(int cp_offset, | 1310 void RegExpMacroAssemblerMIPS::LoadCurrentCharacterUnchecked(int cp_offset, |
1311 int characters) { | 1311 int characters) { |
1312 Register offset = current_input_offset(); | 1312 Register offset = current_input_offset(); |
1313 if (cp_offset != 0) { | 1313 if (cp_offset != 0) { |
1314 // t3 is not being used to store the capture start index at this point. | 1314 // t3 is not being used to store the capture start index at this point. |
1315 __ Daddu(t3, current_input_offset(), Operand(cp_offset * char_size())); | 1315 __ Daddu(t3, current_input_offset(), Operand(cp_offset * char_size())); |
1316 offset = t3; | 1316 offset = t3; |
1317 } | 1317 } |
1318 // We assume that we cannot do unaligned loads on MIPS, so this function | 1318 // We assume that we cannot do unaligned loads on MIPS, so this function |
1319 // must only be used to load a single character at a time. | 1319 // must only be used to load a single character at a time. |
1320 DCHECK(characters == 1); | 1320 DCHECK(characters == 1); |
1321 __ Daddu(t1, end_of_input_address(), Operand(offset)); | 1321 __ Daddu(t1, end_of_input_address(), Operand(offset)); |
1322 if (mode_ == LATIN1) { | 1322 if (mode_ == LATIN1) { |
1323 __ lbu(current_character(), MemOperand(t1, 0)); | 1323 __ Lbu(current_character(), MemOperand(t1, 0)); |
1324 } else { | 1324 } else { |
1325 DCHECK(mode_ == UC16); | 1325 DCHECK(mode_ == UC16); |
1326 __ lhu(current_character(), MemOperand(t1, 0)); | 1326 __ Lhu(current_character(), MemOperand(t1, 0)); |
1327 } | 1327 } |
1328 } | 1328 } |
1329 | 1329 |
1330 #undef __ | 1330 #undef __ |
1331 | 1331 |
1332 #endif // V8_INTERPRETED_REGEXP | 1332 #endif // V8_INTERPRETED_REGEXP |
1333 | 1333 |
1334 } // namespace internal | 1334 } // namespace internal |
1335 } // namespace v8 | 1335 } // namespace v8 |
1336 | 1336 |
1337 #endif // V8_TARGET_ARCH_MIPS64 | 1337 #endif // V8_TARGET_ARCH_MIPS64 |
OLD | NEW |