home *** CD-ROM | disk | FTP | other *** search
/ OpenStep 4.2J (Developer) / os42jdev.iso / NextDeveloper / Source / GNU / gcc / config / i386 / i386.md < prev    next >
Text File  |  1995-12-27  |  164KB  |  6,019 lines

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