1 | |
2 | |
3 | |
4 | |
5 | |
6 | |
7 | |
8 | |
9 | |
10 | |
11 | |
12 | |
13 | #include "RISCV.h" |
14 | #include "clang/Basic/MacroBuilder.h" |
15 | #include "llvm/ADT/StringSwitch.h" |
16 | |
17 | using namespace clang; |
18 | using namespace clang::targets; |
19 | |
20 | ArrayRef<const char *> RISCVTargetInfo::getGCCRegNames() const { |
21 | static const char *const GCCRegNames[] = { |
22 | "x0", "x1", "x2", "x3", "x4", "x5", "x6", "x7", |
23 | "x8", "x9", "x10", "x11", "x12", "x13", "x14", "x15", |
24 | "x16", "x17", "x18", "x19", "x20", "x21", "x22", "x23", |
25 | "x24", "x25", "x26", "x27", "x28", "x29", "x30", "x31"}; |
26 | return llvm::makeArrayRef(GCCRegNames); |
27 | } |
28 | |
29 | ArrayRef<TargetInfo::GCCRegAlias> RISCVTargetInfo::getGCCRegAliases() const { |
30 | static const TargetInfo::GCCRegAlias GCCRegAliases[] = { |
31 | {{"zero"}, "x0"}, {{"ra"}, "x1"}, {{"sp"}, "x2"}, {{"gp"}, "x3"}, |
32 | {{"tp"}, "x4"}, {{"t0"}, "x5"}, {{"t1"}, "x6"}, {{"t2"}, "x7"}, |
33 | {{"s0"}, "x8"}, {{"s1"}, "x9"}, {{"a0"}, "x10"}, {{"a1"}, "x11"}, |
34 | {{"a2"}, "x12"}, {{"a3"}, "x13"}, {{"a4"}, "x15"}, {{"a5"}, "x15"}, |
35 | {{"a6"}, "x16"}, {{"a7"}, "x17"}, {{"s2"}, "x18"}, {{"s3"}, "x19"}, |
36 | {{"s4"}, "x20"}, {{"s5"}, "x21"}, {{"s6"}, "x22"}, {{"s7"}, "x23"}, |
37 | {{"s8"}, "x24"}, {{"s9"}, "x25"}, {{"s10"}, "x26"}, {{"s11"}, "x27"}, |
38 | {{"t3"}, "x28"}, {{"t4"}, "x29"}, {{"t5"}, "x30"}, {{"t6"}, "x31"}}; |
39 | return llvm::makeArrayRef(GCCRegAliases); |
40 | } |
41 | |
42 | void RISCVTargetInfo::getTargetDefines(const LangOptions &Opts, |
43 | MacroBuilder &Builder) const { |
44 | Builder.defineMacro("__ELF__"); |
45 | Builder.defineMacro("__riscv"); |
46 | bool Is64Bit = getTriple().getArch() == llvm::Triple::riscv64; |
47 | Builder.defineMacro("__riscv_xlen", Is64Bit ? "64" : "32"); |
48 | |
49 | Builder.defineMacro("__riscv_cmodel_medlow"); |
50 | Builder.defineMacro("__riscv_float_abi_soft"); |
51 | |
52 | if (HasM) { |
53 | Builder.defineMacro("__riscv_mul"); |
54 | Builder.defineMacro("__riscv_div"); |
55 | Builder.defineMacro("__riscv_muldiv"); |
56 | } |
57 | |
58 | if (HasA) |
59 | Builder.defineMacro("__riscv_atomic"); |
60 | |
61 | if (HasF || HasD) { |
62 | Builder.defineMacro("__riscv_flen", HasD ? "64" : "32"); |
63 | Builder.defineMacro("__riscv_fdiv"); |
64 | Builder.defineMacro("__riscv_fsqrt"); |
65 | } |
66 | |
67 | if (HasC) |
68 | Builder.defineMacro("__riscv_compressed"); |
69 | } |
70 | |
71 | |
72 | bool RISCVTargetInfo::hasFeature(StringRef Feature) const { |
73 | bool Is64Bit = getTriple().getArch() == llvm::Triple::riscv64; |
74 | return llvm::StringSwitch<bool>(Feature) |
75 | .Case("riscv", true) |
76 | .Case("riscv32", !Is64Bit) |
77 | .Case("riscv64", Is64Bit) |
78 | .Case("m", HasM) |
79 | .Case("a", HasA) |
80 | .Case("f", HasF) |
81 | .Case("d", HasD) |
82 | .Case("c", HasC) |
83 | .Default(false); |
84 | } |
85 | |
86 | |
87 | bool RISCVTargetInfo::handleTargetFeatures(std::vector<std::string> &Features, |
88 | DiagnosticsEngine &Diags) { |
89 | for (const auto &Feature : Features) { |
90 | if (Feature == "+m") |
91 | HasM = true; |
92 | else if (Feature == "+a") |
93 | HasA = true; |
94 | else if (Feature == "+f") |
95 | HasF = true; |
96 | else if (Feature == "+d") |
97 | HasD = true; |
98 | else if (Feature == "+c") |
99 | HasC = true; |
100 | } |
101 | |
102 | return true; |
103 | } |
104 | |