aboutsummaryrefslogtreecommitdiff
path: root/gcc/config/pa/pa.md
diff options
context:
space:
mode:
Diffstat (limited to 'gcc/config/pa/pa.md')
-rw-r--r--gcc/config/pa/pa.md114
1 files changed, 79 insertions, 35 deletions
diff --git a/gcc/config/pa/pa.md b/gcc/config/pa/pa.md
index 310a248..1635677 100644
--- a/gcc/config/pa/pa.md
+++ b/gcc/config/pa/pa.md
@@ -5322,15 +5322,25 @@
(define_expand "anddi3"
[(set (match_operand:DI 0 "register_operand" "")
- (and:DI (match_operand:DI 1 "arith_double_operand" "")
- (match_operand:DI 2 "arith_double_operand" "")))]
+ (and:DI (match_operand:DI 1 "and_operand" "")
+ (match_operand:DI 2 "and_operand" "")))]
""
"
{
- if (! register_operand (operands[1], DImode)
- || ! register_operand (operands[2], DImode))
- /* Let GCC break this into word-at-a-time operations. */
- FAIL;
+ if (TARGET_64BIT)
+ {
+ /* One operand must be a register operand. */
+ if (!register_operand (operands[1], DImode)
+ && !register_operand (operands[2], DImode))
+ FAIL;
+ }
+ else
+ {
+ /* Both operands must be register operands. */
+ if (!register_operand (operands[1], DImode)
+ || !register_operand (operands[2], DImode))
+ FAIL;
+ }
}")
(define_insn ""
@@ -5391,15 +5401,25 @@
(define_expand "iordi3"
[(set (match_operand:DI 0 "register_operand" "")
- (ior:DI (match_operand:DI 1 "arith_double_operand" "")
- (match_operand:DI 2 "arith_double_operand" "")))]
+ (ior:DI (match_operand:DI 1 "ior_operand" "")
+ (match_operand:DI 2 "ior_operand" "")))]
""
"
{
- if (! register_operand (operands[1], DImode)
- || ! register_operand (operands[2], DImode))
- /* Let GCC break this into word-at-a-time operations. */
- FAIL;
+ if (TARGET_64BIT)
+ {
+ /* One operand must be a register operand. */
+ if (!register_operand (operands[1], DImode)
+ && !register_operand (operands[2], DImode))
+ FAIL;
+ }
+ else
+ {
+ /* Both operands must be register operands. */
+ if (!register_operand (operands[1], DImode)
+ || !register_operand (operands[2], DImode))
+ FAIL;
+ }
}")
(define_insn ""
@@ -5462,15 +5482,11 @@
(define_expand "xordi3"
[(set (match_operand:DI 0 "register_operand" "")
- (xor:DI (match_operand:DI 1 "arith_double_operand" "")
- (match_operand:DI 2 "arith_double_operand" "")))]
+ (xor:DI (match_operand:DI 1 "register_operand" "")
+ (match_operand:DI 2 "register_operand" "")))]
""
"
{
- if (! register_operand (operands[1], DImode)
- || ! register_operand (operands[2], DImode))
- /* Let GCC break this into word-at-a-time operations. */
- FAIL;
}")
(define_insn ""
@@ -5532,12 +5548,10 @@
(define_expand "one_cmpldi2"
[(set (match_operand:DI 0 "register_operand" "")
- (not:DI (match_operand:DI 1 "arith_double_operand" "")))]
+ (not:DI (match_operand:DI 1 "register_operand" "")))]
""
"
{
- if (! register_operand (operands[1], DImode))
- FAIL;
}")
(define_insn ""
@@ -8828,29 +8842,59 @@ add,l %2,%3,%3\;bv,n %%r0(%3)"
return \"\";
}")
-;; Flush the I and D cache line found at the address in operand 0.
+;; Flush the I and D cache lines from the start address (operand0)
+;; to the end address (operand1). No lines are flushed if the end
+;; address is less than the start address (unsigned).
+;;
+;; Because the range of memory flushed is variable and the size of
+;; a MEM can only be a CONST_INT, the patterns specify that they
+;; perform an unspecified volatile operation on all memory.
+;;
+;; The address range for an icache flush must lie within a single
+;; space on targets with non-equivalent space registers.
+;;
;; This is used by the trampoline code for nested functions.
-;; So long as the trampoline itself is less than 32 bytes this
-;; is sufficient.
-
+;;
+;; Operand 0 contains the start address.
+;; Operand 1 contains the end address.
+;; Operand 2 contains the line length to use.
+;; Operand 3 contains the start address (clobbered).
+;; Operands 4 and 5 (icacheflush) are clobbered scratch registers.
(define_insn "dcacheflush"
- [(unspec_volatile [(const_int 1)] 0)
- (use (mem:SI (match_operand 0 "pmode_register_operand" "r")))
- (use (mem:SI (match_operand 1 "pmode_register_operand" "r")))]
+ [(const_int 1)
+ (unspec_volatile [(mem:BLK (scratch))] 0)
+ (use (match_operand 0 "pmode_register_operand" "r"))
+ (use (match_operand 1 "pmode_register_operand" "r"))
+ (use (match_operand 2 "pmode_register_operand" "r"))
+ (clobber (match_scratch 3 "=&0"))]
""
- "fdc 0(%0)\;fdc 0(%1)\;sync"
+ "*
+{
+ if (TARGET_64BIT)
+ return \"cmpb,*<<=,n %3,%1,.\;fdc,m %2(%3)\;sync\";
+ else
+ return \"cmpb,<<=,n %3,%1,.\;fdc,m %2(%3)\;sync\";
+}"
[(set_attr "type" "multi")
(set_attr "length" "12")])
(define_insn "icacheflush"
- [(unspec_volatile [(const_int 2)] 0)
- (use (mem:SI (match_operand 0 "pmode_register_operand" "r")))
- (use (mem:SI (match_operand 1 "pmode_register_operand" "r")))
+ [(const_int 2)
+ (unspec_volatile [(mem:BLK (scratch))] 0)
+ (use (match_operand 0 "pmode_register_operand" "r"))
+ (use (match_operand 1 "pmode_register_operand" "r"))
(use (match_operand 2 "pmode_register_operand" "r"))
- (clobber (match_operand 3 "pmode_register_operand" "=&r"))
- (clobber (match_operand 4 "pmode_register_operand" "=&r"))]
+ (clobber (match_scratch 3 "=&0"))
+ (clobber (match_operand 4 "pmode_register_operand" "=&r"))
+ (clobber (match_operand 5 "pmode_register_operand" "=&r"))]
""
- "mfsp %%sr0,%4\;ldsid (%2),%3\;mtsp %3,%%sr0\;fic 0(%%sr0,%0)\;fic 0(%%sr0,%1)\;sync\;mtsp %4,%%sr0\;nop\;nop\;nop\;nop\;nop\;nop"
+ "*
+{
+ if (TARGET_64BIT)
+ return \"mfsp %%sr0,%5\;ldsid (%3),%4\;mtsp %4,%%sr0\;cmpb,*<<=,n %3,%1,.\;fic,m %2(%%sr0,%3)\;sync\;mtsp %5,%%sr0\;nop\;nop\;nop\;nop\;nop\;nop\";
+ else
+ return \"mfsp %%sr0,%5\;ldsid (%3),%4\;mtsp %4,%%sr0\;cmpb,<<=,n %3,%1,.\;fic,m %2(%%sr0,%3)\;sync\;mtsp %5,%%sr0\;nop\;nop\;nop\;nop\;nop\;nop\";
+}"
[(set_attr "type" "multi")
(set_attr "length" "52")])