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 #include <map>
00046 #include <vector>
00047
00048 #include "errors.h"
00049 #include "op_map.h"
00050 #include "timing.h"
00051 #include "tracing.h"
00052
00053 #include "op.h"
00054 #include "dag.h"
00055
00056 #include "targ_isa_bundle.h"
00057 #include "ipfec_options.h"
00058 #include "msched_util.h"
00059 #include "cggrp_microsched.h"
00060 #include "cggrp_ptn_table.h"
00061
00062
00063 #define CYCLE_MAX_LENGTH (ISA_MAX_SLOTS * ISA_MAX_ISSUE_BUNDLES)
00064 typedef mINT16 OP_IDX;
00065
00066 enum { invalid_op_idx = -1, invalid_ptn_idx = -1 };
00067 typedef enum {
00068 ptn1_better_than_ptn2,
00069 ptn1_ptn2_is_tie,
00070 ptn1_less_than_ptn2
00071 } PTN_PRIORITY;
00072
00073
00074
00075
00076
00077
00078
00079
00080
00081
00082
00083
00084
00085
00086
00087
00088
00089
00090
00091
00092
00093 enum CYCLE_FLAGS{
00094 CYCLE_FILL_NOP_A,
00095
00096 CYCLE_FILL_NOP_B,
00097 CYCLE_STRICT_ORDER,
00098 CYCLE_HAS_BRANCH
00099 };
00100
00101 class CYCLE_STATE{
00102 protected:
00103 BOOL _valid;
00104 BOOL _fRequire;
00105 BOOL _lRequire;
00106 BOOL _dependency_exist;
00107 BOOL _cyclic;
00108
00109 mINT16 _flags;
00110
00111
00112 OP_IDX _num_ops;
00113 mINT16 _extra_slots;
00114 GROUP_ASSEMBLE group_assemble;
00115
00116
00117 struct OP_ISSUE_STATE{
00118 OP *op;
00119 ISSUE_PORT op_fu;
00120 PORT_SET set_op_fu;
00121 std::vector<OP_IDX> preds;
00122 } _ops[CYCLE_MAX_LENGTH];
00123
00124
00125
00126 std::vector <OP_IDX> _fu_owner;
00127
00128
00129 PORT_SET _reserve;
00130 INT _ptn;
00131
00132 OP_ISSUE_STATE& _OP_State(OP_IDX i)
00133 {
00134 Is_True(i<_num_ops, ("Invalid _ops[%d] access in cycle!", i));
00135 return _ops[i];
00136 }
00137
00138 const OP_ISSUE_STATE& _const_OP_State(OP_IDX i) const
00139 {
00140 Is_True(i<_num_ops, ("Invalid _ops[%d] access in cycle!", i));
00141 return _ops[i];
00142 }
00143 void Init_Mem(void);
00144
00145 public:
00146 CYCLE_STATE(void);
00147 ~CYCLE_STATE(void);
00148
00149 CYCLE_STATE& operator = (const CYCLE_STATE);
00150
00151
00152 OP_IDX Sum_OP(void) const { return _num_ops; }
00153 BOOL Empty(void) const { return Sum_OP() == 0; }
00154 BOOL Full(void) const
00155 { return (Sum_OP()+_extra_slots) >= CYCLE_MAX_LENGTH;}
00156
00157 BOOL Valid(void) const { return _valid; }
00158 BOOL Valid(BOOL val) { return _valid = val; }
00159
00160 BOOL Risky(void) const
00161 {
00162
00163
00164
00165
00166
00167
00168 if (PROCESSOR_Version == 2 && Strict_Order()) return FALSE;
00169 OP_IDX op_index = OP_In_Port(ip_M0);
00170 if ( (op_index!=invalid_op_idx) && ((OP_Preds(op_index)).size()) ){
00171 return TRUE;
00172 }
00173 return FALSE;
00174 }
00175
00176 BOOL Cyclic(void) const {return _cyclic;}
00177 BOOL Cyclic(BOOL val) { return _cyclic = val; }
00178 BOOL Require_First(void) const { return _fRequire; }
00179 BOOL Require_Last(void) const { return _lRequire; }
00180 BOOL Is_Dependency(void) const { return _dependency_exist; }
00181 BOOL Fill_After(void) const { return _flags & (1 << CYCLE_FILL_NOP_A); }
00182 BOOL Fill_Before(void) const { return _flags & (1 << CYCLE_FILL_NOP_B); }
00183 BOOL Strict_Order(void) const { return _flags & (1 << CYCLE_STRICT_ORDER); }
00184 BOOL Branch_Exist(void) const { return _flags & (1 << CYCLE_HAS_BRANCH); }
00185 BOOL Set_Flags(enum CYCLE_FLAGS order) {return _flags |= (1<<order); }
00186
00187 BOOL Legality_Chk_Needed(void) const
00188 { return _dependency_exist|| _fRequire|| _lRequire||(_extra_slots>0)
00189 ||Branch_Exist();}
00190 BOOL Legality_Chk(const PATTERN_TYPE ptn);
00191
00192 PORT_SET Reserve(void) const { return _reserve; }
00193
00194 INT Current_Pattern(void) const { return _ptn; }
00195 INT Current_Pattern(INT p) { return _ptn = p; }
00196
00197 GROUP_ASSEMBLE Assemble(void) {return group_assemble;}
00198
00199
00200 const PATTERN_TYPE Current_Pattern_Type(void)
00201 { return Patterns()[Current_Pattern()]; }
00202
00203 void Clear(void);
00204
00205
00206 OP_IDX OP_In_Port(ISSUE_PORT port) const
00207 {
00208 Is_True((port < ip_invalid),("Invalid Issue Port"));
00209 return _fu_owner[port];
00210 }
00211
00212
00213 ISSUE_PORT OP_Issue_Port(OP_IDX op_index) const
00214 { return _const_OP_State(op_index).op_fu;}
00215
00216
00217 ISSUE_PORT Get_Issue_Port (OP * inst) {
00218 for (OP_IDX i=0;i<_num_ops;i++) {
00219 if (_ops[i].op == inst) {
00220 return OP_Issue_Port(i);
00221 }
00222 }
00223 }
00224
00225
00226 void Set_Issue_Port (OP *inst,PORT_SET set_op_fu) {
00227 for (OP_IDX i=0; i<_num_ops; i++) {
00228 if (_ops[i].op == inst) {
00229 _ops[i].set_op_fu = _ops[i].set_op_fu - set_op_fu;
00230 }
00231 }
00232 }
00233
00234
00235 inline void OP_Issue_Port(OP_IDX op_index, ISSUE_PORT port);
00236 inline void Clear_OP_Issue_Port(INT op_index);
00237
00238 OP * operator [](OP_IDX op_idx) const
00239 { return (_const_OP_State(op_idx)).op; }
00240 const std::vector<OP_IDX> OP_Preds(OP_IDX i) const
00241 { return (_const_OP_State(i)).preds; }
00242
00243 OP_IDX Add_OP(OP * inst, ISSUE_PORT issue_port = ip_invalid);
00244
00245
00246 BOOL Has_Valid_Patterns(void) const
00247 { return PTN_table.Is_Valid(_reserve.Body()); }
00248 const PTN_TABLE_LINE& Patterns(void) const
00249 { return PTN_table[_reserve.Body()]; }
00250
00251 INT Get_B_Unit_Num(void);
00252 void Polish_Tail(void);
00253 void Do_Bundling(void);
00254 OP * Reorder_Branch_OP(void);
00255
00256
00257 BOOL Best_Issue_Order(INT *issue_op_list,PATTERN_TYPE pattern);;
00258 BOOL Best_Issue_Order(INT *issue_op_list);;
00259 void Set_M_Unit (void);
00260
00261 void Dump (FILE *f=stderr) ;
00262 #ifdef Is_True_On
00263 void gdb_dump(void) ;
00264 #endif
00265
00266 };
00267
00268
00270
00271 CYCLE_STATE::CYCLE_STATE(void)
00272 {
00273 Init_Mem();
00274 Clear();
00275 }
00276
00277 void CYCLE_STATE::Init_Mem(void)
00278 {
00279 _fu_owner.clear();
00280 for (INT j=0; j<ip_number; j++) {
00281 _fu_owner.push_back(invalid_op_idx);
00282 }
00283 }
00284 CYCLE_STATE::~CYCLE_STATE(void)
00285 {
00286 _fu_owner.clear();
00287 }
00288 void CYCLE_STATE::Clear(void)
00289 {
00290 _valid = FALSE;
00291 _fRequire = FALSE;
00292 _lRequire = FALSE;
00293 _cyclic = FALSE;
00294 _dependency_exist = FALSE;
00295 _flags = 0;
00296
00297 _num_ops = 0;
00298 _extra_slots = 0;
00299
00300 _reserve =0;
00301
00302 for (OP_IDX i=0; i< CYCLE_MAX_LENGTH; i++){
00303 _ops[i].op = NULL;
00304 _ops[i].op_fu = ip_invalid;
00305 _ops[i].set_op_fu = 0;
00306 _ops[i].preds.clear() ;
00307 }
00308
00309
00310 for (INT j=0; j<ip_number; j++) {
00311 _fu_owner[j] = invalid_op_idx;
00312 }
00313 }
00314
00315
00316 CYCLE_STATE& CYCLE_STATE::operator=(const CYCLE_STATE cs)
00317 {
00318 _valid = cs._valid;
00319 _fRequire = cs._fRequire;
00320 _lRequire = cs._lRequire;
00321 _cyclic = cs._cyclic;
00322 _dependency_exist = cs._dependency_exist;
00323 _num_ops = cs._num_ops;
00324 _extra_slots = cs._extra_slots;
00325 _flags = cs._flags;
00326
00327 _reserve = cs._reserve;
00328 _ptn = cs._ptn;
00329
00330 for (OP_IDX i=0; i< CYCLE_MAX_LENGTH; i++){
00331 _ops[i].op = cs._ops[i].op;
00332 _ops[i].op_fu = cs._ops[i].op_fu;
00333 _ops[i].set_op_fu = cs._ops[i].set_op_fu;
00334 _ops[i].preds = cs._ops[i].preds;
00335 }
00336
00337 for (INT j=0; j<ip_invalid; j++){
00338 _fu_owner[j]= cs._fu_owner[j];
00339 }
00340 return *this;
00341 }
00342
00343 inline void CYCLE_STATE::OP_Issue_Port(OP_IDX op_index, ISSUE_PORT port)
00344 {
00345 Is_True((port < ip_invalid),("Invalid Issue Port"));
00346 _OP_State(op_index).op_fu = port;
00347 _fu_owner[port] = op_index;
00348 _reserve = _reserve + port;
00349
00350 if (Long_Instruction((*this)[op_index])){
00351
00352 Is_True( F_PORTS.In(port), ("LX only issued to FI in Itanium!"));
00353 ISSUE_PORT extra_i = (ISSUE_PORT)(ip_I0 + (port-ip_F0));
00354 Is_True( !_reserve.In(extra_i),
00355 ("LX occupies Fx and Ix at the same time in Itanium"));
00356 _reserve = _reserve + extra_i;
00357 }
00358 }
00359
00360 inline void CYCLE_STATE::Clear_OP_Issue_Port(INT op_index)
00361 {
00362 ISSUE_PORT port = _OP_State(op_index).op_fu;
00363 if (port == ip_invalid){
00364 return;
00365 }
00366
00367 _OP_State(op_index).op_fu = ip_invalid;
00368 _fu_owner[port]= invalid_op_idx;
00369 _reserve = _reserve - port;
00370
00371 if (Long_Instruction((*this)[op_index])){
00372
00373 Is_True( F_PORTS.In(port), ("LX only issued to FI in Itanium!"));
00374 ISSUE_PORT extra_i = (ISSUE_PORT)(ip_I0 + (port-ip_F0));
00375 Is_True(_fu_owner[extra_i] == invalid_op_idx,
00376 ("LX should occupies F0 and I0 at the same time in Itanium"));
00377 _reserve = _reserve - extra_i;
00378 }
00379 }
00381
00382
00383
00384
00385
00386
00387 BOOL CYCLE_STATE::Best_Issue_Order(INT *issue_op_list)
00388 {
00389 const PATTERN_TYPE ptn = Current_Pattern_Type();
00390 return Best_Issue_Order(issue_op_list, ptn);
00391 }
00392 BOOL CYCLE_STATE::Best_Issue_Order(INT *issue_op_list, PATTERN_TYPE ptn)
00393 {
00394 ISSUE_PORT issue_port;
00395 BOOL is_first_pos=true;
00396 BOOL group_start=false;
00397 BOOL issued[CYCLE_MAX_LENGTH] = {false, false};
00398
00399 const DISPERSAL_TARG *ports_vector = dispersal_table.Query(&ptn);
00400 for (INT bundle=0; bundle<ISA_MAX_ISSUE_BUNDLES; bundle++)
00401 {
00402 INT template_index = ptn[bundle];
00403 if (template_index == ISA_MAX_BUNDLES){
00404
00405 break;
00406 }
00407 for (INT slot=0; slot<ISA_MAX_SLOTS; slot++)
00408 {
00409 INT idx = bundle * ISA_MAX_SLOTS + slot;
00410 issue_op_list[idx] = invalid_op_idx;
00411 if (ptn.start_in_bundle && !group_start &&
00412 ISA_EXEC_Stop(template_index, slot)) {
00413 group_start = true;
00414 continue;
00415 }
00416 if (!group_start && ptn.start_in_bundle) continue;
00417
00418
00419
00420
00421
00422
00423 PORT_SET ports = ports_vector->Ports(bundle, slot);
00424
00425 ISSUE_PORT issue_port = ports.First_IP();
00426 for (INT ip=issue_port; ip <= ip_invalid; ip++)
00427 {
00428 issue_port = (ISSUE_PORT)ip;
00429 if (issue_port == ip_invalid) break;
00430 if (!ports.In(issue_port)) continue;
00431 OP_IDX op_index = OP_In_Port(issue_port);
00432 if (op_index != invalid_op_idx) {
00433 if (_fRequire && is_first_pos
00434 && !TOP_is_f_group(OP_code((*this)[op_index])) )
00435 continue;
00436
00437 is_first_pos = false;
00438
00439 if (issued[op_index] != true) {
00440
00441
00442 BOOL pred_issued = true;
00443 for (INT m=0; m<(OP_Preds(op_index)).size(); m++){
00444 OP_IDX pred = OP_Preds(op_index)[m];
00445 if (!issued[pred]){
00446
00447 pred_issued = false;
00448 break;
00449 }
00450 }
00451 if (pred_issued) { break;}
00452 }
00453 }
00454 }
00455 if (issue_port == ip_invalid) {
00456 issue_op_list[idx] = invalid_op_idx;
00457 }else {
00458
00459
00460 if (!_reserve.In(issue_port)) {return false;}
00461 OP_IDX op_idx = OP_In_Port(issue_port);
00462 issue_op_list[idx] = op_idx;
00463 issued[op_idx] = true;
00464 }
00465 }
00466 }
00467 return true;
00468 }
00470
00471
00472
00473
00474
00475 OP_IDX CYCLE_STATE::Add_OP( OP * inst,
00476 ISSUE_PORT issue_port)
00477 {
00478
00479 std::vector<OP_IDX> preds_vector;
00480
00481 Is_True(_num_ops < CYCLE_MAX_LENGTH,
00482 ("Adding too many operations in a cycle!"));
00483
00484 if (OP_xfer(inst)) {
00485 if (Branch_Exist()) {
00486
00487
00488 } else {
00489 Set_Flags(CYCLE_HAS_BRANCH);
00490 }
00491 }
00492 if (IPFEC_sched_care_machine == Sched_care_bundle){
00493 if (TOP_is_f_group(OP_code(inst))){
00494 if (Require_First()){
00495
00496 return invalid_op_idx;
00497 }
00498 else{
00499 _fRequire = TRUE;
00500 }
00501 }
00502 if (TOP_is_l_group(OP_code(inst))) {
00503 if (Require_Last()){
00504
00505 return invalid_op_idx;
00506 }
00507 else{
00508 _lRequire = TRUE;
00509 }
00510 }
00511
00512 if (!Empty()) {
00513
00514
00515 if (Strict_Order()) {
00516 INT last_idx=0;
00517 for (OP_IDX op_idx=0; op_idx< Sum_OP(); op_idx++){
00518 OP *exist_op = (*this)[op_idx];
00519 if (Dependence_Between(inst,exist_op) &&
00520 issue_port == ip_invalid)
00521 return invalid_op_idx;
00522
00523
00524
00525 if ((!OP_xfer(inst) || OP_chk(inst)) &&
00526 (OP_xfer(exist_op) && !OP_chk(exist_op)) &&
00527 OP_has_disjoint_predicate(inst,exist_op)) continue;
00528
00529 preds_vector.push_back(op_idx);
00530 }
00531 _dependency_exist =true;
00532
00533 } else {
00534 for (ARC_LIST *al = OP_preds(inst); al; al=ARC_LIST_rest(al)){
00535
00536 ARC *arc = ARC_LIST_first(al);
00537
00538
00539 if (_cyclic && ARC_omega(arc)!=0) continue;
00540
00541 if (PostBranchArc(arc)) {
00542 if (!OP_xfer(inst) || OP_chk(inst)) continue ;
00543 }
00544
00545 OP *pred = ARC_pred(arc);
00546 for (OP_IDX op_idx=0; op_idx< Sum_OP(); op_idx++){
00547 OP *exist_op = (*this)[op_idx];
00548 if (pred == exist_op){
00549
00550 if (!Dependence_Between(inst, exist_op)
00551 || ARC_latency(arc)==0 ||
00552 (_cyclic && (OP_scycle(inst)!=OP_scycle(exist_op)))) {
00553
00554
00555 _dependency_exist = true;
00556 preds_vector.push_back(op_idx);
00557 }
00558 else{
00559 return invalid_op_idx;
00560 }
00561 }
00562 }
00563 }
00564 }
00565 }
00566 }
00567
00568
00569 _ops[_num_ops].op = inst;
00570 _ops[_num_ops].op_fu = issue_port;
00571 _ops[_num_ops].preds = preds_vector;
00572 _ops[_num_ops].set_op_fu = TSI_Issue_Ports(OP_code(inst));
00573 _num_ops++;
00574 _extra_slots += Instruction_Length(inst) - 1;
00575 if (issue_port!= ip_invalid){
00576 OP_Issue_Port(_num_ops-1, issue_port);
00577 }
00578 return _num_ops-1;
00579 }
00580
00582
00583
00584
00585
00586
00587
00588
00589
00590
00591
00592
00593
00594
00595
00596
00597
00598
00599
00600
00601 BOOL CYCLE_STATE::Legality_Chk(const PATTERN_TYPE ptn)
00602 {
00603
00604
00605 BOOL use_tail = ptn.start_in_bundle;
00606
00607 BOOL issued[CYCLE_MAX_LENGTH]= {false, false};
00608 BOOL first_stop_hit = false;
00609 BOOL last_stop_hit = false;
00610 BOOL is_first_pos = true;
00611 BOOL has_issue_br_op = false;
00612 OP_IDX op_index;
00613 ISSUE_PORT issue_port;
00614 const DISPERSAL_TARG *ports_vector = dispersal_table.Query(&ptn);
00615
00616 #ifdef Is_True_On
00617 if (use_tail){
00618
00619 Is_True(ISA_EXEC_Stop_Mask(ptn[0])!=0,
00620 ("Invalid Compressed Template!"));
00621 }
00622 #endif
00623
00624 INT issue_op_list[CYCLE_MAX_LENGTH];
00625 if (!Best_Issue_Order(issue_op_list,ptn)) {
00626
00627 return FALSE;
00628 }
00629 for (INT bundle=0; bundle < ISA_MAX_ISSUE_BUNDLES; bundle++){
00630 INT template_index = ptn[bundle];
00631 if (template_index == ISA_MAX_BUNDLES){
00632
00633 break;
00634 }
00635 for (INT slot=0; slot < ISA_MAX_SLOTS; slot++){
00636 if (use_tail && !first_stop_hit){
00637
00638 first_stop_hit = ISA_EXEC_Stop(template_index, slot);
00639 }
00640 else{
00641 ISA_EXEC_UNIT_PROPERTY slot_prop =
00642 ISA_EXEC_Slot_Prop(template_index, slot);
00643
00644
00645 op_index = issue_op_list[ bundle * ISA_MAX_SLOTS + slot ];
00646
00647 if (op_index == invalid_op_idx){
00648
00649 is_first_pos = FALSE;
00650 last_stop_hit = ISA_EXEC_Stop(template_index, slot);
00651 if (last_stop_hit) {
00652 break;
00653 }
00654 continue;
00655 } else {
00656
00657 issue_port = OP_Issue_Port(op_index);
00658 if (!Long_Instruction((*this)[op_index]) &&
00659 !_ops[op_index].set_op_fu.In(issue_port)) {
00660 return FALSE;
00661 }
00662 }
00663
00664 Is_True( issued[op_index] == false,
00665 ("OP issued twice in a cycle!"));
00666
00667 if (_fRequire && !is_first_pos
00668 && TOP_is_f_group(OP_code((*this)[op_index])) ){
00669
00670 return false;
00671 }
00672 is_first_pos = false;
00673
00674 if (Long_Instruction((*this)[op_index])){
00675
00676 if (slot_prop != ISA_EXEC_PROPERTY_L_Unit){
00677
00678 return FALSE;
00679 }
00680 }
00681 else {
00682 if (slot_prop == ISA_EXEC_PROPERTY_L_Unit){
00683
00684
00685 return FALSE;
00686 }
00687 }
00688
00689
00690
00691
00692 for (INT m=0; m<(OP_Preds(op_index)).size(); m++){
00693 OP_IDX pred = OP_Preds(op_index)[m];
00694 if (!issued[pred]){
00695
00696 return false;
00697 }
00698 }
00699 issued[op_index] = TRUE;
00700
00701 if (slot_prop == ISA_EXEC_PROPERTY_L_Unit){
00702
00703 slot ++;
00704 Is_True( slot < ISA_MAX_SLOTS,
00705 ("MAX slots exceeded in Legality_Chk!"));
00706
00707 issue_port = ports_vector->Port(bundle, slot);
00708 Is_True(issue_port!=ip_invalid,
00709 ("Invalid Pattern Found in Valid Pattern Table!"));
00710
00711
00712
00713 if (OP_In_Port(issue_port) != invalid_op_idx){
00714
00715 return false;
00716 }
00717 issued[op_index] = TRUE;
00718 }
00719
00720
00721
00722 if (Branch_Exist()) {
00723 if (OP_xfer((*this)[op_index]) &&
00724 !OP_chk((*this)[op_index])) {
00725 has_issue_br_op = TRUE;
00726 } else {
00727 if (has_issue_br_op && !OP_noop((*this)[op_index]) )
00728 return false;
00729 }
00730 }
00731 last_stop_hit = ISA_EXEC_Stop(template_index, slot);
00732 if (last_stop_hit){
00733 break;
00734 }
00735 }
00736 }
00737 }
00738
00739
00740 if (_lRequire &&
00741 (op_index==invalid_op_idx ||
00742 !TOP_is_l_group( OP_code((*this)[op_index])))) {
00743
00744 return false;
00745 }
00746
00747 for (INT I=0; I<Sum_OP(); I++){
00748 if (!issued[I]) {return false;}
00749 }
00750
00751 #ifdef Is_True_On
00752
00753 for (INT I=0; I<Sum_OP(); I++){
00754 Is_True(issued[I]==true, ("Some op not checked in Legality Check!"));
00755 }
00756 #endif
00757
00758 return true;
00759 }
00760
00762
00763
00764
00765
00766
00767
00768
00769
00770
00771
00772
00773
00774
00775
00776
00777 void CYCLE_STATE::Polish_Tail(void)
00778 {
00779 if (Empty()) return;
00780
00781 const PTN_TABLE_LINE ptns = Patterns();
00782 const PATTERN_TYPE s_ptn = ptns[Current_Pattern()];
00783
00784 INT good_ptn_idx = invalid_ptn_idx;
00785 INT probe_better_ptn_num = 0;
00786
00787 for (INT ptn_idx=Current_Pattern(); ptn_idx<ptns.size; ptn_idx++) {
00788 const PATTERN_TYPE ptn = ptns[ptn_idx];
00789
00790 if (ptn.end_in_bundle) {
00791
00792
00793 continue;
00794 }
00795
00796 if (ptn.start_in_bundle != s_ptn.start_in_bundle) {
00797 continue;
00798 }
00799
00800 if (ptn.start_in_bundle && ptn[0]!= s_ptn[0]){
00801 continue;
00802 }
00803 if (Legality_Chk_Needed() &&
00804 !Legality_Chk(ptn)){
00805 continue;
00806 }
00807
00808 Current_Pattern (ptn_idx);
00809 return;
00810 }
00811
00812 Is_True (FALSE,
00813 ("Fail to find a replacement for a compressed template!"));
00814
00815
00816 return;
00817 }
00818
00820
00821
00822
00823
00824
00825
00826 void CYCLE_STATE::Do_Bundling(void)
00827 {
00828 BOOL issued[CYCLE_MAX_LENGTH]= {false, false};
00829 BOOL first_stop_hit = false;
00830 BOOL last_stop_hit = false;
00831 BOOL is_first_pos = true;
00832 OP_IDX op_index;
00833
00834 if (Empty()) return;
00835
00836 const PATTERN_TYPE ptn = Current_Pattern_Type();
00837 ISSUE_PORT issue_port;
00838 const DISPERSAL_TARG *ports_vector = dispersal_table.Query(&ptn);
00839
00840
00841
00842
00843
00844 BB *bb = OP_bb((*this)[0]);
00845 OP *position = OP_prev((*this)[0]);
00846
00847 INT issue_op_list[ CYCLE_MAX_LENGTH ];
00848 if (!Best_Issue_Order(issue_op_list)) {
00849 Is_True(FALSE, ("Can't find a suitable issue order!"));
00850 }
00851
00852 for (INT bundle=0; bundle < ISA_MAX_ISSUE_BUNDLES; bundle++){
00853 INT template_index = ptn[bundle];
00854 OP *op = NULL;
00855 UINT slot;
00856
00857 if (template_index == ISA_MAX_BUNDLES){
00858 break;
00859 }
00860 Is_True( !last_stop_hit,
00861 ("Still bundle after stop bit!"));
00862 for (slot=0; slot < ISA_MAX_SLOTS; slot++){
00863 if ((Fill_Before() && !first_stop_hit)
00864 || (last_stop_hit && Fill_After())){
00865
00866 group_assemble.EmitNop(template_index, slot);
00867 }
00868
00869 if (last_stop_hit && Fill_After()) continue;
00870 if (ptn.start_in_bundle && !first_stop_hit) {
00871 first_stop_hit = ISA_EXEC_Stop(template_index, slot);
00872 continue;
00873 }
00874
00875 ISA_EXEC_UNIT_PROPERTY slot_prop =
00876 ISA_EXEC_Slot_Prop(template_index, slot);
00877
00878
00879 op_index = issue_op_list[bundle * ISA_MAX_SLOTS + slot];
00880
00881
00882 if (op_index == invalid_op_idx){
00883
00884 OP *op = group_assemble.EmitNop(template_index, slot);
00885 }
00886 else{
00887
00888 op = (*this)[op_index];
00889 Is_True(op,
00890 ("Invalid OP found in a cycle when do bundling!"));
00891 if(position == op) {
00892 position = OP_prev(position);
00893 }
00894
00895 BB_Remove_Op(bb, op);
00896 group_assemble.EmitOp(op, template_index, slot);
00897
00898 issued[op_index] = true;
00899 if (Long_Instruction(op)){
00900
00901 slot ++;
00902 Is_True( slot < ISA_MAX_SLOTS,
00903 ("MAX slots exceeded in bundling!"));
00904 Is_True( slot_prop == ISA_EXEC_PROPERTY_L_Unit,
00905 ("Long Instruction should issued in LX slots!"));
00906 issue_port = ports_vector->Port(bundle, slot);
00907 Is_True(issue_port!=ip_invalid,
00908 ("Invalid Pattern Found in Valid Pattern Table!"));
00909 op_index = OP_In_Port(issue_port);
00910 Is_True(op_index == invalid_op_idx,
00911 ("X slot occupied by other ops!"));
00912 }
00913 }
00914
00915 last_stop_hit = ISA_EXEC_Stop(template_index, slot);
00916 if (last_stop_hit){
00917
00918
00919 if (!Fill_After()) { break;}
00920 }
00921 }
00922 }
00923
00924
00925 group_assemble.Group_End();
00926 group_assemble.InsertAfter(bb,position);
00927
00928 #ifdef Is_True_On
00929
00930 for (INT I=0; I<Sum_OP(); I++){
00931 Is_True( issued[I]==true, ("Some op not issued in bundling!"));
00932 }
00933 #endif
00934
00935 return;
00936 }
00937
00939
00940
00941
00942 void
00943 CYCLE_STATE::Set_M_Unit (void) {
00944
00945 for (ISSUE_PORT p=ip_M0; M_PORTS.In(p); p=(ISSUE_PORT)(p+1)) {
00946 OP_IDX op_idx = _fu_owner[p];
00947 if (op_idx == invalid_op_idx) continue;
00948
00949 OP* op = _ops[op_idx].op;
00950 if (EXEC_PROPERTY_is_I_Unit(OP_code(op)) &&
00951 EXEC_PROPERTY_is_M_Unit(OP_code(op))) {
00952 Set_OP_m_unit(op);
00953 }
00954 }
00955 }
00956
00957
00958
00959
00960
00961
00962
00963
00964
00965 OP *
00966 CYCLE_STATE::Reorder_Branch_OP (void)
00967 {
00968 OP_IDX op_idx;
00969 OP *op=NULL;
00970 if (!Branch_Exist()) return NULL;
00971 INT last_idx = Sum_OP() - 1;
00972 for (op_idx=0; op_idx< last_idx; op_idx++){
00973 op = (*this)[op_idx];
00974 if (OP_xfer(op) && !OP_chk(op)) {
00975 break;
00976 }
00977 }
00978 if(op_idx < last_idx) {
00979 BB *bb = OP_bb(op);
00980 BB_Remove_Op(bb, op);
00981 mUINT16 old_map_idx = OP_map_idx(op);
00982 BB_Append_Op(bb, op);
00983 op->map_idx = old_map_idx;
00984 return op;
00985 }
00986 return NULL;
00987 }
00988
00990
00991
00992 static CYCLE_STATE prev_state, cur_state, temp_state;
00993
00995
00996
00997
00998 BOOL CGGRP_Cycle_Full(void)
00999 {
01000 if (!LOCS_Enable_Bundle_Formation){
01001 return (!cur_state.Empty());
01002 }
01003 return cur_state.Full();
01004 }
01005
01007
01008
01009
01010
01011
01012
01013
01014
01015
01016
01017
01018
01019 inline BOOL valid_ptn_found(BOOL commit)
01020 {
01021 temp_state.Valid(TRUE);
01022 if (commit){
01023 cur_state = temp_state;
01024 temp_state.Valid(FALSE);
01025 }
01026 return true;
01027 }
01028 inline BOOL invalid_ptn(void)
01029 {
01030 Is_True(!(temp_state.Empty()),
01031 ("Rejecting OP with an empty cycle!!"));
01032 temp_state.Valid(FALSE);
01033 return false;
01034 }
01035
01036
01037
01038
01039
01040
01041
01042
01043 static PORT_SET port_mark = 0;
01044
01045 static BOOL Bundle_Helper(OP_IDX new_op);
01046
01047
01048 BOOL CGGRP_Issue_OP(OP * inst, BOOL commit)
01049 {
01050 std::vector<OP_IDX> deps;
01051 OP_IDX op_index;
01052
01053 if (IPFEC_sched_care_machine == Sched_care_nothing)
01054 return TRUE;
01055
01056 PORT_SET issuable_ports = TSI_Issue_Ports(OP_code(inst));
01057 if (issuable_ports.Body() == 0){
01058 if (IPFEC_sched_care_machine < Sched_care_bundle){
01059 return TRUE;
01060 }
01061 if (commit && cur_state.Empty()){
01062
01063 CGGRP_Force_Bundle_End();
01064 }
01065 return cur_state.Empty();
01066 }
01067
01068 MSCHED_Real_OP(inst);
01069
01070 if (!LOCS_Enable_Bundle_Formation){
01071
01072
01073 if (!cur_state.Empty())
01074 return FALSE;
01075 if (cur_state.Add_OP(inst)== invalid_op_idx){
01076 cur_state.Clear();
01077 return FALSE;
01078 }
01079 if (!commit)
01080 cur_state.Clear();
01081 return TRUE;
01082 }
01083
01084 if (cur_state.Full()) return FALSE;
01085 if (temp_state.Valid() && temp_state[temp_state.Sum_OP()-1]==inst){
01086
01087 return valid_ptn_found(commit);
01088 }
01089
01090 temp_state = cur_state;
01091 temp_state.Current_Pattern(invalid_ptn_idx);
01092 op_index = temp_state.Add_OP(inst);
01093 if (op_index == invalid_op_idx){
01094 return invalid_ptn();
01095 }
01096 if (IPFEC_sched_care_machine == Sched_care_width){
01097 return valid_ptn_found(commit);
01098 }
01099
01100 Is_True( port_mark.Body()==0,
01101 ("Recursive Cleanup malfunctioning in Bundle_Helper!"));
01102
01103 if (Bundle_Helper(op_index) ){
01104 return valid_ptn_found(commit);
01105 }
01106
01107 return invalid_ptn();
01108 }
01109
01111
01112
01113
01114
01115
01116
01117
01118
01119
01120
01121
01122
01123
01124
01125
01126
01127
01128
01129
01130
01131 static BOOL Bundle_Helper(OP_IDX new_op)
01132 {
01133 PORT_SET issuable_ports = TSI_Issue_Ports(OP_code(temp_state[new_op]));
01134
01135 BOOL deal_with_LX = FALSE;
01136
01137 if ( Long_Instruction(temp_state[new_op]) ){
01138
01139
01140 deal_with_LX = TRUE;
01141 issuable_ports = F_PORTS;
01142 }
01143
01144 if ( (INT)(issuable_ports-port_mark) == 0){
01145
01146 return FALSE;
01147 }
01148
01149 PORT_SET available_ports = issuable_ports
01150 - (temp_state.Reserve())
01151 - port_mark;
01152
01153 INT i;
01154 for (i=0; issue_port_seq[i]<ip_invalid; i++){
01155 if (!available_ports.In(issue_port_seq[i])){
01156 continue;
01157 }
01158
01159 if (deal_with_LX){
01160
01161
01162 Is_True( F_PORTS.In(issue_port_seq[i]),
01163 ("LX only issued to FI in Itanium!"));
01164 ISSUE_PORT extra_i = (ISSUE_PORT)(ip_I0+(issue_port_seq[i]-ip_F0));
01165 if (temp_state.Reserve().In(extra_i))
01166 continue;
01167 }
01168
01169 Is_Violate_Issue_Rule(temp_state[new_op], issue_port_seq[i]);
01170
01171 temp_state.OP_Issue_Port(new_op, issue_port_seq[i]);
01172 if (IPFEC_sched_care_machine!=Sched_care_bundle){
01173 return TRUE;
01174 }
01175
01176 if (!temp_state.Has_Valid_Patterns()){
01177
01178 temp_state.Clear_OP_Issue_Port(new_op);
01179 continue;
01180 }
01181
01182 const PTN_TABLE_LINE ptns = temp_state.Patterns();
01183
01184 for (INT ptn_idx=0; ptn_idx<ptns.size; ptn_idx++){
01185 if (!IPFEC_Enable_Compressed_Template){
01186 if (ptns[ptn_idx].start_in_bundle ||
01187 ptns[ptn_idx].end_in_bundle)
01188 continue;
01189 }
01190
01191 if (prev_state.Empty() && ptns[ptn_idx].start_in_bundle){
01192 continue;
01193 }
01194
01195 if ((!temp_state.Legality_Chk_Needed())
01196 || (temp_state.Legality_Chk(ptns[ptn_idx]))){
01197
01198 if ( temp_state.Risky() && ptns[ptn_idx].start_in_bundle ){
01199
01200
01201
01202 continue;
01203 }
01204 if (temp_state.Current_Pattern() == invalid_ptn_idx) {
01205 temp_state.Current_Pattern(ptn_idx);
01206 return TRUE;
01207 }
01208 }
01209
01210 }
01211
01212 temp_state.Clear_OP_Issue_Port(new_op);
01213 }
01214
01215 if (deal_with_LX){
01216
01217 return FALSE;
01218 }
01219
01220 if (IPFEC_sched_care_machine!=Sched_care_bundle) {
01221
01222 return FALSE;
01223 }
01224
01225 PORT_SET reorder_ports = issuable_ports - port_mark - available_ports;
01226
01227 for (i=0; issue_port_seq[i]<ip_invalid; i++){
01228 if (!reorder_ports.In(issue_port_seq[i])){
01229 continue;
01230 }
01231 OP_IDX old_op = temp_state.OP_In_Port(issue_port_seq[i]);
01232
01233 if (old_op == invalid_op_idx){
01234
01235 Is_True( I_PORTS.In(issue_port_seq[i]),
01236 ("Invalid op_index when reordering old ops"));
01237 continue;
01238 }
01239
01240 temp_state.Clear_OP_Issue_Port(old_op);
01241 temp_state.OP_Issue_Port(new_op, issue_port_seq[i]);
01242 port_mark = port_mark + issue_port_seq[i];
01243
01244 if (Bundle_Helper(old_op)){
01245 port_mark = port_mark - issue_port_seq[i];
01246 return TRUE;
01247 }
01248
01249 port_mark = port_mark - issue_port_seq[i];
01250 temp_state.Clear_OP_Issue_Port(new_op);
01251 temp_state.OP_Issue_Port(old_op, issue_port_seq[i]);
01252 }
01253
01254
01255 for (i= temp_state.Sum_OP()-1 ; i>=0 ; i--) {
01256 if (EXEC_PROPERTY_is_I_Unit(OP_code(temp_state[new_op])) &&
01257 EXEC_PROPERTY_is_M_Unit(OP_code(temp_state[new_op]))) {
01258 break;
01259 }
01260 if (i == new_op) continue;
01261 OP *op = temp_state[i];
01262 if (EXEC_PROPERTY_is_I_Unit(OP_code(op)) &&
01263 EXEC_PROPERTY_is_M_Unit(OP_code(op))) {
01264 ISSUE_PORT issue_port = temp_state.OP_Issue_Port(i);
01265 if (port_mark.In(issue_port)) break;
01266
01267 if (M_PORTS.In(issue_port) &&
01268 (I_PORTS-temp_state.Reserve()) != 0) {
01269 temp_state.Clear_OP_Issue_Port(i);
01270 temp_state.OP_Issue_Port(i,(I_PORTS-temp_state.Reserve()).First_IP());
01271 } else if (I_PORTS.In(issue_port) &&
01272 (M_PORTS-temp_state.Reserve()) != 0) {
01273 temp_state.Clear_OP_Issue_Port(i);
01274 temp_state.OP_Issue_Port(i,(M_PORTS-temp_state.Reserve()).First_IP());
01275 }
01276 if (issue_port == temp_state.OP_Issue_Port(i)) break;
01277 port_mark = port_mark + issue_port + temp_state.OP_Issue_Port(i);
01278
01279 if (Bundle_Helper(new_op)) {
01280 port_mark = port_mark - issue_port - temp_state.OP_Issue_Port(i);
01281 return TRUE;
01282 }
01283 port_mark = port_mark - issue_port - temp_state.OP_Issue_Port(i);
01284 temp_state.Clear_OP_Issue_Port(i);
01285 temp_state.OP_Issue_Port(i,issue_port);
01286 break;
01287 }
01288 }
01289 return FALSE;
01290 }
01291
01293
01294
01295
01296 ISSUE_PORT CGGRP_Get_Issue_Port(OP *inst)
01297 {
01298 return cur_state.Get_Issue_Port(inst);
01299 }
01300
01302
01303
01304
01305
01306 void CGGRP_Set_Issue_Port( OP *inst,PORT_SET set_op_fu)
01307 {
01308 cur_state.Set_Issue_Port(inst,set_op_fu);
01309 }
01310
01312
01313
01314
01315
01316
01317
01318
01319
01320
01321
01322
01323
01324
01325
01326
01327 static void Negotiate_Bundle(void);
01328
01329 void CGGRP_Cycle_Advance(void)
01330 {
01331 if (cur_state.Empty()){
01332 cur_state.Clear();
01333 temp_state.Clear();
01334 return;
01335 }
01336
01337 if (!LOCS_Enable_Bundle_Formation){
01338
01339 Is_True(cur_state.Sum_OP()==1,
01340 ("More than one op found in one-op-per-cycle!"));
01341 Set_OP_end_group(cur_state[0]);
01342
01343
01344
01345
01346
01347 if (OP_simulated(cur_state[0])){
01348 MSCHED_Convert_Simulated(cur_state[0],
01349 ISA_EXEC_PROPERTY_I_Unit);
01350 }
01351 cur_state.Clear();
01352 temp_state.Clear();
01353 return;
01354 }
01355
01356 if (IPFEC_sched_care_machine!=Sched_care_bundle){
01357 if (cur_state.Valid()&& !cur_state.Empty()){
01358 OP *br_op = cur_state.Reorder_Branch_OP();
01359 if (br_op == NULL)
01360 Set_OP_end_group(cur_state[cur_state.Sum_OP()-1]);
01361 else
01362 Set_OP_end_group(br_op);
01363 }
01364 cur_state.Clear();
01365 temp_state.Clear();
01366 return;
01367 }
01368
01369 if (IPFEC_Enable_Compressed_Template){
01370 if (!prev_state.Empty()){
01371
01372 Negotiate_Bundle();
01373 prev_state.Do_Bundling();
01374 }
01375 prev_state = cur_state;
01376 }
01377 else{
01378 cur_state.Do_Bundling();
01379 }
01380
01381 cur_state.Set_M_Unit ();
01382
01383 cur_state.Clear();
01384 temp_state.Clear();
01385 }
01386
01388
01389
01390
01391
01392
01393 void CGGRP_Force_Bundle_End(void)
01394 {
01395 CGGRP_Cycle_Advance();
01396
01397 if (!LOCS_Enable_Bundle_Formation){
01398
01399 return;
01400 }
01401
01402 if (!IPFEC_Enable_Compressed_Template){
01403 return;
01404 }
01405
01406 prev_state.Polish_Tail();
01407 prev_state.Do_Bundling();
01408 prev_state.Clear();
01409 }
01410
01412
01413
01415
01416
01417
01418
01419
01420
01421
01422
01423
01424
01425
01426
01427
01428
01429
01430
01431
01432
01433
01434
01435
01436
01437
01438
01439 static void Negotiate_Bundle(void)
01440 {
01441
01442
01443 std::vector <BOOL> dep_chk_fail;
01444
01445 for (INT i=0; i< MAX_PTN_TABLE_LINE_SIZE; i++) {
01446 dep_chk_fail.push_back(false);
01447 }
01448
01449 Is_True(!prev_state.Empty() && !cur_state.Empty(),
01450 ("No Need to Call Negotiate Bundle!"));
01451
01452 const PTN_TABLE_LINE prev_cycle_ptns = prev_state.Patterns ();
01453 const PTN_TABLE_LINE cur_cycle_ptns = cur_state.Patterns();
01454 const PATTERN_TYPE s_ptn = prev_cycle_ptns[prev_state.Current_Pattern ()];
01455
01456 for (INT prev_ptn_idx = prev_state.Current_Pattern();
01457 prev_ptn_idx < prev_cycle_ptns.size ; prev_ptn_idx ++) {
01458
01459 const PATTERN_TYPE prev_ptn = prev_cycle_ptns[prev_ptn_idx];
01460 INT tail_template_in_prev_ptn;
01461 INT m;
01462
01463 for (m=ISA_MAX_ISSUE_BUNDLES-1; m>=0; m--){
01464 if (prev_ptn[m]!=ISA_MAX_BUNDLES)
01465 break;
01466 }
01467
01468 Is_True((prev_ptn[m]!=ISA_MAX_BUNDLES),
01469 ("Empty pattern in pattern table!"));
01470 tail_template_in_prev_ptn = prev_ptn[m];
01471
01472 if (prev_ptn.start_in_bundle && prev_ptn[0] != s_ptn[0]){
01473 continue;
01474 }
01475
01476
01477 if (s_ptn.start_in_bundle &&
01478 (!prev_ptn.start_in_bundle || prev_ptn[0] != s_ptn[0])) {
01479 continue;
01480 }
01481
01482 if (prev_state.Legality_Chk_Needed()){
01483 if (!prev_state.Legality_Chk(prev_ptn)){
01484 continue;
01485 }
01486 }
01487
01488 for (INT cur_ptn_idx = cur_state.Current_Pattern();
01489 cur_ptn_idx<cur_cycle_ptns.size; cur_ptn_idx++){
01490 const PATTERN_TYPE cur_ptn = cur_cycle_ptns[cur_ptn_idx];
01491
01492 if (!prev_ptn.end_in_bundle){
01493
01494
01495
01496 if (cur_ptn.start_in_bundle){
01497 continue;
01498 }
01499 }
01500 else{
01501
01502
01503
01504 if (!cur_ptn.start_in_bundle){
01505 continue;
01506 }
01507 if (cur_ptn[0] != tail_template_in_prev_ptn){
01508
01509 continue;
01510 }
01511 }
01512 if (cur_state.Legality_Chk_Needed()){
01513 if (dep_chk_fail[cur_ptn_idx]){
01514
01515 continue;
01516 }
01517 if (!cur_state.Legality_Chk(cur_ptn)){
01518 dep_chk_fail[cur_ptn_idx]=true;
01519 continue;
01520 }
01521 }
01522
01523 prev_state.Current_Pattern(prev_ptn_idx);
01524 cur_state.Current_Pattern(cur_ptn_idx);
01525 return;
01526
01527 }
01528 }
01529
01530 dep_chk_fail.clear();
01531 PATTERN_TYPE ptn_t_prev = prev_state.Current_Pattern_Type();
01532 PATTERN_TYPE ptn_t_cur = cur_state.Current_Pattern_Type();
01533
01534
01535
01536 if ( ptn_t_prev.end_in_bundle ) {
01537 prev_state.Set_Flags(CYCLE_FILL_NOP_A);
01538 }
01539 if ( ptn_t_cur.start_in_bundle ) {
01540 cur_state.Set_Flags(CYCLE_FILL_NOP_B);
01541 }
01542 DevWarn(("Two valid cycles with a failed group pattern negotiation!"));
01543 return;
01544 }
01546
01547
01548
01549
01551 void Calculate_BB_Cycle(BB *bb, BOOL dag_exist = TRUE)
01552 {
01553 if (!BB_length (bb)) { BB_cycle(bb) = 0; return;};
01554
01555 DAG_BUILDER dag (bb,NULL);
01556
01557 if (dag_exist == FALSE) {
01558 dag.Build_DAG ();
01559 }
01560
01561 mUINT16 * op_start_cycle =
01562 TYPE_ALLOCA_N (mUINT16,BB_next_op_map_idx (bb));
01563
01564 OP * op ;
01565 FOR_ALL_BB_OPs (bb, op) {
01566 op_start_cycle[OP_map_idx(op)] = 1 ;
01567 }
01568
01569
01570 INT32 grp_start_cycle = 1 ;
01571 OP * grp_first_op = BB_first_op(bb) ;
01572
01573 FOR_ALL_BB_OPs (bb, op) {
01574 if (!OP_noop(op)) {
01575
01576 for (ARC_LIST * arcs = OP_preds (op) ; arcs != NULL;
01577 arcs = ARC_LIST_rest(arcs)) {
01578
01579 ARC * arc = ARC_LIST_first(arcs);
01580 OP * pred = ARC_pred (arc);
01581
01582 INT32 expected_cycle =
01583 op_start_cycle[OP_map_idx(pred)] + ARC_latency(arc);
01584
01585 op_start_cycle[OP_map_idx(op)] =
01586 (op_start_cycle[OP_map_idx(op)] > expected_cycle) ?
01587 op_start_cycle[OP_map_idx(op)] :
01588 expected_cycle ;
01589
01590 }
01591
01592 grp_start_cycle = (grp_start_cycle > op_start_cycle[OP_map_idx(op)]) ?
01593 grp_start_cycle : op_start_cycle[OP_map_idx(op)] ;
01594 }
01595
01596 if (OP_end_group(op)) {
01597 for ( ; grp_first_op != op ; grp_first_op = OP_next(grp_first_op)) {
01598 op_start_cycle [OP_map_idx(grp_first_op)] = grp_start_cycle ;
01599 OP_scycle(grp_first_op) = grp_start_cycle - 1;
01600 }
01601
01602 op_start_cycle [OP_map_idx(op)] = grp_start_cycle ;
01603 OP_scycle(grp_first_op) = grp_start_cycle - 1;
01604
01605 grp_first_op = OP_next(op);
01606 grp_start_cycle ++ ;
01607 }
01608 }
01609
01610 if (dag_exist == FALSE) {
01611 Delete_Graph(bb);
01612 }
01613
01614 BB_cycle(bb) = grp_start_cycle - 1 ;
01615 }
01617
01618
01619
01621 static void CGGRP_Bundle_BB(BB *bb)
01622 {
01623 extern void Clean_Up(BB* bb);
01624
01625
01626 DAG_BUILDER bb_dag(bb);
01627 bb_dag.Build_DAG();
01628
01629 for (OP *op = BB_first_op(bb); op != NULL; ){
01630 if (CGGRP_Issue_OP(op, FALSE)){
01631 CGGRP_Issue_OP(op, TRUE);
01632 if (OP_end_group(op)) {
01633 op = OP_next(op);
01634 CGGRP_Cycle_Advance();
01635 } else {
01636 OP *prev_op = op;
01637 op = OP_next(op);
01638
01639
01640
01641
01642 if ( Debug_Level > 0 && op != NULL &&
01643 OP_srcpos(op) != OP_srcpos(prev_op) )
01644 CGGRP_Cycle_Advance();
01645 }
01646 }
01647 else{
01648 CGGRP_Cycle_Advance();
01649 }
01650 }
01651 CGGRP_End_BB();
01652 Delete_Graph(bb);
01653 Calculate_BB_Cycle(bb,FALSE);
01654 }
01655
01656 void CGGRP_Bundle(void)
01657 {
01658 Is_True(IPFEC_sched_care_machine!=Sched_care_bundle,
01659 ("Bundling Shouldn't called after integerated scheduling done!"));
01660 Set_Error_Phase ("Ipfec Bundling");
01661 Start_Timer(T_Ipfec_LOCS_CU);
01662
01663 INT32 save = IPFEC_sched_care_machine;
01664 IPFEC_sched_care_machine = Sched_care_bundle;
01665 prev_state.Clear();
01666 cur_state.Clear();
01667
01668 for (BB* bb = REGION_First_BB; bb != NULL; bb = BB_next(bb)) {
01669 if (BB_length(bb) == 0) continue;
01670 CGGRP_Bundle_BB(bb);
01671 Set_BB_scheduled(bb);
01672 }
01673
01674 IPFEC_sched_care_machine = save;
01675 Stop_Timer(T_Ipfec_LOCS_CU);
01676 }
01677
01678
01679 BOOL CGGRP_Check_Split_BB(BB* split_bb, BB** end_bbp)
01680 {
01681
01682 Is_True(BB_chk_split(split_bb), ("CGGRP_Check_Split_BB: split_bb must be a chk split BB!\n"));
01683
01684 if(BB_length(split_bb) == 0){
01685 *end_bbp = split_bb;
01686 return FALSE;
01687 }
01688
01689 BOOL no_touch = TRUE;
01690 BB* end_bb;
01691 BB* bb = split_bb;
01692
01693 while(BB_chk_split(bb)){
01694 if(!BB_scheduled(bb))
01695 no_touch = FALSE;
01696 BB* next_bb = BB_next(bb);
01697 if(!BB_chk_split(next_bb))
01698 break;
01699 OP* roof = BB_last_op(bb);
01700 OP* floor = BB_first_op(next_bb);
01701 if(roof && OP_end_group(roof) &&
01702 floor && OP_start_bundle(floor))
01703 break;
01704 bb = next_bb;
01705 }
01706
01707 *end_bbp = end_bb = bb;
01708 if(!no_touch){
01709 return FALSE;
01710 }
01711
01712 bb = split_bb;
01713 for (OP* op = BB_first_op(bb);;) {
01714 ISA_BUNDLE bundle;
01715 UINT64 slot_mask;
01716 UINT stop_mask;
01717 INT slot;
01718 INT ibundle;
01719
01720
01721
01722 stop_mask = 0;
01723 slot_mask = 0;
01724 for (slot = 0; op && slot < ISA_MAX_SLOTS; ) {
01725 INT words;
01726 INT w;
01727
01728 if(!OP_dummy(op)){
01729 if (OP_simulated(op))
01730 return FALSE;
01731 if(slot == 0){
01732 Set_OP_start_bundle(op);
01733 }else{
01734 Reset_OP_start_bundle(op);
01735 }
01736 words = Instruction_Length(op);
01737 for (w = 0; w < words; ++w) {
01738 if (slot >= ISA_MAX_SLOTS)
01739 return FALSE;
01740 slot++;
01741 slot_mask = slot_mask << ISA_TAG_SHIFT;
01742 if ( EXEC_PROPERTY_is_M_Unit(OP_code(op)) &&
01743 EXEC_PROPERTY_is_I_Unit(OP_code(op)) ){
01744 slot_mask |= OP_m_unit(op) ? ISA_EXEC_PROPERTY_M_Unit : ISA_EXEC_PROPERTY_I_Unit;
01745 } else {
01746 slot_mask |= ISA_EXEC_Unit_Prop(OP_code(op));
01747 }
01748 stop_mask = stop_mask << 1;
01749 }
01750 if (TSI_Issue_Ports(OP_code(op)).In(ip_B0) &&
01751 TSI_Issue_Ports(OP_code(op)).In(ip_B2)){
01752 slot_mask = slot_mask | ISA_EXEC_PROPERTY_B_Unit;
01753 }
01754 stop_mask |= (OP_end_group(op) != 0);
01755 }
01756 op = OP_next(op);
01757 if(op == NULL){
01758 bb = BB_next(bb);
01759 while(bb != BB_next(end_bb)){
01760 if(BB_length(bb) == 0){
01761 bb = BB_next(bb);
01762 continue;
01763 }
01764 op = BB_first_op(bb);
01765 break;
01766 }
01767 }
01768 }
01769
01770 if (slot == 0){
01771 return TRUE;
01772 }
01773
01774 if (slot != ISA_MAX_SLOTS)
01775 return FALSE;
01776
01777 for (ibundle = 0; ibundle < ISA_MAX_BUNDLES; ++ibundle) {
01778 UINT64 this_slot_mask = ISA_EXEC_Slot_Mask(ibundle);
01779 UINT32 this_stop_mask = ISA_EXEC_Stop_Mask(ibundle);
01780 if ((slot_mask & this_slot_mask) == this_slot_mask && (stop_mask & ~1) == this_stop_mask)
01781 break;
01782 }
01783 if (ibundle == ISA_MAX_BUNDLES)
01784 return FALSE;
01785 }
01786 Is_True(FALSE,("CGGRP_Check_Split_BB: Can not get to here!"));
01787
01788 }
01789
01790 inline BOOL bundle_ops_fail(void){
01791 prev_state.Clear();
01792 temp_state.Valid(FALSE);
01793 return FALSE;
01794 }
01796
01797
01798
01799
01800
01801
01802
01803 static PATTERN_TYPE
01804 Find_Pattern_OPS(OPS *ops, INT stop_idx=0)
01805 {
01806 OP *cur_op;
01807 INT idx=0;
01808 UINT64 slot_mask=0;
01809 UINT64 stop_mask=0;
01810 PATTERN_TYPE origin_ptn;
01811
01812
01813 for(INT bundle=0; bundle < ISA_MAX_ISSUE_BUNDLES; bundle++)
01814 {
01815 origin_ptn.bundle[bundle] = ISA_MAX_BUNDLES;
01816 origin_ptn.start_in_bundle = 0;
01817 origin_ptn.end_in_bundle = 0;
01818 }
01819
01820 FOR_ALL_OPS_OPs(ops, cur_op) {
01821 INT words = Instruction_Length(cur_op);
01822 for (INT w = 0; w < words; ++w) {
01823 idx++;
01824 slot_mask = slot_mask << ISA_TAG_SHIFT;
01825 if ( EXEC_PROPERTY_is_M_Unit(OP_code(cur_op)) &&
01826 EXEC_PROPERTY_is_I_Unit(OP_code(cur_op)) ){
01827
01828
01829 if (idx >= ISA_MAX_SLOTS) {
01830 slot_mask |= ((idx-1)%ISA_MAX_SLOTS==2) ? ISA_EXEC_PROPERTY_I_Unit : ISA_EXEC_PROPERTY_M_Unit;
01831 slot_mask |= ((idx-1)%ISA_MAX_SLOTS==0) ? ISA_EXEC_PROPERTY_M_Unit : ISA_EXEC_PROPERTY_I_Unit;
01832 }
01833 else
01834 slot_mask |= OP_m_unit(cur_op) ?
01835 ISA_EXEC_PROPERTY_M_Unit :
01836 ISA_EXEC_PROPERTY_I_Unit;
01837 } else { slot_mask |= ISA_EXEC_Unit_Prop(OP_code(cur_op)); }
01838 }
01839
01840
01841
01842 if (TSI_Issue_Ports(OP_code(cur_op)).In(ip_B0) &&
01843 TSI_Issue_Ports(OP_code(cur_op)).In(ip_B2)){
01844 slot_mask = slot_mask | ISA_EXEC_PROPERTY_B_Unit;
01845 }
01846
01847
01848 if (idx % ISA_MAX_SLOTS == 0 && idx != 0) {
01849 if (stop_idx == 0) stop_mask = 0;
01850 else if (idx>stop_idx && ((idx-stop_idx)<ISA_MAX_SLOTS)) {
01851 stop_mask = 1 << (ISA_MAX_SLOTS - stop_idx);
01852 }
01853 INT ibundle;
01854 for (ibundle = 0; ibundle < ISA_MAX_BUNDLES; ++ibundle) {
01855 UINT64 this_slot_mask = ISA_EXEC_Slot_Mask(ibundle);
01856 UINT32 this_stop_mask = ISA_EXEC_Stop_Mask(ibundle);
01857 if ( (slot_mask & this_slot_mask) == this_slot_mask
01858 && stop_mask == this_stop_mask) break;
01859 }
01860
01861 FmtAssert(ibundle != ISA_MAX_BUNDLES,
01862 ("couldn't find bundle for slot mask=0x%llx, stop mask=0x%x in OPS\n",
01863 slot_mask, stop_mask));
01864 origin_ptn.bundle[(idx/ISA_MAX_SLOTS)-1] = ibundle;
01865 if (stop_idx>0) origin_ptn.start_in_bundle = 1;
01866 slot_mask = 0;
01867 stop_mask = 0;
01868 }
01869 }
01870
01871 return origin_ptn;
01872 }
01874
01875
01876
01877
01878
01879
01880
01881
01882 BOOL
01883 Best_Issue_Port(OPS *ops, INT stop_idx, const PATTERN_TYPE ptn, ISSUE_PORT *ip_list)
01884 {
01885 INT idx = 0;
01886 OP *cur_op;
01887 const DISPERSAL_TARG *ports_vector = dispersal_table.Query(&ptn);
01888 std::vector<OP*> _op_orders;
01889 std::vector<OP*>::iterator iter;
01890 std::map<OP*, PORT_SET> _op_avail;
01891
01892 _op_orders.empty();
01893
01894 FOR_ALL_OPS_OPs(ops, cur_op) {
01895 if (Long_Instruction(cur_op)){
01896
01897
01898 return false;
01899 }
01900 ip_list[idx] = ip_invalid;
01901 if (idx >= stop_idx) {
01902 if (!OP_noop(cur_op)) {
01903 INT bundle = (idx)/ISA_MAX_SLOTS;
01904 INT slot = (idx) % ISA_MAX_SLOTS;
01905 PORT_SET ports = ports_vector->Ports(bundle,slot);
01906 PORT_SET avail_ports = TSI_Issue_Ports(OP_code(cur_op));
01907 ports = ports & avail_ports;
01908 _op_avail[cur_op] = ports;
01909
01910
01911 if (ports == 0) return false;
01912
01913 INT count = ports.Count();
01914 for (iter=_op_orders.begin(); iter!=_op_orders.end(); iter++)
01915 {
01916 OP* order = *iter;
01917 if (_op_avail[order].Count() > count)
01918 break;
01919 }
01920 _op_orders.insert(iter, cur_op);
01921 }
01922 }
01923 idx++;
01924 }
01925 PORT_SET used_ports(0);
01926 for (INT m=0; m<_op_orders.size(); m++)
01927 {
01928 OP *op = _op_orders[m];
01929 PORT_SET ports = _op_avail[op];
01930 ports = ports - used_ports;
01931 ISSUE_PORT issue_port = ports.First_IP();
01932 Is_True(issue_port!=ip_invalid,
01933 ("op %s can't find suitable issue port",
01934 TOP_Name(OP_code(op))));
01935
01936 used_ports = used_ports + issue_port;
01937 idx = 0;
01938 FOR_ALL_OPS_OPs(ops, cur_op) {
01939 if (cur_op == op)
01940 break;
01941 idx++;
01942 }
01943 Is_True(cur_op == op, ("Issue_OP can't find in list of ops"));
01944 ip_list[idx] = issue_port;
01945 }
01946
01947 return TRUE;
01948 }
01949
01950
01952
01953
01954
01955
01956
01957
01958
01959
01960
01961
01962
01963
01964 BOOL CGGRP_Bundle_OPS(OPS *ops,OPS *new_ops,INT stop_idx, BOOL cyclic)
01965 {
01966
01967 Is_True(OPS_length(ops) <= CYCLE_MAX_LENGTH,
01968 ("OPS must be put suitable bundle group."));
01969 Is_True(stop_idx < ISA_MAX_SLOTS,
01970 ("stop bit only can occur in first bundle."));
01971
01972 BOOL dump_details = FALSE;
01973
01974 if (Get_Trace(TP_A_MLBR, 0x01)) {
01975 dump_details = TRUE;
01976 }
01977
01978 temp_state.Clear();
01979 prev_state.Clear();
01980 if (!cyclic)
01981 temp_state.Set_Flags(CYCLE_STRICT_ORDER);
01982 else {
01983 temp_state.Cyclic(TRUE);
01984 prev_state.Cyclic(TRUE);
01985 }
01986
01987
01988 OP *cur_op;
01989 INT idx=0;
01990 INT keep_template;
01991 OP *insert_point=NULL;
01992 PATTERN_TYPE origin_ptn;
01993 PTN_TABLE_LINE ptns;
01994
01995 origin_ptn = Find_Pattern_OPS(ops, stop_idx);
01996
01997
01998 if (dump_details) {
01999 fprintf(TFile, "Find last cylce template group:\n");
02000 origin_ptn.Dump(TFile);
02001 }
02002 Is_True(origin_ptn[0]!=ISA_MAX_BUNDLES, ("ops can't bundle in one cycle!"));
02003
02004 ISSUE_PORT ip_list[CYCLE_MAX_LENGTH];
02005 if (!Best_Issue_Port(ops, stop_idx, origin_ptn, ip_list))
02006 return false;
02007
02008
02009 idx = 0;
02010 FOR_ALL_OPS_OPs(ops, cur_op) {
02011 if (idx < stop_idx) {
02012 if (idx == stop_idx-1) {
02013 prev_state.Add_OP(cur_op);
02014 insert_point=cur_op;
02015 }
02016 } else {
02017 if (!OP_noop(cur_op)) {
02018 Is_True(ip_list[idx]!=ip_invalid, ("op do not find the suitable issue port!"));
02019 OP_IDX op_idx=temp_state.Add_OP(cur_op,ip_list[idx]);
02020 Is_True(op_idx!=invalid_op_idx, ("Add_op failed. ops must be bundling well op list!"));
02021 }
02022 }
02023 idx++;
02024 }
02025
02026 if (temp_state.Full()) return bundle_ops_fail();
02027
02028 temp_state.Valid(TRUE);
02029
02030 if (stop_idx > 0) { keep_template = origin_ptn[0]; }
02031
02032 Is_True(temp_state.Valid(),("cannot find bundling for ops %d", OPS_length(ops)));
02033
02034
02035 OP *op;
02036 FOR_ALL_OPS_OPs(new_ops, op) {
02037 if (OP_dummy(op) || OP_simulated(op) || OP_noop(op)) continue;
02038 if (Long_Instruction(op)) return bundle_ops_fail();
02039
02040 temp_state.Current_Pattern(invalid_ptn_idx);
02041 if (temp_state.Full()) return bundle_ops_fail();
02042 OP_IDX new_op_idx = temp_state.Add_OP(op);
02043 if (new_op_idx == invalid_op_idx)
02044 return bundle_ops_fail();
02045 if (!Bundle_Helper(new_op_idx)) {
02046 return bundle_ops_fail();
02047 }
02048 }
02049
02050 ptns = temp_state.Patterns();
02051
02052
02053
02054
02055 temp_state.Valid(FALSE);
02056 for (INT ptn_idx=temp_state.Current_Pattern(); ptn_idx<ptns.size; ptn_idx++)
02057 {
02058 const PATTERN_TYPE ptn = ptns[ptn_idx];
02059 if (stop_idx == 0) {
02060 if (ptn.start_in_bundle || ptn.end_in_bundle) continue;
02061 } else {
02062 if (ptn[0] != keep_template ||
02063 ptn.start_in_bundle != 1) continue;
02064 }
02065 if (temp_state.Legality_Chk_Needed()){
02066 if (!temp_state.Legality_Chk(ptn)) continue;
02067 }
02068
02069
02070 temp_state.Current_Pattern(ptn_idx);
02071 temp_state.Valid(TRUE);
02072 break;
02073 }
02074
02075
02076 BOOL split_between_cycle = FALSE;
02077 if (!temp_state.Valid()) {
02078 if (stop_idx) {
02079 split_between_cycle = TRUE;
02080 prev_state.Clear();
02081
02082 for (INT ptn_idx=temp_state.Current_Pattern(); ptn_idx<ptns.size; ptn_idx++)
02083 {
02084 const PATTERN_TYPE ptn = ptns[ptn_idx];
02085 if (ptn.start_in_bundle || ptn.end_in_bundle) continue;
02086
02087 if (temp_state.Legality_Chk_Needed()){
02088 if (!temp_state.Legality_Chk(ptn)) continue;
02089 }
02090
02091 temp_state.Current_Pattern(ptn_idx);
02092 temp_state.Valid(TRUE);
02093 break;
02094 }
02095 }
02096 if (!temp_state.Valid()) return bundle_ops_fail();
02097 }
02098 temp_state.Polish_Tail();
02099
02100
02101
02102
02103 ptns = temp_state.Patterns();
02104 PATTERN_TYPE ptn = ptns[temp_state.Current_Pattern()];
02105 if (split_between_cycle) {
02106 if (dump_details) {
02107 fprintf(TFile, "split last cycle can get pattern\n");
02108 ptn.Dump(TFile);
02109 }
02110 }
02111
02112
02113 idx = 0;
02114 OP *remove_op=NULL;
02115 INT cur_cycle = 0;
02116 FOR_ALL_OPS_OPs(ops, cur_op) {
02117 idx++;
02118 if (remove_op) {OPS_Remove_Op(ops, remove_op);}
02119 if (idx <= stop_idx) continue;
02120
02121 if (OP_noop(cur_op)) {
02122 remove_op = cur_op;
02123 } else {
02124 remove_op = NULL;
02125 if (!cyclic) cur_cycle = OP_scycle(cur_op);
02126 }
02127 }
02128 if (remove_op) {OPS_Remove_Op(ops, remove_op);}
02129
02130 for(cur_op = OPS_first(new_ops); cur_op ;) {
02131 op = cur_op;
02132 cur_op = OP_next(cur_op);
02133 if (OP_dummy(op) || OP_simulated(op) || OP_noop(op)) continue;
02134 if (!cyclic) OP_scycle(op) = cur_cycle;
02135 OPS_Remove_Op(new_ops, op);
02136 OPS_Append_Op(ops, op);
02137 }
02138 OPS_Remove_All(new_ops);
02139
02140 Is_True(OPS_length(new_ops)==0, ("new ops should be empty!"));
02141
02142 INT issue_op_list[CYCLE_MAX_LENGTH];
02143 if (!temp_state.Best_Issue_Order(issue_op_list)) return false;
02144
02145 GROUP_ASSEMBLE group_assemble = temp_state.Assemble();
02146 if (split_between_cycle)
02147 {
02148 for (INT slot=0; slot < ISA_MAX_SLOTS; slot++) {
02149 if (slot<(stop_idx-1)) continue;
02150 if (slot == (stop_idx-1)) Reset_OP_end_group(insert_point);
02151 if (slot>(stop_idx-1)) {
02152 OP *new_op = group_assemble.MakeNop2Slot(keep_template, slot);
02153 OPS_Insert_Op_After(ops, insert_point, new_op);
02154 insert_point = new_op;
02155 }
02156 }
02157 Set_OP_end_group(insert_point);
02158 }
02159 for (INT bundle=0; bundle < ISA_MAX_ISSUE_BUNDLES; bundle++){
02160 INT template_index = ptn[bundle];
02161 BOOL meet_bundle_start=TRUE;
02162 if (template_index == ISA_MAX_BUNDLES){
02163 break;
02164 }
02165 if (ptn.start_in_bundle && bundle==0)
02166 meet_bundle_start = FALSE;
02167
02168 for (INT slot=0; slot < ISA_MAX_SLOTS; slot++) {
02169 if (ptn.start_in_bundle &&
02170 ISA_EXEC_Stop(template_index,slot)) {
02171 meet_bundle_start=TRUE;
02172 continue;
02173 }
02174 if (!meet_bundle_start) continue;
02175 OP_IDX op_idx = issue_op_list[bundle * ISA_MAX_SLOTS + slot];
02176
02177
02178 if (op_idx==invalid_op_idx) {
02179 OP *new_op = group_assemble.MakeNop2Slot(template_index, slot);
02180
02181 if (insert_point != NULL) {
02182 OPS_Insert_Op_After(ops, insert_point,new_op);
02183 }else {
02184 OPS_Prepend_Op(ops, new_op);
02185 }
02186 insert_point = new_op;
02187 } else {
02188
02189 OPS_Remove_Op(ops, temp_state[op_idx]);
02190 if (insert_point != NULL) {
02191 OPS_Insert_Op_After(ops, insert_point,temp_state[op_idx]);
02192 }else {
02193 OPS_Prepend_Op(ops, temp_state[op_idx]);
02194 }
02195 insert_point = temp_state[op_idx];
02196 }
02197 if (!cyclic) group_assemble.Bundle_OP_End(insert_point,template_index, slot);
02198 }
02199 }
02200 if (!cyclic) group_assemble.Group_End(insert_point);
02201 else temp_state.Set_M_Unit();
02202
02203 if (dump_details) {
02204 fprintf(TFile, "\n-----------------------------\n");
02205 fprintf(TFile, "\nWe can get new bundle group: \n");
02206 ptn = temp_state.Current_Pattern_Type();
02207 ptn.Dump(TFile);
02208 fprintf(TFile, "\n-----------------------------\n");
02209 }
02210
02211 temp_state.Clear();
02212 prev_state.Clear();
02213 return TRUE;
02214 }
02215
02216 void
02217 PTN_TABLE_LINE::Dump (FILE *f) {
02218 for (INT i = 0; i < size; i++) {
02219 fprintf(f,"%d ",i);
02220 ptns[i].Dump(f);
02221 }
02222 }
02223
02224
02225
02226 BOOL CGGRP_Bundle_OPS(OPS *ops,OP *op,INT stop_idx, BOOL cyclic)
02227 {
02228 OPS new_ops;
02229 OPS_Init(&new_ops);
02230
02231 OPS_Append_Op(&new_ops, op);
02232
02233 if (CGGRP_Bundle_OPS(ops, &new_ops, stop_idx, cyclic)) {
02234 return TRUE;
02235 } else {
02236 Is_True(OPS_length(&new_ops) == 1, ("new ops length is not correct!"));
02237 OPS_Remove_Op(&new_ops, op);
02238 return FALSE;
02239 }
02240
02241 }
02242 void CYCLE_STATE::Dump (FILE *f)
02243 {
02244 extern void dump_op(const OP *op);
02245 fprintf(f, "\nValid:%d ",_valid);
02246 fprintf(f, "dependence:%d ",_dependency_exist);
02247 fprintf(f, "Occupied:");
02248
02249 for (INT port=0; port<ip_number; port++){
02250 if (_reserve.In((ISSUE_PORT)port)){
02251 fprintf(f, " %s", Issue_Port_Name((ISSUE_PORT)port));
02252 }
02253 }
02254 fprintf(f, "\n");
02255
02256 for (OP_IDX i=0; i<_num_ops; i++){
02257 fprintf(f, "%s: ",Issue_Port_Name(_const_OP_State(i).op_fu));
02258 dump_op(_const_OP_State(i).op);
02259 }
02260 fprintf(f,"\n");
02261 if (_reserve != 0) {
02262 const PTN_TABLE_LINE& ptns = Patterns ();
02263 for (INT ptn_idx = 0; ptn_idx < ptns.size; ptn_idx++) {
02264
02265 mINT16 bundle;
02266 PATTERN_TYPE ptn = ptns[ptn_idx];
02267
02268
02269 if (ptn_idx == _ptn) {
02270 fprintf (f, "[=>] ");
02271 } else {
02272 fprintf (f, "[%2d] ", ptn_idx);
02273 }
02274
02275 fprintf(f, "{ %d, %d, {", ptn.start_in_bundle, ptn.end_in_bundle);
02276 for (bundle=0; bundle<ISA_MAX_ISSUE_BUNDLES; bundle++){
02277 if (bundle!=0)
02278 fprintf(f, ",");
02279 fprintf(f, " %d", ptn[bundle]);
02280 }
02281 fprintf(f, "} }");
02282
02283
02284 fprintf(f, "\t/*");
02285 if (ptn.start_in_bundle)
02286 fprintf(f, "->");
02287 for (bundle=0; bundle<ISA_MAX_ISSUE_BUNDLES; bundle++){
02288 fprintf(f, "%s ",ISA_EXEC_Name(ptn[bundle]));
02289 }
02290 fprintf(f," */\n");
02291 }
02292 }
02293 }
02294
02295 #ifdef Is_True_On
02296
02297 void CYCLE_STATE::gdb_dump(void) {
02298 Dump (stderr) ; fflush (stderr);
02299 }
02300
02301 void PTN_TABLE_LINE::gdb_dump (void) {
02302 Dump (stderr); fflush (stderr);
02303 }
02304
02305 #endif