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