GCC's bacl-end & assemble emission (21)

来源:互联网 发布:如何查看淘宝排名 编辑:程序博客网 时间:2024/04/30 14:42

9.4.Construct old style pipeline hazards recognizer

Now data needed has been read from machine description file, andcorresponding rtx objects have been created. However, rtx object is still toocoarse for generating pipeline hazards recognizer. Further structured data willbe generated from rtx objects created in above sections.

 

main (continued)

 

6111   if (have_error)

6112     returnFATAL_EXIT_CODE;

6113

6114   insn_code_number++;

6115

6116   /* If we didn'thave a DEFINE_ASM_ATTRIBUTES, make a null one. */

6117   if (! got_define_asm_attributes)

6118   {

6119     tem = rtx_alloc (DEFINE_ASM_ATTRIBUTES);

6120     XVEC (tem, 0) = rtvec_alloc (0);

6121     gen_insn (tem, 0);

6122   }

6123

6124  /* ExpandDEFINE_DELAY information into new attribute. */

6125   if (num_delays)

6126     expand_delays ();

9.4.1. Handling DEFINE_DELAY pattern

In above preparation section, define_delay is linked in list of delay_desc referred by delays. Though function units tellhow they are used by instructions via define_function_unit pattern, orinstructions tell how they use function units via define_insn_reservationpattern, and these patterns form the core of the pipeline hazards recognizer,they tell little about instructions themselves. Other patterns, i.e.,define_insn, define_delay, define_attr etc give the detail of instruction ininterested. Then the detail will be turned into attributes for instruction. Itis what the data we want.

expand_delays produces attributes for define_delay. Notice that define_delaydefinition also may used in the new way chip description, this section is alsoapplied to 9.5 Construct DFA-based pipelinehazards recognizer.

 

1526 static void

1527 expand_delays (void)                                                                          ingenautomata.c

