home *** CD-ROM | disk | FTP | other *** search
/ Fresh Fish 7 / FreshFishVol7.bin / bbs / gnu / gcc-2.3.3-src.lha / GNU / src / amiga / gcc-2.3.3 / config / m88k.md < prev    next >
Text File  |  1994-02-06  |  107KB  |  3,588 lines

  1. ;;- Machine description for the Motorola 88000 for GNU C compiler
  2. ;;  Copyright (C) 1988, 1989, 1990, 1991 Free Software Foundation, Inc.
  3. ;;  Contributed by Michael Tiemann (tiemann@mcc.com)
  4. ;;  Additional changes by Michael Meissner (meissner@osf.org)
  5. ;;  Currently supported by Tom Wood (wood@dg-rtp.dg.com)
  6.  
  7. ;; This file is part of GNU CC.
  8.  
  9. ;; GNU CC is free software; you can redistribute it and/or modify
  10. ;; it under the terms of the GNU General Public License as published by
  11. ;; the Free Software Foundation; either version 2, or (at your option)
  12. ;; any later version.
  13.  
  14. ;; GNU CC is distributed in the hope that it will be useful,
  15. ;; but WITHOUT ANY WARRANTY; without even the implied warranty of
  16. ;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
  17. ;; GNU General Public License for more details.
  18.  
  19. ;; You should have received a copy of the GNU General Public License
  20. ;; along with GNU CC; see the file COPYING.  If not, write to
  21. ;; the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA.
  22.  
  23.  
  24. ;;- See file "rtl.def" for documentation on define_insn, match_*, et. al.
  25.  
  26. ;; SCCS rev field.  This is a NOP, just to get the SCCS id into the
  27. ;; program image.
  28. (define_expand "m88k_sccs_id"
  29.   [(match_operand:SI 0 "" "")]
  30.   ""
  31.   "{ static char sccs_id[] = \"@(#)m88k.md    2.3.2.2 11/05/92 09:03:51\";
  32.      FAIL; }")
  33.  
  34. ;; Attribute specifications
  35.  
  36. ; Target CPU.
  37. (define_attr "cpu" "m88100,m88110,m88000"
  38.   (const (symbol_ref "m88k_cpu")))
  39.  
  40. ; Type of each instruction.  Default is arithmetic.
  41. ; I'd like to write the list as this, but genattrtab won't accept it.
  42. ;
  43. ; "branch,jump,call,            ; flow-control instructions
  44. ;  load,store,loadd,loada,        ; data unit instructions
  45. ;  spadd,dpadd,spcmp,dpcmp,spdiv,dpdiv,idiv, ; FPU add instructions
  46. ;  spmul,dpmul,imul,            ; FPU multiply instructions
  47. ;  arith,bit,mov            ; integer unit instructions
  48. ;  marith,weird"            ; multi-word instructions
  49.  
  50. ; Classification of each insn.  Some insns of TYPE_BRANCH are multi-word.
  51. (define_attr "type"
  52.   "branch,jump,call,load,store,loadd,loada,spadd,dpadd,spcmp,dpcmp,spdiv,dpdiv,idiv,spmul,dpmul,imul,arith,bit,mov,marith,weird"
  53.   (const_string "arith"))
  54.  
  55. (define_attr "fpu" "yes,no"
  56.   (if_then_else
  57.    (eq_attr "type" "spmul,dpmul,imul,spadd,dpadd,spcmp,dpcmp,spdiv,dpdiv,idiv")
  58.    (const_string "yes") (const_string "no")))
  59.  
  60. ; Length in # of instructions of each insn.  The values are not exact, but
  61. ; are safe.
  62. (define_attr "length" ""
  63.   (cond [(eq_attr "type" "marith")
  64.      (const_int 2)]
  65.     (const_int 1)))
  66.  
  67. ; Describe a user's asm statement.
  68. (define_asm_attributes
  69.   [(set_attr "type" "weird")])
  70.  
  71. ; Define the delay slot requirements for branches and calls.
  72. ; The m88100 annuls instructions if a conditional branch is taken.
  73. ; For insns of TYPE_BRANCH that are multi-word instructions, the
  74. ; delay slot applies to the first instruction.
  75.  
  76. ; @@ For the moment, reorg.c requires that the delay slot of a branch not
  77. ; be a call or branch.
  78.  
  79. (define_delay (eq_attr "type" "branch,jump")
  80.   [(and
  81.     (and
  82.      (eq_attr "type" "!branch,jump,call,marith,weird") ; required.
  83.      (eq_attr "type" "!load,loadd")) ; issue as-soon-as-possible.
  84.     (eq_attr "fpu" "no")) ; issue as-soon-as-possible.
  85.    (eq_attr "type" "!call,branch,jump") (nil)]) ; @@ was (const_int 1)
  86.  
  87. ; output_call supports an unconditional branch in the delay slot of
  88. ; a call.  (@@ Support for this case is expected in reorg.c soon.)
  89.  
  90. (define_delay (eq_attr "type" "call")
  91.   [(eq_attr "type" "!branch,call,marith,weird") ; required.
  92.    (nil) (nil)])
  93.  
  94. ; An abstract block diagram of the function units for the m88100.
  95. ;
  96. ;                *
  97. ;                |
  98. ;            +---v----+
  99. ;            | decode |
  100. ;            +-vv-v-v-+     fpu
  101. ;           ,----------'| | `----------------------.
  102. ;           |       | |                  |    ,-----.
  103. ;      load |     store | | arith              |    |     |
  104. ;           |       | |                +-v-v-+   |    dp source
  105. ;           |       | |                | fp1 |---'
  106. ;     store    |       | |        div            +-v-v-+
  107. ;   ,------.   |       | |      ,-----. ,-----------'    `-----------.
  108. ;   |       |   |       | |      |    | |                |
  109. ;   |    +--v---v--+    ,---' |      |   +-v-v---+            +---v---+
  110. ;   |    | stage    2 |    |     |      `---|    add 2 |            | mul 2    |
  111. ;   |    +---------+    |  +--v--+     +-------+          imul    +-------+
  112. ;   |    | stage    1 |    |  | alu    |     |    add 3 |           ,--------| mul 3    |
  113. ;   |    +---------+    |  +--v--+     +-------+           |    +-------+
  114. ;   |    | stage    0 |    |     |          |    add 4 |           |    | mul 4    |
  115. ;   |    +--v---v--+    |     |          +---v---+           |    +-------+
  116. ;   |       |   |       |     |          |           |    | mul 5    |
  117. ;   |       *   |       |     |          |           |    +---v---+
  118. ;   |           |       |     |          |      +----v----+        |
  119. ;   |      load |       |     |       fp add `------>| fp last |<------' fp mul
  120. ;   |           |       |     |              +---v-v--^+
  121. ;   |           |       |     |                  |    |  |
  122. ;   |           |       |     |                  |    `--' dp    dest
  123. ;   |           |    +--v-----v--+              |
  124. ;   |           `--->| writeback    |<--------------------'
  125. ;   |            +--v-----v--+
  126. ;   |               |     |
  127. ;   `------------------'     *
  128. ;
  129. ; The decode unit need not be specified.
  130. ; Consideration of writeback contention is critical to superb scheduling.
  131. ;
  132. ; (define_function_unit NAME MULTIPLICITY SIMULTANEITY
  133. ;            TEST READY-DELAY ISSUE-DELAY [CONFLICT-LIST])
  134.  
  135. ; Describing the '100 alu is currently not useful.
  136. ;(define_function_unit "alu" 1 0 (eq_attr "type"
  137. ;                     "!store,marith,weird") 1 0)
  138. ;(define_function_unit "alu" 1 0 (eq_attr "type" "marith,weird") 2 0)
  139.  
  140. (define_function_unit "alu" 1 0
  141.   (and (eq_attr "type" "loada,arith,mov") (eq_attr "cpu" "!m88100")) 2 0)
  142. (define_function_unit "alu" 1 0
  143.   (and (eq_attr "type" "marith,weird") (eq_attr "cpu" "!m88100")) 4 0)
  144.  
  145. (define_function_unit "bit" 1 0
  146.   (and (eq_attr "type" "bit") (eq_attr "cpu" "!m88100")) 2 2)
  147.  
  148. (define_function_unit "mem100" 1 0
  149.   (and (eq_attr "type" "store,loada") (eq_attr "cpu" "m88100")) 1 0)
  150. (define_function_unit "mem100" 1 0
  151.   (and (eq_attr "type" "load") (eq_attr "cpu" "m88100")) 3 0)
  152. (define_function_unit "mem100" 1 0
  153.   (and (eq_attr "type" "loadd") (eq_attr "cpu" "m88100")) 3 2)
  154.  
  155. (define_function_unit "mem110" 1 0
  156.   (and (eq_attr "type" "load,loadd") (eq_attr "cpu" "!m88100")) 3 2)
  157. (define_function_unit "mem110" 1 0
  158.   (and (eq_attr "type" "store") (eq_attr "cpu" "!m88100")) 1 2)
  159.  
  160. ; The times are adjusted to include fp1 and fplast, but then are further
  161. ; adjusted based on the actual generated code.  The notation to the right
  162. ; is the total latency.  A range denotes a group of instructions and/or
  163. ; conditions (the extra clock of fplast time with some sequences).
  164.  
  165. (define_function_unit "fpmul100" 1 0
  166.   (and (eq_attr "type" "spmul") (eq_attr "cpu" "m88100")) 4 0)        ; 6-8
  167. (define_function_unit "fpmul100" 1 0
  168.   (and (eq_attr "type" "dpmul") (eq_attr "cpu" "m88100")) 7 0)        ; 9-10
  169. (define_function_unit "fpmul100" 1 0
  170.   (and (eq_attr "type" "imul") (eq_attr "cpu" "m88100")) 3 0)        ; 4
  171.  
  172. (define_function_unit "fpmul110" 1 0
  173.   (and (eq_attr "type" "imul,spmul,dpmul")
  174.        (eq_attr "cpu" "!m88100")) 5 2)                    ; 3
  175.  
  176. (define_function_unit "fpadd100" 1 5
  177.   (and (eq_attr "type" "spadd,spcmp") (eq_attr "cpu" "m88100")) 3 0)    ; 5-6
  178. (define_function_unit "fpadd100" 1 5
  179.   (and (eq_attr "type" "dpadd,dpcmp") (eq_attr "cpu" "m88100")) 4 0)    ; 6-7
  180.  
  181. (define_function_unit "fpadd110" 1 0
  182.   (and (eq_attr "type" "spadd,dpadd") (eq_attr "cpu" "!m88100")) 5 2)    ; 3
  183. (define_function_unit "fpadd110" 1 0
  184.   (and (eq_attr "type" "spcmp,dpcmp") (eq_attr "cpu" "!m88100")) 2 2)    ; 1
  185.  
  186. (define_function_unit "fpadd100" 1 5
  187.   (and (eq_attr "type" "spdiv") (eq_attr "cpu" "m88100")) 30 0)        ; 30-31
  188. (define_function_unit "fpadd100" 1 5
  189.   (and (eq_attr "type" "dpdiv") (eq_attr "cpu" "m88100")) 60 0)        ; 60-61
  190. (define_function_unit "fpadd100" 1 5
  191.   (and (eq_attr "type" "idiv") (eq_attr "cpu" "m88100")) 38 0)        ; 38
  192.  
  193. (define_function_unit "div" 1 1
  194.   (and (eq_attr "type" "spdiv") (eq_attr "cpu" "!m88100")) 25 2)    ; 13
  195. (define_function_unit "div" 1 1
  196.   (and (eq_attr "type" "dpdiv") (eq_attr "cpu" "!m88100")) 45 2)    ; 23
  197. (define_function_unit "div" 1 1
  198.   (and (eq_attr "type" "idiv") (eq_attr "cpu" "!m88100")) 35 2)        ; 18
  199.  
  200. ;; Superoptimizer sequences
  201.  
  202. ;; geu+: { r = ((unsigned_word) v0 >= (unsigned_word) v1) + v2; }
  203. ;;      subu.co r5,r2,r3
  204. ;;      addu.cio r6,r4,r0
  205.  
  206. (define_split
  207.   [(set (match_operand:SI 0 "register_operand" "=r")
  208.     (minus:SI (match_operand:SI 1 "register_operand" "r")
  209.           (geu:SI (match_operand:SI 2 "register_operand" "r")
  210.               (match_operand:SI 3 "register_operand" "r"))))]
  211.   ""
  212.   [(set (reg:CC 0) (unspec:CC [(match_dup 2) (match_dup 3)] 1))
  213.    (set (match_dup 0)
  214.     (plus:SI (match_dup 1)
  215.          (unspec:SI [(const_int 0)
  216.                  (reg:CC 0)] 0)))]
  217.   "")
  218.  
  219. ;; leu+: { r = ((unsigned_word) v0 <= (unsigned_word) v1) + v2; }
  220. ;;      subu.co r5,r3,r2
  221. ;;      addu.cio r6,r4,r0
  222.  
  223. (define_split
  224.   [(set (match_operand:SI 0 "register_operand" "=r")
  225.     (minus:SI (match_operand:SI 1 "register_operand" "r")
  226.           (leu:SI (match_operand:SI 3 "register_operand" "r")
  227.               (match_operand:SI 2 "register_operand" "r"))))]
  228.   ""
  229.   [(set (reg:CC 0) (unspec:CC [(match_dup 2) (match_dup 3)] 1))
  230.    (set (match_dup 0)
  231.     (plus:SI (match_dup 1)
  232.          (unspec:SI [(const_int 0)
  233.                  (reg:CC 0)] 0)))]
  234.   "")
  235.  
  236. ;; eq0+: { r = (v0 == 0) + v1; }
  237. ;;      subu.co r4,r0,r2
  238. ;;      addu.cio r5,r3,r0
  239.  
  240. (define_split
  241.   [(set (match_operand:SI 0 "register_operand" "=r")
  242.     (minus:SI (match_operand:SI 1 "register_operand" "r")
  243.           (eq:SI (match_operand:SI 2 "register_operand" "r")
  244.              (const_int 0))))]
  245.   ""
  246.   [(set (reg:CC 0) (unspec:CC [(const_int 0) (match_dup 2)] 1))
  247.    (set (match_dup 0)
  248.     (plus:SI (match_dup 1)
  249.          (unspec:SI [(const_int 0)
  250.                  (reg:CC 0)] 0)))]
  251.   "")
  252.  
  253. ;; ltu-:  { r = v2 - ((unsigned_word) v0 < (unsigned_word) v1); }
  254. ;;      subu.co r5,r2,r3
  255. ;;      subu.cio r6,r4,r0
  256.  
  257. (define_split
  258.   [(set (match_operand:SI 0 "register_operand" "=r")
  259.     (plus:SI (ltu:SI (match_operand:SI 2 "register_operand" "r")
  260.              (match_operand:SI 3 "register_operand" "r"))
  261.          (match_operand:SI 1 "register_operand" "r")))]
  262.   ""
  263.   [(set (reg:CC 0) (unspec:CC [(match_dup 2) (match_dup 3)] 1))
  264.    (set (match_dup 0)
  265.     (minus:SI (match_dup 1)
  266.           (unspec:SI [(const_int 0)
  267.                   (reg:CC 0)] 1)))]
  268.   "")
  269.  
  270. ;; gtu-: { r = v2 - ((unsigned_word) v0 > (unsigned_word) v1); }
  271. ;;      subu.co r5,r3,r2
  272. ;;      subu.cio r6,r4,r0
  273.  
  274. (define_split
  275.   [(set (match_operand:SI 0 "register_operand" "=r")
  276.     (plus:SI (gtu:SI (match_operand:SI 3 "register_operand" "r")
  277.              (match_operand:SI 2 "register_operand" "r"))
  278.          (match_operand:SI 1 "register_operand" "r")))]
  279.   ""
  280.   [(set (reg:CC 0) (unspec:CC [(match_dup 2) (match_dup 3)] 1))
  281.    (set (match_dup 0)
  282.     (minus:SI (match_dup 1)
  283.          (unspec:SI [(const_int 0)
  284.                  (reg:CC 0)] 1)))]
  285.   "")
  286.  
  287. ;; ne0-: { r = v1 - (v0 != 0); }
  288. ;;      subu.co r4,r0,r2
  289. ;;      subu.cio r5,r3,r0
  290.  
  291. (define_split
  292.   [(set (match_operand:SI 0 "register_operand" "=r")
  293.     (plus:SI (ne:SI (match_operand:SI 2 "register_operand" "r")
  294.             (const_int 0))
  295.          (match_operand:SI 1 "register_operand" "r")))]
  296.   ""
  297.   [(set (reg:CC 0) (unspec:CC [(const_int 0) (match_dup 2)] 1))
  298.    (set (match_dup 0)
  299.     (minus:SI (match_dup 1)
  300.           (unspec:SI [(const_int 0)
  301.                   (reg:CC 0)] 1)))]
  302.   "")
  303.  
  304. ;; ges0-: { r = v1 - ((signed_word) v0 >= 0); }
  305. ;;    addu.co    r4,r2,r2
  306. ;;    subu.cio r5,r3,r0
  307.  
  308. (define_split
  309.   [(set (match_operand:SI 0 "register_operand" "=r")
  310.     (minus:SI (match_operand:SI 1 "register_operand" "r")
  311.           (xor:SI (lshiftrt:SI
  312.                (match_operand:SI 2 "register_operand" "r")
  313.                (const_int 31))
  314.               (const_int 1))))]
  315.   ""
  316.   [(set (reg:CC 0) (unspec:CC [(match_dup 2) (match_dup 2)] 0))
  317.    (set (match_dup 0)
  318.     (minus:SI (match_dup 1)
  319.           (unspec:SI [(const_int 0)
  320.                   (reg:CC 0)] 1)))]
  321.   "")
  322.  
  323. ;; This rich set of complex patterns are mostly due to Torbjorn Granlund
  324. ;; (tege@sics.se).  They've changed since then, so don't complain to him
  325. ;; if they don't work right.
  326.  
  327. ;; Regarding shifts, gen_lshlsi3 generates ASHIFT.  LSHIFT opcodes are
  328. ;; not produced and should not normally occur.  Also, the gen functions
  329. ;; produce the necessary insns to support TARGET_*_LARGE_SHIFT, so nothing
  330. ;; special needs to be done here.
  331.  
  332. ;; Optimize possible cases of the set instruction.
  333.  
  334. (define_insn ""
  335.   [(set (match_operand:SI 0 "register_operand" "=r")
  336.         (ashift:SI (const_int -1)
  337.                (match_operand:SI 1 "register_operand" "r")))]
  338.   ""
  339.   "set %0,%#r0,%1"
  340.   [(set_attr "type" "bit")])
  341.  
  342. (define_insn ""
  343.   [(set (match_operand:SI 0 "register_operand" "=r")
  344.         (ior:SI (ashift:SI (const_int -1)
  345.                    (match_operand:SI 1 "register_operand" "r"))
  346.             (match_operand:SI 2 "register_operand" "r")))]
  347.   ""
  348.   "set %0,%2,%1"
  349.   [(set_attr "type" "bit")])
  350.  
  351. (define_insn ""
  352.   [(set (match_operand:SI 0 "register_operand" "=r")
  353.         (ior:SI (match_operand:SI 1 "register_operand" "r")
  354.             (ashift:SI (const_int -1)
  355.                    (match_operand:SI 2 "register_operand" "r"))))]
  356.   ""
  357.   "set %0,%1,%2"
  358.   [(set_attr "type" "bit")])
  359.  
  360. ;; Optimize possible cases of the mak instruction.
  361.  
  362. (define_insn ""
  363.   [(set (match_operand:SI 0 "register_operand" "=r")
  364.     (and:SI (ashift:SI (match_operand:SI 1 "register_operand" "r")
  365.                (match_operand:SI 2 "int5_operand" ""))
  366.         (match_operand:SI 3 "immediate_operand" "n")))]
  367.   "mak_mask_p (INTVAL (operands[3]) >> INTVAL (operands[2]))"
  368.   "*
  369. {
  370.   operands[4] = gen_rtx (CONST_INT, SImode,
  371.              exact_log2 (1 + (INTVAL (operands[3])
  372.                       >> INTVAL(operands[2]))));
  373.   return \"mak %0,%1,%4<%2>\";
  374. }"
  375.   [(set_attr "type" "bit")])
  376.  
  377. ;; Optimize possible cases of output_and.
  378.  
  379. (define_insn ""
  380.   [(set (match_operand:SI 0 "register_operand" "=r")
  381.     (ashift:SI (zero_extract:SI (match_operand:SI 1 "register_operand" "r")
  382.                     (match_operand:SI 2 "int5_operand" "")
  383.                     (match_operand:SI 3 "int5_operand" ""))
  384.            (match_operand:SI 4 "int5_operand" "")))]
  385.   "INTVAL (operands[2]) + INTVAL (operands[3]) + INTVAL (operands[4]) == 32"
  386.   "*
  387. {
  388.   operands[2]
  389.     = gen_rtx (CONST_INT, SImode,
  390.            ((1 << INTVAL (operands[2])) - 1) << INTVAL (operands[4]));
  391.   return output_and (operands);
  392. }"
  393.   [(set_attr "type" "marith")]) ; arith,bit,marith.  length is 1 or 2.
  394.  
  395. ;; Improve logical operations on compare words
  396. ;;
  397. ;; We define all logical operations on CCmode values to preserve the pairwise
  398. ;; relationship of the compare bits.  This allows a future branch prediction
  399. ;; pass the degree of freedom needed to change and/bb0-le into or/bb1-gt.
  400. ;;
  401. ;; Opportunities arise when conditional expressions using && and || are made
  402. ;; unconditional.  When these are used to branch, the sequence is
  403. ;; cmp/cmp/extu/extu/{and,or}/bcnd-{eq0,ne0}.  When these are used to create
  404. ;; a value, the sequence is cmp/cmp/extu/extu/{and,or} for 1 or 0 or
  405. ;; cmp/cmp/ext/ext/{and,or} for -1 or 0.
  406. ;;
  407. ;; When the extracted conditions are the same, the define_split patterns
  408. ;; below change extu/extu/{and,or} into {and,or}/extu.  If the reversed
  409. ;; conditions match, one compare word can be complimented, resulting in
  410. ;; {and.c,or.c}/extu.  These changes are done for ext/ext/{and,or} as well.
  411. ;; If the conditions don't line up, one can be rotated.  To keep the pairwise
  412. ;; relationship, it may be necessary to both rotate and compliment.  Rotating
  413. ;; makes branching cheaper, but doesn't help (or hurt) creating a value, so
  414. ;; we don't do this for ext/ext/{and,or}.
  415. ;;
  416. ;; These changes result in the sequence extu/bcnd-{eq0,ne0} which is combined
  417. ;; into an alternate form of bb0 and bb1.
  418.  
  419. (define_split
  420.   [(set (match_operand:SI 0 "register_operand" "=r")
  421.     (ior:SI (neg:SI 
  422.          (match_operator 1 "relop"
  423.                  [(match_operand:CC 2 "register_operand" "%r")
  424.                   (const_int 0)]))
  425.         (neg:SI
  426.          (match_operator 3 "relop"
  427.                  [(match_operand:CC 4 "register_operand" "r")
  428.                   (const_int 0)]))))
  429.    (clobber (match_operand:SI 5 "register_operand" "=r"))]
  430.   ""
  431.   [(set (match_dup 5)
  432.     (ior:CC (match_dup 4)
  433.         (match_dup 2)))
  434.    (set (match_dup 0)
  435.     (neg:SI (match_op_dup 1 [(match_dup 5) (const_int 0)])))]
  436.   "operands[5] = gen_rtx (SUBREG, CCmode, operands[5], 0);
  437.    if (GET_CODE (operands[1]) == GET_CODE (operands[3]))
  438.      ; /* The conditions match.  */
  439.    else if (GET_CODE (operands[1])
  440.         == reverse_condition (GET_CODE (operands[3])))
  441.      /* Reverse the condition by complimenting the compare word.  */
  442.      operands[4] = gen_rtx (NOT, CCmode, operands[4]);
  443.    else
  444.      {
  445.        /* Make the condition pairs line up by rotating the compare word.  */
  446.        int cv1 = condition_value (operands[1]);
  447.        int cv2 = condition_value (operands[3]);
  448.  
  449.        operands[4] = gen_rtx (ROTATE, CCmode, operands[4],
  450.                   gen_rtx (CONST_INT, VOIDmode,
  451.                        ((cv2 & ~1) - (cv1 & ~1)) & 0x1f));
  452.        /* Reverse the condition if needed.  */
  453.        if ((cv1 & 1) != (cv2 & 1))
  454.      operands[4] = gen_rtx (NOT, CCmode, operands[4]);
  455.      }")
  456.  
  457. (define_split
  458.   [(set (match_operand:SI 0 "register_operand" "=r")
  459.     (ior:SI (match_operator 1 "relop"
  460.                 [(match_operand:CC 2 "register_operand" "%r")
  461.                  (const_int 0)])
  462.         (match_operator 3 "relop"
  463.                 [(match_operand:CC 4 "register_operand" "r")
  464.                  (const_int 0)])))
  465.    (clobber (match_operand:SI 5 "register_operand" "=r"))]
  466.   "GET_CODE (operands[1]) == GET_CODE (operands[3])
  467.    || GET_CODE (operands[1]) == reverse_condition (GET_CODE (operands[3]))"
  468.   [(set (match_dup 5)
  469.     (ior:CC (match_dup 4)
  470.         (match_dup 2)))
  471.    (set (match_dup 0)
  472.     (match_op_dup 1 [(match_dup 5) (const_int 0)]))]
  473.   "operands[5] = gen_rtx (SUBREG, CCmode, operands[5], 0);
  474.    /* Reverse the condition by  complimenting the compare word.  */
  475.    if (GET_CODE (operands[1]) != GET_CODE (operands[3]))
  476.       operands[4] = gen_rtx (NOT, CCmode, operands[4]);")
  477.  
  478. (define_split
  479.   [(set (match_operand:SI 0 "register_operand" "=r")
  480.     (and:SI (neg:SI 
  481.          (match_operator 1 "relop"
  482.                  [(match_operand:CC 2 "register_operand" "%r")
  483.                   (const_int 0)]))
  484.         (neg:SI
  485.          (match_operator 3 "relop"
  486.                  [(match_operand:CC 4 "register_operand" "r")
  487.                   (const_int 0)]))))
  488.    (clobber (match_operand:SI 5 "register_operand" "=r"))]
  489.   ""
  490.   [(set (match_dup 5)
  491.     (and:CC (match_dup 4)
  492.         (match_dup 2)))
  493.    (set (match_dup 0)
  494.     (neg:SI (match_op_dup 1 [(match_dup 5) (const_int 0)])))]
  495.   "operands[5] = gen_rtx (SUBREG, CCmode, operands[5], 0);
  496.    if (GET_CODE (operands[1]) == GET_CODE (operands[3]))
  497.      ; /* The conditions match.  */
  498.    else if (GET_CODE (operands[1])
  499.         == reverse_condition (GET_CODE (operands[3])))
  500.      /* Reverse the condition by complimenting the compare word.  */
  501.      operands[4] = gen_rtx (NOT, CCmode, operands[4]);
  502.    else
  503.      {
  504.        /* Make the condition pairs line up by rotating the compare word.  */
  505.        int cv1 = condition_value (operands[1]);
  506.        int cv2 = condition_value (operands[3]);
  507.  
  508.        operands[4] = gen_rtx (ROTATE, CCmode, operands[4],
  509.                   gen_rtx (CONST_INT, VOIDmode,
  510.                        ((cv2 & ~1) - (cv1 & ~1)) & 0x1f));
  511.        /* Reverse the condition if needed.  */
  512.        if ((cv1 & 1) != (cv2 & 1))
  513.      operands[4] = gen_rtx (NOT, CCmode, operands[4]);
  514.      }")
  515.  
  516. (define_split
  517.   [(set (match_operand:SI 0 "register_operand" "=r")
  518.     (and:SI (match_operator 1 "relop"
  519.                 [(match_operand:CC 2 "register_operand" "%r")
  520.                  (const_int 0)])
  521.         (match_operator 3 "relop"
  522.                 [(match_operand:CC 4 "register_operand" "r")
  523.                  (const_int 0)])))
  524.    (clobber (match_operand:SI 5 "register_operand" "=r"))]
  525.   "GET_CODE (operands[1]) == GET_CODE (operands[3])
  526.    || GET_CODE (operands[1]) == reverse_condition (GET_CODE (operands[3]))"
  527.   [(set (match_dup 5)
  528.     (and:CC (match_dup 4)
  529.         (match_dup 2)))
  530.    (set (match_dup 0)
  531.     (match_op_dup 1 [(match_dup 5) (const_int 0)]))]
  532.   "operands[5] = gen_rtx (SUBREG, CCmode, operands[5], 0);
  533.    /* Reverse the condition by  complimenting the compare word.  */
  534.    if (GET_CODE (operands[1]) != GET_CODE (operands[3]))
  535.       operands[4] = gen_rtx (NOT, CCmode, operands[4]);")
  536.  
  537. ;; Logical operations on compare words.
  538.  
  539. (define_insn ""
  540.   [(set (match_operand:CC 0 "register_operand" "=r")
  541.     (and:CC (not:CC (match_operand:CC 1 "register_operand" "r"))
  542.         (match_operand:CC 2 "register_operand" "r")))]
  543.   ""
  544.   "and.c %0,%2,%1")
  545.  
  546.  
  547. (define_insn ""
  548.   [(set (match_operand:CC 0 "register_operand" "=r")
  549.     (and:CC (match_operand:CC 1 "register_operand" "%r")
  550.         (match_operand:CC 2 "register_operand" "r")))]
  551.   ""
  552.   "and %0,%1,%2")
  553.  
  554. (define_insn ""
  555.   [(set (match_operand:CC 0 "register_operand" "=r")
  556.     (ior:CC (not:CC (match_operand:CC 1 "register_operand" "r"))
  557.         (match_operand:CC 2 "register_operand" "r")))]
  558.   ""
  559.   "or.c %0,%2,%1")
  560.  
  561. (define_insn ""
  562.   [(set (match_operand:CC 0 "register_operand" "=r")
  563.     (ior:CC (match_operand:CC 1 "register_operand" "%r")
  564.         (match_operand:CC 2 "register_operand" "r")))]
  565.   ""
  566.   "or %0,%1,%2")
  567.  
  568. (define_insn ""
  569.   [(set (match_operand:CC 0 "register_operand" "=r")
  570.     (rotate:CC (match_operand:CC 1 "register_operand" "r")
  571.            (match_operand:CC 2 "int5_operand" "")))]
  572.   ""
  573.   "rot %0,%1,%2"
  574.   [(set_attr "type" "bit")])
  575.  
  576. ;; rotate/and[.c] and rotate/ior[.c]
  577.  
  578. (define_split
  579.   [(set (match_operand:CC 0 "register_operand" "=r")
  580.     (ior:CC (rotate:CC (match_operand:CC 1 "register_operand" "r")
  581.                (match_operand:CC 2 "int5_operand" ""))
  582.         (match_operand:CC 3 "register_operand" "r")))
  583.    (clobber (match_operand:CC 4 "register_operand" "=r"))]
  584.   ""
  585.   [(set (match_dup 4)
  586.     (rotate:CC (match_dup 1) (match_dup 2)))
  587.    (set (match_dup 0)
  588.     (ior:CC (match_dup 4) (match_dup 3)))]
  589.   "")
  590.  
  591. (define_insn ""
  592.   [(set (match_operand:CC 0 "register_operand" "=r")
  593.     (ior:CC (rotate:CC (match_operand:CC 1 "register_operand" "r")
  594.                (match_operand:CC 2 "int5_operand" ""))
  595.         (match_operand:CC 3 "register_operand" "r")))
  596.    (clobber (match_scratch:CC 4 "=r"))]
  597.   ""
  598.   "#")
  599.  
  600. (define_split
  601.   [(set (match_operand:CC 0 "register_operand" "=r")
  602.     (ior:CC (not:CC (rotate:CC (match_operand:CC 1 "register_operand" "r")
  603.                    (match_operand:CC 2 "int5_operand" "")))
  604.         (match_operand:CC 3 "register_operand" "r")))
  605.    (clobber (match_operand:CC 4 "register_operand" "=r"))]
  606.   ""
  607.   [(set (match_dup 4)
  608.     (rotate:CC (match_dup 1) (match_dup 2)))
  609.    (set (match_dup 0)
  610.     (ior:CC (not:CC (match_dup 4)) (match_dup 3)))]
  611.   "")
  612.  
  613. (define_insn ""
  614.   [(set (match_operand:CC 0 "register_operand" "=r")
  615.     (ior:CC (not:CC (rotate:CC (match_operand:CC 1 "register_operand" "r")
  616.                    (match_operand:CC 2 "int5_operand" "")))
  617.         (match_operand:CC 3 "register_operand" "r")))
  618.    (clobber (match_scratch:CC 4 "=r"))]
  619.   ""
  620.   "#")
  621.  
  622. (define_split
  623.   [(set (match_operand:CC 0 "register_operand" "=r")
  624.     (and:CC (rotate:CC (match_operand:CC 1 "register_operand" "r")
  625.                (match_operand:CC 2 "int5_operand" ""))
  626.         (match_operand:CC 3 "register_operand" "r")))
  627.    (clobber (match_operand:CC 4 "register_operand" "=r"))]
  628.   ""
  629.   [(set (match_dup 4)
  630.     (rotate:CC (match_dup 1) (match_dup 2)))
  631.    (set (match_dup 0)
  632.     (and:CC (match_dup 4) (match_dup 3)))]
  633.   "")
  634.  
  635. (define_insn ""
  636.   [(set (match_operand:CC 0 "register_operand" "=r")
  637.     (and:CC (rotate:CC (match_operand:CC 1 "register_operand" "r")
  638.                (match_operand:CC 2 "int5_operand" ""))
  639.         (match_operand:CC 3 "register_operand" "r")))
  640.    (clobber (match_scratch:CC 4 "=r"))]
  641.   ""
  642.   "#")
  643.  
  644. (define_split
  645.   [(set (match_operand:CC 0 "register_operand" "=r")
  646.     (and:CC (not:CC (rotate:CC (match_operand:CC 1 "register_operand" "r")
  647.                    (match_operand:CC 2 "int5_operand" "")))
  648.         (match_operand:CC 3 "register_operand" "r")))
  649.    (clobber (match_operand:CC 4 "register_operand" "=r"))]
  650.   ""
  651.   [(set (match_dup 4)
  652.     (rotate:CC (match_dup 1) (match_dup 2)))
  653.    (set (match_dup 0)
  654.     (and:CC (not:CC (match_dup 4)) (match_dup 3)))]
  655.   "")
  656.  
  657. (define_insn ""
  658.   [(set (match_operand:CC 0 "register_operand" "=r")
  659.     (and:CC (not:CC (rotate:CC (match_operand:CC 1 "register_operand" "r")
  660.                    (match_operand:CC 2 "int5_operand" "")))
  661.         (match_operand:CC 3 "register_operand" "r")))
  662.    (clobber (match_scratch:CC 4 "=r"))]
  663.   ""
  664.   "#")
  665.  
  666. ;; Recognize bcnd instructions for integer values.  This is distinguished
  667. ;; from a conditional branch instruction (below) with SImode instead of
  668. ;; CCmode.
  669.  
  670. (define_insn ""
  671.   [(set (pc)
  672.     (if_then_else
  673.      (match_operator 0 "relop_no_unsigned"
  674.              [(match_operand:SI 1 "register_operand" "r")
  675.               (const_int 0)])
  676.      (match_operand 2 "pc_or_label_ref" "")
  677.      (match_operand 3 "pc_or_label_ref" "")))]
  678.   ""
  679.   "bcnd%. %R3%B0,%1,%P2%P3"
  680.   [(set_attr "type" "branch")])
  681.  
  682. ;; Recognize tests for sign and zero.
  683.  
  684. (define_insn ""
  685.   [(set (pc)
  686.     (if_then_else
  687.      (match_operator 0 "equality_op"
  688.              [(match_operand:SI 1 "register_operand" "r")
  689.               (const_int -2147483648)])
  690.      (match_operand 2 "pc_or_label_ref" "")
  691.      (match_operand 3 "pc_or_label_ref" "")))]
  692.   ""
  693.   "bcnd%. %R3%E0,%1,%P2%P3"
  694.   [(set_attr "type" "branch")])
  695.  
  696. (define_insn ""
  697.   [(set (pc)
  698.     (if_then_else
  699.      (match_operator 0 "equality_op"
  700.              [(zero_extract:SI
  701.                (match_operand:SI 1 "register_operand" "r")
  702.                (const_int 31)
  703.                (const_int 1))
  704.               (const_int 0)])
  705.      (match_operand 2 "pc_or_label_ref" "")
  706.      (match_operand 3 "pc_or_label_ref" "")))]
  707.   ""
  708.   "bcnd%. %R3%D0,%1,%P2%P3"
  709.   [(set_attr "type" "branch")])
  710.  
  711. ;; Recognize bcnd instructions for double integer values
  712.  
  713. (define_insn ""
  714.   [(set (pc)
  715.     (if_then_else
  716.      (match_operator 0 "relop_no_unsigned"
  717.              [(sign_extend:DI
  718.                (match_operand:SI 1 "register_operand" "r"))
  719.               (const_int 0)])
  720.      (match_operand 2 "pc_or_label_ref" "")
  721.      (match_operand 3 "pc_or_label_ref" "")))]
  722.   ""
  723.   "bcnd%. %R3%B0,%1,%P2%P3"
  724.   [(set_attr "type" "branch")])
  725.  
  726. (define_insn ""
  727.   [(set (pc)
  728.     (if_then_else
  729.      (match_operator 0 "equality_op"
  730.              [(zero_extend:DI
  731.                (match_operand:SI 1 "register_operand" "r"))
  732.               (const_int 0)])
  733.      (match_operand 2 "pc_or_label_ref" "")
  734.      (match_operand 3 "pc_or_label_ref" "")))]
  735.   ""
  736.   "bcnd%. %R3%B0,%1,%P2%P3"
  737.   [(set_attr "type" "branch")])
  738.  
  739. ; @@ I doubt this is interesting until cmpdi is provided.  Anyway, it needs
  740. ; to be reworked.
  741. ;
  742. ;(define_insn ""
  743. ;  [(set (pc)
  744. ;    (if_then_else
  745. ;     (match_operator 0 "relop_no_unsigned"
  746. ;             [(match_operand:DI 1 "register_operand" "r")
  747. ;              (const_int 0)])
  748. ;     (match_operand 2 "pc_or_label_ref" "")
  749. ;     (match_operand 3 "pc_or_label_ref" "")))]
  750. ;  ""
  751. ;  "*
  752. ;{
  753. ;  switch (GET_CODE (operands[0]))
  754. ;    {
  755. ;    case EQ:
  756. ;    case NE:
  757. ;      /* I'm not sure if it's safe to use .n here.  */
  758. ;      return \"or %!,%1,%d1\;bcnd %R3%B0,%!,%P2%P3\";
  759. ;    case GE:
  760. ;    case LT:
  761. ;      return \"bcnd%. %R3%B0,%1,%P2%P3\";
  762. ;    case GT:
  763. ;      {
  764. ;    rtx op2 = operands[2];
  765. ;    operands[2] = operands[3];
  766. ;    operands[3] = op2;
  767. ;      }
  768. ;    case LE:
  769. ;      if (GET_CODE (operands[3]) == LABEL_REF)
  770. ;    {
  771. ;      int label_num;
  772. ;      operands[2] = gen_label_rtx ();
  773. ;      label_num = XINT (operands[2], 3);
  774. ;      output_asm_insn
  775. ;        (\"bcnd%. %#lt0,%1,%2\;or %!,%1,%d1\;bcnd %#ne0,%!,%3\", operands);
  776. ;      output_label (label_num);
  777. ;      return \"\";
  778. ;    }
  779. ;      else
  780. ;    return \"bcnd%. %#lt0,%1,%2\;or %!,%1,%d1\;bcnd %#eq0,%!,%2\";
  781. ;    }
  782. ;}")
  783.  
  784. ;; Recognize bcnd instructions for single precision float values
  785. ;; Exclude relational operations as they must signal NaNs.
  786.  
  787. ;; @@ These bcnd insns for float and double values don't seem to be recognized.
  788.  
  789. (define_insn ""
  790.   [(set (pc)
  791.     (if_then_else
  792.      (match_operator 0 "equality_op"
  793.              [(float_extend:DF
  794.                (match_operand:SF 1 "register_operand" "r"))
  795.               (const_int 0)])
  796.      (match_operand 2 "pc_or_label_ref" "")
  797.      (match_operand 3 "pc_or_label_ref" "")))]
  798.   ""
  799.   "bcnd%. %R3%D0,%1,%P2%P3"
  800.   [(set_attr "type" "branch")])
  801.  
  802. (define_insn ""
  803.   [(set (pc)
  804.     (if_then_else
  805.      (match_operator 0 "equality_op"
  806.              [(match_operand:SF 1 "register_operand" "r")
  807.               (const_int 0)])
  808.      (match_operand 2 "pc_or_label_ref" "")
  809.      (match_operand 3 "pc_or_label_ref" "")))]
  810.   ""
  811.   "bcnd%. %R3%D0,%1,%P2%P3"
  812.   [(set_attr "type" "branch")])
  813.  
  814. ;; Recognize bcnd instructions for double precision float values
  815. ;; Exclude relational operations as they must signal NaNs.
  816.  
  817. (define_insn ""
  818.   [(set (pc)
  819.     (if_then_else
  820.      (match_operator 0 "equality_op"
  821.              [(match_operand:DF 1 "register_operand" "r")
  822.               (const_int 0)])
  823.      (match_operand 2 "pc_or_label_ref" "")
  824.      (match_operand 3 "pc_or_label_ref" "")))]
  825.   ""
  826.   "*
  827. {
  828.   int label_num;
  829.  
  830.   if (GET_CODE (operands[0]) == NE)
  831.     {
  832.       rtx op2 = operands[2];
  833.       operands[2] = operands[3];
  834.       operands[3] = op2;
  835.     }
  836.   if (GET_CODE (operands[3]) == LABEL_REF)
  837.     return \"bcnd%. 0x5,%1,%3\;bcnd %#ne0,%d1,%3\";
  838.  
  839.   operands[3] = gen_label_rtx ();
  840.   label_num = XINT (operands[3], 3);
  841.   output_asm_insn (\"bcnd%. 0x5,%1,%3\;bcnd %#eq0,%d1,%2\", operands);
  842.   output_label (label_num);
  843.   return \"\";
  844. }"
  845.   [(set_attr "type" "branch")])
  846.  
  847. ;; Recognize bb0 and bb1 instructions.  These use two unusual template
  848. ;; patterns, %Lx and %Px.  %Lx outputs a 1 if operand `x' is a LABEL_REF
  849. ;; otherwise it outputs a 0.  It then may print ".n" if the delay slot
  850. ;; is used.  %Px does noting if `x' is PC and outputs the operand if `x'
  851. ;; is a LABEL_REF.
  852.  
  853. (define_insn ""
  854.   [(set (pc)
  855.     (if_then_else
  856.      (ne (sign_extract:SI (match_operand:SI 0 "register_operand" "r")
  857.                   (const_int 1)
  858.                   (match_operand:SI 1 "int5_operand" ""))
  859.          (const_int 0))
  860.      (match_operand 2 "pc_or_label_ref" "")
  861.      (match_operand 3 "pc_or_label_ref" "")))]
  862.   ""
  863.   "bb%L2 (31-%1),%0,%P2%P3"
  864.   [(set_attr "type" "branch")])
  865.  
  866. (define_insn ""
  867.   [(set (pc)
  868.     (if_then_else
  869.      (eq (sign_extract:SI (match_operand:SI 0 "register_operand" "r")
  870.                   (const_int 1)
  871.                   (match_operand:SI 1 "int5_operand" ""))
  872.          (const_int 0))
  873.      (match_operand 2 "pc_or_label_ref" "")
  874.      (match_operand 3 "pc_or_label_ref" "")))]
  875.   ""
  876.   "bb%L3 (31-%1),%0,%P2%P3"
  877.   [(set_attr "type" "branch")])
  878.  
  879. (define_insn ""
  880.   [(set (pc)
  881.     (if_then_else
  882.      (ne (zero_extract:SI (match_operand:SI 0 "register_operand" "r")
  883.                   (const_int 1)
  884.                   (match_operand:SI 1 "int5_operand" ""))
  885.          (const_int 0))
  886.      (match_operand 2 "pc_or_label_ref" "")
  887.      (match_operand 3 "pc_or_label_ref" "")))]
  888.   ""
  889.   "bb%L2 (31-%1),%0,%P2%P3"
  890.   [(set_attr "type" "branch")])
  891.  
  892. (define_insn ""
  893.   [(set (pc)
  894.     (if_then_else
  895.      (eq (zero_extract:SI (match_operand:SI 0 "register_operand" "r")
  896.                   (const_int 1)
  897.                   (match_operand:SI 1 "int5_operand" ""))
  898.          (const_int 0))
  899.      (match_operand 2 "pc_or_label_ref" "")
  900.      (match_operand 3 "pc_or_label_ref" "")))]
  901.   ""
  902.   "bb%L3 (31-%1),%0,%P2%P3"
  903.   [(set_attr "type" "branch")])
  904.  
  905. (define_insn ""
  906.   [(set (pc)
  907.     (if_then_else
  908.      (eq (and:SI (match_operand:SI 0 "reg_or_bbx_mask_operand" "%r")
  909.              (match_operand:SI 1 "reg_or_bbx_mask_operand" "n"))
  910.           (const_int 0))
  911.      (match_operand 2 "pc_or_label_ref" "")
  912.      (match_operand 3 "pc_or_label_ref" "")))]
  913.   "(GET_CODE (operands[0]) == CONST_INT)
  914.    != (GET_CODE (operands[1]) == CONST_INT)"
  915.   "bb%L3 %p1,%0,%P2%P3"
  916.   [(set_attr "type" "branch")])
  917.  
  918. (define_insn ""
  919.   [(set (pc)
  920.     (if_then_else
  921.      (ne (and:SI (match_operand:SI 0 "reg_or_bbx_mask_operand" "%r")
  922.              (match_operand:SI 1 "reg_or_bbx_mask_operand" "n"))
  923.          (const_int 0))
  924.      (match_operand 2 "pc_or_label_ref" "")
  925.      (match_operand 3 "pc_or_label_ref" "")))]
  926.   "(GET_CODE (operands[0]) == CONST_INT)
  927.    != (GET_CODE (operands[1]) == CONST_INT)"
  928.   "bb%L2 %p1,%0,%P2%P3"
  929.   [(set_attr "type" "branch")])
  930.  
  931. ;; The comparison operations store the comparison into a register and
  932. ;; record that register.  The following Bxx or Sxx insn uses that
  933. ;; register as an input.  To facilitate use of bcnd instead of cmp/bb1,
  934. ;; cmpsi records it's operands and produces no code when any operand
  935. ;; is constant.  In this case, the Bxx insns use gen_bcnd and the
  936. ;; Sxx insns use gen_test to ensure a cmp has been emitted.
  937. ;;
  938. ;; This could also be done for SFmode and DFmode having only beq and bne
  939. ;; use gen_bcnd.  The others must signal NaNs.  It seems though that zero
  940. ;; has already been copied into a register.
  941. ;;
  942. ;; cmpsi/beq and cmpsi/bne can always be done with bcnd if any operand
  943. ;; is a constant.  (This idea is due to Torbjorn Granlund.)  Others can
  944. ;; use bcnd only if an operand is zero.
  945. ;;
  946. ;; It is necessary to distinguish a register holding condition codes.
  947. ;; This is done by context.
  948.  
  949. (define_expand "test"
  950.   [(set (match_dup 2)
  951.     (compare:CC (match_operand 0 "" "")
  952.             (match_operand 1 "" "")))]
  953.   ""
  954.   "
  955. {
  956.   if (m88k_compare_reg)
  957.     abort ();
  958.  
  959.   if (GET_CODE (operands[0]) == CONST_INT
  960.       && ! SMALL_INT (operands[0]))
  961.     operands[0] = force_reg (SImode, operands[0]);
  962.  
  963.   if (GET_CODE (operands[1]) == CONST_INT
  964.       && ! SMALL_INT (operands[1]))
  965.     operands[1] = force_reg (SImode, operands[1]);
  966.  
  967.   operands[2] = m88k_compare_reg = gen_reg_rtx (CCmode);
  968. }")
  969.  
  970. ; @@ The docs say don't do this.  It's probably a nop since the insn looks
  971. ; identical to cmpsi against zero.  Is there an advantage to providing
  972. ; this, perhaps with a different form?
  973.  
  974. ;(define_expand "tstsi"
  975. ;  [(set (match_dup 1)
  976. ;    (compare:CC (match_operand:SI 0 "register_operand" "")
  977. ;            (const_int 0)))]
  978. ; ""
  979. ; "
  980. ;{
  981. ;  m88k_compare_reg = 0;
  982. ;  m88k_compare_op0 = operands[0];
  983. ;  m88k_compare_op1 = const0_rtx;
  984. ;  DONE;
  985. ;}")
  986.  
  987. (define_expand "cmpsi"
  988.   [(set (match_dup 2)
  989.     (compare:CC (match_operand:SI 0 "register_operand" "")
  990.             (match_operand:SI 1 "arith32_operand" "")))]
  991.   ""
  992.   "
  993. {
  994.   if (GET_CODE (operands[0]) == CONST_INT
  995.       || GET_CODE (operands[1]) == CONST_INT)
  996.     {
  997.       m88k_compare_reg = 0;
  998.       m88k_compare_op0 = operands[0];
  999.       m88k_compare_op1 = operands[1];
  1000.       DONE;
  1001.     }
  1002.   operands[2] = m88k_compare_reg = gen_reg_rtx (CCmode);
  1003. }")
  1004.  
  1005. (define_expand "cmpsf"
  1006.   [(set (match_dup 2)
  1007.     (compare:CC (match_operand:SF 0 "register_operand" "")
  1008.             (match_operand:SF 1 "register_operand" "")))]
  1009.   ""
  1010.   "operands[2] = m88k_compare_reg = gen_reg_rtx (CCmode);")
  1011.  
  1012. (define_expand "cmpdf"
  1013.   [(set (match_dup 2)
  1014.     (compare:CC (match_operand:DF 0 "general_operand" "")
  1015.             (match_operand:DF 1 "general_operand" "")))]
  1016.   ""
  1017.   "
  1018. {
  1019.   operands[0] = legitimize_operand (operands[0], DFmode);
  1020.   operands[1] = legitimize_operand (operands[1], DFmode);
  1021.   operands[2] = m88k_compare_reg = gen_reg_rtx (CCmode);
  1022. }")
  1023.  
  1024. ; @@ Get back to this later on.
  1025. ;
  1026. ;(define_insn "cmpdi"
  1027. ;  [(set (cc0)
  1028. ;    (compare:CC (match_operand:DI 0 "register_operand" "r")
  1029. ;            (match_operand:DI 1 "register_operand" "r")))]
  1030. ;  ""
  1031. ;  "*
  1032. ;{
  1033. ;  if ((cc_status.mdep & MDEP_LS_CHANGE) != 0)
  1034. ;    abort ();    /* output_move_double MDEP_LS_CHANGE bits were set. */
  1035. ;
  1036. ;  cc_status.mdep &= ~ MDEP_LS_MASK;
  1037. ;
  1038. ;  operands[2] = gen_label_rtx ();
  1039. ;  /* Remember, %! is the condition code register and %@ is the
  1040. ;     literal synthesis register.  */
  1041. ;
  1042. ;  output_asm_insn (\"cmp %!,%0,%1\;bb0 %#eq,%!,%l2\;cmp %!,%d0,%d1\",
  1043. ;           operands);
  1044. ;
  1045. ;  output_asm_insn (\"extu %@,%!,4<8>\;clr %!,%!,4<4>\", operands);
  1046. ;  output_asm_insn (\"mak %@,%@,4<4>\;or %!,%!,%@\", operands);
  1047. ;  output_label (XINT (operands[2], 3));
  1048. ;  return \"\";
  1049. ;}"
  1050.  
  1051. ;; The actual compare instructions.
  1052.  
  1053. (define_insn ""
  1054.   [(set (match_operand:CC 0 "register_operand" "=r")
  1055.     (compare:CC (match_operand:SI 1 "register_operand" "rO")
  1056.             (match_operand:SI 2 "arith_operand" "rI")))]
  1057.   ""
  1058.   "cmp %0,%r1,%2")
  1059.  
  1060. (define_insn ""
  1061.   [(set (match_operand:CC 0 "register_operand" "=r,r,r,r")
  1062.     (compare:CC (match_operand:SF 1 "register_operand" "r,r,x,x")
  1063.             (match_operand:SF 2 "real_or_0_operand" "r,G,x,G")))]
  1064.   ""
  1065.   "@
  1066.    fcmp.sss %0,%1,%2
  1067.    fcmp.sss %0,%1,%#r0
  1068.    fcmp.sss %0,%1,%2
  1069.    fcmp.sss %0,%1,%#x0"
  1070.   [(set_attr "type" "spcmp")])
  1071.  
  1072. (define_insn ""
  1073.   [(set (match_operand:CC 0 "register_operand" "=r,r")
  1074.     (compare:CC (match_operand:DF 1 "register_operand" "r,x")
  1075.             (float_extend:DF
  1076.              (match_operand:SF 2 "register_operand" "r,x"))))]
  1077.   ""
  1078.   "fcmp.sds %0,%1,%2"
  1079.   [(set_attr "type" "dpcmp")])
  1080.  
  1081. (define_insn ""
  1082.   [(set (match_operand:CC 0 "register_operand" "=r,r")
  1083.     (compare:CC (float_extend:DF
  1084.              (match_operand:SF 1 "register_operand" "r,x"))
  1085.             (match_operand:DF 2 "register_operand" "r,x")))]
  1086.   ""
  1087.   "fcmp.ssd %0,%1,%2"
  1088.   [(set_attr "type" "dpcmp")])
  1089.  
  1090. (define_insn ""
  1091.   [(set (match_operand:CC 0 "register_operand" "=r,r,r,r")
  1092.     (compare:CC (match_operand:DF 1 "register_operand" "r,r,x,x")
  1093.             (match_operand:DF 2 "real_or_0_operand" "r,G,x,G")))]
  1094.   ""
  1095.   "@
  1096.    fcmp.sdd %0,%1,%2
  1097.    fcmp.sds %0,%1,%#r0
  1098.    fcmp.sdd %0,%1,%2
  1099.    fcmp.sds %0,%1,%#x0"
  1100.   [(set_attr "type" "dpcmp")])
  1101.  
  1102. ;; Store condition code insns.  The compare insns set a register
  1103. ;; rather than cc0 and record that register for use here.  See above
  1104. ;; for the special treatment of cmpsi with a constant operand.
  1105.  
  1106. ;; @@ For the m88110, use fcmpu for bxx sxx inequality comparisons.
  1107.  
  1108. (define_expand "seq"
  1109.   [(set (match_operand:SI 0 "register_operand" "")
  1110.     (match_dup 1))]
  1111.   ""
  1112.   "operands[1] = emit_test (EQ, SImode);")
  1113.  
  1114. (define_expand "sne"
  1115.   [(set (match_operand:SI 0 "register_operand" "")
  1116.     (match_dup 1))]
  1117.   ""
  1118.   "operands[1] = emit_test (NE, SImode);")
  1119.  
  1120. (define_expand "sgt"
  1121.   [(set (match_operand:SI 0 "register_operand" "")
  1122.     (match_dup 1))]
  1123.   ""
  1124.   "operands[1] = emit_test (GT, SImode);")
  1125.  
  1126. (define_expand "sgtu"
  1127.   [(set (match_operand:SI 0 "register_operand" "")
  1128.     (match_dup 1))]
  1129.   ""
  1130.   "operands[1] = emit_test (GTU, SImode);")
  1131.  
  1132. (define_expand "slt"
  1133.   [(set (match_operand:SI 0 "register_operand" "")
  1134.     (match_dup 1))]
  1135.   ""
  1136.   "operands[1] = emit_test (LT, SImode);")
  1137.  
  1138. (define_expand "sltu"
  1139.   [(set (match_operand:SI 0 "register_operand" "")
  1140.     (match_dup 1))]
  1141.   ""
  1142.   "operands[1] = emit_test (LTU, SImode);")
  1143.  
  1144. (define_expand "sge"
  1145.   [(set (match_operand:SI 0 "register_operand" "")
  1146.     (match_dup 1))]
  1147.   ""
  1148.   "operands[1] = emit_test (GE, SImode);")
  1149.  
  1150. (define_expand "sgeu"
  1151.   [(set (match_operand:SI 0 "register_operand" "")
  1152.     (match_dup 1))]
  1153.   ""
  1154.   "operands[1] = emit_test (GEU, SImode);")
  1155.  
  1156. (define_expand "sle"
  1157.   [(set (match_operand:SI 0 "register_operand" "")
  1158.     (match_dup 1))]
  1159.   ""
  1160.   "operands[1] = emit_test (LE, SImode);")
  1161.  
  1162. (define_expand "sleu"
  1163.   [(set (match_operand:SI 0 "register_operand" "")
  1164.     (match_dup 1))]
  1165.   ""
  1166.   "operands[1] = emit_test (LEU, SImode);")
  1167.  
  1168. ;; The actual set condition code instruction.
  1169.  
  1170. (define_insn ""
  1171.   [(set (match_operand:SI 0 "register_operand" "=r")
  1172.     (match_operator:SI 1 "relop"
  1173.                [(match_operand:CC 2 "register_operand" "r")
  1174.                 (const_int 0)]))]
  1175.   ""
  1176.   "ext %0,%2,1<%C1>"
  1177.   [(set_attr "type" "bit")])
  1178.  
  1179. (define_insn ""
  1180.   [(set (match_operand:SI 0 "register_operand" "=r")
  1181.     (neg:SI
  1182.      (match_operator:SI 1 "relop"
  1183.                 [(match_operand:CC 2 "register_operand" "r")
  1184.                  (const_int 0)])))]
  1185.   ""
  1186.   "extu %0,%2,1<%C1>"
  1187.   [(set_attr "type" "bit")])
  1188.  
  1189. ;; Conditional branch insns.  The compare insns set a register
  1190. ;; rather than cc0 and record that register for use here.  See above
  1191. ;; for the special case of cmpsi with a constant operand.
  1192.  
  1193. (define_expand "bcnd"
  1194.   [(set (pc)
  1195.     (if_then_else (match_operand 0 "" "")
  1196.               (label_ref (match_operand 1 "" ""))
  1197.               (pc)))]
  1198.   ""
  1199.   "if (m88k_compare_reg) abort ();")
  1200.  
  1201. (define_expand "bxx"
  1202.   [(set (pc)
  1203.     (if_then_else (match_operand 0 "" "")
  1204.               (label_ref (match_operand 1 "" ""))
  1205.               (pc)))]
  1206.   ""
  1207.   "if (m88k_compare_reg == 0) abort ();")
  1208.  
  1209. (define_expand "beq"
  1210.   [(set (pc)
  1211.     (if_then_else (eq (match_dup 1) (const_int 0))
  1212.               (label_ref (match_operand 0 "" ""))
  1213.               (pc)))]
  1214.   ""
  1215.   "if (m88k_compare_reg == 0)
  1216.      {
  1217.        emit_bcnd (EQ, operands[0]);
  1218.        DONE;
  1219.      }
  1220.    operands[1] = m88k_compare_reg;")
  1221.  
  1222. (define_expand "bne"
  1223.   [(set (pc)
  1224.     (if_then_else (ne (match_dup 1) (const_int 0))
  1225.               (label_ref (match_operand 0 "" ""))
  1226.               (pc)))]
  1227.   ""
  1228.   "if (m88k_compare_reg == 0)
  1229.      {
  1230.        emit_bcnd (NE, operands[0]);
  1231.        DONE;
  1232.      }
  1233.    operands[1] = m88k_compare_reg;")
  1234.  
  1235. (define_expand "bgt"
  1236.   [(set (pc)
  1237.     (if_then_else (gt (match_dup 1) (const_int 0))
  1238.               (label_ref (match_operand 0 "" ""))
  1239.               (pc)))]
  1240.   ""
  1241.   "if (m88k_compare_reg == 0)
  1242.      {
  1243.        emit_bcnd (GT, operands[0]);
  1244.        DONE;
  1245.      }
  1246.    operands[1] = m88k_compare_reg;")
  1247.  
  1248. (define_expand "bgtu"
  1249.   [(set (pc)
  1250.     (if_then_else (gtu (match_dup 1) (const_int 0))
  1251.               (label_ref (match_operand 0 "" ""))
  1252.               (pc)))]
  1253.   ""
  1254.   "if (m88k_compare_reg == 0)
  1255.      {
  1256.        emit_jump_insn (gen_bxx (emit_test (GTU, VOIDmode), operands[0]));
  1257.        DONE;
  1258.      }
  1259.    operands[1] = m88k_compare_reg;")
  1260.  
  1261. (define_expand "blt"
  1262.   [(set (pc)
  1263.     (if_then_else (lt (match_dup 1) (const_int 0))
  1264.               (label_ref (match_operand 0 "" ""))
  1265.               (pc)))]
  1266.   ""
  1267.   "if (m88k_compare_reg == 0)
  1268.      {
  1269.        emit_bcnd (LT, operands[0]);
  1270.        DONE;
  1271.      }
  1272.    operands[1] = m88k_compare_reg;")
  1273.  
  1274. (define_expand "bltu"
  1275.   [(set (pc)
  1276.     (if_then_else (ltu (match_dup 1) (const_int 0))
  1277.               (label_ref (match_operand 0 "" ""))
  1278.               (pc)))]
  1279.   ""
  1280.   "if (m88k_compare_reg == 0)
  1281.      {
  1282.        emit_jump_insn (gen_bxx (emit_test (LTU, VOIDmode), operands[0]));
  1283.        DONE;
  1284.      }
  1285.    operands[1] = m88k_compare_reg;")
  1286.  
  1287. (define_expand "bge"
  1288.   [(set (pc)
  1289.     (if_then_else (ge (match_dup 1) (const_int 0))
  1290.               (label_ref (match_operand 0 "" ""))
  1291.               (pc)))]
  1292.   ""
  1293.   "if (m88k_compare_reg == 0)
  1294.      {
  1295.        emit_bcnd (GE, operands[0]);
  1296.        DONE;
  1297.      }
  1298.    operands[1] = m88k_compare_reg;")
  1299.  
  1300. (define_expand "bgeu"
  1301.   [(set (pc)
  1302.     (if_then_else (geu (match_dup 1) (const_int 0))
  1303.               (label_ref (match_operand 0 "" ""))
  1304.               (pc)))]
  1305.   ""
  1306.   "if (m88k_compare_reg == 0)
  1307.      {
  1308.        emit_jump_insn (gen_bxx (emit_test (GEU, VOIDmode), operands[0]));
  1309.        DONE;
  1310.      }
  1311.    operands[1] = m88k_compare_reg;")
  1312.  
  1313. (define_expand "ble"
  1314.   [(set (pc)
  1315.     (if_then_else (le (match_dup 1) (const_int 0))
  1316.               (label_ref (match_operand 0 "" ""))
  1317.               (pc)))]
  1318.   ""
  1319.   "if (m88k_compare_reg == 0)
  1320.      {
  1321.        emit_bcnd (LE, operands[0]);
  1322.        DONE;
  1323.      }
  1324.    operands[1] = m88k_compare_reg;")
  1325.  
  1326. (define_expand "bleu"
  1327.   [(set (pc)
  1328.     (if_then_else (leu (match_dup 1) (const_int 0))
  1329.               (label_ref (match_operand 0 "" ""))
  1330.               (pc)))]
  1331.   ""
  1332.   "if (m88k_compare_reg == 0)
  1333.      {
  1334.        emit_jump_insn (gen_bxx (emit_test (LEU, VOIDmode), operands[0]));
  1335.        DONE;
  1336.      }
  1337.    operands[1] = m88k_compare_reg;")
  1338.  
  1339. ;; The actual conditional branch instruction (both directions).  This
  1340. ;; uses two unusual template patterns, %Rx and %Px.  %Rx is a prefix code
  1341. ;; for the immediately following condition and reverses the condition iff
  1342. ;; operand `x' is a LABEL_REF.  %Px does nothing if `x' is PC and outputs
  1343. ;; the operand if `x' is a LABEL_REF.
  1344.  
  1345. (define_insn ""
  1346.   [(set (pc) (if_then_else
  1347.           (match_operator 0 "relop"
  1348.                   [(match_operand:CC 1 "register_operand" "r")
  1349.                    (const_int 0)])
  1350.           (match_operand 2 "pc_or_label_ref" "")
  1351.           (match_operand 3 "pc_or_label_ref" "")))]
  1352.   ""
  1353.   "*
  1354. {
  1355.   if (mostly_false_jump (insn, operands[0]))
  1356.     return \"bb0%. %R2%C0,%1,%P2%P3\";
  1357.   else
  1358.     return \"bb1%. %R3%C0,%1,%P2%P3\";
  1359. }"
  1360.   [(set_attr "type" "branch")])
  1361.  
  1362. ;; Branch conditional on scc values.  These arise from manipulations on
  1363. ;; compare words above.
  1364.  
  1365. (define_insn ""
  1366.   [(set (pc)
  1367.     (if_then_else
  1368.      (ne (match_operator 0 "relop"
  1369.                  [(match_operand:CC 1 "register_operand" "r")
  1370.                   (const_int 0)])
  1371.          (const_int 0))
  1372.      (match_operand 2 "pc_or_label_ref" "")
  1373.      (match_operand 3 "pc_or_label_ref" "")))]
  1374.   ""
  1375.   "bb1%. %R3%C0,%1,%P2%P3"
  1376.   [(set_attr "type" "branch")])
  1377.  
  1378. (define_insn ""
  1379.   [(set (pc)
  1380.     (if_then_else
  1381.      (eq (match_operator 0 "relop"
  1382.                  [(match_operand:CC 1 "register_operand" "r")
  1383.                   (const_int 0)])
  1384.          (const_int 0))
  1385.      (match_operand 2 "pc_or_label_ref" "")
  1386.      (match_operand 3 "pc_or_label_ref" "")))]
  1387.   ""
  1388.   "bb0%. %R3%C0,%1,%P2%P3"
  1389.   [(set_attr "type" "branch")])
  1390.  
  1391. (define_insn "locate1"
  1392.   [(set (match_operand:SI 0 "register_operand" "=r")
  1393.     (high:SI (unspec:SI [(label_ref (match_operand 1 "" ""))] 0)))]
  1394.   ""
  1395.   "or.u %0,%#r0,%#hi16(%1#abdiff)")
  1396.  
  1397. (define_insn "locate2"
  1398.   [(parallel [(set (reg:SI 1) (pc))
  1399.           (set (match_operand:SI 0 "register_operand" "=r")
  1400.            (lo_sum:SI (match_dup 0)
  1401.                   (unspec:SI
  1402.                    [(label_ref (match_operand 1 "" ""))] 0)))])]
  1403.   ""
  1404.   "bsr.n %1\;or %0,%0,%#lo16(%1#abdiff)\\n%1:"
  1405.   [(set_attr "length" "2")])
  1406.  
  1407. ;; SImode move instructions
  1408.  
  1409. (define_expand "movsi"
  1410.   [(set (match_operand:SI 0 "general_operand" "")
  1411.     (match_operand:SI 1 "general_operand" ""))]
  1412.   ""
  1413.   "
  1414. {
  1415.   if (emit_move_sequence (operands, SImode, 0))
  1416.     DONE;
  1417. }")
  1418.  
  1419. (define_expand "reload_insi"
  1420.   [(set (match_operand:SI 0 "register_operand" "=r")
  1421.     (match_operand:SI 1 "general_operand" ""))
  1422.    (clobber (match_operand:SI 2 "register_operand" "=&r"))]
  1423.   ""
  1424.   "
  1425. {
  1426.   if (emit_move_sequence (operands, SImode, operands[2]))
  1427.     DONE;
  1428.  
  1429.   /* We don't want the clobber emitted, so handle this ourselves.  */
  1430.   emit_insn (gen_rtx (SET, VOIDmode, operands[0], operands[1]));
  1431.   DONE;
  1432. }")
  1433.  
  1434. (define_insn ""
  1435.   [(set (match_operand:SI 0 "nonimmediate_operand" "=r,r,m,r,r,r,x,x,x,m")
  1436.     (match_operand:SI 1 "move_operand" "rI,m,rO,J,M,x,r,x,m,x"))]
  1437.   "(register_operand (operands[0], SImode)
  1438.     || register_operand (operands[1], SImode)
  1439.     || operands[1] == const0_rtx)"
  1440.   "@
  1441.    or %0,%#r0,%1
  1442.    %V1ld %0,%1
  1443.    %v0st %r1,%0
  1444.    subu %0,%#r0,%n1
  1445.    set %0,%#r0,%s1
  1446.    mov.s %0,%1
  1447.    mov.s %0,%1
  1448.    mov %0,%1
  1449.    %V1ld %0,%1
  1450.    %v0st %1,%0"
  1451.   [(set_attr "type" "arith,load,store,arith,bit,mov,mov,mov,load,store")])
  1452.  
  1453. (define_insn ""
  1454.   [(set (match_operand:SI 0 "register_operand" "=r,r,r,r,r")
  1455.     (match_operand:SI 1 "arith32_operand" "rI,J,L,M,n"))]
  1456.   ""
  1457.   "@
  1458.    or %0,%#r0,%1
  1459.    subu %0,%#r0,%n1
  1460.    or.u %0,%#r0,%X1
  1461.    set %0,%#r0,%s1
  1462.    or.u %0,%#r0,%X1\;or %0,%0,%x1"
  1463.   [(set_attr "type" "arith,arith,arith,bit,marith")])
  1464.  
  1465. ;; @@ Why the constraint "in"?  Doesn't `i' include `n'?
  1466. (define_insn ""
  1467.   [(set (match_operand:SI 0 "register_operand" "=r")
  1468.     (lo_sum:SI (match_operand:SI 1 "register_operand" "r")
  1469.            (match_operand:SI 2 "immediate_operand" "in")))]
  1470.   ""
  1471.   "or %0,%1,%#lo16(%g2)")
  1472.  
  1473. (define_insn ""
  1474.   [(set (match_operand:SI 0 "register_operand" "=r")
  1475.     (high:SI (match_operand 1 "" "")))]
  1476.   ""
  1477.   "or.u %0,%#r0,%#hi16(%g1)")
  1478.  
  1479. ;; HImode move instructions
  1480.  
  1481. (define_expand "movhi"
  1482.   [(set (match_operand:HI 0 "general_operand" "")
  1483.     (match_operand:HI 1 "general_operand" ""))]
  1484.   ""
  1485.   "
  1486. {
  1487.   if (emit_move_sequence (operands, HImode, 0))
  1488.     DONE;
  1489. }")
  1490.  
  1491. (define_insn ""
  1492.   [(set (match_operand:HI 0 "nonimmediate_operand" "=r,r,m,r")
  1493.     (match_operand:HI 1 "move_operand" "rP,m,rO,N"))]
  1494.   "(register_operand (operands[0], HImode)
  1495.     || register_operand (operands[1], HImode)
  1496.     || operands[1] == const0_rtx)"
  1497.   "@
  1498.    or %0,%#r0,%h1
  1499.    %V1ld.hu %0,%1
  1500.    %v0st.h %r1,%0
  1501.    subu %0,%#r0,%H1"
  1502.   [(set_attr "type" "arith,load,store,arith")])
  1503.  
  1504. (define_insn ""
  1505.   [(set (match_operand:HI 0 "register_operand" "=r")
  1506.     (subreg:HI (lo_sum:SI (match_operand:SI 1 "register_operand" "r")
  1507.                   (match_operand:SI 2 "immediate_operand" "in")) 0))]
  1508.   "!flag_pic"
  1509.   "or %0,%1,%#lo16(%2)")
  1510.  
  1511. ;; QImode move instructions
  1512.  
  1513. (define_expand "movqi"
  1514.   [(set (match_operand:QI 0 "general_operand" "")
  1515.     (match_operand:QI 1 "general_operand" ""))]
  1516.   ""
  1517.   "
  1518. {
  1519.   if (emit_move_sequence (operands, QImode, 0))
  1520.     DONE;
  1521. }")
  1522.  
  1523. (define_insn ""
  1524.   [(set (match_operand:QI 0 "nonimmediate_operand" "=r,r,m,r")
  1525.     (match_operand:QI 1 "move_operand" "rP,m,rO,N"))]
  1526.   "(register_operand (operands[0], QImode)
  1527.     || register_operand (operands[1], QImode)
  1528.     || operands[1] == const0_rtx)"
  1529.   "@
  1530.    or %0,%#r0,%q1
  1531.    %V1ld.bu %0,%1
  1532.    %v0st.b %r1,%0
  1533.    subu %r0,%#r0,%Q1"
  1534.   [(set_attr "type" "arith,load,store,arith")])
  1535.  
  1536. (define_insn ""
  1537.   [(set (match_operand:QI 0 "register_operand" "=r")
  1538.     (subreg:QI (lo_sum:SI (match_operand:SI 1 "register_operand" "r")
  1539.                   (match_operand:SI 2 "immediate_operand" "in")) 0))]
  1540.   "!flag_pic"
  1541.   "or %0,%1,%#lo16(%2)")
  1542.  
  1543. ;; DImode move instructions
  1544.  
  1545. (define_expand "movdi"
  1546.   [(set (match_operand:DI 0 "general_operand" "")
  1547.     (match_operand:DI 1 "general_operand" ""))]
  1548.   ""
  1549.   "
  1550. {
  1551.   if (emit_move_sequence (operands, DImode, 0))
  1552.     DONE;
  1553. }")
  1554.  
  1555. (define_insn ""
  1556.   [(set (match_operand:DI 0 "register_operand" "=r,x")
  1557.     (const_int 0))]
  1558.   ""
  1559.   "@
  1560.    or %0,%#r0,0\;or %d0,%#r0,0
  1561.    mov %0,%#x0"
  1562.   [(set_attr "type" "marith,mov")])
  1563.  
  1564. (define_insn ""
  1565.   [(set (match_operand:DI 0 "nonimmediate_operand" "=r,r,m,r,x,x,x,m")
  1566.     (match_operand:DI 1 "nonimmediate_operand" "r,m,r,x,r,x,m,x"))]
  1567.   ""
  1568.   "@
  1569.    or %0,%#r0,%1\;or %d0,%#r0,%d1
  1570.    %V1ld.d %0,%1
  1571.    %v0st.d %1,%0
  1572.    mov.d %0,%1
  1573.    mov.d %0,%1
  1574.    mov %0,%1
  1575.    %V1ld.d %0,%1
  1576.    %v0st.d %1,%0"
  1577.   [(set_attr "type" "marith,loadd,store,mov,mov,mov,loadd,store")])
  1578.  
  1579. (define_insn ""
  1580.   [(set (match_operand:DI 0 "register_operand" "=r")
  1581.     (subreg:DI (lo_sum:SI (match_operand:SI 1 "register_operand" "r")
  1582.                   (match_operand:SI 2 "immediate_operand" "in")) 0))]
  1583.   "!flag_pic"
  1584.   "or %0,%1,%#lo16(%2)")
  1585.  
  1586. (define_insn ""
  1587.   [(set (match_operand:DI 0 "register_operand" "=r")
  1588.     (match_operand:DI 1 "immediate_operand" "n"))]
  1589.    ""
  1590.    "* return output_load_const_dimode (operands);"
  1591.   [(set_attr "type" "marith")
  1592.    (set_attr "length" "4")]) ; length is 2, 3 or 4.
  1593.  
  1594. ;; DFmode move instructions
  1595.  
  1596. (define_expand "movdf"
  1597.   [(set (match_operand:DF 0 "general_operand" "")
  1598.     (match_operand:DF 1 "general_operand" ""))]
  1599.   ""
  1600.   "
  1601. {
  1602.   if (emit_move_sequence (operands, DFmode, 0))
  1603.     DONE;
  1604. }")
  1605.  
  1606. ;; @@ This pattern is incomplete and doesn't appear necessary.
  1607. ;;
  1608. ;; This pattern forces (set (reg:DF ...) (const_double ...))
  1609. ;; to be reloaded by putting the constant into memory.
  1610. ;; It must come before the more general movdf pattern.
  1611.  
  1612. ;(define_insn ""
  1613. ;  [(set (match_operand:DF 0 "general_operand" "=r,o")
  1614. ;    (match_operand:DF 1 "" "G,G"))]
  1615. ;  "GET_CODE (operands[1]) == CONST_DOUBLE"
  1616. ;  "*
  1617. ;{
  1618. ;  switch (which_alternative)
  1619. ;    {
  1620. ;    case 0:
  1621. ;      return \"or %0,%#r0,0\;or %d0,%#r0,0\";
  1622. ;    case 1:
  1623. ;      operands[1] = adj_offsettable_operand (operands[0], 4);
  1624. ;      return \"%v0st %#r0,%0\;st %#r0,%1\";
  1625. ;    }
  1626. ;}")
  1627.  
  1628. (define_insn ""
  1629.   [(set (match_operand:DF 0 "register_operand" "=r,x")
  1630.     (const_int 0))]
  1631.   ""
  1632.   "@
  1633.    or %0,%#r0,0\;or %d0,%#r0,0
  1634.    mov %0,%#x0"
  1635.   [(set_attr "type" "marith,mov")])
  1636.  
  1637. (define_insn ""
  1638.   [(set (match_operand:DF 0 "nonimmediate_operand" "=r,r,m,x,r,x,x,m")
  1639.     (match_operand:DF 1 "nonimmediate_operand" "r,m,r,r,x,x,m,x"))]
  1640.   ""
  1641.   "@
  1642.    or %0,%#r0,%1\;or %d0,%#r0,%d1
  1643.    %V1ld.d %0,%1
  1644.    %v0st.d %1,%0
  1645.    mov.d %0,%1
  1646.    mov.d %0,%1
  1647.    mov %0,%1
  1648.    %V1ld.d %0,%1
  1649.    %v0st.d %1,%0"
  1650.   [(set_attr "type" "marith,loadd,store,mov,mov,mov,loadd,store")])
  1651.  
  1652. (define_insn ""
  1653.   [(set (match_operand:DF 0 "register_operand" "=r")
  1654.     (subreg:DF (lo_sum:SI (match_operand:SI 1 "register_operand" "r")
  1655.                   (match_operand:SI 2 "immediate_operand" "in")) 0))]
  1656.   "!flag_pic"
  1657.   "or %0,%1,%#lo16(%2)")
  1658.  
  1659. (define_insn ""
  1660.   [(set (match_operand:DF 0 "register_operand" "=r")
  1661.     (match_operand:DF 1 "immediate_operand" "F"))]
  1662.    ""
  1663.    "* return output_load_const_double (operands);"
  1664.   [(set_attr "type" "marith")
  1665.    (set_attr "length" "4")]) ; length is 2, 3, or 4.
  1666.  
  1667. ;; SFmode move instructions
  1668.  
  1669. (define_expand "movsf"
  1670.   [(set (match_operand:SF 0 "general_operand" "")
  1671.     (match_operand:SF 1 "general_operand" ""))]
  1672.   ""
  1673.   "
  1674. {
  1675.   if (emit_move_sequence (operands, SFmode, 0))
  1676.     DONE;
  1677. }")
  1678.  
  1679. ;; @@ What happens to fconst0_rtx?
  1680. (define_insn ""
  1681.   [(set (match_operand:SF 0 "register_operand" "=r,x")
  1682.     (const_int 0))]
  1683.   ""
  1684.   "@
  1685.    or %0,%#r0,0
  1686.    mov %0,%#x0"
  1687.   [(set_attr "type" "arith,mov")])
  1688.  
  1689. (define_insn ""
  1690.   [(set (match_operand:SF 0 "nonimmediate_operand" "=r,r,m,x,r,x,x,m")
  1691.     (match_operand:SF 1 "nonimmediate_operand" "r,m,r,r,x,x,m,x"))]
  1692.   ""
  1693.   "@
  1694.    or %0,%#r0,%1
  1695.    %V1ld %0,%1
  1696.    %v0st %r1,%0
  1697.    mov.s %0,%1
  1698.    mov.s %0,%1
  1699.    mov %0,%1
  1700.    %V1ld %0,%1
  1701.    %v0st %r1,%0"
  1702.   [(set_attr "type" "arith,load,store,mov,mov,mov,load,store")])
  1703.  
  1704. (define_insn ""
  1705.   [(set (match_operand:SF 0 "register_operand" "=r")
  1706.     (subreg:SF (lo_sum:SI (match_operand:SI 1 "register_operand" "r")
  1707.                   (match_operand:SI 2 "immediate_operand" "in")) 0))]
  1708.   "!flag_pic"
  1709.   "or %0,%1,%#lo16(%2)")
  1710.  
  1711. (define_insn ""
  1712.   [(set (match_operand:SF 0 "register_operand" "=r")
  1713.     (match_operand:SF 1 "immediate_operand" "F"))]
  1714.   "operands[1] != const0_rtx"
  1715.   "* return output_load_const_float (operands);"
  1716.   [(set_attr "type" "marith")]) ; length is 1 or 2.
  1717.  
  1718. ;; String/block move insn.  See m88k.c for details.
  1719.  
  1720. (define_expand "movstrsi"
  1721.   [(parallel [(set (mem:BLK (match_operand:BLK 0 "" ""))
  1722.            (mem:BLK (match_operand:BLK 1 "" "")))
  1723.           (use (match_operand:SI 2 "arith32_operand" ""))
  1724.           (use (match_operand:SI 3 "immediate_operand" ""))])]
  1725.   ""
  1726.   "
  1727. {
  1728.   rtx dest_mem = operands[0];
  1729.   rtx src_mem = operands[1];
  1730.   operands[0] = copy_to_mode_reg (SImode, XEXP (operands[0], 0));
  1731.   operands[1] = copy_to_mode_reg (SImode, XEXP (operands[1], 0));
  1732.   expand_block_move (dest_mem, src_mem, operands);
  1733.   DONE;
  1734. }")
  1735.  
  1736. ;; Call a non-looping block move library function (e.g. __movstrSI96x64).
  1737. ;; operand 0 is the function name
  1738. ;; operand 1 is the destination pointer
  1739. ;; operand 2 is the source pointer
  1740. ;; operand 3 is the offset for the source and destination pointers
  1741. ;; operand 4 is the first value to be loaded
  1742. ;; operand 5 is the register to hold the value (r4 or r5)
  1743.  
  1744. (define_expand "call_block_move"
  1745.   [(set (reg:SI 3) (minus:SI (match_operand:SI 2 "register_operand" "")
  1746.                  (match_operand:SI 3 "immediate_operand" "")))
  1747.    (set (match_operand 5 "register_operand" "")
  1748.     (match_operand 4 "memory_operand" ""))
  1749.    (set (reg:SI 2) (minus:SI (match_operand:SI 1 "register_operand" "")
  1750.                  (match_dup 3)))
  1751.    (use (reg:SI 2))
  1752.    (use (reg:SI 3))
  1753.    (use (match_dup 5))
  1754.    (parallel [(set (reg:DI 2)
  1755.            (call (mem:SI (match_operand 0 "" ""))
  1756.              (const_int 0)))
  1757.           (clobber (reg:SI 1))])]
  1758.   ""
  1759.   "")
  1760.  
  1761. ;; Call an SImode looping block move library function (e.g. __movstrSI64n68).
  1762. ;; operands 0-5 as in the non-looping interface
  1763. ;; operand 6 is the loop count
  1764.  
  1765. (define_expand "call_movstrsi_loop"
  1766.   [(set (reg:SI 3) (minus:SI (match_operand:SI 2 "register_operand" "")
  1767.                  (match_operand:SI 3 "immediate_operand" "")))
  1768.    (set (match_operand:SI 5 "register_operand" "")
  1769.     (match_operand:SI 4 "memory_operand" ""))
  1770.    (set (reg:SI 2) (minus:SI (match_operand:SI 1 "register_operand" "")
  1771.                  (match_dup 3)))
  1772.    (set (reg:SI 6) (match_operand:SI 6 "immediate_operand" ""))
  1773.    (use (reg:SI 2))
  1774.    (use (reg:SI 3))
  1775.    (use (match_dup 5))
  1776.    (use (reg:SI 6))
  1777.    (parallel [(set (reg:DI 2)
  1778.            (call (mem:SI (match_operand 0 "" ""))
  1779.              (const_int 0)))
  1780.           (clobber (reg:SI 1))])]
  1781.   ""
  1782.   "")
  1783.  
  1784. ;;- zero extension instructions
  1785.  
  1786. (define_expand "zero_extendhisi2"
  1787.   [(set (match_operand:SI 0 "register_operand" "")
  1788.     (zero_extend:SI (match_operand:HI 1 "nonimmediate_operand" "")))]
  1789.   ""
  1790.   "
  1791. {
  1792.   if (GET_CODE (operands[1]) == MEM
  1793.       && symbolic_address_p (XEXP (operands[1], 0)))
  1794.     operands[1]
  1795.       = legitimize_address (flag_pic, operands[1], 0, 0);
  1796. }")
  1797.  
  1798. (define_insn ""
  1799.   [(set (match_operand:SI 0 "register_operand" "=r,r,r")
  1800.     (zero_extend:SI (match_operand:HI 1 "move_operand" "!r,n,m")))]
  1801.   "GET_CODE (operands[1]) != CONST_INT"
  1802.   "@
  1803.    mask %0,%1,0xffff
  1804.    or %0,%#r0,%h1
  1805.    %V1ld.hu %0,%1"
  1806.   [(set_attr "type" "arith,arith,load")])
  1807.  
  1808. (define_expand "zero_extendqihi2"
  1809.   [(set (match_operand:HI 0 "register_operand" "")
  1810.     (zero_extend:HI (match_operand:QI 1 "nonimmediate_operand" "")))]
  1811.   ""
  1812.   "
  1813. {
  1814.   if (GET_CODE (operands[1]) == MEM
  1815.       && symbolic_address_p (XEXP (operands[1], 0)))
  1816.     operands[1]
  1817.       = legitimize_address (flag_pic, operands[1], 0, 0);
  1818. }")
  1819.  
  1820. (define_insn ""
  1821.   [(set (match_operand:HI 0 "register_operand" "=r,r,r")
  1822.     (zero_extend:HI (match_operand:QI 1 "move_operand" "r,n,m")))]
  1823.   "GET_CODE (operands[1]) != CONST_INT"
  1824.   "@
  1825.    mask %0,%1,0xff
  1826.    or %0,%#r0,%q1
  1827.    %V1ld.bu %0,%1"
  1828.   [(set_attr "type" "arith,arith,load")])
  1829.  
  1830. (define_expand "zero_extendqisi2"
  1831.   [(set (match_operand:SI 0 "register_operand" "")
  1832.     (zero_extend:SI (match_operand:QI 1 "nonimmediate_operand" "")))]
  1833.   ""
  1834.   "
  1835. {
  1836.   if (GET_CODE (operands[1]) == MEM
  1837.       && symbolic_address_p (XEXP (operands[1], 0)))
  1838.     {
  1839.       operands[1]
  1840.     = legitimize_address (flag_pic, operands[1], 0, 0);
  1841.       emit_insn (gen_rtx (SET, VOIDmode, operands[0],
  1842.               gen_rtx (ZERO_EXTEND, SImode, operands[1])));
  1843.       DONE;
  1844.     }
  1845. }")
  1846.  
  1847. (define_insn ""
  1848.   [(set (match_operand:SI 0 "register_operand" "=r,r,r")
  1849.     (zero_extend:SI (match_operand:QI 1 "move_operand" "r,n,m")))]
  1850.   "GET_CODE (operands[1]) != CONST_INT"
  1851.   "@
  1852.    mask %0,%1,0xff
  1853.    or %0,%#r0,%q1
  1854.    %V1ld.bu %0,%1"
  1855.   [(set_attr "type" "arith,arith,load")])
  1856.  
  1857. ;;- sign extension instructions
  1858.  
  1859. (define_expand "extendsidi2"
  1860.   [(set (subreg:SI (match_operand:DI 0 "register_operand" "=r") 1)
  1861.         (match_operand:SI 1 "general_operand" "g"))
  1862.    (set (subreg:SI (match_dup 0) 0)
  1863.         (ashiftrt:SI (subreg:SI (match_dup 0) 1)
  1864.                      (const_int 31)))]
  1865.   ""
  1866.   "")
  1867.  
  1868. (define_expand "extendhisi2"
  1869.   [(set (match_operand:SI 0 "register_operand" "")
  1870.     (sign_extend:SI (match_operand:HI 1 "nonimmediate_operand" "")))]
  1871.   ""
  1872.   "
  1873. {
  1874.   if (GET_CODE (operands[1]) == MEM
  1875.       && symbolic_address_p (XEXP (operands[1], 0)))
  1876.     operands[1]
  1877.       = legitimize_address (flag_pic, operands[1], 0, 0);
  1878. }")
  1879.  
  1880. (define_insn ""
  1881.   [(set (match_operand:SI 0 "register_operand" "=r,r,r,r")
  1882.     (sign_extend:SI (match_operand:HI 1 "move_operand" "!r,P,N,m")))]
  1883.   "GET_CODE (operands[1]) != CONST_INT"
  1884.   "@
  1885.    ext %0,%1,16<0>
  1886.    or %0,%#r0,%h1
  1887.    subu %0,%#r0,%H1
  1888.    %V1ld.h %0,%1"
  1889.   [(set_attr "type" "bit,arith,arith,load")])
  1890.  
  1891. (define_expand "extendqihi2"
  1892.   [(set (match_operand:HI 0 "register_operand" "")
  1893.     (sign_extend:HI (match_operand:QI 1 "nonimmediate_operand" "")))]
  1894.   ""
  1895.   "
  1896. {
  1897.   if (GET_CODE (operands[1]) == MEM
  1898.       && symbolic_address_p (XEXP (operands[1], 0)))
  1899.     operands[1]
  1900.       = legitimize_address (flag_pic, operands[1], 0, 0);
  1901. }")
  1902.  
  1903. (define_insn ""
  1904.   [(set (match_operand:HI 0 "register_operand" "=r,r,r,r")
  1905.     (sign_extend:HI (match_operand:QI 1 "move_operand" "!r,P,N,m")))]
  1906.   "GET_CODE (operands[1]) != CONST_INT"
  1907.   "@
  1908.    ext %0,%1,8<0>
  1909.    or %0,%#r0,%q1
  1910.    subu %0,%#r0,%Q1
  1911.    %V1ld.b %0,%1"
  1912.   [(set_attr "type" "bit,arith,arith,load")])
  1913.  
  1914. (define_expand "extendqisi2"
  1915.   [(set (match_operand:SI 0 "register_operand" "")
  1916.     (sign_extend:SI (match_operand:QI 1 "nonimmediate_operand" "")))]
  1917.   ""
  1918.   "
  1919. {
  1920.   if (GET_CODE (operands[1]) == MEM
  1921.       && symbolic_address_p (XEXP (operands[1], 0)))
  1922.     operands[1]
  1923.       = legitimize_address (flag_pic, operands[1], 0, 0);
  1924. }")
  1925.  
  1926. (define_insn ""
  1927.   [(set (match_operand:SI 0 "register_operand" "=r,r,r,r")
  1928.     (sign_extend:SI (match_operand:QI 1 "move_operand" "!r,P,N,m")))]
  1929.   "GET_CODE (operands[1]) != CONST_INT"
  1930.   "@
  1931.    ext %0,%1,8<0>
  1932.    or %0,%#r0,%q1
  1933.    subu %0,%#r0,%Q1
  1934.    %V1ld.b %0,%1"
  1935.   [(set_attr "type" "bit,arith,arith,load")])
  1936.  
  1937. ;; Conversions between float and double.
  1938.  
  1939. ;; The fadd instruction does not conform to IEEE 754 when used to
  1940. ;; convert between float and double.  In particular, the sign of -0 is
  1941. ;; not preserved.  Interestingly, fsub does conform.
  1942.  
  1943. (define_expand "extendsfdf2"
  1944.   [(set (match_operand:DF 0 "register_operand" "=r")
  1945.     (float_extend:DF (match_operand:SF 1 "register_operand" "r")))]
  1946.   ""
  1947.   "")
  1948.  
  1949. (define_insn ""
  1950.   [(set (match_operand:DF 0 "register_operand" "=r")
  1951.     (float_extend:DF (match_operand:SF 1 "register_operand" "r")))]
  1952.   "! TARGET_88110"
  1953.   "fsub.dss %0,%1,%#r0"
  1954.   [(set_attr "type" "spadd")])
  1955.  
  1956. (define_insn ""
  1957.   [(set (match_operand:DF 0 "register_operand" "=r,x")
  1958.     (float_extend:DF (match_operand:SF 1 "register_operand" "r,x")))]
  1959.   "TARGET_88110"
  1960.   "fcvt.ds %0,%1"
  1961.   [(set_attr "type" "spadd")])
  1962.  
  1963. (define_expand "truncdfsf2"
  1964.   [(set (match_operand:SF 0 "register_operand" "=r")
  1965.     (float_truncate:SF (match_operand:DF 1 "register_operand" "r")))]
  1966.   ""
  1967.   "")
  1968.  
  1969. (define_insn ""
  1970.   [(set (match_operand:SF 0 "register_operand" "=r")
  1971.     (float_truncate:SF (match_operand:DF 1 "register_operand" "r")))]
  1972.   "! TARGET_88110"
  1973.   "fsub.sds %0,%1,%#r0"
  1974.   [(set_attr "type" "dpadd")])
  1975.  
  1976. (define_insn ""
  1977.   [(set (match_operand:SF 0 "register_operand" "=r,x")
  1978.     (float_truncate:SF (match_operand:DF 1 "register_operand" "r,x")))]
  1979.   "TARGET_88110"
  1980.   "fcvt.sd %0,%1"
  1981.   [(set_attr "type" "dpadd")])
  1982.  
  1983. ;; Conversions between floating point and integer
  1984.  
  1985. (define_insn "floatsidf2"
  1986.   [(set (match_operand:DF 0 "register_operand" "=r,x")
  1987.     (float:DF (match_operand:SI 1 "register_operand" "r,r")))]
  1988.   ""
  1989.   "flt.ds %0,%1"
  1990.   [(set_attr "type" "spadd,dpadd")])
  1991.  
  1992. (define_insn "floatsisf2"
  1993.   [(set (match_operand:SF 0 "register_operand" "=r,x")
  1994.     (float:SF (match_operand:SI 1 "register_operand" "r,r")))]
  1995.   ""
  1996.   "flt.ss %0,%1"
  1997.   [(set_attr "type" "spadd,spadd")])
  1998.  
  1999. (define_insn "fix_truncdfsi2"
  2000.   [(set (match_operand:SI 0 "register_operand" "=r,x")
  2001.     (fix:SI (match_operand:DF 1 "register_operand" "r,r")))]
  2002.   ""
  2003.   "trnc.sd %0,%1"
  2004.   [(set_attr "type" "dpadd,dpadd")])
  2005.  
  2006. (define_insn "fix_truncsfsi2"
  2007.   [(set (match_operand:SI 0 "register_operand" "=r,x")
  2008.     (fix:SI (match_operand:SF 1 "register_operand" "r,r")))]
  2009.   ""
  2010.   "trnc.ss %0,%1"
  2011.   [(set_attr "type" "spadd,dpadd")])
  2012.  
  2013.  
  2014. ;;- arithmetic instructions
  2015. ;;- add instructions
  2016.  
  2017. (define_insn "addsi3"
  2018.   [(set (match_operand:SI 0 "register_operand" "=r,r")
  2019.     (plus:SI (match_operand:SI 1 "add_operand" "%r,r")
  2020.          (match_operand:SI 2 "add_operand" "rI,J")))]
  2021.   ""
  2022.   "@
  2023.    addu %0,%1,%2
  2024.    subu %0,%1,%n2")
  2025.  
  2026. ;; patterns for mixed mode floating point.
  2027. ;; Do not define patterns that utilize mixed mode arithmetic that result
  2028. ;; in narrowing the precision, because it loses accuracy, since the standard
  2029. ;; requires double rounding, whereas the 88000 instruction only rounds once.
  2030.  
  2031. (define_expand "adddf3"
  2032.   [(set (match_operand:DF 0 "register_operand" "=r,x")
  2033.     (plus:DF (match_operand:DF 1 "general_operand" "%r,x")
  2034.          (match_operand:DF 2 "general_operand" "r,x")))]
  2035.   ""
  2036.   "
  2037. {
  2038.   operands[1] = legitimize_operand (operands[1], DFmode);
  2039.   operands[2] = legitimize_operand (operands[2], DFmode);
  2040. }")
  2041.  
  2042. (define_insn ""
  2043.   [(set (match_operand:DF 0 "register_operand" "=r,x")
  2044.     (plus:DF (float_extend:DF (match_operand:SF 1 "register_operand" "r,x"))
  2045.          (float_extend:DF (match_operand:SF 2 "register_operand" "r,x"))))]
  2046.   ""
  2047.   "fadd.dss %0,%1,%2"
  2048.   [(set_attr "type" "spadd")])
  2049.  
  2050. (define_insn ""
  2051.   [(set (match_operand:DF 0 "register_operand" "=r,x")
  2052.     (plus:DF (match_operand:DF 1 "register_operand" "r,x")
  2053.          (float_extend:DF (match_operand:SF 2 "register_operand" "r,x"))))]
  2054.   ""
  2055.   "fadd.dds %0,%1,%2"
  2056.   [(set_attr "type" "dpadd")])
  2057.  
  2058. (define_insn ""
  2059.   [(set (match_operand:DF 0 "register_operand" "=r,x")
  2060.     (plus:DF (float_extend:DF (match_operand:SF 1 "register_operand" "r,x"))
  2061.          (match_operand:DF 2 "register_operand" "r,x")))]
  2062.   ""
  2063.   "fadd.dsd %0,%1,%2"
  2064.   [(set_attr "type" "dpadd")])
  2065.  
  2066. (define_insn ""
  2067.   [(set (match_operand:DF 0 "register_operand" "=r,x")
  2068.     (plus:DF (match_operand:DF 1 "register_operand" "%r,x")
  2069.          (match_operand:DF 2 "register_operand" "r,x")))]
  2070.   ""
  2071.   "fadd.ddd %0,%1,%2"
  2072.   [(set_attr "type" "dpadd")])
  2073.  
  2074. (define_insn "addsf3"
  2075.   [(set (match_operand:SF 0 "register_operand" "=r,x")
  2076.     (plus:SF (match_operand:SF 1 "register_operand" "%r,x")
  2077.          (match_operand:SF 2 "register_operand" "r,x")))]
  2078.   ""
  2079.   "fadd.sss %0,%1,%2"
  2080.   [(set_attr "type" "spadd")])
  2081.  
  2082. (define_insn ""
  2083.   [(set (match_operand:DI 0 "register_operand" "=r")
  2084.     (plus:DI (match_operand:DI 1 "register_operand" "r")
  2085.          (zero_extend:DI
  2086.           (match_operand:SI 2 "register_operand" "r"))))
  2087.    (clobber (reg:CC 0))]
  2088.   ""
  2089.   "addu.co %d0,%d1,%2\;addu.ci %0,%1,%#r0"
  2090.   [(set_attr "type" "marith")])
  2091.  
  2092. (define_insn ""
  2093.   [(set (match_operand:DI 0 "register_operand" "=r")
  2094.     (plus:DI (zero_extend:DI
  2095.           (match_operand:SI 1 "register_operand" "r"))
  2096.          (match_operand:DI 2 "register_operand" "r")))
  2097.    (clobber (reg:CC 0))]
  2098.   ""
  2099.   "addu.co %d0,%1,%d2\;addu.ci %0,%#r0,%2"
  2100.   [(set_attr "type" "marith")])
  2101.  
  2102. (define_insn "adddi3"
  2103.   [(set (match_operand:DI 0 "register_operand" "=r")
  2104.     (plus:DI (match_operand:DI 1 "register_operand" "%r")
  2105.          (match_operand:DI 2 "register_operand" "r")))
  2106.    (clobber (reg:CC 0))]
  2107.   ""
  2108.   "addu.co %d0,%d1,%d2\;addu.ci %0,%1,%2"
  2109.   [(set_attr "type" "marith")])
  2110.  
  2111. ;; Add with carry insns.
  2112.  
  2113. (define_insn ""
  2114.   [(parallel [(set (match_operand:SI 0 "reg_or_0_operand" "=r")
  2115.            (plus:SI (match_operand:SI 1 "reg_or_0_operand" "rO")
  2116.                 (match_operand:SI 2 "reg_or_0_operand" "rO")))
  2117.           (set (reg:CC 0)
  2118.            (unspec:CC [(match_dup 1) (match_dup 2)] 0))])]
  2119.   ""
  2120.   "addu.co %r0,%r1,%r2")
  2121.  
  2122. (define_insn ""
  2123.   [(set (reg:CC 0) (unspec:CC [(match_operand:SI 0 "reg_or_0_operand" "rO")
  2124.                    (match_operand:SI 1 "reg_or_0_operand" "rO")]
  2125.                   0))]
  2126.   ""
  2127.   "addu.co %#r0,%r0,%r1")
  2128.  
  2129. (define_insn ""
  2130.   [(set (match_operand:SI 0 "reg_or_0_operand" "=r")
  2131.     (plus:SI (match_operand:SI 1 "reg_or_0_operand" "rO")
  2132.          (unspec:SI [(match_operand:SI 2 "reg_or_0_operand" "rO")
  2133.                  (reg:CC 0)] 0)))]
  2134.   ""
  2135.   "addu.ci %r0,%r1,%r2")
  2136.  
  2137. ;;- subtract instructions
  2138.  
  2139. (define_insn "subsi3"
  2140.   [(set (match_operand:SI 0 "register_operand" "=r")
  2141.     (minus:SI (match_operand:SI 1 "register_operand" "r")
  2142.           (match_operand:SI 2 "arith32_operand" "rI")))]
  2143.   ""
  2144.   "subu %0,%1,%2")
  2145.  
  2146. ;; patterns for mixed mode floating point
  2147. ;; Do not define patterns that utilize mixed mode arithmetic that result
  2148. ;; in narrowing the precision, because it loses accuracy, since the standard
  2149. ;; requires double rounding, whereas the 88000 instruction only rounds once.
  2150.  
  2151. (define_expand "subdf3"
  2152.   [(set (match_operand:DF 0 "register_operand" "=r,x")
  2153.     (minus:DF (match_operand:DF 1 "general_operand" "r,x")
  2154.           (match_operand:DF 2 "general_operand" "r,x")))]
  2155.   ""
  2156.   "
  2157. {
  2158.   operands[1] = legitimize_operand (operands[1], DFmode);
  2159.   operands[2] = legitimize_operand (operands[2], DFmode);
  2160. }")
  2161.  
  2162. (define_insn ""
  2163.   [(set (match_operand:DF 0 "register_operand" "=r,x")
  2164.     (minus:DF (float_extend:DF (match_operand:SF 1 "register_operand" "r,x"))
  2165.           (float_extend:DF (match_operand:SF 2 "register_operand" "r,x"))))]
  2166.   ""
  2167.   "fsub.dss %0,%1,%2"
  2168.   [(set_attr "type" "spadd")])
  2169.  
  2170. (define_insn ""
  2171.   [(set (match_operand:DF 0 "register_operand" "=r,x")
  2172.     (minus:DF (match_operand:DF 1 "register_operand" "r,x")
  2173.           (float_extend:DF (match_operand:SF 2 "register_operand" "r,x"))))]
  2174.   ""
  2175.   "fsub.dds %0,%1,%2"
  2176.   [(set_attr "type" "dpadd")])
  2177.  
  2178. (define_insn ""
  2179.   [(set (match_operand:DF 0 "register_operand" "=r,x")
  2180.     (minus:DF (float_extend:DF (match_operand:SF 1 "register_operand" "r,x"))
  2181.           (match_operand:DF 2 "register_operand" "r,x")))]
  2182.   ""
  2183.   "fsub.dsd %0,%1,%2"
  2184.   [(set_attr "type" "dpadd")])
  2185.  
  2186. (define_insn ""
  2187.   [(set (match_operand:DF 0 "register_operand" "=r,x")
  2188.     (minus:DF (match_operand:DF 1 "register_operand" "r,x")
  2189.           (match_operand:DF 2 "register_operand" "r,x")))]
  2190.   ""
  2191.   "fsub.ddd %0,%1,%2"
  2192.   [(set_attr "type" "dpadd")])
  2193.  
  2194. (define_insn "subsf3"
  2195.   [(set (match_operand:SF 0 "register_operand" "=r,x")
  2196.     (minus:SF (match_operand:SF 1 "register_operand" "r,x")
  2197.           (match_operand:SF 2 "register_operand" "r,x")))]
  2198.   ""
  2199.   "fsub.sss %0,%1,%2"
  2200.   [(set_attr "type" "spadd")])
  2201.  
  2202. (define_insn ""
  2203.   [(set (match_operand:DI 0 "register_operand" "=r")
  2204.     (minus:DI (match_operand:DI 1 "register_operand" "r")
  2205.           (zero_extend:DI
  2206.            (match_operand:SI 2 "register_operand" "r"))))
  2207.    (clobber (reg:CC 0))]
  2208.   ""
  2209.   "subu.co %d0,%d1,%2\;subu.ci %0,%1,%#r0"
  2210.   [(set_attr "type" "marith")])
  2211.  
  2212. (define_insn ""
  2213.   [(set (match_operand:DI 0 "register_operand" "=r")
  2214.     (minus:DI (zero_extend:DI
  2215.            (match_operand:SI 1 "register_operand" "r"))
  2216.           (match_operand:DI 2 "register_operand" "r")))
  2217.    (clobber (reg:CC 0))]
  2218.   ""
  2219.   "subu.co %d0,%1,%d2\;subu.ci %0,%#r0,%2"
  2220.   [(set_attr "type" "marith")])
  2221.  
  2222. (define_insn "subdi3"
  2223.   [(set (match_operand:DI 0 "register_operand" "=r")
  2224.     (minus:DI (match_operand:DI 1 "register_operand" "r")
  2225.           (match_operand:DI 2 "register_operand" "r")))
  2226.    (clobber (reg:CC 0))]
  2227.   ""
  2228.   "subu.co %d0,%d1,%d2\;subu.ci %0,%1,%2"
  2229.   [(set_attr "type" "marith")])
  2230.  
  2231. ;; Subtract with carry insns.
  2232.  
  2233. (define_insn ""
  2234.   [(parallel [(set (match_operand:SI 0 "reg_or_0_operand" "=r")
  2235.            (minus:SI (match_operand:SI 1 "reg_or_0_operand" "rO")
  2236.                  (match_operand:SI 2 "reg_or_0_operand" "rO")))
  2237.           (set (reg:CC 0)
  2238.            (unspec:CC [(match_dup 1) (match_dup 2)] 1))])]
  2239.   ""
  2240.   "subu.co %r0,%r1,%r2")
  2241.  
  2242. (define_insn ""
  2243.   [(set (reg:CC 0) (unspec:CC [(match_operand:SI 0 "reg_or_0_operand" "rO")
  2244.                    (match_operand:SI 1 "reg_or_0_operand" "rO")]
  2245.                   1))]
  2246.   ""
  2247.   "subu.co %#r0,%r0,%r1")
  2248.  
  2249. (define_insn ""
  2250.   [(set (match_operand:SI 0 "reg_or_0_operand" "=r")
  2251.     (minus:SI (match_operand:SI 1 "reg_or_0_operand" "rO")
  2252.           (unspec:SI [(match_operand:SI 2 "reg_or_0_operand" "rO")
  2253.                   (reg:CC 0)] 1)))]
  2254.   ""
  2255.   "subu.ci %r0,%r1,%r2")
  2256.  
  2257. ;;- multiply instructions
  2258. ;;
  2259. ;; There is an unfounded silicon eratta for E.1 requiring that an
  2260. ;; immediate constant value in div/divu/mul instructions be less than
  2261. ;; 0x800.  This is no longer provided for.
  2262.  
  2263. (define_insn "mulsi3"
  2264.   [(set (match_operand:SI 0 "register_operand" "=r")
  2265.     (mult:SI (match_operand:SI 1 "arith32_operand" "%r")
  2266.          (match_operand:SI 2 "arith32_operand" "rI")))]
  2267.   ""
  2268.   "mul %0,%1,%2"
  2269.   [(set_attr "type" "imul")])
  2270.  
  2271. (define_insn "umulsidi3"
  2272.   [(set (match_operand:DI 0 "register_operand" "=r")
  2273.         (mult:DI (zero_extend:DI (match_operand:SI 1 "register_operand" "%r"))
  2274.                  (zero_extend:DI (match_operand:SI 2 "register_operand" "r"))))]
  2275.   "TARGET_88110"
  2276.   "mulu.d %0,%1,%2"
  2277.   [(set_attr "type" "imul")])
  2278.  
  2279. ;; patterns for mixed mode floating point
  2280. ;; Do not define patterns that utilize mixed mode arithmetic that result
  2281. ;; in narrowing the precision, because it loses accuracy, since the standard
  2282. ;; requires double rounding, whereas the 88000 instruction only rounds once.
  2283.  
  2284. (define_expand "muldf3"
  2285.   [(set (match_operand:DF 0 "register_operand" "=r,x")
  2286.     (mult:DF (match_operand:DF 1 "general_operand" "%r,x")
  2287.          (match_operand:DF 2 "general_operand" "r,x")))]
  2288.   ""
  2289.   "
  2290. {
  2291.   operands[1] = legitimize_operand (operands[1], DFmode);
  2292.   operands[2] = legitimize_operand (operands[2], DFmode);
  2293. }")
  2294.  
  2295. (define_insn ""
  2296.   [(set (match_operand:DF 0 "register_operand" "=r,x")
  2297.     (mult:DF (float_extend:DF (match_operand:SF 1 "register_operand" "r,x"))
  2298.          (float_extend:DF (match_operand:SF 2 "register_operand" "r,x"))))]
  2299.   ""
  2300.   "fmul.dss %0,%1,%2"
  2301.   [(set_attr "type" "spmul")])
  2302.  
  2303. (define_insn ""
  2304.   [(set (match_operand:DF 0 "register_operand" "=r,x")
  2305.     (mult:DF (match_operand:DF 1 "register_operand" "r,x")
  2306.          (float_extend:DF (match_operand:SF 2 "register_operand" "r,x"))))]
  2307.   ""
  2308.   "fmul.dds %0,%1,%2"
  2309.   [(set_attr "type" "spmul")])
  2310.  
  2311. (define_insn ""
  2312.   [(set (match_operand:DF 0 "register_operand" "=r,x")
  2313.     (mult:DF (float_extend:DF (match_operand:SF 1 "register_operand" "r,x"))
  2314.          (match_operand:DF 2 "register_operand" "r,x")))]
  2315.   ""
  2316.   "fmul.dsd %0,%1,%2"
  2317.   [(set_attr "type" "spmul")])
  2318.  
  2319. (define_insn ""
  2320.   [(set (match_operand:DF 0 "register_operand" "=r,x")
  2321.     (mult:DF (match_operand:DF 1 "register_operand" "%r,x")
  2322.          (match_operand:DF 2 "register_operand" "r,x")))]
  2323.   ""
  2324.   "fmul.ddd %0,%1,%2"
  2325.   [(set_attr "type" "dpmul")])
  2326.  
  2327. (define_insn "mulsf3"
  2328.   [(set (match_operand:SF 0 "register_operand" "=r,x")
  2329.     (mult:SF (match_operand:SF 1 "register_operand" "%r,x")
  2330.          (match_operand:SF 2 "register_operand" "r,x")))]
  2331.   ""
  2332.   "fmul.sss %0,%1,%2"
  2333.   [(set_attr "type" "spmul")])
  2334.  
  2335. ;;- divide instructions
  2336. ;;
  2337. ;; The 88k div and divu instructions don't reliably trap on
  2338. ;; divide-by-zero.  A trap to vector 503 asserts divide-by-zero.  The
  2339. ;; general scheme for doing divide is to do a 4-way split based on the
  2340. ;; sign of the two operand and do the appropriate negates.
  2341. ;;
  2342. ;; The conditional trap instruction is not used as this serializes the
  2343. ;; processor.  Instead a conditional branch and an unconditional trap
  2344. ;; are used, but after the divu.  Since the divu takes up to 38 cycles,
  2345. ;; the conditional branch is essentially free.
  2346. ;;
  2347. ;; Two target options control how divide is done.  One options selects
  2348. ;; whether to do the branch and negate scheme instead of using the div
  2349. ;; instruction; the other option selects whether to explicitly check
  2350. ;; for divide-by-zero or take your chances.  If the div instruction is
  2351. ;; used, the O/S must complete the operation if the operands are
  2352. ;; negative.  The O/S will signal an overflow condition if the most
  2353. ;; negative number (-214783648) is divided by negative 1.
  2354. ;;
  2355. ;; There is an unfounded silicon eratta for E.1 requiring that an
  2356. ;; immediate constant value in div/divu/mul instructions be less than
  2357. ;; 0x800.  This is no longer provided for.
  2358.  
  2359. ;; Division by 0 trap
  2360. (define_insn "trap_divide_by_zero"
  2361.   [(trap_if (const_int 1) 503)]
  2362.   ""
  2363.   "tb0 0,%#r0,503"
  2364.   [(set_attr "type" "weird")])
  2365.  
  2366. ;; Conditional division by 0 trap.
  2367. (define_expand "tcnd_divide_by_zero"
  2368.   [(set (pc)
  2369.     (if_then_else (eq (match_operand:SI 0 "register_operand" "")
  2370.               (const_int 0))
  2371.               (pc)
  2372.               (match_operand 1 "" "")))
  2373.    (trap_if (const_int 1) 503)]
  2374.   ""
  2375.   "
  2376. {
  2377.   emit_insn (gen_cmpsi (operands[0], const0_rtx));
  2378.   emit_jump_insn (gen_bne (operands[1]));
  2379.   emit_insn (gen_trap_divide_by_zero ());
  2380.   DONE;
  2381. }")
  2382.  
  2383. (define_expand "divsi3"
  2384.   [(set (match_operand:SI 0 "register_operand" "")
  2385.     (div:SI (match_operand:SI 1 "arith32_operand" "")
  2386.         (match_operand:SI 2 "arith32_operand" "")))]
  2387.   ""
  2388.   "
  2389. {
  2390.   rtx op0 = operands[0];
  2391.   rtx op1 = operands[1];
  2392.   rtx op2 = operands[2];
  2393.   rtx join_label;
  2394.  
  2395.   /* @@ This needs to be reworked.  Torbjorn Granlund has suggested making
  2396.      it a runtime (perhaps quite special).  */
  2397.  
  2398.   if (GET_CODE (op1) == CONST_INT)
  2399.     op1 = force_reg (SImode, op1);
  2400.  
  2401.   else if (GET_CODE (op2) == CONST_INT
  2402.        && ! SMALL_INT (operands[2]))
  2403.     op2 = force_reg (SImode, op2);
  2404.  
  2405.   if (op2 == const0_rtx)
  2406.     {
  2407.       emit_insn (gen_trap_divide_by_zero ());
  2408.       emit_insn (gen_dummy (op0));
  2409.       DONE;
  2410.     }
  2411.  
  2412.   if (TARGET_USE_DIV)
  2413.     {
  2414.       emit_move_insn (op0, gen_rtx (DIV, SImode, op1, op2));
  2415.       if (TARGET_CHECK_ZERO_DIV && GET_CODE (op2) != CONST_INT)
  2416.     {
  2417.       rtx label = gen_label_rtx ();
  2418.       emit_insn (gen_tcnd_divide_by_zero (op2, label));
  2419.       emit_label (label);
  2420.       emit_insn (gen_dummy (op0));
  2421.     }
  2422.       DONE;
  2423.     }
  2424.  
  2425.   join_label = gen_label_rtx ();
  2426.   if (GET_CODE (op1) == CONST_INT)
  2427.     {
  2428.       int neg = FALSE;
  2429.       rtx neg_op2 = gen_reg_rtx (SImode);
  2430.       rtx label1 = gen_label_rtx ();
  2431.  
  2432.       if (INTVAL (op1) < 0)
  2433.     {
  2434.       neg = TRUE;
  2435.       op1 = gen_rtx (CONST_INT, VOIDmode, -INTVAL (op1));
  2436.     }
  2437.       op1 = force_reg (SImode, op1);
  2438.  
  2439.       emit_insn (gen_negsi2 (neg_op2, op2));
  2440.       emit_insn (gen_cmpsi (op2, const0_rtx));
  2441.       emit_jump_insn (gen_bgt (label1));
  2442.                         /* constant / 0-or-negative */
  2443.       emit_move_insn (op0, gen_rtx (UDIV, SImode, op1, neg_op2));
  2444.       if (!neg)
  2445.     emit_insn (gen_negsi2 (op0, op0));
  2446.  
  2447.       if (TARGET_CHECK_ZERO_DIV)
  2448.     emit_insn (gen_tcnd_divide_by_zero (op2, join_label));
  2449.       emit_jump_insn (gen_jump (join_label));
  2450.       emit_barrier ();
  2451.  
  2452.       emit_label (label1);            /* constant / positive */
  2453.       emit_move_insn (op0, gen_rtx (UDIV, SImode, op1, op2));
  2454.       if (neg)
  2455.     emit_insn (gen_negsi2 (op0, op0));
  2456.     }
  2457.  
  2458.   else if (GET_CODE (op2) == CONST_INT)
  2459.     {
  2460.       int neg = FALSE;
  2461.       rtx neg_op1 = gen_reg_rtx (SImode);
  2462.       rtx label1 = gen_label_rtx ();
  2463.  
  2464.       if (INTVAL (op2) < 0)
  2465.     {
  2466.       neg = TRUE;
  2467.       op2 = gen_rtx (CONST_INT, VOIDmode, -INTVAL (op2));
  2468.     }
  2469.       else if (! SMALL_INT (operands[2]))
  2470.     op2 = force_reg (SImode, op2);
  2471.  
  2472.       emit_insn (gen_negsi2 (neg_op1, op1));
  2473.       emit_insn (gen_cmpsi (op1, const0_rtx));
  2474.       emit_jump_insn (gen_bge (label1));
  2475.                         /* 0-or-negative / constant */
  2476.       emit_move_insn (op0, gen_rtx (UDIV, SImode, neg_op1, op2));
  2477.       if (!neg)
  2478.     emit_insn (gen_negsi2 (op0, op0));
  2479.  
  2480.       emit_jump_insn (gen_jump (join_label));
  2481.       emit_barrier ();
  2482.  
  2483.       emit_label (label1);            /* positive / constant */
  2484.       emit_move_insn (op0, gen_rtx (UDIV, SImode, op1, op2));
  2485.       if (neg)
  2486.     emit_insn (gen_negsi2 (op0, op0));
  2487.     }
  2488.  
  2489.   else
  2490.     {
  2491.       rtx neg_op1 = gen_reg_rtx (SImode);
  2492.       rtx neg_op2 = gen_reg_rtx (SImode);
  2493.       rtx label1 = gen_label_rtx ();
  2494.       rtx label2 = gen_label_rtx ();
  2495.       rtx label3 = gen_label_rtx ();
  2496.       rtx label4;
  2497.  
  2498.       emit_insn (gen_negsi2 (neg_op2, op2));
  2499.       emit_insn (gen_cmpsi (op2, const0_rtx));
  2500.       emit_jump_insn (gen_bgt (label1));
  2501.  
  2502.       emit_insn (gen_negsi2 (neg_op1, op1));
  2503.       emit_insn (gen_cmpsi (op1, const0_rtx));
  2504.       emit_jump_insn (gen_bge (label2));
  2505.                         /* negative / negative-or-0 */
  2506.       emit_move_insn (op0, gen_rtx (UDIV, SImode, neg_op1, neg_op2));
  2507.  
  2508.       if (TARGET_CHECK_ZERO_DIV)
  2509.     {
  2510.       label4 = gen_label_rtx ();
  2511.       emit_insn (gen_cmpsi (op2, const0_rtx));
  2512.       emit_jump_insn (gen_bne (join_label));
  2513.       emit_label (label4);
  2514.       emit_insn (gen_trap_divide_by_zero ());
  2515.     }
  2516.       emit_jump_insn (gen_jump (join_label));
  2517.       emit_barrier ();
  2518.  
  2519.       emit_label (label2);            /* pos.-or-0 / neg.-or-0 */
  2520.       emit_move_insn (op0, gen_rtx (UDIV, SImode, op1, neg_op2));
  2521.  
  2522.       if (TARGET_CHECK_ZERO_DIV)
  2523.     {
  2524.       emit_insn (gen_cmpsi (op2, const0_rtx));
  2525.       emit_jump_insn (gen_beq (label4));
  2526.     }
  2527.  
  2528.       emit_insn (gen_negsi2 (op0, op0));
  2529.       emit_jump_insn (gen_jump (join_label));
  2530.       emit_barrier ();
  2531.  
  2532.       emit_label (label1);
  2533.       emit_insn (gen_negsi2 (neg_op1, op1));
  2534.       emit_insn (gen_cmpsi (op1, const0_rtx));
  2535.       emit_jump_insn (gen_bge (label3));
  2536.                         /* negative / positive */
  2537.       emit_move_insn (op0, gen_rtx (UDIV, SImode, neg_op1, op2));
  2538.       emit_insn (gen_negsi2 (op0, op0));
  2539.       emit_jump_insn (gen_jump (join_label));
  2540.       emit_barrier ();
  2541.  
  2542.       emit_label (label3);            /* positive-or-0 / positive */
  2543.       emit_move_insn (op0, gen_rtx (UDIV, SImode, op1, op2));
  2544.     }
  2545.  
  2546.   emit_label (join_label);
  2547.  
  2548.   emit_insn (gen_dummy (op0));
  2549.   DONE;
  2550. }")
  2551.  
  2552. (define_insn ""
  2553.   [(set (match_operand:SI 0 "register_operand" "=r")
  2554.     (div:SI (match_operand:SI 1 "register_operand" "r")
  2555.         (match_operand:SI 2 "arith_operand" "rI")))]
  2556.   ""
  2557.   "div %0,%1,%2"
  2558.   [(set_attr "type" "idiv")])
  2559.  
  2560. (define_expand "udivsi3"
  2561.   [(set (match_operand:SI 0 "register_operand" "")
  2562.     (udiv:SI (match_operand:SI 1 "register_operand" "")
  2563.          (match_operand:SI 2 "arith32_operand" "")))]
  2564.   ""
  2565.   "
  2566. {
  2567.   rtx op2 = operands[2];
  2568.  
  2569.   if (op2 == const0_rtx)
  2570.     {
  2571.       emit_insn (gen_trap_divide_by_zero ());
  2572.       emit_insn (gen_dummy (operands[0]));
  2573.       DONE;
  2574.     }
  2575.   else if (GET_CODE (op2) != CONST_INT && TARGET_CHECK_ZERO_DIV)
  2576.     {
  2577.       rtx label = gen_label_rtx ();
  2578.       emit_insn (gen_rtx (SET, VOIDmode, operands[0],
  2579.               gen_rtx (UDIV, SImode, operands[1], op2)));
  2580.       emit_insn (gen_tcnd_divide_by_zero (op2, label));
  2581.       emit_label (label);
  2582.       emit_insn (gen_dummy (operands[0]));
  2583.       DONE;
  2584.     }
  2585. }")
  2586.  
  2587. (define_insn ""
  2588.  [(set (match_operand:SI 0 "register_operand" "=r")
  2589.        (udiv:SI (match_operand:SI 1 "register_operand" "r")
  2590.         (match_operand:SI 2 "arith32_operand" "rI")))]
  2591.   "operands[2] != const0_rtx"
  2592.   "divu %0,%1,%2"
  2593.   [(set_attr "type" "idiv")])
  2594.  
  2595. (define_insn ""
  2596.  [(set (match_operand:SI 0 "register_operand" "=r")
  2597.        (udiv:SI (match_operand:SI 1 "register_operand" "r")
  2598.         (const_int 0)))]
  2599.   ""
  2600.   "tb0 0,%#r0,503"
  2601.   [(set_attr "type" "weird")])
  2602.  
  2603. ;; patterns for mixed mode floating point.
  2604. ;; Do not define patterns that utilize mixed mode arithmetic that result
  2605. ;; in narrowing the precision, because it loses accuracy, since the standard
  2606. ;; requires double rounding, whereas the 88000 instruction only rounds once.
  2607.  
  2608. (define_expand "divdf3"
  2609.   [(set (match_operand:DF 0 "register_operand" "=r,x")
  2610.     (div:DF (match_operand:DF 1 "general_operand" "r,x")
  2611.         (match_operand:DF 2 "general_operand" "r,x")))]
  2612.   ""
  2613.   "
  2614. {
  2615.   operands[1] = legitimize_operand (operands[1], DFmode);
  2616.   if (real_power_of_2_operand (operands[2]))
  2617.     {
  2618.       union real_extract u;
  2619.       bcopy (&CONST_DOUBLE_LOW (operands[2]), &u, sizeof u);
  2620.       emit_insn (gen_muldf3 (operands[0], operands[1],
  2621.                  CONST_DOUBLE_FROM_REAL_VALUE (1.0/u.d, DFmode)));
  2622.       DONE;
  2623.     }
  2624.   else if (! register_operand (operands[2], DFmode))
  2625.     operands[2] = force_reg (DFmode, operands[2]);
  2626. }")
  2627.  
  2628. (define_insn ""
  2629.   [(set (match_operand:DF 0 "register_operand" "=r,x")
  2630.     (div:DF (float_extend:DF (match_operand:SF 1 "register_operand" "r,x"))
  2631.         (float_extend:DF (match_operand:SF 2 "register_operand" "r,x"))))]
  2632.   ""
  2633.   "fdiv.dss %0,%1,%2"
  2634.   [(set_attr "type" "dpdiv")])
  2635.  
  2636. (define_insn ""
  2637.   [(set (match_operand:DF 0 "register_operand" "=r,x")
  2638.     (div:DF (match_operand:DF 1 "register_operand" "r,x")
  2639.         (float_extend:DF (match_operand:SF 2 "register_operand" "r,x"))))]
  2640.   ""
  2641.   "fdiv.dds %0,%1,%2"
  2642.   [(set_attr "type" "dpdiv")])
  2643.  
  2644. (define_insn ""
  2645.   [(set (match_operand:DF 0 "register_operand" "=r,x")
  2646.     (div:DF (float_extend:DF (match_operand:SF 1 "register_operand" "r,x"))
  2647.         (match_operand:DF 2 "register_operand" "r,x")))]
  2648.   ""
  2649.   "fdiv.dsd %0,%1,%2"
  2650.   [(set_attr "type" "dpdiv")])
  2651.  
  2652. (define_insn "divsf3"
  2653.   [(set (match_operand:SF 0 "register_operand" "=r,x")
  2654.     (div:SF (match_operand:SF 1 "register_operand" "r,x")
  2655.         (match_operand:SF 2 "register_operand" "r,x")))]
  2656.   ""
  2657.   "fdiv.sss %0,%1,%2"
  2658.   [(set_attr "type" "spdiv")])
  2659.  
  2660. (define_insn ""
  2661.   [(set (match_operand:DF 0 "register_operand" "=r,x")
  2662.     (div:DF (match_operand:DF 1 "register_operand" "r,x")
  2663.         (match_operand:DF 2 "register_operand" "r,x")))]
  2664.   ""
  2665.   "fdiv.ddd %0,%1,%2"
  2666.   [(set_attr "type" "dpdiv")])
  2667.  
  2668. ;; - remainder instructions, don't define, since the hardware doesn't have any
  2669. ;; direct support, and GNU can synthesis them out of div/mul just fine.
  2670.  
  2671. ;;- load effective address, must come after add, so that we favor using
  2672. ;;  addu reg,reg,reg  instead of:  lda reg,reg,reg (addu doesn't require
  2673. ;;  the data unit), and also future 88k chips might not support unscaled
  2674. ;;  lda instructions.
  2675.  
  2676. (define_insn ""
  2677.   [(set (match_operand:SI 0 "register_operand" "=r")
  2678.     (match_operand:SI 1 "address_operand" "p"))]
  2679.   "m88k_gp_threshold > 0 && symbolic_address_p (operands[1])"
  2680.   "addu %0,%a1")
  2681.  
  2682. (define_insn ""
  2683.   [(set (match_operand:SI 0 "register_operand" "=r")
  2684.     (match_operand:HI 1 "address_operand" "p"))]
  2685.   ""
  2686.   "lda.h %0,%a1"
  2687.   [(set_attr "type" "loada")])
  2688.  
  2689. (define_insn ""
  2690.   [(set (match_operand:SI 0 "register_operand" "=r")
  2691.     (match_operand:SI 1 "address_operand" "p"))]
  2692.   ""
  2693.   "lda %0,%a1"
  2694.   [(set_attr "type" "loada")])
  2695.  
  2696. (define_insn ""
  2697.   [(set (match_operand:SI 0 "register_operand" "=r")
  2698.     (match_operand:DI 1 "address_operand" "p"))]
  2699.   ""
  2700.   "lda.d %0,%a1"
  2701.   [(set_attr "type" "loada")])
  2702.  
  2703. (define_insn ""
  2704.   [(set (match_operand:SI 0 "register_operand" "=r")
  2705.     (match_operand:SF 1 "address_operand" "p"))]
  2706.   ""
  2707.   "lda %0,%a1"
  2708.   [(set_attr "type" "loada")])
  2709.  
  2710. (define_insn ""
  2711.   [(set (match_operand:SI 0 "register_operand" "=r")
  2712.     (match_operand:DF 1 "address_operand" "p"))]
  2713.   ""
  2714.   "lda.d %0,%a1"
  2715.   [(set_attr "type" "loada")])
  2716.  
  2717. ;;- and instructions (with complement also)
  2718. (define_insn ""
  2719.   [(set (match_operand:SI 0 "register_operand" "=r")
  2720.     (and:SI (not:SI (match_operand:SI 1 "register_operand" "r"))
  2721.         (match_operand:SI 2 "register_operand" "r")))]
  2722.   ""
  2723.   "and.c %0,%2,%1")
  2724.  
  2725. ;; If the operation is being performed on a 32-bit constant such that
  2726. ;; it cannot be done in one insn, do it in two.  We may lose a bit on
  2727. ;; CSE in pathological cases, but it seems better doing it this way.
  2728.  
  2729. (define_expand "andsi3"
  2730.   [(set (match_operand:SI 0 "register_operand" "")
  2731.     (and:SI (match_operand:SI 1 "arith32_operand" "")
  2732.         (match_operand:SI 2 "arith32_operand" "")))]
  2733.   ""
  2734.   "
  2735. {
  2736.   if (GET_CODE (operands[2]) == CONST_INT)
  2737.     {
  2738.       int value = INTVAL (operands[2]);
  2739.  
  2740.       if (! (SMALL_INTVAL (value)
  2741.          || (value & 0xffff0000) == 0xffff0000
  2742.          || (value & 0xffff) == 0xffff
  2743.          || (value & 0xffff) == 0
  2744.          || integer_ok_for_set (~value)))
  2745.     {
  2746.       emit_insn (gen_andsi3 (operands[0], operands[1],
  2747.                  gen_rtx (CONST_INT, VOIDmode,
  2748.                       value | 0xffff)));
  2749.       operands[1] = operands[0];
  2750.       operands[2] = gen_rtx (CONST_INT, VOIDmode, value | 0xffff0000);
  2751.     }
  2752.     }
  2753. }")
  2754.  
  2755. (define_insn ""
  2756.   [(set (match_operand:SI 0 "register_operand" "=r,r")
  2757.     (and:SI (match_operand:SI 1 "arith32_operand" "%r,r")
  2758.         (match_operand:SI 2 "arith32_operand" "rIJL,rn")))]
  2759.   ""
  2760.   "* return output_and (operands);"
  2761.   [(set_attr "type" "arith,marith")])
  2762.  
  2763. (define_insn ""
  2764.   [(set (match_operand:DI 0 "register_operand" "=r")
  2765.     (and:DI (not:DI (match_operand:DI 1 "register_operand" "r"))
  2766.         (match_operand:DI 2 "register_operand" "r")))]
  2767.   ""
  2768.   "and.c %d0,%d2,%d1\;and.c %0,%2,%1"
  2769.   [(set_attr "type" "marith")])
  2770.  
  2771. (define_insn "anddi3"
  2772.   [(set (match_operand:DI 0 "register_operand" "=r")
  2773.     (and:DI (match_operand:DI 1 "arith64_operand" "%r")
  2774.         (match_operand:DI 2 "arith64_operand" "rn")))]
  2775.   ""
  2776.   "*
  2777. {
  2778.   rtx xoperands[10];
  2779.  
  2780.   xoperands[0] = operand_subword (operands[0], 1, 0, DImode);
  2781.   xoperands[1] = operand_subword (operands[1], 1, 0, DImode);
  2782.   xoperands[2] = operand_subword (operands[2], 1, 0, DImode);
  2783.  
  2784.   output_asm_insn (output_and (xoperands), xoperands);
  2785.  
  2786.   operands[0] = operand_subword (operands[0], 0, 0, DImode);
  2787.   operands[1] = operand_subword (operands[1], 0, 0, DImode);
  2788.   operands[2] = operand_subword (operands[2], 0, 0, DImode);
  2789.  
  2790.   return output_and (operands);
  2791. }"
  2792.   [(set_attr "type" "marith")
  2793.    (set_attr "length" "4")]) ; length is 2, 3, or 4.
  2794.  
  2795. ;;- Bit set (inclusive or) instructions (with complement also)
  2796. (define_insn ""
  2797.   [(set (match_operand:SI 0 "register_operand" "=r")
  2798.     (ior:SI (not:SI (match_operand:SI 1 "register_operand" "r"))
  2799.         (match_operand:SI 2 "register_operand" "r")))]
  2800.   ""
  2801.   "or.c %0,%2,%1")
  2802.  
  2803. (define_expand "iorsi3"
  2804.   [(set (match_operand:SI 0 "register_operand" "")
  2805.     (ior:SI (match_operand:SI 1 "arith32_operand" "")
  2806.         (match_operand:SI 2 "arith32_operand" "")))]
  2807.   ""
  2808.   "
  2809. {
  2810.   if (GET_CODE (operands[2]) == CONST_INT)
  2811.     {
  2812.       int value = INTVAL (operands[2]);
  2813.  
  2814.       if (! (SMALL_INTVAL (value)
  2815.          || (value & 0xffff) == 0
  2816.          || integer_ok_for_set (value)))
  2817.     {
  2818.       emit_insn (gen_iorsi3 (operands[0], operands[1],
  2819.                  gen_rtx (CONST_INT, VOIDmode,
  2820.                       value & 0xffff0000)));
  2821.       operands[1] = operands[0];
  2822.       operands[2] = gen_rtx (CONST_INT, VOIDmode, value & 0xffff);
  2823.     }
  2824.     }
  2825. }")
  2826.  
  2827. (define_insn ""
  2828.   [(set (match_operand:SI 0 "register_operand" "=r,r,r,r")
  2829.     (ior:SI (match_operand:SI 1 "arith32_operand" "%r,r,r,r")
  2830.         (match_operand:SI 2 "arith32_operand" "rI,L,M,n")))]
  2831.   ""
  2832.   "@
  2833.    or %0,%1,%2
  2834.    or.u %0,%1,%X2
  2835.    set %0,%1,%s2
  2836.    or.u %0,%1,%X2\;or %0,%0,%x2"
  2837.   [(set_attr "type" "arith,arith,bit,marith")])
  2838.  
  2839. (define_insn ""
  2840.   [(set (match_operand:DI 0 "register_operand" "=r")
  2841.     (ior:DI (not:DI (match_operand:DI 1 "register_operand" "r"))
  2842.         (match_operand:DI 2 "register_operand" "r")))]
  2843.   ""
  2844.   "or.c %d0,%d2,%d1\;or.c %0,%2,%1"
  2845.   [(set_attr "type" "marith")])
  2846.  
  2847. (define_insn "iordi3"
  2848.   [(set (match_operand:DI 0 "register_operand" "=r")
  2849.     (ior:DI (match_operand:DI 1 "arith64_operand" "%r")
  2850.         (match_operand:DI 2 "arith64_operand" "rn")))]
  2851.   ""
  2852.   "*
  2853. {
  2854.   rtx xoperands[10];
  2855.  
  2856.   xoperands[0] = operand_subword (operands[0], 1, 0, DImode);
  2857.   xoperands[1] = operand_subword (operands[1], 1, 0, DImode);
  2858.   xoperands[2] = operand_subword (operands[2], 1, 0, DImode);
  2859.  
  2860.   output_asm_insn (output_ior (xoperands), xoperands);
  2861.  
  2862.   operands[0] = operand_subword (operands[0], 0, 0, DImode);
  2863.   operands[1] = operand_subword (operands[1], 0, 0, DImode);
  2864.   operands[2] = operand_subword (operands[2], 0, 0, DImode);
  2865.  
  2866.   return output_ior (operands);
  2867. }"
  2868.   [(set_attr "type" "marith")
  2869.    (set_attr "length" "4")]) ; length is 2, 3, or 4.
  2870.  
  2871. ;;- xor instructions (with complement also)
  2872. (define_insn ""
  2873.   [(set (match_operand:SI 0 "register_operand" "=r")
  2874.     (not:SI (xor:SI (match_operand:SI 1 "register_operand" "%r")
  2875.             (match_operand:SI 2 "register_operand" "r"))))]
  2876.   ""
  2877.   "xor.c %0,%1,%2")
  2878.  
  2879. (define_expand "xorsi3"
  2880.   [(set (match_operand:SI 0 "register_operand" "")
  2881.     (xor:SI (match_operand:SI 1 "arith32_operand" "")
  2882.         (match_operand:SI 2 "arith32_operand" "")))]
  2883.   ""
  2884.   "
  2885. {
  2886.   if (GET_CODE (operands[2]) == CONST_INT)
  2887.     {
  2888.       int value = INTVAL (operands[2]);
  2889.  
  2890.       if (! (SMALL_INTVAL (value)
  2891.          || (value & 0xffff) == 0))
  2892.     {
  2893.       emit_insn (gen_xorsi3 (operands[0], operands[1],
  2894.                  gen_rtx (CONST_INT, VOIDmode,
  2895.                       value & 0xffff0000)));
  2896.       operands[1] = operands[0];
  2897.       operands[2] = gen_rtx (CONST_INT, VOIDmode, value & 0xffff);
  2898.     }
  2899.     }
  2900. }")
  2901.  
  2902. (define_insn ""
  2903.   [(set (match_operand:SI 0 "register_operand" "=r,r,r")
  2904.     (xor:SI (match_operand:SI 1 "arith32_operand" "%r,r,r")
  2905.         (match_operand:SI 2 "arith32_operand" "rI,L,n")))]
  2906.   ""
  2907.   "@
  2908.    xor %0,%1,%2
  2909.    xor.u %0,%1,%X2
  2910.    xor.u %0,%1,%X2\;xor %0,%0,%x2"
  2911.   [(set_attr "type" "arith,arith,marith")])
  2912.  
  2913. (define_insn ""
  2914.   [(set (match_operand:DI 0 "register_operand" "=r")
  2915.     (not:DI (xor:DI (match_operand:DI 1 "register_operand" "r")
  2916.             (match_operand:DI 2 "register_operand" "r"))))]
  2917.   ""
  2918.   "xor.c %d0,%d1,%d2\;xor.c %0,%1,%2"
  2919.   [(set_attr "type" "marith")])
  2920.  
  2921. (define_insn "xordi3"
  2922.   [(set (match_operand:DI 0 "register_operand" "=r")
  2923.     (xor:DI (match_operand:DI 1 "arith64_operand" "%r")
  2924.         (match_operand:DI 2 "arith64_operand" "rn")))]
  2925.   ""
  2926.   "*
  2927. {
  2928.   rtx xoperands[10];
  2929.  
  2930.   xoperands[0] = operand_subword (operands[0], 1, 0, DImode);
  2931.   xoperands[1] = operand_subword (operands[1], 1, 0, DImode);
  2932.   xoperands[2] = operand_subword (operands[2], 1, 0, DImode);
  2933.  
  2934.   output_asm_insn (output_xor (xoperands), xoperands);
  2935.  
  2936.   operands[0] = operand_subword (operands[0], 0, 0, DImode);
  2937.   operands[1] = operand_subword (operands[1], 0, 0, DImode);
  2938.   operands[2] = operand_subword (operands[2], 0, 0, DImode);
  2939.  
  2940.   return output_xor (operands);
  2941. }"
  2942.   [(set_attr "type" "marith")
  2943.    (set_attr "length" "4")]) ; length is 2, 3, or 4.
  2944.  
  2945. ;;- ones complement instructions
  2946. (define_insn "one_cmplsi2"
  2947.   [(set (match_operand:SI 0 "register_operand" "=r")
  2948.     (not:SI (match_operand:SI 1 "register_operand" "r")))]
  2949.   ""
  2950.   "xor.c %0,%1,%#r0")
  2951.  
  2952. (define_insn "one_cmpldi2"
  2953.   [(set (match_operand:DI 0 "register_operand" "=r")
  2954.     (not:DI (match_operand:DI 1 "register_operand" "r")))]
  2955.   ""
  2956.   "xor.c %d0,%d1,%#r0\;xor.c %0,%1,%#r0"
  2957.   [(set_attr "type" "marith")])
  2958.  
  2959. ;; Optimized special cases of shifting.
  2960. ;; Must precede the general case.
  2961.  
  2962. ;; @@ What about HImode shifted by 8?
  2963.  
  2964. (define_insn ""
  2965.   [(set (match_operand:SI 0 "register_operand" "=r")
  2966.     (ashiftrt:SI (match_operand:SI 1 "memory_operand" "m")
  2967.              (const_int 24)))]
  2968.   "! SCALED_ADDRESS_P (XEXP (operands[1], 0))"
  2969.   "%V1ld.b %0,%1"
  2970.   [(set_attr "type" "load")])
  2971.  
  2972. (define_insn ""
  2973.   [(set (match_operand:SI 0 "register_operand" "=r")
  2974.     (lshiftrt:SI (match_operand:SI 1 "memory_operand" "m")
  2975.              (const_int 24)))]
  2976.   "! SCALED_ADDRESS_P (XEXP (operands[1], 0))"
  2977.   "%V1ld.bu %0,%1"
  2978.   [(set_attr "type" "load")])
  2979.  
  2980. (define_insn ""
  2981.   [(set (match_operand:SI 0 "register_operand" "=r")
  2982.     (ashiftrt:SI (match_operand:SI 1 "memory_operand" "m")
  2983.              (const_int 16)))]
  2984.   "! SCALED_ADDRESS_P (XEXP (operands[1], 0))"
  2985.   "%V1ld.h %0,%1"
  2986.   [(set_attr "type" "load")])
  2987.  
  2988. (define_insn ""
  2989.   [(set (match_operand:SI 0 "register_operand" "=r")
  2990.     (lshiftrt:SI (match_operand:SI 1 "memory_operand" "m")
  2991.              (const_int 16)))]
  2992.   "! SCALED_ADDRESS_P (XEXP (operands[1], 0))"
  2993.   "%V1ld.hu %0,%1"
  2994.   [(set_attr "type" "load")])
  2995.  
  2996. ;;- arithmetic shift instructions.
  2997.  
  2998. ;; @@ Do the optimized patterns with -1 get used?  Perhaps operand 1 should
  2999. ;; be arith32_operand?
  3000.  
  3001. ;; Use tbnd to support TARGET_TRAP_LARGE_SHIFT.
  3002. (define_insn "tbnd"
  3003.   [(trap_if (gtu (match_operand:SI 0 "register_operand" "r")
  3004.          (match_operand:SI 1 "arith_operand" "rI"))
  3005.         7)]
  3006.   ""
  3007.   "tbnd %r0,%1"
  3008.   [(set_attr "type" "weird")])
  3009.  
  3010. ;; Just in case the optimizer decides to fold away the test.
  3011. (define_insn ""
  3012.   [(trap_if (const_int 1) 7)]
  3013.   ""
  3014.   "tbnd %#r31,0"
  3015.   [(set_attr "type" "weird")])
  3016.  
  3017. (define_expand "ashlsi3"
  3018.   [(set (match_operand:SI 0 "register_operand" "")
  3019.     (ashift:SI (match_operand:SI 1 "register_operand" "")
  3020.            (match_operand:SI 2 "arith32_operand" "")))]
  3021.   ""
  3022.   "
  3023. {
  3024.   if (GET_CODE (operands[2]) == CONST_INT)
  3025.     {
  3026.       if ((unsigned) INTVAL (operands[2]) > 31)
  3027.     {
  3028.       if (TARGET_TRAP_LARGE_SHIFT)
  3029.         emit_insn (gen_tbnd (force_reg (SImode, operands[2]),
  3030.                  gen_rtx (CONST_INT, VOIDmode, 31)));
  3031.       else
  3032.         emit_move_insn (operands[0], const0_rtx);
  3033.       DONE;
  3034.     }
  3035.     }
  3036.  
  3037.   else if (TARGET_TRAP_LARGE_SHIFT)
  3038.     emit_insn (gen_tbnd (operands[2], gen_rtx (CONST_INT, VOIDmode, 31)));
  3039.  
  3040.   else if (TARGET_HANDLE_LARGE_SHIFT)
  3041.     {
  3042.       rtx reg = gen_reg_rtx (SImode);
  3043.       emit_insn (gen_cmpsi (operands[2], gen_rtx (CONST_INT, VOIDmode, 31)));
  3044.       emit_insn (gen_sleu (reg));
  3045.       emit_insn (gen_andsi3 (reg, operands[1], reg));
  3046.       operands[1] = reg;
  3047.     }
  3048. }")
  3049.  
  3050. (define_insn ""
  3051.   [(set (match_operand:SI 0 "register_operand" "=r,r")
  3052.     (ashift:SI (match_operand:SI 1 "register_operand" "r,r")
  3053.            (match_operand:SI 2 "arith5_operand" "r,n")))]
  3054.   ""
  3055.   "@
  3056.    mak %0,%1,%2
  3057.    mak %0,%1,0<%2>"
  3058.   [(set_attr "type" "bit")])
  3059.  
  3060. (define_expand "ashrsi3"
  3061.   [(set (match_operand:SI 0 "register_operand" "")
  3062.     (ashiftrt:SI (match_operand:SI 1 "register_operand" "")
  3063.              (match_operand:SI 2 "arith32_operand" "")))]
  3064.   ""
  3065.   "
  3066. {
  3067.   if (GET_CODE (operands[2]) == CONST_INT)
  3068.     {
  3069.       if ((unsigned) INTVAL (operands[2]) > 31)
  3070.     {
  3071.       if (TARGET_TRAP_LARGE_SHIFT)
  3072.         {
  3073.           emit_insn (gen_tbnd (force_reg (SImode, operands[2]),
  3074.                    gen_rtx (CONST_INT, VOIDmode, 31)));
  3075.           DONE;
  3076.         }
  3077.       else
  3078.         operands[2] = gen_rtx (CONST_INT, VOIDmode, 31);
  3079.     }
  3080.     }
  3081.  
  3082.   else if (TARGET_TRAP_LARGE_SHIFT)
  3083.     emit_insn (gen_tbnd (operands[2], gen_rtx (CONST_INT, VOIDmode, 31)));
  3084.  
  3085.   else if (TARGET_HANDLE_LARGE_SHIFT)
  3086.     {
  3087.       rtx reg = gen_reg_rtx (SImode);
  3088.       emit_insn (gen_cmpsi (operands[2], gen_rtx (CONST_INT, VOIDmode, 31)));
  3089.       emit_insn (gen_sgtu (reg));
  3090.       emit_insn (gen_iorsi3 (reg, operands[2], reg));
  3091.       operands[2] = reg;
  3092.     }
  3093. }")
  3094.  
  3095. (define_insn ""
  3096.   [(set (match_operand:SI 0 "register_operand" "=r,r")
  3097.     (ashiftrt:SI (match_operand:SI 1 "register_operand" "r,r")
  3098.              (match_operand:SI 2 "arith5_operand" "r,n")))]
  3099.   ""
  3100.   "@
  3101.    ext %0,%1,%2
  3102.    ext %0,%1,0<%2>"
  3103.   [(set_attr "type" "bit")])
  3104.  
  3105. ;;- logical shift instructions.  Logical shift left becomes arithmetic
  3106. ;; shift left.  LSHIFT is not normally produced, but is supported.
  3107.  
  3108. (define_expand "lshlsi3"
  3109.   [(set (match_operand:SI 0 "register_operand" "")
  3110.     (lshift:SI (match_operand:SI 1 "register_operand" "")
  3111.            (match_operand:SI 2 "arith32_operand" "")))]
  3112.   ""
  3113.   "
  3114. {
  3115.   emit_insn (gen_ashlsi3 (operands[0], operands[1], operands[2]));
  3116.   DONE;
  3117. }")
  3118.  
  3119. (define_insn ""
  3120.   [(set (match_operand:SI 0 "register_operand" "=r,r")
  3121.     (lshift:SI (match_operand:SI 1 "register_operand" "r,r")
  3122.            (match_operand:SI 2 "arith5_operand" "r,n")))]
  3123.   ""
  3124.   "@
  3125.    mak %0,%1,%2
  3126.    mak %0,%1,0<%2>"
  3127.   [(set_attr "type" "bit")])
  3128.  
  3129. (define_expand "lshrsi3"
  3130.   [(set (match_operand:SI 0 "register_operand" "")
  3131.     (lshiftrt:SI (match_operand:SI 1 "register_operand" "")
  3132.              (match_operand:SI 2 "arith32_operand" "")))]
  3133.   ""
  3134.   "
  3135. {
  3136.   if (GET_CODE (operands[2]) == CONST_INT)
  3137.     {
  3138.       if ((unsigned) INTVAL (operands[2]) > 31)
  3139.     {
  3140.       if (TARGET_TRAP_LARGE_SHIFT)
  3141.         emit_insn (gen_tbnd (force_reg (SImode, operands[2]),
  3142.                  gen_rtx (CONST_INT, VOIDmode, 31)));
  3143.       else
  3144.         emit_move_insn (operands[0], const0_rtx);
  3145.       DONE;
  3146.     }
  3147.     }
  3148.  
  3149.   else if (TARGET_TRAP_LARGE_SHIFT)
  3150.     emit_insn (gen_tbnd (operands[2], gen_rtx (CONST_INT, VOIDmode, 31)));
  3151.  
  3152.   else if (TARGET_HANDLE_LARGE_SHIFT)
  3153.     {
  3154.       rtx reg = gen_reg_rtx (SImode);
  3155.       emit_insn (gen_cmpsi (operands[2], gen_rtx (CONST_INT, VOIDmode, 31)));
  3156.       emit_insn (gen_sleu (reg));
  3157.       emit_insn (gen_andsi3 (reg, operands[1], reg));
  3158.       operands[1] = reg;
  3159.     }
  3160. }")
  3161.  
  3162. (define_insn ""
  3163.   [(set (match_operand:SI 0 "register_operand" "=r,r")
  3164.     (lshiftrt:SI (match_operand:SI 1 "register_operand" "r,r")
  3165.              (match_operand:SI 2 "arith5_operand" "r,n")))]
  3166.   ""
  3167.   "@
  3168.    extu %0,%1,%2
  3169.    extu %0,%1,0<%2>"
  3170.   [(set_attr "type" "bit")])
  3171.  
  3172. ;;- rotate instructions
  3173.  
  3174. (define_expand "rotlsi3"
  3175.   [(set (match_operand:SI 0 "register_operand" "")
  3176.     (rotatert:SI (match_operand:SI 1 "register_operand" "")
  3177.              (match_operand:SI 2 "arith32_operand" "")))]
  3178.   ""
  3179.   "
  3180. {
  3181.   if (GET_CODE (operands[2]) == CONST_INT
  3182.       && (unsigned) INTVAL (operands[2]) >= 32)
  3183.     operands[2] = gen_rtx (CONST_INT, VOIDmode,
  3184.                (32 - INTVAL (operands[2])) % 32);
  3185.   else
  3186.     {
  3187.       rtx op = gen_reg_rtx (SImode);
  3188.       emit_insn (gen_negsi2 (op, operands[2]));
  3189.       operands[2] = op;
  3190.     }
  3191. }")
  3192.  
  3193. (define_insn "rotrsi3"
  3194.   [(set (match_operand:SI 0 "register_operand" "=r")
  3195.     (rotatert:SI (match_operand:SI 1 "register_operand" "r")
  3196.              (match_operand:SI 2 "arith_operand" "rI")))]
  3197.   ""
  3198.   "rot %0,%1,%2"
  3199.   [(set_attr "type" "bit")])
  3200.  
  3201. ;; find first set.
  3202.  
  3203. ;; The ff1 instruction searches from the most significant bit while ffs
  3204. ;; searches from the least significant bit.  The bit index and treatment of
  3205. ;; zero also differ.  This amazing sequence was discovered using the GNU
  3206. ;; Superoptimizer.
  3207.  
  3208. (define_insn "ffssi2"
  3209.   [(set (match_operand:SI 0 "register_operand" "=r,&r")
  3210.     (ffs:SI (match_operand:SI 1 "register_operand" "0,r")))
  3211.    (clobber (reg:CC 0))
  3212.    (clobber (match_scratch:SI 2 "=r,X"))]
  3213.   ""
  3214.   "@
  3215.    subu.co %2,%#r0,%1\;and %2,%2,%1\;addu.ci %2,%2,%2\;ff1 %0,%2
  3216.    subu.co %0,%#r0,%1\;and %0,%0,%1\;addu.ci %0,%0,%0\;ff1 %0,%0"
  3217.   [(set_attr "type" "marith")
  3218.    (set_attr "length" "4")])
  3219.  
  3220. ;; Bit field instructions.
  3221.  
  3222. (define_insn ""
  3223.   [(set (match_operand:SI 0 "register_operand" "=r")
  3224.     (sign_extract:SI (match_operand:SI 1 "register_operand" "r")
  3225.              (const_int 32)
  3226.              (const_int 0)))]
  3227.   ""
  3228.   "or %0,%#r0,%1")
  3229.  
  3230. (define_insn "extv"
  3231.   [(set (match_operand:SI 0 "register_operand" "=r")
  3232.     (sign_extract:SI (match_operand:SI 1 "register_operand" "r")
  3233.              (match_operand:SI 2 "int5_operand" "")
  3234.              (match_operand:SI 3 "int5_operand" "")))]
  3235.   ""
  3236.   "*
  3237. {
  3238.   operands[4] = gen_rtx (CONST_INT, SImode,
  3239.              (32 - INTVAL (operands[2])) - INTVAL (operands[3]));
  3240.   return \"ext %0,%1,%2<%4>\";  /* <(32-%2-%3)> */
  3241. }"
  3242.   [(set_attr "type" "bit")])
  3243.  
  3244. (define_insn ""
  3245.   [(set (match_operand:SI 0 "register_operand" "=r")
  3246.     (zero_extract:SI (match_operand:SI 1 "register_operand" "r")
  3247.              (const_int 32)
  3248.              (const_int 0)))]
  3249.   ""
  3250.   "or %0,%#r0,%1")
  3251.  
  3252. (define_insn "extzv"
  3253.   [(set (match_operand:SI 0 "register_operand" "=r")
  3254.     (zero_extract:SI (match_operand:SI 1 "register_operand" "r")
  3255.              (match_operand:SI 2 "int5_operand" "")
  3256.              (match_operand:SI 3 "int5_operand" "")))]
  3257.   ""
  3258.   "*
  3259. {
  3260.   operands[4] = gen_rtx (CONST_INT, SImode,
  3261.              (32 - INTVAL (operands[2])) - INTVAL (operands[3]));
  3262.   return \"extu %0,%1,%2<%4>\";  /* <(32-%2-%3)> */
  3263. }"
  3264.   [(set_attr "type" "bit")])
  3265.  
  3266. (define_insn ""
  3267.   [(set (zero_extract:SI (match_operand:SI 0 "register_operand" "+r")
  3268.              (match_operand:SI 1 "int5_operand" "")
  3269.              (match_operand:SI 2 "int5_operand" ""))
  3270.     (const_int 0))]
  3271.   ""
  3272.   "*
  3273. {
  3274.   operands[3] = gen_rtx (CONST_INT, SImode,
  3275.              (32 - INTVAL (operands[1])) - INTVAL (operands[2]));
  3276.   return \"clr %0,%0,%1<%3>\";  /* <(32-%1-%2)> */
  3277. }"
  3278.   [(set_attr "type" "bit")])
  3279.  
  3280. (define_insn ""
  3281.   [(set (zero_extract:SI (match_operand:SI 0 "register_operand" "+r")
  3282.              (match_operand:SI 1 "int5_operand" "")
  3283.              (match_operand:SI 2 "int5_operand" ""))
  3284.     (const_int -1))]
  3285.   ""
  3286.   "*
  3287. {
  3288.   operands[3] = gen_rtx (CONST_INT, SImode,
  3289.              (32 - INTVAL (operands[1])) - INTVAL (operands[2]));
  3290.   return \"set %0,%0,%1<%3>\";  /* <(32-%1-%2)> */
  3291. }"
  3292.   [(set_attr "type" "bit")])
  3293.  
  3294. (define_insn ""
  3295.   [(set (zero_extract:SI (match_operand:SI 0 "register_operand" "+r")
  3296.              (match_operand:SI 1 "int5_operand" "")
  3297.              (match_operand:SI 2 "int5_operand" ""))
  3298.     (match_operand:SI 3 "int32_operand" "n"))]
  3299.   ""
  3300.   "*
  3301. {
  3302.   int value = INTVAL (operands[3]);
  3303.  
  3304.   if (INTVAL (operands[1]) < 32)
  3305.     value &= (1 << INTVAL (operands[1])) - 1;
  3306.  
  3307.   operands[2] = gen_rtx (CONST_INT, VOIDmode,
  3308.              32 - (INTVAL(operands[1]) + INTVAL(operands[2])));
  3309.  
  3310.   value <<= INTVAL (operands[2]);
  3311.   operands[3] = gen_rtx (CONST_INT, VOIDmode, value);
  3312.  
  3313.   if (SMALL_INTVAL (value))
  3314.     return \"clr %0,%0,%1<%2>\;or %0,%0,%3\";
  3315.   else if ((value & 0x0000ffff) == 0)
  3316.     return \"clr %0,%0,%1<%2>\;or.u %0,%0,%X3\";
  3317.   else
  3318.     return \"clr %0,%0,%1<%2>\;or.u %0,%0,%X3\;or %0,%0,%x3\";
  3319. }"
  3320.   [(set_attr "type" "marith")
  3321.    (set_attr "length" "3")]) ; may be 2 or 3.
  3322.  
  3323. ;; negate insns
  3324. (define_insn "negsi2"
  3325.   [(set (match_operand:SI 0 "register_operand" "=r")
  3326.     (neg:SI (match_operand:SI 1 "arith_operand" "rI")))]
  3327.   ""
  3328.   "subu %0,%#r0,%1")
  3329.  
  3330. (define_insn ""
  3331.   [(set (match_operand:SF 0 "register_operand" "=r,x")
  3332.     (float_truncate:SF (neg:DF (match_operand:DF 1 "register_operand" "r,x"))))]
  3333.   ""
  3334.   "@
  3335.    fsub.ssd %0,%#r0,%1
  3336.    fsub.ssd %0,%#x0,%1"
  3337.   [(set_attr "type" "dpadd")])
  3338.  
  3339. (define_insn "negdf2"
  3340.   [(set (match_operand:DF 0 "register_operand" "=&r,r")
  3341.     (neg:DF (match_operand:DF 1 "register_operand" "r,0")))]
  3342.   ""
  3343.   "@
  3344.    xor.u %0,%1,0x8000\;or %d0,%#r0,%d1
  3345.    xor.u %0,%0,0x8000"
  3346.   [(set_attr "type" "marith,arith")])
  3347.  
  3348. (define_insn "negsf2"
  3349.   [(set (match_operand:SF 0 "register_operand" "=r")
  3350.     (neg:SF (match_operand:SF 1 "register_operand" "r")))]
  3351.   ""
  3352.   "xor.u %0,%1,0x8000")
  3353.  
  3354. ;; absolute value insns for floating-point (integer abs can be done using the
  3355. ;; machine-independent sequence).
  3356.  
  3357. (define_insn "absdf2"
  3358.   [(set (match_operand:DF 0 "register_operand" "=&r,r")
  3359.     (abs:DF (match_operand:DF 1 "register_operand" "r,0")))]
  3360.   ""
  3361.   "@
  3362.    and.u %0,%1,0x7fff\;or %d0,%#r0,%d1
  3363.    and.u %0,%0,0x7fff"
  3364.   [(set_attr "type" "marith,arith")])
  3365.  
  3366. (define_insn "abssf2"
  3367.   [(set (match_operand:SF 0 "register_operand" "=r")
  3368.     (abs:SF (match_operand:SF 1 "register_operand" "r")))]
  3369.   ""
  3370.   "and.u %0,%1,0x7fff")
  3371.  
  3372. ;; Subroutines of "casesi".
  3373.  
  3374. ;; Operand 0 is index
  3375. ;; operand 1 is the minimum bound
  3376. ;; operand 2 is the maximum bound - minimum bound + 1
  3377. ;; operand 3 is CODE_LABEL for the table;
  3378. ;; operand 4 is the CODE_LABEL to go to if index out of range.
  3379.  
  3380. (define_expand "casesi"
  3381.   ;; We don't use these for generating the RTL, but we must describe
  3382.   ;; the operands here.
  3383.   [(match_operand:SI 0 "general_operand" "")
  3384.    (match_operand:SI 1 "immediate_operand" "")
  3385.    (match_operand:SI 2 "immediate_operand" "")
  3386.    (match_operand 3 "" "")
  3387.    (match_operand 4 "" "")]
  3388.   ""
  3389.   "
  3390. {
  3391.   register rtx index_diff = gen_reg_rtx (SImode);
  3392.   register rtx low = gen_rtx (CONST_INT, VOIDmode, -INTVAL (operands[1]));
  3393.   register rtx label = gen_rtx (LABEL_REF, VOIDmode, operands[3]);
  3394.   register rtx base;
  3395.  
  3396.   if (! CASE_VECTOR_INSNS)
  3397.     /* These instructions are likely to be scheduled and made loop invariant.
  3398.        This decreases the cost of the dispatch at the expense of the default
  3399.        case.  */
  3400.     base = force_reg (SImode, memory_address_noforce (SImode, label));
  3401.  
  3402.   /* Compute the index difference and handle the default case.  */
  3403.   emit_insn (gen_addsi3 (index_diff,
  3404.              force_reg (SImode, operands[0]),
  3405.              ADD_INT (low) ? low : force_reg (SImode, low)));
  3406.   emit_insn (gen_cmpsi (index_diff, operands[2]));
  3407.   /* It's possible to replace this branch with sgtu/iorsi3 and adding a -1
  3408.      entry to the table.  However, that doesn't seem to win on the m88110.  */
  3409.   emit_jump_insn (gen_bgtu (operands[4]));
  3410.  
  3411.   if (CASE_VECTOR_INSNS)
  3412.     /* Call the jump that will branch to the appropriate case.  */
  3413.     emit_jump_insn (gen_casesi_enter (label, index_diff, operands[3]));
  3414.   else
  3415.     /* Load the table entry and jump to it.  */
  3416.     emit_jump_insn (gen_casesi_jump (gen_reg_rtx (SImode), base, index_diff));
  3417.  
  3418.   /* Claim that flow drops into the table so it will be adjacent by not
  3419.      emitting a barrier.  */
  3420.   DONE;
  3421. }")
  3422.  
  3423. (define_expand "casesi_jump"
  3424.   [(set (match_operand:SI 0 "" "")
  3425.     (mem:SI (plus:SI (match_operand:SI 1 "" "")
  3426.              (mult:SI (match_operand:SI 2 "" "")
  3427.                   (const_int 4)))))
  3428.    (set (pc) (match_dup 0))]
  3429.   ""
  3430.   "")
  3431.  
  3432. ;; The bsr.n instruction is directed to the END of the table.  See
  3433. ;; ASM_OUTPUT_CASE_END.
  3434.  
  3435. (define_insn "casesi_enter"
  3436.   [(set (pc) (match_operand 0 "" ""))
  3437.    (use (match_operand:SI 1 "register_operand" "r"))
  3438.    ;; The USE here is so that at least one jump-insn will refer to the label,
  3439.    ;; to keep it alive in jump_optimize.
  3440.    (use (label_ref (match_operand 2 "" "")))
  3441.    (clobber (reg:SI 1))]
  3442.   ""
  3443.   "*
  3444. {
  3445.   if (flag_delayed_branch)
  3446.     return \"bsr.n %0e\;lda %#r1,%#r1[%1]\";
  3447.   m88k_case_index = REGNO (operands[1]);
  3448.   return \"bsr %0e\";
  3449. }"
  3450.   [(set_attr "type" "weird")
  3451.    (set_attr "length" "3")]) ; Including the "jmp r1".
  3452.  
  3453. ;;- jump to subroutine
  3454. (define_expand "call"
  3455.   [(parallel [(call (match_operand:SI 0 "" "")
  3456.             (match_operand 1 "" ""))
  3457.           (clobber (reg:SI 1))])]
  3458.   ""
  3459.   "
  3460. {
  3461.   if (GET_CODE (operands[0]) == MEM
  3462.       && ! call_address_operand (XEXP (operands[0], 0), SImode))
  3463.     operands[0] = gen_rtx (MEM, GET_MODE (operands[0]),
  3464.                force_reg (Pmode, XEXP (operands[0], 0)));
  3465. }")
  3466.  
  3467. (define_insn ""
  3468.   [(parallel [(call (mem:SI (match_operand:SI 0 "call_address_operand" "rQ"))
  3469.             (match_operand 1 "" ""))
  3470.           (clobber (reg:SI 1))])]
  3471.   ""
  3472.   "* return output_call (operands, operands[0]);"
  3473.   [(set_attr "type" "call")])
  3474.  
  3475. (define_expand "call_value"
  3476.   [(parallel [(set (match_operand 0 "register_operand" "")
  3477.            (call (match_operand:SI 1 "" "")
  3478.              (match_operand 2 "" "")))
  3479.           (clobber (reg:SI 1))])]
  3480.   ""
  3481.   "
  3482. {
  3483.   if (GET_CODE (operands[1]) == MEM
  3484.       && ! call_address_operand (XEXP (operands[1], 0), SImode))
  3485.     operands[1] = gen_rtx (MEM, GET_MODE (operands[1]),
  3486.                force_reg (Pmode, XEXP (operands[1], 0)));
  3487. }")
  3488.  
  3489. (define_insn ""
  3490.   [(parallel [(set (match_operand 0 "register_operand" "=r")
  3491.            (call (mem:SI
  3492.               (match_operand:SI 1 "call_address_operand" "rQ"))
  3493.              (match_operand 2 "" "")))
  3494.           (clobber (reg:SI 1))])]
  3495.   ""
  3496.   "* return output_call (operands, operands[1]);"
  3497.   [(set_attr "type" "call")])
  3498.  
  3499. ;; Nop instruction and others
  3500.  
  3501. (define_insn "nop"
  3502.   [(const_int 0)]
  3503.   ""
  3504.   "ff0 %#r0,%#r0"
  3505.   [(set_attr "type" "bit")])
  3506.  
  3507. (define_insn "return"
  3508.   [(return)]
  3509.   "reload_completed"
  3510.   "jmp%. %#r1"
  3511.   [(set_attr "type" "jump")])
  3512.  
  3513. (define_expand "prologue"
  3514.   [(const_int 0)]
  3515.   ""
  3516.   "m88k_expand_prologue (); DONE;")
  3517.  
  3518. (define_expand "epilogue"
  3519.   [(return)]
  3520.   "! null_prologue ()"
  3521.   "m88k_expand_epilogue ();")
  3522.  
  3523. (define_insn "blockage"
  3524.   [(unspec_volatile [(const_int 0)] 0)]
  3525.   ""
  3526.   ""
  3527.   [(set_attr "length" "0")])
  3528.  
  3529. (define_insn "indirect_jump"
  3530.   [(set (pc) (match_operand:SI 0 "register_operand" "r"))]
  3531.   ""
  3532.   "jmp%. %0"
  3533.   [(set_attr "type" "jump")])
  3534.  
  3535. (define_insn "jump"
  3536.   [(set (pc)
  3537.     (label_ref (match_operand 0 "" "")))]
  3538.   ""
  3539.   "br%. %l0"
  3540.   [(set_attr "type" "jump")])
  3541.  
  3542. ;; This insn is used for some loop tests, typically loops reversed when
  3543. ;; strength reduction is used.  It is actually created when the instruction
  3544. ;; combination phase combines the special loop test.  Since this insn
  3545. ;; is both a jump insn and has an output, it must deal with it's own
  3546. ;; reloads, hence the `m' constraints.  The `!' constraints direct reload
  3547. ;; to not choose the register alternatives in the event a reload is needed.
  3548.  
  3549. (define_insn "decrement_and_branch_until_zero"
  3550.   [(set (pc)
  3551.     (if_then_else
  3552.      (match_operator 0 "relop_no_unsigned"
  3553.              [(match_operand:SI 1 "register_operand" "+!r,!r,m,m")
  3554.               (const_int 0)])
  3555.       (label_ref (match_operand 2 "" ""))
  3556.       (pc)))
  3557.    (set (match_dup 1)
  3558.     (plus:SI (match_dup 1)
  3559.          (match_operand:SI 3 "add_operand" "rI,J,rI,J")))
  3560.    (clobber (match_scratch:SI 4 "=X,X,&r,&r"))
  3561.    (clobber (match_scratch:SI 5 "=X,X,&r,&r"))]
  3562.   "find_reg_note (insn, REG_NONNEG, 0)"
  3563.   "@
  3564.    bcnd.n %B0,%1,%2\;addu %1,%1,%3
  3565.    bcnd.n %B0,%1,%2\;subu %1,%1,%n3
  3566.    ld %4,%1\;addu %5,%4,%3\;bcnd.n %B0,%4,%2\;st %5,%1
  3567.    ld %4,%1\;subu %5,%4,%n3\;bcnd.n %B0,%4,%2\;st %5,%1"
  3568.   [(set_attr "type" "weird")
  3569.    (set_attr "length" "2,2,4,4")])
  3570.  
  3571. ;; Special insn to serve as the last insn of a define_expand.  This insn
  3572. ;; will generate no code.
  3573.  
  3574. (define_expand "dummy"
  3575.   [(set (match_operand 0 "" "") (match_dup 0))]
  3576.   ""
  3577.   "")
  3578.  
  3579. ;;- Local variables:
  3580. ;;- mode:emacs-lisp
  3581. ;;- comment-start: ";;- "
  3582. ;;- eval: (set-syntax-table (copy-sequence (syntax-table)))
  3583. ;;- eval: (modify-syntax-entry ?[ "(]")
  3584. ;;- eval: (modify-syntax-entry ?] ")[")
  3585. ;;- eval: (modify-syntax-entry ?{ "(}")
  3586. ;;- eval: (modify-syntax-entry ?} "){")
  3587. ;;- End:
  3588.