OSDN Git Service

* alpha.md (builtin_longjmp): Add missing "DONE".
[pf3gnuchains/gcc-fork.git] / gcc / config / alpha / alpha.md
index b4afc21..59b04f9 100644 (file)
@@ -38,6 +38,8 @@
 ;;     3       builtin_longjmp
 ;;     4       trapb
 ;;     5       prologue_stack_probe_loop
+;;     6       realign
+;;     7       exception_receiver
 \f
 ;; Processor type -- this attribute must exactly match the processor_type
 ;; enumeration in alpha.h.
 ;; separately.
 
 (define_attr "type"
-  "ild,fld,ldsym,ist,fst,ibr,fbr,jsr,iadd,ilog,shift,icmov,fcmov,icmp,imul,fadd,fmul,fcpys,fdiv,fsqrt,misc,mvi,ftoi,itof"
+  "ild,fld,ldsym,ist,fst,ibr,fbr,jsr,iadd,ilog,shift,icmov,fcmov,icmp,imul,fadd,fmul,fcpys,fdiv,fsqrt,misc,mvi,ftoi,itof,multi"
   (const_string "iadd"))
 
+;; Describe a user's asm statement.
+(define_asm_attributes
+  [(set_attr "type" "multi")])
+
 ;; Define the operand size an insn operates on.  Used primarily by mul
 ;; and div operations that have size dependant timings.
 
                 (match_operand:SI 2 "add_operand" "")))]
   ""
   "
