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