273 lines
7.4 KiB
LLVM
273 lines
7.4 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 %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* @__strlen(i8* %0)
|
|
{
|
|
ret i8* %0 ; STUB
|
|
}
|
|
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 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 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.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.w = internal constant [2 x i8] c"w\00"
|