GCC后端及汇编发布(33)

9.6.2. 输出delay的数据

对于i386架构,没有使用define_delay。不过,还是值得看一下这个模式如何工作。

 

main (continued)

 

6212   /* Write out delay eligibility information,if DEFINE_DELAY present.

6213     (The function to compute the number ofdelay slots will be written

6214     below.) */

6215   if (num_delays)

6216   {

6217     write_eligible_delay("delay");

6218     if (have_annul_true)

6219       write_eligible_delay("annul_true");

6220     if (have_annul_false)

6221       write_eligible_delay("annul_false");

6222   }

 

expand_delays中,系统将创建以下形式的属性“*delay_type”:

*delay_type(

  cond ([

    (condexp-1)            ;; test part of first define_delay

    (const_string “1”)    ;;NO. of the define_delay

        (condexp-2)           ;; test part of second define_delay

       (const_string “2”)   ;; NO. of the define_delay

        …                         ;; other define_delay

]

const_string “0”)

)

然后是一系列包含以下数据的属性“*delay_`NO`_`slot-NO`”。指向属性显示要放入该槽的指令所必须满足的测试。

*delay_`NO`_`slot-NO` (

cond [ (DELAY-`slot-NO`“1”) ]   ;; attribute test for delay slot

     “0”)

)

接着是一系列包含以下数据的属性“*annul_true_`NO`_`slot-NO`”这些属性显示,如果该跳转为真时要取消的指令,必须满足的测试。

*annul_true_`NO`_`slot-NO` (

        cond [ (ANNUL-TRUE-`slot-NO` “1”) ]      ;;attribute test for insn annul

“0”)

)

跟着是一系列包含以下数据的属性“*annul_false_`NO`_`slot-NO`”。这些属性显示如果该跳转为假时要取消的指令,必须满足的测试。

*annul_false_`NO`_`slot-NO` (

        cond [ (ANNUL-FALSE-`slot-NO` “1”) ]    ;;attribute test for insn annul

 “0”)

)

注意虽然expand_delay为后三个系列属性使用if_then_else,它用来构建这些属性的make_internal_attr将通过make_canonical把if_then_else转换为cond。在这里的write_eligible_delay将为这些属性输出函数。

 

5497 static void

5498 write_eligible_delay (const char *kind)                                                in genattrtab.c

5499 {

5500   struct delay_desc*delay;

5501   int max_slots;

5502   char str[50];

5503   const char*pstr;

5504   struct attr_desc*attr;

5505   struct attr_value*av, *common_av;

5506   int i;

5507

5508   /* Compute themaximum number of delay slots required. We use the delay

5509     ordinal times this number plus one, plusthe slot number as an index into

5510     the appropriate predicate to test.  */

5511

5512   for (delay = delays,max_slots = 0; delay; delay = delay->next)

5513     if (XVECLEN (delay->def, 1) / 3 >max_slots)

5514       max_slots = XVECLEN (delay->def, 1) /3;

5515

5516   /* Write functionprelude.  */

5517

5518   printf ("int\n");

5519   printf ("eligible_for_%s (rtx delay_insnATTRIBUTE_UNUSED, int slot, rtx

5520             candidate_insn, int flags ATTRIBUTE_UNUSED)\n", kind);

5521   printf ("{\n");

5522   printf ("  rtx insn;\n");

5523   printf ("\n");

5524   printf ("  if (slot >= %d)\n", max_slots);

5525   printf ("    abort ();\n");

5526   printf ("\n");

5527

5528   /* If more than onedelay type, find out which type the delay insn is.  */

5529

5530   if (num_delays > 1)

5531   {

5532     attr = find_attr(&delay_type_str,0);

5533     if (! attr)

5534       abort ();

5535     common_av = find_most_used (attr);

5536

5537     printf ("  insn = delay_insn;\n");

5538     printf ("  switch (recog_memoized (insn))\n");

5539     printf ("    {\n");

5540

5541     sprintf (str, " * %d;\n      break;", max_slots);

5542     for (av =attr->first_value; av; av = av->next)

5543       if (av != common_av)

5544         write_attr_case (attr, av, 1, "slot +=", str, 4, true_rtx);

5545

5546     write_attr_case (attr, common_av, 0, "slot +=", str, 4, true_rtx);

5547     printf ("    }\n\n");

5548

5549     /* Ensurematched. Otherwise, shouldn't have been called. */

5550     printf ("  if (slot < %d)\n", max_slots);

5551     printf ("    abort ();\n\n");

5552   }

5553

5554   /* If just one typeof delay slot, write simple switch.  */

5555   if (num_delays == 1 && max_slots == 1)

5556   {

5557     printf ("  insn = candidate_insn;\n");

5558     printf ("  switch (recog_memoized (insn))\n");

5559     printf ("    {\n");

5560

5561     attr = find_attr(&delay_1_0_str,0);

5562     if (! attr)

5563       abort ();

5564     common_av = find_most_used (attr);

5565

5566     for (av =attr->first_value; av; av = av->next)

5567       if (av != common_av)

5568         write_attr_case (attr, av, 1, "return", ";", 4, true_rtx);

5569

5570     write_attr_case (attr, common_av, 0, "return", ";", 4, true_rtx);

5571     printf ("    }\n");

5572   }

5573

5574   else

5575   {

5576     /* Write a nestedCASE. The first indicates which condition we need to

5577       test, and the inner CASE tests thecondition.  */

5578     printf ("  insn = candidate_insn;\n");

5579     printf ("  switch (slot)\n");

5580     printf ("    {\n");

5581

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

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

5584       {

5585         printf ("    case %d:\n",

5586               (i / 3) + (num_delays == 1 ? 0 : delay->num* max_slots));

5587         printf ("      switch (recog_memoized (insn))\n");

5588         printf ("\t{\n");

5589

5590         sprintf (str, "*%s_%d_%d",kind, delay->num, i / 3);

5591         pstr = str;

5592         attr = find_attr(&pstr, 0);

5593         if (! attr)

5594           abort ();

5595         common_av = find_most_used (attr);

5596

5597         for (av= attr->first_value; av; av = av->next)

5598           if (av != common_av)

5599             write_attr_case (attr, av, 1, "return", ";", 8, true_rtx);

5600

5601         write_attr_case (attr, common_av, 0, "return", ";", 8, true_rtx);

5602         printf ("      }\n");

5603       }

5604

5605       printf ("    default:\n");

5606       printf ("      abort ();\n");

5607       printf ("    }\n");

5608   }

5609

5610   printf ("}\n\n");

5611 }

 

