OLD | NEW |
1 // Copyright 2011 the V8 project authors. All rights reserved. | 1 // Copyright 2011 the V8 project authors. All rights reserved. |
2 // Redistribution and use in source and binary forms, with or without | 2 // Redistribution and use in source and binary forms, with or without |
3 // modification, are permitted provided that the following conditions are | 3 // modification, are permitted provided that the following conditions are |
4 // met: | 4 // met: |
5 // | 5 // |
6 // * Redistributions of source code must retain the above copyright | 6 // * Redistributions of source code must retain the above copyright |
7 // notice, this list of conditions and the following disclaimer. | 7 // notice, this list of conditions and the following disclaimer. |
8 // * Redistributions in binary form must reproduce the above | 8 // * Redistributions in binary form must reproduce the above |
9 // copyright notice, this list of conditions and the following | 9 // copyright notice, this list of conditions and the following |
10 // disclaimer in the documentation and/or other materials provided | 10 // disclaimer in the documentation and/or other materials provided |
(...skipping 406 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
417 Context::SECURITY_TOKEN_INDEX * kPointerSize; | 417 Context::SECURITY_TOKEN_INDEX * kPointerSize; |
418 | 418 |
419 lw(scratch, FieldMemOperand(scratch, token_offset)); | 419 lw(scratch, FieldMemOperand(scratch, token_offset)); |
420 lw(at, FieldMemOperand(at, token_offset)); | 420 lw(at, FieldMemOperand(at, token_offset)); |
421 Branch(miss, ne, scratch, Operand(at)); | 421 Branch(miss, ne, scratch, Operand(at)); |
422 | 422 |
423 bind(&same_contexts); | 423 bind(&same_contexts); |
424 } | 424 } |
425 | 425 |
426 | 426 |
| 427 void MacroAssembler::LoadFromNumberDictionary(Label* miss, |
| 428 Register elements, |
| 429 Register key, |
| 430 Register result, |
| 431 Register reg0, |
| 432 Register reg1, |
| 433 Register reg2) { |
| 434 // Register use: |
| 435 // |
| 436 // elements - holds the slow-case elements of the receiver on entry. |
| 437 // Unchanged unless 'result' is the same register. |
| 438 // |
| 439 // key - holds the smi key on entry. |
| 440 // Unchanged unless 'result' is the same register. |
| 441 // |
| 442 // |
| 443 // result - holds the result on exit if the load succeeded. |
| 444 // Allowed to be the same as 'key' or 'result'. |
| 445 // Unchanged on bailout so 'key' or 'result' can be used |
| 446 // in further computation. |
| 447 // |
| 448 // Scratch registers: |
| 449 // |
| 450 // reg0 - holds the untagged key on entry and holds the hash once computed. |
| 451 // |
| 452 // reg1 - Used to hold the capacity mask of the dictionary. |
| 453 // |
| 454 // reg2 - Used for the index into the dictionary. |
| 455 // at - Temporary (avoid MacroAssembler instructions also using 'at'). |
| 456 Label done; |
| 457 |
| 458 // Compute the hash code from the untagged key. This must be kept in sync |
| 459 // with ComputeIntegerHash in utils.h. |
| 460 // |
| 461 // hash = ~hash + (hash << 15); |
| 462 nor(reg1, reg0, zero_reg); |
| 463 sll(at, reg0, 15); |
| 464 addu(reg0, reg1, at); |
| 465 |
| 466 // hash = hash ^ (hash >> 12); |
| 467 srl(at, reg0, 12); |
| 468 xor_(reg0, reg0, at); |
| 469 |
| 470 // hash = hash + (hash << 2); |
| 471 sll(at, reg0, 2); |
| 472 addu(reg0, reg0, at); |
| 473 |
| 474 // hash = hash ^ (hash >> 4); |
| 475 srl(at, reg0, 4); |
| 476 xor_(reg0, reg0, at); |
| 477 |
| 478 // hash = hash * 2057; |
| 479 li(reg1, Operand(2057)); |
| 480 mul(reg0, reg0, reg1); |
| 481 |
| 482 // hash = hash ^ (hash >> 16); |
| 483 srl(at, reg0, 16); |
| 484 xor_(reg0, reg0, at); |
| 485 |
| 486 // Compute the capacity mask. |
| 487 lw(reg1, FieldMemOperand(elements, NumberDictionary::kCapacityOffset)); |
| 488 sra(reg1, reg1, kSmiTagSize); |
| 489 Subu(reg1, reg1, Operand(1)); |
| 490 |
| 491 // Generate an unrolled loop that performs a few probes before giving up. |
| 492 static const int kProbes = 4; |
| 493 for (int i = 0; i < kProbes; i++) { |
| 494 // Use reg2 for index calculations and keep the hash intact in reg0. |
| 495 mov(reg2, reg0); |
| 496 // Compute the masked index: (hash + i + i * i) & mask. |
| 497 if (i > 0) { |
| 498 Addu(reg2, reg2, Operand(NumberDictionary::GetProbeOffset(i))); |
| 499 } |
| 500 and_(reg2, reg2, reg1); |
| 501 |
| 502 // Scale the index by multiplying by the element size. |
| 503 ASSERT(NumberDictionary::kEntrySize == 3); |
| 504 sll(at, reg2, 1); // 2x. |
| 505 addu(reg2, reg2, at); // reg2 = reg2 * 3. |
| 506 |
| 507 // Check if the key is identical to the name. |
| 508 sll(at, reg2, kPointerSizeLog2); |
| 509 addu(reg2, elements, at); |
| 510 |
| 511 lw(at, FieldMemOperand(reg2, NumberDictionary::kElementsStartOffset)); |
| 512 if (i != kProbes - 1) { |
| 513 Branch(&done, eq, key, Operand(at)); |
| 514 } else { |
| 515 Branch(miss, ne, key, Operand(at)); |
| 516 } |
| 517 } |
| 518 |
| 519 bind(&done); |
| 520 // Check that the value is a normal property. |
| 521 // reg2: elements + (index * kPointerSize). |
| 522 const int kDetailsOffset = |
| 523 NumberDictionary::kElementsStartOffset + 2 * kPointerSize; |
| 524 lw(reg1, FieldMemOperand(reg2, kDetailsOffset)); |
| 525 And(at, reg1, Operand(Smi::FromInt(PropertyDetails::TypeField::mask()))); |
| 526 Branch(miss, ne, at, Operand(zero_reg)); |
| 527 |
| 528 // Get the value at the masked, scaled index and return. |
| 529 const int kValueOffset = |
| 530 NumberDictionary::kElementsStartOffset + kPointerSize; |
| 531 lw(result, FieldMemOperand(reg2, kValueOffset)); |
| 532 } |
| 533 |
| 534 |
427 // --------------------------------------------------------------------------- | 535 // --------------------------------------------------------------------------- |
428 // Instruction macros. | 536 // Instruction macros. |
429 | 537 |
430 void MacroAssembler::Addu(Register rd, Register rs, const Operand& rt) { | 538 void MacroAssembler::Addu(Register rd, Register rs, const Operand& rt) { |
431 if (rt.is_reg()) { | 539 if (rt.is_reg()) { |
432 addu(rd, rs, rt.rm()); | 540 addu(rd, rs, rt.rm()); |
433 } else { | 541 } else { |
434 if (is_int16(rt.imm32_) && !MustUseReg(rt.rmode_)) { | 542 if (is_int16(rt.imm32_) && !MustUseReg(rt.rmode_)) { |
435 addiu(rd, rs, rt.imm32_); | 543 addiu(rd, rs, rt.imm32_); |
436 } else { | 544 } else { |
(...skipping 3795 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
4232 opcode == BGTZL); | 4340 opcode == BGTZL); |
4233 opcode = (cond == eq) ? BEQ : BNE; | 4341 opcode = (cond == eq) ? BEQ : BNE; |
4234 instr = (instr & ~kOpcodeMask) | opcode; | 4342 instr = (instr & ~kOpcodeMask) | opcode; |
4235 masm_.emit(instr); | 4343 masm_.emit(instr); |
4236 } | 4344 } |
4237 | 4345 |
4238 | 4346 |
4239 } } // namespace v8::internal | 4347 } } // namespace v8::internal |
4240 | 4348 |
4241 #endif // V8_TARGET_ARCH_MIPS | 4349 #endif // V8_TARGET_ARCH_MIPS |
OLD | NEW |