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