GCC's bacl-end & assemble emission (16)

9.        Tool of genattrtab

9.1. Overview

Above we see tool genattr generates the file insn-attr.h. This file contains the declaration of routines. Now it is time to see where their definitions come from. Here they are output by genattratab. Again we still take the examples in previous section in this section.

Generally, there are 2 kinds of machine description files for target platform. The first one defines the patterns that can recognize input RTL instructions and provide information for outputting assembly for the target platform. This file is shared by machines using the same instruction set. We have seen this in 3. Tool of genrecog and 5. Tool of genoutput .

While the other file is specialized for architecture. Currently, there are two ways to describe the atchitecture, one is via define_function_unit which describes the chip in the position of function units (refer to section 8.1.2 Overview of DEFINE_FUNCTION_UNIT pattern ), and the newer one is by define_insn_reservation which describes the chip in the view from instructions (refer to section 8.1.3 Overview of DEFINE_INSN_RESERVATION pattern ).

Besides these patterns, we need other patterns to provide the details about instructions. For the old way, define_attr, define_insn, define_delay will be found. And for the new way, define_attr, define_insn, define_delay, define_automaton, define_bypass, present_set etc will be present.

9.2. Program Entry

 

5988 int

5989 main (int argc, char **argv)                                                                 in genattrtab.c

