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