00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026
00027
00028
00029
00030
00031
00032
00033
00034
00035
00036
00037
00038
00039
00040
00041
00042
00043
00044
00045
00046
00047
00048
00049
00050
00051
00052
00053 #include <ctype.h>
00054
00055 #include "defs.h"
00056 #include "util.h"
00057 #include "config.h"
00058 #include "config_targ_opt.h"
00059 #include "erglob.h"
00060 #include "tracing.h"
00061 #include "data_layout.h"
00062 #include "const.h"
00063 #include "wn.h"
00064 #include "import.h"
00065 #include "opt_alias_interface.h"
00066 #include "opt_alias_mgr.h"
00067 #include "cgir.h"
00068 #include "cg.h"
00069 #include "targ_sim_core.h"
00070 #include "void_list.h"
00071 #include "cg_dep_graph.h"
00072 #include "cg_spill.h"
00073 #include "cg_vector.h"
00074 #include "whirl2ops.h"
00075 #include "ti_errors.h"
00076 #include "ti_latency.h"
00077 #include "targ_isa_lits.h"
00078 #include "targ_isa_registers.h"
00079 #include "w2op.h"
00080 #include "cgexp.h"
00081 #include "cg_loop_recur.h"
00082 #include "targ_proc_properties.h"
00083 #include "targ_isa_bundle.h"
00084 #include "targ_isa_pack.h"
00085 #include "targ_isa_enums.h"
00086 #include "ti_bundle.h"
00087 #include "hb_sched.h"
00088 #include "hb_hazards.h"
00089 #include "bb.h"
00090 #include "op.h"
00091 #include "op_list.h"
00092 #include "cg_grouping.h"
00093 #include "calls.h"
00094 #include "cgtarget.h"
00095 #include "ipfec_options.h"
00096 #include "cache_analysis.h"
00097 #include "stblock.h"
00098
00099 UINT32 CGTARG_branch_taken_penalty;
00100 BOOL CGTARG_branch_taken_penalty_overridden = FALSE;
00101
00102 TOP CGTARG_Invert_Table[TOP_count+1];
00103 TOP CGTARG_Immed_To_Reg_Table[TOP_count+1];
00104
00105 OPCODE CGTARG_Assoc_Base_Opr_Table[TOP_count];
00106 mTOP CGTARG_Assoc_Base_Top_Table[TOP_count];
00107 mTOP CGTARG_Assoc_Base_Fnc_Table[TOP_count];
00108
00109 mTOP CGTARG_Inter_RegClass_Copy_Table[ISA_REGISTER_CLASS_MAX+1][ISA_REGISTER_CLASS_MAX+1][2];
00110
00111 SI_RESOURCE_ID CGTARG_f0_unit_id;
00112
00113
00114 BOOL Trace_TD = FALSE;
00115 BOOL Trace_Eager = FALSE;
00116 extern BOOL Trace_Call_Exp;
00117
00118
00119 UINT32 CGTARG_Mem_Ref_Bytes(const OP *memop)
00120
00121
00122
00123
00124
00125 {
00126 FmtAssert(OP_load(memop) || OP_store(memop), ("not a load or store"));
00127 switch (OP_code(memop)) {
00128 case TOP_ld1_r:
00129 case TOP_ld1_i:
00130 case TOP_ld1:
00131 case TOP_st1:
00132 case TOP_st1_i:
00133 return 1;
00134 case TOP_ld2_r:
00135 case TOP_ld2_i:
00136 case TOP_ld2:
00137 case TOP_st2:
00138 case TOP_st2_i:
00139 return 2;
00140 case TOP_ld4_r:
00141 case TOP_ld4_i:
00142 case TOP_ldfs_r:
00143 case TOP_ldfs_i:
00144 case TOP_ld4:
00145 case TOP_ldfs:
00146 case TOP_st4:
00147 case TOP_st4_i:
00148 case TOP_stfs:
00149 case TOP_stfs_i:
00150 return 4;
00151 case TOP_ld8_r:
00152 case TOP_ld8_i:
00153 case TOP_ldfd_r:
00154 case TOP_ldfd_i:
00155 case TOP_ldf8_r:
00156 case TOP_ldf8_i:
00157 case TOP_ldfps:
00158 case TOP_ldfps_i:
00159 case TOP_ld8_r_fill:
00160 case TOP_ld8_i_fill:
00161 case TOP_ld8:
00162 case TOP_ld8_fill:
00163 case TOP_ldfd:
00164 case TOP_ldf8:
00165 case TOP_st8:
00166 case TOP_st8_i:
00167 case TOP_st8_spill:
00168 case TOP_st8_i_spill:
00169 case TOP_stfd:
00170 case TOP_stfd_i:
00171 case TOP_stf8:
00172 case TOP_stf8_i:
00173 return 8;
00174 case TOP_ldfe_r:
00175 case TOP_ldfe_i:
00176 case TOP_ldfe:
00177 case TOP_stfe:
00178 case TOP_stfe_i:
00179 return 10;
00180 case TOP_ldf_i_fill:
00181 case TOP_ldfpd:
00182 case TOP_ldfpd_i:
00183 case TOP_ldfp8:
00184 case TOP_ldfp8_i:
00185 case TOP_ldf_fill:
00186 case TOP_stf_spill:
00187 case TOP_stf_i_spill:
00188 return 16;
00189 default:
00190 FmtAssert(FALSE, ("unrecognized op (%s) in CGTARG_Mem_Ref_Bytes",
00191 TOP_Name(OP_code(memop))));
00192 }
00193
00194 }
00195
00196
00197
00198
00199
00200
00201
00202
00203
00204 BOOL
00205 CGTARG_Is_OP_Speculative(OP *op)
00206 {
00207 if (!OP_load(op)) return FALSE;
00208
00209
00210 if (CGTARG_Is_OP_Advanced_Load(op) || CGTARG_Is_OP_Speculative_Load(op))
00211 return TRUE;
00212
00213 return FALSE;
00214 }
00215
00216
00217
00218
00219
00220
00221
00222
00223
00224 void CGTARG_Perform_THR_Code_Generation (OP *load_op, OP *chk_load,
00225 THR_TYPE type)
00226 {
00227 if (type & THR_DATA_SPECULATION_NO_RB) {
00228 FmtAssert(OP_load(load_op), ("CGTARG_Perform_THR_Code_Generation : not a load OP"));
00229 INT enum_pos = -1;
00230
00231 BOOL float_op = OP_Is_Float_Mem(load_op) ? TRUE : FALSE;
00232 CGTARG_Return_Enum_TN(load_op, (float_op) ? ECV_fldtype : ECV_ldtype, &enum_pos);
00233
00234 FmtAssert(enum_pos != -1, ("OP doesn't have enum operand"));
00235
00236
00237
00238 TN *enum1_tn = (float_op) ? Gen_Enum_TN(ECV_fldtype_a) :
00239 Gen_Enum_TN(ECV_ldtype_a);
00240 Set_OP_opnd(load_op, enum_pos, enum1_tn);
00241 Set_OP_speculative(load_op);
00242
00243
00244 OP *check_load = Dup_OP(load_op);
00245 TN *enum2_tn;
00246 enum2_tn = (float_op) ? Gen_Enum_TN(ECV_fldtype_c_nc) :
00247 Gen_Enum_TN(ECV_ldtype_c_nc);
00248 Set_OP_opnd(check_load, enum_pos, enum2_tn);
00249
00250 Set_OP_cond_def_kind(check_load, OP_ALWAYS_COND_DEF);
00251
00252 BB_Insert_Op_After(OP_bb(load_op), load_op, check_load);
00253 } else if (type & THR_DATA_SPECULATION_NO_RB_CLEANUP) {
00254
00255 INT check_base_idx = TOP_Find_Operand_Use(OP_code(load_op), OU_base);
00256 TN *check_base_tn = OP_opnd(load_op, check_base_idx);
00257 TN *adv_load_base_tn = OP_opnd(chk_load, check_base_idx);
00258
00259 TN *check_result_tn = OP_result(load_op, 0);
00260 TN *adv_load_result_tn = OP_result(chk_load, 0);
00261
00262
00263
00264 if (TNs_Are_Equivalent(check_result_tn, adv_load_result_tn) &&
00265 TNs_Are_Equivalent(check_base_tn, adv_load_base_tn)) {
00266 BB_Remove_Op(OP_bb(load_op), load_op);
00267
00268 INT enum_pos = -1;
00269 BOOL float_op = OP_Is_Float_Mem(chk_load) ? TRUE : FALSE;
00270 TN *enum_tn =
00271 CGTARG_Return_Enum_TN(chk_load,
00272 (float_op) ? ECV_fldtype_c_nc : ECV_ldtype_c_nc,
00273 &enum_pos);
00274
00275 FmtAssert(enum_tn, ("OP doesn't have enum operand"));
00276 Set_TN_enum(enum_tn, (float_op) ? ECV_fldtype : ECV_ldtype);
00277 }
00278 }
00279 }
00280
00281
00282
00283
00284
00285
00286
00287
00288
00289 INT CGTARG_ARC_Sched_Latency(
00290 ARC *arc
00291 )
00292 {
00293 if ( ARC_kind(arc) == CG_DEP_PREBR && PROC_has_same_cycle_branch_shadow() )
00294 return 0;
00295 else
00296 return ARC_latency(arc);
00297 }
00298
00299
00300
00301
00302
00303
00304
00305
00306
00307
00308 BOOL
00309 CGTARG_Bundle_Slot_Available(TI_BUNDLE *bundle,
00310 OP *op,
00311 INT slot,
00312 ISA_EXEC_UNIT_PROPERTY *prop,
00313 BOOL stop_bit_reqd,
00314 const CG_GROUPING *grouping)
00315 {
00316
00317
00318 if (TI_BUNDLE_slot_filled(bundle, slot)) return FALSE;
00319
00320 INT inst_words = ISA_PACK_Inst_Words(OP_code(op));
00321
00322
00323
00324
00325
00326 if (EXEC_PROPERTY_is_I_Unit(OP_code(op)) &&
00327 EXEC_PROPERTY_is_M_Unit(OP_code(op))) {
00328 REGISTER reg;
00329
00330
00331 switch (OP_code(op)) {
00332 case TOP_mov_t_ar_i:
00333 case TOP_mov_t_ar_r:
00334 reg = TN_register(OP_result(op, 0));
00335
00336
00337 if (reg <= 47) {
00338 *prop = ISA_EXEC_PROPERTY_M_Unit;
00339 Set_OP_m_unit(op);
00340 }
00341 else if (64 <= reg && reg <= 111) {
00342 *prop = ISA_EXEC_PROPERTY_I_Unit;
00343 Reset_OP_m_unit(op);
00344 } else {
00345 FmtAssert(FALSE, ("unexpected register operand"));
00346 }
00347 break;
00348 case TOP_mov_f_ar:
00349 reg = TN_register(OP_opnd(op, 1));
00350
00351
00352 if (reg <= 47) {
00353 *prop = ISA_EXEC_PROPERTY_M_Unit;
00354 Set_OP_m_unit(op);
00355 }
00356 else if (64 <= reg && reg <= 111) {
00357 *prop = ISA_EXEC_PROPERTY_I_Unit;
00358 Reset_OP_m_unit(op);
00359 } else {
00360 FmtAssert(FALSE, ("unexpected register operand"));
00361 }
00362 break;
00363 default:
00364
00365
00366
00367
00368 if (slot == 0 || (slot == 1 && stop_bit_reqd)) {
00369 *prop = ISA_EXEC_PROPERTY_M_Unit;
00370 Set_OP_m_unit(op);
00371 } else if (grouping != NULL){
00372
00373
00374
00375
00376 if (slot == 2 ||
00377 grouping->avail_i_units() > grouping->avail_m_units())
00378 {
00379 *prop = ISA_EXEC_PROPERTY_I_Unit;
00380 Reset_OP_m_unit(op);
00381 }
00382 else
00383 {
00384 *prop = ISA_EXEC_PROPERTY_M_Unit;
00385 Set_OP_m_unit(op);
00386 }
00387 } else {
00388 *prop = ISA_EXEC_PROPERTY_I_Unit;
00389 Reset_OP_m_unit(op);
00390 }
00391 }
00392 } else if (EXEC_PROPERTY_is_B_Unit(OP_code(op)) &&
00393 EXEC_PROPERTY_is_B2_Unit(OP_code(op))) {
00394 *prop = (slot == 2) ? ISA_EXEC_PROPERTY_B2_Unit : ISA_EXEC_PROPERTY_B_Unit;
00395
00396 } else if (EXEC_PROPERTY_is_I_Unit(OP_code(op)) &&
00397 EXEC_PROPERTY_is_I2_Unit(OP_code(op))) {
00398 *prop = (slot == 2) ? ISA_EXEC_PROPERTY_I2_Unit : ISA_EXEC_PROPERTY_I_Unit;
00399 } else if (EXEC_PROPERTY_is_L_Unit(OP_code(op)) &&
00400 EXEC_PROPERTY_is_I2_Unit(OP_code(op))) {
00401 *prop = (slot == 2) ? ISA_EXEC_PROPERTY_I2_Unit : ISA_EXEC_PROPERTY_L_Unit;
00402 }
00403 else {
00404 *prop = ISA_EXEC_Unit_Prop(OP_code(op));
00405 }
00406
00407
00408
00409 BOOL extra_slot_reqd = (inst_words == 2) ?
00410 TI_BUNDLE_Slot_Available(bundle, *prop, slot + 1) : TRUE;
00411
00412
00413
00414
00415 BOOL stop_bit_avail = (stop_bit_reqd) ?
00416 CGTARG_Bundle_Stop_Bit_Available(bundle, slot - 1) : TRUE;
00417
00418 if (slot > 0) {
00419 if (stop_bit_reqd && stop_bit_avail) {
00420 TI_BUNDLE_Reserve_Stop_Bit(bundle, slot - 1);
00421 }
00422 }
00423
00424 BOOL slot_avail = extra_slot_reqd && stop_bit_avail &&
00425 TI_BUNDLE_Slot_Available (bundle, *prop, slot);
00426
00427 if (slot > 0) {
00428 if (stop_bit_reqd && stop_bit_avail) {
00429 TI_BUNDLE_Unreserve_Stop_Bit(bundle, slot - 1);
00430 }
00431 }
00432
00433 return slot_avail;
00434 }
00435
00436
00437
00438
00439
00440
00441
00442
00443
00444 BOOL
00445 CGTARG_Bundle_Stop_Bit_Available(TI_BUNDLE *bundle, INT slot)
00446 {
00447
00448 if (TI_BUNDLE_stop_bit(bundle, slot)) return TRUE;
00449
00450 return TI_BUNDLE_Stop_Bit_Available(bundle, slot);
00451 }
00452
00453
00454
00455
00456
00457
00458
00459
00460
00461 void
00462 CGTARG_Handle_Bundle_Hazard (OP *op,
00463 TI_BUNDLE *bundle,
00464 VECTOR *bundle_vector,
00465 BOOL can_fill,
00466 INT slot_pos,
00467 INT max_pos,
00468 BOOL stop_bit_reqd,
00469 ISA_EXEC_UNIT_PROPERTY prop)
00470 {
00471
00472 INT ti_err = TI_RC_OKAY;
00473
00474
00475
00476 if (TI_BUNDLE_Is_Empty(bundle, &ti_err)) {
00477 OP *last_real_op = Last_Real_OP(op);
00478 FmtAssert(ti_err != TI_RC_ERROR, ("%s", TI_errmsg));
00479 if (stop_bit_reqd) Set_OP_end_group(last_real_op);
00480 return;
00481 }
00482
00483 INT template_bit = TI_BUNDLE_Return_Template(bundle);
00484
00485 FmtAssert (template_bit != -1, ("Illegal template encoding"));
00486
00487
00488 if (OP_simulated(op)) {
00489 TOP adjust_top = CGTARG_Simulated_Top(op, prop);
00490 OP_Change_Opcode(op, adjust_top);
00491 }
00492
00493
00494
00495 INT adjusted_slot_pos = (can_fill && ISA_PACK_Inst_Words(OP_code(op)) > 1) ?
00496 max_pos + ISA_PACK_Inst_Words(OP_code(op)) - 1 : max_pos;
00497
00498 TOP nop;
00499 INT i;
00500 OP *prev_op = NULL;
00501 FOR_ALL_SLOT_MEMBERS(bundle, i) {
00502 if (i > adjusted_slot_pos) break;
00503 if (!TI_BUNDLE_slot_filled(bundle, i)) {
00504 if (i <= max_pos) {
00505 nop = CGTARG_Noop_Top (ISA_EXEC_Slot_Prop(template_bit, i));
00506
00507 OP *noop = Mk_OP (nop, True_TN, Gen_Literal_TN(0, 4));
00508
00509
00510
00511
00512
00513 if ((can_fill && !TOP_is_xfer(OP_code(op)) && i >= slot_pos)) {
00514 BB_Insert_Op_After(OP_bb(op), (prev_op) ? prev_op : op, noop);
00515 OP_scycle(noop) = -1;
00516 prev_op = noop;
00517 }
00518 else {
00519 BB_Insert_Op_Before(OP_bb(op), op, noop);
00520 OP_scycle(noop) = -1;
00521 prev_op = (can_fill) ? op : noop;
00522 }
00523 Set_OP_bundled (noop);
00524 if (OP_code(noop) == TOP_nop_m)
00525 Set_OP_m_unit(noop);
00526 TI_BUNDLE_Reserve_Slot (bundle, i, ISA_EXEC_Slot_Prop(template_bit, i));
00527 } else {
00528 TI_BUNDLE_Reserve_Slot (bundle, i, prop);
00529 prev_op = op;
00530 }
00531 }
00532 }
00533
00534
00535 if (TI_BUNDLE_Is_Full(bundle, &ti_err)) {
00536 FmtAssert(ti_err != TI_RC_ERROR, ("%s", TI_errmsg));
00537
00538
00539 if (TOP_is_xfer(OP_code(op))) {
00540 if (BB_last_real_op(OP_bb(op)) == op) Set_OP_end_group(op);
00541 if (!can_fill && stop_bit_reqd) {
00542 Set_OP_end_group(prev_op);
00543 VECTOR_Reset (*bundle_vector);
00544 }
00545 }
00546 else if (prev_op &&
00547 ((prev_op != op && stop_bit_reqd) ||
00548 (BB_last_op(OP_bb(prev_op)) == prev_op))) {
00549 Set_OP_end_group(prev_op);
00550 VECTOR_Reset (*bundle_vector);
00551 }
00552 else if (can_fill && BB_last_op(OP_bb(op)) == op) {
00553 Set_OP_end_group(op);
00554 VECTOR_Reset (*bundle_vector);
00555 }
00556 }
00557 }
00558
00559
00560
00561
00562
00563
00564
00565
00566
00567 void
00568 CGTARG_Handle_Errata_Hazard (OP *op, INT erratnum, INT ops_to_check)
00569 {
00570 }
00571
00572
00573
00574
00575
00576
00577
00578
00579
00580
00581
00582
00583
00584
00585 static void
00586 Reduce_Fraction(INT frac[2])
00587 {
00588 INT i;
00589 static const INT primes[] = {2, 3, 5, 7, 11, 13};
00590 INT n = frac[0];
00591 INT d = frac[1];
00592 INT p = d;
00593
00594 if (d < -1 || d > 1) {
00595 for (i = sizeof(primes) / sizeof(primes[0]); ; p = primes[--i]) {
00596 while (n % p == 0 && d % p == 0) {
00597 n = n / p;
00598 d = d / p;
00599 }
00600 if (i == 0) break;
00601 }
00602 }
00603
00604 frac[0] = n;
00605 frac[1] = d;
00606 }
00607
00608
00609
00610
00611
00612
00613
00614
00615
00616
00617
00618
00619
00620
00621
00622
00623
00624
00625
00626 static void
00627 Harmonic_Mean(
00628 INT mean[2],
00629 INT a,
00630 const INT a_rate[2],
00631 INT b,
00632 const INT b_rate[2]
00633 ) {
00634 if (a == 0) {
00635 mean[0] = b_rate[0];
00636 mean[1] = b_rate[1];
00637 } else if (b == 0) {
00638 mean[0] = a_rate[0];
00639 mean[1] = a_rate[1];
00640 } else {
00641 mean[1] = (a * a_rate[1] * b_rate[0])
00642 + (b * b_rate[1] * a_rate[0]);
00643 mean[0] = (a + b) * a_rate[0] * b_rate[0];
00644 Reduce_Fraction(mean);
00645 }
00646 }
00647
00648
00649
00650
00651
00652
00653
00654
00655
00656
00657 void CGTARG_Peak_Rate( PEAK_RATE_CLASS prc, PRC_INFO *info, INT ratio[2] )
00658 {
00659 ratio[0] = 1;
00660 ratio[1] = 1;
00661
00662 switch (prc) {
00663 case PRC_INST:
00664 ratio[0] = 6;
00665 break;
00666 case PRC_MADD:
00667 case PRC_MEMREF:
00668 ratio[0] = 2;
00669 break;
00670 case PRC_FLOP:
00671 case PRC_FADD:
00672 case PRC_FMUL:
00673 ratio[0] = 2;
00674 break;
00675 case PRC_IOP:
00676 ratio[0] = 4;
00677 break;
00678 default:
00679 ratio[0] = 2;
00680 break;
00681 }
00682 }
00683
00684
00685
00686
00687
00688
00689
00690
00691
00692
00693 #define Plural(i) ((i) != 1 ? "s" : "")
00694
00695
00696
00697
00698
00699
00700
00701
00702
00703
00704
00705
00706 static INT
00707 Percent_Of_Peak(INT numer, INT denom, INT peak[2])
00708 {
00709 if (numer == 0) return 0;
00710 return (numer * peak[1] * 100) / ((denom * peak[0]) + peak[1] - 1);
00711 }
00712
00713
00714
00715
00716
00717
00718
00719
00720
00721 void
00722 CGTARG_Print_PRC_INFO(
00723 FILE *file,
00724 PRC_INFO *info,
00725 INT32 ii,
00726 const char *prefix,
00727 const char *suffix
00728 )
00729 {
00730 char *s;
00731 INT madds_per_cycle[2];
00732 INT memrefs_per_cycle[2];
00733 INT flops_per_cycle[2];
00734 INT fadds_per_cycle[2];
00735 INT fmuls_per_cycle[2];
00736 INT iops_per_cycle[2];
00737 INT insts_per_cycle[2];
00738 INT insts = info->refs[PRC_INST];
00739 INT memrefs = info->refs[PRC_MEMREF];
00740 INT flops = info->refs[PRC_FLOP];
00741 INT madds = info->refs[PRC_MADD];
00742 INT fadds = info->refs[PRC_FADD];
00743 INT fmuls = info->refs[PRC_FMUL];
00744 INT iops = info->refs[PRC_IOP];
00745
00746 CGTARG_Peak_Rate(PRC_INST, info, insts_per_cycle);
00747 CGTARG_Peak_Rate(PRC_MEMREF, info, memrefs_per_cycle);
00748 CGTARG_Peak_Rate(PRC_FLOP, info, flops_per_cycle);
00749 CGTARG_Peak_Rate(PRC_MADD, info, madds_per_cycle);
00750 CGTARG_Peak_Rate(PRC_FADD, info, fadds_per_cycle);
00751 CGTARG_Peak_Rate(PRC_FMUL, info, fmuls_per_cycle);
00752 CGTARG_Peak_Rate(PRC_IOP, info, iops_per_cycle);
00753
00754 if (flops != 0) {
00755 BOOL unbalanced_fpu = FALSE;
00756
00757 if ( madds_per_cycle[0] != 0 ) {
00758 fprintf(file,"%s%5d flop%1s (%3d%% of peak) (madds count as 2)%s"
00759 "%s%5d flop%1s (%3d%% of peak) (madds count as 1)%s"
00760 "%s%5d madd%1s (%3d%% of peak)%s",
00761 prefix,
00762 flops + madds,
00763 Plural(flops + madds),
00764 Percent_Of_Peak(flops + madds, ii * 2, madds_per_cycle),
00765 suffix,
00766 prefix,
00767 flops,
00768 Plural(flops),
00769 Percent_Of_Peak(flops, ii, flops_per_cycle),
00770 suffix,
00771 prefix,
00772 madds,
00773 Plural(madds),
00774 Percent_Of_Peak(madds, ii, madds_per_cycle),
00775 suffix);
00776 }
00777 else {
00778 fprintf(file,"%s%5d flop%1s (%3d%% of peak)%s",
00779 prefix,
00780 flops,
00781 Plural(flops),
00782 Percent_Of_Peak(flops, ii, flops_per_cycle),
00783 suffix);
00784 }
00785
00786 if ( unbalanced_fpu ) {
00787 INT fmuls2_per_cycle[2];
00788 INT fadds2_per_cycle[2];
00789 INT fadds2 = fadds + madds;
00790 INT fmuls2 = fmuls + madds;
00791
00792 Harmonic_Mean(fmuls2_per_cycle,
00793 fmuls, fmuls_per_cycle,
00794 madds, madds_per_cycle);
00795 Harmonic_Mean(fadds2_per_cycle,
00796 fadds, fadds_per_cycle,
00797 madds, madds_per_cycle);
00798
00799 fprintf(file,"%s%5d fmul%1s (%3d%% of peak)%s%s",
00800 prefix,
00801 fmuls2,
00802 Plural(fmuls2),
00803 Percent_Of_Peak(fmuls2, ii, fmuls2_per_cycle),
00804 madds_per_cycle[0] ? " (madds count as 1)" : "",
00805 suffix);
00806 fprintf(file,"%s%5d fadd%1s (%3d%% of peak)%s%s",
00807 prefix,
00808 fadds2,
00809 Plural(fadds2),
00810 Percent_Of_Peak(fadds2, ii, fadds2_per_cycle),
00811 madds_per_cycle[0] ? " (madds count as 1)" : "",
00812 suffix);
00813 }
00814 }
00815
00816 s = "";
00817 if (FALSE) {
00818 iops += memrefs;
00819 s = " (mem refs included)";
00820 }
00821
00822 fprintf(file,"%s%5d mem ref%1s (%3d%% of peak)%s"
00823 "%s%5d integer op%1s (%3d%% of peak)%s%s"
00824 "%s%5d instruction%1s (%3d%% of peak)%s",
00825 prefix,
00826 memrefs,
00827 Plural(memrefs),
00828 Percent_Of_Peak(memrefs, ii, memrefs_per_cycle),
00829 suffix,
00830 prefix,
00831 iops,
00832 Plural(iops),
00833 Percent_Of_Peak(iops, ii, iops_per_cycle),
00834 s,
00835 suffix,
00836 prefix,
00837 insts,
00838 Plural(insts),
00839 Percent_Of_Peak(insts, ii, insts_per_cycle),
00840 suffix);
00841 }
00842
00843
00844
00845
00846
00847
00848
00849
00850
00851
00852
00853 void
00854 CGTARG_Compute_PRC_INFO(
00855 BB *bb,
00856 PRC_INFO *info
00857 )
00858 {
00859 OP *op;
00860
00861 bzero (info, sizeof (PRC_INFO));
00862
00863 for ( op = BB_first_op(bb); op != NULL; op = OP_next(op) ) {
00864 INT num_insts = OP_Real_Ops (op);
00865
00866 if (num_insts == 0) continue;
00867
00868 info->refs[PRC_INST] += num_insts;
00869
00870 if ( OP_flop(op) ) {
00871 BOOL is_single = (OP_result_size(op,0) == 32);
00872
00873 ++info->refs[PRC_FLOP];
00874 info->refs[PRC_FLOP_S] += is_single;
00875 if (OP_madd(op)) {
00876 ++info->refs[PRC_MADD];
00877 info->refs[PRC_MADD_S] += is_single;
00878 }
00879 else if (OP_fadd(op) || OP_fsub(op)) {
00880 ++info->refs[PRC_FADD];
00881 info->refs[PRC_FADD_S] += is_single;
00882 }
00883 else if (OP_fmul(op)) {
00884 ++info->refs[PRC_FMUL];
00885 info->refs[PRC_FMUL_S] += is_single;
00886 }
00887 }
00888 else if (OP_memory(op))
00889 ++info->refs[PRC_MEMREF];
00890 else {
00891 INT k;
00892
00893
00894
00895
00896
00897 if (OP_has_result(op) && TN_is_float(OP_result(op,0))) goto not_iop;
00898
00899 for (k = 0; k < OP_opnds(op); k++) {
00900 if (TN_is_float(OP_opnd(op,k))) goto not_iop;
00901 }
00902
00903 info->refs[PRC_IOP] += num_insts;
00904
00905 not_iop:
00906 ;
00907 }
00908 }
00909 }
00910
00911
00912
00913
00914
00915
00916
00917
00918
00919
00920 void
00921 CGTARG_Branch_Info ( const OP *op,
00922 INT *tfirst,
00923 INT *tcount )
00924 {
00925 INT i;
00926 TN *tn;
00927
00928
00929 *tfirst = -1;
00930 *tcount = 0;
00931
00932
00933 for ( i = 0; ; i++ ) {
00934 if ( i >= OP_opnds(op) ) return;
00935 tn = OP_opnd(op,i);
00936 if ( tn != NULL && TN_is_label(tn) ) break;
00937 }
00938 *tfirst = i;
00939
00940
00941 *tcount = 1;
00942 for ( i++; i < OP_opnds(op); i++ ) {
00943 tn = OP_opnd(op,i);
00944 if ( tn == NULL || ! TN_is_label(tn) ) return;
00945 (*tcount)++;
00946 }
00947 return;
00948 }
00949
00950
00951
00952
00953
00954
00955
00956
00957
00958
00959 BOOL
00960 CGTARG_Can_Be_Speculative( OP *op )
00961 {
00962 WN *wn;
00963
00964
00965 if (Eager_Level == EAGER_NONE) return FALSE;
00966
00967
00968 if (OP_volatile(op)) return FALSE;
00969
00970 if (TOP_Can_Be_Speculative(OP_code(op))) return TRUE;
00971
00972 if (!OP_load(op)) return FALSE;
00973
00974
00975
00976
00977
00978
00979
00980
00981
00982
00983
00984 if (OP_no_alias(op)) goto scalar_load;
00985
00986
00987
00988
00989
00990 if (TN_is_symbol(OP_opnd(op, 1)) &&
00991 !ST_is_weak_symbol(TN_var(OP_opnd(op, 1)))) goto scalar_load;
00992
00993
00994
00995
00996
00997 if (
00998 ( (wn = Get_WN_From_Memory_OP(op))
00999 && Alias_Manager->Safe_to_speculate(wn))) goto scalar_load;
01000
01001
01002
01003
01004 if (CGTARG_Is_OP_Speculative(op)) goto scalar_load;
01005
01006
01007
01008
01009 return FALSE;
01010
01011
01012
01013
01014 scalar_load:
01015 return TRUE;
01016 }
01017
01018
01019
01020
01021
01022
01023
01024
01025
01026 BOOL
01027 CGTARG_Is_OP_Speculative_Load( OP *memop )
01028 {
01029 if (!OP_load(memop)) return FALSE;
01030
01031 INT i;
01032 for (i = 0; i < OP_opnds(memop); ++i) {
01033 TN *opnd_tn = OP_opnd(memop, i);
01034 if (TN_is_enum(opnd_tn)) {
01035 if (TN_enum(opnd_tn) == ECV_ldtype_s ||
01036 TN_enum(opnd_tn) == ECV_ldtype_sa ||
01037 TN_enum(opnd_tn) == ECV_fldtype_sa ||
01038 TN_enum(opnd_tn) == ECV_fldtype_s) {
01039 return TRUE;
01040 }
01041 }
01042 }
01043
01044 return FALSE;
01045 }
01046
01047
01048
01049
01050
01051
01052
01053
01054
01055 BOOL
01056 CGTARG_Is_OP_Advanced_Load( OP *memop )
01057 {
01058 if (!OP_load(memop)) return FALSE;
01059
01060 INT i;
01061 for (i = 0; i < OP_opnds(memop); ++i) {
01062 TN *opnd_tn = OP_opnd(memop, i);
01063 if (TN_is_enum(opnd_tn)) {
01064 if (TN_enum(opnd_tn) == ECV_ldtype_a ||
01065 TN_enum(opnd_tn) == ECV_ldtype_sa ||
01066 TN_enum(opnd_tn) == ECV_fldtype_a ||
01067 TN_enum(opnd_tn) == ECV_fldtype_sa) {
01068 return TRUE;
01069 }
01070 }
01071 }
01072
01073 return FALSE;
01074 }
01075
01076
01077
01078
01079
01080
01081
01082
01083
01084 BOOL
01085 CGTARG_Is_OP_Check_Load( OP *memop )
01086 {
01087 if (!OP_load(memop)) return FALSE;
01088
01089 INT i;
01090 for (i = 0; i < OP_opnds(memop); ++i) {
01091 TN *opnd_tn = OP_opnd(memop, i);
01092 if (TN_is_enum(opnd_tn)) {
01093 if (TN_enum(opnd_tn) == ECV_ldtype_c_clr ||
01094 TN_enum(opnd_tn) == ECV_ldtype_c_nc ||
01095 TN_enum(opnd_tn) == ECV_ldtype_c_clr_acq ||
01096 TN_enum(opnd_tn) == ECV_fldtype_c_clr ||
01097 TN_enum(opnd_tn) == ECV_fldtype_c_nc) return TRUE;
01098 }
01099 }
01100
01101 return FALSE;
01102 }
01103
01104
01105
01106
01107
01108
01109
01110
01111
01112 BOOL
01113 CGTARG_Is_Form_For_Advanced_Load (ISA_ENUM_CLASS_VALUE ldform) {
01114 return ldform == ECV_ldtype_sa ||
01115 ldform == ECV_ldtype_a ||
01116 ldform == ECV_fldtype_a ||
01117 ldform == ECV_fldtype_sa;
01118 }
01119
01120
01121
01122
01123
01124
01125
01126
01127
01128
01129 BOOL
01130 CGTARG_OP_Defs_TN( OP *op, TN *tn )
01131 {
01132 return FALSE;
01133 }
01134
01135 BOOL
01136 CGTARG_OP_Refs_TN( OP *op, TN *tn )
01137 {
01138 return FALSE;
01139 }
01140
01141
01142
01143
01144
01145
01146
01147
01148
01149 static MEM_POOL interference_pool;
01150 static VOID_LIST** writing;
01151
01152 static BOOL is_loop;
01153 static INT32 assumed_longest_latency = 40;
01154
01155
01156
01157
01158
01159
01160 static INT32 cycle_count;
01161
01162 static void (*make_interference)(void*,void*);
01163
01164
01165
01166
01167
01168
01169
01170
01171
01172
01173
01174 static void
01175 Increase_Assumed_Longest_Latency(INT32 new_longest_latency )
01176 {
01177 DevWarn("Assumed longest latency should be at least %d",
01178 new_longest_latency);
01179 writing = TYPE_MEM_POOL_REALLOC_N(VOID_LIST*,&interference_pool,writing,
01180 cycle_count + assumed_longest_latency,
01181 cycle_count + new_longest_latency);
01182 assumed_longest_latency = new_longest_latency;
01183 }
01184
01185
01186
01187
01188
01189
01190
01191
01192
01193 BOOL
01194 CGTARG_Interference_Required(void)
01195 {
01196 return FALSE;
01197 }
01198
01199
01200
01201
01202
01203
01204
01205
01206
01207 void
01208 CGTARG_Interference_Initialize( INT32 cycle_count_local, BOOL is_loop_local,
01209 void (*make_interference_local)(void*,void*) )
01210 {
01211 static BOOL interference_pool_initialized = FALSE;
01212
01213 if ( ! interference_pool_initialized ) {
01214 MEM_POOL_Initialize(&interference_pool,"Target_specific_interference",
01215 TRUE);
01216 interference_pool_initialized = TRUE;
01217 }
01218
01219 MEM_POOL_Push(&interference_pool);
01220
01221 is_loop = is_loop_local;
01222 make_interference = make_interference_local;
01223 cycle_count = cycle_count_local;
01224
01225 if ( is_loop )
01226 writing = TYPE_MEM_POOL_ALLOC_N(VOID_LIST*,&interference_pool,cycle_count);
01227 else
01228 writing = TYPE_MEM_POOL_ALLOC_N(VOID_LIST*,&interference_pool,
01229 cycle_count + assumed_longest_latency);
01230 }
01231
01232
01233
01234
01235
01236
01237
01238
01239
01240 void
01241 CGTARG_Result_Live_Range( void* lrange, OP* op, INT32 offset )
01242 {
01243 VOID_LIST* l;
01244 INT32 cycle = OP_scycle(op);
01245
01246 if ( OP_defs_fp(op) ) {
01247 INT32 reg_write_cyc;
01248 reg_write_cyc = TI_LATENCY_Result_Available_Cycle(OP_code(op), 0 )
01249 + (OP_load(op) ? 0 : 1);
01250
01251 if ( is_loop )
01252 reg_write_cyc = Mod(reg_write_cyc + cycle + offset,cycle_count);
01253 else {
01254 reg_write_cyc += cycle + offset;
01255
01256 if ( reg_write_cyc >= cycle_count + assumed_longest_latency ) {
01257
01258 Increase_Assumed_Longest_Latency(1 + reg_write_cyc - cycle_count);
01259 }
01260 }
01261
01262 for ( l = writing[reg_write_cyc]; l != NULL; l = VOID_LIST_rest(l) )
01263 make_interference(lrange,VOID_LIST_first(l));
01264
01265 writing[reg_write_cyc] = VOID_LIST_Push(lrange,writing[reg_write_cyc],
01266 &interference_pool);
01267 }
01268 }
01269
01270
01271
01272
01273
01274
01275
01276
01277
01278 void
01279 CGTARG_Operand_Live_Range( void* lrange, INT opnd, OP* op, INT32 offset )
01280 {
01281 VOID_LIST* l;
01282 INT32 cycle = OP_scycle(op);
01283 INT32 reg_acc_cyc = TI_LATENCY_Operand_Access_Cycle(OP_code(op), opnd);
01284
01285 if ( is_loop )
01286 reg_acc_cyc = Mod(reg_acc_cyc + cycle + offset,cycle_count);
01287 else {
01288 reg_acc_cyc += cycle + offset;
01289
01290 if ( reg_acc_cyc >= cycle_count + assumed_longest_latency )
01291 return;
01292 }
01293
01294 for ( l = writing[reg_acc_cyc]; l != NULL; l = VOID_LIST_rest(l) )
01295 make_interference(lrange,VOID_LIST_first(l));
01296 }
01297
01298
01299
01300
01301
01302
01303
01304
01305
01306 void
01307 CGTARG_Interference_Finalize(void)
01308 {
01309 MEM_POOL_Pop(&interference_pool);
01310 writing = (VOID_LIST **) -1;
01311 }
01312
01313
01314
01315
01316
01317
01318
01319
01320
01321
01322 BOOL
01323 CGTARG_Preg_Register_And_Class(
01324 WN_OFFSET preg,
01325 ISA_REGISTER_CLASS *p_rclass,
01326 REGISTER *p_reg
01327 )
01328 {
01329 ISA_REGISTER_CLASS rclass;
01330 INT regnum;
01331 REGISTER reg;
01332
01333
01334
01335
01336 if (Preg_Offset_Is_Int(preg)) {
01337 regnum = preg - (Int_Preg_Min_Offset - 1);
01338 rclass = ISA_REGISTER_CLASS_integer;
01339 }
01340 else if (Preg_Offset_Is_Float(preg)) {
01341 regnum = preg - Float_Preg_Min_Offset;
01342 rclass = ISA_REGISTER_CLASS_float;
01343 }
01344
01345 else if (Preg_Offset_Is_Branch(preg)) {
01346 regnum = preg - Branch_Preg_Min_Offset;
01347 rclass = ISA_REGISTER_CLASS_branch;
01348 }
01349 else if (preg == 0) {
01350
01351
01352 regnum = 0;
01353 rclass = ISA_REGISTER_CLASS_integer;
01354 }
01355 else {
01356 return FALSE;
01357 }
01358
01359
01360
01361 for ( reg = REGISTER_MIN; reg <= REGISTER_CLASS_last_register(rclass); reg++ ) {
01362 if ( REGISTER_machine_id(rclass,reg) == regnum ) {
01363 *p_reg = reg;
01364 *p_rclass = rclass;
01365 return TRUE;
01366 }
01367 }
01368 FmtAssert(FALSE, ("failed to map preg %d", preg));
01369
01370 }
01371
01372
01373
01374
01375
01376
01377
01378
01379
01380
01381 void CGTARG_Compute_Branch_Parameters(INT32 *mispredict, INT32 *fixed, INT32 *brtaken, double *factor)
01382 {
01383 *mispredict = 0;
01384 *fixed = 0;
01385 *brtaken = 0;
01386 *factor = 0.0;
01387
01388 if (Is_Target_Itanium())
01389 {
01390 *mispredict= 8; *fixed= 1; *brtaken= 1; *factor = 1.0;
01391 }
01392 else
01393 {
01394 FmtAssert(FALSE, ("invalid target"));
01395 }
01396
01397
01398
01399
01400
01401
01402 if (CG_branch_mispredict_penalty >= 0)
01403 *mispredict= CG_branch_mispredict_penalty ;
01404
01405 if (CG_branch_mispredict_factor >= 0)
01406 *factor= CG_branch_mispredict_factor * (.01);
01407 }
01408
01409
01410
01411
01412
01413
01414
01415
01416
01417
01418 BOOL CGTARG_Can_Change_To_Brlikely(OP *xfer_op, TOP *new_opcode)
01419 {
01420 return FALSE;
01421 }
01422
01423
01424
01425
01426
01427
01428
01429
01430
01431
01432 BOOL CGTARG_Is_Long_Latency(TOP op)
01433 {
01434 switch (op) {
01435
01436
01437 case TOP_frcpa:
01438 case TOP_frsqrta:
01439 case TOP_fprcpa:
01440 case TOP_fprsqrta:
01441
01442
01443 return TRUE;
01444 }
01445 return FALSE;
01446 }
01447
01448
01449
01450
01451
01452
01453
01454
01455
01456 VARIANT CGTARG_Analyze_Branch(
01457 OP *br,
01458 TN **tn1,
01459 TN **tn2)
01460 {
01461 VARIANT variant;
01462
01463 *tn1 = NULL;
01464 *tn2 = NULL;
01465
01466 switch (OP_code(br)) {
01467 case TOP_br_cond:
01468 case TOP_br_r_cond:
01469 case TOP_br_call:
01470 case TOP_br_r_call:
01471 case TOP_br_ret:
01472 case TOP_br_ia:
01473 {
01474 TN* pred_tn = OP_opnd(br, OP_PREDICATE_OPND);
01475
01476 if (TN_register_and_class(pred_tn) != CLASS_AND_REG_true) {
01477 *tn1 = pred_tn;
01478 variant = V_BR_P_TRUE;
01479 break;
01480 }
01481 }
01482
01483
01484 case TOP_br:
01485 case TOP_br_r:
01486 variant = V_BR_ALWAYS;
01487 break;
01488
01489 case TOP_br_cloop:
01490 variant = V_BR_CLOOP;
01491 break;
01492
01493 case TOP_br_ctop:
01494 variant = V_BR_CTOP;
01495 break;
01496
01497 case TOP_br_cexit:
01498 variant = V_BR_CEXIT;
01499 break;
01500
01501 case TOP_br_wtop:
01502 variant = V_BR_WTOP;
01503 break;
01504
01505 case TOP_br_wexit:
01506 variant = V_BR_WEXIT;
01507 break;
01508
01509 default:
01510 variant = V_BR_NONE;
01511 break;
01512 }
01513
01514 return variant;
01515 }
01516
01517
01518
01519
01520
01521
01522
01523
01524
01525
01526 VARIANT CGTARG_Analyze_Compare(
01527 OP *br,
01528 TN **tn1,
01529 TN **tn2,
01530 OP **compare_op)
01531 {
01532 VARIANT variant;
01533 TN *cond_tn1;
01534 TN *cond_tn2;
01535 BOOL is_double;
01536 DEF_KIND kind;
01537
01538
01539
01540 variant = CGTARG_Analyze_Branch(br, &cond_tn1, &cond_tn2);
01541
01542
01543
01544
01545 if (cond_tn1 && TN_is_float(cond_tn1) && TN_size(cond_tn1) == 8) {
01546 is_double = TRUE;
01547 } else {
01548 is_double = FALSE;
01549 }
01550
01551
01552
01553
01554
01555 if (variant == V_BR_P_TRUE) {
01556 OP *def_op;
01557
01558
01559
01560 def_op = TN_Reaching_Value_At_Op(cond_tn1, br, &kind, TRUE);
01561
01562
01563
01564 if (!def_op || kind != VAL_KNOWN) goto no_cmp;
01565
01566
01567
01568
01569 switch (OP_code(def_op)) {
01570 case TOP_cmp_eq:
01571 case TOP_cmp_eq_unc:
01572 case TOP_cmp_i_eq:
01573 case TOP_cmp_i_eq_unc:
01574 variant = V_BR_I8EQ;
01575 break;
01576 case TOP_cmp4_eq:
01577 case TOP_cmp4_eq_unc:
01578 case TOP_cmp4_i_eq:
01579 case TOP_cmp4_i_eq_unc:
01580 variant = V_BR_I4EQ;
01581 break;
01582 case TOP_cmp_lt:
01583 case TOP_cmp_i_lt:
01584 case TOP_cmp_lt_unc:
01585 case TOP_cmp_i_lt_unc:
01586 variant = V_BR_I8LT;
01587 break;
01588 case TOP_cmp4_lt:
01589 case TOP_cmp4_i_lt:
01590 case TOP_cmp4_lt_unc:
01591 case TOP_cmp4_i_lt_unc:
01592 variant = V_BR_I4LT;
01593 break;
01594 case TOP_cmp_ltu:
01595 case TOP_cmp_i_ltu:
01596 case TOP_cmp_ltu_unc:
01597 case TOP_cmp_i_ltu_unc:
01598 variant = V_BR_U8LT;
01599 break;
01600 case TOP_cmp4_ltu:
01601 case TOP_cmp4_i_ltu:
01602 case TOP_cmp4_ltu_unc:
01603 case TOP_cmp4_i_ltu_unc:
01604 variant = V_BR_U4LT;
01605 break;
01606 case TOP_cmp_ne:
01607 case TOP_cmp_i_ne:
01608 case TOP_cmp_ne_unc:
01609 case TOP_cmp_i_ne_unc:
01610 variant = V_BR_I8NE;
01611 break;
01612 case TOP_cmp4_ne:
01613 case TOP_cmp4_i_ne:
01614 case TOP_cmp4_ne_unc:
01615 case TOP_cmp4_i_ne_unc:
01616 variant = V_BR_I4NE;
01617 break;
01618 case TOP_cmp_le:
01619 case TOP_cmp_i_le:
01620 case TOP_cmp_le_unc:
01621 case TOP_cmp_i_le_unc:
01622 variant = V_BR_I8LE;
01623 break;
01624 case TOP_cmp4_le:
01625 case TOP_cmp4_i_le:
01626 case TOP_cmp4_le_unc:
01627 case TOP_cmp4_i_le_unc:
01628 variant = V_BR_I4LE;
01629 break;
01630 case TOP_cmp_gt:
01631 case TOP_cmp_i_gt:
01632 case TOP_cmp_gt_unc:
01633 case TOP_cmp_i_gt_unc:
01634 variant = V_BR_I8GT;
01635 break;
01636 case TOP_cmp4_gt:
01637 case TOP_cmp4_i_gt:
01638 case TOP_cmp4_gt_unc:
01639 case TOP_cmp4_i_gt_unc:
01640 variant = V_BR_I4GT;
01641 break;
01642 case TOP_cmp_ge:
01643 case TOP_cmp_i_ge:
01644 case TOP_cmp_ge_unc:
01645 case TOP_cmp_i_ge_unc:
01646 variant = V_BR_I8GE;
01647 break;
01648 case TOP_cmp4_ge:
01649 case TOP_cmp4_i_ge:
01650 case TOP_cmp4_ge_unc:
01651 case TOP_cmp4_i_ge_unc:
01652 variant = V_BR_I4GE;
01653 break;
01654 case TOP_cmp_leu:
01655 case TOP_cmp_i_leu:
01656 case TOP_cmp_leu_unc:
01657 case TOP_cmp_i_leu_unc:
01658 variant = V_BR_U8LE;
01659 break;
01660 case TOP_cmp4_leu:
01661 case TOP_cmp4_i_leu:
01662 case TOP_cmp4_leu_unc:
01663 case TOP_cmp4_i_leu_unc:
01664 variant = V_BR_U4LE;
01665 break;
01666 case TOP_cmp_gtu:
01667 case TOP_cmp_i_gtu:
01668 case TOP_cmp_gtu_unc:
01669 case TOP_cmp_i_gtu_unc:
01670 variant = V_BR_U8GT;
01671 break;
01672 case TOP_cmp4_gtu:
01673 case TOP_cmp4_i_gtu:
01674 case TOP_cmp4_gtu_unc:
01675 case TOP_cmp4_i_gtu_unc:
01676 variant = V_BR_U4GT;
01677 break;
01678 case TOP_cmp_geu:
01679 case TOP_cmp_i_geu:
01680 case TOP_cmp_geu_unc:
01681 case TOP_cmp_i_geu_unc:
01682 variant = V_BR_U8GE;
01683 break;
01684 case TOP_cmp4_geu:
01685 case TOP_cmp4_i_geu:
01686 case TOP_cmp4_geu_unc:
01687 case TOP_cmp4_i_geu_unc:
01688 variant = V_BR_U4GE;
01689 break;
01690
01691 case TOP_fcmp_eq:
01692 case TOP_fcmp_eq_unc:
01693 if (is_double) {
01694 variant = V_BR_DEQ;
01695 } else {
01696 variant = V_BR_FEQ;
01697 }
01698 break;
01699 case TOP_fcmp_ge:
01700 case TOP_fcmp_ge_unc:
01701 if (is_double) {
01702 variant = V_BR_DGE;
01703 } else {
01704 variant = V_BR_FGE;
01705 }
01706 break;
01707 case TOP_fcmp_gt:
01708 case TOP_fcmp_gt_unc:
01709 if (is_double) {
01710 variant = V_BR_DGT;
01711 } else {
01712 variant = V_BR_FGT;
01713 }
01714 break;
01715 case TOP_fcmp_le:
01716 case TOP_fcmp_le_unc:
01717 if (is_double) {
01718 variant = V_BR_DLE;
01719 } else {
01720 variant = V_BR_FLE;
01721 }
01722 break;
01723 case TOP_fcmp_lt:
01724 case TOP_fcmp_lt_unc:
01725 if (is_double) {
01726 variant = V_BR_DLT;
01727 } else {
01728 variant = V_BR_FLT;
01729 }
01730 break;
01731 case TOP_fcmp_neq:
01732 case TOP_fcmp_neq_unc:
01733 if (is_double) {
01734 variant = V_BR_DNE;
01735 } else {
01736 variant = V_BR_FNE;
01737 }
01738 break;
01739 case TOP_fcmp_nge:
01740 case TOP_fcmp_nge_unc:
01741 if (is_double) {
01742 variant = V_BR_DLT;
01743 } else {
01744 variant = V_BR_FLT;
01745 }
01746 break;
01747 case TOP_fcmp_ngt:
01748 case TOP_fcmp_ngt_unc:
01749 if (is_double) {
01750 variant = V_BR_DLE;
01751 } else {
01752 variant = V_BR_FLE;
01753 }
01754 break;
01755 case TOP_fcmp_nle:
01756 case TOP_fcmp_nle_unc:
01757 if (is_double) {
01758 variant = V_BR_DGT;
01759 } else {
01760 variant = V_BR_FGT;
01761 }
01762 break;
01763 case TOP_fcmp_nlt:
01764 case TOP_fcmp_nlt_unc:
01765 if (is_double) {
01766 variant = V_BR_DGE;
01767 } else {
01768 variant = V_BR_FGE;
01769 }
01770 break;
01771 case TOP_fcmp_ord:
01772 case TOP_fcmp_ord_unc:
01773 if (is_double) {
01774 variant = V_BR_DOR;
01775 } else {
01776 variant = V_BR_FOR;
01777 }
01778 break;
01779 case TOP_fcmp_unord:
01780 case TOP_fcmp_unord_unc:
01781 if (is_double) {
01782 variant = V_BR_DUO;
01783 } else {
01784 variant = V_BR_FUO;
01785 }
01786 break;
01787 case TOP_tbit_z:
01788 case TOP_tbit_z_unc:
01789 if (CG_Enable_Ipfec_Phases) {
01790 variant = V_BR_I4EQ;
01791 break;
01792 } else {
01793 goto no_cmp;
01794 }
01795 case TOP_tbit_nz:
01796 case TOP_tbit_nz_unc:
01797 if ( CG_Enable_Ipfec_Phases) {
01798 variant = V_BR_I4NE;
01799 break;
01800 } else {
01801 goto no_cmp;
01802 }
01803 default:
01804
01805
01806 goto no_cmp;
01807 }
01808
01809
01810
01811
01812
01813 if (OP_result(def_op, 1) == cond_tn1) {
01814 variant = Negate_BR_Variant(variant);
01815 }
01816
01817
01818
01819
01820 if (OP_icmp(def_op)) {
01821 cond_tn1 = OP_opnd(def_op, 1);
01822 cond_tn2 = OP_opnd(def_op, 2);
01823 } else {
01824 cond_tn1 = OP_opnd(def_op, 2);
01825 cond_tn2 = OP_opnd(def_op, 3);
01826 }
01827 *compare_op = def_op;
01828 } else {
01829
01830
01831
01832 no_cmp:
01833 *compare_op = NULL;
01834 }
01835
01836 *tn1 = cond_tn1;
01837 *tn2 = cond_tn2;
01838 return variant;
01839 }
01840
01841
01842
01843
01844
01845
01846
01847
01848
01849
01850 TOP
01851 CGTARG_Equiv_Nonindex_Memory_Op ( OP *op )
01852 {
01853 return TOP_UNDEFINED;
01854 }
01855
01856
01857
01858
01859
01860
01861
01862
01863
01864 TOP
01865 CGTARG_Which_OP_Select ( UINT16 bit_size, BOOL is_float, BOOL is_fcc )
01866 {
01867 FmtAssert( FALSE, ( "CGTARG_Which_OP_Select: Unsupported Target") );
01868
01869 }
01870
01871
01872
01873
01874
01875
01876
01877
01878
01879 static BOOL
01880 Is_OP_fp_op1(OP *op)
01881 {
01882 switch (OP_code(op)) {
01883 case TOP_fma:
01884 case TOP_fma_d:
01885 case TOP_fma_s:
01886 case TOP_fms:
01887 case TOP_fms_d:
01888 case TOP_fms_s:
01889 case TOP_fnma:
01890 case TOP_fnma_d:
01891 case TOP_fnma_s:
01892 case TOP_famax:
01893 case TOP_famin:
01894 case TOP_fand:
01895 case TOP_fandcm:
01896 case TOP_fchkf:
01897 case TOP_fmax:
01898 case TOP_fmerge_ns:
01899 case TOP_fmerge_s:
01900 case TOP_fmerge_se:
01901 case TOP_fmin:
01902 case TOP_fmix_l:
01903 case TOP_fmix_lr:
01904 case TOP_fmix_r:
01905 case TOP_for:
01906 case TOP_fpack:
01907 case TOP_frcpa:
01908 case TOP_frsqrta:
01909 case TOP_fselect:
01910 case TOP_fsetc:
01911 case TOP_fswap:
01912 case TOP_fswap_nl:
01913 case TOP_fswap_nr:
01914 case TOP_fsxt_l:
01915 case TOP_fsxt_r:
01916 case TOP_fxor:
01917 case TOP_fclass_m:
01918 case TOP_fclass_m_unc:
01919 case TOP_fclass_nm:
01920 case TOP_fclass_nm_unc:
01921 case TOP_fcmp_eq:
01922 case TOP_fcmp_eq_unc:
01923 case TOP_fcmp_ge:
01924 case TOP_fcmp_ge_unc:
01925 case TOP_fcmp_gt:
01926 case TOP_fcmp_gt_unc:
01927 case TOP_fcmp_le:
01928 case TOP_fcmp_le_unc:
01929 case TOP_fcmp_lt:
01930 case TOP_fcmp_lt_unc:
01931 case TOP_fcmp_neq:
01932 case TOP_fcmp_neq_unc:
01933 case TOP_fcmp_nge:
01934 case TOP_fcmp_nge_unc:
01935 case TOP_fcmp_ngt:
01936 case TOP_fcmp_ngt_unc:
01937 case TOP_fcmp_nle:
01938 case TOP_fcmp_nle_unc:
01939 case TOP_fcmp_nlt:
01940 case TOP_fcmp_nlt_unc:
01941 case TOP_fcmp_ord:
01942 case TOP_fcmp_ord_unc:
01943 case TOP_fcmp_unord:
01944 case TOP_fcmp_unord_unc:
01945 case TOP_fpma:
01946 case TOP_fpms:
01947 case TOP_fpnma:
01948 case TOP_fpamax:
01949 case TOP_fpamin:
01950 case TOP_fpcmp_eq:
01951 case TOP_fpcmp_ge:
01952 case TOP_fpcmp_gt:
01953 case TOP_fpcmp_le:
01954 case TOP_fpcmp_lt:
01955 case TOP_fpcmp_neq:
01956 case TOP_fpcmp_nge:
01957 case TOP_fpcmp_ngt:
01958 case TOP_fpcmp_nle:
01959 case TOP_fpcmp_nlt:
01960 case TOP_fpcmp_ord:
01961 case TOP_fpcmp_unord:
01962 case TOP_fpmax:
01963 case TOP_fpmerge_ns:
01964 case TOP_fpmerge_s:
01965 case TOP_fpmerge_se:
01966 case TOP_fpmin:
01967 case TOP_fprcpa:
01968 case TOP_fprsqrta:
01969 case TOP_fcvt_fx:
01970 case TOP_fcvt_fx_trunc:
01971 case TOP_fcvt_fxu:
01972 case TOP_fcvt_fxu_trunc:
01973 case TOP_fcvt_xuf:
01974 case TOP_fcvt_xuf_d:
01975 case TOP_fcvt_xuf_s:
01976 case TOP_fpcvt_fx:
01977 case TOP_fpcvt_fx_trunc:
01978 case TOP_fpcvt_fxu:
01979 case TOP_fpcvt_fxu_trunc:
01980 case TOP_xma_h:
01981 case TOP_xma_hu:
01982 case TOP_xma_l:
01983 case TOP_xma_lu:
01984 case TOP_xmpy_h:
01985 case TOP_xmpy_hu:
01986 case TOP_xmpy_l:
01987 case TOP_xmpy_lu:
01988 return TRUE;
01989 default:
01990 return FALSE;
01991 }
01992 }
01993
01994
01995
01996
01997
01998
01999
02000 void
02001 Insert_Stop_Bits(BB *bb)
02002 {
02003
02004 if (!Itanium_a0_step) return;
02005
02006 INT slot = 0;
02007 OP *op;
02008
02009 FOR_ALL_BB_OPs_FWD (bb, op) {
02010
02011 if (Is_OP_fp_op1(op)) {
02012 OP *noop1, *noop2, *noop3;
02013
02014
02015
02016
02017 OP *last_op_in_bundle;
02018 if (slot == 2) {
02019
02020 last_op_in_bundle = op;
02021 }
02022 else {
02023
02024
02025 last_op_in_bundle = OP_next(op);
02026 Set_OP_end_group(last_op_in_bundle);
02027 }
02028
02029
02030
02031 noop1 = Mk_OP (TOP_nop_m, True_TN, Gen_Literal_TN(0, 4));
02032 BB_Insert_Op_After(bb, last_op_in_bundle, noop1);
02033 noop2 = Mk_OP (TOP_nop_i, True_TN, Gen_Literal_TN(0, 4));
02034 BB_Insert_Op_After(bb, noop1, noop2);
02035 noop3 = Mk_OP (TOP_nop_i, True_TN, Gen_Literal_TN(0, 4));
02036 BB_Insert_Op_After(bb, noop2, noop3);
02037
02038 Set_OP_end_group(noop3);
02039 }
02040
02041 if (OP_dummy(op)) continue;
02042 if (OP_simulated(op)) continue;
02043 slot += ISA_PACK_Inst_Words(OP_code(op));
02044 if (slot >= ISA_MAX_SLOTS) slot = 0;
02045 }
02046 }
02047
02048
02049
02050
02051
02052
02053
02054
02055
02056 INT32 CGTARG_Special_Min_II(BB* loop_body, BOOL trace)
02057 {
02058 return 0;
02059 }
02060
02061
02062
02063
02064
02065
02066
02067
02068
02069 void
02070 Hardware_Workarounds(void)
02071 {
02072 }
02073
02074
02075
02076
02077
02078
02079
02080
02081
02082 void CGTARG_Initialize(void)
02083 {
02084 INT32 i;
02085
02086
02087
02088 for(i = 0; i <= TOP_count; ++i) {
02089 CGTARG_Invert_Table[i] = TOP_UNDEFINED;
02090 CGTARG_Immed_To_Reg_Table[i] = TOP_UNDEFINED;
02091 }
02092
02093 for (i = 0; i <= ISA_REGISTER_CLASS_MAX; ++i) {
02094 INT j;
02095 for (j = 0; j <= ISA_REGISTER_CLASS_MAX; ++j) {
02096 CGTARG_Inter_RegClass_Copy_Table[i][j][FALSE] = TOP_UNDEFINED;
02097 CGTARG_Inter_RegClass_Copy_Table[i][j][TRUE] = TOP_UNDEFINED;
02098 }
02099 }
02100
02101
02102
02103 CGTARG_Invert_Table[TOP_fadd] = TOP_fsub;
02104 CGTARG_Invert_Table[TOP_fadd_s] = TOP_fsub_s;
02105 CGTARG_Invert_Table[TOP_fadd_d] = TOP_fsub_d;
02106 CGTARG_Invert_Table[TOP_fma] = TOP_fnma;
02107 CGTARG_Invert_Table[TOP_fma_s] = TOP_fnma_s;
02108 CGTARG_Invert_Table[TOP_fma_d] = TOP_fnma_d;
02109 CGTARG_Invert_Table[TOP_add] = TOP_sub;
02110 CGTARG_Invert_Table[TOP_adds] = TOP_sub_i;
02111 CGTARG_Invert_Table[TOP_addl] = TOP_sub;
02112
02113 CGTARG_Invert_Table[TOP_fsub] = TOP_fadd;
02114 CGTARG_Invert_Table[TOP_fsub_s] = TOP_fadd_s;
02115 CGTARG_Invert_Table[TOP_fsub_d] = TOP_fadd_d;
02116 CGTARG_Invert_Table[TOP_fnma] = TOP_fma;
02117 CGTARG_Invert_Table[TOP_fnma_s] = TOP_fma_s;
02118 CGTARG_Invert_Table[TOP_fnma_d] = TOP_fma_d;
02119 CGTARG_Invert_Table[TOP_sub_i] = TOP_adds;
02120
02121 CGTARG_Invert_Table[TOP_mov_f_ar] = TOP_mov_t_ar_r;
02122 CGTARG_Invert_Table[TOP_mov_t_ar_r] = TOP_mov_f_ar;
02123 CGTARG_Invert_Table[TOP_mov_f_ar_i] = TOP_mov_t_ar_r_i;
02124 CGTARG_Invert_Table[TOP_mov_t_ar_r_i] = TOP_mov_f_ar_i;
02125 CGTARG_Invert_Table[TOP_mov_f_ar_m] = TOP_mov_t_ar_r_m;
02126 CGTARG_Invert_Table[TOP_mov_t_ar_r_m] = TOP_mov_f_ar_m;
02127
02128 CGTARG_Invert_Table[TOP_mov_f_br] = TOP_mov_t_br;
02129 CGTARG_Invert_Table[TOP_mov_t_br] = TOP_mov_f_br;
02130
02131 CGTARG_Invert_Table[TOP_mov_f_cr] = TOP_mov_t_cr;
02132 CGTARG_Invert_Table[TOP_mov_t_cr] = TOP_mov_f_cr;
02133
02134 CGTARG_Invert_Table[TOP_mov_f_dbr] = TOP_mov_t_dbr;
02135 CGTARG_Invert_Table[TOP_mov_t_dbr] = TOP_mov_f_dbr;
02136
02137 CGTARG_Invert_Table[TOP_mov_f_ibr] = TOP_mov_t_ibr;
02138 CGTARG_Invert_Table[TOP_mov_t_ibr] = TOP_mov_f_ibr;
02139
02140 CGTARG_Invert_Table[TOP_mov_f_pkr] = TOP_mov_t_pkr;
02141 CGTARG_Invert_Table[TOP_mov_t_pkr] = TOP_mov_f_pkr;
02142
02143 CGTARG_Invert_Table[TOP_mov_f_pmc] = TOP_mov_t_pmc;
02144 CGTARG_Invert_Table[TOP_mov_t_pmc] = TOP_mov_f_pmc;
02145
02146 CGTARG_Invert_Table[TOP_mov_f_pmd] = TOP_mov_t_pmd;
02147 CGTARG_Invert_Table[TOP_mov_t_pmd] = TOP_mov_f_pmd;
02148
02149 CGTARG_Invert_Table[TOP_mov_f_rr] = TOP_mov_t_rr;
02150 CGTARG_Invert_Table[TOP_mov_t_rr] = TOP_mov_f_rr;
02151
02152 CGTARG_Invert_Table[TOP_mov_f_pr] = TOP_mov_t_pr;
02153 CGTARG_Invert_Table[TOP_mov_t_pr] = TOP_mov_f_pr;
02154
02155 CGTARG_Invert_Table[TOP_mov_f_psr] = TOP_mov_t_psr;
02156 CGTARG_Invert_Table[TOP_mov_t_psr] = TOP_mov_f_psr;
02157
02158 CGTARG_Invert_Table[TOP_mov_f_psrum] = TOP_mov_t_psrum;
02159 CGTARG_Invert_Table[TOP_mov_t_psrum] = TOP_mov_f_psrum;
02160
02161
02162
02163 CGTARG_Immed_To_Reg_Table[TOP_addp4_i] = TOP_addp4;
02164 CGTARG_Immed_To_Reg_Table[TOP_adds] = TOP_add;
02165 CGTARG_Immed_To_Reg_Table[TOP_addl] = TOP_add;
02166 CGTARG_Immed_To_Reg_Table[TOP_and_i] = TOP_and;
02167 CGTARG_Immed_To_Reg_Table[TOP_andcm_i] = TOP_andcm;
02168 CGTARG_Immed_To_Reg_Table[TOP_cmp_i_eq] = TOP_cmp_eq;
02169 CGTARG_Immed_To_Reg_Table[TOP_cmp_i_eq_unc] = TOP_cmp_eq_unc;
02170 CGTARG_Immed_To_Reg_Table[TOP_cmp_i_eq_and] = TOP_cmp_eq_and;
02171 CGTARG_Immed_To_Reg_Table[TOP_cmp_i_eq_or] = TOP_cmp_eq_or;
02172 CGTARG_Immed_To_Reg_Table[TOP_cmp_i_eq_or_andcm] = TOP_cmp_eq_or_andcm;
02173 CGTARG_Immed_To_Reg_Table[TOP_cmp_i_ne_and] = TOP_cmp_ne_and;
02174 CGTARG_Immed_To_Reg_Table[TOP_cmp_i_ne_or] = TOP_cmp_ne_or;
02175 CGTARG_Immed_To_Reg_Table[TOP_cmp_i_ne_or_andcm] = TOP_cmp_ne_or_andcm;
02176 CGTARG_Immed_To_Reg_Table[TOP_cmp_i_lt] = TOP_cmp_lt;
02177 CGTARG_Immed_To_Reg_Table[TOP_cmp_i_lt_unc] = TOP_cmp_lt_unc;
02178 CGTARG_Immed_To_Reg_Table[TOP_cmp_i_ltu] = TOP_cmp_ltu;
02179 CGTARG_Immed_To_Reg_Table[TOP_cmp_i_ltu_unc] = TOP_cmp_ltu_unc;
02180 CGTARG_Immed_To_Reg_Table[TOP_cmp_i_eq_orcm] = TOP_cmp_eq_orcm;
02181 CGTARG_Immed_To_Reg_Table[TOP_cmp_i_eq_andcm] = TOP_cmp_eq_andcm;
02182 CGTARG_Immed_To_Reg_Table[TOP_cmp_i_eq_and_orcm] = TOP_cmp_eq_and_orcm;
02183 CGTARG_Immed_To_Reg_Table[TOP_cmp_i_ne] = TOP_cmp_ne;
02184 CGTARG_Immed_To_Reg_Table[TOP_cmp_i_ne_unc] = TOP_cmp_ne_unc;
02185 CGTARG_Immed_To_Reg_Table[TOP_cmp_i_ne_orcm] = TOP_cmp_ne_orcm;
02186 CGTARG_Immed_To_Reg_Table[TOP_cmp_i_ne_andcm] = TOP_cmp_ne_andcm;
02187 CGTARG_Immed_To_Reg_Table[TOP_cmp_i_ne_and_orcm] = TOP_cmp_ne_and_orcm;
02188 CGTARG_Immed_To_Reg_Table[TOP_cmp_i_le] = TOP_cmp_le;
02189 CGTARG_Immed_To_Reg_Table[TOP_cmp_i_le_unc] = TOP_cmp_le_unc;
02190 CGTARG_Immed_To_Reg_Table[TOP_cmp_i_gt] = TOP_cmp_gt;
02191 CGTARG_Immed_To_Reg_Table[TOP_cmp_i_gt_unc] = TOP_cmp_gt_unc;
02192 CGTARG_Immed_To_Reg_Table[TOP_cmp_i_ge] = TOP_cmp_ge;
02193 CGTARG_Immed_To_Reg_Table[TOP_cmp_i_ge_unc] = TOP_cmp_ge_unc;
02194 CGTARG_Immed_To_Reg_Table[TOP_cmp_i_leu] = TOP_cmp_leu;
02195 CGTARG_Immed_To_Reg_Table[TOP_cmp_i_leu_unc] = TOP_cmp_leu_unc;
02196 CGTARG_Immed_To_Reg_Table[TOP_cmp_i_gtu] = TOP_cmp_gtu;
02197 CGTARG_Immed_To_Reg_Table[TOP_cmp_i_gtu_unc] = TOP_cmp_gtu_unc;
02198 CGTARG_Immed_To_Reg_Table[TOP_cmp_i_geu] = TOP_cmp_geu;
02199 CGTARG_Immed_To_Reg_Table[TOP_cmp_i_geu_unc] = TOP_cmp_geu_unc;
02200 CGTARG_Immed_To_Reg_Table[TOP_cmp4_i_eq] = TOP_cmp4_eq;
02201 CGTARG_Immed_To_Reg_Table[TOP_cmp4_i_eq_unc] = TOP_cmp4_eq_unc;
02202 CGTARG_Immed_To_Reg_Table[TOP_cmp4_i_eq_and] = TOP_cmp4_eq_and;
02203 CGTARG_Immed_To_Reg_Table[TOP_cmp4_i_eq_or] = TOP_cmp4_eq_or;
02204 CGTARG_Immed_To_Reg_Table[TOP_cmp4_i_eq_or_andcm] = TOP_cmp4_eq_or_andcm;
02205 CGTARG_Immed_To_Reg_Table[TOP_cmp4_i_ne_and] = TOP_cmp4_ne_and;
02206 CGTARG_Immed_To_Reg_Table[TOP_cmp4_i_ne_or] = TOP_cmp4_ne_or;
02207 CGTARG_Immed_To_Reg_Table[TOP_cmp4_i_ne_or_andcm] = TOP_cmp4_ne_or_andcm;
02208 CGTARG_Immed_To_Reg_Table[TOP_cmp4_i_lt] = TOP_cmp4_lt;
02209 CGTARG_Immed_To_Reg_Table[TOP_cmp4_i_lt_unc] = TOP_cmp4_lt_unc;
02210 CGTARG_Immed_To_Reg_Table[TOP_cmp4_i_ltu] = TOP_cmp4_ltu;
02211 CGTARG_Immed_To_Reg_Table[TOP_cmp4_i_ltu_unc] = TOP_cmp4_ltu_unc;
02212 CGTARG_Immed_To_Reg_Table[TOP_cmp4_i_eq_orcm] = TOP_cmp4_eq_orcm;
02213 CGTARG_Immed_To_Reg_Table[TOP_cmp4_i_eq_andcm] = TOP_cmp4_eq_andcm;
02214 CGTARG_Immed_To_Reg_Table[TOP_cmp4_i_eq_and_orcm] = TOP_cmp4_eq_and_orcm;
02215 CGTARG_Immed_To_Reg_Table[TOP_cmp4_i_ne] = TOP_cmp4_ne;
02216 CGTARG_Immed_To_Reg_Table[TOP_cmp4_i_ne_unc] = TOP_cmp4_ne_unc;
02217 CGTARG_Immed_To_Reg_Table[TOP_cmp4_i_ne_orcm] = TOP_cmp4_ne_orcm;
02218 CGTARG_Immed_To_Reg_Table[TOP_cmp4_i_ne_andcm] = TOP_cmp4_ne_andcm;
02219 CGTARG_Immed_To_Reg_Table[TOP_cmp4_i_ne_and_orcm] = TOP_cmp4_ne_and_orcm;
02220 CGTARG_Immed_To_Reg_Table[TOP_cmp4_i_le] = TOP_cmp4_le;
02221 CGTARG_Immed_To_Reg_Table[TOP_cmp4_i_le_unc] = TOP_cmp4_le_unc;
02222 CGTARG_Immed_To_Reg_Table[TOP_cmp4_i_gt] = TOP_cmp4_gt;
02223 CGTARG_Immed_To_Reg_Table[TOP_cmp4_i_gt_unc] = TOP_cmp4_gt_unc;
02224 CGTARG_Immed_To_Reg_Table[TOP_cmp4_i_ge] = TOP_cmp4_ge;
02225 CGTARG_Immed_To_Reg_Table[TOP_cmp4_i_ge_unc] = TOP_cmp4_ge_unc;
02226 CGTARG_Immed_To_Reg_Table[TOP_cmp4_i_leu] = TOP_cmp4_leu;
02227 CGTARG_Immed_To_Reg_Table[TOP_cmp4_i_leu_unc] = TOP_cmp4_leu_unc;
02228 CGTARG_Immed_To_Reg_Table[TOP_cmp4_i_gtu] = TOP_cmp4_gtu;
02229 CGTARG_Immed_To_Reg_Table[TOP_cmp4_i_gtu_unc] = TOP_cmp4_gtu_unc;
02230 CGTARG_Immed_To_Reg_Table[TOP_cmp4_i_geu] = TOP_cmp4_geu;
02231 CGTARG_Immed_To_Reg_Table[TOP_cmp4_i_geu_unc] = TOP_cmp4_geu_unc;
02232 CGTARG_Immed_To_Reg_Table[TOP_ld1_i] = TOP_ld1_r;
02233 CGTARG_Immed_To_Reg_Table[TOP_ld2_i] = TOP_ld2_r;
02234 CGTARG_Immed_To_Reg_Table[TOP_ld4_i] = TOP_ld4_r;
02235 CGTARG_Immed_To_Reg_Table[TOP_ld8_i] = TOP_ld8_r;
02236 CGTARG_Immed_To_Reg_Table[TOP_ld8_i_fill] = TOP_ld8_r_fill;
02237 CGTARG_Immed_To_Reg_Table[TOP_ldfs_i] = TOP_ldfs_r;
02238 CGTARG_Immed_To_Reg_Table[TOP_ldfd_i] = TOP_ldfd_r;
02239 CGTARG_Immed_To_Reg_Table[TOP_ldfe_i] = TOP_ldfe_r;
02240 CGTARG_Immed_To_Reg_Table[TOP_ldf8_i] = TOP_ldf8_r;
02241 CGTARG_Immed_To_Reg_Table[TOP_ldf_i_fill] = TOP_ldf_r_fill;
02242 CGTARG_Immed_To_Reg_Table[TOP_lfetch_i] = TOP_lfetch_r;
02243 CGTARG_Immed_To_Reg_Table[TOP_lfetch_i_excl] = TOP_lfetch_r_excl;
02244 CGTARG_Immed_To_Reg_Table[TOP_lfetch_i_fault] = TOP_lfetch_r_fault;
02245 CGTARG_Immed_To_Reg_Table[TOP_lfetch_i_fault_excl] = TOP_lfetch_r_fault_excl;
02246 CGTARG_Immed_To_Reg_Table[TOP_mov_t_ar_i] = TOP_mov_t_ar_r;
02247 CGTARG_Immed_To_Reg_Table[TOP_or_i] = TOP_or;
02248 CGTARG_Immed_To_Reg_Table[TOP_probe_i_r] = TOP_probe_r;
02249 CGTARG_Immed_To_Reg_Table[TOP_probe_i_w] = TOP_probe_w;
02250 CGTARG_Immed_To_Reg_Table[TOP_pshl2_i] = TOP_pshl2;
02251 CGTARG_Immed_To_Reg_Table[TOP_pshl4_i] = TOP_pshl4;
02252 CGTARG_Immed_To_Reg_Table[TOP_pshr2_i] = TOP_pshr2;
02253 CGTARG_Immed_To_Reg_Table[TOP_pshr2_i_u] = TOP_pshr2_u;
02254 CGTARG_Immed_To_Reg_Table[TOP_pshr4_i] = TOP_pshr4;
02255 CGTARG_Immed_To_Reg_Table[TOP_pshr4_i_u] = TOP_pshr4_u;
02256 CGTARG_Immed_To_Reg_Table[TOP_shl_i] = TOP_shl;
02257 CGTARG_Immed_To_Reg_Table[TOP_shr_i] = TOP_shr;
02258 CGTARG_Immed_To_Reg_Table[TOP_shr_i_u] = TOP_shr_u;
02259 CGTARG_Immed_To_Reg_Table[TOP_sub_i] = TOP_sub;
02260 CGTARG_Immed_To_Reg_Table[TOP_xor_i] = TOP_xor;
02261
02262
02263
02264 CGTARG_Inter_RegClass_Copy_Table[ISA_REGISTER_CLASS_float]
02265 [ISA_REGISTER_CLASS_integer]
02266 [FALSE] = TOP_getf_s;
02267 CGTARG_Inter_RegClass_Copy_Table[ISA_REGISTER_CLASS_float]
02268 [ISA_REGISTER_CLASS_integer]
02269 [TRUE] = TOP_getf_d;
02270 CGTARG_Inter_RegClass_Copy_Table[ISA_REGISTER_CLASS_application]
02271 [ISA_REGISTER_CLASS_integer]
02272 [FALSE] = TOP_mov_f_ar;
02273 CGTARG_Inter_RegClass_Copy_Table[ISA_REGISTER_CLASS_branch]
02274 [ISA_REGISTER_CLASS_integer]
02275 [FALSE] = TOP_mov_f_br;
02276 CGTARG_Inter_RegClass_Copy_Table[ISA_REGISTER_CLASS_control]
02277 [ISA_REGISTER_CLASS_integer]
02278 [FALSE] = TOP_mov_f_cr;
02279
02280 CGTARG_Inter_RegClass_Copy_Table[ISA_REGISTER_CLASS_integer]
02281 [ISA_REGISTER_CLASS_float]
02282 [FALSE] = TOP_setf_s;
02283 CGTARG_Inter_RegClass_Copy_Table[ISA_REGISTER_CLASS_integer]
02284 [ISA_REGISTER_CLASS_float]
02285 [TRUE] = TOP_setf_d;
02286 CGTARG_Inter_RegClass_Copy_Table[ISA_REGISTER_CLASS_integer]
02287 [ISA_REGISTER_CLASS_application]
02288 [FALSE] = TOP_mov_t_ar_r;
02289 CGTARG_Inter_RegClass_Copy_Table[ISA_REGISTER_CLASS_integer]
02290 [ISA_REGISTER_CLASS_branch]
02291 [FALSE] = TOP_mov_t_br;
02292 CGTARG_Inter_RegClass_Copy_Table[ISA_REGISTER_CLASS_integer]
02293 [ISA_REGISTER_CLASS_control]
02294 [FALSE] = TOP_mov_t_cr;
02295
02296
02297 CGTARG_f0_unit_id = (SI_RESOURCE_ID) -1;
02298 for (SI_RESOURCE_ID res_id = 0; res_id < SI_resource_count; ++res_id) {
02299 if (strcmp("floating-point0", SI_RESOURCE_ID_Name(res_id)) == 0)
02300 CGTARG_f0_unit_id = res_id;
02301 }
02302 }
02303
02304
02305
02306
02307
02308
02309
02310
02311
02312
02313 void CGTARG_Load_From_Memory(TN *tn, ST *mem_loc, OPS *ops)
02314 {
02315 TYPE_ID mtype = TY_mtype(ST_type(mem_loc));
02316
02317 if (TN_register_class(tn) == ISA_REGISTER_CLASS_predicate) {
02318
02319
02320
02321
02322 TN *temp_tn = Build_TN_Of_Mtype (MTYPE_I8);
02323 Exp_Load (mtype, mtype, temp_tn, mem_loc, 0, ops, V_NONE);
02324 Build_OP (TOP_cmp_i_ne, tn, True_TN,
02325 True_TN, Gen_Literal_TN(0, 4), temp_tn, ops);
02326 }
02327 else if (TN_register_class(tn) == ISA_REGISTER_CLASS_branch) {
02328
02329 TN *temp_tn = Build_TN_Of_Mtype (MTYPE_I8);
02330 Exp_Load (mtype, mtype, temp_tn, mem_loc, 0, ops, V_NONE);
02331 Build_OP (TOP_mov_t_br, tn, True_TN, temp_tn, ops);
02332 }
02333 else {
02334
02335
02336
02337 Exp_Load (mtype, mtype, tn, mem_loc, 0, ops, V_NONE);
02338 }
02339 }
02340
02341
02342
02343
02344
02345
02346
02347
02348
02349
02350 void CGTARG_Store_To_Memory(TN *tn, ST *mem_loc, OPS *ops)
02351 {
02352 TYPE_ID mtype = TY_mtype(ST_type(mem_loc));
02353
02354 if (TN_register_class(tn) == ISA_REGISTER_CLASS_predicate) {
02355
02356
02357
02358 TN *temp_tn = Build_TN_Of_Mtype (MTYPE_I8);
02359 Build_OP (TOP_mov, temp_tn, True_TN, Zero_TN, ops);
02360 Build_OP (TOP_mov_i, temp_tn, tn, Gen_Literal_TN(1, 4), ops);
02361 Exp_Store (mtype, temp_tn, mem_loc, 0, ops, V_NONE);
02362 }
02363 else if (TN_register_class(tn) == ISA_REGISTER_CLASS_branch) {
02364
02365 TN *temp_tn = Build_TN_Of_Mtype (MTYPE_I8);
02366 Build_OP (TOP_mov_f_br, temp_tn, True_TN, tn, ops);
02367 Exp_Store (mtype, temp_tn, mem_loc, 0, ops, V_NONE);
02368 }
02369 else {
02370
02371
02372
02373 Exp_Store (mtype, tn, mem_loc, 0, ops, V_NONE);
02374 }
02375 }
02376
02377
02378
02379
02380
02381
02382
02383
02384
02385
02386 void CGTARG_Init_Assoc_Base(void)
02387 {
02388 INT i;
02389 OPCODE * const oprs = CGTARG_Assoc_Base_Opr_Table;
02390 mTOP * const fncs = CGTARG_Assoc_Base_Fnc_Table;
02391 mTOP * const tops = CGTARG_Assoc_Base_Top_Table;
02392
02393 for(i = 0; i < TOP_count; i++) {
02394 oprs[i] = (OPCODE)0;
02395 fncs[i] = ASSOC_BASE_null;
02396 tops[i] = TOP_UNDEFINED;
02397 }
02398
02399
02400
02401 oprs[TOP_add] = OPC_U4ADD; tops[TOP_add] = TOP_add;
02402 oprs[TOP_addl] = OPC_U4ADD; tops[TOP_addl] = TOP_add;
02403 oprs[TOP_adds] = OPC_U4ADD; tops[TOP_adds] = TOP_add;
02404 oprs[TOP_or] = OPC_U8BIOR; tops[TOP_or] = TOP_or;
02405 oprs[TOP_or_i] = OPC_U8BIOR; tops[TOP_or_i] = TOP_or;
02406 oprs[TOP_and] = OPC_U8BAND; tops[TOP_and] = TOP_and;
02407 oprs[TOP_and_i] = OPC_U8BAND; tops[TOP_and_i] = TOP_and;
02408 oprs[TOP_xor] = OPC_U8BXOR; tops[TOP_xor] = TOP_xor;
02409 oprs[TOP_xor_i] = OPC_U8BXOR; tops[TOP_xor_i] = TOP_xor;
02410 oprs[TOP_sub] = OPC_U4ADD; tops[TOP_sub] = TOP_add;
02411 fncs[TOP_sub] = ASSOC_BASE_inverse;
02412
02413 if (Roundoff_Level >= ROUNDOFF_ASSOC) {
02414
02415
02416
02417
02418 oprs[TOP_fadd_s] = OPC_F4ADD; tops[TOP_fadd_s] = TOP_fadd_s;
02419 oprs[TOP_fadd_d] = OPC_F8ADD; tops[TOP_fadd_d] = TOP_fadd_d;
02420 oprs[TOP_fadd ] = OPC_F10ADD; tops[TOP_fadd ] = TOP_fadd ;
02421 oprs[TOP_fmpy_s] = OPC_F4MPY; tops[TOP_fmpy_s] = TOP_fmpy_s;
02422 oprs[TOP_fmpy_d] = OPC_F8MPY; tops[TOP_fmpy_d] = TOP_fmpy_d;
02423 oprs[TOP_fmpy ] = OPC_F10MPY; tops[TOP_fmpy ] = TOP_fmpy ;
02424
02425
02426
02427
02428 oprs[TOP_fma_s] = OPC_F4ADD; tops[TOP_fma_s] = TOP_fadd_s;
02429 oprs[TOP_fma_d] = OPC_F8ADD; tops[TOP_fma_d] = TOP_fadd_d;
02430 oprs[TOP_fma ] = OPC_F10ADD; tops[TOP_fma ] = TOP_fadd ;
02431
02432
02433
02434
02435
02436
02437 oprs[TOP_fsub_s] = OPC_F4ADD; tops[TOP_fsub_s] = TOP_fadd_s;
02438 fncs[TOP_fsub_s] = ASSOC_BASE_inverse;
02439 oprs[TOP_fsub_d] = OPC_F8ADD; tops[TOP_fsub_d] = TOP_fadd_d;
02440 fncs[TOP_fsub_d] = ASSOC_BASE_inverse;
02441 oprs[TOP_fsub ] = OPC_F10ADD; tops[TOP_fsub ] = TOP_fadd;
02442 fncs[TOP_fsub ] = ASSOC_BASE_inverse;
02443 oprs[TOP_fnma_s] = OPC_F4ADD; tops[TOP_fnma_s] = TOP_fadd_s;
02444 fncs[TOP_fnma_s] = ASSOC_BASE_inverse;
02445 oprs[TOP_fnma_d] = OPC_F8ADD; tops[TOP_fnma_d] = TOP_fadd_d;
02446 fncs[TOP_fnma_d] = ASSOC_BASE_inverse;
02447 oprs[TOP_fnma ] = OPC_F10ADD; tops[TOP_fnma ] = TOP_fadd;
02448 fncs[TOP_fnma ] = ASSOC_BASE_inverse;
02449 }
02450
02451
02452
02453
02454
02455 oprs[TOP_xma_l] = OPC_I8MPY; tops[TOP_xma_l] = TOP_xma_l;
02456 fncs[TOP_xma_l] = ASSOC_BASE_imul;
02457 oprs[TOP_xma_lu] = OPC_U8MPY; tops[TOP_xma_lu] = TOP_xma_lu;
02458 fncs[TOP_xma_lu] = ASSOC_BASE_imul;
02459 }
02460
02461
02462
02463
02464
02465
02466
02467
02468
02469
02470 INT CGTARG_Copy_Operand(OP *op)
02471 {
02472 TOP opr = OP_code(op);
02473 switch (opr) {
02474
02475
02476
02477
02478 case TOP_adds:
02479 case TOP_addl:
02480 case TOP_or_i:
02481 case TOP_xor_i:
02482 if (TN_has_value(OP_opnd(op,1)) && TN_value(OP_opnd(op,1)) == 0) {
02483 return 2;
02484 }
02485 break;
02486
02487 case TOP_add:
02488 case TOP_or:
02489 case TOP_xor:
02490 if (TN_register_and_class(OP_opnd(op,2)) == CLASS_AND_REG_zero) {
02491 return 1;
02492 }
02493 if (TN_register_and_class(OP_opnd(op,1)) == CLASS_AND_REG_zero) {
02494 return 2;
02495 }
02496 break;
02497
02498 case TOP_andcm:
02499 case TOP_sub:
02500 if (TN_register_and_class(OP_opnd(op,2)) == CLASS_AND_REG_zero) {
02501 return 1;
02502 }
02503 break;
02504
02505 case TOP_and_i:
02506 if (TN_has_value(OP_opnd(op,1)) && TN_value(OP_opnd(op,1)) == -1) {
02507 return 2;
02508 }
02509 break;
02510
02511 case TOP_extr:
02512 case TOP_extr_u:
02513 if ( TN_has_value(OP_opnd(op,2)) && TN_value(OP_opnd(op,2)) == 0
02514 && TN_has_value(OP_opnd(op,3)) && TN_value(OP_opnd(op,3)) == 64)
02515 {
02516 return 1;
02517 }
02518 break;
02519
02520 case TOP_shl_i:
02521 case TOP_shr_i:
02522 case TOP_shr_i_u:
02523 if ( (TN_register_and_class(OP_opnd(op,1)) == CLASS_AND_REG_zero)
02524 || (TN_has_value(OP_opnd(op,2)) && TN_value(OP_opnd(op,2)) == 0))
02525 {
02526 return 1;
02527 }
02528 break;
02529
02530 case TOP_shl:
02531 case TOP_shr:
02532 case TOP_shr_u:
02533 if ( (TN_register_and_class(OP_opnd(op,1)) == CLASS_AND_REG_zero)
02534 || (TN_register_and_class(OP_opnd(op,2)) == CLASS_AND_REG_zero))
02535 {
02536 return 1;
02537 }
02538 break;
02539
02540 case TOP_mov:
02541 case TOP_mov_f:
02542 case TOP_copy_br:
02543 return 1;
02544 }
02545 return -1;
02546 }
02547
02548
02549
02550
02551
02552
02553
02554
02555
02556
02557 BOOL
02558 CGTARG_Can_Fit_Immediate_In_Add_Instruction (INT64 immed)
02559 {
02560 return ISA_LC_Value_In_Class (immed, LC_i14);
02561 }
02562
02563
02564
02565
02566
02567
02568
02569
02570
02571
02572 BOOL
02573 CGTARG_Can_Load_Immediate_In_Single_Instruction (INT64 immed)
02574 {
02575 return ISA_LC_Value_In_Class (immed, LC_i22);
02576 }
02577
02578
02579
02580
02581
02582
02583
02584
02585
02586
02587
02588
02589 void
02590 CGTARG_Predicate_OP(BB* bb, OP* op, TN* pred_tn)
02591 {
02592 if (OP_has_predicate(op)) {
02593 Set_OP_opnd(op, OP_PREDICATE_OPND, pred_tn);
02594 }
02595 }
02596
02597
02598
02599
02600
02601
02602
02603
02604
02605 BOOL
02606 CGTARG_Branches_On_True(OP* br_op, OP* cmp_op)
02607 {
02608 if (OP_opnd(br_op, OP_PREDICATE_OPND) == OP_result(cmp_op, 0)) {
02609 return TRUE;
02610 }
02611 return FALSE;
02612 }
02613
02614
02615
02616
02617
02618
02619
02620
02621
02622
02623
02624 TOP
02625 CGTARG_Parallel_Compare(OP* cmp_op, COMPARE_TYPE ctype)
02626 {
02627
02628
02629
02630
02631
02632 if (OP_flop(cmp_op)) {
02633 return TOP_UNDEFINED;
02634 }
02635
02636 TOP cmp_top = OP_code(cmp_op);
02637 if (OP_opnd(cmp_op, 1) != Zero_TN && OP_opnd(cmp_op, 2) != Zero_TN) {
02638 switch (cmp_top) {
02639 case TOP_cmp_ne:
02640 case TOP_cmp4_ne:
02641 case TOP_cmp_i_ne:
02642 case TOP_cmp4_i_eq:
02643 case TOP_cmp4_eq:
02644 case TOP_cmp_i_eq:
02645 case TOP_cmp_eq:
02646 break;
02647 default:
02648 return TOP_UNDEFINED;
02649 }
02650 }
02651 switch (cmp_top) {
02652 case TOP_cmp_ne:
02653 case TOP_cmp_ne_unc:
02654 switch (ctype) {
02655 case COMPARE_TYPE_or:
02656 return TOP_cmp_ne_or;
02657 case COMPARE_TYPE_orcm:
02658 return TOP_cmp_ne_orcm;
02659 case COMPARE_TYPE_and:
02660 return TOP_cmp_ne_and;
02661 case COMPARE_TYPE_andcm:
02662 return TOP_cmp_ne_andcm;
02663 case COMPARE_TYPE_or_andcm:
02664 return TOP_cmp_ne_or_andcm;
02665 case COMPARE_TYPE_and_orcm:
02666 return TOP_cmp_ne_and_orcm;
02667 }
02668
02669 case TOP_cmp4_ne:
02670 case TOP_cmp4_ne_unc:
02671 switch (ctype) {
02672 case COMPARE_TYPE_or:
02673 return TOP_cmp4_ne_or;
02674 case COMPARE_TYPE_orcm:
02675 return TOP_cmp4_ne_orcm;
02676 case COMPARE_TYPE_and:
02677 return TOP_cmp4_ne_and;
02678 case COMPARE_TYPE_andcm:
02679 return TOP_cmp4_ne_andcm;
02680 case COMPARE_TYPE_or_andcm:
02681 return TOP_cmp4_ne_or_andcm;
02682 case COMPARE_TYPE_and_orcm:
02683 return TOP_cmp4_ne_and_orcm;
02684 }
02685
02686 case TOP_cmp_i_ne:
02687 switch (ctype) {
02688 case COMPARE_TYPE_or:
02689 return TOP_cmp_i_ne_or;
02690 case COMPARE_TYPE_orcm:
02691 return TOP_cmp_i_ne_orcm;
02692 case COMPARE_TYPE_and:
02693 return TOP_cmp_i_ne_and;
02694 case COMPARE_TYPE_andcm:
02695 return TOP_cmp_i_ne_andcm;
02696 case COMPARE_TYPE_or_andcm:
02697 return TOP_cmp_i_ne_or_andcm;
02698 }
02699
02700 case TOP_cmp4_ge:
02701 case TOP_cmp4_ge_unc:
02702 switch (ctype) {
02703 case COMPARE_TYPE_or:
02704 return TOP_cmp4_ge_or;
02705 case COMPARE_TYPE_orcm:
02706 return TOP_cmp4_ge_orcm;
02707 case COMPARE_TYPE_and:
02708 return TOP_cmp4_ge_and;
02709 case COMPARE_TYPE_andcm:
02710 return TOP_cmp4_ge_andcm;
02711 case COMPARE_TYPE_or_andcm:
02712 return TOP_cmp4_ge_or_andcm;
02713 }
02714
02715 case TOP_cmp4_gt:
02716 case TOP_cmp4_gt_unc:
02717 switch (ctype) {
02718 case COMPARE_TYPE_or:
02719 return TOP_cmp4_gt_or;
02720 case COMPARE_TYPE_orcm:
02721 return TOP_cmp4_gt_orcm;
02722 case COMPARE_TYPE_and:
02723 return TOP_cmp4_gt_and;
02724 case COMPARE_TYPE_andcm:
02725 return TOP_cmp4_gt_andcm;
02726 case COMPARE_TYPE_or_andcm:
02727 return TOP_cmp4_gt_or_andcm;
02728 }
02729
02730 case TOP_cmp4_le:
02731 case TOP_cmp4_le_unc:
02732 switch (ctype) {
02733 case COMPARE_TYPE_or:
02734 return TOP_cmp4_le_or;
02735 case COMPARE_TYPE_orcm:
02736 return TOP_cmp4_le_orcm;
02737 case COMPARE_TYPE_and:
02738 return TOP_cmp4_le_and;
02739 case COMPARE_TYPE_andcm:
02740 return TOP_cmp4_le_andcm;
02741 case COMPARE_TYPE_or_andcm:
02742 return TOP_cmp4_le_or_andcm;
02743 }
02744
02745 case TOP_cmp4_lt:
02746 case TOP_cmp4_lt_unc:
02747 switch (ctype) {
02748 case COMPARE_TYPE_or:
02749 return TOP_cmp4_lt_or;
02750 case COMPARE_TYPE_orcm:
02751 return TOP_cmp4_lt_orcm;
02752 case COMPARE_TYPE_and:
02753 return TOP_cmp4_lt_and;
02754 case COMPARE_TYPE_andcm:
02755 return TOP_cmp4_lt_andcm;
02756 case COMPARE_TYPE_or_andcm:
02757 return TOP_cmp4_lt_or_andcm;
02758 }
02759
02760 case TOP_cmp_ge:
02761 case TOP_cmp_ge_unc:
02762 switch (ctype) {
02763 case COMPARE_TYPE_or:
02764 return TOP_cmp_ge_or;
02765 case COMPARE_TYPE_orcm:
02766 return TOP_cmp_ge_orcm;
02767 case COMPARE_TYPE_and:
02768 return TOP_cmp_ge_and;
02769 case COMPARE_TYPE_andcm:
02770 return TOP_cmp_ge_andcm;
02771 case COMPARE_TYPE_or_andcm:
02772 return TOP_cmp_ge_or_andcm;
02773 }
02774
02775 case TOP_cmp_gt:
02776 case TOP_cmp_gt_unc:
02777 switch (ctype) {
02778 case COMPARE_TYPE_or:
02779 return TOP_cmp_gt_or;
02780 case COMPARE_TYPE_orcm:
02781 return TOP_cmp_gt_orcm;
02782 case COMPARE_TYPE_and:
02783 return TOP_cmp_gt_and;
02784 case COMPARE_TYPE_andcm:
02785 return TOP_cmp_gt_andcm;
02786 case COMPARE_TYPE_or_andcm:
02787 return TOP_cmp_gt_or_andcm;
02788 }
02789
02790 case TOP_cmp_le:
02791 case TOP_cmp_le_unc:
02792 switch (ctype) {
02793 case COMPARE_TYPE_or:
02794 return TOP_cmp_le_or;
02795 case COMPARE_TYPE_orcm:
02796 return TOP_cmp_le_orcm;
02797 case COMPARE_TYPE_and:
02798 return TOP_cmp_le_and;
02799 case COMPARE_TYPE_andcm:
02800 return TOP_cmp_le_andcm;
02801 case COMPARE_TYPE_or_andcm:
02802 return TOP_cmp_le_or_andcm;
02803 }
02804
02805 case TOP_cmp_lt:
02806 case TOP_cmp_lt_unc:
02807 switch (ctype) {
02808 case COMPARE_TYPE_or:
02809 return TOP_cmp_lt_or;
02810 case COMPARE_TYPE_orcm:
02811 return TOP_cmp_lt_orcm;
02812 case COMPARE_TYPE_and:
02813 return TOP_cmp_lt_and;
02814 case COMPARE_TYPE_andcm:
02815 return TOP_cmp_lt_andcm;
02816 case COMPARE_TYPE_or_andcm:
02817 return TOP_cmp_lt_or_andcm;
02818 }
02819
02820 case TOP_cmp4_i_eq:
02821 case TOP_cmp4_i_eq_unc:
02822 switch (ctype) {
02823 case COMPARE_TYPE_or:
02824 return TOP_cmp4_i_eq_or;
02825 case COMPARE_TYPE_orcm:
02826 return TOP_cmp4_i_eq_orcm;
02827 case COMPARE_TYPE_and:
02828 return TOP_cmp4_i_eq_and;
02829 case COMPARE_TYPE_andcm:
02830 return TOP_cmp4_i_eq_andcm;
02831 case COMPARE_TYPE_or_andcm:
02832 return TOP_cmp4_i_eq_or_andcm;
02833 }
02834
02835
02836 case TOP_cmp4_eq:
02837 case TOP_cmp4_eq_unc:
02838 switch (ctype) {
02839 case COMPARE_TYPE_or:
02840 return TOP_cmp4_eq_or;
02841 case COMPARE_TYPE_orcm:
02842 return TOP_cmp4_eq_orcm;
02843 case COMPARE_TYPE_and:
02844 return TOP_cmp4_eq_and;
02845 case COMPARE_TYPE_andcm:
02846 return TOP_cmp4_eq_andcm;
02847 case COMPARE_TYPE_or_andcm:
02848 return TOP_cmp4_eq_or_andcm;
02849 }
02850
02851 case TOP_cmp_i_eq:
02852 case TOP_cmp_i_eq_unc:
02853 switch (ctype) {
02854 case COMPARE_TYPE_or:
02855 return TOP_cmp_i_eq_or;
02856 case COMPARE_TYPE_orcm:
02857 return TOP_cmp_i_eq_orcm;
02858 case COMPARE_TYPE_and:
02859 return TOP_cmp_i_eq_and;
02860 case COMPARE_TYPE_andcm:
02861 return TOP_cmp_i_eq_andcm;
02862 case COMPARE_TYPE_or_andcm:
02863 return TOP_cmp_i_eq_or_andcm;
02864 }
02865
02866 case TOP_cmp_eq:
02867 case TOP_cmp_eq_unc:
02868 switch (ctype) {
02869 case COMPARE_TYPE_or:
02870 return TOP_cmp_eq_or;
02871 case COMPARE_TYPE_orcm:
02872 return TOP_cmp_eq_orcm;
02873 case COMPARE_TYPE_and:
02874 return TOP_cmp_eq_and;
02875 case COMPARE_TYPE_andcm:
02876 return TOP_cmp_eq_andcm;
02877 case COMPARE_TYPE_or_andcm:
02878 return TOP_cmp_eq_or_andcm;
02879 }
02880
02881 }
02882
02883 return TOP_UNDEFINED;
02884 }
02885
02886 BOOL
02887 OP_def_use_stack_regs(OP* op)
02888 {
02889 for (INT i = 0; i < OP_results(op); i++) {
02890 TN *tn = OP_result(op,i);
02891 if (TN_is_register(tn) &&
02892 REGISTER_Is_Stacked(TN_register_class(tn), TN_register(tn))) {
02893 return TRUE;
02894 }
02895 }
02896
02897 for (INT i = 0; i < OP_opnds(op); i++) {
02898 TN* tn = OP_opnd(op,i);
02899 if (TN_is_register(tn) &&
02900 REGISTER_Is_Stacked(TN_register_class(tn), TN_register(tn))) {
02901 return TRUE;
02902 }
02903 }
02904
02905 return FALSE;
02906 }
02907
02908 BOOL
02909 OP_use_sp(OP* op)
02910 {
02911 for (INT i = 0; i < OP_opnds(op); i++) {
02912 TN* tn = OP_opnd(op,i);
02913 if (TN_is_register(tn) &&
02914 TN_is_sp_reg(tn)) {
02915 return TRUE;
02916 }
02917 }
02918
02919 return FALSE;
02920 }
02921
02922
02923
02924
02925
02926
02927
02928
02929
02930 BOOL
02931 CGTARG_Dependence_Required(OP *pred_op, OP *succ_op)
02932 {
02933
02934 BOOL read_write_rotating_all,
02935 read_write_rotating_predicate,
02936
02937 write_rotating_predicate,
02938
02939 read_write_predicate,
02940 write_predicate,
02941 read_write_status_field,
02942
02943 read_write_unat ;
02944
02945 read_write_rotating_all = FALSE;
02946 read_write_rotating_predicate = FALSE;
02947 write_rotating_predicate = FALSE;
02948 read_write_predicate = FALSE;
02949 write_predicate = FALSE;
02950 read_write_status_field = FALSE;
02951 read_write_unat = FALSE ;
02952
02953 OP *hazard_op = NULL;
02954
02955
02956
02957
02958
02959
02960
02961
02962
02963
02964
02965
02966
02967
02968
02969
02970
02971
02972
02973
02974 switch (OP_code(pred_op)) {
02975 case TOP_alloc:
02976 hazard_op = pred_op;
02977 break;
02978 case TOP_spadjust:
02979 hazard_op = pred_op;
02980 break;
02981 case TOP_clrrrb:
02982 case TOP_clrrrb_pr:
02983 read_write_rotating_all = TRUE;
02984 hazard_op = pred_op;
02985 break;
02986 case TOP_mov_t_pr_i:
02987 read_write_rotating_predicate = TRUE;
02988 hazard_op = pred_op;
02989 break;
02990 case TOP_mov_t_pr:
02991 read_write_rotating_predicate = TRUE;
02992 read_write_predicate = TRUE;
02993 hazard_op = pred_op;
02994 break;
02995 case TOP_mov_f_pr:
02996 write_rotating_predicate = TRUE;
02997 write_predicate = TRUE;
02998 hazard_op = pred_op;
02999 break;
03000 case TOP_fsetc:
03001 read_write_status_field = TRUE;
03002 hazard_op = pred_op;
03003 break;
03004
03005 case TOP_st8_spill:
03006 case TOP_mov_f_ar:
03007 case TOP_mov_f_ar_m:
03008 case TOP_ld8_fill:
03009 case TOP_mov_t_ar_r:
03010 case TOP_mov_t_ar_r_m:
03011 read_write_unat = TRUE ;
03012 hazard_op = pred_op ;
03013 break ;
03014
03015 default:
03016 switch (OP_code(succ_op)) {
03017 case TOP_spadjust:
03018 hazard_op = succ_op;
03019 break;
03020 case TOP_clrrrb:
03021 case TOP_clrrrb_pr:
03022 read_write_rotating_all = TRUE;
03023 hazard_op = succ_op;
03024 break;
03025 case TOP_mov_t_pr_i:
03026 read_write_rotating_predicate = TRUE;
03027 hazard_op = succ_op;
03028 break;
03029 case TOP_mov_t_pr:
03030 read_write_rotating_predicate = TRUE;
03031 read_write_predicate = TRUE;
03032 hazard_op = succ_op;
03033 break;
03034 case TOP_mov_f_pr:
03035 write_rotating_predicate = TRUE;
03036 write_predicate = TRUE;
03037 hazard_op = succ_op;
03038 break;
03039 case TOP_fsetc:
03040 read_write_status_field = TRUE;
03041 hazard_op = succ_op;
03042 break;
03043 }
03044 break;
03045 }
03046
03047 if (hazard_op) {
03048 OP *other_op = (hazard_op == pred_op) ? succ_op : pred_op;
03049
03050 if ((OP_code(hazard_op) == TOP_alloc && OP_def_use_stack_regs(other_op)) ||
03051 (OP_code(hazard_op) == TOP_spadjust && OP_use_sp(other_op)))
03052 return TRUE;
03053
03054
03055 if (read_write_unat) {
03056 mTOP hazard_op_code = OP_code (hazard_op) ;
03057 mTOP other_op_code = OP_code (other_op) ;
03058
03059 if (hazard_op_code == TOP_mov_f_ar_m) hazard_op_code = TOP_mov_f_ar;
03060 if (hazard_op_code == TOP_mov_t_ar_r_m) hazard_op_code = TOP_mov_t_ar_r;
03061 if (other_op_code == TOP_mov_f_ar_m) other_op_code = TOP_mov_f_ar;
03062 if (other_op_code == TOP_mov_t_ar_r_m) other_op_code = TOP_mov_t_ar_r;
03063
03064 if (hazard_op_code == TOP_st8_spill && other_op_code == TOP_mov_f_ar ||
03065 hazard_op_code == TOP_mov_f_ar && other_op_code == TOP_st8_spill ||
03066 hazard_op_code == TOP_ld8_fill && other_op_code == TOP_st8_spill ||
03067 hazard_op_code == TOP_st8_spill && other_op_code == TOP_ld8_fill ||
03068 hazard_op_code == TOP_ld8_fill && other_op_code == TOP_ld8_fill ||
03069 hazard_op_code == TOP_st8_spill && other_op_code == TOP_st8_spill ||
03070 hazard_op_code == TOP_mov_t_ar_r && other_op_code == TOP_ld8_fill ||
03071 hazard_op_code == TOP_ld8_fill && other_op_code == TOP_mov_t_ar_r)
03072 {
03073 return TRUE;
03074 }
03075 }
03076
03077
03078
03079
03080
03081
03082
03083
03084 if ((read_write_rotating_predicate ||
03085 read_write_predicate ||
03086 write_rotating_predicate ||
03087 write_predicate) && OP_code(other_op) == TOP_spadjust)
03088 return TRUE;
03089
03090
03091
03092
03093 if ((read_write_rotating_all ||
03094 read_write_rotating_predicate ||
03095 write_rotating_predicate) && OP_access_reg_bank(other_op))
03096 return TRUE;
03097
03098
03099
03100
03101 TN *status_field;
03102 if (read_write_status_field) {
03103 status_field = OP_opnd(hazard_op, 1);
03104 if (OP_code(other_op) == TOP_fsetc &&
03105 TN_enum(status_field) == ECV_sf_s0) return TRUE;
03106 }
03107
03108 INT k;
03109 for (k = 0; k < OP_opnds(other_op); k++) {
03110 TN *opnd_tn = OP_opnd(other_op, k);
03111
03112 if (TN_is_constant(opnd_tn)) {
03113 if (read_write_status_field &&
03114 TN_is_enum(opnd_tn) &&
03115 TN_enum(opnd_tn) == TN_enum(status_field)) return TRUE;
03116 continue;
03117 }
03118
03119 if (TN_is_const_reg(opnd_tn)) continue;
03120
03121 REGISTER reg = TN_register(opnd_tn);
03122 ISA_REGISTER_CLASS reg_class = TN_register_class(opnd_tn);
03123
03124 if (read_write_predicate &&
03125 reg_class == ISA_REGISTER_CLASS_predicate) return TRUE;
03126
03127 if (reg == REGISTER_UNDEFINED) continue;
03128
03129 if (read_write_rotating_all &&
03130 REGISTER_Is_Rotating(reg_class, reg)) return TRUE;
03131
03132 if (read_write_rotating_predicate &&
03133 reg_class == ISA_REGISTER_CLASS_predicate &&
03134 REGISTER_Is_Rotating(reg_class, reg)) return TRUE;
03135 }
03136
03137 for (k = 0; k < OP_results(other_op); k++) {
03138 TN *result_tn = OP_result(other_op, k);
03139
03140 if (TN_is_const_reg(result_tn)) continue;
03141
03142 REGISTER reg = TN_register(result_tn);
03143 ISA_REGISTER_CLASS reg_class = TN_register_class(result_tn);
03144
03145
03146
03147 if (write_predicate &&
03148 reg_class == ISA_REGISTER_CLASS_predicate) return TRUE;
03149
03150 if (reg == REGISTER_UNDEFINED) continue;
03151
03152 if (read_write_rotating_all &&
03153 REGISTER_Is_Rotating(reg_class, reg)) return TRUE;
03154
03155 if (((read_write_rotating_predicate || write_rotating_predicate) &&
03156 reg_class == ISA_REGISTER_CLASS_predicate) &&
03157 REGISTER_Is_Rotating(reg_class, reg)) return TRUE;
03158 }
03159 }
03160
03161
03162
03163
03164
03165
03166
03167
03168
03169
03170
03171
03172
03173
03174
03175
03176
03177
03178
03179
03180
03181
03182
03183 if (OP_code(pred_op) == TOP_alloc &&
03184 (OP_code(succ_op) == TOP_flushrs ||
03185 OP_code(succ_op) == TOP_br_cexit ||
03186 OP_code(succ_op) == TOP_br_ctop ||
03187 OP_code(succ_op) == TOP_br_wexit ||
03188 OP_code(succ_op) == TOP_br_wtop ||
03189 OP_code(succ_op) == TOP_br_call ||
03190 OP_code(succ_op) == TOP_br_ia ||
03191 OP_code(succ_op) == TOP_br_ret ||
03192 OP_code(succ_op) == TOP_cover ||
03193 OP_code(succ_op) == TOP_rfi ||
03194 OP_code(succ_op) == TOP_clrrrb ||
03195 OP_code(succ_op) == TOP_clrrrb_pr)) return TRUE;
03196
03197 return FALSE;
03198 }
03199 SCHED_INFO_CLASS Sched_Info_Class(OP *op)
03200 {
03201 BOOL is_chk = CGTARG_Is_OP_Check_Load(op);
03202 return TARG_Sched_Info_Class(OP_code(op), is_chk);
03203 }
03204
03205
03206
03207
03208
03209
03210
03211
03212
03213 void
03214 CGTARG_Adjust_Latency(OP *pred_op, OP *succ_op, CG_DEP_KIND kind, UINT8 opnd, INT *latency)
03215 {
03216 INT src_reg, dst_reg;
03217 BOOL pred_is_chk, succ_is_chk;
03218 TN *pred_tn = 0, *succ_tn = 0;
03219 const TOP pred_code = OP_code(pred_op);
03220 const TOP succ_code = OP_code(succ_op);
03221
03222
03223 if (OP_opnds(pred_op) > 1) {
03224 TN *src = OP_opnd(pred_op,1);
03225 if (TN_is_dedicated(src))
03226 src_reg = REGISTER_machine_id(TN_register_class(src), TN_register(src));
03227 }
03228
03229 if (OP_results(pred_op) > 0) {
03230 TN *dst = OP_result(pred_op,0);
03231 pred_tn = dst;
03232 if (TN_is_dedicated(dst))
03233 dst_reg = REGISTER_machine_id(TN_register_class(dst), TN_register(dst));
03234 }
03235
03236 if (pred_code == TOP_alloc && OP_opnds(succ_op) > 1) {
03237 succ_tn = OP_opnd(succ_op,1);
03238 }
03239
03240 pred_is_chk = CGTARG_Is_OP_Check_Load(pred_op);
03241 succ_is_chk = CGTARG_Is_OP_Check_Load(succ_op);
03242 TARG_Adjust_Latency(pred_code, succ_code, src_reg, dst_reg, opnd, latency,
03243 pred_is_chk, succ_is_chk);
03244
03245
03246
03247 if (pred_code == TOP_alloc && OP_def_use_stack_regs(succ_op) && (!succ_tn || !pred_tn || !TN_is_register(succ_tn) || !TN_is_register(pred_tn) ||!TNs_Are_Equivalent(succ_tn, pred_tn))) {
03248 *latency = 0;
03249 }
03250 if (pred_code == TOP_alloc &&
03251 (succ_code == TOP_flushrs ||
03252 succ_code == TOP_br_cexit||
03253 succ_code == TOP_br_ctop ||
03254 succ_code == TOP_br_wexit ||
03255 succ_code == TOP_br_wtop ||
03256 succ_code == TOP_br_call ||
03257 succ_code == TOP_br_ia ||
03258 succ_code == TOP_br_ret ||
03259 succ_code == TOP_clrrrb ||
03260 succ_code == TOP_clrrrb_pr ||
03261 succ_code == TOP_cover ||
03262 succ_code == TOP_rfi ))
03263 *latency = 1;
03264
03265
03266
03267
03268
03269
03270
03271 if (OP_load(pred_op) && OP_load(succ_op) &&
03272 ((kind == CG_DEP_MEMIN) || (kind == CG_DEP_MEMOUT) ||
03273 (kind == CG_DEP_MEMANTI))) {
03274 *latency = 0;
03275 }
03276
03277
03278 if ( OP_store(pred_op)
03279 || ( OP_load(pred_op)
03280 && !CGTARG_Use_Load_Latency(pred_op, OP_opnd(succ_op, opnd)))) {
03281 *latency = 1;
03282 }
03283
03284
03285 if (kind == CG_DEP_REGOUT) *latency = MAX(1, *latency);
03286
03287
03288
03289 if ( kind == CG_DEP_REGANTI
03290 && EXEC_PROPERTY_is_F_Unit(pred_code)
03291 && EXEC_PROPERTY_is_F_Unit(succ_code))
03292 {
03293 SI_RESOURCE_TOTAL* rvec = TSI_Resource_Total_Vector(succ_code);
03294 const UINT size = TSI_Resource_Total_Vector_Size(succ_code);
03295 for (UINT i = 0; i < size; ++i ) {
03296 SI_RESOURCE_ID id = SI_RESOURCE_TOTAL_Resource_Id(&rvec[i]);
03297 if (id == CGTARG_f0_unit_id) *latency = MAX(1, *latency);
03298 }
03299 }
03300
03301
03302 if (kind == CG_DEP_REGIN &&
03303 (OP_code(pred_op) == TOP_mov_f_ar ||
03304 OP_code(pred_op) == TOP_mov_t_ar_r ||
03305 OP_code(pred_op) == TOP_mov_t_ar_i))
03306 *latency = MAX(1, *latency);
03307
03308 if ( (*latency) < 0 && kind == CG_DEP_POSTCHK)
03309 *latency =1;
03310
03311
03312
03313
03314
03315 if (kind == CG_DEP_MISC &&
03316 (OP_code(pred_op)==TOP_mov_t_pr_i) &&
03317 (OP_code(succ_op)==TOP_cmp_i_eq) )
03318 *latency = MAX(1, *latency);
03319
03320
03321
03322
03323
03324
03325 if (kind == CG_DEP_MISC &&
03326 (OP_code(pred_op)==TOP_fsetc) &&
03327 (OP_code(succ_op)==TOP_fcvt_fx) )
03328 *latency = MAX(1, *latency);
03329
03330 if ((OP_call (succ_op) || OP_code(succ_op) == TOP_br_ret) &&
03331 kind == CG_DEP_REGIN &&
03332 opnd >= OP_opnds(succ_op) - succ_op->hidden_opnds) {
03333 *latency = 0;
03334 } else if (OP_call (pred_op) && kind == CG_DEP_REGANTI &&
03335 opnd >= OP_opnds(pred_op) - pred_op->hidden_opnds) {
03336 *latency = 1;
03337 }
03338
03339
03340
03341
03342
03343 if ((OP_call (succ_op) || OP_code(succ_op) == TOP_br_ret) &&
03344 kind == CG_DEP_REGIN && Is_Hidden_Opnd(succ_op, opnd)) {
03345 *latency = 0;
03346 } else if (OP_call (pred_op) && kind == CG_DEP_REGANTI &&
03347 Is_Hidden_Opnd(pred_op, opnd)) {
03348 *latency = 1;
03349 }
03350 }
03351
03352 BOOL
03353 Is_MMX_Dependency (OP* pred_op, OP* succ_op, CG_DEP_KIND kind) {
03354
03355 if (kind != CG_DEP_REGIN) { return FALSE; }
03356
03357 switch (Sched_Info_Class(pred_op)) {
03358 case SIC_MMALU_A:
03359 case SIC_MMALU_I:
03360 case SIC_MMMUL:
03361 case SIC_MMSHF:
03362 break;
03363 default:
03364 return FALSE;
03365 }
03366
03367 switch (Sched_Info_Class(succ_op)) {
03368 case SIC_IALU:
03369 case SIC_ISHF:
03370 case SIC_ILOG:
03371 case SIC_LD:
03372 case SIC_ST:
03373 return TRUE;
03374 }
03375
03376 return FALSE;
03377 }
03378
03379 INT32
03380 MMX_Dep_Latency (void) {
03381 return 4;
03382 }
03383
03384
03385
03386
03387
03388
03389
03390
03391
03392 void
03393 CGTARG_Generate_Remainder_Branch(TN *trip_count, TN *label_tn,
03394 OPS *prolog_ops, OPS *body_ops)
03395 {
03396 INT32 trip_size = TN_size(trip_count);
03397
03398 LC_Used_In_PU = TRUE;
03399 if (TN_is_constant(trip_count)) {
03400 TN *tmp_tn = Gen_Register_TN (ISA_REGISTER_CLASS_integer,
03401 trip_size);
03402 Exp_COPY(tmp_tn, Gen_Literal_TN(TN_value(trip_count)-1, trip_size), prolog_ops);
03403 Exp_COPY(LC_TN, tmp_tn, prolog_ops);
03404 } else {
03405 TN *trip_counter_minus_1 = Gen_Register_TN (ISA_REGISTER_CLASS_integer, trip_size);
03406 Exp_OP2(OPC_I8SUB,
03407 trip_counter_minus_1,
03408 trip_count,
03409 Gen_Literal_TN(1, trip_size),
03410 prolog_ops);
03411 Exp_COPY(LC_TN, trip_counter_minus_1, prolog_ops);
03412 }
03413
03414 if(PROCESSOR_Version == 2)
03415 Build_OP (TOP_br_cloop,
03416 LC_TN,
03417 Gen_Enum_TN(ECV_bwh_sptk),
03418 Gen_Enum_TN(ECV_ph_few),
03419 Gen_Enum_TN(ECV_dh),
03420 label_tn,
03421 LC_TN,
03422 body_ops);
03423 else
03424 Build_OP (TOP_br_cloop,
03425 LC_TN,
03426 Gen_Enum_TN(ECV_bwh_dptk),
03427 Gen_Enum_TN(ECV_ph_few),
03428 Gen_Enum_TN(ECV_dh),
03429 label_tn,
03430 LC_TN,
03431 body_ops);
03432
03433
03434 }
03435
03436
03437
03438
03439
03440
03441
03442
03443
03444
03445 BOOL CGTARG_OP_is_counted_loop(OP *op)
03446 {
03447 return OP_code(op) == TOP_br_cloop ||
03448 OP_code(op) == TOP_br_ctop;
03449 }
03450
03451
03452
03453
03454
03455
03456
03457
03458
03459
03460 void
03461 CGTARG_Generate_Branch_Cloop(OP *br_op,
03462 TN *unrolled_trip_count,
03463 TN *trip_count_tn,
03464 INT32 ntimes,
03465 TN *label_tn,
03466 OPS *prolog_ops,
03467 OPS *body_ops)
03468 {
03469 LC_Used_In_PU = TRUE;
03470 if (!CGTARG_OP_is_counted_loop(br_op)) {
03471 if(PROCESSOR_Version == 2)
03472 Build_OP (TOP_br_cloop,
03473 LC_TN,
03474 Gen_Enum_TN(ECV_bwh_sptk),
03475 Gen_Enum_TN(ECV_ph_few),
03476 Gen_Enum_TN(ECV_dh),
03477 label_tn,
03478 LC_TN,
03479 body_ops);
03480 else
03481 Build_OP (TOP_br_cloop,
03482 LC_TN,
03483 Gen_Enum_TN(ECV_bwh_dptk),
03484 Gen_Enum_TN(ECV_ph_few),
03485 Gen_Enum_TN(ECV_dh),
03486 label_tn,
03487 LC_TN,
03488 body_ops);
03489 }
03490
03491 INT32 trip_size = TN_size(trip_count_tn);
03492 TN *unrolled_trip_count_minus_1;
03493
03494 if (TN_is_constant(trip_count_tn)) {
03495 unrolled_trip_count_minus_1 = Gen_Literal_TN(TN_value(trip_count_tn) / ntimes - 1,
03496 trip_size);
03497 } else {
03498 if (unrolled_trip_count == NULL) {
03499 unrolled_trip_count = Build_TN_Like(trip_count_tn);
03500 Exp_OP2(trip_size == 4 ? OPC_U4DIV : OPC_U8DIV,
03501 unrolled_trip_count,
03502 trip_count_tn,
03503 Gen_Literal_TN(ntimes, trip_size),
03504 prolog_ops);
03505 }
03506 unrolled_trip_count_minus_1 = Gen_Register_TN (ISA_REGISTER_CLASS_integer,
03507 trip_size);
03508 Exp_OP2(OPC_I8SUB,
03509 unrolled_trip_count_minus_1,
03510 unrolled_trip_count,
03511 Gen_Literal_TN(1, trip_size),
03512 prolog_ops);
03513 }
03514
03515 if (TN_is_constant(unrolled_trip_count_minus_1)) {
03516 INT64 imm=TN_value(unrolled_trip_count_minus_1);
03517 const ISA_OPERAND_INFO *oinfo;
03518 oinfo = ISA_OPERAND_Info(TOP_mov_t_ar_i_i);
03519 const ISA_OPERAND_VALTYP *vtype = ISA_OPERAND_INFO_Operand(oinfo, 1);
03520 ISA_LIT_CLASS lc = ISA_OPERAND_VALTYP_Literal_Class(vtype);
03521 if (ISA_LC_Value_In_Class(imm, lc)){
03522 Build_OP (TOP_mov_t_ar_i_i, LC_TN, True_TN, unrolled_trip_count_minus_1, prolog_ops);
03523 }
03524 else{
03525 TN *tmp_tn = Gen_Register_TN (ISA_REGISTER_CLASS_integer,
03526 trip_size);
03527 Exp_COPY(tmp_tn, unrolled_trip_count_minus_1, prolog_ops);
03528 Exp_COPY(LC_TN, tmp_tn, prolog_ops);
03529 }
03530 }
03531 else{
03532 Exp_COPY(LC_TN, unrolled_trip_count_minus_1, prolog_ops);
03533 }
03534 }
03535
03536 static TN* asm_constraint_tn[10];
03537 static ISA_REGISTER_SUBCLASS asm_constraint_sc[10];
03538 static char asm_constraint_name[10][8];
03539 static INT asm_constraint_index;
03540
03541
03542 void
03543 CGTARG_Init_Asm_Constraints (void)
03544 {
03545
03546 Setup_Output_Parameter_Locations (MTYPE_To_TY(MTYPE_I8));
03547 for (INT i = 0; i < 10; ++i) {
03548 asm_constraint_tn[i] = NULL;
03549 asm_constraint_sc[i] = ISA_REGISTER_SUBCLASS_UNDEFINED;
03550 asm_constraint_name[i][0] = '\0';
03551 }
03552 asm_constraint_index = 0;
03553 }
03554
03555
03556
03557
03558
03559
03560 extern TN*
03561 CGTARG_TN_For_Asm_Operand (const char* constraint,
03562 const WN* load,
03563 TN* pref_tn,
03564 ISA_REGISTER_SUBCLASS* subclass)
03565 {
03566
03567
03568
03569
03570 static const char* modifiers = "=&%";
03571 while (strchr(modifiers, *constraint)) {
03572 constraint++;
03573 }
03574
03575
03576
03577
03578
03579
03580
03581 if (*constraint != 'm') {
03582 const char* m = constraint;
03583 while (*++m) {
03584 if (*m == 'm') {
03585 constraint = m;
03586 break;
03587 }
03588 }
03589 }
03590
03591
03592
03593 static const char* immediates = "in";
03594 while (strchr(immediates, *constraint) && *(constraint+1)) {
03595 constraint++;
03596 }
03597
03598 TN* ret_tn;
03599
03600
03601 if (strchr(immediates, *constraint)) {
03602 if (load && WN_operator(load)==OPR_LDA &&
03603 ST_is_constant(WN_st(load)) ) {
03604
03605 FmtAssert(WN_st(load) != NULL,
03606 ("WN_st is NULL when handling the const symbol for 'i' constraint"));
03607 ST *base_sym;
03608 INT64 base_ofst;
03609 ST *sym = WN_st(load);
03610 Allocate_Object(sym);
03611 Base_Symbol_And_Offset_For_Addressing (sym, WN_lda_offset(load), &base_sym, &base_ofst);
03612 ret_tn = Gen_Symbol_TN(base_sym, base_ofst, 0);
03613 }
03614 else {
03615 if (load && WN_operator(load)==OPR_LDID &&
03616 WN_class(load)==CLASS_PREG) {
03617
03618 load = Preg_Is_Rematerializable(WN_load_offset(load), NULL);
03619 }
03620 FmtAssert(load && WN_operator(load) == OPR_INTCONST,
03621 ("Cannot find immediate operand for ASM"));
03622 ret_tn = Gen_Literal_TN(WN_const_val(load),
03623 MTYPE_bit_size(WN_rtype(load))/8);
03624
03625
03626
03627 }
03628 }
03629
03630
03631 else if (isdigit(*constraint)) {
03632 INT prev_index = *constraint - '0';
03633 FmtAssert(asm_constraint_tn[prev_index],
03634 ("numeric matching constraint refers to NULL value"));
03635 ret_tn = asm_constraint_tn[prev_index];
03636 }
03637
03638 else if (strchr("gmr", *constraint)) {
03639 TYPE_ID rtype = (load != NULL ? WN_rtype(load) : MTYPE_I8);
03640 FmtAssert(MTYPE_is_integral(rtype),
03641 ("ASM operand does not satisfy its constraint"));
03642 ret_tn = (pref_tn ? pref_tn : Build_TN_Of_Mtype(rtype));
03643 }
03644
03645 else if (*constraint == 'f') {
03646 TYPE_ID rtype = (load != NULL ? WN_rtype(load) : MTYPE_F8);
03647 FmtAssert(MTYPE_is_float(rtype),
03648 ("ASM operand does not satisfy its constraint"));
03649 ret_tn = (pref_tn ? pref_tn : Build_TN_Of_Mtype(rtype));
03650 }
03651
03652 else {
03653 FmtAssert(FALSE, ("ASM constraint <%s> not supported", constraint));
03654 }
03655
03656 asm_constraint_tn[asm_constraint_index] = ret_tn;
03657 asm_constraint_index++;
03658
03659 return ret_tn;
03660 }
03661
03662
03663 static char *
03664 Get_TN_Assembly_Name (TN *tn)
03665 {
03666 char *name = NULL;
03667 if (TN_is_register(tn)) {
03668 ISA_REGISTER_CLASS rc = TN_register_class(tn);
03669 REGISTER reg = TN_register(tn);
03670 if (ABI_PROPERTY_Is_stacked(rc, REGISTER_machine_id(rc, reg))
03671 && REGISTER_Is_Stacked_Output(rc, reg) )
03672 {
03673 name = REGISTER_Stacked_Output_Name (reg);
03674 }
03675 if (name == NULL) {
03676 name = (char*) REGISTER_name(rc, reg);
03677 }
03678 }
03679 else {
03680 FmtAssert(FALSE, ("NYI: non-register parameters in ASM"));
03681 }
03682 return name;
03683 }
03684
03685 void
03686 CGTARG_TN_And_Name_For_Asm_Constraint (char *constraint, TYPE_ID mtype,
03687 TYPE_ID desc, TN **tn, char **name)
03688 {
03689 INT i;
03690 if (*constraint == '=') {
03691
03692 CGTARG_TN_And_Name_For_Asm_Constraint (constraint+1,
03693 mtype, desc, tn, name);
03694 return;
03695 }
03696 if (mtype == MTYPE_V) {
03697
03698 if (*constraint == 'f') mtype = MTYPE_F8;
03699 else mtype = MTYPE_I8;
03700 }
03701 switch (*constraint) {
03702 case 'r':
03703 FmtAssert(MTYPE_is_integral(mtype),
03704 ("ASM constraint is integer but parameter is not"));
03705 break;
03706 case 'f':
03707 FmtAssert(MTYPE_is_float(mtype),
03708 ("ASM constraint is float but parameter is not"));
03709 break;
03710 case 'm':
03711 break;
03712 case '0':
03713 case '1':
03714 case '2':
03715 case '3':
03716 case '4':
03717 case '5':
03718 case '6':
03719 case '7':
03720 case '8':
03721 case '9':
03722 i = *constraint - '0';
03723 FmtAssert(asm_constraint_tn[i],
03724 ("numeric matching constraint refers to NULL value"));
03725 ++asm_constraint_index;
03726 *tn = asm_constraint_tn[i];
03727 *name = asm_constraint_name[i];
03728 return;
03729 case 'i':
03730
03731 *tn = NULL;
03732 *name = NULL;
03733 return;
03734 default:
03735 FmtAssert(FALSE, ("ASM constraint <%s> not supported", constraint));
03736 }
03737 PLOC ploc = Get_Output_Parameter_Location (MTYPE_To_TY(mtype));
03738 *tn = PREG_To_TN (MTYPE_To_PREG(mtype), PLOC_reg(ploc));
03739 asm_constraint_tn[asm_constraint_index] = *tn;
03740 *name = Get_TN_Assembly_Name(*tn);
03741 if (*constraint == 'm') {
03742 sprintf(asm_constraint_name[asm_constraint_index], "[%s]",
03743 *name);
03744 } else {
03745 sprintf(asm_constraint_name[asm_constraint_index], "%s",
03746 *name);
03747 }
03748 *name = asm_constraint_name[asm_constraint_index];
03749 ++asm_constraint_index;
03750 }
03751
03752
03753
03754
03755
03756
03757
03758 char CGTARG_Asm_Opnd_Modifiers[] = { 'r' };
03759 INT CGTARG_Num_Asm_Opnd_Modifiers = 1;
03760
03761 const char*
03762 CGTARG_Modified_Asm_Opnd_Name(char modifier, TN* tn, char *tn_name)
03763 {
03764 if (modifier == 'r') {
03765 return tn_name;
03766 }
03767 else {
03768 FmtAssert(FALSE, ("Unknown ASM operand modifier '%c'", modifier));
03769 }
03770
03771 }
03772
03773
03774
03775
03776
03777
03778
03779
03780
03781
03782
03783
03784 void
03785 CGTARG_Postprocess_Asm_String (char *s)
03786 {
03787 char *p;
03788 while (TRUE) {
03789 p = strstr(s, "%P");
03790 if (p == NULL) break;
03791
03792 *p = ' ';
03793 ++p;
03794 *p = ' ';
03795 ++p;
03796 *p = ' ';
03797 }
03798 }
03799
03800
03801
03802
03803
03804
03805
03806
03807
03808
03809 static
03810 BOOL CGTARG_Unconditional_Compare_Helper(TOP top, TOP* uncond_ver)
03811 {
03812 switch (top) {
03813 case TOP_fcmp_eq_unc:
03814 case TOP_fcmp_ge_unc:
03815 case TOP_fcmp_gt_unc:
03816 case TOP_fcmp_le_unc:
03817 case TOP_fcmp_lt_unc:
03818 case TOP_fcmp_neq_unc:
03819 case TOP_fcmp_nge_unc:
03820 case TOP_fcmp_ngt_unc:
03821 case TOP_fcmp_nle_unc:
03822 case TOP_fcmp_nlt_unc:
03823 case TOP_fcmp_ord_unc:
03824 case TOP_fcmp_unord_unc:
03825 case TOP_cmp_eq_unc:
03826 case TOP_cmp_lt_unc:
03827 case TOP_cmp_ltu_unc:
03828 case TOP_cmp_i_eq_unc:
03829 case TOP_cmp_i_lt_unc:
03830 case TOP_cmp_i_ltu_unc:
03831 case TOP_cmp4_eq_unc:
03832 case TOP_cmp4_lt_unc:
03833 case TOP_cmp4_ltu_unc:
03834 case TOP_cmp4_i_eq_unc:
03835 case TOP_cmp4_i_lt_unc:
03836 case TOP_cmp4_i_ltu_unc:
03837 case TOP_cmp_ne_unc:
03838 case TOP_cmp_le_unc:
03839 case TOP_cmp_gt_unc:
03840 case TOP_cmp_ge_unc:
03841 case TOP_cmp_leu_unc:
03842 case TOP_cmp_gtu_unc:
03843 case TOP_cmp_geu_unc:
03844 case TOP_cmp_i_ne_unc:
03845 case TOP_cmp_i_le_unc:
03846 case TOP_cmp_i_gt_unc:
03847 case TOP_cmp_i_ge_unc:
03848 case TOP_cmp_i_leu_unc:
03849 case TOP_cmp_i_gtu_unc:
03850 case TOP_cmp_i_geu_unc:
03851 case TOP_cmp4_ne_unc:
03852 case TOP_cmp4_le_unc:
03853 case TOP_cmp4_gt_unc:
03854 case TOP_cmp4_ge_unc:
03855 case TOP_cmp4_leu_unc:
03856 case TOP_cmp4_gtu_unc:
03857 case TOP_cmp4_geu_unc:
03858 case TOP_cmp4_i_ne_unc:
03859 case TOP_cmp4_i_le_unc:
03860 case TOP_cmp4_i_gt_unc:
03861 case TOP_cmp4_i_ge_unc:
03862 case TOP_cmp4_i_leu_unc:
03863 case TOP_cmp4_i_gtu_unc:
03864 case TOP_cmp4_i_geu_unc:
03865 case TOP_tbit_nz_unc:
03866 case TOP_tbit_z_unc:
03867 case TOP_tnat_nz_unc:
03868 case TOP_tnat_z_unc:
03869 case TOP_frcpa:
03870 case TOP_frsqrta:
03871 *uncond_ver = top;
03872 return TRUE;
03873
03874 case TOP_fcmp_eq:
03875 *uncond_ver = TOP_fcmp_eq_unc;
03876 break;
03877 case TOP_fcmp_ge:
03878 *uncond_ver = TOP_fcmp_ge_unc;
03879 break;
03880 case TOP_fcmp_gt:
03881 *uncond_ver = TOP_fcmp_gt_unc;
03882 break;
03883 case TOP_fcmp_le:
03884 *uncond_ver = TOP_fcmp_le_unc;
03885 break;
03886 case TOP_fcmp_lt:
03887 *uncond_ver = TOP_fcmp_lt_unc;
03888 break;
03889 case TOP_fcmp_neq:
03890 *uncond_ver = TOP_fcmp_neq_unc;
03891 break;
03892 case TOP_fcmp_nge:
03893 *uncond_ver = TOP_fcmp_nge_unc;
03894 break;
03895 case TOP_fcmp_ngt:
03896 *uncond_ver = TOP_fcmp_ngt_unc;
03897 break;
03898 case TOP_fcmp_nle:
03899 *uncond_ver = TOP_fcmp_nle_unc;
03900 break;
03901 case TOP_fcmp_nlt:
03902 *uncond_ver = TOP_fcmp_nlt_unc;
03903 break;
03904 case TOP_fcmp_ord:
03905 *uncond_ver = TOP_fcmp_ord_unc;
03906 break;
03907 case TOP_fcmp_unord:
03908 *uncond_ver = TOP_fcmp_unord_unc;
03909 break;
03910 case TOP_cmp_eq:
03911 *uncond_ver = TOP_cmp_eq_unc;
03912 break;
03913 case TOP_cmp_lt:
03914 *uncond_ver = TOP_cmp_lt_unc;
03915 break;
03916 case TOP_cmp_ltu:
03917 *uncond_ver = TOP_cmp_ltu_unc;
03918 break;
03919 case TOP_cmp_i_eq:
03920 *uncond_ver = TOP_cmp_i_eq_unc;
03921 break;
03922 case TOP_cmp_i_lt:
03923 *uncond_ver = TOP_cmp_i_lt_unc;
03924 break;
03925 case TOP_cmp_i_ltu:
03926 *uncond_ver = TOP_cmp_i_ltu_unc;
03927 break;
03928 case TOP_cmp4_eq:
03929 *uncond_ver = TOP_cmp4_eq_unc;
03930 break;
03931 case TOP_cmp4_lt:
03932 *uncond_ver = TOP_cmp4_lt_unc;
03933 break;
03934 case TOP_cmp4_ltu:
03935 *uncond_ver = TOP_cmp4_ltu_unc;
03936 break;
03937 case TOP_cmp4_i_eq:
03938 *uncond_ver = TOP_cmp4_i_eq_unc;
03939 break;
03940 case TOP_cmp4_i_lt:
03941 *uncond_ver = TOP_cmp4_i_lt_unc;
03942 break;
03943 case TOP_cmp4_i_ltu:
03944 *uncond_ver = TOP_cmp4_i_ltu_unc;
03945 break;
03946 case TOP_cmp_ne:
03947 *uncond_ver = TOP_cmp_ne_unc;
03948 break;
03949 case TOP_cmp_le:
03950 *uncond_ver = TOP_cmp_le_unc;
03951 break;
03952 case TOP_cmp_gt:
03953 *uncond_ver = TOP_cmp_gt_unc;
03954 break;
03955 case TOP_cmp_ge:
03956 *uncond_ver = TOP_cmp_ge_unc;
03957 break;
03958 case TOP_cmp_leu:
03959 *uncond_ver = TOP_cmp_leu_unc;
03960 break;
03961 case TOP_cmp_gtu:
03962 *uncond_ver = TOP_cmp_gtu_unc;
03963 break;
03964 case TOP_cmp_geu:
03965 *uncond_ver = TOP_cmp_geu_unc;
03966 break;
03967 case TOP_cmp_i_ne:
03968 *uncond_ver = TOP_cmp_i_ne_unc;
03969 break;
03970 case TOP_cmp_i_le:
03971 *uncond_ver = TOP_cmp_i_le_unc;
03972 break;
03973 case TOP_cmp_i_gt:
03974 *uncond_ver = TOP_cmp_i_gt_unc;
03975 break;
03976 case TOP_cmp_i_ge:
03977 *uncond_ver = TOP_cmp_i_ge_unc;
03978 break;
03979 case TOP_cmp_i_leu:
03980 *uncond_ver = TOP_cmp_i_leu_unc;
03981 break;
03982 case TOP_cmp_i_gtu:
03983 *uncond_ver = TOP_cmp_i_gtu_unc;
03984 break;
03985 case TOP_cmp_i_geu:
03986 *uncond_ver = TOP_cmp_i_geu_unc;
03987 break;
03988 case TOP_cmp4_ne:
03989 *uncond_ver = TOP_cmp4_ne_unc;
03990 break;
03991 case TOP_cmp4_le:
03992 *uncond_ver = TOP_cmp4_le_unc;
03993 break;
03994 case TOP_cmp4_gt:
03995 *uncond_ver = TOP_cmp4_gt_unc;
03996 break;
03997 case TOP_cmp4_ge:
03998 *uncond_ver = TOP_cmp4_ge_unc;
03999 break;
04000 case TOP_cmp4_leu:
04001 *uncond_ver = TOP_cmp4_leu_unc;
04002 break;
04003 case TOP_cmp4_gtu:
04004 *uncond_ver = TOP_cmp4_gtu_unc;
04005 break;
04006 case TOP_cmp4_geu:
04007 *uncond_ver = TOP_cmp4_geu_unc;
04008 break;
04009 case TOP_cmp4_i_ne:
04010 *uncond_ver = TOP_cmp4_i_ne_unc;
04011 break;
04012 case TOP_cmp4_i_le:
04013 *uncond_ver = TOP_cmp4_i_le_unc;
04014 break;
04015 case TOP_cmp4_i_gt:
04016 *uncond_ver = TOP_cmp4_i_gt_unc;
04017 break;
04018 case TOP_cmp4_i_ge:
04019 *uncond_ver = TOP_cmp4_i_ge_unc;
04020 break;
04021 case TOP_cmp4_i_leu:
04022 *uncond_ver = TOP_cmp4_i_leu_unc;
04023 break;
04024 case TOP_cmp4_i_gtu:
04025 *uncond_ver = TOP_cmp4_i_gtu_unc;
04026 break;
04027 case TOP_cmp4_i_geu:
04028 *uncond_ver = TOP_cmp4_i_geu_unc;
04029 break;
04030 case TOP_tbit_nz:
04031 *uncond_ver = TOP_tbit_nz_unc;
04032 break;
04033 case TOP_tbit_z:
04034 *uncond_ver = TOP_tbit_z_unc;
04035 break;
04036 case TOP_tnat_nz:
04037 *uncond_ver = TOP_tnat_nz_unc;
04038 break;
04039 case TOP_tnat_z:
04040 *uncond_ver = TOP_tnat_z_unc;
04041 break;
04042
04043 default:
04044 *uncond_ver = TOP_UNDEFINED;
04045 }
04046 return FALSE;
04047 }
04048
04049 BOOL CGTARG_Unconditional_Compare(OP *op, TOP* uncond_ver)
04050 {
04051 return (CGTARG_Unconditional_Compare_Helper(OP_code(op),uncond_ver));
04052 }
04053
04054
04055
04056
04057
04058
04059
04060
04061
04062 TOP CGTARG_Invert_Branch(BB* bb)
04063 {
04064 TN* tn1;
04065 TN* tn2;
04066 OP* compare_op;
04067 OP* br_op = BB_branch_op(bb);
04068
04069 if (!OP_has_predicate(br_op)) {
04070 return TOP_UNDEFINED;
04071 }
04072 TN* pred_tn = OP_opnd(br_op, OP_PREDICATE_OPND);
04073 if (TN_is_true_pred(pred_tn)) {
04074 return TOP_UNDEFINED;
04075 }
04076 CGTARG_Analyze_Compare(br_op, &tn1, &tn2, &compare_op);
04077 if (compare_op == br_op) {
04078 return TOP_UNDEFINED;
04079 }
04080 if (OP_result(compare_op, 0) == pred_tn) {
04081 Set_OP_opnd(br_op, OP_PREDICATE_OPND, OP_result(compare_op, 1));
04082 } else {
04083 Set_OP_opnd(br_op, OP_PREDICATE_OPND, OP_result(compare_op, 0));
04084 }
04085 return OP_code(br_op);
04086 }
04087
04088
04089
04090
04091
04092
04093
04094
04095
04096
04097 void CGTARG_Init_OP_cond_def_kind(OP *op)
04098 {
04099 TOP top = OP_code(op);
04100 switch (top) {
04101
04102
04103
04104 case TOP_cmp_eq_unc:
04105 case TOP_cmp_lt_unc:
04106 case TOP_cmp_ltu_unc:
04107 case TOP_cmp_i_eq_unc:
04108 case TOP_cmp_i_lt_unc:
04109 case TOP_cmp_i_ltu_unc:
04110 case TOP_cmp4_eq_unc:
04111 case TOP_cmp4_lt_unc:
04112 case TOP_cmp4_ltu_unc:
04113 case TOP_cmp4_i_eq_unc:
04114 case TOP_cmp4_i_lt_unc:
04115 case TOP_cmp4_i_ltu_unc:
04116 case TOP_cmp_ne_unc:
04117 case TOP_cmp_le_unc:
04118 case TOP_cmp_gt_unc:
04119 case TOP_cmp_ge_unc:
04120 case TOP_cmp_leu_unc:
04121 case TOP_cmp_gtu_unc:
04122 case TOP_cmp_geu_unc:
04123 case TOP_cmp_i_ne_unc:
04124 case TOP_cmp_i_le_unc:
04125 case TOP_cmp_i_gt_unc:
04126 case TOP_cmp_i_ge_unc:
04127 case TOP_cmp_i_leu_unc:
04128 case TOP_cmp_i_gtu_unc:
04129 case TOP_cmp_i_geu_unc:
04130 case TOP_cmp4_ne_unc:
04131 case TOP_cmp4_le_unc:
04132 case TOP_cmp4_gt_unc:
04133 case TOP_cmp4_ge_unc:
04134 case TOP_cmp4_leu_unc:
04135 case TOP_cmp4_gtu_unc:
04136 case TOP_cmp4_geu_unc:
04137 case TOP_cmp4_i_ne_unc:
04138 case TOP_cmp4_i_le_unc:
04139 case TOP_cmp4_i_gt_unc:
04140 case TOP_cmp4_i_ge_unc:
04141 case TOP_cmp4_i_leu_unc:
04142 case TOP_cmp4_i_gtu_unc:
04143 case TOP_cmp4_i_geu_unc:
04144 case TOP_fcmp_eq_unc:
04145 case TOP_fcmp_lt_unc:
04146 case TOP_fcmp_le_unc:
04147 case TOP_fcmp_unord_unc:
04148 case TOP_fcmp_gt_unc:
04149 case TOP_fcmp_ge_unc:
04150 case TOP_fcmp_neq_unc:
04151 case TOP_fcmp_nlt_unc:
04152 case TOP_fcmp_nle_unc:
04153 case TOP_fcmp_ngt_unc:
04154 case TOP_fcmp_nge_unc:
04155 case TOP_fcmp_ord_unc:
04156 case TOP_tbit_nz_unc:
04157 case TOP_tbit_z_unc:
04158 case TOP_tnat_nz_unc:
04159 case TOP_tnat_z_unc:
04160
04161 Set_OP_cond_def_kind(op, OP_ALWAYS_UNC_DEF);
04162 break;
04163
04164
04165 case TOP_cmp_eq_and:
04166 case TOP_cmp_eq_or:
04167 case TOP_cmp_eq_or_andcm:
04168 case TOP_cmp_ne_and:
04169 case TOP_cmp_ne_or:
04170 case TOP_cmp_ne_or_andcm:
04171 case TOP_cmp_z1_lt_and:
04172 case TOP_cmp_z1_lt_or:
04173 case TOP_cmp_z1_lt_or_andcm:
04174 case TOP_cmp_z1_le_and:
04175 case TOP_cmp_z1_le_or:
04176 case TOP_cmp_z1_le_or_andcm:
04177 case TOP_cmp_z1_gt_and:
04178 case TOP_cmp_z1_gt_or:
04179 case TOP_cmp_z1_gt_or_andcm:
04180 case TOP_cmp_z1_ge_and:
04181 case TOP_cmp_z1_ge_or:
04182 case TOP_cmp_z1_ge_or_andcm:
04183 case TOP_cmp_i_eq_and:
04184 case TOP_cmp_i_eq_or:
04185 case TOP_cmp_i_eq_or_andcm:
04186 case TOP_cmp_i_ne_and:
04187 case TOP_cmp_i_ne_or:
04188 case TOP_cmp_i_ne_or_andcm:
04189 case TOP_cmp4_eq_and:
04190 case TOP_cmp4_eq_or:
04191 case TOP_cmp4_eq_or_andcm:
04192 case TOP_cmp4_ne_and:
04193 case TOP_cmp4_ne_or:
04194 case TOP_cmp4_ne_or_andcm:
04195 case TOP_cmp4_z1_lt_and:
04196 case TOP_cmp4_z1_lt_or:
04197 case TOP_cmp4_z1_lt_or_andcm:
04198 case TOP_cmp4_z1_le_and:
04199 case TOP_cmp4_z1_le_or:
04200 case TOP_cmp4_z1_le_or_andcm:
04201 case TOP_cmp4_z1_gt_and:
04202 case TOP_cmp4_z1_gt_or:
04203 case TOP_cmp4_z1_gt_or_andcm:
04204 case TOP_cmp4_z1_ge_and:
04205 case TOP_cmp4_z1_ge_or:
04206 case TOP_cmp4_z1_ge_or_andcm:
04207 case TOP_cmp4_i_eq_and:
04208 case TOP_cmp4_i_eq_or:
04209 case TOP_cmp4_i_eq_or_andcm:
04210 case TOP_cmp4_i_ne_and:
04211 case TOP_cmp4_i_ne_or:
04212 case TOP_cmp4_i_ne_or_andcm:
04213 case TOP_cmp_eq_orcm:
04214 case TOP_cmp_eq_andcm:
04215 case TOP_cmp_eq_and_orcm:
04216 case TOP_cmp_ne_orcm:
04217 case TOP_cmp_ne_andcm:
04218 case TOP_cmp_ne_and_orcm:
04219 case TOP_cmp_z1_lt_orcm:
04220 case TOP_cmp_z1_lt_andcm:
04221 case TOP_cmp_z1_lt_and_orcm:
04222 case TOP_cmp_z1_le_orcm:
04223 case TOP_cmp_z1_le_andcm:
04224 case TOP_cmp_z1_le_and_orcm:
04225 case TOP_cmp_z1_gt_orcm:
04226 case TOP_cmp_z1_gt_andcm:
04227 case TOP_cmp_z1_gt_and_orcm:
04228 case TOP_cmp_z1_ge_orcm:
04229 case TOP_cmp_z1_ge_andcm:
04230 case TOP_cmp_z1_ge_and_orcm:
04231 case TOP_cmp_z2_lt_orcm:
04232 case TOP_cmp_z2_lt_andcm:
04233 case TOP_cmp_z2_lt_and_orcm:
04234 case TOP_cmp_z2_le_orcm:
04235 case TOP_cmp_z2_le_andcm:
04236 case TOP_cmp_z2_le_and_orcm:
04237 case TOP_cmp_z2_gt_orcm:
04238 case TOP_cmp_z2_gt_andcm:
04239 case TOP_cmp_z2_gt_and_orcm:
04240 case TOP_cmp_z2_ge_orcm:
04241 case TOP_cmp_z2_ge_andcm:
04242 case TOP_cmp_z2_ge_and_orcm:
04243 case TOP_cmp_z2_lt_and:
04244 case TOP_cmp_z2_lt_or:
04245 case TOP_cmp_z2_lt_or_andcm:
04246 case TOP_cmp_z2_le_and:
04247 case TOP_cmp_z2_le_or:
04248 case TOP_cmp_z2_le_or_andcm:
04249 case TOP_cmp_z2_gt_and:
04250 case TOP_cmp_z2_gt_or:
04251 case TOP_cmp_z2_gt_or_andcm:
04252 case TOP_cmp_z2_ge_and:
04253 case TOP_cmp_z2_ge_or:
04254 case TOP_cmp_z2_ge_or_andcm:
04255 case TOP_cmp_i_eq_orcm:
04256 case TOP_cmp_i_eq_andcm:
04257 case TOP_cmp_i_eq_and_orcm:
04258 case TOP_cmp_i_ne_orcm:
04259 case TOP_cmp_i_ne_andcm:
04260 case TOP_cmp_i_ne_and_orcm:
04261 case TOP_cmp4_eq_orcm:
04262 case TOP_cmp4_eq_andcm:
04263 case TOP_cmp4_eq_and_orcm:
04264 case TOP_cmp4_ne_orcm:
04265 case TOP_cmp4_ne_andcm:
04266 case TOP_cmp4_ne_and_orcm:
04267 case TOP_cmp4_z1_lt_orcm:
04268 case TOP_cmp4_z1_lt_andcm:
04269 case TOP_cmp4_z1_lt_and_orcm:
04270 case TOP_cmp4_z1_le_orcm:
04271 case TOP_cmp4_z1_le_andcm:
04272 case TOP_cmp4_z1_le_and_orcm:
04273 case TOP_cmp4_z1_gt_orcm:
04274 case TOP_cmp4_z1_gt_andcm:
04275 case TOP_cmp4_z1_gt_and_orcm:
04276 case TOP_cmp4_z1_ge_orcm:
04277 case TOP_cmp4_z1_ge_andcm:
04278 case TOP_cmp4_z1_ge_and_orcm:
04279 case TOP_cmp4_z2_lt_orcm:
04280 case TOP_cmp4_z2_lt_andcm:
04281 case TOP_cmp4_z2_lt_and_orcm:
04282 case TOP_cmp4_z2_le_orcm:
04283 case TOP_cmp4_z2_le_andcm:
04284 case TOP_cmp4_z2_le_and_orcm:
04285 case TOP_cmp4_z2_gt_orcm:
04286 case TOP_cmp4_z2_gt_andcm:
04287 case TOP_cmp4_z2_gt_and_orcm:
04288 case TOP_cmp4_z2_ge_orcm:
04289 case TOP_cmp4_z2_ge_andcm:
04290 case TOP_cmp4_z2_ge_and_orcm:
04291 case TOP_cmp4_z2_lt_and:
04292 case TOP_cmp4_z2_lt_or:
04293 case TOP_cmp4_z2_lt_or_andcm:
04294 case TOP_cmp4_z2_le_and:
04295 case TOP_cmp4_z2_le_or:
04296 case TOP_cmp4_z2_le_or_andcm:
04297 case TOP_cmp4_z2_gt_and:
04298 case TOP_cmp4_z2_gt_or:
04299 case TOP_cmp4_z2_gt_or_andcm:
04300 case TOP_cmp4_z2_ge_and:
04301 case TOP_cmp4_z2_ge_or:
04302 case TOP_cmp4_z2_ge_or_andcm:
04303 case TOP_cmp4_i_eq_orcm:
04304 case TOP_cmp4_i_eq_andcm:
04305 case TOP_cmp4_i_eq_and_orcm:
04306 case TOP_cmp4_i_ne_orcm:
04307 case TOP_cmp4_i_ne_andcm:
04308 case TOP_cmp4_i_ne_and_orcm:
04309 case TOP_cmp_lt_and:
04310 case TOP_cmp_lt_or:
04311 case TOP_cmp_lt_or_andcm:
04312 case TOP_cmp_le_and:
04313 case TOP_cmp_le_or:
04314 case TOP_cmp_le_or_andcm:
04315 case TOP_cmp_gt_and:
04316 case TOP_cmp_gt_or:
04317 case TOP_cmp_gt_or_andcm:
04318 case TOP_cmp_ge_and:
04319 case TOP_cmp_ge_or:
04320 case TOP_cmp_ge_or_andcm:
04321 case TOP_cmp_lt_orcm:
04322 case TOP_cmp_lt_andcm:
04323 case TOP_cmp_lt_and_orcm:
04324 case TOP_cmp_le_orcm:
04325 case TOP_cmp_le_andcm:
04326 case TOP_cmp_le_and_orcm:
04327 case TOP_cmp_gt_orcm:
04328 case TOP_cmp_gt_andcm:
04329 case TOP_cmp_gt_and_orcm:
04330 case TOP_cmp_ge_orcm:
04331 case TOP_cmp_ge_andcm:
04332 case TOP_cmp_ge_and_orcm:
04333 case TOP_cmp4_lt_and:
04334 case TOP_cmp4_lt_or:
04335 case TOP_cmp4_lt_or_andcm:
04336 case TOP_cmp4_le_and:
04337 case TOP_cmp4_le_or:
04338 case TOP_cmp4_le_or_andcm:
04339 case TOP_cmp4_gt_and:
04340 case TOP_cmp4_gt_or:
04341 case TOP_cmp4_gt_or_andcm:
04342 case TOP_cmp4_ge_and:
04343 case TOP_cmp4_ge_or:
04344 case TOP_cmp4_ge_or_andcm:
04345 case TOP_cmp4_lt_orcm:
04346 case TOP_cmp4_lt_andcm:
04347 case TOP_cmp4_lt_and_orcm:
04348 case TOP_cmp4_le_orcm:
04349 case TOP_cmp4_le_andcm:
04350 case TOP_cmp4_le_and_orcm:
04351 case TOP_cmp4_gt_orcm:
04352 case TOP_cmp4_gt_andcm:
04353 case TOP_cmp4_gt_and_orcm:
04354 case TOP_cmp4_ge_orcm:
04355 case TOP_cmp4_ge_andcm:
04356 case TOP_cmp4_ge_and_orcm:
04357
04358 Set_OP_cond_def_kind(op, OP_ALWAYS_COND_DEF);
04359 break;
04360
04361 default:
04362 if (OP_has_predicate(op))
04363 Set_OP_cond_def_kind(op, OP_PREDICATED_DEF);
04364 else
04365 Set_OP_cond_def_kind(op, OP_ALWAYS_UNC_DEF);
04366 break;
04367 }
04368 }
04369
04370
04371
04372
04373
04374
04375
04376
04377
04378
04379
04380 TOP CGTARG_Get_unc_Variant(TOP top)
04381 {
04382 TOP result;
04383
04384 CGTARG_Unconditional_Compare_Helper(top, &result);
04385
04386 if (result == TOP_UNDEFINED) {
04387 result = top;
04388 }
04389
04390 return (result);
04391 }
04392
04394
04395
04396
04397
04398 void
04399 Make_Branch_Conditional(BB *bb)
04400 {
04401 OP *new_br;
04402 TOP new_top;
04403 OP* br_op = BB_branch_op(bb);
04404
04405 if (!br_op) return;
04406
04407 switch (OP_code(br_op)) {
04408 case TOP_br:
04409 new_top = TOP_br_cond;
04410 break;
04411 case TOP_br_r:
04412 new_top = TOP_br_r_cond;
04413 break;
04414 default:
04415 return;
04416 }
04417
04418 new_br = Mk_OP(new_top,
04419 True_TN,
04420 Gen_Enum_TN(ECV_bwh_dptk),
04421 Gen_Enum_TN(ECV_ph_few),
04422 Gen_Enum_TN(ECV_dh),
04423 OP_opnd(br_op,2));
04424 OP_srcpos(new_br) = OP_srcpos(br_op);
04425 BB_Insert_Op_After(bb, br_op, new_br);
04426 BB_Remove_Op(bb, br_op);
04427 }
04428
04429
04430
04431
04432
04433
04434
04435
04436
04437
04438 BOOL
04439 CGTARG_Check_OP_For_HB_Suitability(OP *op)
04440 {
04441
04442
04443 if (OP_has_predicate(op)) return TRUE;
04444
04445
04446
04447 if (OP_xfer(op)) return TRUE;
04448
04449
04450 if (OP_code(op) == TOP_alloc) return TRUE;
04451
04452 return FALSE;
04453 }
04454
04455
04456
04457
04458
04459
04460
04461
04462 static void
04463 Pad_Cycles_Before(BB *bb, OP *op, UINT cycles)
04464 {
04465 UINT slot_mask, stop_mask, ibundle, one_stop_bundles, two_stop_bundles;
04466 INT slot;
04467 OP *new_op;
04468 OPS new_ops = OPS_EMPTY;
04469 ISA_EXEC_UNIT_PROPERTY unit;
04470
04471 if (!cycles) return;
04472 if (!OP_end_group(OP_prev(op))) {
04473 Set_OP_end_group(OP_prev(op));
04474 cycles--;
04475 if (!cycles) return;
04476 }
04477 one_stop_bundles = cycles % 2;
04478 two_stop_bundles = cycles / 2;
04479
04480
04481
04482
04483 for (ibundle = 0; ibundle < ISA_MAX_BUNDLES; ++ibundle) {
04484 stop_mask = ISA_EXEC_Stop_Mask(ibundle);
04485 slot_mask = ISA_EXEC_Slot_Mask(ibundle);
04486 if (stop_mask == 2) break;
04487 }
04488 stop_mask |= 0x1;
04489
04490
04491 while (two_stop_bundles) {
04492 slot = 0;
04493 do {
04494 unit = (ISA_EXEC_UNIT_PROPERTY)(
04495 (slot_mask >> (ISA_TAG_SHIFT * slot))
04496 & ((1 << ISA_TAG_SHIFT) - 1));
04497 new_op = Mk_OP (CGTARG_Noop_Top(unit), True_TN, Gen_Literal_TN(0, 4));
04498
04499 if((stop_mask >> slot) & 0x1) Set_OP_end_group(new_op);
04500 BB_Insert_Op_Before (bb, op, new_op);
04501 op = new_op;
04502 slot++;
04503 } while (slot < ISA_MAX_SLOTS);
04504 Set_OP_start_bundle(op);
04505 two_stop_bundles--;
04506 }
04507
04508
04509
04510
04511 for (ibundle = 0; ibundle < ISA_MAX_BUNDLES; ++ibundle) {
04512 stop_mask = ISA_EXEC_Stop_Mask(ibundle);
04513 slot_mask = ISA_EXEC_Slot_Mask(ibundle);
04514 if (stop_mask == 0) break;
04515 }
04516 stop_mask |= 0x1;
04517
04518
04519 if (one_stop_bundles) {
04520 slot = 0;
04521 do {
04522 unit = (ISA_EXEC_UNIT_PROPERTY)(
04523 (slot_mask >> (ISA_TAG_SHIFT * slot))
04524 & ((1 << ISA_TAG_SHIFT) - 1));
04525 new_op = Mk_OP (CGTARG_Noop_Top(unit), True_TN, Gen_Literal_TN(0, 4));
04526
04527 if((stop_mask >> slot) & 0x1) Set_OP_end_group(new_op);
04528 BB_Insert_Op_Before (bb, op, new_op);
04529 op = new_op;
04530 slot++;
04531 } while (slot < ISA_MAX_SLOTS);
04532 Set_OP_start_bundle(op);
04533 }
04534 }
04535
04536
04537
04538
04539
04540
04541
04542 static
04543 OP *OP_Replace_With_Noop(BB *bb, OP *op)
04544 {
04545 OP *new_op;
04546 ISA_EXEC_UNIT_PROPERTY unit;
04547
04548 if ( EXEC_PROPERTY_is_M_Unit(OP_code(op)) && EXEC_PROPERTY_is_I_Unit(OP_code(op)) )
04549 unit = OP_m_unit(op)? ISA_EXEC_PROPERTY_M_Unit : ISA_EXEC_PROPERTY_I_Unit;
04550 else unit = ISA_EXEC_Unit_Prop(OP_code(op));
04551
04552
04553 if (EXEC_PROPERTY_is_B_Unit(OP_code(op))) { unit = ISA_EXEC_PROPERTY_B_Unit; }
04554
04555 new_op = Mk_OP (CGTARG_Noop_Top(unit), True_TN, Gen_Literal_TN(0, 4));
04556 OP_flags(new_op) = OP_flags(op);
04557 BB_Insert_Op_Before(bb, op, new_op);
04558 BB_Remove_Op(bb, op);
04559 return new_op;
04560 }
04561
04562
04563
04564
04565
04566
04567
04568
04569
04570 void
04571 Fix_MM_Latency ( BB *bb, TOP_SET *src_op_class, TOP_SET *tgt_op_class, UINT8 cycles_apart)
04572 {
04573 UINT i, j, k, cycles = 0;
04574 OP *op, *src_op, *tgt_op;
04575 ISA_EXEC_UNIT_PROPERTY unit;
04576
04577 FOR_ALL_BB_OPs(bb,op) {
04578 if (OP_dummy(op) || OP_simulated(op)) continue;
04579 if (find((*src_op_class).begin (),
04580 (*src_op_class).end (),
04581 Sched_Info_Class(op)) != (*src_op_class).end()) {
04582 src_op = op;
04583 if (OP_end_group(op)) cycles++;
04584 tgt_op = OP_next(op);
04585 for (; tgt_op; tgt_op = OP_next(tgt_op)) {
04586 if (OP_dummy(op) || OP_simulated(op)) continue;
04587 if (cycles >= cycles_apart) {
04588 break;
04589 } else if (find((*tgt_op_class).begin(), (*tgt_op_class).end(),
04590 Sched_Info_Class(tgt_op)) != (*tgt_op_class).end()) {
04591 for (i = 0; i < OP_results(src_op); i++) {
04592 for (j = 0; j < OP_opnds(tgt_op); j++) {
04593 if (OP_result(src_op, i) == OP_opnd(tgt_op, j)) {
04594 for (op = OP_next(src_op); op != tgt_op; op = OP_next(op)) if (OP_start_bundle(op)) break;
04595
04596 if (op == tgt_op && !OP_start_bundle(tgt_op)) {
04597 OPS new_ops = OPS_EMPTY;
04598 OP *new_op;
04599
04600
04601 op = src_op;
04602 while (!OP_start_bundle(op)) op = OP_prev(op);
04603
04604
04605 do {
04606 new_op = Dup_OP(op);
04607
04608 if (OP_end_group(op)) cycles++;
04609
04610
04611
04612 if (op == tgt_op) tgt_op = new_op;
04613 OPS_Append_Op(&new_ops, new_op);
04614 op = OP_next(op);
04615 } while (op && !OP_start_bundle(op));
04616
04617 if (!op) op = BB_last_op(bb); else op = OP_prev(op);
04618 BB_Insert_Ops_After(bb, op, &new_ops);
04619
04620
04621 for (op = OP_next(src_op); !OP_start_bundle(op); op = OP_next(op)) {
04622 if (OP_dummy(op) || OP_simulated(op)) continue;
04623 op = OP_Replace_With_Noop(bb, op);
04624 }
04625
04626
04627 for ( ; op != tgt_op; op = OP_next(op)) {
04628 if (OP_dummy(op) || OP_simulated(op)) continue;
04629 op = OP_Replace_With_Noop(bb, op);
04630 }
04631
04632
04633 while (!OP_start_bundle(op)) op = OP_prev(op);
04634 Pad_Cycles_Before(bb, op, cycles_apart - cycles);
04635
04636 } else {
04637 for (op = tgt_op; !OP_start_bundle(op); op = OP_prev(op));
04638 Pad_Cycles_Before(bb, op, cycles_apart - cycles);
04639 }
04640 break;
04641 }
04642 }
04643 if (j < OP_opnds(tgt_op)) break;
04644 }
04645 if (j < OP_opnds(tgt_op)) break;
04646 }
04647 if (OP_end_group(tgt_op)) cycles++;
04648 }
04649
04650 op = src_op;
04651 cycles = 0;
04652 }
04653 }
04654 }
04655 void Pad_Cycles_Into(BB *bb, OP* src_op, OP *tgt_op, INT cycles)
04656 {
04657 if (cycles <=0) return;
04658
04659 OP *op;
04660
04661 for (op = OP_next(src_op); op != tgt_op; op = OP_next(op))
04662 if (OP_start_bundle(op)) break;
04663
04664
04665 if (op == tgt_op && !OP_start_bundle(tgt_op)) {
04666 OPS new_ops = OPS_EMPTY;
04667 OP *new_op;
04668
04669
04670 op = src_op;
04671 while (!OP_start_bundle(op)) op = OP_prev(op);
04672
04673
04674 do {
04675 new_op = Dup_OP(op);
04676
04677 if (OP_has_tag(op)) return;
04678
04679 if (OP_end_group(op)) cycles--;
04680
04681
04682
04683 if (op == tgt_op) tgt_op = new_op;
04684 OPS_Append_Op(&new_ops, new_op);
04685 op = OP_next(op);
04686 } while (op && !OP_start_bundle(op));
04687
04688
04689 if ((OPS_length(&new_ops) % ISA_MAX_SLOTS) !=0) return;
04690
04691 if (!op) op = BB_last_op(bb);
04692 else op = OP_prev(op);
04693 BB_Insert_Ops_After(bb, op, &new_ops);
04694
04695
04696 for (op = OP_next(src_op); !OP_start_bundle(op); op = OP_next(op)) {
04697 if (OP_dummy(op) || OP_simulated(op) || OP_noop(op)) continue;
04698 op = OP_Replace_With_Noop(bb, op);
04699 }
04700
04701
04702 for ( ; op != tgt_op; op = OP_next(op)) {
04703 if (OP_dummy(op) || OP_simulated(op)) continue;
04704 op = OP_Replace_With_Noop(bb, op);
04705 }
04706
04707
04708 while (!OP_start_bundle(op)) op = OP_prev(op);
04709 if (cycles > 0) Pad_Cycles_Before(bb, op, cycles);
04710
04711 } else {
04712 for (op = tgt_op; !OP_start_bundle(op); op = OP_prev(op));
04713 Pad_Cycles_Before(bb, op, cycles);
04714 }
04715 }
04716
04717
04718
04719
04720 void Fix_Cache_Conflict_latency(BB *bb){
04721 INT op_order = 0;
04722 BOOL trace = Get_Trace(TP_A_CANA, 0x1);
04723 OP *op;
04724 std::vector <OP *> mem_ops;
04725 OP_MAP reverse_order = OP_MAP32_Create();
04726 FOR_ALL_BB_OPs_REV(bb,op) {
04727
04728
04729
04730
04731 if (OP_prev(op) && OP_end_group(OP_prev(op))) {
04732 op_order++;
04733 }
04734
04735 if (OP_dummy(op) && OP_simulated(op)) continue;
04736 if (!OP_load(op) && !OP_store(op)) continue;
04737
04738 if (OP_prev(op) && OP_end_group(OP_prev(op)))
04739 OP_MAP32_Set(reverse_order,op,op_order-1);
04740 else
04741 OP_MAP32_Set(reverse_order,op,op_order);
04742
04743 for (INT i=0; i<mem_ops.size(); i++) {
04744
04745 if (OP_bb(mem_ops[i]) != bb) continue;
04746 INT distance=0;
04747 BOOL equal;
04748 INT succ_order = OP_MAP32_Get(reverse_order,mem_ops[i]);
04749 INT cur_order = OP_MAP32_Get(reverse_order,op);
04750
04751 if (Cache_Has_Conflict(op,mem_ops[i], &distance, &equal)) {
04752 if (!equal) continue;
04753 INT current_dist = cur_order - succ_order;
04754 Is_True(current_dist >=0, ("order is not accurate!"));
04755 if (distance > current_dist) {
04756 if (trace) {
04757 fprintf(TFile, "fill %d cycles with nop in BB %d between\n",
04758 distance-current_dist,
04759 BB_id(bb));
04760 Print_OP_No_SrcLine(op);
04761 fprintf(TFile, "and\n");
04762 Print_OP_No_SrcLine(mem_ops[i]);
04763 }
04764 Pad_Cycles_Into(bb,op,mem_ops[i],distance-current_dist);
04765
04766
04767 for (INT j=mem_ops.size()-1; j>=0; j--) {
04768
04769
04770
04771 if (mem_ops[j] == mem_ops[i]) break;
04772 INT updated_order = OP_MAP32_Get(reverse_order,mem_ops[j]);
04773 if (updated_order == succ_order) break;
04774 updated_order = updated_order+distance-current_dist;
04775 OP_MAP32_Set(reverse_order,mem_ops[j],updated_order);
04776 }
04777 cur_order += distance-current_dist;
04778 OP_MAP32_Set(reverse_order,op,cur_order);
04779 op_order += distance-current_dist;
04780 }
04781 }
04782 }
04783
04784 mem_ops.push_back(op);
04785 }
04786 }
04787
04788
04789 INT32 CGTARG_Max_Number_of_Hidden_Opnd (mTOP top) {
04790 if (TOP_is_call (top)) {
04791 return MAX_NUMBER_OF_REGISTER_PARAMETERS*2;
04792 } else if (top == TOP_br_ret) {
04793 return MAX_NUMBER_OF_REGISTERS_FOR_RETURN*2;
04794 }
04795
04796 return 0;
04797 }
04798
04799
04800
04801 void CGTARG_Add_Implict_Operands (void) {
04802
04803 vector<TN*> opnds(16);
04804 OP* op;
04805
04806 for (BB* blk = REGION_First_BB; blk != NULL; blk = BB_next(blk)) {
04807 if (!BB_call(blk) && !BB_exit (blk)) continue;
04808
04809 opnds.clear ();
04810 FOR_ALL_BB_OPs (blk, op) {
04811 for (INT i = 0; i < OP_results(op); i++) {
04812 TN* res = OP_result(op, i);
04813 if (!TN_is_register (res) || !TN_is_dedicated(res)) {
04814 continue;
04815 }
04816
04817 if (BB_call(blk)) {
04818 PREG_NUM pnum = TN_To_PREG (res);
04819 if ((Is_Int_Output_Preg (pnum) || Is_Fp_Output_Preg
04820 (pnum)) &&
04821 find(opnds.begin (), opnds.end(), res) == opnds.end())
04822 {
04823 opnds.push_back (res);
04824 }
04825 } else if (Is_Return_Preg (TN_To_PREG (res)) &&
04826 find(opnds.begin (), opnds.end(), res) ==
04827 opnds.end()) {
04828 opnds.push_back (res);
04829 }
04830 }
04831 }
04832
04833 if (opnds.size () != 0) {
04834 OP* xfer = BB_xfer_op (blk);
04835 Is_True (TOP_is_call (OP_code(xfer)) ||
04836 OP_code(xfer) == TOP_br_ret,
04837 ("expected xfer op is either call or return"));
04838 Add_Hidden_Operands (xfer, opnds);
04839 }
04840 }
04841 }
04842
04843
04844
04845 BOOL CGTARG_Load_with_UNAT (OP* op) {
04846
04847 switch (OP_code(op)) {
04848 case TOP_ld8_fill:
04849 case TOP_ld8_r_fill:
04850 case TOP_ld8_i_fill:
04851 case TOP_ldf_fill:
04852 case TOP_ldf_r_fill:
04853 case TOP_ldf_i_fill:
04854 return TRUE;
04855 }
04856
04857 return FALSE;
04858 }
04859
04860
04861 BOOL CGTARG_Store_With_UNAT (OP* op) {
04862
04863 switch (OP_code(op)) {
04864 case TOP_st8_spill:
04865 case TOP_st8_i_spill:
04866 case TOP_stf_spill:
04867 case TOP_stf_i_spill:
04868 return TRUE;
04869 }
04870
04871 return FALSE;
04872 }