Commit 28356f52 by Jan Beulich Committed by Jan Beulich

i386.c (ix86_expand_branch, [...]): Handle TImode in 64-bit mode the same as DImode in 32-bit mode.

gcc/
2005-07-18  Jan Beulich  <jbeulich@novell.com>

	* config/i386/i386.c (ix86_expand_branch, ix86_expand_setcc,
	ix86_expand_carry_flag_compare, ix86_expand_int_movcc): Handle TImode
	in 64-bit mode the same as DImode in 32-bit mode.
	(ix86_expand_ashl_const, ix86_split_ashl, ix86_split_ashr,
	ix86_split_lshr): Likewise. Rename to no longer refer to a specific
	mode. Add new mode parameter.
	* config/i386/i386.h (CONST_OK_FOR_LETTER_P): Describe and handle 'O'.
	* config/i386/i386.md (cmpti, addti3, subti3, negti2, ashlti3, ashrti3,
	x86_64_shift_adj): New expanders.
	(*addti3_1, *subti3_1, *negti2_1, ashlti3_1, *ashlti3_2, ashrti3_1,
	*ashrti3_2, lshrti3_1, *lshrti3_2, x86_64_shld, x86_64_shrd): New
	insns.
	Respective new splitters. Use renamed shift splitter helpers in 32-bit
	DImode shift splitters.
	* config/i386/i386-protos.h (ix86_split_ashl, ix86_split_ashr,
	ix86_split_lshr): Renamed from ix86_split_[al]sh[rl]di. Added new
	mode parameter.

