17. gencheck工具
程序经由前端处理后,被转换为rtl形式。在这个中间形式的程序被构建为一棵树。可以想象在树中的节点是多种多样并且复杂的,为了使节点的构建更容易,也更好控制。在tree.def及C-common.def(专门对应c及c++)中,以类似rtl.def描述rtx对象那样,描述的节点
用于描述节点的指令有如下形式。
DEFTREECODE(SYM, NAME, TYPE, LENGTH)
例如在tree.def中,我们可以看到如下代码。
DEFTREECODE (IDENTIFIER_NODE, "identifier_node",'x', 0)
在gencheck.c里,我们可以看到这样的代码片段。
27 #define DEFTREECODE(SYM, NAME, TYPE, LEN) #SYM, ingencheck.c
28
29 static const char *consttree_codes[] = {
30 #include "tree.def"
31 #include "c-common.def"
32 #include "gencheck.h"
33 (char*) 0
34 };
在上面32行,gencheck.h将被被Makefile产生,它将根据目标语言包括合适的def文件。
44 int
45 main (int argc, char **argvATTRIBUTE_UNUSED) in gencheck.c
46 {
47 int i, j;
48
49 switch (argc)
50 {
51 case 1:
52 break;
53
54 default:
55 usage ();
56 return (1);
57 }
58
59 puts ("/* This file is generated using gencheck. Do not edit.*/\n");
60 puts ("#ifndef GCC_TREE_CHECK_H");
61 puts ("#define GCC_TREE_CHECK_H\n");
62
63 /* Print macros for checks based on each ofthe tree code names. However,
64 since we include the tree nodes from alllanguages, we must check
65 for duplicate names to avoid defining thesame macro twice. */
66 for(i = 0; tree_codes[i];i++)
67 {
68 for(j = 0; j < i; j++)
69 if (strcmp (tree_codes[i], tree_codes[j]) == 0)
70 break;
71
72 if (i == j)
73 printf ("#define %s_CHECK(t)\tTREE_CHECK (t, %s)\n",
74 tree_codes[i], tree_codes[i]);
75 }
76
77 puts ("\n#endif /* GCC_TREE_CHECK_H */");
78 return 0;
79 }
那么对于IDENTIFIER_NODE而言,以下代码将被输出到tree-check.h。
#define IDENTIFIER_NODE_CHECK(t) TREE_CHECK (t, IDENTIFIER_NODE)
18. genconstants工具
这个工具将输出insn-constants.h,它定义了机器描述文件所使用的常量。
52 int
53 main (int argc, char **argv) ingenconstants.c
54 {
55 int dummy1, dummy2;
56 rtx desc;
57
58 progname= "genconstants";
59
60 if (argc <= 1)
61 fatal ("no input file name");
62
63 if (init_md_reader (argv[1]) != SUCCESS_EXIT_CODE)
64 return (FATAL_EXIT_CODE);
65
66 /* Scan and discard the entire file. This hasthe side effect
67 of loading up the constants table that wewish to scan. */
68 do
69 desc = read_md_rtx (&dummy1,&dummy2);
70 while (desc);
71
72 puts ("/* Generated automatically by the program`genconstants'");
73 puts (" from the machinedescription file `md'. */\n");
74 puts ("#ifndefGCC_INSN_CONSTANTS_H");
75 puts ("#defineGCC_INSN_CONSTANTS_H\n");
76
77 traverse_md_constants (print_md_constant, stdout);
78
79 puts ("\n#endif /*GCC_INSN_CONSTANTS_H */");
80
81 if (ferror (stdout) || fflush(stdout) || fclose (stdout))
82 return FATAL_EXIT_CODE;
83
84 return SUCCESS_EXIT_CODE;
85 }
477 void
478 traverse_md_constants (htab_trav callback, void *info) inread-rtl.c
479 {
480 if (md_constants)
481 htab_traverse (md_constants, callback, info);
482 }
在i386.md中,使用了define_constants来定义用到的常量。上面的md_constants 记录了read_constants读入的常量。