OSDN Git Service

* mn10300.h (RETURN_ADDR_RTX): Define.
[pf3gnuchains/gcc-fork.git] / gcc / config / mn10300 / mn10300.md
index 98f4536..13628ec 100644 (file)
@@ -1,4 +1,4 @@
-;; GCC machine description for Matsushita MN10300
+; GCC machine description for Matsushita MN10300
 ;; Copyright (C) 1996, 1997 Free Software Foundation, Inc.
 
 ;;   Contributed by Jeff Law (law@cygnus.com).
 }")
 
 (define_insn ""
-  [(set (match_operand:QI 0 "general_operand" "=d,a,d,d,a,d,a,d,m")
-       (match_operand:QI 1 "general_operand" "0,0,I,a,d,di,ia,m,d"))]
+  [(set (match_operand:QI 0 "general_operand" "=d,a,d,a,d,a,d,a,d,m")
+       (match_operand:QI 1 "general_operand" "0,0,I,I,a,d,di,ia,m,d"))]
   "register_operand (operands[0], QImode)
    || register_operand (operands[1], QImode)"
-  "@
-  nop
-  nop
-  clr %0
-  mov %1,%0
-  mov %1,%0
-  mov %1,%0
-  mov %1,%0
-  movbu %1,%0
-  movbu %1,%0"
-  [(set_attr "cc" "none,none,clobber,none_0hit,none_0hit,none_0hit,none_0hit,none_0hit,none_0hit")])
+  "*
+{
+  switch (which_alternative)
+    {
+    case 0:
+    case 1:
+      return \"nop\";
+    case 2:
+      return \"clr %0\";
+    case 3:
+      if (zero_areg)
+       {
+         rtx xoperands[2];
+
+         xoperands[0] = operands[0];
+         xoperands[1] = zero_areg;
+         if (rtx_equal_p (xoperands[0], xoperands[1]))
+           output_asm_insn (\"sub %1,%0\", xoperands);
+         else
+           output_asm_insn (\"mov %1,%0\", xoperands);
+         return \"\";
+       }
+
+      /* FALLTHROUGH */
+    case 4:
+    case 5:
+    case 6:
+    case 7:
+      return \"mov %1,%0\";
+    case 8:
+    case 9:
+      return \"movbu %1,%0\";
+    }
+}"
+  [(set_attr "cc" "none,none,clobber,none_0hit,none_0hit,none_0hit,none_0hit,none_0hit,none_0hit,none_0hit")])
 
 ;; movhi
 
 }")
 
 (define_insn ""
-  [(set (match_operand:HI 0 "general_operand" "=d,a,d,d,a,d,a,d,m")
-       (match_operand:HI 1 "general_operand" "0,0,I,a,d,di,ia,m,d"))]
+  [(set (match_operand:HI 0 "general_operand" "=d,a,d,a,d,a,d,a,d,m")
+       (match_operand:HI 1 "general_operand" "0,0,I,I,a,d,di,ia,m,d"))]
   "register_operand (operands[0], HImode)
    || register_operand (operands[1], HImode)"
-  "@
-  nop
-  nop
-  clr %0
-  mov %1,%0
-  mov %1,%0
-  mov %1,%0
-  mov %1,%0
-  movhu %1,%0
-  movhu %1,%0"
-  [(set_attr "cc" "none,none,clobber,none_0hit,none_0hit,none_0hit,none_0hit,none_0hit,none_0hit")])
+  "*
+{
+  switch (which_alternative)
+    {
+    case 0:
+    case 1:
+      return \"nop\";
+    case 2:
+      return \"clr %0\";
+    case 3:
+      if (zero_areg)
+       {
+         rtx xoperands[2];
+
+         xoperands[0] = operands[0];
+         xoperands[1] = zero_areg;
+         if (rtx_equal_p (xoperands[0], xoperands[1]))
+           output_asm_insn (\"sub %1,%0\", xoperands);
+         else
+           output_asm_insn (\"mov %1,%0\", xoperands);
+         return \"\";
+       }
+
+      /* FALLTHROUGH */
+    case 4:
+    case 5:
+    case 6:
+    case 7:
+      return \"mov %1,%0\";
+    case 8:
+    case 9:
+      return \"movhu %1,%0\";
+    }
+}"
+  [(set_attr "cc" "none,none,clobber,none_0hit,none_0hit,none_0hit,none_0hit,none_0hit,none_0hit,none_0hit")])
 
 ;; movsi and helpers
 
 }")
 
 (define_insn ""
-  [(set (match_operand:SI 0 "general_operand" "=d,a,d,dm,dm,am,am,d,d,a,a,aR,x")
-       (match_operand:SI 1 "general_operand" "0,0,I,d,a,d,a,dim,aim,dim,aim,x,aR"))]
+  [(set (match_operand:SI 0 "general_operand"
+                               "=d,a,d,a,dm,dm,am,am,d,d,a,a,aR,x")
+       (match_operand:SI 1 "general_operand"
+                               "0,0,I,I,d,a,d,a,dim,aim,dim,aim,x,aR"))]
   "register_operand (operands[0], SImode)
    || register_operand (operands[1], SImode)"
-  "@
-  nop
-  nop
-  clr %0
-  mov %1,%0
-  mov %1,%0
-  mov %1,%0
-  mov %1,%0
-  mov %1,%0
-  mov %1,%0
-  mov %1,%0
-  mov %1,%0
-  mov %1,%0
-  mov %1,%0"
-  [(set_attr "cc" "none,none,clobber,none_0hit,none_0hit,none_0hit,none_0hit,none_0hit,none_0hit,none_0hit,none_0hit,none_0hit,none_0hit")])
+  "*
+{
+  switch (which_alternative)
+    {
+    case 0:
+    case 1:
+      return \"nop\";
+    case 2:
+      return \"clr %0\";
+    case 3:
+      if (zero_areg)
+       {
+         rtx xoperands[2];
+
+         xoperands[0] = operands[0];
+         xoperands[1] = zero_areg;
+         if (rtx_equal_p (xoperands[0], xoperands[1]))
+           output_asm_insn (\"sub %1,%0\", xoperands);
+         else
+           output_asm_insn (\"mov %1,%0\", xoperands);
+         return \"\";
+       }
+
+      /* FALLTHROUGH */
+    case 4:
+    case 5:
+    case 6:
+    case 7:
+    case 8:
+    case 9:
+    case 10:
+    case 11:
+    case 12:
+    case 13:
+      return \"mov %1,%0\";
+    }
+}"
+  [(set_attr "cc" "none,none,clobber,none_0hit,none_0hit,none_0hit,none_0hit,none_0hit,none_0hit,none_0hit,none_0hit,none_0hit,none_0hit,none_0hit")])
 
 (define_expand "movsf"
   [(set (match_operand:SF 0 "general_operand" "")
 }")
 
 (define_insn ""
-  [(set (match_operand:SF 0 "general_operand" "=d,a,d,dam,da")
-       (match_operand:SF 1 "general_operand" "0,0,G,da,daim"))]
+  [(set (match_operand:SF 0 "general_operand" "=d,a,d,a,dam,da")
+       (match_operand:SF 1 "general_operand" "0,0,G,G,da,daim"))]
   "register_operand (operands[0], SFmode)
    || register_operand (operands[1], SFmode)"
-  "@
-  nop
-  nop
-  clr %0
-  mov %1,%0
-  mov %1,%0"
-  [(set_attr "cc" "none,none,clobber,none_0hit,none_0hit")])
+  "*
+{
+  switch (which_alternative)
+    {
+    case 0:
+    case 1:
+      return \"nop\";
+    case 2:
+      return \"clr %0\";
+    case 3:
+      if (zero_areg)
+       {
+         rtx xoperands[2];
+
+         xoperands[0] = operands[0];
+         xoperands[1] = zero_areg;
+         if (rtx_equal_p (xoperands[0], xoperands[1]))
+           output_asm_insn (\"sub %1,%0\", xoperands);
+         else
+           output_asm_insn (\"mov %1,%0\", xoperands);
+         return \"\";
+       }
+
+      /* FALLTHROUGH */
+    case 4:
+    case 5:
+      return \"mov %1,%0\";
+    }
+}"
+  [(set_attr "cc" "none,none,clobber,none_0hit,none_0hit,none_0hit")])
 
 (define_expand "movdi"
   [(set (match_operand:DI 0 "general_operand" "")
 }")
 
 (define_insn ""
-  [(set (match_operand:DI 0 "general_operand" "=d,a,d,dm,dm,am,am,d,d,a,a")
-       (match_operand:DI 1 "general_operand" "0,0,I,d,a,d,a,dim,aim,dim,aim"))]
+  [(set (match_operand:DI 0 "general_operand"
+                               "=d,a,d,a,dm,dm,am,am,d,d,a,a")
+       (match_operand:DI 1 "general_operand"
+                               "0,0,I,I,d,a,d,a,dim,aim,dim,aim"))]
   "register_operand (operands[0], DImode)
    || register_operand (operands[1], DImode)"
   "*
        return \"clr %L0\;clr %H0\";
 
       case 3:
+         {
+           rtx xoperands[2];
+
+           xoperands[0] = operands[0];
+           xoperands[1] = zero_areg ? zero_areg : operands[1];
+           if (rtx_equal_p (xoperands[0], xoperands[1]))
+             output_asm_insn (\"sub %L1,%L0\;mov %L0,%H0\", xoperands);
+           else
+             output_asm_insn (\"mov %1,%L0\;mov %L0,%H0\", xoperands);
+           return \"\";
+         }
       case 4:
       case 5:
       case 6:
       case 8:
       case 9:
       case 10:
+      case 11:
        if (GET_CODE (operands[1]) == CONST_INT)
          {
            val[0] = INTVAL (operands[1]);
              return \"mov %L1,%L0\;mov %H1,%H0\";
              
          }
+       else if (GET_CODE (operands[1]) == MEM
+                && CONSTANT_ADDRESS_P (XEXP (operands[1], 0))
+                && REGNO_REG_CLASS (REGNO (operands[0])) == ADDRESS_REGS)
+         {
+           rtx xoperands[2];
+
+           xoperands[0] = operands[0];
+           xoperands[1] = XEXP (operands[1], 0);
+
+           output_asm_insn (\"mov %1,%L0\;mov (4,%L0),%H0\;mov (%L0),%L0\",
+                            xoperands);
+           return \"\";
+         }
        else
          {
            if ((GET_CODE (operands[1]) == CONST_INT
                 || GET_CODE (operands[1]) == CONST_DOUBLE)
-               && val[0] == 0
-               && REGNO_REG_CLASS (REGNO (operands[0])) == DATA_REGS)
-             output_asm_insn (\"clr %L0\", operands);
+               && val[0] == 0)
+             {
+               if (REGNO_REG_CLASS (REGNO (operands[0])) == DATA_REGS)
+                 output_asm_insn (\"clr %L0\", operands);
+               else if (zero_areg)
+                 {
+                   rtx xoperands[2];
+
+                   xoperands[0] = operands[0];
+                   xoperands[1] = zero_areg;
+                   if (rtx_equal_p (xoperands[0], xoperands[1]))
+                     output_asm_insn (\"sub %L0,%L0\", xoperands);
+                   else
+                     output_asm_insn (\"mov %1,%L0\", xoperands);
+                 }
+               else
+                 output_asm_insn (\"mov %L1,%L0\", operands);
+             }
            else
              output_asm_insn (\"mov %L1,%L0\", operands);
 
            if ((GET_CODE (operands[1]) == CONST_INT
                 || GET_CODE (operands[1]) == CONST_DOUBLE)
-               && val[1] == 0
-               && REGNO_REG_CLASS (REGNO (operands[0])) == DATA_REGS)
-             output_asm_insn (\"clr %H0\", operands);
+               && val[1] == 0)
+             {
+               if (REGNO_REG_CLASS (REGNO (operands[0])) == DATA_REGS)
+                 output_asm_insn (\"clr %H0\", operands);
+               else if (zero_areg)
+                 {
+                   rtx xoperands[2];
+
+                   xoperands[0] = operands[0];
+                   xoperands[1] = zero_areg;
+                   if (rtx_equal_p (xoperands[0], xoperands[1]))
+                     output_asm_insn (\"sub %H0,%H0\", xoperands);
+                   else
+                     output_asm_insn (\"mov %1,%H0\", xoperands);
+                 }
+               else
+                 output_asm_insn (\"mov %H1,%H0\", operands);
+             }
+           else if ((GET_CODE (operands[1]) == CONST_INT
+                     || GET_CODE (operands[1]) == CONST_DOUBLE)
+                    && val[0] == val[1])
+             output_asm_insn (\"mov %L0,%H0\", operands);
            else
              output_asm_insn (\"mov %H1,%H0\", operands);
            return \"\";
          }
     }
 }"
-  [(set_attr "cc" "none,none,clobber,none_0hit,none_0hit,none_0hit,none_0hit,none_0hit,none_0hit,none_0hit,none_0hit")])
+  [(set_attr "cc" "none,none,clobber,none_0hit,none_0hit,none_0hit,none_0hit,none_0hit,none_0hit,none_0hit,none_0hit,none_0hit")])
 
 (define_expand "movdf"
   [(set (match_operand:DF 0 "general_operand" "")
 }")
 
 (define_insn ""
-  [(set (match_operand:DF 0 "general_operand" "=d,a,d,dm,dm,am,am,d,d,a,a")
-       (match_operand:DF 1 "general_operand" "0,0,G,d,a,d,a,dim,aim,dim,aim"))]
+  [(set (match_operand:DF 0 "general_operand"
+                               "=d,a,d,a,dm,dm,am,am,d,d,a,a")
+       (match_operand:DF 1 "general_operand"
+                               "0,0,G,G,d,a,d,a,dim,aim,dim,aim"))]
   "register_operand (operands[0], DFmode)
    || register_operand (operands[1], DFmode)"
   "*
        return \"clr %L0\;clr %H0\";
 
       case 3:
+         {
+           rtx xoperands[2];
+
+           xoperands[0] = operands[0];
+           xoperands[1] = zero_areg ? zero_areg : operands[1];
+           if (rtx_equal_p (xoperands[0], xoperands[1]))
+             output_asm_insn (\"sub %L1,%L0\;mov %L0,%H0\", xoperands);
+           else
+             output_asm_insn (\"mov %1,%L0\;mov %L0,%H0\", xoperands);
+           return \"\";
+         }
       case 4:
       case 5:
       case 6:
       case 8:
       case 9:
       case 10:
+      case 11:
        if (GET_CODE (operands[1]) == CONST_INT)
          {
            val[0] = INTVAL (operands[1]);
              return \"mov %L1,%L0\;mov %H1,%H0\";
              
          }
+       else if (GET_CODE (operands[1]) == MEM
+                && CONSTANT_ADDRESS_P (XEXP (operands[1], 0))
+                && REGNO_REG_CLASS (REGNO (operands[0])) == ADDRESS_REGS)
+         {
+           rtx xoperands[2];
+
+           xoperands[0] = operands[0];
+           xoperands[1] = XEXP (operands[1], 0);
+
+           output_asm_insn (\"mov %1,%L0\;mov (4,%L0),%H0\;mov (%L0),%L0\",
+                            xoperands);
+           return \"\";
+         }
        else
          {
            if ((GET_CODE (operands[1]) == CONST_INT
                 || GET_CODE (operands[1]) == CONST_DOUBLE)
-               && val[0] == 0
-               && REGNO_REG_CLASS (REGNO (operands[0])) == DATA_REGS)
-             output_asm_insn (\"clr %L0\", operands);
+               && val[0] == 0)
+             {
+               if (REGNO_REG_CLASS (REGNO (operands[0])) == DATA_REGS)
+                 output_asm_insn (\"clr %L0\", operands);
+               else if (zero_areg)
+                 {
+                   rtx xoperands[2];
+
+                   xoperands[0] = operands[0];
+                   xoperands[1] = zero_areg;
+                   if (rtx_equal_p (xoperands[0], xoperands[1]))
+                     output_asm_insn (\"sub %L0,%L0\", xoperands);
+                   else
+                     output_asm_insn (\"mov %1,%L0\", xoperands);
+                 }
+               else
+                 output_asm_insn (\"mov %L1,%L0\", operands);
+             }
            else
              output_asm_insn (\"mov %L1,%L0\", operands);
 
            if ((GET_CODE (operands[1]) == CONST_INT
                 || GET_CODE (operands[1]) == CONST_DOUBLE)
-               && val[1] == 0
-               && REGNO_REG_CLASS (REGNO (operands[0])) == DATA_REGS)
-             output_asm_insn (\"clr %H0\", operands);
+               && val[1] == 0)
+             {
+               if (REGNO_REG_CLASS (REGNO (operands[0])) == DATA_REGS)
+                 output_asm_insn (\"clr %H0\", operands);
+               else if (zero_areg)
+                 {
+                   rtx xoperands[2];
+
+                   xoperands[0] = operands[0];
+                   xoperands[1] = zero_areg;
+                   if (rtx_equal_p (xoperands[0], xoperands[1]))
+                     output_asm_insn (\"sub %H0,%H0\", xoperands);
+                   else
+                     output_asm_insn (\"mov %1,%H0\", xoperands);
+                 }
+               else
+                 output_asm_insn (\"mov %H1,%H0\", operands);
+             }
+           else if ((GET_CODE (operands[1]) == CONST_INT
+                     || GET_CODE (operands[1]) == CONST_DOUBLE)
+                    && val[0] == val[1])
+             output_asm_insn (\"mov %L0,%H0\", operands);
            else
              output_asm_insn (\"mov %H1,%H0\", operands);
            return \"\";
          }
     }
 }"
-  [(set_attr "cc" "none,none,clobber,none_0hit,none_0hit,none_0hit,none_0hit,none_0hit,none_0hit,none_0hit,none_0hit")])
+  [(set_attr "cc" "none,none,clobber,none_0hit,none_0hit,none_0hit,none_0hit,none_0hit,none_0hit,none_0hit,none_0hit,none_0hit")])
   
 
 \f
 }")
 
 (define_insn ""
-  [(set (match_operand:SI 0 "register_operand" "=d,a,a,da,x")
-       (plus:SI (match_operand:SI 1 "register_operand" "%0,0,0,0,0")
-                (match_operand:SI 2 "nonmemory_operand" "J,J,L,dai,i")))]
+  [(set (match_operand:SI 0 "register_operand" "=d,a,a,da,x,!&da")
+       (plus:SI (match_operand:SI 1 "register_operand" "%0,0,0,0,0,da")
+                (match_operand:SI 2 "nonmemory_operand" "J,J,L,dai,i,da")))]
   ""
   "@
   inc %0
   inc %0
   inc4 %0
   add %2,%0
-  add %2,%0"
-  [(set_attr "cc" "set_zn_c0,none_0hit,none_0hit,set_zn_c0,none_0hit")])
+  add %2,%0
+  mov %2,%0\;add %1,%0"
+  [(set_attr "cc" "set_zn_c0,none_0hit,none_0hit,set_zn_c0,none_0hit,none_0hit")])
 
 (define_expand "adddi3"
   [(set (reg:DI 0) (match_operand:DI 1 "register_operand" ""))
 (define_insn "return"
   [(return)]
   "can_use_return_insn ()"
-  "rets"
+  "*
+{
+  rtx next = next_active_insn (insn);
+
+  if (next
+      && GET_CODE (next) == JUMP_INSN
+      && GET_CODE (PATTERN (next)) == RETURN)
+    return \"\";
+  else
+    return \"rets\";
+}"
   [(set_attr "cc" "clobber")])
 
 ;; Try to combine consecutive updates of the stack pointer (or any