GCC's bacl-end & assemble emission (1)
来源:互联网 发布:sybase数据库离线语句 编辑:程序博客网 时间:2024/06/09 18:20
1. Overview
To make GCC porting to other machines (architecture) in mostefficient and convient way, GCC needs machine description file (MD file) forchips. To describe a chip, series definitions called pattern are introduced.Generally, we need describe the chip from two ways.
First is the instruction set defined in form of rtl– there includewhat is the instructions look alike (define_insn pattern), which instructionssequence is more efficient than other equivalent ones (define_peephole anddefine_peephole2), how to split a complex instruction into simpler ones thenone of them can be replaced into delay slot or fill pipeline (define_split anddefine_insn_split, for delay slot and pipeline fill in consideration refer to Tool of genattrtab), how to split a complexinstruction into simpler ones then define_insn patterns can be matched(define_expand).
The second is the architecture description; we know different chipsof the same series may still have different function units, different pipelinestructure. To exploit chips ability as possible, we need tell the compilerabout the detail. The description is also defined in rtl language.
So these two forms of description are largely human readable, toconvert the descriptions into a form that can be included into the source codeof GCC, the developer design a series tools for the purpose. These tools are soimportant, without them backend can do nothing. They not only provide the majorwork of assembly generation, but also offer the basic for optimization executedat level close to machine (for release V4, a layer named SSA is introudced toenhence the ability of the compiler to do more optimization at level closer tosource code. By machine description file, release V3 can provide very powerfuloptimization at lower level, however at this lower level form, manyinformations that can help to dependence analysis, such as type and alias, arestripped. It keeps compiler away from taking opportunites of optimization).
In following, we will study most of the tools for handling themachine description file to undertsand how the backend is constructed. Atcompiling GCC, these tools will be first compiled, and then they will be run toparse the description file of target machine to generate the source code.Following, it comes to compile GCC’s source (such that for the front-end wehave seen), tegother with the code emitted here, to build the compiler.
2. Toolof genconditions
2.1.Preparation for Code Emission
Before study genrecog tool, we need first study tool genconditions,as it will produce the file insn-conditions.c which will be used by genrecog.
182 int
183 main (int argc, char **argv) ingenconditions.c
184 {
185 rtx desc;
186 int pattern_lineno; /* not used */
187 int code;
188
189 progname= "genconditions";
190
191 if (argc <= 1)
192 fatal ("No input file name.");
193
194 if (init_md_reader (argv[1]) !=SUCCESS_EXIT_CODE)
195 return (FATAL_EXIT_CODE);
196
197 condition_table= htab_create (1000, hash_c_test, cmp_c_test, NULL);
2.1.1. Read in definitions in rtx
Note, condition_tablebelow and condition_tableabove are two different static variables, which are declared in genconditions.cand gensupport.c respectively. init_md_reader willread in rtx objects from machine description file, which is a common functioninvoked by other tools too.
935 int
936 init_md_reader (const char *filename) in gensupport.c
937 {
938 FILE *input_file;
939 int c;
940 size_t i;
941 char *lastsl;
942
943 lastsl = strrchr (filename, '/');
944 if (lastsl != NULL)
945 base_dir= save_string (filename, lastsl - filename + 1 );
946
947 read_rtx_filename= filename;
948 input_file = fopen (filename, "r");
949 if (input_file == 0)
950 {
951 perror (filename);
952 return FATAL_EXIT_CODE;
953 }
954
955 /* Initialize the table of insnconditions. */
956 condition_table= htab_create (n_insn_conditions,
957 hash_c_test, cmp_c_test, NULL);
958
959 for (i = 0; i < n_insn_conditions; i++)
960 *(htab_find_slot (condition_table, &insn_conditions[i], INSERT))
961 = (void *) &insn_conditions[i];
962 obstack_init (rtl_obstack);
963 errors= 0;
964 sequence_num= 0;
965
966 /* Read the entire file. */
967 while (1)
968 {
969 rtx desc;
970 int lineno;
971
972 c = read_skip_spaces (input_file);
973 if (c == EOF)
974 break;
975
976 ungetc (c, input_file);
977 lineno =read_rtx_lineno;
978 desc = read_rtx (input_file);
979 process_rtx (desc, lineno);
980 }
981 fclose (input_file);
982
983 /* Process define_cond_exec patterns. */
984 if (define_cond_exec_queue!= NULL)
985 process_define_cond_exec ();
986
987 return errors ? FATAL_EXIT_CODE :SUCCESS_EXIT_CODE;
988 }
read_skip_spaces skips white space and comment, and fetches the first validcharacter.
102 int
103 read_skip_spaces(FILE *infile) in read-rtl.c
104 {
105 int c;
106
107 while (1)
108 {
109 c = getc (infile);
110 switch (c)
111 {
112 case '/n':
113 read_rtx_lineno++;
114 break;
115
116 case ' ': case'/t': case '/f': case'/r':
117 break;
118
119 case ';':
120 do
121 c =getc (infile);
122 while(c != '/n' && c != EOF);
123 read_rtx_lineno++;
124 break;
125
126 case '/':
127 {
128 int prevc;
129 c =getc (infile);
130 if (c != '*')
131 fatal_expected_char (infile,'*', c);
132
133 prevc = 0;
134 while((c = getc (infile)) && c != EOF)
135 {
136 if (c == '/n')
137 read_rtx_lineno++;
138 else if (prevc == '*'&& c == '/')
139 break;
140 prevc = c;
141 }
142 }
143 break;
144
145 default:
146 return c;
147 }
148 }
149 }
For md file, “;” at the beginning of the line indicates the wholeline is comment. At the same time, “/*” and “*/” pair serve as comment too.Then read_rtxwith the help of read_skip_spaces constructs rtx object fromrtx definition in machine description file.
509 rtx
510 read_rtx (FILE*infile) in read-rtl.c
511 {
512 int i, j;
513 RTX_CODE tmp_code;
514 const char *format_ptr;
515 /* tmp_char is a buffer used for readingdecimal integers
516 and names of rtx types and machine modes.
517 Therefore, 256 must be enough. */
518 char tmp_char[256];
519 rtx return_rtx;
520 int c;
521 int tmp_int;
522 HOST_WIDE_INT tmp_wide;
523
524 /* Obstack used for allocating RTLobjects. */
525 static structobstackrtl_obstack;
526 static int initialized;
527
528 /* Linked list structure for making RTXs: */
529 struct rtx_list
530 {
531 struct rtx_list *next;
532 rtx value; /* Value of this node. */
533 };
534
535 if (!initialized){
536 obstack_init (&rtl_obstack);
537 initialized= 1;
538 }
539
540 again:
541 c = read_skip_spaces (infile); /* Should be open paren. */
542 if (c != '(')
543 fatal_expected_char (infile, '(', c);
544
545 read_name (tmp_char, infile);
546
547 tmp_code = UNKNOWN;
548
549 if (! strcmp (tmp_char, "define_constants"))
550 {
551 read_constants(infile, tmp_char);
552 goto again;
553 }
554 for (i = 0; i< NUM_RTX_CODE; i++)
555 if (! strcmp(tmp_char, GET_RTX_NAME (i)))
556 {
557 tmp_code = (RTX_CODE) i; /* get value for name */
558 break;
559 }
560
561 if (tmp_code == UNKNOWN)
562 fatal_with_file_and_line (infile, "unknown rtx code `%s'",tmp_char);
563
564 /* (NIL) stands for an expression that isn'tthere. */
565 if (tmp_code == NIL)
566 {
567 /*Discard the closeparen. */
568 while ((c = getc (infile)) && c!= ')')
569 ;
570
571 return 0;
572 }
573
574 /* If we end up with an insn expression thenwe free this space below. */
575 return_rtx = rtx_alloc (tmp_code);
576 format_ptr = GET_RTX_FORMAT (GET_CODE(return_rtx));
In machine description file, every instruction must be enclosedwithin parentheses pair, line 542 ensures it. Then read_name is invoked to get the name ofthe instruction.
154 static void
155 read_name (char*str, FILE *infile) in read-rtl.c
156 {
157 char *p;
158 int c;
159
160 c = read_skip_spaces (infile);
161
162 p = str;
163 while (1)
164 {
165 if (c == ' ' || c == '/n' || c == '/t' || c == '/f' || c == '/r')
166 break;
167 if (c == ':' || c == ')' || c == ']' || c == '"' || c == '/'
168 || c == '(' || c == '[')
169 {
170 ungetc (c, infile);
171 break;
172 }
173 *p++ = c;
174 c = getc (infile);
175 }
176 if (p == str)
177 fatal_with_file_and_line (infile, "missing name or number");
178 if (c == '/n')
179 read_rtx_lineno++;
180
181 *p = 0;
182
183 if (md_constants)
184 {
185 /* Do constant expansion. */
186 struct md_constant *def;
187
188 p = str;
189 do
190 {
191 structmd_constant tmp_def;
192
193 tmp_def.name = p;
194 def = htab_find (md_constants,&tmp_def);
195 if (def)
196 p = def->value;
197 } while (def);
198 if (p != str)
199 strcpy (str, p);
200 }
201 }
Above, at line 183, md_constants is an instance of hash table (htab),while at line 186 the md_constant is a simple struct having two charpointers members nameand value.
In machine description file, there sometimes defines constants whichwill be used in the instruction definition. These constant definitions areindicated by define_constants.At line 551 above in read_rtx,read_constantsis invoked to handle the definitions.
421 static void
422 read_constants(FILE *infile, char *tmp_char) in read-rtl.c
423 {
424 int c;
425 htab_t defs;
426
427 c = read_skip_spaces (infile);
428 if (c != '[')
429 fatal_expected_char (infile, '[', c);
430 defs = md_constants;
431 if (! defs)
432 defs = htab_create (32, def_hash, def_name_eq_p, (htab_del) 0);
433 /* Disable constant expansion duringdefinition processing. */
434 md_constants= 0;
435 while ( (c = read_skip_spaces(infile)) != ']')
436 {
437 struct md_constant *def;
438 void **entry_ptr;
439
440 if (c != '(')
441 fatal_expected_char (infile, '(', c);
442 def = xmalloc (sizeof (structmd_constant));
443 def->name = tmp_char;
444 read_name (tmp_char, infile);
445 entry_ptr = htab_find_slot (defs, def, TRUE);
446 if (! *entry_ptr)
447 def->name = xstrdup (tmp_char);
448 c = read_skip_spaces (infile);
449 ungetc (c, infile);
450 read_name (tmp_char, infile);
451 if (! *entry_ptr)
452 {
453 def->value = xstrdup(tmp_char);
454 *entry_ptr = def;
455 }
456 else
457 {
458 def = *entry_ptr;
459 if (strcmp (def->value,tmp_char))
460 fatal_with_file_and_line(infile,
461 "redefinition of %s, was %s, now%s",
462 def->name, def->value, tmp_char);
463 }
464 c = read_skip_spaces (infile);
465 if (c != ')')
466 fatal_expected_char (infile, ')', c);
467 }
468 md_constants= defs;
469 c = read_skip_spaces (infile);
470 if (c != ')')
471 fatal_expected_char (infile, ')', c);
472 }
The form of the constant definition is like: (define_constants[(name value)…(name value)]), the pair of name and value will be retrieved andsaved into struct md_constant, which saved into hash table of md_constants.
Other machine description patterns include define_insn, define_attr,define_peephole, define_split, define_expand, define_insn_and_split and etc.They also appear in file rtl.def.They are special rtx object, and for i386 system, we can find following
192 DEF_RTL_EXPR(DEFINE_INSN,"define_insn", "sEsTV", 'x') in rtl.def
In this definition, we know that the first parameter is the rtxcode, the second parameter is the name, the third parameter is the format, inwhich “sEsTV” means the rtx object has at most 5 children, and the lastparameter is the rtx class. Let’s see the meaning the character in format andclass for rtx object has.
For format we can get:
"0" field isunused (or used in a phase-dependent manner), prints nothing
"i" an integer,prints the integer
"n" like"i", but prints entries from `note_insn_name'
"w" an integer ofwidth HOST_BITS_PER_WIDE_INT, prints the integer
"s" a pointer toa string, prints the string
"S" like"s", but optional: the containing rtx may end before this operand
"T" like"s", but treated specially by the RTL reader; only in machinedescription patterns.
"e" a pointer toan rtl expression, prints the expression
"E" a pointer to a vector that points to anumber of rtl expressions, prints a list of the rtl expressions
"V" like"E", but optional: the containing rtx may end before this operand
"u" a pointer toanother insn, prints the uid of the insn.
"b" is a pointerto a bitmap header.
"B" is a basicblock pointer.
"t" is a treepointer.
For class we can get:
"o" an rtx codethat can be used to represent an object (e.g, REG, MEM)
"<"an rtx code for a comparison (e.g, EQ, NE, LT)
"1" an rtx codefor a unary arithmetic expression (e.g, NEG, NOT)
"c" an rtx codefor a commutative binary operation (e.g,, PLUS, MULT)
"3" an rtx codefor a non-bitfield three input operation (IF_THEN_ELSE)
"2" an rtx codefor a non-commutative binary operation (e.g., MINUS, DIV)
"b" an rtx codefor a bit-field operation (ZERO_EXTRACT, SIGN_EXTRACT)
"i" an rtx codefor a machine insn (INSN, JUMP_INSN, CALL_INSN)
"m" an rtx codefor something that matches in insns (e.g, MATCH_DUP)
"g" an rtx codefor grouping insns together (e.g, GROUP_PARALLEL)
"a" an rtx codefor autoincrement addressing modes (e.g. POST_DEC)
"x" everythingelse
And other related instructions’ rtl definitions are:
200 DEF_RTL_EXPR(DEFINE_PEEPHOLE,"define_peephole", "EsTV", 'x')
211 DEF_RTL_EXPR(DEFINE_SPLIT,"define_split", "EsES", 'x')
239 DEF_RTL_EXPR(DEFINE_INSN_AND_SPLIT,"define_insn_and_split", "sEsTsESV", 'x')
243 DEF_RTL_EXPR(DEFINE_PEEPHOLE2,"define_peephole2", "EsES", 'x')
247 DEF_RTL_EXPR(DEFINE_COMBINE, "define_combine","Ess", 'x')
260 DEF_RTL_EXPR(DEFINE_EXPAND,"define_expand", "sEss", 'x')
276 DEF_RTL_EXPR(DEFINE_DELAY, "define_delay", "eE", 'x')
So at line 554 infunction read_rtxabove, other instructions in machinde description file are recognized by name,and the corresponding rtx codes are fetched. At line 565, NIL is used by rtl reader andprinter to represent a null pointer. Those instructions are allocated as rtxobjects. And read_rtxcomes to handle these instructions.
Let’s take an example from i386.md.
467 (define_insn"cmpdi_ccno_1_rex64" ini386.md
468 [(set (reg17)
469 (compare (match_operand:DI 0"nonimmediate_operand" "r,?mr")
470 (match_operand:DI 1"const0_operand" "n,n")))]
471 "TARGET_64BIT &&ix86_match_ccmode (insn, CCNOmode)"
472 "@
473 test{q}/t{%0, %0|%0, %0}
474 cmp{q}/t{%1, %0|%0, %1}"
475 [(set_attr "type""test,icmp")
476 (set_attr "length_immediate""0,1")
477 (set_attr "mode" "DI")])
- GCC's bacl-end & assemble emission (1)
- GCC's bacl-end & assemble emission (2)
- GCC's bacl-end & assemble emission (3)
- GCC's bacl-end & assemble emission (4)
- GCC's bacl-end & assemble emission (5)
- GCC's bacl-end & assemble emission (6)
- GCC's bacl-end & assemble emission (7)
- GCC's bacl-end & assemble emission (8)
- GCC's bacl-end & assemble emission (9)
- GCC's bacl-end & assemble emission (10)
- GCC's bacl-end & assemble emission (11)
- GCC's bacl-end & assemble emission (12)
- GCC's bacl-end & assemble emission (13)
- GCC's bacl-end & assemble emission (14)
- GCC's bacl-end & assemble emission (15)
- GCC's bacl-end & assemble emission (16)
- GCC's bacl-end & assemble emission (17)
- GCC's bacl-end & assemble emission (18)
- 托盘图标不响应消息 已解决
- 三个repeater嵌套
- GRID方式ALV导出数据到本地丢掉最后一位的问题
- GCC后端及汇编发布(1)
- OpenGL ES之GLSurfaceView学习一:介绍
- GCC's bacl-end & assemble emission (1)
- JS获取浏览器信息
- POSIX线程:支持内存共享的简捷工具
- OpenGL ES之GLSurfaceView学习二:非交互式的实例
- 2011考研数学真题凸显教材复习重要性
- 20条非常有用的电脑技术
- 4月份复习计划调整
- vc 2005快捷键&及vc 2005使用技巧
- 【C语言】malloc()和free()函数的讲解以及相关内存泄漏问题