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 |