--- ./gcc/config/mips/allegrex.md.orig	2012-01-21 14:11:18.000000000 +0000
+++ ./gcc/config/mips/allegrex.md	2012-01-21 14:11:18.000000000 +0000
@@ -0,0 +1,191 @@
+;; Sony ALLEGREX instructions.
+;; Copyright (C) 2005 Free Software Foundation, Inc.
+;;
+;; This file is part of GCC.
+;;
+;; 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)
+;; any later version.
+;;
+;; 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 GCC; see the file COPYING.  If not, write to
+;; the Free Software Foundation, 59 Temple Place - Suite 330,
+;; Boston, MA 02111-1307, USA.
+
+(define_c_enum "unspec" [
+  UNSPEC_WSBH
+  UNSPEC_CLO
+  UNSPEC_CTO
+  UNSPEC_CACHE
+  UNSPEC_CEIL_W_S
+  UNSPEC_FLOOR_W_S
+  UNSPEC_ROUND_W_S
+])
+
+;; Multiply Add and Subtract.
+;; Note: removed clobbering for madd and msub (testing needed)
+
+(define_insn "allegrex_madd"
+  [(set (match_operand:SI 0 "register_operand" "+l")
+       (plus:SI (mult:SI (match_operand:SI 1 "register_operand" "d")
+             (match_operand:SI 2 "register_operand" "d"))
+        (match_dup 0)))]
+  "TARGET_ALLEGREX"
+  "madd\t%1,%2"
+  [(set_attr "type"    "imadd")
+   (set_attr "mode"    "SI")])
+
+(define_insn "allegrex_msub"
+  [(set (match_operand:SI 0 "register_operand" "+l")
+       (minus:SI (match_dup 0)
+         (mult:SI (match_operand:SI 1 "register_operand" "d")
+              (match_operand:SI 2 "register_operand" "d"))))]
+  "TARGET_ALLEGREX"
+  "msub\t%1,%2"
+  [(set_attr "type"    "imadd")
+   (set_attr "mode"    "SI")])
+
+
+;; Min and max.
+
+(define_insn "sminsi3"
+  [(set (match_operand:SI 0 "register_operand" "=d")
+        (smin:SI (match_operand:SI 1 "register_operand" "d")
+                 (match_operand:SI 2 "register_operand" "d")))]
+  "TARGET_ALLEGREX"
+  "min\t%0,%1,%2"
+  [(set_attr "type"    "arith")
+   (set_attr "mode"    "SI")])
+
+(define_insn "smaxsi3"
+  [(set (match_operand:SI 0 "register_operand" "=d")
+        (smax:SI (match_operand:SI 1 "register_operand" "d")
+                 (match_operand:SI 2 "register_operand" "d")))]
+  "TARGET_ALLEGREX"
+  "max\t%0,%1,%2"
+  [(set_attr "type"    "arith")
+   (set_attr "mode"    "SI")])
+
+
+;; Extended shift instructions.
+
+(define_insn "allegrex_bitrev"
+  [(set (match_operand:SI 0 "register_operand" "=d")
+   (unspec:SI [(match_operand:SI 1 "register_operand" "d")]
+          UNSPEC_BITREV))]
+  "TARGET_ALLEGREX"
+  "bitrev\t%0,%1"
+  [(set_attr "type"    "arith")
+   (set_attr "mode"    "SI")])
+
+(define_insn "allegrex_wsbh"
+  [(set (match_operand:SI 0 "register_operand" "=d")
+   (unspec:SI [(match_operand:SI 1 "register_operand" "d")]
+          UNSPEC_WSBH))]
+  "TARGET_ALLEGREX"
+  "wsbh\t%0,%1"
+  [(set_attr "type"    "arith")
+   (set_attr "mode"    "SI")])
+
+(define_insn "bswapsi2"
+  [(set (match_operand:SI 0 "register_operand" "=d")
+   (bswap:SI (match_operand:SI 1 "register_operand" "d")))]
+  "TARGET_ALLEGREX"
+  "wsbw\t%0,%1"
+  [(set_attr "type"    "shift")
+   (set_attr "mode"    "SI")])
+
+
+;; Count leading ones, count trailing zeros, and count trailing ones (clz is
+;; already defined).
+
+(define_insn "allegrex_clo"
+  [(set (match_operand:SI 0 "register_operand" "=d")
+       (unspec:SI [(match_operand:SI 1 "register_operand" "d")]
+          UNSPEC_CLO))]
+  "TARGET_ALLEGREX"
+  "clo\t%0,%1"
+  [(set_attr "type"    "clz")
+   (set_attr "mode"    "SI")])
+
+(define_expand "ctzsi2"
+  [(set (match_operand:SI 0 "register_operand")
+       (ctz:SI (match_operand:SI 1 "register_operand")))]
+  "TARGET_ALLEGREX"
+{
+  rtx r1;
+
+  r1 = gen_reg_rtx (SImode);
+  emit_insn (gen_allegrex_bitrev (r1, operands[1]));
+  emit_insn (gen_clzsi2 (operands[0], r1));
+  DONE;
+})
+
+(define_expand "allegrex_cto"
+  [(set (match_operand:SI 0 "register_operand")
+       (unspec:SI [(match_operand:SI 1 "register_operand")]
+          UNSPEC_CTO))]
+  "TARGET_ALLEGREX"
+{
+  rtx r1;
+
+  r1 = gen_reg_rtx (SImode);
+  emit_insn (gen_allegrex_bitrev (r1, operands[1]));
+  emit_insn (gen_allegrex_clo (operands[0], r1));
+  DONE;
+})
+
+
+;; Misc.
+
+(define_insn "allegrex_sync"
+  [(unspec_volatile [(const_int 0)] UNSPEC_SYNC)]
+  "TARGET_ALLEGREX"
+  "sync"
+  [(set_attr "type"    "unknown")
+   (set_attr "mode"    "none")])
+
+(define_insn "allegrex_cache"
+  [(unspec_volatile [(match_operand:SI 0 "const_int_operand" "")
+            (match_operand:SI 1 "register_operand" "d")]
+           UNSPEC_CACHE)]
+  "TARGET_ALLEGREX"
+  "cache\t%0,0(%1)"
+  [(set_attr "type"    "unknown")
+   (set_attr "mode"    "none")])
+
+
+;; Floating-point builtins.
+
+(define_insn "allegrex_ceil_w_s"
+  [(set (match_operand:SI 0 "register_operand" "=f")
+       (unspec:SI [(match_operand:SF 1 "register_operand" "f")]
+          UNSPEC_CEIL_W_S))]
+  "TARGET_ALLEGREX"
+  "ceil.w.s\t%0,%1"
+  [(set_attr "type"    "fcvt")
+   (set_attr "mode"    "SF")])
+
+(define_insn "allegrex_floor_w_s"
+  [(set (match_operand:SI 0 "register_operand" "=f")
+       (unspec:SI [(match_operand:SF 1 "register_operand" "f")]
+          UNSPEC_FLOOR_W_S))]
+  "TARGET_ALLEGREX"
+  "floor.w.s\t%0,%1"
+  [(set_attr "type"    "fcvt")
+   (set_attr "mode"    "SF")])
+
+(define_insn "allegrex_round_w_s"
+  [(set (match_operand:SI 0 "register_operand" "=f")
+       (unspec:SI [(match_operand:SF 1 "register_operand" "f")]
+          UNSPEC_ROUND_W_S))]
+  "TARGET_ALLEGREX"
+  "round.w.s\t%0,%1"
+  [(set_attr "type"    "fcvt")
+   (set_attr "mode"    "SF")])