5990 {

5991   rtx desc;

5992   struct attr_desc *attr;

5993   struct insn_def *id;

5994   rtx tem;

5995   int i;

5996

5997   progname = "genattrtab";

5998

5999   if (argc <= 1)

6000     fatal ("no input file name");

6001

6002   if (init_md_reader_args (argc, argv) != SUCCESS_EXIT_CODE)

6003     return (FATAL_EXIT_CODE);

6004

6005   obstack_init (hash_obstack );

6006   obstack_init (temp_obstack );

6007

6008   /* Set up true and false rtx's */

6009   true_rtx = rtx_alloc (CONST_INT);

6010   XWINT (true_rtx , 0) = 1;

6011   false_rtx = rtx_alloc (CONST_INT);

6012   XWINT (false_rtx , 0) = 0;

6013   ATTR_IND_SIMPLIFIED_P (true_rtx ) = ATTR_IND_SIMPLIFIED_P (false_rtx ) = 1;

6014   ATTR_PERMANENT_P (true_rtx ) = ATTR_PERMANENT_P (false_rtx ) = 1;

6015

6016   alternative_name = DEF_ATTR_STRING ("alternative");

6017   length_str = DEF_ATTR_STRING ("length");

6018   delay_type_str = DEF_ATTR_STRING ("*delay_type");

6019   delay_1_0_str = DEF_ATTR_STRING ("*delay_1_0");

6020   num_delay_slots_str = DEF_ATTR_STRING ("*num_delay_slots");

6021

6022   printf ("/* Generated automatically by the program `genattrtab'/n/

6023         from the machine description file `md'.  *//n/n");

6024      

6025         /* Read the machine description.  */

6026      

6027         initiate_automaton_gen (argc, argv);

 

We first have a look at the definition of macros used above.

 

98    #define ATTR_IND_SIMPLIFIED_P(RTX) (RTX_FLAG ((RTX), unchanging)) in genattrtab.c

100  #define ATTR_PERMANENT_P(RTX) ( RTX_FLAG ((RTX), integrated))        in genattrtab.c

402  #define RTX_FLAG(RTX, FLAG) ((RTX)->FLAG)                                       in rtl.h

 

For DEF_ATTR_STRING, it refers to function attr_string . This function will save the string into the hash table (attr_hash_table ).

 

382  #define DEF_ATTR_STRING(S) (attr_string ((S), strlen (S)))                      in genattrtab.c

 

778  static char *

779  attr_string (const char *str, int len)                                                       in genattrtab.c

780  {

781    struct attr_hash *h;

782    int hashcode;

783    int i;

784    char *new_str;

785 

786    /* Compute the hash code.  */

787    hashcode = (len + 1) * 613 + (unsigned) str[0];

788    for (i = 1; i <= len; i += 2)

789      hashcode = ((hashcode * 613) + (unsigned) str[i]);

790    if (hashcode < 0)

791      hashcode = -hashcode;

792 

793    /* Search the table for the string.  */

794    for (h = attr_hash_table [hashcode % RTL_HASH_SIZE]; h; h = h->next)

795      if (h->hashcode == -hashcode && h->u.str[0] == str[0]

796          && !strncmp (h->u.str, str, len))

797        return h->u.str;                 /* <-- return if found.  */

798 

799    /* Not found; create a permanent copy and add it to the hash table.  */

800    new_str = obstack_alloc (hash_obstack , len + 1);

801    memcpy (new_str, str, len);

802    new_str[len] = '/0';

803    attr_hash_add_string (hashcode, new_str);

804 

805    return new_str;                 /* Return the new string.  */

806  }

 

At line 794, table attr_hash_table contains elements of type attr_hash which has following definition.

 

493  struct attr_hash                                                                                    in genattrtab.c

494  {

495    struct attr_hash *next;       /* Next structure in the bucket.  */

496    int hashcode;                    /* Hash code of this rtx or string.  */

497    union

498    {

499      char *str;        /* The string (negative hash codes) */

500      rtx rtl;                   /* or the RTL recorded here.  */

501    } u;

502  };

9.3. Preparation

As usual way, the tool needs to read in the machine description file and build data for them.

 

9634 void

9635 initiate_automaton_gen (int argc, char **argv)                                      in genattrtab.c

9636 {

9637   const char *base_name;

9638   int i;

9639

9640   ndfa_flag = 0;

9641   split_argument = 0;   /* default value */

9642   no_minimization_flag = 0;

9643   time_flag = 0;

9644   v_flag = 0;

9645   w_flag = 0;

9646   progress_flag = 0;

9647   for (i = 2; i < argc; i++)

9648     if (strcmp (argv [i], NO_MINIMIZATION_OPTION) == 0)

9649       no_minimization_flag = 1;

9650     else if (strcmp (argv [i], TIME_OPTION) == 0)

9651       time_flag = 1;

9652     else if (strcmp (argv [i], V_OPTION) == 0)

9653       v_flag = 1;

9654     else if (strcmp (argv [i], W_OPTION) == 0)

9655       w_flag = 1;

9656     else if (strcmp (argv [i], NDFA_OPTION) == 0)

9657       ndfa_flag = 1;

9658     else if (strcmp (argv [i], PROGRESS_OPTION) == 0)

9659       progress_flag = 1;

9660     else if (strcmp (argv [i], "-split") == 0)

9661     {

9662       if (i + 1 >= argc)

9663         fatal ("-split has no argument.");

9664       fatal ("option `-split' has not been implemented yet/n");

9665       /* split_argument = atoi (argument_vect [i + 1]); */

9666     }

9667   VLA_PTR_CREATE (decls , 150, "decls");

9668   /* Initialize IR storage.  */

9669   obstack_init (&irp );

9670   initiate_automaton_decl_table ();

9671   initiate_insn_decl_table ();

9672   initiate_decl_table ();

9673   output_file = stdout;

9674   output_description_file = NULL;

9675   base_name = base_file_name (argv[1]);

9676   obstack_grow (&irp , base_name,

9677       strlen (base_name) - strlen (file_name_suffix (base_name)));

9678   obstack_grow (&irp , STANDARD_OUTPUT_DESCRIPTION_FILE_SUFFIX,

9679       strlen (STANDARD_OUTPUT_DESCRIPTION_FILE_SUFFIX) + 1);

9680   obstack_1grow (&irp , '/0');

9681   output_description_file_name = obstack_base (&irp );

9682   obstack_finish (&irp );

9683 }

9.3.1. Variable Length Array Pointer

In this tool, a facility called variable length array pointer is used. At line 9667 above, is an example.

 

547  #define VLA_PTR_CREATE(vla, allocated_length, name)  /                  in genautomata.c

548    do                                                                /

549    {  /

550      vla_ptr_t *const _vla_ptr = &(vla);                                /

551         /

552      VARRAY_GENERIC_PTR_INIT (_vla_ptr->varray, allocated_length, name);/

553      _vla_ptr->length = 0;                                              /

554    }                                                          /

555    while (0)

 

The variable length array pointer has following definitions:

 

138  typedef struct {                                                                                  in genautomata.c

139    size_t length;       /* current size of vla.  */

140    varray_type varray; /* container for vla.  */

141  } vla_ptr_t;

 

132  struct varray_head_tag GTY(()) {                                                                in varray.h

133    size_t    num_elements;  /* Maximum element number allocated.  */

134    size_t     elements_used;  /* The number of elements used, if

135                              using VARRAY_PUSH/VARRAY_POP.  */

136    enum varray_data_enum type;   /* The kind of elements in the varray.   */

137    const char   *name;         /* name of the varray for reporting errors */

138    varray_data   GTY ((desc ("%0.type"))) data;  /* The data elements follow,

139                                              must be last.  */

140  };

