| // Copyright (c) 2017, the Dart project authors.  Please see the AUTHORS file | 
 | // for details. All rights reserved. Use of this source code is governed by a | 
 | // BSD-style license that can be found in the LICENSE file. | 
 |  | 
 | // This file contains few helpful marker types that can be used with | 
 | // MakeLocationSummaryFromEmitter and InvokeEmitter to simplify writing | 
 | // of ARM code. | 
 |  | 
 | #ifndef RUNTIME_VM_COMPILER_BACKEND_LOCATIONS_HELPERS_ARM_H_ | 
 | #define RUNTIME_VM_COMPILER_BACKEND_LOCATIONS_HELPERS_ARM_H_ | 
 |  | 
 | #if defined(DART_PRECOMPILED_RUNTIME) | 
 | #error "AOT runtime should not use compiler sources (including header files)" | 
 | #endif  // defined(DART_PRECOMPILED_RUNTIME) | 
 |  | 
 | namespace dart { | 
 |  | 
 | // QRegisterView is a wrapper around QRegister that provides helpers for | 
 | // accessing S and D components. | 
 | class QRegisterView { | 
 |  public: | 
 |   explicit QRegisterView(QRegister reg) : reg_(reg) {} | 
 |  | 
 |   operator QRegister() const { return reg_; } | 
 |  | 
 |   inline DRegister d(intptr_t i) const { | 
 |     ASSERT(0 <= i && i < 2); | 
 |     return static_cast<DRegister>(reg_ * 2 + i); | 
 |   } | 
 |  | 
 |   inline SRegister s(intptr_t i) const { | 
 |     ASSERT(0 <= i && i < 4); | 
 |     ASSERT(reg_ <= Q7); | 
 |     return static_cast<SRegister>(reg_ * 4 + i); | 
 |   } | 
 |  | 
 |  private: | 
 |   QRegister reg_; | 
 | }; | 
 |  | 
 | // FixedQRegisterView<r> is a handy replacement for Fixed<QRegister, r> that | 
 | // provides helpers for accessing S and D components. | 
 | // | 
 | // Note: this class is provided because Fixed<QRegisterView, r> is not a valid | 
 | // type. | 
 | template <QRegister reg> | 
 | class FixedQRegisterView { | 
 |  public: | 
 |   inline DRegister d(intptr_t i) const { | 
 |     return static_cast<DRegister>(reg * 2 + i); | 
 |   } | 
 |  | 
 |   inline SRegister s(intptr_t i) const { | 
 |     return static_cast<SRegister>(reg * 4 + i); | 
 |   } | 
 |  | 
 |   operator QRegister() const { return reg; } | 
 | }; | 
 |  | 
 | template <> | 
 | struct LocationTrait<QRegisterView> { | 
 |   static const bool kIsTemp = false; | 
 |  | 
 |   static QRegisterView Unwrap(const Location& loc) { | 
 |     return QRegisterView(loc.fpu_reg()); | 
 |   } | 
 |  | 
 |   template <intptr_t arity, intptr_t index> | 
 |   static QRegisterView UnwrapInput(LocationSummary* locs) { | 
 |     return Unwrap(locs->in(index)); | 
 |   } | 
 |  | 
 |   template <intptr_t arity, intptr_t index> | 
 |   static void SetInputConstraint(LocationSummary* locs) { | 
 |     locs->set_in(index, ToConstraint()); | 
 |   } | 
 |  | 
 |   static Location ToConstraint() { return Location::RequiresFpuRegister(); } | 
 | }; | 
 |  | 
 | template <QRegister reg> | 
 | struct LocationTrait<FixedQRegisterView<reg> > { | 
 |   static const bool kIsTemp = false; | 
 |  | 
 |   static FixedQRegisterView<reg> Unwrap(const Location& loc) { | 
 |     ASSERT(LocationTrait<QRegister>::Unwrap(loc) == reg); | 
 |     return FixedQRegisterView<reg>(); | 
 |   } | 
 |  | 
 |   template <intptr_t arity, intptr_t index> | 
 |   static FixedQRegisterView<reg> UnwrapInput(LocationSummary* locs) { | 
 |     return Unwrap(locs->in(index)); | 
 |   } | 
 |  | 
 |   template <intptr_t arity, intptr_t index> | 
 |   static void SetInputConstraint(LocationSummary* locs) { | 
 |     locs->set_in(index, ToConstraint()); | 
 |   } | 
 |  | 
 |   static Location ToConstraint() { return Location::FpuRegisterLocation(reg); } | 
 | }; | 
 |  | 
 | }  // namespace dart | 
 |  | 
 | #endif  // RUNTIME_VM_COMPILER_BACKEND_LOCATIONS_HELPERS_ARM_H_ |