Commit ffa1b3c6 by Roger Sayle Committed by Roger Sayle

i386.c (ix86_swap_binary_operands_p): New helper function to simplify/factorize…

i386.c (ix86_swap_binary_operands_p): New helper function to simplify/factorize operand order canonicalization.


	* config/i386/i386.c (ix86_swap_binary_operands_p): New helper
	function to simplify/factorize operand order canonicalization.
	(ix86_fixup_binary_operands): Reorganize using the above function.
	(ix86_binary_operator_ok): Likewise.

From-SVN: r121227
parent 18763871
2007-01-26 Roger Sayle <roger@eyesopen.com>
* config/i386/i386.c (ix86_swap_binary_operands_p): New helper
function to simplify/factorize operand order canonicalization.
(ix86_fixup_binary_operands): Reorganize using the above function.
(ix86_binary_operator_ok): Likewise.
2007-01-27 Jakub Jelinek <jakub@redhat.com> 2007-01-27 Jakub Jelinek <jakub@redhat.com>
* genattrtab.c (struct attr_value_list, insn_code_values): Move to * genattrtab.c (struct attr_value_list, insn_code_values): Move to
......
/* Subroutines used for code generation on IA-32. /* Subroutines used for code generation on IA-32.
Copyright (C) 1988, 1992, 1994, 1995, 1996, 1997, 1998, 1999, 2000, 2001, Copyright (C) 1988, 1992, 1994, 1995, 1996, 1997, 1998, 1999, 2000, 2001,
2002, 2003, 2004, 2005, 2006 Free Software Foundation, Inc. 2002, 2003, 2004, 2005, 2006, 2007 Free Software Foundation, Inc.
This file is part of GCC. This file is part of GCC.
...@@ -9384,6 +9384,43 @@ ix86_expand_push (enum machine_mode mode, rtx x) ...@@ -9384,6 +9384,43 @@ ix86_expand_push (enum machine_mode mode, rtx x)
emit_move_insn (tmp, x); emit_move_insn (tmp, x);
} }
/* Helper function of ix86_fixup_binary_operands to canonicalize
operand order. Returns true if the operands should be swapped. */
static bool
ix86_swap_binary_operands_p (enum rtx_code code, enum machine_mode mode,
rtx operands[])
{
rtx dst = operands[0];
rtx src1 = operands[1];
rtx src2 = operands[2];
/* If the operation is not commutative, we can't do anything. */
if (GET_RTX_CLASS (code) != RTX_COMM_ARITH)
return false;
/* Highest priority is that src1 should match dst. */
if (rtx_equal_p (dst, src1))
return false;
if (rtx_equal_p (dst, src2))
return true;
/* Next highest priority is that immediate constants come second. */
if (immediate_operand (src2, mode))
return false;
if (immediate_operand (src1, mode))
return true;
/* Lowest priority is that memory references should come second. */
if (MEM_P (src2))
return false;
if (MEM_P (src1))
return true;
return false;
}
/* Fix up OPERANDS to satisfy ix86_binary_operator_ok. Return the /* Fix up OPERANDS to satisfy ix86_binary_operator_ok. Return the
destination to use for the operation. If different from the true destination to use for the operation. If different from the true
destination in operands[0], a copy operation will be required. */ destination in operands[0], a copy operation will be required. */
...@@ -9392,55 +9429,46 @@ rtx ...@@ -9392,55 +9429,46 @@ rtx
ix86_fixup_binary_operands (enum rtx_code code, enum machine_mode mode, ix86_fixup_binary_operands (enum rtx_code code, enum machine_mode mode,
rtx operands[]) rtx operands[])
{ {
int matching_memory; rtx dst = operands[0];
rtx src1, src2, dst; rtx src1 = operands[1];
rtx src2 = operands[2];
dst = operands[0]; /* Canonicalize operand order. */
src1 = operands[1]; if (ix86_swap_binary_operands_p (code, mode, operands))
src2 = operands[2];
/* Recognize <var1> = <value> <op> <var1> for commutative operators */
if (GET_RTX_CLASS (code) == RTX_COMM_ARITH
&& (rtx_equal_p (dst, src2)
|| immediate_operand (src1, mode)))
{ {
rtx temp = src1; rtx temp = src1;
src1 = src2; src1 = src2;
src2 = temp; src2 = temp;
} }
/* If the destination is memory, and we do not have matching source
operands, do things in registers. */
matching_memory = 0;
if (MEM_P (dst))
{
if (rtx_equal_p (dst, src1))
matching_memory = 1;
else if (GET_RTX_CLASS (code) == RTX_COMM_ARITH
&& rtx_equal_p (dst, src2))
matching_memory = 2;
else
dst = gen_reg_rtx (mode);
}
/* Both source operands cannot be in memory. */ /* Both source operands cannot be in memory. */
if (MEM_P (src1) && MEM_P (src2)) if (MEM_P (src1) && MEM_P (src2))
{ {
if (matching_memory != 2) /* Optimization: Only read from memory once. */
src2 = force_reg (mode, src2); if (rtx_equal_p (src1, src2))
{
src2 = force_reg (mode, src2);
src1 = src2;
}
else else
src1 = force_reg (mode, src1); src2 = force_reg (mode, src2);
} }
/* If the operation is not commutable, source 1 cannot be a constant /* If the destination is memory, and we do not have matching source
or non-matching memory. */ operands, do things in registers. */
if ((CONSTANT_P (src1) if (MEM_P (dst) && !rtx_equal_p (dst, src1))
|| (!matching_memory && MEM_P (src1))) dst = gen_reg_rtx (mode);
&& GET_RTX_CLASS (code) != RTX_COMM_ARITH)
/* Source 1 cannot be a constant. */
if (CONSTANT_P (src1))
src1 = force_reg (mode, src1); src1 = force_reg (mode, src1);
src1 = operands[1] = src1; /* Source 1 cannot be a non-matching memory. */
src2 = operands[2] = src2; if (MEM_P (src1) && !rtx_equal_p (dst, src1))
src1 = force_reg (mode, src1);
operands[1] = src1;
operands[2] = src2;
return dst; return dst;
} }
...@@ -9494,28 +9522,37 @@ ix86_expand_binary_operator (enum rtx_code code, enum machine_mode mode, ...@@ -9494,28 +9522,37 @@ ix86_expand_binary_operator (enum rtx_code code, enum machine_mode mode,
appropriate constraints. */ appropriate constraints. */
int int
ix86_binary_operator_ok (enum rtx_code code, ix86_binary_operator_ok (enum rtx_code code, enum machine_mode mode,
enum machine_mode mode ATTRIBUTE_UNUSED,
rtx operands[3]) rtx operands[3])
{ {
rtx dst = operands[0];
rtx src1 = operands[1];
rtx src2 = operands[2];
/* Both source operands cannot be in memory. */ /* Both source operands cannot be in memory. */
if (MEM_P (operands[1]) && MEM_P (operands[2])) if (MEM_P (src1) && MEM_P (src2))
return 0;
/* If the operation is not commutable, source 1 cannot be a constant. */
if (CONSTANT_P (operands[1]) && GET_RTX_CLASS (code) != RTX_COMM_ARITH)
return 0; return 0;
/* Canonicalize operand order for commutative operators. */
if (ix86_swap_binary_operands_p (code, mode, operands))
{
rtx temp = src1;
src1 = src2;
src2 = temp;
}
/* If the destination is memory, we must have a matching source operand. */ /* If the destination is memory, we must have a matching source operand. */
if (MEM_P (operands[0]) if (MEM_P (dst) && !rtx_equal_p (dst, src1))
&& ! (rtx_equal_p (operands[0], operands[1]) return 0;
|| (GET_RTX_CLASS (code) == RTX_COMM_ARITH
&& rtx_equal_p (operands[0], operands[2])))) /* Source 1 cannot be a constant. */
if (CONSTANT_P (src1))
return 0; return 0;
/* If the operation is not commutable and the source 1 is memory, we must
have a matching destination. */ /* Source 1 cannot be a non-matching memory. */
if (MEM_P (operands[1]) if (MEM_P (src1) && !rtx_equal_p (dst, src1))
&& GET_RTX_CLASS (code) != RTX_COMM_ARITH
&& ! rtx_equal_p (operands[0], operands[1]))
return 0; return 0;
return 1; return 1;
} }
......
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