diff --git a/Documentations/5-bonus/README.md b/Documentations/5-bonus/README.md index 23d30c22799e6da08c1e22de9927a8ae2b27672b..ba6cde5bfc0fa3158c5f672de0e7f4a1ce8a7254 100644 --- a/Documentations/5-bonus/README.md +++ b/Documentations/5-bonus/README.md @@ -46,7 +46,7 @@ 1. 当函数参数个数大于 8 个时,如何传递参数? 2. 浮点常量、全局变量是如何存储的? -> 可以写一段 C 语言代码,在龙芯上用 `gcc -S` 生成汇编代码,观察汇编代码,思考如何实现。 +> 可以写一段 C 语言代码,将该文件命名为 `test.c`,在龙芯上用 `gcc -include io.h -S test.c` 生成汇编代码,观察汇编代码,思考如何实现。 ### 完成代码 @@ -89,15 +89,18 @@ cmake .. make ``` -编译后会产生 `cminusfc`可执行文件,使用 `cminusfc -S test.cminus` 编译 `test.cminus`源文件,生成 `test.s`汇编文件。 +编译后会产生 `cminusfc` 可执行文件,使用 `cminusfc -S test.cminus` 编译 `test.cminus`源文件,生成 `test.s`汇编文件。 -> 可以开启 `-mem2reg` 选项来简化 IR +> 可以选择开启 `cminusfc` 的 `-mem2reg` 选项优化中间代码 -学生可以本地运行生成汇编代码,然后传输到龙芯服务器,代码如下: +学生可以先本地运行生成汇编代码,然后将 `test.s` `io.c` `io.h` 传输到龙芯服务器,再在龙芯服务器上运行: + +> 假设 test.c 在仓库根目录下,用户的用户名为 username ```bash -scp src/io/io.c username@202.38.75.246 -scp test.s username@202.38.75.246 +build/cminusfc -S test.cminus + +scp src/io/io.c src/io/io.h test.s username@202.38.75.246:~/ ssh username@202.38.75.246 # 以下命令在 ssh 会话中执行 @@ -110,7 +113,7 @@ echo $? 在龙芯服务器,loongnix系统上将源代码编译为汇编代码命令如下, -``` +```bash gcc test.s io.c -Wa,--gdwarf2 -o test # 也可以利用静态链接库进行编译 gdb test ``` diff --git a/src/cminusfc/cminusfc.cpp b/src/cminusfc/cminusfc.cpp index 80506d1ab9c5b55971ad078046b3a978301d7388..2a144f0cb0c0931fcafd06f627e789c730e9538d 100644 --- a/src/cminusfc/cminusfc.cpp +++ b/src/cminusfc/cminusfc.cpp @@ -34,6 +34,7 @@ main(int argc, char **argv) { bool gvn = false; bool dump_json = false; bool emit = false; + bool assembly = false; for (int i = 1; i < argc; ++i) { if (argv[i] == "-h"s || argv[i] == "--help"s) { @@ -53,6 +54,8 @@ main(int argc, char **argv) { emit = true; } else if (argv[i] == "-mem2reg"s) { mem2reg = true; + } else if (argv[i] == "-S"s) { + assembly = true; } else if (argv[i] == "-gvn"s) { gvn = true; } else if (argv[i] == "-dump-json"s) { @@ -119,12 +122,14 @@ main(int argc, char **argv) { auto IR = m->print(); - CodeGen codegen(m.get()); - codegen.run(); - - std::ofstream target_file(target_path + ".s"); - target_file << codegen.print(); - target_file.close(); + if (assembly) { + CodeGen codegen(m.get()); + codegen.run(); + std::ofstream target_file(target_path + ".s"); + target_file << codegen.print(); + target_file.close(); + return 0; + } std::ofstream output_stream; auto output_file = target_path + ".ll"; diff --git a/src/io/io.h b/src/io/io.h new file mode 100644 index 0000000000000000000000000000000000000000..0b0473953f10bb196d21262b5781dc56953af393 --- /dev/null +++ b/src/io/io.h @@ -0,0 +1,7 @@ +int input(); + +void output(int a); + +void outputFloat(float a); + +void neg_idx_except(); diff --git a/tests/5-bonus/testcases/10-float.cminus b/tests/5-bonus/testcases/10-float.cminus index b023104ad172db73710d7fb56737f5bb584458f5..e9e47b08179b664aea534ef5e6591811c46b21c3 100644 --- a/tests/5-bonus/testcases/10-float.cminus +++ b/tests/5-bonus/testcases/10-float.cminus @@ -10,3 +10,11 @@ int main(void) { outputFloat(a * b + c); return 0; } + + +/* + 用 gcc 编译此文件生成汇编代码时,命令为 gcc -include io.h -S 10-float.c + 其中 io.h 位于 src/io/io.h, + + 也可以在本文件开头加上 void outputFloat(float x); +*/