home *** CD-ROM | disk | FTP | other *** search
/ Education Sampler 1992 [NeXTSTEP] / Education_1992_Sampler.iso / NeXT / GnuSource / cplusplus-8 / config / sparc.md < prev    next >
Encoding:
Text File  |  1990-09-30  |  67.0 KB  |  2,371 lines

  1.  
  2. ;;- Machine description for SPARC chip for GNU C compiler
  3. ;;   Copyright (C) 1988, 1989 Free Software Foundation, Inc.
  4. ;;   Contributed by Michael Tiemann (tiemann@mcc.com)
  5.  
  6. ;; This file is part of GNU CC.
  7.  
  8. ;; GNU CC is free software; you can redistribute it and/or modify
  9. ;; it under the terms of the GNU General Public License as published by
  10. ;; the Free Software Foundation; either version 1, or (at your option)
  11. ;; any later version.
  12.  
  13. ;; GNU CC is distributed in the hope that it will be useful,
  14. ;; but WITHOUT ANY WARRANTY; without even the implied warranty of
  15. ;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
  16. ;; GNU General Public License for more details.
  17.  
  18. ;; You should have received a copy of the GNU General Public License
  19. ;; along with GNU CC; see the file COPYING.  If not, write to
  20. ;; the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA.
  21.  
  22.  
  23. ;;- See file "rtl.def" for documentation on define_insn, match_*, et. al.
  24.  
  25. ;;- cpp macro #define NOTICE_UPDATE_CC in file tm.h handles condition code
  26. ;;- updates for most instructions.
  27.  
  28. ;;- Operand classes for the register allocator:
  29.  
  30. ;; Compare instructions.
  31. ;; This controls RTL generation and register allocation.
  32.  
  33. ;; Put cmpsi first among compare insns so it matches two CONST_INT operands.
  34.  
  35. (define_insn "cmpsi"
  36.   [(set (cc0)
  37.     (compare (match_operand:SI 0 "arith_operand" "r,rI")
  38.          (match_operand:SI 1 "arith_operand" "I,r")))]
  39.   ""
  40.   "*
  41. {
  42.   if (! REG_P (operands[0]))
  43.     {
  44.       cc_status.flags |= CC_REVERSED;
  45.       return \"cmp %1,%0\";
  46.     }
  47.   return \"cmp %0,%1\";
  48. }")
  49.  
  50. (define_expand "cmpdf"
  51.   [(set (cc0)
  52.     (compare (match_operand:DF 0 "nonmemory_operand" "f,fG")
  53.          (match_operand:DF 1 "nonmemory_operand" "G,f")))]
  54.   ""
  55.   "emit_insn (gen_rtx (USE, VOIDmode, gen_rtx (REG, DFmode, 32)));")
  56.  
  57. (define_insn ""
  58.   [(set (cc0)
  59.     (compare (match_operand:DF 0 "nonmemory_operand" "f,fG")
  60.          (match_operand:DF 1 "nonmemory_operand" "G,f")))]
  61.   "GET_CODE (operands[0]) != CONST_INT && GET_CODE (operands[1]) != CONST_INT"
  62.   "*
  63. {
  64.   if (GET_CODE (operands[0]) == CONST_DOUBLE
  65.       || GET_CODE (operands[1]) == CONST_DOUBLE)
  66.     make_f0_contain_0 (2);
  67.  
  68.   cc_status.flags |= CC_IN_FCCR;
  69.   if (GET_CODE (operands[0]) == CONST_DOUBLE)
  70.     return \"fcmped %%f0,%1\;nop\";
  71.   if (GET_CODE (operands[1]) == CONST_DOUBLE)
  72.     return \"fcmped %0,%%f0\;nop\";
  73.   return \"fcmped %0,%1\;nop\";
  74. }")
  75.  
  76. (define_expand "cmpsf"
  77.   [(set (cc0)
  78.     (compare (match_operand:SF 0 "nonmemory_operand" "f,fG")
  79.          (match_operand:SF 1 "nonmemory_operand" "G,f")))]
  80.   ""
  81.   "emit_insn (gen_rtx (USE, VOIDmode, gen_rtx (REG, SFmode, 32)));")
  82.  
  83. (define_insn ""
  84.   [(set (cc0)
  85.     (compare (match_operand:SF 0 "nonmemory_operand" "f,fG")
  86.          (match_operand:SF 1 "nonmemory_operand" "G,f")))]
  87.   "GET_CODE (operands[0]) != CONST_INT && GET_CODE (operands[1]) != CONST_INT"
  88.   "*
  89. {
  90.   if (GET_CODE (operands[0]) == CONST_DOUBLE
  91.       || GET_CODE (operands[1]) == CONST_DOUBLE)
  92.     make_f0_contain_0 (1);
  93.  
  94.   cc_status.flags |= CC_IN_FCCR;
  95.   if (GET_CODE (operands[0]) == CONST_DOUBLE)
  96.     return \"fcmpes %%f0,%1\;nop\";
  97.   if (GET_CODE (operands[1]) == CONST_DOUBLE)
  98.     return \"fcmpes %0,%%f0\;nop\";
  99.   return \"fcmpes %0,%1\;nop\";
  100. }")
  101.  
  102. ;; Put tstsi first among test insns so it matches a CONST_INT operand.
  103.  
  104. (define_insn "tstsi"
  105.   [(set (cc0)
  106.     (match_operand:SI 0 "register_operand" "r"))]
  107.   ""
  108.   "tst %0")
  109.  
  110. ;; Need this to take a general operand because cse can make
  111. ;; a CONST which won't be in a register.
  112. (define_insn ""
  113.   [(set (cc0)
  114.     (match_operand:SI 0 "immediate_operand" "i"))]
  115.   ""
  116.   "set %0,%%g1\;tst %%g1")
  117.  
  118. ;; Optimize the case of following a reg-reg move with a test
  119. ;; of reg just moved.
  120.  
  121. (define_peephole
  122.   [(set (match_operand:SI 0 "register_operand" "=r")
  123.     (match_operand:SI 1 "register_operand" "r"))
  124.    (set (cc0) (match_operand:SI 2 "register_operand" "r"))]
  125.   "operands[2] == operands[0]
  126.    || operands[2] == operands[1]"
  127.   "orcc %1,%%g0,%0 ! 2-insn combine")
  128.  
  129. ;; Optimize 5(6) insn sequence to 3(4) insns.
  130. ;; These patterns could also optimize more complicated sets
  131. ;; before conditional branches.
  132.  
  133. ;; Turned off because (1) this case is rarely encounted
  134. ;; (2) to be correct, more conditions must be checked
  135. ;; (3) the conditions must be checked with rtx_equal_p, not ==
  136. ;; (4) when branch scheduling is added to the compiler,
  137. ;;     this optimization will be performed by the branch scheduler
  138. ;; Bottom line: it is not worth the trouble of fixing or
  139. ;; maintaining it.
  140.  
  141. ;(define_peephole
  142. ;  [(set (match_operand:SI 0 "register_operand" "=r")
  143. ;    (match_operand:SI 1 "general_operand" "g"))
  144. ;   (set (match_operand:SI 2 "register_operand" "=r")
  145. ;    (match_operand:SI 3 "reg_or_0_operand" "rJ"))
  146. ;   (set (cc0) (match_operand:SI 4 "register_operand" "r"))
  147. ;   (set (pc) (match_operand 5 "" ""))]
  148. ;  "GET_CODE (operands[5]) == IF_THEN_ELSE
  149. ;   && operands[0] != operands[3]
  150. ;   && ! reg_mentioned_p (operands[2], operands[1])
  151. ;   && (operands[4] == operands[0]
  152. ;       || operands[4] == operands[2]
  153. ;       || operands[4] == operands[3])"
  154. ;  "*
  155. ;{
  156. ;  rtx xoperands[2];
  157. ;  int parity;
  158. ;  xoperands[0] = XEXP (operands[5], 0);
  159. ;  if (GET_CODE (XEXP (operands[5], 1)) == PC)
  160. ;    {
  161. ;      parity = 1;
  162. ;      xoperands[1] = XEXP (XEXP (operands[5], 2), 0);
  163. ;    }
  164. ;  else
  165. ;    {
  166. ;      parity = 0;
  167. ;      xoperands[1] = XEXP (XEXP (operands[5], 1), 0);
  168. ;    }
  169. ;
  170. ;  if (operands[4] == operands[0])
  171. ;    {
  172. ;      /* Although the constraints for operands[1] permit a general
  173. ;     operand (and hence possibly a const_int), we know that
  174. ;     in this branch it cannot be a CONST_INT, since that would give
  175. ;     us a fixed condition, and those should have been optimized away.  */
  176. ;      if (REG_P (operands[1]))
  177. ;    output_asm_insn (\"orcc %1,%%g0,%0 ! 3-insn reorder\", operands);
  178. ;      else if (GET_CODE (operands[1]) != MEM)
  179. ;    abort ();
  180. ;      else
  181. ;    {
  182. ;      if (CONSTANT_ADDRESS_P (XEXP (operands[1], 0)))
  183. ;        output_asm_insn (\"sethi %%hi(%m1),%%g1\;ld [%%g1+%%lo(%m1)],%0\;tst %0 ! 4-insn reorder\", operands);
  184. ;      else
  185. ;        output_asm_insn (\"ld %1,%0\;tst %0 ! 3.5-insn reorder\", operands);
  186. ;    }
  187. ;      XVECEXP (PATTERN (insn), 0, 0) = XVECEXP (PATTERN (insn), 0, 2);
  188. ;      XVECEXP (PATTERN (insn), 0, 1) = XVECEXP (PATTERN (insn), 0, 3);
  189. ;    }
  190. ;  else
  191. ;    {
  192. ;      output_asm_insn (\"orcc %3,%%g0,%2 ! 3-insn reorder\", operands);
  193. ;    }
  194. ;  if (parity)
  195. ;    return output_delayed_branch (\"b%N0 %l1\", xoperands, insn);
  196. ;  else
  197. ;    return output_delayed_branch (\"b%C0 %l1\", xoperands, insn);
  198. ;}")
  199.  
  200. ;; By default, operations don't set the condition codes.
  201. ;; These patterns allow cc's to be set, while doing some work
  202.  
  203. (define_insn ""
  204.   [(set (cc0)
  205.     (zero_extend:SI (subreg:QI (match_operand:SI 0 "register_operand" "r") 0)))]
  206.   ""
  207.   "andcc %0,0xff,%%g0")
  208.  
  209. (define_insn ""
  210.   [(set (cc0)
  211.     (plus:SI (match_operand:SI 0 "register_operand" "r%")
  212.          (match_operand:SI 1 "arith_operand" "rI")))]
  213.   "ignore_overflow_conditional_p (NEXT_INSN (insn))"
  214.   "*
  215. {
  216.   cc_status.flags |= CC_NO_OVERFLOW;
  217.   return \"addcc %0,%1,%%g0\";
  218. }")
  219.  
  220. (define_insn ""
  221.   [(set (cc0)
  222.     (plus:SI (match_operand:SI 0 "register_operand" "r%")
  223.          (match_operand:SI 1 "arith_operand" "rI")))
  224.    (set (match_operand:SI 2 "register_operand" "=r")
  225.     (plus:SI (match_dup 0) (match_dup 1)))]
  226.   "ignore_overflow_conditional_p (NEXT_INSN (insn))"
  227.   "*
  228. {
  229.   cc_status.flags |= CC_NO_OVERFLOW;
  230.   return \"addcc %0,%1,%2\";
  231. }")
  232.  
  233. (define_insn ""
  234.   [(set (cc0)
  235.     (minus:SI (match_operand:SI 0 "register_operand" "r")
  236.           (match_operand:SI 1 "arith_operand" "rI")))]
  237.   "ignore_overflow_conditional_p (NEXT_INSN (insn))"
  238.   "*
  239. {
  240.   cc_status.flags |= CC_NO_OVERFLOW;
  241.   return \"subcc %0,%1,%%g0\";
  242. }")
  243.  
  244. (define_insn ""
  245.   [(set (cc0)
  246.     (minus:SI (match_operand:SI 0 "register_operand" "r")
  247.           (match_operand:SI 1 "arith_operand" "rI")))
  248.    (set (match_operand:SI 2 "register_operand" "=r")
  249.     (minus:SI (match_dup 0) (match_dup 1)))]
  250.   "ignore_overflow_conditional_p (NEXT_INSN (insn))"
  251.   "*
  252. {
  253.   cc_status.flags |= CC_NO_OVERFLOW;
  254.   return \"subcc %0,%1,%2\";
  255. }")
  256.  
  257. (define_insn ""
  258.   [(set (cc0)
  259.     (and:SI (match_operand:SI 0 "register_operand" "r%")
  260.         (match_operand:SI 1 "arith_operand" "rI")))]
  261.   ""
  262.   "andcc %0,%1,%%g0")
  263.  
  264. (define_insn ""
  265.   [(set (cc0)
  266.     (and:SI (match_operand:SI 0 "register_operand" "r%")
  267.         (match_operand:SI 1 "arith_operand" "rI")))
  268.    (set (match_operand:SI 2 "register_operand" "=r")
  269.     (and:SI (match_dup 0) (match_dup 1)))]
  270.   ""
  271.   "andcc %0,%1,%2")
  272.  
  273. (define_insn ""
  274.   [(set (cc0)
  275.     (and:SI (match_operand:SI 0 "register_operand" "r")
  276.         (not:SI (match_operand:SI 1 "arith_operand" "rI"))))]
  277.   ""
  278.   "andncc %0,%1,%%g0")
  279.  
  280. (define_insn ""
  281.   [(set (cc0)
  282.     (and:SI (match_operand:SI 0 "register_operand" "r")
  283.         (not:SI (match_operand:SI 1 "arith_operand" "rI"))))
  284.    (set (match_operand:SI 2 "register_operand" "=r")
  285.     (and:SI (match_dup 0) (not:SI (match_dup 1))))]
  286.   ""
  287.   "andncc %0,%1,%2")
  288.  
  289. (define_insn ""
  290.   [(set (cc0)
  291.     (ior:SI (match_operand:SI 0 "register_operand" "r%")
  292.         (match_operand:SI 1 "arith_operand" "rI")))]
  293.   ""
  294.   "orcc %0,%1,%%g0")
  295.  
  296. (define_insn ""
  297.   [(set (cc0)
  298.     (ior:SI (match_operand:SI 0 "register_operand" "r%")
  299.         (match_operand:SI 1 "arith_operand" "rI")))
  300.    (set (match_operand:SI 2 "register_operand" "=r")
  301.     (ior:SI (match_dup 0) (match_dup 1)))]
  302.   ""
  303.   "orcc %0,%1,%2")
  304.  
  305. (define_insn ""
  306.   [(set (cc0)
  307.     (ior:SI (match_operand:SI 0 "register_operand" "r")
  308.         (not:SI (match_operand:SI 1 "arith_operand" "rI"))))]
  309.   ""
  310.   "orncc %0,%1,%%g0")
  311.  
  312. (define_insn ""
  313.   [(set (cc0)
  314.     (ior:SI (match_operand:SI 0 "register_operand" "r")
  315.         (not:SI (match_operand:SI 1 "arith_operand" "rI"))))
  316.    (set (match_operand:SI 2 "register_operand" "=r")
  317.     (ior:SI (match_dup 0) (not:SI (match_dup 1))))]
  318.   ""
  319.   "orncc %0,%1,%2")
  320.  
  321. (define_insn ""
  322.   [(set (cc0)
  323.     (xor:SI (match_operand:SI 0 "register_operand" "r%")
  324.         (match_operand:SI 1 "arith_operand" "rI")))]
  325.   ""
  326.   "xorcc %0,%1,%%g0")
  327.  
  328. (define_insn ""
  329.   [(set (cc0)
  330.     (xor:SI (match_operand:SI 0 "register_operand" "r%")
  331.         (match_operand:SI 1 "arith_operand" "rI")))
  332.    (set (match_operand:SI 2 "register_operand" "=r")
  333.     (xor:SI (match_dup 0) (match_dup 1)))]
  334.   ""
  335.   "xorcc %0,%1,%2")
  336.  
  337. (define_insn ""
  338.   [(set (cc0)
  339.     (xor:SI (match_operand:SI 0 "register_operand" "r")
  340.         (not:SI (match_operand:SI 1 "arith_operand" "rI"))))]
  341.   ""
  342.   "xnorcc %0,%1,%%g0")
  343.  
  344. (define_insn ""
  345.   [(set (cc0)
  346.     (xor:SI (match_operand:SI 0 "register_operand" "r")
  347.         (not:SI (match_operand:SI 1 "arith_operand" "rI"))))
  348.    (set (match_operand:SI 2 "register_operand" "=r")
  349.     (xor:SI (match_dup 0) (not:SI (match_dup 1))))]
  350.   ""
  351.   "xnorcc %0,%1,%2")
  352.  
  353. (define_expand "tstdf"
  354.   [(set (cc0)
  355.     (match_operand:DF 0 "register_operand" "f"))]
  356.   ""
  357.   "emit_insn (gen_rtx (CLOBBER, VOIDmode, gen_rtx (REG, DFmode, 32)));")
  358.  
  359. (define_insn ""
  360.   [(set (cc0)
  361.     (match_operand:DF 0 "register_operand" "f"))]
  362.   ""
  363.   "*
  364. {
  365.   make_f0_contain_0 (2);
  366.   cc_status.flags |= CC_IN_FCCR;
  367.   return \"fcmped %0,%%f0\;nop\";
  368. }")
  369.  
  370. (define_expand "tstsf"
  371.   [(set (cc0)
  372.     (match_operand:SF 0 "register_operand" "f"))]
  373.   ""
  374.   "emit_insn (gen_rtx (CLOBBER, VOIDmode, gen_rtx (REG, SFmode, 32)));")
  375.  
  376. (define_insn ""
  377.   [(set (cc0)
  378.     (match_operand:SF 0 "register_operand" "f"))]
  379.   ""
  380.   "*
  381. {
  382.   make_f0_contain_0 (1);
  383.   cc_status.flags |= CC_IN_FCCR;
  384.   return \"fcmpes %0,%%f0\;nop\";
  385. }")
  386.  
  387. ;; There are no logical links for the condition codes.  This
  388. ;; would not normally be a problem, but on the SPARC (and possibly
  389. ;; other RISC machines), when argument passing, the insn which sets
  390. ;; the condition code and the insn which uses the set condition code
  391. ;; may not be performed adjacently (due to optimizations performed
  392. ;; in combine.c).  To make up for this, we emit insn patterns which
  393. ;; cannot possibly be rearranged on us.
  394. (define_expand "seq"
  395.   [(set (match_operand:SI 0 "general_operand" "=r")
  396.     (eq (cc0) (const_int 0)))]
  397.   ""
  398.   "gen_scc_insn (EQ, VOIDmode, operands); DONE;")
  399.  
  400. (define_expand "sne"
  401.   [(set (match_operand:SI 0 "general_operand" "=r")
  402.     (ne (cc0) (const_int 0)))]
  403.   ""
  404.   "gen_scc_insn (NE, VOIDmode, operands); DONE;")
  405.  
  406. (define_insn ""
  407.   [(set (match_operand:SI 0 "general_operand" "=r,r")
  408.     (match_operator 1 "eq_or_neq"
  409.             [(compare (match_operand:SI 2 "general_operand" "r,rI")
  410.                   (match_operand:SI 3 "general_operand" "I,r"))
  411.              (const_int 0)]))]
  412.   ""
  413.   "*
  414. {
  415.   CC_STATUS_INIT;
  416.   cc_status.value1 = operands[0];
  417.   if (! REG_P (operands[2]))
  418.     {
  419.       output_asm_insn (\"cmp %3,%2\", operands);
  420.       cc_status.flags |= CC_REVERSED;
  421.     }
  422.   else
  423.     output_asm_insn (\"cmp %2,%3\", operands);
  424.   return output_scc_insn (GET_CODE (operands[1]), operands[0]);
  425. }")
  426.  
  427. (define_insn ""
  428.   [(set (match_operand:SI 0 "general_operand" "=r")
  429.     (match_operator 1 "eq_or_neq"
  430.             [(match_operand:SI 2 "general_operand" "r")
  431.              (const_int 0)]))]
  432.   ""
  433.   "*
  434. {
  435.   CC_STATUS_INIT;
  436.   cc_status.value1 = operands[0];
  437.   output_asm_insn (\"tst %2\", operands);
  438.   return output_scc_insn (GET_CODE (operands[1]), operands[0]);
  439. }")
  440.  
  441. (define_insn ""
  442.   [(set (match_operand:SI 0 "general_operand" "=r,r")
  443.     (match_operator 1 "eq_or_neq"
  444.             [(compare (match_operand:DF 2 "general_operand" "f,fG")
  445.                   (match_operand:DF 3 "general_operand" "G,f"))
  446.              (const_int 0)]))]
  447.   ""
  448.   "*
  449. {
  450.   CC_STATUS_INIT;
  451.   cc_status.value1 = operands[0];
  452.   cc_status.flags |= CC_IN_FCCR;
  453.  
  454.   if (GET_CODE (operands[2]) == CONST_DOUBLE
  455.       || GET_CODE (operands[3]) == CONST_DOUBLE)
  456.     make_f0_contain_0 (2);
  457.  
  458.   if (GET_CODE (operands[2]) == CONST_DOUBLE)
  459.     output_asm_insn (\"fcmped %%f0,%3\;nop\", operands);
  460.   else if (GET_CODE (operands[3]) == CONST_DOUBLE)
  461.     output_asm_insn (\"fcmped %2,%%f0\;nop\", operands);
  462.   else output_asm_insn (\"fcmped %2,%3\;nop\", operands);
  463.   return output_scc_insn (GET_CODE (operands[1]), operands[0]);
  464. }")
  465.  
  466. (define_insn ""
  467.   [(set (match_operand:SI 0 "general_operand" "=r")
  468.     (match_operator 1 "eq_or_neq"
  469.             [(match_operand:DF 2 "general_operand" "f")
  470.              (const_int 0)]))]
  471.   ""
  472.   "*
  473. {
  474.   CC_STATUS_INIT;
  475.   cc_status.value1 = operands[0];
  476.   cc_status.flags |= CC_IN_FCCR;
  477.  
  478.   make_f0_contain_0 (2);
  479.   output_asm_insn (\"fcmped %2,%%f0\;nop\", operands);
  480.   return output_scc_insn (GET_CODE (operands[1]), operands[0]);
  481. }")
  482.  
  483. (define_insn ""
  484.   [(set (match_operand:SI 0 "general_operand" "=r,r")
  485.     (match_operator 1 "eq_or_neq"
  486.             [(compare (match_operand:SF 2 "general_operand" "f,fG")
  487.                   (match_operand:SF 3 "general_operand" "G,f"))
  488.              (const_int 0)]))]
  489.   ""
  490.   "*
  491. {
  492.   CC_STATUS_INIT;
  493.   cc_status.value1 = operands[0];
  494.   cc_status.flags |= CC_IN_FCCR;
  495.  
  496.   if (GET_CODE (operands[2]) == CONST_DOUBLE
  497.       || GET_CODE (operands[3]) == CONST_DOUBLE)
  498.     make_f0_contain_0 (1);
  499.  
  500.   if (GET_CODE (operands[2]) == CONST_DOUBLE)
  501.     output_asm_insn (\"fcmpes %%f0,%3\;nop\", operands);
  502.   else if (GET_CODE (operands[3]) == CONST_DOUBLE)
  503.     output_asm_insn (\"fcmpes %2,%%f0\;nop\", operands);
  504.   else output_asm_insn (\"fcmpes %2,%3\;nop\", operands);
  505.   return output_scc_insn (GET_CODE (operands[1]), operands[0]);
  506. }")
  507.  
  508. (define_insn ""
  509.   [(set (match_operand:SI 0 "general_operand" "=r")
  510.     (match_operator 1 "eq_or_neq"
  511.             [(match_operand:SF 2 "general_operand" "f")
  512.              (const_int 0)]))]
  513.   ""
  514.   "*
  515. {
  516.   CC_STATUS_INIT;
  517.   cc_status.value1 = operands[0];
  518.   cc_status.flags |= CC_IN_FCCR;
  519.  
  520.   make_f0_contain_0 (1);
  521.   output_asm_insn (\"fcmpes %2,%%f0\;nop\", operands);
  522.   return output_scc_insn (GET_CODE (operands[1]), operands[0]);
  523. }")
  524.  
  525. ;; These control RTL generation for conditional jump insns
  526. ;; and match them for register allocation.
  527.  
  528. (define_insn "beq"
  529.   [(set (pc)
  530.     (if_then_else (eq (cc0)
  531.               (const_int 0))
  532.               (label_ref (match_operand 0 "" ""))
  533.               (pc)))]
  534.   ""
  535.   "*
  536. {
  537.   OUTPUT_JUMP (\"be %l0\;nop\", \"be %l0\;nop\", \"fbe %l0\;nop\");
  538. }")
  539.  
  540. (define_insn "bne"
  541.   [(set (pc)
  542.     (if_then_else (ne (cc0)
  543.               (const_int 0))
  544.               (label_ref (match_operand 0 "" ""))
  545.               (pc)))]
  546.   ""
  547.   "*
  548. {
  549.   OUTPUT_JUMP (\"bne %l0\;nop\", \"bne %l0\;nop\", \"fbne %l0\;nop\");
  550. }")
  551.  
  552. (define_insn "bgt"
  553.   [(set (pc)
  554.     (if_then_else (gt (cc0)
  555.               (const_int 0))
  556.               (label_ref (match_operand 0 "" ""))
  557.               (pc)))]
  558.   ""
  559.   "*
  560. {
  561.   OUTPUT_JUMP (\"bg %l0\;nop\", 0, \"fbg %l0\;nop\");
  562. }")
  563.  
  564. (define_insn "bgtu"
  565.   [(set (pc)
  566.     (if_then_else (gtu (cc0)
  567.                (const_int 0))
  568.               (label_ref (match_operand 0 "" ""))
  569.               (pc)))]
  570.   ""
  571.   "*
  572. {
  573.   if (cc_prev_status.flags & CC_IN_FCCR)
  574.     abort ();
  575.   return \"bgu %l0\;nop\";
  576. }")
  577.  
  578. (define_insn "blt"
  579.   [(set (pc)
  580.     (if_then_else (lt (cc0)
  581.               (const_int 0))
  582.               (label_ref (match_operand 0 "" ""))
  583.               (pc)))]
  584.   ""
  585.   "*
  586. {
  587.   OUTPUT_JUMP (\"bl %l0\;nop\", \"bneg %l0\;nop\", \"fbl %l0\;nop\");
  588. }")
  589.  
  590. (define_insn "bltu"
  591.   [(set (pc)
  592.     (if_then_else (ltu (cc0)
  593.                (const_int 0))
  594.               (label_ref (match_operand 0 "" ""))
  595.               (pc)))]
  596.   ""
  597.   "*
  598. {
  599.   if (cc_prev_status.flags & CC_IN_FCCR)
  600.     abort ();
  601.   return \"blu %l0\;nop\";
  602. }")
  603.  
  604. (define_insn "bge"
  605.   [(set (pc)
  606.     (if_then_else (ge (cc0)
  607.               (const_int 0))
  608.               (label_ref (match_operand 0 "" ""))
  609.               (pc)))]
  610.   ""
  611.   "*
  612. {
  613.   OUTPUT_JUMP (\"bge %l0\;nop\", \"bpos %l0\;nop\", \"fbge %l0\;nop\");
  614. }")
  615.  
  616. (define_insn "bgeu"
  617.   [(set (pc)
  618.     (if_then_else (geu (cc0)
  619.                (const_int 0))
  620.               (label_ref (match_operand 0 "" ""))
  621.               (pc)))]
  622.   ""
  623.   "*
  624. {
  625.   if (cc_prev_status.flags & CC_IN_FCCR)
  626.     abort ();
  627.   return \"bgeu %l0\;nop\";
  628. }")
  629.  
  630. (define_insn "ble"
  631.   [(set (pc)
  632.     (if_then_else (le (cc0)
  633.               (const_int 0))
  634.               (label_ref (match_operand 0 "" ""))
  635.               (pc)))]
  636.   ""
  637.   "*
  638. {
  639.   OUTPUT_JUMP (\"ble %l0\;nop\", 0, \"fble %l0\;nop\");
  640. }")
  641.  
  642. (define_insn "bleu"
  643.   [(set (pc)
  644.     (if_then_else (leu (cc0)
  645.                (const_int 0))
  646.               (label_ref (match_operand 0 "" ""))
  647.               (pc)))]
  648.   ""
  649.   "*
  650. {
  651.   if (cc_prev_status.flags & CC_IN_FCCR)
  652.     abort ();
  653.   return \"bleu %l0\;nop\";
  654. }")
  655.  
  656. ;; This matches inverted jump insns for register allocation.
  657.  
  658. (define_insn ""
  659.   [(set (pc)
  660.     (if_then_else (match_operator 0 "relop" [(cc0) (const_int 0)])
  661.               (pc)
  662.               (label_ref (match_operand 1 "" ""))))]
  663.   ""
  664.   "*
  665. {
  666.   if (cc_prev_status.flags & CC_NO_OVERFLOW)
  667.     {
  668.       if (GET_CODE (operands[0]) == GT || GET_CODE (operands[0]) == LE)
  669.     /* These two conditions can't ignore overflow,
  670.        so reinsert the deleted test instruction.  */
  671.     return 0;
  672.       return \"b%U0 %l1\;nop\";
  673.     }
  674.   if (cc_prev_status.flags & CC_IN_FCCR)
  675.     return \"fb%F0 %l1\;nop\";
  676.   return \"b%N0 %l1\;nop\";
  677. }")
  678.  
  679. ;; Move instructions
  680.  
  681. (define_insn "swapsi"
  682.   [(set (match_operand:SI 0 "general_operand" "r,rm")
  683.     (match_operand:SI 1 "general_operand" "m,r"))
  684.    (set (match_dup 1) (match_dup 0))]
  685.   ""
  686.   "*
  687. {
  688.   if (GET_CODE (operands[1]) == MEM)
  689.     {
  690.       if (CONSTANT_ADDRESS_P (XEXP (operands[1], 0)))
  691.     output_asm_insn (\"set %a1,%%g1\", operands),
  692.     operands[1] = gen_rtx (MEM, SImode, gen_rtx (REG, SImode, 1)),
  693.     cc_status.flags &= ~CC_KNOW_HI_G1;
  694.       output_asm_insn (\"swap %1,%0\", operands);
  695.     }
  696.   if (REG_P (operands[0]))
  697.     {
  698.       if (REGNO (operands[0]) == REGNO (operands[1]))
  699.     return \"\";
  700.       return \"xor %0,%1,%0\;xor %1,%0,%1\;xor %0,%1,%0\";
  701.     }
  702.   if (CONSTANT_ADDRESS_P (XEXP (operands[0], 0)))
  703.     {
  704.       output_asm_insn (\"set %a0,%%g1\", operands);
  705.       operands[0] = gen_rtx (MEM, SImode, gen_rtx (REG, SImode, 1));
  706.       cc_status.flags &= ~CC_KNOW_HI_G1;
  707.     }
  708.   return \"swap %0,%1\";
  709. }")
  710.  
  711. (define_insn "movsi"
  712.   [(set (match_operand:SI 0 "general_operand" "=r,m")
  713.     (match_operand:SI 1 "general_operand" "rmif,rJ"))]
  714.   ""
  715.   "*
  716. {
  717.   if (GET_CODE (operands[0]) == MEM)
  718.     {
  719.       if (CONSTANT_ADDRESS_P (XEXP (operands[0], 0)))
  720.     return output_store (operands);
  721.       return \"st %r1,%0\";
  722.     }
  723.   if (GET_CODE (operands[1]) == MEM)
  724.     {
  725.       if (CONSTANT_ADDRESS_P (XEXP (operands[1], 0)))
  726.     return output_load_fixed (operands);
  727.       return \"ld %1,%0\";
  728.     }
  729.   if (FP_REG_P (operands[1]))
  730.     return \"st %r1,[%%fp-4]\;ld [%%fp-4],%0\";
  731.   if (REG_P (operands[1])
  732.       || (GET_CODE (operands[1]) == CONST_INT
  733.       && SMALL_INT (operands[1])))
  734.     return \"mov %1,%0\";
  735.   if (GET_CODE (operands[1]) == CONST_INT
  736.       && (INTVAL (operands[1]) & 0x3ff) == 0)
  737.     return \"sethi %%hi(%1),%0\";
  738.   return \"sethi %%hi(%1),%0\;or %%lo(%1),%0,%0\";
  739. }")
  740.  
  741. (define_insn "movhi"
  742.   [(set (match_operand:HI 0 "general_operand" "=r,m")
  743.     (match_operand:HI 1 "general_operand" "rmi,rJ"))]
  744.   ""
  745.   "*
  746. {
  747.   if (GET_CODE (operands[0]) == MEM)
  748.     {
  749.       if (CONSTANT_ADDRESS_P (XEXP (operands[0], 0)))
  750.     return output_store (operands);
  751.       return \"sth %r1,%0\";
  752.     }
  753.   if (GET_CODE (operands[1]) == MEM)
  754.     {
  755.       if (CONSTANT_ADDRESS_P (XEXP (operands[1], 0)))
  756.     return output_load_fixed (operands);
  757.       return \"ldsh %1,%0\";
  758.     }
  759.   if (REG_P (operands[1])
  760.       || (GET_CODE (operands[1]) == CONST_INT
  761.       && SMALL_INT (operands[1])))
  762.     return \"mov %1,%0\";
  763.   return \"sethi %%hi(%1),%0\;or %%lo(%1),%0,%0\";
  764. }")
  765.  
  766. (define_insn "movqi"
  767.   [(set (match_operand:QI 0 "general_operand" "=r,m")
  768.     (match_operand:QI 1 "general_operand" "rmi,rJ"))]
  769.   ""
  770.   "*
  771. {
  772.   if (GET_CODE (operands[0]) == MEM)
  773.     {
  774.       if (CONSTANT_ADDRESS_P (XEXP (operands[0], 0)))
  775.     return output_store (operands);
  776.       return \"stb %r1,%0\";
  777.     }
  778.   if (GET_CODE (operands[1]) == MEM)
  779.     {
  780.       if (CONSTANT_ADDRESS_P (XEXP (operands[1], 0)))
  781.     return output_load_fixed (operands);
  782.       return \"ldsb %1,%0\";
  783.     }
  784.   if (REG_P (operands[1])
  785.       || (GET_CODE (operands[1]) == CONST_INT
  786.       && SMALL_INT (operands[1])))
  787.     return \"mov %1,%0\";
  788.   return \"sethi %%hi(%1),%0\;or %%lo(%1),%0,%0\";
  789. }")
  790.  
  791. ;; The definition of this insn does not really explain what it does,
  792. ;; but it should suffice
  793. ;; that anything generated as this insn will be recognized as one
  794. ;; and that it won't successfully combine with anything.
  795. (define_expand "movstrsi"
  796.   [(parallel [(set (mem:BLK (match_operand:BLK 0 "general_operand" ""))
  797.            (mem:BLK (match_operand:BLK 1 "general_operand" "")))
  798.           (use (match_operand:SI 2 "arith32_operand" ""))
  799.           (use (match_operand:SI 3 "immediate_operand" ""))
  800.           (clobber (match_dup 4))
  801.           (clobber (match_dup 0))
  802.           (clobber (match_dup 1))])]
  803.   ""
  804.   "
  805. {
  806.   operands[0] = copy_to_mode_reg (SImode, XEXP (operands[0], 0));
  807.   operands[1] = copy_to_mode_reg (SImode, XEXP (operands[1], 0));
  808.   operands[4] = gen_reg_rtx (SImode);
  809. }")
  810.  
  811. (define_insn ""
  812.   [(set (mem:BLK (match_operand:SI 0 "register_operand" "r"))
  813.     (mem:BLK (match_operand:SI 1 "register_operand" "r")))
  814.    (use (match_operand:SI 2 "arith32_operand" "rn"))
  815.    (use (match_operand:SI 3 "immediate_operand" "i"))
  816.    (clobber (match_operand:SI 4 "register_operand" "=r"))
  817.    (clobber (match_operand:SI 5 "register_operand" "=0"))
  818.    (clobber (match_operand:SI 6 "register_operand" "=1"))]
  819.   ""
  820.   "* return output_block_move (operands);")
  821.  
  822. ;; Floating point move insns
  823.  
  824. ;; This pattern forces (set (reg:DF ...) (const_double ...))
  825. ;; to be reloaded by putting the constant into memory.
  826. ;; It must come before the more general movdf pattern.
  827. (define_insn ""
  828.   [(set (match_operand:DF 0 "general_operand" "=r,f,o")
  829.     (match_operand:DF 1 "" "mG,m,G"))]
  830.   "GET_CODE (operands[1]) == CONST_DOUBLE"
  831.   "*
  832. {
  833.   if (FP_REG_P (operands[0]))
  834.     return output_fp_move_double (operands);
  835.   if (operands[1] == dconst0_rtx && GET_CODE (operands[0]) == REG)
  836.     {
  837.       operands[1] = gen_rtx (REG, SImode, REGNO (operands[0]) + 1);
  838.       return \"mov %%g0,%0\;mov %%g0,%1\";
  839.     }
  840.   if (operands[1] == dconst0_rtx && GET_CODE (operands[0]) == MEM)
  841.     {
  842.       if (CONSTANT_ADDRESS_P (XEXP (operands[0], 0)))
  843.     {
  844.       if (! ((cc_prev_status.flags & CC_KNOW_HI_G1)
  845.          && XEXP (operands[0], 0) == cc_prev_status.mdep))
  846.         {
  847.           cc_status.flags |= CC_KNOW_HI_G1;
  848.           cc_status.mdep = XEXP (operands[0], 0);
  849.           output_asm_insn (\"sethi %%hi(%m0),%%g1\", operands);
  850.         }
  851.       return \"st %%g0,[%%g1+%%lo(%%m0)]\;st %%g0,[%%g1+%%lo(%%m0)+4]\";
  852.     }
  853.       operands[1] = adj_offsettable_operand (operands[0], 4);
  854.       return \"st %%g0,%0\;st %%g0,%1\";
  855.     }
  856.   return output_move_double (operands);
  857. }")
  858.  
  859. (define_insn "movdf"
  860.   [(set (match_operand:DF 0 "general_operand" "=rm,&r,?f,?rm")
  861.     (match_operand:DF 1 "general_operand" "r,m,rfm,f"))]
  862.   ""
  863.   "*
  864. {
  865.   if (GET_CODE (operands[0]) == MEM
  866.       && CONSTANT_ADDRESS_P (XEXP (operands[0], 0)))
  867.     return output_store (operands);
  868.   if (GET_CODE (operands[1]) == MEM
  869.       && CONSTANT_ADDRESS_P (XEXP (operands[1], 0)))
  870.     return output_load_floating (operands);
  871.  
  872.   if (FP_REG_P (operands[0]) || FP_REG_P (operands[1]))
  873.     return output_fp_move_double (operands);
  874.   return output_move_double (operands);
  875. }")
  876.  
  877. (define_insn "movdi"
  878.   [(set (match_operand:DI 0 "general_operand" "=rm,&r,?f,?rm")
  879.     (match_operand:DI 1 "general_operand" "r,mi,rfm,f"))]
  880.   ""
  881.   "*
  882. {
  883.   if (GET_CODE (operands[0]) == MEM
  884.       && CONSTANT_ADDRESS_P (XEXP (operands[0], 0)))
  885.     return output_store (operands);
  886.   if (GET_CODE (operands[1]) == MEM
  887.       && CONSTANT_ADDRESS_P (XEXP (operands[1], 0)))
  888.     return output_load_fixed (operands);
  889.  
  890.   if (FP_REG_P (operands[0]) || FP_REG_P (operands[1]))
  891.     return output_fp_move_double (operands);
  892.   return output_move_double (operands);
  893. }")
  894.  
  895. (define_insn "movsf"
  896.   [(set (match_operand:SF 0 "general_operand" "=rf,m")
  897.     (match_operand:SF 1 "general_operand" "rfm,rf"))]
  898.   ""
  899.   "*
  900. {
  901.   if (GET_CODE (operands[0]) == MEM
  902.       && CONSTANT_ADDRESS_P (XEXP (operands[0], 0)))
  903.     return output_store (operands);
  904.   if (GET_CODE (operands[1]) == MEM
  905.       && CONSTANT_ADDRESS_P (XEXP (operands[1], 0)))
  906.     return output_load_floating (operands);
  907.   if (FP_REG_P (operands[0]))
  908.     {
  909.       if (FP_REG_P (operands[1]))
  910.     return \"fmovs %1,%0\";
  911.       if (GET_CODE (operands[1]) == REG)
  912.         return \"st %r1,[%%fp-4]\;ld [%%fp-4],%0\";
  913.       if (CONSTANT_ADDRESS_P (XEXP (operands[1], 0)))
  914.     {
  915.       cc_status.flags |= CC_KNOW_HI_G1;
  916.       cc_status.mdep = XEXP (operands[1], 0);
  917.       return \"sethi %%hi(%m1),%%g1\;ld [%%g1+%%lo(%m1)],%0\";
  918.     }
  919.       return \"ld %1,%0\";
  920.     }
  921.   if (FP_REG_P (operands[1]))
  922.     {
  923.       if (GET_CODE (operands[0]) == REG)
  924.     return \"st %r1,[%%fp-4]\;ld [%%fp-4],%0\";
  925.       if (CONSTANT_ADDRESS_P (XEXP (operands[0], 0)))
  926.     {
  927.       if (! ((cc_prev_status.flags & CC_KNOW_HI_G1)
  928.          && XEXP (operands[0], 0) == cc_prev_status.mdep))
  929.         {
  930.           cc_status.flags |= CC_KNOW_HI_G1;
  931.           cc_status.mdep = XEXP (operands[0], 0);
  932.           output_asm_insn (\"sethi %%hi(%m0),%%g1\", operands);
  933.         }
  934.       return \"st %r1,[%%g1+%%lo(%m0)]\";
  935.     }
  936.       return \"st %r1,%0\";
  937.     }
  938.   if (GET_CODE (operands[0]) == MEM)
  939.     return \"st %r1,%0\";
  940.   if (GET_CODE (operands[1]) == MEM)
  941.     return \"ld %1,%0\";
  942.   return \"mov %1,%0\";
  943. }")
  944.  
  945. ;;- truncation instructions
  946. (define_insn "truncsiqi2"
  947.   [(set (match_operand:QI 0 "general_operand" "=g")
  948.     (truncate:QI
  949.      (match_operand:SI 1 "register_operand" "r")))]
  950.   ""
  951.   "*
  952. {
  953.   if (GET_CODE (operands[0]) == MEM)
  954.     if (CONSTANT_ADDRESS_P (XEXP (operands[0], 0)))
  955.       {
  956.     if (! ((cc_prev_status.flags & CC_KNOW_HI_G1)
  957.            && XEXP (operands[0], 0) == cc_prev_status.mdep))
  958.       {
  959.         cc_status.flags |= CC_KNOW_HI_G1;
  960.         cc_status.mdep = XEXP (operands[0], 0);
  961.         output_asm_insn (\"sethi %%hi(%m0),%%g1\", operands);
  962.       }
  963.     return \"stb %1,[%%g1+%%lo(%m0)]\";
  964.       }
  965.     else
  966.       return \"stb %1,%0\";
  967.   return \"mov %1,%0\";
  968. }")
  969.  
  970. (define_insn "trunchiqi2"
  971.   [(set (match_operand:QI 0 "general_operand" "=g")
  972.     (truncate:QI
  973.      (match_operand:HI 1 "register_operand" "r")))]
  974.   ""
  975.   "*
  976. {
  977.   if (GET_CODE (operands[0]) == MEM)
  978.     if (CONSTANT_ADDRESS_P (XEXP (operands[0], 0)))
  979.       {
  980.     if (! ((cc_prev_status.flags & CC_KNOW_HI_G1)
  981.            && XEXP (operands[0], 0) == cc_prev_status.mdep))
  982.       {
  983.         cc_status.flags |= CC_KNOW_HI_G1;
  984.         cc_status.mdep = XEXP (operands[0], 0);
  985.         output_asm_insn (\"sethi %%hi(%m0),%%g1\", operands);
  986.       }
  987.     return \"stb %1,[%%g1+%%lo(%m0)]\";
  988.       }
  989.     else
  990.       return \"stb %1,%0\";
  991.   return \"mov %1,%0\";
  992. }")
  993.  
  994. (define_insn "truncsihi2"
  995.   [(set (match_operand:HI 0 "general_operand" "=g")
  996.     (truncate:HI
  997.      (match_operand:SI 1 "register_operand" "r")))]
  998.   ""
  999.   "*
  1000. {
  1001.   if (GET_CODE (operands[0]) == MEM)
  1002.     if (CONSTANT_ADDRESS_P (XEXP (operands[0], 0)))
  1003.       {
  1004.     if (! ((cc_prev_status.flags & CC_KNOW_HI_G1)
  1005.            && XEXP (operands[0], 0) == cc_prev_status.mdep))
  1006.       {
  1007.         cc_status.flags |= CC_KNOW_HI_G1;
  1008.         cc_status.mdep = XEXP (operands[0], 0);
  1009.         output_asm_insn (\"sethi %%hi(%m0),%%g1\", operands);
  1010.       }
  1011.     return \"sth %1,[%%g1+%%lo(%m0)]\";
  1012.       }
  1013.     else
  1014.       return \"sth %1,%0\";
  1015.   return \"mov %1,%0\";
  1016. }")
  1017.  
  1018. ;;- zero extension instructions
  1019.  
  1020. ;; Note that the one starting from HImode comes before those for QImode
  1021. ;; so that a constant operand will match HImode, not QImode.
  1022.  
  1023. (define_insn "zero_extendhisi2"
  1024.   [(set (match_operand:SI 0 "register_operand" "=r")
  1025.     (zero_extend:SI
  1026.      (match_operand:HI 1 "general_operand" "g")))]
  1027.   ""
  1028.   "*
  1029. {
  1030.   if (REG_P (operands[1]))
  1031.     return \"sll %1,0x10,%0\;srl %0,0x10,%0\";
  1032.   if (GET_CODE (operands[1]) == CONST_INT)
  1033.     {
  1034.       operands[1] = gen_rtx (CONST_INT, VOIDmode,
  1035.                  INTVAL (operands[1]) & 0xffff);
  1036.       output_asm_insn (\"set %1,%0\", operands);
  1037.       return \"\";
  1038.     }
  1039.   if (CONSTANT_ADDRESS_P (XEXP (operands[1], 0)))
  1040.     {
  1041.       cc_status.flags |= CC_KNOW_HI_G1;
  1042.       cc_status.mdep = XEXP (operands[1], 0);
  1043.       return \"sethi %%hi(%m1),%%g1\;lduh [%%g1+%%lo(%m1)],%0\";
  1044.     }
  1045.   else
  1046.     return \"lduh %1,%0\";
  1047. }")
  1048.  
  1049. (define_insn "zero_extendqihi2"
  1050.   [(set (match_operand:HI 0 "register_operand" "=r")
  1051.     (zero_extend:HI
  1052.      (match_operand:QI 1 "general_operand" "g")))]
  1053.   ""
  1054.   "*
  1055. {
  1056.   if (REG_P (operands[1]))
  1057.     return \"and %1,0xff,%0\";
  1058.   if (GET_CODE (operands[1]) == CONST_INT)
  1059.     {
  1060.       operands[1] = gen_rtx (CONST_INT, VOIDmode,
  1061.                  INTVAL (operands[1]) & 0xff);
  1062.       output_asm_insn (\"set %1,%0\", operands);
  1063.       return \"\";
  1064.     }
  1065.   if (CONSTANT_ADDRESS_P (XEXP (operands[1], 0)))
  1066.     {
  1067.       cc_status.flags |= CC_KNOW_HI_G1;
  1068.       cc_status.mdep = XEXP (operands[1], 0);
  1069.       return \"sethi %%hi(%m1),%%g1\;ldub [%%g1+%%lo(%m1)],%0\";
  1070.     }
  1071.   else
  1072.     return \"ldub %1,%0\";
  1073. }")
  1074.  
  1075. (define_insn "zero_extendqisi2"
  1076.   [(set (match_operand:SI 0 "register_operand" "=r")
  1077.     (zero_extend:SI
  1078.      (match_operand:QI 1 "general_operand" "g")))]
  1079.   ""
  1080.   "*
  1081. {
  1082.   if (REG_P (operands[1]))
  1083.     return \"and %1,0xff,%0\";
  1084.   if (GET_CODE (operands[1]) == CONST_INT)
  1085.     {
  1086.       operands[1] = gen_rtx (CONST_INT, VOIDmode,
  1087.                  INTVAL (operands[1]) & 0xff);
  1088.       output_asm_insn (\"set %1,%0\", operands);
  1089.       return \"\";
  1090.     }
  1091.   if (CONSTANT_ADDRESS_P (XEXP (operands[1], 0)))
  1092.     {
  1093.       cc_status.flags |= CC_KNOW_HI_G1;
  1094.       cc_status.mdep = XEXP (operands[1], 0);
  1095.       return \"sethi %%hi(%m1),%%g1\;ldub [%%g1+%%lo(%m1)],%0\";
  1096.     }
  1097.   else
  1098.     return \"ldub %1,%0\";
  1099. }")
  1100.  
  1101. ;;- sign extension instructions
  1102. ;; Note that the one starting from HImode comes before those for QImode
  1103. ;; so that a constant operand will match HImode, not QImode.
  1104.  
  1105. (define_insn "extendhisi2"
  1106.   [(set (match_operand:SI 0 "register_operand" "=r")
  1107.     (sign_extend:SI
  1108.      (match_operand:HI 1 "general_operand" "g")))]
  1109.   ""
  1110.   "*
  1111. {
  1112.   if (REG_P (operands[1]))
  1113.     return \"sll %1,0x10,%0\;sra %0,0x10,%0\";
  1114.   if (GET_CODE (operands[1]) == CONST_INT)
  1115.     {
  1116.       int i = (short)INTVAL (operands[1]);
  1117.       operands[1] = gen_rtx (CONST_INT, VOIDmode, i);
  1118.       output_asm_insn (\"set %1,%0\", operands);
  1119.       return \"\";
  1120.     }
  1121.   if (CONSTANT_ADDRESS_P (XEXP (operands[1], 0)))
  1122.     {
  1123.       cc_status.flags |= CC_KNOW_HI_G1;
  1124.       cc_status.mdep = XEXP (operands[1], 0);
  1125.       return \"sethi %%hi(%m1),%%g1\;ldsh [%%g1+%%lo(%m1)],%0\";
  1126.     }
  1127.   else
  1128.     return \"ldsh %1,%0\";
  1129. }")
  1130.  
  1131. (define_insn "extendqihi2"
  1132.   [(set (match_operand:HI 0 "register_operand" "=r")
  1133.     (sign_extend:HI
  1134.      (match_operand:QI 1 "general_operand" "g")))]
  1135.   ""
  1136.   "*
  1137. {
  1138.   if (REG_P (operands[1]))
  1139.     return \"sll %1,0x18,%0\;sra %0,0x18,%0\";
  1140.   if (GET_CODE (operands[1]) == CONST_INT)
  1141.     {
  1142.       int i = (char)INTVAL (operands[1]);
  1143.       operands[1] = gen_rtx (CONST_INT, VOIDmode, i);
  1144.       output_asm_insn (\"set %1,%0\", operands);
  1145.       return \"\";
  1146.     }
  1147.   if (CONSTANT_ADDRESS_P (XEXP (operands[1], 0)))
  1148.     {
  1149.       cc_status.flags |= CC_KNOW_HI_G1;
  1150.       cc_status.mdep = XEXP (operands[1], 0);
  1151.       return \"sethi %%hi(%m1),%%g1\;ldsb [%%g1+%%lo(%m1)],%0\";
  1152.     }
  1153.   else
  1154.     return \"ldsb %1,%0\";
  1155. }")
  1156.  
  1157. (define_insn "extendqisi2"
  1158.   [(set (match_operand:SI 0 "register_operand" "=r")
  1159.     (sign_extend:SI
  1160.      (match_operand:QI 1 "general_operand" "g")))]
  1161.   ""
  1162.   "*
  1163. {
  1164.   if (REG_P (operands[1]))
  1165.     return \"sll %1,0x18,%0\;sra %0,0x18,%0\";
  1166.   if (GET_CODE (operands[1]) == CONST_INT)
  1167.     {
  1168.       int i = (char)INTVAL (operands[1]);
  1169.       operands[1] = gen_rtx (CONST_INT, VOIDmode, i);
  1170.       output_asm_insn (\"set %1,%0\", operands);
  1171.       return \"\";
  1172.     }
  1173.   if (CONSTANT_ADDRESS_P (XEXP (operands[1], 0)))
  1174.     {
  1175.       cc_status.flags |= CC_KNOW_HI_G1;
  1176.       cc_status.mdep = XEXP (operands[1], 0);
  1177.       return \"sethi %%hi(%m1),%%g1\;ldsb [%%g1+%%lo(%m1)],%0\";
  1178.     }
  1179.   else
  1180.     return \"ldsb %1,%0\";
  1181. }")
  1182.  
  1183. ;; Signed bitfield extractions come out looking like
  1184. ;;    (shiftrt (shift (sign_extend <Y>) <C1>) <C2>)
  1185. ;; which we expand poorly as four shift insns.
  1186. ;; These patters yeild two shifts:
  1187. ;;    (shiftrt (shift <Y> <C3>) <C4>)
  1188. (define_insn ""
  1189.   [(set (match_operand:SI 0 "register_operand" "=r")
  1190.     (ashiftrt:SI
  1191.      (sign_extend:SI
  1192.       (match_operand:QI 1 "register_operand" "r"))
  1193.      (match_operand:SI 2 "small_int" "n")))]
  1194.   ""
  1195.   "sll %1,0x18,%0\;sra %0,0x18+%2,%0")
  1196.  
  1197. (define_insn ""
  1198.   [(set (match_operand:SI 0 "register_operand" "=r")
  1199.     (ashiftrt:SI
  1200.      (sign_extend:SI
  1201.       (subreg:QI (ashift:SI (match_operand:SI 1 "register_operand" "r")
  1202.                 (match_operand:SI 2 "small_int" "n")) 0))
  1203.      (match_operand:SI 3 "small_int" "n")))]
  1204.   ""
  1205.   "sll %1,0x18+%2,%0\;sra %0,0x18+%3,%0")
  1206.  
  1207. ;; Special patterns for optimizing bit-field instructions.
  1208.  
  1209. ;; First two patterns are for bitfields that came from memory
  1210. ;; testing only the high bit.  They work with old combiner.
  1211. ;; @@ Actually, the second pattern does not work if we
  1212. ;; @@ need to set the N bit.
  1213. (define_insn ""
  1214.   [(set (cc0)
  1215.     (zero_extend:SI (subreg:QI (lshiftrt:SI (match_operand:SI 0 "register_operand" "r")
  1216.                         (const_int 7)) 0)))]
  1217.   "0"
  1218.   "andcc %0,128,%%g0")
  1219.  
  1220. (define_insn ""
  1221.   [(set (cc0)
  1222.     (sign_extend:SI (subreg:QI (ashiftrt:SI (match_operand:SI 0 "register_operand" "r")
  1223.                         (const_int 7)) 0)))]
  1224.   "0"
  1225.   "andcc %0,128,%%g0")
  1226.  
  1227. ;; next two patterns are good for bitfields coming from memory
  1228. ;; (via pseudo-register) or from a register, though this optimization
  1229. ;; is only good for values contained wholly within the bottom 13 bits
  1230. (define_insn ""
  1231.   [(set (cc0)
  1232.     (and:SI (lshiftrt:SI (match_operand:SI 0 "register_operand" "r")
  1233.                  (match_operand:SI 1 "small_int" "n"))
  1234.         (match_operand:SI 2 "small_int" "n")))]
  1235.   "(unsigned)((INTVAL (operands[2]) << INTVAL (operands[1])) + 0x1000) < 0x2000"
  1236.   "andcc %0,%2<<%1,%%g0")
  1237.  
  1238. (define_insn ""
  1239.   [(set (cc0)
  1240.     (and:SI (ashiftrt:SI (match_operand:SI 0 "register_operand" "r")
  1241.                  (match_operand:SI 1 "small_int" "n"))
  1242.         (match_operand:SI 2 "small_int" "n")))]
  1243.   "(unsigned)((INTVAL (operands[2]) << INTVAL (operands[1])) + 0x1000) < 0x2000"
  1244.   "andcc %0,%2<<%1,%%g0")
  1245.  
  1246. ;; Conversions between float and double.
  1247.  
  1248. (define_insn "extendsfdf2"
  1249.   [(set (match_operand:DF 0 "register_operand" "=f")
  1250.     (float_extend:DF
  1251.      (match_operand:SF 1 "register_operand" "f")))]
  1252.   ""
  1253.   "fstod %1,%0")
  1254.  
  1255. (define_insn "truncdfsf2"
  1256.   [(set (match_operand:SF 0 "register_operand" "=f")
  1257.     (float_truncate:SF
  1258.      (match_operand:DF 1 "register_operand" "f")))]
  1259.   ""
  1260.   "fdtos %1,%0")
  1261.  
  1262. ;; Conversion between fixed point and floating point.
  1263. ;; Note that among the fix-to-float insns
  1264. ;; the ones that start with SImode come first.
  1265. ;; That is so that an operand that is a CONST_INT
  1266. ;; (and therefore lacks a specific machine mode).
  1267. ;; will be recognized as SImode (which is always valid)
  1268. ;; rather than as QImode or HImode.
  1269.  
  1270. ;; This pattern forces (set (reg:SF ...) (float:SF (const_int ...)))
  1271. ;; to be reloaded by putting the constant into memory.
  1272. ;; It must come before the more general floatsisf2 pattern.
  1273. (define_insn ""
  1274.   [(set (match_operand:SF 0 "general_operand" "=f")
  1275.     (float:SF (match_operand 1 "" "m")))]
  1276.   "GET_CODE (operands[1]) == CONST_INT"
  1277.   "*
  1278. {
  1279.   if (CONSTANT_ADDRESS_P (XEXP (operands[1], 0)))
  1280.     {
  1281.       cc_status.flags |= CC_KNOW_HI_G1;
  1282.       cc_status.mdep = XEXP (operands[1], 0);
  1283.       return \"sethi %%hi(%m1),%%g1\;ld [%%g1+%%lo(%m1)],%0\;fitos %0,%0\";
  1284.     }
  1285.   return \"ld %1,%0\;fitos %0,%0\";
  1286. }")
  1287.  
  1288. (define_insn "floatsisf2"
  1289.   [(set (match_operand:SF 0 "general_operand" "=f")
  1290.     (float:SF (match_operand:SI 1 "general_operand" "rfm")))]
  1291.   ""
  1292.   "*
  1293. {
  1294.   if (GET_CODE (operands[1]) == MEM)
  1295.     if (CONSTANT_ADDRESS_P (XEXP (operands[1], 0)))
  1296.       {
  1297.     cc_status.flags |= CC_KNOW_HI_G1;
  1298.     cc_status.mdep = XEXP (operands[1], 0);
  1299.     return \"sethi %%hi(%m1),%%g1\;ld [%%g1+%%lo(%m1)],%0\;fitos %0,%0\";
  1300.       }
  1301.     else
  1302.       return \"ld %1,%0\;fitos %0,%0\";
  1303.   else if (FP_REG_P (operands[1]))
  1304.     return \"fitos %1,%0\";
  1305.   return \"st %r1,[%%fp-4]\;ld [%%fp-4],%0\;fitos %0,%0\";
  1306. }")
  1307.  
  1308. ;; This pattern forces (set (reg:DF ...) (float:DF (const_int ...)))
  1309. ;; to be reloaded by putting the constant into memory.
  1310. ;; It must come before the more general floatsidf2 pattern.
  1311. (define_insn ""
  1312.   [(set (match_operand:DF 0 "general_operand" "=f")
  1313.     (float:DF (match_operand 1 "" "m")))]
  1314.   "GET_CODE (operands[1]) == CONST_INT"
  1315.   "*
  1316. {
  1317.   if (CONSTANT_ADDRESS_P (XEXP (operands[1], 0)))
  1318.     {
  1319.       cc_status.flags |= CC_KNOW_HI_G1;
  1320.       cc_status.mdep = XEXP (operands[1], 0);
  1321.       return \"sethi %%hi(%m1),%%g1\;ld [%%g1+%%lo(%m1)],%0\;fitod %0,%0\";
  1322.     }
  1323.   return \"ld %1,%0\;fitod %0,%0\";
  1324. }")
  1325.  
  1326. (define_insn "floatsidf2"
  1327.   [(set (match_operand:DF 0 "general_operand" "=f")
  1328.     (float:DF (match_operand:SI 1 "general_operand" "rfm")))]
  1329.   ""
  1330.   "*
  1331. {
  1332.   if (GET_CODE (operands[1]) == MEM)
  1333.     if (CONSTANT_ADDRESS_P (XEXP (operands[1], 0)))
  1334.       {
  1335.     cc_status.flags |= CC_KNOW_HI_G1;
  1336.     cc_status.mdep = XEXP (operands[1], 0);
  1337.     return \"sethi %%hi(%m1),%%g1\;ld [%%g1+%%lo(%m1)],%0\;fitod %0,%0\";
  1338.       }
  1339.     else
  1340.       return \"ld %1,%0\;fitod %0,%0\";
  1341.   else if (FP_REG_P (operands[1]))
  1342.     return \"fitod %1,%0\";
  1343.   else
  1344.     return \"st %r1,[%%fp-4]\;ld [%%fp-4],%0\;fitod %0,%0\";
  1345. }")
  1346.  
  1347. ;; Convert a float to an actual integer.
  1348. ;; Truncation is performed as part of the conversion.
  1349. (define_insn "fix_truncsfsi2"
  1350.   [(set (match_operand:SI 0 "general_operand" "=rm")
  1351.     (fix:SI (fix:SF (match_operand:SF 1 "general_operand" "fm"))))]
  1352.   ""
  1353.   "*
  1354. {
  1355.   cc_status.flags &= ~(CC_F1_IS_0);
  1356.   if (FP_REG_P (operands[1]))
  1357.     output_asm_insn (\"fstoi %1,%%f1\", operands);
  1358.   else if (CONSTANT_ADDRESS_P (XEXP (operands[1], 0)))
  1359.     {
  1360.       cc_status.flags |= CC_KNOW_HI_G1;
  1361.       cc_status.mdep = XEXP (operands[1], 0);
  1362.       output_asm_insn (\"sethi %%hi(%m1),%%g1\;ld [%%g1+%%lo(%m1)],%%f1\;fstoi %%f1,%%f1\", operands);
  1363.     }
  1364.   else
  1365.     output_asm_insn (\"ld %1,%%f1\;fstoi %%f1,%%f1\", operands);
  1366.   if (GET_CODE (operands[0]) == MEM)
  1367.     if (CONSTANT_ADDRESS_P (XEXP (operands[0], 0)))
  1368.       {
  1369.     if (! ((cc_prev_status.flags & CC_KNOW_HI_G1)
  1370.            && XEXP (operands[0], 0) == cc_prev_status.mdep))
  1371.       {
  1372.         cc_status.flags |= CC_KNOW_HI_G1;
  1373.         cc_status.mdep = XEXP (operands[0], 0);
  1374.         output_asm_insn (\"sethi %%hi(%m0),%%g1\", operands);
  1375.       }
  1376.     return \"st %%f1,[%%g1+%%lo(%m0)]\";
  1377.       }
  1378.     else
  1379.       return \"st %%f1,%0\";
  1380.   else
  1381.     return \"st %%f1,[%%fp-4]\;ld [%%fp-4],%0\";
  1382. }")
  1383.  
  1384. (define_insn "fix_truncdfsi2"
  1385.   [(set (match_operand:SI 0 "general_operand" "=rm")
  1386.     (fix:SI (fix:DF (match_operand:DF 1 "general_operand" "fm"))))]
  1387.   ""
  1388.   "*
  1389. {
  1390.   cc_status.flags &= ~CC_F0_IS_0;
  1391.   if (FP_REG_P (operands[1]))
  1392.     output_asm_insn (\"fdtoi %1,%%f0\", operands);
  1393.   else
  1394.     {
  1395.       rtx xoperands[2];
  1396.       xoperands[0] = gen_rtx (REG, DFmode, 32);
  1397.       xoperands[1] = operands[1];
  1398.       output_asm_insn (output_fp_move_double (xoperands), xoperands);
  1399.       output_asm_insn (\"fdtoi %%f0,%%f0\", 0);
  1400.     }
  1401.   if (GET_CODE (operands[0]) == MEM)
  1402.     if (CONSTANT_ADDRESS_P (XEXP (operands[0], 0)))
  1403.       {
  1404.     if (! ((cc_prev_status.flags & CC_KNOW_HI_G1)
  1405.            && XEXP (operands[0], 0) == cc_prev_status.mdep))
  1406.       {
  1407.         cc_status.flags |= CC_KNOW_HI_G1;
  1408.         cc_status.mdep = XEXP (operands[0], 0);
  1409.         output_asm_insn (\"sethi %%hi(%m0),%%g1\", operands);
  1410.       }
  1411.     return \"st %%f0,[%%g1+%%lo(%m0)]\";
  1412.       }
  1413.     else
  1414.       return \"st %%f0,%0\";
  1415.   else
  1416.     return \"st %%f0,[%%fp-4]\;ld [%%fp-4],%0\";
  1417. }")
  1418.  
  1419. ;;- arithmetic instructions
  1420.  
  1421. (define_insn "addsi3"
  1422.   [(set (match_operand:SI 0 "register_operand" "=r")
  1423.     (plus:SI (match_operand:SI 1 "arith32_operand" "%r")
  1424.          (match_operand:SI 2 "arith32_operand" "rn")))]
  1425.   ""
  1426.   "*
  1427. {
  1428.   if (REG_P (operands[2]))
  1429.     return \"add %1,%2,%0\";
  1430.   if (SMALL_INT (operands[2]))
  1431.     return \"add %1,%2,%0\";
  1432.   cc_status.flags &= ~CC_KNOW_HI_G1;
  1433.   return \"sethi %%hi(%2),%%g1\;or %%lo(%2),%%g1,%%g1\;add %1,%%g1,%0\";
  1434. }")
  1435.  
  1436. (define_insn "subsi3"
  1437.   [(set (match_operand:SI 0 "register_operand" "=r")
  1438.     (minus:SI (match_operand:SI 1 "register_operand" "r")
  1439.           (match_operand:SI 2 "arith32_operand" "rn")))]
  1440.   ""
  1441.   "*
  1442. {
  1443.   if (REG_P (operands[2]))
  1444.     return \"sub %1,%2,%0\";
  1445.   if (SMALL_INT (operands[2]))
  1446.     return \"sub %1,%2,%0\";
  1447.   cc_status.flags &= ~CC_KNOW_HI_G1;
  1448.   return \"sethi %%hi(%2),%%g1\;or %%lo(%2),%%g1,%%g1\;sub %1,%%g1,%0\";
  1449. }")
  1450.  
  1451. (define_expand "mulsi3"
  1452.   [(set (match_operand:SI 0 "register_operand" "r")
  1453.     (mult:SI (match_operand:SI 1 "general_operand" "")
  1454.          (match_operand:SI 2 "general_operand" "")))]
  1455.   ""
  1456.   "
  1457. {
  1458.   rtx src;
  1459.  
  1460.   if (GET_CODE (operands[1]) == CONST_INT)
  1461.     if (GET_CODE (operands[2]) == CONST_INT)
  1462.       {
  1463.     emit_move_insn (operands[0],
  1464.             gen_rtx (CONST_INT, VOIDmode,
  1465.                  INTVAL (operands[1]) * INTVAL (operands[2])));
  1466.     DONE;
  1467.       }
  1468.     else
  1469.       src = gen_rtx (MULT, SImode,
  1470.              copy_to_mode_reg (SImode, operands[2]),
  1471.              operands[1]);
  1472.   else if (GET_CODE (operands[2]) == CONST_INT)
  1473.     src = gen_rtx (MULT, SImode,
  1474.            copy_to_mode_reg (SImode, operands[1]),
  1475.            operands[2]);
  1476.   else src = 0;
  1477.  
  1478.   if (src)
  1479.     emit_insn (gen_rtx (SET, VOIDmode, operands[0], src));
  1480.   else
  1481.     emit_insn (gen_rtx (PARALLEL, VOIDmode, gen_rtvec (5,
  1482.            gen_rtx (SET, VOIDmode, operands[0],
  1483.             gen_rtx (MULT, SImode, operands[1], operands[2])),
  1484.            gen_rtx (CLOBBER, VOIDmode, gen_rtx (REG, SImode, 8)),
  1485.            gen_rtx (CLOBBER, VOIDmode, gen_rtx (REG, SImode, 9)),
  1486.            gen_rtx (CLOBBER, VOIDmode, gen_rtx (REG, SImode, 12)),
  1487.            gen_rtx (CLOBBER, VOIDmode, gen_rtx (REG, SImode, 13)))));
  1488.   DONE;
  1489. }")
  1490.  
  1491. (define_expand "umulsi3"
  1492.   [(set (match_operand:SI 0 "register_operand" "r")
  1493.     (umult:SI (match_operand:SI 1 "general_operand" "")
  1494.           (match_operand:SI 2 "general_operand" "")))]
  1495.   ""
  1496.   "
  1497. {
  1498.   rtx src;
  1499.  
  1500.   if (GET_CODE (operands[1]) == CONST_INT)
  1501.     if (GET_CODE (operands[2]) == CONST_INT)
  1502.       {
  1503.     emit_move_insn (operands[0],
  1504.             gen_rtx (CONST_INT, VOIDmode,
  1505.                  (unsigned)INTVAL (operands[1]) * (unsigned)INTVAL (operands[2])));
  1506.     DONE;
  1507.       }
  1508.     else
  1509.       src = gen_rtx (UMULT, SImode,
  1510.              copy_to_mode_reg (SImode, operands[2]),
  1511.              operands[1]);
  1512.   else if (GET_CODE (operands[2]) == CONST_INT)
  1513.     src = gen_rtx (UMULT, SImode,
  1514.            copy_to_mode_reg (SImode, operands[1]),
  1515.            operands[2]);
  1516.   else src = 0;
  1517.  
  1518.   if (src)
  1519.     emit_insn (gen_rtx (SET, VOIDmode, operands[0], src));
  1520.   else
  1521.     emit_insn (gen_rtx (PARALLEL, VOIDmode, gen_rtvec (5,
  1522.            gen_rtx (SET, VOIDmode, operands[0],
  1523.             gen_rtx (UMULT, SImode, operands[1], operands[2])),
  1524.            gen_rtx (CLOBBER, VOIDmode, gen_rtx (REG, SImode, 8)),
  1525.            gen_rtx (CLOBBER, VOIDmode, gen_rtx (REG, SImode, 9)),
  1526.            gen_rtx (CLOBBER, VOIDmode, gen_rtx (REG, SImode, 12)),
  1527.            gen_rtx (CLOBBER, VOIDmode, gen_rtx (REG, SImode, 13)))));
  1528.   DONE;
  1529. }")
  1530.  
  1531. (define_insn ""
  1532.   [(set (match_operand:SI 0 "register_operand" "=r")
  1533.     (mult:SI (match_operand:SI 1 "register_operand" "r")
  1534.          (match_operand:SI 2 "immediate_operand" "n")))]
  1535.   ""
  1536.   "* return output_mul_by_constant (insn, operands, 0);")
  1537.  
  1538. (define_insn ""
  1539.   [(set (match_operand:SI 0 "register_operand" "=r")
  1540.     (umult:SI (match_operand:SI 1 "register_operand" "r")
  1541.           (match_operand:SI 2 "immediate_operand" "n")))]
  1542.   ""
  1543.   "* return output_mul_by_constant (insn, operands, 1);")
  1544.  
  1545. (define_insn ""
  1546.   [(set (match_operand:SI 0 "register_operand" "=r")
  1547.     (mult:SI (match_operand:SI 1 "general_operand" "%r")
  1548.          (match_operand:SI 2 "general_operand" "r")))
  1549.    (clobber (reg:SI 8))
  1550.    (clobber (reg:SI 9))
  1551.    (clobber (reg:SI 12))
  1552.    (clobber (reg:SI 13))]
  1553.   ""
  1554.   "* return output_mul_insn (operands, 0);")
  1555.  
  1556. (define_insn ""
  1557.   [(set (match_operand:SI 0 "register_operand" "=r")
  1558.     (umult:SI (match_operand:SI 1 "general_operand" "%r")
  1559.           (match_operand:SI 2 "general_operand" "r")))
  1560.    (clobber (reg:SI 8))
  1561.    (clobber (reg:SI 9))
  1562.    (clobber (reg:SI 12))
  1563.    (clobber (reg:SI 13))]
  1564.   ""
  1565.   "* return output_mul_insn (operands, 1);")
  1566.  
  1567. ;; this pattern is needed because cse may eliminate the multiplication,
  1568. ;; but leave the clobbers behind.
  1569.  
  1570. (define_insn ""
  1571.   [(set (match_operand:SI 0 "register_operand" "=r")
  1572.     (match_operand:SI 1 "general_operand" "g"))
  1573.    (clobber (reg:SI 8))
  1574.    (clobber (reg:SI 9))
  1575.    (clobber (reg:SI 12))
  1576.    (clobber (reg:SI 13))]
  1577.   ""
  1578.   "*
  1579. {
  1580.   if (GET_CODE (operands[1]) == CONST_INT)
  1581.     {
  1582.       if (SMALL_INT (operands[1]))
  1583.     return \"mov %1,%0\";
  1584.       return \"sethi %%hi(%1),%0\;or %%lo(%1),%0,%0\";
  1585.     }
  1586.   if (GET_CODE (operands[1]) == MEM)
  1587.     return \"ld %1,%0\";
  1588.   return \"mov %1,%0\";
  1589. }")
  1590.  
  1591. ;; In case constant factor turns out to be -1.
  1592. (define_insn ""
  1593.   [(set (match_operand:SI 0 "register_operand" "=r")
  1594.     (neg:SI (match_operand:SI 1 "general_operand" "rI")))
  1595.    (clobber (reg:SI 8))
  1596.    (clobber (reg:SI 9))
  1597.    (clobber (reg:SI 12))
  1598.    (clobber (reg:SI 13))]
  1599.   ""
  1600.   "sub %%g0,%1,%0")
  1601.  
  1602. ;;- and instructions (with compliment also)               
  1603. (define_insn "andsi3"
  1604.   [(set (match_operand:SI 0 "register_operand" "=r")
  1605.     (and:SI (match_operand:SI 1 "arith32_operand" "%r")
  1606.         (match_operand:SI 2 "arith32_operand" "rn")))]
  1607.   ""
  1608.   "*
  1609. {
  1610.   if (REG_P (operands[2]) || SMALL_INT (operands[2]))
  1611.     return \"and %1,%2,%0\";
  1612.   cc_status.flags &= ~CC_KNOW_HI_G1;
  1613.   return \"sethi %%hi(%2),%%g1\;or %%lo(%2),%%g1,%%g1\;and %1,%%g1,%0\";
  1614. }")
  1615.  
  1616. (define_insn "andcbsi3"
  1617.   [(set (match_operand:SI 0 "register_operand" "=r")
  1618.     (and:SI (match_operand:SI 1 "register_operand" "r")
  1619.         (not:SI (match_operand:SI 2 "register_operand" "r"))))]
  1620.   ""
  1621.   "andn %1,%2,%0")
  1622.  
  1623. (define_insn "iorsi3"
  1624.   [(set (match_operand:SI 0 "register_operand" "=r")
  1625.     (ior:SI (match_operand:SI 1 "arith32_operand" "%r")
  1626.         (match_operand:SI 2 "arith32_operand" "rn")))]
  1627.   ""
  1628.   "*
  1629. {
  1630.   if (REG_P (operands[2]) || SMALL_INT (operands[2]))
  1631.     return \"or %1,%2,%0\";
  1632.   cc_status.flags &= ~CC_KNOW_HI_G1;
  1633.   return \"sethi %%hi(%2),%%g1\;or %%lo(%2),%%g1,%%g1\;or %1,%%g1,%0\";
  1634. }")
  1635.  
  1636. (define_insn "iorcbsi3"
  1637.   [(set (match_operand:SI 0 "register_operand" "=r")
  1638.     (ior:SI (match_operand:SI 1 "register_operand" "r")
  1639.         (not:SI (match_operand:SI 2 "register_operand" "r"))))]
  1640.   ""
  1641.   "orn %1,%2,%0")
  1642.  
  1643. (define_insn "xorsi3"
  1644.   [(set (match_operand:SI 0 "register_operand" "=r")
  1645.     (xor:SI (match_operand:SI 1 "arith32_operand" "%r")
  1646.         (match_operand:SI 2 "arith32_operand" "rn")))]
  1647.   ""
  1648.   "*
  1649. {
  1650.   if (REG_P (operands[2]) || SMALL_INT (operands[2]))
  1651.     return \"xor %1,%2,%0\";
  1652.   cc_status.flags &= ~CC_KNOW_HI_G1;
  1653.   return \"sethi %%hi(%2),%%g1\;or %%lo(%2),%%g1,%%g1\;xor %1,%%g1,%0\";
  1654. }")
  1655.  
  1656. (define_insn "xorcbsi3"
  1657.   [(set (match_operand:SI 0 "register_operand" "=r")
  1658.     (xor:SI (match_operand:SI 1 "register_operand" "r")
  1659.         (not:SI (match_operand:SI 2 "register_operand" "r"))))]
  1660.   ""
  1661.   "xnor %1,%2,%0")
  1662.  
  1663. ;; We cannot use the "neg" pseudo insn because the Sun assembler
  1664. ;; does not know how to make it work for constants.
  1665. (define_insn "negsi2"
  1666.   [(set (match_operand:SI 0 "general_operand" "=r")
  1667.     (neg:SI (match_operand:SI 1 "arith_operand" "rI")))]
  1668.   ""
  1669.   "sub %%g0,%1,%0")
  1670.  
  1671. ;; We cannot use the "not" pseudo insn because the Sun assembler
  1672. ;; does not know how to make it work for constants.
  1673. (define_insn "one_cmplsi2"
  1674.   [(set (match_operand:SI 0 "general_operand" "=r")
  1675.     (not:SI (match_operand:SI 1 "arith_operand" "rI")))]
  1676.   ""
  1677.   "xnor %%g0,%1,%0")
  1678.  
  1679. ;; Floating point arithmetic instructions.
  1680.  
  1681. (define_insn "adddf3"
  1682.   [(set (match_operand:DF 0 "register_operand" "=f")
  1683.     (plus:DF (match_operand:DF 1 "register_operand" "f")
  1684.          (match_operand:DF 2 "register_operand" "f")))]
  1685.   ""
  1686.   "faddd %1,%2,%0")
  1687.  
  1688. (define_insn "addsf3"
  1689.   [(set (match_operand:SF 0 "register_operand" "=f")
  1690.     (plus:SF (match_operand:SF 1 "register_operand" "f")
  1691.          (match_operand:SF 2 "register_operand" "f")))]
  1692.   ""
  1693.   "fadds %1,%2,%0")
  1694.  
  1695. (define_insn "subdf3"
  1696.   [(set (match_operand:DF 0 "register_operand" "=f")
  1697.     (minus:DF (match_operand:DF 1 "register_operand" "f")
  1698.           (match_operand:DF 2 "register_operand" "f")))]
  1699.   ""
  1700.   "fsubd %1,%2,%0")
  1701.  
  1702. (define_insn "subsf3"
  1703.   [(set (match_operand:SF 0 "register_operand" "=f")
  1704.     (minus:SF (match_operand:SF 1 "register_operand" "f")
  1705.           (match_operand:SF 2 "register_operand" "f")))]
  1706.   ""
  1707.   "fsubs %1,%2,%0")
  1708.  
  1709. (define_insn "muldf3"
  1710.   [(set (match_operand:DF 0 "register_operand" "=f")
  1711.     (mult:DF (match_operand:DF 1 "register_operand" "f")
  1712.          (match_operand:DF 2 "register_operand" "f")))]
  1713.   ""
  1714.   "fmuld %1,%2,%0")
  1715.  
  1716. (define_insn "mulsf3"
  1717.   [(set (match_operand:SF 0 "register_operand" "=f")
  1718.     (mult:SF (match_operand:SF 1 "register_operand" "f")
  1719.          (match_operand:SF 2 "register_operand" "f")))]
  1720.   ""
  1721.   "fmuls %1,%2,%0")
  1722.  
  1723. (define_insn "divdf3"
  1724.   [(set (match_operand:DF 0 "register_operand" "=f")
  1725.     (div:DF (match_operand:DF 1 "register_operand" "f")
  1726.         (match_operand:DF 2 "register_operand" "f")))]
  1727.   ""
  1728.   "fdivd %1,%2,%0")
  1729.  
  1730. (define_insn "divsf3"
  1731.   [(set (match_operand:SF 0 "register_operand" "=f")
  1732.     (div:SF (match_operand:SF 1 "register_operand" "f")
  1733.         (match_operand:SF 2 "register_operand" "f")))]
  1734.   ""
  1735.   "fdivs %1,%2,%0")
  1736.  
  1737. (define_insn "negdf2"
  1738.   [(set (match_operand:DF 0 "register_operand" "=f")
  1739.     (neg:DF (match_operand:DF 1 "register_operand" "f")))]
  1740.   ""
  1741.   "*
  1742. {
  1743.   output_asm_insn (\"fnegs %1,%0\", operands);
  1744.   if (REGNO (operands[0]) != REGNO (operands[1]))
  1745.     {
  1746.       operands[0] = gen_rtx (REG, VOIDmode, REGNO (operands[0]) + 1);
  1747.       operands[1] = gen_rtx (REG, VOIDmode, REGNO (operands[1]) + 1);
  1748.       output_asm_insn (\"fmovs %1,%0\", operands);
  1749.     }
  1750.   return \"\";
  1751. }")
  1752.  
  1753. (define_insn "negsf2"
  1754.   [(set (match_operand:SF 0 "register_operand" "=f")
  1755.     (neg:SF (match_operand:SF 1 "register_operand" "f")))]
  1756.   ""
  1757.   "fnegs %1,%0")
  1758.  
  1759. (define_insn "absdf2"
  1760.   [(set (match_operand:DF 0 "register_operand" "=f")
  1761.     (abs:DF (match_operand:DF 1 "register_operand" "f")))]
  1762.   ""
  1763.   "*
  1764. {
  1765.   output_asm_insn (\"fabss %1,%0\", operands);
  1766.   if (REGNO (operands[0]) != REGNO (operands[1]))
  1767.     {
  1768.       operands[0] = gen_rtx (REG, VOIDmode, REGNO (operands[0]) + 1);
  1769.       operands[1] = gen_rtx (REG, VOIDmode, REGNO (operands[1]) + 1);
  1770.       output_asm_insn (\"fmovs %1,%0\", operands);
  1771.     }
  1772.   return \"\";
  1773. }")
  1774.  
  1775. (define_insn "abssf2"
  1776.   [(set (match_operand:SF 0 "register_operand" "=f")
  1777.     (abs:SF (match_operand:SF 1 "register_operand" "f")))]
  1778.   ""
  1779.   "fabss %1,%0")
  1780.  
  1781. ;; Shift instructions
  1782.  
  1783. ;; Optimized special case of shifting.
  1784. ;; Must precede the general case.
  1785.  
  1786. (define_insn ""
  1787.   [(set (match_operand:SI 0 "register_operand" "=r")
  1788.     (ashiftrt:SI (match_operand:SI 1 "memory_operand" "m")
  1789.              (const_int 24)))]
  1790.   ""
  1791.   "*
  1792. {
  1793.   if (CONSTANT_ADDRESS_P (XEXP (operands[1], 0)))
  1794.     {
  1795.       cc_status.flags |= CC_KNOW_HI_G1;
  1796.       cc_status.mdep = XEXP (operands[1], 0);
  1797.       return \"sethi %%hi(%m1),%%g1\;ldsb [%%g1+%%lo(%m1)],%0\";
  1798.     }
  1799.   return \"ldsb %1,%0\";
  1800. }")
  1801.  
  1802. (define_insn ""
  1803.   [(set (match_operand:SI 0 "register_operand" "=r")
  1804.     (lshiftrt:SI (match_operand:SI 1 "memory_operand" "m")
  1805.              (const_int 24)))]
  1806.   ""
  1807.   "*
  1808. {
  1809.   if (CONSTANT_ADDRESS_P (XEXP (operands[1], 0)))
  1810.     {
  1811.       cc_status.flags |= CC_KNOW_HI_G1;
  1812.       cc_status.mdep = XEXP (operands[1], 0);
  1813.       return \"sethi %%hi(%m1),%%g1\;ldub [%%g1+%%lo(%m1)],%0\";
  1814.     }
  1815.   return \"ldub %1,%0\";
  1816. }")
  1817.  
  1818. ;;- arithmetic shift instructions
  1819. (define_insn "ashlsi3"
  1820.   [(set (match_operand:SI 0 "register_operand" "=r")
  1821.     (ashift:SI (match_operand:SI 1 "register_operand" "r")
  1822.            (match_operand:SI 2 "arith32_operand" "rn")))]
  1823.   ""
  1824.   "*
  1825. {
  1826.   if (GET_CODE (operands[2]) == CONST_INT
  1827.       && INTVAL (operands[2]) >= 32)
  1828.     operands[2] = gen_rtx (CONST_INT, VOIDmode, INTVAL (operands[2]) & 31);
  1829.   return \"sll %1,%2,%0\";
  1830. }")
  1831.  
  1832. (define_insn "ashrsi3"
  1833.   [(set (match_operand:SI 0 "register_operand" "=r")
  1834.     (ashiftrt:SI (match_operand:SI 1 "register_operand" "r")
  1835.              (match_operand:SI 2 "arith32_operand" "rn")))]
  1836.   ""
  1837.   "*
  1838. {
  1839.   if (GET_CODE (operands[2]) == CONST_INT
  1840.       && INTVAL (operands[2]) >= 32)
  1841.     operands[2] = gen_rtx (CONST_INT, VOIDmode, INTVAL (operands[2]) & 31);
  1842.   return \"sra %1,%2,%0\";
  1843. }")
  1844.  
  1845. (define_insn "lshrsi3"
  1846.   [(set (match_operand:SI 0 "register_operand" "=r")
  1847.     (lshiftrt:SI (match_operand:SI 1 "register_operand" "r")
  1848.              (match_operand:SI 2 "arith32_operand" "rn")))]
  1849.   ""
  1850.   "*
  1851. {
  1852.   if (GET_CODE (operands[2]) == CONST_INT
  1853.       && INTVAL (operands[2]) >= 32)
  1854.     operands[2] = gen_rtx (CONST_INT, VOIDmode, INTVAL (operands[2]) & 31);
  1855.   return \"srl %1,%2,%0\";
  1856. }")
  1857.  
  1858. ;; Unconditional and other jump instructions
  1859. ;; Note that for the Sparc, by setting the annul bit on an unconditional
  1860. ;; branch, the following insn is never executed.  This saves us a nop,
  1861. ;; but requires a debugger which can handle annuled branches.
  1862. (define_insn "jump"
  1863.   [(set (pc) (label_ref (match_operand 0 "" "")))]
  1864.   ""
  1865.   "*
  1866. {
  1867.   extern int optimize;
  1868.   extern int flag_no_peephole;
  1869.  
  1870.   if (optimize && !flag_no_peephole)
  1871.     return \"b,a %l0\";
  1872.   return \"b %l0\;nop\";
  1873. }")
  1874.  
  1875. ;; Peephole optimizers recognize a few simple cases when delay insns are safe.
  1876. ;; Complex ones are up front.  Simple ones after.
  1877.  
  1878. ;; This pattern is just like the following one, but matches when there
  1879. ;; is a jump insn after the "delay" insn.  Without this pattern, we
  1880. ;; de-optimize that case.
  1881.  
  1882. (define_peephole
  1883.   [(set (pc) (match_operand 0 "" ""))
  1884.    (set (match_operand:SI 1 "" "")
  1885.     (match_operand:SI 2 "" ""))
  1886.    (set (pc) (label_ref (match_operand 3 "" "")))]
  1887.   "TARGET_EAGER && operands_satisfy_eager_branch_peephole (operands, 2)"
  1888.   "*
  1889. {
  1890.   rtx xoperands[2];
  1891.   rtx pat = gen_rtx (SET, VOIDmode, operands[1], operands[2]);
  1892.   rtx delay_insn = gen_rtx (INSN, VOIDmode, 0, 0, 0, pat, -1, 0, 0);
  1893.   rtx label, head;
  1894.   int parity;
  1895.  
  1896.   if (GET_CODE (XEXP (operands[0], 1)) == PC)
  1897.     {
  1898.       parity = 1;
  1899.       label = XEXP (XEXP (operands[0], 2), 0);
  1900.     }
  1901.   else
  1902.     {
  1903.       parity = 0;
  1904.       label = XEXP (XEXP (operands[0], 1), 0);
  1905.     }
  1906.   xoperands[0] = XEXP (operands[0], 0);
  1907.   xoperands[1] = label;
  1908.  
  1909.   head = next_real_insn_no_labels (label);
  1910.  
  1911.   /* If at the target of this label we set the condition codes,
  1912.      and the condition codes are already set for that value,
  1913.      advance, if we can, to the following insn.  */
  1914.   if (GET_CODE (PATTERN (head)) == SET
  1915.       && GET_CODE (SET_DEST (PATTERN (head))) == CC0
  1916.       && cc_status.value2 == SET_SRC (PATTERN (head)))
  1917.     {
  1918.       rtx nhead = next_real_insn_no_labels (head);
  1919.       if (nhead
  1920.       && GET_CODE (nhead) == INSN
  1921.       && GET_CODE (PATTERN (nhead)) == SET
  1922.       && strict_single_insn_op_p (SET_SRC (PATTERN (nhead)),
  1923.                       GET_MODE (SET_DEST (PATTERN (nhead))))
  1924.       && strict_single_insn_op_p (SET_DEST (PATTERN (nhead)), VOIDmode)
  1925.       /* Moves between FP regs and CPU regs are two insns.  */
  1926.       && !(GET_CODE (SET_SRC (PATTERN (nhead))) == REG
  1927.            && GET_CODE (SET_DEST (PATTERN (nhead))) == REG
  1928.            && (FP_REG_P (SET_SRC (PATTERN (nhead)))
  1929.            != FP_REG_P (SET_DEST (PATTERN (nhead))))))
  1930.     {
  1931.       head = nhead;
  1932.     }
  1933.     }
  1934.  
  1935.   /* Output the branch instruction first.  */
  1936.   if (cc_prev_status.flags & CC_IN_FCCR)
  1937.     {
  1938.       if (parity)
  1939.     output_asm_insn (\"fb%F0,a %l1 ! eager\", xoperands);
  1940.       else
  1941.     output_asm_insn (\"fb%C0,a %l1 ! eager\", xoperands);
  1942.     }
  1943.   else if (cc_prev_status.flags & CC_NO_OVERFLOW)
  1944.     {
  1945.       if (parity)
  1946.     output_asm_insn (\"b%U0,a %l1 ! eager\", xoperands);
  1947.       else
  1948.     output_asm_insn (\"b%I0,a %l1 ! eager\", xoperands);
  1949.     }
  1950.   else
  1951.     {
  1952.       if (parity)
  1953.     output_asm_insn (\"b%N0,a %l1 ! eager\", xoperands);
  1954.       else
  1955.     output_asm_insn (\"b%C0,a %l1 ! eager\", xoperands);
  1956.     }
  1957.  
  1958.   /* Now steal the first insn of the target.  */
  1959.   output_eager_then_insn (head, operands);
  1960.  
  1961.   XVECEXP (PATTERN (insn), 0, 0) = XVECEXP (PATTERN (insn), 0, 1);
  1962.   XVECEXP (PATTERN (insn), 0, 1) = XVECEXP (PATTERN (insn), 0, 2);
  1963.  
  1964.   return output_delayed_branch (\"b %l3 ! eager2\", operands, insn);
  1965. }")
  1966.  
  1967. ;; Here is a peephole which recognizes where delay insns can be made safe:
  1968. ;; (1) following a conditional branch, if the target of the conditional branch
  1969. ;; has only one user (this insn), move the first insn into our delay slot
  1970. ;; and emit an annulled branch.
  1971. ;; (2) following a conditional branch, if we can execute the fall-through
  1972. ;; insn without risking any evil effects, then do that instead of a nop.
  1973.  
  1974. (define_peephole
  1975.   [(set (pc) (match_operand 0 "" ""))
  1976.    (set (match_operand:SI 1 "" "")
  1977.     (match_operand:SI 2 "" ""))]
  1978.   "TARGET_EAGER && operands_satisfy_eager_branch_peephole (operands, 1)"
  1979.   "*
  1980. {
  1981.   rtx xoperands[2];
  1982.   rtx pat = gen_rtx (SET, VOIDmode, operands[1], operands[2]);
  1983.   rtx delay_insn = gen_rtx (INSN, VOIDmode, 0, 0, 0, pat, -1, 0, 0);
  1984.   rtx label, head, prev = (rtx)1;
  1985.   int parity;
  1986.  
  1987.   if (GET_CODE (XEXP (operands[0], 1)) == PC)
  1988.     {
  1989.       parity = 1;
  1990.       label = XEXP (XEXP (operands[0], 2), 0);
  1991.     }
  1992.   else
  1993.     {
  1994.       parity = 0;
  1995.       label = XEXP (XEXP (operands[0], 1), 0);
  1996.     }
  1997.   xoperands[0] = XEXP (operands[0], 0);
  1998.   xoperands[1] = label;
  1999.  
  2000.   if (LABEL_NUSES (label) == 1)
  2001.     {
  2002.       prev = PREV_INSN (label);
  2003.       while (prev
  2004.          && (GET_CODE (prev) == NOTE
  2005.          || (GET_CODE (prev) == INSN
  2006.              && (GET_CODE (PATTERN (prev)) == CLOBBER
  2007.              || GET_CODE (PATTERN (prev)) == USE))))
  2008.     prev = PREV_INSN (prev);
  2009.       if (prev == 0
  2010.       || GET_CODE (prev) == BARRIER)
  2011.     {
  2012.       prev = 0;
  2013.       head = next_real_insn_no_labels (label);
  2014.     }
  2015.     }
  2016.   if (prev == 0
  2017.       && head != 0
  2018.       && ! INSN_DELETED_P (head)
  2019.       && GET_CODE (head) == INSN
  2020.       && GET_CODE (PATTERN (head)) == SET
  2021.       && strict_single_insn_op_p (SET_SRC (PATTERN (head)),
  2022.                   GET_MODE (SET_DEST (PATTERN (head))))
  2023.       && strict_single_insn_op_p (SET_DEST (PATTERN (head)), VOIDmode)
  2024.       /* Moves between FP regs and CPU regs are two insns.  */
  2025.       && !(GET_CODE (SET_SRC (PATTERN (head))) == REG
  2026.        && GET_CODE (SET_DEST (PATTERN (head))) == REG
  2027.        && (FP_REG_P (SET_SRC (PATTERN (head)))
  2028.            != FP_REG_P (SET_DEST (PATTERN (head))))))
  2029.     {
  2030.       /* If at the target of this label we set the condition codes,
  2031.      and the condition codes are already set for that value,
  2032.      advance, if we can, to the following insn.  */
  2033.       if (GET_CODE (PATTERN (head)) == SET
  2034.       && GET_CODE (SET_DEST (PATTERN (head))) == CC0
  2035.       && cc_status.value2 == SET_SRC (PATTERN (head)))
  2036.     {
  2037.       rtx nhead = next_real_insn_no_labels (head);
  2038.       if (nhead
  2039.           && GET_CODE (nhead) == INSN
  2040.           && GET_CODE (PATTERN (nhead)) == SET
  2041.           && strict_single_insn_op_p (SET_SRC (PATTERN (nhead)),
  2042.                       GET_MODE (SET_DEST (nhead)))
  2043.           && strict_single_insn_op_p (SET_DEST (PATTERN (nhead)), VOIDmode)
  2044.           /* Moves between FP regs and CPU regs are two insns.  */
  2045.           && !(GET_CODE (SET_SRC (PATTERN (nhead))) == REG
  2046.            && GET_CODE (SET_DEST (PATTERN (nhead))) == REG
  2047.            && (FP_REG_P (SET_SRC (PATTERN (nhead)))
  2048.                != FP_REG_P (SET_DEST (PATTERN (nhead))))))
  2049.         head = nhead;
  2050.     }
  2051.  
  2052.       /* Output the branch instruction first.  */
  2053.       if (cc_prev_status.flags & CC_IN_FCCR)
  2054.     {
  2055.       if (parity)
  2056.         output_asm_insn (\"fb%F0,a %l1 ! eager\", xoperands);
  2057.       else
  2058.         output_asm_insn (\"fb%C0,a %l1 ! eager\", xoperands);
  2059.     }
  2060.       else if (cc_prev_status.flags & CC_NO_OVERFLOW)
  2061.     {
  2062.       if (parity)
  2063.         output_asm_insn (\"b%U0,a %l1 ! eager\", xoperands);
  2064.       else
  2065.         output_asm_insn (\"b%I0,a %l1 ! eager\", xoperands);
  2066.     }
  2067.       else
  2068.     {
  2069.       if (parity)
  2070.         output_asm_insn (\"b%N0,a %l1 ! eager\", xoperands);
  2071.       else
  2072.         output_asm_insn (\"b%C0,a %l1 ! eager\", xoperands);
  2073.     }
  2074.  
  2075.       /* Now steal the first insn of the target.  */
  2076.       output_eager_then_insn (head, operands);
  2077.     }
  2078.   else
  2079.     {
  2080.       /* Output the branch instruction first.  */
  2081.       if (cc_prev_status.flags & CC_IN_FCCR)
  2082.     {
  2083.       if (parity)
  2084.         output_asm_insn (\"fb%F0 %l1 ! eager\", xoperands);
  2085.       else
  2086.         output_asm_insn (\"fb%C0 %l1 ! eager\", xoperands);
  2087.     }
  2088.       else if (cc_prev_status.flags & CC_NO_OVERFLOW)
  2089.     {
  2090.       if (parity)
  2091.         output_asm_insn (\"b%U0,a %l1 ! eager\", xoperands);
  2092.       else
  2093.         output_asm_insn (\"b%I0,a %l1 ! eager\", xoperands);
  2094.     }
  2095.       else
  2096.     {
  2097.       if (parity)
  2098.         output_asm_insn (\"b%N0 %l1 ! eager\", xoperands);
  2099.       else
  2100.         output_asm_insn (\"b%C0 %l1 ! eager\", xoperands);
  2101.     }
  2102.     }
  2103.   return output_delay_insn (delay_insn);
  2104. }")
  2105.  
  2106. ;; Here are two simple peepholes which fill the delay slot of
  2107. ;; an unconditional branch.
  2108.  
  2109. (define_peephole
  2110.   [(set (match_operand:SI 0 "register_operand" "=r")
  2111.     (match_operand:SI 1 "single_insn_src_p" "p"))
  2112.    (set (pc) (label_ref (match_operand 2 "" "")))]
  2113.   "single_insn_extra_test (operands[0], operands[1])"
  2114.   "* return output_delayed_branch (\"b %l2\", operands, insn);")
  2115.  
  2116. (define_peephole
  2117.   [(set (match_operand:SI 0 "memory_operand" "=m")
  2118.     (match_operand:SI 1 "reg_or_0_operand" "rJ"))
  2119.    (set (pc) (label_ref (match_operand 2 "" "")))]
  2120.   ""
  2121.   "* return output_delayed_branch (\"b %l2\", operands, insn);")
  2122.  
  2123. (define_insn "tablejump"
  2124.   [(set (pc) (match_operand:SI 0 "register_operand" "r"))
  2125.    (use (label_ref (match_operand 1 "" "")))]
  2126.   ""
  2127.   "jmp %0\;nop")
  2128.  
  2129. (define_peephole
  2130.   [(set (match_operand:SI 0 "register_operand" "=r")
  2131.     (match_operand:SI 1 "single_insn_src_p" "p"))
  2132.    (parallel [(set (pc) (match_operand:SI 2 "register_operand" "r"))
  2133.           (use (label_ref (match_operand 3 "" "")))])]
  2134.   "REGNO (operands[0]) != REGNO (operands[2])
  2135.    && single_insn_extra_test (operands[0], operands[1])"
  2136.   "* return output_delayed_branch (\"jmp %2\", operands, insn);")
  2137.  
  2138. (define_peephole
  2139.   [(set (match_operand:SI 0 "memory_operand" "=m")
  2140.     (match_operand:SI 1 "reg_or_0_operand" "rJ"))
  2141.    (parallel [(set (pc) (match_operand:SI 2 "register_operand" "r"))
  2142.           (use (label_ref (match_operand 3 "" "")))])]
  2143.   ""
  2144.   "* return output_delayed_branch (\"jmp %2\", operands, insn);")
  2145.  
  2146. ;;- jump to subroutine
  2147. (define_expand "call"
  2148.   [(call (match_operand:SI 0 "memory_operand" "m")
  2149.      (match_operand 1 "" "i"))]
  2150.   ;; operand[2] is next_arg_register
  2151.   ""
  2152.   "
  2153. {
  2154.   rtx fn_rtx, nregs_rtx;
  2155.  
  2156.   if (TARGET_SUN_ASM && GET_CODE (XEXP (operands[0], 0)) == REG)
  2157.     {
  2158.       rtx g1_rtx = gen_rtx (REG, SImode, 1);
  2159.       emit_move_insn (g1_rtx, XEXP (operands[0], 0));
  2160.       fn_rtx = gen_rtx (MEM, SImode, g1_rtx);
  2161.     }
  2162.   else
  2163.     fn_rtx = operands[0];
  2164.  
  2165.   /* Count the number of parameter registers being used by this call.
  2166.      if that argument is NULL, it means we are using them all, which
  2167.      means 6 on the sparc.  */
  2168. #if 0
  2169.   if (operands[2])
  2170.     nregs_rtx = gen_rtx (CONST_INT, VOIDmode, REGNO (operands[2]) - 8);
  2171.   else
  2172.     nregs_rtx = gen_rtx (CONST_INT, VOIDmode, 6);
  2173. #else
  2174.   nregs_rtx = const0_rtx;
  2175. #endif
  2176.  
  2177.   emit_call_insn (gen_rtx (PARALLEL, VOIDmode, gen_rtvec (2,
  2178.                gen_rtx (CALL, VOIDmode, fn_rtx, nregs_rtx),
  2179.                gen_rtx (USE, VOIDmode, gen_rtx (REG, SImode, 31)))));
  2180.   DONE;
  2181. }")
  2182.  
  2183. (define_insn ""
  2184.   [(call (match_operand:SI 0 "memory_operand" "m")
  2185.      (match_operand 1 "" "i"))
  2186.    (use (reg:SI 31))]
  2187.   ;;- Don't use operand 1 for most machines.
  2188.   "CONSTANT_P (XEXP (operands[0], 0))
  2189.    || GET_CODE (XEXP (operands[0], 0)) == REG"
  2190.   "*
  2191. {
  2192.   /* strip the MEM.  */
  2193.   operands[0] = XEXP (operands[0], 0);
  2194.   CC_STATUS_INIT;
  2195.   if (TARGET_SUN_ASM && GET_CODE (operands[0]) == REG)
  2196.     return \"jmpl %a0,%%o7\;nop\";
  2197.   return \"call %a0,%1\;nop\";
  2198. }")
  2199.  
  2200. (define_peephole
  2201.   [(set (match_operand:SI 0 "register_operand" "=r")
  2202.     (match_operand:SI 1 "single_insn_src_p" "p"))
  2203.    (parallel [(call (match_operand:SI 2 "memory_operand" "m")
  2204.             (match_operand 3 "" "i"))
  2205.           (use (reg:SI 31))])]
  2206.   ;;- Don't use operand 1 for most machines.
  2207.   "! reg_mentioned_p (operands[0], operands[2])
  2208.    && single_insn_extra_test (operands[0], operands[1])"
  2209.   "*
  2210. {
  2211.   /* strip the MEM.  */
  2212.   operands[2] = XEXP (operands[2], 0);
  2213.   if (TARGET_SUN_ASM && GET_CODE (operands[2]) == REG)
  2214.     return output_delayed_branch (\"jmpl %a2,%%o7\", operands, insn);
  2215.   return output_delayed_branch (\"call %a2,%3\", operands, insn);
  2216. }")
  2217.  
  2218. (define_peephole
  2219.   [(set (match_operand:SI 0 "memory_operand" "=m")
  2220.     (match_operand:SI 1 "reg_or_0_operand" "rJ"))
  2221.    (parallel [(call (match_operand:SI 2 "memory_operand" "m")
  2222.             (match_operand 3 "" "i"))
  2223.           (use (reg:SI 31))])]
  2224.   ;;- Don't use operand 1 for most machines.
  2225.   ""
  2226.   "*
  2227. {
  2228.   /* strip the MEM.  */
  2229.   operands[2] = XEXP (operands[2], 0);
  2230.   if (TARGET_SUN_ASM && GET_CODE (operands[2]) == REG)
  2231.     return output_delayed_branch (\"jmpl %a2,%%o7\", operands, insn);
  2232.   return output_delayed_branch (\"call %a2,%3\", operands, insn);
  2233. }")
  2234.  
  2235. (define_expand "call_value"
  2236.   [(set (match_operand 0 "register_operand" "=rf")
  2237.     (call (match_operand:SI 1 "memory_operand" "m")
  2238.           (match_operand 2 "" "i")))]
  2239.   ;; operand 3 is next_arg_register
  2240.   ""
  2241.   "
  2242. {
  2243.   rtx fn_rtx, nregs_rtx;
  2244.   rtvec vec;
  2245.  
  2246.   if (TARGET_SUN_ASM && GET_CODE (XEXP (operands[1], 0)) == REG)
  2247.     {
  2248.       rtx g1_rtx = gen_rtx (REG, SImode, 1);
  2249.       emit_move_insn (g1_rtx, XEXP (operands[1], 0));
  2250.       fn_rtx = gen_rtx (MEM, SImode, g1_rtx);
  2251.     }
  2252.   else
  2253.     fn_rtx = operands[1];
  2254.  
  2255. #if 0
  2256.   if (operands[3])
  2257.     nregs_rtx = gen_rtx (CONST_INT, VOIDmode, REGNO (operands[3]) - 8);
  2258.   else
  2259.     nregs_rtx = gen_rtx (CONST_INT, VOIDmode, 6);
  2260. #else
  2261.   nregs_rtx = const0_rtx;
  2262. #endif
  2263.  
  2264.   vec = gen_rtvec (2,
  2265.            gen_rtx (SET, VOIDmode, operands[0],
  2266.                 gen_rtx (CALL, VOIDmode, fn_rtx, nregs_rtx)),
  2267.            gen_rtx (USE, VOIDmode, gen_rtx (REG, SImode, 31)));
  2268.  
  2269.   emit_call_insn (gen_rtx (PARALLEL, VOIDmode, vec));
  2270.   DONE;
  2271. }")
  2272.  
  2273. (define_insn ""
  2274.   [(set (match_operand 0 "" "=rf")
  2275.     (call (match_operand:SI 1 "memory_operand" "m")
  2276.           (match_operand 2 "" "i")))
  2277.    (use (reg:SI 31))]
  2278.   ;;- Don't use operand 2 for most machines.
  2279.   "CONSTANT_P (XEXP (operands[1], 0))
  2280.    || GET_CODE (XEXP (operands[1], 0)) == REG"
  2281.   "*
  2282. {
  2283.   /* strip the MEM.  */
  2284.   operands[1] = XEXP (operands[1], 0);
  2285.   CC_STATUS_INIT;
  2286.   if (TARGET_SUN_ASM && GET_CODE (operands[1]) == REG)
  2287.     return \"jmpl %a1,%%o7\;nop\";
  2288.   return \"call %a1,%2\;nop\";
  2289. }")
  2290.  
  2291. (define_peephole
  2292.   [(set (match_operand:SI 0 "register_operand" "=r")
  2293.     (match_operand:SI 1 "single_insn_src_p" "p"))
  2294.    (parallel [(set (match_operand 2 "" "=rf")
  2295.            (call (match_operand:SI 3 "memory_operand" "m")
  2296.              (match_operand 4 "" "i")))
  2297.           (use (reg:SI 31))])]
  2298.   ;;- Don't use operand 4 for most machines.
  2299.   "! reg_mentioned_p (operands[0], operands[3])
  2300.    && single_insn_extra_test (operands[0], operands[1])"
  2301.   "*
  2302. {
  2303.   /* strip the MEM.  */
  2304.   operands[3] = XEXP (operands[3], 0);
  2305.   if (TARGET_SUN_ASM && GET_CODE (operands[3]) == REG)
  2306.     return output_delayed_branch (\"jmpl %a3,%%o7\", operands, insn);
  2307.   return output_delayed_branch (\"call %a3,%4\", operands, insn);
  2308. }")
  2309.  
  2310. (define_peephole
  2311.   [(set (match_operand:SI 0 "memory_operand" "=m")
  2312.     (match_operand:SI 1 "reg_or_0_operand" "rJ"))
  2313.    (parallel [(set (match_operand 2 "" "=rf")
  2314.            (call (match_operand:SI 3 "memory_operand" "m")
  2315.              (match_operand 4 "" "i")))
  2316.           (use (reg:SI 31))])]
  2317.   ;;- Don't use operand 4 for most machines.
  2318.   ""
  2319.   "*
  2320. {
  2321.   /* strip the MEM.  */
  2322.   operands[3] = XEXP (operands[3], 0);
  2323.   if (TARGET_SUN_ASM && GET_CODE (operands[3]) == REG)
  2324.     return output_delayed_branch (\"jmpl %a3,%%o7\", operands, insn);
  2325.   return output_delayed_branch (\"call %a3,%4\", operands, insn);
  2326. }")
  2327.  
  2328. (define_insn "return"
  2329.   [(return)]
  2330.   "! TARGET_EPILOGUE"
  2331.   "ret\;restore")
  2332.  
  2333. (define_peephole
  2334.   [(set (reg:SI 24)
  2335.     (match_operand:SI 0 "reg_or_0_operand" "rJ"))
  2336.    (return)]
  2337.   "! TARGET_EPILOGUE"
  2338.   "ret\;restore %r0,0x0,%%o0")
  2339.  
  2340. (define_peephole
  2341.   [(set (reg:SI 24)
  2342.     (plus:SI (match_operand:SI 0 "register_operand" "r%")
  2343.          (match_operand:SI 1 "arith_operand" "rI")))
  2344.    (return)]
  2345.   "! TARGET_EPILOGUE"
  2346.   "ret\;restore %r0,%1,%%o0")
  2347.  
  2348. (define_peephole
  2349.   [(set (reg:SI 24)
  2350.     (minus:SI (match_operand:SI 0 "register_operand" "r")
  2351.           (match_operand:SI 1 "small_int" "I")))
  2352.    (return)]
  2353.   "! TARGET_EPILOGUE"
  2354.   "ret\;restore %0,-(%1),%%o0")
  2355.  
  2356. (define_insn "nop"
  2357.   [(const_int 0)]
  2358.   ""
  2359.   "nop")
  2360.  
  2361. ;;- Local variables:
  2362. ;;- mode:emacs-lisp
  2363. ;;- comment-start: ";;- "
  2364. ;;- eval: (set-syntax-table (copy-sequence (syntax-table)))
  2365. ;;- eval: (modify-syntax-entry ?[ "(]")
  2366. ;;- eval: (modify-syntax-entry ?] ")[")
  2367. ;;- eval: (modify-syntax-entry ?{ "(}")
  2368. ;;- eval: (modify-syntax-entry ?} "){")
  2369. ;;- End:
  2370.  
  2371.