pa.c (emit_hpdiv_const): Return reg is r2 for 64-bit millicode.
authorAlan Modra <amodra@bigpond.net.au>
Sat, 14 Jul 2001 02:39:39 +0000 (02:39 +0000)
committerAlan Modra <amodra@gcc.gnu.org>
Sat, 14 Jul 2001 02:39:39 +0000 (12:09 +0930)
* config/pa/pa.c (emit_hpdiv_const): Return reg is r2 for 64-bit
millicode.
(insn_refs_are_delayed): Correct comment.
* config/pa/pa.h (INSN_REFERENCES_ARE_DELAYED): Likewise.
* config/pa/pa.md (mulsi3): If TARGET_64BIT, clobber r2
instead of r31.  Make associated insn !TARGET_64BIT, and
provide an additional 64-bit insn that clobbers r2.
(divsi3): Likewise.
(udivsi3): Likewise.
(modsi3): Likewise.
(umodsi3): Likewise.

From-SVN: r44003

gcc/ChangeLog
gcc/config/pa/pa.c
gcc/config/pa/pa.h
gcc/config/pa/pa.md

index 7a365dc201965de0aa894fdabd76c2d52ab746b0..098ffcdfba381b99aad680a3ad3d5b441e556d5a 100644 (file)
@@ -1,3 +1,17 @@
+2001-07-14  Alan Modra  <amodra@bigpond.net.au>
+
+       * config/pa/pa.c (emit_hpdiv_const): Return reg is r2 for 64-bit
+       millicode.
+       (insn_refs_are_delayed): Correct comment.
+       * config/pa/pa.h (INSN_REFERENCES_ARE_DELAYED): Likewise.
+       * config/pa/pa.md (mulsi3): If TARGET_64BIT, clobber r2
+       instead of r31.  Make associated insn !TARGET_64BIT, and
+       provide an additional 64-bit insn that clobbers r2.
+       (divsi3): Likewise.
+       (udivsi3): Likewise.
+       (modsi3): Likewise.
+       (umodsi3): Likewise.
+
 Sat Jul 14 02:58:38 CEST 2001  Jan Hubicka  <jh@suse.cz>
 
        * bb-reorder.c (skip_insn_after_block): Get past the line number notes.
index c1fa4fe8aa5ad5222e834e210e363216ca2976ce..8d9a89124ced5fbba72f42d0fda439d0e8be371c 100644 (file)
@@ -4450,6 +4450,8 @@ emit_hpdiv_const (operands, unsignedp)
       && INTVAL (operands[2]) < 16
       && magic_milli[INTVAL (operands[2])])
     {
+      rtx ret = gen_rtx_REG (SImode, TARGET_64BIT ? 2 : 31);
+
       emit_move_insn (gen_rtx_REG (SImode, 26), operands[1]);
       emit
        (gen_rtx
@@ -4463,7 +4465,7 @@ emit_hpdiv_const (operands, unsignedp)
                     gen_rtx_CLOBBER (VOIDmode, operands[3]),
                     gen_rtx_CLOBBER (VOIDmode, gen_rtx_REG (SImode, 26)),
                     gen_rtx_CLOBBER (VOIDmode, gen_rtx_REG (SImode, 25)),
-                    gen_rtx_CLOBBER (VOIDmode, gen_rtx_REG (SImode, 31)))));
+                    gen_rtx_CLOBBER (VOIDmode, ret))));
       emit_move_insn (operands[0], gen_rtx_REG (SImode, 29));
       return 1;
     }
@@ -6904,12 +6906,18 @@ pa_can_combine_p (new, anchor, floater, reversed, dest, src1, src2)
 
    Millicode calls always expect their arguments in the integer argument
    registers, and always return their result in %r29 (ret1).  They
-   are expected to clobber their arguments, %r1, %r29, and %r31 and
-   nothing else.
-
-   By considering this effects delayed reorg reorg can put insns
-   which set the argument registers into the delay slot of the millicode
-   call -- thus they act more like traditional CALL_INSNs.
+   are expected to clobber their arguments, %r1, %r29, and the return
+   pointer which is %r31 on 32-bit and %r2 on 64-bit, and nothing else.
+
+   This function tells reorg that the references to arguments and
+   millicode calls do not appear to happen until after the millicode call.
+   This allows reorg to put insns which set the argument registers into the
+   delay slot of the millicode call -- thus they act more like traditional
+   CALL_INSNs.
+
+   Note we can not consider side effects of the insn to be delayed because
+   the branch and link insn will clobber the return pointer.  If we happened
+   to use the return pointer in the delay slot of the call, then we lose.
 
    get_attr_type will try to recognize the given insn, so make sure to
    filter out things it will not accept -- SEQUENCE, USE and CLOBBER insns
index 07e7c17c588cf4cbca44a1a514891f80ff7cb8ec..8358e8894687b1fa926262578776c6d7dcf60c12 100644 (file)
@@ -1691,8 +1691,8 @@ while (0)
 
    Millicode calls always expect their arguments in the integer argument
    registers, and always return their result in %r29 (ret1).  They
