]> gcc.gnu.org Git - gcc.git/commitdiff
(calll, tablejump, movsi): New variants for NT.
authorRichard Kenner <kenner@gcc.gnu.org>
Thu, 13 Apr 1995 12:46:37 +0000 (08:46 -0400)
committerRichard Kenner <kenner@gcc.gnu.org>
Thu, 13 Apr 1995 12:46:37 +0000 (08:46 -0400)
From-SVN: r9371

gcc/config/alpha/alpha.md

index 570aaa08bedcc52fa460327d690cdfc557ef6a2f..0af9cc226c915e0b56819f5d51da96f98ceacbec 100644 (file)
                         DImode, operands[4], const0_rtx);
 }")
 \f
-;; Here are the CALL and unconditional branch insns.
+;; Here are the CALL and unconditional branch insns.  Calls on NT and OSF
+;; work differently, so we have different patterns for each.
 
 (define_expand "call"
+  [(use (match_operand:DI 0 "" ""))
+   (use (match_operand 1 "" ""))]
+  ""
+  "
+{ if (WINDOWS_NT)
+    emit_call_insn (gen_call_nt (operands[0], operands[1]));
+  else
+    emit_call_insn (gen_call_osf (operands[0], operands[1]));
+
+  DONE;
+}")
+
+(define_expand "call_osf"
   [(parallel [(call (mem:DI (match_operand 0 "" ""))
                    (match_operand 1 "" ""))
              (clobber (reg:DI 27))
     }
 }")
 
+(define_expand "call_nt"
+  [(parallel [(call (mem:DI (match_operand:DI 0 "" ""))
+                   (match_operand 1 "" ""))
+             (clobber (reg:DI 26))])]
+  ""
+  "
+{ if (GET_CODE (operands[0]) != MEM)
+    abort ();
+  operands[0] = XEXP (operands[0], 0);
+
+  if (GET_CODE (operands[0]) != SYMBOL_REF)
+    operands[0] = force_reg (Pmode, operands[0]);
+}")
+
 (define_expand "call_value"
+  [(use (match_operand 0 "" ""))
+   (use (match_operand:DI 1 "" ""))
+   (use (match_operand 2 "" ""))]
+  ""
+  "
+{ if (WINDOWS_NT)
+    emit_call_insn (gen_call_value_nt (operands[0], operands[1], operands[2]));
+  else
+    emit_call_insn (gen_call_value_osf (operands[0], operands[1],
+                                       operands[2]));
+  DONE;
+}")
+
+(define_expand "call_value_osf"
   [(parallel [(set (match_operand 0 "" "")
                   (call (mem:DI (match_operand 1 "" ""))
                         (match_operand 2 "" "")))
     }
 }")
 
+(define_expand "call_value_nt"
+  [(parallel [(set (match_operand 0 "" "")
+                  (call (mem:DI (match_operand:DI 1 "" ""))
+                        (match_operand 2 "" "")))
+             (clobber (reg:DI 26))])]
+  ""
+  "
+{ if (GET_CODE (operands[1]) != MEM)
+    abort ();
+
+  operands[1] = XEXP (operands[1], 0);
+  if (GET_CODE (operands[1]) != SYMBOL_REF)
+    operands[1] = force_reg (Pmode, operands[1]);
+}")
+
 (define_insn ""
   [(call (mem:DI (match_operand:DI 0 "call_operand" "r,R,i"))
         (match_operand 1 "" ""))
    (clobber (reg:DI 27))
    (clobber (reg:DI 26))]
-  ""
+  "! WINDOWS_NT"
   "@
    jsr $26,($27),0\;ldgp $29,0($26)
    bsr $26,%0..ng
    jsr $26,%0\;ldgp $29,0($26)"
   [(set_attr "type" "jsr,jsr,ibr")])
       
+(define_insn ""
+  [(call (mem:DI (match_operand:DI 0 "call_operand" "r,i"))
+        (match_operand 1 "" ""))
+   (clobber (reg:DI 26))]
+  "WINDOWS_NT"
+  "@
+   jsr $26,(%0)
+   bsr $26,%0"
+  [(set_attr "type" "jsr")])
+      
 (define_insn ""
   [(set (match_operand 0 "register_operand" "=rf,rf,rf")
        (call (mem:DI (match_operand:DI 1 "call_operand" "r,R,i"))
              (match_operand 2 "" "")))
    (clobber (reg:DI 27))
    (clobber (reg:DI 26))]
-  ""
+  "! WINDOWS_NT"
   "@
    jsr $26,($27),0\;ldgp $29,0($26)
    bsr $26,%1..ng
    jsr $26,%1\;ldgp $29,0($26)"
   [(set_attr "type" "jsr,jsr,ibr")])
 
+(define_insn ""
+  [(set (match_operand 0 "register_operand" "=rf,rf")
+       (call (mem:DI (match_operand:DI 1 "call_operand" "r,i"))
+             (match_operand 2 "" "")))
+   (clobber (reg:DI 26))]
+  "WINDOWS_NT"
+  "@
+   jsr $26,(%1)
+   bsr $26,%1"
+  [(set_attr "type" "jsr")])
+
 ;; Call subroutine returning any type.
 
 (define_expand "untyped_call"
   [(set_attr "type" "iaddlog")])
 
 (define_expand "tablejump"
+  [(use (match_operand:SI 0 "register_operand" ""))
+   (use (match_operand:SI 1 "" ""))]
+  ""
+  "
+{
+  if (WINDOWS_NT)
+    emit_jump_insn (gen_tablejump_nt (operands[0], operands[1]));
+  else
+    emit_jump_insn (gen_tablejump_osf (operands[0], operands[1]));
+
+  DONE;
+}")
+
+(define_expand "tablejump_osf"
   [(set (match_dup 3)
        (sign_extend:DI (match_operand:SI 0 "register_operand" "")))
    (parallel [(set (pc)
   "
 { operands[3] = gen_reg_rtx (DImode); }")
 
+(define_expand "tablejump_nt"
+  [(set (match_dup 3)
+       (sign_extend:DI (match_operand:SI 0 "register_operand" "")))
+   (parallel [(set (pc)
+                  (match_dup 3))
+             (use (label_ref (match_operand 1 "" "")))])]
+  ""
+  "
+{ operands[3] = gen_reg_rtx (DImode); }")
+
 (define_insn ""
   [(set (pc)
        (plus:DI (match_operand:DI 0 "register_operand" "r")
                 (label_ref:DI (match_operand 1 "" ""))))
    (clobber (match_scratch:DI 2 "=r"))]
-  "next_active_insn (insn) != 0
+  "! WINDOWS_NT && next_active_insn (insn) != 0
    && GET_CODE (PATTERN (next_active_insn (insn))) == ADDR_DIFF_VEC
    && PREV_INSN (next_active_insn (insn)) == operands[1]"
   "*
 }"
   [(set_attr "type" "ibr")])
 
+(define_insn ""
+  [(set (pc)
+       (match_operand:DI 0 "register_operand" "r"))
+   (use (label_ref (match_operand 1 "" "")))]
+  "WINDOWS_NT && next_active_insn (insn) != 0
+   && GET_CODE (PATTERN (next_active_insn (insn))) == ADDR_DIFF_VEC
+   && PREV_INSN (next_active_insn (insn)) == operands[1]"
+  "*
+{ rtx best_label = 0;
+  rtx jump_table_insn = next_active_insn (operands[1]);
+
+  if (GET_CODE (jump_table_insn) == JUMP_INSN
+      && GET_CODE (PATTERN (jump_table_insn)) == ADDR_DIFF_VEC)
+    {
+      rtx jump_table = PATTERN (jump_table_insn);
+      int n_labels = XVECLEN (jump_table, 1);
+      int best_count = -1;
+      int i, j;
+
+      for (i = 0; i < n_labels; i++)
+       {
+         int count = 1;
+
+         for (j = i + 1; j < n_labels; j++)
+           if (XEXP (XVECEXP (jump_table, 1, i), 0)
+               == XEXP (XVECEXP (jump_table, 1, j), 0))
+             count++;
+
+         if (count > best_count)
+           best_count = count, best_label = XVECEXP (jump_table, 1, i);
+       }
+    }
+
+  if (best_label)
+    {
+      operands[2] = best_label;
+      return \"jmp $31,(%0),%2\";
+    }
+  else
+    return \"jmp $31,(%0),0\";
+}"
+  [(set_attr "type" "ibr")])
+
 ;; Cache flush.  Used by INITIALIZE_TRAMPOLINE.  0x86 is PAL_imb, but we don't
 ;; want to have to include pal.h in our .s file.
 (define_insn ""
 (define_insn ""
   [(set (match_operand:SI 0 "nonimmediate_operand" "=r,r,r,r,r,r,m,f,f,f,m")
        (match_operand:SI 1 "input_operand" "r,J,I,K,L,m,rJ,f,J,m,fG"))]
-  "register_operand (operands[0], SImode)
-   || reg_or_0_operand (operands[1], SImode)"
+  "! WINDOWS_NT && (register_operand (operands[0], SImode)
+                   || reg_or_0_operand (operands[1], SImode))"
   "@
    bis %1,%1,%0
    bis $31,$31,%0
    sts %R1,%0"
   [(set_attr "type" "iaddlog,iaddlog,iaddlog,iaddlog,iaddlog,ld,st,fpop,fpop,ld,st")])
 
+(define_insn ""
+  [(set (match_operand:SI 0 "nonimmediate_operand" "=r,r,r,r,r,r,r,m,f,f,f,m")
+       (match_operand:SI 1 "input_operand" "r,J,I,K,L,s,m,rJ,f,J,m,fG"))]
+  "WINDOWS_NT && (register_operand (operands[0], SImode)
+                 || reg_or_0_operand (operands[1], SImode))"
+  "@
+   bis %1,%1,%0
+   bis $31,$31,%0
+   bis $31,%1,%0
+   lda %0,%1
+   ldah %0,%h1
+   lda %0,%1
+   ldl %0,%1
+   stl %r1,%0
+   cpys %1,%1,%0
+   cpys $f31,$f31,%0
+   lds %0,%1
+   sts %R1,%0"
+  [(set_attr "type" "iaddlog,iaddlog,iaddlog,iaddlog,iaddlog,ldsym,ld,st,fpop,fpop,ld,st")])
+
 (define_insn ""
   [(set (match_operand:HI 0 "nonimmediate_operand" "=r,r,r,r,f,f")
        (match_operand:HI 1 "input_operand" "r,J,I,n,f,J"))]
This page took 0.075754 seconds and 5 git commands to generate.