OpenCores
URL https://opencores.org/ocsvn/openrisc_2011-10-31/openrisc_2011-10-31/trunk

Subversion Repositories openrisc_2011-10-31

[/] [openrisc/] [trunk/] [gnu-src/] [gcc-4.5.1/] [gcc/] [config/] [rx/] [rx.md] - Diff between revs 282 and 378

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

Rev 282 Rev 378
;;  Machine Description for Renesas RX processors
;;  Machine Description for Renesas RX processors
;;  Copyright (C) 2008, 2009, 2010 Free Software Foundation, Inc.
;;  Copyright (C) 2008, 2009, 2010 Free Software Foundation, Inc.
;;  Contributed by Red Hat.
;;  Contributed by Red Hat.
;; 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
;; .
;; .


;; This code iterator allows all branch instructions to
;; This code iterator allows all branch instructions to
;; be generated from a single define_expand template.
;; be generated from a single define_expand template.
(define_code_iterator most_cond [eq ne gt ge lt le gtu geu ltu leu
(define_code_iterator most_cond [eq ne gt ge lt le gtu geu ltu leu
                                 unordered ordered ])
                                 unordered ordered ])
 
 
 
;; Likewise, but only the ones that use Z or S.
 
(define_code_iterator zs_cond [eq ne gtu geu ltu leu ])
 
 
;; This code iterator is used for sign- and zero- extensions.
;; This code iterator is used for sign- and zero- extensions.
(define_mode_iterator small_int_modes [(HI "") (QI "")])
(define_mode_iterator small_int_modes [(HI "") (QI "")])
;; We do not handle DFmode here because it is either
;; We do not handle DFmode here because it is either
;; the same as SFmode, or if -m64bit-doubles is active
;; the same as SFmode, or if -m64bit-doubles is active
;; then all operations on doubles have to be handled by
;; then all operations on doubles have to be handled by
;; library functions.
;; library functions.
(define_mode_iterator register_modes
(define_mode_iterator register_modes
  [(SF "ALLOW_RX_FPU_INSNS") (SI "") (HI "") (QI "")])
  [(SF "ALLOW_RX_FPU_INSNS") (SI "") (HI "") (QI "")])
;; Used to map RX condition names to GCC
;; Used to map RX condition names to GCC
;; condition names for builtin instructions.
;; condition names for builtin instructions.
(define_code_iterator gcc_conds [eq ne gt ge lt le gtu geu ltu leu
(define_code_iterator gcc_conds [eq ne gt ge lt le gtu geu ltu leu
                                unge unlt uneq ltgt])
                                unge unlt uneq ltgt])
(define_code_attr rx_conds [(eq "eq") (ne "ne") (gt "gt") (ge "ge") (lt "lt")
(define_code_attr rx_conds [(eq "eq") (ne "ne") (gt "gt") (ge "ge") (lt "lt")
                            (le "le") (gtu "gtu") (geu "geu") (ltu "ltu")
                            (le "le") (gtu "gtu") (geu "geu") (ltu "ltu")
                            (leu "leu") (unge "pz") (unlt "n") (uneq "o")
                            (leu "leu") (unge "pz") (unlt "n") (uneq "o")
                            (ltgt "no")])
                            (ltgt "no")])
(define_constants
(define_constants
  [
  [
   (SP_REG 0)
   (SP_REG 0)
   (CC_REG                 16)
   (CC_REG                 16)
   (UNSPEC_LOW_REG         0)
   (UNSPEC_LOW_REG         0)
   (UNSPEC_HIGH_REG        1)
   (UNSPEC_HIGH_REG        1)
   (UNSPEC_RTE             10)
   (UNSPEC_RTE             10)
   (UNSPEC_RTFI            11)
   (UNSPEC_RTFI            11)
   (UNSPEC_NAKED           12)
   (UNSPEC_NAKED           12)
   (UNSPEC_MOVSTR          20)
   (UNSPEC_MOVSTR          20)
   (UNSPEC_MOVMEM          21)
   (UNSPEC_MOVMEM          21)
   (UNSPEC_SETMEM          22)
   (UNSPEC_SETMEM          22)
   (UNSPEC_STRLEN          23)
   (UNSPEC_STRLEN          23)
   (UNSPEC_CMPSTRN         24)
   (UNSPEC_CMPSTRN         24)
   (UNSPEC_BUILTIN_BRK     30)
   (UNSPEC_BUILTIN_BRK     30)
   (UNSPEC_BUILTIN_CLRPSW  31)
   (UNSPEC_BUILTIN_CLRPSW  31)
   (UNSPEC_BUILTIN_INT     32)
   (UNSPEC_BUILTIN_INT     32)
   (UNSPEC_BUILTIN_MACHI   33)
   (UNSPEC_BUILTIN_MACHI   33)
   (UNSPEC_BUILTIN_MACLO   34)
   (UNSPEC_BUILTIN_MACLO   34)
   (UNSPEC_BUILTIN_MULHI   35)
   (UNSPEC_BUILTIN_MULHI   35)
   (UNSPEC_BUILTIN_MULLO   36)
   (UNSPEC_BUILTIN_MULLO   36)
   (UNSPEC_BUILTIN_MVFACHI 37)
   (UNSPEC_BUILTIN_MVFACHI 37)
   (UNSPEC_BUILTIN_MVFACMI 38)
   (UNSPEC_BUILTIN_MVFACMI 38)
   (UNSPEC_BUILTIN_MVFC    39)
   (UNSPEC_BUILTIN_MVFC    39)
   (UNSPEC_BUILTIN_MVFCP   40)
   (UNSPEC_BUILTIN_MVFCP   40)
   (UNSPEC_BUILTIN_MVTACHI 41)
   (UNSPEC_BUILTIN_MVTACHI 41)
   (UNSPEC_BUILTIN_MVTACLO 42)
   (UNSPEC_BUILTIN_MVTACLO 42)
   (UNSPEC_BUILTIN_MVTC    43)
   (UNSPEC_BUILTIN_MVTC    43)
   (UNSPEC_BUILTIN_MVTIPL  44)
   (UNSPEC_BUILTIN_MVTIPL  44)
   (UNSPEC_BUILTIN_RACW    45)
   (UNSPEC_BUILTIN_RACW    45)
   (UNSPEC_BUILTIN_REVW    46)
   (UNSPEC_BUILTIN_REVW    46)
   (UNSPEC_BUILTIN_RMPA    47)
   (UNSPEC_BUILTIN_RMPA    47)
   (UNSPEC_BUILTIN_ROUND   48)
   (UNSPEC_BUILTIN_ROUND   48)
   (UNSPEC_BUILTIN_SAT     49)
   (UNSPEC_BUILTIN_SAT     49)
   (UNSPEC_BUILTIN_SETPSW  50)
   (UNSPEC_BUILTIN_SETPSW  50)
   (UNSPEC_BUILTIN_WAIT    51)
   (UNSPEC_BUILTIN_WAIT    51)
  ]
  ]
)
)
(define_attr "length" "" (const_int 8))
(define_attr "length" "" (const_int 8))
(include "predicates.md")
(include "predicates.md")
(include "constraints.md")
(include "constraints.md")
;; Pipeline description.
;; Pipeline description.
;; The RX only has a single pipeline.  It has five stages (fetch,
;; The RX only has a single pipeline.  It has five stages (fetch,
;; decode, execute, memory access, writeback) each of which normally
;; decode, execute, memory access, writeback) each of which normally
;; takes a single CPU clock cycle.
;; takes a single CPU clock cycle.
;; The timings attribute consists of two numbers, the first is the
;; The timings attribute consists of two numbers, the first is the
;; throughput, which is the number of cycles the instruction takes
;; throughput, which is the number of cycles the instruction takes
;; to execute and generate a result.  The second is the latency
;; to execute and generate a result.  The second is the latency
;; which is the effective number of cycles the instruction takes to
;; which is the effective number of cycles the instruction takes to
;; execute if its result is used by the following instruction.  The
;; execute if its result is used by the following instruction.  The
;; latency is always greater than or equal to the throughput.
;; latency is always greater than or equal to the throughput.
;; These values were taken from tables 2.13 and 2.14 in section 2.8
;; These values were taken from tables 2.13 and 2.14 in section 2.8
;; of the RX610 Group Hardware Manual v0.11
;; of the RX610 Group Hardware Manual v0.11
;; Note - it would be nice to use strings rather than integers for
;; Note - it would be nice to use strings rather than integers for
;; the possible values of this attribute, so that we can have the
;; the possible values of this attribute, so that we can have the
;; gcc build mechanism check for values that are not supported by
;; gcc build mechanism check for values that are not supported by
;; the reservations below.  But this will not work because the code
;; the reservations below.  But this will not work because the code
;; in rx_adjust_sched_cost() needs integers not strings.
;; in rx_adjust_sched_cost() needs integers not strings.
(define_attr "timings" "" (const_int 11))
(define_attr "timings" "" (const_int 11))
(define_automaton "pipelining")
(define_automaton "pipelining")
(define_cpu_unit "throughput" "pipelining")
(define_cpu_unit "throughput" "pipelining")
(define_insn_reservation "throughput__1_latency__1"  1
(define_insn_reservation "throughput__1_latency__1"  1
  (eq_attr "timings" "11") "throughput")
  (eq_attr "timings" "11") "throughput")
(define_insn_reservation "throughput__1_latency__2"  2
(define_insn_reservation "throughput__1_latency__2"  2
  (eq_attr "timings" "12") "throughput,nothing")
  (eq_attr "timings" "12") "throughput,nothing")
(define_insn_reservation "throughput__2_latency__2"  1
(define_insn_reservation "throughput__2_latency__2"  1
  (eq_attr "timings" "22") "throughput*2")
  (eq_attr "timings" "22") "throughput*2")
(define_insn_reservation "throughput__3_latency__3"  1
(define_insn_reservation "throughput__3_latency__3"  1
  (eq_attr "timings" "33") "throughput*3")
  (eq_attr "timings" "33") "throughput*3")
(define_insn_reservation "throughput__3_latency__4"  2
(define_insn_reservation "throughput__3_latency__4"  2
  (eq_attr "timings" "34") "throughput*3,nothing")
  (eq_attr "timings" "34") "throughput*3,nothing")
(define_insn_reservation "throughput__4_latency__4"  1
(define_insn_reservation "throughput__4_latency__4"  1
  (eq_attr "timings" "44") "throughput*4")
  (eq_attr "timings" "44") "throughput*4")
(define_insn_reservation "throughput__4_latency__5"  2
(define_insn_reservation "throughput__4_latency__5"  2
  (eq_attr "timings" "45") "throughput*4,nothing")
  (eq_attr "timings" "45") "throughput*4,nothing")
(define_insn_reservation "throughput__5_latency__5"  1
(define_insn_reservation "throughput__5_latency__5"  1
  (eq_attr "timings" "55") "throughput*5")
  (eq_attr "timings" "55") "throughput*5")
(define_insn_reservation "throughput__5_latency__6"  2
(define_insn_reservation "throughput__5_latency__6"  2
  (eq_attr "timings" "56") "throughput*5,nothing")
  (eq_attr "timings" "56") "throughput*5,nothing")
(define_insn_reservation "throughput__6_latency__6"  1
(define_insn_reservation "throughput__6_latency__6"  1
  (eq_attr "timings" "66") "throughput*6")
  (eq_attr "timings" "66") "throughput*6")
(define_insn_reservation "throughput_10_latency_10"  1
(define_insn_reservation "throughput_10_latency_10"  1
  (eq_attr "timings" "1010") "throughput*10")
  (eq_attr "timings" "1010") "throughput*10")
(define_insn_reservation "throughput_11_latency_11"  1
(define_insn_reservation "throughput_11_latency_11"  1
  (eq_attr "timings" "1111") "throughput*11")
  (eq_attr "timings" "1111") "throughput*11")
(define_insn_reservation "throughput_16_latency_16"  1
(define_insn_reservation "throughput_16_latency_16"  1
  (eq_attr "timings" "1616") "throughput*16")
  (eq_attr "timings" "1616") "throughput*16")
(define_insn_reservation "throughput_18_latency_18"  1
(define_insn_reservation "throughput_18_latency_18"  1
  (eq_attr "timings" "1818") "throughput*18")
  (eq_attr "timings" "1818") "throughput*18")
;; Comparisons
;; Comparisons
;; Note - we do not specify the two instructions necessary to perform
;; Note - we do not specify the two instructions necessary to perform
;; a compare-and-branch in the cbranchsi4 pattern because that would
;; a compare-and-branch in the cbranchsi4 pattern because that would
;; allow the comparison to be moved away from the jump before the reload
;; allow the comparison to be moved away from the jump before the reload
;; pass has completed.  That would be problematical because reload can
;; pass has completed.  That would be problematical because reload can
;; generate ADDSI3 instructions which would corrupt the PSW flags.
;; generate ADDSI3 instructions which would corrupt the PSW flags.
(define_expand "cbranchsi4"
(define_expand "cbranchsi4"
  [(set (pc)
  [(set (pc)
        (if_then_else (match_operator:SI 0 "comparison_operator"
        (if_then_else (match_operator 0 "comparison_operator"
                                         [(match_operand:SI 1 "register_operand")
                                         [(match_operand:SI 1 "register_operand")
                                          (match_operand:SI 2 "rx_source_operand")])
                                       (match_operand:SI 2 "rx_source_operand")])
                      (label_ref (match_operand 3 ""))
                      (label_ref (match_operand 3 ""))
                      (pc)))
                      (pc)))
   ]
   ]
  ""
  ""
  ""
  ""
)
)
(define_insn_and_split "*cbranchsi4_"
(define_insn_and_split "*cbranchsi4_"
  [(set (pc)
  [(set (pc)
        (if_then_else (most_cond:SI (match_operand:SI  0 "register_operand"  "r")
        (if_then_else (most_cond (match_operand:SI  0 "register_operand"  "r")
                                    (match_operand:SI  1 "rx_source_operand" "riQ"))
                                    (match_operand:SI  1 "rx_source_operand" "riQ"))
                      (label_ref (match_operand        2 "" ""))
                      (label_ref (match_operand        2 "" ""))
                      (pc)))
                      (pc)))
   ]
   ]
  ""
  ""
  "#"
  "#"
  "reload_completed"
  "reload_completed"
  [(const_int 0)]
  [(const_int 0)]
  "
  "
  /* We contstruct the split by hand as otherwise the JUMP_LABEL
  /* We contstruct the split by hand as otherwise the JUMP_LABEL
     attribute is not set correctly on the jump insn.  */
     attribute is not set correctly on the jump insn.  */
  emit_insn (gen_cmpsi (operands[0], operands[1]));
  emit_insn (gen_cmpsi (operands[0], operands[1]));
  emit_jump_insn (gen_conditional_branch (operands[2],
  emit_jump_insn (gen_conditional_branch (operands[2],
                 gen_rtx_fmt_ee (, CCmode,
                 gen_rtx_fmt_ee (, CCmode,
                                 gen_rtx_REG (CCmode, CC_REG), const0_rtx)));
                                 gen_rtx_REG (CCmode, CC_REG), const0_rtx)));
  "
  "
)
)
 
 
 
;; -----------------------------------------------------------------------------
 
;; These two are the canonical TST/branch insns.  However, GCC
 
;; generates a wide variety of tst-like patterns, we catch those
 
;; below.
 
(define_insn_and_split "*tstbranchsi4_"
 
  [(set (pc)
 
        (if_then_else (zs_cond (and:SI (match_operand:SI  0 "register_operand"  "r")
 
                                       (match_operand:SI  1 "rx_source_operand" "riQ"))
 
                               (const_int 0))
 
                      (label_ref (match_operand 2 "" ""))
 
                      (pc)))
 
   ]
 
  ""
 
  "#"
 
  "reload_completed"
 
  [(const_int 0)]
 
  "
 
  emit_insn (gen_tstsi (operands[0], operands[1]));
 
 
 
  emit_jump_insn (gen_conditional_branch (operands[2],
 
                 gen_rtx_fmt_ee (, CCmode,
 
                                 gen_rtx_REG (CCmode, CC_REG), const0_rtx)));
 
  "
 
)
 
 
 
;; Inverse of above
 
(define_insn_and_split "*tstbranchsi4_"
 
  [(set (pc)
 
        (if_then_else (zs_cond (and:SI (match_operand:SI  0 "register_operand"  "r")
 
                                       (match_operand:SI  1 "rx_source_operand" "riQ"))
 
                               (const_int 0))
 
                      (pc)
 
                      (label_ref (match_operand 2 "" ""))))
 
   ]
 
  ""
 
  "#"
 
  "reload_completed"
 
  [(const_int 0)]
 
  "
 
  emit_insn (gen_tstsi (operands[0], operands[1]));
 
 
 
  emit_jump_insn (gen_conditional_branch (operands[2],
 
                 gen_rtx_fmt_ee (reverse_condition (), CCmode,
 
                                 gen_rtx_REG (CCmode, CC_REG), const0_rtx)));
 
  "
 
)
 
 
 
;; Various other ways that GCC codes "var & const"
 
 
 
(define_insn_and_split "*tstbranchsi4m_eq"
 
  [(set (pc)
 
        (if_then_else (eq (zero_extract:SI (match_operand:SI  0 "register_operand"  "r")
 
                                           (match_operand  1 "rx_constshift_operand" "i")
 
                                           (match_operand  2 "rx_constshift_operand" "i"))
 
                          (const_int 0))
 
                      (label_ref (match_operand        3 "" ""))
 
                      (pc)))
 
   ]
 
  ""
 
  "#"
 
  ""
 
  [(set (pc)
 
        (if_then_else (eq (and:SI (match_dup  0)
 
                                  (match_dup 4))
 
                          (const_int 0))
 
                      (label_ref (match_dup 3))
 
                      (pc)))
 
   ]
 
  "operands[4] = GEN_INT (((1 << INTVAL (operands[1]))-1) << INTVAL (operands[2]));"
 
)
 
 
 
