Open64 (mfef90, whirl2f, and IR tools)
TAG: version-openad; SVN changeset: 916
|
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