home *** CD-ROM | disk | FTP | other *** search
/ Fresh Fish 4 / FreshFish_May-June1994.bin / bbs / gnu / gcc-2.5.8-src.lha / src / amiga / gcc-2.5.8 / config / sparc / sparc.md < prev    next >
Encoding:
Text File  |  1993-12-09  |  103.1 KB  |  3,517 lines

  1. ;;- Machine description for SPARC chip for GNU C compiler
  2. ;;   Copyright (C) 1987, 1988, 1989, 1992, 1993 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. ;; type "call_no_delay_slot" is a call followed by an unimp instruction.
  30.  
  31. (define_attr "type"
  32.   "move,unary,binary,compare,load,store,uncond_branch,branch,call,call_no_delay_slot,address,fpload,fpstore,fp,fpcmp,fpmul,fpdiv,fpsqrt,multi,misc"
  33.   (const_string "binary"))
  34.  
  35. ;; Set true if insn uses call-clobbered intermediate register.
  36. (define_attr "use_clobbered" "false,true"
  37.   (if_then_else (and (eq_attr "type" "address")
  38.              (match_operand 0 "clobbered_register" ""))
  39.          (const_string "true")
  40.         (const_string "false")))
  41.  
  42. ;; Length (in # of insns).
  43. (define_attr "length" ""
  44.   (cond [(eq_attr "type" "load,fpload")
  45.      (if_then_else (match_operand 1 "symbolic_memory_operand" "")
  46.                (const_int 2) (const_int 1))
  47.  
  48.      (eq_attr "type" "store,fpstore")
  49.      (if_then_else (match_operand 0 "symbolic_memory_operand" "")
  50.                (const_int 2) (const_int 1))
  51.  
  52.      (eq_attr "type" "address") (const_int 2)
  53.  
  54.      (eq_attr "type" "binary")
  55.      (if_then_else (ior (match_operand 2 "arith_operand" "")
  56.                 (match_operand 2 "arith_double_operand" ""))
  57.                (const_int 1) (const_int 3))
  58.  
  59.      (eq_attr "type" "multi") (const_int 2)
  60.  
  61.      (eq_attr "type" "move,unary")
  62.      (if_then_else (ior (match_operand 1 "arith_operand" "")
  63.                 (match_operand 1 "arith_double_operand" ""))
  64.                (const_int 1) (const_int 2))]
  65.  
  66.     (const_int 1)))
  67.  
  68. (define_asm_attributes
  69.   [(set_attr "length" "1")
  70.    (set_attr "type" "multi")])
  71.  
  72. ;; Attributes for instruction and branch scheduling
  73.  
  74. (define_attr "in_call_delay" "false,true"
  75.   (cond [(eq_attr "type" "uncond_branch,branch,call,call_no_delay_slot,multi")
  76.          (const_string "false")
  77.      (eq_attr "type" "load,fpload,store,fpstore")
  78.          (if_then_else (eq_attr "length" "1")
  79.                   (const_string "true")
  80.                   (const_string "false"))
  81.      (eq_attr "type" "address")
  82.          (if_then_else (eq_attr "use_clobbered" "false")
  83.                   (const_string "true")
  84.                   (const_string "false"))]
  85.     (if_then_else (eq_attr "length" "1")
  86.               (const_string "true")
  87.               (const_string "false"))))
  88.  
  89. (define_delay (eq_attr "type" "call")
  90.   [(eq_attr "in_call_delay" "true") (nil) (nil)])
  91.  
  92. ;; ??? Should implement the notion of predelay slots for floating point
  93. ;; branches.  This would allow us to remove the nop always inserted before
  94. ;; a floating point branch.
  95.  
  96. ;; ??? It is OK for fill_simple_delay_slots to put load/store instructions
  97. ;; in a delay slot, but it is not OK for fill_eager_delay_slots to do so.
  98. ;; This is because doing so will add several pipeline stalls to the path
  99. ;; that the load/store did not come from.  Unfortunately, there is no way
  100. ;; to prevent fill_eager_delay_slots from using load/store without completely
  101. ;; disabling them.  For the SPEC benchmark set, this is a serious lose,
  102. ;; because it prevents us from moving back the final store of inner loops.
  103.  
  104. (define_attr "in_branch_delay" "false,true"
  105.   (if_then_else (and (eq_attr "type" "!uncond_branch,branch,call,call_no_delay_slot,multi")
  106.              (eq_attr "length" "1"))
  107.         (const_string "true")
  108.         (const_string "false")))
  109.  
  110. (define_attr "in_uncond_branch_delay" "false,true"
  111.   (if_then_else (and (eq_attr "type" "!uncond_branch,branch,call,call_no_delay_slot,multi")
  112.              (eq_attr "length" "1"))
  113.         (const_string "true")
  114.         (const_string "false")))
  115.  
  116. (define_attr "in_annul_branch_delay" "false,true"
  117.   (if_then_else (and (eq_attr "type" "!uncond_branch,branch,call,call_no_delay_slot,multi")
  118.              (eq_attr "length" "1"))
  119.         (const_string "true")
  120.         (const_string "false")))
  121.  
  122. (define_delay (eq_attr "type" "branch")
  123.   [(eq_attr "in_branch_delay" "true")
  124.    (nil) (eq_attr "in_annul_branch_delay" "true")])
  125.  
  126. (define_delay (eq_attr "type" "uncond_branch")
  127.   [(eq_attr "in_uncond_branch_delay" "true")
  128.    (nil) (nil)])
  129.    
  130. ;; Function units of the SPARC
  131.  
  132. ;; (define_function_unit {name} {num-units} {n-users} {test}
  133. ;;                       {ready-delay} {issue-delay} [{conflict-list}])
  134.  
  135. ;; The integer ALU.
  136. ;; (Noted only for documentation; units that take one cycle do not need to
  137. ;; be specified.)
  138.  
  139. ;; On the sparclite, integer multiply takes 1, 3, or 5 cycles depending on
  140. ;; the inputs.
  141.  
  142. ;; (define_function_unit "alu" 1 0
  143. ;;  (eq_attr "type" "unary,binary,move,address") 1 0)
  144.  
  145. ;; Memory with load-delay of 1 (i.e., 2 cycle load).
  146. (define_function_unit "memory" 1 1 (eq_attr "type" "load,fpload") 2 0)
  147.  
  148. ;; SPARC has two floating-point units: the FP ALU,
  149. ;; and the FP MUL/DIV/SQRT unit.
  150. ;; Instruction timings on the CY7C602 are as follows
  151. ;; FABSs    4
  152. ;; FADDs/d    5/5
  153. ;; FCMPs/d    4/4
  154. ;; FDIVs/d    23/37
  155. ;; FMOVs    4
  156. ;; FMULs/d    5/7
  157. ;; FNEGs    4
  158. ;; FSQRTs/d    34/63
  159. ;; FSUBs/d    5/5
  160. ;; FdTOi/s    5/5
  161. ;; FsTOi/d    5/5
  162. ;; FiTOs/d    9/5
  163.  
  164. ;; The CY7C602 can only support 2 fp isnsn simultaneously.
  165. ;; More insns cause the chip to stall.
  166.  
  167. (define_function_unit "fp_alu" 1 1 (eq_attr "type" "fp") 5 0)
  168. (define_function_unit "fp_mds" 1 1 (eq_attr "type" "fpmul") 7 0)
  169. (define_function_unit "fp_mds" 1 1 (eq_attr "type" "fpdiv") 37 0)
  170. (define_function_unit "fp_mds" 1 1 (eq_attr "type" "fpsqrt") 63 0)
  171.  
  172. ;; Compare instructions.
  173. ;; This controls RTL generation and register allocation.
  174.  
  175. ;; We generate RTL for comparisons and branches by having the cmpxx 
  176. ;; patterns store away the operands.  Then, the scc and bcc patterns
  177. ;; emit RTL for both the compare and the branch.
  178. ;;
  179. ;; We do this because we want to generate different code for an sne and
  180. ;; seq insn.  In those cases, if the second operand of the compare is not
  181. ;; const0_rtx, we want to compute the xor of the two operands and test
  182. ;; it against zero.
  183. ;;
  184. ;; We start with the DEFINE_EXPANDs, then then DEFINE_INSNs to match
  185. ;; the patterns.  Finally, we have the DEFINE_SPLITs for some of the scc
  186. ;; insns that actually require more than one machine instruction.
  187.  
  188. ;; Put cmpsi first among compare insns so it matches two CONST_INT operands.
  189.  
  190. (define_expand "cmpsi"
  191.   [(set (reg:CC 0)
  192.     (compare:CC (match_operand:SI 0 "register_operand" "")
  193.             (match_operand:SI 1 "arith_operand" "")))]
  194.   ""
  195.   "
  196. {
  197.   sparc_compare_op0 = operands[0];
  198.   sparc_compare_op1 = operands[1];
  199.   DONE;
  200. }")
  201.  
  202. (define_expand "cmpsf"
  203.   [(set (reg:CCFP 0)
  204.     (compare:CCFP (match_operand:SF 0 "register_operand" "")
  205.               (match_operand:SF 1 "register_operand" "")))]
  206.   "TARGET_FPU"
  207.   "
  208. {
  209.   sparc_compare_op0 = operands[0];
  210.   sparc_compare_op1 = operands[1];
  211.   DONE;
  212. }")
  213.  
  214. (define_expand "cmpdf"
  215.   [(set (reg:CCFP 0)
  216.     (compare:CCFP (match_operand:DF 0 "register_operand" "")
  217.               (match_operand:DF 1 "register_operand" "")))]
  218.   "TARGET_FPU"
  219.   "
  220. {
  221.   sparc_compare_op0 = operands[0];
  222.   sparc_compare_op1 = operands[1];
  223.   DONE;
  224. }")
  225.  
  226. (define_expand "cmptf"
  227.   [(set (reg:CCFP 0)
  228.     (compare:CCFP (match_operand:TF 0 "register_operand" "")
  229.               (match_operand:TF 1 "register_operand" "")))]
  230.   "TARGET_FPU"
  231.   "
  232. {
  233.   sparc_compare_op0 = operands[0];
  234.   sparc_compare_op1 = operands[1];
  235.   DONE;
  236. }")
  237.  
  238. ;; Next come the scc insns.  For seq, sne, sgeu, and sltu, we can do this
  239. ;; without jumps using the addx/subx instructions.  For the rest, we do
  240. ;; branches.  Seq_special and sne_special clobber the CC reg, because they
  241. ;; generate addcc/subcc instructions.
  242.  
  243. (define_expand "seq_special"
  244.   [(set (match_dup 3) (xor:SI (match_operand:SI 1 "register_operand" "")
  245.                   (match_operand:SI 2 "register_operand" "")))
  246.    (parallel [(set (match_operand:SI 0 "register_operand" "")
  247.            (eq:SI (match_dup 3) (const_int 0)))
  248.           (clobber (reg:CC 0))])]
  249.          
  250.   ""
  251.   "{ operands[3] = gen_reg_rtx (SImode); }")
  252.  
  253. (define_expand "sne_special"
  254.   [(set (match_dup 3) (xor:SI (match_operand:SI 1 "register_operand" "")
  255.                   (match_operand:SI 2 "register_operand" "")))
  256.    (parallel [(set (match_operand:SI 0 "register_operand" "")
  257.            (ne:SI (match_dup 3) (const_int 0)))
  258.           (clobber (reg:CC 0))])]
  259.   ""
  260.   "{ operands[3] = gen_reg_rtx (SImode); }")
  261.  
  262. (define_expand "seq"
  263.   [(set (match_operand:SI 0 "register_operand" "")
  264.     (eq:SI (match_dup 1) (const_int 0)))]
  265.   ""
  266.   "
  267. { if (GET_MODE (sparc_compare_op0) == SImode)
  268.     {
  269.       emit_insn (gen_seq_special (operands[0], sparc_compare_op0,
  270.                   sparc_compare_op1));
  271.       DONE;
  272.     }
  273.   else
  274.     operands[1] = gen_compare_reg (EQ, sparc_compare_op0, sparc_compare_op1);
  275. }")
  276.  
  277. (define_expand "sne"
  278.   [(set (match_operand:SI 0 "register_operand" "")
  279.     (ne:SI (match_dup 1) (const_int 0)))]
  280.   ""
  281.   "
  282. { if (GET_MODE (sparc_compare_op0) == SImode)
  283.     {
  284.       emit_insn (gen_sne_special (operands[0], sparc_compare_op0,
  285.                   sparc_compare_op1));
  286.       DONE;
  287.     }
  288.   else
  289.     operands[1] = gen_compare_reg (NE, sparc_compare_op0, sparc_compare_op1);
  290. }")
  291.  
  292. (define_expand "sgt"
  293.   [(set (match_operand:SI 0 "register_operand" "")
  294.     (gt:SI (match_dup 1) (const_int 0)))]
  295.   ""
  296.   "
  297. { operands[1] = gen_compare_reg (GT, sparc_compare_op0, sparc_compare_op1); }")
  298.  
  299. (define_expand "slt"
  300.   [(set (match_operand:SI 0 "register_operand" "")
  301.     (lt:SI (match_dup 1) (const_int 0)))]
  302.   ""
  303.   "
  304. { operands[1] = gen_compare_reg (LT, sparc_compare_op0, sparc_compare_op1); }")
  305.  
  306. (define_expand "sge"
  307.   [(set (match_operand:SI 0 "register_operand" "")
  308.     (ge:SI (match_dup 1) (const_int 0)))]
  309.   ""
  310.   "
  311. { operands[1] = gen_compare_reg (GE, sparc_compare_op0, sparc_compare_op1); }")
  312.  
  313. (define_expand "sle"
  314.   [(set (match_operand:SI 0 "register_operand" "")
  315.     (le:SI (match_dup 1) (const_int 0)))]
  316.   ""
  317.   "
  318. { operands[1] = gen_compare_reg (LE, sparc_compare_op0, sparc_compare_op1); }")
  319.  
  320. (define_expand "sgtu"
  321.   [(set (match_operand:SI 0 "register_operand" "")
  322.     (gtu:SI (match_dup 1) (const_int 0)))]
  323.   ""
  324.   "
  325. {
  326.   rtx tem;
  327.  
  328.   /* We can do ltu easily, so if both operands are registers, swap them and
  329.      do a LTU.  */
  330.   if ((GET_CODE (sparc_compare_op0) == REG
  331.        || GET_CODE (sparc_compare_op0) == SUBREG)
  332.       && (GET_CODE (sparc_compare_op1) == REG
  333.       || GET_CODE (sparc_compare_op1) == SUBREG))
  334.     {
  335.       tem = sparc_compare_op0;
  336.       sparc_compare_op0 = sparc_compare_op1;
  337.       sparc_compare_op1 = tem;
  338.       emit_insn (gen_sltu (operands[0]));
  339.       DONE;
  340.     }
  341.  
  342.   operands[1] = gen_compare_reg (LEU, sparc_compare_op0, sparc_compare_op1);
  343. }")
  344.  
  345. (define_expand "sltu"
  346.   [(set (match_operand:SI 0 "register_operand" "")
  347.     (ltu:SI (match_dup 1) (const_int 0)))]
  348.   ""
  349.   "
  350. { operands[1] = gen_compare_reg (LTU, sparc_compare_op0, sparc_compare_op1);
  351. }")
  352.  
  353. (define_expand "sgeu"
  354.   [(set (match_operand:SI 0 "register_operand" "")
  355.     (geu:SI (match_dup 1) (const_int 0)))]
  356.   ""
  357.   "
  358. { operands[1] = gen_compare_reg (GEU, sparc_compare_op0, sparc_compare_op1);
  359. }")
  360.  
  361. (define_expand "sleu"
  362.   [(set (match_operand:SI 0 "register_operand" "")
  363.     (leu:SI (match_dup 1) (const_int 0)))]
  364.   ""
  365.   "
  366. {
  367.   rtx tem;
  368.  
  369.   /* We can do geu easily, so if both operands are registers, swap them and
  370.      do a GEU.  */
  371.   if ((GET_CODE (sparc_compare_op0) == REG
  372.        || GET_CODE (sparc_compare_op0) == SUBREG)
  373.       && (GET_CODE (sparc_compare_op1) == REG
  374.       || GET_CODE (sparc_compare_op1) == SUBREG))
  375.     {
  376.       tem = sparc_compare_op0;
  377.       sparc_compare_op0 = sparc_compare_op1;
  378.       sparc_compare_op1 = tem;
  379.       emit_insn (gen_sgeu (operands[0]));
  380.       DONE;
  381.     }
  382.  
  383.   operands[1] = gen_compare_reg (LEU, sparc_compare_op0, sparc_compare_op1);
  384. }")
  385.  
  386. ;; Now the DEFINE_INSNs for the compare and scc cases.  First the compares.
  387.  
  388. (define_insn ""
  389.   [(set (reg:CC 0)
  390.     (compare:CC (match_operand:SI 0 "register_operand" "r")
  391.             (match_operand:SI 1 "arith_operand" "rI")))]
  392.   ""
  393.   "cmp %r0,%1"
  394.   [(set_attr "type" "compare")])
  395.  
  396. (define_insn ""
  397.   [(set (reg:CCFPE 0)
  398.     (compare:CCFPE (match_operand:DF 0 "register_operand" "f")
  399.                (match_operand:DF 1 "register_operand" "f")))]
  400.   "TARGET_FPU"
  401.   "fcmped %0,%1"
  402.   [(set_attr "type" "fpcmp")])
  403.  
  404. (define_insn ""
  405.   [(set (reg:CCFPE 0)
  406.     (compare:CCFPE (match_operand:SF 0 "register_operand" "f")
  407.                (match_operand:SF 1 "register_operand" "f")))]
  408.   "TARGET_FPU"
  409.   "fcmpes %0,%1"
  410.   [(set_attr "type" "fpcmp")])
  411.  
  412. (define_insn ""
  413.   [(set (reg:CCFPE 0)
  414.     (compare:CCFPE (match_operand:TF 0 "register_operand" "f")
  415.                (match_operand:TF 1 "register_operand" "f")))]
  416.   "TARGET_FPU"
  417.   "fcmpeq %0,%1"
  418.   [(set_attr "type" "fpcmp")])
  419.  
  420. (define_insn ""
  421.   [(set (reg:CCFP 0)
  422.     (compare:CCFP (match_operand:DF 0 "register_operand" "f")
  423.               (match_operand:DF 1 "register_operand" "f")))]
  424.   "TARGET_FPU"
  425.   "fcmpd %0,%1"
  426.   [(set_attr "type" "fpcmp")])
  427.  
  428. (define_insn ""
  429.   [(set (reg:CCFP 0)
  430.     (compare:CCFP (match_operand:SF 0 "register_operand" "f")
  431.               (match_operand:SF 1 "register_operand" "f")))]
  432.   "TARGET_FPU"
  433.   "fcmps %0,%1"
  434.   [(set_attr "type" "fpcmp")])
  435.  
  436. (define_insn ""
  437.   [(set (reg:CCFP 0)
  438.     (compare:CCFP (match_operand:TF 0 "register_operand" "f")
  439.               (match_operand:TF 1 "register_operand" "f")))]
  440.   "TARGET_FPU"
  441.   "fcmpq %0,%1"
  442.   [(set_attr "type" "fpcmp")])
  443.  
  444. ;; The SEQ and SNE patterns are special because they can be done
  445. ;; without any branching and do not involve a COMPARE.
  446.  
  447. (define_insn ""
  448.   [(set (match_operand:SI 0 "register_operand" "=r")
  449.     (ne:SI (match_operand:SI 1 "register_operand" "r") (const_int 0)))
  450.    (clobber (reg:CC 0))]
  451.   ""
  452.   "subcc %%g0,%1,%%g0\;addx %%g0,0,%0"
  453.   [(set_attr "type" "unary")
  454.    (set_attr "length" "2")])
  455.  
  456. (define_insn ""
  457.   [(set (match_operand:SI 0 "register_operand" "=r")
  458.     (neg:SI (ne:SI (match_operand:SI 1 "register_operand" "r")
  459.                (const_int 0))))
  460.    (clobber (reg:CC 0))]
  461.   ""
  462.   "subcc %%g0,%1,%%g0\;subx %%g0,0,%0"
  463.   [(set_attr "type" "unary")
  464.    (set_attr "length" "2")])
  465.  
  466. (define_insn ""
  467.   [(set (match_operand:SI 0 "register_operand" "=r")
  468.     (eq:SI (match_operand:SI 1 "register_operand" "r") (const_int 0)))
  469.    (clobber (reg:CC 0))]
  470.   ""
  471.   "subcc %%g0,%1,%%g0\;subx %%g0,-1,%0"
  472.   [(set_attr "type" "unary")
  473.    (set_attr "length" "2")])
  474.  
  475. (define_insn ""
  476.   [(set (match_operand:SI 0 "register_operand" "=r")
  477.     (neg:SI (eq:SI (match_operand:SI 1 "register_operand" "r")
  478.                (const_int 0))))
  479.    (clobber (reg:CC 0))]
  480.   ""
  481.   "subcc %%g0,%1,%%g0\;addx %%g0,-1,%0"
  482.   [(set_attr "type" "unary")
  483.    (set_attr "length" "2")])
  484.  
  485. ;; We can also do (x + (i == 0)) and related, so put them in.
  486.  
  487. (define_insn ""
  488.   [(set (match_operand:SI 0 "register_operand" "=r")
  489.     (plus:SI (ne:SI (match_operand:SI 1 "register_operand" "r")
  490.             (const_int 0))
  491.          (match_operand:SI 2 "register_operand" "r")))
  492.    (clobber (reg:CC 0))]
  493.   ""
  494.   "subcc %%g0,%1,%%g0\;addx %2,0,%0"
  495.   [(set_attr "length" "2")])
  496.  
  497. (define_insn ""
  498.   [(set (match_operand:SI 0 "register_operand" "=r")
  499.     (minus:SI (match_operand:SI 2 "register_operand" "r")
  500.           (ne:SI (match_operand:SI 1 "register_operand" "r")
  501.              (const_int 0))))
  502.    (clobber (reg:CC 0))]
  503.   ""
  504.   "subcc %%g0,%1,%%g0\;subx %2,0,%0"
  505.   [(set_attr "length" "2")])
  506.  
  507. (define_insn ""
  508.   [(set (match_operand:SI 0 "register_operand" "=r")
  509.     (plus:SI (eq:SI (match_operand:SI 1 "register_operand" "r")
  510.             (const_int 0))
  511.          (match_operand:SI 2 "register_operand" "r")))
  512.    (clobber (reg:CC 0))]
  513.   ""
  514.   "subcc %%g0,%1,%%g0\;subx %2,-1,%0"
  515.   [(set_attr "length" "2")])
  516.  
  517. (define_insn ""
  518.   [(set (match_operand:SI 0 "register_operand" "=r")
  519.     (minus:SI (match_operand:SI 2 "register_operand" "r")
  520.           (eq:SI (match_operand:SI 1 "register_operand" "r")
  521.              (const_int 0))))
  522.    (clobber (reg:CC 0))]
  523.   ""
  524.   "subcc %%g0,%1,%%g0\;addx %2,-1,%0"
  525.   [(set_attr "length" "2")])
  526.  
  527. ;; We can also do GEU and LTU directly, but these operate after a
  528. ;; compare.
  529.  
  530. (define_insn ""
  531.   [(set (match_operand:SI 0 "register_operand" "=r")
  532.     (ltu:SI (reg:CC 0) (const_int 0)))]
  533.   ""
  534.   "addx %%g0,0,%0"
  535.   [(set_attr "type" "misc")])
  536.  
  537. (define_insn ""
  538.   [(set (match_operand:SI 0 "register_operand" "=r")
  539.     (neg:SI (ltu:SI (reg:CC 0) (const_int 0))))]
  540.   ""
  541.   "subx %%g0,0,%0"
  542.   [(set_attr "type" "misc")])
  543.  
  544. ;; ??? Combine should canonicalize these next two to the same pattern.
  545. (define_insn ""
  546.   [(set (match_operand:SI 0 "register_operand" "=r")
  547.     (minus:SI (neg:SI (ltu:SI (reg:CC 0) (const_int 0)))
  548.           (match_operand:SI 1 "arith_operand" "rI")))]
  549.   ""
  550.   "subx %%g0,%1,%0"
  551.   [(set_attr "type" "unary")])
  552.  
  553. (define_insn ""
  554.   [(set (match_operand:SI 0 "register_operand" "=r")
  555.     (neg:SI (plus:SI (ltu:SI (reg:CC 0) (const_int 0))
  556.              (match_operand:SI 1 "arith_operand" "rI"))))]
  557.   ""
  558.   "subx %%g0,%1,%0"
  559.   [(set_attr "type" "unary")])
  560.  
  561. (define_insn ""
  562.   [(set (match_operand:SI 0 "register_operand" "=r")
  563.     (geu:SI (reg:CC 0) (const_int 0)))]
  564.   ""
  565.   "subx %%g0,-1,%0"
  566.   [(set_attr "type" "misc")])
  567.  
  568. (define_insn ""
  569.   [(set (match_operand:SI 0 "register_operand" "=r")
  570.     (neg:SI (geu:SI (reg:CC 0) (const_int 0))))]
  571.   ""
  572.   "addx %%g0,-1,%0"
  573.   [(set_attr "type" "misc")])
  574.  
  575. ;; We can also do (x + ((unsigned) i >= 0)) and related, so put them in.
  576.  
  577. (define_insn ""
  578.   [(set (match_operand:SI 0 "register_operand" "=r")
  579.     (plus:SI (ltu:SI (reg:CC 0) (const_int 0))
  580.          (match_operand:SI 1 "arith_operand" "rI")))]
  581.   ""
  582.   "addx %%g0,%1,%0"
  583.   [(set_attr "type" "unary")])
  584.  
  585. (define_insn ""
  586.   [(set (match_operand:SI 0 "register_operand" "=r")
  587.     (plus:SI (ltu:SI (reg:CC 0) (const_int 0))
  588.          (plus:SI (match_operand:SI 1 "arith_operand" "%r")
  589.               (match_operand:SI 2 "arith_operand" "rI"))))]
  590.   ""
  591.   "addx %1,%2,%0")
  592.  
  593. (define_insn ""
  594.   [(set (match_operand:SI 0 "register_operand" "=r")
  595.     (minus:SI (match_operand:SI 1 "register_operand" "r")
  596.           (ltu:SI (reg:CC 0) (const_int 0))))]
  597.   ""
  598.   "subx %1,0,%0"
  599.   [(set_attr "type" "unary")])
  600.  
  601. ;; ??? Combine should canonicalize these next two to the same pattern.
  602. (define_insn ""
  603.   [(set (match_operand:SI 0 "register_operand" "=r")
  604.     (minus:SI (minus:SI (match_operand:SI 1 "register_operand" "r")
  605.                 (match_operand:SI 2 "arith_operand" "rI"))
  606.           (ltu:SI (reg:CC 0) (const_int 0))))]
  607.   ""
  608.   "subx %1,%2,%0")
  609.  
  610. (define_insn ""
  611.   [(set (match_operand:SI 0 "register_operand" "=r")
  612.     (minus:SI (match_operand:SI 1 "register_operand" "r")
  613.           (plus:SI (ltu:SI (reg:CC 0) (const_int 0))
  614.                (match_operand:SI 2 "arith_operand" "rI"))))]
  615.   ""
  616.   "subx %1,%2,%0")
  617.  
  618. (define_insn ""
  619.   [(set (match_operand:SI 0 "register_operand" "=r")
  620.     (plus:SI (geu:SI (reg:CC 0) (const_int 0))
  621.          (match_operand:SI 1 "register_operand" "r")))]
  622.   ""
  623.   "subx %1,-1,%0"
  624.   [(set_attr "type" "unary")])
  625.  
  626. (define_insn ""
  627.   [(set (match_operand:SI 0 "register_operand" "=r")
  628.     (minus:SI (match_operand:SI 1 "register_operand" "r")
  629.           (geu:SI (reg:CC 0) (const_int 0))))]
  630.   ""
  631.   "addx %1,-1,%0"
  632.   [(set_attr "type" "unary")])
  633.  
  634. ;; Now we have the generic scc insns.  These will be done using a jump.
  635. ;; We have to exclude the cases above, since we will not want combine to
  636. ;; turn something that does not require a jump into something that does.
  637. (define_insn ""
  638.   [(set (match_operand:SI 0 "register_operand" "=r")
  639.     (match_operator:SI 1 "noov_compare_op" [(reg 0) (const_int 0)]))]
  640.   ""
  641.   "* return output_scc_insn (operands, insn); "
  642.   [(set_attr "type" "multi")
  643.    (set_attr "length" "3")])
  644.  
  645. ;; These control RTL generation for conditional jump insns
  646.  
  647. (define_expand "beq"
  648.   [(set (pc)
  649.     (if_then_else (eq (match_dup 1) (const_int 0))
  650.               (label_ref (match_operand 0 "" ""))
  651.               (pc)))]
  652.   ""
  653.   "
  654. { operands[1] = gen_compare_reg (EQ, sparc_compare_op0, sparc_compare_op1); }")
  655.  
  656. (define_expand "bne"
  657.   [(set (pc)
  658.     (if_then_else (ne (match_dup 1) (const_int 0))
  659.               (label_ref (match_operand 0 "" ""))
  660.               (pc)))]
  661.   ""
  662.   "
  663. { operands[1] = gen_compare_reg (NE, sparc_compare_op0, sparc_compare_op1); }")
  664.  
  665. (define_expand "bgt"
  666.   [(set (pc)
  667.     (if_then_else (gt (match_dup 1) (const_int 0))
  668.               (label_ref (match_operand 0 "" ""))
  669.               (pc)))]
  670.   ""
  671.   "
  672. { operands[1] = gen_compare_reg (GT, sparc_compare_op0, sparc_compare_op1); }")
  673.  
  674. (define_expand "bgtu"
  675.   [(set (pc)
  676.     (if_then_else (gtu (match_dup 1) (const_int 0))
  677.               (label_ref (match_operand 0 "" ""))
  678.               (pc)))]
  679.   ""
  680.   "
  681. { operands[1] = gen_compare_reg (GTU, sparc_compare_op0, sparc_compare_op1);
  682. }")
  683.  
  684. (define_expand "blt"
  685.   [(set (pc)
  686.     (if_then_else (lt (match_dup 1) (const_int 0))
  687.               (label_ref (match_operand 0 "" ""))
  688.               (pc)))]
  689.   ""
  690.   "
  691. { operands[1] = gen_compare_reg (LT, sparc_compare_op0, sparc_compare_op1); }")
  692.  
  693. (define_expand "bltu"
  694.   [(set (pc)
  695.     (if_then_else (ltu (match_dup 1) (const_int 0))
  696.               (label_ref (match_operand 0 "" ""))
  697.               (pc)))]
  698.   ""
  699.   "
  700. { operands[1] = gen_compare_reg (LTU, sparc_compare_op0, sparc_compare_op1);
  701. }")
  702.  
  703. (define_expand "bge"
  704.   [(set (pc)
  705.     (if_then_else (ge (match_dup 1) (const_int 0))
  706.               (label_ref (match_operand 0 "" ""))
  707.               (pc)))]
  708.   ""
  709.   "
  710. { operands[1] = gen_compare_reg (GE, sparc_compare_op0, sparc_compare_op1); }")
  711.  
  712. (define_expand "bgeu"
  713.   [(set (pc)
  714.     (if_then_else (geu (match_dup 1) (const_int 0))
  715.               (label_ref (match_operand 0 "" ""))
  716.               (pc)))]
  717.   ""
  718.   "
  719. { operands[1] = gen_compare_reg (GEU, sparc_compare_op0, sparc_compare_op1);
  720. }")
  721.  
  722. (define_expand "ble"
  723.   [(set (pc)
  724.     (if_then_else (le (match_dup 1) (const_int 0))
  725.               (label_ref (match_operand 0 "" ""))
  726.               (pc)))]
  727.   ""
  728.   "
  729. { operands[1] = gen_compare_reg (LE, sparc_compare_op0, sparc_compare_op1); }")
  730.  
  731. (define_expand "bleu"
  732.   [(set (pc)
  733.     (if_then_else (leu (match_dup 1) (const_int 0))
  734.               (label_ref (match_operand 0 "" ""))
  735.               (pc)))]
  736.   ""
  737.   "
  738. { operands[1] = gen_compare_reg (LEU, sparc_compare_op0, sparc_compare_op1);
  739. }")
  740.  
  741. ;; Now match both normal and inverted jump.
  742.  
  743. (define_insn ""
  744.   [(set (pc)
  745.     (if_then_else (match_operator 0 "noov_compare_op"
  746.                       [(reg 0) (const_int 0)])
  747.               (label_ref (match_operand 1 "" ""))
  748.               (pc)))]
  749.   ""
  750.   "*
  751. {
  752.   return output_cbranch (operands[0], 1, 0,
  753.              final_sequence && INSN_ANNULLED_BRANCH_P (insn),
  754.              ! final_sequence);
  755. }"
  756.   [(set_attr "type" "branch")])
  757.  
  758. (define_insn ""
  759.   [(set (pc)
  760.     (if_then_else (match_operator 0 "noov_compare_op"
  761.                       [(reg 0) (const_int 0)])
  762.               (pc)
  763.               (label_ref (match_operand 1 "" ""))))]
  764.   ""
  765.   "*
  766. {
  767.   return output_cbranch (operands[0], 1, 1,
  768.              final_sequence && INSN_ANNULLED_BRANCH_P (insn),
  769.              ! final_sequence);
  770. }"
  771.   [(set_attr "type" "branch")])
  772.  
  773. ;; Move instructions
  774.  
  775. (define_expand "movqi"
  776.   [(set (match_operand:QI 0 "general_operand" "")
  777.     (match_operand:QI 1 "general_operand" ""))]
  778.   ""
  779.   "
  780. {
  781.   if (emit_move_sequence (operands, QImode))
  782.     DONE;
  783. }")
  784.  
  785. (define_insn ""
  786.   [(set (match_operand:QI 0 "reg_or_nonsymb_mem_operand" "=r,r,r,Q")
  787.     (match_operand:QI 1 "move_operand" "rI,K,Q,rJ"))]
  788.   "register_operand (operands[0], QImode)
  789.    || register_operand (operands[1], QImode)
  790.    || operands[1] == const0_rtx"
  791.   "@
  792.    mov %1,%0
  793.    sethi %%hi(%a1),%0
  794.    ldub %1,%0
  795.    stb %r1,%0"
  796.   [(set_attr "type" "move,move,load,store")
  797.    (set_attr "length" "*,1,*,1")])
  798.  
  799. (define_insn ""
  800.   [(set (match_operand:QI 0 "register_operand" "=r")
  801.     (subreg:QI (lo_sum:SI (match_operand:QI 1 "register_operand" "r")
  802.                   (match_operand 2 "immediate_operand" "in")) 0))]
  803.   ""
  804.   "or %1,%%lo(%a2),%0"
  805.   [(set_attr "length" "1")])
  806.  
  807. (define_insn ""
  808.   [(set (mem:QI (match_operand:SI 0 "symbolic_operand" ""))
  809.     (match_operand:QI 1 "reg_or_0_operand" "rJ"))
  810.    (clobber (match_scratch:SI 2 "=&r"))]
  811.   ""
  812.   "sethi %%hi(%a0),%2\;stb %r1,[%2+%%lo(%a0)]"
  813.   [(set_attr "type" "store")
  814.    (set_attr "length" "2")])
  815.  
  816. (define_expand "movhi"
  817.   [(set (match_operand:HI 0 "general_operand" "")
  818.     (match_operand:HI 1 "general_operand" ""))]
  819.   ""
  820.   "
  821. {
  822.   if (emit_move_sequence (operands, HImode))
  823.     DONE;
  824. }")
  825.  
  826. (define_insn ""
  827.   [(set (match_operand:HI 0 "reg_or_nonsymb_mem_operand" "=r,r,r,Q")
  828.     (match_operand:HI 1 "move_operand" "rI,K,Q,rJ"))]
  829.   "register_operand (operands[0], HImode)
  830.    || register_operand (operands[1], HImode)
  831.    || operands[1] == const0_rtx"
  832.   "@
  833.    mov %1,%0
  834.    sethi %%hi(%a1),%0
  835.    lduh %1,%0
  836.    sth %r1,%0"
  837.   [(set_attr "type" "move,move,load,store")
  838.    (set_attr "length" "*,1,*,1")])
  839.  
  840. (define_insn ""
  841.   [(set (match_operand:HI 0 "register_operand" "=r")
  842.     (lo_sum:HI (match_operand:HI 1 "register_operand" "r")
  843.            (match_operand 2 "immediate_operand" "in")))]
  844.   ""
  845.   "or %1,%%lo(%a2),%0"
  846.   [(set_attr "length" "1")])
  847.  
  848. (define_insn ""
  849.   [(set (mem:HI (match_operand:SI 0 "symbolic_operand" ""))
  850.     (match_operand:HI 1 "reg_or_0_operand" "rJ"))
  851.    (clobber (match_scratch:SI 2 "=&r"))]
  852.   ""
  853.   "sethi %%hi(%a0),%2\;sth %r1,[%2+%%lo(%a0)]"
  854.   [(set_attr "type" "store")
  855.    (set_attr "length" "2")])
  856.  
  857. (define_expand "movsi"
  858.   [(set (match_operand:SI 0 "general_operand" "")
  859.     (match_operand:SI 1 "general_operand" ""))]
  860.   ""
  861.   "
  862. {
  863.   if (emit_move_sequence (operands, SImode))
  864.     DONE;
  865. }")
  866.  
  867. ;; We must support both 'r' and 'f' registers here, because combine may
  868. ;; convert SFmode hard registers to SImode hard registers when simplifying
  869. ;; subreg sets.
  870.  
  871. ;; We cannot combine the similar 'r' and 'f' constraints, because it causes
  872. ;; problems with register allocation.  Reload might try to put an integer
  873. ;; in an fp register, or an fp number is an integer register.
  874.  
  875. (define_insn ""
  876.   [(set (match_operand:SI 0 "reg_or_nonsymb_mem_operand" "=r,f,r,r,f,Q,Q")
  877.     (match_operand:SI 1 "move_operand" "rI,!f,K,Q,!Q,rJ,!f"))]
  878.   "register_operand (operands[0], SImode)
  879.    || register_operand (operands[1], SImode)
  880.    || operands[1] == const0_rtx"
  881.   "@
  882.    mov %1,%0
  883.    fmovs %1,%0
  884.    sethi %%hi(%a1),%0
  885.    ld %1,%0
  886.    ld %1,%0
  887.    st %r1,%0
  888.    st %r1,%0"
  889.   [(set_attr "type" "move,fp,move,load,load,store,store")
  890.    (set_attr "length" "*,*,1,*,*,*,*")])
  891.  
  892. ;; Special pic pattern, for loading the address of a label into a register.
  893. ;; It clobbers o7 because the call puts the return address (i.e. pc value)
  894. ;; there.
  895.  
  896. (define_insn ""
  897.   [(set (match_operand:SI 0 "register_operand" "=r")
  898.     (match_operand:SI 1 "move_pic_label" "i"))
  899.    (set (reg:SI 15) (pc))]
  900.   ""
  901.   "\\n1:\;call 2f\;sethi %%hi(%l1-1b),%0\\n2:\\tor %0,%%lo(%l1-1b),%0\;add %0,%%o7,%0"
  902.   [(set_attr "type" "multi")
  903.    (set_attr "length" "4")])
  904.  
  905. (define_insn ""
  906.   [(set (match_operand:DI 0 "register_operand" "=r")
  907.     (high:DI (match_operand 1 "" "")))]
  908.   "check_pic (1)"
  909.   "*
  910. {
  911.   rtx op0 = operands[0];
  912.   rtx op1 = operands[1];
  913.  
  914.   if (GET_CODE (op1) == CONST_INT)
  915.     {
  916.       operands[0] = operand_subword (op0, 1, 0, DImode);
  917.       output_asm_insn (\"sethi %%hi(%a1),%0\", operands);
  918.  
  919.       operands[0] = operand_subword (op0, 0, 0, DImode);
  920.       if (INTVAL (op1) < 0)
  921.     return \"mov -1,%0\";
  922.       else
  923.     return \"mov 0,%0\";
  924.     }
  925.   else if (GET_CODE (op1) == CONST_DOUBLE)
  926.     {
  927.       operands[0] = operand_subword (op0, 1, 0, DImode);
  928.       operands[1] = gen_rtx (CONST_INT, VOIDmode, CONST_DOUBLE_LOW (op1));
  929.       output_asm_insn (\"sethi %%hi(%a1),%0\", operands);
  930.  
  931.       operands[0] = operand_subword (op0, 0, 0, DImode);
  932.       operands[1] = gen_rtx (CONST_INT, VOIDmode, CONST_DOUBLE_HIGH (op1));
  933.       return singlemove_string (operands);
  934.     }
  935.   else
  936.     abort ();
  937.   return \"\";
  938. }"
  939.   [(set_attr "type" "move")
  940.    (set_attr "length" "2")])
  941.  
  942. ;; For PIC, symbol_refs are put inside unspec so that the optimizer won't
  943. ;; confuse them with real addresses.
  944. (define_insn ""
  945.   [(set (match_operand:SI 0 "register_operand" "=r")
  946.     (high:SI (unspec:SI [(match_operand 1 "" "")] 0)))]
  947.   "check_pic (1)"
  948.   "sethi %%hi(%a1),%0"
  949.   [(set_attr "type" "move")
  950.    (set_attr "length" "1")])
  951.  
  952. (define_insn ""
  953.   [(set (match_operand:SI 0 "register_operand" "=r")
  954.     (high:SI (match_operand 1 "" "")))]
  955.   "check_pic (1)"
  956.   "sethi %%hi(%a1),%0"
  957.   [(set_attr "type" "move")
  958.    (set_attr "length" "1")])
  959.  
  960. (define_insn ""
  961.   [(set (match_operand:HI 0 "register_operand" "=r")
  962.     (high:HI (match_operand 1 "" "")))]
  963.   "check_pic (1)"
  964.   "sethi %%hi(%a1),%0"
  965.   [(set_attr "type" "move")
  966.    (set_attr "length" "1")])
  967.  
  968. ;; For PIC, symbol_refs are put inside unspec so that the optimizer won't
  969. ;; confuse them with real addresses.
  970. (define_insn ""
  971.   [(set (match_operand:SI 0 "register_operand" "=r")
  972.     (lo_sum:SI (match_operand:SI 1 "register_operand" "r")
  973.            (unspec:SI [(match_operand:SI 2 "immediate_operand" "in")] 0)))]
  974.   ""
  975.   "or %1,%%lo(%a2),%0"
  976.   ;; Need to set length for this arith insn because operand2
  977.   ;; is not an "arith_operand".
  978.   [(set_attr "length" "1")])
  979.  
  980. ;; ??? Can the next two be moved above the PIC stuff?
  981.  
  982. (define_insn ""
  983.   [(set (match_operand:SI 0 "register_operand" "=r")
  984.     (lo_sum:SI (match_operand:SI 1 "register_operand" "r")
  985.            (match_operand:SI 2 "immediate_operand" "in")))]
  986.   ""
  987.   "or %1,%%lo(%a2),%0"
  988.   ;; Need to set length for this arith insn because operand2
  989.   ;; is not an "arith_operand".
  990.   [(set_attr "length" "1")])
  991.  
  992. (define_insn ""
  993.   [(set (mem:SI (match_operand:SI 0 "symbolic_operand" ""))
  994.     (match_operand:SI 1 "reg_or_0_operand" "rJ"))
  995.    (clobber (match_scratch:SI 2 "=&r"))]
  996.   ""
  997.   "sethi %%hi(%a0),%2\;st %r1,[%2+%%lo(%a0)]"
  998.   [(set_attr "type" "store")
  999.    (set_attr "length" "2")])
  1000.  
  1001. (define_expand "movdi"
  1002.   [(set (match_operand:DI 0 "reg_or_nonsymb_mem_operand" "")
  1003.     (match_operand:DI 1 "general_operand" ""))]
  1004.   ""
  1005.   "
  1006. {
  1007.   if (emit_move_sequence (operands, DImode))
  1008.     DONE;
  1009. }")
  1010.  
  1011. (define_insn ""
  1012.   [(set (match_operand:DI 0 "reg_or_nonsymb_mem_operand" "=r,Q,r,r,?f,?f,?Q")
  1013.     (match_operand:DI 1 "general_operand" "r,r,Q,i,f,Q,f"))]
  1014.   "register_operand (operands[0], DImode)
  1015.    || register_operand (operands[1], DImode)
  1016.    || operands[1] == const0_rtx"
  1017.   "*
  1018. {
  1019.   if (FP_REG_P (operands[0]) || FP_REG_P (operands[1]))
  1020.     return output_fp_move_double (operands);
  1021.   return output_move_double (operands);
  1022. }"
  1023.   [(set_attr "type" "move,store,load,multi,fp,fpload,fpstore")
  1024.    (set_attr "length" "2,3,3,3,2,3,3")])
  1025.  
  1026. (define_insn ""
  1027.   [(set (match_operand:DI 0 "register_operand" "=r")
  1028.     (lo_sum:DI (match_operand:DI 1 "register_operand" "0")
  1029.            (match_operand:DI 2 "immediate_operand" "in")))]
  1030.   ""
  1031.   "*
  1032. {
  1033.   /* Don't output a 64 bit constant, since we can't trust the assembler to
  1034.      handle it correctly.  */
  1035.   if (GET_CODE (operands[2]) == CONST_DOUBLE)
  1036.     operands[2] = gen_rtx (CONST_INT, VOIDmode, CONST_DOUBLE_LOW (operands[2]));
  1037.   return \"or %R1,%%lo(%a2),%R0\";
  1038. }"
  1039.   ;; Need to set length for this arith insn because operand2
  1040.   ;; is not an "arith_operand".
  1041.   [(set_attr "length" "1")])
  1042.  
  1043. ;; ??? There's no symbolic (set (mem:DI ...) ...).
  1044.  
  1045. ;; Block move insns.
  1046.  
  1047. ;; ??? We get better code without it.  See output_block_move in sparc.c.
  1048.  
  1049. ;; The definition of this insn does not really explain what it does,
  1050. ;; but it should suffice
  1051. ;; that anything generated as this insn will be recognized as one
  1052. ;; and that it will not successfully combine with anything.
  1053. ;(define_expand "movstrsi"
  1054. ;  [(parallel [(set (mem:BLK (match_operand:BLK 0 "general_operand" ""))
  1055. ;           (mem:BLK (match_operand:BLK 1 "general_operand" "")))
  1056. ;          (use (match_operand:SI 2 "nonmemory_operand" ""))
  1057. ;          (use (match_operand:SI 3 "immediate_operand" ""))
  1058. ;          (clobber (match_dup 0))
  1059. ;          (clobber (match_dup 1))
  1060. ;          (clobber (match_scratch:SI 4 ""))
  1061. ;          (clobber (reg:SI 0))
  1062. ;          (clobber (reg:SI 1))])]
  1063. ;  ""
  1064. ;  "
  1065. ;{
  1066. ;  /* If the size isn't known, don't emit inline code.  output_block_move
  1067. ;     would output code that's much slower than the library function.
  1068. ;     Also don't output code for large blocks.  */
  1069. ;  if (GET_CODE (operands[2]) != CONST_INT
  1070. ;      || GET_CODE (operands[3]) != CONST_INT
  1071. ;      || INTVAL (operands[2]) / INTVAL (operands[3]) > 16)
  1072. ;    FAIL;
  1073. ;
  1074. ;  operands[0] = copy_to_mode_reg (Pmode, XEXP (operands[0], 0));
  1075. ;  operands[1] = copy_to_mode_reg (Pmode, XEXP (operands[1], 0));
  1076. ;  operands[2] = force_not_mem (operands[2]);
  1077. ;}")
  1078.  
  1079. ;(define_insn ""
  1080. ;  [(set (mem:BLK (match_operand:SI 0 "register_operand" "+r"))
  1081. ;    (mem:BLK (match_operand:SI 1 "register_operand" "+r")))
  1082. ;   (use (match_operand:SI 2 "nonmemory_operand" "rn"))
  1083. ;   (use (match_operand:SI 3 "immediate_operand" "i"))
  1084. ;   (clobber (match_dup 0))
  1085. ;   (clobber (match_dup 1))
  1086. ;   (clobber (match_scratch:SI 4 "=&r"))
  1087. ;   (clobber (reg:SI 0))
  1088. ;   (clobber (reg:SI 1))]
  1089. ;  ""
  1090. ;  "* return output_block_move (operands);"
  1091. ;  [(set_attr "type" "multi")
  1092. ;   (set_attr "length" "6")])
  1093.  
  1094. ;; Floating point move insns
  1095.  
  1096. ;; This pattern forces (set (reg:SF ...) (const_double ...))
  1097. ;; to be reloaded by putting the constant into memory.
  1098. ;; It must come before the more general movsf pattern.
  1099. (define_insn ""
  1100.   [(set (match_operand:SF 0 "general_operand" "=?r,f,m")
  1101.     (match_operand:SF 1 "" "?E,m,G"))]
  1102.   "TARGET_FPU && GET_CODE (operands[1]) == CONST_DOUBLE"
  1103.   "*
  1104. {
  1105.   switch (which_alternative)
  1106.     {
  1107.     case 0:
  1108.       return singlemove_string (operands);
  1109.     case 1:
  1110.       return \"ld %1,%0\";
  1111.     case 2:
  1112.       return \"st %%g0,%0\";
  1113.     }
  1114. }"
  1115.   [(set_attr "type" "load,fpload,store")
  1116.    (set_attr "length" "2,1,1")])
  1117.  
  1118. (define_expand "movsf"
  1119.   [(set (match_operand:SF 0 "general_operand" "")
  1120.     (match_operand:SF 1 "general_operand" ""))]
  1121.   ""
  1122.   "
  1123. {
  1124.   if (emit_move_sequence (operands, SFmode))
  1125.     DONE;
  1126. }")
  1127.  
  1128. (define_insn ""
  1129.   [(set (match_operand:SF 0 "reg_or_nonsymb_mem_operand" "=f,r,f,r,Q,Q")
  1130.     (match_operand:SF 1 "reg_or_nonsymb_mem_operand" "f,r,Q,Q,f,r"))]
  1131.   "TARGET_FPU
  1132.    && (register_operand (operands[0], SFmode)
  1133.        || register_operand (operands[1], SFmode))"
  1134.   "@
  1135.    fmovs %1,%0
  1136.    mov %1,%0
  1137.    ld %1,%0
  1138.    ld %1,%0
  1139.    st %r1,%0
  1140.    st %r1,%0"
  1141.   [(set_attr "type" "fp,move,fpload,load,fpstore,store")])
  1142.  
  1143. ;; Exactly the same as above, except that all `f' cases are deleted.
  1144. ;; This is necessary to prevent reload from ever trying to use a `f' reg
  1145. ;; when -mno-fpu.
  1146.  
  1147. (define_insn ""
  1148.   [(set (match_operand:SF 0 "reg_or_nonsymb_mem_operand" "=r,r,Q")
  1149.     (match_operand:SF 1 "reg_or_nonsymb_mem_operand" "r,Q,r"))]
  1150.   "! TARGET_FPU
  1151.    && (register_operand (operands[0], SFmode)
  1152.        || register_operand (operands[1], SFmode))"
  1153.   "@
  1154.    mov %1,%0
  1155.    ld %1,%0
  1156.    st %r1,%0"
  1157.   [(set_attr "type" "move,load,store")])
  1158.  
  1159. (define_insn ""
  1160.   [(set (mem:SF (match_operand:SI 0 "symbolic_operand" "i"))
  1161.     (match_operand:SF 1 "reg_or_0_operand" "rfG"))
  1162.    (clobber (match_scratch:SI 2 "=&r"))]
  1163.   ""
  1164.   "sethi %%hi(%a0),%2\;st %r1,[%2+%%lo(%a0)]"
  1165.   [(set_attr "type" "store")
  1166.    (set_attr "length" "2")])
  1167.  
  1168. ;; This pattern forces (set (reg:DF ...) (const_double ...))
  1169. ;; to be reloaded by putting the constant into memory.
  1170. ;; It must come before the more general movdf pattern.
  1171.  
  1172. (define_insn ""
  1173.   [(set (match_operand:DF 0 "general_operand" "=?r,f,o")
  1174.     (match_operand:DF 1 "" "?E,m,G"))]
  1175.   "TARGET_FPU && GET_CODE (operands[1]) == CONST_DOUBLE"
  1176.   "*
  1177. {
  1178.   switch (which_alternative)
  1179.     {
  1180.     case 0:
  1181.       return output_move_double (operands);
  1182.     case 1:
  1183.       return output_fp_move_double (operands);
  1184.     case 2:
  1185.       operands[1] = adj_offsettable_operand (operands[0], 4);
  1186.       return \"st %%g0,%0\;st %%g0,%1\";
  1187.     }
  1188. }"
  1189.   [(set_attr "type" "load,fpload,store")
  1190.    (set_attr "length" "3,3,3")])
  1191.  
  1192. (define_expand "movdf"
  1193.   [(set (match_operand:DF 0 "general_operand" "")
  1194.     (match_operand:DF 1 "general_operand" ""))]
  1195.   ""
  1196.   "
  1197. {
  1198.   if (emit_move_sequence (operands, DFmode))
  1199.     DONE;
  1200. }")
  1201.  
  1202. (define_insn ""
  1203.   [(set (match_operand:DF 0 "reg_or_nonsymb_mem_operand" "=T,U,f,r,Q,Q,f,r")
  1204.     (match_operand:DF 1 "reg_or_nonsymb_mem_operand" "U,T,f,r,f,r,Q,Q"))]
  1205.   "TARGET_FPU
  1206.    && (register_operand (operands[0], DFmode)
  1207.        || register_operand (operands[1], DFmode))"
  1208.   "*
  1209. {
  1210.   if (FP_REG_P (operands[0]) || FP_REG_P (operands[1]))
  1211.     return output_fp_move_double (operands);
  1212.   return output_move_double (operands);
  1213. }"
  1214.   [(set_attr "type" "fpstore,fpload,fp,move,fpstore,store,fpload,load")
  1215.    (set_attr "length" "1,1,2,2,3,3,3,3")])
  1216.  
  1217. ;; Exactly the same as above, except that all `f' cases are deleted.
  1218. ;; This is necessary to prevent reload from ever trying to use a `f' reg
  1219. ;; when -mno-fpu.
  1220.  
  1221. (define_insn ""
  1222.   [(set (match_operand:DF 0 "reg_or_nonsymb_mem_operand" "=T,U,r,Q,&r")
  1223.     (match_operand:DF 1 "reg_or_nonsymb_mem_operand" "U,T,r,r,Q"))]
  1224.   "! TARGET_FPU
  1225.    && (register_operand (operands[0], DFmode)
  1226.        || register_operand (operands[1], DFmode))"
  1227.   "* return output_move_double (operands);"
  1228.   [(set_attr "type" "store,load,move,store,load")
  1229.    (set_attr "length" "1,1,2,3,3")])
  1230.  
  1231. (define_split
  1232.   [(set (match_operand:DF 0 "register_operand" "")
  1233.     (match_operand:DF 1 "register_operand" ""))]
  1234.   "reload_completed"
  1235.   [(set (match_dup 2) (match_dup 3))
  1236.    (set (match_dup 4) (match_dup 5))]
  1237.   "
  1238. { operands[2] = operand_subword (operands[0], 0, 0, DFmode);
  1239.   operands[3] = operand_subword (operands[1], 0, 0, DFmode);
  1240.   operands[4] = operand_subword (operands[0], 1, 0, DFmode);
  1241.   operands[5] = operand_subword (operands[1], 1, 0, DFmode); }")
  1242.  
  1243. (define_insn ""
  1244.   [(set (mem:DF (match_operand:SI 0 "symbolic_operand" "i,i"))
  1245.     (match_operand:DF 1 "reg_or_0_operand" "rf,G"))
  1246.    (clobber (match_scratch:SI 2 "=&r,&r"))]
  1247.   ""
  1248.   "*
  1249. {
  1250.   output_asm_insn (\"sethi %%hi(%a0),%2\", operands);
  1251.   if (which_alternative == 0)
  1252.     return \"std %1,[%2+%%lo(%a0)]\";
  1253.   else
  1254.     return \"st %%g0,[%2+%%lo(%a0)]\;st %%g0,[%2+%%lo(%a0+4)]\";
  1255. }"
  1256.   [(set_attr "type" "store")
  1257.    (set_attr "length" "3")])
  1258.  
  1259. ;; This pattern forces (set (reg:TF ...) (const_double ...))
  1260. ;; to be reloaded by putting the constant into memory.
  1261. ;; It must come before the more general movtf pattern.
  1262. (define_insn ""
  1263.   [(set (match_operand:TF 0 "general_operand" "=?r,f,o")
  1264.     (match_operand:TF 1 "" "?E,m,G"))]
  1265.   "TARGET_FPU && GET_CODE (operands[1]) == CONST_DOUBLE"
  1266.   "*
  1267. {
  1268.   switch (which_alternative)
  1269.     {
  1270.     case 0:
  1271.       return output_move_quad (operands);
  1272.     case 1:
  1273.       return output_fp_move_quad (operands);
  1274.     case 2:
  1275.       operands[1] = adj_offsettable_operand (operands[0], 4);
  1276.       operands[2] = adj_offsettable_operand (operands[0], 8);
  1277.       operands[3] = adj_offsettable_operand (operands[0], 12);
  1278.       return \"st %%g0,%0\;st %%g0,%1\;st %%g0,%2\;st %%g0,%3\";
  1279.     }
  1280. }"
  1281.   [(set_attr "type" "load,fpload,store")
  1282.    (set_attr "length" "5,5,5")])
  1283.  
  1284. (define_expand "movtf"
  1285.   [(set (match_operand:TF 0 "general_operand" "")
  1286.     (match_operand:TF 1 "general_operand" ""))]
  1287.   ""
  1288.   "
  1289. {
  1290.   if (emit_move_sequence (operands, TFmode))
  1291.     DONE;
  1292. }")
  1293.  
  1294. (define_insn ""
  1295.   [(set (match_operand:TF 0 "reg_or_nonsymb_mem_operand" "=f,r,Q,Q,f,&r")
  1296.     (match_operand:TF 1 "reg_or_nonsymb_mem_operand" "f,r,f,r,Q,Q"))]
  1297.   "TARGET_FPU
  1298.    && (register_operand (operands[0], TFmode)
  1299.        || register_operand (operands[1], TFmode))"
  1300.   "*
  1301. {
  1302.   if (FP_REG_P (operands[0]) || FP_REG_P (operands[1]))
  1303.     return output_fp_move_quad (operands);
  1304.   return output_move_quad (operands);
  1305. }"
  1306.   [(set_attr "type" "fp,move,fpstore,store,fpload,load")
  1307.    (set_attr "length" "4,4,5,5,5,5")])
  1308.  
  1309. ;; Exactly the same as above, except that all `f' cases are deleted.
  1310. ;; This is necessary to prevent reload from ever trying to use a `f' reg
  1311. ;; when -mno-fpu.
  1312.  
  1313. (define_insn ""
  1314.   [(set (match_operand:TF 0 "reg_or_nonsymb_mem_operand" "=r,Q,&r")
  1315.     (match_operand:TF 1 "reg_or_nonsymb_mem_operand" "r,r,Q"))]
  1316.   "! TARGET_FPU
  1317.    && (register_operand (operands[0], TFmode)
  1318.        || register_operand (operands[1], TFmode))"
  1319.   "*
  1320. {
  1321.   if (FP_REG_P (operands[0]) || FP_REG_P (operands[1]))
  1322.     return output_fp_move_quad (operands);
  1323.   return output_move_quad (operands);
  1324. }"
  1325.   [(set_attr "type" "move,store,load")
  1326.    (set_attr "length" "4,5,5")])
  1327.  
  1328. (define_insn ""
  1329.   [(set (mem:TF (match_operand:SI 0 "symbolic_operand" "i,i"))
  1330.     (match_operand:TF 1 "reg_or_0_operand" "rf,G"))
  1331.    (clobber (match_scratch:SI 2 "=&r,&r"))]
  1332.   ""
  1333.   "*
  1334. {
  1335.   output_asm_insn (\"sethi %%hi(%a0),%2\", operands);
  1336.   if (which_alternative == 0)
  1337.     return \"std %1,[%2+%%lo(%a0)]\;std %S1,[%2+%%lo(%a0+8)]\";
  1338.   else
  1339.     return \"st %%g0,[%2+%%lo(%a0)]\;st %%g0,[%2+%%lo(%a0+4)]\; st %%g0,[%2+%%lo(%a0+8)]\;st %%g0,[%2+%%lo(%a0+12)]\";
  1340. }"
  1341.   [(set_attr "type" "store")
  1342.    (set_attr "length" "5")])
  1343.  
  1344. ;;- zero extension instructions
  1345.  
  1346. ;; These patterns originally accepted general_operands, however, slightly
  1347. ;; better code is generated by only accepting register_operands, and then
  1348. ;; letting combine generate the ldu[hb] insns.
  1349.  
  1350. (define_expand "zero_extendhisi2"
  1351.   [(set (match_operand:SI 0 "register_operand" "")
  1352.     (zero_extend:SI (match_operand:HI 1 "register_operand" "")))]
  1353.   ""
  1354.   "
  1355. {
  1356.   rtx temp = gen_reg_rtx (SImode);
  1357.   rtx shift_16 = gen_rtx (CONST_INT, VOIDmode, 16);
  1358.   int op1_subword = 0;
  1359.  
  1360.   if (GET_CODE (operand1) == SUBREG)
  1361.     {
  1362.       op1_subword = SUBREG_WORD (operand1);
  1363.       operand1 = XEXP (operand1, 0);
  1364.     }
  1365.  
  1366.   emit_insn (gen_ashlsi3 (temp, gen_rtx (SUBREG, SImode, operand1,
  1367.                      op1_subword),
  1368.               shift_16));
  1369.   emit_insn (gen_lshrsi3 (operand0, temp, shift_16));
  1370.   DONE;
  1371. }")
  1372.  
  1373. (define_insn ""
  1374.   [(set (match_operand:SI 0 "register_operand" "=r")
  1375.     (zero_extend:SI (match_operand:HI 1 "memory_operand" "m")))]
  1376.   ""
  1377.   "lduh %1,%0"
  1378.   [(set_attr "type" "load")])
  1379.  
  1380. (define_expand "zero_extendqihi2"
  1381.   [(set (match_operand:HI 0 "register_operand" "")
  1382.     (zero_extend:HI (match_operand:QI 1 "register_operand" "")))]
  1383.   ""
  1384.   "")
  1385.  
  1386. (define_insn ""
  1387.   [(set (match_operand:HI 0 "register_operand" "=r,r")
  1388.     (zero_extend:HI (match_operand:QI 1 "sparc_operand" "r,Q")))]
  1389.   "GET_CODE (operands[1]) != CONST_INT"
  1390.   "@
  1391.    and %1,0xff,%0
  1392.    ldub %1,%0"
  1393.   [(set_attr "type" "unary,load")
  1394.    (set_attr "length" "1")])
  1395.  
  1396. (define_expand "zero_extendqisi2"
  1397.   [(set (match_operand:SI 0 "register_operand" "")
  1398.     (zero_extend:SI (match_operand:QI 1 "register_operand" "")))]
  1399.   ""
  1400.   "")
  1401.  
  1402. (define_insn ""
  1403.   [(set (match_operand:SI 0 "register_operand" "=r,r")
  1404.     (zero_extend:SI (match_operand:QI 1 "sparc_operand" "r,Q")))]
  1405.   "GET_CODE (operands[1]) != CONST_INT"
  1406.   "@
  1407.    and %1,0xff,%0
  1408.    ldub %1,%0"
  1409.   [(set_attr "type" "unary,load")
  1410.    (set_attr "length" "1")])
  1411.  
  1412. (define_insn ""
  1413.   [(set (reg:CC 0)
  1414.     (compare:CC (zero_extend:SI (match_operand:QI 0 "register_operand" "r"))
  1415.             (const_int 0)))]
  1416.   ""
  1417.   "andcc %0,0xff,%%g0"
  1418.   [(set_attr "type" "compare")])
  1419.  
  1420. (define_insn ""
  1421.   [(set (reg:CC 0)
  1422.     (compare:CC (zero_extend:SI (match_operand:QI 1 "register_operand" "r"))
  1423.             (const_int 0)))
  1424.    (set (match_operand:SI 0 "register_operand" "=r")
  1425.     (zero_extend:SI (match_dup 1)))]
  1426.   ""
  1427.   "andcc %1,0xff,%0"
  1428.   [(set_attr "type" "unary")])
  1429.  
  1430. ;; Similarly, handle SI->QI mode truncation followed by a compare.
  1431.  
  1432. (define_insn ""
  1433.   [(set (reg:CC 0)
  1434.     (compare:CC (subreg:QI (match_operand:SI 0 "register_operand" "r") 0)
  1435.             (const_int 0)))]
  1436.   ""
  1437.   "andcc %0,0xff,%%g0"
  1438.   [(set_attr "type" "compare")])
  1439.  
  1440. (define_insn ""
  1441.   [(set (reg:CC 0)
  1442.     (compare:CC (subreg:QI (match_operand:SI 1 "register_operand" "r") 0)
  1443.             (const_int 0)))
  1444.    (set (match_operand:QI 0 "register_operand" "=r")
  1445.     (match_dup 1))]
  1446.   ""
  1447.   "andcc %1,0xff,%0"
  1448.   [(set_attr "type" "unary")])
  1449.  
  1450. ;;- sign extension instructions
  1451.  
  1452. ;; These patterns originally accepted general_operands, however, slightly
  1453. ;; better code is generated by only accepting register_operands, and then
  1454. ;; letting combine generate the lds[hb] insns.
  1455.  
  1456. (define_expand "extendhisi2"
  1457.   [(set (match_operand:SI 0 "register_operand" "")
  1458.     (sign_extend:SI (match_operand:HI 1 "register_operand" "")))]
  1459.   ""
  1460.   "
  1461. {
  1462.   rtx temp = gen_reg_rtx (SImode);
  1463.   rtx shift_16 = gen_rtx (CONST_INT, VOIDmode, 16);
  1464.   int op1_subword = 0;
  1465.  
  1466.   if (GET_CODE (operand1) == SUBREG)
  1467.     {
  1468.       op1_subword = SUBREG_WORD (operand1);
  1469.       operand1 = XEXP (operand1, 0);
  1470.     }
  1471.  
  1472.   emit_insn (gen_ashlsi3 (temp, gen_rtx (SUBREG, SImode, operand1,
  1473.                      op1_subword),
  1474.               shift_16));
  1475.   emit_insn (gen_ashrsi3 (operand0, temp, shift_16));
  1476.   DONE;
  1477. }")
  1478.  
  1479. (define_insn ""
  1480.   [(set (match_operand:SI 0 "register_operand" "=r")
  1481.     (sign_extend:SI (match_operand:HI 1 "memory_operand" "m")))]
  1482.   ""
  1483.   "ldsh %1,%0"
  1484.   [(set_attr "type" "load")])
  1485.  
  1486. (define_expand "extendqihi2"
  1487.   [(set (match_operand:HI 0 "register_operand" "")
  1488.     (sign_extend:HI (match_operand:QI 1 "register_operand" "")))]
  1489.   ""
  1490.   "
  1491. {
  1492.   rtx temp = gen_reg_rtx (SImode);
  1493.   rtx shift_24 = gen_rtx (CONST_INT, VOIDmode, 24);
  1494.   int op1_subword = 0;
  1495.   int op0_subword = 0;
  1496.  
  1497.   if (GET_CODE (operand1) == SUBREG)
  1498.     {
  1499.       op1_subword = SUBREG_WORD (operand1);
  1500.       operand1 = XEXP (operand1, 0);
  1501.     }
  1502.   if (GET_CODE (operand0) == SUBREG)
  1503.     {
  1504.       op0_subword = SUBREG_WORD (operand0);
  1505.       operand0 = XEXP (operand0, 0);
  1506.     }
  1507.   emit_insn (gen_ashlsi3 (temp, gen_rtx (SUBREG, SImode, operand1,
  1508.                      op1_subword),
  1509.               shift_24));
  1510.   if (GET_MODE (operand0) != SImode)
  1511.     operand0 = gen_rtx (SUBREG, SImode, operand0, op0_subword);
  1512.   emit_insn (gen_ashrsi3 (operand0, temp, shift_24));
  1513.   DONE;
  1514. }")
  1515.  
  1516. (define_insn ""
  1517.   [(set (match_operand:HI 0 "register_operand" "=r")
  1518.     (sign_extend:HI (match_operand:QI 1 "memory_operand" "m")))]
  1519.   ""
  1520.   "ldsb %1,%0"
  1521.   [(set_attr "type" "load")])
  1522.  
  1523. (define_expand "extendqisi2"
  1524.   [(set (match_operand:SI 0 "register_operand" "")
  1525.     (sign_extend:SI (match_operand:QI 1 "register_operand" "")))]
  1526.   ""
  1527.   "
  1528. {
  1529.   rtx temp = gen_reg_rtx (SImode);
  1530.   rtx shift_24 = gen_rtx (CONST_INT, VOIDmode, 24);
  1531.   int op1_subword = 0;
  1532.  
  1533.   if (GET_CODE (operand1) == SUBREG)
  1534.     {
  1535.       op1_subword = SUBREG_WORD (operand1);
  1536.       operand1 = XEXP (operand1, 0);
  1537.     }
  1538.  
  1539.   emit_insn (gen_ashlsi3 (temp, gen_rtx (SUBREG, SImode, operand1,
  1540.                      op1_subword),
  1541.               shift_24));
  1542.   emit_insn (gen_ashrsi3 (operand0, temp, shift_24));
  1543.   DONE;
  1544. }")
  1545.  
  1546. (define_insn ""
  1547.   [(set (match_operand:SI 0 "register_operand" "=r")
  1548.     (sign_extend:SI (match_operand:QI 1 "memory_operand" "m")))]
  1549.   ""
  1550.   "ldsb %1,%0"
  1551.   [(set_attr "type" "load")])
  1552.  
  1553. ;; Special pattern for optimizing bit-field compares.  This is needed
  1554. ;; because combine uses this as a canonical form.
  1555.  
  1556. (define_insn ""
  1557.   [(set (reg:CC 0)
  1558.     (compare:CC
  1559.      (zero_extract:SI (match_operand:SI 0 "register_operand" "r")
  1560.               (match_operand:SI 1 "small_int" "n")
  1561.               (match_operand:SI 2 "small_int" "n"))
  1562.      (const_int 0)))]
  1563.   "INTVAL (operands[2]) > 19"
  1564.   "*
  1565. {
  1566.   int len = INTVAL (operands[1]);
  1567.   int pos = 32 - INTVAL (operands[2]) - len;
  1568.   unsigned mask = ((1 << len) - 1) << pos;
  1569.  
  1570.   operands[1] = gen_rtx (CONST_INT, VOIDmode, mask);
  1571.   return \"andcc %0,%1,%%g0\";
  1572. }")
  1573.  
  1574. ;; Conversions between float, double and long double.
  1575.  
  1576. (define_insn "extendsfdf2"
  1577.   [(set (match_operand:DF 0 "register_operand" "=f")
  1578.     (float_extend:DF
  1579.      (match_operand:SF 1 "register_operand" "f")))]
  1580.   "TARGET_FPU"
  1581.   "fstod %1,%0"
  1582.   [(set_attr "type" "fp")])
  1583.  
  1584. (define_insn "extendsftf2"
  1585.   [(set (match_operand:TF 0 "register_operand" "=f")
  1586.     (float_extend:TF
  1587.      (match_operand:SF 1 "register_operand" "f")))]
  1588.   "TARGET_FPU"
  1589.   "fstoq %1,%0"
  1590.   [(set_attr "type" "fp")])
  1591.  
  1592. (define_insn "extenddftf2"
  1593.   [(set (match_operand:TF 0 "register_operand" "=f")
  1594.     (float_extend:TF
  1595.      (match_operand:DF 1 "register_operand" "f")))]
  1596.   "TARGET_FPU"
  1597.   "fdtoq %1,%0"
  1598.   [(set_attr "type" "fp")])
  1599.  
  1600. (define_insn "truncdfsf2"
  1601.   [(set (match_operand:SF 0 "register_operand" "=f")
  1602.     (float_truncate:SF
  1603.      (match_operand:DF 1 "register_operand" "f")))]
  1604.   "TARGET_FPU"
  1605.   "fdtos %1,%0"
  1606.   [(set_attr "type" "fp")])
  1607.  
  1608. (define_insn "trunctfsf2"
  1609.   [(set (match_operand:SF 0 "register_operand" "=f")
  1610.     (float_truncate:SF
  1611.      (match_operand:TF 1 "register_operand" "f")))]
  1612.   "TARGET_FPU"
  1613.   "fqtos %1,%0"
  1614.   [(set_attr "type" "fp")])
  1615.  
  1616. (define_insn "trunctfdf2"
  1617.   [(set (match_operand:DF 0 "register_operand" "=f")
  1618.     (float_truncate:DF
  1619.      (match_operand:TF 1 "register_operand" "f")))]
  1620.   "TARGET_FPU"
  1621.   "fqtod %1,%0"
  1622.   [(set_attr "type" "fp")])
  1623.  
  1624. ;; Conversion between fixed point and floating point.
  1625.  
  1626. (define_insn "floatsisf2"
  1627.   [(set (match_operand:SF 0 "register_operand" "=f")
  1628.     (float:SF (match_operand:SI 1 "register_operand" "f")))]
  1629.   "TARGET_FPU"
  1630.   "fitos %1,%0"
  1631.   [(set_attr "type" "fp")])
  1632.  
  1633. (define_insn "floatsidf2"
  1634.   [(set (match_operand:DF 0 "register_operand" "=f")
  1635.     (float:DF (match_operand:SI 1 "register_operand" "f")))]
  1636.   "TARGET_FPU"
  1637.   "fitod %1,%0"
  1638.   [(set_attr "type" "fp")])
  1639.  
  1640. (define_insn "floatsitf2"
  1641.   [(set (match_operand:TF 0 "register_operand" "=f")
  1642.     (float:TF (match_operand:SI 1 "register_operand" "f")))]
  1643.   "TARGET_FPU"
  1644.   "fitoq %1,%0"
  1645.   [(set_attr "type" "fp")])
  1646.  
  1647. ;; Convert a float to an actual integer.
  1648. ;; Truncation is performed as part of the conversion.
  1649.  
  1650. (define_insn "fix_truncsfsi2"
  1651.   [(set (match_operand:SI 0 "register_operand" "=f")
  1652.     (fix:SI (fix:SF (match_operand:SF 1 "register_operand" "f"))))]
  1653.   "TARGET_FPU"
  1654.   "fstoi %1,%0"
  1655.   [(set_attr "type" "fp")])
  1656.  
  1657. (define_insn "fix_truncdfsi2"
  1658.   [(set (match_operand:SI 0 "register_operand" "=f")
  1659.     (fix:SI (fix:DF (match_operand:DF 1 "register_operand" "f"))))]
  1660.   "TARGET_FPU"
  1661.   "fdtoi %1,%0"
  1662.   [(set_attr "type" "fp")])
  1663.  
  1664. (define_insn "fix_trunctfsi2"
  1665.   [(set (match_operand:SI 0 "register_operand" "=f")
  1666.     (fix:SI (fix:TF (match_operand:TF 1 "register_operand" "f"))))]
  1667.   "TARGET_FPU"
  1668.   "fqtoi %1,%0"
  1669.   [(set_attr "type" "fp")])
  1670.  
  1671. ;;- arithmetic instructions
  1672.  
  1673. (define_insn "adddi3"
  1674.   [(set (match_operand:DI 0 "register_operand" "=r")
  1675.     (plus:DI (match_operand:DI 1 "arith_double_operand" "%r")
  1676.          (match_operand:DI 2 "arith_double_operand" "rHI")))
  1677.    (clobber (reg:SI 0))]
  1678.   ""
  1679.   "*
  1680. {
  1681.   rtx op2 = operands[2];
  1682.  
  1683.   /* If constant is positive, upper bits zeroed, otherwise unchanged.
  1684.      Give the assembler a chance to pick the move instruction. */
  1685.   if (GET_CODE (op2) == CONST_INT)
  1686.     {
  1687.       int sign = INTVAL (op2);
  1688.       if (sign < 0)
  1689.     return \"addcc %R1,%2,%R0\;addx %1,-1,%0\";
  1690.       return \"addcc %R1,%2,%R0\;addx %1,0,%0\";
  1691.     }
  1692.   else if (GET_CODE (op2) == CONST_DOUBLE)
  1693.     {
  1694.       int sign = CONST_DOUBLE_HIGH (op2);
  1695.       operands[2] = gen_rtx (CONST_INT, VOIDmode,
  1696.                  CONST_DOUBLE_LOW (operands[1]));
  1697.       if (sign < 0)
  1698.         return \"addcc %R1,%2,%R0\;addx %1,-1,%0\";
  1699.       return \"addcc %R1,%2,%R0\;addx %1,0,%0\";
  1700.     }
  1701.   return \"addcc %R1,%R2,%R0\;addx %1,%2,%0\";
  1702. }"
  1703.   [(set_attr "length" "2")])
  1704.  
  1705. (define_insn "addsi3"
  1706.   [(set (match_operand:SI 0 "register_operand" "=r")
  1707.     (plus:SI (match_operand:SI 1 "arith_operand" "%r")
  1708.          (match_operand:SI 2 "arith_operand" "rI")))]
  1709.   ""
  1710.   "add %1,%2,%0")
  1711.  
  1712. (define_insn ""
  1713.   [(set (reg:CC_NOOV 0)
  1714.     (compare:CC_NOOV (plus:SI (match_operand:SI 0 "arith_operand" "%r")
  1715.                   (match_operand:SI 1 "arith_operand" "rI"))
  1716.              (const_int 0)))]
  1717.   ""
  1718.   "addcc %0,%1,%%g0"
  1719.   [(set_attr "type" "compare")])
  1720.  
  1721. (define_insn ""
  1722.   [(set (reg:CC_NOOV 0)
  1723.     (compare:CC_NOOV (plus:SI (match_operand:SI 1 "arith_operand" "%r")
  1724.                   (match_operand:SI 2 "arith_operand" "rI"))
  1725.              (const_int 0)))
  1726.    (set (match_operand:SI 0 "register_operand" "=r")
  1727.     (plus:SI (match_dup 1) (match_dup 2)))]
  1728.   ""
  1729.   "addcc %1,%2,%0")
  1730.  
  1731. (define_insn "subdi3"
  1732.   [(set (match_operand:DI 0 "register_operand" "=r")
  1733.     (minus:DI (match_operand:DI 1 "register_operand" "r")
  1734.           (match_operand:DI 2 "arith_double_operand" "rHI")))
  1735.    (clobber (reg:SI 0))]
  1736.   ""
  1737.   "*
  1738. {
  1739.   rtx op2 = operands[2];
  1740.  
  1741.   /* If constant is positive, upper bits zeroed, otherwise unchanged.
  1742.      Give the assembler a chance to pick the move instruction. */
  1743.   if (GET_CODE (op2) == CONST_INT)
  1744.     {
  1745.       int sign = INTVAL (op2);
  1746.       if (sign < 0)
  1747.     return \"subcc %R1,%2,%R0\;subx %1,-1,%0\";
  1748.       return \"subcc %R1,%2,%R0\;subx %1,0,%0\";
  1749.     }
  1750.   else if (GET_CODE (op2) == CONST_DOUBLE)
  1751.     {
  1752.       int sign = CONST_DOUBLE_HIGH (op2);
  1753.       operands[2] = gen_rtx (CONST_INT, VOIDmode,
  1754.                  CONST_DOUBLE_LOW (operands[1]));
  1755.       if (sign < 0)
  1756.         return \"subcc %R1,%2,%R0\;subx %1,-1,%0\";
  1757.       return \"subcc %R1,%2,%R0\;subx %1,0,%0\";
  1758.     }
  1759.   return \"subcc %R1,%R2,%R0\;subx %1,%2,%0\";
  1760. }"
  1761.   [(set_attr "length" "2")])
  1762.  
  1763. (define_insn "subsi3"
  1764.   [(set (match_operand:SI 0 "register_operand" "=r")
  1765.     (minus:SI (match_operand:SI 1 "register_operand" "r")
  1766.           (match_operand:SI 2 "arith_operand" "rI")))]
  1767.   ""
  1768.   "sub %1,%2,%0")
  1769.  
  1770. (define_insn ""
  1771.   [(set (reg:CC_NOOV 0)
  1772.     (compare:CC_NOOV (minus:SI (match_operand:SI 0 "register_operand" "r")
  1773.                    (match_operand:SI 1 "arith_operand" "rI"))
  1774.              (const_int 0)))]
  1775.   ""
  1776.   "subcc %0,%1,%%g0"
  1777.   [(set_attr "type" "compare")])
  1778.  
  1779. (define_insn ""
  1780.   [(set (reg:CC_NOOV 0)
  1781.     (compare:CC_NOOV (minus:SI (match_operand:SI 1 "register_operand" "r")
  1782.                    (match_operand:SI 2 "arith_operand" "rI"))
  1783.              (const_int 0)))
  1784.    (set (match_operand:SI 0 "register_operand" "=r")
  1785.     (minus:SI (match_dup 1) (match_dup 2)))]
  1786.   ""
  1787.   "subcc %1,%2,%0")
  1788.  
  1789. (define_insn "mulsi3"
  1790.   [(set (match_operand:SI 0 "register_operand" "=r")
  1791.     (mult:SI (match_operand:SI 1 "arith_operand" "%r")
  1792.          (match_operand:SI 2 "arith_operand" "rI")))]
  1793.   "TARGET_V8 || TARGET_SPARCLITE"
  1794.   "smul %1,%2,%0")
  1795.  
  1796. ;; It is not known whether this will match.
  1797.  
  1798. (define_insn ""
  1799.   [(set (match_operand:SI 0 "register_operand" "=r")
  1800.     (mult:SI (match_operand:SI 1 "arith_operand" "%r")
  1801.          (match_operand:SI 2 "arith_operand" "rI")))
  1802.    (set (reg:CC_NOOV 0)
  1803.     (compare:CC_NOOV (mult:SI (match_dup 1) (match_dup 2))
  1804.              (const_int 0)))]
  1805.   "TARGET_V8 || TARGET_SPARCLITE"
  1806.   "smulcc %1,%2,%0")
  1807.  
  1808. (define_expand "mulsidi3"
  1809.   [(set (match_operand:DI 0 "register_operand" "")
  1810.     (mult:DI (sign_extend:DI (match_operand:SI 1 "register_operand" ""))
  1811.          (sign_extend:DI (match_operand:SI 2 "arith_operand" ""))))]
  1812.   "TARGET_V8 || TARGET_SPARCLITE"
  1813.   "
  1814. {
  1815.   if (CONSTANT_P (operands[2]))
  1816.     {
  1817.       emit_insn (gen_const_mulsidi3 (operands[0], operands[1], operands[2]));
  1818.       DONE;
  1819.     }
  1820. }")
  1821.  
  1822. (define_insn ""
  1823.   [(set (match_operand:DI 0 "register_operand" "=r")
  1824.     (mult:DI (sign_extend:DI (match_operand:SI 1 "register_operand" "r"))
  1825.          (sign_extend:DI (match_operand:SI 2 "register_operand" "r"))))]
  1826.   "TARGET_V8 || TARGET_SPARCLITE"
  1827.   "smul %1,%2,%R0\;rd %%y,%0"
  1828.   [(set_attr "length" "2")])
  1829.  
  1830. ;; Extra pattern, because sign_extend of a constant isn't legal.
  1831.  
  1832. (define_insn "const_mulsidi3"
  1833.   [(set (match_operand:DI 0 "register_operand" "=r")
  1834.     (mult:DI (sign_extend:DI (match_operand:SI 1 "register_operand" "r"))
  1835.          (match_operand:SI 2 "small_int" "I")))]
  1836.   "TARGET_V8 || TARGET_SPARCLITE"
  1837.   "smul %1,%2,%R0\;rd %%y,%0"
  1838.   [(set_attr "length" "2")])
  1839.  
  1840. (define_expand "umulsidi3"
  1841.   [(set (match_operand:DI 0 "register_operand" "")
  1842.     (mult:DI (zero_extend:DI (match_operand:SI 1 "register_operand" ""))
  1843.          (zero_extend:DI (match_operand:SI 2 "uns_arith_operand" ""))))]
  1844.   "TARGET_V8 || TARGET_SPARCLITE"
  1845.   "
  1846. {
  1847.   if (CONSTANT_P (operands[2]))
  1848.     {
  1849.       emit_insn (gen_const_umulsidi3 (operands[0], operands[1], operands[2]));
  1850.       DONE;
  1851.     }
  1852. }")
  1853.  
  1854. (define_insn ""
  1855.   [(set (match_operand:DI 0 "register_operand" "=r")
  1856.     (mult:DI (zero_extend:DI (match_operand:SI 1 "register_operand" "r"))
  1857.          (zero_extend:DI (match_operand:SI 2 "register_operand" "r"))))]
  1858.   "TARGET_V8 || TARGET_SPARCLITE"
  1859.   "umul %1,%2,%R0\;rd %%y,%0"
  1860.   [(set_attr "length" "2")])
  1861.  
  1862. ;; Extra pattern, because sign_extend of a constant isn't legal.
  1863.  
  1864. (define_insn "const_umulsidi3"
  1865.   [(set (match_operand:DI 0 "register_operand" "=r")
  1866.     (mult:DI (zero_extend:DI (match_operand:SI 1 "register_operand" "r"))
  1867.          (match_operand:SI 2 "uns_small_int" "")))]
  1868.   "TARGET_V8 || TARGET_SPARCLITE"
  1869.   "umul %1,%2,%R0\;rd %%y,%0"
  1870.   [(set_attr "length" "2")])
  1871.  
  1872. ;; The architecture specifies that there must be 3 instructions between
  1873. ;; a y register write and a use of it for correct results.
  1874.  
  1875. (define_insn "divsi3"
  1876.   [(set (match_operand:SI 0 "register_operand" "=r")
  1877.     (div:SI (match_operand:SI 1 "register_operand" "r")
  1878.         (match_operand:SI 2 "arith_operand" "rI")))
  1879.    (clobber (match_scratch:SI 3 "=&r"))]
  1880.   "TARGET_V8"
  1881.   "sra %1,31,%3\;wr %%g0,%3,%%y\;nop\;nop\;nop\;sdiv %1,%2,%0"
  1882.   [(set_attr "length" "6")])
  1883.  
  1884. ;; It is not known whether this will match.
  1885.  
  1886. (define_insn ""
  1887.   [(set (match_operand:SI 0 "register_operand" "=r")
  1888.     (div:SI (match_operand:SI 1 "register_operand" "r")
  1889.         (match_operand:SI 2 "arith_operand" "rI")))
  1890.    (set (reg:CC 0)
  1891.     (compare:CC (div:SI (match_dup 1) (match_dup 2))
  1892.             (const_int 0)))
  1893.    (clobber (match_scratch:SI 3 "=&r"))]
  1894.   "TARGET_V8"
  1895.   "sra %1,31,%3\;wr %%g0,%3,%%y\;nop\;nop\;nop\;sdivcc %1,%2,%0"
  1896.   [(set_attr "length" "6")])
  1897.  
  1898. (define_insn "udivsi3"
  1899.   [(set (match_operand:SI 0 "register_operand" "=r")
  1900.     (udiv:SI (match_operand:SI 1 "register_operand" "r")
  1901.         (match_operand:SI 2 "arith_operand" "rI")))]
  1902.   "TARGET_V8"
  1903.   "wr %%g0,%%g0,%%y\;nop\;nop\;nop\;udiv %1,%2,%0"
  1904.   [(set_attr "length" "5")])
  1905.  
  1906. ;; It is not known whether this will match.
  1907.  
  1908. (define_insn ""
  1909.   [(set (match_operand:SI 0 "register_operand" "=r")
  1910.     (udiv:SI (match_operand:SI 1 "register_operand" "r")
  1911.         (match_operand:SI 2 "arith_operand" "rI")))
  1912.    (set (reg:CC 0)
  1913.     (compare:CC (udiv:SI (match_dup 1) (match_dup 2))
  1914.             (const_int 0)))]
  1915.   "TARGET_V8"
  1916.   "wr %%g0,%%g0,%%y\;nop\;nop\;nop\;udivcc %1,%2,%0"
  1917.   [(set_attr "length" "5")])
  1918.  
  1919. ;;- Boolean instructions
  1920. ;; We define DImode `and` so with DImode `not` we can get
  1921. ;; DImode `andn`.  Other combinations are possible.
  1922.  
  1923. (define_expand "anddi3"
  1924.   [(set (match_operand:DI 0 "register_operand" "")
  1925.     (and:DI (match_operand:DI 1 "arith_double_operand" "")
  1926.         (match_operand:DI 2 "arith_double_operand" "")))]
  1927.   ""
  1928.   "")
  1929.  
  1930. (define_insn ""
  1931.   [(set (match_operand:DI 0 "register_operand" "=r")
  1932.     (and:DI (match_operand:DI 1 "arith_double_operand" "%r")
  1933.         (match_operand:DI 2 "arith_double_operand" "rHI")))]
  1934.   ""
  1935.   "*
  1936. {
  1937.   rtx op2 = operands[2];
  1938.  
  1939.   /* If constant is positive, upper bits zeroed, otherwise unchanged.
  1940.      Give the assembler a chance to pick the move instruction. */
  1941.   if (GET_CODE (op2) == CONST_INT)
  1942.     {
  1943.       int sign = INTVAL (op2);
  1944.       if (sign < 0)
  1945.     return \"mov %1,%0\;and %R1,%2,%R0\";
  1946.       return \"mov 0,%0\;and %R1,%2,%R0\";
  1947.     }
  1948.   else if (GET_CODE (op2) == CONST_DOUBLE)
  1949.     {
  1950.       int sign = CONST_DOUBLE_HIGH (op2);
  1951.       operands[2] = gen_rtx (CONST_INT, VOIDmode,
  1952.                  CONST_DOUBLE_LOW (operands[1]));
  1953.       if (sign < 0)
  1954.     return \"mov %1,%0\;and %R1,%2,%R0\";
  1955.       return \"mov 0,%0\;and %R1,%2,%R0\";
  1956.     }
  1957.   return \"and %1,%2,%0\;and %R1,%R2,%R0\";
  1958. }"
  1959.   [(set_attr "length" "2")])
  1960.  
  1961. (define_insn "andsi3"
  1962.   [(set (match_operand:SI 0 "register_operand" "=r")
  1963.     (and:SI (match_operand:SI 1 "arith_operand" "%r")
  1964.         (match_operand:SI 2 "arith_operand" "rI")))]
  1965.   ""
  1966.   "and %1,%2,%0")
  1967.  
  1968. (define_split
  1969.   [(set (match_operand:SI 0 "register_operand" "")
  1970.     (and:SI (match_operand:SI 1 "register_operand" "")
  1971.         (match_operand:SI 2 "" "")))
  1972.    (clobber (match_operand:SI 3 "register_operand" ""))]
  1973.   "GET_CODE (operands[2]) == CONST_INT
  1974.    && !SMALL_INT (operands[2])
  1975.    && (INTVAL (operands[2]) & 0x3ff) == 0x3ff"
  1976.   [(set (match_dup 3) (match_dup 4))
  1977.    (set (match_dup 0) (and:SI (not:SI (match_dup 3)) (match_dup 1)))]
  1978.   "
  1979. {
  1980.   operands[4] = gen_rtx (CONST_INT, VOIDmode, ~INTVAL (operands[2]));
  1981. }")
  1982.  
  1983. (define_insn ""
  1984.   [(set (match_operand:DI 0 "register_operand" "=r")
  1985.     (and:DI (not:DI (match_operand:DI 1 "register_operand" "r"))
  1986.         (match_operand:DI 2 "register_operand" "r")))]
  1987.   ""
  1988.   "andn %2,%1,%0\;andn %R2,%R1,%R0"
  1989.   [(set_attr "length" "2")])
  1990.  
  1991. (define_insn ""
  1992.   [(set (match_operand:SI 0 "register_operand" "=r")
  1993.     (and:SI (not:SI (match_operand:SI 1 "register_operand" "r"))
  1994.         (match_operand:SI 2 "register_operand" "r")))]
  1995.   ""
  1996.   "andn %2,%1,%0")
  1997.  
  1998. (define_expand "iordi3"
  1999.   [(set (match_operand:DI 0 "register_operand" "")
  2000.     (ior:DI (match_operand:DI 1 "arith_double_operand" "")
  2001.         (match_operand:DI 2 "arith_double_operand" "")))]
  2002.   ""
  2003.   "")
  2004.  
  2005. (define_insn ""
  2006.   [(set (match_operand:DI 0 "register_operand" "=r")
  2007.     (ior:DI (match_operand:DI 1 "arith_double_operand" "%r")
  2008.         (match_operand:DI 2 "arith_double_operand" "rHI")))]
  2009.   ""
  2010.   "*
  2011. {
  2012.   rtx op2 = operands[2];
  2013.  
  2014.   /* If constant is positive, upper bits zeroed, otherwise unchanged.
  2015.      Give the assembler a chance to pick the move instruction. */
  2016.   if (GET_CODE (op2) == CONST_INT)
  2017.     {
  2018.       int sign = INTVAL (op2);
  2019.       if (sign < 0)
  2020.     return \"mov -1,%0\;or %R1,%2,%R0\";
  2021.       return \"mov %1,%0\;or %R1,%2,%R0\";
  2022.     }
  2023.   else if (GET_CODE (op2) == CONST_DOUBLE)
  2024.     {
  2025.       int sign = CONST_DOUBLE_HIGH (op2);
  2026.       operands[2] = gen_rtx (CONST_INT, VOIDmode,
  2027.                  CONST_DOUBLE_LOW (operands[1]));
  2028.       if (sign < 0)
  2029.     return \"mov -1,%0\;or %R1,%2,%R0\";
  2030.       return \"mov %1,%0\;or %R1,%2,%R0\";
  2031.     }
  2032.   return \"or %1,%2,%0\;or %R1,%R2,%R0\";
  2033. }"
  2034.   [(set_attr "length" "2")])
  2035.  
  2036. (define_insn "iorsi3"
  2037.   [(set (match_operand:SI 0 "register_operand" "=r")
  2038.     (ior:SI (match_operand:SI 1 "arith_operand" "%r")
  2039.         (match_operand:SI 2 "arith_operand" "rI")))]
  2040.   ""
  2041.   "or %1,%2,%0")
  2042.  
  2043. (define_split
  2044.   [(set (match_operand:SI 0 "register_operand" "")
  2045.     (ior:SI (match_operand:SI 1 "register_operand" "")
  2046.         (match_operand:SI 2 "" "")))
  2047.    (clobber (match_operand:SI 3 "register_operand" ""))]
  2048.   "GET_CODE (operands[2]) == CONST_INT
  2049.    && !SMALL_INT (operands[2])
  2050.    && (INTVAL (operands[2]) & 0x3ff) == 0x3ff"
  2051.   [(set (match_dup 3) (match_dup 4))
  2052.    (set (match_dup 0) (ior:SI (not:SI (match_dup 3)) (match_dup 1)))]
  2053.   "
  2054. {
  2055.   operands[4] = gen_rtx (CONST_INT, VOIDmode, ~INTVAL (operands[2]));
  2056. }")
  2057.  
  2058. (define_insn ""
  2059.   [(set (match_operand:DI 0 "register_operand" "=r")
  2060.     (ior:DI (not:DI (match_operand:DI 1 "register_operand" "r"))
  2061.         (match_operand:DI 2 "register_operand" "r")))]
  2062.   ""
  2063.   "orn %2,%1,%0\;orn %R2,%R1,%R0"
  2064.   [(set_attr "length" "2")])
  2065.  
  2066. (define_insn ""
  2067.   [(set (match_operand:SI 0 "register_operand" "=r")
  2068.     (ior:SI (not:SI (match_operand:SI 1 "register_operand" "r"))
  2069.         (match_operand:SI 2 "register_operand" "r")))]
  2070.   ""
  2071.   "orn %2,%1,%0")
  2072.  
  2073. (define_expand "xordi3"
  2074.   [(set (match_operand:DI 0 "register_operand" "")
  2075.     (xor:DI (match_operand:DI 1 "arith_double_operand" "")
  2076.         (match_operand:DI 2 "arith_double_operand" "")))]
  2077.   ""
  2078.   "")
  2079.  
  2080. (define_insn ""
  2081.   [(set (match_operand:DI 0 "register_operand" "=r")
  2082.     (xor:DI (match_operand:DI 1 "arith_double_operand" "%r")
  2083.         (match_operand:DI 2 "arith_double_operand" "rHI")))]
  2084.   ""
  2085.   "*
  2086. {
  2087.   rtx op2 = operands[2];
  2088.  
  2089.   /* If constant is positive, upper bits zeroed, otherwise unchanged.
  2090.      Give the assembler a chance to pick the move instruction. */
  2091.   if (GET_CODE (op2) == CONST_INT)
  2092.     {
  2093.       int sign = INTVAL (op2);
  2094.       if (sign < 0)
  2095.     return \"xor %1,-1,%0\;xor %R1,%2,%R0\";
  2096.       return \"mov %1,%0\;xor %R1,%2,%R0\";
  2097.     }
  2098.   else if (GET_CODE (op2) == CONST_DOUBLE)
  2099.     {
  2100.       int sign = CONST_DOUBLE_HIGH (op2);
  2101.       operands[2] = gen_rtx (CONST_INT, VOIDmode,
  2102.                  CONST_DOUBLE_LOW (operands[1]));
  2103.       if (sign < 0)
  2104.     return \"xor %1,-1,%0\;xor %R1,%2,%R0\";
  2105.       return \"mov %1,%0\;xor %R1,%2,%R0\";
  2106.     }
  2107.   return \"xor %1,%2,%0\;xor %R1,%R2,%R0\";
  2108. }"
  2109.   [(set_attr "length" "2")])
  2110.  
  2111. (define_insn "xorsi3"
  2112.   [(set (match_operand:SI 0 "register_operand" "=r")
  2113.     (xor:SI (match_operand:SI 1 "arith_operand" "%rJ")
  2114.         (match_operand:SI 2 "arith_operand" "rI")))]
  2115.   ""
  2116.   "xor %r1,%2,%0")
  2117.  
  2118. (define_split
  2119.   [(set (match_operand:SI 0 "register_operand" "")
  2120.     (xor:SI (match_operand:SI 1 "register_operand" "")
  2121.         (match_operand:SI 2 "" "")))
  2122.    (clobber (match_operand:SI 3 "register_operand" ""))]
  2123.   "GET_CODE (operands[2]) == CONST_INT
  2124.    && !SMALL_INT (operands[2])
  2125.    && (INTVAL (operands[2]) & 0x3ff) == 0x3ff"
  2126.   [(set (match_dup 3) (match_dup 4))
  2127.    (set (match_dup 0) (not:SI (xor:SI (match_dup 3) (match_dup 1))))]
  2128.   "
  2129. {
  2130.   operands[4] = gen_rtx (CONST_INT, VOIDmode, ~INTVAL (operands[2]));
  2131. }")
  2132.  
  2133. (define_split
  2134.   [(set (match_operand:SI 0 "register_operand" "")
  2135.     (not:SI (xor:SI (match_operand:SI 1 "register_operand" "")
  2136.             (match_operand:SI 2 "" ""))))
  2137.    (clobber (match_operand:SI 3 "register_operand" ""))]
  2138.   "GET_CODE (operands[2]) == CONST_INT
  2139.    && !SMALL_INT (operands[2])
  2140.    && (INTVAL (operands[2]) & 0x3ff) == 0x3ff"
  2141.   [(set (match_dup 3) (match_dup 4))
  2142.    (set (match_dup 0) (xor:SI (match_dup 3) (match_dup 1)))]
  2143.   "
  2144. {
  2145.   operands[4] = gen_rtx (CONST_INT, VOIDmode, ~INTVAL (operands[2]));
  2146. }")
  2147.  
  2148. ;; xnor patterns.  Note that (a ^ ~b) == (~a ^ b) == ~(a ^ b).
  2149. ;; Combine now canonicalizes to the rightmost expression.
  2150. (define_insn ""
  2151.   [(set (match_operand:DI 0 "register_operand" "=r")
  2152.     (not:DI (xor:DI (match_operand:DI 1 "register_operand" "r")
  2153.             (match_operand:DI 2 "register_operand" "r"))))]
  2154.   ""
  2155.   "xnor %1,%2,%0\;xnor %R1,%R2,%R0"
  2156.   [(set_attr "length" "2")])
  2157.  
  2158. (define_insn ""
  2159.   [(set (match_operand:SI 0 "register_operand" "=r")
  2160.     (not:SI (xor:SI (match_operand:SI 1 "reg_or_0_operand" "rJ")
  2161.             (match_operand:SI 2 "arith_operand" "rI"))))]
  2162.   ""
  2163.   "xnor %r1,%2,%0")
  2164.  
  2165. ;; These correspond to the above in the case where we also (or only)
  2166. ;; want to set the condition code.  
  2167.  
  2168. (define_insn ""
  2169.   [(set (reg:CC 0)
  2170.     (compare:CC
  2171.      (match_operator:SI 2 "cc_arithop"
  2172.                 [(match_operand:SI 0 "arith_operand" "%r")
  2173.                  (match_operand:SI 1 "arith_operand" "rI")])
  2174.      (const_int 0)))]
  2175.   ""
  2176.   "%A2cc %0,%1,%%g0"
  2177.   [(set_attr "type" "compare")])
  2178.  
  2179. (define_insn ""
  2180.   [(set (reg:CC 0)
  2181.     (compare:CC
  2182.      (match_operator:SI 3 "cc_arithop"
  2183.                 [(match_operand:SI 1 "arith_operand" "%r")
  2184.                  (match_operand:SI 2 "arith_operand" "rI")])
  2185.      (const_int 0)))
  2186.    (set (match_operand:SI 0 "register_operand" "=r")
  2187.     (match_dup 3))]
  2188.   ""
  2189.   "%A3cc %1,%2,%0")
  2190.  
  2191. (define_insn ""
  2192.   [(set (reg:CC 0)
  2193.     (compare:CC
  2194.      (not:SI (xor:SI (match_operand:SI 0 "reg_or_0_operand" "%rJ")
  2195.              (match_operand:SI 1 "arith_operand" "rI")))
  2196.      (const_int 0)))]
  2197.   ""
  2198.   "xnorcc %r0,%1,%%g0"
  2199.   [(set_attr "type" "compare")])
  2200.  
  2201. (define_insn ""
  2202.   [(set (reg:CC 0)
  2203.     (compare:CC
  2204.      (not:SI (xor:SI (match_operand:SI 1 "reg_or_0_operand" "%rJ")
  2205.              (match_operand:SI 2 "arith_operand" "rI")))
  2206.      (const_int 0)))
  2207.    (set (match_operand:SI 0 "register_operand" "=r")
  2208.     (not:SI (xor:SI (match_dup 1) (match_dup 2))))]
  2209.   ""
  2210.   "xnorcc %r1,%2,%0")
  2211.  
  2212. (define_insn ""
  2213.   [(set (reg:CC 0)
  2214.     (compare:CC
  2215.      (match_operator:SI 2 "cc_arithopn"
  2216.                 [(not:SI (match_operand:SI 0 "arith_operand" "rI"))
  2217.                  (match_operand:SI 1 "reg_or_0_operand" "rJ")])
  2218.      (const_int 0)))]
  2219.   ""
  2220.   "%B2cc %r1,%0,%%g0"
  2221.   [(set_attr "type" "compare")])
  2222.  
  2223. (define_insn ""
  2224.   [(set (reg:CC 0)
  2225.     (compare:CC
  2226.      (match_operator:SI 3 "cc_arithopn"
  2227.                 [(not:SI (match_operand:SI 1 "arith_operand" "rI"))
  2228.                  (match_operand:SI 2 "reg_or_0_operand" "rJ")])
  2229.      (const_int 0)))
  2230.    (set (match_operand:SI 0 "register_operand" "=r")
  2231.     (match_dup 3))]
  2232.   ""
  2233.   "%B3cc %r2,%1,%0")
  2234.  
  2235. ;; We cannot use the "neg" pseudo insn because the Sun assembler
  2236. ;; does not know how to make it work for constants.
  2237.  
  2238. (define_insn "negdi2"
  2239.   [(set (match_operand:DI 0 "register_operand" "=r")
  2240.     (neg:DI (match_operand:DI 1 "register_operand" "r")))
  2241.    (clobber (reg:SI 0))]
  2242.   ""
  2243.   "subcc %%g0,%R1,%R0\;subx %%g0,%1,%0"
  2244.   [(set_attr "type" "unary")
  2245.    (set_attr "length" "2")])
  2246.  
  2247. (define_insn "negsi2"
  2248.   [(set (match_operand:SI 0 "general_operand" "=r")
  2249.     (neg:SI (match_operand:SI 1 "arith_operand" "rI")))]
  2250.   ""
  2251.   "sub %%g0,%1,%0"
  2252.   [(set_attr "type" "unary")])
  2253.  
  2254. (define_insn ""
  2255.   [(set (reg:CC_NOOV 0)
  2256.     (compare:CC_NOOV (neg:SI (match_operand:SI 0 "arith_operand" "rI"))
  2257.              (const_int 0)))]
  2258.   ""
  2259.   "subcc %%g0,%0,%%g0"
  2260.   [(set_attr "type" "compare")])
  2261.  
  2262. (define_insn ""
  2263.   [(set (reg:CC_NOOV 0)
  2264.     (compare:CC_NOOV (neg:SI (match_operand:SI 1 "arith_operand" "rI"))
  2265.              (const_int 0)))
  2266.    (set (match_operand:SI 0 "register_operand" "=r")
  2267.     (neg:SI (match_dup 1)))]
  2268.   ""
  2269.   "subcc %%g0,%1,%0"
  2270.   [(set_attr "type" "unary")])
  2271.  
  2272. ;; We cannot use the "not" pseudo insn because the Sun assembler
  2273. ;; does not know how to make it work for constants.
  2274. (define_expand "one_cmpldi2"
  2275.   [(set (match_operand:DI 0 "register_operand" "=r")
  2276.     (not:DI (match_operand:DI 1 "arith_double_operand" "rHI")))]
  2277.   ""
  2278.   "")
  2279.  
  2280. (define_insn ""
  2281.   [(set (match_operand:DI 0 "register_operand" "=r")
  2282.     (not:DI (match_operand:DI 1 "arith_double_operand" "rHI")))]
  2283.   ""
  2284.   "*
  2285. {
  2286.   rtx op1 = operands[1];
  2287.  
  2288.   if (GET_CODE (op1) == CONST_INT)
  2289.     {
  2290.       int sign = INTVAL (op1);
  2291.       if (sign < 0)
  2292.     return \"xnor %%g0,%1,%R0\;xnor %%g0,-1,%0\";
  2293.       return \"xnor %%g0,%1,%R0\;xnor %%g0,0,%0\";
  2294.     }
  2295.   else if (GET_CODE (op1) == CONST_DOUBLE)
  2296.     {
  2297.       int sign = CONST_DOUBLE_HIGH (op1);
  2298.       operands[1] = gen_rtx (CONST_INT, VOIDmode,
  2299.                  CONST_DOUBLE_LOW (operands[1]));
  2300.       if (sign < 0)
  2301.     return \"xnor %%g0,%1,%R0\;xnor %%g0,-1,%0\";
  2302.       return \"xnor %%g0,%1,%R0\;xnor %%g0,0,%0\";
  2303.     }
  2304.   return \"xnor %%g0,%1,%0\;xnor %%g0,%R1,%R0\";
  2305. }"
  2306.   [(set_attr "type" "unary")
  2307.    (set_attr "length" "2")])
  2308.  
  2309. (define_insn "one_cmplsi2"
  2310.   [(set (match_operand:SI 0 "register_operand" "=r")
  2311.     (not:SI (match_operand:SI 1 "arith_operand" "rI")))]
  2312.   ""
  2313.   "xnor %%g0,%1,%0"
  2314.   [(set_attr "type" "unary")])
  2315.  
  2316. (define_insn ""
  2317.   [(set (reg:CC 0)
  2318.     (compare:CC (not:SI (match_operand:SI 0 "arith_operand" "rI"))
  2319.             (const_int 0)))]
  2320.   ""
  2321.   "xnorcc %%g0,%0,%%g0"
  2322.   [(set_attr "type" "compare")])
  2323.  
  2324. (define_insn ""
  2325.   [(set (reg:CC 0)
  2326.     (compare:CC (not:SI (match_operand:SI 1 "arith_operand" "rI"))
  2327.             (const_int 0)))
  2328.    (set (match_operand:SI 0 "register_operand" "=r")
  2329.     (not:SI (match_dup 1)))]
  2330.   ""
  2331.   "xnorcc %%g0,%1,%0"
  2332.   [(set_attr "type" "unary")])
  2333.  
  2334. ;; Floating point arithmetic instructions.
  2335.  
  2336. (define_insn "addtf3"
  2337.   [(set (match_operand:TF 0 "register_operand" "=f")
  2338.     (plus:TF (match_operand:TF 1 "register_operand" "f")
  2339.          (match_operand:TF 2 "register_operand" "f")))]
  2340.   "TARGET_FPU"
  2341.   "faddq %1,%2,%0"
  2342.   [(set_attr "type" "fp")])
  2343.  
  2344. (define_insn "adddf3"
  2345.   [(set (match_operand:DF 0 "register_operand" "=f")
  2346.     (plus:DF (match_operand:DF 1 "register_operand" "f")
  2347.          (match_operand:DF 2 "register_operand" "f")))]
  2348.   "TARGET_FPU"
  2349.   "faddd %1,%2,%0"
  2350.   [(set_attr "type" "fp")])
  2351.  
  2352. (define_insn "addsf3"
  2353.   [(set (match_operand:SF 0 "register_operand" "=f")
  2354.     (plus:SF (match_operand:SF 1 "register_operand" "f")
  2355.          (match_operand:SF 2 "register_operand" "f")))]
  2356.   "TARGET_FPU"
  2357.   "fadds %1,%2,%0"
  2358.   [(set_attr "type" "fp")])
  2359.  
  2360. (define_insn "subtf3"
  2361.   [(set (match_operand:TF 0 "register_operand" "=f")
  2362.     (minus:TF (match_operand:TF 1 "register_operand" "f")
  2363.           (match_operand:TF 2 "register_operand" "f")))]
  2364.   "TARGET_FPU"
  2365.   "fsubq %1,%2,%0"
  2366.   [(set_attr "type" "fp")])
  2367.  
  2368. (define_insn "subdf3"
  2369.   [(set (match_operand:DF 0 "register_operand" "=f")
  2370.     (minus:DF (match_operand:DF 1 "register_operand" "f")
  2371.           (match_operand:DF 2 "register_operand" "f")))]
  2372.   "TARGET_FPU"
  2373.   "fsubd %1,%2,%0"
  2374.   [(set_attr "type" "fp")])
  2375.  
  2376. (define_insn "subsf3"
  2377.   [(set (match_operand:SF 0 "register_operand" "=f")
  2378.     (minus:SF (match_operand:SF 1 "register_operand" "f")
  2379.           (match_operand:SF 2 "register_operand" "f")))]
  2380.   "TARGET_FPU"
  2381.   "fsubs %1,%2,%0"
  2382.   [(set_attr "type" "fp")])
  2383.  
  2384. (define_insn "multf3"
  2385.   [(set (match_operand:TF 0 "register_operand" "=f")
  2386.     (mult:TF (match_operand:TF 1 "register_operand" "f")
  2387.          (match_operand:TF 2 "register_operand" "f")))]
  2388.   "TARGET_FPU"
  2389.   "fmulq %1,%2,%0"
  2390.   [(set_attr "type" "fpmul")])
  2391.  
  2392. (define_insn "muldf3"
  2393.   [(set (match_operand:DF 0 "register_operand" "=f")
  2394.     (mult:DF (match_operand:DF 1 "register_operand" "f")
  2395.          (match_operand:DF 2 "register_operand" "f")))]
  2396.   "TARGET_FPU"
  2397.   "fmuld %1,%2,%0"
  2398.   [(set_attr "type" "fpmul")])
  2399.  
  2400. (define_insn "mulsf3"
  2401.   [(set (match_operand:SF 0 "register_operand" "=f")
  2402.     (mult:SF (match_operand:SF 1 "register_operand" "f")
  2403.          (match_operand:SF 2 "register_operand" "f")))]
  2404.   "TARGET_FPU"
  2405.   "fmuls %1,%2,%0"
  2406.   [(set_attr "type" "fpmul")])
  2407.  
  2408. (define_insn ""
  2409.   [(set (match_operand:DF 0 "register_operand" "=f")
  2410.     (mult:DF (float_extend:DF (match_operand:SF 1 "register_operand" "f"))
  2411.          (float_extend:DF (match_operand:SF 2 "register_operand" "f"))))]
  2412.   "TARGET_V8 && TARGET_FPU"
  2413.   "fsmuld %1,%2,%0"
  2414.   [(set_attr "type" "fpmul")])
  2415.  
  2416. (define_insn ""
  2417.   [(set (match_operand:TF 0 "register_operand" "=f")
  2418.     (mult:TF (float_extend:TF (match_operand:DF 1 "register_operand" "f"))
  2419.          (float_extend:TF (match_operand:DF 2 "register_operand" "f"))))]
  2420.   "TARGET_V8 && TARGET_FPU"
  2421.   "fdmulq %1,%2,%0"
  2422.   [(set_attr "type" "fpmul")])
  2423.  
  2424. (define_insn "divtf3"
  2425.   [(set (match_operand:TF 0 "register_operand" "=f")
  2426.     (div:TF (match_operand:TF 1 "register_operand" "f")
  2427.         (match_operand:TF 2 "register_operand" "f")))]
  2428.   "TARGET_FPU"
  2429.   "fdivq %1,%2,%0"
  2430.   [(set_attr "type" "fpdiv")])
  2431.  
  2432. (define_insn "divdf3"
  2433.   [(set (match_operand:DF 0 "register_operand" "=f")
  2434.     (div:DF (match_operand:DF 1 "register_operand" "f")
  2435.         (match_operand:DF 2 "register_operand" "f")))]
  2436.   "TARGET_FPU"
  2437.   "fdivd %1,%2,%0"
  2438.   [(set_attr "type" "fpdiv")])
  2439.  
  2440. (define_insn "divsf3"
  2441.   [(set (match_operand:SF 0 "register_operand" "=f")
  2442.     (div:SF (match_operand:SF 1 "register_operand" "f")
  2443.         (match_operand:SF 2 "register_operand" "f")))]
  2444.   "TARGET_FPU"
  2445.   "fdivs %1,%2,%0"
  2446.   [(set_attr "type" "fpdiv")])
  2447.  
  2448. (define_insn "negtf2"
  2449.   [(set (match_operand:TF 0 "register_operand" "=f,f")
  2450.     (neg:TF (match_operand:TF 1 "register_operand" "0,f")))]
  2451.   "TARGET_FPU"
  2452.   "@
  2453.    fnegs %0,%0
  2454.    fnegs %1,%0\;fmovs %R1,%R0\;fmovs %S1,%S0\;fmovs %T1,%T0"
  2455.   [(set_attr "type" "fp")
  2456.    (set_attr "length" "1,4")])
  2457.  
  2458. (define_insn "negdf2"
  2459.   [(set (match_operand:DF 0 "register_operand" "=f,f")
  2460.     (neg:DF (match_operand:DF 1 "register_operand" "0,f")))]
  2461.   "TARGET_FPU"
  2462.   "@
  2463.    fnegs %0,%0
  2464.    fnegs %1,%0\;fmovs %R1,%R0"
  2465.   [(set_attr "type" "fp")
  2466.    (set_attr "length" "1,2")])
  2467.  
  2468. (define_insn "negsf2"
  2469.   [(set (match_operand:SF 0 "register_operand" "=f")
  2470.     (neg:SF (match_operand:SF 1 "register_operand" "f")))]
  2471.   "TARGET_FPU"
  2472.   "fnegs %1,%0"
  2473.   [(set_attr "type" "fp")])
  2474.  
  2475. (define_insn "abstf2"
  2476.   [(set (match_operand:TF 0 "register_operand" "=f,f")
  2477.     (abs:TF (match_operand:TF 1 "register_operand" "0,f")))]
  2478.   "TARGET_FPU"
  2479.   "@
  2480.    fabss %0,%0
  2481.    fabss %1,%0\;fmovs %R1,%R0\;fmovs %S1,%S0\;fmovs %T1,%T0"
  2482.   [(set_attr "type" "fp")
  2483.    (set_attr "length" "1,4")])
  2484.  
  2485. (define_insn "absdf2"
  2486.   [(set (match_operand:DF 0 "register_operand" "=f,f")
  2487.     (abs:DF (match_operand:DF 1 "register_operand" "0,f")))]
  2488.   "TARGET_FPU"
  2489.   "@
  2490.    fabss %0,%0
  2491.    fabss %1,%0\;fmovs %R1,%R0"
  2492.   [(set_attr "type" "fp")
  2493.    (set_attr "length" "1,2")])
  2494.  
  2495. (define_insn "abssf2"
  2496.   [(set (match_operand:SF 0 "register_operand" "=f")
  2497.     (abs:SF (match_operand:SF 1 "register_operand" "f")))]
  2498.   "TARGET_FPU"
  2499.   "fabss %1,%0"
  2500.   [(set_attr "type" "fp")])
  2501.  
  2502. (define_insn "sqrttf2"
  2503.   [(set (match_operand:TF 0 "register_operand" "=f")
  2504.     (sqrt:TF (match_operand:TF 1 "register_operand" "f")))]
  2505.   "TARGET_FPU"
  2506.   "fsqrtq %1,%0"
  2507.   [(set_attr "type" "fpsqrt")])
  2508.  
  2509. (define_insn "sqrtdf2"
  2510.   [(set (match_operand:DF 0 "register_operand" "=f")
  2511.     (sqrt:DF (match_operand:DF 1 "register_operand" "f")))]
  2512.   "TARGET_FPU"
  2513.   "fsqrtd %1,%0"
  2514.   [(set_attr "type" "fpsqrt")])
  2515.  
  2516. (define_insn "sqrtsf2"
  2517.   [(set (match_operand:SF 0 "register_operand" "=f")
  2518.     (sqrt:SF (match_operand:SF 1 "register_operand" "f")))]
  2519.   "TARGET_FPU"
  2520.   "fsqrts %1,%0"
  2521.   [(set_attr "type" "fpsqrt")])
  2522.  
  2523. ;;- arithmetic shift instructions
  2524.  
  2525. (define_insn "ashlsi3"
  2526.   [(set (match_operand:SI 0 "register_operand" "=r")
  2527.     (ashift:SI (match_operand:SI 1 "register_operand" "r")
  2528.            (match_operand:SI 2 "arith_operand" "rI")))]
  2529.   ""
  2530.   "*
  2531. {
  2532.   if (GET_CODE (operands[2]) == CONST_INT
  2533.       && (unsigned) INTVAL (operands[2]) > 31)
  2534.     operands[2] = GEN_INT (INTVAL (operands[2]) & 0x1f);
  2535.  
  2536.   return \"sll %1,%2,%0\";
  2537. }")
  2538.  
  2539. (define_insn ""
  2540.   [(set (reg:CC_NOOV 0)
  2541.     (compare:CC_NOOV (ashift:SI (match_operand:SI 0 "register_operand" "r")
  2542.                     (const_int 1))
  2543.              (const_int 0)))]
  2544.   ""
  2545.   "addcc %0,%0,%%g0"
  2546.   [(set_attr "type" "compare")])
  2547.  
  2548. (define_insn ""
  2549.   [(set (reg:CC_NOOV 0)
  2550.     (compare:CC_NOOV (ashift:SI (match_operand:SI 1 "register_operand" "r")
  2551.                     (const_int 1))
  2552.              (const_int 0)))
  2553.    (set (match_operand:SI 0 "register_operand" "=r")
  2554.     (ashift:SI (match_dup 1) (const_int 1)))]
  2555.   ""
  2556.   "addcc %1,%1,%0")
  2557.  
  2558. (define_insn "ashrsi3"
  2559.   [(set (match_operand:SI 0 "register_operand" "=r")
  2560.     (ashiftrt:SI (match_operand:SI 1 "register_operand" "r")
  2561.              (match_operand:SI 2 "arith_operand" "rI")))]
  2562.   ""
  2563.   "*
  2564. {
  2565.   if (GET_CODE (operands[2]) == CONST_INT
  2566.       && (unsigned) INTVAL (operands[2]) > 31)
  2567.     operands[2] = GEN_INT (INTVAL (operands[2]) & 0x1f);
  2568.  
  2569.   return \"sra %1,%2,%0\";
  2570. }")
  2571.  
  2572. (define_insn "lshrsi3"
  2573.   [(set (match_operand:SI 0 "register_operand" "=r")
  2574.     (lshiftrt:SI (match_operand:SI 1 "register_operand" "r")
  2575.              (match_operand:SI 2 "arith_operand" "rI")))]
  2576.   ""
  2577.   "*
  2578. {
  2579.   if (GET_CODE (operands[2]) == CONST_INT
  2580.       && (unsigned) INTVAL (operands[2]) > 31)
  2581.     operands[2] = GEN_INT (INTVAL (operands[2]) & 0x1f);
  2582.  
  2583.   return \"srl %1,%2,%0\";
  2584. }")
  2585.  
  2586. ;; Unconditional and other jump instructions
  2587. ;; On the Sparc, by setting the annul bit on an unconditional branch, the
  2588. ;; following insn is never executed.  This saves us a nop.  Dbx does not
  2589. ;; handle such branches though, so we only use them when optimizing.
  2590. (define_insn "jump"
  2591.   [(set (pc) (label_ref (match_operand 0 "" "")))]
  2592.   ""
  2593.   "b%* %l0%("
  2594.   [(set_attr "type" "uncond_branch")])
  2595.  
  2596. (define_expand "tablejump"
  2597.   [(parallel [(set (pc) (match_operand:SI 0 "register_operand" "r"))
  2598.           (use (label_ref (match_operand 1 "" "")))])]
  2599.   ""
  2600.   "
  2601. {
  2602.   /* We need to use the PC value in %o7 that was set up when the address
  2603.      of the label was loaded into a register, so we need different RTL.  */
  2604.   if (flag_pic)
  2605.     {
  2606.       emit_insn (gen_pic_tablejump (operands[0], operands[1]));
  2607.       DONE;
  2608.     }
  2609. }")
  2610.  
  2611. (define_insn "pic_tablejump"
  2612.   [(set (pc) (match_operand:SI 0 "register_operand" "r"))
  2613.    (use (label_ref (match_operand 1 "" "")))
  2614.    (use (reg:SI 15))]
  2615.   ""
  2616.   "jmp %%o7+%0%#"
  2617.   [(set_attr "type" "uncond_branch")])
  2618.  
  2619. (define_insn ""
  2620.   [(set (pc) (match_operand:SI 0 "address_operand" "p"))
  2621.    (use (label_ref (match_operand 1 "" "")))]
  2622.   ""
  2623.   "jmp %a0%#"
  2624.   [(set_attr "type" "uncond_branch")])
  2625.  
  2626. (define_insn ""
  2627.   [(set (pc) (label_ref (match_operand 0 "" "")))
  2628.    (set (reg:SI 15) (label_ref (match_dup 0)))]
  2629.   ""
  2630.   "call %l0%#"
  2631.   [(set_attr "type" "uncond_branch")])
  2632.  
  2633. ;; This pattern recognizes the "instruction" that appears in 
  2634. ;; a function call that wants a structure value, 
  2635. ;; to inform the called function if compiled with Sun CC.
  2636. ;(define_insn ""
  2637. ;  [(match_operand:SI 0 "immediate_operand" "")]
  2638. ;  "GET_CODE (operands[0]) == CONST_INT && INTVAL (operands[0]) > 0"
  2639. ;  "unimp %0"
  2640. ;  [(set_attr "type" "marker")])
  2641.  
  2642. ;;- jump to subroutine
  2643. (define_expand "call"
  2644.   ;; Note that this expression is not used for generating RTL.
  2645.   ;; All the RTL is generated explicitly below.
  2646.   [(call (match_operand:SI 0 "call_operand" "")
  2647.      (match_operand 3 "" "i"))]
  2648.   ;; operands[2] is next_arg_register
  2649.   ;; operands[3] is struct_value_size_rtx.
  2650.   ""
  2651.   "
  2652. {
  2653.   rtx fn_rtx, nregs_rtx;
  2654.  
  2655.   if (GET_CODE (XEXP (operands[0], 0)) == LABEL_REF)
  2656.     {
  2657.       /* This is really a PIC sequence.  We want to represent
  2658.      it as a funny jump so it's delay slots can be filled. 
  2659.  
  2660.      ??? But if this really *is* a CALL, will not it clobber the
  2661.      call-clobbered registers?  We lose this if it is a JUMP_INSN.
  2662.      Why cannot we have delay slots filled if it were a CALL?  */
  2663.  
  2664.       if (INTVAL (operands[3]) > 0)
  2665.     emit_jump_insn (gen_rtx (PARALLEL, VOIDmode, gen_rtvec (3,
  2666.                  gen_rtx (SET, VOIDmode, pc_rtx,
  2667.                       XEXP (operands[0], 0)),
  2668.                  operands[3],
  2669.                  gen_rtx (CLOBBER, VOIDmode,
  2670.                       gen_rtx (REG, SImode, 15)))));
  2671.       else
  2672.     emit_jump_insn (gen_rtx (PARALLEL, VOIDmode, gen_rtvec (2,
  2673.                  gen_rtx (SET, VOIDmode, pc_rtx,
  2674.                       XEXP (operands[0], 0)),
  2675.                  gen_rtx (CLOBBER, VOIDmode,
  2676.                       gen_rtx (REG, SImode, 15)))));
  2677.       goto finish_call;
  2678.     }
  2679.  
  2680.   fn_rtx = operands[0];
  2681.  
  2682.   /* Count the number of parameter registers being used by this call.
  2683.      if that argument is NULL, it means we are using them all, which
  2684.      means 6 on the sparc.  */
  2685. #if 0
  2686.   if (operands[2])
  2687.     nregs_rtx = gen_rtx (CONST_INT, VOIDmode, REGNO (operands[2]) - 8);
  2688.   else
  2689.     nregs_rtx = gen_rtx (CONST_INT, VOIDmode, 6);
  2690. #else
  2691.   nregs_rtx = const0_rtx;
  2692. #endif
  2693.  
  2694.   if (INTVAL (operands[3]) > 0)
  2695.     emit_call_insn (gen_rtx (PARALLEL, VOIDmode, gen_rtvec (3,
  2696.                  gen_rtx (CALL, VOIDmode, fn_rtx, nregs_rtx),
  2697.                  operands[3],
  2698.                  gen_rtx (CLOBBER, VOIDmode,
  2699.                            gen_rtx (REG, SImode, 15)))));
  2700.   else
  2701.     emit_call_insn (gen_rtx (PARALLEL, VOIDmode, gen_rtvec (2,
  2702.                  gen_rtx (CALL, VOIDmode, fn_rtx, nregs_rtx),
  2703.                  gen_rtx (CLOBBER, VOIDmode,
  2704.                            gen_rtx (REG, SImode, 15)))));
  2705.  
  2706.  finish_call:
  2707. #if 0
  2708.   /* If this call wants a structure value,
  2709.      emit an unimp insn to let the called function know about this.  */
  2710.   if (INTVAL (operands[3]) > 0)
  2711.     {
  2712.       rtx insn = emit_insn (operands[3]);
  2713.       SCHED_GROUP_P (insn) = 1;
  2714.     }
  2715. #endif
  2716.  
  2717.   DONE;
  2718. }")
  2719.  
  2720. ;; We can't use the same pattern for these two insns, because then registers
  2721. ;; in the address may not be properly reloaded.
  2722.  
  2723. (define_insn ""
  2724.   [(call (mem:SI (match_operand:SI 0 "address_operand" "p"))
  2725.      (match_operand 1 "" ""))
  2726.    (clobber (reg:SI 15))]
  2727.   ;;- Do not use operand 1 for most machines.
  2728.   ""
  2729.   "*
  2730. {
  2731.   return \"call %a0,%1%#\";
  2732. }"
  2733.   [(set_attr "type" "call")])
  2734.  
  2735. (define_insn ""
  2736.   [(call (mem:SI (match_operand:SI 0 "immediate_operand" "i"))
  2737.      (match_operand 1 "" ""))
  2738.    (clobber (reg:SI 15))]
  2739.   ;;- Do not use operand 1 for most machines.
  2740.   ""
  2741.   "*
  2742. {
  2743.   return \"call %a0,%1%#\";
  2744. }"
  2745.   [(set_attr "type" "call")])
  2746.  
  2747. ;; This is a call that wants a structure value.
  2748. (define_insn ""
  2749.   [(call (mem:SI (match_operand:SI 0 "address_operand" "p"))
  2750.      (match_operand 1 "" ""))
  2751.    (match_operand 2 "immediate_operand" "")
  2752.    (clobber (reg:SI 15))]
  2753.   ;;- Do not use operand 1 for most machines.
  2754.   "GET_CODE (operands[2]) == CONST_INT && INTVAL (operands[2]) > 0"
  2755.   "*
  2756. {
  2757.   return \"call %a0,%1\;nop\;unimp %2\";
  2758. }"
  2759.   [(set_attr "type" "call_no_delay_slot")])
  2760.  
  2761. ;; This is a call that wants a structure value.
  2762. (define_insn ""
  2763.   [(call (mem:SI (match_operand:SI 0 "immediate_operand" "i"))
  2764.      (match_operand 1 "" ""))
  2765.    (match_operand 2 "immediate_operand" "")
  2766.    (clobber (reg:SI 15))]
  2767.   ;;- Do not use operand 1 for most machines.
  2768.   "GET_CODE (operands[2]) == CONST_INT && INTVAL (operands[2]) > 0"
  2769.   "*
  2770. {
  2771.   return \"call %a0,%1\;nop\;unimp %2\";
  2772. }"
  2773.   [(set_attr "type" "call_no_delay_slot")])
  2774.  
  2775. (define_expand "call_value"
  2776.   [(set (match_operand 0 "register_operand" "=rf")
  2777.     (call (match_operand:SI 1 "" "")
  2778.           (match_operand 4 "" "")))]
  2779.   ;; operand 3 is next_arg_register
  2780.   ""
  2781.   "
  2782. {
  2783.   rtx fn_rtx, nregs_rtx;
  2784.   rtvec vec;
  2785.  
  2786.   fn_rtx = operands[1];
  2787.  
  2788. #if 0
  2789.   if (operands[3])
  2790.     nregs_rtx = gen_rtx (CONST_INT, VOIDmode, REGNO (operands[3]) - 8);
  2791.   else
  2792.     nregs_rtx = gen_rtx (CONST_INT, VOIDmode, 6);
  2793. #else
  2794.   nregs_rtx = const0_rtx;
  2795. #endif
  2796.  
  2797.   vec = gen_rtvec (2,
  2798.            gen_rtx (SET, VOIDmode, operands[0],
  2799.                 gen_rtx (CALL, VOIDmode, fn_rtx, nregs_rtx)),
  2800.            gen_rtx (CLOBBER, VOIDmode, gen_rtx (REG, SImode, 15)));
  2801.  
  2802.   emit_call_insn (gen_rtx (PARALLEL, VOIDmode, vec));
  2803.  
  2804.   DONE;
  2805. }")
  2806.  
  2807. (define_insn ""
  2808.   [(set (match_operand 0 "" "=rf")
  2809.     (call (mem:SI (match_operand:SI 1 "address_operand" "p"))
  2810.           (match_operand 2 "" "")))
  2811.    (clobber (reg:SI 15))]
  2812.   ;;- Do not use operand 2 for most machines.
  2813.   ""
  2814.   "*
  2815. {
  2816.   return \"call %a1,%2%#\";
  2817. }"
  2818.   [(set_attr "type" "call")])
  2819.  
  2820. (define_insn ""
  2821.   [(set (match_operand 0 "" "=rf")
  2822.     (call (mem:SI (match_operand:SI 1 "immediate_operand" "i"))
  2823.           (match_operand 2 "" "")))
  2824.    (clobber (reg:SI 15))]
  2825.   ;;- Do not use operand 2 for most machines.
  2826.   ""
  2827.   "*
  2828. {
  2829.   return \"call %a1,%2%#\";
  2830. }"
  2831.   [(set_attr "type" "call")])
  2832.  
  2833. (define_expand "untyped_call"
  2834.   [(parallel [(call (match_operand:SI 0 "call_operand" "")
  2835.             (const_int 0))
  2836.           (match_operand:BLK 1 "memory_operand" "")
  2837.           (match_operand 2 "" "")
  2838.           (clobber (reg:SI 15))])]
  2839.   ""
  2840.   "
  2841. {
  2842.   operands[1] = change_address (operands[1], DImode, XEXP (operands[1], 0));
  2843. }")
  2844.  
  2845. ;; Make a call followed by two nops in case the function being called
  2846. ;; returns a structure value and expects to skip an unimp instruction.
  2847.  
  2848. (define_insn ""
  2849.   [(call (mem:SI (match_operand:SI 0 "address_operand" "p"))
  2850.      (const_int 0))
  2851.    (match_operand:DI 1 "memory_operand" "o")
  2852.    (match_operand 2 "" "")
  2853.    (clobber (reg:SI 15))]
  2854.   ""
  2855.   "*
  2856. {
  2857.   operands[2] = adj_offsettable_operand (operands[1], 8);
  2858.   return \"call %a0,0\;nop\;nop\;std %%o0,%1\;std %%f0,%2\";
  2859. }"
  2860.   [(set_attr "type" "multi")])
  2861.  
  2862. ;; Make a call followed by two nops in case the function being called
  2863. ;; returns a structure value and expects to skip an unimp instruction.
  2864.  
  2865. (define_insn ""
  2866.   [(call (mem:SI (match_operand:SI 0 "immediate_operand" "i"))
  2867.      (const_int 0))
  2868.    (match_operand:DI 1 "memory_operand" "o")
  2869.    (match_operand 2 "" "")
  2870.    (clobber (reg:SI 15))]
  2871.   ""
  2872.   "*
  2873. {
  2874.   operands[2] = adj_offsettable_operand (operands[1], 8);
  2875.   return \"call %a0,0\;nop\;nop\;std %%o0,%1\;std %%f0,%2\";
  2876. }"
  2877.   [(set_attr "type" "multi")])
  2878.  
  2879. ;; Prepare to return any type including a structure value.
  2880.  
  2881. (define_expand "untyped_return"
  2882.   [(match_operand:BLK 0 "memory_operand" "")
  2883.    (match_operand 1 "" "")]
  2884.   ""
  2885.   "
  2886. {
  2887.   rtx valreg1 = gen_rtx (REG, DImode, 24);
  2888.   rtx valreg2 = gen_rtx (REG, DFmode, 32);
  2889.   rtx result = operands[0];
  2890.   rtx rtnreg = gen_rtx (REG, SImode, (leaf_function ? 15 : 31));
  2891.   rtx value = gen_reg_rtx (SImode);
  2892.  
  2893.   /* Fetch the instruction where we will return to and see if it's an unimp
  2894.      instruction (the most significant 10 bits will be zero).  If so,
  2895.      update the return address to skip the unimp instruction.  */
  2896.   emit_move_insn (value,
  2897.           gen_rtx (MEM, SImode, plus_constant (rtnreg, 8)));
  2898.   emit_insn (gen_lshrsi3 (value, value, GEN_INT (22)));
  2899.   emit_insn (gen_update_return (rtnreg, value));
  2900.  
  2901.   /* Reload the function value registers.  */
  2902.   emit_move_insn (valreg1, change_address (result, DImode, XEXP (result, 0)));
  2903.   emit_move_insn (valreg2,
  2904.           change_address (result, DFmode,
  2905.                   plus_constant (XEXP (result, 0), 8)));
  2906.  
  2907.   /* Put USE insns before the return.  */
  2908.   emit_insn (gen_rtx (USE, VOIDmode, valreg1));
  2909.   emit_insn (gen_rtx (USE, VOIDmode, valreg2));
  2910.  
  2911.   /* Construct the return.  */
  2912.   expand_null_return ();
  2913.  
  2914.   DONE;
  2915. }")
  2916.  
  2917. ;; This is a bit of a hack.  We're incrementing a fixed register (%i7),
  2918. ;; and parts of the compiler don't want to believe that the add is needed.
  2919.  
  2920. (define_insn "update_return"
  2921.   [(unspec:SI [(match_operand:SI 0 "register_operand" "r")
  2922.            (match_operand:SI 1 "register_operand" "r")] 0)]
  2923.   ""
  2924.   "cmp %1,0\;be,a .+8\;add %0,4,%0"
  2925.   [(set_attr "type" "multi")])
  2926.  
  2927. (define_insn "return"
  2928.   [(return)]
  2929.   "! TARGET_EPILOGUE"
  2930.   "* return output_return (operands);"
  2931.   [(set_attr "type" "multi")])
  2932.  
  2933. (define_insn "nop"
  2934.   [(const_int 0)]
  2935.   ""
  2936.   "nop")
  2937.  
  2938. (define_insn "indirect_jump"
  2939.   [(set (pc) (match_operand:SI 0 "address_operand" "p"))]
  2940.   ""
  2941.  "jmp %a0%#"
  2942.  [(set_attr "type" "uncond_branch")])
  2943.  
  2944. (define_expand "nonlocal_goto"
  2945.   [(match_operand:SI 0 "general_operand" "")
  2946.    (match_operand:SI 1 "general_operand" "")
  2947.    (match_operand:SI 2 "general_operand" "")
  2948.    (match_operand:SI 3 "" "")]
  2949.   ""
  2950.   "
  2951. {
  2952.   /* Trap instruction to flush all the registers window.  */
  2953.   emit_insn (gen_flush_register_windows ());
  2954.   /* Load the fp value for the containing fn into %fp.
  2955.      This is needed because operands[2] refers to %fp.
  2956.      Virtual register instantiation fails if the virtual %fp isn't set from a
  2957.      register.  Thus we must copy operands[0] into a register if it isn't
  2958.      already one.  */
  2959.   if (GET_CODE (operands[0]) != REG)
  2960.     operands[0] = force_reg (SImode, operands[0]);
  2961.   emit_move_insn (virtual_stack_vars_rtx, operands[0]);
  2962.   /* Find the containing function's current nonlocal goto handler,
  2963.      which will do any cleanups and then jump to the label.  */
  2964.   emit_move_insn (gen_rtx (REG, SImode, 8), operands[1]);
  2965.   /* Restore %fp from stack pointer value for containing function.
  2966.      The restore insn that follows will move this to %sp,
  2967.      and reload the appropriate value into %fp.  */
  2968.   emit_move_insn (frame_pointer_rtx, operands[2]);
  2969.   /* Put in the static chain register the nonlocal label address.  */
  2970.   emit_move_insn (static_chain_rtx, operands[3]);
  2971.   /* USE of frame_pointer_rtx added for consistency; not clear if
  2972.      really needed.  */
  2973.   emit_insn (gen_rtx (USE, VOIDmode, frame_pointer_rtx));
  2974.   emit_insn (gen_rtx (USE, VOIDmode, stack_pointer_rtx));
  2975.   emit_insn (gen_rtx (USE, VOIDmode, static_chain_rtx));
  2976.   emit_insn (gen_rtx (USE, VOIDmode, gen_rtx (REG, SImode, 8)));
  2977.   /* Return, restoring reg window and jumping to goto handler.  */
  2978.   emit_insn (gen_goto_handler_and_restore ());
  2979.   DONE;
  2980. }")
  2981.  
  2982. ;; Special trap insn to flush register windows.
  2983. (define_insn "flush_register_windows"
  2984.   [(unspec_volatile [(const_int 0)] 0)]
  2985.   ""
  2986.   "ta 3"
  2987.   [(set_attr "type" "misc")])
  2988.  
  2989. (define_insn "goto_handler_and_restore"
  2990.   [(unspec_volatile [(const_int 0)] 1)]
  2991.   ""
  2992.   "jmp %%o0+0\;restore"
  2993.   [(set_attr "type" "misc")
  2994.    (set_attr "length" "2")])
  2995.  
  2996. ;; Special pattern for the FLUSH instruction.
  2997.  
  2998. (define_insn "flush"
  2999.   [(unspec_volatile [(match_operand 0 "" "")] 2)]
  3000.   ""
  3001.   "iflush %a0"
  3002.   [(set_attr "type" "misc")])
  3003.  
  3004. ;; find first set.
  3005.  
  3006. ;; The scan instruction searches from the most significant bit while ffs
  3007. ;; searches from the least significant bit.  The bit index and treatment of
  3008. ;; zero also differ.  It takes at least 7 instructions to get the proper
  3009. ;; result.  Here is an obvious 8 instruction seequence.
  3010.  
  3011. (define_insn "ffssi2"
  3012.   [(set (match_operand:SI 0 "register_operand" "=&r")
  3013.     (ffs:SI (match_operand:SI 1 "register_operand" "r")))
  3014.    (clobber (match_scratch:SI 2 "=&r"))]
  3015.   "TARGET_SPARCLITE"
  3016.   "sub %%g0,%1,%0\;and %0,%1,%0\;scan %0,0,%0\;mov 32,%2\;sub %2,%0,%0\;sra %0,31,%2\;and %2,31,%2\;add %2,%0,%0"
  3017.   [(set_attr "type" "multi")
  3018.    (set_attr "length" "8")])
  3019.  
  3020. ;; Split up troublesome insns for better scheduling.  */
  3021.  
  3022. ;; The following patterns are straightforward.  They can be applied
  3023. ;; either before or after register allocation.
  3024.  
  3025. (define_split
  3026.   [(set (match_operator 0 "memop" [(match_operand:SI 1 "symbolic_operand" "")])
  3027.     (match_operand 2 "reg_or_0_operand" ""))
  3028.    (clobber (match_operand:SI 3 "register_operand" ""))]
  3029.   "! flag_pic"
  3030.   [(set (match_dup 3) (high:SI (match_dup 1)))
  3031.    (set (match_op_dup 0 [(lo_sum:SI (match_dup 3) (match_dup 1))])
  3032.     (match_dup 2))]
  3033.   "")
  3034.  
  3035. (define_split
  3036.   [(set (match_operator 0 "memop"
  3037.             [(match_operand:SI 1 "immediate_operand" "")])
  3038.     (match_operand 2 "general_operand" ""))
  3039.    (clobber (match_operand:SI 3 "register_operand" ""))]
  3040.   "flag_pic"
  3041.   [(set (match_op_dup 0 [(match_dup 1)])
  3042.     (match_dup 2))]
  3043.   "
  3044. {
  3045.   operands[1] = legitimize_pic_address (operands[1], GET_MODE (operands[0]),
  3046.                     operands[3]);
  3047. }")
  3048.  
  3049. (define_split
  3050.   [(set (match_operand 0 "register_operand" "")
  3051.     (match_operator 1 "memop"
  3052.             [(match_operand:SI 2 "immediate_operand" "")]))]
  3053.   "flag_pic"
  3054.   [(set (match_dup 0)
  3055.     (match_op_dup 1 [(match_dup 2)]))]
  3056.   "
  3057. {
  3058.   operands[2] = legitimize_pic_address (operands[2], GET_MODE (operands[1]),
  3059.                     operands[0]);
  3060. }")
  3061.  
  3062. ;; Sign- and Zero-extend operations can have symbolic memory operands.
  3063.  
  3064. (define_split
  3065.   [(set (match_operand 0 "register_operand" "")
  3066.     (match_operator 1 "extend_op"
  3067.             [(match_operator 2 "memop"
  3068.                      [(match_operand:SI 3 "immediate_operand" "")])]))]
  3069.   "flag_pic"
  3070.   [(set (match_dup 0)
  3071.     (match_op_dup 1 [(match_op_dup 2 [(match_dup 3)])]))]
  3072.   "
  3073. {
  3074.   operands[3] = legitimize_pic_address (operands[3], GET_MODE (operands[2]),
  3075.                     operands[0]);
  3076. }")
  3077.  
  3078. (define_split
  3079.   [(set (match_operand:SI 0 "register_operand" "")
  3080.     (match_operand:SI 1 "immediate_operand" ""))]
  3081.   "! flag_pic && (GET_CODE (operands[1]) == SYMBOL_REF
  3082.           || GET_CODE (operands[1]) == CONST
  3083.           || GET_CODE (operands[1]) == LABEL_REF)"
  3084.   [(set (match_dup 0) (high:SI (match_dup 1)))
  3085.    (set (match_dup 0)
  3086.     (lo_sum:SI (match_dup 0) (match_dup 1)))]
  3087.   "")
  3088.  
  3089. ;; LABEL_REFs are not modified by `legitimize_pic_address`
  3090. ;; so do not recurse infinitely in the PIC case.
  3091. (define_split
  3092.   [(set (match_operand:SI 0 "register_operand" "")
  3093.     (match_operand:SI 1 "immediate_operand" ""))]
  3094.   "flag_pic && (GET_CODE (operands[1]) == SYMBOL_REF
  3095.         || GET_CODE (operands[1]) == CONST)"
  3096.   [(set (match_dup 0) (match_dup 1))]
  3097.   "
  3098. {
  3099.   operands[1] = legitimize_pic_address (operands[1], Pmode, operands[0]);
  3100. }")
  3101.  
  3102. ;; These split sne/seq insns.  The forms of the resulting insns are 
  3103. ;; somewhat bogus, but they avoid extra patterns and show data dependency.
  3104. ;; Nothing will look at these in detail after splitting has occurred.
  3105.  
  3106. (define_split
  3107.   [(set (match_operand:SI 0 "register_operand" "")
  3108.     (ne:SI (match_operand:SI 1 "register_operand" "") (const_int 0)))
  3109.    (clobber (reg:CC 0))]
  3110.   ""
  3111.   [(set (reg:CC_NOOV 0) (compare:CC_NOOV (neg:SI (match_dup 1))
  3112.                      (const_int 0)))
  3113.    (set (match_dup 0) (ltu:SI (reg:CC 0) (const_int 0)))]
  3114.   "")
  3115.  
  3116. (define_split
  3117.   [(set (match_operand:SI 0 "register_operand" "")
  3118.     (neg:SI (ne:SI (match_operand:SI 1 "register_operand" "")
  3119.                (const_int 0))))
  3120.    (clobber (reg:CC 0))]
  3121.   ""
  3122.   [(set (reg:CC_NOOV 0) (compare:CC_NOOV (neg:SI (match_dup 1))
  3123.                      (const_int 0)))
  3124.    (set (match_dup 0) (neg:SI (ltu:SI (reg:CC 0) (const_int 0))))]
  3125.   "")
  3126.  
  3127. (define_split
  3128.   [(set (match_operand:SI 0 "register_operand" "")
  3129.     (eq:SI (match_operand:SI 1 "register_operand" "") (const_int 0)))
  3130.    (clobber (reg:CC 0))]
  3131.   ""
  3132.   [(set (reg:CC_NOOV 0) (compare:CC_NOOV (neg:SI (match_dup 1))
  3133.                      (const_int 0)))
  3134.    (set (match_dup 0) (geu:SI (reg:CC 0) (const_int 0)))]
  3135.   "")
  3136.  
  3137. (define_split
  3138.   [(set (match_operand:SI 0 "register_operand" "")
  3139.     (neg:SI (eq:SI (match_operand:SI 1 "register_operand" "")
  3140.                (const_int 0))))
  3141.    (clobber (reg:CC 0))]
  3142.   ""
  3143.   [(set (reg:CC_NOOV 0) (compare:CC_NOOV (neg:SI (match_dup 1))
  3144.                      (const_int 0)))
  3145.    (set (match_dup 0) (neg:SI (geu:SI (reg:CC 0) (const_int 0))))]
  3146.   "")
  3147.  
  3148. (define_split
  3149.   [(set (match_operand:SI 0 "register_operand" "")
  3150.     (plus:SI (ne:SI (match_operand:SI 1 "register_operand" "")
  3151.             (const_int 0))
  3152.          (match_operand:SI 2 "register_operand" "")))
  3153.    (clobber (reg:CC 0))]
  3154.   ""
  3155.   [(set (reg:CC_NOOV 0) (compare:CC_NOOV (neg:SI (match_dup 1))
  3156.                      (const_int 0)))
  3157.    (set (match_dup 0) (plus:SI (ltu:SI (reg:CC 0) (const_int 0))
  3158.                    (match_dup 2)))]
  3159.   "")
  3160.  
  3161. (define_split
  3162.   [(set (match_operand:SI 0 "register_operand" "")
  3163.     (minus:SI (match_operand:SI 2 "register_operand" "")
  3164.           (ne:SI (match_operand:SI 1 "register_operand" "")
  3165.              (const_int 0))))
  3166.    (clobber (reg:CC 0))]
  3167.   ""
  3168.   [(set (reg:CC_NOOV 0) (compare:CC_NOOV (neg:SI (match_dup 1))
  3169.                      (const_int 0)))
  3170.    (set (match_dup 0) (minus:SI (match_dup 2)
  3171.                 (ltu:SI (reg:CC 0) (const_int 0))))]
  3172.   "")
  3173.  
  3174. (define_split
  3175.   [(set (match_operand:SI 0 "register_operand" "")
  3176.     (plus:SI (eq:SI (match_operand:SI 1 "register_operand" "")
  3177.             (const_int 0))
  3178.          (match_operand:SI 2 "register_operand" "")))
  3179.    (clobber (reg:CC 0))]
  3180.   ""
  3181.   [(set (reg:CC_NOOV 0) (compare:CC_NOOV (neg:SI (match_dup 1))
  3182.                      (const_int 0)))
  3183.    (set (match_dup 0) (plus:SI (geu:SI (reg:CC 0) (const_int 0))
  3184.                    (match_dup 2)))]
  3185.   "")
  3186.  
  3187. (define_split
  3188.   [(set (match_operand:SI 0 "register_operand" "")
  3189.     (minus:SI (match_operand:SI 2 "register_operand" "")
  3190.           (eq:SI (match_operand:SI 1 "register_operand" "")
  3191.              (const_int 0))))
  3192.    (clobber (reg:CC 0))]
  3193.   ""
  3194.   [(set (reg:CC_NOOV 0) (compare:CC_NOOV (neg:SI (match_dup 1))
  3195.                      (const_int 0)))
  3196.    (set (match_dup 0) (minus:SI (match_dup 2)
  3197.                 (geu:SI (reg:CC 0) (const_int 0))))]
  3198.   "")
  3199.  
  3200. ;; Peepholes go at the end.
  3201.  
  3202. ;; Optimize consecutive loads or stores into ldd and std when possible.
  3203. ;; The conditions in which we do this are very restricted and are 
  3204. ;; explained in the code for {registers,memory}_ok_for_ldd functions.
  3205.  
  3206. (define_peephole
  3207.   [(set (match_operand:SI 0 "register_operand" "=rf")
  3208.         (match_operand:SI 1 "memory_operand" ""))
  3209.    (set (match_operand:SI 2 "register_operand" "=rf")
  3210.         (match_operand:SI 3 "memory_operand" ""))]
  3211.   "registers_ok_for_ldd_peep (operands[0], operands[2]) 
  3212.    && ! MEM_VOLATILE_P (operands[1]) && ! MEM_VOLATILE_P (operands[3])
  3213.    && addrs_ok_for_ldd_peep (XEXP (operands[1], 0), XEXP (operands[3], 0))" 
  3214.   "ldd %1,%0")
  3215.  
  3216. (define_peephole
  3217.   [(set (match_operand:SI 0 "memory_operand" "")
  3218.         (match_operand:SI 1 "register_operand" "rf"))
  3219.    (set (match_operand:SI 2 "memory_operand" "")
  3220.         (match_operand:SI 3 "register_operand" "rf"))]
  3221.   "registers_ok_for_ldd_peep (operands[1], operands[3]) 
  3222.    && ! MEM_VOLATILE_P (operands[0]) && ! MEM_VOLATILE_P (operands[2])
  3223.    && addrs_ok_for_ldd_peep (XEXP (operands[0], 0), XEXP (operands[2], 0))"
  3224.   "std %1,%0")
  3225.  
  3226. (define_peephole
  3227.   [(set (match_operand:SF 0 "register_operand" "=fr")
  3228.         (match_operand:SF 1 "memory_operand" ""))
  3229.    (set (match_operand:SF 2 "register_operand" "=fr")
  3230.         (match_operand:SF 3 "memory_operand" ""))]
  3231.   "registers_ok_for_ldd_peep (operands[0], operands[2]) 
  3232.    && ! MEM_VOLATILE_P (operands[1]) && ! MEM_VOLATILE_P (operands[3])
  3233.    && addrs_ok_for_ldd_peep (XEXP (operands[1], 0), XEXP (operands[3], 0))"
  3234.   "ldd %1,%0")
  3235.  
  3236. (define_peephole
  3237.   [(set (match_operand:SF 0 "memory_operand" "")
  3238.         (match_operand:SF 1 "register_operand" "fr"))
  3239.    (set (match_operand:SF 2 "memory_operand" "")
  3240.         (match_operand:SF 3 "register_operand" "fr"))]
  3241.   "registers_ok_for_ldd_peep (operands[1], operands[3]) 
  3242.    && ! MEM_VOLATILE_P (operands[0]) && ! MEM_VOLATILE_P (operands[2])
  3243.    && addrs_ok_for_ldd_peep (XEXP (operands[0], 0), XEXP (operands[2], 0))"
  3244.   "std %1,%0")
  3245.  
  3246. (define_peephole
  3247.   [(set (match_operand:SI 0 "register_operand" "=rf")
  3248.         (match_operand:SI 1 "memory_operand" ""))
  3249.    (set (match_operand:SI 2 "register_operand" "=rf")
  3250.         (match_operand:SI 3 "memory_operand" ""))]
  3251.   "registers_ok_for_ldd_peep (operands[2], operands[0]) 
  3252.    && ! MEM_VOLATILE_P (operands[3]) && ! MEM_VOLATILE_P (operands[1])
  3253.    && addrs_ok_for_ldd_peep (XEXP (operands[3], 0), XEXP (operands[1], 0))"
  3254.   "ldd %3,%2")
  3255.  
  3256. (define_peephole
  3257.   [(set (match_operand:SI 0 "memory_operand" "")
  3258.         (match_operand:SI 1 "register_operand" "rf"))
  3259.    (set (match_operand:SI 2 "memory_operand" "")
  3260.         (match_operand:SI 3 "register_operand" "rf"))]
  3261.   "registers_ok_for_ldd_peep (operands[3], operands[1]) 
  3262.    && ! MEM_VOLATILE_P (operands[2]) && ! MEM_VOLATILE_P (operands[0])
  3263.    && addrs_ok_for_ldd_peep (XEXP (operands[2], 0), XEXP (operands[0], 0))" 
  3264.   "std %3,%2")
  3265.  
  3266. (define_peephole
  3267.   [(set (match_operand:SF 0 "register_operand" "=fr")
  3268.         (match_operand:SF 1 "memory_operand" ""))
  3269.    (set (match_operand:SF 2 "register_operand" "=fr")
  3270.         (match_operand:SF 3 "memory_operand" ""))]
  3271.   "registers_ok_for_ldd_peep (operands[2], operands[0]) 
  3272.    && ! MEM_VOLATILE_P (operands[3]) && ! MEM_VOLATILE_P (operands[1])
  3273.    && addrs_ok_for_ldd_peep (XEXP (operands[3], 0), XEXP (operands[1], 0))"
  3274.   "ldd %3,%2")
  3275.  
  3276. (define_peephole
  3277.   [(set (match_operand:SF 0 "memory_operand" "")
  3278.         (match_operand:SF 1 "register_operand" "fr"))
  3279.    (set (match_operand:SF 2 "memory_operand" "")
  3280.         (match_operand:SF 3 "register_operand" "fr"))]
  3281.   "registers_ok_for_ldd_peep (operands[3], operands[1]) 
  3282.    && ! MEM_VOLATILE_P (operands[2]) && ! MEM_VOLATILE_P (operands[0])
  3283.    && addrs_ok_for_ldd_peep (XEXP (operands[2], 0), XEXP (operands[0], 0))"
  3284.   "std %3,%2")
  3285.  
  3286. ;; Optimize the case of following a reg-reg move with a test
  3287. ;; of reg just moved.  Don't allow floating point regs for operand 0 or 1.
  3288. ;; This can result from a float to fix conversion.
  3289.  
  3290. (define_peephole
  3291.   [(set (match_operand:SI 0 "register_operand" "=r")
  3292.     (match_operand:SI 1 "register_operand" "r"))
  3293.    (set (reg:CC 0)
  3294.     (compare:CC (match_operand:SI 2 "register_operand" "r")
  3295.             (const_int 0)))]
  3296.   "(rtx_equal_p (operands[2], operands[0])
  3297.     || rtx_equal_p (operands[2], operands[1]))
  3298.    && ! FP_REG_P (operands[0]) && ! FP_REG_P (operands[1])"
  3299.   "orcc %1,%%g0,%0")
  3300.  
  3301. ;; Do {sign,zero}-extended compares somewhat more efficiently.
  3302. ;; ??? Is this now the Right Way to do this?  Or will SCRATCH
  3303. ;;     eventually have some impact here?
  3304.  
  3305. (define_peephole
  3306.   [(set (match_operand:HI 0 "register_operand" "")
  3307.     (match_operand:HI 1 "memory_operand" ""))
  3308.    (set (match_operand:SI 2 "register_operand" "")
  3309.     (sign_extend:SI (match_dup 0)))
  3310.    (set (reg:CC 0)
  3311.     (compare:CC (match_dup 2)
  3312.             (const_int 0)))]
  3313.   ""
  3314.   "ldsh %1,%0\;orcc %0,%%g0,%2")
  3315.  
  3316. (define_peephole
  3317.   [(set (match_operand:QI 0 "register_operand" "")
  3318.     (match_operand:QI 1 "memory_operand" ""))
  3319.    (set (match_operand:SI 2 "register_operand" "")
  3320.     (sign_extend:SI (match_dup 0)))
  3321.    (set (reg:CC 0)
  3322.     (compare:CC (match_dup 2)
  3323.             (const_int 0)))]
  3324.   ""
  3325.   "ldsb %1,%0\;orcc %0,%%g0,%2")
  3326.  
  3327. (define_peephole
  3328.   [(set (match_operand:HI 0 "register_operand" "")
  3329.     (match_operand:HI 1 "memory_operand" ""))
  3330.    (set (match_operand:SI 2 "register_operand" "")
  3331.     (sign_extend:SI (match_dup 0)))]
  3332.   "dead_or_set_p (insn, operands[0])"
  3333.   "*
  3334. {
  3335.   warning (\"bad peephole\");
  3336.   if (! MEM_VOLATILE_P (operands[1]))
  3337.     abort ();
  3338.   return \"ldsh %1,%2\";
  3339. }")
  3340.  
  3341. (define_peephole
  3342.   [(set (match_operand:QI 0 "register_operand" "")
  3343.     (match_operand:QI 1 "memory_operand" ""))
  3344.    (set (match_operand:SI 2 "register_operand" "")
  3345.     (sign_extend:SI (match_dup 0)))]
  3346.   "dead_or_set_p (insn, operands[0])"
  3347.   "*
  3348. {
  3349.   warning (\"bad peephole\");
  3350.   if (! MEM_VOLATILE_P (operands[1]))
  3351.     abort ();
  3352.   return \"ldsb %1,%2\";
  3353. }")
  3354.  
  3355. ;; Floating-point move peepholes
  3356.  
  3357. (define_peephole
  3358.   [(set (match_operand:SI 0 "register_operand" "=r")
  3359.     (lo_sum:SI (match_dup 0)
  3360.            (match_operand:SI 1 "immediate_operand" "i")))
  3361.    (set (match_operand:DF 2 "register_operand" "=fr")
  3362.     (mem:DF (match_dup 0)))]
  3363.   "RTX_UNCHANGING_P (operands[1]) && reg_unused_after (operands[0], insn)"
  3364.   "*
  3365. {
  3366.   /* Go by way of output_move_double in case the register in operand 2
  3367.      is not properly aligned for ldd.  */
  3368.   operands[1] = gen_rtx (MEM, DFmode,
  3369.              gen_rtx (LO_SUM, SImode, operands[0], operands[1]));
  3370.   operands[0] = operands[2];
  3371.   return output_move_double (operands);
  3372. }")
  3373.  
  3374. (define_peephole
  3375.   [(set (match_operand:SI 0 "register_operand" "=r")
  3376.     (lo_sum:SI (match_dup 0)
  3377.            (match_operand:SI 1 "immediate_operand" "i")))
  3378.    (set (match_operand:SF 2 "register_operand" "=fr")
  3379.     (mem:SF (match_dup 0)))]
  3380.   "RTX_UNCHANGING_P (operands[1]) && reg_unused_after (operands[0], insn)"
  3381.   "ld [%0+%%lo(%a1)],%2")
  3382.  
  3383. ;; Return peepholes.  First the "normal" ones
  3384.  
  3385. ;; ??? There are QImode, HImode, and SImode versions of this pattern.
  3386. ;; It might be possible to write one more general pattern instead of three.
  3387.  
  3388. (define_insn ""
  3389.   [(set (match_operand:QI 0 "restore_operand" "")
  3390.     (match_operand:QI 1 "arith_operand" "rI"))
  3391.    (return)]
  3392.   "! TARGET_EPILOGUE"
  3393.   "*
  3394. {
  3395.   if (current_function_returns_struct)
  3396.     return \"jmp %%i7+12\;restore %%g0,%1,%Y0\";
  3397.   else
  3398.     return \"ret\;restore %%g0,%1,%Y0\";
  3399. }"
  3400.   [(set_attr "type" "multi")])
  3401.  
  3402. (define_insn ""
  3403.   [(set (match_operand:HI 0 "restore_operand" "")
  3404.     (match_operand:HI 1 "arith_operand" "rI"))
  3405.    (return)]
  3406.   "! TARGET_EPILOGUE"
  3407.   "*
  3408. {
  3409.   if (current_function_returns_struct)
  3410.     return \"jmp %%i7+12\;restore %%g0,%1,%Y0\";
  3411.   else
  3412.     return \"ret\;restore %%g0,%1,%Y0\";
  3413. }"
  3414.   [(set_attr "type" "multi")])
  3415.  
  3416. (define_insn ""
  3417.   [(set (match_operand:SI 0 "restore_operand" "")
  3418.     (match_operand:SI 1 "arith_operand" "rI"))
  3419.    (return)]
  3420.   "! TARGET_EPILOGUE"
  3421.   "*
  3422. {
  3423.   if (current_function_returns_struct)
  3424.     return \"jmp %%i7+12\;restore %%g0,%1,%Y0\";
  3425.   else
  3426.     return \"ret\;restore %%g0,%1,%Y0\";
  3427. }"
  3428.   [(set_attr "type" "multi")])
  3429.  
  3430. ;; The following pattern is only generated by delayed-branch scheduling,
  3431. ;; when the insn winds up in the epilogue.  This can only happen when
  3432. ;; ! TARGET_FPU because otherwise fp return values are in %f0.
  3433. (define_insn ""
  3434.   [(set (match_operand:SF 0 "restore_operand" "r")
  3435.     (match_operand:SF 1 "register_operand" "r"))
  3436.    (return)]
  3437.   "! TARGET_FPU && ! TARGET_EPILOGUE"
  3438.   "*
  3439. {
  3440.   if (current_function_returns_struct)
  3441.     return \"jmp %%i7+12\;restore %%g0,%1,%Y0\";
  3442.   else
  3443.     return \"ret\;restore %%g0,%1,%Y0\";
  3444. }"
  3445.   [(set_attr "type" "multi")])
  3446.  
  3447. (define_insn ""
  3448.   [(set (match_operand:SI 0 "restore_operand" "")
  3449.     (plus:SI (match_operand:SI 1 "arith_operand" "%r")
  3450.          (match_operand:SI 2 "arith_operand" "rI")))
  3451.    (return)]
  3452.   "! TARGET_EPILOGUE"
  3453.   "*
  3454. {
  3455.   if (current_function_returns_struct)
  3456.     return \"jmp %%i7+12\;restore %r1,%2,%Y0\";
  3457.   else
  3458.     return \"ret\;restore %r1,%2,%Y0\";
  3459. }"
  3460.   [(set_attr "type" "multi")])
  3461.  
  3462. ;; Turned off because it should never match (subtracting a constant
  3463. ;; is turned into addition) and because it would do the wrong thing
  3464. ;; when operand 2 is -4096 (--4096 == 4096 is not a valid immediate).
  3465. ;;(define_insn ""
  3466. ;;  [(set (match_operand:SI 0 "restore_operand" "")
  3467. ;;    (minus:SI (match_operand:SI 1 "register_operand" "r")
  3468. ;;          (match_operand:SI 2 "small_int" "I")))
  3469. ;;   (return)]
  3470. ;;  "! TARGET_EPILOGUE"
  3471. ;;  "ret\;restore %1,-(%2),%Y0"
  3472. ;;  [(set_attr "type" "multi")])
  3473.  
  3474. ;; The following pattern is only generated by delayed-branch scheduling,
  3475. ;; when the insn winds up in the epilogue.
  3476. (define_insn ""
  3477.   [(set (reg:SF 32)
  3478.     (match_operand:SF 0 "register_operand" "f"))
  3479.    (return)]
  3480.   "! TARGET_EPILOGUE"
  3481.   "ret\;fmovs %0,%%f0"
  3482.   [(set_attr "type" "multi")])
  3483.  
  3484. ;; Now peepholes to go a call followed by a jump.
  3485.  
  3486. (define_peephole
  3487.   [(parallel [(set (match_operand 0 "" "")
  3488.            (call (mem:SI (match_operand:SI 1 "call_operand_address" "pi"))
  3489.              (match_operand 2 "" "")))
  3490.           (clobber (reg:SI 15))])
  3491.    (set (pc) (label_ref (match_operand 3 "" "")))]
  3492.   "short_branch (INSN_UID (insn), INSN_UID (operands[3]))"
  3493.   "*
  3494. {
  3495.   return \"call %a1,%2\;add %%o7,(%l3-.-4),%%o7\";
  3496. }")
  3497.  
  3498. (define_peephole
  3499.   [(parallel [(call (mem:SI (match_operand:SI 0 "call_operand_address" "pi"))
  3500.             (match_operand 1 "" ""))
  3501.           (clobber (reg:SI 15))])
  3502.    (set (pc) (label_ref (match_operand 2 "" "")))]
  3503.   "short_branch (INSN_UID (insn), INSN_UID (operands[2]))"
  3504.   "*
  3505. {
  3506.   return \"call %a0,%1\;add %%o7,(%l2-.-4),%%o7\";
  3507. }")
  3508.  
  3509. (define_peephole
  3510.   [(parallel [(set (match_operand:SI 0 "register_operand" "=r")
  3511.            (minus:SI (match_operand:SI 1 "reg_or_0_operand" "rJ")
  3512.                  (reg:SI 0)))
  3513.           (clobber (reg:CC 0))])
  3514.    (set (reg:CC 0) (compare (match_dup 0) (const_int 0)))]
  3515.   ""
  3516.   "subxcc %r1,0,%0")
  3517.