lang0/3-lang0ll/runtimetest.ll
2026-02-01 12:49:15 +01:00

401 lines
12 KiB
LLVM

target datalayout = "e-m:e-p270:32:32-p271:32:32-p272:64:64-i64:64-f80:128-n8:16:32:64-S128"
target triple = "x86_64-pc-linux-gnu"
%FILE = type opaque
@stdout = global %FILE* null
declare void @exit(i32)
declare i32 @fputs(i8*, %FILE*)
declare i8* @malloc(i32)
declare %FILE* @fdopen(i32, i8*)
declare void @fclose(%FILE*)
@__BACKSLASH = internal constant [2 x i8] c"\\\00"
@__EOF = internal constant [2 x i8] c"\\\FF"
@__EOL = internal constant [2 x i8] c"\0A\00"
@__QUOTE = internal constant [2 x i8] c"\22\00"
@__FALSE = internal constant [1 x i8] c"\00"
@__TRUE = internal constant [2 x i8] c"1\00"
define i8* @__drop_i8_type(i8* %0) alwaysinline readnone
{
ret i8* %0
}
define i8* @__eq(i8* %0, i8* %1)
{
%i = alloca i64, align 8
store i64 0, i64* %i
br label %loop
loop:
%index = load i64, i64* %i
%char0_adr = getelementptr i8, i8* %0, i64 %index
%char1_adr = getelementptr i8, i8* %1, i64 %index
%char0 = load i8, i8* %char0_adr
%char1 = load i8, i8* %char1_adr
%chars_differ = icmp ne i8 %char0, %char1
br i1 %chars_differ, label %lbl_not_equal, label %lbl_equal
lbl_equal:
%string_end = icmp eq i8 %char0, 0
br i1 %string_end, label %string_equal, label %next_char
string_equal:
ret i8* @__TRUE
next_char:
%next_index = add i64 %index, 1
store i64 %next_index, i64* %i
br label %loop
lbl_not_equal:
ret i8* @__FALSE
}
define i8* @__lt(i8* %0, i8* %1)
{
%i = alloca i64, align 8
store i64 0, i64* %i
br label %loop
loop:
%index = load i64, i64* %i
%char0_adr = getelementptr i8, i8* %0, i64 %index
%char1_adr = getelementptr i8, i8* %1, i64 %index
%char0 = load i8, i8* %char0_adr
%char1 = load i8, i8* %char1_adr
%char0_eol = icmp eq i8 %char0, 0
%char1_eol = icmp eq i8 %char1, 0
; if char0 == 0
; if char1 == 0
; return FALSE ; "" < "" === False
; else
; return TRUE ; "" < "." === True
; endif
; else
; if char1 == 0
; return FALSE ; "." < "" === False
; else
; if char0 < char1
; return TRUE ; "a" < "b" === True
; else
; if char0 > char1
; return FALSE ; "b" < "a" === False
; else
; jump next_char
; endif
; endif
; endif
; endif
br i1 %char0_eol, label %lbl_char0_eol, label %lbl_char0_not_eol
lbl_char0_eol:
br i1 %char1_eol, label %lbl_not_smaller, label %lbl_smaller
lbl_char0_not_eol:
br i1 %char1_eol, label %lbl_not_smaller, label %lbl_char0_not_eol_char1_not_eol
lbl_char0_not_eol_char1_not_eol:
%char0_lt_char1 = icmp ult i8 %char0, %char1
br i1 %char0_lt_char1, label %lbl_smaller, label %lbl_char0_ge_char1
lbl_char0_ge_char1:
%char0_gt_char1 = icmp ugt i8 %char0, %char1
br i1 %char0_gt_char1, label %lbl_not_smaller, label %next_char
next_char:
%next_index = add i64 %index, 1
store i64 %next_index, i64* %i
br label %loop
lbl_smaller:
ret i8* @__TRUE
lbl_not_smaller:
ret i8* @__FALSE
}
define i8* @__not(i8* %0)
{
%char0_adr = getelementptr i8, i8* %0, i64 0
%char0 = load i8, i8* %char0_adr
%char0_eol = icmp eq i8 %char0, 0
br i1 %char0_eol, label %lbl_empty, label %lbl_not_empty
lbl_empty:
ret i8* @__TRUE;
lbl_not_empty:
ret i8* @__FALSE;
}
define i8* @__add(i8* %0, i8* %1)
{
ret i8* %0 ; STUB
}
define i8* @__emit(i8* %0)
{
%stdout_ptr = load %FILE*, %FILE** @stdout
call i32 @fputs(i8* %0, %FILE* %stdout_ptr)
ret i8* @__FALSE
}
define i8* @__trace(i8* %0, i8* %1)
{
ret i8* %0 ; STUB
}
define i8* @__peek()
{
ret i8* @__EOL ; STUB
}
define i8* @__skip()
{
ret i8* @__EOL ; STUB
}
define i8* @__stdinlineno()
{
ret i8* @__EOL ; STUB
}
define i8* @__stdincolno()
{
ret i8* @__EOL ; STUB
}
define i8* @__mapgetkey(i8* %0, i8* %1, i8* %2)
{
ret i8* %0 ; STUB
}
define i8* @__mapsetkey(i8* %0, i8* %1, i8* %2)
{
ret i8* %0 ; STUB
}
define i8* @__str_reverse(i8* %0, i64 %1)
{
%input_empty = icmp ule i64 %1, 1
br i1 %input_empty, label %lbl_done, label %lbl_work_to_do
lbl_work_to_do:
%arg1_sub1 = sub i64 %1, 1
%rgidx_reg = alloca i64, align 8
store i64 %arg1_sub1, i64* %rgidx_reg
%lfidx_reg = alloca i64, align 8
store i64 0, i64* %lfidx_reg
br label %loop
loop:
%rgidx = load i64, i64* %rgidx_reg
%lfidx = load i64, i64* %lfidx_reg
%rgidx_le_lfidx = icmp ule i64 %rgidx, %lfidx
br i1 %rgidx_le_lfidx, label %lbl_done, label %lbl_flip_one
lbl_flip_one:
%rgadr = getelementptr i8, i8* %0, i64 %rgidx
%rgchr = load i8, i8* %rgadr
%lfadr = getelementptr i8, i8* %0, i64 %lfidx
%lfchr = load i8, i8* %lfadr
store i8 %lfchr, i8* %rgadr
store i8 %rgchr, i8* %lfadr
%new_rgidx = sub i64 %rgidx, 1
%new_lfidx = add i64 %lfidx, 1
store i64 %new_rgidx, i64* %rgidx_reg
store i64 %new_lfidx, i64* %lfidx_reg
br label %loop
lbl_done:
ret i8* %0;
}
define i8* @__i64_to_str(i64 %i)
{
%res = call i8* @malloc(i64 32)
store i8 48, i8* %res ; Base case
%idx_reg = alloca i64, align 8
store i64 0, i64* %idx_reg
%rem_idx = alloca i64, align 8
store i64 %i, i64* %rem_idx
br label %loop
loop:
%rem = load i64, i64* %rem_idx
%rem.eq0 = icmp eq i64 %rem, 0
br i1 %rem.eq0, label %lbl_done, label %lbl_addchar
lbl_addchar:
%digit = urem i64 %rem, 10
%char.0 = trunc i64 %digit to i8
%char.1 = add i8 48, %char.0
%idx = load i64, i64* %idx_reg
%char.adr = getelementptr i8, i8* %res, i64 %idx
store i8 %char.1, i8* %char.adr
%newrem.0 = sub i64 %rem, %digit
%newrem.1 = udiv i64 %newrem.0, 10
store i64 %newrem.1, i64* %rem_idx
%newidx = add i64 %idx, 1
store i64 %newidx, i64* %idx_reg
br label %loop
lbl_done:
; null terminator
%nt_idx = load i64, i64* %idx_reg
%nt_adr = getelementptr i8, i8* %res, i64 %nt_idx
store i8 0, i8* %nt_adr
; By not increasing the index, the index is the length
%len = load i64, i64* %idx_reg
%rev = call i8* @__str_reverse(i8* %res, i64 %len)
ret i8 *%rev
}
define i8* @__strlen(i8* %0)
{
%i = alloca i64, align 8
store i64 0, i64* %i
br label %loop
loop:
%index = load i64, i64* %i
%char0_adr = getelementptr i8, i8* %0, i64 %index
%char0 = load i8, i8* %char0_adr
%char0_eol = icmp eq i8 %char0, 0
br i1 %char0_eol, label %lbl_char0_eol, label %lbl_char0_not_eol
lbl_char0_not_eol:
%next_index = add i64 %index, 1
store i64 %next_index, i64* %i
br label %loop
lbl_char0_eol:
%len = load i64, i64* %i
%res = call i8* @__i64_to_str(i64 %len)
ret i8* %res;
}
define i8* @__intinc(i8* %0)
{
ret i8* %0 ; STUB
}
define void @test_result_1(i8* %func, i8* %arg0, i8* %result)
{
call i32 @__emit(i8* %func)
call i32 @__emit(i8* @str.bracket)
call i32 @__emit(i8* %arg0)
call i32 @__emit(i8* @str.bracket_colon_space)
call i32 @__emit(i8* %result)
call i32 @__emit(i8* @__EOL)
ret void
}
define void @test_result_2(i8* %func, i8* %arg0, i8* %arg1, i8* %result)
{
call i32 @__emit(i8* %func)
call i32 @__emit(i8* @str.bracket)
call i32 @__emit(i8* %arg0)
call i32 @__emit(i8* @str.comma_space)
call i32 @__emit(i8* %arg1)
call i32 @__emit(i8* @str.bracket_colon_space)
call i32 @__emit(i8* %result)
call i32 @__emit(i8* @__EOL)
ret void
}
define void @test_eq(i8* %0, i8* %1)
{
%result = call i8* @__eq(i8* %0, i8* %1)
call void @test_result_2(i8* @str.eq, i8* %0, i8* %1, i8* %result)
ret void
}
define void @test_lt(i8* %0, i8* %1)
{
%result = call i8* @__lt(i8* %0, i8* %1)
call void @test_result_2(i8* @str.lt, i8* %0, i8* %1, i8* %result)
ret void
}
define void @test_not(i8* %0)
{
%result = call i8* @__not(i8* %0)
call void @test_result_1(i8* @str.not, i8* %0, i8* %result)
ret void
}
define void @test_strlen(i8* %0)
{
%result = call i8* @__strlen(i8* %0)
call void @test_result_1(i8* @str.strlen, i8* %0, i8* %result)
ret void
}
define i64 @main()
{
%stdout_ptr = call %FILE* @fdopen(i32 1, i8* @str.w)
store %FILE* %stdout_ptr, %FILE** @stdout
call void @test_eq(i8* @str., i8* @str.0)
call void @test_eq(i8* @str.0, i8* @str.)
call void @test_eq(i8* @str.0, i8* @str.0)
call void @test_eq(i8* @str.a, i8* @str.a)
call void @test_eq(i8* @str.a, i8* @str.b)
call void @test_eq(i8* @str.a, i8* @str.c)
call void @test_eq(i8* @str.b, i8* @str.a)
call void @test_eq(i8* @str.b, i8* @str.b)
call void @test_eq(i8* @str.b, i8* @str.c)
call void @test_eq(i8* @str.c, i8* @str.a)
call void @test_eq(i8* @str.c, i8* @str.b)
call void @test_eq(i8* @str.c, i8* @str.c)
call void @test_eq(i8* @str.left, i8* @str.right)
call void @test_eq(i8* @str.left, i8* @str.left)
call void @test_eq(i8* @str.right, i8* @str.left)
call void @test_eq(i8* @str.right, i8* @str.right)
call void @test_lt(i8* @str.0, i8* @str.0)
call void @test_lt(i8* @str.a, i8* @str.a)
call void @test_lt(i8* @str.a, i8* @str.b)
call void @test_lt(i8* @str.a, i8* @str.c)
call void @test_lt(i8* @str.b, i8* @str.a)
call void @test_lt(i8* @str.b, i8* @str.b)
call void @test_lt(i8* @str.b, i8* @str.c)
call void @test_lt(i8* @str.c, i8* @str.a)
call void @test_lt(i8* @str.c, i8* @str.b)
call void @test_lt(i8* @str.c, i8* @str.c)
; `a` and `b` are expected to have length 1.
call void @test_not(i8* @str.)
call void @test_not(i8* @str.0)
call void @test_not(i8* @str.1)
call void @test_strlen(i8* @str.)
call void @test_strlen(i8* @str.a)
call void @test_strlen(i8* @str.eq)
call void @test_strlen(i8* @str.not)
call void @test_strlen(i8* @str.left)
call void @test_strlen(i8* @str.right)
call void @test_strlen(i8* @str.strlen)
call void @test_strlen(i8* @str.explanation)
call void @test_strlen(i8* @str.cats_paragraph)
call i32 @fclose(%FILE* %stdout_ptr)
ret i64 0
}
@str. = internal constant [1 x i8] c"\00"
@str.0 = internal constant [2 x i8] c"0\00"
@str.1 = internal constant [2 x i8] c"1\00"
@str.2 = internal constant [2 x i8] c"2\00"
@str.3 = internal constant [2 x i8] c"3\00"
@str.4 = internal constant [2 x i8] c"4\00"
@str.5 = internal constant [2 x i8] c"5\00"
@str.6 = internal constant [2 x i8] c"6\00"
@str.a = internal constant [2 x i8] c"a\00"
@str.b = internal constant [2 x i8] c"b\00"
@str.c = internal constant [2 x i8] c"c\00"
@str.bracket = internal constant [2 x i8] c"(\00"
@str.bracket_colon_space = internal constant [4 x i8] c"): \00"
@str.comma_space = internal constant [3 x i8] c", \00"
@str.eq = internal constant [3 x i8] c"eq\00"
@str.left = internal constant [5 x i8] c"left\00"
@str.lt = internal constant [3 x i8] c"lt\00"
@str.not = internal constant [4 x i8] c"not\00"
@str.right = internal constant [6 x i8] c"right\00"
@str.strlen = internal constant [7 x i8] c"strlen\00"
@str.w = internal constant [2 x i8] c"w\00"
@str.explanation = internal constant [135 x i8] c"Bitwise AND Operation: The and instruction performs a bitwise AND between the input value and the mask to isolate the smallest 8 bits.\00"
@str.cats_paragraph = internal constant [1193 x i8] c"Cats are fascinating creatures that have captivated humans for thousands of years. Belonging to the family Felidae, they are known for their agility, sharp senses, and playful behavior. Cats communicate through a variety of vocalizations, body language, and purring. One remarkable feature is their keen hunting skills; they possess sharp retractable claws and excellent night vision, enabling them to stalk and capture prey effectively. Domesticated cats, often kept as pets, bring joy to many households. They exhibit a range of personalities, from solitary and aloof to affectionate and social. Cats also enjoy playing, often engaging in activities that mimic hunting, such as chasing toys or pouncing on moving objects. Additionally, their grooming habits help keep their fur clean and contain calming pheromones that promote bonding with their human companions. Studies suggest that having a cat can reduce stress and anxiety levels. This unique relationship invites appreciation for their independence and charm, as they provide companionship while often maintaining a mysterious aura. Overall, cats are beloved pets that enrich our lives with their unique attributes and companionship.\00"