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
00058
00059
00060
00061
00062
00063
00064
00065
00066 #include "defs.h"
00067 #include "config.h"
00068 #include "erglob.h"
00069 #include "ercg.h"
00070 #include "glob.h"
00071 #include "tracing.h"
00072 #include "util.h"
00073
00074 #include "topcode.h"
00075 #include "tn.h"
00076 #include "cg_flags.h"
00077 #include "symtab.h"
00078 #include "opcode.h"
00079 #include "op.h"
00080 #include "cgexp.h"
00081 #include "cgexp_internals.h"
00082 #include "w2op.h"
00083
00084 BOOL Trace_Exp = FALSE;
00085
00086 #ifdef TARG_NVISA
00087
00088 static BOOL Separate_FP_Expansion = FALSE;
00089 #else
00090
00091 static BOOL Separate_FP_Expansion = TRUE;
00092 #endif
00093
00094
00095
00096
00097
00098
00099
00100
00101
00102
00103
00104
00105
00106
00107 static void
00108 Expand_OP (OPCODE opcode, TN *result, TN *op1, TN *op2, TN *op3, VARIANT variant, OPS *ops)
00109 {
00110 TYPE_ID desc = OPCODE_desc(opcode);
00111 TYPE_ID rtype = OPCODE_rtype(opcode);
00112
00113 switch (OPCODE_operator(opcode)) {
00114 case OPR_TRUEBR:
00115 case OPR_FALSEBR:
00116 Expand_Branch (op1, op2, op3, variant, ops);
00117 break;
00118 case OPR_GOTO:
00119 case OPR_GOTO_OUTER_BLOCK:
00120 Expand_Branch (op1, op2, op3, V_BR_ALWAYS, ops);
00121 break;
00122 case OPR_LDA:
00123 Expand_Lda (result, op1, ops);
00124 break;
00125 case OPR_LDA_LABEL:
00126 Expand_Lda_Label (result, op1, ops);
00127 break;
00128 case OPR_INTCONST:
00129 #if defined(TARG_NVISA)
00130 Expand_Mtype_Immediate (result, op1, rtype, ops);
00131 #elif defined(TARG_SL)
00132 Expand_Immediate (result, op1, rtype, ops);
00133 #else
00134 Expand_Immediate (result, op1, TRUE , ops);
00135 #endif
00136 break;
00137 case OPR_CONST:
00138 Expand_Const (result, op1, rtype, ops);
00139 break;
00140 case OPR_ADD:
00141 if (MTYPE_is_float(rtype) && Separate_FP_Expansion)
00142 Expand_Flop (opcode, result, op1, op2, op3, ops);
00143 else
00144 Expand_Add (result, op1, op2, rtype, ops);
00145 break;
00146 case OPR_SUB:
00147 if (MTYPE_is_float(rtype) && Separate_FP_Expansion)
00148 Expand_Flop (opcode, result, op1, op2, op3, ops);
00149 else
00150 Expand_Sub (result, op1, op2, rtype, ops);
00151 break;
00152 case OPR_NEG:
00153 Expand_Neg (result, op1, rtype, ops);
00154 break;
00155 case OPR_SHL:
00156 Expand_Shift (result, op1, op2, rtype, shift_left, ops);
00157 break;
00158 case OPR_ASHR:
00159 Expand_Shift (result, op1, op2, rtype, shift_aright, ops);
00160 break;
00161 case OPR_LSHR:
00162 Expand_Shift (result, op1, op2, rtype, shift_lright, ops);
00163 break;
00164 #ifdef TARG_X8664
00165 case OPR_RROTATE:
00166 Expand_Rrotate (result, op1, op2, rtype, desc, ops);
00167 break;
00168 #endif
00169 case OPR_ILOADX:
00170 case OPR_ILOAD:
00171 case OPR_LDID:
00172 if ( V_align_all(variant) != 0 ) {
00173 Expand_Misaligned_Load ( opcode, result, op1, op2, variant, ops);
00174 }
00175 else {
00176 #if defined(TARG_MIPS) || defined(TARG_X8664)
00177 Expand_Load (opcode, result, op1, op2, ops);
00178 #else
00179 Expand_Load (opcode, result, op1, op2, variant, ops);
00180 #endif
00181 }
00182 break;
00183 case OPR_ISTOREX:
00184 case OPR_ISTORE:
00185 case OPR_STID:
00186 if ( V_align_all(variant) != 0 ) {
00187 #if defined(TARG_SL)
00188 if (CG_check_packed)
00189 Is_True(0, ("SL does not handle unaligned store"));
00190 #endif
00191 Expand_Misaligned_Store (desc, op1, op2, op3, variant, ops);
00192 }
00193 else {
00194 #if defined(TARG_MIPS) || defined(TARG_X8664)
00195 Expand_Store (desc, op1, op2, op3, ops);
00196 #else
00197 Expand_Store (desc, op1, op2, op3, variant, ops);
00198 #endif
00199 }
00200 break;
00201 case OPR_ABS:
00202 Expand_Abs (result, op1, rtype, ops);
00203 break;
00204 case OPR_MPY:
00205 #ifdef TARG_X8664
00206 if (MTYPE_is_float(rtype) || MTYPE_is_mmx_vector(rtype))
00207 #else
00208 if (MTYPE_is_float(rtype) && Separate_FP_Expansion)
00209 #endif
00210 Expand_Flop (opcode, result, op1, op2, op3, ops);
00211 else
00212 #ifdef TARG_IA64
00213 Expand_Multiply (result, op1, op2, rtype, ops, opcode);
00214 #else
00215 Expand_Multiply (result, op1, op2, rtype, ops);
00216 #endif
00217 break;
00218 case OPR_HIGHMPY:
00219 Expand_High_Multiply (result, op1, op2, rtype, ops);
00220 break;
00221 case OPR_REM:
00222 #ifdef TARG_IA64
00223 Expand_Rem (result, op1, op2, rtype, ops, opcode);
00224 #else
00225 Expand_Rem (result, op1, op2, rtype, ops);
00226 #endif
00227 break;
00228 case OPR_MOD:
00229 if (MTYPE_is_signed(rtype))
00230 #ifdef TARG_IA64
00231 Expand_Mod (result, op1, op2, rtype, ops, opcode);
00232 #else
00233 Expand_Mod (result, op1, op2, rtype, ops );
00234 #endif
00235 else
00236
00237 #ifdef TARG_IA64
00238 Expand_Rem (result, op1, op2, rtype, ops, opcode);
00239 #else
00240 Expand_Rem (result, op1, op2, rtype, ops);
00241 #endif
00242 break;
00243 case OPR_DIV:
00244 if (MTYPE_is_float(rtype))
00245 Expand_Flop (opcode, result, op1, op2, op3, ops);
00246 else
00247 Expand_Divide (result, op1, op2, rtype, ops);
00248 break;
00249 case OPR_DIVREM:
00250 #ifdef TARG_IA64
00251 Expand_DivRem(result, op1, op2, op3, rtype, ops, opcode);
00252 #else
00253 Expand_DivRem(result, op1, op2, op3, rtype, ops);
00254 #endif
00255 break;
00256 case OPR_SQRT:
00257 Expand_Sqrt (result, op1, rtype, ops);
00258 break;
00259 case OPR_LNOT:
00260 Expand_Logical_Not (result, op1, variant, ops);
00261 break;
00262 case OPR_LAND:
00263 Expand_Logical_And (result, op1, op2, variant, ops);
00264 break;
00265 case OPR_LIOR:
00266 Expand_Logical_Or (result, op1, op2, variant, ops);
00267 break;
00268 case OPR_BNOT:
00269 Expand_Binary_Complement (result, op1, rtype, ops);
00270 break;
00271 case OPR_BAND:
00272 Expand_Binary_And (result, op1, op2, rtype, ops);
00273 break;
00274 case OPR_BIOR:
00275 Expand_Binary_Or (result, op1, op2, rtype, ops);
00276 break;
00277 case OPR_BXOR:
00278 Expand_Binary_Xor (result, op1, op2, rtype, ops);
00279 break;
00280 case OPR_BNOR:
00281 Expand_Binary_Nor (result, op1, op2, rtype, ops);
00282 break;
00283 case OPR_LT:
00284 if (MTYPE_is_float(desc))
00285 Expand_Float_Less (result, op1, op2, variant, desc, ops);
00286 else
00287 Expand_Int_Less (result, op1, op2, desc, ops);
00288 break;
00289 case OPR_LE:
00290 if (MTYPE_is_float(desc))
00291 Expand_Float_Less_Equal (result, op1, op2, variant, desc, ops);
00292 else
00293 Expand_Int_Less_Equal (result, op1, op2, desc, ops);
00294 break;
00295 case OPR_EQ:
00296 if (MTYPE_is_float(desc))
00297 Expand_Float_Equal (result, op1, op2, variant, desc, ops);
00298 else if (desc == MTYPE_B)
00299 Expand_Bool_Equal (result, op1, op2, ops);
00300 else
00301 Expand_Int_Equal (result, op1, op2, desc, ops);
00302 break;
00303 case OPR_NE:
00304 if (MTYPE_is_float(desc))
00305 Expand_Float_Not_Equal (result, op1, op2, variant, desc, ops);
00306 else if (desc == MTYPE_B)
00307 Expand_Bool_Not_Equal (result, op1, op2, ops);
00308 else
00309 Expand_Int_Not_Equal (result, op1, op2, desc, ops);
00310 break;
00311 case OPR_GE:
00312 if (MTYPE_is_float(desc))
00313 Expand_Float_Greater_Equal (result, op1, op2, variant, desc, ops);
00314 else
00315 Expand_Int_Greater_Equal (result, op1, op2, desc, ops);
00316 break;
00317 case OPR_GT:
00318 if (MTYPE_is_float(desc))
00319 Expand_Float_Greater (result, op1, op2, variant, desc, ops);
00320 else
00321 Expand_Int_Greater (result, op1, op2, desc, ops);
00322 break;
00323
00324 case OPR_CVTL:
00325 Expand_Convert_Length ( result, op1, op2, rtype, MTYPE_is_signed(rtype), ops);
00326 break;
00327 case OPR_CVT:
00328 Is_True(rtype != MTYPE_B, ("conversion to bool unsupported"));
00329 if (MTYPE_is_float(rtype) && MTYPE_is_float(desc)) {
00330 #if defined(TARG_X8664) || defined(TARG_SL) || defined(TARG_MIPS)
00331 Expand_Float_To_Float (result, op1, rtype, desc, ops);
00332 #else
00333 Expand_Float_To_Float (result, op1, rtype, ops);
00334 #endif
00335 }
00336 else if (MTYPE_is_float(rtype)) {
00337
00338 Expand_Int_To_Float (result, op1, desc, rtype, ops);
00339 }
00340 else if (MTYPE_is_float(desc)) {
00341
00342 Expand_Float_To_Int_Cvt (result, op1, rtype, desc, ops);
00343 }
00344 else if (desc == MTYPE_B) {
00345
00346 Expand_Bool_To_Int (result, op1, rtype, ops);
00347 }
00348 #ifdef TARG_X8664
00349 else if (MTYPE_is_vector (rtype)) {
00350
00351 Expand_Conv_To_Vector (result, op1, desc, rtype, ops);
00352 }
00353 else if (MTYPE_is_vector (desc)) {
00354 Expand_Conv_From_Vector (result, op1, desc, rtype, ops);
00355 }
00356 #endif
00357 else {
00358
00359
00360
00361
00362 #ifdef TARG_NVISA
00363
00364 Expand_Convert (result, rtype, op1, desc, ops);
00365 #else
00366 Expand_Convert_Length ( result, op1, op2,
00367 rtype,
00368 (MTYPE_is_signed(desc)
00369 #ifdef TARG_IA64
00370 && (MTYPE_bit_size(desc) < MTYPE_bit_size(rtype) ) ),
00371 ops);
00372 #else
00373 || (MTYPE_bit_size(desc) > MTYPE_bit_size(rtype) ) ),
00374 ops);
00375 #endif
00376 #endif // TARG_NVISA
00377 }
00378 break;
00379 #ifdef TARG_X8664
00380 case OPR_TAS:
00381 if (MTYPE_is_vector(rtype))
00382 Expand_Int_To_Vect_Tas(result, op1, rtype, ops);
00383 else if (MTYPE_is_integral(rtype))
00384 Expand_Float_To_Int_Tas(result, op1, rtype, ops);
00385 else Expand_Int_To_Float_Tas(result, op1, rtype, ops);
00386 break;
00387 #endif
00388 case OPR_RND:
00389 Expand_Float_To_Int_Round (result, op1, rtype, desc, ops);
00390 break;
00391 case OPR_TRUNC:
00392 Expand_Float_To_Int_Trunc (result, op1, rtype, desc, ops);
00393 break;
00394 case OPR_CEIL:
00395 Expand_Float_To_Int_Ceil (result, op1, rtype, desc, ops);
00396 break;
00397 case OPR_FLOOR:
00398 #ifdef TARG_X8664
00399 if( MTYPE_is_float( rtype ) ){
00400 if( MTYPE_is_quad( rtype ) )
00401 Expand_Float_To_Float_Floorl( result, op1, rtype, desc, ops );
00402 else if( rtype == MTYPE_F8 )
00403 Expand_Float_To_Float_Floor( result, op1, rtype, desc, ops );
00404 else
00405 Expand_Float_To_Float_Floorf( result, op1, rtype, desc, ops );
00406 break;
00407 }
00408 #elif defined (TARG_MIPS) && !defined(TARG_SL)
00409 if (MTYPE_is_float (rtype)) {
00410 Expand_Float_To_Float_Floor (result, op1, rtype, desc, ops);
00411 break;
00412 }
00413 #endif
00414 Expand_Float_To_Int_Floor (result, op1, rtype, desc, ops);
00415 break;
00416 case OPR_MIN:
00417 Expand_Min (result, op1, op2, rtype, ops);
00418 break;
00419 case OPR_MAX:
00420 Expand_Max (result, op1, op2, rtype, ops);
00421 break;
00422
00423 case OPR_MINMAX:
00424 Expand_MinMax (result, op1, op2, op3, rtype, ops);
00425 break;
00426
00427 case OPR_SELECT:
00428 Expand_Select (result, op1, op2, op3, rtype, V_select_uses_fcc(variant), ops);
00429 break;
00430
00431 case OPR_MADD:
00432 case OPR_NMADD:
00433 case OPR_MSUB:
00434 case OPR_NMSUB:
00435 case OPR_RECIP:
00436 case OPR_RSQRT:
00437 #ifdef TARG_X8664
00438 case OPR_ATOMIC_RSQRT:
00439 #endif
00440 Expand_Flop (opcode, result, op1, op2, op3, ops);
00441 break;
00442
00443 #ifdef TARG_X8664
00444 case OPR_REPLICATE:
00445 Expand_Replicate (opcode, result, op1, ops);
00446 break;
00447
00448 case OPR_REDUCE_ADD:
00449 Expand_Reduce_Add (opcode, result, op1, ops);
00450 break;
00451
00452 case OPR_REDUCE_MPY:
00453 Expand_Reduce_Mpy (opcode, result, op1, ops);
00454 break;
00455
00456 case OPR_REDUCE_MAX:
00457 Expand_Reduce_Max (opcode, result, op1, ops);
00458 break;
00459
00460 case OPR_REDUCE_MIN:
00461 Expand_Reduce_Min (opcode, result, op1, ops);
00462 break;
00463
00464 #endif
00465 default:
00466 FmtAssert(FALSE,
00467 ("Expand_OP: unexpected opcode %s", OPCODE_name(opcode)));
00468 break;
00469 }
00470
00471 #ifdef TARG_X8664
00472
00473
00474
00475
00476 if( OPCODE_is_compare( opcode ) &&
00477 OP_NEED_PAIR( rtype ) ){
00478 TN* result_hi = Create_TN_Pair( result, rtype );
00479 Exp_Immediate( result_hi, Gen_Literal_TN(0,4), FALSE, ops );
00480 }
00481 #endif // TARG_X8664
00482 }
00483
00484
00485 extern void
00486 Exp_OP (OPCODE opcode, TN *result, TN *op1, TN *op2, TN *op3, VARIANT variant, OPS *ops)
00487 {
00488 TOP top = OPCODE_To_TOP (opcode);
00489
00490 if (Trace_Exp) {
00491 #pragma mips_frequency_hint NEVER
00492 fprintf(TFile, "expand %s: ", OPCODE_name(opcode));
00493 if (result) Print_TN(result,FALSE);
00494 fprintf(TFile, " :- ");
00495 if (op1) Print_TN(op1,FALSE);
00496 fprintf(TFile, " ");
00497 if (op2) Print_TN(op2,FALSE);
00498 fprintf(TFile, " ");
00499 if (op3) Print_TN(op3,FALSE);
00500 fprintf(TFile, " ");
00501 if (variant) fprintf(TFile, "(0x%llx)", (INT64)variant);
00502 fprintf(TFile, "\n");
00503 }
00504
00505 if (top != TOP_UNDEFINED) {
00506 TN *args[5];
00507 OP *op;
00508 INT i = 0;
00509
00510
00511
00512
00513 if (result) args[i++] = result;
00514 if (TOP_is_predicated(top)) {
00515 Is_True(OP_PREDICATE_OPND == 0, ("predicate operand is not 0"));
00516 args[i++] = True_TN;
00517 }
00518 args[i++] = op1;
00519 args[i++] = op2;
00520 args[i] = op3;
00521 op = Mk_OP(top, args[0], args[1], args[2], args[3], args[4]);
00522 if (OP_defs_fpu_int(op)) Set_TN_is_fpu_int(result);
00523
00524 OPS_Append_Op(ops, op);
00525 if (Trace_Exp) {
00526 #pragma mips_frequency_hint NEVER
00527 fprintf(TFile, " into "); Print_OP (op);
00528 }
00529 }
00530 else {
00531
00532
00533
00534 if (OPS_length(ops)==0) {
00535 OPS new_ops;
00536 OPS_Init(&new_ops);
00537 Expand_OP (opcode, result, op1, op2, op3, variant, &new_ops);
00538 if (Trace_Exp) {
00539 #pragma mips_frequency_hint NEVER
00540 OP *op;
00541 FOR_ALL_OPS_OPs (&new_ops, op) {
00542 fprintf(TFile, " into "); Print_OP (op);
00543 }
00544 }
00545
00546 if (OPS_first(&new_ops) != NULL) {
00547
00548 OPS_Append_Ops(ops, &new_ops);
00549 }
00550 }
00551 else {
00552 OP *last_OP = OPS_last(ops);
00553 Expand_OP (opcode, result, op1, op2, op3, variant, ops);
00554 if (Trace_Exp) {
00555 if (OP_next(last_OP)!=NULL) {
00556 #pragma mips_frequency_hint NEVER
00557 OP *op;
00558 for (op = OP_next(last_OP); op && op != OP_next(OPS_last(ops)); op = OP_next(op)){
00559 fprintf(TFile, " into "); Print_OP (op);
00560 }
00561 }
00562 }
00563 }
00564 }
00565 }