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