TCC(TinyC)编译器汉化(中文编译器、汉语编程)之四:语法分析上
程序员文章站
2022-03-30 20:42:26
...
语法分析代码过长,由于单篇博文字数限制,现将语法分析源码分为上下两篇
语法分析.c
/*
* 语法分析:递归下降式语法制导,单趟编译
*/
#定义 全局_使用
#导入 "zhi.h"
/********************************************************/
/* 全局变量 */
静态_外部 整数型 返回符号, 匿名符号索引, 输出代码索引, 局部变量索引;
静态_外部 符号 *全局符号_堆栈;/*主要的符号堆栈:用于全局变量,函数和类型。*/
静态_外部 符号 *局部符号_堆栈;/*主要的符号堆栈:用于局部变量,函数和类型。*/
静态_外部 符号 *宏定义符号_堆栈;/*主要的符号堆栈:用于宏(#defines)。*/
静态_外部 符号 *全局符号_标签_堆栈;/*主要的符号堆栈:全局标签(用于goto)。*/
静态_外部 符号 *局部符号_标签_堆栈;
静态 符号 *符号_释放_第一;
静态 无类型 **符号_池;
静态 整数型 数量_符号_池;
静态 符号 *清理_所有, *待定_去向;
静态 整数型 局部_范围;
静态 整数型 in_大小;
静态 整数型 in_通用;
静态 整数型 段_符号;
静态_外部 堆栈值 *栈顶值;
静态 堆栈值 _堆栈值[1 + 堆栈值_大小];
#定义 宏堆栈值 (_堆栈值 + 1)
静态_外部 整数型 需要_常量; /* 如果需要常量,则为true */
静态_外部 整数型 不需要_代码生成; /* 不需要代码生成 */
#定义 未评估的子表达式 0xffff /* 未评估的子表达式 */
#定义 不需要_静态数据输出 (不需要_代码生成 > 0) /* 也不需要静态数据输出 */
#定义 仅_静态数据输出 (不需要_代码生成 & 0xC0000000) /* 仅静态数据输出 */
/* 自动代码抑制 ----> */
#定义 代码_关() (不需要_代码生成 |= 0x20000000)
#定义 代码_开() (不需要_代码生成 &= ~0x20000000)
/* 如果使用了'不需要_代码生成'标签,请清除它. */
静态_函数 无类型 生成符号(整数型 t)
{
如果 (t)
{
生成符号_地址(t, 输出代码索引);
代码_开();
}
}
静态 整数型 返回代码索引(无类型)
{
代码_开();
返回 输出代码索引;
}
/* 无条件跳转后设置“ 不需要_代码生成” */
静态 无类型 g跳转_地址_acs(整数型 t)
{
生成跳转到_固定地址(t);
代码_关();
}
静态 整数型 g跳转_acs(整数型 t)
{
t = 生成跳转到标签(t);
代码_关();
返回 t;
}
/* 这些文件的末尾是#取消定义 */
#定义 生成跳转到_固定地址 g跳转_地址_acs
#定义 生成跳转到标签 g跳转_acs
/* <---- */
静态_外部 整数型 全局_分配复合字符; /* 如果必须在全局范围内分配复合文字,则为true(在初始化程序解析期间使用) */
静态_外部 C类型 当前函数_返回类型; /* 当前函数的返回类型(由返回指令使用) */
静态_外部 整数型 当前函数_可变参数; /* 如果当前函数是可变参数,则为true(由返回指令使用) */
静态_外部 整数型 函数_vc;
静态 整数型 最后_行_号, 新_文件, func_ind; /* 调试信息控制 */
静态_外部 常量 字符型 *函数名称;
静态_外部 C类型 int_type, 函数_旧_类型, 字符_指针_类型;
静态 动态字符串 初始字符串;
#如果 指针_大小 == 4
#定义 VT_SIZE_T (VT_整数 | VT_无符号)
#定义 VT_指针DIFF_T VT_整数
#否则如果 LONG_SIZE == 4
#定义 VT_SIZE_T (VT_长长整数 | VT_无符号)
#定义 VT_指针DIFF_T VT_长长整数
#否则
#定义 VT_SIZE_T (VT_长整数 | VT_长长整数 | VT_无符号)
#定义 VT_指针DIFF_T (VT_长整数 | VT_长长整数)
#结束如果
静态_外部 结构体 选择结构体 {
结构体 分支_t
{
int64_t v1, v2;
整数型 sym;
} **p;
整数型 n; /* 分支列表清单范围 */
整数型 默认_符号; /* 默认符号 */
整数型 *bsym;
结构体 范围 *范围;
结构体 选择结构体 *prev;
堆栈值 sv;
} *当前_选择; /* 当前选择 */
#定义 局部变量_最多个数 8
/*当前函数堆栈中的临时局部变量列表. */
静态_外部 结构体 局部_变量_范围
{
整数型 位置; //堆栈上的偏移量。 值.
short size;
short align;
} 局部_变量_数组[局部变量_最多个数];
short 数量_局部_变量数_范围;
静态 结构体 范围
{
结构体 范围 *prev;
结构体 { 整数型 局部变量索引, num; } vla;
结构体 { 符号 *s; 整数型 n; } cl;
整数型 *bsym, *csym;
符号 *lstk, *llstk;
} *当前_范围, *循环_范围, *根_范围;
/********************************************************/
/* 使调试支持 */
静态 常量 结构体
{
整数型 type;
常量 字符型 *name;
} 默认_调试[] = {
{ VT_整数, "整数型:t1=r1;-2147483648;2147483647;" },
{ VT_字节, "字符型:t2=r2;0;127;" },
#如果 LONG_SIZE == 4
{ VT_长整数 | VT_整数, "long 整数型:t3=r3;-2147483648;2147483647;" },
#否则
{ VT_长长整数 | VT_长整数, "long 整数型:t3=r3;-9223372036854775808;9223372036854775807;" },
#结束如果
{ VT_整数 | VT_无符号, "无符号 整数型:t4=r4;0;037777777777;" },
#如果 LONG_SIZE == 4
{ VT_长整数 | VT_整数 | VT_无符号, "long 无符号 整数型:t5=r5;0;037777777777;" },
#否则
/* 使用八进制而不是-1,因此size_t有效(gcc中的-gstabs +) */
{ VT_长长整数 | VT_长整数 | VT_无符号, "long 无符号 整数型:t5=r5;0;01777777777777777777777;" },
#结束如果
{ VT_128位整数, "__int128:t6=r6;0;-1;" },
{ VT_128位整数 | VT_无符号, "__int128 无符号:t7=r7;0;-1;" },
{ VT_长长整数, "long long 整数型:t8=r8;-9223372036854775808;9223372036854775807;" },
{ VT_长长整数 | VT_无符号, "long long 无符号 整数型:t9=r9;0;01777777777777777777777;" },
{ VT_短整数, "short 整数型:t10=r10;-32768;32767;" },
{ VT_短整数 | VT_无符号, "short 无符号 整数型:t11=r11;0;65535;" },
{ VT_字节 | VT_显式符号, "signed 字符型:t12=r12;-128;127;" },
{ VT_字节 | VT_显式符号 | VT_无符号, "无符号 字符型:t13=r13;0;255;" },
{ VT_浮点, "float:t14=r1;4;0;" },
{ VT_双精度, "double:t15=r1;8;0;" },
{ VT_长双精度, "long double:t16=r1;16;0;" },
{ -1, "_Float32:t17=r1;4;0;" },
{ -1, "_Float64:t18=r1;8;0;" },
{ -1, "_Float128:t19=r1;16;0;" },
{ -1, "_Float32x:t20=r1;8;0;" },
{ -1, "_Float64x:t21=r1;16;0;" },
{ -1, "_Decimal32:t22=r1;4;0;" },
{ -1, "_Decimal64:t23=r1;8;0;" },
{ -1, "_Decimal128:t24=r1;16;0;" },
/* 如果默认字符是未签名的 */
{ VT_字节 | VT_无符号, "无符号 字符型:t25=r25;0;255;" },
{ VT_无类型, "无类型:t26=26" },
};
静态 整数型 调试_下个_类型;
静态 结构体 调试_哈希
{
整数型 debug_type;
符号 *type;
} *调试_哈希;
静态 整数型 n_调试_哈希;
静态 结构体 调试_信息
{
整数型 start;
整数型 end;
整数型 n_sym;
结构体 debug_sym
{
整数型 type;
无符号 long value;
字符型 *str;
段 *sec;
整数型 sym_index;
} *sym;
结构体 调试_信息 *child, *next, *last, *parent;
} *调试_信息, *调试_信息_根;
/********************************************************/
#如果 1
#定义 优先级_解析器
静态 无类型 初始化_优先权(无类型);
#结束如果
/********************************************************/
#如果未定义 配置_ZHI_汇编
静态_函数 无类型 汇编_指令字符串(无类型)
{
错误_打印("不支持内联 asm()");
}
静态_函数 无类型 汇编_全局_instr(无类型)
{
错误_打印("不支持内联asm()");
}
#结束如果
/* ------------------------------------------------------------------------- */
静态 无类型 通用_转换(C类型 *type);
静态 无类型 通用_转换_s(整数型 t);
静态 内联 C类型 *指定的_类型(C类型 *type);
静态 整数型 是_兼容_类型(C类型 *type1, C类型 *type2);
静态 整数型 解析_基本类型(C类型 *type, 属性定义 *ad);
静态 C类型 *类型_声明(C类型 *type, 属性定义 *ad, 整数型 *v, 整数型 td);
静态 无类型 解析_表达式_类型(C类型 *type);
静态 无类型 将值或表达式_直接存储在全局数据或本地数组中(C类型 *type, 段 *sec, 无符号 long c);
静态 无类型 声明_初始化器(C类型 *type, 段 *sec, 无符号 long c, 整数型 flags);
静态 无类型 块(整数型 is_expr);
静态 无类型 声明_初始化_分配(C类型 *type, 属性定义 *ad, 整数型 r, 整数型 has_init, 整数型 v, 整数型 范围);
静态 无类型 声明(整数型 l);
静态 整数型 声明0(整数型 l, 整数型 is_for_loop_init, 符号 *);
静态 无类型 等于_表达式(无类型);
静态 无类型 vla_运行时_类型_大小(C类型 *type, 整数型 *a);
静态 整数型 是_兼容_不合格的_类型(C类型 *type1, C类型 *type2);
静态 内联 int64_t 表达式_常量64(无类型);
静态 无类型 压入64位常量(整数型 ty, 无符号 long long v);
静态 无类型 压入指定类型常量(C类型 *type);
静态 整数型 生成值测试(整数型 inv, 整数型 t);
静态 无类型 生成_内联函数(知心状态机 *s);
静态 无类型 释放_内联函数(知心状态机 *s);
静态 无类型 跳过_或_保存_块(单词字符串 **str);
静态 无类型 堆栈转为寄存器并复制到另一个寄存器(无类型);
静态 整数型 获取_临时_局部_变量(整数型 size,整数型 align);
静态 无类型 清除_临时_局部_变量_列表();
静态 无类型 投放_错误(C类型 *st, C类型 *dt);
静态_内联 整数型 是_浮点型(整数型 t)
{
整数型 bt = t & VT_基本类型;
返回 bt == VT_长双精度|| bt == VT_双精度|| bt == VT_浮点|| bt == VT_128位浮点;
}
静态 内联 整数型 是_整数_型(整数型 bt)
{
返回 bt == VT_字节|| bt == VT_逻辑|| bt == VT_短整数|| bt == VT_整数|| bt == VT_长长整数;
}
静态 整数型 基本类型_大小(整数型 bt)
{
返回 bt == VT_字节 || bt == VT_逻辑 ? 1 :bt == VT_短整数 ? 2 :bt == VT_整数 ? 4 :bt == VT_长长整数 ? 8 :bt == VT_指针 ? 指针_大小 : 0;
}
/* 从类型返回函数返回寄存器 */
静态 整数型 返回_t的类型寄存器(整数型 t)
{
如果 (!是_浮点型(t))
返回 寄存器_返回16位整数寄存器;
#如果已定义 ZHI_TARGET_X86_64
如果 ((t & VT_基本类型) == VT_长双精度)
返回 TREG_ST0;
#否则如果 已定义 ZHI_TARGET_RISCV64
如果 ((t & VT_基本类型) == VT_长双精度)
返回 寄存器_返回16位整数寄存器;
#结束如果
返回 寄存器_返回浮点寄存器;
}
/* 返回第二个函数返回寄存器(如果有) */
静态 整数型 返回_t的类型寄存器2(整数型 t)
{
t &= VT_基本类型;
#如果 指针_大小 == 4
如果 (t == VT_长长整数)
返回 寄存器_返回32位整数寄存器;
#否则如果 已定义 ZHI_TARGET_X86_64
如果 (t == VT_128位整数)
返回 寄存器_返回32位整数寄存器;
如果 (t == VT_128位浮点)
返回 寄存器_返回第二个浮点寄存器;
#否则如果 已定义 ZHI_TARGET_RISCV64
如果 (t == VT_长双精度)
返回 寄存器_返回32位整数寄存器;
#结束如果
返回 VT_VC常量;
}
/* 对于两个单词的类型返回true */
#定义 使用_两个单词的_类型(t) (返回_t的类型寄存器2(t) != VT_VC常量)
/* 将函数返回寄存器放入堆栈值 */
静态 无类型 将函数_返回寄存器_放入堆栈值(堆栈值 *sv, 整数型 t)
{
sv->r = 返回_t的类型寄存器(t), sv->r2 = 返回_t的类型寄存器2(t);
}
/* 返回类型t的函数返回寄存器类 */
静态 整数型 返回类型t的函数_返回寄存器(整数型 t)
{
返回 寄存器_类数[返回_t的类型寄存器(t)] & ~(寄存器类_浮点 | 寄存器类_整数);
}
/* 返回类型t的通用寄存器类 */
静态 整数型 返回类型t的_通用寄存器类(整数型 t)
{
如果 (!是_浮点型(t))
返回 寄存器类_整数;
#如果已定义 ZHI_TARGET_X86_64
如果 ((t & VT_基本类型) == VT_长双精度)
返回 寄存器类_堆栈0;
如果 ((t & VT_基本类型) == VT_128位浮点)
返回 寄存器类_返回浮点寄存器;
#否则如果 已定义 ZHI_TARGET_RISCV64
如果 ((t & VT_基本类型) == VT_长双精度)
返回 寄存器类_整数;
#结束如果
返回 寄存器类_浮点;
}
/* 返回对应于t和rc的第二个寄存器类 */
静态 整数型 返回类型t的2_通用寄存器类(整数型 t, 整数型 rc)
{
如果 (!使用_两个单词的_类型(t))
返回 0;
#如果已定义 RC_IRE2
如果 (rc == 寄存器类_返回整数寄存器)
返回 RC_IRE2;
#结束如果
#如果已定义 RC_FRE2
如果 (rc == 寄存器类_返回浮点寄存器)
返回 RC_FRE2;
#结束如果
如果 (rc & 寄存器类_浮点)
返回 寄存器类_浮点;
返回 寄存器类_整数;
}
/* 我们使用自己的“有限”函数来避免非标准数学库的潜在问题 */
/* XXX: 依字节序排列 */
静态_函数 整数型 ieee_有限的(double d)
{
整数型 p[4];
memcpy(p, &d, 取大小(double));
返回 ((无符号)((p[1] | 0x800fffff) + 1)) >> 31;
}
/* 本机编译int long double */
#如果 (已定义 __i386__ || 已定义 __x86_64__) \
&& (已定义 ZHI_TARGET_I386 || 已定义 ZHI_TARGET_X86_64)
# 定义 ZHI_IS_NATIVE_387
#结束如果
静态_函数 无类型 测试_左值(无类型)
{
如果 (!(栈顶值->r & VT_LVAL))
应为("lvalue");
}
静态_函数 无类型 检查_堆栈值(无类型)
{
如果 (栈顶值 != 宏堆栈值 - 1)
错误_打印("内部编译器错误:堆栈值泄漏 (%d)",
(整数型)(栈顶值 - 宏堆栈值 + 1));
}
/* ------------------------------------------------------------------------- */
/* vstack调试辅助 */
#如果 0
无类型 堆栈值调试辅助 (常量 字符型 *lbl, 整数型 a, 整数型 b)
{
整数型 i;
循环 (i = a; i < a + b; ++i) {
堆栈值 *p = &栈顶值[-i];
printf("%s 栈顶值[-%d] : type.t:%04x r:%04x r2:%04x c.i:%d\n",lbl, i, p->type.t, p->r, p->r2, (整数型)p->c.i);
}
}
#结束如果
/* ------------------------------------------------------------------------- */
/* 开始翻译单位信息 */
静态_函数 无类型 zhi_调试_开始(知心状态机 *状态机1)
{
如果 (状态机1->执行_调试)
{
整数型 i;
字符型 buf[512];
/* 文件信息:完整路径+文件名 */
段_符号 = 处理_elf_符号(单词表_部分, 0, 0,ELFW(ST_INFO)(STB_LOCAL, STT_SECTION), 0,生成代码_段->sh_num, NULL);
getcwd(buf, 取大小(buf));/*getcwd()会将当前工作目录的绝对路径复制到参数buffer所指的内存空间中*/
#如果已定义 _WIN32
WIN32规范化斜杠(buf);
#结束如果
连接_字符串(buf, 取大小(buf), "/");/**/
处理_单词表_r(状态机1, buf, N_SO, 0, 0,生成代码_段->数据_偏移, 生成代码_段, 段_符号);
处理_单词表_r(状态机1, file->prev->文件名, N_SO, 0, 0,生成代码_段->数据_偏移, 生成代码_段, 段_符号);
循环 (i = 0; i < 取大小 (默认_调试) / 取大小 (默认_调试[0]); i++)
处理_单词表字符串(状态机1, 默认_调试[i].name, N_LSYM, 0, 0, 0);
新_文件 = 最后_行_号 = 0;
func_ind = -1;
调试_下个_类型 = 取大小(默认_调试) / 取大小(默认_调试[0]);
调试_哈希 = NULL;
n_调试_哈希 = 0;
/* 我们目前正在“包含” <命令行> */
zhi_调试_导入文件的开头(状态机1);
}
/* 必须放置类型为STT_FILE的elf符号,以便可以安全地使用STB_LOCAL符号 */
处理_elf_符号(单词表_部分, 0, 0, ELFW(ST_INFO)(STB_LOCAL, STT_FILE), 0,SHN_ABS, file->文件名);
}
静态 无类型 zhi_调试_stabs (知心状态机 *状态机1, 常量 字符型 *str, 整数型 type, 无符号 long value,段 *sec, 整数型 sym_index)
{
结构体 debug_sym *s;
如果 (调试_信息)
{
调试_信息->sym =(结构体 debug_sym *)内存_重分配容量 (调试_信息->sym,取大小(结构体 debug_sym) *(调试_信息->n_sym + 1));
s = 调试_信息->sym + 调试_信息->n_sym++;
s->type = type;
s->value = value;
s->str = 字符串_宽度加1(str);
s->sec = sec;
s->sym_index = sym_index;
}
否则 如果 (sec)
处理_单词表_r (状态机1, str, type, 0, 0, value, sec, sym_index);
否则
处理_单词表字符串 (状态机1, str, type, 0, 0, value);
}
静态 无类型 zhi_调试_stabn(整数型 type, 整数型 value)
{
如果 (type == N_LBRAC)
{
结构体 调试_信息 *info =(结构体 调试_信息 *) 内存_初始化(取大小 (*info));
info->start = value;
info->parent = 调试_信息;
如果 (调试_信息)
{
如果 (调试_信息->child)
{
如果 (调试_信息->child->last)
调试_信息->child->last->next = info;
否则
调试_信息->child->next = info;
调试_信息->child->last = info;
}
否则
调试_信息->child = info;
}
否则
调试_信息_根 = info;
调试_信息 = info;
}
否则 {
调试_信息->end = value;
调试_信息 = 调试_信息->parent;
}
}
静态 无类型 zhi_获取_调试_信息(知心状态机 *状态机1, 符号 *s, 动态字符串 *result)
{
整数型 type;
整数型 n = 0;
整数型 debug_type = -1;
符号 *t = s;
动态字符串 str;
循环 (;;)
{
type = t->type.t & ~(VT_外部 | VT_静态 | VT_常量 | VT_易变);
如果 ((type & VT_基本类型) != VT_字节)
type &= ~VT_显式符号;
如果 (type == VT_指针 || type == (VT_指针 | VT_数组))
n++, t = t->type.ref;
否则
跳出;
}
如果 ((type & VT_基本类型) == VT_结构体)
{
整数型 i;
t = t->type.ref;
循环 (i = 0; i < n_调试_哈希; i++)
{
如果 (t == 调试_哈希[i].type)
{
debug_type = 调试_哈希[i].debug_type;
跳出;
}
}
如果 (debug_type == -1)
{
debug_type = ++调试_下个_类型;
调试_哈希 = (结构体 调试_哈希 *)内存_重分配容量 (调试_哈希,(n_调试_哈希 + 1) * 取大小(*调试_哈希));
调试_哈希[n_调试_哈希].debug_type = debug_type;
调试_哈希[n_调试_哈希++].type = t;
动态字符串_初始化 (&str);
动态字符串_打印 (&str, "%s:T%d=%c%d",(t->v & ~符号_结构体) >= 符号_第一个_匿名? "" : 取_单词字符串(t->v & ~符号_结构体, NULL),debug_type,是_共用体 (t->type.t) ? 'u' : 's',t->c);
判断 (t->next)
{
整数型 pos, size, align;
t = t->next;
动态字符串_打印 (&str, "%s:",(t->v & ~符号_字段) >= 符号_第一个_匿名? "" : 取_单词字符串(t->v & ~符号_字段, NULL));
zhi_获取_调试_信息 (状态机1, t, &str);
如果 (t->type.t & VT_位域)
{
pos = t->c * 8 + BIT_POS(t->type.t);
size = BIT_大小(t->type.t);
}
否则
{
pos = t->c * 8;
size = 类型_大小(&t->type, &align) * 8;
}
动态字符串_打印 (&str, ",%d,%d;", pos, size);
}
动态字符串_打印 (&str, ";");
zhi_调试_stabs(状态机1, str.指向字符串的指针, N_LSYM, 0, NULL, 0);
动态字符串_释放 (&str);
}
}
否则 如果 (是_枚举(type))
{
符号 *e = t = t->type.ref;
debug_type = ++调试_下个_类型;
动态字符串_初始化 (&str);
动态字符串_打印 (&str, "%s:T%d=e",(t->v & ~符号_结构体) >= 符号_第一个_匿名? "" : 取_单词字符串(t->v & ~符号_结构体, NULL),debug_type);
判断 (t->next)
{
t = t->next;
动态字符串_打印 (&str, "%s:",(t->v & ~符号_字段) >= 符号_第一个_匿名? "" : 取_单词字符串(t->v & ~符号_字段, NULL));
动态字符串_打印 (&str, e->type.t & VT_无符号 ? "%u," : "%d,",(整数型)t->enum_val);
}
动态字符串_打印 (&str, ";");
zhi_调试_stabs(状态机1, str.指向字符串的指针, N_LSYM, 0, NULL, 0);
动态字符串_释放 (&str);
}
否则 如果 ((type & VT_基本类型) != VT_函数) {
type &= ~VT_结构体_掩码;
循环 (debug_type = 1;debug_type <= 取大小(默认_调试) / 取大小(默认_调试[0]);debug_type++)
如果 (默认_调试[debug_type - 1].type == type)
跳出;
如果 (debug_type > 取大小(默认_调试) / 取大小(默认_调试[0]))
返回;
}
如果 (n > 0)
动态字符串_打印 (result, "%d=", ++调试_下个_类型);
t = s;
循环 (;;)
{
type = t->type.t & ~(VT_外部 | VT_静态 | VT_常量 | VT_易变);
如果 ((type & VT_基本类型) != VT_字节)
type &= ~VT_显式符号;
如果 (type == VT_指针)
动态字符串_打印 (result, "%d=*", ++调试_下个_类型);
否则 如果 (type == (VT_指针 | VT_数组))
动态字符串_打印 (result, "%d=ar1;0;%d;",++调试_下个_类型, t->type.ref->c - 1);
否则 如果 (type == VT_函数)
{
动态字符串_打印 (result, "%d=f", ++调试_下个_类型);
zhi_获取_调试_信息 (状态机1, t->type.ref, result);
返回;
}
否则
跳出;
t = t->type.ref;
}
动态字符串_打印 (result, "%d", debug_type);
}
静态 无类型 zhi_调试_完成 (知心状态机 *状态机1, 结构体 调试_信息 *cur)
{
判断 (cur)
{
整数型 i;
结构体 调试_信息 *next = cur->next;
循环 (i = 0; i < cur->n_sym; i++) {
结构体 debug_sym *s = &cur->sym[i];
如果 (s->sec)
处理_单词表_r(状态机1, s->str, s->type, 0, 0, s->value,s->sec, s->sym_index);
否则
处理_单词表字符串(状态机1, s->str, s->type, 0, 0, s->value);
内存_释放 (s->str);
}
内存_释放 (cur->sym);
处理_单词表整数(状态机1, N_LBRAC, 0, 0, cur->start);
zhi_调试_完成 (状态机1, cur->child);
处理_单词表整数(状态机1, N_RBRAC, 0, 0, cur->end);
内存_释放 (cur);
cur = next;
}
}
静态 无类型 zhi_添加_调试_信息(知心状态机 *状态机1, 整数型 param, 符号 *s, 符号 *e)
{
动态字符串 debug_str;
动态字符串_初始化 (&debug_str);
循环 (; s != e; s = s->prev)
{
如果 (!s->v || (s->r & VT_值掩码) != VT_LOCAL)
继续;
动态字符串_重置 (&debug_str);
动态字符串_打印 (&debug_str, "%s:%s", 取_单词字符串(s->v, NULL), param ? "p" : "");
zhi_获取_调试_信息(状态机1, s, &debug_str);
zhi_调试_stabs(状态机1, debug_str.指向字符串的指针, param ? N_PSYM : N_LSYM, s->c, NULL, 0);
}
动态字符串_释放 (&debug_str);
}
静态 无类型 zhi_调试_外部_符号(知心状态机 *状态机1, 符号 *sym, 整数型 sh_num, 整数型 sym_bind)
{
段 *s = 状态机1->段数[sh_num];
动态字符串 str;
动态字符串_初始化 (&str);
动态字符串_打印 (&str, "%s:%c",取_单词字符串(sym->v, NULL),sym_bind == STB_GLOBAL ? 'G' : 局部_范围 ? 'V' : 'S');
zhi_获取_调试_信息(状态机1, sym, &str);
如果 (sym_bind == STB_GLOBAL)
zhi_调试_stabs(状态机1, str.指向字符串的指针, N_GSYM, 0, NULL, 0);
否则
zhi_调试_stabs(状态机1, str.指向字符串的指针,(sym->type.t & VT_静态) && 初始化数据_部分 == s? N_STSYM : N_LCSYM, 0, s, sym->c);
动态字符串_释放 (&str);
}
/* 放置翻译单位信息的末尾 */
静态_函数 无类型 zhi_结束_调试(知心状态机 *状态机1)
{
如果 (!状态机1->执行_调试)
返回;
处理_单词表_r(状态机1, NULL, N_SO, 0, 0,生成代码_段->数据_偏移, 生成代码_段, 段_符号);
内存_释放(调试_哈希);
}
静态 缓冲文件* 用_新_文件(知心状态机 *状态机1)
{
缓冲文件 *f = file;
/* 如果从内联“:asm:”使用较高的文件 */
如果 (f->文件名[0] == ':')
f = f->prev;
如果 (f && 新_文件)
{
处理_单词表_r(状态机1, f->文件名, N_SOL, 0, 0, 输出代码索引, 生成代码_段, 段_符号);
新_文件 = 最后_行_号 = 0;
}
返回 f;
}
/* 生成行号信息 */
静态_函数 无类型 zhi_调试_行(知心状态机 *状态机1)
{
缓冲文件 *f;
如果 (!状态机1->执行_调试|| 当前_生成代码_段 != 生成代码_段|| !(f = 用_新_文件(状态机1))|| 最后_行_号 == f->line_num)
返回;
如果 (func_ind != -1)
{
处理_单词表整数(状态机1, N_SLINE, 0, f->line_num, 输出代码索引 - func_ind);
} 否则
{
/* 来自zhi_assemble */
处理_单词表_r(状态机1, NULL, N_SLINE, 0, f->line_num, 输出代码索引, 生成代码_段, 段_符号);
}
最后_行_号 = f->line_num;
}
/* 放置函数标识符 */
静态_函数 无类型 zhi_调试_函数开始(知心状态机 *状态机1, 符号 *sym)
{
动态字符串 debug_str;
缓冲文件 *f;
如果 (!状态机1->执行_调试)
返回;
调试_信息_根 = NULL;
调试_信息 = NULL;
zhi_调试_stabn(N_LBRAC, 输出代码索引 - func_ind);
如果 (!(f = 用_新_文件(状态机1)))
返回;
动态字符串_初始化 (&debug_str);
动态字符串_打印(&debug_str, "%s:%c", 函数名称, sym->type.t & VT_静态 ? 'f' : 'F');
zhi_获取_调试_信息(状态机1, sym->type.ref, &debug_str);
处理_单词表_r(状态机1, debug_str.指向字符串的指针, N_FUN, 0, f->line_num, 0, 当前_生成代码_段, sym->c);
动态字符串_释放 (&debug_str);
zhi_调试_行(状态机1);
}
/* 放置函数大小 */
静态_函数 无类型 zhi_调试_函数结束(知心状态机 *状态机1, 整数型 size)
{
如果 (!状态机1->执行_调试)
返回;
zhi_调试_stabn(N_RBRAC, size);
zhi_调试_完成 (状态机1, 调试_信息_根);
}
/* 放置备用文件名 */
静态_函数 无类型 zhi_调试_备用文件(知心状态机 *状态机1, 常量 字符型 *文件名)
{
如果 (0 == strcmp(file->文件名, 文件名))
返回;
p字符串复制(file->文件名, 取大小(file->文件名), 文件名);
新_文件 = 1;
}
/* #include的开头 */
静态_函数 无类型 zhi_调试_导入文件的开头(知心状态机 *状态机1)
{
如果 (!状态机1->执行_调试)
返回;
处理_单词表字符串(状态机1, file->文件名, N_BINCL, 0, 0, 0);
新_文件 = 1;
}
/* #include的结尾 */
静态_函数 无类型 zhi_调试_导入文件的结尾(知心状态机 *状态机1)
{
如果 (!状态机1->执行_调试)
返回;
处理_单词表整数(状态机1, N_EINCL, 0, 0, 0);
新_文件 = 1;
}
/* ------------------------------------------------------------------------- */
/* 初始化堆栈值和类型。 对于zhi -E也必须这样做 */
静态_函数 无类型 zhi语法_初始化(知心状态机 *状态机1)
{
栈顶值 = 宏堆栈值 - 1;
memset(栈顶值, 0, 取大小 *栈顶值);
/* 定义一些常用的类型 */
int_type.t = VT_整数;
字符_指针_类型.t = VT_字节;
修改类型_指针类型(&字符_指针_类型);
函数_旧_类型.t = VT_函数;
函数_旧_类型.ref = 符号_压入栈(符号_字段, &int_type, 0, 0);
函数_旧_类型.ref->f.函数_调用 = 函数_CDECL;
函数_旧_类型.ref->f.func_type = 函数_旧;
#如果已定义 优先级_解析器
初始化_优先权();
#结束如果
动态字符串_初始化(&初始字符串);
}
静态_函数 整数型 zhi语法_编译(知心状态机 *状态机1)
{
当前_生成代码_段 = NULL;
函数名称 = "";
匿名符号索引 = 符号_第一个_匿名;
段_符号 = 0;
需要_常量 = 0;
不需要_代码生成 = 0x80000000;
局部_范围 = 0;
zhi_调试_开始(状态机1);
#如果已定义 ZHI_TARGET_ARM
arm_初始化(状态机1);
#结束如果
#如果已定义 导入文件_调试
printf("%s: **** 新建文件\n", file->文件名);
#结束如果
解析_标记 = 解析_标记_预处理 | 解析_标记_标识符_数字 | 解析_标记_单词字符串;
带有宏替换的下个标记();
声明(VT_VC常量);
生成_内联函数(状态机1);
检查_堆栈值();
/* 翻译单元信息结尾 */
zhi_结束_调试(状态机1);
返回 0;
}
静态_函数 无类型 zhi语法_完成(知心状态机 *状态机1)
{
动态字符串_释放(&初始字符串);
释放_内联函数(状态机1);
符号_弹出(&全局符号_堆栈, NULL, 0);
符号_弹出(&局部符号_堆栈, NULL, 0);
/* 释放预处理器宏 */
释放_宏定义堆栈(NULL);
/* 释放sym_pools */
动态数组_重分配容量(&符号_池, &数量_符号_池);
符号_释放_第一 = NULL;
}
/* ------------------------------------------------------------------------- */
静态_函数 ELF符号 *elf符号(符号 *s)
{
如果 (!s || !s->c)
返回 NULL;
返回 &((ELF符号 *)单词表_部分->data)[s->c];
}
/* 将存储属性应用于Elf符号 */
静态_函数 无类型 更新_存储(符号 *sym)
{
ELF符号 *esym;
整数型 sym_bind, old_sym_bind;
esym = elf符号(sym);
如果 (!esym)
返回;
如果 (sym->a.visibility)
esym->st_other = (esym->st_other & ~ELFW(ST_VISIBILITY)(-1))| sym->a.visibility;
如果 (sym->type.t & (VT_静态 | VT_内联))
sym_bind = STB_LOCAL;
否则 如果 (sym->a.weak)
sym_bind = STB_WEAK;
否则
sym_bind = STB_GLOBAL;
old_sym_bind = ELFW(ST_BIND)(esym->st_info);
如果 (sym_bind != old_sym_bind)
{
esym->st_info = ELFW(ST_INFO)(sym_bind, ELFW(ST_TYPE)(esym->st_info));
}
#如果已定义 ZHI_TARGET_PE
如果 (sym->a.dllimport)
esym->st_other |= ST_PE_IMPORT;
如果 (sym->a.dllexport)
esym->st_other |= ST_PE_EXPORT;
#结束如果
#如果 0
printf("存储 %s: bind=%c vis=%d exp=%d imp=%d\n",取_单词字符串(sym->v, NULL),sym_bind == STB_WEAK ? 'w' : sym_bind == STB_LOCAL ? 'l' : 'g',sym->a.visibility,sym->a.dllexport,sym->a.dllimport);
#结束如果
}
/* ------------------------------------------------------------------------- */
/* 更新sym-> c,使其指向“ section”部分中的值为“ value”的外部符号 */
静态_函数 无类型 更新_外部_符号2(符号 *sym, 整数型 sh_num,目标地址_类型 value, 无符号 long size,整数型 can_add_underscore)
{
整数型 sym_type, sym_bind, info, other, t;
ELF符号 *esym;
常量 字符型 *name;
字符型 buf1[256];
#如果已定义 配置_ZHI_边界检查
字符型 buf[32];
#结束如果
如果 (!sym->c)
{
name = 取_单词字符串(sym->v, NULL);
#如果已定义 配置_ZHI_边界检查
如果 (zhi_状态->执行_边界_检查器)
{
/* XXX: 避免这样做的静态? */
/* 如果**了边界检查,我们将通过添加“ __bound”前缀来更改某些函数名称 */
#如果 已定义(ZHI_TARGET_ARM) && 已定义(ZHI_ARM_EABI)
如果 (strcmp (name, "memcpy") == 0 ||strcmp (name, "memmove") == 0 ||strcmp (name, "memset") == 0)
去向 add_bound;
#结束如果
选择(sym->v)
{
#如果已定义 ZHI_TARGET_PE
/* XXX: 我们仅依赖于malloc钩子 */
分支 符_malloc:
分支 符_free:
分支 符_realloc:
分支 符_memalign:
分支 符_calloc:
#结束如果
分支 符_memcpy:
分支 符_memmove:
#如果 已定义(ZHI_TARGET_ARM) && 已定义(ZHI_ARM_EABI)
分支 符_memmove4:
分支 符_memmove8:
#结束如果
分支 符_memset:
分支 符_memcmp:
分支 符_strlen:
分支 符_strcpy:
分支 符_strncpy:
分支 符_strcmp:
分支 符_strncmp:
分支 符_strcat:
分支 符_strchr:
分支 符_strdup:
#如果 已定义 ZHI_TARGET_I386 || 已定义 ZHI_TARGET_X86_64
分支 符_alloca:
#结束如果
分支 符_mmap:
分支 符_munmap:
分支 符_longjmp:
#如果未定义 ZHI_TARGET_PE
分支 符_siglongjmp:
#结束如果
#如果 已定义(ZHI_TARGET_ARM) && 已定义(ZHI_ARM_EABI)
add_bound:
#结束如果
strcpy(buf, "__bound_");
strcat(buf, name);
name = buf;
跳出;
}
}
#结束如果
t = sym->type.t;
如果 ((t & VT_基本类型) == VT_函数)
{
sym_type = STT_FUNC;
} 否则 如果 ((t & VT_基本类型) == VT_无类型)
{
sym_type = STT_NOTYPE;
} 否则
{
sym_type = STT_OBJECT;
}
如果 (t & (VT_静态 | VT_内联))
sym_bind = STB_LOCAL;
否则
sym_bind = STB_GLOBAL;
other = 0;
#如果已定义 ZHI_TARGET_PE
如果 (sym_type == STT_FUNC && sym->type.ref)
{
符号 *ref = sym->type.ref;
如果 (ref->a.nodecorate)
{
can_add_underscore = 0;
}
如果 (ref->f.函数_调用 == 函数_标准调用 && can_add_underscore)
{
sprintf(buf1, "_%[email protected]%d", name, ref->f.func_args * 指针_大小);
name = buf1;
other |= ST_PE_标准调用;
can_add_underscore = 0;
}
}
#结束如果
如果 (zhi_状态->前导_下划线 && can_add_underscore)
{
buf1[0] = '_';
p字符串复制(buf1 + 1, 取大小(buf1) - 1, name);
name = buf1;
}
如果 (sym->汇编_label)
name = 取_单词字符串(sym->汇编_label, NULL);
info = ELFW(ST_INFO)(sym_bind, sym_type);
sym->c = 处理_elf_符号(单词表_部分, value, size, info, other, sh_num, name);
如果 (zhi_状态->执行_调试 && sym_type != STT_FUNC && sym->v < 符号_第一个_匿名)
zhi_调试_外部_符号(zhi_状态, sym, sh_num, sym_bind);
} 否则 {
esym = elf符号(sym);
esym->st_value = value;
esym->st_size = size;
esym->st_shndx = sh_num;
}
更新_存储(sym);
}
静态_函数 无类型 更新_外部_符号(符号 *sym, 段 *section,目标地址_类型 value, 无符号 long size)
{
整数型 sh_num = section ? section->sh_num : SHN_UNDEF;
更新_外部_符号2(sym, sh_num, value, size, 1);
}
/* 在“ s”部分的符号“ sym”中添加新的重定位项*/
静态_函数 无类型 添加新的重定位项(段 *s, 符号 *sym, 无符号 long offset, 整数型 type,目标地址_类型 addend)
{
整数型 c = 0;
如果 (不需要_代码生成 && s == 当前_生成代码_段)
返回;
如果 (sym)
{
如果 (0 == sym->c)
更新_外部_符号(sym, NULL, 0, 0);
c = sym->c;
}
/* 现在我们可以添加ELF重定位信息*/
使_elf_重定位目标地址(单词表_部分, s, offset, type, c, addend);
}
#如果 指针_大小 == 4
静态_函数 无类型 段部分符号重定位(段 *s, 符号 *sym, 无符号 long offset, 整数型 type)
{
添加新的重定位项(s, sym, offset, type, 0);
}
#结束如果
/* ------------------------------------------------------------------------- */
/* 符号分配器 */
静态 符号 *__符号_分配器(无类型)
{
符号 *sym_pool, *sym, *last_sym;
整数型 i;
sym_pool = 内存_申请(符号_池_NB * 取大小(符号));
动态数组_追加元素(&符号_池, &数量_符号_池, sym_pool);
last_sym = 符号_释放_第一;
sym = sym_pool;
循环(i = 0; i < 符号_池_NB; i++) {
sym->next = last_sym;
last_sym = sym;
sym++;
}
符号_释放_第一 = last_sym;
返回 last_sym;
}
静态 内联 符号 *符号_分配内存(无类型)
{
符号 *sym;
#如果未定义 SYM_DEBUG
sym = 符号_释放_第一;
如果 (!sym)
sym = __符号_分配器();
符号_释放_第一 = sym->next;
返回 sym;
#否则
sym = 内存_申请(取大小(符号));
返回 sym;
#结束如果
}
静态_内联 无类型 符号_释放(符号 *sym)
{
#如果未定义 SYM_DEBUG
sym->next = 符号_释放_第一;
符号_释放_第一 = sym;
#否则
内存_释放(sym);
#结束如果
}
/* 推送,不散列 */
静态_函数 符号 *符号_推送2(符号 **ps, 整数型 v, 整数型 t, 整数型 c)
{
符号 *s;
s = 符号_分配内存();
memset(s, 0, 取大小 *s);
s->v = v;
s->type.t = t;
s->c = c;
/* 加入堆栈 */
s->prev = *ps;
*ps = s;
返回 s;
}
/* 找到一个符号并返回其关联的结构。 's'是符号堆栈的顶部*/
静态_函数 符号 *符号_查找2(符号 *s, 整数型 v)
{
判断 (s)
{
如果 (s->v == v)
返回 s;
否则 如果 (s->v == -1)
返回 NULL;
s = s->prev;
}
返回 NULL;
}
/* 结构查询 */
静态_内联 符号 *结构体_查询(整数型 v)
{
v -= 符_识别;
如果 ((无符号)v >= (无符号)(单词_识别号 - 符_识别))
返回 NULL;
返回 单词表[v]->sym_struct;
}
/* 找到一个标识符 */
静态_内联 符号 *符号_查询(整数型 v)
{
v -= 符_识别;
如果 ((无符号)v >= (无符号)(单词_识别号 - 符_识别))
返回 NULL;
返回 单词表[v]->sym_identifier;
}
静态 整数型 符号_范围(符号 *s)
{
如果 (是_枚举_变长 (s->type.t))
返回 s->type.ref->符号_范围;
否则
返回 s->符号_范围;
}
/* 将给定的符号压入符号堆栈.用于在本地符号堆栈中添加新符号。如果没有本地符号堆栈处于活动状态,则将其添加到全局符号堆栈中。 */
静态_函数 符号 *符号_压入栈(整数型 v, C类型 *type, 整数型 r, 整数型 c)
{
符号 *s, **ps;
单词存储结构 *ts;
如果 (局部符号_堆栈)
ps = &局部符号_堆栈;
否则
ps = &全局符号_堆栈;
s = 符号_推送2(ps, v, type->t, c);
s->type.ref = type->ref;
s->r = r;
/* 不要记录字段或匿名符号 */
/* XXX: 简化 */
如果 (!(v & 符号_字段) && (v & ~符号_结构体) < 符号_第一个_匿名)
{
/* 在标识符数组中记录符号 */
ts = 单词表[(v & ~符号_结构体) - 符_识别];
如果 (v & 符号_结构体)
ps = &ts->sym_struct;
否则
ps = &ts->sym_identifier;
s->prev_tok = *ps;
*ps = s;
s->符号_范围 = 局部_范围;
如果 (s->prev_tok && 符号_范围(s->prev_tok) == s->符号_范围)
错误_打印("重新声明 '%s'",
取_单词字符串(v & ~符号_结构体, NULL));
}
返回 s;
}
/* 推送一个全局标识符 */
静态_函数 符号 *推送_一个_全局标识符(整数型 v, 整数型 t, 整数型 c)
{
符号 *s, **ps;
s = 符号_推送2(&全局符号_堆栈, v, t, c);
s->r = VT_VC常量 | VT_符号;
/* 不要记录匿名符号 */
如果 (v < 符号_第一个_匿名)
{
ps = &单词表[v - 符_识别]->sym_identifier;
/* 修改最上面的本地标识符,以使sym_identifier弹出时指向“ s”; 从内联asm调用时发生 */
判断 (*ps != NULL && (*ps)->符号_范围)
ps = &(*ps)->prev_tok;
s->prev_tok = *ps;
*ps = s;
}
返回 s;
}
/* 弹出符号,直到顶部达到“ b”。 如果KEEP不为零,则不要从列表中真正弹出它们,但要从令牌数组中删除它们。 */
静态_函数 无类型 符号_弹出(符号 **ptop, 符号 *b, 整数型 keep)
{
符号 *s, *ss, **ps;
单词存储结构 *ts;
整数型 v;
s = *ptop;
判断(s != b) {
ss = s->prev;
v = s->v;
/* 删除标识符数组中的符号 */
/* XXX: 简化 */
如果 (!(v & 符号_字段) && (v & ~符号_结构体) < 符号_第一个_匿名) {
ts = 单词表[(v & ~符号_结构体) - 符_识别];
如果 (v & 符号_结构体)
ps = &ts->sym_struct;
否则
ps = &ts->sym_identifier;
*ps = s->prev_tok;
}
如果 (!keep)
符号_释放(s);
s = ss;
}
如果 (!keep)
*ptop = b;
}
/* ------------------------------------------------------------------------- */
静态 无类型 vcheck_cmp(无类型)
{
/*如果生成其他指令,则不能让cpu标志。 还要避免将VT_JMP放在堆栈顶部以外的任何位置,因为这会使代码生成器复杂化。 nocode_wanted时不要执行此操作。 vtop可能来自!nocode_wanted区域(请参见88_codeopt.c),并将其转换为寄存器而没有实际生成代码是错误的,因为它们的值可能仍用于实数。 我们在nocode_wanted下推送的所有值最终将再次弹出,因此当再次取消压缩代码时,VT_CMP / VT_JMP值将位于vtop中。 */
如果 (栈顶值->r == VT_CMP && !不需要_代码生成)
将rc寄存器值存储在栈顶值中(寄存器类_整数);
}
/*vsetc()并vset()推动价值堆栈上的新的价值。如果先前的vtop存储在非常不安全的位置(例如,在CPU标志中),则会生成一些代码以将先前的vtop放入安全存储中。*/
静态 无类型 vsetc(C类型 *type, 整数型 r, 恒定值 *vc)
{
如果 (栈顶值 >= 宏堆栈值 + (堆栈值_大小 - 1))
错误_打印("内存已满 (宏堆栈值)");
vcheck_cmp();
栈顶值++;
栈顶值->type = *type;
栈顶值->r = r;
栈顶值->r2 = VT_VC常量;
栈顶值->c = *vc;
栈顶值->sym = NULL;
}
静态_函数 无类型 vswap(无类型)
{
堆栈值 tmp;
vcheck_cmp();
tmp = 栈顶值[0];
栈顶值[0] = 栈顶值[-1];
栈顶值[-1] = tmp;
}
/* 弹出堆栈值。在某些情况下,它还会生成清除代码(例如,如果在x86上使用堆叠的浮点寄存器)。 */
静态_函数 无类型 弹出堆栈值(无类型)
{
整数型 v;
v = 栈顶值->r & VT_值掩码;
#如果 已定义(ZHI_TARGET_I386) || 已定义(ZHI_TARGET_X86_64)
/* 对于x86,我们需要弹出FP堆栈 */
如果 (v == TREG_ST0)
{
o(0xd8dd); /* fstp %st(0) */
} 否则
#结束如果
如果 (v == VT_CMP)
{
/* 如果&&或||,则需要进行正确的跳转 未经测试 */
生成符号(栈顶值->jtrue);
生成符号(栈顶值->jfalse);
}
栈顶值--;
}
/* 推入类型“ type”的常量,该数组的值无用 */
静态 无类型 压入指定类型常量(C类型 *type)
{
vset(type, VT_VC常量, 0);
}
/* 推送任意64位常量 */
静态 无类型 压入64位常量(整数型 ty, 无符号 long long v)
{
恒定值 cval;
C类型 ctype;
ctype.t = ty;
ctype.ref = NULL;
cval.i = v;
vsetc(&ctype, VT_VC常量, &cval);
}
/* 推整数常量 */
静态_函数 无类型 压入整数常量(整数型 v)
{
压入64位常量(VT_整数, v);
}
/* 推动指针大小的常量 */
静态 无类型 压入目标地址类型常量(目标地址_类型 v)
{
压入64位常量(VT_SIZE_T, v);
}
/* 推动长久不变 */
静态 内联 无类型 压入长长整数(long long v)
{
压入64位常量(VT_长长整数, v);
}
静态_函数 无类型 vset(C类型 *type, 整数型 r, 整数型 v)
{
恒定值 cval;
cval.i = v;
vsetc(type, r, &cval);
}
静态 无类型 vseti(整数型 r, 整数型 v)
{
C类型 type;
type.t = VT_整数;
type.ref = NULL;
vset(&type, r, v);
}
静态_函数 无类型 vpushv(堆栈值 *v)
{
如果 (栈顶值 >= 宏堆栈值 + (堆栈值_大小 - 1))
错误_打印("内存已满 (宏堆栈值)");
栈顶值++;
*栈顶值 = *v;
}
静态 无类型 vdup(无类型)
{
vpushv(栈顶值);
}
/* 将n个第一个堆栈元素旋转到底部I1 ... ...-> I2 ...在I1中[顶部右]*/
静态_函数 无类型 vrotb(整数型 n)
{
整数型 i;
堆栈值 tmp;
vcheck_cmp();
tmp = 栈顶值[-n + 1];
循环(i=-n+1;i!=0;i++)
栈顶值[i] = 栈顶值[i+1];
栈顶值[0] = tmp;
}
/* 将条目e之前的n个元素旋转到顶部I1 ... In ...->在I1 ... I(n-1)... [顶部右]*/
静态_函数 无类型 vrote(堆栈值 *e, 整数型 n)
{
整数型 i;
堆栈值 tmp;
vcheck_cmp();
tmp = *e;
循环(i = 0;i < n - 1; i++)
e[-i] = e[-i - 1];
e[-n + 1] = tmp;
}
/* 将n个第一个堆栈元素旋转到顶部I1 ...在->在I1 ... I(n-1)中[顶部在右边]*/
静态_函数 无类型 vrott(整数型 n)
{
vrote(栈顶值, n);
}
/* ------------------------------------------------------------------------- */
/* 栈顶值-> r = VT_CMP表示已通过比较或测试设置了CPU标志。 */
/* 从生成器调用以设置关系操作的结果 */
静态_函数 无类型 vset_VT_CMP(整数型 op)
{
栈顶值->r = VT_CMP;
栈顶值->cmp_op = op;
栈顶值->jfalse = 0;
栈顶值->jtrue = 0;
}
/* 在要求生成器将VT_CMP加载到寄存器之前被调用一次 */
静态 无类型 vset_VT_JMP(无类型)
{
整数型 op = 栈顶值->cmp_op;
如果 (栈顶值->jtrue || 栈顶值->jfalse)
{
/* 我们需要跳转到'mov $ 0,%R'或'mov $ 1,%R' */
整数型 inv = op & (op < 2); /* 小优化 */
vseti(VT_JMP+inv, 生成值测试(inv, 0));
} 否则 {
/* 否则将标志(rsp。0/1)转换为寄存器 */
栈顶值->c.i = op;
如果 (op < 2) /* 似乎没有发生 */
栈顶值->r = VT_VC常量;
}
}
/* 设置CPU标志,尚未跳转 */
静态 无类型 gvtst_set(整数型 inv, 整数型 t)
{
整数型 *p;
如果 (栈顶值->r != VT_CMP)
{
压入整数常量(0);
通用_操作(双符号_不等于);
如果 (栈顶值->r != VT_CMP) /* 必须是VT_VC常量 */
vset_VT_CMP(栈顶值->c.i != 0);
}
p = inv ? &栈顶值->jfalse : &栈顶值->jtrue;
*p = g跳转_附件(*p, t);
}
/* 产生价值测试。生成任何值的测试(跳转,比较和整数) */
静态 整数型 生成值测试(整数型 inv, 整数型 t)
{
整数型 op, x, u;
gvtst_set(inv, t);
t = 栈顶值->jtrue, u = 栈顶值->jfalse;
如果 (inv)
x = u, u = t, t = x;
op = 栈顶值->cmp_op;
/* 跳到想要的目标 */
如果 (op > 1)
t = g跳转_条件(op ^ inv, t);
否则 如果 (op != inv)
t = 生成跳转到标签(t);
/* 解决互补跳到这里 */
生成符号(u);
栈顶值--;
返回 t;
}
/* 生成零或非零测试 */
静态 无类型 生成_测试_零(整数型 op)
{
如果 (栈顶值->r == VT_CMP)
{
整数型 j;
如果 (op == 双符号_等于)
{
j = 栈顶值->jfalse;
栈顶值->jfalse = 栈顶值->jtrue;
栈顶值->jtrue = j;
栈顶值->cmp_op ^= 1;
}
} 否则 {
压入整数常量(0);
通用_操作(op);
}
}
/* ------------------------------------------------------------------------- */
/* 推送TYPE的符号值 */
静态 内联 无类型 压入符号值(C类型 *type, 符号 *sym)
{
恒定值 cval;
cval.i = 0;
vsetc(type, VT_VC常量 | VT_符号, &cval);
栈顶值->sym = sym;
}
/* 返回指向某节的静态符号 */
静态_函数 符号 *返回_指向节的_静态符号(C类型 *type, 段 *sec, 无符号 long offset, 无符号 long size)
{
整数型 v;
符号 *sym;
v = 匿名符号索引++;
sym = 符号_压入栈(v, type, VT_VC常量 | VT_符号, 0);
sym->type.t |= VT_静态;
更新_外部_符号(sym, sec, offset, size);
返回 sym;
}
/* 通过添加虚拟符号将引用推送到节偏移量 */
静态 无类型 将引用_推送到_节偏移量(C类型 *type, 段 *sec, 无符号 long offset, 无符号 long size)
{
压入符号值(type, 返回_指向节的_静态符号(type, sec, offset, size));
}
/* 定义对类型为“ u”的符号“ v”的新外部引用 */
静态_函数 符号 *外部_全局_符号(整数型 v, C类型 *type)
{
符号 *s;
s = 符号_查询(v);
如果 (!s)
{
/* 推动参考 */
s = 推送_一个_全局标识符(v, type->t | VT_外部, 0);
s->type.ref = type->ref;
} 否则 如果 (是_汇编_符号(s))
{
s->type.t = type->t | (s->type.t & VT_外部);
s->type.ref = type->ref;
更新_存储(s);
}
返回 s;
}
/* 合并符号属性。 */
静态 无类型 合并_符号属性(结构体 符号属性 *sa, 结构体 符号属性 *sa1)
{
如果 (sa1->aligned && !sa->aligned)
sa->aligned = sa1->aligned;
sa->packed |= sa1->packed;
sa->weak |= sa1->weak;
如果 (sa1->visibility != STV_DEFAULT)
{
整数型 vis = sa->visibility;
如果 (vis == STV_DEFAULT|| vis > sa1->visibility)
vis = sa1->visibility;
sa->visibility = vis;
}
sa->dllexport |= sa1->dllexport;
sa->nodecorate |= sa1->nodecorate;
sa->dllimport |= sa1->dllimport;
}
/* 合并功能属性。 */
静态 无类型 合并_函数属性(结构体 函数属性 *fa, 结构体 函数属性 *fa1)
{
如果 (fa1->函数_调用 && !fa->函数_调用)
fa->函数_调用 = fa1->函数_调用;
如果 (fa1->func_type && !fa->func_type)
fa->func_type = fa1->func_type;
如果 (fa1->func_args && !fa->func_args)
fa->func_args = fa1->func_args;
如果 (fa1->func_noreturn)
fa->func_noreturn = 1;
如果 (fa1->func_ctor)
fa->func_ctor = 1;
如果 (fa1->func_dtor)
fa->func_dtor = 1;
}
/* 合并属性。 */
静态 无类型 合并_属性(属性定义 *ad, 属性定义 *ad1)
{
合并_符号属性(&ad->a, &ad1->a);
合并_函数属性(&ad->f, &ad1->f);
如果 (ad1->section)
ad->section = ad1->section;
如果 (ad1->alias_target)
ad->alias_target = ad1->alias_target;
如果 (ad1->汇编_label)
ad->汇编_label = ad1->汇编_label;
如果 (ad1->attr_mode)
ad->attr_mode = ad1->attr_mode;
}
/* 合并一些类型属性。 */
静态 无类型 合并_其他类型属性(符号 *sym, C类型 *type)
{
如果 (!(type->t & VT_外部) || 是_枚举_变长(sym->type.t))
{
如果 (!(sym->type.t & VT_外部))
错误_打印("重新定义 '%s'", 取_单词字符串(sym->v, NULL));
sym->type.t &= ~VT_外部;
}
如果 (是_汇编_符号(sym))
{
/* 如果两者都是静态的,则保持静态 */
sym->type.t = type->t & (sym->type.t | ~VT_静态);
sym->type.ref = type->ref;
}
如果 (!是_兼容_类型(&sym->type, type)) {
错误_打印("重新定义 '%s'的类型不兼容",
取_单词字符串(sym->v, NULL));
} 否则 如果 ((sym->type.t & VT_基本类型) == VT_函数)
{
整数型 static_proto = sym->type.t & VT_静态;
/* 警告如果静态遵循非静态函数声明 */
/* XXX 内联测试不应该在这里。 在我们再次实现gnu-inline模式之前,它会静默由我们的解决方法引起的有关mingw的警告。 */
如果 ((type->t & VT_静态) && !static_proto && !((type->t | sym->type.t) & VT_内联))
zhi_警告("静态存储被忽略以重新定义 '%s'",取_单词字符串(sym->v, NULL));
/* 如果双方都同意或者一个人静态,则设置“ 内联” */
如果 ((type->t | sym->type.t) & VT_内联)
{
如果 (!((type->t ^ sym->type.t) & VT_内联)|| ((type->t | sym->type.t) & VT_静态))
static_proto |= VT_内联;
}
如果 (0 == (type->t & VT_外部))
{
结构体 函数属性 f = sym->type.ref->f;
/* 放置完整类型,使用原型中的静态 */
sym->type.t = (type->t & ~(VT_静态|VT_内联)) | static_proto;
sym->type.ref = type->ref;
合并_函数属性(&sym->type.ref->f, &f);
} 否则
{
sym->type.t &= ~VT_内联 | static_proto;
}
如果 (sym->type.ref->f.func_type == 函数_旧 && type->ref->f.func_type != 函数_旧)
{
sym->type.ref = type->ref;
}
} 否则
{
如果 ((sym->type.t & VT_数组) && type->ref->c >= 0)
{
/* 设置数组大小(如果在外部声明中省略) */
sym->type.ref->c = type->ref->c;
}
如果 ((type->t ^ sym->type.t) & VT_静态)
zhi_警告("存储不匹配以重新定义 '%s'",取_单词字符串(sym->v, NULL));
}
}
/* 合并一些存储属性. */
静态 无类型 合并_其他存储属性(符号 *sym, 属性定义 *ad, C类型 *type)
{
如果 (type)
合并_其他类型属性(sym, type);
#如果已定义 ZHI_TARGET_PE
如果 (sym->a.dllimport != ad->a.dllimport)
错误_打印("不兼容的DLL链接,用于重新定义 '%s'",取_单词字符串(sym->v, NULL));
#结束如果
合并_符号属性(&sym->a, &ad->a);
如果 (ad->汇编_label)
sym->汇编_label = ad->汇编_label;
更新_存储(sym);
}
/* 将sym复制到其他堆栈 */
静态 符号 *复制符号_到其他堆栈(符号 *s0, 符号 **ps)
{
符号 *s;
s = 符号_分配内存(), *s = *s0;
s->prev = *ps, *ps = s;
如果 (s->v < 符号_第一个_匿名)
{
ps = &单词表[s->v - 符_识别]->sym_identifier;
s->prev_tok = *ps, *ps = s;
}
返回 s;
}
/* 将s-> type.ref复制到VT_FUNC和VT_指针的堆栈``ps'' */
静态 无类型 将ref_复制到_堆栈ps(符号 *s, 符号 **ps)
{
整数型 bt = s->type.t & VT_基本类型;
如果 (bt == VT_函数 || bt == VT_指针)
{
符号 **sp = &s->type.ref;
循环 (s = *sp, *sp = NULL; s; s = s->next)
{
符号 *s2 = 复制符号_到其他堆栈(s, ps);
sp = &(*sp = s2)->next;
将ref_复制到_堆栈ps(s2, ps);
}
}
}
/* 定义对符号“ v”的新外部引用*/
静态 符号 *定义外部引用_符号(整数型 v, C类型 *type, 整数型 r, 属性定义 *ad)
{
符号 *s;
/* 寻找全球象征 */
s = 符号_查询(v);
判断 (s && s->符号_范围)
s = s->prev_tok;
如果 (!s)
{
/* 推动参考 */
s = 推送_一个_全局标识符(v, type->t, 0);
s->r |= r;
s->a = ad->a;
s->汇编_label = ad->汇编_label;
s->type.ref = type->ref;
/* 复制类型到全局堆栈 */
如果 (局部符号_堆栈)
将ref_复制到_堆栈ps(s, &全局符号_堆栈);
} 否则
{
合并_其他存储属性(s, ad, type);
}
/* 将变量推送到local_stack上(如果有) */
如果 (局部符号_堆栈 && (s->type.t & VT_基本类型) != VT_函数)
s = 复制符号_到其他堆栈(s, &局部符号_堆栈);
返回 s;
}
/* 推送对全局符号v的引用 */
静态_函数 无类型 推送对_全局符号V_的引用(C类型 *type, 整数型 v)
{
压入符号值(type, 外部_全局_符号(v, type));
}
/* 保存寄存器最多(栈顶值-n)个堆栈条目 */
静态_函数 无类型 保存_寄存器最多n个堆栈条目(整数型 n)
{
堆栈值 *p, *p1;
循环(p = 宏堆栈值, p1 = 栈顶值 - n; p <= p1; p++)
将r保存到_内存堆栈(p->r);
}
/* 将r保存到内存堆栈,并将其标记为空闲 */
静态_函数 无类型 将r保存到_内存堆栈(整数型 r)
{
将r保存到_内存堆栈_最多n个条目(r, 0);
}
/* 将r保存到内存堆栈中,并将其标记为空闲(如果最多可以看到(栈顶值-n)堆栈条目) */
静态_函数 无类型 将r保存到_内存堆栈_最多n个条目(整数型 r, 整数型 n)
{
整数型 l, size, align, bt;
堆栈值 *p, *p1, sv;
如果 ((r &= VT_值掩码) >= VT_VC常量)
返回;
如果 (不需要_代码生成)
返回;
l = 0;
循环(p = 宏堆栈值, p1 = 栈顶值 - n; p <= p1; p++)
{
如果 ((p->r & VT_值掩码) == r || p->r2 == r)
{
/* 如果尚未完成,必须将价值保存在堆栈中 */
如果 (!l)
{
bt = p->type.t & VT_基本类型;
如果 (bt == VT_无类型)
继续;
如果 ((p->r & VT_LVAL) || bt == VT_函数)
bt = VT_指针;
sv.type.t = bt;
size = 类型_大小(&sv.type, &align);
l = 获取_临时_局部_变量(size,align);
sv.r = VT_LOCAL | VT_LVAL;
sv.c.i = l;
存储(p->r & VT_值掩码, &sv);
#如果 已定义(ZHI_TARGET_I386) || 已定义(ZHI_TARGET_X86_64)
/* x86特定:如果保存,则需要弹出fp寄存器ST0 */
如果 (r == TREG_ST0)
{
o(0xd8dd); /* fstp %st(0) */
}
#结束如果
/* special long long 分支 */
如果 (p->r2 < VT_VC常量 && 使用_两个单词的_类型(bt))
{
sv.c.i += 指针_大小;
存储(p->r2, &sv);
}
}
/* 将该堆栈条目标记为已保存在堆栈中 */
如果 (p->r & VT_LVAL) {
/* 还清除边界标记,因为函数的重定位地址存储在p-> c.i中 */
p->r = (p->r & ~(VT_值掩码 | VT_有界的)) | VT_LLOCAL;
} 否则
{
p->r = VT_LVAL | VT_LOCAL;
}
p->r2 = VT_VC常量;
p->c.i = l;
}
}
}
#如果已定义 ZHI_TARGET_ARM
/* 在堆栈上找到最多包含一个引用的类“ rc2”的寄存器。* 如果不存在,请调用get_reg(rc) */
静态_函数 整数型 查找rc2寄存器_如果不存在就调用rc(整数型 rc, 整数型 rc2)
{
整数型 r;
堆栈值 *p;
循环(r=0;r<可用_寄存器数;r++)
{
如果 (寄存器_类数[r] & rc2)
{
整数型 n;
n=0;
循环(p = 宏堆栈值; p <= 栈顶值; p++)
{
如果 ((p->r & VT_值掩码) == r ||p->r2 == r)
n++;
}
如果 (n <= 1)
返回 r;
}
}
返回 查找释放的rc寄存器_如果不存在就保存一个寄存器(rc);
}
#结束如果
/*查找免费的类“ rc”的寄存器。 如果不存在,请保存一个寄存器 */
静态_函数 整数型 查找释放的rc寄存器_如果不存在就保存一个寄存器(整数型 rc)
{
整数型 r;
堆栈值 *p;
/* 寻找免费的注册 */
循环(r=0;r<可用_寄存器数;r++)
{
如果 (寄存器_类数[r] & rc)
{
如果 (不需要_代码生成)
返回 r;
循环(p=宏堆栈值;p<=栈顶值;p++)
{
如果 ((p->r & VT_值掩码) == r ||p->r2 == r)
去向 notfound;
}
返回 r;
}
notfound: ;
}
/* 没有剩余的寄存器:释放堆栈中的第一个寄存器(从底部开始非常重要,以确保我们不会溢出生成_opi()中使用的寄存器) */
循环(p=宏堆栈值;p<=栈顶值;p++) {
/* 查看第二个寄存器(如果很长) */
r = p->r2;
如果 (r < VT_VC常量 && (寄存器_类数[r] & rc))
去向 save_found;
r = p->r & VT_值掩码;
如果 (r < VT_VC常量 && (寄存器_类数[r] & rc))
{
save_found:
将r保存到_内存堆栈(r);
返回 r;
}
}
/* 不应该来这里 */
返回 -1;
}
/* 找到一个免费的临时局部变量(返回堆栈上的偏移量)以匹配大小并对齐。 如果不存在,请添加新的临时堆栈变量*/
静态 整数型 获取_临时_局部_变量(整数型 size,整数型 align)
{
整数型 i;
结构体 局部_变量_范围 *temp_var;
整数型 found_var;
堆栈值 *p;
整数型 r;
字符型 free;
字符型 found;
found=0;
循环(i=0;i<数量_局部_变量数_范围;i++)
{
temp_var=&局部_变量_数组[i];
如果(temp_var->size<size||align!=temp_var->align)
{
继续;
}
/*检查temp_var是否空闲*/
free=1;
循环(p=宏堆栈值;p<=栈顶值;p++)
{
r=p->r&VT_值掩码;
如果(r==VT_LOCAL||r==VT_LLOCAL)
{
如果(p->c.i==temp_var->位置)
{
free=0;
跳出;
}
}
}
如果(free)
{
found_var=temp_var->位置;
found=1;
跳出;
}
}
如果(!found)
{
局部变量索引 = (局部变量索引 - size) & -align;
如果(数量_局部_变量数_范围<局部变量_最多个数)
{
temp_var=&局部_变量_数组[i];
temp_var->位置=局部变量索引;
temp_var->size=size;
temp_var->align=align;
数量_局部_变量数_范围++;
}
found_var=局部变量索引;
}
返回 found_var;
}
静态 无类型 清除_临时_局部_变量_列表()
{
数量_局部_变量数_范围=0;
}
/* 将寄存器“ s”(类型为“ t”)移至“ r”,并在需要时将r的先前值刷新到内存中 */
静态 无类型 移动_寄存器(整数型 r, 整数型 s, 整数型 t)
{
堆栈值 sv;
如果 (r != s)
{
将r保存到_内存堆栈(r);
sv.type.t = t;
sv.type.ref = NULL;
sv.r = s;
sv.c.i = 0;
加载(r, &sv);
}
}
/* 获取vtop的地址(vtop必须为左值) */
静态_函数 无类型 获取栈顶值地址(无类型)
{
栈顶值->r &= ~VT_LVAL;
/* tricky: 如果 saved lvalue, then we can go back to lvalue */
如果 ((栈顶值->r & VT_值掩码) == VT_LLOCAL)
栈顶值->r = (栈顶值->r & ~VT_值掩码) | VT_LOCAL | VT_LVAL;
}
#如果已定义 配置_ZHI_边界检查
静态 无类型 生成左值边界代码(无类型)
{
C类型 type1;
栈顶值->r &= ~VT_强制边界检查;
/* 如果 lvalue, then use checking code before dereferencing */
如果 (栈顶值->r & VT_LVAL) {
/* 如果 not VT_有界的 value, then make one */
如果 (!(栈顶值->r & VT_有界的)) {
/* must save type because we must set it to 整数型 to get pointer */
type1 = 栈顶值->type;
栈顶值->type.t = VT_指针;
获取栈顶值地址();
压入整数常量(0);
生成_边界的_ptr_添加();
栈顶值->r |= VT_LVAL;
栈顶值->type = type1;
}
/* then check 循环 dereferencing */
生成_边界的_ptr_取消引用();
}
}
/* we need to call __bound_ptr_add before we start to 加载 function
args into registers */
静态_函数 无类型 生成左值边界代码_函数参数加载到寄存器(整数型 数量_args)
{
整数型 i;
循环 (i = 1; i <= 数量_args; ++i)
如果 (栈顶值[1 - i].r & VT_强制边界检查) {
vrotb(i);
生成左值边界代码();
vrott(i);
}
}
/* 将本地符号的范围从S添加到E(通过-> prev) */
静态 无类型 添加_局部_边界(符号 *s, 符号 *e)
{
循环 (; s != e; s = s->prev) {
如果 (!s->v || (s->r & VT_值掩码) != VT_LOCAL)
继续;
/* 添加数组/结构/联合,因为我们总是地址 */
如果 ((s->type.t & VT_数组)
|| (s->type.t & VT_基本类型) == VT_结构体
|| s->a.addrtaken) {
/* 添加局部边界信息 */
整数型 align, size = 类型_大小(&s->type, &align);
目标地址_类型 *bounds_ptr = 段_ptr_添加(本地边界_部分,
2 * 取大小(目标地址_类型));
bounds_ptr[0] = s->c;
bounds_ptr[1] = size;
}
}
}
#结束如果
/* 围绕符号_拖动的包装,也可能会注册局部范围. */
静态 无类型 弹出_局部_符号(符号 **ptop, 符号 *b, 整数型 keep, 整数型 ellipsis)
{
#如果已定义 配置_ZHI_边界检查
如果 (zhi_状态->执行_边界_检查器 && !ellipsis && !keep)
添加_局部_边界(*ptop, b);
#结束如果
如果 (zhi_状态->执行_调试)
zhi_添加_调试_信息 (zhi_状态, !局部_范围, *ptop, b);
符号_弹出(ptop, b, keep);
}
静态 无类型 incr_bf_adr(整数型 o)
{
栈顶值->type = 字符_指针_类型;
获取栈顶值地址();
压入目标地址类型常量(o);
通用_操作('+');
栈顶值->type.t = VT_字节 | VT_无符号;
栈顶值->r |= VT_LVAL;
}
/* 压缩或未对齐位域的单字节加载模式 */
静态 无类型 单字节_加载_模式(C类型 *type, 整数型 bit_pos, 整数型 bit_size)
{
整数型 n, o, bits;
将r保存到_内存堆栈_最多n个条目(栈顶值->r, 1);
压入64位常量(type->t & VT_基本类型, 0); // B X
bits = 0, o = bit_pos >> 3, bit_pos &= 7;
执行 {
vswap(); // X B
incr_bf_adr(o);
vdup(); // X B B
n = 8 - bit_pos;
如果 (n > bit_size)
n = bit_size;
如果 (bit_pos)
压入整数常量(bit_pos), 通用_操作(符_SHR), bit_pos = 0; // X B Y
如果 (n < 8)
压入整数常量((1 << n) - 1), 通用_操作('&');
通用_转换(type);
如果 (bits)
压入整数常量(bits), 通用_操作(双符号_左位移);
vrotb(3); // B Y X
通用_操作('|'); // B X
bits += n, bit_size -= n, o = 1;
} 判断 (bit_size);
vswap(), 弹出堆栈值();
如果 (!(type->t & VT_无符号)) {
n = ((type->t & VT_基本类型) == VT_长长整数 ? 64 : 32) - bits;
压入整数常量(n), 通用_操作(双符号_左位移);
压入整数常量(n), 通用_操作(双符号_右位移);
}
}
/* 压缩或未对齐位域的单字节存储模式 */
静态 无类型 单字节_存储_模式(整数型 bit_pos, 整数型 bit_size)
{
整数型 bits, n, o, m, c;
c = (栈顶值->r & (VT_值掩码 | VT_LVAL | VT_符号)) == VT_VC常量;
vswap(); // X B
将r保存到_内存堆栈_最多n个条目(栈顶值->r, 1);
bits = 0, o = bit_pos >> 3, bit_pos &= 7;
执行 {
incr_bf_adr(o); // X B
vswap(); //B X
c ? vdup() : 堆栈转为寄存器并复制到另一个寄存器(); // B V X
vrott(3); // X B V
如果 (bits)
压入整数常量(bits), 通用_操作(符_SHR);
如果 (bit_pos)
压入整数常量(bit_pos), 通用_操作(双符号_左位移);
n = 8 - bit_pos;
如果 (n > bit_size)
n = bit_size;
如果 (n < 8) {
m = ((1 << n) - 1) << bit_pos;
压入整数常量(m), 通用_操作('&'); // X B V1
vpushv(栈顶值-1); // X B V1 B
压入整数常量(m & 0x80 ? ~m & 0x7f : ~m);
通用_操作('&'); // X B V1 B1
通用_操作('|'); // X B V2
}
vdup(), 栈顶值[-1] = 栈顶值[-2]; // X B B V2
将栈顶值_存储在堆栈左值(), 弹出堆栈值(); // X B
bits += n, bit_size -= n, bit_pos = 0, o = 1;
} 判断 (bit_size);
弹出堆栈值(), 弹出堆栈值();
}
静态 整数型 adjust_单字节(堆栈值 *sv, 整数型 bit_pos, 整数型 bit_size)
{
整数型 t;
如果 (0 == sv->type.ref)
返回 0;
t = sv->type.ref->auxtype;
如果 (t != -1 && t != VT_结构体) {
sv->type.t = (sv->type.t & ~VT_基本类型) | t;
sv->r |= VT_LVAL;
}
返回 t;
}
/* 将属于类“ rc”的寄存器存储在vtop中。 左值被转换为值。 如果无法转换为寄存器值(例如结构),则无法使用。
* 该gv(rc)函数生成代码以将vtop(堆栈的最高值)评估到寄存器中。rc选择应将值放置在哪个寄存器类中。
* 将rc寄存器值存储在栈顶值中()是代码生成器最重要的功能。 */
静态_函数 整数型 将rc寄存器值存储在栈顶值中(整数型 rc)
{
整数型 r, r2, r_ok, r2_ok, rc2, bt;
整数型 bit_pos, bit_size, size, align;
/* NOTE: 查找释放的rc寄存器_如果不存在就保存一个寄存器 can modify 宏堆栈值[] */
如果 (栈顶值->type.t & VT_位域) {
C类型 type;
bit_pos = BIT_POS(栈顶值->type.t);
bit_size = BIT_大小(栈顶值->type.t);
/* 删除位字段信息以避免循环 */
栈顶值->type.t &= ~VT_结构体_掩码;
type.ref = NULL;
type.t = 栈顶值->type.t & VT_无符号;
如果 ((栈顶值->type.t & VT_基本类型) == VT_逻辑)
type.t |= VT_无符号;
r = adjust_单字节(栈顶值, bit_pos, bit_size);
如果 ((栈顶值->type.t & VT_基本类型) == VT_长长整数)
type.t |= VT_长长整数;
否则
type.t |= VT_整数;
如果 (r == VT_结构体) {
单字节_加载_模式(&type, bit_pos, bit_size);
} 否则 {
整数型 bits = (type.t & VT_基本类型) == VT_长长整数 ? 64 : 32;
/* 转换为int以在以下操作中传播签名 */
通用_转换(&type);
/* 产生转变 */
压入整数常量(bits - (bit_pos + bit_size));
通用_操作(双符号_左位移);
压入整数常量(bits - bit_size);
/* 注意:如果未签名,则转换为SHR */
通用_操作(双符号_右位移);
}
r = 将rc寄存器值存储在栈顶值中(rc);
} 否则 {
如果 (是_浮点型(栈顶值->type.t) &&
(栈顶值->r & (VT_值掩码 | VT_LVAL)) == VT_VC常量) {
无符号 long offset;
/* CPU通常不能使用浮点常量,因此我们通常将它们存储在数据段中 */
size = 类型_大小(&栈顶值->type, &align);
如果 (不需要_静态数据输出)
size = 0, align = 1;
offset = 返回_节_对齐偏移量(初始化数据_部分, size, align);
将引用_推送到_节偏移量(&栈顶值->type, 初始化数据_部分, offset, size);
vswap();
将值或表达式_直接存储在全局数据或本地数组中(&栈顶值->type, 初始化数据_部分, offset);
栈顶值->r |= VT_LVAL;
}
#如果已定义 配置_ZHI_边界检查
如果 (栈顶值->r & VT_强制边界检查)
生成左值边界代码();
#结束如果
bt = 栈顶值->type.t & VT_基本类型;
#如果已定义 ZHI_TARGET_RISCV64
/* XXX 超级黑客 */
如果 (bt == VT_长双精度 && rc == 寄存器类_浮点)
rc = 寄存器类_整数;
#结束如果
rc2 = 返回类型t的2_通用寄存器类(bt, rc);
/* 在以下情况下需要重新加载:
- 不变
-左值(需要取消引用指针)
-已经注册,但不在右侧 */
r = 栈顶值->r & VT_值掩码;
r_ok = !(栈顶值->r & VT_LVAL) && (r < VT_VC常量) && (寄存器_类数[r] & rc);
r2_ok = !rc2 || ((栈顶值->r2 < VT_VC常量) && (寄存器_类数[栈顶值->r2] & rc2));
如果 (!r_ok || !r2_ok) {
如果 (!r_ok)
r = 查找释放的rc寄存器_如果不存在就保存一个寄存器(rc);
如果 (rc2) {
整数型 load_type = (bt == VT_128位浮点) ? VT_双精度 : VT_指针DIFF_T;
整数型 original_type = 栈顶值->type.t;
/* two register type 加载 :
expand to two words temporarily */
如果 ((栈顶值->r & (VT_值掩码 | VT_LVAL)) == VT_VC常量) {
/* 加载 constant */
无符号 long long ll = 栈顶值->c.i;
栈顶值->c.i = ll; /* first word */
加载(r, 栈顶值);
栈顶值->r = r; /* save register value */
压入整数常量(ll >> 32); /* second word */
} 否则 如果 (栈顶值->r & VT_LVAL) {
/* We 执行 not want to modifier the long long pointer here.
So we save any other instances down the stack */
将r保存到_内存堆栈_最多n个条目(栈顶值->r, 1);
/* 加载 from memory */
栈顶值->type.t = load_type;
加载(r, 栈顶值);
vdup();
栈顶值[-1].r = r; /* save register value */
/* increment pointer to get second word */
栈顶值->type.t = VT_指针DIFF_T;
获取栈顶值地址();
压入目标地址类型常量(指针_大小);
通用_操作('+');
栈顶值->r |= VT_LVAL;
栈顶值->type.t = load_type;
} 否则 {
/* move registers */
如果 (!r_ok)
加载(r, 栈顶值);
如果 (r2_ok && 栈顶值->r2 < VT_VC常量)
去向 done;
vdup();
栈顶值[-1].r = r; /* save register value */
栈顶值->r = 栈顶值[-1].r2;
}
/* Allocate second register. Here we rely on the fact that
查找释放的rc寄存器_如果不存在就保存一个寄存器() tries first to free r2 of an 堆栈值. */
r2 = 查找释放的rc寄存器_如果不存在就保存一个寄存器(rc2);
加载(r2, 栈顶值);
弹出堆栈值();
/* write second register */
栈顶值->r2 = r2;
done:
栈顶值->type.t = original_type;
} 否则 {
如果 (栈顶值->r == VT_CMP)
vset_VT_JMP();
/* one register type 加载 */
加载(r, 栈顶值);
}
}
栈顶值->r = r;
#如果已定义 ZHI_TARGET_C67
/* uses register pairs 循环 doubles */
如果 (bt == VT_双精度)
栈顶值->r2 = r+1;
#结束如果
}
返回 r;
}
/* 分别生成vtop [-1]和vtop [0]。 rc1和rc2类.对于前两名堆栈条目。 */
静态_函数 无类型 将rc寄存器值存储在栈顶值中2(整数型 rc1, 整数型 rc2)
{
/* generate more generic register first. But VT_JMP or VT_CMP
values must be generated first in all cases to avoid possible
reload errors */
如果 (栈顶值->r != VT_CMP && rc1 <= rc2) {
vswap();
将rc寄存器值存储在栈顶值中(rc1);
vswap();
将rc寄存器值存储在栈顶值中(rc2);
/* test 如果 reload is needed 循环 first register */
如果 ((栈顶值[-1].r & VT_值掩码) >= VT_VC常量) {
vswap();
将rc寄存器值存储在栈顶值中(rc1);
vswap();
}
} 否则 {
将rc寄存器值存储在栈顶值中(rc2);
vswap();
将rc寄存器值存储在栈顶值中(rc1);
vswap();
/* test 如果 reload is needed 循环 first register */
如果 ((栈顶值[0].r & VT_值掩码) >= VT_VC常量) {
将rc寄存器值存储在栈顶值中(rc2);
}
}
}
#如果 指针_大小 == 4
/* 以两个整数在堆栈上扩展64bit */
静态_函数 无类型 整数扩展(无类型)
{
整数型 u, v;
u = 栈顶值->type.t & (VT_显式符号 | VT_无符号);
v = 栈顶值->r & (VT_值掩码 | VT_LVAL);
如果 (v == VT_VC常量) {
vdup();
栈顶值[0].c.i >>= 32;
} 否则 如果 (v == (VT_LVAL|VT_VC常量) || v == (VT_LVAL|VT_LOCAL)) {
vdup();
栈顶值[0].c.i += 4;
} 否则 {
将rc寄存器值存储在栈顶值中(寄存器类_整数);
vdup();
栈顶值[0].r = 栈顶值[-1].r2;
栈顶值[0].r2 = 栈顶值[-1].r2 = VT_VC常量;
}
栈顶值[0].type.t = 栈顶值[-1].type.t = VT_整数 | u;
}
#结束如果
#如果 指针_大小 == 4
/* build a long long from two ints */
静态 无类型 构建长长整数(整数型 t)
{
将rc寄存器值存储在栈顶值中2(寄存器类_整数, 寄存器类_整数);
栈顶值[-1].r2 = 栈顶值[0].r;
栈顶值[-1].type.t = t;
弹出堆栈值();
}
#结束如果
/* 将堆栈条目转换为寄存器并将其值复制到另一个寄存器中 */
静态 无类型 堆栈转为寄存器并复制到另一个寄存器(无类型)
{
整数型 t, rc, r;
t = 栈顶值->type.t;
#如果 指针_大小 == 4
如果 ((t & VT_基本类型) == VT_长长整数) {
如果 (t & VT_位域) {
将rc寄存器值存储在栈顶值中(寄存器类_整数);
t = 栈顶值->type.t;
}
整数扩展();
堆栈转为寄存器并复制到另一个寄存器();
vswap();
vrotb(3);
堆栈转为寄存器并复制到另一个寄存器();
vrotb(4);
/* stack: H L L1 H1 */
构建长长整数(t);
vrotb(3);
vrotb(3);
vswap();
构建长长整数(t);
vswap();
返回;
}
#结束如果
/* duplicate value */
rc = 返回类型t的_通用寄存器类(t);
将rc寄存器值存储在栈顶值中(rc);
r = 查找释放的rc寄存器_如果不存在就保存一个寄存器(rc);
vdup();
加载(r, 栈顶值);
栈顶值->r = r;
}
#如果 指针_大小 == 4
/* 生成独立于CPU(无符号)的长时间操作 */
静态 无类型 生成_独立于CPU的长时间操作(整数型 op)
{
整数型 t, a, b, op1, c, i;
整数型 func;
无符号 short reg_iret = 寄存器_返回16位整数寄存器;
无符号 short reg_lret = 寄存器_返回32位整数寄存器;
堆栈值 tmp;
选择(op) {
分支 '/':
分支 符_指针除法:
func = 符___divdi3;
去向 生成_func;
分支 符_无符除法:
func = 符___udivdi3;
去向 生成_func;
分支 '%':
func = 符___moddi3;
去向 生成_mod_func;
分支 符_无符取模运算:
func = 符___umoddi3;
生成_mod_func:
#如果已定义 ZHI_ARM_EABI
reg_iret = TREG_R2;
reg_lret = TREG_R3;
#结束如果
生成_func:
/* 调用泛型long long函数 */
推送对_全局符号V_的引用(&函数_旧_类型, func);
vrott(3);
具体地址函数_调用(2);
压入整数常量(0);
栈顶值->r = reg_iret;
栈顶值->r2 = reg_lret;
跳出;
分支 '^':
分支 '&':
分支 '|':
分支 '*':
分支 '+':
分支 '-':
//堆栈值调试辅助("生成_独立于CPU的长时间操作 A",0,2);
t = 栈顶值->type.t;
vswap();
整数扩展();
vrotb(3);
整数扩展();
/* stack: L1 H1 L2 H2 */
tmp = 栈顶值[0];
栈顶值[0] = 栈顶值[-3];
栈顶值[-3] = tmp;
tmp = 栈顶值[-2];
栈顶值[-2] = 栈顶值[-3];
栈顶值[-3] = tmp;
vswap();
/* stack: H1 H2 L1 L2 */
//堆栈值调试辅助("生成_独立于CPU的长时间操作 B",0,4);
如果 (op == '*') {
vpushv(栈顶值 - 1);
vpushv(栈顶值 - 1);
通用_操作(符_无符32位乘法);
整数扩展();
/* stack: H1 H2 L1 L2 ML MH */
循环(i=0;i<4;i++)
vrotb(6);
/* stack: ML MH H1 H2 L1 L2 */
tmp = 栈顶值[0];
栈顶值[0] = 栈顶值[-2];
栈顶值[-2] = tmp;
/* stack: ML MH H1 L2 H2 L1 */
通用_操作('*');
vrotb(3);
vrotb(3);
通用_操作('*');
/* stack: ML MH M1 M2 */
通用_操作('+');
通用_操作('+');
} 否则 如果 (op == '+' || op == '-') {
/* XXX: add non carry method too (循环 MIPS or alpha) */
如果 (op == '+')
op1 = 符_加进位生成;
否则
op1 = 符_减借位生成;
通用_操作(op1);
/* stack: H1 H2 (L1 op L2) */
vrotb(3);
vrotb(3);
通用_操作(op1 + 1); /* 符_xxxC2 */
} 否则 {
通用_操作(op);
/* stack: H1 H2 (L1 op L2) */
vrotb(3);
vrotb(3);
/* stack: (L1 op L2) H1 H2 */
通用_操作(op);
/* stack: (L1 op L2) (H1 op H2) */
}
/* stack: L H */
构建长长整数(t);
跳出;
分支 双符号_右位移:
分支 符_SHR:
分支 双符号_左位移:
如果 ((栈顶值->r & (VT_值掩码 | VT_LVAL | VT_符号)) == VT_VC常量) {
t = 栈顶值[-1].type.t;
vswap();
整数扩展();
vrotb(3);
/* stack: L H shift */
c = (整数型)栈顶值->c.i;
/* 常量:更简单 */
/* 注意:所有评论均针对SHL。 其他情况通过交换单词来完成 */
弹出堆栈值();
如果 (op != 双符号_左位移)
vswap();
如果 (c >= 32) {
/* stack: L H */
弹出堆栈值();
如果 (c > 32) {
压入整数常量(c - 32);
通用_操作(op);
}
如果 (op != 双符号_右位移) {
压入整数常量(0);
} 否则 {
堆栈转为寄存器并复制到另一个寄存器();
压入整数常量(31);
通用_操作(双符号_右位移);
}
vswap();
} 否则 {
vswap();
堆栈转为寄存器并复制到另一个寄存器();
/* stack: H L L */
压入整数常量(c);
通用_操作(op);
vswap();
压入整数常量(32 - c);
如果 (op == 双符号_左位移)
通用_操作(符_SHR);
否则
通用_操作(双符号_左位移);
vrotb(3);
/* stack: L L H */
压入整数常量(c);
如果 (op == 双符号_左位移)
通用_操作(双符号_左位移);
否则
通用_操作(符_SHR);
通用_操作('|');
}
如果 (op != 双符号_左位移)
vswap();
构建长长整数(t);
} 否则 {
/* XXX: 应该在x86上提供更快的后备功能? */
选择(op) {
分支 双符号_右位移:
func = 符___ashrdi3;
去向 生成_func;
分支 符_SHR:
func = 符___lshrdi3;
去向 生成_func;
分支 双符号_左位移:
func = 符___ashldi3;
去向 生成_func;
}
}
跳出;
default:
/* 比较操作 */
t = 栈顶值->type.t;
vswap();
整数扩展();
vrotb(3);
整数扩展();
/* stack: L1 H1 L2 H2 */
tmp = 栈顶值[-1];
栈顶值[-1] = 栈顶值[-2];
栈顶值[-2] = tmp;
/* stack: L1 L2 H1 H2 */
保存_寄存器最多n个堆栈条目(4);
/* 对比高位 */
op1 = op;
/* 当值相等时,我们需要比较低位字。 由于跳跃是反向的,我们也将测试反向. */
如果 (op1 == 符_LT)
op1 = 双符号_小于等于;
否则 如果 (op1 == 符_GT)
op1 = 双符号_大于等于;
否则 如果 (op1 == 符号_ULT)
op1 = 符号_ULE;
否则 如果 (op1 == 符_UGT)
op1 = 符号_UGE;
a = 0;
b = 0;
通用_操作(op1);
如果 (op == 双符号_不等于) {
b = 生成值测试(0, 0);
} 否则 {
a = 生成值测试(1, 0);
如果 (op != 双符号_等于) {
/* 生成“不等于”测试 */
压入整数常量(0);
vset_VT_CMP(双符号_不等于);
b = 生成值测试(0, 0);
}
}
/* compare low. Always 无符号 */
op1 = op;
如果 (op1 == 符_LT)
op1 = 符号_ULT;
否则 如果 (op1 == 双符号_小于等于)
op1 = 符号_ULE;
否则 如果 (op1 == 符_GT)
op1 = 符_UGT;
否则 如果 (op1 == 双符号_大于等于)
op1 = 符号_UGE;
通用_操作(op1);
#如果 0//def ZHI_TARGET_I386
如果 (op == 双符号_不等于) { 生成符号(b); 跳出; }
如果 (op == 双符号_等于) { 生成符号(a); 跳出; }
#结束如果
gvtst_set(1, a);
gvtst_set(0, b);
跳出;
}
}
#结束如果
静态 uint64_t 生成_opic_sdiv(uint64_t a, uint64_t b)
{
uint64_t x = (a >> 63 ? -a : a) / (b >> 63 ? -b : b);
返回 (a ^ b) >> 63 ? -x : x;
}
静态 整数型 生成_opic_lt(uint64_t a, uint64_t b)
{
返回 (a ^ (uint64_t)1 << 63) < (b ^ (uint64_t)1 << 63);
}
/* 处理整数常量优化和各种与机器无关的选项 */
静态 无类型 生成_整数常量优化和与机器无关的选项(整数型 op)
{
堆栈值 *v1 = 栈顶值 - 1;
堆栈值 *v2 = 栈顶值;
整数型 t1 = v1->type.t & VT_基本类型;
整数型 t2 = v2->type.t & VT_基本类型;
整数型 c1 = (v1->r & (VT_值掩码 | VT_LVAL | VT_符号)) == VT_VC常量;
整数型 c2 = (v2->r & (VT_值掩码 | VT_LVAL | VT_符号)) == VT_VC常量;
uint64_t l1 = c1 ? v1->c.i : 0;
uint64_t l2 = c2 ? v2->c.i : 0;
整数型 shm = (t1 == VT_长长整数) ? 63 : 31;
如果 (t1 != VT_长长整数 && (指针_大小 != 8 || t1 != VT_指针))
l1 = ((uint32_t)l1 |
(v1->type.t & VT_无符号 ? 0 : -(l1 & 0x80000000)));
如果 (t2 != VT_长长整数 && (指针_大小 != 8 || t2 != VT_指针))
l2 = ((uint32_t)l2 |
(v2->type.t & VT_无符号 ? 0 : -(l2 & 0x80000000)));
如果 (c1 && c2) {
选择(op) {
分支 '+': l1 += l2; 跳出;
分支 '-': l1 -= l2; 跳出;
分支 '&': l1 &= l2; 跳出;
分支 '^': l1 ^= l2; 跳出;
分支 '|': l1 |= l2; 跳出;
分支 '*': l1 *= l2; 跳出;
分支 符_指针除法:
分支 '/':
分支 '%':
分支 符_无符除法:
分支 符_无符取模运算:
/* 如果 division by zero, generate explicit division */
如果 (l2 == 0) {
如果 (需要_常量 && !(不需要_代码生成 & 未评估的子表达式))
错误_打印("division by zero in constant");
去向 general_case;
}
选择(op) {
default: l1 = 生成_opic_sdiv(l1, l2); 跳出;
分支 '%': l1 = l1 - l2 * 生成_opic_sdiv(l1, l2); 跳出;
分支 符_无符除法: l1 = l1 / l2; 跳出;
分支 符_无符取模运算: l1 = l1 % l2; 跳出;
}
跳出;
分支 双符号_左位移: l1 <<= (l2 & shm); 跳出;
分支 符_SHR: l1 >>= (l2 & shm); 跳出;
分支 双符号_右位移:
l1 = (l1 >> 63) ? ~(~l1 >> (l2 & shm)) : l1 >> (l2 & shm);
跳出;
/* tests */
分支 符号_ULT: l1 = l1 < l2; 跳出;
分支 符号_UGE: l1 = l1 >= l2; 跳出;
分支 双符号_等于: l1 = l1 == l2; 跳出;
分支 双符号_不等于: l1 = l1 != l2; 跳出;
分支 符号_ULE: l1 = l1 <= l2; 跳出;
分支 符_UGT: l1 = l1 > l2; 跳出;
分支 符_LT: l1 = 生成_opic_lt(l1, l2); 跳出;
分支 双符号_大于等于: l1 = !生成_opic_lt(l1, l2); 跳出;
分支 双符号_小于等于: l1 = !生成_opic_lt(l2, l1); 跳出;
分支 符_GT: l1 = 生成_opic_lt(l2, l1); 跳出;
/* logical */
分支 双符号_逻辑与: l1 = l1 && l2; 跳出;
分支 双符号_逻辑或: l1 = l1 || l2; 跳出;
default:
去向 general_case;
}
如果 (t1 != VT_长长整数 && (指针_大小 != 8 || t1 != VT_指针))
l1 = ((uint32_t)l1 |
(v1->type.t & VT_无符号 ? 0 : -(l1 & 0x80000000)));
v1->c.i = l1;
栈顶值--;
} 否则 {
/* 如果 commutative ops, put c2 as constant */
如果 (c1 && (op == '+' || op == '&' || op == '^' ||
op == '|' || op == '*' || op == 双符号_等于 || op == 双符号_不等于)) {
vswap();
c2 = c1; //c = c1, c1 = c2, c2 = c;
l2 = l1; //l = l1, l1 = l2, l2 = l;
}
如果 (!需要_常量 &&
c1 && ((l1 == 0 &&
(op == 双符号_左位移 || op == 符_SHR || op == 双符号_右位移)) ||
(l1 == -1 && op == 双符号_右位移))) {
/* treat (0 << x), (0 >> x) and (-1 >> x) as constant */
栈顶值--;
} 否则 如果 (!需要_常量 &&
c2 && ((l2 == 0 && (op == '&' || op == '*')) ||
(op == '|' &&
(l2 == -1 || (l2 == 0xFFFFFFFF && t2 != VT_长长整数))) ||
(l2 == 1 && (op == '%' || op == 符_无符取模运算)))) {
/* treat (x & 0), (x * 0), (x | -1) and (x % 1) as constant */
如果 (l2 == 1)
栈顶值->c.i = 0;
vswap();
栈顶值--;
} 否则 如果 (c2 && (((op == '*' || op == '/' || op == 符_无符除法 ||
op == 符_指针除法) &&
l2 == 1) ||
((op == '+' || op == '-' || op == '|' || op == '^' ||
op == 双符号_左位移 || op == 符_SHR || op == 双符号_右位移) &&
l2 == 0) ||
(op == '&' &&
(l2 == -1 || (l2 == 0xFFFFFFFF && t2 != VT_长长整数))))) {
/* filter out NOP operations like x*1, x-0, x&-1... */
栈顶值--;
} 否则 如果 (c2 && (op == '*' || op == 符_指针除法 || op == 符_无符除法)) {
/* try to use shifts instead of muls or divs */
如果 (l2 > 0 && (l2 & (l2 - 1)) == 0) {
整数型 n = -1;
判断 (l2) {
l2 >>= 1;
n++;
}
栈顶值->c.i = n;
如果 (op == '*')
op = 双符号_左位移;
否则 如果 (op == 符_指针除法)
op = 双符号_右位移;
否则
op = 符_SHR;
}
去向 general_case;
} 否则 如果 (c2 && (op == '+' || op == '-') &&
(((栈顶值[-1].r & (VT_值掩码 | VT_LVAL | VT_符号)) == (VT_VC常量 | VT_符号))
|| (栈顶值[-1].r & (VT_值掩码 | VT_LVAL)) == VT_LOCAL)) {
/* symbol + constant 分支 */
如果 (op == '-')
l2 = -l2;
l2 += 栈顶值[-1].c.i;
/* The backends can't always deal with addends to symbols
larger than +-1<<31. Don't construct such. */
如果 ((整数型)l2 != l2)
去向 general_case;
栈顶值--;
栈顶值->c.i = l2;
} 否则 {
general_case:
/* call low level op generator */
如果 (t1 == VT_长长整数 || t2 == VT_长长整数 ||
(指针_大小 == 8 && (t1 == VT_指针 || t2 == VT_指针)))
生成_独立于CPU的长时间操作(op);
否则
生成_整数二进制运算(op);
}
}
}
/* 生成具有恒定传播的浮点运算 */
静态 无类型 生成_常量传播的浮点运算(整数型 op)
{
整数型 c1, c2;
堆栈值 *v1, *v2;
#如果 已定义 _MSC_VER && 已定义 __x86_64__
/* 避免对f1:-0.0,f2:0.0使用f1-= f2进行错误的优化 */
volatile
#结束如果
long double f1, f2;
v1 = 栈顶值 - 1;
v2 = 栈顶值;
/* 目前,我们无法使用正向符号进行计算 */
c1 = (v1->r & (VT_值掩码 | VT_LVAL | VT_符号)) == VT_VC常量;
c2 = (v2->r & (VT_值掩码 | VT_LVAL | VT_符号)) == VT_VC常量;
如果 (c1 && c2) {
如果 (v1->type.t == VT_浮点) {
f1 = v1->c.f;
f2 = v2->c.f;
} 否则 如果 (v1->type.t == VT_双精度) {
f1 = v1->c.d;
f2 = v2->c.d;
} 否则 {
f1 = v1->c.ld;
f2 = v2->c.ld;
}
/* 注意:我们仅在有限数量(不是NaN或无穷大)(ANSI规范)的情况下进行常数传播*/
如果 (!ieee_有限的(f1) || !ieee_有限的(f2))
去向 general_case;
选择(op) {
分支 '+': f1 += f2; 跳出;
分支 '-': f1 -= f2; 跳出;
分支 '*': f1 *= f2; 跳出;
分支 '/':
如果 (f2 == 0.0) {
/* 如果不在初始化程序中,我们可能需要在运行时生成FP异常,否则我们想折叠。 */
如果 (!需要_常量)
去向 general_case;
}
f1 /= f2;
跳出;
/* XXX: 还可以处理测试吗? */
default:
去向 general_case;
}
/* XXX: 溢出测试? */
如果 (v1->type.t == VT_浮点) {
v1->c.f = f1;
} 否则 如果 (v1->type.t == VT_双精度) {
v1->c.d = f1;
} 否则 {
v1->c.ld = f1;
}
栈顶值--;
} 否则 {
general_case:
生成_浮点运算(op);
}
}
/* 打印类型。 如果'varstr'不为NULL,则该变量也以以下类型打印 */
/* XXX: 联合体 */
/* XXX: 添加数组和函数指针 */
静态 无类型 字符串_的_类型(字符型 *buf, 整数型 buf_size,C类型 *type, 常量 字符型 *varstr)
{
整数型 bt, v, t;
符号 *s, *sa;
字符型 buf1[256];
常量 字符型 *tstr;
t = type->t;
bt = t & VT_基本类型;
buf[0] = '\0';
如果 (t & VT_外部)
连接_字符串(buf, buf_size, "外部 ");
如果 (t & VT_静态)
连接_字符串(buf, buf_size, "静态 ");
如果 (t & VT_别名)
连接_字符串(buf, buf_size, "类型定义 ");
如果 (t & VT_内联)
连接_字符串(buf, buf_size, "内联 ");
如果 (t & VT_易变)
连接_字符串(buf, buf_size, "volatile ");
如果 (t & VT_常量)
连接_字符串(buf, buf_size, "常量 ");
如果 (((t & VT_显式符号) && bt == VT_字节)
|| ((t & VT_无符号)
&& (bt == VT_短整数 || bt == VT_整数 || bt == VT_长长整数)
&& !是_枚举(t)
))
连接_字符串(buf, buf_size, (t & VT_无符号) ? "无符号 " : "signed ");
buf_size -= strlen(buf);
buf += strlen(buf);
选择(bt) {
分支 VT_无类型:
tstr = "无类型";
去向 add_tstr;
分支 VT_逻辑:
tstr = "_Bool";
去向 add_tstr;
分支 VT_字节:
tstr = "字符型";
去向 add_tstr;
分支 VT_短整数:
tstr = "short";
去向 add_tstr;
分支 VT_整数:
tstr = "整数型";
去向 maybe_long;
分支 VT_长长整数:
tstr = "long long";
maybe_long:
如果 (t & VT_长整数)
tstr = "long";
如果 (!是_枚举(t))
去向 add_tstr;
tstr = "枚举 ";
去向 tstruct;
分支 VT_浮点:
tstr = "float";
去向 add_tstr;
分支 VT_双精度:
tstr = "double";
如果 (!(t & VT_长整数))
去向 add_tstr;
分支 VT_长双精度:
tstr = "long double";
add_tstr:
连接_字符串(buf, buf_size, tstr);
跳出;
分支 VT_结构体:
tstr = "结构体 ";
如果 (是_共用体(t))
tstr = "共用体 ";
tstruct:
连接_字符串(buf, buf_size, tstr);
v = type->ref->v & ~符号_结构体;
如果 (v >= 符号_第一个_匿名)
连接_字符串(buf, buf_size, "<anonymous>");
否则
连接_字符串(buf, buf_size, 取_单词字符串(v, NULL));
跳出;
分支 VT_函数:
s = type->ref;
buf1[0]=0;
如果 (varstr && '*' == *varstr) {
连接_字符串(buf1, 取大小(buf1), "(");
连接_字符串(buf1, 取大小(buf1), varstr);
连接_字符串(buf1, 取大小(buf1), ")");
}
连接_字符串(buf1, buf_size, "(");
sa = s->next;
判断 (sa != NULL) {
字符型 buf2[256];
字符串_的_类型(buf2, 取大小(buf2), &sa->type, NULL);
连接_字符串(buf1, 取大小(buf1), buf2);
sa = sa->next;
如果 (sa)
连接_字符串(buf1, 取大小(buf1), ", ");
}
如果 (s->f.func_type == 函数_省略)
连接_字符串(buf1, 取大小(buf1), ", ...");
连接_字符串(buf1, 取大小(buf1), ")");
字符串_的_类型(buf, buf_size, &s->type, buf1);
去向 no_var;
分支 VT_指针:
s = type->ref;
如果 (t & VT_数组) {
如果 (varstr && '*' == *varstr)
snprintf(buf1, 取大小(buf1), "(%s)[%d]", varstr, s->c);
否则
snprintf(buf1, 取大小(buf1), "%s[%d]", varstr ? varstr : "", s->c);
字符串_的_类型(buf, buf_size, &s->type, buf1);
去向 no_var;
}
p字符串复制(buf1, 取大小(buf1), "*");
如果 (t & VT_常量)
连接_字符串(buf1, buf_size, "常量 ");
如果 (t & VT_易变)
连接_字符串(buf1, buf_size, "volatile ");
如果 (varstr)
连接_字符串(buf1, 取大小(buf1), varstr);
字符串_的_类型(buf, buf_size, &s->type, buf1);
去向 no_var;
}
如果 (varstr) {
连接_字符串(buf, buf_size, " ");
连接_字符串(buf, buf_size, varstr);
}
no_var: ;
}
静态 无类型 类型_不兼容_错误(C类型* st, C类型* dt, 常量 字符型* fmt)
{
字符型 buf1[256], buf2[256];
字符串_的_类型(buf1, 取大小(buf1), st, NULL);
字符串_的_类型(buf2, 取大小(buf2), dt, NULL);
错误_打印(fmt, buf1, buf2);
}
静态 无类型 类型_不兼容_警告(C类型* st, C类型* dt, 常量 字符型* fmt)
{
字符型 buf1[256], buf2[256];
字符串_的_类型(buf1, 取大小(buf1), st, NULL);
字符串_的_类型(buf2, 取大小(buf2), dt, NULL);
zhi_警告(fmt, buf1, buf2);
}
静态 整数型 指定类型的_大小(C类型 *type)
{
整数型 align;
返回 类型_大小(指定的_类型(type), &align);
}
静态 无类型 vla_运行时_指向的_类型的大小(C类型 *type)
{
整数型 align;
vla_运行时_类型_大小(指定的_类型(type), &align);
}
静态 内联 整数型 是_空_指针(堆栈值 *p)
{
如果 ((p->r & (VT_值掩码 | VT_LVAL | VT_符号)) != VT_VC常量)
返回 0;
返回 ((p->type.t & VT_基本类型) == VT_整数 && (uint32_t)p->c.i == 0) ||
((p->type.t & VT_基本类型) == VT_长长整数 && p->c.i == 0) ||
((p->type.t & VT_基本类型) == VT_指针 &&
(指针_大小 == 4 ? (uint32_t)p->c.i == 0 : p->c.i == 0) &&
((指定的_类型(&p->type)->t & VT_基本类型) == VT_无类型) &&
0 == (指定的_类型(&p->type)->t & (VT_常量 | VT_易变))
);
}
/* 比较函数类型。 旧功能与任何新功能匹配 */
静态 整数型 是_兼容的_函数(C类型 *type1, C类型 *type2)
{
符号 *状态机1, *s2;
状态机1 = type1->ref;
s2 = type2->ref;
如果 (状态机1->f.函数_调用 != s2->f.函数_调用)
返回 0;
如果 (状态机1->f.func_type != s2->f.func_type
&& 状态机1->f.func_type != 函数_旧
&& s2->f.func_type != 函数_旧)
返回 0;
/* 我们也应该检查函数的返回类型是否为函数_OLD,但这会导致内部使用的支持函数(例如符_memmove)出现问题 */
如果 (状态机1->f.func_type == 函数_旧 && !状态机1->next)
返回 1;
如果 (s2->f.func_type == 函数_旧 && !s2->next)
返回 1;
循环 (;;) {
如果 (!是_兼容_不合格的_类型(&状态机1->type, &s2->type))
返回 0;
状态机1 = 状态机1->next;
s2 = s2->next;
如果 (!状态机1)
返回 !s2;
如果 (!s2)
返回 0;
}
}
/* 如果type1和type2相同,则返回true。 如果unqualified为true,则忽略类型上的限定符。
*/
静态 整数型 比较_2个类型(C类型 *type1, C类型 *type2, 整数型 unqualified)
{
整数型 bt1, t1, t2;
t1 = type1->t & VT_类型;
t2 = type2->t & VT_类型;
如果 (unqualified) {
/* 比较前去除预选赛 */
t1 &= ~(VT_常量 | VT_易变);
t2 &= ~(VT_常量 | VT_易变);
}
/* 默认Vs显式签名仅对char很重要 */
如果 ((t1 & VT_基本类型) != VT_字节) {
t1 &= ~VT_显式符号;
t2 &= ~VT_显式符号;
}
/* XXX: 位域 ? */
如果 (t1 != t2)
返回 0;
如果 ((t1 & VT_数组)
&& !(type1->ref->c < 0
|| type2->ref->c < 0
|| type1->ref->c == type2->ref->c))
返回 0;
/* 测试更复杂的案例 */
bt1 = t1 & VT_基本类型;
如果 (bt1 == VT_指针) {
type1 = 指定的_类型(type1);
type2 = 指定的_类型(type2);
返回 是_兼容_类型(type1, type2);
} 否则 如果 (bt1 == VT_结构体) {
返回 (type1->ref == type2->ref);
} 否则 如果 (bt1 == VT_函数) {
返回 是_兼容的_函数(type1, type2);
} 否则 如果 (是_枚举(type1->t) && 是_枚举(type2->t)) {
/* 如果两个都是枚举,则它们必须相同;如果只有一个,则t1和t2必须相等,这已在上面进行了检查。 */
返回 type1->ref == type2->ref;
} 否则 {
返回 1;
}
}
/*检查OP1和OP2是否可以与操作OP“组合”,如果非null(指针正负除外),则组合类型存储在DEST中。 */
静态 整数型 结合_类型(C类型 *dest, 堆栈值 *op1, 堆栈值 *op2, 整数型 op)
{
C类型 *type1 = &op1->type, *type2 = &op2->type, type;
整数型 t1 = type1->t, t2 = type2->t, bt1 = t1 & VT_基本类型, bt2 = t2 & VT_基本类型;
整数型 ret = 1;
type.t = VT_无类型;
type.ref = NULL;
如果 (bt1 == VT_无类型 || bt2 == VT_无类型) {
ret = op == '?' ? 1 : 0;
/* 注意:作为扩展,我们仅接受一侧的空隙 */
type.t = VT_无类型;
} 否则 如果 (bt1 == VT_指针 || bt2 == VT_指针) {
如果 (op == '+') ; /* 处理来电者 */
/* http://port70.net/~nsz/c/c99/n1256.html#6.5.15p6 */
/* 如果一个为空的ptr常量,则结果类型为另一个。 */
否则 如果 (是_空_指针 (op2)) type = *type1;
否则 如果 (是_空_指针 (op1)) type = *type2;
否则 如果 (bt1 != bt2) {
/* 接受带有警告的指针和整数之间的比较或cond-expr */
如果 ((op == '?' || 符_ISCOND(op))
&& (是_整数_型(bt1) || 是_整数_型(bt2)))
zhi_警告(" %s 指针/整数不匹配", op == '?' ? "条件表达式" : "比较");
否则 如果 (op != '-' || !是_整数_型(bt2))
ret = 0;
type = *(bt1 == VT_指针 ? type1 : type2);
} 否则 {
C类型 *pt1 = 指定的_类型(type1);
C类型 *pt2 = 指定的_类型(type2);
整数型 pbt1 = pt1->t & VT_基本类型;
整数型 pbt2 = pt2->t & VT_基本类型;
整数型 newquals, copied = 0;
如果 (pbt1 != VT_无类型 && pbt2 != VT_无类型
&& !比较_2个类型(pt1, pt2, 1/*不合格*/)) {
如果 (op != '?' && !符_ISCOND(op))
ret = 0;
否则
类型_不兼容_警告(type1, type2, op == '?' ? "条件表达式 ('%s' and '%s') 中的指针类型不匹配." : "比较中的指针类型不匹配('%s' and '%s')");
}
如果 (op == '?') {
/* 首选指向void的指针,否则指向类型的指针减去限定符应兼容 */
type = *((pbt1 == VT_无类型) ? type1 : type2);
/* 结合资格 */
newquals = ((pt1->t | pt2->t) & (VT_常量 | VT_易变));
如果 ((~指定的_类型(&type)->t & (VT_常量 | VT_易变))
& newquals)
{
/* 复制指针目标符号 */
type.ref = 符号_压入栈(符号_字段, &type.ref->type,
0, type.ref->c);
copied = 1;
指定的_类型(&type)->t |= newquals;
}
/* 如果可能,指向不完整数组的指针将转换为指向已完成数组的指针*/
如果 (pt1->t & VT_数组
&& pt2->t & VT_数组
&& 指定的_类型(&type)->ref->c < 0
&& (pt1->ref->c > 0 || pt2->ref->c > 0))
{
如果 (!copied)
type.ref = 符号_压入栈(符号_字段, &type.ref->type,
0, type.ref->c);
指定的_类型(&type)->ref =
符号_压入栈(符号_字段, &指定的_类型(&type)->ref->type,
0, 指定的_类型(&type)->ref->c);
指定的_类型(&type)->ref->c =
0 < pt1->ref->c ? pt1->ref->c : pt2->ref->c;
}
}
}
如果 (符_ISCOND(op))
type.t = VT_SIZE_T;
} 否则 如果 (bt1 == VT_结构体 || bt2 == VT_结构体) {
如果 (op != '?' || !比较_2个类型(type1, type2, 1))
ret = 0;
type = *type1;
} 否则 如果 (是_浮点型(bt1) || 是_浮点型(bt2)) {
如果 (bt1 == VT_长双精度 || bt2 == VT_长双精度) {
type.t = VT_长双精度;
} 否则 如果 (bt1 == VT_双精度 || bt2 == VT_双精度) {
type.t = VT_双精度;
} 否则 {
type.t = VT_浮点;
}
} 否则 如果 (bt1 == VT_长长整数 || bt2 == VT_长长整数) {
/* 投给最大的行动 */
type.t = VT_长长整数 | VT_长整数;
如果 (bt1 == VT_长长整数)
type.t &= t1;
如果 (bt2 == VT_长长整数)
type.t &= t2;
/* 如果长时间不适合,请转换为unsigned */
如果 ((t1 & (VT_基本类型 | VT_无符号 | VT_位域)) == (VT_长长整数 | VT_无符号) ||
(t2 & (VT_基本类型 | VT_无符号 | VT_位域)) == (VT_长长整数 | VT_无符号))
type.t |= VT_无符号;
} 否则 {
/* 整数运算 */
type.t = VT_整数 | (VT_长整数 & (t1 | t2));
/* 如果它不适合整数,则转换为无符号 */
如果 ((t1 & (VT_基本类型 | VT_无符号 | VT_位域)) == (VT_整数 | VT_无符号) ||
(t2 & (VT_基本类型 | VT_无符号 | VT_位域)) == (VT_整数 | VT_无符号))
type.t |= VT_无符号;
}
如果 (dest)
*dest = type;
返回 ret;
}
/* 通用生成_op:处理类型问题 */
静态_函数 无类型 通用_操作(整数型 op)
{
整数型 u, t1, t2, bt1, bt2, t;
C类型 type1, combtype;
redo:
t1 = 栈顶值[-1].type.t;
t2 = 栈顶值[0].type.t;
bt1 = t1 & VT_基本类型;
bt2 = t2 & VT_基本类型;
如果 (bt1 == VT_函数 || bt2 == VT_函数) {
如果 (bt2 == VT_函数) {
修改类型_指针类型(&栈顶值->type);
获取栈顶值地址();
}
如果 (bt1 == VT_函数) {
vswap();
修改类型_指针类型(&栈顶值->type);
获取栈顶值地址();
vswap();
}
去向 redo;
} 否则 如果 (!结合_类型(&combtype, 栈顶值 - 1, 栈顶值, op)) {
zhi_错误_不中止("无效的二进制操作数类型");
弹出堆栈值();
} 否则 如果 (bt1 == VT_指针 || bt2 == VT_指针) {
/* 至少一个操作数是一个指针 */
/*关系操作:必须同时是两个指针 */
如果 (符_ISCOND(op))
去向 std_op;
/* 如果两个指针都必须是'-'op */
如果 (bt1 == VT_指针 && bt2 == VT_指针) {
如果 (op != '-')
错误_打印("不能在这里使用指针");
如果 (栈顶值[-1].type.t & VT_变长数组) {
vla_运行时_指向的_类型的大小(&栈顶值[-1].type);
} 否则 {
压入整数常量(指定类型的_大小(&栈顶值[-1].type));
}
vrott(3);
生成_整数常量优化和与机器无关的选项(op);
栈顶值->type.t = VT_指针DIFF_T;
vswap();
通用_操作(符_指针除法);
} 否则 {
/* 正好一个指针:必须为'+'或'-'。 */
如果 (op != '-' && op != '+')
错误_打印("cannot use pointers here");
/* 将指针作为第一个操作数 */
如果 (bt2 == VT_指针) {
vswap();
t = t1, t1 = t2, t2 = t;
}
#如果 指针_大小 == 4
如果 ((栈顶值[0].type.t & VT_基本类型) == VT_长长整数)
/* XXX: 在这里截断,因为生成_独立于CPU的长期操作无法处理ptr + long long */
通用_转换_s(VT_整数);
#结束如果
type1 = 栈顶值[-1].type;
如果 (栈顶值[-1].type.t & VT_变长数组)
vla_运行时_指向的_类型的大小(&栈顶值[-1].type);
否则 {
u = 指定类型的_大小(&栈顶值[-1].type);
如果 (u < 0)
错误_打印("未知的数组元素大小");
#如果 指针_大小 == 8
压入长长整数(u);
#否则
/* XXX: 转换为int吗? (长大案)*/
压入整数常量(u);
#结束如果
}
通用_操作('*');
#如果已定义 配置_ZHI_边界检查
如果 (zhi_状态->执行_边界_检查器 && !需要_常量) {
/* 如果是有界指针,我们会生成一个特殊的代码来测试界 */
如果 (op == '-') {
压入整数常量(0);
vswap();
通用_操作('-');
}
生成_边界的_ptr_添加();
} 否则
#结束如果
{
生成_整数常量优化和与机器无关的选项(op);
}
type1.t &= ~VT_数组;
/* 如果 生成_整数常量优化和与机器无关的选项()交换操作数,则再次输入 */
栈顶值->type = type1;
}
} 否则 {
/* 浮点数只能用于一些操作 */
如果 (是_浮点型(combtype.t)
&& op != '+' && op != '-' && op != '*' && op != '/'
&& !符_ISCOND(op))
错误_打印("无效的二进制操作数");
否则 如果 (op == 符_SHR || op == 双符号_右位移 || op == 双符号_左位移) {
t = bt1 == VT_长长整数 ? VT_长长整数 : VT_整数;
如果 ((t1 & (VT_基本类型 | VT_无符号 | VT_位域)) == (t | VT_无符号))
t |= VT_无符号;
t |= (VT_长整数 & t1);
combtype.t = t;
}
std_op:
t = t2 = combtype.t;
/* XXX: 当前,一些未签名的操作是显式的,因此我们在此处对其进行修改 */
如果 (t & VT_无符号) {
如果 (op == 双符号_右位移)
op = 符_SHR;
否则 如果 (op == '/')
op = 符_无符除法;
否则 如果 (op == '%')
op = 符_无符取模运算;
否则 如果 (op == 符_LT)
op = 符号_ULT;
否则 如果 (op == 符_GT)
op = 符_UGT;
否则 如果 (op == 双符号_小于等于)
op = 符号_ULE;
否则 如果 (op == 双符号_大于等于)
op = 符号_UGE;
}
vswap();
通用_转换_s(t);
vswap();
/* 移位和long long的特殊情况:我们将移位保留为整数 */
如果 (op == 符_SHR || op == 双符号_右位移 || op == 双符号_左位移)
t2 = VT_整数;
通用_转换_s(t2);
如果 (是_浮点型(t))
生成_常量传播的浮点运算(op);
否则
生成_整数常量优化和与机器无关的选项(op);
如果 (符_ISCOND(op)) {
/* 关系运算:结果为整数 */
栈顶值->type.t = VT_整数;
} 否则 {
栈顶值->type.t = t;
}
}
// 确保我们已转换为右值:
如果 (栈顶值->r & VT_LVAL)
将rc寄存器值存储在栈顶值中(是_浮点型(栈顶值->type.t & VT_基本类型) ? 寄存器类_浮点 : 寄存器类_整数);
}
#如果 已定义 ZHI_TARGET_ARM64 || 已定义 ZHI_TARGET_RISCV64 || 已定义 ZHI_TARGET_ARM
#定义 生成_cvt_itof1 生成_整数转换为浮点
#否则
/* 泛型为无符号 long long 分支 */
静态 无类型 生成_cvt_itof1(整数型 t)
{
如果 ((栈顶值->type.t & (VT_基本类型 | VT_无符号)) ==
(VT_长长整数 | VT_无符号)) {
如果 (t == VT_浮点)
推送对_全局符号V_的引用(&函数_旧_类型, 符___floatundisf);
#如果 长双精度_大小 != 8
否则 如果 (t == VT_长双精度)
推送对_全局符号V_的引用(&函数_旧_类型, 符___floatundixf);
#结束如果
否则
推送对_全局符号V_的引用(&函数_旧_类型, 符___floatundidf);
vrott(2);
具体地址函数_调用(1);
压入整数常量(0);
将函数_返回寄存器_放入堆栈值(栈顶值, t);
} 否则 {
生成_整数转换为浮点(t);
}
}
#结束如果
#如果 已定义 ZHI_TARGET_ARM64 || 已定义 ZHI_TARGET_RISCV64
#定义 生成_cvt_ftoi1 生成_浮点转换为整数
#否则
/* generic ftoi 循环 无符号 long long 分支 */
静态 无类型 生成_cvt_ftoi1(整数型 t)
{
整数型 st;
如果 (t == (VT_长长整数 | VT_无符号)) {
/* 没有本地处理 */
st = 栈顶值->type.t & VT_基本类型;
如果 (st == VT_浮点)
推送对_全局符号V_的引用(&函数_旧_类型, 符___fixunssfdi);
#如果 长双精度_大小 != 8
否则 如果 (st == VT_长双精度)
推送对_全局符号V_的引用(&函数_旧_类型, 符___fixunsxfdi);
#结束如果
否则
推送对_全局符号V_的引用(&函数_旧_类型, 符___fixunsdfdi);
vrott(2);
具体地址函数_调用(1);
压入整数常量(0);
将函数_返回寄存器_放入堆栈值(栈顶值, t);
} 否则 {
生成_浮点转换为整数(t);
}
}
#结束如果
/* 字符型 / short的特殊延迟演员表 */
静态 无类型 强制_字符型短整型_转换(无类型)
{
整数型 sbt = BFGET(栈顶值->r, VT_强制转换) == 2 ? VT_长长整数 : VT_整数;
整数型 dbt = 栈顶值->type.t;
栈顶值->r &= ~VT_强制转换;
栈顶值->type.t = sbt;
通用_转换_s(dbt == VT_逻辑 ? VT_字节|VT_无符号 : dbt);
栈顶值->type.t = dbt;
}
静态 无类型 通用_转换_s(整数型 t)
{
C类型 type;
type.t = t;
type.ref = NULL;
通用_转换(&type);
}
/* 将“栈顶值”转换为“类型”。 禁止转换到位域。 */
静态 无类型 通用_转换(C类型 *type)
{
整数型 sbt, dbt, sf, df, c;
整数型 dbt_bt, sbt_bt, ds, ss, bits, trunc;
/* special delayed cast 循环 字符型/short */
如果 (栈顶值->r & VT_强制转换)
强制_字符型短整型_转换();
/* bitfields first get cast to ints */
如果 (栈顶值->type.t & VT_位域)
将rc寄存器值存储在栈顶值中(寄存器类_整数);
dbt = type->t & (VT_基本类型 | VT_无符号);
sbt = 栈顶值->type.t & (VT_基本类型 | VT_无符号);
如果 (sbt == VT_函数)
sbt = VT_指针;
again:
如果 (sbt != dbt) {
sf = 是_浮点型(sbt);
df = 是_浮点型(dbt);
dbt_bt = dbt & VT_基本类型;
sbt_bt = sbt & VT_基本类型;
c = (栈顶值->r & (VT_值掩码 | VT_LVAL | VT_符号)) == VT_VC常量;
#如果 !已定义 ZHI_是_本机 && !已定义 ZHI_IS_NATIVE_387
c &= (dbt != VT_长双精度) | !!不需要_代码生成;
#结束如果
如果 (c) {
/* constant 分支: we can 执行 it now */
/* XXX: in ISOC, cannot 执行 it 如果 error in convert */
如果 (sbt == VT_浮点)
栈顶值->c.ld = 栈顶值->c.f;
否则 如果 (sbt == VT_双精度)
栈顶值->c.ld = 栈顶值->c.d;
如果 (df) {
如果 (sbt_bt == VT_长长整数) {
如果 ((sbt & VT_无符号) || !(栈顶值->c.i >> 63))
栈顶值->c.ld = 栈顶值->c.i;
否则
栈顶值->c.ld = -(long double)-栈顶值->c.i;
} 否则 如果(!sf) {
如果 ((sbt & VT_无符号) || !(栈顶值->c.i >> 31))
栈顶值->c.ld = (uint32_t)栈顶值->c.i;
否则
栈顶值->c.ld = -(long double)-(uint32_t)栈顶值->c.i;
}
如果 (dbt == VT_浮点)
栈顶值->c.f = (float)栈顶值->c.ld;
否则 如果 (dbt == VT_双精度)
栈顶值->c.d = (double)栈顶值->c.ld;
} 否则 如果 (sf && dbt == VT_逻辑) {
栈顶值->c.i = (栈顶值->c.ld != 0);
} 否则 {
如果(sf)
栈顶值->c.i = 栈顶值->c.ld;
否则 如果 (sbt_bt == VT_长长整数 || (指针_大小 == 8 && sbt == VT_指针))
;
否则 如果 (sbt & VT_无符号)
栈顶值->c.i = (uint32_t)栈顶值->c.i;
否则
栈顶值->c.i = ((uint32_t)栈顶值->c.i | -(栈顶值->c.i & 0x80000000));
如果 (dbt_bt == VT_长长整数 || (指针_大小 == 8 && dbt == VT_指针))
;
否则 如果 (dbt == VT_逻辑)
栈顶值->c.i = (栈顶值->c.i != 0);
否则 {
uint32_t m = dbt_bt == VT_字节 ? 0xff :
dbt_bt == VT_短整数 ? 0xffff :
0xffffffff;
栈顶值->c.i &= m;
如果 (!(dbt & VT_无符号))
栈顶值->c.i |= -(栈顶值->c.i & ((m >> 1) + 1));
}
}
去向 done;
} 否则 如果 (dbt == VT_逻辑
&& (栈顶值->r & (VT_值掩码 | VT_LVAL | VT_符号))
== (VT_VC常量 | VT_符号)) {
/* addresses are considered non-zero (see zhitest.c:sinit23) */
栈顶值->r = VT_VC常量;
栈顶值->c.i = 1;
去向 done;
}
/* cannot generate code 循环 global or 静态 initializers */
如果 (仅_静态数据输出)
去向 done;
/* non constant 分支: generate code */
如果 (dbt == VT_逻辑) {
生成_测试_零(双符号_不等于);
去向 done;
}
如果 (sf || df) {
如果 (sf && df) {
/* convert from fp to fp */
生成_浮点转换为另一种浮点(dbt);
} 否则 如果 (df) {
/* convert 整数型 to fp */
生成_cvt_itof1(dbt);
} 否则 {
/* convert fp to 整数型 */
sbt = dbt;
如果 (dbt_bt != VT_长长整数 && dbt_bt != VT_整数)
sbt = VT_整数;
生成_cvt_ftoi1(sbt);
去向 again; /* may need 字符型/short cast */
}
去向 done;
}
ds = 基本类型_大小(dbt_bt);
ss = 基本类型_大小(sbt_bt);
如果 (ds == 0 || ss == 0) {
如果 (dbt_bt == VT_无类型)
去向 done;
投放_错误(&栈顶值->type, type);
}
如果 (是_枚举(type->t) && type->ref->c < 0)
错误_打印("转换为不完整类型");
/* same size and no sign conversion needed */
如果 (ds == ss && ds >= 4)
去向 done;
如果 (dbt_bt == VT_指针 || sbt_bt == VT_指针) {
zhi_警告("指针和不同大小的整数之间强制转换");
如果 (sbt_bt == VT_指针) {
/* put integer type to allow logical operations below */
栈顶值->type.t = (指针_大小 == 8 ? VT_长长整数 : VT_整数);
}
}
/* processor allows { 整数型 a = 0, b = *(字符型*)&a; }
That means that 如果 we cast to less width, we can just
change the type and read it still later. */
#定义 ALLOW_SUBTYPE_ACCESS 1
如果 (ALLOW_SUBTYPE_ACCESS && (栈顶值->r & VT_LVAL)) {
/* value still in memory */
如果 (ds <= ss)
去向 done;
/* ss <= 4 here */
如果 (ds <= 4) {
将rc寄存器值存储在栈顶值中(寄存器类_整数);
去向 done; /* no 64bit envolved */
}
}
将rc寄存器值存储在栈顶值中(寄存器类_整数);
trunc = 0;
#如果 指针_大小 == 4
如果 (ds == 8) {
/* generate high word */
如果 (sbt & VT_无符号) {
压入整数常量(0);
将rc寄存器值存储在栈顶值中(寄存器类_整数);
} 否则 {
堆栈转为寄存器并复制到另一个寄存器();
压入整数常量(31);
通用_操作(双符号_右位移);
}
构建长长整数(dbt);
} 否则 如果 (ss == 8) {
/* from long long: just take low order word */
整数扩展();
弹出堆栈值();
}
ss = 4;
#否则如果 指针_大小 == 8
如果 (ds == 8) {
/* need to convert from 32bit to 64bit */
如果 (sbt & VT_无符号) {
#如果 已定义(ZHI_TARGET_RISCV64)
/* RISC-V keeps 32bit vals in registers sign-extended.
So here we need a zero-extension. */
trunc = 32;
#否则
去向 done;
#结束如果
} 否则 {
生成_cvt_sxtw();
去向 done;
}
ss = ds, ds = 4, dbt = sbt;
} 否则 如果 (ss == 8) {
/* XXX some architectures (e.g. risc-v) would like it
better 循环 this merely being a 32-to-64 sign or zero-
extension. */
trunc = 32; /* zero upper 32 bits */
} 否则 {
ss = 4;
}
#结束如果
如果 (ds >= ss)
去向 done;
#如果 已定义 ZHI_TARGET_I386 || 已定义 ZHI_TARGET_X86_64 || 已定义 ZHI_TARGET_ARM64
如果 (ss == 4) {
生成_cvt_csti(dbt);
去向 done;
}
#结束如果
bits = (ss - ds) * 8;
/* 循环 无符号, 通用_操作 will convert SAR to SHR */
栈顶值->type.t = (ss == 8 ? VT_长长整数 : VT_整数) | (dbt & VT_无符号);
压入整数常量(bits);
通用_操作(双符号_左位移);
压入整数常量(bits - trunc);
通用_操作(双符号_右位移);
压入整数常量(trunc);
通用_操作(符_SHR);
}
done:
栈顶值->type = *type;
栈顶值->type.t &= ~ ( VT_常量 | VT_易变 | VT_数组);
}
/* 返回类型大小,编译时已知。 将对齐方式设置为“ a” */
静态_函数 整数型 类型_大小(C类型 *type, 整数型 *a)
{
符号 *s;
整数型 bt;
bt = type->t & VT_基本类型;
如果 (bt == VT_结构体) {
/* 结构体/联合体 */
s = type->ref;
*a = s->r;
返回 s->c;
} 否则 如果 (bt == VT_指针) {
如果 (type->t & VT_数组) {
整数型 ts;
s = type->ref;
ts = 类型_大小(&s->type, a);
如果 (ts < 0 && s->c < 0)
ts = -ts;
返回 ts * s->c;
} 否则 {
*a = 指针_大小;
返回 指针_大小;
}
} 否则 如果 (是_枚举(type->t) && type->ref->c < 0) {
返回 -1; /* incomplete 枚举 */
} 否则 如果 (bt == VT_长双精度) {
*a = 长双精度_对齐;
返回 长双精度_大小;
} 否则 如果 (bt == VT_双精度 || bt == VT_长长整数) {
#如果已定义 ZHI_TARGET_I386
#如果已定义 ZHI_TARGET_PE
*a = 8;
#否则
*a = 4;
#结束如果
#否则如果 已定义(ZHI_TARGET_ARM)
#如果已定义 ZHI_ARM_EABI
*a = 8;
#否则
*a = 4;
#结束如果
#否则
*a = 8;
#结束如果
返回 8;
} 否则 如果 (bt == VT_整数 || bt == VT_浮点) {
*a = 4;
返回 4;
} 否则 如果 (bt == VT_短整数) {
*a = 2;
返回 2;
} 否则 如果 (bt == VT_128位整数 || bt == VT_128位浮点) {
*a = 8;
返回 16;
} 否则 {
/* 字符型, 无类型, function, _Bool */
*a = 1;
返回 1;
}
}
/* 在运行时在值堆栈顶部已知的推送类型大小。 将对齐方式设置为“ a” */
静态_函数 无类型 vla_运行时_类型_大小(C类型 *type, 整数型 *a)
{
如果 (type->t & VT_变长数组) {
类型_大小(&type->ref->type, a);
vset(&int_type, VT_LOCAL|VT_LVAL, type->ref->c);
} 否则 {
压入整数常量(类型_大小(type, a));
}
}
/* 返回t的指针类型 */
静态 内联 C类型 *指定的_类型(C类型 *type)
{
返回 &type->ref->type;
}
/* 修改类型,使其成为类型的指针。 */
静态_函数 无类型 修改类型_指针类型(C类型 *type)
{
符号 *s;
s = 符号_压入栈(符号_字段, type, 0, -1);
type->t = VT_指针 | (type->t & VT_存储);
type->ref = s;
}
/* 如果type1和type2完全相同(包括限定符),则返回true.
*/
静态 整数型 是_兼容_类型(C类型 *type1, C类型 *type2)
{
返回 比较_2个类型(type1,type2,0);
}
/* 如果type1和type2相同,则返回true(忽略限定符).
*/
静态 整数型 是_兼容_不合格的_类型(C类型 *type1, C类型 *type2)
{
返回 比较_2个类型(type1,type2,1);
}
静态 无类型 投放_错误(C类型 *st, C类型 *dt)
{
类型_不兼容_错误(st, dt, "无法将 '%s' 转换为 '%s'");
}
/* 验证类型兼容性以将栈顶值存储为“ dt”类型 */
静态 无类型 验证_指定_转换(C类型 *dt)
{
C类型 *st, *type1, *type2;
整数型 dbt, sbt, qualwarn, lvl;
st = &栈顶值->type; /* source type */
dbt = dt->t & VT_基本类型;
sbt = st->t & VT_基本类型;
如果 (dt->t & VT_常量)
zhi_警告("只读位置的指定");
选择(dbt) {
分支 VT_无类型:
如果 (sbt != dbt)
错误_打印("赋予空表达");
跳出;
分支 VT_指针:
/* special cases 循环 pointers */
/* '0' can also be a pointer */
如果 (是_空_指针(栈顶值))
跳出;
/* accept implicit pointer to integer cast with warning */
如果 (是_整数_型(sbt)) {
zhi_警告("赋值使指针从整数开始而无需强制转换");
跳出;
}
type1 = 指定的_类型(dt);
如果 (sbt == VT_指针)
type2 = 指定的_类型(st);
否则 如果 (sbt == VT_函数)
type2 = st; /* a function is implicitly a function pointer */
否则
去向 error;
如果 (是_兼容_类型(type1, type2))
跳出;
循环 (qualwarn = lvl = 0;; ++lvl) {
如果 (((type2->t & VT_常量) && !(type1->t & VT_常量)) ||
((type2->t & VT_易变) && !(type1->t & VT_易变)))
qualwarn = 1;
dbt = type1->t & (VT_基本类型|VT_长整数);
sbt = type2->t & (VT_基本类型|VT_长整数);
如果 (dbt != VT_指针 || sbt != VT_指针)
跳出;
type1 = 指定的_类型(type1);
type2 = 指定的_类型(type2);
}
如果 (!是_兼容_不合格的_类型(type1, type2)) {
如果 ((dbt == VT_无类型 || sbt == VT_无类型) && lvl == 0) {
/* 无类型 * can match anything */
} 否则 如果 (dbt == sbt
&& 是_整数_型(sbt & VT_基本类型)
&& 是_枚举(type1->t) + 是_枚举(type2->t)
+ !!((type1->t ^ type2->t) & VT_无符号) < 2) {
/* 像GCC一样,默认情况下也不会仅针对指针目标签名的更改发出警告。 但是,请警告不同的基本类型,尤其是对于未签名的枚举和已签名的int目标。 */
} 否则 {
zhi_警告("从不兼容的指针类型指定");
跳出;
}
}
如果 (qualwarn)
zhi_警告("指定从指针目标类型中丢弃限定词");
跳出;
分支 VT_字节:
分支 VT_短整数:
分支 VT_整数:
分支 VT_长长整数:
如果 (sbt == VT_指针 || sbt == VT_函数) {
zhi_警告("赋值从指针进行整数转换而无需强制转换");
} 否则 如果 (sbt == VT_结构体) {
去向 case_VT_STRUCT;
}
/* XXX: more tests */
跳出;
分支 VT_结构体:
case_VT_STRUCT:
如果 (!是_兼容_不合格的_类型(dt, st)) {
error:
投放_错误(st, dt);
}
跳出;
}
}
静态 无类型 通用_指定类型_转换(C类型 *dt)
{
验证_指定_转换(dt);
通用_转换(dt);
}
/* 将栈顶值存储在堆栈中的左值中 */
静态_函数 无类型 将栈顶值_存储在堆栈左值(无类型)
{
整数型 sbt, dbt, ft, r, size, align, bit_size, bit_pos, delayed_cast;
ft = 栈顶值[-1].type.t;
sbt = 栈顶值->type.t & VT_基本类型;
dbt = ft & VT_基本类型;
验证_指定_转换(&栈顶值[-1].type);
如果 (sbt == VT_结构体) {
/* 如果 structure, only generate pointer */
/* structure assignment : generate memcpy */
/* XXX: 编译优化 如果 small size */
size = 类型_大小(&栈顶值->type, &align);
/* destination */
vswap();
#如果已定义 配置_ZHI_边界检查
如果 (栈顶值->r & VT_强制边界检查)
生成左值边界代码(); /* check would be wrong after 获取栈顶值地址() */
#结束如果
栈顶值->type.t = VT_指针;
获取栈顶值地址();
/* address of memcpy() */
#如果已定义 ZHI_ARM_EABI
如果(!(align & 7))
推送对_全局符号V_的引用(&函数_旧_类型, 符_memmove8);
否则 如果(!(align & 3))
推送对_全局符号V_的引用(&函数_旧_类型, 符_memmove4);
否则
#结束如果
/* Use memmove, rather than memcpy, as dest and src may be same: */
推送对_全局符号V_的引用(&函数_旧_类型, 符_memmove);
vswap();
/* source */
vpushv(栈顶值 - 2);
#如果已定义 配置_ZHI_边界检查
如果 (栈顶值->r & VT_强制边界检查)
生成左值边界代码();
#结束如果
栈顶值->type.t = VT_指针;
获取栈顶值地址();
/* type size */
压入整数常量(size);
具体地址函数_调用(3);
/* leave source on stack */
} 否则 如果 (ft & VT_位域) {
/* bitfield 存储 handling */
/* save lvalue as expression result (example: s.b = s.a = n;) */
vdup(), 栈顶值[-1] = 栈顶值[-2];
bit_pos = BIT_POS(ft);
bit_size = BIT_大小(ft);
/* remove bit field info to avoid loops */
栈顶值[-1].type.t = ft & ~VT_结构体_掩码;
如果 (dbt == VT_逻辑) {
通用_转换(&栈顶值[-1].type);
栈顶值[-1].type.t = (栈顶值[-1].type.t & ~VT_基本类型) | (VT_字节 | VT_无符号);
}
r = adjust_单字节(栈顶值 - 1, bit_pos, bit_size);
如果 (dbt != VT_逻辑) {
通用_转换(&栈顶值[-1].type);
dbt = 栈顶值[-1].type.t & VT_基本类型;
}
如果 (r == VT_结构体) {
单字节_存储_模式(bit_pos, bit_size);
} 否则 {
无符号 long long mask = (1ULL << bit_size) - 1;
如果 (dbt != VT_逻辑) {
/* mask source */
如果 (dbt == VT_长长整数)
压入长长整数(mask);
否则
压入整数常量((无符号)mask);
通用_操作('&');
}
/* shift source */
压入整数常量(bit_pos);
通用_操作(双符号_左位移);
vswap();
/* duplicate destination */
vdup();
vrott(3);
/* 加载 destination, mask and or with source */
如果 (dbt == VT_长长整数)
压入长长整数(~(mask << bit_pos));
否则
压入整数常量(~((无符号)mask << bit_pos));
通用_操作('&');
通用_操作('|');
/* 存储 result */
将栈顶值_存储在堆栈左值();
/* ... and discard */
弹出堆栈值();
}
} 否则 如果 (dbt == VT_无类型) {
--栈顶值;
} 否则 {
/* 编译优化 字符型/short casts */
delayed_cast = 0;
如果 ((dbt == VT_字节 || dbt == VT_短整数)
&& 是_整数_型(sbt)
) {
如果 ((栈顶值->r & VT_强制转换)
&& 基本类型_大小(dbt) > 基本类型_大小(sbt)
)
强制_字符型短整型_转换();
delayed_cast = 1;
} 否则 {
通用_转换(&栈顶值[-1].type);
}
#如果已定义 配置_ZHI_边界检查
/* bound check 分支 */
如果 (栈顶值[-1].r & VT_强制边界检查) {
vswap();
生成左值边界代码();
vswap();
}
#结束如果
将rc寄存器值存储在栈顶值中(返回类型t的_通用寄存器类(dbt)); /* generate value */
如果 (delayed_cast) {
栈顶值->r |= BFVAL(VT_强制转换, (sbt == VT_长长整数) + 1);
//zhi_警告("deley cast %x -> %x", sbt, dbt);
栈顶值->type.t = ft & VT_类型;
}
/* 如果 lvalue was saved on stack, must read it */
如果 ((栈顶值[-1].r & VT_值掩码) == VT_LLOCAL) {
堆栈值 sv;
r = 查找释放的rc寄存器_如果不存在就保存一个寄存器(寄存器类_整数);
sv.type.t = VT_指针DIFF_T;
sv.r = VT_LOCAL | VT_LVAL;
sv.c.i = 栈顶值[-1].c.i;
加载(r, &sv);
栈顶值[-1].r = r | VT_LVAL;
}
r = 栈顶值->r & VT_值掩码;
/* two word 分支 handling :
存储 second register at word + 4 (or +8 循环 x86-64) */
如果 (使用_两个单词的_类型(dbt)) {
整数型 load_type = (dbt == VT_128位浮点) ? VT_双精度 : VT_指针DIFF_T;
栈顶值[-1].type.t = load_type;
存储(r, 栈顶值 - 1);
vswap();
/* convert to 整数型 to increment easily */
栈顶值->type.t = VT_指针DIFF_T;
获取栈顶值地址();
压入目标地址类型常量(指针_大小);
通用_操作('+');
栈顶值->r |= VT_LVAL;
vswap();
栈顶值[-1].type.t = load_type;
/* XXX: it works because r2 is spilled last ! */
存储(栈顶值->r2, 栈顶值 - 1);
} 否则 {
/* single word */
存储(r, 栈顶值 - 1);
}
vswap();
栈顶值--; /* NOT 弹出堆栈值() because on x86 it would flush the fp stack */
}
}
/* post定义POST / PRE添加。 c是令牌++或- */
静态_函数 无类型 inc(整数型 post, 整数型 c)
{
测试_左值();
vdup(); /* 保存左值 */
如果 (post) {
堆栈转为寄存器并复制到另一个寄存器(); /* 重复值 */
vrotb(3);
vrotb(3);
}
/* 添加常量 */
压入整数常量(c - 符_MID);
通用_操作('+');
将栈顶值_存储在堆栈左值(); /* 存储值 */
如果 (post)
弹出堆栈值(); /* 如果发布操作,返回保存的值 */
}
静态_函数 无类型 解析_多_字符串 (动态字符串 *astr, 常量 字符型 *msg)
{
/* read the string */
如果 (单词编码 != 常量_字符串)
应为(msg);
动态字符串_初始化(astr);
判断 (单词编码 == 常量_字符串) {
/* XXX: add \0 handling too ? */
动态字符串_cat(astr, 单词值.str.data, -1);
带有宏替换的下个标记();
}
动态字符串_追加单个字符(astr, '\0');
}
/* 如果I> = 1且为2的幂,则返回log2(i)+1。 如果我为0,则返回0。 */
静态_函数 整数型 精确_对数2p1(整数型 i)
{
整数型 ret;
如果 (!i)
返回 0;
循环 (ret = 1; i >= 1 << 8; ret += 8)
i >>= 8;
如果 (i >= 1 << 4)
ret += 4, i >>= 4;
如果 (i >= 1 << 2)
ret += 2, i >>= 2;
如果 (i >= 1 << 1)
ret++;
返回 ret;
}
/* Parse __attribute__((...)) GNUC extension. */
静态 无类型 解析_属性(属性定义 *ad)
{
整数型 t, n;
动态字符串 astr;
redo:
如果 (单词编码 != 关键字_ATTRIBUTE1 && 单词编码 != 关键字_ATTRIBUTE2 && 单词编码 != 关键字_属性)
返回;
带有宏替换的下个标记();
跳过('(');
跳过('(');
判断 (单词编码 != ')') {
如果 (单词编码 < 符_识别)
应为("attribute name");
t = 单词编码;
带有宏替换的下个标记();
选择(t) {
分支 符_CLEANUP1:
分支 符_CLEANUP2:
{
符号 *s;
跳过('(');
s = 符号_查询(单词编码);
如果 (!s) {
zhi_警告("函数 '%s'是隐式声明",
取_单词字符串(单词编码, &单词值));
s = 外部_全局_符号(单词编码, &函数_旧_类型);
} 否则 如果 ((s->type.t & VT_基本类型) != VT_函数)
错误_打印("'%s' 未声明为函数", 取_单词字符串(单词编码, &单词值));
ad->cleanup_func = s;
带有宏替换的下个标记();
跳过(')');
跳出;
}
分支 符_CONSTRUCTOR1:
分支 符_CONSTRUCTOR2:
ad->f.func_ctor = 1;
跳出;
分支 符_DESTRUCTOR1:
分支 符_DESTRUCTOR2:
ad->f.func_dtor = 1;
跳出;
分支 符_ALWAYS_INLINE1:
分支 符_ALWAYS_INLINE2:
ad->f.func_alwinl = 1;
跳出;
分支 符_SECTION1:
分支 符_SECTION2:
跳过('(');
解析_多_字符串(&astr, "section name");
ad->section = 查找_段(zhi_状态, (字符型 *)astr.指向字符串的指针);
跳过(')');
动态字符串_释放(&astr);
跳出;
分支 符_ALIAS1:
分支 符_ALIAS2:
跳过('(');
解析_多_字符串(&astr, "alias(\"target\")");
ad->alias_target = /* save string as 标识符, 循环 later */
单词表_查找((字符型*)astr.指向字符串的指针, astr.字符串长度-1)->单词编码;
跳过(')');
动态字符串_释放(&astr);
跳出;
分支 符_VISIBILITY1:
分支 符_VISIBILITY2:
跳过('(');
解析_多_字符串(&astr,
"visibility(\"default|hidden|internal|protected\")");
如果 (!strcmp (astr.指向字符串的指针, "default"))
ad->a.visibility = STV_DEFAULT;
否则 如果 (!strcmp (astr.指向字符串的指针, "hidden"))
ad->a.visibility = STV_HIDDEN;
否则 如果 (!strcmp (astr.指向字符串的指针, "internal"))
ad->a.visibility = STV_INTERNAL;
否则 如果 (!strcmp (astr.指向字符串的指针, "protected"))
ad->a.visibility = STV_PROTECTED;
否则
应为("visibility(\"default|hidden|internal|protected\")");
跳过(')');
动态字符串_释放(&astr);
跳出;
分支 符_ALIGNED1:
分支 符_ALIGNED2:
如果 (单词编码 == '(') {
带有宏替换的下个标记();
n = 表达式_常量();
如果 (n <= 0 || (n & (n - 1)) != 0)
错误_打印("alignment must be a positive power of two");
跳过(')');
} 否则 {
n = MAX_ALIGN;
}
ad->a.aligned = 精确_对数2p1(n);
如果 (n != 1 << (ad->a.aligned - 1))
错误_打印("alignment of %d is larger than implemented", n);
跳出;
分支 符_PACKED1:
分支 符_PACKED2:
ad->a.packed = 1;
跳出;
分支 符_WEAK1:
分支 符_WEAK2:
ad->a.weak = 1;
跳出;
分支 符_UNUSED1:
分支 符_UNUSED2:
/* currently, no need to handle it because zhi does not
track unused objects */
跳出;
分支 符_NORETURN1:
分支 符_NORETURN2:
ad->f.func_noreturn = 1;
跳出;
分支 符_CDECL1:
分支 符_CDECL2:
分支 符_CDECL3:
ad->f.函数_调用 = 函数_CDECL;
跳出;
分支 符_标准调用1:
分支 符_标准调用2:
分支 符_标准调用3:
ad->f.函数_调用 = 函数_标准调用;
跳出;
#如果已定义 ZHI_TARGET_I386
上一篇: ArrayList集合
下一篇: jquery实现颜色拾取功能
推荐阅读
-
TCC(TinyC)编译器汉化(中文编译器、汉语编程)之四:语法分析上
-
TCC(TinyC)编译器汉化(中文编译器、汉语编程)之三:词法分析
-
TCC(TinyC)编译器汉化(中文编译器、汉语编程)之二:字符(token)汉化
-
TCC(TinyC)编译器汉化(中文编译器、汉语编程)之九:核心库源码
-
TCC(TinyC)编译器汉化(中文编译器、汉语编程)之七:中间语言生成器
-
TCC(TinyC)编译器汉化(中文编译器、汉语编程)之六:中间操作码
-
TCC(TinyC)编译器汉化(中文编译器、汉语编程)之八:汇编处理
-
TCC(TinyC)编译器汉化(中文编译器、汉语编程)之一:主文件汉化
-
TCC(TinyC)编译器汉化(中文编译器、汉语编程)之五:语法分析下