home *** CD-ROM | disk | FTP | other *** search
/ Fresh Fish 7 / FreshFishVol7.bin / bbs / gnu / gcc-2.3.3-src.lha / GNU / src / amiga / gcc-2.3.3 / config / i386.md < prev    next >
Text File  |  1994-02-06  |  113KB  |  4,275 lines

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