1 // Copyright 2006-2010 the V8 project authors. All rights reserved. 2 // Redistribution and use in source and binary forms, with or without 3 // modification, are permitted provided that the following conditions are 4 // met: 5 // 6 // * Redistributions of source code must retain the above copyright 7 // notice, this list of conditions and the following disclaimer. 8 // * Redistributions in binary form must reproduce the above 9 // copyright notice, this list of conditions and the following 10 // disclaimer in the documentation and/or other materials provided 11 // with the distribution. 12 // * Neither the name of Google Inc. nor the names of its 13 // contributors may be used to endorse or promote products derived 14 // from this software without specific prior written permission. 15 // 16 // THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 17 // "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 18 // LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR 19 // A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT 20 // OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, 21 // SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT 22 // LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 23 // DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 24 // THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 25 // (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 26 // OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 27 28 #include "v8.h" 29 30 #if defined(V8_TARGET_ARCH_MIPS) 31 32 #include "unicode.h" 33 #include "log.h" 34 #include "code-stubs.h" 35 #include "regexp-stack.h" 36 #include "macro-assembler.h" 37 #include "regexp-macro-assembler.h" 38 #include "mips/regexp-macro-assembler-mips.h" 39 40 namespace v8 { 41 namespace internal { 42 43 #ifndef V8_INTERPRETED_REGEXP 44 /* 45 * This assembler uses the following register assignment convention 46 * - t1 : Pointer to current code object (Code*) including heap object tag. 47 * - t2 : Current position in input, as negative offset from end of string. 48 * Please notice that this is the byte offset, not the character offset! 49 * - t3 : Currently loaded character. Must be loaded using 50 * LoadCurrentCharacter before using any of the dispatch methods. 51 * - t4 : points to tip of backtrack stack 52 * - t5 : Unused. 53 * - t6 : End of input (points to byte after last character in input). 54 * - fp : Frame pointer. Used to access arguments, local variables and 55 * RegExp registers. 56 * - sp : points to tip of C stack. 57 * 58 * The remaining registers are free for computations. 59 * 60 * Each call to a public method should retain this convention. 61 * The stack will have the following structure: 62 * - direct_call (if 1, direct call from JavaScript code, if 0 call 63 * through the runtime system) 64 * - stack_area_base (High end of the memory area to use as 65 * backtracking stack) 66 * - int* capture_array (int[num_saved_registers_], for output). 67 * - stack frame header (16 bytes in size) 68 * --- sp when called --- 69 * - link address 70 * - backup of registers s0..s7 71 * - end of input (Address of end of string) 72 * - start of input (Address of first character in string) 73 * - start index (character index of start) 74 * --- frame pointer ---- 75 * - void* input_string (location of a handle containing the string) 76 * - Offset of location before start of input (effectively character 77 * position -1). Used to initialize capture registers to a non-position. 78 * - At start (if 1, we are starting at the start of the 79 * string, otherwise 0) 80 * - register 0 (Only positions must be stored in the first 81 * - register 1 num_saved_registers_ registers) 82 * - ... 83 * - register num_registers-1 84 * --- sp --- 85 * 86 * The first num_saved_registers_ registers are initialized to point to 87 * "character -1" in the string (i.e., char_size() bytes before the first 88 * character of the string). The remaining registers start out as garbage. 89 * 90 * The data up to the return address must be placed there by the calling 91 * code, by calling the code entry as cast to a function with the signature: 92 * int (*match)(String* input_string, 93 * int start_index, 94 * Address start, 95 * Address end, 96 * int* capture_output_array, 97 * bool at_start, 98 * byte* stack_area_base, 99 * bool direct_call) 100 * The call is performed by NativeRegExpMacroAssembler::Execute() 101 * (in regexp-macro-assembler.cc). 102 */ 103 104 #define __ ACCESS_MASM(masm_) 105 106 RegExpMacroAssemblerMIPS::RegExpMacroAssemblerMIPS( 107 Mode mode, 108 int registers_to_save) 109 : masm_(new MacroAssembler(NULL, kRegExpCodeSize)), 110 mode_(mode), 111 num_registers_(registers_to_save), 112 num_saved_registers_(registers_to_save), 113 entry_label_(), 114 start_label_(), 115 success_label_(), 116 backtrack_label_(), 117 exit_label_() { 118 ASSERT_EQ(0, registers_to_save % 2); 119 __ jmp(&entry_label_); // We'll write the entry code later. 120 __ bind(&start_label_); // And then continue from here. 121 } 122 123 124 RegExpMacroAssemblerMIPS::~RegExpMacroAssemblerMIPS() { 125 delete masm_; 126 // Unuse labels in case we throw away the assembler without calling GetCode. 127 entry_label_.Unuse(); 128 start_label_.Unuse(); 129 success_label_.Unuse(); 130 backtrack_label_.Unuse(); 131 exit_label_.Unuse(); 132 check_preempt_label_.Unuse(); 133 stack_overflow_label_.Unuse(); 134 } 135 136 137 int RegExpMacroAssemblerMIPS::stack_limit_slack() { 138 return RegExpStack::kStackLimitSlack; 139 } 140 141 142 void RegExpMacroAssemblerMIPS::AdvanceCurrentPosition(int by) { 143 UNIMPLEMENTED_MIPS(); 144 } 145 146 147 void RegExpMacroAssemblerMIPS::AdvanceRegister(int reg, int by) { 148 UNIMPLEMENTED_MIPS(); 149 } 150 151 152 void RegExpMacroAssemblerMIPS::Backtrack() { 153 UNIMPLEMENTED_MIPS(); 154 } 155 156 157 void RegExpMacroAssemblerMIPS::Bind(Label* label) { 158 UNIMPLEMENTED_MIPS(); 159 } 160 161 162 void RegExpMacroAssemblerMIPS::CheckCharacter(uint32_t c, Label* on_equal) { 163 UNIMPLEMENTED_MIPS(); 164 } 165 166 167 void RegExpMacroAssemblerMIPS::CheckCharacterGT(uc16 limit, Label* on_greater) { 168 UNIMPLEMENTED_MIPS(); 169 } 170 171 172 void RegExpMacroAssemblerMIPS::CheckAtStart(Label* on_at_start) { 173 UNIMPLEMENTED_MIPS(); 174 } 175 176 177 void RegExpMacroAssemblerMIPS::CheckNotAtStart(Label* on_not_at_start) { 178 UNIMPLEMENTED_MIPS(); 179 } 180 181 182 void RegExpMacroAssemblerMIPS::CheckCharacterLT(uc16 limit, Label* on_less) { 183 UNIMPLEMENTED_MIPS(); 184 } 185 186 187 void RegExpMacroAssemblerMIPS::CheckCharacters(Vector<const uc16> str, 188 int cp_offset, 189 Label* on_failure, 190 bool check_end_of_string) { 191 UNIMPLEMENTED_MIPS(); 192 } 193 194 195 void RegExpMacroAssemblerMIPS::CheckGreedyLoop(Label* on_equal) { 196 UNIMPLEMENTED_MIPS(); 197 } 198 199 200 void RegExpMacroAssemblerMIPS::CheckNotBackReferenceIgnoreCase( 201 int start_reg, 202 Label* on_no_match) { 203 UNIMPLEMENTED_MIPS(); 204 } 205 206 207 void RegExpMacroAssemblerMIPS::CheckNotBackReference( 208 int start_reg, 209 Label* on_no_match) { 210 UNIMPLEMENTED_MIPS(); 211 } 212 213 214 void RegExpMacroAssemblerMIPS::CheckNotRegistersEqual(int reg1, 215 int reg2, 216 Label* on_not_equal) { 217 UNIMPLEMENTED_MIPS(); 218 } 219 220 221 void RegExpMacroAssemblerMIPS::CheckNotCharacter(uint32_t c, 222 Label* on_not_equal) { 223 UNIMPLEMENTED_MIPS(); 224 } 225 226 227 void RegExpMacroAssemblerMIPS::CheckCharacterAfterAnd(uint32_t c, 228 uint32_t mask, 229 Label* on_equal) { 230 UNIMPLEMENTED_MIPS(); 231 } 232 233 234 void RegExpMacroAssemblerMIPS::CheckNotCharacterAfterAnd(uint32_t c, 235 uint32_t mask, 236 Label* on_not_equal) { 237 UNIMPLEMENTED_MIPS(); 238 } 239 240 241 void RegExpMacroAssemblerMIPS::CheckNotCharacterAfterMinusAnd( 242 uc16 c, 243 uc16 minus, 244 uc16 mask, 245 Label* on_not_equal) { 246 UNIMPLEMENTED_MIPS(); 247 } 248 249 250 bool RegExpMacroAssemblerMIPS::CheckSpecialCharacterClass(uc16 type, 251 Label* on_no_match) { 252 UNIMPLEMENTED_MIPS(); 253 return false; 254 } 255 256 257 void RegExpMacroAssemblerMIPS::Fail() { 258 UNIMPLEMENTED_MIPS(); 259 } 260 261 262 Handle<HeapObject> RegExpMacroAssemblerMIPS::GetCode(Handle<String> source) { 263 UNIMPLEMENTED_MIPS(); 264 return Handle<HeapObject>::null(); 265 } 266 267 268 void RegExpMacroAssemblerMIPS::GoTo(Label* to) { 269 UNIMPLEMENTED_MIPS(); 270 } 271 272 273 void RegExpMacroAssemblerMIPS::IfRegisterGE(int reg, 274 int comparand, 275 Label* if_ge) { 276 __ lw(a0, register_location(reg)); 277 BranchOrBacktrack(if_ge, ge, a0, Operand(comparand)); 278 } 279 280 281 void RegExpMacroAssemblerMIPS::IfRegisterLT(int reg, 282 int comparand, 283 Label* if_lt) { 284 UNIMPLEMENTED_MIPS(); 285 } 286 287 288 void RegExpMacroAssemblerMIPS::IfRegisterEqPos(int reg, 289 Label* if_eq) { 290 UNIMPLEMENTED_MIPS(); 291 } 292 293 294 RegExpMacroAssembler::IrregexpImplementation 295 RegExpMacroAssemblerMIPS::Implementation() { 296 return kMIPSImplementation; 297 } 298 299 300 void RegExpMacroAssemblerMIPS::LoadCurrentCharacter(int cp_offset, 301 Label* on_end_of_input, 302 bool check_bounds, 303 int characters) { 304 UNIMPLEMENTED_MIPS(); 305 } 306 307 308 void RegExpMacroAssemblerMIPS::PopCurrentPosition() { 309 UNIMPLEMENTED_MIPS(); 310 } 311 312 313 void RegExpMacroAssemblerMIPS::PopRegister(int register_index) { 314 UNIMPLEMENTED_MIPS(); 315 } 316 317 318 319 void RegExpMacroAssemblerMIPS::PushBacktrack(Label* label) { 320 UNIMPLEMENTED_MIPS(); 321 } 322 323 324 void RegExpMacroAssemblerMIPS::PushCurrentPosition() { 325 Push(current_input_offset()); 326 } 327 328 329 void RegExpMacroAssemblerMIPS::PushRegister(int register_index, 330 StackCheckFlag check_stack_limit) { 331 UNIMPLEMENTED_MIPS(); 332 } 333 334 335 void RegExpMacroAssemblerMIPS::ReadCurrentPositionFromRegister(int reg) { 336 UNIMPLEMENTED_MIPS(); 337 } 338 339 340 void RegExpMacroAssemblerMIPS::ReadStackPointerFromRegister(int reg) { 341 UNIMPLEMENTED_MIPS(); 342 } 343 344 345 void RegExpMacroAssemblerMIPS::SetCurrentPositionFromEnd(int by) { 346 UNIMPLEMENTED_MIPS(); 347 } 348 349 350 void RegExpMacroAssemblerMIPS::SetRegister(int register_index, int to) { 351 UNIMPLEMENTED_MIPS(); 352 } 353 354 355 void RegExpMacroAssemblerMIPS::Succeed() { 356 UNIMPLEMENTED_MIPS(); 357 } 358 359 360 void RegExpMacroAssemblerMIPS::WriteCurrentPositionToRegister(int reg, 361 int cp_offset) { 362 UNIMPLEMENTED_MIPS(); 363 } 364 365 366 void RegExpMacroAssemblerMIPS::ClearRegisters(int reg_from, int reg_to) { 367 UNIMPLEMENTED_MIPS(); 368 } 369 370 371 void RegExpMacroAssemblerMIPS::WriteStackPointerToRegister(int reg) { 372 UNIMPLEMENTED_MIPS(); 373 } 374 375 376 // Private methods: 377 378 void RegExpMacroAssemblerMIPS::CallCheckStackGuardState(Register scratch) { 379 UNIMPLEMENTED_MIPS(); 380 } 381 382 383 // Helper function for reading a value out of a stack frame. 384 template <typename T> 385 static T& frame_entry(Address re_frame, int frame_offset) { 386 return reinterpret_cast<T&>(Memory::int32_at(re_frame + frame_offset)); 387 } 388 389 390 int RegExpMacroAssemblerMIPS::CheckStackGuardState(Address* return_address, 391 Code* re_code, 392 Address re_frame) { 393 UNIMPLEMENTED_MIPS(); 394 return 0; 395 } 396 397 398 MemOperand RegExpMacroAssemblerMIPS::register_location(int register_index) { 399 UNIMPLEMENTED_MIPS(); 400 return MemOperand(zero_reg, 0); 401 } 402 403 404 void RegExpMacroAssemblerMIPS::CheckPosition(int cp_offset, 405 Label* on_outside_input) { 406 UNIMPLEMENTED_MIPS(); 407 } 408 409 410 void RegExpMacroAssemblerMIPS::BranchOrBacktrack(Label* to, 411 Condition condition, 412 Register rs, 413 const Operand& rt) { 414 UNIMPLEMENTED_MIPS(); 415 } 416 417 418 void RegExpMacroAssemblerMIPS::SafeCall(Label* to, Condition cond, Register rs, 419 const Operand& rt) { 420 UNIMPLEMENTED_MIPS(); 421 } 422 423 424 void RegExpMacroAssemblerMIPS::SafeReturn() { 425 UNIMPLEMENTED_MIPS(); 426 } 427 428 429 void RegExpMacroAssemblerMIPS::SafeCallTarget(Label* name) { 430 UNIMPLEMENTED_MIPS(); 431 } 432 433 434 void RegExpMacroAssemblerMIPS::Push(Register source) { 435 UNIMPLEMENTED_MIPS(); 436 } 437 438 439 void RegExpMacroAssemblerMIPS::Pop(Register target) { 440 UNIMPLEMENTED_MIPS(); 441 } 442 443 444 void RegExpMacroAssemblerMIPS::CheckPreemption() { 445 UNIMPLEMENTED_MIPS(); 446 } 447 448 449 void RegExpMacroAssemblerMIPS::CheckStackLimit() { 450 UNIMPLEMENTED_MIPS(); 451 } 452 453 454 void RegExpMacroAssemblerMIPS::CallCFunctionUsingStub( 455 ExternalReference function, 456 int num_arguments) { 457 UNIMPLEMENTED_MIPS(); 458 } 459 460 461 void RegExpMacroAssemblerMIPS::LoadCurrentCharacterUnchecked(int cp_offset, 462 int characters) { 463 UNIMPLEMENTED_MIPS(); 464 } 465 466 467 void RegExpCEntryStub::Generate(MacroAssembler* masm_) { 468 UNIMPLEMENTED_MIPS(); 469 } 470 471 472 #undef __ 473 474 #endif // V8_INTERPRETED_REGEXP 475 476 }} // namespace v8::internal 477 478 #endif // V8_TARGET_ARCH_MIPS 479