Tr_exp Tr_simpleVar(Tr_access tr_acc, Tr_level level){ //printf("Tr_simpleVar\n"); F_access access = tr_acc->access; T_exp exp; if(level!=tr_acc->level){ int cnt = 0; //printf(" (Tr_simpleVar: Follow static link %d)\n", ++cnt); //Follow the static link exp = F_Exp(F_staticLink(), T_Temp(F_FP())); level = level->parent; //TODO check: level cannot be null while(level!=tr_acc->level){ //printf(" (Tr_simpleVar: Follow static link %d)\n", ++cnt); exp = F_Exp(F_staticLink(), exp); level = level->parent; //TODO check: level cannot be null } exp = F_Exp(access, exp); } else { //printf(" (Tr_simpleVar: Don't follow link)\n"); //Just use the current frame pointer exp = F_Exp(access, T_Temp(F_FP())); } return Tr_Ex(exp); }
Temp_map F_TempMap() { static Temp_map m = NULL; if (!m) { m = Temp_empty(); Temp_enter(m, F_FP(), "fp"); Temp_enter(m, F_SP(), "sp"); Temp_enter(m, F_RV(), "rv"); Temp_enter(m, F_ZERO(), "zf"); Temp_tempList args = F_ARGS(); Temp_tempList callee = F_CALLEE(); Temp_tempList caller = F_CALLER(); string buf[10]; for (int i=0; args; args = args->tail, i++) { sprintf(buf, "args%d", i); Temp_enter(m, args, ""); } for (int i=0; callee; callee = callee->tail, i++) { sprintf(buf, "callee%d", i); Temp_enter(m, args, ""); } for (int i=0; caller; caller = caller->tail, i++) { sprintf(buf, "caller%d", i); Temp_enter(m, args, ""); } } return Temp_layerMap(m, Temp_name()); }
static Temp_tempList F_make_calle_saves(void) { Temp_temp rbx = Temp_newtemp(), r12 = Temp_newtemp(), r13 = Temp_newtemp(), r14 = Temp_newtemp(), r15 = Temp_newtemp(); F_add_to_map("rbx", rbx); F_add_to_map("r12", r12); F_add_to_map("r13", r13); F_add_to_map("r14", r14); F_add_to_map("r15", r15); return TL(F_SP(), TL(F_FP(), TL(rbx, TL(r12, TL(r13, TL(r14, TL(r15, NULL))))))); }
static Temp_tempList F_special_registers(void) { static Temp_tempList spregs = NULL; if (!spregs) { spregs = Temp_TempList(F_SP(), Temp_TempList(F_FP(), Temp_TempList(F_RV(), NULL))); } return spregs; }
Tr_exp Tr_callExp(Tr_level caller_lvl, Tr_level callee_lvl, Temp_label fun_label, Tr_exp* argv, int args){ int z = 0; int cnt = 0; debug("caller = %d; callee = %d", caller_lvl->depth, callee_lvl->depth); //1) Get the static link for the called function T_exp slk; if(caller_lvl!=callee_lvl){ debug(" (Tr_callExp: Follow static link %d)", ++cnt); //Follow the static link slk = F_Exp(F_staticLink(), T_Temp(F_FP())); caller_lvl = caller_lvl->parent; //TODO check: caller_lvl cannot be null while(caller_lvl!=callee_lvl){ debug(" (Tr_callExp: Follow static link %d)", ++cnt); slk = F_Exp(F_staticLink(), slk); caller_lvl = caller_lvl->parent; //TODO check: caller_lvl cannot be null } } else { debug(" (Tr_callExp: Don't follow link)"); //Just use the current frame pointer slk = F_Exp(F_staticLink(), T_Temp(F_FP())); } debug("Static link done"); //2) Create the argument list, including the static link //2.1) Allocate memory T_expList listp_head = NULL; if(args>0){ /* Problematic on 64-bit machine int node_size = sizeof(struct T_expList_)/8; T_expList listp = (T_expList)checked_malloc((args+1) * sizeof(struct T_expList_)); listp_head = listp; //2.2) Initialize listp->head = slk; listp->tail = listp + node_size; listp = listp->tail; int i = 0; while(i < args){ //Let head point to the next argument listp->head = unEx(*argv); //Let tail point to next head listp->tail = listp + node_size; //Move the base pointer over one node if(i<args-1){ listp = listp->tail; argv++; } i++; } listp->tail = NULL; */ T_expList listp = (T_expList)checked_malloc(sizeof(struct T_expList_)); listp_head = listp; //2.2) Initialize listp->head = slk; listp->tail = NULL; int i = 0; while(i < args){ //Create new list on the tail listp->tail = (T_expList)checked_malloc(sizeof(struct T_expList_)); listp = listp->tail; //Let head point to the next argument listp->head = unEx(*argv); //Let tail point to next head listp->tail = NULL; //Get next argument argv++; i++; } } debug("argument list prepared"); //3) Generate IR T_exp exp = T_Call(T_Name(fun_label), listp_head); /* int i = 0; while(listp_head!=NULL){ printf("arg %d\n", i++);listp_head=listp_head->tail; } */ debug("call done"); return Tr_Ex(exp); }