[PATCH] i386/x86_64 get_attr_length bugfixes
Jakub Jelinek
jakub@redhat.com
Wed May 20 18:15:00 GMT 2009
Hi!
I've used attached script on -S -dp compiled i386/x86_64 sources to find
various bugs in config/i386/ instruction length computation.
This patch fixes all bugs found in -O2 {-m32,-m64} insn-attrtab.i
compilation and most bugs found in -O3 -fpic {-m32,-m64} tramp3d-v4.ii
compilation. The script isn't perfect, e.g. it doesn't handle multi-insn
instructions (like return_long_internal, which contain \;, or e.g. set_got
(which is wrong anyway, 11 bytes actual vs. 12 bytes returned by
get_attr_length)), but for finding bugs in length computations is quite useful.
The script is invoked with a list of -S -dp compiled files, like:
./analyze.S.-dp.sh *.s
(or
asflags=-32 ./analyze.S.-dp.sh *.s
for -m32 compiled stuff).
I've also run the vanilla and patched gcc on a collection of preprocessed
gcc sources, with -O2 {-m32,-m64} and -O3 -fpic {-m32 -march=core2,-m64},
results of the script attached. There is still work to do, but the patch
already grew quite a bit, so I'd prefer to do further bugfixes in followup
patches. From the results* tarball it is clear that the patch does
substantial improvements in the insn length computation, especially for -m64
compiled code.
My primary reason for working on this is to make get_attr_length good enough
to be usable in min_insn_size for non-jump insns other than
TYPE_MULTI/TYPE_OTHER.
Bootstrapped/regtested on x86_64-linux and i686-linux. Ok for trunk?
Jakub
-------------- next part --------------
2009-05-20 Jakub Jelinek <jakub@redhat.com>
* config/i386/i386.c (memory_address_length): Handle %r12
the same as %rsp and %r13 the same as %rbp. For %rsp and %rbp
also check REGNO.
(ix86_attr_length_address_default): For MODE_SI lea in 64-bit
mode look through optional ZERO_EXTEND and SUBREG.
* config/i386/i386.md (R12_REG): New define_constant.
(prefix_data16): For sse unit set also for MODE_TI insns.
(prefix_rex): For -m32 always return 0. For TYPE_IMOVX
insns set if operand 1 is ext_QIreg_operand.
(modrm): For TYPE_IMOV clear only if not MODE_DI. For
TYPE_{ALU{,1},ICMP,TEST} insn clear if there is non-shortened
immediate.
(*movdi_extzv_1, zero_extendhidi2, zero_extendqidi2): Change
mode from MODE_DI to MODE_SI.
(movdi_1_rex64): Override modrm and length_immediate attributes
only for movabs (TYPE_IMOV, alternative 2).
(zero_extendsidi2_rex64): Clear prefix_0f attribute if TYPE_IMOVX.
(*float<SSEMODEI24:mode><MODEF:mode>2_mixed_interunit,
*float<SSEMODEI24:mode><MODEF:mode>2_mixed_nointerunit,
*float<SSEMODEI24:mode><MODEF:mode>2_sse_interunit,
*float<SSEMODEI24:mode><MODEF:mode>2_sse_nointerunit): Set
prefix_rex attribute if DImode.
(*adddi_1_rex64, *adddi_2_rex64, *adddi_3_rex64, *adddi_5_rex64,
*addsi_1, *addsi_1_zext, *addsi_2, *addsi_2_zext, *addsi_3,
*addsi_3_zext, *addsi_5, *addhi_1_lea, *addhi_1, *addhi_2, *addhi_3,
*addhi_5, *addqi_1_lea, *addqi_1): Override length_immediate
attribute to 1 if TYPE_ALU and operand 2 is const128_operand.
(pro_epilogue_adjust_stack_1, pro_epilogue_adjust_stack_rex64):
Likewise. For TYPE_IMOV clear length_immediate attribute.
(*ashldi3_1_rex64, *ashldi3_cmp_rex64, *ashldi3_cconly_rex64,
*ashlsi3_1, *ashlsi3_1_zext, *ashlsi3_cmp, **ashlsi3_cconly,
*ashlsi3_cmp_zext, *ashlhi3_1_lea, *ashlhi3_1, *ashlhi3_cmp,
*ashlhi3_cconly, *ashlqi3_1_lea, *ashlqi3_1, *ashlqi3_cmp,
*ashlqi3_cconly): Override length_immediate attribute to 0 if TYPE_ALU
or one operand TYPE_ISHIFT.
(*ashrdi3_1_one_bit_rex64, *ashrdi3_one_bit_cmp_rex64,
*ashrdi3_one_bit_cconly_rex64, *ashrsi3_1_one_bit,
*ashrsi3_1_one_bit_zext, *ashrsi3_one_bit_cmp,
*ashrsi3_one_bit_cconly, *ashrsi3_one_bit_cmp_zext,
*ashrhi3_1_one_bit, *ashrhi3_one_bit_cmp, *ashrhi3_one_bit_cconly,
*ashrqi3_1_one_bit, *ashrqi3_1_one_bit_slp, *ashrqi3_one_bit_cmp,
*ashrqi3_one_bit_cconly, *lshrdi3_1_one_bit_rex64,
*lshrdi3_cmp_one_bit_rex64, *lshrdi3_cconly_one_bit_rex64,
*lshrsi3_1_one_bit, *lshrsi3_1_one_bit_zext, *lshrsi3_one_bit_cmp,
*lshrsi3_one_bit_cconly, *lshrsi3_cmp_one_bit_zext,
*lshrhi3_1_one_bit, *lshrhi3_one_bit_cmp, *lshrhi3_one_bit_cconly,
*lshrqi3_1_one_bit, *lshrqi3_1_one_bit_slp, *lshrqi2_one_bit_cmp,
*lshrqi2_one_bit_cconly, *rotlsi3_1_one_bit_rex64, *rotlsi3_1_one_bit,
*rotlsi3_1_one_bit_zext, *rotlhi3_1_one_bit, *rotlqi3_1_one_bit_slp,
*rotlqi3_1_one_bit, *rotrdi3_1_one_bit_rex64, *rotrsi3_1_one_bit,
*rotrsi3_1_one_bit_zext, *rotrhi3_one_bit, *rotrqi3_1_one_bit,
*rotrqi3_1_one_bit_slp): Override length_immediate attribute to 0,
set mode attribute, don't override length attribute.
(*btsq, *btrq, *btcq, *btdi_rex64, *btsi): Set prefix_0f attribute
to 1.
(return_internal_long): Set length attribute to 2 instead of 1.
(*strmovqi_rex_1, *strsetqi_rex_1, *rep_stosqi_rex64,
*cmpstrnqi_nz_rex_1, *cmpstrnqi_rex_1, *strlenqi_rex_1): Clear
prefix_rex attribute.
* config/i386/predicates.md (ext_QIreg_operand,
const128_operand): New predicates.
(memory_displacement_only_operand): Always return 0 for
TARGET_64BIT.
--- gcc/config/i386/i386.c (revision 147701)
+++ gcc/config/i386/i386.c (working copy)
@@ -19308,17 +19308,23 @@ memory_address_length (rtx addr)
/* Rule of thumb:
- esp as the base always wants an index,
- - ebp as the base always wants a displacement. */
+ - ebp as the base always wants a displacement,
+ - r12 as the base always wants an index,
+ - r13 as the base always wants a displacement. */
/* Register Indirect. */
if (base && !index && !disp)
{
/* esp (for its index) and ebp (for its displacement) need
- the two-byte modrm form. */
- if (addr == stack_pointer_rtx
- || addr == arg_pointer_rtx
- || addr == frame_pointer_rtx
- || addr == hard_frame_pointer_rtx)
+ the two-byte modrm form. Similarly for r12 and r13 in 64-bit
+ code. */
+ if (REG_P (addr)
+ && (addr == arg_pointer_rtx
+ || addr == frame_pointer_rtx
+ || REGNO (addr) == SP_REG
+ || REGNO (addr) == BP_REG
+ || REGNO (addr) == R12_REG
+ || REGNO (addr) == R13_REG))
len = 1;
}
@@ -19336,16 +19342,18 @@ memory_address_length (rtx addr)
else
len = 4;
}
- /* ebp always wants a displacement. */
- else if (base == hard_frame_pointer_rtx)
+ /* ebp always wants a displacement. Similarly r13. */
+ else if (REG_P (base)
+ && (REGNO (base) == BP_REG || REGNO (base) == R13_REG))
len = 1;
/* An index requires the two-byte modrm form.... */
if (index
- /* ...like esp, which always wants an index. */
- || base == stack_pointer_rtx
+ /* ...like esp (or r12), which always wants an index. */
|| base == arg_pointer_rtx
- || base == frame_pointer_rtx)
+ || base == frame_pointer_rtx
+ || (REG_P (base)
+ && (REGNO (base) == SP_REG || REGNO (base) == R12_REG)))
len += 1;
}
@@ -19398,14 +19406,23 @@ ix86_attr_length_address_default (rtx in
if (get_attr_type (insn) == TYPE_LEA)
{
- rtx set = PATTERN (insn);
+ rtx set = PATTERN (insn), addr;
if (GET_CODE (set) == PARALLEL)
set = XVECEXP (set, 0, 0);
gcc_assert (GET_CODE (set) == SET);
- return memory_address_length (SET_SRC (set));
+ addr = SET_SRC (set);
+ if (TARGET_64BIT && get_attr_mode (insn) == MODE_SI)
+ {
+ if (GET_CODE (addr) == ZERO_EXTEND)
+ addr = XEXP (addr, 0);
+ if (GET_CODE (addr) == SUBREG)
+ addr = SUBREG_REG (addr);
+ }
+
+ return memory_address_length (addr);
}
extract_insn_cached (insn);
--- gcc/config/i386/i386.md (revision 147701)
+++ gcc/config/i386/i386.md (working copy)
@@ -312,6 +312,7 @@ (define_constants
(R9_REG 38)
(R10_REG 39)
(R11_REG 40)
+ (R12_REG 41)
(R13_REG 42)
(XMM8_REG 45)
(XMM9_REG 46)
@@ -416,7 +417,7 @@ (define_attr "length_address" ""
;; Set when length prefix is used.
(define_attr "prefix_data16" ""
(if_then_else (ior (eq_attr "mode" "HI")
- (and (eq_attr "unit" "sse") (eq_attr "mode" "V2DF")))
+ (and (eq_attr "unit" "sse") (eq_attr "mode" "V2DF,TI")))
(const_int 1)
(const_int 0)))
@@ -436,7 +437,9 @@ (define_attr "prefix_0f" ""
;; Set when REX opcode prefix is used.
(define_attr "prefix_rex" ""
- (cond [(and (eq_attr "mode" "DI")
+ (cond [(ne (symbol_ref "!TARGET_64BIT") (const_int 0))
+ (const_int 0)
+ (and (eq_attr "mode" "DI")
(eq_attr "type" "!push,pop,call,callv,leave,ibr"))
(const_int 1)
(and (eq_attr "mode" "QI")
@@ -446,6 +449,9 @@ (define_attr "prefix_rex" ""
(ne (symbol_ref "x86_extended_reg_mentioned_p (insn)")
(const_int 0))
(const_int 1)
+ (and (eq_attr "type" "imovx")
+ (match_operand:QI 1 "ext_QIreg_operand" ""))
+ (const_int 1)
]
(const_int 0)))
@@ -491,12 +497,13 @@ (define_attr "modrm" ""
(not (match_operand 0 "memory_operand" "")))
(const_int 0)
(and (eq_attr "type" "imov")
- (ior (and (match_operand 0 "register_operand" "")
- (match_operand 1 "immediate_operand" ""))
- (ior (and (match_operand 0 "ax_reg_operand" "")
- (match_operand 1 "memory_displacement_only_operand" ""))
- (and (match_operand 0 "memory_displacement_only_operand" "")
- (match_operand 1 "ax_reg_operand" "")))))
+ (and (not (eq_attr "mode" "DI"))
+ (ior (and (match_operand 0 "register_operand" "")
+ (match_operand 1 "immediate_operand" ""))
+ (ior (and (match_operand 0 "ax_reg_operand" "")
+ (match_operand 1 "memory_displacement_only_operand" ""))
+ (and (match_operand 0 "memory_displacement_only_operand" "")
+ (match_operand 1 "ax_reg_operand" ""))))))
(const_int 0)
(and (eq_attr "type" "call")
(match_operand 0 "constant_call_address_operand" ""))
@@ -504,6 +511,9 @@ (define_attr "modrm" ""
(and (eq_attr "type" "callv")
(match_operand 1 "constant_call_address_operand" ""))
(const_int 0)
+ (and (eq_attr "type" "alu,alu1,icmp,test")
+ (match_operand 0 "ax_reg_operand" ""))
+ (symbol_ref "(get_attr_length_immediate (insn) <= (get_attr_mode (insn) != MODE_QI))")
]
(const_int 1)))
@@ -2283,7 +2293,7 @@ (define_insn "*movdi_extzv_1"
"TARGET_64BIT"
"movz{bl|x}\t{%h1, %k0|%k0, %h1}"
[(set_attr "type" "imovx")
- (set_attr "mode" "DI")])
+ (set_attr "mode" "SI")])
(define_insn "*movsi_extzv_1"
[(set (match_operand:SI 0 "register_operand" "=R")
@@ -2631,8 +2641,16 @@ (define_insn "*movdi_1_rex64"
(const_string "lea")
]
(const_string "imov")))
- (set_attr "modrm" "*,0,0,*,*,*,*,*,*,*,*,*,*,*,*,*,*,*,*")
- (set_attr "length_immediate" "*,4,8,*,*,*,*,*,*,*,*,*,*,*,*,*,*,*,*")
+ (set (attr "modrm")
+ (if_then_else
+ (and (eq_attr "alternative" "2") (eq_attr "type" "imov"))
+ (const_string "0")
+ (const_string "*")))
+ (set (attr "length_immediate")
+ (if_then_else
+ (and (eq_attr "alternative" "2") (eq_attr "type" "imov"))
+ (const_string "8")
+ (const_string "*")))
(set (attr "prefix")
(if_then_else (eq_attr "alternative" "11,12,13,14,15,16")
(const_string "maybe_vex")
@@ -4101,6 +4119,7 @@ (define_insn "zero_extendsidi2_rex64"
%vmovd\t{%1, %0|%0, %1}"
[(set_attr "type" "imovx,imov,mmxmov,mmxmov,ssemov,ssemov")
(set_attr "prefix" "orig,*,orig,orig,maybe_vex,maybe_vex")
+ (set_attr "prefix_0f" "0,*,*,*,*,*")
(set_attr "mode" "SI,DI,DI,DI,TI,TI")])
(define_split
@@ -4135,7 +4154,7 @@ (define_insn "zero_extendhidi2"
"TARGET_64BIT"
"movz{wl|x}\t{%1, %k0|%k0, %1}"
[(set_attr "type" "imovx")
- (set_attr "mode" "DI")])
+ (set_attr "mode" "SI")])
(define_insn "zero_extendqidi2"
[(set (match_operand:DI 0 "register_operand" "=r")
@@ -4143,7 +4162,7 @@ (define_insn "zero_extendqidi2"
"TARGET_64BIT"
"movz{bl|x}\t{%1, %k0|%k0, %1}"
[(set_attr "type" "imovx")
- (set_attr "mode" "DI")])
+ (set_attr "mode" "SI")])
;; Sign extension instructions
@@ -5488,6 +5507,12 @@ (define_insn "*float<SSEMODEI24:mode><MO
[(set_attr "type" "fmov,sseicvt,sseicvt")
(set_attr "prefix" "orig,maybe_vex,maybe_vex")
(set_attr "mode" "<MODEF:MODE>")
+ (set (attr "prefix_rex")
+ (if_then_else
+ (and (eq_attr "prefix" "maybe_vex")
+ (ne (symbol_ref "<SSEMODEI24:MODE>mode == DImode") (const_int 0)))
+ (const_string "1")
+ (const_string "*")))
(set_attr "unit" "i387,*,*")
(set_attr "athlon_decode" "*,double,direct")
(set_attr "amdfam10_decode" "*,vector,double")
@@ -5506,6 +5531,12 @@ (define_insn "*float<SSEMODEI24:mode><MO
[(set_attr "type" "fmov,sseicvt")
(set_attr "prefix" "orig,maybe_vex")
(set_attr "mode" "<MODEF:MODE>")
+ (set (attr "prefix_rex")
+ (if_then_else
+ (and (eq_attr "prefix" "maybe_vex")
+ (ne (symbol_ref "<SSEMODEI24:MODE>mode == DImode") (const_int 0)))
+ (const_string "1")
+ (const_string "*")))
(set_attr "athlon_decode" "*,direct")
(set_attr "amdfam10_decode" "*,double")
(set_attr "fp_int_src" "true")])
@@ -5682,6 +5713,12 @@ (define_insn "*float<SSEMODEI24:mode><MO
[(set_attr "type" "sseicvt")
(set_attr "prefix" "maybe_vex")
(set_attr "mode" "<MODEF:MODE>")
+ (set (attr "prefix_rex")
+ (if_then_else
+ (and (eq_attr "prefix" "maybe_vex")
+ (ne (symbol_ref "<SSEMODEI24:MODE>mode == DImode") (const_int 0)))
+ (const_string "1")
+ (const_string "*")))
(set_attr "athlon_decode" "double,direct")
(set_attr "amdfam10_decode" "vector,double")
(set_attr "fp_int_src" "true")])
@@ -5711,6 +5748,12 @@ (define_insn "*float<SSEMODEI24:mode><MO
[(set_attr "type" "sseicvt")
(set_attr "prefix" "maybe_vex")
(set_attr "mode" "<MODEF:MODE>")
+ (set (attr "prefix_rex")
+ (if_then_else
+ (and (eq_attr "prefix" "maybe_vex")
+ (ne (symbol_ref "<SSEMODEI24:MODE>mode == DImode") (const_int 0)))
+ (const_string "1")
+ (const_string "*")))
(set_attr "athlon_decode" "direct")
(set_attr "amdfam10_decode" "double")
(set_attr "fp_int_src" "true")])
@@ -6430,6 +6473,11 @@ (define_insn "*adddi_1_rex64"
(const_string "incdec")
]
(const_string "alu")))
+ (set (attr "length_immediate")
+ (if_then_else
+ (and (eq_attr "type" "alu") (match_operand 2 "const128_operand" ""))
+ (const_string "1")
+ (const_string "*")))
(set_attr "mode" "DI")])
;; Convert lea to the lea pattern to avoid flags dependency.
@@ -6494,6 +6542,11 @@ (define_insn "*adddi_2_rex64"
(if_then_else (match_operand:DI 2 "incdec_operand" "")
(const_string "incdec")
(const_string "alu")))
+ (set (attr "length_immediate")
+ (if_then_else
+ (and (eq_attr "type" "alu") (match_operand 2 "const128_operand" ""))
+ (const_string "1")
+ (const_string "*")))
(set_attr "mode" "DI")])
(define_insn "*adddi_3_rex64"
@@ -6543,6 +6596,11 @@ (define_insn "*adddi_3_rex64"
(if_then_else (match_operand:DI 2 "incdec_operand" "")
(const_string "incdec")
(const_string "alu")))
+ (set (attr "length_immediate")
+ (if_then_else
+ (and (eq_attr "type" "alu") (match_operand 2 "const128_operand" ""))
+ (const_string "1")
+ (const_string "*")))
(set_attr "mode" "DI")])
; For comparisons against 1, -1 and 128, we may generate better code
@@ -6639,6 +6697,11 @@ (define_insn "*adddi_5_rex64"
(if_then_else (match_operand:DI 2 "incdec_operand" "")
(const_string "incdec")
(const_string "alu")))
+ (set (attr "length_immediate")
+ (if_then_else
+ (and (eq_attr "type" "alu") (match_operand 2 "const128_operand" ""))
+ (const_string "1")
+ (const_string "*")))
(set_attr "mode" "DI")])
@@ -6699,6 +6762,11 @@ (define_insn "*addsi_1"
(const_string "incdec")
]
(const_string "alu")))
+ (set (attr "length_immediate")
+ (if_then_else
+ (and (eq_attr "type" "alu") (match_operand 2 "const128_operand" ""))
+ (const_string "1")
+ (const_string "*")))
(set_attr "mode" "SI")])
;; Convert lea to the lea pattern to avoid flags dependency.
@@ -6779,6 +6847,11 @@ (define_insn "addsi_1_zext"
(const_string "incdec")
]
(const_string "alu")))
+ (set (attr "length_immediate")
+ (if_then_else
+ (and (eq_attr "type" "alu") (match_operand 2 "const128_operand" ""))
+ (const_string "1")
+ (const_string "*")))
(set_attr "mode" "SI")])
;; Convert lea to the lea pattern to avoid flags dependency.
@@ -6842,6 +6915,11 @@ (define_insn "*addsi_2"
(if_then_else (match_operand:SI 2 "incdec_operand" "")
(const_string "incdec")
(const_string "alu")))
+ (set (attr "length_immediate")
+ (if_then_else
+ (and (eq_attr "type" "alu") (match_operand 2 "const128_operand" ""))
+ (const_string "1")
+ (const_string "*")))
(set_attr "mode" "SI")])
;; See comment for addsi_1_zext why we do use nonimmediate_operand
@@ -6888,6 +6966,11 @@ (define_insn "*addsi_2_zext"
(if_then_else (match_operand:SI 2 "incdec_operand" "")
(const_string "incdec")
(const_string "alu")))
+ (set (attr "length_immediate")
+ (if_then_else
+ (and (eq_attr "type" "alu") (match_operand 2 "const128_operand" ""))
+ (const_string "1")
+ (const_string "*")))
(set_attr "mode" "SI")])
(define_insn "*addsi_3"
@@ -6932,6 +7015,11 @@ (define_insn "*addsi_3"
(if_then_else (match_operand:SI 2 "incdec_operand" "")
(const_string "incdec")
(const_string "alu")))
+ (set (attr "length_immediate")
+ (if_then_else
+ (and (eq_attr "type" "alu") (match_operand 2 "const128_operand" ""))
+ (const_string "1")
+ (const_string "*")))
(set_attr "mode" "SI")])
;; See comment for addsi_1_zext why we do use nonimmediate_operand
@@ -6976,6 +7064,11 @@ (define_insn "*addsi_3_zext"
(if_then_else (match_operand:SI 2 "incdec_operand" "")
(const_string "incdec")
(const_string "alu")))
+ (set (attr "length_immediate")
+ (if_then_else
+ (and (eq_attr "type" "alu") (match_operand 2 "const128_operand" ""))
+ (const_string "1")
+ (const_string "*")))
(set_attr "mode" "SI")])
; For comparisons against 1, -1 and 128, we may generate better code
@@ -7067,6 +7160,11 @@ (define_insn "*addsi_5"
(if_then_else (match_operand:SI 2 "incdec_operand" "")
(const_string "incdec")
(const_string "alu")))
+ (set (attr "length_immediate")
+ (if_then_else
+ (and (eq_attr "type" "alu") (match_operand 2 "const128_operand" ""))
+ (const_string "1")
+ (const_string "*")))
(set_attr "mode" "SI")])
(define_expand "addhi3"
@@ -7121,6 +7219,11 @@ (define_insn "*addhi_1_lea"
(if_then_else (match_operand:HI 2 "incdec_operand" "")
(const_string "incdec")
(const_string "alu"))))
+ (set (attr "length_immediate")
+ (if_then_else
+ (and (eq_attr "type" "alu") (match_operand 2 "const128_operand" ""))
+ (const_string "1")
+ (const_string "*")))
(set_attr "mode" "HI,HI,SI")])
(define_insn "*addhi_1"
@@ -7160,6 +7263,11 @@ (define_insn "*addhi_1"
(if_then_else (match_operand:HI 2 "incdec_operand" "")
(const_string "incdec")
(const_string "alu")))
+ (set (attr "length_immediate")
+ (if_then_else
+ (and (eq_attr "type" "alu") (match_operand 2 "const128_operand" ""))
+ (const_string "1")
+ (const_string "*")))
(set_attr "mode" "HI")])
(define_insn "*addhi_2"
@@ -7202,6 +7310,11 @@ (define_insn "*addhi_2"
(if_then_else (match_operand:HI 2 "incdec_operand" "")
(const_string "incdec")
(const_string "alu")))
+ (set (attr "length_immediate")
+ (if_then_else
+ (and (eq_attr "type" "alu") (match_operand 2 "const128_operand" ""))
+ (const_string "1")
+ (const_string "*")))
(set_attr "mode" "HI")])
(define_insn "*addhi_3"
@@ -7241,6 +7354,11 @@ (define_insn "*addhi_3"
(if_then_else (match_operand:HI 2 "incdec_operand" "")
(const_string "incdec")
(const_string "alu")))
+ (set (attr "length_immediate")
+ (if_then_else
+ (and (eq_attr "type" "alu") (match_operand 2 "const128_operand" ""))
+ (const_string "1")
+ (const_string "*")))
(set_attr "mode" "HI")])
; See comments above addsi_4 for details.
@@ -7321,6 +7439,11 @@ (define_insn "*addhi_5"
(if_then_else (match_operand:HI 2 "incdec_operand" "")
(const_string "incdec")
(const_string "alu")))
+ (set (attr "length_immediate")
+ (if_then_else
+ (and (eq_attr "type" "alu") (match_operand 2 "const128_operand" ""))
+ (const_string "1")
+ (const_string "*")))
(set_attr "mode" "HI")])
(define_expand "addqi3"
@@ -7379,6 +7502,11 @@ (define_insn "*addqi_1_lea"
(if_then_else (match_operand:QI 2 "incdec_operand" "")
(const_string "incdec")
(const_string "alu"))))
+ (set (attr "length_immediate")
+ (if_then_else
+ (and (eq_attr "type" "alu") (match_operand 2 "const128_operand" ""))
+ (const_string "1")
+ (const_string "*")))
(set_attr "mode" "QI,QI,SI,SI")])
(define_insn "*addqi_1"
@@ -7425,6 +7553,11 @@ (define_insn "*addqi_1"
(if_then_else (match_operand:QI 2 "incdec_operand" "")
(const_string "incdec")
(const_string "alu")))
+ (set (attr "length_immediate")
+ (if_then_else
+ (and (eq_attr "type" "alu") (match_operand 2 "const128_operand" ""))
+ (const_string "1")
+ (const_string "*")))
(set_attr "mode" "QI,QI,SI")])
(define_insn "*addqi_1_slp"
@@ -11513,6 +11646,15 @@ (define_insn "*ashldi3_1_rex64"
(const_string "alu")
]
(const_string "ishift")))
+ (set (attr "length_immediate")
+ (if_then_else
+ (ior (eq_attr "type" "alu")
+ (and (eq_attr "type" "ishift")
+ (and (match_operand 2 "const1_operand" "")
+ (ne (symbol_ref "TARGET_SHIFT1 || optimize_function_for_size_p (cfun)")
+ (const_int 0)))))
+ (const_string "0")
+ (const_string "*")))
(set_attr "mode" "DI")])
;; Convert lea to the lea pattern to avoid flags dependency.
@@ -11572,6 +11714,15 @@ (define_insn "*ashldi3_cmp_rex64"
(const_string "alu")
]
(const_string "ishift")))
+ (set (attr "length_immediate")
+ (if_then_else
+ (ior (eq_attr "type" "alu")
+ (and (eq_attr "type" "ishift")
+ (and (match_operand 2 "const1_operand" "")
+ (ne (symbol_ref "TARGET_SHIFT1 || optimize_function_for_size_p (cfun)")
+ (const_int 0)))))
+ (const_string "0")
+ (const_string "*")))
(set_attr "mode" "DI")])
(define_insn "*ashldi3_cconly_rex64"
@@ -11614,6 +11765,15 @@ (define_insn "*ashldi3_cconly_rex64"
(const_string "alu")
]
(const_string "ishift")))
+ (set (attr "length_immediate")
+ (if_then_else
+ (ior (eq_attr "type" "alu")
+ (and (eq_attr "type" "ishift")
+ (and (match_operand 2 "const1_operand" "")
+ (ne (symbol_ref "TARGET_SHIFT1 || optimize_function_for_size_p (cfun)")
+ (const_int 0)))))
+ (const_string "0")
+ (const_string "*")))
(set_attr "mode" "DI")])
(define_insn "*ashldi3_1"
@@ -11753,6 +11913,15 @@ (define_insn "*ashlsi3_1"
(const_string "alu")
]
(const_string "ishift")))
+ (set (attr "length_immediate")
+ (if_then_else
+ (ior (eq_attr "type" "alu")
+ (and (eq_attr "type" "ishift")
+ (and (match_operand 2 "const1_operand" "")
+ (ne (symbol_ref "TARGET_SHIFT1 || optimize_function_for_size_p (cfun)")
+ (const_int 0)))))
+ (const_string "0")
+ (const_string "*")))
(set_attr "mode" "SI")])
;; Convert lea to the lea pattern to avoid flags dependency.
@@ -11837,6 +12006,15 @@ (define_insn "*ashlsi3_1_zext"
(const_string "alu")
]
(const_string "ishift")))
+ (set (attr "length_immediate")
+ (if_then_else
+ (ior (eq_attr "type" "alu")
+ (and (eq_attr "type" "ishift")
+ (and (match_operand 2 "const1_operand" "")
+ (ne (symbol_ref "TARGET_SHIFT1 || optimize_function_for_size_p (cfun)")
+ (const_int 0)))))
+ (const_string "0")
+ (const_string "*")))
(set_attr "mode" "SI")])
;; Convert lea to the lea pattern to avoid flags dependency.
@@ -11898,6 +12076,15 @@ (define_insn "*ashlsi3_cmp"
(const_string "alu")
]
(const_string "ishift")))
+ (set (attr "length_immediate")
+ (if_then_else
+ (ior (eq_attr "type" "alu")
+ (and (eq_attr "type" "ishift")
+ (and (match_operand 2 "const1_operand" "")
+ (ne (symbol_ref "TARGET_SHIFT1 || optimize_function_for_size_p (cfun)")
+ (const_int 0)))))
+ (const_string "0")
+ (const_string "*")))
(set_attr "mode" "SI")])
(define_insn "*ashlsi3_cconly"
@@ -11939,6 +12126,15 @@ (define_insn "*ashlsi3_cconly"
(const_string "alu")
]
(const_string "ishift")))
+ (set (attr "length_immediate")
+ (if_then_else
+ (ior (eq_attr "type" "alu")
+ (and (eq_attr "type" "ishift")
+ (and (match_operand 2 "const1_operand" "")
+ (ne (symbol_ref "TARGET_SHIFT1 || optimize_function_for_size_p (cfun)")
+ (const_int 0)))))
+ (const_string "0")
+ (const_string "*")))
(set_attr "mode" "SI")])
(define_insn "*ashlsi3_cmp_zext"
@@ -11981,6 +12177,15 @@ (define_insn "*ashlsi3_cmp_zext"
(const_string "alu")
]
(const_string "ishift")))
+ (set (attr "length_immediate")
+ (if_then_else
+ (ior (eq_attr "type" "alu")
+ (and (eq_attr "type" "ishift")
+ (and (match_operand 2 "const1_operand" "")
+ (ne (symbol_ref "TARGET_SHIFT1 || optimize_function_for_size_p (cfun)")
+ (const_int 0)))))
+ (const_string "0")
+ (const_string "*")))
(set_attr "mode" "SI")])
(define_expand "ashlhi3"
@@ -12026,6 +12231,15 @@ (define_insn "*ashlhi3_1_lea"
(const_string "alu")
]
(const_string "ishift")))
+ (set (attr "length_immediate")
+ (if_then_else
+ (ior (eq_attr "type" "alu")
+ (and (eq_attr "type" "ishift")
+ (and (match_operand 2 "const1_operand" "")
+ (ne (symbol_ref "TARGET_SHIFT1 || optimize_function_for_size_p (cfun)")
+ (const_int 0)))))
+ (const_string "0")
+ (const_string "*")))
(set_attr "mode" "HI,SI")])
(define_insn "*ashlhi3_1"
@@ -12060,6 +12274,15 @@ (define_insn "*ashlhi3_1"
(const_string "alu")
]
(const_string "ishift")))
+ (set (attr "length_immediate")
+ (if_then_else
+ (ior (eq_attr "type" "alu")
+ (and (eq_attr "type" "ishift")
+ (and (match_operand 2 "const1_operand" "")
+ (ne (symbol_ref "TARGET_SHIFT1 || optimize_function_for_size_p (cfun)")
+ (const_int 0)))))
+ (const_string "0")
+ (const_string "*")))
(set_attr "mode" "HI")])
;; This pattern can't accept a variable shift count, since shifts by
@@ -12105,6 +12328,15 @@ (define_insn "*ashlhi3_cmp"
(const_string "alu")
]
(const_string "ishift")))
+ (set (attr "length_immediate")
+ (if_then_else
+ (ior (eq_attr "type" "alu")
+ (and (eq_attr "type" "ishift")
+ (and (match_operand 2 "const1_operand" "")
+ (ne (symbol_ref "TARGET_SHIFT1 || optimize_function_for_size_p (cfun)")
+ (const_int 0)))))
+ (const_string "0")
+ (const_string "*")))
(set_attr "mode" "HI")])
(define_insn "*ashlhi3_cconly"
@@ -12146,6 +12378,15 @@ (define_insn "*ashlhi3_cconly"
(const_string "alu")
]
(const_string "ishift")))
+ (set (attr "length_immediate")
+ (if_then_else
+ (ior (eq_attr "type" "alu")
+ (and (eq_attr "type" "ishift")
+ (and (match_operand 2 "const1_operand" "")
+ (ne (symbol_ref "TARGET_SHIFT1 || optimize_function_for_size_p (cfun)")
+ (const_int 0)))))
+ (const_string "0")
+ (const_string "*")))
(set_attr "mode" "HI")])
(define_expand "ashlqi3"
@@ -12211,6 +12452,15 @@ (define_insn "*ashlqi3_1_lea"
(const_string "alu")
]
(const_string "ishift")))
+ (set (attr "length_immediate")
+ (if_then_else
+ (ior (eq_attr "type" "alu")
+ (and (eq_attr "type" "ishift")
+ (and (match_operand 2 "const1_operand" "")
+ (ne (symbol_ref "TARGET_SHIFT1 || optimize_function_for_size_p (cfun)")
+ (const_int 0)))))
+ (const_string "0")
+ (const_string "*")))
(set_attr "mode" "QI,SI,SI")])
(define_insn "*ashlqi3_1"
@@ -12263,6 +12513,15 @@ (define_insn "*ashlqi3_1"
(const_string "alu")
]
(const_string "ishift")))
+ (set (attr "length_immediate")
+ (if_then_else
+ (ior (eq_attr "type" "alu")
+ (and (eq_attr "type" "ishift")
+ (and (match_operand 2 "const1_operand" "")
+ (ne (symbol_ref "TARGET_SHIFT1 || optimize_function_for_size_p (cfun)")
+ (const_int 0)))))
+ (const_string "0")
+ (const_string "*")))
(set_attr "mode" "QI,SI")])
;; This pattern can't accept a variable shift count, since shifts by
@@ -12308,6 +12567,15 @@ (define_insn "*ashlqi3_cmp"
(const_string "alu")
]
(const_string "ishift")))
+ (set (attr "length_immediate")
+ (if_then_else
+ (ior (eq_attr "type" "alu")
+ (and (eq_attr "type" "ishift")
+ (and (match_operand 2 "const1_operand" "")
+ (ne (symbol_ref "TARGET_SHIFT1 || optimize_function_for_size_p (cfun)")
+ (const_int 0)))))
+ (const_string "0")
+ (const_string "*")))
(set_attr "mode" "QI")])
(define_insn "*ashlqi3_cconly"
@@ -12349,6 +12617,15 @@ (define_insn "*ashlqi3_cconly"
(const_string "alu")
]
(const_string "ishift")))
+ (set (attr "length_immediate")
+ (if_then_else
+ (ior (eq_attr "type" "alu")
+ (and (eq_attr "type" "ishift")
+ (and (match_operand 2 "const1_operand" "")
+ (ne (symbol_ref "TARGET_SHIFT1 || optimize_function_for_size_p (cfun)")
+ (const_int 0)))))
+ (const_string "0")
+ (const_string "*")))
(set_attr "mode" "QI")])
;; See comment above `ashldi3' about how this works.
@@ -12467,10 +12744,8 @@ (define_insn "*ashrdi3_1_one_bit_rex64"
&& ix86_binary_operator_ok (ASHIFTRT, DImode, operands)"
"sar{q}\t%0"
[(set_attr "type" "ishift")
- (set (attr "length")
- (if_then_else (match_operand:DI 0 "register_operand" "")
- (const_string "2")
- (const_string "*")))])
+ (set_attr "length_immediate" "0")
+ (set_attr "mode" "DI")])
(define_insn "*ashrdi3_1_rex64"
[(set (match_operand:DI 0 "nonimmediate_operand" "=rm,rm")
@@ -12501,10 +12776,8 @@ (define_insn "*ashrdi3_one_bit_cmp_rex64
&& ix86_binary_operator_ok (ASHIFTRT, DImode, operands)"
"sar{q}\t%0"
[(set_attr "type" "ishift")
- (set (attr "length")
- (if_then_else (match_operand:DI 0 "register_operand" "")
- (const_string "2")
- (const_string "*")))])
+ (set_attr "length_immediate" "0")
+ (set_attr "mode" "DI")])
(define_insn "*ashrdi3_one_bit_cconly_rex64"
[(set (reg FLAGS_REG)
@@ -12519,7 +12792,8 @@ (define_insn "*ashrdi3_one_bit_cconly_re
&& ix86_binary_operator_ok (ASHIFTRT, DImode, operands)"
"sar{q}\t%0"
[(set_attr "type" "ishift")
- (set_attr "length" "2")])
+ (set_attr "length_immediate" "0")
+ (set_attr "mode" "DI")])
;; This pattern can't accept a variable shift count, since shifts by
;; zero don't affect the flags. We assume that shifts by constant
@@ -12687,10 +12961,8 @@ (define_insn "*ashrsi3_1_one_bit"
&& ix86_binary_operator_ok (ASHIFTRT, SImode, operands)"
"sar{l}\t%0"
[(set_attr "type" "ishift")
- (set (attr "length")
- (if_then_else (match_operand:SI 0 "register_operand" "")
- (const_string "2")
- (const_string "*")))])
+ (set_attr "length_immediate" "0")
+ (set_attr "mode" "SI")])
(define_insn "*ashrsi3_1_one_bit_zext"
[(set (match_operand:DI 0 "register_operand" "=r")
@@ -12702,7 +12974,8 @@ (define_insn "*ashrsi3_1_one_bit_zext"
&& ix86_binary_operator_ok (ASHIFTRT, SImode, operands)"
"sar{l}\t%k0"
[(set_attr "type" "ishift")
- (set_attr "length" "2")])
+ (set_attr "length_immediate" "0")
+ (set_attr "mode" "SI")])
(define_insn "*ashrsi3_1"
[(set (match_operand:SI 0 "nonimmediate_operand" "=rm,rm")
@@ -12744,10 +13017,8 @@ (define_insn "*ashrsi3_one_bit_cmp"
&& ix86_binary_operator_ok (ASHIFTRT, SImode, operands)"
"sar{l}\t%0"
[(set_attr "type" "ishift")
- (set (attr "length")
- (if_then_else (match_operand:SI 0 "register_operand" "")
- (const_string "2")
- (const_string "*")))])
+ (set_attr "length_immediate" "0")
+ (set_attr "mode" "SI")])
(define_insn "*ashrsi3_one_bit_cconly"
[(set (reg FLAGS_REG)
@@ -12761,7 +13032,8 @@ (define_insn "*ashrsi3_one_bit_cconly"
&& ix86_binary_operator_ok (ASHIFTRT, SImode, operands)"
"sar{l}\t%0"
[(set_attr "type" "ishift")
- (set_attr "length" "2")])
+ (set_attr "length_immediate" "0")
+ (set_attr "mode" "SI")])
(define_insn "*ashrsi3_one_bit_cmp_zext"
[(set (reg FLAGS_REG)
@@ -12777,7 +13049,8 @@ (define_insn "*ashrsi3_one_bit_cmp_zext"
&& ix86_binary_operator_ok (ASHIFTRT, SImode, operands)"
"sar{l}\t%k0"
[(set_attr "type" "ishift")
- (set_attr "length" "2")])
+ (set_attr "length_immediate" "0")
+ (set_attr "mode" "SI")])
;; This pattern can't accept a variable shift count, since shifts by
;; zero don't affect the flags. We assume that shifts by constant
@@ -12843,10 +13116,8 @@ (define_insn "*ashrhi3_1_one_bit"
&& ix86_binary_operator_ok (ASHIFTRT, HImode, operands)"
"sar{w}\t%0"
[(set_attr "type" "ishift")
- (set (attr "length")
- (if_then_else (match_operand 0 "register_operand" "")
- (const_string "2")
- (const_string "*")))])
+ (set_attr "length_immediate" "0")
+ (set_attr "mode" "HI")])
(define_insn "*ashrhi3_1"
[(set (match_operand:HI 0 "nonimmediate_operand" "=rm,rm")
@@ -12876,10 +13147,8 @@ (define_insn "*ashrhi3_one_bit_cmp"
&& ix86_binary_operator_ok (ASHIFTRT, HImode, operands)"
"sar{w}\t%0"
[(set_attr "type" "ishift")
- (set (attr "length")
- (if_then_else (match_operand 0 "register_operand" "")
- (const_string "2")
- (const_string "*")))])
+ (set_attr "length_immediate" "0")
+ (set_attr "mode" "HI")])
(define_insn "*ashrhi3_one_bit_cconly"
[(set (reg FLAGS_REG)
@@ -12893,7 +13162,8 @@ (define_insn "*ashrhi3_one_bit_cconly"
&& ix86_binary_operator_ok (ASHIFTRT, HImode, operands)"
"sar{w}\t%0"
[(set_attr "type" "ishift")
- (set_attr "length" "2")])
+ (set_attr "length_immediate" "0")
+ (set_attr "mode" "HI")])
;; This pattern can't accept a variable shift count, since shifts by
;; zero don't affect the flags. We assume that shifts by constant
@@ -12943,10 +13213,8 @@ (define_insn "*ashrqi3_1_one_bit"
&& ix86_binary_operator_ok (ASHIFTRT, QImode, operands)"
"sar{b}\t%0"
[(set_attr "type" "ishift")
- (set (attr "length")
- (if_then_else (match_operand 0 "register_operand" "")
- (const_string "2")
- (const_string "*")))])
+ (set_attr "length_immediate" "0")
+ (set_attr "mode" "QI")])
(define_insn "*ashrqi3_1_one_bit_slp"
[(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm"))
@@ -12958,10 +13226,8 @@ (define_insn "*ashrqi3_1_one_bit_slp"
&& ix86_binary_operator_ok (ASHIFTRT, QImode, operands)"
"sar{b}\t%0"
[(set_attr "type" "ishift1")
- (set (attr "length")
- (if_then_else (match_operand 0 "register_operand" "")
- (const_string "2")
- (const_string "*")))])
+ (set_attr "length_immediate" "0")
+ (set_attr "mode" "QI")])
(define_insn "*ashrqi3_1"
[(set (match_operand:QI 0 "nonimmediate_operand" "=qm,qm")
@@ -13004,10 +13270,8 @@ (define_insn "*ashrqi3_one_bit_cmp"
&& ix86_binary_operator_ok (ASHIFTRT, QImode, operands)"
"sar{b}\t%0"
[(set_attr "type" "ishift")
- (set (attr "length")
- (if_then_else (match_operand 0 "register_operand" "")
- (const_string "2")
- (const_string "*")))])
+ (set_attr "length_immediate" "0")
+ (set_attr "mode" "QI")])
(define_insn "*ashrqi3_one_bit_cconly"
[(set (reg FLAGS_REG)
@@ -13021,7 +13285,8 @@ (define_insn "*ashrqi3_one_bit_cconly"
&& ix86_binary_operator_ok (ASHIFTRT, QImode, operands)"
"sar{b}\t%0"
[(set_attr "type" "ishift")
- (set_attr "length" "2")])
+ (set_attr "length_immediate" "0")
+ (set_attr "mode" "QI")])
;; This pattern can't accept a variable shift count, since shifts by
;; zero don't affect the flags. We assume that shifts by constant
@@ -13143,10 +13408,8 @@ (define_insn "*lshrdi3_1_one_bit_rex64"
&& ix86_binary_operator_ok (LSHIFTRT, HImode, operands)"
"shr{q}\t%0"
[(set_attr "type" "ishift")
- (set (attr "length")
- (if_then_else (match_operand:DI 0 "register_operand" "")
- (const_string "2")
- (const_string "*")))])
+ (set_attr "length_immediate" "0")
+ (set_attr "mode" "DI")])
(define_insn "*lshrdi3_1_rex64"
[(set (match_operand:DI 0 "nonimmediate_operand" "=rm,rm")
@@ -13177,10 +13440,8 @@ (define_insn "*lshrdi3_cmp_one_bit_rex64
&& ix86_binary_operator_ok (LSHIFTRT, HImode, operands)"
"shr{q}\t%0"
[(set_attr "type" "ishift")
- (set (attr "length")
- (if_then_else (match_operand:DI 0 "register_operand" "")
- (const_string "2")
- (const_string "*")))])
+ (set_attr "length_immediate" "0")
+ (set_attr "mode" "DI")])
(define_insn "*lshrdi3_cconly_one_bit_rex64"
[(set (reg FLAGS_REG)
@@ -13195,7 +13456,8 @@ (define_insn "*lshrdi3_cconly_one_bit_re
&& ix86_binary_operator_ok (LSHIFTRT, HImode, operands)"
"shr{q}\t%0"
[(set_attr "type" "ishift")
- (set_attr "length" "2")])
+ (set_attr "length_immediate" "0")
+ (set_attr "mode" "DI")])
;; This pattern can't accept a variable shift count, since shifts by
;; zero don't affect the flags. We assume that shifts by constant
@@ -13280,10 +13542,8 @@ (define_insn "*lshrsi3_1_one_bit"
&& ix86_binary_operator_ok (LSHIFTRT, HImode, operands)"
"shr{l}\t%0"
[(set_attr "type" "ishift")
- (set (attr "length")
- (if_then_else (match_operand:SI 0 "register_operand" "")
- (const_string "2")
- (const_string "*")))])
+ (set_attr "length_immediate" "0")
+ (set_attr "mode" "SI")])
(define_insn "*lshrsi3_1_one_bit_zext"
[(set (match_operand:DI 0 "register_operand" "=r")
@@ -13295,7 +13555,8 @@ (define_insn "*lshrsi3_1_one_bit_zext"
&& ix86_binary_operator_ok (LSHIFTRT, HImode, operands)"
"shr{l}\t%k0"
[(set_attr "type" "ishift")
- (set_attr "length" "2")])
+ (set_attr "length_immediate" "0")
+ (set_attr "mode" "SI")])
(define_insn "*lshrsi3_1"
[(set (match_operand:SI 0 "nonimmediate_operand" "=rm,rm")
@@ -13338,10 +13599,8 @@ (define_insn "*lshrsi3_one_bit_cmp"
&& ix86_binary_operator_ok (LSHIFTRT, HImode, operands)"
"shr{l}\t%0"
[(set_attr "type" "ishift")
- (set (attr "length")
- (if_then_else (match_operand:SI 0 "register_operand" "")
- (const_string "2")
- (const_string "*")))])
+ (set_attr "length_immediate" "0")
+ (set_attr "mode" "SI")])
(define_insn "*lshrsi3_one_bit_cconly"
[(set (reg FLAGS_REG)
@@ -13355,7 +13614,8 @@ (define_insn "*lshrsi3_one_bit_cconly"
&& ix86_binary_operator_ok (LSHIFTRT, HImode, operands)"
"shr{l}\t%0"
[(set_attr "type" "ishift")
- (set_attr "length" "2")])
+ (set_attr "length_immediate" "0")
+ (set_attr "mode" "SI")])
(define_insn "*lshrsi3_cmp_one_bit_zext"
[(set (reg FLAGS_REG)
@@ -13371,7 +13631,8 @@ (define_insn "*lshrsi3_cmp_one_bit_zext"
&& ix86_binary_operator_ok (LSHIFTRT, HImode, operands)"
"shr{l}\t%k0"
[(set_attr "type" "ishift")
- (set_attr "length" "2")])
+ (set_attr "length_immediate" "0")
+ (set_attr "mode" "SI")])
;; This pattern can't accept a variable shift count, since shifts by
;; zero don't affect the flags. We assume that shifts by constant
@@ -13437,10 +13698,8 @@ (define_insn "*lshrhi3_1_one_bit"
&& ix86_binary_operator_ok (LSHIFTRT, HImode, operands)"
"shr{w}\t%0"
[(set_attr "type" "ishift")
- (set (attr "length")
- (if_then_else (match_operand 0 "register_operand" "")
- (const_string "2")
- (const_string "*")))])
+ (set_attr "length_immediate" "0")
+ (set_attr "mode" "HI")])
(define_insn "*lshrhi3_1"
[(set (match_operand:HI 0 "nonimmediate_operand" "=rm,rm")
@@ -13470,10 +13729,8 @@ (define_insn "*lshrhi3_one_bit_cmp"
&& ix86_binary_operator_ok (LSHIFTRT, HImode, operands)"
"shr{w}\t%0"
[(set_attr "type" "ishift")
- (set (attr "length")
- (if_then_else (match_operand:SI 0 "register_operand" "")
- (const_string "2")
- (const_string "*")))])
+ (set_attr "length_immediate" "0")
+ (set_attr "mode" "HI")])
(define_insn "*lshrhi3_one_bit_cconly"
[(set (reg FLAGS_REG)
@@ -13487,7 +13744,8 @@ (define_insn "*lshrhi3_one_bit_cconly"
&& ix86_binary_operator_ok (LSHIFTRT, HImode, operands)"
"shr{w}\t%0"
[(set_attr "type" "ishift")
- (set_attr "length" "2")])
+ (set_attr "length_immediate" "0")
+ (set_attr "mode" "HI")])
;; This pattern can't accept a variable shift count, since shifts by
;; zero don't affect the flags. We assume that shifts by constant
@@ -13537,10 +13795,8 @@ (define_insn "*lshrqi3_1_one_bit"
&& ix86_binary_operator_ok (LSHIFTRT, QImode, operands)"
"shr{b}\t%0"
[(set_attr "type" "ishift")
- (set (attr "length")
- (if_then_else (match_operand 0 "register_operand" "")
- (const_string "2")
- (const_string "*")))])
+ (set_attr "length_immediate" "0")
+ (set_attr "mode" "QI")])
(define_insn "*lshrqi3_1_one_bit_slp"
[(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm"))
@@ -13551,10 +13807,8 @@ (define_insn "*lshrqi3_1_one_bit_slp"
&& (TARGET_SHIFT1 || optimize_function_for_size_p (cfun))"
"shr{b}\t%0"
[(set_attr "type" "ishift1")
- (set (attr "length")
- (if_then_else (match_operand 0 "register_operand" "")
- (const_string "2")
- (const_string "*")))])
+ (set_attr "length_immediate" "0")
+ (set_attr "mode" "QI")])
(define_insn "*lshrqi3_1"
[(set (match_operand:QI 0 "nonimmediate_operand" "=qm,qm")
@@ -13597,10 +13851,8 @@ (define_insn "*lshrqi2_one_bit_cmp"
&& ix86_binary_operator_ok (LSHIFTRT, QImode, operands)"
"shr{b}\t%0"
[(set_attr "type" "ishift")
- (set (attr "length")
- (if_then_else (match_operand:SI 0 "register_operand" "")
- (const_string "2")
- (const_string "*")))])
+ (set_attr "length_immediate" "0")
+ (set_attr "mode" "QI")])
(define_insn "*lshrqi2_one_bit_cconly"
[(set (reg FLAGS_REG)
@@ -13614,7 +13866,8 @@ (define_insn "*lshrqi2_one_bit_cconly"
&& ix86_binary_operator_ok (LSHIFTRT, QImode, operands)"
"shr{b}\t%0"
[(set_attr "type" "ishift")
- (set_attr "length" "2")])
+ (set_attr "length_immediate" "0")
+ (set_attr "mode" "QI")])
;; This pattern can't accept a variable shift count, since shifts by
;; zero don't affect the flags. We assume that shifts by constant
@@ -13703,10 +13956,8 @@ (define_insn "*rotlsi3_1_one_bit_rex64"
&& ix86_binary_operator_ok (ROTATE, DImode, operands)"
"rol{q}\t%0"
[(set_attr "type" "rotate")
- (set (attr "length")
- (if_then_else (match_operand:DI 0 "register_operand" "")
- (const_string "2")
- (const_string "*")))])
+ (set_attr "length_immediate" "0")
+ (set_attr "mode" "DI")])
(define_insn "*rotldi3_1_rex64"
[(set (match_operand:DI 0 "nonimmediate_operand" "=rm,rm")
@@ -13736,10 +13987,8 @@ (define_insn "*rotlsi3_1_one_bit"
&& ix86_binary_operator_ok (ROTATE, SImode, operands)"
"rol{l}\t%0"
[(set_attr "type" "rotate")
- (set (attr "length")
- (if_then_else (match_operand:SI 0 "register_operand" "")
- (const_string "2")
- (const_string "*")))])
+ (set_attr "length_immediate" "0")
+ (set_attr "mode" "SI")])
(define_insn "*rotlsi3_1_one_bit_zext"
[(set (match_operand:DI 0 "register_operand" "=r")
@@ -13752,7 +14001,8 @@ (define_insn "*rotlsi3_1_one_bit_zext"
&& ix86_binary_operator_ok (ROTATE, SImode, operands)"
"rol{l}\t%k0"
[(set_attr "type" "rotate")
- (set_attr "length" "2")])
+ (set_attr "length_immediate" "0")
+ (set_attr "mode" "SI")])
(define_insn "*rotlsi3_1"
[(set (match_operand:SI 0 "nonimmediate_operand" "=rm,rm")
@@ -13795,10 +14045,8 @@ (define_insn "*rotlhi3_1_one_bit"
&& ix86_binary_operator_ok (ROTATE, HImode, operands)"
"rol{w}\t%0"
[(set_attr "type" "rotate")
- (set (attr "length")
- (if_then_else (match_operand 0 "register_operand" "")
- (const_string "2")
- (const_string "*")))])
+ (set_attr "length_immediate" "0")
+ (set_attr "mode" "HI")])
(define_insn "*rotlhi3_1"
[(set (match_operand:HI 0 "nonimmediate_operand" "=rm,rm")
@@ -13838,10 +14086,8 @@ (define_insn "*rotlqi3_1_one_bit_slp"
&& (TARGET_SHIFT1 || optimize_function_for_size_p (cfun))"
"rol{b}\t%0"
[(set_attr "type" "rotate1")
- (set (attr "length")
- (if_then_else (match_operand 0 "register_operand" "")
- (const_string "2")
- (const_string "*")))])
+ (set_attr "length_immediate" "0")
+ (set_attr "mode" "QI")])
(define_insn "*rotlqi3_1_one_bit"
[(set (match_operand:QI 0 "nonimmediate_operand" "=qm")
@@ -13852,10 +14098,8 @@ (define_insn "*rotlqi3_1_one_bit"
&& ix86_binary_operator_ok (ROTATE, QImode, operands)"
"rol{b}\t%0"
[(set_attr "type" "rotate")
- (set (attr "length")
- (if_then_else (match_operand 0 "register_operand" "")
- (const_string "2")
- (const_string "*")))])
+ (set_attr "length_immediate" "0")
+ (set_attr "mode" "QI")])
(define_insn "*rotlqi3_1_slp"
[(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm,qm"))
@@ -13935,10 +14179,8 @@ (define_insn "*rotrdi3_1_one_bit_rex64"
&& ix86_binary_operator_ok (ROTATERT, DImode, operands)"
"ror{q}\t%0"
[(set_attr "type" "rotate")
- (set (attr "length")
- (if_then_else (match_operand:DI 0 "register_operand" "")
- (const_string "2")
- (const_string "*")))])
+ (set_attr "length_immediate" "0")
+ (set_attr "mode" "DI")])
(define_insn "*rotrdi3_1_rex64"
[(set (match_operand:DI 0 "nonimmediate_operand" "=rm,rm")
@@ -13968,10 +14210,8 @@ (define_insn "*rotrsi3_1_one_bit"
&& ix86_binary_operator_ok (ROTATERT, SImode, operands)"
"ror{l}\t%0"
[(set_attr "type" "rotate")
- (set (attr "length")
- (if_then_else (match_operand:SI 0 "register_operand" "")
- (const_string "2")
- (const_string "*")))])
+ (set_attr "length_immediate" "0")
+ (set_attr "mode" "SI")])
(define_insn "*rotrsi3_1_one_bit_zext"
[(set (match_operand:DI 0 "register_operand" "=r")
@@ -13984,10 +14224,8 @@ (define_insn "*rotrsi3_1_one_bit_zext"
&& ix86_binary_operator_ok (ROTATERT, SImode, operands)"
"ror{l}\t%k0"
[(set_attr "type" "rotate")
- (set (attr "length")
- (if_then_else (match_operand:SI 0 "register_operand" "")
- (const_string "2")
- (const_string "*")))])
+ (set_attr "length_immediate" "0")
+ (set_attr "mode" "SI")])
(define_insn "*rotrsi3_1"
[(set (match_operand:SI 0 "nonimmediate_operand" "=rm,rm")
@@ -14030,10 +14268,8 @@ (define_insn "*rotrhi3_one_bit"
&& ix86_binary_operator_ok (ROTATERT, HImode, operands)"
"ror{w}\t%0"
[(set_attr "type" "rotate")
- (set (attr "length")
- (if_then_else (match_operand 0 "register_operand" "")
- (const_string "2")
- (const_string "*")))])
+ (set_attr "length_immediate" "0")
+ (set_attr "mode" "HI")])
(define_insn "*rotrhi3_1"
[(set (match_operand:HI 0 "nonimmediate_operand" "=rm,rm")
@@ -14073,10 +14309,8 @@ (define_insn "*rotrqi3_1_one_bit"
&& ix86_binary_operator_ok (ROTATERT, QImode, operands)"
"ror{b}\t%0"
[(set_attr "type" "rotate")
- (set (attr "length")
- (if_then_else (match_operand 0 "register_operand" "")
- (const_string "2")
- (const_string "*")))])
+ (set_attr "length_immediate" "0")
+ (set_attr "mode" "QI")])
(define_insn "*rotrqi3_1_one_bit_slp"
[(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm"))
@@ -14087,10 +14321,8 @@ (define_insn "*rotrqi3_1_one_bit_slp"
&& (TARGET_SHIFT1 || optimize_function_for_size_p (cfun))"
"ror{b}\t%0"
[(set_attr "type" "rotate1")
- (set (attr "length")
- (if_then_else (match_operand 0 "register_operand" "")
- (const_string "2")
- (const_string "*")))])
+ (set_attr "length_immediate" "0")
+ (set_attr "mode" "QI")])
(define_insn "*rotrqi3_1"
[(set (match_operand:QI 0 "nonimmediate_operand" "=qm,qm")
@@ -14198,7 +14430,8 @@ (define_insn "*btsq"
(clobber (reg:CC FLAGS_REG))]
"TARGET_64BIT && (TARGET_USE_BT || reload_completed)"
"bts{q}\t{%1, %0|%0, %1}"
- [(set_attr "type" "alu1")])
+ [(set_attr "type" "alu1")
+ (set_attr "prefix_0f" "1")])
(define_insn "*btrq"
[(set (zero_extract:DI (match_operand:DI 0 "register_operand" "+r")
@@ -14208,7 +14441,8 @@ (define_insn "*btrq"
(clobber (reg:CC FLAGS_REG))]
"TARGET_64BIT && (TARGET_USE_BT || reload_completed)"
"btr{q}\t{%1, %0|%0, %1}"
- [(set_attr "type" "alu1")])
+ [(set_attr "type" "alu1")
+ (set_attr "prefix_0f" "1")])
(define_insn "*btcq"
[(set (zero_extract:DI (match_operand:DI 0 "register_operand" "+r")
@@ -14218,7 +14452,8 @@ (define_insn "*btcq"
(clobber (reg:CC FLAGS_REG))]
"TARGET_64BIT && (TARGET_USE_BT || reload_completed)"
"btc{q}\t{%1, %0|%0, %1}"
- [(set_attr "type" "alu1")])
+ [(set_attr "type" "alu1")
+ (set_attr "prefix_0f" "1")])
;; Allow Nocona to avoid these instructions if a register is available.
@@ -14329,7 +14564,8 @@ (define_insn "*btdi_rex64"
(const_int 0)))]
"TARGET_64BIT && (TARGET_USE_BT || optimize_function_for_size_p (cfun))"
"bt{q}\t{%1, %0|%0, %1}"
- [(set_attr "type" "alu1")])
+ [(set_attr "type" "alu1")
+ (set_attr "prefix_0f" "1")])
(define_insn "*btsi"
[(set (reg:CCC FLAGS_REG)
@@ -14341,7 +14577,8 @@ (define_insn "*btsi"
(const_int 0)))]
"TARGET_USE_BT || optimize_function_for_size_p (cfun)"
"bt{l}\t{%1, %0|%0, %1}"
- [(set_attr "type" "alu1")])
+ [(set_attr "type" "alu1")
+ (set_attr "prefix_0f" "1")])
;; Store-flag instructions.
@@ -15487,7 +15724,7 @@ (define_insn "return_internal_long"
(unspec [(const_int 0)] UNSPEC_REP)]
"reload_completed"
"rep\;ret"
- [(set_attr "length" "1")
+ [(set_attr "length" "2")
(set_attr "atom_unit" "jeu")
(set_attr "length_immediate" "0")
(set_attr "prefix_rep" "1")
@@ -19365,6 +19602,7 @@ (define_insn "*strmovqi_rex_1"
"movsb"
[(set_attr "type" "str")
(set_attr "memory" "both")
+ (set_attr "prefix_rex" "0")
(set_attr "mode" "QI")])
(define_expand "rep_mov"
@@ -19621,6 +19859,7 @@ (define_insn "*strsetqi_rex_1"
"stosb"
[(set_attr "type" "str")
(set_attr "memory" "store")
+ (set_attr "prefix_rex" "0")
(set_attr "mode" "QI")])
(define_expand "rep_stos"
@@ -19714,6 +19953,7 @@ (define_insn "*rep_stosqi_rex64"
[(set_attr "type" "str")
(set_attr "prefix_rep" "1")
(set_attr "memory" "store")
+ (set_attr "prefix_rex" "0")
(set_attr "mode" "QI")])
(define_expand "cmpstrnsi"
@@ -19840,6 +20080,7 @@ (define_insn "*cmpstrnqi_nz_rex_1"
"repz cmpsb"
[(set_attr "type" "str")
(set_attr "mode" "QI")
+ (set_attr "prefix_rex" "0")
(set_attr "prefix_rep" "1")])
;; The same, but the count is not known to not be zero.
@@ -19893,6 +20134,7 @@ (define_insn "*cmpstrnqi_rex_1"
"repz cmpsb"
[(set_attr "type" "str")
(set_attr "mode" "QI")
+ (set_attr "prefix_rex" "0")
(set_attr "prefix_rep" "1")])
(define_expand "strlensi"
@@ -19954,6 +20196,7 @@ (define_insn "*strlenqi_rex_1"
"repnz scasb"
[(set_attr "type" "str")
(set_attr "mode" "QI")
+ (set_attr "prefix_rex" "0")
(set_attr "prefix_rep" "1")])
;; Peephole optimizations to clean up after cmpstrn*. This should be
@@ -20474,6 +20717,14 @@ (define_insn "pro_epilogue_adjust_stack_
(const_string "imov")
]
(const_string "lea")))
+ (set (attr "length_immediate")
+ (cond [(eq_attr "type" "imov")
+ (const_string "0")
+ (and (eq_attr "type" "alu")
+ (match_operand 2 "const128_operand" ""))
+ (const_string "1")
+ ]
+ (const_string "*")))
(set_attr "mode" "SI")])
(define_insn "pro_epilogue_adjust_stack_rex64"
@@ -20518,6 +20769,14 @@ (define_insn "pro_epilogue_adjust_stack_
(const_string "imov")
]
(const_string "lea")))
+ (set (attr "length_immediate")
+ (cond [(eq_attr "type" "imov")
+ (const_string "0")
+ (and (eq_attr "type" "alu")
+ (match_operand 2 "const128_operand" ""))
+ (const_string "1")
+ ]
+ (const_string "*")))
(set_attr "mode" "DI")])
(define_insn "pro_epilogue_adjust_stack_rex64_2"
--- gcc/config/i386/predicates.md (revision 147701)
+++ gcc/config/i386/predicates.md (working copy)
@@ -76,6 +76,14 @@ (define_predicate "flags_reg_operand"
(and (match_code "reg")
(match_test "REGNO (op) == FLAGS_REG")))
+;; Return true if op is a QImode register operand other than
+;; %[abcd][hl].
+(define_predicate "ext_QIreg_operand"
+ (and (match_code "reg")
+ (match_test "TARGET_64BIT
+ && GET_MODE (op) == QImode
+ && REGNO (op) > BX_REG")))
+
;; Return true if op is not xmm0 register.
(define_predicate "reg_not_xmm0_operand"
(and (match_operand 0 "register_operand")
@@ -574,6 +582,11 @@ (define_predicate "const8_operand"
(and (match_code "const_int")
(match_test "INTVAL (op) == 8")))
+;; Match exactly 128.
+(define_predicate "const128_operand"
+ (and (match_code "const_int")
+ (match_test "INTVAL (op) == 128")))
+
;; Match 2, 4, or 8. Used for leal multiplicands.
(define_predicate "const248_operand"
(match_code "const_int")
@@ -878,6 +891,9 @@ (define_predicate "memory_displacement_o
struct ix86_address parts;
int ok;
+ if (TARGET_64BIT)
+ return 0;
+
ok = ix86_decompose_address (XEXP (op, 0), &parts);
gcc_assert (ok);
-------------- next part --------------
A non-text attachment was scrubbed...
Name: analyze.S.-dp.sh
Type: application/x-sh
Size: 920 bytes
Desc: not available
URL: <http://gcc.gnu.org/pipermail/gcc-patches/attachments/20090520/6bb58c19/attachment.sh>
-------------- next part --------------
A non-text attachment was scrubbed...
Name: results.S.-dp.tar.bz2
Type: application/x-bzip2
Size: 40454 bytes
Desc: not available
URL: <http://gcc.gnu.org/pipermail/gcc-patches/attachments/20090520/6bb58c19/attachment.bz2>
More information about the Gcc-patches
mailing list