aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorJeff Law <law@gcc.gnu.org>1993-01-03 12:02:45 -0700
committerJeff Law <law@gcc.gnu.org>1993-01-03 12:02:45 -0700
commit2fe24884e0495e23d37285c3814dd48a97dd3cf4 (patch)
treed10acb095f8dd9824bfcf593731d92bdf71b3d25
parent2c871711c3e85fc89e67b24e39199f1ac0f18b02 (diff)
downloadgcc-2fe24884e0495e23d37285c3814dd48a97dd3cf4.zip
gcc-2fe24884e0495e23d37285c3814dd48a97dd3cf4.tar.gz
gcc-2fe24884e0495e23d37285c3814dd48a97dd3cf4.tar.bz2
pa.c (fmpyaddoperands): Verifys given registers are suitable for use in fmpyadd instructions.
* pa.c (fmpyaddoperands): Verifys given registers are suitable for use in fmpyadd instructions. (fmpysuboperands): Likewise, but for fmpysub instructions. From-SVN: r3070
-rw-r--r--gcc/config/pa/pa.c94
1 files changed, 93 insertions, 1 deletions
diff --git a/gcc/config/pa/pa.c b/gcc/config/pa/pa.c
index 2e36846..d6bf0b7 100644
--- a/gcc/config/pa/pa.c
+++ b/gcc/config/pa/pa.c
@@ -2249,7 +2249,6 @@ static int magic_milli[]= {0, 0, 0, 1, 0, 1, 1, 1, 0, 1, 1, 0, 1, 0,
whether or not we've used them already. [n][0] is signed, [n][1] is
unsigned. */
-
static int div_milli[16][2];
int
@@ -2532,6 +2531,99 @@ function_label_operand (op, mode)
return GET_CODE (op) == SYMBOL_REF && FUNCTION_NAME_P (XSTR (op, 0));
}
+/* Returns 1 if the 5 operands specified in OPERANDS are suitable for
+ use in fmpyadd instructions. Because of the inout operand in the
+ add part this function may swap operands[3] and operands[4] to make them
+ suitable for fmpyadd instructions. */
+int
+fmpyaddoperands(operands)
+ rtx *operands;
+{
+
+ /* All modes must be the same. */
+ if (! (GET_MODE (operands[0]) == GET_MODE (operands[1])
+ && GET_MODE (operands[0]) == GET_MODE (operands[2])
+ && GET_MODE (operands[0]) == GET_MODE (operands[3])
+ && GET_MODE (operands[0]) == GET_MODE (operands[4])
+ && GET_MODE (operands[0]) == GET_MODE (operands[5])))
+ return 0;
+
+ /* Both DFmode and SFmode should work. But using SFmode makes the
+ assembler complain. Just turn it off for now. */
+ if (GET_MODE (operands[0]) != DFmode)
+ return 0;
+
+ /* Only 2 real operands to the addition. One input must be the output. */
+ if (! rtx_equal_p (operands[3], operands[4])
+ && ! rtx_equal_p (operands[3], operands[5]))
+ return 0;
+
+ /* Inout operand of add can not conflict with any operands from multiply. */
+ if (rtx_equal_p (operands[3], operands[0])
+ || rtx_equal_p (operands[3], operands[1])
+ || rtx_equal_p (operands[3], operands[2]))
+ return 0;
+
+ /* multiply can not feed into addition operands. */
+ if (rtx_equal_p (operands[4], operands[0])
+ || rtx_equal_p (operands[5], operands[0]))
+ return 0;
+
+ /* Make the inout operand be operands[5] and operands[3]. Output template
+ assumes operands[4] is the read-only add operand. */
+ if (rtx_equal_p (operands[3], operands[4]))
+ {
+ rtx tmp;
+ tmp = operands[4];
+ operands[4] = operands[5];
+ operands[5] = tmp;
+ }
+
+ /* Passed. Operands are suitable for fmpyadd. */
+ return 1;
+}
+
+/* Returns 1 if the 5 operands specified in OPERANDS are suitable for
+ use in fmpysub instructions. It is very similar to fmpyaddoperands
+ above except operands[3] and operands[4] must be the same without
+ swapping. */
+int
+fmpysuboperands(operands)
+ rtx *operands;
+{
+
+ /* All modes must be the same. */
+ if (! (GET_MODE (operands[0]) == GET_MODE (operands[1])
+ && GET_MODE (operands[0]) == GET_MODE (operands[2])
+ && GET_MODE (operands[0]) == GET_MODE (operands[3])
+ && GET_MODE (operands[0]) == GET_MODE (operands[4])
+ && GET_MODE (operands[0]) == GET_MODE (operands[5])))
+ return 0;
+
+ /* Both DFmode and SFmode should work. But using SFmode makes the
+ assembler complain. Just turn it off for now. */
+ if (GET_MODE (operands[0]) != DFmode)
+ return 0;
+
+ /* Only 2 real operands to the subtraction. One input must be the output. */
+ if (! rtx_equal_p (operands[3], operands[4]))
+ return 0;
+
+ /* multiply can not feed into subtraction. */
+ if (rtx_equal_p (operands[4], operands[0])
+ || rtx_equal_p (operands[5], operands[0]))
+ return 0;
+
+ /* Inout operand of add can not conflict with any operands from multiply. */
+ if (rtx_equal_p (operands[3], operands[0])
+ || rtx_equal_p (operands[3], operands[1])
+ || rtx_equal_p (operands[3], operands[2]))
+ return 0;
+
+ /* Passed. Operands are suitable for fmpysub. */
+ return 1;
+}
+
/* Return 1 if OP is suitable for the second add operand (the unshifed
operand) in an shadd instruction. Allow CONST_INT to work around
a reload bug. */