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 // -*-C++-*- 00036 // Template stuff for sorting 00037 00038 #include <vector> 00039 #include <algorithm> 00040 00041 using namespace std; 00042 00043 static ST *orig_st; /* The symbol being initialized (for error reporting only) */ 00044 static ST *current_st; /* The symbol being initialized */ 00045 static TY_IDX current_ty; 00046 static INT64 current_bytesize; 00047 static INT32 current_pos; /* position in the array to initialize (0 based, byte indexed) */ 00048 static INT32 array_pos; /* position in the current array */ 00049 static BOOL is_struct_or_array; /* TRUE if initilaizing an array */ 00050 static INITO_IDX current_inito = 0; 00051 00052 /* for pulling apart bases and offsets */ 00053 typedef struct { 00054 INT64 offset; 00055 ST * base; 00056 } b_and_o; 00057 00058 struct data_element_s { 00059 INT64 offset; 00060 INT64 initv_size; 00061 union { 00062 b_and_o bo; 00063 struct { 00064 TCON_IDX tc; 00065 INT32 repeat_count; 00066 } tc_val; 00067 } val; 00068 UINT32 sequence_num:30; 00069 UINT32 is_b_and_o:1; 00070 UINT32 is_valid:1; 00071 00072 #ifdef DATA_DEBUG 00073 void print() { 00074 printf("Off: %12lld TC: %d (x %d) %s\n",offset,val.tc_val.tc,val.tc_val.repeat_count, 00075 is_valid ? "valid" : "invalid"); 00076 } 00077 #endif 00078 00079 inline data_element_s(INT64 o, TCON_IDX tc, b_and_o *bo, INT64 isize, UINT32 seqnum) { 00080 offset=o; initv_size=isize; sequence_num = seqnum; is_valid = TRUE; 00081 if (bo) { 00082 is_b_and_o = TRUE; 00083 val.bo = *bo; 00084 } else { 00085 is_b_and_o = FALSE; 00086 val.tc_val.tc = tc; 00087 val.tc_val.repeat_count = 1; 00088 } 00089 } 00090 00091 INITV_IDX create_initv() 00092 { 00093 if (is_b_and_o) { 00094 return (Irb_Init_Symoff(0, 0, 1, val.bo.base, val.bo.offset)); 00095 } else { 00096 return (Irb_Init_Val(0, 0, val.tc_val.repeat_count, val.tc_val.tc)); 00097 } 00098 } 00099 00100 00101 // Compare on offset first. If the offsets are the same, the larger 00102 // comes first (so that we get a more complete cover). If the sizes are the 00103 // same (the usual case, we'd expect) take the last one entered 00104 static bool comp(data_element_s a, data_element_s b) { 00105 if (a.offset != b.offset) return (a.offset < b.offset); 00106 if (a.initv_size != b.initv_size) return (b.initv_size < a.initv_size); 00107 return (b.sequence_num < a.sequence_num); 00108 } 00109 }; 00110 00111 00112 typedef vector<data_element_s> DATA_ELEMENTS; 00113 00114 // 00115 // miscellaneous stuff needed for data intialization 00116 // 00117 // st_inito - the INITO for a symbol 00118 // data_elements - the data elements of 00119 // 00120 struct data_info_s { 00121 INITO_IDX st_inito; 00122 DATA_ELEMENTS data_elements; 00123 UINT32 sequence_num; 00124 00125 data_info_s(ST *st) {st_inito = New_INITO(st); sequence_num=0;} 00126 ~data_info_s(void) {} 00127 00128 void sort_data(ST *st) { 00129 BOOL message_issued = FALSE; 00130 sort(data_elements.begin(),data_elements.end(),data_element_s::comp); 00131 00132 // Now pack together the data for multiple initv's, and flag errors 00133 INT32 vsize,i,last_index; 00134 INT64 pos=0; 00135 00136 vsize = data_elements.size(); 00137 #ifdef DATA_DEBUG 00138 printf("======== before duplicate processing %s\n",ST_name(st)); 00139 for (i=0; i < vsize; i++) { 00140 data_elements[i].print(); 00141 } 00142 #endif 00143 for (i=0,last_index=0; i < vsize; i++) { 00144 if (data_elements[i].offset < pos) { 00145 if (!message_issued) { 00146 ErrMsg(EC_Multiple_Initialization,ST_name(st)); 00147 message_issued = TRUE; 00148 } 00149 data_elements[i].is_valid = FALSE; 00150 continue; 00151 } 00152 00153 // Valid init, increment pos, check for packing 00154 if ((last_index != i) && 00155 (pos == data_elements[i].offset) && 00156 (!data_elements[last_index].is_b_and_o) && 00157 (!data_elements[i].is_b_and_o) && 00158 (data_elements[i].val.tc_val.tc == data_elements[last_index].val.tc_val.tc)) { 00159 // update repeat count of last_index, mark current as invalid 00160 data_elements[last_index].val.tc_val.repeat_count += 1; 00161 data_elements[last_index].initv_size += data_elements[i].initv_size; 00162 data_elements[i].is_valid = FALSE; 00163 pos += data_elements[i].initv_size; 00164 } else { 00165 // update the current position 00166 pos = data_elements[i].offset + data_elements[i].initv_size; 00167 last_index = i; 00168 } 00169 } 00170 #ifdef DATA_DEBUG 00171 printf("======== after duplicate processing\n"); 00172 for (i=0; i < vsize; i++) { 00173 data_elements[i].print(); 00174 } 00175 #endif 00176 } 00177 00178 inline INITO_IDX Get_Inito(void) {return st_inito;} 00179 inline DATA_ELEMENTS *Get_Data_Elements(void) {return &data_elements;} 00180 00181 inline void Reserve(INT64 num_to_add) { 00182 // To avoid a bad case in which we spend lots of time reserving tiny little 00183 // chunks, we reserve at least at 5% increase each time. 00184 INT64 excess_capacity = data_elements.capacity() - data_elements.size(); 00185 if (excess_capacity > num_to_add) return; 00186 00187 INT64 new_size = num_to_add + data_elements.size(); 00188 INT64 min_new_size = INT64(1.05 * data_elements.capacity()); 00189 if (new_size < min_new_size) new_size = min_new_size; 00190 data_elements.reserve(new_size); 00191 } 00192 00193 inline void Add_Data_Element(INT64 offset, TCON_IDX val, b_and_o *bo, INT64 isize) { 00194 #ifdef DATA_DEBUG 00195 printf("Add at offset %lld: TCON = %d\n",offset,val); 00196 #endif 00197 data_elements.push_back(data_element_s(offset,val,bo,isize,sequence_num++)); 00198 } 00199 }; 00200 00201 typedef data_info_s *DATA_INFO; 00202 00203 static DATA_INFO current_data_info; 00204 00205 static void cwh_data_set_init_flag(ST * st, enum list_name list); 00206 00207