home *** CD-ROM | disk | FTP | other *** search
/ Fresh Fish 4 / FreshFish_May-June1994.bin / bbs / gnu / gcc-2.5.8-src.lha / src / amiga / gcc-2.5.8 / config / arm / arm.md < prev    next >
Encoding:
Text File  |  1993-11-12  |  191.7 KB  |  6,275 lines

  1. ;;- Machine description Acorn RISC Machine for GNU compiler
  2. ;;  Copyright (C) 1991, 1993 Free Software Foundation, Inc.
  3. ;;  Contributed by Pieter `Tiggr' Schoenmakers (rcpieter@win.tue.nl)
  4. ;;             and Martin Simmons (@harleqn.co.uk).
  5. ;;  More major hacks by Richard Earnshaw (rwe11@cl.cam.ac.uk)
  6.  
  7. ;; This file is part of GNU CC.
  8.  
  9. ;; GNU CC is free software; you can redistribute it and/or modify
  10. ;; it under the terms of the GNU General Public License as published by
  11. ;; the Free Software Foundation; either version 2, or (at your option)
  12. ;; any later version.
  13.  
  14. ;; GNU CC is distributed in the hope that it will be useful,
  15. ;; but WITHOUT ANY WARRANTY; without even the implied warranty of
  16. ;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
  17. ;; GNU General Public License for more details.
  18.  
  19. ;; You should have received a copy of the GNU General Public License
  20. ;; along with GNU CC; see the file COPYING.  If not, write to
  21. ;; the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA.
  22.  
  23. ;;- See file "rtl.def" for documentation on define_insn, match_*, et. al.
  24.  
  25. ;; Every template must be output by arm_output_asm_insn, since this keeps
  26. ;; track of the offset of labels within the text segment.  This is needed to
  27. ;; to be able to (correctly) output instructions for loading a value from a
  28. ;; function's constant pool, since different instructions are needed when the
  29. ;; constant pool is more than 4095 bytes away from the PC.
  30.  
  31. ;; There are patterns in this file to support XFmode arithmetic.
  32. ;; Unfortunately RISCiX doesn't work well with these so they are disabled.
  33. ;; (See arm.h)
  34.  
  35. ;; UNSPEC Usage:
  36. ;; 0 `sin' operation: operand 0 is the result, operand 1 the parameter,
  37. ;;   the mode is MODE_FLOAT
  38. ;; 1 `cos' operation: operand 0 is the result, operand 1 the parameter,
  39. ;;   the mode is MODE_FLOAT
  40.  
  41. ;; Attributes
  42.  
  43. ; condition codes: this one is used by final_prescan_insn to speed up
  44. ; conditionalizing instructions.  It saves having to scan the rtl to see if
  45. ; it uses or alters the condition codes.
  46.  
  47. ; USE means that the condition codes are used by the insn in the process of
  48. ; outputting code, this means (at present) that we can't use the insn in
  49. ; inlined branches
  50.  
  51. ; SET means that the purpose of the insn is to set the condition codes in a
  52. ; well defined manner.
  53.  
  54. ; CLOB means that the condition codes are altered in an undefined manner, if
  55. ; they are altered at all
  56.  
  57. ; JUMP_CLOB is used when the conditions are not defined if a branch is taken,
  58. ; but are if the branch wasn't taken; the effect is to limit the branch
  59. ; elimination scanning.
  60.  
  61. ; NOCOND means that the condition codes are niether altered nor affect the
  62. ; output of this insn
  63.  
  64. (define_attr "conds" "use,set,clob,jump_clob,nocond"
  65.     (const_string "nocond"))
  66.  
  67. ; CPU attribute is used to determine whether condition codes are clobbered
  68. ; by a call insn: on the arm6 they are if in 32-bit addressing mode; on the
  69. ; arm2 and arm3 the condition codes are restored by the return.
  70.  
  71. (define_attr "cpu" "arm2,arm3,arm6" (const (symbol_ref "arm_cpu_attr")))
  72.  
  73. ; LENGTH, all instructions are 4 bytes
  74. (define_attr "length" "" (const_int 1))
  75.  
  76. ; An assembler sequence may clobber the condition codes without us knowing
  77. (define_asm_attributes
  78.  [(set_attr "conds" "clob")
  79.   (set_attr "length" "1")])
  80.  
  81. ; TYPE attribute is used to detect floating point instructions which, if
  82. ; running on a co-processor can run in parallel with other, basic instructions
  83. ; If write-buffer scheduling is enabled then it can also be used in the
  84. ; scheduling of writes.
  85.  
  86. ; Classification of each insn
  87. ; normal    any data instruction that doesn't hit memory or fp regs
  88. ; block        blockage insn, this blocks all functional units
  89. ; float        a floating point arithmetic operation (subject to expansion)
  90. ; float_em    a floating point arithmetic operation that is normally emulated
  91. ; f_load    a floating point load from memory
  92. ; f_store    a floating point store to memory
  93. ; f_mem_r    a transfer of a floating point register to a real reg via mem
  94. ; r_mem_f    the reverse of f_mem_r
  95. ; f_2_r        fast transfer float to arm (no memory needed)
  96. ; r_2_f        fast transfer arm to float
  97. ; call        a subroutine call
  98. ; load        any load from memory
  99. ; store1    store 1 word to memory from arm registers
  100. ; store2    store 2 words
  101. ; store3    store 3 words
  102. ; store4    store 4 words
  103. ;
  104. (define_attr "type"
  105.     "normal,block,float,float_em,f_load,f_store,f_mem_r,r_mem_f,f_2_r,r_2_f,call,load,store1,store2,store3,store4" 
  106.     (const_string "normal"))
  107.  
  108. (define_attr "write_conflict" "no,yes"
  109.   (if_then_else (eq_attr "type"
  110.          "block,float_em,f_load,f_store,f_mem_r,r_mem_f,call,load")
  111.         (const_string "yes")
  112.         (const_string "no")))
  113.  
  114. ; The write buffer on some of the arm6 processors is hard to model exactly.
  115. ; There is room in the buffer for up to two addresses and up to eight words
  116. ; of memory, but the two needn't be split evenly.  When writing the two
  117. ; addresses are fully pipelined.  However, a read from memory that is not
  118. ; currently in the cache will block until the writes have completed.
  119. ; It is normally the case that FCLK and MCLK will be in the ratio 2:1, so
  120. ; writes will take 2 FCLK cycles per word, if FCLK and MCLK are asynchronous
  121. ; (they aren't allowed to be at present) then there is a startup cost of 1MCLK
  122. ; cycle to add as well.
  123.  
  124. ;; (define_function_unit {name} {num-units} {n-users} {test}
  125. ;;                       {ready-delay} {issue-delay} [{conflict-list}])
  126. ;; This is not well tuned, but I don't have all the details.
  127. (define_function_unit "fpa" 1 1 (eq_attr "type" "float") 5 0)
  128.  
  129. (define_function_unit "write_buf" 1 2 (eq_attr "type" "store1") 3 3
  130.     [(eq_attr "write_conflict" "yes")])
  131. (define_function_unit "write_buf" 1 2 (eq_attr "type" "store2") 5 5
  132.     [(eq_attr "write_conflict" "yes")])
  133. (define_function_unit "write_buf" 1 2 (eq_attr "type" "store3") 7 7
  134.     [(eq_attr "write_conflict" "yes")])
  135. (define_function_unit "write_buf" 1 2 (eq_attr "type" "store4") 9 9
  136.     [(eq_attr "write_conflict" "yes")])
  137. (define_function_unit "write_buf" 1 2 (eq_attr "type" "r_mem_f") 3 3
  138.     [(eq_attr "write_conflict" "yes")])
  139.  
  140. ;; Note: For DImode insns, there is normally no reason why operands should
  141. ;; not be in the same register, what we don't want is for something being
  142. ;; written to partially overlap something that is an input.
  143.  
  144. ;; Addition insns.
  145.  
  146. (define_insn "adddi3"
  147.   [(set (match_operand:DI 0 "s_register_operand" "=&r,&r")
  148.     (plus:DI (match_operand:DI 1 "s_register_operand" "%0,0")
  149.          (match_operand:DI 2 "s_register_operand" "r,0")))
  150.    (clobber (reg:CC 24))]
  151.   ""
  152.   "*
  153.   arm_output_asm_insn (\"adds\\t%0, %1, %2\", operands);
  154.   return (arm_output_asm_insn (\"adc\\t%R0, %R1, %R2\", operands));
  155. "
  156. [(set_attr "conds" "clob")
  157.  (set_attr "length" "2")])
  158.  
  159. (define_insn ""
  160.   [(set (match_operand:DI 0 "s_register_operand" "=&r,&r")
  161.     (plus:DI (sign_extend:DI
  162.           (match_operand:SI 1 "s_register_operand" "r,r"))
  163.          (match_operand:DI 2 "s_register_operand" "r,0")))
  164.    (clobber (reg:CC 24))]
  165.   ""
  166.   "*
  167.   arm_output_asm_insn (\"adds\\t%0, %2, %1\", operands);
  168.   return (arm_output_asm_insn (\"adc\\t%R0, %R2, %1, asr #31\", operands));
  169. "
  170. [(set_attr "conds" "clob")
  171.  (set_attr "length" "2")])
  172.  
  173. (define_insn ""
  174.   [(set (match_operand:DI 0 "s_register_operand" "=&r,&r")
  175.     (plus:DI (zero_extend:DI
  176.           (match_operand:SI 1 "s_register_operand" "r,r"))
  177.          (match_operand:DI 2 "s_register_operand" "r,0")))
  178.    (clobber (reg:CC 24))]
  179.   ""
  180.   "*
  181.   arm_output_asm_insn (\"adds\\t%0, %2, %1\", operands);
  182.   return (arm_output_asm_insn (\"adc\\t%R0, %R2, #0\", operands));
  183. "
  184. [(set_attr "conds" "clob")
  185.  (set_attr "length" "2")])
  186.  
  187. (define_insn "addsi3"
  188.   [(set (match_operand:SI 0 "s_register_operand" "=r")
  189.     (plus:SI (match_operand:SI 1 "s_register_operand" "r")
  190.          (match_operand:SI 2 "arm_add_operand" "rL")))]
  191.   ""
  192.   "*
  193.   if (GET_CODE (operands[2]) == CONST_INT
  194.       && !const_ok_for_arm (INTVAL (operands[2])))
  195.     {
  196.       operands[2] = gen_rtx (CONST_INT, VOIDmode, -INTVAL (operands[2]));
  197.       return arm_output_asm_insn (\"sub\\t%0, %1, %2\", operands);
  198.     }
  199.   return arm_output_asm_insn (\"add\\t%0, %1, %2\", operands);
  200. ")
  201.  
  202. (define_insn ""
  203.   [(set (reg:CC_NOOV 24)
  204.     (compare:CC_NOOV (plus:SI (match_operand:SI 1 "s_register_operand" "r")
  205.                    (match_operand:SI 2 "arm_add_operand" "rL"))
  206.              (const_int 0)))
  207.    (set (match_operand:SI 0 "s_register_operand" "=r")
  208.     (plus:SI (match_dup 1) (match_dup 2)))]
  209.   ""
  210.   "*
  211.   if (GET_CODE (operands[2]) == CONST_INT
  212.       && !const_ok_for_arm (INTVAL (operands[2])))
  213.     {
  214.       operands[2] = gen_rtx (CONST_INT, VOIDmode, -INTVAL (operands[2]));
  215.       return arm_output_asm_insn (\"subs\\t%0, %1, %2\", operands);
  216.     }
  217.   return (arm_output_asm_insn (\"adds\\t%0, %1, %2\", operands));
  218. "
  219. [(set_attr "conds" "set")])
  220.  
  221. (define_insn ""
  222.   [(set (reg:CC 24)
  223.     (compare:CC (match_operand:SI 1 "s_register_operand" "r")
  224.             (neg:SI (match_operand:SI 2 "arm_add_operand" "rL"))))
  225.    (set (match_operand:SI 0 "s_register_operand" "=r")
  226.     (plus:SI (match_dup 1) (match_dup 2)))]
  227.   ""
  228.   "*
  229.   if (GET_CODE (operands[2]) == CONST_INT
  230.       && !const_ok_for_arm (INTVAL (operands[2])))
  231.     {
  232.       operands[2] = gen_rtx (CONST_INT, VOIDmode, -INTVAL (operands[2]));
  233.       return arm_output_asm_insn (\"subs\\t%0, %1, %2\", operands);
  234.     }
  235.   return (arm_output_asm_insn (\"adds\\t%0, %1, %2\", operands));
  236. "
  237. [(set_attr "conds" "set")])
  238.  
  239. (define_insn "incscc"
  240.   [(set (match_operand:SI 0 "s_register_operand" "=r,r")
  241.         (plus:SI (match_operator:SI 2 "comparison_operator"
  242.                     [(reg 24) (const_int 0)])
  243.                  (match_operand:SI 1 "s_register_operand" "0,?r")))]
  244.   ""
  245.   "*
  246.   if (which_alternative == 1)
  247.     arm_output_asm_insn (\"mov%D2\\t%0, %1\", operands);
  248.   return arm_output_asm_insn (\"add%d2\\t%0, %1, #1\", operands);
  249. "
  250. [(set_attr "conds" "use")
  251.  (set_attr "length" "*,2")])
  252.  
  253. ; If a constant is too big to fit in a single instruction then the constant
  254. ; will be pre-loaded into a register taking at least two insns, we might be
  255. ; able to merge it with an add, but it depends on the exact value.
  256.  
  257. (define_split
  258.   [(set (match_operand:SI 0 "s_register_operand" "=r")
  259.     (plus:SI (match_operand:SI 1 "s_register_operand" "r")
  260.          (match_operand:SI 2 "immediate_operand" "n")))]
  261.   "!(const_ok_for_arm (INTVAL (operands[2]))
  262.      || const_ok_for_arm (-INTVAL (operands[2])))"
  263.   [(set (match_dup 0) (plus:SI (match_dup 1) (match_dup 2)))
  264.    (set (match_dup 0) (plus:SI (match_dup 0) (match_dup 3)))]
  265.   "
  266. {
  267.   unsigned int val = (unsigned) INTVAL (operands[2]);
  268.   int i;
  269.   unsigned int temp;
  270.  
  271.   /* this code is similar to the approach followed in movsi, but it must
  272.      generate exactly two insns */
  273.  
  274.   for (i = 30; i >= 0; i -= 2)
  275.     {
  276.       if (val & (3 << i))
  277.     {
  278.       i -= 6;
  279.       if (i < 0) i = 0;
  280.       if (const_ok_for_arm (temp = (val & ~(255 << i))))
  281.         {
  282.           val &= 255 << i;
  283.           break;
  284.         }
  285.       /* we might be able to do this as (larger number - small number) */
  286.       temp = ((val >> i) & 255) + 1;
  287.       if (temp > 255 && i < 24)
  288.         {
  289.           i += 2;
  290.           temp = ((val >> i) & 255) + 1;
  291.         }
  292.       if (const_ok_for_arm ((temp << i) - val))
  293.         {
  294.           i = temp << i;
  295.           temp = (unsigned) - (int) (i - val);
  296.           val = i;
  297.           break;
  298.         }
  299.       FAIL;
  300.     }
  301.     }
  302.   /* if we got here, we have found a way of doing it in two instructions.
  303.      the two constants are in val and temp */
  304.   operands[2] = GEN_INT ((int)val);
  305.   operands[3] = GEN_INT ((int)temp);
  306. }
  307. ")
  308.  
  309. (define_insn "addsf3"
  310.   [(set (match_operand:SF 0 "s_register_operand" "=f,f")
  311.     (plus:SF (match_operand:SF 1 "s_register_operand" "f,f")
  312.          (match_operand:SF 2 "fpu_add_operand" "fG,H")))]
  313.   ""
  314.   "*
  315. {
  316.   REAL_VALUE_TYPE r;
  317.  
  318.   switch (which_alternative)
  319.     {
  320.     case 0:
  321.       return arm_output_asm_insn (\"adfs\\t%0, %1, %2\", operands);
  322.     case 1:
  323.       REAL_VALUE_FROM_CONST_DOUBLE (r, operands[2]);
  324.       r = REAL_VALUE_NEGATE (r);
  325.       operands[2] = CONST_DOUBLE_FROM_REAL_VALUE (r, GET_MODE (operands[2]));
  326.       return arm_output_asm_insn (\"sufs\\t%0, %1, %2\", operands);
  327.     }
  328. }
  329. "
  330. [(set_attr "type" "float")])
  331.  
  332. (define_insn "adddf3"
  333.   [(set (match_operand:DF 0 "s_register_operand" "=f,f")
  334.     (plus:DF (match_operand:DF 1 "s_register_operand" "f,f")
  335.          (match_operand:DF 2 "fpu_add_operand" "fG,H")))]
  336.   ""
  337.   "*
  338. {
  339.   REAL_VALUE_TYPE r;
  340.  
  341.   switch (which_alternative)
  342.     {
  343.     case 0:
  344.       return (arm_output_asm_insn (\"adfd\\t%0, %1, %2\", operands));
  345.     case 1:
  346.       REAL_VALUE_FROM_CONST_DOUBLE (r, operands[2]);
  347.       r = REAL_VALUE_NEGATE (r);
  348.       operands[2] = CONST_DOUBLE_FROM_REAL_VALUE (r, GET_MODE (operands[2]));
  349.       return arm_output_asm_insn (\"sufd\\t%0, %1, %2\", operands);
  350.     }
  351. }
  352. "
  353. [(set_attr "type" "float")])
  354.  
  355. (define_insn ""
  356.   [(set (match_operand:DF 0 "s_register_operand" "=f,f")
  357.     (plus:DF (float_extend:DF
  358.           (match_operand:SF 1 "s_register_operand" "f,f"))
  359.          (match_operand:DF 2 "fpu_add_operand" "fG,H")))]
  360.   ""
  361.   "*
  362. {
  363.   REAL_VALUE_TYPE r;
  364.  
  365.   switch (which_alternative)
  366.     {
  367.     case 0:
  368.       return (arm_output_asm_insn (\"adfd\\t%0, %1, %2\", operands));
  369.     case 1:
  370.       REAL_VALUE_FROM_CONST_DOUBLE (r, operands[2]);
  371.       r = REAL_VALUE_NEGATE (r);
  372.       operands[2] = CONST_DOUBLE_FROM_REAL_VALUE (r, GET_MODE (operands[2]));
  373.       return arm_output_asm_insn (\"sufd\\t%0, %1, %2\", operands);
  374.     }
  375. }
  376. "
  377. [(set_attr "type" "float")])
  378.  
  379. (define_insn ""
  380.   [(set (match_operand:DF 0 "s_register_operand" "=f")
  381.     (plus:DF (match_operand:DF 1 "s_register_operand" "f")
  382.          (float_extend:DF
  383.           (match_operand:SF 2 "s_register_operand" "f"))))]
  384.   ""
  385.   "*
  386.   return (arm_output_asm_insn (\"adfd\\t%0, %1, %2\", operands));
  387. "
  388. [(set_attr "type" "float")])
  389.  
  390. (define_insn ""
  391.   [(set (match_operand:DF 0 "s_register_operand" "=f")
  392.     (plus:DF (float_extend:DF 
  393.           (match_operand:SF 1 "s_register_operand" "f"))
  394.          (float_extend:DF
  395.           (match_operand:SF 2 "s_register_operand" "f"))))]
  396.   ""
  397.   "*
  398.   return (arm_output_asm_insn (\"adfd\\t%0, %1, %2\", operands));
  399. "
  400. [(set_attr "type" "float")])
  401.  
  402. (define_insn "addxf3"
  403.   [(set (match_operand:XF 0 "s_register_operand" "=f,f")
  404.     (plus:XF (match_operand:XF 1 "s_register_operand" "f,f")
  405.          (match_operand:XF 2 "fpu_add_operand" "fG,H")))]
  406.   "ENABLE_XF_PATTERNS"
  407.   "*
  408. {
  409.   REAL_VALUE_TYPE r;
  410.  
  411.   switch (which_alternative)
  412.     {
  413.     case 0:
  414.       return (arm_output_asm_insn (\"adfe\\t%0, %1, %2\", operands));
  415.     case 1:
  416.       REAL_VALUE_FROM_CONST_DOUBLE (r, operands[2]);
  417.       r = REAL_VALUE_NEGATE (r);
  418.       operands[2] = CONST_DOUBLE_FROM_REAL_VALUE (r, GET_MODE (operands[2]));
  419.       return arm_output_asm_insn (\"sufe\\t%0, %1, %2\", operands);
  420.     }
  421. }
  422. "
  423. [(set_attr "type" "float")])
  424.  
  425. (define_insn "subdi3"
  426.   [(set (match_operand:DI 0 "s_register_operand" "=&r,&r,&r")
  427.     (minus:DI (match_operand:DI 1 "s_register_operand" "0,r,0")
  428.           (match_operand:DI 2 "s_register_operand" "r,0,0")))
  429.    (clobber (reg:CC 24))]
  430.   ""
  431.   "*
  432.   arm_output_asm_insn (\"subs\\t%0, %1, %2\", operands);
  433.   return (arm_output_asm_insn (\"sbc\\t%R0, %R1, %R2\", operands));
  434. "
  435. [(set_attr "conds" "clob")
  436.  (set_attr "length" "2")])
  437.  
  438. (define_insn ""
  439.   [(set (match_operand:DI 0 "s_register_operand" "=&r,&r")
  440.     (minus:DI (match_operand:DI 1 "s_register_operand" "?r,0")
  441.           (zero_extend:DI
  442.            (match_operand:SI 2 "s_register_operand" "r,r"))))
  443.    (clobber (reg:CC 24))]
  444.   ""
  445.   "*
  446.   arm_output_asm_insn (\"subs\\t%0, %1, %2\", operands);
  447.   return (arm_output_asm_insn (\"sbc\\t%R0, %R1, #0\", operands));
  448. "
  449. [(set_attr "conds" "clob")
  450.  (set_attr "length" "2")])
  451.  
  452. (define_insn ""
  453.   [(set (match_operand:DI 0 "s_register_operand" "=&r,&r")
  454.     (minus:DI (match_operand:DI 1 "s_register_operand" "r,0")
  455.           (sign_extend:DI
  456.            (match_operand:SI 2 "s_register_operand" "r,r"))))
  457.    (clobber (reg:CC 24))]
  458.   ""
  459.   "*
  460.   arm_output_asm_insn (\"subs\\t%0, %1, %2\", operands);
  461.   return (arm_output_asm_insn (\"sbc\\t%R0, %R1, %2, asr #31\", operands));
  462. "
  463. [(set_attr "conds" "clob")
  464.  (set_attr "length" "2")])
  465.  
  466. (define_insn ""
  467.   [(set (match_operand:DI 0 "s_register_operand" "=&r,&r")
  468.     (minus:DI (zero_extend:DI
  469.            (match_operand:SI 2 "s_register_operand" "r,r"))
  470.           (match_operand:DI 1 "s_register_operand" "?r,0")))
  471.    (clobber (reg:CC 24))]
  472.   ""
  473.   "*
  474.   arm_output_asm_insn (\"rsbs\\t%0, %1, %2\", operands);
  475.   return (arm_output_asm_insn (\"rsc\\t%R0, %R1, #0\", operands));
  476. "
  477. [(set_attr "conds" "clob")
  478.  (set_attr "length" "2")])
  479.  
  480. (define_insn ""
  481.   [(set (match_operand:DI 0 "s_register_operand" "=&r,&r")
  482.     (minus:DI (sign_extend:DI
  483.            (match_operand:SI 2 "s_register_operand" "r,r"))
  484.           (match_operand:DI 1 "s_register_operand" "?r,0")))
  485.    (clobber (reg:CC 24))]
  486.   ""
  487.   "*
  488.   arm_output_asm_insn (\"rsbs\\t%0, %1, %2\", operands);
  489.   return (arm_output_asm_insn (\"rsc\\t%R0, %R1, %2, asr #31\", operands));
  490. "
  491. [(set_attr "conds" "clob")
  492.  (set_attr "length" "2")])
  493.  
  494. (define_insn ""
  495.   [(set (match_operand:DI 0 "s_register_operand" "=r")
  496.     (minus:DI (zero_extend:DI
  497.            (match_operand:SI 1 "s_register_operand" "r"))
  498.           (zero_extend:DI
  499.            (match_operand:SI 2 "s_register_operand" "r"))))
  500.    (clobber (reg:CC 24))]
  501.   ""
  502.   "*
  503.   arm_output_asm_insn (\"subs\\t%0, %1, %2\", operands);
  504.   return (arm_output_asm_insn (\"rsc\\t%R0, %1, %1 @ extend carry\",
  505.       operands));
  506. "
  507. [(set_attr "conds" "clob")
  508.  (set_attr "length" "2")])
  509.  
  510. (define_insn "subsi3"
  511.   [(set (match_operand:SI 0 "s_register_operand" "=r,r")
  512.     (minus:SI (match_operand:SI 1 "arm_rhs_operand" "r,I")
  513.           (match_operand:SI 2 "arm_rhs_operand" "rI,r")))]
  514.   ""
  515.   "*
  516.   switch (which_alternative)
  517.     {
  518.     case 0:
  519.       return (arm_output_asm_insn (\"sub\\t%0, %1, %2\", operands));
  520.     case 1:
  521.       return (arm_output_asm_insn (\"rsb\\t%0, %2, %1\", operands));
  522.     }
  523. ")
  524.  
  525. (define_insn ""
  526.   [(set (reg:CC_NOOV 24)
  527.     (compare:CC_NOOV (minus:SI (match_operand:SI 1 "arm_rhs_operand" "r,I")
  528.                  (match_operand:SI 2 "arm_rhs_operand" "rI,r"))
  529.              (const_int 0)))
  530.    (set (match_operand:SI 0 "s_register_operand" "=r,r")
  531.     (minus:SI (match_dup 1) (match_dup 2)))]
  532.   ""
  533.   "*
  534.   switch (which_alternative)
  535.     {
  536.     case 0:
  537.       return arm_output_asm_insn (\"subs\\t%0, %1, %2\", operands);
  538.     case 1:
  539.       return arm_output_asm_insn (\"rsbs\\t%0, %2, %1\", operands);
  540.     }
  541. "
  542. [(set_attr "conds" "set")])
  543.  
  544. (define_insn "decscc"
  545.   [(set (match_operand:SI 0 "s_register_operand" "=r,r")
  546.         (minus:SI (match_operand:SI 1 "s_register_operand" "0,?r")
  547.           (match_operator:SI 2 "comparison_operator"
  548.                    [(reg 24) (const_int 0)])))]
  549.   ""
  550.   "*
  551.   if (which_alternative == 1)
  552.     arm_output_asm_insn (\"mov%D2\\t%0, %1\", operands);
  553.   return arm_output_asm_insn (\"sub%d2\\t%0, %1, #1\", operands);
  554. "
  555. [(set_attr "conds" "use")
  556.  (set_attr "length" "*,2")])
  557.  
  558. (define_insn "subsf3"
  559.   [(set (match_operand:SF 0 "s_register_operand" "=f,f")
  560.     (minus:SF (match_operand:SF 1 "fpu_rhs_operand" "f,G")
  561.           (match_operand:SF 2 "fpu_rhs_operand" "fG,f")))]
  562.   ""
  563.   "*
  564.   switch (which_alternative)
  565.     {
  566.     case 0:
  567.       return (arm_output_asm_insn (\"sufs\\t%0, %1, %2\", operands));
  568.     case 1:
  569.       return (arm_output_asm_insn (\"rsfs\\t%0, %2, %1\", operands));
  570.     }
  571. "
  572. [(set_attr "type" "float")])
  573.  
  574. (define_insn "subdf3"
  575.   [(set (match_operand:DF 0 "s_register_operand" "=f,f")
  576.     (minus:DF (match_operand:DF 1 "fpu_rhs_operand" "f,G")
  577.           (match_operand:DF 2 "fpu_rhs_operand" "fG,f")))]
  578.   ""
  579.   "*
  580.   switch (which_alternative)
  581.     {
  582.     case 0:
  583.       return (arm_output_asm_insn (\"sufd\\t%0, %1, %2\", operands));
  584.     case 1:
  585.       return (arm_output_asm_insn (\"rsfd\\t%0, %2, %1\", operands));
  586.     }
  587. "
  588. [(set_attr "type" "float")])
  589.  
  590. (define_insn ""
  591.   [(set (match_operand:DF 0 "s_register_operand" "=f")
  592.     (minus:DF (float_extend:DF
  593.            (match_operand:SF 1 "s_register_operand" "f"))
  594.           (match_operand:DF 2 "fpu_rhs_operand" "fG")))]
  595.   ""
  596.   "*
  597.   return arm_output_asm_insn (\"sufd\\t%0, %1, %2\", operands);
  598. "
  599. [(set_attr "type" "float")])
  600.  
  601. (define_insn ""
  602.   [(set (match_operand:DF 0 "s_register_operand" "=f,f")
  603.     (minus:DF (match_operand:DF 1 "fpu_rhs_operand" "f,G")
  604.           (float_extend:DF
  605.            (match_operand:SF 2 "s_register_operand" "f,f"))))]
  606.   ""
  607.   "*
  608.   switch (which_alternative)
  609.     {
  610.     case 0:
  611.       return (arm_output_asm_insn (\"sufd\\t%0, %1, %2\", operands));
  612.     case 1:
  613.       return (arm_output_asm_insn (\"rsfd\\t%0, %2, %1\", operands));
  614.     }
  615. "
  616. [(set_attr "type" "float")])
  617.  
  618. (define_insn ""
  619.   [(set (match_operand:DF 0 "s_register_operand" "=f")
  620.     (minus:DF (float_extend:DF
  621.            (match_operand:SF 1 "s_register_operand" "f"))
  622.           (float_extend:DF
  623.            (match_operand:SF 2 "s_register_operand" "f"))))]
  624.   ""
  625.   "*
  626.   return arm_output_asm_insn (\"sufd\\t%0, %1, %2\", operands);
  627. "
  628. [(set_attr "type" "float")])
  629.  
  630. (define_insn "subxf3"
  631.   [(set (match_operand:XF 0 "s_register_operand" "=f,f")
  632.     (minus:XF (match_operand:XF 1 "fpu_rhs_operand" "f,G")
  633.           (match_operand:XF 2 "fpu_rhs_operand" "fG,f")))]
  634.   "ENABLE_XF_PATTERNS"
  635.   "*
  636.   switch (which_alternative)
  637.     {
  638.     case 0:
  639.       return (arm_output_asm_insn (\"sufe\\t%0, %1, %2\", operands));
  640.     case 1:
  641.       return (arm_output_asm_insn (\"rsfe\\t%0, %2, %1\", operands));
  642.     }
  643. "
  644. [(set_attr "type" "float")])
  645.  
  646. ;; Multiplication insns
  647.  
  648. ;; Use `&' and then `0' to prevent the operands 0 and 1 being the same
  649. (define_insn "mulsi3"
  650.   [(set (match_operand:SI 0 "s_register_operand" "=&r,&r")
  651.     (mult:SI (match_operand:SI 2 "s_register_operand" "r,r")
  652.          (match_operand:SI 1 "s_register_operand" "%?r,0")))]
  653.   ""
  654.   "*
  655.   return (arm_output_asm_insn (\"mul\\t%0, %2, %1\", operands));
  656. ")
  657.  
  658. (define_insn ""
  659.   [(set (reg:CC_NOOV 24)
  660.     (compare:CC_NOOV (mult:SI
  661.               (match_operand:SI 2 "s_register_operand" "r,r")
  662.               (match_operand:SI 1 "s_register_operand" "%?r,0"))
  663.              (const_int 0)))
  664.    (set (match_operand:SI 0 "s_register_operand" "=&r,&r")
  665.     (mult:SI (match_dup 2) (match_dup 1)))]
  666.   ""
  667.   "*
  668.   return (arm_output_asm_insn (\"muls\\t%0, %2, %1\", operands));
  669. "
  670. [(set_attr "conds" "set")])
  671.  
  672. (define_insn ""
  673.   [(set (reg:CC_NOOV 24)
  674.     (compare:CC_NOOV (mult:SI
  675.               (match_operand:SI 2 "s_register_operand" "r,r")
  676.               (match_operand:SI 1 "s_register_operand" "%?r,0"))
  677.              (const_int 0)))
  678.    (clobber (match_scratch:SI 0 "=&r,&r"))]
  679.   ""
  680.   "*
  681.   return (arm_output_asm_insn (\"muls\\t%0, %2, %1\", operands));
  682. "
  683. [(set_attr "conds" "set")])
  684.  
  685. ;; Unnamed templates to match MLA instruction.
  686.  
  687. (define_insn ""
  688.   [(set (match_operand:SI 0 "s_register_operand" "=&r,&r,&r,&r")
  689.     (plus:SI
  690.       (mult:SI (match_operand:SI 2 "s_register_operand" "r,r,r,r")
  691.            (match_operand:SI 1 "s_register_operand" "%r,0,r,0"))
  692.       (match_operand:SI 3 "s_register_operand" "?r,r,0,0")))]
  693.   ""
  694.   "*
  695.   return (arm_output_asm_insn (\"mla\\t%0, %2, %1, %3\", operands));
  696. ")
  697.  
  698. (define_insn ""
  699.   [(set (reg:CC_NOOV 24)
  700.     (compare:CC_NOOV (plus:SI
  701.               (mult:SI
  702.                (match_operand:SI 2 "s_register_operand" "r,r,r,r")
  703.                (match_operand:SI 1 "s_register_operand" "%r,0,r,0"))
  704.               (match_operand:SI 3 "s_register_operand" "?r,r,0,0"))
  705.              (const_int 0)))
  706.    (set (match_operand:SI 0 "s_register_operand" "=&r,&r,&r,&r")
  707.     (plus:SI (mult:SI (match_dup 2) (match_dup 1))
  708.          (match_dup 3)))]
  709.   ""
  710.   "*
  711.   return (arm_output_asm_insn (\"mlas\\t%0, %2, %1, %3\", operands));
  712. "
  713. [(set_attr "conds" "set")])
  714.  
  715. (define_insn ""
  716.   [(set (reg:CC_NOOV 24)
  717.     (compare:CC_NOOV (plus:SI
  718.               (mult:SI
  719.                (match_operand:SI 2 "s_register_operand" "r,r,r,r")
  720.                (match_operand:SI 1 "s_register_operand" "%r,0,r,0"))
  721.               (match_operand:SI 3 "s_register_operand" "?r,r,0,0"))
  722.              (const_int 0)))
  723.    (clobber (match_scratch:SI 0 "=&r,&r,&r,&r"))]
  724.   ""
  725.   "*
  726.   return (arm_output_asm_insn (\"mlas\\t%0, %2, %1, %3\", operands));
  727. "
  728. [(set_attr "conds" "set")])
  729.  
  730. (define_insn "mulsf3"
  731.   [(set (match_operand:SF 0 "s_register_operand" "=f")
  732.     (mult:SF (match_operand:SF 1 "s_register_operand" "f")
  733.          (match_operand:SF 2 "fpu_rhs_operand" "fG")))]
  734.   ""
  735.   "*
  736.   return (arm_output_asm_insn (\"fmls\\t%0, %1, %2\", operands));
  737. "
  738. [(set_attr "type" "float")])
  739.  
  740. (define_insn "muldf3"
  741.   [(set (match_operand:DF 0 "s_register_operand" "=f")
  742.     (mult:DF (match_operand:DF 1 "s_register_operand" "f")
  743.          (match_operand:DF 2 "fpu_rhs_operand" "fG")))]
  744.   ""
  745.   "*
  746.   return (arm_output_asm_insn (\"mufd\\t%0, %1, %2\", operands));
  747. "
  748. [(set_attr "type" "float")])
  749.  
  750. (define_insn ""
  751.   [(set (match_operand:DF 0 "s_register_operand" "=f")
  752.     (mult:DF (float_extend:DF
  753.           (match_operand:SF 1 "s_register_operand" "f"))
  754.          (match_operand:DF 2 "fpu_rhs_operand" "fG")))]
  755.   ""
  756.   "*
  757.   return (arm_output_asm_insn (\"mufd\\t%0, %1, %2\", operands));
  758. "
  759. [(set_attr "type" "float")])
  760.  
  761. (define_insn ""
  762.   [(set (match_operand:DF 0 "s_register_operand" "=f")
  763.     (mult:DF (match_operand:DF 1 "s_register_operand" "f")
  764.          (float_extend:DF
  765.           (match_operand:SF 2 "s_register_operand" "f"))))]
  766.   ""
  767.   "*
  768.   return (arm_output_asm_insn (\"mufd\\t%0, %1, %2\", operands));
  769. "
  770. [(set_attr "type" "float")])
  771.  
  772. (define_insn ""
  773.   [(set (match_operand:DF 0 "s_register_operand" "=f")
  774.     (mult:DF (float_extend:DF
  775.           (match_operand:SF 1 "s_register_operand" "f"))
  776.          (float_extend:DF
  777.           (match_operand:SF 2 "s_register_operand" "f"))))]
  778.   ""
  779.   "*
  780.   return (arm_output_asm_insn (\"mufd\\t%0, %1, %2\", operands));
  781. "
  782. [(set_attr "type" "float")])
  783.  
  784. (define_insn "mulxf3"
  785.   [(set (match_operand:XF 0 "s_register_operand" "=f")
  786.     (mult:XF (match_operand:XF 1 "s_register_operand" "f")
  787.          (match_operand:XF 2 "fpu_rhs_operand" "fG")))]
  788.   "ENABLE_XF_PATTERNS"
  789.   "*
  790.   return (arm_output_asm_insn (\"mufe\\t%0, %1, %2\", operands));
  791. "
  792. [(set_attr "type" "float")])
  793.  
  794. ;; Division insns
  795.  
  796. (define_insn "divsf3"
  797.   [(set (match_operand:SF 0 "s_register_operand" "=f,f")
  798.     (div:SF (match_operand:SF 1 "fpu_rhs_operand" "f,G")
  799.         (match_operand:SF 2 "fpu_rhs_operand" "fG,f")))]
  800.   ""
  801.   "*
  802.   switch (which_alternative)
  803.     {
  804.     case 0:
  805.       return (arm_output_asm_insn (\"fdvs\\t%0, %1, %2\", operands));
  806.     case 1:
  807.       return (arm_output_asm_insn (\"frds\\t%0, %2, %1\", operands));
  808.     }
  809. "
  810. [(set_attr "type" "float")])
  811.  
  812. (define_insn "divdf3"
  813.   [(set (match_operand:DF 0 "s_register_operand" "=f,f")
  814.     (div:DF (match_operand:DF 1 "fpu_rhs_operand" "f,G")
  815.         (match_operand:DF 2 "fpu_rhs_operand" "fG,f")))]
  816.   ""
  817.   "*
  818.   switch (which_alternative)
  819.     {
  820.     case 0:
  821.       return (arm_output_asm_insn (\"dvfd\\t%0, %1, %2\", operands));
  822.     case 1:
  823.       return (arm_output_asm_insn (\"rdfd\\t%0, %2, %1\", operands));
  824.     }
  825. "
  826. [(set_attr "type" "float")])
  827.  
  828. (define_insn ""
  829.   [(set (match_operand:DF 0 "s_register_operand" "=f")
  830.     (div:DF (float_extend:DF
  831.          (match_operand:SF 1 "s_register_operand" "f"))
  832.         (match_operand:DF 2 "fpu_rhs_operand" "fG")))]
  833.   ""
  834.   "*
  835.   return (arm_output_asm_insn (\"dvfd\\t%0, %1, %2\", operands));
  836. "
  837. [(set_attr "type" "float")])
  838.  
  839. (define_insn ""
  840.   [(set (match_operand:DF 0 "s_register_operand" "=f")
  841.     (div:DF (match_operand:DF 1 "fpu_rhs_operand" "fG")
  842.         (float_extend:DF
  843.          (match_operand:SF 2 "s_register_operand" "f"))))]
  844.   ""
  845.   "*
  846.   return (arm_output_asm_insn (\"rdfd\\t%0, %2, %1\", operands));
  847. "
  848. [(set_attr "type" "float")])
  849.  
  850. (define_insn ""
  851.   [(set (match_operand:DF 0 "s_register_operand" "=f")
  852.     (div:DF (float_extend:DF
  853.          (match_operand:SF 1 "s_register_operand" "f"))
  854.         (float_extend:DF
  855.          (match_operand:SF 2 "s_register_operand" "f"))))]
  856.   ""
  857.   "*
  858.   return (arm_output_asm_insn (\"dvfd\\t%0, %1, %2\", operands));
  859. "
  860. [(set_attr "type" "float")])
  861.  
  862. (define_insn "divxf3"
  863.   [(set (match_operand:XF 0 "s_register_operand" "=f,f")
  864.     (div:XF (match_operand:XF 1 "fpu_rhs_operand" "f,G")
  865.         (match_operand:XF 2 "fpu_rhs_operand" "fG,f")))]
  866.   "ENABLE_XF_PATTERNS"
  867.   "*
  868.   switch (which_alternative)
  869.     {
  870.     case 0:
  871.       return (arm_output_asm_insn (\"dvfe\\t%0, %1, %2\", operands));
  872.     case 1:
  873.       return (arm_output_asm_insn (\"rdfe\\t%0, %2, %1\", operands));
  874.     }
  875. "
  876. [(set_attr "type" "float")])
  877.  
  878. ;; Modulo insns
  879.  
  880. (define_insn "modsf3"
  881.   [(set (match_operand:SF 0 "s_register_operand" "=f")
  882.     (mod:SF (match_operand:SF 1 "s_register_operand" "f")
  883.         (match_operand:SF 2 "fpu_rhs_operand" "fG")))]
  884.   ""
  885.   "*
  886.   return (arm_output_asm_insn (\"rmfs\\t%0, %1, %2\", operands));
  887. "
  888. [(set_attr "type" "float")])
  889.  
  890. (define_insn "moddf3"
  891.   [(set (match_operand:DF 0 "s_register_operand" "=f")
  892.     (mod:DF (match_operand:DF 1 "s_register_operand" "f")
  893.         (match_operand:DF 2 "fpu_rhs_operand" "fG")))]
  894.   ""
  895.   "*
  896.   return (arm_output_asm_insn (\"rmfd\\t%0, %1, %2\", operands));
  897. "
  898. [(set_attr "type" "float")])
  899.  
  900. (define_insn ""
  901.   [(set (match_operand:DF 0 "s_register_operand" "=f")
  902.     (mod:DF (float_extend:DF
  903.          (match_operand:SF 1 "s_register_operand" "f"))
  904.         (match_operand:DF 2 "fpu_rhs_operand" "fG")))]
  905.   ""
  906.   "*
  907.   return (arm_output_asm_insn (\"rmfd\\t%0, %1, %2\", operands));
  908. "
  909. [(set_attr "type" "float")])
  910.  
  911. (define_insn ""
  912.   [(set (match_operand:DF 0 "s_register_operand" "=f")
  913.     (mod:DF (match_operand:DF 1 "s_register_operand" "f")
  914.         (float_extend:DF
  915.          (match_operand:SF 2 "s_register_operand" "f"))))]
  916.   ""
  917.   "*
  918.   return (arm_output_asm_insn (\"rmfd\\t%0, %1, %2\", operands));
  919. "
  920. [(set_attr "type" "float")])
  921.  
  922. (define_insn ""
  923.   [(set (match_operand:DF 0 "s_register_operand" "=f")
  924.     (mod:DF (float_extend:DF
  925.          (match_operand:SF 1 "s_register_operand" "f"))
  926.         (float_extend:DF
  927.          (match_operand:SF 2 "s_register_operand" "f"))))]
  928.   ""
  929.   "*
  930.   return (arm_output_asm_insn (\"rmfd\\t%0, %1, %2\", operands));
  931. "
  932. [(set_attr "type" "float")])
  933.  
  934. (define_insn "modxf3"
  935.   [(set (match_operand:XF 0 "s_register_operand" "=f")
  936.     (mod:XF (match_operand:XF 1 "s_register_operand" "f")
  937.         (match_operand:XF 2 "fpu_rhs_operand" "fG")))]
  938.   "ENABLE_XF_PATTERNS"
  939.   "*
  940.   return (arm_output_asm_insn (\"rmfe\\t%0, %1, %2\", operands));
  941. "
  942. [(set_attr "type" "float")])
  943.  
  944. ;; Boolean and,ior,xor insns
  945.  
  946. (define_insn "anddi3"
  947.   [(set (match_operand:DI 0 "s_register_operand" "=&r,&r")
  948.     (and:DI (match_operand:DI 1 "s_register_operand" "%0,0")
  949.         (match_operand:DI 2 "s_register_operand" "r,0")))]
  950.   ""
  951.   "*
  952.   arm_output_asm_insn (\"and\\t%0, %1, %2\", operands);
  953.   return (arm_output_asm_insn (\"and\\t%R0, %R1, %R2\", operands));
  954. "
  955. [(set_attr "length" "2")])
  956.  
  957. (define_insn ""
  958.   [(set (match_operand:DI 0 "s_register_operand" "=&r,&r")
  959.     (and:DI (zero_extend:DI
  960.          (match_operand:SI 2 "s_register_operand" "r,r"))
  961.         (match_operand:DI 1 "s_register_operand" "?r,0")))]
  962.   ""
  963.   "*
  964.   arm_output_asm_insn (\"and\\t%0, %1, %2\", operands);
  965.   return arm_output_asm_insn (\"mov\\t%R0, #0\", operands);
  966. "
  967. [(set_attr "length" "2")])
  968.  
  969. (define_insn ""
  970.   [(set (match_operand:DI 0 "s_register_operand" "=&r,&r")
  971.     (and:DI (sign_extend:DI
  972.          (match_operand:SI 2 "s_register_operand" "r,r"))
  973.         (match_operand:DI 1 "s_register_operand" "?r,0")))]
  974.   ""
  975.   "*
  976.   arm_output_asm_insn (\"and\\t%0, %1, %2\", operands);
  977.   return arm_output_asm_insn (\"and\\t%R0, %R1, %2, asr #31\", operands);
  978. "
  979. [(set_attr "length" "2")])
  980.  
  981. (define_insn "andsi3"
  982.   [(set (match_operand:SI 0 "s_register_operand" "=r")
  983.     (and:SI (match_operand:SI 1 "s_register_operand" "r")
  984.         (match_operand:SI 2 "arm_not_operand" "rK")))]
  985.   ""
  986.   "*
  987.   if (GET_CODE (operands[2]) == CONST_INT
  988.       && !const_ok_for_arm (INTVAL (operands[2])))
  989.     {
  990.       operands[2] = gen_rtx (CONST_INT, VOIDmode, ~INTVAL (operands[2]));
  991.       return arm_output_asm_insn (\"bic\\t%0, %1, %2\", operands);
  992.     }
  993.   return arm_output_asm_insn (\"and\\t%0, %1, %2\", operands);
  994. ")
  995.  
  996. (define_insn ""
  997.   [(set (reg:CC_NOOV 24)
  998.     (compare:CC_NOOV (and:SI (match_operand:SI 1 "s_register_operand" "r")
  999.                   (match_operand:SI 2 "arm_not_operand" "rK"))
  1000.              (const_int 0)))
  1001.    (set (match_operand:SI 0 "s_register_operand" "=r")
  1002.     (and:SI (match_dup 1) (match_dup 2)))]
  1003.   ""
  1004.   "*
  1005.   if (GET_CODE (operands[2]) == CONST_INT
  1006.       && !const_ok_for_arm (INTVAL (operands[2])))
  1007.     {
  1008.       operands[2] = gen_rtx (CONST_INT, VOIDmode, ~INTVAL (operands[2]));
  1009.       return arm_output_asm_insn (\"bics\\t%0, %1, %2\", operands);
  1010.     }
  1011.   return arm_output_asm_insn (\"ands\\t%0, %1, %2\", operands);
  1012. "
  1013. [(set_attr "conds" "set")])
  1014.  
  1015. (define_insn ""
  1016.   [(set (reg:CC_NOOV 24)
  1017.     (compare:CC_NOOV (and:SI (match_operand:SI 0 "s_register_operand" "r")
  1018.                   (match_operand:SI 1 "arm_rhs_operand" "rI"))
  1019.              (const_int 0)))]
  1020.   ""
  1021.   "*
  1022.   return arm_output_asm_insn (\"tst\\t%0, %1\", operands);
  1023. "
  1024. [(set_attr "conds" "set")])
  1025.  
  1026. (define_insn ""
  1027.   [(set (reg:CC_NOOV 24)
  1028.     (compare:CC_NOOV (and:SI (match_operand:SI 0 "s_register_operand" "r")
  1029.                   (match_operand:SI 1 "immediate_operand" "K"))
  1030.              (const_int 0)))
  1031.    (clobber (match_scratch:SI 3 "=r"))]
  1032.   "const_ok_for_arm (~INTVAL (operands[1]))"
  1033.   "*
  1034.   operands[1] = GEN_INT (~INTVAL (operands[1]));
  1035.   return arm_output_asm_insn (\"bics\\t%3, %0, %1\", operands);
  1036. "
  1037. [(set_attr "conds" "set")])
  1038.  
  1039. (define_insn ""
  1040.   [(set (reg:CC_NOOV 24)
  1041.     (compare:CC_NOOV (zero_extract:SI
  1042.               (match_operand:SI 0 "s_register_operand" "r")
  1043.                (match_operand:SI 1 "immediate_operand" "n")
  1044.               (match_operand:SI 2 "immediate_operand" "n"))
  1045.              (const_int 0)))]
  1046.   "INTVAL (operands[2]) >= 0 && INTVAL (operands[2]) < 32
  1047.    && INTVAL (operands[1]) > 0 
  1048.    && INTVAL (operands[1]) + (INTVAL (operands[2]) & 1) <= 8
  1049.    && INTVAL (operands[1]) + INTVAL (operands[2]) <= 32"
  1050.   "*
  1051. {
  1052.   unsigned int mask = 0;
  1053.   int cnt = INTVAL (operands[1]);
  1054.   
  1055.   while (cnt--)
  1056.     mask = (mask << 1) | 1;
  1057.   operands[1] = gen_rtx (CONST_INT, VOIDmode, mask << INTVAL (operands[2]));
  1058.   return arm_output_asm_insn (\"tst\\t%0, %1\", operands);
  1059. }
  1060. "
  1061. [(set_attr "conds" "set")])
  1062.  
  1063. (define_insn ""
  1064.   [(set (reg:CC_NOOV 24)
  1065.     (compare:CC_NOOV (zero_extract:SI
  1066.               (match_operand:QI 0 "memory_operand" "m")
  1067.                (match_operand 1 "immediate_operand" "n")
  1068.               (match_operand 2 "immediate_operand" "n"))
  1069.              (const_int 0)))
  1070.    (clobber (match_scratch:QI 3 "=r"))]
  1071.   "INTVAL (operands[2]) >= 0 && INTVAL (operands[2]) < 8
  1072.    && INTVAL (operands[1]) > 0 && INTVAL (operands[1]) <= 8"
  1073.   "*
  1074. {
  1075.   unsigned int mask = 0;
  1076.   int cnt = INTVAL (operands[1]);
  1077.   
  1078.   while (cnt--)
  1079.     mask = (mask << 1) | 1;
  1080.   operands[1] = gen_rtx (CONST_INT, VOIDmode, mask << INTVAL (operands[2]));
  1081.   arm_output_asm_insn (\"ldrb\\t%3, %0\", operands);
  1082.   return arm_output_asm_insn (\"tst\\t%3, %1\", operands);
  1083. }
  1084. "
  1085. [(set_attr "conds" "set")
  1086.  (set_attr "length" "2")])
  1087.  
  1088. ;; constants for op 2 will never be given to these patterns.
  1089. (define_insn ""
  1090.   [(set (match_operand:DI 0 "s_register_operand" "=&r,&r")
  1091.     (and:DI (not:DI (match_operand:DI 2 "s_register_operand" "r,0"))
  1092.         (match_operand:DI 1 "s_register_operand" "0,r")))]
  1093.   ""
  1094.   "*
  1095.   arm_output_asm_insn (\"bic\\t%0, %1, %2\", operands);
  1096.   return arm_output_asm_insn (\"bic\\t%R0, %R1, %R2\", operands);
  1097. "
  1098. [(set_attr "length" "2")])
  1099.   
  1100. (define_insn ""
  1101.   [(set (match_operand:DI 0 "s_register_operand" "=&r,&r")
  1102.     (and:DI (not:DI (zero_extend:DI
  1103.              (match_operand:SI 2 "s_register_operand" "r,r")))
  1104.         (match_operand:DI 1 "s_register_operand" "?r,0")))]
  1105.   ""
  1106.   "*
  1107.   arm_output_asm_insn (\"bic\\t%0, %1, %2\", operands);
  1108.   if (REGNO (operands[1]) != REGNO (operands[0]))
  1109.     return arm_output_asm_insn (\"mov\\t%R0, %R1\", operands);
  1110.   return \"\";
  1111. "
  1112. [(set_attr "length" "2,1")])
  1113.   
  1114. (define_insn ""
  1115.   [(set (match_operand:DI 0 "s_register_operand" "=&r,&r")
  1116.     (and:DI (not:DI (sign_extend:DI
  1117.              (match_operand:SI 2 "s_register_operand" "r,r")))
  1118.         (match_operand:DI 1 "s_register_operand" "?r,0")))]
  1119.   ""
  1120.   "*
  1121.   arm_output_asm_insn (\"bic\\t%0, %1, %2\", operands);
  1122.   return arm_output_asm_insn (\"bic\\t%R0, %R1, %2, asr #31\", operands);
  1123. "
  1124. [(set_attr "length" "2")])
  1125.   
  1126. (define_insn ""
  1127.   [(set (match_operand:SI 0 "s_register_operand" "=r")
  1128.     (and:SI (not:SI (match_operand:SI 2 "s_register_operand" "r"))
  1129.         (match_operand:SI 1 "s_register_operand" "r")))]
  1130.   ""
  1131.   "*
  1132.   return (arm_output_asm_insn (\"bic\\t%0, %1, %2\", operands));
  1133. ")
  1134.  
  1135. (define_insn ""
  1136.   [(set (reg:CC_NOOV 24)
  1137.     (compare:CC_NOOV (and:SI
  1138.               (not:SI (match_operand:SI 2 "s_register_operand" "r"))
  1139.               (match_operand:SI 1 "s_register_operand" "r"))
  1140.              (const_int 0)))
  1141.    (set (match_operand:SI 0 "s_register_operand" "=r")
  1142.     (and:SI (not:SI (match_dup 2)) (match_dup 1)))]
  1143.   ""
  1144.   "*
  1145.   return (arm_output_asm_insn (\"bics\\t%0, %1, %2\", operands));
  1146. "
  1147. [(set_attr "conds" "set")])
  1148.  
  1149. (define_insn ""
  1150.   [(set (reg:CC_NOOV 24)
  1151.     (compare:CC_NOOV (and:SI
  1152.               (not:SI (match_operand:SI 2 "s_register_operand" "r"))
  1153.               (match_operand:SI 1 "s_register_operand" "r"))
  1154.              (const_int 0)))
  1155.    (clobber (match_scratch:SI 0 "=r"))]
  1156.   ""
  1157.   "*
  1158.   return (arm_output_asm_insn (\"bics\\t%0, %1, %2\", operands));
  1159. "
  1160. [(set_attr "conds" "set")])
  1161.  
  1162. (define_insn "iordi3"
  1163.   [(set (match_operand:DI 0 "s_register_operand" "=&r")
  1164.     (ior:DI (match_operand:DI 1 "s_register_operand" "%0")
  1165.         (match_operand:DI 2 "s_register_operand" "r")))]
  1166.   ""
  1167.   "*
  1168.   arm_output_asm_insn (\"orr\\t%0, %1, %2\", operands);
  1169.   return (arm_output_asm_insn (\"orr\\t%R0, %R1, %R2\", operands));
  1170. "
  1171. [(set_attr "length" "2")])
  1172.  
  1173. (define_insn ""
  1174.   [(set (match_operand:DI 0 "s_register_operand" "=&r,&r")
  1175.     (ior:DI (zero_extend:DI
  1176.          (match_operand:SI 2 "s_register_operand" "r,r"))
  1177.         (match_operand:DI 1 "s_register_operand" "?r,0")))]
  1178.   ""
  1179.   "*
  1180.   arm_output_asm_insn (\"orr\\t%0, %1, %2\", operands);
  1181.   if (REGNO (operands[0]) != REGNO (operands[1]))
  1182.     return (arm_output_asm_insn (\"mov\\t%R0, %R1\", operands));
  1183.   return \"\";
  1184. "
  1185. [(set_attr "length" "2,1")])
  1186.  
  1187. (define_insn ""
  1188.   [(set (match_operand:DI 0 "s_register_operand" "=&r,&r")
  1189.     (ior:DI (sign_extend:DI
  1190.          (match_operand:SI 2 "s_register_operand" "r,r"))
  1191.         (match_operand:DI 1 "s_register_operand" "?r,0")))]
  1192.   ""
  1193.   "*
  1194.   arm_output_asm_insn (\"orr\\t%0, %1, %2\", operands);
  1195.   return (arm_output_asm_insn (\"orr\\t%R0, %R1, %2, asr #31\", operands));
  1196. "
  1197. [(set_attr "length" "2")])
  1198.  
  1199. (define_insn "iorsi3"
  1200.   [(set (match_operand:SI 0 "s_register_operand" "=r")
  1201.     (ior:SI (match_operand:SI 1 "s_register_operand" "r")
  1202.         (match_operand:SI 2 "arm_rhs_operand" "rI")))]
  1203.   ""
  1204.   "*
  1205.   return (arm_output_asm_insn (\"orr\\t%0, %1, %2\", operands));
  1206. ")
  1207.  
  1208. (define_insn ""
  1209.   [(set (reg:CC_NOOV 24)
  1210.     (compare:CC_NOOV (ior:SI (match_operand:SI 1 "s_register_operand" "%r")
  1211.                  (match_operand:SI 2 "arm_rhs_operand" "rI"))
  1212.              (const_int 0)))
  1213.    (set (match_operand:SI 0 "s_register_operand" "=r")
  1214.     (ior:SI (match_dup 1) (match_dup 2)))]
  1215.   ""
  1216.   "*
  1217.   return arm_output_asm_insn (\"orrs\\t%0, %1, %2\", operands);
  1218. "
  1219. [(set_attr "conds" "set")])
  1220.  
  1221. (define_insn ""
  1222.   [(set (reg:CC_NOOV 24)
  1223.     (compare:CC_NOOV (ior:SI (match_operand:SI 1 "s_register_operand" "%r")
  1224.                  (match_operand:SI 2 "arm_rhs_operand" "rI"))
  1225.              (const_int 0)))
  1226.    (clobber (match_scratch:SI 0 "=r"))]
  1227.   ""
  1228.   "*
  1229.   return arm_output_asm_insn (\"orrs\\t%0, %1, %2\", operands);
  1230. "
  1231. [(set_attr "conds" "set")])
  1232.  
  1233. (define_insn "xordi3"
  1234.   [(set (match_operand:DI 0 "s_register_operand" "=&r,&r")
  1235.     (xor:DI (match_operand:DI 1 "s_register_operand" "%0,0")
  1236.         (match_operand:DI 2 "s_register_operand" "r,0")))]
  1237.   ""
  1238.   "*
  1239.   arm_output_asm_insn (\"eor\\t%0, %1, %2\", operands);
  1240.   return arm_output_asm_insn (\"eor\\t%R0, %R1, %R2\", operands);
  1241. "
  1242. [(set_attr "length" "2")])
  1243.  
  1244. (define_insn ""
  1245.   [(set (match_operand:DI 0 "s_register_operand" "=&r,&r")
  1246.     (xor:DI (zero_extend:DI
  1247.          (match_operand:SI 2 "s_register_operand" "r,r"))
  1248.         (match_operand:DI 1 "s_register_operand" "?r,0")))]
  1249.   ""
  1250.   "*
  1251.   arm_output_asm_insn (\"eor\\t%0, %1, %2\", operands);
  1252.   if (REGNO (operands[0]) != REGNO (operands[1]))
  1253.     return arm_output_asm_insn (\"mov\\t%R0, %R1\", operands);
  1254.   return \"\";
  1255. "
  1256. [(set_attr "length" "2,1")])
  1257.  
  1258. (define_insn ""
  1259.   [(set (match_operand:DI 0 "s_register_operand" "=&r,&r")
  1260.     (xor:DI (sign_extend:DI
  1261.          (match_operand:SI 2 "s_register_operand" "r,r"))
  1262.         (match_operand:DI 1 "s_register_operand" "?r,0")))]
  1263.   ""
  1264.   "*
  1265.   arm_output_asm_insn (\"eor\\t%0, %1, %2\", operands);
  1266.   return arm_output_asm_insn (\"eor\\t%R0, %R1, %2, asr #31\", operands);
  1267. "
  1268. [(set_attr "length" "2")])
  1269.  
  1270. (define_insn "xorsi3"
  1271.   [(set (match_operand:SI 0 "s_register_operand" "=r")
  1272.     (xor:SI (match_operand:SI 1 "s_register_operand" "r")
  1273.         (match_operand:SI 2 "arm_rhs_operand" "rI")))]
  1274.   ""
  1275.   "*
  1276.   return (arm_output_asm_insn (\"eor\\t%0, %1, %2\", operands));
  1277. ")
  1278.  
  1279. (define_insn ""
  1280.   [(set (reg:CC_NOOV 24)
  1281.     (compare:CC_NOOV (xor:SI (match_operand:SI 1 "s_register_operand" "r")
  1282.                  (match_operand:SI 2 "arm_rhs_operand" "rI"))
  1283.              (const_int 0)))
  1284.    (set (match_operand:SI 0 "s_register_operand" "=r")
  1285.     (xor:SI (match_dup 1) (match_dup 2)))]
  1286.   ""
  1287.   "*
  1288.   return arm_output_asm_insn (\"eors\\t%0, %1, %2\", operands);
  1289. "
  1290. [(set_attr "conds" "set")])
  1291.  
  1292. (define_insn ""
  1293.   [(set (reg:CC_NOOV 24)
  1294.     (compare:CC_NOOV (xor:SI (match_operand:SI 0 "s_register_operand" "r")
  1295.                  (match_operand:SI 1 "arm_rhs_operand" "rI"))
  1296.              (const_int 0)))]
  1297.   ""
  1298.   "*
  1299.   return arm_output_asm_insn (\"teq\\t%0, %1\", operands);
  1300. "
  1301. [(set_attr "conds" "set")])
  1302.  
  1303. ;; by splitting (IOR (AND (NOT A) (NOT B)) C) as D = AND (IOR A B) (NOT C), 
  1304. ;; (NOT D) we can sometimes merge the final NOT into one of the following
  1305. ;; insns
  1306.  
  1307. (define_split
  1308.   [(set (match_operand:SI 0 "s_register_operand" "=r")
  1309.     (ior:SI (and:SI (not:SI (match_operand:SI 1 "s_register_operand" "r"))
  1310.             (not:SI (match_operand:SI 2 "arm_rhs_operand" "rI")))
  1311.         (match_operand:SI 3 "arm_rhs_operand" "rI")))
  1312.    (clobber (match_operand:SI 4 "s_register_operand" "=r"))]
  1313.   ""
  1314.   [(set (match_dup 4) (and:SI (ior:SI (match_dup 1) (match_dup 2))
  1315.                   (not:SI (match_dup 3))))
  1316.    (set (match_dup 0) (not:SI (match_dup 4)))]
  1317.   ""
  1318. )
  1319.  
  1320. (define_insn ""
  1321.   [(set (match_operand:SI 0 "s_register_operand" "=&r,&r,&r")
  1322.     (and:SI (ior:SI (match_operand:SI 1 "s_register_operand" "r,r,0")
  1323.             (match_operand:SI 2 "arm_rhs_operand" "rI,0,rI"))
  1324.         (not:SI (match_operand:SI 3 "arm_rhs_operand" "rI,rI,rI"))))]
  1325.   ""
  1326.   "*
  1327.   arm_output_asm_insn (\"orr\\t%0, %1, %2\", operands);
  1328.   return arm_output_asm_insn (\"bic\\t%0, %0, %3\", operands);
  1329. "
  1330. [(set_attr "length" "2")])
  1331.  
  1332.  
  1333.  
  1334. ;; Minimum and maximum insns
  1335.  
  1336. (define_insn "smaxsi3"
  1337.   [(set (match_operand:SI 0 "s_register_operand" "=r,r,r")
  1338.     (smax:SI (match_operand:SI 1 "s_register_operand" "0,r,?r")
  1339.          (match_operand:SI 2 "arm_rhs_operand" "rI,0,rI")))
  1340.    (clobber (reg:CC 24))]
  1341.   ""
  1342.   "*
  1343.   arm_output_asm_insn (\"cmp\\t%1, %2\", operands);
  1344.   if (which_alternative != 0)
  1345.     arm_output_asm_insn (\"movge\\t%0, %1\", operands);
  1346.   if (which_alternative != 1)
  1347.     return arm_output_asm_insn (\"movlt\\t%0, %2\", operands);
  1348.   return \"\";
  1349. "
  1350. [(set_attr "conds" "clob")
  1351.  (set_attr "length" "2,2,3")])
  1352.  
  1353. (define_insn "sminsi3"
  1354.   [(set (match_operand:SI 0 "s_register_operand" "=r,r,r")
  1355.     (smin:SI (match_operand:SI 1 "s_register_operand" "0,r,?r")
  1356.          (match_operand:SI 2 "arm_rhs_operand" "rI,0,rI")))
  1357.    (clobber (reg:CC 24))]
  1358.   ""
  1359.   "*
  1360.   arm_output_asm_insn (\"cmp\\t%1, %2\", operands);
  1361.   if (which_alternative != 0)
  1362.     arm_output_asm_insn (\"movle\\t%0, %1\", operands);
  1363.   if (which_alternative != 1)
  1364.     return arm_output_asm_insn (\"movgt\\t%0, %2\", operands);
  1365.   return \"\";
  1366. "
  1367. [(set_attr "conds" "clob")
  1368.  (set_attr "length" "2,2,3")])
  1369.  
  1370. (define_insn "umaxsi3"
  1371.   [(set (match_operand:SI 0 "s_register_operand" "=r,r,r")
  1372.     (umax:SI (match_operand:SI 1 "s_register_operand" "0,r,?r")
  1373.          (match_operand:SI 2 "arm_rhs_operand" "rI,0,rI")))
  1374.    (clobber (reg:CC 24))]
  1375.   ""
  1376.   "*
  1377.   arm_output_asm_insn (\"cmp\\t%1, %2\", operands);
  1378.   if (which_alternative != 0)
  1379.     arm_output_asm_insn (\"movcs\\t%0, %1\", operands);
  1380.   if (which_alternative != 1)
  1381.     return arm_output_asm_insn (\"movcc\\t%0, %2\", operands);
  1382.   return \"\";
  1383. "
  1384. [(set_attr "conds" "clob")
  1385.  (set_attr "length" "2,2,3")])
  1386.  
  1387. (define_insn "uminsi3"
  1388.   [(set (match_operand:SI 0 "s_register_operand" "=r,r,r")
  1389.     (umin:SI (match_operand:SI 1 "s_register_operand" "0,r,?r")
  1390.          (match_operand:SI 2 "arm_rhs_operand" "rI,0,rI")))
  1391.    (clobber (reg:CC 24))]
  1392.   ""
  1393.   "*
  1394.   arm_output_asm_insn (\"cmp\\t%1, %2\", operands);
  1395.   if (which_alternative != 0)
  1396.     arm_output_asm_insn (\"movcc\\t%0, %1\", operands);
  1397.   if (which_alternative != 1)
  1398.     return arm_output_asm_insn (\"movcs\\t%0, %2\", operands);
  1399.   return \"\";
  1400. "
  1401. [(set_attr "conds" "clob")
  1402.  (set_attr "length" "2,2,3")])
  1403.  
  1404. (define_insn ""
  1405.   [(set (match_operand:SI 0 "memory_operand" "=m")
  1406.     (match_operator:SI 3 "minmax_operator"
  1407.      [(match_operand:SI 1 "s_register_operand" "r")
  1408.       (match_operand:SI 2 "s_register_operand" "r")]))
  1409.    (clobber (reg:CC 24))]
  1410.   ""
  1411.   "*
  1412.   operands[3] = gen_rtx (minmax_code (operands[3]), SImode, operands[1],
  1413.              operands[2]);
  1414.   arm_output_asm_insn (\"cmp\\t%1, %2\", operands);
  1415.   arm_output_asm_insn (\"str%d3\\t%1, %0\", operands);
  1416.   return arm_output_asm_insn (\"str%D3\\t%2, %0\", operands);
  1417. "
  1418. [(set_attr "conds" "clob")
  1419.  (set_attr "length" "3")
  1420.  (set_attr "type" "store1")])
  1421.  
  1422. (define_insn ""
  1423.   [(set (match_operand:SI 0 "s_register_operand" "=r,r")
  1424.     (match_operator:SI 4 "shiftable_operator"
  1425.      [(match_operator:SI 5 "minmax_operator"
  1426.        [(match_operand:SI 2 "s_register_operand" "r,r")
  1427.         (match_operand:SI 3 "arm_rhs_operand" "rI,rI")])
  1428.       (match_operand:SI 1 "s_register_operand" "0,?r")]))
  1429.    (clobber (reg:CC 24))]
  1430.   ""
  1431.   "*
  1432. {
  1433.   char buf[100];
  1434.   enum rtx_code code = GET_CODE (operands[4]);
  1435.   char *inst = arithmetic_instr (operands[4], TRUE);
  1436.  
  1437.   operands[5] = gen_rtx (minmax_code (operands[5]), SImode, operands[2],
  1438.              operands[3]);
  1439.   arm_output_asm_insn (\"cmp\\t%2, %3\", operands);
  1440.   sprintf (buf, \"%s%%d5\\t%%0, %%1, %%2\", inst);
  1441.   arm_output_asm_insn (buf, operands);
  1442.   if (which_alternative != 0 || operands[3] != const0_rtx
  1443.       || (code != PLUS && code != MINUS && code != IOR && code != XOR))
  1444.   {
  1445.     sprintf (buf, \"%s%%D5\\t%%0, %%1, %%3\", inst);
  1446.     return arm_output_asm_insn (buf, operands);
  1447.   }
  1448.   return \"\";
  1449. }
  1450. "
  1451. [(set_attr "conds" "clob")
  1452.  (set_attr "length" "3")])
  1453.  
  1454.  
  1455. ;; Shift and rotation insns
  1456.  
  1457. (define_insn "ashlsi3"
  1458.   [(set (match_operand:SI 0 "s_register_operand" "=r")
  1459.     (ashift:SI (match_operand:SI 1 "s_register_operand" "r")
  1460.            (match_operand:SI 2 "arm_rhs_operand" "rn")))]
  1461.   ""
  1462.   "*
  1463.   return (output_shifted_move (ASHIFT, operands));
  1464. ")
  1465.  
  1466. (define_insn "ashrsi3"
  1467.   [(set (match_operand:SI 0 "s_register_operand" "=r")
  1468.     (ashiftrt:SI (match_operand:SI 1 "s_register_operand" "r")
  1469.              (match_operand:SI 2 "arm_rhs_operand" "rn")))]
  1470.   ""
  1471.   "*
  1472.   return (output_shifted_move (ASHIFTRT, operands));
  1473. ")
  1474.  
  1475. ;; lshlsi3 is not defined because shift counts cannot be negative
  1476. ;; An unnamed pattern is needed for expansion of zero_extend.
  1477.  
  1478. (define_insn ""
  1479.   [(set (match_operand:SI 0 "s_register_operand" "=r")
  1480.     (lshift:SI (match_operand:SI 1 "s_register_operand" "r")
  1481.            (match_operand:SI 2 "arm_rhs_operand" "rn")))]
  1482.   ""
  1483.   "*
  1484.   return (output_shifted_move (LSHIFT, operands));
  1485. ")
  1486.  
  1487. (define_insn "lshrsi3"
  1488.   [(set (match_operand:SI 0 "s_register_operand" "=r")
  1489.     (lshiftrt:SI (match_operand:SI 1 "s_register_operand" "r")
  1490.              (match_operand:SI 2 "arm_rhs_operand" "rn")))]
  1491.   ""
  1492.   "*
  1493.   return (output_shifted_move (LSHIFTRT, operands));
  1494. ")
  1495.  
  1496. ;; rotlsi3 is not defined yet to see what happens
  1497.  
  1498. (define_insn "rotrsi3"
  1499.   [(set (match_operand:SI 0 "s_register_operand" "=r,r")
  1500.     (rotatert:SI (match_operand:SI 1 "s_register_operand" "r,r")
  1501.              (match_operand:SI 2 "arm_rhs_operand" "r,n")))]
  1502.   ""
  1503.   "*
  1504.   switch (which_alternative)
  1505.     {
  1506.     case 0:
  1507.       return (arm_output_asm_insn (\"mov\\t%0, %1, ror %2\", operands));
  1508.     case 1:
  1509.       if (INTVAL(operands[2]) > 31)
  1510.     operands[2] = gen_rtx (CONST_INT, VOIDmode, INTVAL (operands[2]) % 32);
  1511.       return (arm_output_asm_insn (\"mov\\t%0, %1, ror %2\", operands));
  1512.     }
  1513. ")
  1514.  
  1515. (define_insn ""
  1516.   [(set (reg:CC_NOOV 24)
  1517.     (compare:CC_NOOV (match_operator:SI 1 "shift_operator"
  1518.               [(match_operand:SI 2 "s_register_operand" "r")
  1519.                (match_operand:SI 3 "arm_rhs_operand" "rn")])
  1520.              (const_int 0)))
  1521.    (set (match_operand:SI 0 "s_register_operand" "=r")
  1522.     (match_op_dup 1 [(match_dup 2) (match_dup 3)]))]
  1523.   ""
  1524.   "*
  1525. {
  1526.   char buf[100];
  1527.  
  1528.   sprintf (buf, \"movs\\t%%0, %%2, %s %%3\",
  1529.        shift_instr (GET_CODE (operands[1]), &operands[3]));
  1530.   return arm_output_asm_insn (buf, operands);
  1531. }
  1532. "
  1533. [(set_attr "conds" "set")])
  1534.  
  1535. (define_insn ""
  1536.   [(set (reg:CC_NOOV 24)
  1537.     (compare:CC_NOOV (match_operator:SI 1 "shift_operator"
  1538.               [(match_operand:SI 2 "s_register_operand" "r")
  1539.                (match_operand:SI 3 "arm_rhs_operand" "rn")])
  1540.              (const_int 0)))
  1541.    (clobber (match_scratch:SI 0 "=r"))]
  1542.   ""
  1543.   "*
  1544. {
  1545.   char buf[100];
  1546.  
  1547.   sprintf (buf, \"movs\\t%%0, %%2, %s %%3\",
  1548.        shift_instr (GET_CODE (operands[1]), &operands[3]));
  1549.   return arm_output_asm_insn (buf, operands);
  1550. }
  1551. "
  1552. [(set_attr "conds" "set")])
  1553.  
  1554. (define_insn ""
  1555.   [(set (match_operand:SI 0 "s_register_operand" "=r")
  1556.     (not:SI (match_operator:SI 1 "shift_operator"
  1557.          [(match_operand:SI 2 "s_register_operand" "r")
  1558.           (match_operand:SI 3 "arm_rhs_operand" "rn")])))]
  1559.   ""
  1560.   "*
  1561. {
  1562.   char buf[100];
  1563.   sprintf (buf, \"mvn\\t%%0, %%2, %s %%3\",
  1564.        shift_instr (GET_CODE (operands[1]), &operands[3]));
  1565.   return arm_output_asm_insn (buf, operands);
  1566. }
  1567. ")
  1568.  
  1569. (define_insn ""
  1570.   [(set (reg:CC_NOOV 24)
  1571.     (compare:CC_NOOV (not:SI (match_operator:SI 1 "shift_operator"
  1572.               [(match_operand:SI 2 "s_register_operand" "r")
  1573.                (match_operand:SI 3 "arm_rhs_operand" "rn")]))
  1574.              (const_int 0)))
  1575.    (set (match_operand:SI 0 "s_register_operand" "=r")
  1576.     (not:SI (match_op_dup 1 [(match_dup 2) (match_dup 3)])))]
  1577.   ""
  1578.   "*
  1579. {
  1580.   char buf[100];
  1581.   sprintf (buf, \"mvns\\t%%0, %%2, %s %%3\",
  1582.        shift_instr (GET_CODE (operands[1]), &operands[3]));
  1583.   return arm_output_asm_insn (buf, operands);
  1584. }
  1585. "
  1586. [(set_attr "conds" "set")])
  1587.  
  1588. (define_insn ""
  1589.   [(set (reg:CC_NOOV 24)
  1590.     (compare:CC_NOOV (not:SI (match_operator:SI 1 "shift_operator"
  1591.               [(match_operand:SI 2 "s_register_operand" "r")
  1592.                (match_operand:SI 3 "arm_rhs_operand" "rn")]))
  1593.              (const_int 0)))
  1594.    (clobber (match_scratch:SI 0 "=r"))]
  1595.   ""
  1596.   "*
  1597. {
  1598.   char buf[100];
  1599.   sprintf (buf, \"mvns\\t%%0, %%2, %s %%3\",
  1600.        shift_instr (GET_CODE (operands[1]), &operands[3]));
  1601.   return arm_output_asm_insn (buf, operands);
  1602. }
  1603. "
  1604. [(set_attr "conds" "set")])
  1605.  
  1606.  
  1607. ;; Unary arithmetic insns
  1608.  
  1609. (define_insn "negdi2"
  1610.   [(set (match_operand:DI 0 "s_register_operand" "=&r,&r")
  1611.     (neg:DI (match_operand:DI 1 "s_register_operand" "?r,0")))]
  1612.   ""
  1613.   "*
  1614.   arm_output_asm_insn (\"rsbs\\t%0, %1, #0\", operands);
  1615.   return (arm_output_asm_insn (\"rsc\\t%R0, %R1, #0\", operands));
  1616. "
  1617. [(set_attr "conds" "clob")
  1618.  (set_attr "length" "2")])
  1619.  
  1620. (define_insn "negsi2"
  1621.   [(set (match_operand:SI 0 "s_register_operand" "=r")
  1622.     (neg:SI (match_operand:SI 1 "s_register_operand" "r")))]
  1623.   ""
  1624.   "*
  1625.   return (arm_output_asm_insn (\"rsb\\t%0, %1, #0\", operands));
  1626. ")
  1627.  
  1628. (define_insn "negsf2"
  1629.   [(set (match_operand:SF 0 "s_register_operand" "=f")
  1630.     (neg:SF (match_operand:SF 1 "s_register_operand" "f")))]
  1631.   ""
  1632.   "*
  1633.   return (arm_output_asm_insn (\"mnfs\\t%0, %1\", operands));
  1634. "
  1635. [(set_attr "type" "float")])
  1636.  
  1637. (define_insn "negdf2"
  1638.   [(set (match_operand:DF 0 "s_register_operand" "=f")
  1639.     (neg:DF (match_operand:DF 1 "s_register_operand" "f")))]
  1640.   ""
  1641.   "*
  1642.   return (arm_output_asm_insn (\"mnfd\\t%0, %1\", operands));
  1643. "
  1644. [(set_attr "type" "float")])
  1645.  
  1646. (define_insn ""
  1647.   [(set (match_operand:DF 0 "s_register_operand" "=f")
  1648.     (neg:DF (float_extend:DF
  1649.          (match_operand:SF 1 "s_register_operand" "f"))))]
  1650.   ""
  1651.   "*
  1652.   return (arm_output_asm_insn (\"mnfd\\t%0, %1\", operands));
  1653. "
  1654. [(set_attr "type" "float")])
  1655.  
  1656. (define_insn "negxf2"
  1657.   [(set (match_operand:XF 0 "s_register_operand" "=f")
  1658.     (neg:XF (match_operand:XF 1 "s_register_operand" "f")))]
  1659.   "ENABLE_XF_PATTERNS"
  1660.   "*
  1661.   return (arm_output_asm_insn (\"mnfe\\t%0, %1\", operands));
  1662. "
  1663. [(set_attr "type" "float")])
  1664.  
  1665. ;; abssi2 doesn't really clobber the condition codes if a different register
  1666. ;; is being set.  To keep things simple, assume during rtl manipulations that
  1667. ;; it does, but tell the final scan operator the truth.  Similarly for
  1668. ;; (neg (abs...))
  1669.  
  1670. (define_insn "abssi2"
  1671.   [(set (match_operand:SI 0 "s_register_operand" "=r,&r")
  1672.     (abs:SI (match_operand:SI 1 "s_register_operand" "0,r")))
  1673.    (clobber (reg 24))]
  1674.   ""
  1675.   "*
  1676.   switch (which_alternative)
  1677.     {
  1678.     case 0:
  1679.       arm_output_asm_insn (\"cmp\\t%0, #0\", operands);
  1680.       return arm_output_asm_insn (\"rsblt\\t%0, %0, #0\", operands);
  1681.     case 1:
  1682.       arm_output_asm_insn (\"eor\\t%0, %1, %1, asr #31\", operands);
  1683.       return arm_output_asm_insn (\"sub\\t%0, %0, %1, asr #31\", operands);
  1684.     }
  1685. "
  1686. [(set_attr "conds" "clob,*")
  1687.  (set_attr "length" "2")])
  1688.  
  1689. (define_insn ""
  1690.   [(set (match_operand:SI 0 "s_register_operand" "=r,&r")
  1691.     (neg:SI (abs:SI (match_operand:SI 1 "s_register_operand" "0,r"))))
  1692.    (clobber (reg 24))]
  1693.   ""
  1694.   "*
  1695.   switch (which_alternative)
  1696.     {
  1697.     case 0:
  1698.       arm_output_asm_insn (\"cmp\\t%0, #0\", operands);
  1699.       return arm_output_asm_insn (\"rsbgt\\t%0, %0, #0\", operands);
  1700.     case 1:
  1701.       arm_output_asm_insn (\"eor\\t%0, %1, %1, asr #31\", operands);
  1702.       return arm_output_asm_insn (\"rsb\\t%0, %0, %1, asr #31\", operands);
  1703.     }
  1704. "
  1705. [(set_attr "conds" "clob,*")
  1706.  (set_attr "length" "2")])
  1707.  
  1708. (define_insn "abssf2"
  1709.   [(set (match_operand:SF 0 "s_register_operand" "=f")
  1710.      (abs:SF (match_operand:SF 1 "s_register_operand" "f")))]
  1711.   ""
  1712.   "*
  1713.   return (arm_output_asm_insn (\"abss\\t%0, %1\", operands));
  1714. "
  1715. [(set_attr "type" "float")])
  1716.  
  1717. (define_insn "absdf2"
  1718.   [(set (match_operand:DF 0 "s_register_operand" "=f")
  1719.     (abs:DF (match_operand:DF 1 "s_register_operand" "f")))]
  1720.   ""
  1721.   "*
  1722.   return (arm_output_asm_insn (\"absd\\t%0, %1\", operands));
  1723. "
  1724. [(set_attr "type" "float")])
  1725.  
  1726. (define_insn ""
  1727.   [(set (match_operand:DF 0 "s_register_operand" "=f")
  1728.     (abs:DF (float_extend:DF
  1729.          (match_operand:SF 1 "s_register_operand" "f"))))]
  1730.   ""
  1731.   "*
  1732.   return (arm_output_asm_insn (\"absd\\t%0, %1\", operands));
  1733. "
  1734. [(set_attr "type" "float")])
  1735.  
  1736. (define_insn "absxf2"
  1737.   [(set (match_operand:XF 0 "s_register_operand" "=f")
  1738.     (abs:XF (match_operand:XF 1 "s_register_operand" "f")))]
  1739.   "ENABLE_XF_PATTERNS"
  1740.   "*
  1741.   return (arm_output_asm_insn (\"abse\\t%0, %1\", operands));
  1742. "
  1743. [(set_attr "type" "float")])
  1744.  
  1745. (define_insn "sqrtsf2"
  1746.   [(set (match_operand:SF 0 "s_register_operand" "=f")
  1747.     (sqrt:SF (match_operand:SF 1 "s_register_operand" "f")))]
  1748.   ""
  1749.   "*
  1750.   return (arm_output_asm_insn (\"sqts\\t%0, %1\", operands));
  1751. "
  1752. [(set_attr "type" "float_em")])
  1753.  
  1754. (define_insn "sqrtdf2"
  1755.   [(set (match_operand:DF 0 "s_register_operand" "=f")
  1756.     (sqrt:DF (match_operand:DF 1 "s_register_operand" "f")))]
  1757.   ""
  1758.   "*
  1759.   return (arm_output_asm_insn (\"sqtd\\t%0, %1\", operands));
  1760. "
  1761. [(set_attr "type" "float_em")])
  1762.  
  1763. (define_insn ""
  1764.   [(set (match_operand:DF 0 "s_register_operand" "=f")
  1765.     (sqrt:DF (float_extend:DF
  1766.           (match_operand:SF 1 "s_register_operand" "f"))))]
  1767.   ""
  1768.   "*
  1769.   return (arm_output_asm_insn (\"sqtd\\t%0, %1\", operands));
  1770. "
  1771. [(set_attr "type" "float_em")])
  1772.  
  1773. (define_insn "sqrtxf2"
  1774.   [(set (match_operand:XF 0 "s_register_operand" "=f")
  1775.     (sqrt:XF (match_operand:XF 1 "s_register_operand" "f")))]
  1776.   "ENABLE_XF_PATTERNS"
  1777.   "*
  1778.   return (arm_output_asm_insn (\"sqte\\t%0, %1\", operands));
  1779. "
  1780. [(set_attr "type" "float_em")])
  1781.  
  1782. (define_insn "sinsf2"
  1783.   [(set (match_operand:SF 0 "s_register_operand" "=f")
  1784.     (unspec:SF [(match_operand:SF 1 "s_register_operand" "f")] 0))]
  1785.   ""
  1786.   "*
  1787.   return arm_output_asm_insn (\"sins\\t%0, %1\", operands);
  1788. "
  1789. [(set_attr "type" "float_em")])
  1790.  
  1791. (define_insn "sindf2"
  1792.   [(set (match_operand:DF 0 "s_register_operand" "=f")
  1793.     (unspec:DF [(match_operand:DF 1 "s_register_operand" "f")] 0))]
  1794.   ""
  1795.   "*
  1796.   return arm_output_asm_insn (\"sind\\t%0, %1\", operands);
  1797. "
  1798. [(set_attr "type" "float_em")])
  1799.  
  1800. (define_insn ""
  1801.   [(set (match_operand:DF 0 "s_register_operand" "=f")
  1802.     (unspec:DF [(float_extend:DF
  1803.              (match_operand:SF 1 "s_register_operand" "f"))] 0))]
  1804.   ""
  1805.   "*
  1806.   return arm_output_asm_insn (\"sind\\t%0, %1\", operands);
  1807. "
  1808. [(set_attr "type" "float_em")])
  1809.  
  1810. (define_insn "sinxf2"
  1811.   [(set (match_operand:XF 0 "s_register_operand" "=f")
  1812.     (unspec:XF [(match_operand:XF 1 "s_register_operand" "f")] 0))]
  1813.   "ENABLE_XF_PATTERNS"
  1814.   "*
  1815.   return arm_output_asm_insn (\"sine\\t%0, %1\", operands);
  1816. "
  1817. [(set_attr "type" "float_em")])
  1818.  
  1819. (define_insn "cossf2"
  1820.   [(set (match_operand:SF 0 "s_register_operand" "=f")
  1821.     (unspec:SF [(match_operand:SF 1 "s_register_operand" "f")] 1))]
  1822.   ""
  1823.   "*
  1824.   return arm_output_asm_insn (\"coss\\t%0, %1\", operands);
  1825. "
  1826. [(set_attr "type" "float_em")])
  1827.  
  1828. (define_insn "cosdf2"
  1829.   [(set (match_operand:DF 0 "s_register_operand" "=f")
  1830.     (unspec:DF [(match_operand:DF 1 "s_register_operand" "f")] 1))]
  1831.   ""
  1832.   "*
  1833.   return arm_output_asm_insn (\"cosd\\t%0, %1\", operands);
  1834. "
  1835. [(set_attr "type" "float_em")])
  1836.  
  1837. (define_insn ""
  1838.   [(set (match_operand:DF 0 "s_register_operand" "=f")
  1839.     (unspec:DF [(float_extend:DF
  1840.              (match_operand:SF 1 "s_register_operand" "f"))] 1))]
  1841.   ""
  1842.   "*
  1843.   return arm_output_asm_insn (\"cosd\\t%0, %1\", operands);
  1844. "
  1845. [(set_attr "type" "float_em")])
  1846.  
  1847. (define_insn "cosxf2"
  1848.   [(set (match_operand:XF 0 "s_register_operand" "=f")
  1849.     (unspec:XF [(match_operand:XF 1 "s_register_operand" "f")] 1))]
  1850.   "ENABLE_XF_PATTERNS"
  1851.   "*
  1852.   return arm_output_asm_insn (\"cose\\t%0, %1\", operands);
  1853. "
  1854. [(set_attr "type" "float_em")])
  1855.  
  1856. (define_insn "one_cmpldi2"
  1857.   [(set (match_operand:DI 0 "s_register_operand" "=&r,&r")
  1858.     (not:DI (match_operand:DI 1 "s_register_operand" "?r,0")))]
  1859.   ""
  1860.   "*
  1861.   arm_output_asm_insn (\"mvn\\t%0, %1\", operands);
  1862.   return arm_output_asm_insn (\"mvn\\t%R0, %R1\", operands);
  1863. "
  1864. [(set_attr "length" "2")])
  1865.  
  1866. (define_insn "one_cmplsi2"
  1867.   [(set (match_operand:SI 0 "s_register_operand" "=r")
  1868.     (not:SI (match_operand:SI 1 "s_register_operand" "r")))]
  1869.   ""
  1870.   "*
  1871.   return (arm_output_asm_insn (\"mvn\\t%0, %1\", operands));
  1872. ")
  1873.  
  1874. (define_insn ""
  1875.   [(set (reg:CC_NOOV 24)
  1876.     (compare:CC_NOOV (not:SI (match_operand:SI 1 "s_register_operand" "r"))
  1877.              (const_int 0)))
  1878.    (set (match_operand:SI 0 "s_register_operand" "=r")
  1879.     (not:SI (match_dup 1)))]
  1880.   ""
  1881.   "*
  1882.   return (arm_output_asm_insn (\"mvns\\t%0, %1\", operands));
  1883. "
  1884. [(set_attr "conds" "set")])
  1885.  
  1886. (define_insn ""
  1887.   [(set (reg:CC_NOOV 24)
  1888.     (compare:CC_NOOV (not:SI (match_operand:SI 1 "s_register_operand" "r"))
  1889.              (const_int 0)))
  1890.    (clobber (match_scratch:SI 0 "=r"))]
  1891.   ""
  1892.   "*
  1893.   return (arm_output_asm_insn (\"mvns\\t%0, %1\", operands));
  1894. "
  1895. [(set_attr "conds" "set")])
  1896.  
  1897. ;; Fixed <--> Floating conversion insns
  1898.  
  1899. (define_insn "floatsisf2"
  1900.   [(set (match_operand:SF 0 "s_register_operand" "=f")
  1901.     (float:SF (match_operand:SI 1 "s_register_operand" "r")))]
  1902.   ""
  1903.   "*
  1904.   return (arm_output_asm_insn (\"flts\\t%0, %1\", operands));
  1905. "
  1906. [(set_attr "type" "r_2_f")])
  1907.  
  1908. (define_insn "floatsidf2"
  1909.   [(set (match_operand:DF 0 "s_register_operand" "=f")
  1910.     (float:DF (match_operand:SI 1 "s_register_operand" "r")))]
  1911.   ""
  1912.   "*
  1913.   return (arm_output_asm_insn (\"fltd\\t%0, %1\", operands));
  1914. "
  1915. [(set_attr "type" "r_2_f")])
  1916.  
  1917. (define_insn "floatsixf2"
  1918.   [(set (match_operand:XF 0 "s_register_operand" "=f")
  1919.     (float:XF (match_operand:SI 1 "s_register_operand" "r")))]
  1920.   "ENABLE_XF_PATTERNS"
  1921.   "*
  1922.   return (arm_output_asm_insn (\"flte\\t%0, %1\", operands));
  1923. "
  1924. [(set_attr "type" "r_2_f")])
  1925.  
  1926. (define_insn "fix_truncsfsi2"
  1927.   [(set (match_operand:SI 0 "s_register_operand" "=r")
  1928.     (fix:SI (match_operand:SF 1 "s_register_operand" "f")))]
  1929.   ""
  1930.   "*
  1931.   return arm_output_asm_insn (\"fixz\\t%0, %1\", operands);
  1932. "
  1933. [(set_attr "type" "f_2_r")])
  1934.  
  1935. (define_insn "fix_truncdfsi2"
  1936.   [(set (match_operand:SI 0 "s_register_operand" "=r")
  1937.     (fix:SI (match_operand:DF 1 "s_register_operand" "f")))]
  1938.   ""
  1939.   "*
  1940.   return arm_output_asm_insn (\"fixz\\t%0, %1\", operands);
  1941. "
  1942. [(set_attr "type" "f_2_r")])
  1943.  
  1944. (define_insn "fix_truncxfsi2"
  1945.   [(set (match_operand:SI 0 "s_register_operand" "=r")
  1946.     (fix:SI (match_operand:XF 1 "s_register_operand" "f")))]
  1947.   "ENABLE_XF_PATTERNS"
  1948.   "*
  1949.   return arm_output_asm_insn (\"fixz\\t%0, %1\", operands);
  1950. "
  1951. [(set_attr "type" "f_2_r")])
  1952.  
  1953. ;; Truncation insns
  1954.  
  1955. (define_insn "truncdfsf2"
  1956.   [(set (match_operand:SF 0 "s_register_operand" "=f")
  1957.     (float_truncate:SF
  1958.      (match_operand:DF 1 "s_register_operand" "f")))]
  1959.   ""
  1960.   "*
  1961.   return (arm_output_asm_insn (\"mvfs\\t%0, %1\", operands));
  1962. "
  1963. [(set_attr "type" "float")])
  1964.  
  1965. (define_insn "truncxfsf2"
  1966.   [(set (match_operand:SF 0 "s_register_operand" "=f")
  1967.     (float_truncate:SF
  1968.      (match_operand:XF 1 "s_register_operand" "f")))]
  1969.   "ENABLE_XF_PATTERNS"
  1970.   "*
  1971.   return (arm_output_asm_insn (\"mvfs\\t%0, %1\", operands));
  1972. "
  1973. [(set_attr "type" "float")])
  1974.  
  1975. (define_insn "truncxfdf2"
  1976.   [(set (match_operand:DF 0 "s_register_operand" "=f")
  1977.     (float_truncate:DF
  1978.      (match_operand:XF 1 "s_register_operand" "f")))]
  1979.   "ENABLE_XF_PATTERNS"
  1980.   "*
  1981.   return (arm_output_asm_insn (\"mvfd\\t%0, %1\", operands));
  1982. "
  1983. [(set_attr "type" "float")])
  1984.  
  1985. ;; Zero and sign extension instructions.
  1986.  
  1987. (define_insn "zero_extendsidi2"
  1988.   [(set (match_operand:DI 0 "s_register_operand" "=r")
  1989.         (zero_extend:DI (match_operand:SI 1 "s_register_operand" "r")))]
  1990.   ""
  1991.   "*
  1992.   if (REGNO (operands[1]) != REGNO (operands[0]))
  1993.     arm_output_asm_insn (\"mov\\t%0, %1\", operands);
  1994.   return arm_output_asm_insn (\"mov\\t%R0, #0\", operands);
  1995. "
  1996. [(set_attr "length" "2")])
  1997.  
  1998. (define_insn "zero_extendqidi2"
  1999.   [(set (match_operand:DI 0 "s_register_operand" "=r,r")
  2000.     (zero_extend:DI (match_operand:QI 1 "nonimmediate_operand" "r,m")))]
  2001.   ""
  2002.   "*
  2003.   switch (which_alternative)
  2004.     {
  2005.     case 0:
  2006.       arm_output_asm_insn (\"and\\t%0, %1, #255\", operands);
  2007.       break;
  2008.     case 1:
  2009.       arm_output_asm_insn (\"ldrb\\t%0, %1\",operands);
  2010.       break;
  2011.     }
  2012.   return arm_output_asm_insn (\"mov\\t%R0, #0\", operands);
  2013. "
  2014. [(set_attr "length" "2")
  2015.  (set_attr "type" "*,load")])
  2016.  
  2017. (define_insn "extendsidi2"
  2018.   [(set (match_operand:DI 0 "s_register_operand" "=r")
  2019.         (sign_extend:DI (match_operand:SI 1 "s_register_operand" "r")))]
  2020.   ""
  2021.   "*
  2022.   if (REGNO (operands[1]) != REGNO (operands[0]))
  2023.     arm_output_asm_insn (\"mov\\t%0, %1\", operands);
  2024.   return arm_output_asm_insn (\"mov\\t%R0, %0, asr #31\", operands);
  2025. "
  2026. [(set_attr "length" "2")])
  2027.  
  2028. (define_expand "zero_extendhisi2"
  2029.   [(set (match_dup 2)
  2030.     (ashift:SI (match_operand:HI 1 "s_register_operand" "")
  2031.            (const_int 16)))
  2032.    (set (match_operand:SI 0 "s_register_operand" "")
  2033.     (lshiftrt:SI (match_dup 2)
  2034.              (const_int 16)))]
  2035.   ""
  2036.   "
  2037. { operands[1] = gen_lowpart (SImode, operands[1]);
  2038.   operands[2] = gen_reg_rtx (SImode); }")
  2039.  
  2040. (define_insn "zero_extendqihi2"
  2041.   [(set (match_operand:HI 0 "s_register_operand" "=r")
  2042.     (zero_extend:HI
  2043.      (match_operand:QI 1 "s_register_operand" "r")))]
  2044.   ""
  2045.   "*
  2046.   return (arm_output_asm_insn (\"and\\t%0, %1, #255\\t@ zero_extendqihi2\", operands));
  2047. ")
  2048.  
  2049. (define_insn ""
  2050.   [(set (reg:CC_NOOV 24)
  2051.     (compare:CC_NOOV (match_operand:QI 1 "s_register_operand" "r")
  2052.              (const_int 0)))
  2053.    (set (match_operand:SI 0 "s_register_operand" "=r")
  2054.     (zero_extend:HI (match_dup 1)))]
  2055.   ""
  2056.   "*
  2057.   return arm_output_asm_insn (\"ands\\t%0, %1, #255\", operands);
  2058. "
  2059. [(set_attr "conds" "set")])
  2060.  
  2061. (define_insn ""
  2062.   [(set (reg:CC_NOOV 24)
  2063.     (compare:CC_NOOV (match_operand:QI 0 "s_register_operand" "r")
  2064.              (const_int 0)))]
  2065.   ""
  2066.   "*
  2067.   return arm_output_asm_insn (\"tst\\t%0, #255\", operands);
  2068. "
  2069. [(set_attr "conds" "set")])
  2070.  
  2071. (define_insn "zero_extendqisi2"
  2072.   [(set (match_operand:SI 0 "s_register_operand" "=r,r")
  2073.     (zero_extend:SI
  2074.      (match_operand:QI 1 "nonimmediate_operand" "r,m")))]
  2075.   ""
  2076.   "*
  2077.   switch (which_alternative)
  2078.     {
  2079.     case 0:
  2080.       return (arm_output_asm_insn (\"and\\t%0, %1, #255\\t@ zero_extendqisi2\", operands));
  2081.     case 1:
  2082.       return (arm_output_asm_insn (\"ldrb\\t%0, %1\\t@ zero_extendqisi2\", operands));
  2083.     }
  2084. "
  2085. [(set_attr "type" "*,load")])
  2086.  
  2087. (define_insn ""
  2088.   [(set (reg:CC_NOOV 24)
  2089.     (compare:CC_NOOV (match_operand:QI 1 "s_register_operand" "r")
  2090.              (const_int 0)))
  2091.    (set (match_operand:SI 0 "s_register_operand" "=r")
  2092.     (zero_extend:SI (match_dup 1)))]
  2093.   ""
  2094.   "*
  2095.   return arm_output_asm_insn (\"ands\\t%0, %1, #255\", operands);
  2096. "
  2097. [(set_attr "conds" "set")])
  2098.  
  2099. (define_insn ""
  2100.   [(set (reg:CC_NOOV 24)
  2101.     (compare:CC_NOOV (match_operand:QI 1 "s_register_operand" "r")
  2102.              (const_int 0)))
  2103.    (set (match_operand:QI 0 "s_register_operand" "=r")
  2104.     (match_dup 1))]
  2105.   ""
  2106.   "*
  2107.   return arm_output_asm_insn (\"ands\\t%0, %1, #255\", operands);
  2108. "
  2109. [(set_attr "conds" "set")])
  2110.  
  2111. (define_expand "extendhisi2"
  2112.   [(set (match_dup 2)
  2113.     (ashift:SI (match_operand:HI 1 "s_register_operand" "")
  2114.            (const_int 16)))
  2115.    (set (match_operand:SI 0 "s_register_operand" "")
  2116.     (ashiftrt:SI (match_dup 2)
  2117.              (const_int 16)))]
  2118.   ""
  2119.   "
  2120. { operands[1] = gen_lowpart (SImode, operands[1]);
  2121.   operands[2] = gen_reg_rtx (SImode); }")
  2122.  
  2123. (define_expand "extendqihi2"
  2124.   [(set (match_dup 2)
  2125.     (ashift:SI (match_operand:QI 1 "s_register_operand" "")
  2126.            (const_int 24)))
  2127.    (set (match_operand:HI 0 "s_register_operand" "")
  2128.     (ashiftrt:SI (match_dup 2)
  2129.              (const_int 24)))]
  2130.   ""
  2131.   "
  2132. { operands[0] = gen_lowpart (SImode, operands[0]);
  2133.   operands[1] = gen_lowpart (SImode, operands[1]);
  2134.   operands[2] = gen_reg_rtx (SImode); }")
  2135.  
  2136. (define_expand "extendqisi2"
  2137.   [(set (match_dup 2)
  2138.     (ashift:SI (match_operand:QI 1 "s_register_operand" "")
  2139.            (const_int 24)))
  2140.    (set (match_operand:SI 0 "s_register_operand" "")
  2141.     (ashiftrt:SI (match_dup 2)
  2142.              (const_int 24)))]
  2143.   ""
  2144.   "
  2145. { operands[1] = gen_lowpart (SImode, operands[1]);
  2146.   operands[2] = gen_reg_rtx (SImode); }")
  2147.  
  2148. (define_insn "extendsfdf2"
  2149.   [(set (match_operand:DF 0 "s_register_operand" "=f")
  2150.     (float_extend:DF (match_operand:SF 1 "s_register_operand" "f")))]
  2151.   ""
  2152.   "*
  2153.   return (arm_output_asm_insn (\"mvfd\\t%0, %1\", operands));
  2154. "
  2155. [(set_attr "type" "float")])
  2156.  
  2157. (define_insn "extendsfxf2"
  2158.   [(set (match_operand:XF 0 "s_register_operand" "=f")
  2159.     (float_extend:XF (match_operand:SF 1 "s_register_operand" "f")))]
  2160.   "ENABLE_XF_PATTERNS"
  2161.   "*
  2162.   return (arm_output_asm_insn (\"mvfe\\t%0, %1\", operands));
  2163. ")
  2164.  
  2165. (define_insn "extenddfxf2"
  2166.   [(set (match_operand:XF 0 "s_register_operand" "=f")
  2167.     (float_extend:XF (match_operand:DF 1 "s_register_operand" "f")))]
  2168.   "ENABLE_XF_PATTERNS"
  2169.   "*
  2170.   return (arm_output_asm_insn (\"mvfe\\t%0, %1\", operands));
  2171. "
  2172. [(set_attr "type" "float")])
  2173.  
  2174.  
  2175. ;; Move insns (including loads and stores)
  2176.  
  2177. ;; XXX Just some ideas about movti.
  2178. ;; I don't think these are a good idea on the arm, there just aren't enough
  2179. ;; registers
  2180. ;;(define_expand "loadti"
  2181. ;;  [(set (match_operand:TI 0 "s_register_operand" "")
  2182. ;;    (mem:TI (match_operand:SI 1 "address_operand" "")))]
  2183. ;;  "" "")
  2184.  
  2185. ;;(define_expand "storeti"
  2186. ;;  [(set (mem:TI (match_operand:TI 0 "address_operand" ""))
  2187. ;;    (match_operand:TI 1 "s_register_operand" ""))]
  2188. ;;  "" "")
  2189.  
  2190. ;;(define_expand "movti"
  2191. ;;  [(set (match_operand:TI 0 "general_operand" "")
  2192. ;;    (match_operand:TI 1 "general_operand" ""))]
  2193. ;;  ""
  2194. ;;  "
  2195. ;;{
  2196. ;;  rtx insn;
  2197. ;;
  2198. ;;  if (GET_CODE (operands[0]) == MEM && GET_CODE (operands[1]) == MEM)
  2199. ;;    operands[1] = copy_to_reg (operands[1]);
  2200. ;;  if (GET_CODE (operands[0]) == MEM)
  2201. ;;    insn = gen_storeti (XEXP (operands[0], 0), operands[1]);
  2202. ;;  else if (GET_CODE (operands[1]) == MEM)
  2203. ;;    insn = gen_loadti (operands[0], XEXP (operands[1], 0));
  2204. ;;  else
  2205. ;;    FAIL;
  2206. ;;
  2207. ;;  emit_insn (insn);
  2208. ;;  DONE;
  2209. ;;}")
  2210.  
  2211. ;; Recognise garbage generated above.
  2212.  
  2213. ;;(define_insn ""
  2214. ;;  [(set (match_operand:TI 0 "general_operand" "=r,r,r,<,>,m")
  2215. ;;    (match_operand:TI 1 "general_operand" "<,>,m,r,r,r"))]
  2216. ;;  ""
  2217. ;;  "*
  2218. ;;  {
  2219. ;;    register mem = (which_alternative < 3);
  2220. ;;    register char *template;
  2221. ;;
  2222. ;;    operands[mem] = XEXP (operands[mem], 0);
  2223. ;;    switch (which_alternative)
  2224. ;;      {
  2225. ;;      case 0: template = \"ldmdb\\t%1!, %M0\"; break;
  2226. ;;      case 1: template = \"ldmia\\t%1!, %M0\"; break;
  2227. ;;      case 2: template = \"ldmia\\t%1, %M0\"; break;
  2228. ;;      case 3: template = \"stmdb\\t%0!, %M1\"; break;
  2229. ;;      case 4: template = \"stmia\\t%0!, %M1\"; break;
  2230. ;;      case 5: template = \"stmia\\t%0, %M1\"; break;
  2231. ;;      }
  2232. ;;    return (arm_output_asm_insn (template, operands));
  2233. ;;  }")
  2234.  
  2235.  
  2236. (define_insn "movdi"
  2237.   [(set (match_operand:DI 0 "di_operand" "=r,r,r,o<>,r")
  2238.     (match_operand:DI 1 "di_operand" "rK,n,o<>,r,F"))]
  2239.   ""
  2240.   "*
  2241.   return (output_move_double (operands));
  2242. "
  2243. [(set_attr "length" "2,8,2,2,8")
  2244.  (set_attr "type" "*,*,load,store2,*")])
  2245.  
  2246. (define_expand "movsi"
  2247.   [(set (match_operand:SI 0 "general_operand" "")
  2248.         (match_operand:SI 1 "general_operand" ""))]
  2249.   ""
  2250.   "
  2251.   /* Everything except mem = const or mem = mem can be done easily */
  2252.   if (GET_CODE (operands[0]) == MEM)
  2253.     operands[1] = force_reg (SImode, operands[1]);
  2254.   if (GET_CODE (operands[1]) == CONST_INT
  2255.       && !(const_ok_for_arm (INTVAL (operands[1]))
  2256.            || const_ok_for_arm (~INTVAL (operands[1]))))
  2257.     {
  2258.       int n = INTVAL (operands[1]);
  2259.       rtx tmpreg, tmpreg2;
  2260.       int i, n_ones = 0, first = 1, last = 0;
  2261.  
  2262.       if (GET_CODE (operands[0]) != REG
  2263.           && GET_CODE (operands[0]) != SUBREG)
  2264.         abort ();
  2265.       for (i = 0; i < 32; i++)
  2266.         if (n & 1 << i)
  2267.           n_ones++;
  2268.       /* These loops go the opposite way around to those in arm.c so that
  2269.          the last constant may be more likely to be eliminted into the
  2270.          next instruction */
  2271.  
  2272.       if (n_ones > 16)
  2273.         {
  2274.           n = (~n) & 0xffffffff;
  2275.           for (i = 30; i >= 0; i -= 2)
  2276.             {
  2277.               if (n & (3 << i))
  2278.                 {
  2279.                   i -= 6;
  2280.                   if (i < 0)
  2281.                     i = 0;
  2282.                   if ((n & (255 << i)) == n)
  2283.                     last = 1;
  2284.                   if (first)
  2285.                     {
  2286.                       rtx equal;
  2287.                       rtx insn =
  2288.                         emit_insn (gen_movsi (tmpreg = (reload_in_progress
  2289.                                                         || reload_completed)
  2290.                                                       ? operands[0]
  2291.                                                       : gen_reg_rtx (SImode),
  2292.                                       equal = gen_rtx (CONST_INT, VOIDmode,
  2293.                                                        ~(n & (255 << i)))));
  2294.                       first = 0;
  2295.                     }
  2296.                   else
  2297.                     {
  2298.                       rtx constant;
  2299.                       rtx insn =
  2300.                         emit_insn (gen_subsi3 (tmpreg2 = (reload_in_progress
  2301.                                                           || reload_completed
  2302.                                                           || last)
  2303.                                                         ? operands[0]
  2304.                                                         : gen_reg_rtx (SImode),
  2305.                                                tmpreg,
  2306.                                     constant = gen_rtx (CONST_INT, VOIDmode,
  2307.                                                         n & (255 << i))));
  2308.                       tmpreg = tmpreg2;
  2309.                     }
  2310.                   n &= ~(255 << i);
  2311.                 }
  2312.             }
  2313.         }
  2314.       else
  2315.         {
  2316.           for (i = 30; i >= 0; i -= 2)
  2317.             {
  2318.               if (n & (3 << i))
  2319.                 {
  2320.                   i -= 6;
  2321.                   if (i < 0)
  2322.                     i = 0;
  2323.                   if ((n & (255 << i)) == n)
  2324.                     last = 1;
  2325.                   if (first)
  2326.                     {
  2327.                       rtx equal;
  2328.                       rtx insn =
  2329.                         emit_insn (gen_movsi (tmpreg = (reload_in_progress
  2330.                                                         || reload_completed)
  2331.                                                       ? operands[0]
  2332.                                                       : gen_reg_rtx (SImode),
  2333.                                       equal = gen_rtx (CONST_INT, VOIDmode,
  2334.                                                        n & (255 << i))));
  2335.                       first = 0;
  2336.                     }
  2337.                   else
  2338.                     {
  2339.                       rtx constant;
  2340.                       rtx insn =
  2341.                         emit_insn (gen_addsi3 (tmpreg2 = (reload_in_progress
  2342.                                                           || reload_completed
  2343.                                                           || last)
  2344.                                                         ? operands[0]
  2345.                                                         : gen_reg_rtx (SImode),
  2346.                                                tmpreg,
  2347.                                     constant = gen_rtx (CONST_INT, VOIDmode,
  2348.                                                         n & (255 << i))));
  2349.                       tmpreg = tmpreg2;
  2350.                     }
  2351.                   n &= ~(255 << i);
  2352.                 }
  2353.             }
  2354.         }
  2355.       DONE;
  2356.     }
  2357. ")
  2358.  
  2359. (define_insn ""
  2360.   [(set (match_operand:SI 0 "general_operand" "=r,r,r,m,r")
  2361.     (match_operand:SI 1 "general_operand"  "m,K,r,r,S"))]
  2362.   "(register_operand (operands[0], SImode)
  2363.     && (GET_CODE (operands[1]) != CONST_INT
  2364.         || const_ok_for_arm (INTVAL (operands[1]))
  2365.         || const_ok_for_arm (~INTVAL (operands[1])))
  2366.     && (GET_CODE (operands[1]) != SYMBOL_REF
  2367.     || CONSTANT_ADDRESS_P (operands[1])))
  2368.    || register_operand (operands[1], SImode)"
  2369.   "*
  2370.   switch (which_alternative)
  2371.     {
  2372.     case 2:
  2373.       return (arm_output_asm_insn (\"mov\\t%0, %1\", operands));
  2374.     case 1:
  2375.       if (!const_ok_for_arm (INTVAL (operands[1])))
  2376.     {
  2377.       operands[1] = gen_rtx (CONST_INT, VOIDmode, ~INTVAL (operands[1]));
  2378.       return arm_output_asm_insn (\"mvn\\t%0, %1\", operands);
  2379.     }
  2380.       return arm_output_asm_insn (\"mov\\t%0, %1\", operands);
  2381.     case 0:
  2382.       if (GET_CODE (XEXP (operands[1], 0)) == SYMBOL_REF
  2383.       &&  CONSTANT_POOL_ADDRESS_P (XEXP (operands[1], 0)))
  2384.     return (arm_output_llc (operands));
  2385.       else
  2386.     return (arm_output_asm_insn (\"ldr\\t%0, %1\", operands));
  2387.     case 3:
  2388.       return (arm_output_asm_insn (\"str\\t%1, %0\", operands));
  2389.     case 4:
  2390.       return output_load_symbol (operands);
  2391.     }
  2392. "
  2393. [(set_attr "length" "2,*,*,*,4")
  2394.  (set_attr "type" "load,*,*,store1,*")])
  2395.  
  2396. ;; If copying one reg to another we can set the condition codes according to
  2397. ;; its value.  Such a move is common after a return from subroutine and the
  2398. ;; result is being tested against zero.
  2399.  
  2400. (define_insn ""
  2401.   [(set (reg:CC 24) (compare (match_operand:SI 1 "s_register_operand" "r")
  2402.                  (const_int 0)))
  2403.    (set (match_operand:SI 0 "s_register_operand" "=r") (match_dup 1))]
  2404.   ""
  2405.   "*
  2406.   if (GET_CODE (operands[0]) == REG && GET_CODE (operands[1]) == REG
  2407.       && REGNO (operands[0]) == REGNO (operands[1]))
  2408.     return arm_output_asm_insn (\"cmp\\t%0, #0\", operands);
  2409.   return arm_output_asm_insn (\"subs\\t%0, %1, #0\", operands);
  2410. "
  2411. [(set_attr "conds" "set")])
  2412.  
  2413. ;; Subroutine to store a half word from a register into memory.
  2414. ;; Operand 0 is the source register (HImode)
  2415. ;; Operand 1 is the destination address in a register (SImode)
  2416.  
  2417. ;; In both this routine and the next, we must be careful not to spill
  2418. ;; a memory address of reg+large_const into a seperate PLUS insn, since this
  2419. ;; can generate unrecognizable rtl.
  2420.  
  2421. (define_expand "storehi"
  2422.   [;; store the low byte
  2423.    (set (mem:QI (match_operand:SI 1 "" "")) (match_dup 3))
  2424.    ;; extract the high byte
  2425.    (set (match_dup 2)
  2426.     (ashiftrt:SI (match_operand 0 "" "") (const_int 8)))
  2427.    ;; store the high byte
  2428.    (set (mem:QI (match_dup 4))
  2429.     (subreg:QI (match_dup 2) 0))]    ;explicit subreg safe
  2430.   ""
  2431.   "
  2432. {
  2433.   enum rtx_code code = GET_CODE (operands[1]);
  2434.  
  2435.   if ((code == PLUS || code == MINUS)
  2436.       && (GET_CODE (XEXP (operands[1], 1)) == REG
  2437.       || GET_CODE (XEXP (operands[1], 0)) != REG))
  2438.     operands[1] = force_reg (SImode, operands[1]);
  2439.   operands[4] = plus_constant (operands[1], 1);
  2440.   operands[3] = gen_lowpart (QImode, operands[0]);
  2441.   operands[0] = gen_lowpart (SImode, operands[0]);
  2442.   operands[2] = gen_reg_rtx (SImode); 
  2443. }
  2444. ")
  2445.  
  2446. ;; Subroutine to store a half word integer constant into memory.
  2447. ;; Operand 0 is the constant
  2448. ;; Operand 1 is the destination address in a register (SImode)
  2449.  
  2450. (define_expand "storeinthi"
  2451.   [;; store the low byte
  2452.    (set (mem:QI (match_operand:SI 1 "" "")) (match_operand 0 "" ""))
  2453.    ;; store the high byte
  2454.    (set (mem:QI (match_dup 3)) (match_dup 2))]
  2455.   ""
  2456.   "
  2457. {
  2458.   int value = INTVAL (operands[0]);
  2459.   enum rtx_code code = GET_CODE (operands[1]);
  2460.  
  2461.   if ((code == PLUS || code == MINUS)
  2462.       && (GET_CODE (XEXP (operands[1], 1)) == REG
  2463.       || GET_CODE (XEXP (operands[1], 0)) != REG))
  2464.   operands[1] = force_reg (SImode, operands[1]);
  2465.  
  2466.   operands[0] = force_reg (QImode, gen_rtx (CONST_INT, VOIDmode, value & 255));
  2467.   operands[2] = force_reg (QImode,
  2468.                gen_rtx (CONST_INT, VOIDmode,(value>>8) & 255));
  2469.   operands[3] = plus_constant (operands[1], 1);
  2470. }
  2471. ")
  2472.  
  2473. (define_expand "movhi"
  2474.   [(set (match_operand:HI 0 "general_operand" "")
  2475.     (match_operand:HI 1 "general_operand" ""))]
  2476.   ""
  2477.   "
  2478. {
  2479.   rtx insn;
  2480.  
  2481.   if (reload_in_progress || reload_completed)
  2482.     insn = gen_rtx (SET, VOIDmode, operands[0], operands[1]);
  2483.   else
  2484.     {
  2485.       if (GET_CODE (operands[0]) == MEM)
  2486.     {
  2487.       if (GET_CODE (operands[1]) == CONST_INT)
  2488.         {
  2489.           insn = gen_storeinthi (operands[1], XEXP (operands[0],0));
  2490.         }
  2491.       else
  2492.         {
  2493.           if (GET_CODE (operands[1]) == MEM)
  2494.         operands[1] = force_reg (HImode, operands[1]);
  2495.           insn = gen_storehi (operands[1], XEXP (operands[0], 0));
  2496.         }
  2497.     }
  2498.       else if (GET_CODE (operands[1]) == CONST_INT
  2499.            && !(const_ok_for_arm (INTVAL (operands[1]))
  2500.            || const_ok_for_arm (~INTVAL (operands[1]))))
  2501.     {
  2502.       rtx reg, reg2;
  2503.  
  2504.       /* no need to be clever, this will always take two insns.
  2505.          The top sixteen bits should be all zeros or all ones. */
  2506.       if (INTVAL (operands[1]) < 0)
  2507.         {
  2508.           emit_insn (gen_movsi (reg = gen_reg_rtx (SImode),
  2509.                     GEN_INT (INTVAL (operands[1])
  2510.                          | ~(0x0ff00))));
  2511.           emit_insn (gen_addsi3 (reg2 = gen_reg_rtx (SImode), reg,
  2512.                      GEN_INT (-((~INTVAL (operands[1]))
  2513.                             & 0xff))));
  2514.         }
  2515.       else
  2516.         {
  2517.           emit_insn (gen_movsi (reg = gen_reg_rtx (SImode),
  2518.                     GEN_INT (INTVAL (operands[1]) & 0xff00)));
  2519.           emit_insn (gen_addsi3 (reg2 = gen_reg_rtx (SImode), reg,
  2520.                      GEN_INT (INTVAL (operands[1]) & 0x00ff)));
  2521.         }
  2522.       insn = gen_rtx (SET, HImode, operands[0],
  2523.               gen_rtx (SUBREG, HImode, reg2, 0));
  2524.     }
  2525.       else
  2526.     insn = gen_rtx (SET, VOIDmode, operands[0], operands[1]);
  2527.     }
  2528.  
  2529.   emit_insn (insn);
  2530.   DONE;
  2531. }")
  2532.  
  2533. ;; Pattern to recognise insn generated default case above
  2534.  
  2535. (define_insn ""
  2536.   [(set (match_operand:HI 0 "general_operand" "=r,r,r,m")
  2537.     (match_operand:HI 1 "general_operand"  "r,K,m,r"))]
  2538.   "(register_operand (operands[0], HImode)
  2539.     && (GET_CODE (operands[1]) != CONST_INT
  2540.     || const_ok_for_arm (INTVAL (operands[1]))
  2541.     || const_ok_for_arm (~INTVAL (operands[1]))))
  2542.    || register_operand (operands[1], HImode)"
  2543.   "*
  2544.   switch (which_alternative)
  2545.     {
  2546.       case 1:
  2547.     if (!const_ok_for_arm (INTVAL (operands[1])))
  2548.       {
  2549.         operands[1] = GEN_INT (~INTVAL (operands[1]));
  2550.         return arm_output_asm_insn (\"mvn\\t%0, %1\", operands);
  2551.       }
  2552.     /* fall through */
  2553.       case 0:
  2554.     return arm_output_asm_insn (\"mov\\t%0, %1\\t@movhi\", operands);
  2555.       case 2:
  2556.     return arm_output_asm_insn (\"ldr\\t%0, %1\\t@movhi\", operands);
  2557.       case 3:
  2558.     return arm_output_asm_insn (\"str\\t%1, %0\\t@movhi\", operands);
  2559.     }
  2560. "
  2561. [(set_attr "type" "*,*,load,store1")])
  2562.  
  2563. (define_expand "reload_outhi"
  2564.   [(parallel [(match_operand:HI 0 "reload_memory_operand" "=o")
  2565.           (match_operand:HI 1 "s_register_operand" "r")
  2566.           (match_operand:SI 2 "s_register_operand" "=&r")])]
  2567.   ""
  2568.   "
  2569.   arm_reload_out_hi (operands);
  2570.   DONE;
  2571. ")
  2572.  
  2573. (define_expand "movqi"
  2574.   [(set (match_operand:QI 0 "general_operand" "")
  2575.         (match_operand:QI 1 "general_operand" ""))]
  2576.   ""
  2577.   "
  2578.   /* Everything except mem = const or mem = mem can be done easily */
  2579.  
  2580.   if (!(reload_in_progress || reload_completed))
  2581.     {
  2582.       rtx reg;
  2583.       if (GET_CODE (operands[1]) == CONST_INT)
  2584.     {
  2585.       emit_insn (gen_movsi (reg = gen_reg_rtx (SImode), operands[1]));
  2586.       operands[1] = gen_rtx (SUBREG, QImode, reg, 0);
  2587.     }
  2588.     }
  2589.   if (GET_CODE (operands[0]) == MEM)
  2590.     operands[1] = force_reg (QImode, operands[1]);
  2591. ")
  2592.  
  2593.  
  2594. (define_insn ""
  2595.   [(set (match_operand:QI 0 "general_operand" "=r,r,r,m")
  2596.     (match_operand:QI 1 "general_operand" "r,K,m,r"))]
  2597.   "register_operand (operands[0], QImode)
  2598.    || register_operand (operands[1], QImode)"
  2599.   "*
  2600.   switch (which_alternative)
  2601.     {
  2602.     case 1:
  2603.       if (INTVAL (operands[1]) < 0)
  2604.     {
  2605.       operands[1] = GEN_INT (~INTVAL (operands[1]));
  2606.       return arm_output_asm_insn (\"mvn\\t%0, %1\", operands);
  2607.     }
  2608.     case 0:
  2609.       return (arm_output_asm_insn (\"mov\\t%0, %1\", operands));
  2610.     case 2:
  2611.       return (arm_output_asm_insn (\"ldrb\\t%0, %1\", operands));
  2612.     case 3:
  2613.       return (arm_output_asm_insn (\"strb\\t%1, %0\", operands));
  2614.     }
  2615. "
  2616. [(set_attr "type" "*,*,load,store1")])
  2617.  
  2618. (define_insn "movsf"
  2619.   [(set (match_operand:SF 0 "general_operand" "=f,f,f,m,f,r,r,r,m")
  2620.     (match_operand:SF 1 "general_operand" "fG,H,m,f,r,f,r,m,r"))]
  2621.   ""
  2622.   "*
  2623. {
  2624.   REAL_VALUE_TYPE r;
  2625.  
  2626.   switch (which_alternative)
  2627.     {
  2628.     case 0:
  2629.       return arm_output_asm_insn (\"mvfs\\t%0, %1\", operands);
  2630.     case 1:
  2631.       REAL_VALUE_FROM_CONST_DOUBLE (r, operands[1]);
  2632.       r = REAL_VALUE_NEGATE (r);
  2633.       operands[1] = CONST_DOUBLE_FROM_REAL_VALUE (r, GET_MODE (operands[1]));
  2634.       return arm_output_asm_insn (\"mnfs\\t%0, %1\", operands);
  2635.     case 2:
  2636.       return arm_output_asm_insn (\"ldfs\\t%0, %1\", operands);
  2637.     case 3:
  2638.       return arm_output_asm_insn (\"stfs\\t%1, %0\", operands);
  2639.     case 4:
  2640.       arm_output_asm_insn(\"stmfd\\tsp!, {%1}\", operands);
  2641.       return arm_output_asm_insn (\"ldfs\\t%0, [sp],#4\", operands);
  2642.     case 5:
  2643.       arm_output_asm_insn(\"stfs\\t%1, [sp,#-4]!\", operands);
  2644.       return arm_output_asm_insn (\"ldmfd\\tsp!, {%0}\", operands);
  2645.     case 6:
  2646.       return arm_output_asm_insn (\"mov\\t%0, %1\", operands);
  2647.     case 7:
  2648.       return arm_output_asm_insn (\"ldr\\t%0, %1\\t@ float\", operands);
  2649.     case 8:
  2650.       return arm_output_asm_insn (\"str\\t%1, %0\\t@ float\", operands);
  2651.   }
  2652. }
  2653. "
  2654. [(set_attr "length" "1,1,1,1,2,2,1,1,1")
  2655.  (set_attr "type" "float,float,f_load,f_store,r_mem_f,f_mem_r,*,load,store1")])
  2656.  
  2657. (define_expand "movdf"
  2658.   [(parallel [(set (match_operand:DF 0 "general_operand" "")
  2659.            (match_operand:DF 1 "general_operand" ""))
  2660.           (clobber (match_scratch:SI 2 ""))])]
  2661.   ""
  2662.   "
  2663.   if (GET_CODE (operands[0]) == MEM)
  2664.     operands[1] = force_reg (DFmode, operands[1]);
  2665. ")
  2666.  
  2667. ;; Reloading a df mode value stored in integer regs to memory can require a
  2668. ;; scratch reg.
  2669. (define_expand "reload_outdf"
  2670.   [(parallel [(set (match_operand:DF 0 "reload_memory_operand" "=o")
  2671.            (match_operand:DF 1 "s_register_operand" "r"))
  2672.           (clobber (match_operand:SI 2 "s_register_operand" "=&r"))])]
  2673.   ""
  2674.   "")
  2675.  
  2676. (define_insn ""
  2677.   [(set (match_operand:DF 0 "general_operand" "=r,Q,r,o,f,f,f,f,m,!f,!r,r")
  2678.     (match_operand:DF 1 "general_operand" 
  2679.          "Q,r,?o,?r,?f,!G,!H,m,f,r,f,??r"))
  2680.    (clobber (match_scratch:SI 2 "=X,X,X,&r,X,X,X,X,X,X,X,X"))]
  2681.   "GET_CODE (operands[0]) != MEM || register_operand (operands[1], DFmode)"
  2682.   "*
  2683. {
  2684.   REAL_VALUE_TYPE r;
  2685.   rtx ops[3];
  2686.  
  2687.   switch (which_alternative)
  2688.     {
  2689.     case 0:
  2690.       operands[1] = XEXP (operands[1], 0);
  2691.       return arm_output_asm_insn (\"ldmia\\t%1, {%0, %R0}\\t@ double\",
  2692.                   operands);
  2693.     case 1:
  2694.       operands[0] = XEXP (operands[0], 0);
  2695.       return arm_output_asm_insn (\"stmia\\t%0, {%1, %R1}\\t@ double\",
  2696.                   operands);
  2697.     case 2:
  2698.       ops[0] = operands[0];
  2699.       ops[1] = XEXP (XEXP (operands[1], 0), 0);
  2700.       ops[2] = XEXP (XEXP (operands[1], 0), 1);
  2701.       if (!INTVAL (ops[2]) || const_ok_for_arm (INTVAL (ops[2])))
  2702.     arm_output_asm_insn (\"add\\t%0, %1, %2\", ops);
  2703.       else
  2704.     arm_output_asm_insn (\"sub\\t%0, %1, #%n2\", ops);
  2705.       return arm_output_asm_insn (\"ldmia\\t%0, {%0, %R0}\\t@ double\",
  2706.                   operands);
  2707.     case 3:
  2708.  
  2709.       ops[0] = operands[2];
  2710.       ops[1] = XEXP (XEXP (operands[0], 0), 0);
  2711.       ops[2] = XEXP (XEXP (operands[0], 0), 1);
  2712.       if (!INTVAL (ops[2]) || const_ok_for_arm (INTVAL (ops[2])))
  2713.     arm_output_asm_insn (\"add\\t%0, %1, %2\", ops);
  2714.       else
  2715.     arm_output_asm_insn (\"sub\\t%0, %1, #%n2\", ops);
  2716.       return arm_output_asm_insn (\"stmia\\t%2, {%1, %R1}\\t@ double\",
  2717.                   operands);
  2718.     case 4:
  2719.     case 5:
  2720.       return arm_output_asm_insn (\"mvfd\\t%0, %1\", operands);
  2721.     case 6:
  2722.       REAL_VALUE_FROM_CONST_DOUBLE (r, operands[1]);
  2723.       r = REAL_VALUE_NEGATE (r);
  2724.       operands[1] = CONST_DOUBLE_FROM_REAL_VALUE (r, GET_MODE (operands[1]));
  2725.       return arm_output_asm_insn (\"mnfd\\t%0, %1\", operands);
  2726.     case 7: return arm_output_asm_insn (\"ldfd\\t%0, %1\", operands);
  2727.     case 8: return arm_output_asm_insn (\"stfd\\t%1, %0\", operands);
  2728.     case 9: return output_mov_double_fpu_from_arm (operands);
  2729.     case 10: return output_mov_double_arm_from_fpu (operands);
  2730.     case 11: return output_move_double (operands);
  2731.     }
  2732. }
  2733. "
  2734. [(set_attr "length" "1,1,2,2,1,1,1,1,1,2,2,2")
  2735.  (set_attr "type" 
  2736. "load,store2,load,store2,float,float,float,f_load,f_store,r_mem_f,f_mem_r,*")])
  2737.  
  2738. (define_insn "movxf"
  2739.   [(set (match_operand:XF 0 "general_operand" "=f,f,f,m,f,r,r")
  2740.     (match_operand:XF 1 "general_operand" "fG,H,m,f,r,f,r"))]
  2741.   "ENABLE_XF_PATTERNS"
  2742.   "*
  2743. {
  2744.   REAL_VALUE_TYPE r;
  2745.  
  2746.   switch (which_alternative)
  2747.     {
  2748.     case 0: return arm_output_asm_insn (\"mvfe\\t%0, %1\", operands);
  2749.     case 1:
  2750.       REAL_VALUE_FROM_CONST_DOUBLE (r, operands[1]);
  2751.       r = REAL_VALUE_NEGATE (r);
  2752.       operands[1] = CONST_DOUBLE_FROM_REAL_VALUE (r, GET_MODE (operands[1]));
  2753.       return arm_output_asm_insn (\"mnfe\\t%0, %1\", operands);
  2754.     case 2: return arm_output_asm_insn (\"ldfe\\t%0, %1\", operands);
  2755.     case 3: return arm_output_asm_insn (\"stfe\\t%1, %0\", operands);
  2756.     case 4: return output_mov_long_double_fpu_from_arm (operands);
  2757.     case 5: return output_mov_long_double_arm_from_fpu (operands);
  2758.     case 6: return output_mov_long_double_arm_from_arm (operands);
  2759.     }
  2760. }
  2761. "
  2762. [(set_attr "length" "1,1,1,1,2,2,3")
  2763.  (set_attr "type" "float,float,f_load,f_store,r_mem_f,f_mem_r,*")])
  2764.  
  2765.  
  2766. ;; load- and store-multiple insns
  2767. ;; The arm can load/store any set of registers, provided that they are in
  2768. ;; ascending order; but that is beyond GCC so stick with what it knows.
  2769.  
  2770. (define_expand "load_multiple"
  2771.   [(match_par_dup 3 [(set (match_operand:SI 0 "" "")
  2772.                           (match_operand:SI 1 "" ""))
  2773.                      (use (match_operand:SI 2 "" ""))])]
  2774.   ""
  2775.   "
  2776.   /* Support only fixed point registers */
  2777.   if (GET_CODE (operands[2]) != CONST_INT
  2778.       || INTVAL (operands[2]) > 14
  2779.       || INTVAL (operands[2]) < 2
  2780.       || GET_CODE (operands[1]) != MEM
  2781.       || GET_CODE (operands[0]) != REG
  2782.       || REGNO (operands[0]) > 14
  2783.       || REGNO (operands[0]) + INTVAL (operands[2]) > 15)
  2784.     FAIL;
  2785.  
  2786.   operands[3]
  2787.             = arm_gen_load_multiple (REGNO (operands[0]), INTVAL (operands[2]),
  2788.                                      force_reg (SImode, XEXP (operands[1], 0)),
  2789.                                      TRUE, FALSE);
  2790. ")
  2791.  
  2792. ;; Load multiple with write-back
  2793.  
  2794. (define_insn ""
  2795.   [(match_parallel 0 "load_multiple_operation"
  2796.                    [(set (match_operand:SI 1 "s_register_operand" "+r")
  2797.                          (plus:SI (match_dup 1)
  2798.                                   (match_operand:SI 2 "immediate_operand" "n")))
  2799.                     (set (match_operand:SI 3 "s_register_operand" "=r")
  2800.                          (mem:SI (match_dup 1)))])]
  2801.   "(INTVAL (operands[2])  == 4 * (XVECLEN (operands[0], 0) - 2))"
  2802.   "*
  2803. {
  2804.   rtx ops[3];
  2805.   int count = XVECLEN (operands[0], 0);
  2806.  
  2807.   ops[0] = XEXP (SET_SRC (XVECEXP (operands[0], 0, 0)), 0);
  2808.   ops[1] = SET_DEST (XVECEXP (operands[0], 0, 1));
  2809.   ops[2] = SET_DEST (XVECEXP (operands[0], 0, count - 2));
  2810.  
  2811.   return arm_output_asm_insn (\"ldmia\\t%0!, {%1-%2}\\t@ load multiple\", ops);
  2812. }
  2813. "
  2814. [(set_attr "type" "load")])
  2815.  
  2816. ;; Ordinary load multiple
  2817.  
  2818. (define_insn ""
  2819.   [(match_parallel 0 "load_multiple_operation"
  2820.                    [(set (match_operand:SI 1 "s_register_operand" "=r")
  2821.                          (match_operand:SI 2 "indirect_operand" "Q"))])]
  2822.   ""
  2823.   "*
  2824. {
  2825.   rtx ops[3];
  2826.   int count = XVECLEN (operands[0], 0);
  2827.  
  2828.   ops[0] = XEXP (SET_SRC (XVECEXP (operands[0], 0, 0)), 0);
  2829.   ops[1] = SET_DEST (XVECEXP (operands[0], 0, 0));
  2830.   ops[2] = SET_DEST (XVECEXP (operands[0], 0, count - 1));
  2831.  
  2832.   return arm_output_asm_insn (\"ldmia\\t%0, {%1-%2}\\t@ load multiple\", ops);
  2833. }
  2834. "
  2835. [(set_attr "type" "load")])
  2836.  
  2837. (define_expand "store_multiple"
  2838.   [(match_par_dup 3 [(set (match_operand:SI 0 "" "")
  2839.                           (match_operand:SI 1 "" ""))
  2840.                      (use (match_operand:SI 2 "" ""))])]
  2841.   ""
  2842.   "
  2843.   /* Support only fixed point registers */
  2844.   if (GET_CODE (operands[2]) != CONST_INT
  2845.       || INTVAL (operands[2]) > 14
  2846.       || INTVAL (operands[2]) < 2
  2847.       || GET_CODE (operands[1]) != REG
  2848.       || GET_CODE (operands[0]) != MEM
  2849.       || REGNO (operands[1]) > 14
  2850.       || REGNO (operands[1]) + INTVAL (operands[2]) > 15)
  2851.     FAIL;
  2852.  
  2853.   operands[3]
  2854.            = arm_gen_store_multiple (REGNO (operands[1]), INTVAL (operands[2]),
  2855.                                      force_reg (SImode, XEXP (operands[0], 0)),
  2856.                                      TRUE, FALSE);
  2857. ")
  2858.  
  2859. ;; Store multiple with write-back
  2860.  
  2861. (define_insn ""
  2862.   [(match_parallel 0 "store_multiple_operation"
  2863.                    [(set (match_operand:SI 1 "s_register_operand" "+r")
  2864.                          (plus:SI (match_dup 1)
  2865.                                   (match_operand:SI 2 "immediate_operand" "n")))
  2866.                     (set (mem:SI (match_dup 1))
  2867.                          (match_operand:SI 3 "s_register_operand" "r"))])]
  2868.   "(INTVAL (operands[2]) == 4 * (XVECLEN (operands[0], 0) - 2))"
  2869.   "*
  2870. {
  2871.   rtx ops[3];
  2872.   int count = XVECLEN (operands[0], 0);
  2873.  
  2874.   ops[0] = XEXP (SET_SRC (XVECEXP (operands[0], 0, 0)), 0);
  2875.   ops[1] = SET_SRC (XVECEXP (operands[0], 0, 1));
  2876.   ops[2] = SET_SRC (XVECEXP (operands[0], 0, count - 2));
  2877.  
  2878.   return arm_output_asm_insn (\"stmia\\t%0!, {%1-%2}\\t@ str multiple\", ops);
  2879. }
  2880. "
  2881. [(set (attr "type")
  2882.       (cond [(eq (symbol_ref "XVECLEN (operands[0],0)") (const_int 4))
  2883.         (const_string "store2")
  2884.          (eq (symbol_ref "XVECLEN (operands[0],0)") (const_int 5))
  2885.         (const_string "store3")]
  2886.       (const_string "store4")))])
  2887.  
  2888. ;; Ordinary store multiple
  2889.  
  2890. (define_insn ""
  2891.   [(match_parallel 0 "store_multiple_operation"
  2892.                    [(set (match_operand:SI 2 "indirect_operand" "=Q")
  2893.                          (match_operand:SI 1 "s_register_operand" "r"))])]
  2894.   ""
  2895.   "*
  2896. {
  2897.   rtx ops[3];
  2898.   int count = XVECLEN (operands[0], 0);
  2899.  
  2900.   ops[0] = XEXP (SET_DEST (XVECEXP (operands[0], 0, 0)), 0);
  2901.   ops[1] = SET_SRC (XVECEXP (operands[0], 0, 0));
  2902.   ops[2] = SET_SRC (XVECEXP (operands[0], 0, count - 1));
  2903.  
  2904.   return arm_output_asm_insn (\"stmia\\t%0, {%1-%2}\\t@ str multiple\", ops);
  2905. }
  2906. "
  2907. [(set (attr "type")
  2908.       (cond [(eq (symbol_ref "XVECLEN (operands[0],0)") (const_int 3))
  2909.         (const_string "store2")
  2910.          (eq (symbol_ref "XVECLEN (operands[0],0)") (const_int 4))
  2911.         (const_string "store3")]
  2912.       (const_string "store4")))])
  2913.  
  2914. ;; Move a block of memory if it is word aligned and MORE than 2 words long.
  2915. ;; We could let this apply for blocks of less than this, but it clobbers so
  2916. ;; many registers that there is then probably a better way.
  2917.  
  2918. ;; If optimizing, output redundant moves with REG_NOTES on them, this 
  2919. ;; produces better code.
  2920.  
  2921. (define_expand "movstrsi"
  2922.   [(set (match_operand:BLK 0 "general_operand" "=m")
  2923.         (match_operand:BLK 1 "general_operand" "m"))
  2924.    (use (match_operand:SI 2 "immediate_operand" "n"))
  2925.    (use (match_operand:SI 3 "immediate_operand" "n"))
  2926.    (clobber (reg:SI 0))
  2927.    (clobber (reg:SI 1))
  2928.    (clobber (reg:SI 2))
  2929.    (clobber (reg:SI 3))
  2930.    (clobber (match_scratch:SI 4 "=+r"))
  2931.    (clobber (match_scratch:SI 5 "=+r"))]
  2932.   ""
  2933.   "
  2934. {
  2935.   int words_to_go;
  2936.   int i, r;
  2937.   rtx const_sxteen = gen_rtx (CONST_INT, SImode, 16);
  2938.   rtx src = gen_reg_rtx (SImode);
  2939.   rtx dst = gen_reg_rtx (SImode);
  2940.   rtx st_src, st_dst, end_src, end_dst, fin_src, fin_dst;
  2941.   extern int optimize;
  2942.  
  2943.   if (GET_CODE (operands[2]) != CONST_INT
  2944.       || GET_CODE (operands[3]) != CONST_INT
  2945.       || INTVAL (operands[2]) % 4 != 0
  2946.       || INTVAL (operands[2]) < 4
  2947.       || INTVAL (operands[2]) > 64
  2948.       || INTVAL (operands[3]) < 4
  2949.       || INTVAL (operands[3]) % 4 != 0)
  2950.     FAIL;
  2951.   emit_move_insn (dst, st_dst = force_reg (SImode, XEXP (operands[0], 0)));
  2952.   emit_move_insn (src, st_src = force_reg (SImode, XEXP (operands[1], 0)));
  2953.   fin_src = src;
  2954.   fin_dst = dst;
  2955.  
  2956.   for (i = 0, words_to_go = INTVAL (operands[2]) / 4; words_to_go >= 2; i+=4)
  2957.     {
  2958.       emit_insn (arm_gen_load_multiple (0, words_to_go > 4 ? 4 : words_to_go,
  2959.                                         src, TRUE, TRUE));
  2960.       emit_insn (arm_gen_store_multiple (0, words_to_go > 4 ? 4 : words_to_go,
  2961.                                         dst, TRUE, TRUE));
  2962.       if (optimize)
  2963.         for (r = (words_to_go > 4) ? 3 : words_to_go - 1; r >= 0; r--)
  2964.           {
  2965.             rtx note;
  2966.             note = emit_move_insn (gen_reg_rtx (SImode),
  2967.                                    gen_rtx (REG, SImode, r));
  2968.             REG_NOTES (note) = gen_rtx (EXPR_LIST, REG_EQUIV,
  2969.                                         gen_rtx (MEM, SImode,
  2970.                                               plus_constant (st_src, 4*(i+r))),
  2971.                                         REG_NOTES (note));
  2972.             REG_NOTES (note) = gen_rtx (EXPR_LIST, REG_EQUIV,
  2973.                                         gen_rtx (MEM, SImode,
  2974.                                               plus_constant (st_dst, 4*(i+r))),
  2975.                                         REG_NOTES (note));
  2976.           }
  2977.       words_to_go -= words_to_go < 4 ? words_to_go : 4;
  2978.     }
  2979.   if (words_to_go)
  2980.   {
  2981.     rtx sreg;
  2982.  
  2983.     emit_move_insn (sreg = gen_reg_rtx (SImode), gen_rtx (MEM, SImode, src));
  2984.     emit_move_insn (fin_src = gen_reg_rtx (SImode), plus_constant (src, 4));
  2985.     emit_move_insn (gen_rtx (MEM, SImode, dst), sreg);
  2986.     emit_move_insn (fin_dst = gen_reg_rtx (SImode), plus_constant (dst, 4));
  2987.   }
  2988.   if (optimize)
  2989.     {
  2990.       /* Insns for the REG_NOTES: These notes tell the optimiser where the
  2991.          index registers have got to so that consecutive block moves of
  2992.          contiguous data work efficiently */
  2993.  
  2994.       end_src = emit_move_insn (fin_src, fin_src);
  2995.       REG_NOTES (end_src) = gen_rtx(EXPR_LIST, REG_EQUAL,
  2996.                                   plus_constant (st_src, INTVAL (operands[2])),
  2997.                                   REG_NOTES (end_src));
  2998.       end_dst = emit_move_insn (fin_dst, fin_dst);
  2999.       REG_NOTES (end_dst) = gen_rtx(EXPR_LIST, REG_EQUAL,
  3000.                                   plus_constant (st_dst, INTVAL (operands[2])),
  3001.                                   REG_NOTES (end_dst));
  3002.     }
  3003.   DONE;
  3004. }
  3005. ")
  3006.  
  3007.  
  3008. ;; Comparison and test insns
  3009.  
  3010. (define_expand "cmpsi"
  3011.   [(set (reg:CC 24)
  3012.     (compare:CC (match_operand:SI 0 "s_register_operand" "")
  3013.                (match_operand:SI 1 "arm_add_operand" "")))]
  3014.   ""
  3015.   "
  3016. {
  3017.   arm_compare_op0 = operands[0];
  3018.   arm_compare_op1 = operands[1];
  3019.   arm_compare_fp = 0;
  3020.   DONE;
  3021. }
  3022. ")
  3023.  
  3024. (define_expand "cmpsf"
  3025.   [(set (reg:CC 24)
  3026.     (compare:CC (match_operand:SF 0 "s_register_operand" "")
  3027.             (match_operand:SF 1 "fpu_rhs_operand" "")))]
  3028.   ""
  3029.   "
  3030. {
  3031.   arm_compare_op0 = operands[0];
  3032.   arm_compare_op1 = operands[1];
  3033.   arm_compare_fp = 1;
  3034.   DONE;
  3035. }
  3036. ")
  3037.  
  3038. (define_expand "cmpdf"
  3039.   [(set (reg:CC 24)
  3040.     (compare:CC (match_operand:DF 0 "s_register_operand" "")
  3041.             (match_operand:DF 1 "fpu_rhs_operand" "")))]
  3042.   ""
  3043.   "
  3044. {
  3045.   arm_compare_op0 = operands[0];
  3046.   arm_compare_op1 = operands[1];
  3047.   arm_compare_fp = 1;
  3048.   DONE;
  3049. }
  3050. ")
  3051.  
  3052. (define_expand "cmpxf"
  3053.   [(set (reg:CC 24)
  3054.     (compare:CC (match_operand:XF 0 "s_register_operand" "")
  3055.             (match_operand:XF 1 "fpu_rhs_operand" "")))]
  3056.   "ENABLE_XF_PATTERNS"
  3057.   "
  3058. {
  3059.   arm_compare_op0 = operands[0];
  3060.   arm_compare_op1 = operands[1];
  3061.   arm_compare_fp = 1;
  3062.   DONE;
  3063. }
  3064. ")
  3065.  
  3066. (define_insn ""
  3067.   [(set (match_operand 0 "cc_register" "")
  3068.     (compare (match_operand:SI 1 "s_register_operand" "r")
  3069.          (match_operand:SI 2 "arm_add_operand" "rL")))]
  3070.   ""
  3071.   "*
  3072.   if (GET_CODE (operands[2]) == CONST_INT
  3073.       && !const_ok_for_arm (INTVAL (operands[2])))
  3074.     return arm_output_asm_insn (\"cmn\\t%1, #%n2\", operands);
  3075.   return arm_output_asm_insn (\"cmp\\t%1, %2\", operands);
  3076. "
  3077. [(set_attr "conds" "set")])
  3078.  
  3079. (define_insn ""
  3080.   [(set (match_operand 0 "cc_register" "")
  3081.     (compare (match_operand:SI 1 "s_register_operand" "r")
  3082.          (neg:SI (match_operand:SI 2 "s_register_operand" "r"))))]
  3083.   ""
  3084.   "*
  3085.   return arm_output_asm_insn (\"cmn\\t%1, %2\", operands);
  3086. "
  3087. [(set_attr "conds" "set")])
  3088.  
  3089. (define_insn ""
  3090.   [(set (match_operand 0 "cc_register" "")
  3091.     (compare (match_operand:SI 1 "s_register_operand" "r")
  3092.          (match_operator:SI 2 "shift_operator"
  3093.           [(match_operand:SI 3 "s_register_operand" "r")
  3094.            (match_operand:SI 4 "arm_rhs_operand" "rn")])))]
  3095.   ""
  3096.   "*
  3097.   return output_shift_compare (operands, FALSE);
  3098. "
  3099. [(set_attr "conds" "set")])
  3100.  
  3101. (define_insn ""
  3102.   [(set (match_operand 0 "cc_register" "")
  3103.     (compare (match_operand:SI 1 "s_register_operand" "r")
  3104.          (neg:SI (match_operator:SI 2 "shift_operator"
  3105.               [(match_operand:SI 3 "s_register_operand" "r")
  3106.                (match_operand:SI 4 "arm_rhs_operand" "rn")]))))]
  3107.   ""
  3108.   "*
  3109.   return output_shift_compare (operands, TRUE);
  3110. "
  3111. [(set_attr "conds" "set")])
  3112.  
  3113. (define_insn ""
  3114.   [(set (reg:CCFP 24)
  3115.     (compare:CCFP (match_operand:SF 0 "s_register_operand" "f,f")
  3116.               (match_operand:SF 1 "fpu_add_operand" "fG,H")))]
  3117.   ""
  3118.   "*
  3119. {
  3120.   REAL_VALUE_TYPE r;
  3121.  
  3122.   switch (which_alternative)
  3123.     {
  3124.     case 0:
  3125.       return arm_output_asm_insn (\"cmf\\t%0, %1\", operands);
  3126.     case 1:
  3127.       REAL_VALUE_FROM_CONST_DOUBLE (r, operands[1]);
  3128.       r = REAL_VALUE_NEGATE (r);
  3129.       operands[1] = CONST_DOUBLE_FROM_REAL_VALUE (r, GET_MODE (operands[1]));
  3130.       return arm_output_asm_insn (\"cnf\\t%0, %1\", operands);
  3131.     }
  3132. }
  3133. "
  3134. [(set_attr "conds" "set")
  3135.  (set_attr "type" "f_2_r")])
  3136.  
  3137. (define_insn ""
  3138.   [(set (reg:CCFP 24)
  3139.     (compare:CCFP (match_operand:DF 0 "s_register_operand" "f,f")
  3140.               (match_operand:DF 1 "fpu_add_operand" "fG,H")))]
  3141.   ""
  3142.   "*
  3143. {
  3144.   REAL_VALUE_TYPE r;
  3145.  
  3146.   switch (which_alternative)
  3147.     {
  3148.     case 0:
  3149.       return arm_output_asm_insn (\"cmf\\t%0, %1\", operands);
  3150.     case 1:
  3151.       REAL_VALUE_FROM_CONST_DOUBLE (r, operands[1]);
  3152.       r = REAL_VALUE_NEGATE (r);
  3153.       operands[1] = CONST_DOUBLE_FROM_REAL_VALUE (r, GET_MODE (operands[1]));
  3154.       return arm_output_asm_insn (\"cnf\\t%0, %1\", operands);
  3155.     }
  3156. }
  3157. "
  3158. [(set_attr "conds" "set")
  3159.  (set_attr "type" "f_2_r")])
  3160.  
  3161. (define_insn ""
  3162.   [(set (reg:CCFP 24)
  3163.     (compare:CCFP (float_extend:DF
  3164.                (match_operand:SF 0 "s_register_operand" "f,f"))
  3165.               (match_operand:DF 1 "fpu_add_operand" "fG,H")))]
  3166.   ""
  3167.   "*
  3168. {
  3169.   REAL_VALUE_TYPE r;
  3170.  
  3171.   switch (which_alternative)
  3172.     {
  3173.     case 0:
  3174.       return arm_output_asm_insn (\"cmf\\t%0, %1\", operands);
  3175.     case 1:
  3176.       REAL_VALUE_FROM_CONST_DOUBLE (r, operands[1]);
  3177.       r = REAL_VALUE_NEGATE (r);
  3178.       operands[1] = CONST_DOUBLE_FROM_REAL_VALUE (r, GET_MODE (operands[1]));
  3179.       return arm_output_asm_insn (\"cnf\\t%0, %1\", operands);
  3180.     }
  3181. }
  3182. "
  3183. [(set_attr "conds" "set")
  3184.  (set_attr "type" "f_2_r")])
  3185.  
  3186. (define_insn ""
  3187.   [(set (reg:CCFP 24)
  3188.     (compare:CCFP (match_operand:DF 0 "s_register_operand" "f")
  3189.               (float_extend:DF
  3190.                (match_operand:SF 1 "s_register_operand" "f"))))]
  3191.   ""
  3192.   "*
  3193.   return arm_output_asm_insn (\"cmf\\t%0, %1\", operands);
  3194. "
  3195. [(set_attr "conds" "set")
  3196.  (set_attr "type" "f_2_r")])
  3197.  
  3198. (define_insn ""
  3199.   [(set (reg:CCFP 24)
  3200.     (compare:CCFP (match_operand:XF 0 "s_register_operand" "f,f")
  3201.               (match_operand:XF 1 "fpu_add_operand" "fG,H")))]
  3202.   "ENABLE_XF_PATTERNS"
  3203.   "*
  3204. {
  3205.   REAL_VALUE_TYPE r;
  3206.  
  3207.   switch (which_alternative)
  3208.     {
  3209.     case 0:
  3210.       return arm_output_asm_insn (\"cmf\\t%0, %1\", operands);
  3211.     case 1:
  3212.       REAL_VALUE_FROM_CONST_DOUBLE (r, operands[1]);
  3213.       r = REAL_VALUE_NEGATE (r);
  3214.       operands[1] = CONST_DOUBLE_FROM_REAL_VALUE (r, GET_MODE (operands[1]));
  3215.       return arm_output_asm_insn (\"cnf\\t%0, %1\", operands);
  3216.     }
  3217. }
  3218. "
  3219. [(set_attr "conds" "set")
  3220.  (set_attr "type" "f_2_r")])
  3221.  
  3222. (define_insn ""
  3223.   [(set (reg:CCFPE 24)
  3224.     (compare:CCFPE (match_operand:SF 0 "s_register_operand" "f,f")
  3225.                (match_operand:SF 1 "fpu_add_operand" "fG,H")))]
  3226.   ""
  3227.   "*
  3228. {
  3229.   REAL_VALUE_TYPE r;
  3230.  
  3231.   switch (which_alternative)
  3232.     {
  3233.     case 0:
  3234.       return arm_output_asm_insn (\"cmfe\\t%0, %1\", operands);
  3235.     case 1:
  3236.       REAL_VALUE_FROM_CONST_DOUBLE (r, operands[1]);
  3237.       r = REAL_VALUE_NEGATE (r);
  3238.       operands[1] = CONST_DOUBLE_FROM_REAL_VALUE (r, GET_MODE (operands[1]));
  3239.       return arm_output_asm_insn (\"cnfe\\t%0, %1\", operands);
  3240.     }
  3241. }
  3242. "
  3243. [(set_attr "conds" "set")
  3244.  (set_attr "type" "f_2_r")])
  3245.  
  3246. (define_insn ""
  3247.   [(set (reg:CCFPE 24)
  3248.     (compare:CCFPE (match_operand:DF 0 "s_register_operand" "f,f")
  3249.                (match_operand:DF 1 "fpu_add_operand" "fG,H")))]
  3250.   ""
  3251.   "*
  3252. {
  3253.   REAL_VALUE_TYPE r;
  3254.  
  3255.   switch (which_alternative)
  3256.     {
  3257.     case 0:
  3258.       return arm_output_asm_insn (\"cmfe\\t%0, %1\", operands);
  3259.     case 1:
  3260.       REAL_VALUE_FROM_CONST_DOUBLE (r, operands[1]);
  3261.       r = REAL_VALUE_NEGATE (r);
  3262.       operands[1] = CONST_DOUBLE_FROM_REAL_VALUE (r, GET_MODE (operands[1]));
  3263.       return arm_output_asm_insn (\"cnfe\\t%0, %1\", operands);
  3264.     }
  3265. }
  3266. "
  3267. [(set_attr "conds" "set")
  3268.  (set_attr "type" "f_2_r")])
  3269.  
  3270. (define_insn ""
  3271.   [(set (reg:CCFPE 24)
  3272.     (compare:CCFPE (float_extend:DF
  3273.             (match_operand:SF 0 "s_register_operand" "f,f"))
  3274.                (match_operand:DF 1 "fpu_add_operand" "fG,H")))]
  3275.   ""
  3276.   "*
  3277. {
  3278.   REAL_VALUE_TYPE r;
  3279.  
  3280.   switch (which_alternative)
  3281.     {
  3282.     case 0:
  3283.       return arm_output_asm_insn (\"cmfe\\t%0, %1\", operands);
  3284.     case 1:
  3285.       REAL_VALUE_FROM_CONST_DOUBLE (r, operands[1]);
  3286.       r = REAL_VALUE_NEGATE (r);
  3287.       operands[1] = CONST_DOUBLE_FROM_REAL_VALUE (r, GET_MODE (operands[1]));
  3288.       return arm_output_asm_insn (\"cnfe\\t%0, %1\", operands);
  3289.     }
  3290. }
  3291. "
  3292. [(set_attr "conds" "set")
  3293.  (set_attr "type" "f_2_r")])
  3294.  
  3295. (define_insn ""
  3296.   [(set (reg:CCFPE 24)
  3297.     (compare:CCFPE (match_operand:DF 0 "s_register_operand" "f")
  3298.                (float_extend:DF
  3299.             (match_operand:SF 1 "s_register_operand" "f"))))]
  3300.   ""
  3301.   "*
  3302.   return arm_output_asm_insn (\"cmfe\\t%0, %1\", operands);
  3303. "
  3304. [(set_attr "conds" "set")
  3305.  (set_attr "type" "f_2_r")])
  3306.  
  3307. (define_insn ""
  3308.   [(set (reg:CCFPE 24)
  3309.     (compare:CCFPE (match_operand:XF 0 "s_register_operand" "f,f")
  3310.                (match_operand:XF 1 "fpu_add_operand" "fG,H")))]
  3311.   "ENABLE_XF_PATTERNS"
  3312.   "*
  3313. {
  3314.   REAL_VALUE_TYPE r;
  3315.  
  3316.   switch (which_alternative)
  3317.     {
  3318.     case 0:
  3319.       return arm_output_asm_insn (\"cmfe\\t%0, %1\", operands);
  3320.     case 1:
  3321.       REAL_VALUE_FROM_CONST_DOUBLE (r, operands[1]);
  3322.       r = REAL_VALUE_NEGATE (r);
  3323.       operands[1] = CONST_DOUBLE_FROM_REAL_VALUE (r, GET_MODE (operands[1]));
  3324.       return arm_output_asm_insn (\"cnfe\\t%0, %1\", operands);
  3325.     }
  3326. }
  3327. "
  3328. [(set_attr "conds" "set")
  3329.  (set_attr "type" "f_2_r")])
  3330.  
  3331. ; This insn allows redundant compares to be removed by cse, nothing should
  3332. ; ever appear in the output file since (set (reg x) (reg x)) is a no-op that
  3333. ; is deleted later on. The match_dup will match the mode here, so that
  3334. ; mode changes of the condition codes aren't lost by this even though we don't
  3335. ; specify what they are.
  3336.  
  3337. (define_insn ""
  3338.   [(set (match_operand 0 "cc_register" "") (match_dup 0))]
  3339.   ""
  3340.   "\\t@ deleted compare"
  3341. [(set_attr "conds" "set")
  3342.  (set_attr "length" "0")])
  3343.  
  3344.  
  3345. ;; Conditional branch insns
  3346.  
  3347. (define_expand "beq"
  3348.   [(set (pc)
  3349.     (if_then_else (eq (match_dup 1) (const_int 0))
  3350.               (label_ref (match_operand 0 "" ""))
  3351.               (pc)))]
  3352.   ""
  3353.   "
  3354. {
  3355.   operands[1] = gen_compare_reg (EQ, arm_compare_op0, arm_compare_op1,
  3356.                  arm_compare_fp);
  3357. }
  3358. ")
  3359.  
  3360. (define_expand "bne"
  3361.   [(set (pc)
  3362.     (if_then_else (ne (match_dup 1) (const_int 0))
  3363.               (label_ref (match_operand 0 "" ""))
  3364.               (pc)))]
  3365.   ""
  3366.   "
  3367. {
  3368.   operands[1] = gen_compare_reg (NE, arm_compare_op0, arm_compare_op1,
  3369.                  arm_compare_fp);
  3370. }
  3371. ")
  3372.  
  3373. (define_expand "bgt"
  3374.   [(set (pc)
  3375.     (if_then_else (gt (match_dup 1) (const_int 0))
  3376.               (label_ref (match_operand 0 "" ""))
  3377.               (pc)))]
  3378.   ""
  3379.   "
  3380. {
  3381.   operands[1] = gen_compare_reg (GT, arm_compare_op0, arm_compare_op1,
  3382.                  arm_compare_fp);
  3383. }
  3384. ")
  3385.  
  3386. (define_expand "ble"
  3387.   [(set (pc)
  3388.     (if_then_else (le (match_dup 1) (const_int 0))
  3389.               (label_ref (match_operand 0 "" ""))
  3390.               (pc)))]
  3391.   ""
  3392.   "
  3393. {
  3394.   operands[1] = gen_compare_reg (LE, arm_compare_op0, arm_compare_op1,
  3395.                  arm_compare_fp);
  3396. }
  3397. ")
  3398.  
  3399. (define_expand "bge"
  3400.   [(set (pc)
  3401.     (if_then_else (ge (match_dup 1) (const_int 0))
  3402.               (label_ref (match_operand 0 "" ""))
  3403.               (pc)))]
  3404.   ""
  3405.   "
  3406. {
  3407.   operands[1] = gen_compare_reg (GE, arm_compare_op0, arm_compare_op1,
  3408.                  arm_compare_fp);
  3409. }
  3410. ")
  3411.  
  3412. (define_expand "blt"
  3413.   [(set (pc)
  3414.     (if_then_else (lt (match_dup 1) (const_int 0))
  3415.               (label_ref (match_operand 0 "" ""))
  3416.               (pc)))]
  3417.   ""
  3418.   "
  3419. {
  3420.   operands[1] = gen_compare_reg (LT, arm_compare_op0, arm_compare_op1,
  3421.                  arm_compare_fp);
  3422. }
  3423. ")
  3424.  
  3425. (define_expand "bgtu"
  3426.   [(set (pc)
  3427.     (if_then_else (gtu (match_dup 1) (const_int 0))
  3428.               (label_ref (match_operand 0 "" ""))
  3429.               (pc)))]
  3430.   ""
  3431.   "
  3432. {
  3433.   operands[1] = gen_compare_reg (GTU, arm_compare_op0, arm_compare_op1,
  3434.                  arm_compare_fp);
  3435. }
  3436. ")
  3437.  
  3438. (define_expand "bleu"
  3439.   [(set (pc)
  3440.     (if_then_else (leu (match_dup 1) (const_int 0))
  3441.               (label_ref (match_operand 0 "" ""))
  3442.               (pc)))]
  3443.   ""
  3444.   "
  3445. {
  3446.   operands[1] = gen_compare_reg (LEU, arm_compare_op0, arm_compare_op1,
  3447.                  arm_compare_fp);
  3448. }
  3449. ")
  3450.  
  3451. (define_expand "bgeu"
  3452.   [(set (pc)
  3453.     (if_then_else (geu (match_dup 1) (const_int 0))
  3454.               (label_ref (match_operand 0 "" ""))
  3455.               (pc)))]
  3456.   ""
  3457.   "
  3458. {
  3459.   operands[1] = gen_compare_reg (GEU, arm_compare_op0, arm_compare_op1,
  3460.                  arm_compare_fp);
  3461. }
  3462. ")
  3463.  
  3464. (define_expand "bltu"
  3465.   [(set (pc)
  3466.     (if_then_else (ltu (match_dup 1) (const_int 0))
  3467.               (label_ref (match_operand 0 "" ""))
  3468.               (pc)))]
  3469.   ""
  3470.   "
  3471. {
  3472.   operands[1] = gen_compare_reg (LTU, arm_compare_op0, arm_compare_op1,
  3473.                  arm_compare_fp);
  3474. }
  3475. ")
  3476.  
  3477. ;; patterns to match conditional branch insns
  3478.  
  3479. (define_insn ""
  3480.   [(set (pc)
  3481.     (if_then_else (match_operator 1 "comparison_operator"
  3482.                     [(reg 24) (const_int 0)])
  3483.               (label_ref (match_operand 0 "" ""))
  3484.               (pc)))]
  3485.   ""
  3486.   "*
  3487. {
  3488.   extern int arm_ccfsm_state;
  3489.  
  3490.   if (arm_ccfsm_state == 1 || arm_ccfsm_state == 2)
  3491.   {
  3492.     arm_ccfsm_state += 2;
  3493.     return \"\";
  3494.   }
  3495.   return (arm_output_asm_insn (\"b%d1\\t%l0\", operands));
  3496. }"
  3497. [(set_attr "conds" "use")])
  3498.  
  3499. (define_insn ""
  3500.   [(set (pc)
  3501.     (if_then_else (match_operator 1 "comparison_operator"
  3502.                     [(reg 24) (const_int 0)])
  3503.               (pc)
  3504.               (label_ref (match_operand 0 "" ""))))]
  3505.   ""
  3506.   "*
  3507. {
  3508.   extern int arm_ccfsm_state;
  3509.  
  3510.   if (arm_ccfsm_state == 1 || arm_ccfsm_state == 2)
  3511.   {
  3512.     arm_ccfsm_state += 2;
  3513.     return \"\";
  3514.   }
  3515.   return (arm_output_asm_insn (\"b%D1\\t%l0\", operands));
  3516. }"
  3517. [(set_attr "conds" "use")])
  3518.  
  3519.  
  3520. ; scc insns
  3521.  
  3522. (define_expand "seq"
  3523.   [(set (match_operand:SI 0 "s_register_operand" "=r")
  3524.     (eq:SI (match_dup 1) (const_int 0)))]
  3525.   ""
  3526.   "
  3527. {
  3528.   operands[1] = gen_compare_reg (EQ, arm_compare_op0, arm_compare_op1,
  3529.                  arm_compare_fp);
  3530. }
  3531. ")
  3532.  
  3533. (define_expand "sne"
  3534.   [(set (match_operand:SI 0 "s_register_operand" "=r")
  3535.     (ne:SI (match_dup 1) (const_int 0)))]
  3536.   ""
  3537.   "
  3538. {
  3539.   operands[1] = gen_compare_reg (NE, arm_compare_op0, arm_compare_op1,
  3540.                  arm_compare_fp);
  3541. }
  3542. ")
  3543.  
  3544. (define_expand "sgt"
  3545.   [(set (match_operand:SI 0 "s_register_operand" "=r")
  3546.     (gt:SI (match_dup 1) (const_int 0)))]
  3547.   ""
  3548.   "
  3549. {
  3550.   operands[1] = gen_compare_reg (GT, arm_compare_op0, arm_compare_op1,
  3551.                  arm_compare_fp);
  3552. }
  3553. ")
  3554.  
  3555. (define_expand "sle"
  3556.   [(set (match_operand:SI 0 "s_register_operand" "=r")
  3557.     (le:SI (match_dup 1) (const_int 0)))]
  3558.   ""
  3559.   "
  3560. {
  3561.   operands[1] = gen_compare_reg (LE, arm_compare_op0, arm_compare_op1,
  3562.                  arm_compare_fp);
  3563. }
  3564. ")
  3565.  
  3566. (define_expand "sge"
  3567.   [(set (match_operand:SI 0 "s_register_operand" "=r")
  3568.     (ge:SI (match_dup 1) (const_int 0)))]
  3569.   ""
  3570.   "
  3571. {
  3572.   operands[1] = gen_compare_reg (GE, arm_compare_op0, arm_compare_op1,
  3573.                  arm_compare_fp);
  3574. }
  3575. ")
  3576.  
  3577. (define_expand "slt"
  3578.   [(set (match_operand:SI 0 "s_register_operand" "=r")
  3579.     (lt:SI (match_dup 1) (const_int 0)))]
  3580.   ""
  3581.   "
  3582. {
  3583.   operands[1] = gen_compare_reg (LT, arm_compare_op0, arm_compare_op1,
  3584.                  arm_compare_fp);
  3585. }
  3586. ")
  3587.  
  3588. (define_expand "sgtu"
  3589.   [(set (match_operand:SI 0 "s_register_operand" "=r")
  3590.     (gtu:SI (match_dup 1) (const_int 0)))]
  3591.   ""
  3592.   "
  3593. {
  3594.   operands[1] = gen_compare_reg (GTU, arm_compare_op0, arm_compare_op1,
  3595.                  arm_compare_fp);
  3596. }
  3597. ")
  3598.  
  3599. (define_expand "sleu"
  3600.   [(set (match_operand:SI 0 "s_register_operand" "=r")
  3601.     (leu:SI (match_dup 1) (const_int 0)))]
  3602.   ""
  3603.   "
  3604. {
  3605.   operands[1] = gen_compare_reg (LEU, arm_compare_op0, arm_compare_op1,
  3606.                  arm_compare_fp);
  3607. }
  3608. ")
  3609.  
  3610. (define_expand "sgeu"
  3611.   [(set (match_operand:SI 0 "s_register_operand" "=r")
  3612.     (geu:SI (match_dup 1) (const_int 0)))]
  3613.   ""
  3614.   "
  3615. {
  3616.   operands[1] = gen_compare_reg (GEU, arm_compare_op0, arm_compare_op1,
  3617.                  arm_compare_fp);
  3618. }
  3619. ")
  3620.  
  3621. (define_expand "sltu"
  3622.   [(set (match_operand:SI 0 "s_register_operand" "=r")
  3623.     (ltu:SI (match_dup 1) (const_int 0)))]
  3624.   ""
  3625.   "
  3626. {
  3627.   operands[1] = gen_compare_reg (LTU, arm_compare_op0, arm_compare_op1,
  3628.                  arm_compare_fp);
  3629. }
  3630. ")
  3631.  
  3632. (define_insn ""
  3633.   [(set (match_operand:SI 0 "s_register_operand" "=r")
  3634.     (match_operator:SI 1 "comparison_operator" [(reg 24) (const_int 0)]))]
  3635.   ""
  3636.   "*
  3637.   arm_output_asm_insn (\"mov%d1\\t%0, #1\", operands);
  3638.   return arm_output_asm_insn (\"mov%D1\\t%0, #0\", operands);
  3639. "
  3640. [(set_attr "conds" "use")
  3641.  (set_attr "length" "2")])
  3642.  
  3643. (define_insn ""
  3644.   [(set (match_operand:SI 0 "s_register_operand" "=r")
  3645.     (neg:SI (match_operator:SI 1 "comparison_operator"
  3646.          [(reg 24) (const_int 0)])))]
  3647.   ""
  3648.   "*
  3649.   arm_output_asm_insn (\"mvn%d1\\t%0, #0\", operands);
  3650.   return arm_output_asm_insn (\"mov%D1\\t%0, #0\", operands);
  3651. "
  3652. [(set_attr "conds" "use")
  3653.  (set_attr "length" "2")])
  3654.  
  3655. (define_insn ""
  3656.   [(set (match_operand:SI 0 "s_register_operand" "=r")
  3657.     (not:SI (match_operator:SI 1 "comparison_operator"
  3658.          [(reg 24) (const_int 0)])))]
  3659.   ""
  3660.   "*
  3661.   arm_output_asm_insn (\"mvn%d1\\t%0, #1\", operands);
  3662.   return arm_output_asm_insn (\"mov%D1\\t%0, #0\", operands);
  3663. "
  3664. [(set_attr "conds" "use")
  3665.  (set_attr "length" "2")])
  3666.  
  3667.  
  3668. ;; Jump and linkage insns
  3669.  
  3670. (define_insn "jump"
  3671.   [(set (pc)
  3672.     (label_ref (match_operand 0 "" "")))]
  3673.   ""
  3674.   "*
  3675. {
  3676.   extern int arm_ccfsm_state;
  3677.  
  3678.   if (arm_ccfsm_state == 1 || arm_ccfsm_state == 2)
  3679.   {
  3680.     arm_ccfsm_state += 2;
  3681.     return \"\";
  3682.   }
  3683.   return (arm_output_asm_insn (\"b\\t%l0\", operands));
  3684. }")
  3685.  
  3686. (define_expand "call"
  3687.   [(parallel [(call (match_operand 0 "memory_operand" "")
  3688.                 (match_operand 1 "general_operand" ""))
  3689.           (clobber (reg:SI 14))])]
  3690.   ""
  3691.   "")
  3692.  
  3693. (define_insn ""
  3694.   [(call (mem:SI (match_operand:SI 0 "s_register_operand" "r"))
  3695.          (match_operand 1 "" "g"))
  3696.    (clobber (reg:SI 14))]
  3697.   ""
  3698.   "*
  3699.   return (output_call (operands));
  3700. "
  3701. [(set (attr "conds")
  3702.       (if_then_else (eq_attr "cpu" "arm6")
  3703.             (const_string "clob")
  3704.             (const_string "nocond")))
  3705. ;; length is worst case, normally it is only two
  3706.  (set_attr "length" "3")
  3707.  (set_attr "type" "call")])
  3708.  
  3709. (define_insn ""
  3710.   [(call (mem:SI (match_operand 0 "memory_operand" "m"))
  3711.      (match_operand 1 "general_operand" "g"))
  3712.    (clobber (reg:SI 14))]
  3713.   ""
  3714.   "*
  3715.   return (output_call_mem (operands));
  3716. "
  3717. [(set (attr "conds")
  3718.       (if_then_else (eq_attr "cpu" "arm6")
  3719.             (const_string "clob")
  3720.             (const_string "nocond")))
  3721.  (set_attr "length" "3")
  3722.  (set_attr "type" "call")])
  3723.  
  3724. (define_expand "call_value"
  3725.   [(parallel [(set (match_operand 0 "" "=rf")
  3726.                (call (match_operand 1 "memory_operand" "m")
  3727.                  (match_operand 2 "general_operand" "g")))
  3728.           (clobber (reg:SI 14))])]
  3729.   ""
  3730.   "")
  3731.  
  3732. (define_insn ""
  3733.   [(set (match_operand 0 "" "=rf")
  3734.         (call (mem:SI (match_operand:SI 1 "s_register_operand" "r"))
  3735.           (match_operand 2 "general_operand" "g")))
  3736.    (clobber (reg:SI 14))]
  3737.   ""
  3738.   "*
  3739.   return (output_call (&operands[1]));
  3740. "
  3741. [(set (attr "conds")
  3742.       (if_then_else (eq_attr "cpu" "arm6")
  3743.             (const_string "clob")
  3744.             (const_string "nocond")))
  3745.  (set_attr "length" "3")
  3746.  (set_attr "type" "call")])
  3747.  
  3748. (define_insn ""
  3749.   [(set (match_operand 0 "" "=rf")
  3750.     (call (mem:SI (match_operand 1 "memory_operand" "m"))
  3751.     (match_operand 2 "general_operand" "g")))
  3752.    (clobber (reg:SI 14))]
  3753.   "! CONSTANT_ADDRESS_P (XEXP (operands[1], 0))"
  3754.   "*
  3755.   return (output_call_mem (&operands[1]));
  3756. "
  3757. [(set (attr "conds")
  3758.       (if_then_else (eq_attr "cpu" "arm6")
  3759.             (const_string "clob")
  3760.             (const_string "nocond")))
  3761.  (set_attr "length" "3")
  3762.  (set_attr "type" "call")])
  3763.  
  3764. ;; Allow calls to SYMBOL_REFs specially as they are not valid general addresses
  3765. ;; The 'a' causes the operand to be treated as an address, i.e. no '#' output.
  3766.  
  3767. (define_insn ""
  3768.   [(call (mem:SI (match_operand:SI 0 "" "i"))
  3769.      (match_operand:SI 1 "general_operand" "g"))
  3770.    (clobber (reg:SI 14))]
  3771.   "GET_CODE (operands[0]) == SYMBOL_REF"
  3772.   "*
  3773.   return (arm_output_asm_insn (\"bl\\t%a0\", operands));
  3774. "
  3775. [(set (attr "conds")
  3776.       (if_then_else (eq_attr "cpu" "arm6")
  3777.             (const_string "clob")
  3778.             (const_string "nocond")))
  3779.  (set_attr "type" "call")])
  3780.  
  3781. (define_insn ""
  3782.   [(set (match_operand 0 "s_register_operand" "=rf")
  3783.     (call (mem:SI (match_operand:SI 1 "" "i"))
  3784.     (match_operand:SI 2 "general_operand" "g")))
  3785.    (clobber (reg:SI 14))]
  3786.   "GET_CODE(operands[1]) == SYMBOL_REF"
  3787.   "*
  3788.   return (arm_output_asm_insn (\"bl\\t%a1\", operands));
  3789. "
  3790. [(set (attr "conds")
  3791.       (if_then_else (eq_attr "cpu" "arm6")
  3792.             (const_string "clob")
  3793.             (const_string "nocond")))
  3794.  (set_attr "type" "call")])
  3795.  
  3796. ;; Often the return insn will be the same as loading from memory, so set attr
  3797. (define_insn "return"
  3798.   [(return)]
  3799.   "USE_RETURN_INSN"
  3800.   "*
  3801. {
  3802.   extern int arm_ccfsm_state;
  3803.  
  3804.   if (arm_ccfsm_state == 2)
  3805.   {
  3806.     arm_ccfsm_state += 2;
  3807.     return \"\";
  3808.   }
  3809.   return output_return_instruction (NULL, TRUE);
  3810. }"
  3811. [(set_attr "type" "load")])
  3812.  
  3813. (define_insn ""
  3814.   [(set (pc)
  3815.         (if_then_else (match_operator 0 "comparison_operator"
  3816.                [(reg 24) (const_int 0)])
  3817.                       (return)
  3818.                       (pc)))]
  3819.   "USE_RETURN_INSN"
  3820.   "*
  3821. {
  3822.   extern int arm_ccfsm_state;
  3823.  
  3824.   if (arm_ccfsm_state == 2)
  3825.   {
  3826.     arm_ccfsm_state += 2;
  3827.     return \"\";
  3828.   }
  3829.   return output_return_instruction (operands[0], TRUE);
  3830. }"
  3831. [(set_attr "conds" "use")
  3832.  (set_attr "type" "load")])
  3833.  
  3834. (define_insn ""
  3835.   [(set (pc)
  3836.         (if_then_else (match_operator 0 "comparison_operator"
  3837.                [(reg 24) (const_int 0)])
  3838.                       (pc)
  3839.               (return)))]
  3840.   "USE_RETURN_INSN"
  3841.   "*
  3842. {
  3843.   extern int arm_ccfsm_state;
  3844.  
  3845.   if (arm_ccfsm_state == 2)
  3846.   {
  3847.     arm_ccfsm_state += 2;
  3848.     return \"\";
  3849.   }
  3850.   return output_return_instruction 
  3851.     (gen_rtx (reverse_condition (GET_CODE (operands[0])),
  3852.           GET_MODE (operands[0]), XEXP (operands[0], 0),
  3853.           XEXP (operands[0], 1)),
  3854.      TRUE);
  3855. }"
  3856. [(set_attr "conds" "use")
  3857.  (set_attr "type" "load")])
  3858.  
  3859. ;; Call subroutine returning any type.
  3860.  
  3861. (define_expand "untyped_call"
  3862.   [(parallel [(call (match_operand 0 "" "")
  3863.             (const_int 0))
  3864.           (match_operand 1 "" "")
  3865.           (match_operand 2 "" "")])]
  3866.   ""
  3867.   "
  3868. {
  3869.   int i;
  3870.  
  3871.   emit_call_insn (gen_call (operands[0], const0_rtx, NULL, const0_rtx));
  3872.  
  3873.   for (i = 0; i < XVECLEN (operands[2], 0); i++)
  3874.     {
  3875.       rtx set = XVECEXP (operands[2], 0, i);
  3876.       emit_move_insn (SET_DEST (set), SET_SRC (set));
  3877.     }
  3878.  
  3879.   /* The optimizer does not know that the call sets the function value
  3880.      registers we stored in the result block.  We avoid problems by
  3881.      claiming that all hard registers are used and clobbered at this
  3882.      point.  */
  3883.   emit_insn (gen_blockage ());
  3884.  
  3885.   DONE;
  3886. }")
  3887.  
  3888. ;; UNSPEC_VOLATILE is considered to use and clobber all hard registers and
  3889. ;; all of memory.  This blocks insns from being moved across this point.
  3890.  
  3891. (define_insn "blockage"
  3892.   [(unspec_volatile [(const_int 0)] 0)]
  3893.   ""
  3894.   ""
  3895. [(set_attr "length" "0")
  3896.  (set_attr "type" "block")])
  3897.  
  3898. (define_insn "tablejump"
  3899.   [(set (pc)
  3900.     (match_operand:SI 0 "s_register_operand" "r"))
  3901.    (use (label_ref (match_operand 1 "" "")))]
  3902.   ""
  3903.   "*
  3904.   return arm_output_asm_insn (\"mov\\tpc, %0\\t@ table jump, label %l1\",
  3905.                   operands);
  3906. ")
  3907.  
  3908. (define_insn ""
  3909.   [(set (pc)
  3910.     (match_operand:SI 0 "memory_operand" "m"))
  3911.    (use (label_ref (match_operand 1 "" "")))]
  3912.   ""
  3913.   "*
  3914.   return arm_output_asm_insn (\"ldr\\tpc, %0\\t@ table jump, label %l1\",
  3915.                   operands);
  3916. "
  3917. [(set_attr "type" "load")])
  3918.  
  3919. (define_insn "indirect_jump"
  3920.   [(set (pc)
  3921.     (match_operand:SI 0 "s_register_operand" "r"))]
  3922.   ""
  3923.   "*
  3924.   return arm_output_asm_insn (\"mov\\tpc, %0\\t@ indirect jump\", operands);
  3925. ")
  3926.  
  3927. (define_insn ""
  3928.   [(set (pc)
  3929.     (match_operand:SI 0 "memory_operand" "m"))]
  3930.   ""
  3931.   "*
  3932.   return arm_output_asm_insn (\"ldr\\tpc, %0\\t@ indirect jump\", operands);
  3933. "
  3934. [(set_attr "type" "load")])
  3935.  
  3936. ;; Misc insns
  3937.  
  3938. (define_insn "nop"
  3939.   [(const_int 0)]
  3940.   ""
  3941.   "*
  3942.   return arm_output_asm_insn (\"mov\\tr0, r0\\t@ nop\", operands);
  3943. ")
  3944.  
  3945. ;; Patterns to allow combination of arithmetic, cond code and shifts
  3946.  
  3947. (define_insn ""
  3948.   [(set (match_operand:SI 0 "s_register_operand" "=r")
  3949.         (match_operator:SI 1 "shiftable_operator"
  3950.           [(match_operator:SI 3 "shift_operator"
  3951.              [(match_operand:SI 4 "s_register_operand" "r")
  3952.               (match_operand:SI 5 "nonmemory_operand" "rI")])
  3953.            (match_operand:SI 2 "s_register_operand" "r")]))]
  3954.   ""
  3955.   "*
  3956.   return (output_arithmetic_with_shift (operands, TRUE, FALSE));
  3957. ")
  3958.  
  3959. (define_insn ""
  3960.   [(set (reg:CC_NOOV 24)
  3961.         (compare:CC_NOOV (match_operator:SI 1 "shiftable_operator"
  3962.                   [(match_operator:SI 3 "shift_operator"
  3963.                     [(match_operand:SI 4 "s_register_operand" "r")
  3964.                      (match_operand:SI 5 "nonmemory_operand" "rI")])
  3965.                    (match_operand:SI 2 "s_register_operand" "r")])
  3966.              (const_int 0)))
  3967.    (set (match_operand:SI 0 "s_register_operand" "=r")
  3968.     (match_op_dup 1 [(match_op_dup 3 [(match_dup 4) (match_dup 5)])
  3969.              (match_dup 2)]))]
  3970.   ""
  3971.   "*
  3972.   return (output_arithmetic_with_shift (operands, TRUE, TRUE));
  3973. "
  3974. [(set_attr "conds" "set")])
  3975.  
  3976. (define_insn ""
  3977.   [(set (reg:CC_NOOV 24)
  3978.         (compare:CC_NOOV (match_operator:SI 1 "shiftable_operator"
  3979.                   [(match_operator:SI 3 "shift_operator"
  3980.                     [(match_operand:SI 4 "s_register_operand" "r")
  3981.                      (match_operand:SI 5 "nonmemory_operand" "rI")])
  3982.                    (match_operand:SI 2 "s_register_operand" "r")])
  3983.              (const_int 0)))
  3984.    (clobber (match_scratch:SI 0 "=r"))]
  3985.   ""
  3986.   "*
  3987.   return (output_arithmetic_with_shift (operands, TRUE, TRUE));
  3988. "
  3989. [(set_attr "conds" "set")])
  3990.  
  3991. (define_insn ""
  3992.   [(set (match_operand:SI 0 "s_register_operand" "=r")
  3993.     (minus:SI (match_operand:SI 1 "s_register_operand" "r")
  3994.           (match_operator:SI 2 "shift_operator"
  3995.            [(match_operand:SI 3 "s_register_operand" "r")
  3996.             (match_operand:SI 4 "nonmemory_operand" "rn")])))]
  3997.   ""
  3998.   "*
  3999. {
  4000.   rtx ops[6];
  4001.  
  4002.   ops[0] = operands[0];
  4003.   ops[1] = gen_rtx (MINUS, SImode, operands[1], operands[2]);
  4004.   ops[2] = operands[1];
  4005.   ops[3] = operands[2];
  4006.   ops[4] = operands[3];
  4007.   ops[5] = operands[4];
  4008.   return output_arithmetic_with_shift (ops, FALSE, FALSE);
  4009. }
  4010. ")
  4011.  
  4012. (define_insn ""
  4013.   [(set (reg:CC_NOOV 24)
  4014.     (compare:CC_NOOV (minus:SI (match_operand:SI 1 "s_register_operand" "r")
  4015.                    (match_operator:SI 2 "shift_operator"
  4016.                     [(match_operand:SI 3 "s_register_operand" "r")
  4017.                      (match_operand:SI 4 "nonmemory_operand" "rn")]))
  4018.              (const_int 0)))
  4019.    (set (match_operand:SI 0 "s_register_operand" "=r")
  4020.     (minus:SI (match_dup 1) (match_op_dup 2 [(match_dup 3)
  4021.                          (match_dup 4)])))]
  4022.   ""
  4023.   "*
  4024. {
  4025.   rtx ops[6];
  4026.  
  4027.   ops[0] = operands[0];
  4028.   ops[1] = gen_rtx (MINUS, SImode, operands[1], operands[2]);
  4029.   ops[2] = operands[1];
  4030.   ops[3] = operands[2];
  4031.   ops[4] = operands[3];
  4032.   ops[5] = operands[4];
  4033.   return output_arithmetic_with_shift (ops, FALSE, TRUE);
  4034. }
  4035. "
  4036. [(set_attr "conds" "set")])
  4037.  
  4038. (define_insn ""
  4039.   [(set (reg:CC_NOOV 24)
  4040.     (compare:CC_NOOV (minus:SI (match_operand:SI 1 "s_register_operand" "r")
  4041.                    (match_operator:SI 2 "shift_operator"
  4042.                     [(match_operand:SI 3 "s_register_operand" "r")
  4043.                      (match_operand:SI 4 "nonmemory_operand" "rn")]))
  4044.              (const_int 0)))
  4045.    (clobber (match_scratch:SI 0 "=r"))]
  4046.   ""
  4047.   "*
  4048. {
  4049.   rtx ops[6];
  4050.  
  4051.   ops[0] = operands[0];
  4052.   ops[1] = gen_rtx (MINUS, SImode, operands[1], operands[2]);
  4053.   ops[2] = operands[1];
  4054.   ops[3] = operands[2];
  4055.   ops[4] = operands[3];
  4056.   ops[5] = operands[4];
  4057.   return output_arithmetic_with_shift (ops, FALSE, TRUE);
  4058. }
  4059. "
  4060. [(set_attr "conds" "set")])
  4061.  
  4062. ;; These variants of the above insns can occur if the first operand is the
  4063. ;; frame pointer and we eliminate that.  This is a kludge, but there doesn't
  4064. ;; seem to be a way around it.  Most of the predicates have to be null
  4065. ;; because the format can be generated part way through reload, so
  4066. ;; if we don't match it as soon as it becomes available, reload doesn't know
  4067. ;; how to reload pseudos that haven't got hard registers; the constraints will
  4068. ;; sort everything out.
  4069.  
  4070. (define_insn ""
  4071.   [(set (match_operand:SI 0 "" "=&r")
  4072.     (plus:SI (plus:SI (match_operator:SI 5 "shift_operator"
  4073.                [(match_operand:SI 3 "" "r")
  4074.                 (match_operand:SI 4 "" "rn")])
  4075.               (match_operand:SI 2 "" "r"))
  4076.          (match_operand:SI 1 "const_int_operand" "n")))]
  4077.   "reload_in_progress"
  4078.   "*
  4079. {
  4080.   char instr[100];
  4081.   sprintf (instr, \"add\\t%%0, %%2, %%3, %s %%4\", 
  4082.        shift_instr (GET_CODE (operands[5]), &operands[4]));
  4083.   arm_output_asm_insn (instr, operands);
  4084.   operands[2] = operands[1];
  4085.   operands[1] = operands[0];
  4086.   return output_add_immediate (operands);
  4087. }"
  4088. ; we have no idea how long the add_immediate is, it could be up to 4.
  4089. [(set_attr "length" "5")])
  4090.  
  4091. (define_insn ""
  4092.   [(set (reg:CC_NOOV 24)
  4093.     (compare:CC_NOOV (plus:SI
  4094.               (plus:SI 
  4095.                (match_operator:SI 5 "shift_operator"
  4096.                 [(match_operand:SI 3 "" "r")
  4097.                  (match_operand:SI 4 "" "rn")])
  4098.                (match_operand:SI 1 "" "r"))
  4099.               (match_operand:SI 2 "const_int_operand" "n"))
  4100.              (const_int 0)))
  4101.    (set (match_operand:SI 0 "" "=&r")
  4102.     (plus:SI (plus:SI (match_op_dup 5 [(match_dup 3) (match_dup 4)])
  4103.               (match_dup 1))
  4104.          (match_dup 2)))]
  4105.   "reload_in_progress"
  4106.   "*
  4107. {
  4108.   char instr[100];
  4109.   sprintf (instr, \"adds\\t%%0, %%0, %%3, %s %%4\",
  4110.        shift_instr (GET_CODE (operands[5]), &operands[4]));
  4111.   output_add_immediate (operands);
  4112.   return arm_output_asm_insn (instr, operands);
  4113. }"
  4114. [(set_attr "conds" "set")
  4115.  (set_attr "length" "5")])
  4116.  
  4117. (define_insn ""
  4118.   [(set (reg:CC_NOOV 24)
  4119.     (compare:CC_NOOV (plus:SI
  4120.               (plus:SI 
  4121.                (match_operator:SI 5 "shift_operator"
  4122.                 [(match_operand:SI 3 "" "r")
  4123.                  (match_operand:SI 4 "" "rn")])
  4124.                (match_operand:SI 1 "" "r"))
  4125.               (match_operand:SI 2 "const_int_operand" "n"))
  4126.              (const_int 0)))
  4127.    (clobber (match_scratch:SI 0 "=&r"))]
  4128.   "reload_in_progress"
  4129.   "*
  4130. {
  4131.   char instr[100];
  4132.   sprintf (instr, \"adds\\t%%0, %%0, %%3, %s %%4\",
  4133.        shift_instr (GET_CODE (operands[5]), &operands[4]));
  4134.   output_add_immediate (operands);
  4135.   return arm_output_asm_insn (instr, operands);
  4136. }"
  4137. [(set_attr "conds" "set")
  4138.  (set_attr "length" "5")])
  4139.  
  4140. ;; These are similar, but are needed when the mla pattern contains the
  4141. ;; eliminated register as operand 3.
  4142.  
  4143. (define_insn ""
  4144.   [(set (match_operand:SI 0 "" "=&r,&r")
  4145.     (plus:SI (plus:SI (mult:SI (match_operand:SI 1 "" "%0,r")
  4146.                    (match_operand:SI 2 "" "r,r"))
  4147.               (match_operand:SI 3 "" "r,r"))
  4148.          (match_operand:SI 4 "const_int_operand" "n,n")))]
  4149.   "reload_in_progress"
  4150.   "*
  4151.   arm_output_asm_insn (\"mla\\t%0, %2, %1, %3\", operands);
  4152.   operands[2] = operands[4];
  4153.   operands[1] = operands[0];
  4154.   return output_add_immediate (operands);
  4155. "
  4156. [(set_attr "length" "5")])
  4157.  
  4158. (define_insn ""
  4159.   [(set (reg:CC_NOOV 24)
  4160.     (compare:CC_NOOV (plus:SI (plus:SI (mult:SI
  4161.                         (match_operand:SI 3 "" "r")
  4162.                         (match_operand:SI 4 "" "r"))
  4163.                        (match_operand:SI 1 "" "r"))
  4164.                   (match_operand:SI 2 "const_int_operand" "n"))
  4165.              (const_int 0)))
  4166.    (set (match_operand:SI 0 "" "=&r")
  4167.     (plus:SI (plus:SI (mult:SI (match_dup 3) (match_dup 4)) (match_dup 1))
  4168.          (match_dup 2)))]
  4169.   "reload_in_progress"
  4170.   "*
  4171.   output_add_immediate (operands);
  4172.   return arm_output_asm_insn (\"mlas\\t%0, %3, %4, %0\", operands);
  4173. "
  4174. [(set_attr "length" "5")
  4175.  (set_attr "conds" "set")])
  4176.  
  4177. (define_insn ""
  4178.   [(set (reg:CC_NOOV 24)
  4179.     (compare:CC_NOOV (plus:SI (plus:SI (mult:SI
  4180.                         (match_operand:SI 3 "" "r")
  4181.                         (match_operand:SI 4 "" "r"))
  4182.                        (match_operand:SI 1 "" "r"))
  4183.                   (match_operand:SI 2 "const_int_operand" "n"))
  4184.              (const_int 0)))
  4185.    (clobber (match_scratch:SI 0 "=&r"))]
  4186.   "reload_in_progress"
  4187.   "*
  4188.   output_add_immediate (operands);
  4189.   return arm_output_asm_insn (\"mlas\\t%0, %3, %4, %0\", operands);
  4190. "
  4191. [(set_attr "length" "5")
  4192.  (set_attr "conds" "set")])
  4193.  
  4194.  
  4195.  
  4196.  
  4197. (define_insn ""
  4198.   [(set (match_operand:SI 0 "s_register_operand" "=r")
  4199.     (and:SI (match_operator 1 "comparison_operator"
  4200.          [(reg 24) (const_int 0)])
  4201.         (match_operand:SI 2 "s_register_operand" "r")))]
  4202.   ""
  4203.   "*
  4204.   arm_output_asm_insn (\"mov%D1\\t%0, #0\", operands);
  4205.   return arm_output_asm_insn (\"and%d1\\t%0, %2, #1\", operands);
  4206. "
  4207. [(set_attr "conds" "use")
  4208.  (set_attr "length" "2")])
  4209.  
  4210. (define_insn ""
  4211.   [(set (match_operand:SI 0 "s_register_operand" "=r,r")
  4212.     (ior:SI (match_operator 2 "comparison_operator"
  4213.          [(reg 24) (const_int 0)])
  4214.         (match_operand:SI 1 "s_register_operand" "0,?r")))]
  4215.   ""
  4216.   "*
  4217.   if (which_alternative != 0)
  4218.     arm_output_asm_insn (\"mov%D2\\t%0, %1\", operands);
  4219.   return arm_output_asm_insn (\"orr%d2\\t%0, %1, #1\", operands);
  4220. "
  4221. [(set_attr "conds" "use")
  4222.  (set_attr "length" "1,2")])
  4223.  
  4224. (define_insn ""
  4225.   [(set (match_operand:SI 0 "s_register_operand" "=r")
  4226.     (match_operator 1 "comparison_operator"
  4227.      [(match_operand:SI 2 "s_register_operand" "r")
  4228.       (match_operand:SI 3 "arm_add_operand" "rL")]))
  4229.    (clobber (reg 24))]
  4230.   ""
  4231.   "*
  4232.   if (GET_CODE (operands[1]) == LT && operands[3] == const0_rtx)
  4233.     return arm_output_asm_insn (\"mov\\t%0, %2, lsr #31\", operands);
  4234.   if (GET_CODE (operands[1]) == GE && operands[3] == const0_rtx)
  4235.     {
  4236.       arm_output_asm_insn (\"mvn\\t%0, %2\", operands);
  4237.       return arm_output_asm_insn (\"mov\\t%0, %0, lsr #31\", operands);
  4238.     }
  4239.   if (GET_CODE (operands[1]) == NE)
  4240.     {
  4241.       if (GET_CODE (operands[3]) == CONST_INT
  4242.       && !const_ok_for_arm (INTVAL (operands[3])))
  4243.     arm_output_asm_insn (\"adds\\t%0, %2, #%n3\", operands);
  4244.       else
  4245.         arm_output_asm_insn (\"subs\\t%0, %2, %3\", operands);
  4246.       return arm_output_asm_insn (\"movne\\t%0, #1\", operands);
  4247.     }
  4248.   if (GET_CODE (operands[3]) == CONST_INT
  4249.       && !const_ok_for_arm (INTVAL (operands[3])))
  4250.     arm_output_asm_insn (\"cmn\\t%2, #%n3\", operands);
  4251.   else
  4252.     arm_output_asm_insn (\"cmp\\t%2, %3\", operands);
  4253.   arm_output_asm_insn (\"mov%D1\\t%0, #0\", operands);
  4254.   return arm_output_asm_insn (\"mov%d1\\t%0, #1\", operands);
  4255. "
  4256. [(set_attr "conds" "clob")
  4257.  (set_attr "length" "3")])
  4258.  
  4259. (define_insn ""
  4260.   [(set (match_operand:SI 0 "s_register_operand" "=&r")
  4261.     (ior:SI (match_operator 1 "comparison_operator"
  4262.          [(match_operand:SI 2 "s_register_operand" "r")
  4263.           (match_operand:SI 3 "arm_rhs_operand" "rI")])
  4264.         (match_operator 4 "comparison_operator"
  4265.          [(match_operand:SI 5 "s_register_operand" "r")
  4266.           (match_operand:SI 6 "arm_rhs_operand" "rI")])))
  4267.    (clobber (reg 24))]
  4268.   ""
  4269.   "*
  4270. {
  4271.   int dominant = comparison_dominates_p (GET_CODE (operands[4]),
  4272.                      GET_CODE (operands[1]));
  4273.  
  4274.   arm_output_asm_insn (dominant ? \"cmp\\t%5, %6\" : \"cmp\\t%2, %3\",
  4275.                operands);
  4276.   arm_output_asm_insn (\"mov\\t%0, #0\", operands);
  4277.   if (GET_CODE (operands[1]) == GET_CODE (operands[4])
  4278.       || comparison_dominates_p (GET_CODE (operands[1]),
  4279.                  GET_CODE (operands[4]))
  4280.       || dominant)
  4281.     {
  4282.       arm_output_asm_insn (dominant ? \"cmp%D4\\t%2, %3\" : \"cmp%D1\\t%5,%6\",
  4283.                operands);
  4284.     }
  4285.   else
  4286.     {
  4287.       arm_output_asm_insn (\"mov%d1\\t%0, #1\", operands);
  4288.       arm_output_asm_insn (\"cmp\\t%5, %6\", operands);
  4289.     }
  4290.   return arm_output_asm_insn (dominant ? \"mov%d1\\t%0, #1\"
  4291.                   : \"mov%d4\\t%0, #1\", operands);
  4292. }
  4293. "
  4294. [(set_attr "conds" "clob")
  4295. ; worst case length
  4296.  (set_attr "length" "5")])
  4297.  
  4298. (define_split
  4299.   [(set (pc)
  4300.     (if_then_else (match_operator 5 "equality_operator"
  4301.                [(ior:SI (match_operator 6 "comparison_operator"
  4302.                  [(match_operand:SI 0 "s_register_operand" "r")
  4303.                   (match_operand:SI 1 "arm_add_operand" "rL")])
  4304.                 (match_operator 7 "comparison_operator"
  4305.                  [(match_operand:SI 2 "s_register_operand" "r")
  4306.                   (match_operand:SI 3 "arm_add_operand" "rL")]))
  4307.             (const_int 0)])
  4308.               (label_ref (match_operand 4 "" ""))
  4309.               (pc)))
  4310.    (clobber (reg 24))]
  4311.   "(GET_CODE (operands[6]) == GET_CODE (operands[7])
  4312.     || comparison_dominates_p (GET_CODE (operands[6]), GET_CODE (operands[7]))
  4313.     || comparison_dominates_p (GET_CODE (operands[7]), GET_CODE (operands[6])))"
  4314.   [(set (reg:CC 24)
  4315.     (compare:CC (ior:CC (match_op_dup 6
  4316.                  [(match_dup 0) (match_dup 1)])
  4317.                 (match_op_dup 7
  4318.                  [(match_dup 2) (match_dup 3)]))
  4319.             (const_int 0)))
  4320.    (set (pc)
  4321.         (if_then_else (match_op_dup 5 [(reg:CC 24) (const_int 0)])
  4322.               (label_ref (match_dup 4))
  4323.               (pc)))]
  4324.   "
  4325. {
  4326.   enum rtx_code code = comparison_dominates_p (GET_CODE (operands[6]),
  4327.                            GET_CODE (operands[7]))
  4328.                ? GET_CODE (operands[7]) : GET_CODE (operands[6]);
  4329.  
  4330.   if (GET_CODE (operands[5]) == NE)
  4331.     operands[5] = gen_rtx (code, CCmode,
  4332.                XEXP (operands[5], 0), XEXP (operands[5], 1));
  4333.   else
  4334.     operands[5] = gen_rtx (reverse_condition (code), CCmode,
  4335.                XEXP (operands[5], 0), XEXP (operands[5], 1));
  4336. }
  4337. ")
  4338.  
  4339. ;; Don't match these patterns if we can use a conditional compare, since they
  4340. ;; tell the final prescan branch elimator code that full branch inlining
  4341. ;; can't be done.
  4342.  
  4343. (define_insn ""
  4344.   [(set (pc)
  4345.     (if_then_else (ne
  4346.                (ior:SI (match_operator 5 "comparison_operator"
  4347.                 [(match_operand:SI 0 "s_register_operand" "r")
  4348.                  (match_operand:SI 1 "arm_add_operand" "rL")])
  4349.                    (match_operator 6 "comparison_operator"
  4350.                 [(match_operand:SI 2 "s_register_operand" "r")
  4351.                  (match_operand:SI 3 "arm_rhs_operand" "rL")]))
  4352.                (const_int 0))
  4353.               (label_ref (match_operand 4 "" ""))
  4354.               (pc)))
  4355.    (clobber (reg 24))]
  4356.   "!(GET_CODE (operands[5]) == GET_CODE (operands[6])
  4357.      || comparison_dominates_p (GET_CODE (operands[5]), GET_CODE (operands[6]))
  4358.      || comparison_dominates_p (GET_CODE (operands[6]), GET_CODE (operands[5])))"
  4359.   "*
  4360. {
  4361.   extern int arm_ccfsm_state;
  4362.  
  4363.   if (GET_CODE (operands[1]) == CONST_INT
  4364.       && !const_ok_for_arm (INTVAL (operands[1])))
  4365.     arm_output_asm_insn (\"cmn\\t%0, #%n1\", operands);
  4366.   else
  4367.     arm_output_asm_insn (\"cmp\\t%0, %1\", operands);
  4368.   arm_output_asm_insn (\"b%d5\\t%l4\", operands);
  4369.   if (GET_CODE (operands[3]) == CONST_INT
  4370.       && !const_ok_for_arm (INTVAL (operands[3])))
  4371.     arm_output_asm_insn (\"cmn\\t%2, #%n3\", operands);
  4372.   else
  4373.     arm_output_asm_insn (\"cmp\\t%2, %3\", operands);
  4374.   if (arm_ccfsm_state == 1 || arm_ccfsm_state == 2)
  4375.   {
  4376.     arm_ccfsm_state += 2;
  4377.     return \"\";
  4378.   }
  4379.   return arm_output_asm_insn (\"b%d6\\t%l4\", operands);
  4380. }"
  4381. [(set_attr "conds" "jump_clob")
  4382.  (set_attr "length" "4")])
  4383.  
  4384. (define_insn ""
  4385.   [(set (reg:CC 24)
  4386.     (compare:CC (ior:CC (match_operator 4 "comparison_operator"
  4387.                  [(match_operand:SI 0 "s_register_operand" "r")
  4388.                   (match_operand:SI 1 "arm_add_operand" "rL")])
  4389.                 (match_operator 5 "comparison_operator"
  4390.                  [(match_operand:SI 2 "s_register_operand" "r")
  4391.                   (match_operand:SI 3 "arm_add_operand" "rL")]))
  4392.             (const_int 0)))]
  4393.   "(GET_CODE (operands[4]) == GET_CODE (operands[5])
  4394.     || comparison_dominates_p (GET_CODE (operands[4]), GET_CODE (operands[5]))
  4395.     || comparison_dominates_p (GET_CODE (operands[5]), GET_CODE (operands[4])))"
  4396.   "*
  4397.   if (comparison_dominates_p (GET_CODE (operands[5]), GET_CODE (operands[4])))
  4398.     {
  4399.       if (GET_CODE (operands[3]) == CONST_INT
  4400.       && !const_ok_for_arm (INTVAL (operands[3])))
  4401.     arm_output_asm_insn (\"cmn\\t%2, #%n3\", operands);
  4402.       else
  4403.     arm_output_asm_insn (\"cmp\\t%2, %3\", operands);
  4404.       if (GET_CODE (operands[1]) == CONST_INT
  4405.       && !const_ok_for_arm (INTVAL (operands[1])))
  4406.     return arm_output_asm_insn (\"cmn%D5\\t%0, #%n1\", operands);
  4407.       return arm_output_asm_insn (\"cmp%D5\\t%0, %1\", operands);
  4408.     }
  4409.   if (GET_CODE (operands[1]) == CONST_INT
  4410.       && !const_ok_for_arm (INTVAL (operands[1])))
  4411.     arm_output_asm_insn (\"cmn\\t%0, #%n1\", operands);
  4412.   else
  4413.     arm_output_asm_insn (\"cmp\\t%0, %1\", operands);
  4414.   if (GET_CODE (operands[3]) == CONST_INT
  4415.       && !const_ok_for_arm (INTVAL (operands[3])))
  4416.     return arm_output_asm_insn (\"cmn%D4\\t%2, #%n3\", operands);
  4417.   return arm_output_asm_insn (\"cmp%D4\\t%2, %3\", operands);
  4418. "
  4419. [(set_attr "conds" "set")
  4420.  (set_attr "length" "2")])
  4421.  
  4422. (define_insn ""
  4423.   [(set (match_operand:SI 0 "s_register_operand" "=r,r,r")
  4424.     (if_then_else (match_operator 3 "equality_operator"
  4425.                [(match_operator 4 "comparison_operator"
  4426.              [(reg 24) (const_int 0)])
  4427.             (const_int 0)])
  4428.               (match_operand:SI 1 "arm_rhs_operand" "0,rI,?rI")
  4429.               (match_operand:SI 2 "arm_rhs_operand" "rI,0,rI")))]
  4430.   ""
  4431.   "*
  4432.   if (GET_CODE (operands[3]) == NE)
  4433.     {
  4434.       if (which_alternative != 0)
  4435.     arm_output_asm_insn (\"mov%d4\\t%0, %1\", operands);
  4436.       if (which_alternative != 1)
  4437.     arm_output_asm_insn (\"mov%D4\\t%0, %2\", operands);
  4438.       return \"\";
  4439.     }
  4440.   if (which_alternative != 0)
  4441.     arm_output_asm_insn (\"mov%D4\\t%0, %1\", operands);
  4442.   if (which_alternative != 1)
  4443.     arm_output_asm_insn (\"mov%d4\\t%0, %2\", operands);
  4444.   return \"\";
  4445. "
  4446. [(set_attr "conds" "use")
  4447.  (set_attr "length" "1,1,2")])
  4448.  
  4449. (define_insn ""
  4450.   [(set (match_operand:SI 0 "s_register_operand" "=r,r")
  4451.         (match_operator:SI 5 "shiftable_operator" 
  4452.      [(match_operator:SI 4 "comparison_operator"
  4453.            [(match_operand:SI 2 "s_register_operand" "r,r")
  4454.         (match_operand:SI 3 "arm_rhs_operand" "rI,rI")])
  4455.           (match_operand:SI 1 "s_register_operand" "0,?r")]))
  4456.    (clobber (reg 24))]
  4457.   ""
  4458.   "*
  4459. {
  4460.   char *instr = arithmetic_instr (operands[5], TRUE);
  4461.   char pattern[100];
  4462.  
  4463.   if (GET_CODE (operands[4]) == LT && operands[3] == const0_rtx)
  4464.     {
  4465.       sprintf (pattern, \"%s\\t%%0, %%1, %%2, lsr #31\", instr);
  4466.       return arm_output_asm_insn (pattern, operands);
  4467.     }
  4468.   arm_output_asm_insn (\"cmp\\t%2, %3\", operands);
  4469.   if (GET_CODE (operands[5]) == AND)
  4470.     arm_output_asm_insn (\"mov%D4\\t%0, #0\", operands);
  4471.   else if (which_alternative != 0)
  4472.     arm_output_asm_insn (\"mov%D4\\t%0, %1\", operands);
  4473.   sprintf (pattern, \"%s%%d4\\t%%0, %%1, #1\", instr);
  4474.   return arm_output_asm_insn (pattern, operands);
  4475. }
  4476. "
  4477. [(set_attr "conds" "clob")
  4478.  (set_attr "length" "3")])
  4479.  
  4480. (define_insn ""
  4481.   [(set (match_operand:SI 0 "s_register_operand" "=r,r")
  4482.         (minus:SI (match_operand:SI 1 "s_register_operand" "0,?r")
  4483.           (match_operator:SI 4 "comparison_operator"
  4484.                    [(match_operand:SI 2 "s_register_operand" "r,r")
  4485.             (match_operand:SI 3 "arm_rhs_operand" "rI,rI")])))
  4486.    (clobber (reg 24))]
  4487.   ""
  4488.   "*
  4489.   arm_output_asm_insn (\"cmp\\t%2, %3\", operands);
  4490.   if (which_alternative != 0)
  4491.     arm_output_asm_insn (\"mov%D4\\t%0, %1\", operands);
  4492.   return arm_output_asm_insn (\"sub%d4\\t%0, %1, #1\", operands);
  4493. "
  4494. [(set_attr "conds" "clob")
  4495.  (set_attr "length" "2,3")])
  4496.  
  4497. (define_insn ""
  4498.   [(set (match_operand:SI 0 "s_register_operand" "=&r")
  4499.     (and:SI (match_operator 1 "comparison_operator"
  4500.          [(match_operand:SI 2 "s_register_operand" "r")
  4501.           (match_operand:SI 3 "arm_rhs_operand" "rI")])
  4502.         (match_operator 4 "comparison_operator"
  4503.          [(match_operand:SI 5 "s_register_operand" "r")
  4504.           (match_operand:SI 6 "arm_rhs_operand" "rI")])))
  4505.    (clobber (reg 24))]
  4506.   ""
  4507.   "*
  4508. {
  4509.   int dominant =
  4510.     comparison_dominates_p (reverse_condition (GET_CODE (operands[1])),
  4511.                 reverse_condition (GET_CODE (operands[4])))
  4512.     ? 1 
  4513.     : comparison_dominates_p (reverse_condition (GET_CODE (operands[4])),
  4514.                   reverse_condition (GET_CODE (operands[1])))
  4515.     ? 2 : 0;
  4516.   arm_output_asm_insn (dominant == 2 ? \"cmp\\t%5, %6\" : \"cmp\\t%2, %3\",
  4517.                operands);
  4518.   arm_output_asm_insn (\"mov\\t%0, #1\", operands);
  4519.   if (GET_CODE (operands[1]) == GET_CODE (operands[4]) || dominant)
  4520.     {
  4521.       arm_output_asm_insn (dominant == 2 ? \"cmp%d4\\t%2, %3\"
  4522.                : \"cmp%d1\\t%5, %6\", operands);
  4523.     }
  4524.   else
  4525.     {
  4526.       arm_output_asm_insn (\"mov%D1\\t%0, #0\", operands);
  4527.       arm_output_asm_insn (\"cmp\\t%5, %6\", operands);
  4528.     }
  4529.   return arm_output_asm_insn (dominant == 2 ? \"mov%D1\\t%0, #0\" 
  4530.                   : \"mov%D4\\t%0, #0\", operands);
  4531. }
  4532. "
  4533. [(set_attr "conds" "clob")
  4534.  (set_attr "length" "5")])
  4535.  
  4536. (define_split
  4537.   [(set (pc)
  4538.     (if_then_else (match_operator 1 "equality_operator"
  4539.                [(and:SI (match_operator 2 "comparison_operator"
  4540.                  [(match_operand:SI 3 "s_register_operand" "r")
  4541.                   (match_operand:SI 4 "arm_add_operand" "rL")])
  4542.                 (match_operator 0 "comparison_operator"
  4543.                  [(match_operand:SI 5 "s_register_operand" "r")
  4544.                   (match_operand:SI 6 "arm_add_operand" "rL")]))
  4545.             (const_int 0)])
  4546.               (label_ref (match_operand 7 "" ""))
  4547.               (pc)))
  4548.    (clobber (reg 24))]
  4549.   "(GET_CODE (operands[2]) == GET_CODE (operands[0])
  4550.     || comparison_dominates_p (reverse_condition (GET_CODE (operands[2])),
  4551.                    reverse_condition (GET_CODE (operands[0])))
  4552.     || comparison_dominates_p (reverse_condition (GET_CODE (operands[0])),
  4553.                    reverse_condition (GET_CODE (operands[2]))))"
  4554.   [(set (reg:CC 24)
  4555.     (compare:CC (ior:CC (match_op_dup 2
  4556.                  [(match_dup 3) (match_dup 4)])
  4557.                 (match_op_dup 0
  4558.                  [(match_dup 5) (match_dup 6)]))
  4559.             (const_int 0)))
  4560.    (set (pc)
  4561.         (if_then_else (match_op_dup 1 [(reg:CC 24) (const_int 0)])
  4562.               (label_ref (match_dup 7))
  4563.               (pc)))]
  4564.   "
  4565. {
  4566.   /* Use DeMorgans law to convert this into an IOR of the inverse conditions 
  4567.      This is safe since we only do it for integer comparisons. */
  4568.   enum rtx_code code = 
  4569.     comparison_dominates_p (reverse_condition (GET_CODE (operands[2])),
  4570.                 reverse_condition (GET_CODE (operands[0])))
  4571.     ? GET_CODE (operands[0]) : GET_CODE (operands[2]);
  4572.  
  4573.   operands[2] = gen_rtx (reverse_condition (GET_CODE (operands[2])),
  4574.              GET_MODE (operands[2]), operands[3], operands[4]);
  4575.   operands[0] = gen_rtx (reverse_condition (GET_CODE (operands[0])),
  4576.              GET_MODE (operands[0]), operands[5], operands[6]);
  4577.   if (GET_CODE (operands[1]) == NE)
  4578.     operands[1] = gen_rtx (code, CCmode,
  4579.                XEXP (operands[1], 0), XEXP (operands[1], 1));
  4580.   else
  4581.     operands[1] = gen_rtx (reverse_condition (code), CCmode,
  4582.                XEXP (operands[1], 0), XEXP (operands[1], 1));
  4583. }
  4584. ")
  4585.  
  4586. ;; Don't match these patterns if we can use a conditional compare, since they
  4587. ;; tell the final prescan branch elimator code that full branch inlining
  4588. ;; can't be done.
  4589.  
  4590. (define_insn ""
  4591.   [(set (pc)
  4592.     (if_then_else (eq
  4593.                (and:SI (match_operator 1 "comparison_operator"
  4594.                 [(match_operand:SI 2 "s_register_operand" "r")
  4595.                  (match_operand:SI 3 "arm_add_operand" "rL")])
  4596.                    (match_operator 4 "comparison_operator"
  4597.                 [(match_operand:SI 5 "s_register_operand" "r")
  4598.                  (match_operand:SI 6 "arm_rhs_operand" "rL")]))
  4599.                (const_int 0))
  4600.               (label_ref (match_operand 0 "" ""))
  4601.               (pc)))
  4602.    (clobber (reg 24))]
  4603.   "!(GET_CODE (operands[1]) == GET_CODE (operands[4])
  4604.      || comparison_dominates_p (reverse_condition (GET_CODE (operands[1])),
  4605.                     reverse_condition (GET_CODE (operands[4])))
  4606.      || comparison_dominates_p (reverse_condition (GET_CODE (operands[4])),
  4607.                     reverse_condition (GET_CODE (operands[1]))))"
  4608.   "*
  4609. {
  4610.   extern int arm_ccfsm_state;
  4611.  
  4612.   if (GET_CODE (operands[3]) == CONST_INT
  4613.       && !const_ok_for_arm (INTVAL (operands[3])))
  4614.     arm_output_asm_insn (\"cmn\\t%2, #%n3\", operands);
  4615.   else
  4616.     arm_output_asm_insn (\"cmp\\t%2, %3\", operands);
  4617.   arm_output_asm_insn (\"b%D1\\t%l0\", operands);
  4618.   if (GET_CODE (operands[6]) == CONST_INT
  4619.       && !const_ok_for_arm (INTVAL (operands[6])))
  4620.     arm_output_asm_insn (\"cmn\\t%5, #%n6\", operands);
  4621.   else
  4622.     arm_output_asm_insn (\"cmp\\t%5, %6\", operands);
  4623.   if (arm_ccfsm_state == 1 || arm_ccfsm_state == 2)
  4624.   {
  4625.     arm_ccfsm_state += 2;
  4626.     return \"\";
  4627.   }
  4628.   return arm_output_asm_insn (\"b%D4\\t%l0\", operands);
  4629. }"
  4630. [(set_attr "conds" "jump_clob")
  4631.  (set_attr "length" "4")])
  4632.  
  4633. (define_insn ""
  4634.   [(set (match_operand:SI 0 "s_register_operand" "=r")
  4635.     (neg:SI (match_operator 3 "comparison_operator"
  4636.          [(match_operand:SI 1 "s_register_operand" "r")
  4637.           (match_operand:SI 2 "arm_rhs_operand" "rI")])))
  4638.    (clobber (reg 24))]
  4639.   ""
  4640.   "*
  4641.   if (GET_CODE (operands[3]) == LT && operands[3] == const0_rtx)
  4642.     return arm_output_asm_insn (\"mov\\t%0, %1, asr #31\", operands);
  4643.   if (GET_CODE (operands[3]) == NE)
  4644.     {
  4645.       arm_output_asm_insn (\"subs\\t%0, %1, %2\", operands);
  4646.       return arm_output_asm_insn (\"mvnne\\t%0, #0\", operands);
  4647.     }
  4648.   if (GET_CODE (operands[3]) == GT)
  4649.     {
  4650.       arm_output_asm_insn (\"subs\\t%0, %1, %2\", operands);
  4651.       return arm_output_asm_insn (\"mvnne\\t%0, %0, asr #31\", operands);
  4652.     }
  4653.   arm_output_asm_insn (\"cmp\\t%1, %2\", operands);
  4654.   arm_output_asm_insn (\"mov%D3\\t%0, #0\", operands);
  4655.   return arm_output_asm_insn (\"mvn%d3\\t%0, #0\", operands);
  4656. "
  4657. [(set_attr "conds" "clob")
  4658.  (set_attr "length" "3")])
  4659.  
  4660. (define_insn "movcond"
  4661.   [(set (match_operand:SI 0 "s_register_operand" "=r,r,r")
  4662.     (if_then_else:SI (match_operator 5 "comparison_operator"
  4663.               [(match_operand:SI 3 "s_register_operand" "r,r,r")
  4664.                (match_operand:SI 4 "arm_add_operand" "rL,rL,rL")])
  4665.              (match_operand:SI 1 "arm_rhs_operand" "0,rI,?rI")
  4666.              (match_operand:SI 2 "arm_rhs_operand" "rI,0,rI")))
  4667.    (clobber (reg 24))]
  4668.   ""
  4669.   "*
  4670.   if (GET_CODE (operands[5]) == LT
  4671.       && (operands[4] == const0_rtx))
  4672.     {
  4673.       if (which_alternative != 1 && GET_CODE (operands[4]) == REG)
  4674.     {
  4675.       arm_output_asm_insn (\"ands\\t%0, %1, %3, asr #32\", operands);
  4676.       if (operands[2] == const0_rtx)
  4677.         return \"\";
  4678.       return arm_output_asm_insn (\"movcc\\t%0, %2\", operands);
  4679.     }
  4680.       else if (which_alternative != 0 && GET_CODE (operands[2]) == REG)
  4681.     {
  4682.       arm_output_asm_insn (\"bics\\t%0, %2, %3, asr #32\", operands);
  4683.       if (operands[1] == const0_rtx)
  4684.         return \"\";
  4685.       return arm_output_asm_insn (\"movcs\\t%0, %1\", operands);
  4686.     }
  4687.       /* The only case that falls through to here is when both ops 1 & 2
  4688.      are constants */
  4689.     }
  4690.   if (GET_CODE (operands[5]) == GE
  4691.       && (operands[4] == const0_rtx))
  4692.     {
  4693.       if (which_alternative != 1 && GET_CODE (operands[1]) == REG)
  4694.     {
  4695.       arm_output_asm_insn (\"bics\\t%0, %1, %3, asr #32\", operands);
  4696.       if (operands[2] == const0_rtx)
  4697.         return \"\";
  4698.       return arm_output_asm_insn (\"movcs\\t%0, %2\", operands);
  4699.     }
  4700.       else if (which_alternative != 0 && GET_CODE (operands[2]) == REG)
  4701.     {
  4702.       arm_output_asm_insn (\"ands\\t%0, %2, %3, asr #32\", operands);
  4703.       if (operands[1] == const0_rtx)
  4704.         return \"\";
  4705.       return arm_output_asm_insn (\"movcc\\t%0, %1\", operands);
  4706.     }
  4707.       /* The only case that falls through to here is when both ops 1 & 2
  4708.      are constants */
  4709.     }
  4710.   if (GET_CODE (operands[4]) == CONST_INT
  4711.       && !const_ok_for_arm (INTVAL (operands[4])))
  4712.     arm_output_asm_insn (\"cmn\\t%3, #%n4\", operands);
  4713.   else
  4714.     arm_output_asm_insn (\"cmp\\t%3, %4\", operands);
  4715.   if (which_alternative != 0)
  4716.     arm_output_asm_insn (\"mov%d5\\t%0, %1\", operands);
  4717.   if (which_alternative != 1)
  4718.     arm_output_asm_insn (\"mov%D5\\t%0, %2\", operands);
  4719.   return \"\";
  4720. "
  4721. [(set_attr "conds" "clob")
  4722.  (set_attr "length" "2,2,3")])
  4723.  
  4724. (define_insn ""
  4725.   [(set (match_operand:SI 0 "s_register_operand" "=r")
  4726.     (if_then_else:SI (match_operator 9 "comparison_operator"
  4727.               [(match_operand:SI 5 "s_register_operand" "r")
  4728.                (match_operand:SI 6 "arm_add_operand" "rL")])
  4729.              (match_operator:SI 8 "shiftable_operator"
  4730.               [(match_operand:SI 1 "s_register_operand" "r")
  4731.                (match_operand:SI 2 "arm_rhs_operand" "rI")])
  4732.              (match_operator:SI 7 "shiftable_operator"
  4733.               [(match_operand:SI 3 "s_register_operand" "r")
  4734.                (match_operand:SI 4 "arm_rhs_operand" "rI")])))
  4735.    (clobber (reg 24))]
  4736.   ""
  4737.   "*
  4738. {
  4739.   char pattern[100];
  4740.  
  4741.   if (GET_CODE (operands[6]) == CONST_INT
  4742.       && !const_ok_for_arm (INTVAL (operands[6])))
  4743.     arm_output_asm_insn (\"cmn\\t%5, #%n6\", operands);
  4744.   else
  4745.     arm_output_asm_insn (\"cmp\\t%5, %6\", operands);
  4746.   sprintf (pattern, \"%s%%d9\\t%%0, %%1, %%2\", arithmetic_instr (operands[8],
  4747.                                   FALSE));
  4748.   arm_output_asm_insn (pattern, operands);
  4749.   sprintf (pattern, \"%s%%D9\\t%%0, %%3, %%4\", arithmetic_instr (operands[7],
  4750.                                   FALSE));
  4751.   return arm_output_asm_insn (pattern, operands);
  4752. }
  4753. "
  4754. [(set_attr "conds" "clob")
  4755.  (set_attr "length" "3")])
  4756.  
  4757. (define_insn ""
  4758.   [(set (match_operand:SI 0 "s_register_operand" "=r,r")
  4759.     (if_then_else:SI (match_operator 6 "comparison_operator"
  4760.               [(match_operand:SI 2 "s_register_operand" "r,r")
  4761.                (match_operand:SI 3 "arm_add_operand" "rL,rL")])
  4762.              (match_operator:SI 7 "shiftable_operator"
  4763.               [(match_operand:SI 4 "s_register_operand" "r,r")
  4764.                (match_operand:SI 5 "arm_rhs_operand" "rI,rI")])
  4765.              (match_operand:SI 1 "arm_rhsm_operand" "0,?rIm")))
  4766.    (clobber (reg 24))]
  4767.   ""
  4768.   "*
  4769. {
  4770.   char pattern[100];
  4771.  
  4772.   /* If we have an operation where (op x 0) is the identity operation and
  4773.      the condtional operator is LT or GE and we are comparing against zero and
  4774.      everything is in registers then we can do this in two instructions */
  4775.   if (operands[3] == const0_rtx
  4776.       && GET_CODE (operands[7]) != AND
  4777.       && GET_CODE (operands[5]) == REG
  4778.       && GET_CODE (operands[1]) == REG 
  4779.       && REGNO (operands[1]) == REGNO (operands[4])
  4780.       && REGNO (operands[4]) != REGNO (operands[0]))
  4781.     {
  4782.       if (GET_CODE (operands[6]) == LT)
  4783.     {
  4784.       arm_output_asm_insn (\"and\\t%0, %5, %2, asr #31\", operands);
  4785.       sprintf (pattern, \"%s\\t%%0, %%4, %%0\",
  4786.            arithmetic_instr (operands[7], FALSE));
  4787.       return arm_output_asm_insn (pattern, operands);
  4788.         }
  4789.       else if (GET_CODE (operands[6]) == GE)
  4790.     {
  4791.       arm_output_asm_insn (\"bic\\t%0, %5, %2, asr #31\", operands);
  4792.       sprintf (pattern, \"%s\\t%%0, %%4, %%0\",
  4793.            arithmetic_instr (operands[7], FALSE));
  4794.       return arm_output_asm_insn (pattern, operands);
  4795.         }
  4796.     }
  4797.   if (GET_CODE (operands[3]) == CONST_INT
  4798.       && !const_ok_for_arm (INTVAL (operands[3])))
  4799.     arm_output_asm_insn (\"cmn\\t%2, #%n3\", operands);
  4800.   else
  4801.     arm_output_asm_insn (\"cmp\\t%2, %3\", operands);
  4802.   sprintf (pattern, \"%s%%d6\\t%%0, %%4, %%5\", arithmetic_instr (operands[7],
  4803.                                   FALSE));
  4804.   arm_output_asm_insn (pattern, operands);
  4805.   if (which_alternative != 0)
  4806.     {
  4807.       if (GET_CODE (operands[1]) == MEM)
  4808.     arm_output_asm_insn (\"ldr%D6\\t%0, %1\", operands);
  4809.       else
  4810.     arm_output_asm_insn (\"mov%D6\\t%0, %1\", operands);
  4811.     }
  4812.   return \"\";
  4813. }
  4814. "
  4815. [(set_attr "conds" "clob")
  4816.  (set_attr "length" "2,3")])
  4817.  
  4818. (define_insn ""
  4819.   [(set (match_operand:SI 0 "s_register_operand" "=r,r")
  4820.     (if_then_else:SI (match_operator 6 "comparison_operator"
  4821.               [(match_operand:SI 4 "s_register_operand" "r,r")
  4822.                (match_operand:SI 5 "arm_add_operand" "rL,rL")])
  4823.              (match_operand:SI 1 "arm_rhsm_operand" "0,?rIm")
  4824.              (match_operator:SI 7 "shiftable_operator"
  4825.               [(match_operand:SI 2 "s_register_operand" "r,r")
  4826.                (match_operand:SI 3 "arm_rhs_operand" "rI,rI")])))
  4827.    (clobber (reg 24))]
  4828.   ""
  4829.   "*
  4830. {
  4831.   char pattern[100];
  4832.  
  4833.   /* If we have an operation where (op x 0) is the identity operation and
  4834.      the condtional operator is LT or GE and we are comparing against zero and
  4835.      everything is in registers then we can do this in two instructions */
  4836.   if (operands[5] == const0_rtx
  4837.       && GET_CODE (operands[7]) != AND
  4838.       && GET_CODE (operands[3]) == REG
  4839.       && GET_CODE (operands[1]) == REG 
  4840.       && REGNO (operands[1]) == REGNO (operands[2])
  4841.       && REGNO (operands[2]) != REGNO (operands[0]))
  4842.     {
  4843.       if (GET_CODE (operands[6]) == GE)
  4844.     {
  4845.       arm_output_asm_insn (\"and\\t%0, %3, %4, asr #31\", operands);
  4846.       sprintf (pattern, \"%s\\t%%0, %%2, %%0\",
  4847.            arithmetic_instr (operands[7], FALSE));
  4848.       return arm_output_asm_insn (pattern, operands);
  4849.         }
  4850.       else if (GET_CODE (operands[6]) == LT)
  4851.     {
  4852.       arm_output_asm_insn (\"bic\\t%0, %3, %4, asr #31\", operands);
  4853.       sprintf (pattern, \"%s\\t%%0, %%2, %%0\",
  4854.            arithmetic_instr (operands[7], FALSE));
  4855.       return arm_output_asm_insn (pattern, operands);
  4856.         }
  4857.     }
  4858.   if (GET_CODE (operands[5]) == CONST_INT
  4859.       && !const_ok_for_arm (INTVAL (operands[5])))
  4860.     arm_output_asm_insn (\"cmn\\t%4, #%n5\", operands);
  4861.   else
  4862.     arm_output_asm_insn (\"cmp\\t%4, %5\", operands);
  4863.   if (which_alternative != 0)
  4864.     {
  4865.       if (GET_CODE (operands[1]) == MEM)
  4866.     arm_output_asm_insn (\"ldr%d6\\t%0, %1\", operands);
  4867.       else
  4868.     arm_output_asm_insn (\"mov%d6\\t%0, %1\", operands);
  4869.     }
  4870.   sprintf (pattern, \"%s%%D6\\t%%0, %%2, %%3\", arithmetic_instr (operands[7],
  4871.                                   FALSE));
  4872.   return arm_output_asm_insn (pattern, operands);
  4873. }
  4874. "
  4875. [(set_attr "conds" "clob")
  4876.  (set_attr "length" "2,3")])
  4877.  
  4878. (define_insn ""
  4879.   [(set (match_operand:SI 0 "s_register_operand" "=r,r")
  4880.     (if_then_else:SI (match_operator 6 "comparison_operator"
  4881.               [(match_operand:SI 4 "s_register_operand" "r,r")
  4882.                (match_operand:SI 5 "arm_add_operand" "rL,rL")])
  4883.              (plus:SI
  4884.               (match_operand:SI 2 "s_register_operand" "r,r")
  4885.               (match_operand:SI 3 "arm_add_operand" "rL,rL"))
  4886.              (match_operand:SI 1 "arm_rhsm_operand" "0,?rIm")))
  4887.    (clobber (reg 24))]
  4888.   ""
  4889.   "*
  4890. {
  4891.   if (GET_CODE (operands[5]) == CONST_INT
  4892.       && !const_ok_for_arm (INTVAL (operands[5])))
  4893.     arm_output_asm_insn (\"cmn\\t%4, #%n5\", operands);
  4894.   else
  4895.     arm_output_asm_insn (\"cmp\\t%4, %5\", operands);
  4896.   if (GET_CODE (operands[3]) == CONST_INT
  4897.       && !const_ok_for_arm (INTVAL (operands[3])))
  4898.     arm_output_asm_insn (\"sub%d6\\t%0, %2, #%n3\", operands);
  4899.   else
  4900.     arm_output_asm_insn (\"add%d6\\t%0, %2, %3\", operands);
  4901.   if (which_alternative != 0)
  4902.     {
  4903.       if (GET_CODE (operands[1]) == MEM)
  4904.     arm_output_asm_insn (\"ldr%D6\\t%0, %1\", operands);
  4905.       else
  4906.     arm_output_asm_insn (\"mov%D6\\t%0, %1\", operands);
  4907.     }
  4908.   return \"\";
  4909. }
  4910. "
  4911. [(set_attr "conds" "clob")
  4912.  (set_attr "length" "2,3")])
  4913.  
  4914. (define_insn ""
  4915.   [(set (match_operand:SI 0 "s_register_operand" "=r,r")
  4916.     (if_then_else:SI (match_operator 6 "comparison_operator"
  4917.               [(match_operand:SI 4 "s_register_operand" "r,r")
  4918.                (match_operand:SI 5 "arm_add_operand" "rL,rL")])
  4919.              (match_operand:SI 1 "arm_rhsm_operand" "0,?rIm")
  4920.              (plus:SI
  4921.               (match_operand:SI 2 "s_register_operand" "r,r")
  4922.               (match_operand:SI 3 "arm_add_operand" "rL,rL"))))
  4923.    (clobber (reg 24))]
  4924.   ""
  4925.   "*
  4926. {
  4927.   if (GET_CODE (operands[5]) == CONST_INT
  4928.       && !const_ok_for_arm (INTVAL (operands[5])))
  4929.     arm_output_asm_insn (\"cmn\\t%4, #%n5\", operands);
  4930.   else
  4931.     arm_output_asm_insn (\"cmp\\t%4, %5\", operands);
  4932.   if (GET_CODE (operands[3]) == CONST_INT
  4933.       && !const_ok_for_arm (INTVAL (operands[3])))
  4934.     arm_output_asm_insn (\"sub%D6\\t%0, %2, #%n3\", operands);
  4935.   else
  4936.     arm_output_asm_insn (\"add%D6\\t%0, %2, %3\", operands);
  4937.   if (which_alternative != 0)
  4938.     {
  4939.       if (GET_CODE (operands[6]) == MEM)
  4940.     arm_output_asm_insn (\"ldr%d6\\t%0, %1\", operands);
  4941.       else
  4942.     arm_output_asm_insn (\"mov%d6\\t%0, %1\", operands);
  4943.     }
  4944.   return \"\";
  4945. }
  4946. "
  4947. [(set_attr "conds" "clob")
  4948.  (set_attr "length" "2,3")])
  4949.  
  4950. (define_insn ""
  4951.   [(set (match_operand:SI 0 "s_register_operand" "=r,r")
  4952.     (if_then_else:SI (match_operator 5 "comparison_operator"
  4953.               [(match_operand:SI 3 "s_register_operand" "r,r")
  4954.                (match_operand:SI 4 "arm_add_operand" "rL,rL")])
  4955.              (match_operand:SI 1 "arm_rhs_operand" "0,?rI")
  4956.              (not:SI
  4957.               (match_operand:SI 2 "s_register_operand" "r,r"))))
  4958.    (clobber (reg 24))]
  4959.   ""
  4960.   "#"
  4961. [(set_attr "conds" "clob")
  4962.  (set_attr "length" "2,3")])
  4963.  
  4964. ;;  if (GET_CODE (operands[3]) == CONST_INT
  4965. ;;      && !const_ok_for_arm (INTVAL (operands[3])))
  4966. ;;    arm_output_asm_insn (\"cmn\\t%2, #%n3\", operands);
  4967. ;;  else
  4968. ;;    arm_output_asm_insn (\"cmp\\t%2, %3\", operands);
  4969. ;;  if (which_alternative != 0)
  4970. ;;    arm_output_asm_insn (\"mov%d1\\t%0, %4\", operands);
  4971. ;;  return arm_output_asm_insn (\"mvn%D1\\t%0, %5\", operands);
  4972.  
  4973. (define_insn ""
  4974.   [(set (match_operand:SI 0 "s_register_operand" "=r,r")
  4975.     (if_then_else:SI (match_operator 5 "comparison_operator"
  4976.               [(match_operand:SI 3 "s_register_operand" "r,r")
  4977.                (match_operand:SI 4 "arm_add_operand" "rL,rL")])
  4978.              (not:SI
  4979.               (match_operand:SI 2 "s_register_operand" "r,r"))
  4980.              (match_operand:SI 1 "arm_rhs_operand" "0,?rI")))
  4981.    (clobber (reg 24))]
  4982.   ""
  4983.   "*
  4984. {
  4985.   char pattern[100];
  4986.  
  4987.   if (GET_CODE (operands[30]) == CONST_INT
  4988.       && !const_ok_for_arm (INTVAL (operands[4])))
  4989.     arm_output_asm_insn (\"cmn\\t%3, #%n4\", operands);
  4990.   else
  4991.     arm_output_asm_insn (\"cmp\\t%3, %4\", operands);
  4992.   if (which_alternative != 0)
  4993.     arm_output_asm_insn (\"mov%D5\\t%0, %1\", operands);
  4994.   return arm_output_asm_insn (\"mvn%d5\\t%0, %2\", operands);
  4995.  
  4996. }
  4997. "
  4998. [(set_attr "conds" "clob")
  4999.  (set_attr "length" "2,3")])
  5000.  
  5001. (define_insn ""
  5002.   [(set (match_operand:SI 0 "s_register_operand" "=r,r")
  5003.     (if_then_else:SI (match_operator 6 "comparison_operator"
  5004.               [(match_operand:SI 4 "s_register_operand" "r,r")
  5005.                (match_operand:SI 5 "arm_add_operand" "rL,rL")])
  5006.              (match_operator:SI 7 "shift_operator"
  5007.               [(match_operand:SI 2 "s_register_operand" "r,r")
  5008.                (match_operand:SI 3 "arm_rhs_operand" "rn,rn")])
  5009.              (match_operand:SI 1 "arm_rhs_operand" "0,?rI")))
  5010.    (clobber (reg 24))]
  5011.   ""
  5012.   "*
  5013. {
  5014.   char pattern[100];
  5015.  
  5016.   if (GET_CODE (operands[5]) == CONST_INT
  5017.       && !const_ok_for_arm (INTVAL (operands[5])))
  5018.     arm_output_asm_insn (\"cmn\\t%4, #%n5\", operands);
  5019.   else
  5020.     arm_output_asm_insn (\"cmp\\t%4, %5\", operands);
  5021.   if (which_alternative != 0)
  5022.     arm_output_asm_insn (\"mov%D6\\t%0, %1\", operands);
  5023.   sprintf (pattern, \"mov%%d6\\t%%0, %%2, %s %%3\", 
  5024.        shift_instr (GET_CODE (operands[7]), &operands[3]));
  5025.   return arm_output_asm_insn (pattern, operands);
  5026. }
  5027. "
  5028. [(set_attr "conds" "clob")
  5029.  (set_attr "length" "2,3")])
  5030.  
  5031. (define_insn ""
  5032.   [(set (match_operand:SI 0 "s_register_operand" "=r,r")
  5033.     (if_then_else:SI (match_operator 6 "comparison_operator"
  5034.               [(match_operand:SI 4 "s_register_operand" "r,r")
  5035.                (match_operand:SI 5 "arm_add_operand" "rL,rL")])
  5036.              (match_operand:SI 1 "arm_rhs_operand" "0,?rI")
  5037.              (match_operator:SI 7 "shift_operator"
  5038.               [(match_operand:SI 2 "s_register_operand" "r,r")
  5039.                (match_operand:SI 3 "arm_rhs_operand" "rn,rn")])))
  5040.    (clobber (reg 24))]
  5041.   ""
  5042.   "*
  5043. {
  5044.   char pattern[100];
  5045.  
  5046.   if (GET_CODE (operands[5]) == CONST_INT
  5047.       && !const_ok_for_arm (INTVAL (operands[5])))
  5048.     arm_output_asm_insn (\"cmn\\t%4, #%n5\", operands);
  5049.   else
  5050.     arm_output_asm_insn (\"cmp\\t%4, %5\", operands);
  5051.   if (which_alternative != 0)
  5052.     arm_output_asm_insn (\"mov%d6\\t%0, %1\", operands);
  5053.   sprintf (pattern, \"mov%%D6\\t%%0, %%2, %s %%3\", 
  5054.        shift_instr (GET_CODE (operands[7]), &operands[3]));
  5055.   return arm_output_asm_insn (pattern, operands);
  5056. }
  5057. "
  5058. [(set_attr "conds" "clob")
  5059.  (set_attr "length" "2,3")])
  5060.  
  5061. (define_insn ""
  5062.   [(set (match_operand:SI 0 "s_register_operand" "=r")
  5063.     (if_then_else:SI (match_operator 7 "comparison_operator"
  5064.               [(match_operand:SI 5 "s_register_operand" "r")
  5065.                (match_operand:SI 6 "arm_add_operand" "rL")])
  5066.              (match_operator:SI 8 "shift_operator"
  5067.               [(match_operand:SI 1 "s_register_operand" "r")
  5068.                (match_operand:SI 2 "arm_rhs_operand" "rn")])
  5069.              (match_operator:SI 9 "shift_operator"
  5070.               [(match_operand:SI 3 "s_register_operand" "r")
  5071.                (match_operand:SI 4 "arm_rhs_operand" "rI")])))
  5072.    (clobber (reg 24))]
  5073.   ""
  5074.   "*
  5075. {
  5076.   char pattern[100];
  5077.  
  5078.   if (GET_CODE (operands[6]) == CONST_INT
  5079.       && !const_ok_for_arm (INTVAL (operands[6])))
  5080.     arm_output_asm_insn (\"cmn\\t%5, #%n6\", operands);
  5081.   else
  5082.     arm_output_asm_insn (\"cmp\\t%5, %6\", operands);
  5083.   sprintf (pattern, \"mov%%d7\\t%%0, %%1, %s %%2\", 
  5084.        shift_instr (GET_CODE (operands[8]), &operands[2]));
  5085.   arm_output_asm_insn (pattern, operands);
  5086.   sprintf (pattern, \"mov%%D7\\t%%0, %%3, %s %%4\", 
  5087.        shift_instr (GET_CODE (operands[9]), &operands[4]));
  5088.   return arm_output_asm_insn (pattern, operands);
  5089. }
  5090. "
  5091. [(set_attr "conds" "clob")
  5092.  (set_attr "length" "3")])
  5093.  
  5094. (define_insn ""
  5095.   [(set (match_operand:SI 0 "s_register_operand" "=r")
  5096.     (if_then_else:SI (match_operator 6 "comparison_operator"
  5097.               [(match_operand:SI 4 "s_register_operand" "r")
  5098.                (match_operand:SI 5 "arm_add_operand" "rL")])
  5099.              (not:SI (match_operand:SI 1 "s_register_operand" "r"))
  5100.              (match_operator:SI 7 "shiftable_operator"
  5101.               [(match_operand:SI 2 "s_register_operand" "r")
  5102.                (match_operand:SI 3 "arm_rhs_operand" "rI")])))
  5103.    (clobber (reg 24))]
  5104.   ""
  5105.   "*
  5106. {
  5107.   char pattern[100];
  5108.  
  5109.   if (GET_CODE (operands[5]) == CONST_INT
  5110.       && !const_ok_for_arm (INTVAL (operands[5])))
  5111.     arm_output_asm_insn (\"cmn\\t%4, #%n5\", operands);
  5112.   else
  5113.     arm_output_asm_insn (\"cmp\\t%4, %5\", operands);
  5114.   arm_output_asm_insn (\"mvn%d6\\t%0, %1\", operands);
  5115.   sprintf (pattern, \"%s%%D6\\t%%0, %%2, %%3\", arithmetic_instr (operands[7],
  5116.                                   FALSE));
  5117.   return arm_output_asm_insn (pattern, operands);
  5118. }
  5119. "
  5120. [(set_attr "conds" "clob")
  5121.  (set_attr "length" "3")])
  5122.  
  5123. (define_insn ""
  5124.   [(set (match_operand:SI 0 "s_register_operand" "=r")
  5125.     (if_then_else:SI (match_operator 6 "comparison_operator"
  5126.               [(match_operand:SI 4 "s_register_operand" "r")
  5127.                (match_operand:SI 5 "arm_add_operand" "rL")])
  5128.              (match_operator:SI 7 "shiftable_operator"
  5129.               [(match_operand:SI 2 "s_register_operand" "r")
  5130.                (match_operand:SI 3 "arm_rhs_operand" "rI")])
  5131.              (not:SI (match_operand:SI 1 "s_register_operand" "r"))))
  5132.    (clobber (reg 24))]
  5133.   ""
  5134.   "*
  5135. {
  5136.   char pattern[100];
  5137.  
  5138.   if (GET_CODE (operands[5]) == CONST_INT
  5139.       && !const_ok_for_arm (INTVAL (operands[5])))
  5140.     arm_output_asm_insn (\"cmn\\t%4, #%n5\", operands);
  5141.   else
  5142.     arm_output_asm_insn (\"cmp\\t%4, %5\", operands);
  5143.   arm_output_asm_insn (\"mvn%D6\\t%0, %1\", operands);
  5144.   sprintf (pattern, \"%s%%d6\\t%%0, %%2, %%3\", arithmetic_instr (operands[7],
  5145.                                   FALSE));
  5146.   return arm_output_asm_insn (pattern, operands);
  5147. }
  5148. "
  5149. [(set_attr "conds" "clob")
  5150.  (set_attr "length" "3")])
  5151.  
  5152. (define_insn ""
  5153.   [(set (match_operand:SI 0 "s_register_operand" "=r,r")
  5154.     (if_then_else:SI (match_operator 5 "comparison_operator"
  5155.               [(match_operand:SI 3 "s_register_operand" "r,r")
  5156.                (match_operand:SI 4 "arm_add_operand" "rL,rL")])
  5157.              (neg:SI
  5158.               (match_operand:SI 2 "s_register_operand" "r,r"))
  5159.              (match_operand:SI 1 "arm_rhs_operand" "0,?rI")))
  5160.    (clobber (reg:CC 24))]
  5161.   ""
  5162.   "*
  5163.   if (GET_CODE (operands[4]) == CONST_INT
  5164.       && !const_ok_for_arm (INTVAL (operands[4])))
  5165.     arm_output_asm_insn (\"cmn\\t%3, #%n4\", operands);
  5166.   else
  5167.     arm_output_asm_insn (\"cmp\\t%3, %4\", operands);
  5168.   if (which_alternative != 0)
  5169.     arm_output_asm_insn (\"mov%D5\\t%0, %1\", operands);
  5170.   return arm_output_asm_insn (\"rsb%d5\\t%0, %2, #0\", operands);
  5171. "
  5172. [(set_attr "conds" "clob")
  5173.  (set_attr "length" "2,3")])
  5174.  
  5175. (define_insn ""
  5176.   [(set (match_operand:SI 0 "s_register_operand" "=r,r")
  5177.     (if_then_else:SI (match_operator 5 "comparison_operator"
  5178.               [(match_operand:SI 3 "s_register_operand" "r,r")
  5179.                (match_operand:SI 4 "arm_add_operand" "rL,rL")])
  5180.              (match_operand:SI 1 "arm_rhs_operand" "0,?rI")
  5181.              (neg:SI
  5182.               (match_operand:SI 2 "s_register_operand" "r,r"))))
  5183.    (clobber (reg:CC 24))]
  5184.   ""
  5185.   "*
  5186.   if (GET_CODE (operands[4]) == CONST_INT
  5187.       && !const_ok_for_arm (INTVAL (operands[4])))
  5188.     arm_output_asm_insn (\"cmn\\t%3, #%n4\", operands);
  5189.   else
  5190.     arm_output_asm_insn (\"cmp\\t%3, %4\", operands);
  5191.   if (which_alternative != 0)
  5192.     arm_output_asm_insn (\"mov%d5\\t%0, %1\", operands);
  5193.   return arm_output_asm_insn (\"rsb%D5\\t%0, %2, #0\", operands);
  5194. "
  5195. [(set_attr "conds" "clob")
  5196.  (set_attr "length" "2,3")])
  5197.  
  5198. (define_insn ""
  5199.   [(set (match_operand:SI 0 "s_register_operand" "=r")
  5200.     (match_operator:SI 1 "shiftable_operator"
  5201.      [(match_operand:SI 2 "memory_operand" "m")
  5202.       (match_operand:SI 3 "memory_operand" "m")]))
  5203.    (clobber (match_scratch:SI 4 "=r"))]
  5204.   "adjacent_mem_locations (operands[2], operands[3])"
  5205.   "*
  5206. {
  5207.   rtx ldm[3];
  5208.   rtx arith[3];
  5209.   char pattern[100];
  5210.   int val1 = 0, val2 = 0;
  5211.  
  5212.   sprintf (pattern, \"%s\\t%%0, %%1, %%2\",
  5213.        arithmetic_instr (operands[1], FALSE));
  5214.   if (REGNO (operands[0]) > REGNO (operands[4]))
  5215.     {
  5216.       ldm[1] = operands[4];
  5217.       ldm[2] = operands[0];
  5218.     }
  5219.   else
  5220.     {
  5221.       ldm[1] = operands[0];
  5222.       ldm[2] = operands[4];
  5223.     }
  5224.   if (GET_CODE (XEXP (operands[2], 0)) != REG)
  5225.     val1 = INTVAL (XEXP (XEXP (operands[2], 0), 1));
  5226.   if (GET_CODE (XEXP (operands[3], 0)) != REG)
  5227.     val2 = INTVAL (XEXP (XEXP (operands[3], 0), 1));
  5228.   arith[0] = operands[0];
  5229.   if (val1 < val2)
  5230.     {
  5231.       arith[1] = ldm[1];
  5232.       arith[2] = ldm[2];
  5233.     }
  5234.   else
  5235.     {
  5236.       arith[1] = ldm[2];
  5237.       arith[2] = ldm[1];
  5238.     }
  5239.   if (val1 && val2)
  5240.     {
  5241.       rtx ops[3];
  5242.       ldm[0] = ops[0] = operands[4];
  5243.       ops[1] = XEXP (XEXP (operands[2], 0), 0);
  5244.       ops[2] = XEXP (XEXP (operands[2], 0), 1);
  5245.       output_add_immediate (ops);
  5246.       if (val1 < val2)
  5247.     arm_output_asm_insn (\"ldmia\\t%0, {%1, %2}\", ldm);
  5248.       else
  5249.     arm_output_asm_insn (\"ldmda\\t%0, {%1, %2}\", ldm);
  5250.     }
  5251.   else if (val1)
  5252.     {
  5253.       ldm[0] = XEXP (operands[3], 0);
  5254.       if (val1 < val2)
  5255.     arm_output_asm_insn (\"ldmda\\t%0, {%1, %2}\", ldm);
  5256.       else
  5257.     arm_output_asm_insn (\"ldmia\\t%0, {%1, %2}\", ldm);
  5258.     }
  5259.   else
  5260.     {
  5261.       ldm[0] = XEXP (operands[2], 0);
  5262.       if (val1 < val2)
  5263.     arm_output_asm_insn (\"ldmia\\t%0, {%1, %2}\", ldm);
  5264.       else
  5265.     arm_output_asm_insn (\"ldmda\\t%0, {%1, %2}\", ldm);
  5266.     }
  5267.   return arm_output_asm_insn (pattern, arith);
  5268. }
  5269. "
  5270. [(set_attr "length" "3")
  5271.  (set_attr "type" "load")])
  5272.  
  5273. ;; the arm can support extended pre-inc instructions
  5274.  
  5275. ;; In all these cases, we use operands 0 and 1 for the register being
  5276. ;; incremented because those are the operands that local-alloc will
  5277. ;; tie and these are the pair most likely to be tieable (and the ones
  5278. ;; that will benefit the most).
  5279.  
  5280. ;; We reject the frame pointer if it occurs anywhere in these patterns since
  5281. ;; elimination will cause too many headaches.
  5282.  
  5283. (define_insn ""
  5284.   [(set (mem:QI (plus:SI (match_operand:SI 1 "s_register_operand" "%0")
  5285.              (match_operand:SI 2 "index_operand" "rJ")))
  5286.     (match_operand:QI 3 "s_register_operand" "r"))
  5287.    (set (match_operand:SI 0 "s_register_operand" "=r")
  5288.     (plus:SI (match_dup 1) (match_dup 2)))]
  5289.   "REGNO (operands[0]) != FRAME_POINTER_REGNUM
  5290.    && REGNO (operands[1]) != FRAME_POINTER_REGNUM
  5291.    && (GET_CODE (operands[2]) != REG
  5292.        || REGNO (operands[2]) != FRAME_POINTER_REGNUM)"
  5293.   "*
  5294.   return arm_output_asm_insn (\"strb\\t%3, [%0, %2]!\", operands);
  5295. "
  5296. [(set_attr "type" "store1")])
  5297.  
  5298. (define_insn ""
  5299.   [(set (mem:QI (minus:SI (match_operand:SI 1 "s_register_operand" "0")
  5300.               (match_operand:SI 2 "s_register_operand" "r")))
  5301.     (match_operand:QI 3 "s_register_operand" "r"))
  5302.    (set (match_operand:SI 0 "s_register_operand" "=r")
  5303.     (minus:SI (match_dup 1) (match_dup 2)))]
  5304.   "REGNO (operands[0]) != FRAME_POINTER_REGNUM
  5305.    && REGNO (operands[1]) != FRAME_POINTER_REGNUM
  5306.    && (GET_CODE (operands[2]) != REG
  5307.        || REGNO (operands[2]) != FRAME_POINTER_REGNUM)"
  5308.   "*
  5309.   return arm_output_asm_insn (\"strb\\t%3, [%0, -%2]!\", operands);
  5310. "
  5311. [(set_attr "type" "store1")])
  5312.  
  5313. (define_insn ""
  5314.   [(set (match_operand:QI 3 "s_register_operand" "=r")
  5315.     (mem:QI (plus:SI (match_operand:SI 1 "s_register_operand" "%0")
  5316.              (match_operand:SI 2 "index_operand" "rJ"))))
  5317.    (set (match_operand:SI 0 "s_register_operand" "=r")
  5318.     (plus:SI (match_dup 1) (match_dup 2)))]
  5319.   "REGNO (operands[0]) != FRAME_POINTER_REGNUM
  5320.    && REGNO (operands[1]) != FRAME_POINTER_REGNUM
  5321.    && (GET_CODE (operands[2]) != REG
  5322.        || REGNO (operands[2]) != FRAME_POINTER_REGNUM)"
  5323.   "*
  5324.   return arm_output_asm_insn (\"ldrb\\t%3, [%0, %2]!\", operands);
  5325. "
  5326. [(set_attr "type" "load")])
  5327.  
  5328. (define_insn ""
  5329.   [(set (match_operand:QI 3 "s_register_operand" "=r")
  5330.     (mem:QI (minus:SI (match_operand:SI 1 "s_register_operand" "0")
  5331.               (match_operand:SI 2 "s_register_operand" "r"))))
  5332.    (set (match_operand:SI 0 "s_register_operand" "=r")
  5333.     (minus:SI (match_dup 1) (match_dup 2)))]
  5334.   "REGNO (operands[0]) != FRAME_POINTER_REGNUM
  5335.    && REGNO (operands[1]) != FRAME_POINTER_REGNUM
  5336.    && (GET_CODE (operands[2]) != REG
  5337.        || REGNO (operands[2]) != FRAME_POINTER_REGNUM)"
  5338.   "*
  5339.   return arm_output_asm_insn (\"ldrb\\t%3, [%0, -%2]!\", operands);
  5340. "
  5341. [(set_attr "type" "load")])
  5342.  
  5343. (define_insn ""
  5344.   [(set (match_operand:SI 3 "s_register_operand" "=r")
  5345.     (zero_extend:SI
  5346.      (mem:QI (plus:SI (match_operand:SI 1 "s_register_operand" "%0")
  5347.               (match_operand:SI 2 "index_operand" "rJ")))))
  5348.    (set (match_operand:SI 0 "s_register_operand" "=r")
  5349.     (plus:SI (match_dup 1) (match_dup 2)))]
  5350.   "REGNO (operands[0]) != FRAME_POINTER_REGNUM
  5351.    && REGNO (operands[1]) != FRAME_POINTER_REGNUM
  5352.    && (GET_CODE (operands[2]) != REG
  5353.        || REGNO (operands[2]) != FRAME_POINTER_REGNUM)"
  5354.   "*
  5355.   return arm_output_asm_insn (\"ldrb\\t%3, [%0, %2]!\\t@ z_extendqisi\",
  5356.                   operands);
  5357. "
  5358. [(set_attr "type" "load")])
  5359.  
  5360. (define_insn ""
  5361.   [(set (match_operand:SI 3 "s_register_operand" "=r")
  5362.     (zero_extend:SI
  5363.      (mem:QI (minus:SI (match_operand:SI 1 "s_register_operand" "0")
  5364.                (match_operand:SI 2 "s_register_operand" "r")))))
  5365.    (set (match_operand:SI 0 "s_register_operand" "=r")
  5366.     (minus:SI (match_dup 1) (match_dup 2)))]
  5367.   "REGNO (operands[0]) != FRAME_POINTER_REGNUM
  5368.    && REGNO (operands[1]) != FRAME_POINTER_REGNUM
  5369.    && (GET_CODE (operands[2]) != REG
  5370.        || REGNO (operands[2]) != FRAME_POINTER_REGNUM)"
  5371.   "*
  5372.   return arm_output_asm_insn (\"ldrb\\t%3, [%0, -%2]!\\t@ z_extendqisi\",
  5373.                   operands);
  5374. "
  5375. [(set_attr "type" "load")])
  5376.  
  5377. (define_insn ""
  5378.   [(set (mem:SI (plus:SI (match_operand:SI 1 "s_register_operand" "%0")
  5379.              (match_operand:SI 2 "index_operand" "rJ")))
  5380.     (match_operand:SI 3 "s_register_operand" "r"))
  5381.    (set (match_operand:SI 0 "s_register_operand" "=r")
  5382.     (plus:SI (match_dup 1) (match_dup 2)))]
  5383.   "REGNO (operands[0]) != FRAME_POINTER_REGNUM
  5384.    && REGNO (operands[1]) != FRAME_POINTER_REGNUM
  5385.    && (GET_CODE (operands[2]) != REG
  5386.        || REGNO (operands[2]) != FRAME_POINTER_REGNUM)"
  5387.   "*
  5388.   return arm_output_asm_insn (\"str\\t%3, [%0, %2]!\", operands);
  5389. "
  5390. [(set_attr "type" "store1")])
  5391.  
  5392. (define_insn ""
  5393.   [(set (mem:SI (minus:SI (match_operand:SI 1 "s_register_operand" "0")
  5394.               (match_operand:SI 2 "s_register_operand" "r")))
  5395.     (match_operand:SI 3 "s_register_operand" "r"))
  5396.    (set (match_operand:SI 0 "s_register_operand" "=r")
  5397.     (minus:SI (match_dup 1) (match_dup 2)))]
  5398.   "REGNO (operands[0]) != FRAME_POINTER_REGNUM
  5399.    && REGNO (operands[1]) != FRAME_POINTER_REGNUM
  5400.    && (GET_CODE (operands[2]) != REG
  5401.        || REGNO (operands[2]) != FRAME_POINTER_REGNUM)"
  5402.   "*
  5403.   return arm_output_asm_insn (\"str\\t%3, [%0, -%2]!\", operands);
  5404. "
  5405. [(set_attr "type" "store1")])
  5406.  
  5407. (define_insn ""
  5408.   [(set (match_operand:SI 3 "s_register_operand" "=r")
  5409.     (mem:SI (plus:SI (match_operand:SI 1 "s_register_operand" "%0")
  5410.              (match_operand:SI 2 "index_operand" "rJ"))))
  5411.    (set (match_operand:SI 0 "s_register_operand" "=r")
  5412.     (plus:SI (match_dup 1) (match_dup 2)))]
  5413.   "REGNO (operands[0]) != FRAME_POINTER_REGNUM
  5414.    && REGNO (operands[1]) != FRAME_POINTER_REGNUM
  5415.    && (GET_CODE (operands[2]) != REG
  5416.        || REGNO (operands[2]) != FRAME_POINTER_REGNUM)"
  5417.   "*
  5418.   return arm_output_asm_insn (\"ldr\\t%3, [%0, %2]!\", operands);
  5419. "
  5420. [(set_attr "type" "load")])
  5421.  
  5422. (define_insn ""
  5423.   [(set (match_operand:SI 3 "s_register_operand" "=r")
  5424.     (mem:SI (minus:SI (match_operand:SI 1 "s_register_operand" "0")
  5425.               (match_operand:SI 2 "s_register_operand" "r"))))
  5426.    (set (match_operand:SI 0 "s_register_operand" "=r")
  5427.     (minus:SI (match_dup 1) (match_dup 2)))]
  5428.   "REGNO (operands[0]) != FRAME_POINTER_REGNUM
  5429.    && REGNO (operands[1]) != FRAME_POINTER_REGNUM
  5430.    && (GET_CODE (operands[2]) != REG
  5431.        || REGNO (operands[2]) != FRAME_POINTER_REGNUM)"
  5432.   "*
  5433.   return arm_output_asm_insn (\"ldr\\t%3, [%0, -%2]!\", operands);
  5434. "
  5435. [(set_attr "type" "load")])
  5436.  
  5437. (define_insn ""
  5438.   [(set (match_operand:HI 3 "s_register_operand" "=r")
  5439.     (mem:HI (plus:SI (match_operand:SI 1 "s_register_operand" "%0")
  5440.              (match_operand:SI 2 "index_operand" "rJ"))))
  5441.    (set (match_operand:SI 0 "s_register_operand" "=r")
  5442.     (plus:SI (match_dup 1) (match_dup 2)))]
  5443.   "REGNO (operands[0]) != FRAME_POINTER_REGNUM
  5444.    && REGNO (operands[1]) != FRAME_POINTER_REGNUM
  5445.    && (GET_CODE (operands[2]) != REG
  5446.        || REGNO (operands[2]) != FRAME_POINTER_REGNUM)"
  5447.   "*
  5448.   return arm_output_asm_insn (\"ldr\\t%3, [%0, %2]!\\t@ loadhi\", operands);
  5449. "
  5450. [(set_attr "type" "load")])
  5451.  
  5452. (define_insn ""
  5453.   [(set (match_operand:HI 3 "s_register_operand" "=r")
  5454.     (mem:HI (minus:SI (match_operand:SI 1 "s_register_operand" "0")
  5455.               (match_operand:SI 2 "s_register_operand" "r"))))
  5456.    (set (match_operand:SI 0 "s_register_operand" "=r")
  5457.     (minus:SI (match_dup 1) (match_dup 2)))]
  5458.   "REGNO (operands[0]) != FRAME_POINTER_REGNUM
  5459.    && REGNO (operands[1]) != FRAME_POINTER_REGNUM
  5460.    && (GET_CODE (operands[2]) != REG
  5461.        || REGNO (operands[2]) != FRAME_POINTER_REGNUM)"
  5462.   "*
  5463.   return arm_output_asm_insn (\"ldr\\t%3, [%0, -%2]!\\t@ loadhi\", operands);
  5464. "
  5465. [(set_attr "type" "load")])
  5466.  
  5467. (define_insn ""
  5468.   [(set (mem:QI (plus:SI (match_operator:SI 2 "shift_operator"
  5469.               [(match_operand:SI 3 "s_register_operand" "r")
  5470.                (match_operand:SI 4 "const_shift_operand" "n")])
  5471.              (match_operand:SI 1 "s_register_operand" "0")))
  5472.     (match_operand:QI 5 "s_register_operand" "r"))
  5473.    (set (match_operand:SI 0 "s_register_operand" "=r")
  5474.     (plus:SI (match_op_dup 2 [(match_dup 3)    (match_dup 4)])
  5475.          (match_dup 1)))]
  5476.   "REGNO (operands[0]) != FRAME_POINTER_REGNUM
  5477.    && REGNO (operands[1]) != FRAME_POINTER_REGNUM
  5478.    && REGNO (operands[3]) != FRAME_POINTER_REGNUM"
  5479.   "*
  5480. {
  5481.   char instr[100];
  5482.  
  5483.   sprintf (instr, \"strb\\t%%5, [%%0, %%3, %s %%4]!\",
  5484.        shift_instr (GET_CODE (operands[2]), &operands[4]));
  5485.   return arm_output_asm_insn (instr, operands);
  5486. }
  5487. "
  5488. [(set_attr "type" "store1")])
  5489.  
  5490. (define_insn ""
  5491.   [(set (mem:QI (minus:SI (match_operand:SI 1 "s_register_operand" "0")
  5492.               (match_operator:SI 2 "shift_operator"
  5493.                [(match_operand:SI 3 "s_register_operand" "r")
  5494.                 (match_operand:SI 4 "const_shift_operand" "n")])))
  5495.     (match_operand:QI 5 "s_register_operand" "r"))
  5496.    (set (match_operand:SI 0 "s_register_operand" "=r")
  5497.     (minus:SI (match_dup 1) (match_op_dup 2 [(match_dup 3)
  5498.                          (match_dup 4)])))]
  5499.   "REGNO (operands[0]) != FRAME_POINTER_REGNUM
  5500.    && REGNO (operands[1]) != FRAME_POINTER_REGNUM
  5501.    && REGNO (operands[3]) != FRAME_POINTER_REGNUM"
  5502.   "*
  5503. {
  5504.   char instr[100];
  5505.  
  5506.   sprintf (instr, \"strb\\t%%5, [%%0, -%%3, %s %%4]!\",
  5507.        shift_instr (GET_CODE (operands[2]), &operands[4]));
  5508.   return arm_output_asm_insn (instr, operands);
  5509. }
  5510. "
  5511. [(set_attr "type" "store1")])
  5512.  
  5513. (define_insn ""
  5514.   [(set (match_operand:QI 5 "s_register_operand" "=r")
  5515.     (mem:QI (plus:SI (match_operator:SI 2 "shift_operator"
  5516.               [(match_operand:SI 3 "s_register_operand" "r")
  5517.                (match_operand:SI 4 "const_shift_operand" "n")])
  5518.              (match_operand:SI 1 "s_register_operand" "0"))))
  5519.    (set (match_operand:SI 0 "s_register_operand" "=r")
  5520.     (plus:SI (match_op_dup 2 [(match_dup 3)    (match_dup 4)])
  5521.          (match_dup 1)))]
  5522.   "REGNO (operands[0]) != FRAME_POINTER_REGNUM
  5523.    && REGNO (operands[1]) != FRAME_POINTER_REGNUM
  5524.    && REGNO (operands[3]) != FRAME_POINTER_REGNUM"
  5525.   "*
  5526. {
  5527.   char instr[100];
  5528.  
  5529.   sprintf (instr, \"ldrb\\t%%5, [%%0, %%3, %s %%4]!\",
  5530.        shift_instr (GET_CODE (operands[2]), &operands[4]));
  5531.   return arm_output_asm_insn (instr, operands);
  5532. }
  5533. "
  5534. [(set_attr "type" "load")])
  5535.  
  5536. (define_insn ""
  5537.   [(set (match_operand:QI 5 "s_register_operand" "=r")
  5538.     (mem:QI (minus:SI (match_operand:SI 1 "s_register_operand" "0")
  5539.               (match_operator:SI 2 "shift_operator"
  5540.                [(match_operand:SI 3 "s_register_operand" "r")
  5541.                 (match_operand:SI 4 "const_shift_operand" "n")]))))
  5542.    (set (match_operand:SI 0 "s_register_operand" "=r")
  5543.     (minus:SI (match_dup 1) (match_op_dup 2 [(match_dup 3)
  5544.                          (match_dup 4)])))]
  5545.   "REGNO (operands[0]) != FRAME_POINTER_REGNUM
  5546.    && REGNO (operands[1]) != FRAME_POINTER_REGNUM
  5547.    && REGNO (operands[3]) != FRAME_POINTER_REGNUM"
  5548.   "*
  5549. {
  5550.   char instr[100];
  5551.  
  5552.   sprintf (instr, \"ldrb\\t%%5, [%%0, -%%3, %s %%4]!\",
  5553.        shift_instr (GET_CODE (operands[2]), &operands[4]));
  5554.   return arm_output_asm_insn (instr, operands);
  5555. }
  5556. "
  5557. [(set_attr "type" "load")])
  5558.  
  5559. (define_insn ""
  5560.   [(set (mem:SI (plus:SI (match_operator:SI 2 "shift_operator"
  5561.               [(match_operand:SI 3 "s_register_operand" "r")
  5562.                (match_operand:SI 4 "const_shift_operand" "n")])
  5563.              (match_operand:SI 1 "s_register_operand" "0")))
  5564.     (match_operand:SI 5 "s_register_operand" "r"))
  5565.    (set (match_operand:SI 0 "s_register_operand" "=r")
  5566.     (plus:SI (match_op_dup 2 [(match_dup 3)    (match_dup 4)])
  5567.          (match_dup 1)))]
  5568.   "REGNO (operands[0]) != FRAME_POINTER_REGNUM
  5569.    && REGNO (operands[1]) != FRAME_POINTER_REGNUM
  5570.    && REGNO (operands[3]) != FRAME_POINTER_REGNUM"
  5571.   "*
  5572. {
  5573.   char instr[100];
  5574.  
  5575.   sprintf (instr, \"str\\t%%5, [%%0, %%3, %s %%4]!\",
  5576.        shift_instr (GET_CODE (operands[2]), &operands[4]));
  5577.   return arm_output_asm_insn (instr, operands);
  5578. }
  5579. "
  5580. [(set_attr "type" "store1")])
  5581.  
  5582. (define_insn ""
  5583.   [(set (mem:SI (minus:SI (match_operand:SI 1 "s_register_operand" "0")
  5584.               (match_operator:SI 2 "shift_operator"
  5585.                [(match_operand:SI 3 "s_register_operand" "r")
  5586.                 (match_operand:SI 4 "const_shift_operand" "n")])))
  5587.     (match_operand:SI 5 "s_register_operand" "r"))
  5588.    (set (match_operand:SI 0 "s_register_operand" "=r")
  5589.     (minus:SI (match_dup 1) (match_op_dup 2 [(match_dup 3)
  5590.                          (match_dup 4)])))]
  5591.   "REGNO (operands[0]) != FRAME_POINTER_REGNUM
  5592.    && REGNO (operands[1]) != FRAME_POINTER_REGNUM
  5593.    && REGNO (operands[3]) != FRAME_POINTER_REGNUM"
  5594.   "*
  5595. {
  5596.   char instr[100];
  5597.  
  5598.   sprintf (instr, \"str\\t%%5, [%%0, -%%3, %s %%4]!\",
  5599.        shift_instr (GET_CODE (operands[2]), &operands[4]));
  5600.   return arm_output_asm_insn (instr, operands);
  5601. }
  5602. "
  5603. [(set_attr "type" "store1")])
  5604.  
  5605. (define_insn ""
  5606.   [(set (match_operand:SI 5 "s_register_operand" "=r")
  5607.     (mem:SI (plus:SI (match_operator:SI 2 "shift_operator"
  5608.               [(match_operand:SI 3 "s_register_operand" "r")
  5609.                (match_operand:SI 4 "const_shift_operand" "n")])
  5610.              (match_operand:SI 1 "s_register_operand" "0"))))
  5611.    (set (match_operand:SI 0 "s_register_operand" "=r")
  5612.     (plus:SI (match_op_dup 2 [(match_dup 3) (match_dup 4)])
  5613.          (match_dup 1)))]
  5614.   "REGNO (operands[0]) != FRAME_POINTER_REGNUM
  5615.    && REGNO (operands[1]) != FRAME_POINTER_REGNUM
  5616.    && REGNO (operands[3]) != FRAME_POINTER_REGNUM"
  5617.   "*
  5618. {
  5619.   char instr[100];
  5620.  
  5621.   sprintf (instr, \"ldr\\t%%5, [%%0, %%3, %s %%4]!\",
  5622.        shift_instr (GET_CODE (operands[2]), &operands[4]));
  5623.   return arm_output_asm_insn (instr, operands);
  5624. }
  5625. "
  5626. [(set_attr "type" "load")])
  5627.  
  5628. (define_insn ""
  5629.   [(set (match_operand:SI 5 "s_register_operand" "=r")
  5630.     (mem:SI (minus:SI (match_operand:SI 1 "s_register_operand" "0")
  5631.               (match_operator:SI 2 "shift_operator"
  5632.                [(match_operand:SI 3 "s_register_operand" "r")
  5633.                 (match_operand:SI 4 "const_shift_operand" "n")]))))
  5634.    (set (match_operand:SI 0 "s_register_operand" "=r")
  5635.     (minus:SI (match_dup 1) (match_op_dup 2 [(match_dup 3)
  5636.                          (match_dup 4)])))]
  5637.   "REGNO (operands[0]) != FRAME_POINTER_REGNUM
  5638.    && REGNO (operands[1]) != FRAME_POINTER_REGNUM
  5639.    && REGNO (operands[3]) != FRAME_POINTER_REGNUM"
  5640.   "*
  5641. {
  5642.   char instr[100];
  5643.  
  5644.   sprintf (instr, \"ldr\\t%%5, [%%0, -%%3, %s %%4]!\",
  5645.        shift_instr (GET_CODE (operands[2]), &operands[4]));
  5646.   return arm_output_asm_insn (instr, operands);
  5647. }
  5648. "
  5649. [(set_attr "type" "load")])
  5650.  
  5651. (define_insn ""
  5652.   [(set (match_operand:HI 5 "s_register_operand" "=r")
  5653.     (mem:HI (plus:SI (match_operator:SI 2 "shift_operator"
  5654.               [(match_operand:SI 3 "s_register_operand" "r")
  5655.                (match_operand:SI 4 "const_shift_operand" "n")])
  5656.              (match_operand:SI 1 "s_register_operand" "0"))))
  5657.    (set (match_operand:SI 0 "s_register_operand" "=r")
  5658.     (plus:SI (match_op_dup 2 [(match_dup 3)    (match_dup 4)])
  5659.          (match_dup 1)))]
  5660.   "REGNO (operands[0]) != FRAME_POINTER_REGNUM
  5661.    && REGNO (operands[1]) != FRAME_POINTER_REGNUM
  5662.    && REGNO (operands[3]) != FRAME_POINTER_REGNUM"
  5663.   "*
  5664. {
  5665.   char instr[100];
  5666.  
  5667.   sprintf (instr, \"ldr\\t%%5, [%%0, %%3, %s %%4]!\\t@ loadhi\",
  5668.        shift_instr (GET_CODE (operands[2]), &operands[4]));
  5669.   return arm_output_asm_insn (instr, operands);
  5670. }
  5671. "
  5672. [(set_attr "type" "load")])
  5673.  
  5674. (define_insn ""
  5675.   [(set (match_operand:HI 5 "s_register_operand" "=r")
  5676.     (mem:HI (minus:SI (match_operand:SI 1 "s_register_operand" "0")
  5677.               (match_operator:SI 2 "shift_operator"
  5678.                [(match_operand:SI 3 "s_register_operand" "r")
  5679.                 (match_operand:SI 4 "const_shift_operand" "n")]))))
  5680.    (set (match_operand:SI 0 "s_register_operand" "=r")
  5681.     (minus:SI (match_dup 1) (match_op_dup 2 [(match_dup 3)
  5682.                          (match_dup 4)])))]
  5683.   "REGNO (operands[0]) != FRAME_POINTER_REGNUM
  5684.    && REGNO (operands[1]) != FRAME_POINTER_REGNUM
  5685.    && REGNO (operands[3]) != FRAME_POINTER_REGNUM"
  5686.   "*
  5687. {
  5688.   char instr[100];
  5689.  
  5690.   sprintf (instr, \"ldr\\t%%5, [%%0, -%%3, %s %%4]!\\t@ loadhi\",
  5691.        shift_instr (GET_CODE (operands[2]), &operands[4]));
  5692.   return arm_output_asm_insn (instr, operands);
  5693. }
  5694. "
  5695. [(set_attr "type" "load")])
  5696.  
  5697. ; It can also support extended post-inc expressions, but combine doesn't
  5698. ; try these....
  5699. ; It doesn't seem worth adding peepholes for anything but the most common
  5700. ; cases since, unlike combine, the increment must immediately follow the load
  5701. ; for this pattern to match.
  5702. ; When loading we must watch to see that the base register isn't trampled by
  5703. ; the load.  In such cases this isn't a post-inc expression.
  5704.  
  5705. (define_peephole
  5706.   [(set (mem:QI (match_operand:SI 0 "s_register_operand" "+r"))
  5707.     (match_operand:QI 2 "s_register_operand" "r"))
  5708.    (set (match_dup 0)
  5709.     (plus:SI (match_dup 0) (match_operand:SI 1 "index_operand" "rJ")))]
  5710.   ""
  5711.   "*
  5712.   return arm_output_asm_insn (\"strb\\t%2, [%0], %1\", operands);
  5713. ")
  5714.  
  5715. (define_peephole
  5716.   [(set (match_operand:QI 0 "s_register_operand" "=r")
  5717.     (mem:QI (match_operand:SI 1 "s_register_operand" "+r")))
  5718.    (set (match_dup 1)
  5719.     (plus:SI (match_dup 1) (match_operand:SI 2 "index_operand" "rJ")))]
  5720.   "REGNO(operands[0]) != REGNO(operands[1])
  5721.    && (GET_CODE (operands[2]) != REG
  5722.        || REGNO(operands[0]) != REGNO (operands[2]))"
  5723.   "*
  5724.   return arm_output_asm_insn (\"ldrb\\t%0, [%1], %2\", operands);
  5725. ")
  5726.  
  5727. (define_peephole
  5728.   [(set (mem:SI (match_operand:SI 0 "s_register_operand" "+r"))
  5729.     (match_operand:SI 2 "s_register_operand" "r"))
  5730.    (set (match_dup 0)
  5731.     (plus:SI (match_dup 0) (match_operand:SI 1 "index_operand" "rJ")))]
  5732.   ""
  5733.   "*
  5734.   return arm_output_asm_insn (\"str\\t%2, [%0], %1\", operands);
  5735. ")
  5736.  
  5737. (define_peephole
  5738.   [(set (match_operand:HI 0 "s_register_operand" "=r")
  5739.     (mem:HI (match_operand:SI 1 "s_register_operand" "+r")))
  5740.    (set (match_dup 1)
  5741.     (plus:SI (match_dup 1) (match_operand:SI 2 "index_operand" "rJ")))]
  5742.   "REGNO(operands[0]) != REGNO(operands[1])
  5743.    && (GET_CODE (operands[2]) != REG
  5744.        || REGNO(operands[0]) != REGNO (operands[2]))"
  5745.   "*
  5746.   return arm_output_asm_insn (\"ldr\\t%0, [%1], %2\\t@ loadhi\", operands);
  5747. ")
  5748.  
  5749. (define_peephole
  5750.   [(set (match_operand:SI 0 "s_register_operand" "=r")
  5751.     (mem:SI (match_operand:SI 1 "s_register_operand" "+r")))
  5752.    (set (match_dup 1)
  5753.     (plus:SI (match_dup 1) (match_operand:SI 2 "index_operand" "rJ")))]
  5754.   "REGNO(operands[0]) != REGNO(operands[1])
  5755.    && (GET_CODE (operands[2]) != REG
  5756.        || REGNO(operands[0]) != REGNO (operands[2]))"
  5757.   "*
  5758.   return arm_output_asm_insn (\"ldr\\t%0, [%1], %2\", operands);
  5759. ")
  5760.  
  5761. ; This pattern is never tried by combine, so do it as a peephole
  5762.  
  5763. (define_peephole
  5764.   [(set (match_operand:SI 0 "s_register_operand" "=r")
  5765.     (match_operand:SI 1 "s_register_operand" "r"))
  5766.    (set (match_operand 2 "cc_register" "")
  5767.     (compare (match_dup 1) (const_int 0)))]
  5768.   ""
  5769.   "*
  5770.   return arm_output_asm_insn (\"subs\\t%0, %1, #0\", operands);
  5771. "
  5772. [(set_attr "conds" "set")])
  5773.  
  5774. ; Peepholes to spot possible load- and store-multiples, if the ordering is
  5775. ; reversed, check that the memory references aren't volatile.
  5776.  
  5777. (define_peephole
  5778.   [(set (match_operand:SI 0 "s_register_operand" "=r")
  5779.         (mem:SI (plus:SI (match_operand:SI 1 "s_register_operand" "r")
  5780.                          (const_int 12))))
  5781.    (set (match_operand:SI 2 "s_register_operand" "=r")
  5782.         (mem:SI (plus:SI (match_dup 1) (const_int 8))))
  5783.    (set (match_operand:SI 3 "s_register_operand" "=r")
  5784.         (mem:SI (plus:SI (match_dup 1) (const_int 4))))
  5785.    (set (match_operand:SI 4 "s_register_operand" "=r")
  5786.         (mem:SI (match_dup 1)))]
  5787.   "REGNO (operands[0]) > REGNO (operands[2])
  5788.    && REGNO (operands[2]) > REGNO (operands[3])
  5789.    && REGNO (operands[3]) > REGNO (operands[4])
  5790.    && !(REGNO (operands[1]) == REGNO (operands[0])
  5791.        || REGNO (operands[1]) == REGNO (operands[2])
  5792.        || REGNO (operands[1]) == REGNO (operands[3])
  5793.        || REGNO (operands[1]) == REGNO (operands[4]))
  5794.    && !MEM_VOLATILE_P (SET_SRC (PATTERN (insn)))
  5795.    && !MEM_VOLATILE_P (SET_SRC (PATTERN (prev_nonnote_insn (insn))))
  5796.    && !MEM_VOLATILE_P (SET_SRC (PATTERN (prev_nonnote_insn
  5797.                      (prev_nonnote_insn (insn)))))
  5798.    && !MEM_VOLATILE_P (SET_SRC (PATTERN (prev_nonnote_insn
  5799.                      (prev_nonnote_insn 
  5800.                       (prev_nonnote_insn (insn))))))"
  5801.   "*
  5802.   return arm_output_asm_insn (\"ldmia\\t%1, {%4, %3, %2, %0}\\t@ phole ldm\",
  5803.                   operands);
  5804. ")
  5805.  
  5806. (define_peephole
  5807.   [(set (match_operand:SI 0 "s_register_operand" "=r")
  5808.         (mem:SI (plus:SI (match_operand:SI 1 "s_register_operand" "r")
  5809.                          (const_int 8))))
  5810.    (set (match_operand:SI 2 "s_register_operand" "=r")
  5811.         (mem:SI (plus:SI (match_dup 1) (const_int 4))))
  5812.    (set (match_operand:SI 3 "s_register_operand" "=r")
  5813.         (mem:SI (match_dup 1)))]
  5814.   "REGNO (operands[0]) >  REGNO (operands[2])
  5815.    && REGNO (operands[2]) > REGNO (operands[3])
  5816.    && !(REGNO (operands[1]) == REGNO (operands[0])
  5817.        || REGNO (operands[1]) == REGNO (operands[2])
  5818.        || REGNO (operands[1]) == REGNO (operands[3]))
  5819.    && !MEM_VOLATILE_P (SET_SRC (PATTERN (insn)))
  5820.    && !MEM_VOLATILE_P (SET_SRC (PATTERN (prev_nonnote_insn (insn))))
  5821.    && !MEM_VOLATILE_P (SET_SRC (PATTERN (prev_nonnote_insn
  5822.                      (prev_nonnote_insn (insn)))))"
  5823.   "*
  5824.   return arm_output_asm_insn (\"ldmia\\t%1, {%3, %2, %0}\\t@ phole ldm\",
  5825.                   operands);
  5826. ")
  5827.  
  5828. (define_peephole
  5829.   [(set (match_operand:SI 0 "s_register_operand" "=r")
  5830.         (mem:SI (plus:SI (match_operand:SI 1 "s_register_operand" "r")
  5831.                          (const_int 4))))
  5832.    (set (match_operand:SI 2 "s_register_operand" "=r")
  5833.         (mem:SI (match_dup 1)))]
  5834.   "REGNO (operands[0]) > REGNO (operands[2])
  5835.    && !(REGNO (operands[1]) == REGNO (operands[0])
  5836.        || REGNO (operands[1]) == REGNO (operands[2]))
  5837.    && !MEM_VOLATILE_P (SET_SRC (PATTERN (insn)))
  5838.    && !MEM_VOLATILE_P (SET_SRC (PATTERN (prev_nonnote_insn (insn))))"
  5839.   "*
  5840.   return arm_output_asm_insn (\"ldmia\\t%1, {%2, %0}\\t@ phole ldm\",
  5841.                   operands);
  5842. ")
  5843.  
  5844. (define_peephole
  5845.   [(set (mem:SI (plus:SI (match_operand:SI 1 "s_register_operand" "r")
  5846.                          (const_int 12)))
  5847.         (match_operand:SI 0 "s_register_operand" "r"))
  5848.    (set (mem:SI (plus:SI (match_dup 1) (const_int 8)))
  5849.         (match_operand:SI 2 "s_register_operand" "r"))
  5850.    (set (mem:SI (plus:SI (match_dup 1) (const_int 4)))
  5851.         (match_operand:SI 3 "s_register_operand" "r"))
  5852.    (set (mem:SI (match_dup 1))
  5853.         (match_operand:SI 4 "s_register_operand" "r"))]
  5854.   "REGNO (operands[0]) >  REGNO (operands[2])
  5855.    && REGNO (operands[2]) > REGNO (operands[3])
  5856.    && REGNO (operands[3]) > REGNO (operands[4])
  5857.    && !MEM_VOLATILE_P (SET_DEST (PATTERN (insn)))
  5858.    && !MEM_VOLATILE_P (SET_DEST (PATTERN (prev_nonnote_insn (insn))))
  5859.    && !MEM_VOLATILE_P (SET_DEST (PATTERN (prev_nonnote_insn
  5860.                       (prev_nonnote_insn (insn)))))
  5861.    && !MEM_VOLATILE_P (SET_DEST (PATTERN (prev_nonnote_insn
  5862.                       (prev_nonnote_insn 
  5863.                        (prev_nonnote_insn (insn))))))"
  5864.   "*
  5865.   return arm_output_asm_insn (\"stmia\\t%1, {%4, %3, %2, %0}\\t@ phole stm\",
  5866.                   operands);
  5867. ")
  5868.  
  5869. (define_peephole
  5870.   [(set (mem:SI (plus:SI (match_operand:SI 1 "s_register_operand" "r")
  5871.                          (const_int 8)))
  5872.         (match_operand:SI 0 "s_register_operand" "r"))
  5873.    (set (mem:SI (plus:SI (match_dup 1) (const_int 4)))
  5874.         (match_operand:SI 2 "s_register_operand" "r"))
  5875.    (set (mem:SI (match_dup 1))
  5876.         (match_operand:SI 3 "s_register_operand" "r"))]
  5877.   "REGNO (operands[0]) >  REGNO (operands[2])
  5878.    && REGNO (operands[2]) > REGNO (operands[3])
  5879.    && !MEM_VOLATILE_P (SET_DEST (PATTERN (insn)))
  5880.    && !MEM_VOLATILE_P (SET_DEST (PATTERN (prev_nonnote_insn (insn))))
  5881.    && !MEM_VOLATILE_P (SET_DEST (PATTERN (prev_nonnote_insn
  5882.                       (prev_nonnote_insn (insn)))))"
  5883.   "*
  5884.   return arm_output_asm_insn (\"stmia\\t%1, {%3, %2, %0}\\t@ phole stm\",
  5885.                   operands);
  5886. ")
  5887.  
  5888. (define_peephole
  5889.   [(set (mem:SI (plus:SI (match_operand:SI 1 "s_register_operand" "r")
  5890.                          (const_int 4)))
  5891.         (match_operand:SI 0 "s_register_operand" "r"))
  5892.    (set (mem:SI (match_dup 1))
  5893.         (match_operand:SI 2 "s_register_operand" "r"))]
  5894.   "REGNO (operands[0]) >  REGNO (operands[2])
  5895.    && !MEM_VOLATILE_P (SET_DEST (PATTERN (insn)))
  5896.    && !MEM_VOLATILE_P (SET_DEST (PATTERN (prev_nonnote_insn (insn))))"
  5897.   "*
  5898.   return arm_output_asm_insn (\"stmia\\t%1, {%2, %0}\\t@ phole stm\",
  5899.                   operands);
  5900. ")
  5901.  
  5902. ;; A call followed by return can be replaced by restoring the regs and
  5903. ;; jumping to the subroutine, provided we aren't passing the address of
  5904. ;; any of our local variables.  If we call alloca then this is unsafe
  5905. ;; since restoring the frame frees the memory, which is not what we want.
  5906. ;; Sometimes the return might have been targeted by the final prescan:
  5907. ;; if so then emit a propper return insn as well.
  5908. ;; Unfortunately, if the frame pointer is required, we don't know if the
  5909. ;; current function has any implicit stack pointer adjustments that will 
  5910. ;; be restored by the return: we can't therefore do a tail call.
  5911. ;; Another unfortunate that we can't handle is if current_function_args_size
  5912. ;; is non-zero: in this case elimination of the argument pointer assumed
  5913. ;; that lr was pushed onto the stack, so eliminating upsets the offset
  5914. ;; calculations.
  5915.  
  5916. (define_peephole
  5917.   [(parallel [(call (mem:SI (match_operand:SI 0 "" "i"))
  5918.               (match_operand:SI 1 "general_operand" "g"))
  5919.             (clobber (reg:SI 14))])
  5920.    (return)]
  5921.   "(GET_CODE (operands[0]) == SYMBOL_REF && USE_RETURN_INSN
  5922.     && !get_frame_size () && !current_function_calls_alloca
  5923.     && !frame_pointer_needed && !current_function_args_size)"
  5924.   "*
  5925. {
  5926.   extern rtx arm_target_insn;
  5927.   extern int arm_ccfsm_state, arm_current_cc;
  5928.  
  5929.   if (arm_ccfsm_state && arm_target_insn && INSN_DELETED_P (arm_target_insn))
  5930.   {
  5931.     arm_current_cc ^= 1;
  5932.     output_return_instruction (NULL, TRUE);
  5933.     arm_ccfsm_state = 0;
  5934.     arm_target_insn = NULL;
  5935.   }
  5936.  
  5937.   output_return_instruction (NULL, FALSE);
  5938.   return (arm_output_asm_insn (\"b\\t%a0\", operands));
  5939. }"
  5940. [(set (attr "conds")
  5941.       (if_then_else (eq_attr "cpu" "arm6")
  5942.             (const_string "clob")
  5943.             (const_string "nocond")))
  5944.  (set_attr "length" "2")])
  5945.  
  5946. (define_peephole
  5947.   [(parallel [(set (match_operand 0 "s_register_operand" "=rf")
  5948.            (call (mem:SI (match_operand:SI 1 "" "i"))
  5949.              (match_operand:SI 2 "general_operand" "g")))
  5950.           (clobber (reg:SI 14))])
  5951.    (return)]
  5952.   "(GET_CODE (operands[1]) == SYMBOL_REF && USE_RETURN_INSN
  5953.     && !get_frame_size () && !current_function_calls_alloca
  5954.     && !frame_pointer_needed && !current_function_args_size)"
  5955.   "*
  5956. {
  5957.   extern rtx arm_target_insn;
  5958.   extern int arm_ccfsm_state, arm_current_cc;
  5959.  
  5960.   if (arm_ccfsm_state && arm_target_insn && INSN_DELETED_P (arm_target_insn))
  5961.   {
  5962.     arm_current_cc ^= 1;
  5963.     output_return_instruction (NULL, TRUE);
  5964.     arm_ccfsm_state = 0;
  5965.     arm_target_insn = NULL;
  5966.   }
  5967.  
  5968.   output_return_instruction (NULL, FALSE);
  5969.   return (arm_output_asm_insn (\"b\\t%a1\", operands));
  5970. }"
  5971. [(set (attr "conds")
  5972.       (if_then_else (eq_attr "cpu" "arm6")
  5973.             (const_string "clob")
  5974.             (const_string "nocond")))
  5975.  (set_attr "length" "2")])
  5976.  
  5977. ;; As above but when this function is not void, we must be returning the
  5978. ;; result of the called subroutine.
  5979.  
  5980. (define_peephole
  5981.   [(parallel [(set (match_operand 0 "s_register_operand" "=rf")
  5982.            (call (mem:SI (match_operand:SI 1 "" "i"))
  5983.              (match_operand:SI 2 "general_operand" "g")))
  5984.           (clobber (reg:SI 14))])
  5985.    (use (match_dup 0))
  5986.    (return)]
  5987.   "(GET_CODE (operands[1]) == SYMBOL_REF && USE_RETURN_INSN
  5988.     && !get_frame_size () && !current_function_calls_alloca
  5989.     && !frame_pointer_needed && !current_function_args_size)"
  5990.   "*
  5991. {
  5992.   extern rtx arm_target_insn;
  5993.   extern int arm_ccfsm_state, arm_current_cc;
  5994.  
  5995.   if (arm_ccfsm_state && arm_target_insn && INSN_DELETED_P (arm_target_insn))
  5996.   {
  5997.     arm_current_cc ^= 1;
  5998.     output_return_instruction (NULL, TRUE);
  5999.     arm_ccfsm_state = 0;
  6000.     arm_target_insn = NULL;
  6001.   }
  6002.  
  6003.   output_return_instruction (NULL, FALSE);
  6004.   return (arm_output_asm_insn (\"b\\t%a1\", operands));
  6005. }"
  6006. [(set (attr "conds")
  6007.       (if_then_else (eq_attr "cpu" "arm6")
  6008.             (const_string "clob")
  6009.             (const_string "nocond")))
  6010.  (set_attr "length" "2")])
  6011.  
  6012. ;; If calling a subroutine and then jumping back to somewhere else, but not
  6013. ;; too far away, then we can set the link register with the branch address
  6014. ;; and jump direct to the subroutine.  On return from the subroutine
  6015. ;; execution continues at the branch; this avoids a prefetch stall.
  6016. ;; We use the length attribute (via short_branch ()) to establish whether or
  6017. ;; not this is possible, this is the same asthe sparc does.
  6018.  
  6019. (define_peephole
  6020.   [(parallel[(call (mem:SI (match_operand:SI 0 "" "i"))
  6021.                    (match_operand:SI 1 "general_operand" "g"))
  6022.              (clobber (reg:SI 14))])
  6023.    (set (pc)
  6024.         (label_ref (match_operand 2 "" "")))]
  6025.   "GET_CODE (operands[0]) == SYMBOL_REF 
  6026.    && short_branch (INSN_UID (insn), INSN_UID (operands[2]))
  6027.    && arm_insn_not_targeted (insn)"
  6028.   "*
  6029. {
  6030.   int backward = arm_backwards_branch (INSN_UID (insn),
  6031.                        INSN_UID (operands[2]));
  6032.  
  6033. #if 0
  6034.   /* Putting this in means that TARGET_6 code will ONLY run on an arm6 or
  6035.    * above, leaving it out means that the code will still run on an arm 2 or 3
  6036.    */
  6037.   if (TARGET_6)
  6038.     {
  6039.       if (backward)
  6040.     arm_output_asm_insn (\"sub\\tlr, pc, #(8 + . -%l2)\", operands);
  6041.       else
  6042.     arm_output_asm_insn (\"add\\tlr, pc, #(%l2 - . -8)\", operands);
  6043.     }
  6044.   else
  6045. #endif
  6046.     {
  6047.       arm_output_asm_insn (\"mov\\tlr, pc\\t@ protect cc\");
  6048.       if (backward)
  6049.     arm_output_asm_insn (\"sub\\tlr, lr, #(4 + . -%l2)\", operands);
  6050.       else
  6051.     arm_output_asm_insn (\"add\\tlr, lr, #(%l2 - . -4)\", operands);
  6052.     }
  6053.   return arm_output_asm_insn (\"b\\t%a0\", operands);
  6054. }"
  6055. [(set (attr "conds")
  6056.       (if_then_else (eq_attr "cpu" "arm6")
  6057.             (const_string "clob")
  6058.             (const_string "nocond")))
  6059.  (set (attr "length")
  6060.       (if_then_else (eq_attr "cpu" "arm6")
  6061.             (const_int 2)
  6062.             (const_int 3)))])
  6063.  
  6064. (define_peephole
  6065.   [(parallel[(set (match_operand:SI 0 "s_register_operand" "=r")
  6066.           (call (mem:SI (match_operand:SI 1 "" "i"))
  6067.                         (match_operand:SI 2 "general_operand" "g")))
  6068.              (clobber (reg:SI 14))])
  6069.    (set (pc)
  6070.         (label_ref (match_operand 3 "" "")))]
  6071.   "GET_CODE (operands[0]) == SYMBOL_REF
  6072.    && short_branch (INSN_UID (insn), INSN_UID (operands[3]))
  6073.    && arm_insn_not_targeted (insn)"
  6074.   "*
  6075. {
  6076.   int backward = arm_backwards_branch (INSN_UID (insn),
  6077.                        INSN_UID (operands[3]));
  6078.  
  6079. #if 0
  6080.   /* Putting this in means that TARGET_6 code will ONLY run on an arm6 or
  6081.    * above, leaving it out means that the code will still run on an arm 2 or 3
  6082.    */
  6083.   if (TARGET_6)
  6084.     {
  6085.       if (backward)
  6086.     arm_output_asm_insn (\"sub\\tlr, pc, #(8 + . -%l3)\", operands);
  6087.       else
  6088.     arm_output_asm_insn (\"add\\tlr, pc, #(%l3 - . -8)\", operands);
  6089.     }
  6090.   else
  6091. #endif
  6092.     {
  6093.       arm_output_asm_insn (\"mov\\tlr, pc\\t@ protect cc\");
  6094.       if (backward)
  6095.     arm_output_asm_insn (\"sub\\tlr, lr, #(4 + . -%l3)\", operands);
  6096.       else
  6097.     arm_output_asm_insn (\"add\\tlr, lr, #(%l3 - . -4)\", operands);
  6098.     }
  6099.   return arm_output_asm_insn (\"b\\t%a1\", operands);
  6100. }"
  6101. [(set (attr "conds")
  6102.       (if_then_else (eq_attr "cpu" "arm6")
  6103.             (const_string "clob")
  6104.             (const_string "nocond")))
  6105.  (set (attr "length")
  6106.       (if_then_else (eq_attr "cpu" "arm6")
  6107.             (const_int 2)
  6108.             (const_int 3)))])
  6109.  
  6110. (define_split
  6111.   [(set (pc)
  6112.     (if_then_else (match_operator 0 "comparison_operator"
  6113.                [(match_operator:SI 1 "shift_operator"
  6114.              [(match_operand:SI 2 "s_register_operand" "r")
  6115.               (match_operand:SI 3 "nonmemory_operand" "rn")])
  6116.             (match_operand:SI 4 "s_register_operand" "r")])
  6117.               (label_ref (match_operand 5 "" ""))
  6118.               (pc)))
  6119.    (clobber (reg 24))]
  6120.   ""
  6121.   [(set (reg:CC 24)
  6122.     (compare:CC (match_dup 4)
  6123.             (match_op_dup 1 [(match_dup 2) (match_dup 3)])))
  6124.    (set (pc)
  6125.     (if_then_else (match_op_dup 0 [(reg 24) (const_int 0)])
  6126.               (label_ref (match_dup 5))
  6127.               (pc)))]
  6128.   "
  6129.   operands[0] = gen_rtx (swap_condition (GET_CODE (operands[0])), VOIDmode,
  6130.              operands[1], operands[2]);
  6131. ")
  6132.  
  6133. (define_split
  6134.   [(set (match_operand:SI 0 "s_register_operand" "")
  6135.     (and:SI (ge:SI (match_operand:SI 1 "s_register_operand" "")
  6136.                (const_int 0))
  6137.         (neg:SI (match_operator:SI 2 "comparison_operator"
  6138.              [(match_operand:SI 3 "s_register_operand" "")
  6139.               (match_operand:SI 4 "arm_rhs_operand" "")]))))
  6140.    (clobber (match_operand:SI 5 "s_register_operand" ""))]
  6141.   ""
  6142.   [(set (match_dup 5) (not:SI (ashiftrt:SI (match_dup 1) (const_int 31))))
  6143.    (set (match_dup 0) (and:SI (match_op_dup 2 [(match_dup 3) (match_dup 4)])
  6144.                   (match_dup 5)))]
  6145.   "")
  6146.  
  6147. ;; This pattern can be used because cc_noov mode implies that the following
  6148. ;; branch will be an equality (EQ or NE), so the sign extension is not
  6149. ;; needed.  Combine doesn't eliminate these because by the time it sees the
  6150. ;; branch it no-longer knows that the data came from memory.
  6151.  
  6152. (define_insn ""
  6153.   [(set (reg:CC_NOOV 24)
  6154.     (compare:CC_NOOV
  6155.      (ashift:SI (subreg:SI (match_operand:QI 0 "memory_operand" "m") 0)
  6156.             (const_int 24))
  6157.      (match_operand 1 "immediate_operand" "I")))
  6158.    (clobber (match_scratch:SI 2 "=r"))]
  6159.   "((unsigned long) INTVAL (operands[1]))
  6160.    == (((unsigned long) INTVAL (operands[1])) >> 24) << 24"
  6161.   "*
  6162.   operands[1] = GEN_INT (((unsigned long) INTVAL (operands[1])) >> 24);
  6163.   arm_output_asm_insn (\"ldrb\\t%2, %0\", operands);
  6164.   return arm_output_asm_insn (\"cmp\\t%2, %1\", operands);
  6165. "
  6166. [(set_attr "conds" "set")
  6167.  (set_attr "length" "2")
  6168.  (set_attr "type" "load")])
  6169.  
  6170. (define_expand "save_stack_nonlocal"
  6171.   [(match_operand:DI 0 "memory_operand" "")
  6172.    (match_operand:SI 1 "s_register_operand" "")]
  6173.   ""
  6174.   "
  6175. {
  6176.   /* We also need to save the frame pointer for non-local gotos */
  6177.   emit_move_insn (operand_subword (operands[0], 0, 0, DImode),
  6178.           hard_frame_pointer_rtx);
  6179.   emit_move_insn (operand_subword (operands[0], 1, 0, DImode), operands[1]);
  6180.   DONE;
  6181. }")
  6182.  
  6183. (define_expand "restore_stack_nonlocal"
  6184.   [(match_operand:SI 0 "s_register_operand" "")
  6185.    (match_operand:DI 1 "memory_operand" "")]
  6186.   ""
  6187.   "
  6188. {
  6189.   /* Restore the frame pointer first, the stack pointer second. */
  6190.   emit_move_insn (operands[0], operand_subword (operands[1], 1, 0, DImode));
  6191.   emit_move_insn (hard_frame_pointer_rtx, operand_subword (operands[1], 0, 0,
  6192.                                DImode));
  6193.   DONE;
  6194. }")
  6195.  
  6196. ;; This split is only used during output to reduce the number of patterns
  6197. ;; that need assembler instructions adding to them.  We allowed the setting
  6198. ;; of the conditions to be implicit during rtl generation so that
  6199. ;; the conditional compare patterns would work.  However this conflicts to
  6200. ;; some extend with the conditional data operations, so we have to split them
  6201. ;; up again here.
  6202.  
  6203. (define_split
  6204.   [(set (match_operand:SI 0 "s_register_operand" "")
  6205.     (if_then_else:SI (match_operator 1 "comparison_operator"
  6206.               [(match_operand 2 "" "") (match_operand 3 "" "")])
  6207.              (match_operand 4 "" "")
  6208.              (match_operand 5 "" "")))
  6209.    (clobber (reg 24))]
  6210.   "reload_completed"
  6211.   [(set (match_dup 6) (match_dup 7))
  6212.    (set (match_dup 0) 
  6213.     (if_then_else:SI (match_op_dup 1 [(match_dup 6) (const_int 0)])
  6214.              (match_dup 4)
  6215.              (match_dup 5)))]
  6216.   "
  6217. {
  6218.   enum machine_mode mode = SELECT_CC_MODE (GET_CODE (operands[1]), operands[2],
  6219.                        operands[3]);
  6220.  
  6221.   operands[6] = gen_rtx (REG, mode, 24);
  6222.   operands[7] = gen_rtx (COMPARE, mode, operands[2], operands[3]);
  6223. }
  6224. ")
  6225.  
  6226.  
  6227. (define_insn ""
  6228.   [(set (match_operand:SI 0 "s_register_operand" "=r,r")
  6229.     (if_then_else:SI (match_operator 4 "comparison_operator"
  6230.               [(match_operand 3 "cc_register" "") (const_int 0)])
  6231.              (match_operand:SI 1 "arm_rhs_operand" "0,?rI")
  6232.              (not:SI
  6233.               (match_operand:SI 2 "s_register_operand" "r,r"))))]
  6234.   ""
  6235.   "*
  6236.   if (which_alternative != 0)
  6237.     arm_output_asm_insn (\"mov%d4\\t%0, %1\", operands);
  6238.   return arm_output_asm_insn (\"mvn%D4\\t%0, %2\", operands);
  6239. "
  6240. [(set_attr "conds" "use")
  6241.  (set_attr "length" "1,2")])
  6242.  
  6243. ;; The next two patterns occur when an AND operation is followed by a
  6244. ;; scc insn sequence 
  6245.  
  6246. (define_insn ""
  6247.   [(set (match_operand:SI 0 "s_register_operand" "=r")
  6248.     (sign_extract:SI (match_operand:SI 1 "s_register_operand" "r")
  6249.              (const_int 1)
  6250.              (match_operand:SI 2 "immediate_operand" "n")))]
  6251.   ""
  6252.   "*
  6253.   operands[2] = GEN_INT (1 << INTVAL (operands[2]));
  6254.   arm_output_asm_insn (\"ands\\t%0, %1, %2\", operands);
  6255.   return arm_output_asm_insn (\"mvnne\\t%0, #0\", operands);
  6256. "
  6257. [(set_attr "conds" "clob")
  6258.  (set_attr "length" "2")])
  6259.  
  6260. (define_insn ""
  6261.   [(set (match_operand:SI 0 "s_register_operand" "=r")
  6262.     (not:SI
  6263.      (sign_extract:SI (match_operand:SI 1 "s_register_operand" "r")
  6264.               (const_int 1)
  6265.               (match_operand:SI 2 "immediate_operand" "n"))))]
  6266.   ""
  6267.   "*
  6268.   operands[2] = GEN_INT (1 << INTVAL (operands[2]));
  6269.   arm_output_asm_insn (\"tst\\t%1, %2\", operands);
  6270.   arm_output_asm_insn (\"mvneq\\t%0, #0\", operands);
  6271.   return arm_output_asm_insn (\"movne\\t%0, #0\", operands);
  6272. "
  6273. [(set_attr "conds" "clob")
  6274.  (set_attr "length" "3")])
  6275.