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

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

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