OSDN Git Service

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