141  typedef struct varray_head_tag *varray_type;

 

varray_data_enum tells what kinds of data vla can hold. Its value can map to the member of varray_data one by one.

 

63    enum varray_data_enum {                                                                           in varray .h

64      VARRAY_DATA_C,

65      VARRAY_DATA_UC,

66      VARRAY_DATA_S,

67      VARRAY_DATA_US,

68      VARRAY_DATA_I,

69      VARRAY_DATA_U,

70      VARRAY_DATA_L,

71      VARRAY_DATA_UL,

72      VARRAY_DATA_HINT,

73      VARRAY_DATA_UHINT,

74      VARRAY_DATA_GENERIC,

75      VARRAY_DATA_CPTR,

76      VARRAY_DATA_RTX,

77      VARRAY_DATA_RTVEC,

78      VARRAY_DATA_TREE,

79      VARRAY_DATA_BITMAP,

80      VARRAY_DATA_REG,

81      VARRAY_DATA_CONST_EQUIV,

82      VARRAY_DATA_BB,

83      VARRAY_DATA_TE,

84      NUM_VARRAY_DATA

85    };

 

Notice that varray_data in fact is a variable array; it can be any length as long as the system affording.

 

88    typedef union varray_data_tag GTY (()) {                                                     in varray.h

89      char              GTY ((length ("%0.num_elements"),

90                       tag ("VARRAY_DATA_C"))) c[1];

91      unsigned char     GTY ((length ("%0.num_elements"),

92                       tag ("VARRAY_DATA_UC"))) uc[1];

93      short        GTY ((length ("%0.num_elements"),

94                       tag ("VARRAY_DATA_S")))   s[1];

95      unsigned short    GTY ((length ("%0.num_elements"),

96                       tag ("VARRAY_DATA_US"))) us[1];

97      int                     GTY ((length ("%0.num_elements"),

98                       tag ("VARRAY_DATA_I")))   i[1];

99      unsigned int       GTY ((length ("%0.num_elements"),

100                     tag ("VARRAY_DATA_U"))) u[1];

101    long                  GTY ((length ("%0.num_elements"),

102                     tag ("VARRAY_DATA_L"))) l[1];

103    unsigned long     GTY ((length ("%0.num_elements"),

104                     tag ("VARRAY_DATA_UL"))) ul[1];

105    HOST_WIDE_INT    GTY ((length ("%0.num_elements"),

106                     tag ("VARRAY_DATA_HINT")))   hint[1];

107    unsigned HOST_WIDE_INT GTY ((length ("%0.num_elements"),

108                     tag ("VARRAY_DATA_UHINT"))) uhint[1];

109    PTR                  GTY ((length ("%0.num_elements"), use_param (""),

110                     tag ("VARRAY_DATA_GENERIC")))   generic[1];

111    char                   *GTY ((length ("%0.num_elements"),

112                     tag ("VARRAY_DATA_CPTR"))) cptr[1];

113    rtx                     GTY ((length ("%0.num_elements"),

114                     tag ("VARRAY_DATA_RTX"))) rtx[1];

115    rtvec                  GTY ((length ("%0.num_elements"),

116                     tag ("VARRAY_DATA_RTVEC"))) rtvec[1];

117    tree                   GTY ((length ("%0.num_elements"),

118                     tag ("VARRAY_DATA_TREE"))) tree[1];

119    struct bitmap_head_def *GTY ((length ("%0.num_elements"),

120                     tag ("VARRAY_DATA_BITMAP"))) bitmap[1];

121    struct reg_info_def     *GTY ((length ("%0.num_elements"), skip (""),

122                     tag ("VARRAY_DATA_REG"))) reg[1];

123    struct const_equiv_data GTY ((length ("%0.num_elements"),

124                     tag ("VARRAY_DATA_CONST_EQUIV"))) const_equiv[1];

125    struct basic_block_def *GTY ((length ("%0.num_elements"), skip (""),

126                     tag ("VARRAY_DATA_BB"))) bb[1];

127    struct elt_list      *GTY ((length ("%0.num_elements"),

128                     tag ("VARRAY_DATA_TE"))) te[1];

129  } varray_data;

 

Above in VLA_PTR_CREATE , at line 552, VARRAY_GENERIC_PTR_INIT allocates memory for the varray, and the type of the element will be VARRAY_DATA_GENERIC (PTR of varray_data ).

 

