00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026
00027
00028
00029
00030
00031
00032
00033
00034
00035
00036
00037
00038
00039
00040
00041
00042
00043
00044
00045
00046
00047
00048
00049
00050
00051
00052
00053 #include "defs.h"
00054 #include "errors.h"
00055 #include "util.h"
00056 #include "tracing.h"
00057 #include "topcode.h"
00058 #include "wn.h"
00059 #include "opcode.h"
00060 #include "config_targ.h"
00061 #include "targ_isa_lits.h"
00062 #include "betarget.h"
00063 #include "w2op.h"
00064
00065 BOOL Targ_Lower_Float_To_Unsigned = FALSE;
00066 BOOL Targ_Lower_Unsigned_To_Float = FALSE;
00067
00068
00069 INT Max_Small_Frame_Offset = 0x1fff;
00070
00071
00072
00073 TOP
00074 OPCODE_To_TOP (OPCODE opcode)
00075 {
00076 OPERATOR opr = OPCODE_operator (opcode);
00077 TYPE_ID rtype = OPCODE_rtype (opcode);
00078 TYPE_ID desc = OPCODE_desc (opcode);
00079
00080 switch (opr) {
00081
00082 case OPR_FORWARD_BARRIER:
00083 return TOP_fwd_bar;
00084
00085 case OPR_BACKWARD_BARRIER:
00086 return TOP_bwd_bar;
00087
00088 case OPR_INTRINSIC_CALL:
00089 if (rtype == MTYPE_V) return TOP_intrncall;
00090 else return TOP_UNDEFINED;
00091
00092 case OPR_NEG:
00093 if (rtype == MTYPE_F4 || rtype == MTYPE_F8 || rtype == MTYPE_F10)
00094 return TOP_fneg;
00095 else
00096 return TOP_UNDEFINED;
00097
00098 case OPR_ABS:
00099 if (rtype == MTYPE_F4 || rtype == MTYPE_F8 || rtype == MTYPE_F10)
00100 return TOP_fabs;
00101 else
00102 return TOP_UNDEFINED;
00103
00104 case OPR_PAREN:
00105 if (rtype == MTYPE_F4 || rtype == MTYPE_F8 || rtype == MTYPE_F10)
00106 return TOP_nop;
00107 else
00108 return TOP_UNDEFINED;
00109
00110 case OPR_PARM:
00111 return TOP_nop;
00112
00113 case OPR_TRAP:
00114 return TOP_break;
00115
00116 default:
00117 return TOP_UNDEFINED;
00118 }
00119 }
00120
00121
00122
00123 TOP
00124 TAS_To_TOP (WN *tas_wn)
00125 {
00126 TYPE_ID kid_mtype = WN_rtype(WN_kid0(tas_wn));
00127
00128 switch (WN_opcode(tas_wn)) {
00129 case OPC_I8TAS:
00130 case OPC_U8TAS:
00131 return MTYPE_float(kid_mtype) ? TOP_getf_d : TOP_nop;
00132 case OPC_I4TAS:
00133 case OPC_U4TAS:
00134 return MTYPE_float(kid_mtype) ? TOP_getf_s : TOP_nop;
00135 case OPC_F8TAS:
00136 return MTYPE_float(kid_mtype) ? TOP_nop : TOP_setf_d;
00137 case OPC_F4TAS:
00138 return MTYPE_float(kid_mtype) ? TOP_nop : TOP_setf_s;
00139 default:
00140 return TOP_UNDEFINED;
00141 }
00142 }
00143
00144
00145
00146 #define IS_POWER_OF_2(val) ((val != 0) && ((val & (val-1)) == 0))
00147
00148 static BOOL Is_Power_Of_2(INT64 val, TYPE_ID mtype)
00149 {
00150 if (MTYPE_is_signed(mtype) && val < 0)
00151 val= -val;
00152
00153 if (mtype == MTYPE_U4)
00154 val &= 0xffffffffull;
00155
00156 return IS_POWER_OF_2(val);
00157 }
00158
00159
00160 extern BOOL
00161 Can_Do_Fast_Divide (TYPE_ID mtype, INT64 dividend)
00162 {
00163 if (Is_Power_Of_2(dividend, mtype)) {
00164 return TRUE;
00165 }
00166 return FALSE;
00167 }
00168
00169
00170 extern BOOL
00171 Can_Do_Fast_Remainder (TYPE_ID mtype, INT64 dividend)
00172 {
00173 if (Is_Power_Of_2(dividend, mtype)) {
00174 return TRUE;
00175 }
00176 return FALSE;
00177 }
00178
00179
00180
00181
00182
00183
00184
00185
00186
00187
00188
00189
00190
00191
00192
00193 extern INT
00194 Multiply_Limit( BOOL is_64bit, INT64 val)
00195 {
00196 INT limit = 0;
00197
00198 if (is_64bit) {
00199 switch( Target ) {
00200 case TARGET_ITANIUM: limit = 14; break;
00201 case TARGET_ITANIUM2: limit = 14; break;
00202 default: limit = 14; break;
00203 }
00204 } else {
00205 switch( Target ) {
00206 case TARGET_ITANIUM: limit = 14; break;
00207 case TARGET_ITANIUM2: limit = 14; break;
00208 default: limit = 14; break;
00209 }
00210 }
00211 return limit;
00212 }
00213
00214 extern INT
00215 Divide_Limit ( BOOL is_64bit)
00216 {
00217 INT limit = 0;
00218 if (is_64bit) {
00219 switch( Target ) {
00220 case TARGET_ITANIUM: limit = 50; break;
00221 case TARGET_ITANIUM2: limit = 50; break;
00222 default: limit = 50; break;
00223 }
00224 } else {
00225 switch( Target ) {
00226 case TARGET_ITANIUM: limit = 50; break;
00227 case TARGET_ITANIUM2: limit = 50; break;
00228 default: limit = 50; break;
00229 }
00230 }
00231 return ( limit );
00232 }
00233
00234
00235
00236
00237 static INT
00238 Count_Multiply_Shifts (TARG_UINT constant)
00239 {
00240 switch (constant) {
00241 case 0:
00242 case 1:
00243 case 2:
00244 return 1;
00245 default:
00246 if ((constant % 2) == 1) {
00247 if ((constant & 2) != 0)
00248 return 1 + Count_Multiply_Shifts (constant+1);
00249 else
00250 return 1 + Count_Multiply_Shifts (constant-1);
00251 }
00252 else {
00253 while ((constant % 2) == 0) {
00254 constant = (TARG_UINT)constant >> 1;
00255 }
00256 if (constant == 1)
00257 return 1;
00258 else
00259 return 1 + Count_Multiply_Shifts (constant);
00260 }
00261 }
00262 }
00263
00264
00265
00266 extern BOOL
00267 Can_Do_Fast_Multiply (TYPE_ID mtype, INT64 val)
00268 {
00269 INT limit;
00270 INT num = 0;
00271
00272
00273 INT num_ones=0;
00274 INT num_ones_neg=0;
00275
00276 if (val < 0) val = -val;
00277
00278 UINT64 uc=val;
00279 while (uc) {num_ones += (uc&1); uc >>= 1;}
00280
00281 uc = val;
00282 if (uc <= 63) return (TRUE);
00283
00284 if (num_ones == 1) return (TRUE);
00285 while ((uc & 1) == 0) {uc >>= 1;}
00286
00287 if (uc == ((1<<num_ones)-1)) return (TRUE);
00288
00289
00290
00291
00292
00293
00294
00295
00296
00297
00298 if (OPT_Space) return FALSE;
00299 if (uc <= 65535) return TRUE;
00300 return FALSE;
00301 }
00302
00303
00304
00305
00306 INT Copy_Quantum_Ratio(void)
00307 {
00308 INT32 ratio;
00309
00310
00311
00312 switch(Target) {
00313 case TARGET_ITANIUM: ratio= 4; break;
00314 case TARGET_ITANIUM2: ratio= 4; break;
00315 default: ratio= 4; break;
00316 }
00317
00318 return ratio;
00319 }
00320
00321
00322
00323 inline BOOL Is_Signed_Bits(INT64 val, INT bits)
00324 {
00325 INT64 hibit = 1LL << (bits - 1);
00326 return val >= -hibit && val <= (hibit - 1);
00327 }
00328
00329
00330
00331
00332 inline BOOL Is_Unsigned_Bits(UINT64 val, INT bits)
00333 {
00334 return val < (1ULL << bits);
00335 }
00336
00337
00338
00339
00340 BOOL Can_Be_Immediate(OPERATOR opr,
00341 INT64 val,
00342 TYPE_ID dtype,
00343 INT whichkid,
00344 ST *stid_st)
00345 {
00346
00347 if (val == 0) return TRUE;
00348
00349 switch (opr) {
00350 case OPR_AGOTO:
00351 case OPR_LOOP_INFO:
00352 return TRUE;
00353
00354 case OPR_EQ:
00355 case OPR_NE:
00356 case OPR_GE:
00357 case OPR_GT:
00358 case OPR_LE:
00359 case OPR_LT:
00360 case OPR_MAX:
00361 case OPR_MIN:
00362
00363
00364
00365 if (!MTYPE_is_size_double(dtype)) val = (INT32)val;
00366
00367 switch (opr) {
00368 case OPR_LE:
00369 case OPR_GT:
00370 whichkid = !whichkid;
00371
00372 case OPR_LT:
00373 case OPR_GE:
00374 if (whichkid == 1) val = val - 1;
00375 break;
00376 }
00377
00378 return Is_Signed_Bits(val, 8);
00379
00380 case OPR_ASHR:
00381 case OPR_LSHR:
00382 case OPR_MLOAD:
00383 case OPR_SHL:
00384
00385 return whichkid == 1;
00386
00387 case OPR_MSTORE:
00388
00389 return whichkid == 2;
00390
00391 case OPR_BAND:
00392 case OPR_BIOR:
00393 case OPR_BXOR:
00394
00395 return Is_Signed_Bits(val, 8);
00396
00397 case OPR_SUB:
00398
00399
00400
00401
00402 if (whichkid == 0) return Is_Signed_Bits(val, 8);
00403 return Is_Signed_Bits(-val, 14);
00404
00405 case OPR_ADD:
00406
00407 return Is_Signed_Bits(val, 14);
00408
00409 case OPR_DIV:
00410
00411 return whichkid == 1 && Can_Do_Fast_Divide(dtype, val);
00412
00413 case OPR_REM:
00414 case OPR_MOD:
00415
00416 return whichkid == 1 && Can_Do_Fast_Remainder(dtype, val);
00417
00418 case OPR_DIVREM:
00419
00420 return whichkid == 1
00421 && Can_Do_Fast_Remainder(dtype, val)
00422 && Can_Do_Fast_Divide(dtype, val);
00423
00424 case OPR_MPY:
00425
00426 return Can_Do_Fast_Multiply(dtype, val);
00427
00428 case OPR_SELECT:
00429
00430
00431
00432 return whichkid > 0 && Is_Signed_Bits(val, 22);
00433
00434 case OPR_CALL:
00435 case OPR_ICALL:
00436 case OPR_INTRINSIC_CALL:
00437 case OPR_PARM:
00438
00439
00440
00441 return TRUE;
00442
00443 case OPR_STID:
00444
00445
00446
00447 return ST_class(stid_st) == CLASS_PREG;
00448 }
00449
00450 return FALSE;
00451 }