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 #include <stdint.h>
00052 #include "defs.h"
00053 #include "config.h"
00054 #include "erglob.h"
00055 #include "ercg.h"
00056 #include "erbe.h"
00057 #include "glob.h"
00058 #include "tracing.h"
00059 #include "util.h"
00060
00061 #include "tn.h"
00062 #include "cg_flags.h"
00063 #include "bb.h"
00064 #include "symtab.h"
00065 #include "opcode.h"
00066 #include "const.h"
00067 #include "targ_const.h"
00068 #include "op.h"
00069 #include "data_layout.h"
00070 #include "stblock.h"
00071 #include "cgexp.h"
00072 #include "cgexp_internals.h"
00073 #include "w2op.h"
00074 #include "label_util.h"
00075 #include "cgtarget.h"
00076 #include "whirl2ops.h"
00077 #include "targ_sim.h"
00078 #include "targ_const_private.h"
00079 #include "config_opt.h"
00080 #ifdef KEY
00081 #include "ebo.h"
00082 #endif
00083
00084 BOOL Reuse_Temp_TNs = FALSE;
00085
00086 BOOL Trace_Exp2 = FALSE;
00087
00088
00089 static BOOL Disable_Const_Mult_Opt = FALSE;
00090
00091
00092 INT Mtype_Index (TYPE_ID mtype)
00093 {
00094 switch (mtype) {
00095 case MTYPE_I1: return 0;
00096 case MTYPE_I2: return 1;
00097 case MTYPE_I4: return 2;
00098 case MTYPE_I8: return 3;
00099 case MTYPE_U1: return 4;
00100 case MTYPE_U2: return 5;
00101 case MTYPE_U4: return 6;
00102 case MTYPE_U8: return 7;
00103 case MTYPE_F4: return 8;
00104 case MTYPE_F8: return 9;
00105 default: FmtAssert(FALSE, ("unexpected mtype")); return 0;
00106 }
00107 }
00108
00109
00110
00111 INT Mtype_Byte_Index (TYPE_ID mtype)
00112 {
00113 switch (mtype) {
00114 case MTYPE_I1: return 0;
00115 case MTYPE_U1: return 0;
00116 case MTYPE_I2: return 1;
00117 case MTYPE_U2: return 1;
00118 case MTYPE_I4: return 2;
00119 case MTYPE_U4: return 2;
00120 case MTYPE_I8: return 3;
00121 case MTYPE_U8: return 3;
00122 default: FmtAssert(FALSE, ("unexpected mtype")); return 0;
00123 }
00124 }
00125
00126 void Expand_Start()
00127 {
00128 return;
00129
00130 }
00131
00132
00133
00134 void Expand_Finish()
00135 {
00136 return;
00137
00138 }
00139
00140 static TN* Gen_Const_Symbol_TN( INT64 int_val,
00141 double float_val,
00142 TYPE_ID mtype,
00143 TN_RELOCS relocs = TN_RELOC_NONE )
00144 {
00145 FmtAssert( !MTYPE_is_quad(mtype), ("Quad const is not supported") );
00146 FmtAssert( !MTYPE_is_vector(mtype), ("Vector const is not supported") );
00147
00148 const TCON tcon = MTYPE_is_integral(mtype)
00149 ? Host_To_Targ( mtype, int_val ) : Host_To_Targ_Float( mtype, float_val );
00150
00151 ST* sym = New_Const_Sym( Enter_tcon(tcon), Be_Type_Tbl( TCON_ty(tcon) ) );
00152
00153 Allocate_Object(sym);
00154
00155 return Gen_Symbol_TN( sym, 0, relocs );
00156 }
00157
00158
00159 void
00160 Expand_Copy (TN *result, TN *src, TYPE_ID mtype, OPS *ops)
00161 {
00162 if (mtype == MTYPE_I1 || mtype == MTYPE_U1) {
00163
00164
00165 mtype = Mtype_TransferSize (MTYPE_I2, mtype);
00166 }
00167 TOP opc = (TOP) (TOP_mov_s8 + Mtype_Index(mtype));
00168 Build_OP (opc, result, src, ops);
00169 Set_OP_copy (OPS_last(ops));
00170 if (TN_has_memory_space(src))
00171 Set_TN_memory_space (result, TN_memory_space(src));
00172 if (TN_in_texture_mem(src) && TN_home(src) != NULL) {
00173 if (Trace_Exp2) fprintf(TFile,"replace texture tn home copy\n");
00174
00175
00176 Set_TN_home (result, TN_home(src));
00177 }
00178 }
00179
00180 void
00181 Expand_Int_To_Int (TN *result, TYPE_ID rtype, TN *src, TYPE_ID stype, OPS *ops)
00182 {
00183
00184
00185 TOP top;
00186 FmtAssert(MTYPE_byte_size(rtype) <= TN_size(result),
00187 ("cvt rtype won't fit in register"));
00188 if (MTYPE_size_reg(stype) < MTYPE_size_reg(Mtype_Of_TN(src))
00189 && MTYPE_size_reg(rtype) == MTYPE_size_reg(Mtype_Of_TN(result)))
00190 {
00191
00192
00193 DevWarn("stype < tn size");
00194 TN *tmp = Build_TN_Of_Mtype (stype);
00195 Expand_Int_To_Int (tmp, stype, src, Mtype_Of_TN(src), ops);
00196 src = tmp;
00197 }
00198 if ((MTYPE_size_reg(Mtype_Of_TN(result)) > MTYPE_size_reg(Mtype_Of_TN(src)))
00199 && (MTYPE_size_reg(rtype) < MTYPE_size_reg(Mtype_Of_TN(result))))
00200 {
00201
00202
00203
00204
00205
00206 DevWarn("convert of mismatched reg sizes requires extra cvt");
00207 TN *tmp = Build_TN_Like(src);
00208 Expand_Int_To_Int (tmp, rtype, src, stype, ops);
00209 src = tmp;
00210 rtype = Mtype_Of_TN(result);
00211 }
00212 if (MTYPE_size_reg(Mtype_Of_TN(result)) == 32
00213 && MTYPE_size_reg(rtype) < 32)
00214 {
00215
00216
00217
00218
00219 INT ridx;
00220 switch (rtype) {
00221 case MTYPE_I1: ridx = 0; break;
00222 case MTYPE_I2: ridx = 1; break;
00223 case MTYPE_U1: ridx = 2; break;
00224 case MTYPE_U2: ridx = 3; break;
00225 default: FmtAssert(FALSE, ("unexpected mtype"));
00226 }
00227 top = (TOP) (TOP_cvt_s8_s16_b32 + 5*ridx + Mtype_Index(stype));
00228 if (MTYPE_is_unsigned(stype)) {
00229
00230
00231 top = (TOP) (top - 1);
00232 }
00233 }
00234 else if (MTYPE_size_reg(Mtype_Of_TN(result)) == 64
00235 && MTYPE_size_reg(rtype) < 64)
00236 {
00237
00238 INT ridx;
00239 switch (rtype) {
00240 case MTYPE_I1: ridx = 0; break;
00241 case MTYPE_I2: ridx = 1; break;
00242 case MTYPE_I4: ridx = 2; break;
00243 case MTYPE_U1: ridx = 3; break;
00244 case MTYPE_U2: ridx = 4; break;
00245 case MTYPE_U4: ridx = 5; break;
00246 default: FmtAssert(FALSE, ("unexpected mtype"));
00247 }
00248 top = (TOP) (TOP_cvt_s8_s16_b64 + 7*ridx + Mtype_Index(stype));
00249 }
00250 else {
00251 top = (TOP) (TOP_cvt_s8_s16 + 9*Mtype_Index(rtype) + Mtype_Index(stype));
00252 }
00253 if (Mtype_Index(stype) > Mtype_Index(rtype)) {
00254
00255 top = (TOP) (top - 1);
00256 }
00257 Build_OP (top, result, src, ops);
00258 if (TN_is_boolean(src))
00259 Set_TN_is_boolean(result);
00260 }
00261
00262 void
00263 Expand_Convert (TN *result, TYPE_ID rtype, TN *src, TYPE_ID stype, OPS *ops)
00264 {
00265 TOP top;
00266 if (rtype == stype) {
00267 Expand_Copy (result, src, rtype, ops);
00268 }
00269 else if (MTYPE_is_integral(stype) && MTYPE_is_integral(rtype)) {
00270 Expand_Int_To_Int (result, rtype, src, stype, ops);
00271 }
00272 else if (MTYPE_is_integral(stype) && MTYPE_is_float(rtype)) {
00273 Expand_Int_To_Float (result, src, rtype, stype, ops);
00274 }
00275 else if (MTYPE_is_float(stype) && MTYPE_is_integral(rtype)) {
00276 Expand_Float_To_Int_Cvt (result, src, rtype, stype, ops);
00277 }
00278 else if (MTYPE_is_float(stype) && MTYPE_is_float(rtype)) {
00279 Expand_Float_To_Float (result, src, rtype, stype, ops);
00280 }
00281 }
00282
00283
00284
00285
00286
00287
00288
00289 void Expand_Convert_Length ( TN *dest, TN *src, TN *length_tn, TYPE_ID mtype,
00290 BOOL signed_extension, OPS *ops )
00291 {
00292 FmtAssert (! MTYPE_float(mtype),
00293 ("Expand_Convert_Length: illegal data type\n"));
00294 FmtAssert (TN_has_value(length_tn),
00295 ("Expand_Convert_Length: non-constant length\n"));
00296
00297 TYPE_ID length_mtype;
00298 UINT64 length = TN_value (length_tn);
00299 switch (length) {
00300 case 8:
00301 length_mtype = (signed_extension ? MTYPE_I1 : MTYPE_U1);
00302 break;
00303 case 16:
00304 length_mtype = (signed_extension ? MTYPE_I2 : MTYPE_U2);
00305 break;
00306 case 32:
00307 length_mtype = (signed_extension ? MTYPE_I4 : MTYPE_U4);
00308 break;
00309 case 64:
00310 length_mtype = (signed_extension ? MTYPE_I8 : MTYPE_U8);
00311 break;
00312 default:
00313
00314 FmtAssert(FALSE, ("NYI"));
00315 }
00316 Expand_Convert (dest, length_mtype, src, mtype, ops);
00317 }
00318
00319 void
00320 Exp_Immediate (TN *dest, TN *src, BOOL is_signed, OPS *ops)
00321 {
00322 Expand_Mtype_Immediate(dest, src, Mtype_Of_TN(dest), ops);
00323 }
00324
00325
00326
00327
00328 void
00329 Expand_Immediate (TN *dest, TN *src, BOOL is_signed, OPS *ops)
00330 {
00331 FmtAssert((TN_is_constant(src)),
00332 ("unexpected non-constant in Expand_Immediate"));
00333 FmtAssert((TN_has_value(src) || TN_is_symbol(src)),
00334 ("expected value or const in Expand_Immediate"));
00335 FmtAssert(FALSE,("NYI"));
00336 }
00337
00338 void
00339 Expand_Mtype_Immediate (TN *dest, TN *src, TYPE_ID mtype, OPS *ops)
00340 {
00341 TOP opc;
00342 FmtAssert((TN_is_constant(src)),
00343 ("unexpected non-constant in Expand_Immediate"));
00344 FmtAssert((TN_has_value(src) || TN_is_symbol(src)),
00345 ("expected value or const in Expand_Immediate"));
00346
00347 opc = (TOP) (TOP_mov_s8_lit + Mtype_Index(mtype));
00348 Build_OP (opc, dest, src, ops);
00349 }
00350
00351 TN*
00352 Expand_Mtype_Immediate_Into_Register (TN *src, TYPE_ID mtype, OPS *ops)
00353 {
00354
00355 TN *tmp = Build_TN_Of_Mtype (mtype);
00356 Expand_Mtype_Immediate (tmp, src, mtype, ops);
00357 return tmp;
00358 }
00359
00360 TN*
00361 Expand_Immediate_Into_Register (TN *src, BOOL is_64bit, OPS *ops)
00362 {
00363 return Expand_Mtype_Immediate_Into_Register (src,
00364 (is_64bit ? MTYPE_I8 : MTYPE_I4), ops);
00365 }
00366
00367 void
00368 Expand_Add (TN *result, TN *src1, TN *src2, TYPE_ID mtype, OPS *ops)
00369 {
00370 TOP opc = (TOP) (TOP_add_s8 + Mtype_Index(mtype));
00371 INT64 val;
00372 FmtAssert(!TN_is_constant(src1), ("NYI"));
00373
00374
00375
00376 if (TN_has_memory_space(src1))
00377 Set_TN_memory_space (result, TN_memory_space(src1));
00378 else if (TN_has_memory_space(src2))
00379 Set_TN_memory_space (result, TN_memory_space(src2));
00380
00381 if (TN_Can_Use_Constant_Value (src1, mtype, &val)) {
00382 opc = (TOP) (TOP_add_s8_lit + Mtype_Index(mtype));
00383 src1 = src2;
00384 src2 = Gen_Literal_TN_Of_Mtype (val, mtype);
00385 } else if (TN_Can_Use_Constant_Value (src2, mtype, &val)) {
00386 if (val < 0 && ISA_LC_Value_In_Class (-val, Lit_Class_For_Mtype(mtype)))
00387 {
00388
00389
00390 src2 = Gen_Literal_TN_Of_Mtype (-val, mtype);
00391 Expand_Sub (result, src1, src2, mtype, ops);
00392 return;
00393 }
00394 else {
00395 opc = (TOP) (TOP_add_s8_lit + Mtype_Index(mtype));
00396 src2 = Gen_Literal_TN_Of_Mtype (val, mtype);
00397 }
00398 }
00399 else if (TN_is_constant(src2)) {
00400
00401 src2 = Expand_Mtype_Immediate_Into_Register (src2, mtype, ops);
00402 }
00403 Build_OP (opc, result, src1, src2, ops);
00404 }
00405
00406 void
00407 Expand_Sub (TN *result, TN *src1, TN *src2, TYPE_ID mtype, OPS *ops)
00408 {
00409 TOP opc = (TOP) (TOP_sub_s8 + Mtype_Index(mtype));
00410 INT64 val;
00411
00412
00413 if (TN_has_memory_space(src1))
00414 Set_TN_memory_space (result, TN_memory_space(src1));
00415 else if (TN_has_memory_space(src2))
00416 Set_TN_memory_space (result, TN_memory_space(src2));
00417
00418 if (TN_is_constant(src1)) {
00419 FmtAssert(TN_has_value(src1), ("NYI"));
00420
00421 src1 = Expand_Mtype_Immediate_Into_Register (src1, mtype, ops);
00422 }
00423 if (TN_Can_Use_Constant_Value (src2, mtype, &val)) {
00424 opc = (TOP) (TOP_sub_s8_lit + Mtype_Index(mtype));
00425 src2 = Gen_Literal_TN_Of_Mtype (val, mtype);
00426 }
00427 else if (TN_is_constant(src2)) {
00428
00429 src2 = Expand_Mtype_Immediate_Into_Register (src2, mtype, ops);
00430 }
00431 Build_OP (opc, result, src1, src2, ops);
00432 }
00433
00434
00435 void
00436 Expand_Neg (TN *result, TN *src, TYPE_ID mtype, OPS *ops)
00437 {
00438 if (MTYPE_is_unsigned(mtype)) {
00439
00440
00441 mtype = Mtype_TransferSign(MTYPE_I4, mtype);
00442 }
00443 if (TN_is_constant(src)) {
00444 FmtAssert(TN_has_value(src), ("NYI"));
00445
00446 src = Expand_Mtype_Immediate_Into_Register (src, mtype, ops);
00447 }
00448 TOP opc = (TOP) (TOP_neg_s8 + Mtype_Index(mtype));
00449 Build_OP (opc, result, src, ops);
00450 }
00451
00452
00453 void
00454 Expand_Abs (TN *dest, TN *src, TYPE_ID mtype, OPS *ops)
00455 {
00456 if (MTYPE_is_unsigned(mtype)) {
00457
00458
00459 mtype = Mtype_TransferSign(MTYPE_I4, mtype);
00460 }
00461 if (TN_is_constant(src)) {
00462 FmtAssert(TN_has_value(src), ("NYI"));
00463
00464 src = Expand_Mtype_Immediate_Into_Register (src, mtype, ops);
00465 }
00466 TOP opc = (TOP) (TOP_abs_s8 + Mtype_Index(mtype));
00467 Build_OP (opc, dest, src, ops);
00468 }
00469
00470 void
00471 Expand_Shift (TN *result, TN *src1, TN *src2, TYPE_ID mtype, SHIFT_DIRECTION kind, OPS *ops)
00472 {
00473 TOP opc;
00474 INT64 val;
00475 switch (kind) {
00476 case shift_left:
00477 opc = TOP_shl_b8;
00478 break;
00479 case shift_aright:
00480
00481
00482
00483 if (MTYPE_is_unsigned(mtype))
00484 mtype = MTYPE_complement(mtype);
00485 opc = TOP_shr_s8;
00486 break;
00487 case shift_lright:
00488
00489
00490
00491
00492
00493 if (MTYPE_is_signed(mtype))
00494 mtype = MTYPE_complement(mtype);
00495 opc = TOP_shr_s8;
00496 break;
00497 }
00498 if (TN_Can_Use_Constant_Value (src1, mtype, &val)) {
00499 opc = (opc == TOP_shl_b8) ? TOP_shl_b8_lit1 : TOP_shr_s8_lit1;
00500 src1 = Gen_Literal_TN_Of_Mtype (val, mtype);
00501 }
00502 else if (TN_is_constant(src1)) {
00503
00504 src1 = Expand_Mtype_Immediate_Into_Register (src1, mtype, ops);
00505 }
00506 if (TN_Can_Use_Constant_Value (src2, mtype, &val)) {
00507 if (val == 0) {
00508
00509 Expand_Copy (result, src1, mtype, ops);
00510 return;
00511 }
00512 opc = (opc == TOP_shl_b8) ? TOP_shl_b8_lit : TOP_shr_s8_lit;
00513 src2 = Gen_Literal_TN_Of_Mtype (val, mtype);
00514 }
00515 else if (TN_is_constant(src2)) {
00516
00517 src2 = Expand_Mtype_Immediate_Into_Register (src2, mtype, ops);
00518 }
00519 if (kind == shift_left)
00520 opc = (TOP) (opc + Mtype_Byte_Index(mtype));
00521 else
00522 opc = (TOP) (opc + Mtype_Index(mtype));
00523 Build_OP (opc, result, src1, src2, ops);
00524 }
00525
00526
00527
00528
00529 static BOOL
00530 Expand_Constant_Multiply (TN *result, TN *var_tn, TARG_INT constant, TYPE_ID mtype, OPS *ops)
00531 {
00532
00533 BOOL did_do_fast;
00534 INT16 limit;
00535 TN *x = var_tn;
00536 INT64 c = constant;
00537 BOOL needs_sign_extension;
00538
00539
00540 if (c == 0) {
00541 Expand_Copy (result, Zero_TN, MTYPE_I8, ops);
00542 return TRUE;
00543 } else if (c == 1) {
00544 Expand_Copy (result, var_tn, MTYPE_I8, ops);
00545 return TRUE;
00546 } else if (c == -1) {
00547 Expand_Neg(result, var_tn, mtype, ops);
00548 return TRUE;
00549 }
00550
00551 FmtAssert(FALSE, ("NYI"));
00552 return TRUE;
00553 }
00554
00555 void
00556 Expand_Multiply (TN *result, TN *src1, TN *src2, TYPE_ID mtype, OPS *ops)
00557 {
00558 TOP opc;
00559 FmtAssert(!TN_is_constant(src1), ("NYI"));
00560
00561 if (MTYPE_is_integral(mtype)) {
00562 INT64 val;
00563
00564 opc = (TOP) (TOP_mul_lo_s8 + Mtype_Index(mtype));
00565 if (TN_Can_Use_Constant_Value (src2, mtype, &val)) {
00566
00567
00568 opc = (TOP) (TOP_mul_lo_s8_lit + Mtype_Index(mtype));
00569 src2 = Gen_Literal_TN_Of_Mtype (val, mtype);
00570 }
00571 else if (TN_is_constant(src2)) {
00572
00573 src2 = Expand_Mtype_Immediate_Into_Register (src2, mtype, ops);
00574 }
00575 }
00576 else {
00577
00578 opc = (mtype == MTYPE_F4) ? TOP_mul_f32 : TOP_mul_f64;
00579 if (TN_has_value(src2)) {
00580
00581 src2 = Expand_Mtype_Immediate_Into_Register (src2, mtype, ops);
00582 }
00583 }
00584 Build_OP (opc, result, src1, src2, ops);
00585 }
00586
00587
00588 void
00589 Expand_High_Multiply (TN *result, TN *src1, TN *src2, TYPE_ID mtype, OPS *ops)
00590 {
00591 TOP opc = (TOP) (TOP_mul_hi_s8 + Mtype_Index(mtype));
00592 FmtAssert(!TN_is_constant(src1), ("NYI"));
00593 if (TN_is_constant(src2)) {
00594 FmtAssert(TN_has_value(src2), ("NYI"));
00595
00596
00597
00598 src2 = Expand_Mtype_Immediate_Into_Register (src2, mtype, ops);
00599 }
00600 Build_OP (opc, result, src1, src2, ops);
00601 }
00602
00603 static TN*
00604 Normalize_Operand (TN *src, TYPE_ID mtype, OPS *ops)
00605 {
00606
00607 DevWarn("insert normalize of operand");
00608 TN *tmp = Build_TN_Like(src);
00609 Expand_Not_Equal (tmp, src, Gen_Literal_TN(0,4), V_NONE, mtype, mtype, ops);
00610 return tmp;
00611 }
00612
00613 void Expand_Logical_Not (TN *dest, TN *src, VARIANT variant, OPS *ops)
00614 {
00615
00616 TYPE_ID src_mtype = Mtype_Of_TN(src);
00617 TYPE_ID dest_mtype = Mtype_Of_TN(dest);
00618 if ( ! V_normalized_op1(variant)) {
00619 src = Normalize_Operand (src, src_mtype, ops);
00620 }
00621 if (dest_mtype == MTYPE_B && src_mtype == MTYPE_B) {
00622
00623 Build_OP (TOP_not_pred, dest, src, ops);
00624 }
00625 else if (dest_mtype == MTYPE_B && src_mtype != MTYPE_B) {
00626
00627 TOP opc = (TOP) (TOP_setp_eq_s8 + Mtype_Index(src_mtype));
00628 TN *zero_tn = Expand_Mtype_Immediate_Into_Register (
00629 Gen_Literal_TN(0,4), MTYPE_I4, ops);
00630 Build_OP (opc, dest, src, zero_tn, ops);
00631 }
00632 else if (dest_mtype != MTYPE_B && src_mtype == MTYPE_B) {
00633
00634 FmtAssert(FALSE, ("unexpected LNOT"));
00635 }
00636 else {
00637
00638 TOP opc = (TOP) (TOP_xor_b8_lit + Mtype_Byte_Index(src_mtype));
00639 Build_OP (opc, dest, src, Gen_Literal_TN(1,4), ops);
00640 }
00641 }
00642
00643 void Expand_Logical_And (TN *dest, TN *src1, TN *src2, VARIANT variant, OPS *ops)
00644 {
00645 TYPE_ID dest_mtype = Mtype_Of_TN(dest);
00646 TYPE_ID src_mtype = Mtype_Of_TN(src1);
00647 if ( ! V_normalized_op1(variant)) {
00648 src1 = Normalize_Operand (src1, src_mtype, ops);
00649 }
00650 if ( ! V_normalized_op2(variant)) {
00651 src2 = Normalize_Operand (src2, src_mtype, ops);
00652 }
00653 if (src_mtype == MTYPE_B) {
00654
00655
00656 FmtAssert(dest_mtype == MTYPE_B, ("unexpected LAND"));
00657 Build_OP (TOP_and_pred, dest, src1, src2, ops);
00658 }
00659 else {
00660
00661 TOP opc = (TOP) (TOP_and_b8 + Mtype_Byte_Index(src_mtype));
00662 if (dest_mtype == MTYPE_B) {
00663
00664 TN *tmp = Build_TN_Like(src1);
00665 Build_OP (opc, tmp, src1, src2, ops);
00666
00667 opc = (TOP) (TOP_setp_ne_s8 + Mtype_Index(src_mtype));
00668 TN *zero_tn = Expand_Mtype_Immediate_Into_Register (
00669 Gen_Literal_TN(0,4), MTYPE_I4, ops);
00670 Build_OP (opc, dest, tmp, zero_tn, ops);
00671 }
00672 else {
00673 Build_OP (opc, dest, src1, src2, ops);
00674 }
00675 }
00676 }
00677
00678 void Expand_Logical_Or (TN *dest, TN *src1, TN *src2, VARIANT variant, OPS *ops)
00679 {
00680 TYPE_ID dest_mtype = Mtype_Of_TN(dest);
00681 TYPE_ID src_mtype = Mtype_Of_TN(src1);
00682 if ( ! V_normalized_op1(variant)) {
00683 src1 = Normalize_Operand (src1, src_mtype, ops);
00684 }
00685 if ( ! V_normalized_op2(variant)) {
00686 src2 = Normalize_Operand (src2, src_mtype, ops);
00687 }
00688 if (src_mtype == MTYPE_B) {
00689
00690
00691 FmtAssert(dest_mtype == MTYPE_B, ("unexpected LOR"));
00692 Build_OP (TOP_or_pred, dest, src1, src2, ops);
00693 }
00694 else {
00695
00696 TOP opc = (TOP) (TOP_or_b8 + Mtype_Byte_Index(src_mtype));
00697 if (dest_mtype == MTYPE_B) {
00698
00699 TN *tmp = Build_TN_Like(src1);
00700 Build_OP (opc, tmp, src1, src2, ops);
00701
00702 opc = (TOP) (TOP_setp_ne_s8 + Mtype_Index(src_mtype));
00703 TN *zero_tn = Expand_Mtype_Immediate_Into_Register (
00704 Gen_Literal_TN(0,4), MTYPE_I4, ops);
00705 Build_OP (opc, dest, tmp, zero_tn, ops);
00706 }
00707 else {
00708 Build_OP (opc, dest, src1, src2, ops);
00709 }
00710 }
00711 }
00712
00713
00714 void Expand_Binary_Complement (TN *dest, TN *src, TYPE_ID mtype, OPS *ops)
00715 {
00716 TOP opc = (TOP) (TOP_not_b8 + Mtype_Byte_Index(mtype));
00717 if (TN_is_constant(src)) {
00718 FmtAssert(TN_has_value(src), ("NYI"));
00719
00720 src = Expand_Mtype_Immediate_Into_Register (src, mtype, ops);
00721 }
00722 else if (TN_is_boolean(src)) {
00723 Set_TN_is_boolean(dest);
00724 }
00725 Build_OP (opc, dest, src, ops);
00726 }
00727
00728 void Expand_Binary_And (TN *dest, TN *src1, TN *src2, TYPE_ID mtype, OPS *ops)
00729 {
00730 TOP opc = (TOP) (TOP_and_b8 + Mtype_Byte_Index(mtype));
00731 INT64 val;
00732
00733 if (TN_Can_Use_Constant_Value (src1, mtype, &val)) {
00734 opc = (TOP) (TOP_and_b8_lit + Mtype_Byte_Index(mtype));
00735 src1 = src2;
00736 src2 = Gen_Literal_TN_Of_Mtype (val, mtype);
00737 } else if (TN_Can_Use_Constant_Value (src2, mtype, &val)) {
00738 opc = (TOP) (TOP_and_b8_lit + Mtype_Byte_Index(mtype));
00739 src2 = Gen_Literal_TN_Of_Mtype (val, mtype);
00740
00741 if (val == 1) {
00742 Set_TN_is_boolean(dest);
00743 }
00744 }
00745 else if (TN_is_constant(src1)) {
00746
00747 src1 = Expand_Mtype_Immediate_Into_Register (src1, mtype, ops);
00748 }
00749 else if (TN_is_constant(src2)) {
00750
00751 src2 = Expand_Mtype_Immediate_Into_Register (src2, mtype, ops);
00752 }
00753 else if (TN_is_boolean(src1) && TN_is_boolean(src2)) {
00754 Set_TN_is_boolean(dest);
00755 }
00756 Build_OP (opc, dest, src1, src2, ops);
00757 }
00758
00759 void Expand_Binary_Or (TN *dest, TN *src1, TN *src2, TYPE_ID mtype, OPS *ops)
00760 {
00761 TOP opc = (TOP) (TOP_or_b8 + Mtype_Byte_Index(mtype));
00762 INT64 val;
00763
00764 if (TN_Can_Use_Constant_Value (src1, mtype, &val)) {
00765 opc = (TOP) (TOP_or_b8_lit + Mtype_Byte_Index(mtype));
00766 src1 = src2;
00767 src2 = Gen_Literal_TN_Of_Mtype (val, mtype);
00768 } else if (TN_Can_Use_Constant_Value (src2, mtype, &val)) {
00769 opc = (TOP) (TOP_or_b8_lit + Mtype_Byte_Index(mtype));
00770 src2 = Gen_Literal_TN_Of_Mtype (val, mtype);
00771 }
00772 else if (TN_is_constant(src1)) {
00773
00774 src1 = Expand_Mtype_Immediate_Into_Register (src1, mtype, ops);
00775 }
00776 else if (TN_is_constant(src2)) {
00777
00778 src2 = Expand_Mtype_Immediate_Into_Register (src2, mtype, ops);
00779 }
00780 else if (TN_is_boolean(src1) && TN_is_boolean(src2)) {
00781 Set_TN_is_boolean(dest);
00782 }
00783 Build_OP (opc, dest, src1, src2, ops);
00784 }
00785
00786 void Expand_Binary_Xor (TN *dest, TN *src1, TN *src2, TYPE_ID mtype, OPS *ops)
00787 {
00788 TOP opc = (TOP) (TOP_xor_b8 + Mtype_Byte_Index(mtype));
00789 INT64 val;
00790 if (TN_Can_Use_Constant_Value (src1, mtype, &val)) {
00791 opc = (TOP) (TOP_xor_b8_lit + Mtype_Byte_Index(mtype));
00792 src1 = src2;
00793 src2 = Gen_Literal_TN_Of_Mtype (val, mtype);
00794 }
00795 else if (TN_Can_Use_Constant_Value (src2, mtype, &val)) {
00796 opc = (TOP) (TOP_xor_b8_lit + Mtype_Byte_Index(mtype));
00797 src2 = Gen_Literal_TN_Of_Mtype (val, mtype);
00798 }
00799 else if (TN_is_constant(src1)) {
00800
00801 src1 = Expand_Mtype_Immediate_Into_Register (src1, mtype, ops);
00802 }
00803 else if (TN_is_constant(src2)) {
00804
00805 src2 = Expand_Mtype_Immediate_Into_Register (src2, mtype, ops);
00806 }
00807 else if (TN_is_boolean(src1) && TN_is_boolean(src2)) {
00808 Set_TN_is_boolean(dest);
00809 }
00810 Build_OP (opc, dest, src1, src2, ops);
00811 }
00812
00813 void Expand_Binary_Nor (TN *dest, TN *src1, TN *src2, TYPE_ID mtype, OPS *ops)
00814 {
00815 TN *tmp = Build_TN_Like(dest);
00816 Expand_Binary_Or (tmp, src1, src2, mtype, ops);
00817 Expand_Binary_Complement (dest, tmp, mtype, ops);
00818 }
00819
00820
00821 void Expand_Less (TN *dest, TN *src1, TN *src2, VARIANT v, TYPE_ID rtype, TYPE_ID mtype, OPS *ops)
00822 {
00823 TOP opc;
00824 FmtAssert(!TN_is_constant(src1), ("NYI"));
00825 if (TN_is_constant(src2)) {
00826 FmtAssert(TN_has_value(src2), ("NYI"));
00827
00828 src2 = Expand_Mtype_Immediate_Into_Register (src2, mtype, ops);
00829 }
00830
00831 if (rtype == MTYPE_B) {
00832
00833 opc = (TOP) (TOP_setp_lt_s8 + Mtype_Index(mtype));
00834 Build_OP (opc, dest, src1, src2, ops);
00835 }
00836 else {
00837 opc = (TOP) (TOP_set_lt_u32_s8 + Mtype_Index(mtype));
00838 if ( ! V_normalized_op1(v)) {
00839
00840 TN *tmp = Build_TN_Like(dest);
00841 Build_OP (opc, tmp, src1, src2, ops);
00842 Expand_Neg (dest, tmp, MTYPE_I4, ops);
00843 Set_TN_is_boolean(dest);
00844 }
00845 else {
00846 Build_OP (opc, dest, src1, src2, ops);
00847 }
00848 }
00849 }
00850
00851 void Expand_Less_Equal (TN *dest, TN *src1, TN *src2, VARIANT v, TYPE_ID rtype, TYPE_ID mtype, OPS *ops)
00852 {
00853 TOP opc;
00854 FmtAssert(!TN_is_constant(src1), ("NYI"));
00855 if (TN_is_constant(src2)) {
00856 FmtAssert(TN_has_value(src2), ("NYI"));
00857
00858 src2 = Expand_Mtype_Immediate_Into_Register (src2, mtype, ops);
00859 }
00860
00861 if (rtype == MTYPE_B) {
00862
00863 opc = (TOP) (TOP_setp_le_s8 + Mtype_Index(mtype));
00864 Build_OP (opc, dest, src1, src2, ops);
00865 }
00866 else {
00867 opc = (TOP) (TOP_set_le_u32_s8 + Mtype_Index(mtype));
00868 if ( ! V_normalized_op1(v)) {
00869
00870 TN *tmp = Build_TN_Like(dest);
00871 Build_OP (opc, tmp, src1, src2, ops);
00872 Expand_Neg (dest, tmp, MTYPE_I4, ops);
00873 Set_TN_is_boolean(dest);
00874 }
00875 else {
00876 Build_OP (opc, dest, src1, src2, ops);
00877 }
00878 }
00879 }
00880
00881 void Expand_Equal (TN *dest, TN *src1, TN *src2, VARIANT v, TYPE_ID rtype, TYPE_ID mtype, OPS *ops)
00882 {
00883 TOP opc;
00884 FmtAssert(!TN_is_constant(src1), ("NYI"));
00885 if (TN_is_constant(src2)) {
00886 FmtAssert(TN_has_value(src2), ("NYI"));
00887
00888 src2 = Expand_Mtype_Immediate_Into_Register (src2, mtype, ops);
00889 }
00890
00891 if (rtype == MTYPE_B) {
00892
00893 opc = (TOP) (TOP_setp_eq_s8 + Mtype_Index(mtype));
00894 Build_OP (opc, dest, src1, src2, ops);
00895 }
00896 else {
00897 opc = (TOP) (TOP_set_eq_u32_s8 + Mtype_Index(mtype));
00898 if ( ! V_normalized_op1(v)) {
00899
00900 TN *tmp = Build_TN_Like(dest);
00901 Build_OP (opc, tmp, src1, src2, ops);
00902 Expand_Neg (dest, tmp, MTYPE_I4, ops);
00903 Set_TN_is_boolean(dest);
00904 }
00905 else {
00906 Build_OP (opc, dest, src1, src2, ops);
00907 }
00908 }
00909 }
00910
00911 void Expand_Not_Equal (TN *dest, TN *src1, TN *src2, VARIANT v, TYPE_ID rtype, TYPE_ID mtype, OPS *ops)
00912 {
00913 TOP opc;
00914 FmtAssert(!TN_is_constant(src1), ("NYI"));
00915 if (TN_is_constant(src2)) {
00916 FmtAssert(TN_has_value(src2), ("NYI"));
00917
00918 src2 = Expand_Mtype_Immediate_Into_Register (src2, mtype, ops);
00919 }
00920
00921 if (rtype == MTYPE_B) {
00922
00923 opc = (TOP) (TOP_setp_ne_s8 + Mtype_Index(mtype));
00924 Build_OP (opc, dest, src1, src2, ops);
00925 }
00926 else {
00927 opc = (TOP) (TOP_set_ne_u32_s8 + Mtype_Index(mtype));
00928
00929 if (rtype == MTYPE_F4)
00930 opc = TOP_set_neu_u32_f32;
00931 else if (rtype == MTYPE_F8)
00932 opc = TOP_set_neu_u32_f64;
00933 if ( ! V_normalized_op1(v)) {
00934
00935 TN *tmp = Build_TN_Like(dest);
00936 Build_OP (opc, tmp, src1, src2, ops);
00937 Expand_Neg (dest, tmp, MTYPE_I4, ops);
00938 Set_TN_is_boolean(dest);
00939 }
00940 else {
00941 Build_OP (opc, dest, src1, src2, ops);
00942 }
00943 }
00944 }
00945
00946 void Expand_Greater_Equal (TN *dest, TN *src1, TN *src2, VARIANT v, TYPE_ID rtype, TYPE_ID mtype, OPS *ops)
00947 {
00948 TOP opc;
00949 FmtAssert(!TN_is_constant(src1), ("NYI"));
00950 if (TN_is_constant(src2)) {
00951 FmtAssert(TN_has_value(src2), ("NYI"));
00952
00953 src2 = Expand_Mtype_Immediate_Into_Register (src2, mtype, ops);
00954 }
00955
00956 if (rtype == MTYPE_B) {
00957
00958 opc = (TOP) (TOP_setp_ge_s8 + Mtype_Index(mtype));
00959 Build_OP (opc, dest, src1, src2, ops);
00960 }
00961 else {
00962 opc = (TOP) (TOP_set_ge_u32_s8 + Mtype_Index(mtype));
00963 if ( ! V_normalized_op1(v)) {
00964
00965 TN *tmp = Build_TN_Like(dest);
00966 Build_OP (opc, tmp, src1, src2, ops);
00967 Expand_Neg (dest, tmp, MTYPE_I4, ops);
00968 Set_TN_is_boolean(dest);
00969 }
00970 else {
00971 Build_OP (opc, dest, src1, src2, ops);
00972 }
00973 }
00974 }
00975
00976 void Expand_Greater (TN *dest, TN *src1, TN *src2, VARIANT v, TYPE_ID rtype, TYPE_ID mtype, OPS *ops)
00977 {
00978 TOP opc;
00979 FmtAssert(!TN_is_constant(src1), ("NYI"));
00980 if (TN_is_constant(src2)) {
00981 FmtAssert(TN_has_value(src2), ("NYI"));
00982
00983 src2 = Expand_Mtype_Immediate_Into_Register (src2, mtype, ops);
00984 }
00985
00986 if (rtype == MTYPE_B) {
00987
00988 opc = (TOP) (TOP_setp_gt_s8 + Mtype_Index(mtype));
00989 Build_OP (opc, dest, src1, src2, ops);
00990 }
00991 else {
00992 opc = (TOP) (TOP_set_gt_u32_s8 + Mtype_Index(mtype));
00993 if ( ! V_normalized_op1(v)) {
00994
00995 TN *tmp = Build_TN_Like(dest);
00996 Build_OP (opc, tmp, src1, src2, ops);
00997 Expand_Neg (dest, tmp, MTYPE_I4, ops);
00998 Set_TN_is_boolean(dest);
00999 }
01000 else {
01001 Build_OP (opc, dest, src1, src2, ops);
01002 }
01003 }
01004 }
01005
01006 void
01007 Expand_Bool_To_Int (TN *dest, TN *src, VARIANT v, TYPE_ID rtype, OPS *ops)
01008 {
01009
01010 #if 0
01011
01012
01013 TOP opc = TOP_set_cmpb_u32_u32_lit;
01014 TN *zero_tn = Gen_Literal_TN_Of_Mtype(0, rtype);
01015 Build_OP (opc, dest, Gen_Enum_TN(ECV_cmp_eq), Gen_Enum_TN(ECV_boolop_or),
01016 zero_tn, zero_tn, src, ops);
01017 #else
01018
01019 TOP opc = (TOP) (TOP_selp_s8_lit + Mtype_Index(rtype));
01020 TN *true_tn = Gen_Literal_TN_Of_Mtype(1,rtype);
01021 TN *false_tn = Gen_Literal_TN_Of_Mtype(0,rtype);
01022 if (v == V_BR_FALSE) {
01023
01024 Build_OP (opc, dest, false_tn, true_tn, src, ops);
01025 } else {
01026 Build_OP (opc, dest, true_tn, false_tn, src, ops);
01027 }
01028
01029 Set_TN_is_boolean(dest);
01030 #endif
01031 }
01032
01033 void
01034 Expand_Float_To_Int_Cvt (TN *dest, TN *src, TYPE_ID imtype, TYPE_ID fmtype, OPS *ops)
01035 {
01036
01037 Expand_Trunc (dest, src, imtype, fmtype, ops);
01038 }
01039
01040 void
01041 Expand_Float_To_Int_Tas (TN *dest, TN *src, TYPE_ID imtype, OPS *ops)
01042 {
01043 Is_True( Is_Target_32bit(), ("Expand_Float_To_Int_Tas should not be invoked under -m64") );
01044
01045 const TY_IDX ty = MTYPE_To_TY( imtype );
01046 ST* st = Gen_Temp_Symbol( ty, "float_2_int" );
01047 Allocate_Temp_To_Memory( st );
01048
01049 ST* base_sym = NULL;
01050 INT64 base_ofst = 0;
01051
01052 Base_Symbol_And_Offset_For_Addressing( st, 0, &base_sym, &base_ofst );
01053 FmtAssert( base_sym == SP_Sym || base_sym == FP_Sym,
01054 ("Expand_Float_To_Int_Tas: base symbol is on stack") );
01055
01056 TN* base_tn = base_sym == SP_Sym ? SP_TN : FP_TN;
01057 TN* ofst_tn = Gen_Literal_TN( base_ofst, 4 );
01058
01059 FmtAssert(FALSE, ("NYI"));
01060 }
01061
01062 void
01063 Expand_Int_To_Float_Tas (TN *dest, TN *src, TYPE_ID fmtype, OPS *ops)
01064 {
01065 Is_True( Is_Target_32bit(), ("Expand_Int_To_Float_Tas should not be invoked under -m64") );
01066
01067 const TY_IDX ty = MTYPE_To_TY( fmtype );
01068 ST* st = Gen_Temp_Symbol( ty, "int_2_float" );
01069 Allocate_Temp_To_Memory( st );
01070
01071 ST* base_sym = NULL;
01072 INT64 base_ofst = 0;
01073
01074 Base_Symbol_And_Offset_For_Addressing( st, 0, &base_sym, &base_ofst );
01075 FmtAssert( base_sym == SP_Sym || base_sym == FP_Sym,
01076 ("Expand_Float_To_Int_Tas: base symbol is on stack") );
01077
01078 TN* base_tn = base_sym == SP_Sym ? SP_TN : FP_TN;
01079 TN* ofst_tn = Gen_Literal_TN( base_ofst, 4 );
01080
01081 FmtAssert(FALSE, ("NYI"));
01082 }
01083
01084 void
01085 Expand_Floor (TN *dest, TN *src, TYPE_ID rtype, TYPE_ID desc, OPS *ops)
01086 {
01087 TOP top;
01088 if (MTYPE_is_float(rtype)) {
01089 FmtAssert(rtype == desc, ("differing mtypes"));
01090 if (rtype == MTYPE_F4)
01091 top = TOP_cvt_rmi_f32_f32;
01092 else if (rtype == MTYPE_F8)
01093 top = TOP_cvt_rmi_f64_f64;
01094 else
01095 FmtAssert(FALSE, ("unexpected mtype"));
01096 }
01097 else {
01098
01099 top = (TOP) (TOP_cvt_rmi_s8_f32
01100 + 2*Mtype_Index(rtype) + (Mtype_Index(desc) - Mtype_Index(MTYPE_F4)));
01101 }
01102 Build_OP (top, dest, src, ops);
01103 }
01104
01105
01106 void
01107 Expand_Ceil (TN *dest, TN *src, TYPE_ID rtype, TYPE_ID desc, OPS *ops)
01108 {
01109 TOP top;
01110 if (MTYPE_is_float(rtype)) {
01111 FmtAssert(rtype == desc, ("differing mtypes"));
01112 if (rtype == MTYPE_F4)
01113 top = TOP_cvt_rpi_f32_f32;
01114 else if (rtype == MTYPE_F8)
01115 top = TOP_cvt_rpi_f64_f64;
01116 else
01117 FmtAssert(FALSE, ("unexpected mtype"));
01118 }
01119 else {
01120 top = (TOP) (TOP_cvt_rpi_s8_f32
01121 + 2*Mtype_Index(rtype) + (Mtype_Index(desc) - Mtype_Index(MTYPE_F4)));
01122 }
01123 Build_OP (top, dest, src, ops);
01124 }
01125
01126 void
01127 Expand_Round (TN *dest, TN *src, TYPE_ID rtype, TYPE_ID desc, OPS *ops)
01128 {
01129 TOP top;
01130 if (MTYPE_is_float(rtype)) {
01131 FmtAssert(rtype == desc, ("differing mtypes"));
01132 if (rtype == MTYPE_F4)
01133 top = TOP_cvt_rni_f32_f32;
01134 else if (rtype == MTYPE_F8)
01135 top = TOP_cvt_rni_f64_f64;
01136 else
01137 FmtAssert(FALSE, ("unexpected mtype"));
01138 }
01139 else {
01140 top = (TOP) (TOP_cvt_rni_s8_f32
01141 + 2*Mtype_Index(rtype) + (Mtype_Index(desc) - Mtype_Index(MTYPE_F4)));
01142 }
01143 Build_OP (top, dest, src, ops);
01144 }
01145
01146 void
01147 Expand_Trunc (TN *dest, TN *src, TYPE_ID rtype, TYPE_ID desc, OPS *ops)
01148 {
01149 TOP top;
01150 if (MTYPE_is_float(rtype)) {
01151 FmtAssert(rtype == desc, ("differing mtypes"));
01152 if (rtype == MTYPE_F4)
01153 top = TOP_cvt_rzi_f32_f32;
01154 else if (rtype == MTYPE_F8)
01155 top = TOP_cvt_rzi_f64_f64;
01156 else
01157 FmtAssert(FALSE, ("unexpected mtype"));
01158 }
01159 else {
01160 if (MTYPE_size_reg(Mtype_Of_TN(dest)) == 32
01161 && MTYPE_size_reg(rtype) < 32)
01162 {
01163
01164
01165
01166
01167 INT ridx;
01168 switch (rtype) {
01169 case MTYPE_I1: ridx = 0; break;
01170 case MTYPE_I2: ridx = 1; break;
01171 case MTYPE_U1: ridx = 2; break;
01172 case MTYPE_U2: ridx = 3; break;
01173 default: FmtAssert(FALSE, ("unexpected mtype"));
01174 }
01175 top = (TOP) (TOP_cvt_rzi_s8_f32_b32
01176 + 2*ridx + Mtype_Index(desc) - Mtype_Index(MTYPE_F4));
01177 }
01178 else if (MTYPE_size_reg(Mtype_Of_TN(dest)) == 64
01179 && MTYPE_size_reg(rtype) < 64)
01180 {
01181
01182 INT ridx;
01183 switch (rtype) {
01184 case MTYPE_I1: ridx = 0; break;
01185 case MTYPE_I2: ridx = 1; break;
01186 case MTYPE_I4: ridx = 2; break;
01187 case MTYPE_U1: ridx = 3; break;
01188 case MTYPE_U2: ridx = 4; break;
01189 case MTYPE_U4: ridx = 5; break;
01190 default: FmtAssert(FALSE, ("unexpected mtype"));
01191 }
01192 top = (TOP) (TOP_cvt_rzi_s8_f32_b64
01193 + 2*ridx + Mtype_Index(desc) - Mtype_Index(MTYPE_F4));
01194 }
01195 else {
01196 top = (TOP) (TOP_cvt_rzi_s8_f32
01197 + 2*Mtype_Index(rtype) + (Mtype_Index(desc) - Mtype_Index(MTYPE_F4)));
01198 }
01199 }
01200 Build_OP (top, dest, src, ops);
01201 }
01202
01203
01204 void
01205 Expand_Float_To_Float (TN *dest, TN *src, TYPE_ID rtype, TYPE_ID dtype, OPS *ops)
01206 {
01207
01208
01209
01210 TOP top;
01211 if (rtype == MTYPE_F4 && dtype == MTYPE_F8) {
01212 top = TOP_cvt_rn_f32_f64;
01213 }
01214 else if (rtype == MTYPE_F8 && dtype == MTYPE_F4) {
01215 top = TOP_cvt_f64_f32;
01216 } else {
01217 FmtAssert(FALSE, ("unexpected case"));
01218 }
01219 Build_OP (top, dest, src, ops);
01220 }
01221
01222
01223 void
01224 Expand_Int_To_Float (TN *dest, TN *src, TYPE_ID fmtype, TYPE_ID imtype, OPS *ops)
01225 {
01226 TOP top;
01227 if (fmtype == MTYPE_F4) {
01228 top = (TOP) (TOP_cvt_rn_f32_s8 + Mtype_Index(imtype));
01229 } else if (fmtype == MTYPE_F8) {
01230 top = (TOP) (TOP_cvt_rn_f64_s8 + Mtype_Index(imtype));
01231 } else {
01232 FmtAssert(FALSE, ("unexpected case"));
01233 }
01234 Build_OP (top, dest, src, ops);
01235 }
01236
01237
01238 void
01239 Expand_Select (
01240 TN *dest_tn,
01241 TN *cond_tn,
01242 TN *true_tn,
01243 TN *false_tn,
01244 TYPE_ID mtype,
01245 VARIANT variant,
01246 OPS *ops)
01247 {
01248 if (Mtype_Of_TN(cond_tn) == MTYPE_B) {
01249 TOP opc = (TOP) (TOP_selp_s8 + Mtype_Index(mtype));
01250 Build_OP (opc, dest_tn, true_tn, false_tn, cond_tn, ops);
01251 return;
01252 }
01253
01254 TN *tmp;
01255 if (!V_normalized_op1(variant)) {
01256
01257
01258
01259 tmp = Build_TN_Like(cond_tn);
01260 Expand_Neg(tmp, cond_tn, Mtype_Of_TN(cond_tn), ops);
01261 cond_tn = tmp;
01262 }
01263
01264
01265
01266 FmtAssert( MTYPE_bit_size(Mtype_Of_TN(dest_tn)) == MTYPE_bit_size(mtype), ("select mtype doesn't match"));
01267 FmtAssert( MTYPE_bit_size(Mtype_Of_TN(true_tn)) == MTYPE_bit_size(mtype), ("select mtype doesn't match"));
01268 FmtAssert( MTYPE_bit_size(Mtype_Of_TN(false_tn)) == MTYPE_bit_size(mtype), ("select mtype doesn't match"));
01269
01270 FmtAssert( MTYPE_bit_size(Mtype_Of_TN(cond_tn)) == MTYPE_bit_size(MTYPE_I4), ("select condition must be 32bits"));
01271 FmtAssert(!TN_is_constant(cond_tn), ("select const NYI"));
01272 FmtAssert(!TN_is_constant(true_tn), ("select const NYI"));
01273 FmtAssert(!TN_is_constant(false_tn), ("select const NYI"));
01274
01275
01276
01277 TOP opc = (TOP) (TOP_slct_s8_s32 + Mtype_Index(mtype));
01278
01279 Build_OP (opc, dest_tn, false_tn, true_tn, cond_tn, ops);
01280 }
01281
01282 void
01283 Expand_Min (TN *dest, TN *src1, TN *src2, TYPE_ID mtype, OPS *ops)
01284 {
01285 TOP opc = (TOP) (TOP_min_s8 + Mtype_Index(mtype));
01286 FmtAssert(!TN_is_constant(src1), ("NYI"));
01287 if (TN_is_constant(src2)) {
01288 FmtAssert(TN_has_value(src2), ("NYI"));
01289
01290 src2 = Expand_Mtype_Immediate_Into_Register (src2, mtype, ops);
01291 }
01292 Build_OP (opc, dest, src1, src2, ops);
01293 }
01294
01295 void
01296 Expand_Max (TN *dest, TN *src1, TN *src2, TYPE_ID mtype, OPS *ops)
01297 {
01298 TOP opc = (TOP) (TOP_max_s8 + Mtype_Index(mtype));
01299 FmtAssert(!TN_is_constant(src1), ("NYI"));
01300 if (TN_is_constant(src2)) {
01301 FmtAssert(TN_has_value(src2), ("NYI"));
01302
01303 src2 = Expand_Mtype_Immediate_Into_Register (src2, mtype, ops);
01304 }
01305 Build_OP (opc, dest, src1, src2, ops);
01306 }
01307
01308 void
01309 Expand_MinMax (TN *dest_min, TN *dest_max,
01310 TN *src1, TN *src2,
01311 TYPE_ID mtype, OPS *ops)
01312 {
01313 if (TN_is_constant(src2)) {
01314 FmtAssert(TN_has_value(src2), ("NYI"));
01315
01316 src2 = Expand_Mtype_Immediate_Into_Register (src2, mtype, ops);
01317 }
01318 Expand_Min(dest_min, src1, src2, mtype, ops);
01319 Expand_Max(dest_max, src1, src2, mtype, ops);
01320 }
01321
01322
01323 extern BOOL
01324 Check_Select_Expansion (OPCODE compare)
01325 {
01326
01327
01328
01329
01330 return FALSE;
01331 }
01332
01333
01334 extern void
01335 Exp_Select_And_Condition (
01336 OPCODE select, TN *result, TN *true_tn, TN *false_tn,
01337 OPCODE compare, TN *cmp_kid1, TN *cmp_kid2, VARIANT variant, OPS *ops)
01338 {
01339 OPS new_ops = OPS_EMPTY;
01340 const TYPE_ID mtype = OPCODE_rtype(select);
01341 TN *cond = Build_TN_Of_Mtype(OPCODE_rtype(compare));
01342
01343
01344
01345
01346 VARIANT v = V_NONE;
01347 Set_V_normalized_op1(v);
01348
01349
01350 Exp_OP2v (compare, cond, cmp_kid1, cmp_kid2, v, ops);
01351
01352 if (Trace_Exp) {
01353 fprintf(TFile, "expand %s: ", OPCODE_name(select));
01354 if (result) Print_TN(result,FALSE);
01355 fprintf(TFile, " :- (");
01356 if (cond) Print_TN(cond,FALSE);
01357 fprintf(TFile, ") ? ");
01358 if (true_tn) Print_TN(true_tn,FALSE);
01359 fprintf(TFile, " : ");
01360 if (false_tn) Print_TN(false_tn,FALSE);
01361 fprintf(TFile, " ");
01362 if (variant) fprintf(TFile, "(0x%llx)", (INT64)variant);
01363 fprintf(TFile, "\n");
01364 }
01365
01366 Expand_Select (result, cond, true_tn, false_tn, mtype, v, &new_ops);
01367
01368 if( Trace_Exp ){
01369 Print_OPS( &new_ops );
01370 }
01371 OPS_Append_Ops(ops, &new_ops);
01372 }
01373
01374 void
01375 Expand_Vote (TOP opcode, TN *result, TN *src, OPS *ops) {
01376 TYPE_ID mtype = Mtype_Of_TN (src);
01377
01378
01379 if (mtype != MTYPE_B) {
01380 TN *cond = Build_TN_Of_Mtype (MTYPE_B);
01381 Expand_Not_Equal (cond, src, Gen_Literal_TN (0, 4), V_NONE, MTYPE_B, mtype, ops);
01382 src = cond;
01383 }
01384
01385
01386 mtype = Mtype_Of_TN (result);
01387 if (mtype == MTYPE_B) {
01388 Build_OP (opcode, result, src, ops);
01389 } else {
01390 TN *cond = Build_TN_Of_Mtype (MTYPE_B);
01391 Build_OP (opcode, cond, src, ops);
01392 Expand_Bool_To_Int (result, cond, V_NONE, mtype, ops);
01393 }
01394 }
01395
01396 static TN *
01397 Build_Vote (TOP opcode, TN *src, OPS *ops) {
01398 TN *result = PREG_To_TN (Int32_Preg, First_Int_Preg_Return_Offset);
01399 Expand_Vote (opcode, result, src, ops);
01400 return result;
01401 }
01402
01403 void
01404 Expand_Sqrt (TN *result, TN *src, TYPE_ID mtype, OPS *ops)
01405 {
01406 FmtAssert( MTYPE_is_float(mtype), ("Unimplemented sqrt for integer") );
01407 FmtAssert(!TN_is_constant(src), ("NYI"));
01408 if (mtype == MTYPE_F4) {
01409 Build_OP( TOP_sqrt_f32, result, src, ops);
01410 }
01411 else if (mtype == MTYPE_F8) {
01412 Build_OP( TOP_sqrt_f64, result, src, ops);
01413 }
01414 else {
01415 FmtAssert(FALSE, ("unexpected mtype"));
01416 }
01417 }
01418
01419
01420 void Expand_Flop ( OPCODE opcode, TN *result, TN *src1, TN *src2, TN *src3, OPS *ops )
01421 {
01422 FmtAssert(FALSE, ("NYI"));
01423 }
01424
01425 void Expand_Madd ( OPCODE opcode, TN *result, TN *src1, TN *src2, TN *src3, OPS *ops )
01426 {
01427 TOP top;
01428 TN *tmp;
01429 TYPE_ID mtype = OPCODE_rtype(opcode);
01430 FmtAssert(!TN_is_constant(src1), ("NYI"));
01431 FmtAssert(!TN_is_constant(src2), ("NYI"));
01432 FmtAssert(!TN_is_constant(src3), ("NYI"));
01433 if (MTYPE_is_float(mtype))
01434 top = (mtype == MTYPE_F4) ? TOP_mad_f32 : TOP_mad_f64;
01435 else
01436 top = (TOP) (TOP_mad_lo_s8 + Mtype_Index(mtype));
01437
01438
01439 if (TN_has_memory_space(src1))
01440 Set_TN_memory_space (result, TN_memory_space(src1));
01441
01442 switch (OPCODE_operator(opcode)) {
01443
01444
01445 case OPR_MADD:
01446 Build_OP( top, result, src2, src3, src1, ops);
01447 break;
01448 case OPR_NMADD:
01449 tmp = Build_TN_Like(result);
01450 Build_OP( top, tmp, src2, src3, src1, ops);
01451 Expand_Neg (result, tmp, mtype, ops);
01452 break;
01453 case OPR_MSUB:
01454
01455
01456 tmp = Build_TN_Like(src2);
01457 Expand_Multiply (tmp, src2, src3, mtype, ops);
01458 Expand_Sub (result, tmp, src1, mtype, ops);
01459 break;
01460 case OPR_NMSUB:
01461 tmp = Build_TN_Like(src2);
01462 Expand_Multiply (tmp, src2, src3, mtype, ops);
01463 Expand_Sub (result, src1, tmp, mtype, ops);
01464 break;
01465 default:
01466 #pragma mips_frequency_hint NEVER
01467 FmtAssert(FALSE, ("Unimplemented madd: %s", OPCODE_name(opcode)));
01468 }
01469 }
01470
01471 void Expand_Recip (TN *result, TN *src1, TYPE_ID mtype, OPS *ops)
01472 {
01473 TOP top = (mtype == MTYPE_F4) ? TOP_rcp_f32 : TOP_rcp_f64;
01474 FmtAssert(!TN_is_constant(src1), ("NYI"));
01475 Build_OP( top, result, src1, ops);
01476 }
01477
01478 void Expand_Recip_Sqrt (TN *result, TN *src1, TYPE_ID mtype, OPS *ops)
01479 {
01480 TOP top = (mtype == MTYPE_F4) ? TOP_rsqrt_f32 : TOP_rsqrt_f64;
01481 FmtAssert(!TN_is_constant(src1), ("NYI"));
01482 Build_OP( top, result, src1, ops);
01483 }
01484
01485 extern void
01486 Init_CG_Expand (void)
01487 {
01488 static BOOL Initialized = FALSE;
01489
01490
01491 Trace_Exp = Get_Trace (TP_CGEXP, 1);
01492
01493 Trace_Exp2 = Get_Trace (TP_CGEXP, 4);
01494 Disable_Const_Mult_Opt = Get_Trace (TP_CGEXP, 32);
01495 Exp_Ldst_Init();
01496
01497 if (Initialized) return;
01498 Initialized = TRUE;
01499
01500 Initialize_Branch_Variants();
01501 }
01502
01503
01504
01505
01506
01507
01508
01509
01510 void
01511 Exp_COPY_Ext (TOP opcode, TN *tgt_tn, TN *src_tn, OPS *ops)
01512 {
01513 TOP new_op;
01514 FmtAssert(FALSE, ("NYI"));
01515 }
01516
01517
01518
01519
01520
01521
01522 void
01523 Exp_COPY (TN *tgt_tn, TN *src_tn, OPS *ops)
01524 {
01525 OPS newops = OPS_EMPTY;
01526
01527
01528 TYPE_ID mtype;
01529 if (TN_size(src_tn) != TN_size(tgt_tn)) {
01530
01531 Expand_Convert (tgt_tn, Mtype_Of_TN(tgt_tn), src_tn, Mtype_Of_TN(src_tn), ops);
01532 }
01533 else if (TN_register_class(src_tn) != TN_register_class(tgt_tn)) {
01534
01535 TOP opc;
01536 switch (TN_register_class(tgt_tn)) {
01537 case ISA_REGISTER_CLASS_integer: opc = TOP_mov_b32_f2i; break;
01538 case ISA_REGISTER_CLASS_integer64: opc = TOP_mov_b64_f2i; break;
01539 case ISA_REGISTER_CLASS_float: opc = TOP_mov_b32_i2f; break;
01540 case ISA_REGISTER_CLASS_float64: opc = TOP_mov_b64_i2f; break;
01541 default: FmtAssert(FALSE, ("unexpected regclass"));
01542 }
01543 Build_OP (opc, tgt_tn, src_tn, &newops);
01544 Set_OP_copy (OPS_last(&newops));
01545 if (TN_has_memory_space(src_tn))
01546 Set_TN_memory_space (tgt_tn, TN_memory_space(src_tn));
01547 }
01548 else if( TN_is_constant(src_tn) ){
01549 FmtAssert (TN_has_value(src_tn), ("Exp_COPY: illegal source tn"));
01550
01551 Exp_OP1 (OPC_I4INTCONST, tgt_tn, src_tn, &newops);
01552
01553 } else {
01554 switch (TN_register_class(tgt_tn)) {
01555 case ISA_REGISTER_CLASS_integer:
01556 case ISA_REGISTER_CLASS_integer16:
01557 case ISA_REGISTER_CLASS_integer64:
01558 switch (TN_size(tgt_tn)) {
01559 case 1: mtype = MTYPE_I1; break;
01560 case 2: mtype = MTYPE_I2; break;
01561 case 4: mtype = MTYPE_I4; break;
01562 case 8: mtype = MTYPE_I8; break;
01563 default: FmtAssert(FALSE, ("unexpected size"));
01564 }
01565 Expand_Copy (tgt_tn, src_tn, mtype, &newops);
01566 break;
01567 case ISA_REGISTER_CLASS_float:
01568 case ISA_REGISTER_CLASS_float64:
01569 switch (TN_size(tgt_tn)) {
01570 case 4: mtype = MTYPE_F4; break;
01571 case 8: mtype = MTYPE_F8; break;
01572 default: FmtAssert(FALSE, ("unexpected size"));
01573 }
01574 Expand_Copy (tgt_tn, src_tn, mtype, &newops);
01575 break;
01576 case ISA_REGISTER_CLASS_predicate:
01577 Build_OP (TOP_mov_pred, tgt_tn, src_tn, &newops);
01578 Set_OP_copy (OPS_last(&newops));
01579 break;
01580 default:
01581 FmtAssert(FALSE, ("unexpected regclass"));
01582 }
01583 }
01584
01585 if (Trace_Exp2) {
01586 OP *op;
01587 FOR_ALL_OPS_OPs (&newops, op) {
01588 fprintf(TFile, "exp_copy into "); Print_OP (op);
01589 }
01590 }
01591
01592 OPS_Append_Ops(ops, &newops);
01593 }
01594
01595 void
01596 Exp_Intrinsic_Op (INTRINSIC id, TN *result, TN *op0, TN *op1, TN *op2, TYPE_ID mtype, OPS *ops)
01597 {
01598 TN *tmp;
01599 switch (id) {
01600 case INTRN_F4SIN:
01601 Build_OP (TOP_sin_f32, result, op0, op1, ops);
01602 break;
01603 case INTRN_F8SIN:
01604 Build_OP (TOP_sin_f64, result, op0, op1, ops);
01605 break;
01606 case INTRN_F4COS:
01607 Build_OP (TOP_cos_f32, result, op0, op1, ops);
01608 break;
01609 case INTRN_F8COS:
01610 Build_OP (TOP_cos_f64, result, op0, op1, ops);
01611 break;
01612 case INTRN_C_F4CEIL:
01613 Build_OP (TOP_cvt_rpi_f32_f32, result, op0, ops);
01614 break;
01615 case INTRN_C_F8CEIL:
01616 Build_OP (TOP_cvt_rpi_f64_f64, result, op0, ops);
01617 break;
01618 case INTRN_C_F4TRUNC:
01619 Build_OP (TOP_cvt_rzi_f32_f32, result, op0, ops);
01620 break;
01621 case INTRN_C_F8TRUNC:
01622 Build_OP (TOP_cvt_rzi_f64_f64, result, op0, ops);
01623 break;
01624 case INTRN_C_F4ROUND:
01625 Build_OP (TOP_cvt_rni_f32_f32, result, op0, ops);
01626 break;
01627 case INTRN_C_F8ROUND:
01628 Build_OP (TOP_cvt_rni_f64_f64, result, op0, ops);
01629 break;
01630 case INTRN_F4EXP2:
01631 Build_OP (TOP_ex2_f32, result, op0, ops);
01632 break;
01633 case INTRN_F8EXP2:
01634 Build_OP (TOP_ex2_f64, result, op0, ops);
01635 break;
01636 case INTRN_F4LOG2:
01637 Build_OP (TOP_lg2_f32, result, op0, ops);
01638 break;
01639 case INTRN_F8LOG2:
01640 Build_OP (TOP_lg2_f64, result, op0, ops);
01641 break;
01642 case INTRN_F4SATURATE:
01643 Build_OP (TOP_cvt_sat_f32_f32, result, op0, ops);
01644 break;
01645 case INTRN_F8SATURATE:
01646 Build_OP (TOP_cvt_sat_f64_f64, result, op0, ops);
01647 break;
01648 case INTRN_MUL24:
01649 Build_OP (TOP_mul24_lo_s32, result, op0, op1, ops);
01650 break;
01651 case INTRN_UMUL24:
01652 Build_OP (TOP_mul24_lo_u32, result, op0, op1, ops);
01653 break;
01654 case INTRN_F4MA:
01655 Build_OP (TOP_mad_f32, result, op0, op1, op2, ops);
01656 break;
01657 case INTRN_F8MA_ROUND:
01658 Build_OP (TOP_mad_rn_f64, result, op0, op1, op2, ops);
01659 break;
01660 case INTRN_F8MA_TRUNC:
01661 Build_OP (TOP_mad_rz_f64, result, op0, op1, op2, ops);
01662 break;
01663 case INTRN_F8MA_FLOOR:
01664 Build_OP (TOP_mad_rm_f64, result, op0, op1, op2, ops);
01665 break;
01666 case INTRN_F8MA_CEIL:
01667 Build_OP (TOP_mad_rp_f64, result, op0, op1, op2, ops);
01668 break;
01669 case INTRN_F4ADD_ROUND:
01670 Build_OP (TOP_add_rn_f32, result, op0, op1, ops);
01671 break;
01672 case INTRN_F4ADD_TRUNC:
01673 Build_OP (TOP_add_rz_f32, result, op0, op1, ops);
01674 break;
01675 case INTRN_F8ADD_ROUND:
01676 Build_OP (TOP_add_rn_f64, result, op0, op1, ops);
01677 break;
01678 case INTRN_F8ADD_TRUNC:
01679 Build_OP (TOP_add_rz_f64, result, op0, op1, ops);
01680 break;
01681 case INTRN_F8ADD_FLOOR:
01682 Build_OP (TOP_add_rm_f64, result, op0, op1, ops);
01683 break;
01684 case INTRN_F8ADD_CEIL:
01685 Build_OP (TOP_add_rp_f64, result, op0, op1, ops);
01686 break;
01687 case INTRN_F4MUL_ROUND:
01688 Build_OP (TOP_mul_rn_f32, result, op0, op1, ops);
01689 break;
01690 case INTRN_F4MUL_TRUNC:
01691 Build_OP (TOP_mul_rz_f32, result, op0, op1, ops);
01692 break;
01693 case INTRN_F8MUL_ROUND:
01694 Build_OP (TOP_mul_rn_f64, result, op0, op1, ops);
01695 break;
01696 case INTRN_F8MUL_TRUNC:
01697 Build_OP (TOP_mul_rz_f64, result, op0, op1, ops);
01698 break;
01699 case INTRN_F8MUL_FLOOR:
01700 Build_OP (TOP_mul_rm_f64, result, op0, op1, ops);
01701 break;
01702 case INTRN_F8MUL_CEIL:
01703 Build_OP (TOP_mul_rp_f64, result, op0, op1, ops);
01704 break;
01705 case INTRN_I4SAD:
01706 Build_OP (TOP_sad_s32, result, op0, op1, op2, ops);
01707 break;
01708 case INTRN_U4SAD:
01709 Build_OP (TOP_sad_u32, result, op0, op1, op2, ops);
01710 break;
01711 case INTRN_F4F8CVT_ROUND:
01712 Build_OP (TOP_cvt_rn_f32_f64, result, op0, ops);
01713 break;
01714 case INTRN_F4F8CVT_TRUNC:
01715 Build_OP (TOP_cvt_rz_f32_f64, result, op0, ops);
01716 break;
01717 case INTRN_F4F8CVT_FLOOR:
01718 Build_OP (TOP_cvt_rm_f32_f64, result, op0, ops);
01719 break;
01720 case INTRN_F4F8CVT_CEIL:
01721 Build_OP (TOP_cvt_rp_f32_f64, result, op0, ops);
01722 break;
01723 case INTRN_I4F8CVT_ROUND:
01724 Build_OP (TOP_cvt_rni_s32_f64, result, op0, ops);
01725 break;
01726 case INTRN_I4F8CVT_TRUNC:
01727 Build_OP (TOP_cvt_rzi_s32_f64, result, op0, ops);
01728 break;
01729 case INTRN_I4F8CVT_FLOOR:
01730 Build_OP (TOP_cvt_rmi_s32_f64, result, op0, ops);
01731 break;
01732 case INTRN_I4F8CVT_CEIL:
01733 Build_OP (TOP_cvt_rpi_s32_f64, result, op0, ops);
01734 break;
01735 case INTRN_U4F8CVT_ROUND:
01736 Build_OP (TOP_cvt_rni_u32_f64, result, op0, ops);
01737 break;
01738 case INTRN_U4F8CVT_TRUNC:
01739 Build_OP (TOP_cvt_rzi_u32_f64, result, op0, ops);
01740 break;
01741 case INTRN_U4F8CVT_FLOOR:
01742 Build_OP (TOP_cvt_rmi_u32_f64, result, op0, ops);
01743 break;
01744 case INTRN_U4F8CVT_CEIL:
01745 Build_OP (TOP_cvt_rpi_u32_f64, result, op0, ops);
01746 break;
01747 case INTRN_F8I4CVT_ROUND:
01748 Build_OP (TOP_cvt_rn_f64_s32, result, op0, ops);
01749 break;
01750 case INTRN_F8I4CVT_TRUNC:
01751 Build_OP (TOP_cvt_rz_f64_s32, result, op0, ops);
01752 break;
01753 case INTRN_F8I4CVT_FLOOR:
01754 Build_OP (TOP_cvt_rm_f64_s32, result, op0, ops);
01755 break;
01756 case INTRN_F8I4CVT_CEIL:
01757 Build_OP (TOP_cvt_rp_f64_s32, result, op0, ops);
01758 break;
01759 case INTRN_F8U4CVT_ROUND:
01760 Build_OP (TOP_cvt_rn_f64_u32, result, op0, ops);
01761 break;
01762 case INTRN_F8U4CVT_TRUNC:
01763 Build_OP (TOP_cvt_rz_f64_u32, result, op0, ops);
01764 break;
01765 case INTRN_F8U4CVT_FLOOR:
01766 Build_OP (TOP_cvt_rm_f64_u32, result, op0, ops);
01767 break;
01768 case INTRN_F8U4CVT_CEIL:
01769 Build_OP (TOP_cvt_rp_f64_u32, result, op0, ops);
01770 break;
01771 case INTRN_F4I4CVT_ROUND:
01772 Build_OP (TOP_cvt_rn_f32_s32, result, op0, ops);
01773 break;
01774 case INTRN_F4I4CVT_TRUNC:
01775 Build_OP (TOP_cvt_rz_f32_s32, result, op0, ops);
01776 break;
01777 case INTRN_F4I4CVT_FLOOR:
01778 Build_OP (TOP_cvt_rm_f32_s32, result, op0, ops);
01779 break;
01780 case INTRN_F4I4CVT_CEIL:
01781 Build_OP (TOP_cvt_rp_f32_s32, result, op0, ops);
01782 break;
01783 case INTRN_F4U4CVT_ROUND:
01784 Build_OP (TOP_cvt_rn_f32_u32, result, op0, ops);
01785 break;
01786 case INTRN_F4U4CVT_TRUNC:
01787 Build_OP (TOP_cvt_rz_f32_u32, result, op0, ops);
01788 break;
01789 case INTRN_F4U4CVT_FLOOR:
01790 Build_OP (TOP_cvt_rm_f32_u32, result, op0, ops);
01791 break;
01792 case INTRN_F4U4CVT_CEIL:
01793 Build_OP (TOP_cvt_rp_f32_u32, result, op0, ops);
01794 break;
01795 case INTRN_I4F4CVT_ROUND:
01796 Build_OP (TOP_cvt_rni_s32_f32, result, op0, ops);
01797 break;
01798 case INTRN_I4F4CVT_TRUNC:
01799 Build_OP (TOP_cvt_rzi_s32_f32, result, op0, ops);
01800 break;
01801 case INTRN_I4F4CVT_FLOOR:
01802 Build_OP (TOP_cvt_rmi_s32_f32, result, op0, ops);
01803 break;
01804 case INTRN_I4F4CVT_CEIL:
01805 Build_OP (TOP_cvt_rpi_s32_f32, result, op0, ops);
01806 break;
01807 case INTRN_U4F4CVT_ROUND:
01808 Build_OP (TOP_cvt_rni_u32_f32, result, op0, ops);
01809 break;
01810 case INTRN_U4F4CVT_TRUNC:
01811 Build_OP (TOP_cvt_rzi_u32_f32, result, op0, ops);
01812 break;
01813 case INTRN_U4F4CVT_FLOOR:
01814 Build_OP (TOP_cvt_rmi_u32_f32, result, op0, ops);
01815 break;
01816 case INTRN_U4F4CVT_CEIL:
01817 Build_OP (TOP_cvt_rpi_u32_f32, result, op0, ops);
01818 break;
01819 case INTRN_F4I8CVT_ROUND:
01820 Build_OP (TOP_cvt_rn_f32_s64, result, op0, ops);
01821 break;
01822 case INTRN_F4I8CVT_TRUNC:
01823 Build_OP (TOP_cvt_rz_f32_s64, result, op0, ops);
01824 break;
01825 case INTRN_F4I8CVT_FLOOR:
01826 Build_OP (TOP_cvt_rm_f32_s64, result, op0, ops);
01827 break;
01828 case INTRN_F4I8CVT_CEIL:
01829 Build_OP (TOP_cvt_rp_f32_s64, result, op0, ops);
01830 break;
01831 case INTRN_F4U8CVT_ROUND:
01832 Build_OP (TOP_cvt_rn_f32_u64, result, op0, ops);
01833 break;
01834 case INTRN_F4U8CVT_TRUNC:
01835 Build_OP (TOP_cvt_rz_f32_u64, result, op0, ops);
01836 break;
01837 case INTRN_F4U8CVT_FLOOR:
01838 Build_OP (TOP_cvt_rm_f32_u64, result, op0, ops);
01839 break;
01840 case INTRN_F4U8CVT_CEIL:
01841 Build_OP (TOP_cvt_rp_f32_u64, result, op0, ops);
01842 break;
01843 case INTRN_F8I8CVT_ROUND:
01844 Build_OP (TOP_cvt_rn_f64_s64, result, op0, ops);
01845 break;
01846 case INTRN_F8I8CVT_TRUNC:
01847 Build_OP (TOP_cvt_rz_f64_s64, result, op0, ops);
01848 break;
01849 case INTRN_F8I8CVT_FLOOR:
01850 Build_OP (TOP_cvt_rm_f64_s64, result, op0, ops);
01851 break;
01852 case INTRN_F8I8CVT_CEIL:
01853 Build_OP (TOP_cvt_rp_f64_s64, result, op0, ops);
01854 break;
01855 case INTRN_F8U8CVT_ROUND:
01856 Build_OP (TOP_cvt_rn_f64_u64, result, op0, ops);
01857 break;
01858 case INTRN_F8U8CVT_TRUNC:
01859 Build_OP (TOP_cvt_rz_f64_u64, result, op0, ops);
01860 break;
01861 case INTRN_F8U8CVT_FLOOR:
01862 Build_OP (TOP_cvt_rm_f64_u64, result, op0, ops);
01863 break;
01864 case INTRN_F8U8CVT_CEIL:
01865 Build_OP (TOP_cvt_rp_f64_u64, result, op0, ops);
01866 break;
01867 case INTRN_I8F4CVT_ROUND:
01868 Build_OP (TOP_cvt_rni_s64_f32, result, op0, ops);
01869 break;
01870 case INTRN_I8F4CVT_TRUNC:
01871 Build_OP (TOP_cvt_rzi_s64_f32, result, op0, ops);
01872 break;
01873 case INTRN_I8F4CVT_FLOOR:
01874 Build_OP (TOP_cvt_rmi_s64_f32, result, op0, ops);
01875 break;
01876 case INTRN_I8F4CVT_CEIL:
01877 Build_OP (TOP_cvt_rpi_s64_f32, result, op0, ops);
01878 break;
01879 case INTRN_U8F4CVT_ROUND:
01880 Build_OP (TOP_cvt_rni_u64_f32, result, op0, ops);
01881 break;
01882 case INTRN_U8F4CVT_TRUNC:
01883 Build_OP (TOP_cvt_rzi_u64_f32, result, op0, ops);
01884 break;
01885 case INTRN_U8F4CVT_FLOOR:
01886 Build_OP (TOP_cvt_rmi_u64_f32, result, op0, ops);
01887 break;
01888 case INTRN_U8F4CVT_CEIL:
01889 Build_OP (TOP_cvt_rpi_u64_f32, result, op0, ops);
01890 break;
01891 case INTRN_I8F8CVT_ROUND:
01892 Build_OP (TOP_cvt_rni_s64_f64, result, op0, ops);
01893 break;
01894 case INTRN_I8F8CVT_TRUNC:
01895 Build_OP (TOP_cvt_rzi_s64_f64, result, op0, ops);
01896 break;
01897 case INTRN_I8F8CVT_FLOOR:
01898 Build_OP (TOP_cvt_rmi_s64_f64, result, op0, ops);
01899 break;
01900 case INTRN_I8F8CVT_CEIL:
01901 Build_OP (TOP_cvt_rpi_s64_f64, result, op0, ops);
01902 break;
01903 case INTRN_U8F8CVT_ROUND:
01904 Build_OP (TOP_cvt_rni_u64_f64, result, op0, ops);
01905 break;
01906 case INTRN_U8F8CVT_TRUNC:
01907 Build_OP (TOP_cvt_rzi_u64_f64, result, op0, ops);
01908 break;
01909 case INTRN_U8F8CVT_FLOOR:
01910 Build_OP (TOP_cvt_rmi_u64_f64, result, op0, ops);
01911 break;
01912 case INTRN_U8F8CVT_CEIL:
01913 Build_OP (TOP_cvt_rpi_u64_f64, result, op0, ops);
01914 break;
01915 case INTRN_F8HLI2D:
01916
01917 Build_OP (TOP_mov_b64_i22f, result, op1, op0, ops);
01918 break;
01919 case INTRN_I4D2LI:
01920 tmp = Build_TN_Like(result);
01921 Build_OP (TOP_mov_b64_f2i2, result, tmp, op0, ops);
01922 break;
01923 case INTRN_I4D2HI:
01924 tmp = Build_TN_Like(result);
01925 Build_OP (TOP_mov_b64_f2i2, tmp, result, op0, ops);
01926 break;
01927 default:
01928 FmtAssert(FALSE, ("intrinsic NYI"));
01929 }
01930 return;
01931 }
01932
01933
01934
01935
01936
01937
01938
01939
01940
01941 static INT
01942 Expand_TOP_intrncall (
01943 const OP *op,
01944 OPS *ops,
01945 BOOL get_sequence_length,
01946 INT pc_value)
01947 {
01948 ErrMsg( EC_Unimplemented, "Expand_TOP_intrncall: NYI" );
01949 return 0;
01950 }
01951
01952
01953
01954
01955
01956
01957
01958 TN *
01959 Exp_Intrinsic_Call (INTRINSIC id, TN *op0, TN *op1, TN *op2,
01960 OPS *ops, LABEL_IDX *label, OPS *loop_ops)
01961 {
01962
01963
01964 TN *call_iresult, *call_fresult, *call_dresult;
01965 TOP at_opc;
01966 BOOL addr_is64 = op0 != NULL && TN_size(op0) == 8;
01967
01968
01969
01970 if (op1 && TN_is_constant(op1)) {
01971 FmtAssert(TN_has_value(op1), ("NYI"));
01972
01973 op1 = Expand_Mtype_Immediate_Into_Register (op1, Mtype_Of_TN(op1), ops);
01974 }
01975 if (op2 && TN_is_constant(op2)) {
01976 FmtAssert(TN_has_value(op2), ("NYI"));
01977
01978 op2 = Expand_Mtype_Immediate_Into_Register (op2, Mtype_Of_TN(op2), ops);
01979 }
01980
01981 switch (id) {
01982 case INTRN_SYNCHRONIZE:
01983 Build_OP (TOP_bar_sync, Gen_Literal_TN(0, 4), ops);
01984 return NULL;
01985 case INTRN_BRKPT:
01986 Build_OP (TOP_brkpt, ops);
01987 return NULL;
01988 case INTRN_TRAP:
01989 Build_OP (TOP_trap, ops);
01990 return NULL;
01991 case INTRN_CLOCK:
01992 call_iresult = PREG_To_TN (Int32_Preg, First_Int_Preg_Return_Offset);
01993 Build_OP (TOP_mov_u32, call_iresult, Clock_TN(), ops);
01994 return call_iresult;
01995 case INTRN_I4ATOMICADD:
01996 if (TN_in_shared_mem(op0))
01997 at_opc = addr_is64 ? TOP_atom_shared_add_s32_a64 : TOP_atom_shared_add_s32;
01998 else
01999 at_opc = addr_is64 ? TOP_atom_global_add_s32_a64 : TOP_atom_global_add_s32;
02000 call_iresult = PREG_To_TN (Int32_Preg, First_Int_Preg_Return_Offset);
02001 Build_OP (at_opc, call_iresult, op0, op1, ops);
02002 return call_iresult;
02003 case INTRN_U4ATOMICADD:
02004 if (TN_in_shared_mem(op0))
02005 at_opc = addr_is64 ? TOP_atom_shared_add_u32_a64 : TOP_atom_shared_add_u32;
02006 else
02007 at_opc = addr_is64 ? TOP_atom_global_add_u32_a64 : TOP_atom_global_add_u32;
02008 call_iresult = PREG_To_TN (Int32_Preg, First_Int_Preg_Return_Offset);
02009 Build_OP (at_opc, call_iresult, op0, op1, ops);
02010 return call_iresult;
02011 case INTRN_U8ATOMICADD:
02012 if (TN_in_shared_mem(op0)) {
02013 ErrMsgSrcpos(EC_Shared_Atomic64_Opnd, current_srcpos);
02014 }
02015 at_opc = addr_is64 ? TOP_atom_global_add_u64_a64 : TOP_atom_global_add_u64;
02016 call_iresult = PREG_To_TN (Int64_Preg, First_Int64_Preg_Return_Offset);
02017 Build_OP (at_opc, call_iresult, op0, op1, ops);
02018 return call_iresult;
02019 case INTRN_F4ATOMICADD:
02020 if (TN_in_shared_mem(op0))
02021 at_opc = addr_is64 ? TOP_atom_shared_add_f32_a64 : TOP_atom_shared_add_f32;
02022 else
02023 at_opc = addr_is64 ? TOP_atom_global_add_f32_a64 : TOP_atom_global_add_f32;
02024 call_fresult = PREG_To_TN (Float32_Preg, First_Float_Preg_Return_Offset);
02025 Build_OP (at_opc, call_fresult, op0, op1, ops);
02026 return call_fresult;
02027 case INTRN_F8ATOMICADD:
02028 if (TN_in_shared_mem(op0)) {
02029 ErrMsgSrcpos(EC_Shared_Atomic64_Opnd, current_srcpos);
02030 }
02031 at_opc = addr_is64 ? TOP_atom_global_add_f64_a64 : TOP_atom_global_add_f64;
02032 call_dresult = PREG_To_TN (Float64_Preg, First_Float64_Preg_Return_Offset);
02033 Build_OP (at_opc, call_dresult, op0, op1, ops);
02034 return call_dresult;
02035 case INTRN_I4ATOMICMIN:
02036 if (TN_in_shared_mem(op0))
02037 at_opc = addr_is64 ? TOP_atom_shared_min_s32_a64 : TOP_atom_shared_min_s32;
02038 else
02039 at_opc = addr_is64 ? TOP_atom_global_min_s32_a64 : TOP_atom_global_min_s32;
02040 call_iresult = PREG_To_TN (Int32_Preg, First_Int_Preg_Return_Offset);
02041 Build_OP (at_opc, call_iresult, op0, op1, ops);
02042 return call_iresult;
02043 case INTRN_U4ATOMICMIN:
02044 if (TN_in_shared_mem(op0))
02045 at_opc = addr_is64 ? TOP_atom_shared_min_u32_a64 : TOP_atom_shared_min_u32;
02046 else
02047 at_opc = addr_is64 ? TOP_atom_global_min_u32_a64 : TOP_atom_global_min_u32;
02048 call_iresult = PREG_To_TN (Int32_Preg, First_Int_Preg_Return_Offset);
02049 Build_OP (at_opc, call_iresult, op0, op1, ops);
02050 return call_iresult;
02051 case INTRN_F4ATOMICMIN:
02052 if (TN_in_shared_mem(op0))
02053 at_opc = addr_is64 ? TOP_atom_shared_min_f32_a64 : TOP_atom_shared_min_f32;
02054 else
02055 at_opc = addr_is64 ? TOP_atom_global_min_f32_a64 : TOP_atom_global_min_f32;
02056 call_fresult = PREG_To_TN (Float32_Preg, First_Float_Preg_Return_Offset);
02057 Build_OP (at_opc, call_fresult, op0, op1, ops);
02058 return call_fresult;
02059 case INTRN_I4ATOMICMAX:
02060 if (TN_in_shared_mem(op0))
02061 at_opc = addr_is64 ? TOP_atom_shared_max_s32_a64 : TOP_atom_shared_max_s32;
02062 else
02063 at_opc = addr_is64 ? TOP_atom_global_max_s32_a64 : TOP_atom_global_max_s32;
02064 call_iresult = PREG_To_TN (Int32_Preg, First_Int_Preg_Return_Offset);
02065 Build_OP (at_opc, call_iresult, op0, op1, ops);
02066 return call_iresult;
02067 case INTRN_U4ATOMICMAX:
02068 if (TN_in_shared_mem(op0))
02069 at_opc = addr_is64 ? TOP_atom_shared_max_u32_a64 : TOP_atom_shared_max_u32;
02070 else
02071 at_opc = addr_is64 ? TOP_atom_global_max_u32_a64 : TOP_atom_global_max_u32;
02072 call_iresult = PREG_To_TN (Int32_Preg, First_Int_Preg_Return_Offset);
02073 Build_OP (at_opc, call_iresult, op0, op1, ops);
02074 return call_iresult;
02075 case INTRN_F4ATOMICMAX:
02076 if (TN_in_shared_mem(op0))
02077 at_opc = addr_is64 ? TOP_atom_shared_max_f32_a64 : TOP_atom_shared_max_f32;
02078 else
02079 at_opc = addr_is64 ? TOP_atom_global_max_f32_a64 : TOP_atom_global_max_f32;
02080 call_fresult = PREG_To_TN (Float32_Preg, First_Float_Preg_Return_Offset);
02081 Build_OP (at_opc, call_fresult, op0, op1, ops);
02082 return call_fresult;
02083 case INTRN_I4ATOMICEXCH:
02084 case INTRN_U4ATOMICEXCH:
02085 if (TN_in_shared_mem(op0))
02086 at_opc = addr_is64 ? TOP_atom_shared_exch_b32_a64 : TOP_atom_shared_exch_b32;
02087 else
02088 at_opc = addr_is64 ? TOP_atom_global_exch_b32_a64 : TOP_atom_global_exch_b32;
02089 call_iresult = PREG_To_TN (Int32_Preg, First_Int_Preg_Return_Offset);
02090 Build_OP (at_opc, call_iresult, op0, op1, ops);
02091 return call_iresult;
02092 case INTRN_U8ATOMICEXCH:
02093 if (TN_in_shared_mem(op0)) {
02094 ErrMsgSrcpos(EC_Shared_Atomic64_Opnd, current_srcpos);
02095 }
02096 at_opc = addr_is64 ? TOP_atom_global_exch_b64_a64 : TOP_atom_global_exch_b64;
02097 call_iresult = PREG_To_TN (Int64_Preg, First_Int64_Preg_Return_Offset);
02098 Build_OP (at_opc, call_iresult, op0, op1, ops);
02099 return call_iresult;
02100 case INTRN_F4ATOMICEXCH:
02101 if (TN_in_shared_mem(op0))
02102 at_opc = addr_is64 ? TOP_atom_shared_exch_b32_a64_f : TOP_atom_shared_exch_b32_f;
02103 else
02104 at_opc = addr_is64 ? TOP_atom_global_exch_b32_a64_f : TOP_atom_global_exch_b32_f;
02105 call_fresult = PREG_To_TN (Float32_Preg, First_Float_Preg_Return_Offset);
02106 Build_OP (at_opc, call_fresult, op0, op1, ops);
02107 return call_fresult;
02108 case INTRN_F8ATOMICEXCH:
02109 if (TN_in_shared_mem(op0)) {
02110 ErrMsgSrcpos(EC_Shared_Atomic64_Opnd, current_srcpos);
02111 }
02112 at_opc = addr_is64 ? TOP_atom_global_exch_b64_a64_f : TOP_atom_global_exch_b64_f;
02113 call_dresult = PREG_To_TN (Float64_Preg, First_Float64_Preg_Return_Offset);
02114 Build_OP (at_opc, call_dresult, op0, op1, ops);
02115 return call_dresult;
02116 case INTRN_U4ATOMICAND:
02117 if (TN_in_shared_mem(op0))
02118 at_opc = addr_is64 ? TOP_atom_shared_and_b32_a64 : TOP_atom_shared_and_b32;
02119 else
02120 at_opc = addr_is64 ? TOP_atom_global_and_b32_a64 : TOP_atom_global_and_b32;
02121 call_iresult = PREG_To_TN (Int32_Preg, First_Int_Preg_Return_Offset);
02122 Build_OP (at_opc, call_iresult, op0, op1, ops);
02123 return call_iresult;
02124 case INTRN_U4ATOMICOR:
02125 if (TN_in_shared_mem(op0))
02126 at_opc = addr_is64 ? TOP_atom_shared_or_b32_a64 : TOP_atom_shared_or_b32;
02127 else
02128 at_opc = addr_is64 ? TOP_atom_global_or_b32_a64 : TOP_atom_global_or_b32;
02129 call_iresult = PREG_To_TN (Int32_Preg, First_Int_Preg_Return_Offset);
02130 Build_OP (at_opc, call_iresult, op0, op1, ops);
02131 return call_iresult;
02132 case INTRN_U4ATOMICXOR:
02133 if (TN_in_shared_mem(op0))
02134 at_opc = addr_is64 ? TOP_atom_shared_xor_b32_a64 : TOP_atom_shared_xor_b32;
02135 else
02136 at_opc = addr_is64 ? TOP_atom_global_xor_b32_a64 : TOP_atom_global_xor_b32;
02137 call_iresult = PREG_To_TN (Int32_Preg, First_Int_Preg_Return_Offset);
02138 Build_OP (at_opc, call_iresult, op0, op1, ops);
02139 return call_iresult;
02140 case INTRN_U4ATOMICINC:
02141 if (TN_in_shared_mem(op0))
02142 at_opc = addr_is64 ? TOP_atom_shared_inc_u32_a64 : TOP_atom_shared_inc_u32;
02143 else
02144 at_opc = addr_is64 ? TOP_atom_global_inc_u32_a64 : TOP_atom_global_inc_u32;
02145 call_iresult = PREG_To_TN (Int32_Preg, First_Int_Preg_Return_Offset);
02146 Build_OP (at_opc, call_iresult, op0, op1, ops);
02147 return call_iresult;
02148 case INTRN_U4ATOMICDEC:
02149 if (TN_in_shared_mem(op0))
02150 at_opc = addr_is64 ? TOP_atom_shared_dec_u32_a64 : TOP_atom_shared_dec_u32;
02151 else
02152 at_opc = addr_is64 ? TOP_atom_global_dec_u32_a64 : TOP_atom_global_dec_u32;
02153 call_iresult = PREG_To_TN (Int32_Preg, First_Int_Preg_Return_Offset);
02154 Build_OP (at_opc, call_iresult, op0, op1, ops);
02155 return call_iresult;
02156 case INTRN_I4ATOMICCAS:
02157 case INTRN_U4ATOMICCAS:
02158 if (TN_in_shared_mem(op0))
02159 at_opc = addr_is64 ? TOP_atom_shared_cas_b32_a64 : TOP_atom_shared_cas_b32;
02160 else
02161 at_opc = addr_is64 ? TOP_atom_global_cas_b32_a64 : TOP_atom_global_cas_b32;
02162 call_iresult = PREG_To_TN (Int32_Preg, First_Int_Preg_Return_Offset);
02163 Build_OP (at_opc, call_iresult, op0, op1, op2, ops);
02164 return call_iresult;
02165 case INTRN_U8ATOMICCAS:
02166 if (TN_in_shared_mem(op0)) {
02167 ErrMsgSrcpos(EC_Shared_Atomic64_Opnd, current_srcpos);
02168 }
02169 at_opc = addr_is64 ? TOP_atom_global_cas_b64_a64 : TOP_atom_global_cas_b64;
02170 call_iresult = PREG_To_TN (Int64_Preg, First_Int64_Preg_Return_Offset);
02171 Build_OP (at_opc, call_iresult, op0, op1, op2, ops);
02172 return call_iresult;
02173 case INTRN_F4ATOMICCAS:
02174 if (TN_in_shared_mem(op0))
02175 at_opc = addr_is64 ? TOP_atom_shared_cas_b32_a64_f : TOP_atom_shared_cas_b32_f;
02176 else
02177 at_opc = addr_is64 ? TOP_atom_global_cas_b32_a64_f : TOP_atom_global_cas_b32_f;
02178 call_fresult = PREG_To_TN (Float32_Preg, First_Float_Preg_Return_Offset);
02179 Build_OP (at_opc, call_fresult, op0, op1, op2, ops);
02180 return call_fresult;
02181 case INTRN_F8ATOMICCAS:
02182 if (TN_in_shared_mem(op0)) {
02183 ErrMsgSrcpos(EC_Shared_Atomic64_Opnd, current_srcpos);
02184 }
02185 at_opc = addr_is64 ? TOP_atom_global_cas_b64_a64_f : TOP_atom_global_cas_b64_f;
02186 call_dresult = PREG_To_TN (Float64_Preg, First_Float64_Preg_Return_Offset);
02187 Build_OP (at_opc, call_dresult, op0, op1, op2, ops);
02188 return call_dresult;
02189
02190 case INTRN_VOTEALL:
02191 return Build_Vote (TOP_vote_all_pred, op0, ops);
02192 case INTRN_VOTEANY:
02193 return Build_Vote (TOP_vote_any_pred, op0, ops);
02194 case INTRN_VOTEUNI:
02195 return Build_Vote (TOP_vote_uni_pred, op0, ops);
02196 case INTRN_VOTEALL_NOT:
02197 return Build_Vote (TOP_vote_all_pred_not, op0, ops);
02198 case INTRN_VOTEANY_NOT:
02199 return Build_Vote (TOP_vote_any_pred_not, op0, ops);
02200
02201 default:
02202 FmtAssert( FALSE, ("NYI intrinsic call") );
02203 }
02204 }
02205
02206
02207
02208
02209
02210
02211
02212
02213 void Exp_Simulated_Op(const OP *op, OPS *ops, INT pc_value)
02214 {
02215 TOP top = OP_code(op);
02216 BB *bb = OP_bb(op);
02217
02218 switch (top)
02219 {
02220 default:
02221 FmtAssert(FALSE, ("simulated OP %s not handled", TOP_Name(top)));
02222 }
02223 }
02224
02225
02226
02227
02228
02229
02230
02231 INT
02232 Simulated_Op_Real_Ops(const OP *op)
02233 {
02234 switch (OP_code(op)) {
02235 case TOP_intrncall:
02236 return Expand_TOP_intrncall (op, NULL, TRUE, 0);
02237 default:
02238
02239
02240
02241
02242
02243 return 0;
02244 }
02245 }
02246
02247
02248
02249
02250
02251
02252
02253
02254 INT
02255 Simulated_Op_Real_Inst_Words(const OP *op)
02256 {
02257 TOP top = OP_code(op);
02258 switch (top)
02259 {
02260 case TOP_asm:
02261
02262
02263 return 3;
02264 case TOP_call:
02265 case TOP_call_uni:
02266 return 1;
02267
02268 default:
02269 FmtAssert(FALSE, ("simulated OP %s not handled", TOP_Name(OP_code(op))));
02270 return 0;
02271 }
02272 }
02273
02274
02275
02276
02277
02278
02279
02280
02281 BOOL
02282 Exp_Is_Large_Stack_Sym(ST* sym, INT64 ofst)
02283 {
02284 ST *base_sym;
02285 INT64 base_ofst;
02286
02287 if (sym == NULL)
02288 return FALSE;
02289
02290 Allocate_Object(sym);
02291 Base_Symbol_And_Offset_For_Addressing (sym, ofst, &base_sym, &base_ofst);
02292
02293
02294
02295
02296 return FALSE;
02297 }
02298
02299 void Exp_Noop (OPS *ops)
02300 {
02301 Build_OP (CGTARG_Noop_Top(), ops);
02302 }
02303
02304 void Expand_Const (TN *dest, TN *src, TYPE_ID mtype, OPS *ops)
02305 {
02306
02307 TOP opc = (TOP) (TOP_mov_s8_lit + Mtype_Index(mtype));
02308 FmtAssert( TN_is_symbol(src), ("Expand_Const: src not a symbol TN") );
02309 Build_OP (opc, dest, src, ops);
02310 }
02311
02312 static BB* last_bb = NULL;
02313 static TN *last_true_tn = NULL, *last_false_tn = NULL;
02314 void
02315 HB_Reinit_Pred ()
02316 {
02317 last_true_tn = NULL;
02318 last_false_tn = NULL;
02319 last_bb = NULL;
02320 }
02321
02322 void
02323 Exp_True_False_Preds_For_Block(BB *bb, TN* &true_tn, TN * &false_tn)
02324 {
02325 if (last_bb != bb)
02326 last_bb = bb;
02327 else {
02328 true_tn = last_true_tn;
02329 false_tn = last_false_tn;
02330 return;
02331 }
02332 OP* br_op = BB_branch_op(bb);
02333 if (!br_op)
02334 return;
02335
02336 FmtAssert( FALSE, ("UNIMPLEMENTED") );
02337 }
02338
02339 BOOL
02340 Target_Has_Immediate_Operand (WN *parent, WN *expr)
02341 {
02342 OPERATOR opr = WN_operator(parent);
02343 return opr == OPR_ADD || opr == OPR_SUB || opr == OPR_EQ ||
02344 opr == OPR_BAND || opr == OPR_BIOR || opr == OPR_BXOR ||
02345 opr == OPR_LT || opr == OPR_LE || opr == OPR_GT || opr == OPR_GE ||
02346 opr == OPR_LSHR || opr == OPR_ASHR || opr == OPR_SHL;
02347 }
02348
02349 void
02350 Exp_Spadjust (TN *dest, TN *size, VARIANT variant, OPS *ops)
02351 {
02352 Build_OP (TOP_spadjust, dest, SP_TN, size, ops);
02353 OP_variant(OPS_last(ops)) = variant;
02354 }
02355
02356
02357 char *
02358 Exp_Unique_Literal_Name (void)
02359 {
02360 static int unique;
02361 static char name[32];
02362
02363 sprintf(name, ".LC%d", unique);
02364 unique++;
02365 return name;
02366 }
02367
02368
02369
02370
02371
02372 void Exp_Fetch_and_Add( TN* addr, TN* opnd1, TYPE_ID mtype, OPS* ops )
02373 {
02374 TOP top = TOP_UNDEFINED;
02375
02376 FmtAssert(FALSE, ("NYI"));
02377 }
02378
02379 TN* Exp_Compare_and_Swap( TN* addr, TN* opnd1, TN* opnd2, TYPE_ID mtype, OPS* ops )
02380 {
02381 FmtAssert(FALSE, ("NYI"));
02382 return NULL;
02383 }
02384
02385
02386
02387 void Exp_Fetch_and_And( TN* addr, TN* opnd1, TYPE_ID mtype, OPS* ops )
02388 {
02389 TOP top = TOP_UNDEFINED;
02390 FmtAssert(FALSE, ("NYI"));
02391
02392 }
02393
02394
02395
02396 void Exp_Fetch_and_Or( TN* addr, TN* opnd1, TYPE_ID mtype, OPS* ops )
02397 {
02398 TOP top = TOP_UNDEFINED;
02399 FmtAssert(FALSE, ("NYI"));
02400
02401 }
02402
02403
02404
02405 void Exp_Fetch_and_Xor( TN* addr, TN* opnd1, TYPE_ID mtype, OPS* ops )
02406 {
02407 TOP top = TOP_UNDEFINED;
02408 FmtAssert(FALSE, ("NYI"));
02409 }
02410
02411
02412
02413 void Exp_Fetch_and_Sub( TN* addr, TN* opnd1, TYPE_ID mtype, OPS* ops )
02414 {
02415 TOP top = TOP_UNDEFINED;
02416 FmtAssert(FALSE, ("NYI"));
02417 }