OpenCores
URL https://opencores.org/ocsvn/openrisc/openrisc/trunk

Subversion Repositories openrisc

[/] [openrisc/] [trunk/] [gnu-old/] [gcc-4.2.2/] [gcc/] [config/] [arc/] [arc.md] - Diff between revs 154 and 816

Only display areas with differences | Details | Blame | View Log

Rev 154 Rev 816
;; Machine description of the Argonaut ARC cpu for GNU C compiler
;; Machine description of the Argonaut ARC cpu for GNU C compiler
;; Copyright (C) 1994, 1997, 1998, 1999, 2000, 2004, 2005, 2007
;; Copyright (C) 1994, 1997, 1998, 1999, 2000, 2004, 2005, 2007
;; Free Software Foundation, Inc.
;; Free Software Foundation, Inc.
;; This file is part of GCC.
;; This file is part of GCC.
;; GCC 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
;; it under the terms of the GNU General Public License as published by
;; the Free Software Foundation; either version 3, or (at your option)
;; the Free Software Foundation; either version 3, or (at your option)
;; any later version.
;; any later version.
;; GCC 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
;; but WITHOUT ANY WARRANTY; without even the implied warranty of
;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
;; GNU General Public License for more details.
;; GNU General Public License for more details.
;; You should have received a copy of the GNU General Public License
;; You should have received a copy of the GNU General Public License
;; along with GCC; see the file COPYING3.  If not see
;; along with GCC; see the file COPYING3.  If not see
;; .
;; .
;; See file "rtl.def" for documentation on define_insn, match_*, et. al.
;; See file "rtl.def" for documentation on define_insn, match_*, et. al.
;; ??? This is an old port, and is undoubtedly suffering from bit rot.
;; ??? This is an old port, and is undoubtedly suffering from bit rot.


;; Insn type.  Used to default other attribute values.
;; Insn type.  Used to default other attribute values.
(define_attr "type"
(define_attr "type"
  "move,load,store,cmove,unary,binary,compare,shift,mul,uncond_branch,branch,call,call_no_delay_slot,multi,misc"
  "move,load,store,cmove,unary,binary,compare,shift,mul,uncond_branch,branch,call,call_no_delay_slot,multi,misc"
  (const_string "binary"))
  (const_string "binary"))
;; Length (in # of insns, long immediate constants counted too).
;; Length (in # of insns, long immediate constants counted too).
;; ??? There's a nasty interaction between the conditional execution fsm
;; ??? There's a nasty interaction between the conditional execution fsm
;; and insn lengths: insns with shimm values cannot be conditionally executed.
;; and insn lengths: insns with shimm values cannot be conditionally executed.
(define_attr "length" ""
(define_attr "length" ""
  (cond [(eq_attr "type" "load")
  (cond [(eq_attr "type" "load")
         (if_then_else (match_operand 1 "long_immediate_loadstore_operand" "")
         (if_then_else (match_operand 1 "long_immediate_loadstore_operand" "")
                       (const_int 2) (const_int 1))
                       (const_int 2) (const_int 1))
         (eq_attr "type" "store")
         (eq_attr "type" "store")
         (if_then_else (match_operand 0 "long_immediate_loadstore_operand" "")
         (if_then_else (match_operand 0 "long_immediate_loadstore_operand" "")
                       (const_int 2) (const_int 1))
                       (const_int 2) (const_int 1))
         (eq_attr "type" "move,unary,compare")
         (eq_attr "type" "move,unary,compare")
         (if_then_else (match_operand 1 "long_immediate_operand" "")
         (if_then_else (match_operand 1 "long_immediate_operand" "")
                       (const_int 2) (const_int 1))
                       (const_int 2) (const_int 1))
         (eq_attr "type" "binary,mul")
         (eq_attr "type" "binary,mul")
         (if_then_else (match_operand 2 "long_immediate_operand" "")
         (if_then_else (match_operand 2 "long_immediate_operand" "")
                       (const_int 2) (const_int 1))
                       (const_int 2) (const_int 1))
         (eq_attr "type" "cmove")
         (eq_attr "type" "cmove")
         (if_then_else (match_operand 2 "register_operand" "")
         (if_then_else (match_operand 2 "register_operand" "")
                       (const_int 1) (const_int 2))
                       (const_int 1) (const_int 2))
         (eq_attr "type" "multi") (const_int 2)
         (eq_attr "type" "multi") (const_int 2)
        ]
        ]
        (const_int 1)))
        (const_int 1)))
;; The length here is the length of a single asm.  Unfortunately it might be
;; The length here is the length of a single asm.  Unfortunately it might be
;; 1 or 2 so we must allow for 2.  That's ok though.  How often will users
;; 1 or 2 so we must allow for 2.  That's ok though.  How often will users
;; lament asm's not being put in delay slots?
;; lament asm's not being put in delay slots?
(define_asm_attributes
(define_asm_attributes
  [(set_attr "length" "2")
  [(set_attr "length" "2")
   (set_attr "type" "multi")])
   (set_attr "type" "multi")])
;; Condition codes: this one is used by final_prescan_insn to speed up
;; Condition codes: this one is used by final_prescan_insn to speed up
;; conditionalizing instructions.  It saves having to scan the rtl to see if
;; conditionalizing instructions.  It saves having to scan the rtl to see if
;; it uses or alters the condition codes.
;; it uses or alters the condition codes.
;; USE: This insn uses the condition codes (e.g.: a conditional branch).
;; USE: This insn uses the condition codes (e.g.: a conditional branch).
;; CANUSE: This insn can use the condition codes (for conditional execution).
;; CANUSE: This insn can use the condition codes (for conditional execution).
;; SET: All condition codes are set by this insn.
;; SET: All condition codes are set by this insn.
;; SET_ZN: the Z and N flags are set by this insn.
;; SET_ZN: the Z and N flags are set by this insn.
;; SET_ZNC: the Z, N, and C flags are set by this insn.
;; SET_ZNC: the Z, N, and C flags are set by this insn.
;; CLOB: The condition codes are set to unknown values by this insn.
;; CLOB: The condition codes are set to unknown values by this insn.
;; NOCOND: This insn can't use and doesn't affect the condition codes.
;; NOCOND: This insn can't use and doesn't affect the condition codes.
(define_attr "cond" "use,canuse,set,set_zn,set_znc,clob,nocond"
(define_attr "cond" "use,canuse,set,set_zn,set_znc,clob,nocond"
  (cond [(and (eq_attr "type" "unary,binary,move")
  (cond [(and (eq_attr "type" "unary,binary,move")
              (eq_attr "length" "1"))
              (eq_attr "length" "1"))
         (const_string "canuse")
         (const_string "canuse")
         (eq_attr "type" "compare")
         (eq_attr "type" "compare")
         (const_string "set")
         (const_string "set")
         (eq_attr "type" "cmove,branch")
         (eq_attr "type" "cmove,branch")
         (const_string "use")
         (const_string "use")
         (eq_attr "type" "multi,misc")
         (eq_attr "type" "multi,misc")
         (const_string "clob")
         (const_string "clob")
         ]
         ]
         (const_string "nocond")))
         (const_string "nocond")))


;; Delay slots.
;; Delay slots.
(define_attr "in_delay_slot" "false,true"
(define_attr "in_delay_slot" "false,true"
  (cond [(eq_attr "type" "uncond_branch,branch,call,call_no_delay_slot,multi")
  (cond [(eq_attr "type" "uncond_branch,branch,call,call_no_delay_slot,multi")
         (const_string "false")
         (const_string "false")
         ]
         ]
         (if_then_else (eq_attr "length" "1")
         (if_then_else (eq_attr "length" "1")
                       (const_string "true")
                       (const_string "true")
                       (const_string "false"))))
                       (const_string "false"))))
(define_delay (eq_attr "type" "call")
(define_delay (eq_attr "type" "call")
  [(eq_attr "in_delay_slot" "true")
  [(eq_attr "in_delay_slot" "true")
   (eq_attr "in_delay_slot" "true")
   (eq_attr "in_delay_slot" "true")
   (eq_attr "in_delay_slot" "true")])
   (eq_attr "in_delay_slot" "true")])
(define_delay (eq_attr "type" "branch,uncond_branch")
(define_delay (eq_attr "type" "branch,uncond_branch")
  [(eq_attr "in_delay_slot" "true")
  [(eq_attr "in_delay_slot" "true")
   (eq_attr "in_delay_slot" "true")
   (eq_attr "in_delay_slot" "true")
   (eq_attr "in_delay_slot" "true")])
   (eq_attr "in_delay_slot" "true")])


;; Scheduling description for the ARC
;; Scheduling description for the ARC
(define_cpu_unit "branch")
(define_cpu_unit "branch")
(define_insn_reservation "any_insn" 1 (eq_attr "type" "!load,compare,branch")
(define_insn_reservation "any_insn" 1 (eq_attr "type" "!load,compare,branch")
                         "nothing")
                         "nothing")
;; 1) A conditional jump cannot immediately follow the insn setting the flags.
;; 1) A conditional jump cannot immediately follow the insn setting the flags.
;; This isn't a complete solution as it doesn't come with guarantees.  That
;; This isn't a complete solution as it doesn't come with guarantees.  That
;; is done in the branch patterns and in arc_print_operand.  This exists to
;; is done in the branch patterns and in arc_print_operand.  This exists to
;; avoid inserting a nop when we can.
;; avoid inserting a nop when we can.
(define_insn_reservation "compare" 1 (eq_attr "type" "compare")
(define_insn_reservation "compare" 1 (eq_attr "type" "compare")
                         "nothing,branch")
                         "nothing,branch")
(define_insn_reservation "branch" 1 (eq_attr "type" "branch")
(define_insn_reservation "branch" 1 (eq_attr "type" "branch")
                         "branch")
                         "branch")
;; 2) References to loaded registers should wait a cycle.
;; 2) References to loaded registers should wait a cycle.
;; Memory with load-delay of 1 (i.e., 2 cycle load).
;; Memory with load-delay of 1 (i.e., 2 cycle load).
(define_insn_reservation "memory" 2 (eq_attr "type" "load")
(define_insn_reservation "memory" 2 (eq_attr "type" "load")
                         "nothing")
                         "nothing")


