欢迎您访问程序员文章站本站旨在为大家提供分享程序员计算机编程知识!
您现在的位置是: 首页

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