我们以eligible_for_delay为例,看一下我们会得到什么。eligible_for_delay为属性“*delay_type”及“*delay_`NO`_`slot-NO`”所产生。

 

int

eligible_for_delay(rtx delay_insn ATTRIBUTE_UNUSED, int slot, rtx

     candidate_insn, int flags ATTRIBUTE_UNUSED)

{

  rtx insn;

 

  if (slot >= `max_slot`)        // max_slot records the biggest slot number indefine_delays.

abort();

      

         insn = delay_insn;

         switch (recog_memoized (insn))

         {

           case `insn-code-m` :      // insn of code m matching define_delay of n

              case …                         // other matching insns

extract_constrain_insn_cached (insn);      // used according to attr char.

                extract_insn_cached(insn);                     // used according to attr char.

                if (`condexp-n-s`)       // test partof define_delay of n after simplified

                {

               slot += n * `max_slot ;

                  break ;

                }

               else

                {

                     slot+= 0 * `max_slot` ; // should not happen

                     break ;

                }

              …                                // other insns

              default:

extract_constrain_insn_cached (insn);      // used according to attr char.

                extract_insn_cached(insn);                     // used according to attr char.

                if (`condexp-d-s`)       // test partof most common used delay after simplified

                {

                  slot += d * `max_slot ;  // d is num of most common used delay

                  break ;

}

else

{

  slot += 0 ;            // slot +=0 * `max_slot`, should not happen

  break ;

}

         }

 

         if (slot < `max_slot`)

           abort() ;

 

         insn = candidate_insn;

         switch (slot)

         {

              case0 * `max_slot` + 0:      

             switch (recog_memoized (insn))

                {

                     case`insn-code-p` :              // insn of code p matching define_delay of 0

                     case… :                       // other matching insns

                       extract_constrain_insn_cached(insn);      // usedaccording to attr char.

                       extract_insn_cached(insn);                     // used according to attr char.

                       if (`delay-0-0-s`)        // attr testfor 0 slot of define_delay of 0 after simplified

                         return 1 ;

                       else

                            return0 ;

                       break ;

                     …                                // other insns

                     default :

extract_constrain_insn_cached (insn);      // used according to attr char.

                       extract_insn_cached(insn);                     // used according to attr char.

                       if (`delay-0-d-s`) // attr test for slotof most used of define_delay of 0 after simplified

                            return1 ;

                       else

                            return0 ;

                }

              case 0 *`max_slot` + 1 :

                …                                    // other slots

              default :

                abort() ;

         }

}

 

eligible_for_delay给定指令delay_insn,检查指令candidate_insn是否可以被放入槽slot。注意`delay-NO` * `max_slot` + `slot-NO`的使用,及如何从相关属性获取数据。


  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值