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