1 /*
2  * Copyright (C) 2014 The Android Open Source Project
3  *
4  * Licensed under the Apache License, Version 2.0 (the "License");
5  * you may not use this file except in compliance with the License.
6  * You may obtain a copy of the License at
7  *
8  *      http://www.apache.org/licenses/LICENSE-2.0
9  *
10  * Unless required by applicable law or agreed to in writing, software
11  * distributed under the License is distributed on an "AS IS" BASIS,
12  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13  * See the License for the specific language governing permissions and
14  * limitations under the License.
15  */
16 
17 #ifndef ART_RUNTIME_ARCH_MIPS_INSTRUCTION_SET_FEATURES_MIPS_H_
18 #define ART_RUNTIME_ARCH_MIPS_INSTRUCTION_SET_FEATURES_MIPS_H_
19 
20 #include <android-base/logging.h>
21 
22 #include "arch/instruction_set_features.h"
23 #include "base/macros.h"
24 
25 namespace art {
26 
27 class MipsInstructionSetFeatures;
28 using MipsFeaturesUniquePtr = std::unique_ptr<const MipsInstructionSetFeatures>;
29 
30 // Instruction set features relevant to the MIPS architecture.
31 class MipsInstructionSetFeatures final : public InstructionSetFeatures {
32  public:
33   // Process a CPU variant string like "r4000" and create InstructionSetFeatures.
34   static MipsFeaturesUniquePtr FromVariant(const std::string& variant, std::string* error_msg);
35 
36   // Parse a bitmap and create an InstructionSetFeatures.
37   static MipsFeaturesUniquePtr FromBitmap(uint32_t bitmap);
38 
39   // Turn C pre-processor #defines into the equivalent instruction set features.
40   static MipsFeaturesUniquePtr FromCppDefines();
41 
42   // Process /proc/cpuinfo and use kRuntimeISA to produce InstructionSetFeatures.
43   static MipsFeaturesUniquePtr FromCpuInfo();
44 
45   // Process the auxiliary vector AT_HWCAP entry and use kRuntimeISA to produce
46   // InstructionSetFeatures.
47   static MipsFeaturesUniquePtr FromHwcap();
48 
49   // Use assembly tests of the current runtime (ie kRuntimeISA) to determine the
50   // InstructionSetFeatures. This works around kernel bugs in AT_HWCAP and /proc/cpuinfo.
51   static MipsFeaturesUniquePtr FromAssembly();
52 
53   bool Equals(const InstructionSetFeatures* other) const override;
54 
GetInstructionSet()55   InstructionSet GetInstructionSet() const override {
56     return InstructionSet::kMips;
57   }
58 
59   uint32_t AsBitmap() const override;
60 
61   std::string GetFeatureString() const override;
62 
63   // Is this an ISA revision greater than 2 opening up new opcodes.
IsMipsIsaRevGreaterThanEqual2()64   bool IsMipsIsaRevGreaterThanEqual2() const {
65     return mips_isa_gte2_;
66   }
67 
68   // Floating point double registers are encoded differently based on whether the Status.FR bit is
69   // set. When the FR bit is 0 then the FPU is 32-bit, 1 its 64-bit. Return true if the code should
70   // be generated assuming Status.FR is 0.
Is32BitFloatingPoint()71   bool Is32BitFloatingPoint() const {
72     return fpu_32bit_;
73   }
74 
IsR6()75   bool IsR6() const {
76     return r6_;
77   }
78 
79   // Does it have MSA (MIPS SIMD Architecture) support.
HasMsa()80   bool HasMsa() const {
81     return msa_;
82   }
83 
~MipsInstructionSetFeatures()84   virtual ~MipsInstructionSetFeatures() {}
85 
86  protected:
87   // Parse a vector of the form "fpu32", "mips2" adding these to a new MipsInstructionSetFeatures.
88   std::unique_ptr<const InstructionSetFeatures>
89       AddFeaturesFromSplitString(const std::vector<std::string>& features,
90                                  std::string* error_msg) const override;
91 
92  private:
MipsInstructionSetFeatures(bool fpu_32bit,bool mips_isa_gte2,bool r6,bool msa)93   MipsInstructionSetFeatures(bool fpu_32bit, bool mips_isa_gte2, bool r6, bool msa)
94       : InstructionSetFeatures(),
95         fpu_32bit_(fpu_32bit),
96         mips_isa_gte2_(mips_isa_gte2),
97         r6_(r6),
98         msa_(msa) {
99     // Sanity checks.
100     if (r6) {
101       CHECK(mips_isa_gte2);
102       CHECK(!fpu_32bit);
103     }
104     if (!mips_isa_gte2) {
105       CHECK(fpu_32bit);
106     }
107   }
108 
109   // Bitmap positions for encoding features as a bitmap.
110   enum {
111     kFpu32Bitfield = 1 << 0,
112     kIsaRevGte2Bitfield = 1 << 1,
113     kR6 = 1 << 2,
114     kMsaBitfield = 1 << 3,
115   };
116 
117   const bool fpu_32bit_;
118   const bool mips_isa_gte2_;
119   const bool r6_;
120   const bool msa_;
121 
122   DISALLOW_COPY_AND_ASSIGN(MipsInstructionSetFeatures);
123 };
124 
125 }  // namespace art
126 
127 #endif  // ART_RUNTIME_ARCH_MIPS_INSTRUCTION_SET_FEATURES_MIPS_H_
128