summaryrefslogtreecommitdiff
path: root/include/llvm/Target/SubtargetFeature.h
blob: 4d504c1939cfa4bd285fdd88b6912b07e66285e2 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
//===-- llvm/Target/SubtargetFeature.h - CPU characteristics ----*- C++ -*-===//
//
//                     The LLVM Compiler Infrastructure
//
// This file was developed by Jim Laskey and is distributed under the 
// University of Illinois Open Source License. See LICENSE.TXT for details.
//
//===----------------------------------------------------------------------===//
//
// This file defines and manages user or tool specified CPU characteristics.
// The intent is to be able to package specific features that should or should
// not be used on a specific target processor.  A tool, such as llc, could, as
// as example, gather chip info from the command line, a long with features
// that should be used on that chip.
//
//===----------------------------------------------------------------------===//

#ifndef LLVM_TARGET_SUBTARGETFEATURE_H
#define LLVM_TARGET_SUBTARGETFEATURE_H


#include <string>
#include <vector>
#include <iostream>
#include <cassert>
#include "llvm/Support/DataTypes.h"

namespace llvm {

//===----------------------------------------------------------------------===//
///
/// SubtargetFeatureKV - Used to provide key value pairs for feature and
/// CPU bit flags.
//
struct SubtargetFeatureKV {
  const char *Key;                      // K-V key string
  uint32_t Value;                       // K-V integer value
  
  // Compare routine for std binary search
  bool operator<(const std::string &S) const {
    return strcmp(Key, S.c_str()) < 0;
  }
};
  
//===----------------------------------------------------------------------===//
///
/// SubtargetFeatures - Manages the enabling and disabling of subtarget 
/// specific features.  Features are encoded as a string of the form
///   "cpu,+attr1,+attr2,-attr3,...,+attrN"
/// A comma separates each feature from the next (all lowercase.)
/// The first feature is always the CPU subtype (eg. pentiumm).  If the CPU
/// value is "generic" then the CPU subtype should be generic for the target.
/// Each of the remaining features is prefixed with + or - indicating whether
/// that feature should be enabled or disabled contrary to the cpu
/// specification.
///

class SubtargetFeatures {
private:
  std::vector<std::string> Features;    // Subtarget features as a vector

  // Determine if a feature has a flag; '+' or '-'
  static inline bool hasFlag(const std::string &Feature) {
    assert(!Feature.empty() && "Empty string");
    // Get first character
    char Ch = Feature[0];
    // Check if first character is '+' or '-' flag
    return Ch == '+' || Ch =='-';
  }
  
  // Return true if enable flag; '+'.
  static inline bool isEnabled(const std::string &Feature) {
    assert(!Feature.empty() && "Empty string");
    // Get first character
    char Ch = Feature[0];
    // Check if first character is '+' for enabled
    return Ch == '+';
  }
  
  // Return a string with a prepended flag; '+' or '-'.
  static inline std::string PrependFlag(const std::string &Feature,
                                        bool IsEnabled) {
    assert(!Feature.empty() && "Empty string");
    if (hasFlag(Feature)) return Feature;
    return std::string(IsEnabled ? "+" : "-") + Feature;
  }
  
  // Return string stripped of flag.
  static inline std::string StripFlag(const std::string &Feature) {
    return hasFlag(Feature) ? Feature.substr(1) : Feature;
  }

  /// Splits a string of comma separated items in to a vector of strings.
  static void Split(std::vector<std::string> &V, const std::string &S);
  
  /// Join a vector of strings into a string with a comma separating each
  /// item.
  static std::string Join(const std::vector<std::string> &V);
  
  /// Convert a string to lowercase.
  static std::string toLower(const std::string &S);
  
  /// Find item in array using binary search.
  static const SubtargetFeatureKV *Find(const std::string &S,
                                        const SubtargetFeatureKV *A, size_t L);

public:
  /// Ctor.
  SubtargetFeatures(const std::string Initial = std::string()) {
    // Break up string into separate features
    Split(Features, Initial);
  }

  /// Features string accessors.
  inline std::string getString() const { return Join(Features); }
  void setString(const std::string &Initial) {
    // Throw out old features
    Features.clear();
    // Break up string into separate features
    Split(Features, toLower(Initial));
  }

  /// Setting CPU string.  Replaces previous setting.  Setting to "" clears CPU.
  void setCPU(std::string String) { Features[0] = toLower(String); }
  
  /// Adding Features.
  void AddFeature(const std::string &String, bool IsEnabled = true);

  /// Parse feature string for quick usage.
  static uint32_t Parse(const std::string &String,
                        const std::string &DefaultCPU,
                        const SubtargetFeatureKV *CPUTable,
                        size_t CPUTableSize,
                        const SubtargetFeatureKV *FeatureTable,
                        size_t FeatureTableSize);
  
  /// Print feature string.
  void print(std::ostream &OS) const;
  
  // Dump feature info.
  void dump() const;
};

} // End namespace llvm

#endif