home *** CD-ROM | disk | FTP | other *** search
/ Education Sampler 1992 [NeXTSTEP] / Education_1992_Sampler.iso / NeXT / GnuSource / cplusplus-8 / config / mips.md < prev    next >
Encoding:
Text File  |  1990-12-03  |  48.6 KB  |  1,958 lines

  1. ;;  Mips.md        Naive version of Machine Description for MIPS
  2. ;;  Contributed by   A. Lichnewsky, lich@inria.inria.fr
  3. ;;  Changes by       Michael Meissner, meissner@osf.org
  4. ;;  Copyright (C) 1989, 1990 Free Software Foundation, Inc.
  5.  
  6. ;; This file is part of GNU CC.
  7.  
  8. ;; GNU CC is free software; you can redistribute it and/or modify
  9. ;; it under the terms of the GNU General Public License as published by
  10. ;; the Free Software Foundation; either version 1, or (at your option)
  11. ;; any later version.
  12.  
  13. ;; GNU CC is distributed in the hope that it will be useful,
  14. ;; but WITHOUT ANY WARRANTY; without even the implied warranty of
  15. ;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
  16. ;; GNU General Public License for more details.
  17.  
  18. ;; You should have received a copy of the GNU General Public License
  19. ;; along with GNU CC; see the file COPYING.  If not, write to
  20. ;; the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA.
  21.  
  22. ;;
  23. ;;------------------------------------------------------------------------
  24. ;;
  25.  
  26. ;;
  27. ;;  ....................
  28. ;;
  29. ;;  Peephole Optimizations for
  30. ;;
  31. ;;          ARITHMETIC
  32. ;;
  33. ;;  ....................
  34. ;;
  35.                     ;;- The following peepholes are
  36.                     ;;- motivated by the fact that
  37.                     ;;- stack movement result in some
  38.                     ;;- cases in embarrassing sequences
  39.                     ;;- of addiu SP,SP,int
  40.                     ;;-    addiu SP,SP,other_int
  41.  
  42.                     ;;- --------------------
  43.                     ;;- REMARK: this would be done better
  44.                     ;;- by analysis of dependencies in
  45.                     ;;- basic blocks, prior to REG ALLOC,
  46.                     ;;- and simplification of trees:
  47.                     ;;-      (+  (+ REG const) const)
  48.                     ;;- ->   (+ REG newconst)
  49.                     ;;- --------------------
  50.                     ;;- Merged peephole code from
  51.                     ;;- raeburn@ATHENA.MIT.EDU
  52.  
  53. (define_peephole
  54.   [(set (match_operand:SI 0 "register_operand" "=r")
  55.         (match_operator 1 "additive_op"
  56.                         [(match_operand:SI 2 "register_operand" "r")
  57.                          (match_operand:SI 3 "small_int" "I")]))
  58.    (set (match_operand:SI 4 "register_operand" "=r")
  59.         (match_operator 5 "additive_op"
  60.                         [(match_dup 0)
  61.                          (match_operand:SI 6 "small_int" "I")]))]
  62.   "(REGNO (operands[0]) == REGNO (operands[4])
  63.     || dead_or_set_p (insn, operands[0]))"
  64.   "*
  65. {
  66.   int addend;
  67.   /* compute sum, with signs */
  68.   addend = INTVAL (operands[3]) * (GET_CODE (operands[1]) == PLUS ? 1 : -1);
  69.   addend += INTVAL (operands[6]) * (GET_CODE (operands[5]) == PLUS ? 1 : -1);
  70.   if (addend != 0)
  71.     {
  72.       operands[0] = gen_rtx (CONST_INT, VOIDmode, addend);
  73.       return \"addi%:\\t%4,%2,%0\";
  74.     }
  75.   /* value is zero; copy */
  76.   if (REGNO (operands[4]) != REGNO (operands[2]))
  77.     return \"add%:\\t%4,%2,$0\";
  78.   /* copying to self; punt */
  79.   return \" # null operation: additive operands cancel (%0,%2)\";
  80. }")
  81.  
  82. ;;
  83. ;;  ....................
  84. ;;
  85. ;;          ARITHMETIC
  86. ;;
  87. ;;  ....................
  88. ;;
  89.  
  90. (define_insn "adddf3"
  91.   [(set (match_operand:DF 0 "register_operand" "=f")
  92.     (plus:DF (match_operand:DF 1 "register_operand" "f")
  93.          (match_operand:DF 2 "register_operand" "f")))]
  94.   ""
  95.   "add.d\\t%0,%1,%2")
  96.  
  97. (define_insn "addsf3"
  98.   [(set (match_operand:SF 0 "register_operand" "=f")
  99.     (plus:SF (match_operand:SF 1 "register_operand" "f")
  100.          (match_operand:SF 2 "register_operand" "f")))]
  101.   ""
  102.   "add.s\\t%0,%1,%2")
  103.  
  104. ;; The following is generated when omiting the frame pointer
  105. ;; and for referencing large auto arrays during optimization.
  106.  
  107. (define_insn ""
  108.   [(set (match_operand:SI 0 "register_operand" "=r")
  109.     (plus:SI (match_operand:SI 1 "register_operand" "%r")
  110.          (match_operand:SI 2 "immediate_operand" "i")))]
  111.   "operands[1] == stack_pointer_rtx || operands[1] == frame_pointer_rtx"
  112.   "*
  113. {
  114.   int number;
  115.   if (GET_CODE (operands[2]) != CONST_INT)
  116.     return \"add%:\\t%0,%1,%2\";
  117.  
  118.   number = INTVAL (operands[2]);
  119.   if (((unsigned) (number + 0x8000) > 0xffff))
  120.     {
  121.       operands[3] = gen_rtx (REG, SImode, 1);    /* assembler temp. */
  122.       return \".set\\tnoat\\n\\tli\\t%3,%2\\n\\tadd%:\\t%0,%1,%3\\n\\t.set\\tat\";
  123.     }
  124.  
  125.   return (number < 0) ? \"sub%:\\t%0,%1,%n2\" : \"add%:\\t%0,%1,%2\";
  126. }")
  127.  
  128. (define_insn "addsi3"
  129.   [(set (match_operand:SI 0 "register_operand" "=r")
  130.     (plus:SI (match_operand:SI 1 "arith_operand" "%r")
  131.          (match_operand:SI 2 "arith_operand" "rI")))]
  132.   ""
  133.   "*
  134. {
  135.   return (GET_CODE (operands[2]) == CONST_INT && INTVAL (operands[2]) < 0)
  136.     ? \"sub%:\\t%0,%1,%n2\"
  137.     : \"add%:\\t%0,%1,%2\";
  138. }")
  139.  
  140.  
  141. ;;- All kinds of subtract instructions.
  142.  
  143. (define_insn "subdf3"
  144.   [(set (match_operand:DF 0 "register_operand" "=f")
  145.     (minus:DF (match_operand:DF 1 "register_operand" "f")
  146.           (match_operand:DF 2 "register_operand" "f")))]
  147.   ""
  148.   "sub.d\\t%0,%1,%2")
  149.  
  150. (define_insn "subsf3"
  151.   [(set (match_operand:SF 0 "register_operand" "=f")
  152.     (minus:SF (match_operand:SF 1 "register_operand" "f")
  153.           (match_operand:SF 2 "register_operand" "f")))]
  154.   ""
  155.   "sub.s\\t%0,%1,%2")
  156.  
  157. ;; The following is generated when omiting the frame pointer
  158. ;; and for referencing large auto arrays during optimization.
  159.  
  160. (define_insn ""
  161.   [(set (match_operand:SI 0 "register_operand" "=r")
  162.     (minus:SI (match_operand:SI 1 "register_operand" "%r")
  163.           (match_operand:SI 2 "immediate_operand" "i")))]
  164.   "operands[1] == stack_pointer_rtx || operands[1] == frame_pointer_rtx"
  165.   "*
  166. {
  167.   int number;
  168.   if (GET_CODE (operands[2]) != CONST_INT)
  169.     return \"sub%:\\t%0,%1,%2\";
  170.  
  171.   number = INTVAL (operands[2]);
  172.   if (((unsigned) (number + 0x8000) > 0xffff))
  173.     {
  174.       operands[3] = gen_rtx (REG, SImode, 1);    /* assembler temp. */
  175.       return \".set\\tnoat\\n\\tli\\t%3,%2\\n\\tsub%:\\t%0,%1,%3\\n\\t.set\\tat\";
  176.     }
  177.  
  178.   return (number < 0) ? \"add%:\\t%0,%1,%n2\" : \"sub%:\\t%0,%1,%2\";
  179. }")
  180.  
  181. (define_insn "subsi3"
  182.   [(set (match_operand:SI 0 "register_operand" "=r")
  183.     (minus:SI (match_operand:SI 1 "register_operand" "r")
  184.           (match_operand:SI 2 "arith_operand" "rI")))]
  185.   ""
  186.   "*
  187. {
  188.   return (GET_CODE (operands[2]) == CONST_INT && INTVAL (operands[2]) < 0)
  189.     ? \"add%:\\t%0,%1,%n2\"
  190.     : \"sub%:\\t%0,%1,%2\";
  191. }")
  192.  
  193.  
  194. ;;- Multiply instructions.
  195.  
  196. (define_insn "muldf3"
  197.   [(set (match_operand:DF 0 "register_operand" "=f")
  198.     (mult:DF (match_operand:DF 1 "register_operand" "f")
  199.          (match_operand:DF 2 "register_operand" "f")))]
  200.   ""
  201.   "mul.d\\t%0,%1,%2")
  202.  
  203. (define_insn "mulsf3"
  204.   [(set (match_operand:SF 0 "register_operand" "=f")
  205.     (mult:SF (match_operand:SF 1 "register_operand" "f")
  206.          (match_operand:SF 2 "register_operand" "f")))]
  207.   ""
  208.   "mul.s\\t%0,%1,%2")
  209.  
  210. (define_insn "mulsi3"
  211.   [(set (match_operand:SI 0 "register_operand" "=r")
  212.     (mult:SI (match_operand:SI 1 "arith_operand" "%r")
  213.          (match_operand:SI 2 "arith_operand" "rI")))]
  214.   ""
  215.   "mul\\t%0,%1,%2")
  216.  
  217.  
  218. ;;- Divide instructions.
  219.  
  220. (define_insn "divdf3"
  221.   [(set (match_operand:DF 0 "register_operand" "=f")
  222.     (div:DF (match_operand:DF 1 "register_operand" "f")
  223.         (match_operand:DF 2 "register_operand" "f")))]
  224.   ""
  225.   "div.d\\t%0,%1,%2")
  226.  
  227. (define_insn "divsf3"
  228.   [(set (match_operand:SF 0 "register_operand" "=f")
  229.     (div:SF (match_operand:SF 1 "register_operand" "f")
  230.         (match_operand:SF 2 "register_operand" "f")))]
  231.   ""
  232.   "div.s\\t%0,%1,%2")
  233.  
  234. (define_insn "divmodsi4"
  235.   [(set (match_operand:SI 0 "register_operand" "=r")
  236.     (div:SI (match_operand:SI 1 "register_operand" "r")
  237.         (match_operand:SI 2 "arith_operand" "rI")))
  238.    (set (match_operand:SI 3 "register_operand" "=r")
  239.     (mod:SI (match_dup 1)
  240.         (match_dup 2)))]
  241.   ""
  242.   "div\\t$0,%1,%2\\n\\tmflo\\t%0\\t\\t#quotient\\n\\tmfhi\\t%3\\t\\t#remainder")
  243.  
  244. (define_insn "divsi3"
  245.   [(set (match_operand:SI 0 "register_operand" "=r")
  246.     (div:SI (match_operand:SI 1 "register_operand" "r")
  247.         (match_operand:SI 2 "arith_operand" "rI")))]
  248.   ""
  249.   "div\\t%0,%1,%2")
  250.  
  251. (define_insn "udivmodsi4"
  252.   [(set (match_operand:SI 0 "register_operand" "=r")
  253.     (udiv:SI (match_operand:SI 1 "register_operand" "r")
  254.          (match_operand:SI 2 "arith_operand" "rI")))
  255.    (set (match_operand:SI 3 "register_operand" "=r")
  256.     (umod:SI (match_dup 1)
  257.          (match_dup 2)))]
  258.   ""
  259.   "divu\\t$0,%1,%2\\n\\tmflo\\t%0\\t\\t#quotient\\n\\tmfhi\\t%3\\t\\t#remainder")
  260.  
  261. (define_insn "udivsi3"
  262.   [(set (match_operand:SI 0 "register_operand" "=r")
  263.     (udiv:SI (match_operand:SI 1 "register_operand" "r")
  264.          (match_operand:SI 2 "arith_operand" "rI")))]
  265.   ""
  266.   "divu\\t%0,%1,%2")
  267.  
  268.  
  269. ;; Remainder instructions
  270.  
  271.  
  272. (define_insn "modsi3"
  273.   [(set (match_operand:SI 0 "register_operand" "=r")
  274.     (mod:SI (match_operand:SI 1 "register_operand" "r")
  275.         (match_operand:SI 2 "arith_operand" "rI")))]
  276.   ""
  277.   "rem\\t%0,%1,%2")
  278.  
  279. (define_insn "umodsi3"
  280.   [(set (match_operand:SI 0 "register_operand" "=r")
  281.     (umod:SI (match_operand:SI 1 "register_operand" "r")
  282.          (match_operand:SI 2 "arith_operand" "rI")))]
  283.   ""
  284.   "remu\\t%0,%1,%2")
  285.  
  286.  
  287. ;; Absoluate value instructions -- Don't use the integer abs,
  288. ;; since that signals an exception on -2147483648 (sigh).
  289.  
  290. (define_insn "abssf2"
  291.   [(set (match_operand:SF 0 "register_operand" "=f")
  292.     (abs:SF (match_operand:SF 1 "register_operand" "f")))]
  293.   ""
  294.   "abs.s\\t%0,%1")
  295.  
  296. (define_insn "absdf2"
  297.   [(set (match_operand:DF 0 "register_operand" "=f")
  298.     (abs:DF (match_operand:DF 1 "register_operand" "f")))]
  299.   ""
  300.   "abs.d\\t%0,%1")
  301.  
  302. ;;
  303. ;;  ....................
  304. ;;
  305. ;;          LOGICAL
  306. ;;
  307. ;;  ....................
  308. ;;
  309.  
  310. (define_insn "anddi3"
  311.   [(set (match_operand:DI 0 "register_operand" "=&r")
  312.     (and:DI (match_operand:DI 1 "register_operand" "r")
  313.                 (match_operand:DI 2 "register_operand" "r")))]
  314.   ""
  315.   "and\\t%0,%1,%2\;and\\t%D0,%D1,%D2")
  316.  
  317. (define_insn "andsi3"
  318.   [(set (match_operand:SI 0 "register_operand" "=r")
  319.     (and:SI (match_operand:SI 1 "uns_arith_operand" "%r")
  320.         (match_operand:SI 2 "uns_arith_operand" "rK")))]
  321.   ""
  322.   "*
  323. {
  324.   return (GET_CODE (operands[2]) == CONST_INT)
  325.         ? \"andi\\t%0,%1,%x2\"
  326.         : \"and\\t%0,%1,%2\";
  327. }")
  328.  
  329.  
  330. ;; Simple hack to recognize the "nor" instruction on the MIPS
  331. ;; [rms: I don't think the following is actually required.]
  332. ;; This must appear before the normal or patterns, so that the
  333. ;; combiner will correctly fold things.
  334.  
  335. (define_insn ""
  336.   [(set (match_operand:DI 0 "register_operand" "=r")
  337.     (not:DI (ior:DI (match_operand:DI 1 "register_operand" "r")
  338.             (match_operand:DI 2 "register_operand" "r"))))]
  339.   ""
  340.   "nor\\t%0,%1,%2\;nor\\t%D0,%D1,%D2")
  341.  
  342. (define_insn ""
  343.   [(set (match_operand:SI 0 "register_operand" "=r")
  344.     (not:SI (ior:SI (match_operand:SI 1 "register_operand" "r")
  345.             (match_operand:SI 2 "register_operand" "r"))))]
  346.   ""
  347.   "nor\\t%0,%1,%2")
  348.  
  349. (define_insn "iordi3"
  350.   [(set (match_operand:DI 0 "register_operand" "=&r")
  351.     (ior:DI (match_operand:DI 1 "register_operand" "r")
  352.                 (match_operand:DI 2 "register_operand" "r")))]
  353.   ""
  354.   "or\\t%0,%1,%2\;or\\t%D0,%D1,%D2")
  355.  
  356. (define_insn "iorsi3"
  357.   [(set (match_operand:SI 0 "register_operand" "=r")
  358.     (ior:SI (match_operand:SI 1 "uns_arith_operand" "%r")
  359.         (match_operand:SI 2 "uns_arith_operand" "rJ")))]
  360.   ""
  361.   "*
  362. {
  363.   return (GET_CODE (operands[2]) == CONST_INT)
  364.         ? \"ori\\t%0,%1,%x2\"
  365.         : \"or\\t%0,%1,%2\";
  366. }")
  367.  
  368. (define_insn "xordi3"
  369.   [(set (match_operand:DI 0 "register_operand" "=&r")
  370.     (xor:DI (match_operand:DI 1 "register_operand" "r")
  371.                 (match_operand:DI 2 "register_operand" "r")))]
  372.   ""
  373.   "xor\\t%0,%1,%2\;xor\\t%D0,%D1,%D2")
  374.  
  375. (define_insn "xorsi3"
  376.   [(set (match_operand:SI 0 "register_operand" "=r")
  377.     (xor:SI (match_operand:SI 1 "uns_arith_operand" "%r")
  378.         (match_operand:SI 2 "uns_arith_operand" "rK")))]
  379.   ""
  380.   "*
  381. {
  382.   return (GET_CODE (operands[2]) == CONST_INT)
  383.         ? \"xori\\t%0,%1,%x2\"
  384.         : \"xor\\t%0,%1,%2\";
  385. }")
  386.  
  387. ;;
  388. ;;  ....................
  389. ;;
  390. ;;          TRUNCATION
  391. ;;
  392. ;;  ....................
  393.  
  394. ;; Extension and truncation insns.
  395. ;; Those for integer source operand
  396. ;; are ordered widest source type first.
  397.  
  398.  
  399. (define_insn "truncsiqi2"
  400.   [(set (match_operand:QI 0 "register_operand" "=r")
  401.     (truncate:QI (match_operand:SI 1 "register_operand" "r")))]
  402.   ""
  403.   "andi\\t%0,%1,0xff\\t#truncsiqi2\\t %1 -> %0")
  404.  
  405. (define_insn "truncsihi2"
  406.   [(set (match_operand:HI 0 "register_operand" "=r")
  407.     (truncate:HI (match_operand:SI 1 "register_operand" "r")))]
  408.   ""
  409.   "*
  410.     output_asm_insn (\"sll\\t%0,%1,0x10\\t#truncsihi2\\t %1 -> %0\",
  411.                     operands);
  412.     return \"sra\\t%0,%0,0x10\\t#truncsihi2\\t %1 -> %0\";
  413. ")
  414.  
  415. (define_insn "trunchiqi2"
  416.   [(set (match_operand:QI 0 "register_operand" "=r")
  417.     (truncate:QI (match_operand:HI 1 "register_operand" "r")))]
  418.   ""
  419.   "andi\\t%0,%1,0xff\\t#trunchiqi2\\t %1 -> %0")
  420.  
  421. (define_insn "truncdfsf2"
  422.   [(set (match_operand:SF 0 "register_operand" "=f")
  423.     (float_truncate:SF (match_operand:DF 1 "register_operand" "f")))]
  424.   ""
  425.   "cvt.s.d\\t%0,%1\\t#truncdfsf2\\t %1 -> %0")
  426.  
  427. ;;
  428. ;;  ....................
  429. ;;
  430. ;;          ZERO EXTENSION
  431. ;;
  432. ;;  ....................
  433.  
  434. ;; Extension insns.
  435. ;; Those for integer source operand
  436. ;; are ordered widest source type first.
  437.  
  438.  
  439.  
  440. (define_insn "zero_extendhisi2"
  441.   [(set (match_operand:SI 0 "register_operand" "=r,r")
  442.     (zero_extend:SI (match_operand:HI 1 "general_operand" "r,m")))]
  443.   ""
  444.   "*
  445. {
  446.   if (which_alternative == 0)
  447.     {
  448.       output_asm_insn (\"sll\\t%0,%1,0x10\\t#zero_extendhisi2\\t %1 -> %0\",
  449.                operands);
  450.       return \"srl\\t%0,%0,0x10\\t#zero_extendhisi2\\t %1 -> %0\";
  451.     }
  452.   else
  453.     return \"lhu\\t%0,%1\\t#zero extendhisi2 %1 -> %0\";
  454. }")
  455.  
  456. (define_insn "zero_extendqihi2"
  457.   [(set (match_operand:HI 0 "register_operand" "=r")
  458.     (zero_extend:HI (match_operand:QI 1 "register_operand" "r")))]
  459.   ""
  460.   "*
  461.     output_asm_insn (\"sll\\t%0,%1,0x18\\t#zero_extendqihi2\\t %1 -> %0\",
  462.                     operands);
  463.     return \"srl\\t%0,%0,0x18\\t#zero_extendqihi2\\t %1 -> %0\";
  464.   ")
  465.  
  466.  
  467. (define_insn "zero_extendqisi2"
  468.   [(set (match_operand:SI 0 "register_operand" "=r,r")
  469.     (zero_extend:SI (match_operand:QI 1 "general_operand" "r,m")))]
  470.   ""
  471.   "*
  472. {
  473.   if (which_alternative == 0)
  474.     {
  475.       return \"andi\\t%0,%1,0xff\\t#zero_extendqisi2\\t %1 -> %0\";
  476.     }
  477.   else
  478.     return \"lbu\\t%0,%1\\t#zero extendqisi2 %1 -> %0\";
  479. }")
  480.  
  481.  
  482. ;;
  483. ;;  ....................
  484. ;;
  485. ;;          SIGN EXTENSION
  486. ;;
  487. ;;  ....................
  488.  
  489. ;; Extension insns.
  490. ;; Those for integer source operand
  491. ;; are ordered widest source type first.
  492.  
  493.  
  494.  
  495. (define_insn "extendhisi2"
  496.   [(set (match_operand:SI 0 "register_operand" "=r,r")
  497.     (sign_extend:SI (match_operand:HI 1 "general_operand" "r,m")))]
  498.   ""
  499.   "*
  500. {
  501.   if (which_alternative == 0)
  502.     {
  503.       output_asm_insn (\"sll\\t%0,%1,0x10\\t#sign extendhisi2\\t %1 -> %0\",
  504.                operands);
  505.       return \"sra\\t%0,%0,0x10\\t#sign extendhisi2\\t %1 -> %0\";
  506.     }
  507.   else
  508.     return \"lh\\t%0,%1\\t#sign extendhisi2 %1 -> %0\";
  509. }")
  510.  
  511. (define_insn "extendqihi2"
  512.   [(set (match_operand:HI 0 "register_operand" "=r")
  513.     (sign_extend:HI (match_operand:QI 1 "register_operand" "r")))]
  514.   ""
  515.   "*
  516.     output_asm_insn (\"sll\\t%0,%1,0x18\\t#sign extendqihi2\\t %1 -> %0\",
  517.                     operands);
  518.     return \"sra\\t%0,%0,0x18\\t#sign extendqihi2\\t %1 -> %0\";
  519.   ")
  520.  
  521.  
  522. (define_insn "extendqisi2"
  523.   [(set (match_operand:SI 0 "register_operand" "=r,r")
  524.     (sign_extend:SI (match_operand:QI 1 "general_operand" "r,m")))]
  525.   ""
  526.   "*
  527. {
  528.   if (which_alternative == 0)
  529.     {
  530.       output_asm_insn (\"sll\\t%0,%1,0x18\\t#sign extendqisi2\\t %1 -> %0\",
  531.                operands);
  532.       return \"sra\\t%0,%0,0x18\\t#sign extendqisi2\\t %1 -> %0\";
  533.     }
  534.   else
  535.     return \"lb\\t%0,%1\\t#sign extendqisi2 %1 -> %0\";
  536. }")
  537.  
  538.  
  539. (define_insn "extendsfdf2"
  540.   [(set (match_operand:DF 0 "register_operand" "=f")
  541.     (float_extend:DF (match_operand:SF 1 "register_operand" "f")))]
  542.   ""
  543.   "cvt.d.s\\t%0,%1\\t#extendsfdf2\\t %1 -> %0")
  544.  
  545.  
  546. ;;
  547. ;;  ....................
  548. ;;
  549. ;;          CONVERSIONS
  550. ;;
  551. ;;  ....................
  552.  
  553.  
  554. (define_insn "fix_truncdfsi2_internal"
  555.   [(set (match_operand:DF 0 "register_operand" "=f")
  556.     (fix:DF (match_operand:DF 1 "register_operand" "f")))
  557.    (clobber (match_operand:SI 2 "register_operand" "r"))]
  558.   ""
  559.   "trunc.w.d %0,%1,%2")
  560.  
  561. (define_insn ""
  562.   [(set (match_operand:SI 0 "register_operand" "=r")
  563.     (fix:SI (fix:DF (match_operand:DF 1 "register_operand" "f"))))]
  564.   ""
  565.   "mfc1\\t%0,%1")
  566.  
  567. (define_expand "fix_truncdfsi2"
  568.   [(set (match_operand:SI 0 "register_operand" "=r")
  569.     (fix:SI (fix:DF (match_operand:DF 1 "register_operand" "f"))))]
  570.   ""
  571.   "
  572. {
  573.   rtx reg1 = gen_reg_rtx (DFmode);    /* fp reg that gets trunc result */
  574.   rtx reg2 = gen_reg_rtx (SImode);    /* gp reg that saves FP status bits */
  575.   emit_insn (gen_fix_truncdfsi2_internal (reg1, operands[1], reg2));
  576.   operands[1] = reg1;
  577.   /* Fall through and generate default code */
  578. }")
  579.  
  580. (define_insn "fix_truncsfsi2_internal"
  581.   [(set (match_operand:SF 0 "register_operand" "=f")
  582.     (fix:SF (match_operand:SF 1 "register_operand" "f")))
  583.    (clobber (match_operand:SI 2 "register_operand" "r"))]
  584.   ""
  585.   "trunc.w.s %0,%1,%2")
  586.  
  587. (define_insn ""
  588.   [(set (match_operand:SI 0 "register_operand" "=r")
  589.     (fix:SI (fix:SF (match_operand:SF 1 "register_operand" "f"))))]
  590.   ""
  591.   "mfc1\\t%0,%1")
  592.  
  593. (define_expand "fix_truncsfsi2"
  594.   [(set (match_operand:SI 0 "register_operand" "=r")
  595.     (fix:SI (fix:SF (match_operand:SF 1 "register_operand" "f"))))]
  596.   ""
  597.   "
  598. {
  599.   rtx reg1 = gen_reg_rtx (SFmode);    /* fp reg that gets trunc result */
  600.   rtx reg2 = gen_reg_rtx (SImode);    /* gp reg that saves FP status bits */
  601.   emit_insn (gen_fix_truncsfsi2_internal (reg1, operands[1], reg2));
  602.   operands[1] = reg1;
  603.   /* Fall through and generate default code */
  604. }")
  605.  
  606. (define_insn "floatsidf2"
  607.   [(set (match_operand:DF 0 "register_operand" "=f")
  608.     (float:DF (match_operand:SI 1 "register_operand" "r")))]
  609.   ""
  610.   "mtc1\\t%1,%0\\t\\t#floatsidf2\\t%1 -> %0\;cvt.d.w\\t%0,%0")
  611.  
  612.  
  613. (define_insn "floatsisf2"
  614.   [(set (match_operand:SF 0 "register_operand" "=f")
  615.     (float:SF (match_operand:SI 1 "register_operand" "r")))]
  616.   ""
  617.   "mtc1\\t%1,%0\\t\\t#floatsisf2\\t%1 -> %0\;cvt.s.w\\t%0,%0")
  618.  
  619. (define_expand "fixuns_truncdfsi2"
  620.   [(set (match_operand:SI 0 "register_operand" "")
  621.     (unsigned_fix:SI (match_operand:DF 1 "register_operand" "")))]
  622.   ""
  623.   "
  624. {
  625.   rtx reg1 = gen_reg_rtx (DFmode);
  626.   rtx reg2 = gen_reg_rtx (DFmode);
  627.   rtx reg3 = gen_reg_rtx (SImode);
  628.   rtx label1 = gen_label_rtx ();
  629.   rtx label2 = gen_label_rtx ();
  630.   REAL_VALUE_TYPE offset = REAL_VALUE_LDEXP (1.0, 31);
  631.  
  632.   if (reg1)            /* turn off complaints about unreached code */
  633.     {
  634.       emit_move_insn (reg1, immed_real_const_1 (offset, DFmode));
  635.       do_pending_stack_adjust ();
  636.       emit_insn (gen_rtx (SET, VOIDmode, cc0_rtx,
  637.               gen_rtx (COMPARE, DFmode, operands[1], reg1)));
  638.  
  639.       emit_jump_insn (gen_bge (label1));
  640.  
  641.       emit_insn (gen_fix_truncdfsi2 (operands[0], operands[1]));
  642.       emit_jump_insn (gen_rtx (SET, VOIDmode, pc_rtx,
  643.                    gen_rtx (LABEL_REF, VOIDmode, label2)));
  644.       emit_barrier ();
  645.  
  646.       emit_label (label1);
  647.       emit_move_insn (reg2, gen_rtx (MINUS, DFmode, operands[1], reg1));
  648.       emit_move_insn (reg3, gen_rtx (CONST_INT, VOIDmode, 0x80000000));
  649.  
  650.       emit_insn (gen_fix_truncdfsi2 (operands[0], reg2));
  651.       emit_insn (gen_iorsi3 (operands[0], operands[0], reg3));
  652.  
  653.       emit_label (label2);
  654.  
  655.       /* allow REG_NOTES to be set on last insn (labels don't have enough
  656.      fields, and can't be used for REG_NOTES anyway).  */
  657.       emit_insn (gen_rtx (USE, VOIDmode, stack_pointer_rtx));
  658.       DONE;
  659.     }
  660. }")
  661.  
  662. (define_expand "fixuns_truncsfsi2"
  663.   [(set (match_operand:SI 0 "register_operand" "")
  664.     (unsigned_fix:SI (match_operand:SF 1 "register_operand" "")))]
  665.   ""
  666.   "
  667. {
  668.   rtx reg1 = gen_reg_rtx (SFmode);
  669.   rtx reg2 = gen_reg_rtx (SFmode);
  670.   rtx reg3 = gen_reg_rtx (SImode);
  671.   rtx label1 = gen_label_rtx ();
  672.   rtx label2 = gen_label_rtx ();
  673.   REAL_VALUE_TYPE offset = REAL_VALUE_LDEXP (1.0, 31);
  674.  
  675.   if (reg1)            /* turn off complaints about unreached code */
  676.     {
  677.       emit_move_insn (reg1, immed_real_const_1 (offset, SFmode));
  678.       do_pending_stack_adjust ();
  679.       emit_insn (gen_rtx (SET, VOIDmode, cc0_rtx,
  680.               gen_rtx (COMPARE, SFmode, operands[1], reg1)));
  681.  
  682.       emit_jump_insn (gen_bge (label1));
  683.  
  684.       emit_insn (gen_fix_truncsfsi2 (operands[0], operands[1]));
  685.       emit_jump_insn (gen_rtx (SET, VOIDmode, pc_rtx,
  686.                    gen_rtx (LABEL_REF, VOIDmode, label2)));
  687.       emit_barrier ();
  688.  
  689.       emit_label (label1);
  690.       emit_move_insn (reg2, gen_rtx (MINUS, SFmode, operands[1], reg1));
  691.       emit_move_insn (reg3, gen_rtx (CONST_INT, VOIDmode, 0x80000000));
  692.  
  693.       emit_insn (gen_fix_truncsfsi2 (operands[0], reg2));
  694.       emit_insn (gen_iorsi3 (operands[0], operands[0], reg3));
  695.  
  696.       emit_label (label2);
  697.  
  698.       /* allow REG_NOTES to be set on last insn (labels don't have enough
  699.      fields, and can't be used for REG_NOTES anyway).  */
  700.       emit_insn (gen_rtx (USE, VOIDmode, stack_pointer_rtx));
  701.       DONE;
  702.     }
  703. }")
  704.  
  705.                     ;;- Wild things used when
  706.                     ;;- unions make double and int
  707.                     ;;- overlap.
  708.                     ;;-
  709.                     ;;- This must be supported
  710.                     ;;- since corresponding code
  711.                     ;;- gets generated
  712.  
  713. (define_insn ""
  714.   [(set (subreg:DF (match_operand:DI 0 "register_operand" "=ry") 0)
  715.     (match_operand:DF 1  "register_operand" "rf"))
  716.    (clobber (match_operand  2  "register_operand" "rf"))]
  717.   ""
  718.   "mfc1\\t%0,%L1\;mfc1\\t%D0,%M1")
  719.  
  720. (define_insn ""
  721.   [(set (subreg:DF (match_operand:DI 0 "register_operand" "=ry") 0)
  722.     (match_operand:DF 1  "register_operand" "rf"))]
  723.   ""
  724.   "mfc1\\t%0,%L1\;mfc1\\t%D0,%M1")
  725.  
  726. (define_insn ""
  727.   [(set (match_operand:DF 0 "register_operand" "=rf")
  728.         (subreg:DF (match_operand:DI 1 "register_operand" "ry") 0))
  729.    (clobber (match_operand  2  "register_operand" "rf"))]
  730.   ""
  731.   "mfc1\\t%0,%L1\;mfc1\\t%D0,%M1")
  732.  
  733. (define_insn ""
  734.   [(set (match_operand:DF 0 "register_operand" "=rf")
  735.         (subreg:DF (match_operand:DI 1 "register_operand" "ry") 0))]
  736.   ""
  737.   "mfc1\\t%0,%L1\;mfc1\\t%D0,%M1")
  738.  
  739. ;;
  740. ;;  ....................
  741. ;;
  742. ;;          MOVES
  743. ;;
  744. ;;          and
  745. ;;
  746. ;;          LOADS AND STORES
  747. ;;
  748. ;;  ....................
  749.  
  750. (define_insn "movdi"
  751.   [(set (match_operand:DI 0 "general_operand" "=r,*r,*m")
  752.     (match_operand:DI 1 "general_operand" "r,*miF,*r"))]
  753.   ""
  754.   "*
  755. {
  756.   extern rtx adj_offsettable_operand ();
  757.   extern int offsettable_address_p ();
  758.  
  759.   if (which_alternative == 0)
  760.     {
  761.       /* Move REGISTER <- REGISTER */
  762.       if (REGNO (operands[0]) != (REGNO (operands[1])+1))
  763.     return \"move\\t%0,%1\\n\\tmove\\t%D0,%D1\";
  764.       else
  765.     return \"move\\t%D0,%D1\\n\\tmove\\t%0,%1\";
  766.     }
  767.  
  768.   else if (which_alternative == 1)
  769.     {
  770.       if (GET_CODE (operands[1]) == MEM)
  771.     {
  772.       /* REGISTER <- MEMORY */
  773.       if (offsettable_address_p (1, DImode, XEXP (operands[1], 0)))
  774.         {
  775.           operands[2] = adj_offsettable_operand (operands[1], 4);
  776.           return \"lw\\t%0,%1\;lw\\t%D0,%2\";
  777.         }
  778.  
  779.       else
  780.         {
  781.           operands[2] = gen_rtx (REG, Pmode, 1);
  782.           return \".set\\tnoat\;la\\t%2,%1\;lw\\t%0,0(%2)\;lw\\t%D0,4(%2)\;set\\tat\";
  783.         }
  784.     }
  785.  
  786.       /* REGISTER <- small integer constant */
  787.       else if (CONSTANT_P (operands[1]))
  788.     {
  789.       operands[2] = gen_rtx (CONST_INT, VOIDmode, INTVAL (operands[1]) >= 0 ? 0 : -1);
  790.       return \"li\\t%M0,%2\;li\\t%L0,%1\";
  791.     }
  792.  
  793.       /* Register <- large integer constant */
  794.       else if (GET_CODE (operands[1]) == CONST_DOUBLE)
  795.     {
  796.       operands[2] = gen_rtx (CONST_INT, VOIDmode, CONST_DOUBLE_LOW (operands[1]));
  797.       operands[3] = gen_rtx (CONST_INT, VOIDmode, CONST_DOUBLE_HIGH (operands[1]));
  798.       return \"li\\t%M0,%3\;li\\t%L0,%2\";
  799.     }
  800.     }
  801.  
  802.   else if (which_alternative == 2 && GET_CODE (operands[0]) == MEM)
  803.     {
  804.       /* Memory <- Register */
  805.       if (offsettable_address_p (1, DImode, XEXP (operands[0], 0)))
  806.     {
  807.       operands[2] = adj_offsettable_operand (operands[0], 4);
  808.       return \"sw\\t%1,%0\;sw\\t%D1,%2\";
  809.     }
  810.  
  811.       else
  812.     {
  813.       operands[2] = gen_rtx (REG, Pmode, 1);
  814.       return \".set\\tnoat\;la\\t%2,%0\;sw\\t%1,0(%2)\;sw\\t%D1,4(%2)\;set\\tat\";
  815.     }
  816.     }
  817.  
  818.   abort_with_insn (insn, \"impossible case in movdi\");
  819.   return \"\";
  820. }")
  821.  
  822. (define_insn "movsi"
  823.   [(set (match_operand:SI 0 "general_operand" "=r,r,m,r,r,m,*r")
  824.     (match_operand:SI 1 "general_operand" "r,m,r,i,J,J,*p"))]
  825.   ""
  826.   "*
  827. {
  828.   enum rtx_code code0 = GET_CODE (operands[0]);
  829.   enum rtx_code code1 = GET_CODE (operands[1]);
  830.  
  831.   if (code0 == REG && code1 == REG)
  832.     return \"move\\t%0,%1\";
  833.  
  834.   else if (code0 == REG && code1 == MEM)
  835.     return \"lw\\t%0,%1\";
  836.  
  837.   else if (code0 == MEM && code1 == REG)
  838.     return \"sw\\t%1,%0\";
  839.  
  840.   else if (code0 == REG && code1 == CONST_INT)
  841.     return \"li\\t%0,%1\";
  842.  
  843.   else if (code0 == MEM && code1 == CONST_INT && INTVAL (operands[1]) == 0)
  844.     return \"sw\\t$0,%0\";
  845.  
  846.   else if (code0 == REG && CONSTANT_P (operands[1]))
  847.     return \"la\\t%0,%a1\";
  848.  
  849.   else if (code0 == REG && code1 == PLUS
  850.        && GET_CODE (XEXP (operands[1], 0)) == REG
  851.        && GET_CODE (XEXP (operands[1], 1)) == CONST_INT)
  852.     {
  853.       operands[2] = XEXP (operands[1], 0);
  854.       operands[3] = XEXP (operands[1], 1);
  855.       return \"add%:\\t%0,%2,%3\";
  856.     }
  857.  
  858.   abort_with_insn (insn, \"Bad movsi\");
  859.   return 0;
  860. }")
  861.  
  862. (define_insn "movhi"
  863.   [(set (match_operand:HI 0 "general_operand" "=r,r,m,r,r,m")
  864.     (match_operand:HI 1 "general_operand" "r,m,r,i,J,J"))]
  865.   ""
  866.   "*
  867. {
  868.   enum rtx_code code0 = GET_CODE (operands[0]);
  869.   enum rtx_code code1 = GET_CODE (operands[1]);
  870.  
  871.   if (code0 == REG && code1 == REG)
  872.     return \"move\\t%0,%1\";
  873.  
  874.   else if (code0 == REG && code1 == MEM)
  875.     return \"lh\\t%0,%1\";
  876.  
  877.   else if (code0 == MEM && code1 == REG)
  878.     return \"sh\\t%1,%0\";
  879.  
  880.   else if (code0 == REG && code1 == CONST_INT)
  881.     return \"li\\t%0,%1\";
  882.  
  883.   else if (code0 == MEM && code1 == CONST_INT && INTVAL (operands[1]) == 0)
  884.     return \"sh\\t$0,%0\";
  885.  
  886.   else if (code0 == REG && CONSTANT_P (operands[1]))
  887.     return \"la\\t%0,%a1\";
  888.  
  889.   else if (code0 == REG && code1 == PLUS
  890.        && GET_CODE (XEXP (operands[1], 0)) == REG
  891.        && GET_CODE (XEXP (operands[1], 1)) == CONST_INT)
  892.     {
  893.       operands[2] = XEXP (operands[1], 0);
  894.       operands[3] = XEXP (operands[1], 1);
  895.       return \"add%:\\t%0,%2,%3\";
  896.     }
  897.  
  898.   abort_with_insn (insn, \"Bad movhi\");
  899.   return 0;
  900. }")
  901.  
  902. (define_insn "movqi"
  903.   [(set (match_operand:QI 0 "general_operand" "=r,r,m,r,r,m")
  904.     (match_operand:QI 1 "general_operand" "r,m,r,i,J,J"))]
  905.   ""
  906.   "*
  907. {
  908.   enum rtx_code code0 = GET_CODE (operands[0]);
  909.   enum rtx_code code1 = GET_CODE (operands[1]);
  910.  
  911.   if (code0 == REG && code1 == REG)
  912.     return \"move\\t%0,%1\";
  913.  
  914.   else if (code0 == REG && code1 == MEM)
  915.     return \"lb\\t%0,%1\";
  916.  
  917.   else if (code0 == MEM && code1 == REG)
  918.     return \"sb\\t%1,%0\";
  919.  
  920.   else if (code0 == REG && code1 == CONST_INT)
  921.     return \"li\\t%0,%1\";
  922.  
  923.   else if (code0 == MEM && code1 == CONST_INT && INTVAL (operands[1]) == 0)
  924.     return \"sb\\t$0,%0\";
  925.  
  926.   else if (code0 == REG && CONSTANT_P (operands[1]))
  927.     return \"la\\t%0,%a1\";
  928.  
  929.   else if (code0 == REG && code1 == PLUS
  930.        && GET_CODE (XEXP (operands[1], 0)) == REG
  931.        && GET_CODE (XEXP (operands[1], 1)) == CONST_INT)
  932.     {
  933.       operands[2] = XEXP (operands[1], 0);
  934.       operands[3] = XEXP (operands[1], 1);
  935.       return \"add%:\\t%0,%2,%3\";
  936.     }
  937.  
  938.   abort_with_insn (insn, \"Bad movqi\");
  939.   return 0;
  940. }")
  941.  
  942. (define_insn "movsf"
  943.   [(set (match_operand:SF 0 "general_operand" "=f,f,m,fy,*f,*y,*y,*m")
  944.     (match_operand:SF 1 "general_operand" "f,m,f,F,*y,*f,*m,*y"))]
  945.   ""
  946.   "*
  947. {
  948.   enum rtx_code code0 = GET_CODE (operands[0]);
  949.   enum rtx_code code1 = GET_CODE (operands[1]);
  950.  
  951.   if (code0 == REG)
  952.     {
  953.       if (code1 == REG)
  954.     {
  955.       if (FP_REG_P (REGNO (operands[0])))
  956.         {
  957.           if (FP_REG_P (REGNO (operands[1])))
  958.         return \"mov.s\\t%0,%1\";
  959.           else
  960.         return \"mtc1\\t%1,%0\\t\\t# Calling sequence trick\";
  961.         }
  962.  
  963.       else if (FP_REG_P (REGNO (operands[1])))
  964.         return \"mfc1\\t%0,%1\\t\\t# Calling sequence trick\";
  965.  
  966.       else
  967.         return \"move\\t%0,%1\";
  968.     }
  969.  
  970.       else if (code1 == CONST_DOUBLE)
  971.     return \"li.s\\t%0,%1\";
  972.  
  973.       else if (code1 == MEM)
  974.     return (GP_REG_P (REGNO (operands[0]))) ? \"lw\\t%0,%1\" : \"l.s\\t%0,%1\";
  975.     }
  976.  
  977.   else if (code0 == MEM && code1 == REG)
  978.     return (GP_REG_P (REGNO (operands[1]))) ? \"sw\\t%1,%0\" : \"s.s\\t%1,%0\";
  979.  
  980.   abort_with_insn (insn, \"Bad movsf\");
  981.   return \"\";
  982. }")
  983.  
  984.  
  985. (define_insn "movdf"
  986.   [(set (match_operand:DF 0 "general_operand" "=f,f,m,fy,*f,*y,&*y,*m")
  987.     (match_operand:DF 1 "general_operand" "f,m,f,F,*y,*f,*m,*y"))]
  988.   ""
  989.   "*
  990. {
  991.   extern rtx adj_offsettable_operand ();
  992.   extern int offsettable_address_p ();
  993.  
  994.   enum rtx_code code0 = GET_CODE (operands[0]);
  995.   enum rtx_code code1 = GET_CODE (operands[1]);
  996.  
  997.   if (code0 == REG)
  998.     {
  999.       if (code1 == REG)
  1000.     {
  1001.       if (FP_REG_P (REGNO (operands[0])))
  1002.         {
  1003.           if (FP_REG_P (REGNO (operands[1])))
  1004.         return \"mov.d\\t%0,%1\";
  1005.           else
  1006.         return \"mtc1\\t%L1,%0\\t\\t# Calling sequence trick\;mtc1\\t%M1,%D0\";
  1007.         }
  1008.  
  1009.       else if (FP_REG_P (REGNO (operands[1])))
  1010.         return \"mfc1\\t%L0,%1\\t\\t# Calling sequence trick\;mfc1\\t%M0,%D1\";
  1011.  
  1012.       else if (REGNO (operands[0]) != (REGNO (operands[1])+1))
  1013.         return \"move\\t%0,%1\\n\\tmove\\t%D0,%D1\";
  1014.  
  1015.       else
  1016.         return \"move\\t%D0,%D1\\n\\tmove\\t%0,%1\";
  1017.     }
  1018.  
  1019.       else if (code1 == CONST_DOUBLE)
  1020.     return \"li.d\\t%0,%1\";
  1021.  
  1022.       else if (code1 == MEM)
  1023.     {
  1024.       if (FP_REG_P (REGNO (operands[0])))
  1025.         return \"l.d\\t%0,%1\";
  1026.  
  1027.       else if (offsettable_address_p (1, DFmode, XEXP (operands[1], 0)))
  1028.         {
  1029.           operands[2] = adj_offsettable_operand (operands[1], 4);
  1030.           if (reg_mentioned_p (operands[0], operands[1]))
  1031.         return \"lw\\t%D0,%2\;lw\\t%0,%1\";
  1032.           else
  1033.         return \"lw\\t%0,%1\;lw\\t%D0,%2\";
  1034.         }
  1035.  
  1036.       else
  1037.         {
  1038.           operands[2] = gen_rtx (REG, Pmode, 1);
  1039.           return \".set\\tnoat\;la\\t%2,%1\;lw\\t%0,0(%2)\;lw\\t%D0,4(%2)\;set\\tat\";
  1040.         }
  1041.     }
  1042.     }
  1043.  
  1044.   else if (code0 == MEM && code1 == REG)
  1045.     {
  1046.       if (FP_REG_P (REGNO (operands[1])))
  1047.     return \"s.d\\t%1,%0\";
  1048.  
  1049.       else if (offsettable_address_p (1, DFmode, XEXP (operands[0], 0)))
  1050.     {
  1051.       operands[2] = adj_offsettable_operand (operands[0], 4);
  1052.       return \"sw\\t%1,%0\;sw\\t%D1,%2\";
  1053.     }
  1054.  
  1055.       else
  1056.     {
  1057.       operands[2] = gen_rtx (REG, Pmode, 1);
  1058.       return \".set\\tnoat\;la\\t%2,%0\;sw\\t%1,0(%2)\;sw\\t%D1,4(%2)\;set\\tat\";
  1059.     }
  1060.     }
  1061.  
  1062.   abort_with_insn (insn, \"Bad movdf\");
  1063.   return \"\";
  1064. }")
  1065.  
  1066.  
  1067. ;;
  1068. ;;  ....................
  1069. ;;
  1070. ;;          OTHER ARITHMETIC AND SHIFT
  1071. ;;
  1072. ;;  ....................
  1073.  
  1074. (define_insn "ashlsi3"
  1075.   [(set (match_operand:SI 0 "register_operand" "=r")
  1076.     (ashift:SI (match_operand:SI 1 "register_operand" "r")
  1077.            (match_operand:SI 2 "arith_operand" "rI")))]
  1078.   ""
  1079.   "*
  1080. {
  1081.   if (GET_CODE (operands[2]) == CONST_INT)
  1082.     operands[2] = gen_rtx (CONST_INT, VOIDmode, (XINT (operands[2], 0))& 0x1f);
  1083.  
  1084.   return \"sll\\t%0,%1,%2\";
  1085. }")
  1086.  
  1087. (define_insn "ashrsi3"
  1088.   [(set (match_operand:SI 0 "register_operand" "=r")
  1089.     (ashiftrt:SI (match_operand:SI 1 "register_operand" "r")
  1090.              (match_operand:SI 2 "arith_operand" "rI")))]
  1091.   ""
  1092.   "*
  1093. {
  1094.   if (GET_CODE (operands[2]) == CONST_INT)
  1095.     operands[2] = gen_rtx (CONST_INT, VOIDmode, (XINT (operands[2], 0))& 0x1f);
  1096.  
  1097.   return \"sra\\t%0,%1,%2\";
  1098. }")
  1099.  
  1100. (define_insn "lshrsi3"
  1101.   [(set (match_operand:SI 0 "register_operand" "=r")
  1102.     (lshiftrt:SI (match_operand:SI 1 "register_operand" "r")
  1103.              (match_operand:SI 2 "arith_operand" "rI")))]
  1104.   ""
  1105.   "*
  1106. {
  1107.   if (GET_CODE (operands[2]) == CONST_INT)
  1108.     operands[2] = gen_rtx (CONST_INT, VOIDmode, (XINT (operands[2], 0))& 0x1f);
  1109.  
  1110.   return \"srl\\t%0,%1,%2\";
  1111. }")
  1112.  
  1113. (define_insn "negsi2"
  1114.   [(set (match_operand:SI 0 "register_operand" "=r")
  1115.     (neg:SI (match_operand:SI 1 "register_operand" "r")))]
  1116.   ""
  1117.   "sub%:\\t%0,$0,%1")
  1118.  
  1119. (define_insn "negdf2"
  1120.   [(set (match_operand:DF 0 "register_operand" "=f")
  1121.     (neg:DF (match_operand:DF 1 "register_operand" "f")))]
  1122.   ""
  1123.   "neg.d\\t%0,%1")
  1124.  
  1125. (define_insn "negsf2"
  1126.  
  1127.   [(set (match_operand:SF 0 "register_operand" "=f")
  1128.     (neg:SF (match_operand:SF 1 "register_operand" "f")))]
  1129.   ""
  1130.   "neg.s\\t%0,%1")
  1131.  
  1132.  
  1133. (define_insn "one_cmplsi2"
  1134.   [(set (match_operand:SI 0 "register_operand" "=r")
  1135.     (not:SI (match_operand:SI 1 "register_operand" "r")))]
  1136.   ""
  1137.   "nor\\t%0,$0,%1")
  1138.  
  1139. ;;
  1140. ;;  ....................
  1141. ;;
  1142. ;;          COMPARISONS
  1143. ;;
  1144. ;;  ....................
  1145.  
  1146.                     ;;- Order is significant here
  1147.                     ;;- because there are untyped
  1148.                     ;;- comparisons generated by
  1149.                     ;;- the optimizer
  1150.                                         ;;- (set (cc0)
  1151.                                         ;;-      (compare (const_int 2)
  1152.                                         ;;-           (const_int 1)))
  1153.  
  1154. (define_insn "cmpsi"
  1155.   [(set (cc0)
  1156.     (compare (match_operand:SI 0 "register_operand" "r")
  1157.          (match_operand:SI 1 "arith_operand" "rI")))]
  1158.   ""
  1159.   "*
  1160.     compare_collect (SImode, operands[0], operands[1]);
  1161.     return \"\\t\\t\\t\\t# cmpsi\\t%0,%1\";
  1162. ")
  1163.  
  1164.  
  1165. (define_insn ""
  1166.   [(set (cc0)
  1167.     (match_operand:SI 0 "register_operand" "r"))]
  1168.   ""
  1169.   "*
  1170.     compare_collect (SImode, operands[0], gen_rtx (REG, SImode, 0));
  1171.     return \"\\t\\t\\t\\t# (set (cc0)\\t%0)\";
  1172. ")
  1173.  
  1174. ;; These patterns are hopelessly invalid, because
  1175. ;; comparing subword values properly requires extending them.
  1176.  
  1177. ;; (define_insn "cmphi"
  1178. ;;   [(set (cc0)
  1179. ;;     (compare (match_operand:HI 0 "register_operand" "r")
  1180. ;;          (match_operand:HI 1 "register_operand" "r")))]
  1181. ;;   ""
  1182. ;;   "*
  1183. ;;     compare_collect (HImode, operands[0], operands[1]);
  1184. ;;     return      \" #\\tcmphi\\t%0,%1\";
  1185. ;;   ")
  1186. ;; 
  1187. ;; (define_insn "cmpqi"
  1188. ;;   [(set (cc0)
  1189. ;;     (compare (match_operand:QI 0 "register_operand" "r")
  1190. ;;          (match_operand:QI 1 "register_operand" "r")))]
  1191. ;;   ""
  1192. ;;   "*
  1193. ;;     compare_collect (QImode, operands[0], operands[1]);
  1194. ;;     return      \" #\\tcmpqi\\t%0,%1\";
  1195. ;;   ")
  1196. ;; 
  1197. ;; (define_insn ""
  1198. ;;   [(set (cc0)
  1199. ;;     (match_operand:QI 0 "register_operand" "r"))]
  1200. ;;   ""
  1201. ;;   "*
  1202. ;;     compare_collect (QImode, operands[0], gen_rtx (REG, QImode, 0));
  1203. ;;     return \" #\\t (set (cc0)\\t%0)\";
  1204. ;; ")
  1205. ;; 
  1206. ;; (define_insn ""
  1207. ;;   [(set (cc0)
  1208. ;;     (match_operand:HI 0 "register_operand" "r"))]
  1209. ;;   ""
  1210. ;;   "*
  1211. ;;     compare_collect (HImode, operands[0], gen_rtx (REG, HImode, 0));
  1212. ;;     return \" #\\t (set (cc0)\\t%0)\";
  1213. ;; ")
  1214.  
  1215. (define_insn "cmpdf"
  1216.   [(set (cc0)
  1217.     (compare (match_operand:DF 0 "register_operand" "f")
  1218.          (match_operand:DF 1 "register_operand" "f")))]
  1219.   ""
  1220.   "*
  1221.     compare_collect (DFmode, operands[0], operands[1]);
  1222.     return \" #\\t\\t\\t\\tcmpdf\\t%0,%1\" ;
  1223. ")
  1224.  
  1225. (define_insn "cmpsf"
  1226.   [(set (cc0)
  1227.     (compare (match_operand:SF 0 "register_operand" "f")
  1228.          (match_operand:SF 1 "register_operand" "f")))]
  1229.   ""
  1230.   "*
  1231.     compare_collect (SFmode, operands[0], operands[1]);
  1232.     return \"\\t\\t\\t\\t# cmpsf\\t%0,%1\" ;
  1233. ")
  1234.  
  1235. ;;
  1236. ;;  ....................
  1237. ;;
  1238. ;;          BRANCHES
  1239. ;;
  1240. ;;  ....................
  1241.  
  1242. (define_insn "jump"
  1243.   [(set (pc)
  1244.     (label_ref (match_operand 0 "" "")))]
  1245.   ""
  1246.   "*
  1247. {
  1248.   if (GET_CODE (operands[0]) == REG)
  1249.     return \"j\\t%0\";
  1250.   else
  1251.     return \"j\\t%l0\";
  1252. }")
  1253.  
  1254.  
  1255. (define_insn "tablejump"
  1256.   [(set (pc)
  1257.     (match_operand:SI 0 "register_operand" "r"))
  1258.    (use (label_ref (match_operand 1 "" "")))]
  1259.   ""
  1260.   "j\\t%0")
  1261.  
  1262.  
  1263. (define_insn "beq"
  1264.   [(set (pc)
  1265.     (if_then_else (eq (cc0)
  1266.               (const_int 0))
  1267.               (label_ref (match_operand 0 "" ""))
  1268.               (pc)))]
  1269.   ""
  1270.   "*
  1271. {
  1272.   rtx br_ops[3];
  1273.   enum machine_mode mode;
  1274.   compare_restore (br_ops,  &mode, insn);
  1275.   br_ops[2] = operands[0];
  1276.   if (mode == DFmode)
  1277.     {
  1278.       output_asm_insn (\"c.eq.d\\t%0,%1\\t\\t# beq\", br_ops);
  1279.       output_asm_insn (\"bc1t\\t%2\\t\\t# beq\", br_ops);
  1280.     }
  1281.   else if  (mode == SFmode)
  1282.     {
  1283.       output_asm_insn (\"c.eq.s\\t%0,%1\\t\\t# beq\", br_ops);
  1284.       output_asm_insn (\"bc1t\\t%2\\t\\t# beq\", br_ops);
  1285.     }
  1286.   else
  1287.     {
  1288.       output_asm_insn (\"beq\\t%0,%1,%2\\t\\t# beq\", br_ops);
  1289.     }
  1290.   return \"\";
  1291. }
  1292.    ")
  1293.  
  1294. (define_insn "bne"
  1295.   [(set (pc)
  1296.     (if_then_else (ne (cc0)
  1297.               (const_int 0))
  1298.               (label_ref (match_operand 0 "" ""))
  1299.               (pc)))]
  1300.   ""
  1301.   "*
  1302. {
  1303.   rtx br_ops[3];
  1304.   enum machine_mode mode;
  1305.   compare_restore (br_ops,  &mode, insn);
  1306.   br_ops[2] = operands[0];
  1307.   if (mode == DFmode)
  1308.     {
  1309.       output_asm_insn (\"c.eq.d\\t%0,%1\\t\\t# bne\", br_ops);
  1310.       output_asm_insn (\"bc1f\\t%2\\t\\t# bne\", br_ops);
  1311.     }
  1312.   else if  (mode == SFmode)
  1313.     {
  1314.       output_asm_insn (\"c.eq.s\\t%0,%1\\t\\t# bne\", br_ops);
  1315.       output_asm_insn (\"bc1f\\t%2\\t\\t# bne\", br_ops);
  1316.     }
  1317.   else
  1318.     {
  1319.       output_asm_insn (\"bne\\t%0,%1,%2\\t\\t# bne\", br_ops);
  1320.     }
  1321.   return \"\";
  1322. }
  1323.  
  1324. ")
  1325.  
  1326. (define_insn "bgt"
  1327.   [(set (pc)
  1328.     (if_then_else (gt (cc0)
  1329.               (const_int 0))
  1330.               (label_ref (match_operand 0 "" ""))
  1331.               (pc)))]
  1332.   ""
  1333.   "*
  1334. {
  1335.   rtx br_ops[3];
  1336.   enum machine_mode mode;
  1337.   compare_restore (br_ops,  &mode, insn);
  1338.   br_ops[2] = operands[0];
  1339.   if (mode == DFmode)
  1340.     {
  1341.       output_asm_insn (\"c.le.d\\t%0,%1\\t\\t# bgt branch %0 > %1\", br_ops);
  1342.       output_asm_insn (\"bc1f\\t%2\\t\\t# bgt\", br_ops);
  1343.     }
  1344.   else if  (mode == SFmode)
  1345.     {
  1346.       output_asm_insn (\"c.le.s\\t%0,%1\\t\\t# bgt branch %0 > %1\", br_ops);
  1347.       output_asm_insn (\"bc1f\\t%2\\t\\t# bgt\", br_ops);
  1348.     }
  1349.   else
  1350.     {
  1351.       output_asm_insn (\"bgt\\t%0,%1,%2\\t\\t# bgt\", br_ops);
  1352.     }
  1353.   return \"\";
  1354. }
  1355.  
  1356. ")
  1357.  
  1358. (define_insn "blt"
  1359.   [(set (pc)
  1360.     (if_then_else (lt (cc0)
  1361.               (const_int 0))
  1362.               (label_ref (match_operand 0 "" ""))
  1363.               (pc)))]
  1364.   ""
  1365.   "*
  1366. {
  1367.   rtx br_ops[3];
  1368.   enum machine_mode mode;
  1369.   compare_restore (br_ops,  &mode, insn);
  1370.   br_ops[2] = operands[0];
  1371.   if (mode == DFmode)
  1372.     {
  1373.       output_asm_insn (\"c.lt.d\\t%0,%1\\t\\t# blt\", br_ops);
  1374.       output_asm_insn (\"bc1t\\t%2\\t\\t# blt\", br_ops);
  1375.     }
  1376.   else if  (mode == SFmode)
  1377.     {
  1378.       output_asm_insn (\"c.lt.s\\t%0,%1\\t\\t# blt\", br_ops);
  1379.       output_asm_insn (\"bc1t\\t%2\\t\\t# blt\", br_ops);
  1380.     }
  1381.   else
  1382.     {
  1383.       output_asm_insn (\"blt\\t%0,%1,%2\\t\\t# blt\", br_ops);
  1384.     }
  1385.   return \" #\\tblt\\t%l0\\t\\t# blt\";
  1386. }
  1387. ")
  1388.  
  1389. (define_insn "bgtu"
  1390.   [(set (pc)
  1391.     (if_then_else (gtu (cc0)
  1392.                (const_int 0))
  1393.               (label_ref (match_operand 0 "" ""))
  1394.               (pc)))]
  1395.   ""
  1396.   "*
  1397. {
  1398.   rtx br_ops[3];
  1399.   enum machine_mode mode;
  1400.   compare_restore (br_ops,  &mode, insn);
  1401.   br_ops[2] = operands[0];
  1402.   if (mode == DFmode)
  1403.     {
  1404.       output_asm_insn (\"c.le.d\\t%0,%1\\t\\t# bgtu\", br_ops);
  1405.       output_asm_insn (\"bc1f\\t%2\\t\\t# bgtu\", br_ops);
  1406.     }
  1407.   else if  (mode == SFmode)
  1408.     {
  1409.       output_asm_insn (\"c.le.s\\t%0,%1\\t\\t# bgtu\", br_ops);
  1410.       output_asm_insn (\"bc1f\\t%2\\t\\t# bgtu\", br_ops);
  1411.     }
  1412.   else
  1413.     {
  1414.       output_asm_insn (\"bgtu\\t%0,%1,%2\\t\\t# bgtu\", br_ops);
  1415.     }
  1416.   return \" #\\tbgtu\\t%l0\\t\\t# bgtu\";
  1417. }
  1418. ")
  1419.  
  1420. (define_insn "bltu"
  1421.   [(set (pc)
  1422.     (if_then_else (ltu (cc0)
  1423.                (const_int 0))
  1424.               (label_ref (match_operand 0 "" ""))
  1425.               (pc)))]
  1426.   ""
  1427.   "*
  1428. {
  1429.   rtx br_ops[3];
  1430.   enum machine_mode mode;
  1431.   compare_restore (br_ops,  &mode, insn);
  1432.   br_ops[2] = operands[0];
  1433.   if (mode == DFmode)
  1434.     {
  1435.       output_asm_insn (\"c.lt.d\\t%0,%1\\t\\t# bltu\", br_ops);
  1436.       output_asm_insn (\"bc1t\\t%2\\t\\t# bltu\", br_ops);
  1437.     }
  1438.   else if  (mode == SFmode)
  1439.     {
  1440.       output_asm_insn (\"c.lt.s\\t%0,%1\\t\\t# bltu\", br_ops);
  1441.       output_asm_insn (\"bc1t\\t%2\\t\\t# bltu\", br_ops);
  1442.     }
  1443.   else
  1444.     {
  1445.       output_asm_insn (\"bltu\\t%0,%1,%2\\t\\t# bltu\", br_ops);
  1446.     }
  1447.   return \"\";
  1448. }
  1449. ")
  1450.  
  1451. (define_insn "bge"
  1452.   [(set (pc)
  1453.     (if_then_else (ge (cc0)
  1454.               (const_int 0))
  1455.               (label_ref (match_operand 0 "" ""))
  1456.               (pc)))]
  1457.   ""
  1458.   "*
  1459. {
  1460.   rtx br_ops[3];
  1461.   enum machine_mode mode;
  1462.   compare_restore (br_ops,  &mode, insn);
  1463.   br_ops[2] = operands[0];
  1464.   if (mode == DFmode)
  1465.     {
  1466.       output_asm_insn (\"c.lt.d\\t%0,%1\\t\\t# bge\", br_ops);
  1467.       output_asm_insn (\"bc1f\\t%2\\t\\t# bge\", br_ops);
  1468.     }
  1469.   else if  (mode == SFmode)
  1470.     {
  1471.       output_asm_insn (\"c.lt.s\\t%0,%1\\t\\t# bge\", br_ops);
  1472.       output_asm_insn (\"bc1f\\t%2\\t\\t# bge\", br_ops);
  1473.     }
  1474.   else
  1475.     {
  1476.       output_asm_insn (\"bge\\t%0,%1,%2\\t\\t# bge\", br_ops);
  1477.     }
  1478.   return \"\";
  1479. }
  1480. ")
  1481.  
  1482. (define_insn "bgeu"
  1483.   [(set (pc)
  1484.     (if_then_else (geu (cc0)
  1485.                (const_int 0))
  1486.               (label_ref (match_operand 0 "" ""))
  1487.               (pc)))]
  1488.   ""
  1489.   "*
  1490. {
  1491.   rtx br_ops[3];
  1492.   enum machine_mode mode;
  1493.   compare_restore (br_ops,  &mode, insn);
  1494.   br_ops[2] = operands[0];
  1495.   if (mode == DFmode)
  1496.     {
  1497.       output_asm_insn (\"c.lt.d\\t%0,%1\\t\\t# bgeu\", br_ops);
  1498.       output_asm_insn (\"bc1f\\t%2\\t\\t# bgeu\", br_ops);
  1499.     }
  1500.   else if  (mode == SFmode)
  1501.     {
  1502.       output_asm_insn (\"c.lt.s\\t%0,%1\\t\\t# bgeu\", br_ops);
  1503.       output_asm_insn (\"bc1f\\t%2\\t\\t# bgeu\", br_ops);
  1504.     }
  1505.   else
  1506.     {
  1507.       output_asm_insn (\"bgeu\\t%0,%1,%2\\t\\t# bgeu\", br_ops);
  1508.     }
  1509.   return \"\";
  1510. }
  1511. ")
  1512.  
  1513. (define_insn "ble"
  1514.   [(set (pc)
  1515.     (if_then_else (le (cc0)
  1516.               (const_int 0))
  1517.               (label_ref (match_operand 0 "" ""))
  1518.               (pc)))]
  1519.   ""
  1520.   "*
  1521. {
  1522.   rtx br_ops[3];
  1523.   enum machine_mode mode;
  1524.   compare_restore (br_ops,  &mode, insn);
  1525.   br_ops[2] = operands[0];
  1526.   if (mode == DFmode)
  1527.     {
  1528.       output_asm_insn (\"c.le.d\\t%0,%1\\t\\t# ble\", br_ops);
  1529.       output_asm_insn (\"bc1t\\t%2\\t\\t# ble\", br_ops);
  1530.     }
  1531.   else if  (mode == SFmode)
  1532.     {
  1533.       output_asm_insn (\"c.le.s\\t%0,%1\\t\\t# ble\", br_ops);
  1534.       output_asm_insn (\"bc1t\\t%2\\t\\t# ble\", br_ops);
  1535.     }
  1536.   else
  1537.     {
  1538.       output_asm_insn (\"ble\\t%0,%1,%2\\t\\t# ble\", br_ops);
  1539.     }
  1540.   return \"\";
  1541. }
  1542. ")
  1543.  
  1544. (define_insn "bleu"
  1545.   [(set (pc)
  1546.     (if_then_else (leu (cc0)
  1547.               (const_int 0))
  1548.               (label_ref (match_operand 0 "" ""))
  1549.               (pc)))]
  1550.   ""
  1551.   "*
  1552. {
  1553.   rtx br_ops[3];
  1554.   enum machine_mode mode;
  1555.   compare_restore (br_ops,  &mode, insn);
  1556.   br_ops[2] = operands[0];
  1557.   if (mode == DFmode)
  1558.     {
  1559.       output_asm_insn (\"c.le.d\\t%0,%1\\t\\t# ble\", br_ops);
  1560.       output_asm_insn (\"bc1t\\t%2\\t\\t# ble\", br_ops);
  1561.     }
  1562.   else if  (mode == SFmode)
  1563.     {
  1564.       output_asm_insn (\"c.le.s\\t%0,%1\\t\\t# ble\", br_ops);
  1565.       output_asm_insn (\"bc1t\\t%2\\t\\t# ble\", br_ops);
  1566.     }
  1567.   else
  1568.     {
  1569.       output_asm_insn (\"bleu\\t%0,%1,%2\\t\\t# bleu\", br_ops);
  1570.     }
  1571.   return \" #\\tbleu\\t%l0\\t\\t# bleu\";
  1572. }
  1573. ")
  1574.  
  1575. (define_insn ""
  1576.   [(set (pc)
  1577.     (if_then_else (ne (cc0)
  1578.               (const_int 0))
  1579.               (pc)
  1580.               (label_ref (match_operand 0 "" ""))))]
  1581.   ""
  1582.   "*
  1583. {
  1584.   rtx br_ops[3];
  1585.   enum machine_mode mode;
  1586.   compare_restore (br_ops,  &mode, insn);
  1587.   br_ops[2] = operands[0];
  1588.   if (mode == DFmode)
  1589.     {
  1590.       output_asm_insn (\"c.eq.d\\t%0,%1\\t\\t# beq\", br_ops);
  1591.       output_asm_insn (\"bc1t\\t%2\\t\\t# beq\", br_ops);
  1592.     }
  1593.   else if  (mode == SFmode)
  1594.     {
  1595.       output_asm_insn (\"c.eq.s\\t%0,%1\\t\\t# beq\", br_ops);
  1596.       output_asm_insn (\"bc1t\\t%2\\t\\t# beq\", br_ops);
  1597.     }
  1598.   else
  1599.     {
  1600.       output_asm_insn (\"beq\\t%0,%1,%2\\t\\t# beq Inv.\", br_ops);
  1601.     }
  1602.   return \"\";
  1603. }
  1604. ")
  1605.  
  1606. (define_insn ""
  1607.   [(set (pc)
  1608.     (if_then_else (eq (cc0)
  1609.               (const_int 0))
  1610.               (pc)
  1611.               (label_ref (match_operand 0 "" ""))))]
  1612.   ""
  1613.   "*
  1614. {
  1615.   rtx br_ops[3];
  1616.   enum machine_mode mode;
  1617.   compare_restore (br_ops,  &mode, insn);
  1618.   br_ops[2] = operands[0];
  1619.   if (mode == DFmode)
  1620.     {
  1621.       output_asm_insn (\"c.eq.d\\t%0,%1\\t\\t# bne\", br_ops);
  1622.       output_asm_insn (\"bc1f\\t%2\\t\\t# bne\", br_ops);
  1623.     }
  1624.   else if  (mode == SFmode)
  1625.     {
  1626.       output_asm_insn (\"c.eq.s\\t%0,%1\\t\\t# bne\", br_ops);
  1627.       output_asm_insn (\"bc1f\\t%2\\t\\t# beq\", br_ops);
  1628.     }
  1629.   else
  1630.     {
  1631.       output_asm_insn (\"bne\\t%0,%1,%2\\t\\t# bne Inv.\", br_ops);
  1632.     }
  1633.   return \"\";
  1634. }
  1635.  
  1636. ")
  1637.  
  1638. (define_insn ""
  1639.   [(set (pc)
  1640.     (if_then_else (le (cc0)
  1641.               (const_int 0))
  1642.               (pc)
  1643.               (label_ref (match_operand 0 "" ""))))]
  1644.   ""
  1645.   "*
  1646. {
  1647.   rtx br_ops[3];
  1648.   enum machine_mode mode;
  1649.   compare_restore (br_ops,  &mode, insn);
  1650.   br_ops[2] = operands[0];
  1651.   if (mode == DFmode)
  1652.     {
  1653.       output_asm_insn (\"c.le.d\\t%0,%1\\t\\t# bgt\", br_ops);
  1654.       output_asm_insn (\"bc1f\\t%2\\t\\t# beq\", br_ops);
  1655.     }
  1656.   else if  (mode == SFmode)
  1657.     {
  1658.       output_asm_insn (\"c.le.s\\t%0,%1\\t\\t# bgt\", br_ops);
  1659.       output_asm_insn (\"bc1f\\t%2\\t\\t# beq\", br_ops);
  1660.     }
  1661.   else
  1662.     {
  1663.       output_asm_insn (\"bgt\\t%0,%1,%2\\t\\t# bgt Inv.\", br_ops);
  1664.     }
  1665.   return \"\";
  1666. }
  1667. ")
  1668.  
  1669. (define_insn ""
  1670.   [(set (pc)
  1671.     (if_then_else (leu (cc0)
  1672.                (const_int 0))
  1673.               (pc)
  1674.               (label_ref (match_operand 0 "" ""))))]
  1675.   ""
  1676.   "*
  1677. {
  1678.   rtx br_ops[3];
  1679.   enum machine_mode mode;
  1680.   compare_restore (br_ops,  &mode, insn);
  1681.   br_ops[2] = operands[0];
  1682.   if (mode == DFmode)
  1683.     {
  1684.       output_asm_insn (\"c.le.d\\t%0,%1\\t\\t# bgt\", br_ops);
  1685.       output_asm_insn (\"bc1f\\t%2\\t\\t# beq\", br_ops);
  1686.     }
  1687.   else if  (mode == SFmode)
  1688.     {
  1689.       output_asm_insn (\"c.le.s\\t%0,%1\\t\\t# bgt\", br_ops);
  1690.       output_asm_insn (\"bc1f\\t%2\\t\\t# beq\", br_ops);
  1691.     }
  1692.   else
  1693.     {
  1694.       output_asm_insn (\"bgtu\\t%0,%1,%2\\t\\t# bgtu Inv.\", br_ops);
  1695.     }
  1696.   return \" #\\tbgtu\\t%l0\\t\\t# bgtu\";
  1697. }
  1698. ")
  1699.  
  1700. (define_insn ""
  1701.   [(set (pc)
  1702.     (if_then_else (ge (cc0)
  1703.               (const_int 0))
  1704.               (pc)
  1705.               (label_ref (match_operand 0 "" ""))))]
  1706.   ""
  1707.   "*
  1708. {
  1709.   rtx br_ops[3];
  1710.   enum machine_mode mode;
  1711.   compare_restore (br_ops,  &mode, insn);
  1712.   br_ops[2] = operands[0];
  1713.   if (mode == DFmode)
  1714.     {
  1715.       output_asm_insn (\"c.lt.d\\t%0,%1\\t\\t# blt\", br_ops);
  1716.       output_asm_insn (\"bc1t\\t%2\\t\\t# beq\", br_ops);
  1717.     }
  1718.   else if  (mode == SFmode)
  1719.     {
  1720.       output_asm_insn (\"c.lt.s\\t%0,%1\\t\\t# blt\", br_ops);
  1721.       output_asm_insn (\"bc1t\\t%2\\t\\t# beq\", br_ops);
  1722.     }
  1723.   else
  1724.     {
  1725.       output_asm_insn (\"blt\\t%0,%1,%2\\t\\t# blt Inv.\", br_ops);
  1726.     }
  1727.   return \"\";
  1728. }
  1729. ")
  1730.  
  1731. (define_insn ""
  1732.   [(set (pc)
  1733.     (if_then_else (geu (cc0)
  1734.                (const_int 0))
  1735.               (pc)
  1736.               (label_ref (match_operand 0 "" ""))))]
  1737.   ""
  1738.   "*
  1739. {
  1740.   rtx br_ops[3];
  1741.   enum machine_mode mode;
  1742.   compare_restore (br_ops,  &mode, insn);
  1743.   br_ops[2] = operands[0];
  1744.   if (mode == DFmode)
  1745.     {
  1746.       output_asm_insn (\"c.lt.d\\t%0,%1\\t\\t# bltu\", br_ops);
  1747.       output_asm_insn (\"bc1t\\t%2\\t\\t# bltu\", br_ops);
  1748.     }
  1749.   else if  (mode == SFmode)
  1750.     {
  1751.       output_asm_insn (\"c.lt.s\\t%0,%1\\t\\t# bltu\", br_ops);
  1752.       output_asm_insn (\"bc1t\\t%2\\t\\t# bltu\", br_ops);
  1753.     }
  1754.   else
  1755.     {
  1756.       output_asm_insn (\"bltu\\t%0,%1,%2\\t\\t# bltu Inv.\", br_ops);
  1757.     }
  1758.   return \" #\\tbltu\\t%l0\\t\\t# bltu\";
  1759. }
  1760. ")
  1761.  
  1762. (define_insn ""
  1763.   [(set (pc)
  1764.     (if_then_else (lt (cc0)
  1765.               (const_int 0))
  1766.               (pc)
  1767.               (label_ref (match_operand 0 "" ""))))]
  1768.   ""
  1769.   "*
  1770. {
  1771.   rtx br_ops[3];
  1772.   enum machine_mode mode;
  1773.   compare_restore (br_ops,  &mode, insn);
  1774.   br_ops[2] = operands[0];
  1775.   if (mode == DFmode)
  1776.     {
  1777.       output_asm_insn (\"c.lt.d\\t%0,%1\\t\\t# bge\", br_ops);
  1778.       output_asm_insn (\"bc1f\\t%2\\t\\t# bge (DF) Inv.\", br_ops);
  1779.     }
  1780.   else if  (mode == SFmode)
  1781.     {
  1782.       output_asm_insn (\"c.lt.s\\t%0,%1\\t\\t# bge\", br_ops);
  1783.       output_asm_insn (\"bc1f\\t%2\\t\\t# bge (SF) Inv.\", br_ops);
  1784.     }
  1785.   else
  1786.     {
  1787.       output_asm_insn (\"bge\\t%0,%1,%2\\t\\t# bge Inv.\", br_ops);
  1788.     }
  1789.   return \"\";
  1790. }
  1791. ")
  1792.  
  1793. (define_insn ""
  1794.   [(set (pc)
  1795.     (if_then_else (ltu (cc0)
  1796.                (const_int 0))
  1797.               (pc)
  1798.               (label_ref (match_operand 0 "" ""))))]
  1799.   ""
  1800.   "*
  1801. {
  1802.   rtx br_ops[3];
  1803.   enum machine_mode mode;
  1804.   compare_restore (br_ops,  &mode, insn);
  1805.   br_ops[2] = operands[0];
  1806.   if (mode == DFmode)
  1807.     {
  1808.       output_asm_insn (\"c.lt.d\\t%0,%1\\t\\t# bge\", br_ops);
  1809.       output_asm_insn (\"bc1f\\t%2\\t\\t# bgeu (DF)  Inv.\", br_ops);
  1810.     }
  1811.   else if  (mode == SFmode)
  1812.     {
  1813.       output_asm_insn (\"c.lt.s\\t%0,%1\\t\\t# bge\", br_ops);
  1814.       output_asm_insn (\"bc1f\\t%2\\t\\t# bgeu (SF )Inv.\", br_ops);
  1815.     }
  1816.   else
  1817.     {
  1818.       output_asm_insn (\"bgeu\\t%0,%1,%2\\t\\t# bgeu Inv.\", br_ops);
  1819.     }
  1820.   return \" #\\tbgeu\\t%l0\\t\\t# bgeu\";
  1821. }
  1822. ")
  1823.  
  1824. (define_insn ""
  1825.   [(set (pc)
  1826.     (if_then_else (gt (cc0)
  1827.               (const_int 0))
  1828.               (pc)
  1829.               (label_ref (match_operand 0 "" ""))))]
  1830.   ""
  1831.   "*
  1832. {
  1833.   rtx br_ops[3];
  1834.   enum machine_mode mode;
  1835.   compare_restore (br_ops,  &mode, insn);
  1836.   br_ops[2] = operands[0];
  1837.   if (mode == DFmode)
  1838.     {
  1839.       output_asm_insn (\"c.le.d\\t%0,%1\\t\\t# ble\", br_ops);
  1840.       output_asm_insn (\"bc1t\\t%2\\t\\t# ble\", br_ops);
  1841.     }
  1842.   else if  (mode == SFmode)
  1843.     {
  1844.       output_asm_insn (\"c.le.s\\t%0,%1\\t\\t# ble\", br_ops);
  1845.       output_asm_insn (\"bc1t\\t%2\\t\\t# ble\", br_ops);
  1846.     }
  1847.   else
  1848.     {
  1849.       output_asm_insn (\"ble\\t%0,%1,%2\\t\\t# ble Inv.\", br_ops);
  1850.     }
  1851.   return \"\";
  1852. }
  1853. ")
  1854.  
  1855. (define_insn ""
  1856.   [(set (pc)
  1857.     (if_then_else (gtu (cc0)
  1858.                (const_int 0))
  1859.               (pc)
  1860.               (label_ref (match_operand 0 "" ""))))]
  1861.   ""
  1862.   "*
  1863. {
  1864.   rtx br_ops[3];
  1865.   enum machine_mode mode;
  1866.   compare_restore (br_ops,  &mode, insn);
  1867.   br_ops[2] = operands[0];
  1868.   if (mode == DFmode)
  1869.     {
  1870.       output_asm_insn (\"c.le.d\\t%0,%1\\t\\t# bleu\", br_ops);
  1871.       output_asm_insn (\"bc1t\\t%2\\t\\t# bleu\", br_ops);
  1872.     }
  1873.   else if  (mode == SFmode)
  1874.     {
  1875.       output_asm_insn (\"c.le.s\\t%0,%1\\t\\t# bleu\", br_ops);
  1876.       output_asm_insn (\"bc1t\\t%2\\t\\t# bleu\", br_ops);
  1877.     }
  1878.   else
  1879.     {
  1880.       output_asm_insn (\"bleu\\t%0,%1,%2\\t\\t# bleu Inv.\", br_ops);
  1881.     }
  1882.   return \"\";
  1883. }
  1884. ")
  1885.  
  1886. ;;
  1887. ;;  ....................
  1888. ;;
  1889. ;;          LINKAGE
  1890. ;;
  1891. ;;  ....................
  1892.  
  1893. (define_insn "call"
  1894.   [(call (match_operand 0 "memory_operand" "m")
  1895.      (match_operand 1 "" "i"))
  1896.    (clobber (reg:SI 31))]
  1897.   ""
  1898.   "*
  1899. {
  1900.   register rtx target = XEXP (operands[0], 0);
  1901.  
  1902.   if (GET_CODE (target) == SYMBOL_REF)
  1903.     return \"jal\\t%0\";
  1904.  
  1905.   else
  1906.     {
  1907.       operands[0] = target;
  1908.       return \"jal\\t$31,%0\";
  1909.     }
  1910. }")
  1911.  
  1912.  
  1913. (define_insn "call_value"
  1914.   [(set (match_operand 0 "" "=rf")
  1915.         (call (match_operand 1 "memory_operand" "m")
  1916.               (match_operand 2 "" "i")))
  1917.    (clobber (reg:SI 31))]
  1918.   ""
  1919.   "*
  1920. {
  1921.   register rtx target = XEXP (operands[1], 0);
  1922.  
  1923.   if (GET_CODE (target) == SYMBOL_REF)
  1924.     return \"jal\\t%1\";
  1925.  
  1926.   else
  1927.     {
  1928.       operands[1] = target;
  1929.       return \"jal\\t$31,%1\";
  1930.     }
  1931. }")
  1932.  
  1933. (define_insn "nop"
  1934.   [(const_int 0)]
  1935.   ""
  1936.   ".set\\tnoreorder\;nop\;.set\\treorder")
  1937.  
  1938. (define_insn "probe"
  1939.   [(mem:SI (reg:SI 29))]
  1940.   ""
  1941.   "*
  1942. {
  1943.   operands[0] = gen_rtx (REG, SImode, 1);
  1944.   operands[1] = stack_pointer_rtx;
  1945.   return \".set\\tnoat\;lw\\t%0,0(%1)\\t\\t# stack probe\;.set\\tat\";
  1946. }")
  1947.  
  1948. ;;
  1949. ;;- Local variables:
  1950. ;;- mode:emacs-lisp
  1951. ;;- comment-start: ";;- "
  1952. ;;- eval: (set-syntax-table (copy-sequence (syntax-table)))
  1953. ;;- eval: (modify-syntax-entry ?[ "(]")
  1954. ;;- eval: (modify-syntax-entry ?] ")[")
  1955. ;;- eval: (modify-syntax-entry ?{ "(}")
  1956. ;;- eval: (modify-syntax-entry ?} "){")
  1957. ;;- End:
  1958.