OSDN Git Service

6e13568a651ac7c451d9a61ec84a2acbfab44a08
[pf3gnuchains/gcc-fork.git] / gcc / config / xtensa / xtensa.md
1 ;; GCC machine description for Tensilica's Xtensa architecture.
2 ;; Copyright (C) 2001, 2002, 2003, 2004 Free Software Foundation, Inc.
3 ;; Contributed by Bob Wilson (bwilson@tensilica.com) at Tensilica.
4
5 ;; This file is part of GCC.
6
7 ;; GCC is free software; you can redistribute it and/or modify it
8 ;; under the terms of the GNU General Public License as published by
9 ;; the Free Software Foundation; either version 2, or (at your option)
10 ;; any later version.
11
12 ;; GCC is distributed in the hope that it will be useful, but WITHOUT
13 ;; ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
14 ;; or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public
15 ;; License for more details.
16
17 ;; You should have received a copy of the GNU General Public License
18 ;; along with GCC; see the file COPYING.  If not, write to the Free
19 ;; Software Foundation, 59 Temple Place - Suite 330, Boston, MA
20 ;; 02111-1307, USA.
21
22
23 (define_constants [
24   (A0_REG               0)
25   (A1_REG               1)
26   (A7_REG               7)
27   (A8_REG               8)
28
29   (UNSPEC_NSAU          1)
30   (UNSPEC_NOP           2)
31   (UNSPEC_PLT           3)
32   (UNSPEC_RET_ADDR      4)
33   (UNSPECV_SET_FP       1)
34   (UNSPECV_ENTRY        2)
35 ])
36
37 \f
38 ;; Attributes.
39
40 (define_attr "type"
41   "unknown,jump,call,load,store,move,arith,multi,nop,farith,fmadd,fdiv,fsqrt,fconv,fload,fstore,mul16,mul32,div32,mac16,rsr,wsr"
42   (const_string "unknown"))
43
44 (define_attr "mode"
45   "unknown,none,QI,HI,SI,DI,SF,DF,BL"
46   (const_string "unknown"))
47
48 (define_attr "length" "" (const_int 1))
49
50 ;; Describe a user's asm statement.
51 (define_asm_attributes
52   [(set_attr "type" "multi")])
53
54 \f
55 ;; Functional units.
56
57 (define_function_unit "memory" 1 0 (eq_attr "type" "load,fload") 2 0)
58
59 (define_function_unit "sreg" 1 1 (eq_attr "type" "rsr") 2 0)
60
61 (define_function_unit "mul16" 1 0 (eq_attr "type" "mul16") 2 0)
62
63 (define_function_unit "mul32" 1 0 (eq_attr "type" "mul32") 2 0)
64
65 (define_function_unit "fpmadd" 1 0 (eq_attr "type" "fmadd") 4 0)
66
67 (define_function_unit "fpconv" 1 0 (eq_attr "type" "fconv") 2 0)
68
69 \f
70 ;; Addition.
71
72 (define_expand "adddi3"
73   [(set (match_operand:DI 0 "register_operand" "")
74         (plus:DI (match_operand:DI 1 "register_operand" "")
75                  (match_operand:DI 2 "register_operand" "")))]
76   ""
77 {
78   rtx srclo;
79   rtx dstlo = gen_lowpart (SImode, operands[0]);
80   rtx src1lo = gen_lowpart (SImode, operands[1]);
81   rtx src2lo = gen_lowpart (SImode, operands[2]);
82
83   rtx dsthi = gen_highpart (SImode, operands[0]);
84   rtx src1hi = gen_highpart (SImode, operands[1]);
85   rtx src2hi = gen_highpart (SImode, operands[2]);
86
87   /* Either source can be used for overflow checking, as long as it's
88      not clobbered by the first addition.  */
89   if (!rtx_equal_p (dstlo, src1lo))
90     srclo = src1lo;
91   else if (!rtx_equal_p (dstlo, src2lo))
92     srclo = src2lo;
93   else
94     {
95       srclo = gen_reg_rtx (SImode);
96       emit_move_insn (srclo, src1lo);
97     }
98
99   emit_insn (gen_addsi3 (dstlo, src1lo, src2lo));
100   emit_insn (gen_addsi3 (dsthi, src1hi, src2hi));
101   emit_insn (gen_adddi_carry (dsthi, dstlo, srclo));
102   DONE;
103 })
104
105 ;; Represent the add-carry operation as an atomic operation instead of
106 ;; expanding it to a conditional branch.  Otherwise, the edge
107 ;; profiling code breaks because inserting the count increment code
108 ;; causes a new jump insn to be added.
109
110 (define_insn "adddi_carry"
111   [(set (match_operand:SI 0 "register_operand" "+a")
112         (plus:SI (ltu:SI (match_operand:SI 1 "register_operand" "r")
113                          (match_operand:SI 2 "register_operand" "r"))
114                  (match_dup 0)))]
115   ""
116   "bgeu\t%1, %2, 0f\;addi\t%0, %0, 1\;0:"
117   [(set_attr "type"     "multi")
118    (set_attr "mode"     "SI")
119    (set_attr "length"   "6")])
120
121 (define_insn "addsi3"
122   [(set (match_operand:SI 0 "register_operand" "=D,D,a,a,a")
123         (plus:SI (match_operand:SI 1 "register_operand" "%d,d,r,r,r")
124                  (match_operand:SI 2 "add_operand" "d,O,r,J,N")))]
125   ""
126   "@
127    add.n\t%0, %1, %2
128    addi.n\t%0, %1, %d2
129    add\t%0, %1, %2
130    addi\t%0, %1, %d2
131    addmi\t%0, %1, %x2"
132   [(set_attr "type"     "arith,arith,arith,arith,arith")
133    (set_attr "mode"     "SI")
134    (set_attr "length"   "2,2,3,3,3")])
135
136 (define_insn "*addx2"
137   [(set (match_operand:SI 0 "register_operand" "=a")
138         (plus:SI (mult:SI (match_operand:SI 1 "register_operand" "r")
139                           (const_int 2))
140                  (match_operand:SI 2 "register_operand" "r")))]
141   "TARGET_ADDX"
142   "addx2\t%0, %1, %2"
143   [(set_attr "type"     "arith")
144    (set_attr "mode"     "SI")
145    (set_attr "length"   "3")])
146
147 (define_insn "*addx4"
148   [(set (match_operand:SI 0 "register_operand" "=a")
149         (plus:SI (mult:SI (match_operand:SI 1 "register_operand" "r")
150                           (const_int 4))
151                  (match_operand:SI 2 "register_operand" "r")))]
152   "TARGET_ADDX"
153   "addx4\t%0, %1, %2"
154   [(set_attr "type"     "arith")
155    (set_attr "mode"     "SI")
156    (set_attr "length"   "3")])
157
158 (define_insn "*addx8"
159   [(set (match_operand:SI 0 "register_operand" "=a")
160         (plus:SI (mult:SI (match_operand:SI 1 "register_operand" "r")
161                           (const_int 8))
162                  (match_operand:SI 2 "register_operand" "r")))]
163   "TARGET_ADDX"
164   "addx8\t%0, %1, %2"
165   [(set_attr "type"     "arith")
166    (set_attr "mode"     "SI")
167    (set_attr "length"   "3")])
168
169 (define_insn "addsf3"
170   [(set (match_operand:SF 0 "register_operand" "=f")
171         (plus:SF (match_operand:SF 1 "register_operand" "%f")
172                  (match_operand:SF 2 "register_operand" "f")))]
173   "TARGET_HARD_FLOAT"
174   "add.s\t%0, %1, %2"
175   [(set_attr "type"     "fmadd")
176    (set_attr "mode"     "SF")
177    (set_attr "length"   "3")])
178
179 \f
180 ;; Subtraction.
181
182 (define_expand "subdi3"
183   [(set (match_operand:DI 0 "register_operand" "")
184         (minus:DI (match_operand:DI 1 "register_operand" "")
185                   (match_operand:DI 2 "register_operand" "")))]
186   ""
187 {
188   rtx dstlo = gen_lowpart (SImode, operands[0]);
189   rtx src1lo = gen_lowpart (SImode, operands[1]);
190   rtx src2lo = gen_lowpart (SImode, operands[2]);
191
192   rtx dsthi = gen_highpart (SImode, operands[0]);
193   rtx src1hi = gen_highpart (SImode, operands[1]);
194   rtx src2hi = gen_highpart (SImode, operands[2]);
195
196   emit_insn (gen_subsi3 (dsthi, src1hi, src2hi));
197   emit_insn (gen_subdi_carry (dsthi, src1lo, src2lo));
198   emit_insn (gen_subsi3 (dstlo, src1lo, src2lo));
199   DONE;
200 })
201
202 (define_insn "subdi_carry"
203   [(set (match_operand:SI 0 "register_operand" "+a")
204         (minus:SI (match_dup 0)
205                   (ltu:SI (match_operand:SI 1 "register_operand" "r")
206                           (match_operand:SI 2 "register_operand" "r"))))]
207   ""
208   "bgeu\t%1, %2, 0f\;addi\t%0, %0, -1\;0:"
209   [(set_attr "type"     "multi")
210    (set_attr "mode"     "SI")
211    (set_attr "length"   "6")])
212
213 (define_insn "subsi3"
214   [(set (match_operand:SI 0 "register_operand" "=a")
215         (minus:SI (match_operand:SI 1 "register_operand" "r")
216                   (match_operand:SI 2 "register_operand" "r")))]
217   ""
218   "sub\t%0, %1, %2"
219   [(set_attr "type"     "arith")
220    (set_attr "mode"     "SI")
221    (set_attr "length"   "3")])
222
223 (define_insn "*subx2"
224   [(set (match_operand:SI 0 "register_operand" "=a")
225         (minus:SI (mult:SI (match_operand:SI 1 "register_operand" "r")
226                            (const_int 2))
227                   (match_operand:SI 2 "register_operand" "r")))]
228   "TARGET_ADDX"
229   "subx2\t%0, %1, %2"
230   [(set_attr "type"     "arith")
231    (set_attr "mode"     "SI")
232    (set_attr "length"   "3")])
233
234 (define_insn "*subx4"
235   [(set (match_operand:SI 0 "register_operand" "=a")
236         (minus:SI (mult:SI (match_operand:SI 1 "register_operand" "r")
237                            (const_int 4))
238                   (match_operand:SI 2 "register_operand" "r")))]
239   "TARGET_ADDX"
240   "subx4\t%0, %1, %2"
241   [(set_attr "type"     "arith")
242    (set_attr "mode"     "SI")
243    (set_attr "length"   "3")])
244
245 (define_insn "*subx8"
246   [(set (match_operand:SI 0 "register_operand" "=a")
247         (minus:SI (mult:SI (match_operand:SI 1 "register_operand" "r")
248                            (const_int 8))
249                   (match_operand:SI 2 "register_operand" "r")))]
250   "TARGET_ADDX"
251   "subx8\t%0, %1, %2"
252   [(set_attr "type"     "arith")
253    (set_attr "mode"     "SI")
254    (set_attr "length"   "3")])
255
256 (define_insn "subsf3"
257   [(set (match_operand:SF 0 "register_operand" "=f")
258         (minus:SF (match_operand:SF 1 "register_operand" "f")
259                   (match_operand:SF 2 "register_operand" "f")))]
260   "TARGET_HARD_FLOAT"
261   "sub.s\t%0, %1, %2"
262   [(set_attr "type"     "fmadd")
263    (set_attr "mode"     "SF")
264    (set_attr "length"   "3")])
265
266 \f
267 ;; Multiplication.
268
269 (define_insn "mulsi3"
270   [(set (match_operand:SI 0 "register_operand" "=a")
271         (mult:SI (match_operand:SI 1 "register_operand" "%r")
272                  (match_operand:SI 2 "register_operand" "r")))]
273   "TARGET_MUL32"
274   "mull\t%0, %1, %2"
275   [(set_attr "type"     "mul32")
276    (set_attr "mode"     "SI")
277    (set_attr "length"   "3")])
278
279 (define_insn "mulhisi3"
280   [(set (match_operand:SI 0 "register_operand" "=C,A")
281         (mult:SI (sign_extend:SI
282                   (match_operand:HI 1 "register_operand" "%r,r"))
283                  (sign_extend:SI
284                   (match_operand:HI 2 "register_operand" "r,r"))))]
285   "TARGET_MUL16 || TARGET_MAC16"
286   "@
287    mul16s\t%0, %1, %2
288    mul.aa.ll\t%1, %2"
289   [(set_attr "type"     "mul16,mac16")
290    (set_attr "mode"     "SI")
291    (set_attr "length"   "3,3")])
292
293 (define_insn "umulhisi3"
294   [(set (match_operand:SI 0 "register_operand" "=C,A")
295         (mult:SI (zero_extend:SI
296                   (match_operand:HI 1 "register_operand" "%r,r"))
297                  (zero_extend:SI
298                   (match_operand:HI 2 "register_operand" "r,r"))))]
299   "TARGET_MUL16 || TARGET_MAC16"
300   "@
301    mul16u\t%0, %1, %2
302    umul.aa.ll\t%1, %2"
303   [(set_attr "type"     "mul16,mac16")
304    (set_attr "mode"     "SI")
305    (set_attr "length"   "3,3")])
306
307 (define_insn "muladdhisi"
308   [(set (match_operand:SI 0 "register_operand" "=A")
309         (plus:SI (mult:SI (sign_extend:SI
310                            (match_operand:HI 1 "register_operand" "%r"))
311                           (sign_extend:SI
312                            (match_operand:HI 2 "register_operand" "r")))
313                  (match_operand:SI 3 "register_operand" "0")))]
314   "TARGET_MAC16"
315   "mula.aa.ll\t%1, %2"
316   [(set_attr "type"     "mac16")
317    (set_attr "mode"     "SI")
318    (set_attr "length"   "3")])
319
320 (define_insn "mulsubhisi"
321   [(set (match_operand:SI 0 "register_operand" "=A")
322         (minus:SI (match_operand:SI 1 "register_operand" "0")
323                   (mult:SI (sign_extend:SI
324                             (match_operand:HI 2 "register_operand" "%r"))
325                            (sign_extend:SI
326                             (match_operand:HI 3 "register_operand" "r")))))]
327   "TARGET_MAC16"
328   "muls.aa.ll\t%2, %3"
329   [(set_attr "type"     "mac16")
330    (set_attr "mode"     "SI")
331    (set_attr "length"   "3")])
332
333 (define_insn "mulsf3"
334   [(set (match_operand:SF 0 "register_operand" "=f")
335         (mult:SF (match_operand:SF 1 "register_operand" "%f")
336                  (match_operand:SF 2 "register_operand" "f")))]
337   "TARGET_HARD_FLOAT"
338   "mul.s\t%0, %1, %2"
339   [(set_attr "type"     "fmadd")
340    (set_attr "mode"     "SF")
341    (set_attr "length"   "3")])
342
343 (define_insn "muladdsf3"
344   [(set (match_operand:SF 0 "register_operand" "=f")
345         (plus:SF (mult:SF (match_operand:SF 1 "register_operand" "%f")
346                           (match_operand:SF 2 "register_operand" "f"))
347                  (match_operand:SF 3 "register_operand" "0")))]
348   "TARGET_HARD_FLOAT && !TARGET_NO_FUSED_MADD"
349   "madd.s\t%0, %1, %2"
350   [(set_attr "type"     "fmadd")
351    (set_attr "mode"     "SF")
352    (set_attr "length"   "3")])
353
354 (define_insn "mulsubsf3"
355   [(set (match_operand:SF 0 "register_operand" "=f")
356         (minus:SF (match_operand:SF 1 "register_operand" "0")
357                   (mult:SF (match_operand:SF 2 "register_operand" "%f")
358                            (match_operand:SF 3 "register_operand" "f"))))]
359   "TARGET_HARD_FLOAT && !TARGET_NO_FUSED_MADD"
360   "msub.s\t%0, %2, %3"
361   [(set_attr "type"     "fmadd")
362    (set_attr "mode"     "SF")
363    (set_attr "length"   "3")])
364
365 \f
366 ;; Division.
367
368 (define_insn "divsi3"
369   [(set (match_operand:SI 0 "register_operand" "=a")
370         (div:SI (match_operand:SI 1 "register_operand" "r")
371                 (match_operand:SI 2 "register_operand" "r")))]
372   "TARGET_DIV32"
373   "quos\t%0, %1, %2"
374   [(set_attr "type"     "div32")
375    (set_attr "mode"     "SI")
376    (set_attr "length"   "3")])
377
378 (define_insn "udivsi3"
379   [(set (match_operand:SI 0 "register_operand" "=a")
380         (udiv:SI (match_operand:SI 1 "register_operand" "r")
381                  (match_operand:SI 2 "register_operand" "r")))]
382   "TARGET_DIV32"
383   "quou\t%0, %1, %2"
384   [(set_attr "type"     "div32")
385    (set_attr "mode"     "SI")
386    (set_attr "length"   "3")])
387
388 (define_insn "divsf3"
389   [(set (match_operand:SF 0 "register_operand" "=f")
390         (div:SF (match_operand:SF 1 "register_operand" "f")
391                 (match_operand:SF 2 "register_operand" "f")))]
392   "TARGET_HARD_FLOAT_DIV"
393   "div.s\t%0, %1, %2"
394   [(set_attr "type"     "fdiv")
395    (set_attr "mode"     "SF")
396    (set_attr "length"   "3")])
397
398 (define_insn "*recipsf2"
399   [(set (match_operand:SF 0 "register_operand" "=f")
400         (div:SF (match_operand:SF 1 "const_float_1_operand" "")
401                 (match_operand:SF 2 "register_operand" "f")))]
402   "TARGET_HARD_FLOAT_RECIP && flag_unsafe_math_optimizations"
403   "recip.s\t%0, %2"
404   [(set_attr "type"     "fdiv")
405    (set_attr "mode"     "SF")
406    (set_attr "length"   "3")])
407
408 \f
409 ;; Remainders.
410
411 (define_insn "modsi3"
412   [(set (match_operand:SI 0 "register_operand" "=a")
413         (mod:SI (match_operand:SI 1 "register_operand" "r")
414                 (match_operand:SI 2 "register_operand" "r")))]
415   "TARGET_DIV32"
416   "rems\t%0, %1, %2"
417   [(set_attr "type"     "div32")
418    (set_attr "mode"     "SI")
419    (set_attr "length"   "3")])
420
421 (define_insn "umodsi3"
422   [(set (match_operand:SI 0 "register_operand" "=a")
423         (umod:SI (match_operand:SI 1 "register_operand" "r")
424                  (match_operand:SI 2 "register_operand" "r")))]
425   "TARGET_DIV32"
426   "remu\t%0, %1, %2"
427   [(set_attr "type"     "div32")
428    (set_attr "mode"     "SI")
429    (set_attr "length"   "3")])
430
431 \f
432 ;; Square roots.
433
434 (define_insn "sqrtsf2"
435   [(set (match_operand:SF 0 "register_operand" "=f")
436         (sqrt:SF (match_operand:SF 1 "register_operand" "f")))]
437   "TARGET_HARD_FLOAT_SQRT"
438   "sqrt.s\t%0, %1"
439   [(set_attr "type"     "fsqrt")
440    (set_attr "mode"     "SF")
441    (set_attr "length"   "3")])
442
443 (define_insn "*rsqrtsf2"
444   [(set (match_operand:SF 0 "register_operand" "=f")
445         (div:SF (match_operand:SF 1 "const_float_1_operand" "")
446                 (sqrt:SF (match_operand:SF 2 "register_operand" "f"))))]
447   "TARGET_HARD_FLOAT_RSQRT && flag_unsafe_math_optimizations"
448   "rsqrt.s\t%0, %2"
449   [(set_attr "type"     "fsqrt")
450    (set_attr "mode"     "SF")
451    (set_attr "length"   "3")])
452
453 \f
454 ;; Absolute value.
455
456 (define_insn "abssi2"
457   [(set (match_operand:SI 0 "register_operand" "=a")
458         (abs:SI (match_operand:SI 1 "register_operand" "r")))]
459   "TARGET_ABS"
460   "abs\t%0, %1"
461   [(set_attr "type"     "arith")
462    (set_attr "mode"     "SI")
463    (set_attr "length"   "3")])
464
465 (define_insn "abssf2"
466   [(set (match_operand:SF 0 "register_operand" "=f")
467         (abs:SF (match_operand:SF 1 "register_operand" "f")))]
468   "TARGET_HARD_FLOAT"
469   "abs.s\t%0, %1"
470   [(set_attr "type"     "farith")
471    (set_attr "mode"     "SF")
472    (set_attr "length"   "3")])
473
474 \f
475 ;; Min and max.
476
477 (define_insn "sminsi3"
478   [(set (match_operand:SI 0 "register_operand" "=a")
479         (smin:SI (match_operand:SI 1 "register_operand" "%r")
480                  (match_operand:SI 2 "register_operand" "r")))]
481   "TARGET_MINMAX"
482   "min\t%0, %1, %2"
483   [(set_attr "type"     "arith")
484    (set_attr "mode"     "SI")
485    (set_attr "length"   "3")])
486
487 (define_insn "uminsi3"
488   [(set (match_operand:SI 0 "register_operand" "=a")
489         (umin:SI (match_operand:SI 1 "register_operand" "%r")
490                  (match_operand:SI 2 "register_operand" "r")))]
491   "TARGET_MINMAX"
492   "minu\t%0, %1, %2"
493   [(set_attr "type"     "arith")
494    (set_attr "mode"     "SI")
495    (set_attr "length"   "3")])
496
497 (define_insn "smaxsi3"
498   [(set (match_operand:SI 0 "register_operand" "=a")
499         (smax:SI (match_operand:SI 1 "register_operand" "%r")
500                  (match_operand:SI 2 "register_operand" "r")))]
501   "TARGET_MINMAX"
502   "max\t%0, %1, %2"
503   [(set_attr "type"     "arith")
504    (set_attr "mode"     "SI")
505    (set_attr "length"   "3")])
506
507 (define_insn "umaxsi3"
508   [(set (match_operand:SI 0 "register_operand" "=a")
509         (umax:SI (match_operand:SI 1 "register_operand" "%r")
510                  (match_operand:SI 2 "register_operand" "r")))]
511   "TARGET_MINMAX"
512   "maxu\t%0, %1, %2"
513   [(set_attr "type"     "arith")
514    (set_attr "mode"     "SI")
515    (set_attr "length"   "3")])
516
517 \f
518 ;; Find first bit.
519
520 (define_expand "ffssi2"
521   [(set (match_operand:SI 0 "register_operand" "")
522         (ffs:SI (match_operand:SI 1 "register_operand" "")))]
523   "TARGET_NSA"
524 {
525   rtx temp = gen_reg_rtx (SImode);
526   emit_insn (gen_negsi2 (temp, operands[1]));
527   emit_insn (gen_andsi3 (temp, temp, operands[1]));
528   emit_insn (gen_nsau (temp, temp));
529   emit_insn (gen_negsi2 (temp, temp));
530   emit_insn (gen_addsi3 (operands[0], temp, GEN_INT (32)));
531   DONE;
532 })
533
534 ;; There is no RTL operator corresponding to NSAU.
535 (define_insn "nsau"
536   [(set (match_operand:SI 0 "register_operand" "=a")
537         (unspec:SI [(match_operand:SI 1 "register_operand" "r")] UNSPEC_NSAU))]
538   "TARGET_NSA"
539   "nsau\t%0, %1"
540   [(set_attr "type"     "arith")
541    (set_attr "mode"     "SI")
542    (set_attr "length"   "3")])
543
544 \f
545 ;; Negation and one's complement.
546
547 (define_insn "negsi2"
548   [(set (match_operand:SI 0 "register_operand" "=a")
549         (neg:SI (match_operand:SI 1 "register_operand" "r")))]
550   ""
551   "neg\t%0, %1"
552   [(set_attr "type"     "arith")
553    (set_attr "mode"     "SI")
554    (set_attr "length"   "3")])
555
556 (define_expand "one_cmplsi2"
557   [(set (match_operand:SI 0 "register_operand" "")
558         (not:SI (match_operand:SI 1 "register_operand" "")))]
559   ""
560 {
561   rtx temp = gen_reg_rtx (SImode);
562   emit_insn (gen_movsi (temp, constm1_rtx));
563   emit_insn (gen_xorsi3 (operands[0], temp, operands[1]));
564   DONE;
565 })
566
567 (define_insn "negsf2"
568   [(set (match_operand:SF 0 "register_operand" "=f")
569         (neg:SF (match_operand:SF 1 "register_operand" "f")))]
570   "TARGET_HARD_FLOAT"
571   "neg.s\t%0, %1"
572   [(set_attr "type"     "farith")
573    (set_attr "mode"     "SF")
574    (set_attr "length"   "3")])
575
576 \f
577 ;; Logical instructions.
578
579 (define_insn "andsi3"
580   [(set (match_operand:SI 0 "register_operand" "=a,a")
581         (and:SI (match_operand:SI 1 "register_operand" "%r,r")
582                 (match_operand:SI 2 "mask_operand" "P,r")))]
583   ""
584   "@
585    extui\t%0, %1, 0, %K2
586    and\t%0, %1, %2"
587   [(set_attr "type"     "arith,arith")
588    (set_attr "mode"     "SI")
589    (set_attr "length"   "3,3")])
590
591 (define_insn "iorsi3"
592   [(set (match_operand:SI 0 "register_operand" "=a")
593         (ior:SI (match_operand:SI 1 "register_operand" "%r")
594                 (match_operand:SI 2 "register_operand" "r")))]
595   ""
596   "or\t%0, %1, %2"
597   [(set_attr "type"     "arith")
598    (set_attr "mode"     "SI")
599    (set_attr "length"   "3")])
600
601 (define_insn "xorsi3"
602   [(set (match_operand:SI 0 "register_operand" "=a")
603         (xor:SI (match_operand:SI 1 "register_operand" "%r")
604                 (match_operand:SI 2 "register_operand" "r")))]
605   ""
606   "xor\t%0, %1, %2"
607   [(set_attr "type"     "arith")
608    (set_attr "mode"     "SI")
609    (set_attr "length"   "3")])
610
611 \f
612 ;; Zero-extend instructions.
613
614 (define_insn "zero_extendhisi2"
615   [(set (match_operand:SI 0 "register_operand" "=a,a")
616         (zero_extend:SI (match_operand:HI 1 "nonimmed_operand" "r,U")))]
617   ""
618   "@
619    extui\t%0, %1, 0, 16
620    l16ui\t%0, %1"
621   [(set_attr "type"     "arith,load")
622    (set_attr "mode"     "SI")
623    (set_attr "length"   "3,3")])
624
625 (define_insn "zero_extendqisi2"
626   [(set (match_operand:SI 0 "register_operand" "=a,a")
627         (zero_extend:SI (match_operand:QI 1 "nonimmed_operand" "r,U")))]
628   ""
629   "@
630    extui\t%0, %1, 0, 8
631    l8ui\t%0, %1"
632   [(set_attr "type"     "arith,load")
633    (set_attr "mode"     "SI")
634    (set_attr "length"   "3,3")])
635
636 \f
637 ;; Sign-extend instructions.
638
639 (define_expand "extendhisi2"
640   [(set (match_operand:SI 0 "register_operand" "")
641         (sign_extend:SI (match_operand:HI 1 "register_operand" "")))]
642   ""
643 {
644   if (sext_operand (operands[1], HImode))
645     emit_insn (gen_extendhisi2_internal (operands[0], operands[1]));
646   else
647     xtensa_extend_reg (operands[0], operands[1]);
648   DONE;
649 })
650
651 (define_insn "extendhisi2_internal"
652   [(set (match_operand:SI 0 "register_operand" "=B,a")
653         (sign_extend:SI (match_operand:HI 1 "sext_operand" "r,U")))]
654   ""
655   "@
656    sext\t%0, %1, 15
657    l16si\t%0, %1"
658   [(set_attr "type"     "arith,load")
659    (set_attr "mode"     "SI")
660    (set_attr "length"   "3,3")])
661
662 (define_expand "extendqisi2"
663   [(set (match_operand:SI 0 "register_operand" "")
664         (sign_extend:SI (match_operand:QI 1 "register_operand" "")))]
665   ""
666 {
667   if (TARGET_SEXT)
668     emit_insn (gen_extendqisi2_internal (operands[0], operands[1]));
669   else
670     xtensa_extend_reg (operands[0], operands[1]);
671   DONE;
672 })
673
674 (define_insn "extendqisi2_internal"
675   [(set (match_operand:SI 0 "register_operand" "=B")
676         (sign_extend:SI (match_operand:QI 1 "register_operand" "r")))]
677   "TARGET_SEXT"
678   "sext\t%0, %1, 7"
679   [(set_attr "type"     "arith")
680    (set_attr "mode"     "SI")
681    (set_attr "length"   "3")])
682
683 \f
684 ;; Field extract instructions.
685
686 (define_expand "extv"
687   [(set (match_operand:SI 0 "register_operand" "")
688         (sign_extract:SI (match_operand:SI 1 "register_operand" "")
689                          (match_operand:SI 2 "const_int_operand" "")
690                          (match_operand:SI 3 "const_int_operand" "")))]
691   "TARGET_SEXT"
692 {
693   if (!sext_fldsz_operand (operands[2], SImode))
694     FAIL;
695
696   /* We could expand to a right shift followed by SEXT but that's
697      no better than the standard left and right shift sequence.  */
698   if (!lsbitnum_operand (operands[3], SImode))
699     FAIL;
700
701   emit_insn (gen_extv_internal (operands[0], operands[1],
702                                 operands[2], operands[3]));
703   DONE;
704 })
705
706 (define_insn "extv_internal"
707   [(set (match_operand:SI 0 "register_operand" "=a")
708         (sign_extract:SI (match_operand:SI 1 "register_operand" "r")
709                          (match_operand:SI 2 "sext_fldsz_operand" "i")
710                          (match_operand:SI 3 "lsbitnum_operand" "i")))]
711   "TARGET_SEXT"
712 {
713   int fldsz = INTVAL (operands[2]);
714   operands[2] = GEN_INT (fldsz - 1);
715   return "sext\t%0, %1, %2";
716 }
717   [(set_attr "type"     "arith")
718    (set_attr "mode"     "SI")
719    (set_attr "length"   "3")])
720
721 (define_expand "extzv"
722   [(set (match_operand:SI 0 "register_operand" "")
723         (zero_extract:SI (match_operand:SI 1 "register_operand" "")
724                          (match_operand:SI 2 "const_int_operand" "")
725                          (match_operand:SI 3 "const_int_operand" "")))]
726   ""
727 {
728   if (!extui_fldsz_operand (operands[2], SImode))
729     FAIL;
730   emit_insn (gen_extzv_internal (operands[0], operands[1],
731                                  operands[2], operands[3]));
732   DONE;
733 })
734
735 (define_insn "extzv_internal"
736   [(set (match_operand:SI 0 "register_operand" "=a")
737         (zero_extract:SI (match_operand:SI 1 "register_operand" "r")
738                          (match_operand:SI 2 "extui_fldsz_operand" "i")
739                          (match_operand:SI 3 "const_int_operand" "i")))]
740   ""
741 {
742   int shift;
743   if (BITS_BIG_ENDIAN)
744     shift = (32 - (INTVAL (operands[2]) + INTVAL (operands[3]))) & 0x1f;
745   else
746     shift = INTVAL (operands[3]) & 0x1f;
747   operands[3] = GEN_INT (shift);
748   return "extui\t%0, %1, %3, %2";
749 }
750   [(set_attr "type"     "arith")
751    (set_attr "mode"     "SI")
752    (set_attr "length"   "3")])
753
754 \f
755 ;; Conversions.
756
757 (define_insn "fix_truncsfsi2"
758   [(set (match_operand:SI 0 "register_operand" "=a")
759         (fix:SI (match_operand:SF 1 "register_operand" "f")))]
760   "TARGET_HARD_FLOAT"
761   "trunc.s\t%0, %1, 0"
762   [(set_attr "type"     "fconv")
763    (set_attr "mode"     "SF")
764    (set_attr "length"   "3")])
765
766 (define_insn "fixuns_truncsfsi2"
767   [(set (match_operand:SI 0 "register_operand" "=a")
768         (unsigned_fix:SI (match_operand:SF 1 "register_operand" "f")))]
769   "TARGET_HARD_FLOAT"
770   "utrunc.s\t%0, %1, 0"
771   [(set_attr "type"     "fconv")
772    (set_attr "mode"     "SF")
773    (set_attr "length"   "3")])
774
775 (define_insn "floatsisf2"
776   [(set (match_operand:SF 0 "register_operand" "=f")
777         (float:SF (match_operand:SI 1 "register_operand" "a")))]
778   "TARGET_HARD_FLOAT"
779   "float.s\t%0, %1, 0"
780   [(set_attr "type"     "fconv")
781    (set_attr "mode"     "SF")
782    (set_attr "length"   "3")])
783
784 (define_insn "floatunssisf2"
785   [(set (match_operand:SF 0 "register_operand" "=f")
786         (unsigned_float:SF (match_operand:SI 1 "register_operand" "a")))]
787   "TARGET_HARD_FLOAT"
788   "ufloat.s\t%0, %1, 0"
789   [(set_attr "type"     "fconv")
790    (set_attr "mode"     "SF")
791    (set_attr "length"   "3")])
792
793 \f
794 ;; Data movement instructions.
795
796 ;; 64-bit Integer moves
797
798 (define_expand "movdi"
799   [(set (match_operand:DI 0 "nonimmed_operand" "")
800         (match_operand:DI 1 "general_operand" ""))]
801   ""
802 {
803   if (CONSTANT_P (operands[1]) && !TARGET_CONST16)
804     operands[1] = force_const_mem (DImode, operands[1]);
805
806   if (!register_operand (operands[0], DImode)
807       && !register_operand (operands[1], DImode))
808     operands[1] = force_reg (DImode, operands[1]);
809
810   operands[1] = xtensa_copy_incoming_a7 (operands[1]);
811 })
812
813 (define_insn_and_split "movdi_internal"
814   [(set (match_operand:DI 0 "nonimmed_operand" "=a,W,a,a,U")
815         (match_operand:DI 1 "move_operand" "r,i,T,U,r"))]
816   "register_operand (operands[0], DImode)
817    || register_operand (operands[1], DImode)"
818   "#"
819   "reload_completed"
820   [(set (match_dup 0) (match_dup 2))
821    (set (match_dup 1) (match_dup 3))]
822 {
823   xtensa_split_operand_pair (operands, SImode);
824   if (reg_overlap_mentioned_p (operands[0], operands[3]))
825     {
826       rtx tmp;
827       tmp = operands[0], operands[0] = operands[1], operands[1] = tmp;
828       tmp = operands[2], operands[2] = operands[3], operands[3] = tmp;
829     }
830 })
831
832 ;; 32-bit Integer moves
833
834 (define_expand "movsi"
835   [(set (match_operand:SI 0 "nonimmed_operand" "")
836         (match_operand:SI 1 "general_operand" ""))]
837   ""
838 {
839   if (xtensa_emit_move_sequence (operands, SImode))
840     DONE;
841 })
842
843 (define_insn "movsi_internal"
844   [(set (match_operand:SI 0 "nonimmed_operand" "=D,D,D,D,R,R,a,q,a,W,a,a,U,*a,*A")
845         (match_operand:SI 1 "move_operand" "M,D,d,R,D,d,r,r,I,i,T,U,r,*A,*r"))]
846   "xtensa_valid_move (SImode, operands)"
847   "@
848    movi.n\t%0, %x1
849    mov.n\t%0, %1
850    mov.n\t%0, %1
851    %v1l32i.n\t%0, %1
852    %v0s32i.n\t%1, %0
853    %v0s32i.n\t%1, %0
854    mov\t%0, %1
855    movsp\t%0, %1
856    movi\t%0, %x1
857    const16\t%0, %t1\;const16\t%0, %b1
858    %v1l32r\t%0, %1
859    %v1l32i\t%0, %1
860    %v0s32i\t%1, %0
861    rsr\t%0, 16 # ACCLO
862    wsr\t%1, 16 # ACCLO"
863   [(set_attr "type" "move,move,move,load,store,store,move,move,move,move,load,load,store,rsr,wsr")
864    (set_attr "mode"     "SI")
865    (set_attr "length"   "2,2,2,2,2,2,3,3,3,6,3,3,3,3,3")])
866
867 ;; 16-bit Integer moves
868
869 (define_expand "movhi"
870   [(set (match_operand:HI 0 "nonimmed_operand" "")
871         (match_operand:HI 1 "general_operand" ""))]
872   ""
873 {
874   if (xtensa_emit_move_sequence (operands, HImode))
875     DONE;
876 })
877
878 (define_insn "movhi_internal"
879   [(set (match_operand:HI 0 "nonimmed_operand" "=D,D,a,a,a,U,*a,*A")
880         (match_operand:HI 1 "move_operand" "M,d,r,I,U,r,*A,*r"))]
881   "xtensa_valid_move (HImode, operands)"
882   "@
883    movi.n\t%0, %x1
884    mov.n\t%0, %1
885    mov\t%0, %1
886    movi\t%0, %x1
887    %v1l16ui\t%0, %1
888    %v0s16i\t%1, %0
889    rsr\t%0, 16 # ACCLO
890    wsr\t%1, 16 # ACCLO"
891   [(set_attr "type"     "move,move,move,move,load,store,rsr,wsr")
892    (set_attr "mode"     "HI")
893    (set_attr "length"   "2,2,3,3,3,3,3,3")])
894
895 ;; 8-bit Integer moves
896
897 (define_expand "movqi"
898   [(set (match_operand:QI 0 "nonimmed_operand" "")
899         (match_operand:QI 1 "general_operand" ""))]
900   ""
901 {
902   if (xtensa_emit_move_sequence (operands, QImode))
903     DONE;
904 })
905
906 (define_insn "movqi_internal"
907   [(set (match_operand:QI 0 "nonimmed_operand" "=D,D,a,a,a,U,*a,*A")
908         (match_operand:QI 1 "move_operand" "M,d,r,I,U,r,*A,*r"))]
909   "xtensa_valid_move (QImode, operands)"
910   "@
911    movi.n\t%0, %x1
912    mov.n\t%0, %1
913    mov\t%0, %1
914    movi\t%0, %x1
915    %v1l8ui\t%0, %1
916    %v0s8i\t%1, %0
917    rsr\t%0, 16 # ACCLO
918    wsr\t%1, 16 # ACCLO"
919   [(set_attr "type"     "move,move,move,move,load,store,rsr,wsr")
920    (set_attr "mode"     "QI")
921    (set_attr "length"   "2,2,3,3,3,3,3,3")])
922
923 ;; 32-bit floating point moves
924
925 (define_expand "movsf"
926   [(set (match_operand:SF 0 "nonimmed_operand" "")
927         (match_operand:SF 1 "general_operand" ""))]
928   ""
929 {
930   if (!TARGET_CONST16 && CONSTANT_P (operands[1]))
931     operands[1] = force_const_mem (SFmode, operands[1]);
932
933   if ((!register_operand (operands[0], SFmode)
934        && !register_operand (operands[1], SFmode))
935       || (FP_REG_P (xt_true_regnum (operands[0]))
936           && !(reload_in_progress | reload_completed)
937           && (constantpool_mem_p (operands[1])
938               || CONSTANT_P (operands[1]))))
939     operands[1] = force_reg (SFmode, operands[1]);
940
941   operands[1] = xtensa_copy_incoming_a7 (operands[1]);
942 })
943
944 (define_insn "movsf_internal"
945   [(set (match_operand:SF 0 "nonimmed_operand" "=f,f,U,D,D,R,a,f,a,W,a,a,U")
946         (match_operand:SF 1 "move_operand" "f,U,f,d,R,d,r,r,f,iF,T,U,r"))]
947   "((register_operand (operands[0], SFmode)
948      || register_operand (operands[1], SFmode))
949     && !(FP_REG_P (xt_true_regnum (operands[0]))
950          && (constantpool_mem_p (operands[1]) || CONSTANT_P (operands[1]))))"
951   "@
952    mov.s\t%0, %1
953    %v1lsi\t%0, %1
954    %v0ssi\t%1, %0
955    mov.n\t%0, %1
956    %v1l32i.n\t%0, %1
957    %v0s32i.n\t%1, %0
958    mov\t%0, %1
959    wfr\t%0, %1
960    rfr\t%0, %1
961    const16\t%0, %t1\;const16\t%0, %b1
962    %v1l32r\t%0, %1
963    %v1l32i\t%0, %1
964    %v0s32i\t%1, %0"
965   [(set_attr "type"     "farith,fload,fstore,move,load,store,move,farith,farith,move,load,load,store")
966    (set_attr "mode"     "SF")
967    (set_attr "length"   "3,3,3,2,2,2,3,3,3,6,3,3,3")])
968
969 (define_insn "*lsiu"
970   [(set (match_operand:SF 0 "register_operand" "=f")
971         (mem:SF (plus:SI (match_operand:SI 1 "register_operand" "+a")
972                          (match_operand:SI 2 "fpmem_offset_operand" "i"))))
973    (set (match_dup 1)
974         (plus:SI (match_dup 1) (match_dup 2)))]
975   "TARGET_HARD_FLOAT"
976 {
977   if (volatile_refs_p (PATTERN (insn)))
978     output_asm_insn ("memw", operands);
979   return "lsiu\t%0, %1, %2";
980 }
981   [(set_attr "type"     "fload")
982    (set_attr "mode"     "SF")
983    (set_attr "length"   "3")])
984
985 (define_insn "*ssiu"
986   [(set (mem:SF (plus:SI (match_operand:SI 0 "register_operand" "+a")
987                          (match_operand:SI 1 "fpmem_offset_operand" "i")))
988         (match_operand:SF 2 "register_operand" "f"))
989    (set (match_dup 0)
990         (plus:SI (match_dup 0) (match_dup 1)))]
991   "TARGET_HARD_FLOAT"
992 {
993   if (volatile_refs_p (PATTERN (insn)))
994     output_asm_insn ("memw", operands);
995   return "ssiu\t%2, %0, %1";
996 }
997   [(set_attr "type"     "fstore")
998    (set_attr "mode"     "SF")
999    (set_attr "length"   "3")])
1000
1001 ;; 64-bit floating point moves
1002
1003 (define_expand "movdf"
1004   [(set (match_operand:DF 0 "nonimmed_operand" "")
1005         (match_operand:DF 1 "general_operand" ""))]
1006   ""
1007 {
1008   if (CONSTANT_P (operands[1]) && !TARGET_CONST16)
1009     operands[1] = force_const_mem (DFmode, operands[1]);
1010
1011   if (!register_operand (operands[0], DFmode)
1012       && !register_operand (operands[1], DFmode))
1013     operands[1] = force_reg (DFmode, operands[1]);
1014
1015   operands[1] = xtensa_copy_incoming_a7 (operands[1]);
1016 })
1017
1018 (define_insn_and_split "movdf_internal"
1019   [(set (match_operand:DF 0 "nonimmed_operand" "=a,W,a,a,U")
1020         (match_operand:DF 1 "move_operand" "r,iF,T,U,r"))]
1021   "register_operand (operands[0], DFmode)
1022    || register_operand (operands[1], DFmode)"
1023   "#"
1024   "reload_completed"
1025   [(set (match_dup 0) (match_dup 2))
1026    (set (match_dup 1) (match_dup 3))]
1027 {
1028   xtensa_split_operand_pair (operands, SFmode);
1029   if (reg_overlap_mentioned_p (operands[0], operands[3]))
1030     {
1031       rtx tmp;
1032       tmp = operands[0], operands[0] = operands[1], operands[1] = tmp;
1033       tmp = operands[2], operands[2] = operands[3], operands[3] = tmp;
1034     }
1035 })
1036
1037 ;; Block moves
1038
1039 (define_expand "movstrsi"
1040   [(parallel [(set (match_operand:BLK 0 "" "")
1041                    (match_operand:BLK 1 "" ""))
1042               (use (match_operand:SI 2 "arith_operand" ""))
1043               (use (match_operand:SI 3 "const_int_operand" ""))])]
1044   ""
1045 {
1046   if (!xtensa_expand_block_move (operands))
1047     FAIL;
1048   DONE;
1049 })
1050
1051 (define_insn "movstrsi_internal"
1052   [(set (match_operand:BLK 0 "memory_operand" "=U")
1053         (match_operand:BLK 1 "memory_operand" "U"))
1054    (use (match_operand:SI 2 "arith_operand" ""))
1055    (use (match_operand:SI 3 "const_int_operand" ""))
1056    (clobber (match_scratch:SI 4 "=&r"))
1057    (clobber (match_scratch:SI 5 "=&r"))]
1058   ""
1059 {
1060   rtx tmpregs[2];
1061   tmpregs[0] = operands[4];
1062   tmpregs[1] = operands[5];
1063   xtensa_emit_block_move (operands, tmpregs, 1);
1064   return "";
1065 }
1066   [(set_attr "type"     "multi")
1067    (set_attr "mode"     "none")
1068    (set_attr "length"   "300")])
1069
1070 \f
1071 ;; Shift instructions.
1072
1073 (define_expand "ashlsi3"
1074   [(set (match_operand:SI 0 "register_operand" "")
1075         (ashift:SI (match_operand:SI 1 "register_operand" "")
1076                    (match_operand:SI 2 "arith_operand" "")))]
1077   ""
1078 {
1079   operands[1] = xtensa_copy_incoming_a7 (operands[1]);
1080 })
1081
1082 (define_insn "ashlsi3_internal"
1083   [(set (match_operand:SI 0 "register_operand" "=a,a")
1084         (ashift:SI (match_operand:SI 1 "register_operand" "r,r")
1085                    (match_operand:SI 2 "arith_operand" "J,r")))]
1086   ""      
1087   "@
1088    slli\t%0, %1, %R2
1089    ssl\t%2\;sll\t%0, %1"
1090   [(set_attr "type"     "arith,arith")
1091    (set_attr "mode"     "SI")
1092    (set_attr "length"   "3,6")])
1093
1094 (define_insn "ashrsi3"
1095   [(set (match_operand:SI 0 "register_operand" "=a,a")
1096         (ashiftrt:SI (match_operand:SI 1 "register_operand" "r,r")
1097                      (match_operand:SI 2 "arith_operand" "J,r")))]
1098   ""
1099   "@
1100    srai\t%0, %1, %R2
1101    ssr\t%2\;sra\t%0, %1"
1102   [(set_attr "type"     "arith,arith")
1103    (set_attr "mode"     "SI")
1104    (set_attr "length"   "3,6")])
1105
1106 (define_insn "lshrsi3"
1107   [(set (match_operand:SI 0 "register_operand" "=a,a")
1108         (lshiftrt:SI (match_operand:SI 1 "register_operand" "r,r")
1109                      (match_operand:SI 2 "arith_operand" "J,r")))]
1110   ""
1111 {
1112   if (which_alternative == 0)
1113     {
1114       if ((INTVAL (operands[2]) & 0x1f) < 16)
1115         return "srli\t%0, %1, %R2";
1116       else
1117         return "extui\t%0, %1, %R2, %L2";
1118     }
1119   return "ssr\t%2\;srl\t%0, %1";
1120 }
1121   [(set_attr "type"     "arith,arith")
1122    (set_attr "mode"     "SI")
1123    (set_attr "length"   "3,6")])
1124
1125 (define_insn "rotlsi3"
1126   [(set (match_operand:SI 0 "register_operand" "=a,a")
1127         (rotate:SI (match_operand:SI 1 "register_operand" "r,r")
1128                      (match_operand:SI 2 "arith_operand" "J,r")))]
1129   ""
1130   "@
1131    ssai\t%L2\;src\t%0, %1, %1
1132    ssl\t%2\;src\t%0, %1, %1"
1133   [(set_attr "type"     "multi,multi")
1134    (set_attr "mode"     "SI")
1135    (set_attr "length"   "6,6")])
1136
1137 (define_insn "rotrsi3"
1138   [(set (match_operand:SI 0 "register_operand" "=a,a")
1139         (rotatert:SI (match_operand:SI 1 "register_operand" "r,r")
1140                      (match_operand:SI 2 "arith_operand" "J,r")))]
1141   ""
1142   "@
1143    ssai\t%R2\;src\t%0, %1, %1
1144    ssr\t%2\;src\t%0, %1, %1"
1145   [(set_attr "type"     "multi,multi")
1146    (set_attr "mode"     "SI")
1147    (set_attr "length"   "6,6")])
1148
1149 \f
1150 ;; Comparisons.
1151
1152 ;; Handle comparisons by stashing away the operands and then using that
1153 ;; information in the subsequent conditional branch.
1154
1155 (define_expand "cmpsi"
1156   [(set (cc0)
1157         (compare:CC (match_operand:SI 0 "register_operand" "")
1158                     (match_operand:SI 1 "nonmemory_operand" "")))]
1159   ""
1160 {
1161   branch_cmp[0] = operands[0];
1162   branch_cmp[1] = operands[1];
1163   branch_type = CMP_SI;
1164   DONE;
1165 })
1166
1167 (define_expand "tstsi"
1168   [(set (cc0)
1169         (match_operand:SI 0 "register_operand" ""))]
1170   ""
1171 {
1172   branch_cmp[0] = operands[0];
1173   branch_cmp[1] = const0_rtx;
1174   branch_type = CMP_SI;
1175   DONE;
1176 })
1177
1178 (define_expand "cmpsf"
1179   [(set (cc0)
1180         (compare:CC (match_operand:SF 0 "register_operand" "")
1181                     (match_operand:SF 1 "register_operand" "")))]
1182   "TARGET_HARD_FLOAT"
1183 {
1184   branch_cmp[0] = operands[0];
1185   branch_cmp[1] = operands[1];
1186   branch_type = CMP_SF;
1187   DONE;
1188 })
1189
1190 \f
1191 ;; Conditional branches.
1192
1193 (define_expand "beq"
1194   [(set (pc)
1195         (if_then_else (eq (cc0) (const_int 0))
1196                       (label_ref (match_operand 0 "" ""))
1197                       (pc)))]
1198   ""
1199 {
1200   xtensa_expand_conditional_branch (operands, EQ);
1201   DONE;
1202 })
1203
1204 (define_expand "bne"
1205   [(set (pc)
1206         (if_then_else (ne (cc0) (const_int 0))
1207                       (label_ref (match_operand 0 "" ""))
1208                       (pc)))]
1209   ""
1210 {
1211   xtensa_expand_conditional_branch (operands, NE);
1212   DONE;
1213 })
1214
1215 (define_expand "bgt"
1216   [(set (pc)
1217         (if_then_else (gt (cc0) (const_int 0))
1218                       (label_ref (match_operand 0 "" ""))
1219                       (pc)))]
1220   ""
1221 {
1222   xtensa_expand_conditional_branch (operands, GT);
1223   DONE;
1224 })
1225
1226 (define_expand "bge"
1227   [(set (pc)
1228         (if_then_else (ge (cc0) (const_int 0))
1229                       (label_ref (match_operand 0 "" ""))
1230                       (pc)))]
1231   ""
1232 {
1233   xtensa_expand_conditional_branch (operands, GE);
1234   DONE;
1235 })
1236
1237 (define_expand "blt"
1238   [(set (pc)
1239         (if_then_else (lt (cc0) (const_int 0))
1240                       (label_ref (match_operand 0 "" ""))
1241                       (pc)))]
1242   ""
1243 {
1244   xtensa_expand_conditional_branch (operands, LT);
1245   DONE;
1246 })
1247
1248 (define_expand "ble"
1249   [(set (pc)
1250         (if_then_else (le (cc0) (const_int 0))
1251                       (label_ref (match_operand 0 "" ""))
1252                       (pc)))]
1253   ""
1254 {
1255   xtensa_expand_conditional_branch (operands, LE);
1256   DONE;
1257 })
1258
1259 (define_expand "bgtu"
1260   [(set (pc)
1261         (if_then_else (gtu (cc0) (const_int 0))
1262                       (label_ref (match_operand 0 "" ""))
1263                       (pc)))]
1264   ""
1265 {
1266   xtensa_expand_conditional_branch (operands, GTU);
1267   DONE;
1268 })
1269
1270 (define_expand "bgeu"
1271   [(set (pc)
1272         (if_then_else (geu (cc0) (const_int 0))
1273                       (label_ref (match_operand 0 "" ""))
1274                       (pc)))]
1275   ""
1276 {
1277   xtensa_expand_conditional_branch (operands, GEU);
1278   DONE;
1279 })
1280
1281 (define_expand "bltu"
1282   [(set (pc)
1283         (if_then_else (ltu (cc0) (const_int 0))
1284                       (label_ref (match_operand 0 "" ""))
1285                       (pc)))]
1286   ""
1287 {
1288   xtensa_expand_conditional_branch (operands, LTU);
1289   DONE;
1290 })
1291
1292 (define_expand "bleu"
1293   [(set (pc)
1294         (if_then_else (leu (cc0) (const_int 0))
1295                       (label_ref (match_operand 0 "" ""))
1296                       (pc)))]
1297   ""
1298 {
1299   xtensa_expand_conditional_branch (operands, LEU);
1300   DONE;
1301 })
1302
1303 ;; Branch patterns for standard integer comparisons
1304
1305 (define_insn "*btrue"
1306   [(set (pc)
1307         (if_then_else (match_operator 3 "branch_operator"
1308                          [(match_operand:SI 0 "register_operand" "r,r")
1309                           (match_operand:SI 1 "branch_operand" "K,r")])
1310                       (label_ref (match_operand 2 "" ""))
1311                       (pc)))]
1312   ""
1313 {
1314   if (which_alternative == 1)
1315     {
1316       switch (GET_CODE (operands[3]))
1317         {
1318         case EQ:        return "beq\t%0, %1, %2";
1319         case NE:        return "bne\t%0, %1, %2";
1320         case LT:        return "blt\t%0, %1, %2";
1321         case GE:        return "bge\t%0, %1, %2";
1322         default:        break;
1323         }
1324     }
1325   else if (INTVAL (operands[1]) == 0)
1326     {
1327       switch (GET_CODE (operands[3]))
1328         {
1329         case EQ:        return (TARGET_DENSITY
1330                                 ? "beqz.n\t%0, %2"
1331                                 : "beqz\t%0, %2");
1332         case NE:        return (TARGET_DENSITY
1333                                 ? "bnez.n\t%0, %2"
1334                                 : "bnez\t%0, %2");
1335         case LT:        return "bltz\t%0, %2";
1336         case GE:        return "bgez\t%0, %2";
1337         default:        break;
1338         }
1339     }
1340   else
1341     {
1342       switch (GET_CODE (operands[3]))
1343         {
1344         case EQ:        return "beqi\t%0, %d1, %2";
1345         case NE:        return "bnei\t%0, %d1, %2";
1346         case LT:        return "blti\t%0, %d1, %2";
1347         case GE:        return "bgei\t%0, %d1, %2";
1348         default:        break;
1349         }
1350     }
1351   abort ();
1352   return "";
1353 }
1354   [(set_attr "type"     "jump,jump")
1355    (set_attr "mode"     "none")
1356    (set_attr "length"   "3,3")])
1357
1358 (define_insn "*bfalse"
1359   [(set (pc)
1360         (if_then_else (match_operator 3 "branch_operator"
1361                          [(match_operand:SI 0 "register_operand" "r,r")
1362                           (match_operand:SI 1 "branch_operand" "K,r")])
1363                       (pc)
1364                       (label_ref (match_operand 2 "" ""))))]
1365   ""
1366 {
1367   if (which_alternative == 1)
1368     {
1369       switch (GET_CODE (operands[3]))
1370         {
1371         case EQ:        return "bne\t%0, %1, %2";
1372         case NE:        return "beq\t%0, %1, %2";
1373         case LT:        return "bge\t%0, %1, %2";
1374         case GE:        return "blt\t%0, %1, %2";
1375         default:        break;
1376         }
1377     }
1378   else if (INTVAL (operands[1]) == 0)
1379     {
1380       switch (GET_CODE (operands[3]))
1381         {
1382         case EQ:        return (TARGET_DENSITY
1383                                 ? "bnez.n\t%0, %2"
1384                                 : "bnez\t%0, %2");
1385         case NE:        return (TARGET_DENSITY
1386                                 ? "beqz.n\t%0, %2"
1387                                 : "beqz\t%0, %2");
1388         case LT:        return "bgez\t%0, %2";
1389         case GE:        return "bltz\t%0, %2";
1390         default:        break;
1391         }
1392     }
1393   else
1394     {
1395       switch (GET_CODE (operands[3]))
1396         {
1397         case EQ:        return "bnei\t%0, %d1, %2";
1398         case NE:        return "beqi\t%0, %d1, %2";
1399         case LT:        return "bgei\t%0, %d1, %2";
1400         case GE:        return "blti\t%0, %d1, %2";
1401         default:        break;
1402         }
1403     }
1404   abort ();
1405   return "";
1406 }
1407   [(set_attr "type"     "jump,jump")
1408    (set_attr "mode"     "none")
1409    (set_attr "length"   "3,3")])
1410
1411 (define_insn "*ubtrue"
1412   [(set (pc)
1413         (if_then_else (match_operator 3 "ubranch_operator"
1414                          [(match_operand:SI 0 "register_operand" "r,r")
1415                           (match_operand:SI 1 "ubranch_operand" "L,r")])
1416                       (label_ref (match_operand 2 "" ""))
1417                       (pc)))]
1418   ""
1419 {
1420   if (which_alternative == 1)
1421     {
1422       switch (GET_CODE (operands[3]))
1423         {
1424         case LTU:       return "bltu\t%0, %1, %2";
1425         case GEU:       return "bgeu\t%0, %1, %2";
1426         default:        break;
1427         }
1428     }
1429   else
1430     {
1431       switch (GET_CODE (operands[3]))
1432         {
1433         case LTU:       return "bltui\t%0, %d1, %2";
1434         case GEU:       return "bgeui\t%0, %d1, %2";
1435         default:        break;
1436         }
1437     }
1438   abort ();
1439   return "";
1440 }
1441   [(set_attr "type"     "jump,jump")
1442    (set_attr "mode"     "none")
1443    (set_attr "length"   "3,3")])
1444
1445 (define_insn "*ubfalse"
1446   [(set (pc)
1447         (if_then_else (match_operator 3 "ubranch_operator"
1448                          [(match_operand:SI 0 "register_operand" "r,r")
1449                           (match_operand:SI 1 "ubranch_operand" "L,r")])
1450                       (pc)
1451                       (label_ref (match_operand 2 "" ""))))]
1452   ""
1453 {
1454   if (which_alternative == 1)
1455     {
1456       switch (GET_CODE (operands[3]))
1457         {
1458         case LTU:       return "bgeu\t%0, %1, %2";
1459         case GEU:       return "bltu\t%0, %1, %2";
1460         default:        break;
1461         }
1462     }
1463   else
1464     {
1465       switch (GET_CODE (operands[3]))
1466         {
1467         case LTU:       return "bgeui\t%0, %d1, %2";
1468         case GEU:       return "bltui\t%0, %d1, %2";
1469         default:        break;
1470         }
1471     }
1472   abort ();
1473   return "";
1474 }
1475   [(set_attr "type"     "jump,jump")
1476    (set_attr "mode"     "none")
1477    (set_attr "length"   "3,3")])
1478
1479 ;; Branch patterns for bit testing
1480
1481 (define_insn "*bittrue"
1482   [(set (pc)
1483         (if_then_else (match_operator 3 "boolean_operator"
1484                         [(zero_extract:SI
1485                             (match_operand:SI 0 "register_operand" "r,r")
1486                             (const_int 1)
1487                             (match_operand:SI 1 "arith_operand" "J,r"))
1488                          (const_int 0)])
1489                       (label_ref (match_operand 2 "" ""))
1490                       (pc)))]
1491   ""
1492 {
1493   if (which_alternative == 0)
1494     {
1495       unsigned bitnum = INTVAL(operands[1]) & 0x1f;
1496       operands[1] = GEN_INT(bitnum);
1497       switch (GET_CODE (operands[3]))
1498         {
1499         case EQ:        return "bbci\t%0, %d1, %2";
1500         case NE:        return "bbsi\t%0, %d1, %2";
1501         default:        break;
1502         }
1503     }
1504   else
1505     {
1506       switch (GET_CODE (operands[3]))
1507         {
1508         case EQ:        return "bbc\t%0, %1, %2";
1509         case NE:        return "bbs\t%0, %1, %2";
1510         default:        break;
1511         }
1512     }
1513   abort ();
1514   return "";
1515 }
1516   [(set_attr "type"     "jump")
1517    (set_attr "mode"     "none")
1518    (set_attr "length"   "3")])
1519
1520 (define_insn "*bitfalse"
1521   [(set (pc)
1522         (if_then_else (match_operator 3 "boolean_operator"
1523                         [(zero_extract:SI
1524                             (match_operand:SI 0 "register_operand" "r,r")
1525                             (const_int 1)
1526                             (match_operand:SI 1 "arith_operand" "J,r"))
1527                          (const_int 0)])
1528                       (pc)
1529                       (label_ref (match_operand 2 "" ""))))]
1530   ""
1531 {
1532   if (which_alternative == 0)
1533     {
1534       unsigned bitnum = INTVAL (operands[1]) & 0x1f;
1535       operands[1] = GEN_INT (bitnum);
1536       switch (GET_CODE (operands[3]))
1537         {
1538         case EQ:        return "bbsi\t%0, %d1, %2";
1539         case NE:        return "bbci\t%0, %d1, %2";
1540         default:        break;
1541         }
1542     }
1543   else
1544     {
1545       switch (GET_CODE (operands[3]))
1546         {
1547         case EQ:        return "bbs\t%0, %1, %2";
1548         case NE:        return "bbc\t%0, %1, %2";
1549         default:        break;
1550         }
1551     }
1552   abort ();
1553   return "";
1554 }
1555   [(set_attr "type"     "jump")
1556    (set_attr "mode"     "none")
1557    (set_attr "length"   "3")])
1558
1559 (define_insn "*masktrue"
1560   [(set (pc)
1561         (if_then_else (match_operator 3 "boolean_operator"
1562                  [(and:SI (match_operand:SI 0 "register_operand" "r")
1563                           (match_operand:SI 1 "register_operand" "r"))
1564                   (const_int 0)])
1565                       (label_ref (match_operand 2 "" ""))
1566                       (pc)))]
1567   ""
1568 {
1569   switch (GET_CODE (operands[3]))
1570     {
1571     case EQ:            return "bnone\t%0, %1, %2";
1572     case NE:            return "bany\t%0, %1, %2";
1573     default:            break;
1574     }
1575   abort ();
1576   return "";
1577 }
1578   [(set_attr "type"     "jump")
1579    (set_attr "mode"     "none")
1580    (set_attr "length"   "3")])
1581
1582 (define_insn "*maskfalse"
1583   [(set (pc)
1584         (if_then_else (match_operator 3 "boolean_operator"
1585                  [(and:SI (match_operand:SI 0 "register_operand" "r")
1586                           (match_operand:SI 1 "register_operand" "r"))
1587                   (const_int 0)])
1588                       (pc)
1589                       (label_ref (match_operand 2 "" ""))))]
1590   ""
1591 {
1592   switch (GET_CODE (operands[3]))
1593     {
1594     case EQ:            return "bany\t%0, %1, %2";
1595     case NE:            return "bnone\t%0, %1, %2";
1596     default:            break;
1597     }
1598   abort ();
1599   return "";
1600 }
1601   [(set_attr "type"     "jump")
1602    (set_attr "mode"     "none")
1603    (set_attr "length"   "3")])
1604
1605
1606 ;; Define the loop insns used by bct optimization to represent the
1607 ;; start and end of a zero-overhead loop (in loop.c).  This start
1608 ;; template generates the loop insn; the end template doesn't generate
1609 ;; any instructions since loop end is handled in hardware.
1610
1611 (define_insn "zero_cost_loop_start"
1612   [(set (pc)
1613         (if_then_else (eq (match_operand:SI 0 "register_operand" "a")
1614                           (const_int 0))
1615                       (label_ref (match_operand 1 "" ""))
1616                       (pc)))
1617    (set (reg:SI 19)
1618         (plus:SI (match_dup 0) (const_int -1)))]
1619   ""
1620   "loopnez\t%0, %l1"
1621   [(set_attr "type"     "jump")
1622    (set_attr "mode"     "none")
1623    (set_attr "length"   "3")])
1624
1625 (define_insn "zero_cost_loop_end"
1626   [(set (pc)
1627         (if_then_else (ne (reg:SI 19) (const_int 0))
1628                       (label_ref (match_operand 0 "" ""))
1629                       (pc)))
1630    (set (reg:SI 19)
1631         (plus:SI (reg:SI 19) (const_int -1)))]
1632   ""
1633 {
1634     xtensa_emit_loop_end (insn, operands);
1635     return "";
1636 }
1637   [(set_attr "type"     "jump")
1638    (set_attr "mode"     "none")
1639    (set_attr "length"   "0")])
1640
1641 \f
1642 ;; Setting a register from a comparison.
1643
1644 (define_expand "seq"
1645   [(set (match_operand:SI 0 "register_operand" "")
1646         (match_dup 1))]
1647   ""
1648 {
1649   operands[1] = gen_rtx_EQ (SImode, branch_cmp[0], branch_cmp[1]);
1650   if (!xtensa_expand_scc (operands))
1651     FAIL;
1652   DONE;
1653 })
1654
1655 (define_expand "sne"
1656   [(set (match_operand:SI 0 "register_operand" "")
1657         (match_dup 1))]
1658   ""
1659 {
1660   operands[1] = gen_rtx_NE (SImode, branch_cmp[0], branch_cmp[1]);
1661   if (!xtensa_expand_scc (operands))
1662     FAIL;
1663   DONE;
1664 })
1665
1666 (define_expand "sgt"
1667   [(set (match_operand:SI 0 "register_operand" "")
1668         (match_dup 1))]
1669   ""
1670 {
1671   operands[1] = gen_rtx_GT (SImode, branch_cmp[0], branch_cmp[1]);
1672   if (!xtensa_expand_scc (operands))
1673     FAIL;
1674   DONE;
1675 })
1676
1677 (define_expand "sge"
1678   [(set (match_operand:SI 0 "register_operand" "")
1679         (match_dup 1))]
1680   ""
1681 {
1682   operands[1] = gen_rtx_GE (SImode, branch_cmp[0], branch_cmp[1]);
1683   if (!xtensa_expand_scc (operands))
1684     FAIL;
1685   DONE;
1686 })
1687
1688 (define_expand "slt"
1689   [(set (match_operand:SI 0 "register_operand" "")
1690         (match_dup 1))]
1691   ""
1692 {
1693   operands[1] = gen_rtx_LT (SImode, branch_cmp[0], branch_cmp[1]);
1694   if (!xtensa_expand_scc (operands))
1695     FAIL;
1696   DONE;
1697 })
1698
1699 (define_expand "sle"
1700   [(set (match_operand:SI 0 "register_operand" "")
1701         (match_dup 1))]
1702   ""
1703 {
1704   operands[1] = gen_rtx_LE (SImode, branch_cmp[0], branch_cmp[1]);
1705   if (!xtensa_expand_scc (operands))
1706     FAIL;
1707   DONE;
1708 })
1709
1710 \f
1711 ;; Conditional moves.
1712
1713 (define_expand "movsicc"
1714   [(set (match_operand:SI 0 "register_operand" "")
1715         (if_then_else:SI (match_operand 1 "comparison_operator" "")
1716                          (match_operand:SI 2 "register_operand" "")
1717                          (match_operand:SI 3 "register_operand" "")))]
1718   ""
1719 {
1720   if (!xtensa_expand_conditional_move (operands, 0))
1721     FAIL;
1722   DONE;
1723 })
1724
1725 (define_expand "movsfcc"
1726   [(set (match_operand:SF 0 "register_operand" "")
1727         (if_then_else:SF (match_operand 1 "comparison_operator" "")
1728                          (match_operand:SF 2 "register_operand" "")
1729                          (match_operand:SF 3 "register_operand" "")))]
1730   ""
1731 {
1732   if (!xtensa_expand_conditional_move (operands, 1))
1733     FAIL;
1734   DONE;
1735 })
1736
1737 (define_insn "movsicc_internal0"
1738   [(set (match_operand:SI 0 "register_operand" "=a,a")
1739         (if_then_else:SI (match_operator 4 "branch_operator"
1740                            [(match_operand:SI 1 "register_operand" "r,r")
1741                             (const_int 0)])
1742                          (match_operand:SI 2 "register_operand" "r,0")
1743                          (match_operand:SI 3 "register_operand" "0,r")))]
1744   ""
1745 {
1746   if (which_alternative == 0)
1747     {
1748       switch (GET_CODE (operands[4]))
1749         {
1750         case EQ:        return "moveqz\t%0, %2, %1";
1751         case NE:        return "movnez\t%0, %2, %1";
1752         case LT:        return "movltz\t%0, %2, %1";
1753         case GE:        return "movgez\t%0, %2, %1";
1754         default:        break;
1755         }
1756     }
1757   else
1758     {
1759       switch (GET_CODE (operands[4]))
1760         {
1761         case EQ:        return "movnez\t%0, %3, %1";
1762         case NE:        return "moveqz\t%0, %3, %1";
1763         case LT:        return "movgez\t%0, %3, %1";
1764         case GE:        return "movltz\t%0, %3, %1";
1765         default:        break;
1766         }
1767     }
1768   abort ();
1769   return "";
1770 }
1771   [(set_attr "type"     "move,move")
1772    (set_attr "mode"     "SI")
1773    (set_attr "length"   "3,3")])
1774
1775 (define_insn "movsicc_internal1"
1776   [(set (match_operand:SI 0 "register_operand" "=a,a")
1777         (if_then_else:SI (match_operator 4 "boolean_operator"
1778                            [(match_operand:CC 1 "register_operand" "b,b")
1779                             (const_int 0)])
1780                          (match_operand:SI 2 "register_operand" "r,0")
1781                          (match_operand:SI 3 "register_operand" "0,r")))]
1782   "TARGET_BOOLEANS"
1783 {
1784   int isEq = (GET_CODE (operands[4]) == EQ);
1785   switch (which_alternative)
1786     {
1787     case 0:
1788       if (isEq) return "movf\t%0, %2, %1";
1789       return "movt\t%0, %2, %1";
1790     case 1:
1791       if (isEq) return "movt\t%0, %3, %1";
1792       return "movf\t%0, %3, %1";
1793     }
1794   abort ();
1795   return "";
1796 }
1797   [(set_attr "type"     "move,move")
1798    (set_attr "mode"     "SI")
1799    (set_attr "length"   "3,3")])
1800
1801 (define_insn "movsfcc_internal0"
1802   [(set (match_operand:SF 0 "register_operand" "=a,a,f,f")
1803         (if_then_else:SF (match_operator 4 "branch_operator"
1804                            [(match_operand:SI 1 "register_operand" "r,r,r,r")
1805                             (const_int 0)])
1806                          (match_operand:SF 2 "register_operand" "r,0,f,0")
1807                          (match_operand:SF 3 "register_operand" "0,r,0,f")))]
1808   ""
1809 {
1810   if (which_alternative == 0)
1811     {
1812       switch (GET_CODE (operands[4]))
1813         {
1814         case EQ:        return "moveqz\t%0, %2, %1";
1815         case NE:        return "movnez\t%0, %2, %1";
1816         case LT:        return "movltz\t%0, %2, %1";
1817         case GE:        return "movgez\t%0, %2, %1";
1818         default:        break;
1819         }
1820     }
1821   else if (which_alternative == 1)
1822     {
1823       switch (GET_CODE (operands[4]))
1824         {
1825         case EQ:        return "movnez\t%0, %3, %1";
1826         case NE:        return "moveqz\t%0, %3, %1";
1827         case LT:        return "movgez\t%0, %3, %1";
1828         case GE:        return "movltz\t%0, %3, %1";
1829         default:        break;
1830         }
1831     }
1832   else if (which_alternative == 2)
1833     {
1834       switch (GET_CODE (operands[4]))
1835         {
1836         case EQ:        return "moveqz.s %0, %2, %1";
1837         case NE:        return "movnez.s %0, %2, %1";
1838         case LT:        return "movltz.s %0, %2, %1";
1839         case GE:        return "movgez.s %0, %2, %1";
1840         default:        break;
1841         }
1842     }
1843   else if (which_alternative == 3)
1844     {
1845       switch (GET_CODE (operands[4]))
1846         {
1847         case EQ:        return "movnez.s %0, %3, %1";
1848         case NE:        return "moveqz.s %0, %3, %1";
1849         case LT:        return "movgez.s %0, %3, %1";
1850         case GE:        return "movltz.s %0, %3, %1";
1851         default:        break;
1852         }
1853     }
1854   abort ();
1855   return "";
1856 }
1857   [(set_attr "type"     "move,move,move,move")
1858    (set_attr "mode"     "SF")
1859    (set_attr "length"   "3,3,3,3")])
1860
1861 (define_insn "movsfcc_internal1"
1862   [(set (match_operand:SF 0 "register_operand" "=a,a,f,f")
1863         (if_then_else:SF (match_operator 4 "boolean_operator"
1864                            [(match_operand:CC 1 "register_operand" "b,b,b,b")
1865                             (const_int 0)])
1866                          (match_operand:SF 2 "register_operand" "r,0,f,0")
1867                          (match_operand:SF 3 "register_operand" "0,r,0,f")))]
1868   "TARGET_BOOLEANS"
1869 {
1870   int isEq = (GET_CODE (operands[4]) == EQ);
1871   switch (which_alternative)
1872     {
1873     case 0:
1874       if (isEq) return "movf\t%0, %2, %1";
1875       return "movt\t%0, %2, %1";
1876     case 1:
1877       if (isEq) return "movt\t%0, %3, %1";
1878       return "movf\t%0, %3, %1";
1879     case 2:
1880       if (isEq) return "movf.s\t%0, %2, %1";
1881       return "movt.s\t%0, %2, %1";
1882     case 3:
1883       if (isEq) return "movt.s\t%0, %3, %1";
1884       return "movf.s\t%0, %3, %1";
1885     }
1886   abort ();
1887   return "";
1888 }
1889   [(set_attr "type"     "move,move,move,move")
1890    (set_attr "mode"     "SF")
1891    (set_attr "length"   "3,3,3,3")])
1892
1893 \f
1894 ;; Floating-point comparisons.
1895
1896 (define_insn "seq_sf"
1897   [(set (match_operand:CC 0 "register_operand" "=b")
1898         (eq:CC (match_operand:SF 1 "register_operand" "f")
1899                (match_operand:SF 2 "register_operand" "f")))]
1900   "TARGET_HARD_FLOAT"
1901   "oeq.s\t%0, %1, %2"
1902   [(set_attr "type"     "farith")
1903    (set_attr "mode"     "BL")
1904    (set_attr "length"   "3")])
1905
1906 (define_insn "slt_sf"
1907   [(set (match_operand:CC 0 "register_operand" "=b")
1908         (lt:CC (match_operand:SF 1 "register_operand" "f")
1909                (match_operand:SF 2 "register_operand" "f")))]
1910   "TARGET_HARD_FLOAT"
1911   "olt.s\t%0, %1, %2"
1912   [(set_attr "type"     "farith")
1913    (set_attr "mode"     "BL")
1914    (set_attr "length"   "3")])
1915
1916 (define_insn "sle_sf"
1917   [(set (match_operand:CC 0 "register_operand" "=b")
1918         (le:CC (match_operand:SF 1 "register_operand" "f")
1919                (match_operand:SF 2 "register_operand" "f")))]
1920   "TARGET_HARD_FLOAT"
1921   "ole.s\t%0, %1, %2"
1922   [(set_attr "type"     "farith")
1923    (set_attr "mode"     "BL")
1924    (set_attr "length"   "3")])
1925
1926 \f
1927 ;; Unconditional branches.
1928
1929 (define_insn "jump"
1930   [(set (pc)
1931         (label_ref (match_operand 0 "" "")))]
1932   ""
1933   "j\t%l0"
1934   [(set_attr "type"     "jump")
1935    (set_attr "mode"     "none")
1936    (set_attr "length"   "3")])
1937
1938 (define_expand "indirect_jump"
1939   [(set (pc)
1940         (match_operand 0 "register_operand" ""))]
1941   ""
1942 {
1943   rtx dest = operands[0];
1944   if (GET_CODE (dest) != REG || GET_MODE (dest) != Pmode)
1945     operands[0] = copy_to_mode_reg (Pmode, dest);
1946
1947   emit_jump_insn (gen_indirect_jump_internal (dest));
1948   DONE;
1949 })
1950
1951 (define_insn "indirect_jump_internal"
1952   [(set (pc) (match_operand:SI 0 "register_operand" "r"))]
1953   ""
1954   "jx\t%0"
1955   [(set_attr "type"     "jump")
1956    (set_attr "mode"     "none")
1957    (set_attr "length"   "3")])
1958
1959
1960 (define_expand "tablejump"
1961   [(use (match_operand:SI 0 "register_operand" ""))
1962    (use (label_ref (match_operand 1 "" "")))]
1963    ""
1964 {
1965   rtx target = operands[0];
1966   if (flag_pic)
1967     {
1968       /* For PIC, the table entry is relative to the start of the table.  */
1969       rtx label = gen_reg_rtx (SImode);
1970       target = gen_reg_rtx (SImode);
1971       emit_move_insn (label, gen_rtx_LABEL_REF (SImode, operands[1]));
1972       emit_insn (gen_addsi3 (target, operands[0], label));
1973     }
1974   emit_jump_insn (gen_tablejump_internal (target, operands[1]));
1975   DONE;
1976 })
1977
1978 (define_insn "tablejump_internal"
1979   [(set (pc)
1980         (match_operand:SI 0 "register_operand" "r"))
1981    (use (label_ref (match_operand 1 "" "")))]
1982   ""
1983   "jx\t%0"
1984   [(set_attr "type"     "jump")
1985    (set_attr "mode"     "none")
1986    (set_attr "length"   "3")])
1987
1988 \f
1989 ;; Function calls.
1990
1991 (define_expand "sym_PLT"
1992   [(const (unspec [(match_operand:SI 0 "" "")] UNSPEC_PLT))]
1993   ""
1994   "")
1995
1996 (define_expand "call"
1997   [(call (match_operand 0 "memory_operand" "")
1998          (match_operand 1 "" ""))]
1999   ""
2000 {
2001   rtx addr = XEXP (operands[0], 0);
2002   if (flag_pic && GET_CODE (addr) == SYMBOL_REF && !SYMBOL_REF_LOCAL_P (addr))
2003     addr = gen_sym_PLT (addr);
2004   if (!call_insn_operand (addr, VOIDmode))
2005     XEXP (operands[0], 0) = copy_to_mode_reg (Pmode, addr);
2006 })
2007
2008 (define_insn "call_internal"
2009   [(call (mem (match_operand:SI 0 "call_insn_operand" "n,i,r"))
2010          (match_operand 1 "" "i,i,i"))]
2011   ""
2012 {
2013   return xtensa_emit_call (0, operands);
2014 }
2015   [(set_attr "type"     "call")
2016    (set_attr "mode"     "none")
2017    (set_attr "length"   "3")])
2018
2019 (define_expand "call_value"
2020   [(set (match_operand 0 "register_operand" "")
2021         (call (match_operand 1 "memory_operand" "")
2022               (match_operand 2 "" "")))]
2023   ""
2024 {
2025   rtx addr = XEXP (operands[1], 0);
2026   if (flag_pic && GET_CODE (addr) == SYMBOL_REF && !SYMBOL_REF_LOCAL_P (addr))
2027     addr = gen_sym_PLT (addr);
2028   if (!call_insn_operand (addr, VOIDmode))
2029     XEXP (operands[1], 0) = copy_to_mode_reg (Pmode, addr);
2030 })
2031
2032 ;; Cannot combine constraints for operand 0 into "afvb":
2033 ;; reload.c:find_reloads seems to assume that grouped constraints somehow
2034 ;; specify related register classes, and when they don't the constraints
2035 ;; fail to match.  By not grouping the constraints, we get the correct
2036 ;; behavior.
2037 (define_insn "call_value_internal"
2038    [(set (match_operand 0 "register_operand" "=af,af,af,v,v,v,b,b,b")
2039          (call (mem (match_operand:SI 1 "call_insn_operand"
2040                                         "n,i,r,n,i,r,n,i,r"))
2041                (match_operand 2 "" "i,i,i,i,i,i,i,i,i")))]
2042   ""
2043 {
2044   return xtensa_emit_call (1, operands);
2045 }
2046   [(set_attr "type"     "call")
2047    (set_attr "mode"     "none")
2048    (set_attr "length"   "3")])
2049
2050 (define_insn "entry"
2051   [(set (reg:SI A1_REG)
2052         (unspec_volatile:SI [(match_operand:SI 0 "const_int_operand" "i")
2053                              (match_operand:SI 1 "const_int_operand" "i")]
2054                             UNSPECV_ENTRY))]
2055   ""
2056 {
2057   if (frame_pointer_needed)
2058     output_asm_insn (".frame\ta7, %0", operands);
2059   else
2060     output_asm_insn (".frame\tsp, %0", operands);
2061   return "entry\tsp, %1";
2062 }
2063   [(set_attr "type"     "move")
2064    (set_attr "mode"     "SI")
2065    (set_attr "length"   "3")])
2066
2067 (define_insn "return"
2068   [(return)
2069    (use (reg:SI A0_REG))]
2070   "reload_completed"
2071 {
2072   return (TARGET_DENSITY ? "retw.n" : "retw");
2073 }
2074   [(set_attr "type"     "jump")
2075    (set_attr "mode"     "none")
2076    (set_attr "length"   "2")])
2077
2078 \f
2079 ;; Miscellaneous instructions.
2080
2081 (define_expand "prologue"
2082   [(const_int 0)]
2083   ""
2084 {
2085   xtensa_expand_prologue ();
2086   DONE;
2087 })
2088
2089 (define_expand "epilogue"
2090   [(return)]
2091   ""
2092 {
2093   emit_jump_insn (gen_return ());
2094   DONE;
2095 })
2096
2097 (define_insn "nop"
2098   [(const_int 0)]
2099   ""
2100 {
2101   return (TARGET_DENSITY ? "nop.n" : "nop");
2102 }
2103   [(set_attr "type"     "nop")
2104    (set_attr "mode"     "none")
2105    (set_attr "length"   "3")])
2106
2107 (define_expand "nonlocal_goto"
2108   [(match_operand:SI 0 "general_operand" "")
2109    (match_operand:SI 1 "general_operand" "")
2110    (match_operand:SI 2 "general_operand" "")
2111    (match_operand:SI 3 "" "")]
2112   ""
2113 {
2114   xtensa_expand_nonlocal_goto (operands);
2115   DONE;
2116 })
2117
2118 ;; Setting up a frame pointer is tricky for Xtensa because GCC doesn't
2119 ;; know if a frame pointer is required until the reload pass, and
2120 ;; because there may be an incoming argument value in the hard frame
2121 ;; pointer register (a7).  If there is an incoming argument in that
2122 ;; register, the "set_frame_ptr" insn gets inserted immediately after
2123 ;; the insn that copies the incoming argument to a pseudo or to the
2124 ;; stack.  This serves several purposes here: (1) it keeps the
2125 ;; optimizer from copy-propagating or scheduling the use of a7 as an
2126 ;; incoming argument away from the beginning of the function; (2) we
2127 ;; can use a post-reload splitter to expand away the insn if a frame
2128 ;; pointer is not required, so that the post-reload scheduler can do
2129 ;; the right thing; and (3) it makes it easy for the prologue expander
2130 ;; to search for this insn to determine whether it should add a new insn
2131 ;; to set up the frame pointer.
2132
2133 (define_insn "set_frame_ptr"
2134   [(set (reg:SI A7_REG) (unspec_volatile:SI [(const_int 0)] UNSPECV_SET_FP))]
2135   ""
2136 {
2137   if (frame_pointer_needed)
2138     return "mov\ta7, sp";
2139   return "";
2140 }
2141   [(set_attr "type"     "move")
2142    (set_attr "mode"     "SI")
2143    (set_attr "length"   "3")])
2144
2145 ;; Post-reload splitter to remove fp assignment when it's not needed.
2146 (define_split
2147   [(set (reg:SI A7_REG) (unspec_volatile:SI [(const_int 0)] UNSPECV_SET_FP))]
2148   "reload_completed && !frame_pointer_needed"
2149   [(unspec [(const_int 0)] UNSPEC_NOP)]
2150   "")
2151
2152 ;; The preceding splitter needs something to split the insn into;
2153 ;; things start breaking if the result is just a "use" so instead we
2154 ;; generate the following insn.
2155 (define_insn "*unspec_nop"
2156   [(unspec [(const_int 0)] UNSPEC_NOP)]
2157   ""
2158   ""
2159   [(set_attr "type"     "nop")
2160    (set_attr "mode"     "none")
2161    (set_attr "length"   "0")])
2162
2163 ;; The fix_return_addr pattern sets the high 2 bits of an address in a
2164 ;; register to match the high bits of the current PC.
2165 (define_insn "fix_return_addr"
2166   [(set (match_operand:SI 0 "register_operand" "=a")
2167         (unspec:SI [(match_operand:SI 1 "register_operand" "r")]
2168                    UNSPEC_RET_ADDR))
2169    (clobber (match_scratch:SI 2 "=r"))
2170    (clobber (match_scratch:SI 3 "=r"))]
2171   ""
2172   "mov\t%2, a0\;call0\t0f\;.align\t4\;0:\;mov\t%3, a0\;mov\ta0, %2\;\
2173 srli\t%3, %3, 30\;slli\t%0, %1, 2\;ssai\t2\;src\t%0, %3, %0"
2174   [(set_attr "type"     "multi")
2175    (set_attr "mode"     "SI")
2176    (set_attr "length"   "24")])
2177
2178 \f
2179 ;; Instructions for the Xtensa "boolean" option.
2180
2181 (define_insn "*booltrue"
2182   [(set (pc)
2183         (if_then_else (match_operator 2 "boolean_operator"
2184                          [(match_operand:CC 0 "register_operand" "b")
2185                           (const_int 0)])
2186                       (label_ref (match_operand 1 "" ""))
2187                       (pc)))]
2188   "TARGET_BOOLEANS"
2189 {
2190   if (GET_CODE (operands[2]) == EQ)
2191     return "bf\t%0, %1";
2192   else
2193     return "bt\t%0, %1";
2194 }
2195   [(set_attr "type"     "jump")
2196    (set_attr "mode"     "none")
2197    (set_attr "length"   "3")])
2198
2199 (define_insn "*boolfalse"
2200   [(set (pc)
2201         (if_then_else (match_operator 2 "boolean_operator"
2202                          [(match_operand:CC 0 "register_operand" "b")
2203                           (const_int 0)])
2204                       (pc)
2205                       (label_ref (match_operand 1 "" ""))))]
2206   "TARGET_BOOLEANS"
2207 {
2208   if (GET_CODE (operands[2]) == EQ)
2209     return "bt\t%0, %1";
2210   else
2211     return "bf\t%0, %1";
2212 }
2213   [(set_attr "type"     "jump")
2214    (set_attr "mode"     "none")
2215    (set_attr "length"   "3")])