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

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

Issue 571173003: PowerPC specific sub-directories (Closed) Base URL: http://v8.googlecode.com/svn/branches/bleeding_edge
Patch Set: Address comments Created 6 years, 1 month 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/ppc/assembler-ppc.cc ('k') | src/ppc/builtins-ppc.cc » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
(Empty)
1 // Copyright (c) 1994-2006 Sun Microsystems Inc.
2 // All Rights Reserved.
3 //
4 // Redistribution and use in source and binary forms, with or without
5 // modification, are permitted provided that the following conditions
6 // are met:
7 //
8 // - Redistributions of source code must retain the above copyright notice,
9 // this list of conditions and the following disclaimer.
10 //
11 // - Redistribution in binary form must reproduce the above copyright
12 // notice, this list of conditions and the following disclaimer in the
13 // documentation and/or other materials provided with the
14 // distribution.
15 //
16 // - Neither the name of Sun Microsystems or the names of contributors may
17 // be used to endorse or promote products derived from this software without
18 // specific prior written permission.
19 //
20 // THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
21 // "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
22 // LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
23 // FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
24 // COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
25 // INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
26 // (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
27 // SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
28 // HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
29 // STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
30 // ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
31 // OF THE POSSIBILITY OF SUCH DAMAGE.
32
33 // The original source code covered by the above license above has been modified
34 // significantly by Google Inc.
35 // Copyright 2014 the V8 project authors. All rights reserved.
36
37 #ifndef V8_PPC_ASSEMBLER_PPC_INL_H_
38 #define V8_PPC_ASSEMBLER_PPC_INL_H_
39
40 #include "src/ppc/assembler-ppc.h"
41
42 #include "src/assembler.h"
43 #include "src/debug.h"
44
45
46 namespace v8 {
47 namespace internal {
48
49
50 bool CpuFeatures::SupportsCrankshaft() { return true; }
51
52
53 void RelocInfo::apply(intptr_t delta, ICacheFlushMode icache_flush_mode) {
54 #if ABI_USES_FUNCTION_DESCRIPTORS || V8_OOL_CONSTANT_POOL
55 if (RelocInfo::IsInternalReference(rmode_)) {
56 // absolute code pointer inside code object moves with the code object.
57 Assembler::RelocateInternalReference(pc_, delta, 0, icache_flush_mode);
58 }
59 #endif
60 // We do not use pc relative addressing on PPC, so there is
61 // nothing else to do.
62 }
63
64
65 Address RelocInfo::target_address() {
66 DCHECK(IsCodeTarget(rmode_) || IsRuntimeEntry(rmode_));
67 return Assembler::target_address_at(pc_, host_);
68 }
69
70
71 Address RelocInfo::target_address_address() {
72 DCHECK(IsCodeTarget(rmode_) || IsRuntimeEntry(rmode_) ||
73 rmode_ == EMBEDDED_OBJECT || rmode_ == EXTERNAL_REFERENCE);
74
75 #if V8_OOL_CONSTANT_POOL
76 if (Assembler::IsConstantPoolLoadStart(pc_)) {
77 // We return the PC for ool constant pool since this function is used by the
78 // serializerer and expects the address to reside within the code object.
79 return reinterpret_cast<Address>(pc_);
80 }
81 #endif
82
83 // Read the address of the word containing the target_address in an
84 // instruction stream.
85 // The only architecture-independent user of this function is the serializer.
86 // The serializer uses it to find out how many raw bytes of instruction to
87 // output before the next target.
88 // For an instruction like LIS/ORI where the target bits are mixed into the
89 // instruction bits, the size of the target will be zero, indicating that the
90 // serializer should not step forward in memory after a target is resolved
91 // and written.
92 return reinterpret_cast<Address>(pc_);
93 }
94
95
96 Address RelocInfo::constant_pool_entry_address() {
97 #if V8_OOL_CONSTANT_POOL
98 return Assembler::target_constant_pool_address_at(pc_,
99 host_->constant_pool());
100 #else
101 UNREACHABLE();
102 return NULL;
103 #endif
104 }
105
106
107 int RelocInfo::target_address_size() { return Assembler::kSpecialTargetSize; }
108
109
110 void RelocInfo::set_target_address(Address target,
111 WriteBarrierMode write_barrier_mode,
112 ICacheFlushMode icache_flush_mode) {
113 DCHECK(IsCodeTarget(rmode_) || IsRuntimeEntry(rmode_));
114 Assembler::set_target_address_at(pc_, host_, target, icache_flush_mode);
115 if (write_barrier_mode == UPDATE_WRITE_BARRIER && host() != NULL &&
116 IsCodeTarget(rmode_)) {
117 Object* target_code = Code::GetCodeFromTargetAddress(target);
118 host()->GetHeap()->incremental_marking()->RecordWriteIntoCode(
119 host(), this, HeapObject::cast(target_code));
120 }
121 }
122
123
124 Address Assembler::break_address_from_return_address(Address pc) {
125 return target_address_from_return_address(pc);
126 }
127
128
129 Address Assembler::target_address_from_return_address(Address pc) {
130 // Returns the address of the call target from the return address that will
131 // be returned to after a call.
132 // Call sequence is :
133 // mov ip, @ call address
134 // mtlr ip
135 // blrl
136 // @ return address
137 #if V8_OOL_CONSTANT_POOL
138 if (IsConstantPoolLoadEnd(pc - 3 * kInstrSize)) {
139 return pc - (kMovInstructionsConstantPool + 2) * kInstrSize;
140 }
141 #endif
142 return pc - (kMovInstructionsNoConstantPool + 2) * kInstrSize;
143 }
144
145
146 Address Assembler::return_address_from_call_start(Address pc) {
147 #if V8_OOL_CONSTANT_POOL
148 Address load_address = pc + (kMovInstructionsConstantPool - 1) * kInstrSize;
149 if (IsConstantPoolLoadEnd(load_address))
150 return pc + (kMovInstructionsConstantPool + 2) * kInstrSize;
151 #endif
152 return pc + (kMovInstructionsNoConstantPool + 2) * kInstrSize;
153 }
154
155
156 Object* RelocInfo::target_object() {
157 DCHECK(IsCodeTarget(rmode_) || rmode_ == EMBEDDED_OBJECT);
158 return reinterpret_cast<Object*>(Assembler::target_address_at(pc_, host_));
159 }
160
161
162 Handle<Object> RelocInfo::target_object_handle(Assembler* origin) {
163 DCHECK(IsCodeTarget(rmode_) || rmode_ == EMBEDDED_OBJECT);
164 return Handle<Object>(
165 reinterpret_cast<Object**>(Assembler::target_address_at(pc_, host_)));
166 }
167
168
169 void RelocInfo::set_target_object(Object* target,
170 WriteBarrierMode write_barrier_mode,
171 ICacheFlushMode icache_flush_mode) {
172 DCHECK(IsCodeTarget(rmode_) || rmode_ == EMBEDDED_OBJECT);
173 Assembler::set_target_address_at(
174 pc_, host_, reinterpret_cast<Address>(target), icache_flush_mode);
175 if (write_barrier_mode == UPDATE_WRITE_BARRIER && host() != NULL &&
176 target->IsHeapObject()) {
177 host()->GetHeap()->incremental_marking()->RecordWrite(
178 host(), &Memory::Object_at(pc_), HeapObject::cast(target));
179 }
180 }
181
182
183 Address RelocInfo::target_reference() {
184 DCHECK(rmode_ == EXTERNAL_REFERENCE);
185 return Assembler::target_address_at(pc_, host_);
186 }
187
188
189 Address RelocInfo::target_runtime_entry(Assembler* origin) {
190 DCHECK(IsRuntimeEntry(rmode_));
191 return target_address();
192 }
193
194
195 void RelocInfo::set_target_runtime_entry(Address target,
196 WriteBarrierMode write_barrier_mode,
197 ICacheFlushMode icache_flush_mode) {
198 DCHECK(IsRuntimeEntry(rmode_));
199 if (target_address() != target)
200 set_target_address(target, write_barrier_mode, icache_flush_mode);
201 }
202
203
204 Handle<Cell> RelocInfo::target_cell_handle() {
205 DCHECK(rmode_ == RelocInfo::CELL);
206 Address address = Memory::Address_at(pc_);
207 return Handle<Cell>(reinterpret_cast<Cell**>(address));
208 }
209
210
211 Cell* RelocInfo::target_cell() {
212 DCHECK(rmode_ == RelocInfo::CELL);
213 return Cell::FromValueAddress(Memory::Address_at(pc_));
214 }
215
216
217 void RelocInfo::set_target_cell(Cell* cell, WriteBarrierMode write_barrier_mode,
218 ICacheFlushMode icache_flush_mode) {
219 DCHECK(rmode_ == RelocInfo::CELL);
220 Address address = cell->address() + Cell::kValueOffset;
221 Memory::Address_at(pc_) = address;
222 if (write_barrier_mode == UPDATE_WRITE_BARRIER && host() != NULL) {
223 // TODO(1550) We are passing NULL as a slot because cell can never be on
224 // evacuation candidate.
225 host()->GetHeap()->incremental_marking()->RecordWrite(host(), NULL, cell);
226 }
227 }
228
229
230 #if V8_OOL_CONSTANT_POOL
231 static const int kNoCodeAgeInstructions = 7;
232 #else
233 static const int kNoCodeAgeInstructions = 6;
234 #endif
235 static const int kCodeAgingInstructions =
236 Assembler::kMovInstructionsNoConstantPool + 3;
237 static const int kNoCodeAgeSequenceInstructions =
238 ((kNoCodeAgeInstructions >= kCodeAgingInstructions)
239 ? kNoCodeAgeInstructions
240 : kCodeAgingInstructions);
241 static const int kNoCodeAgeSequenceNops =
242 (kNoCodeAgeSequenceInstructions - kNoCodeAgeInstructions);
243 static const int kCodeAgingSequenceNops =
244 (kNoCodeAgeSequenceInstructions - kCodeAgingInstructions);
245 static const int kCodeAgingTargetDelta = 1 * Assembler::kInstrSize;
246 static const int kNoCodeAgeSequenceLength =
247 (kNoCodeAgeSequenceInstructions * Assembler::kInstrSize);
248
249
250 Handle<Object> RelocInfo::code_age_stub_handle(Assembler* origin) {
251 UNREACHABLE(); // This should never be reached on PPC.
252 return Handle<Object>();
253 }
254
255
256 Code* RelocInfo::code_age_stub() {
257 DCHECK(rmode_ == RelocInfo::CODE_AGE_SEQUENCE);
258 return Code::GetCodeFromTargetAddress(
259 Assembler::target_address_at(pc_ + kCodeAgingTargetDelta, host_));
260 }
261
262
263 void RelocInfo::set_code_age_stub(Code* stub,
264 ICacheFlushMode icache_flush_mode) {
265 DCHECK(rmode_ == RelocInfo::CODE_AGE_SEQUENCE);
266 Assembler::set_target_address_at(pc_ + kCodeAgingTargetDelta, host_,
267 stub->instruction_start(),
268 icache_flush_mode);
269 }
270
271
272 Address RelocInfo::call_address() {
273 DCHECK((IsJSReturn(rmode()) && IsPatchedReturnSequence()) ||
274 (IsDebugBreakSlot(rmode()) && IsPatchedDebugBreakSlotSequence()));
275 // The pc_ offset of 0 assumes patched return sequence per
276 // BreakLocationIterator::SetDebugBreakAtReturn(), or debug break
277 // slot per BreakLocationIterator::SetDebugBreakAtSlot().
278 return Assembler::target_address_at(pc_, host_);
279 }
280
281
282 void RelocInfo::set_call_address(Address target) {
283 DCHECK((IsJSReturn(rmode()) && IsPatchedReturnSequence()) ||
284 (IsDebugBreakSlot(rmode()) && IsPatchedDebugBreakSlotSequence()));
285 Assembler::set_target_address_at(pc_, host_, target);
286 if (host() != NULL) {
287 Object* target_code = Code::GetCodeFromTargetAddress(target);
288 host()->GetHeap()->incremental_marking()->RecordWriteIntoCode(
289 host(), this, HeapObject::cast(target_code));
290 }
291 }
292
293
294 Object* RelocInfo::call_object() { return *call_object_address(); }
295
296
297 void RelocInfo::set_call_object(Object* target) {
298 *call_object_address() = target;
299 }
300
301
302 Object** RelocInfo::call_object_address() {
303 DCHECK((IsJSReturn(rmode()) && IsPatchedReturnSequence()) ||
304 (IsDebugBreakSlot(rmode()) && IsPatchedDebugBreakSlotSequence()));
305 return reinterpret_cast<Object**>(pc_ + 2 * Assembler::kInstrSize);
306 }
307
308
309 void RelocInfo::WipeOut() {
310 DCHECK(IsEmbeddedObject(rmode_) || IsCodeTarget(rmode_) ||
311 IsRuntimeEntry(rmode_) || IsExternalReference(rmode_));
312 Assembler::set_target_address_at(pc_, host_, NULL);
313 }
314
315
316 bool RelocInfo::IsPatchedReturnSequence() {
317 //
318 // The patched return sequence is defined by
319 // BreakLocationIterator::SetDebugBreakAtReturn()
320 // FIXED_SEQUENCE
321
322 Instr instr0 = Assembler::instr_at(pc_);
323 Instr instr1 = Assembler::instr_at(pc_ + 1 * Assembler::kInstrSize);
324 #if V8_TARGET_ARCH_PPC64
325 Instr instr3 = Assembler::instr_at(pc_ + (3 * Assembler::kInstrSize));
326 Instr instr4 = Assembler::instr_at(pc_ + (4 * Assembler::kInstrSize));
327 Instr binstr = Assembler::instr_at(pc_ + (7 * Assembler::kInstrSize));
328 #else
329 Instr binstr = Assembler::instr_at(pc_ + 4 * Assembler::kInstrSize);
330 #endif
331 bool patched_return =
332 ((instr0 & kOpcodeMask) == ADDIS && (instr1 & kOpcodeMask) == ORI &&
333 #if V8_TARGET_ARCH_PPC64
334 (instr3 & kOpcodeMask) == ORIS && (instr4 & kOpcodeMask) == ORI &&
335 #endif
336 (binstr == 0x7d821008)); // twge r2, r2
337
338 // printf("IsPatchedReturnSequence: %d\n", patched_return);
339 return patched_return;
340 }
341
342
343 bool RelocInfo::IsPatchedDebugBreakSlotSequence() {
344 Instr current_instr = Assembler::instr_at(pc_);
345 return !Assembler::IsNop(current_instr, Assembler::DEBUG_BREAK_NOP);
346 }
347
348
349 void RelocInfo::Visit(Isolate* isolate, ObjectVisitor* visitor) {
350 RelocInfo::Mode mode = rmode();
351 if (mode == RelocInfo::EMBEDDED_OBJECT) {
352 visitor->VisitEmbeddedPointer(this);
353 } else if (RelocInfo::IsCodeTarget(mode)) {
354 visitor->VisitCodeTarget(this);
355 } else if (mode == RelocInfo::CELL) {
356 visitor->VisitCell(this);
357 } else if (mode == RelocInfo::EXTERNAL_REFERENCE) {
358 visitor->VisitExternalReference(this);
359 } else if (RelocInfo::IsCodeAgeSequence(mode)) {
360 visitor->VisitCodeAgeSequence(this);
361 } else if (((RelocInfo::IsJSReturn(mode) && IsPatchedReturnSequence()) ||
362 (RelocInfo::IsDebugBreakSlot(mode) &&
363 IsPatchedDebugBreakSlotSequence())) &&
364 isolate->debug()->has_break_points()) {
365 visitor->VisitDebugTarget(this);
366 } else if (IsRuntimeEntry(mode)) {
367 visitor->VisitRuntimeEntry(this);
368 }
369 }
370
371
372 template <typename StaticVisitor>
373 void RelocInfo::Visit(Heap* heap) {
374 RelocInfo::Mode mode = rmode();
375 if (mode == RelocInfo::EMBEDDED_OBJECT) {
376 StaticVisitor::VisitEmbeddedPointer(heap, this);
377 } else if (RelocInfo::IsCodeTarget(mode)) {
378 StaticVisitor::VisitCodeTarget(heap, this);
379 } else if (mode == RelocInfo::CELL) {
380 StaticVisitor::VisitCell(heap, this);
381 } else if (mode == RelocInfo::EXTERNAL_REFERENCE) {
382 StaticVisitor::VisitExternalReference(this);
383 } else if (RelocInfo::IsCodeAgeSequence(mode)) {
384 StaticVisitor::VisitCodeAgeSequence(heap, this);
385 } else if (heap->isolate()->debug()->has_break_points() &&
386 ((RelocInfo::IsJSReturn(mode) && IsPatchedReturnSequence()) ||
387 (RelocInfo::IsDebugBreakSlot(mode) &&
388 IsPatchedDebugBreakSlotSequence()))) {
389 StaticVisitor::VisitDebugTarget(heap, this);
390 } else if (IsRuntimeEntry(mode)) {
391 StaticVisitor::VisitRuntimeEntry(this);
392 }
393 }
394
395 Operand::Operand(intptr_t immediate, RelocInfo::Mode rmode) {
396 rm_ = no_reg;
397 imm_ = immediate;
398 rmode_ = rmode;
399 }
400
401 Operand::Operand(const ExternalReference& f) {
402 rm_ = no_reg;
403 imm_ = reinterpret_cast<intptr_t>(f.address());
404 rmode_ = RelocInfo::EXTERNAL_REFERENCE;
405 }
406
407 Operand::Operand(Smi* value) {
408 rm_ = no_reg;
409 imm_ = reinterpret_cast<intptr_t>(value);
410 rmode_ = kRelocInfo_NONEPTR;
411 }
412
413 Operand::Operand(Register rm) {
414 rm_ = rm;
415 rmode_ = kRelocInfo_NONEPTR; // PPC -why doesn't ARM do this?
416 }
417
418 void Assembler::CheckBuffer() {
419 if (buffer_space() <= kGap) {
420 GrowBuffer();
421 }
422 }
423
424 void Assembler::CheckTrampolinePoolQuick() {
425 if (pc_offset() >= next_buffer_check_) {
426 CheckTrampolinePool();
427 }
428 }
429
430 void Assembler::emit(Instr x) {
431 CheckBuffer();
432 *reinterpret_cast<Instr*>(pc_) = x;
433 pc_ += kInstrSize;
434 CheckTrampolinePoolQuick();
435 }
436
437 bool Operand::is_reg() const { return rm_.is_valid(); }
438
439
440 // Fetch the 32bit value from the FIXED_SEQUENCE lis/ori
441 Address Assembler::target_address_at(Address pc,
442 ConstantPoolArray* constant_pool) {
443 Instr instr1 = instr_at(pc);
444 Instr instr2 = instr_at(pc + kInstrSize);
445 // Interpret 2 instructions generated by lis/ori
446 if (IsLis(instr1) && IsOri(instr2)) {
447 #if V8_TARGET_ARCH_PPC64
448 Instr instr4 = instr_at(pc + (3 * kInstrSize));
449 Instr instr5 = instr_at(pc + (4 * kInstrSize));
450 // Assemble the 64 bit value.
451 uint64_t hi = (static_cast<uint32_t>((instr1 & kImm16Mask) << 16) |
452 static_cast<uint32_t>(instr2 & kImm16Mask));
453 uint64_t lo = (static_cast<uint32_t>((instr4 & kImm16Mask) << 16) |
454 static_cast<uint32_t>(instr5 & kImm16Mask));
455 return reinterpret_cast<Address>((hi << 32) | lo);
456 #else
457 // Assemble the 32 bit value.
458 return reinterpret_cast<Address>(((instr1 & kImm16Mask) << 16) |
459 (instr2 & kImm16Mask));
460 #endif
461 }
462 #if V8_OOL_CONSTANT_POOL
463 return Memory::Address_at(target_constant_pool_address_at(pc, constant_pool));
464 #else
465 DCHECK(false);
466 return (Address)0;
467 #endif
468 }
469
470
471 #if V8_OOL_CONSTANT_POOL
472 bool Assembler::IsConstantPoolLoadStart(Address pc) {
473 #if V8_TARGET_ARCH_PPC64
474 if (!IsLi(instr_at(pc))) return false;
475 pc += kInstrSize;
476 #endif
477 return GetRA(instr_at(pc)).is(kConstantPoolRegister);
478 }
479
480
481 bool Assembler::IsConstantPoolLoadEnd(Address pc) {
482 #if V8_TARGET_ARCH_PPC64
483 pc -= kInstrSize;
484 #endif
485 return IsConstantPoolLoadStart(pc);
486 }
487
488
489 int Assembler::GetConstantPoolOffset(Address pc) {
490 DCHECK(IsConstantPoolLoadStart(pc));
491 Instr instr = instr_at(pc);
492 int offset = SIGN_EXT_IMM16((instr & kImm16Mask));
493 return offset;
494 }
495
496
497 void Assembler::SetConstantPoolOffset(Address pc, int offset) {
498 DCHECK(IsConstantPoolLoadStart(pc));
499 DCHECK(is_int16(offset));
500 Instr instr = instr_at(pc);
501 instr &= ~kImm16Mask;
502 instr |= (offset & kImm16Mask);
503 instr_at_put(pc, instr);
504 }
505
506
507 Address Assembler::target_constant_pool_address_at(
508 Address pc, ConstantPoolArray* constant_pool) {
509 Address addr = reinterpret_cast<Address>(constant_pool);
510 DCHECK(addr);
511 addr += GetConstantPoolOffset(pc);
512 return addr;
513 }
514 #endif
515
516
517 // This sets the branch destination (which gets loaded at the call address).
518 // This is for calls and branches within generated code. The serializer
519 // has already deserialized the mov instructions etc.
520 // There is a FIXED_SEQUENCE assumption here
521 void Assembler::deserialization_set_special_target_at(
522 Address instruction_payload, Code* code, Address target) {
523 set_target_address_at(instruction_payload, code, target);
524 }
525
526 // This code assumes the FIXED_SEQUENCE of lis/ori
527 void Assembler::set_target_address_at(Address pc,
528 ConstantPoolArray* constant_pool,
529 Address target,
530 ICacheFlushMode icache_flush_mode) {
531 Instr instr1 = instr_at(pc);
532 Instr instr2 = instr_at(pc + kInstrSize);
533 // Interpret 2 instructions generated by lis/ori
534 if (IsLis(instr1) && IsOri(instr2)) {
535 #if V8_TARGET_ARCH_PPC64
536 Instr instr4 = instr_at(pc + (3 * kInstrSize));
537 Instr instr5 = instr_at(pc + (4 * kInstrSize));
538 // Needs to be fixed up when mov changes to handle 64-bit values.
539 uint32_t* p = reinterpret_cast<uint32_t*>(pc);
540 uintptr_t itarget = reinterpret_cast<uintptr_t>(target);
541
542 instr5 &= ~kImm16Mask;
543 instr5 |= itarget & kImm16Mask;
544 itarget = itarget >> 16;
545
546 instr4 &= ~kImm16Mask;
547 instr4 |= itarget & kImm16Mask;
548 itarget = itarget >> 16;
549
550 instr2 &= ~kImm16Mask;
551 instr2 |= itarget & kImm16Mask;
552 itarget = itarget >> 16;
553
554 instr1 &= ~kImm16Mask;
555 instr1 |= itarget & kImm16Mask;
556 itarget = itarget >> 16;
557
558 *p = instr1;
559 *(p + 1) = instr2;
560 *(p + 3) = instr4;
561 *(p + 4) = instr5;
562 if (icache_flush_mode != SKIP_ICACHE_FLUSH) {
563 CpuFeatures::FlushICache(p, 5 * kInstrSize);
564 }
565 #else
566 uint32_t* p = reinterpret_cast<uint32_t*>(pc);
567 uint32_t itarget = reinterpret_cast<uint32_t>(target);
568 int lo_word = itarget & kImm16Mask;
569 int hi_word = itarget >> 16;
570 instr1 &= ~kImm16Mask;
571 instr1 |= hi_word;
572 instr2 &= ~kImm16Mask;
573 instr2 |= lo_word;
574
575 *p = instr1;
576 *(p + 1) = instr2;
577 if (icache_flush_mode != SKIP_ICACHE_FLUSH) {
578 CpuFeatures::FlushICache(p, 2 * kInstrSize);
579 }
580 #endif
581 } else {
582 #if V8_OOL_CONSTANT_POOL
583 Memory::Address_at(target_constant_pool_address_at(pc, constant_pool)) =
584 target;
585 #else
586 UNREACHABLE();
587 #endif
588 }
589 }
590 }
591 } // namespace v8::internal
592
593 #endif // V8_PPC_ASSEMBLER_PPC_INL_H_
OLDNEW
« no previous file with comments | « src/ppc/assembler-ppc.cc ('k') | src/ppc/builtins-ppc.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698