GCC后端及汇编发布(21)

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

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

 

main (continued)

 

6111   if (have_error )

6112     return FATAL_EXIT_CODE;

6113

6114   insn_code_number ++;

6115

6116   /* If we didn't have 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   /* Expand DEFINE_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_insn define_delay define_attr 等,给出了所感兴趣的指令的细节。然后这些细节将被转换成指令的属性。这是我们需要的数据。

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

 

1526 static void

1527 expand_delays (void)                                                                          in genautomata.c

1528 {

1529   struct delay_desc *delay;

1530   rtx condexp;

1531   rtx newexp;

1532   int i;

1533   char *p;

1534

1535   /* First, generate data 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 one delay 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 delay_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)                                                                       in genautomata.c

5913 {

5914   static rtx int_values[20];

5915   rtx exp;

5916   char *p;

5917

5918   if (n < 0)

5919     abort ();

5920

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

5922     return int_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 delay possibility and delay slot, compute an eligibility

1527     attribute for non-annulled insns and for each 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_true 1 ,如果当跳转为真时,某些指令可以被取消;类似的, have_annul_false 1 ,如果当跳转为假时,某些指令可以被取消。显然,它们也需要被保存作属性。

 

你可能感兴趣的:(struct,汇编,function,gcc,attributes,delay)