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