LCC编译器的源程序分析(47)计算需要使用栈大小
2007-06-28 22:55
363 查看
计算栈的大小,是通过后端接口的代码来完成计算的。栈的大小,主要就是局部变量、临时变量、调用参数和返回值等使用的字节大小,如果变量可以放到寄存器,就不需加到栈的大小里。上面已经看了下面的代码:
#044 case Blockbeg:
#045 {
#046 Symbol *p = cp->u.block.locals;
#047 (*IR->blockbeg)(&cp->u.block.x);
#048 for ( ; *p; p++)
#049 if ((*p)->ref != 0.0)
#050 (*IR->local)(*p);
#051 else if (glevel) (*IR->local)(*p);
#052 }
#053 break;
现在,就接着查看IR->blockbeg接口的函数,它的代码如下:
#001 void blockbeg(Env *e) {
#002 e->offset = offset;
#003 e->freemask[IREG] = freemask[IREG];
#004 e->freemask[FREG] = freemask[FREG];
#005 }
第2行是保存当前使用栈的大小。
第3行是保存使用的寄存器。
第4行是保存自由的寄存器。
IR->local接口的代码如下:
#001 static void local(Symbol p) {
#002 if (isfloat(p->type))
#003 p->sclass = AUTO;
#004 if (askregvar(p, (*IR->x.rmap)(ttob(p->type))) == 0) {
#005 assert(p->sclass == AUTO);
#006 offset = roundup(offset + p->type->size,
#007 p->type->align < 4 ? 4 : p->type->align);
#008 p->x.offset = -offset;
#009 p->x.name = stringd(-offset);
#010 }
#011 }
这个函数local是计算一个符号使用栈的开始位置。
第2行判断是否是浮点数据类型,如果是就设置为自动存储类型。
第4行是查询这个符号是否可以使用寄存器,如果不使用寄存器,就放置在栈里,然后就添加栈的大小。
第6行是按4字节对齐取整栈的开始位置。
第8行和第9行是保存变量保存在栈的开始位置。
下一节再来分析寄存器分配部分的函数。
#044 case Blockbeg:
#045 {
#046 Symbol *p = cp->u.block.locals;
#047 (*IR->blockbeg)(&cp->u.block.x);
#048 for ( ; *p; p++)
#049 if ((*p)->ref != 0.0)
#050 (*IR->local)(*p);
#051 else if (glevel) (*IR->local)(*p);
#052 }
#053 break;
现在,就接着查看IR->blockbeg接口的函数,它的代码如下:
#001 void blockbeg(Env *e) {
#002 e->offset = offset;
#003 e->freemask[IREG] = freemask[IREG];
#004 e->freemask[FREG] = freemask[FREG];
#005 }
第2行是保存当前使用栈的大小。
第3行是保存使用的寄存器。
第4行是保存自由的寄存器。
IR->local接口的代码如下:
#001 static void local(Symbol p) {
#002 if (isfloat(p->type))
#003 p->sclass = AUTO;
#004 if (askregvar(p, (*IR->x.rmap)(ttob(p->type))) == 0) {
#005 assert(p->sclass == AUTO);
#006 offset = roundup(offset + p->type->size,
#007 p->type->align < 4 ? 4 : p->type->align);
#008 p->x.offset = -offset;
#009 p->x.name = stringd(-offset);
#010 }
#011 }
这个函数local是计算一个符号使用栈的开始位置。
第2行判断是否是浮点数据类型,如果是就设置为自动存储类型。
第4行是查询这个符号是否可以使用寄存器,如果不使用寄存器,就放置在栈里,然后就添加栈的大小。
第6行是按4字节对齐取整栈的开始位置。
第8行和第9行是保存变量保存在栈的开始位置。
下一节再来分析寄存器分配部分的函数。
相关文章推荐
- LCC编译器的源程序分析(47)计算需要使用栈大小
- LCC编译器的源程序分析(46)计算需要使用栈大小
- LCC编译器的源程序分析(46)计算需要使用栈大小
- LCC编译器的源程序分析(46)计算需要使用栈大小
- LCC编译器的源程序分析(47)计算需要使用栈大小
- [转载]LCC编译器的源程序分析(47)计算需要使用栈大小
- [转载]LCC编译器的源程序分析(46)计算需要使用栈大小
- [转载]LCC编译器的源程序分析(58)后端使用的节点结构
- LCC编译器的源程序分析(58)后端使用的节点结构
- LCC编译器的源程序分析(58)后端使用的节点结构
- LCC编译器的源程序分析(58)后端使用的节点结构
- LCC编译器的源程序分析(1)C编译器的目标
- pbc-0.5.12 使用arm编译器编译 过程中出现extend_printf.c中错误,需要替换extend_printf.c文件
- LCC编译器的源程序分析(5)行号同步与类型初始化
- LCC编译器的源程序分析(6)词法分析
- [转载]LCC编译器的源程序分析(9)声明分析
- [转载]LCC编译器的源程序分析(15)结构类型成员的声明
- [转载]LCC编译器的源程序分析(25)赋值表达式
- [转载]LCC编译器的源程序分析(33)break语句
- [转载]LCC编译器的源程序分析(41)赋值表达式的有向无环图