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的例子
发表评论
-
shell实例(七) --参数/字符串替换
2012-07-06 09:52 10331.说明 ${parameter-default} --- ... -
asp.net下集成(Active Messenger)AM消息发送组件
2012-07-03 13:44 1280Active Messenger是杭州恒创软件公司开发的一 ... -
Flex富文本编辑器(嵌入Fck)
2012-07-02 13:04 1022... -
(Flex)让Panel可拖动
2012-07-02 13:04 562height="300" mouseD ... -
flex 中Tree的数据由数组提供
2012-07-02 13:04 420flex/spark" xmln ... -
flex 事件触发篇
2012-07-02 13:04 573事件触发篇 完整代码 ... -
FLEX 条形图(柱状图)设置刻度为百分比
2012-07-02 13:04 1105作者原创,如需转载请注明出处:www.krzone.org ... -
[转]Flex中[Bindable]的用法
2012-07-01 10:37 624什么是元数据(metadata):[Bindable]大 ... -
Flex 动态datagrid的应用
2012-07-01 10:37 635Flex有2种常用的datagrid: ... -
FLEX与javascript交互
2012-07-01 10:37 587用Flex来调用同一页面中的javascript函数。调用 ... -
Flex + BlazeDS 学习笔记 (一) --- BlazeDS的功能原理及配置实例
2012-07-01 10:37 743BlazeDS Test Drive里面 ... -
页面中嵌入FLEX应用-传参
2012-06-30 17:01 662页面中嵌入FLEX应用-传参 2010年06月29日 项 ... -
用Parsley实现Flex Ioc的简单例子
2012-06-30 17:01 567用Parsley实现Flex Ioc的简单例子 2010年0 ... -
Flex嵌入jsp开发心得
2012-06-30 17:01 734Flex嵌入jsp开发心得 2010年07月02日 PM ... -
flex与数据库交互
2012-06-30 17:01 538flex与数据库交互 2010年07月04日 Flex最 ...
相关推荐
从GCC编译器的体系结构出发,提出了GCC前后端分离的结构以适合移植到不同的硬件平台,分析了GCC后 端移植的关键技术。重点阐述后端移植所必须的...体系结构,GCC后端移植技术是可行的,能够产生正确的汇编语言代码。
前端设计方面,主要是通过添加函数属性的方式来实现对特定形式 中断函数的处理,并沿用整数类型的处理机制实现对如bit等数据...计相关接口,实现了特定汇编信息的输出,解决了GCC标准输出与现有汇编器 不兼容的问题。
源代码首先由前端(例如llvm-gcc或 . 然后将 LLVM IR 转换为汇编代码,链接到其他 Java 类,然后汇编为 JVM 字节码。 与使用 MIPS 二进制作为中间表示的其他方法(例如 和 )相比,使用 LLVM IR 作为中间表示允许...
Python简单神经网络这是一个带有C后端的NeuralNetwork库,非常适合分类问题,并且具有一些适用于游戏的强化学习代理(下面的示例)。 它非常易于使用(不需要外部库,甚至...汇编这将为python接口编译C后端库gcc -fPIC
MIR - 一个由 Redhat GCC 维护者开发的新的 C 语言 JIT 后端 NanoJIT - 最初由 Adobe 为 Flash 编写的小型 JIT 引擎 nj - 基于Eclipse OMR用 C++ 编写的 JIT 引擎。 IBM 的 Java 实现中使用了 Eclipse OMR,但 ...
快速开始 ... 具有代码分析和改进阶段的后端(优化器) 将SASM转换为实用的汇编语言(x86,MIPS) 具有基本内存管理和垃圾收集器的运行时库 这个想法是,要为某种编程语言构建一个编译器,你必须主要编
该编译器执行source.c-> a.out的大部分过程,但需要外部预处理器以及外部汇编器和链接器的帮助。 Lexer 该是用Flex构建的,并读取和标记化应进行预处理的C语言输入(例如,使用gcc -E)。 所有C99都应包括在内。 ...
RarVM工具链此代码主要用于历史参考。 自该代码发布以来,WinRAR和其他产品... 反汇编程序将很快面市,也许最终会提供编译器(以llvm后端或gcc目标的形式)。 相关博客文章可在此处找到,用法本文档中引用了五种类型的
1.基于处理器的移植 这种类型的移植要求从支持处理器的编译器开始,这是主要的也是困难的一步。...这些后端告诉goo在编译时如何形成汇编代码,如何满足处理器体系结构下的参数传递,如何针对处理器进行流水
还有一个替代渲染后端,它使用 OpenGL 硬件细分进行性能比较。 这是它的运行视频: 汇编 在 Linux 上构建 micropolis 需要以下依赖项: 控制器 GLFW 3.0 促进 开放式语言 魔鬼 Python 3.x 喘息模板 Cap'n Proto...
它包括一个C / C ++编译器(clang),汇编器,链接器和调试器(lldb)。 尽管此项目包括C / C ++编译器,但LLVM后端可以支持任何语言。 问题或问题可以直接发送至或...建造NyuziProcessor存储库README也提供了有关...