GCC后端及汇编发布(20)
来源:互联网 发布:如何查看淘宝排名 编辑:程序博客网 时间:2024/04/30 09:12
9.3.11. 读入DEFINE_RESERVATION模式
DEFINE_INSN_RESERVATION模式的概览一节描述了DEFINE_RESERVATION模式的细节。对于这个模式,我们使用以下的例子:
129 (define_reservation"pentium-firstuvboth" "(pentium-load + pentium-firstuv in pentium.md
130 + pentium-memory)
131 |(pentium-firstv,pentium-v,
132 (pentium-load+pentium-firstv))")
这个模式是构建基于DFA识别器的流水线危险描述的一部分,该模式不应该与define_function_unit共存于同一个机器描述文件里。
在经过init_md_reader_args的处理后,上面的模式将作为以下的rtx对象载入内存。
图47:DEFINE_RESERVATION模式的例子
显然这个原始的形式不是我们想要的。gen_reserv产生更有序的对象。
2106 void
2107 gen_reserv (rtx def) ingenautomata.c
2108 {
2109 decl_t decl;
2110
2111 decl = create_node (sizeof(struct decl));
2112 decl->mode = dm_reserv;
2113 decl->pos = 0;
2114 DECL_RESERV (decl)->name = check_name ((char *) XSTR (def, 0),decl->pos);
2115 DECL_RESERV (decl)->regexp = gen_regexp ((char *) XSTR (def, 1));
2116 VLA_PTR_ADD (decls, decl);
2117 num_dfa_decls++;
2118 }
DECL_RESERV访问decl的reserv域。
845 struct reserv_decl ingenautomata.c
846 {
847 char *name;
848 regexp_t regexp;
849
850 /* The following fields are defined bychecker. */
851
852 /* The following field value is nonzero ifthe unit is used in an
853 regexp. */
854 char reserv_is_used;
855 /* The following field is used to check upcycle in expression
856 definition. */
857 int loop_pass_num;
858 };
Regexp设计用于描述指令对cpu单元占据的正则表达式。正则表达式的细节参考DEFINE_INSN_RESERVATION模式的概览一节。
990 struct regexp ingenautomata.c
991 {
992 /* What node in theunion? */
993 enum regexp_mode mode;
994 pos_t pos;
995 union
996 {
997 structunit_regexp unit;
998 structreserv_regexp reserv;
999 structnothing_regexp nothing;
1000 structsequence_regexp sequence;
1001 structrepeat_regexp repeat;
1002 structallof_regexp allof;
1003 struct oneof_regexponeof;
1004 } regexp;
1005 };
197 typedef struct regexp *regexp_t; ingenautomata.c
这个结构体由gen_regexp生成。正则表达式遵循以下的语法:
regexp = regexp "," oneof
| oneof
oneof = oneof"|" allof
| allof
allof = allof"+" repeat
| repeat
repeat = element"*" number
| element
element =cpu_function_unit_name
| reservation_name
| result_name
| "nothing"
| "(" regexp")"
gen_regexp根据上图中的正则表达式,构成regexp对象。
2094 static regexp_t
2095 gen_regexp (char *str) ingenautomata.c
2096 {
2097 reserv_str = str;
2098 return gen_regexp_sequence (str);;
2099 }
gen_regexp通过从顶向下解析表达式来生成这个结构体。对于我们的例子,这个表达式是“(pentium-load+ pentium-firstuv + pentium-memory) | (pentium-firstv, pentium-v, (pentium-load+ pentium-firstv))”。
2069 static regexp_t
2070 gen_regexp_sequence (char *str) ingenautomata.c
2071 {
2072 regexp_t sequence;
2073 char **sequence_vect;
2074 int els_num;
2075 int i;
2076
2077 sequence_vect = get_str_vect (str,&els_num, ',', TRUE);
2078 if (els_num > 1)
2079 {
2080 sequence = create_node (sizeof (structregexp)
2081 + sizeof(regexp_t) * (els_num - 1));
2082 sequence->mode = rm_sequence;
2083 REGEXP_SEQUENCE (sequence)->regexps_num= els_num;
2084 for (i = 0; i < els_num; i++)
2085 REGEXP_SEQUENCE (sequence)->regexps[i]
2086 = gen_regexp_oneof (sequence_vect [i]);
2087 returnsequence;
2088 }
2089 else
2090 return gen_regexp_oneof (str);
在正则表达式中,‘,’用于表示在单元预订中下一个周期的开始。在2077行,get_str_vect尝试把这个正则表达式分解成周期。注意到该函数的第三个参数是TRUE,表示这个分解,仅当左右括号数目匹配时,才被执行。在“,”的两边可能是“|”表达式,因此调用gen_regexp_oneof来处理这两边。
2043 static regexp_t
2044 gen_regexp_oneof (char *str) ingenautomata.c
2045 {
2046 regexp_t oneof;
2047 char **oneof_vect;
2048 int els_num;
2049 int i;
2050
2051 oneof_vect = get_str_vect (str, &els_num,'|', TRUE);
2052 if (oneof_vect == NULL)
2053 fatal ("invalid `%s' in reservation`%s'", str, reserv_str);
2054 if (els_num > 1)
2055 {
2056 oneof = create_node (sizeof (struct regexp)
2057 + sizeof (regexp_t) *(els_num - 1));
2058 oneof->mode = rm_oneof;
2059 REGEXP_ONEOF (oneof)->regexps_num =els_num;
2060 for (i = 0; i < els_num; i++)
2061 REGEXP_ONEOF (oneof)->regexps [i] = gen_regexp_allof (oneof_vect [i]);
2062 return oneof;
2063 }
2064 else
2065 return gen_regexp_allof (str);
2066 }
这次get_str_vect尝试根据‘|’来分解字符串。再次,get_str_vect的第三个参数是TRUE,因此对于我们的例子,我们可以在2051行得到具有两个元素的oneof_vect:
"(pentium-load + pentium-firstuv + pentium-memory)"
"(pentium-firstv, pentium-v, (pentium-load + pentium-firstv))"
第二个不能被get_str_vect根据“,”来分解,因为当“(”的数目匹配“)”时,没有 “,”可见。
上面在2059行,宏REGEXP_ONEOF访问regexp的oneof域,它具有如下的定义,其中regexps域是一个可变长度数组,其大小依赖于“|”操作符的数目(参见上面的2056行)。
983 struct oneof_regexp ingenautomata.c
984 {
985 int regexps_num;
986 regexp_t regexps [1];
987 };
在“|”表达式中,我们可能遇到“+”表达式,因此我们需要gen_regexp_allof来处理这些分解的片段。
2017 static regexp_t
2018 gen_regexp_allof (char *str) ingenautomata.c
2019 {
2020 regexp_t allof;
2021 char **allof_vect;
2022 int els_num;
2023 int i;
2024
2025 allof_vect = get_str_vect (str, &els_num,'+', TRUE);
2026 if (allof_vect == NULL)
2027 fatal ("invalid `%s' in reservation`%s'", str, reserv_str);
2028 if (els_num > 1)
2029 {
2030 allof = create_node (sizeof (structregexp)
2031 + sizeof(regexp_t) * (els_num - 1));
2032 allof->mode = rm_allof;
2033 REGEXP_ALLOF (allof)->regexps_num = els_num;
2034 for (i = 0; i < els_num; i++)
2035 REGEXP_ALLOF (allof)->regexps [i] = gen_regexp_repeat (allof_vect [i]);
2036 returnallof;
2037 }
2038 else
2039 return gen_regexp_repeat (str);
2040 }
在2025行的get_str_vect这次尝试找出由‘+’连接的部分,再次第三个参数是TRUE,只有匹配的括号对才被考虑。
现在对于我们的例子,正则表达式已经被分解为两部分。对于这两部分get_str_vect不能进一步分解。这两者都在2039行进入gen_regexp_repeat。
1984 static regexp_t
1985 gen_regexp_repeat (char *str) ingenautomata.c
1986 {
1987 regexp_t regexp;
1988 regexp_t repeat;
1989 char **repeat_vect;
1990 int els_num;
1991 int i;
1992
1993 repeat_vect = get_str_vect (str,&els_num, '*', TRUE);
1994 if (repeat_vect == NULL)
1995 fatal ("invalid `%s' in reservation`%s'", str, reserv_str);
1996 if(els_num > 1)
1997 {
1998 regexp = gen_regexp_el (repeat_vect [0]);
1999 for (i = 1; i < els_num; i++)
2000 {
2001 repeat= create_node (sizeof (structregexp));
2002 repeat->mode= rm_repeat;
2003 REGEXP_REPEAT (repeat)->regexp = regexp;
2004 REGEXP_REPEAT (repeat)->repeat_num = atoi(repeat_vect [i]);
2005 if (REGEXP_REPEAT (repeat)->repeat_num<= 1)
2006 fatal ("repetition `%s' <= 1 in reservation `%s'",
2007 str, reserv_str);
2008 regexp = repeat;
2009 }
2010 returnregexp;
2011 }
2012 else
2013 return gen_regexp_el (str);
2014 }
记得‘*’为了方便使用,它仅简单地表示一个序列,在其中这个正则表达式重复NUMBER次,同时伴随周期的推进。例如,*5表示重复5次。在我们的例子中,这两部分都不包含‘*’,它们只是在2013行进入gen_regexp_el。
1955 static regexp_t
1956 gen_regexp_el (char *str) ingenautomata.c
1957 {
1958 regexp_t regexp;
1959 int len;
1960
1961 if (*str == '(')
1962 {
1963 len = strlen (str);
1964 if (str [len - 1] != ')')
1965 fatal ("garbage after ) inreservation `%s'", reserv_str);
1966 str [len - 1] = '/0';
1967 regexp = gen_regexp_sequence (str + 1);
1968 }
1969 else if (strcmp (str, NOTHING_NAME) == 0)
1970 {
1971 regexp = create_node (sizeof (structdecl));
1972 regexp->mode = rm_nothing;
1973 }
1974 else
1975 {
1976 regexp = create_node (sizeof (structdecl));
1977 regexp->mode = rm_unit;
1978 REGEXP_UNIT (regexp)->name = str;
1979 }
1980 returnregexp;
1981 }
在这个例子中,这两部分都被括号所包围,括号之间应该被视为一个序列。因此gen_regexp_sequence将在1967行被递归。最后这个例子被转换到如下的结构。
图48:为define_ reservation模式所产生的regexp对象的例子
9.3.12. 读入DEFINE_INSN_RESERVATION模式
DEFINE_INSN_RESERVATION模式的概览一节描述了DEFINE_INSN_RESERVATION模式的细节。对于这个模式,我们使用如下的例子:
166 (define_insn_reservation"pent_fpmovxf" 3 in pentium.md
167 (and (eq_attr "cpu" "pentium")
168 (and (eq_attr "type" "fmov")
169 (and (eq_attr "memory""load,store")
170 (eq_attr"mode" "XF"))))
171 "(pentium-fp+pentium-np)*3")
这个模式是构建基于DFA识别器的流水线危险描述的一部分,该模式不应该与define_function_unit共存于同一个机器描述文件里。正如我们在读入DEFINE_FUNCTION_UNIT模式已经所讨论的,这个模式以指令的角度来描述系统,而不是从功能单元的角度。通常,指令的数目要远远多于功能单元的数目,因此自动机,对于流水线危险识别器来说,是一个更好的形式。
在经过init_md_reader_args的处理后,上面的模式将作为以下的rtx对象载入内存。
图49:DEFINE_INSN_RESERVATION模式的例子
这个rtx对象对于构建基于DFA的流水线危险识器起重要作用。gen_insn_reserv被调用来收集数据。
2125 void
2126 gen_insn_reserv (rtx def) ingenautomata.c
2127 {
2128 decl_t decl;
2129
2130 decl = create_node (sizeof(struct decl));
2131 decl->mode= dm_insn_reserv;
2132 decl->pos = 0;
2133 DECL_INSN_RESERV (decl)->name
2134 = check_name ((char *) XSTR (def, 0),decl->pos);
2135 DECL_INSN_RESERV (decl)->default_latency =XINT (def, 1);
2136 DECL_INSN_RESERV (decl)->condexp = XEXP (def,2);
2137 DECL_INSN_RESERV (decl)->regexp = gen_regexp((char *) XSTR (def, 3));
2138 VLA_PTR_ADD (decls, decl);
2139 num_dfa_decls++;
2140 }
宏DECL_INSN_RESERV访问decl的insn_reserv域,它具有如下的定义。
861 struct insn_reserv_decl ingenautomata.c
862 {
863 rtx condexp;
864 int default_latency;
865 regexp_t regexp;
866 char *name;
867
868 /* The following fields are defined bychecker. */
869
870 /* The following field value is order number(0, 1, ...) of given
871 insn. */
872 int insn_num;
873 /* The following field value is list ofbypasses in which given insn
874 is output insn. */
875 struct bypass_decl*bypass_list;
876
877 /* The following fields are defined byautomaton generator. */
878
879 /* The following field is the insn regexptransformed that
880 the regexp has not optional regexp,repetition regexp, and an
881 reservation name (i.e. reservationidentifiers are changed by the
882 corresponding regexp) and all alternationsare the topest level
883 of the regexp. The value can be NULL onlyif it is special
884 insn `cycle advancing'. */
885 regexp_t transformed_regexp;
886 /* The following field value is list of arcsmarked given
887 insn. The field is used in transformationNDFA -> DFA. */
888 arc_t arcs_marked_by_insn;
889 /* The two following fields are used duringminimization of a finite state
890 automaton. */
891 /* The field value is number of equivalenceclass of state into
892 which arc marked by given insn enters froma state (fixed during
893 an automaton minimization). */
894 int equiv_class_num;
895 /* The field value is state_alts of arcleaving a state (fixed
896 during an automaton minimization) and markedby given insn
897 enters. */
898 int state_alts;
899 /* The following member value is the list toautomata which can be
900 changed by the insn issue. */
901 automata_list_el_t important_automata_list;
902 /* The following member is used to processinsn once for output. */
903 int processed_p;
904 };
在gen_insn_reserv中的2138行,gen_regexp的参数是“(pentium-fp+pentium-np)*3”。 这部分在gen_regexp处理后,产生以下的数据。
图50:为define_insn_reservation模式产生的regexp的例子
- GCC后端及汇编发布(20)
- GCC后端及汇编发布(1)
- GCC后端及汇编发布(2)
- GCC后端及汇编发布(3)
- GCC后端及汇编发布(4)
- GCC后端及汇编发布(5)
- GCC后端及汇编发布(6)
- GCC后端及汇编发布(7)
- GCC后端及汇编发布(8)
- GCC后端及汇编发布(9)
- GCC后端及汇编发布(10)
- GCC后端及汇编发布(11)
- GCC后端及汇编发布(12)
- GCC后端及汇编发布(13)
- GCC后端及汇编发布(14)
- GCC后端及汇编发布(15)
- GCC后端及汇编发布(16)
- GCC后端及汇编发布(17)
- 分词实验小结
- GCC's bacl-end & assemble emission (19)
- au3和tcp
- Vista/server2008引导修复(转载)
- struts2项目中用Js获取URL地址参数
- GCC后端及汇编发布(20)
- css相关
- GCC's bacl-end & assemble emission (20)
- GCC后端及汇编发布(21)
- GCC's bacl-end & assemble emission (21)
- 歌词
- 如何增加私有MIB
- asp.net 防止外部提交数据
- 菜单相关