GCC后端及汇编发布(21)

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

9.4.构建旧式的流水线危险识别器

现在所需要的数据已经从机器描述文件中读入,并且相应的rtx对象也已经被构建。不过,对于生成流水线危险识别器来说,rtx对象还是太粗糙了。更结构化的数据将被从上面节中构建的rtx对象中产生出来。

 

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. 处理DEFINE_DELAY模式

在上面进行准备工作的节中,define_delay被链接入由delays指向的delay_desc。虽然功能单元通过define_function_unit模式显示了它们如何被指令所使用,或者指令通过define_insn_reservation模式显示它们如何使用功能单元,这些模式构成了流水线危险识别器的核心,它们对指令只有很有限的描述。其它模式,即define_insndefine_delaydefine_attr等,给出了所感兴趣的指令的细节。然后这些细节将被转换成指令的属性。这是我们需要的数据。

expand_delaysdefine_delay生成属性。注意到define_delay定义同样也为新的芯片模式方式所采用,本节也同样应用于构建基于DFA的流水线危险识别器一节。

 

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_strdelay_type_str都在程序入口处被构建、保存入哈希表。至于num_delay_slots_str,其内容是“*num_delay_slots”,而对于delay_type_str,其内容是“*delay_type”。

1537行构建的condexp记录了每个define_attr模式的测试部分及延迟槽的数目,这是属性“*num_delay_slots”的内容。

1553行构建的condexp记录了每个define_attr模式带有延迟号码的条件部分,这是属性“*delay_type”的内容。

在上面make_numeric_value被用来构建对应数值的rtx对象。

 

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 }

 

然后由函数make_internal_attr填充attr_desc。注意在写属性“*delay_type”时,ATTR_SPECIAL被传递给make_internal_attr,这个函数随后在产生输出文件时将跳过对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为每个define_delay定义构建属性。注意标记ATTR_SPECIAL也被传递给这些属性。

 

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 }

 

上面,have_annul_true1,如果当跳转为真时,某些指令可以被取消;类似的,have_annul_false1,如果当跳转为假时,某些指令可以被取消。显然,它们也需要被保存作属性。

 

原创粉丝点击