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