summaryrefslogtreecommitdiff
path: root/gcc/config/arm/arm.c
diff options
context:
space:
mode:
authorramana <ramana@138bc75d-0d04-0410-961f-82ee72b054a4>2012-05-22 09:06:55 +0000
committerramana <ramana@138bc75d-0d04-0410-961f-82ee72b054a4>2012-05-22 09:06:55 +0000
commitf9aa4160acdcc56f456c2f98c25cc4acb14ac56c (patch)
treede16055277b7b505489b96f8ea473e055fc1ec5f /gcc/config/arm/arm.c
parent6940c58b59d91f9bd9c7bfe4d32d0dc5b6a8c31f (diff)
downloadgcc-f9aa4160acdcc56f456c2f98c25cc4acb14ac56c.tar.gz
Fix PR target/53334
2012-05-22 Ramana Radhakrishnan <ramana.radhakrishnan@linaro.org> PR target/53334 * config/arm/arm-protos.h (arm_validize_comparison): Declare. * config/arm/arm.c (arm_validize_comparison): Define. * config/arm/arm.md ("cbranchsi4"): Cleanup expansion and use arm_validize_comparison. ("cbranchdi4"): Likewise. ("cstoredi4"): Likewise. ("movsicc"): Likewise. ("movsfcc"): Likewise. ("movdfcc"): Likewise. git-svn-id: svn+ssh://gcc.gnu.org/svn/gcc/trunk@187761 138bc75d-0d04-0410-961f-82ee72b054a4
Diffstat (limited to 'gcc/config/arm/arm.c')
-rw-r--r--gcc/config/arm/arm.c50
1 files changed, 50 insertions, 0 deletions
diff --git a/gcc/config/arm/arm.c b/gcc/config/arm/arm.c
index 3ad4c752ac8..7a9819705e5 100644
--- a/gcc/config/arm/arm.c
+++ b/gcc/config/arm/arm.c
@@ -26185,4 +26185,54 @@ arm_emit_coreregs_64bit_shift (enum rtx_code code, rtx out, rtx in,
#undef BRANCH
}
+
+/* Returns true if a valid comparison operation and makes
+ the operands in a form that is valid. */
+bool
+arm_validize_comparison (rtx *comparison, rtx * op1, rtx * op2)
+{
+ enum rtx_code code = GET_CODE (*comparison);
+ enum rtx_code canonical_code;
+ enum machine_mode mode = (GET_MODE (*op1) == VOIDmode)
+ ? GET_MODE (*op2) : GET_MODE (*op1);
+
+ gcc_assert (GET_MODE (*op1) != VOIDmode || GET_MODE (*op2) != VOIDmode);
+
+ if (code == UNEQ || code == LTGT)
+ return false;
+
+ canonical_code = arm_canonicalize_comparison (code, op1, op2);
+ PUT_CODE (*comparison, canonical_code);
+
+ switch (mode)
+ {
+ case SImode:
+ if (!arm_add_operand (*op1, mode))
+ *op1 = force_reg (mode, *op1);
+ if (!arm_add_operand (*op2, mode))
+ *op2 = force_reg (mode, *op2);
+ return true;
+
+ case DImode:
+ if (!cmpdi_operand (*op1, mode))
+ *op1 = force_reg (mode, *op1);
+ if (!cmpdi_operand (*op2, mode))
+ *op2 = force_reg (mode, *op2);
+ return true;
+
+ case SFmode:
+ case DFmode:
+ if (!arm_float_compare_operand (*op1, mode))
+ *op1 = force_reg (mode, *op1);
+ if (!arm_float_compare_operand (*op2, mode))
+ *op2 = force_reg (mode, *op2);
+ return true;
+ default:
+ break;
+ }
+
+ return false;
+
+}
+
#include "gt-arm.h"