Commit 014753cc by Uros Bizjak

i386.md (DWI): New mode iterator.

	* config/i386/i386.md (DWI): New mode iterator.
	(S): New mode attribute.
	(shift_operand): Ditto.
	(shift_immediate_operand): Ditto.
	(ashl_input_operand): Ditto.
	(ashl<mode>3): Macroize expander from ashl{qi,hi,si,di,ti}3_1
	using SDWIM mode iterator.
	(*ashl<mode>3_doubleword): New insn_and_split_pattern.  Macroize
	pattern from *ashl{di,ti}3_1 and corresponding splitters using
	DWI mode iterator.
	(*ashl<mode>3_doubleword peephole2): Macroize peephole2 pattern
	from corresponding peephole2 patterns.
	(x86_shift<mode>_adj_1): Macroize expander from x86_shift_adj_1
	and x86_64_shift_adj_1 using SWI48 mode iterator.
	(x86_shift<mode>_adj_2): Ditto.
	(*ashldi3_1_rex64): Split TYPE_LEA pattern.
	(*ashl<mode>3_1): Macroize insn from *ashlsi3_1 and *ashldi3_1_rex64
	using SWI48 mode iterator.
	(*ashl<mode>3_cmp): Macroize insn from *ashl{qi,hi,si}3_cmp and
	*ashldi3_cmp_rex64 using SWI mode iterator.
	(*ashl<mode>3_cconly): Macroize insn from *ashl{qi,hi,si}3_cconly and
	*ashldi3_cconly_rex64 using SWI mode iterator.
	* config/i386/i386.c (ix86_split_ashl): Update for renamed
	x86_shift<mode>_adj_{1,2}.
	(ix86_split_ashr): Ditto.
	(ix86_split_lshr): Ditto.

