diff options
Diffstat (limited to 'gcc/config/pa/pa.md')
-rw-r--r-- | gcc/config/pa/pa.md | 114 |
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")]) |