-   are expected to clobber their arguments, %r1, %r29, and %r31 and
-   nothing else.
+   are expected to clobber their arguments, %r1, %r29, and the return
+   pointer which is %r31 on 32-bit and %r2 on 64-bit, and nothing else.
 
    This macro tells reorg that the references to arguments and
    millicode calls do not appear to happen until after the millicode call.
index 3e2efad05272a0cbb4784d2ccdb57184937c40be..3962de9729bb5040651dad1b03de2e888341464d 100644 (file)
              (clobber (match_dup 3))
              (clobber (reg:SI 26))
              (clobber (reg:SI 25))
-             (clobber (reg:SI 31))])
+             (clobber (match_dup 4))])
    (set (match_operand:SI 0 "general_operand" "") (reg:SI 29))]
   ""
   "
 {
+  operands[4] = gen_rtx_REG (SImode, TARGET_64BIT ? 2 : 31);
   if (TARGET_PA_11 && ! TARGET_DISABLE_FPREGS && ! TARGET_SOFT_FLOAT)
     {
       rtx scratch = gen_reg_rtx (DImode);
    (clobber (reg:SI 26))
    (clobber (reg:SI 25))
    (clobber (reg:SI 31))]
-  ""
+  "!TARGET_64BIT"
   "* return output_mul_insn (0, insn);"
   [(set_attr "type" "milli")
    (set (attr "length")
 ;; Out of reach, can use ble
           (const_int 12)))])
 
+(define_insn ""
+  [(set (reg:SI 29) (mult:SI (reg:SI 26) (reg:SI 25)))
+   (clobber (match_operand:SI 0 "register_operand" "=a"))
+   (clobber (reg:SI 26))
+   (clobber (reg:SI 25))
+   (clobber (reg:SI 2))]
+  "TARGET_64BIT"
+  "* return output_mul_insn (0, insn);"
+  [(set_attr "type" "milli")
+   (set (attr "length") (const_int 4))])
+
 (define_expand "muldi3"
   [(set (match_operand:DI 0 "register_operand" "")
         (mult:DI (match_operand:DI 1 "register_operand" "")
              (clobber (match_dup 4))
              (clobber (reg:SI 26))
              (clobber (reg:SI 25))
-             (clobber (reg:SI 31))])
+             (clobber (match_dup 5))])
    (set (match_operand:SI 0 "general_operand" "") (reg:SI 29))]
   ""
   "
 {
   operands[3] = gen_reg_rtx (SImode);
-  operands[4] = gen_reg_rtx (SImode);
   if (TARGET_64BIT)
-    operands[4] = gen_rtx_REG (SImode, 2);
+    {
+      operands[5] = gen_rtx_REG (SImode, 2);
+      operands[4] = operands[5];
+    }
+  else
+    {
+      operands[5] = gen_rtx_REG (SImode, 31);
+      operands[4] = gen_reg_rtx (SImode);
+    }
   if (GET_CODE (operands[2]) == CONST_INT && emit_hpdiv_const (operands, 0))
     DONE;
 }")
    (clobber (reg:SI 26))
    (clobber (reg:SI 25))
    (clobber (reg:SI 31))]
-  ""
+  "!TARGET_64BIT"
   "*
    return output_div_insn (operands, 0, insn);"
   [(set_attr "type" "milli")
 ;; Out of reach, can use ble
           (const_int 12)))])
 
+(define_insn ""
+  [(set (reg:SI 29)
+       (div:SI (reg:SI 26) (match_operand:SI 0 "div_operand" "")))
+   (clobber (match_operand:SI 1 "register_operand" "=a"))
+   (clobber (match_operand:SI 2 "register_operand" "=&r"))
+   (clobber (reg:SI 26))
+   (clobber (reg:SI 25))
+   (clobber (reg:SI 2))]
+  "TARGET_64BIT"
+  "*
+   return output_div_insn (operands, 0, insn);"
+  [(set_attr "type" "milli")
+   (set (attr "length") (const_int 4))])
+
 (define_expand "udivsi3"
   [(set (reg:SI 26) (match_operand:SI 1 "move_operand" ""))
    (set (reg:SI 25) (match_operand:SI 2 "move_operand" ""))
              (clobber (match_dup 4))
              (clobber (reg:SI 26))
              (clobber (reg:SI 25))
-             (clobber (reg:SI 31))])
+             (clobber (match_dup 5))])
    (set (match_operand:SI 0 "general_operand" "") (reg:SI 29))]
   ""
   "
 {
   operands[3] = gen_reg_rtx (SImode);
-  operands[4] = gen_reg_rtx (SImode);
   if (TARGET_64BIT)
-    operands[4] = gen_rtx_REG (SImode, 2);
+    {
+      operands[5] = gen_rtx_REG (SImode, 2);
+      operands[4] = operands[5];
+    }
+  else
+    {
+      operands[5] = gen_rtx_REG (SImode, 31);
+      operands[4] = gen_reg_rtx (SImode);
+    }
   if (GET_CODE (operands[2]) == CONST_INT && emit_hpdiv_const (operands, 1))
     DONE;
 }")
    (clobber (reg:SI 26))
    (clobber (reg:SI 25))
    (clobber (reg:SI 31))]
