关于simplescalar是什么,干什么,我就不介绍了。开门见山,直接开始。
泰勒斯说万物源与水,C语言说万物源于main()(当然这个entry是main还是要由ld.script决定),二话不说直接进main()
找到main.c,在main()的函数体里面都是_init(),都是模拟器的初始化,
真正进入执行的是sim-main() ,make决定了到达了哪个执行主体里面,sim-safe,sim-outorder,sim-fast.etc.
我们选择最简单的一个sim-fast.c
追踪到sim-main(),再次回避困难,直接进入#ifdef的else(还不清楚JUMP_TABLE是用来干什么的)
#else /* !USE_JUMP_TABLE */部分
在短暂的选择Alpha格式是否pre-decode的过程之后,进入真正的decode阶段。 通过以下的语句
/* load instruction */
MD_FETCH_INST(inst, mem, regs.regs_PC);
/* decode the instruction */
MD_SET_OPCODE(op, inst);
载入inst -> op, switch(op)进入decode,
这里有3个技巧,
1.#define DEFINST(OP,MSK,NAME,OPFORM,RES,FLAGS,O1,O2,I1,I2,I3)\
case OP:\
SYMCAT(OP,_IMPL);\
break; Macro DEFINST的定义,与下面include的结合,完成了case的相应功能。
2.include “machine.def”的加入,与Macro DEFINST的结合,完成case的功能。
3. SYMCAT(OP,_IMPL) Macro的调用,把case中的OP转化为相应的指令。
3点结合起来为,载入machine.def与ISA相关的控制程序,switch(op){#include”machine.def”}
通过Macro转化为 #define LDA_IMPL \
{ \
SET_GPR(RA, GPR(RB) + SEXT(OFS)); \
}
case LDA:
LDA_IMPL;
break;
完成之后,
/* execute next instruction */
regs.regs_PC = regs.regs_NPC;
regs.regs_NPC += sizeof(md_inst_t);
进入下一个while死循环。