int-code-util.pl 3.54 KB
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
%
% allocAddr/3: Allocate an address for the result of an expression.

allocAddr(_, Addr, S)			% Destination already known
	! <= nonvar(Addr).

allocAddr(exp(type(map(_,_), Sz), id(X)), address(X), S)
	! <= nonvar(X).

allocAddr(exp(_, id(X)), Addr, S)	% In case it's a named symbol
	<-> lookup1(address(Addr), A)
	<=  nonvar(X), lookup(id(X)-A, S).

allocAddr(exp(_, lit(X)), lit(X), S)	% A literal: take it as it is
	! <= nonvar(X).

allocAddr(exp(type(_,Sz), _), Addr, S)	% Anything else: need a temporary
	<-> allocTemp1(Sz, Addr, S).


%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
%
% allocAddrNoReg/3: Allocate an address for the result of an expression.
%                   Don't allow registers.
%

allocAddrNoReg(_, Addr, S)		% Destination already known
	! <= nonvar(Addr).

allocAddrNoReg(exp(type(map(_,_), Sz), id(X)), address(X), S)
	! <= nonvar(X).

allocAddrNoReg(exp(_, id(X)), Addr, S)	% In case it's a named symbol
	<-> lookup1(address(Addr), A)
	<=  nonvar(X), lookup(id(X)-A, S).

allocAddrNoReg(exp(_, lit(X)), lit(X), S) % A literal: take it as it is
	! <= nonvar(X).

allocAddrNoReg(exp(type(_,Sz), _), Addr, S) % Anything else: need a temporary
	<-> allocTempNoReg1(Sz, Addr, S).


%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
%
% freeAddr/2: Free an address in case it's a temporary.
%

freeAddr(t(Sz, A, L), S) ! <= freeTemp(t(Sz, A, L), S).
freeAddr(_,           S) !.

/*****************************************************************************/
/*      								     */
/*   Projecto de Compiladores ---------------------------------- VSPL        */
/*		                                        	 Level 0     */
/*		                                        		     */
/*   Code generation (utilities).					     */
/*		        						     */
/*						    Salvador Pinto Abreu     */
/*									     */
/*****************************************************************************/


%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
%
% allocTemp1/3: allocate a temporary if it's not already chosen.
%

allocTemp1(Sz, Temp, S) ! <= nonvar(Temp).
allocTemp1(Sz, Temp, S) <-> allocTemp(Sz, Temp, S).


%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
%
% allocTempNoReg1/3: allocate a temporary if it's not already chosen. Avoid
%		     registers.
%

allocTempNoReg1(Sz, Temp, S) ! <= nonvar(Temp).
allocTempNoReg1(Sz, Temp, S) <-> allocTempNoReg(Sz, Temp, S).


%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
%
% getRelOpcode/2: Obtain VAX opcode for relationals.
%

getRelOpcode(le, jleq).
getRelOpcode(lt, jlss).
getRelOpcode(eq, jeql).
getRelOpcode(ne, jneq).
getRelOpcode(ge, jgeq).
getRelOpcode(gt, jgtr).


%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
%
% getInvRelOpcode/2: Obtain inverse VAX opcode for relationals.
%

getInvRelOpcode(le, jgtr).
getInvRelOpcode(lt, jgeq).
getInvRelOpcode(eq, jneq).
getInvRelOpcode(ne, jeql).
getInvRelOpcode(ge, jlss).
getInvRelOpcode(gt, jleq).


%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
%
% genLabel/1: Generate a unique label.
%

resetLabels(Root) <-> try retract(curLabel(Root,_)), asserta(curLabel(Root,0)).

newLabel(Root, N) <-> retract(curLabel(Root,M)), N is M+1,
		      assert(curLabel(Root,N)).

genLabel(R, N, L) <-> name(R, RN), name(N, NN),
		      append("L", RN, X0), append(X0, "_", X1),
		      append(X1, NN, X2), name(L, X2).