Open64 (mfef90, whirl2f, and IR tools)  TAG: version-openad; SVN changeset: 916
u64_lower_template.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 //-*-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
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Defines