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

Side by Side Diff: src/arm/assembler-arm-inl.h

Issue 356393003: [Arm]: Enable use of extended out-of-line constant pool for Arm. (Closed) Base URL: https://v8.googlecode.com/svn/branches/bleeding_edge
Patch Set: Formatted with git cl format Created 6 years, 5 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch | Annotate | Revision Log
« no previous file with comments | « src/arm/assembler-arm.cc ('k') | src/arm/code-stubs-arm.cc » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
1 // Copyright (c) 1994-2006 Sun Microsystems Inc. 1 // Copyright (c) 1994-2006 Sun Microsystems Inc.
2 // All Rights Reserved. 2 // All Rights Reserved.
3 // 3 //
4 // Redistribution and use in source and binary forms, with or without 4 // Redistribution and use in source and binary forms, with or without
5 // modification, are permitted provided that the following conditions 5 // modification, are permitted provided that the following conditions
6 // are met: 6 // are met:
7 // 7 //
8 // - Redistributions of source code must retain the above copyright notice, 8 // - Redistributions of source code must retain the above copyright notice,
9 // this list of conditions and the following disclaimer. 9 // this list of conditions and the following disclaimer.
10 // 10 //
(...skipping 411 matching lines...) Expand 10 before | Expand all | Expand 10 after
422 422
423 423
424 Address Assembler::target_address_from_return_address(Address pc) { 424 Address Assembler::target_address_from_return_address(Address pc) {
425 // Returns the address of the call target from the return address that will 425 // Returns the address of the call target from the return address that will
426 // be returned to after a call. 426 // be returned to after a call.
427 // Call sequence on V7 or later is : 427 // Call sequence on V7 or later is :
428 // movw ip, #... @ call address low 16 428 // movw ip, #... @ call address low 16
429 // movt ip, #... @ call address high 16 429 // movt ip, #... @ call address high 16
430 // blx ip 430 // blx ip
431 // @ return address 431 // @ return address
432 // Or pre-V7 or cases that need frequent patching: 432 // Or pre-V7 or cases that need frequent patching, the address is in the
433 // ldr ip, [pc, #...] @ call address 433 // constant pool. It could be a small constant pool load:
434 // ldr ip, [pc / pp, #...] @ call address
435 // blx ip
436 // @ return address
437 // Or an extended constant pool load:
438 // movw ip, #...
439 // movt ip, #...
440 // ldr ip, [pc, ip] @ call address
434 // blx ip 441 // blx ip
435 // @ return address 442 // @ return address
436 Address candidate = pc - 2 * Assembler::kInstrSize; 443 Address candidate = pc - 2 * Assembler::kInstrSize;
437 Instr candidate_instr(Memory::int32_at(candidate)); 444 Instr candidate_instr(Memory::int32_at(candidate));
438 if (IsLdrPcImmediateOffset(candidate_instr) | 445 if (IsLdrPcImmediateOffset(candidate_instr) |
439 IsLdrPpImmediateOffset(candidate_instr)) { 446 IsLdrPpImmediateOffset(candidate_instr)) {
440 return candidate; 447 return candidate;
448 } else if (IsLdrPpRegOffset(candidate_instr)) {
449 candidate = pc - 4 * Assembler::kInstrSize;
450 ASSERT(IsMovW(Memory::int32_at(candidate)) &&
451 IsMovT(Memory::int32_at(candidate + Assembler::kInstrSize)));
452 return candidate;
453 } else {
454 candidate = pc - 3 * Assembler::kInstrSize;
455 ASSERT(IsMovW(Memory::int32_at(candidate)) &&
456 IsMovT(Memory::int32_at(candidate + kInstrSize)));
457 return candidate;
441 } 458 }
442 candidate = pc - 3 * Assembler::kInstrSize;
443 ASSERT(IsMovW(Memory::int32_at(candidate)) &&
444 IsMovT(Memory::int32_at(candidate + kInstrSize)));
445 return candidate;
446 } 459 }
447 460
448 461
449 Address Assembler::return_address_from_call_start(Address pc) { 462 Address Assembler::return_address_from_call_start(Address pc) {
450 if (IsLdrPcImmediateOffset(Memory::int32_at(pc)) | 463 if (IsLdrPcImmediateOffset(Memory::int32_at(pc)) |
451 IsLdrPpImmediateOffset(Memory::int32_at(pc))) { 464 IsLdrPpImmediateOffset(Memory::int32_at(pc))) {
465 // Load from constant pool, small section.
452 return pc + kInstrSize * 2; 466 return pc + kInstrSize * 2;
453 } else { 467 } else {
454 ASSERT(IsMovW(Memory::int32_at(pc))); 468 ASSERT(IsMovW(Memory::int32_at(pc)));
455 ASSERT(IsMovT(Memory::int32_at(pc + kInstrSize))); 469 ASSERT(IsMovT(Memory::int32_at(pc + kInstrSize)));
456 return pc + kInstrSize * 3; 470 if (IsLdrPpRegOffset(Memory::int32_at(pc + kInstrSize))) {
471 // Load from constant pool, extended section.
472 return pc + kInstrSize * 4;
473 } else {
474 // A movw / movt load immediate.
475 return pc + kInstrSize * 3;
476 }
457 } 477 }
458 } 478 }
459 479
460 480
461 void Assembler::deserialization_set_special_target_at( 481 void Assembler::deserialization_set_special_target_at(
462 Address constant_pool_entry, Code* code, Address target) { 482 Address constant_pool_entry, Code* code, Address target) {
463 if (FLAG_enable_ool_constant_pool) { 483 if (FLAG_enable_ool_constant_pool) {
464 set_target_address_at(constant_pool_entry, code, target); 484 set_target_address_at(constant_pool_entry, code, target);
465 } else { 485 } else {
466 Memory::Address_at(constant_pool_entry) = target; 486 Memory::Address_at(constant_pool_entry) = target;
467 } 487 }
468 } 488 }
469 489
470 490
471 static Instr EncodeMovwImmediate(uint32_t immediate) { 491 bool Assembler::is_constant_pool_load(Address pc) {
472 ASSERT(immediate < 0x10000); 492 return !Assembler::IsMovW(Memory::int32_at(pc)) ||
473 return ((immediate & 0xf000) << 4) | (immediate & 0xfff); 493 (FLAG_enable_ool_constant_pool &&
494 Assembler::IsLdrPpRegOffset(
495 Memory::int32_at(pc + 2 * Assembler::kInstrSize)));
474 } 496 }
475 497
476 498
477 static Instr PatchMovwImmediate(Instr instruction, uint32_t immediate) {
478 instruction &= ~EncodeMovwImmediate(0xffff);
479 return instruction | EncodeMovwImmediate(immediate);
480 }
481
482
483 static bool IsConstantPoolLoad(Address pc) {
484 return !Assembler::IsMovW(Memory::int32_at(pc));
485 }
486
487
488 Address Assembler::constant_pool_entry_address( 499 Address Assembler::constant_pool_entry_address(
489 Address pc, ConstantPoolArray* constant_pool) { 500 Address pc, ConstantPoolArray* constant_pool) {
490 if (FLAG_enable_ool_constant_pool) { 501 if (FLAG_enable_ool_constant_pool) {
491 ASSERT(constant_pool != NULL); 502 ASSERT(constant_pool != NULL);
492 ASSERT(Assembler::IsLdrPpImmediateOffset(Memory::int32_at(pc))); 503 int cp_offset;
493 return reinterpret_cast<Address>(constant_pool) + 504 if (IsMovW(Memory::int32_at(pc))) {
494 GetLdrRegisterImmediateOffset(Memory::int32_at(pc)); 505 ASSERT(IsMovT(Memory::int32_at(pc + kInstrSize)) &&
506 IsLdrPpRegOffset(Memory::int32_at(pc + 2 * kInstrSize)));
507 // This is an extended constant pool lookup.
508 Instruction* movw_instr = Instruction::At(pc);
509 Instruction* movt_instr = Instruction::At(pc + kInstrSize);
510 cp_offset = (movt_instr->ImmedMovwMovtValue() << 16) |
511 movw_instr->ImmedMovwMovtValue();
512 } else {
513 // This is a small constant pool lookup.
514 ASSERT(Assembler::IsLdrPpImmediateOffset(Memory::int32_at(pc)));
515 cp_offset = GetLdrRegisterImmediateOffset(Memory::int32_at(pc));
516 }
517 return reinterpret_cast<Address>(constant_pool) + cp_offset;
495 } else { 518 } else {
496 ASSERT(Assembler::IsLdrPcImmediateOffset(Memory::int32_at(pc))); 519 ASSERT(Assembler::IsLdrPcImmediateOffset(Memory::int32_at(pc)));
497 Instr instr = Memory::int32_at(pc); 520 Instr instr = Memory::int32_at(pc);
498 return pc + GetLdrRegisterImmediateOffset(instr) + kPcLoadDelta; 521 return pc + GetLdrRegisterImmediateOffset(instr) + kPcLoadDelta;
499 } 522 }
500 } 523 }
501 524
502 525
503 Address Assembler::target_address_at(Address pc, 526 Address Assembler::target_address_at(Address pc,
504 ConstantPoolArray* constant_pool) { 527 ConstantPoolArray* constant_pool) {
505 if (IsConstantPoolLoad(pc)) { 528 if (is_constant_pool_load(pc)) {
506 // This is a constant pool lookup. Return the value in the constant pool. 529 // This is a constant pool lookup. Return the value in the constant pool.
507 return Memory::Address_at(constant_pool_entry_address(pc, constant_pool)); 530 return Memory::Address_at(constant_pool_entry_address(pc, constant_pool));
508 } else { 531 } else {
509 // This is an movw_movt immediate load. Return the immediate. 532 // This is an movw_movt immediate load. Return the immediate.
510 ASSERT(IsMovW(Memory::int32_at(pc)) && 533 ASSERT(IsMovW(Memory::int32_at(pc)) &&
511 IsMovT(Memory::int32_at(pc + kInstrSize))); 534 IsMovT(Memory::int32_at(pc + kInstrSize)));
512 Instruction* movw_instr = Instruction::At(pc); 535 Instruction* movw_instr = Instruction::At(pc);
513 Instruction* movt_instr = Instruction::At(pc + kInstrSize); 536 Instruction* movt_instr = Instruction::At(pc + kInstrSize);
514 return reinterpret_cast<Address>( 537 return reinterpret_cast<Address>(
515 (movt_instr->ImmedMovwMovtValue() << 16) | 538 (movt_instr->ImmedMovwMovtValue() << 16) |
516 movw_instr->ImmedMovwMovtValue()); 539 movw_instr->ImmedMovwMovtValue());
517 } 540 }
518 } 541 }
519 542
520 543
521 void Assembler::set_target_address_at(Address pc, 544 void Assembler::set_target_address_at(Address pc,
522 ConstantPoolArray* constant_pool, 545 ConstantPoolArray* constant_pool,
523 Address target, 546 Address target,
524 ICacheFlushMode icache_flush_mode) { 547 ICacheFlushMode icache_flush_mode) {
525 if (IsConstantPoolLoad(pc)) { 548 if (is_constant_pool_load(pc)) {
526 // This is a constant pool lookup. Update the entry in the constant pool. 549 // This is a constant pool lookup. Update the entry in the constant pool.
527 Memory::Address_at(constant_pool_entry_address(pc, constant_pool)) = target; 550 Memory::Address_at(constant_pool_entry_address(pc, constant_pool)) = target;
528 // Intuitively, we would think it is necessary to always flush the 551 // Intuitively, we would think it is necessary to always flush the
529 // instruction cache after patching a target address in the code as follows: 552 // instruction cache after patching a target address in the code as follows:
530 // CpuFeatures::FlushICache(pc, sizeof(target)); 553 // CpuFeatures::FlushICache(pc, sizeof(target));
531 // However, on ARM, no instruction is actually patched in the case 554 // However, on ARM, no instruction is actually patched in the case
532 // of embedded constants of the form: 555 // of embedded constants of the form:
533 // ldr ip, [pp, #...] 556 // ldr ip, [pp, #...]
534 // since the instruction accessing this address in the constant pool remains 557 // since the instruction accessing this address in the constant pool remains
535 // unchanged. 558 // unchanged.
(...skipping 11 matching lines...) Expand all
547 if (icache_flush_mode != SKIP_ICACHE_FLUSH) { 570 if (icache_flush_mode != SKIP_ICACHE_FLUSH) {
548 CpuFeatures::FlushICache(pc, 2 * kInstrSize); 571 CpuFeatures::FlushICache(pc, 2 * kInstrSize);
549 } 572 }
550 } 573 }
551 } 574 }
552 575
553 576
554 } } // namespace v8::internal 577 } } // namespace v8::internal
555 578
556 #endif // V8_ARM_ASSEMBLER_ARM_INL_H_ 579 #endif // V8_ARM_ASSEMBLER_ARM_INL_H_
OLDNEW
« no previous file with comments | « src/arm/assembler-arm.cc ('k') | src/arm/code-stubs-arm.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698