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

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