LCC为了生成不同机器的目标代码,它提供了一个接口给后端的代码生成,以便可以只修改后端,就可以达到生成不同的机器代码。它的接口如下:
#001 //后端代码生成接口,可以写生成不同的目标代码。
#002 //
#003 //蔡军生 2007/07/20 QQ: 9073204
#004 //
#005 typedef struct {
#006 //对齐方式的最大字节。
#007 unsigned char max_unaligned_load;
#008
#009 //根据数据类型选择寄存器类型。
#010 Symbol (*rmap)(int);
#011
#012 //给定单元取数到寄存器的代码。
#013 void (*blkfetch)(int size, int off, int reg, int tmp);
#014
#015 //将给出寄存器内容保存到单元里。
#016 void (*blkstore)(int size, int off, int reg, int tmp);
#017
#018 //生成一个循环来复制内存里的内容。
#019 void (*blkloop)(int dreg, int doff,
#020 int sreg, int soff,
#021 int size, int tmps[]);
#022
#023 //每个节点的指令选择
#024 void (*_label)(Node);
#025
#026 //获取指令编码。
#027 int (*_rule)(void*, int);
#028
#029 short **_nts;
#030
#031 //根据指令模板保存子节点到kids中
#032 void (*_kids)(Node, int, Node*);
#033
#034 //指令模板字符串数组。
#035 char **_string;
#036
#037 //指令模板数组.
#038 char **_templates;
#039
#040 //是指令还是参数的标记数组。
#041 char *_isinstruction;
#042
#043 //分类名称。
#044 char **_ntname;
#045
#046 //复杂的指令生成函数。
#047 void (*emit2)(Node);
#048
#049 //计算下一个参数的寄存器或者内存单元。
#050 void (*doarg)(Node);
#051
#052 //计算那些需要放到特定寄存器的树节点。
#053 void (*target)(Node);
#054
#055 //寄存器溢出后,重新加载内存单元数据到寄存器。
#056 void (*clobber)(Node);
#057
#058 } Xinterface;