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