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