//Refer to FIGURE 7.4 (P168) //struct {T_stm left, right;} SEQ; T_stm_ //struct {T_stm stm; T_exp exp;} ESEQ; T_exp_ void Tr_recordExp_app(Tr_exp te, Tr_exp init, bool last){ debug("Tr_recordExp_app %s", last==TRUE?"(LAST)":""); //1) Retrieve T_stm, which should be an ESEQ T_exp ex = unEx(te); //2) Prepare for iteration //The first sub-node for field initialization T_stm* right = &(ex->u.ESEQ.stm->u.SEQ.right); //The register saving the base addr of record var T_exp temp = ex->u.ESEQ.exp; //3) Iterate over the SEQs, until the rightmost node is found, which should be NULL int i = 0; while(*right!=NULL){ right = &((*right)->u.SEQ.right); i++; } //4) Create a new sub-node to initialize the next field T_stm move = T_Move(T_Mem(T_Binop(T_plus, temp, T_Const(i*F_wordSize))), unEx(init)); //5) Substitue the rightmode node if(!last){ *right = T_Seq(move, NULL); } else { *right = move; } }
T_exp F_Exp(F_access access, T_exp framePtr) { if (access->kind == inFrame) { return T_Mem(T_Binop(T_plus, framePtr, T_Const(access->u.offset))); } else { return T_Temp(access->u.reg); } }
Tr_exp Tr_arithExp(A_oper oper, Tr_exp left, Tr_exp right){ T_exp exp; switch(oper){ case A_plusOp: exp = T_Binop(T_plus, unEx(left), unEx(right)); break; case A_minusOp: exp = T_Binop(T_minus, unEx(left), unEx(right)); break; case A_timesOp: exp = T_Binop(T_mul, unEx(left), unEx(right)); break; case A_divideOp: exp = T_Binop(T_div, unEx(left), unEx(right)); break; default: //Should not reach here printf("Illegal arithmetic operator"); exit(2); } return Tr_Ex(exp); }
Tr_exp Tr_forExp(Tr_exp var, Tr_exp low, Tr_exp high, Tr_exp body){ debug("Tr_forExp"); T_stm st; T_exp v = unEx(var); Temp_label t = Temp_newlabel(); Temp_label f = LL_peek();//Get done label from the list, which should have been prepared before this function is called. Temp_label start = Temp_newlabel(); T_stm cond = T_Cjump(T_le, v, unEx(high), t, f); /* T_Move var <- low T_Label start T_CJump var <= high, t, f T_Label(t) body T_Move var + 1 T_Jump start T_Label(f) */ st = T_Seq(T_Move(v, unEx(low)), T_Seq(T_Label(start), T_Seq(cond, T_Seq(T_Label(t), T_Seq(unNx(body), T_Seq(T_Move(v, T_Binop(T_plus, v, T_Const(1))), T_Seq( T_Jump( T_Name(start), Temp_LabelList(start, NULL) ), T_Label(f) ) ) ) ) ) ) ); //Pop the label as it's no longer used LL_pop(); return Tr_Nx(st); }
Tr_exp Tr_arrayVar(Tr_exp base, Tr_exp offset_exp){ return Tr_Ex(T_Mem(T_Binop(T_plus, unEx(base), T_Binop(T_mul, unEx(offset_exp), T_Const(F_wordSize))))); }
Tr_exp Tr_fieldVar(Tr_exp base, int field_offset){ return Tr_Ex(T_Mem(T_Binop(T_plus, unEx(base), T_Const(field_offset * F_wordSize)))); }
T_exp F_Exp(F_access acc, T_exp framePtr) { if (acc->kind == inFrame) return T_Mem(T_Binop(T_plus, T_Const(acc->u.offset), framePtr)); else return T_Temp(acc->u.reg); }