-
Notifications
You must be signed in to change notification settings - Fork 80
String examples #22
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Comments
Hi Darrel! To create character arrays, set the CharArray member to package main
import (
"fmt"
"github.com/llir/llvm/ir"
"github.com/llir/llvm/ir/constant"
"github.com/llir/llvm/ir/types"
)
func main() {
// Convenience types and values.
i32 := types.I32
i8 := types.I8
i8x50 := types.NewArray(50, i8)
i8ptr := types.NewPointer
8000
(i8)
zero := constant.NewInt(i32, 0)
// Function declarations.
m := ir.NewModule()
strcpy := m.NewFunc("strcpy", i8ptr, ir.NewParam("dst", i8ptr), ir.NewParam("src", i8ptr))
strcat := m.NewFunc("strcat", i8ptr, ir.NewParam("dst", i8ptr), ir.NewParam("src", i8ptr))
printf := m.NewFunc("printf", i32, ir.NewParam("format", i8ptr))
printf.Sig.Variadic = true
// Global variables.
str := m.NewGlobalDef(".str", constant.NewCharArrayFromString("This is source\x00"))
str.Immutable = true
strElemType := str.Type().(*types.PointerType).ElemType
str1 := m.NewGlobalDef(".str.1", constant.NewCharArrayFromString("This is destination\x00"))
str1.Immutable = true
str1ElemType := str1.Type().(*types.PointerType).ElemType
str2 := m.NewGlobalDef(".str.2", constant.NewCharArrayFromString("Final destination string : |%s|\x00"))
str2.Immutable = true
str2ElemType := str2.Type().(*types.PointerType).ElemType
// Function definitions.
f := m.NewFunc("main", i32)
entry := f.NewBlock("")
tmp1 := entry.NewAlloca(i32)
tmp2 := entry.NewAlloca(i8x50)
tmp3 := entry.NewAlloca(i8x50)
entry.NewStore(zero, tmp1)
tmp4 := entry.NewGetElementPtr(i8x50, tmp2, zero, zero)
entry.NewCall(strcpy, tmp4, constant.NewGetElementPtr(strElemType, str, zero, zero))
tmp6 := entry.NewGetElementPtr(i8x50, tmp3, zero, zero)
entry.NewCall(strcpy, tmp6, constant.NewGetElementPtr(str1ElemType, str1, zero, zero))
tmp8 := entry.NewGetElementPtr(i8x50, tmp3, zero, zero)
tmp9 := entry.NewGetElementPtr(i8x50, tmp2, zero, zero)
entry.NewCall(strcat, tmp8, tmp9)
tmp11 := entry.NewGetElementPtr(i8x50, tmp3, zero, zero)
entry.NewCall(printf, constant.NewGetElementPtr(str2ElemType, str2, zero, zero), tmp11)
entry.NewRet(zero)
// Print module to standard output.
fmt.Println(m)
} Produces the following LLVM IR output: @.str = constant [15 x i8] c"This is source\00"
@.str.1 = constant [20 x i8] c"This is destination\00"
@.str.2 = constant [32 x i8] c"Final destination string : |%s|\00"
declare i8* @strcpy(i8* %dst, i8* %src)
declare i8* @strcat(i8* %dst, i8* %src)
declare i32 @printf(i8* %format, ...)
define i32 @main() {
0:
%1 = alloca i32
%2 = alloca [50 x i8]
%3 = alloca [50 x i8]
store i32 0, i32* %1
%4 = getelementptr [50 x i8], [50 x i8]* %2, i32 0, i32 0
%5 = call i8* @strcpy(i8* %4, i8* getelementptr ([15 x i8], [15 x i8]* @.str, i32 0, i32 0))
%6 = getelementptr [50 x i8], [50 x i8]* %3, i32 0, i32 0
%7 = call i8* @strcpy(i8* %6, i8* getelementptr ([20 x i8], [20 x i8]* @.str.1, i32 0, i32 0))
%8 = getelementptr [50 x i8], [50 x i8]* %3, i32 0, i32 0
%9 = getelementptr [50 x i8], [50 x i8]* %2, i32 0, i32 0
%10 = call i8* @strcat(i8* %8, i8* %9)
%11 = getelementptr [50 x i8], [50 x i8]* %3, i32 0, i32 0
%12 = call i32 (i8*, ...) @printf(i8* getelementptr ([32 x i8], [32 x i8]* @.str.2, i32 0, i32 0), i8* %11)
ret i32 0
} Edit: the code example was updated to version v0.3.6 of llir/llvm on 2024-03-09. |
Wow! Thank you so much! You went above and beyond here! Can't wait to experiment with this on the weekend. The newCharArray function was exactly what I was missing! PS. Kudos on all your hard work with this library. |
Glad to see others eager to play with LLVM IR :) If you play with something fun, would be lovely to check out your git repo later! Happy hacking! Cheers /u |
The code shown above doesn't compile in the latest version. Could it be possible to have a revision of the code? Especially the newCharArray. |
Hi @dequeb! Happy to see you are exploring the world of LLVM : ) I've updated the code example in #22 (comment) so now it should work with the latest version of llir/llvm (v0.3.6 at time of writing). In particular, there is now a function called constant.NewCharArrayFromString that will create a character array constant given a Go string. Happy coding! Cheers, |
Could you provide an example of generating llvm ir with string usage and concatenation using the API? Your main example on the readme is great for using integer values and variables but I am struggling to convert the example to use strings or pointer values in general.
I know what I would like the ir to look like, but I am unclear how to generate the resultant ir using the API.
example:
From C:
To desired llvm ir:
The text was updated successfully, but these errors were encountered: