Skip to content

Instantly share code, notes, and snippets.

@FreeMasen
Created September 30, 2023 00:30
Show Gist options
  • Select an option

  • Save FreeMasen/b9b754d4ebb4cd174de89511b987eb4f to your computer and use it in GitHub Desktop.

Select an option

Save FreeMasen/b9b754d4ebb4cd174de89511b987eb4f to your computer and use it in GitHub Desktop.

Revisions

  1. FreeMasen created this gist Sep 30, 2023.
    542 changes: 542 additions & 0 deletions add.ll
    Original file line number Diff line number Diff line change
    @@ -0,0 +1,542 @@
    ; ModuleID = 'std::tvalue'
    source_filename = "std::tvalue"

    %"std::tvalue::TValue" = type { i8, [23 x i8] }
    %"std::tvalue::TValue::Bool" = type { [23 x i8], i8 }
    %"std::tvalue::TValue::Number" = type { [12 x i8], float }
    %"std::tvalue::TValue::String" = type { i8, i32, i32, i32, ptr }

    @"tvalue::names::nil" = global [5 x i8] c"nil\0A\00"
    @"tvalue::names::true" = global [6 x i8] c"true\0A\00"
    @"tvalue::names::false" = global [7 x i8] c"false\0A\00"
    @"tvalue::names::float_fmt" = global [4 x i8] c"%f\0A\00"

    ; Function Attrs: nounwind
    declare ptr @malloc(i32) #0

    define void @"std::tvalue::new_nil"(ptr %0) {
    entry:
    %tag_ptr = getelementptr inbounds %"std::tvalue::TValue", ptr %0, i32 0, i32 0
    store i8 0, ptr %tag_ptr, align 1
    %data_ptr = getelementptr inbounds %"std::tvalue::TValue", ptr %0, i32 0, i32 1
    store [15 x i8] zeroinitializer, ptr %data_ptr, align 1
    ret void
    }

    define void @"std::tvalue::new_bool"(ptr %0, i1 %1) {
    entry:
    %tag_ptr = getelementptr inbounds %"std::tvalue::TValue", ptr %0, i32 0, i32 0
    store i8 1, ptr %tag_ptr, align 1
    %data_ptr = getelementptr inbounds %"std::tvalue::TValue::Bool", ptr %0, i32 0, i32 1
    store i1 %1, ptr %data_ptr, align 1
    ret void
    }

    define void @"std::tvalue::new_num"(ptr %0, float %1) {
    entry:
    %tag_ptr = getelementptr inbounds %"std::tvalue::TValue", ptr %0, i32 0, i32 0
    store i8 2, ptr %tag_ptr, align 1
    %data_ptr = getelementptr inbounds %"std::tvalue::TValue::Number", ptr %0, i32 0, i32 1
    store float %1, ptr %data_ptr, align 4
    ret void
    }

    define void @"std::tvalue::new_str"(ptr %0, i32 %1) {
    entry:
    %tag_ptr = getelementptr inbounds %"std::tvalue::TValue", ptr %0, i32 0, i32 0
    store i8 3, ptr %tag_ptr, align 1
    %len_ptr = getelementptr inbounds %"std::tvalue::TValue::String", ptr %0, i32 0, i32 1
    store i32 0, ptr %len_ptr, align 4
    %cap_ptr = getelementptr inbounds %"std::tvalue::TValue::String", ptr %0, i32 0, i32 2
    store i32 %1, ptr %cap_ptr, align 4
    %ref_ct = getelementptr inbounds %"std::tvalue::TValue::String", ptr %0, i32 0, i32 3
    store i32 0, ptr %ref_ct, align 4
    %bytes_ptr = call ptr @malloc(i32 %1)
    %storage = getelementptr inbounds %"std::tvalue::TValue::String", ptr %0, i32 0, i32 4
    store ptr %bytes_ptr, ptr %storage, align 8
    ret void
    }

    define i8 @"std::tvalue::get_tag"(ptr %tagged_value) {
    entry:
    %tag_ptr = getelementptr inbounds %"std::tvalue::TValue", ptr %tagged_value, i32 0, i32 0
    %tag_val = load i8, ptr %tag_ptr, align 1
    ret i8 %tag_val
    }

    define i1 @"std::tvalue::is_truthy"(ptr %tagged_value) {
    entry:
    %tag = call i8 @"std::tvalue::get_tag"(ptr %tagged_value)
    %is_nil = icmp eq i8 %tag, 0
    br i1 %is_nil, label %is_nil1, label %is_not_nil

    is_nil1: ; preds = %entry
    ret i1 false

    is_not_nil: ; preds = %entry
    %is_bool = icmp eq i8 %tag, 1
    br i1 %is_bool, label %is_bool2, label %is_not_bool

    is_bool2: ; preds = %is_not_nil
    %raw_variant_pointer = getelementptr inbounds %"std::tvalue::TValue::Bool", ptr %tagged_value, i32 0, i32 1
    %bool_t_int = load i8, ptr %raw_variant_pointer, align 1
    %ret = icmp ugt i8 %bool_t_int, 0
    ret i1 %ret

    is_not_bool: ; preds = %is_not_nil
    ret i1 true
    }

    define i1 @"std::tvalue::is_number"(ptr %0) {
    entry:
    %tag = call i8 @"std::tvalue::get_tag"(ptr %0)
    %cmp = icmp eq i8 %tag, 2
    ret i1 %cmp
    }

    define float @"std::tvalue::get_value_number"(ptr %0) {
    entry:
    %is_num = call i1 @"std::tvalue::is_number"(ptr %0)
    br i1 %is_num, label %ian, label %nan

    ian: ; preds = %entry
    %value_ptr = getelementptr inbounds %"std::tvalue::TValue::Number", ptr %0, i32 0, i32 1
    %value = load float, ptr %value_ptr, align 4
    ret float %value

    nan: ; preds = %entry
    ret float 0x7FF8000000000000
    }

    declare i32 @printf(ptr, ...)

    declare i32 @write(i32, ptr, i32)

    define void @"std::tvalue::test::print_tvalue_string"(ptr %0) {
    entry:
    %len_ptr = getelementptr inbounds %"std::tvalue::TValue::String", ptr %0, i32 0, i32 1
    %len = load i32, ptr %len_ptr, align 4
    %bytes_ptr_ptr = getelementptr inbounds %"std::tvalue::TValue::String", ptr %0, i32 0, i32 4
    %bytes_ptr = load ptr, ptr %bytes_ptr_ptr, align 8
    %_ = call i32 @write(i32 1, ptr %bytes_ptr, i32 %len)
    ret void
    }

    define void @"std::tvalue::test::print_tvalue_raw"(ptr %0) {
    entry:
    %ob = alloca [2 x i8], align 1
    store [2 x i8] c"[\00", ptr %ob, align 1
    %_ = call i32 (ptr, ...) @printf(ptr %ob)
    br label %looptop

    looptop: ; preds = %looptop, %entry
    %idx = phi i32 [ %nextidx, %looptop ], [ 0, %entry ]
    %nextidx = add i32 %idx, 1
    %ch = getelementptr [16 x i8], ptr %0, i32 0, i32 %idx
    %ch1 = load i8, ptr %ch, align 1
    %ch_fmt = alloca [5 x i8], align 1
    store [5 x i8] c"%*i,\00", ptr %ch_fmt, align 1
    %_2 = call i32 (ptr, ...) @printf(ptr %ch_fmt, i8 3, i8 %ch1)
    %done = icmp uge i32 %nextidx, ptrtoint (ptr getelementptr (%"std::tvalue::TValue", ptr null, i32 1) to i32)
    br i1 %done, label %exit, label %looptop

    exit: ; preds = %looptop
    %cb = alloca [3 x i8], align 1
    store [3 x i8] c"]\0A\00", ptr %cb, align 1
    %_3 = call i32 (ptr, ...) @printf(ptr %cb)
    ret void
    }

    define void @"std::tvalue::test::print_tvalue"(ptr %0) {
    entry:
    %tag = call i8 @"std::tvalue::get_tag"(ptr %0)
    switch i8 %tag, label %unknown [
    i8 0, label %nil
    i8 1, label %boolean
    i8 2, label %number
    i8 3, label %string
    ]

    unknown: ; preds = %entry
    call void @"std::tvalue::test::print_tvalue_raw"(ptr %0)
    ret void

    nil: ; preds = %entry
    %_ = call i32 (ptr, ...) @printf(ptr @"tvalue::names::nil")
    ret void

    boolean: ; preds = %entry
    %truthy_ptr = getelementptr inbounds %"std::tvalue::TValue::Bool", ptr %0, i32 0, i32 1
    %truthy = load i1, ptr %truthy_ptr, align 1
    br i1 %truthy, label %bool_true, label %bool_false

    number: ; preds = %entry
    %num_ptr = getelementptr inbounds %"std::tvalue::TValue::Number", ptr %0, i32 0, i32 1
    %num = load float, ptr %num_ptr, align 4
    %dbl = fpext float %num to double
    %_3 = call i32 (ptr, ...) @printf(ptr @"tvalue::names::float_fmt", double %dbl)
    ret void

    string: ; preds = %entry
    call void @"std::tvalue::test::print_tvalue_string"(ptr %0)
    ret void

    bool_true: ; preds = %boolean
    %_1 = call i32 (ptr, ...) @printf(ptr @"tvalue::names::true")
    ret void

    bool_false: ; preds = %boolean
    %_2 = call i32 (ptr, ...) @printf(ptr @"tvalue::names::false")
    ret void
    }

    define i1 @"std::tvalue::is_two_numbers"(ptr %lhs, ptr %rhs) {
    entry:
    %lhs_is_num = call i1 @"std::tvalue::is_number"(ptr %lhs)
    br i1 %lhs_is_num, label %lhs_ian, label %nan

    nan: ; preds = %lhs_ian, %entry
    ret i1 false

    lhs_ian: ; preds = %entry
    %rhs_is_num = call i1 @"std::tvalue::is_number"(ptr %rhs)
    br i1 %rhs_is_num, label %rhs_ian, label %nan

    rhs_ian: ; preds = %lhs_ian
    ret i1 true
    }

    define i1 @"std::tvalue::add"(ptr %lhs, ptr %rhs, ptr %out) {
    entry:
    %are_nums = call i1 @"std::tvalue::is_two_numbers"(ptr %lhs, ptr %rhs)
    br i1 %are_nums, label %ian, label %nan

    ian: ; preds = %entry
    %lhs_value = call float @"std::tvalue::get_value_number"(ptr %lhs)
    %rhs_value = call float @"std::tvalue::get_value_number"(ptr %rhs)
    %out_value = fadd float %lhs_value, %rhs_value
    call void @"std::tvalue::new_num"(ptr %out, float %out_value)
    ret i1 true

    nan: ; preds = %entry
    ret i1 false
    }

    define i1 @"std::tvalue::sub"(ptr %lhs, ptr %rhs, ptr %out) {
    entry:
    %are_nums = call i1 @"std::tvalue::is_two_numbers"(ptr %lhs, ptr %rhs)
    br i1 %are_nums, label %ian, label %nan

    ian: ; preds = %entry
    %lhs_value = call float @"std::tvalue::get_value_number"(ptr %lhs)
    %rhs_value = call float @"std::tvalue::get_value_number"(ptr %rhs)
    %out_value = fsub float %lhs_value, %rhs_value
    call void @"std::tvalue::new_num"(ptr %out, float %out_value)
    ret i1 true

    nan: ; preds = %entry
    ret i1 false
    }

    define i1 @"std::tvalue::mul"(ptr %lhs, ptr %rhs, ptr %out) {
    entry:
    %are_nums = call i1 @"std::tvalue::is_two_numbers"(ptr %lhs, ptr %rhs)
    br i1 %are_nums, label %ian, label %nan

    ian: ; preds = %entry
    %lhs_value = call float @"std::tvalue::get_value_number"(ptr %lhs)
    %rhs_value = call float @"std::tvalue::get_value_number"(ptr %rhs)
    %out_value = fmul float %lhs_value, %rhs_value
    call void @"std::tvalue::new_num"(ptr %out, float %out_value)
    ret i1 true

    nan: ; preds = %entry
    ret i1 false
    }

    define i1 @"std::tvalue::div"(ptr %lhs, ptr %rhs, ptr %out) {
    entry:
    %are_nums = call i1 @"std::tvalue::is_two_numbers"(ptr %lhs, ptr %rhs)
    br i1 %are_nums, label %ian, label %nan

    ian: ; preds = %entry
    %lhs_value = call float @"std::tvalue::get_value_number"(ptr %lhs)
    %rhs_value = call float @"std::tvalue::get_value_number"(ptr %rhs)
    %out_value = fdiv float %lhs_value, %rhs_value
    call void @"std::tvalue::new_num"(ptr %out, float %out_value)
    ret i1 true

    nan: ; preds = %entry
    ret i1 false
    }

    ; Function Attrs: nocallback nofree nosync nounwind speculatable willreturn memory(none)
    declare float @llvm.floor.f32(float) #1

    define i1 @"std::tvalue::floor_div"(ptr %lhs, ptr %rhs, ptr %out) {
    entry:
    %are_nums = call i1 @"std::tvalue::is_two_numbers"(ptr %lhs, ptr %rhs)
    br i1 %are_nums, label %ian, label %nan

    ian: ; preds = %entry
    %lhs_value = call float @"std::tvalue::get_value_number"(ptr %lhs)
    %rhs_value = call float @"std::tvalue::get_value_number"(ptr %rhs)
    %out_value = fdiv float %lhs_value, %rhs_value
    %ret = call float @llvm.floor.f32(float %out_value)
    call void @"std::tvalue::new_num"(ptr %out, float %ret)
    ret i1 true

    nan: ; preds = %entry
    ret i1 false
    }

    ; Function Attrs: nocallback nofree nosync nounwind speculatable willreturn memory(none)
    declare float @llvm.pow.f32(float, float) #1

    define i1 @"std::tvalue::pow"(ptr %lhs, ptr %rhs, ptr %out) {
    entry:
    %are_nums = call i1 @"std::tvalue::is_two_numbers"(ptr %lhs, ptr %rhs)
    br i1 %are_nums, label %ian, label %nan

    ian: ; preds = %entry
    %lhs_value = call float @"std::tvalue::get_value_number"(ptr %lhs)
    %rhs_value = call float @"std::tvalue::get_value_number"(ptr %rhs)
    %out_value = call float @llvm.pow.f32(float %lhs_value, float %rhs_value)
    call void @"std::tvalue::new_num"(ptr %out, float %out_value)
    ret i1 true

    nan: ; preds = %entry
    ret i1 false
    }

    define i1 @"std::tvalue::mod"(ptr %lhs, ptr %rhs, ptr %out) {
    entry:
    %are_nums = call i1 @"std::tvalue::is_two_numbers"(ptr %lhs, ptr %rhs)
    br i1 %are_nums, label %ian, label %nan

    ian: ; preds = %entry
    %lhs_value = call float @"std::tvalue::get_value_number"(ptr %lhs)
    %rhs_value = call float @"std::tvalue::get_value_number"(ptr %rhs)
    %out_value = frem float %lhs_value, %rhs_value
    call void @"std::tvalue::new_num"(ptr %out, float %out_value)
    ret i1 true

    nan: ; preds = %entry
    ret i1 false
    }

    define i1 @"std::tvalue::NEG"(ptr %0, ptr %1) {
    entry:
    %arg_ian = call i1 @"std::tvalue::is_number"(ptr %0)
    br i1 %arg_ian, label %ian, label %nan

    nan: ; preds = %entry
    ret i1 false

    ian: ; preds = %entry
    %lhs_value = call float @"std::tvalue::get_value_number"(ptr %0)
    %out_value = fneg float %lhs_value
    call void @"std::tvalue::new_num"(ptr %1, float %out_value)
    ret i1 true
    }

    define i1 @"std::tvalue::is_int"(float %0) {
    entry:
    %floored = call float @llvm.floor.f32(float %0)
    %is_int = fcmp oeq float %0, %floored
    br i1 %is_int, label %exit, label %nai

    exit: ; preds = %entry
    ret i1 true

    nai: ; preds = %entry
    ret i1 false
    }

    define i1 @"std::tvalue::is_two_ints"(float %lhs, float %rhs) {
    entry:
    %lhs_is = call i1 @"std::tvalue::is_int"(float %lhs)
    br i1 %lhs_is, label %lhs_iai, label %nai

    lhs_iai: ; preds = %entry
    %rhs_is = call i1 @"std::tvalue::is_int"(float %rhs)
    br i1 %rhs_is, label %rhs_iai, label %nai

    rhs_iai: ; preds = %lhs_iai
    ret i1 true

    nai: ; preds = %lhs_iai, %entry
    ret i1 false
    }

    define i1 @"std::tvalue::bin_and"(ptr %lhs, ptr %rhs, ptr %out) {
    entry:
    %are_nums = call i1 @"std::tvalue::is_two_numbers"(ptr %lhs, ptr %rhs)
    br i1 %are_nums, label %ian, label %nan

    ian: ; preds = %entry
    %lhs_value = call float @"std::tvalue::get_value_number"(ptr %lhs)
    %rhs_value = call float @"std::tvalue::get_value_number"(ptr %rhs)
    %are_ints = call i1 @"std::tvalue::is_two_ints"(float %lhs_value, float %rhs_value)
    br i1 %are_ints, label %two_ints, label %not_ints

    nan: ; preds = %entry
    ret i1 false

    two_ints: ; preds = %ian
    %lhs1 = fptosi float %lhs_value to i32
    %rhs2 = fptosi float %rhs_value to i32
    %anded = and i32 %lhs1, %rhs2
    %out3 = sitofp i32 %anded to float
    call void @"std::tvalue::new_num"(ptr %out, float %out3)
    ret i1 true

    not_ints: ; preds = %ian
    ret i1 false
    }

    define i1 @"std::tvalue::bin_or"(ptr %lhs, ptr %rhs, ptr %out) {
    entry:
    %are_nums = call i1 @"std::tvalue::is_two_numbers"(ptr %lhs, ptr %rhs)
    br i1 %are_nums, label %ian, label %nan

    ian: ; preds = %entry
    %lhs_value = call float @"std::tvalue::get_value_number"(ptr %lhs)
    %rhs_value = call float @"std::tvalue::get_value_number"(ptr %rhs)
    %are_ints = call i1 @"std::tvalue::is_two_ints"(float %lhs_value, float %rhs_value)
    br i1 %are_ints, label %two_ints, label %not_ints

    nan: ; preds = %entry
    ret i1 false

    two_ints: ; preds = %ian
    %lhs1 = fptosi float %lhs_value to i32
    %rhs2 = fptosi float %rhs_value to i32
    %ored = or i32 %lhs1, %rhs2
    %out3 = sitofp i32 %ored to float
    call void @"std::tvalue::new_num"(ptr %out, float %out3)
    ret i1 true

    not_ints: ; preds = %ian
    ret i1 false
    }

    define i1 @"std::tvalue::lsh"(ptr %lhs, ptr %rhs, ptr %out) {
    entry:
    %are_nums = call i1 @"std::tvalue::is_two_numbers"(ptr %lhs, ptr %rhs)
    br i1 %are_nums, label %ian, label %nan

    ian: ; preds = %entry
    %lhs_value = call float @"std::tvalue::get_value_number"(ptr %lhs)
    %rhs_value = call float @"std::tvalue::get_value_number"(ptr %rhs)
    %are_ints = call i1 @"std::tvalue::is_two_ints"(float %lhs_value, float %rhs_value)
    br i1 %are_ints, label %two_ints, label %not_ints

    nan: ; preds = %entry
    ret i1 false

    two_ints: ; preds = %ian
    %lhs1 = fptosi float %lhs_value to i32
    %rhs2 = fptosi float %rhs_value to i32
    %lshed = shl i32 %lhs1, %rhs2
    %out3 = sitofp i32 %lshed to float
    call void @"std::tvalue::new_num"(ptr %out, float %out3)
    ret i1 true

    not_ints: ; preds = %ian
    ret i1 false
    }

    define i1 @"std::tvalue::rsh"(ptr %lhs, ptr %rhs, ptr %out) {
    entry:
    %are_nums = call i1 @"std::tvalue::is_two_numbers"(ptr %lhs, ptr %rhs)
    br i1 %are_nums, label %ian, label %nan

    ian: ; preds = %entry
    %lhs_value = call float @"std::tvalue::get_value_number"(ptr %lhs)
    %rhs_value = call float @"std::tvalue::get_value_number"(ptr %rhs)
    %are_ints = call i1 @"std::tvalue::is_two_ints"(float %lhs_value, float %rhs_value)
    br i1 %are_ints, label %two_ints, label %not_ints

    nan: ; preds = %entry
    ret i1 false

    two_ints: ; preds = %ian
    %lhs1 = fptosi float %lhs_value to i32
    %rhs2 = fptosi float %rhs_value to i32
    %rshed = lshr i32 %lhs1, %rhs2
    %out3 = sitofp i32 %rshed to float
    call void @"std::tvalue::new_num"(ptr %out, float %out3)
    ret i1 true

    not_ints: ; preds = %ian
    ret i1 false
    }

    define i1 @"std::tvalue::bin_not"(ptr %value, ptr %out) {
    entry:
    %is_num = call i1 @"std::tvalue::is_number"(ptr %value)
    br i1 %is_num, label %ian, label %no

    ian: ; preds = %entry
    %value_num = call float @"std::tvalue::get_value_number"(ptr %value)
    %is_int = call i1 @"std::tvalue::is_int"(float %value_num)
    br i1 %is_int, label %iai, label %no

    no: ; preds = %ian, %entry
    ret i1 false

    iai: ; preds = %ian
    %value_int = fptosi float %value_num to i32
    %value_int1 = xor i32 %value_int, -1
    %ret_float = sitofp i32 %value_int1 to float
    call void @"std::tvalue::new_num"(ptr %out, float %ret_float)
    ret i1 true
    }

    define float @test_num_add_happy(float %0, float %1) {
    entry:
    %lhs = alloca %"std::tvalue::TValue::Number", align 8
    call void @"std::tvalue::new_num"(ptr %lhs, float %0)
    %lhs1 = alloca %"std::tvalue::TValue::Number", align 8
    call void @"std::tvalue::new_num"(ptr %lhs1, float %1)
    %ret = alloca %"std::tvalue::TValue::Number", align 8
    call void @"std::tvalue::new_num"(ptr %ret, float 0x7FF8000000000000)
    %ret2 = call i1 @"std::tvalue::add"(ptr %lhs, ptr %lhs1, ptr %ret)
    %ret3 = call float @"std::tvalue::get_value_number"(ptr %ret)
    ret float %ret3
    }

    define float @add_num_bool() {
    entry:
    %lhs = alloca %"std::tvalue::TValue::Number", align 8
    call void @"std::tvalue::new_num"(ptr %lhs, float 1.000000e+00)
    %rhs = alloca %"std::tvalue::TValue::Bool", align 8
    call void @"std::tvalue::new_bool"(ptr %rhs, float 1.000000e+00)
    %ret = alloca %"std::tvalue::TValue::Number", align 8
    call void @"std::tvalue::new_num"(ptr %ret, float 0x7FF8000000000000)
    %ret1 = call i1 @"std::tvalue::add"(ptr %lhs, ptr %rhs, ptr %ret)
    %ret2 = call float @"std::tvalue::get_value_number"(ptr %ret)
    ret float %ret2
    }

    define float @add_num_nil() {
    entry:
    %lhs = alloca %"std::tvalue::TValue", align 8
    call void @"std::tvalue::new_nil"(ptr %lhs)
    %rhs = alloca %"std::tvalue::TValue::Bool", align 8
    call void @"std::tvalue::new_bool"(ptr %rhs, float 1.000000e+00)
    %ret = alloca %"std::tvalue::TValue::Number", align 8
    call void @"std::tvalue::new_num"(ptr %ret, float 0x7FF8000000000000)
    %ret1 = call i1 @"std::tvalue::add"(ptr %lhs, ptr %rhs, ptr %ret)
    %ret2 = call float @"std::tvalue::get_value_number"(ptr %ret)
    ret float %ret2
    }

    attributes #0 = { nounwind }
    attributes #1 = { nocallback nofree nosync nounwind speculatable willreturn memory(none) }

    !llvm.dbg.cu = !{!0}

    !0 = distinct !DICompileUnit(language: DW_LANG_C, file: !1, producer: "luminary", isOptimized: false, runtimeVersion: 1, emissionKind: FullDebug, splitDebugInlining: false)
    !1 = !DIFile(filename: "std_tvalue.ll", directory: ".")