1528 {

1529   struct delay_desc*delay;

1530   rtx condexp;

1531   rtx newexp;

1532   int i;

1533   char *p;

1534

1535   /* First, generatedata for `num_delay_slots' function.  */

1536

1537   condexp = rtx_alloc (COND);

1538   XVEC (condexp, 0) = rtvec_alloc (num_delays* 2);

1539   XEXP (condexp, 1) = make_numeric_value (0);

1540

1541   for (i = 0,delay = delays;delay; i += 2, delay = delay->next)

1542   {

1543     XVECEXP (condexp, 0, i) = XEXP(delay->def, 0);

1544     XVECEXP (condexp, 0, i + 1)

1545         = make_numeric_value (XVECLEN (delay->def, 1) / 3);

1546   }

1547

1548   make_internal_attr (num_delay_slots_str,condexp, ATTR_NONE);

1549

1550  /* If more than onedelay type, do the same for computing the delay type.  */

1551   if (num_delays > 1)

1552   {

1553     condexp = rtx_alloc (COND);

1554     XVEC (condexp, 0) = rtvec_alloc (num_delays* 2);

1555     XEXP (condexp, 1) = make_numeric_value (0);

1556

1557     for (i = 0,delay = delays;delay; i += 2, delay = delay->next)

1558     {

1559       XVECEXP (condexp, 0, i) = XEXP(delay->def, 0);

1560       XVECEXP (condexp, 0, i + 1) = make_numeric_value (delay->num);

1561          }

1562

1563     make_internal_attr (delay_type_str,condexp, ATTR_SPECIAL);

1564   }

 

num_delay_slots_str and delay_type_strare created and saved into hash table at program entry. For num_delay_slots_str,its content is "*num_delay_slots", and for delay_type_str, its content is "*delay_type".

condexp created at line 1537 records the testing part and the number of delayslots for every define_attr patterns, which is the content of attribute of "*num_delay_slots".

condexp created at line 1553 records the condition part with the delay No.for every define_attr patterns, which is the content of attribute of "*delay_type".

Above make_numeric_valueis used to create corresponding rtx object of numeric value.

 

5911 rtx

5912 make_numeric_value (int n)                                                                       ingenautomata.c

5913 {

5914   static rtxint_values[20];

5915   rtx exp;

5916   char *p;

5917

5918   if (n < 0)

5919     abort ();

5920

5921   if (n < 20 && int_values[n])

5922     returnint_values[n];

5923

5924   p = attr_printf (MAX_DIGITS, "%d",n);

5925   exp = attr_rtx (CONST_STRING, p);

5926

5927   if (n < 20)

5928     int_values[n] = exp;

5929

5930   return exp;

5931 }

 

Then function make_internal_attr fills out attr_desc.Notice that in writing attribute of "*delay_type", ATTR_SPECIAL ispassed to make_internal_attr,which later in generating output file will skip the invocation of write_attr_set.

 

5848 void

5849 make_internal_attr (const char *name, rtx value, int special)                   in genattrtab.c

5850 {

5851   struct attr_desc*attr;

5852

5853   attr = find_attr (&name, 1);

5854   if (attr->default_val)

5855     abort ();

5856

5857   attr->is_numeric = 1;

5858   attr->is_const = 0;

5859   attr->is_special = (special &ATTR_SPECIAL) != 0;

5860   attr->negative_ok = (special &ATTR_NEGATIVE_OK) != 0;

5861   attr->unsigned_p = (special &ATTR_UNSIGNED) != 0;

5862   attr->func_units_p = (special &ATTR_FUNC_UNITS) != 0;

5863   attr->blockage_p = (special &ATTR_BLOCKAGE) != 0;

5864   attr->static_p = (special &ATTR_STATIC) != 0;

5865   attr->default_val = get_attr_value (value, attr, -2);

5866 }

 

expand_delays then createsattributes for every define_delay definition. Notice that flag ATTR_SPECIALpassed for all these attributes too.

 

expand_delays (continued)

 

1526  /* For each delaypossibility and delay slot, compute an eligibility

1527     attribute for non-annulled insns and foreach type of annulled (annul

1528     if true and annul if false).  */

1529   for (delay = delays;delay; delay = delay->next)

1530   {

1531     for (i = 0;i < XVECLEN (delay->def, 1); i += 3)

1532     {

1533       condexp = XVECEXP (delay->def, 1, i);

1534       if (condexp== 0)

1535         condexp = false_rtx;

1536       newexp = attr_rtx(IF_THEN_ELSE, condexp,

1537                       make_numeric_value (1), make_numeric_value (0));

1538

1539       p =attr_printf (sizeof "*delay__" +MAX_DIGITS * 2,

1540                   "*delay_%d_%d", delay->num, i /3);

1541       make_internal_attr (p, newexp, ATTR_SPECIAL);

1542

1543       if(have_annul_true)

1544       {

1545         condexp = XVECEXP (delay->def, 1, i +1);

1546         if (condexp == 0) condexp = false_rtx;

1547         newexp = attr_rtx(IF_THEN_ELSE, condexp,

1548                           make_numeric_value (1),

1549                           make_numeric_value (0));

1550         p= attr_printf (sizeof "*annul_true__"+ MAX_DIGITS * 2,

1551                     "*annul_true_%d_%d",delay->num, i / 3);

1552         make_internal_attr (p, newexp, ATTR_SPECIAL);

1553       }

1554

1555       if(have_annul_false)

1556       {

1557         condexp = XVECEXP (delay->def, 1, i +2);

1558        if(condexp == 0) condexp = false_rtx;

1559         newexp = attr_rtx(IF_THEN_ELSE, condexp,

1560                           make_numeric_value (1),

1561                           make_numeric_value (0));

1562         p= attr_printf (sizeof"*annul_false__" + MAX_DIGITS * 2,

1563                     "*annul_false_%d_%d",delay->num, i / 3);

1564         make_internal_attr (p, newexp, ATTR_SPECIAL);

1565       }

1566     }

1567   }

1568 }

 

Above, have_annul_true is 1 when some instructions can be annulled ifbranch is true; similiar have_annul_false is 1 when some instructions canbe annulled if branch is false. They also should be saved as attributes too.

 

原创粉丝点击