From: Roger Sayle Date: Sat, 27 Jan 2007 02:52:37 +0000 (+0000) Subject: i386.c (ix86_swap_binary_operands_p): New helper function to simplify/factorize opera... X-Git-Tag: releases/gcc-4.3.0~7226 X-Git-Url: http://git.ipfire.org/?a=commitdiff_plain;h=ffa1b3c6848f5109f2aa75b6de16300e2ad0c85e;p=thirdparty%2Fgcc.git 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 --- diff --git a/gcc/ChangeLog b/gcc/ChangeLog index 55a40469404e..2b169ff328aa 100644 --- a/gcc/ChangeLog +++ b/gcc/ChangeLog @@ -1,3 +1,10 @@ +2007-01-26 Roger Sayle + + * 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 * genattrtab.c (struct attr_value_list, insn_code_values): Move to diff --git a/gcc/config/i386/i386.c b/gcc/config/i386/i386.c index 3d1b64d02e29..35b03a9cc48a 100644 --- a/gcc/config/i386/i386.c +++ b/gcc/config/i386/i386.c @@ -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 = 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; }