]> oss.titaniummirror.com Git - msp430-gcc.git/blobdiff - gcc/config/pdp11/pdp11.md
Imported gcc-4.4.3
[msp430-gcc.git] / gcc / config / pdp11 / pdp11.md
index 13f8d02f9c12add3b4d3af4549c4943eec5fcd16..d5d4396b1c6d5e5ca296d624d404ead5e5750f80 100644 (file)
@@ -1,24 +1,23 @@
 ;;- Machine description for the pdp11 for GNU C compiler
-;; Copyright (C) 1994, 1995, 1997, 1998, 1999, 2000, 2001
-;; Free Software Foundation, Inc.
+;; Copyright (C) 1994, 1995, 1997, 1998, 1999, 2000, 2001, 2004, 2005
+;; 2007, 2008 Free Software Foundation, Inc.
 ;; Contributed by Michael K. Gschwind (mike@vlsivie.tuwien.ac.at).
 
-;; This file is part of GNU CC.
+;; This file is part of GCC.
 
-;; GNU CC is free software; you can redistribute it and/or modify
+;; GCC is free software; you can redistribute it and/or modify
 ;; it under the terms of the GNU General Public License as published by
-;; the Free Software Foundation; either version 2, or (at your option)
+;; the Free Software Foundation; either version 3, or (at your option)
 ;; any later version.
 
-;; GNU CC is distributed in the hope that it will be useful,
+;; GCC is distributed in the hope that it will be useful,
 ;; but WITHOUT ANY WARRANTY; without even the implied warranty of
 ;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 ;; GNU General Public License for more details.
 
 ;; You should have received a copy of the GNU General Public License
-;; along with GNU CC; see the file COPYING.  If not, write to
-;; the Free Software Foundation, 59 Temple Place - Suite 330,
-;; Boston, MA 02111-1307, USA.
+;; along with GCC; see the file COPYING3.  If not see
+;; <http://www.gnu.org/licenses/>.
 
 
 ;; HI is 16 bit
   rtx br_insn = NEXT_INSN (insn);
   RTX_CODE br_code;
 
-  if (GET_CODE (br_insn) != JUMP_INSN)
-    abort();
+  gcc_assert (GET_CODE (br_insn) == JUMP_INSN);
   br_code =  GET_CODE (XEXP (XEXP (PATTERN (br_insn), 1), 0));
   
   switch(br_code)
 
     default:
 
