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 #include "defs.h"
00059 #include "config.h"
00060 #include "erglob.h"
00061 #include "ercg.h"
00062 #include "glob.h"
00063 #include "tracing.h"
00064 #include "util.h"
00065
00066 #include "topcode.h"
00067 #include "tn.h"
00068 #include "cg_flags.h"
00069 #include "targ_isa_lits.h"
00070 #include "bb.h"
00071 #include "symtab.h"
00072 #include "opcode.h"
00073 #include "const.h"
00074 #include "targ_const.h"
00075 #include "op.h"
00076 #include "data_layout.h"
00077 #include "stblock.h"
00078 #include "cgexp.h"
00079 #include "cgexp_internals.h"
00080 #include "w2op.h"
00081 #include "label_util.h"
00082 #include "cgtarget.h"
00083 #include "whirl2ops.h"
00084 #include "cg_spill.h"
00085
00086 BOOL Reuse_Temp_TNs = FALSE;
00087
00088 BOOL Trace_Exp2 = FALSE;
00089
00090
00091 static BOOL Disable_Const_Mult_Opt = FALSE;
00092
00093
00094
00095
00096
00097
00098
00099
00100 #define DUP_TN(tn) Dup_TN_Even_If_Dedicated(tn)
00101
00102 static TOP
00103 Pick_Imm_Form_TOP (TOP regform)
00104 {
00105 switch (regform) {
00106 case TOP_shl: return TOP_shl_i;
00107 case TOP_shr: return TOP_shr_i;
00108 case TOP_shr_u: return TOP_shr_i_u;
00109 case TOP_and: return TOP_and_i;
00110 case TOP_or: return TOP_or_i;
00111 case TOP_xor: return TOP_xor_i;
00112 default: return regform;
00113 }
00114 }
00115
00116
00117
00118
00119 void
00120 Expand_Copy (TN *result, TN *src, TYPE_ID mtype, OPS *ops)
00121 {
00122 TOP mov_opc = MTYPE_is_float(mtype) ? TOP_mov_f : TOP_mov;
00123 Build_OP (mov_opc, result, True_TN, src, ops);
00124 Set_OP_copy (OPS_last(ops));
00125 }
00126
00127
00128
00129
00130 static void
00131 Fixup_32_Bit_Op(TN *result,TN *src, TYPE_ID dest_type, OPS *ops)
00132 {
00133 if (dest_type == MTYPE_I8 || dest_type == MTYPE_U8) {
00134 Expand_Copy(result,src,dest_type,ops);
00135 } else {
00136 Expand_Convert_Length (result, src, Gen_Literal_TN(MTYPE_size_reg(dest_type), 4),
00137 dest_type, MTYPE_is_signed(dest_type),ops);
00138 }
00139 }
00140
00141
00142
00143
00144
00145
00146
00147
00148
00149
00150
00151
00152
00153
00154 void
00155 Expand_Convert_Length ( TN *dest, TN *src, TN *length_tn, TYPE_ID mtype, BOOL signed_extension, OPS *ops)
00156 {
00157 INT16 new_length;
00158 TOP opc = TOP_UNDEFINED;
00159
00160
00161
00162
00163
00164 new_length = TN_value (length_tn);
00165 if (new_length == 8) opc = (signed_extension ? TOP_sxt1 : TOP_zxt1);
00166 else if (new_length == 16) opc = (signed_extension ? TOP_sxt2 : TOP_zxt2);
00167 else if (new_length == 32) opc = (signed_extension ? TOP_sxt4 : TOP_zxt4);
00168 if (opc != TOP_UNDEFINED) {
00169 Build_OP ( opc, dest, True_TN, src, ops);
00170 return;
00171 }
00172
00173 opc = signed_extension ? TOP_extr : TOP_extr_u;
00174 Build_OP ( opc, dest, True_TN, src, Gen_Literal_TN(0, 4),
00175 Gen_Literal_TN(new_length, 4), ops );
00176 }
00177
00178 void
00179 Exp_Immediate (TN *dest, TN *src, BOOL is_signed, OPS *ops)
00180 {
00181 INT64 val;
00182 if ( TN_has_value(src) ) {
00183 val = TN_value(src);
00184 }
00185 else if ( TN_is_symbol(src) ) {
00186 ST *base;
00187 Base_Symbol_And_Offset_For_Addressing (TN_var(src), TN_offset(src), &base, &val);
00188 }
00189 if (ISA_LC_Value_In_Class (val, LC_i22)) {
00190 Build_OP (TOP_mov_i, dest, True_TN, src, ops);
00191 }
00192 else {
00193 Build_OP (TOP_movl, dest, True_TN, src, ops);
00194 }
00195 }
00196
00197
00198
00199
00200 void
00201 Expand_Immediate (TN *dest, TN *src, BOOL is_signed, OPS *ops)
00202 {
00203 FmtAssert((TN_is_constant(src)),
00204 ("unexpected non-constant in Expand_Immediate"));
00205 FmtAssert((TN_has_value(src) || TN_is_symbol(src)),
00206 ("expected value or const in Expand_Immediate"));
00207 Exp_Immediate (dest, src, TRUE, ops);
00208 }
00209
00210 TN*
00211 Expand_Immediate_Into_Register (TN *src, OPS *ops)
00212 {
00213
00214 TN *tmp = Build_TN_Of_Mtype (MTYPE_I8);
00215 Expand_Immediate (tmp, src, TRUE, ops);
00216 return tmp;
00217 }
00218
00219 void
00220 Expand_Add (TN *result, TN *src1, TN *src2, TYPE_ID mtype, OPS *ops)
00221 {
00222 TOP new_opcode;
00223 INT64 val;
00224 if (TN_is_constant(src1)) {
00225 if (TN_has_value(src1)) {
00226 val = TN_value(src1);
00227 if (val == 0) {
00228 Expand_Copy (result, src2, mtype, ops);
00229 return;
00230 }
00231 if (ISA_LC_Value_In_Class ( val, LC_i14)) {
00232 new_opcode = TOP_adds;
00233 } else {
00234 src1 = Expand_Immediate_Into_Register (src1, ops);
00235 new_opcode = TOP_add;
00236 }
00237 } else if ( TN_is_symbol(src1) ) {
00238
00239 if (TN_is_gp_reg(src2))
00240 new_opcode = TOP_addl;
00241 else {
00242 ST *base;
00243 INT64 ofst;
00244 Base_Symbol_And_Offset_For_Addressing (TN_var(src1), TN_offset(src1), &base, &ofst);
00245 if (ISA_LC_Value_In_Class ( ofst, LC_i14)) {
00246 new_opcode = TOP_adds;
00247 } else {
00248 src1 = Expand_Immediate_Into_Register (src1, ops);
00249 new_opcode = TOP_add;
00250 }
00251 }
00252 } else {
00253 FmtAssert(FALSE,("unexpected constant in Expand_Add"));
00254 }
00255 Build_OP (new_opcode, result, True_TN, src1, src2, ops);
00256 }
00257 else if (TN_is_constant(src2)) {
00258
00259 Expand_Add (result, src2, src1, mtype, ops);
00260 }
00261 else {
00262 Build_OP (TOP_add, result, True_TN, src1, src2, ops);
00263 }
00264 }
00265
00266 void
00267 Expand_Sub (TN *result, TN *src1, TN *src2, TYPE_ID mtype, OPS *ops)
00268 {
00269 INT64 val;
00270 TOP new_opcode = TOP_sub;
00271 if (TN_is_constant(src1)) {
00272 if (TN_has_value(src1)) {
00273 val = TN_value(src1);
00274 if (ISA_LC_Value_In_Class ( val, LC_i8)) {
00275 new_opcode = TOP_sub_i;
00276 } else {
00277 src1 = Expand_Immediate_Into_Register (src1, ops);
00278 }
00279 } else if ( TN_is_symbol(src1) ) {
00280 src1 = Expand_Immediate_Into_Register (src1, ops);
00281 } else {
00282 FmtAssert(FALSE,("unexpected constant in Expand_Sub"));
00283 }
00284 }
00285 else if (TN_is_constant(src2)) {
00286 if (TN_has_value(src2)) {
00287 val = TN_value(src2);
00288 if (ISA_LC_Value_In_Class ( val, LC_i14)) {
00289
00290 val = -val;
00291 src2 = Gen_Literal_TN (val, 4);
00292 Expand_Add (result, src1, src2, mtype, ops);
00293 return;
00294 } else {
00295 src2 = Expand_Immediate_Into_Register (src2, ops);
00296 }
00297 } else if ( TN_is_symbol(src2) ) {
00298
00299 src2 = Gen_Symbol_TN ( TN_var(src2), TN_offset(src2),
00300 TN_RELOC_NEG );
00301 Expand_Add (result, src1, src2, mtype, ops);
00302 return;
00303 }
00304 }
00305 Build_OP (new_opcode, result, True_TN, src1, src2, ops);
00306 }
00307
00308
00309 void
00310 Expand_Neg (TN *result, TN *src, TYPE_ID mtype, OPS *ops)
00311 {
00312
00313 Build_OP (TOP_sub, result, True_TN, Zero_TN, src, ops);
00314 }
00315
00316
00317 void
00318 Expand_Abs (TN *dest, TN *src, TYPE_ID mtype, OPS *ops)
00319 {
00320 TN *p1 = Build_RCLASS_TN (ISA_REGISTER_CLASS_predicate);
00321 TN *p2 = Build_RCLASS_TN (ISA_REGISTER_CLASS_predicate);
00322 Expand_Copy (dest, src, mtype, ops);
00323 Build_OP (TOP_cmp_lt, p1, p2, True_TN, src, Zero_TN, ops);
00324 Build_OP (TOP_sub, dest, p1, Zero_TN, src, ops);
00325 }
00326
00327 void
00328 Expand_Shift (TN *result, TN *src1, TN *src2, TYPE_ID mtype, SHIFT_DIRECTION kind, OPS *ops)
00329 {
00330 TOP new_opcode;
00331 UINT wordsize = MTYPE_is_size_double(mtype) ? 64 : 32;
00332
00333 switch (kind) {
00334 case shift_left:
00335 new_opcode = TOP_shl;
00336 break;
00337 case shift_aright:
00338 new_opcode = TOP_shr;
00339 break;
00340 case shift_lright:
00341 new_opcode = TOP_shr_u;
00342 break;
00343 }
00344 if (TN_has_value(src2)) {
00345 UINT64 val = TN_value(src2);
00346
00347
00348
00349
00350
00351
00352
00353
00354 if (val >= wordsize) {
00355 if (kind == shift_aright) {
00356 Build_OP (TOP_extr, result, True_TN, src1,
00357 Gen_Literal_TN (wordsize - 1, 4),
00358 Gen_Literal_TN (1, 4), ops);
00359 } else {
00360 Build_OP (TOP_mov_i, result, True_TN, Gen_Literal_TN (0, 4), ops);
00361 }
00362 return;
00363 }
00364
00365 if (kind == shift_left) {
00366 if (wordsize == 64) {
00367 if (val >= 1 && val <= 4) {
00368 Build_OP (TOP_shladd,result,True_TN,src1,Gen_Literal_TN (val, 4),Zero_TN,ops);
00369 } else if (val > 4 && val <= 8 && !OPT_Space) {
00370 Build_OP(TOP_shl_i,result,True_TN,src1,src2,ops);
00371 } else {
00372
00373 Build_OP (TOP_shl_i, result, True_TN, src1, src2, ops);
00374 }
00375 } else {
00376
00377
00378 if (MTYPE_is_signed(mtype)) {
00379 TN *r1 = DUP_TN(result);
00380 Expand_Shift(r1, src1, src2, MTYPE_I8, kind, ops);
00381 Fixup_32_Bit_Op(result,r1,mtype,ops);
00382 } else {
00383 Build_OP (TOP_dep_z, result, True_TN, src1, src2, Gen_Literal_TN (wordsize-val, 4), ops);
00384 }
00385 }
00386 return;
00387 }
00388
00389
00390
00391
00392
00393 if (wordsize != 64) {
00394 new_opcode = (kind == shift_aright) ? TOP_extr : TOP_extr_u;
00395
00396 Build_OP (new_opcode, result, True_TN, src1, src2,
00397 Gen_Literal_TN (32-val, 4), ops);
00398 } else {
00399 new_opcode = Pick_Imm_Form_TOP (new_opcode);
00400 Build_OP (new_opcode, result, True_TN, src1, src2, ops);
00401 }
00402 return;
00403 }
00404
00405
00406
00407 if (wordsize != 64) {
00408 TN *r1 = DUP_TN(result);
00409 if (kind == shift_left) {
00410 Build_OP (new_opcode, r1, True_TN, src1, src2, ops);
00411 Fixup_32_Bit_Op(result,r1,mtype,ops);
00412 } else {
00413
00414 if (kind == shift_aright) {
00415 Fixup_32_Bit_Op(r1,src1,MTYPE_I4,ops);
00416 } else {
00417 Fixup_32_Bit_Op(r1,src1,MTYPE_U4,ops);
00418 }
00419 Build_OP (new_opcode, result, True_TN, r1, src2, ops);
00420 }
00421 } else {
00422 Build_OP (new_opcode, result, True_TN, src1, src2, ops);
00423 }
00424 }
00425
00426 inline void
00427 Expand_G_To_F (TN *ftn, TN *gtn, OPS *ops)
00428 {
00429 Build_OP (TOP_setf_sig, ftn, True_TN, gtn, ops);
00430 }
00431
00432 inline void
00433 Expand_F_To_G (TN *gtn, TN *ftn, OPS *ops)
00434 {
00435 Build_OP (TOP_getf_sig, gtn, True_TN, ftn, ops);
00436 }
00437
00438
00439
00440
00441
00442
00443
00444
00445 static void shladd(TN *r, TN *x1, INT s, TN *x2, OPS *ops)
00446 {
00447 Build_OP (TOP_shladd,r,True_TN,x1,Gen_Literal_TN (s, 4),x2,ops);
00448 }
00449
00450 static void shl(TN *r, TN *x1, INT s, OPS *ops)
00451 {
00452 Build_OP (TOP_shl_i,r,True_TN,x1,Gen_Literal_TN (s, 4),ops);
00453 }
00454
00455
00456
00457
00458
00459
00460
00461
00462 static void
00463 Expand_Small_Multiply(TN *r,
00464 TN *x,
00465 INT16 val,
00466 OPS * ops)
00467 {
00468 TN *r1;
00469 TN *r2;
00470 TN *Z=Zero_TN;
00471
00472 #define ONE_TEMP r1=Build_TN_Of_Mtype(MTYPE_I8)
00473 #define TWO_TEMPS ONE_TEMP; r2=Build_TN_Of_Mtype(MTYPE_I8)
00474
00475
00476 switch (val) {
00477 case -1:
00478 Expand_Neg(r,x,MTYPE_I8,ops);
00479 break;
00480 case 0:
00481 Expand_Copy (r, Z, MTYPE_I8, ops);
00482 break;
00483 case 1 :
00484 Expand_Copy (r, x, MTYPE_I8, ops);
00485 break;
00486 case 2 :
00487 shladd(r,x,1,Z,ops);
00488 break;
00489 case 3 :
00490 shladd(r,x,1,x,ops);
00491 break;
00492 case 4 :
00493 shladd(r,x,2,Z,ops);
00494 break;
00495 case 5 :
00496 shladd(r,x,2,x,ops);
00497 break;
00498 case 6:
00499 ONE_TEMP;
00500 Expand_Small_Multiply(r1,x,3,ops);
00501 Expand_Small_Multiply(r,r1,2,ops);
00502 break;
00503 case 7 :
00504 ONE_TEMP;
00505 shladd(r1,x,1,x,ops);
00506 shladd(r,r1,1,x,ops);
00507 break;
00508 case 8 :
00509 shladd(r,x,3,Z,ops);
00510 break;
00511 case 9 :
00512 shladd(r,x,3,x,ops);
00513 break;
00514 case 10 :
00515 ONE_TEMP;
00516 Expand_Small_Multiply(r1,x,5,ops);
00517 Expand_Small_Multiply(r,r1,2,ops);
00518 break;
00519 case 11 :
00520 ONE_TEMP;
00521 Expand_Small_Multiply(r1,x,9,ops);
00522 shladd(r,x,1,r1,ops);
00523 break;
00524 case 12 :
00525 ONE_TEMP;
00526 Expand_Small_Multiply(r1,x,3,ops);
00527 Expand_Small_Multiply(r,r1,4,ops);
00528 break;
00529 case 13 :
00530 ONE_TEMP;
00531 Expand_Small_Multiply(r1,x,5,ops);
00532 shladd(r,x,3,r1,ops);
00533 break;
00534 case 14 :
00535 TWO_TEMPS;
00536 Expand_Small_Multiply(r1,x,5,ops);
00537 Expand_Small_Multiply(r2,x,9,ops);
00538 Expand_Add(r,r1,r2,MTYPE_I8,ops);
00539 break;
00540 case 15 :
00541 ONE_TEMP;
00542 Expand_Small_Multiply(r1,x,3,ops);
00543 Expand_Small_Multiply(r,r1,5,ops);
00544 break;
00545 case 16 :
00546 shladd(r,x,4,Z,ops);
00547 break;
00548 case 17 :
00549 shladd(r,x,4,x,ops);
00550 break;
00551 case 18 :
00552 ONE_TEMP;
00553 Expand_Small_Multiply(r1,x,9,ops);
00554 Expand_Small_Multiply(r,r1,2,ops);
00555 break;
00556 case 19 :
00557 ONE_TEMP;
00558 Expand_Small_Multiply(r1,x,9,ops);
00559 shladd(r,r1,1,x,ops);
00560 break;
00561 case 20 :
00562 ONE_TEMP;
00563 Expand_Small_Multiply(r1,x,5,ops);
00564 Expand_Small_Multiply(r,r1,4,ops);
00565 break;
00566 case 21 :
00567 ONE_TEMP;
00568 Expand_Small_Multiply(r1,x,5,ops);
00569 shladd(r,x,4,r1,ops);
00570 break;
00571 case 22 :
00572 TWO_TEMPS;
00573 Expand_Small_Multiply(r1,x,17,ops);
00574 Expand_Small_Multiply(r2,x,5,ops);
00575 Expand_Add(r,r1,r2,MTYPE_I8,ops);
00576 break;
00577 case 23 :
00578 TWO_TEMPS;
00579 Expand_Small_Multiply(r1,x,17,ops);
00580 Expand_Small_Multiply(r2,x,3,ops);
00581 shladd(r,r2,1,r1,ops);
00582 break;
00583 case 24 :
00584 ONE_TEMP;
00585 Expand_Small_Multiply(r1,x,3,ops);
00586 Expand_Small_Multiply(r,r1,8,ops);
00587 break;
00588 case 25 :
00589 ONE_TEMP;
00590 Expand_Small_Multiply(r1,x,5,ops);
00591 Expand_Small_Multiply(r,r1,5,ops);
00592 break;
00593 case 26 :
00594 TWO_TEMPS;
00595 Expand_Small_Multiply(r1,x,17,ops);
00596 Expand_Small_Multiply(r2,x,9,ops);
00597 Expand_Add(r,r1,r2,MTYPE_I8,ops);
00598 break;
00599 case 27 :
00600 ONE_TEMP;
00601 Expand_Small_Multiply(r1,x,9,ops);
00602 Expand_Small_Multiply(r,r1,3,ops);
00603 break;
00604 case 28 :
00605 TWO_TEMPS;
00606 Expand_Small_Multiply(r1,x,3,ops);
00607 Expand_Small_Multiply(r2,x,4,ops);
00608 shladd(r,r1,3,r2,ops);
00609 break;
00610 case 29 :
00611 TWO_TEMPS;
00612 Expand_Small_Multiply(r1,x,3,ops);
00613 Expand_Small_Multiply(r2,x,5,ops);
00614 shladd(r,r1,3,r2,ops);
00615 break;
00616 case 30 :
00617 ONE_TEMP;
00618 Expand_Small_Multiply(r1,x,15,ops);
00619 Expand_Small_Multiply(r,r1,2,ops);
00620 break;
00621 case 31 :
00622 TWO_TEMPS;
00623 Expand_Small_Multiply(r1,x,16,ops);
00624 Expand_Small_Multiply(r2,x,-1,ops);
00625 shladd(r,r1,1,r2,ops);
00626 break;
00627 case 32 :
00628 shl(r,x,5,ops);
00629 break;
00630 case 33 :
00631 ONE_TEMP;
00632 Expand_Small_Multiply(r1,x,16,ops);
00633 shladd(r,r1,1,x,ops);
00634 break;
00635 case 34 :
00636 ONE_TEMP;
00637 Expand_Small_Multiply(r1,x,17,ops);
00638 Expand_Small_Multiply(r,r1,2,ops);
00639 break;
00640 case 35 :
00641 ONE_TEMP;
00642 Expand_Small_Multiply(r1,x,17,ops);
00643 shladd(r,r1,1,x,ops);
00644 break;
00645 case 36 :
00646 ONE_TEMP;
00647 Expand_Small_Multiply(r1,x,9,ops);
00648 Expand_Small_Multiply(r,r1,4,ops);
00649 break;
00650 case 37 :
00651 ONE_TEMP;
00652 Expand_Small_Multiply(r1,x,9,ops);
00653 shladd(r,r1,2,x,ops);
00654 break;
00655 case 38 :
00656 TWO_TEMPS;
00657 Expand_Small_Multiply(r1,x,17,ops);
00658 Expand_Small_Multiply(r2,x,4,ops);
00659 shladd(r,r1,1,r2,ops);
00660 break;
00661 case 39 :
00662 TWO_TEMPS;
00663 Expand_Small_Multiply(r1,x,17,ops);
00664 Expand_Small_Multiply(r2,x,5,ops);
00665 shladd(r,r1,1,r2,ops);
00666 break;
00667 case 40 :
00668 ONE_TEMP;
00669 Expand_Small_Multiply(r1,x,5,ops);
00670 Expand_Small_Multiply(r,r1,8,ops);
00671 break;
00672 case 41 :
00673 ONE_TEMP;
00674 Expand_Small_Multiply(r1,x,5,ops);
00675 shladd(r,r1,3,x,ops);
00676 break;
00677 case 42 :
00678 TWO_TEMPS;
00679 Expand_Small_Multiply(r1,x,5,ops);
00680 Expand_Small_Multiply(r2,x,2,ops);
00681 shladd(r,r1,3,r2,ops);
00682 break;
00683 case 43 :
00684 TWO_TEMPS;
00685 Expand_Small_Multiply(r1,x,5,ops);
00686 Expand_Small_Multiply(r2,x,3,ops);
00687 shladd(r,r1,3,r2,ops);
00688 break;
00689 case 44 :
00690 TWO_TEMPS;
00691 Expand_Small_Multiply(r1,x,5,ops);
00692 Expand_Small_Multiply(r2,x,4,ops);
00693 shladd(r,r1,3,r2,ops);
00694 break;
00695 case 45 :
00696 ONE_TEMP;
00697 Expand_Small_Multiply(r1,x,5,ops);
00698 Expand_Small_Multiply(r,r1,9,ops);
00699 break;
00700 case 46 :
00701 ONE_TEMP;
00702 Expand_Small_Multiply(r1,x,45,ops);
00703 Expand_Add(r,r1,x,MTYPE_I8,ops);
00704 break;
00705 case 47 :
00706 TWO_TEMPS;
00707 Expand_Small_Multiply(r1,x,-1,ops);
00708 Expand_Small_Multiply(r2,x,3,ops);
00709 shladd(r,r2,4,r1,ops);
00710 break;
00711 case 48 :
00712 ONE_TEMP;
00713 Expand_Small_Multiply(r1,x,3,ops);
00714 Expand_Small_Multiply(r,r1,16,ops);
00715 break;
00716 case 49 :
00717 ONE_TEMP;
00718 Expand_Small_Multiply(r1,x,3,ops);
00719 shladd(r,r1,4,x,ops);
00720 break;
00721 case 50 :
00722 TWO_TEMPS;
00723 Expand_Small_Multiply(r1,x,3,ops);
00724 Expand_Small_Multiply(r2,x,2,ops);
00725 shladd(r,r1,4,r2,ops);
00726 break;
00727 case 51 :
00728 ONE_TEMP;
00729 Expand_Small_Multiply(r1,x,3,ops);
00730 Expand_Small_Multiply(r,r1,17,ops);
00731 break;
00732 case 52 :
00733 TWO_TEMPS;
00734 Expand_Small_Multiply(r1,x,3,ops);
00735 Expand_Small_Multiply(r2,x,4,ops);
00736 shladd(r,r1,4,r2,ops);
00737 break;
00738 case 53 :
00739 TWO_TEMPS;
00740 Expand_Small_Multiply(r1,x,3,ops);
00741 Expand_Small_Multiply(r2,x,5,ops);
00742 shladd(r,r1,4,r2,ops);
00743 break;
00744 case 54 :
00745 ONE_TEMP;
00746 Expand_Small_Multiply(r1,x,9,ops);
00747 Expand_Small_Multiply(r,r1,6,ops);
00748 break;
00749 case 55 :
00750 ONE_TEMP;
00751 Expand_Small_Multiply(r1,x,11,ops);
00752 Expand_Small_Multiply(r,r1,5,ops);
00753 break;
00754 case 56 :
00755 TWO_TEMPS;
00756 Expand_Small_Multiply(r1,x,3,ops);
00757 Expand_Small_Multiply(r2,x,8,ops);
00758 shladd(r,r1,4,r2,ops);
00759 break;
00760 case 57 :
00761 TWO_TEMPS;
00762 Expand_Small_Multiply(r1,x,3,ops);
00763 Expand_Small_Multiply(r2,x,9,ops);
00764 shladd(r,r1,4,r2,ops);
00765 break;
00766 case 58 :
00767 ONE_TEMP;
00768 Expand_Small_Multiply(r1,x,29,ops);
00769 Expand_Small_Multiply(r,r1,2,ops);
00770 break;
00771 case 59 :
00772 ONE_TEMP;
00773 Expand_Small_Multiply(r1,x,29,ops);
00774 shladd(r,r1,1,x,ops);
00775 break;
00776 case 60 :
00777 ONE_TEMP;
00778 Expand_Small_Multiply(r1,x,12,ops);
00779 Expand_Small_Multiply(r,r1,5,ops);
00780 break;
00781 case 61 :
00782 ONE_TEMP;
00783 Expand_Small_Multiply(r1,x,45,ops);
00784 shladd(r,x,4,r1,ops);
00785 break;
00786 case 62 :
00787 ONE_TEMP;
00788 Expand_Small_Multiply(r1,x,31,ops);
00789 Expand_Small_Multiply(r,r1,2,ops);
00790 break;
00791 case 63 :
00792 TWO_TEMPS;
00793 Expand_Small_Multiply(r1,x,-1,ops);
00794 Expand_Small_Multiply(r2,x,16,ops);
00795 shladd(r,r2,2,r1,ops);
00796 break;
00797 default:
00798 #pragma mips_frequency_hint NEVER
00799 FmtAssert(0,("Can't small multiply by %d",val));
00800
00801 }
00802 }
00803
00804
00805
00806
00807
00808
00809
00810 static BOOL
00811 Expand_Multiply_Into_Shifts (
00812 TN *result_tn,
00813 TN *var_tn,
00814 TARG_UINT constant,
00815 INT16 limit,
00816 TYPE_ID mtype,
00817 OPS *ops)
00818 {
00819 TN *tmp_tn;
00820 switch (constant) {
00821 case 0:
00822 if ( limit < 1 ) return FALSE;
00823 Expand_Copy (result_tn, Zero_TN, mtype, ops);
00824 return TRUE;
00825 case 1:
00826 if ( limit < 1 ) return FALSE;
00827 Expand_Copy (result_tn, var_tn, mtype, ops);
00828 return TRUE;
00829 case 2:
00830 if ( limit < 1 ) return FALSE;
00831 Expand_Add (result_tn, var_tn, var_tn, mtype, ops);
00832 return TRUE;
00833 default:
00834 if ((constant % 2) == 1) {
00835 tmp_tn = DUP_TN(result_tn);
00836 if ((constant & 2) != 0) {
00837 if ( limit < 2 ) return FALSE;
00838 if (!Expand_Multiply_Into_Shifts (
00839 tmp_tn, var_tn,
00840 constant+1, limit-1,
00841 mtype, ops))
00842 return FALSE;
00843 Expand_Sub (result_tn, tmp_tn, var_tn, mtype, ops);
00844 return TRUE;
00845 }
00846 else {
00847 if ( limit < 2 ) return FALSE;
00848 if (!Expand_Multiply_Into_Shifts (
00849 tmp_tn, var_tn,
00850 constant-1, limit-1,
00851 mtype, ops))
00852 return FALSE;
00853 Expand_Add (result_tn, tmp_tn, var_tn, mtype, ops);
00854 return TRUE;
00855 }
00856 }
00857 else {
00858 INT shift_cnt = 0;
00859 while ((constant % 2) == 0) {
00860 shift_cnt++;
00861 constant = (TARG_UINT)constant >> 1;
00862 }
00863 if (constant == 1) {
00864 if ( limit < 1 ) return FALSE;
00865 Expand_Shift(result_tn, var_tn, Gen_Literal_TN(shift_cnt, 4), mtype, shift_left, ops);
00866 return TRUE;
00867 }
00868 else {
00869 if ( limit < 2 ) return FALSE;
00870 tmp_tn = DUP_TN(result_tn);
00871 if (!Expand_Multiply_Into_Shifts (
00872 tmp_tn, var_tn,
00873 constant, limit-1,
00874 mtype, ops))
00875 return FALSE;
00876 Expand_Shift(result_tn, tmp_tn, Gen_Literal_TN(shift_cnt, 4), mtype, shift_left, ops);
00877 return TRUE;
00878 }
00879 }
00880 }
00881 }
00882
00883
00884
00885
00886 #define NUM_FAST_MPYS 8
00887 static INT fast_mpys[NUM_FAST_MPYS] = {17,16,9,8,5,4,3,2};
00888
00889 static BOOL
00890 Expand_Constant_Multiply (TN *result, TN *var_tn, TARG_INT constant, TYPE_ID mtype, OPS *ops)
00891 {
00892 BOOL did_do_fast;
00893 INT16 limit;
00894 TN *x = var_tn;
00895 INT64 c = constant;
00896 BOOL needs_sign_extension;
00897
00898
00899 if (c == 0) {
00900 Expand_Copy (result, Zero_TN, MTYPE_I8, ops);
00901 return TRUE;
00902 } else if (c == 1) {
00903 Expand_Copy (result, var_tn, MTYPE_I8, ops);
00904 return TRUE;
00905 } else if (c == -1) {
00906 Expand_Neg(result, var_tn, mtype, ops);
00907 return TRUE;
00908 }
00909
00910 needs_sign_extension = MTYPE_size_reg(mtype) != 64;
00911
00912 if (c < 0) {
00913 c = -c;
00914 x = DUP_TN(var_tn);
00915 Expand_Neg(x, var_tn, mtype, ops);
00916 }
00917
00918
00919
00920 INT num_ones=0;
00921 UINT64 uc=c;
00922 while (uc) {num_ones += (uc&1); uc >>= 1;}
00923 uc = c;
00924
00925
00926
00927
00928 if (uc <= 63) {
00929 if (needs_sign_extension) {
00930 Expand_Small_Multiply(result,x,uc,ops);
00931 } else {
00932 TN *r1 = Build_TN_Of_Mtype(MTYPE_I8);
00933 Expand_Small_Multiply(r1,x,uc,ops);
00934 Fixup_32_Bit_Op(result, r1, mtype,ops);
00935 }
00936 return TRUE;
00937 }
00938
00939
00940
00941
00942
00943
00944 INT first_1 = 0;
00945 while ((uc & 1) == 0) {++first_1; uc >>= 1;}
00946 if (first_1 != 0) {
00947 if (num_ones == 1) {
00948
00949 Expand_Shift(result, x, Gen_Literal_TN(first_1, 4), mtype, shift_left, ops);
00950 return TRUE;
00951 } else {
00952 TN *x1 = DUP_TN(x);
00953 Expand_Shift(x1, x, Gen_Literal_TN(first_1, 4), MTYPE_I8, shift_left, ops);
00954 x = x1;
00955 }
00956 }
00957
00958
00959
00960
00961
00962
00963
00964 if (uc == ((1<<num_ones)-1) && uc > 63) {
00965 TN *r1 = DUP_TN(result);
00966 Expand_Shift(r1, x, Gen_Literal_TN(num_ones, 4), MTYPE_I8, shift_left, ops);
00967 if (!needs_sign_extension) {
00968 Expand_Sub(result,r1,x,mtype,ops);
00969 } else {
00970 TN *r2 = DUP_TN(result);
00971 Expand_Sub(r2,r1,x,mtype,ops);
00972 Fixup_32_Bit_Op(result,r2,mtype,ops);
00973 }
00974 return TRUE;
00975 }
00976
00977
00978
00979
00980
00981 INT i;
00982 for (i=0; i < NUM_FAST_MPYS; i++) {
00983 INT mpy=fast_mpys[i];
00984 if (uc%mpy == 0 && uc/mpy <= 63) {
00985 INT64 uc1;
00986 TN *r1 = DUP_TN(result);
00987 Expand_Small_Multiply(r1,x,uc/mpy,ops);
00988 Expand_Constant_Multiply(result,r1,mpy,mtype,ops);
00989 return TRUE;
00990 }
00991 }
00992
00993
00994
00995
00996 TN *r = result;
00997 if (needs_sign_extension) {
00998 r = DUP_TN(result);
00999 }
01000
01001
01002
01003
01004
01005
01006 if (uc <= 63) {
01007 Expand_Small_Multiply(r,x,uc,ops);
01008 } else if (uc <= 1023) {
01009 INT64 uc1,uc2;
01010 TN *r1 = DUP_TN(result);
01011
01012
01013 uc1 = uc & 15;
01014 uc2 = uc >> 4;
01015
01016 Expand_Small_Multiply(r1,x,uc2,ops);
01017 if (uc1 == 0) {
01018 shladd(r,r1,4,Zero_TN,ops);
01019 } else if (uc1 == 1) {
01020 shladd(r,r1,4,x,ops);
01021 } else if (uc1 == uc2) {
01022 shladd(r,r1,4,r1,ops);
01023 } else {
01024 TN *r2 = DUP_TN(result);
01025 Expand_Small_Multiply(r2,x,uc1,ops);
01026 shladd(r,r1,4,r2,ops);
01027 }
01028 } else if (uc <= 65535) {
01029
01030
01031
01032
01033
01034
01035
01036 INT64 uc1,uc2;
01037 TN *r1 = DUP_TN(result);
01038 TN *r2 = DUP_TN(result);
01039 uc1 = uc & 255;
01040 uc2 = uc >> 8;
01041 Expand_Constant_Multiply (r1, x, uc2, MTYPE_I8, ops);
01042 if (uc1 == 0) {
01043 shladd(r2,r1,4,Zero_TN,ops);
01044 shladd(r,r2,4,Zero_TN,ops);
01045 } else if (uc1 == 1) {
01046 shladd(r2,r1,4,Zero_TN,ops);
01047 shladd(r,r2,4,x,ops);
01048
01049 } else if (uc1 == 16) {
01050 shladd(r2,r1,4,x,ops);
01051 shladd(r,r2,4,Zero_TN,ops);
01052
01053 } else if (uc1 == 17) {
01054 shladd(r2,r1,4,x,ops);
01055 shladd(r,r2,4,x,ops);
01056
01057 } else if (uc1 == uc2) {
01058 shladd(r2,r1,4,Zero_TN,ops);
01059 shladd(r,r2,4,r1,ops);
01060
01061 } else if (uc1 == 16*uc2) {
01062 shladd(r2,r1,4,r1,ops);
01063 shladd(r,r2,4,Zero_TN,ops);
01064
01065 } else if (uc1 == 17*uc2) {
01066 shladd(r2,r1,4,r1,ops);
01067 shladd(r,r2,4,r1,ops);
01068
01069 } else if (uc1%16 == 0) {
01070 TN *r3 = DUP_TN(result);
01071 uc1 /= 16;
01072 Expand_Constant_Multiply(r3,x,uc1,MTYPE_I8,ops);
01073 shladd(r2,r1,4,r3,ops);
01074 shladd(r,r2,4,Zero_TN,ops);
01075
01076 } else if (uc1%17 == 0) {
01077 TN *r3 = DUP_TN(result);
01078 uc1 /= 17;
01079 Expand_Constant_Multiply(r3,x,uc1,MTYPE_I8,ops);
01080 shladd(r2,r1,4,r3,ops);
01081 shladd(r,r2,4,r3,ops);
01082
01083 } else {
01084 TN *r3 = DUP_TN(result);
01085 Expand_Constant_Multiply(r3,x,uc1,MTYPE_I8,ops);
01086 shladd(r2,r1,4,Zero_TN,ops);
01087 shladd(r,r2,4,r3,ops);
01088 }
01089 } else if (uc <= ((1LL << 32)-1)) {
01090
01091
01092
01093
01094 INT64 uc1,uc2;
01095 TN *r1 = DUP_TN(result);
01096 TN *r2 = DUP_TN(result);
01097 TN *r3 = DUP_TN(result);
01098 uc1 = uc & 65535;
01099 uc2 = uc >> 16;
01100 Expand_Constant_Multiply(r1,x,uc1,MTYPE_I8,ops);
01101 Expand_Constant_Multiply(r2,x,uc2,MTYPE_I8,ops);
01102 Expand_Shift(r3,r2,Gen_Literal_TN(16, 4),MTYPE_I8,shift_left,ops);
01103 Expand_Add(r,r1,r3,MTYPE_I8,ops);
01104 } else {
01105
01106
01107
01108
01109
01110
01111
01112 INT64 uc1,uc2;
01113 TN *r1 = DUP_TN(result);
01114 TN *r2 = DUP_TN(result);
01115 TN *r3 = DUP_TN(result);
01116 uc1 = uc & 0xffffffff;
01117 uc2 = uc >> 32;
01118 Expand_Constant_Multiply(r1,x,uc1,MTYPE_I8,ops);
01119 Expand_Constant_Multiply(r2,x,uc2,MTYPE_I8,ops);
01120 Expand_Shift(r3,r2,Gen_Literal_TN(32, 4),MTYPE_I8,shift_left,ops);
01121 Expand_Add(r,r1,r3,MTYPE_I8,ops);
01122 }
01123
01124 if (needs_sign_extension) {
01125 Fixup_32_Bit_Op(result,r,mtype,ops);
01126 }
01127
01128 return TRUE;
01129 }
01130
01131 void
01132 Expand_Multiply (TN *result, TN *src1, TN *src2, TYPE_ID mtype, OPS *ops, OPCODE opcode)
01133 {
01134 TOP new_opcode;
01135 INT64 constant;
01136
01137
01138
01139 if ((TN_has_value(src1) || TN_is_rematerializable(src1)) &&
01140 (TN_has_value(src2) || TN_is_rematerializable(src2))) {
01141
01142 TN *val_tn;
01143 constant = TN_has_value(src1) ? TN_value(src1) : WN_const_val(TN_home(src1));
01144 constant *= TN_has_value(src2) ? TN_value(src2) : WN_const_val(TN_home(src2));
01145
01146 constant = Targ_To_Host(Host_To_Targ(mtype,constant));
01147 val_tn = Gen_Literal_TN(constant, 8);
01148 Exp_Immediate(result,val_tn,MTYPE_is_signed(mtype),ops);
01149 return;
01150 }
01151
01152 #ifdef KEY
01153 if (CGEXP_cvrt_int_mult_to_add_shift &&
01154 (TN_has_value(src1) || TN_has_value(src2) ||
01155 TN_is_rematerializable(src1) ||TN_is_rematerializable(src2))) {
01156 #else
01157 if (!Disable_Const_Mult_Opt && (TN_has_value(src1) || TN_has_value(src2) ||
01158 TN_is_rematerializable(src1) ||TN_is_rematerializable(src2))) {
01159 #endif
01160 TN *var_tn;
01161 if ( TN_has_value(src1) || TN_is_rematerializable(src1) ) {
01162 constant = TN_has_value(src1) ? TN_value(src1) : WN_const_val(TN_home(src1));
01163 var_tn = src2;
01164 }
01165 else {
01166 constant = TN_has_value(src2) ? TN_value(src2) : WN_const_val(TN_home(src2));
01167 var_tn = src1;
01168 }
01169
01170 if (Can_Do_Fast_Multiply (mtype, constant)) {
01171 if (Expand_Constant_Multiply (result, var_tn, constant, mtype, ops)) {
01172
01173 return;
01174 }
01175 }
01176 }
01177 if (TN_has_value(src2)) {
01178 src2 = Expand_Immediate_Into_Register (src2, ops);
01179 }
01180
01181
01182
01183 if (CGEXP_fast_imul) {
01184 switch (mtype) {
01185 case MTYPE_I1:
01186 case MTYPE_I2:
01187 case MTYPE_U1:
01188 case MTYPE_U2:
01189 Build_OP(TOP_pmpy2_r, result, True_TN, src1, src2, ops);
01190 return;
01191 case MTYPE_I4:
01192 case MTYPE_U4:
01193 if (!OPT_Space) {
01194 TN *t0 = Build_TN_Of_Mtype(MTYPE_I8);
01195 TN *t1 = Build_TN_Of_Mtype(MTYPE_I8);
01196 TN *t2 = Build_TN_Of_Mtype(MTYPE_I8);
01197 TN *t3 = Build_TN_Of_Mtype(MTYPE_I8);
01198 TN *t4 = Build_TN_Of_Mtype(MTYPE_I8);
01199 TN *t5 = Build_TN_Of_Mtype(MTYPE_I8);
01200 TN *t6 = Build_TN_Of_Mtype(MTYPE_I8);
01201
01202
01203 Build_OP(TOP_mux2, t0, True_TN, src1, Gen_Literal_TN(0x50, 4), ops);
01204 Build_OP(TOP_mux2, t1, True_TN, src2, Gen_Literal_TN(0x44, 4), ops);
01205 Build_OP(TOP_pmpyshr2_u, t2, True_TN, src1, src2, Gen_Literal_TN(16, 4), ops);
01206 Build_OP(TOP_shl_i, t3, True_TN, t2, Gen_Literal_TN(16, 4), ops);
01207 Build_OP(TOP_pmpyshr2_u, t4, True_TN, t0, t1, Gen_Literal_TN(0, 4), ops);
01208 Build_OP(TOP_unpack2_h, t5, True_TN, t4, Zero_TN, ops);
01209 Build_OP(TOP_add, t6, True_TN, t4, t3, ops);
01210 Build_OP(TOP_add, result, True_TN, t5, t6, ops);
01211 return;
01212 }
01213 break;
01214 }
01215 }
01216
01217
01218
01219 TN *fdest, *fsrc1, *fsrc2;
01220 fdest = Build_TN_Of_Mtype (MTYPE_F8);
01221 fsrc1 = Build_TN_Of_Mtype (MTYPE_F8);
01222 fsrc2 = Build_TN_Of_Mtype (MTYPE_F8);
01223 Expand_G_To_F (fsrc1, src1, ops);
01224 Expand_G_To_F (fsrc2, src2, ops);
01225 new_opcode = (MTYPE_is_signed(mtype) ? TOP_xmpy_l : TOP_xmpy_lu);
01226 Build_OP (new_opcode, fdest, True_TN, fsrc1, fsrc2, ops);
01227 Expand_F_To_G (result, fdest, ops);
01228 }
01229
01230
01231 void
01232 Expand_High_Multiply (TN *result, TN *src1, TN *src2, TYPE_ID mtype, OPS *ops)
01233 {
01234 TOP new_opcode;
01235
01236 if (TN_has_value(src2)) {
01237 src2 = Expand_Immediate_Into_Register (src2, ops);
01238 }
01239
01240 TN *fdest, *fsrc1, *fsrc2;
01241 fdest = Build_TN_Of_Mtype (MTYPE_F8);
01242 fsrc1 = Build_TN_Of_Mtype (MTYPE_F8);
01243 fsrc2 = Build_TN_Of_Mtype (MTYPE_F8);
01244 Expand_G_To_F (fsrc1, src1, ops);
01245 Expand_G_To_F (fsrc2, src2, ops);
01246 new_opcode = (MTYPE_is_signed(mtype) ? TOP_xmpy_h : TOP_xmpy_hu);
01247 Build_OP (new_opcode, fdest, True_TN, fsrc1, fsrc2, ops);
01248 Expand_F_To_G (result, fdest, ops);
01249 }
01250
01251
01252 static void
01253 Expand_Normalize_Logical (TN *src, OPS *ops)
01254 {
01255 TN *p1 = Build_RCLASS_TN (ISA_REGISTER_CLASS_predicate);
01256 TN *p2 = Build_RCLASS_TN (ISA_REGISTER_CLASS_predicate);
01257 Build_OP (TOP_cmp_ne, p1, p2, True_TN, src, Zero_TN, ops);
01258 Build_OP (TOP_mov_i, src, p1, Gen_Literal_TN(1, 4), ops);
01259 }
01260
01261 void
01262 Expand_Logical_Not (TN *dest, TN *src, VARIANT variant, OPS *ops)
01263 {
01264
01265 if (TN_register_class(dest) == ISA_REGISTER_CLASS_predicate) {
01266 TN *p1 = dest;
01267 TN *p2 = Get_Complement_TN(dest);
01268 if (TN_register_class(src) == ISA_REGISTER_CLASS_predicate) {
01269 Build_OP (TOP_cmp_eq, p1, p2, True_TN, Zero_TN, Zero_TN, ops);
01270 Build_OP (TOP_cmp_ne, p1, p2, src, Zero_TN, Zero_TN, ops);
01271 } else {
01272 Build_OP (TOP_cmp_eq, p1, p2, True_TN, src, Zero_TN, ops);
01273 }
01274 } else {
01275
01276
01277
01278
01279 if (!V_normalized_op1(variant) && CGEXP_normalize_logical)
01280 {
01281 Expand_Normalize_Logical (src, ops);
01282 }
01283 Build_OP (TOP_xor_i, dest, True_TN, Gen_Literal_TN(1, 4), src, ops);
01284 }
01285 }
01286
01287
01288
01289
01290
01291
01292
01293 static void
01294 Expand_Logical_And_Or (TOP action, TN *dest, TN *src1, TN *src2, VARIANT variant, OPS *ops)
01295 {
01296
01297
01298
01299
01300 if (!V_normalized_op1(variant) && CGEXP_normalize_logical)
01301 {
01302 Expand_Normalize_Logical (src1, ops);
01303 }
01304 if (!V_normalized_op2(variant) && CGEXP_normalize_logical)
01305 {
01306 Expand_Normalize_Logical (src2, ops);
01307 }
01308
01309 Build_OP (action, dest, True_TN, src1, src2, ops);
01310 }
01311
01312 void
01313 Expand_Logical_And (TN *dest, TN *src1, TN *src2, VARIANT variant, OPS *ops)
01314 {
01315 Expand_Logical_And_Or (TOP_and, dest, src1, src2, variant, ops);
01316 }
01317
01318 void
01319 Expand_Logical_Or (TN *dest, TN *src1, TN *src2, VARIANT variant, OPS *ops)
01320 {
01321 Expand_Logical_And_Or (TOP_or, dest, src1, src2, variant, ops);
01322 }
01323
01324
01325 void
01326 Expand_Binary_Complement (TN *dest, TN *src, TYPE_ID , OPS *ops)
01327 {
01328
01329 Build_OP (TOP_xor_i, dest, True_TN, Gen_Literal_TN(-1, 4), src, ops);
01330 }
01331
01332
01333
01334
01335
01336
01337
01338
01339
01340 BOOL Expand_Special_And_Immed(TN *dest, TN *src1, INT64 imm, OPS *ops)
01341 {
01342 UINT len;
01343 UINT start;
01344 UINT64 v;
01345
01346
01347
01348
01349 if (imm == 0 || imm == -1) {
01350 Is_True(FALSE, ("Expand_Special_And_Immed called with imm == %d", imm));
01351 return FALSE;
01352 }
01353
01354
01355
01356
01357
01358 start = 0;
01359 for (v = ~imm; (v & 1) == 0; v >>= 1) ++start;
01360
01361 len = 0;
01362 for (; (v & 1) != 0; v >>= 1) ++len;
01363
01364 if (v != 0) return FALSE;
01365
01366
01367
01368
01369
01370
01371 if (start > 0 && start + len == 64) {
01372 const UINT extr_len = start;
01373 if (extr_len == 8 || extr_len == 16 || extr_len == 32) {
01374 TOP zxt_opc;
01375 switch (extr_len / 8) {
01376 case 1: zxt_opc = TOP_zxt1; break;
01377 case 2: zxt_opc = TOP_zxt2; break;
01378 case 4: zxt_opc = TOP_zxt4; break;
01379 }
01380 Build_OP(zxt_opc, dest, True_TN, src1, ops);
01381 } else {
01382 Build_OP(TOP_extr_u, dest, True_TN, src1,
01383 Gen_Literal_TN(0, 4), Gen_Literal_TN(extr_len, 4), ops);
01384 }
01385 } else {
01386 Build_OP(TOP_dep_i, dest, True_TN, Gen_Literal_TN(0, 4), src1,
01387 Gen_Literal_TN(start, 4), Gen_Literal_TN(len, 4), ops);
01388 }
01389
01390 return TRUE;
01391 }
01392
01393
01394 static void
01395 Expand_Binary_And_Or (TOP action, TN *dest, TN *src1, TN *src2, TYPE_ID mtype, OPS *ops)
01396 {
01397
01398 if (TN_has_value(src2)) {
01399 if (ISA_LC_Value_In_Class(TN_value(src2), LC_i8)) {
01400 action = Pick_Imm_Form_TOP (action);
01401
01402 Build_OP (action, dest, True_TN, src2, src1, ops);
01403 return;
01404 } else if (action == TOP_and &&
01405 Expand_Special_And_Immed(dest, src1, TN_value(src2), ops))
01406 {
01407 return;
01408 } else {
01409 src2 = Expand_Immediate_Into_Register (src2, ops);
01410 }
01411 }
01412 Build_OP (action, dest, True_TN, src1, src2, ops);
01413 }
01414
01415 void
01416 Expand_Binary_And (TN *dest, TN *src1, TN *src2, TYPE_ID mtype, OPS *ops)
01417 {
01418 Expand_Binary_And_Or (TOP_and, dest, src1, src2, mtype, ops);
01419 }
01420
01421 void
01422 Expand_Binary_Or (TN *dest, TN *src1, TN *src2, TYPE_ID mtype, OPS *ops)
01423 {
01424 Expand_Binary_And_Or (TOP_or, dest, src1, src2, mtype, ops);
01425 }
01426
01427 void
01428 Expand_Binary_Xor (TN *dest, TN *src1, TN *src2, TYPE_ID mtype, OPS *ops)
01429 {
01430 Expand_Binary_And_Or (TOP_xor, dest, src1, src2, mtype, ops);
01431 }
01432
01433 void
01434 Expand_Binary_Nor (TN *dest, TN *src1, TN *src2, TYPE_ID mtype, OPS *ops)
01435 {
01436
01437
01438
01439
01440
01441
01442 TN *tmp = Build_TN_Like(dest);
01443 Expand_Binary_And_Or (TOP_or, tmp, src1, src2, mtype, ops);
01444 Expand_Binary_And_Or (TOP_xor, dest, tmp, Gen_Literal_TN(-1, 4), mtype, ops);
01445 }
01446
01447 static void
01448 Expand_Int_Comparison (TOP action, TN *dest, TN *src1, TN *src2, OPS *ops)
01449 {
01450 if (TN_register_class(dest) == ISA_REGISTER_CLASS_predicate) {
01451
01452 TN *p1 = dest;
01453 TN *p2 = Get_Complement_TN(dest);
01454 Build_OP (action, p1, p2, True_TN, src1, src2, ops);
01455 } else {
01456
01457 TN *p1 = Build_RCLASS_TN (ISA_REGISTER_CLASS_predicate);
01458 TN *p2 = Build_RCLASS_TN (ISA_REGISTER_CLASS_predicate);
01459 Build_OP (action, p1, p2, True_TN, src1, src2, ops);
01460
01461
01462
01463 Build_OP (TOP_mov, dest, p2, Zero_TN, ops);
01464 Build_OP (TOP_mov_i, dest, p1, Gen_Literal_TN(1, 4), ops);
01465 }
01466 }
01467
01468 void
01469 Expand_Int_Less (TN *dest, TN *src1, TN *src2, TYPE_ID mtype, OPS *ops)
01470 {
01471 VARIANT variant;
01472 TOP action;
01473 switch (mtype) {
01474 case MTYPE_I8: variant = V_BR_I8LT; break;
01475 case MTYPE_I4: variant = V_BR_I4LT; break;
01476 case MTYPE_U8: variant = V_BR_U8LT; break;
01477 case MTYPE_U4: variant = V_BR_U4LT; break;
01478 default:
01479 #pragma mips_frequency_hint NEVER
01480 Is_True(FALSE, ("Expand_Int_Less: MTYPE_%s is not handled", Mtype_Name(mtype)));
01481 }
01482 action = Pick_Compare_TOP (&variant, &src1, &src2, ops);
01483 Expand_Int_Comparison (action, dest, src1, src2, ops);
01484 }
01485
01486 void
01487 Expand_Int_Less_Equal (TN *dest, TN *src1, TN *src2, TYPE_ID mtype, OPS *ops)
01488 {
01489 VARIANT variant;
01490 TOP action;
01491 switch (mtype) {
01492 case MTYPE_I8: variant = V_BR_I8LE; break;
01493 case MTYPE_I4: variant = V_BR_I4LE; break;
01494 case MTYPE_U8: variant = V_BR_U8LE; break;
01495 case MTYPE_U4: variant = V_BR_U4LE; break;
01496 default:
01497 #pragma mips_frequency_hint NEVER
01498 Is_True(FALSE, ("Expand_Int_Less_Equal: MTYPE_%s is not handled", Mtype_Name(mtype)));
01499 }
01500 action = Pick_Compare_TOP (&variant, &src1, &src2, ops);
01501 Expand_Int_Comparison (action, dest, src1, src2, ops);
01502 }
01503
01504 void
01505 Expand_Int_Equal (TN *dest, TN *src1, TN *src2, TYPE_ID mtype, OPS *ops)
01506 {
01507 VARIANT variant;
01508 TOP action;
01509 switch (mtype) {
01510 case MTYPE_I8: variant = V_BR_I8EQ; break;
01511 case MTYPE_I4: variant = V_BR_I4EQ; break;
01512 case MTYPE_U8: variant = V_BR_U8EQ; break;
01513 case MTYPE_U4: variant = V_BR_U4EQ; break;
01514 default:
01515 #pragma mips_frequency_hint NEVER
01516 Is_True(FALSE, ("Expand_Int_Equal: MTYPE_%s is not handled", Mtype_Name(mtype)));
01517 }
01518 action = Pick_Compare_TOP (&variant, &src1, &src2, ops);
01519 Expand_Int_Comparison (action, dest, src1, src2, ops);
01520 }
01521
01522 void
01523 Expand_Int_Not_Equal (TN *dest, TN *src1, TN *src2, TYPE_ID mtype, OPS *ops)
01524 {
01525 VARIANT variant;
01526 TOP action;
01527 switch (mtype) {
01528 case MTYPE_I8: variant = V_BR_I8NE; break;
01529 case MTYPE_I4: variant = V_BR_I4NE; break;
01530 case MTYPE_U8: variant = V_BR_U8NE; break;
01531 case MTYPE_U4: variant = V_BR_U4NE; break;
01532 default:
01533 #pragma mips_frequency_hint NEVER
01534 Is_True(FALSE, ("Expand_Int_Not_Equal: MTYPE_%s is not handled", Mtype_Name(mtype)));
01535 }
01536 action = Pick_Compare_TOP (&variant, &src1, &src2, ops);
01537 Expand_Int_Comparison (action, dest, src1, src2, ops);
01538 }
01539
01540 void
01541 Expand_Int_Greater_Equal (TN *dest, TN *src1, TN *src2, TYPE_ID mtype, OPS *ops)
01542 {
01543 VARIANT variant;
01544 TOP action;
01545 switch (mtype) {
01546 case MTYPE_I8: variant = V_BR_I8GE; break;
01547 case MTYPE_I4: variant = V_BR_I4GE; break;
01548 case MTYPE_U8: variant = V_BR_U8GE; break;
01549 case MTYPE_U4: variant = V_BR_U4GE; break;
01550 default:
01551 #pragma mips_frequency_hint NEVER
01552 Is_True(FALSE, ("Expand_Int_Greater_Equal: MTYPE_%s is not handled", Mtype_Name(mtype)));
01553 }
01554 action = Pick_Compare_TOP (&variant, &src1, &src2, ops);
01555 Expand_Int_Comparison (action, dest, src1, src2, ops);
01556 }
01557
01558 void
01559 Expand_Int_Greater (TN *dest, TN *src1, TN *src2, TYPE_ID mtype, OPS *ops)
01560 {
01561 VARIANT variant;
01562 TOP action;
01563 switch (mtype) {
01564 case MTYPE_I8: variant = V_BR_I8GT; break;
01565 case MTYPE_I4: variant = V_BR_I4GT; break;
01566 case MTYPE_U8: variant = V_BR_U8GT; break;
01567 case MTYPE_U4: variant = V_BR_U4GT; break;
01568 default:
01569 #pragma mips_frequency_hint NEVER
01570 Is_True(FALSE, ("Expand_Int_Greater: MTYPE_%s is not handled", Mtype_Name(mtype)));
01571 }
01572 action = Pick_Compare_TOP (&variant, &src1, &src2, ops);
01573 Expand_Int_Comparison (action, dest, src1, src2, ops);
01574 }
01575
01576 static void
01577 Expand_Bool_Comparison (BOOL equals, TN *dest, TN *src1, TN *src2, OPS *ops)
01578 {
01579 if (TN_register_class(dest) == ISA_REGISTER_CLASS_predicate) {
01580
01581 TOP action = equals ? TOP_cmp_ne : TOP_cmp_eq;
01582 TN *p1 = dest;
01583 TN *p2 = Get_Complement_TN (dest);
01584 TN *tn = Build_TN_Of_Mtype (MTYPE_I4);
01585
01586
01587 Build_OP (TOP_mov_i, tn, True_TN, Gen_Literal_TN (1, 4), ops);
01588 Build_OP (TOP_xor_i, tn, src1, Gen_Literal_TN (1, 4), tn, ops);
01589 Build_OP (TOP_xor_i, tn, src2, Gen_Literal_TN (1, 4), tn, ops);
01590
01591 Build_OP (action, p1, p2, True_TN, tn, Zero_TN, ops);
01592 }
01593 else if (TN_is_dedicated (dest)) {
01594 TN *tn = Build_TN_Of_Mtype (MTYPE_I4);
01595
01596 Build_OP (TOP_mov_i, tn, True_TN, Gen_Literal_TN (equals, 4), ops);
01597 Build_OP (TOP_xor_i, tn, src1, Gen_Literal_TN (1, 4), tn, ops);
01598 Build_OP (TOP_xor_i, tn, src2, Gen_Literal_TN (1, 4), tn, ops);
01599
01600 Build_OP (TOP_mov, dest, True_TN, tn, ops);
01601 }
01602 else {
01603 Build_OP (TOP_mov_i, dest, True_TN, Gen_Literal_TN (equals, 4), ops);
01604 Build_OP (TOP_xor_i, dest, src1, Gen_Literal_TN (1, 4), dest, ops);
01605 Build_OP (TOP_xor_i, dest, src2, Gen_Literal_TN (1, 4), dest, ops);
01606 }
01607 }
01608
01609 void
01610 Expand_Bool_Equal (TN *dest, TN *src1, TN *src2, OPS *ops)
01611 {
01612 Expand_Bool_Comparison (TRUE, dest, src1, src2, ops);
01613 }
01614
01615 void
01616 Expand_Bool_Not_Equal (TN *dest, TN *src1, TN *src2, OPS *ops)
01617 {
01618 Expand_Bool_Comparison (FALSE, dest, src1, src2, ops);
01619 }
01620
01621 void
01622 Expand_Bool_To_Int (TN *dest, TN *src, TYPE_ID rtype, OPS *ops)
01623 {
01624 Build_OP (TOP_mov, dest, True_TN, Zero_TN, ops);
01625 Build_OP (TOP_mov_i, dest, src, Gen_Literal_TN(1, 4), ops);
01626 }
01627
01628 typedef enum {
01629 ROUND_USER,
01630 ROUND_NEAREST,
01631 ROUND_CHOP,
01632 ROUND_NEG_INF,
01633 ROUND_PLUS_INF
01634 } ROUND_MODE;
01635
01636
01637 static void
01638 Expand_Float_To_Int (ROUND_MODE rm, TN *dest, TN *src, TYPE_ID imtype, TYPE_ID fmtype, OPS *ops)
01639 {
01640
01641 TOP fcvt;
01642 TN *sf;
01643 const BOOL is_signed = MTYPE_is_signed(imtype);
01644 TN *tmp = Build_RCLASS_TN(ISA_REGISTER_CLASS_float);
01645 switch (rm) {
01646 case ROUND_USER:
01647 fcvt = is_signed ? TOP_fcvt_fx : TOP_fcvt_fxu;
01648 sf = Gen_Enum_TN(ECV_sf_s0);
01649 break;
01650 case ROUND_NEAREST:
01651 fcvt = is_signed ? TOP_fcvt_fx : TOP_fcvt_fxu;
01652 sf = Gen_Enum_TN(ECV_sf_s2);
01653 Build_OP(TOP_fsetc,
01654 True_TN, sf, Gen_Literal_TN(0x4f, 4), Gen_Literal_TN(0x00, 4), ops);
01655 break;
01656 case ROUND_CHOP:
01657 fcvt = is_signed ? TOP_fcvt_fx_trunc : TOP_fcvt_fxu_trunc;
01658 sf = Gen_Enum_TN(ECV_sf_s0);
01659 break;
01660 case ROUND_NEG_INF:
01661 fcvt = is_signed ? TOP_fcvt_fx : TOP_fcvt_fxu;
01662 sf = Gen_Enum_TN(ECV_sf_s2);
01663 Build_OP(TOP_fsetc,
01664 True_TN, sf, Gen_Literal_TN(0x4f, 4), Gen_Literal_TN(0x10, 4), ops);
01665 break;
01666 case ROUND_PLUS_INF:
01667 fcvt = is_signed ? TOP_fcvt_fx : TOP_fcvt_fxu;
01668 sf = Gen_Enum_TN(ECV_sf_s2);
01669 Build_OP(TOP_fsetc,
01670 True_TN, sf, Gen_Literal_TN(0x4f, 4), Gen_Literal_TN(0x20, 4), ops);
01671 break;
01672 }
01673 Build_OP(fcvt, tmp, True_TN, sf, src, ops);
01674 Build_OP(TOP_getf_sig, dest, True_TN, tmp, ops);
01675 }
01676
01677 void
01678 Expand_Float_To_Int_Cvt (TN *dest, TN *src, TYPE_ID imtype, TYPE_ID fmtype, OPS *ops)
01679 {
01680 Expand_Float_To_Int (ROUND_USER, dest, src, imtype, fmtype, ops);
01681 }
01682
01683 void
01684 Expand_Float_To_Int_Round (TN *dest, TN *src, TYPE_ID imtype, TYPE_ID fmtype, OPS *ops)
01685 {
01686 Expand_Float_To_Int (ROUND_NEAREST, dest, src, imtype, fmtype, ops);
01687 }
01688
01689 void
01690 Expand_Float_To_Int_Trunc (TN *dest, TN *src, TYPE_ID imtype, TYPE_ID fmtype, OPS *ops)
01691 {
01692 Expand_Float_To_Int (ROUND_CHOP, dest, src, imtype, fmtype, ops);
01693 }
01694
01695 void
01696 Expand_Float_To_Int_Floor (TN *dest, TN *src, TYPE_ID imtype, TYPE_ID fmtype, OPS *ops)
01697 {
01698 Is_True ( MTYPE_is_float(fmtype), ("fmtype is not floating-point"));
01699
01700 if ( MTYPE_is_integral(imtype) ) {
01701 Expand_Float_To_Int (ROUND_NEG_INF, dest, src, imtype, fmtype, ops);
01702 }
01703 else {
01704
01705 TN* expmask = Build_TN_Of_Mtype(MTYPE_I4);
01706 Build_OP(TOP_mov_i, expmask, True_TN, Gen_Literal_TN(0x1FFFF, 4), ops);
01707
01708 TN* sigwidth = Build_TN_Of_Mtype(MTYPE_I4);
01709 switch(fmtype) {
01710 default:
01711 FmtAssert(FALSE, ("Invalid fmtype in ..."));
01712 case MTYPE_F4:
01713
01714 Build_OP(TOP_mov_i, sigwidth, True_TN, Gen_Literal_TN(0x10016, 4), ops);
01715 break;
01716 case MTYPE_F8:
01717
01718 Build_OP(TOP_mov_i, sigwidth, True_TN, Gen_Literal_TN(0x10033, 4), ops);
01719 break;
01720 case MTYPE_F10:
01721
01722 Build_OP(TOP_mov_i, sigwidth, True_TN, Gen_Literal_TN(0x1003E, 4), ops);
01723 break;
01724 }
01725
01726 TN* exp = Build_TN_Of_Mtype(MTYPE_I4);
01727 Build_OP (TOP_getf_exp, exp, True_TN, src, ops);
01728
01729 TN* trunc_val = Build_RCLASS_TN(ISA_REGISTER_CLASS_float);
01730 Build_OP (TOP_fcvt_fx_trunc, trunc_val, True_TN,
01731 Gen_Enum_TN(ECV_sf_s1), src, ops);
01732
01733 Build_OP (TOP_fmerge_s, dest, True_TN,
01734 src, src, ops);
01735
01736 Build_OP (TOP_fcvt_xf, trunc_val, True_TN, trunc_val, ops);
01737 Build_OP (TOP_and, exp, True_TN, expmask, exp, ops);
01738
01739 TN *p1 = Build_RCLASS_TN (ISA_REGISTER_CLASS_predicate);
01740 TN *p2 = Build_RCLASS_TN (ISA_REGISTER_CLASS_predicate);
01741
01742
01743 Build_OP (TOP_cmp_geu_unc, True_TN, p1, True_TN, exp, sigwidth, ops);
01744 Build_OP (TOP_fcmp_nlt_unc, p2, p1, p1,
01745 Gen_Enum_TN(ECV_sf_s1), src, trunc_val, ops);
01746 Build_OP (TOP_fsub_d, dest, p1,
01747 Gen_Enum_TN(ECV_sf_s1), trunc_val, FOne_TN, ops);
01748 Build_OP (TOP_fmerge_s, dest, p2, src, trunc_val, ops);
01749
01750 }
01751 }
01752
01753 void
01754 Expand_Float_To_Int_Ceil (TN *dest, TN *src, TYPE_ID imtype, TYPE_ID fmtype, OPS *ops)
01755 {
01756 Expand_Float_To_Int (ROUND_PLUS_INF, dest, src, imtype, fmtype, ops);
01757 }
01758
01759 void
01760 Expand_Float_To_Float (TN *dest, TN *src, TYPE_ID mtype, OPS *ops)
01761 {
01762 TOP top;
01763 if (mtype == MTYPE_F4)
01764 top = TOP_fnorm_s;
01765 else if (mtype == MTYPE_F8)
01766 top = TOP_fnorm_d;
01767 else if (mtype == MTYPE_F10)
01768 top = TOP_fnorm;
01769 else
01770 FmtAssert(FALSE, ("NYI: Expand_Float_To_Float mtype"));
01771 Build_OP (top, dest, True_TN, Gen_Enum_TN(ECV_sf_s0), src, ops);
01772 }
01773
01774
01775 void
01776 Expand_Int_To_Float (TN *dest, TN *src, TYPE_ID imtype, TYPE_ID fmtype, OPS *ops)
01777 {
01778
01779 TN *tmp = Build_TN_Like(dest);
01780 Build_OP (TOP_setf_sig, tmp, True_TN, src, ops);
01781 if (MTYPE_is_signed(imtype)) {
01782 TN *tmp2 = Build_TN_Like(dest);
01783 Build_OP (TOP_fcvt_xf, tmp2, True_TN, tmp, ops);
01784 tmp = tmp2;
01785 }
01786
01787 Expand_Float_To_Float (dest, tmp, fmtype, ops);
01788 }
01789
01790
01791 static BOOL
01792 Optimize_Select (
01793 TOP cmp,
01794 TN *cond1,
01795 TN *cond2,
01796 TN *dest,
01797 TN *dest2,
01798 TN *src1,
01799 TN *src2,
01800 BOOL is_float,
01801 OPS *ops)
01802 {
01803
01804
01805 BOOL reversed;
01806 if (cond1 == src1 && cond2 == src2) {
01807 reversed = FALSE;
01808 } else if (cond1 == src2 && cond2 == src1) {
01809 reversed = TRUE;
01810 } else {
01811 return FALSE;
01812 }
01813
01814
01815 switch (cmp) {
01816 case TOP_fcmp_gt:
01817 case TOP_fcmp_ge:
01818 reversed = !reversed;
01819
01820 case TOP_fcmp_lt:
01821 case TOP_fcmp_le:
01822 {
01823 TOP opc = reversed ? TOP_fmax : TOP_fmin;
01824 Build_OP(opc, dest, True_TN, Gen_Enum_TN(ECV_sf_s0), src1, src2, ops);
01825 if (dest2) {
01826 opc = reversed ? TOP_fmin : TOP_fmax;
01827 Build_OP(opc, dest2, True_TN, Gen_Enum_TN(ECV_sf_s0), src1, src2, ops);
01828 }
01829 }
01830 return TRUE;
01831 case TOP_cmp_ne:
01832 case TOP_cmp4_ne:
01833 case TOP_cmp_i_ne:
01834 case TOP_cmp4_i_ne:
01835 case TOP_fcmp_neq:
01836 reversed = !reversed;
01837
01838 case TOP_cmp_eq:
01839 case TOP_cmp4_eq:
01840 case TOP_cmp_i_eq:
01841 case TOP_cmp4_i_eq:
01842 case TOP_fcmp_eq:
01843 {
01844 TN *src = reversed ? src1 : src2;
01845 Exp_COPY(dest, src, ops);
01846 if (dest2) {
01847 src = reversed ? src2 : src1;
01848 Exp_COPY(dest2, src, ops);
01849 }
01850 }
01851 return TRUE;
01852 }
01853
01854 return FALSE;
01855 }
01856
01857
01858 static void
01859 Expand_Compare_And_Select (
01860 TOP cmp,
01861 TN *cond1,
01862 TN *cond2,
01863 TN *dest,
01864 TN *opposite_dest,
01865 TN *true_tn,
01866 TN *false_tn,
01867 BOOL is_float,
01868 OPS *ops)
01869 {
01870
01871 if (Optimize_Select(cmp, cond1, cond2, dest, opposite_dest,
01872 true_tn, false_tn, is_float, ops)) return;
01873
01874 TOP tmove;
01875 TOP fmove;
01876 TN *p1 = Build_RCLASS_TN (ISA_REGISTER_CLASS_predicate);
01877 TN *p2 = Build_RCLASS_TN (ISA_REGISTER_CLASS_predicate);
01878 if (TOP_is_flop(cmp)) {
01879 Build_OP (cmp, p1, p2, True_TN, Gen_Enum_TN(ECV_sf_s0),
01880 cond1, cond2, ops);
01881 } else {
01882 Build_OP (cmp, p1, p2, True_TN, cond1, cond2, ops);
01883 }
01884
01885
01886 if (is_float) {
01887 tmove = TOP_mov_f;
01888 fmove = TOP_mov_f;
01889 } else {
01890 tmove = TN_has_value(true_tn) ? TOP_mov_i : TOP_mov;
01891 fmove = TN_has_value(false_tn) ? TOP_mov_i : TOP_mov;
01892 }
01893 Build_OP (tmove, dest, p1, true_tn, ops);
01894 Build_OP (fmove, dest, p2, false_tn, ops);
01895 if (opposite_dest) {
01896 Build_OP (tmove, opposite_dest, p2, true_tn, ops);
01897 Build_OP (fmove, opposite_dest, p1, false_tn, ops);
01898 }
01899 }
01900
01901 void
01902 Expand_Select (
01903 TN *dest_tn,
01904 TN *cond_tn,
01905 TN *true_tn,
01906 TN *false_tn,
01907 TYPE_ID mtype,
01908 BOOL float_cond,
01909 OPS *ops)
01910 {
01911 const BOOL is_float = MTYPE_is_float(mtype);
01912 if (TN_register_class(cond_tn) == ISA_REGISTER_CLASS_predicate) {
01913 TOP tmove, fmove;
01914 TN *p1 = cond_tn;
01915
01916
01917
01918 TN *p2;
01919 if ((ops->length!=0) && (OP_result(OPS_last(ops), 0)==p1)) {
01920 p2 = OP_result(OPS_last(ops), 1);
01921 }
01922 else
01923 {
01924 p2 = Get_Complement_TN(cond_tn);
01925 }
01926
01927 if (is_float) {
01928 tmove = TOP_mov_f;
01929 fmove = TOP_mov_f;
01930 } else {
01931 tmove = TN_has_value(true_tn) ? TOP_mov_i : TOP_mov;
01932 fmove = TN_has_value(false_tn) ? TOP_mov_i : TOP_mov;
01933 }
01934 Build_OP (tmove, dest_tn, p1, true_tn, ops);
01935 Build_OP (fmove, dest_tn, p2, false_tn, ops);
01936 } else {
01937
01938 TOP cmp;
01939 if (float_cond)
01940 cmp = TOP_fcmp_neq;
01941 else if (MTYPE_is_size_double(mtype))
01942 cmp = TOP_cmp_ne;
01943 else
01944 cmp = TOP_cmp4_ne;
01945 Expand_Compare_And_Select (cmp, cond_tn,
01946 (float_cond ? FZero_TN : Zero_TN),
01947 dest_tn, NULL,
01948 true_tn, false_tn,
01949 is_float, ops);
01950 }
01951 }
01952
01953 void
01954 Expand_Min (TN *dest, TN *src1, TN *src2, TYPE_ID mtype, OPS *ops)
01955 {
01956
01957 TOP cmp;
01958 VARIANT variant;
01959 switch (mtype) {
01960 case MTYPE_I8: variant = V_BR_I8LT; break;
01961 case MTYPE_I4: variant = V_BR_I4LT; break;
01962 case MTYPE_U8: variant = V_BR_U8LT; break;
01963 case MTYPE_U4: variant = V_BR_U4LT; break;
01964 case MTYPE_F4:
01965 case MTYPE_F8:
01966 case MTYPE_F10:
01967 Build_OP(TOP_fmin, dest, True_TN, Gen_Enum_TN(ECV_sf_s0), src1, src2, ops);
01968 return;
01969 default:
01970 #pragma mips_frequency_hint NEVER
01971 Is_True(FALSE, ("Expand_Min: unexpected mtype"));
01972 }
01973 cmp = Pick_Compare_TOP (&variant, &src1, &src2, ops);
01974
01975 Is_True(!MTYPE_is_float(mtype), ("Expand_Min: float should have been handled"));
01976 Expand_Compare_And_Select (cmp, src1, src2, dest, NULL, src1, src2, FALSE, ops);
01977 }
01978
01979 void
01980 Expand_Max (TN *dest, TN *src1, TN *src2, TYPE_ID mtype, OPS *ops)
01981 {
01982
01983 TOP cmp;
01984 VARIANT variant;
01985 switch (mtype) {
01986 case MTYPE_I8: variant = V_BR_I8GT; break;
01987 case MTYPE_I4: variant = V_BR_I4GT; break;
01988 case MTYPE_U8: variant = V_BR_U8GT; break;
01989 case MTYPE_U4: variant = V_BR_U4GT; break;
01990 case MTYPE_F4:
01991 case MTYPE_F8:
01992 case MTYPE_F10:
01993 Build_OP(TOP_fmax, dest, True_TN, Gen_Enum_TN(ECV_sf_s0), src1, src2, ops);
01994 return;
01995 default:
01996 #pragma mips_frequency_hint NEVER
01997 Is_True(FALSE, ("Expand_Max: unexpected mtype"));
01998 }
01999 cmp = Pick_Compare_TOP (&variant, &src1, &src2, ops);
02000
02001 Is_True(!MTYPE_is_float(mtype), ("Expand_Max: float should have been handled"));
02002 Expand_Compare_And_Select (cmp, src1, src2, dest, NULL, src1, src2, FALSE, ops);
02003 }
02004
02005 void
02006 Expand_MinMax (TN *dest, TN *dest2, TN *src1, TN *src2, TYPE_ID mtype, OPS *ops)
02007 {
02008
02009 TOP cmp;
02010 VARIANT variant;
02011 switch (mtype) {
02012 case MTYPE_I8: variant = V_BR_I8LT; break;
02013 case MTYPE_I4: variant = V_BR_I4LT; break;
02014 case MTYPE_U8: variant = V_BR_U8LT; break;
02015 case MTYPE_U4: variant = V_BR_U4LT; break;
02016 case MTYPE_F4:
02017 case MTYPE_F8:
02018 case MTYPE_F10:
02019 Build_OP(TOP_fmin, dest, True_TN, Gen_Enum_TN(ECV_sf_s0), src1, src2, ops);
02020 Build_OP(TOP_fmax, dest2, True_TN, Gen_Enum_TN(ECV_sf_s0), src1, src2, ops);
02021 return;
02022 default:
02023 #pragma mips_frequency_hint NEVER
02024 Is_True(FALSE, ("Expand_MinMax: unexpected mtype"));
02025 }
02026 cmp = Pick_Compare_TOP (&variant, &src1, &src2, ops);
02027
02028 Is_True(!MTYPE_is_float(mtype), ("Expand_MinMax: float should have been handled"));
02029 Expand_Compare_And_Select (cmp, src1, src2, dest, dest2, src1, src2, FALSE, ops);
02030 }
02031
02032
02033 extern BOOL
02034 Check_Select_Expansion (OPCODE compare)
02035 {
02036
02037
02038
02039
02040 return FALSE;
02041 }
02042
02043 extern void
02044 Exp_Select_And_Condition (
02045 OPCODE select, TN *result, TN *true_tn, TN *false_tn,
02046 OPCODE compare, TN *cmp_kid1, TN *cmp_kid2, VARIANT variant, OPS *ops)
02047 {
02048 OPS newops = OPS_EMPTY;
02049 TOP cmp = Pick_Compare_TOP (&variant, &cmp_kid1, &cmp_kid2, &newops);
02050
02051 switch (variant) {
02052 case V_BR_PEQ:
02053 case V_BR_PNE:
02054 {
02055 Is_True(cmp == TOP_UNDEFINED,
02056 ("unexpected compare op for V_BR_PEQ/V_BR_PNE"));
02057
02058
02059 TN *tmp = Build_TN_Of_Mtype (MTYPE_I8);
02060 Build_OP (TOP_mov_i, tmp, True_TN, Gen_Literal_TN(1, 8), &newops);
02061 Build_OP (TOP_xor_i, tmp, cmp_kid1, Gen_Literal_TN(1, 8), tmp, &newops);
02062 Build_OP (TOP_xor_i, tmp, cmp_kid2, Gen_Literal_TN(1, 8), tmp, &newops);
02063
02064 cmp = (variant == V_BR_PEQ) ? TOP_cmp_ne : TOP_cmp_eq;
02065 cmp_kid1 = tmp;
02066 cmp_kid2 = Zero_TN;
02067 }
02068 break;
02069 case V_BR_NONE:
02070 #pragma mips_frequency_hint NEVER
02071 FmtAssert(FALSE, ("Exp_Select_And_Condition given br_none variant"));
02072
02073 default:
02074 FmtAssert(cmp != TOP_UNDEFINED, ("Exp_Select_And_Condition: unexpected comparison"));
02075 break;
02076 }
02077
02078 Expand_Compare_And_Select (cmp, cmp_kid1, cmp_kid2,
02079 result, NULL, true_tn, false_tn,
02080 MTYPE_is_float(OPCODE_rtype(select)), &newops);
02081
02082 if (Trace_Exp) {
02083 #pragma mips_frequency_hint NEVER
02084 OP *op;
02085 fprintf(TFile, "Exp_Select_And_Condition:\n");
02086 FOR_ALL_OPS_OPs(&newops, op) {
02087 fprintf(TFile, " into ");
02088 Print_OP (op);
02089 }
02090 }
02091
02092 OPS_Append_Ops(ops, &newops);
02093 }
02094
02095
02096 #define RESET_COND_DEF_LAST(ops) Set_OP_cond_def_kind(OPS_last(ops),OP_ALWAYS_UNC_DEF)
02097
02098 static void
02099 Expand_SGI_Sqrt (TN *result, TN *src, TYPE_ID mtype, OPS *ops)
02100 {
02101
02102
02103
02104
02105
02106
02107
02108
02109
02110
02111
02112
02113
02114
02115
02116
02117
02118
02119
02120
02121
02122
02123
02124
02125
02126
02127
02128
02129
02130
02131
02132
02133
02134
02135 INT i;
02136 TN *tn;
02137 TN *p2;
02138 TN *f2, *f3, *f4, *f5, *f6, *f6a, *f7, *f8;
02139 BOOL is_double = MTYPE_is_size_double(mtype) != 0;
02140
02141
02142
02143
02144
02145
02146
02147
02148
02149
02150 const TOP fnma = TOP_fnma;
02151 const TOP fma = TOP_fma;
02152 const TOP fmpy = TOP_fmpy;
02153 const TOP fadd = TOP_fadd;
02154 const TOP rounded_fma = is_double ? TOP_fma_d : TOP_fma_s;
02155
02156 INT epsilon_pow2 = is_double ? -53 : -24;
02157 const INT exp_bias = 0xffff;
02158 TN * const p0 = True_TN;
02159
02160 p2 = Build_RCLASS_TN (ISA_REGISTER_CLASS_predicate);
02161 f6 = Build_TN_Of_Mtype (mtype);
02162 Build_OP(TOP_frsqrta, f6, p2, p0, Gen_Enum_TN(ECV_sf_s0), src, ops);
02163
02164
02165 tn = Build_TN_Of_Mtype (MTYPE_I8);
02166 Build_OP(TOP_mov_i, tn, p0, Gen_Literal_TN(-1 + exp_bias, 4), ops);
02167 f4 = Build_TN_Of_Mtype (mtype);
02168 Build_OP(TOP_setf_exp, f4, p0, tn, ops);
02169
02170
02171 tn = Build_TN_Of_Mtype (MTYPE_I8);
02172 Build_OP(TOP_mov_i, tn, p0, Gen_Literal_TN(epsilon_pow2 + exp_bias, 4), ops);
02173 f7 = Build_TN_Of_Mtype (mtype);
02174 Build_OP(TOP_setf_exp, f7, p0, tn, ops);
02175 tn = Build_TN_Of_Mtype (mtype);
02176 Build_OP(TOP_fadd, tn, p0, Gen_Enum_TN(ECV_sf_s1), f7, f4, ops);
02177 f7 = tn;
02178
02179 f3 = Build_TN_Of_Mtype (mtype);
02180 Build_OP(fmpy, f3, p2, Gen_Enum_TN(ECV_sf_s1), src, f6, ops);
02181 RESET_COND_DEF_LAST(ops);
02182 tn = Build_TN_Of_Mtype (mtype);
02183 Build_OP(fmpy, tn, p2, Gen_Enum_TN(ECV_sf_s1), f4, f6, ops);
02184 RESET_COND_DEF_LAST(ops);
02185 f2 = tn;
02186
02187 f5 = Build_TN_Of_Mtype (mtype);
02188 Build_OP(fnma, f5, p2, Gen_Enum_TN(ECV_sf_s1), f3, f3, src, ops);
02189 RESET_COND_DEF_LAST(ops);
02190
02191 tn = Build_TN_Of_Mtype (mtype);
02192 Build_OP(fma, tn, p2, Gen_Enum_TN(ECV_sf_s1), f2, f5, f3, ops);
02193 RESET_COND_DEF_LAST(ops);
02194 f3 = tn;
02195
02196 f6a = f6;
02197 for (i = 0;; ++i) {
02198 tn = Build_TN_Of_Mtype (mtype);
02199 Build_OP(fnma, tn, p2, Gen_Enum_TN(ECV_sf_s1), f2, f3, f7, ops);
02200 RESET_COND_DEF_LAST(ops);
02201 f8 = tn;
02202 tn = Build_TN_Of_Mtype (mtype);
02203 Build_OP(fnma, tn, p2, Gen_Enum_TN(ECV_sf_s1), f3, f3, src, ops);
02204 RESET_COND_DEF_LAST(ops);
02205 f5 = tn;
02206 tn = Build_TN_Of_Mtype (mtype);
02207 Build_OP(fma, tn, p2, Gen_Enum_TN(ECV_sf_s1), f8, f6a, f2, ops);
02208 RESET_COND_DEF_LAST(ops);
02209 f2 = tn;
02210
02211 if (i == 1 + is_double) break;
02212
02213 tn = Build_TN_Of_Mtype (mtype);
02214 Build_OP(fma, tn, p2, Gen_Enum_TN(ECV_sf_s1), f2, f5, f3, ops);
02215 RESET_COND_DEF_LAST(ops);
02216 f3 = tn;
02217 tn = Build_TN_Of_Mtype (mtype);
02218 Build_OP(fadd, tn, p2, Gen_Enum_TN(ECV_sf_s1), f2, f2, ops);
02219 RESET_COND_DEF_LAST(ops);
02220 f6a = tn;
02221 }
02222
02223 Build_OP(rounded_fma, f6, p2, Gen_Enum_TN(ECV_sf_s0), f2, f5, f3, ops);
02224
02225
02226
02227
02228
02229
02230 Exp_COPY(result, f6, ops);
02231 }
02232
02233
02234 static void
02235 Expand_Intel_F10_Sqrt(TN *result, TN *src, OPS *ops)
02236 {
02237 TN * const f0 = FZero_TN;
02238 TN * const f1 = FOne_TN;
02239 TN * const f6 = src;
02240 TN *f7, *f8, *f9, *f10, *fr;
02241 TN * const p0 = True_TN;
02242 TN *p6;
02243 TN *r2;
02244 TN *t1;
02245
02246
02247
02248
02249
02250 t1 = Gen_Literal_TN(0x0fffe, 8);
02251 r2 = Build_TN_Of_Mtype(MTYPE_I8);
02252 Build_OP(TOP_movl, r2, p0, t1, ops);
02253 CGSPILL_Attach_Intconst_Remat(r2, TN_value(t1));
02254
02255
02256 f8 = Build_TN_Of_Mtype(MTYPE_F10);
02257 Build_OP(TOP_setf_exp, f8, p0, r2, ops);
02258
02259
02260
02261 p6 = Build_RCLASS_TN(ISA_REGISTER_CLASS_predicate);
02262 f7 = Build_TN_Of_Mtype(MTYPE_F10);
02263 Build_OP(TOP_frsqrta, f7, p6, p0, Gen_Enum_TN(ECV_sf_s0), f6, ops);
02264 fr = f7;
02265
02266
02267
02268 t1 = Build_TN_Of_Mtype(MTYPE_F10);
02269 Build_OP(TOP_fma, t1, p6, Gen_Enum_TN(ECV_sf_s1), f8, f7, f0, ops);
02270 RESET_COND_DEF_LAST(ops);
02271 f9 = t1;
02272
02273
02274
02275 t1 = Build_TN_Of_Mtype(MTYPE_F10);
02276 Build_OP(TOP_fma, t1, p6, Gen_Enum_TN(ECV_sf_s1), f6, f7, f0, ops);
02277 RESET_COND_DEF_LAST(ops);
02278 f7 = t1;
02279
02280
02281
02282 t1 = Build_TN_Of_Mtype(MTYPE_F10);
02283 Build_OP(TOP_fnma, t1, p6, Gen_Enum_TN(ECV_sf_s1), f7, f9, f8, ops);
02284 RESET_COND_DEF_LAST(ops);
02285 f10 = t1;
02286
02287
02288
02289 t1 = Build_TN_Of_Mtype(MTYPE_F10);
02290 Build_OP(TOP_fma, t1, p6, Gen_Enum_TN(ECV_sf_s1), f10, f9, f9, ops);
02291 RESET_COND_DEF_LAST(ops);
02292 f9 = t1;
02293
02294
02295
02296 t1 = Build_TN_Of_Mtype(MTYPE_F10);
02297 Build_OP(TOP_fma, t1, p6, Gen_Enum_TN(ECV_sf_s1), f10, f7, f7, ops);
02298 RESET_COND_DEF_LAST(ops);
02299 f7 = t1;
02300
02301
02302
02303 t1 = Build_TN_Of_Mtype(MTYPE_F10);
02304 Build_OP(TOP_fnma, t1, p6, Gen_Enum_TN(ECV_sf_s1), f7, f9, f8, ops);
02305 RESET_COND_DEF_LAST(ops);
02306 f10 = t1;
02307
02308
02309
02310 t1 = Build_TN_Of_Mtype(MTYPE_F10);
02311 Build_OP(TOP_fma, t1, p6, Gen_Enum_TN(ECV_sf_s1), f10, f9, f9, ops);
02312 RESET_COND_DEF_LAST(ops);
02313 f9 = t1;
02314
02315
02316
02317 t1 = Build_TN_Of_Mtype(MTYPE_F10);
02318 Build_OP(TOP_fma, t1, p6, Gen_Enum_TN(ECV_sf_s1), f10, f7, f7, ops);
02319 RESET_COND_DEF_LAST(ops);
02320 f7 = t1;
02321
02322
02323
02324 t1 = Build_TN_Of_Mtype(MTYPE_F10);
02325 Build_OP(TOP_fnma, t1, p6, Gen_Enum_TN(ECV_sf_s1), f7, f9, f8, ops);
02326 RESET_COND_DEF_LAST(ops);
02327 f10 = t1;
02328
02329
02330
02331 t1 = Build_TN_Of_Mtype(MTYPE_F10);
02332 Build_OP(TOP_fnma, t1, p6, Gen_Enum_TN(ECV_sf_s1), f7, f7, f6, ops);
02333 RESET_COND_DEF_LAST(ops);
02334 f8 = t1;
02335
02336
02337
02338 t1 = Build_TN_Of_Mtype(MTYPE_F10);
02339 Build_OP(TOP_fma, t1, p6, Gen_Enum_TN(ECV_sf_s1), f8, f9, f7, ops);
02340 RESET_COND_DEF_LAST(ops);
02341 f7 = t1;
02342
02343
02344
02345 t1 = Build_TN_Of_Mtype(MTYPE_F10);
02346 Build_OP(TOP_fma, t1, p6, Gen_Enum_TN(ECV_sf_s1), f10, f9, f9, ops);
02347 RESET_COND_DEF_LAST(ops);
02348 f9 = t1;
02349
02350
02351
02352 t1 = Build_TN_Of_Mtype(MTYPE_F10);
02353 Build_OP(TOP_fnma, t1, p6, Gen_Enum_TN(ECV_sf_s1), f7, f7, f6, ops);
02354 RESET_COND_DEF_LAST(ops);
02355 f8 = t1;
02356
02357
02358
02359 Build_OP(TOP_fma, fr, p6, Gen_Enum_TN(ECV_sf_s0), f8, f9, f7, ops);
02360 f7 = fr;
02361
02362
02363
02364 Exp_COPY(result, f7, ops);
02365 }
02366
02367
02368 static void
02369 Expand_Intel_Max_Thr_F8_Sqrt(TN *result, TN *src, OPS *ops)
02370 {
02371 TN * const f0 = FZero_TN;
02372 TN * const f1 = FOne_TN;
02373 TN * const f6 = src;
02374 TN *f7, *f8, *f9, *f10, *fr;
02375 TN * const p0 = True_TN;
02376 TN *p6;
02377 TN *r2;
02378 TN *t1;
02379
02380
02381
02382
02383
02384 t1 = Gen_Literal_TN(0x0fffe, 8);
02385 r2 = Build_TN_Of_Mtype(MTYPE_I8);
02386 Build_OP(TOP_movl, r2, p0, t1, ops);
02387 CGSPILL_Attach_Intconst_Remat(r2, TN_value(t1));
02388
02389
02390 f10 = Build_TN_Of_Mtype(MTYPE_F10);
02391 Build_OP(TOP_setf_exp, f10, p0, r2, ops);
02392
02393
02394
02395 p6 = Build_RCLASS_TN(ISA_REGISTER_CLASS_predicate);
02396 f7 = Build_TN_Of_Mtype(MTYPE_F10);
02397 Build_OP(TOP_frsqrta, f7, p6, p0, Gen_Enum_TN(ECV_sf_s0), f6, ops);
02398 fr = f7;
02399
02400
02401
02402 t1 = Build_TN_Of_Mtype(MTYPE_F10);
02403 Build_OP(TOP_fma, t1, p6, Gen_Enum_TN(ECV_sf_s1), f10, f7, f0, ops);
02404 RESET_COND_DEF_LAST(ops);
02405 f8 = t1;
02406
02407
02408
02409 t1 = Build_TN_Of_Mtype(MTYPE_F10);
02410 Build_OP(TOP_fma, t1, p6, Gen_Enum_TN(ECV_sf_s1), f6, f7, f0, ops);
02411 RESET_COND_DEF_LAST(ops);
02412 f7 = t1;
02413
02414
02415
02416 t1 = Build_TN_Of_Mtype(MTYPE_F10);
02417 Build_OP(TOP_fnma, t1, p6, Gen_Enum_TN(ECV_sf_s1), f7, f8, f10, ops);
02418 RESET_COND_DEF_LAST(ops);
02419 f9 = t1;
02420
02421
02422
02423 t1 = Build_TN_Of_Mtype(MTYPE_F10);
02424 Build_OP(TOP_fma, t1, p6, Gen_Enum_TN(ECV_sf_s1), f9, f8, f8, ops);
02425 RESET_COND_DEF_LAST(ops);
02426 f8 = t1;
02427
02428
02429
02430 t1 = Build_TN_Of_Mtype(MTYPE_F10);
02431 Build_OP(TOP_fma, t1, p6, Gen_Enum_TN(ECV_sf_s1), f9, f7, f7, ops);
02432 RESET_COND_DEF_LAST(ops);
02433 f7 = t1;
02434
02435
02436
02437 t1 = Build_TN_Of_Mtype(MTYPE_F10);
02438 Build_OP(TOP_fnma, t1, p6, Gen_Enum_TN(ECV_sf_s1), f7, f8, f10, ops);
02439 RESET_COND_DEF_LAST(ops);
02440 f9 = t1;
02441
02442
02443
02444 t1 = Build_TN_Of_Mtype(MTYPE_F10);
02445 Build_OP(TOP_fma, t1, p6, Gen_Enum_TN(ECV_sf_s1), f9, f8, f8, ops);
02446 RESET_COND_DEF_LAST(ops);
02447 f8 = t1;
02448
02449
02450
02451 t1 = Build_TN_Of_Mtype(MTYPE_F10);
02452 Build_OP(TOP_fma, t1, p6, Gen_Enum_TN(ECV_sf_s1), f9, f7, f7, ops);
02453 RESET_COND_DEF_LAST(ops);
02454 f7 = t1;
02455
02456
02457
02458 t1 = Build_TN_Of_Mtype(MTYPE_F10);
02459 Build_OP(TOP_fnma, t1, p6, Gen_Enum_TN(ECV_sf_s1), f7, f7, f6, ops);
02460 RESET_COND_DEF_LAST(ops);
02461 f9 = t1;
02462
02463
02464
02465 t1 = Build_TN_Of_Mtype(MTYPE_F10);
02466 Build_OP(TOP_fma, t1, p6, Gen_Enum_TN(ECV_sf_s1), f9, f8, f7, ops);
02467 RESET_COND_DEF_LAST(ops);
02468 f7 = t1;
02469
02470
02471
02472 t1 = Build_TN_Of_Mtype(MTYPE_F8);
02473 Build_OP(TOP_fnma, t1, p6, Gen_Enum_TN(ECV_sf_s1), f7, f7, f6, ops);
02474 RESET_COND_DEF_LAST(ops);
02475 f9 = t1;
02476
02477
02478
02479 Build_OP(TOP_fma_d, fr, p6, Gen_Enum_TN(ECV_sf_s0), f9, f8, f7, ops);
02480 f7 = fr;
02481
02482
02483
02484 Exp_COPY(result, f7, ops);
02485 }
02486
02487
02488 static void
02489 Expand_Intel_Max_Thr_F4_Sqrt(TN *result, TN *src, OPS *ops)
02490 {
02491 TN * const f0 = FZero_TN;
02492 TN * const f1 = FOne_TN;
02493 TN * const f6 = src;
02494 TN *f7, *f8, *f9, *f10, *fr;
02495 TN * const p0 = True_TN;
02496 TN *p6;
02497 TN *r2;
02498 TN *t1;
02499
02500
02501
02502
02503
02504 t1 = Gen_Literal_TN(0x0fffe, 8);
02505 r2 = Build_TN_Of_Mtype(MTYPE_I8);
02506 Build_OP(TOP_movl, r2, p0, t1, ops);
02507 CGSPILL_Attach_Intconst_Remat(r2, TN_value(t1));
02508
02509
02510 f8 = Build_TN_Of_Mtype(MTYPE_F10);
02511 Build_OP(TOP_setf_exp, f8, p0, r2, ops);
02512
02513
02514
02515 p6 = Build_RCLASS_TN(ISA_REGISTER_CLASS_predicate);
02516 f7 = Build_TN_Of_Mtype(MTYPE_F10);
02517 Build_OP(TOP_frsqrta, f7, p6, p0, Gen_Enum_TN(ECV_sf_s0), f6, ops);
02518 fr = f7;
02519
02520
02521
02522 t1 = Build_TN_Of_Mtype(MTYPE_F10);
02523 Build_OP(TOP_fma, t1, p6, Gen_Enum_TN(ECV_sf_s1), f8, f7, f0, ops);
02524 RESET_COND_DEF_LAST(ops);
02525 f9 = t1;
02526
02527
02528
02529 t1 = Build_TN_Of_Mtype(MTYPE_F10);
02530 Build_OP(TOP_fma, t1, p6, Gen_Enum_TN(ECV_sf_s1), f6, f7, f0, ops);
02531 RESET_COND_DEF_LAST(ops);
02532 f7 = t1;
02533
02534
02535
02536 t1 = Build_TN_Of_Mtype(MTYPE_F10);
02537 Build_OP(TOP_fnma, t1, p6, Gen_Enum_TN(ECV_sf_s1), f7, f9, f8, ops);
02538 RESET_COND_DEF_LAST(ops);
02539 f10 = t1;
02540
02541
02542
02543 t1 = Build_TN_Of_Mtype(MTYPE_F10);
02544 Build_OP(TOP_fma, t1, p6, Gen_Enum_TN(ECV_sf_s1), f8, f10, f10, ops);
02545 RESET_COND_DEF_LAST(ops);
02546 f8 = t1;
02547
02548
02549
02550 t1 = Build_TN_Of_Mtype(MTYPE_F10);
02551 Build_OP(TOP_fma, t1, p6, Gen_Enum_TN(ECV_sf_s1), f10, f8, f10, ops);
02552 RESET_COND_DEF_LAST(ops);
02553 f8 = t1;
02554
02555
02556
02557 t1 = Build_TN_Of_Mtype(MTYPE_F10);
02558 Build_OP(TOP_fma_s, t1, p6, Gen_Enum_TN(ECV_sf_s1), f8, f7, f7, ops);
02559 RESET_COND_DEF_LAST(ops);
02560 f7 = t1;
02561
02562
02563
02564 t1 = Build_TN_Of_Mtype(MTYPE_F10);
02565 Build_OP(TOP_fma, t1, p6, Gen_Enum_TN(ECV_sf_s1), f8, f9, f9, ops);
02566 RESET_COND_DEF_LAST(ops);
02567 f8 = t1;
02568
02569
02570
02571 t1 = Build_TN_Of_Mtype(MTYPE_F10);
02572 Build_OP(TOP_fnma, t1, p6, Gen_Enum_TN(ECV_sf_s1), f7, f7, f6, ops);
02573 RESET_COND_DEF_LAST(ops);
02574 f9 = t1;
02575
02576
02577
02578 Build_OP(TOP_fma_s, fr, p6, Gen_Enum_TN(ECV_sf_s0), f9, f8, f7, ops);
02579 f7 = fr;
02580
02581
02582
02583 Exp_COPY(result, f7, ops);
02584 }
02585
02586
02587 static void
02588 Expand_Intel_Min_Lat_F8_Sqrt(TN *result, TN *src, OPS *ops)
02589 {
02590 TN * const f0 = FZero_TN;
02591 TN * const f1 = FOne_TN;
02592 TN * const f6 = src;
02593 TN *f7, *f8, *f9, *f10, *f11, *f12, *f13, *f14, *fr;
02594 TN * const p0 = True_TN;
02595 TN *p6;
02596 TN *r2, *r3;
02597 TN *t1;
02598
02599
02600
02601
02602
02603 t1 = Gen_Literal_TN(0x0fffe, 8);
02604 r2 = Build_TN_Of_Mtype(MTYPE_I8);
02605 Build_OP(TOP_movl, r2, p0, t1, ops);
02606 CGSPILL_Attach_Intconst_Remat(r2, TN_value(t1));
02607
02608
02609 f9 = Build_TN_Of_Mtype(MTYPE_F10);
02610 Build_OP(TOP_setf_exp, f9, p0, r2, ops);
02611
02612
02613
02614 t1 = Gen_Literal_TN(0x3fc00000, 8);
02615 r3 = Build_TN_Of_Mtype(MTYPE_I8);
02616 Build_OP(TOP_movl, r3, p0, t1, ops);
02617 CGSPILL_Attach_Intconst_Remat(r3, TN_value(t1));
02618 f10 = Build_TN_Of_Mtype(MTYPE_F10);
02619 Build_OP(TOP_setf_s, f10, p0, r3, ops);
02620
02621
02622
02623 p6 = Build_RCLASS_TN(ISA_REGISTER_CLASS_predicate);
02624 f7 = Build_TN_Of_Mtype(MTYPE_F10);
02625 Build_OP(TOP_frsqrta, f7, p6, p0, Gen_Enum_TN(ECV_sf_s0), f6, ops);
02626 fr = f7;
02627
02628
02629
02630 t1 = Gen_Literal_TN(0x40200000, 8);
02631 r2 = Build_TN_Of_Mtype(MTYPE_I8);
02632 Build_OP(TOP_movl, r2, p0, t1, ops);
02633 CGSPILL_Attach_Intconst_Remat(r2, TN_value(t1));
02634 f11 = Build_TN_Of_Mtype(MTYPE_F10);
02635 Build_OP(TOP_setf_s, f11, p0, r2, ops);
02636
02637
02638
02639 t1 = Gen_Literal_TN(0x40fc0000, 8);
02640 r3 = Build_TN_Of_Mtype(MTYPE_I8);
02641 Build_OP(TOP_movl, r3, p0, t1, ops);
02642 CGSPILL_Attach_Intconst_Remat(r3, TN_value(t1));
02643 f12 = Build_TN_Of_Mtype(MTYPE_F10);
02644 Build_OP(TOP_setf_s, f12, p0, r3, ops);
02645
02646
02647
02648 t1 = Build_TN_Of_Mtype(MTYPE_F10);
02649 Build_OP(TOP_fma, t1, p6, Gen_Enum_TN(ECV_sf_s1), f9, f7, f0, ops);
02650 RESET_COND_DEF_LAST(ops);
02651 f8 = t1;
02652
02653
02654
02655 t1 = Build_TN_Of_Mtype(MTYPE_F10);
02656 Build_OP(TOP_fma, t1, p6, Gen_Enum_TN(ECV_sf_s1), f6, f7, f0, ops);
02657 RESET_COND_DEF_LAST(ops);
02658 f7 = t1;
02659
02660
02661
02662 t1 = Gen_Literal_TN(0x41670000, 8);
02663 r2 = Build_TN_Of_Mtype(MTYPE_I8);
02664 Build_OP(TOP_movl, r2, p0, t1, ops);
02665 CGSPILL_Attach_Intconst_Remat(r2, TN_value(t1));
02666 f13 = Build_TN_Of_Mtype(MTYPE_F10);
02667 Build_OP(TOP_setf_s, f13, p0, r2, ops);
02668
02669
02670
02671 t1 = Build_TN_Of_Mtype(MTYPE_F10);
02672 Build_OP(TOP_fnma, t1, p6, Gen_Enum_TN(ECV_sf_s1), f7, f8, f9, ops);
02673 RESET_COND_DEF_LAST(ops);
02674 f9 = t1;
02675
02676
02677
02678 t1 = Gen_Literal_TN(0x408c0000, 8);
02679 r3 = Build_TN_Of_Mtype(MTYPE_I8);
02680 Build_OP(TOP_movl, r3, p0, t1, ops);
02681 CGSPILL_Attach_Intconst_Remat(r3, TN_value(t1));
02682 f14 = Build_TN_Of_Mtype(MTYPE_F10);
02683 Build_OP(TOP_setf_s, f14, p0, r3, ops);
02684
02685
02686
02687 t1 = Build_TN_Of_Mtype(MTYPE_F10);
02688 Build_OP(TOP_fma, t1, p6, Gen_Enum_TN(ECV_sf_s1), f11, f9, f10, ops);
02689 RESET_COND_DEF_LAST(ops);
02690 f10 = t1;
02691
02692
02693
02694 t1 = Build_TN_Of_Mtype(MTYPE_F10);
02695 Build_OP(TOP_fma, t1, p6, Gen_Enum_TN(ECV_sf_s1), f9, f9, f0, ops);
02696 RESET_COND_DEF_LAST(ops);
02697 f11 = t1;
02698
02699
02700
02701 t1 = Build_TN_Of_Mtype(MTYPE_F10);
02702 Build_OP(TOP_fma, t1, p6, Gen_Enum_TN(ECV_sf_s1), f13, f9, f12, ops);
02703 RESET_COND_DEF_LAST(ops);
02704 f12 = t1;
02705
02706
02707
02708 t1 = Build_TN_Of_Mtype(MTYPE_F10);
02709 Build_OP(TOP_fma, t1, p6, Gen_Enum_TN(ECV_sf_s1), f11, f10, f9, ops);
02710 RESET_COND_DEF_LAST(ops);
02711 f10 = t1;
02712
02713
02714
02715 t1 = Build_TN_Of_Mtype(MTYPE_F10);
02716 Build_OP(TOP_fma, t1, p6, Gen_Enum_TN(ECV_sf_s1), f11, f11, f0, ops);
02717 RESET_COND_DEF_LAST(ops);
02718 f11 = t1;
02719
02720
02721
02722 t1 = Build_TN_Of_Mtype(MTYPE_F10);
02723 Build_OP(TOP_fma, t1, p6, Gen_Enum_TN(ECV_sf_s1), f9, f12, f14, ops);
02724 RESET_COND_DEF_LAST(ops);
02725 f9 = t1;
02726
02727
02728
02729 t1 = Build_TN_Of_Mtype(MTYPE_F10);
02730 Build_OP(TOP_fma, t1, p6, Gen_Enum_TN(ECV_sf_s1), f10, f7, f7, ops);
02731 RESET_COND_DEF_LAST(ops);
02732 f12 = t1;
02733
02734
02735
02736 t1 = Build_TN_Of_Mtype(MTYPE_F10);
02737 Build_OP(TOP_fma, t1, p6, Gen_Enum_TN(ECV_sf_s1), f7, f11, f0, ops);
02738 RESET_COND_DEF_LAST(ops);
02739 f7 = t1;
02740
02741
02742
02743 t1 = Build_TN_Of_Mtype(MTYPE_F10);
02744 Build_OP(TOP_fma, t1, p6, Gen_Enum_TN(ECV_sf_s1), f11, f9, f10, ops);
02745 RESET_COND_DEF_LAST(ops);
02746 f10 = t1;
02747
02748
02749
02750 t1 = Build_TN_Of_Mtype(MTYPE_F10);
02751 Build_OP(TOP_fma_d, t1, p6, Gen_Enum_TN(ECV_sf_s1), f9, f7, f12, ops);
02752 RESET_COND_DEF_LAST(ops);
02753 f7 = t1;
02754
02755
02756
02757 t1 = Build_TN_Of_Mtype(MTYPE_F10);
02758 Build_OP(TOP_fma, t1, p6, Gen_Enum_TN(ECV_sf_s1), f10, f8, f8, ops);
02759 RESET_COND_DEF_LAST(ops);
02760 f8 = t1;
02761
02762
02763
02764 t1 = Build_TN_Of_Mtype(MTYPE_F10);
02765 Build_OP(TOP_fnma, t1, p6, Gen_Enum_TN(ECV_sf_s1), f7, f7, f6, ops);
02766 RESET_COND_DEF_LAST(ops);
02767 f9 = t1;
02768
02769
02770
02771 Build_OP(TOP_fma_d, fr, p6, Gen_Enum_TN(ECV_sf_s0), f9, f8, f7, ops);
02772 f7 = fr;
02773
02774
02775
02776 Exp_COPY(result, f7, ops);
02777 }
02778
02779
02780 static void
02781 Expand_Intel_Min_Lat_F4_Sqrt(TN *result, TN *src, OPS *ops)
02782 {
02783 TN * const f0 = FZero_TN;
02784 TN * const f1 = FOne_TN;
02785 TN * const f6 = src;
02786 TN *f7, *f8, *f9, *f10, *f11, *fr;
02787 TN * const p0 = True_TN;
02788 TN *p6;
02789 TN *r2;
02790 TN *t1;
02791
02792
02793
02794
02795
02796 t1 = Gen_Literal_TN(0x0fffe, 8);
02797 r2 = Build_TN_Of_Mtype(MTYPE_I8);
02798 Build_OP(TOP_movl, r2, p0, t1, ops);
02799 CGSPILL_Attach_Intconst_Remat(r2, TN_value(t1));
02800
02801
02802 f8 = Build_TN_Of_Mtype(MTYPE_F10);
02803 Build_OP(TOP_setf_exp, f8, p0, r2, ops);
02804
02805
02806
02807 p6 = Build_RCLASS_TN(ISA_REGISTER_CLASS_predicate);
02808 f7 = Build_TN_Of_Mtype(MTYPE_F10);
02809 Build_OP(TOP_frsqrta, f7, p6, p0, Gen_Enum_TN(ECV_sf_s0), f6, ops);
02810 fr = f7;
02811
02812
02813
02814 t1 = Build_TN_Of_Mtype(MTYPE_F10);
02815 Build_OP(TOP_fma, t1, p6, Gen_Enum_TN(ECV_sf_s1), f8, f7, f0, ops);
02816 RESET_COND_DEF_LAST(ops);
02817 f9 = t1;
02818
02819
02820
02821 t1 = Build_TN_Of_Mtype(MTYPE_F10);
02822 Build_OP(TOP_fma, t1, p6, Gen_Enum_TN(ECV_sf_s1), f6, f7, f0, ops);
02823 RESET_COND_DEF_LAST(ops);
02824 f7 = t1;
02825
02826
02827
02828 t1 = Build_TN_Of_Mtype(MTYPE_F10);
02829 Build_OP(TOP_fnma, t1, p6, Gen_Enum_TN(ECV_sf_s1), f7, f9, f8, ops);
02830 RESET_COND_DEF_LAST(ops);
02831 f10 = t1;
02832
02833
02834
02835 t1 = Build_TN_Of_Mtype(MTYPE_F10);
02836 Build_OP(TOP_fma, t1, p6, Gen_Enum_TN(ECV_sf_s1), f8, f1, f1, ops);
02837 RESET_COND_DEF_LAST(ops);
02838 f8 = t1;
02839
02840
02841
02842 t1 = Build_TN_Of_Mtype(MTYPE_F10);
02843 Build_OP(TOP_fma, t1, p6, Gen_Enum_TN(ECV_sf_s1), f8, f10, f1, ops);
02844 RESET_COND_DEF_LAST(ops);
02845 f8 = t1;
02846
02847
02848
02849 t1 = Build_TN_Of_Mtype(MTYPE_F10);
02850 Build_OP(TOP_fma, t1, p6, Gen_Enum_TN(ECV_sf_s1), f10, f7, f0, ops);
02851 RESET_COND_DEF_LAST(ops);
02852 f11 = t1;
02853
02854
02855
02856 t1 = Build_TN_Of_Mtype(MTYPE_F10);
02857 Build_OP(TOP_fma, t1, p6, Gen_Enum_TN(ECV_sf_s1), f10, f9, f0, ops);
02858 RESET_COND_DEF_LAST(ops);
02859 f10 = t1;
02860
02861
02862
02863 t1 = Build_TN_Of_Mtype(MTYPE_F10);
02864 Build_OP(TOP_fma_s, t1, p6, Gen_Enum_TN(ECV_sf_s1), f8, f11, f7, ops);
02865 RESET_COND_DEF_LAST(ops);
02866 f7 = t1;
02867
02868
02869
02870 t1 = Build_TN_Of_Mtype(MTYPE_F10);
02871 Build_OP(TOP_fma, t1, p6, Gen_Enum_TN(ECV_sf_s1), f8, f10, f9, ops);
02872 RESET_COND_DEF_LAST(ops);
02873 f8 = t1;
02874
02875
02876
02877 t1 = Build_TN_Of_Mtype(MTYPE_F10);
02878 Build_OP(TOP_fnma, t1, p6, Gen_Enum_TN(ECV_sf_s1), f7, f7, f6, ops);
02879 RESET_COND_DEF_LAST(ops);
02880 f9 = t1;
02881
02882
02883
02884 Build_OP(TOP_fma_s, fr, p6, Gen_Enum_TN(ECV_sf_s1), f9, f8, f7, ops);
02885 f7 = fr;
02886
02887
02888
02889 Exp_COPY(result, f7, ops);
02890 }
02891
02892
02893 static void
02894 Expand_Intel_Max_Thr_Sqrt (TN *result, TN *src, TYPE_ID mtype, OPS *ops)
02895 {
02896 switch (mtype) {
02897 case MTYPE_F4:
02898 Expand_Intel_Max_Thr_F4_Sqrt(result, src, ops);
02899 break;
02900 case MTYPE_F8:
02901 Expand_Intel_Max_Thr_F8_Sqrt(result, src, ops);
02902 break;
02903 case MTYPE_F10:
02904 Expand_Intel_F10_Sqrt(result, src, ops);
02905 break;
02906 default:
02907 #pragma mips_frequency_hint NEVER
02908 FmtAssert(FALSE, ("Bad type in Expand_Intel_Max_Thr_Sqrt"));
02909
02910 }
02911 }
02912
02913
02914 static void
02915 Expand_Intel_Min_Lat_Sqrt (TN *result, TN *src, TYPE_ID mtype, OPS *ops)
02916 {
02917 switch (mtype) {
02918 case MTYPE_F4:
02919 Expand_Intel_Min_Lat_F4_Sqrt(result, src, ops);
02920 break;
02921 case MTYPE_F8:
02922 Expand_Intel_Min_Lat_F8_Sqrt(result, src, ops);
02923 break;
02924 case MTYPE_F10:
02925 Expand_Intel_F10_Sqrt(result, src, ops);
02926 break;
02927 default:
02928 #pragma mips_frequency_hint NEVER
02929 FmtAssert(FALSE, ("Bad type in Expand_Intel_Min_Lat_Sqrt"));
02930
02931 }
02932 }
02933
02934
02935 void
02936 Expand_Sqrt (TN *result, TN *src, TYPE_ID mtype, OPS *ops)
02937 {
02938 static BOOL initialized;
02939 static void (*exp_sqrt)(TN *, TN *, TYPE_ID, OPS *) = Expand_SGI_Sqrt;
02940
02941
02942 if (mtype == MTYPE_F10) {
02943 Expand_Intel_F10_Sqrt(result, src, ops);
02944 return;
02945 }
02946
02947 if (!initialized) {
02948 const char * const alg = CGEXP_sqrt_algorithm;
02949 if (strcasecmp(alg, "intel_max_thr") == 0) {
02950 exp_sqrt = Expand_Intel_Max_Thr_Sqrt;
02951 } else if (strcasecmp(alg, "intel_min_lat") == 0) {
02952 exp_sqrt = Expand_Intel_Min_Lat_Sqrt;
02953 } else if (strcasecmp(alg, "sgi") != 0) {
02954 DevWarn("invalid fdiv algorithm: %s", alg);
02955 }
02956 initialized = TRUE;
02957 }
02958
02959 exp_sqrt(result, src, mtype, ops);
02960 }
02961
02962
02963 static void
02964 Expand_Float_Compares(TOP cmp_opcode, TN *dest, TN *src1, TN *src2, OPS *ops, BOOL disable_exception = FALSE)
02965 {
02966 TN* sf = (disable_exception == TRUE) ? Gen_Enum_TN(ECV_sf_s1) : Gen_Enum_TN(ECV_sf_s0);
02967 if (TN_register_class(dest) == ISA_REGISTER_CLASS_predicate) {
02968
02969 TN *p1 = dest;
02970 TN *p2 = Get_Complement_TN(dest);
02971 Build_OP (cmp_opcode, p1, p2, True_TN, sf, src1, src2, ops);
02972 } else {
02973 TN *p1 = Build_RCLASS_TN (ISA_REGISTER_CLASS_predicate);
02974 TN *p2 = Build_RCLASS_TN (ISA_REGISTER_CLASS_predicate);
02975 Build_OP (cmp_opcode, p1, p2, True_TN, sf, src1, src2, ops);
02976
02977
02978
02979 Build_OP (TOP_mov, dest, p2, Zero_TN, ops);
02980 Build_OP (TOP_mov_i, dest, p1, Gen_Literal_TN(1, 4), ops);
02981 }
02982 }
02983
02984 void
02985 Expand_Float_Less (TN *dest, TN *src1, TN *src2, VARIANT variant, TYPE_ID mtype, OPS *ops)
02986 {
02987 Expand_Float_Compares(TOP_fcmp_lt, dest, src1, src2, ops);
02988 }
02989
02990 void
02991 Expand_Float_Greater (TN *dest, TN *src1, TN *src2, VARIANT variant, TYPE_ID mtype, OPS *ops)
02992 {
02993 Expand_Float_Compares(TOP_fcmp_gt, dest, src1, src2, ops);
02994 }
02995
02996 void
02997 Expand_Float_Less_Equal (TN *dest, TN *src1, TN *src2, VARIANT variant, TYPE_ID mtype, OPS *ops)
02998 {
02999 Expand_Float_Compares(TOP_fcmp_le, dest, src1, src2, ops);
03000 }
03001
03002 void
03003 Expand_Float_Greater_Equal (TN *dest, TN *src1, TN *src2, VARIANT variant, TYPE_ID mtype, OPS *ops)
03004 {
03005 Expand_Float_Compares(TOP_fcmp_ge, dest, src1, src2, ops);
03006 }
03007
03008 void
03009 Expand_Float_Equal (TN *dest, TN *src1, TN *src2, VARIANT variant, TYPE_ID mtype, OPS *ops)
03010 {
03011 Expand_Float_Compares(TOP_fcmp_eq, dest, src1, src2, ops);
03012 }
03013
03014 void
03015 Expand_Float_Not_Equal (TN *dest, TN *src1, TN *src2, VARIANT variant, TYPE_ID mtype, OPS *ops)
03016 {
03017 Expand_Float_Compares(TOP_fcmp_neq, dest, src1, src2, ops);
03018 }
03019
03020 void
03021 Expand_Recip_Sqrt (TN *result, TN *src, TYPE_ID mtype, OPS *ops)
03022 {
03023
03024
03025
03026
03027
03028
03029
03030
03031
03032
03033
03034
03035
03036
03037
03038
03039
03040
03041 INT i;
03042 TN *tn;
03043 TN *p2;
03044 TN *fr, *f2, *f3, *f4, *f5, *f6;
03045 BOOL is_double = MTYPE_is_size_double(mtype) != 0;
03046 TOP fnma = is_double ? TOP_fnma_d : TOP_fnma_s;
03047 TOP fma = is_double ? TOP_fma_d : TOP_fma_s;
03048 TOP fmpy = is_double ? TOP_fmpy_d : TOP_fmpy_s;
03049 const INT exp_bias = 0xffff;
03050 TN * const p0 = True_TN;
03051
03052 p2 = Build_RCLASS_TN (ISA_REGISTER_CLASS_predicate);
03053 f2 = Build_TN_Of_Mtype (mtype);
03054 Build_OP(TOP_frsqrta, f2, p2, p0, Gen_Enum_TN(ECV_sf_s0), src, ops);
03055 fr = f2;
03056
03057
03058 tn = Build_TN_Of_Mtype (MTYPE_I8);
03059 Build_OP(TOP_mov_i, tn, p0, Gen_Literal_TN(-1 + exp_bias, 4), ops);
03060 f4 = Build_TN_Of_Mtype (mtype);
03061 Build_OP(TOP_setf_exp, f4, p0, tn, ops);
03062 f5 = Build_TN_Of_Mtype (mtype);
03063 Build_OP(fmpy, f5, p2, Gen_Enum_TN(ECV_sf_s1), f4, src, ops);
03064 RESET_COND_DEF_LAST(ops);
03065
03066 for (i = 0; ; ++i) {
03067 tn = Build_TN_Of_Mtype (mtype);
03068 Build_OP(fmpy, tn, p2, Gen_Enum_TN(ECV_sf_s1), f2, f2, ops);
03069 RESET_COND_DEF_LAST(ops);
03070 f3 = tn;
03071 tn = Build_TN_Of_Mtype (mtype);
03072 Build_OP(fnma, tn, p2, Gen_Enum_TN(ECV_sf_s1), f5, f3, f4, ops);
03073 RESET_COND_DEF_LAST(ops);
03074 f6 = tn;
03075
03076
03077
03078
03079 if (i == 2) break;
03080
03081 tn = Build_TN_Of_Mtype (mtype);
03082 Build_OP(fma, tn, p2, Gen_Enum_TN(ECV_sf_s1), f2, f6, f2, ops);
03083 RESET_COND_DEF_LAST(ops);
03084 f2 = tn;
03085 }
03086
03087 Build_OP(fma, fr, p2, Gen_Enum_TN(ECV_sf_s1), f2, f6, f2, ops);
03088 Exp_COPY(result, f2, ops);
03089 }
03090
03091 void
03092 Expand_Flop (OPCODE opcode, TN *result, TN *src1, TN *src2, TN *src3, OPS *ops)
03093 {
03094 TOP opc;
03095
03096 switch (opcode) {
03097 case OPC_F4ADD:
03098 opc = TOP_fadd_s;
03099 break;
03100 case OPC_F8ADD:
03101 opc = TOP_fadd_d;
03102 break;
03103 case OPC_F10ADD:
03104 opc = TOP_fadd;
03105 break;
03106 case OPC_F4SUB:
03107 opc = TOP_fsub_s;
03108 break;
03109 case OPC_F8SUB:
03110 opc = TOP_fsub_d;
03111 break;
03112 case OPC_F10SUB:
03113 opc = TOP_fsub;
03114 break;
03115 case OPC_F4MPY:
03116 opc = TOP_fmpy_s;
03117 break;
03118 case OPC_F8MPY:
03119 opc = TOP_fmpy_d;
03120 break;
03121 case OPC_F10MPY:
03122 opc = TOP_fmpy;
03123 break;
03124 case OPC_F4MADD:
03125 opc = TOP_fma_s;
03126 break;
03127 case OPC_F4NMADD:
03128 {
03129 TN *tn = Build_TN_Of_Mtype (MTYPE_F4);
03130 Build_OP(TOP_fneg, tn, True_TN, src1, ops);
03131 src1 = tn;
03132 opc = TOP_fnma_s;
03133 }
03134 break;
03135 case OPC_F4MSUB:
03136 opc = TOP_fms_s;
03137 break;
03138 case OPC_F4NMSUB:
03139 opc = TOP_fnma_s;
03140 break;
03141 case OPC_F8MADD:
03142 opc = TOP_fma_d;
03143 break;
03144 case OPC_F8NMADD:
03145 {
03146 TN *tn = Build_TN_Of_Mtype (MTYPE_F8);
03147 Build_OP(TOP_fneg, tn, True_TN, src1, ops);
03148 src1 = tn;
03149 opc = TOP_fnma_d;
03150 }
03151 break;
03152 case OPC_F8MSUB:
03153 opc = TOP_fms_d;
03154 break;
03155 case OPC_F8NMSUB:
03156 opc = TOP_fnma_d;
03157 break;
03158 case OPC_F10MADD:
03159 opc = TOP_fma;
03160 break;
03161 case OPC_F10NMADD:
03162 {
03163 TN *tn = Build_TN_Of_Mtype (MTYPE_F10);
03164 Build_OP(TOP_fneg, tn, True_TN, src1, ops);
03165 src1 = tn;
03166 opc = TOP_fnma;
03167 }
03168 break;
03169 case OPC_F10MSUB:
03170 opc = TOP_fms;
03171 break;
03172 case OPC_F10NMSUB:
03173 opc = TOP_fnma;
03174 break;
03175 case OPC_F4DIV:
03176 case OPC_F8DIV:
03177 case OPC_F10DIV:
03178 Expand_Float_Divide (result, src1, src2, OPCODE_rtype(opcode), ops);
03179 return;
03180 case OPC_F4RECIP:
03181 case OPC_F8RECIP:
03182 case OPC_F10RECIP:
03183 Expand_Float_Recip (result, src1, OPCODE_rtype(opcode), ops);
03184 return;
03185 case OPC_F4RSQRT:
03186 case OPC_F8RSQRT:
03187 case OPC_F10RSQRT:
03188 Expand_Recip_Sqrt (result, src1, OPCODE_rtype(opcode), ops);
03189 return;
03190 default:
03191 #pragma mips_frequency_hint NEVER
03192 FmtAssert(FALSE, ("unexpected opcode %s", OPCODE_name(opcode)));
03193
03194 }
03195 if (TOP_is_madd(opc)) {
03196 Build_OP(opc, result, True_TN, Gen_Enum_TN(ECV_sf_s0), src2, src3, src1, ops);
03197 } else {
03198 Build_OP(opc, result, True_TN, Gen_Enum_TN(ECV_sf_s0), src1, src2, ops);
03199 }
03200 }
03201
03202
03203
03204 extern void
03205 Init_CG_Expand (void)
03206 {
03207 static BOOL Initialized = FALSE;
03208
03209
03210 Trace_Exp = Get_Trace (TP_CGEXP, 1);
03211
03212 Trace_Exp2 = Get_Trace (TP_CGEXP, 4);
03213
03214
03215 if (Initialized) return;
03216 Initialized = TRUE;
03217
03218 Initialize_Branch_Variants();
03219 }
03220
03221
03222
03223
03224
03225
03226
03227 void
03228 Exp_COPY (TN *tgt_tn, TN *src_tn, OPS *ops)
03229 {
03230 if ( TN_is_constant(src_tn) ) {
03231 FmtAssert (TN_has_value(src_tn), ("Exp_COPY: illegal source tn"));
03232
03233 Exp_OP1 (OPC_I8INTCONST, tgt_tn, src_tn, ops);
03234 }
03235 else {
03236 ISA_REGISTER_CLASS tgt_rc = TN_register_class(tgt_tn);
03237 ISA_REGISTER_CLASS src_rc = TN_register_class(src_tn);
03238
03239 if (tgt_rc != src_rc) {
03240
03241
03242
03243
03244 BOOL is_double = FALSE;
03245 if ( (tgt_rc == ISA_REGISTER_CLASS_float && TN_size(tgt_tn) == 8)
03246 || (src_rc == ISA_REGISTER_CLASS_float && TN_size(src_tn) == 8)) {
03247 is_double = TRUE;
03248 }
03249
03250 TOP opc = CGTARG_Inter_RegClass_Copy(tgt_rc, src_rc, is_double);
03251
03252 FmtAssert(opc != TOP_UNDEFINED, ("NYI: Exp_COPY inter-class copy for %s to %s",
03253 ISA_REGISTER_CLASS_INFO_Name(ISA_REGISTER_CLASS_Info(src_rc)),
03254 ISA_REGISTER_CLASS_INFO_Name(ISA_REGISTER_CLASS_Info(tgt_rc))));
03255
03256 Build_OP(opc, tgt_tn, True_TN, src_tn, ops);
03257 } else if (tgt_rc == ISA_REGISTER_CLASS_float) {
03258 Build_OP (TOP_mov_f, tgt_tn, True_TN, src_tn, ops);
03259 Set_OP_copy (OPS_last(ops));
03260 } else if (tgt_rc == ISA_REGISTER_CLASS_integer) {
03261 Build_OP (TOP_mov, tgt_tn, True_TN, src_tn, ops);
03262 Set_OP_copy (OPS_last(ops));
03263 } else if (tgt_rc == ISA_REGISTER_CLASS_branch) {
03264 Build_OP (TOP_copy_br, tgt_tn, True_TN, src_tn, ops);
03265 Set_OP_copy (OPS_last(ops));
03266 } else if (tgt_rc == ISA_REGISTER_CLASS_predicate) {
03267 Build_OP(TOP_cmp_eq_unc,tgt_tn,True_TN,src_tn,Zero_TN,Zero_TN,ops);
03268
03269 } else {
03270 #pragma mips_frequency_hint NEVER
03271 FmtAssert(FALSE, ("NYI: Exp_COPY intra-class copy for %s",
03272 ISA_REGISTER_CLASS_INFO_Name(ISA_REGISTER_CLASS_Info(tgt_rc))));
03273
03274 }
03275
03276 if (Trace_Exp2) {
03277 #pragma mips_frequency_hint NEVER
03278 fprintf(TFile, "exp_copy into: ");
03279 Print_OP(OPS_last(ops));
03280 }
03281 }
03282 }
03283
03284 void
03285 Exp_Intrinsic_Op (INTRINSIC id, TN *result, TN *op0, TN * op1, OPS *ops)
03286 {
03287 switch (id) {
03288 case INTRN_GETF_EXP:
03289 Build_OP (TOP_getf_exp, result, True_TN, op0, ops);
03290 break;
03291 case INTRN_GETF_SIG:
03292 Build_OP (TOP_getf_sig, result, True_TN, op0, ops);
03293 break;
03294 case INTRN_SETF_EXP:
03295 Build_OP (TOP_setf_exp, result, True_TN, op0, ops);
03296 break;
03297 case INTRN_SETF_SIG:
03298 Build_OP (TOP_setf_sig, result, True_TN, op0, ops);
03299 break;
03300 case INTRN_I4FFS:
03301 {
03302
03303
03304
03305
03306
03307
03308
03309
03310
03311 TN *p1 = Build_RCLASS_TN (ISA_REGISTER_CLASS_predicate);
03312 TN *p2 = Build_RCLASS_TN (ISA_REGISTER_CLASS_predicate);
03313 TN *t1 = Build_TN_Of_Mtype (MTYPE_I4);
03314 TN *t2 = Build_TN_Of_Mtype (MTYPE_I4);
03315 Build_OP (TOP_cmp_eq, p1, p2, True_TN, op0, Zero_TN, ops);
03316 Build_OP (TOP_adds, t1, True_TN, Gen_Literal_TN(-1, 4), op0, ops);
03317 Build_OP (TOP_xor, t2, True_TN, t1, op0, ops);
03318 Build_OP (TOP_mov, result, p1, Zero_TN, ops);
03319 Build_OP (TOP_popcnt, result, p2, t2, ops);
03320 }
03321 break;
03322 case INTRN_ISGREATER:
03323 Expand_Float_Compares(TOP_fcmp_gt, result, op0, op1, ops, TRUE );
03324 break;
03325 case INTRN_ISGREATEREQUAL:
03326 Expand_Float_Compares(TOP_fcmp_ge, result, op0, op1, ops, TRUE );
03327 break;
03328 case INTRN_ISLESS:
03329 Expand_Float_Compares(TOP_fcmp_lt, result, op0, op1, ops, TRUE );
03330 break;
03331 case INTRN_ISLESSEQUAL:
03332 Expand_Float_Compares(TOP_fcmp_le, result, op0, op1, ops, TRUE );
03333 break;
03334 case INTRN_ISLESSGREATER:
03335 Expand_Float_Compares(TOP_fcmp_neq, result, op0, op1, ops, TRUE );
03336 break;
03337 case INTRN_ISUNORDERED:
03338 Expand_Float_Compares(TOP_fcmp_unord, result, op0, op1, ops, TRUE );
03339 break;
03340 case INTRN_CLZ32:
03341
03342
03343
03344 {
03345 TN* t1 = Build_TN_Of_Mtype (MTYPE_F8);
03346 TN* t2 = Build_TN_Of_Mtype (MTYPE_F8);
03347 TN* t3 = Build_TN_Of_Mtype (MTYPE_I4);
03348 Build_OP (TOP_setf_sig, t1, True_TN, op0, ops);
03349 Build_OP (TOP_fcvt_xuf, t2, True_TN, Gen_Enum_TN(ECV_sf_s0), t1, ops);
03350 Build_OP (TOP_getf_exp, t3, True_TN, t2, ops);
03351 Build_OP (TOP_mov_i, result, True_TN, Gen_Literal_TN(65598, 4), ops);
03352 Build_OP (TOP_sub, result, True_TN, result, t3, ops);
03353 Build_OP (TOP_adds, result, True_TN, Gen_Literal_TN(-32, 4), result, ops);
03354 }
03355 break;
03356 case INTRN_CTZ:
03357
03358
03359
03360 {
03361 TN* tn1 = Build_TN_Of_Mtype (MTYPE_I8);
03362 Build_OP (TOP_adds, tn1, True_TN, Gen_Literal_TN(-1, 8), op0, ops);
03363 Build_OP (TOP_andcm_i, op0, True_TN, Gen_Literal_TN(-1, 8), op0, ops);
03364 Build_OP (TOP_and, op0, True_TN, op0, tn1, ops);
03365 Build_OP (TOP_popcnt, result, True_TN, op0, ops);
03366 }
03367 break;
03368 default:
03369 #pragma mips_frequency_hint NEVER
03370 FmtAssert (FALSE, ("WHIRL_To_OPs: illegal intrinsic op"));
03371
03372 }
03373 }
03374
03375
03376
03377
03378
03379
03380
03381
03382
03383 static INT
03384 Expand_TOP_intrncall (
03385 const OP *op,
03386 OPS *ops,
03387 BOOL get_sequence_length,
03388 INT pc_value)
03389 {
03390 FmtAssert(FALSE, ("Expand_TOP_intrncall NYI"));
03391
03392 }
03393
03394 static TYPE_ID
03395 Get_Intrinsic_Size_Mtype (INTRINSIC id)
03396 {
03397 switch (id) {
03398 case INTRN_COMPARE_AND_SWAP_I4:
03399 case INTRN_LOCK_TEST_AND_SET_I4:
03400 case INTRN_LOCK_RELEASE_I4:
03401 case INTRN_FETCH_AND_ADD_I4:
03402 case INTRN_ADD_AND_FETCH_I4:
03403 case INTRN_SUB_AND_FETCH_I4:
03404 case INTRN_OR_AND_FETCH_I4:
03405 case INTRN_XOR_AND_FETCH_I4:
03406 case INTRN_AND_AND_FETCH_I4:
03407 case INTRN_NAND_AND_FETCH_I4:
03408 case INTRN_FETCH_AND_SUB_I4:
03409 case INTRN_FETCH_AND_OR_I4:
03410 case INTRN_FETCH_AND_XOR_I4:
03411 case INTRN_FETCH_AND_AND_I4:
03412 case INTRN_FETCH_AND_NAND_I4:
03413 return MTYPE_I4;
03414 case INTRN_COMPARE_AND_SWAP_I8:
03415 case INTRN_LOCK_TEST_AND_SET_I8:
03416 case INTRN_LOCK_RELEASE_I8:
03417 case INTRN_FETCH_AND_ADD_I8:
03418 case INTRN_ADD_AND_FETCH_I8:
03419 case INTRN_SUB_AND_FETCH_I8:
03420 case INTRN_OR_AND_FETCH_I8:
03421 case INTRN_XOR_AND_FETCH_I8:
03422 case INTRN_AND_AND_FETCH_I8:
03423 case INTRN_NAND_AND_FETCH_I8:
03424 case INTRN_FETCH_AND_SUB_I8:
03425 case INTRN_FETCH_AND_OR_I8:
03426 case INTRN_FETCH_AND_XOR_I8:
03427 case INTRN_FETCH_AND_AND_I8:
03428 case INTRN_FETCH_AND_NAND_I8:
03429 case INTRN_SYNCHRONIZE:
03430 return MTYPE_I8;
03431 default:
03432 #pragma mips_frequency_hint NEVER
03433 FmtAssert(FALSE, ("Unexpected intrinsic %d", id));
03434
03435 }
03436 }
03437
03438 static BOOL
03439 Intrinsic_Returns_New_Value (INTRINSIC id)
03440 {
03441 switch (id) {
03442 case INTRN_ADD_AND_FETCH_I4:
03443 case INTRN_SUB_AND_FETCH_I4:
03444 case INTRN_OR_AND_FETCH_I4:
03445 case INTRN_XOR_AND_FETCH_I4:
03446 case INTRN_AND_AND_FETCH_I4:
03447 case INTRN_NAND_AND_FETCH_I4:
03448 case INTRN_ADD_AND_FETCH_I8:
03449 case INTRN_SUB_AND_FETCH_I8:
03450 case INTRN_OR_AND_FETCH_I8:
03451 case INTRN_XOR_AND_FETCH_I8:
03452 case INTRN_AND_AND_FETCH_I8:
03453 case INTRN_NAND_AND_FETCH_I8:
03454 return TRUE;
03455 default:
03456 return FALSE;
03457 }
03458 }
03459
03460
03461
03462
03463
03464
03465 TN *
03466 Exp_Intrinsic_Call (INTRINSIC id, TN *op0, TN *op1, TN *op2, OPS *ops,
03467 LABEL_IDX *label, OPS *loop_ops)
03468 {
03469 TN *result;
03470 TN *ar_ccv;
03471 TN *p1;
03472 TN *p2;
03473 TOP top;
03474 TYPE_ID size_mtype = Get_Intrinsic_Size_Mtype (id);
03475
03476
03477
03478 switch (id) {
03479 case INTRN_COMPARE_AND_SWAP_I4:
03480 case INTRN_COMPARE_AND_SWAP_I8:
03481
03482
03483
03484
03485
03486
03487
03488
03489 result = Build_TN_Of_Mtype (MTYPE_I8);
03490 ar_ccv = Build_Dedicated_TN ( ISA_REGISTER_CLASS_application,
03491 (REGISTER)(REGISTER_MIN + 32),
03492 8);
03493 Build_OP (TOP_mov_t_ar_r, ar_ccv, True_TN, op1, ops);
03494 Build_OP (TOP_mf, True_TN, ops);
03495 if (size_mtype == MTYPE_I4)
03496 top = TOP_cmpxchg4;
03497 else
03498 top = TOP_cmpxchg8;
03499 Build_OP (top, result, True_TN, Gen_Enum_TN(ECV_sem_rel),
03500 Gen_Enum_TN(ECV_ldhint_nta), op0, op2, ops);
03501 p1 = Build_RCLASS_TN (ISA_REGISTER_CLASS_predicate);
03502 p2 = Build_RCLASS_TN (ISA_REGISTER_CLASS_predicate);
03503 Build_OP (TOP_cmp_eq, p1, p2, True_TN, result, op1, ops);
03504 Build_OP (TOP_mov_i, result, p1, Gen_Literal_TN(1, 4), ops);
03505 Build_OP (TOP_mov, result, p2, Zero_TN, ops);
03506 break;
03507
03508 case INTRN_LOCK_TEST_AND_SET_I4:
03509 case INTRN_LOCK_TEST_AND_SET_I8:
03510
03511
03512
03513
03514
03515 if (size_mtype == MTYPE_I4)
03516 top = TOP_xchg4;
03517 else
03518 top = TOP_xchg8;
03519 result = Build_TN_Of_Mtype (MTYPE_I8);
03520 Build_OP (top, result, True_TN, Gen_Enum_TN(ECV_ldhint_nta),
03521 op0, op1, ops);
03522 break;
03523
03524 case INTRN_LOCK_RELEASE_I4:
03525 case INTRN_LOCK_RELEASE_I8:
03526
03527
03528
03529 if (size_mtype == MTYPE_I4)
03530 top = TOP_st4;
03531 else
03532 top = TOP_st8;
03533 Build_OP (top, True_TN,
03534 Gen_Enum_TN(ECV_sttype_rel),
03535 Gen_Enum_TN(ECV_sthint_nta),
03536 op0, Zero_TN, ops);
03537 break;
03538
03539 case INTRN_SYNCHRONIZE:
03540 Build_OP (TOP_mf, True_TN, ops);
03541 break;
03542
03543 case INTRN_FETCH_AND_ADD_I4:
03544 case INTRN_FETCH_AND_ADD_I8:
03545
03546
03547
03548
03549 if (TN_is_constant(op1) && TN_has_value(op1)
03550 && ISA_LC_Value_In_Class ( TN_value(op1), LC_fetchadd) )
03551 {
03552 Build_OP (TOP_mf, True_TN, ops);
03553 if (size_mtype == MTYPE_I4)
03554 top = TOP_fetchadd4;
03555 else
03556 top = TOP_fetchadd8;
03557 result = Build_TN_Of_Mtype (MTYPE_I8);
03558 Build_OP (top, result, True_TN,
03559 Gen_Enum_TN(ECV_sem_rel),
03560 Gen_Enum_TN(ECV_ldhint),
03561 op0, op1, ops);
03562 break;
03563 }
03564
03565 case INTRN_ADD_AND_FETCH_I4:
03566 case INTRN_ADD_AND_FETCH_I8:
03567 {
03568
03569 TN *orig_value = Build_TN_Of_Mtype (size_mtype);
03570 TN *old_value = Build_TN_Of_Mtype (size_mtype);
03571 TN *new_value = Build_TN_Of_Mtype (size_mtype);
03572 if (Intrinsic_Returns_New_Value(id))
03573 result = new_value;
03574 else
03575 result = old_value;
03576
03577 Expand_Load (
03578
03579 OPCODE_make_op(OPR_LDID, Pointer_Mtype, Pointer_Mtype),
03580 orig_value, op0, Gen_Literal_TN (0, 4), V_NONE, ops);
03581
03582 *label = Gen_Temp_Label();
03583 Expand_Add (new_value, orig_value, op1, size_mtype, loop_ops);
03584 ar_ccv = Build_Dedicated_TN ( ISA_REGISTER_CLASS_application,
03585 (REGISTER)(REGISTER_MIN + 32),
03586 8);
03587 Build_OP (TOP_mov_t_ar_r, ar_ccv, True_TN, orig_value, loop_ops);
03588 Build_OP (TOP_mf, True_TN, loop_ops);
03589 if (size_mtype == MTYPE_I4)
03590 top = TOP_cmpxchg4;
03591 else
03592 top = TOP_cmpxchg8;
03593 Build_OP (top, old_value, True_TN, Gen_Enum_TN(ECV_sem_rel),
03594 Gen_Enum_TN(ECV_ldhint), op0, new_value, loop_ops);
03595 p1 = Build_RCLASS_TN (ISA_REGISTER_CLASS_predicate);
03596 p2 = Build_RCLASS_TN (ISA_REGISTER_CLASS_predicate);
03597 Build_OP (TOP_cmp_eq, p1, p2, True_TN, old_value, orig_value, loop_ops);
03598 Build_OP (TOP_mov, orig_value, p2, old_value, loop_ops);
03599 Build_OP (TOP_br_cond, p2,
03600 Gen_Enum_TN(ECV_bwh_dptk),
03601 Gen_Enum_TN(ECV_ph_few),
03602 Gen_Enum_TN(ECV_dh),
03603 Gen_Label_TN(*label,0), loop_ops);
03604 break;
03605 }
03606 case INTRN_FETCH_AND_SUB_I4:
03607 case INTRN_FETCH_AND_SUB_I8:
03608 case INTRN_SUB_AND_FETCH_I4:
03609 case INTRN_OR_AND_FETCH_I4:
03610 case INTRN_XOR_AND_FETCH_I4:
03611 case INTRN_AND_AND_FETCH_I4:
03612 case INTRN_NAND_AND_FETCH_I4:
03613 case INTRN_FETCH_AND_OR_I4:
03614 case INTRN_FETCH_AND_XOR_I4:
03615 case INTRN_FETCH_AND_AND_I4:
03616 case INTRN_FETCH_AND_NAND_I4:
03617 case INTRN_SUB_AND_FETCH_I8:
03618 case INTRN_OR_AND_FETCH_I8:
03619 case INTRN_XOR_AND_FETCH_I8:
03620 case INTRN_AND_AND_FETCH_I8:
03621 case INTRN_NAND_AND_FETCH_I8:
03622 case INTRN_FETCH_AND_OR_I8:
03623 case INTRN_FETCH_AND_XOR_I8:
03624 case INTRN_FETCH_AND_AND_I8:
03625 case INTRN_FETCH_AND_NAND_I8:
03626 default:
03627 #pragma mips_frequency_hint NEVER
03628 FmtAssert (FALSE, ("WHIRL_To_OPs: illegal intrinsic call"));
03629
03630 }
03631 return result;
03632 }
03633
03634
03635
03636
03637
03638
03639
03640
03641 void Exp_Simulated_Op(const OP *op, OPS *ops, INT pc_value)
03642 {
03643 DevWarn("Exp_Simulated_Op should not be reached");
03644 switch (OP_code(op)) {
03645 case TOP_intrncall:
03646 Expand_TOP_intrncall(op, ops, FALSE, pc_value);
03647 break;
03648 case TOP_spadjust:
03649
03650 if (OP_spadjust_plus(op)) {
03651
03652 Expand_Copy (OP_result(op,0), OP_opnd(op,2), Pointer_Mtype, ops);
03653 } else {
03654 Expand_Sub (OP_result(op,0), OP_opnd(op,1), OP_opnd(op,2), Pointer_Mtype, ops);
03655 }
03656 {
03657
03658 OP *newop;
03659 FOR_ALL_OPS_OPs(ops, newop) {
03660 if (OP_has_predicate(newop))
03661 Set_OP_opnd (newop, OP_PREDICATE_OPND,
03662 OP_opnd(op, OP_PREDICATE_OPND) );
03663 }
03664 }
03665 break;
03666 default:
03667 #pragma mips_frequency_hint NEVER
03668 FmtAssert(FALSE, ("simulated OP %s not handled", TOP_Name(OP_code(op))));
03669
03670 }
03671 }
03672
03673
03674
03675
03676
03677
03678
03679 INT
03680 Simulated_Op_Real_Ops(const OP *op)
03681 {
03682 switch (OP_code(op)) {
03683 case TOP_intrncall:
03684 return Expand_TOP_intrncall (op, NULL, TRUE, 0);
03685 case TOP_spadjust:
03686 return 1;
03687 default:
03688
03689
03690
03691
03692
03693 return 0;
03694 }
03695 }
03696
03697
03698
03699
03700
03701
03702
03703
03704 INT
03705 Simulated_Op_Real_Inst_Words(const OP *op)
03706 {
03707 switch (OP_code(op)) {
03708 case TOP_spadjust:
03709 return 1;
03710 case TOP_asm:
03711
03712
03713 return 3;
03714 default:
03715
03716 #pragma mips_frequency_hint NEVER
03717 FmtAssert(FALSE, ("shouldn't be calling Simulated_Op_Real_Inst_Words for %s", TOP_Name(OP_code(op)) ));
03718
03719 }
03720 }
03721
03722
03723
03724
03725
03726
03727
03728
03729 BOOL
03730 Exp_Is_Large_Stack_Sym(ST* sym, INT64 ofst)
03731 {
03732 ST *base_sym;
03733 INT64 base_ofst;
03734
03735 if (sym == NULL) {
03736 return FALSE;
03737 }
03738
03739 Allocate_Object(sym);
03740
03741 Base_Symbol_And_Offset_For_Addressing (sym, ofst, &base_sym, &base_ofst);
03742
03743 if (ST_on_stack(sym) && !ISA_LC_Value_In_Class(base_ofst, LC_i14)) {
03744 return TRUE;
03745 }
03746 return FALSE;
03747 }
03748
03749 void
03750 Exp_Noop (OPS *ops)
03751 {
03752 Build_OP (CGTARG_Noop_Top(), True_TN, Gen_Literal_TN(0, 4), ops);
03753 }
03754
03755 void
03756 Exp_Generic_Pred_Calc(TN* result1, TN *result2, COMPARE_TYPE ctype,
03757 TN *qual_pred, OPS* ops)
03758 {
03759 TOP pred_top;
03760
03761 switch (ctype) {
03762 case COMPARE_TYPE_or:
03763 pred_top = TOP_cmp_eq_or;
03764 break;
03765 case COMPARE_TYPE_and:
03766 pred_top = TOP_cmp_ne_and;
03767 break;
03768 }
03769 Build_OP(pred_top, result1, result2, qual_pred, Zero_TN, Zero_TN, ops);
03770 }
03771
03772
03773 void
03774 Exp_Pred_Calc(TN* result, OP* cmp_op, COMPARE_TYPE ctype, BOOL false_result,
03775 OPS* ops)
03776 {
03777 TOP pred_top;
03778
03779 switch (ctype) {
03780 case COMPARE_TYPE_or:
03781 case COMPARE_TYPE_orcm:
03782 case COMPARE_TYPE_and:
03783 case COMPARE_TYPE_andcm:
03784
03785
03786
03787
03788
03789
03790 pred_top = CGTARG_Parallel_Compare(cmp_op, ctype);
03791 if (pred_top == TOP_UNDEFINED) {
03792 TN* pred;
03793 switch (ctype) {
03794 case COMPARE_TYPE_or:
03795 pred = OP_result(cmp_op, 0);
03796 pred_top = TOP_cmp_eq_or;
03797 break;
03798 case COMPARE_TYPE_orcm:
03799 pred = OP_result(cmp_op, 1);
03800 pred_top = TOP_cmp_eq_or;
03801 break;
03802 case COMPARE_TYPE_and:
03803 pred = OP_result(cmp_op, 0);
03804 pred_top = TOP_cmp_eq_and;
03805 break;
03806 case COMPARE_TYPE_andcm:
03807 pred = OP_result(cmp_op, 1);
03808 pred_top = TOP_cmp_eq_and;
03809 break;
03810 }
03811 Build_OP(pred_top, result,
03812 True_TN, pred,
03813 Zero_TN, Zero_TN, ops);
03814 } else {
03815 Build_OP(pred_top, result, True_TN,
03816 OP_opnd(cmp_op, OP_PREDICATE_OPND),
03817 OP_opnd(cmp_op, OP_PREDICATE_OPND+1),
03818 OP_opnd(cmp_op, OP_PREDICATE_OPND+2),
03819 ops);
03820 }
03821 break;
03822
03823 case COMPARE_TYPE_or_andcm:
03824 case COMPARE_TYPE_and_orcm:
03825 FmtAssert(0,("Exp_Pred_Calc NYI for or_andcm, and and_orcm compares."));
03826 break;
03827
03828 case COMPARE_TYPE_unc:
03829 if (false_result) {
03830 if (TOP_is_flop(OP_code(cmp_op))) {
03831 Build_OP(OP_code(cmp_op), True_TN, result,
03832 OP_opnd(cmp_op, OP_PREDICATE_OPND),
03833 OP_opnd(cmp_op, OP_PREDICATE_OPND+1),
03834 OP_opnd(cmp_op, OP_PREDICATE_OPND+2),
03835 OP_opnd(cmp_op, OP_PREDICATE_OPND+3),
03836 ops);
03837 } else {
03838 Build_OP(OP_code(cmp_op), True_TN, result,
03839 OP_opnd(cmp_op, OP_PREDICATE_OPND),
03840 OP_opnd(cmp_op, OP_PREDICATE_OPND+1),
03841 OP_opnd(cmp_op, OP_PREDICATE_OPND+2),
03842 ops);
03843 }
03844 } else {
03845 if (TOP_is_flop(OP_code(cmp_op))) {
03846 Build_OP(OP_code(cmp_op), result, True_TN,
03847 OP_opnd(cmp_op, OP_PREDICATE_OPND),
03848 OP_opnd(cmp_op, OP_PREDICATE_OPND+1),
03849 OP_opnd(cmp_op, OP_PREDICATE_OPND+2),
03850 OP_opnd(cmp_op, OP_PREDICATE_OPND+3),
03851 ops);
03852 } else {
03853 Build_OP(OP_code(cmp_op), result, True_TN,
03854 OP_opnd(cmp_op, OP_PREDICATE_OPND),
03855 OP_opnd(cmp_op, OP_PREDICATE_OPND+1),
03856 OP_opnd(cmp_op, OP_PREDICATE_OPND+2),
03857 ops);
03858 }
03859 }
03860 break;
03861 }
03862 }
03863
03865
03866
03867
03868
03869
03870
03871
03872
03873
03874
03875
03876
03877
03878
03879
03880
03881
03882
03883
03884
03885
03886 void
03887 Exp_True_False_Preds_For_Block(BB *bb, TN* &true_tn, TN * &false_tn)
03888 {
03889 COMPARE_TYPE comp_type;
03890 TN* tn1;
03891 TN* tn2;
03892 OP* compare_op;
03893 OP* br_op = BB_branch_op(bb);
03894 BOOL reusing_tns;
03895 VARIANT branch_variant;
03896 DEF_KIND kind;
03897
03898 true_tn = NULL;
03899 false_tn = NULL;
03900 reusing_tns = FALSE;
03901
03902 branch_variant = CGTARG_Analyze_Branch(br_op, &tn1, &tn2);
03903 Is_True(branch_variant == V_BR_P_TRUE,("Can't get predicates for block %d",BB_id(bb)));
03904
03905
03906 compare_op = TN_Reaching_Value_At_Op(tn1, br_op, &kind, TRUE);
03907 if (compare_op && kind == VAL_KNOWN && !OP_cond_def(compare_op)) {
03908
03909
03910
03911
03912
03913
03914 reusing_tns = TRUE;
03915 OP_Change_Opcode(compare_op,CGTARG_Get_unc_Variant(OP_code(compare_op)));
03916 Set_OP_cond_def_kind(compare_op,OP_ALWAYS_UNC_DEF);
03917
03918 true_tn = tn1;
03919
03920 if (OP_result(compare_op,1) != tn1) {
03921 false_tn = OP_result(compare_op,1);
03922 } else {
03923 false_tn = OP_result(compare_op,0);
03924 }
03925 }
03926
03927 if (!reusing_tns) {
03928 OPS ops = OPS_EMPTY;
03929 DevWarn("inserting non-optimal inverse predicate in BB %d",BB_id(bb));
03930 true_tn = tn1;
03931
03932 false_tn = Gen_Predicate_TN();
03933 Exp_Pred_Complement(false_tn, True_TN, true_tn, &ops);
03934 BB_Insert_Ops(bb,br_op,&ops,TRUE);
03935 }
03936
03937 return;
03938 }
03939
03940 void Expand_Const (TN *dest, TN *src, TYPE_ID mtype, OPS *ops)
03941 {
03942 FmtAssert( TN_is_symbol(src), ("Expand_Const: src not a symbol TN"));
03943
03944 TCON tc = ST_tcon_val(TN_var(src));
03945
03946 if (Targ_Is_Zero(tc)) {
03947
03948 Build_OP (TOP_mov_f, dest, True_TN, FZero_TN, ops);
03949 return;
03950 }
03951
03952 if (MTYPE_is_float(mtype) && mtype == TCON_ty(tc)) {
03953 if (mtype == MTYPE_F4 || mtype == MTYPE_F8 || mtype == MTYPE_F10) {
03954 double val = Targ_To_Host_Float(tc);
03955 if (val == 1.0) {
03956
03957 Build_OP (TOP_mov_f, dest, True_TN, FOne_TN, ops);
03958 return;
03959 }
03960 if (val == -1.0) {
03961
03962 Build_OP (TOP_fneg, dest, True_TN, FOne_TN, ops);
03963 return;
03964 }
03965 if (val == 2.0) {
03966
03967 TOP fadd = (mtype == MTYPE_F4) ? TOP_fadd_s :
03968 (mtype == MTYPE_F8) ? TOP_fadd_d : TOP_fadd;
03969 Build_OP (fadd, dest, True_TN, Gen_Enum_TN(ECV_sf_s0), FOne_TN,
03970 FOne_TN, ops);
03971 return;
03972 }
03973 }
03974 if (CGEXP_float_consts_from_ints &&
03975 (mtype == MTYPE_F4 || mtype == MTYPE_F8)) {
03976 TN *tn = Build_TN_Of_Mtype (MTYPE_I8);
03977 INT64 fimm = (mtype == MTYPE_F4) ? TCON_uval(tc) : TCON_k0(tc);
03978 if (Targ_Is_Power_Of_Two(tc)) {
03979
03980 INT exp;
03981 INT sign;
03982 INT sign_exp;
03983 if (mtype == MTYPE_F4) {
03984 exp = ((fimm >> 23) & 0xff) - 127;
03985 sign = (fimm >> 31) & 0x1;
03986 } else {
03987 exp = ((fimm >> 52) & 0x7ff) - 1023;
03988 sign = (fimm >> 63) & 0x1;
03989 }
03990 sign_exp = (sign << 17) | (exp + 0xffff);
03991 Build_OP (TOP_mov_i, tn, True_TN, Gen_Literal_TN(sign_exp, 4), ops);
03992 CGSPILL_Attach_Intconst_Remat (tn, sign_exp);
03993 Build_OP (TOP_setf_exp, dest, True_TN, tn, ops);
03994 return;
03995 }
03996 if (mtype == MTYPE_F4 || mtype == MTYPE_F8) {
03997
03998 TOP setf = (mtype == MTYPE_F4) ? TOP_setf_s : TOP_setf_d;
03999 Build_OP (TOP_movl, tn, True_TN, Gen_Literal_TN(fimm, 8), ops);
04000 CGSPILL_Attach_Intconst_Remat (tn, fimm);
04001 Build_OP (setf, dest, True_TN, tn, ops);
04002 return;
04003 }
04004 }
04005 }
04006
04007
04008 Exp_Load (mtype, mtype, dest, TN_var(src), 0, ops, V_NONE);
04009 }
04010
04011 BOOL
04012 Target_Has_Immediate_Operand (WN *parent, WN *expr)
04013 {
04014 if (WN_operator(parent) == OPR_INTRINSIC_CALL
04015 && (((INTRINSIC) WN_intrinsic (parent) == INTRN_FETCH_AND_ADD_I4)
04016 || ((INTRINSIC) WN_intrinsic (parent) == INTRN_FETCH_AND_ADD_I8)) )
04017 {
04018
04019 return TRUE;
04020 }
04021 if (WN_operator(parent) == OPR_SUB) {
04022
04023 return TRUE;
04024 }
04025
04026 return FALSE;
04027 }
04028
04029 void
04030 Exp_Spadjust (TN *dest, TN *size, VARIANT variant, OPS *ops)
04031 {
04032 Build_OP (TOP_spadjust, dest, True_TN, SP_TN, size, ops);
04033 switch (variant) {
04034 case V_SPADJUST_PLUS:
04035 Set_OP_spadjust_plus(OPS_last(ops));
04036 break;
04037 case V_SPADJUST_MINUS:
04038 Set_OP_spadjust_minus(OPS_last(ops));
04039 break;
04040 case V_NONE:
04041 break;
04042 default:
04043 Is_True(FALSE, ("bad variant (0x%llx) for Exp_Spadjust", (INT64)variant));
04044 break;
04045 }
04046 }