9.3.7. Read in DEFINE_BYPASS pattern
Section 8.1.3 Overview of DEFINE_INSN_RESERVATION pattern describes the detail of define_bypass pattern. For this pattern we use following example:
188 (define_bypass 0 "pent_push,pent_pop" "pent_push,pent_pop,pent_call") in pentium.md
figure 44 : example of DEFINE_BYPASS pattern
[This pattern is part of pipe hazards description for construting DFA-based recognizer, this pattern shouldn’t coexist with define_function_unit in same machine description file]
After treated by init_md_reader_args , above pattern will be loaded into memory as rtx object as above. The handling of define_bypass here is quite similar with define_cup_unit. And the created decl also linked into list referred by decls .
1713 void
1714 gen_bypass (rtx def) in genattrtab.c
1715 {
1716 decl_t decl;
1717 char **out_insns;
1718 int out_length;
1719 char **in_insns;
1720 int in_length;
1721 int i, j;
1722
1723 out_insns = get_str_vect ((char *) XSTR (def, 1), &out_length, ',', FALSE);
1724 if (out_insns == NULL)
1725 fatal ("invalid string `%s' in define_bypass", XSTR (def, 1));
1726 i n_insns = get_str_vect ((char *) XSTR (def, 2), &in_length, ',', FALSE);
1727 if (in_insns == NULL)
1728 fatal ("invalid string `%s' in define_bypass", XSTR (def, 2));
1729 for (i = 0; i < out_length; i++)
1730 for (j = 0; j < in_length; j++)
1731 {
1732 decl = create_node (sizeof (struct decl));
1733 decl->mode = dm_bypass;
1734 decl->pos = 0;
1735 DECL_BYPASS (decl)->latency = XINT (def, 0);
1736 DECL_BYPASS (decl)->out_insn_name = out_insns [i];
1737 DECL_BYPASS (decl)->in_insn_name = in_insns [j];
1738 DECL_BYPASS (decl)->bypass_guard_name = (char *) XSTR (def, 3);
1739 VLA_PTR_ADD (decls , decl);
1740 num_dfa_decls ++;
1741 }
1742 }
Above, DECL_BYPASS accesses bypass field of decl, which has definition as following:
788 struct bypass_decl in genautomata.c
789 {
790 int latency;
791 char *out_insn_name;
792 char *in_insn_name;
793 char *bypass_guard_name;
794
795 /* The following fields are defined by checker. */
796
797 /* output and input insns of given bypass. */
798 struct insn_reserv_decl *out_insn_reserv;
799 struct insn_reserv_decl *in_insn_reserv;
800 /* The next bypass for given output insn. */
801 struct bypass_decl *next;
802 };
9.3.8. Read in EXCLUSION_SET pattern
Section 8.1.3 Overview of DEFINE_INSN_RESERVATION pattern describes the detail of EXCLUSION_SET pattern. For this pattern we use following example:
211 (exclusion_set "1_0m.ii" in itanium.md
212 "1_0m.mi, 1_0m.fi, 1_0m.mf, 1_0b.bb, 1_0m.bb, 1_0m.ib, 1_0m.mb, 1_0m.fb,/
213 1_0m.lx")
This pattern is part of pipe hazards description for construting DFA-based recognizer, this pattern shouldn’t coexist with define_function_unit in same machined description file.
After treated by init_md_reader_args , above pattern will be loaded into memory as rtx object as following. The handling of exclusion_set here is also similar with define_cup_unit. And the created decl also linked into list pointed by decls .
figure 45 : example of EXCLUSION_SET pattern
1749 void
1750 gen_excl_set (rtx def) in genattrtab.c
1751 {
1752 decl_t decl;
1753 char **first_str_cpu_units;
1754 char **second_str_cpu_units;
1755 int first_vect_length;
1756 int length;
1757 int i;
1758
1759 first_str_cpu_units
1760 = get_str_vect ((char *) XSTR (def, 0), &first_vect_length, ',', FALSE);
1761 if (first_str_cpu_units == NULL)
1762 fatal ("invalid first string `%s' in exclusion_set", XSTR (def, 0));
1763 second_str_cpu_units = get_str_vect ((char *) XSTR (def, 1), &length, ',',
1764 FALSE);
1765 if (second_str_cpu_units == NULL)
1766 fatal ("invalid second string `%s' in exclusion_set", XSTR (def, 1));
1767 length += first_vect_length;
1768 decl = create_node (sizeof (struct decl) + (length - 1) * sizeof (char *));
1769 decl->mode = dm_excl;
1770 decl->pos = 0;
1771 DECL_EXCL (decl)->all_names_num = length;
1772 DECL_EXCL (decl)->first_list_length = first_vect_length;
1773 for (i = 0; i < length; i++)
1774 if (i < first_vect_length)
1775 DECL_EXCL (decl)->names [i] = first_str_cpu_units [i];
1776 else
1777 DECL_EXCL (decl)->names [i]
1778 = second_str_cpu_units [i - first_vect_length];
1779 VLA_PTR_ADD (decls , decl);
1780 num_dfa_decls ++;
1781 }
DECL_EXCL accesses the excl_rel_decl field of decl. excl_rel_decl has following definition, see that names field is variable array indeed with element per unit name.
826 struct excl_rel_decl in genautomata.c
827 {
828 int all_names_num;
829 int first_list_length;
830 char *names [1];
831 };
As we see before, pattern PRESENCE_SET, FINAL_PRESENCE_SET, ABSENCE_SET, and FINAL_ABSENCE_SET use similar format, so their handling are similar.
Here are functions handling PRESENCE_SET, FINAL_PRESENCE_SET, ABSENCE_SET, and FINAL_ABSENCE_SET.
1857 void
1858 gen_presence_set (rtx def) in genautomata.c
1859 {
1860 gen_presence_absence_set (def, TRUE, FALSE);
1861 }
1868 void
1869 gen_final_presence_set (rtx def) in genautomata.c
1870 {
1871 gen_presence_absence_set (def, TRUE, TRUE);
1872 }
1879 void
1880 gen_absence_set (rtx def) in genautomata.c
1881 {
1882 gen_presence_absence_set (def, FALSE, FALSE);
1883 }
1890 void
1891 gen_final_absence_set (rtx def) in genautomata.c
1892 {
1893 gen_presence_absence_set (def, TRUE, TRUE);
1894 }
See that except exclude_set, the second operand of other patterns is ‘PATTERNS’, i.e., one unit or units separated by white-spaces (which of exclude_set is ‘UNIT-NAMES’, the units list).
1789 static void
1790 gen_presence_absence_set (rtx def, int presence_p, int final_p) in genautomata.c
1791 {
1792 decl_t decl;
1793 char **str_cpu_units;
1794 char ***str_patterns;
1795 int cpu_units_length;
1796 int length;
1797 int patterns_length;
1798 int i;
1799
1800 str_cpu_units = get_str_vect ((char *) XSTR (def, 0), &cpu_units_length, ',',
1801 FALSE);
1802 if (str_cpu_units == NULL)
1803 fatal ((presence_p
1804 ? (final_p
1805 ? "invalid first string `%s' in final_presence_set"
1806 : "invalid first string `%s' in presence_set")
1807 : (final_p
1808 ? "invalid first string `%s' in final_absence_set"
1809 : "invalid first string `%s' in absence_set")),
1810 XSTR (def, 0));
1811 str_patterns = (char ***) get_str_vect ((char *) XSTR (def, 1),
1812 &patterns_length, ',', FALSE);
1813 if (str_patterns == NULL)
1814 fatal ((presence_p
1815 ? (final_p
1816 ? "invalid second string `%s' in final_presence_set"
1817 : "invalid second string `%s' in presence_set")
1818 : (final_p
1819 ? "invalid second string `%s' in final_absence_set"
1820 : "invalid second string `%s' in absence_set")), XSTR (def, 1));
1821 for (i = 0; i < patterns_length; i++)
1822 {
1823 str_patterns [i] = get_str_vect ((char *) str_patterns [i], &length, ' ',
1824 FALSE);
1825 if (str_patterns [i] == NULL)
1826 abort ();
1827 }
1828 decl = create_node (sizeof (struct decl));
1829 decl->pos = 0;
1830 if (presence_p)
1831 {
1832 decl->mode = dm_presence;
1833 DECL_PRESENCE (decl)->names_num = cpu_units_length;
1834 DECL_PRESENCE (decl)->names = str_cpu_units;
1835 DECL_PRESENCE (decl)->patterns = str_patterns;
1836 DECL_PRESENCE (decl)->patterns_num = patterns_length;
1837 DECL_PRESENCE (decl)->final_p = final_p;
1838 }
1839 else
1840 {
1841 decl->mode = dm_absence;
1842 DECL_ABSENCE (decl)->names_num = cpu_units_length;
1843 DECL_ABSENCE (decl)->names = str_cpu_units;
1844 DECL_ABSENCE (decl)->patterns = str_patterns;
1845 DECL_ABSENCE (decl)->patterns_num = patterns_length;
1846 DECL_ABSENCE (decl)->final_p = final_p;
1847 }
1848 VLA_PTR_ADD (decls , decl);
1849 num_dfa_decls ++;
1850 }
DECL_PRESENT accesses presence field of decl, while DECL_ABSENT accesses absence field of decl. Both are of type unit_pattern_rel_decl.
835 struct unit_pattern_rel_decl in genautomata.c
836 {
837 int final_p;
838 int names_num;
839 int patterns_num;
840 char **names;
841 char ***patterns;
842 };
9.3.9. Read in DEFINE_AUTOMATON pattern
Section 8.1.3 Overview of DEFINE_INSN_RESERVATION pattern describes the detail of DEFINE_AUTOMATON pattern. For this pattern, we use following example:
71 (define_automaton "pentium,pentium_fpu") in pentium.md
This pattern is part of pipe hazards description for construting DFA-based recognizer, this pattern shouldn’t coexist with define_function_unit in same machine description file.
After treated by init_md_reader_args , above pattern will be loaded into memory as rtx object as following.
figure 46 : example of DEFINE_AUTOMATON pattern
We need change this rtx object into object of decl_t by gen_automaton .
1901 void
1902 gen_automaton (rtx def) in genautomata.c
1903 {
1904 decl_t decl;
1905 char **str_automata;
1906 int vect_length;
1907 int i;
1908
1909 str_automata = get_str_vect ((char *) XSTR (def, 0), &vect_length, ',',
1910 FALSE);
1911 if (str_automata == NULL)
1912 fatal ("invalid string `%s' in define_automaton", XSTR (def, 0));
1913 for (i = 0; i < vect_length; i++)
1914 {
1915 decl = create_node (sizeof (struct decl));
1916 decl->mode = dm_automaton;
1917 decl->pos = 0;
1918 DECL_AUTOMATON (decl)->name = check_name (str_automata [i], decl->pos);
1919 VLA_PTR_ADD (decls , decl);
1920 num_dfa_decls ++;
1921 }
1922 }
DECL_AUTOMATON accesses automaton field of decl, which has following definition.
803 struct automaton_decl in genautomata.c
804 {
805 char *name;
806
807 /* The following fields are defined by automaton generator. */
808
809 /* The following field value is nonzero if the automaton is used in
810 an regexp definition. */
811 char automaton_is_used;
812
813 /* The following fields are defined by checker. */
814
815 /* The following field value is the corresponding automaton. This
816 field is not NULL only if the automaton is present in unit
817 declarations and the automatic partition on automata is not
818 used. */
819 automaton_t corresponding_automaton;
820 };
automaton_t field referres to the object of automaton created later. We will look at it later.
9.3.10. Read in AUTOMATA_OPTION pattern
As we see before, we can use AUTOMATA_OPTION pattern to instruct the automaton generation.
1928 void
1929 gen_automata_option (rtx def) in genautomata.c
1930 {
1931 if (strcmp (XSTR (def, 0), NO_MINIMIZATION_OPTION + 1) == 0)
1932 no_minimization_flag = 1;
1933 else if (strcmp (XSTR (def, 0), TIME_OPTION + 1) == 0)
1934 time_flag = 1;
1935 else if (strcmp (XSTR (def, 0), V_OPTION + 1) == 0)
1936 v_flag = 1;
1937 else if (strcmp (XSTR (def, 0), W_OPTION + 1) == 0)
1938 w_flag = 1;
1939 else if (strcmp (XSTR (def, 0), NDFA_OPTION + 1) == 0)
1940 ndfa_flag = 1;
1941 else if (strcmp (XSTR (def, 0), PROGRESS_OPTION + 1) == 0)
1942 progress_flag = 1;
1943 else
1944 fatal ("invalid option `%s' in automata_option", XSTR (def, 0));
1945 }
This pattern is part of pipe hazards description for construting DFA-based recognizer, this pattern shouldn’t coexist with define_function_unit in same machine description file.
Notice that to specify more than one option, more than one AUTOMATA_OPTION pattern should be used.