| OLD | NEW |
| 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 57 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 68 | 68 |
| 69 Address RelocInfo::target_address() { | 69 Address RelocInfo::target_address() { |
| 70 DCHECK(IsCodeTarget(rmode_) || IsRuntimeEntry(rmode_)); | 70 DCHECK(IsCodeTarget(rmode_) || IsRuntimeEntry(rmode_)); |
| 71 return Assembler::target_address_at(pc_, host_); | 71 return Assembler::target_address_at(pc_, host_); |
| 72 } | 72 } |
| 73 | 73 |
| 74 Address RelocInfo::target_address_address() { | 74 Address RelocInfo::target_address_address() { |
| 75 DCHECK(IsCodeTarget(rmode_) || IsRuntimeEntry(rmode_) | 75 DCHECK(IsCodeTarget(rmode_) || IsRuntimeEntry(rmode_) |
| 76 || rmode_ == EMBEDDED_OBJECT | 76 || rmode_ == EMBEDDED_OBJECT |
| 77 || rmode_ == EXTERNAL_REFERENCE); | 77 || rmode_ == EXTERNAL_REFERENCE); |
| 78 if (FLAG_enable_embedded_constant_pool || | 78 if (Assembler::IsMovW(Memory::int32_at(pc_))) { |
| 79 Assembler::IsMovW(Memory::int32_at(pc_))) { | |
| 80 // We return the PC for embedded constant pool since this function is used | |
| 81 // by the serializer and expects the address to reside within the code | |
| 82 // object. | |
| 83 return reinterpret_cast<Address>(pc_); | 79 return reinterpret_cast<Address>(pc_); |
| 84 } else { | 80 } else { |
| 85 DCHECK(Assembler::IsLdrPcImmediateOffset(Memory::int32_at(pc_))); | 81 DCHECK(Assembler::IsLdrPcImmediateOffset(Memory::int32_at(pc_))); |
| 86 return constant_pool_entry_address(); | 82 return constant_pool_entry_address(); |
| 87 } | 83 } |
| 88 } | 84 } |
| 89 | 85 |
| 90 | 86 |
| 91 Address RelocInfo::constant_pool_entry_address() { | 87 Address RelocInfo::constant_pool_entry_address() { |
| 92 DCHECK(IsInConstantPool()); | 88 DCHECK(IsInConstantPool()); |
| (...skipping 244 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 337 // @ return address | 333 // @ return address |
| 338 // For V6 when the constant pool is unavailable, it is: | 334 // For V6 when the constant pool is unavailable, it is: |
| 339 // mov ip, #... @ call address low 8 | 335 // mov ip, #... @ call address low 8 |
| 340 // orr ip, ip, #... @ call address 2nd 8 | 336 // orr ip, ip, #... @ call address 2nd 8 |
| 341 // orr ip, ip, #... @ call address 3rd 8 | 337 // orr ip, ip, #... @ call address 3rd 8 |
| 342 // orr ip, ip, #... @ call address high 8 | 338 // orr ip, ip, #... @ call address high 8 |
| 343 // blx ip | 339 // blx ip |
| 344 // @ return address | 340 // @ return address |
| 345 // In cases that need frequent patching, the address is in the | 341 // In cases that need frequent patching, the address is in the |
| 346 // constant pool. It could be a small constant pool load: | 342 // constant pool. It could be a small constant pool load: |
| 347 // ldr ip, [pc / pp, #...] @ call address | 343 // ldr ip, [pc, #...] @ call address |
| 348 // blx ip | |
| 349 // @ return address | |
| 350 // Or an extended constant pool load (ARMv7): | |
| 351 // movw ip, #... | |
| 352 // movt ip, #... | |
| 353 // ldr ip, [pc, ip] @ call address | |
| 354 // blx ip | |
| 355 // @ return address | |
| 356 // Or an extended constant pool load (ARMv6): | |
| 357 // mov ip, #... | |
| 358 // orr ip, ip, #... | |
| 359 // orr ip, ip, #... | |
| 360 // orr ip, ip, #... | |
| 361 // ldr ip, [pc, ip] @ call address | |
| 362 // blx ip | 344 // blx ip |
| 363 // @ return address | 345 // @ return address |
| 364 Address candidate = pc - 2 * Assembler::kInstrSize; | 346 Address candidate = pc - 2 * Assembler::kInstrSize; |
| 365 Instr candidate_instr(Memory::int32_at(candidate)); | 347 Instr candidate_instr(Memory::int32_at(candidate)); |
| 366 if (IsLdrPcImmediateOffset(candidate_instr) | | 348 if (IsLdrPcImmediateOffset(candidate_instr)) { |
| 367 IsLdrPpImmediateOffset(candidate_instr)) { | |
| 368 return candidate; | 349 return candidate; |
| 369 } else { | 350 } else { |
| 370 if (IsLdrPpRegOffset(candidate_instr)) { | |
| 371 candidate -= Assembler::kInstrSize; | |
| 372 } | |
| 373 if (CpuFeatures::IsSupported(ARMv7)) { | 351 if (CpuFeatures::IsSupported(ARMv7)) { |
| 374 candidate -= 1 * Assembler::kInstrSize; | 352 candidate -= 1 * Assembler::kInstrSize; |
| 375 DCHECK(IsMovW(Memory::int32_at(candidate)) && | 353 DCHECK(IsMovW(Memory::int32_at(candidate)) && |
| 376 IsMovT(Memory::int32_at(candidate + Assembler::kInstrSize))); | 354 IsMovT(Memory::int32_at(candidate + Assembler::kInstrSize))); |
| 377 } else { | 355 } else { |
| 378 candidate -= 3 * Assembler::kInstrSize; | 356 candidate -= 3 * Assembler::kInstrSize; |
| 379 DCHECK( | 357 DCHECK( |
| 380 IsMovImmed(Memory::int32_at(candidate)) && | 358 IsMovImmed(Memory::int32_at(candidate)) && |
| 381 IsOrrImmed(Memory::int32_at(candidate + Assembler::kInstrSize)) && | 359 IsOrrImmed(Memory::int32_at(candidate + Assembler::kInstrSize)) && |
| 382 IsOrrImmed(Memory::int32_at(candidate + 2 * Assembler::kInstrSize)) && | 360 IsOrrImmed(Memory::int32_at(candidate + 2 * Assembler::kInstrSize)) && |
| 383 IsOrrImmed(Memory::int32_at(candidate + 3 * Assembler::kInstrSize))); | 361 IsOrrImmed(Memory::int32_at(candidate + 3 * Assembler::kInstrSize))); |
| 384 } | 362 } |
| 385 return candidate; | 363 return candidate; |
| 386 } | 364 } |
| 387 } | 365 } |
| 388 | 366 |
| 389 | 367 |
| 390 Address Assembler::return_address_from_call_start(Address pc) { | 368 Address Assembler::return_address_from_call_start(Address pc) { |
| 391 if (IsLdrPcImmediateOffset(Memory::int32_at(pc)) | | 369 if (IsLdrPcImmediateOffset(Memory::int32_at(pc))) { |
| 392 IsLdrPpImmediateOffset(Memory::int32_at(pc))) { | |
| 393 // Load from constant pool, small section. | 370 // Load from constant pool, small section. |
| 394 return pc + kInstrSize * 2; | 371 return pc + kInstrSize * 2; |
| 395 } else { | 372 } else { |
| 396 if (CpuFeatures::IsSupported(ARMv7)) { | 373 if (CpuFeatures::IsSupported(ARMv7)) { |
| 397 DCHECK(IsMovW(Memory::int32_at(pc))); | 374 DCHECK(IsMovW(Memory::int32_at(pc))); |
| 398 DCHECK(IsMovT(Memory::int32_at(pc + kInstrSize))); | 375 DCHECK(IsMovT(Memory::int32_at(pc + kInstrSize))); |
| 399 if (IsLdrPpRegOffset(Memory::int32_at(pc + 2 * kInstrSize))) { | 376 // A movw / movt load immediate. |
| 400 // Load from constant pool, extended section. | 377 return pc + kInstrSize * 3; |
| 401 return pc + kInstrSize * 4; | |
| 402 } else { | |
| 403 // A movw / movt load immediate. | |
| 404 return pc + kInstrSize * 3; | |
| 405 } | |
| 406 } else { | 378 } else { |
| 407 DCHECK(IsMovImmed(Memory::int32_at(pc))); | 379 DCHECK(IsMovImmed(Memory::int32_at(pc))); |
| 408 DCHECK(IsOrrImmed(Memory::int32_at(pc + kInstrSize))); | 380 DCHECK(IsOrrImmed(Memory::int32_at(pc + kInstrSize))); |
| 409 DCHECK(IsOrrImmed(Memory::int32_at(pc + 2 * kInstrSize))); | 381 DCHECK(IsOrrImmed(Memory::int32_at(pc + 2 * kInstrSize))); |
| 410 DCHECK(IsOrrImmed(Memory::int32_at(pc + 3 * kInstrSize))); | 382 DCHECK(IsOrrImmed(Memory::int32_at(pc + 3 * kInstrSize))); |
| 411 if (IsLdrPpRegOffset(Memory::int32_at(pc + 4 * kInstrSize))) { | 383 // A mov / orr load immediate. |
| 412 // Load from constant pool, extended section. | 384 return pc + kInstrSize * 5; |
| 413 return pc + kInstrSize * 6; | |
| 414 } else { | |
| 415 // A mov / orr load immediate. | |
| 416 return pc + kInstrSize * 5; | |
| 417 } | |
| 418 } | 385 } |
| 419 } | 386 } |
| 420 } | 387 } |
| 421 | 388 |
| 422 | 389 |
| 423 void Assembler::deserialization_set_special_target_at( | 390 void Assembler::deserialization_set_special_target_at( |
| 424 Isolate* isolate, Address constant_pool_entry, Code* code, Address target) { | 391 Isolate* isolate, Address constant_pool_entry, Code* code, Address target) { |
| 425 if (FLAG_enable_embedded_constant_pool) { | 392 Memory::Address_at(constant_pool_entry) = target; |
| 426 set_target_address_at(isolate, constant_pool_entry, code, target); | |
| 427 } else { | |
| 428 Memory::Address_at(constant_pool_entry) = target; | |
| 429 } | |
| 430 } | 393 } |
| 431 | 394 |
| 432 | 395 |
| 433 void Assembler::deserialization_set_target_internal_reference_at( | 396 void Assembler::deserialization_set_target_internal_reference_at( |
| 434 Isolate* isolate, Address pc, Address target, RelocInfo::Mode mode) { | 397 Isolate* isolate, Address pc, Address target, RelocInfo::Mode mode) { |
| 435 Memory::Address_at(pc) = target; | 398 Memory::Address_at(pc) = target; |
| 436 } | 399 } |
| 437 | 400 |
| 438 | 401 |
| 439 bool Assembler::is_constant_pool_load(Address pc) { | 402 bool Assembler::is_constant_pool_load(Address pc) { |
| 440 if (CpuFeatures::IsSupported(ARMv7)) { | 403 if (CpuFeatures::IsSupported(ARMv7)) { |
| 441 return !Assembler::IsMovW(Memory::int32_at(pc)) || | 404 return !Assembler::IsMovW(Memory::int32_at(pc)); |
| 442 (FLAG_enable_embedded_constant_pool && | |
| 443 Assembler::IsLdrPpRegOffset( | |
| 444 Memory::int32_at(pc + 2 * Assembler::kInstrSize))); | |
| 445 } else { | 405 } else { |
| 446 return !Assembler::IsMovImmed(Memory::int32_at(pc)) || | 406 return !Assembler::IsMovImmed(Memory::int32_at(pc)); |
| 447 (FLAG_enable_embedded_constant_pool && | |
| 448 Assembler::IsLdrPpRegOffset( | |
| 449 Memory::int32_at(pc + 4 * Assembler::kInstrSize))); | |
| 450 } | 407 } |
| 451 } | 408 } |
| 452 | 409 |
| 453 | 410 |
| 454 Address Assembler::constant_pool_entry_address(Address pc, | 411 Address Assembler::constant_pool_entry_address(Address pc, |
| 455 Address constant_pool) { | 412 Address constant_pool) { |
| 456 if (FLAG_enable_embedded_constant_pool) { | 413 DCHECK(Assembler::IsLdrPcImmediateOffset(Memory::int32_at(pc))); |
| 457 DCHECK(constant_pool != NULL); | 414 Instr instr = Memory::int32_at(pc); |
| 458 int cp_offset; | 415 return pc + GetLdrRegisterImmediateOffset(instr) + kPcLoadDelta; |
| 459 if (!CpuFeatures::IsSupported(ARMv7) && IsMovImmed(Memory::int32_at(pc))) { | |
| 460 DCHECK(IsOrrImmed(Memory::int32_at(pc + kInstrSize)) && | |
| 461 IsOrrImmed(Memory::int32_at(pc + 2 * kInstrSize)) && | |
| 462 IsOrrImmed(Memory::int32_at(pc + 3 * kInstrSize)) && | |
| 463 IsLdrPpRegOffset(Memory::int32_at(pc + 4 * kInstrSize))); | |
| 464 // This is an extended constant pool lookup (ARMv6). | |
| 465 Instr mov_instr = instr_at(pc); | |
| 466 Instr orr_instr_1 = instr_at(pc + kInstrSize); | |
| 467 Instr orr_instr_2 = instr_at(pc + 2 * kInstrSize); | |
| 468 Instr orr_instr_3 = instr_at(pc + 3 * kInstrSize); | |
| 469 cp_offset = DecodeShiftImm(mov_instr) | DecodeShiftImm(orr_instr_1) | | |
| 470 DecodeShiftImm(orr_instr_2) | DecodeShiftImm(orr_instr_3); | |
| 471 } else if (IsMovW(Memory::int32_at(pc))) { | |
| 472 DCHECK(IsMovT(Memory::int32_at(pc + kInstrSize)) && | |
| 473 IsLdrPpRegOffset(Memory::int32_at(pc + 2 * kInstrSize))); | |
| 474 // This is an extended constant pool lookup (ARMv7). | |
| 475 Instruction* movw_instr = Instruction::At(pc); | |
| 476 Instruction* movt_instr = Instruction::At(pc + kInstrSize); | |
| 477 cp_offset = (movt_instr->ImmedMovwMovtValue() << 16) | | |
| 478 movw_instr->ImmedMovwMovtValue(); | |
| 479 } else { | |
| 480 // This is a small constant pool lookup. | |
| 481 DCHECK(Assembler::IsLdrPpImmediateOffset(Memory::int32_at(pc))); | |
| 482 cp_offset = GetLdrRegisterImmediateOffset(Memory::int32_at(pc)); | |
| 483 } | |
| 484 return constant_pool + cp_offset; | |
| 485 } else { | |
| 486 DCHECK(Assembler::IsLdrPcImmediateOffset(Memory::int32_at(pc))); | |
| 487 Instr instr = Memory::int32_at(pc); | |
| 488 return pc + GetLdrRegisterImmediateOffset(instr) + kPcLoadDelta; | |
| 489 } | |
| 490 } | 416 } |
| 491 | 417 |
| 492 | 418 |
| 493 Address Assembler::target_address_at(Address pc, Address constant_pool) { | 419 Address Assembler::target_address_at(Address pc, Address constant_pool) { |
| 494 if (is_constant_pool_load(pc)) { | 420 if (is_constant_pool_load(pc)) { |
| 495 // This is a constant pool lookup. Return the value in the constant pool. | 421 // This is a constant pool lookup. Return the value in the constant pool. |
| 496 return Memory::Address_at(constant_pool_entry_address(pc, constant_pool)); | 422 return Memory::Address_at(constant_pool_entry_address(pc, constant_pool)); |
| 497 } else if (CpuFeatures::IsSupported(ARMv7)) { | 423 } else if (CpuFeatures::IsSupported(ARMv7)) { |
| 498 // This is an movw / movt immediate load. Return the immediate. | 424 // This is an movw / movt immediate load. Return the immediate. |
| 499 DCHECK(IsMovW(Memory::int32_at(pc)) && | 425 DCHECK(IsMovW(Memory::int32_at(pc)) && |
| (...skipping 84 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 584 Address constant_pool = code ? code->constant_pool() : NULL; | 510 Address constant_pool = code ? code->constant_pool() : NULL; |
| 585 set_target_address_at(isolate, pc, constant_pool, target, icache_flush_mode); | 511 set_target_address_at(isolate, pc, constant_pool, target, icache_flush_mode); |
| 586 } | 512 } |
| 587 | 513 |
| 588 EnsureSpace::EnsureSpace(Assembler* assembler) { assembler->CheckBuffer(); } | 514 EnsureSpace::EnsureSpace(Assembler* assembler) { assembler->CheckBuffer(); } |
| 589 | 515 |
| 590 } // namespace internal | 516 } // namespace internal |
| 591 } // namespace v8 | 517 } // namespace v8 |
| 592 | 518 |
| 593 #endif // V8_ARM_ASSEMBLER_ARM_INL_H_ | 519 #endif // V8_ARM_ASSEMBLER_ARM_INL_H_ |
| OLD | NEW |