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 #ifndef u64_lower_template_INCLUDED 00039 #define u64_lower_template_INCLUDED "u64_lower_template.h" 00040 00041 00042 00043 enum HIGH_ORDER_BITS { 00044 HOB_none, 00045 HOB_zero_xtd, 00046 HOB_sign_xtd 00047 }; 00048 00049 00050 /* ==================================================================== 00051 * Lowers integer operations to exclusively use 64-bit operations and 00052 * unsigned loads. Size of integer (in bits) currently representing the 00053 * result is returned in maxsize. Floating-point and boolean values are assumed 00054 * stored in special registers, so the optimization does not apply to them. 00055 * Thus, maxsize is 0 if it is a floating-point or boolean value. 00056 * hob_state returns info about the bits that are outside the part 00057 * representing the result. hob_to_do returns info as to whether any delayed 00058 * operation to the high-order bits is needed in order to represent the value 00059 * correctly in the 64-bit register. hob_state and hob_to_do is unused 00060 * if maxsize is 0 or 64. 00061 * ==================================================================== */ 00062 template <class NODE> 00063 NODE * 00064 U64_LOWER_expr(NODE *tree, INT &maxsize, 00065 HIGH_ORDER_BITS &hob_state, HIGH_ORDER_BITS &hob_to_do, 00066 BOOL leave_CVTL_at_leaf) 00067 { 00068 INT maxsize0, maxsize1, new_maxsize; 00069 HIGH_ORDER_BITS hob_state0, hob_state1; 00070 HIGH_ORDER_BITS hob_to_do0, hob_to_do1; 00071 INT i; 00072 NODE *nd; 00073 NODE *new_nd = U64_LOWER_alloc_stack(tree); U64_LOWER_copy_node(new_nd, tree); 00074 OPERATOR opr = U64_LOWER_operator(tree); 00075 TYPE_ID res = U64_LOWER_rtype(tree); 00076 TYPE_ID desc = U64_LOWER_desc(tree); 00077 if (desc == MTYPE_V || desc == MTYPE_UNKNOWN) desc = res; 00078 00079 if (opr == OPR_INTRINSIC_OP) { 00080 for (i = 0; i < U64_LOWER_kid_count(tree); i++) { // kids must be PARMs 00081 U64_LOWER_set_kid(new_nd, i, U64_LOWER_expr(U64_LOWER_kid(tree,i), 00082 maxsize0, hob_state0, hob_to_do0, leave_CVTL_at_leaf)); 00083 } 00084 if (MTYPE_is_integral(res) && res != MTYPE_B) { 00085 maxsize = MTYPE_bit_size(res); 00086 hob_state = HOB_none; 00087 hob_to_do = MTYPE_signed(res) ? HOB_sign_xtd : HOB_zero_xtd; 00088 } 00089 else maxsize = 0; 00090 return U64_LOWER_form_node(new_nd, tree); 00091 } 00092 if (opr == OPR_SELECT) { 00093 U64_LOWER_set_kid(new_nd, 0, U64_LOWER_expr(U64_LOWER_kid(tree,0), maxsize0, 00094 hob_state0, hob_to_do0, leave_CVTL_at_leaf)); 00095 if (maxsize0 != 0 && maxsize0 != 64) { // generate comparison with 0 00096 if (hob_state0 == HOB_none) 00097 U64_LOWER_insert_cvtl_for_kid(new_nd, HOB_zero_xtd, 0, maxsize0, hob_state0); 00098 #if 0 00099 U64_LOWER_set_kid0(new_nd, U64_LOWER_create_ne_0(Boolean_type, MTYPE_U8, 00100 U64_LOWER_kid0(new_nd))); 00101 #endif 00102 } 00103 U64_LOWER_set_kid1(new_nd, U64_LOWER_expr(U64_LOWER_kid1(tree), maxsize1, 00104 hob_state1, hob_to_do1, leave_CVTL_at_leaf)); 00105 U64_LOWER_set_kid2(new_nd, U64_LOWER_expr(U64_LOWER_kid2(tree), maxsize, 00106 hob_state, hob_to_do, leave_CVTL_at_leaf)); 00107 if (! MTYPE_is_integral(res) || res == MTYPE_B) 00108 return U64_LOWER_form_node(new_nd, tree); 00109 U64_LOWER_set_rtype(new_nd, Mtype_TransferSize(MTYPE_A8, res)); 00110 if (maxsize == maxsize1 && hob_state == hob_state1 && 00111 hob_to_do == hob_to_do1) 00112 return U64_LOWER_form_node(new_nd, tree); 00113 U64_LOWER_insert_cvtl_for_kid(new_nd, hob_to_do1, 1, maxsize1, hob_state1); 00114 U64_LOWER_insert_cvtl_for_kid(new_nd, hob_to_do, 2, maxsize, hob_state); 00115 maxsize = 64; 00116 return U64_LOWER_form_node(new_nd, tree); 00117 } 00118 // only leaves, unary, binary or ternary expression operators are left 00119 if (U64_LOWER_kid_count(tree) > 0) { 00120 U64_LOWER_set_kid0(new_nd, U64_LOWER_expr(U64_LOWER_kid0(tree), maxsize, 00121 hob_state, hob_to_do, leave_CVTL_at_leaf)); 00122 if (U64_LOWER_kid_count(tree) > 1) { 00123 U64_LOWER_set_kid1(new_nd, U64_LOWER_expr(U64_LOWER_kid1(tree), maxsize1, 00124 hob_state1, hob_to_do1, leave_CVTL_at_leaf)); 00125 if (U64_LOWER_kid_count(tree) > 2) { 00126 Is_True(! MTYPE_is_integral(desc), ("unhandled ternary operator")); 00127 U64_LOWER_set_kid2(new_nd, U64_LOWER_expr(U64_LOWER_kid2(tree), maxsize1, 00128 hob_state1, hob_to_do1, leave_CVTL_at_leaf)); 00129 maxsize = 0; 00130 return U64_LOWER_form_node(new_nd, tree); // must be floating-point 00131 // ops, so nothing can be done 00132 } 00133 } 00134 } 00135 00136 // only leaves, unary or binary expression operators are left 00137 switch (opr) { 00138 00139 // loads 00140 00141 case OPR_LDID: 00142 if (! MTYPE_is_integral(res) || res == MTYPE_B) { 00143 maxsize = 0; 00144 return tree; 00145 } 00146 if (U64_LOWER_class(tree) == CLASS_PREG) { 00147 maxsize = MTYPE_bit_size(res); 00148 hob_state = HOB_none; 00149 hob_to_do = MTYPE_signed(res) ? HOB_sign_xtd : HOB_zero_xtd; 00150 U64_LOWER_set_rtype(tree, Mtype_TransferSize(MTYPE_A8, res)); 00151 #if 0 00152 // this triggers whirl verifier assertion due to desc's inconsistency 00153 // with TY's size 00154 U64_LOWER_set_desc(tree, Mtype_TransferSize(MTYPE_A8, res)); 00155 #endif 00156 return tree; 00157 } 00158 maxsize = MTYPE_bit_size(desc); 00159 if (maxsize == 64) 00160 return tree; 00161 hob_state = HOB_zero_xtd; // all loads are zero extended 00162 hob_to_do = MTYPE_signed(res) ? HOB_sign_xtd : HOB_zero_xtd; 00163 if (MTYPE_signed(desc)) { // change to unsigned 00164 U64_LOWER_set_desc(tree, Mtype_TransferSign(MTYPE_U8, desc)); 00165 } 00166 #if 0 // this is done in post-pass instead 00167 U64_LOWER_reset_sign_extd(tree); 00168 #endif 00169 // force 8-byte loads 00170 U64_LOWER_set_rtype(tree, Mtype_TransferSize(MTYPE_A8, U64_LOWER_desc(tree))); 00171 00172 if (! leave_CVTL_at_leaf) 00173 return tree; 00174 else if (maxsize < 64 && hob_to_do == HOB_sign_xtd) { 00175 hob_state = HOB_sign_xtd; 00176 return U64_LOWER_create_cvtl(MTYPE_I8, tree, maxsize); 00177 } 00178 else return tree; 00179 00180 case OPR_ILOAD: 00181 if (! MTYPE_is_integral(res) || res == MTYPE_B) { 00182 maxsize = 0; 00183 return U64_LOWER_form_node(new_nd, tree); 00184 } 00185 maxsize = MTYPE_bit_size(desc); 00186 if (maxsize == 64) 00187 return U64_LOWER_form_node(new_nd, tree); 00188 hob_state = HOB_zero_xtd; // all loads are zero extended 00189 hob_to_do = MTYPE_signed(res) ? HOB_sign_xtd : HOB_zero_xtd; 00190 if (MTYPE_signed(desc)) { // change to unsigned 00191 U64_LOWER_set_desc(new_nd, Mtype_TransferSign(MTYPE_U8, desc)); 00192 } 00193 #if 0 // this is done in post-pass instead 00194 U64_LOWER_reset_sign_extd(new_nd); 00195 #endif 00196 // force 8-byte loads 00197 U64_LOWER_set_rtype(new_nd, Mtype_TransferSize(MTYPE_A8, U64_LOWER_desc(new_nd))); 00198 00199 if (! leave_CVTL_at_leaf) 00200 return U64_LOWER_form_node(new_nd, tree); 00201 else if (maxsize < 64 && hob_to_do == HOB_sign_xtd) { 00202 hob_state = HOB_sign_xtd; 00203 return U64_LOWER_create_cvtl(MTYPE_I8, 00204 U64_LOWER_form_node(new_nd, tree), 00205 maxsize); 00206 } 00207 else return U64_LOWER_form_node(new_nd, tree); 00208 00209 case OPR_LDBITS: 00210 maxsize = U64_LOWER_bit_size(tree); // maxsize cannot be 64 or 0 00211 hob_state = MTYPE_signed(res) ? HOB_sign_xtd : HOB_zero_xtd; 00212 hob_to_do = HOB_none; 00213 return tree; 00214 00215 case OPR_ILDBITS: 00216 maxsize = U64_LOWER_bit_size(tree); // maxsize cannot be 64 or 0 00217 hob_state = MTYPE_signed(res) ? HOB_sign_xtd : HOB_zero_xtd; 00218 hob_to_do = HOB_none; 00219 return U64_LOWER_form_node(new_nd, tree); 00220 00221 case OPR_MLOAD: 00222 Is_True(maxsize1 != 0, ("illegal type for kid 1 of MLOAD node")); 00223 U64_LOWER_insert_cvtl_for_kid(new_nd, hob_to_do, 1, maxsize1, hob_state1); 00224 maxsize = 0; // because result type is M 00225 return U64_LOWER_form_node(new_nd, tree); 00226 00227 // other leaves 00228 00229 case OPR_INTCONST: 00230 maxsize = MTYPE_bit_size(res); 00231 if (maxsize == 32) { 00232 if (MTYPE_signed(res)) { // change to I8 00233 U64_LOWER_set_const_val(tree, (U64_LOWER_const_val(tree) << 32) >> 32); 00234 hob_state = HOB_sign_xtd; 00235 } 00236 else { // change to U8 00237 U64_LOWER_set_const_val(tree, (UINT64) (U64_LOWER_const_val(tree) << 32) >> 32); 00238 hob_state = HOB_zero_xtd; 00239 } 00240 U64_LOWER_set_rtype(tree, Mtype_TransferSize(MTYPE_A8, res)); 00241 hob_to_do = hob_state; 00242 } 00243 return tree; 00244 00245 case OPR_CONST: 00246 if (! MTYPE_is_integral(res)) { 00247 maxsize = 0; 00248 return tree; 00249 } 00250 maxsize = MTYPE_bit_size(res); 00251 hob_state = HOB_none; // because don't know how it is generated 00252 hob_to_do = MTYPE_signed(res) ? HOB_sign_xtd : HOB_zero_xtd; 00253 return tree; 00254 00255 case OPR_LDA: case OPR_LDA_LABEL: 00256 maxsize = MTYPE_bit_size(res); 00257 hob_state = HOB_zero_xtd; // assume all addresses are 0-extended in register 00258 hob_to_do = HOB_none; 00259 return tree; 00260 00261 // unary ops 00262 00263 case OPR_SQRT: case OPR_RSQRT: case OPR_RECIP: 00264 case OPR_PAREN: 00265 case OPR_REALPART: case OPR_IMAGPART: 00266 case OPR_HIGHPART: case OPR_LOWPART: 00267 return U64_LOWER_form_node(new_nd, tree); 00268 00269 case OPR_LNOT: 00270 if (MTYPE_bit_size(res) > maxsize) 00271 U64_LOWER_insert_cvtl_for_kid(new_nd, hob_to_do, 0, maxsize, hob_state); 00272 maxsize = 1; 00273 hob_state = HOB_zero_xtd; 00274 hob_to_do = HOB_none; 00275 return U64_LOWER_form_node(new_nd, tree); 00276 00277 case OPR_ALLOCA: 00278 U64_LOWER_insert_cvtl_for_kid(new_nd, hob_to_do, 0, maxsize, hob_state); 00279 maxsize = MTYPE_bit_size(res); 00280 hob_state = HOB_zero_xtd; // all addresses are 0-extended in register 00281 hob_to_do = HOB_none; 00282 return U64_LOWER_form_node(new_nd, tree); 00283 00284 case OPR_NEG: 00285 if (MTYPE_is_integral(res)) { 00286 if (maxsize < MTYPE_bit_size(res)) { // enlarge Kid 0 00287 U64_LOWER_insert_cvtl_for_kid(new_nd, hob_to_do, 0, maxsize, hob_state); 00288 } 00289 U64_LOWER_set_rtype(new_nd, Mtype_TransferSize(MTYPE_A8, res)); 00290 } 00291 return U64_LOWER_form_node(new_nd, tree); 00292 00293 case OPR_EXTRACT_BITS: 00294 U64_LOWER_insert_cvtl_for_kid(new_nd, hob_to_do, 0, maxsize, hob_state); 00295 // if bit offset is 0, can do same optimization as ORP_CVTL; omit for now 00296 U64_LOWER_set_rtype(new_nd, Mtype_TransferSize(MTYPE_A8, res)); 00297 maxsize = U64_LOWER_bit_size(tree); // maxsize cannot be 64 or 0 00298 hob_state = MTYPE_signed(res) ? HOB_sign_xtd : HOB_zero_xtd; 00299 hob_to_do = HOB_none; 00300 return U64_LOWER_form_node(new_nd, tree); 00301 00302 case OPR_BNOT: 00303 if (maxsize < MTYPE_bit_size(res)) 00304 U64_LOWER_insert_cvtl_for_kid(new_nd, hob_to_do, 0, maxsize, hob_state); 00305 if (MTYPE_bit_size(res) == 64) { 00306 hob_to_do = HOB_none; 00307 maxsize = 64; 00308 } 00309 else { 00310 U64_LOWER_set_rtype(new_nd, Mtype_TransferSize(MTYPE_A8, res)); 00311 hob_to_do = MTYPE_signed(res) ? HOB_sign_xtd : HOB_zero_xtd; 00312 maxsize = MTYPE_bit_size(res); 00313 hob_state = HOB_none; // because after the bitwise not operation 00314 } 00315 return U64_LOWER_form_node(new_nd, tree); 00316 00317 case OPR_PARM: 00318 case OPR_TAS: 00319 if (MTYPE_bit_size(res) > maxsize) 00320 U64_LOWER_insert_cvtl_for_kid(new_nd, hob_to_do, 0, maxsize, hob_state); 00321 maxsize = MTYPE_is_integral(res) ? 64 : 0; 00322 return U64_LOWER_form_node(new_nd, tree); 00323 00324 case OPR_ABS: 00325 if (maxsize != 0 && maxsize != 64) { 00326 U64_LOWER_insert_cvtl_for_kid(new_nd, hob_to_do, 0, maxsize, hob_state); 00327 hob_state = HOB_zero_xtd; 00328 hob_to_do = HOB_zero_xtd; 00329 // leave maxsize's value unchanged 00330 } 00331 if (MTYPE_is_integral(res)) 00332 U64_LOWER_set_rtype(new_nd, Mtype_TransferSize(MTYPE_A8, res)); 00333 return U64_LOWER_form_node(new_nd, tree); 00334 00335 case OPR_CVTL: 00336 if (U64_LOWER_cvtl_bits(tree) > maxsize) { 00337 if (MTYPE_signed(res) && 00338 (hob_to_do == HOB_sign_xtd || 00339 hob_to_do == HOB_none && hob_state == HOB_sign_xtd) || 00340 (hob_to_do == HOB_zero_xtd || 00341 hob_to_do == HOB_none && hob_state == HOB_zero_xtd) ) { 00342 // CVTL can be deleted 00343 } 00344 else { 00345 U64_LOWER_insert_cvtl_for_kid(new_nd, hob_to_do, 0, maxsize, hob_state); 00346 maxsize = U64_LOWER_cvtl_bits(tree); 00347 hob_state = MTYPE_signed(res) ? HOB_sign_xtd : HOB_zero_xtd; 00348 hob_to_do = HOB_none; 00349 return U64_LOWER_form_node(new_nd, tree); 00350 } 00351 } 00352 else { 00353 maxsize = U64_LOWER_cvtl_bits(tree); 00354 hob_state = HOB_none; 00355 hob_to_do = MTYPE_signed(res) ? HOB_sign_xtd : HOB_zero_xtd; 00356 } 00357 // CVTL can be omitted because delayed 00358 nd = U64_LOWER_kid0(new_nd); 00359 U64_LOWER_delete(tree); 00360 return nd; 00361 00362 case OPR_CVT: 00363 if (! MTYPE_is_integral(res)) { 00364 U64_LOWER_insert_cvtl_for_kid(new_nd, hob_to_do, 0, maxsize, hob_state); 00365 maxsize = 0; 00366 if (MTYPE_is_integral(desc)) 00367 U64_LOWER_set_desc(new_nd, Mtype_TransferSize(MTYPE_A8, desc)); 00368 return U64_LOWER_form_node(new_nd, tree); 00369 } 00370 if (! MTYPE_is_integral(desc) || desc == MTYPE_B) { 00371 // res must be integral here 00372 U64_LOWER_set_rtype(new_nd, Mtype_TransferSize(MTYPE_A8, res)); 00373 maxsize = 64; 00374 return U64_LOWER_form_node(new_nd, tree); 00375 } 00376 if (MTYPE_bit_size(res) < maxsize) { // truncation 00377 maxsize = MTYPE_bit_size(res); 00378 hob_state = HOB_none; 00379 hob_to_do = MTYPE_signed(res) ? HOB_sign_xtd : HOB_zero_xtd; 00380 } 00381 else if (MTYPE_bit_size(desc) == maxsize) { 00382 if (MTYPE_bit_size(res) == MTYPE_bit_size(desc)) 00383 hob_to_do = MTYPE_signed(res) ? HOB_sign_xtd : HOB_zero_xtd; 00384 else hob_to_do = MTYPE_signed(desc) ? HOB_sign_xtd : HOB_zero_xtd; 00385 } 00386 // this CVT can be omitted 00387 nd = U64_LOWER_kid0(new_nd); 00388 U64_LOWER_delete(tree); 00389 return nd; 00390 00391 case OPR_MINPART: case OPR_MAXPART: 00392 if (! MTYPE_is_integral(res) || res == MTYPE_B) 00393 return U64_LOWER_form_node(new_nd, tree); 00394 // fall thru 00395 case OPR_RND: case OPR_TRUNC: case OPR_CEIL: case OPR_FLOOR: 00396 U64_LOWER_set_rtype(new_nd, Mtype_TransferSize(MTYPE_A8, res)); 00397 maxsize = 64; 00398 return U64_LOWER_form_node(new_nd, tree); 00399 00400 // binary ops 00401 00402 case OPR_ADD: case OPR_SUB: 00403 if (MTYPE_is_integral(res) && res != MTYPE_B) { 00404 if (maxsize < MTYPE_bit_size(res)) { // enlarge Kid 0 00405 U64_LOWER_insert_cvtl_for_kid(new_nd, hob_to_do, 0, maxsize, hob_state); 00406 } 00407 if (maxsize1 < MTYPE_bit_size(res)) { // enlarge Kid 1 00408 U64_LOWER_insert_cvtl_for_kid(new_nd, hob_to_do1, 1, maxsize1, hob_state1); 00409 } 00410 U64_LOWER_set_rtype(new_nd, Mtype_TransferSize(MTYPE_A8, res)); 00411 maxsize = MIN(MAX(maxsize, maxsize1) + 1, 64); 00412 // if both operands's high-order bits were already in designated state and 00413 // the operation's result cannot overflow the bit size, just return 00414 if (hob_state != HOB_none && hob_state == hob_state1 && 00415 (hob_to_do == HOB_none || hob_to_do == hob_state) && 00416 (hob_to_do1 == HOB_none || hob_to_do1 == hob_state1) && 00417 maxsize <= MTYPE_bit_size(res)) 00418 return U64_LOWER_form_node(new_nd, tree); 00419 if (maxsize > MTYPE_bit_size(res)) 00420 maxsize = MTYPE_bit_size(res); // can overflow, so need to truncate 00421 hob_state = HOB_none; 00422 hob_to_do = MTYPE_signed(res) ? HOB_sign_xtd : HOB_zero_xtd; 00423 } 00424 return U64_LOWER_form_node(new_nd, tree); 00425 00426 case OPR_MPY: // coming in must be either 64-bit or 32-bit 00427 if (MTYPE_is_integral(res) && res != MTYPE_B) { 00428 // in our implementation of int multiply, the high-order bits of the 00429 // operands are not looked at and the high-order bits of the result can 00430 // contain garbage 00431 if (maxsize < maxsize1) { // enlarge Kid 0 00432 U64_LOWER_insert_cvtl_for_kid(new_nd, hob_to_do, 0, maxsize, hob_state); 00433 maxsize = maxsize1; 00434 } 00435 if (maxsize > maxsize1) { // enlarge Kid 1 00436 U64_LOWER_insert_cvtl_for_kid(new_nd, hob_to_do1, 1, maxsize1, hob_state1); 00437 } 00438 00439 if (MTYPE_bit_size(res) == 64 && maxsize > 16) { // use 64-bit MPY 00440 if (maxsize < 64) { 00441 U64_LOWER_insert_cvtl_for_kid(new_nd, hob_to_do, 0, maxsize, hob_state); 00442 U64_LOWER_insert_cvtl_for_kid(new_nd, hob_to_do1, 1, maxsize1, hob_state1); 00443 } 00444 U64_LOWER_set_rtype(new_nd, Mtype_TransferSize(MTYPE_A8, res)); 00445 maxsize = 64; 00446 } 00447 else if (maxsize > 8) { // use 32-bit MPY 00448 if (maxsize < 32) { 00449 U64_LOWER_insert_cvtl_for_kid(new_nd, hob_to_do, 0, maxsize, hob_state); 00450 U64_LOWER_insert_cvtl_for_kid(new_nd, hob_to_do1, 1, maxsize1, hob_state1); 00451 } 00452 U64_LOWER_set_rtype(new_nd, Mtype_TransferSize(MTYPE_A4, res)); 00453 maxsize = 32; 00454 } 00455 else if (maxsize > 4) { // use 16-bit MPY 00456 if (maxsize < 16) { 00457 U64_LOWER_insert_cvtl_for_kid(new_nd, hob_to_do, 0, maxsize, hob_state); 00458 U64_LOWER_insert_cvtl_for_kid(new_nd, hob_to_do1, 1, maxsize1, hob_state1); 00459 } 00460 U64_LOWER_set_rtype(new_nd, Mtype_TransferSize(MTYPE_I2, res)); 00461 maxsize = 16; 00462 } 00463 else { // use 8-bit MPY 00464 if (maxsize < 8) { 00465 U64_LOWER_insert_cvtl_for_kid(new_nd, hob_to_do, 0, maxsize, hob_state); 00466 U64_LOWER_insert_cvtl_for_kid(new_nd, hob_to_do1, 1, maxsize1, hob_state1); 00467 } 00468 U64_LOWER_set_rtype(new_nd, Mtype_TransferSize(MTYPE_I1, res)); 00469 maxsize = 8; 00470 } 00471 00472 if (MTYPE_bit_size(res) == 32 && maxsize > 32) 00473 maxsize = 32; // for [IU]4MPY, extra truncation at 32-bit boundary 00474 hob_state = HOB_none; 00475 hob_to_do = MTYPE_signed(res) ? HOB_sign_xtd : HOB_zero_xtd; 00476 } 00477 return U64_LOWER_form_node(new_nd, tree); 00478 00479 case OPR_DIV: 00480 case OPR_MOD: case OPR_REM: 00481 case OPR_DIVREM: 00482 // in our implementation of int divide, the high-order bits of the 00483 // operands ARE looked at and the high-order bits of the result does NOT 00484 // contain garbage; will leave operation as original size (4 or 8 bytes) 00485 // since smaller-size operation translates to shorter code sequence 00486 if (MTYPE_is_integral(res) && res != MTYPE_B) { 00487 #if 0 // this has problem with pregs introduced by wopt of types I8/U8 00488 Is_True(MTYPE_bit_size(res) >= maxsize && 00489 MTYPE_bit_size(res) >= maxsize1, 00490 ("size of operation smaller than size of operand")); 00491 #endif 00492 if (opr == OPR_DIV || opr == OPR_DIVREM) 00493 new_maxsize = maxsize; 00494 else new_maxsize = maxsize1; 00495 // [IU]4DIV assumes high-order 32-bits do not contain garbage 00496 U64_LOWER_insert_cvtl_for_kid(new_nd, hob_to_do, 0, maxsize, hob_state); 00497 U64_LOWER_insert_cvtl_for_kid(new_nd, hob_to_do1, 1, maxsize1, hob_state1); 00498 // following needed because operand of 32-bit div may be of different sign 00499 // e.g. for -2 under U4DIV, need to zero-out the high-order 32 bits 00500 if (res == MTYPE_I4) { 00501 U64_LOWER_insert_cvtl_for_kid(new_nd, HOB_sign_xtd, 0, 32, hob_state); 00502 U64_LOWER_insert_cvtl_for_kid(new_nd, HOB_sign_xtd, 1, 32, hob_state1); 00503 } 00504 else if (res == MTYPE_U4) { 00505 U64_LOWER_insert_cvtl_for_kid(new_nd, HOB_zero_xtd, 0, 32, hob_state); 00506 U64_LOWER_insert_cvtl_for_kid(new_nd, HOB_zero_xtd, 1, 32, hob_state1); 00507 } 00508 00509 maxsize = new_maxsize; 00510 // high-order 32-bits of result guaranteed clean 00511 hob_state = MTYPE_signed(res) ? HOB_sign_xtd : HOB_zero_xtd; 00512 hob_to_do = HOB_none; 00513 } 00514 return U64_LOWER_form_node(new_nd, tree); 00515 00516 case OPR_BAND: case OPR_BIOR: case OPR_BNOR: case OPR_BXOR: 00517 // the sign in these operators are somewhat arbitrary, so need to be 00518 // less aggressive (751054) 00519 if (desc != MTYPE_B) { 00520 U64_LOWER_insert_cvtl_for_kid(new_nd, hob_to_do, 0, maxsize, hob_state); 00521 U64_LOWER_insert_cvtl_for_kid(new_nd, hob_to_do1, 1, maxsize1, hob_state1); 00522 maxsize = MAX(maxsize, maxsize1); 00523 U64_LOWER_set_rtype(new_nd, Mtype_TransferSize(MTYPE_A8, res)); 00524 hob_state = HOB_none; 00525 hob_to_do = HOB_none; 00526 } 00527 return U64_LOWER_form_node(new_nd, tree); 00528 00529 case OPR_MAX: case OPR_MIN: 00530 if (MTYPE_is_integral(desc) && desc != MTYPE_B) { 00531 // desc size is either 64 or 32; make both operands at least that size 00532 if (maxsize < MTYPE_bit_size(desc)) // enlarge Kid 0 00533 U64_LOWER_insert_cvtl_for_kid(new_nd, hob_to_do, 0, maxsize, hob_state); 00534 if (maxsize1 < MTYPE_bit_size(desc)) // enlarge Kid 1 00535 U64_LOWER_insert_cvtl_for_kid(new_nd, hob_to_do1, 1, maxsize1, hob_state1); 00536 maxsize = MAX(maxsize, maxsize1); 00537 if (MTYPE_bit_size(desc) == 64) { 00538 hob_to_do = HOB_none; 00539 hob_state = MTYPE_signed(desc) ? HOB_sign_xtd : HOB_zero_xtd; 00540 } 00541 else { 00542 if (hob_to_do == hob_state && hob_to_do1 == hob_state1 || 00543 hob_to_do == HOB_none && hob_to_do1 == HOB_none) { 00544 hob_to_do = HOB_none; 00545 hob_state = MTYPE_signed(desc) ? HOB_sign_xtd : HOB_zero_xtd; 00546 } 00547 else { 00548 hob_state = HOB_none; 00549 hob_to_do = MTYPE_signed(desc) ? HOB_sign_xtd : HOB_zero_xtd; 00550 } 00551 } 00552 } 00553 return U64_LOWER_form_node(new_nd, tree); 00554 00555 case OPR_MINMAX: 00556 if (MTYPE_is_integral(desc) && desc != MTYPE_B) { 00557 U64_LOWER_insert_cvtl_for_kid(new_nd, hob_to_do, 0, maxsize, hob_state); 00558 U64_LOWER_insert_cvtl_for_kid(new_nd, hob_to_do1, 1, maxsize1, hob_state1); 00559 maxsize = MAX(maxsize, maxsize1); 00560 U64_LOWER_set_rtype(new_nd, Mtype_TransferSize(MTYPE_A8, res)); 00561 hob_state = MTYPE_signed(desc) ? HOB_sign_xtd : HOB_zero_xtd; 00562 hob_to_do = HOB_none; 00563 } 00564 return U64_LOWER_form_node(new_nd, tree); 00565 00566 case OPR_EQ: case OPR_NE: 00567 case OPR_GE: case OPR_GT: case OPR_LE: case OPR_LT: 00568 if (MTYPE_is_integral(desc) && desc != MTYPE_B) { 00569 // desc size is either 64 or 32; make both operands at least that size 00570 if (maxsize < MTYPE_bit_size(desc)) // enlarge Kid 0 00571 U64_LOWER_insert_cvtl_for_kid(new_nd, hob_to_do, 0, maxsize, hob_state); 00572 if (maxsize1 < MTYPE_bit_size(desc)) // enlarge Kid 1 00573 U64_LOWER_insert_cvtl_for_kid(new_nd, hob_to_do1, 1, maxsize1, hob_state1); 00574 } 00575 maxsize = 0; // since result is type B 00576 return U64_LOWER_form_node(new_nd, tree); 00577 00578 case OPR_ASHR: case OPR_LSHR: 00579 if (MTYPE_bit_size(res) == 64) { 00580 U64_LOWER_insert_cvtl_for_kid(new_nd, hob_to_do, 0, maxsize, hob_state); 00581 U64_LOWER_insert_cvtl_for_kid(new_nd, hob_to_do1, 1, maxsize1, hob_state1); 00582 // maxsize is maxsize of left operand 00583 hob_state = (opr == OPR_ASHR) ? HOB_sign_xtd : HOB_zero_xtd; 00584 hob_to_do = HOB_none; 00585 return U64_LOWER_form_node(new_nd, tree); 00586 } 00587 // MTYPE_bit_size(res) == 32 00588 if (U64_LOWER_operator(U64_LOWER_kid1(tree)) == OPR_INTCONST) { 00589 // I4SHR will translate to extr, U4SHR to extr.u 00590 if (maxsize < 32) { // CVTL for kid 0 00591 U64_LOWER_insert_cvtl_for_kid(new_nd, hob_to_do, 0, maxsize, hob_state); 00592 } 00593 } 00594 else { // variable shift amount 00595 if (maxsize < 32) { // CVTL for kid 0 00596 U64_LOWER_insert_cvtl_for_kid(new_nd, hob_to_do, 0, maxsize, hob_state); 00597 } 00598 00599 if (maxsize > 32) { // truncate kid via a CVTL 32 00600 nd = U64_LOWER_create_cvtl((opr == OPR_ASHR) ? MTYPE_I8 : MTYPE_U8, 00601 U64_LOWER_kid0(tree), 32); 00602 U64_LOWER_set_kid0(new_nd, nd); 00603 } 00604 else { 00605 if (opr == OPR_ASHR && hob_state != HOB_sign_xtd) 00606 U64_LOWER_insert_cvtl_for_kid(new_nd, HOB_sign_xtd, 0, 32, hob_state); 00607 else if (opr == OPR_LSHR && hob_state != HOB_zero_xtd) 00608 U64_LOWER_insert_cvtl_for_kid(new_nd, HOB_zero_xtd, 0, 32, hob_state); 00609 } 00610 00611 U64_LOWER_insert_cvtl_for_kid(new_nd, hob_to_do1, 1, maxsize1, hob_state1); // kid 1 00612 U64_LOWER_set_rtype(new_nd, Mtype_TransferSize(MTYPE_A8, res)); 00613 } 00614 maxsize = 32; 00615 hob_state = (opr == OPR_ASHR) ? HOB_sign_xtd : HOB_zero_xtd; 00616 hob_to_do = HOB_none; 00617 return U64_LOWER_form_node(new_nd, tree); 00618 00619 case OPR_SHL: 00620 if (MTYPE_bit_size(res) == 64) { 00621 U64_LOWER_insert_cvtl_for_kid(new_nd, hob_to_do, 0, maxsize, hob_state); 00622 U64_LOWER_insert_cvtl_for_kid(new_nd, hob_to_do1, 1, maxsize1, hob_state1); 00623 maxsize = 64; 00624 return U64_LOWER_form_node(new_nd, tree); 00625 } 00626 // MTYPE_bit_size(res) == 32 00627 if (maxsize < 32) { // CVTL for kid 0 00628 U64_LOWER_insert_cvtl_for_kid(new_nd, hob_to_do, 0, maxsize, hob_state); 00629 } 00630 maxsize = 32; 00631 hob_state = HOB_none; 00632 hob_to_do = MTYPE_signed(res) ? HOB_sign_xtd : HOB_zero_xtd; 00633 if (U64_LOWER_operator(U64_LOWER_kid1(tree)) == OPR_INTCONST) { 00634 // I4SHL and U4SHL will translate to dep.z 00635 return U64_LOWER_form_node(new_nd, tree); 00636 } 00637 else { // variable shift amount 00638 U64_LOWER_insert_cvtl_for_kid(new_nd, hob_to_do1, 1, maxsize1, hob_state1); // kid 1 00639 U64_LOWER_set_rtype(new_nd, Mtype_TransferSize(MTYPE_A8, res)); 00640 return U64_LOWER_form_node(new_nd, tree); 00641 } 00642 00643 case OPR_COMPOSE_BITS: 00644 if (maxsize <= (U64_LOWER_bit_size(tree) + U64_LOWER_bit_offset(tree))) 00645 U64_LOWER_insert_cvtl_for_kid(new_nd, hob_to_do, 0, maxsize, hob_state); 00646 if (maxsize1 < U64_LOWER_bit_size(tree)) 00647 U64_LOWER_insert_cvtl_for_kid(new_nd, hob_to_do1, 1, maxsize1, hob_state1); 00648 U64_LOWER_set_rtype(new_nd, Mtype_TransferSize(MTYPE_A8, res)); 00649 return U64_LOWER_form_node(new_nd, tree); 00650 00651 case OPR_LAND: case OPR_LIOR: 00652 case OPR_COMPLEX: 00653 return U64_LOWER_form_node(new_nd, tree); 00654 00655 default: 00656 Is_True(FALSE,("unexpected operator")); 00657 } 00658 return NULL; 00659 } 00660 00661 #endif