OSDN Git Service

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