Index: src/ppc/code-stubs-ppc.h |
diff --git a/src/arm/code-stubs-arm.h b/src/ppc/code-stubs-ppc.h |
similarity index 57% |
copy from src/arm/code-stubs-arm.h |
copy to src/ppc/code-stubs-ppc.h |
index 727bb1b22703cfee80acdbbdddb3747dedc2d128..e4eed516181856793ee15cdbd0b1664c3d4bae24 100644 |
--- a/src/arm/code-stubs-arm.h |
+++ b/src/ppc/code-stubs-ppc.h |
@@ -1,9 +1,9 @@ |
-// Copyright 2012 the V8 project authors. All rights reserved. |
+// Copyright 2014 the V8 project authors. All rights reserved. |
// Use of this source code is governed by a BSD-style license that can be |
// found in the LICENSE file. |
-#ifndef V8_ARM_CODE_STUBS_ARM_H_ |
-#define V8_ARM_CODE_STUBS_ARM_H_ |
+#ifndef V8_PPC_CODE_STUBS_PPC_H_ |
+#define V8_PPC_CODE_STUBS_PPC_H_ |
namespace v8 { |
namespace internal { |
@@ -18,79 +18,65 @@ class StringHelper : public AllStatic { |
// is allowed to spend extra time setting up conditions to make copying |
// faster. Copying of overlapping regions is not supported. |
// Dest register ends at the position after the last character written. |
- static void GenerateCopyCharacters(MacroAssembler* masm, |
- Register dest, |
- Register src, |
- Register count, |
+ static void GenerateCopyCharacters(MacroAssembler* masm, Register dest, |
+ Register src, Register count, |
Register scratch, |
String::Encoding encoding); |
// Compares two flat one-byte strings and returns result in r0. |
- static void GenerateCompareFlatOneByteStrings( |
- MacroAssembler* masm, Register left, Register right, Register scratch1, |
- Register scratch2, Register scratch3, Register scratch4); |
+ static void GenerateCompareFlatOneByteStrings(MacroAssembler* masm, |
+ Register left, Register right, |
+ Register scratch1, |
+ Register scratch2, |
+ Register scratch3); |
// Compares two flat one-byte strings for equality and returns result in r0. |
static void GenerateFlatOneByteStringEquals(MacroAssembler* masm, |
Register left, Register right, |
Register scratch1, |
- Register scratch2, |
- Register scratch3); |
+ Register scratch2); |
private: |
- static void GenerateOneByteCharsCompareLoop( |
- MacroAssembler* masm, Register left, Register right, Register length, |
- Register scratch1, Register scratch2, Label* chars_not_equal); |
+ static void GenerateOneByteCharsCompareLoop(MacroAssembler* masm, |
+ Register left, Register right, |
+ Register length, |
+ Register scratch1, |
+ Label* chars_not_equal); |
DISALLOW_IMPLICIT_CONSTRUCTORS(StringHelper); |
}; |
-// This stub can convert a signed int32 to a heap number (double). It does |
-// not work for int32s that are in Smi range! No GC occurs during this stub |
-// so you don't have to set up the frame. |
-class WriteInt32ToHeapNumberStub : public PlatformCodeStub { |
+class StoreRegistersStateStub : public PlatformCodeStub { |
public: |
- WriteInt32ToHeapNumberStub(Isolate* isolate, Register the_int, |
- Register the_heap_number, Register scratch) |
- : PlatformCodeStub(isolate) { |
- minor_key_ = IntRegisterBits::encode(the_int.code()) | |
- HeapNumberRegisterBits::encode(the_heap_number.code()) | |
- ScratchRegisterBits::encode(scratch.code()); |
- } |
+ explicit StoreRegistersStateStub(Isolate* isolate) |
+ : PlatformCodeStub(isolate) {} |
- static void GenerateFixedRegStubsAheadOfTime(Isolate* isolate); |
+ static void GenerateAheadOfTime(Isolate* isolate); |
private: |
- Register the_int() const { |
- return Register::from_code(IntRegisterBits::decode(minor_key_)); |
- } |
+ DEFINE_NULL_CALL_INTERFACE_DESCRIPTOR(); |
+ DEFINE_PLATFORM_CODE_STUB(StoreRegistersState, PlatformCodeStub); |
+}; |
- Register the_heap_number() const { |
- return Register::from_code(HeapNumberRegisterBits::decode(minor_key_)); |
- } |
- Register scratch() const { |
- return Register::from_code(ScratchRegisterBits::decode(minor_key_)); |
- } |
+class RestoreRegistersStateStub : public PlatformCodeStub { |
+ public: |
+ explicit RestoreRegistersStateStub(Isolate* isolate) |
+ : PlatformCodeStub(isolate) {} |
- // Minor key encoding in 16 bits. |
- class IntRegisterBits: public BitField<int, 0, 4> {}; |
- class HeapNumberRegisterBits: public BitField<int, 4, 4> {}; |
- class ScratchRegisterBits: public BitField<int, 8, 4> {}; |
+ static void GenerateAheadOfTime(Isolate* isolate); |
+ private: |
DEFINE_NULL_CALL_INTERFACE_DESCRIPTOR(); |
- DEFINE_PLATFORM_CODE_STUB(WriteInt32ToHeapNumber, PlatformCodeStub); |
+ DEFINE_PLATFORM_CODE_STUB(RestoreRegistersState, PlatformCodeStub); |
}; |
-class RecordWriteStub: public PlatformCodeStub { |
+class RecordWriteStub : public PlatformCodeStub { |
public: |
- RecordWriteStub(Isolate* isolate, |
- Register object, |
- Register value, |
- Register address, |
- RememberedSetAction remembered_set_action, |
+ RecordWriteStub(Isolate* isolate, Register object, Register value, |
+ Register address, RememberedSetAction remembered_set_action, |
SaveFPRegsMode fp_mode) |
: PlatformCodeStub(isolate), |
regs_(object, // An input reg. |
@@ -106,66 +92,60 @@ class RecordWriteStub: public PlatformCodeStub { |
RecordWriteStub(uint32_t key, Isolate* isolate) |
: PlatformCodeStub(key, isolate), regs_(object(), address(), value()) {} |
- enum Mode { |
- STORE_BUFFER_ONLY, |
- INCREMENTAL, |
- INCREMENTAL_COMPACTION |
- }; |
+ enum Mode { STORE_BUFFER_ONLY, INCREMENTAL, INCREMENTAL_COMPACTION }; |
virtual bool SometimesSetsUpAFrame() { return false; } |
static void PatchBranchIntoNop(MacroAssembler* masm, int pos) { |
- masm->instr_at_put(pos, (masm->instr_at(pos) & ~B27) | (B24 | B20)); |
- DCHECK(Assembler::IsTstImmediate(masm->instr_at(pos))); |
+ // Consider adding DCHECK here to catch bad patching |
+ masm->instr_at_put(pos, (masm->instr_at(pos) & ~kBOfieldMask) | BT); |
} |
static void PatchNopIntoBranch(MacroAssembler* masm, int pos) { |
- masm->instr_at_put(pos, (masm->instr_at(pos) & ~(B24 | B20)) | B27); |
- DCHECK(Assembler::IsBranch(masm->instr_at(pos))); |
+ // Consider adding DCHECK here to catch bad patching |
+ masm->instr_at_put(pos, (masm->instr_at(pos) & ~kBOfieldMask) | BF); |
} |
static Mode GetMode(Code* stub) { |
- Instr first_instruction = Assembler::instr_at(stub->instruction_start()); |
+ Instr first_instruction = |
+ Assembler::instr_at(stub->instruction_start() + Assembler::kInstrSize); |
Instr second_instruction = Assembler::instr_at(stub->instruction_start() + |
- Assembler::kInstrSize); |
+ (Assembler::kInstrSize * 2)); |
- if (Assembler::IsBranch(first_instruction)) { |
+ // Consider adding DCHECK here to catch unexpected instruction sequence |
+ if (BF == (first_instruction & kBOfieldMask)) { |
return INCREMENTAL; |
} |
- DCHECK(Assembler::IsTstImmediate(first_instruction)); |
- |
- if (Assembler::IsBranch(second_instruction)) { |
+ if (BF == (second_instruction & kBOfieldMask)) { |
return INCREMENTAL_COMPACTION; |
} |
- DCHECK(Assembler::IsTstImmediate(second_instruction)); |
- |
return STORE_BUFFER_ONLY; |
} |
static void Patch(Code* stub, Mode mode) { |
- MacroAssembler masm(NULL, |
- stub->instruction_start(), |
+ MacroAssembler masm(NULL, stub->instruction_start(), |
stub->instruction_size()); |
switch (mode) { |
case STORE_BUFFER_ONLY: |
DCHECK(GetMode(stub) == INCREMENTAL || |
GetMode(stub) == INCREMENTAL_COMPACTION); |
- PatchBranchIntoNop(&masm, 0); |
+ |
PatchBranchIntoNop(&masm, Assembler::kInstrSize); |
+ PatchBranchIntoNop(&masm, Assembler::kInstrSize * 2); |
break; |
case INCREMENTAL: |
DCHECK(GetMode(stub) == STORE_BUFFER_ONLY); |
- PatchNopIntoBranch(&masm, 0); |
+ PatchNopIntoBranch(&masm, Assembler::kInstrSize); |
break; |
case INCREMENTAL_COMPACTION: |
DCHECK(GetMode(stub) == STORE_BUFFER_ONLY); |
- PatchNopIntoBranch(&masm, Assembler::kInstrSize); |
+ PatchNopIntoBranch(&masm, Assembler::kInstrSize * 2); |
break; |
} |
DCHECK(GetMode(stub) == mode); |
- CpuFeatures::FlushICache(stub->instruction_start(), |
+ CpuFeatures::FlushICache(stub->instruction_start() + Assembler::kInstrSize, |
2 * Assembler::kInstrSize); |
} |
@@ -177,12 +157,8 @@ class RecordWriteStub: public PlatformCodeStub { |
// the caller. |
class RegisterAllocation { |
public: |
- RegisterAllocation(Register object, |
- Register address, |
- Register scratch0) |
- : object_(object), |
- address_(address), |
- scratch0_(scratch0) { |
+ RegisterAllocation(Register object, Register address, Register scratch0) |
+ : object_(object), address_(address), scratch0_(scratch0) { |
DCHECK(!AreAliased(scratch0, object, address, no_reg)); |
scratch1_ = GetRegisterThatIsNotOneOf(object_, address_, scratch0_); |
} |
@@ -194,26 +170,30 @@ class RecordWriteStub: public PlatformCodeStub { |
masm->push(scratch1_); |
} |
- void Restore(MacroAssembler* masm) { |
- masm->pop(scratch1_); |
- } |
+ void Restore(MacroAssembler* masm) { masm->pop(scratch1_); } |
// If we have to call into C then we need to save and restore all caller- |
// saved registers that were not already preserved. The scratch registers |
// will be restored by other means so we don't bother pushing them here. |
void SaveCallerSaveRegisters(MacroAssembler* masm, SaveFPRegsMode mode) { |
- masm->stm(db_w, sp, (kCallerSaved | lr.bit()) & ~scratch1_.bit()); |
+ masm->mflr(r0); |
+ masm->push(r0); |
+ masm->MultiPush(kJSCallerSaved & ~scratch1_.bit()); |
if (mode == kSaveFPRegs) { |
- masm->SaveFPRegs(sp, scratch0_); |
+ // Save all volatile FP registers except d0. |
+ masm->SaveFPRegs(sp, 1, DoubleRegister::kNumVolatileRegisters - 1); |
} |
} |
- inline void RestoreCallerSaveRegisters(MacroAssembler*masm, |
+ inline void RestoreCallerSaveRegisters(MacroAssembler* masm, |
SaveFPRegsMode mode) { |
if (mode == kSaveFPRegs) { |
- masm->RestoreFPRegs(sp, scratch0_); |
+ // Restore all volatile FP registers except d0. |
+ masm->RestoreFPRegs(sp, 1, DoubleRegister::kNumVolatileRegisters - 1); |
} |
- masm->ldm(ia_w, sp, (kCallerSaved | lr.bit()) & ~scratch1_.bit()); |
+ masm->MultiPop(kJSCallerSaved & ~scratch1_.bit()); |
+ masm->pop(r0); |
+ masm->mtlr(r0); |
} |
inline Register object() { return object_; } |
@@ -240,8 +220,7 @@ class RecordWriteStub: public PlatformCodeStub { |
virtual void Generate(MacroAssembler* masm) OVERRIDE; |
void GenerateIncremental(MacroAssembler* masm, Mode mode); |
void CheckNeedsToInformIncrementalMarker( |
- MacroAssembler* masm, |
- OnNoNeedToInformIncrementalMarker on_no_need, |
+ MacroAssembler* masm, OnNoNeedToInformIncrementalMarker on_no_need, |
Mode mode); |
void InformIncrementalMarker(MacroAssembler* masm); |
@@ -269,11 +248,12 @@ class RecordWriteStub: public PlatformCodeStub { |
return SaveFPRegsModeBits::decode(minor_key_); |
} |
- class ObjectBits: public BitField<int, 0, 4> {}; |
- class ValueBits: public BitField<int, 4, 4> {}; |
- class AddressBits: public BitField<int, 8, 4> {}; |
- class RememberedSetActionBits: public BitField<RememberedSetAction, 12, 1> {}; |
- class SaveFPRegsModeBits: public BitField<SaveFPRegsMode, 13, 1> {}; |
+ class ObjectBits : public BitField<int, 0, 5> {}; |
+ class ValueBits : public BitField<int, 5, 5> {}; |
+ class AddressBits : public BitField<int, 10, 5> {}; |
+ class RememberedSetActionBits : public BitField<RememberedSetAction, 15, 1> { |
+ }; |
+ class SaveFPRegsModeBits : public BitField<SaveFPRegsMode, 16, 1> {}; |
Label slow_; |
RegisterAllocation regs_; |
@@ -287,7 +267,7 @@ class RecordWriteStub: public PlatformCodeStub { |
// keep the code which called into native pinned in the memory. Currently the |
// simplest approach is to generate such stub early enough so it can never be |
// moved by GC |
-class DirectCEntryStub: public PlatformCodeStub { |
+class DirectCEntryStub : public PlatformCodeStub { |
public: |
explicit DirectCEntryStub(Isolate* isolate) : PlatformCodeStub(isolate) {} |
void GenerateCall(MacroAssembler* masm, Register target); |
@@ -300,7 +280,7 @@ class DirectCEntryStub: public PlatformCodeStub { |
}; |
-class NameDictionaryLookupStub: public PlatformCodeStub { |
+class NameDictionaryLookupStub : public PlatformCodeStub { |
public: |
enum LookupMode { POSITIVE_LOOKUP, NEGATIVE_LOOKUP }; |
@@ -309,21 +289,14 @@ class NameDictionaryLookupStub: public PlatformCodeStub { |
minor_key_ = LookupModeBits::encode(mode); |
} |
- static void GenerateNegativeLookup(MacroAssembler* masm, |
- Label* miss, |
- Label* done, |
- Register receiver, |
- Register properties, |
- Handle<Name> name, |
+ static void GenerateNegativeLookup(MacroAssembler* masm, Label* miss, |
+ Label* done, Register receiver, |
+ Register properties, Handle<Name> name, |
Register scratch0); |
- static void GeneratePositiveLookup(MacroAssembler* masm, |
- Label* miss, |
- Label* done, |
- Register elements, |
- Register name, |
- Register r0, |
- Register r1); |
+ static void GeneratePositiveLookup(MacroAssembler* masm, Label* miss, |
+ Label* done, Register elements, |
+ Register name, Register r0, Register r1); |
virtual bool SometimesSetsUpAFrame() { return false; } |
@@ -341,12 +314,12 @@ class NameDictionaryLookupStub: public PlatformCodeStub { |
LookupMode mode() const { return LookupModeBits::decode(minor_key_); } |
- class LookupModeBits: public BitField<LookupMode, 0, 1> {}; |
+ class LookupModeBits : public BitField<LookupMode, 0, 1> {}; |
DEFINE_NULL_CALL_INTERFACE_DESCRIPTOR(); |
DEFINE_PLATFORM_CODE_STUB(NameDictionaryLookup, PlatformCodeStub); |
}; |
+} |
+} // namespace v8::internal |
-} } // namespace v8::internal |
- |
-#endif // V8_ARM_CODE_STUBS_ARM_H_ |
+#endif // V8_PPC_CODE_STUBS_PPC_H_ |