![]() | ![]() | ![]() | Handling Address Temporaries |
a[3*i+j]
operand_desc *expr_gen(node * expr, int useAddr) { operand_desc *left_loc, *right_loc, *new_loc; switch (expr->internal.type) { . . . case Nplus: left_loc = expr_gen(expr->internal.child[0], useAddr); right_loc = expr_gen(expr->internal.child[1], useAddr && ! isAddr(left_loc)); if is_temporary(left_loc) { output ``add right_loc,left_loc''; freeOp(right_loc); return left_loc; } else if is_temporary(right_loc) { output ``add left_loc,right_loc''; freeOp(left_loc); return right_loc; } else { new_loc = get_temporary( useAddr ); output ``move left_loc,new_loc''; output ``add right_loc,new_loc''; freeOp(left_loc); freeOp(right_loc); return new_loc; } break; . . .
In this case, the routine that is eventually asked to generate an instruction referencing the operand may first have to generate instructions to load the needed static link pointer.
move | static-link-pointer,a1 |
code for big expression | |
add | disp(a1),result-of-big-expr |
code for big expression | |
move | static-link-pointer,a1 |
add | disp(a1),result-of-big-expr |
The second approach reduces the total demand for registers by reducing the range of instruction during which a register must be reserved for a base address.
a[i]+ (a[j] + (a[k] + ( a[l] + ( a[m] + a[n]))))
![]() | ![]() | ![]() | Handling Address Temporaries |