From-SVN: r158163
parent 88dd7150
2010-04-09 Uros Bizjak <ubizjak@gmail.com>
* config/i386/i386.md (DWI): New mode iterator.
(S): New mode attribute.
(shift_operand): Ditto.
(shift_immediate_operand): Ditto.
(ashl_input_operand): Ditto.
(ashl<mode>3): Macroize expander from ashl{qi,hi,si,di,ti}3_1
using SDWIM mode iterator.
(*ashl<mode>3_doubleword): New insn_and_split_pattern. Macroize
pattern from *ashl{di,ti}3_1 and corresponding splitters using
DWI mode iterator.
(*ashl<mode>3_doubleword peephole2): Macroize peephole2 pattern
from corresponding peephole2 patterns.
(x86_shift<mode>_adj_1): Macroize expander from x86_shift_adj_1
and x86_64_shift_adj_1 using SWI48 mode iterator.
(x86_shift<mode>_adj_2): Ditto.
(*ashldi3_1_rex64): Split TYPE_LEA pattern.
(*ashl<mode>3_1): Macroize insn from *ashlsi3_1 and *ashldi3_1_rex64
using SWI48 mode iterator.
(*ashl<mode>3_cmp): Macroize insn from *ashl{qi,hi,si}3_cmp and
*ashldi3_cmp_rex64 using SWI mode iterator.
(*ashl<mode>3_cconly): Macroize insn from *ashl{qi,hi,si}3_cconly and
*ashldi3_cconly_rex64 using SWI mode iterator.
* config/i386/i386.c (ix86_split_ashl): Update for renamed
x86_shift<mode>_adj_{1,2}.
(ix86_split_ashr): Ditto.
(ix86_split_lshr): Ditto.
2010-04-09 Richard Guenther <rguenther@suse.de>
* target.h (builtin_conversion): Pass in input and output types.
......@@ -58,8 +87,7 @@
(x86_this_parameter): Likewise.
(x86_output_mi_thunk): Likewise.
(ix86_attribute_table): Add description for thiscall attribute.
* config/i386/i386.h (ix86_args): Adjust comment for member
fastcall.
* config/i386/i386.h (ix86_args): Adjust comment for member fastcall.
* doc/extend.texi: Add documentation for thiscall.
2010-04-09 Manuel López-Ibáñez <manu@gcc.gnu.org>
......@@ -83,8 +111,8 @@
PR tree-optimization/42720
* tree-ssa-loop-unswitch.c (tree_ssa_unswitch_loops): Move one-time
loop unswitch conditions here from
(tree_unswitch_single_loop).
loop unswitch conditions here from ...
(tree_unswitch_single_loop): ... here.
2010-04-08 Sebastian Pop <sebastian.pop@amd.com>
......@@ -108,14 +136,15 @@
2010-04-08 Christian Borntraeger <borntraeger@de.ibm.com>
Wolfgang Gellerich <gellerich@de.ibm.com>
Implement target hook for loop unrolling
* target.h (loop_unroll_adjust): Add a new target hook function.
* target-def.h (TARGET_LOOP_UNROLL_ADJUST): Likewise.
* doc/tm.texi (TARGET_LOOP_UNROLL_ADJUST): Document it.
* config/s390/s390.c (TARGET_LOOP_UNROLL_ADJUST): Define it.
(s390_loop_unroll_adjust): Implement the new target hook for s390.
* loop-unroll.c (decide_unroll_runtime_iterations): Call loop unroll target hook
(decide_unroll_stupid): Likewise.
Implement target hook for loop unrolling
* target.h (loop_unroll_adjust): Add a new target hook function.
* target-def.h (TARGET_LOOP_UNROLL_ADJUST): Likewise.
* doc/tm.texi (TARGET_LOOP_UNROLL_ADJUST): Document it.
* config/s390/s390.c (TARGET_LOOP_UNROLL_ADJUST): Define it.
(s390_loop_unroll_adjust): Implement the new target hook for s390.
* loop-unroll.c (decide_unroll_runtime_iterations): Call loop unroll
target hook.
(decide_unroll_stupid): Likewise.
2010-04-08 Rainer Orth <ro@CeBiTec.Uni-Bielefeld.DE>
......@@ -131,8 +160,8 @@
2010-04-08 Wolfgang Gellerich <gellerich@de.ibm.com>
* config/s390/s390.c (override_options): Adjust the z10
defaults for max-unroll-times, max-completely-peeled-insns
and max-completely-peel-times.
defaults for max-unroll-times, max-completely-peeled-insns
and max-completely-peel-times.
2010-04-08 Andreas Krebbel <Andreas.Krebbel@de.ibm.com>
......@@ -283,8 +312,7 @@
* tree-ssa-forwprop.c (forward_propagate_into_gimple_cond):
Handle reversed comparison ops.
* tree-sra.c (asm_visit_addr): Use get_base_address.
* ipa-prop.c (visit_store_addr_for_mod_analysis): Use
get_base_address.
* ipa-prop.c (visit_store_addr_for_mod_analysis): Use get_base_address.
* ipa-reference.c (mark_address): Use get_base_address.
2010-04-07 Richard Guenther <rguenther@suse.de>
......@@ -305,10 +333,8 @@
* doc/invoke.texi (-fargument-alias, -fargument-noalias,
-fargument-noalias-global, -fargument-noalias-anything): Remove.
* common.opt: Likewise.
* tree-ssa-structalias.c (intra_create_variable_infos): Adjust
comment.
* alias.c (base_alias_check): Remove flag_argument_noalias
handling.
* tree-ssa-structalias.c (intra_create_variable_infos): Adjust comment.
* alias.c (base_alias_check): Remove flag_argument_noalias handling.
(nonoverlapping_memrefs_p): Likewise.
* emit-rtl.c (set_mem_attributes_minus_bitpos): Likewise.
* opts.c (common_handle_option): Handle OPT_fargument_alias,
......@@ -318,8 +344,7 @@
2010-04-07 Richard Guenther <rguenther@suse.de>
PR tree-optimization/43270
* tree-vrp.c (check_array_ref): Fix flexible array member
detection.
* tree-vrp.c (check_array_ref): Fix flexible array member detection.
* tree-ssa-sccvn.h (fully_constant_vn_reference_p): Declare.
* tree-ssa-pre.c (phi_translate_1): Adjust.
(fully_constant_expression): Split out vn_reference handling to ...
......@@ -340,15 +365,13 @@
2010-04-07 Rainer Orth <ro@CeBiTec.Uni-Bielefeld.DE>
* config.gcc (i[34567]86-*-solaris2*): Default with_tune_32 to
generic.
* config.gcc (i[34567]86-*-solaris2*): Default with_tune_32 to generic.
2010-04-07 Richard Guenther <rguenther@suse.de>
PR middle-end/42617
* expr.c (expand_expr_real_1): For TARGET_MEM_REFs with
pointer bases build simple mem attributes to retain
points-to information.
* expr.c (expand_expr_real_1): For TARGET_MEM_REFs with pointer
bases build simple mem attributes to retain points-to information.
2010-04-07 Richard Guenther <rguenther@suse.de>
......@@ -361,8 +384,7 @@
PR middle-end/42617
* emit-rtl.c (set_mem_attributes_minus_bitpos): Do not
discard plain indirect references.
* fold-const.c (operand_equal_p): Guard against NULL_TREE
type.
* fold-const.c (operand_equal_p): Guard against NULL_TREE type.
* tree.c (tree_nop_conversion): Likewise.
2010-04-07 Dodji Seketeli <dodji@redhat.com>
......@@ -391,11 +413,13 @@
PR middle-end/43519
* graphite-clast-to-gimple.c (max_signed_precision_type): Use
lang_hooks.types.type_for_size instead of build_nonstandard_integer_type.
lang_hooks.types.type_for_size instead of
build_nonstandard_integer_type.
When converting an unsigned type to signed, double its precision.
(gcc_type_for_interval): Use lang_hooks.types.type_for_size.
(gcc_type_for_iv_of_clast_loop): Call max_signed_precision_type.
(graphite_create_new_loop_guard): When ub + 1 wraps around, use lb <= ub.
(graphite_create_new_loop_guard): When ub + 1 wraps around,
use lb <= ub.
2010-04-06 Sebastian Pop <sebastian.pop@amd.com>
......@@ -631,8 +655,7 @@
2010-04-02 Joseph Myers <joseph@codesourcery.com>
* read-rtl.c (read_rtx_1): Give an error for EOF while looking for
']'.
* read-rtl.c (read_rtx_1): Give an error for EOF while looking for ']'.
2010-04-02 Richard Earnshaw <rearnsha@arm.com>
......@@ -656,12 +679,12 @@
2010-04-01 Ralf Corsépius <ralf.corsepius@rtems.org>
* config.gcc (lm32-*-rtems*): Add t-lm32.
* config.gcc (lm32-*-rtems*): Add t-lm32.
2010-04-01 Joel Sherrill <joel.sherrill@oarcorp.com>
* config.gcc: Add lm32-*-rtems*.
* config/lm32/rtems.h: New file.
* config.gcc: Add lm32-*-rtems*.
* config/lm32/rtems.h: New file.
2010-04-01 Dave Korn <dave.korn.cygwin@gmail.com>
......@@ -714,7 +737,7 @@
PR middle-end/43602
Revert
2010-03-30 Seongbae Park <seongbae.park@gmail.com>
Jack Howarth <howarth@bromo.med.uc.edu>
Jack Howarth <howarth@bromo.med.uc.edu>
* tree-profile.c (tree_init_ic_make_global_vars): Make static
variables TLS.
......@@ -746,8 +769,7 @@
Update IDO URL.
Document GNU as requirement.
Update configure requirements.
(Specific, mips-sgi-irix6): Document IRIX 6 < 6.5 obsoletion,
removal.
(Specific, mips-sgi-irix6): Document IRIX 6 < 6.5 obsoletion, removal.
Recomment IRIX 6.5.18+.
Document IDF/IDL requirement.
Document GNU as requirement.
......
......@@ -17130,20 +17130,22 @@ ix86_split_ashl (rtx *operands, rtx scratch, enum machine_mode mode)
: gen_x86_64_shld) (high[0], low[0], operands[2]));
}
emit_insn ((mode == DImode ? gen_ashlsi3 : gen_ashldi3) (low[0], low[0], operands[2]));
emit_insn ((mode == DImode
? gen_ashlsi3
: gen_ashldi3) (low[0], low[0], operands[2]));
if (TARGET_CMOVE && scratch)
{
ix86_expand_clear (scratch);
emit_insn ((mode == DImode
? gen_x86_shift_adj_1
: gen_x86_64_shift_adj_1) (high[0], low[0], operands[2],
scratch));
? gen_x86_shiftsi_adj_1
: gen_x86_shiftdi_adj_1) (high[0], low[0], operands[2],
scratch));
}
else
emit_insn ((mode == DImode
? gen_x86_shift_adj_2
: gen_x86_64_shift_adj_2) (high[0], low[0], operands[2]));
? gen_x86_shiftsi_adj_2
: gen_x86_shiftdi_adj_2) (high[0], low[0], operands[2]));
}
void
......@@ -17216,9 +17218,9 @@ ix86_split_ashr (rtx *operands, rtx scratch, enum machine_mode mode)
: gen_ashrdi3) (scratch, scratch,
GEN_INT (single_width - 1)));
emit_insn ((mode == DImode
? gen_x86_shift_adj_1
: gen_x86_64_shift_adj_1) (low[0], high[0], operands[2],
scratch));
? gen_x86_shiftsi_adj_1
: gen_x86_shiftdi_adj_1) (low[0], high[0], operands[2],
scratch));
}
else
emit_insn ((mode == DImode
......@@ -17281,14 +17283,14 @@ ix86_split_lshr (rtx *operands, rtx scratch, enum machine_mode mode)
{
ix86_expand_clear (scratch);
emit_insn ((mode == DImode
? gen_x86_shift_adj_1
: gen_x86_64_shift_adj_1) (low[0], high[0], operands[2],
scratch));
? gen_x86_shiftsi_adj_1
: gen_x86_shiftdi_adj_1) (low[0], high[0], operands[2],
scratch));
}
else
emit_insn ((mode == DImode
? gen_x86_shift_adj_2
: gen_x86_64_shift_adj_2) (low[0], high[0], operands[2]));
? gen_x86_shiftsi_adj_2
: gen_x86_shiftdi_adj_2) (low[0], high[0], operands[2]));
}
}
......
......@@ -771,14 +771,18 @@
(define_mode_iterator SWIM248 [(HI "TARGET_HIMODE_MATH")
SI (DI "TARGET_64BIT")])
;; Half mode for double word integer modes.
(define_mode_iterator DWIH [(SI "!TARGET_64BIT")
(DI "TARGET_64BIT")])
;; Double word integer modes.
(define_mode_iterator DWI [(DI "!TARGET_64BIT")
(TI "TARGET_64BIT")])
;; Double word integer modes as mode attribute.
(define_mode_attr DWI [(SI "DI") (DI "TI")])
(define_mode_attr dwi [(SI "di") (DI "ti")])
;; Half mode for double word integer modes.
(define_mode_iterator DWIH [(SI "!TARGET_64BIT")
(DI "TARGET_64BIT")])
;; Instruction suffix for integer modes.
(define_mode_attr imodesuffix [(QI "b") (HI "w") (SI "l") (DI "q")])
......@@ -794,6 +798,9 @@
;; Immediate operand constraint for double integer modes.
(define_mode_attr di [(SI "iF") (DI "e")])
;; Immediate operand constraint for shifts.
(define_mode_attr S [(QI "I") (HI "I") (SI "I") (DI "J") (TI "O")])
;; General operand predicate for integer modes.
(define_mode_attr general_operand
[(QI "general_operand")
......@@ -809,6 +816,29 @@
(SI "general_operand")
(DI "x86_64_szext_general_operand")])
;; Operand predicate for shifts.
(define_mode_attr shift_operand
[(QI "nonimmediate_operand")
(HI "nonimmediate_operand")
(SI "nonimmediate_operand")
(DI "shiftdi_operand")
(TI "register_operand")])
;; Operand predicate for shift argument.
(define_mode_attr shift_immediate_operand
[(QI "const_1_to_31_operand")
(HI "const_1_to_31_operand")
(SI "const_1_to_31_operand")
(DI "const_1_to_63_operand")])
;; Input operand predicate for arithmetic left shifts.
(define_mode_attr ashl_input_operand
[(QI "nonimmediate_operand")
(HI "nonimmediate_operand")
(SI "nonimmediate_operand")
(DI "ashldi_input_operand")
(TI "reg_or_pm1_operand")])
;; SSE and x87 SFmode and DFmode floating point modes
(define_mode_iterator MODEF [SF DF])
......@@ -9523,42 +9553,40 @@
;; shift pair, instead using moves and sign extension for counts greater
;; than 31.
(define_expand "ashlti3"
[(set (match_operand:TI 0 "register_operand" "")
(ashift:TI (match_operand:TI 1 "reg_or_pm1_operand" "")
(match_operand:QI 2 "nonmemory_operand" "")))]
"TARGET_64BIT"
"ix86_expand_binary_operator (ASHIFT, TImode, operands); DONE;")
(define_expand "ashl<mode>3"
[(set (match_operand:SDWIM 0 "<shift_operand>" "")
(ashift:SDWIM (match_operand:SDWIM 1 "<ashl_input_operand>" "")
(match_operand:QI 2 "nonmemory_operand" "")))]
""
"ix86_expand_binary_operator (ASHIFT, <MODE>mode, operands); DONE;")
(define_insn "*ashlti3_1"
[(set (match_operand:TI 0 "register_operand" "=&r,r")
(ashift:TI (match_operand:TI 1 "reg_or_pm1_operand" "n,0")
(match_operand:QI 2 "nonmemory_operand" "Oc,Oc")))
(define_insn_and_split "*ashl<mode>3_doubleword"
[(set (match_operand:DWI 0 "register_operand" "=&r,r")
(ashift:DWI (match_operand:DWI 1 "reg_or_pm1_operand" "n,0")
(match_operand:QI 2 "nonmemory_operand" "<S>c,<S>c")))
(clobber (reg:CC FLAGS_REG))]
"TARGET_64BIT"
"ix86_binary_operator_ok (ASHIFT, <MODE>mode, operands)"
"#"
"(optimize && flag_peephole2) ? epilogue_completed : reload_completed"
[(const_int 0)]
"ix86_split_ashl (operands, NULL_RTX, <MODE>mode); DONE;"
[(set_attr "type" "multi")])
;; By default we don't ask for a scratch register, because when DWImode
;; values are manipulated, registers are already at a premium. But if
;; we have one handy, we won't turn it away.
(define_peephole2
[(match_scratch:DI 3 "r")
(parallel [(set (match_operand:TI 0 "register_operand" "")
(ashift:TI (match_operand:TI 1 "nonmemory_operand" "")
(match_operand:QI 2 "nonmemory_operand" "")))
[(match_scratch:DWIH 3 "r")
(parallel [(set (match_operand:<DWI> 0 "register_operand" "")
(ashift:<DWI>
(match_operand:<DWI> 1 "nonmemory_operand" "")
(match_operand:QI 2 "nonmemory_operand" "")))
(clobber (reg:CC FLAGS_REG))])
(match_dup 3)]
"TARGET_64BIT"
[(const_int 0)]
"ix86_split_ashl (operands, operands[3], TImode); DONE;")
(define_split
[(set (match_operand:TI 0 "register_operand" "")
(ashift:TI (match_operand:TI 1 "nonmemory_operand" "")
(match_operand:QI 2 "nonmemory_operand" "")))
(clobber (reg:CC FLAGS_REG))]
"TARGET_64BIT && ((optimize > 0 && flag_peephole2)
? epilogue_completed : reload_completed)"
"TARGET_CMOVE"
[(const_int 0)]
"ix86_split_ashl (operands, NULL_RTX, TImode); DONE;")
"ix86_split_ashl (operands, operands[3], <DWI>mode); DONE;")
(define_insn "x86_64_shld"
[(set (match_operand:DI 0 "nonimmediate_operand" "+r*m")
......@@ -9575,32 +9603,49 @@
(set_attr "athlon_decode" "vector")
(set_attr "amdfam10_decode" "vector")])
(define_expand "x86_64_shift_adj_1"
(define_insn "x86_shld"
[(set (match_operand:SI 0 "nonimmediate_operand" "+r*m")
(ior:SI (ashift:SI (match_dup 0)
(match_operand:QI 2 "nonmemory_operand" "Ic"))
(lshiftrt:SI (match_operand:SI 1 "register_operand" "r")
(minus:QI (const_int 32) (match_dup 2)))))
(clobber (reg:CC FLAGS_REG))]
""
"shld{l}\t{%s2%1, %0|%0, %1, %2}"
[(set_attr "type" "ishift")
(set_attr "prefix_0f" "1")
(set_attr "mode" "SI")
(set_attr "pent_pair" "np")
(set_attr "athlon_decode" "vector")
(set_attr "amdfam10_decode" "vector")])
(define_expand "x86_shift<mode>_adj_1"
[(set (reg:CCZ FLAGS_REG)
(compare:CCZ (and:QI (match_operand:QI 2 "register_operand" "")
(const_int 64))
(match_dup 4))
(const_int 0)))
(set (match_operand:DI 0 "register_operand" "")
(if_then_else:DI (ne (reg:CCZ FLAGS_REG) (const_int 0))
(match_operand:DI 1 "register_operand" "")
(match_dup 0)))
(set (match_operand:SWI48 0 "register_operand" "")
(if_then_else:SWI48 (ne (reg:CCZ FLAGS_REG) (const_int 0))
(match_operand:SWI48 1 "register_operand" "")
(match_dup 0)))
(set (match_dup 1)
(if_then_else:DI (ne (reg:CCZ FLAGS_REG) (const_int 0))
(match_operand:DI 3 "register_operand" "r")
(match_dup 1)))]
"TARGET_64BIT"
"")
(if_then_else:SWI48 (ne (reg:CCZ FLAGS_REG) (const_int 0))
(match_operand:SWI48 3 "register_operand" "r")
(match_dup 1)))]
"TARGET_CMOVE"
"operands[4] = GEN_INT (GET_MODE_BITSIZE (<MODE>mode));")
(define_expand "x86_64_shift_adj_2"
[(use (match_operand:DI 0 "register_operand" ""))
(use (match_operand:DI 1 "register_operand" ""))
(define_expand "x86_shift<mode>_adj_2"
[(use (match_operand:SWI48 0 "register_operand" ""))
(use (match_operand:SWI48 1 "register_operand" ""))
(use (match_operand:QI 2 "register_operand" ""))]
"TARGET_64BIT"
""
{
rtx label = gen_label_rtx ();
rtx tmp;
emit_insn (gen_testqi_ccz_1 (operands[2], GEN_INT (64)));
emit_insn (gen_testqi_ccz_1 (operands[2],
GEN_INT (GET_MODE_BITSIZE (<MODE>mode))));
tmp = gen_rtx_REG (CCZmode, FLAGS_REG);
tmp = gen_rtx_EQ (VOIDmode, tmp, const0_rtx);
......@@ -9619,42 +9664,31 @@
DONE;
})
(define_expand "ashldi3"
[(set (match_operand:DI 0 "shiftdi_operand" "")
(ashift:DI (match_operand:DI 1 "ashldi_input_operand" "")
(match_operand:QI 2 "nonmemory_operand" "")))]
""
"ix86_expand_binary_operator (ASHIFT, DImode, operands); DONE;")
(define_insn "*ashldi3_1_rex64"
[(set (match_operand:DI 0 "nonimmediate_operand" "=rm,r")
(ashift:DI (match_operand:DI 1 "nonimmediate_operand" "0,l")
(match_operand:QI 2 "nonmemory_operand" "cJ,M")))
(define_insn "*ashl<mode>3_1"
[(set (match_operand:SWI48 0 "nonimmediate_operand" "=rm,r")
(ashift:SWI48 (match_operand:SWI48 1 "nonimmediate_operand" "0,l")
(match_operand:QI 2 "nonmemory_operand" "c<S>,M")))
(clobber (reg:CC FLAGS_REG))]
"TARGET_64BIT && ix86_binary_operator_ok (ASHIFT, DImode, operands)"
"ix86_binary_operator_ok (ASHIFT, <MODE>mode, operands)"
{
switch (get_attr_type (insn))
{
case TYPE_ALU:
gcc_assert (operands[2] == const1_rtx);
gcc_assert (rtx_equal_p (operands[0], operands[1]));
return "add{q}\t%0, %0";
return "add{<imodesuffix>}\t%0, %0";
case TYPE_LEA:
gcc_assert (CONST_INT_P (operands[2]));
gcc_assert ((unsigned HOST_WIDE_INT) INTVAL (operands[2]) <= 3);
operands[1] = gen_rtx_MULT (DImode, operands[1],
GEN_INT (1 << INTVAL (operands[2])));
return "lea{q}\t{%a1, %0|%0, %a1}";
return "#";
default:
if (REG_P (operands[2]))
return "sal{q}\t{%b2, %0|%0, %b2}";
return "sal{<imodesuffix>}\t{%b2, %0|%0, %b2}";
else if (operands[2] == const1_rtx
&& (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
return "sal{q}\t%0";
return "sal{<imodesuffix>}\t%0";
else
return "sal{q}\t{%2, %0|%0, %2}";
return "sal{<imodesuffix>}\t{%2, %0|%0, %2}";
}
}
[(set (attr "type")
......@@ -9676,61 +9710,40 @@
(const_int 0)))))
(const_string "0")
(const_string "*")))
(set_attr "mode" "DI")])
(set_attr "mode" "<MODE>")])
;; Convert lea to the lea pattern to avoid flags dependency.
(define_split
[(set (match_operand:DI 0 "register_operand" "")
(ashift:DI (match_operand:DI 1 "index_register_operand" "")
(match_operand:QI 2 "immediate_operand" "")))
(define_insn "*ashlsi3_1_zext"
[(set (match_operand:DI 0 "register_operand" "=r,r")
(zero_extend:DI
(ashift:SI (match_operand:SI 1 "register_operand" "0,l")
(match_operand:QI 2 "nonmemory_operand" "cI,M"))))
(clobber (reg:CC FLAGS_REG))]
"TARGET_64BIT && reload_completed
&& true_regnum (operands[0]) != true_regnum (operands[1])"
[(set (match_dup 0)
(mult:DI (match_dup 1)
(match_dup 2)))]
"operands[2] = gen_int_mode (1 << INTVAL (operands[2]), DImode);")
;; This pattern can't accept a variable shift count, since shifts by
;; zero don't affect the flags. We assume that shifts by constant
;; zero are optimized away.
(define_insn "*ashldi3_cmp_rex64"
[(set (reg FLAGS_REG)
(compare
(ashift:DI (match_operand:DI 1 "nonimmediate_operand" "0")
(match_operand:QI 2 "const_1_to_63_operand" "J"))
(const_int 0)))
(set (match_operand:DI 0 "nonimmediate_operand" "=rm")
(ashift:DI (match_dup 1) (match_dup 2)))]
"TARGET_64BIT
&& (optimize_function_for_size_p (cfun)
|| !TARGET_PARTIAL_FLAG_REG_STALL
|| (operands[2] == const1_rtx
&& (TARGET_SHIFT1
|| (TARGET_DOUBLE_WITH_ADD && REG_P (operands[0])))))
&& ix86_match_ccmode (insn, CCGOCmode)
&& ix86_binary_operator_ok (ASHIFT, DImode, operands)"
"TARGET_64BIT && ix86_binary_operator_ok (ASHIFT, SImode, operands)"
{
switch (get_attr_type (insn))
{
case TYPE_ALU:
gcc_assert (operands[2] == const1_rtx);
return "add{q}\t%0, %0";
return "add{l}\t%k0, %k0";
case TYPE_LEA:
return "#";
default:
if (REG_P (operands[2]))
return "sal{q}\t{%b2, %0|%0, %b2}";
return "sal{l}\t{%b2, %k0|%k0, %b2}";
else if (operands[2] == const1_rtx
&& (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
return "sal{q}\t%0";
return "sal{l}\t%k0";
else
return "sal{q}\t{%2, %0|%0, %2}";
return "sal{l}\t{%2, %k0|%k0, %2}";
}
}
[(set (attr "type")
(cond [(and (and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
(const_int 0))
(match_operand 0 "register_operand" ""))
(cond [(eq_attr "alternative" "1")
(const_string "lea")
(and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
(const_int 0))
(match_operand 2 "const1_operand" ""))
(const_string "alu")
]
......@@ -9744,38 +9757,30 @@
(const_int 0)))))
(const_string "0")
(const_string "*")))
(set_attr "mode" "DI")])
(set_attr "mode" "SI")])
(define_insn "*ashldi3_cconly_rex64"
[(set (reg FLAGS_REG)
(compare
(ashift:DI (match_operand:DI 1 "nonimmediate_operand" "0")
(match_operand:QI 2 "const_1_to_63_operand" "J"))
(const_int 0)))
(clobber (match_scratch:DI 0 "=r"))]
"TARGET_64BIT
&& (optimize_function_for_size_p (cfun)
|| !TARGET_PARTIAL_FLAG_REG_STALL
|| (operands[2] == const1_rtx
&& (TARGET_SHIFT1
|| TARGET_DOUBLE_WITH_ADD)))
&& ix86_match_ccmode (insn, CCGOCmode)
&& ix86_binary_operator_ok (ASHIFT, DImode, operands)"
(define_insn "*ashlhi3_1"
[(set (match_operand:HI 0 "nonimmediate_operand" "=rm")
(ashift:HI (match_operand:HI 1 "nonimmediate_operand" "0")
(match_operand:QI 2 "nonmemory_operand" "cI")))
(clobber (reg:CC FLAGS_REG))]
"TARGET_PARTIAL_REG_STALL
&& ix86_binary_operator_ok (ASHIFT, HImode, operands)"
{
switch (get_attr_type (insn))
{
case TYPE_ALU:
gcc_assert (operands[2] == const1_rtx);
return "add{q}\t%0, %0";
return "add{w}\t%0, %0";
default:
if (REG_P (operands[2]))
return "sal{q}\t{%b2, %0|%0, %b2}";
return "sal{w}\t{%b2, %0|%0, %b2}";
else if (operands[2] == const1_rtx
&& (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
return "sal{q}\t%0";
return "sal{w}\t%0";
else
return "sal{q}\t{%2, %0|%0, %2}";
return "sal{w}\t{%2, %0|%0, %2}";
}
}
[(set (attr "type")
......@@ -9795,133 +9800,32 @@
(const_int 0)))))
(const_string "0")
(const_string "*")))
(set_attr "mode" "DI")])
(define_insn "*ashldi3_1"
[(set (match_operand:DI 0 "register_operand" "=&r,r")
(ashift:DI (match_operand:DI 1 "reg_or_pm1_operand" "n,0")
(match_operand:QI 2 "nonmemory_operand" "Jc,Jc")))
(clobber (reg:CC FLAGS_REG))]
"!TARGET_64BIT"
"#"
[(set_attr "type" "multi")])
;; By default we don't ask for a scratch register, because when DImode
;; values are manipulated, registers are already at a premium. But if
;; we have one handy, we won't turn it away.
(define_peephole2
[(match_scratch:SI 3 "r")
(parallel [(set (match_operand:DI 0 "register_operand" "")
(ashift:DI (match_operand:DI 1 "nonmemory_operand" "")
(match_operand:QI 2 "nonmemory_operand" "")))
(clobber (reg:CC FLAGS_REG))])
(match_dup 3)]
"!TARGET_64BIT && TARGET_CMOVE"
[(const_int 0)]
"ix86_split_ashl (operands, operands[3], DImode); DONE;")
(define_split
[(set (match_operand:DI 0 "register_operand" "")
(ashift:DI (match_operand:DI 1 "nonmemory_operand" "")
(match_operand:QI 2 "nonmemory_operand" "")))
(clobber (reg:CC FLAGS_REG))]
"!TARGET_64BIT && ((optimize > 0 && flag_peephole2)
? epilogue_completed : reload_completed)"
[(const_int 0)]
"ix86_split_ashl (operands, NULL_RTX, DImode); DONE;")
(define_insn "x86_shld"
[(set (match_operand:SI 0 "nonimmediate_operand" "+r*m")
(ior:SI (ashift:SI (match_dup 0)
(match_operand:QI 2 "nonmemory_operand" "Ic"))
(lshiftrt:SI (match_operand:SI 1 "register_operand" "r")
(minus:QI (const_int 32) (match_dup 2)))))
(clobber (reg:CC FLAGS_REG))]
""
"shld{l}\t{%s2%1, %0|%0, %1, %2}"
[(set_attr "type" "ishift")
(set_attr "prefix_0f" "1")
(set_attr "mode" "SI")
(set_attr "pent_pair" "np")
(set_attr "athlon_decode" "vector")
(set_attr "amdfam10_decode" "vector")])
(define_expand "x86_shift_adj_1"
[(set (reg:CCZ FLAGS_REG)
(compare:CCZ (and:QI (match_operand:QI 2 "register_operand" "")
(const_int 32))
(const_int 0)))
(set (match_operand:SI 0 "register_operand" "")
(if_then_else:SI (ne (reg:CCZ FLAGS_REG) (const_int 0))
(match_operand:SI 1 "register_operand" "")
(match_dup 0)))
(set (match_dup 1)
(if_then_else:SI (ne (reg:CCZ FLAGS_REG) (const_int 0))
(match_operand:SI 3 "register_operand" "r")
(match_dup 1)))]
"TARGET_CMOVE"
"")
(define_expand "x86_shift_adj_2"
[(use (match_operand:SI 0 "register_operand" ""))
(use (match_operand:SI 1 "register_operand" ""))
(use (match_operand:QI 2 "register_operand" ""))]
""
{
rtx label = gen_label_rtx ();
rtx tmp;
emit_insn (gen_testqi_ccz_1 (operands[2], GEN_INT (32)));
tmp = gen_rtx_REG (CCZmode, FLAGS_REG);
tmp = gen_rtx_EQ (VOIDmode, tmp, const0_rtx);
tmp = gen_rtx_IF_THEN_ELSE (VOIDmode, tmp,
gen_rtx_LABEL_REF (VOIDmode, label),
pc_rtx);
tmp = emit_jump_insn (gen_rtx_SET (VOIDmode, pc_rtx, tmp));
JUMP_LABEL (tmp) = label;
emit_move_insn (operands[0], operands[1]);
ix86_expand_clear (operands[1]);
emit_label (label);
LABEL_NUSES (label) = 1;
DONE;
})
(define_expand "ashlsi3"
[(set (match_operand:SI 0 "nonimmediate_operand" "")
(ashift:SI (match_operand:SI 1 "nonimmediate_operand" "")
(match_operand:QI 2 "nonmemory_operand" "")))]
""
"ix86_expand_binary_operator (ASHIFT, SImode, operands); DONE;")
(set_attr "mode" "HI")])
(define_insn "*ashlsi3_1"
[(set (match_operand:SI 0 "nonimmediate_operand" "=rm,r")
(ashift:SI (match_operand:SI 1 "nonimmediate_operand" "0,l")
(define_insn "*ashlhi3_1_lea"
[(set (match_operand:HI 0 "nonimmediate_operand" "=rm,r")
(ashift:HI (match_operand:HI 1 "nonimmediate_operand" "0,l")
(match_operand:QI 2 "nonmemory_operand" "cI,M")))
(clobber (reg:CC FLAGS_REG))]
"ix86_binary_operator_ok (ASHIFT, SImode, operands)"
"!TARGET_PARTIAL_REG_STALL
&& ix86_binary_operator_ok (ASHIFT, HImode, operands)"
{
switch (get_attr_type (insn))
{
case TYPE_ALU:
gcc_assert (operands[2] == const1_rtx);
gcc_assert (rtx_equal_p (operands[0], operands[1]));
return "add{l}\t%0, %0";
case TYPE_LEA:
return "#";
case TYPE_ALU:
gcc_assert (operands[2] == const1_rtx);
return "add{w}\t%0, %0";
default:
if (REG_P (operands[2]))
return "sal{l}\t{%b2, %0|%0, %b2}";
return "sal{w}\t{%b2, %0|%0, %b2}";
else if (operands[2] == const1_rtx
&& (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
return "sal{l}\t%0";
return "sal{w}\t%0";
else
return "sal{l}\t{%2, %0|%0, %2}";
return "sal{w}\t{%2, %0|%0, %2}";
}
}
[(set (attr "type")
......@@ -9943,452 +9847,48 @@
(const_int 0)))))
(const_string "0")
(const_string "*")))
(set_attr "mode" "SI")])
(set_attr "mode" "HI,SI")])
;; Convert lea to the lea pattern to avoid flags dependency.
(define_split
[(set (match_operand 0 "register_operand" "")
(ashift (match_operand 1 "index_register_operand" "")
(match_operand:QI 2 "const_int_operand" "")))
(define_insn "*ashlqi3_1"
[(set (match_operand:QI 0 "nonimmediate_operand" "=qm,r")
(ashift:QI (match_operand:QI 1 "nonimmediate_operand" "0,0")
(match_operand:QI 2 "nonmemory_operand" "cI,cI")))
(clobber (reg:CC FLAGS_REG))]
"reload_completed
&& true_regnum (operands[0]) != true_regnum (operands[1])
&& GET_MODE_SIZE (GET_MODE (operands[0])) <= 4"
[(const_int 0)]
"TARGET_PARTIAL_REG_STALL
&& ix86_binary_operator_ok (ASHIFT, QImode, operands)"
{
rtx pat;
enum machine_mode mode = GET_MODE (operands[0]);
if (GET_MODE_SIZE (mode) < 4)
operands[0] = gen_lowpart (SImode, operands[0]);
if (mode != Pmode)
operands[1] = gen_lowpart (Pmode, operands[1]);
operands[2] = gen_int_mode (1 << INTVAL (operands[2]), Pmode);
pat = gen_rtx_MULT (Pmode, operands[1], operands[2]);
if (Pmode != SImode)
pat = gen_rtx_SUBREG (SImode, pat, 0);
emit_insn (gen_rtx_SET (VOIDmode, operands[0], pat));
DONE;
})
;; Rare case of shifting RSP is handled by generating move and shift
(define_split
[(set (match_operand 0 "register_operand" "")
(ashift (match_operand 1 "register_operand" "")
(match_operand:QI 2 "const_int_operand" "")))
(clobber (reg:CC FLAGS_REG))]
"reload_completed
&& true_regnum (operands[0]) != true_regnum (operands[1])"
[(const_int 0)]
{
rtx pat, clob;
emit_move_insn (operands[0], operands[1]);
pat = gen_rtx_SET (VOIDmode, operands[0],
gen_rtx_ASHIFT (GET_MODE (operands[0]),
operands[0], operands[2]));
clob = gen_rtx_CLOBBER (VOIDmode, gen_rtx_REG (CCmode, FLAGS_REG));
emit_insn (gen_rtx_PARALLEL (VOIDmode, gen_rtvec (2, pat, clob)));
DONE;
})
(define_insn "*ashlsi3_1_zext"
[(set (match_operand:DI 0 "register_operand" "=r,r")
(zero_extend:DI (ashift:SI (match_operand:SI 1 "register_operand" "0,l")
(match_operand:QI 2 "nonmemory_operand" "cI,M"))))
(clobber (reg:CC FLAGS_REG))]
"TARGET_64BIT && ix86_binary_operator_ok (ASHIFT, SImode, operands)"
{
switch (get_attr_type (insn))
{
case TYPE_ALU:
gcc_assert (operands[2] == const1_rtx);
return "add{l}\t%k0, %k0";
case TYPE_LEA:
return "#";
default:
if (REG_P (operands[2]))
return "sal{l}\t{%b2, %k0|%k0, %b2}";
else if (operands[2] == const1_rtx
&& (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
return "sal{l}\t%k0";
else
return "sal{l}\t{%2, %k0|%k0, %2}";
}
}
[(set (attr "type")
(cond [(eq_attr "alternative" "1")
(const_string "lea")
(and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
(const_int 0))
(match_operand 2 "const1_operand" ""))
(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.
(define_split
[(set (match_operand:DI 0 "register_operand" "")
(zero_extend:DI (ashift (match_operand 1 "register_operand" "")
(match_operand:QI 2 "const_int_operand" ""))))
(clobber (reg:CC FLAGS_REG))]
"TARGET_64BIT && reload_completed
&& true_regnum (operands[0]) != true_regnum (operands[1])"
[(set (match_dup 0) (zero_extend:DI
(subreg:SI (mult:SI (match_dup 1)
(match_dup 2)) 0)))]
{
operands[1] = gen_lowpart (Pmode, operands[1]);
operands[2] = gen_int_mode (1 << INTVAL (operands[2]), Pmode);
})
;; This pattern can't accept a variable shift count, since shifts by
;; zero don't affect the flags. We assume that shifts by constant
;; zero are optimized away.
(define_insn "*ashlsi3_cmp"
[(set (reg FLAGS_REG)
(compare
(ashift:SI (match_operand:SI 1 "nonimmediate_operand" "0")
(match_operand:QI 2 "const_1_to_31_operand" "I"))
(const_int 0)))
(set (match_operand:SI 0 "nonimmediate_operand" "=rm")
(ashift:SI (match_dup 1) (match_dup 2)))]
"(optimize_function_for_size_p (cfun)
|| !TARGET_PARTIAL_FLAG_REG_STALL
|| (operands[2] == const1_rtx
&& (TARGET_SHIFT1
|| (TARGET_DOUBLE_WITH_ADD && REG_P (operands[0])))))
&& ix86_match_ccmode (insn, CCGOCmode)
&& ix86_binary_operator_ok (ASHIFT, SImode, operands)"
{
switch (get_attr_type (insn))
{
case TYPE_ALU:
gcc_assert (operands[2] == const1_rtx);
return "add{l}\t%0, %0";
default:
if (REG_P (operands[2]))
return "sal{l}\t{%b2, %0|%0, %b2}";
else if (operands[2] == const1_rtx
&& (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
return "sal{l}\t%0";
else
return "sal{l}\t{%2, %0|%0, %2}";
}
}
[(set (attr "type")
(cond [(and (and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
(const_int 0))
(match_operand 0 "register_operand" ""))
(match_operand 2 "const1_operand" ""))
(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"
[(set (reg FLAGS_REG)
(compare
(ashift:SI (match_operand:SI 1 "nonimmediate_operand" "0")
(match_operand:QI 2 "const_1_to_31_operand" "I"))
(const_int 0)))
(clobber (match_scratch:SI 0 "=r"))]
"(optimize_function_for_size_p (cfun)
|| !TARGET_PARTIAL_FLAG_REG_STALL
|| (operands[2] == const1_rtx
&& (TARGET_SHIFT1
|| TARGET_DOUBLE_WITH_ADD)))
&& ix86_match_ccmode (insn, CCGOCmode)
&& ix86_binary_operator_ok (ASHIFT, SImode, operands)"
{
switch (get_attr_type (insn))
{
case TYPE_ALU:
gcc_assert (operands[2] == const1_rtx);
return "add{l}\t%0, %0";
default:
if (REG_P (operands[2]))
return "sal{l}\t{%b2, %0|%0, %b2}";
else if (operands[2] == const1_rtx
&& (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
return "sal{l}\t%0";
else
return "sal{l}\t{%2, %0|%0, %2}";
}
}
[(set (attr "type")
(cond [(and (and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
(const_int 0))
(match_operand 0 "register_operand" ""))
(match_operand 2 "const1_operand" ""))
(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"
[(set (reg FLAGS_REG)
(compare
(ashift:SI (match_operand:SI 1 "register_operand" "0")
(match_operand:QI 2 "const_1_to_31_operand" "I"))
(const_int 0)))
(set (match_operand:DI 0 "register_operand" "=r")
(zero_extend:DI (ashift:SI (match_dup 1) (match_dup 2))))]
"TARGET_64BIT
&& (optimize_function_for_size_p (cfun)
|| !TARGET_PARTIAL_FLAG_REG_STALL
|| (operands[2] == const1_rtx
&& (TARGET_SHIFT1
|| TARGET_DOUBLE_WITH_ADD)))
&& ix86_match_ccmode (insn, CCGOCmode)
&& ix86_binary_operator_ok (ASHIFT, SImode, operands)"
{
switch (get_attr_type (insn))
{
case TYPE_ALU:
gcc_assert (operands[2] == const1_rtx);
return "add{l}\t%k0, %k0";
default:
if (REG_P (operands[2]))
return "sal{l}\t{%b2, %k0|%k0, %b2}";
else if (operands[2] == const1_rtx
&& (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
return "sal{l}\t%k0";
else
return "sal{l}\t{%2, %k0|%k0, %2}";
}
}
[(set (attr "type")
(cond [(and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
(const_int 0))
(match_operand 2 "const1_operand" ""))
(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"
[(set (match_operand:HI 0 "nonimmediate_operand" "")
(ashift:HI (match_operand:HI 1 "nonimmediate_operand" "")
(match_operand:QI 2 "nonmemory_operand" "")))]
"TARGET_HIMODE_MATH"
"ix86_expand_binary_operator (ASHIFT, HImode, operands); DONE;")
(define_insn "*ashlhi3_1_lea"
[(set (match_operand:HI 0 "nonimmediate_operand" "=rm,r")
(ashift:HI (match_operand:HI 1 "nonimmediate_operand" "0,l")
(match_operand:QI 2 "nonmemory_operand" "cI,M")))
(clobber (reg:CC FLAGS_REG))]
"!TARGET_PARTIAL_REG_STALL
&& ix86_binary_operator_ok (ASHIFT, HImode, operands)"
{
switch (get_attr_type (insn))
{
case TYPE_LEA:
return "#";
case TYPE_ALU:
gcc_assert (operands[2] == const1_rtx);
return "add{w}\t%0, %0";
default:
if (REG_P (operands[2]))
return "sal{w}\t{%b2, %0|%0, %b2}";
else if (operands[2] == const1_rtx
&& (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
return "sal{w}\t%0";
else
return "sal{w}\t{%2, %0|%0, %2}";
}
}
[(set (attr "type")
(cond [(eq_attr "alternative" "1")
(const_string "lea")
(and (and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
(const_int 0))
(match_operand 0 "register_operand" ""))
(match_operand 2 "const1_operand" ""))
(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"
[(set (match_operand:HI 0 "nonimmediate_operand" "=rm")
(ashift:HI (match_operand:HI 1 "nonimmediate_operand" "0")
(match_operand:QI 2 "nonmemory_operand" "cI")))
(clobber (reg:CC FLAGS_REG))]
"TARGET_PARTIAL_REG_STALL
&& ix86_binary_operator_ok (ASHIFT, HImode, operands)"
{
switch (get_attr_type (insn))
{
case TYPE_ALU:
gcc_assert (operands[2] == const1_rtx);
return "add{w}\t%0, %0";
default:
if (REG_P (operands[2]))
return "sal{w}\t{%b2, %0|%0, %b2}";
else if (operands[2] == const1_rtx
&& (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
return "sal{w}\t%0";
else
return "sal{w}\t{%2, %0|%0, %2}";
}
}
[(set (attr "type")
(cond [(and (and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
(const_int 0))
(match_operand 0 "register_operand" ""))
(match_operand 2 "const1_operand" ""))
(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
;; zero don't affect the flags. We assume that shifts by constant
;; zero are optimized away.
(define_insn "*ashlhi3_cmp"
[(set (reg FLAGS_REG)
(compare
(ashift:HI (match_operand:HI 1 "nonimmediate_operand" "0")
(match_operand:QI 2 "const_1_to_31_operand" "I"))
(const_int 0)))
(set (match_operand:HI 0 "nonimmediate_operand" "=rm")
(ashift:HI (match_dup 1) (match_dup 2)))]
"(optimize_function_for_size_p (cfun)
|| !TARGET_PARTIAL_FLAG_REG_STALL
|| (operands[2] == const1_rtx
&& (TARGET_SHIFT1
|| (TARGET_DOUBLE_WITH_ADD && REG_P (operands[0])))))
&& ix86_match_ccmode (insn, CCGOCmode)
&& ix86_binary_operator_ok (ASHIFT, HImode, operands)"
{
switch (get_attr_type (insn))
{
case TYPE_ALU:
gcc_assert (operands[2] == const1_rtx);
return "add{w}\t%0, %0";
default:
if (REG_P (operands[2]))
return "sal{w}\t{%b2, %0|%0, %b2}";
else if (operands[2] == const1_rtx
&& (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
return "sal{w}\t%0";
else
return "sal{w}\t{%2, %0|%0, %2}";
}
}
[(set (attr "type")
(cond [(and (and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
(const_int 0))
(match_operand 0 "register_operand" ""))
(match_operand 2 "const1_operand" ""))
(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"
[(set (reg FLAGS_REG)
(compare
(ashift:HI (match_operand:HI 1 "nonimmediate_operand" "0")
(match_operand:QI 2 "const_1_to_31_operand" "I"))
(const_int 0)))
(clobber (match_scratch:HI 0 "=r"))]
"(optimize_function_for_size_p (cfun)
|| !TARGET_PARTIAL_FLAG_REG_STALL
|| (operands[2] == const1_rtx
&& (TARGET_SHIFT1
|| TARGET_DOUBLE_WITH_ADD)))
&& ix86_match_ccmode (insn, CCGOCmode)
&& ix86_binary_operator_ok (ASHIFT, HImode, operands)"
{
switch (get_attr_type (insn))
{
case TYPE_ALU:
gcc_assert (operands[2] == const1_rtx);
return "add{w}\t%0, %0";
switch (get_attr_type (insn))
{
case TYPE_ALU:
gcc_assert (operands[2] == const1_rtx);
if (REG_P (operands[1]) && !ANY_QI_REG_P (operands[1]))
return "add{l}\t%k0, %k0";
else
return "add{b}\t%0, %0";
default:
if (REG_P (operands[2]))
return "sal{w}\t{%b2, %0|%0, %b2}";
{
if (get_attr_mode (insn) == MODE_SI)
return "sal{l}\t{%b2, %k0|%k0, %b2}";
else
return "sal{b}\t{%b2, %0|%0, %b2}";
}
else if (operands[2] == const1_rtx
&& (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
return "sal{w}\t%0";
{
if (get_attr_mode (insn) == MODE_SI)
return "sal{l}\t%0";
else
return "sal{b}\t%0";
}
else
return "sal{w}\t{%2, %0|%0, %2}";
{
if (get_attr_mode (insn) == MODE_SI)
return "sal{l}\t{%2, %k0|%k0, %2}";
else
return "sal{b}\t{%2, %0|%0, %2}";
}
}
}
[(set (attr "type")
......@@ -10408,17 +9908,9 @@
(const_int 0)))))
(const_string "0")
(const_string "*")))
(set_attr "mode" "HI")])
(define_expand "ashlqi3"
[(set (match_operand:QI 0 "nonimmediate_operand" "")
(ashift:QI (match_operand:QI 1 "nonimmediate_operand" "")
(match_operand:QI 2 "nonmemory_operand" "")))]
"TARGET_QIMODE_MATH"
"ix86_expand_binary_operator (ASHIFT, QImode, operands); DONE;")
(set_attr "mode" "QI,SI")])
;; %%% Potential partial reg stall on alternative 2. What to do?
(define_insn "*ashlqi3_1_lea"
[(set (match_operand:QI 0 "nonimmediate_operand" "=qm,r,r")
(ashift:QI (match_operand:QI 1 "nonimmediate_operand" "0,0,l")
......@@ -10484,46 +9976,113 @@
(const_string "*")))
(set_attr "mode" "QI,SI,SI")])
(define_insn "*ashlqi3_1"
[(set (match_operand:QI 0 "nonimmediate_operand" "=qm,r")
(ashift:QI (match_operand:QI 1 "nonimmediate_operand" "0,0")
(match_operand:QI 2 "nonmemory_operand" "cI,cI")))
;; Convert lea to the lea pattern to avoid flags dependency.
(define_split
[(set (match_operand:DI 0 "register_operand" "")
(ashift:DI (match_operand:DI 1 "index_register_operand" "")
(match_operand:QI 2 "const_int_operand" "")))
(clobber (reg:CC FLAGS_REG))]
"TARGET_PARTIAL_REG_STALL
&& ix86_binary_operator_ok (ASHIFT, QImode, operands)"
"TARGET_64BIT && reload_completed
&& true_regnum (operands[0]) != true_regnum (operands[1])"
[(set (match_dup 0)
(mult:DI (match_dup 1)
(match_dup 2)))]
"operands[2] = gen_int_mode (1 << INTVAL (operands[2]), DImode);")
;; Convert lea to the lea pattern to avoid flags dependency.
(define_split
[(set (match_operand 0 "register_operand" "")
(ashift (match_operand 1 "index_register_operand" "")
(match_operand:QI 2 "const_int_operand" "")))
(clobber (reg:CC FLAGS_REG))]
"reload_completed
&& true_regnum (operands[0]) != true_regnum (operands[1])
&& GET_MODE_SIZE (GET_MODE (operands[0])) <= 4"
[(const_int 0)]
{
rtx pat;
enum machine_mode mode = GET_MODE (operands[0]);
if (GET_MODE_SIZE (mode) < 4)
operands[0] = gen_lowpart (SImode, operands[0]);
if (mode != Pmode)
operands[1] = gen_lowpart (Pmode, operands[1]);
operands[2] = gen_int_mode (1 << INTVAL (operands[2]), Pmode);
pat = gen_rtx_MULT (Pmode, operands[1], operands[2]);
if (Pmode != SImode)
pat = gen_rtx_SUBREG (SImode, pat, 0);
emit_insn (gen_rtx_SET (VOIDmode, operands[0], pat));
DONE;
})
;; Rare case of shifting RSP is handled by generating move and shift
(define_split
[(set (match_operand 0 "register_operand" "")
(ashift (match_operand 1 "register_operand" "")
(match_operand:QI 2 "const_int_operand" "")))
(clobber (reg:CC FLAGS_REG))]
"reload_completed
&& true_regnum (operands[0]) != true_regnum (operands[1])"
[(const_int 0)]
{
rtx pat, clob;
emit_move_insn (operands[0], operands[1]);
pat = gen_rtx_SET (VOIDmode, operands[0],
gen_rtx_ASHIFT (GET_MODE (operands[0]),
operands[0], operands[2]));
clob = gen_rtx_CLOBBER (VOIDmode, gen_rtx_REG (CCmode, FLAGS_REG));
emit_insn (gen_rtx_PARALLEL (VOIDmode, gen_rtvec (2, pat, clob)));
DONE;
})
;; Convert lea to the lea pattern to avoid flags dependency.
(define_split
[(set (match_operand:DI 0 "register_operand" "")
(zero_extend:DI
(ashift:SI (match_operand:SI 1 "register_operand" "")
(match_operand:QI 2 "const_int_operand" ""))))
(clobber (reg:CC FLAGS_REG))]
"TARGET_64BIT && reload_completed
&& true_regnum (operands[0]) != true_regnum (operands[1])"
[(set (match_dup 0)
(zero_extend:DI (subreg:SI (mult:SI (match_dup 1) (match_dup 2)) 0)))]
{
operands[1] = gen_lowpart (Pmode, operands[1]);
operands[2] = gen_int_mode (1 << INTVAL (operands[2]), Pmode);
})
;; This pattern can't accept a variable shift count, since shifts by
;; zero don't affect the flags. We assume that shifts by constant
;; zero are optimized away.
(define_insn "*ashl<mode>3_cmp"
[(set (reg FLAGS_REG)
(compare
(ashift:SWI (match_operand:SWI 1 "nonimmediate_operand" "0")
(match_operand:QI 2 "<shift_immediate_operand>" "<S>"))
(const_int 0)))
(set (match_operand:SWI 0 "nonimmediate_operand" "=<r>m")
(ashift:SWI (match_dup 1) (match_dup 2)))]
"(optimize_function_for_size_p (cfun)
|| !TARGET_PARTIAL_FLAG_REG_STALL
|| (operands[2] == const1_rtx
&& (TARGET_SHIFT1
|| (TARGET_DOUBLE_WITH_ADD && REG_P (operands[0])))))
&& ix86_match_ccmode (insn, CCGOCmode)
&& ix86_binary_operator_ok (ASHIFT, <MODE>mode, operands)"
{
switch (get_attr_type (insn))
{
case TYPE_ALU:
gcc_assert (operands[2] == const1_rtx);
if (REG_P (operands[1]) && !ANY_QI_REG_P (operands[1]))
return "add{l}\t%k0, %k0";
else
return "add{b}\t%0, %0";
return "add{<imodesuffix>}\t%0, %0";
default:
if (REG_P (operands[2]))
{
if (get_attr_mode (insn) == MODE_SI)
return "sal{l}\t{%b2, %k0|%k0, %b2}";
else
return "sal{b}\t{%b2, %0|%0, %b2}";
}
else if (operands[2] == const1_rtx
&& (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
{
if (get_attr_mode (insn) == MODE_SI)
return "sal{l}\t%0";
else
return "sal{b}\t%0";
}
if (operands[2] == const1_rtx
&& (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
return "sal{<imodesuffix>}\t%0";
else
{
if (get_attr_mode (insn) == MODE_SI)
return "sal{l}\t{%2, %k0|%k0, %2}";
else
return "sal{b}\t{%2, %0|%0, %2}";
}
return "sal{<imodesuffix>}\t{%2, %0|%0, %2}";
}
}
[(set (attr "type")
......@@ -10543,47 +10102,42 @@
(const_int 0)))))
(const_string "0")
(const_string "*")))
(set_attr "mode" "QI,SI")])
(set_attr "mode" "<MODE>")])
;; This pattern can't accept a variable shift count, since shifts by
;; zero don't affect the flags. We assume that shifts by constant
;; zero are optimized away.
(define_insn "*ashlqi3_cmp"
(define_insn "*ashlsi3_cmp_zext"
[(set (reg FLAGS_REG)
(compare
(ashift:QI (match_operand:QI 1 "nonimmediate_operand" "0")
(ashift:SI (match_operand:SI 1 "register_operand" "0")
(match_operand:QI 2 "const_1_to_31_operand" "I"))
(const_int 0)))
(set (match_operand:QI 0 "nonimmediate_operand" "=qm")
(ashift:QI (match_dup 1) (match_dup 2)))]
"(optimize_function_for_size_p (cfun)
|| !TARGET_PARTIAL_FLAG_REG_STALL
|| (operands[2] == const1_rtx
&& (TARGET_SHIFT1
|| (TARGET_DOUBLE_WITH_ADD && REG_P (operands[0])))))
(set (match_operand:DI 0 "register_operand" "=r")
(zero_extend:DI (ashift:SI (match_dup 1) (match_dup 2))))]
"TARGET_64BIT
&& (optimize_function_for_size_p (cfun)
|| !TARGET_PARTIAL_FLAG_REG_STALL
|| (operands[2] == const1_rtx
&& (TARGET_SHIFT1
|| TARGET_DOUBLE_WITH_ADD)))
&& ix86_match_ccmode (insn, CCGOCmode)
&& ix86_binary_operator_ok (ASHIFT, QImode, operands)"
&& ix86_binary_operator_ok (ASHIFT, SImode, operands)"
{
switch (get_attr_type (insn))
{
case TYPE_ALU:
gcc_assert (operands[2] == const1_rtx);
return "add{b}\t%0, %0";
return "add{l}\t%k0, %k0";
default:
if (REG_P (operands[2]))
return "sal{b}\t{%b2, %0|%0, %b2}";
else if (operands[2] == const1_rtx
&& (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
return "sal{b}\t%0";
if (operands[2] == const1_rtx
&& (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
return "sal{l}\t%k0";
else
return "sal{b}\t{%2, %0|%0, %2}";
return "sal{l}\t{%2, %k0|%k0, %2}";
}
}
[(set (attr "type")
(cond [(and (and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
(const_int 0))
(match_operand 0 "register_operand" ""))
(cond [(and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
(const_int 0))
(match_operand 2 "const1_operand" ""))
(const_string "alu")
]
......@@ -10597,37 +10151,35 @@
(const_int 0)))))
(const_string "0")
(const_string "*")))
(set_attr "mode" "QI")])
(set_attr "mode" "SI")])
(define_insn "*ashlqi3_cconly"
(define_insn "*ashl<mode>3_cconly"
[(set (reg FLAGS_REG)
(compare
(ashift:QI (match_operand:QI 1 "nonimmediate_operand" "0")
(match_operand:QI 2 "const_1_to_31_operand" "I"))
(ashift:SWI (match_operand:SWI 1 "nonimmediate_operand" "0")
(match_operand:QI 2 "<shift_immediate_operand>" "<S>"))
(const_int 0)))
(clobber (match_scratch:QI 0 "=q"))]
(clobber (match_scratch:SWI 0 "=<r>"))]
"(optimize_function_for_size_p (cfun)
|| !TARGET_PARTIAL_FLAG_REG_STALL
|| (operands[2] == const1_rtx
&& (TARGET_SHIFT1
|| TARGET_DOUBLE_WITH_ADD)))
&& ix86_match_ccmode (insn, CCGOCmode)
&& ix86_binary_operator_ok (ASHIFT, QImode, operands)"
&& ix86_binary_operator_ok (ASHIFT, <MODE>mode, operands)"
{
switch (get_attr_type (insn))
{
case TYPE_ALU:
gcc_assert (operands[2] == const1_rtx);
return "add{b}\t%0, %0";
return "add{<imodesuffix>}\t%0, %0";
default:
if (REG_P (operands[2]))
return "sal{b}\t{%b2, %0|%0, %b2}";
else if (operands[2] == const1_rtx
&& (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
return "sal{b}\t%0";
if (operands[2] == const1_rtx
&& (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
return "sal{<imodesuffix>}\t%0";
else
return "sal{b}\t{%2, %0|%0, %2}";
return "sal{<imodesuffix>}\t{%2, %0|%0, %2}";
}
}
[(set (attr "type")
......@@ -10647,7 +10199,7 @@
(const_int 0)))))
(const_string "0")
(const_string "*")))
(set_attr "mode" "QI")])
(set_attr "mode" "<MODE>")])
;; See comment above `ashldi3' about how this works.
......
......@@ -308,7 +308,7 @@
* gcc.c-torture/execute/pr43629.c: New testcase.
2010-04-01 Janne Blomqvist <jb@gcc.gnu.org>
Dominique d'Humieres <dominiq@lps.ens.fr>
Dominique d'Humieres <dominiq@lps.ens.fr>
PR libfortran/43605
* gfortran.dg/ftell_3.f90: Enhance test case by reading more.
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment