diff --git a/Student/task1/ll/assign_hand.ll b/Student/task1/ll/assign_hand.ll index e69de29..4d5aca3 100644 --- a/Student/task1/ll/assign_hand.ll +++ b/Student/task1/ll/assign_hand.ll @@ -0,0 +1,24 @@ +source_filename = "assign_test.sy" +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" +; 配置信息 + +define dso_local i32 @main() { ; 定义主函数 + %1 = alloca float, align 4 ; 分配一个float, 相当于b + %2 = alloca [2 x i32], align 4 ; 分配两个i32,相当于a[2] + store float 0x3FFCCCCCC0000000, float* %1, align 4 ; 相当于b=1.8,用二进制表示1.8 + %3 = getelementptr [2 x i32], [2 x i32]* %2, i64 0, i64 0 ; 获得%2的第0个元素的指针,下同 + store i32 2, i32* %3 ; 将这个值赋给2,即a[0]=2,相当于a[2]={2}。 + %4 = getelementptr [2 x i32], [2 x i32]* %2, i64 0, i64 0 + %5 = load i32, i32* %4, align 4 + %6 = sitofp i32 %5 to float ; 把%5(也就是a[0])转成float + %7 = load float, float* %1, align 4 + %8 = fmul float %6, %7 + %9 = fptosi float %8 to i32 ; 把%8(也就是a[0]*b)转成i32 + %10 = getelementptr [2 x i32], [2 x i32]* %2, i64 0, i64 1 ; 获得%2的第1个元素的指针,下同 + store i32 %9, i32* %10, align 4 ; 把%9的结果存储在%10(即a[1]中) + %11 = getelementptr [2 x i32], [2 x i32]* %2, i64 0, i64 1 + %12 = load i32, i32* %11, align 4 ; 读出%10(即a[1])的值 + ret i32 %12 ; main 返回 +} + diff --git a/Student/task1/ll/func_hand.ll b/Student/task1/ll/func_hand.ll index e69de29..5b21390 100644 --- a/Student/task1/ll/func_hand.ll +++ b/Student/task1/ll/func_hand.ll @@ -0,0 +1,30 @@ +source_filename = "func_test.sy" +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" + +define dso_local i32 @add(i32 %0, i32 %1) { ; 定义add函数 + %3 = alloca i32, align 4 + %4 = alloca i32, align 4 + store i32 %0, i32* %3, align 4 + store i32 %1, i32* %4, align 4 ; 以上四步把两个参数移到%3 %4,必须从3开始 + %5 = load i32, i32* %3, align 4 + %6 = load i32, i32* %4, align 4 + %7 = add i32 %5, %6 + %8 = sub i32 %7, 1 + ret i32 %8 ; 此处用静态单赋值的方式计算a+b-1 +} + +define dso_local i32 @main() { + %1 = alloca i32, align 4 + %2 = alloca i32, align 4 + %3 = alloca i32, align 4 + store i32 3, i32* %1, align 4 + store i32 2, i32* %2, align 4 + store i32 5, i32* %3, align 4 ; %1 浪费不用,%2~%4赋给3,2,5相当于a,b,c。 + %4 = load i32, i32* %3, align 4 + %5 = load i32, i32* %1, align 4 + %6 = load i32, i32* %2, align 4 + %7 = call i32 @add(i32 %5, i32 %6) ; 执行函数调用 + %8 = add i32 %4, %7 ; 加法 + ret i32 %8 +} \ No newline at end of file diff --git a/Student/task1/ll/if_hand.ll b/Student/task1/ll/if_hand.ll index e69de29..7d141b3 100644 --- a/Student/task1/ll/if_hand.ll +++ b/Student/task1/ll/if_hand.ll @@ -0,0 +1,20 @@ +source_filename = "if_test.sy" +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" + +@a = dso_local global i32 0, align 4 + +define dso_local i32 @main() { + store i32 10, i32* @a, align 4 ; 相当于a=10 + %1 = load i32, i32* @a, align 4 + %2 = icmp sgt i32 %1, 0 ; %2(a)和a比较 + br i1 %2, label %3, label %5 ; %4代表真,%6代表假 + +3: + %4 = load i32, i32* @a, align 4 + ret i32 %4 ; 预测为真,返回a + +5: + ret i32 0 ; 返回0 + +} \ No newline at end of file diff --git a/Student/task1/ll/while_hand.ll b/Student/task1/ll/while_hand.ll index e69de29..92870eb 100644 --- a/Student/task1/ll/while_hand.ll +++ b/Student/task1/ll/while_hand.ll @@ -0,0 +1,31 @@ +source_filename = "while_test.sy" +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" + +@b = dso_local global i32 0, align 4 +@a = dso_local global i32 0, align 4 + +define dso_local i32 @main() { + store i32 0, i32* @b, align 4 + store i32 3, i32* @a, align 4 ; b, a分别赋给0, 3 + br label %1 ; 跳转到标签2处 + +1: + %2 = load i32, i32* @a, align 4 + %3 = icmp sgt i32 %2, 0 + br i1 %3, label %4, label %10 ; 判断a是否大于0,大于则进入循环 + +4: + %5 = load i32, i32* @b, align 4 + %6 = load i32, i32* @a, align 4 + %7 = add i32 %5, %6 + store i32 %7, i32* @b, align 4 + %8 = load i32, i32* @a, align 4 + %9 = sub i32 %8, 1 + store i32 %9, i32* @a, align 4 ; 进入循环,执行b = b+a; a = a-1; + br label %1 ; 跳转循环开头 + +10: + %11 = load i32, i32* @b, align 4 + ret i32 %11 ; 加载%b并返回 +} diff --git a/report/report.md b/report/report.md index c43624a..3523883 100644 --- a/report/report.md +++ b/report/report.md @@ -1,9 +1,16 @@ # PW6 实验报告 -学号1 姓名1 学号2 姓名2 学号3 姓名3 +舒英特 PB21111704 + +杨宇航 PB21051030 ## 问题回答 +1-1 一个while语句对应三个标签:第一个标签处执行判断,第二个标签处执行函数体, +第三个标签对应while的末尾。br指令有两种形式:br label a表示直接跳转到a标签处;br i1 x, label a, label b表示x是真则跳到a,x是假则跳到b。 + +1-2 函数调用语句的格式是call @( ),包含了返回值类型,参数类型及其具体值。 + ## 实验设计 ## 实验难点及解决方案