home *** CD-ROM | disk | FTP | other *** search
/ NeXTSTEP 3.3 (Developer) / NeXT_Developer-3.3.iso / NextDeveloper / Source / GNU / cc / config / i386 / i386.md < prev    next >
Encoding:
Text File  |  1994-12-18  |  143.9 KB  |  5,454 lines

  1. ;; GCC machine description for Intel 80386.
  2. ;; Copyright (C) 1988 Free Software Foundation, Inc.
  3. ;; Mostly by William Schelter.
  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. ;; Attribute specifications
  23.  
  24. ;; Classify each instruction as to the precision control it requires.
  25. (define_attr "fppc" "none,single,double,conflict" (const_string "none"))
  26.  
  27. ;; The original PO technology requires these to be ordered by speed,
  28. ;; so that assigner will pick the fastest.
  29.  
  30. ;; See file "rtl.def" for documentation on define_insn, match_*, et. al.
  31.  
  32. ;; Macro #define NOTICE_UPDATE_CC in file i386.h handles condition code
  33. ;; updates for most instructions.
  34.  
  35. ;; Macro REG_CLASS_FROM_LETTER in file i386.h defines the register
  36. ;; constraint letters.
  37.  
  38. ;; the special asm out single letter directives following a '%' are:
  39. ;; 'z' mov%z1 would be movl, movw, or movb depending on the mode of
  40. ;;     operands[1].
  41. ;; 'L' Print the opcode suffix for a 32-bit integer opcode.
  42. ;; 'W' Print the opcode suffix for a 16-bit integer opcode.
  43. ;; 'B' Print the opcode suffix for an 8-bit integer opcode.
  44. ;; 'S' Print the opcode suffix for a 32-bit float opcode.
  45. ;; 'Q' Print the opcode suffix for a 64-bit float opcode.
  46.  
  47. ;; 'b' Print the QImode name of the register for the indicated operand.
  48. ;;     %b0 would print %al if operands[0] is reg 0.
  49. ;; 'w' Likewise, print the HImode name of the register.
  50. ;; 'k' Likewise, print the SImode name of the register.
  51. ;; 'h' Print the QImode name for a "high" register, either ah, bh, ch or dh.
  52. ;; 'y' Print "st(0)" instead of "st" as a register.
  53. ;; 'T' Print the opcode suffix for an 80-bit extended real XFmode float opcode.
  54.  
  55. ;; UNSPEC usage:
  56. ;; 0  This is a `scas' operation.  The mode of the UNSPEC is always SImode.
  57. ;;    operand 0 is the memory address to scan.
  58. ;;    operand 1 is a register containing the value to scan for.  The mode
  59. ;;       of the scas opcode will be the same as the mode of this operand.
  60. ;;    operand 2 is the known alignment of operand 0.
  61. ;; 1  This is a `sin' operation.  The mode of the UNSPEC is MODE_FLOAT.
  62. ;;    operand 0 is the argument for `sin'.
  63. ;; 2  This is a `cos' operation.  The mode of the UNSPEC is MODE_FLOAT.
  64. ;;    operand 0 is the argument for `cos'.
  65.  
  66. ;; "movl MEM,REG / testl REG,REG" is faster on a 486 than "cmpl $0,MEM".
  67. ;; But restricting MEM here would mean that gcc could not remove a redundant
  68. ;; test in cases like "incl MEM / je TARGET".
  69. ;;
  70. ;; We don't want to allow a constant operand for test insns because
  71. ;; (set (cc0) (const_int foo)) has no mode information.  Such insns will
  72. ;; be folded while optimizing anyway.
  73.  
  74. ;; All test insns have expanders that save the operands away without
  75. ;; actually generating RTL.  The bCOND or sCOND (emitted immediately
  76. ;; after the tstM or cmp) will actually emit the tstM or cmpM.
  77.  
  78. (define_insn "tstsi_1"
  79.   [(set (cc0)
  80.     (match_operand:SI 0 "nonimmediate_operand" "rm"))]
  81.   ""
  82.   "*
  83. {
  84.   if (REG_P (operands[0]))
  85.     return AS2 (test%L0,%0,%0);
  86.  
  87.   operands[1] = const0_rtx;
  88.   return AS2 (cmp%L0,%1,%0);
  89. }")
  90.  
  91. (define_expand "tstsi"
  92.   [(set (cc0)
  93.     (match_operand:SI 0 "nonimmediate_operand" ""))]
  94.   ""
  95.   "
  96. {
  97.   i386_compare_gen = gen_tstsi_1;
  98.   i386_compare_op0 = operands[0];
  99.   DONE;
  100. }")
  101.  
  102. (define_insn "tsthi_1"
  103.   [(set (cc0)
  104.     (match_operand:HI 0 "nonimmediate_operand" "rm"))]
  105.   ""
  106.   "*
  107. {
  108.   if (REG_P (operands[0]))
  109.     return AS2 (test%W0,%0,%0);
  110.  
  111.   operands[1] = const0_rtx;
  112.   return AS2 (cmp%W0,%1,%0);
  113. }")
  114.  
  115. (define_expand "tsthi"
  116.   [(set (cc0)
  117.     (match_operand:HI 0 "nonimmediate_operand" ""))]
  118.   ""
  119.   "
  120. {
  121.   i386_compare_gen = gen_tsthi_1;
  122.   i386_compare_op0 = operands[0];
  123.   DONE;
  124. }")
  125.  
  126. (define_insn "tstqi_1"
  127.   [(set (cc0)
  128.     (match_operand:QI 0 "nonimmediate_operand" "qm"))]
  129.   ""
  130.   "*
  131. {
  132.   if (REG_P (operands[0]))
  133.     return AS2 (test%B0,%0,%0);
  134.  
  135.   operands[1] = const0_rtx;
  136.   return AS2 (cmp%B0,%1,%0);
  137. }")
  138.  
  139. (define_expand "tstqi"
  140.   [(set (cc0)
  141.     (match_operand:QI 0 "nonimmediate_operand" ""))]
  142.   ""
  143.   "
  144. {
  145.   i386_compare_gen = gen_tstqi_1;
  146.   i386_compare_op0 = operands[0];
  147.   DONE;
  148. }")
  149.  
  150. (define_insn "tstsf_cc"
  151.   [(set (cc0)
  152.     (match_operand:SF 0 "register_operand" "f"))
  153.    (clobber (match_scratch:HI 1 "=a"))]
  154.   "TARGET_80387 && ! TARGET_IEEE_FP"
  155.   "*
  156. {
  157.   if (! STACK_TOP_P (operands[0]))
  158.     abort ();
  159.  
  160.   output_asm_insn (\"ftst\", operands);
  161.  
  162.   if (find_regno_note (insn, REG_DEAD, FIRST_STACK_REG))
  163.     output_asm_insn (AS1 (fstp,%y0), operands);
  164.  
  165.   return (char *) output_fp_cc0_set (insn);
  166. }")
  167.  
  168. ;; Don't generate tstsf if generating IEEE code, since the `ftst' opcode
  169. ;; isn't IEEE compliant.
  170.  
  171. (define_expand "tstsf"
  172.   [(parallel [(set (cc0)
  173.            (match_operand:SF 0 "register_operand" ""))
  174.           (clobber (match_scratch:HI 1 ""))])]
  175.   "TARGET_80387 && ! TARGET_IEEE_FP"
  176.   "
  177. {
  178.   i386_compare_gen = gen_tstsf_cc;
  179.   i386_compare_op0 = operands[0];
  180.   DONE;
  181. }")
  182.  
  183. (define_insn "tstdf_cc"
  184.   [(set (cc0)
  185.     (match_operand:DF 0 "register_operand" "f"))
  186.    (clobber (match_scratch:HI 1 "=a"))]
  187.   "TARGET_80387 && ! TARGET_IEEE_FP"
  188.   "*
  189. {
  190.   if (! STACK_TOP_P (operands[0]))
  191.     abort ();
  192.  
  193.   output_asm_insn (\"ftst\", operands);
  194.  
  195.   if (find_regno_note (insn, REG_DEAD, FIRST_STACK_REG))
  196.     output_asm_insn (AS1 (fstp,%y0), operands);
  197.  
  198.   return (char *) output_fp_cc0_set (insn);
  199. }")
  200.  
  201. ;; Don't generate tstdf if generating IEEE code, since the `ftst' opcode
  202. ;; isn't IEEE compliant.
  203.  
  204. (define_expand "tstdf"
  205.   [(parallel [(set (cc0)
  206.            (match_operand:DF 0 "register_operand" ""))
  207.           (clobber (match_scratch:HI 1 ""))])]
  208.   "TARGET_80387 && ! TARGET_IEEE_FP"
  209.   "
  210. {
  211.   i386_compare_gen = gen_tstdf_cc;
  212.   i386_compare_op0 = operands[0];
  213.   DONE;
  214. }")
  215.  
  216. (define_insn "tstxf_cc"
  217.   [(set (cc0)
  218.     (match_operand:XF 0 "register_operand" "f"))
  219.    (clobber (match_scratch:HI 1 "=a"))]
  220.   "TARGET_80387 && ! TARGET_IEEE_FP"
  221.   "*
  222. {
  223.   if (! STACK_TOP_P (operands[0]))
  224.     abort ();
  225.  
  226.   output_asm_insn (\"ftst\", operands);
  227.  
  228.   if (find_regno_note (insn, REG_DEAD, FIRST_STACK_REG))
  229.     output_asm_insn (AS1 (fstp,%y0), operands);
  230.  
  231.   return (char *) output_fp_cc0_set (insn);
  232. }")
  233.  
  234. ;; Don't generate tstdf if generating IEEE code, since the `ftst' opcode
  235. ;; isn't IEEE compliant.
  236.  
  237. (define_expand "tstxf"
  238.   [(parallel [(set (cc0)
  239.            (match_operand:XF 0 "register_operand" ""))
  240.           (clobber (match_scratch:HI 1 ""))])]
  241.   "TARGET_80387 && ! TARGET_IEEE_FP"
  242.   "
  243. {
  244.   i386_compare_gen = gen_tstxf_cc;
  245.   i386_compare_op0 = operands[0];
  246.   DONE;
  247. }")
  248.  
  249. ;;- compare instructions.  See comments above tstM patterns about
  250. ;;  expansion of these insns.
  251.  
  252. (define_insn "cmpsi_1"
  253.   [(set (cc0)
  254.     (compare (match_operand:SI 0 "nonimmediate_operand" "mr,r")
  255.          (match_operand:SI 1 "general_operand" "ri,mr")))]
  256.   "GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM"
  257.   "*
  258. {
  259.   if (CONSTANT_P (operands[0]) || GET_CODE (operands[1]) == MEM)
  260.     {
  261.       cc_status.flags |= CC_REVERSED;
  262.       return AS2 (cmp%L0,%0,%1);
  263.     }
  264.   return AS2 (cmp%L0,%1,%0);
  265. }")
  266.  
  267. (define_expand "cmpsi"
  268.   [(set (cc0)
  269.     (compare (match_operand:SI 0 "nonimmediate_operand" "")
  270.          (match_operand:SI 1 "general_operand" "")))]
  271.   ""
  272.   "
  273. {
  274.   if (GET_CODE (operands[0]) == MEM && GET_CODE (operands[1]) == MEM)
  275.     operands[0] = force_reg (SImode, operands[0]);
  276.  
  277.   i386_compare_gen = gen_cmpsi_1;
  278.   i386_compare_op0 = operands[0];
  279.   i386_compare_op1 = operands[1];
  280.   DONE;
  281. }")
  282.  
  283. (define_insn "cmphi_1"
  284.   [(set (cc0)
  285.     (compare (match_operand:HI 0 "nonimmediate_operand" "mr,r")
  286.          (match_operand:HI 1 "general_operand" "ri,mr")))]
  287.   "GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM"
  288.   "*
  289. {
  290.   if (CONSTANT_P (operands[0]) || GET_CODE (operands[1]) == MEM)
  291.     {
  292.       cc_status.flags |= CC_REVERSED;
  293.       return AS2 (cmp%W0,%0,%1);
  294.     }
  295.   return AS2 (cmp%W0,%1,%0);
  296. }")
  297.  
  298. (define_expand "cmphi"
  299.   [(set (cc0)
  300.     (compare (match_operand:HI 0 "nonimmediate_operand" "")
  301.          (match_operand:HI 1 "general_operand" "")))]
  302.   ""
  303.   "
  304. {
  305.   if (GET_CODE (operands[0]) == MEM && GET_CODE (operands[1]) == MEM)
  306.     operands[0] = force_reg (HImode, operands[0]);
  307.  
  308.   i386_compare_gen = gen_cmphi_1;
  309.   i386_compare_op0 = operands[0];
  310.   i386_compare_op1 = operands[1];
  311.   DONE;
  312. }")
  313.  
  314. (define_insn "cmpqi_1"
  315.   [(set (cc0)
  316.     (compare (match_operand:QI 0 "nonimmediate_operand" "q,mq")
  317.          (match_operand:QI 1 "general_operand" "qm,nq")))]
  318.   "GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM"
  319.   "*
  320. {
  321.   if (CONSTANT_P (operands[0]) || GET_CODE (operands[1]) == MEM)
  322.     {
  323.       cc_status.flags |= CC_REVERSED;
  324.       return AS2 (cmp%B0,%0,%1);
  325.     }
  326.   return AS2 (cmp%B0,%1,%0);
  327. }")
  328.  
  329. (define_expand "cmpqi"
  330.   [(set (cc0)
  331.     (compare (match_operand:QI 0 "nonimmediate_operand" "")
  332.          (match_operand:QI 1 "general_operand" "")))]
  333.   ""
  334.   "
  335. {
  336.   if (GET_CODE (operands[0]) == MEM && GET_CODE (operands[1]) == MEM)
  337.     operands[0] = force_reg (QImode, operands[0]);
  338.  
  339.   i386_compare_gen = gen_cmpqi_1;
  340.   i386_compare_op0 = operands[0];
  341.   i386_compare_op1 = operands[1];
  342.   DONE;
  343. }")
  344.  
  345. ;; These implement float point compares.  For each of DFmode and
  346. ;; SFmode, there is the normal insn, and an insn where the second operand
  347. ;; is converted to the desired mode.
  348.  
  349. (define_insn ""
  350.   [(set (cc0)
  351.     (match_operator 2 "VOIDmode_compare_op"
  352.             [(match_operand:XF 0 "nonimmediate_operand" "f")
  353.              (match_operand:XF 1 "nonimmediate_operand" "f")]))
  354.    (clobber (match_scratch:HI 3 "=a"))]
  355.   "TARGET_80387
  356.    && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
  357.   "* return (char *) output_float_compare (insn, operands);"
  358.   [(set_attr "fppc" "conflict")])
  359.  
  360. (define_insn ""
  361.   [(set (cc0)
  362.     (match_operator 2 "VOIDmode_compare_op"
  363.             [(match_operand:XF 0 "register_operand" "f")
  364.              (float:XF
  365.               (match_operand:SI 1 "nonimmediate_operand" "rm"))]))
  366.    (clobber (match_scratch:HI 3 "=a"))]
  367.   "TARGET_80387"
  368.   "* return (char *) output_float_compare (insn, operands);"
  369.   [(set_attr "fppc" "conflict")])
  370.  
  371. (define_insn ""
  372.   [(set (cc0)
  373.     (match_operator 2 "VOIDmode_compare_op"
  374.             [(float:XF
  375.               (match_operand:SI 0 "nonimmediate_operand" "rm"))
  376.              (match_operand:XF 1 "register_operand" "f")]))
  377.    (clobber (match_scratch:HI 3 "=a"))]
  378.   "TARGET_80387"
  379.   "* return (char *) output_float_compare (insn, operands);"
  380.   [(set_attr "fppc" "conflict")])
  381.  
  382. (define_insn ""
  383.   [(set (cc0)
  384.     (match_operator 2 "VOIDmode_compare_op"
  385.             [(match_operand:XF 0 "register_operand" "f")
  386.              (float_extend:XF
  387.               (match_operand:DF 1 "nonimmediate_operand" "fm"))]))
  388.    (clobber (match_scratch:HI 3 "=a"))]
  389.   "TARGET_80387"
  390.   "* return (char *) output_float_compare (insn, operands);"
  391.   [(set_attr "fppc" "conflict")])
  392.  
  393. (define_insn ""
  394.   [(set (cc0)
  395.     (match_operator 2 "VOIDmode_compare_op"
  396.             [(match_operand:XF 0 "register_operand" "f")
  397.              (float_extend:XF
  398.               (match_operand:SF 1 "nonimmediate_operand" "fm"))]))
  399.    (clobber (match_scratch:HI 3 "=a"))]
  400.   "TARGET_80387"
  401.   "* return (char *) output_float_compare (insn, operands);"
  402.   [(set_attr "fppc" "conflict")])
  403.  
  404. (define_insn ""
  405.   [(set (cc0)
  406.     (compare:CCFPEQ (match_operand:XF 0 "register_operand" "f")
  407.             (match_operand:XF 1 "register_operand" "f")))
  408.    (clobber (match_scratch:HI 2 "=a"))]
  409.   "TARGET_80387"
  410.   "* return (char *) output_float_compare (insn, operands);"
  411.   [(set_attr "fppc" "conflict")])
  412.  
  413. (define_insn ""
  414.   [(set (cc0)
  415.     (match_operator 2 "VOIDmode_compare_op"
  416.             [(match_operand:DF 0 "nonimmediate_operand" "f,fm")
  417.              (match_operand:DF 1 "nonimmediate_operand" "fm,f")]))
  418.    (clobber (match_scratch:HI 3 "=a,a"))]
  419.   "TARGET_80387
  420.    && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
  421.   "* return (char *) output_float_compare (insn, operands);")
  422.  
  423. (define_insn ""
  424.   [(set (cc0)
  425.     (match_operator 2 "VOIDmode_compare_op"
  426.             [(match_operand:DF 0 "register_operand" "f")
  427.              (float:DF
  428.               (match_operand:SI 1 "nonimmediate_operand" "rm"))]))
  429.    (clobber (match_scratch:HI 3 "=a"))]
  430.   "TARGET_80387"
  431.   "* return (char *) output_float_compare (insn, operands);")
  432.  
  433. (define_insn ""
  434.   [(set (cc0)
  435.     (match_operator 2 "VOIDmode_compare_op"
  436.             [(float:DF
  437.               (match_operand:SI 0 "nonimmediate_operand" "rm"))
  438.              (match_operand:DF 1 "register_operand" "f")]))
  439.    (clobber (match_scratch:HI 3 "=a"))]
  440.   "TARGET_80387"
  441.   "* return (char *) output_float_compare (insn, operands);"
  442.   [(set_attr "fppc" "conflict")])
  443.  
  444. (define_insn ""
  445.   [(set (cc0)
  446.     (match_operator 2 "VOIDmode_compare_op"
  447.             [(match_operand:DF 0 "register_operand" "f")
  448.              (float_extend:DF
  449.               (match_operand:SF 1 "nonimmediate_operand" "fm"))]))
  450.    (clobber (match_scratch:HI 3 "=a"))]
  451.   "TARGET_80387"
  452.   "* return (char *) output_float_compare (insn, operands);")
  453.  
  454. (define_insn ""
  455.   [(set (cc0)
  456.     (match_operator 2 "VOIDmode_compare_op"
  457.             [(float_extend:DF
  458.               (match_operand:SF 0 "nonimmediate_operand" "fm"))
  459.              (match_operand:DF 1 "register_operand" "f")]))
  460.    (clobber (match_scratch:HI 3 "=a"))]
  461.   "TARGET_80387"
  462.   "* return (char *) output_float_compare (insn, operands);")
  463.  
  464. (define_insn ""
  465.   [(set (cc0)
  466.     (compare:CCFPEQ (match_operand:DF 0 "register_operand" "f")
  467.             (match_operand:DF 1 "register_operand" "f")))
  468.    (clobber (match_scratch:HI 2 "=a"))]
  469.   "TARGET_80387"
  470.   "* return (char *) output_float_compare (insn, operands);")
  471.  
  472. ;; These two insns will never be generated by combine due to the mode of
  473. ;; the COMPARE.
  474. ;(define_insn ""
  475. ;  [(set (cc0)
  476. ;    (compare:CCFPEQ (match_operand:DF 0 "register_operand" "f")
  477. ;            (float_extend:DF
  478. ;             (match_operand:SF 1 "register_operand" "f"))))
  479. ;   (clobber (match_scratch:HI 2 "=a"))]
  480. ;  "TARGET_80387"
  481. ;  "* return (char *) output_float_compare (insn, operands);")
  482. ;
  483. ;(define_insn ""
  484. ;  [(set (cc0)
  485. ;    (compare:CCFPEQ (float_extend:DF
  486. ;             (match_operand:SF 0 "register_operand" "f"))
  487. ;            (match_operand:DF 1 "register_operand" "f")))
  488. ;   (clobber (match_scratch:HI 2 "=a"))]
  489. ;  "TARGET_80387"
  490. ;  "* return (char *) output_float_compare (insn, operands);")
  491.  
  492. (define_insn "cmpsf_cc_1"
  493.   [(set (cc0)
  494.     (match_operator 2 "VOIDmode_compare_op"
  495.             [(match_operand:SF 0 "nonimmediate_operand" "f,fm")
  496.              (match_operand:SF 1 "nonimmediate_operand" "fm,f")]))
  497.    (clobber (match_scratch:HI 3 "=a,a"))]
  498.   "TARGET_80387
  499.    && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
  500.   "* return (char *) output_float_compare (insn, operands);")
  501.  
  502. (define_insn ""
  503.   [(set (cc0)
  504.     (match_operator 2 "VOIDmode_compare_op"
  505.             [(match_operand:SF 0 "register_operand" "f")
  506.              (float:SF
  507.               (match_operand:SI 1 "nonimmediate_operand" "rm"))]))
  508.    (clobber (match_scratch:HI 3 "=a"))]
  509.   "TARGET_80387"
  510.   "* return (char *) output_float_compare (insn, operands);")
  511.  
  512. (define_insn ""
  513.   [(set (cc0)
  514.     (match_operator 2 "VOIDmode_compare_op"
  515.             [(float:SF
  516.               (match_operand:SI 0 "nonimmediate_operand" "rm"))
  517.              (match_operand:SF 1 "register_operand" "f")]))
  518.    (clobber (match_scratch:HI 3 "=a"))]
  519.   "TARGET_80387"
  520.   "* return (char *) output_float_compare (insn, operands);"
  521.   [(set_attr "fppc" "none")])
  522.  
  523. (define_insn ""
  524.   [(set (cc0)
  525.     (compare:CCFPEQ (match_operand:SF 0 "register_operand" "f")
  526.             (match_operand:SF 1 "register_operand" "f")))
  527.    (clobber (match_scratch:HI 2 "=a"))]
  528.   "TARGET_80387"
  529.   "* return (char *) output_float_compare (insn, operands);")
  530.  
  531. (define_expand "cmpxf"
  532.   [(set (cc0)
  533.     (compare (match_operand:XF 0 "register_operand" "")
  534.          (match_operand:XF 1 "nonimmediate_operand" "")))]
  535.   "TARGET_80387"
  536.   "
  537. {
  538.   i386_compare_gen = gen_cmpxf_cc;
  539.   i386_compare_gen_eq = gen_cmpxf_ccfpeq;
  540.   i386_compare_op0 = operands[0];
  541.   i386_compare_op1 = operands[1];
  542.   DONE;
  543. }")
  544.  
  545. (define_expand "cmpdf"
  546.   [(set (cc0)
  547.     (compare (match_operand:DF 0 "register_operand" "")
  548.          (match_operand:DF 1 "nonimmediate_operand" "")))]
  549.   "TARGET_80387"
  550.   "
  551. {
  552.   i386_compare_gen = gen_cmpdf_cc;
  553.   i386_compare_gen_eq = gen_cmpdf_ccfpeq;
  554.   i386_compare_op0 = operands[0];
  555.   i386_compare_op1 = operands[1];
  556.   DONE;
  557. }")
  558.  
  559. (define_expand "cmpsf"
  560.   [(set (cc0)
  561.     (compare (match_operand:SF 0 "register_operand" "")
  562.          (match_operand:SF 1 "nonimmediate_operand" "")))]
  563.   "TARGET_80387"
  564.   "
  565. {
  566.   i386_compare_gen = gen_cmpsf_cc;
  567.   i386_compare_gen_eq = gen_cmpsf_ccfpeq;
  568.   i386_compare_op0 = operands[0];
  569.   i386_compare_op1 = operands[1];
  570.   DONE;
  571. }")
  572.  
  573. (define_expand "cmpxf_cc"
  574.   [(parallel [(set (cc0)
  575.            (compare (match_operand:XF 0 "register_operand" "")
  576.                 (match_operand:XF 1 "register_operand" "")))
  577.           (clobber (match_scratch:HI 2 ""))])]
  578.   "TARGET_80387"
  579.   "")
  580.  
  581. (define_expand "cmpxf_ccfpeq"
  582.   [(parallel [(set (cc0)
  583.            (compare:CCFPEQ (match_operand:XF 0 "register_operand" "")
  584.                    (match_operand:XF 1 "register_operand" "")))
  585.           (clobber (match_scratch:HI 2 ""))])]
  586.   "TARGET_80387"
  587.   "
  588. {
  589.   if (! register_operand (operands[1], XFmode))
  590.     operands[1] = copy_to_mode_reg (XFmode, operands[1]);
  591. }")
  592.  
  593. (define_expand "cmpdf_cc"
  594.   [(parallel [(set (cc0)
  595.            (compare (match_operand:DF 0 "register_operand" "")
  596.                 (match_operand:DF 1 "register_operand" "")))
  597.           (clobber (match_scratch:HI 2 ""))])]
  598.   "TARGET_80387"
  599.   "")
  600.  
  601. (define_expand "cmpdf_ccfpeq"
  602.   [(parallel [(set (cc0)
  603.            (compare:CCFPEQ (match_operand:DF 0 "register_operand" "")
  604.                    (match_operand:DF 1 "register_operand" "")))
  605.           (clobber (match_scratch:HI 2 ""))])]
  606.   "TARGET_80387"
  607.   "
  608. {
  609.   if (! register_operand (operands[1], DFmode))
  610.     operands[1] = copy_to_mode_reg (DFmode, operands[1]);
  611. }")
  612.  
  613. (define_expand "cmpsf_cc"
  614.   [(parallel [(set (cc0)
  615.            (compare (match_operand:SF 0 "register_operand" "")
  616.                 (match_operand:SF 1 "register_operand" "")))
  617.           (clobber (match_scratch:HI 2 ""))])]
  618.   "TARGET_80387"
  619.   "")
  620.  
  621. (define_expand "cmpsf_ccfpeq"
  622.   [(parallel [(set (cc0)
  623.            (compare:CCFPEQ (match_operand:SF 0 "register_operand" "")
  624.                    (match_operand:SF 1 "register_operand" "")))
  625.           (clobber (match_scratch:HI 2 ""))])]
  626.   "TARGET_80387"
  627.   "
  628. {
  629.   if (! register_operand (operands[1], SFmode))
  630.     operands[1] = copy_to_mode_reg (SFmode, operands[1]);
  631. }")
  632.  
  633. ;; logical compare
  634.  
  635. (define_insn ""
  636.   [(set (cc0)
  637.     (and:SI (match_operand:SI 0 "general_operand" "%ro")
  638.         (match_operand:SI 1 "general_operand" "ri")))]
  639.   ""
  640.   "*
  641. {
  642.   /* For small integers, we may actually use testb. */
  643.   if (GET_CODE (operands[1]) == CONST_INT
  644.       && ! (GET_CODE (operands[0]) == MEM && MEM_VOLATILE_P (operands[0]))
  645.       && (! REG_P (operands[0]) || QI_REG_P (operands[0])))
  646.     {
  647.       /* We may set the sign bit spuriously.  */
  648.  
  649.       if ((INTVAL (operands[1]) & ~0xff) == 0)
  650.         {
  651.       cc_status.flags |= CC_NOT_NEGATIVE;
  652.       return AS2 (test%B0,%1,%b0);
  653.     }
  654.  
  655.       if ((INTVAL (operands[1]) & ~0xff00) == 0)
  656.         {
  657.       cc_status.flags |= CC_NOT_NEGATIVE;
  658.       operands[1] = GEN_INT (INTVAL (operands[1]) >> 8);
  659.  
  660.       if (QI_REG_P (operands[0]))
  661.         return AS2 (test%B0,%1,%h0);
  662.       else
  663.         {
  664.           operands[0] = adj_offsettable_operand (operands[0], 1);
  665.           return AS2 (test%B0,%1,%b0);
  666.         }
  667.     }
  668.  
  669.       if (GET_CODE (operands[0]) == MEM
  670.       && (INTVAL (operands[1]) & ~0xff0000) == 0)
  671.         {
  672.       cc_status.flags |= CC_NOT_NEGATIVE;
  673.       operands[1] = GEN_INT (INTVAL (operands[1]) >> 16);
  674.       operands[0] = adj_offsettable_operand (operands[0], 2);
  675.       return AS2 (test%B0,%1,%b0);
  676.     }
  677.  
  678.       if (GET_CODE (operands[0]) == MEM
  679.       && (INTVAL (operands[1]) & ~0xff000000) == 0)
  680.         {
  681.       operands[1] = GEN_INT ((INTVAL (operands[1]) >> 24) & 0xff);
  682.       operands[0] = adj_offsettable_operand (operands[0], 3);
  683.       return AS2 (test%B0,%1,%b0);
  684.     }
  685.     }
  686.  
  687.   if (CONSTANT_P (operands[1]) || GET_CODE (operands[0]) == MEM)
  688.     return AS2 (test%L0,%1,%0);
  689.  
  690.   return AS2 (test%L1,%0,%1);
  691. }")
  692.  
  693. (define_insn ""
  694.   [(set (cc0)
  695.     (and:HI (match_operand:HI 0 "general_operand" "%ro")
  696.         (match_operand:HI 1 "general_operand" "ri")))]
  697.   ""
  698.   "*
  699. {
  700.   if (GET_CODE (operands[1]) == CONST_INT
  701.       && ! (GET_CODE (operands[0]) == MEM && MEM_VOLATILE_P (operands[0]))
  702.       && (! REG_P (operands[0]) || QI_REG_P (operands[0])))
  703.     {
  704.       if ((INTVAL (operands[1]) & 0xff00) == 0)
  705.     {
  706.       /* ??? This might not be necessary. */
  707.       if (INTVAL (operands[1]) & 0xffff0000)
  708.         operands[1] = GEN_INT (INTVAL (operands[1]) & 0xff);
  709.  
  710.       /* We may set the sign bit spuriously.  */
  711.       cc_status.flags |= CC_NOT_NEGATIVE;
  712.       return AS2 (test%B0,%1,%b0);
  713.     }
  714.  
  715.       if ((INTVAL (operands[1]) & 0xff) == 0)
  716.         {
  717.       operands[1] = GEN_INT ((INTVAL (operands[1]) >> 8) & 0xff);
  718.  
  719.       if (QI_REG_P (operands[0]))
  720.         return AS2 (test%B0,%1,%h0);
  721.       else
  722.         {
  723.           operands[0] = adj_offsettable_operand (operands[0], 1);
  724.           return AS2 (test%B0,%1,%b0);
  725.         }
  726.     }
  727.     }
  728.  
  729.   if (CONSTANT_P (operands[1]) || GET_CODE (operands[0]) == MEM)
  730.     return AS2 (test%W0,%1,%0);
  731.  
  732.   return AS2 (test%W1,%0,%1);
  733. }")
  734.  
  735. (define_insn ""
  736.   [(set (cc0)
  737.     (and:QI (match_operand:QI 0 "general_operand" "%qm")
  738.         (match_operand:QI 1 "general_operand" "qi")))]
  739.   ""
  740.   "*
  741. {
  742.   if (CONSTANT_P (operands[1]) || GET_CODE (operands[0]) == MEM)
  743.     return AS2 (test%B0,%1,%0);
  744.  
  745.   return AS2 (test%B1,%0,%1);
  746. }")
  747.  
  748. ;; move instructions.
  749. ;; There is one for each machine mode,
  750. ;; and each is preceded by a corresponding push-insn pattern
  751. ;; (since pushes are not general_operands on the 386).
  752.  
  753. (define_insn ""
  754.   [(set (match_operand:SI 0 "push_operand" "=<")
  755.     (match_operand:SI 1 "general_operand" "g"))]
  756.   "! TARGET_486"
  757.   "push%L0 %1")
  758.  
  759. ;; On a 486, it is faster to move MEM to a REG and then push, rather than
  760. ;; push MEM directly.
  761.  
  762. (define_insn ""
  763.   [(set (match_operand:SI 0 "push_operand" "=<")
  764.     (match_operand:SI 1 "general_operand" "ri"))]
  765.   "TARGET_486"
  766.   "push%L0 %1")
  767.  
  768. ;; General case of fullword move.
  769.  
  770. ;; If generating PIC code and operands[1] is a symbolic CONST, emit a
  771. ;; move to get the address of the symbolic object from the GOT.
  772.  
  773. (define_expand "movsi"
  774.   [(set (match_operand:SI 0 "general_operand" "")
  775.     (match_operand:SI 1 "general_operand" ""))]
  776.   ""
  777.   "
  778. {
  779.   extern int flag_pic;
  780.  
  781.   if (flag_pic)
  782.     emit_pic_move (operands, SImode);
  783. }")
  784.  
  785. ;; On i486, incl reg is faster than movl $1,reg.
  786.  
  787. (define_insn ""
  788.   [(set (match_operand:SI 0 "general_operand" "=g,r")
  789.     (match_operand:SI 1 "general_operand" "ri,m"))]
  790.   ""
  791.   "*
  792. {
  793.   rtx link;
  794.   if (operands[1] == const0_rtx && REG_P (operands[0]))
  795.     return AS2 (xor%L0,%0,%0);
  796.  
  797.   if (operands[1] == const1_rtx
  798.       && (link = find_reg_note (insn, REG_WAS_0, 0))
  799.       /* Make sure the insn that stored the 0 is still present.  */
  800.       && ! INSN_DELETED_P (XEXP (link, 0))
  801.       && GET_CODE (XEXP (link, 0)) != NOTE
  802.       /* Make sure cross jumping didn't happen here.  */
  803.       && no_labels_between_p (XEXP (link, 0), insn)
  804.       /* Make sure the reg hasn't been clobbered.  */
  805.       && ! reg_set_between_p (operands[0], XEXP (link, 0), insn))
  806.     /* Fastest way to change a 0 to a 1.  */
  807.     return AS1 (inc%L0,%0);
  808.  
  809.   return AS2 (mov%L0,%1,%0);
  810. }")
  811.  
  812. (define_insn ""
  813.   [(set (match_operand:HI 0 "push_operand" "=<")
  814.     (match_operand:HI 1 "general_operand" "g"))]
  815.   ""
  816.   "push%W0 %1")
  817.  
  818. ;; On i486, an incl and movl are both faster than incw and movw.
  819.  
  820. (define_insn "movhi"
  821.   [(set (match_operand:HI 0 "general_operand" "=g,r")
  822.     (match_operand:HI 1 "general_operand" "ri,m"))]
  823.   ""
  824.   "*
  825. {
  826.   rtx link;
  827.   if (REG_P (operands[0]) && operands[1] == const0_rtx)
  828.     return AS2 (xor%L0,%k0,%k0);
  829.  
  830.   if (REG_P (operands[0]) && operands[1] == const1_rtx 
  831.       && (link = find_reg_note (insn, REG_WAS_0, 0))
  832.       /* Make sure the insn that stored the 0 is still present.  */
  833.       && ! INSN_DELETED_P (XEXP (link, 0))
  834.       && GET_CODE (XEXP (link, 0)) != NOTE
  835.       /* Make sure cross jumping didn't happen here.  */
  836.       && no_labels_between_p (XEXP (link, 0), insn)
  837.       /* Make sure the reg hasn't been clobbered.  */
  838.       && ! reg_set_between_p (operands[0], XEXP (link, 0), insn))
  839.     /* Fastest way to change a 0 to a 1.  */
  840.     return AS1 (inc%L0,%k0);
  841.  
  842.   if (REG_P (operands[0]))
  843.     {
  844.       if (REG_P (operands[1]))
  845.     return AS2 (mov%L0,%k1,%k0);
  846.       else if (CONSTANT_P (operands[1]))
  847.     return AS2 (mov%L0,%1,%k0);
  848.     }
  849.  
  850.   return AS2 (mov%W0,%1,%0);
  851. }")
  852.  
  853. (define_insn "movstricthi"
  854.   [(set (strict_low_part (match_operand:HI 0 "general_operand" "+g,r"))
  855.     (match_operand:HI 1 "general_operand" "ri,m"))]
  856.   ""
  857.   "*
  858. {
  859.   rtx link;
  860.   if (operands[1] == const0_rtx && REG_P (operands[0]))
  861.     return AS2 (xor%W0,%0,%0);
  862.  
  863.   if (operands[1] == const1_rtx
  864.       && (link = find_reg_note (insn, REG_WAS_0, 0))
  865.       /* Make sure the insn that stored the 0 is still present.  */
  866.       && ! INSN_DELETED_P (XEXP (link, 0))
  867.       && GET_CODE (XEXP (link, 0)) != NOTE
  868.       /* Make sure cross jumping didn't happen here.  */
  869.       && no_labels_between_p (XEXP (link, 0), insn)
  870.       /* Make sure the reg hasn't been clobbered.  */
  871.       && ! reg_set_between_p (operands[0], XEXP (link, 0), insn))
  872.     /* Fastest way to change a 0 to a 1.  */
  873.     return AS1 (inc%W0,%0);
  874.  
  875.   return AS2 (mov%W0,%1,%0);
  876. }")
  877.  
  878. ;; emit_push_insn when it calls move_by_pieces
  879. ;; requires an insn to "push a byte".
  880. ;; But actually we use pushw, which has the effect of rounding
  881. ;; the amount pushed up to a halfword.
  882. (define_insn ""
  883.   [(set (match_operand:QI 0 "push_operand" "=<")
  884.     (match_operand:QI 1 "general_operand" "q"))]
  885.   ""
  886.   "*
  887. {
  888.   operands[1] = gen_rtx (REG, HImode, REGNO (operands[1]));
  889.   return AS1 (push%W0,%1);
  890. }")
  891.  
  892. ;; On i486, incb reg is faster than movb $1,reg.
  893.  
  894. ;; ??? Do a recognizer for zero_extract that looks just like this, but reads
  895. ;; or writes %ah, %bh, %ch, %dh.
  896.  
  897. (define_insn "movqi"
  898.   [(set (match_operand:QI 0 "general_operand" "=q,*r,qm")
  899.     (match_operand:QI 1 "general_operand" "*g,q,qn"))]
  900.   ""
  901.   "*
  902. {
  903.   rtx link;
  904.   if (operands[1] == const0_rtx && REG_P (operands[0]))
  905.     return AS2 (xor%B0,%0,%0);
  906.  
  907.   if (operands[1] == const1_rtx
  908.       && (link = find_reg_note (insn, REG_WAS_0, 0))
  909.       /* Make sure the insn that stored the 0 is still present.  */
  910.       && ! INSN_DELETED_P (XEXP (link, 0))
  911.       && GET_CODE (XEXP (link, 0)) != NOTE
  912.       /* Make sure cross jumping didn't happen here.  */
  913.       && no_labels_between_p (XEXP (link, 0), insn)
  914.       /* Make sure the reg hasn't been clobbered.  */
  915.       && ! reg_set_between_p (operands[0], XEXP (link, 0), insn))
  916.     /* Fastest way to change a 0 to a 1.  */
  917.     return AS1 (inc%B0,%0);
  918.  
  919.   /* If mov%B0 isn't allowed for one of these regs, use mov%L0.  */
  920.   if (NON_QI_REG_P (operands[0]) || NON_QI_REG_P (operands[1]))
  921.     return (AS2 (mov%L0,%k1,%k0));
  922.  
  923.   return (AS2 (mov%B0,%1,%0));
  924. }")
  925.  
  926. ;; If it becomes necessary to support movstrictqi into %esi or %edi,
  927. ;; use the insn sequence:
  928. ;;
  929. ;;    shrdl $8,srcreg,dstreg
  930. ;;    rorl $24,dstreg
  931. ;;
  932. ;; If operands[1] is a constant, then an andl/orl sequence would be
  933. ;; faster.
  934.  
  935. (define_insn "movstrictqi"
  936.   [(set (strict_low_part (match_operand:QI 0 "general_operand" "+qm,q"))
  937.     (match_operand:QI 1 "general_operand" "*qn,m"))]
  938.   ""
  939.   "*
  940. {
  941.   rtx link;
  942.   if (operands[1] == const0_rtx && REG_P (operands[0]))
  943.     return AS2 (xor%B0,%0,%0);
  944.  
  945.   if (operands[1] == const1_rtx
  946.       && (link = find_reg_note (insn, REG_WAS_0, 0))
  947.       /* Make sure the insn that stored the 0 is still present.  */
  948.       && ! INSN_DELETED_P (XEXP (link, 0))
  949.       && GET_CODE (XEXP (link, 0)) != NOTE
  950.       /* Make sure cross jumping didn't happen here.  */
  951.       && no_labels_between_p (XEXP (link, 0), insn)
  952.       /* Make sure the reg hasn't been clobbered.  */
  953.       && ! reg_set_between_p (operands[0], XEXP (link, 0), insn))
  954.     /* Fastest way to change a 0 to a 1.  */
  955.     return AS1 (inc%B0,%0);
  956.  
  957.   /* If mov%B0 isn't allowed for one of these regs, use mov%L0.  */
  958.   if (NON_QI_REG_P (operands[0]) || NON_QI_REG_P (operands[1]))
  959.     {
  960.       abort ();
  961.       return (AS2 (mov%L0,%k1,%k0));
  962.     }
  963.  
  964.   return AS2 (mov%B0,%1,%0);
  965. }")
  966.  
  967. (define_insn ""
  968.   [(set (match_operand:SF 0 "push_operand" "=<,<")
  969.     (match_operand:SF 1 "general_operand" "gF,f"))]
  970.   ""
  971.   "*
  972. {
  973.   if (STACK_REG_P (operands[1]))
  974.     {
  975.       rtx xops[3];
  976.  
  977.       if (! STACK_TOP_P (operands[1]))
  978.         abort ();
  979.  
  980.       xops[0] = AT_SP (SFmode);
  981.       xops[1] = GEN_INT (4);
  982.       xops[2] = stack_pointer_rtx;
  983.  
  984.       output_asm_insn (AS2 (sub%L2,%1,%2), xops);
  985.  
  986.       if (find_regno_note (insn, REG_DEAD, FIRST_STACK_REG))
  987.         output_asm_insn (AS1 (fstp%S0,%0), xops);
  988.       else
  989.         output_asm_insn (AS1 (fst%S0,%0), xops);
  990.       RET;
  991.     }
  992.   return AS1 (push%L1,%1);
  993. }")
  994.  
  995. ;; Allow MEM-MEM moves before reload.  The reload class for such a
  996. ;; move will be ALL_REGS.  PREFERRED_RELOAD_CLASS will narrow this to
  997. ;; GENERAL_REGS.  For the purposes of regclass, prefer FLOAT_REGS.
  998.  
  999. (define_insn "movsf"
  1000.   [(set (match_operand:SF 0 "general_operand" "=*rfm,*rf,f,!*rm")
  1001.     (match_operand:SF 1 "general_operand" "*rf,*rfm,fG,fF"))]
  1002.   ""
  1003.   "*
  1004. {
  1005.   int stack_top_dies = find_regno_note (insn, REG_DEAD, FIRST_STACK_REG) != 0;
  1006.  
  1007.   /* First handle a `pop' insn or a `fld %st(0)' */
  1008.  
  1009.   if (STACK_TOP_P (operands[0]) && STACK_TOP_P (operands[1]))
  1010.     {
  1011.       if (stack_top_dies)
  1012.     return AS1 (fstp,%y0);
  1013.       else
  1014.         return AS1 (fld,%y0);
  1015.     }
  1016.  
  1017.   /* Handle a transfer between the 387 and a 386 register */
  1018.  
  1019.   if (STACK_TOP_P (operands[0]) && NON_STACK_REG_P (operands[1]))
  1020.     {
  1021.       output_op_from_reg (operands[1], AS1 (fld%z0,%y1));
  1022.       RET;
  1023.     }
  1024.  
  1025.   if (STACK_TOP_P (operands[1]) && NON_STACK_REG_P (operands[0]))
  1026.     {
  1027.       output_to_reg (operands[0], stack_top_dies);
  1028.       RET;
  1029.     }
  1030.  
  1031.   /* Handle other kinds of writes from the 387 */
  1032.  
  1033.   if (STACK_TOP_P (operands[1]))
  1034.     {
  1035.       if (stack_top_dies)
  1036.     return AS1 (fstp%z0,%y0);
  1037.       else
  1038.         return AS1 (fst%z0,%y0);
  1039.     }
  1040.  
  1041.   /* Handle other kinds of reads to the 387 */
  1042.  
  1043.   if (STACK_TOP_P (operands[0]) && GET_CODE (operands[1]) == CONST_DOUBLE)
  1044.     return (char *) output_move_const_single (operands);
  1045.  
  1046.   if (STACK_TOP_P (operands[0]))
  1047.     return AS1 (fld%z1,%y1);
  1048.  
  1049.   /* Handle all SFmode moves not involving the 387 */
  1050.  
  1051.   return (char *) singlemove_string (operands);
  1052. }")
  1053.  
  1054. ;;should change to handle the memory operands[1] without doing df push..
  1055. (define_insn ""
  1056.   [(set (match_operand:DF 0 "push_operand" "=<,<")
  1057.     (match_operand:DF 1 "general_operand" "gF,f"))]
  1058.   ""
  1059.   "*
  1060. {
  1061.   if (STACK_REG_P (operands[1]))
  1062.     {
  1063.       rtx xops[3];
  1064.  
  1065.       xops[0] = AT_SP (SFmode);
  1066.       xops[1] = GEN_INT (8);
  1067.       xops[2] = stack_pointer_rtx;
  1068.  
  1069.       output_asm_insn (AS2 (sub%L2,%1,%2), xops);
  1070.  
  1071.       if (find_regno_note (insn, REG_DEAD, FIRST_STACK_REG))
  1072.         output_asm_insn (AS1 (fstp%Q0,%0), xops);
  1073.       else
  1074.         output_asm_insn (AS1 (fst%Q0,%0), xops);
  1075.  
  1076.       RET;
  1077.     }
  1078.   else
  1079.     return (char *) output_move_double (operands);
  1080. }")
  1081.  
  1082. (define_insn "swapdf"
  1083.   [(set (match_operand:DF 0 "register_operand" "f")
  1084.     (match_operand:DF 1 "register_operand" "f"))
  1085.    (set (match_dup 1)
  1086.     (match_dup 0))]
  1087.   ""
  1088.   "*
  1089. {
  1090.   if (STACK_TOP_P (operands[0]))
  1091.     return AS1 (fxch,%1);
  1092.   else
  1093.     return AS1 (fxch,%0);
  1094. }")
  1095.  
  1096. ;; Allow MEM-MEM moves before reload.  The reload class for such a
  1097. ;; move will be ALL_REGS.  PREFERRED_RELOAD_CLASS will narrow this to
  1098. ;; GENERAL_REGS.  For the purposes of regclass, prefer FLOAT_REGS.
  1099.  
  1100. (define_insn "movdf"
  1101.   [(set (match_operand:DF 0 "general_operand" "=*rfm,*rf,f,!*rm")
  1102.     (match_operand:DF 1 "general_operand" "*rf,*rfm,fG,fF"))]
  1103.   ""
  1104.   "*
  1105. {
  1106.   int stack_top_dies = find_regno_note (insn, REG_DEAD, FIRST_STACK_REG) != 0;
  1107.  
  1108.   /* First handle a `pop' insn or a `fld %st(0)' */
  1109.  
  1110.   if (STACK_TOP_P (operands[0]) && STACK_TOP_P (operands[1]))
  1111.     {
  1112.       if (stack_top_dies)
  1113.     return AS1 (fstp,%y0);
  1114.       else
  1115.         return AS1 (fld,%y0);
  1116.     }
  1117.  
  1118.   /* Handle a transfer between the 387 and a 386 register */
  1119.  
  1120.   if (STACK_TOP_P (operands[0]) && NON_STACK_REG_P (operands[1]))
  1121.     {
  1122.       output_op_from_reg (operands[1], AS1 (fld%z0,%y1));
  1123.       RET;
  1124.     }
  1125.  
  1126.   if (STACK_TOP_P (operands[1]) && NON_STACK_REG_P (operands[0]))
  1127.     {
  1128.       output_to_reg (operands[0], stack_top_dies);
  1129.       RET;
  1130.     }
  1131.  
  1132.   /* Handle other kinds of writes from the 387 */
  1133.  
  1134.   if (STACK_TOP_P (operands[1]))
  1135.     {
  1136.       if (stack_top_dies)
  1137.     return AS1 (fstp%z0,%y0);
  1138.       else
  1139.         return AS1 (fst%z0,%y0);
  1140.     }
  1141.  
  1142.   /* Handle other kinds of reads to the 387 */
  1143.  
  1144.   if (STACK_TOP_P (operands[0]) && GET_CODE (operands[1]) == CONST_DOUBLE)
  1145.     return (char *) output_move_const_single (operands);
  1146.  
  1147.   if (STACK_TOP_P (operands[0]))
  1148.     return AS1 (fld%z1,%y1);
  1149.  
  1150.   /* Handle all DFmode moves not involving the 387 */
  1151.  
  1152.   return (char *) output_move_double (operands);
  1153. }")
  1154.  
  1155. (define_insn ""
  1156.   [(set (match_operand:XF 0 "push_operand" "=<,<")
  1157.      (match_operand:XF 1 "general_operand" "gF,f"))]
  1158.   ""
  1159.   "*
  1160. {
  1161.   if (STACK_REG_P (operands[1]))
  1162.     {
  1163.       rtx xops[3];
  1164.  
  1165.       xops[0] = AT_SP (SFmode);
  1166.       xops[1] = GEN_INT (12);
  1167.       xops[2] = stack_pointer_rtx;
  1168.  
  1169.       output_asm_insn (AS2 (sub%L2,%1,%2), xops);
  1170.       output_asm_insn (AS1 (fstp%T0,%0), xops);
  1171.       if (! find_regno_note (insn, REG_DEAD, FIRST_STACK_REG))
  1172.     output_asm_insn (AS1 (fld%T0,%0), xops);
  1173.  
  1174.       RET;
  1175.     }
  1176.   else
  1177.     return (char *) output_move_double (operands);
  1178.  }")
  1179.  
  1180. (define_insn "swapxf"
  1181.   [(set (match_operand:XF 0 "register_operand" "f")
  1182.     (match_operand:XF 1 "register_operand" "f"))
  1183.    (set (match_dup 1)
  1184.     (match_dup 0))]
  1185.   ""
  1186.   "*
  1187. {
  1188.   if (STACK_TOP_P (operands[0]))
  1189.     return AS1 (fxch,%1);
  1190.   else
  1191.     return AS1 (fxch,%0);
  1192. }")
  1193.  
  1194. (define_insn "movxf"
  1195.   [(set (match_operand:XF 0 "general_operand" "=f,fm,!*rf,!*rm")
  1196.     (match_operand:XF 1 "general_operand" "fmG,f,*rfm,*rfF"))]
  1197. ;;  [(set (match_operand:XF 0 "general_operand" "=*rf,*rfm,f,!*rm")
  1198. ;;    (match_operand:XF 1 "general_operand" "*rfm,*rf,fG,fF"))]
  1199.   ""
  1200.   "*
  1201. {
  1202.   int stack_top_dies = find_regno_note (insn, REG_DEAD, FIRST_STACK_REG) != 0;
  1203.  
  1204.   /* First handle a `pop' insn or a `fld %st(0)' */
  1205.  
  1206.   if (STACK_TOP_P (operands[0]) && STACK_TOP_P (operands[1]))
  1207.     {
  1208.       if (stack_top_dies)
  1209.     return AS1 (fstp,%y0);
  1210.       else
  1211.         return AS1 (fld,%y0);
  1212.     }
  1213.  
  1214.   /* Handle a transfer between the 387 and a 386 register */
  1215.  
  1216.   if (STACK_TOP_P (operands[0]) && NON_STACK_REG_P (operands[1]))
  1217.     {
  1218.       output_op_from_reg (operands[1], AS1 (fld%z0,%y1));
  1219.       RET;
  1220.     }
  1221.  
  1222.   if (STACK_TOP_P (operands[1]) && NON_STACK_REG_P (operands[0]))
  1223.     {
  1224.       output_to_reg (operands[0], stack_top_dies);
  1225.       RET;
  1226.     }
  1227.  
  1228.   /* Handle other kinds of writes from the 387 */
  1229.  
  1230.   if (STACK_TOP_P (operands[1]))
  1231.     {
  1232.       output_asm_insn (AS1 (fstp%z0,%y0), operands);
  1233.       if (! stack_top_dies)
  1234.     return AS1 (fld%z0,%y0);
  1235.  
  1236.       RET;
  1237.     }
  1238.  
  1239.   /* Handle other kinds of reads to the 387 */
  1240.  
  1241.   if (STACK_TOP_P (operands[0]) && GET_CODE (operands[1]) == CONST_DOUBLE)
  1242.     return (char *) output_move_const_single (operands);
  1243.  
  1244.   if (STACK_TOP_P (operands[0]))
  1245.        return AS1 (fld%z1,%y1);
  1246.  
  1247.   /* Handle all XFmode moves not involving the 387 */
  1248.  
  1249.   return (char *) output_move_double (operands);
  1250. }")
  1251.  
  1252. (define_insn ""
  1253.   [(set (match_operand:DI 0 "push_operand" "=<")
  1254.     (match_operand:DI 1 "general_operand" "roiF"))]
  1255.   ""
  1256.   "*
  1257. {
  1258.   return (char *) output_move_double (operands);
  1259. }")
  1260.  
  1261. (define_insn "movdi"
  1262.   [(set (match_operand:DI 0 "general_operand" "=r,rm")
  1263.     (match_operand:DI 1 "general_operand" "m,riF"))]
  1264.   ""
  1265.   "*
  1266. {
  1267.   return (char *) output_move_double (operands);
  1268. }")
  1269.  
  1270. ;;- conversion instructions
  1271. ;;- NONE
  1272.  
  1273. ;;- zero extension instructions
  1274. ;; See comments by `andsi' for when andl is faster than movzx.
  1275.  
  1276. (define_insn "zero_extendhisi2"
  1277.   [(set (match_operand:SI 0 "general_operand" "=r")
  1278.     (zero_extend:SI
  1279.      (match_operand:HI 1 "nonimmediate_operand" "rm")))]
  1280.   ""
  1281.   "*
  1282. {
  1283.   if ((TARGET_486 || REGNO (operands[0]) == 0)
  1284.       && REG_P (operands[1]) && REGNO (operands[0]) == REGNO (operands[1]))
  1285.     {
  1286.       rtx xops[2];
  1287.       xops[0] = operands[0];
  1288.       xops[1] = GEN_INT (0xffff);
  1289.       output_asm_insn (AS2 (and%L0,%1,%k0), xops);
  1290.       RET;
  1291.     }
  1292.  
  1293. #ifdef INTEL_SYNTAX
  1294.   return AS2 (movzx,%1,%0);
  1295. #else
  1296.   return AS2 (movz%W0%L0,%1,%0);
  1297. #endif
  1298. }")
  1299.  
  1300. (define_insn "zero_extendqihi2"
  1301.   [(set (match_operand:HI 0 "general_operand" "=r")
  1302.     (zero_extend:HI
  1303.      (match_operand:QI 1 "nonimmediate_operand" "qm")))]
  1304.   ""
  1305.   "*
  1306. {
  1307.   if ((TARGET_486 || REGNO (operands[0]) == 0)
  1308.       && REG_P (operands[1]) && REGNO (operands[0]) == REGNO (operands[1]))
  1309.     {
  1310.       rtx xops[2];
  1311.       xops[0] = operands[0];
  1312.       xops[1] = GEN_INT (0xff);
  1313.       output_asm_insn (AS2 (and%L0,%1,%k0), xops);
  1314.       RET;
  1315.     }
  1316.  
  1317. #ifdef INTEL_SYNTAX
  1318.   return AS2 (movzx,%1,%0);
  1319. #else
  1320.   return AS2 (movz%B0%W0,%1,%0);
  1321. #endif
  1322. }")
  1323.  
  1324. (define_insn "zero_extendqisi2"
  1325.   [(set (match_operand:SI 0 "general_operand" "=r")
  1326.     (zero_extend:SI
  1327.      (match_operand:QI 1 "nonimmediate_operand" "qm")))]
  1328.   ""
  1329.   "*
  1330. {
  1331.   if ((TARGET_486 || REGNO (operands[0]) == 0)
  1332.       && REG_P (operands[1]) && REGNO (operands[0]) == REGNO (operands[1]))
  1333.     {
  1334.       rtx xops[2];
  1335.       xops[0] = operands[0];
  1336.       xops[1] = GEN_INT (0xff);
  1337.       output_asm_insn (AS2 (and%L0,%1,%k0), xops);
  1338.       RET;
  1339.     }
  1340.  
  1341. #ifdef INTEL_SYNTAX
  1342.   return AS2 (movzx,%1,%0);
  1343. #else
  1344.   return AS2 (movz%B0%L0,%1,%0);
  1345. #endif
  1346. }")
  1347.  
  1348. (define_insn "zero_extendsidi2"
  1349.   [(set (match_operand:DI 0 "register_operand" "=r")
  1350.     (zero_extend:DI
  1351.      (match_operand:SI 1 "register_operand" "0")))]
  1352.   ""
  1353.   "*
  1354. {
  1355.   operands[0] = gen_rtx (REG, SImode, REGNO (operands[0]) + 1);
  1356.   return AS2 (xor%L0,%0,%0);
  1357. }")
  1358.  
  1359. ;;- sign extension instructions
  1360.  
  1361. (define_insn "extendsidi2"
  1362.   [(set (match_operand:DI 0 "register_operand" "=r")
  1363.     (sign_extend:DI
  1364.      (match_operand:SI 1 "register_operand" "0")))]
  1365.   ""
  1366.   "*
  1367. {
  1368.   if (REGNO (operands[0]) == 0)
  1369.     {
  1370.       /* This used to be cwtl, but that extends HI to SI somehow.  */
  1371. #ifdef INTEL_SYNTAX
  1372.       return \"cdq\";
  1373. #else
  1374.       return \"cltd\";
  1375. #endif
  1376.     }
  1377.  
  1378.   operands[1] = gen_rtx (REG, SImode, REGNO (operands[0]) + 1);
  1379.   output_asm_insn (AS2 (mov%L0,%0,%1), operands);
  1380.  
  1381.   operands[0] = GEN_INT (31);
  1382.   return AS2 (sar%L1,%0,%1);
  1383. }")
  1384.  
  1385. ;; Note that the i386 programmers' manual says that the opcodes
  1386. ;; are named movsx..., but the assembler on Unix does not accept that.
  1387. ;; We use what the Unix assembler expects.
  1388.  
  1389. (define_insn "extendhisi2"
  1390.   [(set (match_operand:SI 0 "general_operand" "=r")
  1391.     (sign_extend:SI
  1392.      (match_operand:HI 1 "nonimmediate_operand" "rm")))]
  1393.   ""
  1394.   "*
  1395. {
  1396.   if (REGNO (operands[0]) == 0
  1397.       && REG_P (operands[1]) && REGNO (operands[1]) == 0)
  1398. #ifdef INTEL_SYNTAX
  1399.     return \"cwde\";
  1400. #else
  1401.     return \"cwtl\";
  1402. #endif
  1403.  
  1404. #ifdef INTEL_SYNTAX
  1405.   return AS2 (movsx,%1,%0);
  1406. #else
  1407.   return AS2 (movs%W0%L0,%1,%0);
  1408. #endif
  1409. }")
  1410.  
  1411. (define_insn "extendqihi2"
  1412.   [(set (match_operand:HI 0 "general_operand" "=r")
  1413.     (sign_extend:HI
  1414.      (match_operand:QI 1 "nonimmediate_operand" "qm")))]
  1415.   ""
  1416.   "*
  1417. {
  1418.   if (REGNO (operands[0]) == 0
  1419.       && REG_P (operands[1]) && REGNO (operands[1]) == 0)
  1420.     return \"cbtw\";
  1421.  
  1422. #ifdef INTEL_SYNTAX
  1423.   return AS2 (movsx,%1,%0);
  1424. #else
  1425.   return AS2 (movs%B0%W0,%1,%0);
  1426. #endif
  1427. }")
  1428.  
  1429. (define_insn "extendqisi2"
  1430.   [(set (match_operand:SI 0 "general_operand" "=r")
  1431.     (sign_extend:SI
  1432.      (match_operand:QI 1 "nonimmediate_operand" "qm")))]
  1433.   ""
  1434.   "*
  1435. {
  1436. #ifdef INTEL_SYNTAX
  1437.   return AS2 (movsx,%1,%0);
  1438. #else
  1439.   return AS2 (movs%B0%L0,%1,%0);
  1440. #endif
  1441. }")
  1442.  
  1443. ;; Conversions between float and double.
  1444.  
  1445. (define_insn "extendsfdf2"
  1446.   [(set (match_operand:DF 0 "general_operand" "=fm,f")
  1447.     (float_extend:DF
  1448.      (match_operand:SF 1 "general_operand" "f,fm")))]
  1449.   "TARGET_80387"
  1450.   "*
  1451. {
  1452.   int stack_top_dies = find_regno_note (insn, REG_DEAD, FIRST_STACK_REG) != 0;
  1453.  
  1454.   if (NON_STACK_REG_P (operands[1]))
  1455.     {
  1456.       output_op_from_reg (operands[1], AS1 (fld%z0,%y1));
  1457.       RET;
  1458.     }
  1459.  
  1460.   if (NON_STACK_REG_P (operands[0]))
  1461.     {
  1462.       output_to_reg (operands[0], stack_top_dies);
  1463.       RET;
  1464.     }
  1465.  
  1466.   if (STACK_TOP_P (operands[0]))
  1467.     return AS1 (fld%z1,%y1);
  1468.  
  1469.   if (GET_CODE (operands[0]) == MEM)
  1470.     {
  1471.       if (stack_top_dies)
  1472.     return AS1 (fstp%z0,%y0);
  1473.       else
  1474.         return AS1 (fst%z0,%y0);
  1475.     }
  1476.  
  1477.   abort ();
  1478. }")
  1479.  
  1480. (define_insn "extenddfxf2"
  1481.   [(set (match_operand:XF 0 "general_operand" "=fm,f,f,!*r")
  1482.     (float_extend:XF
  1483.      (match_operand:DF 1 "general_operand" "f,fm,!*r,f")))]
  1484.   "TARGET_80387"
  1485.   "*
  1486. {
  1487.   int stack_top_dies = find_regno_note (insn, REG_DEAD, FIRST_STACK_REG) != 0;
  1488.  
  1489.   if (NON_STACK_REG_P (operands[1]))
  1490.     {
  1491.       output_op_from_reg (operands[1], AS1 (fld%z0,%y1));
  1492.       RET;
  1493.     }
  1494.  
  1495.   if (NON_STACK_REG_P (operands[0]))
  1496.     {
  1497.       output_to_reg (operands[0], stack_top_dies);
  1498.       RET;
  1499.     }
  1500.  
  1501.   if (STACK_TOP_P (operands[0]))
  1502.     return AS1 (fld%z1,%y1);
  1503.  
  1504.   if (GET_CODE (operands[0]) == MEM)
  1505.     {
  1506.       output_asm_insn (AS1 (fstp%z0,%y0), operands);
  1507.       if (! stack_top_dies)
  1508.     return AS1 (fld%z0,%y0);
  1509.       RET;
  1510.     }
  1511.  
  1512.   abort ();
  1513. }")
  1514.  
  1515. (define_insn "extendsfxf2"
  1516.   [(set (match_operand:XF 0 "general_operand" "=fm,f,f,!*r")
  1517.     (float_extend:XF
  1518.      (match_operand:SF 1 "general_operand" "f,fm,!*r,f")))]
  1519.   "TARGET_80387"
  1520.   "*
  1521. {
  1522.   int stack_top_dies = find_regno_note (insn, REG_DEAD, FIRST_STACK_REG) != 0;
  1523.  
  1524.   if (NON_STACK_REG_P (operands[1]))
  1525.     {
  1526.       output_op_from_reg (operands[1], AS1 (fld%z0,%y1));
  1527.       RET;
  1528.     }
  1529.  
  1530.   if (NON_STACK_REG_P (operands[0]))
  1531.     {
  1532.       output_to_reg (operands[0], stack_top_dies);
  1533.       RET;
  1534.     }
  1535.  
  1536.   if (STACK_TOP_P (operands[0]))
  1537.     return AS1 (fld%z1,%y1);
  1538.  
  1539.   if (GET_CODE (operands[0]) == MEM)
  1540.     {
  1541.       output_asm_insn (AS1 (fstp%z0,%y0), operands);
  1542.       if (! stack_top_dies)
  1543.     return AS1 (fld%z0,%y0);
  1544.       RET;
  1545.     }
  1546.  
  1547.   abort ();
  1548. }")
  1549.  
  1550. (define_expand "truncdfsf2"
  1551.   [(parallel [(set (match_operand:SF 0 "nonimmediate_operand" "")
  1552.            (float_truncate:SF
  1553.             (match_operand:DF 1 "register_operand" "")))
  1554.           (clobber (match_dup 2))])]
  1555.   "TARGET_80387"
  1556.   "
  1557. {
  1558.   operands[2] = (rtx) assign_386_stack_local (SFmode, 0);
  1559. }")
  1560.  
  1561. ;; This cannot output into an f-reg because there is no way to be sure
  1562. ;; of truncating in that case.  Otherwise this is just like a simple move
  1563. ;; insn.  So we pretend we can output to a reg in order to get better
  1564. ;; register preferencing, but we really use a stack slot.
  1565.  
  1566. (define_insn ""
  1567.   [(set (match_operand:SF 0 "nonimmediate_operand" "=f,m")
  1568.     (float_truncate:SF
  1569.      (match_operand:DF 1 "register_operand" "0,f")))
  1570.    (clobber (match_operand:SF 2 "memory_operand" "m,m"))]
  1571.   "TARGET_80387"
  1572.   "*
  1573. {
  1574.   int stack_top_dies = find_regno_note (insn, REG_DEAD, FIRST_STACK_REG) != 0;
  1575.  
  1576.   if (GET_CODE (operands[0]) == MEM)
  1577.     {
  1578.       if (stack_top_dies)
  1579.     return AS1 (fstp%z0,%0);
  1580.       else
  1581.         return AS1 (fst%z0,%0);
  1582.     }
  1583.   else if (STACK_TOP_P (operands[0]))
  1584.     {
  1585.       output_asm_insn (AS1 (fstp%z2,%y2), operands);
  1586.       return AS1 (fld%z2,%y2);
  1587.     }
  1588.   else
  1589.     abort ();
  1590. }")
  1591.  
  1592. (define_insn "truncxfsf2"
  1593.   [(set (match_operand:SF 0 "general_operand" "=m,!*r")
  1594.     (float_truncate:SF
  1595.      (match_operand:XF 1 "register_operand" "f,f")))]
  1596.   "TARGET_80387"
  1597.   "*
  1598. {
  1599.   int stack_top_dies = find_regno_note (insn, REG_DEAD, FIRST_STACK_REG) != 0;
  1600.  
  1601.   if (NON_STACK_REG_P (operands[0]))
  1602.     {
  1603.       if (stack_top_dies == 0)
  1604.     {
  1605.       output_asm_insn (AS1 (fld,%y1), operands);
  1606.       stack_top_dies = 1;
  1607.     }
  1608.       output_to_reg (operands[0], stack_top_dies);
  1609.       RET;
  1610.     }
  1611.   else if (GET_CODE (operands[0]) == MEM)
  1612.     {
  1613.       if (stack_top_dies)
  1614.     return AS1 (fstp%z0,%0);
  1615.       else
  1616.     {
  1617.       output_asm_insn (AS1 (fld,%y1), operands);
  1618.       return AS1 (fstp%z0,%0);
  1619.     }
  1620.     }
  1621.   else
  1622.     abort ();
  1623. }")
  1624.  
  1625. (define_insn "truncxfdf2"
  1626.   [(set (match_operand:DF 0 "general_operand" "=m,!*r")
  1627.     (float_truncate:DF
  1628.      (match_operand:XF 1 "register_operand" "f,f")))]
  1629.   "TARGET_80387"
  1630.   "*
  1631. {
  1632.   int stack_top_dies = find_regno_note (insn, REG_DEAD, FIRST_STACK_REG) != 0;
  1633.  
  1634.   if (NON_STACK_REG_P (operands[0]))
  1635.     {
  1636.       if (stack_top_dies == 0)
  1637.     {
  1638.       output_asm_insn (AS1 (fld,%y1), operands);
  1639.       stack_top_dies = 1;
  1640.     }
  1641.       output_to_reg (operands[0], stack_top_dies);
  1642.       RET;
  1643.     }
  1644.   else if (GET_CODE (operands[0]) == MEM)
  1645.     {
  1646.       if (stack_top_dies)
  1647.     return AS1 (fstp%z0,%0);
  1648.       else
  1649.     {
  1650.       output_asm_insn (AS1 (fld,%y1), operands);
  1651.       return AS1 (fstp%z0,%0);
  1652.     }
  1653.     }
  1654.   else
  1655.     abort ();
  1656. }")
  1657.  
  1658.  
  1659. ;; The 387 requires that the stack top dies after converting to DImode.
  1660.  
  1661. ;; Represent an unsigned conversion from SImode to MODE_FLOAT by first
  1662. ;; doing a signed conversion to DImode, and then taking just the low
  1663. ;; part.
  1664.  
  1665. (define_expand "fixuns_truncxfsi2"
  1666.   [(set (match_dup 4)
  1667.     (match_operand:XF 1 "register_operand" ""))
  1668.    (parallel [(set (match_dup 2)
  1669.            (fix:DI (fix:XF (match_dup 4))))
  1670.           (clobber (match_dup 4))
  1671.           (clobber (match_dup 5))
  1672.           (clobber (match_dup 6))
  1673.           (clobber (match_scratch:SI 7 ""))])
  1674.    (set (match_operand:SI 0 "general_operand" "")
  1675.     (match_dup 3))]
  1676.   "TARGET_80387"
  1677.   "
  1678. {
  1679.   operands[2] = gen_reg_rtx (DImode);
  1680.   operands[3] = gen_lowpart (SImode, operands[2]);
  1681.   operands[4] = gen_reg_rtx (XFmode);
  1682.   operands[5] = (rtx) assign_386_stack_local (SImode, 0);
  1683.   operands[6] = (rtx) assign_386_stack_local (SImode, 1);
  1684. }")
  1685.  
  1686. (define_expand "fixuns_truncdfsi2"
  1687.   [(set (match_dup 4)
  1688.     (match_operand:DF 1 "register_operand" ""))
  1689.    (parallel [(set (match_dup 2)
  1690.            (fix:DI (fix:DF (match_dup 4))))
  1691.           (clobber (match_dup 4))
  1692.           (clobber (match_dup 5))
  1693.           (clobber (match_dup 6))
  1694.           (clobber (match_scratch:SI 7 ""))])
  1695.    (set (match_operand:SI 0 "general_operand" "")
  1696.     (match_dup 3))]
  1697.   "TARGET_80387"
  1698.   "
  1699. {
  1700.   operands[2] = gen_reg_rtx (DImode);
  1701.   operands[3] = gen_lowpart (SImode, operands[2]);
  1702.   operands[4] = gen_reg_rtx (DFmode);
  1703.   operands[5] = (rtx) assign_386_stack_local (SImode, 0);
  1704.   operands[6] = (rtx) assign_386_stack_local (SImode, 1);
  1705. }")
  1706.  
  1707. (define_expand "fixuns_truncsfsi2"
  1708.   [(set (match_dup 4)
  1709.     (match_operand:SF 1 "register_operand" ""))
  1710.    (parallel [(set (match_dup 2)
  1711.            (fix:DI (fix:SF (match_dup 4))))
  1712.           (clobber (match_dup 4))
  1713.           (clobber (match_dup 5))
  1714.           (clobber (match_dup 6))
  1715.           (clobber (match_scratch:SI 7 ""))])
  1716.    (set (match_operand:SI 0 "general_operand" "")
  1717.     (match_dup 3))]
  1718.   "TARGET_80387"
  1719.   "
  1720. {
  1721.   operands[2] = gen_reg_rtx (DImode);
  1722.   operands[3] = gen_lowpart (SImode, operands[2]);
  1723.   operands[4] = gen_reg_rtx (SFmode);
  1724.   operands[5] = (rtx) assign_386_stack_local (SImode, 0);
  1725.   operands[6] = (rtx) assign_386_stack_local (SImode, 1);
  1726. }")
  1727.  
  1728. ;; Signed conversion to DImode.
  1729.  
  1730. (define_expand "fix_truncxfdi2"
  1731.   [(set (match_dup 2)
  1732.     (match_operand:XF 1 "register_operand" ""))
  1733.    (parallel [(set (match_operand:DI 0 "general_operand" "")
  1734.            (fix:DI (fix:XF (match_dup 2))))
  1735.           (clobber (match_dup 2))
  1736.           (clobber (match_dup 3))
  1737.           (clobber (match_dup 4))
  1738.           (clobber (match_scratch:SI 5 ""))])]
  1739.   "TARGET_80387"
  1740.   "
  1741. {
  1742.   operands[1] = copy_to_mode_reg (XFmode, operands[1]);
  1743.   operands[2] = gen_reg_rtx (XFmode);
  1744.   operands[3] = (rtx) assign_386_stack_local (SImode, 0);
  1745.   operands[4] = (rtx) assign_386_stack_local (SImode, 1);
  1746. }")
  1747.  
  1748. (define_expand "fix_truncdfdi2"
  1749.   [(set (match_dup 2)
  1750.     (match_operand:DF 1 "register_operand" ""))
  1751.    (parallel [(set (match_operand:DI 0 "general_operand" "")
  1752.            (fix:DI (fix:DF (match_dup 2))))
  1753.           (clobber (match_dup 2))
  1754.           (clobber (match_dup 3))
  1755.           (clobber (match_dup 4))
  1756.           (clobber (match_scratch:SI 5 ""))])]
  1757.   "TARGET_80387"
  1758.   "
  1759. {
  1760.   operands[1] = copy_to_mode_reg (DFmode, operands[1]);
  1761.   operands[2] = gen_reg_rtx (DFmode);
  1762.   operands[3] = (rtx) assign_386_stack_local (SImode, 0);
  1763.   operands[4] = (rtx) assign_386_stack_local (SImode, 1);
  1764. }")
  1765.  
  1766. (define_expand "fix_truncsfdi2"
  1767.   [(set (match_dup 2)
  1768.     (match_operand:SF 1 "register_operand" ""))
  1769.    (parallel [(set (match_operand:DI 0 "general_operand" "")
  1770.            (fix:DI (fix:SF (match_dup 2))))
  1771.           (clobber (match_dup 2))
  1772.           (clobber (match_dup 3))
  1773.           (clobber (match_dup 4))
  1774.           (clobber (match_scratch:SI 5 ""))])]
  1775.   "TARGET_80387"
  1776.   "
  1777. {
  1778.   operands[1] = copy_to_mode_reg (SFmode, operands[1]);
  1779.   operands[2] = gen_reg_rtx (SFmode);
  1780.   operands[3] = (rtx) assign_386_stack_local (SImode, 0);
  1781.   operands[4] = (rtx) assign_386_stack_local (SImode, 1);
  1782. }")
  1783.  
  1784. ;; These match a signed conversion of either DFmode or SFmode to DImode.
  1785.  
  1786. (define_insn ""
  1787.   [(set (match_operand:DI 0 "general_operand" "=rm")
  1788.     (fix:DI (fix:XF (match_operand:XF 1 "register_operand" "f"))))
  1789.    (clobber (match_dup 1))
  1790.    (clobber (match_operand:SI 2 "memory_operand" "m"))
  1791.    (clobber (match_operand:SI 3 "memory_operand" "m"))
  1792.    (clobber (match_scratch:SI 4 "=&q"))]
  1793.   "TARGET_80387"
  1794.   "* return (char *) output_fix_trunc (insn, operands);")
  1795.  
  1796. (define_insn ""
  1797.   [(set (match_operand:DI 0 "general_operand" "=rm")
  1798.     (fix:DI (fix:DF (match_operand:DF 1 "register_operand" "f"))))
  1799.    (clobber (match_dup 1))
  1800.    (clobber (match_operand:SI 2 "memory_operand" "m"))
  1801.    (clobber (match_operand:SI 3 "memory_operand" "m"))
  1802.    (clobber (match_scratch:SI 4 "=&q"))]
  1803.   "TARGET_80387"
  1804.   "* return (char *) output_fix_trunc (insn, operands);")
  1805.  
  1806. (define_insn ""
  1807.   [(set (match_operand:DI 0 "general_operand" "=rm")
  1808.     (fix:DI (fix:SF (match_operand:SF 1 "register_operand" "f"))))
  1809.    (clobber (match_dup 1))
  1810.    (clobber (match_operand:SI 2 "memory_operand" "m"))
  1811.    (clobber (match_operand:SI 3 "memory_operand" "m"))
  1812.    (clobber (match_scratch:SI 4 "=&q"))]
  1813.   "TARGET_80387"
  1814.   "* return (char *) output_fix_trunc (insn, operands);")
  1815.  
  1816. ;; Signed MODE_FLOAT conversion to SImode.
  1817.  
  1818. (define_expand "fix_truncxfsi2"
  1819.   [(parallel [(set (match_operand:SI 0 "general_operand" "")
  1820.            (fix:SI
  1821.             (fix:XF (match_operand:XF 1 "register_operand" ""))))
  1822.           (clobber (match_dup 2))
  1823.           (clobber (match_dup 3))
  1824.           (clobber (match_scratch:SI 4 ""))])]
  1825.   "TARGET_80387"
  1826.   "
  1827. {
  1828.   operands[2] = (rtx) assign_386_stack_local (SImode, 0);
  1829.   operands[3] = (rtx) assign_386_stack_local (SImode, 1);
  1830. }")
  1831.  
  1832. (define_expand "fix_truncdfsi2"
  1833.   [(parallel [(set (match_operand:SI 0 "general_operand" "")
  1834.            (fix:SI
  1835.             (fix:DF (match_operand:DF 1 "register_operand" ""))))
  1836.           (clobber (match_dup 2))
  1837.           (clobber (match_dup 3))
  1838.           (clobber (match_scratch:SI 4 ""))])]
  1839.   "TARGET_80387"
  1840.   "
  1841. {
  1842.   operands[2] = (rtx) assign_386_stack_local (SImode, 0);
  1843.   operands[3] = (rtx) assign_386_stack_local (SImode, 1);
  1844. }")
  1845.  
  1846. (define_expand "fix_truncsfsi2"
  1847.   [(parallel [(set (match_operand:SI 0 "general_operand" "")
  1848.            (fix:SI
  1849.             (fix:SF (match_operand:SF 1 "register_operand" ""))))
  1850.           (clobber (match_dup 2))
  1851.           (clobber (match_dup 3))
  1852.           (clobber (match_scratch:SI 4 ""))])]
  1853.   "TARGET_80387"
  1854.   "
  1855. {
  1856.   operands[2] = (rtx) assign_386_stack_local (SImode, 0);
  1857.   operands[3] = (rtx) assign_386_stack_local (SImode, 1);
  1858. }")
  1859.  
  1860. (define_insn ""
  1861.   [(set (match_operand:SI 0 "general_operand" "=rm")
  1862.     (fix:SI (fix:XF (match_operand:XF 1 "register_operand" "f"))))
  1863.    (clobber (match_operand:SI 2 "memory_operand" "m"))
  1864.    (clobber (match_operand:SI 3 "memory_operand" "m"))
  1865.    (clobber (match_scratch:SI 4 "=&q"))]
  1866.   "TARGET_80387"
  1867.   "* return (char *) output_fix_trunc (insn, operands);")
  1868.  
  1869. (define_insn ""
  1870.   [(set (match_operand:SI 0 "general_operand" "=rm")
  1871.     (fix:SI (fix:DF (match_operand:DF 1 "register_operand" "f"))))
  1872.    (clobber (match_operand:SI 2 "memory_operand" "m"))
  1873.    (clobber (match_operand:SI 3 "memory_operand" "m"))
  1874.    (clobber (match_scratch:SI 4 "=&q"))]
  1875.   "TARGET_80387"
  1876.   "* return (char *) output_fix_trunc (insn, operands);")
  1877.  
  1878. (define_insn ""
  1879.   [(set (match_operand:SI 0 "general_operand" "=rm")
  1880.     (fix:SI (fix:SF (match_operand:SF 1 "register_operand" "f"))))
  1881.    (clobber (match_operand:SI 2 "memory_operand" "m"))
  1882.    (clobber (match_operand:SI 3 "memory_operand" "m"))
  1883.    (clobber (match_scratch:SI 4 "=&q"))]
  1884.   "TARGET_80387"
  1885.   "* return (char *) output_fix_trunc (insn, operands);")
  1886.  
  1887. ;; Conversion between fixed point and floating point.
  1888. ;; The actual pattern that matches these is at the end of this file.
  1889.  
  1890. ;; ??? Possibly represent floatunssidf2 here in gcc2.
  1891.  
  1892. (define_expand "floatsisf2"
  1893.   [(set (match_operand:SF 0 "register_operand" "")
  1894.     (float:SF (match_operand:SI 1 "nonimmediate_operand" "")))]
  1895.   "TARGET_80387"
  1896.   "")
  1897.  
  1898. (define_expand "floatdisf2"
  1899.   [(set (match_operand:SF 0 "register_operand" "")
  1900.     (float:SF (match_operand:DI 1 "nonimmediate_operand" "")))]
  1901.   "TARGET_80387"
  1902.   "")
  1903.  
  1904. (define_expand "floatsidf2"
  1905.   [(set (match_operand:DF 0 "register_operand" "")
  1906.     (float:DF (match_operand:SI 1 "nonimmediate_operand" "")))]
  1907.   "TARGET_80387"
  1908.   "")
  1909.  
  1910. (define_expand "floatdidf2"
  1911.   [(set (match_operand:DF 0 "register_operand" "")
  1912.     (float:DF (match_operand:DI 1 "nonimmediate_operand" "")))]
  1913.   "TARGET_80387"
  1914.   "")
  1915.  
  1916. (define_expand "floatsixf2"
  1917.   [(set (match_operand:XF 0 "register_operand" "")
  1918.     (float:XF (match_operand:SI 1 "nonimmediate_operand" "")))]
  1919.   "TARGET_80387"
  1920.   "")
  1921.  
  1922. (define_expand "floatdixf2"
  1923.   [(set (match_operand:XF 0 "register_operand" "")
  1924.     (float:XF (match_operand:DI 1 "nonimmediate_operand" "")))]
  1925.   "TARGET_80387"
  1926.   "")
  1927.  
  1928. ;; This will convert from SImode or DImode to MODE_FLOAT.
  1929.  
  1930. (define_insn ""
  1931.   [(set (match_operand:XF 0 "register_operand" "=f")
  1932.     (float:XF (match_operand:DI 1 "general_operand" "rm")))]
  1933.   "TARGET_80387"
  1934.   "*
  1935. {
  1936.   if (NON_STACK_REG_P (operands[1]))
  1937.     {
  1938.       output_op_from_reg (operands[1], AS1 (fild%z0,%1));
  1939.       RET;
  1940.     }
  1941.   else if (GET_CODE (operands[1]) == MEM)
  1942.     return AS1 (fild%z1,%1);
  1943.   else
  1944.     abort ();
  1945. }")
  1946.  
  1947. (define_insn ""
  1948.   [(set (match_operand:DF 0 "register_operand" "=f")
  1949.     (float:DF (match_operand:DI 1 "nonimmediate_operand" "rm")))]
  1950.   "TARGET_80387"
  1951.   "*
  1952. {
  1953.   if (NON_STACK_REG_P (operands[1]))
  1954.     {
  1955.       output_op_from_reg (operands[1], AS1 (fild%z0,%1));
  1956.       RET;
  1957.     }
  1958.   else if (GET_CODE (operands[1]) == MEM)
  1959.     return AS1 (fild%z1,%1);
  1960.   else
  1961.     abort ();
  1962. }")
  1963.  
  1964. (define_insn ""
  1965.   [(set (match_operand:SF 0 "register_operand" "=f")
  1966.     (float:SF (match_operand:DI 1 "nonimmediate_operand" "rm")))]
  1967.   "TARGET_80387"
  1968.   "*
  1969. {
  1970.   if (NON_STACK_REG_P (operands[1]))
  1971.     {
  1972.       output_op_from_reg (operands[1], AS1 (fild%z0,%1));
  1973.       RET;
  1974.     }
  1975.   else if (GET_CODE (operands[1]) == MEM)
  1976.     return AS1 (fild%z1,%1);
  1977.   else
  1978.     abort ();
  1979. }")
  1980.  
  1981. (define_insn ""
  1982.   [(set (match_operand:DF 0 "register_operand" "=f")
  1983.     (float:DF (match_operand:SI 1 "nonimmediate_operand" "rm")))]
  1984.   "TARGET_80387"
  1985.   "*
  1986. {
  1987.   if (NON_STACK_REG_P (operands[1]))
  1988.     {
  1989.       output_op_from_reg (operands[1], AS1 (fild%z0,%1));
  1990.       RET;
  1991.     }
  1992.   else if (GET_CODE (operands[1]) == MEM)
  1993.     return AS1 (fild%z1,%1);
  1994.   else
  1995.     abort ();
  1996. }")
  1997.  
  1998. (define_insn ""
  1999.   [(set (match_operand:XF 0 "register_operand" "=f,f")
  2000.     (float:XF (match_operand:SI 1 "general_operand" "m,!*r")))]
  2001.   "TARGET_80387"
  2002.   "*
  2003. {
  2004.   if (NON_STACK_REG_P (operands[1]))
  2005.     {
  2006.       output_op_from_reg (operands[1], AS1 (fild%z0,%1));
  2007.       RET;
  2008.     }
  2009.   else if (GET_CODE (operands[1]) == MEM)
  2010.     return AS1 (fild%z1,%1);
  2011.   else
  2012.     abort ();
  2013. }")
  2014.  
  2015. (define_insn ""
  2016.   [(set (match_operand:SF 0 "register_operand" "=f")
  2017.     (float:SF (match_operand:SI 1 "nonimmediate_operand" "rm")))]
  2018.   "TARGET_80387"
  2019.   "*
  2020. {
  2021.   if (NON_STACK_REG_P (operands[1]))
  2022.     {
  2023.       output_op_from_reg (operands[1], AS1 (fild%z0,%1));
  2024.       RET;
  2025.     }
  2026.   else if (GET_CODE (operands[1]) == MEM)
  2027.     return AS1 (fild%z1,%1);
  2028.   else
  2029.     abort ();
  2030. }")
  2031.  
  2032. ;;- add instructions
  2033.  
  2034. (define_insn "adddi3"
  2035.   [(set (match_operand:DI 0 "general_operand" "=&r,ro")
  2036.     (plus:DI (match_operand:DI 1 "general_operand" "%0,0")
  2037.          (match_operand:DI 2 "general_operand" "o,riF")))]
  2038.   ""
  2039.   "*
  2040. {
  2041.   rtx low[3], high[3];
  2042.  
  2043.   CC_STATUS_INIT;
  2044.  
  2045.   split_di (operands, 3, low, high);
  2046.  
  2047.   if (GET_CODE (low[2]) != CONST_INT || INTVAL (low[2]) != 0)
  2048.     {
  2049.       output_asm_insn (AS2 (add%L0,%2,%0), low);
  2050.       output_asm_insn (AS2 (adc%L0,%2,%0), high);
  2051.     }
  2052.   else
  2053.     output_asm_insn (AS2 (add%L0,%2,%0), high);
  2054.   RET;
  2055. }")
  2056.  
  2057. ;; On a 486, it is faster to do movl/addl than to do a single leal if
  2058. ;; operands[1] and operands[2] are both registers.
  2059.  
  2060. (define_insn "addsi3"
  2061.   [(set (match_operand:SI 0 "general_operand" "=?r,rm,r")
  2062.     (plus:SI (match_operand:SI 1 "general_operand" "%r,0,0")
  2063.          (match_operand:SI 2 "general_operand" "ri,ri,rm")))]
  2064.   ""
  2065.   "*
  2066. {
  2067.   if (REG_P (operands[0]) && REGNO (operands[0]) != REGNO (operands[1]))
  2068.     {
  2069.       if (REG_P (operands[2]) && REGNO (operands[0]) == REGNO (operands[2]))
  2070.     return AS2 (add%L0,%1,%0);
  2071.  
  2072.       if (! TARGET_486 || ! REG_P (operands[2]))
  2073.         {
  2074.       CC_STATUS_INIT;
  2075.  
  2076.       if (operands[2] == stack_pointer_rtx)
  2077.         {
  2078.           rtx temp;
  2079.  
  2080.           temp = operands[1];
  2081.           operands[1] = operands[2];
  2082.           operands[2] = temp;
  2083.         }
  2084.       if (operands[2] != stack_pointer_rtx)
  2085.         {
  2086.           operands[1] = SET_SRC (PATTERN (insn));
  2087.           return AS2 (lea%L0,%a1,%0);
  2088.         }
  2089.     }
  2090.  
  2091.       output_asm_insn (AS2 (mov%L0,%1,%0), operands);
  2092.     }
  2093.  
  2094.   if (operands[2] == const1_rtx)
  2095.     return AS1 (inc%L0,%0);
  2096.  
  2097.   if (operands[2] == constm1_rtx)
  2098.     return AS1 (dec%L0,%0);
  2099.  
  2100.   return AS2 (add%L0,%2,%0);
  2101. }")
  2102.  
  2103. ;; ??? `lea' here, for three operand add?  If leaw is used, only %bx,
  2104. ;; %si and %di can appear in SET_SRC, and output_asm_insn might not be
  2105. ;; able to handle the operand.  But leal always works?
  2106.  
  2107. (define_insn "addhi3"
  2108.   [(set (match_operand:HI 0 "general_operand" "=rm,r")
  2109.     (plus:HI (match_operand:HI 1 "general_operand" "%0,0")
  2110.          (match_operand:HI 2 "general_operand" "ri,rm")))]
  2111.   ""
  2112.   "*
  2113. {
  2114.   /* ??? what about offsettable memory references? */
  2115.   if (QI_REG_P (operands[0])
  2116.       && GET_CODE (operands[2]) == CONST_INT
  2117.       && (INTVAL (operands[2]) & 0xff) == 0)
  2118.     {
  2119.       CC_STATUS_INIT;
  2120.  
  2121.       operands[2] = GEN_INT ((INTVAL (operands[2]) >> 8) & 0xff);
  2122.  
  2123.       if (operands[2] == const1_rtx)
  2124.     return AS1 (inc%B0,%h0);
  2125.  
  2126.       if (operands[2] == constm1_rtx)
  2127.     return AS1 (dec%B0,%h0);
  2128.  
  2129.       return AS2 (add%B0,%2,%h0);
  2130.     }
  2131.  
  2132.   if (operands[2] == const1_rtx)
  2133.     return AS1 (inc%W0,%0);
  2134.  
  2135.   if (operands[2] == constm1_rtx)
  2136.     return AS1 (dec%W0,%0);
  2137.  
  2138.   return AS2 (add%W0,%2,%0);
  2139. }")
  2140.  
  2141. (define_insn "addqi3"
  2142.   [(set (match_operand:QI 0 "general_operand" "=qm,q")
  2143.     (plus:QI (match_operand:QI 1 "general_operand" "%0,0")
  2144.          (match_operand:QI 2 "general_operand" "qn,qmn")))]
  2145.   ""
  2146.   "*
  2147. {
  2148.   if (operands[2] == const1_rtx)
  2149.     return AS1 (inc%B0,%0);
  2150.  
  2151.   if (operands[2] == constm1_rtx)
  2152.     return AS1 (dec%B0,%0);
  2153.  
  2154.   return AS2 (add%B0,%2,%0);
  2155. }")
  2156.  
  2157. ;Lennart Augustsson <augustss@cs.chalmers.se>
  2158. ;says this pattern just makes slower code:
  2159. ;    pushl    %ebp
  2160. ;    addl    $-80,(%esp)
  2161. ;instead of
  2162. ;    leal    -80(%ebp),%eax
  2163. ;    pushl    %eax
  2164. ;
  2165. ;(define_insn ""
  2166. ;  [(set (match_operand:SI 0 "push_operand" "=<")
  2167. ;    (plus:SI (match_operand:SI 1 "general_operand" "%r")
  2168. ;         (match_operand:SI 2 "general_operand" "ri")))]
  2169. ;  ""
  2170. ;  "*
  2171. ;{
  2172. ;  rtx xops[4];
  2173. ;  xops[0] = operands[0];
  2174. ;  xops[1] = operands[1];
  2175. ;  xops[2] = operands[2];
  2176. ;  xops[3] = gen_rtx (MEM, SImode, stack_pointer_rtx);
  2177. ;  output_asm_insn (\"push%z1 %1\", xops);
  2178. ;  output_asm_insn (AS2 (add%z3,%2,%3), xops);
  2179. ;  RET;
  2180. ;}")
  2181.  
  2182. ;; addsi3 is faster, so put this after.
  2183.  
  2184. (define_insn ""
  2185.   [(set (match_operand:SI 0 "register_operand" "=r")
  2186.         (match_operand:QI 1 "address_operand" "p"))]
  2187.   ""
  2188.   "*
  2189. {
  2190.   CC_STATUS_INIT;
  2191.   /* Adding a constant to a register is faster with an add.  */
  2192.   /* ??? can this ever happen? */
  2193.   if (GET_CODE (operands[1]) == PLUS
  2194.       && GET_CODE (XEXP (operands[1], 1)) == CONST_INT
  2195.       && rtx_equal_p (operands[0], XEXP (operands[1], 0)))
  2196.     {
  2197.       operands[1] = XEXP (operands[1], 1);
  2198.  
  2199.       if (operands[1] == const1_rtx)
  2200.         return AS1 (inc%L0,%0);
  2201.  
  2202.       if (operands[1] == constm1_rtx)
  2203.         return AS1 (dec%L0,%0);
  2204.  
  2205.       return AS2 (add%L0,%1,%0);
  2206.     }
  2207.   return AS2 (lea%L0,%a1,%0);
  2208. }")
  2209.  
  2210. ;; The patterns that match these are at the end of this file.
  2211.  
  2212. (define_expand "addxf3"
  2213.   [(set (match_operand:XF 0 "register_operand" "")
  2214.     (plus:XF (match_operand:XF 1 "nonimmediate_operand" "")
  2215.          (match_operand:XF 2 "nonimmediate_operand" "")))]
  2216.   "TARGET_80387"
  2217.   "")
  2218.  
  2219. (define_expand "adddf3"
  2220.   [(set (match_operand:DF 0 "register_operand" "")
  2221.     (plus:DF (match_operand:DF 1 "nonimmediate_operand" "")
  2222.          (match_operand:DF 2 "nonimmediate_operand" "")))]
  2223.   "TARGET_80387"
  2224.   "")
  2225.  
  2226. (define_expand "addsf3"
  2227.   [(set (match_operand:SF 0 "register_operand" "")
  2228.     (plus:SF (match_operand:SF 1 "nonimmediate_operand" "")
  2229.          (match_operand:SF 2 "nonimmediate_operand" "")))]
  2230.   "TARGET_80387"
  2231.   "")
  2232.  
  2233. ;;- subtract instructions
  2234.  
  2235. (define_insn "subdi3"
  2236.   [(set (match_operand:DI 0 "general_operand" "=&r,ro")
  2237.     (minus:DI (match_operand:DI 1 "general_operand" "0,0")
  2238.           (match_operand:DI 2 "general_operand" "o,riF")))]
  2239.   ""
  2240.   "*
  2241. {
  2242.   rtx low[3], high[3];
  2243.  
  2244.   CC_STATUS_INIT;
  2245.  
  2246.   split_di (operands, 3, low, high);
  2247.  
  2248.   if (GET_CODE (low[2]) != CONST_INT || INTVAL (low[2]) != 0)
  2249.     {
  2250.       output_asm_insn (AS2 (sub%L0,%2,%0), low);
  2251.       output_asm_insn (AS2 (sbb%L0,%2,%0), high);
  2252.     }
  2253.   else
  2254.     output_asm_insn (AS2 (sub%L0,%2,%0), high);
  2255.  
  2256.   RET;
  2257. }")
  2258.  
  2259. (define_insn "subsi3"
  2260.   [(set (match_operand:SI 0 "general_operand" "=rm,r")
  2261.     (minus:SI (match_operand:SI 1 "general_operand" "0,0")
  2262.           (match_operand:SI 2 "general_operand" "ri,rm")))]
  2263.   ""
  2264.   "* return AS2 (sub%L0,%2,%0);")
  2265.  
  2266. (define_insn "subhi3"
  2267.   [(set (match_operand:HI 0 "general_operand" "=rm,r")
  2268.     (minus:HI (match_operand:HI 1 "general_operand" "0,0")
  2269.           (match_operand:HI 2 "general_operand" "ri,rm")))]
  2270.   ""
  2271.   "* return AS2 (sub%W0,%2,%0);")
  2272.  
  2273. (define_insn "subqi3"
  2274.   [(set (match_operand:QI 0 "general_operand" "=qm,q")
  2275.     (minus:QI (match_operand:QI 1 "general_operand" "0,0")
  2276.           (match_operand:QI 2 "general_operand" "qn,qmn")))]
  2277.   ""
  2278.   "* return AS2 (sub%B0,%2,%0);")
  2279.  
  2280. ;; The patterns that match these are at the end of this file.
  2281.  
  2282. (define_expand "subxf3"
  2283.   [(set (match_operand:XF 0 "register_operand" "")
  2284.     (minus:XF (match_operand:XF 1 "nonimmediate_operand" "")
  2285.           (match_operand:XF 2 "nonimmediate_operand" "")))]
  2286.   "TARGET_80387"
  2287.   "")
  2288.  
  2289. (define_expand "subdf3"
  2290.   [(set (match_operand:DF 0 "register_operand" "")
  2291.     (minus:DF (match_operand:DF 1 "nonimmediate_operand" "")
  2292.           (match_operand:DF 2 "nonimmediate_operand" "")))]
  2293.   "TARGET_80387"
  2294.   "")
  2295.  
  2296. (define_expand "subsf3"
  2297.   [(set (match_operand:SF 0 "register_operand" "")
  2298.     (minus:SF (match_operand:SF 1 "nonimmediate_operand" "")
  2299.           (match_operand:SF 2 "nonimmediate_operand" "")))]
  2300.   "TARGET_80387"
  2301.   "")
  2302.  
  2303. ;;- multiply instructions
  2304.  
  2305. ;(define_insn "mulqi3"
  2306. ;  [(set (match_operand:QI 0 "general_operand" "=a")
  2307. ;    (mult:QI (match_operand:QI 1 "general_operand" "%0")
  2308. ;         (match_operand:QI 2 "general_operand" "qm")))]
  2309. ;  ""
  2310. ;  "imul%B0 %2,%0")
  2311.  
  2312. (define_insn ""
  2313.   [(set (match_operand:HI 0 "general_operand" "=r")
  2314.     (mult:SI (match_operand:HI 1 "general_operand" "%0")
  2315.          (match_operand:HI 2 "general_operand" "r")))]
  2316.   "GET_CODE (operands[2]) == CONST_INT && INTVAL (operands[2]) == 0x80"
  2317.   "* return AS2 (imul%W0,%2,%0);")
  2318.  
  2319. (define_insn "mulhi3"
  2320.   [(set (match_operand:HI 0 "general_operand" "=r,r")
  2321.     (mult:SI (match_operand:HI 1 "general_operand" "%0,rm")
  2322.          (match_operand:HI 2 "general_operand" "g,i")))]
  2323.   ""
  2324.   "*
  2325. {
  2326.   if (GET_CODE (operands[1]) == REG
  2327.       && REGNO (operands[1]) == REGNO (operands[0])
  2328.       && (GET_CODE (operands[2]) == MEM || GET_CODE (operands[2]) == REG))
  2329.     /* Assembler has weird restrictions.  */
  2330.     return AS2 (imul%W0,%2,%0);
  2331.   return AS3 (imul%W0,%2,%1,%0);
  2332. }")
  2333.  
  2334. (define_insn ""
  2335.   [(set (match_operand:SI 0 "general_operand" "=r")
  2336.     (mult:SI (match_operand:SI 1 "general_operand" "%0")
  2337.          (match_operand:SI 2 "general_operand" "r")))]
  2338.   "GET_CODE (operands[2]) == CONST_INT && INTVAL (operands[2]) == 0x80"
  2339.   "* return AS2 (imul%L0,%2,%0);")
  2340.  
  2341. (define_insn "mulsi3"
  2342.   [(set (match_operand:SI 0 "general_operand" "=r,r")
  2343.     (mult:SI (match_operand:SI 1 "general_operand" "%0,rm")
  2344.          (match_operand:SI 2 "general_operand" "g,i")))]
  2345.   ""
  2346.   "*
  2347. {
  2348.   if (GET_CODE (operands[1]) == REG
  2349.       && REGNO (operands[1]) == REGNO (operands[0])
  2350.       && (GET_CODE (operands[2]) == MEM || GET_CODE (operands[2]) == REG))
  2351.     /* Assembler has weird restrictions.  */
  2352.     return AS2 (imul%L0,%2,%0);
  2353.   return AS3 (imul%L0,%2,%1,%0);
  2354. }")
  2355.  
  2356. (define_insn ""
  2357.   [(set (match_operand:HI 0 "general_operand" "=a")
  2358.     (mult:SI (zero_extend:HI
  2359.           (match_operand:QI 1 "nonimmediate_operand" "%0"))
  2360.          (zero_extend:HI
  2361.           (match_operand:QI 2 "nonimmediate_operand" "qm"))))]
  2362.   ""
  2363.   "mul%B0 %2")
  2364.  
  2365. ;; The patterns that match these are at the end of this file.
  2366.  
  2367. (define_expand "mulxf3"
  2368.   [(set (match_operand:XF 0 "register_operand" "")
  2369.     (mult:XF (match_operand:XF 1 "nonimmediate_operand" "")
  2370.          (match_operand:XF 2 "nonimmediate_operand" "")))]
  2371.   "TARGET_80387"
  2372.   "")
  2373.  
  2374. (define_expand "muldf3"
  2375.   [(set (match_operand:DF 0 "register_operand" "")
  2376.     (mult:DF (match_operand:DF 1 "nonimmediate_operand" "")
  2377.          (match_operand:DF 2 "nonimmediate_operand" "")))]
  2378.   "TARGET_80387"
  2379.   "")
  2380.  
  2381. (define_expand "mulsf3"
  2382.   [(set (match_operand:SF 0 "register_operand" "")
  2383.     (mult:SF (match_operand:SF 1 "nonimmediate_operand" "")
  2384.          (match_operand:SF 2 "nonimmediate_operand" "")))]
  2385.   "TARGET_80387"
  2386.   "")
  2387.  
  2388. ;; The next two patterns cause inlining of long long
  2389. ;; multiplication to happen in expand_binop.
  2390.  
  2391. (define_expand "umulsidi3"
  2392.   [(parallel
  2393.     [(set (subreg:SI (match_operand:DI 0 "register_operand" "") 0)
  2394.           (subreg:SI
  2395.            (mult:DI (zero_extend:DI
  2396.                      (match_operand:SI 1 "register_operand" ""))
  2397.                     (zero_extend:DI
  2398.                      (match_operand:SI 2 "nonimmediate_operand" ""))) 0))
  2399.      (set (subreg:SI (match_dup 0) 1)
  2400.           (subreg:SI
  2401.            (mult:DI (zero_extend:DI
  2402.                      (match_dup 1))
  2403.                     (zero_extend:DI
  2404.                      (match_dup 2))) 1))])]
  2405.   ""
  2406.   "")
  2407.  
  2408. (define_insn ""
  2409.   [(set (match_operand:SI 0 "register_operand" "=a")
  2410.         (subreg:SI
  2411.          (mult:DI (zero_extend:DI
  2412.                    (match_operand:SI 1 "register_operand" "0"))
  2413.                   (zero_extend:DI
  2414.                    (match_operand:SI 2 "nonimmediate_operand" "rm"))) 0))
  2415.    (set (match_operand:SI 3 "register_operand" "=d")
  2416.         (subreg:SI
  2417.          (mult:DI (zero_extend:DI
  2418.                    (match_dup 1))
  2419.                   (zero_extend:DI
  2420.                    (match_dup 2))) 1))]
  2421.   ""
  2422.   "mul%L0 %2")
  2423.  
  2424. (define_insn ""
  2425.   [(set (match_operand:SI 0 "register_operand" "=a")
  2426.         (subreg:SI
  2427.          (mult:DI (zero_extend:DI
  2428.                    (match_operand:SI 1 "register_operand" "0"))
  2429.                   (zero_extend:DI
  2430.                    (match_operand:SI 2 "immediate_operand" "n"))) 0))
  2431.    (set (match_operand:SI 3 "register_operand" "=d")
  2432.         (subreg:SI
  2433.          (mult:DI (zero_extend:DI
  2434.                    (match_dup 1))
  2435.                   (zero_extend:DI
  2436.                    (match_dup 2))) 1))]
  2437.   ""
  2438.   "mul%L0 %2")
  2439.  
  2440. (define_expand "mulsidi3"
  2441.   [(parallel
  2442.     [(set (subreg:SI (match_operand:DI 0 "register_operand" "") 0)
  2443.           (subreg:SI
  2444.            (mult:DI (sign_extend:DI
  2445.                      (match_operand:SI 1 "register_operand" ""))
  2446.                     (sign_extend:DI
  2447.                      (match_operand:SI 2 "nonimmediate_operand" ""))) 0))
  2448.      (set (subreg:SI (match_dup 0) 1)
  2449.           (subreg:SI
  2450.            (mult:DI (sign_extend:DI
  2451.                      (match_dup 1))
  2452.                     (sign_extend:DI
  2453.                      (match_dup 2))) 1))])]
  2454.   ""
  2455.   "")
  2456.  
  2457. (define_insn ""
  2458.   [(set (match_operand:SI 0 "register_operand" "=a")
  2459.         (subreg:SI
  2460.          (mult:DI (sign_extend:DI
  2461.                    (match_operand:SI 1 "register_operand" "0"))
  2462.                   (sign_extend:DI
  2463.                    (match_operand:SI 2 "nonimmediate_operand" "rm"))) 0))
  2464.    (set (match_operand:SI 3 "register_operand" "=d")
  2465.         (subreg:SI
  2466.          (mult:DI (sign_extend:DI
  2467.                    (match_dup 1))
  2468.                   (sign_extend:DI
  2469.                    (match_dup 2))) 1))]
  2470.   ""
  2471.   "imul%L0 %2")
  2472.  
  2473. (define_insn ""
  2474.   [(set (match_operand:SI 0 "register_operand" "=a")
  2475.         (subreg:SI
  2476.          (mult:DI (sign_extend:DI
  2477.                    (match_operand:SI 1 "register_operand" "0"))
  2478.                   (sign_extend:DI
  2479.                    (match_operand:SI 2 "immediate_operand" "n"))) 0))
  2480.    (set (match_operand:SI 3 "register_operand" "=d")
  2481.         (subreg:SI
  2482.          (mult:DI (sign_extend:DI
  2483.                    (match_dup 1))
  2484.                   (sign_extend:DI
  2485.                    (match_dup 2))) 1))]
  2486.   ""
  2487.   "imul%L0 %2")
  2488.  
  2489. ;;- divide instructions
  2490.  
  2491. (define_insn "divqi3"
  2492.   [(set (match_operand:QI 0 "general_operand" "=a")
  2493.     (div:QI (match_operand:HI 1 "general_operand" "0")
  2494.         (match_operand:QI 2 "general_operand" "qm")))]
  2495.   ""
  2496.   "idiv%B0 %2")
  2497.  
  2498. (define_insn "udivqi3"
  2499.   [(set (match_operand:QI 0 "general_operand" "=a")
  2500.     (udiv:QI (match_operand:HI 1 "general_operand" "0")
  2501.          (match_operand:QI 2 "general_operand" "qm")))]
  2502.   ""
  2503.   "div%B0 %2")
  2504.  
  2505. ;; The patterns that match these are at the end of this file.
  2506.  
  2507. (define_expand "divxf3"
  2508.   [(set (match_operand:XF 0 "register_operand" "")
  2509.     (div:XF (match_operand:XF 1 "nonimmediate_operand" "")
  2510.         (match_operand:XF 2 "nonimmediate_operand" "")))]
  2511.   "TARGET_80387"
  2512.   "")
  2513.  
  2514. (define_expand "divdf3"
  2515.   [(set (match_operand:DF 0 "register_operand" "")
  2516.     (div:DF (match_operand:DF 1 "nonimmediate_operand" "")
  2517.         (match_operand:DF 2 "nonimmediate_operand" "")))]
  2518.   "TARGET_80387"
  2519.   "")
  2520.  
  2521. (define_expand "divsf3"
  2522.   [(set (match_operand:SF 0 "register_operand" "")
  2523.     (div:SF (match_operand:SF 1 "nonimmediate_operand" "")
  2524.         (match_operand:SF 2 "nonimmediate_operand" "")))]
  2525.   "TARGET_80387"
  2526.   "")
  2527.  
  2528. ;; Remainder instructions.
  2529.  
  2530. (define_insn "divmodsi4"
  2531.   [(set (match_operand:SI 0 "register_operand" "=a")
  2532.     (div:SI (match_operand:SI 1 "register_operand" "0")
  2533.         (match_operand:SI 2 "general_operand" "rm")))
  2534.    (set (match_operand:SI 3 "register_operand" "=&d")
  2535.     (mod:SI (match_dup 1) (match_dup 2)))]
  2536.   ""
  2537.   "*
  2538. {
  2539. #ifdef INTEL_SYNTAX
  2540.   output_asm_insn (\"cdq\", operands);
  2541. #else
  2542.   output_asm_insn (\"cltd\", operands);
  2543. #endif
  2544.   return AS1 (idiv%L0,%2);
  2545. }")
  2546.  
  2547. (define_insn "divmodhi4"
  2548.   [(set (match_operand:HI 0 "register_operand" "=a")
  2549.     (div:HI (match_operand:HI 1 "register_operand" "0")
  2550.         (match_operand:HI 2 "general_operand" "rm")))
  2551.    (set (match_operand:HI 3 "register_operand" "=&d")
  2552.     (mod:HI (match_dup 1) (match_dup 2)))]
  2553.   ""
  2554.   "cwtd\;idiv%W0 %2")
  2555.  
  2556. ;; ??? Can we make gcc zero extend operand[0]?
  2557. (define_insn "udivmodsi4"
  2558.   [(set (match_operand:SI 0 "register_operand" "=a")
  2559.     (udiv:SI (match_operand:SI 1 "register_operand" "0")
  2560.          (match_operand:SI 2 "general_operand" "rm")))
  2561.    (set (match_operand:SI 3 "register_operand" "=&d")
  2562.     (umod:SI (match_dup 1) (match_dup 2)))]
  2563.   ""
  2564.   "*
  2565. {
  2566.   output_asm_insn (AS2 (xor%L3,%3,%3), operands);
  2567.   return AS1 (div%L0,%2);
  2568. }")
  2569.  
  2570. ;; ??? Can we make gcc zero extend operand[0]?
  2571. (define_insn "udivmodhi4"
  2572.   [(set (match_operand:HI 0 "register_operand" "=a")
  2573.     (udiv:HI (match_operand:HI 1 "register_operand" "0")
  2574.          (match_operand:HI 2 "general_operand" "rm")))
  2575.    (set (match_operand:HI 3 "register_operand" "=&d")
  2576.     (umod:HI (match_dup 1) (match_dup 2)))]
  2577.   ""
  2578.   "*
  2579. {
  2580.   output_asm_insn (AS2 (xor%W0,%3,%3), operands);
  2581.   return AS1 (div%W0,%2);
  2582. }")
  2583.  
  2584. /*
  2585. ;;this should be a valid double division which we may want to add
  2586.  
  2587. (define_insn ""
  2588.   [(set (match_operand:SI 0 "register_operand" "=a")
  2589.     (udiv:DI (match_operand:DI 1 "register_operand" "a")
  2590.          (match_operand:SI 2 "general_operand" "rm")))
  2591.    (set (match_operand:SI 3 "register_operand" "=d")
  2592.     (umod:SI (match_dup 1) (match_dup 2)))]
  2593.   ""
  2594.   "div%L0 %2,%0")
  2595. */
  2596.  
  2597. ;;- and instructions
  2598.  
  2599. ;; On i386,
  2600. ;;            movzbl %bl,%ebx
  2601. ;; is faster than
  2602. ;;            andl $255,%ebx
  2603. ;;
  2604. ;; but if the reg is %eax, then the "andl" is faster.
  2605. ;;
  2606. ;; On i486, the "andl" is always faster than the "movzbl".
  2607. ;;
  2608. ;; On both i386 and i486, a three operand AND is as fast with movzbl or
  2609. ;; movzwl as with andl, if operands[0] != operands[1].
  2610.  
  2611. ;; The `r' in `rm' for operand 3 looks redundant, but it causes
  2612. ;; optional reloads to be generated if op 3 is a pseudo in a stack slot.
  2613.  
  2614. ;; ??? What if we only change one byte of an offsettable memory reference?
  2615. (define_insn "andsi3"
  2616.   [(set (match_operand:SI 0 "general_operand" "=r,r,rm,r")
  2617.     (and:SI (match_operand:SI 1 "general_operand" "%rm,qm,0,0")
  2618.         (match_operand:SI 2 "general_operand" "L,K,ri,rm")))]
  2619.   ""
  2620.   "*
  2621. {
  2622.   if (GET_CODE (operands[2]) == CONST_INT
  2623.       && ! (GET_CODE (operands[0]) == MEM && MEM_VOLATILE_P (operands[0])))
  2624.     {
  2625.       if (INTVAL (operands[2]) == 0xffff && REG_P (operands[0])
  2626.       && (! REG_P (operands[1])
  2627.           || REGNO (operands[0]) != 0 || REGNO (operands[1]) != 0)
  2628.       && (! TARGET_486 || ! rtx_equal_p (operands[0], operands[1])))
  2629.     {
  2630.       /* ??? tege: Should forget CC_STATUS only if we clobber a
  2631.          remembered operand.  Fix that later.  */
  2632.       CC_STATUS_INIT;
  2633. #ifdef INTEL_SYNTAX
  2634.       return AS2 (movzx,%w1,%0);
  2635. #else
  2636.       return AS2 (movz%W0%L0,%w1,%0);
  2637. #endif
  2638.     }
  2639.  
  2640.       if (INTVAL (operands[2]) == 0xff && REG_P (operands[0])
  2641.       && !(REG_P (operands[1]) && NON_QI_REG_P (operands[1]))
  2642.       && (! REG_P (operands[1])
  2643.           || REGNO (operands[0]) != 0 || REGNO (operands[1]) != 0)
  2644.       && (! TARGET_486 || ! rtx_equal_p (operands[0], operands[1])))
  2645.     {
  2646.       /* ??? tege: Should forget CC_STATUS only if we clobber a
  2647.          remembered operand.  Fix that later.  */
  2648.       CC_STATUS_INIT;
  2649. #ifdef INTEL_SYNTAX
  2650.       return AS2 (movzx,%b1,%0);
  2651. #else
  2652.       return AS2 (movz%B0%L0,%b1,%0);
  2653. #endif
  2654.     }
  2655.  
  2656.       if (QI_REG_P (operands[0]) && ~(INTVAL (operands[2]) | 0xff) == 0)
  2657.     {
  2658.       CC_STATUS_INIT;
  2659.  
  2660.       if (INTVAL (operands[2]) == 0xffffff00)
  2661.         {
  2662.           operands[2] = const0_rtx;
  2663.           return AS2 (mov%B0,%2,%b0);
  2664.         }
  2665.  
  2666.       operands[2] = GEN_INT (INTVAL (operands[2]) & 0xff);
  2667.       return AS2 (and%B0,%2,%b0);
  2668.     }
  2669.  
  2670.       if (QI_REG_P (operands[0]) && ~(INTVAL (operands[2]) | 0xff00) == 0)
  2671.     {
  2672.       CC_STATUS_INIT;
  2673.  
  2674.       if (INTVAL (operands[2]) == 0xffff00ff)
  2675.         {
  2676.           operands[2] = const0_rtx;
  2677.           return AS2 (mov%B0,%2,%h0);
  2678.         }
  2679.  
  2680.       operands[2] = GEN_INT ((INTVAL (operands[2]) >> 8) & 0xff);
  2681.       return AS2 (and%B0,%2,%h0);
  2682.     }
  2683.  
  2684.       if (GET_CODE (operands[0]) == MEM && INTVAL (operands[2]) == 0xffff0000)
  2685.         {
  2686.       operands[2] = const0_rtx;
  2687.       return AS2 (mov%W0,%2,%w0);
  2688.     }
  2689.     }
  2690.  
  2691.   return AS2 (and%L0,%2,%0);
  2692. }")
  2693.  
  2694. (define_insn "andhi3"
  2695.   [(set (match_operand:HI 0 "general_operand" "=rm,r")
  2696.     (and:HI (match_operand:HI 1 "general_operand" "%0,0")
  2697.         (match_operand:HI 2 "general_operand" "ri,rm")))]
  2698.   ""
  2699.   "*
  2700. {
  2701.   if (GET_CODE (operands[2]) == CONST_INT
  2702.       && ! (GET_CODE (operands[0]) == MEM && MEM_VOLATILE_P (operands[0])))
  2703.     {
  2704.       /* Can we ignore the upper byte? */
  2705.       if ((! REG_P (operands[0]) || QI_REG_P (operands[0]))
  2706.       && (INTVAL (operands[2]) & 0xff00) == 0xff00)
  2707.     {
  2708.       CC_STATUS_INIT;
  2709.  
  2710.       if ((INTVAL (operands[2]) & 0xff) == 0)
  2711.         {
  2712.           operands[2] = const0_rtx;
  2713.           return AS2 (mov%B0,%2,%b0);
  2714.         }
  2715.  
  2716.       operands[2] = GEN_INT (INTVAL (operands[2]) & 0xff);
  2717.       return AS2 (and%B0,%2,%b0);
  2718.     }
  2719.  
  2720.       /* Can we ignore the lower byte? */
  2721.       /* ??? what about offsettable memory references? */
  2722.       if (QI_REG_P (operands[0]) && (INTVAL (operands[2]) & 0xff) == 0xff)
  2723.     {
  2724.       CC_STATUS_INIT;
  2725.  
  2726.       if ((INTVAL (operands[2]) & 0xff00) == 0)
  2727.         {
  2728.           operands[2] = const0_rtx;
  2729.           return AS2 (mov%B0,%2,%h0);
  2730.         }
  2731.  
  2732.       operands[2] = GEN_INT ((INTVAL (operands[2]) >> 8) & 0xff);
  2733.       return AS2 (and%B0,%2,%h0);
  2734.     }
  2735.     }
  2736.  
  2737.   return AS2 (and%W0,%2,%0);
  2738. }")
  2739.  
  2740. (define_insn "andqi3"
  2741.   [(set (match_operand:QI 0 "general_operand" "=qm,q")
  2742.     (and:QI (match_operand:QI 1 "general_operand" "%0,0")
  2743.         (match_operand:QI 2 "general_operand" "qn,qmn")))]
  2744.   ""
  2745.   "* return AS2 (and%B0,%2,%0);")
  2746.  
  2747. /* I am nervous about these two.. add them later..
  2748. ;I presume this means that we have something in say op0= eax which is small
  2749. ;and we want to and it with memory so we can do this by just an
  2750. ;andb m,%al  and have success.
  2751. (define_insn ""
  2752.   [(set (match_operand:SI 0 "general_operand" "=r")
  2753.     (and:SI (zero_extend:SI
  2754.          (match_operand:HI 1 "nonimmediate_operand" "rm"))
  2755.         (match_operand:SI 2 "general_operand" "0")))]
  2756.   "GET_CODE (operands[2]) == CONST_INT
  2757.    && (unsigned int) INTVAL (operands[2]) < (1 << GET_MODE_BITSIZE (HImode))"
  2758.   "and%W0 %1,%0")
  2759.  
  2760. (define_insn ""
  2761.   [(set (match_operand:SI 0 "general_operand" "=q")
  2762.     (and:SI
  2763.      (zero_extend:SI (match_operand:QI 1 "nonimmediate_operand" "qm"))
  2764.         (match_operand:SI 2 "general_operand" "0")))]
  2765.   "GET_CODE (operands[2]) == CONST_INT
  2766.    && (unsigned int) INTVAL (operands[2]) < (1 << GET_MODE_BITSIZE (QImode))"
  2767.   "and%L0 %1,%0")
  2768.  
  2769. */
  2770.  
  2771. ;;- Bit set (inclusive or) instructions
  2772.  
  2773. ;; ??? What if we only change one byte of an offsettable memory reference?
  2774. (define_insn "iorsi3"
  2775.   [(set (match_operand:SI 0 "general_operand" "=rm,r")
  2776.     (ior:SI (match_operand:SI 1 "general_operand" "%0,0")
  2777.         (match_operand:SI 2 "general_operand" "ri,rm")))]
  2778.   ""
  2779.   "*
  2780. {
  2781.   if (GET_CODE (operands[2]) == CONST_INT
  2782.       && ! (GET_CODE (operands[0]) == MEM && MEM_VOLATILE_P (operands[0])))
  2783.     {
  2784.       if ((! REG_P (operands[0]) || QI_REG_P (operands[0]))
  2785.       && (INTVAL (operands[2]) & ~0xff) == 0)
  2786.     {
  2787.       CC_STATUS_INIT;
  2788.  
  2789.       if (INTVAL (operands[2]) == 0xff)
  2790.         return AS2 (mov%B0,%2,%b0);
  2791.  
  2792.       return AS2 (or%B0,%2,%b0);
  2793.     }
  2794.  
  2795.       if (QI_REG_P (operands[0]) && (INTVAL (operands[2]) & ~0xff00) == 0)
  2796.     {
  2797.       CC_STATUS_INIT;
  2798.       operands[2] = GEN_INT (INTVAL (operands[2]) >> 8);
  2799.  
  2800.       if (INTVAL (operands[2]) == 0xff)
  2801.         return AS2 (mov%B0,%2,%h0);
  2802.  
  2803.       return AS2 (or%B0,%2,%h0);
  2804.     }
  2805.     }
  2806.  
  2807.   return AS2 (or%L0,%2,%0);
  2808. }")
  2809.  
  2810. (define_insn "iorhi3"
  2811.   [(set (match_operand:HI 0 "general_operand" "=rm,r")
  2812.     (ior:HI (match_operand:HI 1 "general_operand" "%0,0")
  2813.         (match_operand:HI 2 "general_operand" "ri,rm")))]
  2814.   ""
  2815.   "*
  2816. {
  2817.   if (GET_CODE (operands[2]) == CONST_INT
  2818.       && ! (GET_CODE (operands[0]) == MEM && MEM_VOLATILE_P (operands[0])))
  2819.     {
  2820.       /* Can we ignore the upper byte? */
  2821.       if ((! REG_P (operands[0]) || QI_REG_P (operands[0]))
  2822.       && (INTVAL (operands[2]) & 0xff00) == 0)
  2823.     {
  2824.       CC_STATUS_INIT;
  2825.       if (INTVAL (operands[2]) & 0xffff0000)
  2826.         operands[2] = GEN_INT (INTVAL (operands[2]) & 0xffff);
  2827.  
  2828.       if (INTVAL (operands[2]) == 0xff)
  2829.         return AS2 (mov%B0,%2,%b0);
  2830.  
  2831.       return AS2 (or%B0,%2,%b0);
  2832.     }
  2833.  
  2834.       /* Can we ignore the lower byte? */
  2835.       /* ??? what about offsettable memory references? */
  2836.       if (QI_REG_P (operands[0])
  2837.       && (INTVAL (operands[2]) & 0xff) == 0)
  2838.     {
  2839.       CC_STATUS_INIT;
  2840.       operands[2] = GEN_INT ((INTVAL (operands[2]) >> 8) & 0xff);
  2841.  
  2842.       if (INTVAL (operands[2]) == 0xff)
  2843.         return AS2 (mov%B0,%2,%h0);
  2844.  
  2845.       return AS2 (or%B0,%2,%h0);
  2846.     }
  2847.     }
  2848.  
  2849.   return AS2 (or%W0,%2,%0);
  2850. }")
  2851.  
  2852. (define_insn "iorqi3"
  2853.   [(set (match_operand:QI 0 "general_operand" "=qm,q")
  2854.     (ior:QI (match_operand:QI 1 "general_operand" "%0,0")
  2855.         (match_operand:QI 2 "general_operand" "qn,qmn")))]
  2856.   ""
  2857.   "* return AS2 (or%B0,%2,%0);")
  2858.  
  2859. ;;- xor instructions
  2860.  
  2861. ;; ??? What if we only change one byte of an offsettable memory reference?
  2862. (define_insn "xorsi3"
  2863.   [(set (match_operand:SI 0 "general_operand" "=rm,r")
  2864.     (xor:SI (match_operand:SI 1 "general_operand" "%0,0")
  2865.         (match_operand:SI 2 "general_operand" "ri,rm")))]
  2866.   ""
  2867.   "*
  2868. {
  2869.   if (GET_CODE (operands[2]) == CONST_INT
  2870.       && ! (GET_CODE (operands[0]) == MEM && MEM_VOLATILE_P (operands[0])))
  2871.     {
  2872.       if ((! REG_P (operands[0]) || QI_REG_P (operands[0]))
  2873.       && (INTVAL (operands[2]) & ~0xff) == 0)
  2874.     {
  2875.       CC_STATUS_INIT;
  2876.  
  2877.       if (INTVAL (operands[2]) == 0xff)
  2878.         return AS1 (not%B0,%b0);
  2879.  
  2880.       return AS2 (xor%B0,%2,%b0);
  2881.     }
  2882.  
  2883.       if (QI_REG_P (operands[0]) && (INTVAL (operands[2]) & ~0xff00) == 0)
  2884.     {
  2885.       CC_STATUS_INIT;
  2886.       operands[2] = GEN_INT (INTVAL (operands[2]) >> 8);
  2887.  
  2888.       if (INTVAL (operands[2]) == 0xff)
  2889.         return AS1 (not%B0,%h0);
  2890.  
  2891.       return AS2 (xor%B0,%2,%h0);
  2892.     }
  2893.     }
  2894.  
  2895.   return AS2 (xor%L0,%2,%0);
  2896. }")
  2897.  
  2898. (define_insn "xorhi3"
  2899.   [(set (match_operand:HI 0 "general_operand" "=rm,r")
  2900.     (xor:HI (match_operand:HI 1 "general_operand" "%0,0")
  2901.         (match_operand:HI 2 "general_operand" "ri,rm")))]
  2902.   ""
  2903.   "*
  2904. {
  2905.   if (GET_CODE (operands[2]) == CONST_INT
  2906.       && ! (GET_CODE (operands[0]) == MEM && MEM_VOLATILE_P (operands[0])))
  2907.     {
  2908.       /* Can we ignore the upper byte? */
  2909.       if ((! REG_P (operands[0]) || QI_REG_P (operands[0]))
  2910.       && (INTVAL (operands[2]) & 0xff00) == 0)
  2911.     {
  2912.       CC_STATUS_INIT;
  2913.       if (INTVAL (operands[2]) & 0xffff0000)
  2914.         operands[2] = GEN_INT (INTVAL (operands[2]) & 0xffff);
  2915.  
  2916.       if (INTVAL (operands[2]) == 0xff)
  2917.         return AS1 (not%B0,%b0);
  2918.  
  2919.       return AS2 (xor%B0,%2,%b0);
  2920.     }
  2921.  
  2922.       /* Can we ignore the lower byte? */
  2923.       /* ??? what about offsettable memory references? */
  2924.       if (QI_REG_P (operands[0])
  2925.       && (INTVAL (operands[2]) & 0xff) == 0)
  2926.     {
  2927.       CC_STATUS_INIT;
  2928.       operands[2] = GEN_INT ((INTVAL (operands[2]) >> 8) & 0xff);
  2929.  
  2930.       if (INTVAL (operands[2]) == 0xff)
  2931.         return AS1 (not%B0,%h0);
  2932.  
  2933.       return AS2 (xor%B0,%2,%h0);
  2934.     }
  2935.     }
  2936.  
  2937.   return AS2 (xor%W0,%2,%0);
  2938. }")
  2939.  
  2940. (define_insn "xorqi3"
  2941.   [(set (match_operand:QI 0 "general_operand" "=qm,q")
  2942.     (xor:QI (match_operand:QI 1 "general_operand" "%0,0")
  2943.         (match_operand:QI 2 "general_operand" "qn,qm")))]
  2944.   ""
  2945.   "* return AS2 (xor%B0,%2,%0);")
  2946.  
  2947. ;;- negation instructions
  2948.  
  2949. (define_insn "negdi2"
  2950.   [(set (match_operand:DI 0 "general_operand" "=&ro")
  2951.     (neg:DI (match_operand:DI 1 "general_operand" "0")))]
  2952.   ""
  2953.   "*
  2954. {
  2955.   rtx xops[2], low[1], high[1];
  2956.  
  2957.   CC_STATUS_INIT;
  2958.  
  2959.   split_di (operands, 1, low, high);
  2960.   xops[0] = const0_rtx;
  2961.   xops[1] = high[0];
  2962.  
  2963.   output_asm_insn (AS1 (neg%L0,%0), low);
  2964.   output_asm_insn (AS2 (adc%L1,%0,%1), xops);
  2965.   output_asm_insn (AS1 (neg%L0,%0), high);
  2966.   RET;
  2967. }")
  2968.  
  2969. (define_insn "negsi2"
  2970.   [(set (match_operand:SI 0 "general_operand" "=rm")
  2971.     (neg:SI (match_operand:SI 1 "general_operand" "0")))]
  2972.   ""
  2973.   "neg%L0 %0")
  2974.  
  2975. (define_insn "neghi2"
  2976.   [(set (match_operand:HI 0 "general_operand" "=rm")
  2977.     (neg:HI (match_operand:HI 1 "general_operand" "0")))]
  2978.   ""
  2979.   "neg%W0 %0")
  2980.  
  2981. (define_insn "negqi2"
  2982.   [(set (match_operand:QI 0 "general_operand" "=qm")
  2983.     (neg:QI (match_operand:QI 1 "general_operand" "0")))]
  2984.   ""
  2985.   "neg%B0 %0")
  2986.  
  2987. (define_insn "negsf2"
  2988.   [(set (match_operand:SF 0 "register_operand" "=f")
  2989.     (neg:SF (match_operand:SF 1 "general_operand" "0")))]
  2990.   "TARGET_80387"
  2991.   "fchs")
  2992.  
  2993. (define_insn "negdf2"
  2994.   [(set (match_operand:DF 0 "register_operand" "=f")
  2995.     (neg:DF (match_operand:DF 1 "general_operand" "0")))]
  2996.   "TARGET_80387"
  2997.   "fchs")
  2998.  
  2999. (define_insn ""
  3000.   [(set (match_operand:DF 0 "register_operand" "=f")
  3001.     (neg:DF (float_extend:DF (match_operand:SF 1 "general_operand" "0"))))]
  3002.   "TARGET_80387"
  3003.   "fchs")
  3004.  
  3005. (define_insn "negxf2"
  3006.   [(set (match_operand:XF 0 "register_operand" "=f")
  3007.     (neg:XF (match_operand:XF 1 "general_operand" "0")))]
  3008.   "TARGET_80387"
  3009.   "fchs")
  3010.  
  3011. (define_insn ""
  3012.   [(set (match_operand:XF 0 "register_operand" "=f")
  3013.     (neg:XF (float_extend:XF (match_operand:DF 1 "general_operand" "0"))))]
  3014.   "TARGET_80387"
  3015.   "fchs")
  3016.  
  3017. ;; Absolute value instructions
  3018.  
  3019. (define_insn "abssf2"
  3020.   [(set (match_operand:SF 0 "register_operand" "=f")
  3021.     (abs:SF (match_operand:SF 1 "general_operand" "0")))]
  3022.   "TARGET_80387"
  3023.   "fabs")
  3024.  
  3025. (define_insn "absdf2"
  3026.   [(set (match_operand:DF 0 "register_operand" "=f")
  3027.     (abs:DF (match_operand:DF 1 "general_operand" "0")))]
  3028.   "TARGET_80387"
  3029.   "fabs")
  3030.  
  3031. (define_insn ""
  3032.   [(set (match_operand:DF 0 "register_operand" "=f")
  3033.     (abs:DF (float_extend:DF (match_operand:SF 1 "general_operand" "0"))))]
  3034.   "TARGET_80387"
  3035.   "fabs")
  3036.  
  3037. (define_insn "absxf2"
  3038.   [(set (match_operand:XF 0 "register_operand" "=f")
  3039.     (abs:XF (match_operand:XF 1 "general_operand" "0")))]
  3040.   "TARGET_80387"
  3041.   "fabs")
  3042.  
  3043. (define_insn ""
  3044.   [(set (match_operand:XF 0 "register_operand" "=f")
  3045.     (abs:XF (float_extend:XF (match_operand:DF 1 "general_operand" "0"))))]
  3046.   "TARGET_80387"
  3047.   "fabs")
  3048.  
  3049. (define_insn "sqrtsf2"
  3050.   [(set (match_operand:SF 0 "register_operand" "=f")
  3051.     (sqrt:SF (match_operand:SF 1 "general_operand" "0")))]
  3052.   "TARGET_80387 && (TARGET_IEEE_FP || flag_fast_math)"
  3053.   "fsqrt"
  3054.   [(set_attr "fppc" "single")])
  3055.  
  3056. (define_insn "sqrtdf2"
  3057.   [(set (match_operand:DF 0 "register_operand" "=f")
  3058.     (sqrt:DF (match_operand:DF 1 "general_operand" "0")))]
  3059.   "TARGET_80387 && (TARGET_IEEE_FP || flag_fast_math)"
  3060.   "fsqrt"
  3061.   [(set_attr "fppc" "double")])
  3062.  
  3063. (define_insn ""
  3064.   [(set (match_operand:DF 0 "register_operand" "=f")
  3065.     (sqrt:DF (float_extend:DF
  3066.           (match_operand:SF 1 "general_operand" "0"))))]
  3067.   "TARGET_80387 && (TARGET_IEEE_FP || flag_fast_math)"
  3068.   "fsqrt"
  3069.   [(set_attr "fppc" "double")])
  3070.  
  3071. (define_insn "sqrtxf2"
  3072.   [(set (match_operand:XF 0 "register_operand" "=f")
  3073.     (sqrt:XF (match_operand:XF 1 "general_operand" "0")))]
  3074.   "TARGET_80387 && (TARGET_IEEE_FP || flag_fast_math)"
  3075.   "fsqrt")
  3076.  
  3077. (define_insn ""
  3078.   [(set (match_operand:XF 0 "register_operand" "=f")
  3079.     (sqrt:XF (float_extend:XF
  3080.           (match_operand:DF 1 "general_operand" "0"))))]
  3081.   "TARGET_80387 && (TARGET_IEEE_FP || flag_fast_math)"
  3082.   "fsqrt")
  3083.  
  3084. (define_insn ""
  3085.   [(set (match_operand:XF 0 "register_operand" "=f")
  3086.     (sqrt:XF (float_extend:XF
  3087.           (match_operand:SF 1 "general_operand" "0"))))]
  3088.   "TARGET_80387 && (TARGET_IEEE_FP || flag_fast_math)"
  3089.   "fsqrt")
  3090.  
  3091. (define_insn "sindf2"
  3092.   [(set (match_operand:DF 0 "register_operand" "=f")
  3093.     (unspec:DF [(match_operand:DF 1 "register_operand" "0")] 1))]
  3094.   "TARGET_80387 && (TARGET_IEEE_FP || flag_fast_math)"
  3095.   "fsin"
  3096.   [(set_attr "fppc" "double")])
  3097.  
  3098. (define_insn "sinsf2"
  3099.   [(set (match_operand:SF 0 "register_operand" "=f")
  3100.     (unspec:SF [(match_operand:SF 1 "register_operand" "0")] 1))]
  3101.   "TARGET_80387 && (TARGET_IEEE_FP || flag_fast_math)"
  3102.   "fsin"
  3103.   [(set_attr "fppc" "single")])
  3104.  
  3105. (define_insn ""
  3106.   [(set (match_operand:DF 0 "register_operand" "=f")
  3107.     (unspec:DF [(float_extend:DF
  3108.              (match_operand:SF 1 "register_operand" "0"))] 1))]
  3109.   "TARGET_80387 && (TARGET_IEEE_FP || flag_fast_math)"
  3110.   "fsin"
  3111.   [(set_attr "fppc" "double")])
  3112.  
  3113. (define_insn "cosdf2"
  3114.   [(set (match_operand:DF 0 "register_operand" "=f")
  3115.     (unspec:DF [(match_operand:DF 1 "register_operand" "0")] 2))]
  3116.   "TARGET_80387 && (TARGET_IEEE_FP || flag_fast_math)"
  3117.   "fcos"
  3118.   [(set_attr "fppc" "double")])
  3119.  
  3120. (define_insn "cossf2"
  3121.   [(set (match_operand:SF 0 "register_operand" "=f")
  3122.     (unspec:SF [(match_operand:SF 1 "register_operand" "0")] 2))]
  3123.   "TARGET_80387 && (TARGET_IEEE_FP || flag_fast_math)"
  3124.   "fcos"
  3125.   [(set_attr "fppc" "single")])
  3126.  
  3127. (define_insn ""
  3128.   [(set (match_operand:DF 0 "register_operand" "=f")
  3129.     (unspec:DF [(float_extend:DF
  3130.              (match_operand:SF 1 "register_operand" "0"))] 2))]
  3131.   "TARGET_80387 && (TARGET_IEEE_FP || flag_fast_math)"
  3132.   "fcos"
  3133.   [(set_attr "fppc" "double")])
  3134.  
  3135. ;;- one complement instructions
  3136.  
  3137. (define_insn "one_cmplsi2"
  3138.   [(set (match_operand:SI 0 "general_operand" "=rm")
  3139.     (not:SI (match_operand:SI 1 "general_operand" "0")))]
  3140.   ""
  3141.   "not%L0 %0")
  3142.  
  3143. (define_insn "one_cmplhi2"
  3144.   [(set (match_operand:HI 0 "general_operand" "=rm")
  3145.     (not:HI (match_operand:HI 1 "general_operand" "0")))]
  3146.   ""
  3147.   "not%W0 %0")
  3148.  
  3149. (define_insn "one_cmplqi2"
  3150.   [(set (match_operand:QI 0 "general_operand" "=qm")
  3151.     (not:QI (match_operand:QI 1 "general_operand" "0")))]
  3152.   ""
  3153.   "not%B0 %0")
  3154.  
  3155. ;;- arithmetic shift instructions
  3156.  
  3157. ;; DImode shifts are implemented using the i386 "shift double" opcode,
  3158. ;; which is written as "sh[lr]d[lw] imm,reg,reg/mem".  If the shift count
  3159. ;; is variable, then the count is in %cl and the "imm" operand is dropped
  3160. ;; from the assembler input.
  3161.  
  3162. ;; This instruction shifts the target reg/mem as usual, but instead of
  3163. ;; shifting in zeros, bits are shifted in from reg operand.  If the insn
  3164. ;; is a left shift double, bits are taken from the high order bits of
  3165. ;; reg, else if the insn is a shift right double, bits are taken from the
  3166. ;; low order bits of reg.  So if %eax is "1234" and %edx is "5678",
  3167. ;; "shldl $8,%edx,%eax" leaves %edx unchanged and sets %eax to "2345".
  3168.  
  3169. ;; Since sh[lr]d does not change the `reg' operand, that is done
  3170. ;; separately, making all shifts emit pairs of shift double and normal
  3171. ;; shift.  Since sh[lr]d does not shift more than 31 bits, and we wish to
  3172. ;; support a 63 bit shift, each shift where the count is in a reg expands
  3173. ;; to three pairs.  If the overall shift is by N bits, then the first two
  3174. ;; pairs shift by N / 2 and the last pair by N & 1.
  3175.  
  3176. ;; If the shift count is a constant, we need never emit more than one
  3177. ;; shift pair, instead using moves and sign extension for counts greater
  3178. ;; than 31.
  3179.  
  3180. (define_expand "ashldi3"
  3181.   [(set (match_operand:DI 0 "register_operand" "")
  3182.     (ashift:DI (match_operand:DI 1 "register_operand" "")
  3183.            (match_operand:QI 2 "nonmemory_operand" "")))]
  3184.   ""
  3185.   "
  3186. {
  3187.   if (GET_CODE (operands[2]) != CONST_INT
  3188.       || ! CONST_OK_FOR_LETTER_P (INTVAL (operands[2]), 'J'))
  3189.     {
  3190.       operands[2] = copy_to_mode_reg (QImode, operands[2]);
  3191.       emit_insn (gen_ashldi3_non_const_int (operands[0], operands[1],
  3192.                         operands[2]));
  3193.     }
  3194.   else
  3195.     emit_insn (gen_ashldi3_const_int (operands[0], operands[1], operands[2]));
  3196.  
  3197.   DONE;
  3198. }")
  3199.  
  3200. (define_insn "ashldi3_const_int"
  3201.   [(set (match_operand:DI 0 "register_operand" "=&r")
  3202.     (ashift:DI (match_operand:DI 1 "register_operand" "0")
  3203.            (match_operand:QI 2 "const_int_operand" "J")))]
  3204.   ""
  3205.   "*
  3206. {
  3207.   rtx xops[4], low[1], high[1];
  3208.  
  3209.   CC_STATUS_INIT;
  3210.  
  3211.   split_di (operands, 1, low, high);
  3212.   xops[0] = operands[2];
  3213.   xops[1] = const1_rtx;
  3214.   xops[2] = low[0];
  3215.   xops[3] = high[0];
  3216.  
  3217.   if (INTVAL (xops[0]) > 31)
  3218.     {
  3219.       output_asm_insn (AS2 (mov%L3,%2,%3), xops);    /* Fast shift by 32 */
  3220.       output_asm_insn (AS2 (xor%L2,%2,%2), xops);
  3221.  
  3222.       if (INTVAL (xops[0]) > 32)
  3223.         {
  3224.       xops[0] = GEN_INT (INTVAL (xops[0]) - 32);
  3225.       output_asm_insn (AS2 (sal%L3,%0,%3), xops); /* Remaining shift */
  3226.     }
  3227.     }
  3228.   else
  3229.     {
  3230.       output_asm_insn (AS3 (shld%L3,%0,%2,%3), xops);
  3231.       output_asm_insn (AS2 (sal%L2,%0,%2), xops);
  3232.     }
  3233.   RET;
  3234. }")
  3235.  
  3236. (define_insn "ashldi3_non_const_int"
  3237.   [(set (match_operand:DI 0 "register_operand" "=&r")
  3238.     (ashift:DI (match_operand:DI 1 "register_operand" "0")
  3239.            (match_operand:QI 2 "register_operand" "c")))
  3240.    (clobber (match_dup 2))]
  3241.   ""
  3242.   "*
  3243. {
  3244.   rtx xops[4], low[1], high[1];
  3245.  
  3246.   CC_STATUS_INIT;
  3247.  
  3248.   split_di (operands, 1, low, high);
  3249.   xops[0] = operands[2];
  3250.   xops[1] = const1_rtx;
  3251.   xops[2] = low[0];
  3252.   xops[3] = high[0];
  3253.  
  3254.   output_asm_insn (AS2 (ror%B0,%1,%0), xops);    /* shift count / 2 */
  3255.  
  3256.   output_asm_insn (AS3_SHIFT_DOUBLE (shld%L3,%0,%2,%3), xops);
  3257.   output_asm_insn (AS2 (sal%L2,%0,%2), xops);
  3258.   output_asm_insn (AS3_SHIFT_DOUBLE (shld%L3,%0,%2,%3), xops);
  3259.   output_asm_insn (AS2 (sal%L2,%0,%2), xops);
  3260.  
  3261.   xops[1] = GEN_INT (7);            /* shift count & 1 */
  3262.  
  3263.   output_asm_insn (AS2 (shr%B0,%1,%0), xops);
  3264.  
  3265.   output_asm_insn (AS3_SHIFT_DOUBLE (shld%L3,%0,%2,%3), xops);
  3266.   output_asm_insn (AS2 (sal%L2,%0,%2), xops);
  3267.  
  3268.   RET;
  3269. }")
  3270.  
  3271. ;; On i386 and i486, "addl reg,reg" is faster than "sall $1,reg"
  3272. ;; On i486, movl/sall appears slightly faster than leal, but the leal
  3273. ;; is smaller - use leal for now unless the shift count is 1.
  3274.  
  3275. (define_insn "ashlsi3"
  3276.   [(set (match_operand:SI 0 "general_operand" "=r,rm")
  3277.     (ashift:SI (match_operand:SI 1 "general_operand" "r,0")
  3278.            (match_operand:SI 2 "nonmemory_operand" "M,cI")))]
  3279.   ""
  3280.   "*
  3281. {
  3282.   if (REG_P (operands[0]) && REGNO (operands[0]) != REGNO (operands[1]))
  3283.     {
  3284.       if (TARGET_486 && INTVAL (operands[2]) == 1)
  3285.     {
  3286.       output_asm_insn (AS2 (mov%L0,%1,%0), operands);
  3287.       return AS2 (add%L0,%1,%0);
  3288.     }
  3289.       else
  3290.         {
  3291.           CC_STATUS_INIT;
  3292.  
  3293.       if (operands[1] == stack_pointer_rtx)
  3294.         {
  3295.           output_asm_insn (AS2 (mov%L0,%1,%0), operands);
  3296.           operands[1] = operands[0];
  3297.         }
  3298.           operands[1] = gen_rtx (MULT, SImode, operands[1],
  3299.                  GEN_INT (1 << INTVAL (operands[2])));
  3300.       return AS2 (lea%L0,%a1,%0);
  3301.     }
  3302.     }
  3303.  
  3304.   if (REG_P (operands[2]))
  3305.     return AS2 (sal%L0,%b2,%0);
  3306.  
  3307.   if (REG_P (operands[0]) && operands[2] == const1_rtx)
  3308.     return AS2 (add%L0,%0,%0);
  3309.  
  3310.   return AS2 (sal%L0,%2,%0);
  3311. }")
  3312.  
  3313. (define_insn "ashlhi3"
  3314.   [(set (match_operand:HI 0 "general_operand" "=rm")
  3315.     (ashift:HI (match_operand:HI 1 "general_operand" "0")
  3316.            (match_operand:HI 2 "nonmemory_operand" "cI")))]
  3317.   ""
  3318.   "*
  3319. {
  3320.   if (REG_P (operands[2]))
  3321.     return AS2 (sal%W0,%b2,%0);
  3322.  
  3323.   if (REG_P (operands[0]) && operands[2] == const1_rtx)
  3324.     return AS2 (add%W0,%0,%0);
  3325.  
  3326.   return AS2 (sal%W0,%2,%0);
  3327. }")
  3328.  
  3329. (define_insn "ashlqi3"
  3330.   [(set (match_operand:QI 0 "general_operand" "=qm")
  3331.     (ashift:QI (match_operand:QI 1 "general_operand" "0")
  3332.            (match_operand:QI 2 "nonmemory_operand" "cI")))]
  3333.   ""
  3334.   "*
  3335. {
  3336.   if (REG_P (operands[2]))
  3337.     return AS2 (sal%B0,%b2,%0);
  3338.  
  3339.   if (REG_P (operands[0]) && operands[2] == const1_rtx)
  3340.     return AS2 (add%B0,%0,%0);
  3341.  
  3342.   return AS2 (sal%B0,%2,%0);
  3343. }")
  3344.  
  3345. ;; See comment above `ashldi3' about how this works.
  3346.  
  3347. (define_expand "ashrdi3"
  3348.   [(set (match_operand:DI 0 "register_operand" "")
  3349.     (ashiftrt:DI (match_operand:DI 1 "register_operand" "")
  3350.              (match_operand:QI 2 "nonmemory_operand" "")))]
  3351.   ""
  3352.   "
  3353. {
  3354.   if (GET_CODE (operands[2]) != CONST_INT
  3355.       || ! CONST_OK_FOR_LETTER_P (INTVAL (operands[2]), 'J'))
  3356.     {
  3357.       operands[2] = copy_to_mode_reg (QImode, operands[2]);
  3358.       emit_insn (gen_ashrdi3_non_const_int (operands[0], operands[1],
  3359.                         operands[2]));
  3360.     }
  3361.   else
  3362.     emit_insn (gen_ashrdi3_const_int (operands[0], operands[1], operands[2]));
  3363.  
  3364.   DONE;
  3365. }")
  3366.  
  3367. (define_insn "ashrdi3_const_int"
  3368.   [(set (match_operand:DI 0 "register_operand" "=&r")
  3369.     (ashiftrt:DI (match_operand:DI 1 "register_operand" "0")
  3370.              (match_operand:QI 2 "const_int_operand" "J")))]
  3371.   ""
  3372.   "*
  3373. {
  3374.   rtx xops[4], low[1], high[1];
  3375.  
  3376.   CC_STATUS_INIT;
  3377.  
  3378.   split_di (operands, 1, low, high);
  3379.   xops[0] = operands[2];
  3380.   xops[1] = const1_rtx;
  3381.   xops[2] = low[0];
  3382.   xops[3] = high[0];
  3383.  
  3384.   if (INTVAL (xops[0]) > 31)
  3385.     {
  3386.       xops[1] = GEN_INT (31);
  3387.       output_asm_insn (AS2 (mov%L2,%3,%2), xops);
  3388.       output_asm_insn (AS2 (sar%L3,%1,%3), xops);    /* shift by 32 */
  3389.  
  3390.       if (INTVAL (xops[0]) > 32)
  3391.         {
  3392.       xops[0] = GEN_INT (INTVAL (xops[0]) - 32);
  3393.       output_asm_insn (AS2 (sar%L2,%0,%2), xops); /* Remaining shift */
  3394.     }
  3395.     }
  3396.   else
  3397.     {
  3398.       output_asm_insn (AS3 (shrd%L2,%0,%3,%2), xops);
  3399.       output_asm_insn (AS2 (sar%L3,%0,%3), xops);
  3400.     }
  3401.  
  3402.   RET;
  3403. }")
  3404.  
  3405. (define_insn "ashrdi3_non_const_int"
  3406.   [(set (match_operand:DI 0 "register_operand" "=&r")
  3407.     (ashiftrt:DI (match_operand:DI 1 "register_operand" "0")
  3408.              (match_operand:QI 2 "register_operand" "c")))
  3409.    (clobber (match_dup 2))]
  3410.   ""
  3411.   "*
  3412. {
  3413.   rtx xops[4], low[1], high[1];
  3414.  
  3415.   CC_STATUS_INIT;
  3416.  
  3417.   split_di (operands, 1, low, high);
  3418.   xops[0] = operands[2];
  3419.   xops[1] = const1_rtx;
  3420.   xops[2] = low[0];
  3421.   xops[3] = high[0];
  3422.  
  3423.   output_asm_insn (AS2 (ror%B0,%1,%0), xops);    /* shift count / 2 */
  3424.  
  3425.   output_asm_insn (AS3_SHIFT_DOUBLE (shrd%L2,%0,%3,%2), xops);
  3426.   output_asm_insn (AS2 (sar%L3,%0,%3), xops);
  3427.   output_asm_insn (AS3_SHIFT_DOUBLE (shrd%L2,%0,%3,%2), xops);
  3428.   output_asm_insn (AS2 (sar%L3,%0,%3), xops);
  3429.  
  3430.   xops[1] = GEN_INT (7);            /* shift count & 1 */
  3431.  
  3432.   output_asm_insn (AS2 (shr%B0,%1,%0), xops);
  3433.  
  3434.   output_asm_insn (AS3_SHIFT_DOUBLE (shrd%L2,%0,%3,%2), xops);
  3435.   output_asm_insn (AS2 (sar%L3,%0,%3), xops);
  3436.  
  3437.   RET;
  3438. }")
  3439.  
  3440. (define_insn "ashrsi3"
  3441.   [(set (match_operand:SI 0 "general_operand" "=rm")
  3442.     (ashiftrt:SI (match_operand:SI 1 "general_operand" "0")
  3443.              (match_operand:SI 2 "nonmemory_operand" "cI")))]
  3444.   ""
  3445.   "*
  3446. {
  3447.   if (REG_P (operands[2]))
  3448.     return AS2 (sar%L0,%b2,%0);
  3449.   else
  3450.     return AS2 (sar%L0,%2,%0);
  3451. }")
  3452.  
  3453. (define_insn "ashrhi3"
  3454.   [(set (match_operand:HI 0 "general_operand" "=rm")
  3455.     (ashiftrt:HI (match_operand:HI 1 "general_operand" "0")
  3456.              (match_operand:HI 2 "nonmemory_operand" "cI")))]
  3457.   ""
  3458.   "*
  3459. {
  3460.   if (REG_P (operands[2]))
  3461.     return AS2 (sar%W0,%b2,%0);
  3462.   else
  3463.     return AS2 (sar%W0,%2,%0);
  3464. }")
  3465.  
  3466. (define_insn "ashrqi3"
  3467.   [(set (match_operand:QI 0 "general_operand" "=qm")
  3468.     (ashiftrt:QI (match_operand:QI 1 "general_operand" "0")
  3469.              (match_operand:QI 2 "nonmemory_operand" "cI")))]
  3470.   ""
  3471.   "*
  3472. {
  3473.   if (REG_P (operands[2]))
  3474.     return AS2 (sar%B0,%b2,%0);
  3475.   else
  3476.     return AS2 (sar%B0,%2,%0);
  3477. }")
  3478.  
  3479. ;;- logical shift instructions
  3480.  
  3481. ;; See comment above `ashldi3' about how this works.
  3482.  
  3483. (define_expand "lshrdi3"
  3484.   [(set (match_operand:DI 0 "register_operand" "")
  3485.     (lshiftrt:DI (match_operand:DI 1 "register_operand" "")
  3486.              (match_operand:QI 2 "nonmemory_operand" "")))]
  3487.   ""
  3488.   "
  3489. {
  3490.   if (GET_CODE (operands[2]) != CONST_INT
  3491.       || ! CONST_OK_FOR_LETTER_P (INTVAL (operands[2]), 'J'))
  3492.     {
  3493.       operands[2] = copy_to_mode_reg (QImode, operands[2]);
  3494.       emit_insn (gen_lshrdi3_non_const_int (operands[0], operands[1],
  3495.                         operands[2]));
  3496.     }
  3497.   else
  3498.     emit_insn (gen_lshrdi3_const_int (operands[0], operands[1], operands[2]));
  3499.  
  3500.   DONE;
  3501. }")
  3502.  
  3503. (define_insn "lshrdi3_const_int"
  3504.   [(set (match_operand:DI 0 "register_operand" "=&r")
  3505.     (lshiftrt:DI (match_operand:DI 1 "register_operand" "0")
  3506.              (match_operand:QI 2 "const_int_operand" "J")))]
  3507.   ""
  3508.   "*
  3509. {
  3510.   rtx xops[4], low[1], high[1];
  3511.  
  3512.   CC_STATUS_INIT;
  3513.  
  3514.   split_di (operands, 1, low, high);
  3515.   xops[0] = operands[2];
  3516.   xops[1] = const1_rtx;
  3517.   xops[2] = low[0];
  3518.   xops[3] = high[0];
  3519.  
  3520.   if (INTVAL (xops[0]) > 31)
  3521.     {
  3522.       output_asm_insn (AS2 (mov%L2,%3,%2), xops);    /* Fast shift by 32 */
  3523.       output_asm_insn (AS2 (xor%L3,%3,%3), xops);
  3524.  
  3525.       if (INTVAL (xops[0]) > 32)
  3526.         {
  3527.       xops[0] = GEN_INT (INTVAL (xops[0]) - 32);
  3528.       output_asm_insn (AS2 (shr%L2,%0,%2), xops); /* Remaining shift */
  3529.     }
  3530.     }
  3531.   else
  3532.     {
  3533.       output_asm_insn (AS3 (shrd%L2,%0,%3,%2), xops);
  3534.       output_asm_insn (AS2 (shr%L3,%0,%3), xops);
  3535.     }
  3536.  
  3537.   RET;
  3538. }")
  3539.  
  3540. (define_insn "lshrdi3_non_const_int"
  3541.   [(set (match_operand:DI 0 "register_operand" "=&r")
  3542.     (lshiftrt:DI (match_operand:DI 1 "register_operand" "0")
  3543.              (match_operand:QI 2 "register_operand" "c")))
  3544.    (clobber (match_dup 2))]
  3545.   ""
  3546.   "*
  3547. {
  3548.   rtx xops[4], low[1], high[1];
  3549.  
  3550.   CC_STATUS_INIT;
  3551.  
  3552.   split_di (operands, 1, low, high);
  3553.   xops[0] = operands[2];
  3554.   xops[1] = const1_rtx;
  3555.   xops[2] = low[0];
  3556.   xops[3] = high[0];
  3557.  
  3558.   output_asm_insn (AS2 (ror%B0,%1,%0), xops);    /* shift count / 2 */
  3559.  
  3560.   output_asm_insn (AS3_SHIFT_DOUBLE (shrd%L2,%0,%3,%2), xops);
  3561.   output_asm_insn (AS2 (shr%L3,%0,%3), xops);
  3562.   output_asm_insn (AS3_SHIFT_DOUBLE (shrd%L2,%0,%3,%2), xops);
  3563.   output_asm_insn (AS2 (shr%L3,%0,%3), xops);
  3564.  
  3565.   xops[1] = GEN_INT (7);            /* shift count & 1 */
  3566.  
  3567.   output_asm_insn (AS2 (shr%B0,%1,%0), xops);
  3568.  
  3569.   output_asm_insn (AS3_SHIFT_DOUBLE (shrd%L2,%0,%3,%2), xops);
  3570.   output_asm_insn (AS2 (shr%L3,%0,%3), xops);
  3571.  
  3572.   RET;
  3573. }")
  3574.  
  3575. (define_insn "lshrsi3"
  3576.   [(set (match_operand:SI 0 "general_operand" "=rm")
  3577.     (lshiftrt:SI (match_operand:SI 1 "general_operand" "0")
  3578.              (match_operand:SI 2 "nonmemory_operand" "cI")))]
  3579.   ""
  3580.   "*
  3581. {
  3582.   if (REG_P (operands[2]))
  3583.     return AS2 (shr%L0,%b2,%0);
  3584.   else
  3585.     return AS2 (shr%L0,%2,%1);
  3586. }")
  3587.  
  3588. (define_insn "lshrhi3"
  3589.   [(set (match_operand:HI 0 "general_operand" "=rm")
  3590.     (lshiftrt:HI (match_operand:HI 1 "general_operand" "0")
  3591.              (match_operand:HI 2 "nonmemory_operand" "cI")))]
  3592.   ""
  3593.   "*
  3594. {
  3595.   if (REG_P (operands[2]))
  3596.     return AS2 (shr%W0,%b2,%0);
  3597.   else
  3598.     return AS2 (shr%W0,%2,%0);
  3599. }")
  3600.  
  3601. (define_insn "lshrqi3"
  3602.   [(set (match_operand:QI 0 "general_operand" "=qm")
  3603.     (lshiftrt:QI (match_operand:QI 1 "general_operand" "0")
  3604.              (match_operand:QI 2 "nonmemory_operand" "cI")))]
  3605.   ""
  3606.   "*
  3607. {
  3608.   if (REG_P (operands[2]))
  3609.     return AS2 (shr%B0,%b2,%0);
  3610.   else
  3611.     return AS2 (shr%B0,%2,%0);
  3612. }")
  3613.  
  3614. ;;- rotate instructions
  3615.  
  3616. (define_insn "rotlsi3"
  3617.   [(set (match_operand:SI 0 "general_operand" "=rm")
  3618.     (rotate:SI (match_operand:SI 1 "general_operand" "0")
  3619.            (match_operand:SI 2 "nonmemory_operand" "cI")))]
  3620.   ""
  3621.   "*
  3622. {
  3623.   if (REG_P (operands[2]))
  3624.     return AS2 (rol%L0,%b2,%0);
  3625.   else
  3626.     return AS2 (rol%L0,%2,%0);
  3627. }")
  3628.  
  3629. (define_insn "rotlhi3"
  3630.   [(set (match_operand:HI 0 "general_operand" "=rm")
  3631.     (rotate:HI (match_operand:HI 1 "general_operand" "0")
  3632.            (match_operand:HI 2 "nonmemory_operand" "cI")))]
  3633.   ""
  3634.   "*
  3635. {
  3636.   if (REG_P (operands[2]))
  3637.     return AS2 (rol%W0,%b2,%0);
  3638.   else
  3639.     return AS2 (rol%W0,%2,%0);
  3640. }")
  3641.  
  3642. (define_insn "rotlqi3"
  3643.   [(set (match_operand:QI 0 "general_operand" "=qm")
  3644.     (rotate:QI (match_operand:QI 1 "general_operand" "0")
  3645.            (match_operand:QI 2 "nonmemory_operand" "cI")))]
  3646.   ""
  3647.   "*
  3648. {
  3649.   if (REG_P (operands[2]))
  3650.     return AS2 (rol%B0,%b2,%0);
  3651.   else
  3652.     return AS2 (rol%B0,%2,%0);
  3653. }")
  3654.  
  3655. (define_insn "rotrsi3"
  3656.   [(set (match_operand:SI 0 "general_operand" "=rm")
  3657.     (rotatert:SI (match_operand:SI 1 "general_operand" "0")
  3658.              (match_operand:SI 2 "nonmemory_operand" "cI")))]
  3659.   ""
  3660.   "*
  3661. {
  3662.   if (REG_P (operands[2]))
  3663.     return AS2 (ror%L0,%b2,%0);
  3664.   else
  3665.     return AS2 (ror%L0,%2,%0);
  3666. }")
  3667.  
  3668. (define_insn "rotrhi3"
  3669.   [(set (match_operand:HI 0 "general_operand" "=rm")
  3670.     (rotatert:HI (match_operand:HI 1 "general_operand" "0")
  3671.              (match_operand:HI 2 "nonmemory_operand" "cI")))]
  3672.   ""
  3673.   "*
  3674. {
  3675.   if (REG_P (operands[2]))
  3676.     return AS2 (ror%W0,%b2,%0);
  3677.   else
  3678.     return AS2 (ror%W0,%2,%0);
  3679. }")
  3680.  
  3681. (define_insn "rotrqi3"
  3682.   [(set (match_operand:QI 0 "general_operand" "=qm")
  3683.     (rotatert:QI (match_operand:QI 1 "general_operand" "0")
  3684.              (match_operand:QI 2 "nonmemory_operand" "cI")))]
  3685.   ""
  3686.   "*
  3687. {
  3688.   if (REG_P (operands[2]))
  3689.     return AS2 (ror%B0,%b2,%0);
  3690.   else
  3691.     return AS2 (ror%B0,%2,%0);
  3692. }")
  3693.  
  3694. /*
  3695. ;; This usually looses.  But try a define_expand to recognize a few case
  3696. ;; we can do efficiently, such as accessing the "high" QImode registers,
  3697. ;; %ah, %bh, %ch, %dh.
  3698. (define_insn "insv"
  3699.   [(set (zero_extract:SI (match_operand:SI 0 "register_operand" "+&r")
  3700.              (match_operand:SI 1 "general_operand" "i")
  3701.              (match_operand:SI 2 "general_operand" "i"))
  3702.     (match_operand:SI 3 "general_operand" "ri"))]
  3703.   ""
  3704.   "*
  3705. {
  3706.   if (INTVAL (operands[1]) + INTVAL (operands[2]) > GET_MODE_BITSIZE (SImode))
  3707.     abort ();
  3708.   if (GET_CODE (operands[3]) == CONST_INT)
  3709.     {
  3710.       unsigned int mask = (1 << INTVAL (operands[1])) - 1; 
  3711.       operands[1] = GEN_INT (~(mask << INTVAL (operands[2])));
  3712.       output_asm_insn (AS2 (and%L0,%1,%0), operands);
  3713.       operands[3] = GEN_INT (INTVAL (operands[3]) << INTVAL (operands[2]));
  3714.       output_asm_insn (AS2 (or%L0,%3,%0), operands);
  3715.     }
  3716.   else
  3717.     {
  3718.       operands[0] = gen_rtx (REG, SImode, REGNO (operands[0]));
  3719.       if (INTVAL (operands[2]))
  3720.     output_asm_insn (AS2 (ror%L0,%2,%0), operands);
  3721.       output_asm_insn (AS3 (shrd%L0,%1,%3,%0), operands);
  3722.       operands[2] = GEN_INT (BITS_PER_WORD
  3723.                  - INTVAL (operands[1]) - INTVAL (operands[2]));
  3724.       if (INTVAL (operands[2]))
  3725.     output_asm_insn (AS2 (ror%L0,%2,%0), operands);
  3726.     }
  3727.   RET;
  3728. }")
  3729. */
  3730. /*
  3731. ;; ??? There are problems with the mode of operand[3].  The point of this
  3732. ;; is to represent an HImode move to a "high byte" register.
  3733.  
  3734. (define_expand "insv"
  3735.   [(set (zero_extract:SI (match_operand:SI 0 "general_operand" "")
  3736.              (match_operand:SI 1 "immediate_operand" "")
  3737.              (match_operand:SI 2 "immediate_operand" ""))
  3738.     (match_operand:QI 3 "general_operand" "ri"))]
  3739.   ""
  3740.   "
  3741. {
  3742.   if (GET_CODE (operands[1]) != CONST_INT
  3743.       || GET_CODE (operands[2]) != CONST_INT)
  3744.     FAIL;
  3745.  
  3746.   if (! (INTVAL (operands[1]) == 8
  3747.      && (INTVAL (operands[2]) == 8 || INTVAL (operands[2]) == 0))
  3748.       && ! INTVAL (operands[1]) == 1)
  3749.     FAIL;
  3750. }")
  3751.  
  3752. ;; ??? Are these constraints right?
  3753. (define_insn ""
  3754.   [(set (zero_extract:SI (match_operand:SI 0 "general_operand" "+&qo")
  3755.              (const_int 8)
  3756.              (const_int 8))
  3757.     (match_operand:QI 1 "general_operand" "qn"))]
  3758.   ""
  3759.   "*
  3760. {
  3761.   if (REG_P (operands[0]))
  3762.     return AS2 (mov%B0,%1,%h0);
  3763.  
  3764.   operands[0] = adj_offsettable_operand (operands[0], 1);
  3765.   return AS2 (mov%B0,%1,%0);
  3766. }")
  3767. */
  3768.  
  3769. ;; On i386, the register count for a bit operation is *not* truncated,
  3770. ;; so SHIFT_COUNT_TRUNCATED must not be defined.
  3771.  
  3772. ;; On i486, the shift & or/and code is faster than bts or btr.  If
  3773. ;; operands[0] is a MEM, the bt[sr] is half as fast as the normal code.
  3774.  
  3775. ;; On i386, bts is a little faster if operands[0] is a reg, and a
  3776. ;; little slower if operands[0] is a MEM, than the shift & or/and code.
  3777. ;; Use bts & btr, since they reload better.
  3778.  
  3779. ;; General bit set and clear.
  3780. (define_insn ""
  3781.   [(set (zero_extract:SI (match_operand:SI 0 "general_operand" "+rm")
  3782.              (const_int 1)
  3783.              (match_operand:SI 2 "general_operand" "r"))
  3784.     (match_operand:SI 3 "const_int_operand" "n"))]
  3785.   "! TARGET_486 && GET_CODE (operands[2]) != CONST_INT"
  3786.   "*
  3787. {
  3788.   CC_STATUS_INIT;
  3789.  
  3790.   if (INTVAL (operands[3]) == 1)
  3791.     return AS2 (bts%L0,%2,%0);
  3792.   else
  3793.     return AS2 (btr%L0,%2,%0);
  3794. }")
  3795.  
  3796. ;; Bit complement.  See comments on previous pattern.
  3797. ;; ??? Is this really worthwhile?
  3798. (define_insn ""
  3799.   [(set (match_operand:SI 0 "general_operand" "=rm")
  3800.     (xor:SI (ashift:SI (const_int 1)
  3801.                (match_operand:SI 1 "general_operand" "r"))
  3802.         (match_operand:SI 2 "general_operand" "0")))]
  3803.   "! TARGET_486 && GET_CODE (operands[1]) != CONST_INT"
  3804.   "*
  3805. {
  3806.   CC_STATUS_INIT;
  3807.  
  3808.   return AS2 (btc%L0,%1,%0);
  3809. }")
  3810.  
  3811. (define_insn ""
  3812.   [(set (match_operand:SI 0 "general_operand" "=rm")
  3813.     (xor:SI (match_operand:SI 1 "general_operand" "0")
  3814.         (ashift:SI (const_int 1)
  3815.                (match_operand:SI 2 "general_operand" "r"))))]
  3816.   "! TARGET_486 && GET_CODE (operands[2]) != CONST_INT"
  3817.   "*
  3818. {
  3819.   CC_STATUS_INIT;
  3820.  
  3821.   return AS2 (btc%L0,%2,%0);
  3822. }")
  3823.  
  3824. ;; Recognizers for bit-test instructions.
  3825.  
  3826. ;; The bt opcode allows a MEM in operands[0].  But on both i386 and
  3827. ;; i486, it is faster to copy a MEM to REG and then use bt, than to use
  3828. ;; bt on the MEM directly.
  3829.  
  3830. ;; ??? The first argument of a zero_extract must not be reloaded, so
  3831. ;; don't allow a MEM in the operand predicate without allowing it in the
  3832. ;; constraint.
  3833.  
  3834. (define_insn ""
  3835.   [(set (cc0) (zero_extract (match_operand:SI 0 "register_operand" "r")
  3836.                 (const_int 1)
  3837.                 (match_operand:SI 1 "general_operand" "r")))]
  3838.   "GET_CODE (operands[1]) != CONST_INT"
  3839.   "*
  3840. {
  3841.   cc_status.flags |= CC_Z_IN_NOT_C;
  3842.   return AS2 (bt%L0,%1,%0);
  3843. }")
  3844.  
  3845. (define_insn ""
  3846.   [(set (cc0) (zero_extract (match_operand:SI 0 "register_operand" "r")
  3847.                 (match_operand:SI 1 "const_int_operand" "n")
  3848.                 (match_operand:SI 2 "const_int_operand" "n")))]
  3849.   ""
  3850.   "*
  3851. {
  3852.   unsigned int mask;
  3853.  
  3854.   mask = ((1 << INTVAL (operands[1])) - 1) << INTVAL (operands[2]);
  3855.   operands[1] = GEN_INT (mask);
  3856.  
  3857.   if (QI_REG_P (operands[0]))
  3858.     {
  3859.       if ((mask & ~0xff) == 0)
  3860.         {
  3861.       cc_status.flags |= CC_NOT_NEGATIVE;
  3862.       return AS2 (test%B0,%1,%b0);
  3863.     }
  3864.  
  3865.       if ((mask & ~0xff00) == 0)
  3866.         {
  3867.       cc_status.flags |= CC_NOT_NEGATIVE;
  3868.       operands[1] = GEN_INT (mask >> 8);
  3869.       return AS2 (test%B0,%1,%h0);
  3870.     }
  3871.     }
  3872.  
  3873.   return AS2 (test%L0,%1,%0);
  3874. }")
  3875.  
  3876. ;; ??? All bets are off if operand 0 is a volatile MEM reference.
  3877. ;; The CPU may access unspecified bytes around the actual target byte.
  3878.  
  3879. (define_insn ""
  3880.   [(set (cc0) (zero_extract (match_operand:QI 0 "general_operand" "rm")
  3881.                 (match_operand:SI 1 "const_int_operand" "n")
  3882.                 (match_operand:SI 2 "const_int_operand" "n")))]
  3883.   "GET_CODE (operands[0]) != MEM || ! MEM_VOLATILE_P (operands[0])"
  3884.   "*
  3885. {
  3886.   unsigned int mask;
  3887.  
  3888.   mask = ((1 << INTVAL (operands[1])) - 1) << INTVAL (operands[2]);
  3889.   operands[1] = GEN_INT (mask);
  3890.  
  3891.   if (! REG_P (operands[0]) || QI_REG_P (operands[0]))
  3892.     {
  3893.       if ((mask & ~0xff) == 0)
  3894.         {
  3895.       cc_status.flags |= CC_NOT_NEGATIVE;
  3896.       return AS2 (test%B0,%1,%b0);
  3897.     }
  3898.  
  3899.       if ((mask & ~0xff00) == 0)
  3900.         {
  3901.       cc_status.flags |= CC_NOT_NEGATIVE;
  3902.       operands[1] = GEN_INT (mask >> 8);
  3903.  
  3904.       if (QI_REG_P (operands[0]))
  3905.         return AS2 (test%B0,%1,%h0);
  3906.       else
  3907.         {
  3908.           operands[0] = adj_offsettable_operand (operands[0], 1);
  3909.           return AS2 (test%B0,%1,%b0);
  3910.         }
  3911.     }
  3912.  
  3913.       if (GET_CODE (operands[0]) == MEM && (mask & ~0xff0000) == 0)
  3914.         {
  3915.       cc_status.flags |= CC_NOT_NEGATIVE;
  3916.       operands[1] = GEN_INT (mask >> 16);
  3917.       operands[0] = adj_offsettable_operand (operands[0], 2);
  3918.       return AS2 (test%B0,%1,%b0);
  3919.     }
  3920.  
  3921.       if (GET_CODE (operands[0]) == MEM && (mask & ~0xff000000) == 0)
  3922.         {
  3923.       cc_status.flags |= CC_NOT_NEGATIVE;
  3924.       operands[1] = GEN_INT (mask >> 24);
  3925.       operands[0] = adj_offsettable_operand (operands[0], 3);
  3926.       return AS2 (test%B0,%1,%b0);
  3927.     }
  3928.     }
  3929.  
  3930.   if (CONSTANT_P (operands[1]) || GET_CODE (operands[0]) == MEM)
  3931.     return AS2 (test%L0,%1,%0);
  3932.  
  3933.   return AS2 (test%L1,%0,%1);
  3934. }")
  3935.  
  3936. ;; Store-flag instructions.
  3937.  
  3938. ;; For all sCOND expanders, also expand the compare or test insn that
  3939. ;; generates cc0.  Generate an equality comparison if `seq' or `sne'.
  3940.  
  3941. ;; The 386 sCOND opcodes can write to memory.  But a gcc sCOND insn may
  3942. ;; not have any input reloads.  A MEM write might need an input reload
  3943. ;; for the address of the MEM.  So don't allow MEM as the SET_DEST.
  3944.  
  3945. (define_expand "seq"
  3946.   [(match_dup 1)
  3947.    (set (match_operand:QI 0 "register_operand" "")
  3948.     (eq:QI (cc0) (const_int 0)))]
  3949.   ""
  3950.   "
  3951. {
  3952.   if (TARGET_IEEE_FP
  3953.       && GET_MODE_CLASS (GET_MODE (i386_compare_op0)) == MODE_FLOAT)
  3954.     operands[1] = (*i386_compare_gen_eq)(i386_compare_op0, i386_compare_op1);
  3955.   else
  3956.     operands[1] = (*i386_compare_gen)(i386_compare_op0, i386_compare_op1);
  3957. }")
  3958.  
  3959. (define_insn ""
  3960.   [(set (match_operand:QI 0 "register_operand" "=q")
  3961.     (eq:QI (cc0) (const_int 0)))]
  3962.   ""
  3963.   "*
  3964. {
  3965.   if (cc_prev_status.flags & CC_Z_IN_NOT_C)
  3966.     return AS1 (setnb,%0);
  3967.   else
  3968.     return AS1 (sete,%0);
  3969. }")
  3970.  
  3971. (define_expand "sne"
  3972.   [(match_dup 1)
  3973.    (set (match_operand:QI 0 "register_operand" "")
  3974.     (ne:QI (cc0) (const_int 0)))]
  3975.   ""
  3976.   "
  3977. {
  3978.   if (TARGET_IEEE_FP
  3979.       && GET_MODE_CLASS (GET_MODE (i386_compare_op0)) == MODE_FLOAT)
  3980.     operands[1] = (*i386_compare_gen_eq)(i386_compare_op0, i386_compare_op1);
  3981.   else
  3982.     operands[1] = (*i386_compare_gen)(i386_compare_op0, i386_compare_op1);
  3983. }")
  3984.  
  3985. (define_insn ""
  3986.   [(set (match_operand:QI 0 "register_operand" "=q")
  3987.     (ne:QI (cc0) (const_int 0)))]
  3988.   ""
  3989.   "*
  3990. {
  3991.   if (cc_prev_status.flags & CC_Z_IN_NOT_C)
  3992.     return AS1 (setb,%0);
  3993.   else
  3994.     return AS1 (setne,%0);
  3995. }
  3996. ")
  3997.  
  3998. (define_expand "sgt"
  3999.   [(match_dup 1)
  4000.    (set (match_operand:QI 0 "register_operand" "")
  4001.     (gt:QI (cc0) (const_int 0)))]
  4002.   ""
  4003.   "operands[1] = (*i386_compare_gen)(i386_compare_op0, i386_compare_op1);")
  4004.  
  4005. (define_insn ""
  4006.   [(set (match_operand:QI 0 "register_operand" "=q")
  4007.     (gt:QI (cc0) (const_int 0)))]
  4008.   ""
  4009.   "*
  4010. {
  4011.   if (TARGET_IEEE_FP && (cc_prev_status.flags & CC_IN_80387))
  4012.     return AS1 (sete,%0);
  4013.  
  4014.   OUTPUT_JUMP (\"setg %0\", \"seta %0\", NULL_PTR);
  4015. }")
  4016.  
  4017. (define_expand "sgtu"
  4018.   [(match_dup 1)
  4019.    (set (match_operand:QI 0 "register_operand" "")
  4020.     (gtu:QI (cc0) (const_int 0)))]
  4021.   ""
  4022.   "operands[1] = (*i386_compare_gen)(i386_compare_op0, i386_compare_op1);")
  4023.  
  4024. (define_insn ""
  4025.   [(set (match_operand:QI 0 "register_operand" "=q")
  4026.     (gtu:QI (cc0) (const_int 0)))]
  4027.   ""
  4028.   "* return \"seta %0\"; ")
  4029.  
  4030. (define_expand "slt"
  4031.   [(match_dup 1)
  4032.    (set (match_operand:QI 0 "register_operand" "")
  4033.     (lt:QI (cc0) (const_int 0)))]
  4034.   ""
  4035.   "operands[1] = (*i386_compare_gen)(i386_compare_op0, i386_compare_op1);")
  4036.  
  4037. (define_insn ""
  4038.   [(set (match_operand:QI 0 "register_operand" "=q")
  4039.     (lt:QI (cc0) (const_int 0)))]
  4040.   ""
  4041.   "*
  4042. {
  4043.   if (TARGET_IEEE_FP && (cc_prev_status.flags & CC_IN_80387))
  4044.     return AS1 (sete,%0);
  4045.  
  4046.   OUTPUT_JUMP (\"setl %0\", \"setb %0\", \"sets %0\");
  4047. }")
  4048.  
  4049. (define_expand "sltu"
  4050.   [(match_dup 1)
  4051.    (set (match_operand:QI 0 "register_operand" "")
  4052.     (ltu:QI (cc0) (const_int 0)))]
  4053.   ""
  4054.   "operands[1] = (*i386_compare_gen)(i386_compare_op0, i386_compare_op1);")
  4055.  
  4056. (define_insn ""
  4057.   [(set (match_operand:QI 0 "register_operand" "=q")
  4058.     (ltu:QI (cc0) (const_int 0)))]
  4059.   ""
  4060.   "* return \"setb %0\"; ")
  4061.  
  4062. (define_expand "sge"
  4063.   [(match_dup 1)
  4064.    (set (match_operand:QI 0 "register_operand" "")
  4065.     (ge:QI (cc0) (const_int 0)))]
  4066.   ""
  4067.   "operands[1] = (*i386_compare_gen)(i386_compare_op0, i386_compare_op1);")
  4068.  
  4069. (define_insn ""
  4070.   [(set (match_operand:QI 0 "register_operand" "=q")
  4071.     (ge:QI (cc0) (const_int 0)))]
  4072.   ""
  4073.   "*
  4074. {
  4075.   if (TARGET_IEEE_FP && (cc_prev_status.flags & CC_IN_80387))
  4076.     return AS1 (sete,%0);
  4077.  
  4078.   OUTPUT_JUMP (\"setge %0\", \"setae %0\", \"setns %0\");
  4079. }")
  4080.  
  4081. (define_expand "sgeu"
  4082.   [(match_dup 1)
  4083.    (set (match_operand:QI 0 "register_operand" "")
  4084.     (geu:QI (cc0) (const_int 0)))]
  4085.   ""
  4086.   "operands[1] = (*i386_compare_gen)(i386_compare_op0, i386_compare_op1);")
  4087.  
  4088. (define_insn ""
  4089.   [(set (match_operand:QI 0 "register_operand" "=q")
  4090.     (geu:QI (cc0) (const_int 0)))]
  4091.   ""
  4092.   "* return \"setae %0\"; ")
  4093.  
  4094. (define_expand "sle"
  4095.   [(match_dup 1)
  4096.    (set (match_operand:QI 0 "register_operand" "")
  4097.     (le:QI (cc0) (const_int 0)))]
  4098.   ""
  4099.   "operands[1] = (*i386_compare_gen)(i386_compare_op0, i386_compare_op1);")
  4100.  
  4101. (define_insn ""
  4102.   [(set (match_operand:QI 0 "register_operand" "=q")
  4103.     (le:QI (cc0) (const_int 0)))]
  4104.   ""
  4105.   "*
  4106. {
  4107.   if (TARGET_IEEE_FP && (cc_prev_status.flags & CC_IN_80387))
  4108.     return AS1 (setb,%0);
  4109.  
  4110.   OUTPUT_JUMP (\"setle %0\", \"setbe %0\", NULL_PTR);
  4111. }")
  4112.  
  4113. (define_expand "sleu"
  4114.   [(match_dup 1)
  4115.    (set (match_operand:QI 0 "register_operand" "")
  4116.     (leu:QI (cc0) (const_int 0)))]
  4117.   ""
  4118.   "operands[1] = (*i386_compare_gen)(i386_compare_op0, i386_compare_op1);")
  4119.  
  4120. (define_insn ""
  4121.   [(set (match_operand:QI 0 "register_operand" "=q")
  4122.     (leu:QI (cc0) (const_int 0)))]
  4123.   ""
  4124.   "* return \"setbe %0\"; ")
  4125.  
  4126. ;; Basic conditional jump instructions.
  4127. ;; We ignore the overflow flag for signed branch instructions.
  4128.  
  4129. ;; For all bCOND expanders, also expand the compare or test insn that
  4130. ;; generates cc0.  Generate an equality comparison if `beq' or `bne'.
  4131.  
  4132. (define_expand "beq"
  4133.   [(match_dup 1)
  4134.    (set (pc)
  4135.     (if_then_else (eq (cc0)
  4136.               (const_int 0))
  4137.               (label_ref (match_operand 0 "" ""))
  4138.               (pc)))]
  4139.   ""
  4140.   "
  4141. {
  4142.   if (TARGET_IEEE_FP
  4143.       && GET_MODE_CLASS (GET_MODE (i386_compare_op0)) == MODE_FLOAT)
  4144.     operands[1] = (*i386_compare_gen_eq)(i386_compare_op0, i386_compare_op1);
  4145.   else
  4146.     operands[1] = (*i386_compare_gen)(i386_compare_op0, i386_compare_op1);
  4147. }")
  4148.  
  4149. (define_insn ""
  4150.   [(set (pc)
  4151.     (if_then_else (eq (cc0)
  4152.               (const_int 0))
  4153.               (label_ref (match_operand 0 "" ""))
  4154.               (pc)))]
  4155.   ""
  4156.   "*
  4157. {
  4158.   if (cc_prev_status.flags & CC_Z_IN_NOT_C)
  4159.     return \"jnc %l0\";
  4160.   else
  4161.     return \"je %l0\";
  4162. }")
  4163.  
  4164. (define_expand "bne"
  4165.   [(match_dup 1)
  4166.    (set (pc)
  4167.     (if_then_else (ne (cc0)
  4168.               (const_int 0))
  4169.               (label_ref (match_operand 0 "" ""))
  4170.               (pc)))]
  4171.   ""
  4172.   "
  4173. {
  4174.   if (TARGET_IEEE_FP
  4175.       && GET_MODE_CLASS (GET_MODE (i386_compare_op0)) == MODE_FLOAT)
  4176.     operands[1] = (*i386_compare_gen_eq)(i386_compare_op0, i386_compare_op1);
  4177.   else
  4178.     operands[1] = (*i386_compare_gen)(i386_compare_op0, i386_compare_op1);
  4179. }")
  4180.  
  4181. (define_insn ""
  4182.   [(set (pc)
  4183.     (if_then_else (ne (cc0)
  4184.               (const_int 0))
  4185.               (label_ref (match_operand 0 "" ""))
  4186.               (pc)))]
  4187.   ""
  4188.   "*
  4189. {
  4190.   if (cc_prev_status.flags & CC_Z_IN_NOT_C)
  4191.     return \"jc %l0\";
  4192.   else
  4193.     return \"jne %l0\";
  4194. }")
  4195.  
  4196. (define_expand "bgt"
  4197.   [(match_dup 1)
  4198.    (set (pc)
  4199.     (if_then_else (gt (cc0)
  4200.               (const_int 0))
  4201.               (label_ref (match_operand 0 "" ""))
  4202.               (pc)))]
  4203.   ""
  4204.   "operands[1] = (*i386_compare_gen)(i386_compare_op0, i386_compare_op1);")
  4205.  
  4206. (define_insn ""
  4207.   [(set (pc)
  4208.     (if_then_else (gt (cc0)
  4209.               (const_int 0))
  4210.               (label_ref (match_operand 0 "" ""))
  4211.               (pc)))]
  4212.   ""
  4213.   "*
  4214. {
  4215.   if (TARGET_IEEE_FP && (cc_prev_status.flags & CC_IN_80387))
  4216.     return AS1 (je,%l0);
  4217.  
  4218.   OUTPUT_JUMP (\"jg %l0\", \"ja %l0\", NULL_PTR);
  4219. }")
  4220.  
  4221. (define_expand "bgtu"
  4222.   [(match_dup 1)
  4223.    (set (pc)
  4224.     (if_then_else (gtu (cc0)
  4225.                (const_int 0))
  4226.               (label_ref (match_operand 0 "" ""))
  4227.               (pc)))]
  4228.   ""
  4229.   "operands[1] = (*i386_compare_gen)(i386_compare_op0, i386_compare_op1);")
  4230.  
  4231. (define_insn ""
  4232.   [(set (pc)
  4233.     (if_then_else (gtu (cc0)
  4234.                (const_int 0))
  4235.               (label_ref (match_operand 0 "" ""))
  4236.               (pc)))]
  4237.   ""
  4238.   "ja %l0")
  4239.  
  4240. (define_expand "blt"
  4241.   [(match_dup 1)
  4242.    (set (pc)
  4243.     (if_then_else (lt (cc0)
  4244.               (const_int 0))
  4245.               (label_ref (match_operand 0 "" ""))
  4246.               (pc)))]
  4247.   ""
  4248.   "operands[1] = (*i386_compare_gen)(i386_compare_op0, i386_compare_op1);")
  4249.  
  4250. (define_insn ""
  4251.   [(set (pc)
  4252.     (if_then_else (lt (cc0)
  4253.               (const_int 0))
  4254.               (label_ref (match_operand 0 "" ""))
  4255.               (pc)))]
  4256.   ""
  4257.   "*
  4258. {
  4259.   if (TARGET_IEEE_FP && (cc_prev_status.flags & CC_IN_80387))
  4260.     return AS1 (je,%l0);
  4261.  
  4262.   OUTPUT_JUMP (\"jl %l0\", \"jb %l0\", \"js %l0\");
  4263. }")
  4264.  
  4265. (define_expand "bltu"
  4266.   [(match_dup 1)
  4267.    (set (pc)
  4268.     (if_then_else (ltu (cc0)
  4269.                (const_int 0))
  4270.               (label_ref (match_operand 0 "" ""))
  4271.               (pc)))]
  4272.   ""
  4273.   "operands[1] = (*i386_compare_gen)(i386_compare_op0, i386_compare_op1);")
  4274.  
  4275. (define_insn ""
  4276.   [(set (pc)
  4277.     (if_then_else (ltu (cc0)
  4278.                (const_int 0))
  4279.               (label_ref (match_operand 0 "" ""))
  4280.               (pc)))]
  4281.   ""
  4282.   "jb %l0")
  4283.  
  4284. (define_expand "bge"
  4285.   [(match_dup 1)
  4286.    (set (pc)
  4287.     (if_then_else (ge (cc0)
  4288.               (const_int 0))
  4289.               (label_ref (match_operand 0 "" ""))
  4290.               (pc)))]
  4291.   ""
  4292.   "operands[1] = (*i386_compare_gen)(i386_compare_op0, i386_compare_op1);")
  4293.  
  4294. (define_insn ""
  4295.   [(set (pc)
  4296.     (if_then_else (ge (cc0)
  4297.               (const_int 0))
  4298.               (label_ref (match_operand 0 "" ""))
  4299.               (pc)))]
  4300.   ""
  4301.   "*
  4302. {
  4303.   if (TARGET_IEEE_FP && (cc_prev_status.flags & CC_IN_80387))
  4304.     return AS1 (je,%l0);
  4305.  
  4306.   OUTPUT_JUMP (\"jge %l0\", \"jae %l0\", \"jns %l0\");
  4307. }")
  4308.  
  4309. (define_expand "bgeu"
  4310.   [(match_dup 1)
  4311.    (set (pc)
  4312.     (if_then_else (geu (cc0)
  4313.                (const_int 0))
  4314.               (label_ref (match_operand 0 "" ""))
  4315.               (pc)))]
  4316.   ""
  4317.   "operands[1] = (*i386_compare_gen)(i386_compare_op0, i386_compare_op1);")
  4318.  
  4319. (define_insn ""
  4320.   [(set (pc)
  4321.     (if_then_else (geu (cc0)
  4322.                (const_int 0))
  4323.               (label_ref (match_operand 0 "" ""))
  4324.               (pc)))]
  4325.   ""
  4326.   "jae %l0")
  4327.  
  4328. (define_expand "ble"
  4329.   [(match_dup 1)
  4330.    (set (pc)
  4331.     (if_then_else (le (cc0)
  4332.               (const_int 0))
  4333.               (label_ref (match_operand 0 "" ""))
  4334.               (pc)))]
  4335.   ""
  4336.   "operands[1] = (*i386_compare_gen)(i386_compare_op0, i386_compare_op1);")
  4337.  
  4338. (define_insn ""
  4339.   [(set (pc)
  4340.     (if_then_else (le (cc0)
  4341.               (const_int 0))
  4342.               (label_ref (match_operand 0 "" ""))
  4343.               (pc)))]
  4344.   ""
  4345.   "*
  4346. {
  4347.   if (TARGET_IEEE_FP && (cc_prev_status.flags & CC_IN_80387))
  4348.     return AS1 (jb,%l0);
  4349.  
  4350.   OUTPUT_JUMP (\"jle %l0\", \"jbe %l0\", NULL_PTR);
  4351. }")
  4352.  
  4353. (define_expand "bleu"
  4354.   [(match_dup 1)
  4355.    (set (pc)
  4356.     (if_then_else (leu (cc0)
  4357.                (const_int 0))
  4358.               (label_ref (match_operand 0 "" ""))
  4359.               (pc)))]
  4360.   ""
  4361.   "operands[1] = (*i386_compare_gen)(i386_compare_op0, i386_compare_op1);")
  4362.  
  4363. (define_insn ""
  4364.   [(set (pc)
  4365.     (if_then_else (leu (cc0)
  4366.                (const_int 0))
  4367.               (label_ref (match_operand 0 "" ""))
  4368.               (pc)))]
  4369.   ""
  4370.   "jbe %l0")
  4371.  
  4372. ;; Negated conditional jump instructions.
  4373.  
  4374. (define_insn ""
  4375.   [(set (pc)
  4376.     (if_then_else (eq (cc0)
  4377.               (const_int 0))
  4378.               (pc)
  4379.               (label_ref (match_operand 0 "" ""))))]
  4380.   ""
  4381.   "*
  4382. {
  4383.   if (cc_prev_status.flags & CC_Z_IN_NOT_C)
  4384.     return \"jc %l0\";
  4385.   else
  4386.     return \"jne %l0\";
  4387. }")
  4388.  
  4389. (define_insn ""
  4390.   [(set (pc)
  4391.     (if_then_else (ne (cc0)
  4392.               (const_int 0))
  4393.               (pc)
  4394.               (label_ref (match_operand 0 "" ""))))]
  4395.   ""
  4396.   "*
  4397. {
  4398.   if (cc_prev_status.flags & CC_Z_IN_NOT_C)
  4399.     return \"jnc %l0\";
  4400.   else
  4401.     return \"je %l0\";
  4402. }")
  4403.  
  4404. (define_insn ""
  4405.   [(set (pc)
  4406.     (if_then_else (gt (cc0)
  4407.               (const_int 0))
  4408.               (pc)
  4409.               (label_ref (match_operand 0 "" ""))))]
  4410.   ""
  4411.   "*
  4412. {
  4413.   if (TARGET_IEEE_FP && (cc_prev_status.flags & CC_IN_80387))
  4414.     return AS1 (jne,%l0);
  4415.  
  4416.   OUTPUT_JUMP (\"jle %l0\", \"jbe %l0\", NULL_PTR);
  4417. }")
  4418.  
  4419. (define_insn ""
  4420.   [(set (pc)
  4421.     (if_then_else (gtu (cc0)
  4422.                (const_int 0))
  4423.               (pc)
  4424.               (label_ref (match_operand 0 "" ""))))]
  4425.   ""
  4426.   "jbe %l0")
  4427.  
  4428. (define_insn ""
  4429.   [(set (pc)
  4430.     (if_then_else (lt (cc0)
  4431.               (const_int 0))
  4432.               (pc)
  4433.               (label_ref (match_operand 0 "" ""))))]
  4434.   ""
  4435.   "*
  4436. {
  4437.   if (TARGET_IEEE_FP && (cc_prev_status.flags & CC_IN_80387))
  4438.     return AS1 (jne,%l0);
  4439.  
  4440.   OUTPUT_JUMP (\"jge %l0\", \"jae %l0\", \"jns %l0\");
  4441. }")
  4442.  
  4443. (define_insn ""
  4444.   [(set (pc)
  4445.     (if_then_else (ltu (cc0)
  4446.                (const_int 0))
  4447.               (pc)
  4448.               (label_ref (match_operand 0 "" ""))))]
  4449.   ""
  4450.   "jae %l0")
  4451.  
  4452. (define_insn ""
  4453.   [(set (pc)
  4454.     (if_then_else (ge (cc0)
  4455.               (const_int 0))
  4456.               (pc)
  4457.               (label_ref (match_operand 0 "" ""))))]
  4458.   ""
  4459.   "*
  4460. {
  4461.   if (TARGET_IEEE_FP && (cc_prev_status.flags & CC_IN_80387))
  4462.     return AS1 (jne,%l0);
  4463.  
  4464.   OUTPUT_JUMP (\"jl %l0\", \"jb %l0\", \"js %l0\");
  4465. }")
  4466.  
  4467. (define_insn ""
  4468.   [(set (pc)
  4469.     (if_then_else (geu (cc0)
  4470.                (const_int 0))
  4471.               (pc)
  4472.               (label_ref (match_operand 0 "" ""))))]
  4473.   ""
  4474.   "jb %l0")
  4475.  
  4476. (define_insn ""
  4477.   [(set (pc)
  4478.     (if_then_else (le (cc0)
  4479.               (const_int 0))
  4480.               (pc)
  4481.               (label_ref (match_operand 0 "" ""))))]
  4482.   ""
  4483.   "*
  4484. {
  4485.   if (TARGET_IEEE_FP && (cc_prev_status.flags & CC_IN_80387))
  4486.     return AS1 (jae,%l0);
  4487.  
  4488.   OUTPUT_JUMP (\"jg %l0\", \"ja %l0\", NULL_PTR);
  4489. }")
  4490.  
  4491. (define_insn ""
  4492.   [(set (pc)
  4493.     (if_then_else (leu (cc0)
  4494.                (const_int 0))
  4495.               (pc)
  4496.               (label_ref (match_operand 0 "" ""))))]
  4497.   ""
  4498.   "ja %l0")
  4499.  
  4500. ;; Unconditional and other jump instructions
  4501.  
  4502. (define_insn "jump"
  4503.   [(set (pc)
  4504.     (label_ref (match_operand 0 "" "")))]
  4505.   ""
  4506.   "jmp %l0")
  4507.  
  4508. (define_insn "indirect_jump"
  4509.   [(set (pc) (match_operand:SI 0 "general_operand" "rm"))]
  4510.   ""
  4511.   "*
  4512. {
  4513.   CC_STATUS_INIT;
  4514.  
  4515.   return AS1 (jmp,%*%0);
  4516. }")
  4517.  
  4518. ;; Implement switch statements when generating PIC code.  Switches are
  4519. ;; implemented by `tablejump' when not using -fpic.
  4520.  
  4521. ;; Emit code here to do the range checking and make the index zero based.
  4522.  
  4523. (define_expand "casesi"
  4524.   [(set (match_dup 5)
  4525.     (minus:SI (match_operand:SI 0 "general_operand" "")
  4526.           (match_operand:SI 1 "general_operand" "")))
  4527.    (set (cc0)
  4528.     (compare:CC (match_dup 5)
  4529.             (match_operand:SI 2 "general_operand" "")))
  4530.    (set (pc)
  4531.     (if_then_else (gtu (cc0)
  4532.                (const_int 0))
  4533.               (label_ref (match_operand 4 "" ""))
  4534.               (pc)))
  4535.    (parallel
  4536.     [(set (pc)
  4537.       (minus:SI (reg:SI 3)
  4538.             (mem:SI (plus:SI (mult:SI (match_dup 5)
  4539.                           (const_int 4))
  4540.                      (label_ref (match_operand 3 "" ""))))))
  4541.      (clobber (match_scratch:SI 6 ""))])]
  4542.   "flag_pic"
  4543.   "
  4544. {
  4545.   operands[5] = gen_reg_rtx (SImode);
  4546.   current_function_uses_pic_offset_table = 1;
  4547. }")
  4548.  
  4549. ;; Implement a casesi insn.
  4550.  
  4551. ;; Each entry in the "addr_diff_vec" looks like this as the result of the
  4552. ;; two rules below:
  4553. ;; 
  4554. ;;     .long _GLOBAL_OFFSET_TABLE_+[.-.L2]
  4555. ;; 
  4556. ;; 1. An expression involving an external reference may only use the
  4557. ;;    addition operator, and only with an assembly-time constant.
  4558. ;;    The example above satisfies this because ".-.L2" is a constant.
  4559. ;; 
  4560. ;; 2. The symbol _GLOBAL_OFFSET_TABLE_ is magic, and at link time is
  4561. ;;    given the value of "GOT - .", where GOT is the actual address of
  4562. ;;    the Global Offset Table.  Therefore, the .long above actually
  4563. ;;    stores the value "( GOT - . ) + [ . - .L2 ]", or "GOT - .L2".  The
  4564. ;;    expression "GOT - .L2" by itself would generate an error from as(1).
  4565. ;; 
  4566. ;; The pattern below emits code that looks like this:
  4567. ;; 
  4568. ;;     movl %ebx,reg
  4569. ;;     subl TABLE@GOTOFF(%ebx,index,4),reg
  4570. ;;     jmp reg
  4571. ;; 
  4572. ;; The addr_diff_vec contents may be directly referenced with @GOTOFF, since
  4573. ;; the addr_diff_vec is known to be part of this module.
  4574. ;; 
  4575. ;; The subl above calculates "GOT - (( GOT - . ) + [ . - .L2 ])", which
  4576. ;; evaluates to just ".L2".
  4577.  
  4578. (define_insn ""
  4579.   [(set (pc)
  4580.     (minus:SI (reg:SI 3)
  4581.           (mem:SI (plus:SI
  4582.                (mult:SI (match_operand:SI 0 "register_operand" "r")
  4583.                     (const_int 4))
  4584.                (label_ref (match_operand 1 "" ""))))))
  4585.    (clobber (match_scratch:SI 2 "=&r"))]
  4586.   ""
  4587.   "*
  4588. {
  4589.   rtx xops[6];
  4590.  
  4591.   xops[0] = operands[0];
  4592.   xops[1] = operands[1];
  4593.   xops[2] = operands[2];
  4594.   xops[3] = pic_offset_table_rtx;
  4595.  
  4596.  
  4597. #ifdef MACHO_PIC
  4598.   xops[4] = gen_rtx (SYMBOL_REF, QImode, machopic_function_base_name ());
  4599.   xops[5] = gen_rtx (MINUS, Pmode, xops[1], xops[4]);
  4600.  
  4601. /*  
  4602.    leal %5(%3),%2
  4603.    addl (%2,%0,4),%2
  4604.    jmp *%2
  4605.  */ 
  4606.  
  4607.   output_asm_insn (\"leal %5(%3),%2\", xops);
  4608.   output_asm_insn (\"addl (%2,%0,4),%2\", xops);
  4609.   output_asm_insn (\"jmp %*%2\", xops);
  4610.   ASM_OUTPUT_ALIGN_CODE (asm_out_file);
  4611.   RET;
  4612. #else
  4613.   output_asm_insn (AS2 (mov%L2,%3,%2), xops);
  4614.   output_asm_insn (\"sub%L2 %l1@GOTOFF(%3,%0,4),%2\", xops);
  4615.   output_asm_insn (AS1 (jmp,%*%2), xops);
  4616.   ASM_OUTPUT_ALIGN_CODE (asm_out_file);
  4617.   RET;
  4618. #endif
  4619. }")
  4620.  
  4621. (define_insn "tablejump"
  4622.   [(set (pc) (match_operand:SI 0 "general_operand" "rm"))
  4623.    (use (label_ref (match_operand 1 "" "")))]
  4624.   ""
  4625.   "*
  4626. {
  4627.   CC_STATUS_INIT;
  4628.  
  4629.   return AS1 (jmp,%*%0);
  4630. }")
  4631.  
  4632. ;; Call insns.
  4633.  
  4634. ;; If generating PIC code, the predicate indirect_operand will fail
  4635. ;; for operands[0] containing symbolic references on all of the named
  4636. ;; call* patterns.  Each named pattern is followed by an unnamed pattern
  4637. ;; that matches any call to a symbolic CONST (ie, a symbol_ref).  The
  4638. ;; unnamed patterns are only used while generating PIC code, because
  4639. ;; otherwise the named patterns match.
  4640.  
  4641. ;; Call subroutine returning no value.
  4642.  
  4643. (define_expand "call_pop"
  4644.   [(parallel [(call (match_operand:QI 0 "indirect_operand" "")
  4645.             (match_operand:SI 1 "general_operand" ""))
  4646.           (set (reg:SI 7)
  4647.            (plus:SI (reg:SI 7)
  4648.                 (match_operand:SI 3 "immediate_operand" "")))])]
  4649.   ""
  4650.   "
  4651. {
  4652.   rtx addr;
  4653.  
  4654. #ifdef MACHO_PIC
  4655.   if (flag_pic && GET_CODE (XEXP (operands[0], 0)) == SYMBOL_REF)
  4656.     { 
  4657.     extern rtx machopic_indirect_call_target();
  4658.     operands[0] = machopic_indirect_call_target (operands[0]);
  4659.     }
  4660. #else
  4661.   if (flag_pic)
  4662.     current_function_uses_pic_offset_table = 1;
  4663. #endif
  4664.   
  4665.  /* With half-pic, force the address into a register.  */
  4666.   addr = XEXP (operands[0], 0);
  4667.   if (GET_CODE (addr) != REG && HALF_PIC_P () && !CONSTANT_ADDRESS_P (addr))
  4668.     XEXP (operands[0], 0) = force_reg (Pmode, addr);
  4669.  
  4670.   if (! expander_call_insn_operand (operands[0], QImode))
  4671.     operands[0]
  4672.       = change_address (operands[0], VOIDmode,
  4673.             copy_to_mode_reg (Pmode, XEXP (operands[0], 0)));
  4674. }")
  4675.  
  4676. (define_insn ""
  4677.   [(call (match_operand:QI 0 "call_insn_operand" "m")
  4678.      (match_operand:SI 1 "general_operand" "g"))
  4679.    (set (reg:SI 7) (plus:SI (reg:SI 7)
  4680.                 (match_operand:SI 3 "immediate_operand" "i")))]
  4681.   ""
  4682.   "*
  4683. {
  4684.   if (GET_CODE (operands[0]) == MEM
  4685.       && ! CONSTANT_ADDRESS_P (XEXP (operands[0], 0)))
  4686.     {
  4687.       operands[0] = XEXP (operands[0], 0);
  4688.       return AS1 (call,%*%0);
  4689.     }
  4690.   else
  4691.     return AS1 (call,%P0);
  4692. }")
  4693.  
  4694. (define_insn ""
  4695.   [(call (mem:QI (match_operand:SI 0 "symbolic_operand" ""))
  4696.      (match_operand:SI 1 "general_operand" "g"))
  4697.    (set (reg:SI 7) (plus:SI (reg:SI 7)
  4698.                 (match_operand:SI 3 "immediate_operand" "i")))]
  4699.   "!HALF_PIC_P ()"
  4700.   "call %P0")
  4701.  
  4702. (define_expand "call"
  4703.   [(call (match_operand:QI 0 "indirect_operand" "")
  4704.      (match_operand:SI 1 "general_operand" ""))]
  4705.   ;; Operand 1 not used on the i386.
  4706.   ""
  4707.   "
  4708. {
  4709.   rtx addr;
  4710.  
  4711. #ifdef MACHO_PIC
  4712.   if (flag_pic && GET_CODE (XEXP (operands[0], 0)) == SYMBOL_REF)
  4713.     { 
  4714.     extern rtx machopic_indirect_call_target();
  4715.     operands[0] = machopic_indirect_call_target (operands[0]);
  4716.     }
  4717. #else
  4718.   if (flag_pic)
  4719.     current_function_uses_pic_offset_table = 1;
  4720. #endif
  4721.   
  4722.   /* With half-pic, force the address into a register.  */
  4723.   addr = XEXP (operands[0], 0);
  4724.   if (GET_CODE (addr) != REG && HALF_PIC_P () && !CONSTANT_ADDRESS_P (addr))
  4725.     XEXP (operands[0], 0) = force_reg (Pmode, addr);
  4726.  
  4727.   if (! expander_call_insn_operand (operands[0], QImode))
  4728.     operands[0]
  4729.       = change_address (operands[0], VOIDmode,
  4730.             copy_to_mode_reg (Pmode, XEXP (operands[0], 0)));
  4731. }")
  4732.  
  4733. (define_insn ""
  4734.   [(call (match_operand:QI 0 "call_insn_operand" "m")
  4735.      (match_operand:SI 1 "general_operand" "g"))]
  4736.   ;; Operand 1 not used on the i386.
  4737.   ""
  4738.   "*
  4739. {
  4740.   if (GET_CODE (operands[0]) == MEM
  4741.       && ! CONSTANT_ADDRESS_P (XEXP (operands[0], 0)))
  4742.     {
  4743.       operands[0] = XEXP (operands[0], 0);
  4744.       return AS1 (call,%*%0);
  4745.     }
  4746.   else
  4747.     return AS1 (call,%P0);
  4748. }")
  4749.  
  4750. (define_insn ""
  4751.   [(call (mem:QI (match_operand:SI 0 "symbolic_operand" ""))
  4752.      (match_operand:SI 1 "general_operand" "g"))]
  4753.   ;; Operand 1 not used on the i386.
  4754.   "!HALF_PIC_P ()"
  4755.   "call %P0")
  4756.  
  4757. ;; Call subroutine, returning value in operand 0
  4758. ;; (which must be a hard register).
  4759.  
  4760. (define_expand "call_value_pop"
  4761.   [(parallel [(set (match_operand 0 "" "")
  4762.            (call (match_operand:QI 1 "indirect_operand" "")
  4763.              (match_operand:SI 2 "general_operand" "")))
  4764.           (set (reg:SI 7)
  4765.            (plus:SI (reg:SI 7)
  4766.                 (match_operand:SI 4 "immediate_operand" "")))])]
  4767.   ""
  4768.   "
  4769. {
  4770.   rtx addr;
  4771.  
  4772. #ifdef MACHO_PIC
  4773.   if (flag_pic && GET_CODE (XEXP (operands[1], 0)) == SYMBOL_REF)
  4774.     { 
  4775.     extern rtx machopic_indirect_call_target();
  4776.     operands[1] = machopic_indirect_call_target (operands[1]);
  4777.     }
  4778. #else
  4779.   if (flag_pic)
  4780.     current_function_uses_pic_offset_table = 1;
  4781. #endif
  4782.   
  4783.   /* With half-pic, force the address into a register.  */
  4784.   addr = XEXP (operands[1], 0);
  4785.   if (GET_CODE (addr) != REG && HALF_PIC_P () && !CONSTANT_ADDRESS_P (addr))
  4786.     XEXP (operands[1], 0) = force_reg (Pmode, addr);
  4787.  
  4788.   if (! expander_call_insn_operand (operands[1], QImode))
  4789.     operands[1]
  4790.       = change_address (operands[1], VOIDmode,
  4791.             copy_to_mode_reg (Pmode, XEXP (operands[1], 0)));
  4792. }")
  4793.  
  4794. (define_insn ""
  4795.   [(set (match_operand 0 "" "=rf")
  4796.     (call (match_operand:QI 1 "call_insn_operand" "m")
  4797.           (match_operand:SI 2 "general_operand" "g")))
  4798.    (set (reg:SI 7) (plus:SI (reg:SI 7)
  4799.                 (match_operand:SI 4 "immediate_operand" "i")))]
  4800.   ""
  4801.   "*
  4802. {
  4803.   if (GET_CODE (operands[1]) == MEM
  4804.       && ! CONSTANT_ADDRESS_P (XEXP (operands[1], 0)))
  4805.     {
  4806.       operands[1] = XEXP (operands[1], 0);
  4807.       output_asm_insn (AS1 (call,%*%1), operands);
  4808.     }
  4809.   else
  4810.     output_asm_insn (AS1 (call,%P1), operands);
  4811.  
  4812.   RET;
  4813. }")
  4814.  
  4815. (define_insn ""
  4816.   [(set (match_operand 0 "" "=rf")
  4817.     (call (mem:QI (match_operand:SI 1 "symbolic_operand" ""))
  4818.           (match_operand:SI 2 "general_operand" "g")))
  4819.    (set (reg:SI 7) (plus:SI (reg:SI 7)
  4820.                 (match_operand:SI 4 "immediate_operand" "i")))]
  4821.   "!HALF_PIC_P ()"
  4822.   "call %P1")
  4823.  
  4824. (define_expand "call_value"
  4825.   [(set (match_operand 0 "" "")
  4826.     (call (match_operand:QI 1 "indirect_operand" "")
  4827.           (match_operand:SI 2 "general_operand" "")))]
  4828.   ;; Operand 2 not used on the i386.
  4829.   ""
  4830.   "
  4831. {
  4832.   rtx addr;
  4833.  
  4834. #ifdef MACHO_PIC
  4835.   if (flag_pic && GET_CODE (XEXP (operands[1], 0)) == SYMBOL_REF)
  4836.     { 
  4837.     extern rtx machopic_indirect_call_target();
  4838.     operands[1] = machopic_indirect_call_target (operands[1]);
  4839.     }
  4840. #else
  4841.   if (flag_pic)
  4842.     current_function_uses_pic_offset_table = 1;
  4843. #endif
  4844.  
  4845.   /* With half-pic, force the address into a register.  */
  4846.   addr = XEXP (operands[1], 0);
  4847.   if (GET_CODE (addr) != REG && HALF_PIC_P () && !CONSTANT_ADDRESS_P (addr))
  4848.     XEXP (operands[1], 0) = force_reg (Pmode, addr);
  4849.  
  4850.   if (! expander_call_insn_operand (operands[1], QImode))
  4851.     operands[1]
  4852.       = change_address (operands[1], VOIDmode,
  4853.             copy_to_mode_reg (Pmode, XEXP (operands[1], 0)));
  4854. }")
  4855.  
  4856. (define_insn ""
  4857.   [(set (match_operand 0 "" "=rf")
  4858.     (call (match_operand:QI 1 "call_insn_operand" "m")
  4859.           (match_operand:SI 2 "general_operand" "g")))]
  4860.   ;; Operand 2 not used on the i386.
  4861.   ""
  4862.   "*
  4863. {
  4864.   if (GET_CODE (operands[1]) == MEM
  4865.       && ! CONSTANT_ADDRESS_P (XEXP (operands[1], 0)))
  4866.     {
  4867.       operands[1] = XEXP (operands[1], 0);
  4868.       output_asm_insn (AS1 (call,%*%1), operands);
  4869.     }
  4870.   else
  4871.     output_asm_insn (AS1 (call,%P1), operands);
  4872.  
  4873.   RET;
  4874. }")
  4875.  
  4876. (define_insn ""
  4877.   [(set (match_operand 0 "" "=rf")
  4878.     (call (mem:QI (match_operand:SI 1 "symbolic_operand" ""))
  4879.           (match_operand:SI 2 "general_operand" "g")))]
  4880.   ;; Operand 2 not used on the i386.
  4881.   "!HALF_PIC_P ()"
  4882.   "call %P1")
  4883.  
  4884. (define_expand "untyped_call"
  4885.   [(parallel [(call (match_operand:QI 0 "indirect_operand" "")
  4886.             (const_int 0))
  4887.           (match_operand:BLK 1 "memory_operand" "")
  4888.           (match_operand 2 "" "")])]
  4889.   ""
  4890.   "
  4891. {
  4892.   rtx addr;
  4893.  
  4894.   if (flag_pic)
  4895.     current_function_uses_pic_offset_table = 1;
  4896.  
  4897.   /* With half-pic, force the address into a register.  */
  4898.   addr = XEXP (operands[0], 0);
  4899.   if (GET_CODE (addr) != REG && HALF_PIC_P () && !CONSTANT_ADDRESS_P (addr))
  4900.     XEXP (operands[0], 0) = force_reg (Pmode, addr);
  4901.  
  4902.   operands[1] = change_address (operands[1], DImode, XEXP (operands[1], 0));
  4903.   if (! expander_call_insn_operand (operands[1], QImode))
  4904.     operands[1]
  4905.       = change_address (operands[1], VOIDmode,
  4906.             copy_to_mode_reg (Pmode, XEXP (operands[1], 0)));
  4907. }")
  4908.  
  4909. (define_insn ""
  4910.   [(call (match_operand:QI 0 "call_insn_operand" "m")
  4911.      (const_int 0))
  4912.    (match_operand:DI 1 "memory_operand" "o")
  4913.    (match_operand 2 "" "")]
  4914.   ""
  4915.   "*
  4916. {
  4917.   rtx addr = operands[1];
  4918.  
  4919.   if (GET_CODE (operands[0]) == MEM
  4920.       && ! CONSTANT_ADDRESS_P (XEXP (operands[0], 0)))
  4921.     {
  4922.       operands[0] = XEXP (operands[0], 0);
  4923.       output_asm_insn (AS1 (call,%*%0), operands);
  4924.     }
  4925.   else
  4926.     output_asm_insn (AS1 (call,%P0), operands);
  4927.  
  4928.   operands[2] = gen_rtx (REG, SImode, 0);
  4929.   output_asm_insn (AS2 (mov%L2,%2,%1), operands);
  4930.  
  4931.   operands[2] = gen_rtx (REG, SImode, 1);
  4932.   operands[1] = adj_offsettable_operand (addr, 4);
  4933.   output_asm_insn (AS2 (mov%L2,%2,%1), operands);
  4934.  
  4935.   operands[1] = adj_offsettable_operand (addr, 8);
  4936.   return AS1 (fnsave,%1);
  4937. }")
  4938.  
  4939. (define_insn ""
  4940.   [(call (mem:QI (match_operand:SI 0 "symbolic_operand" ""))
  4941.      (const_int 0))
  4942.    (match_operand:DI 1 "memory_operand" "o")
  4943.    (match_operand 2 "" "")]
  4944.   "!HALF_PIC_P ()"
  4945.   "*
  4946. {
  4947.   rtx addr = operands[1];
  4948.  
  4949.   output_asm_insn (AS1 (call,%P0), operands);
  4950.  
  4951.   operands[2] = gen_rtx (REG, SImode, 0);
  4952.   output_asm_insn (AS2 (mov%L2,%2,%1), operands);
  4953.  
  4954.   operands[2] = gen_rtx (REG, SImode, 1);
  4955.   operands[1] = adj_offsettable_operand (addr, 4);
  4956.   output_asm_insn (AS2 (mov%L2,%2,%1), operands);
  4957.  
  4958.   operands[1] = adj_offsettable_operand (addr, 8);
  4959.   return AS1 (fnsave,%1);
  4960. }")
  4961.  
  4962. ;; We use fnsave and frstor to save and restore the floating point result.
  4963. ;; These are expensive instructions and require a large space to save the
  4964. ;; FPU state.  An more complicated alternative is to use fnstenv to store
  4965. ;; the FPU environment and test whether the stack top is valid.  Store the
  4966. ;; result of the test, and if it is valid, pop and save the value.  The
  4967. ;; untyped_return would check the test and optionally push the saved value.
  4968.  
  4969. (define_expand "untyped_return"
  4970.   [(match_operand:BLK 0 "memory_operand" "")
  4971.    (match_operand 1 "" "")]
  4972.   ""
  4973.   "
  4974. {
  4975.   rtx valreg1 = gen_rtx (REG, SImode, 0);
  4976.   rtx valreg2 = gen_rtx (REG, SImode, 1);
  4977.   rtx result = operands[0];
  4978.  
  4979.   /* Restore the FPU state.  */
  4980.   emit_insn (gen_update_return (change_address (result, SImode,
  4981.                         plus_constant (XEXP (result, 0),
  4982.                                    8))));
  4983.  
  4984.   /* Reload the function value registers.  */
  4985.   emit_move_insn (valreg1, change_address (result, SImode, XEXP (result, 0)));
  4986.   emit_move_insn (valreg2,
  4987.           change_address (result, SImode,
  4988.                   plus_constant (XEXP (result, 0), 4)));
  4989.  
  4990.   /* Put USE insns before the return.  */
  4991.   emit_insn (gen_rtx (USE, VOIDmode, valreg1));
  4992.   emit_insn (gen_rtx (USE, VOIDmode, valreg2));
  4993.  
  4994.   /* Construct the return.  */
  4995.   expand_null_return ();
  4996.  
  4997.   DONE;
  4998. }")
  4999.  
  5000. (define_insn "update_return"
  5001.   [(unspec:SI [(match_operand:SI 0 "memory_operand" "m")] 0)]
  5002.   ""
  5003.   "frstor %0")
  5004.  
  5005. ;; Insn emitted into the body of a function to return from a function.
  5006. ;; This is only done if the function's epilogue is known to be simple.
  5007. ;; See comments for simple_386_epilogue in i386.c.
  5008.  
  5009. (define_insn "return"
  5010.   [(return)]
  5011.   "simple_386_epilogue ()"
  5012.   "*
  5013. {
  5014.   function_epilogue (asm_out_file, get_frame_size ());
  5015.   RET;
  5016. }")
  5017.  
  5018. (define_insn "nop"
  5019.   [(const_int 0)]
  5020.   ""
  5021.   "nop")
  5022.  
  5023. (define_expand "movstrsi"
  5024.   [(parallel [(set (match_operand:BLK 0 "memory_operand" "")
  5025.            (match_operand:BLK 1 "memory_operand" ""))
  5026.           (use (match_operand:SI 2 "const_int_operand" ""))
  5027.           (use (match_operand:SI 3 "const_int_operand" ""))
  5028.           (clobber (match_scratch:SI 4 ""))
  5029.           (clobber (match_dup 5))
  5030.           (clobber (match_dup 6))])]
  5031.   ""
  5032.   "
  5033. {
  5034.   rtx addr0, addr1;
  5035.  
  5036.   if (GET_CODE (operands[2]) != CONST_INT)
  5037.     FAIL;
  5038.  
  5039.   addr0 = copy_to_mode_reg (Pmode, XEXP (operands[0], 0));
  5040.   addr1 = copy_to_mode_reg (Pmode, XEXP (operands[1], 0));
  5041.  
  5042.   operands[5] = addr0;
  5043.   operands[6] = addr1;
  5044.  
  5045.   operands[0] = gen_rtx (MEM, BLKmode, addr0);
  5046.   operands[1] = gen_rtx (MEM, BLKmode, addr1);
  5047. }")
  5048.  
  5049. ;; It might seem that operands 0 & 1 could use predicate register_operand.
  5050. ;; But strength reduction might offset the MEM expression.  So we let
  5051. ;; reload put the address into %edi & %esi.
  5052.  
  5053. (define_insn ""
  5054.   [(set (mem:BLK (match_operand:SI 0 "address_operand" "D"))
  5055.     (mem:BLK (match_operand:SI 1 "address_operand" "S")))
  5056.    (use (match_operand:SI 2 "const_int_operand" "n"))
  5057.    (use (match_operand:SI 3 "immediate_operand" "i"))
  5058.    (clobber (match_scratch:SI 4 "=&c"))
  5059.    (clobber (match_dup 0))
  5060.    (clobber (match_dup 1))]
  5061.   ""
  5062.   "*
  5063. {
  5064.   rtx xops[2];
  5065.  
  5066.   output_asm_insn (\"cld\", operands);
  5067.   if (GET_CODE (operands[2]) == CONST_INT)
  5068.     {
  5069.       if (INTVAL (operands[2]) & ~0x03)
  5070.     {
  5071.       xops[0] = GEN_INT ((INTVAL (operands[2]) >> 2) & 0x3fffffff);
  5072.       xops[1] = operands[4];
  5073.  
  5074.       output_asm_insn (AS2 (mov%L1,%0,%1), xops);
  5075. #ifdef INTEL_SYNTAX
  5076.       output_asm_insn (\"rep movsd\", xops);
  5077. #else
  5078.       output_asm_insn (\"rep\;movsl\", xops);
  5079. #endif
  5080.     }
  5081.       if (INTVAL (operands[2]) & 0x02)
  5082.     output_asm_insn (\"movsw\", operands);
  5083.       if (INTVAL (operands[2]) & 0x01)
  5084.     output_asm_insn (\"movsb\", operands);
  5085.     }
  5086.   else
  5087.     abort ();
  5088.   RET;
  5089. }")
  5090.  
  5091. (define_expand "cmpstrsi"
  5092.   [(parallel [(set (match_operand:SI 0 "general_operand" "")
  5093.            (compare:SI (match_operand:BLK 1 "general_operand" "")
  5094.                    (match_operand:BLK 2 "general_operand" "")))
  5095.           (use (match_operand:SI 3 "general_operand" ""))
  5096.           (use (match_operand:SI 4 "immediate_operand" ""))
  5097.           (clobber (match_dup 5))
  5098.           (clobber (match_dup 6))
  5099.           (clobber (match_dup 3))])]
  5100.   ""
  5101.   "
  5102. {
  5103.   rtx addr1, addr2;
  5104.  
  5105.   addr1 = copy_to_mode_reg (Pmode, XEXP (operands[1], 0));
  5106.   addr2 = copy_to_mode_reg (Pmode, XEXP (operands[2], 0));
  5107.   operands[3] = copy_to_mode_reg (SImode, operands[3]);
  5108.  
  5109.   operands[5] = addr1;
  5110.   operands[6] = addr2;
  5111.  
  5112.   operands[1] = gen_rtx (MEM, BLKmode, addr1);
  5113.   operands[2] = gen_rtx (MEM, BLKmode, addr2);
  5114.  
  5115. }")
  5116.  
  5117. ;; memcmp recognizers.  The `cmpsb' opcode does nothing if the count is
  5118. ;; zero.  Emit extra code to make sure that a zero-length compare is EQ.
  5119.  
  5120. ;; It might seem that operands 0 & 1 could use predicate register_operand.
  5121. ;; But strength reduction might offset the MEM expression.  So we let
  5122. ;; reload put the address into %edi & %esi.
  5123.  
  5124. ;; ??? Most comparisons have a constant length, and it's therefore
  5125. ;; possible to know that the length is non-zero, and to avoid the extra
  5126. ;; code to handle zero-length compares.
  5127.  
  5128. (define_insn ""
  5129.   [(set (match_operand:SI 0 "general_operand" "=&r")
  5130.     (compare:SI (mem:BLK (match_operand:SI 1 "address_operand" "S"))
  5131.             (mem:BLK (match_operand:SI 2 "address_operand" "D"))))
  5132.    (use (match_operand:SI 3 "register_operand" "c"))
  5133.    (use (match_operand:SI 4 "immediate_operand" "i"))
  5134.    (clobber (match_dup 1))
  5135.    (clobber (match_dup 2))
  5136.    (clobber (match_dup 3))]
  5137.   ""
  5138.   "*
  5139. {
  5140.   rtx xops[4], label;
  5141.  
  5142.   label = gen_label_rtx ();
  5143.  
  5144.   output_asm_insn (\"cld\", operands);
  5145.   output_asm_insn (AS2 (xor%L0,%0,%0), operands);
  5146.   output_asm_insn (\"repz\;cmps%B2\", operands);
  5147.   output_asm_insn (\"je %l0\", &label);
  5148.  
  5149.   xops[0] = operands[0];
  5150.   xops[1] = gen_rtx (MEM, QImode,
  5151.              gen_rtx (PLUS, SImode, operands[1], constm1_rtx));
  5152.   xops[2] = gen_rtx (MEM, QImode,
  5153.              gen_rtx (PLUS, SImode, operands[2], constm1_rtx));
  5154.   xops[3] = operands[3];
  5155.  
  5156.   output_asm_insn (AS2 (movz%B1%L0,%1,%0), xops);
  5157.   output_asm_insn (AS2 (movz%B2%L3,%2,%3), xops);
  5158.  
  5159.   output_asm_insn (AS2 (sub%L0,%3,%0), xops);
  5160.   ASM_OUTPUT_INTERNAL_LABEL (asm_out_file, \"L\", CODE_LABEL_NUMBER (label));
  5161.   RET;
  5162. }")
  5163.  
  5164. (define_insn ""
  5165.   [(set (cc0)
  5166.     (compare:SI (mem:BLK (match_operand:SI 0 "address_operand" "S"))
  5167.             (mem:BLK (match_operand:SI 1 "address_operand" "D"))))
  5168.    (use (match_operand:SI 2 "register_operand" "c"))
  5169.    (use (match_operand:SI 3 "immediate_operand" "i"))
  5170.    (clobber (match_dup 0))
  5171.    (clobber (match_dup 1))
  5172.    (clobber (match_dup 2))]
  5173.   ""
  5174.   "*
  5175. {
  5176.   rtx xops[2];
  5177.  
  5178.   cc_status.flags |= CC_NOT_SIGNED;
  5179.  
  5180.   xops[0] = gen_rtx (REG, QImode, 0);
  5181.   xops[1] = CONST0_RTX (QImode);
  5182.  
  5183.   output_asm_insn (\"cld\", operands);
  5184.   output_asm_insn (AS2 (test%B0,%1,%0), xops);
  5185.   return \"repz\;cmps%B2\";
  5186. }")
  5187.  
  5188. (define_expand "ffssi2"
  5189.   [(set (match_dup 2)
  5190.     (plus:SI (ffs:SI (match_operand:SI 1 "general_operand" ""))
  5191.          (const_int -1)))
  5192.    (set (match_operand:SI 0 "general_operand" "")
  5193.     (plus:SI (match_dup 2) (const_int 1)))]
  5194.   ""
  5195.   "operands[2] = gen_reg_rtx (SImode);")
  5196.  
  5197. (define_insn ""
  5198.   [(set (match_operand:SI 0 "general_operand" "=&r")
  5199.     (plus:SI (ffs:SI (match_operand:SI 1 "general_operand" "rm"))
  5200.          (const_int -1)))]
  5201.   ""
  5202.   "*
  5203. {
  5204.   rtx xops[3];
  5205.   static int ffssi_label_number;
  5206.   char buffer[30];
  5207.  
  5208.   xops[0] = operands[0];
  5209.   xops[1] = operands[1];
  5210.   xops[2] = constm1_rtx;
  5211.   /* Can there be a way to avoid the jump here?  */
  5212.   output_asm_insn (AS2 (bsf%L0,%1,%0), xops);
  5213. #ifdef LOCAL_LABEL_PREFIX
  5214.   sprintf (buffer, \"jnz %sLFFSSI%d\",
  5215.        LOCAL_LABEL_PREFIX, ffssi_label_number);
  5216. #else
  5217.   sprintf (buffer, \"jnz %sLFFSSI%d\",
  5218.        \"\", ffssi_label_number);
  5219. #endif
  5220.   output_asm_insn (buffer, xops);
  5221.   output_asm_insn (AS2 (mov%L0,%2,%0), xops);
  5222. #ifdef LOCAL_LABEL_PREFIX
  5223.   sprintf (buffer, \"%sLFFSSI%d:\",
  5224.        LOCAL_LABEL_PREFIX, ffssi_label_number);
  5225. #else
  5226.   sprintf (buffer, \"%sLFFSSI%d:\",
  5227.        \"\", ffssi_label_number);
  5228. #endif
  5229.   output_asm_insn (buffer, xops);
  5230.  
  5231.   ffssi_label_number++;
  5232.   return \"\";
  5233. }")
  5234.  
  5235. (define_expand "ffshi2"
  5236.   [(set (match_dup 2)
  5237.     (plus:HI (ffs:HI (match_operand:HI 1 "general_operand" ""))
  5238.          (const_int -1)))
  5239.    (set (match_operand:HI 0 "general_operand" "")
  5240.     (plus:HI (match_dup 2) (const_int 1)))]
  5241.   ""
  5242.   "operands[2] = gen_reg_rtx (HImode);")
  5243.  
  5244. (define_insn ""
  5245.   [(set (match_operand:HI 0 "general_operand" "=&r")
  5246.     (plus:HI (ffs:HI (match_operand:SI 1 "general_operand" "rm"))
  5247.          (const_int -1)))]
  5248.   ""
  5249.   "*
  5250. {
  5251.   rtx xops[3];
  5252.   static int ffshi_label_number;
  5253.   char buffer[30];
  5254.  
  5255.   xops[0] = operands[0];
  5256.   xops[1] = operands[1];
  5257.   xops[2] = constm1_rtx;
  5258.   output_asm_insn (AS2 (bsf%W0,%1,%0), xops);
  5259. #ifdef LOCAL_LABEL_PREFIX
  5260.   sprintf (buffer, \"jnz %sLFFSHI%d\",
  5261.        LOCAL_LABEL_PREFIX, ffshi_label_number);
  5262. #else
  5263.   sprintf (buffer, \"jnz %sLFFSHI%d\",
  5264.        \"\", ffshi_label_number);
  5265. #endif
  5266.   output_asm_insn (buffer, xops);
  5267.   output_asm_insn (AS2 (mov%W0,%2,%0), xops);
  5268. #ifdef LOCAL_LABEL_PREFIX
  5269.   sprintf (buffer, \"%sLFFSHI%d:\",
  5270.        LOCAL_LABEL_PREFIX, ffshi_label_number);
  5271. #else
  5272.   sprintf (buffer, \"%sLFFSHI%d:\",
  5273.        \"\", ffshi_label_number);
  5274. #endif
  5275.   output_asm_insn (buffer, xops);
  5276.  
  5277.   ffshi_label_number++;
  5278.   return \"\";
  5279. }")
  5280.  
  5281. ;; These patterns match the binary 387 instructions for addM3, subM3,
  5282. ;; mulM3 and divM3.  There are three patterns for each of DFmode and
  5283. ;; SFmode.  The first is the normal insn, the second the same insn but
  5284. ;; with one operand a conversion, and the third the same insn but with
  5285. ;; the other operand a conversion.  The conversion may be SFmode or
  5286. ;; SImode if the target mode DFmode, but only SImode if the target mode
  5287. ;; is SFmode.
  5288.  
  5289. (define_insn ""
  5290.   [(set (match_operand:DF 0 "register_operand" "=f,f")
  5291.     (match_operator:DF 3 "binary_387_op"
  5292.             [(match_operand:DF 1 "nonimmediate_operand" "0,fm")
  5293.              (match_operand:DF 2 "nonimmediate_operand" "fm,0")]))]
  5294.   "TARGET_80387"
  5295.   "* return (char *) output_387_binary_op (insn, operands);"
  5296.   [(set_attr "fppc" "double")])
  5297.  
  5298. (define_insn ""
  5299.   [(set (match_operand:DF 0 "register_operand" "=f")
  5300.     (match_operator:DF 3 "binary_387_op"
  5301.        [(float:DF (match_operand:SI 1 "general_operand" "rm"))
  5302.         (match_operand:DF 2 "general_operand" "0")]))]
  5303.   "TARGET_80387"
  5304.   "* return (char *) output_387_binary_op (insn, operands);"
  5305.   [(set_attr "fppc" "double")])
  5306.  
  5307. (define_insn ""
  5308.   [(set (match_operand:XF 0 "register_operand" "=f,f")
  5309.     (match_operator:XF 3 "binary_387_op"
  5310.             [(match_operand:XF 1 "nonimmediate_operand" "0,f")
  5311.              (match_operand:XF 2 "nonimmediate_operand" "f,0")]))]
  5312.   "TARGET_80387"
  5313.   "* return (char *) output_387_binary_op (insn, operands);")
  5314.  
  5315. (define_insn ""
  5316.   [(set (match_operand:XF 0 "register_operand" "=f")
  5317.     (match_operator:XF 3 "binary_387_op"
  5318.        [(float:XF (match_operand:SI 1 "general_operand" "rm"))
  5319.         (match_operand:XF 2 "general_operand" "0")]))]
  5320.   "TARGET_80387"
  5321.   "* return (char *) output_387_binary_op (insn, operands);")
  5322.  
  5323. (define_insn ""
  5324.   [(set (match_operand:XF 0 "register_operand" "=f,f")
  5325.     (match_operator:XF 3 "binary_387_op"
  5326.        [(float_extend:XF (match_operand:SF 1 "general_operand" "fm,0"))
  5327.         (match_operand:XF 2 "general_operand" "0,f")]))]
  5328.   "TARGET_80387"
  5329.   "* return (char *) output_387_binary_op (insn, operands);")
  5330.  
  5331. (define_insn ""
  5332.   [(set (match_operand:XF 0 "register_operand" "=f")
  5333.     (match_operator:XF 3 "binary_387_op"
  5334.       [(match_operand:XF 1 "general_operand" "0")
  5335.        (float:XF (match_operand:SI 2 "general_operand" "rm"))]))]
  5336.   "TARGET_80387"
  5337.   "* return (char *) output_387_binary_op (insn, operands);")
  5338.  
  5339. (define_insn ""
  5340.   [(set (match_operand:XF 0 "register_operand" "=f,f")
  5341.     (match_operator:XF 3 "binary_387_op"
  5342.       [(match_operand:XF 1 "general_operand" "0,f")
  5343.        (float_extend:XF
  5344.         (match_operand:SF 2 "general_operand" "fm,0"))]))]
  5345.   "TARGET_80387"
  5346.   "* return (char *) output_387_binary_op (insn, operands);")
  5347.  
  5348. (define_insn ""
  5349.   [(set (match_operand:DF 0 "register_operand" "=f,f")
  5350.     (match_operator:DF 3 "binary_387_op"
  5351.        [(float_extend:DF (match_operand:SF 1 "general_operand" "fm,0"))
  5352.         (match_operand:DF 2 "general_operand" "0,f")]))]
  5353.   "TARGET_80387"
  5354.   "* return (char *) output_387_binary_op (insn, operands);"
  5355.   [(set_attr "fppc" "double")])
  5356.  
  5357. (define_insn ""
  5358.   [(set (match_operand:DF 0 "register_operand" "=f")
  5359.     (match_operator:DF 3 "binary_387_op"
  5360.       [(match_operand:DF 1 "general_operand" "0")
  5361.        (float:DF (match_operand:SI 2 "general_operand" "rm"))]))]
  5362.   "TARGET_80387"
  5363.   "* return (char *) output_387_binary_op (insn, operands);"
  5364.   [(set_attr "fppc" "double")])
  5365.  
  5366. (define_insn ""
  5367.   [(set (match_operand:DF 0 "register_operand" "=f,f")
  5368.     (match_operator:DF 3 "binary_387_op"
  5369.       [(match_operand:DF 1 "general_operand" "0,f")
  5370.        (float_extend:DF
  5371.         (match_operand:SF 2 "general_operand" "fm,0"))]))]
  5372.   "TARGET_80387"
  5373.   "* return (char *) output_387_binary_op (insn, operands);"
  5374.   [(set_attr "fppc" "double")])
  5375.  
  5376. (define_insn ""
  5377.   [(set (match_operand:SF 0 "register_operand" "=f,f")
  5378.     (match_operator:SF 3 "binary_387_op"
  5379.             [(match_operand:SF 1 "nonimmediate_operand" "0,fm")
  5380.              (match_operand:SF 2 "nonimmediate_operand" "fm,0")]))]
  5381.   "TARGET_80387"
  5382.   "* return (char *) output_387_binary_op (insn, operands);"
  5383.   [(set_attr "fppc" "single")])
  5384.  
  5385. (define_insn ""
  5386.   [(set (match_operand:SF 0 "register_operand" "=f")
  5387.     (match_operator:SF 3 "binary_387_op"
  5388.       [(float:SF (match_operand:SI 1 "general_operand" "rm"))
  5389.        (match_operand:SF 2 "general_operand" "0")]))]
  5390.   "TARGET_80387"
  5391.   "* return (char *) output_387_binary_op (insn, operands);"
  5392.   [(set_attr "fppc" "single")])
  5393.  
  5394. (define_insn ""
  5395.   [(set (match_operand:SF 0 "register_operand" "=f")
  5396.     (match_operator:SF 3 "binary_387_op"
  5397.       [(match_operand:SF 1 "general_operand" "0")
  5398.        (float:SF (match_operand:SI 2 "general_operand" "rm"))]))]
  5399.   "TARGET_80387"
  5400.   "* return (char *) output_387_binary_op (insn, operands);"
  5401.   [(set_attr "fppc" "single")])
  5402.  
  5403. (define_expand "strlensi"
  5404.   [(parallel [(set (match_dup 4)
  5405.            (unspec:SI [(mem:BLK (match_operand:BLK 1 "general_operand" ""))
  5406.                    (match_operand:QI 2 "register_operand" "")
  5407.                    (match_operand:SI 3 "immediate_operand" "")] 0))
  5408.           (clobber (match_dup 1))])
  5409.    (set (match_dup 5)
  5410.     (not:SI (match_dup 4)))
  5411.    (set (match_operand:SI 0 "register_operand" "")
  5412.     (minus:SI (match_dup 5)
  5413.          (const_int 1)))]
  5414.   ""
  5415.   "
  5416. {
  5417.   operands[1] = copy_to_mode_reg (SImode, XEXP (operands[1], 0));
  5418.   operands[4] = gen_reg_rtx (SImode);
  5419.   operands[5] = gen_reg_rtx (SImode);
  5420. }")
  5421.  
  5422. ;; It might seem that operands 0 & 1 could use predicate register_operand.
  5423. ;; But strength reduction might offset the MEM expression.  So we let
  5424. ;; reload put the address into %edi.
  5425.  
  5426. (define_insn ""
  5427.   [(set (match_operand:SI 0 "register_operand" "=&c")
  5428.     (unspec:SI [(mem:BLK (match_operand:SI 1 "address_operand" "D"))
  5429.             (match_operand:QI 2 "register_operand" "a")
  5430.             (match_operand:SI 3 "immediate_operand" "i")] 0))
  5431.    (clobber (match_dup 1))]
  5432.   ""
  5433.   "*
  5434. {
  5435.   rtx xops[2];
  5436.  
  5437.   xops[0] = operands[0];
  5438.   xops[1] = constm1_rtx;
  5439.   output_asm_insn (\"cld\", operands);
  5440.   output_asm_insn (AS2 (mov%L0,%1,%0), xops);
  5441.   return \"repnz\;scas%B2\";
  5442. }")
  5443.  
  5444.  
  5445. ;; Switch the floating-point precision control between single and double.
  5446. ;; This doesn't work if the precision control is set to extended.
  5447.  
  5448. (define_insn "fppc_switch"
  5449.   [(unspec [(match_operand:HI 0 "memory_operand" "m")] 0)]
  5450.   ""
  5451.   "fnstcw %0\;xorw $512,%0\;fldcw %0")
  5452.  
  5453.  
  5454.