Open64 (mfef90, whirl2f, and IR tools)  TAG: version-openad; SVN changeset: 916
targ_sim_core.h
Go to the documentation of this file.
00001 /*
00002 
00003   Copyright (C) 2000, 2001 Silicon Graphics, Inc.  All Rights Reserved.
00004 
00005   This program is free software; you can redistribute it and/or modify it
00006   under the terms of version 2 of the GNU General Public License as
00007   published by the Free Software Foundation.
00008 
00009   This program is distributed in the hope that it would be useful, but
00010   WITHOUT ANY WARRANTY; without even the implied warranty of
00011   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  
00012 
00013   Further, this software is distributed without any warranty that it is
00014   free of the rightful claim of any third person regarding infringement 
00015   or the like.  Any license provided herein, whether implied or 
00016   otherwise, applies only to this software file.  Patent licenses, if 
00017   any, provided herein do not apply to combinations of this program with 
00018   other software, or any other product whatsoever.  
00019 
00020   You should have received a copy of the GNU General Public License along
00021   with this program; if not, write the Free Software Foundation, Inc., 59
00022   Temple Place - Suite 330, Boston MA 02111-1307, USA.
00023 
00024   Contact information:  Silicon Graphics, Inc., 1600 Amphitheatre Pky,
00025   Mountain View, CA 94043, or:
00026 
00027   http://www.sgi.com
00028 
00029   For further information regarding this notice, see:
00030 
00031   http://oss.sgi.com/projects/GenInfo/NoticeExplan
00032 
00033 */
00034 
00035 
00036 #ifndef targ_sim_core_INCLUDED
00037 #define targ_sim_core_INCLUDED
00038 #ifdef __cplusplus
00039 extern "C" {
00040 #endif
00041 
00042 /*
00043  * This defines the ABI subprogram interface,
00044  * and is used to determine how parameters and results are passed.
00045  * The global variable Target_ABI is used to determine which
00046  * calling convention to use.
00047  * The register values are the PREG offsets, so these values can be
00048  * used in WHIRL.
00049  */
00050 
00051 #define Preg_Offset_Is_Int(n) \
00052         ((n) >= Int_Preg_Min_Offset && (n) <= Int_Preg_Max_Offset)
00053 #define Preg_Offset_Is_Float(n) \
00054         ((n) >= Float_Preg_Min_Offset && (n) <= Float_Preg_Max_Offset)
00055 #define Preg_Offset_Is_Fcc(n) \
00056         ((n) >= Fcc_Preg_Min_Offset && (n) <= Fcc_Preg_Max_Offset)
00057 #define Preg_Is_Dedicated(n) (n <= Last_Dedicated_Preg_Offset)
00058 
00059 /* return whether preg is a return preg */
00060 extern BOOL Is_Return_Preg (PREG_NUM preg);
00061 
00062 /* return whether preg is an output preg */
00063 extern BOOL Is_Int_Output_Preg (PREG_NUM preg);
00064 
00065 /* return whether preg is an input parameter preg */
00066 extern BOOL Is_Formal_Preg (PREG_NUM preg);
00067 
00068 /* define an enumeration of the different levels of mtypes/whirl
00069  * that we can use for returns */
00070 typedef enum {
00071         Use_Simulated,          /* use simulated types */
00072         Complex_Not_Simulated,  /* lower complex but not quad */
00073         No_Simulated            /* all lowered to machine-level */
00074 } Mtype_Return_Level;
00075 
00076 class RETURN_INFO {
00077 private:
00078   mINT8    count;
00079   BOOL     return_via_first_arg;
00080   TYPE_ID  mtype [MAX_NUMBER_OF_REGISTERS_FOR_RETURN];
00081   PREG_NUM preg  [MAX_NUMBER_OF_REGISTERS_FOR_RETURN];
00082 public:
00083   friend inline mINT8 RETURN_INFO_count (const RETURN_INFO&);
00084   friend inline BOOL  RETURN_INFO_return_via_first_arg (const RETURN_INFO&);
00085   friend inline TYPE_ID  RETURN_INFO_mtype (const RETURN_INFO&, INT32);
00086   friend inline PREG_NUM RETURN_INFO_preg (const RETURN_INFO&, INT32);
00087   friend RETURN_INFO Get_Return_Info (TY_IDX rtype, Mtype_Return_Level level);
00088 };
00089 
00090 inline mINT8
00091 RETURN_INFO_count (const RETURN_INFO& info) { return info.count; }
00092 
00093 inline BOOL 
00094 RETURN_INFO_return_via_first_arg (const RETURN_INFO& info)
00095 {
00096   return info.return_via_first_arg;
00097 }
00098 
00099 inline TYPE_ID
00100 RETURN_INFO_mtype (const RETURN_INFO& info, INT32 i) { return info.mtype [i]; }
00101 
00102 inline PREG_NUM
00103 RETURN_INFO_preg (const RETURN_INFO& info, INT32 i) { return info.preg [i]; }
00104 
00105 /* This routine figures out the mtypes of the return registers that are
00106  * used for returning an object of the given type.
00107  * This returns the mtypes to use for the CALL opcode in high-level whirl.
00108  * This means that returns of simulated objects, like FQ, are just shown
00109  * as returning FQ, which will later be split into F8F8.
00110  * However, structures that return in registers are specified explicitly.
00111  * If a register is unused, MTYPE_V is returned.
00112  */
00113 extern void Get_Return_Mtypes (
00114   TY_IDX rtype,         /* The result type */
00115   Mtype_Return_Level level,     /* whether to lower the mtypes */
00116   TYPE_ID *mreg1,       /* out: mtype for result register 1 */
00117   TYPE_ID *mreg2);      /* out: mtype for result register 2 */
00118 
00119 /* This routine figures out which return registers are to be used
00120  * for returning an object with the given mtypes.
00121  * Preg 0 is returned for unused registers.
00122  * It is assumed that the mtypes will be determined by calling
00123  * Get_Return_Mtypes.
00124  */
00125 extern void Get_Return_Pregs (
00126   TYPE_ID mreg1,        /* in:  mtype for result register 1 */
00127   TYPE_ID mreg2,        /* in:  mtype for result register 2 */
00128   PREG_NUM *rreg1,      /* out: result register 1 */
00129   PREG_NUM *rreg2);     /* out: result register 2 */
00130 
00131 
00132 /* PLOC contains information about the location of a parameter.
00133  * If reg == 0, then the parameter is stored on the stack. 
00134  * For -DEBUG:varargs_prototypes=off a floating point parameter is
00135  * passed in both the floating point register and integer register.
00136  */
00137 typedef struct {
00138         PREG_NUM reg;
00139         INT32 start_offset;
00140         INT32 size;
00141         PREG_NUM vararg_reg;
00142 } PLOC;
00143 
00144 #define PLOC_reg(p)             (p.reg)
00145 #define PLOC_vararg_reg(p)      (p.vararg_reg)
00146 #define PLOC_offset(p)          (p.start_offset)
00147 #define PLOC_on_stack(p)        (p.reg == 0)
00148 #define PLOC_total_size(p)      (p.start_offset+p.size)
00149 #define PLOC_size(p)            (p.size)
00150 #define PLOC_is_empty(p)        (PLOC_size(p) == 0)
00151 #define PLOC_is_nonempty(p)     (PLOC_size(p) != 0)
00152 
00153 /* 
00154  * When processing a parameter list,
00155  * we first call Setup_Parameter_Locations with the TY of the PU.
00156  * Setup_* returns a ploc initialized to zero's.
00157  * Then we iterate over each parameter with Get_Parameter_Location.
00158  * Get_Parameter_Location uses the parameter TY and the previous
00159  * location to determine the current location.  
00160  * Structures and register-pairs return the beginning location,
00161  * then First/Next_PLOC_Reg must be used to get info about each preg.
00162  * e.g.
00163     ploc = Setup_Parameter_Locations (call_ty);
00164     foreach parm
00165         ploc = Get_Parameter_Location (parm_ty);
00166         ploc = First_PLOC_Reg (ploc, parm_ty);
00167         while (PLOC_is_nonempty(ploc)) {
00168                 do_something;
00169                 ploc = Next_PLOC_Reg (ploc);
00170  *
00171  */
00172 extern PLOC Setup_Input_Parameter_Locations (TY_IDX pu_type);
00173 extern PLOC Get_Input_Parameter_Location (TY_IDX ptype);
00174 
00175 extern PLOC First_Input_PLOC_Reg (PLOC ploc, TY_IDX parm_ty);
00176 extern PLOC Next_Input_PLOC_Reg (PLOC prev);
00177 
00178 extern PLOC Setup_Output_Parameter_Locations (TY_IDX pu_type);
00179 extern PLOC Get_Output_Parameter_Location (TY_IDX ptype);
00180 
00181 extern PLOC First_Output_PLOC_Reg (PLOC ploc, TY_IDX parm_ty);
00182 extern PLOC Next_Output_PLOC_Reg (PLOC prev);
00183 
00184 /* Iterate over implicit vararg non-fixed register parameters */
00185 extern PLOC Get_Vararg_Input_Parameter_Location (PLOC prev);
00186 extern PLOC Get_Vararg_Output_Parameter_Location (PLOC prev);
00187 
00188 /* Return the size of Preg, based on the register and the abi. 
00189  */
00190 extern INT32 Get_Preg_Size (PREG_NUM p);
00191 
00192 /*
00193  * When we have a structure or register-pair,
00194  * we need to break it into register-sized chunks.
00195  * So we first call Setup_Struct_Parameter_Locations with the structure TY,
00196  * then we iterate with Get_Struct_Parameter_Location until it
00197  * returns PLOC_is_empty.
00198  */
00199 extern void Setup_Struct_Input_Parameter_Locations (TY_IDX struct_ty);
00200 extern PLOC Get_Struct_Input_Parameter_Location ( PLOC prev );
00201 extern void Setup_Struct_Output_Parameter_Locations (TY_IDX struct_ty);
00202 extern PLOC Get_Struct_Output_Parameter_Location ( PLOC prev );
00203 
00204 /*
00205  * TY_mtype() is not correct for structures/arrays.
00206  * This function will return a corrected TYPE_ID
00207  */
00208 extern TYPE_ID Fix_TY_mtype(TY_IDX);
00209 
00210 /*
00211  * The following variables give info about the calling convention,
00212  * and are set by Init_Targ_Sim()
00213  */
00214 
00215 extern BOOL Is_Caller_Save_GP;  /* whether GP is caller-save */
00216 
00217 /* Amount of space available in stack frame to save register formals. */
00218 extern INT Formal_Save_Area_Size;
00219 /* Adjust all stack offsets by this amount,
00220  * which represents the space available to subsequent frames. */
00221 extern INT Stack_Offset_Adjustment;
00222 
00223 extern void Init_Targ_Sim (void);       /* initialize the info */
00224 
00225 // PREG_IDX == PREG_NUM - Last_Dedicated_Preg_Offset
00226 
00227 inline PREG_IDX
00228 Get_Preg_Idx (PREG_NUM n)       { return n - Last_Dedicated_Preg_Offset; }
00229 inline PREG_NUM
00230 Get_Preg_Num (PREG_IDX i)       { return i + Last_Dedicated_Preg_Offset; }
00231 
00232 #ifndef PUSH_RETURN_ADDRESS_ON_STACK
00233 #define PUSH_RETURN_ADDRESS_ON_STACK FALSE
00234 #endif
00235 
00236 #ifndef PUSH_FRAME_POINTER_ON_STACK
00237 #define PUSH_FRAME_POINTER_ON_STACK  FALSE
00238 #endif
00239 
00240 #ifdef __cplusplus
00241 }
00242 #endif
00243 #endif /* targ_sim_core_INCLUDED */
00244 
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Defines