忠心gengen得gen培训心得体会怎么写写

人到底要怎样的活着
许三多说:人要活得有意义。那怎么才叫有意义了,许家老三说好好活就是有意义.我经常在思考这个问题。我觉得非常有必要,因为思考好了它能够指导现实生活。用小沈阳的话说:人的一生可短暂了!那我们如何活了?如何更好的活了?人的一生都应该离不开这个问题。对于我来说,其实真的很矛盾,有些时候很难取舍,很难把握,但有一点是可以肯定的那就是要有一个健康的心态,有人说健康的心态比一百种智慧都宝贵。其次加强自己的修养,多读书是捷径,但读什么书了?真希望有经验的前辈能够指导哈!每个年龄阶段有不同的需求,因此对书籍也有不同的选择。现在心静不下来,总被周围的事物所影响,真希望有那种大军压境面不改色的从容,更希望有那种运筹与帷幄之中,决胜与千里之外的睿智。目标在前,脚步就应该紧随其后。第三,平时就应该多听,少说。人为什么要长两个耳朵,一个嘴巴是有道理的,它要我们多听少说。是达尔文的进化论的体现,所以毋庸质疑。俗话说人多的地方是非多,要有选择的交友,真心待人,非礼勿视,非礼勿听,非礼勿言,非礼勿动。第四,保持微笑。微笑的面对生活,面对你所接触的人。没有人会喜欢看你的苦瓜脸,别人不欠你的钱。遇到生活中的困难时,要积极乐观,明白消极逃避不能解决问题,问题是生活中的磨石,只有在上面不断的磨,不断的取舍,你才能长大,才能成为一个能够扛起一片天的爷们,才能让家人,周边的人有安全感,踏实,才是活的有意义。有意义除了为自己活以外,很大的情况下都是为家人,为身边的人活着。学会让微笑成为一种习惯!第五,种好自己的一亩三分地。它是你生活的保障,是你活得有意义的前提。会种地的三两年就可以把地种好,不会种地的一辈子都在种,但产量低,效果差。会与不会之间关键在于是否善于思考,想起一句话,不记得原话,大概意思就是”吃不穷穿不穷,不会算计一辈子穷”。“算计”不就是思考,反思吗?
已投稿到:
以上网友发言只代表其个人观点,不代表新浪网的观点或立场。忠心gengen得gen怎么写_百度知道
忠心gengen得gen怎么写
提问者采纳
忠心耿耿,请采纳,谢谢
提问者评价
太给力了,你的回答完美地解决了我的问题,非常感谢!
其他类似问题
按默认排序
其他2条回答
等待您来回答
下载知道APP
随时随地咨询
出门在外也不愁GCC-3.4.6源代码学习笔记(42)
4.2.1.2.&&& 初始化哈希表
与前端相似,后端亦对常用、共享的对象使用哈希表。在以后的章节,结合编译过程,我们再来看这些哈希表中,元素的意义。
接着在init_emit_once,5474到5494行,找出适合字节类型,字类型及double类型的模式,而ptr_mode在5494行由mode_for_size来确定。
4.2.1.3.&&& 创建Rtl对象
4.2.1.3.1.&&&&&&&&&&& Rtl语言
接下来,init_emit_once开始创建唯一的rtx对象。与前端所使用的树的形式不同,后端使用rtl对象构成的树。前端树节点接近于源语言。而RTL比源语言要简单得多,因此将它翻译为汇编要更容易,而且独立于前端。在RTL语言中,编码用于描述所要执行的动作。在rtl.h文件中rtx_code被定义如下。
41&&& #define RTX_CODE&&&& enum rtx_code&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&& in rtl.h
42&&& enum rtx_code& {
44&&& #define DEF_RTL_EXPR(ENUM, NAME, FORMAT, CLASS)&& ENUM ,
45&&& #include "rtl.def"&&&&&&&&& /* rtl expressions are documented here */
46&&& #undef DEF_RTL_EXPR
48&&& & LAST_AND_UNUSED_RTX_CODE};&& /* A convenient way to get a value for
49&&& &&&&&&&&&&&&&&&&&&&& && NUM_RTX_CODE.
50&&& &&&&&&&&&&&&&&&&&&&& && Assumes default enum value assignment.& */
Rtl.def文件包含了表达式定义及可用于所有目标平台的描述。在这个文件中所有rtx对象以形式DEF_RTL_EXPR(ENUM, NAME, FORMAT, CLASS)给出。通过在此处相应地定义DEF_RTL_EXPR,可以为该rtx对象获得对应的数据(比如,rtx_class,rtx_format)。
RTL使用五种对象:表达式,整数,宽整数,字符串及向量。表达式是其中最重要的一个。一个RTL表达式(为了简洁起见,称为RTX)是一个C结构,但通常它由一个指针来引用;这个指针的类型由一个rtx的typedef名字给出。
一个整数简单地是一个int;它们的书写形式使用十进制数。一个宽整数是一个类型为HOST_WIDE_INT的整数对象;它们的书写形式使用十进制数。
一个字符串是一串字符。其核心是普通的C风格的char *,同时以符合C语法。不过, RTL中的字符串永远不可为空。如果在一个机器描述中写入了一个空字符串,在核心里它被表示为一个空指针,而不是指向空字符的指针。在某些上下文环境下,这些空指针而不是字符串是有效的。在RTL代码里,字符串最可能在symbol_ref表达式中找到,不过它们也出现在,构成机器描述的RTL表达式的,其他上下文环境里。
在一个机器描述中,字符串通常带有双引号,就像在C里一样。不过机器描述里的字符串可能扩展至许多行,这在C中是非法的,并且相邻的字符串常量不能像在C中那样合并。任意字符串常量可能被一组括号所包含。这有时使得机器描述的可读性好一些。
RTL的字符串有一个特殊的语法,在C代码嵌入在机器描述里时有用。只要字符串能出现的地方,同样可以写入一个C风格的大括号块。整个大括号块,包含最外围的大括号对,被认为是字符串常量。大括号内双引号中的字符如常处理。因而,如果在这个C代码中有字符串常量,就不需要用&/&来转义双引号。
一个向量包含任意数目的指向表达式的指针。向量中元素的数目显式地在向量中指出。一个向量的书写形式由中括号及所包含的元素组成([...]),这些元素依次出现,并且由空格分隔开。0长度的向量不被创建,而是使用空指针来表示。
表示式由&表达式编码&(亦称为RTX编码)。表达式编码是在rtl.def文件中定义的名字,它是一个C枚举常量(大写)。可能的表达式编码及其含义是与机器无关的。一个rtx对象的编码可以通过宏GET_MODE(X)获取,通过PUT_CODE(X, NEWCODE )改写。
表达式编码确定了该表达式所包含的参数数目,及它们的类型。在RTL中,不像Lisp,不能通过观察参数而知道其类型。相反,必须从其上下文中得知&&通过包含表达式的表达式编码。例如,在一个编码为subreg的表达式,第一个参数被认为是一个表达式,而第二个参数被视为一个整数。在一个编码为plus的表达式,有2个参数,均被认为是表达式。在一个symbol_ref表达式,有一个参数,其被视为一个字符串。
表达式被写成包含在括号中的表达式类型名,标识符,机器模式如果有的话,及表达式的参数(由空格分隔)。
在md文件中,表达式编码名是小写,但当它们出现在C代码中时,它们被大写。
在一些上下文环境中,一个空指针是有效的。在那里一个表达式如常被期待。这个空指针的书写形式是(nil)。
不同的表达式编码被分为多个&类别&,类别由单个字符表示。可以用宏GET_RTX_CLASS (CODE)来确定一个RTX编码的类别。当前,rtx.def定义了如下类别:
?&&&&&&& 用于C源代码中rtx的内部名。它是定义在rtl.h 中的枚举类型enum rtx_code 中的一个标签(tag)。按常规它们都是大写。
?&&&&&&& 被read_rtx 读入,及被print_rtx 输出的外部ASCII格式的rtx名字。这些名字被保存在rtx_name[]值。按惯例,它们是内部名字的小写形式。
?&&&&&&& 输出格式,及在该rtx中每个rtx-&u.fld[] 域的类型。这些格式被保存在rtx_format[]中。这些格式的含义被注释在rtl.c文件,该数组定义之前。
?&&&&&&& Rtx的类别。这个信息被保存在rtx_class,并由宏GET_RTX_CLASS访问。类别被定义为如下:
w&&&&&&&&& o &&用于表示一个对象(例如REG,MEM)的rtx编码
w&&&&&&&&& & &&用于比较的rtx编码(例如EQ,NE,LT)
w&&&&&&&&& 1 &&用于算术一元表达式的rtx编码(例如NEG,NOT)
w&&&&&&&&& c &&用于符合交换律的二元操作的rtx编码(例如PLUS, MULT)
w&&&&&&&&& 3 &&用于非位域的三元操作(IF_THEN_ELSE)的rtx编码
w&&&&&&&&& 2 &&用于不符合交换律的二元操作(例如MINUS,DIV)的rtx编码
w&&&&&&&&& b &&用于位域操作(ZERO_EXTRACT,SIGN_EXTRACT)的rtx编码
w&&&&&&&&& i &&用于机器指令(INSN,JUMP_INSN,CALL_INSN)的rtx编码
w&&&&&&&&& m &&用于在指令中所匹配之对象(例如MATCH_DUP)的rtx编码
w&&&&&&&&& g &&用于组合指令(例如GROUP_PARALLEL)的rtx编码
w&&&&&&&&& a &&用于自增地址模式(例如POST_DEC)的rtx编码
w&&&&&&&&& x &&其他
4.2.1.3.2.&&&&&&&&&&& 创建对象
4.2.1.3.2.1.&&&&& 用于寄存器及相关的对象
以下是将要创建的一些变量的含义:
virtual_incoming_args_rtx:指向在栈上所传入参数的第一个字,参数或者由调用者或者由被调用者传入,并假定为调用者传入。
virtual_stack_vars_rtx:如果设置了FRAME_GROWS_DOWNWARD,指向栈上第一个变量的正上方。否则,指向栈上的第一个变量。
virtual_stack_dynamic_rtx:在栈指针按所要求的数量进行调整后,指向栈上动态分配内存的位置。
virtual_cfa_rtx:指向函数的规范栈框地址(Canonical Frame Address,CFA)。这对应于由INCOMING_FRAME_SP_OFFSET产生的CFA,但出于简单起见,它相对于arg指针计算。栈指针或栈框指针,直到重装(reload)后,相对于CFA,不需要为不变。
virtual_outgoing_args_rtx:当栈在压入前(使用push指令压入的参数总是使用sp),指向栈中将写入传出参数的位置。
static_regno_reg_rtx:通常用于物理寄存器。这些对象不需要是唯一的,因此它们在global_rtl以外分配。在每个编译单元它们被初始化一次,然后在每个函数的开始被拷贝入regno_reg_rtx。
init_emit_once (continue)
5496 &&/* Assign register numbers to the globally defined register rtx.
5497 &&&&This must be done at runtime because the register number field
5498 &&&&is in a union and some compilers can't initialize unions.& */
5500 &&pc_rtx = gen_rtx (PC, VOIDmode);
5501 &&cc0_rtx = gen_rtx (CC0, VOIDmode);
5502 &&stack_pointer_rtx = gen_raw_REG (Pmode, STACK_POINTER_REGNUM);
5503 &&frame_pointer_rtx = gen_raw_REG (Pmode, FRAME_POINTER_REGNUM);
5504 &&if (hard_frame_pointer_rtx == 0)
5505 &&&&hard_frame_pointer_rtx = gen_raw_REG (Pmode,
5506&&&&&&&&&&&&&&&&&&&& & HARD_FRAME_POINTER_REGNUM);
5507 &&if (arg_pointer_rtx == 0)
5508 &&&&arg_pointer_rtx = gen_raw_REG (Pmode, ARG_POINTER_REGNUM);
5509 &&virtual_incoming_args_rtx =
5510 &&&&gen_raw_REG (Pmode, VIRTUAL_INCOMING_ARGS_REGNUM);
5511 &&virtual_stack_vars_rtx =
5512 &&&&gen_raw_REG (Pmode, VIRTUAL_STACK_VARS_REGNUM);
5513 &&virtual_stack_dynamic_rtx =
5514 &&&&gen_raw_REG (Pmode, VIRTUAL_STACK_DYNAMIC_REGNUM);
5515 &&virtual_outgoing_args_rtx =
5516 &&&&gen_raw_REG (Pmode, VIRTUAL_OUTGOING_ARGS_REGNUM);
5517 &&virtual_cfa_rtx = gen_raw_REG (Pmode, VIRTUAL_CFA_REGNUM);
5519 &&/* Initialize RTL for commonly used hard registers. These are
5520 &&&&copied into regno_reg_rtx as we begin to compile each function.& */
5521 &&for (i = 0; i & FIRST_PSEUDO_REGISTER; i++)
5522 &&&&static_regno_reg_rtx[i] = gen_raw_REG (reg_raw_mode[i], i);
5524 #ifdef INIT_EXPANDERS
5525 &&/* This is to initialize {init|mark|free}_machine_status before the first
5526 &&&&call to push_function_context_to. This is needed by the Chill front
5527 &&&&end which calls push_function_context_to before the first call to
5528 &&&&init_function_start.& */
5529 &&INIT_EXPANDERS;
5530 #endif
在上面5500和5501行,pc_rtx(程序计数器)及cc0_rtx(条件代码)都是全局rtx数组global_rtl的成员。而从索引可以看出引用了何种寄存器。它们中的大多数没有对应的物理寄存器,创建它们是为了rtl语言处理上的方便。
1807 enum global_rtl_index&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&& in rtl.h
1809 &&GR_PC,
1810 &&GR_CC0,
1811 &&GR_STACK_POINTER,
1812 &&GR_FRAME_POINTER,
1813 &&/* For register elimination to work properly these hard_frame_pointer_rtx,
1814 &&&&frame_pointer_rtx, and arg_pointer_rtx must be the same if they refer to
1815 &&&&the same register.& */
1816 #if FRAME_POINTER_REGNUM == ARG_POINTER_REGNUM
1817 &&GR_ARG_POINTER = GR_FRAME_POINTER,
1818 #endif
1819 #if HARD_FRAME_POINTER_REGNUM == FRAME_POINTER_REGNUM
1820 &&GR_HARD_FRAME_POINTER = GR_FRAME_POINTER,
1821 #else
1822 &&GR_HARD_FRAME_POINTER,
1823 #endif
1824 #if FRAME_POINTER_REGNUM != ARG_POINTER_REGNUM
1825 #if HARD_FRAME_POINTER_REGNUM == ARG_POINTER_REGNUM
1826 &&GR_ARG_POINTER = GR_HARD_FRAME_POINTER,
1827 #else
1828 &&GR_ARG_POINTER,
1829 #endif
1830 #endif
1831 &&GR_VIRTUAL_INCOMING_ARGS,
1832 &&GR_VIRTUAL_STACK_ARGS,
1833 &&GR_VIRTUAL_STACK_DYNAMIC,
1834 &&GR_VIRTUAL_OUTGOING_ARGS,
1835 &&GR_VIRTUAL_CFA,
1837 &&GR_MAX
gen_rtx用于创建,除了赋予了寄存器号码的寄存器以外,普通rtx对象。在创建pc_rtx及cc0_rtx对象时,执行了下面部分的代码。
674& gen_rtx (enum rtx_code code, enum machine_mode mode, ...) &&&&&&&&&&&&&&&&&&&&&&&&&&& in emit-rtl.c
676& & &&&&&&&&& /* Array indices...&& */
677& & const char * /* Current rtx's format...&&&&&& */
678& & rtx rt_&&&&&&&&& /* RTX to return to caller...&& */
679& & va_
681& & va_start (p, mode);
683& & switch (code)
706& &&& default:
707& &&&&& rt_val = rtx_alloc (code);& &&&&& /* Allocate the storage space.& */
708& &&&&& rt_val-&mode =&&&&&&&&&&&& /* Store the machine mode...& */
710& &&&&& fmt = GET_RTX_FORMAT (code);& /* Find the right format...& */
711&& &&&&& for (i = 0; i & GET_RTX_LENGTH (code); i++)
712& & &&&& {
750& &&&& &}
751& &&& }
752& &&& break;
755& & va_end (p);
756& & return rt_
上面在707行,所创建的rtx对象由GCC的垃圾收集器管理。每个rtx对象根据其大小来分配。这个大小尺寸记录着rtx_size中,这也是个全局数组,具有如下定义。
101&&& const unsigned char rtx_size[NUM_RTX_CODE] = {&&&&&&&&&&&&&&&&&&&&&&&&&& &&&&&&&&&&&&& in rtl.c
102&&& #define DEF_RTL_EXPR(ENUM, NAME, FORMAT, CLASS)&&&&&&&&&&&&&&&&&&&&&&&&&& /
103&&& & ((ENUM) == CONST_INT || (ENUM) == CONST_DOUBLE&&&&&&&&&&&&&&&&& /
104&&& && ? RTX_HDR_SIZE + (sizeof FORMAT - 1) * sizeof (HOST_WIDE_INT)&&&&&& /
105&&& && : RTX_HDR_SIZE + (sizeof FORMAT - 1) * sizeof (rtunion)),
107&&& #include "rtl.def"
108&&& #undef DEF_RTL_EXPR
rtl.def的内容是表达式,其具有形式:rtx编码,名字字符串,以字符串形式定义的格式,以字符串形式定义的类别。因而PC和CC0具有以下的rtx形式。注意到两者的格式均是空字符串,而rtx_length都是0。
803& /* program counter. Ordinary jumps are represented&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&& in rtl.def
804&&& & by a SET whose first operand is (PC).& */
805&&& DEF_RTL_EXPR(PC, "pc", "", 'o')
873&&& /* The condition code register is represented, in our imagination,
874&&& & as a register holding a value that can be compared to zero.
875&&& & In fact, the machine has already compared them and recorded the
but instructions that look at the condition code
877&&& & pretend to be looking at the entire value and comparing it.& */
878&&& DEF_RTL_EXPR(CC0, "cc0", "", 'o')
在104及105行rtx_size的定义中,RTX_HDR_SIZE被定义为从rtx_def的开头到其u域的偏移。
225&&& #define RTX_HDR_SIZE offsetof (struct rtx_def, u) &&&& &&&&&&&&&&&&& &&&&&&&&&&&&&&&&&&&& in rtl.h
对于PC及CC0对象,它们只有RTX_HDR_SIZE大小,因为(sizeof FORMAT & 1)是0。在gen_rtx中的710及711行,宏形如GET_RTX_...被用于获取rtl定义中相应的域。
56&&& #define GET_RTX_LENGTH(CODE)&&&&&&&& (rtx_length[(int) (CODE)]) &&&&&&&&&&&&&&& in rtl.h
62&&& #define GET_RTX_FORMAT(CODE)&&&&&&&& (rtx_format[(int) (CODE)])
rtx_format及rtx_length也均是全局数组。它们的定义来自rtl.def。
57&&& const char * const rtx_format[NUM_RTX_CODE] = {&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&& in rtl.c
58&&& & /* "*" undefined.
59&&& &&&&&&&& can cause a warning message
60&&& &&& "0" field is unused (or used in a phase-dependent manner)
61&&& &&&& &&&&prints nothing
62&&& &&& "i" an integer
63&&& &&&&&&&& prints the integer
64&&& &&& "n" like "i", but prints entries from `note_insn_name'
65&&& &&& "w" an integer of width HOST_BITS_PER_WIDE_INT
66&&& &&&&&&&& prints the integer
67&&& &&& "s" a pointer to a string
68&&& &&&&&&&&prints the string
69&&& &&& "S" like "s", but optional:
70&&& &&&&&&& &the containing rtx may end before this operand
71&&& &&& "T" like "s", but treated specially by the RTL
72&&& &&&&&&&& only found in machine description patterns.
73&&& &&& "e" a pointer to an rtl expression
74&&& &&&&&&&& prints the expression
75&&& &&& "E" a pointer to a vector that points to a number of rtl expressions
76&&& &&&&&&&& prints a list of the rtl expressions
77&&& &&& "V" like "E", but optional:
78&&& &&&&&&& &the containing rtx may end before this operand
79&&& &&& "u" a pointer to another insn
80&&& &&&&&&&& prints the uid of the insn.
81&&& &&& "b" is a pointer to a bitmap header.
82&&& &&& "B" is a basic block pointer.
83&&& &&& "t" is a tree pointer.& */
85&&& #define DEF_RTL_EXPR(ENUM, NAME, FORMAT, CLASS)&& FORMAT ,
86&&& #include "rtl.def"&&&&&&&&& /* rtl expressions are defined here */
87&&& #undef DEF_RTL_EXPR
35&&& #define DEF_RTL_EXPR(ENUM, NAME, FORMAT, CLASS) sizeof FORMAT - 1 ,
37&&& const unsigned char rtx_length[NUM_RTX_CODE] = {
38&&& #include "rtl.def"
而在gcc的源代码中,rtx对象由下面的struct rtx_def来代表。
139& struct rtx_def GTY((chain_next ("RTX_NEXT (&%h)"),&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&& in rtl.h
140& &&&&&& &&& chain_prev ("RTX_PREV (&%h)")))
142& & /* The kind of expression this is.& */
143& & ENUM_BITFIELD(rtx_code) code: 16;
145& & /* The kind of value the expression has.& */
146& & ENUM_BITFIELD(machine_mode) mode : 8;
148& & /* 1 in a MEM if we should keep the alias set for this mem unchanged
149& &&& when we access a component.
150& &&& 1 in a CALL_INSN if it is a sibling call.
151& &&& 1 in a SET that is for a return.
152& &&& In a CODE_LABEL, part of the two-bit alternate entry field.& */
153& & unsigned int jump : 1;
154& &/* In a CODE_LABEL, part of the two-bit alternate entry field.
155& &&& 1 in a MEM if it cannot trap.& */
156& & unsigned int call : 1;
157& &/* 1 in a REG, MEM, or CONCAT if the value is set at most once, anywhere.
158& &&& 1 in a SUBREG if it references an unsigned object whose mode has been
159& &&& from a promoted to a wider mode.
160& &&&1 in a SYMBOL_REF if it addresses something in the per-function
161& &&& constants pool.
162& &&& 1 in a CALL_INSN, NOTE, or EXPR_LIST for a const or pure call.
163& &&& 1 in a JUMP_INSN, CALL_INSN, or INSN of an annulling branch.& */
164& & unsigned int unchanging : 1;
165& & /* 1 in a MEM or ASM_OPERANDS expression if the memory reference is volatile.
166& &&& 1 in an INSN, CALL_INSN, JUMP_INSN, CODE_LABEL, BARRIER, or NOTE
167& &&& if it has been deleted.
168& &&& 1 in a REG expression if corresponds to a variable declared by the user,
169& &&& 0 for an internally generated temporary.
170& &&& 1 in a SUBREG with a negative value.
171& &&& 1 in a LABEL_REF or in a REG_LABEL note for a non-local label.
172& &&& In a SYMBOL_REF, this flag is used for machine-specific purposes.& */
173& & unsigned int volatil : 1;
174& & /* 1 in a MEM referring to a field of an aggregate.
175& &&& 0 if the MEM was a variable or the result of a * operator in C;
176& &&& 1 if it was the result of a . or -& operator (on a struct) in C.
177& & &&1 in a REG if the register is used only in exit code a loop.
178& &&& 1 in a SUBREG expression if was generated from a variable with a
179& &&& promoted mode.
180& &&& 1 in a CODE_LABEL if the label is used for nonlocal gotos
181& &&& and must not be deleted even if its count is zero.
182& &&& 1 in a LABEL_REF if this is a reference to a label outside the
183& &&& current loop.
184& &&& 1 in an INSN, JUMP_INSN or CALL_INSN if this insn must be scheduled
185& &&& together with the preceding insn. Valid only within sched.
186& &&& 1 in an INSN, JUMP_INSN, or CALL_INSN if insn is in a delay slot and
187& &&& from the target of a branch. Valid from reorg unti
188& &&& cleared before used.
189& &&& 1 in an INSN, JUMP_INSN or CALL_INSN or related rtx if this insn is
190& &&& dead code. Valid only during dead-co cleared
191& &&& before use.& */
192& & unsigned int in_struct : 1;
193& & /* At the end of RTL generation, 1 if this rtx is used. This is used for
194& &&& copying shared structure. See `unshare_all_rtl'.
195& &&& In a REG, this is not needed for that purpose, and used instead
196& &&& in `leaf_renumber_regs_insn'.
197& &&& 1 in a SYMBOL_REF, means that emit_library_call
198& &&& has used it as the function.& */
199& & unsigned int used : 1;
200& &/* Nonzero if this rtx came from procedure integration.
201& &&& 1 in a REG or PARALLEL means this rtx refers to the return value
202& &&& of the current function.
203& &&& 1 in a SYMBOL_REF if the symbol is weak.& */
204& & unsigned integrated : 1;
205& &/* 1 in an INSN or a SET if this rtx is related to the call frame,
206& &&& either changing how we compute the frame address or saving and
207& &&& restoring registers in the prologue and epilogue.
208& &&& 1 in a MEM if the MEM refers to a scalar, rather than a member of
209& &&& an aggregate.
210& &&& 1 in a REG if the register is a pointer.
211&& &&& 1 in a SYMBOL_REF if it addresses something in the per-function
212& &&& constant string pool.& */
213& & unsigned frame_related : 1;
215& & /* The first element of the operands of this rtx.
216& &&& The number of operands and their types are controlled
217& &&& by the `code' field, according to rtl.def.& */
218& & union u {
219& &&& rtunion fld[1];
220& &&& HOST_WIDE_INT hwint[1];
221& & } GTY ((special ("rtx_def"), desc ("GET_CODE (&%0)")))
在上面的定义中,ENUM_BITFIELD在当前版本里被定义为enum。域union u持有rtl表达式的成员。对于真实的rtx表达式,这个域是一个数组。数组中的每个元素保存表达式的一个子部分。
例如,表达式2+3+5,当转换为rtx语言时,它以中序的形式:+ (2) + (3) (5)出现。对于这个rtx表达式,它应是:
图1:rtx表达式例子
显然,rtunion必须是另一个union类型。它需要保存为目标平台产生代码所需的所有信息。
119&& union rtunion_def&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&& in rtl.h
123& & const char *
126& & enum machine_
127& & addr_diff_vec_flags rt_addr_diff_vec_
128& & struct cselib_val_struct *rt_
129& & struct bitmap_head_def *
131& & struct basic_block_def *
132& & mem_attrs *
133& & reg_attrs *
135& typedef union rtunion_
其中,tinit用于整数的RTX表达式,rtuint用于无符号整数,rtstr用于字符串对象,rtx用于表达式(对于上面的图,rtx_expression,cont_int_RTX都保存在rtx的域rtunion中),rtvec则用于数组对象,rttype用于数据类型的机器模式,addr_diff_vec_flags保存用于优化分支块的信息,bb保存了基本块(一个入口,一个出口)的信息,rtmem和rtreg分别保存了内存和寄存器的属性,rttree指向对应的前端子树。
在接下来的init_emit_once 中,从5502到5517行,其他global_rtl中的对象由gen_raw_REG创建,这包括了指定寄存器编号的寄存器对象。
378& gen_raw_REG (enum machine_mode mode, int regno)&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&& in emit-rtl.c
380& & rtx x = gen_rtx_raw_REG (mode, regno);
381& & ORIGINAL_REGNO (x) =
382& & return
gen_rtx_raw_REG由工具gengenrtl根据rtl.def文件产生。通过这种方式,可以相当容易地扩展RTL语言,而不需要重新源文件,除了rtl.def。即便当需要对RTX语言进行大的改动,我们所需要做的只是重写gengenrtl.c和rtl.def。这是个聪明的设计。gen_rtx_raw_REG 是gen_rtx_fmt_i00的别名。
245& #define gen_rtx_raw_REG(MODE, ARG0) /&&&&& &&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&& in genrtl.h
246& && gen_rtx_fmt_i00 (REG, (MODE), (ARG0))
gen_rtx_fmt_i00的名字透露了如下的信息:i表示rtx-&u.fld第一个元素的类型是int,旁边的0表示rtx-&u.fld中接下来的元素没有被使用。这些字符的含义与 rtx_format相同。rtx-&u.fld的大小是3。
631& gen_rtx_fmt_i00 (RTX_CODE code, enum machine_mode mode, &&&&&&&&&&&&&&&& in genrtl.c
632& &&&&&&&&&&&&&&int arg0)
634& & rtx
635& & rt = ggc_alloc_rtx (code);
637& & memset (rt, 0, RTX_HDR_SIZE);
639& & PUT_CODE (rt, code);
640& & PUT_MODE (rt, mode);
641& & XINT (rt, 0) = arg0;
642& & X0EXP (rt, 1) = NULL_RTX;
643& & X0EXP (rt, 2) = NULL_RTX;
645& & return
GCC定义了一系列的宏首先检查RTX对象的合法性,然后获取指定的域。在调用处,可以看到arg0是寄存器号码。而XINT是这些宏的其中之一。
506& #define XINT(RTX, N) (RTL_CHECK2 (RTX, N, 'i', 'n').rtint) &&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&& in rtl.h
RTL_CHECK2类似于RTL_CHECK1,除了需要验证给定的2个格式。
对于X0EXP,其名字中的0代表应用了rtx_format中0,0的含义是未使用(或用于阶段相关的方式),EXP表明rtx的内容是rtx表达式。
525& #define X0EXP(RTX, N)&&&&& && (RTL_CHECK1 (RTX, N, '0').rtx) &&&&&&&&&&&&&& &&&&&& in rtl.h
如果定义了ENABLE_RTL_CHECKING,RTL_CHECK1将进行合法性验证。这在GCC开发阶段很有意义。而在发布时,取消ENABLE_RTL_CHECKING的定义,RTL_CHECK1将只是RTX-&u.fld[N],大大加快了执行速度。
302& #if defined ENABLE_RTL_CHECKING && (GCC_VERSION &= 2007) &&&&&&&&&&& in rtl.h
303& /* The bit with a star outside the statement expr and an & inside is
304& & so that N can be evaluated only once.& */
305& #define RTL_CHECK1(RTX, N, C1) __extension__&&&&&&&&&&&&&&&&&&&&&&& /
306& (*({ rtx const _rtx = (RTX); const int _n = (N);&&&&&&&&&&&&&&&&&&&& /
307& &&&& const enum rtx_code _code = GET_CODE (_rtx);&&&&&&&&&&&&&&&&& /
308& &&&& if (_n & 0 || _n &= GET_RTX_LENGTH (_code))&&&&&&&&&&&&&&&&&& /
309& &&&&&& rtl_check_failed_bounds (_rtx, _n, __FILE__, __LINE__,&&&&&&&&& /
310& & &&&&&&&&&&& &&&&&&&&&&&&&&&__FUNCTION__);&&&&&&&&&&&&&&&&&&&&& /
311&& &&&& if (GET_RTX_FORMAT(_code)[_n] != C1)&&&&&&&&&&&&&&&&&&&&&&&&&& /
312& &&&&&& rtl_check_failed_type1 (_rtx, _n, C1, __FILE__, __LINE__,&&&&& /
313& & &&&&&&&&&&&&&&&&&&&& &&&&&__FUNCTION__);&&&&&&&&&&&&&&&&&&&&&& /
314& && &_rtx-&u.fld[_n]; }))
当gen_rtx_raw_REG返回时,gen_raw_REG用寄存器号码重写rtunion的第二个元素,这个元素保存寄存器原始的号码。对于一个变成物理寄存器的伪寄存器,这将是伪寄存器的原始号码。
1019 #define ORIGINAL_REGNO(RTX) X0UINT (RTX, 1)&&&&&&&&&&&&&&&&&&&&&&&&& &&&&&& &&&&&& in rtl.h
1020 #define X0UINT(RTX, N)&&& && (RTL_CHECK1 (RTX, N, '0').rtuint)
然后在init_emit_once的5522行,开始创建通用寄存器的rtx对象。reg_raw_mode记录了特定寄存器所能支持的最大机器模式,该数据在init_reg_modes_once中设置。
在5529行,对于除ia64以外的x86机器,INIT_EXPANDERS没有定义。
init_emit_once (continue)
5532 &&/* Create the unique rtx's for certain rtx codes and operand values.& */
5534 &&/* Don't use gen_rtx here since gen_rtx in this case
5535 &&&&tries to use these variables.& */
5536 &&for (i = - MAX_SAVED_CONST_INT; i &= MAX_SAVED_CONST_INT; i++)
5537 &&&&const_int_rtx[i + MAX_SAVED_CONST_INT] =
5538 &&&&&&gen_rtx_raw_CONST_INT (VOIDmode, (HOST_WIDE_INT) i);
5540 &&if (STORE_FLAG_VALUE &= - MAX_SAVED_CONST_INT
5541 &&&&&&&& STORE_FLAG_VALUE &= MAX_SAVED_CONST_INT)
5542 &&&&const_true_rtx = const_int_rtx[STORE_FLAG_VALUE + MAX_SAVED_CONST_INT];
5543 &&else
5544 &&&&const_true_rtx = gen_rtx_CONST_INT (VOIDmode, STORE_FLAG_VALUE);
在5537行,const_int_rtx保存了(const_int C)的一份拷贝,C的取值在[-64, 64]。这将为整数的比较及计算节省空间。MAX_SAVED_CONST_INT被定义为64。这些常量的rtx对象由gen_rtx_raw_CONST_INT创建。
233& #define gen_rtx_raw_CONST_INT(MODE, ARG0) /&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&& in genrtl.h
234& & gen_rtx_fmt_w (CONST_INT, (MODE), (ARG0))
函数gen_rtx_fmt_w亦是由工具gengenrtl根据rtl.def生成。同样,它的名字泄露了它的内涵。字母w表示所处理rtx表达式的内容是宽整数,因此这次使用的是rtx-&u.wint。而且rtx-&u.wint也是一个数组。
600& gen_rtx_fmt_w (RTX_CODE code, enum machine_mode mode,&&&&&&&&&&&&&&&&&&&& in genrtl.c
601& &&&&&&& HOST_WIDE_INT arg0)
604& & rt = ggc_alloc_rtx (code);
606& & memset (rt, 0, RTX_HDR_SIZE);
608& & PUT_CODE (rt, code);
609& & PUT_MODE (rt, mode);
610& & XWINT (rt, 0) = arg0;
612& & return
350& #define XWINT(RTX, N) __extension__&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&& /&&&&&&&&&&&&&&&&&&& in rtl.h
351& (*({ rtx const _rtx = (RTX); const int _n = (N);&&&&&&&&&&&&&&&&&&&& /
352& &&&& const enum rtx_code _code = GET_CODE (_rtx);&&&&&&&&&&&&&&&&& /
353& &&&& if (_n & 0 || _n &= GET_RTX_LENGTH (_code))&&&&&&&&&&&&&&&&&& /
354& &&&&&& rtl_check_failed_bounds (_rtx, _n, __FILE__, __LINE__,&&&&&&&&& /
355& & &&&&&&&&&&&&&&&&&&&&&&&&&& __FUNCTION__);&&&&&&&&&&&&&&&&&&&&& /
356& &&&& if (GET_RTX_FORMAT(_code)[_n] != 'w')&&&&& &&&&&&&&&&&&&&&&&&&& /
357& &&&&&& rtl_check_failed_type1 (_rtx, _n, 'w', __FILE__, __LINE__,&&&&&& /
358& &&&&&&&&&&&&& && &&&&&&&&&&&&&&&&__FUNCTION__);&&&&&&&&&&&&&&&&&&&&&&& /
359& &&&&&& &_rtx-&u.hwint[_n]; }))
在上面的init_emit_once的5540行,对于x86系统,STORE_FLAG_VALUE被定义为1。因此const_true_rtx只是const_int_rtx [65]的别名。
文章评论 以下网友留言只代表其个人观点,不代表本网站的观点和立场。}

我要回帖

更多关于 读书心得怎么写 的文章

更多推荐

版权声明:文章内容来源于网络,版权归原作者所有,如有侵权请点击这里与我们联系,我们将及时删除。

点击添加站长微信