From 0f48a7d299a80c2e461bdcf5b37b5f624a48d7e8 Mon Sep 17 00:00:00 2001 From: gingerBill Date: Sun, 14 Aug 2016 22:19:39 +0100 Subject: [PATCH] #foreign "custom_name"; bugs (see test.ll and test2.ll) --- examples/main.ll | 837 ++----------------------------------- examples/main.odin | 79 +++- examples/test.ll | 41 ++ examples/test2.ll | 43 ++ src/checker/stmt.cpp | 24 +- src/checker/type.cpp | 2 +- src/codegen/codegen.cpp | 14 +- src/codegen/print_llvm.cpp | 6 +- src/codegen/ssa.cpp | 12 +- src/parser.cpp | 65 ++- src/printer.cpp | 1 - 11 files changed, 261 insertions(+), 863 deletions(-) create mode 100644 examples/test.ll create mode 100644 examples/test2.ll diff --git a/examples/main.ll b/examples/main.ll index c40ed90b5..4dae460be 100644 --- a/examples/main.ll +++ b/examples/main.ll @@ -4,808 +4,45 @@ declare void @llvm.memmove.p0i8.p0i8.i64(i8*, i8*, i64, i32, i1) +declare void @putchar(i32 %c) ; foreign procedure + define void @main() { entry.-.0: - %0 = alloca <16 x i1>, align 1 ; v - store <16 x i1> zeroinitializer, <16 x i1>* %0 - %1 = alloca <16 x i1>, align 1 - store <16 x i1> zeroinitializer, <16 x i1>* %1 - %2 = load <16 x i1>, <16 x i1>* %1 - %3 = insertelement <16 x i1> %2, i1 true, i64 0 - %4 = insertelement <16 x i1> %3, i1 false, i64 1 - %5 = insertelement <16 x i1> %4, i1 false, i64 2 - %6 = insertelement <16 x i1> %5, i1 false, i64 3 - %7 = insertelement <16 x i1> %6, i1 false, i64 4 - %8 = insertelement <16 x i1> %7, i1 false, i64 5 - %9 = insertelement <16 x i1> %8, i1 false, i64 6 - %10 = insertelement <16 x i1> %9, i1 false, i64 7 - %11 = insertelement <16 x i1> %10, i1 false, i64 8 - %12 = insertelement <16 x i1> %11, i1 false, i64 9 - %13 = insertelement <16 x i1> %12, i1 false, i64 10 - %14 = insertelement <16 x i1> %13, i1 false, i64 11 - %15 = insertelement <16 x i1> %14, i1 false, i64 12 - %16 = insertelement <16 x i1> %15, i1 false, i64 13 - %17 = insertelement <16 x i1> %16, i1 false, i64 14 - %18 = insertelement <16 x i1> %17, i1 true, i64 15 - store <16 x i1> %18, <16 x i1>* %0 - %19 = load <16 x i1>, <16 x i1>* %0 - %20 = extractelement <16 x i1> %19, i64 0 - call void @print_bool(i1 %20) - call void @main$nl-0() - %21 = load <16 x i1>, <16 x i1>* %0 - %22 = extractelement <16 x i1> %21, i64 1 - call void @print_bool(i1 %22) - call void @main$nl-0() + %0 = alloca <8 x i1>, align 8 ; v + store <8 x i1> zeroinitializer, <8 x i1>* %0 + %1 = alloca <8 x i1>, align 8 + store <8 x i1> zeroinitializer, <8 x i1>* %1 + %2 = load <8 x i1>, <8 x i1>* %1, align 8 + %3 = insertelement <8 x i1> %2, i1 true, i64 0 + %4 = insertelement <8 x i1> %3, i1 false, i64 1 + %5 = insertelement <8 x i1> %4, i1 true, i64 2 + %6 = insertelement <8 x i1> %5, i1 false, i64 3 + %7 = insertelement <8 x i1> %6, i1 true, i64 4 + %8 = insertelement <8 x i1> %7, i1 false, i64 5 + %9 = insertelement <8 x i1> %8, i1 true, i64 6 + %10 = insertelement <8 x i1> %9, i1 false, i64 7 + store <8 x i1> %10, <8 x i1>* %0 + %11 = load <8 x i1>, <8 x i1>* %0, align 8 + %12 = extractelement <8 x i1> %11, i64 0 + %13 = zext i1 %12 to i32 + %14 = add i32 %13, 65 + call void @putchar(i32 %14) + %15 = load <8 x i1>, <8 x i1>* %0, align 8 + %16 = extractelement <8 x i1> %15, i64 1 + %17 = zext i1 %16 to i32 + %18 = add i32 %17, 65 + call void @putchar(i32 %18) + %19 = load <8 x i1>, <8 x i1>* %0, align 8 + %20 = extractelement <8 x i1> %19, i64 2 + %21 = zext i1 %20 to i32 + %22 = add i32 %21, 65 + call void @putchar(i32 %22) + %23 = load <8 x i1>, <8 x i1>* %0, align 8 + %24 = extractelement <8 x i1> %23, i64 3 + %25 = zext i1 %24 to i32 + %26 = add i32 %25, 65 + call void @putchar(i32 %26) + call void @putchar(i32 10) ret void } -define void @main$nl-0() { -entry.-.0: - call void @print_rune(i32 10) - ret void -} - -define void @print_hello() { -entry.-.0: - %0 = getelementptr inbounds [26 x i8], [26 x i8]* @.str0, i64 0, i64 0 - %1 = alloca %.string, align 8 - store %.string zeroinitializer, %.string* %1 - %2 = getelementptr inbounds %.string, %.string* %1, i64 0, i32 0 - %3 = getelementptr inbounds %.string, %.string* %1, i64 0, i32 1 - store i8* %0, i8** %2 - store i64 26, i64* %3 - %4 = load %.string, %.string* %1 - call void @print_string(%.string %4) - %5 = getelementptr inbounds [26 x i8], [26 x i8]* @.str1, i64 0, i64 0 - %6 = alloca %.string, align 8 - store %.string zeroinitializer, %.string* %6 - %7 = getelementptr inbounds %.string, %.string* %6, i64 0, i32 0 - %8 = getelementptr inbounds %.string, %.string* %6, i64 0, i32 1 - store i8* %5, i8** %7 - store i64 26, i64* %8 - %9 = load %.string, %.string* %6 - call void @print_string(%.string %9) - %10 = getelementptr inbounds [25 x i8], [25 x i8]* @.str2, i64 0, i64 0 - %11 = alloca %.string, align 8 - store %.string zeroinitializer, %.string* %11 - %12 = getelementptr inbounds %.string, %.string* %11, i64 0, i32 0 - %13 = getelementptr inbounds %.string, %.string* %11, i64 0, i32 1 - store i8* %10, i8** %12 - store i64 25, i64* %13 - %14 = load %.string, %.string* %11 - call void @print_string(%.string %14) - %15 = getelementptr inbounds [27 x i8], [27 x i8]* @.str3, i64 0, i64 0 - %16 = alloca %.string, align 8 - store %.string zeroinitializer, %.string* %16 - %17 = getelementptr inbounds %.string, %.string* %16, i64 0, i32 0 - %18 = getelementptr inbounds %.string, %.string* %16, i64 0, i32 1 - store i8* %15, i8** %17 - store i64 27, i64* %18 - %19 = load %.string, %.string* %16 - call void @print_string(%.string %19) - %20 = getelementptr inbounds [24 x i8], [24 x i8]* @.str4, i64 0, i64 0 - %21 = alloca %.string, align 8 - store %.string zeroinitializer, %.string* %21 - %22 = getelementptr inbounds %.string, %.string* %21, i64 0, i32 0 - %23 = getelementptr inbounds %.string, %.string* %21, i64 0, i32 1 - store i8* %20, i8** %22 - store i64 24, i64* %23 - %24 = load %.string, %.string* %21 - call void @print_string(%.string %24) - %25 = getelementptr inbounds [42 x i8], [42 x i8]* @.str5, i64 0, i64 0 - %26 = alloca %.string, align 8 - store %.string zeroinitializer, %.string* %26 - %27 = getelementptr inbounds %.string, %.string* %26, i64 0, i32 0 - %28 = getelementptr inbounds %.string, %.string* %26, i64 0, i32 1 - store i8* %25, i8** %27 - store i64 42, i64* %28 - %29 = load %.string, %.string* %26 - call void @print_string(%.string %29) - %30 = getelementptr inbounds [24 x i8], [24 x i8]* @.str6, i64 0, i64 0 - %31 = alloca %.string, align 8 - store %.string zeroinitializer, %.string* %31 - %32 = getelementptr inbounds %.string, %.string* %31, i64 0, i32 0 - %33 = getelementptr inbounds %.string, %.string* %31, i64 0, i32 1 - store i8* %30, i8** %32 - store i64 24, i64* %33 - %34 = load %.string, %.string* %31 - call void @print_string(%.string %34) - %35 = getelementptr inbounds [35 x i8], [35 x i8]* @.str7, i64 0, i64 0 - %36 = alloca %.string, align 8 - store %.string zeroinitializer, %.string* %36 - %37 = getelementptr inbounds %.string, %.string* %36, i64 0, i32 0 - %38 = getelementptr inbounds %.string, %.string* %36, i64 0, i32 1 - store i8* %35, i8** %37 - store i64 35, i64* %38 - %39 = load %.string, %.string* %36 - call void @print_string(%.string %39) - %40 = getelementptr inbounds [33 x i8], [33 x i8]* @.str8, i64 0, i64 0 - %41 = alloca %.string, align 8 - store %.string zeroinitializer, %.string* %41 - %42 = getelementptr inbounds %.string, %.string* %41, i64 0, i32 0 - %43 = getelementptr inbounds %.string, %.string* %41, i64 0, i32 1 - store i8* %40, i8** %42 - store i64 33, i64* %43 - %44 = load %.string, %.string* %41 - call void @print_string(%.string %44) - %45 = getelementptr inbounds [24 x i8], [24 x i8]* @.str9, i64 0, i64 0 - %46 = alloca %.string, align 8 - store %.string zeroinitializer, %.string* %46 - %47 = getelementptr inbounds %.string, %.string* %46, i64 0, i32 0 - %48 = getelementptr inbounds %.string, %.string* %46, i64 0, i32 1 - store i8* %45, i8** %47 - store i64 24, i64* %48 - %49 = load %.string, %.string* %46 - call void @print_string(%.string %49) - %50 = getelementptr inbounds [45 x i8], [45 x i8]* @.stra, i64 0, i64 0 - %51 = alloca %.string, align 8 - store %.string zeroinitializer, %.string* %51 - %52 = getelementptr inbounds %.string, %.string* %51, i64 0, i32 0 - %53 = getelementptr inbounds %.string, %.string* %51, i64 0, i32 1 - store i8* %50, i8** %52 - store i64 45, i64* %53 - %54 = load %.string, %.string* %51 - call void @print_string(%.string %54) - %55 = getelementptr inbounds [24 x i8], [24 x i8]* @.strb, i64 0, i64 0 - %56 = alloca %.string, align 8 - store %.string zeroinitializer, %.string* %56 - %57 = getelementptr inbounds %.string, %.string* %56, i64 0, i32 0 - %58 = getelementptr inbounds %.string, %.string* %56, i64 0, i32 1 - store i8* %55, i8** %57 - store i64 24, i64* %58 - %59 = load %.string, %.string* %56 - call void @print_string(%.string %59) - ret void -} - -declare i32 @putchar(i32 %c) ; foreign procedure - -declare %.rawptr @malloc(i64 %sz) ; foreign procedure - -declare void @free(%.rawptr %ptr) ; foreign procedure - -define void @print_string(%.string %s) { -entry.-.0: - %0 = alloca %.string, align 8 ; s - store %.string zeroinitializer, %.string* %0 - store %.string %s, %.string* %0 - %1 = alloca i64, align 8 ; i - store i64 zeroinitializer, i64* %1 - store i64 0, i64* %1 - br label %for.loop.-.2 - -for.body.-.1: - %2 = getelementptr inbounds %.string, %.string* %0, i64 0, i32 0 - %3 = load i8*, i8** %2 - %4 = load i64, i64* %1 - %5 = getelementptr i8, i8* %3, i64 %4 - %6 = load i8, i8* %5 - %7 = zext i8 %6 to i32 - %8 = call i32 @putchar(i32 %7) - br label %for.post.-.3 - -for.loop.-.2: - %9 = load i64, i64* %1 - %10 = getelementptr inbounds %.string, %.string* %0, i64 0, i32 1 - %11 = load i64, i64* %10 - %12 = icmp slt i64 %9, %11 - br i1 %12, label %for.body.-.1, label %for.done.-.4 - -for.post.-.3: - %13 = load i64, i64* %1 - %14 = add i64 %13, 1 - store i64 %14, i64* %1 - br label %for.loop.-.2 - -for.done.-.4: - ret void -} - -define void @byte_reverse({i8*, i64, i64} %b) { -entry.-.0: - %0 = alloca {i8*, i64, i64}, align 8 ; b - store {i8*, i64, i64} zeroinitializer, {i8*, i64, i64}* %0 - store {i8*, i64, i64} %b, {i8*, i64, i64}* %0 - %1 = alloca i64, align 8 ; n - store i64 zeroinitializer, i64* %1 - %2 = getelementptr inbounds {i8*, i64, i64}, {i8*, i64, i64}* %0, i64 0, i32 1 - %3 = load i64, i64* %2 - store i64 %3, i64* %1 - %4 = alloca i64, align 8 ; i - store i64 zeroinitializer, i64* %4 - store i64 0, i64* %4 - br label %for.loop.-.2 - -for.body.-.1: - %5 = getelementptr inbounds {i8*, i64, i64}, {i8*, i64, i64}* %0, i64 0, i32 0 - %6 = load i8*, i8** %5 - %7 = load i64, i64* %4 - %8 = getelementptr i8, i8* %6, i64 %7 - %9 = getelementptr inbounds {i8*, i64, i64}, {i8*, i64, i64}* %0, i64 0, i32 0 - %10 = load i8*, i8** %9 - %11 = load i64, i64* %4 - %12 = load i64, i64* %1 - %13 = sub i64 %12, 1 - %14 = sub i64 %13, %11 - %15 = getelementptr i8, i8* %10, i64 %14 - %16 = getelementptr inbounds {i8*, i64, i64}, {i8*, i64, i64}* %0, i64 0, i32 0 - %17 = load i8*, i8** %16 - %18 = load i64, i64* %4 - %19 = load i64, i64* %1 - %20 = sub i64 %19, 1 - %21 = sub i64 %20, %18 - %22 = getelementptr i8, i8* %17, i64 %21 - %23 = load i8, i8* %22 - %24 = getelementptr inbounds {i8*, i64, i64}, {i8*, i64, i64}* %0, i64 0, i32 0 - %25 = load i8*, i8** %24 - %26 = load i64, i64* %4 - %27 = getelementptr i8, i8* %25, i64 %26 - %28 = load i8, i8* %27 - store i8 %23, i8* %8 - store i8 %28, i8* %15 - br label %for.post.-.3 - -for.loop.-.2: - %29 = load i64, i64* %4 - %30 = load i64, i64* %1 - %31 = sdiv i64 %30, 2 - %32 = icmp slt i64 %29, %31 - br i1 %32, label %for.body.-.1, label %for.done.-.4 - -for.post.-.3: - %33 = load i64, i64* %4 - %34 = add i64 %33, 1 - store i64 %34, i64* %4 - br label %for.loop.-.2 - -for.done.-.4: - ret void -} - -define {[4 x i8], i64} @encode_rune(i32 %r) { -entry.-.0: - %0 = alloca i32, align 4 ; r - store i32 zeroinitializer, i32* %0 - store i32 %r, i32* %0 - %1 = alloca [4 x i8], align 1 ; buf - store [4 x i8] zeroinitializer, [4 x i8]* %1 - %2 = alloca i32, align 4 ; i - store i32 zeroinitializer, i32* %2 - %3 = load i32, i32* %0 - store i32 %3, i32* %2 - %4 = load i32, i32* %2 - %5 = icmp ule i32 %4, 127 - br i1 %5, label %if.then.-.1, label %if.done.-.2 - -if.then.-.1: - %6 = getelementptr inbounds [4 x i8], [4 x i8]* %1, i64 0, i64 0 - %7 = getelementptr i8, i8* %6, i64 0 - %8 = load i32, i32* %0 - %9 = trunc i32 %8 to i8 - store i8 %9, i8* %7 - %10 = alloca {[4 x i8], i64}, align 8 - store {[4 x i8], i64} zeroinitializer, {[4 x i8], i64}* %10 - %11 = load [4 x i8], [4 x i8]* %1 - %12 = getelementptr inbounds {[4 x i8], i64}, {[4 x i8], i64}* %10, i64 0, i32 0 - store [4 x i8] %11, [4 x i8]* %12 - %13 = getelementptr inbounds {[4 x i8], i64}, {[4 x i8], i64}* %10, i64 0, i32 1 - store i64 1, i64* %13 - %14 = load {[4 x i8], i64}, {[4 x i8], i64}* %10 - ret {[4 x i8], i64} %14 - -if.done.-.2: - %15 = load i32, i32* %2 - %16 = icmp ule i32 %15, 2047 - br i1 %16, label %if.then.-.3, label %if.done.-.4 - -if.then.-.3: - %17 = getelementptr inbounds [4 x i8], [4 x i8]* %1, i64 0, i64 0 - %18 = getelementptr i8, i8* %17, i64 0 - %19 = load i32, i32* %0 - %20 = lshr i32 %19, 6 - %21 = trunc i32 %20 to i8 - %22 = or i8 192, %21 - store i8 %22, i8* %18 - %23 = getelementptr inbounds [4 x i8], [4 x i8]* %1, i64 0, i64 0 - %24 = getelementptr i8, i8* %23, i64 1 - %25 = load i32, i32* %0 - %26 = trunc i32 %25 to i8 - %27 = and i8 %26, 63 - %28 = or i8 128, %27 - store i8 %28, i8* %24 - %29 = alloca {[4 x i8], i64}, align 8 - store {[4 x i8], i64} zeroinitializer, {[4 x i8], i64}* %29 - %30 = load [4 x i8], [4 x i8]* %1 - %31 = getelementptr inbounds {[4 x i8], i64}, {[4 x i8], i64}* %29, i64 0, i32 0 - store [4 x i8] %30, [4 x i8]* %31 - %32 = getelementptr inbounds {[4 x i8], i64}, {[4 x i8], i64}* %29, i64 0, i32 1 - store i64 2, i64* %32 - %33 = load {[4 x i8], i64}, {[4 x i8], i64}* %29 - ret {[4 x i8], i64} %33 - -if.done.-.4: - %34 = load i32, i32* %2 - %35 = icmp ugt i32 %34, 1114111 - br i1 %35, label %if.then.-.5, label %cmp-or.-.6 - -if.then.-.5: - store i32 65533, i32* %0 - br label %if.done.-.8 - -cmp-or.-.6: - %36 = load i32, i32* %2 - %37 = icmp uge i32 %36, 55296 - br i1 %37, label %cmp-and.-.7, label %if.done.-.8 - -cmp-and.-.7: - %38 = load i32, i32* %2 - %39 = icmp ule i32 %38, 57343 - br i1 %39, label %if.then.-.5, label %if.done.-.8 - -if.done.-.8: - %40 = load i32, i32* %2 - %41 = icmp ule i32 %40, 65535 - br i1 %41, label %if.then.-.9, label %if.done.-.10 - -if.then.-.9: - %42 = getelementptr inbounds [4 x i8], [4 x i8]* %1, i64 0, i64 0 - %43 = getelementptr i8, i8* %42, i64 0 - %44 = load i32, i32* %0 - %45 = lshr i32 %44, 12 - %46 = trunc i32 %45 to i8 - %47 = or i8 224, %46 - store i8 %47, i8* %43 - %48 = getelementptr inbounds [4 x i8], [4 x i8]* %1, i64 0, i64 0 - %49 = getelementptr i8, i8* %48, i64 1 - %50 = load i32, i32* %0 - %51 = lshr i32 %50, 6 - %52 = trunc i32 %51 to i8 - %53 = and i8 %52, 63 - %54 = or i8 128, %53 - store i8 %54, i8* %49 - %55 = getelementptr inbounds [4 x i8], [4 x i8]* %1, i64 0, i64 0 - %56 = getelementptr i8, i8* %55, i64 2 - %57 = load i32, i32* %0 - %58 = trunc i32 %57 to i8 - %59 = and i8 %58, 63 - %60 = or i8 128, %59 - store i8 %60, i8* %56 - %61 = alloca {[4 x i8], i64}, align 8 - store {[4 x i8], i64} zeroinitializer, {[4 x i8], i64}* %61 - %62 = load [4 x i8], [4 x i8]* %1 - %63 = getelementptr inbounds {[4 x i8], i64}, {[4 x i8], i64}* %61, i64 0, i32 0 - store [4 x i8] %62, [4 x i8]* %63 - %64 = getelementptr inbounds {[4 x i8], i64}, {[4 x i8], i64}* %61, i64 0, i32 1 - store i64 3, i64* %64 - %65 = load {[4 x i8], i64}, {[4 x i8], i64}* %61 - ret {[4 x i8], i64} %65 - -if.done.-.10: - %66 = getelementptr inbounds [4 x i8], [4 x i8]* %1, i64 0, i64 0 - %67 = getelementptr i8, i8* %66, i64 0 - %68 = load i32, i32* %0 - %69 = lshr i32 %68, 18 - %70 = trunc i32 %69 to i8 - %71 = or i8 240, %70 - store i8 %71, i8* %67 - %72 = getelementptr inbounds [4 x i8], [4 x i8]* %1, i64 0, i64 0 - %73 = getelementptr i8, i8* %72, i64 1 - %74 = load i32, i32* %0 - %75 = lshr i32 %74, 12 - %76 = trunc i32 %75 to i8 - %77 = and i8 %76, 63 - %78 = or i8 128, %77 - store i8 %78, i8* %73 - %79 = getelementptr inbounds [4 x i8], [4 x i8]* %1, i64 0, i64 0 - %80 = getelementptr i8, i8* %79, i64 2 - %81 = load i32, i32* %0 - %82 = lshr i32 %81, 6 - %83 = trunc i32 %82 to i8 - %84 = and i8 %83, 63 - %85 = or i8 128, %84 - store i8 %85, i8* %80 - %86 = getelementptr inbounds [4 x i8], [4 x i8]* %1, i64 0, i64 0 - %87 = getelementptr i8, i8* %86, i64 3 - %88 = load i32, i32* %0 - %89 = trunc i32 %88 to i8 - %90 = and i8 %89, 63 - %91 = or i8 128, %90 - store i8 %91, i8* %87 - %92 = alloca {[4 x i8], i64}, align 8 - store {[4 x i8], i64} zeroinitializer, {[4 x i8], i64}* %92 - %93 = load [4 x i8], [4 x i8]* %1 - %94 = getelementptr inbounds {[4 x i8], i64}, {[4 x i8], i64}* %92, i64 0, i32 0 - store [4 x i8] %93, [4 x i8]* %94 - %95 = getelementptr inbounds {[4 x i8], i64}, {[4 x i8], i64}* %92, i64 0, i32 1 - store i64 4, i64* %95 - %96 = load {[4 x i8], i64}, {[4 x i8], i64}* %92 - ret {[4 x i8], i64} %96 -} - -define void @print_rune(i32 %r) { -entry.-.0: - %0 = alloca i32, align 4 ; r - store i32 zeroinitializer, i32* %0 - store i32 %r, i32* %0 - %1 = alloca [4 x i8], align 1 ; buf - store [4 x i8] zeroinitializer, [4 x i8]* %1 - %2 = alloca i64, align 8 ; n - store i64 zeroinitializer, i64* %2 - %3 = load i32, i32* %0 - %4 = call {[4 x i8], i64} @encode_rune(i32 %3) - %5 = extractvalue {[4 x i8], i64} %4, 0 - %6 = extractvalue {[4 x i8], i64} %4, 1 - store [4 x i8] %5, [4 x i8]* %1 - store i64 %6, i64* %2 - %7 = alloca %.string, align 8 ; str - store %.string zeroinitializer, %.string* %7 - %8 = load i64, i64* %2 - %9 = sub i64 %8, 0 - %10 = sub i64 4, 0 - %11 = getelementptr inbounds [4 x i8], [4 x i8]* %1, i64 0, i64 0 - %12 = getelementptr i8, i8* %11, i64 0 - %13 = alloca {i8*, i64, i64}, align 8 - store {i8*, i64, i64} zeroinitializer, {i8*, i64, i64}* %13 - %14 = getelementptr inbounds {i8*, i64, i64}, {i8*, i64, i64}* %13, i64 0, i32 0 - store i8* %12, i8** %14 - %15 = getelementptr inbounds {i8*, i64, i64}, {i8*, i64, i64}* %13, i64 0, i32 1 - store i64 %9, i64* %15 - %16 = getelementptr inbounds {i8*, i64, i64}, {i8*, i64, i64}* %13, i64 0, i32 2 - store i64 %10, i64* %16 - %17 = load {i8*, i64, i64}, {i8*, i64, i64}* %13 - %18 = alloca {i8*, i64, i64}, align 8 - store {i8*, i64, i64} zeroinitializer, {i8*, i64, i64}* %18 - store {i8*, i64, i64} %17, {i8*, i64, i64}* %18 - %19 = getelementptr inbounds {i8*, i64, i64}, {i8*, i64, i64}* %18, i64 0, i32 0 - %20 = load i8*, i8** %19 - %21 = getelementptr inbounds {i8*, i64, i64}, {i8*, i64, i64}* %18, i64 0, i32 1 - %22 = load i64, i64* %21 - %23 = alloca %.string, align 8 - store %.string zeroinitializer, %.string* %23 - %24 = getelementptr inbounds %.string, %.string* %23, i64 0, i32 0 - %25 = getelementptr inbounds %.string, %.string* %23, i64 0, i32 1 - store i8* %20, i8** %24 - store i64 %22, i64* %25 - %26 = load %.string, %.string* %23 - store %.string %26, %.string* %7 - %27 = load %.string, %.string* %7 - call void @print_string(%.string %27) - ret void -} - -define void @print_int(i64 %i) { -entry.-.0: - %0 = alloca i64, align 8 ; i - store i64 zeroinitializer, i64* %0 - store i64 %i, i64* %0 - %1 = load i64, i64* %0 - call void @print_int_base(i64 %1, i64 10) - ret void -} - -define void @print_int_base(i64 %i, i64 %base) { -entry.-.0: - %0 = alloca i64, align 8 ; i - store i64 zeroinitializer, i64* %0 - store i64 %i, i64* %0 - %1 = alloca i64, align 8 ; base - store i64 zeroinitializer, i64* %1 - store i64 %base, i64* %1 - %2 = alloca [65 x i8], align 1 ; buf - store [65 x i8] zeroinitializer, [65 x i8]* %2 - %3 = alloca i64, align 8 ; len - store i64 zeroinitializer, i64* %3 - store i64 0, i64* %3 - %4 = alloca i1, align 1 ; negative - store i1 zeroinitializer, i1* %4 - store i1 false, i1* %4 - %5 = load i64, i64* %0 - %6 = icmp slt i64 %5, 0 - br i1 %6, label %if.then.-.1, label %if.done.-.2 - -if.then.-.1: - store i1 true, i1* %4 - %7 = load i64, i64* %0 - %8 = sub i64 0, %7 - store i64 %8, i64* %0 - br label %if.done.-.2 - -if.done.-.2: - %9 = load i64, i64* %0 - %10 = icmp eq i64 %9, 0 - br i1 %10, label %if.then.-.3, label %if.done.-.4 - -if.then.-.3: - %11 = getelementptr inbounds [65 x i8], [65 x i8]* %2, i64 0, i64 0 - %12 = load i64, i64* %3 - %13 = getelementptr i8, i8* %11, i64 %12 - store i8 48, i8* %13 - %14 = load i64, i64* %3 - %15 = add i64 %14, 1 - store i64 %15, i64* %3 - br label %if.done.-.4 - -if.done.-.4: - br label %for.loop.-.6 - -for.body.-.5: - %16 = getelementptr inbounds [65 x i8], [65 x i8]* %2, i64 0, i64 0 - %17 = load i64, i64* %3 - %18 = getelementptr i8, i8* %16, i64 %17 - %19 = getelementptr inbounds [64 x i8], [64 x i8]* @.strc, i64 0, i64 0 - %20 = load i64, i64* %1 - %21 = load i64, i64* %0 - %22 = srem i64 %21, %20 - %23 = getelementptr i8, i8* %19, i64 %22 - %24 = load i8, i8* %23 - store i8 %24, i8* %18 - %25 = load i64, i64* %3 - %26 = add i64 %25, 1 - store i64 %26, i64* %3 - %27 = load i64, i64* %1 - %28 = load i64, i64* %0 - %29 = sdiv i64 %28, %27 - store i64 %29, i64* %0 - br label %for.loop.-.6 - -for.loop.-.6: - %30 = load i64, i64* %0 - %31 = icmp sgt i64 %30, 0 - br i1 %31, label %for.body.-.5, label %for.done.-.7 - -for.done.-.7: - %32 = load i1, i1* %4 - br i1 %32, label %if.then.-.8, label %if.done.-.9 - -if.then.-.8: - %33 = getelementptr inbounds [65 x i8], [65 x i8]* %2, i64 0, i64 0 - %34 = load i64, i64* %3 - %35 = getelementptr i8, i8* %33, i64 %34 - store i8 45, i8* %35 - %36 = load i64, i64* %3 - %37 = add i64 %36, 1 - store i64 %37, i64* %3 - br label %if.done.-.9 - -if.done.-.9: - %38 = load i64, i64* %3 - %39 = sub i64 %38, 0 - %40 = sub i64 65, 0 - %41 = getelementptr inbounds [65 x i8], [65 x i8]* %2, i64 0, i64 0 - %42 = getelementptr i8, i8* %41, i64 0 - %43 = alloca {i8*, i64, i64}, align 8 - store {i8*, i64, i64} zeroinitializer, {i8*, i64, i64}* %43 - %44 = getelementptr inbounds {i8*, i64, i64}, {i8*, i64, i64}* %43, i64 0, i32 0 - store i8* %42, i8** %44 - %45 = getelementptr inbounds {i8*, i64, i64}, {i8*, i64, i64}* %43, i64 0, i32 1 - store i64 %39, i64* %45 - %46 = getelementptr inbounds {i8*, i64, i64}, {i8*, i64, i64}* %43, i64 0, i32 2 - store i64 %40, i64* %46 - %47 = load {i8*, i64, i64}, {i8*, i64, i64}* %43 - call void @byte_reverse({i8*, i64, i64} %47) - %48 = load i64, i64* %3 - %49 = sub i64 %48, 0 - %50 = sub i64 65, 0 - %51 = getelementptr inbounds [65 x i8], [65 x i8]* %2, i64 0, i64 0 - %52 = getelementptr i8, i8* %51, i64 0 - %53 = alloca {i8*, i64, i64}, align 8 - store {i8*, i64, i64} zeroinitializer, {i8*, i64, i64}* %53 - %54 = getelementptr inbounds {i8*, i64, i64}, {i8*, i64, i64}* %53, i64 0, i32 0 - store i8* %52, i8** %54 - %55 = getelementptr inbounds {i8*, i64, i64}, {i8*, i64, i64}* %53, i64 0, i32 1 - store i64 %49, i64* %55 - %56 = getelementptr inbounds {i8*, i64, i64}, {i8*, i64, i64}* %53, i64 0, i32 2 - store i64 %50, i64* %56 - %57 = load {i8*, i64, i64}, {i8*, i64, i64}* %53 - %58 = alloca {i8*, i64, i64}, align 8 - store {i8*, i64, i64} zeroinitializer, {i8*, i64, i64}* %58 - store {i8*, i64, i64} %57, {i8*, i64, i64}* %58 - %59 = getelementptr inbounds {i8*, i64, i64}, {i8*, i64, i64}* %58, i64 0, i32 0 - %60 = load i8*, i8** %59 - %61 = getelementptr inbounds {i8*, i64, i64}, {i8*, i64, i64}* %58, i64 0, i32 1 - %62 = load i64, i64* %61 - %63 = alloca %.string, align 8 - store %.string zeroinitializer, %.string* %63 - %64 = getelementptr inbounds %.string, %.string* %63, i64 0, i32 0 - %65 = getelementptr inbounds %.string, %.string* %63, i64 0, i32 1 - store i8* %60, i8** %64 - store i64 %62, i64* %65 - %66 = load %.string, %.string* %63 - call void @print_string(%.string %66) - ret void -} - -define void @print_uint(i64 %i) { -entry.-.0: - %0 = alloca i64, align 8 ; i - store i64 zeroinitializer, i64* %0 - store i64 %i, i64* %0 - %1 = load i64, i64* %0 - call void @print_uint_base(i64 %1, i64 10) - ret void -} - -define void @print_uint_base(i64 %i, i64 %base) { -entry.-.0: - %0 = alloca i64, align 8 ; i - store i64 zeroinitializer, i64* %0 - store i64 %i, i64* %0 - %1 = alloca i64, align 8 ; base - store i64 zeroinitializer, i64* %1 - store i64 %base, i64* %1 - %2 = alloca [65 x i8], align 1 ; buf - store [65 x i8] zeroinitializer, [65 x i8]* %2 - %3 = alloca i64, align 8 ; len - store i64 zeroinitializer, i64* %3 - store i64 0, i64* %3 - %4 = alloca i1, align 1 ; negative - store i1 zeroinitializer, i1* %4 - store i1 false, i1* %4 - %5 = load i64, i64* %0 - %6 = icmp ult i64 %5, 0 - br i1 %6, label %if.then.-.1, label %if.done.-.2 - -if.then.-.1: - store i1 true, i1* %4 - %7 = load i64, i64* %0 - %8 = sub i64 0, %7 - store i64 %8, i64* %0 - br label %if.done.-.2 - -if.done.-.2: - %9 = load i64, i64* %0 - %10 = icmp eq i64 %9, 0 - br i1 %10, label %if.then.-.3, label %if.done.-.4 - -if.then.-.3: - %11 = getelementptr inbounds [65 x i8], [65 x i8]* %2, i64 0, i64 0 - %12 = load i64, i64* %3 - %13 = getelementptr i8, i8* %11, i64 %12 - store i8 48, i8* %13 - %14 = load i64, i64* %3 - %15 = add i64 %14, 1 - store i64 %15, i64* %3 - br label %if.done.-.4 - -if.done.-.4: - br label %for.loop.-.6 - -for.body.-.5: - %16 = getelementptr inbounds [65 x i8], [65 x i8]* %2, i64 0, i64 0 - %17 = load i64, i64* %3 - %18 = getelementptr i8, i8* %16, i64 %17 - %19 = getelementptr inbounds [64 x i8], [64 x i8]* @.strd, i64 0, i64 0 - %20 = load i64, i64* %1 - %21 = load i64, i64* %0 - %22 = urem i64 %21, %20 - %23 = getelementptr i8, i8* %19, i64 %22 - %24 = load i8, i8* %23 - store i8 %24, i8* %18 - %25 = load i64, i64* %3 - %26 = add i64 %25, 1 - store i64 %26, i64* %3 - %27 = load i64, i64* %1 - %28 = load i64, i64* %0 - %29 = udiv i64 %28, %27 - store i64 %29, i64* %0 - br label %for.loop.-.6 - -for.loop.-.6: - %30 = load i64, i64* %0 - %31 = icmp ugt i64 %30, 0 - br i1 %31, label %for.body.-.5, label %for.done.-.7 - -for.done.-.7: - %32 = load i1, i1* %4 - br i1 %32, label %if.then.-.8, label %if.done.-.9 - -if.then.-.8: - %33 = getelementptr inbounds [65 x i8], [65 x i8]* %2, i64 0, i64 0 - %34 = load i64, i64* %3 - %35 = getelementptr i8, i8* %33, i64 %34 - store i8 45, i8* %35 - %36 = load i64, i64* %3 - %37 = add i64 %36, 1 - store i64 %37, i64* %3 - br label %if.done.-.9 - -if.done.-.9: - %38 = load i64, i64* %3 - %39 = sub i64 %38, 0 - %40 = sub i64 65, 0 - %41 = getelementptr inbounds [65 x i8], [65 x i8]* %2, i64 0, i64 0 - %42 = getelementptr i8, i8* %41, i64 0 - %43 = alloca {i8*, i64, i64}, align 8 - store {i8*, i64, i64} zeroinitializer, {i8*, i64, i64}* %43 - %44 = getelementptr inbounds {i8*, i64, i64}, {i8*, i64, i64}* %43, i64 0, i32 0 - store i8* %42, i8** %44 - %45 = getelementptr inbounds {i8*, i64, i64}, {i8*, i64, i64}* %43, i64 0, i32 1 - store i64 %39, i64* %45 - %46 = getelementptr inbounds {i8*, i64, i64}, {i8*, i64, i64}* %43, i64 0, i32 2 - store i64 %40, i64* %46 - %47 = load {i8*, i64, i64}, {i8*, i64, i64}* %43 - call void @byte_reverse({i8*, i64, i64} %47) - %48 = load i64, i64* %3 - %49 = sub i64 %48, 0 - %50 = sub i64 65, 0 - %51 = getelementptr inbounds [65 x i8], [65 x i8]* %2, i64 0, i64 0 - %52 = getelementptr i8, i8* %51, i64 0 - %53 = alloca {i8*, i64, i64}, align 8 - store {i8*, i64, i64} zeroinitializer, {i8*, i64, i64}* %53 - %54 = getelementptr inbounds {i8*, i64, i64}, {i8*, i64, i64}* %53, i64 0, i32 0 - store i8* %52, i8** %54 - %55 = getelementptr inbounds {i8*, i64, i64}, {i8*, i64, i64}* %53, i64 0, i32 1 - store i64 %49, i64* %55 - %56 = getelementptr inbounds {i8*, i64, i64}, {i8*, i64, i64}* %53, i64 0, i32 2 - store i64 %50, i64* %56 - %57 = load {i8*, i64, i64}, {i8*, i64, i64}* %53 - %58 = alloca {i8*, i64, i64}, align 8 - store {i8*, i64, i64} zeroinitializer, {i8*, i64, i64}* %58 - store {i8*, i64, i64} %57, {i8*, i64, i64}* %58 - %59 = getelementptr inbounds {i8*, i64, i64}, {i8*, i64, i64}* %58, i64 0, i32 0 - %60 = load i8*, i8** %59 - %61 = getelementptr inbounds {i8*, i64, i64}, {i8*, i64, i64}* %58, i64 0, i32 1 - %62 = load i64, i64* %61 - %63 = alloca %.string, align 8 - store %.string zeroinitializer, %.string* %63 - %64 = getelementptr inbounds %.string, %.string* %63, i64 0, i32 0 - %65 = getelementptr inbounds %.string, %.string* %63, i64 0, i32 1 - store i8* %60, i8** %64 - store i64 %62, i64* %65 - %66 = load %.string, %.string* %63 - call void @print_string(%.string %66) - ret void -} - -define void @print_bool(i1 %b) { -entry.-.0: - %0 = alloca i1, align 1 ; b - store i1 zeroinitializer, i1* %0 - store i1 %b, i1* %0 - %1 = load i1, i1* %0 - br i1 %1, label %if.then.-.1, label %if.else.-.2 - -if.then.-.1: - %2 = getelementptr inbounds [4 x i8], [4 x i8]* @.stre, i64 0, i64 0 - %3 = alloca %.string, align 8 - store %.string zeroinitializer, %.string* %3 - %4 = getelementptr inbounds %.string, %.string* %3, i64 0, i32 0 - %5 = getelementptr inbounds %.string, %.string* %3, i64 0, i32 1 - store i8* %2, i8** %4 - store i64 4, i64* %5 - %6 = load %.string, %.string* %3 - call void @print_string(%.string %6) - br label %if.done.-.3 - -if.else.-.2: - %7 = getelementptr inbounds [5 x i8], [5 x i8]* @.strf, i64 0, i64 0 - %8 = alloca %.string, align 8 - store %.string zeroinitializer, %.string* %8 - %9 = getelementptr inbounds %.string, %.string* %8, i64 0, i32 0 - %10 = getelementptr inbounds %.string, %.string* %8, i64 0, i32 1 - store i8* %7, i8** %9 - store i64 5, i64* %10 - %11 = load %.string, %.string* %8 - call void @print_string(%.string %11) - br label %if.done.-.3 - -if.done.-.3: - ret void -} - -@.str0 = global [26 x i8] c"Chinese\20\20\20\20-\20\E4\BD\A0\E5\A5\BD\E4\B8\96\E7\95\8C\0A" -@.str1 = global [26 x i8] c"Dutch\20\20\20\20\20\20-\20Hello\20wereld\0A" -@.str2 = global [25 x i8] c"English\20\20\20\20-\20Hello\20world\0A" -@.str3 = global [27 x i8] c"French\20\20\20\20\20-\20Bonjour\20monde\0A" -@.str4 = global [24 x i8] c"German\20\20\20\20\20-\20Hallo\20Welt\0A" -@.str5 = global [42 x i8] c"Greek\20\20\20\20\20\20-\20\CE\B3\CE\B5\CE\B9\CE\AC\20\CF\83\CE\BF\CF\85\20\CE\BA\CF\8C\CF\83\CE\BC\CE\BF\CF\82\0A" -@.str6 = global [24 x i8] c"Italian\20\20\20\20-\20Ciao\20mondo\0A" -@.str7 = global [35 x i8] c"Japanese\20\20\20-\20\E3\81\93\E3\82\93\E3\81\AB\E3\81\A1\E3\81\AF\E4\B8\96\E7\95\8C\0A" -@.str8 = global [33 x i8] c"Korean\20\20\20\20\20-\20\EC\97\AC\EB\B3\B4\EC\84\B8\EC\9A\94\20\EC\84\B8\EA\B3\84\0A" -@.str9 = global [24 x i8] c"Portuguese\20-\20Ol\C3\A1\20mundo\0A" -@.stra = global [45 x i8] c"Russian\20\20\20\20-\20\D0\97\D0\B4\D1\80\D0\B0\D0\B2\D1\81\D1\82\D0\B2\D1\83\D0\BB\D1\82\D0\B5\20\D0\BC\D0\B8\D1\80\0A" -@.strb = global [24 x i8] c"Spanish\20\20\20\20-\20Hola\20mundo\0A" -@.strc = global [64 x i8] c"0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz\40$" -@.strd = global [64 x i8] c"0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz\40$" -@.stre = global [4 x i8] c"true" -@.strf = global [5 x i8] c"false" diff --git a/examples/main.odin b/examples/main.odin index e77d2f1bb..1e4274491 100644 --- a/examples/main.odin +++ b/examples/main.odin @@ -1,3 +1,17 @@ +pc :: proc(c: i32) #foreign "putchar" + +main :: proc() { + f :: false; + t :: true; + v := {8}bool{t, f, t, f, t, f, t, f}; + pc(v[0] as rune + 'A'); + pc(v[1] as rune + 'A'); + pc(v[2] as rune + 'A'); + pc(v[3] as rune + 'A'); + pc('\n'); +} + +/* import "basic" TWO_HEARTS :: '💕'; @@ -8,12 +22,36 @@ main :: proc() { t :: true; f :: false; - v := {16}bool{ - t, f, f, f, f, f, f, f, - f, f, f, f, f, f, f, t, - }; - print_bool(v[0]); nl(); - print_bool(v[1]); nl(); + // v := {8}bool{t, t, t, f, f, f, t, t}; + v : {8}bool; + v[0] = true; + v[1] = false; + v[2] = true; + + for i := 0; i < len(v); i++ { + b := v[i]; + if b { + print_rune('t'); + } else { + print_rune('f'); + } + nl(); + } + // v[1] = false; + // v[2] = true; + // print_rune(v[0] as rune + 65); nl(); + // print_rune(v[1] as rune + 65); nl(); + // print_rune(v[2] as rune + 65); nl(); + + + // for i := 0; i < len(v); i++ { + // v[i] = (i%2) == 0; + // } + // for i := 0; i < len(v); i++ { + // print_bool(v[i]); nl(); + // } + + // print_int(v transmute u8 as int); /* DATA_SIZE :: 100; data := malloc(DATA_SIZE); @@ -37,17 +75,18 @@ main :: proc() { } -print_hello :: proc() { - print_string("Chinese - 你好世界\n"); - print_string("Dutch - Hello wereld\n"); - print_string("English - Hello world\n"); - print_string("French - Bonjour monde\n"); - print_string("German - Hallo Welt\n"); - print_string("Greek - γειά σου κόσμος\n"); - print_string("Italian - Ciao mondo\n"); - print_string("Japanese - こんにちは世界\n"); - print_string("Korean - 여보세요 세계\n"); - print_string("Portuguese - Olá mundo\n"); - print_string("Russian - Здравствулте мир\n"); - print_string("Spanish - Hola mundo\n"); -} +// print_hello :: proc() { +// print_string("Chinese - 你好世界\n"); +// print_string("Dutch - Hello wereld\n"); +// print_string("English - Hello world\n"); +// print_string("French - Bonjour monde\n"); +// print_string("German - Hallo Welt\n"); +// print_string("Greek - γειά σου κόσμος\n"); +// print_string("Italian - Ciao mondo\n"); +// print_string("Japanese - こんにちは世界\n"); +// print_string("Korean - 여보세요 세계\n"); +// print_string("Portuguese - Olá mundo\n"); +// print_string("Russian - Здравствулте мир\n"); +// print_string("Spanish - Hola mundo\n"); +// } +*/ diff --git a/examples/test.ll b/examples/test.ll new file mode 100644 index 000000000..7dc066390 --- /dev/null +++ b/examples/test.ll @@ -0,0 +1,41 @@ +declare i32 @putchar(i32) + +define void @main() { +entry: + %0 = alloca <8 x i1>, align 8 ; v + store <8 x i1> zeroinitializer, <8 x i1>* %0 + %1 = alloca <8 x i1>, align 8 + store <8 x i1> zeroinitializer, <8 x i1>* %1 + %2 = load <8 x i1>, <8 x i1>* %1, align 8 + %3 = insertelement <8 x i1> %2, i1 true, i64 0 + %4 = insertelement <8 x i1> %3, i1 false, i64 1 + %5 = insertelement <8 x i1> %4, i1 true, i64 2 + %6 = insertelement <8 x i1> %5, i1 false, i64 3 + %7 = insertelement <8 x i1> %6, i1 true, i64 4 + %8 = insertelement <8 x i1> %7, i1 false, i64 5 + %9 = insertelement <8 x i1> %8, i1 true, i64 6 + %10 = insertelement <8 x i1> %9, i1 false, i64 7 + store <8 x i1> %10, <8 x i1>* %0 + + %11 = load <8 x i1>, <8 x i1>* %0, align 8 + %12 = extractelement <8 x i1> %11, i64 0 + %13 = zext i1 %12 to i32 + %14 = add i32 %13, 65 ; + 'A' + %15 = call i32 @putchar(i32 %14) + + %16 = load <8 x i1>, <8 x i1>* %0, align 8 + %17 = extractelement <8 x i1> %16, i64 1 + %18 = zext i1 %17 to i32 + %19 = add i32 %18, 65 ; + 'A' + %20 = call i32 @putchar(i32 %19) + + %21 = load <8 x i1>, <8 x i1>* %0, align 8 + %22 = extractelement <8 x i1> %21, i64 2 + %23 = zext i1 %22 to i32 + %24 = add i32 %23, 65 ; + 'A' + %25 = call i32 @putchar(i32 %24) + + %26 = call i32 @putchar(i32 10) ; \n + + ret void +} diff --git a/examples/test2.ll b/examples/test2.ll new file mode 100644 index 000000000..446c5532d --- /dev/null +++ b/examples/test2.ll @@ -0,0 +1,43 @@ +declare i32 @putchar(i32) + +define void @main() { +entry: + %0 = alloca <8 x i1>, align 8 ; v + store <8 x i1> zeroinitializer, <8 x i1>* %0 + %1 = alloca <8 x i1>, align 8 + store <8 x i1> zeroinitializer, <8 x i1>* %1 + %2 = load <8 x i1>, <8 x i1>* %1, align 8 + %3 = insertelement <8 x i1> %2, i1 true, i64 0 + %4 = insertelement <8 x i1> %3, i1 false, i64 1 + %5 = insertelement <8 x i1> %4, i1 true, i64 2 + %6 = insertelement <8 x i1> %5, i1 false, i64 3 + %7 = insertelement <8 x i1> %6, i1 true, i64 4 + %8 = insertelement <8 x i1> %7, i1 false, i64 5 + %9 = insertelement <8 x i1> %8, i1 true, i64 6 + %10 = insertelement <8 x i1> %9, i1 false, i64 7 + store <8 x i1> %10, <8 x i1>* %0 + + %11 = load <8 x i1>, <8 x i1>* %0, align 8 + %12 = load <8 x i1>, <8 x i1>* %0, align 8 + %13 = load <8 x i1>, <8 x i1>* %0, align 8 + + %14 = extractelement <8 x i1> %11, i64 0 + %15 = extractelement <8 x i1> %12, i64 1 + %16 = extractelement <8 x i1> %13, i64 2 + + %17 = zext i1 %14 to i32 + %18 = zext i1 %15 to i32 + %19 = zext i1 %16 to i32 + + %20 = add i32 %17, 65 ; + 'A' + %21 = add i32 %18, 65 ; + 'A' + %22 = add i32 %19, 65 ; + 'A' + + %23 = call i32 @putchar(i32 %20) + %24 = call i32 @putchar(i32 %21) + %25 = call i32 @putchar(i32 %22) + + %26 = call i32 @putchar(i32 10) ; \n + + ret void +} diff --git a/src/checker/stmt.cpp b/src/checker/stmt.cpp index f3625def1..9b127b7aa 100644 --- a/src/checker/stmt.cpp +++ b/src/checker/stmt.cpp @@ -418,28 +418,12 @@ void check_proc_decl(Checker *c, Entity *e, DeclInfo *d, b32 check_body_later) { check_procedure_type(c, proc_type, pd->type); - b32 is_foreign = false; - b32 is_inline = false; - b32 is_no_inline = false; - for (AstNode *tag = pd->tag_list; tag != NULL; tag = tag->next) { - GB_ASSERT(tag->kind == AstNode_TagExpr); - - ast_node(te, TagExpr, tag); - String tag_name = te->name.string; - if (are_strings_equal(tag_name, make_string("foreign"))) { - is_foreign = true; - } else if (are_strings_equal(tag_name, make_string("inline"))) { - is_inline = true; - } else if (are_strings_equal(tag_name, make_string("no_inline"))) { - is_no_inline = true; - } else { - error(&c->error_collector, ast_node_token(tag), "Unknown procedure tag"); - } - // TODO(bill): Other tags - } + b32 is_foreign = (pd->tags & ProcTag_foreign) != 0; + b32 is_inline = (pd->tags & ProcTag_inline) != 0; + b32 is_no_inline = (pd->tags & ProcTag_no_inline) != 0; if (is_inline && is_no_inline) { - error(&c->error_collector, ast_node_token(pd->tag_list), + error(&c->error_collector, ast_node_token(pd->type), "You cannot apply both `inline` and `no_inline` to a procedure"); } diff --git a/src/checker/type.cpp b/src/checker/type.cpp index 4504cd06f..e0ce88c03 100644 --- a/src/checker/type.cpp +++ b/src/checker/type.cpp @@ -560,7 +560,7 @@ i64 type_align_of(BaseTypeSizes s, gbAllocator allocator, Type *t) { case Type_Vector: { i64 size = type_size_of(s, allocator, t->vector.elem); // TODO(bill): Type_Vector type_align_of - return gb_clamp(size, 1, 2*s.max_align); + return gb_clamp(size, s.max_align, 2*s.max_align); } break; case Type_Structure: { diff --git a/src/codegen/codegen.cpp b/src/codegen/codegen.cpp index 4cb4a98be..0c36ca8f3 100644 --- a/src/codegen/codegen.cpp +++ b/src/codegen/codegen.cpp @@ -18,6 +18,11 @@ b32 ssa_gen_init(ssaGen *s, Checker *c) { return false; } + isize tc = c->parser->total_token_count; + if (tc < 2) { + return false; + } + ssa_module_init(&s->module, c); // TODO(bill): generate appropriate output name @@ -79,8 +84,13 @@ void ssa_gen_code(ssaGen *s) { } break; case Entity_Procedure: { - AstNode *body = decl->proc_decl->ProcDecl.body; - ssaValue *p = ssa_make_value_procedure(a, m, e->type, decl->type_expr, body, e->token.string); + auto *pd = &decl->proc_decl->ProcDecl; + String name = e->token.string; + AstNode *body = pd->body; + if (pd->foreign_name.len > 0) { + name = pd->foreign_name; + } + ssaValue *p = ssa_make_value_procedure(a, m, e->type, decl->type_expr, body, name); map_set(&m->values, hash_pointer(e), p); map_set(&m->members, hash_string(name), p); } break; diff --git a/src/codegen/print_llvm.cpp b/src/codegen/print_llvm.cpp index 2c9277f4d..5f2160182 100644 --- a/src/codegen/print_llvm.cpp +++ b/src/codegen/print_llvm.cpp @@ -269,7 +269,7 @@ void ssa_print_instr(gbFile *f, ssaModule *m, ssaValue *value) { Type *type = instr->local.entity->type; ssa_fprintf(f, "%%%d = alloca ", value->id); ssa_print_type(f, m->sizes, type); - ssa_fprintf(f, ", align %lld ", type_align_of(m->sizes, gb_heap_allocator(), type)); + ssa_fprintf(f, ", align %lld ", type_align_of(m->sizes, m->allocator, type)); { String str = instr->local.entity->token.string; if (str.len > 0) @@ -304,7 +304,7 @@ void ssa_print_instr(gbFile *f, ssaModule *m, ssaValue *value) { ssa_print_type(f, m->sizes, type); ssa_fprintf(f, "* "); ssa_print_value(f, m, instr->load.address, type); - ssa_fprintf(f, "\n"); + ssa_fprintf(f, ", align %lld\n", type_align_of(m->sizes, m->allocator, type)); } break; case ssaInstr_GetElementPtr: { @@ -616,7 +616,7 @@ void ssa_print_proc(gbFile *f, ssaModule *m, ssaProcedure *proc) { ssa_fprintf(f, ") "); if (proc->body == NULL) { - ssa_fprintf(f, "\t; foreign procedure\n\n"); + ssa_fprintf(f, "; foreign procedure\n\n"); } else { ssa_fprintf(f, "{\n"); gb_for_array(i, proc->blocks) { diff --git a/src/codegen/ssa.cpp b/src/codegen/ssa.cpp index 19b4f1e3e..f20100a8b 100644 --- a/src/codegen/ssa.cpp +++ b/src/codegen/ssa.cpp @@ -2067,6 +2067,9 @@ void ssa_build_stmt(ssaProcedure *proc, AstNode *node) { ssa_build_proc(value, proc); } else { String name = pd->name->Ident.token.string; + if (pd->foreign_name.len > 0) { + name = pd->foreign_name; + } Entity **found = map_get(&proc->module->info->definitions, hash_pointer(pd->name)); GB_ASSERT(found != NULL); @@ -2240,6 +2243,9 @@ void ssa_build_stmt(ssaProcedure *proc, AstNode *node) { case_ast_node(is, IfStmt, node); if (is->init != NULL) { + ssaBlock *init = ssa_add_block(proc, node, make_string("if.init")); + ssa_emit_jump(proc, init); + proc->curr_block = init; ssa_build_stmt(proc, is->init); } ssaBlock *then = ssa_add_block(proc, node, make_string("if.then")); @@ -2265,9 +2271,12 @@ void ssa_build_stmt(ssaProcedure *proc, AstNode *node) { case_ast_node(fs, ForStmt, node); if (fs->init != NULL) { + ssaBlock *init = ssa_add_block(proc, node, make_string("for.init")); + ssa_emit_jump(proc, init); + proc->curr_block = init; ssa_build_stmt(proc, fs->init); } - ssaBlock *body = ssa_add_block(proc, node, make_string("for.body")); + ssaBlock *body = ssa__make_block(proc, node, make_string("for.body")); ssaBlock *done = ssa__make_block(proc, node, make_string("for.done")); // NOTE(bill): Append later ssaBlock *loop = body; @@ -2283,6 +2292,7 @@ void ssa_build_stmt(ssaProcedure *proc, AstNode *node) { proc->curr_block = loop; if (loop != body) { ssa_build_cond(proc, fs->cond, body, done); + gb_array_append(proc->blocks, body); proc->curr_block = body; } diff --git a/src/parser.cpp b/src/parser.cpp index 9e9992fa5..328220cfa 100644 --- a/src/parser.cpp +++ b/src/parser.cpp @@ -71,6 +71,12 @@ enum DeclKind { Declaration_Count, }; +enum ProcTag { + ProcTag_foreign = GB_BIT(0), + ProcTag_inline = GB_BIT(1), + ProcTag_no_inline = GB_BIT(2), +}; + #define AST_NODE_KINDS \ AST_NODE_KIND(Invalid, struct{}) \ AST_NODE_KIND(BasicLit, Token) \ @@ -163,11 +169,11 @@ AST_NODE_KIND(_DeclBegin, struct{}) \ isize name_count, value_count; \ }) \ AST_NODE_KIND(ProcDecl, struct { \ - AstNode *name; \ - AstNode *type; \ - AstNode *body; \ - AstNode *tag_list; \ - isize tag_count; \ + AstNode *name; \ + AstNode *type; \ + AstNode *body; \ + u64 tags; \ + String foreign_name; \ }) \ AST_NODE_KIND(TypeDecl, struct { Token token; AstNode *name, *type; }) \ AST_NODE_KIND(AliasDecl, struct { Token token; AstNode *name, *type; }) \ @@ -701,13 +707,13 @@ gb_inline AstNode *make_proc_type(AstFile *f, Token token, AstNode *param_list, return result; } -gb_inline AstNode *make_proc_decl(AstFile *f, AstNode *name, AstNode *proc_type, AstNode *body, AstNode *tag_list, isize tag_count) { +gb_inline AstNode *make_proc_decl(AstFile *f, AstNode *name, AstNode *proc_type, AstNode *body, u64 tags, String foreign_name) { AstNode *result = make_node(f, AstNode_ProcDecl); result->ProcDecl.name = name; result->ProcDecl.type = proc_type; result->ProcDecl.body = body; - result->ProcDecl.tag_list = tag_list; - result->ProcDecl.tag_count = tag_count; + result->ProcDecl.tags = tags; + result->ProcDecl.foreign_name = foreign_name; return result; } @@ -1589,7 +1595,7 @@ AstNode *parse_body(AstFile *f, AstScope *scope) { return make_block_stmt(f, statement_list, statement_list_count, open, close); } - AstNode *parse_proc_decl(AstFile *f, Token proc_token, AstNode *name) { +AstNode *parse_proc_decl(AstFile *f, Token proc_token, AstNode *name) { AstNode *param_list = NULL; AstNode *result_list = NULL; isize param_count = 0; @@ -1600,21 +1606,50 @@ AstNode *parse_body(AstFile *f, AstScope *scope) { parse_procedure_signature(f, scope, ¶m_list, ¶m_count, &result_list, &result_count); AstNode *body = NULL; - AstNode *tag_list = NULL; - AstNode *tag_list_curr = NULL; - isize tag_count = 0; + u64 tags = 0; + String foreign_name = {}; while (f->cursor[0].kind == Token_Hash) { - DLIST_APPEND(tag_list, tag_list_curr, parse_tag_expr(f, NULL)); - tag_count++; + AstNode *tag_expr = parse_tag_expr(f, NULL); + ast_node(te, TagExpr, tag_expr); + String tag_name = te->name.string; + if (are_strings_equal(tag_name, make_string("foreign"))) { + tags |= ProcTag_foreign; + if (f->cursor[0].kind == Token_String) { + foreign_name = f->cursor[0].string; + // TODO(bill): Check if valid string + if (foreign_name.len == 0) { + ast_file_err(f, ast_node_token(tag_expr), "Invalid alternative foreign procedure name"); + } + + next_token(f); + } + } else if (are_strings_equal(tag_name, make_string("inline"))) { + tags |= ProcTag_inline; + } else if (are_strings_equal(tag_name, make_string("no_inline"))) { + tags |= ProcTag_no_inline; + } else { + ast_file_err(f, ast_node_token(tag_expr), "Unknown procedure tag"); + } } + + b32 is_inline = (tags & ProcTag_inline) != 0; + b32 is_no_inline = (tags & ProcTag_no_inline) != 0; + + if (is_inline && is_no_inline) { + ast_file_err(f, f->cursor[0], "You cannot apply both `inline` and `no_inline` to a procedure"); + } + if (f->cursor[0].kind == Token_OpenBrace) { + if ((tags & ProcTag_foreign) != 0) { + ast_file_err(f, f->cursor[0], "A procedure tagged as `#foreign` cannot have a body"); + } body = parse_body(f, scope); } close_ast_scope(f); AstNode *proc_type = make_proc_type(f, proc_token, param_list, param_count, result_list, result_count); - return make_proc_decl(f, name, proc_type, body, tag_list, tag_count); + return make_proc_decl(f, name, proc_type, body, tags, foreign_name); } AstNode *parse_decl(AstFile *f, AstNode *name_list, isize name_count) { diff --git a/src/printer.cpp b/src/printer.cpp index 465714783..cbac29f94 100644 --- a/src/printer.cpp +++ b/src/printer.cpp @@ -143,7 +143,6 @@ void print_ast(AstNode *node, isize indent) { gb_printf("(decl:proc)\n"); print_ast(node->ProcDecl.type, indent+1); print_ast(node->ProcDecl.body, indent+1); - print_ast(node->ProcDecl.tag_list, indent+1); break; case AstNode_TypeDecl: