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;