home *** CD-ROM | disk | FTP | other *** search
/ Education Sampler 1992 [NeXTSTEP] / Education_1992_Sampler.iso / NeXT / GnuSource / cc-61.0.1 / cc / config / sparc.md < prev    next >
Text File  |  1991-06-03  |  75KB  |  2,600 lines

  1. ;;- Machine description for SPARC chip for GNU C compiler
  2. ;;   Copyright (C) 1988-1990 Free Software Foundation, Inc.
  3. ;;   Contributed by Michael Tiemann (tiemann@cygnus.com)
  4.  
  5. ;; This file is part of GNU CC.
  6.  
  7. ;; GNU CC is free software; you can redistribute it and/or modify
  8. ;; it under the terms of the GNU General Public License as published by
  9. ;; the Free Software Foundation; either version 2, or (at your option)
  10. ;; any later version.
  11.  
  12. ;; GNU CC is distributed in the hope that it will be useful,
  13. ;; but WITHOUT ANY WARRANTY; without even the implied warranty of
  14. ;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
  15. ;; GNU General Public License for more details.
  16.  
  17. ;; You should have received a copy of the GNU General Public License
  18. ;; along with GNU CC; see the file COPYING.  If not, write to
  19. ;; the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA.
  20.  
  21.  
  22. ;;- See file "rtl.def" for documentation on define_insn, match_*, et. al.
  23.  
  24. ;; Insn type.  Used to default other attribute values.
  25.  
  26. ;; type "unary" insns have one input operand (1) and one output operand (0)
  27. ;; type "binary" insns have two input operands (1,2) and one output (0)
  28. ;; type "compare" insns have one or two input operands (0,1) and no output
  29.  
  30. (define_attr "type"
  31.   "move,unary,binary,compare,load,store,branch,call,address,fpload,fpstore,fp,fpcc,fpmul,fpdiv,fpsqrt,multi,misc"
  32.   (const_string "binary"))
  33.  
  34. ;; Set true if insn uses call-clobbered intermediate register.
  35. (define_attr "use_clobbered" "false,true"
  36.   (if_then_else (and (eq_attr "type" "address")
  37.              (match_operand 0 "clobbered_register" ""))
  38.          (const_string "true")
  39.         (const_string "false")))
  40.  
  41. ;; Length (in # of insns).
  42. (define_attr "length" ""
  43.   (cond [(eq_attr "type" "load,fpload")
  44.      (if_then_else (match_operand 1 "symbolic_memory_operand" "")
  45.                (const_int 2) (const_int 1))
  46.  
  47.      (eq_attr "type" "store,fpstore")
  48.      (if_then_else (match_operand 0 "symbolic_memory_operand" "")
  49.                (const_int 2) (const_int 1))
  50.  
  51.      (eq_attr "type" "address") (const_int 2)
  52.  
  53.      (eq_attr "type" "binary")
  54.      (if_then_else (match_operand 2 "arith_operand" "")
  55.                (const_int 1) (const_int 3))
  56.  
  57.      (eq_attr "type" "move,unary")
  58.      (if_then_else (match_operand 1 "arith_operand" "")
  59.                (const_int 1) (const_int 2))]
  60.  
  61.     (const_int 1)))
  62.  
  63. (define_asm_attributes
  64.   [(set_attr "length" "1")
  65.    (set_attr "type" "multi")])
  66.  
  67. ;; Attributes for instruction and branch scheduling
  68.  
  69. (define_attr "in_call_delay" "false,true"
  70.   (cond [(eq_attr "type" "branch,call,multi") (const_string "false")
  71.      (eq_attr "type" "load,fpload,store,fpstore")
  72.          (if_then_else (eq_attr "length" "1")
  73.                   (const_string "true")
  74.                   (const_string "false"))
  75.      (eq_attr "type" "address")
  76.          (if_then_else (eq_attr "use_clobbered" "false")
  77.                   (const_string "true")
  78.                   (const_string "false"))]
  79.     (if_then_else (eq_attr "length" "1")
  80.               (const_string "true")
  81.               (const_string "false"))))
  82.  
  83. (define_delay (eq_attr "type" "call")
  84.   [(eq_attr "in_call_delay" "true") (nil) (nil)])
  85.  
  86. (define_delay (eq_attr "type" "fpcc")
  87.   [(eq_attr "type" "!branch,fpload,fpstore,fp,fpmul,fpdiv,fpsqrt,fpcc")
  88.    (nil) (nil)])
  89.  
  90. (define_attr "in_branch_delay" "false,true"
  91.   (if_then_else (and (eq_attr "type" "!branch,call,multi")
  92.              (eq_attr "length" "1"))
  93.         (const_string "true")
  94.         (const_string "false")))
  95.  
  96. (define_delay (eq_attr "type" "branch")
  97.   [(eq_attr "in_branch_delay" "true")
  98.    (nil) (eq_attr "in_branch_delay" "true")])
  99.  
  100. ;; Function units of the SPARC
  101.  
  102. ;; (define_function_unit {name} {num-units} {n-users} {test}
  103. ;;                       {ready-delay} {busy-delay} [{conflict-list}])
  104.  
  105. ;; The integer ALU.
  106. ;; (Noted only for documentation; units that take one cycle do not need to
  107. ;; be specified.)
  108.  
  109. ;; (define_function_unit "alu" 1 0
  110. ;;  (eq_attr "type" "unary,binary,move,address") 1 0)
  111.  
  112. ;; Memory with load-delay of 1 (i.e., 2 cycle load).
  113. (define_function_unit "memory" 1 0 (eq_attr "type" "load,fpload") 2 0)
  114.  
  115. ;; SPARC has two floating-point units: the FP ALU,
  116. ;; and the FP MUL/DIV/SQRT unit.
  117. ;; Instruction timings on the CY7C602 are as follows
  118. ;; FABSs    4
  119. ;; FADDs/d    5/5
  120. ;; FCMPs/d    4/4
  121. ;; FDIVs/d    23/37
  122. ;; FMOVs    4
  123. ;; FMULs/d    5/7
  124. ;; FNEGs    4
  125. ;; FSQRTs/d    34/63
  126. ;; FSUBs/d    5/5
  127. ;; FdTOi/s    5/5
  128. ;; FsTOi/d    5/5
  129. ;; FiTOs/d    9/5
  130.  
  131. ;; The CY7C602 can only support 2 fp isnsn simultaneously.
  132. ;; More insns cause the chip to stall.  Until we handle this
  133. ;; better in the scheduler, we use excess cycle times to
  134. ;; more evenly spread out fp insns.
  135.  
  136. (define_function_unit "fp_alu" 1 2 (eq_attr "type" "fp") 8 0)
  137. (define_function_unit "fp_mul" 1 2 (eq_attr "type" "fpmul") 10 0)
  138. (define_function_unit "fp_div" 1 2 (eq_attr "type" "fpdiv") 23 0)
  139. (define_function_unit "fp_sqrt" 1 2 (eq_attr "type" "fpsqrt") 34 0)
  140.  
  141. ;; Compare instructions.
  142. ;; This controls RTL generation and register allocation.
  143.  
  144. ;; We generate RTL for comparisons and branches by having the cmpxx 
  145. ;; patterns store away the operands.  Then, the scc and bcc patterns
  146. ;; emit RTL for both the compare and the branch.
  147. ;;
  148. ;; We do this because we want to generate different code for an sne and
  149. ;; seq insn.  In those cases, if the second operand of the compare is not
  150. ;; const0_rtx, we want to compute the xor of the two operands and test
  151. ;; it against zero.
  152. ;;
  153. ;; We start with the DEFINE_EXPANDs, then then DEFINE_INSNs to match
  154. ;; the patterns.  Finally, we have the DEFINE_SPLITs for some of the scc
  155. ;; insns that actually require more than one machine instruction.
  156.  
  157. ;; Put cmpsi first among compare insns so it matches two CONST_INT operands.
  158.  
  159. (define_expand "cmpsi"
  160.   [(set (reg:CC 0)
  161.     (compare:CC (match_operand:SI 0 "register_operand" "")
  162.             (match_operand:SI 1 "arith_operand" "")))]
  163.   ""
  164.   "
  165. {
  166.   sparc_compare_op0 = operands[0];
  167.   sparc_compare_op1 = operands[1];
  168.   DONE;
  169. }")
  170.  
  171. (define_expand "cmpsf"
  172.   [(set (reg:CCFP 0)
  173.     (compare:CCFP (match_operand:SF 0 "register_operand" "")
  174.               (match_operand:SF 1 "register_operand" "")))]
  175.   ""
  176.   "
  177. {
  178.   sparc_compare_op0 = operands[0];
  179.   sparc_compare_op1 = operands[1];
  180.   DONE;
  181. }")
  182.  
  183. (define_expand "cmpdf"
  184.   [(set (reg:CCFP 0)
  185.       (compare:CCFP (match_operand:DF 0 "register_operand" "")
  186.                     (match_operand:DF 1 "register_operand" "")))]
  187.   ""
  188.   "
  189. {
  190.   sparc_compare_op0 = operands[0];
  191.   sparc_compare_op1 = operands[1];
  192.   DONE;
  193. }")
  194.  
  195. ;; Next come the scc insns.  For seq, sne, sgeu, and sltu, we can do this
  196. ;; without jumps using the addx/subx instructions.  For the rest, we do
  197. ;; branches.  Except for seq and sne, we really do not clobber the condition
  198. ;; code.  However, indicate that we do to allow combine to change from
  199. ;; one operation to another easily.  When SCRATCH is implemented, we will not
  200. ;; have to do this any more.
  201.  
  202. (define_expand "seq_special"
  203.   [(set (match_dup 3) (xor:SI (match_operand:SI 1 "register_operand" "")
  204.                   (match_operand:SI 2 "register_operand" "")))
  205.    (parallel [(set (match_operand:SI 0 "register_operand" "")
  206.            (eq:SI (match_dup 3) (const_int 0)))
  207.           (clobber (reg:CC 0))])]
  208.          
  209.   ""
  210.   "{ operands[3] = gen_reg_rtx (SImode); }")
  211.  
  212. (define_expand "sne_special"
  213.   [(set (match_dup 3) (xor:SI (match_operand:SI 1 "register_operand" "")
  214.                   (match_operand:SI 2 "register_operand" "")))
  215.    (parallel [(set (match_operand:SI 0 "register_operand" "")
  216.            (ne:SI (match_dup 3) (const_int 0)))
  217.           (clobber (reg:CC 0))])]
  218.   ""
  219.   "{ operands[3] = gen_reg_rtx (SImode); }")
  220.  
  221. (define_expand "seq"
  222.   [(parallel [(set (match_operand:SI 0 "register_operand" "")
  223.            (eq:SI (match_dup 1) (const_int 0)))
  224.           (clobber (reg:CC 0))])]
  225.   ""
  226.   "
  227. { if (GET_MODE (sparc_compare_op0) == SImode)
  228.     {
  229.       if (sparc_compare_op1 == const0_rtx)
  230.     operands[1] = sparc_compare_op0;
  231.       else
  232.     {
  233.       emit_insn (gen_seq_special (operands[0], sparc_compare_op0,
  234.                       sparc_compare_op1));
  235.       DONE;
  236.     }
  237.     }
  238.   else
  239.     operands[1] = gen_compare_reg (EQ, sparc_compare_op0, sparc_compare_op1);
  240. }")
  241.  
  242. (define_expand "sne"
  243.   [(parallel [(set (match_operand:SI 0 "register_operand" "")
  244.            (ne:SI (match_dup 1) (const_int 0)))
  245.           (clobber (reg:CC 0))])]
  246.   ""
  247.   "
  248. { if (GET_MODE (sparc_compare_op0) == SImode)
  249.     {
  250.       if (sparc_compare_op1 == const0_rtx)
  251.     operands[1] = sparc_compare_op0;
  252.       else
  253.     {
  254.       emit_insn (gen_sne_special (operands[0], sparc_compare_op0,
  255.                       sparc_compare_op1));
  256.       DONE;
  257.     }
  258.     }
  259.   else
  260.     operands[1] = gen_compare_reg (NE, sparc_compare_op0, sparc_compare_op1);
  261. }")
  262.  
  263. (define_expand "sgt"
  264.   [(parallel [(set (match_operand:SI 0 "register_operand" "")
  265.            (gt:SI (match_dup 1) (const_int 0)))
  266.           (clobber (reg:CC 0))])]
  267.   ""
  268.   "
  269. { operands[1] = gen_compare_reg (GT, sparc_compare_op0, sparc_compare_op1); }")
  270.  
  271. (define_expand "slt"
  272.   [(parallel [(set (match_operand:SI 0 "register_operand" "")
  273.            (lt:SI (match_dup 1) (const_int 0)))
  274.           (clobber (reg:CC 0))])]
  275.   ""
  276.   "
  277. { operands[1] = gen_compare_reg (LT, sparc_compare_op0, sparc_compare_op1); }")
  278.  
  279. (define_expand "sge"
  280.   [(parallel [(set (match_operand:SI 0 "register_operand" "")
  281.            (ge:SI (match_dup 1) (const_int 0)))
  282.           (clobber (reg:CC 0))])]
  283.   ""
  284.   "
  285. { operands[1] = gen_compare_reg (GE, sparc_compare_op0, sparc_compare_op1); }")
  286.  
  287. (define_expand "sle"
  288.   [(parallel [(set (match_operand:SI 0 "register_operand" "")
  289.            (le:SI (match_dup 1) (const_int 0)))
  290.           (clobber (reg:CC 0))])]
  291.   ""
  292.   "
  293. { operands[1] = gen_compare_reg (LE, sparc_compare_op0, sparc_compare_op1); }")
  294.  
  295. (define_expand "sgtu"
  296.   [(parallel [(set (match_operand:SI 0 "register_operand" "")
  297.            (gtu:SI (match_dup 1) (const_int 0)))
  298.           (clobber (reg:CC 0))])]
  299.   ""
  300.   "
  301. {
  302.   rtx tem;
  303.  
  304.   /* We can do ltu easily, so if both operands are registers, swap them and
  305.      do a LTU.  */
  306.   if (GET_CODE (sparc_compare_op0) == REG
  307.       && GET_CODE (sparc_compare_op1) == REG)
  308.     {
  309.       tem = sparc_compare_op0;
  310.       sparc_compare_op0 = sparc_compare_op1;
  311.       sparc_compare_op1 = tem;
  312.       emit_insn (gen_sltu (operands[0]));
  313.       DONE;
  314.     }
  315.  
  316.   operands[1] = gen_compare_reg (LEU, sparc_compare_op0, sparc_compare_op1);
  317. }")
  318.  
  319. (define_expand "sltu"
  320.   [(parallel [(set (match_operand:SI 0 "register_operand" "")
  321.            (ltu:SI (match_dup 1) (const_int 0)))
  322.           (clobber (reg:CC 0))])]
  323.   ""
  324.   "
  325. { operands[1] = gen_compare_reg (LTU, sparc_compare_op0, sparc_compare_op1);
  326. }")
  327.  
  328. (define_expand "sgeu"
  329.   [(parallel [(set (match_operand:SI 0 "register_operand" "")
  330.            (geu:SI (match_dup 1) (const_int 0)))
  331.           (clobber (reg:CC 0))])]
  332.   ""
  333.   "
  334. { operands[1] = gen_compare_reg (GEU, sparc_compare_op0, sparc_compare_op1);
  335. }")
  336.  
  337. (define_expand "sleu"
  338.   [(parallel [(set (match_operand:SI 0 "register_operand" "")
  339.            (leu:SI (match_dup 1) (const_int 0)))
  340.           (clobber (reg:CC 0))])]
  341.   ""
  342.   "
  343. {
  344.   rtx tem;
  345.  
  346.   /* We can do geu easily, so if both operands are registers, swap them and
  347.      do a GEU.  */
  348.   if (GET_CODE (sparc_compare_op0) == REG
  349.       && GET_CODE (sparc_compare_op1) == REG)
  350.     {
  351.       tem = sparc_compare_op0;
  352.       sparc_compare_op0 = sparc_compare_op1;
  353.       sparc_compare_op1 = tem;
  354.       emit_insn (gen_sgeu (operands[0]));
  355.       DONE;
  356.     }
  357.  
  358.   operands[1] = gen_compare_reg (LEU, sparc_compare_op0, sparc_compare_op1);
  359. }")
  360.  
  361. ;; Now the DEFINE_INSNs for the compare and scc cases.  First the compares.
  362.  
  363. (define_insn ""
  364.   [(set (reg:CC 0)
  365.     (compare:CC (match_operand:SI 0 "reg_or_0_operand" "rJ")
  366.             (match_operand:SI 1 "arith_operand" "rI")))]
  367.   ""
  368.   "cmp %r0,%1"
  369.   [(set_attr "type" "compare")])
  370.  
  371. (define_insn ""
  372.   [(set (reg:CCFP 0)
  373.     (compare:CCFP (match_operand:DF 0 "register_operand" "f")
  374.               (match_operand:DF 1 "register_operand" "f")))]
  375.   ""
  376.   "fcmped %0,%1%#"
  377.   [(set_attr "type" "fpcc")])
  378.  
  379. (define_insn ""
  380.   [(set (reg:CCFP 0)
  381.     (compare:CCFP (match_operand:SF 0 "nonmemory_operand" "f")
  382.               (match_operand:SF 1 "nonmemory_operand" "f")))]
  383.   ""
  384.   "fcmpes %0,%1%#"
  385.   [(set_attr "type" "fpcc")])
  386.  
  387. ;; The SEQ and SNE patterns are special because they can be done
  388. ;; without any branching and do not involve a COMPARE.
  389.  
  390. (define_insn ""
  391.   [(set (match_operand:SI 0 "register_operand" "=r")
  392.     (ne:SI (match_operand:SI 1 "register_operand" "r") (const_int 0)))
  393.    (clobber (reg:CC 0))]
  394.   ""
  395.   "subcc %%g0,%1,%%g0\;addx %%g0,0,%0"
  396.   [(set_attr "type" "unary")
  397.    (set_attr "length" "2")])
  398.  
  399. (define_insn ""
  400.   [(set (match_operand:SI 0 "register_operand" "=r")
  401.     (neg:SI (ne:SI (match_operand:SI 1 "register_operand" "r")
  402.                (const_int 0))))
  403.    (clobber (reg:CC 0))]
  404.   ""
  405.   "subcc %%g0,%1,%%g0\;subx %%g0,0,%0"
  406.   [(set_attr "type" "unary")
  407.    (set_attr "length" "2")])
  408.  
  409. (define_insn ""
  410.   [(set (match_operand:SI 0 "register_operand" "=r")
  411.     (eq:SI (match_operand:SI 1 "register_operand" "r") (const_int 0)))
  412.    (clobber (reg:CC 0))]
  413.   ""
  414.   "subcc %%g0,%1,%%g0\;subx %%g0,-1,%0"
  415.   [(set_attr "type" "unary")
  416.    (set_attr "length" "2")])
  417.  
  418. (define_insn ""
  419.   [(set (match_operand:SI 0 "register_operand" "=r")
  420.     (neg:SI (eq:SI (match_operand:SI 1 "register_operand" "r")
  421.                (const_int 0))))
  422.    (clobber (reg:CC 0))]
  423.   ""
  424.   "subcc %%g0,%1,%%g0\;addx %%g0,-1,%0"
  425.   [(set_attr "type" "unary")
  426.    (set_attr "length" "2")])
  427.  
  428. ;; We can also do (x + (i == 0)) and related, so put them in.
  429.  
  430. (define_insn ""
  431.   [(set (match_operand:SI 0 "register_operand" "=r")
  432.     (plus:SI (ne:SI (match_operand:SI 1 "register_operand" "r")
  433.             (const_int 0))
  434.          (match_operand:SI 2 "register_operand" "r")))
  435.    (clobber (reg:CC 0))]
  436.   ""
  437.   "subcc %%g0,%1,%%g0\;addx %2,0,%0"
  438.   [(set_attr "type" "binary")
  439.    (set_attr "length" "2")])
  440.  
  441. (define_insn ""
  442.   [(set (match_operand:SI 0 "register_operand" "=r")
  443.     (minus:SI (match_operand:SI 2 "register_operand" "r")
  444.           (ne:SI (match_operand:SI 1 "register_operand" "r")
  445.              (const_int 0))))
  446.    (clobber (reg:CC 0))]
  447.   ""
  448.   "subcc %%g0,%1,%%g0\;subx %2,0,%0"
  449.   [(set_attr "type" "binary")
  450.    (set_attr "length" "2")])
  451.  
  452. (define_insn ""
  453.   [(set (match_operand:SI 0 "register_operand" "=r")
  454.     (plus:SI (eq:SI (match_operand:SI 1 "register_operand" "r")
  455.             (const_int 0))
  456.          (match_operand:SI 2 "register_operand" "r")))
  457.    (clobber (reg:CC 0))]
  458.   ""
  459.   "subcc %%g0,%1,%%g0\;subx %2,-1,%0"
  460.   [(set_attr "type" "binary")
  461.    (set_attr "length" "2")])
  462.  
  463. (define_insn ""
  464.   [(set (match_operand:SI 0 "register_operand" "=r")
  465.     (minus:SI (match_operand:SI 2 "register_operand" "r")
  466.           (eq:SI (match_operand:SI 1 "register_operand" "r")
  467.                 (const_int 0))))
  468.    (clobber (reg:CC 0))]
  469.   ""
  470.   "subcc %%g0,%1,%%g0\;addx %2,-1,%0"
  471.   [(set_attr "type" "unary")
  472.    (set_attr "length" "2")])
  473.  
  474. ;; We can also do GEU and LTU directly, but these operate after a
  475. ;; compare.
  476.  
  477. (define_insn ""
  478.   [(set (match_operand:SI 0 "register_operand" "=r")
  479.     (ltu:SI (reg:CC 0) (const_int 0)))
  480.    (clobber (reg:CC 0))]
  481.   ""
  482.   "addx %%g0,0,%0"
  483.   [(set_attr "type" "misc")])
  484.  
  485. (define_insn ""
  486.   [(set (match_operand:SI 0 "register_operand" "=r")
  487.     (neg:SI (ltu:SI (reg:CC 0) (const_int 0))))]
  488.   ""
  489.   "subx %%g0,0,%0"
  490.   [(set_attr "type" "misc")])
  491.  
  492. (define_insn ""
  493.   [(set (match_operand:SI 0 "register_operand" "=r")
  494.     (geu:SI (reg:CC 0) (const_int 0)))
  495.    (clobber (reg:CC 0))]
  496.   ""
  497.   "subx %%g0,-1,%0"
  498.   [(set_attr "type" "misc")])
  499.  
  500. (define_insn ""
  501.   [(set (match_operand:SI 0 "register_operand" "=r")
  502.     (neg:SI (geu:SI (reg:CC 0) (const_int 0))))]
  503.   ""
  504.   "addx %%g0,-1,%0"
  505.   [(set_attr "type" "misc")])
  506.  
  507. ;; We can also do (x + ((unsigned) i >= 0)) and related, so put them in.
  508.  
  509. (define_insn ""
  510.   [(set (match_operand:SI 0 "register_operand" "=r")
  511.     (plus:SI (ltu:SI (reg:CC 0) (const_int 0))
  512.          (match_operand:SI 1 "register_operand" "r")))]
  513.   ""
  514.   "addx %1,0,%0"
  515.   [(set_attr "type" "unary")])
  516.  
  517. (define_insn ""
  518.   [(set (match_operand:SI 0 "register_operand" "=r")
  519.     (minus:SI (match_operand:SI 1 "register_operand" "r")
  520.           (ltu:SI (reg:CC 0) (const_int 0))))]
  521.   ""
  522.   "subx %1,0,%0"
  523.   [(set_attr "type" "unary")])
  524.  
  525. (define_insn ""
  526.   [(set (match_operand:SI 0 "register_operand" "=r")
  527.     (plus:SI (geu:SI (reg:CC 0) (const_int 0))
  528.          (match_operand:SI 1 "register_operand" "r")))]
  529.   ""
  530.   "subx %1,-1,%0"
  531.   [(set_attr "type" "unary")])
  532.  
  533. ;; Now we have the generic scc insns.  These will be done using a jump.
  534. ;; We have to exclude the cases above, since we won't want combine to
  535. ;; turn something that doesn't require a jump into something that does.
  536. (define_insn ""
  537.   [(set (match_operand:SI 0 "register_operand" "=r")
  538.     (match_operator:SI 1 "normal_comp_operator" [(reg 0) (const_int 0)]))
  539.    (clobber (reg:CC 0))]
  540.   ""
  541.   "* return output_scc_insn (operands, insn); "
  542.   [(set_attr "type" "multi")])
  543.  
  544. ;; These control RTL generation for conditional jump insns
  545.  
  546. (define_expand "beq"
  547.   [(set (pc)
  548.     (if_then_else (eq (match_dup 1) (const_int 0))
  549.               (label_ref (match_operand 0 "" ""))
  550.               (pc)))]
  551.   ""
  552.   "
  553. { operands[1] = gen_compare_reg (EQ, sparc_compare_op0, sparc_compare_op1); }")
  554.  
  555. (define_expand "bne"
  556.   [(set (pc)
  557.     (if_then_else (ne (match_dup 1) (const_int 0))
  558.               (label_ref (match_operand 0 "" ""))
  559.               (pc)))]
  560.   ""
  561.   "
  562. { operands[1] = gen_compare_reg (NE, sparc_compare_op0, sparc_compare_op1); }")
  563.  
  564. (define_expand "bgt"
  565.   [(set (pc)
  566.     (if_then_else (gt (match_dup 1) (const_int 0))
  567.               (label_ref (match_operand 0 "" ""))
  568.               (pc)))]
  569.   ""
  570.   "
  571. { operands[1] = gen_compare_reg (GT, sparc_compare_op0, sparc_compare_op1); }")
  572.  
  573. (define_expand "bgtu"
  574.   [(set (pc)
  575.     (if_then_else (gtu (match_dup 1) (const_int 0))
  576.               (label_ref (match_operand 0 "" ""))
  577.               (pc)))]
  578.   ""
  579.   "
  580. { operands[1] = gen_compare_reg (GTU, sparc_compare_op0, sparc_compare_op1);
  581. }")
  582.  
  583. (define_expand "blt"
  584.   [(set (pc)
  585.     (if_then_else (lt (match_dup 1) (const_int 0))
  586.               (label_ref (match_operand 0 "" ""))
  587.               (pc)))]
  588.   ""
  589.   "
  590. { operands[1] = gen_compare_reg (LT, sparc_compare_op0, sparc_compare_op1); }")
  591.  
  592. (define_expand "bltu"
  593.   [(set (pc)
  594.     (if_then_else (ltu (match_dup 1) (const_int 0))
  595.               (label_ref (match_operand 0 "" ""))
  596.               (pc)))]
  597.   ""
  598.   "
  599. { operands[1] = gen_compare_reg (LTU, sparc_compare_op0, sparc_compare_op1);
  600. }")
  601.  
  602. (define_expand "bge"
  603.   [(set (pc)
  604.     (if_then_else (ge (match_dup 1) (const_int 0))
  605.               (label_ref (match_operand 0 "" ""))
  606.               (pc)))]
  607.   ""
  608.   "
  609. { operands[1] = gen_compare_reg (GE, sparc_compare_op0, sparc_compare_op1); }")
  610.  
  611. (define_expand "bgeu"
  612.   [(set (pc)
  613.     (if_then_else (geu (match_dup 1) (const_int 0))
  614.               (label_ref (match_operand 0 "" ""))
  615.               (pc)))]
  616.   ""
  617.   "
  618. { operands[1] = gen_compare_reg (GEU, sparc_compare_op0, sparc_compare_op1);
  619. }")
  620.  
  621. (define_expand "ble"
  622.   [(set (pc)
  623.     (if_then_else (le (match_dup 1) (const_int 0))
  624.               (label_ref (match_operand 0 "" ""))
  625.               (pc)))]
  626.   ""
  627.   "
  628. { operands[1] = gen_compare_reg (LE, sparc_compare_op0, sparc_compare_op1); }")
  629.  
  630. (define_expand "bleu"
  631.   [(set (pc)
  632.     (if_then_else (leu (match_dup 1) (const_int 0))
  633.               (label_ref (match_operand 0 "" ""))
  634.               (pc)))]
  635.   ""
  636.   "
  637. { operands[1] = gen_compare_reg (LEU, sparc_compare_op0, sparc_compare_op1);
  638. }")
  639.  
  640. ;; Now match both normal and inverted jump.
  641.  
  642. (define_insn ""
  643.   [(set (pc)
  644.     (if_then_else (match_operator 0 "noov_compare_op"
  645.                       [(reg 0) (const_int 0)])
  646.               (label_ref (match_operand 1 "" ""))
  647.               (pc)))]
  648.   ""
  649.   "*
  650. {
  651.   return output_cbranch (operands[0], 1, 0,
  652.              final_sequence && INSN_ANNULLED_BRANCH_P (insn),
  653.              ! final_sequence);
  654. }"
  655.   [(set_attr "type" "branch")])
  656.  
  657. (define_insn ""
  658.   [(set (pc)
  659.     (if_then_else (match_operator 0 "noov_compare_op"
  660.                       [(reg 0) (const_int 0)])
  661.               (pc)
  662.               (label_ref (match_operand 1 "" ""))))]
  663.   ""
  664.   "*
  665. {
  666.   return output_cbranch (operands[0], 1, 1,
  667.              final_sequence && INSN_ANNULLED_BRANCH_P (insn),
  668.              ! final_sequence);
  669. }"
  670.   [(set_attr "type" "branch")])
  671.  
  672. ;; Move instructions
  673.  
  674. (define_expand "movsi"
  675.   [(set (match_operand:SI 0 "general_operand" "")
  676.     (match_operand:SI 1 "general_operand" ""))]
  677.   ""
  678.   "
  679. {
  680.   if (emit_move_sequence (operands, SImode))
  681.     DONE;
  682. }")
  683.  
  684. (define_insn ""
  685.   [(set (match_operand:SI 0 "reg_or_nonsymb_mem_operand" "=r,r,Q")
  686.     (match_operand:SI 1 "move_operand" "rJ,Q,rJ"))]
  687.   ""
  688.   "@
  689.    mov %1,%0
  690.    ld %1,%0
  691.    st %r1,%0"
  692.   [(set_attr "type" "move,load,store")
  693.    (set_attr "length" "*,*,1")])
  694.  
  695. (define_insn ""
  696.   [(set (match_operand:SI 0 "register_operand" "=r,r,r")
  697.     (match_operand:SI 1 "move_reg_or_immed_operand" "rI,K,i"))]
  698.   ""
  699.   "@
  700.    mov %1,%0
  701.    sethi %%hi(%a1),%0
  702.    \\n1:\;call 2f\;sethi %%hi(%l1-1b),%0\\n2:\\tor %0,%%lo(%l1-1b),%0\;add %0,%%o7,%0"
  703.   [(set_attr "type" "move,move,multi")
  704.    (set_attr "length" "*,1,4")])
  705.   
  706. (define_insn ""
  707.   [(set (match_operand:SI 0 "register_operand" "=r")
  708.     (high:SI (match_operand 1 "" "")))]
  709.   "check_pic (1)"
  710.   "sethi %%hi(%a1),%0"
  711.   [(set_attr "type" "move")
  712.    (set_attr "length" "1")])
  713.  
  714. (define_insn ""
  715.   [(set (match_operand:HI 0 "register_operand" "=r")
  716.     (high:HI (match_operand 1 "" "")))]
  717.   "check_pic (1)"
  718.   "sethi %%hi(%a1),%0"
  719.   [(set_attr "type" "move")
  720.    (set_attr "length" "1")])
  721.  
  722. (define_insn ""
  723.   [(set (match_operand:SI 0 "register_operand" "=r")
  724.     (lo_sum:SI (match_operand:SI 1 "register_operand" "r")
  725.            (match_operand:SI 2 "immediate_operand" "in")))]
  726.   ""
  727.   "or %1,%%lo(%a2),%0"
  728.   ;; Need to set length for this arith insn because operand2
  729.   ;; is not an "arith_operand".
  730.   [(set_attr "length" "1")])
  731.  
  732. (define_insn ""
  733.   [(set (mem:SI (match_operand:SI 0 "symbolic_operand" ""))
  734.     (match_operand:SI 1 "reg_or_0_operand" "rJ"))
  735.    (clobber (match_scratch:SI 2 "=&r"))]
  736.   ""
  737.   "sethi %%hi(%a0),%2\;st %r1,[%2+%%lo(%a0)]"
  738.   [(set_attr "type" "store")
  739.    (set_attr "length" "2")])
  740.  
  741. (define_expand "movhi"
  742.   [(set (match_operand:HI 0 "general_operand" "")
  743.     (match_operand:HI 1 "general_operand" ""))]
  744.   ""
  745.   "
  746. {
  747.   if (emit_move_sequence (operands, HImode))
  748.     DONE;
  749. }")
  750.  
  751. (define_insn ""
  752.   [(set (match_operand:HI 0 "reg_or_nonsymb_mem_operand" "=r,r,Q")
  753.     (match_operand:HI 1 "move_operand" "rJ,Q,rJ"))]
  754.   ""
  755.   "@
  756.    mov %1,%0
  757.    lduh %1,%0
  758.    sth %r1,%0"
  759.   [(set_attr "type" "move,load,store")
  760.    (set_attr "length" "*,*,1")])
  761.  
  762. (define_insn ""
  763.   [(set (match_operand:HI 0 "register_operand" "=r,r")
  764.     (match_operand:HI 1 "move_reg_or_immed_operand" "rI,K"))]
  765.   ""
  766.   "@
  767.    mov %1,%0
  768.    sethi %%hi(%a1),%0"
  769.   [(set_attr "type" "move,move")
  770.    (set_attr "length" "*,1")])
  771.  
  772. (define_insn ""
  773.   [(set (match_operand:HI 0 "register_operand" "=r")
  774.     (lo_sum:HI (match_operand:HI 1 "register_operand" "r")
  775.            (match_operand 2 "immediate_operand" "in")))]
  776.   ""
  777.   "or %1,%%lo(%a2),%0"
  778.   [(set_attr "length" "1")])
  779.  
  780. (define_insn ""
  781.   [(set (mem:HI (match_operand:SI 0 "symbolic_operand" ""))
  782.     (match_operand:HI 1 "reg_or_0_operand" "rJ"))
  783.    (clobber (match_scratch:SI 2 "=&r"))]
  784.   ""
  785.   "sethi %%hi(%a0),%2\;sth %r1,[%2+%%lo(%a0)]"
  786.   [(set_attr "type" "store")
  787.    (set_attr "length" "2")])
  788.  
  789. (define_expand "movqi"
  790.   [(set (match_operand:QI 0 "general_operand" "")
  791.     (match_operand:QI 1 "general_operand" ""))]
  792.   ""
  793.   "
  794. {
  795.   if (emit_move_sequence (operands, QImode))
  796.     DONE;
  797. }")
  798.  
  799. (define_insn ""
  800.   [(set (match_operand:QI 0 "reg_or_nonsymb_mem_operand" "=r,r,Q")
  801.     (match_operand:QI 1 "move_operand" "rJ,Q,rJ"))]
  802.   ""
  803.   "@
  804.    mov %1,%0
  805.    ldub %1,%0
  806.    stb %r1,%0"
  807.   [(set_attr "type" "move,load,store")
  808.    (set_attr "length" "*,*,1")])
  809.  
  810. (define_insn ""
  811.   [(set (match_operand:QI 0 "register_operand" "=r,r")
  812.     (match_operand:QI 1 "move_reg_or_immed_operand" "rI,K"))]
  813.   ""
  814.   "@
  815.    mov %1,%0
  816.    sethi %%hi(%a1),%0"
  817.   [(set_attr "type" "move,move")
  818.    (set_attr "length" "*,1")])
  819.  
  820. (define_insn ""
  821.   [(set (match_operand:QI 0 "register_operand" "=r")
  822.     (subreg:QI (lo_sum:SI (match_operand:QI 1 "register_operand" "r")
  823.                   (match_operand 2 "immediate_operand" "in")) 0))]
  824.   ""
  825.   "or %1,%%lo(%a2),%0"
  826.   [(set_attr "length" "1")])
  827.  
  828. (define_insn ""
  829.   [(set (mem:QI (match_operand:SI 0 "symbolic_operand" ""))
  830.     (match_operand:QI 1 "reg_or_0_operand" "rJ"))
  831.    (clobber (match_scratch:SI 2 "=&r"))]
  832.   ""
  833.   "sethi %%hi(%a0),%2\;stb %r1,[%2+%%lo(%a0)]"
  834.   [(set_attr "type" "store")
  835.    (set_attr "length" "2")])
  836.  
  837. ;; The definition of this insn does not really explain what it does,
  838. ;; but it should suffice
  839. ;; that anything generated as this insn will be recognized as one
  840. ;; and that it will not successfully combine with anything.
  841. (define_expand "movstrsi"
  842.   [(parallel [(set (mem:BLK (match_operand:BLK 0 "general_operand" ""))
  843.            (mem:BLK (match_operand:BLK 1 "general_operand" "")))
  844.           (use (match_operand:SI 2 "arith32_operand" ""))
  845.           (use (match_operand:SI 3 "immediate_operand" ""))
  846.           (clobber (match_dup 0))
  847.           (clobber (match_dup 1))
  848.           (clobber (match_scratch:SI 4 ""))
  849.           (clobber (reg:SI 0))
  850.           (clobber (reg:SI 1))])]
  851.   ""
  852.   "
  853. {
  854.   operands[0] = copy_to_mode_reg (SImode, XEXP (operands[0], 0));
  855.   operands[1] = copy_to_mode_reg (SImode, XEXP (operands[1], 0));
  856.   operands[2] = force_not_mem (operands[2]);
  857. }")
  858.  
  859. (define_insn ""
  860.   [(set (mem:BLK (match_operand:SI 0 "register_operand" "r"))
  861.     (mem:BLK (match_operand:SI 1 "register_operand" "r")))
  862.    (use (match_operand:SI 2 "arith32_operand" "rn"))
  863.    (use (match_operand:SI 3 "immediate_operand" "i"))
  864.    (clobber (match_dup 0))
  865.    (clobber (match_dup 1))
  866.    (clobber (match_scratch:SI 4 "=&r"))
  867.    (clobber (reg:SI 0))
  868.    (clobber (reg:SI 1))]
  869.   ""
  870.   "* return output_block_move (operands);"
  871.   [(set_attr "type" "multi")])
  872.  
  873. ;; Floating point move insns
  874.  
  875. ;; This pattern forces (set (reg:DF ...) (const_double ...))
  876. ;; to be reloaded by putting the constant into memory.
  877. ;; It must come before the more general movdf pattern.
  878. (define_insn ""
  879.   [(set (match_operand:DF 0 "general_operand" "=?r,r,f,o")
  880.     (match_operand:DF 1 "" "?E,G,m,G"))]
  881.   "GET_CODE (operands[1]) == CONST_DOUBLE"
  882.   "*
  883. {
  884.   switch (which_alternative)
  885.     {
  886.     case 0:
  887.       return output_move_double (operands);
  888.     case 1:
  889.       return \"mov %%g0,%0\;mov %%g0,%R0\";
  890.     case 2:
  891.       return output_fp_move_double (operands);
  892.     case 3:
  893.       operands[1] = adj_offsettable_operand (operands[0], 4);
  894.       return \"st %%g0,%0\;st %%g0,%1\";
  895.     }
  896. }"
  897.   [(set_attr "type" "load,move,fpload,store")
  898.    (set_attr "length" "3,2,3,3")])
  899.  
  900. (define_expand "movdf"
  901.   [(set (match_operand:DF 0 "general_operand" "")
  902.     (match_operand:DF 1 "general_operand" ""))]
  903.   ""
  904.   "
  905. {
  906.   if (emit_move_sequence (operands, DFmode))
  907.     DONE;
  908. }")
  909.  
  910. (define_insn ""
  911.   [(set (match_operand:DF 0 "reg_or_nonsymb_mem_operand" "=f,r,Q,Q,f,&r,?f,?r")
  912.     (match_operand:DF 1 "reg_or_nonsymb_mem_operand" "f,r,f,r,Q,Q,r,f"))]
  913.   ""
  914.   "*
  915. {
  916.   if (FP_REG_P (operands[0]) || FP_REG_P (operands[1]))
  917.     return output_fp_move_double (operands);
  918.   return output_move_double (operands);
  919. }"
  920.   [(set_attr "type" "fp,move,fpstore,store,fpload,load,multi,multi")
  921.    (set_attr "length" "2,2,3,3,3,3,3,3")])
  922.  
  923. (define_insn ""
  924.   [(set (mem:DF (match_operand:SI 0 "symbolic_operand" "i,i"))
  925.     (match_operand:DF 1 "reg_or_0_operand" "rf,G"))
  926.    (clobber (match_scratch:SI 2 "=&r,&r"))]
  927.   ""
  928.   "*
  929. {
  930.   output_asm_insn (\"sethi %%hi(%a0),%2\", operands);
  931.   if (which_alternative == 0)
  932.     return \"std %1,[%2+%%lo(%a0)]\";
  933.   else
  934.     return \"st %%g0,[%2+%%lo(%a0)]\;st %%g0,[%2+%%lo(%a0+4)]\";
  935. }"
  936.   [(set_attr "type" "store")
  937.    (set_attr "length" "3")])
  938.  
  939. (define_expand "movdi"
  940.   [(set (match_operand:DI 0 "reg_or_nonsymb_mem_operand" "")
  941.     (match_operand:DI 1 "general_operand" ""))]
  942.   ""
  943.   "
  944. {
  945.   if (emit_move_sequence (operands, DImode))
  946.     DONE;
  947. }")
  948.  
  949. (define_insn ""
  950.   [(set (match_operand:DI 0 "reg_or_nonsymb_mem_operand" "=r,Q,&r,&r,?f,?f,?f,?r,Q")
  951.     (match_operand:DI 1 "general_operand" "r,r,Q,i,r,f,Q,f,f"))]
  952.   ""
  953.   "*
  954. {
  955.   if (FP_REG_P (operands[0]) || FP_REG_P (operands[1]))
  956.     return output_fp_move_double (operands);
  957.   return output_move_double (operands);
  958. }"
  959.   [(set_attr "type" "move,store,load,misc,multi,fp,fpload,multi,fpstore")
  960.    (set_attr "length" "2,3,3,3,3,2,3,3,3")])
  961.  
  962. (define_expand "movsf"
  963.   [(set (match_operand:SF 0 "general_operand" "")
  964.     (match_operand:SF 1 "general_operand" ""))]
  965.   ""
  966.   "
  967. {
  968.   if (emit_move_sequence (operands, SFmode))
  969.     DONE;
  970. }")
  971.  
  972. (define_insn ""
  973.   [(set (match_operand:SF 0 "reg_or_nonsymb_mem_operand" "=f,r,rf,f,r,Q,Q")
  974.     (match_operand:SF 1 "reg_or_nonsymb_mem_operand" "f,r,!rf,Q,Q,f,r"))]
  975.   ""
  976.   "@
  977.    fmovs %1,%0
  978.    mov %1,%0
  979.    st %r1,[%%fp-4]\;ld [%%fp-4],%0
  980.    ld %1,%0
  981.    ld %1,%0
  982.    st %r1,%0
  983.    st %r1,%0"
  984.   [(set_attr "type" "fp,move,multi,fpload,load,fpstore,store")
  985.    (set_attr "length" "*,*,2,*,*,*,*")])
  986.  
  987. (define_insn ""
  988.   [(set (mem:SI (match_operand:SF 0 "symbolic_operand" "i"))
  989.     (match_operand:SF 1 "reg_or_0_operand" "rfG"))
  990.    (clobber (match_scratch:SI 2 "=&r"))]
  991.   ""
  992.   "sethi %%hi(%a0),%2\;st %r1,[%2+%%lo(%a0)]"
  993.   [(set_attr "type" "store")
  994.    (set_attr "length" "2")])
  995.  
  996. ;;- zero extension instructions
  997.  
  998. ;; Note that the one starting from HImode comes before those for QImode
  999. ;; so that a constant operand will match HImode, not QImode.
  1000.  
  1001. (define_expand "zero_extendhisi2"
  1002.   [(set (match_operand:SI 0 "register_operand" "")
  1003.     (zero_extend:SI
  1004.      (match_operand:HI 1 "general_operand" "")))]
  1005.   ""
  1006.   "
  1007. {
  1008.   if (GET_CODE (operand1) == MEM
  1009.       && symbolic_operand (XEXP (operand1, 0), Pmode))
  1010.     {
  1011.       rtx temp = copy_to_mode_reg (Pmode, gen_rtx (HIGH, Pmode,
  1012.                            XEXP (operand1, 0)));
  1013.       operands[1] = gen_rtx (MEM, HImode,
  1014.                  gen_rtx (LO_SUM, Pmode,
  1015.                       temp, XEXP (operand1, 0)));
  1016.     }
  1017.   if (GET_CODE (operand1) == REG
  1018.       || (GET_CODE (operand1) == SUBREG
  1019.       && GET_CODE (XEXP (operand1, 0)) == REG))
  1020.     {
  1021.       rtx temp = gen_reg_rtx (SImode);
  1022.       rtx shift_16 = gen_rtx (CONST_INT, VOIDmode, 16);
  1023.       if (GET_CODE (operand1) == SUBREG)
  1024.     operand1 = XEXP (operand1, 0);
  1025.       emit_insn (gen_ashlsi3 (temp, gen_rtx (SUBREG, SImode, operand1, 0), shift_16));
  1026.       emit_insn (gen_lshrsi3 (operand0, temp, shift_16));
  1027.       DONE;
  1028.     }
  1029. }")
  1030.  
  1031. (define_insn ""
  1032.   [(set (match_operand:SI 0 "register_operand" "=r")
  1033.     (zero_extend:SI (match_operand:HI 1 "memory_operand" "m")))]
  1034.   ""
  1035.   "lduh %1,%0"
  1036.   [(set_attr "type" "load")])
  1037.  
  1038. (define_expand "zero_extendqihi2"
  1039.   [(set (match_operand:HI 0 "register_operand" "")
  1040.     (zero_extend:HI
  1041.      (match_operand:QI 1 "general_operand" "")))]
  1042.   ""
  1043.   "
  1044. {
  1045.   if (GET_CODE (operand1) == MEM
  1046.       && symbolic_operand (XEXP (operand1, 0), Pmode))
  1047.     {
  1048.       rtx temp = copy_to_mode_reg (Pmode, gen_rtx (HIGH, Pmode,
  1049.                            XEXP (operand1, 0)));
  1050.       operands[1] = gen_rtx (MEM, QImode,
  1051.                  gen_rtx (LO_SUM, Pmode,
  1052.                       temp, XEXP (operand1, 0)));
  1053.     }
  1054. }")
  1055.  
  1056. (define_insn ""
  1057.   [(set (match_operand:HI 0 "register_operand" "=r,r,r")
  1058.     (zero_extend:HI
  1059.      (match_operand:QI 1 "sparc_operand" "r,I,Q")))]
  1060.   ""
  1061.   "@
  1062.    and %1,0xff,%0;
  1063.    mov (%1 & 0xff),%0
  1064.    ldub %1,%0"
  1065.   [(set_attr "type" "unary,move,load")
  1066.    (set_attr "length" "1")])
  1067.  
  1068. (define_expand "zero_extendqisi2"
  1069.   [(set (match_operand:SI 0 "register_operand" "")
  1070.     (zero_extend:SI
  1071.      (match_operand:QI 1 "general_operand" "")))]
  1072.   ""
  1073.   "
  1074. {
  1075.   if (GET_CODE (operand1) == MEM
  1076.       && symbolic_operand (XEXP (operand1, 0), Pmode))
  1077.     {
  1078.       rtx temp = copy_to_mode_reg (Pmode, gen_rtx (HIGH, Pmode,
  1079.                            XEXP (operand1, 0)));
  1080.       operand1 = gen_rtx (MEM, QImode,
  1081.               gen_rtx (LO_SUM, Pmode,
  1082.                    temp, XEXP (operand1, 0)));
  1083.       emit_insn (gen_rtx (SET, VOIDmode, operand0,
  1084.               gen_rtx (ZERO_EXTEND, SImode, operand1)));
  1085.       DONE;
  1086.     }
  1087. }")
  1088.  
  1089. (define_insn ""
  1090.   [(set (match_operand:SI 0 "register_operand" "=r,r,r")
  1091.     (zero_extend:SI
  1092.      (match_operand:QI 1 "sparc_operand" "r,I,Q")))]
  1093.   ""
  1094.   "@
  1095.    and %1,0xff,%0
  1096.    mov (%1 & 0xff),%0
  1097.    ldub %1,%0"
  1098.   [(set_attr "type" "unary,move,load")
  1099.    (set_attr "length" "1")])
  1100.  
  1101. (define_insn ""
  1102.   [(set (reg:CC 0)
  1103.     (compare:CC (zero_extend:SI (match_operand:QI 0 "register_operand" "r"))
  1104.             (const_int 0)))]
  1105.   ""
  1106.   "andcc %0,0xff,%%g0"
  1107.   [(set_attr "type" "compare")])
  1108.  
  1109. (define_insn ""
  1110.   [(set (reg:CC 0)
  1111.     (compare:CC (zero_extend:SI (match_operand:QI 1 "register_operand" "r"))
  1112.             (const_int 0)))
  1113.    (set (match_operand:SI 0 "register_operand" "=r")
  1114.     (zero_extend:SI (match_dup 1)))]
  1115.   ""
  1116.   "andcc %1,0xff,%0"
  1117.   [(set_attr "type" "unary")])
  1118.  
  1119. ;;- sign extension instructions
  1120. ;; Note that the one starting from HImode comes before those for QImode
  1121. ;; so that a constant operand will match HImode, not QImode.
  1122.  
  1123. (define_expand "extendhisi2"
  1124.   [(set (match_operand:SI 0 "register_operand" "")
  1125.     (sign_extend:SI
  1126.      (match_operand:HI 1 "general_operand" "")))]
  1127.   ""
  1128.   "
  1129. {
  1130.   if (GET_CODE (operand1) == MEM
  1131.       && symbolic_operand (XEXP (operand1, 0), Pmode))
  1132.     {
  1133.       rtx temp = copy_to_mode_reg (Pmode, gen_rtx (HIGH, Pmode,
  1134.                            XEXP (operand1, 0)));
  1135.       operands[1] = gen_rtx (MEM, HImode,
  1136.                  gen_rtx (LO_SUM, Pmode,
  1137.                       temp, XEXP (operand1, 0)));
  1138.     }
  1139.   if (GET_CODE (operand1) == REG
  1140.       || (GET_CODE (operand1) == SUBREG
  1141.       && GET_CODE (XEXP (operand1, 0)) == REG))
  1142.     {
  1143.       rtx temp = gen_reg_rtx (SImode);
  1144.       rtx shift_16 = gen_rtx (CONST_INT, VOIDmode, 16);
  1145.       if (GET_CODE (operand1) == SUBREG)
  1146.     operand1 = XEXP (operand1, 0);
  1147.       emit_insn (gen_ashlsi3 (temp, gen_rtx (SUBREG, SImode, operand1, 0), shift_16));
  1148.       emit_insn (gen_ashrsi3 (operand0, temp, shift_16));
  1149.       DONE;
  1150.     }
  1151. }")
  1152.  
  1153. (define_insn ""
  1154.   [(set (match_operand:SI 0 "register_operand" "=r")
  1155.     (sign_extend:SI (match_operand:HI 1 "memory_operand" "m")))]
  1156.   ""
  1157.   "ldsh %1,%0"
  1158.   [(set_attr "type" "load")])
  1159.  
  1160. (define_insn ""
  1161.   [(set (match_operand:SI 0 "register_operand" "=r")
  1162.     (sign_extend:SI (match_operand:HI 1 "memory_operand" "m")))
  1163.    (set (match_operand:HI 2 "register_operand" "=r")
  1164.     (match_dup 1))]
  1165.   ""
  1166.   "ldsh %1,%0\;mov %0,%2"
  1167.   [(set_attr "type" "multi")
  1168.    (set_attr "length" "2")])
  1169.  
  1170. (define_insn ""
  1171.   [(set (match_operand:SI 0 "register_operand" "=r")
  1172.     (sign_extend:SI (match_operand:HI 1 "memory_operand" "m")))
  1173.    (set (match_operand:HI 2 "register_operand" "=r")
  1174.     (match_dup 1))
  1175.    (set (reg:CC 0)
  1176.     (compare:CC (match_dup 0) (const_int 0)))]
  1177.   ""
  1178.   "* warning (\"new cc insn\"); return \"ldsh %1,%0\;orcc %0,%%g0,%2\";"
  1179.   [(set_attr "type" "multi")
  1180.    (set_attr "length" "2")])
  1181.  
  1182. (define_expand "extendqihi2"
  1183.   [(set (match_operand:HI 0 "register_operand" "")
  1184.     (sign_extend:HI
  1185.      (match_operand:QI 1 "general_operand" "")))]
  1186.   ""
  1187.   "
  1188. {
  1189.   if (GET_CODE (operand1) == MEM
  1190.       && symbolic_operand (XEXP (operand1, 0), Pmode))
  1191.     {
  1192.       rtx temp = copy_to_mode_reg (Pmode, gen_rtx (HIGH, Pmode,
  1193.                            XEXP (operand1, 0)));
  1194.       operands[1] = gen_rtx (MEM, QImode,
  1195.                  gen_rtx (LO_SUM, Pmode,
  1196.                       temp, XEXP (operand1, 0)));
  1197.     }
  1198.   if (GET_CODE (operand1) == REG
  1199.       || (GET_CODE (operand1) == SUBREG
  1200.       && GET_CODE (XEXP (operand1, 0)) == REG))
  1201.     {
  1202.       rtx temp = gen_reg_rtx (SImode);
  1203.       rtx shift_24 = gen_rtx (CONST_INT, VOIDmode, 24);
  1204.       if (GET_CODE (operand1) == SUBREG)
  1205.     operand1 = XEXP (operand1, 0);
  1206.       if (GET_CODE (operand0) == SUBREG)
  1207.     operand0 = XEXP (operand0, 0);
  1208.       emit_insn (gen_ashlsi3 (temp, gen_rtx (SUBREG, SImode, operand1, 0), shift_24));
  1209.       if (GET_MODE (operand0) != SImode)
  1210.     operand0 = gen_rtx (SUBREG, SImode, operand0, 0);
  1211.       emit_insn (gen_ashrsi3 (operand0, temp, shift_24));
  1212.       DONE;
  1213.     }
  1214. }")
  1215.  
  1216. (define_insn ""
  1217.   [(set (match_operand:HI 0 "register_operand" "=r")
  1218.     (sign_extend:HI (match_operand:QI 1 "memory_operand" "m")))]
  1219.   ""
  1220.   "ldsb %1,%0"
  1221.   [(set_attr "type" "load")])
  1222.  
  1223. (define_insn ""
  1224.   [(set (match_operand:HI 0 "register_operand" "=r")
  1225.     (sign_extend:HI (match_operand:QI 1 "memory_operand" "m")))
  1226.    (set (match_operand:HI 2 "register_operand" "=r")
  1227.     (match_dup 1))]
  1228.   ""
  1229.   "ldsb %1,%0\;mov %0,%2"
  1230.   [(set_attr "type" "multi")
  1231.    (set_attr "length" "2")])
  1232.  
  1233. (define_insn ""
  1234.   [(set (match_operand:HI 0 "register_operand" "=r")
  1235.     (sign_extend:HI (match_operand:QI 1 "memory_operand" "m")))
  1236.    (set (match_operand:HI 2 "register_operand" "=r")
  1237.     (match_dup 1))
  1238.    (set (reg:CC 0)
  1239.     (compare:CC (match_dup 1) (const_int 0)))]
  1240.   ""
  1241.   "* warning (\"new cc insn\"); return \"ldsb %1,%0\;orcc %0,%%g0,%2\";"
  1242.   [(set_attr "type" "multi")
  1243.    (set_attr "length" "2")])
  1244.  
  1245. (define_expand "extendqisi2"
  1246.   [(set (match_operand:SI 0 "register_operand" "")
  1247.     (sign_extend:SI
  1248.      (match_operand:QI 1 "general_operand" "")))]
  1249.   ""
  1250.   "
  1251. {
  1252.   if (GET_CODE (operand1) == MEM
  1253.       && symbolic_operand (XEXP (operand1, 0), Pmode))
  1254.     {
  1255.       rtx temp = copy_to_mode_reg (Pmode, gen_rtx (HIGH, Pmode,
  1256.                            XEXP (operand1, 0)));
  1257.       operands[1] = gen_rtx (MEM, QImode,
  1258.                  gen_rtx (LO_SUM, Pmode,
  1259.                       temp, XEXP (operand1, 0)));
  1260.     }
  1261.   if (GET_CODE (operand1) == REG
  1262.       || (GET_CODE (operand1) == SUBREG
  1263.       && GET_CODE (XEXP (operand1, 0)) == REG))
  1264.     {
  1265.       rtx temp = gen_reg_rtx (SImode);
  1266.       rtx shift_24 = gen_rtx (CONST_INT, VOIDmode, 24);
  1267.       if (GET_CODE (operand1) == SUBREG)
  1268.     operand1 = XEXP (operand1, 0);
  1269.       emit_insn (gen_ashlsi3 (temp, gen_rtx (SUBREG, SImode, operand1, 0), shift_24));
  1270.       emit_insn (gen_ashrsi3 (operand0, temp, shift_24));
  1271.       DONE;
  1272.     }
  1273. }")
  1274.  
  1275. (define_insn ""
  1276.   [(set (match_operand:SI 0 "register_operand" "=r")
  1277.     (sign_extend:SI (match_operand:QI 1 "memory_operand" "m")))]
  1278.   ""
  1279.   "ldsb %1,%0"
  1280.   [(set_attr "type" "load")])
  1281.  
  1282. (define_insn ""
  1283.   [(set (match_operand:SI 0 "register_operand" "=r")
  1284.     (sign_extend:SI (match_operand:QI 1 "memory_operand" "m")))
  1285.    (set (match_operand:QI 2 "register_operand" "=r")
  1286.     (match_dup 1))]
  1287.   ""
  1288.   "ldsb %1,%0\;mov %0,%2"
  1289.   [(set_attr "type" "multi")
  1290.    (set_attr "length" "2")])
  1291.  
  1292. (define_insn ""
  1293.   [(set (match_operand:SI 0 "register_operand" "=r")
  1294.     (sign_extend:SI (match_operand:QI 1 "memory_operand" "m")))
  1295.    (set (match_operand:QI 2 "register_operand" "=r")
  1296.     (match_dup 1))
  1297.    (set (reg:CC 0)
  1298.     (compare:CC (match_dup 0) (const_int 0)))]
  1299.   ""
  1300.   "* warning (\"new cc insn\"); return \"ldsb %1,%0\;orcc %0,%%g0,%2\";"
  1301.   [(set_attr "type" "multi")
  1302.    (set_attr "length" "2")])
  1303.  
  1304. ;; Signed bitfield extractions come out looking like
  1305. ;;    (shiftrt (shift (sign_extend <Y>) <C1>) <C2>)
  1306. ;; which we expand poorly as four shift insns.
  1307. ;; These patters yeild two shifts:
  1308. ;;    (shiftrt (shift <Y> <C3>) <C4>)
  1309. (define_insn ""
  1310.   [(set (match_operand:SI 0 "register_operand" "=r")
  1311.     (sign_extract:SI (match_operand:SI 1 "register_operand" "r")
  1312.              (match_operand:SI 2 "small_int" "n")
  1313.              (match_operand:SI 3 "small_int" "n")))]
  1314.   ""
  1315.   "sll %1,%3,%0\;sra %0,32-%2,%0"
  1316.   [(set_attr "length" "2")])
  1317.  
  1318. (define_insn ""
  1319.   [(set (match_operand:SI 0 "register_operand" "=r")
  1320.     (zero_extract:SI (match_operand:SI 1 "register_operand" "r")
  1321.              (match_operand:SI 2 "small_int" "n")
  1322.              (match_operand:SI 3 "small_int" "n")))]
  1323.   ""
  1324.   "sll %1,%3,%0\;srl %0,32-%2,%0"
  1325.   [(set_attr "length" "2")])
  1326.  
  1327. (define_split
  1328.   [(set (match_operand:SI 0 "register_operand" "=r")
  1329.     (sign_extract:SI (match_operand:SI 1 "register_operand" "r")
  1330.              (match_operand:SI 2 "small_int" "n")
  1331.              (match_operand:SI 3 "small_int" "n")))]
  1332.   ""
  1333.   [(set (match_dup 0) (ashift:SI (match_dup 1) (match_dup 3)))
  1334.    (set (match_dup 0) (ashiftrt:SI (match_dup 0) (match_dup 2)))]
  1335.   "
  1336. {
  1337.   operands[2] = gen_rtx (CONST_INT, VOIDmode,
  1338.              BITS_PER_WORD - INTVAL (operands[2]));
  1339. }")
  1340.  
  1341. (define_split
  1342.   [(set (match_operand:SI 0 "register_operand" "=r")
  1343.     (zero_extract:SI (match_operand:SI 1 "register_operand" "r")
  1344.              (match_operand:SI 2 "small_int" "n")
  1345.              (match_operand:SI 3 "small_int" "n")))]
  1346.   ""
  1347.   [(set (match_dup 0) (ashift:SI (match_dup 1) (match_dup 3)))
  1348.    (set (match_dup 0) (lshiftrt:SI (match_dup 0) (match_dup 2)))]
  1349.   "
  1350. {
  1351.   operands[2] = gen_rtx (CONST_INT, VOIDmode,
  1352.              BITS_PER_WORD - INTVAL (operands[2]));
  1353. }")
  1354.  
  1355. ;; Special pattern for optimizing bit-field compares.
  1356.  
  1357. (define_insn ""
  1358.   [(set (reg:CC 0)
  1359.     (compare:CC
  1360.      (zero_extract:SI (match_operand:SI 0 "register_operand" "r")
  1361.               (match_operand:SI 1 "small_int" "n")
  1362.               (match_operand:SI 2 "small_int" "n"))
  1363.      (const_int 0)))]
  1364.   "INTVAL (operands[2]) > 19"
  1365.   "*
  1366. {
  1367.   int len = INTVAL (operands[1]);
  1368.   int pos = 32 - INTVAL (operands[2]) - len;
  1369.   unsigned mask = ((1 << len) - 1) << pos;
  1370.  
  1371.   operands[1] = gen_rtx (CONST_INT, VOIDmode, mask);
  1372.   return \"andcc %0,%1,%%g0\";
  1373. }")
  1374.  
  1375. ;; Conversions between float and double.
  1376.  
  1377. (define_insn "extendsfdf2"
  1378.   [(set (match_operand:DF 0 "register_operand" "=f")
  1379.     (float_extend:DF
  1380.      (match_operand:SF 1 "register_operand" "f")))]
  1381.   ""
  1382.   "fstod %1,%0"
  1383.   [(set_attr "type" "fp")])
  1384.  
  1385. (define_insn "truncdfsf2"
  1386.   [(set (match_operand:SF 0 "register_operand" "=f")
  1387.     (float_truncate:SF
  1388.      (match_operand:DF 1 "register_operand" "f")))]
  1389.   ""
  1390.   "fdtos %1,%0"
  1391.   [(set_attr "type" "fp")])
  1392.  
  1393. ;; Conversion between fixed point and floating point.
  1394. ;; Note that among the fix-to-float insns
  1395. ;; the ones that start with SImode come first.
  1396. ;; That is so that an operand that is a CONST_INT
  1397. ;; (and therefore lacks a specific machine mode).
  1398. ;; will be recognized as SImode (which is always valid)
  1399. ;; rather than as QImode or HImode.
  1400.  
  1401. ;; This pattern forces (set (reg:SF ...) (float:SF (const_int ...)))
  1402. ;; to be reloaded by putting the constant into memory.
  1403. ;; It must come before the more general floatsisf2 pattern.
  1404. (define_insn ""
  1405.   [(set (match_operand:SF 0 "general_operand" "=f")
  1406.     (float:SF (match_operand 1 "" "m")))]
  1407.   "GET_CODE (operands[1]) == CONST_INT"
  1408.   "* return output_floatsisf2 (operands);"
  1409.   [(set_attr "type" "fp")
  1410.    (set_attr "length" "3")])
  1411.  
  1412. (define_insn "floatsisf2"
  1413.   [(set (match_operand:SF 0 "general_operand" "=f")
  1414.     (float:SF (match_operand:SI 1 "general_operand" "rfm")))]
  1415.   ""
  1416.   "* return output_floatsisf2 (operands);"
  1417.   [(set_attr "type" "fp")
  1418.    (set_attr "length" "3")])
  1419.  
  1420. ;; This pattern forces (set (reg:DF ...) (float:DF (const_int ...)))
  1421. ;; to be reloaded by putting the constant into memory.
  1422. ;; It must come before the more general floatsidf2 pattern.
  1423. (define_insn ""
  1424.   [(set (match_operand:DF 0 "general_operand" "=f")
  1425.     (float:DF (match_operand 1 "" "m")))]
  1426.   "GET_CODE (operands[1]) == CONST_INT"
  1427.   "* return output_floatsidf2 (operands);"
  1428.   [(set_attr "type" "fp")
  1429.    (set_attr "length" "3")])
  1430.  
  1431. (define_insn "floatsidf2"
  1432.   [(set (match_operand:DF 0 "general_operand" "=f")
  1433.     (float:DF (match_operand:SI 1 "general_operand" "rm")))]
  1434.   ""
  1435.   "* return output_floatsidf2 (operands);"
  1436.   [(set_attr "type" "fp")
  1437.    (set_attr "length" "3")])
  1438.  
  1439. ;; Convert a float to an actual integer.
  1440. ;; Truncation is performed as part of the conversion.
  1441. (define_insn "fix_truncsfsi2"
  1442.   [(set (match_operand:SI 0 "general_operand" "=rm")
  1443.     (fix:SI (fix:SF (match_operand:SF 1 "general_operand" "fm"))))
  1444.    (clobber (match_scratch:SF 2 "=&f"))]
  1445.   ""
  1446.   "*
  1447. {
  1448.   if (FP_REG_P (operands[1]))
  1449.     output_asm_insn (\"fstoi %1,%2\", operands);
  1450.   else
  1451.     output_asm_insn (\"ld %1,%2\;fstoi %2,%2\", operands);
  1452.   if (GET_CODE (operands[0]) == MEM)
  1453.     return \"st %2,%0\";
  1454.   else
  1455.     return \"st %2,[%%fp-4]\;ld [%%fp-4],%0\";
  1456. }"
  1457.   [(set_attr "type" "fp")
  1458.    (set_attr "length" "3")])
  1459.  
  1460. (define_insn "fix_truncdfsi2"
  1461.   [(set (match_operand:SI 0 "general_operand" "=rm")
  1462.     (fix:SI (fix:DF (match_operand:DF 1 "general_operand" "fm"))))
  1463.    (clobber (match_scratch:DF 2 "=&f"))]
  1464.   ""
  1465.   "*
  1466. {
  1467.   if (FP_REG_P (operands[1]))
  1468.     output_asm_insn (\"fdtoi %1,%2\", operands);
  1469.   else
  1470.     {
  1471.       rtx xoperands[3];
  1472.       xoperands[0] = operands[2];
  1473.       xoperands[1] = operands[1];
  1474.       output_asm_insn (output_fp_move_double (xoperands), xoperands);
  1475.       output_asm_insn (\"fdtoi %2,%2\", operands);
  1476.     }
  1477.   if (GET_CODE (operands[0]) == MEM)
  1478.     return \"st %2,%0\";
  1479.   else
  1480.     return \"st %2,[%%fp-4]\;ld [%%fp-4],%0\";
  1481. }"
  1482.   [(set_attr "type" "fp")
  1483.    (set_attr "length" "3")])
  1484.  
  1485. ;;- arithmetic instructions
  1486.  
  1487. (define_insn "adddi3"
  1488.   [(set (match_operand:DI 0 "register_operand" "=r")
  1489.     (plus:DI (match_operand:DI 1 "register_operand" "%r")
  1490.          (match_operand:DI 2 "register_operand" "r")))
  1491.    (clobber (reg:SI 0))]
  1492.   ""
  1493.   "addcc %R1,%R2,%R0\;addx %1,%2,%0"
  1494.   [(set_attr "type" "binary")
  1495.    (set_attr "length" "2")])
  1496.  
  1497. (define_insn "addsi3"
  1498.   [(set (match_operand:SI 0 "register_operand" "=r")
  1499.     (plus:SI (match_operand:SI 1 "arith_operand" "%r")
  1500.          (match_operand:SI 2 "arith_operand" "rI")))]
  1501.   ""
  1502.   "add %1,%2,%0")
  1503.  
  1504. (define_insn ""
  1505.   [(set (reg:CC_NOOV 0)
  1506.     (compare:CC_NOOV (plus:SI (match_operand:SI 0 "register_operand" "%r")
  1507.                   (match_operand:SI 1 "arith_operand" "rI"))
  1508.              (const_int 0)))]
  1509.   ""
  1510.   "addcc %0,%1,%%g0"
  1511.   [(set_attr "type" "compare")])
  1512.  
  1513. (define_insn ""
  1514.   [(set (reg:CC_NOOV 0)
  1515.     (compare:CC_NOOV (plus:SI (match_operand:SI 1 "register_operand" "%r")
  1516.                   (match_operand:SI 2 "arith_operand" "rI"))
  1517.              (const_int 0)))
  1518.    (set (match_operand:SI 0 "register_operand" "=r")
  1519.     (plus:SI (match_dup 1) (match_dup 2)))]
  1520.   ""
  1521.   "addcc %1,%2,%0")
  1522.  
  1523. (define_insn "subdi3"
  1524.   [(set (match_operand:DI 0 "register_operand" "=r")
  1525.     (minus:DI (match_operand:DI 1 "register_operand" "r")
  1526.           (match_operand:DI 2 "register_operand" "r")))
  1527.    (clobber (reg:SI 0))]
  1528.   ""
  1529.   "subcc %R1,%R2,%R0\;subx %1,%2,%0"
  1530.   [(set_attr "length" "2")])
  1531.  
  1532. (define_insn "subsi3"
  1533.   [(set (match_operand:SI 0 "register_operand" "=r")
  1534.     (minus:SI (match_operand:SI 1 "arith_operand" "r")
  1535.           (match_operand:SI 2 "arith_operand" "rI")))]
  1536.   ""
  1537.   "sub %1,%2,%0")
  1538.  
  1539. (define_insn ""
  1540.   [(set (reg:CC_NOOV 0)
  1541.     (compare:CC_NOOV (minus:SI (match_operand:SI 0 "register_operand" "r")
  1542.                    (match_operand:SI 1 "arith_operand" "rI"))
  1543.              (const_int 0)))]
  1544.   ""
  1545.   "subcc %0,%1,%%g0"
  1546.   [(set_attr "type" "compare")])
  1547.  
  1548. (define_insn ""
  1549.   [(set (reg:CC_NOOV 0)
  1550.     (compare:CC_NOOV (minus:SI (match_operand:SI 1 "register_operand" "r")
  1551.                    (match_operand:SI 2 "arith_operand" "rI"))
  1552.              (const_int 0)))
  1553.    (set (match_operand:SI 0 "register_operand" "=r")
  1554.     (minus:SI (match_dup 1) (match_dup 2)))]
  1555.   ""
  1556.   "subcc %1,%2,%0")
  1557.  
  1558. ;;- and instructions
  1559. ;; We define DImode `and` so with DImode `not` we can get
  1560. ;; DImode `andn`.  Other combinations are possible.
  1561.  
  1562. (define_expand "anddi3"
  1563.   [(set (match_operand:DI 0 "register_operand" "")
  1564.     (and:DI (match_operand:DI 1 "arith_double_operand" "")
  1565.         (match_operand:DI 2 "arith_double_operand" "")))]
  1566.   ""
  1567.   "
  1568. {
  1569.   if (! register_operand (operands[1], DImode)
  1570.       || ! register_operand (operands[2], DImode))
  1571.     /* Let GCC break this into word-at-a-time operations.  */
  1572.     FAIL;
  1573. }")
  1574.  
  1575. (define_insn ""
  1576.   [(set (match_operand:DI 0 "register_operand" "=r")
  1577.     (and:DI (match_operand:DI 1 "register_operand" "%r")
  1578.         (match_operand:DI 2 "register_operand" "r")))]
  1579.   ""
  1580.   "and %1,%2,%0\;and %R1,%R2,%R0"
  1581.   [(set_attr "length" "2")])
  1582.  
  1583. (define_insn "andsi3"
  1584.   [(set (match_operand:SI 0 "register_operand" "=r")
  1585.     (and:SI (match_operand:SI 1 "arith_operand" "%r")
  1586.         (match_operand:SI 2 "arith_operand" "rI")))]
  1587.   ""
  1588.   "and %1,%2,%0")
  1589.  
  1590. (define_insn ""
  1591.   [(set (match_operand:DI 0 "register_operand" "=r")
  1592.     (and:DI (not:DI (match_operand:DI 1 "register_operand" "r"))
  1593.         (match_operand:DI 2 "register_operand" "r")))]
  1594.   ""
  1595.   "andn %2,%1,%0\;andn %R2,%R1,%R0"
  1596.   [(set_attr "length" "2")])
  1597.  
  1598. (define_insn ""
  1599.   [(set (match_operand:SI 0 "register_operand" "=r")
  1600.     (and:SI (not:SI (match_operand:SI 1 "register_operand" "r"))
  1601.         (match_operand:SI 2 "register_operand" "r")))]
  1602.   ""
  1603.   "andn %2,%1,%0")
  1604.  
  1605. (define_expand "iordi3"
  1606.   [(set (match_operand:DI 0 "register_operand" "")
  1607.     (ior:DI (match_operand:DI 1 "arith_double_operand" "")
  1608.         (match_operand:DI 2 "arith_double_operand" "")))]
  1609.   ""
  1610.   "
  1611. {
  1612.   if (! register_operand (operands[1], DImode)
  1613.       || ! register_operand (operands[2], DImode))
  1614.     /* Let GCC break this into word-at-a-time operations.  */
  1615.     FAIL;
  1616. }")
  1617.  
  1618. (define_insn ""
  1619.   [(set (match_operand:DI 0 "register_operand" "=r")
  1620.     (ior:DI (match_operand:DI 1 "register_operand" "%r")
  1621.         (match_operand:DI 2 "register_operand" "r")))]
  1622.   ""
  1623.   "or %1,%2,%0\;or %R1,%R2,%R0"
  1624.   [(set_attr "length" "2")])
  1625.  
  1626. (define_insn "iorsi3"
  1627.   [(set (match_operand:SI 0 "register_operand" "=r")
  1628.     (ior:SI (match_operand:SI 1 "arith_operand" "%r")
  1629.         (match_operand:SI 2 "arith_operand" "rI")))]
  1630.   ""
  1631.   "or %1,%2,%0")
  1632.  
  1633. (define_insn ""
  1634.   [(set (match_operand:DI 0 "register_operand" "=r")
  1635.     (ior:DI (not:DI (match_operand:DI 1 "register_operand" "r"))
  1636.         (match_operand:DI 2 "register_operand" "r")))]
  1637.   ""
  1638.   "orn %2,%1,%0\;orn %R2,%R1,%R0"
  1639.   [(set_attr "length" "2")])
  1640.  
  1641. (define_insn ""
  1642.   [(set (match_operand:SI 0 "register_operand" "=r")
  1643.     (ior:SI (not:SI (match_operand:SI 1 "register_operand" "r"))
  1644.         (match_operand:SI 2 "register_operand" "r")))]
  1645.   ""
  1646.   "orn %2,%1,%0")
  1647.  
  1648. (define_expand "xordi3"
  1649.   [(set (match_operand:DI 0 "register_operand" "")
  1650.     (xor:DI (match_operand:DI 1 "arith_double_operand" "")
  1651.         (match_operand:DI 2 "arith_double_operand" "")))]
  1652.   ""
  1653.   "
  1654. {
  1655.   if (! register_operand (operands[1], DImode)
  1656.       || ! register_operand (operands[2], DImode))
  1657.     /* Let GCC break this into word-at-a-time operations.  */
  1658.     FAIL;
  1659. }")
  1660.  
  1661. (define_insn ""
  1662.   [(set (match_operand:DI 0 "register_operand" "=r")
  1663.     (xor:DI (match_operand:DI 1 "register_operand" "%r")
  1664.         (match_operand:DI 2 "register_operand" "r")))]
  1665.   ""
  1666.   "xor %1,%2,%0\;xor %R1,%R2,%R0"
  1667.   [(set_attr "length" "2")])
  1668.  
  1669. (define_insn "xorsi3"
  1670.   [(set (match_operand:SI 0 "register_operand" "=r")
  1671.     (xor:SI (match_operand:SI 1 "arith_operand" "%rJ")
  1672.         (match_operand:SI 2 "arith_operand" "rI")))]
  1673.   ""
  1674.   "xor %r1,%2,%0")
  1675.  
  1676. ;; xnor patterns.  Note that (a ^ ~b) == (~a ^ b) == ~(a ^ b).
  1677. ;; Combine now canonicalizes to the rightmost expression.
  1678. (define_insn ""
  1679.   [(set (match_operand:DI 0 "register_operand" "=r")
  1680.     (not:DI (xor:DI (match_operand:DI 1 "register_operand" "r")
  1681.             (match_operand:DI 2 "register_operand" "rI"))))]
  1682.   ""
  1683.   "xnor %1,%2,%0\;xnor %R1,%R2,%R0"
  1684.   [(set_attr "length" "2")])
  1685.  
  1686. (define_insn ""
  1687.   [(set (match_operand:SI 0 "register_operand" "=r")
  1688.     (not:SI (xor:SI (match_operand:SI 1 "reg_or_0_operand" "rJ")
  1689.             (match_operand:SI 2 "arith_operand" "rI"))))]
  1690.   ""
  1691.   "xnor %r1,%2,%0")
  1692.  
  1693. ;; These correspond to the above in the case where we also (or only)
  1694. ;; want to set the condition code.  
  1695.  
  1696. (define_insn ""
  1697.   [(set (reg:CC 0)
  1698.     (compare:CC
  1699.      (match_operator:SI 2 "cc_arithop"
  1700.                 [(match_operand:SI 0 "register_operand" "%r")
  1701.                  (match_operand:SI 1 "arith_operand" "rI")])
  1702.      (const_int 0)))]
  1703.   ""
  1704.   "%A2cc %0,%1,%%g0"
  1705.   [(set_attr "type" "compare")])
  1706.  
  1707. (define_insn ""
  1708.   [(set (reg:CC 0)
  1709.     (compare:CC
  1710.      (match_operator:SI 3 "cc_arithop"
  1711.                 [(match_operand:SI 1 "register_operand" "%r")
  1712.                  (match_operand:SI 2 "arith_operand" "rI")])
  1713.      (const_int 0)))
  1714.    (set (match_operand:SI 0 "register_operand" "=r")
  1715.     (match_dup 3))]
  1716.   ""
  1717.   "%A3cc %1,%2,%0")
  1718.  
  1719. (define_insn ""
  1720.   [(set (reg:CC 0)
  1721.     (compare:CC
  1722.      (not:SI (xor:SI (match_operand:SI 0 "reg_or_0_operand" "%rJ")
  1723.              (match_operand:SI 1 "arith_operand" "rI")))
  1724.      (const_int 0)))]
  1725.   ""
  1726.   "xnorcc %r0,%1,%%g0"
  1727.   [(set_attr "type" "compare")])
  1728.  
  1729. (define_insn ""
  1730.   [(set (reg:CC 0)
  1731.     (compare:CC
  1732.      (not:SI (xor:SI (match_operand:SI 1 "reg_or_0_operand" "%rJ")
  1733.              (match_operand:SI 2 "arith_operand" "rI")))
  1734.      (const_int 0)))
  1735.    (set (match_operand:SI 0 "register_operand" "=r")
  1736.     (not:SI (xor:SI (match_dup 1) (match_dup 2))))]
  1737.   ""
  1738.   "xnorcc %r1,%2,%0")
  1739.  
  1740. (define_insn ""
  1741.   [(set (reg:CC 0)
  1742.     (compare:CC
  1743.      (match_operator:SI 2 "cc_arithopn"
  1744.                 [(not:SI (match_operand:SI 0 "arith_operand" "rI"))
  1745.                  (match_operand:SI 1 "reg_or_0_operand" "rJ")])
  1746.      (const_int 0)))]
  1747.   ""
  1748.   "%B2cc %r1,%0,%%g0"
  1749.   [(set_attr "type" "compare")])
  1750.  
  1751. (define_insn ""
  1752.   [(set (reg:CC 0)
  1753.     (compare:CC
  1754.      (match_operator:SI 3 "cc_arithopn"
  1755.                 [(not:SI (match_operand:SI 1 "arith_operand" "rI"))
  1756.                  (match_operand:SI 2 "reg_or_0_operand" "rJ")])
  1757.      (const_int 0)))
  1758.    (set (match_operand:SI 0 "register_operand" "=r")
  1759.     (match_dup 3))]
  1760.   ""
  1761.   "%B3cc %r2,%1,%0")
  1762.  
  1763. ;; We cannot use the "neg" pseudo insn because the Sun assembler
  1764. ;; does not know how to make it work for constants.
  1765.  
  1766. (define_insn "negdi2"
  1767.   [(set (match_operand:DI 0 "register_operand" "=r")
  1768.     (neg:DI (match_operand:DI 1 "register_operand" "r")))
  1769.    (clobber (reg:SI 0))]
  1770.   ""
  1771.   "subcc %%g0,%R1,%R0\;subx %%g0,%1,%0"
  1772.   [(set_attr "type" "unary")
  1773.    (set_attr "length" "2")])
  1774.  
  1775. (define_insn "negsi2"
  1776.   [(set (match_operand:SI 0 "general_operand" "=r")
  1777.     (neg:SI (match_operand:SI 1 "arith_operand" "rI")))]
  1778.   ""
  1779.   "sub %%g0,%1,%0"
  1780.   [(set_attr "type" "unary")])
  1781.  
  1782. (define_insn ""
  1783.   [(set (reg:CC_NOOV 0)
  1784.     (compare:CC_NOOV (neg:SI (match_operand:SI 0 "arith_operand" "rI"))
  1785.              (const_int 0)))]
  1786.   ""
  1787.   "subcc %%g0,%0,%%g0"
  1788.   [(set_attr "type" "compare")])
  1789.  
  1790. (define_insn ""
  1791.   [(set (reg:CC_NOOV 0)
  1792.     (compare:CC_NOOV (neg:SI (match_operand:SI 1 "arith_operand" "rI"))
  1793.              (const_int 0)))
  1794.    (set (match_operand:SI 0 "register_operand" "=r")
  1795.     (neg:SI (match_dup 1)))]
  1796.   ""
  1797.   "subcc %%g0,%1,%0"
  1798.   [(set_attr "type" "unary")])
  1799.  
  1800. ;; We cannot use the "not" pseudo insn because the Sun assembler
  1801. ;; does not know how to make it work for constants.
  1802. (define_expand "one_cmpldi2"
  1803.   [(set (match_operand:DI 0 "register_operand" "")
  1804.     (not:DI (match_operand:DI 1 "arith_double_operand" "")))]
  1805.   ""
  1806.   "
  1807. {
  1808.   if (! register_operand (operands[1], DImode))
  1809.     FAIL;
  1810. }")
  1811.  
  1812. (define_insn ""
  1813.   [(set (match_operand:DI 0 "register_operand" "=r")
  1814.     (not:DI (match_operand:DI 1 "arith_double_operand" "r")))]
  1815.   ""
  1816.   "xnor %%g0,%1,%0\;xnor %%g0,%R1,%R0"
  1817.   [(set_attr "type" "unary")
  1818.    (set_attr "length" "2")])
  1819.  
  1820. (define_insn "one_cmplsi2"
  1821.   [(set (match_operand:SI 0 "general_operand" "=r")
  1822.     (not:SI (match_operand:SI 1 "arith_operand" "rI")))]
  1823.   ""
  1824.   "xnor %%g0,%1,%0"
  1825.   [(set_attr "type" "unary")])
  1826.  
  1827. (define_insn ""
  1828.   [(set (reg:CC 0)
  1829.     (compare:CC (not:SI (match_operand:SI 0 "arith_operand" "rI"))
  1830.             (const_int 0)))]
  1831.   ""
  1832.   "xnorcc %%g0,%0,%%g0"
  1833.   [(set_attr "type" "compare")])
  1834.  
  1835. (define_insn ""
  1836.   [(set (reg:CC 0)
  1837.     (compare:CC (not:SI (match_operand:SI 1 "arith_operand" "rI"))
  1838.             (const_int 0)))
  1839.    (set (match_operand:SI 0 "register_operand" "=r")
  1840.     (not:SI (match_dup 1)))]
  1841.   ""
  1842.   "xnorcc %%g0,%1,%0"
  1843.   [(set_attr "type" "unary")])
  1844.  
  1845. ;; Floating point arithmetic instructions.
  1846.  
  1847. (define_insn "adddf3"
  1848.   [(set (match_operand:DF 0 "register_operand" "=f")
  1849.     (plus:DF (match_operand:DF 1 "register_operand" "f")
  1850.          (match_operand:DF 2 "register_operand" "f")))]
  1851.   ""
  1852.   "faddd %1,%2,%0"
  1853.   [(set_attr "type" "fp")])
  1854.  
  1855. (define_insn "addsf3"
  1856.   [(set (match_operand:SF 0 "register_operand" "=f")
  1857.     (plus:SF (match_operand:SF 1 "register_operand" "f")
  1858.          (match_operand:SF 2 "register_operand" "f")))]
  1859.   ""
  1860.   "fadds %1,%2,%0"
  1861.   [(set_attr "type" "fp")])
  1862.  
  1863. (define_insn "subdf3"
  1864.   [(set (match_operand:DF 0 "register_operand" "=f")
  1865.     (minus:DF (match_operand:DF 1 "register_operand" "f")
  1866.           (match_operand:DF 2 "register_operand" "f")))]
  1867.   ""
  1868.   "fsubd %1,%2,%0"
  1869.   [(set_attr "type" "fp")])
  1870.  
  1871. (define_insn "subsf3"
  1872.   [(set (match_operand:SF 0 "register_operand" "=f")
  1873.     (minus:SF (match_operand:SF 1 "register_operand" "f")
  1874.           (match_operand:SF 2 "register_operand" "f")))]
  1875.   ""
  1876.   "fsubs %1,%2,%0"
  1877.   [(set_attr "type" "fp")])
  1878.  
  1879. (define_insn "muldf3"
  1880.   [(set (match_operand:DF 0 "register_operand" "=f")
  1881.     (mult:DF (match_operand:DF 1 "register_operand" "f")
  1882.          (match_operand:DF 2 "register_operand" "f")))]
  1883.   ""
  1884.   "fmuld %1,%2,%0"
  1885.   [(set_attr "type" "fpmul")])
  1886.  
  1887. (define_insn "mulsf3"
  1888.   [(set (match_operand:SF 0 "register_operand" "=f")
  1889.     (mult:SF (match_operand:SF 1 "register_operand" "f")
  1890.          (match_operand:SF 2 "register_operand" "f")))]
  1891.   ""
  1892.   "fmuls %1,%2,%0"
  1893.   [(set_attr "type" "fpmul")])
  1894.  
  1895. (define_insn "divdf3"
  1896.   [(set (match_operand:DF 0 "register_operand" "=f")
  1897.     (div:DF (match_operand:DF 1 "register_operand" "f")
  1898.         (match_operand:DF 2 "register_operand" "f")))]
  1899.   ""
  1900.   "fdivd %1,%2,%0"
  1901.   [(set_attr "type" "fpdiv")])
  1902.  
  1903. (define_insn "divsf3"
  1904.   [(set (match_operand:SF 0 "register_operand" "=f")
  1905.     (div:SF (match_operand:SF 1 "register_operand" "f")
  1906.         (match_operand:SF 2 "register_operand" "f")))]
  1907.   ""
  1908.   "fdivs %1,%2,%0"
  1909.   [(set_attr "type" "fpdiv")])
  1910.  
  1911. (define_insn "negdf2"
  1912.   [(set (match_operand:DF 0 "register_operand" "=f,f")
  1913.     (neg:DF (match_operand:DF 1 "register_operand" "0,f")))]
  1914.   ""
  1915.   "@
  1916.    fnegs %0,%0
  1917.    fnegs %1,%0\;fmovs %R1,%R0"
  1918.   [(set_attr "type" "fp")
  1919.    (set_attr "length" "1,2")])
  1920.  
  1921.  
  1922. (define_insn "negsf2"
  1923.   [(set (match_operand:SF 0 "register_operand" "=f")
  1924.     (neg:SF (match_operand:SF 1 "register_operand" "f")))]
  1925.   ""
  1926.   "fnegs %1,%0"
  1927.   [(set_attr "type" "fp")])
  1928.  
  1929. (define_insn "absdf2"
  1930.   [(set (match_operand:DF 0 "register_operand" "=f,f")
  1931.     (abs:DF (match_operand:DF 1 "register_operand" "0,f")))]
  1932.   ""
  1933.   "@
  1934.    fabss %0,%0
  1935.    fabss %1,%0\;%fmovs %R1,%R0"
  1936.   [(set_attr "type" "fp")
  1937.    (set_attr "length" "1,2")])
  1938.  
  1939. (define_insn "abssf2"
  1940.   [(set (match_operand:SF 0 "register_operand" "=f")
  1941.     (abs:SF (match_operand:SF 1 "register_operand" "f")))]
  1942.   ""
  1943.   "fabss %1,%0"
  1944.   [(set_attr "type" "fp")])
  1945.  
  1946. (define_insn "sqrtdf2"
  1947.   [(set (match_operand:DF 0 "register_operand" "=f")
  1948.     (sqrt:DF (match_operand:DF 1 "register_operand" "f")))]
  1949.   ""
  1950.   "fsqrtd %1,%0"
  1951.   [(set_attr "type" "fpsqrt")])
  1952.  
  1953. (define_insn "sqrtsf2"
  1954.   [(set (match_operand:SF 0 "register_operand" "=f")
  1955.     (sqrt:SF (match_operand:SF 1 "register_operand" "f")))]
  1956.   ""
  1957.   "fsqrts %1,%0"
  1958.   [(set_attr "type" "fpsqrt")])
  1959.  
  1960. ;; Shift instructions
  1961.  
  1962. ;; Optimized special case of shifting.
  1963. ;; Must precede the general case.
  1964.  
  1965. (define_insn ""
  1966.   [(set (match_operand:SI 0 "register_operand" "=r")
  1967.     (ashiftrt:SI (match_operand:SI 1 "memory_operand" "m")
  1968.              (const_int 24)))]
  1969.   ""
  1970.   "ldsb %1,%0"
  1971.   [(set_attr "type" "load")])
  1972.  
  1973. (define_insn ""
  1974.   [(set (match_operand:SI 0 "register_operand" "=r")
  1975.     (lshiftrt:SI (match_operand:SI 1 "memory_operand" "m")
  1976.              (const_int 24)))]
  1977.   ""
  1978.   "ldub %1,%0"
  1979.   [(set_attr "type" "load")])
  1980.  
  1981. ;;- arithmetic shift instructions
  1982.  
  1983. ;; We can trivially handle shifting the constant 1 by 64 bits.
  1984. ;; For other shifts we use the library routine.
  1985. (define_expand "ashldi3"
  1986.   [(parallel [(set (match_operand:DI 0 "register_operand" "=&r")
  1987.            (ashift:DI (match_operand:DI 1 "const_double_operand" "")
  1988.                   (match_operand:DI 2 "register_operand" "r")))
  1989.           (clobber (reg:SI 0))])]
  1990.   ""
  1991.   "
  1992. {
  1993.   if (GET_CODE (operands[1]) == CONST_DOUBLE
  1994.       || (CONST_DOUBLE_HIGH (operands[1]) == 0
  1995.       && CONST_DOUBLE_LOW (operands[1]) == 1))
  1996.     operands[1] = const1_rtx;
  1997.   else if (operands[1] != const1_rtx)
  1998.     FAIL;
  1999. }")
  2000.  
  2001. (define_insn ""
  2002.   [(set (match_operand:DI 0 "register_operand" "=&r")
  2003.     (ashift:DI (const_int 1)
  2004.            (match_operand:DI  2 "register_operand" "r")))
  2005.    (clobber (reg:SI 0))]
  2006.   ""
  2007.   "subcc %2,32,%%g0\;addx %%g0,0,%R0\;xor %R0,1,%0\;sll %R0,%2,%R0\;sll %0,%2,%0"
  2008.   [(set_attr "type" "multi")
  2009.    (set_attr "length" "5")])
  2010.  
  2011. (define_insn "ashlsi3"
  2012.   [(set (match_operand:SI 0 "register_operand" "=r")
  2013.     (ashift:SI (match_operand:SI 1 "register_operand" "r")
  2014.            (match_operand:SI 2 "arith_operand" "rI")))]
  2015.   ""
  2016.   "sll %1,%2,%0")
  2017.  
  2018. (define_insn "ashrsi3"
  2019.   [(set (match_operand:SI 0 "register_operand" "=r")
  2020.     (ashiftrt:SI (match_operand:SI 1 "register_operand" "r")
  2021.              (match_operand:SI 2 "arith_operand" "rI")))]
  2022.   ""
  2023.   "sra %1,%2,%0")
  2024.  
  2025. (define_insn "lshrsi3"
  2026.   [(set (match_operand:SI 0 "register_operand" "=r")
  2027.     (lshiftrt:SI (match_operand:SI 1 "register_operand" "r")
  2028.              (match_operand:SI 2 "arith_operand" "rI")))]
  2029.   ""
  2030.   "srl %1,%2,%0")
  2031.  
  2032. ;; Unconditional and other jump instructions
  2033. ;; Note that for the Sparc, by setting the annul bit on an unconditional
  2034. ;; branch, the following insn is never executed.  This saves us a nop,
  2035. ;; but requires a debugger which can handle annuled branches.
  2036. (define_insn "jump"
  2037.   [(set (pc) (label_ref (match_operand 0 "" "")))]
  2038.   ""
  2039.   "b%* %l0"
  2040.   [(set_attr "type" "branch")])
  2041.  
  2042. (define_insn "tablejump"
  2043.   [(set (pc) (match_operand:SI 0 "register_operand" "r"))
  2044.    (use (label_ref (match_operand 1 "" "")))]
  2045.   ""
  2046.   "jmp %^%0%#"
  2047.   [(set_attr "type" "branch")])
  2048.  
  2049. (define_insn ""
  2050.   [(set (pc) (label_ref (match_operand 0 "" "")))
  2051.    (set (reg:SI 15) (label_ref (match_dup 0)))]
  2052.   ""
  2053.   "call %l0%#"
  2054.   [(set_attr "type" "branch")])
  2055.  
  2056. ;;- jump to subroutine
  2057. (define_expand "call"
  2058.   [(call (match_operand:SI 0 "call_operand" "")
  2059.      (match_operand 1 "" "i"))]
  2060.   ;; operand[2] is next_arg_register
  2061.   ""
  2062.   "
  2063. {
  2064.   rtx fn_rtx, nregs_rtx;
  2065.  
  2066.   if (GET_CODE (XEXP (operands[0], 0)) == LABEL_REF)
  2067.     {
  2068.       /* This is really a PIC sequence.  We want to represent
  2069.      it as a funny jump so it`s delay slots can be filled. 
  2070.  
  2071.      ??? But if this really *is* a CALL, will not it clobber the
  2072.      call-clobbered registers?  We lose this if it is a JUMP_INSN.
  2073.      Why cannot we have delay slots filled if it were a CALL?  */
  2074.  
  2075.       emit_jump_insn (gen_rtx (PARALLEL, VOIDmode, gen_rtvec (2,
  2076.                    gen_rtx (SET, VOIDmode, pc_rtx,
  2077.                          XEXP (operands[0], 0)),
  2078.                    gen_rtx (CLOBBER, VOIDmode,
  2079.                          gen_rtx (REG, SImode, 15)))));
  2080.       DONE;
  2081.     }
  2082.  
  2083.   if (TARGET_SUN_ASM && GET_CODE (XEXP (operands[0], 0)) == REG)
  2084.     {
  2085.       rtx g1_rtx = gen_rtx (REG, Pmode, 1);
  2086.       emit_move_insn (g1_rtx, XEXP (operands[0], 0));
  2087.       fn_rtx = gen_rtx (MEM, Pmode, g1_rtx);
  2088.     }
  2089.   else
  2090.     fn_rtx = operands[0];
  2091.  
  2092.   /* Count the number of parameter registers being used by this call.
  2093.      if that argument is NULL, it means we are using them all, which
  2094.      means 6 on the sparc.  */
  2095. #if 0
  2096.   if (operands[2])
  2097.     nregs_rtx = gen_rtx (CONST_INT, VOIDmode, REGNO (operands[2]) - 8);
  2098.   else
  2099.     nregs_rtx = gen_rtx (CONST_INT, VOIDmode, 6);
  2100. #else
  2101.   nregs_rtx = const0_rtx;
  2102. #endif
  2103.  
  2104.   emit_call_insn (gen_rtx (PARALLEL, VOIDmode, gen_rtvec (2,
  2105.                gen_rtx (CALL, VOIDmode, fn_rtx, nregs_rtx),
  2106.                gen_rtx (CLOBBER, VOIDmode,
  2107.                          gen_rtx (REG, SImode, 15)))));
  2108.   DONE;
  2109. }")
  2110.  
  2111. (define_insn ""
  2112.   [(call (mem:SI (match_operand:SI 0 "call_operand_address" "S,r"))
  2113.      (match_operand 1 "" ""))
  2114.    (clobber (reg:SI 15))]
  2115.   ;;- Do not use operand 1 for most machines.
  2116.   ""
  2117.   "*
  2118. {
  2119.   if (TARGET_SUN_ASM && GET_CODE (operands[0]) == REG)
  2120.     return \"jmpl %a0,%%o7%#\";
  2121.   else
  2122.     return \"call %a0,%1%#\";
  2123. }"
  2124.   [(set_attr "type" "call")])
  2125.  
  2126. (define_expand "call_value"
  2127.   [(set (match_operand 0 "register_operand" "=rf")
  2128.     (call (match_operand:SI 1 "" "")
  2129.           (match_operand 2 "" "")))]
  2130.   ;; operand 3 is next_arg_register
  2131.   ""
  2132.   "
  2133. {
  2134.   rtx fn_rtx, nregs_rtx;
  2135.   rtvec vec;
  2136.  
  2137.   if (TARGET_SUN_ASM && GET_CODE (XEXP (operands[1], 0)) == REG)
  2138.     {
  2139.       rtx g1_rtx = gen_rtx (REG, Pmode, 1);
  2140.       emit_move_insn (g1_rtx, XEXP (operands[1], 0));
  2141.       fn_rtx = gen_rtx (MEM, Pmode, g1_rtx);
  2142.     }
  2143.   else
  2144.     fn_rtx = operands[1];
  2145.  
  2146. #if 0
  2147.   if (operands[3])
  2148.     nregs_rtx = gen_rtx (CONST_INT, VOIDmode, REGNO (operands[3]) - 8);
  2149.   else
  2150.     nregs_rtx = gen_rtx (CONST_INT, VOIDmode, 6);
  2151. #else
  2152.   nregs_rtx = const0_rtx;
  2153. #endif
  2154.  
  2155.   vec = gen_rtvec (2,
  2156.            gen_rtx (SET, VOIDmode, operands[0],
  2157.                 gen_rtx (CALL, VOIDmode, fn_rtx, nregs_rtx)),
  2158.            gen_rtx (CLOBBER, VOIDmode, gen_rtx (REG, SImode, 15)));
  2159.  
  2160.   emit_call_insn (gen_rtx (PARALLEL, VOIDmode, vec));
  2161.   DONE;
  2162. }")
  2163.  
  2164. (define_insn ""
  2165.   [(set (match_operand 0 "" "=rf")
  2166.     (call (mem:SI (match_operand:SI 1 "call_operand_address" "rS"))
  2167.           (match_operand 2 "" "")))
  2168.    (clobber (reg:SI 15))]
  2169.   ;;- Do not use operand 2 for most machines.
  2170.   ""
  2171.   "*
  2172. {
  2173.   if (TARGET_SUN_ASM && GET_CODE (operands[1]) == REG)
  2174.     return \"jmpl %a1,%%o7%#\";
  2175.   else
  2176.     return \"call %a1,%2%#\";
  2177. }"
  2178.   [(set_attr "type" "call")])
  2179.  
  2180. (define_insn "return"
  2181.   [(return)]
  2182.   "! TARGET_EPILOGUE"
  2183.   "* return output_return (operands);"
  2184.   [(set_attr "type" "multi")])
  2185.  
  2186. (define_insn "nop"
  2187.   [(const_int 0)]
  2188.   ""
  2189.   "nop")
  2190.  
  2191. (define_insn "indirect_jump"
  2192.   [(set (pc) (match_operand:SI 0 "register_operand" "r"))]
  2193.   ""
  2194.  "jmp %0%#"
  2195.  [(set_attr "type" "branch")])
  2196.  
  2197. ;(define_insn "tail_call" ;; tail call
  2198. ;  [(set (pc) (match_operand 0 "memory_operand" "m"))]
  2199. ;  "tail_call_valid_p ()"
  2200. ;  "* return output_tail_call (operands, insn);"
  2201. ;  [(set_attr "type" "branch")])
  2202.  
  2203. ;; Split up troublesome insns for better scheduling.  */
  2204.  
  2205. ;; The following patterns are straightforward.  They can be applied
  2206. ;; either before or after register allocation.
  2207.  
  2208. (define_split
  2209.   [(set (match_operator 0 "memop" [(match_operand:SI 1 "symbolic_operand" "")])
  2210.     (match_operand 2 "reg_or_0_operand" ""))
  2211.    (clobber (match_operand:SI 3 "register_operand" ""))]
  2212.   "! flag_pic"
  2213.   [(set (match_dup 3) (high:SI (match_dup 1)))
  2214.    (set (match_op_dup 0 [(lo_sum:SI (match_dup 3) (match_dup 1))])
  2215.     (match_dup 2))]
  2216.   "")
  2217.  
  2218. (define_split
  2219.   [(set (match_operator 0 "memop"
  2220.             [(match_operand:SI 1 "immediate_operand" "")])
  2221.     (match_operand 2 "general_operand" ""))
  2222.    (clobber (match_operand:SI 3 "register_operand" ""))]
  2223.   "flag_pic"
  2224.   [(set (match_op_dup 0 [(match_dup 1)])
  2225.     (match_dup 2))]
  2226.   "
  2227. {
  2228.   operands[1] = legitimize_pic_address (operands[1], GET_MODE (operands[0]),
  2229.                     operands[3]);
  2230. }")
  2231.  
  2232. (define_split
  2233.   [(set (match_operand 0 "register_operand" "")
  2234.     (match_operator 1 "memop"
  2235.             [(match_operand:SI 2 "immediate_operand" "")]))]
  2236.   "flag_pic"
  2237.   [(set (match_dup 0)
  2238.     (match_op_dup 1 [(match_dup 2)]))]
  2239.   "
  2240. {
  2241.   operands[2] = legitimize_pic_address (operands[2], GET_MODE (operands[1]),
  2242.                     operands[0]);
  2243. }")
  2244.  
  2245. ;; Sign- and Zero-extend operations can have symbolic memory operands.
  2246.  
  2247. (define_split
  2248.   [(set (match_operand 0 "register_operand" "")
  2249.     (match_operator 1 "extend_op"
  2250.             [(match_operator 2 "memop"
  2251.                      [(match_operand:SI 3 "immediate_operand" "")])]))]
  2252.   "flag_pic"
  2253.   [(set (match_dup 0)
  2254.     (match_op_dup 1 [(match_op_dup 2 [(match_dup 3)])]))]
  2255.   "
  2256. {
  2257.   operands[3] = legitimize_pic_address (operands[3], GET_MODE (operands[2]),
  2258.                     operands[0]);
  2259. }")
  2260.  
  2261. (define_split
  2262.   [(set (match_operand:SI 0 "register_operand" "")
  2263.     (match_operand:SI 1 "immediate_operand" ""))]
  2264.   "! flag_pic && (GET_CODE (operands[1]) == SYMBOL_REF
  2265.           || GET_CODE (operands[1]) == CONST
  2266.           || GET_CODE (operands[1]) == LABEL_REF)"
  2267.   [(set (match_dup 0) (high:SI (match_dup 1)))
  2268.    (set (match_dup 0)
  2269.     (lo_sum:SI (match_dup 0) (match_dup 1)))]
  2270.   "")
  2271.  
  2272. ;; LABEL_REFs are not modified by `legitimize_pic_address`
  2273. ;; so do not recurse infinitely in the PIC case.
  2274. (define_split
  2275.   [(set (match_operand:SI 0 "register_operand" "")
  2276.     (match_operand:SI 1 "immediate_operand" ""))]
  2277.   "flag_pic && (GET_CODE (operands[1]) == SYMBOL_REF
  2278.         || GET_CODE (operands[1]) == CONST)"
  2279.   [(set (match_dup 0) (match_dup 1))]
  2280.   "
  2281. {
  2282.   operands[1] = legitimize_pic_address (operands[1], Pmode, operands[0]);
  2283. }")
  2284.  
  2285. ;; Split certain compound insns back into single insns.
  2286.  
  2287. (define_split
  2288.   [(parallel [(set (match_operand:SI 0 "register_operand" "=r")
  2289.            (sign_extend:SI (match_operand:HI 1 "memory_operand" "m")))
  2290.           (set (match_operand:HI 2 "register_operand" "=r")
  2291.            (match_dup 1))])]
  2292.   ""
  2293.   [(set (match_operand:SI 0 "register_operand" "=r")
  2294.     (sign_extend:SI (match_operand:HI 1 "memory_operand" "m")))
  2295.    (set (match_operand:HI 2 "register_operand" "=r")
  2296.     (match_dup 1))]
  2297.   "")
  2298.  
  2299. (define_split
  2300.   [(parallel [(set (match_operand:HI 0 "register_operand" "=r")
  2301.            (sign_extend:HI (match_operand:QI 1 "memory_operand" "m")))
  2302.           (set (match_operand:QI 2 "register_operand" "=r")
  2303.            (match_dup 1))])]
  2304.   ""
  2305.   [(set (match_operand:HI 0 "register_operand" "=r")
  2306.     (sign_extend:HI (match_operand:QI 1 "memory_operand" "m")))
  2307.    (set (match_operand:QI 2 "register_operand" "=r")
  2308.     (match_dup 1))]
  2309.   "")
  2310.  
  2311. (define_split
  2312.   [(parallel [(set (match_operand:SI 0 "register_operand" "=r")
  2313.            (sign_extend:SI (match_operand:QI 1 "memory_operand" "m")))
  2314.           (set (match_operand:QI 2 "register_operand" "=r")
  2315.            (match_dup 1))])]
  2316.   ""
  2317.   [(set (match_operand:SI 0 "register_operand" "=r")
  2318.     (sign_extend:SI (match_operand:QI 1 "memory_operand" "m")))
  2319.    (set (match_operand:QI 2 "register_operand" "=r")
  2320.     (match_dup 1))]
  2321.   "")
  2322.  
  2323. ;; These split sne/seq insns.  The forms of the resulting insns are 
  2324. ;; somewhat bogus, but they avoid extra patterns and show data dependency.
  2325. ;; Nothing will look at these in detail after splitting has occurred.
  2326.  
  2327. (define_split
  2328.   [(set (match_operand:SI 0 "register_operand" "")
  2329.     (ne:SI (match_operand:SI 1 "register_operand" "") (const_int 0)))
  2330.    (clobber (reg:CC 0))]
  2331.   ""
  2332.   [(set (reg:CC_NOOV 0) (compare:CC_NOOV (neg:SI (match_dup 1))
  2333.                      (const_int 0)))
  2334.    (parallel [(set (match_dup 0) (ltu:SI (reg:CC 0) (const_int 0)))
  2335.           (clobber (reg:CC 0))])]
  2336.   "")
  2337.  
  2338. (define_split
  2339.   [(set (match_operand:SI 0 "register_operand" "")
  2340.     (neg:SI (ne:SI (match_operand:SI 1 "register_operand" "")
  2341.                (const_int 0))))
  2342.    (clobber (reg:CC 0))]
  2343.   ""
  2344.   [(set (reg:CC_NOOV 0) (compare:CC_NOOV (neg:SI (match_dup 1))
  2345.                      (const_int 0)))
  2346.    (set (match_dup 0) (neg:SI (ltu:SI (reg:CC 0) (const_int 0))))]
  2347.   "")
  2348.  
  2349. (define_split
  2350.   [(set (match_operand:SI 0 "register_operand" "")
  2351.     (eq:SI (match_operand:SI 1 "register_operand" "") (const_int 0)))
  2352.    (clobber (reg:CC 0))]
  2353.   ""
  2354.   [(set (reg:CC_NOOV 0) (compare:CC_NOOV (neg:SI (match_dup 1))
  2355.                      (const_int 0)))
  2356.    (parallel [(set (match_dup 0) (geu:SI (reg:CC 0) (const_int 0)))
  2357.           (clobber (reg:CC 0))])]
  2358.   "")
  2359.  
  2360. (define_split
  2361.   [(set (match_operand:SI 0 "register_operand" "")
  2362.     (neg:SI (eq:SI (match_operand:SI 1 "register_operand" "")
  2363.                (const_int 0))))
  2364.    (clobber (reg:CC 0))]
  2365.   ""
  2366.   [(set (reg:CC_NOOV 0) (compare:CC_NOOV (neg:SI (match_dup 1))
  2367.                      (const_int 0)))
  2368.    (set (match_dup 0) (neg:SI (geu:SI (reg:CC 0) (const_int 0))))]
  2369.   "")
  2370.  
  2371. (define_split
  2372.   [(set (match_operand:SI 0 "register_operand" "")
  2373.     (plus:SI (ne:SI (match_operand:SI 1 "register_operand" "")
  2374.             (const_int 0))
  2375.          (match_operand:SI 2 "register_operand" "")))
  2376.    (clobber (reg:CC 0))]
  2377.   ""
  2378.   [(set (reg:CC_NOOV 0) (compare:CC_NOOV (neg:SI (match_dup 1))
  2379.                      (const_int 0)))
  2380.    (set (match_dup 0) (plus:SI (ltu:SI (reg:CC 0) (const_int 0))
  2381.                    (match_dup 2)))]
  2382.   "")
  2383.  
  2384. (define_split
  2385.   [(set (match_operand:SI 0 "register_operand" "")
  2386.     (minus:SI (match_operand:SI 2 "register_operand" "")
  2387.           (ne:SI (match_operand:SI 1 "register_operand" "")
  2388.              (const_int 0))))
  2389.    (clobber (reg:CC 0))]
  2390.   ""
  2391.   [(set (reg:CC_NOOV 0) (compare:CC_NOOV (neg:SI (match_dup 1))
  2392.                      (const_int 0)))
  2393.    (set (match_dup 0) (minus:SI (match_dup 2)
  2394.                 (geu:SI (match_dup 1) (const_int 0))))]
  2395.   "")
  2396.  
  2397. (define_split
  2398.   [(set (match_operand:SI 0 "register_operand" "")
  2399.     (plus:SI (eq:SI (match_operand:SI 1 "register_operand" "")
  2400.             (const_int 0))
  2401.          (match_operand:SI 2 "register_operand" "")))
  2402.    (clobber (reg:CC 0))]
  2403.   ""
  2404.   [(set (reg:CC_NOOV 0) (compare:CC_NOOV (neg:SI (match_dup 1))
  2405.                      (const_int 0)))
  2406.    (set (match_dup 0) (plus:SI (geu:SI (reg:CC 0) (const_int 0))
  2407.                    (match_dup 2)))]
  2408.   "")
  2409.  
  2410. (define_split
  2411.   [(set (match_operand:SI 0 "register_operand" "")
  2412.     (minus:SI (match_operand:SI 2 "register_operand" "")
  2413.           (eq:SI (match_operand:SI 1 "register_operand" "")
  2414.                 (const_int 0))))
  2415.    (clobber (reg:CC 0))]
  2416.   ""
  2417.   [(set (reg:CC_NOOV 0) (compare:CC_NOOV (neg:SI (match_dup 1))
  2418.                      (const_int 0)))
  2419.    (set (match_dup 0) (minus:SI (match_dup 2)
  2420.                 (geu:SI (match_dup 1) (const_int 0))))]
  2421.   "")
  2422.  
  2423. ;; Peepholes go at the end.
  2424.  
  2425. ;; Optimize the case of following a reg-reg move with a test
  2426. ;; of reg just moved.
  2427.  
  2428. (define_peephole
  2429.   [(set (match_operand:SI 0 "register_operand" "=r")
  2430.     (match_operand:SI 1 "register_operand" "r"))
  2431.    (set (reg:CC 0)
  2432.     (compare:CC (match_operand:SI 2 "register_operand" "r")
  2433.             (const_int 0)))]
  2434.   "rtx_equal_p (operands[2], operands[0])
  2435.    || rtx_equal_p (operands[2], operands[1])"
  2436.   "orcc %1,%%g0,%0"
  2437.   [(set_attr "type" "move")])
  2438.  
  2439. ;; Do {sign,zero}-extended compares somewhat more efficiently.
  2440. ;; ??? Is this now the Right Way to do this?  Or will SCRATCH
  2441. ;;     eventually have some impact here?
  2442.  
  2443. (define_peephole
  2444.   [(set (match_operand:HI 0 "register_operand" "")
  2445.     (match_operand:HI 1 "memory_operand" ""))
  2446.    (set (match_operand:SI 2 "register_operand" "")
  2447.     (sign_extend:SI (match_dup 0)))
  2448.    (set (reg:CC 0)
  2449.     (compare:CC (match_dup 2)
  2450.             (const_int 0)))]
  2451.   ""
  2452.   "ldsh %1,%0\;orcc %0,%%g0,%2")
  2453.  
  2454. (define_peephole
  2455.   [(set (match_operand:QI 0 "register_operand" "")
  2456.     (match_operand:QI 1 "memory_operand" ""))
  2457.    (set (match_operand:SI 2 "register_operand" "")
  2458.     (sign_extend:SI (match_dup 0)))
  2459.    (set (reg:CC 0)
  2460.     (compare:CC (match_dup 2)
  2461.             (const_int 0)))]
  2462.   ""
  2463.   "ldsb %1,%0\;orcc %0,%%g0,%2")
  2464.  
  2465. (define_peephole
  2466.   [(set (match_operand:HI 0 "register_operand" "")
  2467.     (match_operand:HI 1 "memory_operand" ""))
  2468.    (set (match_operand:SI 2 "register_operand" "")
  2469.     (sign_extend:SI (match_dup 0)))]
  2470.   "dead_or_set_p (insn, operands[0])"
  2471.   "*
  2472. {
  2473.   warning (\"bad peephole\");
  2474.   if (! MEM_VOLATILE_P (operands[1]))
  2475.     abort ();
  2476.   return \"ldsh %1,%2\";
  2477. }")
  2478.  
  2479. (define_peephole
  2480.   [(set (match_operand:QI 0 "register_operand" "")
  2481.     (match_operand:QI 1 "memory_operand" ""))
  2482.    (set (match_operand:SI 2 "register_operand" "")
  2483.     (sign_extend:SI (match_dup 0)))]
  2484.   "dead_or_set_p (insn, operands[0])"
  2485.   "*
  2486. {
  2487.   warning (\"bad peephole\");
  2488.   if (! MEM_VOLATILE_P (operands[1]))
  2489.     abort ();
  2490.   return \"ldsb %1,%2\";
  2491. }")
  2492.  
  2493. ;; Floating-point move peepholes
  2494.  
  2495. (define_peephole
  2496.   [(set (match_operand:SI 0 "register_operand" "=r")
  2497.     (lo_sum:SI (match_dup 0)
  2498.            (match_operand:SI 1 "immediate_operand" "i")))
  2499.    (set (match_operand:DF 2 "register_operand" "=fr")
  2500.     (mem:DF (match_dup 0)))]
  2501.   "RTX_UNCHANGING_P (operands[1]) && reg_unused_after (operands[0], insn)"
  2502.   "ldd [%0+%%lo(%a1)],%2")
  2503.  
  2504. (define_peephole
  2505.   [(set (match_operand:SI 0 "register_operand" "=r")
  2506.     (lo_sum:SI (match_dup 0)
  2507.            (match_operand:SI 1 "immediate_operand" "i")))
  2508.    (set (match_operand:SF 2 "register_operand" "=fr")
  2509.     (mem:SF (match_dup 0)))]
  2510.   "RTX_UNCHANGING_P (operands[1]) && reg_unused_after (operands[0], insn)"
  2511.   "ld [%0+%%lo(%a1)],%2")
  2512.  
  2513. ;; Return peepholes.  First the "normal" ones
  2514.  
  2515. (define_insn ""
  2516.   [(set (match_operand:SI 0 "restore_operand" "")
  2517.     (match_operand:SI 1 "arith_operand" "rI"))
  2518.    (return)]
  2519.   "! TARGET_EPILOGUE"
  2520.   "ret\;restore %%g0,%1,%Y0"
  2521.   [(set_attr "type" "multi")])
  2522.  
  2523. (define_insn ""
  2524.   [(set (match_operand:SI 0 "restore_operand" "")
  2525.     (plus:SI (match_operand:SI 1 "register_operand" "r%")
  2526.          (match_operand:SI 2 "arith_operand" "rI")))
  2527.    (return)]
  2528.   "! TARGET_EPILOGUE"
  2529.   "ret\;restore %r1,%2,%Y0"
  2530.   [(set_attr "type" "multi")])
  2531.  
  2532. (define_insn ""
  2533.   [(set (match_operand:SI 0 "restore_operand" "")
  2534.     (minus:SI (match_operand:SI 1 "register_operand" "r")
  2535.           (match_operand:SI 2 "small_int" "I")))
  2536.    (return)]
  2537.   "! TARGET_EPILOGUE"
  2538.   "ret\;restore %1,-(%2),%Y0"
  2539.   [(set_attr "type" "multi")])
  2540.  
  2541. ;; The following pattern is only generated by delayed-branch scheduling,
  2542. ;; when the insn winds up in the epilogue.
  2543. (define_insn ""
  2544.   [(set (reg:SF 32)
  2545.     (match_operand:SF 0 "register_operand" "f"))
  2546.    (return)]
  2547.   "! TARGET_EPILOGUE"
  2548.   "ret\;fmovs %0,%%f0")
  2549.  
  2550. ;; Now peepholes to go a call followed by a jump.
  2551.  
  2552. (define_peephole
  2553.   [(parallel [(set (match_operand 0 "" "")
  2554.            (call (mem:SI (match_operand:SI 1 "call_operand_address" "S,r"))
  2555.              (match_operand 2 "" "")))
  2556.           (clobber (reg:SI 15))])
  2557.    (set (pc) (label_ref (match_operand 3 "" "")))]
  2558.   "short_branch (INSN_UID (insn), INSN_UID (operands[3]))"
  2559.   "*
  2560. {
  2561.   if (TARGET_SUN_ASM && GET_CODE (operands[1]) == REG)
  2562.     return \"jmpl %a1,%%o7\;add %%o7,(%l3-.-4),%%o7\";
  2563.   else
  2564.     return \"call %a1,%2\;add %%o7,(%l3-.-4),%%o7\";
  2565. }")
  2566.  
  2567. (define_peephole
  2568.   [(parallel [(call (mem:SI (match_operand:SI 0 "call_operand_address" "S,r"))
  2569.             (match_operand 1 "" ""))
  2570.           (clobber (reg:SI 15))])
  2571.    (set (pc) (label_ref (match_operand 2 "" "")))]
  2572.   "short_branch (INSN_UID (insn), INSN_UID (operands[2]))"
  2573.   "*
  2574. {
  2575.   if (TARGET_SUN_ASM && GET_CODE (operands[0]) == REG)
  2576.     return \"jmpl %a0,%%o7\;add %%o7,(%l2-.-4),%%o7\";
  2577.   else
  2578.     return \"call %a0,%1\;add %%o7,(%l2-.-4),%%o7\";
  2579. }")
  2580.  
  2581. (define_peephole
  2582.   [(parallel [(set (match_operand:SI 0 "register_operand" "=r")
  2583.            (minus:SI (match_operand:SI 1 "reg_or_0_operand" "rJ")
  2584.                  (reg:SI 0)))
  2585.           (clobber (reg:SI 0))])
  2586.    (set (reg:SI 0) (compare (match_dup 0) (const_int 0)))]
  2587.   ""
  2588.   "subxcc %r1,0,%0"
  2589.   [(set_attr "type" "compare")])
  2590.  
  2591. ;;- Local variables:
  2592. ;;- mode:emacs-lisp
  2593. ;;- comment-start: ";;- "
  2594. ;;- eval: (set-syntax-table (copy-sequence (syntax-table)))
  2595. ;;- eval: (modify-syntax-entry ?[ "(]")
  2596. ;;- eval: (modify-syntax-entry ?] ")[")
  2597. ;;- eval: (modify-syntax-entry ?{ "(}")
  2598. ;;- eval: (modify-syntax-entry ?} "){")
  2599. ;;- End:
  2600.