# HXD1
**Repository Path**: glucose180/hxd1
## Basic Information
- **Project Name**: HXD1
- **Description**: 2024年春季学期编译原理研讨课CACT实验2组
- **Primary Language**: Unknown
- **License**: Not specified
- **Default Branch**: master
- **Homepage**: None
- **GVP Project**: No
## Statistics
- **Stars**: 0
- **Forks**: 0
- **Created**: 2024-11-08
- **Last Updated**: 2024-11-08
## Categories & Tags
**Categories**: Uncategorized
**Tags**: None
## README
# CACT 编译器 'HXD1'
你说得对,但是 HXD1(如果非要读的话,读作“和谐电一”)~~是由西门子公司和中车株洲电力机车有限公司联合研制的一款全新开放的干线货运用八轴大功率交流传动电力机车~~是由仲剑、岳俊宇、郑雨欣自主研发的一款全新开放的 CACT 编译器,它产生的汇编代码可以运行在一个叫做 RISC-V 的体系结构上。
HXD1 由两部分组成:CACT 前端(被称为 HXD1C)和 RV64IMFD 后端(被称为 HXD1D)。
这里是 UCAS 编译原理研讨课 CACT 实验 2 组的代码!
README-0.md是详细的实验记录,点击查看:[详细记录](README-0.md)。
## 运行方法
### 使用 ANTLR4 产生词法语法分析器
```bash
java -jar ../deps/antlr-4.13.1-complete.jar -Dlanguage=Cpp CACT.g4 -visitor -no-listener
```
### 编译 HXD1
```bash
mkdir -p build
cd build
cmake ..
#make -j
make
cd ..
```
### 编译 HEMU(HXD1 IR 解释执行工具)
```bash
mkdir -p build
cd HEMU
make
```
### 具体用法
#### HXD1
可用`-h`选项获得用法信息。
```bash
glucose@Glucose:~/cact/build$ ./compiler -h
HXD1: a simple CACT compiler built at Jun 13 2024, 19:07:56
Usage: hxd1 [options]
Options:
-d Enable debug mode.
-h Show basic help info.
-O Enable optimization where level can be 0, K, T, Z or 0, 1, 2, 3.
-o Place the output into .
-emit-IR Dump HXD1 IR code to a file.
-hf Show help info of options starting with -f.
-S Dump RV64 assembly code. (default)
If is omitted and -d is specified, stdin will be used to get input.
```
##### HXD1C(HXD1 的 CACT 前端)
使用`./build/compiler -emit-IR`命令可只激活 HXD1C,产生 HXD1 IR 文件。默认情况下,生成到相同目录下,扩展名自动改为`.ll`。可用`-o `指定输出文件。例如:
```bash
glucose@Glucose:~/cact$ build/compiler test/samples_codegen/tim_sort.cact -emit-IR -o temp/tim_sort.ll
HXD1: IR code dumped to file temp/tim_sort.ll
```
这将使用 HXD1C 编译 test/samples_codegen/tim_sort.cact 产生 HXD1 IR,并输出到文件 temp/tim_sort.ll。
此外,可以使用`-d`选项开启调试模式,在 IR 中会以更可读的形式打印指令,并且附带一些注释信息。**但是调试模式下产生的 IR 不要直接喂给 HEMU 去解释执行,可能出问题。**
##### HXD1D(HXD1 的 RV64IMFD 后端)
使用`./build/compiler `命令可同时激活 HXD1C 和 HXD1D,产生 RV64 汇编文件。默认情况下,生成到相同目录下,扩展名自动改为`.s`。可用`-o `指定输出文件。例如:
```bash
glucose@Glucose:~/cact$ build/compiler test/samples_codegen/tim_sort.cact -o temp/tim_sort.s -OT
```
这将编译 tim_sort.cact 产生 RV64 汇编文件并输出到 temp/tim_sort.s。
`-d`选项可以使汇编文件中包含一些注释,且不会影响喂给汇编器。
如果像上面那样开启`-OT`,则会启动优化功能。HXD1 支持 2 级优化,分别为快速优化(使用`-OK`或`-O1`选项激活,将启用简单优化)和特快优化(使用`-OT`、`-O2`、`-OZ`或`-O3`这四种等效选项激活,将启用全部优化)。
具体的优化功能包括:
`-fno-alloc-stack`
尽可能不为局部变量显式(在前端)分配栈空间,便于后端寄存器分配以减少访存指令。在快速优化(`-O1`)或更高等级默认启用。
`-fstrength-reduce`
简单的强度削弱。在快速优化(`-O1`)或更高等级默认启用。
`-fdce`
死代码消除。在快速优化(`-O1`)或更高等级默认启用。
`-fcse`
局部公共子表达式消除。在快速优化(`-O1`)或更高等级默认启用。
`-fmerge-const-expr`
常量合并。在快速优化(`-O1`)或更高等级默认启用。
`-fcfg-cleanup`
控制流优化。在快速优化(`-O1`)或更高等级默认启用。
`-fgra`
全局寄存器分配。在特快优化(`-O2`)等级默认启用。
也可以用`-f`开头的选项单独启用某些优化,或用相应的`-fno-`关闭某些优化。**当多个优化选项发生冲突时,将以最后一个为准。**例如,如果依次加上`-fno-dce`、`-fcse`、`-O2`、`-fno-cse`,那么最终效果是除了局部公共子表达式消除之外的优化都启用。
产生的汇编文件需要喂给 RV64 的 GCC(riscv64-unknown-elf-gcc)汇编并与 libcactio.a 静态库链接后得到 RV64 的可执行文件,并用 spike 模拟即可运行。例如:
( **可在实验课的服务器上进行下面的操作。**)
```bash
glucose@Glucose:~/cact/temp$ riscv64-unknown-elf-gcc tim_sort.s -L../build -lcactio -o tim_sort
glucose@Glucose:~/cact/temp$ spike pk tim_sort
bbl loader
please enter an int number:
3
-1398
-1245
821
1223
```
当然,也可以使用 PR3 的功能性自动测试脚本。进入 test/samples_codegen_functional/ 目录,新建 temp 和 io 两个目录,并把测试程序的输入和参考输出置于 io 目录中,然后执行下面的命令即可进行自动测试(具体的参数选项请看脚本 test_functional.py 的内容):
```bash
python3 test_functional.py
```
#### HXD1 IR 解释执行器 HEMU
对于 HEMU(HXD1 IR 解释执行工具):
按上面的步骤编译后,会生成可执行文件 **build/interpreter**。
### 运行方法
```bash
Usage: ./interpreter [options]
Options:
-hdb Enable debug mode
```
模拟器在运行中发现IR错误将进入**受限调试模式**。
使用`-hdb`选项将进入调试模式,使用方法和gdb类似,支持的调试命令如下:
#### 调试命令
```bash
break
print
x/ 0x
x/
continue
list cur_line
```
`break`(可简写`b`)打断点,`print`(可简写`p`)打印变量值,`x`打印内存,`continue`(可简写`c`)继续运行至断点,`list cur_line`(可简写`l`)显示行号。
``输入一个整数即可。``为临时变量名或者全局变量名,如:`%3`,`@a`。``有四种:`i32`、 `i8` 、`double` 、`float`。
命令均支持缩写,受限调试模式下`break`和`continue`命令不可用。
命令使用示例:
```bash
break 11
p %5
x/i8 0x7fff8660
x/double %8
list cur_line
```