purego_llvm.go raw

   1  //go:build purego
   2  
   3  package llvm
   4  
   5  import (
   6  	"fmt"
   7  	"os"
   8  	"unsafe"
   9  
  10  	"github.com/ebitengine/purego"
  11  )
  12  
  13  type (
  14  	Context      struct{ C uintptr }
  15  	Module       struct{ C uintptr }
  16  	Type         struct{ C uintptr }
  17  	Value        struct{ C uintptr }
  18  	BasicBlock   struct{ C uintptr }
  19  	Builder      struct{ C uintptr }
  20  	Metadata     struct{ C uintptr }
  21  	Attribute    struct{ C uintptr }
  22  	Comdat       struct{ C uintptr }
  23  	MemoryBuffer struct{ C uintptr }
  24  	PassManager  struct{ C uintptr }
  25  	Use          struct{ C uintptr }
  26  )
  27  
  28  var Version string
  29  
  30  type DebugLoc struct {
  31  	Line, Col uint
  32  	Scope     Metadata
  33  	InlinedAt Metadata
  34  }
  35  
  36  func (c Context) IsNil() bool      { return c.C == 0 }
  37  func (m Module) IsNil() bool       { return m.C == 0 }
  38  func (t Type) IsNil() bool         { return t.C == 0 }
  39  func (v Value) IsNil() bool        { return v.C == 0 }
  40  func (b BasicBlock) IsNil() bool   { return b.C == 0 }
  41  func (b Builder) IsNil() bool      { return b.C == 0 }
  42  func (m Metadata) IsNil() bool     { return m.C == 0 }
  43  func (a Attribute) IsNil() bool    { return a.C == 0 }
  44  func (c Comdat) IsNil() bool       { return c.C == 0 }
  45  func (m MemoryBuffer) IsNil() bool { return m.C == 0 }
  46  func (p PassManager) IsNil() bool  { return p.C == 0 }
  47  func (u Use) IsNil() bool          { return u.C == 0 }
  48  
  49  type TypeKind int
  50  
  51  const (
  52  	VoidTypeKind      TypeKind = 0
  53  	HalfTypeKind      TypeKind = 1
  54  	FloatTypeKind     TypeKind = 2
  55  	DoubleTypeKind    TypeKind = 3
  56  	X86_FP80TypeKind  TypeKind = 4
  57  	FP128TypeKind     TypeKind = 5
  58  	PPC_FP128TypeKind TypeKind = 6
  59  	LabelTypeKind     TypeKind = 7
  60  	IntegerTypeKind   TypeKind = 8
  61  	FunctionTypeKind  TypeKind = 9
  62  	StructTypeKind    TypeKind = 10
  63  	ArrayTypeKind     TypeKind = 11
  64  	PointerTypeKind   TypeKind = 12
  65  	VectorTypeKind    TypeKind = 13
  66  	MetadataTypeKind  TypeKind = 14
  67  	TokenTypeKind     TypeKind = 16
  68  )
  69  
  70  type Opcode int
  71  
  72  const (
  73  	Ret         Opcode = 1
  74  	Br          Opcode = 2
  75  	Switch      Opcode = 3
  76  	IndirectBr  Opcode = 4
  77  	Invoke      Opcode = 5
  78  	Unreachable Opcode = 7
  79  	Add         Opcode = 8
  80  	FAdd        Opcode = 9
  81  	Sub         Opcode = 10
  82  	FSub        Opcode = 11
  83  	Mul         Opcode = 12
  84  	FMul        Opcode = 13
  85  	UDiv        Opcode = 14
  86  	SDiv        Opcode = 15
  87  	FDiv        Opcode = 16
  88  	URem        Opcode = 17
  89  	SRem        Opcode = 18
  90  	FRem        Opcode = 19
  91  	Shl         Opcode = 20
  92  	LShr        Opcode = 21
  93  	AShr        Opcode = 22
  94  	And         Opcode = 23
  95  	Or          Opcode = 24
  96  	Xor         Opcode = 25
  97  	Alloca      Opcode = 26
  98  	Load        Opcode = 27
  99  	Store       Opcode = 28
 100  	GEP            Opcode = 29
 101  	GetElementPtr  Opcode = 29
 102  	Trunc       Opcode = 30
 103  	ZExt        Opcode = 31
 104  	SExt        Opcode = 32
 105  	FPToUI      Opcode = 33
 106  	FPToSI      Opcode = 34
 107  	UIToFP      Opcode = 35
 108  	SIToFP      Opcode = 36
 109  	FPTrunc     Opcode = 37
 110  	FPExt       Opcode = 38
 111  	PtrToInt    Opcode = 39
 112  	IntToPtr    Opcode = 40
 113  	BitCast     Opcode = 41
 114  	ICmp        Opcode = 42
 115  	FCmp        Opcode = 43
 116  	PHI         Opcode = 44
 117  	Call        Opcode = 45
 118  	Select      Opcode = 46
 119  	VAArg       Opcode = 49
 120  	ExtractElement Opcode = 50
 121  	InsertElement  Opcode = 51
 122  	ShuffleVector  Opcode = 52
 123  	ExtractValue   Opcode = 53
 124  	InsertValue    Opcode = 54
 125  	Resume         Opcode = 58
 126  	LandingPad     Opcode = 59
 127  	CleanupRet     Opcode = 61
 128  	CatchRet       Opcode = 62
 129  	CatchPad       Opcode = 63
 130  	CleanupPad     Opcode = 64
 131  	CatchSwitch    Opcode = 65
 132  )
 133  
 134  type Linkage int
 135  
 136  const (
 137  	ExternalLinkage            Linkage = 0
 138  	AvailableExternallyLinkage Linkage = 1
 139  	LinkOnceAnyLinkage         Linkage = 2
 140  	LinkOnceODRLinkage         Linkage = 3
 141  	WeakAnyLinkage             Linkage = 5
 142  	WeakODRLinkage             Linkage = 6
 143  	AppendingLinkage           Linkage = 7
 144  	InternalLinkage            Linkage = 8
 145  	PrivateLinkage             Linkage = 9
 146  	ExternalWeakLinkage        Linkage = 12
 147  	CommonLinkage              Linkage = 14
 148  )
 149  
 150  type Visibility int
 151  
 152  const (
 153  	DefaultVisibility   Visibility = 0
 154  	HiddenVisibility    Visibility = 1
 155  	ProtectedVisibility Visibility = 2
 156  )
 157  
 158  type CallConv int
 159  
 160  const (
 161  	CCallConv           CallConv = 0
 162  	FastCallConv        CallConv = 8
 163  	ColdCallConv        CallConv = 9
 164  	X86StdcallCallConv  CallConv = 64
 165  	X86FastcallCallConv CallConv = 65
 166  )
 167  
 168  type IntPredicate int
 169  
 170  const (
 171  	IntEQ  IntPredicate = 32
 172  	IntNE  IntPredicate = 33
 173  	IntUGT IntPredicate = 34
 174  	IntUGE IntPredicate = 35
 175  	IntULT IntPredicate = 36
 176  	IntULE IntPredicate = 37
 177  	IntSGT IntPredicate = 38
 178  	IntSGE IntPredicate = 39
 179  	IntSLT IntPredicate = 40
 180  	IntSLE IntPredicate = 41
 181  )
 182  
 183  type FloatPredicate int
 184  
 185  const (
 186  	FloatPredicateFalse FloatPredicate = 0
 187  	FloatOEQ            FloatPredicate = 1
 188  	FloatOGT            FloatPredicate = 2
 189  	FloatOGE            FloatPredicate = 3
 190  	FloatOLT            FloatPredicate = 4
 191  	FloatOLE            FloatPredicate = 5
 192  	FloatONE            FloatPredicate = 6
 193  	FloatORD            FloatPredicate = 7
 194  	FloatUNO            FloatPredicate = 8
 195  	FloatUEQ            FloatPredicate = 9
 196  	FloatUGT            FloatPredicate = 10
 197  	FloatUGE            FloatPredicate = 11
 198  	FloatULT            FloatPredicate = 12
 199  	FloatULE            FloatPredicate = 13
 200  	FloatUNE            FloatPredicate = 14
 201  	FloatPredicateTrue  FloatPredicate = 15
 202  )
 203  
 204  type AtomicRMWBinOp int
 205  
 206  const (
 207  	AtomicRMWBinOpXchg AtomicRMWBinOp = 0
 208  	AtomicRMWBinOpAdd  AtomicRMWBinOp = 1
 209  	AtomicRMWBinOpSub  AtomicRMWBinOp = 2
 210  	AtomicRMWBinOpAnd  AtomicRMWBinOp = 3
 211  	AtomicRMWBinOpNand AtomicRMWBinOp = 4
 212  	AtomicRMWBinOpOr   AtomicRMWBinOp = 5
 213  	AtomicRMWBinOpXor  AtomicRMWBinOp = 6
 214  	AtomicRMWBinOpMax  AtomicRMWBinOp = 7
 215  	AtomicRMWBinOpMin  AtomicRMWBinOp = 8
 216  	AtomicRMWBinOpUMax AtomicRMWBinOp = 9
 217  	AtomicRMWBinOpUMin AtomicRMWBinOp = 10
 218  )
 219  
 220  type AtomicOrdering int
 221  
 222  const (
 223  	AtomicOrderingNotAtomic              AtomicOrdering = 0
 224  	AtomicOrderingUnordered              AtomicOrdering = 1
 225  	AtomicOrderingMonotonic              AtomicOrdering = 2
 226  	AtomicOrderingAcquire                AtomicOrdering = 4
 227  	AtomicOrderingRelease                AtomicOrdering = 5
 228  	AtomicOrderingAcquireRelease         AtomicOrdering = 6
 229  	AtomicOrderingSequentiallyConsistent AtomicOrdering = 7
 230  )
 231  
 232  type ComdatSelectionKind int
 233  
 234  const (
 235  	AnyComdatSelectionKind           ComdatSelectionKind = 0
 236  	ExactMatchComdatSelectionKind    ComdatSelectionKind = 1
 237  	LargestComdatSelectionKind       ComdatSelectionKind = 2
 238  	NoDeduplicateComdatSelectionKind ComdatSelectionKind = 3
 239  	SameSizeComdatSelectionKind      ComdatSelectionKind = 4
 240  )
 241  
 242  type LandingPadClause int
 243  
 244  const (
 245  	LandingPadCatch  LandingPadClause = 0
 246  	LandingPadFilter LandingPadClause = 1
 247  )
 248  
 249  type InlineAsmDialect int
 250  
 251  const (
 252  	InlineAsmDialectATT   InlineAsmDialect = 0
 253  	InlineAsmDialectIntel InlineAsmDialect = 1
 254  )
 255  
 256  var (
 257  	libLLVM  uintptr
 258  	libGlue  uintptr
 259  	initDone bool
 260  	initErr  error
 261  )
 262  
 263  func Init(llvmPath, gluePath string) error {
 264  	if initDone {
 265  		return initErr
 266  	}
 267  	initDone = true
 268  	var err error
 269  	libLLVM, err = purego.Dlopen(llvmPath, purego.RTLD_NOW|purego.RTLD_GLOBAL)
 270  	if err != nil {
 271  		initErr = fmt.Errorf("dlopen %s: %w", llvmPath, err)
 272  		return initErr
 273  	}
 274  	if gluePath != "" {
 275  		libGlue, err = purego.Dlopen(gluePath, purego.RTLD_NOW|purego.RTLD_GLOBAL)
 276  		if err != nil {
 277  			initErr = fmt.Errorf("dlopen %s: %w", gluePath, err)
 278  			return initErr
 279  		}
 280  	}
 281  	registerAll()
 282  	return nil
 283  }
 284  
 285  func mustSym(lib uintptr, name string) uintptr {
 286  	sym, err := purego.Dlsym(lib, name)
 287  	if err != nil {
 288  		fmt.Fprintf(os.Stderr, "llvmpure: missing symbol %s: %v\n", name, err)
 289  		os.Exit(1)
 290  	}
 291  	return sym
 292  }
 293  
 294  func trySym(lib uintptr, name string) uintptr {
 295  	sym, _ := purego.Dlsym(lib, name)
 296  	return sym
 297  }
 298  
 299  func goString(ptr uintptr) string {
 300  	if ptr == 0 {
 301  		return ""
 302  	}
 303  	p := (*byte)(unsafe.Pointer(ptr))
 304  	n := 0
 305  	for {
 306  		if *(*byte)(unsafe.Pointer(uintptr(unsafe.Pointer(p)) + uintptr(n))) == 0 {
 307  			break
 308  		}
 309  		n++
 310  	}
 311  	return string((*[1 << 30]byte)(unsafe.Pointer(p))[:n:n])
 312  }
 313  
 314  func cString(s string) uintptr {
 315  	b := append([]byte(s), 0)
 316  	return uintptr(unsafe.Pointer(&b[0]))
 317  }
 318  
 319  func boolToInt(b bool) uintptr {
 320  	if b {
 321  		return 1
 322  	}
 323  	return 0
 324  }
 325  
 326  func typeRefPtr(types []Type) uintptr {
 327  	if len(types) == 0 {
 328  		return 0
 329  	}
 330  	return uintptr(unsafe.Pointer(&types[0]))
 331  }
 332  
 333  func valueRefPtr(values []Value) uintptr {
 334  	if len(values) == 0 {
 335  		return 0
 336  	}
 337  	return uintptr(unsafe.Pointer(&values[0]))
 338  }
 339  
 340  func metadataRefPtr(mds []Metadata) uintptr {
 341  	if len(mds) == 0 {
 342  		return 0
 343  	}
 344  	return uintptr(unsafe.Pointer(&mds[0]))
 345  }
 346