1 /*===-- llvm-c/Target.h - Target Lib C Iface --------------------*- C++ -*-===*/
2 /*                                                                            */
3 /*                     The LLVM Compiler Infrastructure                       */
4 /*                                                                            */
5 /* This file is distributed under the University of Illinois Open Source      */
6 /* License. See LICENSE.TXT for details.                                      */
7 /*                                                                            */
8 /*===----------------------------------------------------------------------===*/
9 /*                                                                            */
10 /* This header declares the C interface to libLLVMTarget.a, which             */
11 /* implements target information.                                             */
12 /*                                                                            */
13 /* Many exotic languages can interoperate with C code but have a harder time  */
14 /* with C++ due to name mangling. So in addition to C, this interface enables */
15 /* tools written in such languages.                                           */
16 /*                                                                            */
17 /*===----------------------------------------------------------------------===*/
18 
19 module deimos.llvm.c.target;
20 
21 import deimos.llvm.c.core;
22 
23 private
24 {
25   import std.algorithm : find, startsWith, countUntil;
26   import std.conv;
27   import std.array;
28 
29   string llvmDefFile(string llvmDefFileContent, string type)
30   {
31     string[] targets;
32     auto targetDefinitions = llvmDefFileContent.find("#endif");
33     auto str = "LLVM_" ~ type ~ "(";
34 
35     while (!targetDefinitions.empty)
36     {
37       if (targetDefinitions.startsWith(str))
38       {
39         targetDefinitions = targetDefinitions[str.length .. $];
40         auto target = targetDefinitions[0 .. targetDefinitions.countUntil(")")];
41         targetDefinitions = targetDefinitions[target.length + 1 .. $];
42         targets ~= target;
43       }
44       else targetDefinitions.popFront();
45     }
46 
47     return targets.to!string();
48   }
49 }
50 
51 extern(C) nothrow:
52 
53 /**
54  * @defgroup LLVMCTarget Target information
55  * @ingroup LLVMC
56  *
57  * @{
58  */
59 
60 enum LLVMByteOrdering { LLVMBigEndian, LLVMLittleEndian };
61 
62 struct __LLVMOpaqueTargetData {};
63 alias __LLVMOpaqueTargetData *LLVMTargetDataRef;
64 struct __LLVMOpaqueTargetLibraryInfotData {};
65 alias __LLVMOpaqueTargetLibraryInfotData *LLVMTargetLibraryInfoRef;
66 struct __LLVMStructLayout {};
67 alias __LLVMStructLayout *LLVMStructLayoutRef;
68 
69 private extern(D) string LLVM_TARGET(string delegate(string) nothrow fun)
70 {
71   string ret;
72   string[] targets;
73   version(llvmNoConfig) {}
74   else targets = mixin(llvmDefFile(import("Targets.def"), "TARGET"));
75   foreach (str; targets)
76   {
77     ret ~= fun(str) ~ "\n";
78   }
79   return ret;
80 }
81 
82 /* Declare all of the target-initialization functions that are available. */
83 extern(D) mixin(LLVM_TARGET(delegate string(string name) {
84   return "extern(C) void LLVMInitialize" ~ name ~ "TargetInfo();";
85 }));
86 
87 extern(D) mixin(LLVM_TARGET(delegate string(string name) {
88   return "extern(C) void LLVMInitialize" ~ name ~ "Target();";
89 }));
90 
91 extern(D) mixin(LLVM_TARGET(delegate string(string name) {
92   return "extern(C) void LLVMInitialize" ~ name ~ "TargetMC();";
93 }));
94 
95 private extern(D) string LLVM_ASM_PRINTER(string delegate(string) nothrow fun)
96 {
97   string ret;
98   string[] targets;
99   version(llvmNoConfig) {}
100   else targets = mixin(llvmDefFile(import("AsmPrinters.def"), "ASM_PRINTER"));
101   foreach (str; targets)
102   {
103     ret ~= fun(str) ~ "\n";
104   }
105   return ret;
106 }
107 
108 /* Declare all of the available assembly printer initialization functions. */
109 extern(D) mixin(LLVM_ASM_PRINTER(delegate string(string name) {
110   return "extern(C) void LLVMInitialize" ~ name ~ "AsmPrinter();";
111 }));
112 
113 private extern(D) string LLVM_ASM_PARSER(string delegate(string) nothrow fun)
114 {
115   string ret;
116   string[] targets;
117   version(llvmNoConfig) {}
118   else targets = mixin(llvmDefFile(import("AsmParsers.def"), "ASM_PARSER"));
119   foreach (str; targets)
120   {
121     ret ~= fun(str) ~ "\n";
122   }
123   return ret;
124 }
125 
126 /* Declare all of the available assembly parser initialization functions. */
127 extern(D) mixin(LLVM_ASM_PARSER(delegate string(string name) {
128   return "extern(C) void LLVMInitialize" ~ name ~ "AsmParser();";
129 }));
130 
131 private extern(D) string LLVM_ASM_DISASSEMBLER(string delegate(string) nothrow fun)
132 {
133   string ret;
134   string[] targets;
135   version(llvmNoConfig) {}
136   else targets = mixin(llvmDefFile(import("Disassemblers.def"), "DISASSEMBLER"));
137   foreach (str; targets)
138   {
139     ret ~= fun(str) ~ "\n";
140   }
141   return ret;
142 }
143 
144 /* Declare all of the available disassembler initialization functions. */
145 extern(D) mixin(LLVM_ASM_DISASSEMBLER(delegate string(string name) {
146   return "extern(C) void LLVMInitialize" ~ name ~ "Disassembler();";
147 }));
148 
149 /** LLVMInitializeAllTargetInfos - The main program should call this function if
150     it wants access to all available targets that LLVM is configured to
151     support. */
152 static void LLVMInitializeAllTargetInfos() {
153   mixin(LLVM_TARGET(delegate string(string name) {
154     return "LLVMInitialize" ~ name ~ "TargetInfo();";
155   }));
156 }
157 
158 /** LLVMInitializeAllTargets - The main program should call this function if it
159     wants to link in all available targets that LLVM is configured to
160     support. */
161 static void LLVMInitializeAllTargets() {
162   mixin(LLVM_TARGET(delegate string(string name) {
163     return "LLVMInitialize" ~ name ~ "Target();";
164   }));
165 }
166 
167 /** LLVMInitializeAllTargetMCs - The main program should call this function if
168     it wants access to all available target MC that LLVM is configured to
169     support. */
170 static void LLVMInitializeAllTargetMCs() {
171   mixin(LLVM_TARGET(delegate string(string name) {
172     return "LLVMInitialize" ~ name ~ "TargetMC();";
173   }));
174 }
175   
176 /** LLVMInitializeAllAsmPrinters - The main program should call this function if
177     it wants all asm printers that LLVM is configured to support, to make them
178     available via the TargetRegistry. */
179 static void LLVMInitializeAllAsmPrinters() {
180   mixin(LLVM_ASM_PRINTER(delegate string(string name) {
181     return "LLVMInitialize" ~ name ~ "AsmPrinter();";
182   }));
183 }
184   
185 /** LLVMInitializeAllAsmParsers - The main program should call this function if
186     it wants all asm parsers that LLVM is configured to support, to make them
187     available via the TargetRegistry. */
188 static void LLVMInitializeAllAsmParsers() {
189   mixin(LLVM_ASM_PARSER(delegate string(string name) {
190     return "LLVMInitialize" ~ name ~ "AsmParser();";
191   }));
192 }
193   
194 /** LLVMInitializeAllDisassemblers - The main program should call this function
195     if it wants all disassemblers that LLVM is configured to support, to make
196     them available via the TargetRegistry. */
197 static void LLVMInitializeAllDisassemblers() {
198   mixin(LLVM_ASM_DISASSEMBLER(delegate string(string name) {
199     return "LLVMInitialize" ~ name ~ "Disassembler();";
200   }));
201 }
202   
203 /** LLVMInitializeNativeTarget - The main program should call this function to
204     initialize the native target corresponding to the host.  This is useful 
205     for JIT applications to ensure that the target gets linked in correctly. */
206 static LLVMBool LLVMInitializeNativeTarget() {
207   /* If we have a native target, initialize it to ensure it is linked in. */
208   version(llvmNoConfig)
209   {
210     return 1;
211   }
212   else
213   {
214     import deimos.llvm.config.llvm_config;
215     LLVM_NATIVE_TARGETINFO();
216     LLVM_NATIVE_TARGET();
217     LLVM_NATIVE_TARGETMC();
218     return 0;
219   }
220 }  
221 
222 /*===-- Target Data -------------------------------------------------------===*/
223 
224 /** Creates target data from a target layout string.
225     See the constructor llvm::DataLayout::DataLayout. */
226 LLVMTargetDataRef LLVMCreateTargetData(const(char) *StringRep);
227 
228 /** Adds target data information to a pass manager. This does not take ownership
229     of the target data.
230     See the method llvm::PassManagerBase::add. */
231 void LLVMAddTargetData(LLVMTargetDataRef, LLVMPassManagerRef);
232 
233 /** Adds target library information to a pass manager. This does not take
234     ownership of the target library info.
235     See the method llvm::PassManagerBase::add. */
236 void LLVMAddTargetLibraryInfo(LLVMTargetLibraryInfoRef, LLVMPassManagerRef);
237 
238 /** Converts target data to a target layout string. The string must be disposed
239     with LLVMDisposeMessage.
240     See the constructor llvm::DataLayout::DataLayout. */
241 char *LLVMCopyStringRepOfTargetData(LLVMTargetDataRef);
242 
243 /** Returns the byte order of a target, either LLVMBigEndian or
244     LLVMLittleEndian.
245     See the method llvm::DataLayout::isLittleEndian. */
246 LLVMByteOrdering LLVMByteOrder(LLVMTargetDataRef);
247 
248 /** Returns the pointer size in bytes for a target.
249     See the method llvm::DataLayout::getPointerSize. */
250 uint LLVMPointerSize(LLVMTargetDataRef);
251 
252 /** Returns the pointer size in bytes for a target for a specified
253     address space.
254     See the method llvm::DataLayout::getPointerSize. */
255 uint LLVMPointerSizeForAS(LLVMTargetDataRef, uint AS);
256 
257 /** Returns the integer type that is the same size as a pointer on a target.
258     See the method llvm::DataLayout::getIntPtrType. */
259 LLVMTypeRef LLVMIntPtrType(LLVMTargetDataRef);
260 
261 /** Returns the integer type that is the same size as a pointer on a target.
262     This version allows the address space to be specified.
263     See the method llvm::DataLayout::getIntPtrType. */
264 LLVMTypeRef LLVMIntPtrTypeForAS(LLVMTargetDataRef, uint AS);
265 
266 /** Computes the size of a type in bytes for a target.
267     See the method llvm::DataLayout::getTypeSizeInBits. */
268 ulong LLVMSizeOfTypeInBits(LLVMTargetDataRef, LLVMTypeRef);
269 
270 /** Computes the storage size of a type in bytes for a target.
271     See the method llvm::DataLayout::getTypeStoreSize. */
272 ulong LLVMStoreSizeOfType(LLVMTargetDataRef, LLVMTypeRef);
273 
274 /** Computes the ABI size of a type in bytes for a target.
275     See the method llvm::DataLayout::getTypeAllocSize. */
276 ulong LLVMABISizeOfType(LLVMTargetDataRef, LLVMTypeRef);
277 
278 /** Computes the ABI alignment of a type in bytes for a target.
279     See the method llvm::DataLayout::getTypeABISize. */
280 uint LLVMABIAlignmentOfType(LLVMTargetDataRef, LLVMTypeRef);
281 
282 /** Computes the call frame alignment of a type in bytes for a target.
283     See the method llvm::DataLayout::getTypeABISize. */
284 uint LLVMCallFrameAlignmentOfType(LLVMTargetDataRef, LLVMTypeRef);
285 
286 /** Computes the preferred alignment of a type in bytes for a target.
287     See the method llvm::DataLayout::getTypeABISize. */
288 uint LLVMPreferredAlignmentOfType(LLVMTargetDataRef, LLVMTypeRef);
289 
290 /** Computes the preferred alignment of a global variable in bytes for a target.
291     See the method llvm::DataLayout::getPreferredAlignment. */
292 uint LLVMPreferredAlignmentOfGlobal(LLVMTargetDataRef,
293                                         LLVMValueRef GlobalVar);
294 
295 /** Computes the structure element that contains the byte offset for a target.
296     See the method llvm::StructLayout::getElementContainingOffset. */
297 uint LLVMElementAtOffset(LLVMTargetDataRef, LLVMTypeRef StructTy,
298                              ulong Offset);
299 
300 /** Computes the byte offset of the indexed struct element for a target.
301     See the method llvm::StructLayout::getElementContainingOffset. */
302 ulong LLVMOffsetOfElement(LLVMTargetDataRef, LLVMTypeRef StructTy,
303                                        uint Element);
304 
305 /** Deallocates a TargetData.
306     See the destructor llvm::DataLayout::~DataLayout. */
307 void LLVMDisposeTargetData(LLVMTargetDataRef);
308 
309 /**
310  * @}
311  */