Statements, such as for-loop and while-loop, are translated into IR statements that contain jumps and conditional jumps.
The while loop while c do body;
is evaluated in the following way:
loop: if not(c) goto cont else goto done
cont: body
goto loop
done:
which corresponds to the following IR:
SEQ(LABEL(loop),
CJUMP(EQ,c,0,NAME(done),NAME(cont)),
LABEL(cont),
s,
JUMP(NAME(loop)),
LABEL(done))
The for statement for i:=lo to hi do body
is evaluated in the following way:
i := lo
j := hi
if i>j goto done
loop: body
i := i+1
if i<=j goto loop
done:
The break statement is translated into a JUMP. The compiler
keeps track which label to JUMP to on a ``break'' statement by
maintaining a stack of labels that holds the ``done:'' labels of the
for- or while-loop. When it compiles a loop, it pushes the label in
the stack, and when it exits a loop, it pops the stack. The
break statement is thus translated into a JUMP to the label at
the top of the stack.
A function call f(a1,...,an) is translated into the IR
CALL(NAME(l_f),[sl,e1,...,en]), where l_r is the label
of the first statement of the f code, sl is the static
link, and ei is the IR for ai. For example, if the
difference between the static levels of the caller and callee is one,
then sl is MEM(+(TEMP(fp),CONST(static))), where
static is the offset of the static link in a frame. That is, we
follow the static link once. The code generated for the body of the
function f is a sequence which contains the prolog, the code of
f, and the epilogue, as it was discussed in Section 7.
For example, suppose that records and vectors are implemented as pointers (i.e. memory addresses) to dynamically allocated data in the heap. Consider the following declarations:
struct { X: int, Y: int, Z: int } S; /* a record */
int i;
int V[10][10]; /* a vector of vectors */
where the variables S, i, and V are stored
in the current frame with offsets -16, -20, and -24 respectively.
By using the following abbreviations:
S = MEM(+(TEMP(fp),CONST(-16))) I = MEM(+(TEMP(fp),CONST(-20))) V = MEM(+(TEMP(fp),CONST(-24)))
we have the following IR translations:
S.Z+S.X
--> +(MEM(+(S,CONST(8))),MEM(S))
if (i<10) then S.Y := i else i := i-1
--> SEQ(CJUMP(LT,I,CONST(10),trueL,falseL),
LABEL(trueL),
MOVE(MEM(+(S,CONST(4))),I),
JUMP(exit),
LABEL(falseL),
MOVE(I,-(I,CONST(1))),
JUMP(exit),
LABEL(exit))
V[i][i+1] := V[i][i]+1
--> MOVE(MEM(+(MEM(+(V,*(I,CONST(4)))),*(+(I,CONST(1)),CONST(4)))),
MEM(+(MEM(+(V,*(I,CONST(4)))),*(I,CONST(4)))))
for i:=0 to 9 do V[0][i] := i
--> SEQ(MOVE(I,CONST(0)),
MOVE(TEMP(t1),CONST(9)),
CJUMP(GT,I,TEMP(t1),done,loop),
LABEL(loop),
MOVE(MEM(+(MEM(V),*(I,CONST(4)))),I),
MOVE(I,+(I,CONST(1))),
CJUMP(LEQ,I,TEMP(t1),loop,done),
LABEL(done))