| OLD | NEW |
| 1 | 1 |
| 2 // Copyright (c) 1994-2006 Sun Microsystems Inc. | 2 // Copyright (c) 1994-2006 Sun Microsystems Inc. |
| 3 // All Rights Reserved. | 3 // All Rights Reserved. |
| 4 // | 4 // |
| 5 // Redistribution and use in source and binary forms, with or without | 5 // Redistribution and use in source and binary forms, with or without |
| 6 // modification, are permitted provided that the following conditions are | 6 // modification, are permitted provided that the following conditions are |
| 7 // met: | 7 // met: |
| 8 // | 8 // |
| 9 // - Redistributions of source code must retain the above copyright notice, | 9 // - Redistributions of source code must retain the above copyright notice, |
| 10 // this list of conditions and the following disclaimer. | 10 // this list of conditions and the following disclaimer. |
| (...skipping 19 matching lines...) Expand all Loading... |
| 30 // SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. | 30 // SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. |
| 31 | 31 |
| 32 // The original source code covered by the above license above has been | 32 // The original source code covered by the above license above has been |
| 33 // modified significantly by Google Inc. | 33 // modified significantly by Google Inc. |
| 34 // Copyright 2012 the V8 project authors. All rights reserved. | 34 // Copyright 2012 the V8 project authors. All rights reserved. |
| 35 | 35 |
| 36 | 36 |
| 37 #ifndef V8_MIPS_ASSEMBLER_MIPS_INL_H_ | 37 #ifndef V8_MIPS_ASSEMBLER_MIPS_INL_H_ |
| 38 #define V8_MIPS_ASSEMBLER_MIPS_INL_H_ | 38 #define V8_MIPS_ASSEMBLER_MIPS_INL_H_ |
| 39 | 39 |
| 40 #include "src/mips/assembler-mips.h" | 40 #include "src/mips64/assembler-mips64.h" |
| 41 | 41 |
| 42 #include "src/assembler.h" | 42 #include "src/assembler.h" |
| 43 #include "src/debug.h" | 43 #include "src/debug.h" |
| 44 | 44 |
| 45 | 45 |
| 46 namespace v8 { | 46 namespace v8 { |
| 47 namespace internal { | 47 namespace internal { |
| 48 | 48 |
| 49 | 49 |
| 50 bool CpuFeatures::SupportsCrankshaft() { return IsSupported(FPU); } | 50 bool CpuFeatures::SupportsCrankshaft() { return IsSupported(FPU); } |
| 51 | 51 |
| 52 | 52 |
| 53 // ----------------------------------------------------------------------------- | 53 // ----------------------------------------------------------------------------- |
| 54 // Operand and MemOperand. | 54 // Operand and MemOperand. |
| 55 | 55 |
| 56 Operand::Operand(int32_t immediate, RelocInfo::Mode rmode) { | 56 Operand::Operand(int64_t immediate, RelocInfo::Mode rmode) { |
| 57 rm_ = no_reg; | 57 rm_ = no_reg; |
| 58 imm32_ = immediate; | 58 imm64_ = immediate; |
| 59 rmode_ = rmode; | 59 rmode_ = rmode; |
| 60 } | 60 } |
| 61 | 61 |
| 62 | 62 |
| 63 Operand::Operand(const ExternalReference& f) { | 63 Operand::Operand(const ExternalReference& f) { |
| 64 rm_ = no_reg; | 64 rm_ = no_reg; |
| 65 imm32_ = reinterpret_cast<int32_t>(f.address()); | 65 imm64_ = reinterpret_cast<int64_t>(f.address()); |
| 66 rmode_ = RelocInfo::EXTERNAL_REFERENCE; | 66 rmode_ = RelocInfo::EXTERNAL_REFERENCE; |
| 67 } | 67 } |
| 68 | 68 |
| 69 | 69 |
| 70 Operand::Operand(Smi* value) { | 70 Operand::Operand(Smi* value) { |
| 71 rm_ = no_reg; | 71 rm_ = no_reg; |
| 72 imm32_ = reinterpret_cast<intptr_t>(value); | 72 imm64_ = reinterpret_cast<intptr_t>(value); |
| 73 rmode_ = RelocInfo::NONE32; | 73 rmode_ = RelocInfo::NONE32; |
| 74 } | 74 } |
| 75 | 75 |
| 76 | 76 |
| 77 Operand::Operand(Register rm) { | 77 Operand::Operand(Register rm) { |
| 78 rm_ = rm; | 78 rm_ = rm; |
| 79 } | 79 } |
| 80 | 80 |
| 81 | 81 |
| 82 bool Operand::is_reg() const { | 82 bool Operand::is_reg() const { |
| (...skipping 23 matching lines...) Expand all Loading... |
| 106 ASSERT(!reg.is(kDoubleRegZero)); | 106 ASSERT(!reg.is(kDoubleRegZero)); |
| 107 ASSERT(!reg.is(kLithiumScratchDouble)); | 107 ASSERT(!reg.is(kLithiumScratchDouble)); |
| 108 return (reg.code() / 2); | 108 return (reg.code() / 2); |
| 109 } | 109 } |
| 110 | 110 |
| 111 | 111 |
| 112 // ----------------------------------------------------------------------------- | 112 // ----------------------------------------------------------------------------- |
| 113 // RelocInfo. | 113 // RelocInfo. |
| 114 | 114 |
| 115 void RelocInfo::apply(intptr_t delta, ICacheFlushMode icache_flush_mode) { | 115 void RelocInfo::apply(intptr_t delta, ICacheFlushMode icache_flush_mode) { |
| 116 if (IsCodeTarget(rmode_)) { | |
| 117 uint32_t scope1 = (uint32_t) target_address() & ~kImm28Mask; | |
| 118 uint32_t scope2 = reinterpret_cast<uint32_t>(pc_) & ~kImm28Mask; | |
| 119 | |
| 120 if (scope1 != scope2) { | |
| 121 Assembler::JumpLabelToJumpRegister(pc_); | |
| 122 } | |
| 123 } | |
| 124 if (IsInternalReference(rmode_)) { | 116 if (IsInternalReference(rmode_)) { |
| 125 // Absolute code pointer inside code object moves with the code object. | 117 // Absolute code pointer inside code object moves with the code object. |
| 126 byte* p = reinterpret_cast<byte*>(pc_); | 118 byte* p = reinterpret_cast<byte*>(pc_); |
| 127 int count = Assembler::RelocateInternalReference(p, delta); | 119 int count = Assembler::RelocateInternalReference(p, delta); |
| 128 CpuFeatures::FlushICache(p, count * sizeof(uint32_t)); | 120 CpuFeatures::FlushICache(p, count * sizeof(uint32_t)); |
| 129 } | 121 } |
| 130 } | 122 } |
| 131 | 123 |
| 132 | 124 |
| 133 Address RelocInfo::target_address() { | 125 Address RelocInfo::target_address() { |
| (...skipping 14 matching lines...) Expand all Loading... |
| 148 // output before the next target. | 140 // output before the next target. |
| 149 // For an instruction like LUI/ORI where the target bits are mixed into the | 141 // For an instruction like LUI/ORI where the target bits are mixed into the |
| 150 // instruction bits, the size of the target will be zero, indicating that the | 142 // instruction bits, the size of the target will be zero, indicating that the |
| 151 // serializer should not step forward in memory after a target is resolved | 143 // serializer should not step forward in memory after a target is resolved |
| 152 // and written. In this case the target_address_address function should | 144 // and written. In this case the target_address_address function should |
| 153 // return the end of the instructions to be patched, allowing the | 145 // return the end of the instructions to be patched, allowing the |
| 154 // deserializer to deserialize the instructions as raw bytes and put them in | 146 // deserializer to deserialize the instructions as raw bytes and put them in |
| 155 // place, ready to be patched with the target. After jump optimization, | 147 // place, ready to be patched with the target. After jump optimization, |
| 156 // that is the address of the instruction that follows J/JAL/JR/JALR | 148 // that is the address of the instruction that follows J/JAL/JR/JALR |
| 157 // instruction. | 149 // instruction. |
| 150 // return reinterpret_cast<Address>( |
| 151 // pc_ + Assembler::kInstructionsFor32BitConstant * Assembler::kInstrSize); |
| 158 return reinterpret_cast<Address>( | 152 return reinterpret_cast<Address>( |
| 159 pc_ + Assembler::kInstructionsFor32BitConstant * Assembler::kInstrSize); | 153 pc_ + Assembler::kInstructionsFor64BitConstant * Assembler::kInstrSize); |
| 160 } | 154 } |
| 161 | 155 |
| 162 | 156 |
| 163 Address RelocInfo::constant_pool_entry_address() { | 157 Address RelocInfo::constant_pool_entry_address() { |
| 164 UNREACHABLE(); | 158 UNREACHABLE(); |
| 165 return NULL; | 159 return NULL; |
| 166 } | 160 } |
| 167 | 161 |
| 168 | 162 |
| 169 int RelocInfo::target_address_size() { | 163 int RelocInfo::target_address_size() { |
| (...skipping 92 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 262 Memory::Address_at(pc_) = address; | 256 Memory::Address_at(pc_) = address; |
| 263 if (write_barrier_mode == UPDATE_WRITE_BARRIER && host() != NULL) { | 257 if (write_barrier_mode == UPDATE_WRITE_BARRIER && host() != NULL) { |
| 264 // TODO(1550) We are passing NULL as a slot because cell can never be on | 258 // TODO(1550) We are passing NULL as a slot because cell can never be on |
| 265 // evacuation candidate. | 259 // evacuation candidate. |
| 266 host()->GetHeap()->incremental_marking()->RecordWrite( | 260 host()->GetHeap()->incremental_marking()->RecordWrite( |
| 267 host(), NULL, cell); | 261 host(), NULL, cell); |
| 268 } | 262 } |
| 269 } | 263 } |
| 270 | 264 |
| 271 | 265 |
| 272 static const int kNoCodeAgeSequenceLength = 7 * Assembler::kInstrSize; | 266 static const int kNoCodeAgeSequenceLength = 9 * Assembler::kInstrSize; |
| 273 | 267 |
| 274 | 268 |
| 275 Handle<Object> RelocInfo::code_age_stub_handle(Assembler* origin) { | 269 Handle<Object> RelocInfo::code_age_stub_handle(Assembler* origin) { |
| 276 UNREACHABLE(); // This should never be reached on Arm. | 270 UNREACHABLE(); // This should never be reached on Arm. |
| 277 return Handle<Object>(); | 271 return Handle<Object>(); |
| 278 } | 272 } |
| 279 | 273 |
| 280 | 274 |
| 281 Code* RelocInfo::code_age_stub() { | 275 Code* RelocInfo::code_age_stub() { |
| 282 ASSERT(rmode_ == RelocInfo::CODE_AGE_SEQUENCE); | 276 ASSERT(rmode_ == RelocInfo::CODE_AGE_SEQUENCE); |
| (...skipping 37 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 320 | 314 |
| 321 | 315 |
| 322 Object* RelocInfo::call_object() { | 316 Object* RelocInfo::call_object() { |
| 323 return *call_object_address(); | 317 return *call_object_address(); |
| 324 } | 318 } |
| 325 | 319 |
| 326 | 320 |
| 327 Object** RelocInfo::call_object_address() { | 321 Object** RelocInfo::call_object_address() { |
| 328 ASSERT((IsJSReturn(rmode()) && IsPatchedReturnSequence()) || | 322 ASSERT((IsJSReturn(rmode()) && IsPatchedReturnSequence()) || |
| 329 (IsDebugBreakSlot(rmode()) && IsPatchedDebugBreakSlotSequence())); | 323 (IsDebugBreakSlot(rmode()) && IsPatchedDebugBreakSlotSequence())); |
| 330 return reinterpret_cast<Object**>(pc_ + 2 * Assembler::kInstrSize); | 324 return reinterpret_cast<Object**>(pc_ + 6 * Assembler::kInstrSize); |
| 331 } | 325 } |
| 332 | 326 |
| 333 | 327 |
| 334 void RelocInfo::set_call_object(Object* target) { | 328 void RelocInfo::set_call_object(Object* target) { |
| 335 *call_object_address() = target; | 329 *call_object_address() = target; |
| 336 } | 330 } |
| 337 | 331 |
| 338 | 332 |
| 339 void RelocInfo::WipeOut() { | 333 void RelocInfo::WipeOut() { |
| 340 ASSERT(IsEmbeddedObject(rmode_) || | 334 ASSERT(IsEmbeddedObject(rmode_) || |
| 341 IsCodeTarget(rmode_) || | 335 IsCodeTarget(rmode_) || |
| 342 IsRuntimeEntry(rmode_) || | 336 IsRuntimeEntry(rmode_) || |
| 343 IsExternalReference(rmode_)); | 337 IsExternalReference(rmode_)); |
| 344 Assembler::set_target_address_at(pc_, host_, NULL); | 338 Assembler::set_target_address_at(pc_, host_, NULL); |
| 345 } | 339 } |
| 346 | 340 |
| 347 | 341 |
| 348 bool RelocInfo::IsPatchedReturnSequence() { | 342 bool RelocInfo::IsPatchedReturnSequence() { |
| 349 Instr instr0 = Assembler::instr_at(pc_); | 343 Instr instr0 = Assembler::instr_at(pc_); // lui. |
| 350 Instr instr1 = Assembler::instr_at(pc_ + 1 * Assembler::kInstrSize); | 344 Instr instr1 = Assembler::instr_at(pc_ + 1 * Assembler::kInstrSize); // ori. |
| 351 Instr instr2 = Assembler::instr_at(pc_ + 2 * Assembler::kInstrSize); | 345 Instr instr2 = Assembler::instr_at(pc_ + 2 * Assembler::kInstrSize); // dsll. |
| 346 Instr instr3 = Assembler::instr_at(pc_ + 3 * Assembler::kInstrSize); // ori. |
| 347 Instr instr4 = Assembler::instr_at(pc_ + 4 * Assembler::kInstrSize); // jalr. |
| 348 |
| 352 bool patched_return = ((instr0 & kOpcodeMask) == LUI && | 349 bool patched_return = ((instr0 & kOpcodeMask) == LUI && |
| 353 (instr1 & kOpcodeMask) == ORI && | 350 (instr1 & kOpcodeMask) == ORI && |
| 354 ((instr2 & kOpcodeMask) == JAL || | 351 (instr2 & kFunctionFieldMask) == DSLL && |
| 355 ((instr2 & kOpcodeMask) == SPECIAL && | 352 (instr3 & kOpcodeMask) == ORI && |
| 356 (instr2 & kFunctionFieldMask) == JALR))); | 353 (instr4 & kFunctionFieldMask) == JALR); |
| 357 return patched_return; | 354 return patched_return; |
| 358 } | 355 } |
| 359 | 356 |
| 360 | 357 |
| 361 bool RelocInfo::IsPatchedDebugBreakSlotSequence() { | 358 bool RelocInfo::IsPatchedDebugBreakSlotSequence() { |
| 362 Instr current_instr = Assembler::instr_at(pc_); | 359 Instr current_instr = Assembler::instr_at(pc_); |
| 363 return !Assembler::IsNop(current_instr, Assembler::DEBUG_BREAK_NOP); | 360 return !Assembler::IsNop(current_instr, Assembler::DEBUG_BREAK_NOP); |
| 364 } | 361 } |
| 365 | 362 |
| 366 | 363 |
| (...skipping 67 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 434 void Assembler::emit(Instr x) { | 431 void Assembler::emit(Instr x) { |
| 435 if (!is_buffer_growth_blocked()) { | 432 if (!is_buffer_growth_blocked()) { |
| 436 CheckBuffer(); | 433 CheckBuffer(); |
| 437 } | 434 } |
| 438 *reinterpret_cast<Instr*>(pc_) = x; | 435 *reinterpret_cast<Instr*>(pc_) = x; |
| 439 pc_ += kInstrSize; | 436 pc_ += kInstrSize; |
| 440 CheckTrampolinePoolQuick(); | 437 CheckTrampolinePoolQuick(); |
| 441 } | 438 } |
| 442 | 439 |
| 443 | 440 |
| 441 void Assembler::emit(uint64_t x) { |
| 442 if (!is_buffer_growth_blocked()) { |
| 443 CheckBuffer(); |
| 444 } |
| 445 *reinterpret_cast<uint64_t*>(pc_) = x; |
| 446 pc_ += kInstrSize * 2; |
| 447 CheckTrampolinePoolQuick(); |
| 448 } |
| 449 |
| 450 |
| 444 } } // namespace v8::internal | 451 } } // namespace v8::internal |
| 445 | 452 |
| 446 #endif // V8_MIPS_ASSEMBLER_MIPS_INL_H_ | 453 #endif // V8_MIPS_ASSEMBLER_MIPS_INL_H_ |
| OLD | NEW |