-  ""
+  "!TARGET_64BIT"
   "*
    return output_div_insn (operands, 1, insn);"
   [(set_attr "type" "milli")
 ;; Out of reach, can use ble
           (const_int 12)))])
 
+(define_insn ""
+  [(set (reg:SI 29)
+       (udiv:SI (reg:SI 26) (match_operand:SI 0 "div_operand" "")))
+   (clobber (match_operand:SI 1 "register_operand" "=a"))
+   (clobber (match_operand:SI 2 "register_operand" "=&r"))
+   (clobber (reg:SI 26))
+   (clobber (reg:SI 25))
+   (clobber (reg:SI 2))]
+  "TARGET_64BIT"
+  "*
+   return output_div_insn (operands, 1, insn);"
+  [(set_attr "type" "milli")
+   (set (attr "length") (const_int 4))])
+
 (define_expand "modsi3"
   [(set (reg:SI 26) (match_operand:SI 1 "move_operand" ""))
    (set (reg:SI 25) (match_operand:SI 2 "move_operand" ""))
              (clobber (match_dup 4))
              (clobber (reg:SI 26))
              (clobber (reg:SI 25))
-             (clobber (reg:SI 31))])
+             (clobber (match_dup 5))])
    (set (match_operand:SI 0 "general_operand" "") (reg:SI 29))]
   ""
   "
 {
-  operands[4] = gen_reg_rtx (SImode);
   if (TARGET_64BIT)
-    operands[4] = gen_rtx_REG (SImode, 2);
+    {
+      operands[5] = gen_rtx_REG (SImode, 2);
+      operands[4] = operands[5];
+    }
+  else
+    {
+      operands[5] = gen_rtx_REG (SImode, 31);
+      operands[4] = gen_reg_rtx (SImode);
+    }
   operands[3] = gen_reg_rtx (SImode);
 }")
 
    (clobber (reg:SI 26))
    (clobber (reg:SI 25))
    (clobber (reg:SI 31))]
-  ""
+  "!TARGET_64BIT"
   "*
   return output_mod_insn (0, insn);"
   [(set_attr "type" "milli")
 ;; Out of reach, can use ble
           (const_int 12)))])
 
+(define_insn ""
+  [(set (reg:SI 29) (mod:SI (reg:SI 26) (reg:SI 25)))
+   (clobber (match_operand:SI 0 "register_operand" "=a"))
+   (clobber (match_operand:SI 1 "register_operand" "=&r"))
+   (clobber (reg:SI 26))
+   (clobber (reg:SI 25))
+   (clobber (reg:SI 2))]
+  "TARGET_64BIT"
+  "*
+  return output_mod_insn (0, insn);"
+  [(set_attr "type" "milli")
+   (set (attr "length") (const_int 4))])
+
 (define_expand "umodsi3"
   [(set (reg:SI 26) (match_operand:SI 1 "move_operand" ""))
    (set (reg:SI 25) (match_operand:SI 2 "move_operand" ""))
              (clobber (match_dup 4))
              (clobber (reg:SI 26))
              (clobber (reg:SI 25))
-             (clobber (reg:SI 31))])
+             (clobber (match_dup 5))])
    (set (match_operand:SI 0 "general_operand" "") (reg:SI 29))]
   ""
   "
 {
-  operands[4] = gen_reg_rtx (SImode);
   if (TARGET_64BIT)
-    operands[4] = gen_rtx_REG (SImode, 2);
+    {
+      operands[5] = gen_rtx_REG (SImode, 2);
+      operands[4] = operands[5];
+    }
+  else
+    {
+      operands[5] = gen_rtx_REG (SImode, 31);
+      operands[4] = gen_reg_rtx (SImode);
+    }
   operands[3] = gen_reg_rtx (SImode);
 }")
 
    (clobber (reg:SI 26))
    (clobber (reg:SI 25))
    (clobber (reg:SI 31))]
-  ""
+  "!TARGET_64BIT"
   "*
   return output_mod_insn (1, insn);"
   [(set_attr "type" "milli")
 ;; Out of reach, can use ble
           (const_int 12)))])
 
+(define_insn ""
+  [(set (reg:SI 29) (umod:SI (reg:SI 26) (reg:SI 25)))
+   (clobber (match_operand:SI 0 "register_operand" "=a"))
+   (clobber (match_operand:SI 1 "register_operand" "=&r"))
+   (clobber (reg:SI 26))
+   (clobber (reg:SI 25))
+   (clobber (reg:SI 2))]
+  "TARGET_64BIT"
+  "*
+  return output_mod_insn (1, insn);"
+  [(set_attr "type" "milli")
+   (set (attr "length") (const_int 4))])
+
 ;;- and instructions
 ;; We define DImode `and` so with DImode `not` we can get
 ;; DImode `andn`.  Other combinations are possible.