diff options
author | Jeff Law <law@gcc.gnu.org> | 1993-01-03 12:02:45 -0700 |
---|---|---|
committer | Jeff Law <law@gcc.gnu.org> | 1993-01-03 12:02:45 -0700 |
commit | 2fe24884e0495e23d37285c3814dd48a97dd3cf4 (patch) | |
tree | d10acb095f8dd9824bfcf593731d92bdf71b3d25 | |
parent | 2c871711c3e85fc89e67b24e39199f1ac0f18b02 (diff) | |
download | gcc-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.c | 94 |
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. */ |