DEFINE_INSN_RESERVATION模式的概览 一节描述了 define_bypass 模式的细节。对于这个模式,我们使用以下的例子:
188 (define_bypass 0 "pent_push,pent_pop" "pent_push,pent_pop,pent_call") in pentium.md
图 44 : DEFINE_BYPASS 模式的例子
这个模式是构建基于 DFA 识别器的流水线危险描述的一部分,该模式不应该与 define_function_unit 共存于同一个机器描述文件里。
在经过 init_md_reader_args 的处理后,上面的模式将作为上面的 rtx 对象载入内存。这里对 define_bypass 的处理类似于 define_cup_unit 。并且所构建的 decl 同样链入由 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 }
上面 , DECL_BYPASS 访问 decl 的 bypass 域 , 它具有如下的定义 :
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 };
DEFINE_INSN_RESERVATION模式的概览 一节描述了 EXCLUSION_SET 模式的细节。对于这个模式,我们使用以下的例子:
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")
这个模式是构建基于 DFA 识别器的流水线危险描述的一部分,该模式不应该与 define_function_unit 共存于同一个机器描述文件里。
在经过 init_md_reader_args 的处理后,上面的模式将作为以下的 rtx 对象载入内存。这里对 exclusion_set 的处理类似于 define_cup_unit 。并且所构建的 decl 同样链入由 decls 所指向的链表。
图 45 : EXCLUSION_SET 模式的例子
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 访问 decl 的 excl_rel_decl 域。 excl_rel_decl 具有如下定义 , 看到 names 域实际上是可变长度数组 , 其元素对应单元名。
826 struct excl_rel_decl in genautomata.c
827 {
828 int all_names_num;
829 int first_list_length;
830 char *names [1];
831 };
前面看过,模式 PRESENCE_SET , FINAL_PRESENCE_SET , ABSENCE_SET 及 FINAL_ABSENCE_SET 使用相同的格式,因此它们的处理是类似的。
下面的函数处理 PRESENCE_SET , FINAL_PRESENCE_SET , ABSENCE_SET 及 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 }
注意对于 exclude_set 之外,其它模式的第二个操作数都是‘ PATTERNS ’,即功能单元模式列表,每个功能单元模式是一个单元或由空格分隔的多个单元( exclude_set 中则是‘ UNIT-NAMES ’,即单元列表)。
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 访问 decl 的 presence 域 , 而 DECL_ABSENT 访问 decl 的 absence 域。两者都具有类型 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 };
DEFINE_INSN_RESERVATION模式的概览 一节描述了 DEFINE_AUTOMATON 模式的细节。对于这个模式,我们使用以下例子:
71 (define_automaton "pentium,pentium_fpu") in pentium.md
这个模式是构建基于 DFA 识别器的流水线危险描述的一部分 , 该模式不应该与 define_function_unit 共存于同一个机器描述文件里。
在经过 init_md_reader_args 的处理后,上面的模式将作为以下的 rtx 对象载入内存。
图 46 : DEFINE_AUTOMATON 模式的例子
我们需要把这个 rtx 对象通过 gen_automaton 转换为 decl_t 对象。
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 访问 decl 的 automaton 域,这个域具有如下的定义。
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 域指向后面所构建的 automaton 对象。我们将在后面看到它。
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 }
这个模式是构建基于 DFA 识别器的流水线危险描述的一部分 , 该模式不应该与 define_function_unit 共存于同一个机器描述文件里。
注意为了指明多个选项, 应该使用多个 AUTOMATA_OPTION 模式。