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
This commit is contained in:
parent
1876387108
commit
ffa1b3c684
2 changed files with 94 additions and 50 deletions
|
@ -1,3 +1,10 @@
|
|||
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>
|
||||
|
||||
* genattrtab.c (struct attr_value_list, insn_code_values): Move to
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
/* Subroutines used for code generation on IA-32.
|
||||
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.
|
||||
|
||||
|
@ -9384,6 +9384,43 @@ ix86_expand_push (enum machine_mode mode, rtx 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
|
||||
destination to use for the operation. If different from the true
|
||||
destination in operands[0], a copy operation will be required. */
|
||||
|
@ -9392,55 +9429,46 @@ rtx
|
|||
ix86_fixup_binary_operands (enum rtx_code code, enum machine_mode mode,
|
||||
rtx operands[])
|
||||
{
|
||||
int matching_memory;
|
||||
rtx src1, src2, dst;
|
||||
rtx dst = operands[0];
|
||||
rtx src1 = operands[1];
|
||||
rtx src2 = operands[2];
|
||||
|
||||
dst = operands[0];
|
||||
src1 = operands[1];
|
||||
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)))
|
||||
/* Canonicalize operand order. */
|
||||
if (ix86_swap_binary_operands_p (code, mode, operands))
|
||||
{
|
||||
rtx temp = src1;
|
||||
src1 = src2;
|
||||
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. */
|
||||
if (MEM_P (src1) && MEM_P (src2))
|
||||
{
|
||||
if (matching_memory != 2)
|
||||
src2 = force_reg (mode, src2);
|
||||
/* Optimization: Only read from memory once. */
|
||||
if (rtx_equal_p (src1, src2))
|
||||
{
|
||||
src2 = force_reg (mode, src2);
|
||||
src1 = src2;
|
||||
}
|
||||
else
|
||||
src1 = force_reg (mode, src1);
|
||||
src2 = force_reg (mode, src2);
|
||||
}
|
||||
|
||||
/* If the operation is not commutable, source 1 cannot be a constant
|
||||
or non-matching memory. */
|
||||
if ((CONSTANT_P (src1)
|
||||
|| (!matching_memory && MEM_P (src1)))
|
||||
&& GET_RTX_CLASS (code) != RTX_COMM_ARITH)
|
||||
/* If the destination is memory, and we do not have matching source
|
||||
operands, do things in registers. */
|
||||
if (MEM_P (dst) && !rtx_equal_p (dst, src1))
|
||||
dst = gen_reg_rtx (mode);
|
||||
|
||||
/* Source 1 cannot be a constant. */
|
||||
if (CONSTANT_P (src1))
|
||||
src1 = force_reg (mode, src1);
|
||||
|
||||
src1 = operands[1] = src1;
|
||||
src2 = operands[2] = src2;
|
||||
/* Source 1 cannot be a non-matching memory. */
|
||||
if (MEM_P (src1) && !rtx_equal_p (dst, src1))
|
||||
src1 = force_reg (mode, src1);
|
||||
|
||||
operands[1] = src1;
|
||||
operands[2] = src2;
|
||||
return dst;
|
||||
}
|
||||
|
||||
|
@ -9494,28 +9522,37 @@ ix86_expand_binary_operator (enum rtx_code code, enum machine_mode mode,
|
|||
appropriate constraints. */
|
||||
|
||||
int
|
||||
ix86_binary_operator_ok (enum rtx_code code,
|
||||
enum machine_mode mode ATTRIBUTE_UNUSED,
|
||||
ix86_binary_operator_ok (enum rtx_code code, enum machine_mode mode,
|
||||
rtx operands[3])
|
||||
{
|
||||
rtx dst = operands[0];
|
||||
rtx src1 = operands[1];
|
||||
rtx src2 = operands[2];
|
||||
|
||||
/* Both source operands cannot be in memory. */
|
||||
if (MEM_P (operands[1]) && MEM_P (operands[2]))
|
||||
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)
|
||||
if (MEM_P (src1) && MEM_P (src2))
|
||||
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 (MEM_P (operands[0])
|
||||
&& ! (rtx_equal_p (operands[0], operands[1])
|
||||
|| (GET_RTX_CLASS (code) == RTX_COMM_ARITH
|
||||
&& rtx_equal_p (operands[0], operands[2]))))
|
||||
if (MEM_P (dst) && !rtx_equal_p (dst, src1))
|
||||
return 0;
|
||||
|
||||
/* Source 1 cannot be a constant. */
|
||||
if (CONSTANT_P (src1))
|
||||
return 0;
|
||||
/* If the operation is not commutable and the source 1 is memory, we must
|
||||
have a matching destination. */
|
||||
if (MEM_P (operands[1])
|
||||
&& GET_RTX_CLASS (code) != RTX_COMM_ARITH
|
||||
&& ! rtx_equal_p (operands[0], operands[1]))
|
||||
|
||||
/* Source 1 cannot be a non-matching memory. */
|
||||
if (MEM_P (src1) && !rtx_equal_p (dst, src1))
|
||||
return 0;
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
||||
|
|
Loading…
Add table
Reference in a new issue