llvm.go raw

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