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 //-*-c++-*- 00037 // ==================================================================== 00038 // ==================================================================== 00039 // 00040 // 00041 // Description: Conversion rules 00042 // 00043 // ==================================================================== 00044 // ==================================================================== 00045 00046 #include "opt_cvtl_rule.h" 00047 #include "wn.h" 00048 00049 #define nop {NOT_AT_ALL,OPCODE_LAST+1} 00050 #define I8I4 {NEED_CVT, OPC_I8I4CVT} 00051 #define U8I4 {NEED_CVT, OPC_U8I4CVT} 00052 #define I4I8 {NEED_CVT, OPC_I4I8CVT} 00053 #define U4I8 {NEED_CVT, OPC_U4I8CVT} 00054 #define I8U4 {NEED_CVT, OPC_I8U4CVT} 00055 #define U8U4 {NEED_CVT, OPC_U8U4CVT} 00056 #define I4U8 {NEED_CVT, OPC_I4U8CVT} 00057 #define U4U8 {NEED_CVT, OPC_U4U8CVT} 00058 00059 #define I4I2 {NEED_CVTL, OPC_I4CVTL} 00060 #define I4I1 {NEED_CVTL, OPC_I4CVTL} 00061 #define U4U2 {NEED_CVTL, OPC_U4CVTL} 00062 #define U4U1 {NEED_CVTL, OPC_U4CVTL} 00063 #define I4U4 {NEED_CVTL, OPC_U4CVTL} 00064 #define U4I4 {NEED_CVTL, OPC_I4CVTL} 00065 #define I8I2 {NEED_CVTL, OPC_I8CVTL} 00066 #define I8I1 {NEED_CVTL, OPC_I8CVTL} 00067 #define U8U2 {NEED_CVTL, OPC_U8CVTL} 00068 #define U8U1 {NEED_CVTL, OPC_U8CVTL} 00069 00070 #define I1I4 {NEED_CVTL, OPC_I4CVTL} 00071 #define I2I4 {NEED_CVTL, OPC_I4CVTL} 00072 #define I1I8 {NEED_CVTL, OPC_I8CVTL} 00073 #define I2I8 {NEED_CVTL, OPC_I8CVTL} 00074 #define U1U4 {NEED_CVTL, OPC_U4CVTL} 00075 #define U2U4 {NEED_CVTL, OPC_U4CVTL} 00076 #define U1U8 {NEED_CVTL, OPC_U8CVTL} 00077 #define U2U8 {NEED_CVTL, OPC_U8CVTL} 00078 00079 #define I4B {NEED_CVT, OPC_I4BCVT} 00080 #define I8B {NEED_CVT, OPC_I8BCVT} 00081 #define U4B {NEED_CVT, OPC_U4BCVT} 00082 #define U8B {NEED_CVT, OPC_U8BCVT} 00083 00084 // This table reflexs the table 3 in whirl definition document. There 00085 // is minor differences, the convert in the original table is removed 00086 // if it does not require an instruction in MIPS architecture. all 00087 // macros for conversion is ToFrom sequence. 00088 static struct cvt_rule { 00089 char _cvt_kind; 00090 mINT32 _cvt_opcode; 00091 } cvt_rule[MTYPE_U8+1][MTYPE_U8+1] = { 00092 //UNK, B, I1, I2, I4, I8, U1, U2, U4, U8 From 00093 { nop, nop, nop, nop, nop, nop, nop, nop, nop, nop},//to UNK 00094 { nop, nop, nop, nop, nop, nop, nop, nop, nop, nop},//to B 00095 { nop, nop, nop, nop,I1I4,I1I8, nop, nop,I1I4,I1I8},//to I1 00096 { nop, nop, nop, nop,I2I4,I2I8, nop, nop,I2I4,I1I8},//to I2 00097 { nop, I4B,I4I1,I4I2, nop,I4I8, nop, nop, nop,I4U8},//to I4 00098 #ifdef TARG_MIPS 00099 { nop, nop,I8I1,I8I2, nop, nop, nop, nop,I8U4, nop},//to I8 00100 #elif defined(TARG_IA32) 00101 { nop, nop,I8I1,I8I2,I8I4, nop, nop, nop,I8U4, nop},//to I8 00102 #else 00103 { nop, I8B,I8I1,I8I2,I8I4, nop, nop, nop, nop, nop},//to I8 00104 #endif 00105 { nop, nop, nop, nop,U1U4,U1U8, nop, nop,U1U4,U1U8},//to U1 00106 { nop, nop, nop, nop,U2U4,U2U8, nop, nop,U2U4,U2U8},//to U2 00107 { nop, U4B, nop, nop, nop,U4I8,U4U1,U4U2, nop,U4U8},//to U4 00108 #ifdef TARG_MIPS 00109 { nop, nop, nop, nop, nop, nop,U8U1,U8U2,U8U4, nop} //to U8 00110 #elif defined(TARG_IA32) 00111 { nop, nop, nop, nop,U8I4, nop,U8U1,U8U2,U8U4, nop} //to U8 00112 #else 00113 { nop, U8B, nop, nop,U8I4, nop,U8U1,U8U2, nop, nop} //to U8 00114 #endif 00115 }; 00116 00117 // return NOT_AT_ALL, NEED_CVT, or NEED_CVTL. The reference parameter 00118 // opc returns the opcode for the conversion, if it is either NEED_CVT 00119 // or NEED_CVTL. 00120 INT Need_type_conversion(TYPE_ID from_ty, TYPE_ID to_ty, OPCODE *opc) 00121 { 00122 if (!(MTYPE_is_integral(from_ty) && MTYPE_is_integral(to_ty))) { 00123 if (from_ty == to_ty) return NOT_AT_ALL; 00124 if (opc != NULL) 00125 *opc = OPCODE_make_op(OPR_CVT, to_ty, from_ty); 00126 return NEED_CVT; 00127 } 00128 00129 if (opc != NULL) 00130 *opc = (OPCODE)cvt_rule[to_ty][from_ty]._cvt_opcode; 00131 return (INT)cvt_rule[to_ty][from_ty]._cvt_kind; 00132 } 00133 00134 00135 // ========================================================== 00136 // Load/Iload convertion rule for desc type if size 4 00137 // hi32 sign extended 00138 // U8U4ILOAD 0 00139 // I8I4ILOAD 1 00140 // U4U4ILOAD 1 00141 // I4I4ILOAD 1 00142 // need conversion between {U8U4ILOAD} and {I8I4ILOAD,U4U4ILOAD,I4I4ILOAD} 00143 // ========================================================== 00144 // static struct load_convert_rule_4 { 00145 // char _cvt_kind; 00146 // mINT32 _cvt_opcode; 00147 // } load_convert_rule_4[2][2] = { 00148 // // 0 1 From 00149 // { nop, U8U4},//to 0 00150 // { U4U8, nop} //to 1 00151 // }; 00152 // 00153 // ========================================================== 00154 // Load/Iload convertion rule for desc type if size < 4 00155 // lo32 sign extended 00156 // U8U{1,2}ILOAD 0 00157 // I8I{1,2}ILOAD 1 00158 // U4U{1,2}ILOAD 0 00159 // I4I{1,2}ILOAD 1 00160 // need conversion between {U{8,4}U{1,2}ILOAD} and {I{8,4}I{1,2}ILOAD} 00161 // ========================================================== 00162 // static struct load_convert_rule_1_2 { 00163 // char _cvt_kind; 00164 // mINT32 _cvt_opcode; 00165 // } load_convert_rule_1_2[2][2] = { 00166 // // 0 1 From 00167 // { nop, U4U1 },// to 0 00168 // {I4I1, nop } // to 1 00169 // }; 00170 // 00171 // =================================================================== 00172 // Implementing Load/Iload conversion rule as scratched above. 00173 // return NOT_AT_ALL, NEED_CVT, or NEED_CVTL. The reference parameter 00174 // opc returns the opcode for the conversion, if it is either NEED_CVT 00175 // or NEED_CVTL. 00176 // =================================================================== 00177 INT Need_load_type_conversion(BOOL source_sign_extd, BOOL target_sign_extd, 00178 TYPE_ID to_ty, TYPE_ID dsc_ty, OPCODE *opc) 00179 { 00180 00181 Is_True(MTYPE_is_integral(to_ty),("Need_load_type_conversion: non integral type")); 00182 Is_True(to_ty != MTYPE_BS,("Need_load_type_conversion: illegal MTYPE_BS")); 00183 Is_True(MTYPE_size_min(to_ty)>=MTYPE_size_min(MTYPE_I4), 00184 ("Need_load_type_conversion: data type size less than I4")); 00185 00186 if (source_sign_extd == target_sign_extd || 00187 MTYPE_size_min(dsc_ty) > MTYPE_size_min(MTYPE_I4) && dsc_ty != MTYPE_BS) 00188 return NOT_AT_ALL; 00189 00190 if (MTYPE_size_min(dsc_ty) == MTYPE_size_min(MTYPE_I4) && 00191 dsc_ty != MTYPE_BS) { 00192 if (source_sign_extd) { // !targ_sign_extd 00193 *opc = (OPCODE) OPC_U8U4CVT; 00194 } else { // targ_sign_extd && !source_sign_extd 00195 *opc = (OPCODE) OPC_U4U8CVT; 00196 } 00197 return NEED_CVT; 00198 } 00199 else { 00200 if (source_sign_extd) { // !targ_sign_extd 00201 *opc = (OPCODE) (MTYPE_size_min(to_ty) == MTYPE_size_min(MTYPE_I4)) ? 00202 OPC_U4CVTL : OPC_U8CVTL; 00203 } else { // targ_sign_extd && !source_sign_extd 00204 *opc = (OPCODE) (MTYPE_size_min(to_ty) == MTYPE_size_min(MTYPE_I4)) ? 00205 OPC_I4CVTL : OPC_I8CVTL; 00206 } 00207 return NEED_CVTL; 00208 } 00209 00210 } 00211 00212 // Check if TYPE_ID lhs_type is compatible with the RHS of assignment stmt 00213 BOOL 00214 Types_are_compatible(TYPE_ID lhs_type, TYPE_ID rhs_type) 00215 { 00216 BOOL compatible; 00217 OPCODE opc; 00218 00219 if ((MTYPE_type_class(rhs_type)&MTYPE_CLASS_UNSIGNED_INTEGER) == 0 || 00220 (MTYPE_type_class(lhs_type)&MTYPE_CLASS_UNSIGNED_INTEGER) == 0) { 00221 if (rhs_type == lhs_type) return FALSE; 00222 else 00223 return TRUE; 00224 } 00225 compatible = Need_type_conversion(rhs_type, lhs_type, &opc) != NEED_CVT; 00226 return compatible; 00227 } 00228 00229 // Check if TYPE_ID lhs_type is compatible with the RHS of assignment stmt 00230 BOOL 00231 Types_are_compatible(TYPE_ID lhs_type, WN *rhs_wn) 00232 { 00233 TYPE_ID rhs_type = Actual_result_type(rhs_wn); 00234 00235 return Types_are_compatible(lhs_type, rhs_type); 00236 } 00237 00238 00239 00240 TYPE_ID Rebuild_rtype(TYPE_ID rtype, INT bits) 00241 { 00242 if ( rtype == MTYPE_I4 || rtype == MTYPE_I8 ) { 00243 if ( bits <= 8 ) 00244 rtype = MTYPE_I1; 00245 else if ( bits <= 16 ) 00246 rtype = MTYPE_I2; 00247 else if ( bits <= 32 ) 00248 rtype = MTYPE_I4; 00249 else 00250 rtype = MTYPE_I8; 00251 } 00252 else { 00253 if ( bits <= 8 ) 00254 rtype = MTYPE_U1; 00255 else if ( bits <= 16 ) 00256 rtype = MTYPE_U2; 00257 else if ( bits <= 32 ) 00258 rtype = MTYPE_U4; 00259 else 00260 rtype = MTYPE_U8; 00261 } 00262 return rtype; 00263 } 00264 00265 // Actual_data_size calculates the number of bits for the data 00266 // carried by the tree, ie do not count those bits contains 0 in the 00267 // lsb. This function is ENDIAN dependent! 00268 INT Actual_data_size(WN *wn) 00269 { 00270 OPERATOR opr = WN_operator(wn); 00271 TYPE_ID rtype = WN_rtype(wn); 00272 INT actual_size; 00273 00274 if ((MTYPE_type_class(rtype) & MTYPE_CLASS_INTEGER) == 0) 00275 return MTYPE_size_min(rtype); 00276 00277 switch ( opr ) { 00278 case OPR_INTCONST: 00279 { 00280 INT64 val; 00281 for (val = WN_const_val(wn), actual_size = 0; 00282 actual_size < 64 && val != 0; actual_size++) 00283 val = val >> 1; 00284 if (MTYPE_is_integral(rtype) && !MTYPE_is_unsigned(rtype) && MTYPE_size_min(rtype) == actual_size) { 00285 // must assume sign extended 00286 actual_size = MTYPE_size_min(Pointer_type); 00287 } 00288 return actual_size; 00289 } 00290 00291 case OPR_CVTL: 00292 if (MTYPE_is_signed(rtype)) { 00293 actual_size = Actual_data_size(WN_kid0(wn)); 00294 if (MTYPE_size_min(rtype) == actual_size) 00295 return actual_size; 00296 else 00297 return WN_cvtl_bits(wn); 00298 } 00299 else 00300 return WN_cvtl_bits(wn); 00301 00302 case OPR_LDBITS: 00303 case OPR_ILDBITS: 00304 if (MTYPE_is_signed(rtype)) 00305 return MTYPE_size_min(rtype); 00306 else 00307 return WN_bit_size (wn); 00308 00309 case OPR_LDID: 00310 case OPR_ILOAD: 00311 if (MTYPE_is_signed(rtype)) // pv 361929 00312 return MTYPE_size_min(rtype); 00313 else 00314 return MTYPE_size_min(WN_desc(wn)); 00315 00316 case OPR_BAND: 00317 case OPR_BIOR: 00318 { 00319 INT kid0_size = Actual_data_size(WN_kid0(wn)); 00320 INT kid1_size = Actual_data_size(WN_kid1(wn)); 00321 if (MTYPE_is_unsigned(rtype)) { 00322 if (opr == OPR_BIOR) 00323 return (kid0_size > kid1_size)? kid0_size : kid1_size; 00324 else return (kid0_size > kid1_size)? kid1_size : kid0_size; 00325 } 00326 else return MTYPE_size_min(rtype); 00327 } 00328 00329 case OPR_SHL: 00330 case OPR_ASHR: 00331 case OPR_LSHR: 00332 { 00333 // The kid1 contains the number of bits. 00334 WN *bits = WN_kid1(wn); 00335 00336 // skip if kid 1 is not a constant. 00337 if ( WN_operator(bits) == OPR_INTCONST ) { 00338 UINT bit_cnt = WN_const_val(bits); 00339 if (MTYPE_size_min(rtype) == 32) 00340 bit_cnt &= 0x1F; // use the low 5 bits 00341 else 00342 bit_cnt &= 0x3F; 00343 00344 actual_size = Actual_data_size(WN_kid0(wn)); 00345 if (opr == OPR_SHL) { 00346 if (MTYPE_is_unsigned(rtype)) { 00347 actual_size += bit_cnt; 00348 if (actual_size > MTYPE_size_min(rtype)) // pv 364274 00349 actual_size = MTYPE_size_min(rtype); 00350 } 00351 else actual_size = MTYPE_size_min(rtype); 00352 } 00353 else if (MTYPE_is_unsigned(rtype)) { 00354 actual_size -= bit_cnt; 00355 if (actual_size < 0) actual_size = 0; 00356 } 00357 else actual_size = MTYPE_size_min(rtype); 00358 return actual_size; 00359 } 00360 } 00361 break; 00362 default: 00363 ; 00364 } 00365 return MTYPE_size_min(rtype); 00366 } 00367 00368 00369 // given a OPR_CVTL opcode and the number of bits it converting to, 00370 // return the actual type. 00371 TYPE_ID Actual_cvtl_type(OPCODE opc, INT bits) 00372 { 00373 return Rebuild_rtype(OPCODE_rtype(opc), bits); 00374 } 00375 00376 // Actual_result_type returns the data type of the tree with the 00377 // actual number of bytes that we can determine at this point. This 00378 // function helps to determine a CVTL node is required or can be 00379 // deleted by the optimizer emitter. 00380 TYPE_ID Actual_result_type(WN *wn) 00381 { 00382 OPCODE opc = WN_opcode(wn); 00383 TYPE_ID rtype = OPCODE_rtype(opc); 00384 INT bits; 00385 00386 // only do it for an integer type 00387 if ((MTYPE_type_class(rtype) & MTYPE_CLASS_INTEGER) == 0) 00388 return rtype; 00389 00390 switch ( OPCODE_operator(opc) ) { 00391 case OPR_CVTL: 00392 case OPR_LDID: 00393 case OPR_LDBITS: 00394 case OPR_ILOAD: 00395 case OPR_ILDBITS: 00396 case OPR_BIOR: 00397 case OPR_BAND: 00398 case OPR_SHL: 00399 case OPR_ASHR: 00400 case OPR_LSHR: 00401 case OPR_INTCONST: 00402 bits = Actual_data_size(wn); 00403 rtype = Rebuild_rtype(rtype, bits); 00404 } 00405 00406 return rtype; 00407 } 00408 00409 TYPE_ID Adjust_signed_type(TYPE_ID rtype, INT size, WN *wn) 00410 { 00411 INT bits = Actual_data_size(wn); 00412 00413 if (MTYPE_is_integral(rtype) && !MTYPE_is_unsigned(rtype) && size == bits) { 00414 // need sign extension 00415 // 32 is the largest size CVTL would convert to 00416 return Rebuild_rtype(rtype, 32); 00417 } 00418 return MTYPE_UNKNOWN; 00419 }