Home | History | Annotate | Download | only in llvm
      1 //===- target.go - Bindings for target ------------------------------------===//
      2 //
      3 //                     The LLVM Compiler Infrastructure
      4 //
      5 // This file is distributed under the University of Illinois Open Source
      6 // License. See LICENSE.TXT for details.
      7 //
      8 //===----------------------------------------------------------------------===//
      9 //
     10 // This file defines bindings for the target component.
     11 //
     12 //===----------------------------------------------------------------------===//
     13 
     14 package llvm
     15 
     16 /*
     17 #include "llvm-c/Core.h"
     18 #include "llvm-c/Target.h"
     19 #include "llvm-c/TargetMachine.h"
     20 #include <stdlib.h>
     21 */
     22 import "C"
     23 import "unsafe"
     24 import "errors"
     25 
     26 type (
     27 	TargetData struct {
     28 		C C.LLVMTargetDataRef
     29 	}
     30 	Target struct {
     31 		C C.LLVMTargetRef
     32 	}
     33 	TargetMachine struct {
     34 		C C.LLVMTargetMachineRef
     35 	}
     36 	ByteOrdering    C.enum_LLVMByteOrdering
     37 	RelocMode       C.LLVMRelocMode
     38 	CodeGenOptLevel C.LLVMCodeGenOptLevel
     39 	CodeGenFileType C.LLVMCodeGenFileType
     40 	CodeModel       C.LLVMCodeModel
     41 )
     42 
     43 const (
     44 	BigEndian    ByteOrdering = C.LLVMBigEndian
     45 	LittleEndian ByteOrdering = C.LLVMLittleEndian
     46 )
     47 
     48 const (
     49 	RelocDefault      RelocMode = C.LLVMRelocDefault
     50 	RelocStatic       RelocMode = C.LLVMRelocStatic
     51 	RelocPIC          RelocMode = C.LLVMRelocPIC
     52 	RelocDynamicNoPic RelocMode = C.LLVMRelocDynamicNoPic
     53 )
     54 
     55 const (
     56 	CodeGenLevelNone       CodeGenOptLevel = C.LLVMCodeGenLevelNone
     57 	CodeGenLevelLess       CodeGenOptLevel = C.LLVMCodeGenLevelLess
     58 	CodeGenLevelDefault    CodeGenOptLevel = C.LLVMCodeGenLevelDefault
     59 	CodeGenLevelAggressive CodeGenOptLevel = C.LLVMCodeGenLevelAggressive
     60 )
     61 
     62 const (
     63 	CodeModelDefault    CodeModel = C.LLVMCodeModelDefault
     64 	CodeModelJITDefault CodeModel = C.LLVMCodeModelJITDefault
     65 	CodeModelSmall      CodeModel = C.LLVMCodeModelSmall
     66 	CodeModelKernel     CodeModel = C.LLVMCodeModelKernel
     67 	CodeModelMedium     CodeModel = C.LLVMCodeModelMedium
     68 	CodeModelLarge      CodeModel = C.LLVMCodeModelLarge
     69 )
     70 
     71 const (
     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.
     78 func 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.
     82 func InitializeAllTargets() { C.LLVMInitializeAllTargets() }
     83 
     84 func InitializeAllTargetMCs() { C.LLVMInitializeAllTargetMCs() }
     85 
     86 func InitializeAllAsmParsers() { C.LLVMInitializeAllAsmParsers() }
     87 
     88 func InitializeAllAsmPrinters() { C.LLVMInitializeAllAsmPrinters() }
     89 
     90 var 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.
     95 func InitializeNativeTarget() error {
     96 	fail := C.LLVMInitializeNativeTarget()
     97 	if fail != 0 {
     98 		return initializeNativeTargetError
     99 	}
    100 	return nil
    101 }
    102 
    103 func 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.
    117 func 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.
    127 func (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.
    136 func (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.
    140 func (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.
    144 func (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.
    148 func (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.
    154 func (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.
    160 func (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.
    166 func (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.
    172 func (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.
    178 func (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.
    184 func (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.
    190 func (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.
    196 func (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.
    202 func (td TargetData) Dispose() { C.LLVMDisposeTargetData(td.C) }
    203 
    204 //-------------------------------------------------------------------------
    205 // llvm.Target
    206 //-------------------------------------------------------------------------
    207 
    208 func FirstTarget() Target {
    209 	return Target{C.LLVMGetFirstTarget()}
    210 }
    211 
    212 func (t Target) NextTarget() Target {
    213 	return Target{C.LLVMGetNextTarget(t.C)}
    214 }
    215 
    216 func 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 
    228 func (t Target) Name() string {
    229 	return C.GoString(C.LLVMGetTargetName(t.C))
    230 }
    231 
    232 func (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.
    241 func (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.
    260 func (tm TargetMachine) CreateTargetData() TargetData {
    261 	return TargetData{C.LLVMCreateTargetDataLayout(tm.C)}
    262 }
    263 
    264 // Triple returns the triple describing the machine (arch-vendor-os).
    265 func (tm TargetMachine) Triple() string {
    266 	cstr := C.LLVMGetTargetMachineTriple(tm.C)
    267 	return C.GoString(cstr)
    268 }
    269 
    270 func (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 
    282 func (tm TargetMachine) AddAnalysisPasses(pm PassManager) {
    283 	C.LLVMAddAnalysisPasses(tm.C, pm.C)
    284 }
    285 
    286 // Dispose releases resources related to the TargetMachine.
    287 func (tm TargetMachine) Dispose() {
    288 	C.LLVMDisposeTargetMachine(tm.C)
    289 }
    290 
    291 func DefaultTargetTriple() (triple string) {
    292 	cTriple := C.LLVMGetDefaultTargetTriple()
    293 	defer C.free(unsafe.Pointer(cTriple))
    294 	triple = C.GoString(cTriple)
    295 	return
    296 }
    297