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