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
00054
00055
00056
00057 #include "defs.h"
00058 #include "errors.h"
00059 #include "util.h"
00060 #include "tracing.h"
00061 #include "topcode.h"
00062 #include "wn.h"
00063 #include "opcode.h"
00064 #include "config_targ.h"
00065 #include "targ_isa_lits.h"
00066 #include "betarget.h"
00067 #include "w2op.h"
00068
00069
00070 BOOL Targ_Lower_Float_To_Unsigned = FALSE;
00071 BOOL Targ_Lower_Unsigned_To_Float = FALSE;
00072
00073
00074 INT Max_Small_Frame_Offset = 0x7fffffff;
00075
00076
00077
00078 TOP
00079 OPCODE_To_TOP (OPCODE opcode)
00080 {
00081 OPERATOR opr = OPCODE_operator (opcode);
00082 TYPE_ID rtype = OPCODE_rtype (opcode);
00083 TYPE_ID desc = OPCODE_desc (opcode);
00084
00085 switch (opr) {
00086
00087 case OPR_GOTO:
00088 case OPR_GOTO_OUTER_BLOCK:
00089 return TOP_jmp;
00090
00091 case OPR_FORWARD_BARRIER:
00092 return TOP_fwd_bar;
00093
00094 case OPR_BACKWARD_BARRIER:
00095 return TOP_bwd_bar;
00096
00097 case OPR_INTRINSIC_CALL:
00098 if (rtype == MTYPE_V) return TOP_intrncall;
00099 else return TOP_UNDEFINED;
00100
00101 case OPR_NEG:
00102 return TOP_UNDEFINED;
00103
00104 case OPR_ABS:
00105 return TOP_UNDEFINED;
00106
00107 case OPR_PAREN:
00108 if (rtype == MTYPE_F4) return TOP_noop;
00109 else if (rtype == MTYPE_F8) return TOP_noop;
00110 #ifdef TARG_X8664
00111 else if (rtype == MTYPE_FQ) return TOP_noop;
00112 else if (rtype == MTYPE_I1) return TOP_noop;
00113 else if (rtype == MTYPE_I2) return TOP_noop;
00114 else if (rtype == MTYPE_I4) return TOP_noop;
00115 else if (rtype == MTYPE_I8) return TOP_noop;
00116 else if (rtype == MTYPE_V16F4) return TOP_noop;
00117 else if (rtype == MTYPE_V16F8) return TOP_noop;
00118 else if (rtype == MTYPE_V16I1) return TOP_noop;
00119 else if (rtype == MTYPE_V16I2) return TOP_noop;
00120 else if (rtype == MTYPE_V16I4) return TOP_noop;
00121 else if (rtype == MTYPE_V16I8) return TOP_noop;
00122 else if (rtype == MTYPE_V16C4) return TOP_noop;
00123 else if (rtype == MTYPE_V16C8) return TOP_noop;
00124 #endif
00125 else return TOP_UNDEFINED;
00126
00127 case OPR_PARM:
00128 return TOP_noop;
00129
00130 case OPR_TRAP:
00131 FmtAssert( FALSE, ("UNIMPLEMENTED") );
00132
00133 default:
00134 return TOP_UNDEFINED;
00135 }
00136 }
00137
00138
00139
00140 TOP
00141 TAS_To_TOP (WN *tas_wn)
00142 {
00143 TYPE_ID kid_mtype = WN_rtype(WN_kid0(tas_wn));
00144
00145 switch (WN_opcode(tas_wn)) {
00146 case OPC_I8TAS:
00147 case OPC_U8TAS:
00148 if (Is_Target_32bit())
00149 return TOP_UNDEFINED;
00150 return MTYPE_float(kid_mtype) ? TOP_movx2g64 : TOP_nop;
00151 case OPC_I4TAS:
00152 case OPC_U4TAS:
00153 if (Is_Target_32bit() && !Is_Target_SSE2())
00154 return TOP_UNDEFINED;
00155 return MTYPE_float(kid_mtype) ? TOP_movx2g : TOP_nop;
00156 case OPC_F8TAS:
00157 if (Is_Target_32bit())
00158 return TOP_UNDEFINED;
00159 return MTYPE_float(kid_mtype) ? TOP_nop : TOP_movg2x64;
00160 case OPC_F4TAS:
00161 if (Is_Target_32bit() && !Is_Target_SSE2())
00162 return TOP_UNDEFINED;
00163 return MTYPE_float(kid_mtype) ? TOP_nop : TOP_movg2x;
00164 default:
00165 return TOP_UNDEFINED;
00166 }
00167 }
00168
00169
00170
00171 #define IS_POWER_OF_2(val) ((val != 0) && ((val & (val-1)) == 0))
00172
00173 static BOOL Is_Power_Of_2(INT64 val, TYPE_ID mtype)
00174 {
00175 if (MTYPE_is_signed(mtype) && val < 0)
00176 val= -val;
00177
00178 if (mtype == MTYPE_U4)
00179 val &= 0xffffffffull;
00180
00181 return IS_POWER_OF_2(val);
00182 }
00183
00184
00185 extern BOOL
00186 Can_Do_Fast_Divide (TYPE_ID mtype, INT64 dividend)
00187 {
00188 if (Is_Power_Of_2(dividend, mtype)) {
00189 return TRUE;
00190 }
00191 return FALSE;
00192 }
00193
00194
00195 extern BOOL
00196 Can_Do_Fast_Remainder (TYPE_ID mtype, INT64 dividend)
00197 {
00198 if (Is_Power_Of_2(dividend, mtype)) {
00199 return TRUE;
00200 }
00201 return FALSE;
00202 }
00203
00204
00205
00206
00207
00208
00209
00210
00211
00212
00213
00214
00215
00216
00217
00218 extern INT
00219 Multiply_Limit( BOOL is_64bit, INT64 val)
00220 {
00221 INT limit = 0;
00222
00223 if (is_64bit) {
00224 switch( Target ) {
00225 case TARGET_opteron: limit = 14; break;
00226 default: limit = 14; break;
00227 }
00228 } else {
00229 switch( Target ) {
00230 case TARGET_opteron: limit = 14; break;
00231 default: limit = 14; break;
00232 }
00233 }
00234 return limit;
00235 }
00236
00237 extern INT
00238 Divide_Limit ( BOOL is_64bit)
00239 {
00240 INT limit = 0;
00241 if (is_64bit) {
00242 switch( Target ) {
00243 case TARGET_opteron: limit = 50; break;
00244 default: limit = 50; break;
00245 }
00246 } else {
00247 switch( Target ) {
00248 case TARGET_opteron: limit = 50; break;
00249 default: limit = 50; break;
00250 }
00251 }
00252 return ( limit );
00253 }
00254
00255
00256
00257
00258 static INT
00259 Count_Multiply_Shifts (TARG_UINT constant)
00260 {
00261 switch (constant) {
00262 case 0:
00263 case 1:
00264 case 2:
00265 return 1;
00266 default:
00267 if ((constant % 2) == 1) {
00268 if ((constant & 2) != 0)
00269 return 1 + Count_Multiply_Shifts (constant+1);
00270 else
00271 return 1 + Count_Multiply_Shifts (constant-1);
00272 }
00273 else {
00274 while ((constant % 2) == 0) {
00275 constant = (TARG_UINT)constant >> 1;
00276 }
00277 if (constant == 1)
00278 return 1;
00279 else
00280 return 1 + Count_Multiply_Shifts (constant);
00281 }
00282 }
00283 }
00284
00285
00286
00287 extern BOOL
00288 Can_Do_Fast_Multiply (TYPE_ID mtype, INT64 val)
00289 {
00290 #define MULTIPLICATION_LATENCY_32_BIT 2
00291 #define MULTIPLICATION_LATENCY_64_BIT 3
00292
00293 INT num_ops = 4;
00294 BOOL neg = FALSE;
00295
00296 if (OPT_Space) return FALSE;
00297
00298
00299
00300 if (val == 0 || val == 1 || val == -1)
00301 return TRUE;
00302 else if (val < 0) {
00303 val = -val;
00304 neg = TRUE;
00305 }
00306 switch (val) {
00307 case 3: num_ops = 2; break;
00308 case 5: num_ops = 2; break;
00309 case 6: num_ops = 3; break;
00310 case 7: num_ops = 2; break;
00311 case 9: num_ops = 2; break;
00312 case 10: num_ops = 3; break;
00313 case 11: num_ops = 3; break;
00314 case 12: num_ops = 3; break;
00315 case 13: num_ops = 3; break;
00316 case 14: num_ops = 3; break;
00317 case 15: num_ops = 2; break;
00318 case 17: num_ops = 2; break;
00319 case 18: num_ops = 3; break;
00320 case 19: num_ops = 3; break;
00321 case 20: num_ops = 3; break;
00322 case 21: num_ops = 3; break;
00323 case 23: num_ops = 3; break;
00324 case 24: num_ops = 3; break;
00325 case 25: num_ops = 3; break;
00326 case 27: num_ops = 3; break;
00327 case 28: num_ops = 3; break;
00328 case 29: num_ops = 3; break;
00329 case 30: num_ops = 3; break;
00330 case 31: num_ops = 2; break;
00331 }
00332 if (neg)
00333 num_ops ++;
00334 if ((mtype == MTYPE_I4 || mtype == MTYPE_U4) &&
00335 num_ops <= MULTIPLICATION_LATENCY_32_BIT)
00336 return TRUE;
00337 else if ((mtype == MTYPE_I8 || mtype == MTYPE_U8) &&
00338 num_ops <= MULTIPLICATION_LATENCY_64_BIT)
00339 return TRUE;
00340 else
00341 return FALSE;
00342 }
00343
00344
00345
00346
00347 INT Copy_Quantum_Ratio(void)
00348 {
00349 INT32 ratio;
00350
00351
00352
00353 switch(Target) {
00354 case TARGET_opteron: ratio= 4; break;
00355 default: ratio= 4; break;
00356 }
00357
00358 return ratio;
00359 }
00360
00361
00362
00363 inline BOOL Is_Signed_Bits(INT64 val, INT bits)
00364 {
00365 INT64 hibit = 1LL << (bits - 1);
00366 return val >= -hibit && val <= (hibit - 1);
00367 }
00368
00369
00370
00371
00372 inline BOOL Is_Unsigned_Bits(UINT64 val, INT bits)
00373 {
00374 return val < (1ULL << bits);
00375 }
00376
00377
00378
00379
00380 BOOL Can_Be_Immediate(OPERATOR opr,
00381 INT64 val,
00382 TYPE_ID dtype,
00383 INT whichkid,
00384 ST *stid_st)
00385 {
00386 return ISA_LC_Value_In_Class( val, LC_simm32 );
00387 }