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#include "instruction_set_features_mips64.h"
18
19#include <fstream>
20#include <sstream>
21
22#include "base/stringprintf.h"
23#include "utils.h"  // For Trim.
24
25namespace art {
26
27const Mips64InstructionSetFeatures* Mips64InstructionSetFeatures::FromVariant(
28    const std::string& variant, std::string* error_msg ATTRIBUTE_UNUSED) {
29  if (variant != "default" && variant != "mips64r6") {
30    LOG(WARNING) << "Unexpected CPU variant for Mips64 using defaults: " << variant;
31  }
32  bool smp = true;  // Conservative default.
33  return new Mips64InstructionSetFeatures(smp);
34}
35
36const Mips64InstructionSetFeatures* Mips64InstructionSetFeatures::FromBitmap(uint32_t bitmap) {
37  bool smp = (bitmap & kSmpBitfield) != 0;
38  return new Mips64InstructionSetFeatures(smp);
39}
40
41const Mips64InstructionSetFeatures* Mips64InstructionSetFeatures::FromCppDefines() {
42  const bool smp = true;
43
44  return new Mips64InstructionSetFeatures(smp);
45}
46
47const Mips64InstructionSetFeatures* Mips64InstructionSetFeatures::FromCpuInfo() {
48  // Look in /proc/cpuinfo for features we need.  Only use this when we can guarantee that
49  // the kernel puts the appropriate feature flags in here.  Sometimes it doesn't.
50  bool smp = false;
51
52  std::ifstream in("/proc/cpuinfo");
53  if (!in.fail()) {
54    while (!in.eof()) {
55      std::string line;
56      std::getline(in, line);
57      if (!in.eof()) {
58        LOG(INFO) << "cpuinfo line: " << line;
59        if (line.find("processor") != std::string::npos && line.find(": 1") != std::string::npos) {
60          smp = true;
61        }
62      }
63    }
64    in.close();
65  } else {
66    LOG(ERROR) << "Failed to open /proc/cpuinfo";
67  }
68  return new Mips64InstructionSetFeatures(smp);
69}
70
71const Mips64InstructionSetFeatures* Mips64InstructionSetFeatures::FromHwcap() {
72  UNIMPLEMENTED(WARNING);
73  return FromCppDefines();
74}
75
76const Mips64InstructionSetFeatures* Mips64InstructionSetFeatures::FromAssembly() {
77  UNIMPLEMENTED(WARNING);
78  return FromCppDefines();
79}
80
81bool Mips64InstructionSetFeatures::Equals(const InstructionSetFeatures* other) const {
82  if (kMips64 != other->GetInstructionSet()) {
83    return false;
84  }
85  return (IsSmp() == other->IsSmp());
86}
87
88uint32_t Mips64InstructionSetFeatures::AsBitmap() const {
89  return (IsSmp() ? kSmpBitfield : 0);
90}
91
92std::string Mips64InstructionSetFeatures::GetFeatureString() const {
93  std::string result;
94  if (IsSmp()) {
95    result += "smp";
96  } else {
97    result += "-smp";
98  }
99  return result;
100}
101
102const InstructionSetFeatures* Mips64InstructionSetFeatures::AddFeaturesFromSplitString(
103    const bool smp, const std::vector<std::string>& features, std::string* error_msg) const {
104  auto i = features.begin();
105  if (i != features.end()) {
106    // We don't have any features.
107    std::string feature = Trim(*i);
108    *error_msg = StringPrintf("Unknown instruction set feature: '%s'", feature.c_str());
109    return nullptr;
110  }
111  return new Mips64InstructionSetFeatures(smp);
112}
113
114}  // namespace art
115