/*
 * File:
 *   frame.h
 * Author:
 *   Samuel A. Rebelsky, based on code from Andrew Appel
 * Version:
 *   0.4 of 7 December 1998
 * Description:
 *   A header file describing the stack-frame utilities needed for
 *   Tiger compilers.
 * Required headers:
 *   temp.h - defines Temp_label and string
 *   tree.h - defines T_exp
 *   util.h - defines U_boolList
 * Note:
 *   The "full" version of frame.h is given on p. 268 of the Green
 *   book.  This one was developed somewhat differently.
 * History:
 *   20 November 1998
 *     First version (0.1).
 *   23 November 1998
 *     Updated description of registers() function.
 *   07 December 1998
 *     Changed some return types, so that we don't need assem.h.
 *     Re-updated description of registers() function.
 *   12 December 1998 (Version 0.4)
 *     Fixed some typos
 */

/* The following lines ensure that this gets loaded only once. */

#ifndef _FRAME_H_
#define _FRAME_H_

/***********************************************************
 * Constants *
 *************/ 

/*
 * The size of words (in bytes).
 * Green book, p. 159.
 */
extern const int F_wordSize;

/*
 * A map from special registers to their names.
 * Green book, p. 214.
 */
Temp_map F_tempMap;


/***********************************************************
 * Types *
 *********/ 

/* 
 * A frame.  Frames are used to gather information about memory
 * usage in functions.  Since different architectures will have
 * different requirements, we keep these as generic as possible.
 * Green book, p. 136.
 */
typedef struct F_frame_ *F_frame;

/*
 * A storage location (or something that allows us to access a
 * storage location).
 * Green book, p. 136.
 */
typedef struct F_access_ *F_access;

/*
 * A list of storage locations.
 * Green book, p. 136.
 */
typedef struct F_accessList_ *F_accessList;
struct F_accessList_ {
  F_access head;	/* The first element. */
  F_accessList tail;	/* The rest. */
};

/*
 * A code fragment.  Used because we often generate fragments that
 * have no clear place in the program.
 * Green book, p. 172.
 */
typedef struct F_frag_ *F_frag;
struct F_frag_ {
  enum { F_stringFrag, F_procFrag } kind; 
  union {
    struct { Temp_label label; string str; } stringg;
    struct { T_stm body; F_frame frame; } proc;
  } u;
}; /* struct F_frag_ */

/*
 * A list of code fragments.
 * Green book, p. 173.
 */
typedef struct F_fragList_ *F_fragList;
struct F_fragList_ { 
  F_frag head;
  F_fragList tail;
}; /* F_fragList_ */


/***********************************************************
 * Functions *
 *************/ 

/*
 * Create a new frame, given information about the parameters to
 * the function.  The booleans indicate whether or not the parameters
 * "escape" (must be stored in the frame, rather than in registers).
 * Green book, p. 136.
 */
F_frame F_newFrame(Temp_label name, U_boolList formals);

/*
 * Get the label associated with the frame.  Used when calling the
 * function.  (It's not clear that this really belongs here, but
 * that's how Appel designed it.)
 * Green book, p. 136.
 */
Temp_label F_name(F_frame f);

/*
 * Get the locations associated with the parameters.  Presumably,
 * this is only used by the stuff that manipulates the body of the
 * corresponding function.
 * Green book, p. 136.
 */
F_accessList F_formals(F_frame f);

/*
 * Allocate a new local storage location, which might be a register
 * or space on the frame (or ....).  In doing so, indicate whether it
 * must be stored in the frame.
 * Green book, p. 136.
 */
F_access F_allocLocal(F_frame f, bool escapes);

/*
 * A list of all the register names on the machine.
 * Appears in Green book, p. 268.  Defined on p. 267.
 *
 * Note that this should not be needed for your compiler, and
 * is part of the register allocation process.
 */
Temp_tempList F_registers(void);

/*
 * Compute the appropriate IRT for an access.  This might be a TEMP,
 * or it might be a memory location.  Requires the qualified base of
 * the frame, which is computed at a different level (by translate.c).
 * Green book, p. 159.
 */
T_exp F_Exp(F_access acc, T_exp framePtr);

/*
 * Get the frame pointer.
 * Green book, p. 159.
 */
Temp_temp F_FP(void);

/*
 * Get the return-address register.
 * Green book, p. 268.  Defined earlier?
 */
Temp_temp F_RA(void);

/*
 * Get the return-value register.
 * Green book, p. 172.
 */
Temp_temp F_RV(void);

/*
 * Get the stack pointer.
 * Green book, p. 268.  Defined earlier?
 */
Temp_temp F_SP(void);

/*
 * Some special temporary?  Perhaps register 0?
 * Green book, p. 268.  Defined earlier?
 */
Temp_temp F_ZERO(void);

/*
 * Call an external function (one of the built-in functions).
 * Green book, p. 168.
 */
T_exp F_externalCall(string s, T_expList args);

/*
 * Create the IRT for the start and end of the frame.  This includes
 * saving parameters and saving registers.  The associated statement
 * is the body of the function (I hope).
 * Green book, p. 172 and 267.
 */
T_stm F_procEntryExit1(F_frame frame, T_stm stm);

/*
 * Add ``sink'' instructions to the function body so that the register
 * allocator can determine which registers are live at procedure exit.
 * Note that this does not seem to rely on the current frame.
 * Green book, p. 215.
 *
 * Modified to take and return a statement list (since statements are 
 * our assembly code).
 */
T_stmList F_procEntryExit2(T_stmList body);

/*
 * Create assembly code for the start and the end of the frame.
 * Handles sizing the frame.
 * Green book, p. 269.
 */
T_stmList F_procEntryExit3(F_frame frame, T_stmList body);

/*
 * Create a new fragment corresponding to a string.
 * Green book, p. 172.
 */
F_frag F_StringFrag(Temp_label label, string str);

/*
 * Create a new fragment corresopnding to a procedure body. 
 * Green book, p. 173.
 */
F_frag F_ProcFrag(T_stm body, F_frame frame);

/*
 * Create a new list of fragments. 
 */
F_fragList F_FragList(F_frag head, F_fragList tail);


/***********************************************************
 * Special Functions *
 *********************/ 

/*
 * The following are functions that I added to ease creation of
 * ``straight-line'' IRT code.  They may not be appropriate for
 * all implementations.  They may also be moved to irtframe.h.
 */

/*
 * Get the program counter.
 */
Temp_temp F_PC(void);

/*
 * Get the heap pointer.
 */
Temp_temp F_HP(void);

/*
 * Get the accumulator.
 */
Temp_temp F_ACC(void);

/*
 * Get an argument register.  Argument registers are numbered 0 through 9.
 */
Temp_temp F_Arg(int num);

#endif /* _FRAME_H_ */
