gccint: Disable Insn Alternatives

1 
1 17.8.6 Disable insn alternatives using the 'enabled' attribute
1 --------------------------------------------------------------
1 
1 There are three insn attributes that may be used to selectively disable
1 instruction alternatives:
1 
1 'enabled'
1      Says whether an alternative is available on the current subtarget.
1 
1 'preferred_for_size'
1      Says whether an enabled alternative should be used in code that is
1      optimized for size.
1 
1 'preferred_for_speed'
1      Says whether an enabled alternative should be used in code that is
1      optimized for speed.
1 
1  All these attributes should use '(const_int 1)' to allow an alternative
1 or '(const_int 0)' to disallow it.  The attributes must be a static
1 property of the subtarget; they cannot for example depend on the current
1 operands, on the current optimization level, on the location of the insn
1 within the body of a loop, on whether register allocation has finished,
1 or on the current compiler pass.
1 
1  The 'enabled' attribute is a correctness property.  It tells GCC to act
1 as though the disabled alternatives were never defined in the first
1 place.  This is useful when adding new instructions to an existing
1 pattern in cases where the new instructions are only available for
1 certain cpu architecture levels (typically mapped to the '-march='
1 command-line option).
1 
1  In contrast, the 'preferred_for_size' and 'preferred_for_speed'
1 attributes are strong optimization hints rather than correctness
1 properties.  'preferred_for_size' tells GCC which alternatives to
1 consider when adding or modifying an instruction that GCC wants to
1 optimize for size.  'preferred_for_speed' does the same thing for speed.
1 Note that things like code motion can lead to cases where code optimized
1 for size uses alternatives that are not preferred for size, and
1 similarly for speed.
1 
1  Although 'define_insn's can in principle specify the 'enabled'
1 attribute directly, it is often clearer to have subsiduary attributes
1 for each architectural feature of interest.  The 'define_insn's can then
1 use these subsiduary attributes to say which alternatives require which
1 features.  The example below does this for 'cpu_facility'.
1 
1  E.g.  the following two patterns could easily be merged using the
1 'enabled' attribute:
1 
1 
1      (define_insn "*movdi_old"
1        [(set (match_operand:DI 0 "register_operand" "=d")
1              (match_operand:DI 1 "register_operand" " d"))]
1        "!TARGET_NEW"
1        "lgr %0,%1")
1 
1      (define_insn "*movdi_new"
1        [(set (match_operand:DI 0 "register_operand" "=d,f,d")
1              (match_operand:DI 1 "register_operand" " d,d,f"))]
1        "TARGET_NEW"
1        "@
1         lgr  %0,%1
1         ldgr %0,%1
1         lgdr %0,%1")
1 
1 
1  to:
1 
1 
1      (define_insn "*movdi_combined"
1        [(set (match_operand:DI 0 "register_operand" "=d,f,d")
1              (match_operand:DI 1 "register_operand" " d,d,f"))]
1        ""
1        "@
1         lgr  %0,%1
1         ldgr %0,%1
1         lgdr %0,%1"
1        [(set_attr "cpu_facility" "*,new,new")])
1 
1 
1  with the 'enabled' attribute defined like this:
1 
1 
1      (define_attr "cpu_facility" "standard,new" (const_string "standard"))
1 
1      (define_attr "enabled" ""
1        (cond [(eq_attr "cpu_facility" "standard") (const_int 1)
1               (and (eq_attr "cpu_facility" "new")
1                    (ne (symbol_ref "TARGET_NEW") (const_int 0)))
1               (const_int 1)]
1              (const_int 0)))
1 
1