(define_insn_and_split "*tstbranchsi4m_ne"
 
  [(set (pc)
 
        (if_then_else (ne (zero_extract:SI (match_operand:SI  0 "register_operand"  "r")
 
                                           (match_operand  1 "rx_constshift_operand" "i")
 
                                           (match_operand  2 "rx_constshift_operand" "i"))
 
                          (const_int 0))
 
                      (label_ref (match_operand        3 "" ""))
 
                      (pc)))
 
   ]
 
  ""
 
  "#"
 
  ""
 
  [(set (pc)
 
        (if_then_else (ne (and:SI (match_dup  0)
 
                                  (match_dup 4))
 
                          (const_int 0))
 
                      (label_ref (match_dup 3))
 
                      (pc)))
 
   ]
 
  "operands[4] = GEN_INT (((1 << INTVAL (operands[1]))-1) << INTVAL (operands[2]));"
 
)
 
 
 
;; -----------------------------------------------------------------------------
 
 
(define_expand "cbranchsf4"
(define_expand "cbranchsf4"
  [(set (pc)
  [(set (pc)
        (if_then_else (match_operator:SF 0 "comparison_operator"
        (if_then_else (match_operator 0 "comparison_operator"
                                         [(match_operand:SF 1 "register_operand")
                                         [(match_operand:SF 1 "register_operand")
                                          (match_operand:SF 2 "rx_source_operand")])
                                       (match_operand:SF 2 "rx_source_operand")])
                      (label_ref (match_operand 3 ""))
                      (label_ref (match_operand 3 ""))
                      (pc)))
                      (pc)))
   ]
   ]
  "ALLOW_RX_FPU_INSNS"
  "ALLOW_RX_FPU_INSNS"
  ""
  ""
)
)
(define_insn_and_split "*cbranchsf4_"
(define_insn_and_split "*cbranchsf4_"
  [(set (pc)
  [(set (pc)
        (if_then_else (most_cond:SF (match_operand:SF  0 "register_operand"  "r")
        (if_then_else (most_cond (match_operand:SF  0 "register_operand"  "r")
                                    (match_operand:SF  1 "rx_source_operand" "rFiQ"))
                                    (match_operand:SF  1 "rx_source_operand" "rFiQ"))
                      (label_ref (match_operand        2 "" ""))
                      (label_ref (match_operand        2 "" ""))
                      (pc)))
                      (pc)))
   ]
   ]
  "ALLOW_RX_FPU_INSNS"
  "ALLOW_RX_FPU_INSNS"
  "#"
  "#"
  "&& reload_completed"
  "&& reload_completed"
  [(const_int 0)]
  [(const_int 0)]
  "
  "
  /* We contstruct the split by hand as otherwise the JUMP_LABEL
  /* We contstruct the split by hand as otherwise the JUMP_LABEL
     attribute is not set correctly on the jump insn.  */
     attribute is not set correctly on the jump insn.  */
  emit_insn (gen_cmpsf (operands[0], operands[1]));
  emit_insn (gen_cmpsf (operands[0], operands[1]));
  emit_jump_insn (gen_conditional_branch (operands[2],
  emit_jump_insn (gen_conditional_branch (operands[2],
                 gen_rtx_fmt_ee (, CCmode,
                 gen_rtx_fmt_ee (, CCmode,
                                 gen_rtx_REG (CCmode, CC_REG), const0_rtx)));
                                 gen_rtx_REG (CCmode, CC_REG), const0_rtx)));
  "
  "
)
)
(define_insn "tstsi"
(define_insn "tstsi"
  [(set (reg:CC_ZS CC_REG)
  [(set (reg:CC_ZS CC_REG)
        (compare:CC_ZS (and:SI (match_operand:SI 0 "register_operand"  "r,r,r")
        (compare:CC_ZS (and:SI (match_operand:SI 0 "register_operand"  "r,r,r")
                               (match_operand:SI 1 "rx_source_operand" "r,i,Q"))
                               (match_operand:SI 1 "rx_source_operand" "r,i,Q"))
                       (const_int 0)))]
                       (const_int 0)))]
  ""
  ""
  {
  {
    rx_float_compare_mode = false;
    rx_float_compare_mode = false;
    return "tst\t%Q1, %0";
    return "tst\t%Q1, %0";
  }
  }
  [(set_attr "timings" "11,11,33")
  [(set_attr "timings" "11,11,33")
   (set_attr "length"   "3,7,6")]
   (set_attr "length"   "3,7,6")]
)
)
(define_insn "cmpsi"
(define_insn "cmpsi"
  [(set (reg:CC CC_REG)
  [(set (reg:CC CC_REG)
        (compare:CC (match_operand:SI 0 "register_operand"  "r,r,r,r,r,r,r")
        (compare:CC (match_operand:SI 0 "register_operand"  "r,r,r,r,r,r,r")
                    (match_operand:SI 1 "rx_source_operand" "r,Uint04,Int08,Sint16,Sint24,i,Q")))]
                    (match_operand:SI 1 "rx_source_operand" "r,Uint04,Int08,Sint16,Sint24,i,Q")))]
  ""
  ""
  {
  {
    rx_float_compare_mode = false;
    rx_float_compare_mode = false;
    if (rx_compare_redundant (insn))
    if (rx_compare_redundant (insn))
      return "; Compare Eliminated: cmp %Q1, %0";
      return "; Compare Eliminated: cmp %Q1, %0";
    return "cmp\t%Q1, %0";
    return "cmp\t%Q1, %0";
  }
  }
  [(set_attr "timings" "11,11,11,11,11,11,33")
  [(set_attr "timings" "11,11,11,11,11,11,33")
   (set_attr "length"  "2,2,3,4,5,6,5")]
   (set_attr "length"  "2,2,3,4,5,6,5")]
)
)
;; This pattern is disabled when -fnon-call-exceptions is active because
;; This pattern is disabled when -fnon-call-exceptions is active because
;; it could generate a floating point exception, which would introduce an
;; it could generate a floating point exception, which would introduce an
;; edge into the flow graph between this insn and the conditional branch
;; edge into the flow graph between this insn and the conditional branch
;; insn to follow, thus breaking the cc0 relationship.  Run the g++ test
;; insn to follow, thus breaking the cc0 relationship.  Run the g++ test
;; g++.dg/eh/080514-1.C to see this happen.
;; g++.dg/eh/080514-1.C to see this happen.
(define_insn "cmpsf"
(define_insn "cmpsf"
  [(set (reg:CC_ZSO CC_REG)
  [(set (reg:CC_ZSO CC_REG)
        (compare:CC_ZSO (match_operand:SF 0 "register_operand"  "r,r,r")
        (compare:CC_ZSO (match_operand:SF 0 "register_operand"  "r,r,r")
                        (match_operand:SF 1 "rx_source_operand" "r,iF,Q")))]
                        (match_operand:SF 1 "rx_source_operand" "r,iF,Q")))]
  "ALLOW_RX_FPU_INSNS"
  "ALLOW_RX_FPU_INSNS"
  {
  {
    rx_float_compare_mode = true;
    rx_float_compare_mode = true;
    return "fcmp\t%1, %0";
    return "fcmp\t%1, %0";
  }
  }
  [(set_attr "timings" "11,11,33")
  [(set_attr "timings" "11,11,33")
   (set_attr "length" "3,7,5")]
   (set_attr "length" "3,7,5")]
)
)
;; Flow Control Instructions:
;; Flow Control Instructions:
(define_expand "b"
(define_expand "b"
  [(set (pc)
  [(set (pc)
        (if_then_else (most_cond (reg:CC CC_REG) (const_int 0))
        (if_then_else (most_cond (reg:CC CC_REG) (const_int 0))
                      (label_ref (match_operand 0))
                      (label_ref (match_operand 0))
                      (pc)))]
                      (pc)))]
  ""
  ""
  ""
  ""
)
)
(define_insn "conditional_branch"
(define_insn "conditional_branch"
  [(set (pc)
  [(set (pc)
        (if_then_else (match_operator           1 "comparison_operator"
        (if_then_else (match_operator           1 "comparison_operator"
                                                [(reg:CC CC_REG) (const_int 0)])
                                                [(reg:CC CC_REG) (const_int 0)])
                      (label_ref (match_operand 0 "" ""))
                      (label_ref (match_operand 0 "" ""))
                      (pc)))]
                      (pc)))]
  ""
  ""
  {
  {
    return rx_gen_cond_branch_template (operands[1], false);
    return rx_gen_cond_branch_template (operands[1], false);
  }
  }
  [(set_attr "length" "8")    ;; This length is wrong, but it is
  [(set_attr "length" "8")    ;; This length is wrong, but it is
                              ;; too hard to compute statically.
                              ;; too hard to compute statically.
   (set_attr "timings" "33")] ;; The timing assumes that the branch is taken.
   (set_attr "timings" "33")] ;; The timing assumes that the branch is taken.
)
)
(define_insn "*reveresed_conditional_branch"
(define_insn "*reveresed_conditional_branch"
  [(set (pc)
  [(set (pc)
        (if_then_else (match_operator 1 "comparison_operator"
        (if_then_else (match_operator 1 "comparison_operator"
                                      [(reg:CC CC_REG) (const_int 0)])
                                      [(reg:CC CC_REG) (const_int 0)])
                      (pc)
                      (pc)
                      (label_ref (match_operand 0 "" ""))))]
                      (label_ref (match_operand 0 "" ""))))]
  ""
  ""
  {
  {
    return rx_gen_cond_branch_template (operands[1], true);
    return rx_gen_cond_branch_template (operands[1], true);
  }
  }
  [(set_attr "length" "8")    ;; This length is wrong, but it is
  [(set_attr "length" "8")    ;; This length is wrong, but it is
                              ;; too hard to compute statically.
                              ;; too hard to compute statically.
   (set_attr "timings" "33")] ;; The timing assumes that the branch is taken.
   (set_attr "timings" "33")] ;; The timing assumes that the branch is taken.
)
)
(define_insn "jump"
(define_insn "jump"
  [(set (pc)
  [(set (pc)
        (label_ref (match_operand 0 "" "")))]
        (label_ref (match_operand 0 "" "")))]
  ""
  ""
  "bra\t%0"
  "bra\t%0"
  [(set_attr "length" "4")
  [(set_attr "length" "4")
   (set_attr "timings" "33")]
   (set_attr "timings" "33")]
)
)
(define_insn "indirect_jump"
(define_insn "indirect_jump"
  [(set (pc)
  [(set (pc)
        (match_operand:SI 0 "register_operand" "r"))]
        (match_operand:SI 0 "register_operand" "r"))]
  ""
  ""
  "jmp\t%0"
  "jmp\t%0"
  [(set_attr "length" "2")
  [(set_attr "length" "2")
   (set_attr "timings" "33")]
   (set_attr "timings" "33")]
)
)
(define_insn "tablejump"
(define_insn "tablejump"
  [(set (pc)
  [(set (pc)
        (match_operand:SI          0 "register_operand" "r"))
        (match_operand:SI          0 "register_operand" "r"))
   (use (label_ref (match_operand  1 "" "")))]
   (use (label_ref (match_operand  1 "" "")))]
  ""
  ""
  { return flag_pic ? (TARGET_AS100_SYNTAX ? "\n?:\tbra\t%0"
  { return flag_pic ? (TARGET_AS100_SYNTAX ? "\n?:\tbra\t%0"
                                           : "\n1:\tbra\t%0")
                                           : "\n1:\tbra\t%0")
                                           : "jmp\t%0";
                                           : "jmp\t%0";
  }
  }
  [(set_attr "timings" "33")
  [(set_attr "timings" "33")
   (set_attr "length" "2")]
   (set_attr "length" "2")]
)
)
(define_insn "simple_return"
(define_insn "simple_return"
  [(return)]
  [(return)]
  ""
  ""
  "rts"
  "rts"
  [(set_attr "length" "1")
  [(set_attr "length" "1")
   (set_attr "timings" "55")]
   (set_attr "timings" "55")]
)
)
(define_insn "deallocate_and_return"
(define_insn "deallocate_and_return"
  [(set (reg:SI SP_REG)
  [(set (reg:SI SP_REG)
        (plus:SI (reg:SI SP_REG)
        (plus:SI (reg:SI SP_REG)
                 (match_operand:SI 0 "immediate_operand" "i")))
                 (match_operand:SI 0 "immediate_operand" "i")))
   (return)]
   (return)]
  ""
  ""
  "rtsd\t%0"
  "rtsd\t%0"
  [(set_attr "length" "2")
  [(set_attr "length" "2")
   (set_attr "timings" "55")]
   (set_attr "timings" "55")]
)
)
(define_insn "pop_and_return"
(define_insn "pop_and_return"
  [(match_parallel 1 "rx_rtsd_vector"
  [(match_parallel 1 "rx_rtsd_vector"
                   [(set:SI (reg:SI SP_REG)
                   [(set:SI (reg:SI SP_REG)
                            (plus:SI (reg:SI SP_REG)
                            (plus:SI (reg:SI SP_REG)
                                     (match_operand:SI 0 "const_int_operand" "n")))])]
                                     (match_operand:SI 0 "const_int_operand" "n")))])]
  "reload_completed"
  "reload_completed"
  {
  {
    rx_emit_stack_popm (operands, false);
    rx_emit_stack_popm (operands, false);
    return "";
    return "";
  }
  }
  [(set_attr "length" "3")
  [(set_attr "length" "3")
   (set_attr "timings" "56")]
   (set_attr "timings" "56")]
)
)
(define_insn "fast_interrupt_return"
(define_insn "fast_interrupt_return"
  [(unspec_volatile [(return)] UNSPEC_RTFI) ]
  [(unspec_volatile [(return)] UNSPEC_RTFI) ]
  ""
  ""
  "rtfi"
  "rtfi"
  [(set_attr "length" "2")
  [(set_attr "length" "2")
   (set_attr "timings" "33")]
   (set_attr "timings" "33")]
)
)
(define_insn "exception_return"
(define_insn "exception_return"
  [(unspec_volatile [(return)] UNSPEC_RTE) ]
  [(unspec_volatile [(return)] UNSPEC_RTE) ]
  ""
  ""
  "rte"
  "rte"
  [(set_attr "length" "2")
  [(set_attr "length" "2")
   (set_attr "timings" "66")]
   (set_attr "timings" "66")]
)
)
(define_insn "naked_return"
(define_insn "naked_return"
  [(unspec_volatile [(return)] UNSPEC_NAKED) ]
  [(unspec_volatile [(return)] UNSPEC_NAKED) ]
  ""
  ""
  "; Naked function: epilogue provided by programmer."
  "; Naked function: epilogue provided by programmer."
)
)
;; Note - the following set of patterns do not use the "memory_operand"
;; Note - the following set of patterns do not use the "memory_operand"
;; predicate or an "m" constraint because we do not allow symbol_refs
;; predicate or an "m" constraint because we do not allow symbol_refs
;; or label_refs as legitmate memory addresses.  This matches the
;; or label_refs as legitmate memory addresses.  This matches the
;; behaviour of most of the RX instructions.  Only the call/branch
;; behaviour of most of the RX instructions.  Only the call/branch
;; instructions are allowed to refer to symbols/labels directly.
;; instructions are allowed to refer to symbols/labels directly.
;; The call operands are in QImode because that is the value of
;; The call operands are in QImode because that is the value of
;; FUNCTION_MODE
;; FUNCTION_MODE
(define_expand "call"
(define_expand "call"
  [(call (match_operand:QI 0 "general_operand")
  [(call (match_operand:QI 0 "general_operand")
         (match_operand:SI 1 "general_operand"))]
         (match_operand:SI 1 "general_operand"))]
  ""
  ""
  {
  {
    rtx dest = XEXP (operands[0], 0);
    rtx dest = XEXP (operands[0], 0);
    if (! rx_call_operand (dest, Pmode))
    if (! rx_call_operand (dest, Pmode))
      dest = force_reg (Pmode, dest);
      dest = force_reg (Pmode, dest);
    emit_call_insn (gen_call_internal (dest, operands[1]));
    emit_call_insn (gen_call_internal (dest, operands[1]));
    DONE;
    DONE;
  }
  }
)
)
(define_insn "call_internal"
(define_insn "call_internal"
  [(call (mem:QI (match_operand:SI 0 "rx_call_operand" "r,Symbol"))
  [(call (mem:QI (match_operand:SI 0 "rx_call_operand" "r,Symbol"))
         (match_operand:SI         1 "general_operand" "g,g"))
         (match_operand:SI         1 "general_operand" "g,g"))
   (clobber (reg:CC CC_REG))]
   (clobber (reg:CC CC_REG))]
  ""
  ""
  "@
  "@
  jsr\t%0
  jsr\t%0
  bsr\t%A0"
  bsr\t%A0"
  [(set_attr "length" "2,4")
  [(set_attr "length" "2,4")
   (set_attr "timings" "33")]
   (set_attr "timings" "33")]
)
)
(define_expand "call_value"
(define_expand "call_value"
  [(set (match_operand          0 "register_operand")
  [(set (match_operand          0 "register_operand")
        (call (match_operand:QI 1 "general_operand")
        (call (match_operand:QI 1 "general_operand")
              (match_operand:SI 2 "general_operand")))]
              (match_operand:SI 2 "general_operand")))]
  ""
  ""
  {
  {
    rtx dest = XEXP (operands[1], 0);
    rtx dest = XEXP (operands[1], 0);
    if (! rx_call_operand (dest, Pmode))
    if (! rx_call_operand (dest, Pmode))
      dest = force_reg (Pmode, dest);
      dest = force_reg (Pmode, dest);
    emit_call_insn (gen_call_value_internal (operands[0], dest, operands[2]));
    emit_call_insn (gen_call_value_internal (operands[0], dest, operands[2]));
    DONE;
    DONE;
  }
  }
)
)
(define_insn "call_value_internal"
(define_insn "call_value_internal"
  [(set (match_operand                  0 "register_operand" "=r,r")
  [(set (match_operand                  0 "register_operand" "=r,r")
        (call (mem:QI (match_operand:SI 1 "rx_call_operand"   "r,Symbol"))
        (call (mem:QI (match_operand:SI 1 "rx_call_operand"   "r,Symbol"))
              (match_operand:SI         2 "general_operand"   "g,g")))
              (match_operand:SI         2 "general_operand"   "g,g")))
   (clobber (reg:CC CC_REG))]
   (clobber (reg:CC CC_REG))]
  ""
  ""
  "@
  "@
  jsr\t%1
  jsr\t%1
  bsr\t%A1"
  bsr\t%A1"
  [(set_attr "length" "2,4")
  [(set_attr "length" "2,4")
   (set_attr "timings" "33")]
   (set_attr "timings" "33")]
)
)
;; Note - we do not allow indirect sibcalls (with the address
;; Note - we do not allow indirect sibcalls (with the address
;; held in a register) because we cannot guarantee that the register
;; held in a register) because we cannot guarantee that the register
;; chosen will be a call-used one.  If it is a call-saved register,
;; chosen will be a call-used one.  If it is a call-saved register,
;; then the epilogue code will corrupt it by popping the saved value
;; then the epilogue code will corrupt it by popping the saved value
;; off of the stack.
;; off of the stack.
(define_expand "sibcall"
(define_expand "sibcall"
  [(parallel
  [(parallel
    [(call (mem:QI (match_operand:SI 0 "rx_symbolic_call_operand"))
    [(call (mem:QI (match_operand:SI 0 "rx_symbolic_call_operand"))
           (match_operand:SI         1 "general_operand"))
           (match_operand:SI         1 "general_operand"))
     (return)])]
     (return)])]
  ""
  ""
  {
  {
    if (MEM_P (operands[0]))
    if (MEM_P (operands[0]))
      operands[0] = XEXP (operands[0], 0);
      operands[0] = XEXP (operands[0], 0);
  }
  }
)
)
(define_insn "sibcall_internal"
(define_insn "sibcall_internal"
  [(call (mem:QI (match_operand:SI 0 "rx_symbolic_call_operand" "Symbol"))
  [(call (mem:QI (match_operand:SI 0 "rx_symbolic_call_operand" "Symbol"))
         (match_operand:SI         1 "general_operand"          "g"))
         (match_operand:SI         1 "general_operand"          "g"))
   (return)]
   (return)]
  ""
  ""
  "bra\t%A0"
  "bra\t%A0"
  [(set_attr "length"  "4")
  [(set_attr "length"  "4")
   (set_attr "timings" "33")]
   (set_attr "timings" "33")]
)
)
(define_expand "sibcall_value"
(define_expand "sibcall_value"
 [(parallel
 [(parallel
   [(set (match_operand                  0 "register_operand")
   [(set (match_operand                  0 "register_operand")
         (call (mem:QI (match_operand:SI 1 "rx_symbolic_call_operand"))
         (call (mem:QI (match_operand:SI 1 "rx_symbolic_call_operand"))
               (match_operand:SI         2 "general_operand")))
               (match_operand:SI         2 "general_operand")))
    (return)])]
    (return)])]
  ""
  ""
  {
  {
    if (MEM_P (operands[1]))
    if (MEM_P (operands[1]))
      operands[1] = XEXP (operands[1], 0);
      operands[1] = XEXP (operands[1], 0);
  }
  }
)
)
(define_insn "sibcall_value_internal"
(define_insn "sibcall_value_internal"
 [(set (match_operand                  0 "register_operand"         "=r")
 [(set (match_operand                  0 "register_operand"         "=r")
       (call (mem:QI (match_operand:SI 1 "rx_symbolic_call_operand" "Symbol"))
       (call (mem:QI (match_operand:SI 1 "rx_symbolic_call_operand" "Symbol"))
             (match_operand:SI         2 "general_operand"          "g")))
             (match_operand:SI         2 "general_operand"          "g")))
  (return)]
  (return)]
  ""
  ""
  "bra\t%A1"
  "bra\t%A1"
  [(set_attr "length"  "4")
  [(set_attr "length"  "4")
   (set_attr "timings" "33")]
   (set_attr "timings" "33")]
)
)
;; Function Prologue/Epilogue Instructions
;; Function Prologue/Epilogue Instructions
(define_expand "prologue"
(define_expand "prologue"
  [(const_int 0)]
  [(const_int 0)]
  ""
  ""
  "rx_expand_prologue (); DONE;"
  "rx_expand_prologue (); DONE;"
)
)
(define_expand "epilogue"
(define_expand "epilogue"
  [(return)]
  [(return)]
  ""
  ""
  "rx_expand_epilogue (false); DONE;"
  "rx_expand_epilogue (false); DONE;"
)
)
(define_expand "sibcall_epilogue"
(define_expand "sibcall_epilogue"
  [(return)]
  [(return)]
  ""
  ""
  "rx_expand_epilogue (true); DONE;"
  "rx_expand_epilogue (true); DONE;"
)
)
;; Move Instructions
;; Move Instructions
;; Note - we do not allow memory to memory moves, even though the ISA
;; Note - we do not allow memory to memory moves, even though the ISA
;; supports them.  The reason is that the conditions on such moves are
;; supports them.  The reason is that the conditions on such moves are
;; too restrictive, specifically the source addressing mode is limited
;; too restrictive, specifically the source addressing mode is limited
;; by the destination addressing mode and vice versa.  (For example it
;; by the destination addressing mode and vice versa.  (For example it
;; is not possible to use indexed register indirect addressing for one
;; is not possible to use indexed register indirect addressing for one
;; of the operands if the other operand is anything other than a register,
;; of the operands if the other operand is anything other than a register,
;; but it is possible to use register relative addressing when the other
;; but it is possible to use register relative addressing when the other
;; operand also uses register relative or register indirect addressing).
;; operand also uses register relative or register indirect addressing).
;;
;;
;; GCC does not support computing legitimate addresses based on the
;; GCC does not support computing legitimate addresses based on the
;; nature of other operands involved in the instruction, and reload is
;; nature of other operands involved in the instruction, and reload is
;; not smart enough to cope with a whole variety of different memory
;; not smart enough to cope with a whole variety of different memory
;; addressing constraints, so it is simpler and safer to just refuse
;; addressing constraints, so it is simpler and safer to just refuse
;; to support memory to memory moves.
;; to support memory to memory moves.
(define_expand "mov"
(define_expand "mov"
  [(set (match_operand:register_modes 0 "general_operand")
  [(set (match_operand:register_modes 0 "general_operand")
        (match_operand:register_modes 1 "general_operand"))]
        (match_operand:register_modes 1 "general_operand"))]
  ""
  ""
  {
  {
    if (MEM_P (operand0) && MEM_P (operand1))
    if (MEM_P (operand0) && MEM_P (operand1))
      operands[1] = copy_to_mode_reg (mode, operand1);
      operands[1] = copy_to_mode_reg (mode, operand1);
  }
  }
)
)
(define_insn "*mov_internal"
(define_insn "*mov_internal"
  [(set (match_operand:register_modes
  [(set (match_operand:register_modes
         0 "nonimmediate_operand" "=r,r,r,r,r,r,m,Q,Q,Q,Q")
         0 "nonimmediate_operand" "=r,r,r,r,r,r,m,Q,Q,Q,Q")
        (match_operand:register_modes
        (match_operand:register_modes
         1 "general_operand" "Int08,Sint16,Sint24,i,r,m,r,Int08,Sint16,Sint24,i"))]
         1 "general_operand" "Int08,Sint16,Sint24,i,r,m,r,Int08,Sint16,Sint24,i"))]
  ""
  ""
  { return rx_gen_move_template (operands, false); }
  { return rx_gen_move_template (operands, false); }
  [(set_attr "length" "3,4,5,6,2,4,6,5,6,7,8")
  [(set_attr "length" "3,4,5,6,2,4,6,5,6,7,8")
   (set_attr "timings" "11,11,11,11,11,12,11,11,11,11,11")]
   (set_attr "timings" "11,11,11,11,11,12,11,11,11,11,11")]
)
)
(define_insn "extendsi2"
(define_insn "extendsi2"
  [(set (match_operand:SI 0 "register_operand"    "=r,r")
  [(set (match_operand:SI 0 "register_operand"    "=r,r")
        (sign_extend:SI (match_operand:small_int_modes
        (sign_extend:SI (match_operand:small_int_modes
                          1 "nonimmediate_operand" "r,m")))]
                          1 "nonimmediate_operand" "r,m")))]
  ""
  ""
  { return rx_gen_move_template (operands, false); }
  { return rx_gen_move_template (operands, false); }
  [(set_attr "length" "2,6")
  [(set_attr "length" "2,6")
   (set_attr "timings" "11,12")]
   (set_attr "timings" "11,12")]
)
)
(define_insn "zero_extendsi2"
(define_insn "zero_extendsi2"
  [(set (match_operand:SI 0 "register_operand"     "=r,r")
  [(set (match_operand:SI 0 "register_operand"     "=r,r")
        (zero_extend:SI (match_operand:small_int_modes
        (zero_extend:SI (match_operand:small_int_modes
                          1 "nonimmediate_operand"  "r,m")))]
                          1 "nonimmediate_operand"  "r,m")))]
  ""
  ""
  { return rx_gen_move_template (operands, true); }
  { return rx_gen_move_template (operands, true); }
  [(set_attr "length" "2,4")
  [(set_attr "length" "2,4")
   (set_attr "timings" "11,12")]
   (set_attr "timings" "11,12")]
)
)
(define_insn "stack_push"
(define_insn "stack_push"
  [(set:SI (reg:SI SP_REG)
  [(set:SI (reg:SI SP_REG)
           (minus:SI (reg:SI SP_REG)
           (minus:SI (reg:SI SP_REG)
                     (const_int 4)))
                     (const_int 4)))
   (set:SI (mem:SI (reg:SI SP_REG))
   (set:SI (mem:SI (reg:SI SP_REG))
           (match_operand:SI 0 "register_operand" "r"))]
           (match_operand:SI 0 "register_operand" "r"))]
  ""
  ""
  "push.l\t%0"
  "push.l\t%0"
  [(set_attr "length" "2")]
  [(set_attr "length" "2")]
)
)
(define_insn "stack_pushm"
(define_insn "stack_pushm"
  [(match_parallel 1 "rx_store_multiple_vector"
  [(match_parallel 1 "rx_store_multiple_vector"
                   [(set:SI (reg:SI SP_REG)
                   [(set:SI (reg:SI SP_REG)
                            (minus:SI (reg:SI SP_REG)
                            (minus:SI (reg:SI SP_REG)
                                      (match_operand:SI 0 "const_int_operand" "n")))])]
                                      (match_operand:SI 0 "const_int_operand" "n")))])]
  "reload_completed"
  "reload_completed"
  {
  {
    rx_emit_stack_pushm (operands);
    rx_emit_stack_pushm (operands);
    return "";
    return "";
  }
  }
  [(set_attr "length" "2")
  [(set_attr "length" "2")
   (set_attr "timings" "44")] ;; The timing is a guesstimate average timing.
   (set_attr "timings" "44")] ;; The timing is a guesstimate average timing.
)
)
(define_insn "stack_pop"
(define_insn "stack_pop"
  [(set:SI (match_operand:SI 0 "register_operand" "=r")
  [(set:SI (match_operand:SI 0 "register_operand" "=r")
           (mem:SI (reg:SI SP_REG)))
           (mem:SI (reg:SI SP_REG)))
   (set:SI (reg:SI SP_REG)
   (set:SI (reg:SI SP_REG)
           (plus:SI (reg:SI SP_REG)
           (plus:SI (reg:SI SP_REG)
                    (const_int 4)))]
                    (const_int 4)))]
  ""
  ""
  "pop\t%0"
  "pop\t%0"
  [(set_attr "length" "2")
  [(set_attr "length" "2")
   (set_attr "timings" "12")]
   (set_attr "timings" "12")]
)
)
(define_insn "stack_popm"
(define_insn "stack_popm"
  [(match_parallel 1 "rx_load_multiple_vector"
  [(match_parallel 1 "rx_load_multiple_vector"
                   [(set:SI (reg:SI SP_REG)
                   [(set:SI (reg:SI SP_REG)
                            (plus:SI (reg:SI SP_REG)
                            (plus:SI (reg:SI SP_REG)
                                     (match_operand:SI 0 "const_int_operand" "n")))])]
                                     (match_operand:SI 0 "const_int_operand" "n")))])]
  "reload_completed"
  "reload_completed"
  {
  {
    rx_emit_stack_popm (operands, true);
    rx_emit_stack_popm (operands, true);
    return "";
    return "";
  }
  }
  [(set_attr "length" "2")
  [(set_attr "length" "2")
   (set_attr "timings" "45")] ;; The timing is a guesstimate average timing.
   (set_attr "timings" "45")] ;; The timing is a guesstimate average timing.
)
)
;; FIXME: Add memory destination options ?
;; FIXME: Add memory destination options ?
(define_insn "cstoresi4"
(define_insn "cstoresi4"
  [(set (match_operand:SI   0 "register_operand" "=r,r,r,r,r,r,r")
  [(set (match_operand:SI   0 "register_operand" "=r,r,r,r,r,r,r")
        (match_operator:SI  1 "comparison_operator"
        (match_operator:SI  1 "comparison_operator"
         [(match_operand:SI 2 "register_operand"  "r,r,r,r,r,r,r")
         [(match_operand:SI 2 "register_operand"  "r,r,r,r,r,r,r")
          (match_operand:SI 3 "rx_source_operand" "r,Uint04,Int08,Sint16,Sint24,i,Q")]))
          (match_operand:SI 3 "rx_source_operand" "r,Uint04,Int08,Sint16,Sint24,i,Q")]))
   (clobber (reg:CC CC_REG))] ;; Because the cc flags are set based on comparing ops 2 & 3 not the value in op 0.
   (clobber (reg:CC CC_REG))] ;; Because the cc flags are set based on comparing ops 2 & 3 not the value in op 0.
  ""
  ""
  {
  {
    rx_float_compare_mode = false;
    rx_float_compare_mode = false;
    return "cmp\t%Q3, %Q2\n\tsc%B1.L\t%0";
    return "cmp\t%Q3, %Q2\n\tsc%B1.L\t%0";
  }
  }
  [(set_attr "timings" "22,22,22,22,22,22,44")
  [(set_attr "timings" "22,22,22,22,22,22,44")
   (set_attr "length"  "5,5,6,7,8,9,8")]
   (set_attr "length"  "5,5,6,7,8,9,8")]
)
)
(define_expand "movsicc"
(define_expand "movsicc"
  [(parallel
  [(parallel
    [(set (match_operand:SI                  0 "register_operand")
    [(set (match_operand:SI                  0 "register_operand")
          (if_then_else:SI (match_operand:SI 1 "comparison_operator")
          (if_then_else:SI (match_operand:SI 1 "comparison_operator")
                           (match_operand:SI 2 "nonmemory_operand")
                           (match_operand:SI 2 "nonmemory_operand")
                           (match_operand:SI 3 "immediate_operand")))
                           (match_operand:SI 3 "immediate_operand")))
     (clobber (reg:CC CC_REG))])] ;; See cstoresi4
     (clobber (reg:CC CC_REG))])] ;; See cstoresi4
  ""
  ""
  {
  {
    if (GET_CODE (operands[1]) != EQ && GET_CODE (operands[1]) != NE)
    if (GET_CODE (operands[1]) != EQ && GET_CODE (operands[1]) != NE)
      FAIL;
      FAIL;
    if (! CONST_INT_P (operands[3]))
    if (! CONST_INT_P (operands[3]))
      FAIL;
      FAIL;
  }
  }
)
)
(define_insn "*movsieq"
(define_insn "*movsieq"
  [(set (match_operand:SI                      0 "register_operand" "=r,r,r")
  [(set (match_operand:SI                      0 "register_operand" "=r,r,r")
        (if_then_else:SI (eq (match_operand:SI 3 "register_operand"  "r,r,r")
        (if_then_else:SI (eq (match_operand:SI 3 "register_operand"  "r,r,r")
                             (match_operand:SI 4 "rx_source_operand" "riQ,riQ,riQ"))
                             (match_operand:SI 4 "rx_source_operand" "riQ,riQ,riQ"))
                         (match_operand:SI     1 "nonmemory_operand" "0,i,r")
                         (match_operand:SI     1 "nonmemory_operand" "0,i,r")
                         (match_operand:SI     2 "immediate_operand" "i,i,i")))
                         (match_operand:SI     2 "immediate_operand" "i,i,i")))
   (clobber (reg:CC CC_REG))] ;; See cstoresi4
   (clobber (reg:CC CC_REG))] ;; See cstoresi4
  ""
  ""
  "@
  "@
  cmp\t%Q4, %Q3\n\tstnz\t%2, %0
  cmp\t%Q4, %Q3\n\tstnz\t%2, %0
  cmp\t%Q4, %Q3\n\tmov.l\t%2, %0\n\tstz\t%1, %0
  cmp\t%Q4, %Q3\n\tmov.l\t%2, %0\n\tstz\t%1, %0
  cmp\t%Q4, %Q3\n\tmov.l\t%1, %0\n\tstnz\t%2, %0"
  cmp\t%Q4, %Q3\n\tmov.l\t%1, %0\n\tstnz\t%2, %0"
  [(set_attr "length"  "13,19,15")
  [(set_attr "length"  "13,19,15")
   (set_attr "timings" "22,33,33")]
   (set_attr "timings" "22,33,33")]
)
)
(define_insn "*movsine"
(define_insn "*movsine"
  [(set (match_operand:SI                      0 "register_operand" "=r,r,r")
  [(set (match_operand:SI                      0 "register_operand" "=r,r,r")
        (if_then_else:SI (ne (match_operand:SI 3 "register_operand"  "r,r,r")
        (if_then_else:SI (ne (match_operand:SI 3 "register_operand"  "r,r,r")
                             (match_operand:SI 4 "rx_source_operand" "riQ,riQ,riQ"))
                             (match_operand:SI 4 "rx_source_operand" "riQ,riQ,riQ"))
                         (match_operand:SI     1 "nonmemory_operand" "0,i,r")
                         (match_operand:SI     1 "nonmemory_operand" "0,i,r")
                         (match_operand:SI     2 "immediate_operand" "i,i,i")))
                         (match_operand:SI     2 "immediate_operand" "i,i,i")))
   (clobber (reg:CC CC_REG))] ;; See cstoresi4
   (clobber (reg:CC CC_REG))] ;; See cstoresi4
  ""
  ""
  "@
  "@
  cmp\t%Q4, %Q3\n\tstz\t%2, %0
  cmp\t%Q4, %Q3\n\tstz\t%2, %0
  cmp\t%Q4, %Q3\n\tmov.l\t%2, %0\n\tstnz\t%1, %0
  cmp\t%Q4, %Q3\n\tmov.l\t%2, %0\n\tstnz\t%1, %0
  cmp\t%Q4, %Q3\n\tmov.l\t%1, %0\n\tstz\t%2, %0"
  cmp\t%Q4, %Q3\n\tmov.l\t%1, %0\n\tstz\t%2, %0"
  [(set_attr "length"  "13,19,15")
  [(set_attr "length"  "13,19,15")
   (set_attr "timings" "22,33,33")]
   (set_attr "timings" "22,33,33")]
)
)
;; Arithmetic Instructions
;; Arithmetic Instructions
(define_insn "abssi2"
(define_insn "abssi2"
  [(set (match_operand:SI         0 "register_operand" "=r,r")
  [(set (match_operand:SI         0 "register_operand" "=r,r")
        (abs:SI (match_operand:SI 1 "register_operand"  "0,r")))
        (abs:SI (match_operand:SI 1 "register_operand"  "0,r")))
   (set (reg:CC_ZSO CC_REG)
   (set (reg:CC_ZSO CC_REG)
        (compare:CC_ZSO (abs:SI (match_dup 1))
        (compare:CC_ZSO (abs:SI (match_dup 1))
                        (const_int 0)))]
                        (const_int 0)))]
  ""
  ""
  "@
  "@
  abs\t%0
  abs\t%0
  abs\t%1, %0"
  abs\t%1, %0"
  [(set_attr "length" "2,3")]
  [(set_attr "length" "2,3")]
)
)
(define_insn "addsi3"
(define_insn "addsi3"
  [(set (match_operand:SI          0 "register_operand"  "=r,r,r,r,r,r,r,r,r,r,r,r,r,r")
  [(set (match_operand:SI          0 "register_operand"  "=r,r,r,r,r,r,r,r,r,r,r,r,r,r")
        (plus:SI (match_operand:SI 1 "register_operand"  "%0,0,0,0,0,0,0,r,r,r,r,r,r,0")
        (plus:SI (match_operand:SI 1 "register_operand"  "%0,0,0,0,0,0,0,r,r,r,r,r,r,0")
                 (match_operand:SI 2 "rx_source_operand" "r,Uint04,NEGint4,Sint08,Sint16,Sint24,i,0,r,Sint08,Sint16,Sint24,i,Q")))
                 (match_operand:SI 2 "rx_source_operand" "r,Uint04,NEGint4,Sint08,Sint16,Sint24,i,0,r,Sint08,Sint16,Sint24,i,Q")))
   (set (reg:CC_ZSC CC_REG) ;; See subsi3
   (set (reg:CC_ZSC CC_REG) ;; See subsi3
        (compare:CC_ZSC (plus:SI (match_dup 1) (match_dup 2))
        (compare:CC_ZSC (plus:SI (match_dup 1) (match_dup 2))
                        (const_int 0)))]
                        (const_int 0)))]
  ""
  ""
  "@
  "@
  add\t%2, %0
  add\t%2, %0
  add\t%2, %0
  add\t%2, %0
  sub\t%N2, %0
  sub\t%N2, %0
  add\t%2, %0
  add\t%2, %0
  add\t%2, %0
  add\t%2, %0
  add\t%2, %0
  add\t%2, %0
  add\t%2, %0
  add\t%2, %0
  add\t%1, %0
  add\t%1, %0
  add\t%2, %1, %0
  add\t%2, %1, %0
  add\t%2, %1, %0
  add\t%2, %1, %0
  add\t%2, %1, %0
  add\t%2, %1, %0
  add\t%2, %1, %0
  add\t%2, %1, %0
  add\t%2, %1, %0
  add\t%2, %1, %0
  add\t%Q2, %0"
  add\t%Q2, %0"
  [(set_attr "timings" "11,11,11,11,11,11,11,11,11,11,11,11,11,33")
  [(set_attr "timings" "11,11,11,11,11,11,11,11,11,11,11,11,11,33")
   (set_attr "length"   "2,2,2,3,4,5,6,2,3,3,4,5,6,5")]
   (set_attr "length"   "2,2,2,3,4,5,6,2,3,3,4,5,6,5")]
)
)
(define_insn "adddi3"
(define_insn "adddi3"
  [(set (match_operand:DI          0 "register_operand" "=r,r,r,r,r,r")
  [(set (match_operand:DI          0 "register_operand" "=r,r,r,r,r,r")
        (plus:DI (match_operand:DI 1 "register_operand" "%0,0,0,0,0,0")
        (plus:DI (match_operand:DI 1 "register_operand" "%0,0,0,0,0,0")
                 (match_operand:DI 2 "rx_source_operand"
                 (match_operand:DI 2 "rx_source_operand"
                                   "r,Sint08,Sint16,Sint24,i,Q")))
                                   "r,Sint08,Sint16,Sint24,i,Q")))
   (set (reg:CC_ZSC CC_REG) ;; See subsi3
   (set (reg:CC_ZSC CC_REG) ;; See subsi3
        (compare:CC_ZSC (plus:DI (match_dup 1) (match_dup 2))
        (compare:CC_ZSC (plus:DI (match_dup 1) (match_dup 2))
                        (const_int 0)))]
                        (const_int 0)))]
  ""
  ""
  "add\t%L2, %L0\n\tadc\t%H2, %H0"
  "add\t%L2, %L0\n\tadc\t%H2, %H0"
  [(set_attr "timings" "22,22,22,22,22,44")
  [(set_attr "timings" "22,22,22,22,22,44")
   (set_attr "length" "5,7,9,11,13,11")]
   (set_attr "length" "5,7,9,11,13,11")]
)
)
(define_insn "andsi3"
(define_insn "andsi3"
  [(set (match_operand:SI         0 "register_operand"  "=r,r,r,r,r,r,r,r,r")
  [(set (match_operand:SI         0 "register_operand"  "=r,r,r,r,r,r,r,r,r")
        (and:SI (match_operand:SI 1 "register_operand"  "%0,0,0,0,0,0,r,r,0")
        (and:SI (match_operand:SI 1 "register_operand"  "%0,0,0,0,0,0,r,r,0")
                (match_operand:SI 2 "rx_source_operand" "r,Uint04,Sint08,Sint16,Sint24,i,0,r,Q")))
                (match_operand:SI 2 "rx_source_operand" "r,Uint04,Sint08,Sint16,Sint24,i,0,r,Q")))
   (set (reg:CC_ZS CC_REG)
   (set (reg:CC_ZS CC_REG)
        (compare:CC_ZS (and:SI (match_dup 1) (match_dup 2))
        (compare:CC_ZS (and:SI (match_dup 1) (match_dup 2))
                       (const_int 0)))]
                       (const_int 0)))]
  ""
  ""
  "@
  "@
  and\t%2, %0
  and\t%2, %0
  and\t%2, %0
  and\t%2, %0
  and\t%2, %0
  and\t%2, %0
  and\t%2, %0
  and\t%2, %0
  and\t%2, %0
  and\t%2, %0
  and\t%2, %0
  and\t%2, %0
  and\t%1, %0
  and\t%1, %0
  and\t%2, %1, %0
  and\t%2, %1, %0
  and\t%Q2, %0"
  and\t%Q2, %0"
  [(set_attr "timings" "11,11,11,11,11,11,11,33,33")
  [(set_attr "timings" "11,11,11,11,11,11,11,33,33")
   (set_attr "length" "2,2,3,4,5,6,2,5,5")]
   (set_attr "length" "2,2,3,4,5,6,2,5,5")]
)
)
;; Byte swap (single 32-bit value).
;; Byte swap (single 32-bit value).
(define_insn "bswapsi2"
(define_insn "bswapsi2"
  [(set (match_operand:SI           0 "register_operand" "+r")
  [(set (match_operand:SI           0 "register_operand" "+r")
        (bswap:SI (match_operand:SI 1 "register_operand"  "r")))]
        (bswap:SI (match_operand:SI 1 "register_operand"  "r")))]
  ""
  ""
  "revl\t%1, %0"
  "revl\t%1, %0"
  [(set_attr "length" "3")]
  [(set_attr "length" "3")]
)
)
;; Byte swap (single 16-bit value).  Note - we ignore the swapping of the high 16-bits.
;; Byte swap (single 16-bit value).  Note - we ignore the swapping of the high 16-bits.
(define_insn "bswaphi2"
(define_insn "bswaphi2"
  [(set (match_operand:HI           0 "register_operand" "+r")
  [(set (match_operand:HI           0 "register_operand" "+r")
        (bswap:HI (match_operand:HI 1 "register_operand"  "r")))]
        (bswap:HI (match_operand:HI 1 "register_operand"  "r")))]
  ""
  ""
  "revw\t%1, %0"
  "revw\t%1, %0"
  [(set_attr "length" "3")]
  [(set_attr "length" "3")]
)
)
(define_insn "divsi3"
(define_insn "divsi3"
  [(set (match_operand:SI         0 "register_operand" "=r,r,r,r,r,r")
  [(set (match_operand:SI         0 "register_operand" "=r,r,r,r,r,r")
        (div:SI (match_operand:SI 1 "register_operand"  "0,0,0,0,0,0")
        (div:SI (match_operand:SI 1 "register_operand"  "0,0,0,0,0,0")
                (match_operand:SI 2 "rx_source_operand" "r,Sint08,Sint16,Sint24,i,Q")))
                (match_operand:SI 2 "rx_source_operand" "r,Sint08,Sint16,Sint24,i,Q")))
   (clobber (reg:CC CC_REG))]
   (clobber (reg:CC CC_REG))]
  ""
  ""
  "div\t%Q2, %0"
  "div\t%Q2, %0"
  [(set_attr "timings" "1111") ;; Strictly speaking the timing should be
  [(set_attr "timings" "1111") ;; Strictly speaking the timing should be
                               ;; 2222, but that is a worst case sceanario.
                               ;; 2222, but that is a worst case sceanario.
   (set_attr "length" "3,4,5,6,7,6")]
   (set_attr "length" "3,4,5,6,7,6")]
)
)
(define_insn "udivsi3"
(define_insn "udivsi3"
  [(set (match_operand:SI          0 "register_operand"  "=r,r,r,r,r,r")
  [(set (match_operand:SI          0 "register_operand"  "=r,r,r,r,r,r")
        (udiv:SI (match_operand:SI 1 "register_operand"   "0,0,0,0,0,0")
        (udiv:SI (match_operand:SI 1 "register_operand"   "0,0,0,0,0,0")
                 (match_operand:SI 2 "rx_source_operand"  "r,Sint08,Sint16,Sint24,i,Q")))
                 (match_operand:SI 2 "rx_source_operand"  "r,Sint08,Sint16,Sint24,i,Q")))
   (clobber (reg:CC CC_REG))]
   (clobber (reg:CC CC_REG))]
  ""
  ""
  "divu\t%Q2, %0"
  "divu\t%Q2, %0"
  [(set_attr "timings" "1010") ;; Strictly speaking the timing should be
  [(set_attr "timings" "1010") ;; Strictly speaking the timing should be
                               ;; 2020, but that is a worst case sceanario.
                               ;; 2020, but that is a worst case sceanario.
   (set_attr "length" "3,4,5,6,7,6")]
   (set_attr "length" "3,4,5,6,7,6")]
)
)
;; Note - these patterns are suppressed in big-endian mode because they
;; Note - these patterns are suppressed in big-endian mode because they
;; generate a little endian result.  ie the most significant word of the
;; generate a little endian result.  ie the most significant word of the
;; result is placed in the higher numbered register of the destination
;; result is placed in the higher numbered register of the destination
;; register pair.
;; register pair.
(define_insn "mulsidi3"
(define_insn "mulsidi3"
  [(set (match_operand:DI          0 "register_operand"  "=r,r,r,r,r,r")
  [(set (match_operand:DI          0 "register_operand"  "=r,r,r,r,r,r")
        (mult:DI (sign_extend:DI (match_operand:SI
        (mult:DI (sign_extend:DI (match_operand:SI
                                  1 "register_operand"  "%0,0,0,0,0,0"))
                                  1 "register_operand"  "%0,0,0,0,0,0"))
                 (sign_extend:DI (match_operand:SI
                 (sign_extend:DI (match_operand:SI
                                  2 "rx_source_operand"
                                  2 "rx_source_operand"
                                  "r,Sint08,Sint16,Sint24,i,Q"))))]
                                  "r,Sint08,Sint16,Sint24,i,Q"))))]
  "! TARGET_BIG_ENDIAN_DATA"
  "! TARGET_BIG_ENDIAN_DATA"
  "emul\t%Q2, %0"
  "emul\t%Q2, %0"
  [(set_attr "length" "3,4,5,6,7,6")
  [(set_attr "length" "3,4,5,6,7,6")
   (set_attr "timings" "22,22,22,22,22,44")]
   (set_attr "timings" "22,22,22,22,22,44")]
)
)
;; See comment for mulsidi3.
;; See comment for mulsidi3.
;; Note - the zero_extends are to distinguish this pattern from the
;; Note - the zero_extends are to distinguish this pattern from the
;; mulsidi3 pattern.  Immediate mode addressing is not supported
;; mulsidi3 pattern.  Immediate mode addressing is not supported
;; because gcc cannot handle the expression: (zero_extend (const_int)).
;; because gcc cannot handle the expression: (zero_extend (const_int)).
(define_insn "umulsidi3"
(define_insn "umulsidi3"
  [(set (match_operand:DI                          0 "register_operand"  "=r,r")
  [(set (match_operand:DI                          0 "register_operand"  "=r,r")
        (mult:DI (zero_extend:DI (match_operand:SI 1 "register_operand"  "%0,0"))
        (mult:DI (zero_extend:DI (match_operand:SI 1 "register_operand"  "%0,0"))
                 (zero_extend:DI (match_operand:SI 2 "rx_compare_operand" "r,Q"))))]
                 (zero_extend:DI (match_operand:SI 2 "rx_compare_operand" "r,Q"))))]
  "! TARGET_BIG_ENDIAN_DATA"
  "! TARGET_BIG_ENDIAN_DATA"
  "emulu\t%Q2, %0"
  "emulu\t%Q2, %0"
  [(set_attr "length" "3,6")
  [(set_attr "length" "3,6")
   (set_attr "timings" "22,44")]
   (set_attr "timings" "22,44")]
)
)
(define_insn "smaxsi3"
(define_insn "smaxsi3"
  [(set (match_operand:SI          0 "register_operand" "=r,r,r,r,r,r")
  [(set (match_operand:SI          0 "register_operand" "=r,r,r,r,r,r")
        (smax:SI (match_operand:SI 1 "register_operand" "%0,0,0,0,0,0")
        (smax:SI (match_operand:SI 1 "register_operand" "%0,0,0,0,0,0")
                 (match_operand:SI 2 "rx_source_operand"
                 (match_operand:SI 2 "rx_source_operand"
                                   "r,Sint08,Sint16,Sint24,i,Q")))]
                                   "r,Sint08,Sint16,Sint24,i,Q")))]
  ""
  ""
  "max\t%Q2, %0"
  "max\t%Q2, %0"
  [(set_attr "length" "3,4,5,6,7,6")
  [(set_attr "length" "3,4,5,6,7,6")
   (set_attr "timings" "11,11,11,11,11,33")]
   (set_attr "timings" "11,11,11,11,11,33")]
)
)
(define_insn "sminsi3"
(define_insn "sminsi3"
  [(set (match_operand:SI          0 "register_operand" "=r,r,r,r,r,r")
  [(set (match_operand:SI          0 "register_operand" "=r,r,r,r,r,r")
        (smin:SI (match_operand:SI 1 "register_operand" "%0,0,0,0,0,0")
        (smin:SI (match_operand:SI 1 "register_operand" "%0,0,0,0,0,0")
                 (match_operand:SI 2 "rx_source_operand"
                 (match_operand:SI 2 "rx_source_operand"
                                   "r,Sint08,Sint16,Sint24,i,Q")))]
                                   "r,Sint08,Sint16,Sint24,i,Q")))]
  ""
  ""
  "min\t%Q2, %0"
  "min\t%Q2, %0"
  [(set_attr "length"  "3,4,5,6,7,6")
  [(set_attr "length"  "3,4,5,6,7,6")
   (set_attr "timings" "11,11,11,11,11,33")]
   (set_attr "timings" "11,11,11,11,11,33")]
)
)
(define_insn "mulsi3"
(define_insn "mulsi3"
  [(set (match_operand:SI          0 "register_operand" "=r,r,r,r,r,r,r,r,r")
  [(set (match_operand:SI          0 "register_operand" "=r,r,r,r,r,r,r,r,r")
        (mult:SI (match_operand:SI 1 "register_operand" "%0,0,0,0,0,0,0,r,r")
        (mult:SI (match_operand:SI 1 "register_operand" "%0,0,0,0,0,0,0,r,r")
                 (match_operand:SI 2 "rx_source_operand"
                 (match_operand:SI 2 "rx_source_operand"
                                   "r,Uint04,Sint08,Sint16,Sint24,i,Q,0,r")))]
                                   "r,Uint04,Sint08,Sint16,Sint24,i,Q,0,r")))]
  ""
  ""
  "@
  "@
  mul\t%2, %0
  mul\t%2, %0
  mul\t%2, %0
  mul\t%2, %0
  mul\t%2, %0
  mul\t%2, %0
  mul\t%2, %0
  mul\t%2, %0
  mul\t%2, %0
  mul\t%2, %0
  mul\t%Q2, %0
  mul\t%Q2, %0
  mul\t%Q2, %0
  mul\t%Q2, %0
  mul\t%1, %0
  mul\t%1, %0
  mul\t%2, %1, %0"
  mul\t%2, %1, %0"
  [(set_attr "length"  "2,2,3,4,5,6,5,2,3")
  [(set_attr "length"  "2,2,3,4,5,6,5,2,3")
   (set_attr "timings" "11,11,11,11,11,11,33,11,11")]
   (set_attr "timings" "11,11,11,11,11,11,33,11,11")]
)
)
(define_insn "negsi2"
(define_insn "negsi2"
  [(set (match_operand:SI         0 "register_operand" "=r,r")
  [(set (match_operand:SI         0 "register_operand" "=r,r")
        (neg:SI (match_operand:SI 1 "register_operand"  "0,r")))
        (neg:SI (match_operand:SI 1 "register_operand"  "0,r")))
   (set (reg:CC CC_REG)
   (set (reg:CC CC_REG)
        (compare:CC (neg:SI (match_dup 1))
        (compare:CC (neg:SI (match_dup 1))
                    (const_int 0)))]
                    (const_int 0)))]
  ;; The NEG instruction does not comply with -fwrapv semantics.
  ;; The NEG instruction does not comply with -fwrapv semantics.
  ;; See gcc.c-torture/execute/pr22493-1.c for an example of this.
  ;; See gcc.c-torture/execute/pr22493-1.c for an example of this.
  "! flag_wrapv"
  "! flag_wrapv"
  "@
  "@
  neg\t%0
  neg\t%0
  neg\t%1, %0"
  neg\t%1, %0"
  [(set_attr "length" "2,3")]
  [(set_attr "length" "2,3")]
)
)
(define_insn "one_cmplsi2"
(define_insn "one_cmplsi2"
  [(set (match_operand:SI         0 "register_operand" "=r,r")
  [(set (match_operand:SI         0 "register_operand" "=r,r")
        (not:SI (match_operand:SI 1 "register_operand"  "0,r")))
        (not:SI (match_operand:SI 1 "register_operand"  "0,r")))
   (set (reg:CC_ZS CC_REG)
   (set (reg:CC_ZS CC_REG)
        (compare:CC_ZS (not:SI (match_dup 1))
        (compare:CC_ZS (not:SI (match_dup 1))
                       (const_int 0)))]
                       (const_int 0)))]
  ""
  ""
  "@
  "@
  not\t%0
  not\t%0
  not\t%1, %0"
  not\t%1, %0"
  [(set_attr "length" "2,3")]
  [(set_attr "length" "2,3")]
)
)
(define_insn "iorsi3"
(define_insn "iorsi3"
  [(set (match_operand:SI         0 "register_operand" "=r,r,r,r,r,r,r,r,r")
  [(set (match_operand:SI         0 "register_operand" "=r,r,r,r,r,r,r,r,r")
        (ior:SI (match_operand:SI 1 "register_operand" "%0,0,0,0,0,0,r,r,0")
        (ior:SI (match_operand:SI 1 "register_operand" "%0,0,0,0,0,0,r,r,0")
                (match_operand:SI 2 "rx_source_operand" "r,Uint04,Sint08,Sint16,Sint24,i,0,r,Q")))
                (match_operand:SI 2 "rx_source_operand" "r,Uint04,Sint08,Sint16,Sint24,i,0,r,Q")))
   (set (reg:CC_ZS CC_REG)
   (set (reg:CC_ZS CC_REG)
        (compare:CC_ZS (ior:SI (match_dup 1) (match_dup 2))
        (compare:CC_ZS (ior:SI (match_dup 1) (match_dup 2))
                       (const_int 0)))]
                       (const_int 0)))]
  ""
  ""
  "@
  "@
  or\t%2, %0
  or\t%2, %0
  or\t%2, %0
  or\t%2, %0
  or\t%2, %0
  or\t%2, %0
  or\t%2, %0
  or\t%2, %0
  or\t%2, %0
  or\t%2, %0
  or\t%Q2, %0
  or\t%Q2, %0
  or\t%1, %0
  or\t%1, %0
  or\t%2, %1, %0
  or\t%2, %1, %0
  or\t%Q2, %0"
  or\t%Q2, %0"
  [(set_attr "timings" "11,11,11,11,11,11,11,11,33")
  [(set_attr "timings" "11,11,11,11,11,11,11,11,33")
   (set_attr "length"  "2,2,3,4,5,6,2,3,5")]
   (set_attr "length"  "2,2,3,4,5,6,2,3,5")]
)
)
(define_insn "rotlsi3"
(define_insn "rotlsi3"
  [(set (match_operand:SI            0 "register_operand" "=r")
  [(set (match_operand:SI            0 "register_operand" "=r")
        (rotate:SI (match_operand:SI 1 "register_operand"  "0")
        (rotate:SI (match_operand:SI 1 "register_operand"  "0")
                   (match_operand:SI 2 "rx_shift_operand" "rn")))
                   (match_operand:SI 2 "rx_shift_operand" "rn")))
   (set (reg:CC_ZS CC_REG)
   (set (reg:CC_ZS CC_REG)
        (compare:CC_ZS (rotate:SI (match_dup 1) (match_dup 2))
        (compare:CC_ZS (rotate:SI (match_dup 1) (match_dup 2))
                       (const_int 0)))]
                       (const_int 0)))]
  ""
  ""
  "rotl\t%2, %0"
  "rotl\t%2, %0"
  [(set_attr "length" "3")]
  [(set_attr "length" "3")]
)
)
(define_insn "rotrsi3"
(define_insn "rotrsi3"
  [(set (match_operand:SI              0 "register_operand" "=r")
  [(set (match_operand:SI              0 "register_operand" "=r")
        (rotatert:SI (match_operand:SI 1 "register_operand"  "0")
        (rotatert:SI (match_operand:SI 1 "register_operand"  "0")
                     (match_operand:SI 2 "rx_shift_operand" "rn")))
                     (match_operand:SI 2 "rx_shift_operand" "rn")))
   (set (reg:CC_ZS CC_REG)
   (set (reg:CC_ZS CC_REG)
        (compare:CC_ZS (rotatert:SI (match_dup 1) (match_dup 2))
        (compare:CC_ZS (rotatert:SI (match_dup 1) (match_dup 2))
                       (const_int 0)))]
                       (const_int 0)))]
  ""
  ""
  "rotr\t%2, %0"
  "rotr\t%2, %0"
  [(set_attr "length" "3")]
  [(set_attr "length" "3")]
)
)
(define_insn "ashrsi3"
(define_insn "ashrsi3"
  [(set (match_operand:SI              0 "register_operand" "=r,r,r")
  [(set (match_operand:SI              0 "register_operand" "=r,r,r")
        (ashiftrt:SI (match_operand:SI 1 "register_operand"  "0,0,r")
        (ashiftrt:SI (match_operand:SI 1 "register_operand"  "0,0,r")
                     (match_operand:SI 2 "rx_shift_operand"  "r,n,n")))
                     (match_operand:SI 2 "rx_shift_operand"  "r,n,n")))
   (set (reg:CC_ZS CC_REG)
   (set (reg:CC_ZS CC_REG)
        (compare:CC_ZS (ashiftrt:SI (match_dup 1) (match_dup 2))
        (compare:CC_ZS (ashiftrt:SI (match_dup 1) (match_dup 2))
                       (const_int 0)))]
                       (const_int 0)))]
  ""
  ""
  "@
  "@
  shar\t%2, %0
  shar\t%2, %0
  shar\t%2, %0
  shar\t%2, %0
  shar\t%2, %1, %0"
  shar\t%2, %1, %0"
  [(set_attr "length" "3,2,3")]
  [(set_attr "length" "3,2,3")]
)
)
(define_insn "lshrsi3"
(define_insn "lshrsi3"
  [(set (match_operand:SI              0 "register_operand" "=r,r,r")
  [(set (match_operand:SI              0 "register_operand" "=r,r,r")
        (lshiftrt:SI (match_operand:SI 1 "register_operand"  "0,0,r")
        (lshiftrt:SI (match_operand:SI 1 "register_operand"  "0,0,r")
                     (match_operand:SI 2 "rx_shift_operand"  "r,n,n")))
                     (match_operand:SI 2 "rx_shift_operand"  "r,n,n")))
   (set (reg:CC_ZS CC_REG)
   (set (reg:CC_ZS CC_REG)
        (compare:CC_ZS (lshiftrt:SI (match_dup 1) (match_dup 2))
        (compare:CC_ZS (lshiftrt:SI (match_dup 1) (match_dup 2))
                       (const_int 0)))]
                       (const_int 0)))]
  ""
  ""
  "@
  "@
  shlr\t%2, %0
  shlr\t%2, %0
  shlr\t%2, %0
  shlr\t%2, %0
  shlr\t%2, %1, %0"
  shlr\t%2, %1, %0"
  [(set_attr "length" "3,2,3")]
  [(set_attr "length" "3,2,3")]
)
)
(define_insn "ashlsi3"
(define_insn "ashlsi3"
  [(set (match_operand:SI            0 "register_operand" "=r,r,r")
  [(set (match_operand:SI            0 "register_operand" "=r,r,r")
        (ashift:SI (match_operand:SI 1 "register_operand"  "0,0,r")
        (ashift:SI (match_operand:SI 1 "register_operand"  "0,0,r")
                   (match_operand:SI 2 "rx_shift_operand"  "r,n,n")))
                   (match_operand:SI 2 "rx_shift_operand"  "r,n,n")))
   (set (reg:CC_ZS CC_REG)
   (set (reg:CC_ZS CC_REG)
        (compare:CC_ZS (ashift:SI (match_dup 1) (match_dup 2))
        (compare:CC_ZS (ashift:SI (match_dup 1) (match_dup 2))
                       (const_int 0)))]
                       (const_int 0)))]
  ""
  ""
  "@
  "@
  shll\t%2, %0
  shll\t%2, %0
  shll\t%2, %0
  shll\t%2, %0
  shll\t%2, %1, %0"
  shll\t%2, %1, %0"
  [(set_attr "length" "3,2,3")]
  [(set_attr "length" "3,2,3")]
)
)
(define_insn "subsi3"
(define_insn "subsi3"
  [(set (match_operand:SI           0 "register_operand" "=r,r,r,r,r")
  [(set (match_operand:SI           0 "register_operand" "=r,r,r,r,r")
        (minus:SI (match_operand:SI 1 "register_operand"  "0,0,0,r,0")
        (minus:SI (match_operand:SI 1 "register_operand"  "0,0,0,r,0")
                  (match_operand:SI 2 "rx_source_operand" "r,Uint04,n,r,Q")))
                  (match_operand:SI 2 "rx_source_operand" "r,Uint04,n,r,Q")))
   (set (reg:CC_ZSC CC_REG)
   (set (reg:CC_ZSC CC_REG)
        ;; Note - we do not acknowledge that the SUB instruction sets the Overflow
        ;; Note - we do not acknowledge that the SUB instruction sets the Overflow
        ;; flag because its interpretation is different from comparing the result
        ;; flag because its interpretation is different from comparing the result
        ;; against zero.  Compile and run gcc.c-torture/execute/cmpsi-1.c to see this.
        ;; against zero.  Compile and run gcc.c-torture/execute/cmpsi-1.c to see this.
        (compare:CC_ZSC (minus:SI (match_dup 1) (match_dup 2))
        (compare:CC_ZSC (minus:SI (match_dup 1) (match_dup 2))
                        (const_int 0)))]
                        (const_int 0)))]
  ""
  ""
  "@
  "@
  sub\t%2, %0
  sub\t%2, %0
  sub\t%2, %0
  sub\t%2, %0
  add\t%N2, %0
  add\t%N2, %0
  sub\t%2, %1, %0
  sub\t%2, %1, %0
  sub\t%Q2, %0"
  sub\t%Q2, %0"
  [(set_attr "timings" "11,11,11,11,33")
  [(set_attr "timings" "11,11,11,11,33")
   (set_attr "length" "2,2,6,3,5")]
   (set_attr "length" "2,2,6,3,5")]
)
)
(define_insn "subdi3"
(define_insn "subdi3"
  [(set (match_operand:DI           0 "register_operand" "=r,r")
  [(set (match_operand:DI           0 "register_operand" "=r,r")
        (minus:DI (match_operand:DI 1 "register_operand"  "0,0")
        (minus:DI (match_operand:DI 1 "register_operand"  "0,0")
                  (match_operand:DI 2 "rx_source_operand" "r,Q")))
                  (match_operand:DI 2 "rx_source_operand" "r,Q")))
   (set (reg:CC_ZSC CC_REG) ;; See subsi3
   (set (reg:CC_ZSC CC_REG) ;; See subsi3
        (compare:CC_ZSC (minus:DI (match_dup 1) (match_dup 2))
        (compare:CC_ZSC (minus:DI (match_dup 1) (match_dup 2))
                        (const_int 0)))]
                        (const_int 0)))]
  ""
  ""
  "sub\t%L2, %L0\n\tsbb\t%H2, %H0"
  "sub\t%L2, %L0\n\tsbb\t%H2, %H0"
  [(set_attr "timings" "22,44")
  [(set_attr "timings" "22,44")
   (set_attr "length" "5,11")]
   (set_attr "length" "5,11")]
)
)
(define_insn "xorsi3"
(define_insn "xorsi3"
  [(set (match_operand:SI         0 "register_operand" "=r,r,r,r,r,r")
  [(set (match_operand:SI         0 "register_operand" "=r,r,r,r,r,r")
        (xor:SI (match_operand:SI 1 "register_operand" "%0,0,0,0,0,0")
        (xor:SI (match_operand:SI 1 "register_operand" "%0,0,0,0,0,0")
                (match_operand:SI 2 "rx_source_operand"
                (match_operand:SI 2 "rx_source_operand"
                                  "r,Sint08,Sint16,Sint24,i,Q")))
                                  "r,Sint08,Sint16,Sint24,i,Q")))
   (set (reg:CC_ZS CC_REG)
   (set (reg:CC_ZS CC_REG)
        (compare:CC_ZS (xor:SI (match_dup 1) (match_dup 2))
        (compare:CC_ZS (xor:SI (match_dup 1) (match_dup 2))
                       (const_int 0)))]
                       (const_int 0)))]
  ""
  ""
  "xor\t%Q2, %0"
  "xor\t%Q2, %0"
  [(set_attr "timings" "11,11,11,11,11,33")
  [(set_attr "timings" "11,11,11,11,11,33")
   (set_attr "length" "3,4,5,6,7,6")]
   (set_attr "length" "3,4,5,6,7,6")]
)
)


;; Floating Point Instructions
;; Floating Point Instructions
(define_insn "addsf3"
(define_insn "addsf3"
  [(set (match_operand:SF          0 "register_operand"  "=r,r,r")
  [(set (match_operand:SF          0 "register_operand"  "=r,r,r")
        (plus:SF (match_operand:SF 1 "register_operand"  "%0,0,0")
        (plus:SF (match_operand:SF 1 "register_operand"  "%0,0,0")
                 (match_operand:SF 2 "rx_source_operand"  "r,F,Q")))
                 (match_operand:SF 2 "rx_source_operand"  "r,F,Q")))
   (set (reg:CC_ZS CC_REG)
   (set (reg:CC_ZS CC_REG)
        (compare:CC_ZS (plus:SF (match_dup 1) (match_dup 2))
        (compare:CC_ZS (plus:SF (match_dup 1) (match_dup 2))
                        (const_int 0)))]
                        (const_int 0)))]
  "ALLOW_RX_FPU_INSNS"
  "ALLOW_RX_FPU_INSNS"
  "fadd\t%2, %0"
  "fadd\t%2, %0"
  [(set_attr "timings" "44,44,66")
  [(set_attr "timings" "44,44,66")
   (set_attr "length" "3,7,5")]
   (set_attr "length" "3,7,5")]
)
)
(define_insn "divsf3"
(define_insn "divsf3"
  [(set (match_operand:SF         0 "register_operand" "=r,r,r")
  [(set (match_operand:SF         0 "register_operand" "=r,r,r")
        (div:SF (match_operand:SF 1 "register_operand"  "0,0,0")
        (div:SF (match_operand:SF 1 "register_operand"  "0,0,0")
                (match_operand:SF 2 "rx_source_operand" "r,F,Q")))
                (match_operand:SF 2 "rx_source_operand" "r,F,Q")))
   (set (reg:CC_ZS CC_REG)
   (set (reg:CC_ZS CC_REG)
        (compare:CC_ZS (div:SF (match_dup 1) (match_dup 2))
        (compare:CC_ZS (div:SF (match_dup 1) (match_dup 2))
                        (const_int 0)))]
                        (const_int 0)))]
  "ALLOW_RX_FPU_INSNS"
  "ALLOW_RX_FPU_INSNS"
  "fdiv\t%2, %0"
  "fdiv\t%2, %0"
  [(set_attr "timings" "1616,1616,1818")
  [(set_attr "timings" "1616,1616,1818")
   (set_attr "length" "3,7,5")]
   (set_attr "length" "3,7,5")]
)
)
(define_insn "mulsf3"
(define_insn "mulsf3"
  [(set (match_operand:SF          0 "register_operand" "=r,r,r")
  [(set (match_operand:SF          0 "register_operand" "=r,r,r")
        (mult:SF (match_operand:SF 1 "register_operand" "%0,0,0")
        (mult:SF (match_operand:SF 1 "register_operand" "%0,0,0")
                (match_operand:SF  2 "rx_source_operand" "r,F,Q")))
                (match_operand:SF  2 "rx_source_operand" "r,F,Q")))
   (set (reg:CC_ZS CC_REG)
   (set (reg:CC_ZS CC_REG)
        (compare:CC_ZS (mult:SF (match_dup 1) (match_dup 2))
        (compare:CC_ZS (mult:SF (match_dup 1) (match_dup 2))
                        (const_int 0)))]
                        (const_int 0)))]
  "ALLOW_RX_FPU_INSNS"
  "ALLOW_RX_FPU_INSNS"
  "fmul\t%2, %0"
  "fmul\t%2, %0"
  [(set_attr "timings" "33,33,55")
  [(set_attr "timings" "33,33,55")
   (set_attr "length"  "3,7,5")]
   (set_attr "length"  "3,7,5")]
)
)
(define_insn "subsf3"
(define_insn "subsf3"
  [(set (match_operand:SF           0 "register_operand" "=r,r,r")
  [(set (match_operand:SF           0 "register_operand" "=r,r,r")
        (minus:SF (match_operand:SF 1 "register_operand"  "0,0,0")
        (minus:SF (match_operand:SF 1 "register_operand"  "0,0,0")
                  (match_operand:SF 2 "rx_source_operand" "r,F,Q")))
                  (match_operand:SF 2 "rx_source_operand" "r,F,Q")))
   (set (reg:CC_ZS CC_REG)
   (set (reg:CC_ZS CC_REG)
        (compare:CC_ZS (minus:SF (match_dup 1) (match_dup 2))
        (compare:CC_ZS (minus:SF (match_dup 1) (match_dup 2))
                       (const_int 0)))]
                       (const_int 0)))]
  "ALLOW_RX_FPU_INSNS"
  "ALLOW_RX_FPU_INSNS"
  "fsub\t%Q2, %0"
  "fsub\t%Q2, %0"
  [(set_attr "timings" "44,44,66")
  [(set_attr "timings" "44,44,66")
   (set_attr "length" "3,7,5")]
   (set_attr "length" "3,7,5")]
)
)
(define_insn "fix_truncsfsi2"
(define_insn "fix_truncsfsi2"
  [(set (match_operand:SI         0 "register_operand"  "=r,r")
  [(set (match_operand:SI         0 "register_operand"  "=r,r")
        (fix:SI (match_operand:SF 1 "rx_compare_operand" "r,Q")))
        (fix:SI (match_operand:SF 1 "rx_compare_operand" "r,Q")))
   (set (reg:CC_ZS CC_REG)
   (set (reg:CC_ZS CC_REG)
        (compare:CC_ZS (fix:SI (match_dup 1))
        (compare:CC_ZS (fix:SI (match_dup 1))
                       (const_int 0)))]
                       (const_int 0)))]
  "ALLOW_RX_FPU_INSNS"
  "ALLOW_RX_FPU_INSNS"
  "ftoi\t%Q1, %0"
  "ftoi\t%Q1, %0"
  [(set_attr "timings" "22,44")
  [(set_attr "timings" "22,44")
   (set_attr "length" "3,5")]
   (set_attr "length" "3,5")]
)
)
(define_insn "floatsisf2"
(define_insn "floatsisf2"
  [(set (match_operand:SF           0 "register_operand"  "=r,r")
  [(set (match_operand:SF           0 "register_operand"  "=r,r")
        (float:SF (match_operand:SI 1 "rx_compare_operand" "r,Q")))
        (float:SF (match_operand:SI 1 "rx_compare_operand" "r,Q")))
   (set (reg:CC_ZS CC_REG)
   (set (reg:CC_ZS CC_REG)
        (compare:CC_ZS (float:SF (match_dup 1))
        (compare:CC_ZS (float:SF (match_dup 1))
                        (const_int 0)))]
                        (const_int 0)))]
  "ALLOW_RX_FPU_INSNS"
  "ALLOW_RX_FPU_INSNS"
  "itof\t%Q1, %0"
  "itof\t%Q1, %0"
  [(set_attr "timings" "22,44")
  [(set_attr "timings" "22,44")
   (set_attr "length" "3,6")]
   (set_attr "length" "3,6")]
)
)


;; Bit manipulation instructions.
;; Bit manipulation instructions.
;; Note - there are two versions of each pattern because the memory
;; Note - there are two versions of each pattern because the memory
;; accessing versions use QImode whilst the register accessing
;; accessing versions use QImode whilst the register accessing
;; versions use SImode.
;; versions use SImode.
;; The peephole are here because the combiner only looks at a maximum
;; The peephole are here because the combiner only looks at a maximum
;; of three instructions at a time.
;; of three instructions at a time.
(define_insn "bitset"
(define_insn "bitset"
  [(set:SI (match_operand:SI                    0 "register_operand" "=r")
  [(set:SI (match_operand:SI                    0 "register_operand" "=r")
           (ior:SI (match_operand:SI            1 "register_operand" "0")
           (ior:SI (match_operand:SI            1 "register_operand" "0")
                   (ashift:SI (const_int 1)
                   (ashift:SI (const_int 1)
                              (match_operand:SI 2 "nonmemory_operand" "ri"))))]
                              (match_operand:SI 2 "nonmemory_operand" "ri"))))]
  ""
  ""
  "bset\t%2, %0"
  "bset\t%2, %0"
  [(set_attr "length" "3")]
  [(set_attr "length" "3")]
)
)
(define_insn "bitset_in_memory"
(define_insn "bitset_in_memory"
  [(set:QI (match_operand:QI                    0 "memory_operand" "=m")
  [(set:QI (match_operand:QI                    0 "memory_operand" "=m")
           (ior:QI (match_operand:QI            1 "memory_operand" "0")
           (ior:QI (match_operand:QI            1 "memory_operand" "0")
                   (ashift:QI (const_int 1)
                   (ashift:QI (const_int 1)
                              (match_operand:QI 2 "nonmemory_operand" "ri"))))]
                              (match_operand:QI 2 "nonmemory_operand" "ri"))))]
  ""
  ""
  "bset\t%2, %0.B"
  "bset\t%2, %0.B"
  [(set_attr "length" "3")
  [(set_attr "length" "3")
   (set_attr "timings" "34")]
   (set_attr "timings" "34")]
)
)
;; (set (reg A) (const_int 1))
;; (set (reg A) (const_int 1))
;; (set (reg A) (ashift (reg A) (reg B)))
;; (set (reg A) (ashift (reg A) (reg B)))
;; (set (reg C) (ior (reg A) (reg C)))
;; (set (reg C) (ior (reg A) (reg C)))
(define_peephole2
(define_peephole2
  [(set:SI (match_operand:SI 0 "register_operand" "")
  [(set:SI (match_operand:SI 0 "register_operand" "")
           (const_int 1))
           (const_int 1))
   (set:SI (match_dup 0)
   (set:SI (match_dup 0)
           (ashift:SI (match_dup 0)
           (ashift:SI (match_dup 0)
                      (match_operand:SI 1 "register_operand" "")))
                      (match_operand:SI 1 "register_operand" "")))
   (set:SI (match_operand:SI 2 "register_operand" "")
   (set:SI (match_operand:SI 2 "register_operand" "")
           (ior:SI (match_dup 0)
           (ior:SI (match_dup 0)
                   (match_dup 2)))]
                   (match_dup 2)))]
  "dead_or_set_p (insn, operands[0])"
  "dead_or_set_p (insn, operands[0])"
  [(set:SI (match_dup 2)
  [(set:SI (match_dup 2)
           (ior:SI (match_dup 2)
           (ior:SI (match_dup 2)
                   (ashift:SI (const_int 1)
                   (ashift:SI (const_int 1)
                              (match_dup 1))))]
                              (match_dup 1))))]
)
)
;; (set (reg A) (const_int 1))
;; (set (reg A) (const_int 1))
;; (set (reg A) (ashift (reg A) (reg B)))
;; (set (reg A) (ashift (reg A) (reg B)))
;; (set (reg A) (ior (reg A) (reg C)))
;; (set (reg A) (ior (reg A) (reg C)))
;; (set (reg C) (reg A)
;; (set (reg C) (reg A)
(define_peephole2
(define_peephole2
  [(set:SI (match_operand:SI 0 "register_operand" "")
  [(set:SI (match_operand:SI 0 "register_operand" "")
           (const_int 1))
           (const_int 1))
   (set:SI (match_dup 0)
   (set:SI (match_dup 0)
           (ashift:SI (match_dup 0)
           (ashift:SI (match_dup 0)
                      (match_operand:SI 1 "register_operand" "")))
                      (match_operand:SI 1 "register_operand" "")))
   (set:SI (match_dup 0)
   (set:SI (match_dup 0)
           (ior:SI (match_dup 0)
           (ior:SI (match_dup 0)
                   (match_operand:SI 2 "register_operand" "")))
                   (match_operand:SI 2 "register_operand" "")))
   (set:SI (match_dup 2) (match_dup 0))]
   (set:SI (match_dup 2) (match_dup 0))]
  "dead_or_set_p (insn, operands[0])"
  "dead_or_set_p (insn, operands[0])"
  [(set:SI (match_dup 2)
  [(set:SI (match_dup 2)
           (ior:SI (match_dup 2)
           (ior:SI (match_dup 2)
                   (ashift:SI (const_int 1)
                   (ashift:SI (const_int 1)
                              (match_dup 1))))]
                              (match_dup 1))))]
)
)
(define_insn "bitinvert"
(define_insn "bitinvert"
  [(set:SI (match_operand:SI 0 "register_operand" "+r")
  [(set:SI (match_operand:SI 0 "register_operand" "+r")
           (xor:SI (match_operand:SI 1 "register_operand" "0")
           (xor:SI (match_operand:SI 1 "register_operand" "0")
                   (ashift:SI (const_int 1)
                   (ashift:SI (const_int 1)
                              (match_operand:SI 2 "nonmemory_operand" "ri"))))]
                              (match_operand:SI 2 "nonmemory_operand" "ri"))))]
  ""
  ""
  "bnot\t%2, %0"
  "bnot\t%2, %0"
  [(set_attr "length" "3")]
  [(set_attr "length" "3")]
)
)
(define_insn "bitinvert_in_memory"
(define_insn "bitinvert_in_memory"
  [(set:QI (match_operand:QI 0 "memory_operand" "+m")
  [(set:QI (match_operand:QI 0 "memory_operand" "+m")
           (xor:QI (match_operand:QI 1 "register_operand" "0")
           (xor:QI (match_operand:QI 1 "register_operand" "0")
                   (ashift:QI (const_int 1)
                   (ashift:QI (const_int 1)
                              (match_operand:QI 2 "nonmemory_operand" "ri"))))]
                              (match_operand:QI 2 "nonmemory_operand" "ri"))))]
  ""
  ""
  "bnot\t%2, %0.B"
  "bnot\t%2, %0.B"
  [(set_attr "length" "5")
  [(set_attr "length" "5")
   (set_attr "timings" "33")]
   (set_attr "timings" "33")]
)
)
;; (set (reg A) (const_int 1))
;; (set (reg A) (const_int 1))
;; (set (reg A) (ashift (reg A) (reg B)))
;; (set (reg A) (ashift (reg A) (reg B)))
;; (set (reg C) (xor (reg A) (reg C)))
;; (set (reg C) (xor (reg A) (reg C)))
(define_peephole2
(define_peephole2
  [(set:SI (match_operand:SI 0 "register_operand" "")
  [(set:SI (match_operand:SI 0 "register_operand" "")
           (const_int 1))
           (const_int 1))
   (set:SI (match_dup 0)
   (set:SI (match_dup 0)
           (ashift:SI (match_dup 0)
           (ashift:SI (match_dup 0)
                      (match_operand:SI 1 "register_operand" "")))
                      (match_operand:SI 1 "register_operand" "")))
   (set:SI (match_operand:SI 2 "register_operand" "")
   (set:SI (match_operand:SI 2 "register_operand" "")
           (xor:SI (match_dup 0)
           (xor:SI (match_dup 0)
                   (match_dup 2)))]
                   (match_dup 2)))]
  "dead_or_set_p (insn, operands[0])"
  "dead_or_set_p (insn, operands[0])"
  [(set:SI (match_dup 2)
  [(set:SI (match_dup 2)
           (xor:SI (match_dup 2)
           (xor:SI (match_dup 2)
                   (ashift:SI (const_int 1)
                   (ashift:SI (const_int 1)
                              (match_dup 1))))]
                              (match_dup 1))))]
  ""
  ""
)
)
;; (set (reg A) (const_int 1))
;; (set (reg A) (const_int 1))
;; (set (reg A) (ashift (reg A) (reg B)))
;; (set (reg A) (ashift (reg A) (reg B)))
;; (set (reg A) (xor (reg A) (reg C)))
;; (set (reg A) (xor (reg A) (reg C)))
;; (set (reg C) (reg A))
;; (set (reg C) (reg A))
(define_peephole2
(define_peephole2
  [(set:SI (match_operand:SI 0 "register_operand" "")
  [(set:SI (match_operand:SI 0 "register_operand" "")
           (const_int 1))
           (const_int 1))
   (set:SI (match_dup 0)
   (set:SI (match_dup 0)
           (ashift:SI (match_dup 0)
           (ashift:SI (match_dup 0)
                      (match_operand:SI 1 "register_operand" "")))
                      (match_operand:SI 1 "register_operand" "")))
   (set:SI (match_dup 0)
   (set:SI (match_dup 0)
           (xor:SI (match_dup 0)
           (xor:SI (match_dup 0)
                   (match_operand:SI 2 "register_operand" "")))
                   (match_operand:SI 2 "register_operand" "")))
   (set:SI (match_dup 2) (match_dup 0))]
   (set:SI (match_dup 2) (match_dup 0))]
  "dead_or_set_p (insn, operands[0])"
  "dead_or_set_p (insn, operands[0])"
  [(set:SI (match_dup 2)
  [(set:SI (match_dup 2)
           (xor:SI (match_dup 2)
           (xor:SI (match_dup 2)
                   (ashift:SI (const_int 1)
                   (ashift:SI (const_int 1)
                              (match_dup 1))))]
                              (match_dup 1))))]
  ""
  ""
)
)
(define_insn "bitclr"
(define_insn "bitclr"
  [(set:SI (match_operand:SI 0 "register_operand" "+r")
  [(set:SI (match_operand:SI 0 "register_operand" "+r")
           (and:SI (match_operand:SI 1 "register_operand" "0")
           (and:SI (match_operand:SI 1 "register_operand" "0")
                   (not:SI (ashift:SI (const_int 1)
                   (not:SI (ashift:SI (const_int 1)
                                      (match_operand:SI 2 "nonmemory_operand" "ri")))))]
                                      (match_operand:SI 2 "nonmemory_operand" "ri")))))]
  ""
  ""
  "bclr\t%2, %0"
  "bclr\t%2, %0"
  [(set_attr "length" "3")]
  [(set_attr "length" "3")]
)
)
(define_insn "bitclr_in_memory"
(define_insn "bitclr_in_memory"
  [(set:QI (match_operand:QI 0 "memory_operand" "+m")
  [(set:QI (match_operand:QI 0 "memory_operand" "+m")
           (and:QI (match_operand:QI 1 "memory_operand" "0")
           (and:QI (match_operand:QI 1 "memory_operand" "0")
                   (not:QI (ashift:QI (const_int 1)
                   (not:QI (ashift:QI (const_int 1)
                                      (match_operand:QI 2 "nonmemory_operand" "ri")))))]
                                      (match_operand:QI 2 "nonmemory_operand" "ri")))))]
  ""
  ""
  "bclr\t%2, %0.B"
  "bclr\t%2, %0.B"
  [(set_attr "length" "3")
  [(set_attr "length" "3")
   (set_attr "timings" "34")]
   (set_attr "timings" "34")]
)
)
;; (set (reg A) (const_int -2))
;; (set (reg A) (const_int -2))
;; (set (reg A) (rotate (reg A) (reg B)))
;; (set (reg A) (rotate (reg A) (reg B)))
;; (set (reg C) (and (reg A) (reg C)))
;; (set (reg C) (and (reg A) (reg C)))
(define_peephole2
(define_peephole2
  [(set:SI (match_operand:SI 0 "register_operand" "")
  [(set:SI (match_operand:SI 0 "register_operand" "")
           (const_int -2))
           (const_int -2))
   (set:SI (match_dup 0)
   (set:SI (match_dup 0)
           (rotate:SI (match_dup 0)
           (rotate:SI (match_dup 0)
                      (match_operand:SI 1 "register_operand" "")))
                      (match_operand:SI 1 "register_operand" "")))
   (set:SI (match_operand:SI 2 "register_operand" "")
   (set:SI (match_operand:SI 2 "register_operand" "")
           (and:SI (match_dup 0)
           (and:SI (match_dup 0)
                   (match_dup 2)))]
                   (match_dup 2)))]
  "dead_or_set_p (insn, operands[0])"
  "dead_or_set_p (insn, operands[0])"
  [(set:SI (match_dup 2)
  [(set:SI (match_dup 2)
           (and:SI (match_dup 2)
           (and:SI (match_dup 2)
                   (not:SI (ashift:SI (const_int 1)
                   (not:SI (ashift:SI (const_int 1)
                                      (match_dup 1)))))]
                                      (match_dup 1)))))]
)
)
;; (set (reg A) (const_int -2))
;; (set (reg A) (const_int -2))
;; (set (reg A) (rotate (reg A) (reg B)))
;; (set (reg A) (rotate (reg A) (reg B)))
;; (set (reg A) (and (reg A) (reg C)))
;; (set (reg A) (and (reg A) (reg C)))
;; (set (reg C) (reg A)
;; (set (reg C) (reg A)
(define_peephole2
(define_peephole2
  [(set:SI (match_operand:SI 0 "register_operand" "")
  [(set:SI (match_operand:SI 0 "register_operand" "")
           (const_int -2))
           (const_int -2))
   (set:SI (match_dup 0)
   (set:SI (match_dup 0)
           (rotate:SI (match_dup 0)
           (rotate:SI (match_dup 0)
                      (match_operand:SI 1 "register_operand" "")))
                      (match_operand:SI 1 "register_operand" "")))
   (set:SI (match_dup 0)
   (set:SI (match_dup 0)
           (and:SI (match_dup 0)
           (and:SI (match_dup 0)
                   (match_operand:SI 2 "register_operand" "")))
                   (match_operand:SI 2 "register_operand" "")))
   (set:SI (match_dup 2) (match_dup 0))]
   (set:SI (match_dup 2) (match_dup 0))]
  "dead_or_set_p (insn, operands[0])"
  "dead_or_set_p (insn, operands[0])"
  [(set:SI (match_dup 2)
  [(set:SI (match_dup 2)
           (and:SI (match_dup 2)
           (and:SI (match_dup 2)
                   (not:SI (ashift:SI (const_int 1)
                   (not:SI (ashift:SI (const_int 1)
                                      (match_dup 1)))))]
                                      (match_dup 1)))))]
)
)
(define_expand "insv"
(define_expand "insv"
  [(set:SI (zero_extract:SI (match_operand:SI 0 "nonimmediate_operand") ;; Destination
  [(set:SI (zero_extract:SI (match_operand:SI 0 "nonimmediate_operand") ;; Destination
                            (match_operand    1 "immediate_operand")    ;; # of bits to set
                            (match_operand    1 "immediate_operand")    ;; # of bits to set
                            (match_operand    2 "immediate_operand"))   ;; Starting bit
                            (match_operand    2 "immediate_operand"))   ;; Starting bit
           (match_operand                     3 "immediate_operand"))]  ;; Bits to insert
           (match_operand                     3 "immediate_operand"))]  ;; Bits to insert
  ""
  ""
  {
  {
    if (rx_expand_insv (operands))
    if (rx_expand_insv (operands))
      DONE;
      DONE;
    FAIL;
    FAIL;
  }
  }
)
)


;; Atomic exchange operation.
;; Atomic exchange operation.
(define_insn "sync_lock_test_and_setsi"
(define_insn "sync_lock_test_and_setsi"
  [(set:SI (match_operand:SI 0 "register_operand"   "=r,r")
  [(set:SI (match_operand:SI 0 "register_operand"   "=r,r")
           (match_operand:SI 1 "rx_compare_operand" "=r,Q"))
           (match_operand:SI 1 "rx_compare_operand" "=r,Q"))
   (set:SI (match_dup 1)
   (set:SI (match_dup 1)
           (match_operand:SI 2 "register_operand"    "0,0"))]
           (match_operand:SI 2 "register_operand"    "0,0"))]
  ""
  ""
  "xchg\t%1, %0"
  "xchg\t%1, %0"
  [(set_attr "length" "3,6")
  [(set_attr "length" "3,6")
   (set_attr "timings" "22")]
   (set_attr "timings" "22")]
)
)


;; Block move functions.
;; Block move functions.
(define_expand "movstr"
(define_expand "movstr"
  [(set:SI (match_operand:BLK 1 "memory_operand")    ;; Dest
  [(set:SI (match_operand:BLK 1 "memory_operand")    ;; Dest
           (match_operand:BLK 2 "memory_operand"))   ;; Source
           (match_operand:BLK 2 "memory_operand"))   ;; Source
   (use (match_operand:SI     0 "register_operand")) ;; Updated Dest
   (use (match_operand:SI     0 "register_operand")) ;; Updated Dest
  ]
  ]
  ""
  ""
  {
  {
    rtx addr1 = gen_rtx_REG (SImode, 1);
    rtx addr1 = gen_rtx_REG (SImode, 1);
    rtx addr2 = gen_rtx_REG (SImode, 2);
    rtx addr2 = gen_rtx_REG (SImode, 2);
    rtx len   = gen_rtx_REG (SImode, 3);
    rtx len   = gen_rtx_REG (SImode, 3);
    rtx dest_copy = gen_reg_rtx (SImode);
    rtx dest_copy = gen_reg_rtx (SImode);
    emit_move_insn (len, GEN_INT (-1));
    emit_move_insn (len, GEN_INT (-1));
    emit_move_insn (addr1, force_operand (XEXP (operands[1], 0), NULL_RTX));
    emit_move_insn (addr1, force_operand (XEXP (operands[1], 0), NULL_RTX));
    emit_move_insn (addr2, force_operand (XEXP (operands[2], 0), NULL_RTX));
    emit_move_insn (addr2, force_operand (XEXP (operands[2], 0), NULL_RTX));
    operands[1] = replace_equiv_address_nv (operands[1], addr1);
    operands[1] = replace_equiv_address_nv (operands[1], addr1);
    operands[2] = replace_equiv_address_nv (operands[2], addr2);
    operands[2] = replace_equiv_address_nv (operands[2], addr2);
    emit_move_insn (dest_copy, addr1);
    emit_move_insn (dest_copy, addr1);
    emit_insn (gen_rx_movstr ());
    emit_insn (gen_rx_movstr ());
    emit_move_insn (len, GEN_INT (-1));
    emit_move_insn (len, GEN_INT (-1));
    emit_insn (gen_rx_strend (operands[0], dest_copy));
    emit_insn (gen_rx_strend (operands[0], dest_copy));
    DONE;
    DONE;
  }
  }
)
)
(define_insn "rx_movstr"
(define_insn "rx_movstr"
  [(set:SI (mem:BLK (reg:SI 1))
  [(set:SI (mem:BLK (reg:SI 1))
           (mem:BLK (reg:SI 2)))
           (mem:BLK (reg:SI 2)))
   (unspec_volatile:BLK [(reg:SI 1) (reg:SI 2) (reg:SI 3)] UNSPEC_MOVSTR)
   (unspec_volatile:BLK [(reg:SI 1) (reg:SI 2) (reg:SI 3)] UNSPEC_MOVSTR)
   (clobber (reg:SI 1))
   (clobber (reg:SI 1))
   (clobber (reg:SI 2))
   (clobber (reg:SI 2))
   (clobber (reg:SI 3))]
   (clobber (reg:SI 3))]
  ""
  ""
  "smovu"
  "smovu"
  [(set_attr "length" "2")
  [(set_attr "length" "2")
   (set_attr "timings" "1111")] ;; The timing is a guesstimate.
   (set_attr "timings" "1111")] ;; The timing is a guesstimate.
)
)
(define_insn "rx_strend"
(define_insn "rx_strend"
  [(set:SI (match_operand:SI                      0 "register_operand" "=r")
  [(set:SI (match_operand:SI                      0 "register_operand" "=r")
           (unspec_volatile:SI [(match_operand:SI 1 "register_operand"  "r")
           (unspec_volatile:SI [(match_operand:SI 1 "register_operand"  "r")
                                (reg:SI 3)] UNSPEC_STRLEN))
                                (reg:SI 3)] UNSPEC_STRLEN))
   (clobber (reg:SI 1))
   (clobber (reg:SI 1))
   (clobber (reg:SI 2))
   (clobber (reg:SI 2))
   (clobber (reg:SI 3))
   (clobber (reg:SI 3))
   (clobber (reg:CC CC_REG))
   (clobber (reg:CC CC_REG))
   ]
   ]
  ""
  ""
  "mov\t%1, r1\n\tmov\t#0, r2\n\tsuntil.b\n\tmov\tr1, %0\n\tsub\t#1, %0"
  "mov\t%1, r1\n\tmov\t#0, r2\n\tsuntil.b\n\tmov\tr1, %0\n\tsub\t#1, %0"
  [(set_attr "length" "10")
  [(set_attr "length" "10")
   (set_attr "timings" "1111")] ;; The timing is a guesstimate.
   (set_attr "timings" "1111")] ;; The timing is a guesstimate.
)
)
(define_expand "movmemsi"
(define_expand "movmemsi"
  [(parallel
  [(parallel
    [(set (match_operand:BLK 0 "memory_operand")    ;; Dest
    [(set (match_operand:BLK 0 "memory_operand")    ;; Dest
          (match_operand:BLK 1 "memory_operand"))   ;; Source
          (match_operand:BLK 1 "memory_operand"))   ;; Source
     (use (match_operand:SI  2 "register_operand")) ;; Length in bytes
     (use (match_operand:SI  2 "register_operand")) ;; Length in bytes
     (match_operand          3 "immediate_operand") ;; Align
     (match_operand          3 "immediate_operand") ;; Align
     (unspec_volatile:BLK [(reg:SI 1) (reg:SI 2) (reg:SI 3)] UNSPEC_MOVMEM)]
     (unspec_volatile:BLK [(reg:SI 1) (reg:SI 2) (reg:SI 3)] UNSPEC_MOVMEM)]
    )]
    )]
  ""
  ""
  {
  {
    rtx addr1 = gen_rtx_REG (SImode, 1);
    rtx addr1 = gen_rtx_REG (SImode, 1);
    rtx addr2 = gen_rtx_REG (SImode, 2);
    rtx addr2 = gen_rtx_REG (SImode, 2);
    rtx len   = gen_rtx_REG (SImode, 3);
    rtx len   = gen_rtx_REG (SImode, 3);
    if (REG_P (operands[0]) && (REGNO (operands[0]) == 2
    if (REG_P (operands[0]) && (REGNO (operands[0]) == 2
                                      || REGNO (operands[0]) == 3))
                                      || REGNO (operands[0]) == 3))
      FAIL;
      FAIL;
    if (REG_P (operands[1]) && (REGNO (operands[1]) == 1
    if (REG_P (operands[1]) && (REGNO (operands[1]) == 1
                                      || REGNO (operands[1]) == 3))
                                      || REGNO (operands[1]) == 3))
      FAIL;
      FAIL;
    if (REG_P (operands[2]) && (REGNO (operands[2]) == 1
    if (REG_P (operands[2]) && (REGNO (operands[2]) == 1
                                      || REGNO (operands[2]) == 2))
                                      || REGNO (operands[2]) == 2))
      FAIL;
      FAIL;
    emit_move_insn (addr1, force_operand (XEXP (operands[0], 0), NULL_RTX));
    emit_move_insn (addr1, force_operand (XEXP (operands[0], 0), NULL_RTX));
    emit_move_insn (addr2, force_operand (XEXP (operands[1], 0), NULL_RTX));
    emit_move_insn (addr2, force_operand (XEXP (operands[1], 0), NULL_RTX));
    emit_move_insn (len, force_operand (operands[2], NULL_RTX));
    emit_move_insn (len, force_operand (operands[2], NULL_RTX));
    operands[0] = replace_equiv_address_nv (operands[0], addr1);
    operands[0] = replace_equiv_address_nv (operands[0], addr1);
    operands[1] = replace_equiv_address_nv (operands[1], addr2);
    operands[1] = replace_equiv_address_nv (operands[1], addr2);
    emit_insn (gen_rx_movmem ());
    emit_insn (gen_rx_movmem ());
    DONE;
    DONE;
  }
  }
)
)
(define_insn "rx_movmem"
(define_insn "rx_movmem"
  [(set (mem:BLK (reg:SI 1))
  [(set (mem:BLK (reg:SI 1))
        (mem:BLK (reg:SI 2)))
        (mem:BLK (reg:SI 2)))
   (use (reg:SI 3))
   (use (reg:SI 3))
   (unspec_volatile:BLK [(reg:SI 1) (reg:SI 2) (reg:SI 3)] UNSPEC_MOVMEM)
   (unspec_volatile:BLK [(reg:SI 1) (reg:SI 2) (reg:SI 3)] UNSPEC_MOVMEM)
   (clobber (reg:SI 1))
   (clobber (reg:SI 1))
   (clobber (reg:SI 2))
   (clobber (reg:SI 2))
   (clobber (reg:SI 3))]
   (clobber (reg:SI 3))]
  ""
  ""
  "smovf"
  "smovf"
  [(set_attr "length" "2")
  [(set_attr "length" "2")
   (set_attr "timings" "1111")] ;; The timing is a guesstimate.
   (set_attr "timings" "1111")] ;; The timing is a guesstimate.
)
)
(define_expand "setmemsi"
(define_expand "setmemsi"
  [(set (match_operand:BLK 0 "memory_operand")     ;; Dest
  [(set (match_operand:BLK 0 "memory_operand")     ;; Dest
        (match_operand:QI  2 "nonmemory_operand")) ;; Value
        (match_operand:QI  2 "nonmemory_operand")) ;; Value
   (use (match_operand:SI  1 "nonmemory_operand")) ;; Length
   (use (match_operand:SI  1 "nonmemory_operand")) ;; Length
   (match_operand          3 "immediate_operand")  ;; Align
   (match_operand          3 "immediate_operand")  ;; Align
   (unspec_volatile:BLK [(reg:SI 1) (reg:SI 2) (reg:SI 3)] UNSPEC_SETMEM)]
   (unspec_volatile:BLK [(reg:SI 1) (reg:SI 2) (reg:SI 3)] UNSPEC_SETMEM)]
  ""
  ""
  {
  {
    rtx addr = gen_rtx_REG (SImode, 1);
    rtx addr = gen_rtx_REG (SImode, 1);
    rtx val  = gen_rtx_REG (QImode, 2);
    rtx val  = gen_rtx_REG (QImode, 2);
    rtx len  = gen_rtx_REG (SImode, 3);
    rtx len  = gen_rtx_REG (SImode, 3);
    emit_move_insn (addr, force_operand (XEXP (operands[0], 0), NULL_RTX));
    emit_move_insn (addr, force_operand (XEXP (operands[0], 0), NULL_RTX));
    emit_move_insn (len, force_operand (operands[1], NULL_RTX));
    emit_move_insn (len, force_operand (operands[1], NULL_RTX));
    emit_move_insn (val, operands[2]);
    emit_move_insn (val, operands[2]);
    emit_insn (gen_rx_setmem ());
    emit_insn (gen_rx_setmem ());
    DONE;
    DONE;
  }
  }
)
)
(define_insn "rx_setmem"
(define_insn "rx_setmem"
  [(set:BLK (mem:BLK (reg:SI 1)) (reg 2))
  [(set:BLK (mem:BLK (reg:SI 1)) (reg 2))
   (unspec_volatile:BLK [(reg:SI 1) (reg:SI 2) (reg:SI 3)] UNSPEC_SETMEM)
   (unspec_volatile:BLK [(reg:SI 1) (reg:SI 2) (reg:SI 3)] UNSPEC_SETMEM)
   (clobber (reg:SI 1))
   (clobber (reg:SI 1))
   (clobber (reg:SI 3))]
   (clobber (reg:SI 3))]
  ""
  ""
  "sstr.b"
  "sstr.b"
  [(set_attr "length" "2")
  [(set_attr "length" "2")
   (set_attr "timings" "1111")] ;; The timing is a guesstimate.
   (set_attr "timings" "1111")] ;; The timing is a guesstimate.
)
)
(define_expand "cmpstrnsi"
(define_expand "cmpstrnsi"
  [(set (match_operand:SI                       0 "register_operand")   ;; Result
  [(set (match_operand:SI                       0 "register_operand")   ;; Result
        (unspec_volatile:SI [(match_operand:BLK 1 "memory_operand")     ;; String1
        (unspec_volatile:SI [(match_operand:BLK 1 "memory_operand")     ;; String1
                             (match_operand:BLK 2 "memory_operand")]    ;; String2
                             (match_operand:BLK 2 "memory_operand")]    ;; String2
                            UNSPEC_CMPSTRN))
                            UNSPEC_CMPSTRN))
   (use (match_operand:SI                       3 "register_operand"))  ;; Max Length
   (use (match_operand:SI                       3 "register_operand"))  ;; Max Length
   (match_operand:SI                            4 "immediate_operand")] ;; Known Align
   (match_operand:SI                            4 "immediate_operand")] ;; Known Align
  ""
  ""
  {
  {
    rtx str1 = gen_rtx_REG (SImode, 1);
    rtx str1 = gen_rtx_REG (SImode, 1);
    rtx str2 = gen_rtx_REG (SImode, 2);
    rtx str2 = gen_rtx_REG (SImode, 2);
    rtx len  = gen_rtx_REG (SImode, 3);
    rtx len  = gen_rtx_REG (SImode, 3);
    emit_move_insn (str1, force_operand (XEXP (operands[1], 0), NULL_RTX));
    emit_move_insn (str1, force_operand (XEXP (operands[1], 0), NULL_RTX));
    emit_move_insn (str2, force_operand (XEXP (operands[2], 0), NULL_RTX));
    emit_move_insn (str2, force_operand (XEXP (operands[2], 0), NULL_RTX));
    emit_move_insn (len, force_operand (operands[3], NULL_RTX));
    emit_move_insn (len, force_operand (operands[3], NULL_RTX));
    emit_insn (gen_rx_cmpstrn (operands[0], operands[1], operands[2]));
    emit_insn (gen_rx_cmpstrn (operands[0], operands[1], operands[2]));
    DONE;
    DONE;
  }
  }
)
)
(define_expand "cmpstrsi"
(define_expand "cmpstrsi"
  [(set (match_operand:SI                       0 "register_operand")   ;; Result
  [(set (match_operand:SI                       0 "register_operand")   ;; Result
        (unspec_volatile:SI [(match_operand:BLK 1 "memory_operand")     ;; String1
        (unspec_volatile:SI [(match_operand:BLK 1 "memory_operand")     ;; String1
                             (match_operand:BLK 2 "memory_operand")]    ;; String2
                             (match_operand:BLK 2 "memory_operand")]    ;; String2
                            UNSPEC_CMPSTRN))
                            UNSPEC_CMPSTRN))
   (match_operand:SI                            3 "immediate_operand")] ;; Known Align
   (match_operand:SI                            3 "immediate_operand")] ;; Known Align
  ""
  ""
  {
  {
    rtx str1 = gen_rtx_REG (SImode, 1);
    rtx str1 = gen_rtx_REG (SImode, 1);
    rtx str2 = gen_rtx_REG (SImode, 2);
    rtx str2 = gen_rtx_REG (SImode, 2);
    rtx len  = gen_rtx_REG (SImode, 3);
    rtx len  = gen_rtx_REG (SImode, 3);
    emit_move_insn (str1, force_reg (SImode, XEXP (operands[1], 0)));
    emit_move_insn (str1, force_reg (SImode, XEXP (operands[1], 0)));
    emit_move_insn (str2, force_reg (SImode, XEXP (operands[2], 0)));
    emit_move_insn (str2, force_reg (SImode, XEXP (operands[2], 0)));
    emit_move_insn (len, GEN_INT (-1));
    emit_move_insn (len, GEN_INT (-1));
    emit_insn (gen_rx_cmpstrn (operands[0], operands[1], operands[2]));
    emit_insn (gen_rx_cmpstrn (operands[0], operands[1], operands[2]));
    DONE;
    DONE;
  }
  }
)
)
(define_insn "rx_cmpstrn"
(define_insn "rx_cmpstrn"
  [(set:SI (match_operand:SI 0 "register_operand" "=r")
  [(set:SI (match_operand:SI 0 "register_operand" "=r")
           (unspec_volatile:SI [(reg:SI 1) (reg:SI 2) (reg:SI 3)]
           (unspec_volatile:SI [(reg:SI 1) (reg:SI 2) (reg:SI 3)]
                               UNSPEC_CMPSTRN))
                               UNSPEC_CMPSTRN))
   (use (match_operand:BLK   1 "memory_operand" "m"))
   (use (match_operand:BLK   1 "memory_operand" "m"))
   (use (match_operand:BLK   2 "memory_operand" "m"))
   (use (match_operand:BLK   2 "memory_operand" "m"))
   (clobber (reg:SI 1))
   (clobber (reg:SI 1))
   (clobber (reg:SI 2))
   (clobber (reg:SI 2))
   (clobber (reg:SI 3))
   (clobber (reg:SI 3))
   (clobber (reg:CC CC_REG))]
   (clobber (reg:CC CC_REG))]
  ""
  ""
  "scmpu                ; Perform the string comparison
  "scmpu                ; Perform the string comparison
   mov     #-1, %0      ; Set up -1 result (which cannot be created
   mov     #-1, %0      ; Set up -1 result (which cannot be created
                        ; by the SC insn)
                        ; by the SC insn)
   bnc     ?+           ; If Carry is not set skip over
   bnc     ?+           ; If Carry is not set skip over
   scne.L  %0           ; Set result based on Z flag
   scne.L  %0           ; Set result based on Z flag
?:
?:
"
"
  [(set_attr "length" "9")
  [(set_attr "length" "9")
   (set_attr "timings" "1111")] ;; The timing is a guesstimate.
   (set_attr "timings" "1111")] ;; The timing is a guesstimate.
)
)


;;   Builtin Functions
;;   Builtin Functions
;;
;;
;; GCC does not have the ability to generate the following instructions
;; GCC does not have the ability to generate the following instructions
;; on its own so they are provided as builtins instead.  To use them from
;; on its own so they are provided as builtins instead.  To use them from
;; a program for example invoke them as __builtin_rx_.  For
;; a program for example invoke them as __builtin_rx_.  For
;; example:
;; example:
;;
;;
;;    int short_byte_swap (int arg) { return __builtin_rx_revw (arg); }
;;    int short_byte_swap (int arg) { return __builtin_rx_revw (arg); }
;;---------- Accumulator Support ------------------------
;;---------- Accumulator Support ------------------------
;; Multiply & Accumulate (high)
;; Multiply & Accumulate (high)
(define_insn "machi"
(define_insn "machi"
  [(unspec:SI [(match_operand:SI 0 "register_operand" "r")
  [(unspec:SI [(match_operand:SI 0 "register_operand" "r")
               (match_operand:SI 1 "register_operand" "r")]
               (match_operand:SI 1 "register_operand" "r")]
              UNSPEC_BUILTIN_MACHI)]
              UNSPEC_BUILTIN_MACHI)]
  ""
  ""
  "machi\t%0, %1"
  "machi\t%0, %1"
  [(set_attr "length" "3")]
  [(set_attr "length" "3")]
)
)
;; Multiply & Accumulate (low)
;; Multiply & Accumulate (low)
(define_insn "maclo"
(define_insn "maclo"
  [(unspec:SI [(match_operand:SI 0 "register_operand" "r")
  [(unspec:SI [(match_operand:SI 0 "register_operand" "r")
               (match_operand:SI 1 "register_operand" "r")]
               (match_operand:SI 1 "register_operand" "r")]
              UNSPEC_BUILTIN_MACLO)]
              UNSPEC_BUILTIN_MACLO)]
  ""
  ""
  "maclo\t%0, %1"
  "maclo\t%0, %1"
  [(set_attr "length" "3")]
  [(set_attr "length" "3")]
)
)
;; Multiply (high)
;; Multiply (high)
(define_insn "mulhi"
(define_insn "mulhi"
  [(unspec:SI [(match_operand:SI 0 "register_operand" "r")
  [(unspec:SI [(match_operand:SI 0 "register_operand" "r")
               (match_operand:SI 1 "register_operand" "r")]
               (match_operand:SI 1 "register_operand" "r")]
              UNSPEC_BUILTIN_MULHI)]
              UNSPEC_BUILTIN_MULHI)]
  ""
  ""
  "mulhi\t%0, %1"
  "mulhi\t%0, %1"
  [(set_attr "length" "3")]
  [(set_attr "length" "3")]
)
)
;; Multiply (low)
;; Multiply (low)
(define_insn "mullo"
(define_insn "mullo"
  [(unspec:SI [(match_operand:SI 0 "register_operand" "r")
  [(unspec:SI [(match_operand:SI 0 "register_operand" "r")
               (match_operand:SI 1 "register_operand" "r")]
               (match_operand:SI 1 "register_operand" "r")]
              UNSPEC_BUILTIN_MULLO)]
              UNSPEC_BUILTIN_MULLO)]
  ""
  ""
  "mullo\t%0, %1"
  "mullo\t%0, %1"
  [(set_attr "length" "3")]
  [(set_attr "length" "3")]
)
)
;; Move from Accumulator (high)
;; Move from Accumulator (high)
(define_insn "mvfachi"
(define_insn "mvfachi"
  [(set (match_operand:SI 0 "register_operand" "=r")
  [(set (match_operand:SI 0 "register_operand" "=r")
        (unspec:SI [(const_int 0)]
        (unspec:SI [(const_int 0)]
                   UNSPEC_BUILTIN_MVFACHI))]
                   UNSPEC_BUILTIN_MVFACHI))]
  ""
  ""
  "mvfachi\t%0"
  "mvfachi\t%0"
  [(set_attr "length" "3")]
  [(set_attr "length" "3")]
)
)
;; Move from Accumulator (middle)
;; Move from Accumulator (middle)
(define_insn "mvfacmi"
(define_insn "mvfacmi"
  [(set (match_operand:SI 0 "register_operand" "=r")
  [(set (match_operand:SI 0 "register_operand" "=r")
        (unspec:SI [(const_int 0)]
        (unspec:SI [(const_int 0)]
                   UNSPEC_BUILTIN_MVFACMI))]
                   UNSPEC_BUILTIN_MVFACMI))]
  ""
  ""
  "mvfacmi\t%0"
  "mvfacmi\t%0"
  [(set_attr "length" "3")]
  [(set_attr "length" "3")]
)
)
;; Move to Accumulator (high)
;; Move to Accumulator (high)
(define_insn "mvtachi"
(define_insn "mvtachi"
  [(unspec_volatile:SI [(match_operand:SI 0 "register_operand" "r")]
  [(unspec_volatile:SI [(match_operand:SI 0 "register_operand" "r")]
                       UNSPEC_BUILTIN_MVTACHI)]
                       UNSPEC_BUILTIN_MVTACHI)]
  ""
  ""
  "mvtachi\t%0"
  "mvtachi\t%0"
  [(set_attr "length" "3")]
  [(set_attr "length" "3")]
)
)
;; Move to Accumulator (low)
;; Move to Accumulator (low)
(define_insn "mvtaclo"
(define_insn "mvtaclo"
  [(unspec_volatile:SI [(match_operand:SI 0 "register_operand" "r")]
  [(unspec_volatile:SI [(match_operand:SI 0 "register_operand" "r")]
                       UNSPEC_BUILTIN_MVTACLO)]
                       UNSPEC_BUILTIN_MVTACLO)]
  ""
  ""
  "mvtaclo\t%0"
  "mvtaclo\t%0"
  [(set_attr "length" "3")]
  [(set_attr "length" "3")]
)
)
;; Round Accumulator
;; Round Accumulator
(define_insn "racw"
(define_insn "racw"
  [(unspec_volatile:SI [(match_operand:SI 0 "immediate_operand" "i")]
  [(unspec_volatile:SI [(match_operand:SI 0 "immediate_operand" "i")]
                       UNSPEC_BUILTIN_RACW)]
                       UNSPEC_BUILTIN_RACW)]
  ""
  ""
  "racw\t%0"
  "racw\t%0"
  [(set_attr "length" "3")]
  [(set_attr "length" "3")]
)
)
;; Repeat multiply and accumulate
;; Repeat multiply and accumulate
(define_insn "rmpa"
(define_insn "rmpa"
  [(unspec:SI [(const_int 0) (reg:SI 1) (reg:SI 2) (reg:SI 3)
  [(unspec:SI [(const_int 0) (reg:SI 1) (reg:SI 2) (reg:SI 3)
               (reg:SI 4) (reg:SI 5) (reg:SI 6)]
               (reg:SI 4) (reg:SI 5) (reg:SI 6)]
              UNSPEC_BUILTIN_RMPA)
              UNSPEC_BUILTIN_RMPA)
  (clobber (reg:SI 1))
  (clobber (reg:SI 1))
  (clobber (reg:SI 2))
  (clobber (reg:SI 2))
  (clobber (reg:SI 3))]
  (clobber (reg:SI 3))]
  ""
  ""
  "rmpa"
  "rmpa"
  [(set_attr "length" "2")
  [(set_attr "length" "2")
   (set_attr "timings" "1010")]
   (set_attr "timings" "1010")]
)
)
;;---------- Arithmetic ------------------------
;;---------- Arithmetic ------------------------
;; Byte swap (two 16-bit values).
;; Byte swap (two 16-bit values).
(define_insn "revw"
(define_insn "revw"
  [(set (match_operand:SI             0 "register_operand" "+r")
  [(set (match_operand:SI             0 "register_operand" "+r")
        (unspec:SI [(match_operand:SI 1 "register_operand"  "r")]
        (unspec:SI [(match_operand:SI 1 "register_operand"  "r")]
                   UNSPEC_BUILTIN_REVW))]
                   UNSPEC_BUILTIN_REVW))]
  ""
  ""
  "revw\t%1, %0"
  "revw\t%1, %0"
  [(set_attr "length" "3")]
  [(set_attr "length" "3")]
)
)
;; Round to integer.
;; Round to integer.
(define_insn "lrintsf2"
(define_insn "lrintsf2"
  [(set (match_operand:SI             0 "register_operand"  "=r,r")
  [(set (match_operand:SI             0 "register_operand"  "=r,r")
        (unspec:SI [(match_operand:SF 1 "rx_compare_operand" "r,Q")]
        (unspec:SI [(match_operand:SF 1 "rx_compare_operand" "r,Q")]
                   UNSPEC_BUILTIN_ROUND))
                   UNSPEC_BUILTIN_ROUND))
   (clobber (reg:CC CC_REG))]
   (clobber (reg:CC CC_REG))]
  ""
  ""
  "round\t%1, %0"
  "round\t%1, %0"
  [(set_attr "timings" "22,44")
  [(set_attr "timings" "22,44")
   (set_attr "length" "3,5")]
   (set_attr "length" "3,5")]
)
)
;; Saturate to 32-bits
;; Saturate to 32-bits
(define_insn "sat"
(define_insn "sat"
  [(set (match_operand:SI             0 "register_operand" "=r")
  [(set (match_operand:SI             0 "register_operand" "=r")
        (unspec:SI [(match_operand:SI 1 "register_operand"  "0")]
        (unspec:SI [(match_operand:SI 1 "register_operand"  "0")]
                   UNSPEC_BUILTIN_SAT))]
                   UNSPEC_BUILTIN_SAT))]
  ""
  ""
  "sat\t%0"
  "sat\t%0"
  [(set_attr "length" "2")]
  [(set_attr "length" "2")]
)
)
;;---------- Control Registers ------------------------
;;---------- Control Registers ------------------------
;; Clear Processor Status Word
;; Clear Processor Status Word
(define_insn "clrpsw"
(define_insn "clrpsw"
  [(unspec:SI [(match_operand:SI 0 "immediate_operand" "i")]
  [(unspec:SI [(match_operand:SI 0 "immediate_operand" "i")]
              UNSPEC_BUILTIN_CLRPSW)
              UNSPEC_BUILTIN_CLRPSW)
   (clobber (reg:CC CC_REG))]
   (clobber (reg:CC CC_REG))]
  ""
  ""
  "clrpsw\t%F0"
  "clrpsw\t%F0"
  [(set_attr "length" "2")]
  [(set_attr "length" "2")]
)
)
;; Set Processor Status Word
;; Set Processor Status Word
(define_insn "setpsw"
(define_insn "setpsw"
  [(unspec:SI [(match_operand:SI 0 "immediate_operand" "i")]
  [(unspec:SI [(match_operand:SI 0 "immediate_operand" "i")]
              UNSPEC_BUILTIN_SETPSW)
              UNSPEC_BUILTIN_SETPSW)
   (clobber (reg:CC CC_REG))]
   (clobber (reg:CC CC_REG))]
  ""
  ""
  "setpsw\t%F0"
  "setpsw\t%F0"
  [(set_attr "length" "2")]
  [(set_attr "length" "2")]
)
)
;; Move from control register
;; Move from control register
(define_insn "mvfc"
(define_insn "mvfc"
  [(set (match_operand:SI             0 "register_operand" "=r")
  [(set (match_operand:SI             0 "register_operand" "=r")
        (unspec:SI [(match_operand:SI 1 "immediate_operand" "i")]
        (unspec:SI [(match_operand:SI 1 "immediate_operand" "i")]
                   UNSPEC_BUILTIN_MVFC))]
                   UNSPEC_BUILTIN_MVFC))]
  ""
  ""
  "mvfc\t%C1, %0"
  "mvfc\t%C1, %0"
  [(set_attr "length" "3")]
  [(set_attr "length" "3")]
)
)
;; Move to control register
;; Move to control register
(define_insn "mvtc"
(define_insn "mvtc"
  [(unspec:SI [(match_operand:SI 0 "immediate_operand" "i,i")
  [(unspec:SI [(match_operand:SI 0 "immediate_operand" "i,i")
               (match_operand:SI 1 "nonmemory_operand" "r,i")]
               (match_operand:SI 1 "nonmemory_operand" "r,i")]
              UNSPEC_BUILTIN_MVTC)]
              UNSPEC_BUILTIN_MVTC)]
  ""
  ""
  "mvtc\t%1, %C0"
  "mvtc\t%1, %C0"
  [(set_attr "length" "3,7")]
  [(set_attr "length" "3,7")]
  ;; Ignore possible clobbering of the comparison flags in the
  ;; Ignore possible clobbering of the comparison flags in the
  ;; PSW register.  This is a cc0 target so any cc0 setting
  ;; PSW register.  This is a cc0 target so any cc0 setting
  ;; instruction will always be paired with a cc0 user, without
  ;; instruction will always be paired with a cc0 user, without
  ;; the possibility of this instruction being placed in between
  ;; the possibility of this instruction being placed in between
  ;; them.
  ;; them.
)
)
;; Move to interrupt priority level
;; Move to interrupt priority level
(define_insn "mvtipl"
(define_insn "mvtipl"
  [(unspec:SI [(match_operand:SI 0 "immediate_operand" "Uint04")]
  [(unspec:SI [(match_operand:SI 0 "immediate_operand" "Uint04")]
              UNSPEC_BUILTIN_MVTIPL)]
              UNSPEC_BUILTIN_MVTIPL)]
  ""
  ""
  "mvtipl\t%0"
  "mvtipl\t%0"
  [(set_attr "length" "3")]
  [(set_attr "length" "3")]
)
)
;;---------- Interrupts ------------------------
;;---------- Interrupts ------------------------
;; Break
;; Break
(define_insn "brk"
(define_insn "brk"
  [(unspec_volatile [(const_int 0)]
  [(unspec_volatile [(const_int 0)]
                    UNSPEC_BUILTIN_BRK)]
                    UNSPEC_BUILTIN_BRK)]
  ""
  ""
  "brk"
  "brk"
  [(set_attr "length" "1")
  [(set_attr "length" "1")
   (set_attr "timings" "66")]
   (set_attr "timings" "66")]
)
)
;; Interrupt
;; Interrupt
(define_insn "int"
(define_insn "int"
  [(unspec_volatile:SI [(match_operand:SI 0 "immediate_operand" "i")]
  [(unspec_volatile:SI [(match_operand:SI 0 "immediate_operand" "i")]
                       UNSPEC_BUILTIN_INT)]
                       UNSPEC_BUILTIN_INT)]
  ""
  ""
  "int\t%0"
  "int\t%0"
  [(set_attr "length" "3")]
  [(set_attr "length" "3")]
)
)
;; Wait
;; Wait
(define_insn "wait"
(define_insn "wait"
  [(unspec_volatile [(const_int 0)]
  [(unspec_volatile [(const_int 0)]
                    UNSPEC_BUILTIN_WAIT)]
                    UNSPEC_BUILTIN_WAIT)]
  ""
  ""
  "wait"
  "wait"
  [(set_attr "length" "2")]
  [(set_attr "length" "2")]
)
)
;;---------- CoProcessor Support ------------------------
;;---------- CoProcessor Support ------------------------
;; FIXME: The instructions are currently commented out because
;; FIXME: The instructions are currently commented out because
;; the bit patterns have not been finalized, so the assembler
;; the bit patterns have not been finalized, so the assembler
;; does not support them.  Once they are decided and the assembler
;; does not support them.  Once they are decided and the assembler
;; supports them, enable the instructions here.
;; supports them, enable the instructions here.
;; Move from co-processor register
;; Move from co-processor register
(define_insn "mvfcp"
(define_insn "mvfcp"
  [(set (match_operand:SI             0 "register_operand" "=r")
  [(set (match_operand:SI             0 "register_operand" "=r")
        (unspec:SI [(match_operand:SI 1 "immediate_operand" "i")
        (unspec:SI [(match_operand:SI 1 "immediate_operand" "i")
                    (match_operand:SI 2 "immediate_operand" "i")]
                    (match_operand:SI 2 "immediate_operand" "i")]
                   UNSPEC_BUILTIN_MVFCP))]
                   UNSPEC_BUILTIN_MVFCP))]
  ""
  ""
  "; mvfcp\t%1, %0, %2"
  "; mvfcp\t%1, %0, %2"
  [(set_attr "length" "5")]
  [(set_attr "length" "5")]
)
)
;;---------- Misc ------------------------
;;---------- Misc ------------------------
;; Required by cfglayout.c...
;; Required by cfglayout.c...
(define_insn "nop"
(define_insn "nop"
  [(const_int 0)]
  [(const_int 0)]
  ""
  ""
  "nop"
  "nop"
  [(set_attr "length" "1")]
  [(set_attr "length" "1")]
)
)
 
 

powered by: WebSVN 2.1.0

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