* config/xtensa/xtensa.md: Give "*xxx" names to all unnamed insn's.
[official-gcc.git] / gcc / config / xtensa / xtensa.md
blobd4f8c84852e05e438e1f647fa6253a5699ad32c9
1 ;; GCC machine description for Tensilica's Xtensa architecture.
2 ;; Copyright (C) 2001 Free Software Foundation, Inc.
3 ;; Contributed by Bob Wilson (bwilson@tensilica.com) at Tensilica.
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, 59 Temple Place - Suite 330, Boston, MA
20 ;; 02111-1307, USA.
23 ;; ....................
25 ;;      CONSTANTS
27 ;; ....................
30 (define_constants [
31   (A0_REG               0)
32   (A7_REG               7)
34   (UNSPEC_NSAU          1)
35   (UNSPEC_NOP           2)
36   (UNSPEC_PLT           3)
37   (UNSPEC_RET_ADDR      4)
38   (UNSPECV_SET_FP       1)
42 ;; ....................
44 ;;      ATTRIBUTES
46 ;; ....................
49 (define_attr "type"
50   "unknown,jump,call,load,store,move,arith,multi,nop,farith,fmadd,fdiv,fsqrt,fconv,fload,fstore,mul16,mul32,div32,mac16,rsr,wsr"
51   (const_string "unknown"))
53 (define_attr "mode"
54   "unknown,none,QI,HI,SI,DI,SF,DF,BL"
55   (const_string "unknown"))
57 (define_attr "length" "" (const_int 1))
59 ;; Describe a user's asm statement.
60 (define_asm_attributes
61   [(set_attr "type" "multi")])
65 ;; ....................
67 ;;      FUNCTIONAL UNITS
69 ;; ....................
72 (define_function_unit "memory" 1 0 (eq_attr "type" "load,fload") 2 0)
74 (define_function_unit "sreg" 1 1 (eq_attr "type" "rsr") 2 0)
76 (define_function_unit "mul16" 1 0 (eq_attr "type" "mul16") 2 0)
78 (define_function_unit "mul32" 1 0 (eq_attr "type" "mul32") 2 0)
80 (define_function_unit "fpmadd" 1 0 (eq_attr "type" "fmadd") 4 0)
82 (define_function_unit "fpconv" 1 0 (eq_attr "type" "fconv") 2 0)
86 ;;  ....................
88 ;;      ADDITION
90 ;;  ....................
93 (define_expand "adddi3"
94   [(set (match_operand:DI 0 "register_operand" "")
95         (plus:DI (match_operand:DI 1 "register_operand" "")
96                  (match_operand:DI 2 "register_operand" "")))]
97   ""
98   "
100   rtx dstlo = gen_lowpart (SImode, operands[0]);
101   rtx src1lo = gen_lowpart (SImode, operands[1]);
102   rtx src2lo = gen_lowpart (SImode, operands[2]);
104   rtx dsthi = gen_highpart (SImode, operands[0]);
105   rtx src1hi = gen_highpart (SImode, operands[1]);
106   rtx src2hi = gen_highpart (SImode, operands[2]);
108   emit_insn (gen_addsi3 (dstlo, src1lo, src2lo));
109   emit_insn (gen_addsi3 (dsthi, src1hi, src2hi));
110   emit_insn (gen_adddi_carry (dsthi, dstlo, src2lo));
111   DONE;
114 ;; Represent the add-carry operation as an atomic operation instead of
115 ;; expanding it to a conditional branch.  Otherwise, the edge
116 ;; profiling code breaks because inserting the count increment code
117 ;; causes a new jump insn to be added.
119 (define_insn "adddi_carry"
120   [(set (match_operand:SI 0 "register_operand" "+a")
121         (plus:SI (ltu:SI (match_operand:SI 1 "register_operand" "r")
122                          (match_operand:SI 2 "register_operand" "r"))
123                  (match_dup 0)))]
124   ""
125   "bgeu\\t%1, %2, 0f\;addi\\t%0, %0, 1\;0:"
126   [(set_attr "type"     "multi")
127    (set_attr "mode"     "SI")
128    (set_attr "length"   "6")])
130 (define_insn "addsi3"
131   [(set (match_operand:SI 0 "register_operand" "=D,D,a,a,a")
132         (plus:SI (match_operand:SI 1 "register_operand" "%d,d,r,r,r")
133                  (match_operand:SI 2 "add_operand" "d,O,r,J,N")))]
134   ""
135   "@
136    add.n\\t%0, %1, %2
137    addi.n\\t%0, %1, %d2
138    add\\t%0, %1, %2
139    addi\\t%0, %1, %d2
140    addmi\\t%0, %1, %x2"
141   [(set_attr "type"     "arith,arith,arith,arith,arith")
142    (set_attr "mode"     "SI")
143    (set_attr "length"   "2,2,3,3,3")])
145 (define_insn "*addx2"
146   [(set (match_operand:SI 0 "register_operand" "=a")
147         (plus:SI (mult:SI (match_operand:SI 1 "register_operand" "r")
148                           (const_int 2))
149                  (match_operand:SI 2 "register_operand" "r")))]
150   ""
151   "addx2\\t%0, %1, %2"
152   [(set_attr "type"     "arith")
153    (set_attr "mode"     "SI")
154    (set_attr "length"   "3")])
156 (define_insn "*addx4"
157   [(set (match_operand:SI 0 "register_operand" "=a")
158         (plus:SI (mult:SI (match_operand:SI 1 "register_operand" "r")
159                           (const_int 4))
160                  (match_operand:SI 2 "register_operand" "r")))]
161   ""
162   "addx4\\t%0, %1, %2"
163   [(set_attr "type"     "arith")
164    (set_attr "mode"     "SI")
165    (set_attr "length"   "3")])
167 (define_insn "*addx8"
168   [(set (match_operand:SI 0 "register_operand" "=a")
169         (plus:SI (mult:SI (match_operand:SI 1 "register_operand" "r")
170                           (const_int 8))
171                  (match_operand:SI 2 "register_operand" "r")))]
172   ""
173   "addx8\\t%0, %1, %2"
174   [(set_attr "type"     "arith")
175    (set_attr "mode"     "SI")
176    (set_attr "length"   "3")])
178 (define_insn "addsf3"
179   [(set (match_operand:SF 0 "register_operand" "=f")
180         (plus:SF (match_operand:SF 1 "register_operand" "%f")
181                  (match_operand:SF 2 "register_operand" "f")))]
182   "TARGET_HARD_FLOAT"
183   "add.s\\t%0, %1, %2"
184   [(set_attr "type"     "fmadd")
185    (set_attr "mode"     "SF")
186    (set_attr "length"   "3")])
190 ;;  ....................
192 ;;      SUBTRACTION
194 ;;  ....................
197 (define_expand "subdi3"
198   [(set (match_operand:DI 0 "register_operand" "")
199         (minus:DI (match_operand:DI 1 "register_operand" "")
200                   (match_operand:DI 2 "register_operand" "")))]
201   ""
202   "
204   rtx dstlo = gen_lowpart (SImode, operands[0]);
205   rtx src1lo = gen_lowpart (SImode, operands[1]);
206   rtx src2lo = gen_lowpart (SImode, operands[2]);
208   rtx dsthi = gen_highpart (SImode, operands[0]);
209   rtx src1hi = gen_highpart (SImode, operands[1]);
210   rtx src2hi = gen_highpart (SImode, operands[2]);
212   emit_insn (gen_subsi3 (dstlo, src1lo, src2lo));
213   emit_insn (gen_subsi3 (dsthi, src1hi, src2hi));
214   emit_insn (gen_subdi_carry (dsthi, src1lo, src2lo));
215   DONE;
218 (define_insn "subdi_carry"
219   [(set (match_operand:SI 0 "register_operand" "+a")
220         (minus:SI (match_dup 0)
221                   (ltu:SI (match_operand:SI 1 "register_operand" "r")
222                           (match_operand:SI 2 "register_operand" "r"))))]
223   ""
224   "bgeu\\t%1, %2, 0f\;addi\\t%0, %0, -1\;0:"
225   [(set_attr "type"     "multi")
226    (set_attr "mode"     "SI")
227    (set_attr "length"   "6")])
229 (define_insn "subsi3"
230   [(set (match_operand:SI 0 "register_operand" "=a")
231         (minus:SI (match_operand:SI 1 "register_operand" "r")
232                   (match_operand:SI 2 "register_operand" "r")))]
233   ""
234   "sub\\t%0, %1, %2"
235   [(set_attr "type"     "arith")
236    (set_attr "mode"     "SI")
237    (set_attr "length"   "3")])
239 (define_insn "*subx2"
240   [(set (match_operand:SI 0 "register_operand" "=a")
241         (minus:SI (mult:SI (match_operand:SI 1 "register_operand" "r")
242                            (const_int 2))
243                   (match_operand:SI 2 "register_operand" "r")))]
244   ""
245   "subx2\\t%0, %1, %2"
246   [(set_attr "type"     "arith")
247    (set_attr "mode"     "SI")
248    (set_attr "length"   "3")])
250 (define_insn "*subx4"
251   [(set (match_operand:SI 0 "register_operand" "=a")
252         (minus:SI (mult:SI (match_operand:SI 1 "register_operand" "r")
253                            (const_int 4))
254                   (match_operand:SI 2 "register_operand" "r")))]
255   ""
256   "subx4\\t%0, %1, %2"
257   [(set_attr "type"     "arith")
258    (set_attr "mode"     "SI")
259    (set_attr "length"   "3")])
261 (define_insn "*subx8"
262   [(set (match_operand:SI 0 "register_operand" "=a")
263         (minus:SI (mult:SI (match_operand:SI 1 "register_operand" "r")
264                            (const_int 8))
265                   (match_operand:SI 2 "register_operand" "r")))]
266   ""
267   "subx8\\t%0, %1, %2"
268   [(set_attr "type"     "arith")
269    (set_attr "mode"     "SI")
270    (set_attr "length"   "3")])
272 (define_insn "subsf3"
273   [(set (match_operand:SF 0 "register_operand" "=f")
274         (minus:SF (match_operand:SF 1 "register_operand" "f")
275                   (match_operand:SF 2 "register_operand" "f")))]
276   "TARGET_HARD_FLOAT"
277   "sub.s\\t%0, %1, %2"
278   [(set_attr "type"     "fmadd")
279    (set_attr "mode"     "SF")
280    (set_attr "length"   "3")])
284 ;;  ....................
286 ;;      MULTIPLICATION
288 ;;  ....................
291 (define_insn "mulsi3"
292   [(set (match_operand:SI 0 "register_operand" "=a")
293         (mult:SI (match_operand:SI 1 "register_operand" "%r")
294                  (match_operand:SI 2 "register_operand" "r")))]
295   "TARGET_MUL32"
296   "mull\\t%0, %1, %2"
297   [(set_attr "type"     "mul32")
298    (set_attr "mode"     "SI")
299    (set_attr "length"   "3")])
301 (define_insn "mulhisi3"
302   [(set (match_operand:SI 0 "register_operand" "=C,A")
303         (mult:SI (sign_extend:SI
304                   (match_operand:HI 1 "register_operand" "%r,r"))
305                  (sign_extend:SI
306                   (match_operand:HI 2 "register_operand" "r,r"))))]
307   "TARGET_MUL16 || TARGET_MAC16"
308   "@
309    mul16s\\t%0, %1, %2
310    mul.aa.ll\\t%1, %2"
311   [(set_attr "type"     "mul16,mac16")
312    (set_attr "mode"     "SI")
313    (set_attr "length"   "3,3")])
315 (define_insn "umulhisi3"
316   [(set (match_operand:SI 0 "register_operand" "=C,A")
317         (mult:SI (zero_extend:SI
318                   (match_operand:HI 1 "register_operand" "%r,r"))
319                  (zero_extend:SI
320                   (match_operand:HI 2 "register_operand" "r,r"))))]
321   "TARGET_MUL16 || TARGET_MAC16"
322   "@
323    mul16u\\t%0, %1, %2
324    umul.aa.ll\\t%1, %2"
325   [(set_attr "type"     "mul16,mac16")
326    (set_attr "mode"     "SI")
327    (set_attr "length"   "3,3")])
329 (define_insn "muladdhisi"
330   [(set (match_operand:SI 0 "register_operand" "=A")
331         (plus:SI (mult:SI (sign_extend:SI
332                            (match_operand:HI 1 "register_operand" "%r"))
333                           (sign_extend:SI
334                            (match_operand:HI 2 "register_operand" "r")))
335                  (match_operand:SI 3 "register_operand" "0")))]
336   "TARGET_MAC16"
337   "mula.aa.ll\\t%1, %2"
338   [(set_attr "type"     "mac16")
339    (set_attr "mode"     "SI")
340    (set_attr "length"   "3")])
342 (define_insn "mulsubhisi"
343   [(set (match_operand:SI 0 "register_operand" "=A")
344         (minus:SI (match_operand:SI 1 "register_operand" "0")
345                   (mult:SI (sign_extend:SI
346                             (match_operand:HI 2 "register_operand" "%r"))
347                            (sign_extend:SI
348                             (match_operand:HI 3 "register_operand" "r")))))]
349   "TARGET_MAC16"
350   "muls.aa.ll\\t%2, %3"
351   [(set_attr "type"     "mac16")
352    (set_attr "mode"     "SI")
353    (set_attr "length"   "3")])
355 (define_insn "mulsf3"
356   [(set (match_operand:SF 0 "register_operand" "=f")
357         (mult:SF (match_operand:SF 1 "register_operand" "%f")
358                  (match_operand:SF 2 "register_operand" "f")))]
359   "TARGET_HARD_FLOAT"
360   "mul.s\\t%0, %1, %2"
361   [(set_attr "type"     "fmadd")
362    (set_attr "mode"     "SF")
363    (set_attr "length"   "3")])
365 (define_insn "muladdsf3"
366   [(set (match_operand:SF 0 "register_operand" "=f")
367         (plus:SF (mult:SF (match_operand:SF 1 "register_operand" "%f")
368                           (match_operand:SF 2 "register_operand" "f"))
369                  (match_operand:SF 3 "register_operand" "0")))]
370   "TARGET_HARD_FLOAT && !TARGET_NO_FUSED_MADD"
371   "madd.s\\t%0, %1, %2"
372   [(set_attr "type"     "fmadd")
373    (set_attr "mode"     "SF")
374    (set_attr "length"   "3")])
376 (define_insn "mulsubsf3"
377   [(set (match_operand:SF 0 "register_operand" "=f")
378         (minus:SF (match_operand:SF 1 "register_operand" "0")
379                   (mult:SF (match_operand:SF 2 "register_operand" "%f")
380                            (match_operand:SF 3 "register_operand" "f"))))]
381   "TARGET_HARD_FLOAT && !TARGET_NO_FUSED_MADD"
382   "msub.s\\t%0, %2, %3"
383   [(set_attr "type"     "fmadd")
384    (set_attr "mode"     "SF")
385    (set_attr "length"   "3")])
389 ;;  ....................
391 ;;      DIVISION
393 ;;  ....................
396 (define_insn "divsi3"
397   [(set (match_operand:SI 0 "register_operand" "=a")
398         (div:SI (match_operand:SI 1 "register_operand" "r")
399                 (match_operand:SI 2 "register_operand" "r")))]
400   "TARGET_DIV32"
401   "quos\\t%0, %1, %2"
402   [(set_attr "type"     "div32")
403    (set_attr "mode"     "SI")
404    (set_attr "length"   "3")])
406 (define_insn "udivsi3"
407   [(set (match_operand:SI 0 "register_operand" "=a")
408         (udiv:SI (match_operand:SI 1 "register_operand" "r")
409                  (match_operand:SI 2 "register_operand" "r")))]
410   "TARGET_DIV32"
411   "quou\\t%0, %1, %2"
412   [(set_attr "type"     "div32")
413    (set_attr "mode"     "SI")
414    (set_attr "length"   "3")])
416 (define_insn "divsf3"
417   [(set (match_operand:SF 0 "register_operand" "=f")
418         (div:SF (match_operand:SF 1 "register_operand" "f")
419                 (match_operand:SF 2 "register_operand" "f")))]
420   "TARGET_HARD_FLOAT_DIV"
421   "div.s\\t%0, %1, %2"
422   [(set_attr "type"     "fdiv")
423    (set_attr "mode"     "SF")
424    (set_attr "length"   "3")])
426 (define_insn "*recipsf2"
427   [(set (match_operand:SF 0 "register_operand" "=f")
428         (div:SF (match_operand:SF 1 "const_float_1_operand" "")
429                 (match_operand:SF 2 "register_operand" "f")))]
430   "TARGET_HARD_FLOAT_RECIP && flag_unsafe_math_optimizations"
431   "recip.s\\t%0, %2"
432   [(set_attr "type"     "fdiv")
433    (set_attr "mode"     "SF")
434    (set_attr "length"   "3")])
438 ;;  ....................
440 ;;      REMAINDER
442 ;;  ....................
445 (define_insn "modsi3"
446   [(set (match_operand:SI 0 "register_operand" "=a")
447         (mod:SI (match_operand:SI 1 "register_operand" "r")
448                 (match_operand:SI 2 "register_operand" "r")))]
449   "TARGET_DIV32"
450   "rems\\t%0, %1, %2"
451   [(set_attr "type"     "div32")
452    (set_attr "mode"     "SI")
453    (set_attr "length"   "3")])
455 (define_insn "umodsi3"
456   [(set (match_operand:SI 0 "register_operand" "=a")
457         (umod:SI (match_operand:SI 1 "register_operand" "r")
458                  (match_operand:SI 2 "register_operand" "r")))]
459   "TARGET_DIV32"
460   "remu\\t%0, %1, %2"
461   [(set_attr "type"     "div32")
462    (set_attr "mode"     "SI")
463    (set_attr "length"   "3")])
467 ;;  ....................
469 ;;      SQUARE ROOT
471 ;;  ....................
474 (define_insn "sqrtsf2"
475   [(set (match_operand:SF 0 "register_operand" "=f")
476         (sqrt:SF (match_operand:SF 1 "register_operand" "f")))]
477   "TARGET_HARD_FLOAT_SQRT"
478   "sqrt.s\\t%0, %1"
479   [(set_attr "type"     "fsqrt")
480    (set_attr "mode"     "SF")
481    (set_attr "length"   "3")])
483 (define_insn "*rsqrtsf2"
484   [(set (match_operand:SF 0 "register_operand" "=f")
485         (div:SF (match_operand:SF 1 "const_float_1_operand" "")
486                 (sqrt:SF (match_operand:SF 2 "register_operand" "f"))))]
487   "TARGET_HARD_FLOAT_RSQRT && flag_unsafe_math_optimizations"
488   "rsqrt.s\\t%0, %2"
489   [(set_attr "type"     "fsqrt")
490    (set_attr "mode"     "SF")
491    (set_attr "length"   "3")])
495 ;;  ....................
497 ;;      ABSOLUTE VALUE
499 ;;  ....................
502 (define_insn "abssi2"
503   [(set (match_operand:SI 0 "register_operand" "=a")
504         (abs:SI (match_operand:SI 1 "register_operand" "r")))]
505   ""
506   "abs\\t%0, %1"
507   [(set_attr "type"     "arith")
508    (set_attr "mode"     "SI")
509    (set_attr "length"   "3")])
511 (define_insn "abssf2"
512   [(set (match_operand:SF 0 "register_operand" "=f")
513         (abs:SF (match_operand:SF 1 "register_operand" "f")))]
514   "TARGET_HARD_FLOAT"
515   "abs.s\\t%0, %1"
516   [(set_attr "type"     "farith")
517    (set_attr "mode"     "SF")
518    (set_attr "length"   "3")])
522 ;;  ....................
524 ;;      MIN AND MAX INSTRUCTIONS
526 ;;  ....................
529 (define_insn "sminsi3"
530   [(set (match_operand:SI 0 "register_operand" "=a")
531         (smin:SI (match_operand:SI 1 "register_operand" "%r")
532                  (match_operand:SI 2 "register_operand" "r")))]
533   "TARGET_MINMAX"
534   "min\\t%0, %1, %2"
535   [(set_attr "type"     "arith")
536    (set_attr "mode"     "SI")
537    (set_attr "length"   "3")])
539 (define_insn "uminsi3"
540   [(set (match_operand:SI 0 "register_operand" "=a")
541         (umin:SI (match_operand:SI 1 "register_operand" "%r")
542                  (match_operand:SI 2 "register_operand" "r")))]
543   "TARGET_MINMAX"
544   "minu\\t%0, %1, %2"
545   [(set_attr "type"     "arith")
546    (set_attr "mode"     "SI")
547    (set_attr "length"   "3")])
549 (define_insn "smaxsi3"
550   [(set (match_operand:SI 0 "register_operand" "=a")
551         (smax:SI (match_operand:SI 1 "register_operand" "%r")
552                  (match_operand:SI 2 "register_operand" "r")))]
553   "TARGET_MINMAX"
554   "max\\t%0, %1, %2"
555   [(set_attr "type"     "arith")
556    (set_attr "mode"     "SI")
557    (set_attr "length"   "3")])
559 (define_insn "umaxsi3"
560   [(set (match_operand:SI 0 "register_operand" "=a")
561         (umax:SI (match_operand:SI 1 "register_operand" "%r")
562                  (match_operand:SI 2 "register_operand" "r")))]
563   "TARGET_MINMAX"
564   "maxu\\t%0, %1, %2"
565   [(set_attr "type"     "arith")
566    (set_attr "mode"     "SI")
567    (set_attr "length"   "3")])
571 ;;  ....................
573 ;;      FIND FIRST BIT INSTRUCTION
575 ;;  ....................
578 (define_expand "ffssi2"
579   [(set (match_operand:SI 0 "register_operand" "")
580         (ffs:SI (match_operand:SI 1 "register_operand" "")))]
581   "TARGET_NSA"
582   "
584   rtx temp = gen_reg_rtx (SImode);
585   emit_insn (gen_negsi2 (temp, operands[1]));
586   emit_insn (gen_andsi3 (temp, temp, operands[1]));
587   emit_insn (gen_nsau (temp, temp));
588   emit_insn (gen_negsi2 (temp, temp));
589   emit_insn (gen_addsi3 (operands[0], temp, GEN_INT (32)));
590   DONE;
593 ;; there is no RTL operator corresponding to NSAU
594 (define_insn "nsau"
595   [(set (match_operand:SI 0 "register_operand" "=a")
596         (unspec:SI [(match_operand:SI 1 "register_operand" "r")] UNSPEC_NSAU))]
597   "TARGET_NSA"
598   "nsau\\t%0, %1"
599   [(set_attr "type"     "arith")
600    (set_attr "mode"     "SI")
601    (set_attr "length"   "3")])
605 ;;  ....................
607 ;;      NEGATION and ONE'S COMPLEMENT
609 ;;  ....................
612 (define_insn "negsi2"
613   [(set (match_operand:SI 0 "register_operand" "=a")
614         (neg:SI (match_operand:SI 1 "register_operand" "r")))]
615   ""
616   "neg\\t%0, %1"
617   [(set_attr "type"     "arith")
618    (set_attr "mode"     "SI")
619    (set_attr "length"   "3")])
621 (define_expand "one_cmplsi2"
622   [(set (match_operand:SI 0 "register_operand" "")
623         (not:SI (match_operand:SI 1 "register_operand" "")))]
624   ""
625   "
627   rtx temp = gen_reg_rtx (SImode);
628   emit_insn (gen_movsi (temp, constm1_rtx));
629   emit_insn (gen_xorsi3 (operands[0], temp, operands[1]));
630   DONE;
633 (define_insn "negsf2"
634   [(set (match_operand:SF 0 "register_operand" "=f")
635         (neg:SF (match_operand:SF 1 "register_operand" "f")))]
636   "TARGET_HARD_FLOAT"
637   "neg.s\\t%0, %1"
638   [(set_attr "type"     "farith")
639    (set_attr "mode"     "SF")
640    (set_attr "length"   "3")])
644 ;;  ....................
646 ;;      LOGICAL
648 ;;  ....................
651 (define_insn "andsi3"
652   [(set (match_operand:SI 0 "register_operand" "=a,a")
653         (and:SI (match_operand:SI 1 "register_operand" "%r,r")
654                 (match_operand:SI 2 "mask_operand" "P,r")))]
655   ""
656   "@
657    extui\\t%0, %1, 0, %K2
658    and\\t%0, %1, %2"
659   [(set_attr "type"     "arith,arith")
660    (set_attr "mode"     "SI")
661    (set_attr "length"   "3,3")])
663 (define_insn "iorsi3"
664   [(set (match_operand:SI 0 "register_operand" "=a")
665         (ior:SI (match_operand:SI 1 "register_operand" "%r")
666                 (match_operand:SI 2 "register_operand" "r")))]
667   ""
668   "or\\t%0, %1, %2"
669   [(set_attr "type"     "arith")
670    (set_attr "mode"     "SI")
671    (set_attr "length"   "3")])
673 (define_insn "xorsi3"
674   [(set (match_operand:SI 0 "register_operand" "=a")
675         (xor:SI (match_operand:SI 1 "register_operand" "%r")
676                 (match_operand:SI 2 "register_operand" "r")))]
677   ""
678   "xor\\t%0, %1, %2"
679   [(set_attr "type"     "arith")
680    (set_attr "mode"     "SI")
681    (set_attr "length"   "3")])
685 ;;  ....................
687 ;;      ZERO EXTENSION
689 ;;  ....................
692 (define_insn "zero_extendhisi2"
693   [(set (match_operand:SI 0 "register_operand" "=a,a")
694         (zero_extend:SI (match_operand:HI 1 "nonimmed_operand" "r,U")))]
695   ""
696   "@
697    extui\\t%0, %1, 0, 16
698    l16ui\\t%0, %1"
699   [(set_attr "type"     "arith,load")
700    (set_attr "mode"     "SI")
701    (set_attr "length"   "3,3")])
703 (define_insn "zero_extendqisi2"
704   [(set (match_operand:SI 0 "register_operand" "=a,a")
705         (zero_extend:SI (match_operand:QI 1 "nonimmed_operand" "r,U")))]
706   ""
707   "@
708    extui\\t%0, %1, 0, 8
709    l8ui\\t%0, %1"
710   [(set_attr "type"     "arith,load")
711    (set_attr "mode"     "SI")
712    (set_attr "length"   "3,3")])
716 ;;  ....................
718 ;;      SIGN EXTENSION
720 ;;  ....................
723 (define_expand "extendhisi2"
724   [(set (match_operand:SI 0 "register_operand" "")
725         (sign_extend:SI (match_operand:HI 1 "register_operand" "")))]
726   ""
727   "
729   if (sext_operand (operands[1], HImode))
730     emit_insn (gen_extendhisi2_internal (operands[0], operands[1]));
731   else
732     xtensa_extend_reg (operands[0], operands[1]);
733   DONE;
736 (define_insn "extendhisi2_internal"
737   [(set (match_operand:SI 0 "register_operand" "=B,a")
738         (sign_extend:SI (match_operand:HI 1 "sext_operand" "r,U")))]
739   ""
740   "@
741    sext\\t%0, %1, 15
742    l16si\\t%0, %1"
743   [(set_attr "type"     "arith,load")
744    (set_attr "mode"     "SI")
745    (set_attr "length"   "3,3")])
747 (define_expand "extendqisi2"
748   [(set (match_operand:SI 0 "register_operand" "")
749         (sign_extend:SI (match_operand:QI 1 "register_operand" "")))]
750   ""
751   "
753   if (TARGET_SEXT)
754     {
755       emit_insn (gen_extendqisi2_internal (operands[0], operands[1]));
756       DONE;
757     }
758   xtensa_extend_reg (operands[0], operands[1]);
759   DONE;
762 (define_insn "extendqisi2_internal"
763   [(set (match_operand:SI 0 "register_operand" "=B")
764         (sign_extend:SI (match_operand:QI 1 "register_operand" "r")))]
765   "TARGET_SEXT"
766   "sext\\t%0, %1, 7"
767   [(set_attr "type"     "arith")
768    (set_attr "mode"     "SI")
769    (set_attr "length"   "3")])
773 ;;  ....................
775 ;;      FIELD EXTRACT
777 ;;  ....................
780 (define_expand "extv"
781   [(set (match_operand:SI 0 "register_operand" "")
782         (sign_extract:SI (match_operand:SI 1 "register_operand" "")
783                          (match_operand:SI 2 "const_int_operand" "")
784                          (match_operand:SI 3 "const_int_operand" "")))]
785   "TARGET_SEXT"
786   "
788   if (!sext_fldsz_operand (operands[2], SImode)) FAIL;
789   /* we could expand to a right shift followed by sext but that's
790      no better than the standard left and right shift sequence */
791   if (!lsbitnum_operand (operands[3], SImode)) FAIL;
792   emit_insn (gen_extv_internal (operands[0], operands[1],
793                                 operands[2], operands[3]));
794   DONE;
797 (define_insn "extv_internal"
798   [(set (match_operand:SI 0 "register_operand" "=a")
799         (sign_extract:SI (match_operand:SI 1 "register_operand" "r")
800                          (match_operand:SI 2 "sext_fldsz_operand" "i")
801                          (match_operand:SI 3 "lsbitnum_operand" "i")))]
802   "TARGET_SEXT"
803   "*
805   int fldsz = INTVAL (operands[2]);
806   operands[2] = GEN_INT (fldsz - 1);
807   return \"sext\\t%0, %1, %2\";
809   [(set_attr "type"     "arith")
810    (set_attr "mode"     "SI")
811    (set_attr "length"   "3")])
813 (define_expand "extzv"
814   [(set (match_operand:SI 0 "register_operand" "")
815         (zero_extract:SI (match_operand:SI 1 "register_operand" "")
816                          (match_operand:SI 2 "const_int_operand" "")
817                          (match_operand:SI 3 "const_int_operand" "")))]
818   ""
819   "
821   if (!extui_fldsz_operand (operands[2], SImode)) FAIL;
822   emit_insn (gen_extzv_internal (operands[0], operands[1],
823                                  operands[2], operands[3]));
824   DONE;
827 (define_insn "extzv_internal"
828   [(set (match_operand:SI 0 "register_operand" "=a")
829         (zero_extract:SI (match_operand:SI 1 "register_operand" "r")
830                          (match_operand:SI 2 "extui_fldsz_operand" "i")
831                          (match_operand:SI 3 "const_int_operand" "i")))]
832   ""
833   "*
835   int shift;
836   if (BITS_BIG_ENDIAN)
837     shift = (32 - (INTVAL (operands[2]) + INTVAL (operands[3]))) & 0x1f;
838   else
839     shift = INTVAL (operands[3]) & 0x1f;
840   operands[3] = GEN_INT (shift);
841   return \"extui\\t%0, %1, %3, %2\";
843   [(set_attr "type"     "arith")
844    (set_attr "mode"     "SI")
845    (set_attr "length"   "3")])
849 ;;  ....................
851 ;;      CONVERSIONS
853 ;;  ....................
856 (define_insn "fix_truncsfsi2"
857   [(set (match_operand:SI 0 "register_operand" "=a")
858         (fix:SI (match_operand:SF 1 "register_operand" "f")))]
859   "TARGET_HARD_FLOAT"
860   "trunc.s\\t%0, %1, 0"
861   [(set_attr "type"     "fconv")
862    (set_attr "mode"     "SF")
863    (set_attr "length"   "3")])
865 (define_insn "fixuns_truncsfsi2"
866   [(set (match_operand:SI 0 "register_operand" "=a")
867         (unsigned_fix:SI (match_operand:SF 1 "register_operand" "f")))]
868   "TARGET_HARD_FLOAT"
869   "utrunc.s %0, %1, 0"
870   [(set_attr "type"     "fconv")
871    (set_attr "mode"     "SF")
872    (set_attr "length"   "3")])
874 (define_insn "floatsisf2"
875   [(set (match_operand:SF 0 "register_operand" "=f")
876         (float:SF (match_operand:SI 1 "register_operand" "a")))]
877   "TARGET_HARD_FLOAT"
878   "float.s\\t%0, %1, 0"
879   [(set_attr "type"     "fconv")
880    (set_attr "mode"     "SF")
881    (set_attr "length"   "3")])
883 (define_insn "floatunssisf2"
884   [(set (match_operand:SF 0 "register_operand" "=f")
885         (unsigned_float:SF (match_operand:SI 1 "register_operand" "a")))]
886   "TARGET_HARD_FLOAT"
887   "ufloat.s %0, %1, 0"
888   [(set_attr "type"     "fconv")
889    (set_attr "mode"     "SF")
890    (set_attr "length"   "3")])
894 ;;  ....................
896 ;;      DATA MOVEMENT
898 ;;  ....................
901 ;; 64-bit Integer moves
903 (define_expand "movdi"
904   [(set (match_operand:DI 0 "nonimmed_operand" "")
905         (match_operand:DI 1 "general_operand" ""))]
906   ""
907   "
909   if (CONSTANT_P (operands[1]))
910     {
911       rtx src0, src1, dst0, dst1;
912       if ((dst0 = operand_subword (operands[0], 0, 1, DImode))
913           && (src0 = operand_subword (operands[1], 0, 1, DImode))
914           && (dst1 = operand_subword (operands[0], 1, 1, DImode))
915           && (src1 = operand_subword (operands[1], 1, 1, DImode)))
916         {
917           emit_insn (gen_movsi (dst0, src0));
918           emit_insn (gen_movsi (dst1, src1));
919           DONE;
920         }
921       else
922         /* any other constant will be loaded from memory */
923         operands[1] = force_const_mem (DImode, operands[1]);
924     }
926   if (!(reload_in_progress | reload_completed))
927     {
928       if (!register_operand (operands[0], DImode)
929           && !register_operand (operands[1], DImode))
930         operands[1] = force_reg (DImode, operands[1]);
932       if (a7_overlap_mentioned_p (operands[1]))
933         {
934           emit_insn (gen_movdi_internal (operands[0], operands[1]));
935           emit_insn (gen_set_frame_ptr ());
936           DONE;
937         }
938     }
941 (define_insn "movdi_internal"
942   [(set (match_operand:DI 0 "nonimmed_operand" "=D,D,S,a,a,a,U")
943         (match_operand:DI 1 "non_const_move_operand" "d,S,d,r,T,U,r"))]
944   "register_operand (operands[0], DImode)
945    || register_operand (operands[1], DImode)"
946   "*
948   switch (which_alternative)
949     {
950     case 0: return \"mov.n\\t%0, %1\;mov.n\\t%D0, %D1\";
951     case 2: return \"%v0s32i.n\\t%1, %0\;s32i.n\\t%D1, %N0\";
952     case 3: return \"mov\\t%0, %1\;mov\\t%D0, %D1\";
953     case 6: return \"%v0s32i\\t%1, %0\;s32i\\t%D1, %N0\";
955     case 1:
956     case 4:
957     case 5:
958       {
959         /* Check if the first half of the destination register is used
960            in the source address.  If so, reverse the order of the loads
961            so that the source address doesn't get clobbered until it is
962            no longer needed. */
964         rtx dstreg = operands[0];
965         if (GET_CODE (dstreg) == SUBREG)
966           dstreg = SUBREG_REG (dstreg);
967         if (GET_CODE (dstreg) != REG)
968           abort();
970         if (reg_mentioned_p (dstreg, operands[1]))
971           {
972             switch (which_alternative)
973               {
974               case 1: return \"%v1l32i.n\\t%D0, %N1\;l32i.n\\t%0, %1\";
975               case 4: return \"%v1l32r\\t%D0, %N1\;l32r\\t%0, %1\";
976               case 5: return \"%v1l32i\\t%D0, %N1\;l32i\\t%0, %1\";
977               }
978           }
979         else
980           {
981             switch (which_alternative)
982               {
983               case 1: return \"%v1l32i.n\\t%0, %1\;l32i.n\\t%D0, %N1\";
984               case 4: return \"%v1l32r\\t%0, %1\;l32r\\t%D0, %N1\";
985               case 5: return \"%v1l32i\\t%0, %1\;l32i\\t%D0, %N1\";
986               }
987           }
988       }
989     }
990   abort ();
991   return \"\";
993   [(set_attr "type"     "move,load,store,move,load,load,store")
994    (set_attr "mode"     "DI")
995    (set_attr "length"   "4,4,4,6,6,6,6")])
998 ;; 32-bit Integer moves
1000 (define_expand "movsi"
1001   [(set (match_operand:SI 0 "nonimmed_operand" "")
1002         (match_operand:SI 1 "general_operand" ""))]
1003   ""
1004   "
1006   if (xtensa_emit_move_sequence (operands, SImode))
1007     DONE;
1010 (define_insn "movsi_internal"
1011   [(set (match_operand:SI 0 "nonimmed_operand" "=D,D,D,D,R,R,a,q,a,a,a,U,*a,*A")
1012         (match_operand:SI 1 "move_operand" "M,D,d,R,D,d,r,r,I,T,U,r,*A,*r"))]
1013   "xtensa_valid_move (SImode, operands)"
1014   "@
1015    movi.n\\t%0, %x1
1016    mov.n\\t%0, %1
1017    mov.n\\t%0, %1
1018    %v1l32i.n\\t%0, %1
1019    %v0s32i.n\\t%1, %0
1020    %v0s32i.n\\t%1, %0
1021    mov\\t%0, %1
1022    movsp\\t%0, %1
1023    movi\\t%0, %x1
1024    %v1l32r\\t%0, %1
1025    %v1l32i\\t%0, %1
1026    %v0s32i\\t%1, %0
1027    rsr\\t%0, 16 # ACCLO
1028    wsr\\t%1, 16 # ACCLO"
1029   [(set_attr "type"     "move,move,move,load,store,store,move,move,move,load,load,store,rsr,wsr")
1030    (set_attr "mode"     "SI")
1031    (set_attr "length"   "2,2,2,2,2,2,3,3,3,3,3,3,3,3")])
1033 ;; 16-bit Integer moves
1035 (define_expand "movhi"
1036   [(set (match_operand:HI 0 "nonimmed_operand" "")
1037         (match_operand:HI 1 "general_operand" ""))]
1038   ""
1039   "
1041   if (xtensa_emit_move_sequence (operands, HImode))
1042     DONE;
1045 (define_insn "movhi_internal"
1046   [(set (match_operand:HI 0 "nonimmed_operand" "=D,D,a,a,a,U,*a,*A")
1047         (match_operand:HI 1 "move_operand" "M,d,r,I,U,r,*A,*r"))]
1048   "xtensa_valid_move (HImode, operands)"
1049   "@
1050    movi.n\\t%0, %x1
1051    mov.n\\t%0, %1
1052    mov\\t%0, %1
1053    movi\\t%0, %x1
1054    %v1l16ui\\t%0, %1
1055    %v0s16i\\t%1, %0
1056    rsr\\t%0, 16 # ACCLO
1057    wsr\\t%1, 16 # ACCLO"
1058   [(set_attr "type"     "move,move,move,move,load,store,rsr,wsr")
1059    (set_attr "mode"     "HI")
1060    (set_attr "length"   "2,2,3,3,3,3,3,3")])
1062 ;; 8-bit Integer moves
1064 (define_expand "movqi"
1065   [(set (match_operand:QI 0 "nonimmed_operand" "")
1066         (match_operand:QI 1 "general_operand" ""))]
1067   ""
1068   "
1070   if (xtensa_emit_move_sequence (operands, QImode))
1071     DONE;
1074 (define_insn "movqi_internal"
1075   [(set (match_operand:QI 0 "nonimmed_operand" "=D,D,a,a,a,U,*a,*A")
1076         (match_operand:QI 1 "move_operand" "M,d,r,I,U,r,*A,*r"))]
1077   "xtensa_valid_move (QImode, operands)"
1078   "@
1079    movi.n\\t%0, %x1
1080    mov.n\\t%0, %1
1081    mov\\t%0, %1
1082    movi\\t%0, %x1
1083    %v1l8ui\\t%0, %1
1084    %v0s8i\\t%1, %0
1085    rsr\\t%0, 16 # ACCLO
1086    wsr\\t%1, 16 # ACCLO"
1087   [(set_attr "type"     "move,move,move,move,load,store,rsr,wsr")
1088    (set_attr "mode"     "QI")
1089    (set_attr "length"   "2,2,3,3,3,3,3,3")])
1091 ;; 32-bit floating point moves
1093 (define_expand "movsf"
1094   [(set (match_operand:SF 0 "nonimmed_operand" "")
1095         (match_operand:SF 1 "general_operand" ""))]
1096   ""
1097   "
1099   if (GET_CODE (operands[1]) == CONST_DOUBLE)
1100     operands[1] = force_const_mem (SFmode, operands[1]);
1102   if (!(reload_in_progress | reload_completed))
1103     {
1104       if (((!register_operand (operands[0], SFmode)
1105            && !register_operand (operands[1], SFmode))
1106           || (FP_REG_P (xt_true_regnum (operands[0]))
1107               && constantpool_mem_p (operands[1]))))
1108         operands[1] = force_reg (SFmode, operands[1]);
1110       if (a7_overlap_mentioned_p (operands[1]))
1111         {
1112           emit_insn (gen_movsf_internal (operands[0], operands[1]));
1113           emit_insn (gen_set_frame_ptr ());
1114           DONE;
1115         }
1116     }
1119 (define_insn "movsf_internal"
1120   [(set (match_operand:SF 0 "nonimmed_operand"
1121                             "=f,f,U,D,D,R,a,f,a,a,a,U")
1122         (match_operand:SF 1 "non_const_move_operand"
1123                             "f,U,f,d,R,d,r,r,f,T,U,r"))]
1124   "((register_operand (operands[0], SFmode)
1125      || register_operand (operands[1], SFmode))
1126     && (!FP_REG_P (xt_true_regnum (operands[0]))
1127         || !constantpool_mem_p (operands[1])))"
1128   "@
1129    mov.s\\t%0, %1
1130    %v1lsi\\t%0, %1
1131    %v0ssi\\t%1, %0
1132    mov.n\\t%0, %1
1133    %v1l32i.n\\t%0, %1
1134    %v0s32i.n\\t%1, %0
1135    mov\\t%0, %1
1136    wfr\\t%0, %1
1137    rfr\\t%0, %1
1138    %v1l32r\\t%0, %1
1139    %v1l32i\\t%0, %1
1140    %v0s32i\\t%1, %0"
1141   [(set_attr "type"     "farith,fload,fstore,move,load,store,move,farith,farith,load,load,store")
1142    (set_attr "mode"     "SF")
1143    (set_attr "length"   "3,3,3,2,2,2,3,3,3,3,3,3")])
1145 (define_insn "*lsiu"
1146   [(set (match_operand:SF 0 "register_operand" "=f")
1147         (mem:SF (plus:SI (match_operand:SI 1 "register_operand" "+a")
1148                          (match_operand:SI 2 "fpmem_offset_operand" "i"))))
1149    (set (match_dup 1)
1150         (plus:SI (match_dup 1) (match_dup 2)))]
1151   "TARGET_HARD_FLOAT"
1152   "*
1154   if (TARGET_SERIALIZE_VOLATILE && volatile_refs_p (PATTERN (insn)))
1155     output_asm_insn (\"memw\", operands);
1156   return \"lsiu\\t%0, %1, %2\";
1158   [(set_attr "type"     "fload")
1159    (set_attr "mode"     "SF")
1160    (set_attr "length"   "3")])
1162 (define_insn "*ssiu"
1163   [(set (mem:SF (plus:SI (match_operand:SI 0 "register_operand" "+a")
1164                          (match_operand:SI 1 "fpmem_offset_operand" "i")))
1165         (match_operand:SF 2 "register_operand" "f"))
1166    (set (match_dup 0)
1167         (plus:SI (match_dup 0) (match_dup 1)))]
1168   "TARGET_HARD_FLOAT"
1169   "*
1171   if (TARGET_SERIALIZE_VOLATILE && volatile_refs_p (PATTERN (insn)))
1172     output_asm_insn (\"memw\", operands);
1173   return \"ssiu\\t%2, %0, %1\";
1175   [(set_attr "type"     "fstore")
1176    (set_attr "mode"     "SF")
1177    (set_attr "length"   "3")])
1179 ;; 64-bit floating point moves
1181 (define_expand "movdf"
1182   [(set (match_operand:DF 0 "nonimmed_operand" "")
1183         (match_operand:DF 1 "general_operand" ""))]
1184   ""
1185   "
1187   if (GET_CODE (operands[1]) == CONST_DOUBLE)
1188     operands[1] = force_const_mem (DFmode, operands[1]);
1190   if (!(reload_in_progress | reload_completed))
1191     {
1192       if (!register_operand (operands[0], DFmode)
1193           && !register_operand (operands[1], DFmode))
1194         operands[1] = force_reg (DFmode, operands[1]);
1196       if (a7_overlap_mentioned_p (operands[1]))
1197         {
1198           emit_insn (gen_movdf_internal (operands[0], operands[1]));
1199           emit_insn (gen_set_frame_ptr ());
1200           DONE;
1201         }
1202     }
1205 (define_insn "movdf_internal"
1206   [(set (match_operand:DF 0 "nonimmed_operand" "=D,D,S,a,a,a,U")
1207         (match_operand:DF 1 "non_const_move_operand" "d,S,d,r,T,U,r"))]
1208   "register_operand (operands[0], DFmode)
1209    || register_operand (operands[1], DFmode)"
1210   "*
1212   switch (which_alternative)
1213     {
1214     case 0: return \"mov.n\\t%0, %1\;mov.n\\t%D0, %D1\";
1215     case 2: return \"%v0s32i.n\\t%1, %0\;s32i.n\\t%D1, %N0\";
1216     case 3: return \"mov\\t%0, %1\;mov\\t%D0, %D1\";
1217     case 6: return \"%v0s32i\\t%1, %0\;s32i\\t%D1, %N0\";
1219     case 1:
1220     case 4:
1221     case 5:
1222       {
1223         /* Check if the first half of the destination register is used
1224            in the source address.  If so, reverse the order of the loads
1225            so that the source address doesn't get clobbered until it is
1226            no longer needed. */
1228         rtx dstreg = operands[0];
1229         if (GET_CODE (dstreg) == SUBREG)
1230           dstreg = SUBREG_REG (dstreg);
1231         if (GET_CODE (dstreg) != REG)
1232           abort ();
1234         if (reg_mentioned_p (dstreg, operands[1]))
1235           {
1236             switch (which_alternative)
1237               {
1238               case 1: return \"%v1l32i.n\\t%D0, %N1\;l32i.n\\t%0, %1\";
1239               case 4: return \"%v1l32r\\t%D0, %N1\;l32r\\t%0, %1\";
1240               case 5: return \"%v1l32i\\t%D0, %N1\;l32i\\t%0, %1\";
1241               }
1242           }
1243         else
1244           {
1245             switch (which_alternative)
1246               {
1247               case 1: return \"%v1l32i.n\\t%0, %1\;l32i.n\\t%D0, %N1\";
1248               case 4: return \"%v1l32r\\t%0, %1\;l32r\\t%D0, %N1\";
1249               case 5: return \"%v1l32i\\t%0, %1\;l32i\\t%D0, %N1\";
1250               }
1251           }
1252       }
1253     }
1254   abort ();
1255   return \"\";
1257   [(set_attr "type"     "move,load,store,move,load,load,store")
1258    (set_attr "mode"     "DF")
1259    (set_attr "length"   "4,4,4,6,6,6,6")])
1261 ;; Block moves
1263 (define_expand "movstrsi"
1264   [(parallel [(set (match_operand:BLK 0 "" "")
1265                    (match_operand:BLK 1 "" ""))
1266               (use (match_operand:SI 2 "arith_operand" ""))
1267               (use (match_operand:SI 3 "const_int_operand" ""))])]
1268   ""
1269   "
1271   if (!xtensa_expand_block_move (operands)) FAIL;
1272   DONE;
1275 (define_insn "movstrsi_internal"
1276   [(set (match_operand:BLK 0 "memory_operand" "=U")
1277         (match_operand:BLK 1 "memory_operand" "U"))
1278    (use (match_operand:SI 2 "arith_operand" ""))
1279    (use (match_operand:SI 3 "const_int_operand" ""))
1280    (clobber (match_scratch:SI 4 "=&r"))
1281    (clobber (match_scratch:SI 5 "=&r"))]
1282   ""
1283   "*
1285   rtx tmpregs[2];
1286   tmpregs[0] = operands[4];
1287   tmpregs[1] = operands[5];
1288   xtensa_emit_block_move (operands, tmpregs, 1);
1289   return \"\";
1291   [(set_attr "type"     "multi")
1292    (set_attr "mode"     "none")
1293    (set_attr "length"   "300")])
1297 ;;  ....................
1299 ;;      SHIFTS
1301 ;;  ....................
1304 (define_insn "ashlsi3"
1305   [(set (match_operand:SI 0 "register_operand" "=a,a")
1306         (ashift:SI (match_operand:SI 1 "register_operand" "r,r")
1307                    (match_operand:SI 2 "arith_operand" "J,r")))]
1308   ""      
1309   "@
1310    slli\\t%0, %1, %R2
1311    ssl\\t%2\;sll\\t%0, %1"
1312   [(set_attr "type"     "arith,arith")
1313    (set_attr "mode"     "SI")
1314    (set_attr "length"   "3,6")])
1316 (define_insn "ashrsi3"
1317   [(set (match_operand:SI 0 "register_operand" "=a,a")
1318         (ashiftrt:SI (match_operand:SI 1 "register_operand" "r,r")
1319                      (match_operand:SI 2 "arith_operand" "J,r")))]
1320   ""
1321   "@
1322    srai\\t%0, %1, %R2
1323    ssr\\t%2\;sra\\t%0, %1"
1324   [(set_attr "type"     "arith,arith")
1325    (set_attr "mode"     "SI")
1326    (set_attr "length"   "3,6")])
1328 (define_insn "lshrsi3"
1329   [(set (match_operand:SI 0 "register_operand" "=a,a")
1330         (lshiftrt:SI (match_operand:SI 1 "register_operand" "r,r")
1331                      (match_operand:SI 2 "arith_operand" "J,r")))]
1332   ""
1333   "*
1335   if (which_alternative == 0)
1336     {
1337       if ((INTVAL (operands[2]) & 0x1f) < 16)
1338         return \"srli\\t%0, %1, %R2\";
1339       else
1340         return \"extui\\t%0, %1, %R2, %L2\";
1341     }
1342   return \"ssr\\t%2\;srl\\t%0, %1\";
1344   [(set_attr "type"     "arith,arith")
1345    (set_attr "mode"     "SI")
1346    (set_attr "length"   "3,6")])
1348 (define_insn "rotlsi3"
1349   [(set (match_operand:SI 0 "register_operand" "=a,a")
1350         (rotate:SI (match_operand:SI 1 "register_operand" "r,r")
1351                      (match_operand:SI 2 "arith_operand" "J,r")))]
1352   ""
1353   "@
1354    ssai\\t%L2\;src\\t%0, %1, %1
1355    ssl\\t%2\;src\\t%0, %1, %1"
1356   [(set_attr "type"     "multi,multi")
1357    (set_attr "mode"     "SI")
1358    (set_attr "length"   "6,6")])
1360 (define_insn "rotrsi3"
1361   [(set (match_operand:SI 0 "register_operand" "=a,a")
1362         (rotatert:SI (match_operand:SI 1 "register_operand" "r,r")
1363                      (match_operand:SI 2 "arith_operand" "J,r")))]
1364   ""
1365   "@
1366    ssai\\t%R2\;src\\t%0, %1, %1
1367    ssr\\t%2\;src\\t%0, %1, %1"
1368   [(set_attr "type"     "multi,multi")
1369    (set_attr "mode"     "SI")
1370    (set_attr "length"   "6,6")])
1374 ;;  ....................
1376 ;;      COMPARISONS
1378 ;;  ....................
1381 ;; Like the md files for MIPS and SPARC, we handle comparisons by stashing
1382 ;; away the operands and then using that information in the subsequent
1383 ;; conditional branch.
1385 (define_expand "cmpsi"
1386   [(set (cc0)
1387         (compare:CC (match_operand:SI 0 "register_operand" "")
1388                     (match_operand:SI 1 "nonmemory_operand" "")))]
1389   ""
1390   "
1392   branch_cmp[0] = operands[0];
1393   branch_cmp[1] = operands[1];
1394   branch_type = CMP_SI;
1395   DONE;
1398 (define_expand "tstsi"
1399   [(set (cc0)
1400         (match_operand:SI 0 "register_operand" ""))]
1401   ""
1402   "
1404   branch_cmp[0] = operands[0];
1405   branch_cmp[1] = const0_rtx;
1406   branch_type = CMP_SI;
1407   DONE;
1410 (define_expand "cmpsf"
1411   [(set (cc0)
1412         (compare:CC (match_operand:SF 0 "register_operand" "")
1413                     (match_operand:SF 1 "register_operand" "")))]
1414   "TARGET_HARD_FLOAT"
1415   "
1417   branch_cmp[0] = operands[0];
1418   branch_cmp[1] = operands[1];
1419   branch_type = CMP_SF;
1420   DONE;
1425 ;;  ....................
1427 ;;      CONDITIONAL BRANCHES
1429 ;;  ....................
1432 (define_expand "beq"
1433   [(set (pc)
1434         (if_then_else (eq (cc0) (const_int 0))
1435                       (label_ref (match_operand 0 "" ""))
1436                       (pc)))]
1437   ""
1438   "
1440   xtensa_expand_conditional_branch (operands, EQ);
1441   DONE;
1444 (define_expand "bne"
1445   [(set (pc)
1446         (if_then_else (ne (cc0) (const_int 0))
1447                       (label_ref (match_operand 0 "" ""))
1448                       (pc)))]
1449   ""
1450   "
1452   xtensa_expand_conditional_branch (operands, NE);
1453   DONE;
1456 (define_expand "bgt"
1457   [(set (pc)
1458         (if_then_else (gt (cc0) (const_int 0))
1459                       (label_ref (match_operand 0 "" ""))
1460                       (pc)))]
1461   ""
1462   "
1464   xtensa_expand_conditional_branch (operands, GT);
1465   DONE;
1468 (define_expand "bge"
1469   [(set (pc)
1470         (if_then_else (ge (cc0) (const_int 0))
1471                       (label_ref (match_operand 0 "" ""))
1472                       (pc)))]
1473   ""
1474   "
1476   xtensa_expand_conditional_branch (operands, GE);
1477   DONE;
1480 (define_expand "blt"
1481   [(set (pc)
1482         (if_then_else (lt (cc0) (const_int 0))
1483                       (label_ref (match_operand 0 "" ""))
1484                       (pc)))]
1485   ""
1486   "
1488   xtensa_expand_conditional_branch (operands, LT);
1489   DONE;
1492 (define_expand "ble"
1493   [(set (pc)
1494         (if_then_else (le (cc0) (const_int 0))
1495                       (label_ref (match_operand 0 "" ""))
1496                       (pc)))]
1497   ""
1498   "
1500   xtensa_expand_conditional_branch (operands, LE);
1501   DONE;
1504 (define_expand "bgtu"
1505   [(set (pc)
1506         (if_then_else (gtu (cc0) (const_int 0))
1507                       (label_ref (match_operand 0 "" ""))
1508                       (pc)))]
1509   ""
1510   "
1512   xtensa_expand_conditional_branch (operands, GTU);
1513   DONE;
1516 (define_expand "bgeu"
1517   [(set (pc)
1518         (if_then_else (geu (cc0) (const_int 0))
1519                       (label_ref (match_operand 0 "" ""))
1520                       (pc)))]
1521   ""
1522   "
1524   xtensa_expand_conditional_branch (operands, GEU);
1525   DONE;
1528 (define_expand "bltu"
1529   [(set (pc)
1530         (if_then_else (ltu (cc0) (const_int 0))
1531                       (label_ref (match_operand 0 "" ""))
1532                       (pc)))]
1533   ""
1534   "
1536   xtensa_expand_conditional_branch (operands, LTU);
1537   DONE;
1540 (define_expand "bleu"
1541   [(set (pc)
1542         (if_then_else (leu (cc0) (const_int 0))
1543                       (label_ref (match_operand 0 "" ""))
1544                       (pc)))]
1545   ""
1546   "
1548   xtensa_expand_conditional_branch (operands, LEU);
1549   DONE;
1552 ;; Branch patterns for standard integer comparisons
1554 (define_insn "*btrue"
1555   [(set (pc)
1556         (if_then_else (match_operator 3 "branch_operator"
1557                          [(match_operand:SI 0 "register_operand" "r,r")
1558                           (match_operand:SI 1 "branch_operand" "K,r")])
1559                       (label_ref (match_operand 2 "" ""))
1560                       (pc)))]
1561   ""
1562   "*
1564   if (which_alternative == 1)
1565     {
1566       switch (GET_CODE (operands[3]))
1567         {
1568         case EQ:        return \"beq\\t%0, %1, %2\";
1569         case NE:        return \"bne\\t%0, %1, %2\";
1570         case LT:        return \"blt\\t%0, %1, %2\";
1571         case GE:        return \"bge\\t%0, %1, %2\";
1572         default:        break;
1573         }
1574     }
1575   else if (INTVAL (operands[1]) == 0)
1576     {
1577       switch (GET_CODE (operands[3]))
1578         {
1579         case EQ:        return (TARGET_DENSITY
1580                                 ? \"beqz.n\\t%0, %2\"
1581                                 : \"beqz\\t%0, %2\");
1582         case NE:        return (TARGET_DENSITY
1583                                 ? \"bnez.n\\t%0, %2\"
1584                                 : \"bnez\\t%0, %2\");
1585         case LT:        return \"bltz\\t%0, %2\";
1586         case GE:        return \"bgez\\t%0, %2\";
1587         default:        break;
1588         }
1589     }
1590   else
1591     {
1592       switch (GET_CODE (operands[3]))
1593         {
1594         case EQ:        return \"beqi\\t%0, %d1, %2\";
1595         case NE:        return \"bnei\\t%0, %d1, %2\";
1596         case LT:        return \"blti\\t%0, %d1, %2\";
1597         case GE:        return \"bgei\\t%0, %d1, %2\";
1598         default:        break;
1599         }
1600     }
1601   fatal_insn (\"unexpected branch operator\", operands[3]);
1602   return \"\";
1604   [(set_attr "type"     "jump,jump")
1605    (set_attr "mode"     "none")
1606    (set_attr "length"   "3,3")])
1608 (define_insn "*bfalse"
1609   [(set (pc)
1610         (if_then_else (match_operator 3 "branch_operator"
1611                          [(match_operand:SI 0 "register_operand" "r,r")
1612                           (match_operand:SI 1 "branch_operand" "K,r")])
1613                       (pc)
1614                       (label_ref (match_operand 2 "" ""))))]
1615   ""
1616   "*
1618   if (which_alternative == 1)
1619     {
1620       switch (GET_CODE (operands[3]))
1621         {
1622         case EQ:        return \"bne\\t%0, %1, %2\";
1623         case NE:        return \"beq\\t%0, %1, %2\";
1624         case LT:        return \"bge\\t%0, %1, %2\";
1625         case GE:        return \"blt\\t%0, %1, %2\";
1626         default:        break;
1627         }
1628     }
1629   else if (INTVAL (operands[1]) == 0)
1630     {
1631       switch (GET_CODE (operands[3]))
1632         {
1633         case EQ:        return (TARGET_DENSITY
1634                                 ? \"bnez.n\\t%0, %2\"
1635                                 : \"bnez\\t%0, %2\");
1636         case NE:        return (TARGET_DENSITY
1637                                 ? \"beqz.n\\t%0, %2\"
1638                                 : \"beqz\\t%0, %2\");
1639         case LT:        return \"bgez\\t%0, %2\";
1640         case GE:        return \"bltz\\t%0, %2\";
1641         default:        break;
1642         }
1643     }
1644   else
1645     {
1646       switch (GET_CODE (operands[3]))
1647         {
1648         case EQ:        return \"bnei\\t%0, %d1, %2\";
1649         case NE:        return \"beqi\\t%0, %d1, %2\";
1650         case LT:        return \"bgei\\t%0, %d1, %2\";
1651         case GE:        return \"blti\\t%0, %d1, %2\";
1652         default:        break;
1653         }
1654     }
1655   fatal_insn (\"unexpected branch operator\", operands[3]);
1656   return \"\";
1658   [(set_attr "type"     "jump,jump")
1659    (set_attr "mode"     "none")
1660    (set_attr "length"   "3,3")])
1662 (define_insn "*ubtrue"
1663   [(set (pc)
1664         (if_then_else (match_operator 3 "ubranch_operator"
1665                          [(match_operand:SI 0 "register_operand" "r,r")
1666                           (match_operand:SI 1 "ubranch_operand" "L,r")])
1667                       (label_ref (match_operand 2 "" ""))
1668                       (pc)))]
1669   ""
1670   "*
1672   if (which_alternative == 1)
1673     {
1674       switch (GET_CODE (operands[3]))
1675         {
1676         case LTU:       return \"bltu\\t%0, %1, %2\";
1677         case GEU:       return \"bgeu\\t%0, %1, %2\";
1678         default:        break;
1679         }
1680     }
1681   else
1682     {
1683       switch (GET_CODE (operands[3]))
1684         {
1685         case LTU:       return \"bltui\\t%0, %d1, %2\";
1686         case GEU:       return \"bgeui\\t%0, %d1, %2\";
1687         default:        break;
1688         }
1689     }
1690   fatal_insn (\"unexpected branch operator\", operands[3]);
1691   return \"\";
1693   [(set_attr "type"     "jump,jump")
1694    (set_attr "mode"     "none")
1695    (set_attr "length"   "3,3")])
1697 (define_insn "*ubfalse"
1698   [(set (pc)
1699         (if_then_else (match_operator 3 "ubranch_operator"
1700                          [(match_operand:SI 0 "register_operand" "r,r")
1701                           (match_operand:SI 1 "ubranch_operand" "L,r")])
1702                       (pc)
1703                       (label_ref (match_operand 2 "" ""))))]
1704   ""
1705   "*
1707   if (which_alternative == 1)
1708     {
1709       switch (GET_CODE (operands[3]))
1710         {
1711         case LTU:       return \"bgeu\\t%0, %1, %2\";
1712         case GEU:       return \"bltu\\t%0, %1, %2\";
1713         default:        break;
1714         }
1715     }
1716   else
1717     {
1718       switch (GET_CODE (operands[3]))
1719         {
1720         case LTU:       return \"bgeui\\t%0, %d1, %2\";
1721         case GEU:       return \"bltui\\t%0, %d1, %2\";
1722         default:        break;
1723         }
1724     }
1725   fatal_insn (\"unexpected branch operator\", operands[3]);
1726   return \"\";
1728   [(set_attr "type"     "jump,jump")
1729    (set_attr "mode"     "none")
1730    (set_attr "length"   "3,3")])
1732 ;; Branch patterns for bit testing
1734 (define_insn "*bittrue"
1735   [(set (pc)
1736         (if_then_else (match_operator 3 "boolean_operator"
1737                         [(zero_extract:SI
1738                             (match_operand:SI 0 "register_operand" "r,r")
1739                             (const_int 1)
1740                             (match_operand:SI 1 "arith_operand" "J,r"))
1741                          (const_int 0)])
1742                       (label_ref (match_operand 2 "" ""))
1743                       (pc)))]
1744   ""
1745   "*
1747   if (which_alternative == 0)
1748     {
1749       unsigned bitnum = INTVAL(operands[1]) & 0x1f;
1750       operands[1] = GEN_INT(bitnum);
1751       switch (GET_CODE (operands[3]))
1752         {
1753         case EQ:        return \"bbci\\t%0, %d1, %2\";
1754         case NE:        return \"bbsi\\t%0, %d1, %2\";
1755         default:        break;
1756         }
1757     }
1758   else
1759     {
1760       switch (GET_CODE (operands[3]))
1761         {
1762         case EQ:        return \"bbc\\t%0, %1, %2\";
1763         case NE:        return \"bbs\\t%0, %1, %2\";
1764         default:        break;
1765         }
1766     }
1767   fatal_insn (\"unexpected branch operator\", operands[3]);
1768   return \"\";
1770   [(set_attr "type"     "jump")
1771    (set_attr "mode"     "none")
1772    (set_attr "length"   "3")])
1774 (define_insn "*bitfalse"
1775   [(set (pc)
1776         (if_then_else (match_operator 3 "boolean_operator"
1777                         [(zero_extract:SI
1778                             (match_operand:SI 0 "register_operand" "r,r")
1779                             (const_int 1)
1780                             (match_operand:SI 1 "arith_operand" "J,r"))
1781                          (const_int 0)])
1782                       (pc)
1783                       (label_ref (match_operand 2 "" ""))))]
1784   ""
1785   "*
1787   if (which_alternative == 0)
1788     {
1789       unsigned bitnum = INTVAL (operands[1]) & 0x1f;
1790       operands[1] = GEN_INT (bitnum);
1791       switch (GET_CODE (operands[3]))
1792         {
1793         case EQ:    return \"bbsi\\t%0, %d1, %2\";
1794         case NE:    return \"bbci\\t%0, %d1, %2\";
1795         default:    break;
1796         }
1797     }
1798   else
1799     {
1800       switch (GET_CODE (operands[3]))
1801         {
1802         case EQ:        return \"bbs\\t%0, %1, %2\";
1803         case NE:        return \"bbc\\t%0, %1, %2\";
1804         default:        break;
1805         }
1806     }
1807   fatal_insn (\"unexpected branch operator\", operands[3]);
1808   return \"\";
1810   [(set_attr "type"     "jump")
1811    (set_attr "mode"     "none")
1812    (set_attr "length"   "3")])
1814 (define_insn "*masktrue"
1815   [(set (pc)
1816         (if_then_else (match_operator 3 "boolean_operator"
1817                  [(and:SI (match_operand:SI 0 "register_operand" "r")
1818                           (match_operand:SI 1 "register_operand" "r"))
1819                   (const_int 0)])
1820                       (label_ref (match_operand 2 "" ""))
1821                       (pc)))]
1822   ""
1823   "*
1825   switch (GET_CODE (operands[3]))
1826     {
1827     case EQ:    return \"bnone\\t%0, %1, %2\";
1828     case NE:    return \"bany\\t%0, %1, %2\";
1829     default:    break;
1830     }
1831   fatal_insn (\"unexpected branch operator\", operands[3]);
1832   return \"\";
1834   [(set_attr "type"     "jump")
1835    (set_attr "mode"     "none")
1836    (set_attr "length"   "3")])
1838 (define_insn "*maskfalse"
1839   [(set (pc)
1840         (if_then_else (match_operator 3 "boolean_operator"
1841                  [(and:SI (match_operand:SI 0 "register_operand" "r")
1842                           (match_operand:SI 1 "register_operand" "r"))
1843                   (const_int 0)])
1844                       (pc)
1845                       (label_ref (match_operand 2 "" ""))))]
1846   ""
1847   "*
1849   switch (GET_CODE (operands[3]))
1850     {
1851     case EQ:    return \"bany\\t%0, %1, %2\";
1852     case NE:    return \"bnone\\t%0, %1, %2\";
1853     default:    break;
1854     }
1855   fatal_insn (\"unexpected branch operator\", operands[3]);
1856   return \"\";
1858   [(set_attr "type"     "jump")
1859    (set_attr "mode"     "none")
1860    (set_attr "length"   "3")])
1863 ;; Define the loop insns that is used by bct optimization to represent the
1864 ;; start and end of a zero-overhead loop (in loop.c). This start template
1865 ;; generates the loop insn, the end template doesn't generate any instructions
1866 ;; since since loop end is handled in hardware.
1868 (define_insn "zero_cost_loop_start"
1869   [(set (pc) (if_then_else (eq (match_operand:SI 0 "register_operand" "a")
1870                                (const_int 0))
1871                            (label_ref (match_operand 1 "" ""))
1872                            (pc)))
1873    (set (reg:SI 19)
1874         (plus:SI (match_dup 0) (const_int -1)))]
1875   ""
1876   "loopnez %0, %l1"
1877   [(set_attr "type"     "jump")
1878    (set_attr "mode"     "none")
1879    (set_attr "length"   "3")])
1881 (define_insn "zero_cost_loop_end"
1882   [(set (pc) (if_then_else (ne (reg:SI 19) (const_int 0))
1883                            (label_ref (match_operand 0 "" ""))
1884                            (pc)))
1885    (set (reg:SI 19)
1886         (plus:SI (reg:SI 19) (const_int -1)))]
1887   ""
1888   "*
1889     xtensa_emit_loop_end (insn, operands);
1890     return \"\";
1891   "
1892   [(set_attr "type"     "jump")
1893    (set_attr "mode"     "none")
1894    (set_attr "length"   "0")])
1898 ;;  ....................
1900 ;;      SETTING A REGISTER FROM A COMPARISON
1902 ;;  ....................
1905 (define_expand "seq"
1906   [(set (match_operand:SI 0 "register_operand" "")
1907         (match_dup 1))]
1908   ""
1909   "
1911   operands[1] = gen_rtx (EQ, SImode, branch_cmp[0], branch_cmp[1]);
1912   if (!xtensa_expand_scc (operands)) FAIL;
1913   DONE;
1916 (define_expand "sne"
1917   [(set (match_operand:SI 0 "register_operand" "")
1918         (match_dup 1))]
1919   ""
1920   "
1922   operands[1] = gen_rtx (NE, SImode, branch_cmp[0], branch_cmp[1]);
1923   if (!xtensa_expand_scc (operands)) FAIL;
1924   DONE;
1927 (define_expand "sgt"
1928   [(set (match_operand:SI 0 "register_operand" "")
1929         (match_dup 1))]
1930   ""
1931   "
1933   operands[1] = gen_rtx (GT, SImode, branch_cmp[0], branch_cmp[1]);
1934   if (!xtensa_expand_scc (operands)) FAIL;
1935   DONE;
1938 (define_expand "sge"
1939   [(set (match_operand:SI 0 "register_operand" "")
1940         (match_dup 1))]
1941   ""
1942   "
1944   operands[1] = gen_rtx (GE, SImode, branch_cmp[0], branch_cmp[1]);
1945   if (!xtensa_expand_scc (operands)) FAIL;
1946   DONE;
1949 (define_expand "slt"
1950   [(set (match_operand:SI 0 "register_operand" "")
1951         (match_dup 1))]
1952   ""
1953   "
1955   operands[1] = gen_rtx (LT, SImode, branch_cmp[0], branch_cmp[1]);
1956   if (!xtensa_expand_scc (operands)) FAIL;
1957   DONE;
1960 (define_expand "sle"
1961   [(set (match_operand:SI 0 "register_operand" "")
1962         (match_dup 1))]
1963   ""
1964   "
1966   operands[1] = gen_rtx (LE, SImode, branch_cmp[0], branch_cmp[1]);
1967   if (!xtensa_expand_scc (operands)) FAIL;
1968   DONE;
1973 ;;  ....................
1975 ;;      CONDITIONAL MOVES
1977 ;;  ....................
1980 (define_expand "movsicc"
1981   [(set (match_operand:SI 0 "register_operand" "")
1982         (if_then_else:SI (match_operand 1 "comparison_operator" "")
1983                          (match_operand:SI 2 "register_operand" "")
1984                          (match_operand:SI 3 "register_operand" "")))]
1985   ""
1986   "
1988   if (!xtensa_expand_conditional_move (operands, 0)) FAIL;
1989   DONE;
1992 (define_expand "movsfcc"
1993   [(set (match_operand:SF 0 "register_operand" "")
1994         (if_then_else:SF (match_operand 1 "comparison_operator" "")
1995                          (match_operand:SF 2 "register_operand" "")
1996                          (match_operand:SF 3 "register_operand" "")))]
1997   ""
1998   "
2000   if (!xtensa_expand_conditional_move (operands, 1)) FAIL;
2001   DONE;
2004 (define_insn "movsicc_internal0"
2005   [(set (match_operand:SI 0 "register_operand" "=a,a")
2006         (if_then_else:SI (match_operator 4 "branch_operator"
2007                            [(match_operand:SI 1 "register_operand" "r,r")
2008                             (const_int 0)])
2009                          (match_operand:SI 2 "register_operand" "r,0")
2010                          (match_operand:SI 3 "register_operand" "0,r")))]
2011   ""
2012   "*
2014   if (which_alternative == 0)
2015     {
2016       switch (GET_CODE (operands[4]))
2017         {
2018         case EQ:        return \"moveqz\\t%0, %2, %1\";
2019         case NE:        return \"movnez\\t%0, %2, %1\";
2020         case LT:        return \"movltz\\t%0, %2, %1\";
2021         case GE:        return \"movgez\\t%0, %2, %1\";
2022         default:        break;
2023         }
2024     }
2025   else
2026     {
2027       switch (GET_CODE (operands[4]))
2028         {
2029         case EQ:        return \"movnez\\t%0, %3, %1\";
2030         case NE:        return \"moveqz\\t%0, %3, %1\";
2031         case LT:        return \"movgez\\t%0, %3, %1\";
2032         case GE:        return \"movltz\\t%0, %3, %1\";
2033         default:        break;
2034         }
2035     }
2036   fatal_insn (\"unexpected cmov operator\", operands[4]);
2037   return \"\";
2039   [(set_attr "type"     "move,move")
2040    (set_attr "mode"     "SI")
2041    (set_attr "length"   "3,3")])
2043 (define_insn "movsicc_internal1"
2044   [(set (match_operand:SI 0 "register_operand" "=a,a")
2045         (if_then_else:SI (match_operator 4 "boolean_operator"
2046                            [(match_operand:CC 1 "register_operand" "b,b")
2047                             (const_int 0)])
2048                          (match_operand:SI 2 "register_operand" "r,0")
2049                          (match_operand:SI 3 "register_operand" "0,r")))]
2050   "TARGET_BOOLEANS"
2051   "*
2053   int isEq = (GET_CODE (operands[4]) == EQ);
2054   switch (which_alternative)
2055     {
2056     case 0:
2057       if (isEq) return \"movf\\t%0, %2, %1\";
2058       return \"movt\\t%0, %2, %1\";
2059     case 1:
2060       if (isEq) return \"movt\\t%0, %3, %1\";
2061       return \"movf\\t%0, %3, %1\";
2062     }
2063   abort ();
2064   return \"\";
2066   [(set_attr "type"     "move,move")
2067    (set_attr "mode"     "SI")
2068    (set_attr "length"   "3,3")])
2070 (define_insn "movsfcc_internal0"
2071   [(set (match_operand:SF 0 "register_operand" "=a,a,f,f")
2072         (if_then_else:SF (match_operator 4 "branch_operator"
2073                            [(match_operand:SI 1 "register_operand" "r,r,r,r")
2074                             (const_int 0)])
2075                          (match_operand:SF 2 "register_operand" "r,0,f,0")
2076                          (match_operand:SF 3 "register_operand" "0,r,0,f")))]
2077   ""
2078   "*
2080   if (which_alternative == 0)
2081     {
2082       switch (GET_CODE (operands[4]))
2083         {
2084         case EQ:        return \"moveqz\\t%0, %2, %1\";
2085         case NE:        return \"movnez\\t%0, %2, %1\";
2086         case LT:        return \"movltz\\t%0, %2, %1\";
2087         case GE:        return \"movgez\\t%0, %2, %1\";
2088         default:        break;
2089         }
2090     }
2091   else if (which_alternative == 1)
2092     {
2093       switch (GET_CODE (operands[4]))
2094         {
2095         case EQ:        return \"movnez\\t%0, %3, %1\";
2096         case NE:        return \"moveqz\\t%0, %3, %1\";
2097         case LT:        return \"movgez\\t%0, %3, %1\";
2098         case GE:        return \"movltz\\t%0, %3, %1\";
2099         default:        break;
2100         }
2101     }
2102   else if (which_alternative == 2)
2103     {
2104       switch (GET_CODE (operands[4]))
2105         {
2106         case EQ:        return \"moveqz.s %0, %2, %1\";
2107         case NE:        return \"movnez.s %0, %2, %1\";
2108         case LT:        return \"movltz.s %0, %2, %1\";
2109         case GE:        return \"movgez.s %0, %2, %1\";
2110         default:        break;
2111         }
2112     }
2113   else if (which_alternative == 3)
2114     {
2115       switch (GET_CODE (operands[4]))
2116         {
2117         case EQ:        return \"movnez.s %0, %3, %1\";
2118         case NE:        return \"moveqz.s %0, %3, %1\";
2119         case LT:        return \"movgez.s %0, %3, %1\";
2120         case GE:        return \"movltz.s %0, %3, %1\";
2121         default:        break;
2122         }
2123     }
2124   fatal_insn (\"unexpected cmov operator\", operands[4]);
2125   return \"\";
2127   [(set_attr "type"     "move,move,move,move")
2128    (set_attr "mode"     "SF")
2129    (set_attr "length"   "3,3,3,3")])
2131 (define_insn "movsfcc_internal1"
2132   [(set (match_operand:SF 0 "register_operand" "=a,a,f,f")
2133         (if_then_else:SF (match_operator 4 "boolean_operator"
2134                            [(match_operand:CC 1 "register_operand" "b,b,b,b")
2135                             (const_int 0)])
2136                          (match_operand:SF 2 "register_operand" "r,0,f,0")
2137                          (match_operand:SF 3 "register_operand" "0,r,0,f")))]
2138   "TARGET_BOOLEANS"
2139   "*
2141   int isEq = (GET_CODE (operands[4]) == EQ);
2142   switch (which_alternative)
2143     {
2144     case 0:
2145       if (isEq) return \"movf\\t%0, %2, %1\";
2146       return \"movt\\t%0, %2, %1\";
2147     case 1:
2148       if (isEq) return \"movt\\t%0, %3, %1\";
2149       return \"movf\\t%0, %3, %1\";
2150     case 2:
2151       if (isEq) return \"movf.s\\t%0, %2, %1\";
2152       return \"movt.s\\t%0, %2, %1\";
2153     case 3:
2154       if (isEq) return \"movt.s\\t%0, %3, %1\";
2155       return \"movf.s\\t%0, %3, %1\";
2156     }
2157   abort ();
2158   return \"\";
2160   [(set_attr "type"     "move,move,move,move")
2161    (set_attr "mode"     "SF")
2162    (set_attr "length"   "3,3,3,3")])
2166 ;;  ....................
2168 ;;      FLOATING POINT COMPARISONS
2170 ;;  ....................
2173 (define_insn "seq_sf"
2174   [(set (match_operand:CC 0 "register_operand" "=b")
2175         (eq:CC (match_operand:SF 1 "register_operand" "f")
2176                (match_operand:SF 2 "register_operand" "f")))]
2177   "TARGET_HARD_FLOAT"
2178   "oeq.s\\t%0, %1, %2"
2179   [(set_attr "type"     "farith")
2180    (set_attr "mode"     "BL")
2181    (set_attr "length"   "3")])
2183 (define_insn "slt_sf"
2184   [(set (match_operand:CC 0 "register_operand" "=b")
2185         (lt:CC (match_operand:SF 1 "register_operand" "f")
2186                (match_operand:SF 2 "register_operand" "f")))]
2187   "TARGET_HARD_FLOAT"
2188   "olt.s\\t%0, %1, %2"
2189   [(set_attr "type"     "farith")
2190    (set_attr "mode"     "BL")
2191    (set_attr "length"   "3")])
2193 (define_insn "sle_sf"
2194   [(set (match_operand:CC 0 "register_operand" "=b")
2195         (le:CC (match_operand:SF 1 "register_operand" "f")
2196                (match_operand:SF 2 "register_operand" "f")))]
2197   "TARGET_HARD_FLOAT"
2198   "ole.s\\t%0, %1, %2"
2199   [(set_attr "type"     "farith")
2200    (set_attr "mode"     "BL")
2201    (set_attr "length"   "3")])
2205 ;;  ....................
2207 ;;      UNCONDITIONAL BRANCHES
2209 ;;  ....................
2212 (define_insn "jump"
2213   [(set (pc)
2214         (label_ref (match_operand 0 "" "")))]
2215   ""
2216   "j\\t%l0"
2217   [(set_attr "type"     "jump")
2218    (set_attr "mode"     "none")
2219    (set_attr "length"   "3")])
2221 (define_expand "indirect_jump"
2222   [(set (pc) (match_operand 0 "register_operand" ""))]
2223   ""
2224   "
2226   rtx dest = operands[0];
2227   if (GET_CODE (dest) != REG || GET_MODE (dest) != Pmode)
2228     operands[0] = copy_to_mode_reg (Pmode, dest);
2230   emit_jump_insn (gen_indirect_jump_internal (dest));
2231   DONE;
2234 (define_insn "indirect_jump_internal"
2235   [(set (pc) (match_operand:SI 0 "register_operand" "r"))]
2236   ""
2237   "jx\\t%0"
2238   [(set_attr "type"     "jump")
2239    (set_attr "mode"     "none")
2240    (set_attr "length"   "3")])
2243 (define_expand "tablejump"
2244   [(use (match_operand:SI 0 "register_operand" ""))
2245    (use (label_ref (match_operand 1 "" "")))]
2246    ""
2247    "
2249   rtx target = operands[0];
2250   if (flag_pic)
2251     {
2252       /* For PIC, the table entry is relative to the start of the table. */
2253       rtx label = gen_reg_rtx (SImode);
2254       target = gen_reg_rtx (SImode);
2255       emit_move_insn (label, gen_rtx_LABEL_REF (SImode, operands[1]));
2256       emit_insn (gen_addsi3 (target, operands[0], label));
2257     }
2258   emit_jump_insn (gen_tablejump_internal (target, operands[1]));
2259   DONE;
2262 (define_insn "tablejump_internal"
2263   [(set (pc)
2264         (match_operand:SI 0 "register_operand" "r"))
2265    (use (label_ref (match_operand 1 "" "")))]
2266   ""
2267   "jx\\t%0"
2268   [(set_attr "type"     "jump")
2269    (set_attr "mode"     "none")
2270    (set_attr "length"   "3")])
2274 ;;  ....................
2276 ;;      FUNCTION CALLS
2278 ;;  ....................
2281 (define_expand "sym_PLT"
2282   [(const (unspec [(match_operand:SI 0 "" "")] UNSPEC_PLT))]
2283   ""
2284   "")
2286 (define_expand "call"
2287   [(call (match_operand 0 "memory_operand" "")
2288          (match_operand 1 "" ""))]
2289   ""
2290   "
2292   rtx addr = XEXP (operands[0], 0);
2293   if (flag_pic && GET_CODE (addr) == SYMBOL_REF && !SYMBOL_REF_FLAG (addr))
2294     addr = gen_sym_PLT (addr);
2295   if (!call_insn_operand (addr, VOIDmode))
2296     XEXP (operands[0], 0) = copy_to_mode_reg (Pmode, addr);
2299 (define_insn "call_internal"
2300   [(call (mem (match_operand:SI 0 "call_insn_operand" "n,i,r"))
2301          (match_operand 1 "" "i,i,i"))]
2302   ""
2303   "*
2304     return xtensa_emit_call (0, operands);
2305   "
2306   [(set_attr "type"     "call")
2307    (set_attr "mode"     "none")
2308    (set_attr "length"   "3")])
2310 (define_expand "call_value"
2311   [(set (match_operand 0 "register_operand" "")
2312         (call (match_operand 1 "memory_operand" "")
2313               (match_operand 2 "" "")))]
2314   ""
2315   "
2317   rtx addr = XEXP (operands[1], 0);
2318   if (flag_pic && GET_CODE (addr) == SYMBOL_REF && !SYMBOL_REF_FLAG (addr))
2319     addr = gen_sym_PLT (addr);
2320   if (!call_insn_operand (addr, VOIDmode))
2321     XEXP (operands[1], 0) = copy_to_mode_reg (Pmode, addr);
2324 ;; cannot combine constraints for operand 0 into "afvb"
2325 ;; reload.c:find_reloads seems to assume that grouped constraints somehow
2326 ;; specify related register classes, and when they don't the constraints
2327 ;; fail to match. By not grouping the constraints, we get the correct
2328 ;; behavior.
2329 (define_insn "call_value_internal"
2330    [(set (match_operand 0 "register_operand" "=af,af,af,v,v,v,b,b,b")
2331          (call (mem (match_operand:SI 1 "call_insn_operand"
2332                                         "n,i,r,n,i,r,n,i,r"))
2333                (match_operand 2 "" "i,i,i,i,i,i,i,i,i")))]
2334   ""
2335   "*
2336     return xtensa_emit_call (1, operands);
2337   "
2338   [(set_attr "type"     "call")
2339    (set_attr "mode"     "none")
2340    (set_attr "length"   "3")])
2342 (define_insn "return"
2343   [(return)
2344    (use (reg:SI A0_REG))]
2345   "reload_completed"
2346   "*
2348   return (TARGET_DENSITY ? \"retw.n\" : \"retw\");
2350   [(set_attr "type"     "jump")
2351    (set_attr "mode"     "none")
2352    (set_attr "length"   "2")])
2356 ;;  ....................
2358 ;;      MISC.
2360 ;;  ....................
2363 (define_insn "nop"
2364   [(const_int 0)]
2365   ""
2366   "*
2368   return (TARGET_DENSITY ? \"nop.n\" : \"nop\");
2370   [(set_attr "type"     "nop")
2371    (set_attr "mode"     "none")
2372    (set_attr "length"   "3")])
2374 (define_expand "nonlocal_goto"
2375   [(match_operand:SI 0 "general_operand" "")
2376    (match_operand:SI 1 "general_operand" "")
2377    (match_operand:SI 2 "general_operand" "")
2378    (match_operand:SI 3 "" "")]
2379   ""
2380   "
2382   xtensa_expand_nonlocal_goto (operands);
2383   DONE;
2386 ;; Setting up a frame pointer is tricky for Xtensa because GCC doesn't
2387 ;; know if a frame pointer is required until the reload pass, and
2388 ;; because there may be an incoming argument value in the hard frame
2389 ;; pointer register (a7). If there is an incoming argument in that
2390 ;; register, the "set_frame_ptr" insn gets inserted immediately after
2391 ;; the insn that copies the incoming argument to a pseudo or to the
2392 ;; stack.  This serves several purposes here: (1) it keeps the
2393 ;; optimizer from copy-propagating or scheduling the use of a7 as an
2394 ;; incoming argument away from the beginning of the function; (2) we
2395 ;; can use a post-reload splitter to expand away the insn if a frame
2396 ;; pointer is not required, so that the post-reload scheduler can do
2397 ;; the right thing; and (3) it makes it easy for xtensa_reorg() to
2398 ;; search for this insn to determine whether it should add a new insn
2399 ;; to set up the frame pointer.
2401 (define_insn "set_frame_ptr"
2402   [(unspec_volatile [(const_int 0)] UNSPECV_SET_FP)]
2403   ""
2404   "*
2406   if (frame_pointer_needed)
2407     return \"mov\\ta7, sp\";
2408   return \"\";
2410   [(set_attr "type"     "move")
2411    (set_attr "mode"     "SI")
2412    (set_attr "length"   "3")])
2414 ;; Post-reload splitter to remove fp assignment when it's not needed.
2415 (define_split
2416   [(unspec_volatile [(const_int 0)] UNSPECV_SET_FP)]
2417   "reload_completed && !frame_pointer_needed"
2418   [(unspec [(const_int 0)] UNSPEC_NOP)]
2419   "")
2421 ;; The preceding splitter needs something to split the insn into;
2422 ;; things start breaking if the result is just a "use" so instead we
2423 ;; generate the following insn.
2424 (define_insn "*unspec_nop"
2425   [(unspec [(const_int 0)] UNSPEC_NOP)]
2426   ""
2427   ""
2428   [(set_attr "type"     "nop")
2429    (set_attr "mode"     "none")
2430    (set_attr "length"   "0")])
2432 ;; The fix_return_addr pattern sets the high 2 bits of an address in a
2433 ;; register to match the high bits of the current PC.
2435 (define_insn "fix_return_addr"
2436   [(set (match_operand:SI 0 "register_operand" "=a")
2437         (unspec:SI [(match_operand:SI 1 "register_operand" "r")]
2438                    UNSPEC_RET_ADDR))
2439    (clobber (match_scratch:SI 2 "=r"))
2440    (clobber (match_scratch:SI 3 "=r"))]
2441   ""
2442   "mov\\t%2, a0\;call0\\t0f\;.align\\t4\;0:\;mov\\t%3, a0\;mov\\ta0, %2\;\
2443 srli\\t%3, %3, 30\;slli\\t%0, %1, 2\;ssai\\t2\;src\\t%0, %3, %0"
2444   [(set_attr "type"     "multi")
2445    (set_attr "mode"     "SI")
2446    (set_attr "length"   "24")])
2450 ;;  ....................
2452 ;;      BOOLEANS
2454 ;;  ....................
2457 ;; branch patterns
2459 (define_insn "*booltrue"
2460   [(set (pc)
2461         (if_then_else (match_operator 2 "boolean_operator"
2462                          [(match_operand:CC 0 "register_operand" "b")
2463                           (const_int 0)])
2464                       (label_ref (match_operand 1 "" ""))
2465                       (pc)))]
2466   "TARGET_BOOLEANS"
2467   "*
2469   if (GET_CODE (operands[2]) == EQ)
2470     return \"bf\\t%0, %1\";
2471   else
2472     return \"bt\\t%0, %1\";
2474   [(set_attr "type"     "jump")
2475    (set_attr "mode"     "none")
2476    (set_attr "length"   "3")])
2478 (define_insn "*boolfalse"
2479   [(set (pc)
2480         (if_then_else (match_operator 2 "boolean_operator"
2481                          [(match_operand:CC 0 "register_operand" "b")
2482                           (const_int 0)])
2483                       (pc)
2484                       (label_ref (match_operand 1 "" ""))))]
2485   "TARGET_BOOLEANS"
2486   "*
2488   if (GET_CODE (operands[2]) == EQ)
2489     return \"bt\\t%0, %1\";
2490   else
2491     return \"bf\\t%0, %1\";
2493   [(set_attr "type"     "jump")
2494    (set_attr "mode"     "none")
2495    (set_attr "length"   "3")])