| // Copyright 2018, VIXL authors |
| // All rights reserved. |
| // |
| // Redistribution and use in source and binary forms, with or without |
| // modification, are permitted provided that the following conditions are met: |
| // |
| // * Redistributions of source code must retain the above copyright notice, |
| // this list of conditions and the following disclaimer. |
| // * Redistributions in binary form must reproduce the above copyright notice, |
| // this list of conditions and the following disclaimer in the documentation |
| // and/or other materials provided with the distribution. |
| // * Neither the name of Arm Limited nor the names of its contributors may be |
| // used to endorse or promote products derived from this software without |
| // specific prior written permission. |
| // |
| // THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS CONTRIBUTORS "AS IS" AND |
| // ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED |
| // WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE |
| // DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE |
| // FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL |
| // DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR |
| // SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER |
| // CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, |
| // OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE |
| // OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. |
| |
| #ifndef VIXL_AARCH64_CPU_FEATURES_AUDITOR_AARCH64_H_ |
| #define VIXL_AARCH64_CPU_FEATURES_AUDITOR_AARCH64_H_ |
| |
| #include <iostream> |
| |
| #include "cpu-features.h" |
| #include "decoder-aarch64.h" |
| |
| namespace vixl { |
| namespace aarch64 { |
| |
| // This visitor records the CPU features that each decoded instruction requires. |
| // It provides: |
| // - the set of CPU features required by the most recently decoded instruction, |
| // - a cumulative set of encountered CPU features, |
| // - an optional list of 'available' CPU features. |
| // |
| // Primarily, this allows the Disassembler and Simulator to share the same CPU |
| // features logic. However, it can be used standalone to scan code blocks for |
| // CPU features. |
| class CPUFeaturesAuditor : public DecoderVisitor { |
| public: |
| // Construction arguments: |
| // - If a decoder is specified, the CPUFeaturesAuditor automatically |
| // registers itself as a visitor. Otherwise, this can be done manually. |
| // |
| // - If an `available` features list is provided, it is used as a hint in |
| // cases where instructions may be provided by multiple separate features. |
| // An example of this is FP&SIMD loads and stores: some of these are used |
| // in both FP and integer SIMD code. If exactly one of those features is |
| // in `available` when one of these instructions is encountered, then the |
| // auditor will record that feature. Otherwise, it will record _both_ |
| // features. |
| explicit CPUFeaturesAuditor( |
| Decoder* decoder, const CPUFeatures& available = CPUFeatures::None()) |
| : available_(available), decoder_(decoder) { |
| if (decoder_ != NULL) decoder_->AppendVisitor(this); |
| } |
| |
| explicit CPUFeaturesAuditor( |
| const CPUFeatures& available = CPUFeatures::None()) |
| : available_(available), decoder_(NULL) {} |
| |
| virtual ~CPUFeaturesAuditor() { |
| if (decoder_ != NULL) decoder_->RemoveVisitor(this); |
| } |
| |
| void ResetSeenFeatures() { |
| seen_ = CPUFeatures::None(); |
| last_instruction_ = CPUFeatures::None(); |
| } |
| |
| // Query or set available CPUFeatures. |
| const CPUFeatures& GetAvailableFeatures() const { return available_; } |
| void SetAvailableFeatures(const CPUFeatures& available) { |
| available_ = available; |
| } |
| |
| // Query CPUFeatures seen since construction (or the last call to `Reset()`). |
| const CPUFeatures& GetSeenFeatures() const { return seen_; } |
| |
| // Query CPUFeatures from the last instruction visited by this auditor. |
| const CPUFeatures& GetInstructionFeatures() const { |
| return last_instruction_; |
| } |
| |
| bool InstructionIsAvailable() const { |
| return available_.Has(last_instruction_); |
| } |
| |
| // The common CPUFeatures interface operates on the available_ list. |
| CPUFeatures* GetCPUFeatures() { return &available_; } |
| void SetCPUFeatures(const CPUFeatures& available) { |
| SetAvailableFeatures(available); |
| } |
| |
| // Declare all Visitor functions. |
| #define DECLARE(A) \ |
| virtual void Visit##A(const Instruction* instr) VIXL_OVERRIDE; |
| VISITOR_LIST(DECLARE) |
| #undef DECLARE |
| |
| private: |
| class RecordInstructionFeaturesScope; |
| |
| void LoadStoreHelper(const Instruction* instr); |
| void LoadStorePairHelper(const Instruction* instr); |
| |
| CPUFeatures seen_; |
| CPUFeatures last_instruction_; |
| CPUFeatures available_; |
| |
| Decoder* decoder_; |
| }; |
| |
| } // namespace aarch64 |
| } // namespace vixl |
| |
| #endif // VIXL_AARCH64_CPU_FEATURES_AUDITOR_AARCH64_H_ |