;; Move instructions.
;; Move instructions.
(define_expand "movqi"
(define_expand "movqi"
  [(set (match_operand:QI 0 "general_operand" "")
  [(set (match_operand:QI 0 "general_operand" "")
        (match_operand:QI 1 "general_operand" ""))]
        (match_operand:QI 1 "general_operand" ""))]
  ""
  ""
  "
  "
{
{
  /* Everything except mem = const or mem = mem can be done easily.  */
  /* Everything except mem = const or mem = mem can be done easily.  */
  if (GET_CODE (operands[0]) == MEM)
  if (GET_CODE (operands[0]) == MEM)
    operands[1] = force_reg (QImode, operands[1]);
    operands[1] = force_reg (QImode, operands[1]);
}")
}")
(define_insn "*movqi_insn"
(define_insn "*movqi_insn"
  [(set (match_operand:QI 0 "move_dest_operand" "=r,r,r,m")
  [(set (match_operand:QI 0 "move_dest_operand" "=r,r,r,m")
        (match_operand:QI 1 "move_src_operand" "rI,Ji,m,r"))]
        (match_operand:QI 1 "move_src_operand" "rI,Ji,m,r"))]
;; ??? Needed?
;; ??? Needed?
  "register_operand (operands[0], QImode)
  "register_operand (operands[0], QImode)
   || register_operand (operands[1], QImode)"
   || register_operand (operands[1], QImode)"
  "@
  "@
   mov%? %0,%1
   mov%? %0,%1
   mov%? %0,%1
   mov%? %0,%1
   ldb%U1%V1 %0,%1
   ldb%U1%V1 %0,%1
   stb%U0%V0 %1,%0"
   stb%U0%V0 %1,%0"
  [(set_attr "type" "move,move,load,store")])
  [(set_attr "type" "move,move,load,store")])
;; ??? This may never match since there's no cmpqi insn.
;; ??? This may never match since there's no cmpqi insn.
(define_insn "*movqi_set_cc_insn"
(define_insn "*movqi_set_cc_insn"
  [(set (reg:CCZN 61) (compare:CCZN
  [(set (reg:CCZN 61) (compare:CCZN
                       (sign_extend:SI (match_operand:QI 1 "move_src_operand" "rIJi"))
                       (sign_extend:SI (match_operand:QI 1 "move_src_operand" "rIJi"))
                       (const_int 0)))
                       (const_int 0)))
   (set (match_operand:QI 0 "move_dest_operand" "=r")
   (set (match_operand:QI 0 "move_dest_operand" "=r")
        (match_dup 1))]
        (match_dup 1))]
  ""
  ""
  "mov%?.f %0,%1"
  "mov%?.f %0,%1"
  [(set_attr "type" "move")
  [(set_attr "type" "move")
   (set_attr "cond" "set_zn")])
   (set_attr "cond" "set_zn")])
(define_expand "movhi"
(define_expand "movhi"
  [(set (match_operand:HI 0 "general_operand" "")
  [(set (match_operand:HI 0 "general_operand" "")
        (match_operand:HI 1 "general_operand" ""))]
        (match_operand:HI 1 "general_operand" ""))]
  ""
  ""
  "
  "
{
{
  /* Everything except mem = const or mem = mem can be done easily.  */
  /* Everything except mem = const or mem = mem can be done easily.  */
  if (GET_CODE (operands[0]) == MEM)
  if (GET_CODE (operands[0]) == MEM)
    operands[1] = force_reg (HImode, operands[1]);
    operands[1] = force_reg (HImode, operands[1]);
}")
}")
(define_insn "*movhi_insn"
(define_insn "*movhi_insn"
  [(set (match_operand:HI 0 "move_dest_operand" "=r,r,r,m")
  [(set (match_operand:HI 0 "move_dest_operand" "=r,r,r,m")
        (match_operand:HI 1 "move_src_operand" "rI,Ji,m,r"))]
        (match_operand:HI 1 "move_src_operand" "rI,Ji,m,r"))]
  "register_operand (operands[0], HImode)
  "register_operand (operands[0], HImode)
   || register_operand (operands[1], HImode)"
   || register_operand (operands[1], HImode)"
  "@
  "@
   mov%? %0,%1
   mov%? %0,%1
   mov%? %0,%1
   mov%? %0,%1
   ldw%U1%V1 %0,%1
   ldw%U1%V1 %0,%1
   stw%U0%V0 %1,%0"
   stw%U0%V0 %1,%0"
  [(set_attr "type" "move,move,load,store")])
  [(set_attr "type" "move,move,load,store")])
;; ??? Will this ever match?
;; ??? Will this ever match?
(define_insn "*movhi_set_cc_insn"
(define_insn "*movhi_set_cc_insn"
  [(set (reg:CCZN 61) (compare:CCZN
  [(set (reg:CCZN 61) (compare:CCZN
                       (sign_extend:SI (match_operand:HI 1 "move_src_operand" "rIJi"))
                       (sign_extend:SI (match_operand:HI 1 "move_src_operand" "rIJi"))
                       (const_int 0)))
                       (const_int 0)))
   (set (match_operand:HI 0 "move_dest_operand" "=r")
   (set (match_operand:HI 0 "move_dest_operand" "=r")
        (match_dup 1))]
        (match_dup 1))]
;; ??? Needed?
;; ??? Needed?
  "register_operand (operands[0], HImode)
  "register_operand (operands[0], HImode)
   || register_operand (operands[1], HImode)"
   || register_operand (operands[1], HImode)"
  "mov%?.f %0,%1"
  "mov%?.f %0,%1"
  [(set_attr "type" "move")
  [(set_attr "type" "move")
   (set_attr "cond" "set_zn")])
   (set_attr "cond" "set_zn")])
(define_expand "movsi"
(define_expand "movsi"
  [(set (match_operand:SI 0 "general_operand" "")
  [(set (match_operand:SI 0 "general_operand" "")
        (match_operand:SI 1 "general_operand" ""))]
        (match_operand:SI 1 "general_operand" ""))]
  ""
  ""
  "
  "
{
{
  /* Everything except mem = const or mem = mem can be done easily.  */
  /* Everything except mem = const or mem = mem can be done easily.  */
  if (GET_CODE (operands[0]) == MEM)
  if (GET_CODE (operands[0]) == MEM)
    operands[1] = force_reg (SImode, operands[1]);
    operands[1] = force_reg (SImode, operands[1]);
}")
}")
(define_insn "*movsi_insn"
(define_insn "*movsi_insn"
  [(set (match_operand:SI 0 "move_dest_operand" "=r,r,r,m")
  [(set (match_operand:SI 0 "move_dest_operand" "=r,r,r,m")
        (match_operand:SI 1 "move_src_operand" "rI,GJi,m,r"))]
        (match_operand:SI 1 "move_src_operand" "rI,GJi,m,r"))]
  "register_operand (operands[0], SImode)
  "register_operand (operands[0], SImode)
   || register_operand (operands[1], SImode)"
   || register_operand (operands[1], SImode)"
  "@
  "@
   mov%? %0,%1
   mov%? %0,%1
   mov%? %0,%S1
   mov%? %0,%S1
   ld%U1%V1 %0,%1
   ld%U1%V1 %0,%1
   st%U0%V0 %1,%0"
   st%U0%V0 %1,%0"
  [(set_attr "type" "move,move,load,store")])
  [(set_attr "type" "move,move,load,store")])
(define_insn "*movsi_set_cc_insn"
(define_insn "*movsi_set_cc_insn"
  [(set (reg:CCZN 61) (compare:CCZN
  [(set (reg:CCZN 61) (compare:CCZN
                       (match_operand:SI 1 "move_src_operand" "rIJi")
                       (match_operand:SI 1 "move_src_operand" "rIJi")
                       (const_int 0)))
                       (const_int 0)))
   (set (match_operand:SI 0 "move_dest_operand" "=r")
   (set (match_operand:SI 0 "move_dest_operand" "=r")
        (match_dup 1))]
        (match_dup 1))]
  "register_operand (operands[0], SImode)
  "register_operand (operands[0], SImode)
   || register_operand (operands[1], SImode)"
   || register_operand (operands[1], SImode)"
  "mov%?.f %0,%S1"
  "mov%?.f %0,%S1"
  [(set_attr "type" "move")
  [(set_attr "type" "move")
   (set_attr "cond" "set_zn")])
   (set_attr "cond" "set_zn")])
(define_expand "movdi"
(define_expand "movdi"
  [(set (match_operand:DI 0 "general_operand" "")
  [(set (match_operand:DI 0 "general_operand" "")
        (match_operand:DI 1 "general_operand" ""))]
        (match_operand:DI 1 "general_operand" ""))]
  ""
  ""
  "
  "
{
{
  /* Everything except mem = const or mem = mem can be done easily.  */
  /* Everything except mem = const or mem = mem can be done easily.  */
  if (GET_CODE (operands[0]) == MEM)
  if (GET_CODE (operands[0]) == MEM)
    operands[1] = force_reg (DImode, operands[1]);
    operands[1] = force_reg (DImode, operands[1]);
}")
}")
(define_insn "*movdi_insn"
(define_insn "*movdi_insn"
  [(set (match_operand:DI 0 "move_dest_operand" "=r,r,r,m")
  [(set (match_operand:DI 0 "move_dest_operand" "=r,r,r,m")
        (match_operand:DI 1 "move_double_src_operand" "r,HK,m,r"))]
        (match_operand:DI 1 "move_double_src_operand" "r,HK,m,r"))]
  "register_operand (operands[0], DImode)
  "register_operand (operands[0], DImode)
   || register_operand (operands[1], DImode)"
   || register_operand (operands[1], DImode)"
  "*
  "*
{
{
  switch (which_alternative)
  switch (which_alternative)
    {
    {
    case 0 :
    case 0 :
      /* We normally copy the low-numbered register first.  However, if
      /* We normally copy the low-numbered register first.  However, if
         the first register operand 0 is the same as the second register of
         the first register operand 0 is the same as the second register of
         operand 1, we must copy in the opposite order.  */
         operand 1, we must copy in the opposite order.  */
      if (REGNO (operands[0]) == REGNO (operands[1]) + 1)
      if (REGNO (operands[0]) == REGNO (operands[1]) + 1)
        return \"mov %R0,%R1\;mov %0,%1\";
        return \"mov %R0,%R1\;mov %0,%1\";
      else
      else
        return \"mov %0,%1\;mov %R0,%R1\";
        return \"mov %0,%1\;mov %R0,%R1\";
    case 1 :
    case 1 :
      return \"mov %0,%L1\;mov %R0,%H1\";
      return \"mov %0,%L1\;mov %R0,%H1\";
    case 2 :
    case 2 :
      /* If the low-address word is used in the address, we must load it
      /* If the low-address word is used in the address, we must load it
         last.  Otherwise, load it first.  Note that we cannot have
         last.  Otherwise, load it first.  Note that we cannot have
         auto-increment in that case since the address register is known to be
         auto-increment in that case since the address register is known to be
         dead.  */
         dead.  */
      if (refers_to_regno_p (REGNO (operands[0]), REGNO (operands[0]) + 1,
      if (refers_to_regno_p (REGNO (operands[0]), REGNO (operands[0]) + 1,
                             operands [1], 0))
                             operands [1], 0))
          return \"ld%V1 %R0,%R1\;ld%V1 %0,%1\";
          return \"ld%V1 %R0,%R1\;ld%V1 %0,%1\";
      else
      else
          return \"ld%V1 %0,%1\;ld%V1 %R0,%R1\";
          return \"ld%V1 %0,%1\;ld%V1 %R0,%R1\";
    case 3 :
    case 3 :
      return \"st%V0 %1,%0\;st%V0 %R1,%R0\";
      return \"st%V0 %1,%0\;st%V0 %R1,%R0\";
    default:
    default:
      gcc_unreachable ();
      gcc_unreachable ();
    }
    }
}"
}"
  [(set_attr "type" "move,move,load,store")
  [(set_attr "type" "move,move,load,store")
   ;; ??? The ld/st values could be 4 if it's [reg,bignum].
   ;; ??? The ld/st values could be 4 if it's [reg,bignum].
   (set_attr "length" "2,4,2,2")])
   (set_attr "length" "2,4,2,2")])
;(define_expand "movdi"
;(define_expand "movdi"
;  [(set (match_operand:DI 0 "general_operand" "")
;  [(set (match_operand:DI 0 "general_operand" "")
;       (match_operand:DI 1 "general_operand" ""))]
;       (match_operand:DI 1 "general_operand" ""))]
;  ""
;  ""
;  "
;  "
;{
;{
;  /* Flow doesn't understand that this is effectively a DFmode move.
;  /* Flow doesn't understand that this is effectively a DFmode move.
;     It doesn't know that all of `operands[0]' is set.  */
;     It doesn't know that all of `operands[0]' is set.  */
;  emit_insn (gen_rtx_CLOBBER (VOIDmode, operands[0]));
;  emit_insn (gen_rtx_CLOBBER (VOIDmode, operands[0]));
;
;
;  /* Emit insns that movsi_insn can handle.  */
;  /* Emit insns that movsi_insn can handle.  */
;  emit_insn (gen_movsi (operand_subword (operands[0], 0, 0, DImode),
;  emit_insn (gen_movsi (operand_subword (operands[0], 0, 0, DImode),
;                       operand_subword (operands[1], 0, 0, DImode)));
;                       operand_subword (operands[1], 0, 0, DImode)));
;  emit_insn (gen_movsi (operand_subword (operands[0], 1, 0, DImode),
;  emit_insn (gen_movsi (operand_subword (operands[0], 1, 0, DImode),
;                       operand_subword (operands[1], 1, 0, DImode)));
;                       operand_subword (operands[1], 1, 0, DImode)));
;  DONE;
;  DONE;
;}")
;}")


;; Floating point move insns.
;; Floating point move insns.
(define_expand "movsf"
(define_expand "movsf"
  [(set (match_operand:SF 0 "general_operand" "")
  [(set (match_operand:SF 0 "general_operand" "")
        (match_operand:SF 1 "general_operand" ""))]
        (match_operand:SF 1 "general_operand" ""))]
  ""
  ""
  "
  "
{
{
  /* Everything except mem = const or mem = mem can be done easily.  */
  /* Everything except mem = const or mem = mem can be done easily.  */
  if (GET_CODE (operands[0]) == MEM)
  if (GET_CODE (operands[0]) == MEM)
    operands[1] = force_reg (SFmode, operands[1]);
    operands[1] = force_reg (SFmode, operands[1]);
}")
}")
(define_insn "*movsf_insn"
(define_insn "*movsf_insn"
  [(set (match_operand:SF 0 "move_dest_operand" "=r,r,r,m")
  [(set (match_operand:SF 0 "move_dest_operand" "=r,r,r,m")
        (match_operand:SF 1 "move_src_operand" "r,E,m,r"))]
        (match_operand:SF 1 "move_src_operand" "r,E,m,r"))]
  "register_operand (operands[0], SFmode)
  "register_operand (operands[0], SFmode)
   || register_operand (operands[1], SFmode)"
   || register_operand (operands[1], SFmode)"
  "@
  "@
   mov%? %0,%1
   mov%? %0,%1
   mov%? %0,%1 ; %A1
   mov%? %0,%1 ; %A1
   ld%U1%V1 %0,%1
   ld%U1%V1 %0,%1
   st%U0%V0 %1,%0"
   st%U0%V0 %1,%0"
  [(set_attr "type" "move,move,load,store")])
  [(set_attr "type" "move,move,load,store")])
(define_expand "movdf"
(define_expand "movdf"
  [(set (match_operand:DF 0 "general_operand" "")
  [(set (match_operand:DF 0 "general_operand" "")
        (match_operand:DF 1 "general_operand" ""))]
        (match_operand:DF 1 "general_operand" ""))]
  ""
  ""
  "
  "
{
{
  /* Everything except mem = const or mem = mem can be done easily.  */
  /* Everything except mem = const or mem = mem can be done easily.  */
  if (GET_CODE (operands[0]) == MEM)
  if (GET_CODE (operands[0]) == MEM)
    operands[1] = force_reg (DFmode, operands[1]);
    operands[1] = force_reg (DFmode, operands[1]);
}")
}")
(define_insn "*movdf_insn"
(define_insn "*movdf_insn"
  [(set (match_operand:DF 0 "move_dest_operand" "=r,r,r,m")
  [(set (match_operand:DF 0 "move_dest_operand" "=r,r,r,m")
        (match_operand:DF 1 "move_double_src_operand" "r,E,m,r"))]
        (match_operand:DF 1 "move_double_src_operand" "r,E,m,r"))]
  "register_operand (operands[0], DFmode)
  "register_operand (operands[0], DFmode)
   || register_operand (operands[1], DFmode)"
   || register_operand (operands[1], DFmode)"
  "*
  "*
{
{
  switch (which_alternative)
  switch (which_alternative)
    {
    {
    case 0 :
    case 0 :
      /* We normally copy the low-numbered register first.  However, if
      /* We normally copy the low-numbered register first.  However, if
         the first register operand 0 is the same as the second register of
         the first register operand 0 is the same as the second register of
         operand 1, we must copy in the opposite order.  */
         operand 1, we must copy in the opposite order.  */
      if (REGNO (operands[0]) == REGNO (operands[1]) + 1)
      if (REGNO (operands[0]) == REGNO (operands[1]) + 1)
        return \"mov %R0,%R1\;mov %0,%1\";
        return \"mov %R0,%R1\;mov %0,%1\";
      else
      else
        return \"mov %0,%1\;mov %R0,%R1\";
        return \"mov %0,%1\;mov %R0,%R1\";
    case 1 :
    case 1 :
      return \"mov %0,%L1\;mov %R0,%H1 ; %A1\";
      return \"mov %0,%L1\;mov %R0,%H1 ; %A1\";
    case 2 :
    case 2 :
      /* If the low-address word is used in the address, we must load it
      /* If the low-address word is used in the address, we must load it
         last.  Otherwise, load it first.  Note that we cannot have
         last.  Otherwise, load it first.  Note that we cannot have
         auto-increment in that case since the address register is known to be
         auto-increment in that case since the address register is known to be
         dead.  */
         dead.  */
      if (refers_to_regno_p (REGNO (operands[0]), REGNO (operands[0]) + 1,
      if (refers_to_regno_p (REGNO (operands[0]), REGNO (operands[0]) + 1,
                             operands [1], 0))
                             operands [1], 0))
        return \"ld%V1 %R0,%R1\;ld%V1 %0,%1\";
        return \"ld%V1 %R0,%R1\;ld%V1 %0,%1\";
      else
      else
        return \"ld%V1 %0,%1\;ld%V1 %R0,%R1\";
        return \"ld%V1 %0,%1\;ld%V1 %R0,%R1\";
    case 3 :
    case 3 :
      return \"st%V0 %1,%0\;st%V0 %R1,%R0\";
      return \"st%V0 %1,%0\;st%V0 %R1,%R0\";
    default:
    default:
      gcc_unreachable ();
      gcc_unreachable ();
    }
    }
}"
}"
  [(set_attr "type" "move,move,load,store")
  [(set_attr "type" "move,move,load,store")
   ;; ??? The ld/st values could be 4 if it's [reg,bignum].
   ;; ??? The ld/st values could be 4 if it's [reg,bignum].
   (set_attr "length" "2,4,2,2")])
   (set_attr "length" "2,4,2,2")])
;(define_expand "movdf"
;(define_expand "movdf"
;  [(set (match_operand:DF 0 "general_operand" "")
;  [(set (match_operand:DF 0 "general_operand" "")
;       (match_operand:DF 1 "general_operand" ""))]
;       (match_operand:DF 1 "general_operand" ""))]
;  ""
;  ""
;  "
;  "
;{
;{
;  /* Flow doesn't understand that this is effectively a DFmode move.
;  /* Flow doesn't understand that this is effectively a DFmode move.
;     It doesn't know that all of `operands[0]' is set.  */
;     It doesn't know that all of `operands[0]' is set.  */
;  emit_insn (gen_rtx_CLOBBER (VOIDmode, operands[0]));
;  emit_insn (gen_rtx_CLOBBER (VOIDmode, operands[0]));
;
;
;  /* Emit insns that movsi_insn can handle.  */
;  /* Emit insns that movsi_insn can handle.  */
;  emit_insn (gen_movsi (operand_subword (operands[0], 0, 0, DFmode),
;  emit_insn (gen_movsi (operand_subword (operands[0], 0, 0, DFmode),
;                       operand_subword (operands[1], 0, 0, DFmode)));
;                       operand_subword (operands[1], 0, 0, DFmode)));
;  emit_insn (gen_movsi (operand_subword (operands[0], 1, 0, DFmode),
;  emit_insn (gen_movsi (operand_subword (operands[0], 1, 0, DFmode),
;                       operand_subword (operands[1], 1, 0, DFmode)));
;                       operand_subword (operands[1], 1, 0, DFmode)));
;  DONE;
;  DONE;
;}")
;}")


;; Load/Store with update instructions.
;; Load/Store with update instructions.
;;
;;
;; Some of these we can get by using pre-decrement or pre-increment, but the
;; Some of these we can get by using pre-decrement or pre-increment, but the
;; hardware can also do cases where the increment is not the size of the
;; hardware can also do cases where the increment is not the size of the
;; object.
;; object.
;;
;;
;; In all these cases, we use operands 0 and 1 for the register being
;; In all these cases, we use operands 0 and 1 for the register being
;; incremented because those are the operands that local-alloc will
;; incremented because those are the operands that local-alloc will
;; tie and these are the pair most likely to be tieable (and the ones
;; tie and these are the pair most likely to be tieable (and the ones
;; that will benefit the most).
;; that will benefit the most).
;;
;;
;; We use match_operator here because we need to know whether the memory
;; We use match_operator here because we need to know whether the memory
;; object is volatile or not.
;; object is volatile or not.
(define_insn "*loadqi_update"
(define_insn "*loadqi_update"
  [(set (match_operand:QI 3 "register_operand" "=r,r")
  [(set (match_operand:QI 3 "register_operand" "=r,r")
        (match_operator:QI 4 "load_update_operand"
        (match_operator:QI 4 "load_update_operand"
         [(match_operand:SI 1 "register_operand" "0,0")
         [(match_operand:SI 1 "register_operand" "0,0")
          (match_operand:SI 2 "nonmemory_operand" "rI,J")]))
          (match_operand:SI 2 "nonmemory_operand" "rI,J")]))
   (set (match_operand:SI 0 "register_operand" "=r,r")
   (set (match_operand:SI 0 "register_operand" "=r,r")
        (plus:SI (match_dup 1) (match_dup 2)))]
        (plus:SI (match_dup 1) (match_dup 2)))]
  ""
  ""
  "ldb.a%V4 %3,[%0,%2]"
  "ldb.a%V4 %3,[%0,%2]"
  [(set_attr "type" "load,load")
  [(set_attr "type" "load,load")
   (set_attr "length" "1,2")])
   (set_attr "length" "1,2")])
(define_insn "*load_zeroextendqisi_update"
(define_insn "*load_zeroextendqisi_update"
  [(set (match_operand:SI 3 "register_operand" "=r,r")
  [(set (match_operand:SI 3 "register_operand" "=r,r")
        (zero_extend:SI (match_operator:QI 4 "load_update_operand"
        (zero_extend:SI (match_operator:QI 4 "load_update_operand"
                         [(match_operand:SI 1 "register_operand" "0,0")
                         [(match_operand:SI 1 "register_operand" "0,0")
                          (match_operand:SI 2 "nonmemory_operand" "rI,J")])))
                          (match_operand:SI 2 "nonmemory_operand" "rI,J")])))
   (set (match_operand:SI 0 "register_operand" "=r,r")
   (set (match_operand:SI 0 "register_operand" "=r,r")
        (plus:SI (match_dup 1) (match_dup 2)))]
        (plus:SI (match_dup 1) (match_dup 2)))]
  ""
  ""
  "ldb.a%V4 %3,[%0,%2]"
  "ldb.a%V4 %3,[%0,%2]"
  [(set_attr "type" "load,load")
  [(set_attr "type" "load,load")
   (set_attr "length" "1,2")])
   (set_attr "length" "1,2")])
(define_insn "*load_signextendqisi_update"
(define_insn "*load_signextendqisi_update"
  [(set (match_operand:SI 3 "register_operand" "=r,r")
  [(set (match_operand:SI 3 "register_operand" "=r,r")
        (sign_extend:SI (match_operator:QI 4 "load_update_operand"
        (sign_extend:SI (match_operator:QI 4 "load_update_operand"
                         [(match_operand:SI 1 "register_operand" "0,0")
                         [(match_operand:SI 1 "register_operand" "0,0")
                          (match_operand:SI 2 "nonmemory_operand" "rI,J")])))
                          (match_operand:SI 2 "nonmemory_operand" "rI,J")])))
   (set (match_operand:SI 0 "register_operand" "=r,r")
   (set (match_operand:SI 0 "register_operand" "=r,r")
        (plus:SI (match_dup 1) (match_dup 2)))]
        (plus:SI (match_dup 1) (match_dup 2)))]
  ""
  ""
  "ldb.x.a%V4 %3,[%0,%2]"
  "ldb.x.a%V4 %3,[%0,%2]"
  [(set_attr "type" "load,load")
  [(set_attr "type" "load,load")
   (set_attr "length" "1,2")])
   (set_attr "length" "1,2")])
(define_insn "*storeqi_update"
(define_insn "*storeqi_update"
  [(set (match_operator:QI 4 "store_update_operand"
  [(set (match_operator:QI 4 "store_update_operand"
         [(match_operand:SI 1 "register_operand" "0")
         [(match_operand:SI 1 "register_operand" "0")
          (match_operand:SI 2 "short_immediate_operand" "I")])
          (match_operand:SI 2 "short_immediate_operand" "I")])
        (match_operand:QI 3 "register_operand" "r"))
        (match_operand:QI 3 "register_operand" "r"))
   (set (match_operand:SI 0 "register_operand" "=r")
   (set (match_operand:SI 0 "register_operand" "=r")
        (plus:SI (match_dup 1) (match_dup 2)))]
        (plus:SI (match_dup 1) (match_dup 2)))]
  ""
  ""
  "stb.a%V4 %3,[%0,%2]"
  "stb.a%V4 %3,[%0,%2]"
  [(set_attr "type" "store")
  [(set_attr "type" "store")
   (set_attr "length" "1")])
   (set_attr "length" "1")])
(define_insn "*loadhi_update"
(define_insn "*loadhi_update"
  [(set (match_operand:HI 3 "register_operand" "=r,r")
  [(set (match_operand:HI 3 "register_operand" "=r,r")
        (match_operator:HI 4 "load_update_operand"
        (match_operator:HI 4 "load_update_operand"
         [(match_operand:SI 1 "register_operand" "0,0")
         [(match_operand:SI 1 "register_operand" "0,0")
          (match_operand:SI 2 "nonmemory_operand" "rI,J")]))
          (match_operand:SI 2 "nonmemory_operand" "rI,J")]))
   (set (match_operand:SI 0 "register_operand" "=r,r")
   (set (match_operand:SI 0 "register_operand" "=r,r")
        (plus:SI (match_dup 1) (match_dup 2)))]
        (plus:SI (match_dup 1) (match_dup 2)))]
  ""
  ""
  "ldw.a%V4 %3,[%0,%2]"
  "ldw.a%V4 %3,[%0,%2]"
  [(set_attr "type" "load,load")
  [(set_attr "type" "load,load")
   (set_attr "length" "1,2")])
   (set_attr "length" "1,2")])
(define_insn "*load_zeroextendhisi_update"
(define_insn "*load_zeroextendhisi_update"
  [(set (match_operand:SI 3 "register_operand" "=r,r")
  [(set (match_operand:SI 3 "register_operand" "=r,r")
        (zero_extend:SI (match_operator:HI 4 "load_update_operand"
        (zero_extend:SI (match_operator:HI 4 "load_update_operand"
                         [(match_operand:SI 1 "register_operand" "0,0")
                         [(match_operand:SI 1 "register_operand" "0,0")
                          (match_operand:SI 2 "nonmemory_operand" "rI,J")])))
                          (match_operand:SI 2 "nonmemory_operand" "rI,J")])))
   (set (match_operand:SI 0 "register_operand" "=r,r")
   (set (match_operand:SI 0 "register_operand" "=r,r")
        (plus:SI (match_dup 1) (match_dup 2)))]
        (plus:SI (match_dup 1) (match_dup 2)))]
  ""
  ""
  "ldw.a%V4 %3,[%0,%2]"
  "ldw.a%V4 %3,[%0,%2]"
  [(set_attr "type" "load,load")
  [(set_attr "type" "load,load")
   (set_attr "length" "1,2")])
   (set_attr "length" "1,2")])
(define_insn "*load_signextendhisi_update"
(define_insn "*load_signextendhisi_update"
  [(set (match_operand:SI 3 "register_operand" "=r,r")
  [(set (match_operand:SI 3 "register_operand" "=r,r")
        (sign_extend:SI (match_operator:HI 4 "load_update_operand"
        (sign_extend:SI (match_operator:HI 4 "load_update_operand"
                         [(match_operand:SI 1 "register_operand" "0,0")
                         [(match_operand:SI 1 "register_operand" "0,0")
                          (match_operand:SI 2 "nonmemory_operand" "rI,J")])))
                          (match_operand:SI 2 "nonmemory_operand" "rI,J")])))
   (set (match_operand:SI 0 "register_operand" "=r,r")
   (set (match_operand:SI 0 "register_operand" "=r,r")
        (plus:SI (match_dup 1) (match_dup 2)))]
        (plus:SI (match_dup 1) (match_dup 2)))]
  ""
  ""
  "ldw.x.a%V4 %3,[%0,%2]"
  "ldw.x.a%V4 %3,[%0,%2]"
  [(set_attr "type" "load,load")
  [(set_attr "type" "load,load")
   (set_attr "length" "1,2")])
   (set_attr "length" "1,2")])
(define_insn "*storehi_update"
(define_insn "*storehi_update"
  [(set (match_operator:HI 4 "store_update_operand"
  [(set (match_operator:HI 4 "store_update_operand"
         [(match_operand:SI 1 "register_operand" "0")
         [(match_operand:SI 1 "register_operand" "0")
          (match_operand:SI 2 "short_immediate_operand" "I")])
          (match_operand:SI 2 "short_immediate_operand" "I")])
        (match_operand:HI 3 "register_operand" "r"))
        (match_operand:HI 3 "register_operand" "r"))
   (set (match_operand:SI 0 "register_operand" "=r")
   (set (match_operand:SI 0 "register_operand" "=r")
        (plus:SI (match_dup 1) (match_dup 2)))]
        (plus:SI (match_dup 1) (match_dup 2)))]
  ""
  ""
  "stw.a%V4 %3,[%0,%2]"
  "stw.a%V4 %3,[%0,%2]"
  [(set_attr "type" "store")
  [(set_attr "type" "store")
   (set_attr "length" "1")])
   (set_attr "length" "1")])
(define_insn "*loadsi_update"
(define_insn "*loadsi_update"
  [(set (match_operand:SI 3 "register_operand" "=r,r")
  [(set (match_operand:SI 3 "register_operand" "=r,r")
        (match_operator:SI 4 "load_update_operand"
        (match_operator:SI 4 "load_update_operand"
         [(match_operand:SI 1 "register_operand" "0,0")
         [(match_operand:SI 1 "register_operand" "0,0")
          (match_operand:SI 2 "nonmemory_operand" "rI,J")]))
          (match_operand:SI 2 "nonmemory_operand" "rI,J")]))
   (set (match_operand:SI 0 "register_operand" "=r,r")
   (set (match_operand:SI 0 "register_operand" "=r,r")
        (plus:SI (match_dup 1) (match_dup 2)))]
        (plus:SI (match_dup 1) (match_dup 2)))]
  ""
  ""
  "ld.a%V4 %3,[%0,%2]"
  "ld.a%V4 %3,[%0,%2]"
  [(set_attr "type" "load,load")
  [(set_attr "type" "load,load")
   (set_attr "length" "1,2")])
   (set_attr "length" "1,2")])
(define_insn "*storesi_update"
(define_insn "*storesi_update"
  [(set (match_operator:SI 4 "store_update_operand"
  [(set (match_operator:SI 4 "store_update_operand"
         [(match_operand:SI 1 "register_operand" "0")
         [(match_operand:SI 1 "register_operand" "0")
          (match_operand:SI 2 "short_immediate_operand" "I")])
          (match_operand:SI 2 "short_immediate_operand" "I")])
        (match_operand:SI 3 "register_operand" "r"))
        (match_operand:SI 3 "register_operand" "r"))
   (set (match_operand:SI 0 "register_operand" "=r")
   (set (match_operand:SI 0 "register_operand" "=r")
        (plus:SI (match_dup 1) (match_dup 2)))]
        (plus:SI (match_dup 1) (match_dup 2)))]
  ""
  ""
  "st.a%V4 %3,[%0,%2]"
  "st.a%V4 %3,[%0,%2]"
  [(set_attr "type" "store")
  [(set_attr "type" "store")
   (set_attr "length" "1")])
   (set_attr "length" "1")])
(define_insn "*loadsf_update"
(define_insn "*loadsf_update"
  [(set (match_operand:SF 3 "register_operand" "=r,r")
  [(set (match_operand:SF 3 "register_operand" "=r,r")
        (match_operator:SF 4 "load_update_operand"
        (match_operator:SF 4 "load_update_operand"
         [(match_operand:SI 1 "register_operand" "0,0")
         [(match_operand:SI 1 "register_operand" "0,0")
          (match_operand:SI 2 "nonmemory_operand" "rI,J")]))
          (match_operand:SI 2 "nonmemory_operand" "rI,J")]))
   (set (match_operand:SI 0 "register_operand" "=r,r")
   (set (match_operand:SI 0 "register_operand" "=r,r")
        (plus:SI (match_dup 1) (match_dup 2)))]
        (plus:SI (match_dup 1) (match_dup 2)))]
  ""
  ""
  "ld.a%V4 %3,[%0,%2]"
  "ld.a%V4 %3,[%0,%2]"
  [(set_attr "type" "load,load")
  [(set_attr "type" "load,load")
   (set_attr "length" "1,2")])
   (set_attr "length" "1,2")])
(define_insn "*storesf_update"
(define_insn "*storesf_update"
  [(set (match_operator:SF 4 "store_update_operand"
  [(set (match_operator:SF 4 "store_update_operand"
         [(match_operand:SI 1 "register_operand" "0")
         [(match_operand:SI 1 "register_operand" "0")
          (match_operand:SI 2 "short_immediate_operand" "I")])
          (match_operand:SI 2 "short_immediate_operand" "I")])
        (match_operand:SF 3 "register_operand" "r"))
        (match_operand:SF 3 "register_operand" "r"))
   (set (match_operand:SI 0 "register_operand" "=r")
   (set (match_operand:SI 0 "register_operand" "=r")
        (plus:SI (match_dup 1) (match_dup 2)))]
        (plus:SI (match_dup 1) (match_dup 2)))]
  ""
  ""
  "st.a%V4 %3,[%0,%2]"
  "st.a%V4 %3,[%0,%2]"
  [(set_attr "type" "store")
  [(set_attr "type" "store")
   (set_attr "length" "1")])
   (set_attr "length" "1")])


;; Conditional move instructions.
;; Conditional move instructions.
(define_expand "movsicc"
(define_expand "movsicc"
  [(set (match_operand:SI 0 "register_operand" "")
  [(set (match_operand:SI 0 "register_operand" "")
        (if_then_else:SI (match_operand 1 "comparison_operator" "")
        (if_then_else:SI (match_operand 1 "comparison_operator" "")
                         (match_operand:SI 2 "nonmemory_operand" "")
                         (match_operand:SI 2 "nonmemory_operand" "")
                         (match_operand:SI 3 "register_operand" "")))]
                         (match_operand:SI 3 "register_operand" "")))]
  ""
  ""
  "
  "
{
{
  enum rtx_code code = GET_CODE (operands[1]);
  enum rtx_code code = GET_CODE (operands[1]);
  rtx ccreg
  rtx ccreg
    = gen_rtx_REG (SELECT_CC_MODE (code, arc_compare_op0, arc_compare_op1),
    = gen_rtx_REG (SELECT_CC_MODE (code, arc_compare_op0, arc_compare_op1),
                   61);
                   61);
  operands[1] = gen_rtx_fmt_ee (code, VOIDmode, ccreg, const0_rtx);
  operands[1] = gen_rtx_fmt_ee (code, VOIDmode, ccreg, const0_rtx);
}")
}")
;(define_expand "movdicc"
;(define_expand "movdicc"
;  [(set (match_operand:DI 0 "register_operand" "")
;  [(set (match_operand:DI 0 "register_operand" "")
;       (if_then_else:DI (match_operand 1 "comparison_operator" "")
;       (if_then_else:DI (match_operand 1 "comparison_operator" "")
;                        (match_operand:DI 2 "nonmemory_operand" "")
;                        (match_operand:DI 2 "nonmemory_operand" "")
;                        (match_operand:DI 3 "register_operand" "")))]
;                        (match_operand:DI 3 "register_operand" "")))]
;  "0 /* ??? this would work better if we had cmpdi */"
;  "0 /* ??? this would work better if we had cmpdi */"
;  "
;  "
;{
;{
;  enum rtx_code code = GET_CODE (operands[1]);
;  enum rtx_code code = GET_CODE (operands[1]);
;  rtx ccreg
;  rtx ccreg
;   = gen_rtx_REG (SELECT_CC_MODE (code, arc_compare_op0, arc_compare_op1),
;   = gen_rtx_REG (SELECT_CC_MODE (code, arc_compare_op0, arc_compare_op1),
;                  61);
;                  61);
;
;
;  operands[1] = gen_rtx_fmt_ee (code, VOIDmode, ccreg, const0_rtx);
;  operands[1] = gen_rtx_fmt_ee (code, VOIDmode, ccreg, const0_rtx);
;}")
;}")
(define_expand "movsfcc"
(define_expand "movsfcc"
  [(set (match_operand:SF 0 "register_operand" "")
  [(set (match_operand:SF 0 "register_operand" "")
        (if_then_else:SF (match_operand 1 "comparison_operator" "")
        (if_then_else:SF (match_operand 1 "comparison_operator" "")
                         (match_operand:SF 2 "nonmemory_operand" "")
                         (match_operand:SF 2 "nonmemory_operand" "")
                         (match_operand:SF 3 "register_operand" "")))]
                         (match_operand:SF 3 "register_operand" "")))]
  ""
  ""
  "
  "
{
{
  enum rtx_code code = GET_CODE (operands[1]);
  enum rtx_code code = GET_CODE (operands[1]);
  rtx ccreg
  rtx ccreg
    = gen_rtx_REG (SELECT_CC_MODE (code, arc_compare_op0, arc_compare_op1),
    = gen_rtx_REG (SELECT_CC_MODE (code, arc_compare_op0, arc_compare_op1),
                   61);
                   61);
  operands[1] = gen_rtx_fmt_ee (code, VOIDmode, ccreg, const0_rtx);
  operands[1] = gen_rtx_fmt_ee (code, VOIDmode, ccreg, const0_rtx);
}")
}")
;(define_expand "movdfcc"
;(define_expand "movdfcc"
;  [(set (match_operand:DF 0 "register_operand" "")
;  [(set (match_operand:DF 0 "register_operand" "")
;       (if_then_else:DF (match_operand 1 "comparison_operator" "")
;       (if_then_else:DF (match_operand 1 "comparison_operator" "")
;                        (match_operand:DF 2 "nonmemory_operand" "")
;                        (match_operand:DF 2 "nonmemory_operand" "")
;                        (match_operand:DF 3 "register_operand" "")))]
;                        (match_operand:DF 3 "register_operand" "")))]
;  "0 /* ??? can generate less efficient code if constants involved */"
;  "0 /* ??? can generate less efficient code if constants involved */"
;  "
;  "
;{
;{
; enum rtx_code code = GET_CODE (operands[1]);
; enum rtx_code code = GET_CODE (operands[1]);
; rtx ccreg
; rtx ccreg
;   = gen_rtx_REG (SELECT_CC_MODE (code, arc_compare_op0, arc_compare_op1),
;   = gen_rtx_REG (SELECT_CC_MODE (code, arc_compare_op0, arc_compare_op1),
;                  61);
;                  61);
;
;
;  operands[1] = gen_rtx_fmt_ee (code, VOIDmode, ccreg, const0_rtx);
;  operands[1] = gen_rtx_fmt_ee (code, VOIDmode, ccreg, const0_rtx);
;}")
;}")
(define_insn "*movsicc_insn"
(define_insn "*movsicc_insn"
  [(set (match_operand:SI 0 "register_operand" "=r")
  [(set (match_operand:SI 0 "register_operand" "=r")
        (if_then_else:SI (match_operand 1 "comparison_operator" "")
        (if_then_else:SI (match_operand 1 "comparison_operator" "")
                         (match_operand:SI 2 "nonmemory_operand" "rJi")
                         (match_operand:SI 2 "nonmemory_operand" "rJi")
                         (match_operand:SI 3 "register_operand" "0")))]
                         (match_operand:SI 3 "register_operand" "0")))]
  ""
  ""
  "mov.%d1 %0,%S2"
  "mov.%d1 %0,%S2"
  [(set_attr "type" "cmove")])
  [(set_attr "type" "cmove")])
; ??? This doesn't properly handle constants.
; ??? This doesn't properly handle constants.
;(define_insn "*movdicc_insn"
;(define_insn "*movdicc_insn"
;  [(set (match_operand:DI 0 "register_operand" "=r,r")
;  [(set (match_operand:DI 0 "register_operand" "=r,r")
;       (if_then_else:DI (match_operand 1 "comparison_operator" "")
;       (if_then_else:DI (match_operand 1 "comparison_operator" "")
;                        (match_operand:DI 2 "nonmemory_operand" "r,Ji")
;                        (match_operand:DI 2 "nonmemory_operand" "r,Ji")
;                        (match_operand:DI 3 "register_operand" "0,0")))]
;                        (match_operand:DI 3 "register_operand" "0,0")))]
;  "0"
;  "0"
;  "*
;  "*
;{
;{
;  switch (which_alternative)
;  switch (which_alternative)
;    {
;    {
;    case 0 :
;    case 0 :
;      /* We normally copy the low-numbered register first.  However, if
;      /* We normally copy the low-numbered register first.  However, if
;        the first register operand 0 is the same as the second register of
;        the first register operand 0 is the same as the second register of
;        operand 1, we must copy in the opposite order.  */
;        operand 1, we must copy in the opposite order.  */
;      if (REGNO (operands[0]) == REGNO (operands[2]) + 1)
;      if (REGNO (operands[0]) == REGNO (operands[2]) + 1)
;       return \"mov.%d1 %R0,%R2\;mov.%d1 %0,%2\";
;       return \"mov.%d1 %R0,%R2\;mov.%d1 %0,%2\";
;      else
;      else
;       return \"mov.%d1 %0,%2\;mov.%d1 %R0,%R2\";
;       return \"mov.%d1 %0,%2\;mov.%d1 %R0,%R2\";
;    case 1 :
;    case 1 :
;      return \"mov.%d1 %0,%2\;mov.%d1 %R0,%R2\";
;      return \"mov.%d1 %0,%2\;mov.%d1 %R0,%R2\";
;    }
;    }
;}"
;}"
;  [(set_attr "type" "cmove,cmove")
;  [(set_attr "type" "cmove,cmove")
;   (set_attr "length" "2,4")])
;   (set_attr "length" "2,4")])
(define_insn "*movsfcc_insn"
(define_insn "*movsfcc_insn"
  [(set (match_operand:SF 0 "register_operand" "=r,r")
  [(set (match_operand:SF 0 "register_operand" "=r,r")
        (if_then_else:SF (match_operand 1 "comparison_operator" "")
        (if_then_else:SF (match_operand 1 "comparison_operator" "")
                         (match_operand:SF 2 "nonmemory_operand" "r,E")
                         (match_operand:SF 2 "nonmemory_operand" "r,E")
                         (match_operand:SF 3 "register_operand" "0,0")))]
                         (match_operand:SF 3 "register_operand" "0,0")))]
  ""
  ""
  "@
  "@
   mov.%d1 %0,%2
   mov.%d1 %0,%2
   mov.%d1 %0,%2 ; %A2"
   mov.%d1 %0,%2 ; %A2"
  [(set_attr "type" "cmove,cmove")])
  [(set_attr "type" "cmove,cmove")])
;(define_insn "*movdfcc_insn"
;(define_insn "*movdfcc_insn"
;  [(set (match_operand:DF 0 "register_operand" "=r,r")
;  [(set (match_operand:DF 0 "register_operand" "=r,r")
;       (if_then_else:DF (match_operand 1 "comparison_operator" "")
;       (if_then_else:DF (match_operand 1 "comparison_operator" "")
;                        (match_operand:DF 2 "nonmemory_operand" "r,E")
;                        (match_operand:DF 2 "nonmemory_operand" "r,E")
;                        (match_operand:DF 3 "register_operand" "0,0")))]
;                        (match_operand:DF 3 "register_operand" "0,0")))]
;  "0"
;  "0"
;  "*
;  "*
;{
;{
;  switch (which_alternative)
;  switch (which_alternative)
;    {
;    {
;    case 0 :
;    case 0 :
;      /* We normally copy the low-numbered register first.  However, if
;      /* We normally copy the low-numbered register first.  However, if
;        the first register operand 0 is the same as the second register of
;        the first register operand 0 is the same as the second register of
;        operand 1, we must copy in the opposite order.  */
;        operand 1, we must copy in the opposite order.  */
;      if (REGNO (operands[0]) == REGNO (operands[2]) + 1)
;      if (REGNO (operands[0]) == REGNO (operands[2]) + 1)
;       return \"mov.%d1 %R0,%R2\;mov.%d1 %0,%2\";
;       return \"mov.%d1 %R0,%R2\;mov.%d1 %0,%2\";
;      else
;      else
;       return \"mov.%d1 %0,%2\;mov.%d1 %R0,%R2\";
;       return \"mov.%d1 %0,%2\;mov.%d1 %R0,%R2\";
;    case 1 :
;    case 1 :
;      return \"mov.%d1 %0,%L2\;mov.%d1 %R0,%H2 ; %A2\";
;      return \"mov.%d1 %0,%L2\;mov.%d1 %R0,%H2 ; %A2\";
;    }
;    }
;}"
;}"
;  [(set_attr "type" "cmove,cmove")
;  [(set_attr "type" "cmove,cmove")
;   (set_attr "length" "2,4")])
;   (set_attr "length" "2,4")])


;; Zero extension instructions.
;; Zero extension instructions.
;; ??? We don't support volatile memrefs here, but I'm not sure why.
;; ??? We don't support volatile memrefs here, but I'm not sure why.
(define_insn "zero_extendqihi2"
(define_insn "zero_extendqihi2"
  [(set (match_operand:HI 0 "register_operand" "=r,r")
  [(set (match_operand:HI 0 "register_operand" "=r,r")
        (zero_extend:HI (match_operand:QI 1 "nonvol_nonimm_operand" "r,m")))]
        (zero_extend:HI (match_operand:QI 1 "nonvol_nonimm_operand" "r,m")))]
  ""
  ""
  "@
  "@
   extb%? %0,%1
   extb%? %0,%1
   ldb%U1 %0,%1"
   ldb%U1 %0,%1"
  [(set_attr "type" "unary,load")])
  [(set_attr "type" "unary,load")])
(define_insn "*zero_extendqihi2_set_cc_insn"
(define_insn "*zero_extendqihi2_set_cc_insn"
  [(set (reg:CCZN 61) (compare:CCZN
  [(set (reg:CCZN 61) (compare:CCZN
                       (zero_extend:SI (match_operand:QI 1 "register_operand" "r"))
                       (zero_extend:SI (match_operand:QI 1 "register_operand" "r"))
                       (const_int 0)))
                       (const_int 0)))
   (set (match_operand:HI 0 "register_operand" "=r")
   (set (match_operand:HI 0 "register_operand" "=r")
        (zero_extend:HI (match_dup 1)))]
        (zero_extend:HI (match_dup 1)))]
  ""
  ""
  "extb%?.f %0,%1"
  "extb%?.f %0,%1"
  [(set_attr "type" "unary")
  [(set_attr "type" "unary")
   (set_attr "cond" "set_zn")])
   (set_attr "cond" "set_zn")])
(define_insn "zero_extendqisi2"
(define_insn "zero_extendqisi2"
  [(set (match_operand:SI 0 "register_operand" "=r,r")
  [(set (match_operand:SI 0 "register_operand" "=r,r")
        (zero_extend:SI (match_operand:QI 1 "nonvol_nonimm_operand" "r,m")))]
        (zero_extend:SI (match_operand:QI 1 "nonvol_nonimm_operand" "r,m")))]
  ""
  ""
  "@
  "@
   extb%? %0,%1
   extb%? %0,%1
   ldb%U1 %0,%1"
   ldb%U1 %0,%1"
  [(set_attr "type" "unary,load")])
  [(set_attr "type" "unary,load")])
(define_insn "*zero_extendqisi2_set_cc_insn"
(define_insn "*zero_extendqisi2_set_cc_insn"
  [(set (reg:CCZN 61) (compare:CCZN
  [(set (reg:CCZN 61) (compare:CCZN
                       (zero_extend:SI (match_operand:QI 1 "register_operand" "r"))
                       (zero_extend:SI (match_operand:QI 1 "register_operand" "r"))
                       (const_int 0)))
                       (const_int 0)))
   (set (match_operand:SI 0 "register_operand" "=r")
   (set (match_operand:SI 0 "register_operand" "=r")
        (zero_extend:SI (match_dup 1)))]
        (zero_extend:SI (match_dup 1)))]
  ""
  ""
  "extb%?.f %0,%1"
  "extb%?.f %0,%1"
  [(set_attr "type" "unary")
  [(set_attr "type" "unary")
   (set_attr "cond" "set_zn")])
   (set_attr "cond" "set_zn")])
(define_insn "zero_extendhisi2"
(define_insn "zero_extendhisi2"
  [(set (match_operand:SI 0 "register_operand" "=r,r")
  [(set (match_operand:SI 0 "register_operand" "=r,r")
        (zero_extend:SI (match_operand:HI 1 "nonvol_nonimm_operand" "r,m")))]
        (zero_extend:SI (match_operand:HI 1 "nonvol_nonimm_operand" "r,m")))]
  ""
  ""
  "@
  "@
   extw%? %0,%1
   extw%? %0,%1
   ldw%U1 %0,%1"
   ldw%U1 %0,%1"
  [(set_attr "type" "unary,load")])
  [(set_attr "type" "unary,load")])
(define_insn "*zero_extendhisi2_set_cc_insn"
(define_insn "*zero_extendhisi2_set_cc_insn"
  [(set (reg:CCZN 61) (compare:CCZN
  [(set (reg:CCZN 61) (compare:CCZN
                       (zero_extend:SI (match_operand:HI 1 "register_operand" "r"))
                       (zero_extend:SI (match_operand:HI 1 "register_operand" "r"))
                       (const_int 0)))
                       (const_int 0)))
   (set (match_operand:SI 0 "register_operand" "=r")
   (set (match_operand:SI 0 "register_operand" "=r")
        (zero_extend:SI (match_dup 1)))]
        (zero_extend:SI (match_dup 1)))]
  ""
  ""
  "extw%?.f %0,%1"
  "extw%?.f %0,%1"
  [(set_attr "type" "unary")
  [(set_attr "type" "unary")
   (set_attr "cond" "set_zn")])
   (set_attr "cond" "set_zn")])


;; Sign extension instructions.
;; Sign extension instructions.
(define_insn "extendqihi2"
(define_insn "extendqihi2"
  [(set (match_operand:HI 0 "register_operand" "=r,r")
  [(set (match_operand:HI 0 "register_operand" "=r,r")
        (sign_extend:HI (match_operand:QI 1 "nonvol_nonimm_operand" "r,m")))]
        (sign_extend:HI (match_operand:QI 1 "nonvol_nonimm_operand" "r,m")))]
  ""
  ""
  "@
  "@
   sexb%? %0,%1
   sexb%? %0,%1
   ldb.x%U1 %0,%1"
   ldb.x%U1 %0,%1"
  [(set_attr "type" "unary,load")])
  [(set_attr "type" "unary,load")])
(define_insn "*extendqihi2_set_cc_insn"
(define_insn "*extendqihi2_set_cc_insn"
  [(set (reg:CCZN 61) (compare:CCZN
  [(set (reg:CCZN 61) (compare:CCZN
                       (sign_extend:SI (match_operand:QI 1 "register_operand" "r"))
                       (sign_extend:SI (match_operand:QI 1 "register_operand" "r"))
                       (const_int 0)))
                       (const_int 0)))
   (set (match_operand:HI 0 "register_operand" "=r")
   (set (match_operand:HI 0 "register_operand" "=r")
        (sign_extend:HI (match_dup 1)))]
        (sign_extend:HI (match_dup 1)))]
  ""
  ""
  "sexb%?.f %0,%1"
  "sexb%?.f %0,%1"
  [(set_attr "type" "unary")
  [(set_attr "type" "unary")
   (set_attr "cond" "set_zn")])
   (set_attr "cond" "set_zn")])
(define_insn "extendqisi2"
(define_insn "extendqisi2"
  [(set (match_operand:SI 0 "register_operand" "=r,r")
  [(set (match_operand:SI 0 "register_operand" "=r,r")
        (sign_extend:SI (match_operand:QI 1 "nonvol_nonimm_operand" "r,m")))]
        (sign_extend:SI (match_operand:QI 1 "nonvol_nonimm_operand" "r,m")))]
  ""
  ""
  "@
  "@
   sexb%? %0,%1
   sexb%? %0,%1
   ldb.x%U1 %0,%1"
   ldb.x%U1 %0,%1"
  [(set_attr "type" "unary,load")])
  [(set_attr "type" "unary,load")])
(define_insn "*extendqisi2_set_cc_insn"
(define_insn "*extendqisi2_set_cc_insn"
  [(set (reg:CCZN 61) (compare:CCZN
  [(set (reg:CCZN 61) (compare:CCZN
                       (sign_extend:SI (match_operand:QI 1 "register_operand" "r"))
                       (sign_extend:SI (match_operand:QI 1 "register_operand" "r"))
                       (const_int 0)))
                       (const_int 0)))
   (set (match_operand:SI 0 "register_operand" "=r")
   (set (match_operand:SI 0 "register_operand" "=r")
        (sign_extend:SI (match_dup 1)))]
        (sign_extend:SI (match_dup 1)))]
  ""
  ""
  "sexb%?.f %0,%1"
  "sexb%?.f %0,%1"
  [(set_attr "type" "unary")
  [(set_attr "type" "unary")
   (set_attr "cond" "set_zn")])
   (set_attr "cond" "set_zn")])
(define_insn "extendhisi2"
(define_insn "extendhisi2"
  [(set (match_operand:SI 0 "register_operand" "=r,r")
  [(set (match_operand:SI 0 "register_operand" "=r,r")
        (sign_extend:SI (match_operand:HI 1 "nonvol_nonimm_operand" "r,m")))]
        (sign_extend:SI (match_operand:HI 1 "nonvol_nonimm_operand" "r,m")))]
  ""
  ""
  "@
  "@
   sexw%? %0,%1
   sexw%? %0,%1
   ldw.x%U1 %0,%1"
   ldw.x%U1 %0,%1"
  [(set_attr "type" "unary,load")])
  [(set_attr "type" "unary,load")])
(define_insn "*extendhisi2_set_cc_insn"
(define_insn "*extendhisi2_set_cc_insn"
  [(set (reg:CCZN 61) (compare:CCZN
  [(set (reg:CCZN 61) (compare:CCZN
                       (sign_extend:SI (match_operand:HI 1 "register_operand" "r"))
                       (sign_extend:SI (match_operand:HI 1 "register_operand" "r"))
                       (const_int 0)))
                       (const_int 0)))
   (set (match_operand:SI 0 "register_operand" "=r")
   (set (match_operand:SI 0 "register_operand" "=r")
        (sign_extend:SI (match_dup 1)))]
        (sign_extend:SI (match_dup 1)))]
  ""
  ""
  "sexw%?.f %0,%1"
  "sexw%?.f %0,%1"
  [(set_attr "type" "unary")
  [(set_attr "type" "unary")
   (set_attr "cond" "set_zn")])
   (set_attr "cond" "set_zn")])


;; Arithmetic instructions.
;; Arithmetic instructions.
(define_insn "addsi3"
(define_insn "addsi3"
  [(set (match_operand:SI 0 "register_operand" "=r")
  [(set (match_operand:SI 0 "register_operand" "=r")
        (plus:SI (match_operand:SI 1 "register_operand" "%r")
        (plus:SI (match_operand:SI 1 "register_operand" "%r")
                 (match_operand:SI 2 "nonmemory_operand" "rIJ")))]
                 (match_operand:SI 2 "nonmemory_operand" "rIJ")))]
  ""
  ""
  "add%? %0,%1,%2")
  "add%? %0,%1,%2")
(define_insn "*addsi3_set_cc_insn"
(define_insn "*addsi3_set_cc_insn"
  [(set (reg:CC 61) (compare:CC
  [(set (reg:CC 61) (compare:CC
                     (plus:SI (match_operand:SI 1 "register_operand" "%r")
                     (plus:SI (match_operand:SI 1 "register_operand" "%r")
                              (match_operand:SI 2 "nonmemory_operand" "rIJ"))
                              (match_operand:SI 2 "nonmemory_operand" "rIJ"))
                     (const_int 0)))
                     (const_int 0)))
   (set (match_operand:SI 0 "register_operand" "=r")
   (set (match_operand:SI 0 "register_operand" "=r")
        (plus:SI (match_dup 1)
        (plus:SI (match_dup 1)
                 (match_dup 2)))]
                 (match_dup 2)))]
  ""
  ""
  "add%?.f %0,%1,%2"
  "add%?.f %0,%1,%2"
  [(set_attr "cond" "set")])
  [(set_attr "cond" "set")])
(define_insn "adddi3"
(define_insn "adddi3"
  [(set (match_operand:DI 0 "register_operand" "=r")
  [(set (match_operand:DI 0 "register_operand" "=r")
        (plus:DI (match_operand:DI 1 "nonmemory_operand" "%r")
        (plus:DI (match_operand:DI 1 "nonmemory_operand" "%r")
                 (match_operand:DI 2 "nonmemory_operand" "ri")))
                 (match_operand:DI 2 "nonmemory_operand" "ri")))
   (clobber (reg:CC 61))]
   (clobber (reg:CC 61))]
  ""
  ""
  "*
  "*
{
{
  rtx op2 = operands[2];
  rtx op2 = operands[2];
  if (GET_CODE (op2) == CONST_INT)
  if (GET_CODE (op2) == CONST_INT)
    {
    {
      int sign = INTVAL (op2);
      int sign = INTVAL (op2);
      if (sign < 0)
      if (sign < 0)
        return \"add.f %L0,%L1,%2\;adc %H0,%H1,-1\";
        return \"add.f %L0,%L1,%2\;adc %H0,%H1,-1\";
      else
      else
        return \"add.f %L0,%L1,%2\;adc %H0,%H1,0\";
        return \"add.f %L0,%L1,%2\;adc %H0,%H1,0\";
    }
    }
  else
  else
    return \"add.f %L0,%L1,%L2\;adc %H0,%H1,%H2\";
    return \"add.f %L0,%L1,%L2\;adc %H0,%H1,%H2\";
}"
}"
  [(set_attr "length" "2")])
  [(set_attr "length" "2")])
(define_insn "subsi3"
(define_insn "subsi3"
  [(set (match_operand:SI 0 "register_operand" "=r")
  [(set (match_operand:SI 0 "register_operand" "=r")
        (minus:SI (match_operand:SI 1 "register_operand" "r")
        (minus:SI (match_operand:SI 1 "register_operand" "r")
                  (match_operand:SI 2 "nonmemory_operand" "rIJ")))]
                  (match_operand:SI 2 "nonmemory_operand" "rIJ")))]
  ""
  ""
  "sub%? %0,%1,%2")
  "sub%? %0,%1,%2")
(define_insn "*subsi3_set_cc_insn"
(define_insn "*subsi3_set_cc_insn"
  [(set (reg:CC 61) (compare:CC
  [(set (reg:CC 61) (compare:CC
                     (minus:SI (match_operand:SI 1 "register_operand" "%r")
                     (minus:SI (match_operand:SI 1 "register_operand" "%r")
                               (match_operand:SI 2 "nonmemory_operand" "rIJ"))
                               (match_operand:SI 2 "nonmemory_operand" "rIJ"))
                     (const_int 0)))
                     (const_int 0)))
   (set (match_operand:SI 0 "register_operand" "=r")
   (set (match_operand:SI 0 "register_operand" "=r")
        (minus:SI (match_dup 1)
        (minus:SI (match_dup 1)
                  (match_dup 2)))]
                  (match_dup 2)))]
  ""
  ""
  "sub%?.f %0,%1,%2"
  "sub%?.f %0,%1,%2"
  [(set_attr "cond" "set")])
  [(set_attr "cond" "set")])
(define_insn "subdi3"
(define_insn "subdi3"
  [(set (match_operand:DI 0 "register_operand" "=r")
  [(set (match_operand:DI 0 "register_operand" "=r")
        (minus:DI (match_operand:DI 1 "nonmemory_operand" "r")
        (minus:DI (match_operand:DI 1 "nonmemory_operand" "r")
                  (match_operand:DI 2 "nonmemory_operand" "ri")))
                  (match_operand:DI 2 "nonmemory_operand" "ri")))
   (clobber (reg:CC 61))]
   (clobber (reg:CC 61))]
  ""
  ""
  "*
  "*
{
{
  rtx op2 = operands[2];
  rtx op2 = operands[2];
  if (GET_CODE (op2) == CONST_INT)
  if (GET_CODE (op2) == CONST_INT)
    {
    {
      int sign = INTVAL (op2);
      int sign = INTVAL (op2);
      if (sign < 0)
      if (sign < 0)
        return \"sub.f %L0,%L1,%2\;sbc %H0,%H1,-1\";
        return \"sub.f %L0,%L1,%2\;sbc %H0,%H1,-1\";
      else
      else
        return \"sub.f %L0,%L1,%2\;sbc %H0,%H1,0\";
        return \"sub.f %L0,%L1,%2\;sbc %H0,%H1,0\";
    }
    }
  else
  else
    return \"sub.f %L0,%L1,%L2\;sbc %H0,%H1,%H2\";
    return \"sub.f %L0,%L1,%L2\;sbc %H0,%H1,%H2\";
}"
}"
  [(set_attr "length" "2")])
  [(set_attr "length" "2")])


;; Boolean instructions.
;; Boolean instructions.
;;
;;
;; We don't define the DImode versions as expand_binop does a good enough job.
;; We don't define the DImode versions as expand_binop does a good enough job.
(define_insn "andsi3"
(define_insn "andsi3"
  [(set (match_operand:SI 0 "register_operand" "=r")
  [(set (match_operand:SI 0 "register_operand" "=r")
        (and:SI (match_operand:SI 1 "register_operand" "%r")
        (and:SI (match_operand:SI 1 "register_operand" "%r")
                (match_operand:SI 2 "nonmemory_operand" "rIJ")))]
                (match_operand:SI 2 "nonmemory_operand" "rIJ")))]
  ""
  ""
  "and%? %0,%1,%2")
  "and%? %0,%1,%2")
(define_insn "*andsi3_set_cc_insn"
(define_insn "*andsi3_set_cc_insn"
  [(set (reg:CCZN 61) (compare:CCZN
  [(set (reg:CCZN 61) (compare:CCZN
                       (and:SI (match_operand:SI 1 "register_operand" "%r")
                       (and:SI (match_operand:SI 1 "register_operand" "%r")
                               (match_operand:SI 2 "nonmemory_operand" "rIJ"))
                               (match_operand:SI 2 "nonmemory_operand" "rIJ"))
                       (const_int 0)))
                       (const_int 0)))
   (set (match_operand:SI 0 "register_operand" "=r")
   (set (match_operand:SI 0 "register_operand" "=r")
        (and:SI (match_dup 1)
        (and:SI (match_dup 1)
                (match_dup 2)))]
                (match_dup 2)))]
  ""
  ""
  "and%?.f %0,%1,%2"
  "and%?.f %0,%1,%2"
  [(set_attr "cond" "set_zn")])
  [(set_attr "cond" "set_zn")])
(define_insn "*bicsi3_insn"
(define_insn "*bicsi3_insn"
  [(set (match_operand:SI 0 "register_operand" "=r,r,r,r")
  [(set (match_operand:SI 0 "register_operand" "=r,r,r,r")
        (and:SI (match_operand:SI 1 "nonmemory_operand" "r,r,I,J")
        (and:SI (match_operand:SI 1 "nonmemory_operand" "r,r,I,J")
                (not:SI (match_operand:SI 2 "nonmemory_operand" "rI,J,r,r"))))]
                (not:SI (match_operand:SI 2 "nonmemory_operand" "rI,J,r,r"))))]
  ""
  ""
  "bic%? %0,%1,%2"
  "bic%? %0,%1,%2"
  [(set_attr "length" "1,2,1,2")])
  [(set_attr "length" "1,2,1,2")])
(define_insn "*bicsi3_set_cc_insn"
(define_insn "*bicsi3_set_cc_insn"
  [(set (reg:CCZN 61) (compare:CCZN
  [(set (reg:CCZN 61) (compare:CCZN
                       (and:SI (match_operand:SI 1 "register_operand" "%r")
                       (and:SI (match_operand:SI 1 "register_operand" "%r")
                               (not:SI (match_operand:SI 2 "nonmemory_operand" "rIJ")))
                               (not:SI (match_operand:SI 2 "nonmemory_operand" "rIJ")))
                       (const_int 0)))
                       (const_int 0)))
   (set (match_operand:SI 0 "register_operand" "=r")
   (set (match_operand:SI 0 "register_operand" "=r")
        (and:SI (match_dup 1)
        (and:SI (match_dup 1)
                (not:SI (match_dup 2))))]
                (not:SI (match_dup 2))))]
  ""
  ""
  "bic%?.f %0,%1,%2"
  "bic%?.f %0,%1,%2"
  [(set_attr "cond" "set_zn")])
  [(set_attr "cond" "set_zn")])
(define_insn "iorsi3"
(define_insn "iorsi3"
  [(set (match_operand:SI 0 "register_operand" "=r")
  [(set (match_operand:SI 0 "register_operand" "=r")
        (ior:SI (match_operand:SI 1 "register_operand" "%r")
        (ior:SI (match_operand:SI 1 "register_operand" "%r")
                (match_operand:SI 2 "nonmemory_operand" "rIJ")))]
                (match_operand:SI 2 "nonmemory_operand" "rIJ")))]
  ""
  ""
  "or%? %0,%1,%2")
  "or%? %0,%1,%2")
(define_insn "*iorsi3_set_cc_insn"
(define_insn "*iorsi3_set_cc_insn"
  [(set (reg:CCZN 61) (compare:CCZN
  [(set (reg:CCZN 61) (compare:CCZN
                       (ior:SI (match_operand:SI 1 "register_operand" "%r")
                       (ior:SI (match_operand:SI 1 "register_operand" "%r")
                               (match_operand:SI 2 "nonmemory_operand" "rIJ"))
                               (match_operand:SI 2 "nonmemory_operand" "rIJ"))
                       (const_int 0)))
                       (const_int 0)))
   (set (match_operand:SI 0 "register_operand" "=r")
   (set (match_operand:SI 0 "register_operand" "=r")
        (ior:SI (match_dup 1)
        (ior:SI (match_dup 1)
                (match_dup 2)))]
                (match_dup 2)))]
  ""
  ""
  "or%?.f %0,%1,%2"
  "or%?.f %0,%1,%2"
  [(set_attr "cond" "set_zn")])
  [(set_attr "cond" "set_zn")])
(define_insn "xorsi3"
(define_insn "xorsi3"
  [(set (match_operand:SI 0 "register_operand" "=r")
  [(set (match_operand:SI 0 "register_operand" "=r")
        (xor:SI (match_operand:SI 1 "register_operand" "%r")
        (xor:SI (match_operand:SI 1 "register_operand" "%r")
                (match_operand:SI 2 "nonmemory_operand" "rIJ")))]
                (match_operand:SI 2 "nonmemory_operand" "rIJ")))]
  ""
  ""
  "xor%? %0,%1,%2")
  "xor%? %0,%1,%2")
(define_insn "*xorsi3_set_cc_insn"
(define_insn "*xorsi3_set_cc_insn"
  [(set (reg:CCZN 61) (compare:CCZN
  [(set (reg:CCZN 61) (compare:CCZN
                       (xor:SI (match_operand:SI 1 "register_operand" "%r")
                       (xor:SI (match_operand:SI 1 "register_operand" "%r")
                               (match_operand:SI 2 "nonmemory_operand" "rIJ"))
                               (match_operand:SI 2 "nonmemory_operand" "rIJ"))
                       (const_int 0)))
                       (const_int 0)))
   (set (match_operand:SI 0 "register_operand" "=r")
   (set (match_operand:SI 0 "register_operand" "=r")
        (xor:SI (match_dup 1)
        (xor:SI (match_dup 1)
                (match_dup 2)))]
                (match_dup 2)))]
  ""
  ""
  "xor%?.f %0,%1,%2"
  "xor%?.f %0,%1,%2"
  [(set_attr "cond" "set_zn")])
  [(set_attr "cond" "set_zn")])
(define_insn "negsi2"
(define_insn "negsi2"
  [(set (match_operand:SI 0 "register_operand" "=r")
  [(set (match_operand:SI 0 "register_operand" "=r")
        (neg:SI (match_operand:SI 1 "register_operand" "r")))]
        (neg:SI (match_operand:SI 1 "register_operand" "r")))]
  ""
  ""
  "sub%? %0,0,%1"
  "sub%? %0,0,%1"
  [(set_attr "type" "unary")])
  [(set_attr "type" "unary")])
(define_insn "*negsi2_set_cc_insn"
(define_insn "*negsi2_set_cc_insn"
  [(set (reg:CC 61) (compare:CC
  [(set (reg:CC 61) (compare:CC
                     (neg:SI (match_operand:SI 1 "register_operand" "r"))
                     (neg:SI (match_operand:SI 1 "register_operand" "r"))
                     (const_int 0)))
                     (const_int 0)))
   (set (match_operand:SI 0 "register_operand" "=r")
   (set (match_operand:SI 0 "register_operand" "=r")
        (neg:SI (match_dup 1)))]
        (neg:SI (match_dup 1)))]
  ""
  ""
  "sub%?.f %0,0,%1"
  "sub%?.f %0,0,%1"
  [(set_attr "type" "unary")
  [(set_attr "type" "unary")
   (set_attr "cond" "set")])
   (set_attr "cond" "set")])
(define_insn "negdi2"
(define_insn "negdi2"
  [(set (match_operand:DI 0 "register_operand" "=r")
  [(set (match_operand:DI 0 "register_operand" "=r")
        (neg:DI (match_operand:DI 1 "register_operand" "r")))
        (neg:DI (match_operand:DI 1 "register_operand" "r")))
   (clobber (reg:SI 61))]
   (clobber (reg:SI 61))]
  ""
  ""
  "sub.f %L0,0,%L1\;sbc %H0,0,%H1"
  "sub.f %L0,0,%L1\;sbc %H0,0,%H1"
  [(set_attr "type" "unary")
  [(set_attr "type" "unary")
   (set_attr "length" "2")])
   (set_attr "length" "2")])
(define_insn "one_cmplsi2"
(define_insn "one_cmplsi2"
  [(set (match_operand:SI 0 "register_operand" "=r")
  [(set (match_operand:SI 0 "register_operand" "=r")
        (not:SI (match_operand:SI 1 "register_operand" "r")))]
        (not:SI (match_operand:SI 1 "register_operand" "r")))]
  ""
  ""
  "xor%? %0,%1,-1"
  "xor%? %0,%1,-1"
  [(set_attr "type" "unary")])
  [(set_attr "type" "unary")])
(define_insn "*one_cmplsi2_set_cc_insn"
(define_insn "*one_cmplsi2_set_cc_insn"
  [(set (reg:CCZN 61) (compare:CCZN
  [(set (reg:CCZN 61) (compare:CCZN
                       (not:SI (match_operand:SI 1 "register_operand" "r"))
                       (not:SI (match_operand:SI 1 "register_operand" "r"))
                       (const_int 0)))
                       (const_int 0)))
   (set (match_operand:SI 0 "register_operand" "=r")
   (set (match_operand:SI 0 "register_operand" "=r")
        (not:SI (match_dup 1)))]
        (not:SI (match_dup 1)))]
  ""
  ""
  "xor%?.f %0,%1,-1"
  "xor%?.f %0,%1,-1"
  [(set_attr "type" "unary")
  [(set_attr "type" "unary")
   (set_attr "cond" "set_zn")])
   (set_attr "cond" "set_zn")])


;; Shift instructions.
;; Shift instructions.
(define_expand "ashlsi3"
(define_expand "ashlsi3"
  [(set (match_operand:SI 0 "register_operand" "")
  [(set (match_operand:SI 0 "register_operand" "")
        (ashift:SI (match_operand:SI 1 "register_operand" "")
        (ashift:SI (match_operand:SI 1 "register_operand" "")
                   (match_operand:SI 2 "nonmemory_operand" "")))]
                   (match_operand:SI 2 "nonmemory_operand" "")))]
  ""
  ""
  "
  "
{
{
  if (! TARGET_SHIFTER)
  if (! TARGET_SHIFTER)
    {
    {
      emit_insn (gen_rtx_PARALLEL
      emit_insn (gen_rtx_PARALLEL
                 (VOIDmode,
                 (VOIDmode,
                  gen_rtvec (2,
                  gen_rtvec (2,
                             gen_rtx_SET (VOIDmode, operands[0],
                             gen_rtx_SET (VOIDmode, operands[0],
                                          gen_rtx_ASHIFT (SImode, operands[1],
                                          gen_rtx_ASHIFT (SImode, operands[1],
                                                          operands[2])),
                                                          operands[2])),
                             gen_rtx_CLOBBER (VOIDmode,
                             gen_rtx_CLOBBER (VOIDmode,
                                              gen_rtx_SCRATCH (SImode)))));
                                              gen_rtx_SCRATCH (SImode)))));
      DONE;
      DONE;
    }
    }
}")
}")
(define_expand "ashrsi3"
(define_expand "ashrsi3"
  [(set (match_operand:SI 0 "register_operand" "")
  [(set (match_operand:SI 0 "register_operand" "")
        (ashiftrt:SI (match_operand:SI 1 "register_operand" "")
        (ashiftrt:SI (match_operand:SI 1 "register_operand" "")
                     (match_operand:SI 2 "nonmemory_operand" "")))]
                     (match_operand:SI 2 "nonmemory_operand" "")))]
  ""
  ""
  "
  "
{
{
  if (! TARGET_SHIFTER)
  if (! TARGET_SHIFTER)
    {
    {
      emit_insn (gen_rtx_PARALLEL
      emit_insn (gen_rtx_PARALLEL
                 (VOIDmode,
                 (VOIDmode,
                  gen_rtvec (2,
                  gen_rtvec (2,
                             gen_rtx_SET (VOIDmode, operands[0],
                             gen_rtx_SET (VOIDmode, operands[0],
                                          gen_rtx_ASHIFTRT (SImode,
                                          gen_rtx_ASHIFTRT (SImode,
                                                            operands[1],
                                                            operands[1],
                                                            operands[2])),
                                                            operands[2])),
                             gen_rtx_CLOBBER (VOIDmode,
                             gen_rtx_CLOBBER (VOIDmode,
                                              gen_rtx_SCRATCH (SImode)))));
                                              gen_rtx_SCRATCH (SImode)))));
      DONE;
      DONE;
    }
    }
}")
}")
(define_expand "lshrsi3"
(define_expand "lshrsi3"
  [(set (match_operand:SI 0 "register_operand" "")
  [(set (match_operand:SI 0 "register_operand" "")
        (lshiftrt:SI (match_operand:SI 1 "register_operand" "")
        (lshiftrt:SI (match_operand:SI 1 "register_operand" "")
                     (match_operand:SI 2 "nonmemory_operand" "")))]
                     (match_operand:SI 2 "nonmemory_operand" "")))]
  ""
  ""
  "
  "
{
{
  if (! TARGET_SHIFTER)
  if (! TARGET_SHIFTER)
    {
    {
      emit_insn (gen_rtx_PARALLEL
      emit_insn (gen_rtx_PARALLEL
                 (VOIDmode,
                 (VOIDmode,
                  gen_rtvec (2,
                  gen_rtvec (2,
                             gen_rtx_SET (VOIDmode, operands[0],
                             gen_rtx_SET (VOIDmode, operands[0],
                                          gen_rtx_LSHIFTRT (SImode,
                                          gen_rtx_LSHIFTRT (SImode,
                                                            operands[1],
                                                            operands[1],
                                                            operands[2])),
                                                            operands[2])),
                             gen_rtx_CLOBBER (VOIDmode,
                             gen_rtx_CLOBBER (VOIDmode,
                                              gen_rtx_SCRATCH (SImode)))));
                                              gen_rtx_SCRATCH (SImode)))));
      DONE;
      DONE;
    }
    }
}")
}")
(define_insn "*ashlsi3_insn"
(define_insn "*ashlsi3_insn"
  [(set (match_operand:SI 0 "register_operand" "=r,r,r,r")
  [(set (match_operand:SI 0 "register_operand" "=r,r,r,r")
        (ashift:SI (match_operand:SI 1 "nonmemory_operand" "r,r,I,J")
        (ashift:SI (match_operand:SI 1 "nonmemory_operand" "r,r,I,J")
                   (match_operand:SI 2 "nonmemory_operand" "rI,J,r,r")))]
                   (match_operand:SI 2 "nonmemory_operand" "rI,J,r,r")))]
  "TARGET_SHIFTER"
  "TARGET_SHIFTER"
  "asl%? %0,%1,%2"
  "asl%? %0,%1,%2"
  [(set_attr "type" "shift")
  [(set_attr "type" "shift")
   (set_attr "length" "1,2,1,2")])
   (set_attr "length" "1,2,1,2")])
(define_insn "*ashrsi3_insn"
(define_insn "*ashrsi3_insn"
  [(set (match_operand:SI 0 "register_operand" "=r,r,r,r")
  [(set (match_operand:SI 0 "register_operand" "=r,r,r,r")
        (ashiftrt:SI (match_operand:SI 1 "nonmemory_operand" "r,r,I,J")
        (ashiftrt:SI (match_operand:SI 1 "nonmemory_operand" "r,r,I,J")
                     (match_operand:SI 2 "nonmemory_operand" "rI,J,r,r")))]
                     (match_operand:SI 2 "nonmemory_operand" "rI,J,r,r")))]
  "TARGET_SHIFTER"
  "TARGET_SHIFTER"
  "asr%? %0,%1,%2"
  "asr%? %0,%1,%2"
  [(set_attr "type" "shift")
  [(set_attr "type" "shift")
   (set_attr "length" "1,2,1,2")])
   (set_attr "length" "1,2,1,2")])
(define_insn "*lshrsi3_insn"
(define_insn "*lshrsi3_insn"
  [(set (match_operand:SI 0 "register_operand" "=r,r,r,r")
  [(set (match_operand:SI 0 "register_operand" "=r,r,r,r")
        (lshiftrt:SI (match_operand:SI 1 "nonmemory_operand" "r,r,I,J")
        (lshiftrt:SI (match_operand:SI 1 "nonmemory_operand" "r,r,I,J")
                     (match_operand:SI 2 "nonmemory_operand" "rI,J,r,r")))]
                     (match_operand:SI 2 "nonmemory_operand" "rI,J,r,r")))]
  "TARGET_SHIFTER"
  "TARGET_SHIFTER"
  "lsr%? %0,%1,%2"
  "lsr%? %0,%1,%2"
  [(set_attr "type" "shift")
  [(set_attr "type" "shift")
   (set_attr "length" "1,2,1,2")])
   (set_attr "length" "1,2,1,2")])
(define_insn "*shift_si3"
(define_insn "*shift_si3"
  [(set (match_operand:SI 0 "register_operand" "=r")
  [(set (match_operand:SI 0 "register_operand" "=r")
        (match_operator:SI 3 "shift_operator"
        (match_operator:SI 3 "shift_operator"
                           [(match_operand:SI 1 "register_operand" "0")
                           [(match_operand:SI 1 "register_operand" "0")
                            (match_operand:SI 2 "nonmemory_operand" "rIJ")]))
                            (match_operand:SI 2 "nonmemory_operand" "rIJ")]))
   (clobber (match_scratch:SI 4 "=&r"))]
   (clobber (match_scratch:SI 4 "=&r"))]
  "! TARGET_SHIFTER"
  "! TARGET_SHIFTER"
  "* return output_shift (operands);"
  "* return output_shift (operands);"
  [(set_attr "type" "shift")
  [(set_attr "type" "shift")
   (set_attr "length" "8")])
   (set_attr "length" "8")])


;; Compare instructions.
;; Compare instructions.
;; This controls RTL generation and register allocation.
;; This controls RTL generation and register allocation.
;; We generate RTL for comparisons and branches by having the cmpxx
;; We generate RTL for comparisons and branches by having the cmpxx
;; patterns store away the operands.  Then, the scc and bcc patterns
;; patterns store away the operands.  Then, the scc and bcc patterns
;; emit RTL for both the compare and the branch.
;; emit RTL for both the compare and the branch.
(define_expand "cmpsi"
(define_expand "cmpsi"
  [(set (reg:CC 61)
  [(set (reg:CC 61)
        (compare:CC (match_operand:SI 0 "register_operand" "")
        (compare:CC (match_operand:SI 0 "register_operand" "")
                    (match_operand:SI 1 "nonmemory_operand" "")))]
                    (match_operand:SI 1 "nonmemory_operand" "")))]
  ""
  ""
  "
  "
{
{
  arc_compare_op0 = operands[0];
  arc_compare_op0 = operands[0];
  arc_compare_op1 = operands[1];
  arc_compare_op1 = operands[1];
  DONE;
  DONE;
}")
}")
;; ??? We may be able to relax this a bit by adding a new constant 'K' for 0.
;; ??? We may be able to relax this a bit by adding a new constant 'K' for 0.
;; This assumes sub.f 0,symbol,0 is a valid insn.
;; This assumes sub.f 0,symbol,0 is a valid insn.
;; Note that "sub.f 0,r0,1" is an 8 byte insn.  To avoid unnecessarily
;; Note that "sub.f 0,r0,1" is an 8 byte insn.  To avoid unnecessarily
;; creating 8 byte insns we duplicate %1 in the destination reg of the insn
;; creating 8 byte insns we duplicate %1 in the destination reg of the insn
;; if it's a small constant.
;; if it's a small constant.
(define_insn "*cmpsi_cc_insn"
(define_insn "*cmpsi_cc_insn"
  [(set (reg:CC 61)
  [(set (reg:CC 61)
        (compare:CC (match_operand:SI 0 "register_operand" "r,r,r")
        (compare:CC (match_operand:SI 0 "register_operand" "r,r,r")
                    (match_operand:SI 1 "nonmemory_operand" "r,I,J")))]
                    (match_operand:SI 1 "nonmemory_operand" "r,I,J")))]
  ""
  ""
  "@
  "@
   sub.f 0,%0,%1
   sub.f 0,%0,%1
   sub.f %1,%0,%1
   sub.f %1,%0,%1
   sub.f 0,%0,%1"
   sub.f 0,%0,%1"
  [(set_attr "type" "compare,compare,compare")])
  [(set_attr "type" "compare,compare,compare")])
(define_insn "*cmpsi_cczn_insn"
(define_insn "*cmpsi_cczn_insn"
  [(set (reg:CCZN 61)
  [(set (reg:CCZN 61)
        (compare:CCZN (match_operand:SI 0 "register_operand" "r,r,r")
        (compare:CCZN (match_operand:SI 0 "register_operand" "r,r,r")
                      (match_operand:SI 1 "nonmemory_operand" "r,I,J")))]
                      (match_operand:SI 1 "nonmemory_operand" "r,I,J")))]
  ""
  ""
  "@
  "@
   sub.f 0,%0,%1
   sub.f 0,%0,%1
   sub.f %1,%0,%1
   sub.f %1,%0,%1
   sub.f 0,%0,%1"
   sub.f 0,%0,%1"
  [(set_attr "type" "compare,compare,compare")])
  [(set_attr "type" "compare,compare,compare")])
(define_insn "*cmpsi_ccznc_insn"
(define_insn "*cmpsi_ccznc_insn"
  [(set (reg:CCZNC 61)
  [(set (reg:CCZNC 61)
        (compare:CCZNC (match_operand:SI 0 "register_operand" "r,r,r")
        (compare:CCZNC (match_operand:SI 0 "register_operand" "r,r,r")
                       (match_operand:SI 1 "nonmemory_operand" "r,I,J")))]
                       (match_operand:SI 1 "nonmemory_operand" "r,I,J")))]
  ""
  ""
  "@
  "@
   sub.f 0,%0,%1
   sub.f 0,%0,%1
   sub.f %1,%0,%1
   sub.f %1,%0,%1
   sub.f 0,%0,%1"
   sub.f 0,%0,%1"
  [(set_attr "type" "compare,compare,compare")])
  [(set_attr "type" "compare,compare,compare")])
;; Next come the scc insns.
;; Next come the scc insns.
(define_expand "seq"
(define_expand "seq"
  [(set (match_operand:SI 0 "register_operand" "=r")
  [(set (match_operand:SI 0 "register_operand" "=r")
        (eq:SI (match_dup 1) (const_int 0)))]
        (eq:SI (match_dup 1) (const_int 0)))]
  ""
  ""
  "
  "
{
{
  operands[1] = gen_compare_reg (EQ, arc_compare_op0, arc_compare_op1);
  operands[1] = gen_compare_reg (EQ, arc_compare_op0, arc_compare_op1);
}")
}")
(define_expand "sne"
(define_expand "sne"
  [(set (match_operand:SI 0 "register_operand" "=r")
  [(set (match_operand:SI 0 "register_operand" "=r")
        (ne:SI (match_dup 1) (const_int 0)))]
        (ne:SI (match_dup 1) (const_int 0)))]
  ""
  ""
  "
  "
{
{
  operands[1] = gen_compare_reg (NE, arc_compare_op0, arc_compare_op1);
  operands[1] = gen_compare_reg (NE, arc_compare_op0, arc_compare_op1);
}")
}")
(define_expand "sgt"
(define_expand "sgt"
  [(set (match_operand:SI 0 "register_operand" "=r")
  [(set (match_operand:SI 0 "register_operand" "=r")
        (gt:SI (match_dup 1) (const_int 0)))]
        (gt:SI (match_dup 1) (const_int 0)))]
  ""
  ""
  "
  "
{
{
  operands[1] = gen_compare_reg (GT, arc_compare_op0, arc_compare_op1);
  operands[1] = gen_compare_reg (GT, arc_compare_op0, arc_compare_op1);
}")
}")
(define_expand "sle"
(define_expand "sle"
  [(set (match_operand:SI 0 "register_operand" "=r")
  [(set (match_operand:SI 0 "register_operand" "=r")
        (le:SI (match_dup 1) (const_int 0)))]
        (le:SI (match_dup 1) (const_int 0)))]
  ""
  ""
  "
  "
{
{
  operands[1] = gen_compare_reg (LE, arc_compare_op0, arc_compare_op1);
  operands[1] = gen_compare_reg (LE, arc_compare_op0, arc_compare_op1);
}")
}")
(define_expand "sge"
(define_expand "sge"
  [(set (match_operand:SI 0 "register_operand" "=r")
  [(set (match_operand:SI 0 "register_operand" "=r")
        (ge:SI (match_dup 1) (const_int 0)))]
        (ge:SI (match_dup 1) (const_int 0)))]
  ""
  ""
  "
  "
{
{
  operands[1] = gen_compare_reg (GE, arc_compare_op0, arc_compare_op1);
  operands[1] = gen_compare_reg (GE, arc_compare_op0, arc_compare_op1);
}")
}")
(define_expand "slt"
(define_expand "slt"
  [(set (match_operand:SI 0 "register_operand" "=r")
  [(set (match_operand:SI 0 "register_operand" "=r")
        (lt:SI (match_dup 1) (const_int 0)))]
        (lt:SI (match_dup 1) (const_int 0)))]
  ""
  ""
  "
  "
{
{
  operands[1] = gen_compare_reg (LT, arc_compare_op0, arc_compare_op1);
  operands[1] = gen_compare_reg (LT, arc_compare_op0, arc_compare_op1);
}")
}")
(define_expand "sgtu"
(define_expand "sgtu"
  [(set (match_operand:SI 0 "register_operand" "=r")
  [(set (match_operand:SI 0 "register_operand" "=r")
        (gtu:SI (match_dup 1) (const_int 0)))]
        (gtu:SI (match_dup 1) (const_int 0)))]
  ""
  ""
  "
  "
{
{
  operands[1] = gen_compare_reg (GTU, arc_compare_op0, arc_compare_op1);
  operands[1] = gen_compare_reg (GTU, arc_compare_op0, arc_compare_op1);
}")
}")
(define_expand "sleu"
(define_expand "sleu"
  [(set (match_operand:SI 0 "register_operand" "=r")
  [(set (match_operand:SI 0 "register_operand" "=r")
        (leu:SI (match_dup 1) (const_int 0)))]
        (leu:SI (match_dup 1) (const_int 0)))]
  ""
  ""
  "
  "
{
{
  operands[1] = gen_compare_reg (LEU, arc_compare_op0, arc_compare_op1);
  operands[1] = gen_compare_reg (LEU, arc_compare_op0, arc_compare_op1);
}")
}")
(define_expand "sgeu"
(define_expand "sgeu"
  [(set (match_operand:SI 0 "register_operand" "=r")
  [(set (match_operand:SI 0 "register_operand" "=r")
        (geu:SI (match_dup 1) (const_int 0)))]
        (geu:SI (match_dup 1) (const_int 0)))]
  ""
  ""
  "
  "
{
{
  operands[1] = gen_compare_reg (GEU, arc_compare_op0, arc_compare_op1);
  operands[1] = gen_compare_reg (GEU, arc_compare_op0, arc_compare_op1);
}")
}")
(define_expand "sltu"
(define_expand "sltu"
  [(set (match_operand:SI 0 "register_operand" "=r")
  [(set (match_operand:SI 0 "register_operand" "=r")
        (ltu:SI (match_dup 1) (const_int 0)))]
        (ltu:SI (match_dup 1) (const_int 0)))]
  ""
  ""
  "
  "
{
{
  operands[1] = gen_compare_reg (LTU, arc_compare_op0, arc_compare_op1);
  operands[1] = gen_compare_reg (LTU, arc_compare_op0, arc_compare_op1);
}")
}")
(define_insn "*scc_insn"
(define_insn "*scc_insn"
  [(set (match_operand:SI 0 "register_operand" "=r")
  [(set (match_operand:SI 0 "register_operand" "=r")
        (match_operator:SI 1 "comparison_operator" [(reg 61) (const_int 0)]))]
        (match_operator:SI 1 "comparison_operator" [(reg 61) (const_int 0)]))]
  ""
  ""
  "mov %0,1\;sub.%D1 %0,%0,%0"
  "mov %0,1\;sub.%D1 %0,%0,%0"
  [(set_attr "type" "unary")
  [(set_attr "type" "unary")
   (set_attr "length" "2")])
   (set_attr "length" "2")])
;; ??? Look up negscc insn.  See pa.md for example.
;; ??? Look up negscc insn.  See pa.md for example.
(define_insn "*neg_scc_insn"
(define_insn "*neg_scc_insn"
  [(set (match_operand:SI 0 "register_operand" "=r")
  [(set (match_operand:SI 0 "register_operand" "=r")
        (neg:SI (match_operator:SI 1 "comparison_operator"
        (neg:SI (match_operator:SI 1 "comparison_operator"
                 [(reg 61) (const_int 0)])))]
                 [(reg 61) (const_int 0)])))]
  ""
  ""
  "mov %0,-1\;sub.%D1 %0,%0,%0"
  "mov %0,-1\;sub.%D1 %0,%0,%0"
  [(set_attr "type" "unary")
  [(set_attr "type" "unary")
   (set_attr "length" "2")])
   (set_attr "length" "2")])
(define_insn "*not_scc_insn"
(define_insn "*not_scc_insn"
  [(set (match_operand:SI 0 "register_operand" "=r")
  [(set (match_operand:SI 0 "register_operand" "=r")
        (not:SI (match_operator:SI 1 "comparison_operator"
        (not:SI (match_operator:SI 1 "comparison_operator"
                 [(reg 61) (const_int 0)])))]
                 [(reg 61) (const_int 0)])))]
  ""
  ""
  "mov %0,1\;sub.%d1 %0,%0,%0"
  "mov %0,1\;sub.%d1 %0,%0,%0"
  [(set_attr "type" "unary")
  [(set_attr "type" "unary")
   (set_attr "length" "2")])
   (set_attr "length" "2")])


;; These control RTL generation for conditional jump insns
;; These control RTL generation for conditional jump insns
(define_expand "beq"
(define_expand "beq"
  [(set (pc)
  [(set (pc)
        (if_then_else (eq (match_dup 1) (const_int 0))
        (if_then_else (eq (match_dup 1) (const_int 0))
                      (label_ref (match_operand 0 "" ""))
                      (label_ref (match_operand 0 "" ""))
                      (pc)))]
                      (pc)))]
  ""
  ""
  "
  "
{
{
  operands[1] = gen_compare_reg (EQ, arc_compare_op0, arc_compare_op1);
  operands[1] = gen_compare_reg (EQ, arc_compare_op0, arc_compare_op1);
}")
}")
(define_expand "bne"
(define_expand "bne"
  [(set (pc)
  [(set (pc)
        (if_then_else (ne (match_dup 1) (const_int 0))
        (if_then_else (ne (match_dup 1) (const_int 0))
                      (label_ref (match_operand 0 "" ""))
                      (label_ref (match_operand 0 "" ""))
                      (pc)))]
                      (pc)))]
  ""
  ""
  "
  "
{
{
  operands[1] = gen_compare_reg (NE, arc_compare_op0, arc_compare_op1);
  operands[1] = gen_compare_reg (NE, arc_compare_op0, arc_compare_op1);
}")
}")
(define_expand "bgt"
(define_expand "bgt"
  [(set (pc)
  [(set (pc)
        (if_then_else (gt (match_dup 1) (const_int 0))
        (if_then_else (gt (match_dup 1) (const_int 0))
                      (label_ref (match_operand 0 "" ""))
                      (label_ref (match_operand 0 "" ""))
                      (pc)))]
                      (pc)))]
  ""
  ""
  "
  "
{
{
  operands[1] = gen_compare_reg (GT, arc_compare_op0, arc_compare_op1);
  operands[1] = gen_compare_reg (GT, arc_compare_op0, arc_compare_op1);
}")
}")
(define_expand "ble"
(define_expand "ble"
  [(set (pc)
  [(set (pc)
        (if_then_else (le (match_dup 1) (const_int 0))
        (if_then_else (le (match_dup 1) (const_int 0))
                      (label_ref (match_operand 0 "" ""))
                      (label_ref (match_operand 0 "" ""))
                      (pc)))]
                      (pc)))]
  ""
  ""
  "
  "
{
{
  operands[1] = gen_compare_reg (LE, arc_compare_op0, arc_compare_op1);
  operands[1] = gen_compare_reg (LE, arc_compare_op0, arc_compare_op1);
}")
}")
(define_expand "bge"
(define_expand "bge"
  [(set (pc)
  [(set (pc)
        (if_then_else (ge (match_dup 1) (const_int 0))
        (if_then_else (ge (match_dup 1) (const_int 0))
                      (label_ref (match_operand 0 "" ""))
                      (label_ref (match_operand 0 "" ""))
                      (pc)))]
                      (pc)))]
  ""
  ""
  "
  "
{
{
  operands[1] = gen_compare_reg (GE, arc_compare_op0, arc_compare_op1);
  operands[1] = gen_compare_reg (GE, arc_compare_op0, arc_compare_op1);
}")
}")
(define_expand "blt"
(define_expand "blt"
  [(set (pc)
  [(set (pc)
        (if_then_else (lt (match_dup 1) (const_int 0))
        (if_then_else (lt (match_dup 1) (const_int 0))
                      (label_ref (match_operand 0 "" ""))
                      (label_ref (match_operand 0 "" ""))
                      (pc)))]
                      (pc)))]
  ""
  ""
  "
  "
{
{
  operands[1] = gen_compare_reg (LT, arc_compare_op0, arc_compare_op1);
  operands[1] = gen_compare_reg (LT, arc_compare_op0, arc_compare_op1);
}")
}")
(define_expand "bgtu"
(define_expand "bgtu"
  [(set (pc)
  [(set (pc)
        (if_then_else (gtu (match_dup 1) (const_int 0))
        (if_then_else (gtu (match_dup 1) (const_int 0))
                      (label_ref (match_operand 0 "" ""))
                      (label_ref (match_operand 0 "" ""))
                      (pc)))]
                      (pc)))]
  ""
  ""
  "
  "
{
{
  operands[1] = gen_compare_reg (GTU, arc_compare_op0, arc_compare_op1);
  operands[1] = gen_compare_reg (GTU, arc_compare_op0, arc_compare_op1);
}")
}")
(define_expand "bleu"
(define_expand "bleu"
  [(set (pc)
  [(set (pc)
        (if_then_else (leu (match_dup 1) (const_int 0))
        (if_then_else (leu (match_dup 1) (const_int 0))
                      (label_ref (match_operand 0 "" ""))
                      (label_ref (match_operand 0 "" ""))
                      (pc)))]
                      (pc)))]
  ""
  ""
  "
  "
{
{
  operands[1] = gen_compare_reg (LEU, arc_compare_op0, arc_compare_op1);
  operands[1] = gen_compare_reg (LEU, arc_compare_op0, arc_compare_op1);
}")
}")
(define_expand "bgeu"
(define_expand "bgeu"
  [(set (pc)
  [(set (pc)
        (if_then_else (geu (match_dup 1) (const_int 0))
        (if_then_else (geu (match_dup 1) (const_int 0))
                      (label_ref (match_operand 0 "" ""))
                      (label_ref (match_operand 0 "" ""))
                      (pc)))]
                      (pc)))]
  ""
  ""
  "
  "
{
{
  operands[1] = gen_compare_reg (GEU, arc_compare_op0, arc_compare_op1);
  operands[1] = gen_compare_reg (GEU, arc_compare_op0, arc_compare_op1);
}")
}")
(define_expand "bltu"
(define_expand "bltu"
  [(set (pc)
  [(set (pc)
        (if_then_else (ltu (match_dup 1) (const_int 0))
        (if_then_else (ltu (match_dup 1) (const_int 0))
                      (label_ref (match_operand 0 "" ""))
                      (label_ref (match_operand 0 "" ""))
                      (pc)))]
                      (pc)))]
  ""
  ""
  "
  "
{
{
  operands[1] = gen_compare_reg (LTU, arc_compare_op0, arc_compare_op1);
  operands[1] = gen_compare_reg (LTU, arc_compare_op0, arc_compare_op1);
}")
}")
;; Now match both normal and inverted jump.
;; Now match both normal and inverted jump.
(define_insn "*branch_insn"
(define_insn "*branch_insn"
  [(set (pc)
  [(set (pc)
        (if_then_else (match_operator 1 "proper_comparison_operator"
        (if_then_else (match_operator 1 "proper_comparison_operator"
                                      [(reg 61) (const_int 0)])
                                      [(reg 61) (const_int 0)])
                      (label_ref (match_operand 0 "" ""))
                      (label_ref (match_operand 0 "" ""))
                      (pc)))]
                      (pc)))]
  ""
  ""
  "*
  "*
{
{
  if (arc_ccfsm_branch_deleted_p ())
  if (arc_ccfsm_branch_deleted_p ())
    {
    {
      arc_ccfsm_record_branch_deleted ();
      arc_ccfsm_record_branch_deleted ();
      return \"; branch deleted, next insns conditionalized\";
      return \"; branch deleted, next insns conditionalized\";
    }
    }
  else
  else
    return \"%~b%d1%# %l0\";
    return \"%~b%d1%# %l0\";
}"
}"
  [(set_attr "type" "branch")])
  [(set_attr "type" "branch")])
(define_insn "*rev_branch_insn"
(define_insn "*rev_branch_insn"
  [(set (pc)
  [(set (pc)
        (if_then_else (match_operator 1 "proper_comparison_operator"
        (if_then_else (match_operator 1 "proper_comparison_operator"
                                      [(reg 61) (const_int 0)])
                                      [(reg 61) (const_int 0)])
                      (pc)
                      (pc)
                      (label_ref (match_operand 0 "" ""))))]
                      (label_ref (match_operand 0 "" ""))))]
  "REVERSIBLE_CC_MODE (GET_MODE (XEXP (operands[1], 0)))"
  "REVERSIBLE_CC_MODE (GET_MODE (XEXP (operands[1], 0)))"
  "*
  "*
{
{
  if (arc_ccfsm_branch_deleted_p ())
  if (arc_ccfsm_branch_deleted_p ())
    {
    {
      arc_ccfsm_record_branch_deleted ();
      arc_ccfsm_record_branch_deleted ();
      return \"; branch deleted, next insns conditionalized\";
      return \"; branch deleted, next insns conditionalized\";
    }
    }
  else
  else
    return \"%~b%D1%# %l0\";
    return \"%~b%D1%# %l0\";
}"
}"
  [(set_attr "type" "branch")])
  [(set_attr "type" "branch")])


;; Unconditional and other jump instructions.
;; Unconditional and other jump instructions.
(define_insn "jump"
(define_insn "jump"
  [(set (pc) (label_ref (match_operand 0 "" "")))]
  [(set (pc) (label_ref (match_operand 0 "" "")))]
  ""
  ""
  "b%* %l0"
  "b%* %l0"
  [(set_attr "type" "uncond_branch")])
  [(set_attr "type" "uncond_branch")])
(define_insn "indirect_jump"
(define_insn "indirect_jump"
  [(set (pc) (match_operand:SI 0 "address_operand" "p"))]
  [(set (pc) (match_operand:SI 0 "address_operand" "p"))]
  ""
  ""
  "j%* %a0"
  "j%* %a0"
  [(set_attr "type" "uncond_branch")])
  [(set_attr "type" "uncond_branch")])
;; Implement a switch statement.
;; Implement a switch statement.
;; This wouldn't be necessary in the non-pic case if we could distinguish
;; This wouldn't be necessary in the non-pic case if we could distinguish
;; label refs of the jump table from other label refs.  The problem is that
;; label refs of the jump table from other label refs.  The problem is that
;; label refs are output as "%st(.LL42)" but we don't want the %st - we want
;; label refs are output as "%st(.LL42)" but we don't want the %st - we want
;; the real address since it's the address of the table.
;; the real address since it's the address of the table.
(define_expand "casesi"
(define_expand "casesi"
  [(set (match_dup 5)
  [(set (match_dup 5)
        (minus:SI (match_operand:SI 0 "register_operand" "")
        (minus:SI (match_operand:SI 0 "register_operand" "")
                  (match_operand:SI 1 "nonmemory_operand" "")))
                  (match_operand:SI 1 "nonmemory_operand" "")))
   (set (reg:CC 61)
   (set (reg:CC 61)
        (compare:CC (match_dup 5)
        (compare:CC (match_dup 5)
                    (match_operand:SI 2 "nonmemory_operand" "")))
                    (match_operand:SI 2 "nonmemory_operand" "")))
   (set (pc)
   (set (pc)
        (if_then_else (gtu (reg:CC 61)
        (if_then_else (gtu (reg:CC 61)
                           (const_int 0))
                           (const_int 0))
                      (label_ref (match_operand 4 "" ""))
                      (label_ref (match_operand 4 "" ""))
                      (pc)))
                      (pc)))
   (parallel
   (parallel
    [(set (pc)
    [(set (pc)
          (mem:SI (plus:SI (mult:SI (match_dup 5)
          (mem:SI (plus:SI (mult:SI (match_dup 5)
                                    (const_int 4))
                                    (const_int 4))
                           (label_ref (match_operand 3 "" "")))))
                           (label_ref (match_operand 3 "" "")))))
     (clobber (match_scratch:SI 6 ""))
     (clobber (match_scratch:SI 6 ""))
     (clobber (match_scratch:SI 7 ""))])]
     (clobber (match_scratch:SI 7 ""))])]
  ""
  ""
  "
  "
{
{
  operands[5] = gen_reg_rtx (SImode);
  operands[5] = gen_reg_rtx (SImode);
}")
}")
(define_insn "*casesi_insn"
(define_insn "*casesi_insn"
  [(set (pc)
  [(set (pc)
        (mem:SI (plus:SI (mult:SI (match_operand:SI 0 "register_operand" "r")
        (mem:SI (plus:SI (mult:SI (match_operand:SI 0 "register_operand" "r")
                                  (const_int 4))
                                  (const_int 4))
                         (label_ref (match_operand 1 "" "")))))
                         (label_ref (match_operand 1 "" "")))))
   (clobber (match_scratch:SI 2 "=r"))
   (clobber (match_scratch:SI 2 "=r"))
   (clobber (match_scratch:SI 3 "=r"))]
   (clobber (match_scratch:SI 3 "=r"))]
  ""
  ""
  "*
  "*
{
{
  output_asm_insn (\"mov %2,%1\", operands);
  output_asm_insn (\"mov %2,%1\", operands);
  if (TARGET_SHIFTER)
  if (TARGET_SHIFTER)
    output_asm_insn (\"asl %3,%0,2\", operands);
    output_asm_insn (\"asl %3,%0,2\", operands);
  else
  else
    output_asm_insn (\"asl %3,%0\;asl %3,%3\", operands);
    output_asm_insn (\"asl %3,%0\;asl %3,%3\", operands);
  output_asm_insn (\"ld %2,[%2,%3]\", operands);
  output_asm_insn (\"ld %2,[%2,%3]\", operands);
  output_asm_insn (\"j.nd %a2\", operands);
  output_asm_insn (\"j.nd %a2\", operands);
  return \"\";
  return \"\";
}"
}"
  [(set_attr "type" "uncond_branch")
  [(set_attr "type" "uncond_branch")
   (set_attr "length" "6")])
   (set_attr "length" "6")])
(define_insn "tablejump"
(define_insn "tablejump"
  [(set (pc) (match_operand:SI 0 "address_operand" "p"))
  [(set (pc) (match_operand:SI 0 "address_operand" "p"))
   (use (label_ref (match_operand 1 "" "")))]
   (use (label_ref (match_operand 1 "" "")))]
  "0 /* disabled -> using casesi now */"
  "0 /* disabled -> using casesi now */"
  "j%* %a0"
  "j%* %a0"
  [(set_attr "type" "uncond_branch")])
  [(set_attr "type" "uncond_branch")])
(define_expand "call"
(define_expand "call"
  ;; operands[1] is stack_size_rtx
  ;; operands[1] is stack_size_rtx
  ;; operands[2] is next_arg_register
  ;; operands[2] is next_arg_register
  [(parallel [(call (match_operand:SI 0 "call_operand" "")
  [(parallel [(call (match_operand:SI 0 "call_operand" "")
                    (match_operand 1 "" ""))
                    (match_operand 1 "" ""))
             (clobber (reg:SI 31))])]
             (clobber (reg:SI 31))])]
  ""
  ""
  "")
  "")
(define_insn "*call_via_reg"
(define_insn "*call_via_reg"
  [(call (mem:SI (match_operand:SI 0 "register_operand" "r"))
  [(call (mem:SI (match_operand:SI 0 "register_operand" "r"))
         (match_operand 1 "" ""))
         (match_operand 1 "" ""))
   (clobber (reg:SI 31))]
   (clobber (reg:SI 31))]
  ""
  ""
  "lr blink,[status]\;j.d %0\;add blink,blink,2"
  "lr blink,[status]\;j.d %0\;add blink,blink,2"
  [(set_attr "type" "call_no_delay_slot")
  [(set_attr "type" "call_no_delay_slot")
   (set_attr "length" "3")])
   (set_attr "length" "3")])
(define_insn "*call_via_label"
(define_insn "*call_via_label"
  [(call (mem:SI (match_operand:SI 0 "call_address_operand" ""))
  [(call (mem:SI (match_operand:SI 0 "call_address_operand" ""))
         (match_operand 1 "" ""))
         (match_operand 1 "" ""))
   (clobber (reg:SI 31))]
   (clobber (reg:SI 31))]
  ""
  ""
  ; The %~ is necessary in case this insn gets conditionalized and the previous
  ; The %~ is necessary in case this insn gets conditionalized and the previous
  ; insn is the cc setter.
  ; insn is the cc setter.
  "%~bl%!%* %0"
  "%~bl%!%* %0"
  [(set_attr "type" "call")
  [(set_attr "type" "call")
   (set_attr "cond" "canuse")])
   (set_attr "cond" "canuse")])
(define_expand "call_value"
(define_expand "call_value"
  ;; operand 2 is stack_size_rtx
  ;; operand 2 is stack_size_rtx
  ;; operand 3 is next_arg_register
  ;; operand 3 is next_arg_register
  [(parallel [(set (match_operand 0 "register_operand" "=r")
  [(parallel [(set (match_operand 0 "register_operand" "=r")
                   (call (match_operand:SI 1 "call_operand" "")
                   (call (match_operand:SI 1 "call_operand" "")
                         (match_operand 2 "" "")))
                         (match_operand 2 "" "")))
             (clobber (reg:SI 31))])]
             (clobber (reg:SI 31))])]
  ""
  ""
  "")
  "")
(define_insn "*call_value_via_reg"
(define_insn "*call_value_via_reg"
  [(set (match_operand 0 "register_operand" "=r")
  [(set (match_operand 0 "register_operand" "=r")
        (call (mem:SI (match_operand:SI 1 "register_operand" "r"))
        (call (mem:SI (match_operand:SI 1 "register_operand" "r"))
              (match_operand 2 "" "")))
              (match_operand 2 "" "")))
   (clobber (reg:SI 31))]
   (clobber (reg:SI 31))]
  ""
  ""
  "lr blink,[status]\;j.d %1\;add blink,blink,2"
  "lr blink,[status]\;j.d %1\;add blink,blink,2"
  [(set_attr "type" "call_no_delay_slot")
  [(set_attr "type" "call_no_delay_slot")
   (set_attr "length" "3")])
   (set_attr "length" "3")])
(define_insn "*call_value_via_label"
(define_insn "*call_value_via_label"
  [(set (match_operand 0 "register_operand" "=r")
  [(set (match_operand 0 "register_operand" "=r")
        (call (mem:SI (match_operand:SI 1 "call_address_operand" ""))
        (call (mem:SI (match_operand:SI 1 "call_address_operand" ""))
              (match_operand 2 "" "")))
              (match_operand 2 "" "")))
   (clobber (reg:SI 31))]
   (clobber (reg:SI 31))]
  ""
  ""
  ; The %~ is necessary in case this insn gets conditionalized and the previous
  ; The %~ is necessary in case this insn gets conditionalized and the previous
  ; insn is the cc setter.
  ; insn is the cc setter.
  "%~bl%!%* %1"
  "%~bl%!%* %1"
  [(set_attr "type" "call")
  [(set_attr "type" "call")
   (set_attr "cond" "canuse")])
   (set_attr "cond" "canuse")])


(define_insn "nop"
(define_insn "nop"
  [(const_int 0)]
  [(const_int 0)]
  ""
  ""
  "nop"
  "nop"
  [(set_attr "type" "misc")])
  [(set_attr "type" "misc")])
;; Special pattern to flush the icache.
;; Special pattern to flush the icache.
;; ??? Not sure what to do here.  Some ARC's are known to support this.
;; ??? Not sure what to do here.  Some ARC's are known to support this.
(define_insn "flush_icache"
(define_insn "flush_icache"
  [(unspec_volatile [(match_operand 0 "memory_operand" "m")] 0)]
  [(unspec_volatile [(match_operand 0 "memory_operand" "m")] 0)]
  ""
  ""
  "* return \"\";"
  "* return \"\";"
  [(set_attr "type" "misc")])
  [(set_attr "type" "misc")])


;; Split up troublesome insns for better scheduling.
;; Split up troublesome insns for better scheduling.


;; Peepholes go at the end.
;; Peepholes go at the end.
 
 

powered by: WebSVN 2.1.0

© copyright 1999-2024 OpenCores.org, equivalent to Oliscience, all rights reserved. OpenCores®, registered trademark.