TCC(TinyC)编译器汉化(中文编译器、汉语编程)之七:中间语言生成器
程序员文章站
2022-03-30 20:17:17
...
中间语言生成器源码如下:
/*
* ZHI的CIL(Common Intermediate Language:通用中间语言)代码生成器
*/
#error 自2003年以来,此代码已被破坏
/* 可用寄存器数 */
#定义 可用_寄存器数 3
/* 一个寄存器可以属于几个类。 这些类必须从更一般的类到更精确的类进行排序(请参见gv2()代码进行假设)。 */
#定义 寄存器类_堆栈 0x0001 /* 任何堆栈条目 */
#定义 寄存器类_堆栈0 0x0002 /* 堆栈顶部 */
#定义 寄存器类_堆栈1 0x0004 /* top - 1 */
#定义 寄存器类_整数 寄存器类_堆栈
#定义 寄存器类_浮点 寄存器类_堆栈
#定义 寄存器类_返回整数寄存器 寄存器类_堆栈0 /* 函数返回:整数寄存器 */
#定义 寄存器类_返回长整数寄存器 寄存器类_堆栈0 /* 函数返回:第二个整数寄存器*/
#定义 寄存器类_返回浮点寄存器 寄存器类_堆栈0 /* 函数返回:浮点寄存器 */
/* 寄存器的漂亮名字 */
枚举 {
寄存器_堆栈0 = 0,
寄存器_堆栈1,
寄存器_堆栈2,
};
常量 整数型 寄存器_类数[可用_寄存器数] = {
/* ST0 */ 寄存器类_堆栈| 寄存器类_堆栈0,
/* ST1 */ 寄存器类_堆栈| 寄存器类_堆栈1,
/* ST2 */ 寄存器类_堆栈,
};
/* 返回功能寄存器 */
#定义 寄存器_返回16位整数寄存器 寄存器_堆栈0 /* 单字int返回寄存器 */
#定义 寄存器_返回长整数寄存器 寄存器_堆栈0 /* 第二个字返回寄存器(很长很长) */
#定义 寄存器_返回浮点寄存器 寄存器_堆栈0 /* 浮动返回寄存器 */
/* 定义是否必须以相反顺序求值函数参数 */
/* #定义 相反顺序_函数_参数 */
/* 定义是否将结构作为指针传递。 否则,结构将直接压入堆栈。 */
/* #定义 函数_STRUCT_PARAM_AS_PTR */
/* 指针大小,以字节为单位 */
#定义 指针_大小 4
/* 长整型和对齐(以字节为单位) */
#定义 长双精度_大小 8
#定义 长双精度_对齐 8
/* 函数调用上下文 */
类型定义 结构体 调用函数上下文 {
整数型 函数_调用; /* 函数调用类型(函数_标准调用或函数_CDECL) */
} 调用函数上下文;
/******************************************************/
/* 操作码定义 */
#定义 中间语言_操作码_前缀 0xFE
枚举 中间语言操作代码 {
#定义 操作码(名称, 字符串, 编号) 中间语言_操作码_ ## name = n,
#导入 "中间语言-操作码.h"
};
字符型 *中间语言_操作码_字符串[] = {
#定义 操作码(名称, 字符串, 编号) [n] = str,
#导入 "中间语言-操作码.h"
};
/******************************************************/
/* 参数变量编号从此处开始 */
#定义 参数变量_编号 0x70000000
静态 FILE *中间语言_输出文件;
静态 无类型 输出_字节(整数型 c)
{
*(字符型 *)输出代码索引++ = c;
}
静态 无类型 输出_le32(整数型 c)
{
输出_字节(c);
输出_字节(c >> 8);
输出_字节(c >> 16);
输出_字节(c >> 24);
}
静态 无类型 初始化_输出文件(无类型)
{
如果 (!中间语言_输出文件) {
中间语言_输出文件 = stdout;
fprintf(中间语言_输出文件,
".汇编 外部 mscorlib\n"
"{\n"
".ver 1:0:2411:0\n"
"}\n\n");
}
}
静态 无类型 输出_操作码1(整数型 op)
{
如果 (op & 0x100)
输出_字节(中间语言_操作码_前缀);
输出_字节(op & 0xff);
}
/* 输出带有前缀的操作码 */
静态 无类型 输出_操作码(整数型 op)
{
输出_操作码1(op);
fprintf(中间语言_输出文件, " %s\n", 中间语言_操作码_字符串[op]);
}
静态 无类型 输出_操作码字节(整数型 op, 整数型 c)
{
输出_操作码1(op);
输出_字节(c);
fprintf(中间语言_输出文件, " %s %d\n", 中间语言_操作码_字符串[op], c);
}
静态 无类型 输出_操作码整数(整数型 op, 整数型 c)
{
输出_操作码1(op);
输出_le32(c);
fprintf(中间语言_输出文件, " %s 0x%x\n", 中间语言_操作码_字符串[op], c);
}
/* XXX: 不完整 */
静态 无类型 中间语言_类型_的_字符串(字符型 *buf, 整数型 buf_size,
整数型 t, 常量 字符型 *varstr)
{
整数型 bt;
符号 *s, *sa;
字符型 buf1[256];
常量 字符型 *tstr;
t = t & VT_类型;
bt = t & VT_基本类型;
buf[0] = '\0';
如果 (t & VT_无符号)
连接_字符串(buf, buf_size, "无符号 ");
选择(bt) {
分支 VT_无类型:
tstr = "无类型";
去向 add_tstr;
分支 VT_逻辑:
tstr = "bool";
去向 add_tstr;
分支 VT_字节:
tstr = "int8";
去向 add_tstr;
分支 VT_短整数:
tstr = "int16";
去向 add_tstr;
分支 VT_枚举:
分支 VT_整数:
分支 VT_长整数:
tstr = "int32";
去向 add_tstr;
分支 VT_长长整数:
tstr = "int64";
去向 add_tstr;
分支 VT_浮点:
tstr = "float32";
去向 add_tstr;
分支 VT_双精度:
分支 VT_长双精度:
tstr = "float64";
add_tstr:
连接_字符串(buf, buf_size, tstr);
跳出;
分支 VT_结构体:
错误_打印("尚未处理的结构");
跳出;
分支 VT_函数:
s = 符号_查询((无符号)t >> VT_结构体_转换);
中间语言_类型_的_字符串(buf, buf_size, s->t, varstr);
连接_字符串(buf, buf_size, "(");
sa = s->next;
判断 (sa != NULL) {
中间语言_类型_的_字符串(buf1, 取大小(buf1), sa->t, NULL);
连接_字符串(buf, buf_size, buf1);
sa = sa->next;
如果 (sa)
连接_字符串(buf, buf_size, ", ");
}
连接_字符串(buf, buf_size, ")");
去向 no_var;
分支 VT_指针:
s = 符号_查询((无符号)t >> VT_结构体_转换);
p字符串复制(buf1, 取大小(buf1), "*");
如果 (varstr)
连接_字符串(buf1, 取大小(buf1), varstr);
中间语言_类型_的_字符串(buf, buf_size, s->t, buf1);
去向 no_var;
}
如果 (varstr) {
连接_字符串(buf, buf_size, " ");
连接_字符串(buf, buf_size, varstr);
}
no_var: ;
}
/* 值为“ val”的修补程序重定位条目 */
无类型 greloc_patch1(Reloc *p, 整数型 val)
{
}
/* 输出一个符号并修补对它的所有调用 */
无类型 生成符号_地址(t, a)
{
}
/* 输出跳转和返回符号 */
静态 整数型 输出_跳转和操作码符号(整数型 op, 整数型 c)
{
输出_操作码1(op);
输出_le32(0);
如果 (c == 0) {
c = 输出代码索引 - (整数型)当前_生成代码_段->data;
}
fprintf(中间语言_输出文件, " %s L%d\n", 中间语言_操作码_字符串[op], c);
返回 c;
}
无类型 生成符号(整数型 t)
{
fprintf(中间语言_输出文件, "L%d:\n", t);
}
/* 从值“ sv”加载“ r” */
无类型 加载(整数型 r, 堆栈值 *sv)
{
整数型 v, fc, ft;
v = sv->r & VT_值掩码;
fc = sv->c.i;
ft = sv->t;
如果 (sv->r & VT_LVAL) {
如果 (v == VT_LOCAL) {
如果 (fc >= 参数变量_编号) {
fc -= 参数变量_编号;
如果 (fc >= 0 && fc <= 4) {
输出_操作码(中间语言_操作码_LDARG_0 + fc);
} 否则 如果 (fc <= 0xff) {
输出_操作码字节(中间语言_操作码_LDARG_S, fc);
} 否则 {
输出_操作码整数(中间语言_操作码_LDARG, fc);
}
} 否则 {
如果 (fc >= 0 && fc <= 4) {
输出_操作码(中间语言_操作码_LDLOC_0 + fc);
} 否则 如果 (fc <= 0xff) {
输出_操作码字节(中间语言_操作码_LDLOC_S, fc);
} 否则 {
输出_操作码整数(中间语言_操作码_LDLOC, fc);
}
}
} 否则 如果 (v == VT_VC常量) {
/* XXX: handle globals */
输出_操作码整数(中间语言_操作码_LDSFLD, 0);
} 否则 {
如果 ((ft & VT_基本类型) == VT_浮点) {
输出_操作码(中间语言_操作码_LDIND_R4);
} 否则 如果 ((ft & VT_基本类型) == VT_双精度) {
输出_操作码(中间语言_操作码_LDIND_R8);
} 否则 如果 ((ft & VT_基本类型) == VT_长双精度) {
输出_操作码(中间语言_操作码_LDIND_R8);
} 否则 如果 ((ft & VT_类型) == VT_字节)
输出_操作码(中间语言_操作码_LDIND_I1);
否则 如果 ((ft & VT_类型) == (VT_字节 | VT_无符号))
输出_操作码(中间语言_操作码_LDIND_U1);
否则 如果 ((ft & VT_类型) == VT_短整数)
输出_操作码(中间语言_操作码_LDIND_I2);
否则 如果 ((ft & VT_类型) == (VT_短整数 | VT_无符号))
输出_操作码(中间语言_操作码_LDIND_U2);
否则
输出_操作码(中间语言_操作码_LDIND_I4);
}
} 否则 {
如果 (v == VT_VC常量) {
/* XXX: handle globals */
如果 (fc >= -1 && fc <= 8) {
输出_操作码(中间语言_操作码_LDC_I4_M1 + fc + 1);
} 否则 {
输出_操作码整数(中间语言_操作码_LDC_I4, fc);
}
} 否则 如果 (v == VT_LOCAL) {
如果 (fc >= 参数变量_编号) {
fc -= 参数变量_编号;
如果 (fc <= 0xff) {
输出_操作码字节(中间语言_操作码_LDARGA_S, fc);
} 否则 {
输出_操作码整数(中间语言_操作码_LDARGA, fc);
}
} 否则 {
如果 (fc <= 0xff) {
输出_操作码字节(中间语言_操作码_LDLOCA_S, fc);
} 否则 {
输出_操作码整数(中间语言_操作码_LDLOCA, fc);
}
}
} 否则 {
/* XXX: 执行 it */
}
}
}
/* 将寄存器“ r”存储在左值“ v”中 */
无类型 存储(整数型 r, 堆栈值 *sv)
{
整数型 v, fc, ft;
v = sv->r & VT_值掩码;
fc = sv->c.i;
ft = sv->t;
如果 (v == VT_LOCAL) {
如果 (fc >= 参数变量_编号) {
fc -= 参数变量_编号;
/* XXX: check IL arg 存储 semantics */
如果 (fc <= 0xff) {
输出_操作码字节(中间语言_操作码_STARG_S, fc);
} 否则 {
输出_操作码整数(中间语言_操作码_STARG, fc);
}
} 否则 {
如果 (fc >= 0 && fc <= 4) {
输出_操作码(中间语言_操作码_STLOC_0 + fc);
} 否则 如果 (fc <= 0xff) {
输出_操作码字节(中间语言_操作码_STLOC_S, fc);
} 否则 {
输出_操作码整数(中间语言_操作码_STLOC, fc);
}
}
} 否则 如果 (v == VT_VC常量) {
/* XXX: handle globals */
输出_操作码整数(中间语言_操作码_STSFLD, 0);
} 否则 {
如果 ((ft & VT_基本类型) == VT_浮点)
输出_操作码(中间语言_操作码_STIND_R4);
否则 如果 ((ft & VT_基本类型) == VT_双精度)
输出_操作码(中间语言_操作码_STIND_R8);
否则 如果 ((ft & VT_基本类型) == VT_长双精度)
输出_操作码(中间语言_操作码_STIND_R8);
否则 如果 ((ft & VT_基本类型) == VT_字节)
输出_操作码(中间语言_操作码_STIND_I1);
否则 如果 ((ft & VT_基本类型) == VT_短整数)
输出_操作码(中间语言_操作码_STIND_I2);
否则
输出_操作码(中间语言_操作码_STIND_I4);
}
}
/* 开始函数调用和返回函数调用上下文 */
无类型 开始调用函数_返回函数调用上下文(调用函数上下文 *c, 整数型 函数_调用)
{
c->函数_调用 = 函数_调用;
}
/* 在(栈顶值-> t,栈顶值-> c)中的push函数参数。 然后弹出堆栈条目. */
无类型 开始调用函数_参数(调用函数上下文 *c)
{
如果 ((栈顶值->t & VT_基本类型) == VT_结构体) {
错误_打印("作为值传递的结构尚未处理");
} 否则 {
/* simply push on stack */
将rc寄存器值存储在栈顶值中(寄存器类_堆栈0);
}
栈顶值--;
}
/* 在(栈顶值-> t,栈顶值-> c)和*函数上下文中生成具有地址的函数调用。 弹出堆栈条目 */
无类型 具体地址函数_调用(调用函数上下文 *c)
{
字符型 buf[1024];
如果 ((栈顶值->r & (VT_值掩码 | VT_LVAL)) == VT_VC常量) {
/* XXX: zhi需要更多信息 */
中间语言_类型_的_字符串(buf, 取大小(buf), 栈顶值->t, "xxx");
fprintf(中间语言_输出文件, " call %s\n", buf);
} 否则 {
/* 间接的ect call */
将rc寄存器值存储在栈顶值中(寄存器类_整数);
中间语言_类型_的_字符串(buf, 取大小(buf), 栈顶值->t, NULL);
fprintf(中间语言_输出文件, " calli %s\n", buf);
}
栈顶值--;
}
/* 生成类型为“ t”的函数序言 */
无类型 生成函数_序言(整数型 t)
{
整数型 addr, u, 函数_调用;
符号 *sym;
字符型 buf[1024];
初始化_输出文件();
/* XXX: pass function name to 生成函数_序言 */
中间语言_类型_的_字符串(buf, 取大小(buf), t, 函数名称);
fprintf(中间语言_输出文件, ".method 静态 %s il managed\n", buf);
fprintf(中间语言_输出文件, "{\n");
/* XXX: cannot 执行 better now */
fprintf(中间语言_输出文件, " .maxstack %d\n", 可用_寄存器数);
fprintf(中间语言_输出文件, " .locals (int32, int32, int32, int32, int32, int32, int32, int32)\n");
如果 (!strcmp(函数名称, "main")||!strcmp(函数名称, "主函数"))
fprintf(中间语言_输出文件, " .entrypoint\n");
sym = 符号_查询((无符号)t >> VT_结构体_转换);
函数_调用 = sym->r;
addr = 参数变量_编号;
/* 如果函数返回结构,则添加一个隐式指针参数 */
当前函数_返回类型 = sym->t;
当前函数_可变参数 = (sym->c == 函数_省略);
如果 ((当前函数_返回类型 & VT_基本类型) == VT_结构体) {
函数_vc = addr;
addr++;
}
/* 定义参数 */
判断 ((sym = sym->next) != NULL) {
u = sym->t;
符号_压入栈(sym->v & ~符号_字段, u,
VT_LOCAL | lvalue_type(sym->type.t), addr);
addr++;
}
}
/* 生成函数结尾 */
无类型 生成函数_结尾(无类型)
{
输出_操作码(中间语言_操作码_RET);
fprintf(中间语言_输出文件, "}\n\n");
}
/* 生成跳转到标签 */
整数型 生成跳转到标签(整数型 t)
{
返回 输出_跳转和操作码符号(中间语言_操作码_BR, t);
}
/* 生成跳转到固定地址 */
无类型 生成跳转到_固定地址(整数型 a)
{
/* XXX: 处理符号 */
输出_操作码整数(中间语言_操作码_BR, a);
}
/* 生成测试。 将“ inv”设置为反转测试。 弹出堆栈条目 */
整数型 生成测试(整数型 inv, 整数型 t)
{
整数型 v, *p, c;
v = 栈顶值->r & VT_值掩码;
如果 (v == VT_CMP) {
c = 栈顶值->c.i ^ inv;
选择(c) {
分支 双符号_等于:
c = 中间语言_操作码_BEQ;
跳出;
分支 双符号_不等于:
c = 中间语言_操作码_BNE_UN;
跳出;
分支 符_LT:
c = 中间语言_操作码_BLT;
跳出;
分支 双符号_小于等于:
c = 中间语言_操作码_BLE;
跳出;
分支 符_GT:
c = 中间语言_操作码_BGT;
跳出;
分支 双符号_大于等于:
c = 中间语言_操作码_BGE;
跳出;
分支 符号_ULT:
c = 中间语言_操作码_BLT_UN;
跳出;
分支 符号_ULE:
c = 中间语言_操作码_BLE_UN;
跳出;
分支 符_UGT:
c = 中间语言_操作码_BGT_UN;
跳出;
分支 符号_UGE:
c = 中间语言_操作码_BGE_UN;
跳出;
}
t = 输出_跳转和操作码符号(c, t);
} 否则 如果 (v == VT_JMP || v == VT_JMPI) {
/* && or || optimization */
如果 ((v & 1) == inv) {
/* insert 栈顶值->c jump list in t */
p = &栈顶值->c.i;
判断 (*p != 0)
p = (整数型 *)*p;
*p = t;
t = 栈顶值->c.i;
} 否则 {
t = 生成跳转到标签(t);
生成符号(栈顶值->c.i);
}
}
栈顶值--;
返回 t;
}
/* 生成整数二进制运算 */
无类型 生成_整数二进制运算(整数型 op)
{
将rc寄存器值存储在栈顶值中2(寄存器类_堆栈1, 寄存器类_堆栈0);
选择(op) {
分支 '+':
输出_操作码(中间语言_操作码_ADD);
去向 std_op;
分支 '-':
输出_操作码(中间语言_操作码_SUB);
去向 std_op;
分支 '&':
输出_操作码(中间语言_操作码_AND);
去向 std_op;
分支 '^':
输出_操作码(中间语言_操作码_XOR);
去向 std_op;
分支 '|':
输出_操作码(中间语言_操作码_OR);
去向 std_op;
分支 '*':
输出_操作码(中间语言_操作码_MUL);
去向 std_op;
分支 双符号_左位移:
输出_操作码(中间语言_操作码_SHL);
去向 std_op;
分支 符_SHR:
输出_操作码(中间语言_操作码_SHR_UN);
去向 std_op;
分支 双符号_右位移:
输出_操作码(中间语言_操作码_SHR);
去向 std_op;
分支 '/':
分支 符_指针除法:
输出_操作码(中间语言_操作码_DIV);
去向 std_op;
分支 符_无符除法:
输出_操作码(中间语言_操作码_DIV_UN);
去向 std_op;
分支 '%':
输出_操作码(中间语言_操作码_REM);
去向 std_op;
分支 符_无符取模运算:
输出_操作码(中间语言_操作码_REM_UN);
std_op:
栈顶值--;
栈顶值[0].r = 寄存器_堆栈0;
跳出;
分支 双符号_等于:
分支 双符号_不等于:
分支 符_LT:
分支 双符号_小于等于:
分支 符_GT:
分支 双符号_大于等于:
分支 符号_ULT:
分支 符号_ULE:
分支 符_UGT:
分支 符号_UGE:
栈顶值--;
栈顶值[0].r = VT_CMP;
栈顶值[0].c.i = op;
跳出;
}
}
/* 生成浮点运算“ v = t1 op t2”指令。 保证两个操作数具有相同的浮点类型 */
无类型 生成_浮点运算(整数型 op)
{
/* same as integer */
生成_整数二进制运算(op);
}
/* 将整数转换为fp't'类型。 必须处理'整数型','无符号 整数型'和'long long'情况。 */
无类型 生成_整数转换为浮点(整数型 t)
{
将rc寄存器值存储在栈顶值中(寄存器类_堆栈0);
如果 (t == VT_浮点)
输出_操作码(中间语言_操作码_CONV_R4);
否则
输出_操作码(中间语言_操作码_CONV_R8);
}
/* 将fp转换为int't'类型 */
/* XXX: handle long long 分支 */
无类型 生成_浮点转换为整数(整数型 t)
{
将rc寄存器值存储在栈顶值中(寄存器类_堆栈0);
选择(t) {
分支 VT_整数 | VT_无符号:
输出_操作码(中间语言_操作码_CONV_U4);
跳出;
分支 VT_长长整数:
输出_操作码(中间语言_操作码_CONV_I8);
跳出;
分支 VT_长长整数 | VT_无符号:
输出_操作码(中间语言_操作码_CONV_U8);
跳出;
default:
输出_操作码(中间语言_操作码_CONV_I4);
跳出;
}
}
/* 从一种浮点类型转换为另一种 */
无类型 生成_浮点转换为另一种浮点(整数型 t)
{
将rc寄存器值存储在栈顶值中(寄存器类_堆栈0);
如果 (t == VT_浮点) {
输出_操作码(中间语言_操作码_CONV_R4);
} 否则 {
输出_操作码(中间语言_操作码_CONV_R8);
}
}
/* CIL代码生成器的结尾 */
/*************************************************************/
推荐阅读
-
TCC(TinyC)编译器汉化(中文编译器、汉语编程)之四:语法分析上
-
TCC(TinyC)编译器汉化(中文编译器、汉语编程)之三:词法分析
-
TCC(TinyC)编译器汉化(中文编译器、汉语编程)之二:字符(token)汉化
-
TCC(TinyC)编译器汉化(中文编译器、汉语编程)之九:核心库源码
-
TCC(TinyC)编译器汉化(中文编译器、汉语编程)之七:中间语言生成器
-
TCC(TinyC)编译器汉化(中文编译器、汉语编程)之六:中间操作码
-
TCC(TinyC)编译器汉化(中文编译器、汉语编程)之八:汇编处理
-
TCC(TinyC)编译器汉化(中文编译器、汉语编程)之一:主文件汉化
-
TCC(TinyC)编译器汉化(中文编译器、汉语编程)之五:语法分析下