From-SVN: r102129
parent 422edd6f
2005-07-18 Jan Beulich <jbeulich@novell.com> 2005-07-18 Jan Beulich <jbeulich@novell.com>
* config/i386/i386.c (ix86_expand_branch, ix86_expand_setcc,
ix86_expand_carry_flag_compare, ix86_expand_int_movcc): Handle TImode
in 64-bit mode the same as DImode in 32-bit mode.
(ix86_expand_ashl_const, ix86_split_ashl, ix86_split_ashr,
ix86_split_lshr): Likewise. Rename to no longer refer to a specific
mode. Add new mode parameter.
* config/i386/i386.h (CONST_OK_FOR_LETTER_P): Describe and handle 'O'.
* config/i386/i386.md (cmpti, addti3, subti3, negti2, ashlti3, ashrti3,
x86_64_shift_adj): New expanders.
(*addti3_1, *subti3_1, *negti2_1, ashlti3_1, *ashlti3_2, ashrti3_1,
*ashrti3_2, lshrti3_1, *lshrti3_2, x86_64_shld, x86_64_shrd): New
insns.
Respective new splitters. Use renamed shift splitter helpers in 32-bit
DImode shift splitters.
* config/i386/i386-protos.h (ix86_split_ashl, ix86_split_ashr,
ix86_split_lshr): Renamed from ix86_split_[al]sh[rl]di. Added new
mode parameter.
2005-07-18 Jan Beulich <jbeulich@novell.com>
* i386.md (movdi_extzv_1): New. * i386.md (movdi_extzv_1): New.
(zero_extendhidi2): Combine alternatives and never force use of (zero_extendhidi2): Combine alternatives and never force use of
REX64 prefix. REX64 prefix.
......
...@@ -155,9 +155,9 @@ extern void ix86_expand_call (rtx, rtx, rtx, rtx, rtx, int); ...@@ -155,9 +155,9 @@ extern void ix86_expand_call (rtx, rtx, rtx, rtx, rtx, int);
extern void x86_initialize_trampoline (rtx, rtx, rtx); extern void x86_initialize_trampoline (rtx, rtx, rtx);
extern rtx ix86_zero_extend_to_Pmode (rtx); extern rtx ix86_zero_extend_to_Pmode (rtx);
extern void ix86_split_long_move (rtx[]); extern void ix86_split_long_move (rtx[]);
extern void ix86_split_ashldi (rtx *, rtx); extern void ix86_split_ashl (rtx *, rtx, enum machine_mode);
extern void ix86_split_ashrdi (rtx *, rtx); extern void ix86_split_ashr (rtx *, rtx, enum machine_mode);
extern void ix86_split_lshrdi (rtx *, rtx); extern void ix86_split_lshr (rtx *, rtx, enum machine_mode);
extern rtx ix86_find_base_term (rtx); extern rtx ix86_find_base_term (rtx);
extern int ix86_check_movabs (rtx, int); extern int ix86_check_movabs (rtx, int);
......
...@@ -7200,7 +7200,7 @@ split_di (rtx operands[], int num, rtx lo_half[], rtx hi_half[]) ...@@ -7200,7 +7200,7 @@ split_di (rtx operands[], int num, rtx lo_half[], rtx hi_half[])
} }
} }
} }
/* Split one or more TImode RTL references into pairs of SImode /* Split one or more TImode RTL references into pairs of DImode
references. The RTL can be REG, offsettable MEM, integer constant, or references. The RTL can be REG, offsettable MEM, integer constant, or
CONST_DOUBLE. "operands" is a pointer to an array of DImode RTL to CONST_DOUBLE. "operands" is a pointer to an array of DImode RTL to
split and "num" is its length. lo_half and hi_half are output arrays split and "num" is its length. lo_half and hi_half are output arrays
...@@ -9344,10 +9344,12 @@ ix86_expand_branch (enum rtx_code code, rtx label) ...@@ -9344,10 +9344,12 @@ ix86_expand_branch (enum rtx_code code, rtx label)
case DImode: case DImode:
if (TARGET_64BIT) if (TARGET_64BIT)
goto simple; goto simple;
case TImode:
/* Expand DImode branch into multiple compare+branch. */ /* Expand DImode branch into multiple compare+branch. */
{ {
rtx lo[2], hi[2], label2; rtx lo[2], hi[2], label2;
enum rtx_code code1, code2, code3; enum rtx_code code1, code2, code3;
enum machine_mode submode;
if (CONSTANT_P (ix86_compare_op0) && ! CONSTANT_P (ix86_compare_op1)) if (CONSTANT_P (ix86_compare_op0) && ! CONSTANT_P (ix86_compare_op1))
{ {
...@@ -9356,8 +9358,18 @@ ix86_expand_branch (enum rtx_code code, rtx label) ...@@ -9356,8 +9358,18 @@ ix86_expand_branch (enum rtx_code code, rtx label)
ix86_compare_op1 = tmp; ix86_compare_op1 = tmp;
code = swap_condition (code); code = swap_condition (code);
} }
split_di (&ix86_compare_op0, 1, lo+0, hi+0); if (GET_MODE (ix86_compare_op0) == DImode)
split_di (&ix86_compare_op1, 1, lo+1, hi+1); {
split_di (&ix86_compare_op0, 1, lo+0, hi+0);
split_di (&ix86_compare_op1, 1, lo+1, hi+1);
submode = SImode;
}
else
{
split_ti (&ix86_compare_op0, 1, lo+0, hi+0);
split_ti (&ix86_compare_op1, 1, lo+1, hi+1);
submode = DImode;
}
/* When comparing for equality, we can use (hi0^hi1)|(lo0^lo1) to /* When comparing for equality, we can use (hi0^hi1)|(lo0^lo1) to
avoid two branches. This costs one extra insn, so disable when avoid two branches. This costs one extra insn, so disable when
...@@ -9371,15 +9383,15 @@ ix86_expand_branch (enum rtx_code code, rtx label) ...@@ -9371,15 +9383,15 @@ ix86_expand_branch (enum rtx_code code, rtx label)
xor1 = hi[0]; xor1 = hi[0];
if (hi[1] != const0_rtx) if (hi[1] != const0_rtx)
xor1 = expand_binop (SImode, xor_optab, xor1, hi[1], xor1 = expand_binop (submode, xor_optab, xor1, hi[1],
NULL_RTX, 0, OPTAB_WIDEN); NULL_RTX, 0, OPTAB_WIDEN);
xor0 = lo[0]; xor0 = lo[0];
if (lo[1] != const0_rtx) if (lo[1] != const0_rtx)
xor0 = expand_binop (SImode, xor_optab, xor0, lo[1], xor0 = expand_binop (submode, xor_optab, xor0, lo[1],
NULL_RTX, 0, OPTAB_WIDEN); NULL_RTX, 0, OPTAB_WIDEN);
tmp = expand_binop (SImode, ior_optab, xor1, xor0, tmp = expand_binop (submode, ior_optab, xor1, xor0,
NULL_RTX, 0, OPTAB_WIDEN); NULL_RTX, 0, OPTAB_WIDEN);
ix86_compare_op0 = tmp; ix86_compare_op0 = tmp;
...@@ -9547,8 +9559,7 @@ ix86_expand_setcc (enum rtx_code code, rtx dest) ...@@ -9547,8 +9559,7 @@ ix86_expand_setcc (enum rtx_code code, rtx dest)
rtx ret, tmp, tmpreg, equiv; rtx ret, tmp, tmpreg, equiv;
rtx second_test, bypass_test; rtx second_test, bypass_test;
if (GET_MODE (ix86_compare_op0) == DImode if (GET_MODE (ix86_compare_op0) == (TARGET_64BIT ? TImode : DImode))
&& !TARGET_64BIT)
return 0; /* FAIL */ return 0; /* FAIL */
gcc_assert (GET_MODE (dest) == QImode); gcc_assert (GET_MODE (dest) == QImode);
...@@ -9603,7 +9614,7 @@ ix86_expand_carry_flag_compare (enum rtx_code code, rtx op0, rtx op1, rtx *pop) ...@@ -9603,7 +9614,7 @@ ix86_expand_carry_flag_compare (enum rtx_code code, rtx op0, rtx op1, rtx *pop)
/* Do not handle DImode compares that go trought special path. Also we can't /* Do not handle DImode compares that go trought special path. Also we can't
deal with FP compares yet. This is possible to add. */ deal with FP compares yet. This is possible to add. */
if ((mode == DImode && !TARGET_64BIT)) if (mode == (TARGET_64BIT ? TImode : DImode))
return false; return false;
if (FLOAT_MODE_P (mode)) if (FLOAT_MODE_P (mode))
{ {
...@@ -9743,7 +9754,7 @@ ix86_expand_int_movcc (rtx operands[]) ...@@ -9743,7 +9754,7 @@ ix86_expand_int_movcc (rtx operands[])
HImode insns, we'd be swallowed in word prefix ops. */ HImode insns, we'd be swallowed in word prefix ops. */
if ((mode != HImode || TARGET_FAST_PREFIX) if ((mode != HImode || TARGET_FAST_PREFIX)
&& (mode != DImode || TARGET_64BIT) && (mode != (TARGET_64BIT ? TImode : DImode))
&& GET_CODE (operands[2]) == CONST_INT && GET_CODE (operands[2]) == CONST_INT
&& GET_CODE (operands[3]) == CONST_INT) && GET_CODE (operands[3]) == CONST_INT)
{ {
...@@ -11092,68 +11103,81 @@ ix86_split_long_move (rtx operands[]) ...@@ -11092,68 +11103,81 @@ ix86_split_long_move (rtx operands[])
return; return;
} }
/* Helper function of ix86_split_ashldi used to generate an SImode /* Helper function of ix86_split_ashl used to generate an SImode/DImode
left shift by a constant, either using a single shift or left shift by a constant, either using a single shift or
a sequence of add instructions. */ a sequence of add instructions. */
static void static void
ix86_expand_ashlsi3_const (rtx operand, int count) ix86_expand_ashl_const (rtx operand, int count, enum machine_mode mode)
{ {
if (count == 1) if (count == 1)
emit_insn (gen_addsi3 (operand, operand, operand)); {
emit_insn ((mode == DImode
? gen_addsi3
: gen_adddi3) (operand, operand, operand));
}
else if (!optimize_size else if (!optimize_size
&& count * ix86_cost->add <= ix86_cost->shift_const) && count * ix86_cost->add <= ix86_cost->shift_const)
{ {
int i; int i;
for (i=0; i<count; i++) for (i=0; i<count; i++)
emit_insn (gen_addsi3 (operand, operand, operand)); {
emit_insn ((mode == DImode
? gen_addsi3
: gen_adddi3) (operand, operand, operand));
}
} }
else else
emit_insn (gen_ashlsi3 (operand, operand, GEN_INT (count))); emit_insn ((mode == DImode
? gen_ashlsi3
: gen_ashldi3) (operand, operand, GEN_INT (count)));
} }
void void
ix86_split_ashldi (rtx *operands, rtx scratch) ix86_split_ashl (rtx *operands, rtx scratch, enum machine_mode mode)
{ {
rtx low[2], high[2]; rtx low[2], high[2];
int count; int count;
const int single_width = mode == DImode ? 32 : 64;
if (GET_CODE (operands[2]) == CONST_INT) if (GET_CODE (operands[2]) == CONST_INT)
{ {
split_di (operands, 2, low, high); (mode == DImode ? split_di : split_ti) (operands, 2, low, high);
count = INTVAL (operands[2]) & 63; count = INTVAL (operands[2]) & (single_width * 2 - 1);
if (count >= 32) if (count >= single_width)
{ {
emit_move_insn (high[0], low[1]); emit_move_insn (high[0], low[1]);
emit_move_insn (low[0], const0_rtx); emit_move_insn (low[0], const0_rtx);
if (count > 32) if (count > single_width)
ix86_expand_ashlsi3_const (high[0], count - 32); ix86_expand_ashl_const (high[0], count - single_width, mode);
} }
else else
{ {
if (!rtx_equal_p (operands[0], operands[1])) if (!rtx_equal_p (operands[0], operands[1]))
emit_move_insn (operands[0], operands[1]); emit_move_insn (operands[0], operands[1]);
emit_insn (gen_x86_shld_1 (high[0], low[0], GEN_INT (count))); emit_insn ((mode == DImode
ix86_expand_ashlsi3_const (low[0], count); ? gen_x86_shld_1
: gen_x86_64_shld) (high[0], low[0], GEN_INT (count)));
ix86_expand_ashl_const (low[0], count, mode);
} }
return; return;
} }
split_di (operands, 1, low, high); (mode == DImode ? split_di : split_ti) (operands, 1, low, high);
if (operands[1] == const1_rtx) if (operands[1] == const1_rtx)
{ {
/* Assuming we've chosen a QImode capable registers, then 1LL << N /* Assuming we've chosen a QImode capable registers, then 1 << N
can be done with two 32-bit shifts, no branches, no cmoves. */ can be done with two 32/64-bit shifts, no branches, no cmoves. */
if (ANY_QI_REG_P (low[0]) && ANY_QI_REG_P (high[0])) if (ANY_QI_REG_P (low[0]) && ANY_QI_REG_P (high[0]))
{ {
rtx s, d, flags = gen_rtx_REG (CCZmode, FLAGS_REG); rtx s, d, flags = gen_rtx_REG (CCZmode, FLAGS_REG);
ix86_expand_clear (low[0]); ix86_expand_clear (low[0]);
ix86_expand_clear (high[0]); ix86_expand_clear (high[0]);
emit_insn (gen_testqi_ccz_1 (operands[2], GEN_INT (32))); emit_insn (gen_testqi_ccz_1 (operands[2], GEN_INT (single_width)));
d = gen_lowpart (QImode, low[0]); d = gen_lowpart (QImode, low[0]);
d = gen_rtx_STRICT_LOW_PART (VOIDmode, d); d = gen_rtx_STRICT_LOW_PART (VOIDmode, d);
...@@ -11167,7 +11191,7 @@ ix86_split_ashldi (rtx *operands, rtx scratch) ...@@ -11167,7 +11191,7 @@ ix86_split_ashldi (rtx *operands, rtx scratch)
} }
/* Otherwise, we can get the same results by manually performing /* Otherwise, we can get the same results by manually performing
a bit extract operation on bit 5, and then performing the two a bit extract operation on bit 5/6, and then performing the two
shifts. The two methods of getting 0/1 into low/high are exactly shifts. The two methods of getting 0/1 into low/high are exactly
the same size. Avoiding the shift in the bit extract case helps the same size. Avoiding the shift in the bit extract case helps
pentium4 a bit; no one else seems to care much either way. */ pentium4 a bit; no one else seems to care much either way. */
...@@ -11176,29 +11200,39 @@ ix86_split_ashldi (rtx *operands, rtx scratch) ...@@ -11176,29 +11200,39 @@ ix86_split_ashldi (rtx *operands, rtx scratch)
rtx x; rtx x;
if (TARGET_PARTIAL_REG_STALL && !optimize_size) if (TARGET_PARTIAL_REG_STALL && !optimize_size)
x = gen_rtx_ZERO_EXTEND (SImode, operands[2]); x = gen_rtx_ZERO_EXTEND (mode == DImode ? SImode : DImode, operands[2]);
else else
x = gen_lowpart (SImode, operands[2]); x = gen_lowpart (mode == DImode ? SImode : DImode, operands[2]);
emit_insn (gen_rtx_SET (VOIDmode, high[0], x)); emit_insn (gen_rtx_SET (VOIDmode, high[0], x));
emit_insn (gen_lshrsi3 (high[0], high[0], GEN_INT (5))); emit_insn ((mode == DImode
emit_insn (gen_andsi3 (high[0], high[0], GEN_INT (1))); ? gen_lshrsi3
: gen_lshrdi3) (high[0], high[0], GEN_INT (mode == DImode ? 5 : 6)));
emit_insn ((mode == DImode
? gen_andsi3
: gen_anddi3) (high[0], high[0], GEN_INT (1)));
emit_move_insn (low[0], high[0]); emit_move_insn (low[0], high[0]);
emit_insn (gen_xorsi3 (low[0], low[0], GEN_INT (1))); emit_insn ((mode == DImode
? gen_xorsi3
: gen_xordi3) (low[0], low[0], GEN_INT (1)));
} }
emit_insn (gen_ashlsi3 (low[0], low[0], operands[2])); emit_insn ((mode == DImode
emit_insn (gen_ashlsi3 (high[0], high[0], operands[2])); ? gen_ashlsi3
: gen_ashldi3) (low[0], low[0], operands[2]));
emit_insn ((mode == DImode
? gen_ashlsi3
: gen_ashldi3) (high[0], high[0], operands[2]));
return; return;
} }
if (operands[1] == constm1_rtx) if (operands[1] == constm1_rtx)
{ {
/* For -1LL << N, we can avoid the shld instruction, because we /* For -1 << N, we can avoid the shld instruction, because we
know that we're shifting 0...31 ones into a -1. */ know that we're shifting 0...31/63 ones into a -1. */
emit_move_insn (low[0], constm1_rtx); emit_move_insn (low[0], constm1_rtx);
if (optimize_size) if (optimize_size)
emit_move_insn (high[0], low[0]); emit_move_insn (high[0], low[0]);
else else
emit_move_insn (high[0], constm1_rtx); emit_move_insn (high[0], constm1_rtx);
} }
...@@ -11207,53 +11241,71 @@ ix86_split_ashldi (rtx *operands, rtx scratch) ...@@ -11207,53 +11241,71 @@ ix86_split_ashldi (rtx *operands, rtx scratch)
if (!rtx_equal_p (operands[0], operands[1])) if (!rtx_equal_p (operands[0], operands[1]))
emit_move_insn (operands[0], operands[1]); emit_move_insn (operands[0], operands[1]);
split_di (operands, 1, low, high); (mode == DImode ? split_di : split_ti) (operands, 1, low, high);
emit_insn (gen_x86_shld_1 (high[0], low[0], operands[2])); emit_insn ((mode == DImode
? gen_x86_shld_1
: gen_x86_64_shld) (high[0], low[0], operands[2]));
} }
emit_insn (gen_ashlsi3 (low[0], low[0], operands[2])); emit_insn ((mode == DImode ? gen_ashlsi3 : gen_ashldi3) (low[0], low[0], operands[2]));
if (TARGET_CMOVE && scratch) if (TARGET_CMOVE && scratch)
{ {
ix86_expand_clear (scratch); ix86_expand_clear (scratch);
emit_insn (gen_x86_shift_adj_1 (high[0], low[0], operands[2], scratch)); emit_insn ((mode == DImode
? gen_x86_shift_adj_1
: gen_x86_64_shift_adj) (high[0], low[0], operands[2], scratch));
} }
else else
emit_insn (gen_x86_shift_adj_2 (high[0], low[0], operands[2])); emit_insn (gen_x86_shift_adj_2 (high[0], low[0], operands[2]));
} }
void void
ix86_split_ashrdi (rtx *operands, rtx scratch) ix86_split_ashr (rtx *operands, rtx scratch, enum machine_mode mode)
{ {
rtx low[2], high[2]; rtx low[2], high[2];
int count; int count;
const int single_width = mode == DImode ? 32 : 64;
if (GET_CODE (operands[2]) == CONST_INT) if (GET_CODE (operands[2]) == CONST_INT)
{ {
split_di (operands, 2, low, high); (mode == DImode ? split_di : split_ti) (operands, 2, low, high);
count = INTVAL (operands[2]) & 63; count = INTVAL (operands[2]) & (single_width * 2 - 1);
if (count == 63) if (count == single_width * 2 - 1)
{ {
emit_move_insn (high[0], high[1]); emit_move_insn (high[0], high[1]);
emit_insn (gen_ashrsi3 (high[0], high[0], GEN_INT (31))); emit_insn ((mode == DImode
? gen_ashrsi3
: gen_ashrdi3) (high[0], high[0],
GEN_INT (single_width - 1)));
emit_move_insn (low[0], high[0]); emit_move_insn (low[0], high[0]);
} }
else if (count >= 32) else if (count >= single_width)
{ {
emit_move_insn (low[0], high[1]); emit_move_insn (low[0], high[1]);
emit_move_insn (high[0], low[0]); emit_move_insn (high[0], low[0]);
emit_insn (gen_ashrsi3 (high[0], high[0], GEN_INT (31))); emit_insn ((mode == DImode
if (count > 32) ? gen_ashrsi3
emit_insn (gen_ashrsi3 (low[0], low[0], GEN_INT (count - 32))); : gen_ashrdi3) (high[0], high[0],
GEN_INT (single_width - 1)));
if (count > single_width)
emit_insn ((mode == DImode
? gen_ashrsi3
: gen_ashrdi3) (low[0], low[0],
GEN_INT (count - single_width)));
} }
else else
{ {
if (!rtx_equal_p (operands[0], operands[1])) if (!rtx_equal_p (operands[0], operands[1]))
emit_move_insn (operands[0], operands[1]); emit_move_insn (operands[0], operands[1]);
emit_insn (gen_x86_shrd_1 (low[0], high[0], GEN_INT (count))); emit_insn ((mode == DImode
emit_insn (gen_ashrsi3 (high[0], high[0], GEN_INT (count))); ? gen_x86_shrd_1
: gen_x86_64_shrd) (low[0], high[0], GEN_INT (count)));
emit_insn ((mode == DImode
? gen_ashrsi3
: gen_ashrdi3) (high[0], high[0], GEN_INT (count)));
} }
} }
else else
...@@ -11261,17 +11313,26 @@ ix86_split_ashrdi (rtx *operands, rtx scratch) ...@@ -11261,17 +11313,26 @@ ix86_split_ashrdi (rtx *operands, rtx scratch)
if (!rtx_equal_p (operands[0], operands[1])) if (!rtx_equal_p (operands[0], operands[1]))
emit_move_insn (operands[0], operands[1]); emit_move_insn (operands[0], operands[1]);
split_di (operands, 1, low, high); (mode == DImode ? split_di : split_ti) (operands, 1, low, high);
emit_insn (gen_x86_shrd_1 (low[0], high[0], operands[2])); emit_insn ((mode == DImode
emit_insn (gen_ashrsi3 (high[0], high[0], operands[2])); ? gen_x86_shrd_1
: gen_x86_64_shrd) (low[0], high[0], operands[2]));
emit_insn ((mode == DImode
? gen_ashrsi3
: gen_ashrdi3) (high[0], high[0], operands[2]));
if (TARGET_CMOVE && scratch) if (TARGET_CMOVE && scratch)
{ {
emit_move_insn (scratch, high[0]); emit_move_insn (scratch, high[0]);
emit_insn (gen_ashrsi3 (scratch, scratch, GEN_INT (31))); emit_insn ((mode == DImode
emit_insn (gen_x86_shift_adj_1 (low[0], high[0], operands[2], ? gen_ashrsi3
scratch)); : gen_ashrdi3) (scratch, scratch,
GEN_INT (single_width - 1)));
emit_insn ((mode == DImode
? gen_x86_shift_adj_1
: gen_x86_64_shift_adj) (low[0], high[0], operands[2],
scratch));
} }
else else
emit_insn (gen_x86_shift_adj_3 (low[0], high[0], operands[2])); emit_insn (gen_x86_shift_adj_3 (low[0], high[0], operands[2]));
...@@ -11279,30 +11340,38 @@ ix86_split_ashrdi (rtx *operands, rtx scratch) ...@@ -11279,30 +11340,38 @@ ix86_split_ashrdi (rtx *operands, rtx scratch)
} }
void void
ix86_split_lshrdi (rtx *operands, rtx scratch) ix86_split_lshr (rtx *operands, rtx scratch, enum machine_mode mode)
{ {
rtx low[2], high[2]; rtx low[2], high[2];
int count; int count;
const int single_width = mode == DImode ? 32 : 64;
if (GET_CODE (operands[2]) == CONST_INT) if (GET_CODE (operands[2]) == CONST_INT)
{ {
split_di (operands, 2, low, high); (mode == DImode ? split_di : split_ti) (operands, 2, low, high);
count = INTVAL (operands[2]) & 63; count = INTVAL (operands[2]) & (single_width * 2 - 1);
if (count >= 32) if (count >= single_width)
{ {
emit_move_insn (low[0], high[1]); emit_move_insn (low[0], high[1]);
ix86_expand_clear (high[0]); ix86_expand_clear (high[0]);
if (count > 32) if (count > single_width)
emit_insn (gen_lshrsi3 (low[0], low[0], GEN_INT (count - 32))); emit_insn ((mode == DImode
? gen_lshrsi3
: gen_lshrdi3) (low[0], low[0],
GEN_INT (count - single_width)));
} }
else else
{ {
if (!rtx_equal_p (operands[0], operands[1])) if (!rtx_equal_p (operands[0], operands[1]))
emit_move_insn (operands[0], operands[1]); emit_move_insn (operands[0], operands[1]);
emit_insn (gen_x86_shrd_1 (low[0], high[0], GEN_INT (count))); emit_insn ((mode == DImode
emit_insn (gen_lshrsi3 (high[0], high[0], GEN_INT (count))); ? gen_x86_shrd_1
: gen_x86_64_shrd) (low[0], high[0], GEN_INT (count)));
emit_insn ((mode == DImode
? gen_lshrsi3
: gen_lshrdi3) (high[0], high[0], GEN_INT (count)));
} }
} }
else else
...@@ -11310,17 +11379,23 @@ ix86_split_lshrdi (rtx *operands, rtx scratch) ...@@ -11310,17 +11379,23 @@ ix86_split_lshrdi (rtx *operands, rtx scratch)
if (!rtx_equal_p (operands[0], operands[1])) if (!rtx_equal_p (operands[0], operands[1]))
emit_move_insn (operands[0], operands[1]); emit_move_insn (operands[0], operands[1]);
split_di (operands, 1, low, high); (mode == DImode ? split_di : split_ti) (operands, 1, low, high);
emit_insn (gen_x86_shrd_1 (low[0], high[0], operands[2])); emit_insn ((mode == DImode
emit_insn (gen_lshrsi3 (high[0], high[0], operands[2])); ? gen_x86_shrd_1
: gen_x86_64_shrd) (low[0], high[0], operands[2]));
emit_insn ((mode == DImode
? gen_lshrsi3
: gen_lshrdi3) (high[0], high[0], operands[2]));
/* Heh. By reversing the arguments, we can reuse this pattern. */ /* Heh. By reversing the arguments, we can reuse this pattern. */
if (TARGET_CMOVE && scratch) if (TARGET_CMOVE && scratch)
{ {
ix86_expand_clear (scratch); ix86_expand_clear (scratch);
emit_insn (gen_x86_shift_adj_1 (low[0], high[0], operands[2], emit_insn ((mode == DImode
scratch)); ? gen_x86_shift_adj_1
: gen_x86_64_shift_adj) (low[0], high[0], operands[2],
scratch));
} }
else else
emit_insn (gen_x86_shift_adj_2 (low[0], high[0], operands[2])); emit_insn (gen_x86_shift_adj_2 (low[0], high[0], operands[2]));
......
...@@ -1218,7 +1218,7 @@ enum reg_class ...@@ -1218,7 +1218,7 @@ enum reg_class
(C) == 'l' ? INDEX_REGS : \ (C) == 'l' ? INDEX_REGS : \
NO_REGS) NO_REGS)
/* The letters I, J, K, L and M in a register constraint string /* The letters I, J, K, L, M, N, and O in a register constraint string
can be used to stand for particular ranges of immediate operands. can be used to stand for particular ranges of immediate operands.
This macro defines what the ranges are. This macro defines what the ranges are.
C is the letter, and VALUE is a constant value. C is the letter, and VALUE is a constant value.
...@@ -1230,6 +1230,7 @@ enum reg_class ...@@ -1230,6 +1230,7 @@ enum reg_class
L is for andsi as zero-extending move. L is for andsi as zero-extending move.
M is for shifts that can be executed by the "lea" opcode. M is for shifts that can be executed by the "lea" opcode.
N is for immediate operands for out/in instructions (0-255) N is for immediate operands for out/in instructions (0-255)
O is for TImode shifts.
*/ */
#define CONST_OK_FOR_LETTER_P(VALUE, C) \ #define CONST_OK_FOR_LETTER_P(VALUE, C) \
...@@ -1239,6 +1240,7 @@ enum reg_class ...@@ -1239,6 +1240,7 @@ enum reg_class
: (C) == 'L' ? (VALUE) == 0xff || (VALUE) == 0xffff \ : (C) == 'L' ? (VALUE) == 0xff || (VALUE) == 0xffff \
: (C) == 'M' ? (VALUE) >= 0 && (VALUE) <= 3 \ : (C) == 'M' ? (VALUE) >= 0 && (VALUE) <= 3 \
: (C) == 'N' ? (VALUE) >= 0 && (VALUE) <= 255 \ : (C) == 'N' ? (VALUE) >= 0 && (VALUE) <= 255 \
: (C) == 'O' ? (VALUE) >= 0 && (VALUE) <= 127 \
: 0) : 0)
/* Similar, but for floating constants, and defining letters G and H. /* Similar, but for floating constants, and defining letters G and H.
......
...@@ -478,6 +478,19 @@ ...@@ -478,6 +478,19 @@
;; actually generating RTL. The bCOND or sCOND (emitted immediately ;; actually generating RTL. The bCOND or sCOND (emitted immediately
;; after the cmp) will actually emit the cmpM. ;; after the cmp) will actually emit the cmpM.
(define_expand "cmpti"
[(set (reg:CC FLAGS_REG)
(compare:CC (match_operand:TI 0 "nonimmediate_operand" "")
(match_operand:TI 1 "x86_64_general_operand" "")))]
"TARGET_64BIT"
{
if (GET_CODE (operands[0]) == MEM && GET_CODE (operands[1]) == MEM)
operands[0] = force_reg (TImode, operands[0]);
ix86_compare_op0 = operands[0];
ix86_compare_op1 = operands[1];
DONE;
})
(define_expand "cmpdi" (define_expand "cmpdi"
[(set (reg:CC FLAGS_REG) [(set (reg:CC FLAGS_REG)
(compare:CC (match_operand:DI 0 "nonimmediate_operand" "") (compare:CC (match_operand:DI 0 "nonimmediate_operand" "")
...@@ -4694,6 +4707,42 @@ ...@@ -4694,6 +4707,42 @@
;; Add instructions ;; Add instructions
;; %%% splits for addditi3
(define_expand "addti3"
[(set (match_operand:TI 0 "nonimmediate_operand" "")
(plus:TI (match_operand:TI 1 "nonimmediate_operand" "")
(match_operand:TI 2 "x86_64_general_operand" "")))
(clobber (reg:CC FLAGS_REG))]
"TARGET_64BIT"
"ix86_expand_binary_operator (PLUS, TImode, operands); DONE;")
(define_insn "*addti3_1"
[(set (match_operand:TI 0 "nonimmediate_operand" "=r,o")
(plus:TI (match_operand:TI 1 "nonimmediate_operand" "%0,0")
(match_operand:TI 2 "general_operand" "roiF,riF")))
(clobber (reg:CC FLAGS_REG))]
"TARGET_64BIT && ix86_binary_operator_ok (PLUS, TImode, operands)"
"#")
(define_split
[(set (match_operand:TI 0 "nonimmediate_operand" "")
(plus:TI (match_operand:TI 1 "nonimmediate_operand" "")
(match_operand:TI 2 "general_operand" "")))
(clobber (reg:CC FLAGS_REG))]
"TARGET_64BIT && reload_completed"
[(parallel [(set (reg:CC FLAGS_REG) (unspec:CC [(match_dup 1) (match_dup 2)]
UNSPEC_ADD_CARRY))
(set (match_dup 0) (plus:DI (match_dup 1) (match_dup 2)))])
(parallel [(set (match_dup 3)
(plus:DI (plus:DI (ltu:DI (reg:CC FLAGS_REG) (const_int 0))
(match_dup 4))
(match_dup 5)))
(clobber (reg:CC FLAGS_REG))])]
"split_ti (operands+0, 1, operands+0, operands+3);
split_ti (operands+1, 1, operands+1, operands+4);
split_ti (operands+2, 1, operands+2, operands+5);")
;; %%% splits for addsidi3 ;; %%% splits for addsidi3
; [(set (match_operand:DI 0 "nonimmediate_operand" "") ; [(set (match_operand:DI 0 "nonimmediate_operand" "")
; (plus:DI (match_operand:DI 1 "general_operand" "") ; (plus:DI (match_operand:DI 1 "general_operand" "")
...@@ -6392,6 +6441,41 @@ ...@@ -6392,6 +6441,41 @@
;; Subtract instructions ;; Subtract instructions
;; %%% splits for subditi3
(define_expand "subti3"
[(parallel [(set (match_operand:TI 0 "nonimmediate_operand" "")
(minus:TI (match_operand:TI 1 "nonimmediate_operand" "")
(match_operand:TI 2 "x86_64_general_operand" "")))
(clobber (reg:CC FLAGS_REG))])]
"TARGET_64BIT"
"ix86_expand_binary_operator (MINUS, TImode, operands); DONE;")
(define_insn "*subti3_1"
[(set (match_operand:TI 0 "nonimmediate_operand" "=r,o")
(minus:TI (match_operand:TI 1 "nonimmediate_operand" "0,0")
(match_operand:TI 2 "general_operand" "roiF,riF")))
(clobber (reg:CC FLAGS_REG))]
"TARGET_64BIT && ix86_binary_operator_ok (MINUS, TImode, operands)"
"#")
(define_split
[(set (match_operand:TI 0 "nonimmediate_operand" "")
(minus:TI (match_operand:TI 1 "nonimmediate_operand" "")
(match_operand:TI 2 "general_operand" "")))
(clobber (reg:CC FLAGS_REG))]
"TARGET_64BIT && reload_completed"
[(parallel [(set (reg:CC FLAGS_REG) (compare:CC (match_dup 1) (match_dup 2)))
(set (match_dup 0) (minus:DI (match_dup 1) (match_dup 2)))])
(parallel [(set (match_dup 3)
(minus:DI (match_dup 4)
(plus:DI (ltu:DI (reg:CC FLAGS_REG) (const_int 0))
(match_dup 5))))
(clobber (reg:CC FLAGS_REG))])]
"split_ti (operands+0, 1, operands+0, operands+3);
split_ti (operands+1, 1, operands+1, operands+4);
split_ti (operands+2, 1, operands+2, operands+5);")
;; %%% splits for subsidi3 ;; %%% splits for subsidi3
(define_expand "subdi3" (define_expand "subdi3"
...@@ -9198,6 +9282,43 @@ ...@@ -9198,6 +9282,43 @@
;; Negation instructions ;; Negation instructions
(define_expand "negti2"
[(parallel [(set (match_operand:TI 0 "nonimmediate_operand" "")
(neg:TI (match_operand:TI 1 "nonimmediate_operand" "")))
(clobber (reg:CC FLAGS_REG))])]
"TARGET_64BIT"
"ix86_expand_unary_operator (NEG, TImode, operands); DONE;")
(define_insn "*negti2_1"
[(set (match_operand:TI 0 "nonimmediate_operand" "=ro")
(neg:TI (match_operand:TI 1 "general_operand" "0")))
(clobber (reg:CC FLAGS_REG))]
"TARGET_64BIT
&& ix86_unary_operator_ok (NEG, TImode, operands)"
"#")
(define_split
[(set (match_operand:TI 0 "nonimmediate_operand" "")
(neg:TI (match_operand:TI 1 "general_operand" "")))
(clobber (reg:CC FLAGS_REG))]
"TARGET_64BIT && reload_completed"
[(parallel
[(set (reg:CCZ FLAGS_REG)
(compare:CCZ (neg:DI (match_dup 2)) (const_int 0)))
(set (match_dup 0) (neg:DI (match_dup 2)))])
(parallel
[(set (match_dup 1)
(plus:DI (plus:DI (ltu:DI (reg:CC FLAGS_REG) (const_int 0))
(match_dup 3))
(const_int 0)))
(clobber (reg:CC FLAGS_REG))])
(parallel
[(set (match_dup 1)
(neg:DI (match_dup 1)))
(clobber (reg:CC FLAGS_REG))])]
"split_ti (operands+1, 1, operands+2, operands+3);
split_ti (operands+0, 1, operands+0, operands+1);")
(define_expand "negdi2" (define_expand "negdi2"
[(parallel [(set (match_operand:DI 0 "nonimmediate_operand" "") [(parallel [(set (match_operand:DI 0 "nonimmediate_operand" "")
(neg:DI (match_operand:DI 1 "nonimmediate_operand" ""))) (neg:DI (match_operand:DI 1 "nonimmediate_operand" "")))
...@@ -10079,6 +10200,92 @@ ...@@ -10079,6 +10200,92 @@
;; shift pair, instead using moves and sign extension for counts greater ;; shift pair, instead using moves and sign extension for counts greater
;; than 31. ;; than 31.
(define_expand "ashlti3"
[(parallel [(set (match_operand:TI 0 "register_operand" "")
(ashift:TI (match_operand:TI 1 "register_operand" "")
(match_operand:QI 2 "nonmemory_operand" "")))
(clobber (reg:CC FLAGS_REG))])]
"TARGET_64BIT"
{
if (! immediate_operand (operands[2], QImode))
{
emit_insn (gen_ashlti3_1 (operands[0], operands[1], operands[2]));
DONE;
}
ix86_expand_binary_operator (ASHIFT, TImode, operands);
DONE;
})
(define_insn "ashlti3_1"
[(set (match_operand:TI 0 "register_operand" "=r")
(ashift:TI (match_operand:TI 1 "register_operand" "0")
(match_operand:QI 2 "register_operand" "c")))
(clobber (match_scratch:DI 3 "=&r"))
(clobber (reg:CC FLAGS_REG))]
"TARGET_64BIT"
"#"
[(set_attr "type" "multi")])
(define_insn "*ashlti3_2"
[(set (match_operand:TI 0 "register_operand" "=r")
(ashift:TI (match_operand:TI 1 "register_operand" "0")
(match_operand:QI 2 "immediate_operand" "O")))
(clobber (reg:CC FLAGS_REG))]
"TARGET_64BIT"
"#"
[(set_attr "type" "multi")])
(define_split
[(set (match_operand:TI 0 "register_operand" "")
(ashift:TI (match_operand:TI 1 "nonmemory_operand" "")
(match_operand:QI 2 "register_operand" "")))
(clobber (match_scratch:DI 3 ""))
(clobber (reg:CC FLAGS_REG))]
"TARGET_64BIT && reload_completed"
[(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 "register_operand" "")
(match_operand:QI 2 "immediate_operand" "")))
(clobber (reg:CC FLAGS_REG))]
"TARGET_64BIT && reload_completed"
[(const_int 0)]
"ix86_split_ashl (operands, NULL_RTX, TImode); DONE;")
(define_insn "x86_64_shld"
[(set (match_operand:DI 0 "nonimmediate_operand" "+r*m,r*m")
(ior:DI (ashift:DI (match_dup 0)
(match_operand:QI 2 "nonmemory_operand" "J,c"))
(lshiftrt:DI (match_operand:DI 1 "register_operand" "r,r")
(minus:QI (const_int 64) (match_dup 2)))))
(clobber (reg:CC FLAGS_REG))]
"TARGET_64BIT"
"@
shld{q}\t{%2, %1, %0|%0, %1, %2}
shld{q}\t{%s2%1, %0|%0, %1, %2}"
[(set_attr "type" "ishift")
(set_attr "prefix_0f" "1")
(set_attr "mode" "DI")
(set_attr "athlon_decode" "vector")])
(define_expand "x86_64_shift_adj"
[(set (reg:CCZ FLAGS_REG)
(compare:CCZ (and:QI (match_operand:QI 2 "register_operand" "")
(const_int 64))
(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_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"
"")
(define_expand "ashldi3" (define_expand "ashldi3"
[(set (match_operand:DI 0 "shiftdi_operand" "") [(set (match_operand:DI 0 "shiftdi_operand" "")
(ashift:DI (match_operand:DI 1 "ashldi_input_operand" "") (ashift:DI (match_operand:DI 1 "ashldi_input_operand" "")
...@@ -10203,7 +10410,7 @@ ...@@ -10203,7 +10410,7 @@
(match_dup 3)] (match_dup 3)]
"!TARGET_64BIT && TARGET_CMOVE" "!TARGET_64BIT && TARGET_CMOVE"
[(const_int 0)] [(const_int 0)]
"ix86_split_ashldi (operands, operands[3]); DONE;") "ix86_split_ashl (operands, operands[3], DImode); DONE;")
(define_split (define_split
[(set (match_operand:DI 0 "register_operand" "") [(set (match_operand:DI 0 "register_operand" "")
...@@ -10212,7 +10419,7 @@ ...@@ -10212,7 +10419,7 @@
(clobber (reg:CC FLAGS_REG))] (clobber (reg:CC FLAGS_REG))]
"!TARGET_64BIT && (flag_peephole2 ? flow2_completed : reload_completed)" "!TARGET_64BIT && (flag_peephole2 ? flow2_completed : reload_completed)"
[(const_int 0)] [(const_int 0)]
"ix86_split_ashldi (operands, NULL_RTX); DONE;") "ix86_split_ashl (operands, NULL_RTX, DImode); DONE;")
(define_insn "x86_shld_1" (define_insn "x86_shld_1"
[(set (match_operand:SI 0 "nonimmediate_operand" "+r*m,r*m") [(set (match_operand:SI 0 "nonimmediate_operand" "+r*m,r*m")
...@@ -10778,6 +10985,76 @@ ...@@ -10778,6 +10985,76 @@
;; See comment above `ashldi3' about how this works. ;; See comment above `ashldi3' about how this works.
(define_expand "ashrti3"
[(parallel [(set (match_operand:TI 0 "register_operand" "")
(ashiftrt:TI (match_operand:TI 1 "register_operand" "")
(match_operand:QI 2 "nonmemory_operand" "")))
(clobber (reg:CC FLAGS_REG))])]
"TARGET_64BIT"
{
if (! immediate_operand (operands[2], QImode))
{
emit_insn (gen_ashrti3_1 (operands[0], operands[1], operands[2]));
DONE;
}
ix86_expand_binary_operator (ASHIFTRT, TImode, operands);
DONE;
})
(define_insn "ashrti3_1"
[(set (match_operand:TI 0 "register_operand" "=r")
(ashiftrt:TI (match_operand:TI 1 "register_operand" "0")
(match_operand:QI 2 "register_operand" "c")))
(clobber (match_scratch:DI 3 "=&r"))
(clobber (reg:CC FLAGS_REG))]
"TARGET_64BIT"
"#"
[(set_attr "type" "multi")])
(define_insn "*ashrti3_2"
[(set (match_operand:TI 0 "register_operand" "=r")
(ashiftrt:TI (match_operand:TI 1 "register_operand" "0")
(match_operand:QI 2 "immediate_operand" "O")))
(clobber (reg:CC FLAGS_REG))]
"TARGET_64BIT"
"#"
[(set_attr "type" "multi")])
(define_split
[(set (match_operand:TI 0 "register_operand" "")
(ashiftrt:TI (match_operand:TI 1 "register_operand" "")
(match_operand:QI 2 "register_operand" "")))
(clobber (match_scratch:DI 3 ""))
(clobber (reg:CC FLAGS_REG))]
"TARGET_64BIT && reload_completed"
[(const_int 0)]
"ix86_split_ashr (operands, operands[3], TImode); DONE;")
(define_split
[(set (match_operand:TI 0 "register_operand" "")
(ashiftrt:TI (match_operand:TI 1 "register_operand" "")
(match_operand:QI 2 "immediate_operand" "")))
(clobber (reg:CC FLAGS_REG))]
"TARGET_64BIT && reload_completed"
[(const_int 0)]
"ix86_split_ashr (operands, NULL_RTX, TImode); DONE;")
(define_insn "x86_64_shrd"
[(set (match_operand:DI 0 "nonimmediate_operand" "+r*m,r*m")
(ior:DI (ashiftrt:DI (match_dup 0)
(match_operand:QI 2 "nonmemory_operand" "J,c"))
(ashift:DI (match_operand:DI 1 "register_operand" "r,r")
(minus:QI (const_int 64) (match_dup 2)))))
(clobber (reg:CC FLAGS_REG))]
"TARGET_64BIT"
"@
shrd{q}\t{%2, %1, %0|%0, %1, %2}
shrd{q}\t{%s2%1, %0|%0, %1, %2}"
[(set_attr "type" "ishift")
(set_attr "prefix_0f" "1")
(set_attr "mode" "DI")
(set_attr "athlon_decode" "vector")])
(define_expand "ashrdi3" (define_expand "ashrdi3"
[(set (match_operand:DI 0 "shiftdi_operand" "") [(set (match_operand:DI 0 "shiftdi_operand" "")
(ashiftrt:DI (match_operand:DI 1 "shiftdi_operand" "") (ashiftrt:DI (match_operand:DI 1 "shiftdi_operand" "")
...@@ -10887,7 +11164,7 @@ ...@@ -10887,7 +11164,7 @@
(match_dup 3)] (match_dup 3)]
"!TARGET_64BIT && TARGET_CMOVE" "!TARGET_64BIT && TARGET_CMOVE"
[(const_int 0)] [(const_int 0)]
"ix86_split_ashrdi (operands, operands[3]); DONE;") "ix86_split_ashr (operands, operands[3], DImode); DONE;")
(define_split (define_split
[(set (match_operand:DI 0 "register_operand" "") [(set (match_operand:DI 0 "register_operand" "")
...@@ -10896,7 +11173,7 @@ ...@@ -10896,7 +11173,7 @@
(clobber (reg:CC FLAGS_REG))] (clobber (reg:CC FLAGS_REG))]
"!TARGET_64BIT && (flag_peephole2 ? flow2_completed : reload_completed)" "!TARGET_64BIT && (flag_peephole2 ? flow2_completed : reload_completed)"
[(const_int 0)] [(const_int 0)]
"ix86_split_ashrdi (operands, NULL_RTX); DONE;") "ix86_split_ashr (operands, NULL_RTX, DImode); DONE;")
(define_insn "x86_shrd_1" (define_insn "x86_shrd_1"
[(set (match_operand:SI 0 "nonimmediate_operand" "+r*m,r*m") [(set (match_operand:SI 0 "nonimmediate_operand" "+r*m,r*m")
...@@ -11275,6 +11552,60 @@ ...@@ -11275,6 +11552,60 @@
;; See comment above `ashldi3' about how this works. ;; See comment above `ashldi3' about how this works.
(define_expand "lshrti3"
[(parallel [(set (match_operand:TI 0 "register_operand" "")
(lshiftrt:TI (match_operand:TI 1 "register_operand" "")
(match_operand:QI 2 "nonmemory_operand" "")))
(clobber (reg:CC FLAGS_REG))])]
"TARGET_64BIT"
{
if (! immediate_operand (operands[2], QImode))
{
emit_insn (gen_lshrti3_1 (operands[0], operands[1], operands[2]));
DONE;
}
ix86_expand_binary_operator (LSHIFTRT, TImode, operands);
DONE;
})
(define_insn "lshrti3_1"
[(set (match_operand:TI 0 "register_operand" "=r")
(lshiftrt:TI (match_operand:TI 1 "register_operand" "0")
(match_operand:QI 2 "register_operand" "c")))
(clobber (match_scratch:DI 3 "=&r"))
(clobber (reg:CC FLAGS_REG))]
"TARGET_64BIT"
"#"
[(set_attr "type" "multi")])
(define_insn "*lshrti3_2"
[(set (match_operand:TI 0 "register_operand" "=r")
(lshiftrt:TI (match_operand:TI 1 "register_operand" "0")
(match_operand:QI 2 "immediate_operand" "O")))
(clobber (reg:CC FLAGS_REG))]
"TARGET_64BIT"
"#"
[(set_attr "type" "multi")])
(define_split
[(set (match_operand:TI 0 "register_operand" "")
(lshiftrt:TI (match_operand:TI 1 "register_operand" "")
(match_operand:QI 2 "register_operand" "")))
(clobber (match_scratch:DI 3 ""))
(clobber (reg:CC FLAGS_REG))]
"TARGET_64BIT && reload_completed"
[(const_int 0)]
"ix86_split_lshr (operands, operands[3], TImode); DONE;")
(define_split
[(set (match_operand:TI 0 "register_operand" "")
(lshiftrt:TI (match_operand:TI 1 "register_operand" "")
(match_operand:QI 2 "immediate_operand" "")))
(clobber (reg:CC FLAGS_REG))]
"TARGET_64BIT && reload_completed"
[(const_int 0)]
"ix86_split_lshr (operands, NULL_RTX, TImode); DONE;")
(define_expand "lshrdi3" (define_expand "lshrdi3"
[(set (match_operand:DI 0 "shiftdi_operand" "") [(set (match_operand:DI 0 "shiftdi_operand" "")
(lshiftrt:DI (match_operand:DI 1 "shiftdi_operand" "") (lshiftrt:DI (match_operand:DI 1 "shiftdi_operand" "")
...@@ -11367,7 +11698,7 @@ ...@@ -11367,7 +11698,7 @@
(match_dup 3)] (match_dup 3)]
"!TARGET_64BIT && TARGET_CMOVE" "!TARGET_64BIT && TARGET_CMOVE"
[(const_int 0)] [(const_int 0)]
"ix86_split_lshrdi (operands, operands[3]); DONE;") "ix86_split_lshr (operands, operands[3], DImode); DONE;")
(define_split (define_split
[(set (match_operand:DI 0 "register_operand" "") [(set (match_operand:DI 0 "register_operand" "")
...@@ -11376,7 +11707,7 @@ ...@@ -11376,7 +11707,7 @@
(clobber (reg:CC FLAGS_REG))] (clobber (reg:CC FLAGS_REG))]
"!TARGET_64BIT && (flag_peephole2 ? flow2_completed : reload_completed)" "!TARGET_64BIT && (flag_peephole2 ? flow2_completed : reload_completed)"
[(const_int 0)] [(const_int 0)]
"ix86_split_lshrdi (operands, NULL_RTX); DONE;") "ix86_split_lshr (operands, NULL_RTX, DImode); DONE;")
(define_expand "lshrsi3" (define_expand "lshrsi3"
[(set (match_operand:SI 0 "nonimmediate_operand" "") [(set (match_operand:SI 0 "nonimmediate_operand" "")
......
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