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

Unified Diff: src/a64/macro-assembler-a64.h

Issue 164793003: A64: Use a scope utility to allocate scratch registers. (Closed) Base URL: https://v8.googlecode.com/svn/branches/bleeding_edge
Patch Set: Rebase. Created 6 years, 9 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 side-by-side diff with in-line comments
Download patch
« no previous file with comments | « src/a64/lithium-codegen-a64.cc ('k') | src/a64/macro-assembler-a64.cc » ('j') | no next file with comments »
Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
Index: src/a64/macro-assembler-a64.h
diff --git a/src/a64/macro-assembler-a64.h b/src/a64/macro-assembler-a64.h
index 81d0df62c8183f1a271ea06d39d41f959d7bd843..f5fa14f7dac1dd3483a981fb631a94bcc5f1c440 100644
--- a/src/a64/macro-assembler-a64.h
+++ b/src/a64/macro-assembler-a64.h
@@ -520,7 +520,6 @@ class MacroAssembler : public Assembler {
//
// Other than the registers passed into Pop, the stack pointer and (possibly)
// the system stack pointer, these methods do not modify any other registers.
- // Scratch registers such as Tmp0() and Tmp1() are preserved.
void Push(const CPURegister& src0, const CPURegister& src1 = NoReg,
const CPURegister& src2 = NoReg, const CPURegister& src3 = NoReg);
void Pop(const CPURegister& dst0, const CPURegister& dst1 = NoReg,
@@ -746,7 +745,7 @@ class MacroAssembler : public Assembler {
// Set the current stack pointer, but don't generate any code.
inline void SetStackPointer(const Register& stack_pointer) {
- ASSERT(!AreAliased(stack_pointer, Tmp0(), Tmp1()));
+ ASSERT(!TmpList()->IncludesAliasOf(stack_pointer));
sp_ = stack_pointer;
}
@@ -940,13 +939,13 @@ class MacroAssembler : public Assembler {
// Copy fields from 'src' to 'dst', where both are tagged objects.
// The 'temps' list is a list of X registers which can be used for scratch
- // values. The temps list must include at least one register, and it must not
- // contain Tmp0() or Tmp1().
+ // values. The temps list must include at least one register.
//
// Currently, CopyFields cannot make use of more than three registers from
// the 'temps' list.
//
- // As with several MacroAssembler methods, Tmp0() and Tmp1() will be used.
+ // CopyFields expects to be able to take at least two registers from
+ // MacroAssembler::TmpList().
void CopyFields(Register dst, Register src, CPURegList temps, unsigned count);
// Copies a number of bytes from src to dst. All passed registers are
@@ -1449,7 +1448,6 @@ class MacroAssembler : public Assembler {
void LoadElementsKind(Register result, Register object);
// Compare the object in a register to a value from the root list.
- // Uses the Tmp0() register as scratch.
void CompareRoot(const Register& obj, Heap::RootListIndex index);
// Compare the object in a register to a value and jump if they are equal.
@@ -1556,7 +1554,8 @@ class MacroAssembler : public Assembler {
// on access to global objects across environments. The holder register
// is left untouched, whereas both scratch registers are clobbered.
void CheckAccessGlobalProxy(Register holder_reg,
- Register scratch,
+ Register scratch1,
+ Register scratch2,
Label* miss);
// Hash the interger value in 'key' register.
@@ -1588,8 +1587,6 @@ class MacroAssembler : public Assembler {
// Frames.
// Activation support.
- // Note that Tmp0() and Tmp1() are used as a scratch registers. This is safe
- // because these methods are not used in Crankshaft.
void EnterFrame(StackFrame::Type type);
void LeaveFrame(StackFrame::Type type);
@@ -1678,7 +1675,7 @@ class MacroAssembler : public Assembler {
void LoadContext(Register dst, int context_chain_length);
// Emit code for a flooring division by a constant. The dividend register is
- // unchanged and Tmp0() gets clobbered. Dividend and result must be different.
+ // unchanged. Dividend and result must be different.
void FlooringDiv(Register result, Register dividend, int32_t divisor);
// ---------------------------------------------------------------------------
@@ -1704,7 +1701,7 @@ class MacroAssembler : public Assembler {
// in new space.
void RememberedSetHelper(Register object, // Used for debug code.
Register addr,
- Register scratch,
+ Register scratch1,
SaveFPRegsMode save_fp,
RememberedSetFinalAction and_then);
@@ -1889,7 +1886,8 @@ class MacroAssembler : public Assembler {
ElementsKind expected_kind,
ElementsKind transitioned_kind,
Register map_in_out,
- Register scratch,
+ Register scratch1,
+ Register scratch2,
Label* no_map_match);
void LoadGlobalFunction(int index, Register function);
@@ -1900,72 +1898,8 @@ class MacroAssembler : public Assembler {
Register map,
Register scratch);
- // --------------------------------------------------------------------------
- // Set the registers used internally by the MacroAssembler as scratch
- // registers. These registers are used to implement behaviours which are not
- // directly supported by A64, and where an intermediate result is required.
- //
- // Both tmp0 and tmp1 may be set to any X register except for xzr, sp,
- // and StackPointer(). Also, they must not be the same register (though they
- // may both be NoReg).
- //
- // It is valid to set either or both of these registers to NoReg if you don't
- // want the MacroAssembler to use any scratch registers. In a debug build, the
- // Assembler will assert that any registers it uses are valid. Be aware that
- // this check is not present in release builds. If this is a problem, use the
- // Assembler directly.
- void SetScratchRegisters(const Register& tmp0, const Register& tmp1) {
- // V8 assumes the macro assembler uses ip0 and ip1 as temp registers.
- ASSERT(tmp0.IsNone() || tmp0.Is(ip0));
- ASSERT(tmp1.IsNone() || tmp1.Is(ip1));
-
- ASSERT(!AreAliased(xzr, csp, tmp0, tmp1));
- ASSERT(!AreAliased(StackPointer(), tmp0, tmp1));
- tmp0_ = tmp0;
- tmp1_ = tmp1;
- }
-
- const Register& Tmp0() const {
- return tmp0_;
- }
-
- const Register& Tmp1() const {
- return tmp1_;
- }
-
- const Register WTmp0() const {
- return Register::Create(tmp0_.code(), kWRegSize);
- }
-
- const Register WTmp1() const {
- return Register::Create(tmp1_.code(), kWRegSize);
- }
-
- void SetFPScratchRegister(const FPRegister& fptmp0) {
- fptmp0_ = fptmp0;
- }
-
- const FPRegister& FPTmp0() const {
- return fptmp0_;
- }
-
- const Register AppropriateTempFor(
- const Register& target,
- const CPURegister& forbidden = NoCPUReg) const {
- Register candidate = forbidden.Is(Tmp0()) ? Tmp1() : Tmp0();
- ASSERT(!candidate.Is(target));
- return Register::Create(candidate.code(), target.SizeInBits());
- }
-
- const FPRegister AppropriateTempFor(
- const FPRegister& target,
- const CPURegister& forbidden = NoCPUReg) const {
- USE(forbidden);
- FPRegister candidate = FPTmp0();
- ASSERT(!candidate.Is(forbidden));
- ASSERT(!candidate.Is(target));
- return FPRegister::Create(candidate.code(), target.SizeInBits());
- }
+ CPURegList* TmpList() { return &tmp_list_; }
+ CPURegList* FPTmpList() { return &fptmp_list_; }
// Like printf, but print at run-time from generated code.
//
@@ -1978,7 +1912,7 @@ class MacroAssembler : public Assembler {
// size.
//
// The following registers cannot be printed:
- // Tmp0(), Tmp1(), StackPointer(), csp.
+ // StackPointer(), csp.
//
// This function automatically preserves caller-saved registers so that
// calling code can use Printf at any point without having to worry about
@@ -2063,11 +1997,14 @@ class MacroAssembler : public Assembler {
// These each implement CopyFields in a different way.
void CopyFieldsLoopPairsHelper(Register dst, Register src, unsigned count,
Register scratch1, Register scratch2,
- Register scratch3);
+ Register scratch3, Register scratch4,
+ Register scratch5);
void CopyFieldsUnrolledPairsHelper(Register dst, Register src, unsigned count,
- Register scratch1, Register scratch2);
+ Register scratch1, Register scratch2,
+ Register scratch3, Register scratch4);
void CopyFieldsUnrolledHelper(Register dst, Register src, unsigned count,
- Register scratch1);
+ Register scratch1, Register scratch2,
+ Register scratch3);
// The actual Push and Pop implementations. These don't generate any code
// other than that required for the push or pop. This allows
@@ -2148,10 +2085,9 @@ class MacroAssembler : public Assembler {
// The register to use as a stack pointer for stack operations.
Register sp_;
- // Scratch registers used internally by the MacroAssembler.
- Register tmp0_;
- Register tmp1_;
- FPRegister fptmp0_;
+ // Scratch registers available for use by the MacroAssembler.
+ CPURegList tmp_list_;
+ CPURegList fptmp_list_;
void InitializeNewString(Register string,
Register length,
@@ -2232,6 +2168,49 @@ class InstructionAccurateScope BASE_EMBEDDED {
};
+// This scope utility allows scratch registers to be managed safely. The
+// MacroAssembler's TmpList() (and FPTmpList()) is used as a pool of scratch
+// registers. These registers can be allocated on demand, and will be returned
+// at the end of the scope.
+//
+// When the scope ends, the MacroAssembler's lists will be restored to their
+// original state, even if the lists were modified by some other means.
+class UseScratchRegisterScope {
+ public:
+ explicit UseScratchRegisterScope(MacroAssembler* masm)
+ : available_(masm->TmpList()),
+ availablefp_(masm->FPTmpList()),
+ old_available_(available_->list()),
+ old_availablefp_(availablefp_->list()) {
+ ASSERT(available_->type() == CPURegister::kRegister);
+ ASSERT(availablefp_->type() == CPURegister::kFPRegister);
+ }
+
+ ~UseScratchRegisterScope();
+
+ // Take a register from the appropriate temps list. It will be returned
+ // automatically when the scope ends.
+ Register AcquireW() { return AcquireNextAvailable(available_).W(); }
+ Register AcquireX() { return AcquireNextAvailable(available_).X(); }
+ FPRegister AcquireS() { return AcquireNextAvailable(availablefp_).S(); }
+ FPRegister AcquireD() { return AcquireNextAvailable(availablefp_).D(); }
+
+ Register AcquireSameSizeAs(const Register& reg);
+ FPRegister AcquireSameSizeAs(const FPRegister& reg);
+
+ private:
+ static CPURegister AcquireNextAvailable(CPURegList* available);
+
+ // Available scratch registers.
+ CPURegList* available_; // kRegister
+ CPURegList* availablefp_; // kFPRegister
+
+ // The state of the available lists at the start of this scope.
+ RegList old_available_; // kRegister
+ RegList old_availablefp_; // kFPRegister
+};
+
+
inline MemOperand ContextMemOperand(Register context, int index) {
return MemOperand(context, Context::SlotOffset(index));
}
« no previous file with comments | « src/a64/lithium-codegen-a64.cc ('k') | src/a64/macro-assembler-a64.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698