177  #define VARRAY_GENERIC_PTR_INIT(va, num, name) /                                   in varray.h

178    va = varray_init (num, VARRAY_DATA_GENERIC, name)

 

115  varray_type

116  varray_init (size_t num_elements, enum varray_data_enum element_kind,       in varray.c

117              const char *name)

118  {

119    size_t data_size = num_elements * element[element_kind].size;

120    varray_type ptr;

121  #ifdef GATHER_STATISTICS

122    struct varray_descriptor *desc = varray_descriptor (name);

123 

124    desc->created++;

125    desc->allocated += data_size + VARRAY_HDR_SIZE;

126  #endif

127    if (element[element_kind].uses_ggc)

128      ptr = ggc_alloc_cleared (VARRAY_HDR_SIZE + data_size);

129    else

130      ptr = xcalloc (VARRAY_HDR_SIZE + data_size, 1);

131 

132    ptr->num_elements = num_elements;

133    ptr->elements_used = 0;

134    ptr->type = element_kind;

135    ptr->name = name;

136    return ptr;

137  }

 

Then following, the hash tables for declarations are initiated by following functions.

 

2237 static void

2238 initiate_automaton_decl_table (void)                                                    in genattrtab.c

2239 {

2240   work_automaton_decl.mode = dm_automaton;

2241   automaton_decl_table = htab_create (10, automaton_decl_hash,

2242                                   automaton_decl_eq_p, (htab_del) 0);

2243 }

 

2336 static void

2337 initiate_insn_decl_table (void)                                                             in genattrtab.c

2338 {

2339   work_insn_decl.mode = dm_insn_reserv;

2340   insn_decl_table = htab_create (10, insn_decl_hash, insn_decl_eq_p,

2341                             (htab_del) 0);

2342 }

 

2438 static void

2439 initiate_decl_table (void)                                                                    in genattrtab.c

2440 {

2441   work_decl.mode = dm_unit;

2442   decl_table = htab_create (10, decl_hash, decl_eq_p, (htab_del) 0);

2443 }

 

Continue with main , after allocating the resource needed, system begins to read in the machine description file.

 

main (continued)

 

5988   while (1)

5989   {

5990     int lineno;

5991

5992     desc = read_md_rtx (&lineno, &insn_code_number );

5993     if (desc == NULL)

5994       break ;

5995

5996     switch (GET_CODE (desc))

5997     {

5998       case DEFINE_INSN:

5999       case DEFINE_PEEPHOLE:

6000       case DEFINE_ASM_ATTRIBUTES:

6001         gen_insn (desc, lineno);

6002         break ;

6003

6004       case DEFINE_ATTR:

6005         gen_attr (desc, lineno);

6006         break ;

6007

6008       case DEFINE_DELAY:

6009         gen_delay (desc, lineno);

6010         break ;

6011

6012       case DEFINE_FUNCTION_UNIT:

6013         gen_unit (desc, lineno);

6014         break ;

6015

6016       case DEFINE_CPU_UNIT:

6017         gen_cpu_unit (desc);

6018         break ;

6019

6020       case DEFINE_QUERY_CPU_UNIT:

6021         gen_query_cpu_unit (desc);

6022         break ;

6023

6024       case DEFINE_BYPASS:

6025         gen_bypass (desc);

6026         break ;

6027

6028       case EXCLUSION_SET:

6029         gen_excl_set (desc);

6030         break ;

6031

6032       case PRESENCE_SET:

6033         gen_presence_set (desc);

6034         break ;

6035

6036       case FINAL_PRESENCE_SET:

6037         gen_final_presence_set (desc);

6038          break ;

6039

6040       case ABSENCE_SET:

6041         gen_absence_set (desc);

6042         break ;

6043

6044       case FINAL_ABSENCE_SET:

6045         gen_final_absence_set (desc);

6046          break ;

6047

6048       case DEFINE_AUTOMATON:

6049         gen_automaton (desc);

6050         break ;

6051

6052       case AUTOMATA_OPTION:

6053         gen_automata_option (desc);

6054         break ;

6055

6056       case DEFINE_RESERVATION:

6057         gen_reserv (desc);

6058         break;

6059

6060       case DEFINE_INSN_RESERVATION:

6061         gen_insn_reserv (desc);

6062         break ;

6063

6064       default :

6065         break ;

6066     }

6067     if (GET_CODE (desc) != DEFINE_ASM_ATTRIBUTES)

6068       insn_index_number ++;

6069   }

 

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值