gccint: Constant Definitions

1 
1 17.22 Constant Definitions
1 ==========================
1 
1 Using literal constants inside instruction patterns reduces legibility
1 and can be a maintenance problem.
1 
1  To overcome this problem, you may use the 'define_constants'
1 expression.  It contains a vector of name-value pairs.  From that point
1 on, wherever any of the names appears in the MD file, it is as if the
1 corresponding value had been written instead.  You may use
1 'define_constants' multiple times; each appearance adds more constants
1 to the table.  It is an error to redefine a constant with a different
1 value.
1 
1  To come back to the a29k load multiple example, instead of
1 
1      (define_insn ""
1        [(match_parallel 0 "load_multiple_operation"
1           [(set (match_operand:SI 1 "gpc_reg_operand" "=r")
1                 (match_operand:SI 2 "memory_operand" "m"))
1            (use (reg:SI 179))
1            (clobber (reg:SI 179))])]
1        ""
1        "loadm 0,0,%1,%2")
1 
1  You could write:
1 
1      (define_constants [
1          (R_BP 177)
1          (R_FC 178)
1          (R_CR 179)
1          (R_Q  180)
1      ])
1 
1      (define_insn ""
1        [(match_parallel 0 "load_multiple_operation"
1           [(set (match_operand:SI 1 "gpc_reg_operand" "=r")
1                 (match_operand:SI 2 "memory_operand" "m"))
1            (use (reg:SI R_CR))
1            (clobber (reg:SI R_CR))])]
1        ""
1        "loadm 0,0,%1,%2")
1 
1  The constants that are defined with a define_constant are also output
1 in the insn-codes.h header file as #defines.
1 
1  You can also use the machine description file to define enumerations.
1 Like the constants defined by 'define_constant', these enumerations are
1 visible to both the machine description file and the main C code.
1 
1  The syntax is as follows:
1 
1      (define_c_enum "NAME" [
1        VALUE0
1        VALUE1
1        ...
1        VALUEN
1      ])
1 
1  This definition causes the equivalent of the following C code to appear
1 in 'insn-constants.h':
1 
1      enum NAME {
1        VALUE0 = 0,
1        VALUE1 = 1,
1        ...
1        VALUEN = N
1      };
1      #define NUM_CNAME_VALUES (N + 1)
1 
1  where CNAME is the capitalized form of NAME.  It also makes each VALUEI
1 available in the machine description file, just as if it had been
1 declared with:
1 
1      (define_constants [(VALUEI I)])
1 
1  Each VALUEI is usually an upper-case identifier and usually begins with
1 CNAME.
1 
1  You can split the enumeration definition into as many statements as you
1 like.  The above example is directly equivalent to:
1 
1      (define_c_enum "NAME" [VALUE0])
1      (define_c_enum "NAME" [VALUE1])
1      ...
1      (define_c_enum "NAME" [VALUEN])
1 
1  Splitting the enumeration helps to improve the modularity of each
1 individual '.md' file.  For example, if a port defines its
1 synchronization instructions in a separate 'sync.md' file, it is
1 convenient to define all synchronization-specific enumeration values in
1 'sync.md' rather than in the main '.md' file.
1 
1  Some enumeration names have special significance to GCC:
1 
1 'unspecv'
1      If an enumeration called 'unspecv' is defined, GCC will use it when
1      printing out 'unspec_volatile' expressions.  For example:
1 
1           (define_c_enum "unspecv" [
1             UNSPECV_BLOCKAGE
1           ])
1 
1      causes GCC to print '(unspec_volatile ... 0)' as:
1 
1           (unspec_volatile ... UNSPECV_BLOCKAGE)
1 
1 'unspec'
1      If an enumeration called 'unspec' is defined, GCC will use it when
1      printing out 'unspec' expressions.  GCC will also use it when
1      printing out 'unspec_volatile' expressions unless an 'unspecv'
1      enumeration is also defined.  You can therefore decide whether to
1      keep separate enumerations for volatile and non-volatile
1      expressions or whether to use the same enumeration for both.
1 
1  Another way of defining an enumeration is to use 'define_enum':
1 
1      (define_enum "NAME" [
1        VALUE0
1        VALUE1
1        ...
1        VALUEN
1      ])
1 
1  This directive implies:
1 
1      (define_c_enum "NAME" [
1        CNAME_CVALUE0
1        CNAME_CVALUE1
1        ...
1        CNAME_CVALUEN
1      ])
1 
1  where CVALUEI is the capitalized form of VALUEI.  However, unlike
1 'define_c_enum', the enumerations defined by 'define_enum' can be used
1 in attribute specifications (⇒define_enum_attr).
1