83
|
1 //===- target.go - Bindings for target ------------------------------------===//
|
|
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 file defines bindings for the target component.
|
|
11 //
|
|
12 //===----------------------------------------------------------------------===//
|
|
13
|
|
14 package llvm
|
|
15
|
|
16 /*
|
|
17 #include "llvm-c/Target.h"
|
|
18 #include "llvm-c/TargetMachine.h"
|
|
19 #include <stdlib.h>
|
|
20 */
|
|
21 import "C"
|
|
22 import "unsafe"
|
|
23 import "errors"
|
|
24
|
|
25 type (
|
|
26 TargetData struct {
|
|
27 C C.LLVMTargetDataRef
|
|
28 }
|
|
29 Target struct {
|
|
30 C C.LLVMTargetRef
|
|
31 }
|
|
32 TargetMachine struct {
|
|
33 C C.LLVMTargetMachineRef
|
|
34 }
|
|
35 ByteOrdering C.enum_LLVMByteOrdering
|
|
36 RelocMode C.LLVMRelocMode
|
|
37 CodeGenOptLevel C.LLVMCodeGenOptLevel
|
|
38 CodeGenFileType C.LLVMCodeGenFileType
|
|
39 CodeModel C.LLVMCodeModel
|
|
40 )
|
|
41
|
|
42 const (
|
|
43 BigEndian ByteOrdering = C.LLVMBigEndian
|
|
44 LittleEndian ByteOrdering = C.LLVMLittleEndian
|
|
45 )
|
|
46
|
|
47 const (
|
|
48 RelocDefault RelocMode = C.LLVMRelocDefault
|
|
49 RelocStatic RelocMode = C.LLVMRelocStatic
|
|
50 RelocPIC RelocMode = C.LLVMRelocPIC
|
|
51 RelocDynamicNoPic RelocMode = C.LLVMRelocDynamicNoPic
|
|
52 )
|
|
53
|
|
54 const (
|
|
55 CodeGenLevelNone CodeGenOptLevel = C.LLVMCodeGenLevelNone
|
|
56 CodeGenLevelLess CodeGenOptLevel = C.LLVMCodeGenLevelLess
|
|
57 CodeGenLevelDefault CodeGenOptLevel = C.LLVMCodeGenLevelDefault
|
|
58 CodeGenLevelAggressive CodeGenOptLevel = C.LLVMCodeGenLevelAggressive
|
|
59 )
|
|
60
|
|
61 const (
|
|
62 CodeModelDefault CodeModel = C.LLVMCodeModelDefault
|
|
63 CodeModelJITDefault CodeModel = C.LLVMCodeModelJITDefault
|
|
64 CodeModelSmall CodeModel = C.LLVMCodeModelSmall
|
|
65 CodeModelKernel CodeModel = C.LLVMCodeModelKernel
|
|
66 CodeModelMedium CodeModel = C.LLVMCodeModelMedium
|
|
67 CodeModelLarge CodeModel = C.LLVMCodeModelLarge
|
|
68 )
|
|
69
|
|
70 const (
|
|
71 AssemblyFile CodeGenFileType = C.LLVMAssemblyFile
|
|
72 ObjectFile CodeGenFileType = C.LLVMObjectFile
|
|
73 )
|
|
74
|
|
75 // InitializeAllTargetInfos - The main program should call this function if it
|
|
76 // wants access to all available targets that LLVM is configured to support.
|
|
77 func InitializeAllTargetInfos() { C.LLVMInitializeAllTargetInfos() }
|
|
78
|
|
79 // InitializeAllTargets - The main program should call this function if it wants
|
|
80 // to link in all available targets that LLVM is configured to support.
|
|
81 func InitializeAllTargets() { C.LLVMInitializeAllTargets() }
|
|
82
|
|
83 func InitializeAllTargetMCs() { C.LLVMInitializeAllTargetMCs() }
|
|
84
|
|
85 func InitializeAllAsmParsers() { C.LLVMInitializeAllAsmParsers() }
|
|
86
|
|
87 func InitializeAllAsmPrinters() { C.LLVMInitializeAllAsmPrinters() }
|
|
88
|
|
89 var initializeNativeTargetError = errors.New("Failed to initialize native target")
|
|
90
|
|
91 // InitializeNativeTarget - The main program should call this function to
|
|
92 // initialize the native target corresponding to the host. This is useful
|
|
93 // for JIT applications to ensure that the target gets linked in correctly.
|
|
94 func InitializeNativeTarget() error {
|
|
95 fail := C.LLVMInitializeNativeTarget()
|
|
96 if fail != 0 {
|
|
97 return initializeNativeTargetError
|
|
98 }
|
|
99 return nil
|
|
100 }
|
|
101
|
|
102 func InitializeNativeAsmPrinter() error {
|
|
103 fail := C.LLVMInitializeNativeAsmPrinter()
|
|
104 if fail != 0 {
|
|
105 return initializeNativeTargetError
|
|
106 }
|
|
107 return nil
|
|
108 }
|
|
109
|
|
110 //-------------------------------------------------------------------------
|
|
111 // llvm.TargetData
|
|
112 //-------------------------------------------------------------------------
|
|
113
|
|
114 // Creates target data from a target layout string.
|
|
115 // See the constructor llvm::TargetData::TargetData.
|
|
116 func NewTargetData(rep string) (td TargetData) {
|
|
117 crep := C.CString(rep)
|
|
118 defer C.free(unsafe.Pointer(crep))
|
|
119 td.C = C.LLVMCreateTargetData(crep)
|
|
120 return
|
|
121 }
|
|
122
|
|
123 // Adds target data information to a pass manager. This does not take ownership
|
|
124 // of the target data.
|
|
125 // See the method llvm::PassManagerBase::add.
|
|
126 func (pm PassManager) Add(td TargetData) {
|
|
127 C.LLVMAddTargetData(td.C, pm.C)
|
|
128 }
|
|
129
|
|
130 // Converts target data to a target layout string. The string must be disposed
|
|
131 // with LLVMDisposeMessage.
|
|
132 // See the constructor llvm::TargetData::TargetData.
|
|
133 func (td TargetData) String() (s string) {
|
|
134 cmsg := C.LLVMCopyStringRepOfTargetData(td.C)
|
|
135 s = C.GoString(cmsg)
|
|
136 C.LLVMDisposeMessage(cmsg)
|
|
137 return
|
|
138 }
|
|
139
|
|
140 // Returns the byte order of a target, either BigEndian or LittleEndian.
|
|
141 // See the method llvm::TargetData::isLittleEndian.
|
|
142 func (td TargetData) ByteOrder() ByteOrdering { return ByteOrdering(C.LLVMByteOrder(td.C)) }
|
|
143
|
|
144 // Returns the pointer size in bytes for a target.
|
|
145 // See the method llvm::TargetData::getPointerSize.
|
|
146 func (td TargetData) PointerSize() int { return int(C.LLVMPointerSize(td.C)) }
|
|
147
|
|
148 // Returns the integer type that is the same size as a pointer on a target.
|
|
149 // See the method llvm::TargetData::getIntPtrType.
|
|
150 func (td TargetData) IntPtrType() (t Type) { t.C = C.LLVMIntPtrType(td.C); return }
|
|
151
|
|
152 // Computes the size of a type in bytes for a target.
|
|
153 // See the method llvm::TargetData::getTypeSizeInBits.
|
|
154 func (td TargetData) TypeSizeInBits(t Type) uint64 {
|
|
155 return uint64(C.LLVMSizeOfTypeInBits(td.C, t.C))
|
|
156 }
|
|
157
|
|
158 // Computes the storage size of a type in bytes for a target.
|
|
159 // See the method llvm::TargetData::getTypeStoreSize.
|
|
160 func (td TargetData) TypeStoreSize(t Type) uint64 {
|
|
161 return uint64(C.LLVMStoreSizeOfType(td.C, t.C))
|
|
162 }
|
|
163
|
|
164 // Computes the ABI size of a type in bytes for a target.
|
|
165 // See the method llvm::TargetData::getTypeAllocSize.
|
|
166 func (td TargetData) TypeAllocSize(t Type) uint64 {
|
|
167 return uint64(C.LLVMABISizeOfType(td.C, t.C))
|
|
168 }
|
|
169
|
|
170 // Computes the ABI alignment of a type in bytes for a target.
|
|
171 // See the method llvm::TargetData::getABITypeAlignment.
|
|
172 func (td TargetData) ABITypeAlignment(t Type) int {
|
|
173 return int(C.LLVMABIAlignmentOfType(td.C, t.C))
|
|
174 }
|
|
175
|
|
176 // Computes the call frame alignment of a type in bytes for a target.
|
|
177 // See the method llvm::TargetData::getCallFrameTypeAlignment.
|
|
178 func (td TargetData) CallFrameTypeAlignment(t Type) int {
|
|
179 return int(C.LLVMCallFrameAlignmentOfType(td.C, t.C))
|
|
180 }
|
|
181
|
|
182 // Computes the preferred alignment of a type in bytes for a target.
|
|
183 // See the method llvm::TargetData::getPrefTypeAlignment.
|
|
184 func (td TargetData) PrefTypeAlignment(t Type) int {
|
|
185 return int(C.LLVMPreferredAlignmentOfType(td.C, t.C))
|
|
186 }
|
|
187
|
|
188 // Computes the preferred alignment of a global variable in bytes for a target.
|
|
189 // See the method llvm::TargetData::getPreferredAlignment.
|
|
190 func (td TargetData) PreferredAlignment(g Value) int {
|
|
191 return int(C.LLVMPreferredAlignmentOfGlobal(td.C, g.C))
|
|
192 }
|
|
193
|
|
194 // Computes the structure element that contains the byte offset for a target.
|
|
195 // See the method llvm::StructLayout::getElementContainingOffset.
|
|
196 func (td TargetData) ElementContainingOffset(t Type, offset uint64) int {
|
|
197 return int(C.LLVMElementAtOffset(td.C, t.C, C.ulonglong(offset)))
|
|
198 }
|
|
199
|
|
200 // Computes the byte offset of the indexed struct element for a target.
|
|
201 // See the method llvm::StructLayout::getElementOffset.
|
|
202 func (td TargetData) ElementOffset(t Type, element int) uint64 {
|
|
203 return uint64(C.LLVMOffsetOfElement(td.C, t.C, C.unsigned(element)))
|
|
204 }
|
|
205
|
|
206 // Deallocates a TargetData.
|
|
207 // See the destructor llvm::TargetData::~TargetData.
|
|
208 func (td TargetData) Dispose() { C.LLVMDisposeTargetData(td.C) }
|
|
209
|
|
210 //-------------------------------------------------------------------------
|
|
211 // llvm.Target
|
|
212 //-------------------------------------------------------------------------
|
|
213
|
|
214 func FirstTarget() Target {
|
|
215 return Target{C.LLVMGetFirstTarget()}
|
|
216 }
|
|
217
|
|
218 func (t Target) NextTarget() Target {
|
|
219 return Target{C.LLVMGetNextTarget(t.C)}
|
|
220 }
|
|
221
|
|
222 func GetTargetFromTriple(triple string) (t Target, err error) {
|
|
223 var errstr *C.char
|
|
224 ctriple := C.CString(triple)
|
|
225 defer C.free(unsafe.Pointer(ctriple))
|
|
226 fail := C.LLVMGetTargetFromTriple(ctriple, &t.C, &errstr)
|
|
227 if fail != 0 {
|
|
228 err = errors.New(C.GoString(errstr))
|
|
229 C.free(unsafe.Pointer(errstr))
|
|
230 }
|
|
231 return
|
|
232 }
|
|
233
|
|
234 func (t Target) Name() string {
|
|
235 return C.GoString(C.LLVMGetTargetName(t.C))
|
|
236 }
|
|
237
|
|
238 func (t Target) Description() string {
|
|
239 return C.GoString(C.LLVMGetTargetDescription(t.C))
|
|
240 }
|
|
241
|
|
242 //-------------------------------------------------------------------------
|
|
243 // llvm.TargetMachine
|
|
244 //-------------------------------------------------------------------------
|
|
245
|
|
246 // CreateTargetMachine creates a new TargetMachine.
|
|
247 func (t Target) CreateTargetMachine(Triple string, CPU string, Features string,
|
|
248 Level CodeGenOptLevel, Reloc RelocMode,
|
|
249 CodeModel CodeModel) (tm TargetMachine) {
|
|
250 cTriple := C.CString(Triple)
|
|
251 defer C.free(unsafe.Pointer(cTriple))
|
|
252 cCPU := C.CString(CPU)
|
|
253 defer C.free(unsafe.Pointer(cCPU))
|
|
254 cFeatures := C.CString(Features)
|
|
255 defer C.free(unsafe.Pointer(cFeatures))
|
|
256 tm.C = C.LLVMCreateTargetMachine(t.C, cTriple, cCPU, cFeatures,
|
|
257 C.LLVMCodeGenOptLevel(Level),
|
|
258 C.LLVMRelocMode(Reloc),
|
|
259 C.LLVMCodeModel(CodeModel))
|
|
260 return
|
|
261 }
|
|
262
|
|
263 // Triple returns the triple describing the machine (arch-vendor-os).
|
|
264 func (tm TargetMachine) Triple() string {
|
|
265 cstr := C.LLVMGetTargetMachineTriple(tm.C)
|
|
266 return C.GoString(cstr)
|
|
267 }
|
|
268
|
|
269 // TargetData returns the TargetData for the machine.
|
|
270 func (tm TargetMachine) TargetData() TargetData {
|
|
271 return TargetData{C.LLVMGetTargetMachineData(tm.C)}
|
|
272 }
|
|
273
|
|
274 func (tm TargetMachine) EmitToMemoryBuffer(m Module, ft CodeGenFileType) (MemoryBuffer, error) {
|
|
275 var errstr *C.char
|
|
276 var mb MemoryBuffer
|
|
277 fail := C.LLVMTargetMachineEmitToMemoryBuffer(tm.C, m.C, C.LLVMCodeGenFileType(ft), &errstr, &mb.C)
|
|
278 if fail != 0 {
|
|
279 err := errors.New(C.GoString(errstr))
|
|
280 C.free(unsafe.Pointer(errstr))
|
|
281 return MemoryBuffer{}, err
|
|
282 }
|
|
283 return mb, nil
|
|
284 }
|
|
285
|
|
286 func (tm TargetMachine) AddAnalysisPasses(pm PassManager) {
|
|
287 C.LLVMAddAnalysisPasses(tm.C, pm.C)
|
|
288 }
|
|
289
|
|
290 // Dispose releases resources related to the TargetMachine.
|
|
291 func (tm TargetMachine) Dispose() {
|
|
292 C.LLVMDisposeTargetMachine(tm.C)
|
|
293 }
|
|
294
|
|
295 func DefaultTargetTriple() (triple string) {
|
|
296 cTriple := C.LLVMGetDefaultTargetTriple()
|
|
297 defer C.free(unsafe.Pointer(cTriple))
|
|
298 triple = C.GoString(cTriple)
|
|
299 return
|
|
300 }
|