For i386 architecture, no define_delay is used. However, it is worthto have a look how this pattern works.
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 }
In expand_delays, system will create attribute “*delay_type” in following shape:
*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”)
)
Then are series of attribute “*delay_`NO`_`slot-NO`” whichcontains following data. These attribute indicate the testings that must besatisified for instruction being placed into the slot.
*delay_`NO`_`slot-NO` (
cond [ (DELAY-`slot-NO`“1”) ] ;; attribute test for delay slot
“0”)
)
Following are series of attribute “*annul_true_`NO`_`slot-NO`” whichcontains following data. These attributes indicate the testing that must besatisified for instruction being annulled if the branch is true.
*annul_true_`NO`_`slot-NO` (
cond [ (ANNUL-TRUE-`slot-NO` “1”) ] ;;attribute test for insn annul
“0”)
)
Next are series of attribute “*annul_false_`NO`_`slot-NO`” whichcontains following data. These attributes indicate the testing that must besatisified for instruction being annulled if the branch is false.
*annul_false_`NO`_`slot-NO` (
cond [ (ANNUL-FALSE-`slot-NO` “1”) ] ;;attribute test for insn annul
“0”)
)
Notice that though expand_delay usesif_then_else for the rear 3 attribute series, make_internal_attr it uses tocreate these attributes will transform if_then_else into cond by make_canonical. Here write_eligible_delay will outputfunctions for these attributes.
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 }
We take eligible_for_delay for example see what weget. eligible_for_delayis produced for attributes of “*delay_type”, and “*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 in define_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 forslot of most used of define_delay of 0 after simplified
return1 ;
else
return0 ;
}
case 0 *`max_slot` + 1 :
… // other slots
default :
abort() ;
}
}
eligible_for_delay given instruction delay_insn, checks if instruction candidate_insn canbe placed into slot.See the usage of `delay-NO` * `max_slot` + `slot-NO`, and how it extracts datafrom attributes related.