OSDN Git Service

* config/xtensa/xtensa-protos.h (smalloffset_double_mem_p): Delete.
[pf3gnuchains/gcc-fork.git] / gcc / config / xtensa / xtensa.md
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.
4
5 ;; This file is part of GCC.
6
7 ;; GCC is free software; you can redistribute it and/or modify it
8 ;; under the terms of the GNU General Public License as published by
9 ;; the Free Software Foundation; either version 2, or (at your option)
10 ;; any later version.
11
12 ;; GCC is distributed in the hope that it will be useful, but WITHOUT
13 ;; ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
14 ;; or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public
15 ;; License for more details.
16
17 ;; You should have received a copy of the GNU General Public License
18 ;; along with GCC; see the file COPYING.  If not, write to the Free
19 ;; Software Foundation, 59 Temple Place - Suite 330, Boston, MA
20 ;; 02111-1307, USA.
21
22 ;;
23 ;; ....................
24 ;;
25 ;;      CONSTANTS
26 ;;
27 ;; ....................
28 ;;
29
30 (define_constants [
31   (A0_REG               0)
32   (A1_REG               1)
33   (A7_REG               7)
34   (A8_REG               8)
35
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)
42 ])
43
44 ;;
45 ;; ....................
46 ;;
47 ;;      ATTRIBUTES
48 ;;
49 ;; ....................
50 ;;
51
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"))
55
56 (define_attr "mode"
57   "unknown,none,QI,HI,SI,DI,SF,DF,BL"
58   (const_string "unknown"))
59
60 (define_attr "length" "" (const_int 1))
61
62 ;; Describe a user's asm statement.
63 (define_asm_attributes
64   [(set_attr "type" "multi")])
65
66
67 ;;
68 ;; ....................
69 ;;
70 ;;      FUNCTIONAL UNITS
71 ;;
72 ;; ....................
73 ;;
74
75 (define_function_unit "memory" 1 0 (eq_attr "type" "load,fload") 2 0)
76
77 (define_function_unit "sreg" 1 1 (eq_attr "type" "rsr") 2 0)
78
79 (define_function_unit "mul16" 1 0 (eq_attr "type" "mul16") 2 0)
80
81 (define_function_unit "mul32" 1 0 (eq_attr "type" "mul32") 2 0)
82
83 (define_function_unit "fpmadd" 1 0 (eq_attr "type" "fmadd") 4 0)
84
85 (define_function_unit "fpconv" 1 0 (eq_attr "type" "fconv") 2 0)
86
87
88 ;;
89 ;;  ....................
90 ;;
91 ;;      ADDITION
92 ;;
93 ;;  ....................
94 ;;
95
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   "
102 {
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]);
107
108   rtx dsthi = gen_highpart (SImode, operands[0]);
109   rtx src1hi = gen_highpart (SImode, operands[1]);
110   rtx src2hi = gen_highpart (SImode, operands[2]);
111
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     }
123
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;
128 }")
129
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.
134
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")])
145
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")])
160
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   "TARGET_ADDX"
167   "addx2\\t%0, %1, %2"
168   [(set_attr "type"     "arith")
169    (set_attr "mode"     "SI")
170    (set_attr "length"   "3")])
171
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   "TARGET_ADDX"
178   "addx4\\t%0, %1, %2"
179   [(set_attr "type"     "arith")
180    (set_attr "mode"     "SI")
181    (set_attr "length"   "3")])
182
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   "TARGET_ADDX"
189   "addx8\\t%0, %1, %2"
190   [(set_attr "type"     "arith")
191    (set_attr "mode"     "SI")
192    (set_attr "length"   "3")])
193
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")])
203
204
205 ;;
206 ;;  ....................
207 ;;
208 ;;      SUBTRACTION
209 ;;
210 ;;  ....................
211 ;;
212
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   "
219 {
220   rtx dstlo = gen_lowpart (SImode, operands[0]);
221   rtx src1lo = gen_lowpart (SImode, operands[1]);
222   rtx src2lo = gen_lowpart (SImode, operands[2]);
223
224   rtx dsthi = gen_highpart (SImode, operands[0]);
225   rtx src1hi = gen_highpart (SImode, operands[1]);
226   rtx src2hi = gen_highpart (SImode, operands[2]);
227
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;
232 }")
233
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")])
244
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")])
254
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   "TARGET_ADDX"
261   "subx2\\t%0, %1, %2"
262   [(set_attr "type"     "arith")
263    (set_attr "mode"     "SI")
264    (set_attr "length"   "3")])
265
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   "TARGET_ADDX"
272   "subx4\\t%0, %1, %2"
273   [(set_attr "type"     "arith")
274    (set_attr "mode"     "SI")
275    (set_attr "length"   "3")])
276
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   "TARGET_ADDX"
283   "subx8\\t%0, %1, %2"
284   [(set_attr "type"     "arith")
285    (set_attr "mode"     "SI")
286    (set_attr "length"   "3")])
287
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")])
297
298
299 ;;
300 ;;  ....................
301 ;;
302 ;;      MULTIPLICATION
303 ;;
304 ;;  ....................
305 ;;
306
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")])
316
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")])
330
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")])
344
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")])
357
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")])
370
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")])
380
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")])
391
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")])
402
403
404 ;;
405 ;;  ....................
406 ;;
407 ;;      DIVISION
408 ;;
409 ;;  ....................
410 ;;
411
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")])
421
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")])
431
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")])
441
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")])
451
452
453 ;;
454 ;;  ....................
455 ;;
456 ;;      REMAINDER
457 ;;
458 ;;  ....................
459 ;;
460
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")])
470
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")])
480
481
482 ;;
483 ;;  ....................
484 ;;
485 ;;      SQUARE ROOT
486 ;;
487 ;;  ....................
488 ;;
489
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")])
498
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")])
508
509
510 ;;
511 ;;  ....................
512 ;;
513 ;;      ABSOLUTE VALUE
514 ;;
515 ;;  ....................
516 ;;
517
518 (define_insn "abssi2"
519   [(set (match_operand:SI 0 "register_operand" "=a")
520         (abs:SI (match_operand:SI 1 "register_operand" "r")))]
521   "TARGET_ABS"
522   "abs\\t%0, %1"
523   [(set_attr "type"     "arith")
524    (set_attr "mode"     "SI")
525    (set_attr "length"   "3")])
526
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")])
535
536
537 ;;
538 ;;  ....................
539 ;;
540 ;;      MIN AND MAX INSTRUCTIONS
541 ;;
542 ;;  ....................
543 ;;
544
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")])
554
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")])
564
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")])
574
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")])
584
585
586 ;;
587 ;;  ....................
588 ;;
589 ;;      FIND FIRST BIT INSTRUCTION
590 ;;
591 ;;  ....................
592 ;;
593
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   "
599 {
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;
607 }")
608
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")])
618
619
620 ;;
621 ;;  ....................
622 ;;
623 ;;      NEGATION and ONE'S COMPLEMENT
624 ;;
625 ;;  ....................
626 ;;
627
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")])
636
637 (define_expand "one_cmplsi2"
638   [(set (match_operand:SI 0 "register_operand" "")
639         (not:SI (match_operand:SI 1 "register_operand" "")))]
640   ""
641   "
642 {
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;
647 }")
648
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")])
657
658
659 ;;
660 ;;  ....................
661 ;;
662 ;;      LOGICAL
663 ;;
664 ;;  ....................
665 ;;
666
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")])
678
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")])
688
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")])
698
699
700 ;;
701 ;;  ....................
702 ;;
703 ;;      ZERO EXTENSION
704 ;;
705 ;;  ....................
706 ;;
707
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")])
718
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")])
729
730
731 ;;
732 ;;  ....................
733 ;;
734 ;;      SIGN EXTENSION
735 ;;
736 ;;  ....................
737 ;;
738
739 (define_expand "extendhisi2"
740   [(set (match_operand:SI 0 "register_operand" "")
741         (sign_extend:SI (match_operand:HI 1 "register_operand" "")))]
742   ""
743   "
744 {
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;
750 }")
751
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")])
762
763 (define_expand "extendqisi2"
764   [(set (match_operand:SI 0 "register_operand" "")
765         (sign_extend:SI (match_operand:QI 1 "register_operand" "")))]
766   ""
767   "
768 {
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;
776 }")
777
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")])
786
787
788 ;;
789 ;;  ....................
790 ;;
791 ;;      FIELD EXTRACT
792 ;;
793 ;;  ....................
794 ;;
795
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   "
803 {
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;
811 }")
812
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   "*
820 {
821   int fldsz = INTVAL (operands[2]);
822   operands[2] = GEN_INT (fldsz - 1);
823   return \"sext\\t%0, %1, %2\";
824 }"
825   [(set_attr "type"     "arith")
826    (set_attr "mode"     "SI")
827    (set_attr "length"   "3")])
828
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   "
836 {
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;
841 }")
842
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   "*
850 {
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\";
858 }"
859   [(set_attr "type"     "arith")
860    (set_attr "mode"     "SI")
861    (set_attr "length"   "3")])
862
863
864 ;;
865 ;;  ....................
866 ;;
867 ;;      CONVERSIONS
868 ;;
869 ;;  ....................
870 ;;
871
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")])
880
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")])
889
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")])
898
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")])
907
908
909 ;;
910 ;;  ....................
911 ;;
912 ;;      DATA MOVEMENT
913 ;;
914 ;;  ....................
915 ;;
916
917 ;; 64-bit Integer moves
918
919 (define_expand "movdi"
920   [(set (match_operand:DI 0 "nonimmed_operand" "")
921         (match_operand:DI 1 "general_operand" ""))]
922   ""
923   "
924 {
925   if (CONSTANT_P (operands[1]) && !TARGET_CONST16)
926     operands[1] = force_const_mem (DImode, operands[1]);
927
928   if (!register_operand (operands[0], DImode)
929       && !register_operand (operands[1], DImode))
930     operands[1] = force_reg (DImode, operands[1]);
931
932   if (xtensa_copy_incoming_a7 (operands, DImode))
933     DONE;
934 }")
935
936 (define_insn_and_split "movdi_internal"
937   [(set (match_operand:DI 0 "nonimmed_operand" "=a,W,a,a,U")
938         (match_operand:DI 1 "move_operand" "r,i,T,U,r"))]
939   "register_operand (operands[0], DImode)
940    || register_operand (operands[1], DImode)"
941   "#"
942   "reload_completed"
943   [(set (match_dup 0) (match_dup 2))
944    (set (match_dup 1) (match_dup 3))]
945 {
946   xtensa_split_operand_pair (operands, SImode);
947   if (reg_overlap_mentioned_p (operands[0], operands[3]))
948     {
949       rtx tmp;
950       tmp = operands[0], operands[0] = operands[1], operands[1] = tmp;
951       tmp = operands[2], operands[2] = operands[3], operands[3] = tmp;
952     }
953 })
954
955
956 ;; 32-bit Integer moves
957
958 (define_expand "movsi"
959   [(set (match_operand:SI 0 "nonimmed_operand" "")
960         (match_operand:SI 1 "general_operand" ""))]
961   ""
962   "
963 {
964   if (xtensa_emit_move_sequence (operands, SImode))
965     DONE;
966 }")
967
968 (define_insn "movsi_internal"
969   [(set (match_operand:SI 0 "nonimmed_operand" "=D,D,D,D,R,R,a,q,a,W,a,a,U,*a,*A")
970         (match_operand:SI 1 "move_operand" "M,D,d,R,D,d,r,r,I,i,T,U,r,*A,*r"))]
971   "xtensa_valid_move (SImode, operands)"
972   "@
973    movi.n\\t%0, %x1
974    mov.n\\t%0, %1
975    mov.n\\t%0, %1
976    %v1l32i.n\\t%0, %1
977    %v0s32i.n\\t%1, %0
978    %v0s32i.n\\t%1, %0
979    mov\\t%0, %1
980    movsp\\t%0, %1
981    movi\\t%0, %x1
982    const16\\t%0, %t1\;const16\\t%0, %b1
983    %v1l32r\\t%0, %1
984    %v1l32i\\t%0, %1
985    %v0s32i\\t%1, %0
986    rsr\\t%0, 16 # ACCLO
987    wsr\\t%1, 16 # ACCLO"
988   [(set_attr "type" "move,move,move,load,store,store,move,move,move,move,load,load,store,rsr,wsr")
989    (set_attr "mode"     "SI")
990    (set_attr "length"   "2,2,2,2,2,2,3,3,3,6,3,3,3,3,3")])
991
992 ;; 16-bit Integer moves
993
994 (define_expand "movhi"
995   [(set (match_operand:HI 0 "nonimmed_operand" "")
996         (match_operand:HI 1 "general_operand" ""))]
997   ""
998   "
999 {
1000   if (xtensa_emit_move_sequence (operands, HImode))
1001     DONE;
1002 }")
1003
1004 (define_insn "movhi_internal"
1005   [(set (match_operand:HI 0 "nonimmed_operand" "=D,D,a,a,a,U,*a,*A")
1006         (match_operand:HI 1 "move_operand" "M,d,r,I,U,r,*A,*r"))]
1007   "xtensa_valid_move (HImode, operands)"
1008   "@
1009    movi.n\\t%0, %x1
1010    mov.n\\t%0, %1
1011    mov\\t%0, %1
1012    movi\\t%0, %x1
1013    %v1l16ui\\t%0, %1
1014    %v0s16i\\t%1, %0
1015    rsr\\t%0, 16 # ACCLO
1016    wsr\\t%1, 16 # ACCLO"
1017   [(set_attr "type"     "move,move,move,move,load,store,rsr,wsr")
1018    (set_attr "mode"     "HI")
1019    (set_attr "length"   "2,2,3,3,3,3,3,3")])
1020
1021 ;; 8-bit Integer moves
1022
1023 (define_expand "movqi"
1024   [(set (match_operand:QI 0 "nonimmed_operand" "")
1025         (match_operand:QI 1 "general_operand" ""))]
1026   ""
1027   "
1028 {
1029   if (xtensa_emit_move_sequence (operands, QImode))
1030     DONE;
1031 }")
1032
1033 (define_insn "movqi_internal"
1034   [(set (match_operand:QI 0 "nonimmed_operand" "=D,D,a,a,a,U,*a,*A")
1035         (match_operand:QI 1 "move_operand" "M,d,r,I,U,r,*A,*r"))]
1036   "xtensa_valid_move (QImode, operands)"
1037   "@
1038    movi.n\\t%0, %x1
1039    mov.n\\t%0, %1
1040    mov\\t%0, %1
1041    movi\\t%0, %x1
1042    %v1l8ui\\t%0, %1
1043    %v0s8i\\t%1, %0
1044    rsr\\t%0, 16 # ACCLO
1045    wsr\\t%1, 16 # ACCLO"
1046   [(set_attr "type"     "move,move,move,move,load,store,rsr,wsr")
1047    (set_attr "mode"     "QI")
1048    (set_attr "length"   "2,2,3,3,3,3,3,3")])
1049
1050 ;; 32-bit floating point moves
1051
1052 (define_expand "movsf"
1053   [(set (match_operand:SF 0 "nonimmed_operand" "")
1054         (match_operand:SF 1 "general_operand" ""))]
1055   ""
1056   "
1057 {
1058   if (!TARGET_CONST16 && CONSTANT_P (operands[1]))
1059     operands[1] = force_const_mem (SFmode, operands[1]);
1060
1061   if (!(reload_in_progress | reload_completed))
1062     {
1063       if ((!register_operand (operands[0], SFmode)
1064            && !register_operand (operands[1], SFmode))
1065           || (FP_REG_P (xt_true_regnum (operands[0]))
1066               && (constantpool_mem_p (operands[1])
1067                   || CONSTANT_P (operands[1]))))
1068         operands[1] = force_reg (SFmode, operands[1]);
1069
1070       if (xtensa_copy_incoming_a7 (operands, SFmode))
1071         DONE;
1072     }
1073 }")
1074
1075 (define_insn "movsf_internal"
1076   [(set (match_operand:SF 0 "nonimmed_operand" "=f,f,U,D,D,R,a,f,a,W,a,a,U")
1077         (match_operand:SF 1 "move_operand" "f,U,f,d,R,d,r,r,f,iF,T,U,r"))]
1078   "((register_operand (operands[0], SFmode)
1079      || register_operand (operands[1], SFmode))
1080     && !(FP_REG_P (xt_true_regnum (operands[0]))
1081          && (constantpool_mem_p (operands[1]) || CONSTANT_P (operands[1]))))"
1082   "@
1083    mov.s\\t%0, %1
1084    %v1lsi\\t%0, %1
1085    %v0ssi\\t%1, %0
1086    mov.n\\t%0, %1
1087    %v1l32i.n\\t%0, %1
1088    %v0s32i.n\\t%1, %0
1089    mov\\t%0, %1
1090    wfr\\t%0, %1
1091    rfr\\t%0, %1
1092    const16\\t%0, %t1\;const16\\t%0, %b1
1093    %v1l32r\\t%0, %1
1094    %v1l32i\\t%0, %1
1095    %v0s32i\\t%1, %0"
1096   [(set_attr "type"     "farith,fload,fstore,move,load,store,move,farith,farith,move,load,load,store")
1097    (set_attr "mode"     "SF")
1098    (set_attr "length"   "3,3,3,2,2,2,3,3,3,6,3,3,3")])
1099
1100 (define_insn "*lsiu"
1101   [(set (match_operand:SF 0 "register_operand" "=f")
1102         (mem:SF (plus:SI (match_operand:SI 1 "register_operand" "+a")
1103                          (match_operand:SI 2 "fpmem_offset_operand" "i"))))
1104    (set (match_dup 1)
1105         (plus:SI (match_dup 1) (match_dup 2)))]
1106   "TARGET_HARD_FLOAT"
1107   "*
1108 {
1109   if (volatile_refs_p (PATTERN (insn)))
1110     output_asm_insn (\"memw\", operands);
1111   return \"lsiu\\t%0, %1, %2\";
1112 }"
1113   [(set_attr "type"     "fload")
1114    (set_attr "mode"     "SF")
1115    (set_attr "length"   "3")])
1116
1117 (define_insn "*ssiu"
1118   [(set (mem:SF (plus:SI (match_operand:SI 0 "register_operand" "+a")
1119                          (match_operand:SI 1 "fpmem_offset_operand" "i")))
1120         (match_operand:SF 2 "register_operand" "f"))
1121    (set (match_dup 0)
1122         (plus:SI (match_dup 0) (match_dup 1)))]
1123   "TARGET_HARD_FLOAT"
1124   "*
1125 {
1126   if (volatile_refs_p (PATTERN (insn)))
1127     output_asm_insn (\"memw\", operands);
1128   return \"ssiu\\t%2, %0, %1\";
1129 }"
1130   [(set_attr "type"     "fstore")
1131    (set_attr "mode"     "SF")
1132    (set_attr "length"   "3")])
1133
1134 ;; 64-bit floating point moves
1135
1136 (define_expand "movdf"
1137   [(set (match_operand:DF 0 "nonimmed_operand" "")
1138         (match_operand:DF 1 "general_operand" ""))]
1139   ""
1140   "
1141 {
1142   if (CONSTANT_P (operands[1]) && !TARGET_CONST16)
1143     operands[1] = force_const_mem (DFmode, operands[1]);
1144
1145   if (!register_operand (operands[0], DFmode)
1146       && !register_operand (operands[1], DFmode))
1147     operands[1] = force_reg (DFmode, operands[1]);
1148
1149   if (xtensa_copy_incoming_a7 (operands, DFmode))
1150     DONE;
1151 }")
1152
1153 (define_insn_and_split "movdf_internal"
1154   [(set (match_operand:DF 0 "nonimmed_operand" "=a,W,a,a,U")
1155         (match_operand:DF 1 "move_operand" "r,iF,T,U,r"))]
1156   "register_operand (operands[0], DFmode)
1157    || register_operand (operands[1], DFmode)"
1158   "#"
1159   "reload_completed"
1160   [(set (match_dup 0) (match_dup 2))
1161    (set (match_dup 1) (match_dup 3))]
1162 {
1163   xtensa_split_operand_pair (operands, SFmode);
1164   if (reg_overlap_mentioned_p (operands[0], operands[3]))
1165     {
1166       rtx tmp;
1167       tmp = operands[0], operands[0] = operands[1], operands[1] = tmp;
1168       tmp = operands[2], operands[2] = operands[3], operands[3] = tmp;
1169     }
1170 })
1171  
1172
1173 ;; Block moves
1174
1175 (define_expand "movstrsi"
1176   [(parallel [(set (match_operand:BLK 0 "" "")
1177                    (match_operand:BLK 1 "" ""))
1178               (use (match_operand:SI 2 "arith_operand" ""))
1179               (use (match_operand:SI 3 "const_int_operand" ""))])]
1180   ""
1181   "
1182 {
1183   if (!xtensa_expand_block_move (operands)) FAIL;
1184   DONE;
1185 }")
1186
1187 (define_insn "movstrsi_internal"
1188   [(set (match_operand:BLK 0 "memory_operand" "=U")
1189         (match_operand:BLK 1 "memory_operand" "U"))
1190    (use (match_operand:SI 2 "arith_operand" ""))
1191    (use (match_operand:SI 3 "const_int_operand" ""))
1192    (clobber (match_scratch:SI 4 "=&r"))
1193    (clobber (match_scratch:SI 5 "=&r"))]
1194   ""
1195   "*
1196 {
1197   rtx tmpregs[2];
1198   tmpregs[0] = operands[4];
1199   tmpregs[1] = operands[5];
1200   xtensa_emit_block_move (operands, tmpregs, 1);
1201   return \"\";
1202 }"
1203   [(set_attr "type"     "multi")
1204    (set_attr "mode"     "none")
1205    (set_attr "length"   "300")])
1206
1207
1208 ;;
1209 ;;  ....................
1210 ;;
1211 ;;      SHIFTS
1212 ;;
1213 ;;  ....................
1214 ;;
1215
1216 (define_insn "ashlsi3"
1217   [(set (match_operand:SI 0 "register_operand" "=a,a")
1218         (ashift:SI (match_operand:SI 1 "register_operand" "r,r")
1219                    (match_operand:SI 2 "arith_operand" "J,r")))]
1220   ""      
1221   "@
1222    slli\\t%0, %1, %R2
1223    ssl\\t%2\;sll\\t%0, %1"
1224   [(set_attr "type"     "arith,arith")
1225    (set_attr "mode"     "SI")
1226    (set_attr "length"   "3,6")])
1227
1228 (define_insn "ashrsi3"
1229   [(set (match_operand:SI 0 "register_operand" "=a,a")
1230         (ashiftrt:SI (match_operand:SI 1 "register_operand" "r,r")
1231                      (match_operand:SI 2 "arith_operand" "J,r")))]
1232   ""
1233   "@
1234    srai\\t%0, %1, %R2
1235    ssr\\t%2\;sra\\t%0, %1"
1236   [(set_attr "type"     "arith,arith")
1237    (set_attr "mode"     "SI")
1238    (set_attr "length"   "3,6")])
1239
1240 (define_insn "lshrsi3"
1241   [(set (match_operand:SI 0 "register_operand" "=a,a")
1242         (lshiftrt:SI (match_operand:SI 1 "register_operand" "r,r")
1243                      (match_operand:SI 2 "arith_operand" "J,r")))]
1244   ""
1245   "*
1246 {
1247   if (which_alternative == 0)
1248     {
1249       if ((INTVAL (operands[2]) & 0x1f) < 16)
1250         return \"srli\\t%0, %1, %R2\";
1251       else
1252         return \"extui\\t%0, %1, %R2, %L2\";
1253     }
1254   return \"ssr\\t%2\;srl\\t%0, %1\";
1255 }"
1256   [(set_attr "type"     "arith,arith")
1257    (set_attr "mode"     "SI")
1258    (set_attr "length"   "3,6")])
1259
1260 (define_insn "rotlsi3"
1261   [(set (match_operand:SI 0 "register_operand" "=a,a")
1262         (rotate:SI (match_operand:SI 1 "register_operand" "r,r")
1263                      (match_operand:SI 2 "arith_operand" "J,r")))]
1264   ""
1265   "@
1266    ssai\\t%L2\;src\\t%0, %1, %1
1267    ssl\\t%2\;src\\t%0, %1, %1"
1268   [(set_attr "type"     "multi,multi")
1269    (set_attr "mode"     "SI")
1270    (set_attr "length"   "6,6")])
1271
1272 (define_insn "rotrsi3"
1273   [(set (match_operand:SI 0 "register_operand" "=a,a")
1274         (rotatert:SI (match_operand:SI 1 "register_operand" "r,r")
1275                      (match_operand:SI 2 "arith_operand" "J,r")))]
1276   ""
1277   "@
1278    ssai\\t%R2\;src\\t%0, %1, %1
1279    ssr\\t%2\;src\\t%0, %1, %1"
1280   [(set_attr "type"     "multi,multi")
1281    (set_attr "mode"     "SI")
1282    (set_attr "length"   "6,6")])
1283
1284
1285 ;;
1286 ;;  ....................
1287 ;;
1288 ;;      COMPARISONS
1289 ;;
1290 ;;  ....................
1291 ;;
1292
1293 ;; Like the md files for MIPS and SPARC, we handle comparisons by stashing
1294 ;; away the operands and then using that information in the subsequent
1295 ;; conditional branch.
1296
1297 (define_expand "cmpsi"
1298   [(set (cc0)
1299         (compare:CC (match_operand:SI 0 "register_operand" "")
1300                     (match_operand:SI 1 "nonmemory_operand" "")))]
1301   ""
1302   "
1303 {
1304   branch_cmp[0] = operands[0];
1305   branch_cmp[1] = operands[1];
1306   branch_type = CMP_SI;
1307   DONE;
1308 }")
1309
1310 (define_expand "tstsi"
1311   [(set (cc0)
1312         (match_operand:SI 0 "register_operand" ""))]
1313   ""
1314   "
1315 {
1316   branch_cmp[0] = operands[0];
1317   branch_cmp[1] = const0_rtx;
1318   branch_type = CMP_SI;
1319   DONE;
1320 }")
1321
1322 (define_expand "cmpsf"
1323   [(set (cc0)
1324         (compare:CC (match_operand:SF 0 "register_operand" "")
1325                     (match_operand:SF 1 "register_operand" "")))]
1326   "TARGET_HARD_FLOAT"
1327   "
1328 {
1329   branch_cmp[0] = operands[0];
1330   branch_cmp[1] = operands[1];
1331   branch_type = CMP_SF;
1332   DONE;
1333 }")
1334
1335
1336 ;;
1337 ;;  ....................
1338 ;;
1339 ;;      CONDITIONAL BRANCHES
1340 ;;
1341 ;;  ....................
1342 ;;
1343
1344 (define_expand "beq"
1345   [(set (pc)
1346         (if_then_else (eq (cc0) (const_int 0))
1347                       (label_ref (match_operand 0 "" ""))
1348                       (pc)))]
1349   ""
1350   "
1351 {
1352   xtensa_expand_conditional_branch (operands, EQ);
1353   DONE;
1354 }")
1355
1356 (define_expand "bne"
1357   [(set (pc)
1358         (if_then_else (ne (cc0) (const_int 0))
1359                       (label_ref (match_operand 0 "" ""))
1360                       (pc)))]
1361   ""
1362   "
1363 {
1364   xtensa_expand_conditional_branch (operands, NE);
1365   DONE;
1366 }")
1367
1368 (define_expand "bgt"
1369   [(set (pc)
1370         (if_then_else (gt (cc0) (const_int 0))
1371                       (label_ref (match_operand 0 "" ""))
1372                       (pc)))]
1373   ""
1374   "
1375 {
1376   xtensa_expand_conditional_branch (operands, GT);
1377   DONE;
1378 }")
1379
1380 (define_expand "bge"
1381   [(set (pc)
1382         (if_then_else (ge (cc0) (const_int 0))
1383                       (label_ref (match_operand 0 "" ""))
1384                       (pc)))]
1385   ""
1386   "
1387 {
1388   xtensa_expand_conditional_branch (operands, GE);
1389   DONE;
1390 }")
1391
1392 (define_expand "blt"
1393   [(set (pc)
1394         (if_then_else (lt (cc0) (const_int 0))
1395                       (label_ref (match_operand 0 "" ""))
1396                       (pc)))]
1397   ""
1398   "
1399 {
1400   xtensa_expand_conditional_branch (operands, LT);
1401   DONE;
1402 }")
1403
1404 (define_expand "ble"
1405   [(set (pc)
1406         (if_then_else (le (cc0) (const_int 0))
1407                       (label_ref (match_operand 0 "" ""))
1408                       (pc)))]
1409   ""
1410   "
1411 {
1412   xtensa_expand_conditional_branch (operands, LE);
1413   DONE;
1414 }")
1415
1416 (define_expand "bgtu"
1417   [(set (pc)
1418         (if_then_else (gtu (cc0) (const_int 0))
1419                       (label_ref (match_operand 0 "" ""))
1420                       (pc)))]
1421   ""
1422   "
1423 {
1424   xtensa_expand_conditional_branch (operands, GTU);
1425   DONE;
1426 }")
1427
1428 (define_expand "bgeu"
1429   [(set (pc)
1430         (if_then_else (geu (cc0) (const_int 0))
1431                       (label_ref (match_operand 0 "" ""))
1432                       (pc)))]
1433   ""
1434   "
1435 {
1436   xtensa_expand_conditional_branch (operands, GEU);
1437   DONE;
1438 }")
1439
1440 (define_expand "bltu"
1441   [(set (pc)
1442         (if_then_else (ltu (cc0) (const_int 0))
1443                       (label_ref (match_operand 0 "" ""))
1444                       (pc)))]
1445   ""
1446   "
1447 {
1448   xtensa_expand_conditional_branch (operands, LTU);
1449   DONE;
1450 }")
1451
1452 (define_expand "bleu"
1453   [(set (pc)
1454         (if_then_else (leu (cc0) (const_int 0))
1455                       (label_ref (match_operand 0 "" ""))
1456                       (pc)))]
1457   ""
1458   "
1459 {
1460   xtensa_expand_conditional_branch (operands, LEU);
1461   DONE;
1462 }")
1463
1464 ;; Branch patterns for standard integer comparisons
1465
1466 (define_insn "*btrue"
1467   [(set (pc)
1468         (if_then_else (match_operator 3 "branch_operator"
1469                          [(match_operand:SI 0 "register_operand" "r,r")
1470                           (match_operand:SI 1 "branch_operand" "K,r")])
1471                       (label_ref (match_operand 2 "" ""))
1472                       (pc)))]
1473   ""
1474   "*
1475 {
1476   if (which_alternative == 1)
1477     {
1478       switch (GET_CODE (operands[3]))
1479         {
1480         case EQ:        return \"beq\\t%0, %1, %2\";
1481         case NE:        return \"bne\\t%0, %1, %2\";
1482         case LT:        return \"blt\\t%0, %1, %2\";
1483         case GE:        return \"bge\\t%0, %1, %2\";
1484         default:        break;
1485         }
1486     }
1487   else if (INTVAL (operands[1]) == 0)
1488     {
1489       switch (GET_CODE (operands[3]))
1490         {
1491         case EQ:        return (TARGET_DENSITY
1492                                 ? \"beqz.n\\t%0, %2\"
1493                                 : \"beqz\\t%0, %2\");
1494         case NE:        return (TARGET_DENSITY
1495                                 ? \"bnez.n\\t%0, %2\"
1496                                 : \"bnez\\t%0, %2\");
1497         case LT:        return \"bltz\\t%0, %2\";
1498         case GE:        return \"bgez\\t%0, %2\";
1499         default:        break;
1500         }
1501     }
1502   else
1503     {
1504       switch (GET_CODE (operands[3]))
1505         {
1506         case EQ:        return \"beqi\\t%0, %d1, %2\";
1507         case NE:        return \"bnei\\t%0, %d1, %2\";
1508         case LT:        return \"blti\\t%0, %d1, %2\";
1509         case GE:        return \"bgei\\t%0, %d1, %2\";
1510         default:        break;
1511         }
1512     }
1513   fatal_insn (\"unexpected branch operator\", operands[3]);
1514   return \"\";
1515 }"
1516   [(set_attr "type"     "jump,jump")
1517    (set_attr "mode"     "none")
1518    (set_attr "length"   "3,3")])
1519
1520 (define_insn "*bfalse"
1521   [(set (pc)
1522         (if_then_else (match_operator 3 "branch_operator"
1523                          [(match_operand:SI 0 "register_operand" "r,r")
1524                           (match_operand:SI 1 "branch_operand" "K,r")])
1525                       (pc)
1526                       (label_ref (match_operand 2 "" ""))))]
1527   ""
1528   "*
1529 {
1530   if (which_alternative == 1)
1531     {
1532       switch (GET_CODE (operands[3]))
1533         {
1534         case EQ:        return \"bne\\t%0, %1, %2\";
1535         case NE:        return \"beq\\t%0, %1, %2\";
1536         case LT:        return \"bge\\t%0, %1, %2\";
1537         case GE:        return \"blt\\t%0, %1, %2\";
1538         default:        break;
1539         }
1540     }
1541   else if (INTVAL (operands[1]) == 0)
1542     {
1543       switch (GET_CODE (operands[3]))
1544         {
1545         case EQ:        return (TARGET_DENSITY
1546                                 ? \"bnez.n\\t%0, %2\"
1547                                 : \"bnez\\t%0, %2\");
1548         case NE:        return (TARGET_DENSITY
1549                                 ? \"beqz.n\\t%0, %2\"
1550                                 : \"beqz\\t%0, %2\");
1551         case LT:        return \"bgez\\t%0, %2\";
1552         case GE:        return \"bltz\\t%0, %2\";
1553         default:        break;
1554         }
1555     }
1556   else
1557     {
1558       switch (GET_CODE (operands[3]))
1559         {
1560         case EQ:        return \"bnei\\t%0, %d1, %2\";
1561         case NE:        return \"beqi\\t%0, %d1, %2\";
1562         case LT:        return \"bgei\\t%0, %d1, %2\";
1563         case GE:        return \"blti\\t%0, %d1, %2\";
1564         default:        break;
1565         }
1566     }
1567   fatal_insn (\"unexpected branch operator\", operands[3]);
1568   return \"\";
1569 }"
1570   [(set_attr "type"     "jump,jump")
1571    (set_attr "mode"     "none")
1572    (set_attr "length"   "3,3")])
1573
1574 (define_insn "*ubtrue"
1575   [(set (pc)
1576         (if_then_else (match_operator 3 "ubranch_operator"
1577                          [(match_operand:SI 0 "register_operand" "r,r")
1578                           (match_operand:SI 1 "ubranch_operand" "L,r")])
1579                       (label_ref (match_operand 2 "" ""))
1580                       (pc)))]
1581   ""
1582   "*
1583 {
1584   if (which_alternative == 1)
1585     {
1586       switch (GET_CODE (operands[3]))
1587         {
1588         case LTU:       return \"bltu\\t%0, %1, %2\";
1589         case GEU:       return \"bgeu\\t%0, %1, %2\";
1590         default:        break;
1591         }
1592     }
1593   else
1594     {
1595       switch (GET_CODE (operands[3]))
1596         {
1597         case LTU:       return \"bltui\\t%0, %d1, %2\";
1598         case GEU:       return \"bgeui\\t%0, %d1, %2\";
1599         default:        break;
1600         }
1601     }
1602   fatal_insn (\"unexpected branch operator\", operands[3]);
1603   return \"\";
1604 }"
1605   [(set_attr "type"     "jump,jump")
1606    (set_attr "mode"     "none")
1607    (set_attr "length"   "3,3")])
1608
1609 (define_insn "*ubfalse"
1610   [(set (pc)
1611         (if_then_else (match_operator 3 "ubranch_operator"
1612                          [(match_operand:SI 0 "register_operand" "r,r")
1613                           (match_operand:SI 1 "ubranch_operand" "L,r")])
1614                       (pc)
1615                       (label_ref (match_operand 2 "" ""))))]
1616   ""
1617   "*
1618 {
1619   if (which_alternative == 1)
1620     {
1621       switch (GET_CODE (operands[3]))
1622         {
1623         case LTU:       return \"bgeu\\t%0, %1, %2\";
1624         case GEU:       return \"bltu\\t%0, %1, %2\";
1625         default:        break;
1626         }
1627     }
1628   else
1629     {
1630       switch (GET_CODE (operands[3]))
1631         {
1632         case LTU:       return \"bgeui\\t%0, %d1, %2\";
1633         case GEU:       return \"bltui\\t%0, %d1, %2\";
1634         default:        break;
1635         }
1636     }
1637   fatal_insn (\"unexpected branch operator\", operands[3]);
1638   return \"\";
1639 }"
1640   [(set_attr "type"     "jump,jump")
1641    (set_attr "mode"     "none")
1642    (set_attr "length"   "3,3")])
1643
1644 ;; Branch patterns for bit testing
1645
1646 (define_insn "*bittrue"
1647   [(set (pc)
1648         (if_then_else (match_operator 3 "boolean_operator"
1649                         [(zero_extract:SI
1650                             (match_operand:SI 0 "register_operand" "r,r")
1651                             (const_int 1)
1652                             (match_operand:SI 1 "arith_operand" "J,r"))
1653                          (const_int 0)])
1654                       (label_ref (match_operand 2 "" ""))
1655                       (pc)))]
1656   ""
1657   "*
1658 {
1659   if (which_alternative == 0)
1660     {
1661       unsigned bitnum = INTVAL(operands[1]) & 0x1f;
1662       operands[1] = GEN_INT(bitnum);
1663       switch (GET_CODE (operands[3]))
1664         {
1665         case EQ:        return \"bbci\\t%0, %d1, %2\";
1666         case NE:        return \"bbsi\\t%0, %d1, %2\";
1667         default:        break;
1668         }
1669     }
1670   else
1671     {
1672       switch (GET_CODE (operands[3]))
1673         {
1674         case EQ:        return \"bbc\\t%0, %1, %2\";
1675         case NE:        return \"bbs\\t%0, %1, %2\";
1676         default:        break;
1677         }
1678     }
1679   fatal_insn (\"unexpected branch operator\", operands[3]);
1680   return \"\";
1681 }"
1682   [(set_attr "type"     "jump")
1683    (set_attr "mode"     "none")
1684    (set_attr "length"   "3")])
1685
1686 (define_insn "*bitfalse"
1687   [(set (pc)
1688         (if_then_else (match_operator 3 "boolean_operator"
1689                         [(zero_extract:SI
1690                             (match_operand:SI 0 "register_operand" "r,r")
1691                             (const_int 1)
1692                             (match_operand:SI 1 "arith_operand" "J,r"))
1693                          (const_int 0)])
1694                       (pc)
1695                       (label_ref (match_operand 2 "" ""))))]
1696   ""
1697   "*
1698 {
1699   if (which_alternative == 0)
1700     {
1701       unsigned bitnum = INTVAL (operands[1]) & 0x1f;
1702       operands[1] = GEN_INT (bitnum);
1703       switch (GET_CODE (operands[3]))
1704         {
1705         case EQ:    return \"bbsi\\t%0, %d1, %2\";
1706         case NE:    return \"bbci\\t%0, %d1, %2\";
1707         default:    break;
1708         }
1709     }
1710   else
1711     {
1712       switch (GET_CODE (operands[3]))
1713         {
1714         case EQ:        return \"bbs\\t%0, %1, %2\";
1715         case NE:        return \"bbc\\t%0, %1, %2\";
1716         default:        break;
1717         }
1718     }
1719   fatal_insn (\"unexpected branch operator\", operands[3]);
1720   return \"\";
1721 }"
1722   [(set_attr "type"     "jump")
1723    (set_attr "mode"     "none")
1724    (set_attr "length"   "3")])
1725
1726 (define_insn "*masktrue"
1727   [(set (pc)
1728         (if_then_else (match_operator 3 "boolean_operator"
1729                  [(and:SI (match_operand:SI 0 "register_operand" "r")
1730                           (match_operand:SI 1 "register_operand" "r"))
1731                   (const_int 0)])
1732                       (label_ref (match_operand 2 "" ""))
1733                       (pc)))]
1734   ""
1735   "*
1736 {
1737   switch (GET_CODE (operands[3]))
1738     {
1739     case EQ:    return \"bnone\\t%0, %1, %2\";
1740     case NE:    return \"bany\\t%0, %1, %2\";
1741     default:    break;
1742     }
1743   fatal_insn (\"unexpected branch operator\", operands[3]);
1744   return \"\";
1745 }"
1746   [(set_attr "type"     "jump")
1747    (set_attr "mode"     "none")
1748    (set_attr "length"   "3")])
1749
1750 (define_insn "*maskfalse"
1751   [(set (pc)
1752         (if_then_else (match_operator 3 "boolean_operator"
1753                  [(and:SI (match_operand:SI 0 "register_operand" "r")
1754                           (match_operand:SI 1 "register_operand" "r"))
1755                   (const_int 0)])
1756                       (pc)
1757                       (label_ref (match_operand 2 "" ""))))]
1758   ""
1759   "*
1760 {
1761   switch (GET_CODE (operands[3]))
1762     {
1763     case EQ:    return \"bany\\t%0, %1, %2\";
1764     case NE:    return \"bnone\\t%0, %1, %2\";
1765     default:    break;
1766     }
1767   fatal_insn (\"unexpected branch operator\", operands[3]);
1768   return \"\";
1769 }"
1770   [(set_attr "type"     "jump")
1771    (set_attr "mode"     "none")
1772    (set_attr "length"   "3")])
1773
1774
1775 ;; Define the loop insns that is used by bct optimization to represent the
1776 ;; start and end of a zero-overhead loop (in loop.c). This start template
1777 ;; generates the loop insn, the end template doesn't generate any instructions
1778 ;; since since loop end is handled in hardware.
1779
1780 (define_insn "zero_cost_loop_start"
1781   [(set (pc) (if_then_else (eq (match_operand:SI 0 "register_operand" "a")
1782                                (const_int 0))
1783                            (label_ref (match_operand 1 "" ""))
1784                            (pc)))
1785    (set (reg:SI 19)
1786         (plus:SI (match_dup 0) (const_int -1)))]
1787   ""
1788   "loopnez %0, %l1"
1789   [(set_attr "type"     "jump")
1790    (set_attr "mode"     "none")
1791    (set_attr "length"   "3")])
1792
1793 (define_insn "zero_cost_loop_end"
1794   [(set (pc) (if_then_else (ne (reg:SI 19) (const_int 0))
1795                            (label_ref (match_operand 0 "" ""))
1796                            (pc)))
1797    (set (reg:SI 19)
1798         (plus:SI (reg:SI 19) (const_int -1)))]
1799   ""
1800   "*
1801     xtensa_emit_loop_end (insn, operands);
1802     return \"\";
1803   "
1804   [(set_attr "type"     "jump")
1805    (set_attr "mode"     "none")
1806    (set_attr "length"   "0")])
1807
1808
1809 ;;
1810 ;;  ....................
1811 ;;
1812 ;;      SETTING A REGISTER FROM A COMPARISON
1813 ;;
1814 ;;  ....................
1815 ;;
1816
1817 (define_expand "seq"
1818   [(set (match_operand:SI 0 "register_operand" "")
1819         (match_dup 1))]
1820   ""
1821   "
1822 {
1823   operands[1] = gen_rtx (EQ, SImode, branch_cmp[0], branch_cmp[1]);
1824   if (!xtensa_expand_scc (operands)) FAIL;
1825   DONE;
1826 }")
1827
1828 (define_expand "sne"
1829   [(set (match_operand:SI 0 "register_operand" "")
1830         (match_dup 1))]
1831   ""
1832   "
1833 {
1834   operands[1] = gen_rtx (NE, SImode, branch_cmp[0], branch_cmp[1]);
1835   if (!xtensa_expand_scc (operands)) FAIL;
1836   DONE;
1837 }")
1838
1839 (define_expand "sgt"
1840   [(set (match_operand:SI 0 "register_operand" "")
1841         (match_dup 1))]
1842   ""
1843   "
1844 {
1845   operands[1] = gen_rtx (GT, SImode, branch_cmp[0], branch_cmp[1]);
1846   if (!xtensa_expand_scc (operands)) FAIL;
1847   DONE;
1848 }")
1849
1850 (define_expand "sge"
1851   [(set (match_operand:SI 0 "register_operand" "")
1852         (match_dup 1))]
1853   ""
1854   "
1855 {
1856   operands[1] = gen_rtx (GE, SImode, branch_cmp[0], branch_cmp[1]);
1857   if (!xtensa_expand_scc (operands)) FAIL;
1858   DONE;
1859 }")
1860
1861 (define_expand "slt"
1862   [(set (match_operand:SI 0 "register_operand" "")
1863         (match_dup 1))]
1864   ""
1865   "
1866 {
1867   operands[1] = gen_rtx (LT, SImode, branch_cmp[0], branch_cmp[1]);
1868   if (!xtensa_expand_scc (operands)) FAIL;
1869   DONE;
1870 }")
1871
1872 (define_expand "sle"
1873   [(set (match_operand:SI 0 "register_operand" "")
1874         (match_dup 1))]
1875   ""
1876   "
1877 {
1878   operands[1] = gen_rtx (LE, SImode, branch_cmp[0], branch_cmp[1]);
1879   if (!xtensa_expand_scc (operands)) FAIL;
1880   DONE;
1881 }")
1882
1883
1884 ;;
1885 ;;  ....................
1886 ;;
1887 ;;      CONDITIONAL MOVES
1888 ;;
1889 ;;  ....................
1890 ;;
1891
1892 (define_expand "movsicc"
1893   [(set (match_operand:SI 0 "register_operand" "")
1894         (if_then_else:SI (match_operand 1 "comparison_operator" "")
1895                          (match_operand:SI 2 "register_operand" "")
1896                          (match_operand:SI 3 "register_operand" "")))]
1897   ""
1898   "
1899 {
1900   if (!xtensa_expand_conditional_move (operands, 0)) FAIL;
1901   DONE;
1902 }")
1903
1904 (define_expand "movsfcc"
1905   [(set (match_operand:SF 0 "register_operand" "")
1906         (if_then_else:SF (match_operand 1 "comparison_operator" "")
1907                          (match_operand:SF 2 "register_operand" "")
1908                          (match_operand:SF 3 "register_operand" "")))]
1909   ""
1910   "
1911 {
1912   if (!xtensa_expand_conditional_move (operands, 1)) FAIL;
1913   DONE;
1914 }")
1915
1916 (define_insn "movsicc_internal0"
1917   [(set (match_operand:SI 0 "register_operand" "=a,a")
1918         (if_then_else:SI (match_operator 4 "branch_operator"
1919                            [(match_operand:SI 1 "register_operand" "r,r")
1920                             (const_int 0)])
1921                          (match_operand:SI 2 "register_operand" "r,0")
1922                          (match_operand:SI 3 "register_operand" "0,r")))]
1923   ""
1924   "*
1925 {
1926   if (which_alternative == 0)
1927     {
1928       switch (GET_CODE (operands[4]))
1929         {
1930         case EQ:        return \"moveqz\\t%0, %2, %1\";
1931         case NE:        return \"movnez\\t%0, %2, %1\";
1932         case LT:        return \"movltz\\t%0, %2, %1\";
1933         case GE:        return \"movgez\\t%0, %2, %1\";
1934         default:        break;
1935         }
1936     }
1937   else
1938     {
1939       switch (GET_CODE (operands[4]))
1940         {
1941         case EQ:        return \"movnez\\t%0, %3, %1\";
1942         case NE:        return \"moveqz\\t%0, %3, %1\";
1943         case LT:        return \"movgez\\t%0, %3, %1\";
1944         case GE:        return \"movltz\\t%0, %3, %1\";
1945         default:        break;
1946         }
1947     }
1948   fatal_insn (\"unexpected cmov operator\", operands[4]);
1949   return \"\";
1950 }"
1951   [(set_attr "type"     "move,move")
1952    (set_attr "mode"     "SI")
1953    (set_attr "length"   "3,3")])
1954
1955 (define_insn "movsicc_internal1"
1956   [(set (match_operand:SI 0 "register_operand" "=a,a")
1957         (if_then_else:SI (match_operator 4 "boolean_operator"
1958                            [(match_operand:CC 1 "register_operand" "b,b")
1959                             (const_int 0)])
1960                          (match_operand:SI 2 "register_operand" "r,0")
1961                          (match_operand:SI 3 "register_operand" "0,r")))]
1962   "TARGET_BOOLEANS"
1963   "*
1964 {
1965   int isEq = (GET_CODE (operands[4]) == EQ);
1966   switch (which_alternative)
1967     {
1968     case 0:
1969       if (isEq) return \"movf\\t%0, %2, %1\";
1970       return \"movt\\t%0, %2, %1\";
1971     case 1:
1972       if (isEq) return \"movt\\t%0, %3, %1\";
1973       return \"movf\\t%0, %3, %1\";
1974     }
1975   abort ();
1976   return \"\";
1977 }"
1978   [(set_attr "type"     "move,move")
1979    (set_attr "mode"     "SI")
1980    (set_attr "length"   "3,3")])
1981
1982 (define_insn "movsfcc_internal0"
1983   [(set (match_operand:SF 0 "register_operand" "=a,a,f,f")
1984         (if_then_else:SF (match_operator 4 "branch_operator"
1985                            [(match_operand:SI 1 "register_operand" "r,r,r,r")
1986                             (const_int 0)])
1987                          (match_operand:SF 2 "register_operand" "r,0,f,0")
1988                          (match_operand:SF 3 "register_operand" "0,r,0,f")))]
1989   ""
1990   "*
1991 {
1992   if (which_alternative == 0)
1993     {
1994       switch (GET_CODE (operands[4]))
1995         {
1996         case EQ:        return \"moveqz\\t%0, %2, %1\";
1997         case NE:        return \"movnez\\t%0, %2, %1\";
1998         case LT:        return \"movltz\\t%0, %2, %1\";
1999         case GE:        return \"movgez\\t%0, %2, %1\";
2000         default:        break;
2001         }
2002     }
2003   else if (which_alternative == 1)
2004     {
2005       switch (GET_CODE (operands[4]))
2006         {
2007         case EQ:        return \"movnez\\t%0, %3, %1\";
2008         case NE:        return \"moveqz\\t%0, %3, %1\";
2009         case LT:        return \"movgez\\t%0, %3, %1\";
2010         case GE:        return \"movltz\\t%0, %3, %1\";
2011         default:        break;
2012         }
2013     }
2014   else if (which_alternative == 2)
2015     {
2016       switch (GET_CODE (operands[4]))
2017         {
2018         case EQ:        return \"moveqz.s %0, %2, %1\";
2019         case NE:        return \"movnez.s %0, %2, %1\";
2020         case LT:        return \"movltz.s %0, %2, %1\";
2021         case GE:        return \"movgez.s %0, %2, %1\";
2022         default:        break;
2023         }
2024     }
2025   else if (which_alternative == 3)
2026     {
2027       switch (GET_CODE (operands[4]))
2028         {
2029         case EQ:        return \"movnez.s %0, %3, %1\";
2030         case NE:        return \"moveqz.s %0, %3, %1\";
2031         case LT:        return \"movgez.s %0, %3, %1\";
2032         case GE:        return \"movltz.s %0, %3, %1\";
2033         default:        break;
2034         }
2035     }
2036   fatal_insn (\"unexpected cmov operator\", operands[4]);
2037   return \"\";
2038 }"
2039   [(set_attr "type"     "move,move,move,move")
2040    (set_attr "mode"     "SF")
2041    (set_attr "length"   "3,3,3,3")])
2042
2043 (define_insn "movsfcc_internal1"
2044   [(set (match_operand:SF 0 "register_operand" "=a,a,f,f")
2045         (if_then_else:SF (match_operator 4 "boolean_operator"
2046                            [(match_operand:CC 1 "register_operand" "b,b,b,b")
2047                             (const_int 0)])
2048                          (match_operand:SF 2 "register_operand" "r,0,f,0")
2049                          (match_operand:SF 3 "register_operand" "0,r,0,f")))]
2050   "TARGET_BOOLEANS"
2051   "*
2052 {
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     case 2:
2063       if (isEq) return \"movf.s\\t%0, %2, %1\";
2064       return \"movt.s\\t%0, %2, %1\";
2065     case 3:
2066       if (isEq) return \"movt.s\\t%0, %3, %1\";
2067       return \"movf.s\\t%0, %3, %1\";
2068     }
2069   abort ();
2070   return \"\";
2071 }"
2072   [(set_attr "type"     "move,move,move,move")
2073    (set_attr "mode"     "SF")
2074    (set_attr "length"   "3,3,3,3")])
2075
2076
2077 ;;
2078 ;;  ....................
2079 ;;
2080 ;;      FLOATING POINT COMPARISONS
2081 ;;
2082 ;;  ....................
2083 ;;
2084
2085 (define_insn "seq_sf"
2086   [(set (match_operand:CC 0 "register_operand" "=b")
2087         (eq:CC (match_operand:SF 1 "register_operand" "f")
2088                (match_operand:SF 2 "register_operand" "f")))]
2089   "TARGET_HARD_FLOAT"
2090   "oeq.s\\t%0, %1, %2"
2091   [(set_attr "type"     "farith")
2092    (set_attr "mode"     "BL")
2093    (set_attr "length"   "3")])
2094
2095 (define_insn "slt_sf"
2096   [(set (match_operand:CC 0 "register_operand" "=b")
2097         (lt:CC (match_operand:SF 1 "register_operand" "f")
2098                (match_operand:SF 2 "register_operand" "f")))]
2099   "TARGET_HARD_FLOAT"
2100   "olt.s\\t%0, %1, %2"
2101   [(set_attr "type"     "farith")
2102    (set_attr "mode"     "BL")
2103    (set_attr "length"   "3")])
2104
2105 (define_insn "sle_sf"
2106   [(set (match_operand:CC 0 "register_operand" "=b")
2107         (le:CC (match_operand:SF 1 "register_operand" "f")
2108                (match_operand:SF 2 "register_operand" "f")))]
2109   "TARGET_HARD_FLOAT"
2110   "ole.s\\t%0, %1, %2"
2111   [(set_attr "type"     "farith")
2112    (set_attr "mode"     "BL")
2113    (set_attr "length"   "3")])
2114
2115
2116 ;;
2117 ;;  ....................
2118 ;;
2119 ;;      UNCONDITIONAL BRANCHES
2120 ;;
2121 ;;  ....................
2122 ;;
2123
2124 (define_insn "jump"
2125   [(set (pc)
2126         (label_ref (match_operand 0 "" "")))]
2127   ""
2128   "j\\t%l0"
2129   [(set_attr "type"     "jump")
2130    (set_attr "mode"     "none")
2131    (set_attr "length"   "3")])
2132
2133 (define_expand "indirect_jump"
2134   [(set (pc) (match_operand 0 "register_operand" ""))]
2135   ""
2136   "
2137 {
2138   rtx dest = operands[0];
2139   if (GET_CODE (dest) != REG || GET_MODE (dest) != Pmode)
2140     operands[0] = copy_to_mode_reg (Pmode, dest);
2141
2142   emit_jump_insn (gen_indirect_jump_internal (dest));
2143   DONE;
2144 }")
2145
2146 (define_insn "indirect_jump_internal"
2147   [(set (pc) (match_operand:SI 0 "register_operand" "r"))]
2148   ""
2149   "jx\\t%0"
2150   [(set_attr "type"     "jump")
2151    (set_attr "mode"     "none")
2152    (set_attr "length"   "3")])
2153
2154
2155 (define_expand "tablejump"
2156   [(use (match_operand:SI 0 "register_operand" ""))
2157    (use (label_ref (match_operand 1 "" "")))]
2158    ""
2159    "
2160 {
2161   rtx target = operands[0];
2162   if (flag_pic)
2163     {
2164       /* For PIC, the table entry is relative to the start of the table. */
2165       rtx label = gen_reg_rtx (SImode);
2166       target = gen_reg_rtx (SImode);
2167       emit_move_insn (label, gen_rtx_LABEL_REF (SImode, operands[1]));
2168       emit_insn (gen_addsi3 (target, operands[0], label));
2169     }
2170   emit_jump_insn (gen_tablejump_internal (target, operands[1]));
2171   DONE;
2172 }")
2173
2174 (define_insn "tablejump_internal"
2175   [(set (pc)
2176         (match_operand:SI 0 "register_operand" "r"))
2177    (use (label_ref (match_operand 1 "" "")))]
2178   ""
2179   "jx\\t%0"
2180   [(set_attr "type"     "jump")
2181    (set_attr "mode"     "none")
2182    (set_attr "length"   "3")])
2183
2184
2185 ;;
2186 ;;  ....................
2187 ;;
2188 ;;      FUNCTION CALLS
2189 ;;
2190 ;;  ....................
2191 ;;
2192
2193 (define_expand "sym_PLT"
2194   [(const (unspec [(match_operand:SI 0 "" "")] UNSPEC_PLT))]
2195   ""
2196   "")
2197
2198 (define_expand "call"
2199   [(call (match_operand 0 "memory_operand" "")
2200          (match_operand 1 "" ""))]
2201   ""
2202   "
2203 {
2204   rtx addr = XEXP (operands[0], 0);
2205   if (flag_pic && GET_CODE (addr) == SYMBOL_REF && !SYMBOL_REF_LOCAL_P (addr))
2206     addr = gen_sym_PLT (addr);
2207   if (!call_insn_operand (addr, VOIDmode))
2208     XEXP (operands[0], 0) = copy_to_mode_reg (Pmode, addr);
2209 }")
2210
2211 (define_insn "call_internal"
2212   [(call (mem (match_operand:SI 0 "call_insn_operand" "n,i,r"))
2213          (match_operand 1 "" "i,i,i"))]
2214   ""
2215   "*
2216     return xtensa_emit_call (0, operands);
2217   "
2218   [(set_attr "type"     "call")
2219    (set_attr "mode"     "none")
2220    (set_attr "length"   "3")])
2221
2222 (define_expand "call_value"
2223   [(set (match_operand 0 "register_operand" "")
2224         (call (match_operand 1 "memory_operand" "")
2225               (match_operand 2 "" "")))]
2226   ""
2227   "
2228 {
2229   rtx addr = XEXP (operands[1], 0);
2230   if (flag_pic && GET_CODE (addr) == SYMBOL_REF && !SYMBOL_REF_LOCAL_P (addr))
2231     addr = gen_sym_PLT (addr);
2232   if (!call_insn_operand (addr, VOIDmode))
2233     XEXP (operands[1], 0) = copy_to_mode_reg (Pmode, addr);
2234 }")
2235
2236 ;; cannot combine constraints for operand 0 into "afvb"
2237 ;; reload.c:find_reloads seems to assume that grouped constraints somehow
2238 ;; specify related register classes, and when they don't the constraints
2239 ;; fail to match. By not grouping the constraints, we get the correct
2240 ;; behavior.
2241 (define_insn "call_value_internal"
2242    [(set (match_operand 0 "register_operand" "=af,af,af,v,v,v,b,b,b")
2243          (call (mem (match_operand:SI 1 "call_insn_operand"
2244                                         "n,i,r,n,i,r,n,i,r"))
2245                (match_operand 2 "" "i,i,i,i,i,i,i,i,i")))]
2246   ""
2247   "*
2248     return xtensa_emit_call (1, operands);
2249   "
2250   [(set_attr "type"     "call")
2251    (set_attr "mode"     "none")
2252    (set_attr "length"   "3")])
2253
2254 (define_insn "entry"
2255   [(set (reg:SI A1_REG)
2256         (unspec_volatile:SI [(match_operand:SI 0 "const_int_operand" "i")
2257                              (match_operand:SI 1 "const_int_operand" "i")]
2258                             UNSPECV_ENTRY))]
2259   ""
2260   "*
2261 {
2262   if (frame_pointer_needed)
2263     output_asm_insn (\".frame\\ta7, %0\", operands);
2264   else
2265     output_asm_insn (\".frame\\tsp, %0\", operands);
2266   return \"entry\\tsp, %1\";
2267 }"
2268   [(set_attr "type"     "move")
2269    (set_attr "mode"     "SI")
2270    (set_attr "length"   "3")])
2271
2272 (define_insn "return"
2273   [(return)
2274    (use (reg:SI A0_REG))]
2275   "reload_completed"
2276   "*
2277 {
2278   return (TARGET_DENSITY ? \"retw.n\" : \"retw\");
2279 }"
2280   [(set_attr "type"     "jump")
2281    (set_attr "mode"     "none")
2282    (set_attr "length"   "2")])
2283
2284
2285 ;;
2286 ;;  ....................
2287 ;;
2288 ;;      MISC.
2289 ;;
2290 ;;  ....................
2291 ;;
2292
2293 (define_expand "prologue"
2294   [(const_int 0)]
2295   ""
2296   "
2297 {
2298   xtensa_expand_prologue ();
2299   DONE;
2300 }")
2301
2302 (define_expand "epilogue"
2303   [(return)]
2304   ""
2305   "
2306 {
2307   emit_jump_insn (gen_return ());
2308   DONE;
2309 }")
2310
2311 (define_insn "nop"
2312   [(const_int 0)]
2313   ""
2314   "*
2315 {
2316   return (TARGET_DENSITY ? \"nop.n\" : \"nop\");
2317 }"
2318   [(set_attr "type"     "nop")
2319    (set_attr "mode"     "none")
2320    (set_attr "length"   "3")])
2321
2322 (define_expand "nonlocal_goto"
2323   [(match_operand:SI 0 "general_operand" "")
2324    (match_operand:SI 1 "general_operand" "")
2325    (match_operand:SI 2 "general_operand" "")
2326    (match_operand:SI 3 "" "")]
2327   ""
2328   "
2329 {
2330   xtensa_expand_nonlocal_goto (operands);
2331   DONE;
2332 }")
2333
2334 ;; Setting up a frame pointer is tricky for Xtensa because GCC doesn't
2335 ;; know if a frame pointer is required until the reload pass, and
2336 ;; because there may be an incoming argument value in the hard frame
2337 ;; pointer register (a7). If there is an incoming argument in that
2338 ;; register, the "set_frame_ptr" insn gets inserted immediately after
2339 ;; the insn that copies the incoming argument to a pseudo or to the
2340 ;; stack.  This serves several purposes here: (1) it keeps the
2341 ;; optimizer from copy-propagating or scheduling the use of a7 as an
2342 ;; incoming argument away from the beginning of the function; (2) we
2343 ;; can use a post-reload splitter to expand away the insn if a frame
2344 ;; pointer is not required, so that the post-reload scheduler can do
2345 ;; the right thing; and (3) it makes it easy for xtensa_reorg() to
2346 ;; search for this insn to determine whether it should add a new insn
2347 ;; to set up the frame pointer.
2348
2349 (define_insn "set_frame_ptr"
2350   [(set (reg:SI A7_REG) (unspec_volatile:SI [(const_int 0)] UNSPECV_SET_FP))]
2351   ""
2352   "*
2353 {
2354   if (frame_pointer_needed)
2355     return \"mov\\ta7, sp\";
2356   return \"\";
2357 }"
2358   [(set_attr "type"     "move")
2359    (set_attr "mode"     "SI")
2360    (set_attr "length"   "3")])
2361
2362 ;; Post-reload splitter to remove fp assignment when it's not needed.
2363 (define_split
2364   [(set (reg:SI A7_REG) (unspec_volatile:SI [(const_int 0)] UNSPECV_SET_FP))]
2365   "reload_completed && !frame_pointer_needed"
2366   [(unspec [(const_int 0)] UNSPEC_NOP)]
2367   "")
2368
2369 ;; The preceding splitter needs something to split the insn into;
2370 ;; things start breaking if the result is just a "use" so instead we
2371 ;; generate the following insn.
2372 (define_insn "*unspec_nop"
2373   [(unspec [(const_int 0)] UNSPEC_NOP)]
2374   ""
2375   ""
2376   [(set_attr "type"     "nop")
2377    (set_attr "mode"     "none")
2378    (set_attr "length"   "0")])
2379
2380 ;; The fix_return_addr pattern sets the high 2 bits of an address in a
2381 ;; register to match the high bits of the current PC.
2382
2383 (define_insn "fix_return_addr"
2384   [(set (match_operand:SI 0 "register_operand" "=a")
2385         (unspec:SI [(match_operand:SI 1 "register_operand" "r")]
2386                    UNSPEC_RET_ADDR))
2387    (clobber (match_scratch:SI 2 "=r"))
2388    (clobber (match_scratch:SI 3 "=r"))]
2389   ""
2390   "mov\\t%2, a0\;call0\\t0f\;.align\\t4\;0:\;mov\\t%3, a0\;mov\\ta0, %2\;\
2391 srli\\t%3, %3, 30\;slli\\t%0, %1, 2\;ssai\\t2\;src\\t%0, %3, %0"
2392   [(set_attr "type"     "multi")
2393    (set_attr "mode"     "SI")
2394    (set_attr "length"   "24")])
2395
2396
2397 ;;
2398 ;;  ....................
2399 ;;
2400 ;;      BOOLEANS
2401 ;;
2402 ;;  ....................
2403 ;;
2404
2405 ;; branch patterns
2406
2407 (define_insn "*booltrue"
2408   [(set (pc)
2409         (if_then_else (match_operator 2 "boolean_operator"
2410                          [(match_operand:CC 0 "register_operand" "b")
2411                           (const_int 0)])
2412                       (label_ref (match_operand 1 "" ""))
2413                       (pc)))]
2414   "TARGET_BOOLEANS"
2415   "*
2416 {
2417   if (GET_CODE (operands[2]) == EQ)
2418     return \"bf\\t%0, %1\";
2419   else
2420     return \"bt\\t%0, %1\";
2421 }"
2422   [(set_attr "type"     "jump")
2423    (set_attr "mode"     "none")
2424    (set_attr "length"   "3")])
2425
2426 (define_insn "*boolfalse"
2427   [(set (pc)
2428         (if_then_else (match_operator 2 "boolean_operator"
2429                          [(match_operand:CC 0 "register_operand" "b")
2430                           (const_int 0)])
2431                       (pc)
2432                       (label_ref (match_operand 1 "" ""))))]
2433   "TARGET_BOOLEANS"
2434   "*
2435 {
2436   if (GET_CODE (operands[2]) == EQ)
2437     return \"bt\\t%0, %1\";
2438   else
2439     return \"bf\\t%0, %1\";
2440 }"
2441   [(set_attr "type"     "jump")
2442    (set_attr "mode"     "none")
2443    (set_attr "length"   "3")])