(iorscc): New recognizer.
authorTorbjorn Granlund <tege@gnu.org>
Fri, 24 Dec 1993 03:13:01 +0000 (03:13 +0000)
committerTorbjorn Granlund <tege@gnu.org>
Fri, 24 Dec 1993 03:13:01 +0000 (03:13 +0000)
2 new recognizers for sub;subb.  1 new recognizer for addi;subb.
(movstrsi): Remove predicates.  Set inline threshold to 8.
(umulsidi3): Change predicates to nonimmediate_operand.
New recognizer for multiply-by-immediate.
(andsi3): Add `!' for register alternative.
(vdepi_ior, vdepi_and): New recognizers.
(vextru rx,1,ry, vextrs rx,1,ry): New recognizers.
(call, call_value): If PIC, emit USE for for
PIC_OFFSET_TABLE_REGNUM.  Use PIC_OFFSET_TABLE_REGNUM rather than 19.

From-SVN: r6294

gcc/config/pa/pa.md

index f15a36d63989f52d949c12e2ef50ede3ba1444fc..472110ff9743428a5d85bbb582aba3971a1869bf 100644 (file)
@@ -74,7 +74,7 @@
                (const_string "true")
                (const_string "false")))
 
-;; For calls and millicode calls.  Allow unconditional branches in the 
+;; For calls and millicode calls.  Allow unconditional branches in the
 ;; delay slot.
 (define_attr "in_call_delay" "false,true"
   (cond [(and (eq_attr "type" "!uncond_branch,branch,cbranch,fbranch,call,dyncall,multi,milli")
@@ -86,7 +86,6 @@
                         (const_string "true")
                         (const_string "false"))]
        (const_string "false")))
-       
 
 
 ;; Unconditional branch, call, and millicode call delay slot description.
 ;; backward branches nullify false.  If the direction is unknown
 ;; then nullification is not allowed.
 (define_delay (eq_attr "type" "cbranch")
-  [(eq_attr "in_branch_delay" "true") 
-   (and (eq_attr "in_nullified_branch_delay" "true") 
+  [(eq_attr "in_branch_delay" "true")
+   (and (eq_attr "in_nullified_branch_delay" "true")
        (attr_flag "forward"))
    (and (eq_attr "in_nullified_branch_delay" "true")
        (attr_flag "backward"))])
 }")
 
 (define_insn ""
- [(set (reg:CCFP 0)
-       (match_operator:CCFP 2 "comparison_operator"
-                           [(match_operand:SF 0 "reg_or_0_operand" "fxG")
-                            (match_operand:SF 1 "reg_or_0_operand" "fxG")]))]
- ""
- "fcmp,sgl,%Y2 %r0,%r1"
- [(set_attr "type" "fpcc")])
 [(set (reg:CCFP 0)
+       (match_operator:CCFP 2 "comparison_operator"
+                            [(match_operand:SF 0 "reg_or_0_operand" "fxG")
+                             (match_operand:SF 1 "reg_or_0_operand" "fxG")]))]
 ""
 "fcmp,sgl,%Y2 %r0,%r1"
 [(set_attr "type" "fpcc")])
 
 (define_insn ""
- [(set (reg:CCFP 0)
-       (match_operator:CCFP 2 "comparison_operator"
-                           [(match_operand:DF 0 "reg_or_0_operand" "fxG")
-                            (match_operand:DF 1 "reg_or_0_operand" "fxG")]))]
- ""
- "fcmp,dbl,%Y2 %r0,%r1"
- [(set_attr "type" "fpcc")])
 [(set (reg:CCFP 0)
+       (match_operator:CCFP 2 "comparison_operator"
+                            [(match_operand:DF 0 "reg_or_0_operand" "fxG")
+                             (match_operand:DF 1 "reg_or_0_operand" "fxG")]))]
 ""
 "fcmp,dbl,%Y2 %r0,%r1"
 [(set_attr "type" "fpcc")])
 
 ;; scc insns.
 
   [(set (match_operand:SI 0 "register_operand" "=r")
        (match_operator:SI 3 "comparison_operator"
                           [(match_operand:SI 1 "register_operand" "r")
-                           (match_operand:SI 2  "arith11_operand" "rI")]))]
+                           (match_operand:SI 2 "arith11_operand" "rI")]))]
   ""
   "com%I2clr,%B3 %2,%1,%0\;ldi 1,%0"
   [(set_attr "type" "binary")
    (set_attr "length" "8")])
 
+(define_insn "iorscc"
+  [(set (match_operand:SI 0 "register_operand" "=r")
+       (ior:SI (match_operator:SI 3 "comparison_operator"
+                                  [(match_operand:SI 1 "register_operand" "r")
+                                   (match_operand:SI 2 "arith11_operand" "rI")])
+               (match_operator:SI 6 "comparison_operator"
+                                  [(match_operand:SI 4 "register_operand" "r")
+                                   (match_operand:SI 5 "arith11_operand" "rI")])))]
+  ""
+  "com%I2clr,%S3 %2,%1,0\;com%I2clr,%B6 %5,%4,%0\;ldi 1,%0"
+  [(set_attr "type" "binary")
+   (set_attr "length" "8")])
+
 ;; Combiner patterns for common operations performed with the output
-;; from an scc insn (negscc and incscc).  
+;; from an scc insn (negscc and incscc).
 (define_insn "negscc"
   [(set (match_operand:SI 0 "register_operand" "=r")
        (neg:SI (match_operator:SI 3 "comparison_operator"
               [(match_operand:SI 1 "register_operand" "r")
-               (match_operand:SI 2  "arith11_operand" "rI")])))]
+               (match_operand:SI 2 "arith11_operand" "rI")])))]
   ""
   "com%I2clr,%B3 %2,%1,%0\;ldi -1,%0"
   [(set_attr "type" "binary")
   [(set_attr "type" "binary")
    (set_attr "length" "8")])
 
+(define_insn ""
+  [(set (match_operand:SI 0 "register_operand" "=r")
+       (minus:SI (minus:SI (match_operand:SI 1 "register_operand" "r")
+                           (gtu:SI (match_operand:SI 2 "register_operand" "r")
+                                   (match_operand:SI 3 "arith11_operand" "rI")))
+                 (match_operand:SI 4 "register_operand" "r")))]
+  ""
+  "sub%I3 %3,%2,0\;subb %1,%4,%0"
+  [(set_attr "type" "binary")
+   (set_attr "length" "8")])
+
 ; This need only accept registers for op3, since canonicalization
 ; replaces ltu with leu when op3 is an integer.
 (define_insn ""
   [(set_attr "type" "binary")
    (set_attr "length" "8")])
 
+(define_insn ""
+  [(set (match_operand:SI 0 "register_operand" "=r")
+       (minus:SI (minus:SI (match_operand:SI 1 "register_operand" "r")
+                           (ltu:SI (match_operand:SI 2 "register_operand" "r")
+                                   (match_operand:SI 3 "register_operand" "r")))
+                 (match_operand:SI 4 "register_operand" "r")))]
+  ""
+  "sub %2,%3,0\;subb %1,%4,%0"
+  [(set_attr "type" "binary")
+   (set_attr "length" "8")])
+
 ; Match only integers for op3 here.  This is used as canonical form of the
 ; ltu pattern when op3 is an integer.  Don't match registers since we can't
 ; make better code than the general incscc pattern.
   [(set_attr "type" "binary")
    (set_attr "length" "8")])
 
+(define_insn ""
+  [(set (match_operand:SI 0 "register_operand" "=r")
+       (minus:SI (minus:SI (match_operand:SI 1 "register_operand" "r")
+                           (leu:SI (match_operand:SI 2 "register_operand" "r")
+                                   (match_operand:SI 3 "int11_operand" "I")))
+                 (match_operand:SI 4 "register_operand" "r")))]
+  ""
+  "addi %k3,%2,0\;subb %1,%4,%0"
+  [(set_attr "type" "binary")
+   (set_attr "length" "8")])
+
 (define_insn "decscc"
   [(set (match_operand:SI 0 "register_operand" "=r,r")
        (minus:SI (match_operand:SI 1 "register_operand" "0,?r")
 
 
 ;; Note a long backward conditional branch with an annulled delay slot
-;; has a length of 12.  
+;; has a length of 12.
 (define_insn ""
   [(set (pc)
        (if_then_else
   ""
   "*
 {
-  return output_cbranch (operands, INSN_ANNULLED_BRANCH_P (insn), 
+  return output_cbranch (operands, INSN_ANNULLED_BRANCH_P (insn),
                         get_attr_length (insn), 0, insn);
 }"
 [(set_attr "type" "cbranch")
- (set (attr "length") 
+ (set (attr "length")
     (if_then_else (lt (abs (minus (match_dup 0) (plus (pc) (const_int 8))))
                      (const_int 8188))
            (const_int 4)
   ""
   "*
 {
-  return output_cbranch (operands, INSN_ANNULLED_BRANCH_P (insn), 
+  return output_cbranch (operands, INSN_ANNULLED_BRANCH_P (insn),
                         get_attr_length (insn), 1, insn);
 }"
 [(set_attr "type" "cbranch")
- (set (attr "length") 
+ (set (attr "length")
     (if_then_else (lt (abs (minus (match_dup 0) (plus (pc) (const_int 8))))
                      (const_int 8188))
            (const_int 4)
   ""
   "*
 {
-  return output_bb (operands, INSN_ANNULLED_BRANCH_P (insn), 
-                        get_attr_length (insn), 
+  return output_bb (operands, INSN_ANNULLED_BRANCH_P (insn),
+                        get_attr_length (insn),
                         (operands[3] != pc_rtx),
                         insn, 0);
 }"
 [(set_attr "type" "cbranch")
- (set (attr "length") 
+ (set (attr "length")
     (if_then_else (lt (abs (minus (match_dup 0) (plus (pc) (const_int 8))))
                      (const_int 8188))
            (const_int 4)
   ""
   "*
 {
-  return output_bb (operands, INSN_ANNULLED_BRANCH_P (insn), 
-                        get_attr_length (insn), 
+  return output_bb (operands, INSN_ANNULLED_BRANCH_P (insn),
+                        get_attr_length (insn),
                         (operands[3] != pc_rtx),
                         insn, 1);
 }"
 [(set_attr "type" "cbranch")
- (set (attr "length") 
+ (set (attr "length")
     (if_then_else (lt (abs (minus (match_dup 0) (plus (pc) (const_int 8))))
                      (const_int 8188))
            (const_int 4)
    (set_attr "length" "4")])
 
 (define_insn ""
-  [(set (match_operand:SI 0 "reg_or_nonsymb_mem_operand" 
+  [(set (match_operand:SI 0 "reg_or_nonsymb_mem_operand"
                                "=r,r,r,r,r,Q,*q,!fx,fx,*T")
-       (match_operand:SI 1 "move_operand" 
+       (match_operand:SI 1 "move_operand"
                                "rM,J,N,K,Q,rM,rM,!fxM,*T,fx"))]
   "register_operand (operands[0], SImode)
    || reg_or_0_operand (operands[1], SImode)"
 ;; seem to be a way around it.  Only recognize it while reloading.
 (define_insn ""
   [(set (match_operand:SI 0 "register_operand" "&=r")
-       (mem:SI (plus:SI (plus:SI 
+       (mem:SI (plus:SI (plus:SI
                            (mult:SI (match_operand:SI 1 "register_operand" "r")
                                     (const_int 4))
                            (match_operand:SI 2 "register_operand" "r"))
   [(set (match_operand:SI 3 "register_operand" "r")
        (mem:SI (match_operand:SI 1 "register_operand" "0")))
    (set (match_operand:SI 0 "register_operand" "=r")
-       (plus:SI (match_dup 1) 
+       (plus:SI (match_dup 1)
                 (match_operand:SI 2 "post_cint_operand" "")))]
   ""
   "*
   [(set (mem:SI (match_operand:SI 1 "register_operand" "0"))
        (match_operand:SI 3 "reg_or_0_operand" "rM"))
    (set (match_operand:SI 0 "register_operand" "=r")
-       (plus:SI (match_dup 1) 
+       (plus:SI (match_dup 1)
                 (match_operand:SI 2 "post_cint_operand" "")))]
   ""
   "*
 (define_insn ""
   [(set (match_operand:SI 0 "register_operand" "=a")
        (high:SI (match_operand 1 "" "")))]
-  "symbolic_operand(operands[1], Pmode)
+  "symbolic_operand (operands[1], Pmode)
    && ! function_label_operand (operands[1])
    && ! read_only_operand (operands[1])"
   "@
   [(set_attr "type" "binary")
    (set_attr "length" "4")])
 
-;; This is for use in the prologue/epilogue code.  We need it 
+;; This is for use in the prologue/epilogue code.  We need it
 ;; to add large constants to a stack pointer or frame pointer.
 ;; Because of the additional %r1 pressure, we probably do not
 ;; want to use this in general code, so make it available
 ;; Now that a symbolic_address plus a constant is broken up early
 ;; in the compilation phase (for better CSE) we need a special
 ;; combiner pattern to load the symbolic address plus the constant
-;; in only 2 instructions. (For cases where the symbolic address 
+;; in only 2 instructions. (For cases where the symbolic address
 ;; was not a common subexpression.)
 (define_split
   [(set (match_operand:SI 0 "register_operand" "")
 ;; seem to be a way around it.  Only recognize it while reloading.
 (define_insn ""
   [(set (match_operand:HI 0 "register_operand" "=&r")
-       (mem:HI (plus:SI (plus:SI 
+       (mem:HI (plus:SI (plus:SI
                            (mult:SI (match_operand:SI 2 "register_operand" "r")
                                     (const_int 2))
                            (match_operand:SI 1 "register_operand" "r"))
 ;; that anything generated as this insn will be recognized as one
 ;; and that it will not successfully combine with anything.
 (define_expand "movstrsi"
-  [(parallel [(set (mem:BLK (match_operand:BLK 0 "general_operand" ""))
-                  (mem:BLK (match_operand:BLK 1 "general_operand" "")))
+  [(parallel [(set (mem:BLK (match_operand:BLK 0 "" ""))
+                  (mem:BLK (match_operand:BLK 1 "" "")))
              (clobber (match_dup 0))
              (clobber (match_dup 1))
              (clobber (match_dup 4))
      runtime and make the optimal decisions.  */
      if (INTVAL (operands[3]) < 4
         && (GET_CODE (operands[2]) != CONST_INT
-            || (INTVAL (operands[2]) / INTVAL (operands[3]) > 16)))
+            || (INTVAL (operands[2]) / INTVAL (operands[3]) > 8)))
        FAIL;
 
   operands[0] = copy_to_mode_reg (SImode, XEXP (operands[0], 0));
 ;;
 ;; For integer registers we use ldil;ldo to set the appropriate
 ;; value.
-;; 
+;;
 ;; This must come before the movdf pattern, and it must be present
 ;; to handle obscure reloading cases.
 (define_insn ""
    || reg_or_0_operand (operands[1], DFmode)"
   "*
 {
-  if (FP_REG_P (operands[0]) || FP_REG_P (operands[1]) 
+  if (FP_REG_P (operands[0]) || FP_REG_P (operands[1])
       || operands[1] == CONST0_RTX (DFmode))
     return output_fp_move_double (operands);
   return output_move_double (operands);
 ;; is the frame pointer.  This is a kludge, but there doesn't
 ;; seem to be a way around it.  Only recognize it while reloading.
 ;; Ugh. Output is a FP register; so we need to earlyclobber something
-;; else as a temporary. 
+;; else as a temporary.
 (define_insn ""
   [(set (match_operand:DF 0 "register_operand" "=fx")
-       (mem:DF (plus:SI 
-                 (plus:SI 
+       (mem:DF (plus:SI
+                 (plus:SI
                    (mult:SI (match_operand:SI 1 "register_operand" "+&r")
                             (const_int 8))
                    (match_operand:SI 2 "register_operand" "r"))
 ;; is the frame pointer.  This is a kludge, but there doesn't
 ;; seem to be a way around it.  Only recognize it while reloading.
 ;; Ugh. Output is a FP register; so we need to earlyclobber something
-;; else as a temporary. 
+;; else as a temporary.
 (define_insn ""
-  [(set (mem:DF (plus:SI 
-                 (plus:SI 
+  [(set (mem:DF (plus:SI
+                 (plus:SI
                     (mult:SI (match_operand:SI 1 "register_operand" "+&r")
                              (const_int 8))
                     (match_operand:SI 2 "register_operand" "r"))
 ;;
 ;; For integer registers we use ldil;ldo to set the appropriate
 ;; value.
-;; 
+;;
 ;; This must come before the movsf pattern, and it must be present
 ;; to handle obscure reloading cases.
 (define_insn ""
 ;; is the frame pointer.  This is a kludge, but there doesn't
 ;; seem to be a way around it.  Only recognize it while reloading.
 ;; Ugh. Output is a FP register; so we need to earlyclobber something
-;; else as a temporary. 
+;; else as a temporary.
 (define_insn ""
   [(set (match_operand:SF 0 "register_operand" "=fx")
-       (mem:SF (plus:SI 
-                 (plus:SI 
+       (mem:SF (plus:SI
+                 (plus:SI
                    (mult:SI (match_operand:SI 1 "register_operand" "+&r")
                             (const_int 4))
                    (match_operand:SI 2 "register_operand" "r"))
 ;; is the frame pointer.  This is a kludge, but there doesn't
 ;; seem to be a way around it.  Only recognize it while reloading.
 ;; Ugh. Output is a FP register; so we need to earlyclobber something
-;; else as a temporary. 
+;; else as a temporary.
 (define_insn ""
-  [(set (mem:SF (plus:SI 
-                 (plus:SI 
+  [(set (mem:SF (plus:SI
+                 (plus:SI
                     (mult:SI (match_operand:SI 1 "register_operand" "+&r")
                              (const_int 4))
                     (match_operand:SI 2 "register_operand" "r"))
        (plus:SI (match_operand:SI 1 "register_operand" "")
                 (match_operand:SI 2 "const_int_operand" "")))
    (clobber (match_operand:SI 4 "register_operand" ""))]
-  "! cint_ok_for_move (INTVAL (operands[2])) 
+  "! cint_ok_for_move (INTVAL (operands[2]))
    && VAL_14_BITS_P (INTVAL (operands[2]) >> 1)"
   [(set (match_dup 4) (plus:SI (match_dup 1) (match_dup 2)))
    (set (match_dup 0) (plus:SI (match_dup 4) (match_dup 3)))]
       operands[2] = GEN_INT (INTVAL (operands[2]) / 8);
       operands[3] = GEN_INT (8);
     }
-  else 
+  else
     FAIL;
 }")
 
 }")
 
 (define_insn "umulsidi3"
-  [(set (match_operand:DI 0 "register_operand" "=x")
-       (mult:DI (zero_extend:DI (match_operand:SI 1 "register_operand" "x"))
-                (zero_extend:DI (match_operand:SI 2 "register_operand" "x"))))]
+  [(set (match_operand:DI 0 "nonimmediate_operand" "=x")
+       (mult:DI (zero_extend:DI (match_operand:SI 1 "nonimmediate_operand" "x"))
+                (zero_extend:DI (match_operand:SI 2 "nonimmediate_operand" "x"))))]
   "TARGET_SNAKE && ! TARGET_DISABLE_FPREGS"
   "xmpyu %1,%2,%0"
   [(set_attr "type" "fpmul")])
 
+(define_insn ""
+  [(set (match_operand:DI 0 "nonimmediate_operand" "=x")
+       (mult:DI (zero_extend:DI (match_operand:SI 1 "nonimmediate_operand" "x"))
+                (match_operand:DI 2 "uint32_operand" "x")))]
+  "TARGET_SNAKE && ! TARGET_DISABLE_FPREGS"
+  "xmpyu %1,%R2,%0"
+  [(set_attr "type" "fpmul")])
+
 (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 31))]
- ""
- "*
- return output_div_insn (operands, 0, insn);"
- [(set_attr "type" "milli")])
 ""
 "*
  return output_div_insn (operands, 0, insn);"
 [(set_attr "type" "milli")])
 
 (define_expand "udivsi3"
   [(set (reg:SI 26) (match_operand:SI 1 "move_operand" ""))
                                 gen_rtx (UDIV, SImode,
                                          gen_rtx (REG, SImode, 26),
                                          gen_rtx (REG, SImode, 25))),
-                    gen_rtx (CLOBBER, VOIDmode, operands[3]), 
+                    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)))));
    (clobber (reg:SI 26))
    (clobber (reg:SI 25))
    (clobber (reg:SI 31))]
- ""
- "*
- return output_div_insn (operands, 1, insn);"
- [(set_attr "type" "milli")])
 ""
 "*
  return output_div_insn (operands, 1, insn);"
 [(set_attr "type" "milli")])
 
 (define_expand "modsi3"
   [(set (reg:SI 26) (match_operand:SI 1 "move_operand" ""))
                             gen_rtx (MOD, SImode,
                                      gen_rtx (REG, SImode, 26),
                                      gen_rtx (REG, SImode, 25))),
-                gen_rtx (CLOBBER, VOIDmode, operands[3]), 
+                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 (UMOD, SImode,
                                      gen_rtx (REG, SImode, 26),
                                      gen_rtx (REG, SImode, 25))),
-                gen_rtx (CLOBBER, VOIDmode, operands[3]), 
+                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)))));
   "and %1,%2,%0\;and %R1,%R2,%R0"
   [(set_attr "length" "8")])
 
+; The ! for op1 makes reload prefer zdepi instead of loading a huge
+; constant with ldil;ldo.
 (define_insn "andsi3"
   [(set (match_operand:SI 0 "register_operand" "=r,r")
-       (and:SI (match_operand:SI 1 "register_operand" "%r,0")
+       (and:SI (match_operand:SI 1 "register_operand" "%!r,0")
                (match_operand:SI 2 "and_operand" "rO,P")))]
   ""
   "* return output_and (operands); "
          emit_insn (gen_zvdep32 (operands[0], operands[1], temp));
       DONE;
     }
-  /* Make sure both inputs are not constants, 
+  /* Make sure both inputs are not constants,
      the recognizer can't handle that.  */
   operands[1] = force_reg (SImode, operands[1]);
 }")
   return \"zvdepi %1,%2,%0\";
 }")
 
+(define_insn "vdepi_ior"
+  [(set (match_operand:SI 0 "register_operand" "=r")
+       (ior:SI (ashift:SI (match_operand:SI 1 "const_int_operand" "")
+                          (minus:SI (const_int 31)
+                                    (match_operand:SI 2 "register_operand" "q")))
+               (match_operand:SI 3 "register_operand" "0")))]
+  ; accept ...0001...1, can this be generalized?
+  "exact_log2 (INTVAL (operands[1]) + 1) >= 0"
+  "*
+{
+  int x = INTVAL (operands[1]);
+  operands[2] = GEN_INT (exact_log2 (x + 1));
+  return \"vdepi -1,%2,%0\";
+}")
+
+(define_insn "vdepi_and"
+  [(set (match_operand:SI 0 "register_operand" "=r")
+       (and:SI (rotate:SI (match_operand:SI 1 "const_int_operand" "")
+                          (minus:SI (const_int 31)
+                                    (match_operand:SI 2 "register_operand" "q")))
+               (match_operand:SI 3 "register_operand" "0")))]
+  ; this can be generalized...!
+  "INTVAL (operands[1]) == -2"
+  "*
+{
+  int x = INTVAL (operands[1]);
+  operands[2] = GEN_INT (exact_log2 ((~x) + 1));
+  return \"vdepi 0,%2,%0\";
+}")
+
 (define_expand "ashrsi3"
   [(set (match_operand:SI 0 "register_operand" "")
        (ashiftrt:SI (match_operand:SI 1 "register_operand" "")
   "bv%* 0(%%r2)"
   [(set_attr "type" "branch")])
 
-;; Use a different pattern for functions which have non-trivial 
+;; Use a different pattern for functions which have non-trivial
 ;; epilogues so as not to confuse jump and reorg.
 (define_insn "return_internal"
   [(use (reg:SI 2))
   ""
   "
 {
-  /* Try to use the trivial return first.  Else use the full 
+  /* Try to use the trivial return first.  Else use the full
      epilogue.  */
   if (hppa_can_use_return_insn_p ())
    emit_jump_insn (gen_return ());
    (set (attr "length")
     (cond [(eq (symbol_ref "jump_in_call_delay (insn)") (const_int 0))
           (const_int 4)
-;; If the jump is in the delay slot of a call, then its length depends 
+;; If the jump is in the delay slot of a call, then its length depends
 ;; on whether or not we can add the proper offset to %r2 with an ldo
 ;; instruction.
           (lt (abs (minus (match_dup 0) (plus (pc) (const_int 8))))
       return \"sub,>> %0,%1,0\;blr,n %0,0\;b,n %l3\";
     }
 }"
- [(set_attr "length" "12")])
 [(set_attr "length" "12")])
 
 ;; Need nops for the calls because execution is supposed to continue
 ;; past; we don't want to nullify an instruction that we need.
 ;;- jump to subroutine
 
 (define_expand "call"
- [(parallel [(call (match_operand:SI 0 "" "")
-                  (match_operand 1 "" ""))
-            (clobber (reg:SI 2))])]
- ""
- "
 [(parallel [(call (match_operand:SI 0 "" "")
+                   (match_operand 1 "" ""))
+             (clobber (reg:SI 2))])]
 ""
 "
 {
   rtx op;
-  
-  if (TARGET_LONG_CALLS) 
+
+  if (flag_pic)
+    emit_insn (gen_rtx (USE, VOIDmode,
+                       gen_rtx (REG, Pmode, PIC_OFFSET_TABLE_REGNUM)));
+
+  if (TARGET_LONG_CALLS)
     op = force_reg (SImode, XEXP (operands[0], 0));
   else
     op = XEXP (operands[0], 0);
       if (!hppa_save_pic_table_rtx)
        hppa_save_pic_table_rtx = gen_reg_rtx (Pmode);
       emit_insn (gen_rtx (SET, VOIDmode,
-                         gen_rtx (REG, Pmode, 19), hppa_save_pic_table_rtx));
+                         gen_rtx (REG, Pmode, PIC_OFFSET_TABLE_REGNUM),
+                         hppa_save_pic_table_rtx));
     }
   DONE;
 }")
 
 (define_insn "call_internal_symref"
- [(call (mem:SI (match_operand:SI 0 "call_operand_address" ""))
-       (match_operand 1 "" "i"))
-  (clobber (reg:SI 2))
-  (use (const_int 0))]
- "! TARGET_LONG_CALLS"
- "*
 [(call (mem:SI (match_operand:SI 0 "call_operand_address" ""))
+        (match_operand 1 "" "i"))
+   (clobber (reg:SI 2))
+   (use (const_int 0))]
 "! TARGET_LONG_CALLS"
 "*
 {
   output_arg_descriptor (insn);
   return output_call (insn, operands[0], gen_rtx (REG, SImode, 2));
 }"
- [(set_attr "type" "call")
-  (set_attr "length" "4")])
 [(set_attr "type" "call")
+   (set_attr "length" "4")])
 
 (define_insn "call_internal_reg"
- [(call (mem:SI (match_operand:SI 0 "register_operand" "r"))
-       (match_operand 1 "" "i"))
-  (clobber (reg:SI 2))
-  (use (const_int 1))]
- ""
- "copy %r0,%%r22\;.CALL\\tARGW0=GR\;bl $$dyncall,%%r31\;copy %%r31,%%r2"
- [(set_attr "type" "dyncall")
-  (set_attr "length" "12")])
 [(call (mem:SI (match_operand:SI 0 "register_operand" "r"))
+        (match_operand 1 "" "i"))
+   (clobber (reg:SI 2))
+   (use (const_int 1))]
 ""
 "copy %r0,%%r22\;.CALL\\tARGW0=GR\;bl $$dyncall,%%r31\;copy %%r31,%%r2"
 [(set_attr "type" "dyncall")
+   (set_attr "length" "12")])
 
 (define_expand "call_value"
   [(parallel [(set (match_operand 0 "" "")
   "
 {
   rtx op;
-  
-  if (TARGET_LONG_CALLS) 
+
+  if (flag_pic)
+    emit_insn (gen_rtx (USE, VOIDmode,
+                       gen_rtx (REG, Pmode, PIC_OFFSET_TABLE_REGNUM)));
+
+  if (TARGET_LONG_CALLS)
     op = force_reg (SImode, XEXP (operands[1], 0));
   else
     op = XEXP (operands[1], 0);
       if (!hppa_save_pic_table_rtx)
        hppa_save_pic_table_rtx = gen_reg_rtx (Pmode);
       emit_insn (gen_rtx (SET, VOIDmode,
-                         gen_rtx (REG, Pmode, 19), hppa_save_pic_table_rtx));
+                         gen_rtx (REG, Pmode, PIC_OFFSET_TABLE_REGNUM),
+                         hppa_save_pic_table_rtx));
     }
   DONE;
 }")
   output_arg_descriptor (insn);
   return output_call (insn, operands[1], gen_rtx (REG, SImode, 2));
 }"
- [(set_attr "type" "call")
-  (set_attr "length" "4")])
 [(set_attr "type" "call")
+   (set_attr "length" "4")])
 
 (define_insn "call_value_internal_reg"
   [(set (match_operand 0 "" "=rfx")
   ;;- Don't use operand 1 for most machines.
   ""
   "copy %r1,%%r22\;.CALL\\tARGW0=GR\;bl $$dyncall,%%r31\;copy %%r31,%%r2"
- [(set_attr "type" "dyncall")
-  (set_attr "length" "12")])
 [(set_attr "type" "dyncall")
+   (set_attr "length" "12")])
 
 ;; Call subroutine returning any type.
 
 (define_insn "indirect_jump"
   [(set (pc) (match_operand:SI 0 "register_operand" "r"))]
   ""
- "bv%* 0(%0)"
- [(set_attr "type" "branch")])
 "bv%* 0(%0)"
 [(set_attr "type" "branch")])
 
 (define_insn "extzv"
   [(set (match_operand:SI 0 "register_operand" "=r")
   ""
   "extru %1,%3+%2-1,%2,%0")
 
+(define_insn ""
+  [(set (match_operand:SI 0 "register_operand" "=r")
+       (zero_extract:SI (match_operand:SI 1 "register_operand" "r")
+                        (const_int 1)
+                        (match_operand:SI 3 "register_operand" "q")))]
+  ""
+  "vextru %1,1,%0")
+
 (define_insn "extv"
   [(set (match_operand:SI 0 "register_operand" "=r")
        (sign_extract:SI (match_operand:SI 1 "register_operand" "r")
   ""
   "extrs %1,%3+%2-1,%2,%0")
 
+(define_insn ""
+  [(set (match_operand:SI 0 "register_operand" "=r")
+       (sign_extract:SI (match_operand:SI 1 "register_operand" "r")
+                        (const_int 1)
+                        (match_operand:SI 3 "register_operand" "q")))]
+  ""
+  "vextrs %1,1,%0")
+
 (define_insn "insv"
   [(set (zero_extract:SI (match_operand:SI 0 "register_operand" "+r,r")
                         (match_operand:SI 1 "uint5_operand" "")
    (clobber (match_scratch:SI 4 "=X,r,r"))]
   ""
   "* return output_dbra (operands, insn, which_alternative); "
-;; Do not expect to understand this the first time through.  
+;; Do not expect to understand this the first time through.
 [(set_attr "type" "cbranch,multi,multi")
  (set (attr "length")
       (if_then_else (eq_attr "alternative" "0")
 ;; Extra goo to deal with additional reload insns.
        (if_then_else (eq_attr "alternative" "1")
          (if_then_else (lt (match_dup 3) (pc))
-           (if_then_else 
+           (if_then_else
              (lt (abs (minus (match_dup 3) (plus (pc) (const_int 24))))
                  (const_int 8188))
              (const_int 24)
              (const_int 28))
-           (if_then_else 
+           (if_then_else
              (lt (abs (minus (match_dup 3) (plus (pc) (const_int 8))))
                  (const_int 8188))
              (const_int 24)
 ;; Loop counter in memory case.
 ;; Extra goo to deal with additional reload insns.
        (if_then_else (lt (match_dup 3) (pc))
-         (if_then_else 
+         (if_then_else
            (lt (abs (minus (match_dup 3) (plus (pc) (const_int 12))))
                (const_int 8188))
            (const_int 12)
            (const_int 16))
-         (if_then_else 
+         (if_then_else
            (lt (abs (minus (match_dup 3) (plus (pc) (const_int 8))))
                (const_int 8188))
            (const_int 12)
            (const_int 16))))))])
 
-;; Simply another variant of the dbra pattern.  More restrictive 
+;; Simply another variant of the dbra pattern.  More restrictive
 ;; in testing the comparison operator as it must worry about overflow
 ;; problems.
 (define_insn ""
    (clobber (match_scratch:SI 4 "=X,r,r"))]
   "INTVAL (operands[5]) == - INTVAL (operands[1])"
 "* return output_dbra (operands, insn, which_alternative);"
-;; Do not expect to understand this the first time through.  
+;; Do not expect to understand this the first time through.
 [(set_attr "type" "cbranch,multi,multi")
  (set (attr "length")
       (if_then_else (eq_attr "alternative" "0")
 ;; Extra goo to deal with additional reload insns.
        (if_then_else (eq_attr "alternative" "1")
          (if_then_else (lt (match_dup 3) (pc))
-           (if_then_else 
+           (if_then_else
              (lt (abs (minus (match_dup 3) (plus (pc) (const_int 24))))
                  (const_int 8188))
              (const_int 24)
              (const_int 28))
-           (if_then_else 
+           (if_then_else
              (lt (abs (minus (match_dup 3) (plus (pc) (const_int 8))))
                  (const_int 8188))
              (const_int 24)
 ;; Loop counter in memory case.
 ;; Extra goo to deal with additional reload insns.
        (if_then_else (lt (match_dup 3) (pc))
-         (if_then_else 
+         (if_then_else
            (lt (abs (minus (match_dup 3) (plus (pc) (const_int 12))))
                (const_int 8188))
            (const_int 12)
            (const_int 16))
-         (if_then_else 
+         (if_then_else
            (lt (abs (minus (match_dup 3) (plus (pc) (const_int 8))))
                (const_int 8188))
            (const_int 12)
        (match_dup 1))]
   ""
 "* return output_movb (operands, insn, which_alternative, 0); "
-;; Do not expect to understand this the first time through.  
+;; Do not expect to understand this the first time through.
 [(set_attr "type" "cbranch,multi,multi")
  (set (attr "length")
       (if_then_else (eq_attr "alternative" "0")
 ;; Extra goo to deal with additional reload insns.
        (if_then_else (eq_attr "alternative" "1")
          (if_then_else (lt (match_dup 3) (pc))
-           (if_then_else 
+           (if_then_else
              (lt (abs (minus (match_dup 3) (plus (pc) (const_int 12))))
                  (const_int 8188))
              (const_int 12)
              (const_int 16))
-           (if_then_else 
+           (if_then_else
              (lt (abs (minus (match_dup 3) (plus (pc) (const_int 8))))
                  (const_int 8188))
              (const_int 12)
              (const_int 16)))
 ;; Loop counter in memory case.
 ;; Extra goo to deal with additional reload insns.
-       (if_then_else 
+       (if_then_else
          (lt (abs (minus (match_dup 3) (plus (pc) (const_int 8))))
              (const_int 8188))
          (const_int 8)
        (match_dup 1))]
   ""
 "* return output_movb (operands, insn, which_alternative, 1); "
-;; Do not expect to understand this the first time through.  
+;; Do not expect to understand this the first time through.
 [(set_attr "type" "cbranch,multi,multi")
  (set (attr "length")
       (if_then_else (eq_attr "alternative" "0")
 ;; Extra goo to deal with additional reload insns.
        (if_then_else (eq_attr "alternative" "1")
          (if_then_else (lt (match_dup 3) (pc))
-           (if_then_else 
+           (if_then_else
              (lt (abs (minus (match_dup 3) (plus (pc) (const_int 12))))
                  (const_int 8188))
              (const_int 12)
              (const_int 16))
-           (if_then_else 
+           (if_then_else
              (lt (abs (minus (match_dup 3) (plus (pc) (const_int 8))))
                  (const_int 8188))
              (const_int 12)
              (const_int 16)))
 ;; Loop counter in memory case.
 ;; Extra goo to deal with additional reload insns.
-       (if_then_else 
+       (if_then_else
          (lt (abs (minus (match_dup 3) (plus (pc) (const_int 8))))
              (const_int 8188))
          (const_int 8)
          (const_int 12)))))])
 
-;; The next four peepholes take advantage of the new 5 operand 
+;; The next four peepholes take advantage of the new 5 operand
 ;; fmpy{add,sub} instructions available on 1.1 CPUS.  Basically
 ;; fmpyadd performs a multiply and add/sub of independent operands
 ;; at the same time.  Because the operands must be independent
     }
 }")
 
-(define_peephole 
+(define_peephole
   [(set (match_operand 3 "register_operand" "+fx")
        (plus (match_operand 4 "register_operand" "fx")
              (match_operand 5 "register_operand" "fx")))