home *** CD-ROM | disk | FTP | other *** search
/ Fresh Fish 6 / FreshFish_September1994.bin / bbs / gnu / gcc-2.6.0-src.lha / GNU / src / amiga / gcc-2.6.0 / config / i386 / i386.md < prev    next >
Encoding:
Text File  |  1994-06-15  |  139.6 KB  |  5,296 lines

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