OSDN Git Service

01ec40d63a78931df3ad85c10f6291c93c84940b
[pf3gnuchains/gcc-fork.git] / gcc / config / xtensa / xtensa.md
1 ;; GCC machine description for Tensilica's Xtensa architecture.
2 ;; Copyright (C) 2001 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   if (xtensa_copy_incoming_a7 (operands, DImode))
811     DONE;
812 })
813
814 (define_insn_and_split "movdi_internal"
815   [(set (match_operand:DI 0 "nonimmed_operand" "=a,W,a,a,U")
816         (match_operand:DI 1 "move_operand" "r,i,T,U,r"))]
817   "register_operand (operands[0], DImode)
818    || register_operand (operands[1], DImode)"
819   "#"
820   "reload_completed"
821   [(set (match_dup 0) (match_dup 2))
822    (set (match_dup 1) (match_dup 3))]
823 {
824   xtensa_split_operand_pair (operands, SImode);
825   if (reg_overlap_mentioned_p (operands[0], operands[3]))
826     {
827       rtx tmp;
828       tmp = operands[0], operands[0] = operands[1], operands[1] = tmp;
829       tmp = operands[2], operands[2] = operands[3], operands[3] = tmp;
830     }
831 })
832
833 ;; 32-bit Integer moves
834
835 (define_expand "movsi"
836   [(set (match_operand:SI 0 "nonimmed_operand" "")
837         (match_operand:SI 1 "general_operand" ""))]
838   ""
839 {
840   if (xtensa_emit_move_sequence (operands, SImode))
841     DONE;
842 })
843
844 (define_insn "movsi_internal"
845   [(set (match_operand:SI 0 "nonimmed_operand" "=D,D,D,D,R,R,a,q,a,W,a,a,U,*a,*A")
846         (match_operand:SI 1 "move_operand" "M,D,d,R,D,d,r,r,I,i,T,U,r,*A,*r"))]
847   "xtensa_valid_move (SImode, operands)"
848   "@
849    movi.n\t%0, %x1
850    mov.n\t%0, %1
851    mov.n\t%0, %1
852    %v1l32i.n\t%0, %1
853    %v0s32i.n\t%1, %0
854    %v0s32i.n\t%1, %0
855    mov\t%0, %1
856    movsp\t%0, %1
857    movi\t%0, %x1
858    const16\t%0, %t1\;const16\t%0, %b1
859    %v1l32r\t%0, %1
860    %v1l32i\t%0, %1
861    %v0s32i\t%1, %0
862    rsr\t%0, 16 # ACCLO
863    wsr\t%1, 16 # ACCLO"
864   [(set_attr "type" "move,move,move,load,store,store,move,move,move,move,load,load,store,rsr,wsr")
865    (set_attr "mode"     "SI")
866    (set_attr "length"   "2,2,2,2,2,2,3,3,3,6,3,3,3,3,3")])
867
868 ;; 16-bit Integer moves
869
870 (define_expand "movhi"
871   [(set (match_operand:HI 0 "nonimmed_operand" "")
872         (match_operand:HI 1 "general_operand" ""))]
873   ""
874 {
875   if (xtensa_emit_move_sequence (operands, HImode))
876     DONE;
877 })
878
879 (define_insn "movhi_internal"
880   [(set (match_operand:HI 0 "nonimmed_operand" "=D,D,a,a,a,U,*a,*A")
881         (match_operand:HI 1 "move_operand" "M,d,r,I,U,r,*A,*r"))]
882   "xtensa_valid_move (HImode, operands)"
883   "@
884    movi.n\t%0, %x1
885    mov.n\t%0, %1
886    mov\t%0, %1
887    movi\t%0, %x1
888    %v1l16ui\t%0, %1
889    %v0s16i\t%1, %0
890    rsr\t%0, 16 # ACCLO
891    wsr\t%1, 16 # ACCLO"
892   [(set_attr "type"     "move,move,move,move,load,store,rsr,wsr")
893    (set_attr "mode"     "HI")
894    (set_attr "length"   "2,2,3,3,3,3,3,3")])
895
896 ;; 8-bit Integer moves
897
898 (define_expand "movqi"
899   [(set (match_operand:QI 0 "nonimmed_operand" "")
900         (match_operand:QI 1 "general_operand" ""))]
901   ""
902 {
903   if (xtensa_emit_move_sequence (operands, QImode))
904     DONE;
905 })
906
907 (define_insn "movqi_internal"
908   [(set (match_operand:QI 0 "nonimmed_operand" "=D,D,a,a,a,U,*a,*A")
909         (match_operand:QI 1 "move_operand" "M,d,r,I,U,r,*A,*r"))]
910   "xtensa_valid_move (QImode, operands)"
911   "@
912    movi.n\t%0, %x1
913    mov.n\t%0, %1
914    mov\t%0, %1
915    movi\t%0, %x1
916    %v1l8ui\t%0, %1
917    %v0s8i\t%1, %0
918    rsr\t%0, 16 # ACCLO
919    wsr\t%1, 16 # ACCLO"
920   [(set_attr "type"     "move,move,move,move,load,store,rsr,wsr")
921    (set_attr "mode"     "QI")
922    (set_attr "length"   "2,2,3,3,3,3,3,3")])
923
924 ;; 32-bit floating point moves
925
926 (define_expand "movsf"
927   [(set (match_operand:SF 0 "nonimmed_operand" "")
928         (match_operand:SF 1 "general_operand" ""))]
929   ""
930 {
931   if (!TARGET_CONST16 && CONSTANT_P (operands[1]))
932     operands[1] = force_const_mem (SFmode, operands[1]);
933
934   if (!(reload_in_progress | reload_completed))
935     {
936       if ((!register_operand (operands[0], SFmode)
937            && !register_operand (operands[1], SFmode))
938           || (FP_REG_P (xt_true_regnum (operands[0]))
939               && (constantpool_mem_p (operands[1])
940                   || CONSTANT_P (operands[1]))))
941         operands[1] = force_reg (SFmode, operands[1]);
942
943       if (xtensa_copy_incoming_a7 (operands, SFmode))
944         DONE;
945     }
946 })
947
948 (define_insn "movsf_internal"
949   [(set (match_operand:SF 0 "nonimmed_operand" "=f,f,U,D,D,R,a,f,a,W,a,a,U")
950         (match_operand:SF 1 "move_operand" "f,U,f,d,R,d,r,r,f,iF,T,U,r"))]
951   "((register_operand (operands[0], SFmode)
952      || register_operand (operands[1], SFmode))
953     && !(FP_REG_P (xt_true_regnum (operands[0]))
954          && (constantpool_mem_p (operands[1]) || CONSTANT_P (operands[1]))))"
955   "@
956    mov.s\t%0, %1
957    %v1lsi\t%0, %1
958    %v0ssi\t%1, %0
959    mov.n\t%0, %1
960    %v1l32i.n\t%0, %1
961    %v0s32i.n\t%1, %0
962    mov\t%0, %1
963    wfr\t%0, %1
964    rfr\t%0, %1
965    const16\t%0, %t1\;const16\t%0, %b1
966    %v1l32r\t%0, %1
967    %v1l32i\t%0, %1
968    %v0s32i\t%1, %0"
969   [(set_attr "type"     "farith,fload,fstore,move,load,store,move,farith,farith,move,load,load,store")
970    (set_attr "mode"     "SF")
971    (set_attr "length"   "3,3,3,2,2,2,3,3,3,6,3,3,3")])
972
973 (define_insn "*lsiu"
974   [(set (match_operand:SF 0 "register_operand" "=f")
975         (mem:SF (plus:SI (match_operand:SI 1 "register_operand" "+a")
976                          (match_operand:SI 2 "fpmem_offset_operand" "i"))))
977    (set (match_dup 1)
978         (plus:SI (match_dup 1) (match_dup 2)))]
979   "TARGET_HARD_FLOAT"
980 {
981   if (volatile_refs_p (PATTERN (insn)))
982     output_asm_insn ("memw", operands);
983   return "lsiu\t%0, %1, %2";
984 }
985   [(set_attr "type"     "fload")
986    (set_attr "mode"     "SF")
987    (set_attr "length"   "3")])
988
989 (define_insn "*ssiu"
990   [(set (mem:SF (plus:SI (match_operand:SI 0 "register_operand" "+a")
991                          (match_operand:SI 1 "fpmem_offset_operand" "i")))
992         (match_operand:SF 2 "register_operand" "f"))
993    (set (match_dup 0)
994         (plus:SI (match_dup 0) (match_dup 1)))]
995   "TARGET_HARD_FLOAT"
996 {
997   if (volatile_refs_p (PATTERN (insn)))
998     output_asm_insn ("memw", operands);
999   return "ssiu\t%2, %0, %1";
1000 }
1001   [(set_attr "type"     "fstore")
1002    (set_attr "mode"     "SF")
1003    (set_attr "length"   "3")])
1004
1005 ;; 64-bit floating point moves
1006
1007 (define_expand "movdf"
1008   [(set (match_operand:DF 0 "nonimmed_operand" "")
1009         (match_operand:DF 1 "general_operand" ""))]
1010   ""
1011 {
1012   if (CONSTANT_P (operands[1]) && !TARGET_CONST16)
1013     operands[1] = force_const_mem (DFmode, operands[1]);
1014
1015   if (!register_operand (operands[0], DFmode)
1016       && !register_operand (operands[1], DFmode))
1017     operands[1] = force_reg (DFmode, operands[1]);
1018
1019   if (xtensa_copy_incoming_a7 (operands, DFmode))
1020     DONE;
1021 })
1022
1023 (define_insn_and_split "movdf_internal"
1024   [(set (match_operand:DF 0 "nonimmed_operand" "=a,W,a,a,U")
1025         (match_operand:DF 1 "move_operand" "r,iF,T,U,r"))]
1026   "register_operand (operands[0], DFmode)
1027    || register_operand (operands[1], DFmode)"
1028   "#"
1029   "reload_completed"
1030   [(set (match_dup 0) (match_dup 2))
1031    (set (match_dup 1) (match_dup 3))]
1032 {
1033   xtensa_split_operand_pair (operands, SFmode);
1034   if (reg_overlap_mentioned_p (operands[0], operands[3]))
1035     {
1036       rtx tmp;
1037       tmp = operands[0], operands[0] = operands[1], operands[1] = tmp;
1038       tmp = operands[2], operands[2] = operands[3], operands[3] = tmp;
1039     }
1040 })
1041
1042 ;; Block moves
1043
1044 (define_expand "movstrsi"
1045   [(parallel [(set (match_operand:BLK 0 "" "")
1046                    (match_operand:BLK 1 "" ""))
1047               (use (match_operand:SI 2 "arith_operand" ""))
1048               (use (match_operand:SI 3 "const_int_operand" ""))])]
1049   ""
1050 {
1051   if (!xtensa_expand_block_move (operands))
1052     FAIL;
1053   DONE;
1054 })
1055
1056 (define_insn "movstrsi_internal"
1057   [(set (match_operand:BLK 0 "memory_operand" "=U")
1058         (match_operand:BLK 1 "memory_operand" "U"))
1059    (use (match_operand:SI 2 "arith_operand" ""))
1060    (use (match_operand:SI 3 "const_int_operand" ""))
1061    (clobber (match_scratch:SI 4 "=&r"))
1062    (clobber (match_scratch:SI 5 "=&r"))]
1063   ""
1064 {
1065   rtx tmpregs[2];
1066   tmpregs[0] = operands[4];
1067   tmpregs[1] = operands[5];
1068   xtensa_emit_block_move (operands, tmpregs, 1);
1069   return "";
1070 }
1071   [(set_attr "type"     "multi")
1072    (set_attr "mode"     "none")
1073    (set_attr "length"   "300")])
1074
1075 \f
1076 ;; Shift instructions.
1077
1078 (define_insn "ashlsi3"
1079   [(set (match_operand:SI 0 "register_operand" "=a,a")
1080         (ashift:SI (match_operand:SI 1 "register_operand" "r,r")
1081                    (match_operand:SI 2 "arith_operand" "J,r")))]
1082   ""      
1083   "@
1084    slli\t%0, %1, %R2
1085    ssl\t%2\;sll\t%0, %1"
1086   [(set_attr "type"     "arith,arith")
1087    (set_attr "mode"     "SI")
1088    (set_attr "length"   "3,6")])
1089
1090 (define_insn "ashrsi3"
1091   [(set (match_operand:SI 0 "register_operand" "=a,a")
1092         (ashiftrt:SI (match_operand:SI 1 "register_operand" "r,r")
1093                      (match_operand:SI 2 "arith_operand" "J,r")))]
1094   ""
1095   "@
1096    srai\t%0, %1, %R2
1097    ssr\t%2\;sra\t%0, %1"
1098   [(set_attr "type"     "arith,arith")
1099    (set_attr "mode"     "SI")
1100    (set_attr "length"   "3,6")])
1101
1102 (define_insn "lshrsi3"
1103   [(set (match_operand:SI 0 "register_operand" "=a,a")
1104         (lshiftrt:SI (match_operand:SI 1 "register_operand" "r,r")
1105                      (match_operand:SI 2 "arith_operand" "J,r")))]
1106   ""
1107 {
1108   if (which_alternative == 0)
1109     {
1110       if ((INTVAL (operands[2]) & 0x1f) < 16)
1111         return "srli\t%0, %1, %R2";
1112       else
1113         return "extui\t%0, %1, %R2, %L2";
1114     }
1115   return "ssr\t%2\;srl\t%0, %1";
1116 }
1117   [(set_attr "type"     "arith,arith")
1118    (set_attr "mode"     "SI")
1119    (set_attr "length"   "3,6")])
1120
1121 (define_insn "rotlsi3"
1122   [(set (match_operand:SI 0 "register_operand" "=a,a")
1123         (rotate:SI (match_operand:SI 1 "register_operand" "r,r")
1124                      (match_operand:SI 2 "arith_operand" "J,r")))]
1125   ""
1126   "@
1127    ssai\t%L2\;src\t%0, %1, %1
1128    ssl\t%2\;src\t%0, %1, %1"
1129   [(set_attr "type"     "multi,multi")
1130    (set_attr "mode"     "SI")
1131    (set_attr "length"   "6,6")])
1132
1133 (define_insn "rotrsi3"
1134   [(set (match_operand:SI 0 "register_operand" "=a,a")
1135         (rotatert:SI (match_operand:SI 1 "register_operand" "r,r")
1136                      (match_operand:SI 2 "arith_operand" "J,r")))]
1137   ""
1138   "@
1139    ssai\t%R2\;src\t%0, %1, %1
1140    ssr\t%2\;src\t%0, %1, %1"
1141   [(set_attr "type"     "multi,multi")
1142    (set_attr "mode"     "SI")
1143    (set_attr "length"   "6,6")])
1144
1145 \f
1146 ;; Comparisons.
1147
1148 ;; Handle comparisons by stashing away the operands and then using that
1149 ;; information in the subsequent conditional branch.
1150
1151 (define_expand "cmpsi"
1152   [(set (cc0)
1153         (compare:CC (match_operand:SI 0 "register_operand" "")
1154                     (match_operand:SI 1 "nonmemory_operand" "")))]
1155   ""
1156 {
1157   branch_cmp[0] = operands[0];
1158   branch_cmp[1] = operands[1];
1159   branch_type = CMP_SI;
1160   DONE;
1161 })
1162
1163 (define_expand "tstsi"
1164   [(set (cc0)
1165         (match_operand:SI 0 "register_operand" ""))]
1166   ""
1167 {
1168   branch_cmp[0] = operands[0];
1169   branch_cmp[1] = const0_rtx;
1170   branch_type = CMP_SI;
1171   DONE;
1172 })
1173
1174 (define_expand "cmpsf"
1175   [(set (cc0)
1176         (compare:CC (match_operand:SF 0 "register_operand" "")
1177                     (match_operand:SF 1 "register_operand" "")))]
1178   "TARGET_HARD_FLOAT"
1179 {
1180   branch_cmp[0] = operands[0];
1181   branch_cmp[1] = operands[1];
1182   branch_type = CMP_SF;
1183   DONE;
1184 })
1185
1186 \f
1187 ;; Conditional branches.
1188
1189 (define_expand "beq"
1190   [(set (pc)
1191         (if_then_else (eq (cc0) (const_int 0))
1192                       (label_ref (match_operand 0 "" ""))
1193                       (pc)))]
1194   ""
1195 {
1196   xtensa_expand_conditional_branch (operands, EQ);
1197   DONE;
1198 })
1199
1200 (define_expand "bne"
1201   [(set (pc)
1202         (if_then_else (ne (cc0) (const_int 0))
1203                       (label_ref (match_operand 0 "" ""))
1204                       (pc)))]
1205   ""
1206 {
1207   xtensa_expand_conditional_branch (operands, NE);
1208   DONE;
1209 })
1210
1211 (define_expand "bgt"
1212   [(set (pc)
1213         (if_then_else (gt (cc0) (const_int 0))
1214                       (label_ref (match_operand 0 "" ""))
1215                       (pc)))]
1216   ""
1217 {
1218   xtensa_expand_conditional_branch (operands, GT);
1219   DONE;
1220 })
1221
1222 (define_expand "bge"
1223   [(set (pc)
1224         (if_then_else (ge (cc0) (const_int 0))
1225                       (label_ref (match_operand 0 "" ""))
1226                       (pc)))]
1227   ""
1228 {
1229   xtensa_expand_conditional_branch (operands, GE);
1230   DONE;
1231 })
1232
1233 (define_expand "blt"
1234   [(set (pc)
1235         (if_then_else (lt (cc0) (const_int 0))
1236                       (label_ref (match_operand 0 "" ""))
1237                       (pc)))]
1238   ""
1239 {
1240   xtensa_expand_conditional_branch (operands, LT);
1241   DONE;
1242 })
1243
1244 (define_expand "ble"
1245   [(set (pc)
1246         (if_then_else (le (cc0) (const_int 0))
1247                       (label_ref (match_operand 0 "" ""))
1248                       (pc)))]
1249   ""
1250 {
1251   xtensa_expand_conditional_branch (operands, LE);
1252   DONE;
1253 })
1254
1255 (define_expand "bgtu"
1256   [(set (pc)
1257         (if_then_else (gtu (cc0) (const_int 0))
1258                       (label_ref (match_operand 0 "" ""))
1259                       (pc)))]
1260   ""
1261 {
1262   xtensa_expand_conditional_branch (operands, GTU);
1263   DONE;
1264 })
1265
1266 (define_expand "bgeu"
1267   [(set (pc)
1268         (if_then_else (geu (cc0) (const_int 0))
1269                       (label_ref (match_operand 0 "" ""))
1270                       (pc)))]
1271   ""
1272 {
1273   xtensa_expand_conditional_branch (operands, GEU);
1274   DONE;
1275 })
1276
1277 (define_expand "bltu"
1278   [(set (pc)
1279         (if_then_else (ltu (cc0) (const_int 0))
1280                       (label_ref (match_operand 0 "" ""))
1281                       (pc)))]
1282   ""
1283 {
1284   xtensa_expand_conditional_branch (operands, LTU);
1285   DONE;
1286 })
1287
1288 (define_expand "bleu"
1289   [(set (pc)
1290         (if_then_else (leu (cc0) (const_int 0))
1291                       (label_ref (match_operand 0 "" ""))
1292                       (pc)))]
1293   ""
1294 {
1295   xtensa_expand_conditional_branch (operands, LEU);
1296   DONE;
1297 })
1298
1299 ;; Branch patterns for standard integer comparisons
1300
1301 (define_insn "*btrue"
1302   [(set (pc)
1303         (if_then_else (match_operator 3 "branch_operator"
1304                          [(match_operand:SI 0 "register_operand" "r,r")
1305                           (match_operand:SI 1 "branch_operand" "K,r")])
1306                       (label_ref (match_operand 2 "" ""))
1307                       (pc)))]
1308   ""
1309 {
1310   if (which_alternative == 1)
1311     {
1312       switch (GET_CODE (operands[3]))
1313         {
1314         case EQ:        return "beq\t%0, %1, %2";
1315         case NE:        return "bne\t%0, %1, %2";
1316         case LT:        return "blt\t%0, %1, %2";
1317         case GE:        return "bge\t%0, %1, %2";
1318         default:        break;
1319         }
1320     }
1321   else if (INTVAL (operands[1]) == 0)
1322     {
1323       switch (GET_CODE (operands[3]))
1324         {
1325         case EQ:        return (TARGET_DENSITY
1326                                 ? "beqz.n\t%0, %2"
1327                                 : "beqz\t%0, %2");
1328         case NE:        return (TARGET_DENSITY
1329                                 ? "bnez.n\t%0, %2"
1330                                 : "bnez\t%0, %2");
1331         case LT:        return "bltz\t%0, %2";
1332         case GE:        return "bgez\t%0, %2";
1333         default:        break;
1334         }
1335     }
1336   else
1337     {
1338       switch (GET_CODE (operands[3]))
1339         {
1340         case EQ:        return "beqi\t%0, %d1, %2";
1341         case NE:        return "bnei\t%0, %d1, %2";
1342         case LT:        return "blti\t%0, %d1, %2";
1343         case GE:        return "bgei\t%0, %d1, %2";
1344         default:        break;
1345         }
1346     }
1347   abort ();
1348   return "";
1349 }
1350   [(set_attr "type"     "jump,jump")
1351    (set_attr "mode"     "none")
1352    (set_attr "length"   "3,3")])
1353
1354 (define_insn "*bfalse"
1355   [(set (pc)
1356         (if_then_else (match_operator 3 "branch_operator"
1357                          [(match_operand:SI 0 "register_operand" "r,r")
1358                           (match_operand:SI 1 "branch_operand" "K,r")])
1359                       (pc)
1360                       (label_ref (match_operand 2 "" ""))))]
1361   ""
1362 {
1363   if (which_alternative == 1)
1364     {
1365       switch (GET_CODE (operands[3]))
1366         {
1367         case EQ:        return "bne\t%0, %1, %2";
1368         case NE:        return "beq\t%0, %1, %2";
1369         case LT:        return "bge\t%0, %1, %2";
1370         case GE:        return "blt\t%0, %1, %2";
1371         default:        break;
1372         }
1373     }
1374   else if (INTVAL (operands[1]) == 0)
1375     {
1376       switch (GET_CODE (operands[3]))
1377         {
1378         case EQ:        return (TARGET_DENSITY
1379                                 ? "bnez.n\t%0, %2"
1380                                 : "bnez\t%0, %2");
1381         case NE:        return (TARGET_DENSITY
1382                                 ? "beqz.n\t%0, %2"
1383                                 : "beqz\t%0, %2");
1384         case LT:        return "bgez\t%0, %2";
1385         case GE:        return "bltz\t%0, %2";
1386         default:        break;
1387         }
1388     }
1389   else
1390     {
1391       switch (GET_CODE (operands[3]))
1392         {
1393         case EQ:        return "bnei\t%0, %d1, %2";
1394         case NE:        return "beqi\t%0, %d1, %2";
1395         case LT:        return "bgei\t%0, %d1, %2";
1396         case GE:        return "blti\t%0, %d1, %2";
1397         default:        break;
1398         }
1399     }
1400   abort ();
1401   return "";
1402 }
1403   [(set_attr "type"     "jump,jump")
1404    (set_attr "mode"     "none")
1405    (set_attr "length"   "3,3")])
1406
1407 (define_insn "*ubtrue"
1408   [(set (pc)
1409         (if_then_else (match_operator 3 "ubranch_operator"
1410                          [(match_operand:SI 0 "register_operand" "r,r")
1411                           (match_operand:SI 1 "ubranch_operand" "L,r")])
1412                       (label_ref (match_operand 2 "" ""))
1413                       (pc)))]
1414   ""
1415 {
1416   if (which_alternative == 1)
1417     {
1418       switch (GET_CODE (operands[3]))
1419         {
1420         case LTU:       return "bltu\t%0, %1, %2";
1421         case GEU:       return "bgeu\t%0, %1, %2";
1422         default:        break;
1423         }
1424     }
1425   else
1426     {
1427       switch (GET_CODE (operands[3]))
1428         {
1429         case LTU:       return "bltui\t%0, %d1, %2";
1430         case GEU:       return "bgeui\t%0, %d1, %2";
1431         default:        break;
1432         }
1433     }
1434   abort ();
1435   return "";
1436 }
1437   [(set_attr "type"     "jump,jump")
1438    (set_attr "mode"     "none")
1439    (set_attr "length"   "3,3")])
1440
1441 (define_insn "*ubfalse"
1442   [(set (pc)
1443         (if_then_else (match_operator 3 "ubranch_operator"
1444                          [(match_operand:SI 0 "register_operand" "r,r")
1445                           (match_operand:SI 1 "ubranch_operand" "L,r")])
1446                       (pc)
1447                       (label_ref (match_operand 2 "" ""))))]
1448   ""
1449 {
1450   if (which_alternative == 1)
1451     {
1452       switch (GET_CODE (operands[3]))
1453         {
1454         case LTU:       return "bgeu\t%0, %1, %2";
1455         case GEU:       return "bltu\t%0, %1, %2";
1456         default:        break;
1457         }
1458     }
1459   else
1460     {
1461       switch (GET_CODE (operands[3]))
1462         {
1463         case LTU:       return "bgeui\t%0, %d1, %2";
1464         case GEU:       return "bltui\t%0, %d1, %2";
1465         default:        break;
1466         }
1467     }
1468   abort ();
1469   return "";
1470 }
1471   [(set_attr "type"     "jump,jump")
1472    (set_attr "mode"     "none")
1473    (set_attr "length"   "3,3")])
1474
1475 ;; Branch patterns for bit testing
1476
1477 (define_insn "*bittrue"
1478   [(set (pc)
1479         (if_then_else (match_operator 3 "boolean_operator"
1480                         [(zero_extract:SI
1481                             (match_operand:SI 0 "register_operand" "r,r")
1482                             (const_int 1)
1483                             (match_operand:SI 1 "arith_operand" "J,r"))
1484                          (const_int 0)])
1485                       (label_ref (match_operand 2 "" ""))
1486                       (pc)))]
1487   ""
1488 {
1489   if (which_alternative == 0)
1490     {
1491       unsigned bitnum = INTVAL(operands[1]) & 0x1f;
1492       operands[1] = GEN_INT(bitnum);
1493       switch (GET_CODE (operands[3]))
1494         {
1495         case EQ:        return "bbci\t%0, %d1, %2";
1496         case NE:        return "bbsi\t%0, %d1, %2";
1497         default:        break;
1498         }
1499     }
1500   else
1501     {
1502       switch (GET_CODE (operands[3]))
1503         {
1504         case EQ:        return "bbc\t%0, %1, %2";
1505         case NE:        return "bbs\t%0, %1, %2";
1506         default:        break;
1507         }
1508     }
1509   abort ();
1510   return "";
1511 }
1512   [(set_attr "type"     "jump")
1513    (set_attr "mode"     "none")
1514    (set_attr "length"   "3")])
1515
1516 (define_insn "*bitfalse"
1517   [(set (pc)
1518         (if_then_else (match_operator 3 "boolean_operator"
1519                         [(zero_extract:SI
1520                             (match_operand:SI 0 "register_operand" "r,r")
1521                             (const_int 1)
1522                             (match_operand:SI 1 "arith_operand" "J,r"))
1523                          (const_int 0)])
1524                       (pc)
1525                       (label_ref (match_operand 2 "" ""))))]
1526   ""
1527 {
1528   if (which_alternative == 0)
1529     {
1530       unsigned bitnum = INTVAL (operands[1]) & 0x1f;
1531       operands[1] = GEN_INT (bitnum);
1532       switch (GET_CODE (operands[3]))
1533         {
1534         case EQ:        return "bbsi\t%0, %d1, %2";
1535         case NE:        return "bbci\t%0, %d1, %2";
1536         default:        break;
1537         }
1538     }
1539   else
1540     {
1541       switch (GET_CODE (operands[3]))
1542         {
1543         case EQ:        return "bbs\t%0, %1, %2";
1544         case NE:        return "bbc\t%0, %1, %2";
1545         default:        break;
1546         }
1547     }
1548   abort ();
1549   return "";
1550 }
1551   [(set_attr "type"     "jump")
1552    (set_attr "mode"     "none")
1553    (set_attr "length"   "3")])
1554
1555 (define_insn "*masktrue"
1556   [(set (pc)
1557         (if_then_else (match_operator 3 "boolean_operator"
1558                  [(and:SI (match_operand:SI 0 "register_operand" "r")
1559                           (match_operand:SI 1 "register_operand" "r"))
1560                   (const_int 0)])
1561                       (label_ref (match_operand 2 "" ""))
1562                       (pc)))]
1563   ""
1564 {
1565   switch (GET_CODE (operands[3]))
1566     {
1567     case EQ:            return "bnone\t%0, %1, %2";
1568     case NE:            return "bany\t%0, %1, %2";
1569     default:            break;
1570     }
1571   abort ();
1572   return "";
1573 }
1574   [(set_attr "type"     "jump")
1575    (set_attr "mode"     "none")
1576    (set_attr "length"   "3")])
1577
1578 (define_insn "*maskfalse"
1579   [(set (pc)
1580         (if_then_else (match_operator 3 "boolean_operator"
1581                  [(and:SI (match_operand:SI 0 "register_operand" "r")
1582                           (match_operand:SI 1 "register_operand" "r"))
1583                   (const_int 0)])
1584                       (pc)
1585                       (label_ref (match_operand 2 "" ""))))]
1586   ""
1587 {
1588   switch (GET_CODE (operands[3]))
1589     {
1590     case EQ:            return "bany\t%0, %1, %2";
1591     case NE:            return "bnone\t%0, %1, %2";
1592     default:            break;
1593     }
1594   abort ();
1595   return "";
1596 }
1597   [(set_attr "type"     "jump")
1598    (set_attr "mode"     "none")
1599    (set_attr "length"   "3")])
1600
1601
1602 ;; Define the loop insns used by bct optimization to represent the
1603 ;; start and end of a zero-overhead loop (in loop.c).  This start
1604 ;; template generates the loop insn; the end template doesn't generate
1605 ;; any instructions since loop end is handled in hardware.
1606
1607 (define_insn "zero_cost_loop_start"
1608   [(set (pc)
1609         (if_then_else (eq (match_operand:SI 0 "register_operand" "a")
1610                           (const_int 0))
1611                       (label_ref (match_operand 1 "" ""))
1612                       (pc)))
1613    (set (reg:SI 19)
1614         (plus:SI (match_dup 0) (const_int -1)))]
1615   ""
1616   "loopnez\t%0, %l1"
1617   [(set_attr "type"     "jump")
1618    (set_attr "mode"     "none")
1619    (set_attr "length"   "3")])
1620
1621 (define_insn "zero_cost_loop_end"
1622   [(set (pc)
1623         (if_then_else (ne (reg:SI 19) (const_int 0))
1624                       (label_ref (match_operand 0 "" ""))
1625                       (pc)))
1626    (set (reg:SI 19)
1627         (plus:SI (reg:SI 19) (const_int -1)))]
1628   ""
1629 {
1630     xtensa_emit_loop_end (insn, operands);
1631     return "";
1632 }
1633   [(set_attr "type"     "jump")
1634    (set_attr "mode"     "none")
1635    (set_attr "length"   "0")])
1636
1637 \f
1638 ;; Setting a register from a comparison.
1639
1640 (define_expand "seq"
1641   [(set (match_operand:SI 0 "register_operand" "")
1642         (match_dup 1))]
1643   ""
1644 {
1645   operands[1] = gen_rtx (EQ, SImode, branch_cmp[0], branch_cmp[1]);
1646   if (!xtensa_expand_scc (operands))
1647     FAIL;
1648   DONE;
1649 })
1650
1651 (define_expand "sne"
1652   [(set (match_operand:SI 0 "register_operand" "")
1653         (match_dup 1))]
1654   ""
1655 {
1656   operands[1] = gen_rtx (NE, SImode, branch_cmp[0], branch_cmp[1]);
1657   if (!xtensa_expand_scc (operands))
1658     FAIL;
1659   DONE;
1660 })
1661
1662 (define_expand "sgt"
1663   [(set (match_operand:SI 0 "register_operand" "")
1664         (match_dup 1))]
1665   ""
1666 {
1667   operands[1] = gen_rtx (GT, SImode, branch_cmp[0], branch_cmp[1]);
1668   if (!xtensa_expand_scc (operands))
1669     FAIL;
1670   DONE;
1671 })
1672
1673 (define_expand "sge"
1674   [(set (match_operand:SI 0 "register_operand" "")
1675         (match_dup 1))]
1676   ""
1677 {
1678   operands[1] = gen_rtx (GE, SImode, branch_cmp[0], branch_cmp[1]);
1679   if (!xtensa_expand_scc (operands))
1680     FAIL;
1681   DONE;
1682 })
1683
1684 (define_expand "slt"
1685   [(set (match_operand:SI 0 "register_operand" "")
1686         (match_dup 1))]
1687   ""
1688 {
1689   operands[1] = gen_rtx (LT, SImode, branch_cmp[0], branch_cmp[1]);
1690   if (!xtensa_expand_scc (operands))
1691     FAIL;
1692   DONE;
1693 })
1694
1695 (define_expand "sle"
1696   [(set (match_operand:SI 0 "register_operand" "")
1697         (match_dup 1))]
1698   ""
1699 {
1700   operands[1] = gen_rtx (LE, SImode, branch_cmp[0], branch_cmp[1]);
1701   if (!xtensa_expand_scc (operands))
1702     FAIL;
1703   DONE;
1704 })
1705
1706 \f
1707 ;; Conditional moves.
1708
1709 (define_expand "movsicc"
1710   [(set (match_operand:SI 0 "register_operand" "")
1711         (if_then_else:SI (match_operand 1 "comparison_operator" "")
1712                          (match_operand:SI 2 "register_operand" "")
1713                          (match_operand:SI 3 "register_operand" "")))]
1714   ""
1715 {
1716   if (!xtensa_expand_conditional_move (operands, 0))
1717     FAIL;
1718   DONE;
1719 })
1720
1721 (define_expand "movsfcc"
1722   [(set (match_operand:SF 0 "register_operand" "")
1723         (if_then_else:SF (match_operand 1 "comparison_operator" "")
1724                          (match_operand:SF 2 "register_operand" "")
1725                          (match_operand:SF 3 "register_operand" "")))]
1726   ""
1727 {
1728   if (!xtensa_expand_conditional_move (operands, 1))
1729     FAIL;
1730   DONE;
1731 })
1732
1733 (define_insn "movsicc_internal0"
1734   [(set (match_operand:SI 0 "register_operand" "=a,a")
1735         (if_then_else:SI (match_operator 4 "branch_operator"
1736                            [(match_operand:SI 1 "register_operand" "r,r")
1737                             (const_int 0)])
1738                          (match_operand:SI 2 "register_operand" "r,0")
1739                          (match_operand:SI 3 "register_operand" "0,r")))]
1740   ""
1741 {
1742   if (which_alternative == 0)
1743     {
1744       switch (GET_CODE (operands[4]))
1745         {
1746         case EQ:        return "moveqz\t%0, %2, %1";
1747         case NE:        return "movnez\t%0, %2, %1";
1748         case LT:        return "movltz\t%0, %2, %1";
1749         case GE:        return "movgez\t%0, %2, %1";
1750         default:        break;
1751         }
1752     }
1753   else
1754     {
1755       switch (GET_CODE (operands[4]))
1756         {
1757         case EQ:        return "movnez\t%0, %3, %1";
1758         case NE:        return "moveqz\t%0, %3, %1";
1759         case LT:        return "movgez\t%0, %3, %1";
1760         case GE:        return "movltz\t%0, %3, %1";
1761         default:        break;
1762         }
1763     }
1764   abort ();
1765   return "";
1766 }
1767   [(set_attr "type"     "move,move")
1768    (set_attr "mode"     "SI")
1769    (set_attr "length"   "3,3")])
1770
1771 (define_insn "movsicc_internal1"
1772   [(set (match_operand:SI 0 "register_operand" "=a,a")
1773         (if_then_else:SI (match_operator 4 "boolean_operator"
1774                            [(match_operand:CC 1 "register_operand" "b,b")
1775                             (const_int 0)])
1776                          (match_operand:SI 2 "register_operand" "r,0")
1777                          (match_operand:SI 3 "register_operand" "0,r")))]
1778   "TARGET_BOOLEANS"
1779 {
1780   int isEq = (GET_CODE (operands[4]) == EQ);
1781   switch (which_alternative)
1782     {
1783     case 0:
1784       if (isEq) return "movf\t%0, %2, %1";
1785       return "movt\t%0, %2, %1";
1786     case 1:
1787       if (isEq) return "movt\t%0, %3, %1";
1788       return "movf\t%0, %3, %1";
1789     }
1790   abort ();
1791   return "";
1792 }
1793   [(set_attr "type"     "move,move")
1794    (set_attr "mode"     "SI")
1795    (set_attr "length"   "3,3")])
1796
1797 (define_insn "movsfcc_internal0"
1798   [(set (match_operand:SF 0 "register_operand" "=a,a,f,f")
1799         (if_then_else:SF (match_operator 4 "branch_operator"
1800                            [(match_operand:SI 1 "register_operand" "r,r,r,r")
1801                             (const_int 0)])
1802                          (match_operand:SF 2 "register_operand" "r,0,f,0")
1803                          (match_operand:SF 3 "register_operand" "0,r,0,f")))]
1804   ""
1805 {
1806   if (which_alternative == 0)
1807     {
1808       switch (GET_CODE (operands[4]))
1809         {
1810         case EQ:        return "moveqz\t%0, %2, %1";
1811         case NE:        return "movnez\t%0, %2, %1";
1812         case LT:        return "movltz\t%0, %2, %1";
1813         case GE:        return "movgez\t%0, %2, %1";
1814         default:        break;
1815         }
1816     }
1817   else if (which_alternative == 1)
1818     {
1819       switch (GET_CODE (operands[4]))
1820         {
1821         case EQ:        return "movnez\t%0, %3, %1";
1822         case NE:        return "moveqz\t%0, %3, %1";
1823         case LT:        return "movgez\t%0, %3, %1";
1824         case GE:        return "movltz\t%0, %3, %1";
1825         default:        break;
1826         }
1827     }
1828   else if (which_alternative == 2)
1829     {
1830       switch (GET_CODE (operands[4]))
1831         {
1832         case EQ:        return "moveqz.s %0, %2, %1";
1833         case NE:        return "movnez.s %0, %2, %1";
1834         case LT:        return "movltz.s %0, %2, %1";
1835         case GE:        return "movgez.s %0, %2, %1";
1836         default:        break;
1837         }
1838     }
1839   else if (which_alternative == 3)
1840     {
1841       switch (GET_CODE (operands[4]))
1842         {
1843         case EQ:        return "movnez.s %0, %3, %1";
1844         case NE:        return "moveqz.s %0, %3, %1";
1845         case LT:        return "movgez.s %0, %3, %1";
1846         case GE:        return "movltz.s %0, %3, %1";
1847         default:        break;
1848         }
1849     }
1850   abort ();
1851   return "";
1852 }
1853   [(set_attr "type"     "move,move,move,move")
1854    (set_attr "mode"     "SF")
1855    (set_attr "length"   "3,3,3,3")])
1856
1857 (define_insn "movsfcc_internal1"
1858   [(set (match_operand:SF 0 "register_operand" "=a,a,f,f")
1859         (if_then_else:SF (match_operator 4 "boolean_operator"
1860                            [(match_operand:CC 1 "register_operand" "b,b,b,b")
1861                             (const_int 0)])
1862                          (match_operand:SF 2 "register_operand" "r,0,f,0")
1863                          (match_operand:SF 3 "register_operand" "0,r,0,f")))]
1864   "TARGET_BOOLEANS"
1865 {
1866   int isEq = (GET_CODE (operands[4]) == EQ);
1867   switch (which_alternative)
1868     {
1869     case 0:
1870       if (isEq) return "movf\t%0, %2, %1";
1871       return "movt\t%0, %2, %1";
1872     case 1:
1873       if (isEq) return "movt\t%0, %3, %1";
1874       return "movf\t%0, %3, %1";
1875     case 2:
1876       if (isEq) return "movf.s\t%0, %2, %1";
1877       return "movt.s\t%0, %2, %1";
1878     case 3:
1879       if (isEq) return "movt.s\t%0, %3, %1";
1880       return "movf.s\t%0, %3, %1";
1881     }
1882   abort ();
1883   return "";
1884 }
1885   [(set_attr "type"     "move,move,move,move")
1886    (set_attr "mode"     "SF")
1887    (set_attr "length"   "3,3,3,3")])
1888
1889 \f
1890 ;; Floating-point comparisons.
1891
1892 (define_insn "seq_sf"
1893   [(set (match_operand:CC 0 "register_operand" "=b")
1894         (eq:CC (match_operand:SF 1 "register_operand" "f")
1895                (match_operand:SF 2 "register_operand" "f")))]
1896   "TARGET_HARD_FLOAT"
1897   "oeq.s\t%0, %1, %2"
1898   [(set_attr "type"     "farith")
1899    (set_attr "mode"     "BL")
1900    (set_attr "length"   "3")])
1901
1902 (define_insn "slt_sf"
1903   [(set (match_operand:CC 0 "register_operand" "=b")
1904         (lt:CC (match_operand:SF 1 "register_operand" "f")
1905                (match_operand:SF 2 "register_operand" "f")))]
1906   "TARGET_HARD_FLOAT"
1907   "olt.s\t%0, %1, %2"
1908   [(set_attr "type"     "farith")
1909    (set_attr "mode"     "BL")
1910    (set_attr "length"   "3")])
1911
1912 (define_insn "sle_sf"
1913   [(set (match_operand:CC 0 "register_operand" "=b")
1914         (le:CC (match_operand:SF 1 "register_operand" "f")
1915                (match_operand:SF 2 "register_operand" "f")))]
1916   "TARGET_HARD_FLOAT"
1917   "ole.s\t%0, %1, %2"
1918   [(set_attr "type"     "farith")
1919    (set_attr "mode"     "BL")
1920    (set_attr "length"   "3")])
1921
1922 \f
1923 ;; Unconditional branches.
1924
1925 (define_insn "jump"
1926   [(set (pc)
1927         (label_ref (match_operand 0 "" "")))]
1928   ""
1929   "j\t%l0"
1930   [(set_attr "type"     "jump")
1931    (set_attr "mode"     "none")
1932    (set_attr "length"   "3")])
1933
1934 (define_expand "indirect_jump"
1935   [(set (pc)
1936         (match_operand 0 "register_operand" ""))]
1937   ""
1938 {
1939   rtx dest = operands[0];
1940   if (GET_CODE (dest) != REG || GET_MODE (dest) != Pmode)
1941     operands[0] = copy_to_mode_reg (Pmode, dest);
1942
1943   emit_jump_insn (gen_indirect_jump_internal (dest));
1944   DONE;
1945 })
1946
1947 (define_insn "indirect_jump_internal"
1948   [(set (pc) (match_operand:SI 0 "register_operand" "r"))]
1949   ""
1950   "jx\t%0"
1951   [(set_attr "type"     "jump")
1952    (set_attr "mode"     "none")
1953    (set_attr "length"   "3")])
1954
1955
1956 (define_expand "tablejump"
1957   [(use (match_operand:SI 0 "register_operand" ""))
1958    (use (label_ref (match_operand 1 "" "")))]
1959    ""
1960 {
1961   rtx target = operands[0];
1962   if (flag_pic)
1963     {
1964       /* For PIC, the table entry is relative to the start of the table.  */
1965       rtx label = gen_reg_rtx (SImode);
1966       target = gen_reg_rtx (SImode);
1967       emit_move_insn (label, gen_rtx_LABEL_REF (SImode, operands[1]));
1968       emit_insn (gen_addsi3 (target, operands[0], label));
1969     }
1970   emit_jump_insn (gen_tablejump_internal (target, operands[1]));
1971   DONE;
1972 })
1973
1974 (define_insn "tablejump_internal"
1975   [(set (pc)
1976         (match_operand:SI 0 "register_operand" "r"))
1977    (use (label_ref (match_operand 1 "" "")))]
1978   ""
1979   "jx\t%0"
1980   [(set_attr "type"     "jump")
1981    (set_attr "mode"     "none")
1982    (set_attr "length"   "3")])
1983
1984 \f
1985 ;; Function calls.
1986
1987 (define_expand "sym_PLT"
1988   [(const (unspec [(match_operand:SI 0 "" "")] UNSPEC_PLT))]
1989   ""
1990   "")
1991
1992 (define_expand "call"
1993   [(call (match_operand 0 "memory_operand" "")
1994          (match_operand 1 "" ""))]
1995   ""
1996 {
1997   rtx addr = XEXP (operands[0], 0);
1998   if (flag_pic && GET_CODE (addr) == SYMBOL_REF && !SYMBOL_REF_LOCAL_P (addr))
1999     addr = gen_sym_PLT (addr);
2000   if (!call_insn_operand (addr, VOIDmode))
2001     XEXP (operands[0], 0) = copy_to_mode_reg (Pmode, addr);
2002 })
2003
2004 (define_insn "call_internal"
2005   [(call (mem (match_operand:SI 0 "call_insn_operand" "n,i,r"))
2006          (match_operand 1 "" "i,i,i"))]
2007   ""
2008 {
2009   return xtensa_emit_call (0, operands);
2010 }
2011   [(set_attr "type"     "call")
2012    (set_attr "mode"     "none")
2013    (set_attr "length"   "3")])
2014
2015 (define_expand "call_value"
2016   [(set (match_operand 0 "register_operand" "")
2017         (call (match_operand 1 "memory_operand" "")
2018               (match_operand 2 "" "")))]
2019   ""
2020 {
2021   rtx addr = XEXP (operands[1], 0);
2022   if (flag_pic && GET_CODE (addr) == SYMBOL_REF && !SYMBOL_REF_LOCAL_P (addr))
2023     addr = gen_sym_PLT (addr);
2024   if (!call_insn_operand (addr, VOIDmode))
2025     XEXP (operands[1], 0) = copy_to_mode_reg (Pmode, addr);
2026 })
2027
2028 ;; Cannot combine constraints for operand 0 into "afvb":
2029 ;; reload.c:find_reloads seems to assume that grouped constraints somehow
2030 ;; specify related register classes, and when they don't the constraints
2031 ;; fail to match.  By not grouping the constraints, we get the correct
2032 ;; behavior.
2033 (define_insn "call_value_internal"
2034    [(set (match_operand 0 "register_operand" "=af,af,af,v,v,v,b,b,b")
2035          (call (mem (match_operand:SI 1 "call_insn_operand"
2036                                         "n,i,r,n,i,r,n,i,r"))
2037                (match_operand 2 "" "i,i,i,i,i,i,i,i,i")))]
2038   ""
2039 {
2040   return xtensa_emit_call (1, operands);
2041 }
2042   [(set_attr "type"     "call")
2043    (set_attr "mode"     "none")
2044    (set_attr "length"   "3")])
2045
2046 (define_insn "entry"
2047   [(set (reg:SI A1_REG)
2048         (unspec_volatile:SI [(match_operand:SI 0 "const_int_operand" "i")
2049                              (match_operand:SI 1 "const_int_operand" "i")]
2050                             UNSPECV_ENTRY))]
2051   ""
2052 {
2053   if (frame_pointer_needed)
2054     output_asm_insn (".frame\ta7, %0", operands);
2055   else
2056     output_asm_insn (".frame\tsp, %0", operands);
2057   return "entry\tsp, %1";
2058 }
2059   [(set_attr "type"     "move")
2060    (set_attr "mode"     "SI")
2061    (set_attr "length"   "3")])
2062
2063 (define_insn "return"
2064   [(return)
2065    (use (reg:SI A0_REG))]
2066   "reload_completed"
2067 {
2068   return (TARGET_DENSITY ? "retw.n" : "retw");
2069 }
2070   [(set_attr "type"     "jump")
2071    (set_attr "mode"     "none")
2072    (set_attr "length"   "2")])
2073
2074 \f
2075 ;; Miscellaneous instructions.
2076
2077 (define_expand "prologue"
2078   [(const_int 0)]
2079   ""
2080 {
2081   xtensa_expand_prologue ();
2082   DONE;
2083 })
2084
2085 (define_expand "epilogue"
2086   [(return)]
2087   ""
2088 {
2089   emit_jump_insn (gen_return ());
2090   DONE;
2091 })
2092
2093 (define_insn "nop"
2094   [(const_int 0)]
2095   ""
2096 {
2097   return (TARGET_DENSITY ? "nop.n" : "nop");
2098 }
2099   [(set_attr "type"     "nop")
2100    (set_attr "mode"     "none")
2101    (set_attr "length"   "3")])
2102
2103 (define_expand "nonlocal_goto"
2104   [(match_operand:SI 0 "general_operand" "")
2105    (match_operand:SI 1 "general_operand" "")
2106    (match_operand:SI 2 "general_operand" "")
2107    (match_operand:SI 3 "" "")]
2108   ""
2109 {
2110   xtensa_expand_nonlocal_goto (operands);
2111   DONE;
2112 })
2113
2114 ;; Setting up a frame pointer is tricky for Xtensa because GCC doesn't
2115 ;; know if a frame pointer is required until the reload pass, and
2116 ;; because there may be an incoming argument value in the hard frame
2117 ;; pointer register (a7).  If there is an incoming argument in that
2118 ;; register, the "set_frame_ptr" insn gets inserted immediately after
2119 ;; the insn that copies the incoming argument to a pseudo or to the
2120 ;; stack.  This serves several purposes here: (1) it keeps the
2121 ;; optimizer from copy-propagating or scheduling the use of a7 as an
2122 ;; incoming argument away from the beginning of the function; (2) we
2123 ;; can use a post-reload splitter to expand away the insn if a frame
2124 ;; pointer is not required, so that the post-reload scheduler can do
2125 ;; the right thing; and (3) it makes it easy for the prologue expander
2126 ;; to search for this insn to determine whether it should add a new insn
2127 ;; to set up the frame pointer.
2128
2129 (define_insn "set_frame_ptr"
2130   [(set (reg:SI A7_REG) (unspec_volatile:SI [(const_int 0)] UNSPECV_SET_FP))]
2131   ""
2132 {
2133   if (frame_pointer_needed)
2134     return "mov\ta7, sp";
2135   return "";
2136 }
2137   [(set_attr "type"     "move")
2138    (set_attr "mode"     "SI")
2139    (set_attr "length"   "3")])
2140
2141 ;; Post-reload splitter to remove fp assignment when it's not needed.
2142 (define_split
2143   [(set (reg:SI A7_REG) (unspec_volatile:SI [(const_int 0)] UNSPECV_SET_FP))]
2144   "reload_completed && !frame_pointer_needed"
2145   [(unspec [(const_int 0)] UNSPEC_NOP)]
2146   "")
2147
2148 ;; The preceding splitter needs something to split the insn into;
2149 ;; things start breaking if the result is just a "use" so instead we
2150 ;; generate the following insn.
2151 (define_insn "*unspec_nop"
2152   [(unspec [(const_int 0)] UNSPEC_NOP)]
2153   ""
2154   ""
2155   [(set_attr "type"     "nop")
2156    (set_attr "mode"     "none")
2157    (set_attr "length"   "0")])
2158
2159 ;; The fix_return_addr pattern sets the high 2 bits of an address in a
2160 ;; register to match the high bits of the current PC.
2161 (define_insn "fix_return_addr"
2162   [(set (match_operand:SI 0 "register_operand" "=a")
2163         (unspec:SI [(match_operand:SI 1 "register_operand" "r")]
2164                    UNSPEC_RET_ADDR))
2165    (clobber (match_scratch:SI 2 "=r"))
2166    (clobber (match_scratch:SI 3 "=r"))]
2167   ""
2168   "mov\t%2, a0\;call0\t0f\;.align\t4\;0:\;mov\t%3, a0\;mov\ta0, %2\;\
2169 srli\t%3, %3, 30\;slli\t%0, %1, 2\;ssai\t2\;src\t%0, %3, %0"
2170   [(set_attr "type"     "multi")
2171    (set_attr "mode"     "SI")
2172    (set_attr "length"   "24")])
2173
2174 \f
2175 ;; Instructions for the Xtensa "boolean" option.
2176
2177 (define_insn "*booltrue"
2178   [(set (pc)
2179         (if_then_else (match_operator 2 "boolean_operator"
2180                          [(match_operand:CC 0 "register_operand" "b")
2181                           (const_int 0)])
2182                       (label_ref (match_operand 1 "" ""))
2183                       (pc)))]
2184   "TARGET_BOOLEANS"
2185 {
2186   if (GET_CODE (operands[2]) == EQ)
2187     return "bf\t%0, %1";
2188   else
2189     return "bt\t%0, %1";
2190 }
2191   [(set_attr "type"     "jump")
2192    (set_attr "mode"     "none")
2193    (set_attr "length"   "3")])
2194
2195 (define_insn "*boolfalse"
2196   [(set (pc)
2197         (if_then_else (match_operator 2 "boolean_operator"
2198                          [(match_operand:CC 0 "register_operand" "b")
2199                           (const_int 0)])
2200                       (pc)
2201                       (label_ref (match_operand 1 "" ""))))]
2202   "TARGET_BOOLEANS"
2203 {
2204   if (GET_CODE (operands[2]) == EQ)
2205     return "bt\t%0, %1";
2206   else
2207     return "bf\t%0, %1";
2208 }
2209   [(set_attr "type"     "jump")
2210    (set_attr "mode"     "none")
2211    (set_attr "length"   "3")])