llvm.go raw

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