* config/xtensa/lib2funcs.S (TRAMPOLINE_SIZE): Change from 49 to 59.
[official-gcc.git] / gcc / config / xtensa / xtensa.md
blobaa5896ed51182a4eb2451d2fc5a208202dfe2d78
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   (A1_REG               1)
33   (A7_REG               7)
34   (A8_REG               8)
36   (UNSPEC_NSAU          1)
37   (UNSPEC_NOP           2)
38   (UNSPEC_PLT           3)
39   (UNSPEC_RET_ADDR      4)
40   (UNSPECV_SET_FP       1)
41   (UNSPECV_ENTRY        2)
45 ;; ....................
47 ;;      ATTRIBUTES
49 ;; ....................
52 (define_attr "type"
53   "unknown,jump,call,load,store,move,arith,multi,nop,farith,fmadd,fdiv,fsqrt,fconv,fload,fstore,mul16,mul32,div32,mac16,rsr,wsr"
54   (const_string "unknown"))
56 (define_attr "mode"
57   "unknown,none,QI,HI,SI,DI,SF,DF,BL"
58   (const_string "unknown"))
60 (define_attr "length" "" (const_int 1))
62 ;; Describe a user's asm statement.
63 (define_asm_attributes
64   [(set_attr "type" "multi")])
68 ;; ....................
70 ;;      FUNCTIONAL UNITS
72 ;; ....................
75 (define_function_unit "memory" 1 0 (eq_attr "type" "load,fload") 2 0)
77 (define_function_unit "sreg" 1 1 (eq_attr "type" "rsr") 2 0)
79 (define_function_unit "mul16" 1 0 (eq_attr "type" "mul16") 2 0)
81 (define_function_unit "mul32" 1 0 (eq_attr "type" "mul32") 2 0)
83 (define_function_unit "fpmadd" 1 0 (eq_attr "type" "fmadd") 4 0)
85 (define_function_unit "fpconv" 1 0 (eq_attr "type" "fconv") 2 0)
89 ;;  ....................
91 ;;      ADDITION
93 ;;  ....................
96 (define_expand "adddi3"
97   [(set (match_operand:DI 0 "register_operand" "")
98         (plus:DI (match_operand:DI 1 "register_operand" "")
99                  (match_operand:DI 2 "register_operand" "")))]
100   ""
101   "
103   rtx srclo;
104   rtx dstlo = gen_lowpart (SImode, operands[0]);
105   rtx src1lo = gen_lowpart (SImode, operands[1]);
106   rtx src2lo = gen_lowpart (SImode, operands[2]);
108   rtx dsthi = gen_highpart (SImode, operands[0]);
109   rtx src1hi = gen_highpart (SImode, operands[1]);
110   rtx src2hi = gen_highpart (SImode, operands[2]);
112   /* Either source can be used for overflow checking, as long as it's
113      not clobbered by the first addition.  */
114   if (!rtx_equal_p (dstlo, src1lo))
115     srclo = src1lo;
116   else if (!rtx_equal_p (dstlo, src2lo))
117     srclo = src2lo;
118   else
119     {
120       srclo = gen_reg_rtx (SImode);
121       emit_move_insn (srclo, src1lo);
122     }
124   emit_insn (gen_addsi3 (dstlo, src1lo, src2lo));
125   emit_insn (gen_addsi3 (dsthi, src1hi, src2hi));
126   emit_insn (gen_adddi_carry (dsthi, dstlo, srclo));
127   DONE;
130 ;; Represent the add-carry operation as an atomic operation instead of
131 ;; expanding it to a conditional branch.  Otherwise, the edge
132 ;; profiling code breaks because inserting the count increment code
133 ;; causes a new jump insn to be added.
135 (define_insn "adddi_carry"
136   [(set (match_operand:SI 0 "register_operand" "+a")
137         (plus:SI (ltu:SI (match_operand:SI 1 "register_operand" "r")
138                          (match_operand:SI 2 "register_operand" "r"))
139                  (match_dup 0)))]
140   ""
141   "bgeu\\t%1, %2, 0f\;addi\\t%0, %0, 1\;0:"
142   [(set_attr "type"     "multi")
143    (set_attr "mode"     "SI")
144    (set_attr "length"   "6")])
146 (define_insn "addsi3"
147   [(set (match_operand:SI 0 "register_operand" "=D,D,a,a,a")
148         (plus:SI (match_operand:SI 1 "register_operand" "%d,d,r,r,r")
149                  (match_operand:SI 2 "add_operand" "d,O,r,J,N")))]
150   ""
151   "@
152    add.n\\t%0, %1, %2
153    addi.n\\t%0, %1, %d2
154    add\\t%0, %1, %2
155    addi\\t%0, %1, %d2
156    addmi\\t%0, %1, %x2"
157   [(set_attr "type"     "arith,arith,arith,arith,arith")
158    (set_attr "mode"     "SI")
159    (set_attr "length"   "2,2,3,3,3")])
161 (define_insn "*addx2"
162   [(set (match_operand:SI 0 "register_operand" "=a")
163         (plus:SI (mult:SI (match_operand:SI 1 "register_operand" "r")
164                           (const_int 2))
165                  (match_operand:SI 2 "register_operand" "r")))]
166   ""
167   "addx2\\t%0, %1, %2"
168   [(set_attr "type"     "arith")
169    (set_attr "mode"     "SI")
170    (set_attr "length"   "3")])
172 (define_insn "*addx4"
173   [(set (match_operand:SI 0 "register_operand" "=a")
174         (plus:SI (mult:SI (match_operand:SI 1 "register_operand" "r")
175                           (const_int 4))
176                  (match_operand:SI 2 "register_operand" "r")))]
177   ""
178   "addx4\\t%0, %1, %2"
179   [(set_attr "type"     "arith")
180    (set_attr "mode"     "SI")
181    (set_attr "length"   "3")])
183 (define_insn "*addx8"
184   [(set (match_operand:SI 0 "register_operand" "=a")
185         (plus:SI (mult:SI (match_operand:SI 1 "register_operand" "r")
186                           (const_int 8))
187                  (match_operand:SI 2 "register_operand" "r")))]
188   ""
189   "addx8\\t%0, %1, %2"
190   [(set_attr "type"     "arith")
191    (set_attr "mode"     "SI")
192    (set_attr "length"   "3")])
194 (define_insn "addsf3"
195   [(set (match_operand:SF 0 "register_operand" "=f")
196         (plus:SF (match_operand:SF 1 "register_operand" "%f")
197                  (match_operand:SF 2 "register_operand" "f")))]
198   "TARGET_HARD_FLOAT"
199   "add.s\\t%0, %1, %2"
200   [(set_attr "type"     "fmadd")
201    (set_attr "mode"     "SF")
202    (set_attr "length"   "3")])
206 ;;  ....................
208 ;;      SUBTRACTION
210 ;;  ....................
213 (define_expand "subdi3"
214   [(set (match_operand:DI 0 "register_operand" "")
215         (minus:DI (match_operand:DI 1 "register_operand" "")
216                   (match_operand:DI 2 "register_operand" "")))]
217   ""
218   "
220   rtx dstlo = gen_lowpart (SImode, operands[0]);
221   rtx src1lo = gen_lowpart (SImode, operands[1]);
222   rtx src2lo = gen_lowpart (SImode, operands[2]);
224   rtx dsthi = gen_highpart (SImode, operands[0]);
225   rtx src1hi = gen_highpart (SImode, operands[1]);
226   rtx src2hi = gen_highpart (SImode, operands[2]);
228   emit_insn (gen_subsi3 (dsthi, src1hi, src2hi));
229   emit_insn (gen_subdi_carry (dsthi, src1lo, src2lo));
230   emit_insn (gen_subsi3 (dstlo, src1lo, src2lo));
231   DONE;
234 (define_insn "subdi_carry"
235   [(set (match_operand:SI 0 "register_operand" "+a")
236         (minus:SI (match_dup 0)
237                   (ltu:SI (match_operand:SI 1 "register_operand" "r")
238                           (match_operand:SI 2 "register_operand" "r"))))]
239   ""
240   "bgeu\\t%1, %2, 0f\;addi\\t%0, %0, -1\;0:"
241   [(set_attr "type"     "multi")
242    (set_attr "mode"     "SI")
243    (set_attr "length"   "6")])
245 (define_insn "subsi3"
246   [(set (match_operand:SI 0 "register_operand" "=a")
247         (minus:SI (match_operand:SI 1 "register_operand" "r")
248                   (match_operand:SI 2 "register_operand" "r")))]
249   ""
250   "sub\\t%0, %1, %2"
251   [(set_attr "type"     "arith")
252    (set_attr "mode"     "SI")
253    (set_attr "length"   "3")])
255 (define_insn "*subx2"
256   [(set (match_operand:SI 0 "register_operand" "=a")
257         (minus:SI (mult:SI (match_operand:SI 1 "register_operand" "r")
258                            (const_int 2))
259                   (match_operand:SI 2 "register_operand" "r")))]
260   ""
261   "subx2\\t%0, %1, %2"
262   [(set_attr "type"     "arith")
263    (set_attr "mode"     "SI")
264    (set_attr "length"   "3")])
266 (define_insn "*subx4"
267   [(set (match_operand:SI 0 "register_operand" "=a")
268         (minus:SI (mult:SI (match_operand:SI 1 "register_operand" "r")
269                            (const_int 4))
270                   (match_operand:SI 2 "register_operand" "r")))]
271   ""
272   "subx4\\t%0, %1, %2"
273   [(set_attr "type"     "arith")
274    (set_attr "mode"     "SI")
275    (set_attr "length"   "3")])
277 (define_insn "*subx8"
278   [(set (match_operand:SI 0 "register_operand" "=a")
279         (minus:SI (mult:SI (match_operand:SI 1 "register_operand" "r")
280                            (const_int 8))
281                   (match_operand:SI 2 "register_operand" "r")))]
282   ""
283   "subx8\\t%0, %1, %2"
284   [(set_attr "type"     "arith")
285    (set_attr "mode"     "SI")
286    (set_attr "length"   "3")])
288 (define_insn "subsf3"
289   [(set (match_operand:SF 0 "register_operand" "=f")
290         (minus:SF (match_operand:SF 1 "register_operand" "f")
291                   (match_operand:SF 2 "register_operand" "f")))]
292   "TARGET_HARD_FLOAT"
293   "sub.s\\t%0, %1, %2"
294   [(set_attr "type"     "fmadd")
295    (set_attr "mode"     "SF")
296    (set_attr "length"   "3")])
300 ;;  ....................
302 ;;      MULTIPLICATION
304 ;;  ....................
307 (define_insn "mulsi3"
308   [(set (match_operand:SI 0 "register_operand" "=a")
309         (mult:SI (match_operand:SI 1 "register_operand" "%r")
310                  (match_operand:SI 2 "register_operand" "r")))]
311   "TARGET_MUL32"
312   "mull\\t%0, %1, %2"
313   [(set_attr "type"     "mul32")
314    (set_attr "mode"     "SI")
315    (set_attr "length"   "3")])
317 (define_insn "mulhisi3"
318   [(set (match_operand:SI 0 "register_operand" "=C,A")
319         (mult:SI (sign_extend:SI
320                   (match_operand:HI 1 "register_operand" "%r,r"))
321                  (sign_extend:SI
322                   (match_operand:HI 2 "register_operand" "r,r"))))]
323   "TARGET_MUL16 || TARGET_MAC16"
324   "@
325    mul16s\\t%0, %1, %2
326    mul.aa.ll\\t%1, %2"
327   [(set_attr "type"     "mul16,mac16")
328    (set_attr "mode"     "SI")
329    (set_attr "length"   "3,3")])
331 (define_insn "umulhisi3"
332   [(set (match_operand:SI 0 "register_operand" "=C,A")
333         (mult:SI (zero_extend:SI
334                   (match_operand:HI 1 "register_operand" "%r,r"))
335                  (zero_extend:SI
336                   (match_operand:HI 2 "register_operand" "r,r"))))]
337   "TARGET_MUL16 || TARGET_MAC16"
338   "@
339    mul16u\\t%0, %1, %2
340    umul.aa.ll\\t%1, %2"
341   [(set_attr "type"     "mul16,mac16")
342    (set_attr "mode"     "SI")
343    (set_attr "length"   "3,3")])
345 (define_insn "muladdhisi"
346   [(set (match_operand:SI 0 "register_operand" "=A")
347         (plus:SI (mult:SI (sign_extend:SI
348                            (match_operand:HI 1 "register_operand" "%r"))
349                           (sign_extend:SI
350                            (match_operand:HI 2 "register_operand" "r")))
351                  (match_operand:SI 3 "register_operand" "0")))]
352   "TARGET_MAC16"
353   "mula.aa.ll\\t%1, %2"
354   [(set_attr "type"     "mac16")
355    (set_attr "mode"     "SI")
356    (set_attr "length"   "3")])
358 (define_insn "mulsubhisi"
359   [(set (match_operand:SI 0 "register_operand" "=A")
360         (minus:SI (match_operand:SI 1 "register_operand" "0")
361                   (mult:SI (sign_extend:SI
362                             (match_operand:HI 2 "register_operand" "%r"))
363                            (sign_extend:SI
364                             (match_operand:HI 3 "register_operand" "r")))))]
365   "TARGET_MAC16"
366   "muls.aa.ll\\t%2, %3"
367   [(set_attr "type"     "mac16")
368    (set_attr "mode"     "SI")
369    (set_attr "length"   "3")])
371 (define_insn "mulsf3"
372   [(set (match_operand:SF 0 "register_operand" "=f")
373         (mult:SF (match_operand:SF 1 "register_operand" "%f")
374                  (match_operand:SF 2 "register_operand" "f")))]
375   "TARGET_HARD_FLOAT"
376   "mul.s\\t%0, %1, %2"
377   [(set_attr "type"     "fmadd")
378    (set_attr "mode"     "SF")
379    (set_attr "length"   "3")])
381 (define_insn "muladdsf3"
382   [(set (match_operand:SF 0 "register_operand" "=f")
383         (plus:SF (mult:SF (match_operand:SF 1 "register_operand" "%f")
384                           (match_operand:SF 2 "register_operand" "f"))
385                  (match_operand:SF 3 "register_operand" "0")))]
386   "TARGET_HARD_FLOAT && !TARGET_NO_FUSED_MADD"
387   "madd.s\\t%0, %1, %2"
388   [(set_attr "type"     "fmadd")
389    (set_attr "mode"     "SF")
390    (set_attr "length"   "3")])
392 (define_insn "mulsubsf3"
393   [(set (match_operand:SF 0 "register_operand" "=f")
394         (minus:SF (match_operand:SF 1 "register_operand" "0")
395                   (mult:SF (match_operand:SF 2 "register_operand" "%f")
396                            (match_operand:SF 3 "register_operand" "f"))))]
397   "TARGET_HARD_FLOAT && !TARGET_NO_FUSED_MADD"
398   "msub.s\\t%0, %2, %3"
399   [(set_attr "type"     "fmadd")
400    (set_attr "mode"     "SF")
401    (set_attr "length"   "3")])
405 ;;  ....................
407 ;;      DIVISION
409 ;;  ....................
412 (define_insn "divsi3"
413   [(set (match_operand:SI 0 "register_operand" "=a")
414         (div:SI (match_operand:SI 1 "register_operand" "r")
415                 (match_operand:SI 2 "register_operand" "r")))]
416   "TARGET_DIV32"
417   "quos\\t%0, %1, %2"
418   [(set_attr "type"     "div32")
419    (set_attr "mode"     "SI")
420    (set_attr "length"   "3")])
422 (define_insn "udivsi3"
423   [(set (match_operand:SI 0 "register_operand" "=a")
424         (udiv:SI (match_operand:SI 1 "register_operand" "r")
425                  (match_operand:SI 2 "register_operand" "r")))]
426   "TARGET_DIV32"
427   "quou\\t%0, %1, %2"
428   [(set_attr "type"     "div32")
429    (set_attr "mode"     "SI")
430    (set_attr "length"   "3")])
432 (define_insn "divsf3"
433   [(set (match_operand:SF 0 "register_operand" "=f")
434         (div:SF (match_operand:SF 1 "register_operand" "f")
435                 (match_operand:SF 2 "register_operand" "f")))]
436   "TARGET_HARD_FLOAT_DIV"
437   "div.s\\t%0, %1, %2"
438   [(set_attr "type"     "fdiv")
439    (set_attr "mode"     "SF")
440    (set_attr "length"   "3")])
442 (define_insn "*recipsf2"
443   [(set (match_operand:SF 0 "register_operand" "=f")
444         (div:SF (match_operand:SF 1 "const_float_1_operand" "")
445                 (match_operand:SF 2 "register_operand" "f")))]
446   "TARGET_HARD_FLOAT_RECIP && flag_unsafe_math_optimizations"
447   "recip.s\\t%0, %2"
448   [(set_attr "type"     "fdiv")
449    (set_attr "mode"     "SF")
450    (set_attr "length"   "3")])
454 ;;  ....................
456 ;;      REMAINDER
458 ;;  ....................
461 (define_insn "modsi3"
462   [(set (match_operand:SI 0 "register_operand" "=a")
463         (mod:SI (match_operand:SI 1 "register_operand" "r")
464                 (match_operand:SI 2 "register_operand" "r")))]
465   "TARGET_DIV32"
466   "rems\\t%0, %1, %2"
467   [(set_attr "type"     "div32")
468    (set_attr "mode"     "SI")
469    (set_attr "length"   "3")])
471 (define_insn "umodsi3"
472   [(set (match_operand:SI 0 "register_operand" "=a")
473         (umod:SI (match_operand:SI 1 "register_operand" "r")
474                  (match_operand:SI 2 "register_operand" "r")))]
475   "TARGET_DIV32"
476   "remu\\t%0, %1, %2"
477   [(set_attr "type"     "div32")
478    (set_attr "mode"     "SI")
479    (set_attr "length"   "3")])
483 ;;  ....................
485 ;;      SQUARE ROOT
487 ;;  ....................
490 (define_insn "sqrtsf2"
491   [(set (match_operand:SF 0 "register_operand" "=f")
492         (sqrt:SF (match_operand:SF 1 "register_operand" "f")))]
493   "TARGET_HARD_FLOAT_SQRT"
494   "sqrt.s\\t%0, %1"
495   [(set_attr "type"     "fsqrt")
496    (set_attr "mode"     "SF")
497    (set_attr "length"   "3")])
499 (define_insn "*rsqrtsf2"
500   [(set (match_operand:SF 0 "register_operand" "=f")
501         (div:SF (match_operand:SF 1 "const_float_1_operand" "")
502                 (sqrt:SF (match_operand:SF 2 "register_operand" "f"))))]
503   "TARGET_HARD_FLOAT_RSQRT && flag_unsafe_math_optimizations"
504   "rsqrt.s\\t%0, %2"
505   [(set_attr "type"     "fsqrt")
506    (set_attr "mode"     "SF")
507    (set_attr "length"   "3")])
511 ;;  ....................
513 ;;      ABSOLUTE VALUE
515 ;;  ....................
518 (define_insn "abssi2"
519   [(set (match_operand:SI 0 "register_operand" "=a")
520         (abs:SI (match_operand:SI 1 "register_operand" "r")))]
521   ""
522   "abs\\t%0, %1"
523   [(set_attr "type"     "arith")
524    (set_attr "mode"     "SI")
525    (set_attr "length"   "3")])
527 (define_insn "abssf2"
528   [(set (match_operand:SF 0 "register_operand" "=f")
529         (abs:SF (match_operand:SF 1 "register_operand" "f")))]
530   "TARGET_HARD_FLOAT"
531   "abs.s\\t%0, %1"
532   [(set_attr "type"     "farith")
533    (set_attr "mode"     "SF")
534    (set_attr "length"   "3")])
538 ;;  ....................
540 ;;      MIN AND MAX INSTRUCTIONS
542 ;;  ....................
545 (define_insn "sminsi3"
546   [(set (match_operand:SI 0 "register_operand" "=a")
547         (smin:SI (match_operand:SI 1 "register_operand" "%r")
548                  (match_operand:SI 2 "register_operand" "r")))]
549   "TARGET_MINMAX"
550   "min\\t%0, %1, %2"
551   [(set_attr "type"     "arith")
552    (set_attr "mode"     "SI")
553    (set_attr "length"   "3")])
555 (define_insn "uminsi3"
556   [(set (match_operand:SI 0 "register_operand" "=a")
557         (umin:SI (match_operand:SI 1 "register_operand" "%r")
558                  (match_operand:SI 2 "register_operand" "r")))]
559   "TARGET_MINMAX"
560   "minu\\t%0, %1, %2"
561   [(set_attr "type"     "arith")
562    (set_attr "mode"     "SI")
563    (set_attr "length"   "3")])
565 (define_insn "smaxsi3"
566   [(set (match_operand:SI 0 "register_operand" "=a")
567         (smax:SI (match_operand:SI 1 "register_operand" "%r")
568                  (match_operand:SI 2 "register_operand" "r")))]
569   "TARGET_MINMAX"
570   "max\\t%0, %1, %2"
571   [(set_attr "type"     "arith")
572    (set_attr "mode"     "SI")
573    (set_attr "length"   "3")])
575 (define_insn "umaxsi3"
576   [(set (match_operand:SI 0 "register_operand" "=a")
577         (umax:SI (match_operand:SI 1 "register_operand" "%r")
578                  (match_operand:SI 2 "register_operand" "r")))]
579   "TARGET_MINMAX"
580   "maxu\\t%0, %1, %2"
581   [(set_attr "type"     "arith")
582    (set_attr "mode"     "SI")
583    (set_attr "length"   "3")])
587 ;;  ....................
589 ;;      FIND FIRST BIT INSTRUCTION
591 ;;  ....................
594 (define_expand "ffssi2"
595   [(set (match_operand:SI 0 "register_operand" "")
596         (ffs:SI (match_operand:SI 1 "register_operand" "")))]
597   "TARGET_NSA"
598   "
600   rtx temp = gen_reg_rtx (SImode);
601   emit_insn (gen_negsi2 (temp, operands[1]));
602   emit_insn (gen_andsi3 (temp, temp, operands[1]));
603   emit_insn (gen_nsau (temp, temp));
604   emit_insn (gen_negsi2 (temp, temp));
605   emit_insn (gen_addsi3 (operands[0], temp, GEN_INT (32)));
606   DONE;
609 ;; there is no RTL operator corresponding to NSAU
610 (define_insn "nsau"
611   [(set (match_operand:SI 0 "register_operand" "=a")
612         (unspec:SI [(match_operand:SI 1 "register_operand" "r")] UNSPEC_NSAU))]
613   "TARGET_NSA"
614   "nsau\\t%0, %1"
615   [(set_attr "type"     "arith")
616    (set_attr "mode"     "SI")
617    (set_attr "length"   "3")])
621 ;;  ....................
623 ;;      NEGATION and ONE'S COMPLEMENT
625 ;;  ....................
628 (define_insn "negsi2"
629   [(set (match_operand:SI 0 "register_operand" "=a")
630         (neg:SI (match_operand:SI 1 "register_operand" "r")))]
631   ""
632   "neg\\t%0, %1"
633   [(set_attr "type"     "arith")
634    (set_attr "mode"     "SI")
635    (set_attr "length"   "3")])
637 (define_expand "one_cmplsi2"
638   [(set (match_operand:SI 0 "register_operand" "")
639         (not:SI (match_operand:SI 1 "register_operand" "")))]
640   ""
641   "
643   rtx temp = gen_reg_rtx (SImode);
644   emit_insn (gen_movsi (temp, constm1_rtx));
645   emit_insn (gen_xorsi3 (operands[0], temp, operands[1]));
646   DONE;
649 (define_insn "negsf2"
650   [(set (match_operand:SF 0 "register_operand" "=f")
651         (neg:SF (match_operand:SF 1 "register_operand" "f")))]
652   "TARGET_HARD_FLOAT"
653   "neg.s\\t%0, %1"
654   [(set_attr "type"     "farith")
655    (set_attr "mode"     "SF")
656    (set_attr "length"   "3")])
660 ;;  ....................
662 ;;      LOGICAL
664 ;;  ....................
667 (define_insn "andsi3"
668   [(set (match_operand:SI 0 "register_operand" "=a,a")
669         (and:SI (match_operand:SI 1 "register_operand" "%r,r")
670                 (match_operand:SI 2 "mask_operand" "P,r")))]
671   ""
672   "@
673    extui\\t%0, %1, 0, %K2
674    and\\t%0, %1, %2"
675   [(set_attr "type"     "arith,arith")
676    (set_attr "mode"     "SI")
677    (set_attr "length"   "3,3")])
679 (define_insn "iorsi3"
680   [(set (match_operand:SI 0 "register_operand" "=a")
681         (ior:SI (match_operand:SI 1 "register_operand" "%r")
682                 (match_operand:SI 2 "register_operand" "r")))]
683   ""
684   "or\\t%0, %1, %2"
685   [(set_attr "type"     "arith")
686    (set_attr "mode"     "SI")
687    (set_attr "length"   "3")])
689 (define_insn "xorsi3"
690   [(set (match_operand:SI 0 "register_operand" "=a")
691         (xor:SI (match_operand:SI 1 "register_operand" "%r")
692                 (match_operand:SI 2 "register_operand" "r")))]
693   ""
694   "xor\\t%0, %1, %2"
695   [(set_attr "type"     "arith")
696    (set_attr "mode"     "SI")
697    (set_attr "length"   "3")])
701 ;;  ....................
703 ;;      ZERO EXTENSION
705 ;;  ....................
708 (define_insn "zero_extendhisi2"
709   [(set (match_operand:SI 0 "register_operand" "=a,a")
710         (zero_extend:SI (match_operand:HI 1 "nonimmed_operand" "r,U")))]
711   ""
712   "@
713    extui\\t%0, %1, 0, 16
714    l16ui\\t%0, %1"
715   [(set_attr "type"     "arith,load")
716    (set_attr "mode"     "SI")
717    (set_attr "length"   "3,3")])
719 (define_insn "zero_extendqisi2"
720   [(set (match_operand:SI 0 "register_operand" "=a,a")
721         (zero_extend:SI (match_operand:QI 1 "nonimmed_operand" "r,U")))]
722   ""
723   "@
724    extui\\t%0, %1, 0, 8
725    l8ui\\t%0, %1"
726   [(set_attr "type"     "arith,load")
727    (set_attr "mode"     "SI")
728    (set_attr "length"   "3,3")])
732 ;;  ....................
734 ;;      SIGN EXTENSION
736 ;;  ....................
739 (define_expand "extendhisi2"
740   [(set (match_operand:SI 0 "register_operand" "")
741         (sign_extend:SI (match_operand:HI 1 "register_operand" "")))]
742   ""
743   "
745   if (sext_operand (operands[1], HImode))
746     emit_insn (gen_extendhisi2_internal (operands[0], operands[1]));
747   else
748     xtensa_extend_reg (operands[0], operands[1]);
749   DONE;
752 (define_insn "extendhisi2_internal"
753   [(set (match_operand:SI 0 "register_operand" "=B,a")
754         (sign_extend:SI (match_operand:HI 1 "sext_operand" "r,U")))]
755   ""
756   "@
757    sext\\t%0, %1, 15
758    l16si\\t%0, %1"
759   [(set_attr "type"     "arith,load")
760    (set_attr "mode"     "SI")
761    (set_attr "length"   "3,3")])
763 (define_expand "extendqisi2"
764   [(set (match_operand:SI 0 "register_operand" "")
765         (sign_extend:SI (match_operand:QI 1 "register_operand" "")))]
766   ""
767   "
769   if (TARGET_SEXT)
770     {
771       emit_insn (gen_extendqisi2_internal (operands[0], operands[1]));
772       DONE;
773     }
774   xtensa_extend_reg (operands[0], operands[1]);
775   DONE;
778 (define_insn "extendqisi2_internal"
779   [(set (match_operand:SI 0 "register_operand" "=B")
780         (sign_extend:SI (match_operand:QI 1 "register_operand" "r")))]
781   "TARGET_SEXT"
782   "sext\\t%0, %1, 7"
783   [(set_attr "type"     "arith")
784    (set_attr "mode"     "SI")
785    (set_attr "length"   "3")])
789 ;;  ....................
791 ;;      FIELD EXTRACT
793 ;;  ....................
796 (define_expand "extv"
797   [(set (match_operand:SI 0 "register_operand" "")
798         (sign_extract:SI (match_operand:SI 1 "register_operand" "")
799                          (match_operand:SI 2 "const_int_operand" "")
800                          (match_operand:SI 3 "const_int_operand" "")))]
801   "TARGET_SEXT"
802   "
804   if (!sext_fldsz_operand (operands[2], SImode)) FAIL;
805   /* we could expand to a right shift followed by sext but that's
806      no better than the standard left and right shift sequence */
807   if (!lsbitnum_operand (operands[3], SImode)) FAIL;
808   emit_insn (gen_extv_internal (operands[0], operands[1],
809                                 operands[2], operands[3]));
810   DONE;
813 (define_insn "extv_internal"
814   [(set (match_operand:SI 0 "register_operand" "=a")
815         (sign_extract:SI (match_operand:SI 1 "register_operand" "r")
816                          (match_operand:SI 2 "sext_fldsz_operand" "i")
817                          (match_operand:SI 3 "lsbitnum_operand" "i")))]
818   "TARGET_SEXT"
819   "*
821   int fldsz = INTVAL (operands[2]);
822   operands[2] = GEN_INT (fldsz - 1);
823   return \"sext\\t%0, %1, %2\";
825   [(set_attr "type"     "arith")
826    (set_attr "mode"     "SI")
827    (set_attr "length"   "3")])
829 (define_expand "extzv"
830   [(set (match_operand:SI 0 "register_operand" "")
831         (zero_extract:SI (match_operand:SI 1 "register_operand" "")
832                          (match_operand:SI 2 "const_int_operand" "")
833                          (match_operand:SI 3 "const_int_operand" "")))]
834   ""
835   "
837   if (!extui_fldsz_operand (operands[2], SImode)) FAIL;
838   emit_insn (gen_extzv_internal (operands[0], operands[1],
839                                  operands[2], operands[3]));
840   DONE;
843 (define_insn "extzv_internal"
844   [(set (match_operand:SI 0 "register_operand" "=a")
845         (zero_extract:SI (match_operand:SI 1 "register_operand" "r")
846                          (match_operand:SI 2 "extui_fldsz_operand" "i")
847                          (match_operand:SI 3 "const_int_operand" "i")))]
848   ""
849   "*
851   int shift;
852   if (BITS_BIG_ENDIAN)
853     shift = (32 - (INTVAL (operands[2]) + INTVAL (operands[3]))) & 0x1f;
854   else
855     shift = INTVAL (operands[3]) & 0x1f;
856   operands[3] = GEN_INT (shift);
857   return \"extui\\t%0, %1, %3, %2\";
859   [(set_attr "type"     "arith")
860    (set_attr "mode"     "SI")
861    (set_attr "length"   "3")])
865 ;;  ....................
867 ;;      CONVERSIONS
869 ;;  ....................
872 (define_insn "fix_truncsfsi2"
873   [(set (match_operand:SI 0 "register_operand" "=a")
874         (fix:SI (match_operand:SF 1 "register_operand" "f")))]
875   "TARGET_HARD_FLOAT"
876   "trunc.s\\t%0, %1, 0"
877   [(set_attr "type"     "fconv")
878    (set_attr "mode"     "SF")
879    (set_attr "length"   "3")])
881 (define_insn "fixuns_truncsfsi2"
882   [(set (match_operand:SI 0 "register_operand" "=a")
883         (unsigned_fix:SI (match_operand:SF 1 "register_operand" "f")))]
884   "TARGET_HARD_FLOAT"
885   "utrunc.s %0, %1, 0"
886   [(set_attr "type"     "fconv")
887    (set_attr "mode"     "SF")
888    (set_attr "length"   "3")])
890 (define_insn "floatsisf2"
891   [(set (match_operand:SF 0 "register_operand" "=f")
892         (float:SF (match_operand:SI 1 "register_operand" "a")))]
893   "TARGET_HARD_FLOAT"
894   "float.s\\t%0, %1, 0"
895   [(set_attr "type"     "fconv")
896    (set_attr "mode"     "SF")
897    (set_attr "length"   "3")])
899 (define_insn "floatunssisf2"
900   [(set (match_operand:SF 0 "register_operand" "=f")
901         (unsigned_float:SF (match_operand:SI 1 "register_operand" "a")))]
902   "TARGET_HARD_FLOAT"
903   "ufloat.s %0, %1, 0"
904   [(set_attr "type"     "fconv")
905    (set_attr "mode"     "SF")
906    (set_attr "length"   "3")])
910 ;;  ....................
912 ;;      DATA MOVEMENT
914 ;;  ....................
917 ;; 64-bit Integer moves
919 (define_expand "movdi"
920   [(set (match_operand:DI 0 "nonimmed_operand" "")
921         (match_operand:DI 1 "general_operand" ""))]
922   ""
923   "
925   if (CONSTANT_P (operands[1])
926       && register_operand (operands[0], DImode))
927     {
928       rtx src0, src1, dst0, dst1;
929       dst0 = operand_subword (operands[0], 0, 1, DImode);
930       src0 = operand_subword (operands[1], 0, 1, DImode);
931       dst1 = operand_subword (operands[0], 1, 1, DImode);
932       src1 = operand_subword (operands[1], 1, 1, DImode);
933       if (!dst0 || !src0 || !dst1 || !src1)
934         abort ();
935       emit_insn (gen_movsi (dst0, src0));
936       emit_insn (gen_movsi (dst1, src1));
937       DONE;
938     }
940   if (!(reload_in_progress | reload_completed))
941     {
942       if (!register_operand (operands[0], DImode)
943           && !register_operand (operands[1], DImode))
944         operands[1] = force_reg (DImode, operands[1]);
946       if (xtensa_copy_incoming_a7 (operands, DImode))
947         DONE;
948     }
951 (define_insn "movdi_internal"
952   [(set (match_operand:DI 0 "nonimmed_operand" "=D,D,S,a,a,U")
953         (match_operand:DI 1 "nonimmed_operand" "d,S,d,r,U,r"))]
954   "register_operand (operands[0], DImode)
955    || register_operand (operands[1], DImode)"
956   "*
958   rtx dstreg;
959   switch (which_alternative)
960     {
961     case 0: return \"mov.n\\t%0, %1\;mov.n\\t%D0, %D1\";
962     case 2: return \"%v0s32i.n\\t%1, %0\;s32i.n\\t%D1, %N0\";
963     case 3: return \"mov\\t%0, %1\;mov\\t%D0, %D1\";
964     case 5: return \"%v0s32i\\t%1, %0\;s32i\\t%D1, %N0\";
966     case 1:
967     case 4:
968       /* Check if the first half of the destination register is used
969          in the source address.  If so, reverse the order of the loads
970          so that the source address doesn't get clobbered until it is
971          no longer needed. */
973       dstreg = operands[0];
974       if (GET_CODE (dstreg) == SUBREG)
975         dstreg = SUBREG_REG (dstreg);
976       if (GET_CODE (dstreg) != REG)
977         abort();
979       if (reg_mentioned_p (dstreg, operands[1]))
980         {
981           switch (which_alternative)
982             {
983             case 1: return \"%v1l32i.n\\t%D0, %N1\;l32i.n\\t%0, %1\";
984             case 4: return \"%v1l32i\\t%D0, %N1\;l32i\\t%0, %1\";
985             }
986         }
987       else
988         {
989           switch (which_alternative)
990             {
991             case 1: return \"%v1l32i.n\\t%0, %1\;l32i.n\\t%D0, %N1\";
992             case 4: return \"%v1l32i\\t%0, %1\;l32i\\t%D0, %N1\";
993             }
994         }
995     }
996   abort ();
997   return \"\";
999   [(set_attr "type"     "move,load,store,move,load,store")
1000    (set_attr "mode"     "DI")
1001    (set_attr "length"   "4,4,4,6,6,6")])
1004 ;; 32-bit Integer moves
1006 (define_expand "movsi"
1007   [(set (match_operand:SI 0 "nonimmed_operand" "")
1008         (match_operand:SI 1 "general_operand" ""))]
1009   ""
1010   "
1012   if (xtensa_emit_move_sequence (operands, SImode))
1013     DONE;
1016 (define_insn "movsi_internal"
1017   [(set (match_operand:SI 0 "nonimmed_operand" "=D,D,D,D,R,R,a,q,a,W,a,a,U,*a,*A")
1018         (match_operand:SI 1 "move_operand" "M,D,d,R,D,d,r,r,I,i,T,U,r,*A,*r"))]
1019   "xtensa_valid_move (SImode, operands)"
1020   "@
1021    movi.n\\t%0, %x1
1022    mov.n\\t%0, %1
1023    mov.n\\t%0, %1
1024    %v1l32i.n\\t%0, %1
1025    %v0s32i.n\\t%1, %0
1026    %v0s32i.n\\t%1, %0
1027    mov\\t%0, %1
1028    movsp\\t%0, %1
1029    movi\\t%0, %x1
1030    const16\\t%0, %t1\;const16\\t%0, %b1
1031    %v1l32r\\t%0, %1
1032    %v1l32i\\t%0, %1
1033    %v0s32i\\t%1, %0
1034    rsr\\t%0, 16 # ACCLO
1035    wsr\\t%1, 16 # ACCLO"
1036   [(set_attr "type" "move,move,move,load,store,store,move,move,move,move,load,load,store,rsr,wsr")
1037    (set_attr "mode"     "SI")
1038    (set_attr "length"   "2,2,2,2,2,2,3,3,3,6,3,3,3,3,3")])
1040 ;; 16-bit Integer moves
1042 (define_expand "movhi"
1043   [(set (match_operand:HI 0 "nonimmed_operand" "")
1044         (match_operand:HI 1 "general_operand" ""))]
1045   ""
1046   "
1048   if (xtensa_emit_move_sequence (operands, HImode))
1049     DONE;
1052 (define_insn "movhi_internal"
1053   [(set (match_operand:HI 0 "nonimmed_operand" "=D,D,a,a,a,U,*a,*A")
1054         (match_operand:HI 1 "move_operand" "M,d,r,I,U,r,*A,*r"))]
1055   "xtensa_valid_move (HImode, operands)"
1056   "@
1057    movi.n\\t%0, %x1
1058    mov.n\\t%0, %1
1059    mov\\t%0, %1
1060    movi\\t%0, %x1
1061    %v1l16ui\\t%0, %1
1062    %v0s16i\\t%1, %0
1063    rsr\\t%0, 16 # ACCLO
1064    wsr\\t%1, 16 # ACCLO"
1065   [(set_attr "type"     "move,move,move,move,load,store,rsr,wsr")
1066    (set_attr "mode"     "HI")
1067    (set_attr "length"   "2,2,3,3,3,3,3,3")])
1069 ;; 8-bit Integer moves
1071 (define_expand "movqi"
1072   [(set (match_operand:QI 0 "nonimmed_operand" "")
1073         (match_operand:QI 1 "general_operand" ""))]
1074   ""
1075   "
1077   if (xtensa_emit_move_sequence (operands, QImode))
1078     DONE;
1081 (define_insn "movqi_internal"
1082   [(set (match_operand:QI 0 "nonimmed_operand" "=D,D,a,a,a,U,*a,*A")
1083         (match_operand:QI 1 "move_operand" "M,d,r,I,U,r,*A,*r"))]
1084   "xtensa_valid_move (QImode, operands)"
1085   "@
1086    movi.n\\t%0, %x1
1087    mov.n\\t%0, %1
1088    mov\\t%0, %1
1089    movi\\t%0, %x1
1090    %v1l8ui\\t%0, %1
1091    %v0s8i\\t%1, %0
1092    rsr\\t%0, 16 # ACCLO
1093    wsr\\t%1, 16 # ACCLO"
1094   [(set_attr "type"     "move,move,move,move,load,store,rsr,wsr")
1095    (set_attr "mode"     "QI")
1096    (set_attr "length"   "2,2,3,3,3,3,3,3")])
1098 ;; 32-bit floating point moves
1100 (define_expand "movsf"
1101   [(set (match_operand:SF 0 "nonimmed_operand" "")
1102         (match_operand:SF 1 "general_operand" ""))]
1103   ""
1104   "
1106   if (!TARGET_CONST16 && CONSTANT_P (operands[1]))
1107     operands[1] = force_const_mem (SFmode, operands[1]);
1109   if (!(reload_in_progress | reload_completed))
1110     {
1111       if ((!register_operand (operands[0], SFmode)
1112            && !register_operand (operands[1], SFmode))
1113           || (FP_REG_P (xt_true_regnum (operands[0]))
1114               && (constantpool_mem_p (operands[1])
1115                   || CONSTANT_P (operands[1]))))
1116         operands[1] = force_reg (SFmode, operands[1]);
1118       if (xtensa_copy_incoming_a7 (operands, SFmode))
1119         DONE;
1120     }
1123 (define_insn "movsf_internal"
1124   [(set (match_operand:SF 0 "nonimmed_operand" "=f,f,U,D,D,R,a,f,a,W,a,a,U")
1125         (match_operand:SF 1 "move_operand" "f,U,f,d,R,d,r,r,f,F,T,U,r"))]
1126   "((register_operand (operands[0], SFmode)
1127      || register_operand (operands[1], SFmode))
1128     && !(FP_REG_P (xt_true_regnum (operands[0]))
1129          && (constantpool_mem_p (operands[1]) || CONSTANT_P (operands[1]))))"
1130   "@
1131    mov.s\\t%0, %1
1132    %v1lsi\\t%0, %1
1133    %v0ssi\\t%1, %0
1134    mov.n\\t%0, %1
1135    %v1l32i.n\\t%0, %1
1136    %v0s32i.n\\t%1, %0
1137    mov\\t%0, %1
1138    wfr\\t%0, %1
1139    rfr\\t%0, %1
1140    const16\\t%0, %t1\;const16\\t%0, %b1
1141    %v1l32r\\t%0, %1
1142    %v1l32i\\t%0, %1
1143    %v0s32i\\t%1, %0"
1144   [(set_attr "type"     "farith,fload,fstore,move,load,store,move,farith,farith,move,load,load,store")
1145    (set_attr "mode"     "SF")
1146    (set_attr "length"   "3,3,3,2,2,2,3,3,3,6,3,3,3")])
1148 (define_insn "*lsiu"
1149   [(set (match_operand:SF 0 "register_operand" "=f")
1150         (mem:SF (plus:SI (match_operand:SI 1 "register_operand" "+a")
1151                          (match_operand:SI 2 "fpmem_offset_operand" "i"))))
1152    (set (match_dup 1)
1153         (plus:SI (match_dup 1) (match_dup 2)))]
1154   "TARGET_HARD_FLOAT"
1155   "*
1157   if (TARGET_SERIALIZE_VOLATILE && volatile_refs_p (PATTERN (insn)))
1158     output_asm_insn (\"memw\", operands);
1159   return \"lsiu\\t%0, %1, %2\";
1161   [(set_attr "type"     "fload")
1162    (set_attr "mode"     "SF")
1163    (set_attr "length"   "3")])
1165 (define_insn "*ssiu"
1166   [(set (mem:SF (plus:SI (match_operand:SI 0 "register_operand" "+a")
1167                          (match_operand:SI 1 "fpmem_offset_operand" "i")))
1168         (match_operand:SF 2 "register_operand" "f"))
1169    (set (match_dup 0)
1170         (plus:SI (match_dup 0) (match_dup 1)))]
1171   "TARGET_HARD_FLOAT"
1172   "*
1174   if (TARGET_SERIALIZE_VOLATILE && volatile_refs_p (PATTERN (insn)))
1175     output_asm_insn (\"memw\", operands);
1176   return \"ssiu\\t%2, %0, %1\";
1178   [(set_attr "type"     "fstore")
1179    (set_attr "mode"     "SF")
1180    (set_attr "length"   "3")])
1182 ;; 64-bit floating point moves
1184 (define_expand "movdf"
1185   [(set (match_operand:DF 0 "nonimmed_operand" "")
1186         (match_operand:DF 1 "general_operand" ""))]
1187   ""
1188   "
1190   if (CONSTANT_P (operands[1]))
1191     {
1192       rtx src0, src1, dst0, dst1;
1193       dst0 = operand_subword (operands[0], 0, 1, DFmode);
1194       src0 = operand_subword (operands[1], 0, 1, DFmode);
1195       dst1 = operand_subword (operands[0], 1, 1, DFmode);
1196       src1 = operand_subword (operands[1], 1, 1, DFmode);
1197       if (!dst0 || !src0 || !dst1 || !src1)
1198         abort ();
1199       emit_insn (gen_movsi (dst0, src0));
1200       emit_insn (gen_movsi (dst1, src1));
1201       DONE;
1202     }
1204   if (!(reload_in_progress | reload_completed))
1205     {
1206       if (!register_operand (operands[0], DFmode)
1207           && !register_operand (operands[1], DFmode))
1208         operands[1] = force_reg (DFmode, operands[1]);
1210       if (xtensa_copy_incoming_a7 (operands, DFmode))
1211         DONE;
1212     }
1215 (define_insn "movdf_internal"
1216   [(set (match_operand:DF 0 "nonimmed_operand" "=D,D,S,a,a,U")
1217         (match_operand:DF 1 "nonimmed_operand" "d,S,d,r,U,r"))]
1218   "register_operand (operands[0], DFmode)
1219    || register_operand (operands[1], DFmode)"
1220   "*
1222   rtx dstreg;
1223   switch (which_alternative)
1224     {
1225     case 0: return \"mov.n\\t%0, %1\;mov.n\\t%D0, %D1\";
1226     case 2: return \"%v0s32i.n\\t%1, %0\;s32i.n\\t%D1, %N0\";
1227     case 3: return \"mov\\t%0, %1\;mov\\t%D0, %D1\";
1228     case 5: return \"%v0s32i\\t%1, %0\;s32i\\t%D1, %N0\";
1230     case 1:
1231     case 4:
1232       /* Check if the first half of the destination register is used
1233          in the source address.  If so, reverse the order of the loads
1234          so that the source address doesn't get clobbered until it is
1235          no longer needed.  */
1237       dstreg = operands[0];
1238       if (GET_CODE (dstreg) == SUBREG)
1239         dstreg = SUBREG_REG (dstreg);
1240       if (GET_CODE (dstreg) != REG)
1241         abort ();
1243       if (reg_mentioned_p (dstreg, operands[1]))
1244         {
1245           switch (which_alternative)
1246             {
1247             case 1: return \"%v1l32i.n\\t%D0, %N1\;l32i.n\\t%0, %1\";
1248             case 4: return \"%v1l32i\\t%D0, %N1\;l32i\\t%0, %1\";
1249             }
1250         }
1251       else
1252         {
1253           switch (which_alternative)
1254             {
1255             case 1: return \"%v1l32i.n\\t%0, %1\;l32i.n\\t%D0, %N1\";
1256             case 4: return \"%v1l32i\\t%0, %1\;l32i\\t%D0, %N1\";
1257             }
1258         }
1259     }
1260   abort ();
1261   return \"\";
1263   [(set_attr "type"     "move,load,store,move,load,store")
1264    (set_attr "mode"     "DF")
1265    (set_attr "length"   "4,4,4,6,6,6")])
1267 ;; Block moves
1269 (define_expand "movstrsi"
1270   [(parallel [(set (match_operand:BLK 0 "" "")
1271                    (match_operand:BLK 1 "" ""))
1272               (use (match_operand:SI 2 "arith_operand" ""))
1273               (use (match_operand:SI 3 "const_int_operand" ""))])]
1274   ""
1275   "
1277   if (!xtensa_expand_block_move (operands)) FAIL;
1278   DONE;
1281 (define_insn "movstrsi_internal"
1282   [(set (match_operand:BLK 0 "memory_operand" "=U")
1283         (match_operand:BLK 1 "memory_operand" "U"))
1284    (use (match_operand:SI 2 "arith_operand" ""))
1285    (use (match_operand:SI 3 "const_int_operand" ""))
1286    (clobber (match_scratch:SI 4 "=&r"))
1287    (clobber (match_scratch:SI 5 "=&r"))]
1288   ""
1289   "*
1291   rtx tmpregs[2];
1292   tmpregs[0] = operands[4];
1293   tmpregs[1] = operands[5];
1294   xtensa_emit_block_move (operands, tmpregs, 1);
1295   return \"\";
1297   [(set_attr "type"     "multi")
1298    (set_attr "mode"     "none")
1299    (set_attr "length"   "300")])
1303 ;;  ....................
1305 ;;      SHIFTS
1307 ;;  ....................
1310 (define_insn "ashlsi3"
1311   [(set (match_operand:SI 0 "register_operand" "=a,a")
1312         (ashift:SI (match_operand:SI 1 "register_operand" "r,r")
1313                    (match_operand:SI 2 "arith_operand" "J,r")))]
1314   ""      
1315   "@
1316    slli\\t%0, %1, %R2
1317    ssl\\t%2\;sll\\t%0, %1"
1318   [(set_attr "type"     "arith,arith")
1319    (set_attr "mode"     "SI")
1320    (set_attr "length"   "3,6")])
1322 (define_insn "ashrsi3"
1323   [(set (match_operand:SI 0 "register_operand" "=a,a")
1324         (ashiftrt:SI (match_operand:SI 1 "register_operand" "r,r")
1325                      (match_operand:SI 2 "arith_operand" "J,r")))]
1326   ""
1327   "@
1328    srai\\t%0, %1, %R2
1329    ssr\\t%2\;sra\\t%0, %1"
1330   [(set_attr "type"     "arith,arith")
1331    (set_attr "mode"     "SI")
1332    (set_attr "length"   "3,6")])
1334 (define_insn "lshrsi3"
1335   [(set (match_operand:SI 0 "register_operand" "=a,a")
1336         (lshiftrt:SI (match_operand:SI 1 "register_operand" "r,r")
1337                      (match_operand:SI 2 "arith_operand" "J,r")))]
1338   ""
1339   "*
1341   if (which_alternative == 0)
1342     {
1343       if ((INTVAL (operands[2]) & 0x1f) < 16)
1344         return \"srli\\t%0, %1, %R2\";
1345       else
1346         return \"extui\\t%0, %1, %R2, %L2\";
1347     }
1348   return \"ssr\\t%2\;srl\\t%0, %1\";
1350   [(set_attr "type"     "arith,arith")
1351    (set_attr "mode"     "SI")
1352    (set_attr "length"   "3,6")])
1354 (define_insn "rotlsi3"
1355   [(set (match_operand:SI 0 "register_operand" "=a,a")
1356         (rotate:SI (match_operand:SI 1 "register_operand" "r,r")
1357                      (match_operand:SI 2 "arith_operand" "J,r")))]
1358   ""
1359   "@
1360    ssai\\t%L2\;src\\t%0, %1, %1
1361    ssl\\t%2\;src\\t%0, %1, %1"
1362   [(set_attr "type"     "multi,multi")
1363    (set_attr "mode"     "SI")
1364    (set_attr "length"   "6,6")])
1366 (define_insn "rotrsi3"
1367   [(set (match_operand:SI 0 "register_operand" "=a,a")
1368         (rotatert:SI (match_operand:SI 1 "register_operand" "r,r")
1369                      (match_operand:SI 2 "arith_operand" "J,r")))]
1370   ""
1371   "@
1372    ssai\\t%R2\;src\\t%0, %1, %1
1373    ssr\\t%2\;src\\t%0, %1, %1"
1374   [(set_attr "type"     "multi,multi")
1375    (set_attr "mode"     "SI")
1376    (set_attr "length"   "6,6")])
1380 ;;  ....................
1382 ;;      COMPARISONS
1384 ;;  ....................
1387 ;; Like the md files for MIPS and SPARC, we handle comparisons by stashing
1388 ;; away the operands and then using that information in the subsequent
1389 ;; conditional branch.
1391 (define_expand "cmpsi"
1392   [(set (cc0)
1393         (compare:CC (match_operand:SI 0 "register_operand" "")
1394                     (match_operand:SI 1 "nonmemory_operand" "")))]
1395   ""
1396   "
1398   branch_cmp[0] = operands[0];
1399   branch_cmp[1] = operands[1];
1400   branch_type = CMP_SI;
1401   DONE;
1404 (define_expand "tstsi"
1405   [(set (cc0)
1406         (match_operand:SI 0 "register_operand" ""))]
1407   ""
1408   "
1410   branch_cmp[0] = operands[0];
1411   branch_cmp[1] = const0_rtx;
1412   branch_type = CMP_SI;
1413   DONE;
1416 (define_expand "cmpsf"
1417   [(set (cc0)
1418         (compare:CC (match_operand:SF 0 "register_operand" "")
1419                     (match_operand:SF 1 "register_operand" "")))]
1420   "TARGET_HARD_FLOAT"
1421   "
1423   branch_cmp[0] = operands[0];
1424   branch_cmp[1] = operands[1];
1425   branch_type = CMP_SF;
1426   DONE;
1431 ;;  ....................
1433 ;;      CONDITIONAL BRANCHES
1435 ;;  ....................
1438 (define_expand "beq"
1439   [(set (pc)
1440         (if_then_else (eq (cc0) (const_int 0))
1441                       (label_ref (match_operand 0 "" ""))
1442                       (pc)))]
1443   ""
1444   "
1446   xtensa_expand_conditional_branch (operands, EQ);
1447   DONE;
1450 (define_expand "bne"
1451   [(set (pc)
1452         (if_then_else (ne (cc0) (const_int 0))
1453                       (label_ref (match_operand 0 "" ""))
1454                       (pc)))]
1455   ""
1456   "
1458   xtensa_expand_conditional_branch (operands, NE);
1459   DONE;
1462 (define_expand "bgt"
1463   [(set (pc)
1464         (if_then_else (gt (cc0) (const_int 0))
1465                       (label_ref (match_operand 0 "" ""))
1466                       (pc)))]
1467   ""
1468   "
1470   xtensa_expand_conditional_branch (operands, GT);
1471   DONE;
1474 (define_expand "bge"
1475   [(set (pc)
1476         (if_then_else (ge (cc0) (const_int 0))
1477                       (label_ref (match_operand 0 "" ""))
1478                       (pc)))]
1479   ""
1480   "
1482   xtensa_expand_conditional_branch (operands, GE);
1483   DONE;
1486 (define_expand "blt"
1487   [(set (pc)
1488         (if_then_else (lt (cc0) (const_int 0))
1489                       (label_ref (match_operand 0 "" ""))
1490                       (pc)))]
1491   ""
1492   "
1494   xtensa_expand_conditional_branch (operands, LT);
1495   DONE;
1498 (define_expand "ble"
1499   [(set (pc)
1500         (if_then_else (le (cc0) (const_int 0))
1501                       (label_ref (match_operand 0 "" ""))
1502                       (pc)))]
1503   ""
1504   "
1506   xtensa_expand_conditional_branch (operands, LE);
1507   DONE;
1510 (define_expand "bgtu"
1511   [(set (pc)
1512         (if_then_else (gtu (cc0) (const_int 0))
1513                       (label_ref (match_operand 0 "" ""))
1514                       (pc)))]
1515   ""
1516   "
1518   xtensa_expand_conditional_branch (operands, GTU);
1519   DONE;
1522 (define_expand "bgeu"
1523   [(set (pc)
1524         (if_then_else (geu (cc0) (const_int 0))
1525                       (label_ref (match_operand 0 "" ""))
1526                       (pc)))]
1527   ""
1528   "
1530   xtensa_expand_conditional_branch (operands, GEU);
1531   DONE;
1534 (define_expand "bltu"
1535   [(set (pc)
1536         (if_then_else (ltu (cc0) (const_int 0))
1537                       (label_ref (match_operand 0 "" ""))
1538                       (pc)))]
1539   ""
1540   "
1542   xtensa_expand_conditional_branch (operands, LTU);
1543   DONE;
1546 (define_expand "bleu"
1547   [(set (pc)
1548         (if_then_else (leu (cc0) (const_int 0))
1549                       (label_ref (match_operand 0 "" ""))
1550                       (pc)))]
1551   ""
1552   "
1554   xtensa_expand_conditional_branch (operands, LEU);
1555   DONE;
1558 ;; Branch patterns for standard integer comparisons
1560 (define_insn "*btrue"
1561   [(set (pc)
1562         (if_then_else (match_operator 3 "branch_operator"
1563                          [(match_operand:SI 0 "register_operand" "r,r")
1564                           (match_operand:SI 1 "branch_operand" "K,r")])
1565                       (label_ref (match_operand 2 "" ""))
1566                       (pc)))]
1567   ""
1568   "*
1570   if (which_alternative == 1)
1571     {
1572       switch (GET_CODE (operands[3]))
1573         {
1574         case EQ:        return \"beq\\t%0, %1, %2\";
1575         case NE:        return \"bne\\t%0, %1, %2\";
1576         case LT:        return \"blt\\t%0, %1, %2\";
1577         case GE:        return \"bge\\t%0, %1, %2\";
1578         default:        break;
1579         }
1580     }
1581   else if (INTVAL (operands[1]) == 0)
1582     {
1583       switch (GET_CODE (operands[3]))
1584         {
1585         case EQ:        return (TARGET_DENSITY
1586                                 ? \"beqz.n\\t%0, %2\"
1587                                 : \"beqz\\t%0, %2\");
1588         case NE:        return (TARGET_DENSITY
1589                                 ? \"bnez.n\\t%0, %2\"
1590                                 : \"bnez\\t%0, %2\");
1591         case LT:        return \"bltz\\t%0, %2\";
1592         case GE:        return \"bgez\\t%0, %2\";
1593         default:        break;
1594         }
1595     }
1596   else
1597     {
1598       switch (GET_CODE (operands[3]))
1599         {
1600         case EQ:        return \"beqi\\t%0, %d1, %2\";
1601         case NE:        return \"bnei\\t%0, %d1, %2\";
1602         case LT:        return \"blti\\t%0, %d1, %2\";
1603         case GE:        return \"bgei\\t%0, %d1, %2\";
1604         default:        break;
1605         }
1606     }
1607   fatal_insn (\"unexpected branch operator\", operands[3]);
1608   return \"\";
1610   [(set_attr "type"     "jump,jump")
1611    (set_attr "mode"     "none")
1612    (set_attr "length"   "3,3")])
1614 (define_insn "*bfalse"
1615   [(set (pc)
1616         (if_then_else (match_operator 3 "branch_operator"
1617                          [(match_operand:SI 0 "register_operand" "r,r")
1618                           (match_operand:SI 1 "branch_operand" "K,r")])
1619                       (pc)
1620                       (label_ref (match_operand 2 "" ""))))]
1621   ""
1622   "*
1624   if (which_alternative == 1)
1625     {
1626       switch (GET_CODE (operands[3]))
1627         {
1628         case EQ:        return \"bne\\t%0, %1, %2\";
1629         case NE:        return \"beq\\t%0, %1, %2\";
1630         case LT:        return \"bge\\t%0, %1, %2\";
1631         case GE:        return \"blt\\t%0, %1, %2\";
1632         default:        break;
1633         }
1634     }
1635   else if (INTVAL (operands[1]) == 0)
1636     {
1637       switch (GET_CODE (operands[3]))
1638         {
1639         case EQ:        return (TARGET_DENSITY
1640                                 ? \"bnez.n\\t%0, %2\"
1641                                 : \"bnez\\t%0, %2\");
1642         case NE:        return (TARGET_DENSITY
1643                                 ? \"beqz.n\\t%0, %2\"
1644                                 : \"beqz\\t%0, %2\");
1645         case LT:        return \"bgez\\t%0, %2\";
1646         case GE:        return \"bltz\\t%0, %2\";
1647         default:        break;
1648         }
1649     }
1650   else
1651     {
1652       switch (GET_CODE (operands[3]))
1653         {
1654         case EQ:        return \"bnei\\t%0, %d1, %2\";
1655         case NE:        return \"beqi\\t%0, %d1, %2\";
1656         case LT:        return \"bgei\\t%0, %d1, %2\";
1657         case GE:        return \"blti\\t%0, %d1, %2\";
1658         default:        break;
1659         }
1660     }
1661   fatal_insn (\"unexpected branch operator\", operands[3]);
1662   return \"\";
1664   [(set_attr "type"     "jump,jump")
1665    (set_attr "mode"     "none")
1666    (set_attr "length"   "3,3")])
1668 (define_insn "*ubtrue"
1669   [(set (pc)
1670         (if_then_else (match_operator 3 "ubranch_operator"
1671                          [(match_operand:SI 0 "register_operand" "r,r")
1672                           (match_operand:SI 1 "ubranch_operand" "L,r")])
1673                       (label_ref (match_operand 2 "" ""))
1674                       (pc)))]
1675   ""
1676   "*
1678   if (which_alternative == 1)
1679     {
1680       switch (GET_CODE (operands[3]))
1681         {
1682         case LTU:       return \"bltu\\t%0, %1, %2\";
1683         case GEU:       return \"bgeu\\t%0, %1, %2\";
1684         default:        break;
1685         }
1686     }
1687   else
1688     {
1689       switch (GET_CODE (operands[3]))
1690         {
1691         case LTU:       return \"bltui\\t%0, %d1, %2\";
1692         case GEU:       return \"bgeui\\t%0, %d1, %2\";
1693         default:        break;
1694         }
1695     }
1696   fatal_insn (\"unexpected branch operator\", operands[3]);
1697   return \"\";
1699   [(set_attr "type"     "jump,jump")
1700    (set_attr "mode"     "none")
1701    (set_attr "length"   "3,3")])
1703 (define_insn "*ubfalse"
1704   [(set (pc)
1705         (if_then_else (match_operator 3 "ubranch_operator"
1706                          [(match_operand:SI 0 "register_operand" "r,r")
1707                           (match_operand:SI 1 "ubranch_operand" "L,r")])
1708                       (pc)
1709                       (label_ref (match_operand 2 "" ""))))]
1710   ""
1711   "*
1713   if (which_alternative == 1)
1714     {
1715       switch (GET_CODE (operands[3]))
1716         {
1717         case LTU:       return \"bgeu\\t%0, %1, %2\";
1718         case GEU:       return \"bltu\\t%0, %1, %2\";
1719         default:        break;
1720         }
1721     }
1722   else
1723     {
1724       switch (GET_CODE (operands[3]))
1725         {
1726         case LTU:       return \"bgeui\\t%0, %d1, %2\";
1727         case GEU:       return \"bltui\\t%0, %d1, %2\";
1728         default:        break;
1729         }
1730     }
1731   fatal_insn (\"unexpected branch operator\", operands[3]);
1732   return \"\";
1734   [(set_attr "type"     "jump,jump")
1735    (set_attr "mode"     "none")
1736    (set_attr "length"   "3,3")])
1738 ;; Branch patterns for bit testing
1740 (define_insn "*bittrue"
1741   [(set (pc)
1742         (if_then_else (match_operator 3 "boolean_operator"
1743                         [(zero_extract:SI
1744                             (match_operand:SI 0 "register_operand" "r,r")
1745                             (const_int 1)
1746                             (match_operand:SI 1 "arith_operand" "J,r"))
1747                          (const_int 0)])
1748                       (label_ref (match_operand 2 "" ""))
1749                       (pc)))]
1750   ""
1751   "*
1753   if (which_alternative == 0)
1754     {
1755       unsigned bitnum = INTVAL(operands[1]) & 0x1f;
1756       operands[1] = GEN_INT(bitnum);
1757       switch (GET_CODE (operands[3]))
1758         {
1759         case EQ:        return \"bbci\\t%0, %d1, %2\";
1760         case NE:        return \"bbsi\\t%0, %d1, %2\";
1761         default:        break;
1762         }
1763     }
1764   else
1765     {
1766       switch (GET_CODE (operands[3]))
1767         {
1768         case EQ:        return \"bbc\\t%0, %1, %2\";
1769         case NE:        return \"bbs\\t%0, %1, %2\";
1770         default:        break;
1771         }
1772     }
1773   fatal_insn (\"unexpected branch operator\", operands[3]);
1774   return \"\";
1776   [(set_attr "type"     "jump")
1777    (set_attr "mode"     "none")
1778    (set_attr "length"   "3")])
1780 (define_insn "*bitfalse"
1781   [(set (pc)
1782         (if_then_else (match_operator 3 "boolean_operator"
1783                         [(zero_extract:SI
1784                             (match_operand:SI 0 "register_operand" "r,r")
1785                             (const_int 1)
1786                             (match_operand:SI 1 "arith_operand" "J,r"))
1787                          (const_int 0)])
1788                       (pc)
1789                       (label_ref (match_operand 2 "" ""))))]
1790   ""
1791   "*
1793   if (which_alternative == 0)
1794     {
1795       unsigned bitnum = INTVAL (operands[1]) & 0x1f;
1796       operands[1] = GEN_INT (bitnum);
1797       switch (GET_CODE (operands[3]))
1798         {
1799         case EQ:    return \"bbsi\\t%0, %d1, %2\";
1800         case NE:    return \"bbci\\t%0, %d1, %2\";
1801         default:    break;
1802         }
1803     }
1804   else
1805     {
1806       switch (GET_CODE (operands[3]))
1807         {
1808         case EQ:        return \"bbs\\t%0, %1, %2\";
1809         case NE:        return \"bbc\\t%0, %1, %2\";
1810         default:        break;
1811         }
1812     }
1813   fatal_insn (\"unexpected branch operator\", operands[3]);
1814   return \"\";
1816   [(set_attr "type"     "jump")
1817    (set_attr "mode"     "none")
1818    (set_attr "length"   "3")])
1820 (define_insn "*masktrue"
1821   [(set (pc)
1822         (if_then_else (match_operator 3 "boolean_operator"
1823                  [(and:SI (match_operand:SI 0 "register_operand" "r")
1824                           (match_operand:SI 1 "register_operand" "r"))
1825                   (const_int 0)])
1826                       (label_ref (match_operand 2 "" ""))
1827                       (pc)))]
1828   ""
1829   "*
1831   switch (GET_CODE (operands[3]))
1832     {
1833     case EQ:    return \"bnone\\t%0, %1, %2\";
1834     case NE:    return \"bany\\t%0, %1, %2\";
1835     default:    break;
1836     }
1837   fatal_insn (\"unexpected branch operator\", operands[3]);
1838   return \"\";
1840   [(set_attr "type"     "jump")
1841    (set_attr "mode"     "none")
1842    (set_attr "length"   "3")])
1844 (define_insn "*maskfalse"
1845   [(set (pc)
1846         (if_then_else (match_operator 3 "boolean_operator"
1847                  [(and:SI (match_operand:SI 0 "register_operand" "r")
1848                           (match_operand:SI 1 "register_operand" "r"))
1849                   (const_int 0)])
1850                       (pc)
1851                       (label_ref (match_operand 2 "" ""))))]
1852   ""
1853   "*
1855   switch (GET_CODE (operands[3]))
1856     {
1857     case EQ:    return \"bany\\t%0, %1, %2\";
1858     case NE:    return \"bnone\\t%0, %1, %2\";
1859     default:    break;
1860     }
1861   fatal_insn (\"unexpected branch operator\", operands[3]);
1862   return \"\";
1864   [(set_attr "type"     "jump")
1865    (set_attr "mode"     "none")
1866    (set_attr "length"   "3")])
1869 ;; Define the loop insns that is used by bct optimization to represent the
1870 ;; start and end of a zero-overhead loop (in loop.c). This start template
1871 ;; generates the loop insn, the end template doesn't generate any instructions
1872 ;; since since loop end is handled in hardware.
1874 (define_insn "zero_cost_loop_start"
1875   [(set (pc) (if_then_else (eq (match_operand:SI 0 "register_operand" "a")
1876                                (const_int 0))
1877                            (label_ref (match_operand 1 "" ""))
1878                            (pc)))
1879    (set (reg:SI 19)
1880         (plus:SI (match_dup 0) (const_int -1)))]
1881   ""
1882   "loopnez %0, %l1"
1883   [(set_attr "type"     "jump")
1884    (set_attr "mode"     "none")
1885    (set_attr "length"   "3")])
1887 (define_insn "zero_cost_loop_end"
1888   [(set (pc) (if_then_else (ne (reg:SI 19) (const_int 0))
1889                            (label_ref (match_operand 0 "" ""))
1890                            (pc)))
1891    (set (reg:SI 19)
1892         (plus:SI (reg:SI 19) (const_int -1)))]
1893   ""
1894   "*
1895     xtensa_emit_loop_end (insn, operands);
1896     return \"\";
1897   "
1898   [(set_attr "type"     "jump")
1899    (set_attr "mode"     "none")
1900    (set_attr "length"   "0")])
1904 ;;  ....................
1906 ;;      SETTING A REGISTER FROM A COMPARISON
1908 ;;  ....................
1911 (define_expand "seq"
1912   [(set (match_operand:SI 0 "register_operand" "")
1913         (match_dup 1))]
1914   ""
1915   "
1917   operands[1] = gen_rtx (EQ, SImode, branch_cmp[0], branch_cmp[1]);
1918   if (!xtensa_expand_scc (operands)) FAIL;
1919   DONE;
1922 (define_expand "sne"
1923   [(set (match_operand:SI 0 "register_operand" "")
1924         (match_dup 1))]
1925   ""
1926   "
1928   operands[1] = gen_rtx (NE, SImode, branch_cmp[0], branch_cmp[1]);
1929   if (!xtensa_expand_scc (operands)) FAIL;
1930   DONE;
1933 (define_expand "sgt"
1934   [(set (match_operand:SI 0 "register_operand" "")
1935         (match_dup 1))]
1936   ""
1937   "
1939   operands[1] = gen_rtx (GT, SImode, branch_cmp[0], branch_cmp[1]);
1940   if (!xtensa_expand_scc (operands)) FAIL;
1941   DONE;
1944 (define_expand "sge"
1945   [(set (match_operand:SI 0 "register_operand" "")
1946         (match_dup 1))]
1947   ""
1948   "
1950   operands[1] = gen_rtx (GE, SImode, branch_cmp[0], branch_cmp[1]);
1951   if (!xtensa_expand_scc (operands)) FAIL;
1952   DONE;
1955 (define_expand "slt"
1956   [(set (match_operand:SI 0 "register_operand" "")
1957         (match_dup 1))]
1958   ""
1959   "
1961   operands[1] = gen_rtx (LT, SImode, branch_cmp[0], branch_cmp[1]);
1962   if (!xtensa_expand_scc (operands)) FAIL;
1963   DONE;
1966 (define_expand "sle"
1967   [(set (match_operand:SI 0 "register_operand" "")
1968         (match_dup 1))]
1969   ""
1970   "
1972   operands[1] = gen_rtx (LE, SImode, branch_cmp[0], branch_cmp[1]);
1973   if (!xtensa_expand_scc (operands)) FAIL;
1974   DONE;
1979 ;;  ....................
1981 ;;      CONDITIONAL MOVES
1983 ;;  ....................
1986 (define_expand "movsicc"
1987   [(set (match_operand:SI 0 "register_operand" "")
1988         (if_then_else:SI (match_operand 1 "comparison_operator" "")
1989                          (match_operand:SI 2 "register_operand" "")
1990                          (match_operand:SI 3 "register_operand" "")))]
1991   ""
1992   "
1994   if (!xtensa_expand_conditional_move (operands, 0)) FAIL;
1995   DONE;
1998 (define_expand "movsfcc"
1999   [(set (match_operand:SF 0 "register_operand" "")
2000         (if_then_else:SF (match_operand 1 "comparison_operator" "")
2001                          (match_operand:SF 2 "register_operand" "")
2002                          (match_operand:SF 3 "register_operand" "")))]
2003   ""
2004   "
2006   if (!xtensa_expand_conditional_move (operands, 1)) FAIL;
2007   DONE;
2010 (define_insn "movsicc_internal0"
2011   [(set (match_operand:SI 0 "register_operand" "=a,a")
2012         (if_then_else:SI (match_operator 4 "branch_operator"
2013                            [(match_operand:SI 1 "register_operand" "r,r")
2014                             (const_int 0)])
2015                          (match_operand:SI 2 "register_operand" "r,0")
2016                          (match_operand:SI 3 "register_operand" "0,r")))]
2017   ""
2018   "*
2020   if (which_alternative == 0)
2021     {
2022       switch (GET_CODE (operands[4]))
2023         {
2024         case EQ:        return \"moveqz\\t%0, %2, %1\";
2025         case NE:        return \"movnez\\t%0, %2, %1\";
2026         case LT:        return \"movltz\\t%0, %2, %1\";
2027         case GE:        return \"movgez\\t%0, %2, %1\";
2028         default:        break;
2029         }
2030     }
2031   else
2032     {
2033       switch (GET_CODE (operands[4]))
2034         {
2035         case EQ:        return \"movnez\\t%0, %3, %1\";
2036         case NE:        return \"moveqz\\t%0, %3, %1\";
2037         case LT:        return \"movgez\\t%0, %3, %1\";
2038         case GE:        return \"movltz\\t%0, %3, %1\";
2039         default:        break;
2040         }
2041     }
2042   fatal_insn (\"unexpected cmov operator\", operands[4]);
2043   return \"\";
2045   [(set_attr "type"     "move,move")
2046    (set_attr "mode"     "SI")
2047    (set_attr "length"   "3,3")])
2049 (define_insn "movsicc_internal1"
2050   [(set (match_operand:SI 0 "register_operand" "=a,a")
2051         (if_then_else:SI (match_operator 4 "boolean_operator"
2052                            [(match_operand:CC 1 "register_operand" "b,b")
2053                             (const_int 0)])
2054                          (match_operand:SI 2 "register_operand" "r,0")
2055                          (match_operand:SI 3 "register_operand" "0,r")))]
2056   "TARGET_BOOLEANS"
2057   "*
2059   int isEq = (GET_CODE (operands[4]) == EQ);
2060   switch (which_alternative)
2061     {
2062     case 0:
2063       if (isEq) return \"movf\\t%0, %2, %1\";
2064       return \"movt\\t%0, %2, %1\";
2065     case 1:
2066       if (isEq) return \"movt\\t%0, %3, %1\";
2067       return \"movf\\t%0, %3, %1\";
2068     }
2069   abort ();
2070   return \"\";
2072   [(set_attr "type"     "move,move")
2073    (set_attr "mode"     "SI")
2074    (set_attr "length"   "3,3")])
2076 (define_insn "movsfcc_internal0"
2077   [(set (match_operand:SF 0 "register_operand" "=a,a,f,f")
2078         (if_then_else:SF (match_operator 4 "branch_operator"
2079                            [(match_operand:SI 1 "register_operand" "r,r,r,r")
2080                             (const_int 0)])
2081                          (match_operand:SF 2 "register_operand" "r,0,f,0")
2082                          (match_operand:SF 3 "register_operand" "0,r,0,f")))]
2083   ""
2084   "*
2086   if (which_alternative == 0)
2087     {
2088       switch (GET_CODE (operands[4]))
2089         {
2090         case EQ:        return \"moveqz\\t%0, %2, %1\";
2091         case NE:        return \"movnez\\t%0, %2, %1\";
2092         case LT:        return \"movltz\\t%0, %2, %1\";
2093         case GE:        return \"movgez\\t%0, %2, %1\";
2094         default:        break;
2095         }
2096     }
2097   else if (which_alternative == 1)
2098     {
2099       switch (GET_CODE (operands[4]))
2100         {
2101         case EQ:        return \"movnez\\t%0, %3, %1\";
2102         case NE:        return \"moveqz\\t%0, %3, %1\";
2103         case LT:        return \"movgez\\t%0, %3, %1\";
2104         case GE:        return \"movltz\\t%0, %3, %1\";
2105         default:        break;
2106         }
2107     }
2108   else if (which_alternative == 2)
2109     {
2110       switch (GET_CODE (operands[4]))
2111         {
2112         case EQ:        return \"moveqz.s %0, %2, %1\";
2113         case NE:        return \"movnez.s %0, %2, %1\";
2114         case LT:        return \"movltz.s %0, %2, %1\";
2115         case GE:        return \"movgez.s %0, %2, %1\";
2116         default:        break;
2117         }
2118     }
2119   else if (which_alternative == 3)
2120     {
2121       switch (GET_CODE (operands[4]))
2122         {
2123         case EQ:        return \"movnez.s %0, %3, %1\";
2124         case NE:        return \"moveqz.s %0, %3, %1\";
2125         case LT:        return \"movgez.s %0, %3, %1\";
2126         case GE:        return \"movltz.s %0, %3, %1\";
2127         default:        break;
2128         }
2129     }
2130   fatal_insn (\"unexpected cmov operator\", operands[4]);
2131   return \"\";
2133   [(set_attr "type"     "move,move,move,move")
2134    (set_attr "mode"     "SF")
2135    (set_attr "length"   "3,3,3,3")])
2137 (define_insn "movsfcc_internal1"
2138   [(set (match_operand:SF 0 "register_operand" "=a,a,f,f")
2139         (if_then_else:SF (match_operator 4 "boolean_operator"
2140                            [(match_operand:CC 1 "register_operand" "b,b,b,b")
2141                             (const_int 0)])
2142                          (match_operand:SF 2 "register_operand" "r,0,f,0")
2143                          (match_operand:SF 3 "register_operand" "0,r,0,f")))]
2144   "TARGET_BOOLEANS"
2145   "*
2147   int isEq = (GET_CODE (operands[4]) == EQ);
2148   switch (which_alternative)
2149     {
2150     case 0:
2151       if (isEq) return \"movf\\t%0, %2, %1\";
2152       return \"movt\\t%0, %2, %1\";
2153     case 1:
2154       if (isEq) return \"movt\\t%0, %3, %1\";
2155       return \"movf\\t%0, %3, %1\";
2156     case 2:
2157       if (isEq) return \"movf.s\\t%0, %2, %1\";
2158       return \"movt.s\\t%0, %2, %1\";
2159     case 3:
2160       if (isEq) return \"movt.s\\t%0, %3, %1\";
2161       return \"movf.s\\t%0, %3, %1\";
2162     }
2163   abort ();
2164   return \"\";
2166   [(set_attr "type"     "move,move,move,move")
2167    (set_attr "mode"     "SF")
2168    (set_attr "length"   "3,3,3,3")])
2172 ;;  ....................
2174 ;;      FLOATING POINT COMPARISONS
2176 ;;  ....................
2179 (define_insn "seq_sf"
2180   [(set (match_operand:CC 0 "register_operand" "=b")
2181         (eq:CC (match_operand:SF 1 "register_operand" "f")
2182                (match_operand:SF 2 "register_operand" "f")))]
2183   "TARGET_HARD_FLOAT"
2184   "oeq.s\\t%0, %1, %2"
2185   [(set_attr "type"     "farith")
2186    (set_attr "mode"     "BL")
2187    (set_attr "length"   "3")])
2189 (define_insn "slt_sf"
2190   [(set (match_operand:CC 0 "register_operand" "=b")
2191         (lt:CC (match_operand:SF 1 "register_operand" "f")
2192                (match_operand:SF 2 "register_operand" "f")))]
2193   "TARGET_HARD_FLOAT"
2194   "olt.s\\t%0, %1, %2"
2195   [(set_attr "type"     "farith")
2196    (set_attr "mode"     "BL")
2197    (set_attr "length"   "3")])
2199 (define_insn "sle_sf"
2200   [(set (match_operand:CC 0 "register_operand" "=b")
2201         (le:CC (match_operand:SF 1 "register_operand" "f")
2202                (match_operand:SF 2 "register_operand" "f")))]
2203   "TARGET_HARD_FLOAT"
2204   "ole.s\\t%0, %1, %2"
2205   [(set_attr "type"     "farith")
2206    (set_attr "mode"     "BL")
2207    (set_attr "length"   "3")])
2211 ;;  ....................
2213 ;;      UNCONDITIONAL BRANCHES
2215 ;;  ....................
2218 (define_insn "jump"
2219   [(set (pc)
2220         (label_ref (match_operand 0 "" "")))]
2221   ""
2222   "j\\t%l0"
2223   [(set_attr "type"     "jump")
2224    (set_attr "mode"     "none")
2225    (set_attr "length"   "3")])
2227 (define_expand "indirect_jump"
2228   [(set (pc) (match_operand 0 "register_operand" ""))]
2229   ""
2230   "
2232   rtx dest = operands[0];
2233   if (GET_CODE (dest) != REG || GET_MODE (dest) != Pmode)
2234     operands[0] = copy_to_mode_reg (Pmode, dest);
2236   emit_jump_insn (gen_indirect_jump_internal (dest));
2237   DONE;
2240 (define_insn "indirect_jump_internal"
2241   [(set (pc) (match_operand:SI 0 "register_operand" "r"))]
2242   ""
2243   "jx\\t%0"
2244   [(set_attr "type"     "jump")
2245    (set_attr "mode"     "none")
2246    (set_attr "length"   "3")])
2249 (define_expand "tablejump"
2250   [(use (match_operand:SI 0 "register_operand" ""))
2251    (use (label_ref (match_operand 1 "" "")))]
2252    ""
2253    "
2255   rtx target = operands[0];
2256   if (flag_pic)
2257     {
2258       /* For PIC, the table entry is relative to the start of the table. */
2259       rtx label = gen_reg_rtx (SImode);
2260       target = gen_reg_rtx (SImode);
2261       emit_move_insn (label, gen_rtx_LABEL_REF (SImode, operands[1]));
2262       emit_insn (gen_addsi3 (target, operands[0], label));
2263     }
2264   emit_jump_insn (gen_tablejump_internal (target, operands[1]));
2265   DONE;
2268 (define_insn "tablejump_internal"
2269   [(set (pc)
2270         (match_operand:SI 0 "register_operand" "r"))
2271    (use (label_ref (match_operand 1 "" "")))]
2272   ""
2273   "jx\\t%0"
2274   [(set_attr "type"     "jump")
2275    (set_attr "mode"     "none")
2276    (set_attr "length"   "3")])
2280 ;;  ....................
2282 ;;      FUNCTION CALLS
2284 ;;  ....................
2287 (define_expand "sym_PLT"
2288   [(const (unspec [(match_operand:SI 0 "" "")] UNSPEC_PLT))]
2289   ""
2290   "")
2292 (define_expand "call"
2293   [(call (match_operand 0 "memory_operand" "")
2294          (match_operand 1 "" ""))]
2295   ""
2296   "
2298   rtx addr = XEXP (operands[0], 0);
2299   if (flag_pic && GET_CODE (addr) == SYMBOL_REF && !SYMBOL_REF_LOCAL_P (addr))
2300     addr = gen_sym_PLT (addr);
2301   if (!call_insn_operand (addr, VOIDmode))
2302     XEXP (operands[0], 0) = copy_to_mode_reg (Pmode, addr);
2305 (define_insn "call_internal"
2306   [(call (mem (match_operand:SI 0 "call_insn_operand" "n,i,r"))
2307          (match_operand 1 "" "i,i,i"))]
2308   ""
2309   "*
2310     return xtensa_emit_call (0, operands);
2311   "
2312   [(set_attr "type"     "call")
2313    (set_attr "mode"     "none")
2314    (set_attr "length"   "3")])
2316 (define_expand "call_value"
2317   [(set (match_operand 0 "register_operand" "")
2318         (call (match_operand 1 "memory_operand" "")
2319               (match_operand 2 "" "")))]
2320   ""
2321   "
2323   rtx addr = XEXP (operands[1], 0);
2324   if (flag_pic && GET_CODE (addr) == SYMBOL_REF && !SYMBOL_REF_LOCAL_P (addr))
2325     addr = gen_sym_PLT (addr);
2326   if (!call_insn_operand (addr, VOIDmode))
2327     XEXP (operands[1], 0) = copy_to_mode_reg (Pmode, addr);
2330 ;; cannot combine constraints for operand 0 into "afvb"
2331 ;; reload.c:find_reloads seems to assume that grouped constraints somehow
2332 ;; specify related register classes, and when they don't the constraints
2333 ;; fail to match. By not grouping the constraints, we get the correct
2334 ;; behavior.
2335 (define_insn "call_value_internal"
2336    [(set (match_operand 0 "register_operand" "=af,af,af,v,v,v,b,b,b")
2337          (call (mem (match_operand:SI 1 "call_insn_operand"
2338                                         "n,i,r,n,i,r,n,i,r"))
2339                (match_operand 2 "" "i,i,i,i,i,i,i,i,i")))]
2340   ""
2341   "*
2342     return xtensa_emit_call (1, operands);
2343   "
2344   [(set_attr "type"     "call")
2345    (set_attr "mode"     "none")
2346    (set_attr "length"   "3")])
2348 (define_insn "entry"
2349   [(set (reg:SI A1_REG)
2350         (unspec_volatile:SI [(match_operand:SI 0 "const_int_operand" "i")
2351                              (match_operand:SI 1 "const_int_operand" "i")]
2352                             UNSPECV_ENTRY))]
2353   ""
2354   "*
2356   if (frame_pointer_needed)
2357     output_asm_insn (\".frame\\ta7, %0\", operands);
2358   else
2359     output_asm_insn (\".frame\\tsp, %0\", operands);
2360   return \"entry\\tsp, %1\";
2362   [(set_attr "type"     "move")
2363    (set_attr "mode"     "SI")
2364    (set_attr "length"   "3")])
2366 (define_insn "return"
2367   [(return)
2368    (use (reg:SI A0_REG))]
2369   "reload_completed"
2370   "*
2372   return (TARGET_DENSITY ? \"retw.n\" : \"retw\");
2374   [(set_attr "type"     "jump")
2375    (set_attr "mode"     "none")
2376    (set_attr "length"   "2")])
2380 ;;  ....................
2382 ;;      MISC.
2384 ;;  ....................
2387 (define_expand "prologue"
2388   [(const_int 0)]
2389   ""
2390   "
2392   xtensa_expand_prologue ();
2393   DONE;
2396 (define_expand "epilogue"
2397   [(return)]
2398   ""
2399   "
2401   emit_jump_insn (gen_return ());
2402   DONE;
2405 (define_insn "nop"
2406   [(const_int 0)]
2407   ""
2408   "*
2410   return (TARGET_DENSITY ? \"nop.n\" : \"nop\");
2412   [(set_attr "type"     "nop")
2413    (set_attr "mode"     "none")
2414    (set_attr "length"   "3")])
2416 (define_expand "nonlocal_goto"
2417   [(match_operand:SI 0 "general_operand" "")
2418    (match_operand:SI 1 "general_operand" "")
2419    (match_operand:SI 2 "general_operand" "")
2420    (match_operand:SI 3 "" "")]
2421   ""
2422   "
2424   xtensa_expand_nonlocal_goto (operands);
2425   DONE;
2428 ;; Setting up a frame pointer is tricky for Xtensa because GCC doesn't
2429 ;; know if a frame pointer is required until the reload pass, and
2430 ;; because there may be an incoming argument value in the hard frame
2431 ;; pointer register (a7). If there is an incoming argument in that
2432 ;; register, the "set_frame_ptr" insn gets inserted immediately after
2433 ;; the insn that copies the incoming argument to a pseudo or to the
2434 ;; stack.  This serves several purposes here: (1) it keeps the
2435 ;; optimizer from copy-propagating or scheduling the use of a7 as an
2436 ;; incoming argument away from the beginning of the function; (2) we
2437 ;; can use a post-reload splitter to expand away the insn if a frame
2438 ;; pointer is not required, so that the post-reload scheduler can do
2439 ;; the right thing; and (3) it makes it easy for xtensa_reorg() to
2440 ;; search for this insn to determine whether it should add a new insn
2441 ;; to set up the frame pointer.
2443 (define_insn "set_frame_ptr"
2444   [(set (reg:SI A7_REG) (unspec_volatile:SI [(const_int 0)] UNSPECV_SET_FP))]
2445   ""
2446   "*
2448   if (frame_pointer_needed)
2449     return \"mov\\ta7, sp\";
2450   return \"\";
2452   [(set_attr "type"     "move")
2453    (set_attr "mode"     "SI")
2454    (set_attr "length"   "3")])
2456 ;; Post-reload splitter to remove fp assignment when it's not needed.
2457 (define_split
2458   [(set (reg:SI A7_REG) (unspec_volatile:SI [(const_int 0)] UNSPECV_SET_FP))]
2459   "reload_completed && !frame_pointer_needed"
2460   [(unspec [(const_int 0)] UNSPEC_NOP)]
2461   "")
2463 ;; The preceding splitter needs something to split the insn into;
2464 ;; things start breaking if the result is just a "use" so instead we
2465 ;; generate the following insn.
2466 (define_insn "*unspec_nop"
2467   [(unspec [(const_int 0)] UNSPEC_NOP)]
2468   ""
2469   ""
2470   [(set_attr "type"     "nop")
2471    (set_attr "mode"     "none")
2472    (set_attr "length"   "0")])
2474 ;; The fix_return_addr pattern sets the high 2 bits of an address in a
2475 ;; register to match the high bits of the current PC.
2477 (define_insn "fix_return_addr"
2478   [(set (match_operand:SI 0 "register_operand" "=a")
2479         (unspec:SI [(match_operand:SI 1 "register_operand" "r")]
2480                    UNSPEC_RET_ADDR))
2481    (clobber (match_scratch:SI 2 "=r"))
2482    (clobber (match_scratch:SI 3 "=r"))]
2483   ""
2484   "mov\\t%2, a0\;call0\\t0f\;.align\\t4\;0:\;mov\\t%3, a0\;mov\\ta0, %2\;\
2485 srli\\t%3, %3, 30\;slli\\t%0, %1, 2\;ssai\\t2\;src\\t%0, %3, %0"
2486   [(set_attr "type"     "multi")
2487    (set_attr "mode"     "SI")
2488    (set_attr "length"   "24")])
2492 ;;  ....................
2494 ;;      BOOLEANS
2496 ;;  ....................
2499 ;; branch patterns
2501 (define_insn "*booltrue"
2502   [(set (pc)
2503         (if_then_else (match_operator 2 "boolean_operator"
2504                          [(match_operand:CC 0 "register_operand" "b")
2505                           (const_int 0)])
2506                       (label_ref (match_operand 1 "" ""))
2507                       (pc)))]
2508   "TARGET_BOOLEANS"
2509   "*
2511   if (GET_CODE (operands[2]) == EQ)
2512     return \"bf\\t%0, %1\";
2513   else
2514     return \"bt\\t%0, %1\";
2516   [(set_attr "type"     "jump")
2517    (set_attr "mode"     "none")
2518    (set_attr "length"   "3")])
2520 (define_insn "*boolfalse"
2521   [(set (pc)
2522         (if_then_else (match_operator 2 "boolean_operator"
2523                          [(match_operand:CC 0 "register_operand" "b")
2524                           (const_int 0)])
2525                       (pc)
2526                       (label_ref (match_operand 1 "" ""))))]
2527   "TARGET_BOOLEANS"
2528   "*
2530   if (GET_CODE (operands[2]) == EQ)
2531     return \"bt\\t%0, %1\";
2532   else
2533     return \"bf\\t%0, %1\";
2535   [(set_attr "type"     "jump")
2536    (set_attr "mode"     "none")
2537    (set_attr "length"   "3")])