aboutsummaryrefslogtreecommitdiff
path: root/src/aarch64/macro-assembler-aarch64.h
diff options
context:
space:
mode:
authorJacob Bramley <jacob.bramley@arm.com>2016-12-14 16:03:31 +0000
committerJacob Bramley <jacob.bramley@arm.com>2016-12-19 18:14:23 +0000
commite8ce9f0ec7fe9484fca0c446ecc8a9d7929bea66 (patch)
tree3cfa1f60292dc97c318a695a9e9fbf11ae27706e /src/aarch64/macro-assembler-aarch64.h
parent1091d74cee7404c902fccdc6dba81609bbbdf443 (diff)
Assert perfect nesting for UseScratchRegisterScope.
Since UseScratchRegisterScope now has a MacroAssembler pointer anyway, this patch also removes available_ and availablefp_, and uses the MacroAssembler directly. Some negative tests would be useful but I'll add them separately. Change-Id: Ia093c67a980044f8e1514cff81998fd9dbfaa44e
Diffstat (limited to 'src/aarch64/macro-assembler-aarch64.h')
-rw-r--r--src/aarch64/macro-assembler-aarch64.h49
1 files changed, 37 insertions, 12 deletions
diff --git a/src/aarch64/macro-assembler-aarch64.h b/src/aarch64/macro-assembler-aarch64.h
index 46b03468..6c626c79 100644
--- a/src/aarch64/macro-assembler-aarch64.h
+++ b/src/aarch64/macro-assembler-aarch64.h
@@ -2948,6 +2948,14 @@ class MacroAssembler : public Assembler, public MacroAssemblerInterface {
return GetScratchFPRegisterList();
}
+ // Get or set the current (most-deeply-nested) UseScratchRegisterScope.
+ void SetCurrentScratchRegisterScope(UseScratchRegisterScope* scope) {
+ current_scratch_scope_ = scope;
+ }
+ UseScratchRegisterScope* GetCurrentScratchRegisterScope() {
+ return current_scratch_scope_;
+ }
+
// Like printf, but print at run-time from generated code.
//
// The caller must ensure that arguments for floating-point placeholders
@@ -3135,6 +3143,8 @@ class MacroAssembler : public Assembler, public MacroAssemblerInterface {
CPURegList tmp_list_;
CPURegList fptmp_list_;
+ UseScratchRegisterScope* current_scratch_scope_;
+
LiteralPool literal_pool_;
VeneerPool veneer_pool_;
@@ -3222,16 +3232,22 @@ class UseScratchRegisterScope {
// This constructor implicitly calls `Open` to initialise the scope (`masm`
// must not be `NULL`), so it is ready to use immediately after it has been
// constructed.
- explicit UseScratchRegisterScope(MacroAssembler* masm);
+ explicit UseScratchRegisterScope(MacroAssembler* masm)
+ : masm_(NULL), parent_(NULL), old_available_(0), old_availablefp_(0) {
+ Open(masm);
+ }
// This constructor does not implicitly initialise the scope. Instead, the
// user is required to explicitly call the `Open` function before using the
// scope.
- UseScratchRegisterScope();
+ UseScratchRegisterScope()
+ : masm_(NULL), parent_(NULL), old_available_(0), old_availablefp_(0) {}
+
// This function performs the actual initialisation work.
void Open(MacroAssembler* masm);
// The destructor always implicitly calls the `Close` function.
- ~UseScratchRegisterScope();
+ ~UseScratchRegisterScope() { Close(); }
+
// This function performs the cleaning-up work. It must succeed even if the
// scope has not been opened. It is safe to call multiple times.
void Close();
@@ -3242,10 +3258,18 @@ class 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(); }
- VRegister AcquireS() { return AcquireNextAvailable(availablefp_).S(); }
- VRegister AcquireD() { return AcquireNextAvailable(availablefp_).D(); }
+ Register AcquireW() {
+ return AcquireNextAvailable(masm_->GetScratchRegisterList()).W();
+ }
+ Register AcquireX() {
+ return AcquireNextAvailable(masm_->GetScratchRegisterList()).X();
+ }
+ VRegister AcquireS() {
+ return AcquireNextAvailable(masm_->GetScratchFPRegisterList()).S();
+ }
+ VRegister AcquireD() {
+ return AcquireNextAvailable(masm_->GetScratchFPRegisterList()).D();
+ }
Register AcquireRegisterOfSize(int size_in_bits);
@@ -3257,7 +3281,7 @@ class UseScratchRegisterScope {
return AcquireVRegisterOfSize(reg.GetSizeInBits());
}
CPURegister AcquireCPURegisterOfSize(int size_in_bits) {
- return available_->IsEmpty()
+ return masm_->GetScratchRegisterList()->IsEmpty()
? CPURegister(AcquireVRegisterOfSize(size_in_bits))
: CPURegister(AcquireRegisterOfSize(size_in_bits));
}
@@ -3313,14 +3337,15 @@ class UseScratchRegisterScope {
static void ExcludeByRegList(CPURegList* available, RegList exclude);
- // Available scratch registers.
- CPURegList* available_; // kRegister
- CPURegList* availablefp_; // kVRegister
+ // The MacroAssembler maintains a list of available scratch registers, and
+ // also keeps track of the most recently-opened scope so that on destruction
+ // we can check that scopes do not outlive their parents.
+ MacroAssembler* masm_;
+ UseScratchRegisterScope* parent_;
// The state of the available lists at the start of this scope.
RegList old_available_; // kRegister
RegList old_availablefp_; // kVRegister
- bool initialised_;
// Disallow copy constructor and operator=.
VIXL_DEBUG_NO_RETURN UseScratchRegisterScope(const UseScratchRegisterScope&) {