`
vr393vr
  • 浏览: 11822 次
最近访客 更多访客>>
社区版块
存档分类
最新评论

GCC后端及汇编发布(20)

 
阅读更多

  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产生更有序的对象。 2106void 2107gen_reserv (rtx def)                                                                             in genautomata.c 2108{ 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  structreserv_decl                                                                                 in genautomata.c 846  { 847     char *name; 849   850     /* The following fields are defined by checker.   */ 851   852     /* The following field value is nonzero if the unit is used in an 853       regexp.   */ 854     char reserv_is_used; 855     /* The following field is used to check up cycle in expression 856       definition.   */ 857     int loop_pass_num; 858  }; Regexp设计用于描述指令对cpu单元占据的正则表达式。正则表达式的细节参考DEFINE_INSN_RESERVATION模式的概览一节。 990  struct regexp                                                                                       in genautomata.c 991  { 992    /* What node in the union? */ 993    enum regexp_mode mode; 994     pos_t pos; 995    union 996     { 997      struct unit_regexp unit; 998      struct reserv_regexp reserv; 999      struct nothing_regexp nothing; 1000    struct sequence_regexp sequence; 1001    struct repeat_regexp repeat; 1002    struct allof_regexp allof; 1004   } regexp; 1005}; 197  typedefstruct regexp *regexp_t;                                                            in genautomata.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对象。 2095gen_regexp (char *str)                                                                         in genautomata.c 2096{ 2097  reserv_str = str; 2099} gen_regexp通过从顶向下解析表达式来生成这个结构体。对于我们的例子,这个表达式是"(pentium-load + pentium-firstuv + pentium-memory) | (pentium-firstv, pentium-v, (pentium-load + pentium-firstv))"。 2070gen_regexp_sequence (char *str)                                                           in genautomata.c 2071{ 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 (struct regexp) 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 regexps [i] 2086                = gen_regexp_oneof (sequence_vect [i]); 2087    return sequence; 2088   } 2089   else 在正则表达式中,','用于表示在单元预订中下一个周期的开始。在2077行,get_str_vect尝试把这个正则表达式分解成周期。注意到该函数的第三个参数是TRUE,表示这个分解,仅当左右括号数目匹配时,才被执行。在","的两边可能是"|"表达式,因此调用gen_regexp_oneof来处理这两边。 2044gen_regexp_oneof (char *str)                                                               in genautomata.c 2045{ 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 (structregexp) 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 regexps [i] = gen_regexp_allof (oneof_vect [i]); 2062    return oneof; 2063   } 2064   else 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  structoneof_regexp                                                                                     in genautomata.c 984  { 985     int regexps_num; 987  }; 在"|"表达式中,我们可能遇到"+"表达式,因此我们需要gen_regexp_allof来处理这些分解的片段。 2018gen_regexp_allof (char *str)                                                                 in genautomata.c 2019{ 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 (struct regexp) 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 regexps [i] = gen_regexp_repeat (allof_vect [i]); 2036    return allof; 2037   } 2038   else 2040} 在2025行的get_str_vect这次尝试找出由'+'连接的部分,再次第三个参数是TRUE,只有匹配的括号对才被考虑。 现在对于我们的例子,正则表达式已经被分解为两部分。对于这两部分get_str_vect不能进一步分解。这两者都在2039行进入gen_regexp_repeat。 1985gen_regexp_repeat (char *str)                                                               in genautomata.c 1986{ 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 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 正则表达式重复NUMBER次,同时伴随周期的推进。例如,*5表示重复5次。在我们的例子中,这两部分都不包含'*',它们只是在2013行进入gen_regexp_el。 1956gen_regexp_el (char *str)                                                                     in genautomata.c 1957{ 1959   int len; 1960 1961   if (*str == '(') 1962   { 1963     len = strlen (str); 1964     if (str [len - 1] != ')') 1965       fatal ("garbage after ) in reservation `%s'", reserv_str); 1966     str [len - 1] = '\0'; 1968   } 1969   else if (strcmp (str, NOTHING_NAME) == 0) 1970   { 1971     regexp = create_node (sizeof (struct decl)); 1972     regexp->mode = rm_nothing; 1973   } 1974   else 1975   { 1976     regexp = create_node (sizeof (struct decl)); 1977     regexp->mode = rm_unit; 1978     REGEXP_UNIT (regexp)->name = str; 1979   } 1980  return regexp; 1981} 在这个例子中,这两部分都被括号所包围,括号之间应该被视为一个序列。因此gen_regexp_sequence将在1967行被递归。最后这个例子被转换到如下的结构。 
  
  图48:为define_ reservation模式所产生的regexp对象的例子 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被调用来收集数据。 2125void 2126gen_insn_reserv (rtx def)                                                                     in genautomata.c 2127{ 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  structinsn_reserv_decl                                                                          in genautomata.c 862  { 863     rtx condexp; 864     int default_latency; 866     char *name; 867   868     /* The following fields are defined by checker.   */ 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 of bypasses in which given insn 874       is output insn.   */ 876   877     /* The following fields are defined by automaton generator.   */ 878   879     /* The following field is the insn regexp transformed that 880       the regexp has not optional regexp, repetition regexp, and an 881       reservation name (i.e. reservation identifiers are changed by the 882       corresponding regexp) and all alternations are the topest level 883       of the regexp. The value can be NULL only if it is special 884       insn `cycle advancing'.   */ 886     /* The following field value is list of arcs marked given 887       insn. The field is used in transformation NDFA -> DFA.   */ 888     arc_t arcs_marked_by_insn; 889     /* The two following fields are used during minimization of a finite state 890       automaton.   */ 891     /* The field value is number of equivalence class of state into 892       which arc marked by given insn enters from a state (fixed during 893       an automaton minimization).   */ 894     int equiv_class_num; 895     /* The field value is state_alts of arc leaving a state (fixed 896       during an automaton minimization) and marked by given insn 897       enters.   */ 898     int state_alts; 899    /* The following member value is the list to automata which can be 900       changed by the insn issue.   */ 901     automata_list_el_t important_automata_list; 902    /* The following member is used to process insn 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的例子
分享到:
评论

相关推荐

Global site tag (gtag.js) - Google Analytics