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