-{ emit_insn (gen_rtx_SET (VOIDmode, gen_lowpart (DImode, operands[0]),
-                         gen_rtx_PLUS (DImode,
-                                       gen_lowpart (DImode, operands[1]),
-                                       gen_lowpart (DImode, operands[2]))));
-  DONE;
-} ")
+{
+  if (optimize)
+    {
+      rtx op1 = gen_lowpart (DImode, operands[1]);
+      rtx op2 = gen_lowpart (DImode, operands[2]);
+
+      if (! cse_not_expected)
+        {
+          rtx tmp = gen_reg_rtx (DImode);
+          emit_insn (gen_adddi3 (tmp, op1, op2));
+          emit_move_insn (gen_lowpart (DImode, operands[0]), tmp);
+        }
+      else
+        emit_insn (gen_adddi3 (gen_lowpart (DImode, operands[0]), op1, op2));
+      DONE;
+    }
+}")
 
 (define_insn ""
   [(set (match_operand:SI 0 "register_operand" "=r,r,r,r")
        (sign_extend:DI
         (plus:SI (match_operand:SI 1 "register_operand" "")
                  (match_operand:SI 2 "const_int_operand" ""))))
-   (clobber (match_operand:SI 3 "register_operand" ""))]
+   (clobber (match_operand:SI 3 "reg_not_elim_operand" ""))]
   "! sext_add_operand (operands[2], SImode) && INTVAL (operands[2]) > 0
    && INTVAL (operands[2]) % 4 == 0"
   [(set (match_dup 3) (match_dup 4))
 
 (define_insn ""
   [(set (match_operand:SI 0 "register_operand" "=r,r")
-       (plus:SI (mult:SI (match_operand:SI 1 "reg_or_0_operand" "rJ,rJ")
+       (plus:SI (mult:SI (match_operand:SI 1 "reg_not_elim_operand" "r,r")
                          (match_operand:SI 2 "const48_operand" "I,I"))
                 (match_operand:SI 3 "sext_add_operand" "rI,O")))]
   ""
   "@
-   s%2addl %r1,%3,%0
-   s%2subl %r1,%n3,%0")
+   s%2addl %1,%3,%0
+   s%2subl %1,%n3,%0")
 
 (define_insn ""
   [(set (match_operand:DI 0 "register_operand" "=r,r")
        (sign_extend:DI
-        (plus:SI (mult:SI (match_operand:SI 1 "reg_or_0_operand" "rJ,rJ")
+        (plus:SI (mult:SI (match_operand:SI 1 "reg_not_elim_operand" "r,r")
                           (match_operand:SI 2 "const48_operand" "I,I"))
                  (match_operand:SI 3 "sext_add_operand" "rI,O"))))]
   ""
   "@
-   s%2addl %r1,%3,%0
-   s%2subl %r1,%n3,%0")
+   s%2addl %1,%3,%0
+   s%2subl %1,%n3,%0")
 
 (define_split
   [(set (match_operand:DI 0 "register_operand" "")
                                               (match_operand 3 "" "")])
                           (match_operand:SI 4 "const48_operand" ""))
                  (match_operand:SI 5 "add_operand" ""))))
-   (clobber (match_operand:DI 6 "register_operand" ""))]
+   (clobber (match_operand:DI 6 "reg_not_elim_operand" ""))]
   ""
   [(set (match_dup 6) (match_dup 7))
    (set (match_dup 0)
 
 (define_insn ""
   [(set (match_operand:DI 0 "register_operand" "=r,r")
-       (plus:DI (mult:DI (match_operand:DI 1 "reg_or_0_operand" "rJ,rJ")
+       (plus:DI (mult:DI (match_operand:DI 1 "reg_not_elim_operand" "r,r")
                          (match_operand:DI 2 "const48_operand" "I,I"))
-                (match_operand:DI 3 "reg_or_8bit_operand" "rI,O")))]
+                (match_operand:DI 3 "sext_add_operand" "rI,O")))]
   ""
   "@
-   s%2addq %r1,%3,%0
+   s%2addq %1,%3,%0
    s%2subq %1,%n3,%0")
 
 ;; These variants of the above insns can occur if the third operand
   [(set (match_dup 5)
        (plus:SI (mult:SI (match_dup 1) (match_dup 2)) (match_dup 3)))
    (set (match_dup 0) (sign_extend:DI (plus:SI (match_dup 5) (match_dup 4))))]
-  "
-{ operands[5] = gen_lowpart (SImode, operands[0]);
-}")
+  "operands[5] = gen_lowpart (SImode, operands[0]);")
 
 (define_insn ""
   [(set (match_operand:DI 0 "some_operand" "=&r")
                  (match_operand:SI 2 "reg_or_8bit_operand" "")))]
   ""
   "
-{ emit_insn (gen_rtx_SET (VOIDmode, gen_lowpart (DImode, operands[0]),
-                         gen_rtx_MINUS (DImode,
-                                        gen_lowpart (DImode, operands[1]),
-                                        gen_lowpart (DImode, operands[2]))));
-  DONE;
+{
+  if (optimize)
+    {
+      rtx op1 = gen_lowpart (DImode, operands[1]);
+      rtx op2 = gen_lowpart (DImode, operands[2]);
+
+      if (! cse_not_expected)
+        {
+          rtx tmp = gen_reg_rtx (DImode);
+          emit_insn (gen_subdi3 (tmp, op1, op2));
+          emit_move_insn (gen_lowpart (DImode, operands[0]), tmp);
+        }
+      else
+        emit_insn (gen_subdi3 (gen_lowpart (DImode, operands[0]), op1, op2));
+      DONE;
+    }
 } ")
 
 (define_insn ""
 
 (define_insn ""
   [(set (match_operand:SI 0 "register_operand" "=r")
-       (minus:SI (mult:SI (match_operand:SI 1 "reg_or_0_operand" "rJ")
+       (minus:SI (mult:SI (match_operand:SI 1 "reg_not_elim_operand" "r")
                           (match_operand:SI 2 "const48_operand" "I"))
                  (match_operand:SI 3 "reg_or_8bit_operand" "rI")))]
   ""
-  "s%2subl %r1,%3,%0")
+  "s%2subl %1,%3,%0")
 
 (define_insn ""
   [(set (match_operand:DI 0 "register_operand" "=r")
        (sign_extend:DI
-        (minus:SI (mult:SI (match_operand:SI 1 "reg_or_0_operand" "rJ")
+        (minus:SI (mult:SI (match_operand:SI 1 "reg_not_elim_operand" "r")
                            (match_operand:SI 2 "const48_operand" "I"))
                   (match_operand:SI 3 "reg_or_8bit_operand" "rI"))))]
   ""
-  "s%2subl %r1,%3,%0")
+  "s%2subl %1,%3,%0")
 
 (define_insn ""
   [(set (match_operand:DI 0 "register_operand" "=r")
-       (minus:DI (mult:DI (match_operand:DI 1 "reg_or_0_operand" "rJ")
+       (minus:DI (mult:DI (match_operand:DI 1 "reg_not_elim_operand" "r")
                           (match_operand:DI 2 "const48_operand" "I"))
                  (match_operand:DI 3 "reg_or_8bit_operand" "rI")))]
   ""
-  "s%2subq %r1,%3,%0")
+  "s%2subq %1,%3,%0")
 
 (define_insn "mulsi3"
   [(set (match_operand:SI 0 "register_operand" "=r")
        (mult:SI (match_operand:SI 1 "reg_or_0_operand" "%rJ")
-                (match_operand:SI 2 "reg_or_0_operand" "rJ")))]
+                (match_operand:SI 2 "reg_or_8bit_operand" "rI")))]
   ""
-  "mull %r1,%r2,%0"
+  "mull %r1,%2,%0"
   [(set_attr "type" "imul")
    (set_attr "opsize" "si")])
 
 (define_insn ""
   [(set (match_operand:DI 0 "register_operand" "=r")
-       (sign_extend:DI (mult:SI (match_operand:SI 1 "reg_or_0_operand" "%rJ")
-                                (match_operand:SI 2 "reg_or_0_operand" "rJ"))))]
+       (sign_extend:DI
+         (mult:SI (match_operand:SI 1 "reg_or_0_operand" "%rJ")
+                  (match_operand:SI 2 "reg_or_8bit_operand" "rI"))))]
   ""
-  "mull %r1,%r2,%0"
+  "mull %r1,%2,%0"
   [(set_attr "type" "imul")
    (set_attr "opsize" "si")])
 
 (define_insn "muldi3"
   [(set (match_operand:DI 0 "register_operand" "=r")
        (mult:DI (match_operand:DI 1 "reg_or_0_operand" "%rJ")
-                (match_operand:DI 2 "reg_or_0_operand" "rJ")))]
+                (match_operand:DI 2 "reg_or_8bit_operand" "rI")))]
   ""
-  "mulq %r1,%r2,%0"
+  "mulq %r1,%2,%0"
   [(set_attr "type" "imul")])
 
 (define_insn "umuldi3_highpart"
   [(set (match_operand:DI 0 "register_operand" "=r")
        (truncate:DI
         (lshiftrt:TI
-         (mult:TI (zero_extend:TI (match_operand:DI 1 "register_operand" "r"))
-                  (zero_extend:TI (match_operand:DI 2 "register_operand" "r")))
+         (mult:TI (zero_extend:TI
+                    (match_operand:DI 1 "reg_or_0_operand" "%rJ"))
+                  (zero_extend:TI
+                    (match_operand:DI 2 "reg_or_8bit_operand" "rI")))
          (const_int 64))))]
   ""
-  "umulh %1,%2,%0"
+  "umulh %r1,%2,%0"
   [(set_attr "type" "imul")
    (set_attr "opsize" "udi")])
 
    bsr $26,$%0..ng
    jsr $26,%0\;ldgp $29,0($26)"
   [(set_attr "type" "jsr")
-   (set_attr "length" "12,*,12")])
+   (set_attr "length" "12,*,16")])
       
 (define_insn ""
   [(call (mem:DI (match_operand:DI 0 "call_operand" "r,R,i"))
    bsr $26,$%1..ng
    jsr $26,%1\;ldgp $29,0($26)"
   [(set_attr "type" "jsr")
-   (set_attr "length" "12,*,12")])
+   (set_attr "length" "12,*,16")])
 
 (define_insn ""
   [(set (match_operand 0 "register_operand" "=rf,rf,rf")
   "jmp $31,(%0),0"
   [(set_attr "type" "ibr")])
 
-(define_insn "nop"
-  [(const_int 0)]
-  ""
-  "nop"
-  [(set_attr "type" "ilog")])
-
 (define_expand "tablejump"
   [(use (match_operand:SI 0 "register_operand" ""))
    (use (match_operand:SI 1 "" ""))]
     {
       if (TARGET_BUILD_CONSTANTS)
        {
-#if HOST_BITS_PER_WIDE_INT == 64
-         HOST_WIDE_INT i;
+         HOST_WIDE_INT i0, i1;
 
          if (GET_CODE (operands[1]) == CONST_INT)
-           i = INTVAL (operands[1]);
+           {
+             i0 = INTVAL (operands[1]);
+             i1 = -(i0 < 0);
+           }
          else if (GET_CODE (operands[1]) == CONST_DOUBLE)
-           i = CONST_DOUBLE_LOW (operands[1]);
+           {
+#if HOST_BITS_PER_WIDE_INT >= 64
+             i0 = CONST_DOUBLE_LOW (operands[1]);
+             i1 = -(i0 < 0);
+#else
+             i0 = CONST_DOUBLE_LOW (operands[1]);
+             i1 = CONST_DOUBLE_HIGH (operands[1]);
+#endif
+           }
          else
            abort();
          
-          tem = alpha_emit_set_long_const (operands[0], i);
+          tem = alpha_emit_set_long_const (operands[0], i0, i1);
           if (rtx_equal_p (tem, operands[0]))
            DONE;
           else
            operands[1] = tem;
-#else
-          abort();
-#endif
        }
       else
        {
 
   return \"\";
 }"
-  [(set_attr "length" "16")])
+  [(set_attr "length" "16")
+   (set_attr "type" "multi")])
 
 (define_expand "prologue"
   [(clobber (const_int 0))]
   ""
   "alpha_expand_epilogue (); DONE;")
 
+(define_expand "eh_epilogue"
+  [(use (match_operand:DI 0 "register_operand" "r"))
+   (use (match_operand:DI 1 "register_operand" "r"))
+   (use (match_operand:DI 2 "register_operand" "r"))]
+  "! TARGET_OPEN_VMS"
+  "
+{
+  alpha_eh_epilogue_sp_ofs = operands[1];
+  if (GET_CODE (operands[2]) != REG || REGNO (operands[2]) != 26)
+    {
+      rtx ra = gen_rtx_REG (Pmode, 26);
+      emit_move_insn (ra, operands[2]);
+      operands[2] = ra;
+    }
+}")
+
 (define_expand "builtin_longjmp"
   [(unspec_volatile [(match_operand 0 "register_operand" "r")] 3)]
   "! TARGET_OPEN_VMS && ! TARGET_WINDOWS_NT"
      where to look for it when we get back to setjmp's function for
      restoring the gp.  */
   emit_indirect_jump (pv);
+  DONE;
 }")
 
 (define_insn "builtin_setjmp_receiver"
   [(unspec_volatile [(match_operand 0 "" "")] 2)]
   "! TARGET_OPEN_VMS && ! TARGET_WINDOWS_NT && TARGET_AS_CAN_SUBTRACT_LABELS"
   "\\n$LSJ%=:\;ldgp $29,$LSJ%=-%l0($27)"
-  [(set_attr "length" "8")])
+  [(set_attr "length" "8")
+   (set_attr "type" "multi")])
 
 (define_insn ""
   [(unspec_volatile [(match_operand 0 "" "")] 2)]
   "! TARGET_OPEN_VMS && ! TARGET_WINDOWS_NT"
-  "br $27,$LSJ%=\\n$LSJ%=:\;ldgp $29,0($27)"
-  [(set_attr "length" "12")])
+  "br $29,$LSJ%=\\n$LSJ%=:\;ldgp $29,0($29)"
+  [(set_attr "length" "12")
+   (set_attr "type" "multi")])
+
+(define_insn "exception_receiver"
+  [(unspec_volatile [(const_int 0)] 7)]
+  "! TARGET_OPEN_VMS && ! TARGET_WINDOWS_NT"
+  "br $29,$LSJ%=\\n$LSJ%=:\;ldgp $29,0($29)"
+  [(set_attr "length" "12")
+   (set_attr "type" "multi")])
 
 (define_expand "nonlocal_goto_receiver"
   [(unspec_volatile [(const_int 0)] 1)
    (clobber (reg:DI 0))]
   "TARGET_OPEN_VMS"
   "lda $0,OTS$HOME_ARGS\;ldq $0,8($0)\;jsr $0,OTS$HOME_ARGS"
-  [(set_attr "length" "16")])
+  [(set_attr "length" "16")
+   (set_attr "type" "multi")])
 
 ;; Close the trap shadow of preceeding instructions.  This is generated
 ;; by alpha_reorg.
   ""
   "trapb"
   [(set_attr "type" "misc")])
+
+;; No-op instructions used by machine-dependant reorg to preserve
+;; alignment for instruction issue.
+
+(define_insn "nop"
+  [(const_int 0)]
+  ""
+  "nop"
+  [(set_attr "type" "ilog")])
+
+(define_insn "fnop"
+  [(const_int 1)]
+  "TARGET_FP"
+  "fnop"
+  [(set_attr "type" "fcpys")])
+
+(define_insn "unop"
+  [(const_int 2)]
+  ""
+  "unop")
+
+(define_insn "realign"
+  [(unspec_volatile [(match_operand 0 "immediate_operand" "i")] 6)]
+  ""
+  ".align %0 #realign")
 \f
 ;; Peepholes go at the end.