-      abort();
+      gcc_unreachable ();
   }
 }"
   [(set_attr "length" "4")])
 ;; Move instructions
 
 (define_insn "movdi"
-  [(set (match_operand:DI 0 "general_operand" "=g")
-       (match_operand:DI 1 "general_operand" "g"))]
+  [(set (match_operand:DI 0 "general_operand" "=g,rm,o")
+       (match_operand:DI 1 "general_operand" "m,r,a"))]
   ""
   "* return output_move_quad (operands);"
 ;; what's the mose expensive code - say twice movsi = 16
-  [(set_attr "length" "16")])
+  [(set_attr "length" "16,16,16")])
 
 (define_insn "movsi"
   [(set (match_operand:SI 0 "general_operand" "=r,r,r,rm,m")
   [(set_attr "length" "1,2,2,3")])
 
 (define_insn "movqi"
-  [(set (match_operand:QI 0 "general_operand" "=rR,rR,Q,Q")
-       (match_operand:QI 1 "general_operand" "rRN,Qi,rRN,Qi"))]
+  [(set (match_operand:QI 0 "nonimmediate_operand" "=g")
+       (match_operand:QI 1 "general_operand" "g"))]
   ""
   "*
 {
 
   return \"movb %1, %0\";
 }"
-  [(set_attr "length" "1,2,2,3")])
+  [(set_attr "length" "1")])
 
 ;; do we have to supply all these moves? e.g. to 
 ;; NO_LOAD_FPU_REGs ? 
 (define_insn "movdf"
-  [(set (match_operand:DF 0 "general_operand" "=f,R,f,Q,f,m")
-        (match_operand:DF 1 "general_operand" "fR,f,Q,f,F,m"))]
+  [(set (match_operand:DF 0 "general_operand" "=a,fR,a,Q,m")
+        (match_operand:DF 1 "general_operand" "fFR,a,Q,a,m"))]
   ""
-  "* return output_move_quad (operands);"
+  "* if (which_alternative ==0)
+       return \"ldd %1, %0\";
+     else if (which_alternative == 1)
+       return \"std %1, %0\";
+     else 
+       return output_move_quad (operands); "
 ;; just a guess..
-  [(set_attr "length" "1,1,2,2,5,16")])
+  [(set_attr "length" "1,1,5,5,16")])
 
 (define_insn "movsf"
   [(set (match_operand:SF 0 "general_operand" "=g,r,g")
 ;; maybe fiddle a bit with move_ratio, then 
 ;; let constraints only accept a register ...
 
-(define_expand "movstrhi"
+(define_expand "movmemhi"
   [(parallel [(set (match_operand:BLK 0 "general_operand" "=g,g")
                   (match_operand:BLK 1 "general_operand" "g,g"))
              (use (match_operand:HI 2 "arith_operand" "n,&mr"))
 }")
 
 
-(define_insn "" ; "movstrhi"
+(define_insn "" ; "movmemhi"
   [(set (mem:BLK (match_operand:HI 0 "general_operand" "=r,r"))
        (mem:BLK (match_operand:HI 1 "general_operand" "r,r")))
    (use (match_operand:HI 2 "arith_operand" "n,&r"))
   [(set (match_operand:HI 0 "general_operand" "=r")
        (zero_extend:HI (match_operand:QI 1 "general_operand" "0")))]
   ""
-  "bic $(256*255), %0"
+  "bic $0177400, %0"
   [(set_attr "length" "2")])
                         
 (define_expand "zero_extendhisi2"
 
     default:
 
-      abort();
+      gcc_unreachable ();
   }
 }"
   [(set_attr "length" "5,3,3")])
        rtx latehalf[2];
 
        latehalf[0] = NULL; 
-       latehalf[1] = gen_rtx_REG (HImode, REGNO (operands[0]) + 1);
+       latehalf[1] = gen_rtx_REG (HImode, REGNO (operands[1]) + 1);
        output_asm_insn(\"mov %1, -(sp)\", latehalf);
        output_asm_insn(\"mov %1, -(sp)\", operands);
        
        return \"decb %0\";
     }
 
-  return \"addb %2, %0\";
+  return \"add %2, %0\";
 }"
   [(set_attr "length" "1,2,2,3")])
 
   ""
   "*
 {
-  if (GET_CODE (operands[2]) == CONST_INT)
-    abort();
+  gcc_assert (GET_CODE (operands[2]) != CONST_INT);
 
   return \"sub %2, %0\";
 }"
   ""
   "*
 {
-  if (GET_CODE (operands[2]) == CONST_INT)
-    abort();
+  gcc_assert (GET_CODE (operands[2]) != CONST_INT);
 
-  return \"subb %2, %0\";
+  return \"sub %2, %0\";
 }"
   [(set_attr "length" "1,2,2,3")])
 
 ;;;;- and instructions
 ;; Bit-and on the pdp (like on the VAX) is done with a clear-bits insn.
-(define_expand "andsi3"
-  [(set (match_operand:SI 0 "general_operand" "=g")
-       (and:SI (match_operand:SI 1 "general_operand" "0")
-               (not:SI (match_operand:SI 2 "general_operand" "g"))))]
-  ""
-  "
-{
-  if (GET_CODE (operands[2]) == CONST_INT)
-    operands[2] = GEN_INT (~INTVAL (operands[2]));
-  else
-    operands[2] = expand_unop (SImode, one_cmpl_optab, operands[2], 0, 1);
-}")
-
-(define_expand "andhi3"
-  [(set (match_operand:HI 0 "general_operand" "=g")
-       (and:HI (match_operand:HI 1 "general_operand" "0")
-               (not:HI (match_operand:HI 2 "general_operand" "g"))))]
-  ""
-  "
-{
-  if (GET_CODE (operands[2]) == CONST_INT)
-    operands[2] = GEN_INT (~INTVAL (operands[2]));
-  else
-    operands[2] = expand_unop (HImode, one_cmpl_optab, operands[2], 0, 1);
-}")
-
-(define_expand "andqi3"
-  [(set (match_operand:QI 0 "general_operand" "=g")
-       (and:QI (match_operand:QI 1 "general_operand" "0")
-               (not:QI (match_operand:QI 2 "general_operand" "g"))))]
-  ""
-  "
-{
-  rtx op = operands[2];
-  if (GET_CODE (op) == CONST_INT)
-    operands[2] = GEN_INT (((1 << 8) - 1) & ~INTVAL (op));
-  else
-    operands[2] = expand_unop (QImode, one_cmpl_optab, op, 0, 1);
-}")
 
-(define_insn "andcbsi3"
+(define_insn "andsi3"
   [(set (match_operand:SI 0 "general_operand" "=r,r,o,o,r,r,r,o,o,o")
         (and:SI (match_operand:SI 1 "general_operand" "%0,0,0,0,0,0,0,0,0,0")
                 (not:SI (match_operand:SI 2 "general_operand" "r,o,r,o,I,J,K,I,J,K"))))]
 }"
   [(set_attr "length" "2,4,4,6,2,2,4,3,3,6")])
 
-(define_insn "andcbhi3"
+(define_insn "andhi3"
   [(set (match_operand:HI 0 "general_operand" "=rR,rR,Q,Q")
        (and:HI (match_operand:HI 1 "general_operand" "0,0,0,0")
                (not:HI (match_operand:HI 2 "general_operand" "rR,Qi,rR,Qi"))))]
   "bic %2, %0"
   [(set_attr "length" "1,2,2,3")])
 
-(define_insn "andcbqi3"
+(define_insn "andqi3"
   [(set (match_operand:QI 0 "general_operand" "=rR,rR,Q,Q")
        (and:QI (match_operand:QI 1 "general_operand" "0,0,0,0")
                (not:QI (match_operand:QI 2 "general_operand" "rR,Qi,rR,Qi"))))]
 
 ;;- xor instructions
 (define_insn "xorsi3"
-  [(set (match_operand:SI 0 "register_operand" "=r,r,r,r")
-        (xor:SI (match_operand:SI 1 "register_operand" "%0,0,0,0")
-                  (match_operand:SI 2 "arith_operand" "r,I,J,K")))]
+  [(set (match_operand:SI 0 "register_operand" "=r")
+        (xor:SI (match_operand:SI 1 "register_operand" "%0")
+                (match_operand:SI 2 "arith_operand" "r")))]
   "TARGET_40_PLUS"
   "*
 { /* Here we trust that operands don't overlap */
       return \"\";
     }
 
-  lateoperands[2] = GEN_INT ((INTVAL (operands[2]) >> 16) & 0xffff);
-  operands[2] = GEN_INT (INTVAL(operands[2]) & 0xffff);
-  
-  if (INTVAL (operands[2]))
-    output_asm_insn (\"xor %2, %0\", operands);
-
-  if (INTVAL (lateoperands[2]))
-    output_asm_insn (\"xor %2, %0\", lateoperands);
-
-  return \"\";
 }"
-  [(set_attr "length" "2,1,1,2")])
+  [(set_attr "length" "2")])
 
 (define_insn "xorhi3"
   [(set (match_operand:HI 0 "general_operand" "=rR,Q")
   [(set_attr "length" "1,2")])
 
 (define_insn "one_cmplqi2"
-  [(set (match_operand:QI 0 "general_operand" "=rR,Q")
-        (not:QI (match_operand:QI 1 "general_operand" "0,0")))]
+  [(set (match_operand:QI 0 "general_operand" "=rR,rR")
+        (not:QI (match_operand:QI 1 "general_operand" "0,g")))]
   ""
-  "comb %0"
+  "@
+  comb %0
+  movb %1, %0\; comb %0"
   [(set_attr "length" "1,2")])
 
 ;;- arithmetic shift instructions
   "asr %0"
   [(set_attr "length" "1,2")])
 
+;; lsr
+(define_insn "" 
+  [(set (match_operand:HI 0 "general_operand" "=rR,Q")
+       (lshiftrt:HI (match_operand:HI 1 "general_operand" "0,0")
+                  (const_int 1)))]
+  ""
+  "clc\;ror %0"
+  [(set_attr "length" "1,2")])
+
+(define_insn "lshrsi3"
+  [(set (match_operand:SI 0 "register_operand" "=r")
+       (lshiftrt:SI (match_operand:SI 1 "general_operand" "0")
+                   (const_int 1)))]
+  ""
+{
+
+  rtx lateoperands[2];
+
+  lateoperands[0] = operands[0];
+  operands[0] = gen_rtx_REG (HImode, REGNO (operands[0]) + 1);
+
+  lateoperands[1] = operands[1];
+  operands[1] = gen_rtx_REG (HImode, REGNO (operands[1]) + 1);
+
+  output_asm_insn (\"clc\", operands);
+  output_asm_insn (\"ror %0\", lateoperands);
+  output_asm_insn (\"ror %0\", operands);
+
+  return \"\";
+}
+  [(set_attr "length" "5")])
+
 ;; shift is by arbitrary count is expensive, 
 ;; shift by one cheap - so let's do that, if
 ;; space doesn't matter
 ;
 ;  /* allow REG_NOTES to be set on last insn (labels don't have enough
 ;     fields, and can't be used for REG_NOTES anyway).  */
-;  emit_insn (gen_rtx_USE (VOIDmode, stack_pointer_rtx));
+;  emit_use (stack_pointer_rtx);
 ;  DONE;
 ;}")
 
   "{negd|negf} %0"
   [(set_attr "length" "1,2")])
 
+(define_insn "negsi2"
+  [(set (match_operand:SI 0 "register_operand" "=r")
+       (neg:SI (match_operand:SI 1 "general_operand" "0")))]
+  ""
+{
+
+  rtx lateoperands[2];
+
+  lateoperands[0] = operands[0];
+  operands[0] = gen_rtx_REG (HImode, REGNO (operands[0]) + 1);
+
+  lateoperands[1] = operands[1];
+  operands[1] = gen_rtx_REG (HImode, REGNO (operands[1]) + 1);
+
+  output_asm_insn (\"com %0\", operands);
+  output_asm_insn (\"com %0\", lateoperands);
+  output_asm_insn (\"inc %0\", operands);
+  output_asm_insn (\"adc %0\", lateoperands);
+
+  return \"\";
+}
+  [(set_attr "length" "5")])
+
 (define_insn "neghi2"
   [(set (match_operand:HI 0 "general_operand" "=rR,Q")
        (neg:HI (match_operand:HI 1 "general_operand" "0,0")))]
 ;;- jump to subroutine
 
 (define_insn "call"
-  [(call (match_operand:HI 0 "general_operand" "R,Q")
+  [(call (match_operand:HI 0 "general_operand" "rR,Q")
         (match_operand:HI 1 "general_operand" "g,g"))
 ;;   (use (reg:HI 0)) what was that ???
   ]
 ;;- jump to subroutine
 (define_insn "call_value"
   [(set (match_operand 0 "" "")
-       (call (match_operand:HI 1 "general_operand" "R,Q")
+       (call (match_operand:HI 1 "general_operand" "rR,Q")
              (match_operand:HI 2 "general_operand" "g,g")))
 ;;   (use (reg:HI 0)) - what was that ????
   ]
   "")
 
 (define_insn ""
-  [(set (subreg:HI (match_operand:SI 0 "general_operand" "=r") 4)
+  [(set (subreg:HI (match_operand:SI 0 "general_operand" "=r") 2)
        (mod:HI (match_operand:SI 1 "general_operand" "0")
                (match_operand:HI 2 "general_operand" "g")))]
   "TARGET_45"