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对象载入内存。

t47

47DEFINE_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访问declreserv域。

 

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访问regexponeof域,它具有如下的定义,其中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行被递归。最后这个例子被转换到如下的结构。

t48

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对象载入内存。

t49

49DEFINE_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访问declinsn_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处理后,产生以下的数据。

t50

50:为define_insn_reservation模式产生的regexp的例子