1 module llvm.config;
2 
3 import std.conv : to;
4 import std.array : array, replace, join;
5 import std.algorithm.iteration : filter, map, joiner;
6 import std.algorithm.searching : canFind;
7 
8 /// LLVM Versions that llvm-d supports
9 immutable LLVM_Versions = [
10 	[3,9,1],
11 	[3,9,0],
12 	[3,8,1],
13 	[3,8,0],
14 	[3,7,1],
15 	[3,7,0],
16 	[3,6,2],
17 	[3,6,1],
18 	[3,6,0],
19 	[3,5,2],
20 	[3,5,1],
21 	[3,5,0],
22 	[3,4,2],
23 	[3,4,1],
24 	[3,4,0],
25 	[3,3,0],
26 	[3,2,0],
27 	[3,1,0],
28 ];
29 
30 mixin(LLVM_Versions.map!(ver =>
31 	q{version(LLVM_%MAJOR_%MINOR_%PATCH) {
32 			immutable LLVM_VERSION_MAJOR = %MAJOR;
33 			immutable LLVM_VERSION_MINOR = %MINOR;
34 			immutable LLVM_VERSION_PATCH = %PATCH;
35 		}}.replace("%MAJOR", ver[0].to!string).replace("%MINOR", ver[1].to!string).replace("%PATCH", ver[2].to!string)
36 	).join("else\n") ~
37 	q{else {
38 		immutable LLVM_VERSION_MAJOR = LLVM_Versions[0][0];
39 		immutable LLVM_VERSION_MINOR = LLVM_Versions[0][1];
40 		immutable LLVM_VERSION_PATCH = LLVM_Versions[0][2];
41 	}}
42 );
43 
44 /// Makes an ordered identifier from a major, minor, and patch number
45 pure nothrow @nogc
46 ulong asVersion(ushort major, ushort minor, ushort patch)
47 {
48 	return cast(ulong)(major) << (ushort.sizeof*2*8) | cast(ulong)(minor) << (ushort.sizeof*8) | cast(ulong)(patch);
49 }
50 
51 /// LLVM Version that llvm-d was compiled against
52 immutable LLVM_Version = asVersion(LLVM_VERSION_MAJOR, LLVM_VERSION_MINOR, LLVM_VERSION_PATCH);
53 
54 /// LLVM Targets that can be used (enable target Name via version LLVM_Target_Name)
55 immutable LLVM_Targets = {
56 	string[] targets;
57 	mixin({
58 		       static if (LLVM_Version >= asVersion(3, 9, 0)) {
59 			return ["AArch64","AMDGPU","ARM","AVR","BPF","Hexagon","Lanai","MSP430","Mips","NVPTX","PowerPC","Sparc","SystemZ","WebAssembly","X86","XCore"];
60 		} else static if (LLVM_Version >= asVersion(3, 8, 0)) {
61 			return ["AArch64","AMDGPU","ARM","AVR","BPF","CppBackend","Hexagon","MSP430","Mips","NVPTX","PowerPC","Sparc","SystemZ","WebAssembly","X86","XCore"];
62 		} else static if (LLVM_Version >= asVersion(3, 7, 0)) {
63 			return ["AArch64","AMDGPU","ARM","BPF","CppBackend","Hexagon","MSP430","Mips","NVPTX","PowerPC","Sparc","SystemZ","WebAssembly","X86","XCore"];
64 		} else static if (LLVM_Version >= asVersion(3, 6, 0)) {
65 			return ["AArch64","ARM","CppBackend","Hexagon","MSP430","Mips","NVPTX","PowerPC","R600","Sparc","SystemZ","X86","XCore"];
66 		} else static if (LLVM_Version >= asVersion(3, 5, 0)) {
67 			return ["AArch64","ARM","CppBackend","Hexagon","MSP430","Mips","NVPTX","PowerPC","R600","Sparc","SystemZ","X86","XCore"];
68 		} else static if (LLVM_Version >= asVersion(3, 4, 0)) {
69 			return ["AArch64","ARM","CppBackend","Hexagon","MSP430","Mips","NVPTX","PowerPC","R600","Sparc","SystemZ","X86","XCore"];
70 		} else static if (LLVM_Version >= asVersion(3, 3, 0)) {
71 			return ["AArch64","ARM","CppBackend","Hexagon","MBlaze","MSP430","Mips","NVPTX","PowerPC","R600","Sparc","SystemZ","X86","XCore"];
72 		} else static if (LLVM_Version >= asVersion(3, 2, 0)) {
73 			return ["ARM","CellSPU","CppBackend","Hexagon","MBlaze","MSP430","Mips","NVPTX","PTX","PowerPC","Sparc","X86","XCore"];
74 		} else {
75 			return ["ARM","CellSPU","CppBackend","Hexagon","MBlaze","MSP430","Mips","PTX","PowerPC","Sparc","X86","XCore"];
76 		}
77 	}().map!(t => "version (LLVM_Target_" ~ t ~ ") targets ~= \"" ~ t ~ "\";").joiner.array);
78 	return targets;
79 }();
80 
81 /// LLVM Targets with AsmPrinter capability (if enabled)
82 immutable LLVM_AsmPrinters = {
83 	       static if (LLVM_Version >= asVersion(3, 9, 0)) {
84 		return ["AArch64","AMDGPU","ARM","BPF","Hexagon","Lanai","MSP430","Mips","NVPTX","PowerPC","Sparc","SystemZ","WebAssembly","X86","XCore"];
85 	} else static if (LLVM_Version >= asVersion(3, 8, 0)) {
86 		return ["AArch64","AMDGPU","ARM","BPF","Hexagon","MSP430","Mips","NVPTX","PowerPC","Sparc","SystemZ","WebAssembly","X86","XCore"];
87 	} else static if (LLVM_Version >= asVersion(3, 7, 0)) {
88 		return ["AArch64","AMDGPU","ARM","BPF","Hexagon","MSP430","Mips","NVPTX","PowerPC","Sparc","SystemZ","X86","XCore"];
89 	} else static if (LLVM_Version >= asVersion(3, 6, 0)) {
90 		return ["AArch64","ARM","Hexagon","MSP430","Mips","NVPTX","PowerPC","R600","Sparc","SystemZ","X86","XCore"];
91 	} else static if (LLVM_Version >= asVersion(3, 5, 0)) {
92 		return ["AArch64","ARM","Hexagon","MSP430","Mips","NVPTX","PowerPC","R600","Sparc","SystemZ","X86","XCore"];
93 	} else static if (LLVM_Version >= asVersion(3, 4, 0)) {
94 		return ["AArch64","ARM","Hexagon","MSP430","Mips","NVPTX","PowerPC","R600","Sparc","SystemZ","X86","XCore"];
95 	} else static if (LLVM_Version >= asVersion(3, 3, 0)) {
96 		return ["AArch64","ARM","Hexagon","MBlaze","MSP430","Mips","NVPTX","PowerPC","R600","Sparc","SystemZ","X86","XCore"];
97 	} else static if (LLVM_Version >= asVersion(3, 2, 0)) {
98 		return ["ARM","CellSPU","Hexagon","MBlaze","MSP430","Mips","NVPTX","PowerPC","Sparc","X86","XCore"];
99 	} else {
100 		return ["ARM","CellSPU","Hexagon","MBlaze","MSP430","Mips","PTX","PowerPC","Sparc","X86","XCore"];
101 	}
102 }().filter!(t => LLVM_Targets.canFind(t)).array;
103 
104 /// LLVM Targets with AsmParser capability (if enabled)
105 immutable LLVM_AsmParsers = {
106 	       static if (LLVM_Version >= asVersion(3, 9, 0)) {
107 		return ["AArch64","AMDGPU","ARM","Hexagon","Lanai","Mips","PowerPC","Sparc","SystemZ","X86"];
108 	} else static if (LLVM_Version >= asVersion(3, 8, 0)) {
109 		return ["AArch64","AMDGPU","ARM","Hexagon","Mips","PowerPC","Sparc","SystemZ","X86"];
110 	} else static if (LLVM_Version >= asVersion(3, 7, 0)) {
111 		return ["AArch64","AMDGPU","ARM","Mips","PowerPC","Sparc","SystemZ","X86"];
112 	} else static if (LLVM_Version >= asVersion(3, 6, 0)) {
113 		return ["AArch64","ARM","Mips","PowerPC","R600","Sparc","SystemZ","X86"];
114 	} else static if (LLVM_Version >= asVersion(3, 5, 0)) {
115 		return ["AArch64","ARM","Mips","PowerPC","Sparc","SystemZ","X86"];
116 	} else static if (LLVM_Version >= asVersion(3, 4, 0)) {
117 		return ["AArch64","ARM","Mips","PowerPC","SystemZ","X86"];
118 	} else static if (LLVM_Version >= asVersion(3, 3, 0)) {
119 		return ["AArch64","ARM","MBlaze","Mips","PowerPC","SystemZ","X86"];
120 	} else static if (LLVM_Version >= asVersion(3, 2, 0)) {
121 		return ["ARM","MBlaze","Mips","X86"];
122 	} else {
123 		return ["ARM","MBlaze","Mips","X86"];
124 	}
125 }().filter!(t => LLVM_Targets.canFind(t)).array;
126 
127 /// LLVM Targets with Disassembler capability (if enabled)
128 immutable LLVM_Disassemblers = {
129 	       static if (LLVM_Version >= asVersion(3, 9, 0)) {
130 		return ["AArch64","AMDGPU","ARM","Hexagon","Lanai","Mips","PowerPC","Sparc","SystemZ","WebAssembly","X86","XCore"];
131 	} else static if (LLVM_Version >= asVersion(3, 8, 0)) {
132 		return ["AArch64","ARM","Hexagon","Mips","PowerPC","Sparc","SystemZ","WebAssembly","X86","XCore"];
133 	} else static if (LLVM_Version >= asVersion(3, 7, 0)) {
134 		return ["AArch64","ARM","Hexagon","Mips","PowerPC","Sparc","SystemZ","X86","XCore"];
135 	} else static if (LLVM_Version >= asVersion(3, 6, 0)) {
136 		return ["AArch64","ARM","Hexagon","Mips","PowerPC","Sparc","SystemZ","X86","XCore"];
137 	} else static if (LLVM_Version >= asVersion(3, 5, 0)) {
138 		return ["AArch64","ARM","Mips","PowerPC","Sparc","SystemZ","X86","XCore"];
139 	} else static if (LLVM_Version >= asVersion(3, 4, 0)) {
140 		return ["AArch64","ARM","Mips","SystemZ","X86","XCore"];
141 	} else static if (LLVM_Version >= asVersion(3, 3, 0)) {
142 		return ["AArch64","ARM","MBlaze","Mips","X86","XCore"];
143 	} else static if (LLVM_Version >= asVersion(3, 2, 0)) {
144 		return ["ARM","MBlaze","Mips","X86"];
145 	} else {
146 		return ["ARM","MBlaze","Mips","X86"];
147 	}
148 }().filter!(t => LLVM_Targets.canFind(t)).array;
149 
150 /// LLVM Target that corresponds to the native architecture (if enabled)
151 immutable LLVM_NativeTarget = {
152 	auto t = {
153 		     version(X86)     return "X86";
154 		else version(X86_64)  return "X86";
155 		else version(SPARC)   return "Sparc";
156 		else version(SPARC64) return "Sparc";
157 		else version(PPC)     return "PowerPC";
158 		else version(PPC64)   return "PowerPC";
159 		else version(AArch64) return "AArch64";
160 		else version(ARM)     return "ARM";
161 		else version(MIPS32)  return "Mips";
162 		else version(MIPS64)  return "Mips";
163 		else version(SystemZ) return "SystemZ";
164 		else                  return "";
165 	}();
166 	if (t != "" && LLVM_Targets.canFind(t)) return t;
167 	else return "";
168 }();