| 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 |