OSDN Git Service

* config/xtensa/xtensa.md: Remove unused type attributes.
[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   (A7_REG               7)
33
34   (UNSPEC_NSAU          1)
35   (UNSPEC_NOP           2)
36   (UNSPEC_PLT           3)
37   (UNSPECV_SET_FP       1)
38 ])
39
40 ;;
41 ;; ....................
42 ;;
43 ;;      ATTRIBUTES
44 ;;
45 ;; ....................
46 ;;
47
48 (define_attr "type"
49   "unknown,jump,call,load,store,move,arith,multi,nop,farith,fmadd,fdiv,fsqrt,fconv,fload,fstore,mul16,mul32,div32,mac16,rsr,wsr"
50   (const_string "unknown"))
51
52 (define_attr "mode"
53   "unknown,none,QI,HI,SI,DI,SF,DF,BL"
54   (const_string "unknown"))
55
56 (define_attr "length" "" (const_int 1))
57
58 ;; Describe a user's asm statement.
59 (define_asm_attributes
60   [(set_attr "type" "multi")])
61
62
63 ;;
64 ;; ....................
65 ;;
66 ;;      FUNCTIONAL UNITS
67 ;;
68 ;; ....................
69 ;;
70
71 (define_function_unit "memory" 1 0 (eq_attr "type" "load,fload") 2 0)
72
73 (define_function_unit "sreg" 1 1 (eq_attr "type" "rsr") 2 0)
74
75 (define_function_unit "mul16" 1 0 (eq_attr "type" "mul16") 2 0)
76
77 (define_function_unit "mul32" 1 0 (eq_attr "type" "mul32") 2 0)
78
79 (define_function_unit "fpmadd" 1 0 (eq_attr "type" "fmadd") 4 0)
80
81 (define_function_unit "fpconv" 1 0 (eq_attr "type" "fconv") 2 0)
82
83
84 ;;
85 ;;  ....................
86 ;;
87 ;;      ADDITION
88 ;;
89 ;;  ....................
90 ;;
91
92 (define_expand "adddi3"
93   [(set (match_operand:DI 0 "register_operand" "")
94         (plus:DI (match_operand:DI 1 "register_operand" "")
95                  (match_operand:DI 2 "register_operand" "")))]
96   ""
97   "
98 {
99   rtx dstlo = gen_lowpart (SImode, operands[0]);
100   rtx src1lo = gen_lowpart (SImode, operands[1]);
101   rtx src2lo = gen_lowpart (SImode, operands[2]);
102
103   rtx dsthi = gen_highpart (SImode, operands[0]);
104   rtx src1hi = gen_highpart (SImode, operands[1]);
105   rtx src2hi = gen_highpart (SImode, operands[2]);
106
107   emit_insn (gen_addsi3 (dstlo, src1lo, src2lo));
108   emit_insn (gen_addsi3 (dsthi, src1hi, src2hi));
109   emit_insn (gen_adddi_carry (dsthi, dstlo, src2lo));
110   DONE;
111 }")
112
113 ;; Represent the add-carry operation as an atomic operation instead of
114 ;; expanding it to a conditional branch.  Otherwise, the edge
115 ;; profiling code breaks because inserting the count increment code
116 ;; causes a new jump insn to be added.
117
118 (define_insn "adddi_carry"
119   [(set (match_operand:SI 0 "register_operand" "+a")
120         (plus:SI (ltu:SI (match_operand:SI 1 "register_operand" "r")
121                          (match_operand:SI 2 "register_operand" "r"))
122                  (match_dup 0)))]
123   ""
124   "bgeu\\t%1, %2, 0f\;addi\\t%0, %0, 1\;0:"
125   [(set_attr "type"     "multi")
126    (set_attr "mode"     "SI")
127    (set_attr "length"   "6")])
128
129 (define_insn "addsi3"
130   [(set (match_operand:SI 0 "register_operand" "=D,D,a,a,a")
131         (plus:SI (match_operand:SI 1 "register_operand" "%d,d,r,r,r")
132                  (match_operand:SI 2 "add_operand" "d,O,r,J,N")))]
133   ""
134   "@
135    add.n\\t%0, %1, %2
136    addi.n\\t%0, %1, %d2
137    add\\t%0, %1, %2
138    addi\\t%0, %1, %d2
139    addmi\\t%0, %1, %x2"
140   [(set_attr "type"     "arith,arith,arith,arith,arith")
141    (set_attr "mode"     "SI")
142    (set_attr "length"   "2,2,3,3,3")])
143
144 (define_insn ""
145   [(set (match_operand:SI 0 "register_operand" "=a")
146         (plus:SI (mult:SI (match_operand:SI 1 "register_operand" "r")
147                           (const_int 2))
148                  (match_operand:SI 2 "register_operand" "r")))]
149   ""
150   "addx2\\t%0, %1, %2"
151   [(set_attr "type"     "arith")
152    (set_attr "mode"     "SI")
153    (set_attr "length"   "3")])
154
155 (define_insn ""
156   [(set (match_operand:SI 0 "register_operand" "=a")
157         (plus:SI (mult:SI (match_operand:SI 1 "register_operand" "r")
158                           (const_int 4))
159                  (match_operand:SI 2 "register_operand" "r")))]
160   ""
161   "addx4\\t%0, %1, %2"
162   [(set_attr "type"     "arith")
163    (set_attr "mode"     "SI")
164    (set_attr "length"   "3")])
165
166 (define_insn ""
167   [(set (match_operand:SI 0 "register_operand" "=a")
168         (plus:SI (mult:SI (match_operand:SI 1 "register_operand" "r")
169                           (const_int 8))
170                  (match_operand:SI 2 "register_operand" "r")))]
171   ""
172   "addx8\\t%0, %1, %2"
173   [(set_attr "type"     "arith")
174    (set_attr "mode"     "SI")
175    (set_attr "length"   "3")])
176
177 (define_insn "addsf3"
178   [(set (match_operand:SF 0 "register_operand" "=f")
179         (plus:SF (match_operand:SF 1 "register_operand" "%f")
180                  (match_operand:SF 2 "register_operand" "f")))]
181   "TARGET_HARD_FLOAT"
182   "add.s\\t%0, %1, %2"
183   [(set_attr "type"     "fmadd")
184    (set_attr "mode"     "SF")
185    (set_attr "length"   "3")])
186
187
188 ;;
189 ;;  ....................
190 ;;
191 ;;      SUBTRACTION
192 ;;
193 ;;  ....................
194 ;;
195
196 (define_expand "subdi3"
197   [(set (match_operand:DI 0 "register_operand" "")
198         (minus:DI (match_operand:DI 1 "register_operand" "")
199                   (match_operand:DI 2 "register_operand" "")))]
200   ""
201   "
202 {
203   rtx dstlo = gen_lowpart (SImode, operands[0]);
204   rtx src1lo = gen_lowpart (SImode, operands[1]);
205   rtx src2lo = gen_lowpart (SImode, operands[2]);
206
207   rtx dsthi = gen_highpart (SImode, operands[0]);
208   rtx src1hi = gen_highpart (SImode, operands[1]);
209   rtx src2hi = gen_highpart (SImode, operands[2]);
210
211   emit_insn (gen_subsi3 (dstlo, src1lo, src2lo));
212   emit_insn (gen_subsi3 (dsthi, src1hi, src2hi));
213   emit_insn (gen_subdi_carry (dsthi, src1lo, src2lo));
214   DONE;
215 }")
216
217 (define_insn "subdi_carry"
218   [(set (match_operand:SI 0 "register_operand" "+a")
219         (minus:SI (match_dup 0)
220                   (ltu:SI (match_operand:SI 1 "register_operand" "r")
221                           (match_operand:SI 2 "register_operand" "r"))))]
222   ""
223   "bgeu\\t%1, %2, 0f\;addi\\t%0, %0, -1\;0:"
224   [(set_attr "type"     "multi")
225    (set_attr "mode"     "SI")
226    (set_attr "length"   "6")])
227
228 (define_insn "subsi3"
229   [(set (match_operand:SI 0 "register_operand" "=a")
230         (minus:SI (match_operand:SI 1 "register_operand" "r")
231                   (match_operand:SI 2 "register_operand" "r")))]
232   ""
233   "sub\\t%0, %1, %2"
234   [(set_attr "type"     "arith")
235    (set_attr "mode"     "SI")
236    (set_attr "length"   "3")])
237
238 (define_insn ""
239   [(set (match_operand:SI 0 "register_operand" "=a")
240         (minus:SI (mult:SI (match_operand:SI 1 "register_operand" "r")
241                            (const_int 2))
242                   (match_operand:SI 2 "register_operand" "r")))]
243   ""
244   "subx2\\t%0, %1, %2"
245   [(set_attr "type"     "arith")
246    (set_attr "mode"     "SI")
247    (set_attr "length"   "3")])
248
249 (define_insn ""
250   [(set (match_operand:SI 0 "register_operand" "=a")
251         (minus:SI (mult:SI (match_operand:SI 1 "register_operand" "r")
252                            (const_int 4))
253                   (match_operand:SI 2 "register_operand" "r")))]
254   ""
255   "subx4\\t%0, %1, %2"
256   [(set_attr "type"     "arith")
257    (set_attr "mode"     "SI")
258    (set_attr "length"   "3")])
259
260 (define_insn ""
261   [(set (match_operand:SI 0 "register_operand" "=a")
262         (minus:SI (mult:SI (match_operand:SI 1 "register_operand" "r")
263                            (const_int 8))
264                   (match_operand:SI 2 "register_operand" "r")))]
265   ""
266   "subx8\\t%0, %1, %2"
267   [(set_attr "type"     "arith")
268    (set_attr "mode"     "SI")
269    (set_attr "length"   "3")])
270
271 (define_insn "subsf3"
272   [(set (match_operand:SF 0 "register_operand" "=f")
273         (minus:SF (match_operand:SF 1 "register_operand" "f")
274                   (match_operand:SF 2 "register_operand" "f")))]
275   "TARGET_HARD_FLOAT"
276   "sub.s\\t%0, %1, %2"
277   [(set_attr "type"     "fmadd")
278    (set_attr "mode"     "SF")
279    (set_attr "length"   "3")])
280
281
282 ;;
283 ;;  ....................
284 ;;
285 ;;      MULTIPLICATION
286 ;;
287 ;;  ....................
288 ;;
289
290 (define_insn "mulsi3"
291   [(set (match_operand:SI 0 "register_operand" "=a")
292         (mult:SI (match_operand:SI 1 "register_operand" "%r")
293                  (match_operand:SI 2 "register_operand" "r")))]
294   "TARGET_MUL32"
295   "mull\\t%0, %1, %2"
296   [(set_attr "type"     "mul32")
297    (set_attr "mode"     "SI")
298    (set_attr "length"   "3")])
299
300 (define_insn "mulhisi3"
301   [(set (match_operand:SI 0 "register_operand" "=C,A")
302         (mult:SI (sign_extend:SI
303                   (match_operand:HI 1 "register_operand" "%r,r"))
304                  (sign_extend:SI
305                   (match_operand:HI 2 "register_operand" "r,r"))))]
306   "TARGET_MUL16 || TARGET_MAC16"
307   "@
308    mul16s\\t%0, %1, %2
309    mul.aa.ll\\t%1, %2"
310   [(set_attr "type"     "mul16,mac16")
311    (set_attr "mode"     "SI")
312    (set_attr "length"   "3,3")])
313
314 (define_insn "umulhisi3"
315   [(set (match_operand:SI 0 "register_operand" "=C,A")
316         (mult:SI (zero_extend:SI
317                   (match_operand:HI 1 "register_operand" "%r,r"))
318                  (zero_extend:SI
319                   (match_operand:HI 2 "register_operand" "r,r"))))]
320   "TARGET_MUL16 || TARGET_MAC16"
321   "@
322    mul16u\\t%0, %1, %2
323    umul.aa.ll\\t%1, %2"
324   [(set_attr "type"     "mul16,mac16")
325    (set_attr "mode"     "SI")
326    (set_attr "length"   "3,3")])
327
328 (define_insn "muladdhisi"
329   [(set (match_operand:SI 0 "register_operand" "=A")
330         (plus:SI (mult:SI (sign_extend:SI
331                            (match_operand:HI 1 "register_operand" "%r"))
332                           (sign_extend:SI
333                            (match_operand:HI 2 "register_operand" "r")))
334                  (match_operand:SI 3 "register_operand" "0")))]
335   "TARGET_MAC16"
336   "mula.aa.ll\\t%1, %2"
337   [(set_attr "type"     "mac16")
338    (set_attr "mode"     "SI")
339    (set_attr "length"   "3")])
340
341 (define_insn "mulsubhisi"
342   [(set (match_operand:SI 0 "register_operand" "=A")
343         (minus:SI (match_operand:SI 1 "register_operand" "0")
344                   (mult:SI (sign_extend:SI
345                             (match_operand:HI 2 "register_operand" "%r"))
346                            (sign_extend:SI
347                             (match_operand:HI 3 "register_operand" "r")))))]
348   "TARGET_MAC16"
349   "muls.aa.ll\\t%2, %3"
350   [(set_attr "type"     "mac16")
351    (set_attr "mode"     "SI")
352    (set_attr "length"   "3")])
353
354 (define_insn "mulsf3"
355   [(set (match_operand:SF 0 "register_operand" "=f")
356         (mult:SF (match_operand:SF 1 "register_operand" "%f")
357                  (match_operand:SF 2 "register_operand" "f")))]
358   "TARGET_HARD_FLOAT"
359   "mul.s\\t%0, %1, %2"
360   [(set_attr "type"     "fmadd")
361    (set_attr "mode"     "SF")
362    (set_attr "length"   "3")])
363
364 (define_insn "muladdsf3"
365   [(set (match_operand:SF 0 "register_operand" "=f")
366         (plus:SF (mult:SF (match_operand:SF 1 "register_operand" "%f")
367                           (match_operand:SF 2 "register_operand" "f"))
368                  (match_operand:SF 3 "register_operand" "0")))]
369   "TARGET_HARD_FLOAT && !TARGET_NO_FUSED_MADD"
370   "madd.s\\t%0, %1, %2"
371   [(set_attr "type"     "fmadd")
372    (set_attr "mode"     "SF")
373    (set_attr "length"   "3")])
374
375 (define_insn "mulsubsf3"
376   [(set (match_operand:SF 0 "register_operand" "=f")
377         (minus:SF (match_operand:SF 1 "register_operand" "0")
378                   (mult:SF (match_operand:SF 2 "register_operand" "%f")
379                            (match_operand:SF 3 "register_operand" "f"))))]
380   "TARGET_HARD_FLOAT && !TARGET_NO_FUSED_MADD"
381   "msub.s\\t%0, %2, %3"
382   [(set_attr "type"     "fmadd")
383    (set_attr "mode"     "SF")
384    (set_attr "length"   "3")])
385
386
387 ;;
388 ;;  ....................
389 ;;
390 ;;      DIVISION
391 ;;
392 ;;  ....................
393 ;;
394
395 (define_insn "divsi3"
396   [(set (match_operand:SI 0 "register_operand" "=a")
397         (div:SI (match_operand:SI 1 "register_operand" "r")
398                 (match_operand:SI 2 "register_operand" "r")))]
399   "TARGET_DIV32"
400   "quos\\t%0, %1, %2"
401   [(set_attr "type"     "div32")
402    (set_attr "mode"     "SI")
403    (set_attr "length"   "3")])
404
405 (define_insn "udivsi3"
406   [(set (match_operand:SI 0 "register_operand" "=a")
407         (udiv:SI (match_operand:SI 1 "register_operand" "r")
408                  (match_operand:SI 2 "register_operand" "r")))]
409   "TARGET_DIV32"
410   "quou\\t%0, %1, %2"
411   [(set_attr "type"     "div32")
412    (set_attr "mode"     "SI")
413    (set_attr "length"   "3")])
414
415 (define_insn "divsf3"
416   [(set (match_operand:SF 0 "register_operand" "=f")
417         (div:SF (match_operand:SF 1 "register_operand" "f")
418                 (match_operand:SF 2 "register_operand" "f")))]
419   "TARGET_HARD_FLOAT_DIV"
420   "div.s\\t%0, %1, %2"
421   [(set_attr "type"     "fdiv")
422    (set_attr "mode"     "SF")
423    (set_attr "length"   "3")])
424
425 (define_insn ""
426   [(set (match_operand:SF 0 "register_operand" "=f")
427         (div:SF (match_operand:SF 1 "const_float_1_operand" "")
428                 (match_operand:SF 2 "register_operand" "f")))]
429   "TARGET_HARD_FLOAT_RECIP && flag_unsafe_math_optimizations"
430   "recip.s\\t%0, %2"
431   [(set_attr "type"     "fdiv")
432    (set_attr "mode"     "SF")
433    (set_attr "length"   "3")])
434
435
436 ;;
437 ;;  ....................
438 ;;
439 ;;      REMAINDER
440 ;;
441 ;;  ....................
442 ;;
443
444 (define_insn "modsi3"
445   [(set (match_operand:SI 0 "register_operand" "=a")
446         (mod:SI (match_operand:SI 1 "register_operand" "r")
447                 (match_operand:SI 2 "register_operand" "r")))]
448   "TARGET_DIV32"
449   "rems\\t%0, %1, %2"
450   [(set_attr "type"     "div32")
451    (set_attr "mode"     "SI")
452    (set_attr "length"   "3")])
453
454 (define_insn "umodsi3"
455   [(set (match_operand:SI 0 "register_operand" "=a")
456         (umod:SI (match_operand:SI 1 "register_operand" "r")
457                  (match_operand:SI 2 "register_operand" "r")))]
458   "TARGET_DIV32"
459   "remu\\t%0, %1, %2"
460   [(set_attr "type"     "div32")
461    (set_attr "mode"     "SI")
462    (set_attr "length"   "3")])
463
464
465 ;;
466 ;;  ....................
467 ;;
468 ;;      SQUARE ROOT
469 ;;
470 ;;  ....................
471 ;;
472
473 (define_insn "sqrtsf2"
474   [(set (match_operand:SF 0 "register_operand" "=f")
475         (sqrt:SF (match_operand:SF 1 "register_operand" "f")))]
476   "TARGET_HARD_FLOAT_SQRT"
477   "sqrt.s\\t%0, %1"
478   [(set_attr "type"     "fsqrt")
479    (set_attr "mode"     "SF")
480    (set_attr "length"   "3")])
481
482 (define_insn ""
483   [(set (match_operand:SF 0 "register_operand" "=f")
484         (div:SF (match_operand:SF 1 "const_float_1_operand" "")
485                 (sqrt:SF (match_operand:SF 2 "register_operand" "f"))))]
486   "TARGET_HARD_FLOAT_RSQRT && flag_unsafe_math_optimizations"
487   "rsqrt.s\\t%0, %2"
488   [(set_attr "type"     "fsqrt")
489    (set_attr "mode"     "SF")
490    (set_attr "length"   "3")])
491
492
493 ;;
494 ;;  ....................
495 ;;
496 ;;      ABSOLUTE VALUE
497 ;;
498 ;;  ....................
499 ;;
500
501 (define_insn "abssi2"
502   [(set (match_operand:SI 0 "register_operand" "=a")
503         (abs:SI (match_operand:SI 1 "register_operand" "r")))]
504   ""
505   "abs\\t%0, %1"
506   [(set_attr "type"     "arith")
507    (set_attr "mode"     "SI")
508    (set_attr "length"   "3")])
509
510 (define_insn "abssf2"
511   [(set (match_operand:SF 0 "register_operand" "=f")
512         (abs:SF (match_operand:SF 1 "register_operand" "f")))]
513   "TARGET_HARD_FLOAT"
514   "abs.s\\t%0, %1"
515   [(set_attr "type"     "farith")
516    (set_attr "mode"     "SF")
517    (set_attr "length"   "3")])
518
519
520 ;;
521 ;;  ....................
522 ;;
523 ;;      MIN AND MAX INSTRUCTIONS
524 ;;
525 ;;  ....................
526 ;;
527
528 (define_insn "sminsi3"
529   [(set (match_operand:SI 0 "register_operand" "=a")
530         (smin:SI (match_operand:SI 1 "register_operand" "%r")
531                  (match_operand:SI 2 "register_operand" "r")))]
532   "TARGET_MINMAX"
533   "min\\t%0, %1, %2"
534   [(set_attr "type"     "arith")
535    (set_attr "mode"     "SI")
536    (set_attr "length"   "3")])
537
538 (define_insn "uminsi3"
539   [(set (match_operand:SI 0 "register_operand" "=a")
540         (umin:SI (match_operand:SI 1 "register_operand" "%r")
541                  (match_operand:SI 2 "register_operand" "r")))]
542   "TARGET_MINMAX"
543   "minu\\t%0, %1, %2"
544   [(set_attr "type"     "arith")
545    (set_attr "mode"     "SI")
546    (set_attr "length"   "3")])
547
548 (define_insn "smaxsi3"
549   [(set (match_operand:SI 0 "register_operand" "=a")
550         (smax:SI (match_operand:SI 1 "register_operand" "%r")
551                  (match_operand:SI 2 "register_operand" "r")))]
552   "TARGET_MINMAX"
553   "max\\t%0, %1, %2"
554   [(set_attr "type"     "arith")
555    (set_attr "mode"     "SI")
556    (set_attr "length"   "3")])
557
558 (define_insn "umaxsi3"
559   [(set (match_operand:SI 0 "register_operand" "=a")
560         (umax:SI (match_operand:SI 1 "register_operand" "%r")
561                  (match_operand:SI 2 "register_operand" "r")))]
562   "TARGET_MINMAX"
563   "maxu\\t%0, %1, %2"
564   [(set_attr "type"     "arith")
565    (set_attr "mode"     "SI")
566    (set_attr "length"   "3")])
567
568
569 ;;
570 ;;  ....................
571 ;;
572 ;;      FIND FIRST BIT INSTRUCTION
573 ;;
574 ;;  ....................
575 ;;
576
577 (define_expand "ffssi2"
578   [(set (match_operand:SI 0 "register_operand" "")
579         (ffs:SI (match_operand:SI 1 "register_operand" "")))]
580   "TARGET_NSA"
581   "
582 {
583   rtx temp = gen_reg_rtx (SImode);
584   emit_insn (gen_negsi2 (temp, operands[1]));
585   emit_insn (gen_andsi3 (temp, temp, operands[1]));
586   emit_insn (gen_nsau (temp, temp));
587   emit_insn (gen_negsi2 (temp, temp));
588   emit_insn (gen_addsi3 (operands[0], temp, GEN_INT (32)));
589   DONE;
590 }")
591
592 ;; there is no RTL operator corresponding to NSAU
593 (define_insn "nsau"
594   [(set (match_operand:SI 0 "register_operand" "=a")
595         (unspec:SI [(match_operand:SI 1 "register_operand" "r")] UNSPEC_NSAU))]
596   "TARGET_NSA"
597   "nsau\\t%0, %1"
598   [(set_attr "type"     "arith")
599    (set_attr "mode"     "SI")
600    (set_attr "length"   "3")])
601
602
603 ;;
604 ;;  ....................
605 ;;
606 ;;      NEGATION and ONE'S COMPLEMENT
607 ;;
608 ;;  ....................
609 ;;
610
611 (define_insn "negsi2"
612   [(set (match_operand:SI 0 "register_operand" "=a")
613         (neg:SI (match_operand:SI 1 "register_operand" "r")))]
614   ""
615   "neg\\t%0, %1"
616   [(set_attr "type"     "arith")
617    (set_attr "mode"     "SI")
618    (set_attr "length"   "3")])
619
620 (define_expand "one_cmplsi2"
621   [(set (match_operand:SI 0 "register_operand" "")
622         (not:SI (match_operand:SI 1 "register_operand" "")))]
623   ""
624   "
625 {
626   rtx temp = gen_reg_rtx (SImode);
627   emit_insn (gen_movsi (temp, constm1_rtx));
628   emit_insn (gen_xorsi3 (operands[0], temp, operands[1]));
629   DONE;
630 }")
631
632 (define_insn "negsf2"
633   [(set (match_operand:SF 0 "register_operand" "=f")
634         (neg:SF (match_operand:SF 1 "register_operand" "f")))]
635   "TARGET_HARD_FLOAT"
636   "neg.s\\t%0, %1"
637   [(set_attr "type"     "farith")
638    (set_attr "mode"     "SF")
639    (set_attr "length"   "3")])
640
641
642 ;;
643 ;;  ....................
644 ;;
645 ;;      LOGICAL
646 ;;
647 ;;  ....................
648 ;;
649
650 (define_insn "andsi3"
651   [(set (match_operand:SI 0 "register_operand" "=a,a")
652         (and:SI (match_operand:SI 1 "register_operand" "%r,r")
653                 (match_operand:SI 2 "mask_operand" "P,r")))]
654   ""
655   "@
656    extui\\t%0, %1, 0, %K2
657    and\\t%0, %1, %2"
658   [(set_attr "type"     "arith,arith")
659    (set_attr "mode"     "SI")
660    (set_attr "length"   "3,3")])
661
662 (define_insn "iorsi3"
663   [(set (match_operand:SI 0 "register_operand" "=a")
664         (ior:SI (match_operand:SI 1 "register_operand" "%r")
665                 (match_operand:SI 2 "register_operand" "r")))]
666   ""
667   "or\\t%0, %1, %2"
668   [(set_attr "type"     "arith")
669    (set_attr "mode"     "SI")
670    (set_attr "length"   "3")])
671
672 (define_insn "xorsi3"
673   [(set (match_operand:SI 0 "register_operand" "=a")
674         (xor:SI (match_operand:SI 1 "register_operand" "%r")
675                 (match_operand:SI 2 "register_operand" "r")))]
676   ""
677   "xor\\t%0, %1, %2"
678   [(set_attr "type"     "arith")
679    (set_attr "mode"     "SI")
680    (set_attr "length"   "3")])
681
682
683 ;;
684 ;;  ....................
685 ;;
686 ;;      ZERO EXTENSION
687 ;;
688 ;;  ....................
689 ;;
690
691 (define_insn "zero_extendhisi2"
692   [(set (match_operand:SI 0 "register_operand" "=a,a")
693         (zero_extend:SI (match_operand:HI 1 "nonimmed_operand" "r,U")))]
694   ""
695   "@
696    extui\\t%0, %1, 0, 16
697    l16ui\\t%0, %1"
698   [(set_attr "type"     "arith,load")
699    (set_attr "mode"     "SI")
700    (set_attr "length"   "3,3")])
701
702 (define_insn "zero_extendqisi2"
703   [(set (match_operand:SI 0 "register_operand" "=a,a")
704         (zero_extend:SI (match_operand:QI 1 "nonimmed_operand" "r,U")))]
705   ""
706   "@
707    extui\\t%0, %1, 0, 8
708    l8ui\\t%0, %1"
709   [(set_attr "type"     "arith,load")
710    (set_attr "mode"     "SI")
711    (set_attr "length"   "3,3")])
712
713
714 ;;
715 ;;  ....................
716 ;;
717 ;;      SIGN EXTENSION
718 ;;
719 ;;  ....................
720 ;;
721
722 (define_expand "extendhisi2"
723   [(set (match_operand:SI 0 "register_operand" "")
724         (sign_extend:SI (match_operand:HI 1 "register_operand" "")))]
725   ""
726   "
727 {
728   if (sext_operand (operands[1], HImode))
729     emit_insn (gen_extendhisi2_internal (operands[0], operands[1]));
730   else
731     xtensa_extend_reg (operands[0], operands[1]);
732   DONE;
733 }")
734
735 (define_insn "extendhisi2_internal"
736   [(set (match_operand:SI 0 "register_operand" "=B,a")
737         (sign_extend:SI (match_operand:HI 1 "sext_operand" "r,U")))]
738   ""
739   "@
740    sext\\t%0, %1, 15
741    l16si\\t%0, %1"
742   [(set_attr "type"     "arith,load")
743    (set_attr "mode"     "SI")
744    (set_attr "length"   "3,3")])
745
746 (define_expand "extendqisi2"
747   [(set (match_operand:SI 0 "register_operand" "")
748         (sign_extend:SI (match_operand:QI 1 "register_operand" "")))]
749   ""
750   "
751 {
752   if (TARGET_SEXT)
753     {
754       emit_insn (gen_extendqisi2_internal (operands[0], operands[1]));
755       DONE;
756     }
757   xtensa_extend_reg (operands[0], operands[1]);
758   DONE;
759 }")
760
761 (define_insn "extendqisi2_internal"
762   [(set (match_operand:SI 0 "register_operand" "=B")
763         (sign_extend:SI (match_operand:QI 1 "register_operand" "r")))]
764   "TARGET_SEXT"
765   "sext\\t%0, %1, 7"
766   [(set_attr "type"     "arith")
767    (set_attr "mode"     "SI")
768    (set_attr "length"   "3")])
769
770
771 ;;
772 ;;  ....................
773 ;;
774 ;;      FIELD EXTRACT
775 ;;
776 ;;  ....................
777 ;;
778
779 (define_expand "extv"
780   [(set (match_operand:SI 0 "register_operand" "")
781         (sign_extract:SI (match_operand:SI 1 "register_operand" "")
782                          (match_operand:SI 2 "const_int_operand" "")
783                          (match_operand:SI 3 "const_int_operand" "")))]
784   "TARGET_SEXT"
785   "
786 {
787   if (!sext_fldsz_operand (operands[2], SImode)) FAIL;
788   /* we could expand to a right shift followed by sext but that's
789      no better than the standard left and right shift sequence */
790   if (!lsbitnum_operand (operands[3], SImode)) FAIL;
791   emit_insn (gen_extv_internal (operands[0], operands[1],
792                                 operands[2], operands[3]));
793   DONE;
794 }")
795
796 (define_insn "extv_internal"
797   [(set (match_operand:SI 0 "register_operand" "=a")
798         (sign_extract:SI (match_operand:SI 1 "register_operand" "r")
799                          (match_operand:SI 2 "sext_fldsz_operand" "i")
800                          (match_operand:SI 3 "lsbitnum_operand" "i")))]
801   "TARGET_SEXT"
802   "*
803 {
804   int fldsz = INTVAL (operands[2]);
805   operands[2] = GEN_INT (fldsz - 1);
806   return \"sext\\t%0, %1, %2\";
807 }"
808   [(set_attr "type"     "arith")
809    (set_attr "mode"     "SI")
810    (set_attr "length"   "3")])
811
812 (define_expand "extzv"
813   [(set (match_operand:SI 0 "register_operand" "")
814         (zero_extract:SI (match_operand:SI 1 "register_operand" "")
815                          (match_operand:SI 2 "const_int_operand" "")
816                          (match_operand:SI 3 "const_int_operand" "")))]
817   ""
818   "
819 {
820   if (!extui_fldsz_operand (operands[2], SImode)) FAIL;
821   emit_insn (gen_extzv_internal (operands[0], operands[1],
822                                  operands[2], operands[3]));
823   DONE;
824 }")
825
826 (define_insn "extzv_internal"
827   [(set (match_operand:SI 0 "register_operand" "=a")
828         (zero_extract:SI (match_operand:SI 1 "register_operand" "r")
829                          (match_operand:SI 2 "extui_fldsz_operand" "i")
830                          (match_operand:SI 3 "const_int_operand" "i")))]
831   ""
832   "*
833 {
834   int shift;
835   if (BITS_BIG_ENDIAN)
836     shift = (32 - (INTVAL (operands[2]) + INTVAL (operands[3]))) & 0x1f;
837   else
838     shift = INTVAL (operands[3]) & 0x1f;
839   operands[3] = GEN_INT (shift);
840   return \"extui\\t%0, %1, %3, %2\";
841 }"
842   [(set_attr "type"     "arith")
843    (set_attr "mode"     "SI")
844    (set_attr "length"   "3")])
845
846
847 ;;
848 ;;  ....................
849 ;;
850 ;;      CONVERSIONS
851 ;;
852 ;;  ....................
853 ;;
854
855 (define_insn "fix_truncsfsi2"
856   [(set (match_operand:SI 0 "register_operand" "=a")
857         (fix:SI (match_operand:SF 1 "register_operand" "f")))]
858   "TARGET_HARD_FLOAT"
859   "trunc.s\\t%0, %1, 0"
860   [(set_attr "type"     "fconv")
861    (set_attr "mode"     "SF")
862    (set_attr "length"   "3")])
863
864 (define_insn "fixuns_truncsfsi2"
865   [(set (match_operand:SI 0 "register_operand" "=a")
866         (unsigned_fix:SI (match_operand:SF 1 "register_operand" "f")))]
867   "TARGET_HARD_FLOAT"
868   "utrunc.s %0, %1, 0"
869   [(set_attr "type"     "fconv")
870    (set_attr "mode"     "SF")
871    (set_attr "length"   "3")])
872
873 (define_insn "floatsisf2"
874   [(set (match_operand:SF 0 "register_operand" "=f")
875         (float:SF (match_operand:SI 1 "register_operand" "a")))]
876   "TARGET_HARD_FLOAT"
877   "float.s\\t%0, %1, 0"
878   [(set_attr "type"     "fconv")
879    (set_attr "mode"     "SF")
880    (set_attr "length"   "3")])
881
882 (define_insn "floatunssisf2"
883   [(set (match_operand:SF 0 "register_operand" "=f")
884         (unsigned_float:SF (match_operand:SI 1 "register_operand" "a")))]
885   "TARGET_HARD_FLOAT"
886   "ufloat.s %0, %1, 0"
887   [(set_attr "type"     "fconv")
888    (set_attr "mode"     "SF")
889    (set_attr "length"   "3")])
890
891
892 ;;
893 ;;  ....................
894 ;;
895 ;;      DATA MOVEMENT
896 ;;
897 ;;  ....................
898 ;;
899
900 ;; 64-bit Integer moves
901
902 (define_expand "movdi"
903   [(set (match_operand:DI 0 "nonimmed_operand" "")
904         (match_operand:DI 1 "general_operand" ""))]
905   ""
906   "
907 {
908   if (CONSTANT_P (operands[1]))
909     {
910       rtx src0, src1, dst0, dst1;
911       if ((dst0 = operand_subword (operands[0], 0, 1, DImode))
912           && (src0 = operand_subword (operands[1], 0, 1, DImode))
913           && (dst1 = operand_subword (operands[0], 1, 1, DImode))
914           && (src1 = operand_subword (operands[1], 1, 1, DImode)))
915         {
916           emit_insn (gen_movsi (dst0, src0));
917           emit_insn (gen_movsi (dst1, src1));
918           DONE;
919         }
920       else
921         /* any other constant will be loaded from memory */
922         operands[1] = force_const_mem (DImode, operands[1]);
923     }
924
925   if (!(reload_in_progress | reload_completed))
926     {
927       if (!register_operand (operands[0], DImode)
928           && !register_operand (operands[1], DImode))
929         operands[1] = force_reg (DImode, operands[1]);
930
931       if (a7_overlap_mentioned_p (operands[1]))
932         {
933           emit_insn (gen_movdi_internal (operands[0], operands[1]));
934           emit_insn (gen_set_frame_ptr ());
935           DONE;
936         }
937     }
938 }")
939
940 (define_insn "movdi_internal"
941   [(set (match_operand:DI 0 "nonimmed_operand" "=D,D,S,a,a,a,U")
942         (match_operand:DI 1 "non_const_move_operand" "d,S,d,r,T,U,r"))]
943   "register_operand (operands[0], DImode)
944    || register_operand (operands[1], DImode)"
945   "*
946 {
947   switch (which_alternative)
948     {
949     case 0: return \"mov.n\\t%0, %1\;mov.n\\t%D0, %D1\";
950     case 2: return \"%v0s32i.n\\t%1, %0\;s32i.n\\t%D1, %N0\";
951     case 3: return \"mov\\t%0, %1\;mov\\t%D0, %D1\";
952     case 6: return \"%v0s32i\\t%1, %0\;s32i\\t%D1, %N0\";
953
954     case 1:
955     case 4:
956     case 5:
957       {
958         /* Check if the first half of the destination register is used
959            in the source address.  If so, reverse the order of the loads
960            so that the source address doesn't get clobbered until it is
961            no longer needed. */
962
963         rtx dstreg = operands[0];
964         if (GET_CODE (dstreg) == SUBREG)
965           dstreg = SUBREG_REG (dstreg);
966         if (GET_CODE (dstreg) != REG)
967           abort();
968
969         if (reg_mentioned_p (dstreg, operands[1]))
970           {
971             switch (which_alternative)
972               {
973               case 1: return \"%v1l32i.n\\t%D0, %N1\;l32i.n\\t%0, %1\";
974               case 4: return \"%v1l32r\\t%D0, %N1\;l32r\\t%0, %1\";
975               case 5: return \"%v1l32i\\t%D0, %N1\;l32i\\t%0, %1\";
976               }
977           }
978         else
979           {
980             switch (which_alternative)
981               {
982               case 1: return \"%v1l32i.n\\t%0, %1\;l32i.n\\t%D0, %N1\";
983               case 4: return \"%v1l32r\\t%0, %1\;l32r\\t%D0, %N1\";
984               case 5: return \"%v1l32i\\t%0, %1\;l32i\\t%D0, %N1\";
985               }
986           }
987       }
988     }
989   abort ();
990   return \"\";
991 }"
992   [(set_attr "type"     "move,load,store,move,load,load,store")
993    (set_attr "mode"     "DI")
994    (set_attr "length"   "4,4,4,6,6,6,6")])
995
996
997 ;; 32-bit Integer moves
998
999 (define_expand "movsi"
1000   [(set (match_operand:SI 0 "nonimmed_operand" "")
1001         (match_operand:SI 1 "general_operand" ""))]
1002   ""
1003   "
1004 {
1005   if (xtensa_emit_move_sequence (operands, SImode))
1006     DONE;
1007 }")
1008
1009 (define_insn "movsi_internal"
1010   [(set (match_operand:SI 0 "nonimmed_operand" "=D,D,D,D,R,R,a,q,a,a,a,U,*a,*A")
1011         (match_operand:SI 1 "move_operand" "M,D,d,R,D,d,r,r,I,T,U,r,*A,*r"))]
1012   "non_acc_reg_operand (operands[0], SImode)
1013    || non_acc_reg_operand (operands[1], SImode)"
1014   "@
1015    movi.n\\t%0, %x1
1016    mov.n\\t%0, %1
1017    mov.n\\t%0, %1
1018    %v1l32i.n\\t%0, %1
1019    %v0s32i.n\\t%1, %0
1020    %v0s32i.n\\t%1, %0
1021    mov\\t%0, %1
1022    movsp\\t%0, %1
1023    movi\\t%0, %x1
1024    %v1l32r\\t%0, %1
1025    %v1l32i\\t%0, %1
1026    %v0s32i\\t%1, %0
1027    rsr\\t%0, 16 # ACCLO
1028    wsr\\t%1, 16 # ACCLO"
1029   [(set_attr "type"     "move,move,move,load,store,store,move,move,move,load,load,store,rsr,wsr")
1030    (set_attr "mode"     "SI")
1031    (set_attr "length"   "2,2,2,2,2,2,3,3,3,3,3,3,3,3")])
1032
1033 ;; 16-bit Integer moves
1034
1035 (define_expand "movhi"
1036   [(set (match_operand:HI 0 "nonimmed_operand" "")
1037         (match_operand:HI 1 "general_operand" ""))]
1038   ""
1039   "
1040 {
1041   if (xtensa_emit_move_sequence (operands, HImode))
1042     DONE;
1043 }")
1044
1045 (define_insn "movhi_internal"
1046   [(set (match_operand:HI 0 "nonimmed_operand" "=D,D,a,a,a,U,*a,*A")
1047         (match_operand:HI 1 "move_operand" "M,d,r,I,U,r,*A,*r"))]
1048   "non_acc_reg_operand (operands[0], HImode)
1049    || non_acc_reg_operand (operands[1], HImode)"
1050   "@
1051    movi.n\\t%0, %x1
1052    mov.n\\t%0, %1
1053    mov\\t%0, %1
1054    movi\\t%0, %x1
1055    %v1l16ui\\t%0, %1
1056    %v0s16i\\t%1, %0
1057    rsr\\t%0, 16 # ACCLO
1058    wsr\\t%1, 16 # ACCLO"
1059   [(set_attr "type"     "move,move,move,move,load,store,rsr,wsr")
1060    (set_attr "mode"     "HI")
1061    (set_attr "length"   "2,2,3,3,3,3,3,3")])
1062
1063 ;; 8-bit Integer moves
1064
1065 (define_expand "movqi"
1066   [(set (match_operand:QI 0 "nonimmed_operand" "")
1067         (match_operand:QI 1 "general_operand" ""))]
1068   ""
1069   "
1070 {
1071   if (xtensa_emit_move_sequence (operands, QImode))
1072     DONE;
1073 }")
1074
1075 (define_insn "movqi_internal"
1076   [(set (match_operand:QI 0 "nonimmed_operand" "=D,D,a,a,a,U,*a,*A")
1077         (match_operand:QI 1 "move_operand" "M,d,r,I,U,r,*A,*r"))]
1078   "non_acc_reg_operand (operands[0], QImode)
1079    || non_acc_reg_operand (operands[1], QImode)"
1080   "@
1081    movi.n\\t%0, %x1
1082    mov.n\\t%0, %1
1083    mov\\t%0, %1
1084    movi\\t%0, %x1
1085    %v1l8ui\\t%0, %1
1086    %v0s8i\\t%1, %0
1087    rsr\\t%0, 16 # ACCLO
1088    wsr\\t%1, 16 # ACCLO"
1089   [(set_attr "type"     "move,move,move,move,load,store,rsr,wsr")
1090    (set_attr "mode"     "QI")
1091    (set_attr "length"   "2,2,3,3,3,3,3,3")])
1092
1093 ;; 32-bit floating point moves
1094
1095 (define_expand "movsf"
1096   [(set (match_operand:SF 0 "nonimmed_operand" "")
1097         (match_operand:SF 1 "general_operand" ""))]
1098   ""
1099   "
1100 {
1101   if (GET_CODE (operands[1]) == CONST_DOUBLE)
1102     operands[1] = force_const_mem (SFmode, operands[1]);
1103
1104   if (!(reload_in_progress | reload_completed))
1105     {
1106       if (((!register_operand (operands[0], SFmode)
1107            && !register_operand (operands[1], SFmode))
1108           || (FP_REG_P (xt_true_regnum (operands[0]))
1109               && constantpool_mem_p (operands[1]))))
1110         operands[1] = force_reg (SFmode, operands[1]);
1111
1112       if (a7_overlap_mentioned_p (operands[1]))
1113         {
1114           emit_insn (gen_movsf_internal (operands[0], operands[1]));
1115           emit_insn (gen_set_frame_ptr ());
1116           DONE;
1117         }
1118     }
1119 }")
1120
1121 (define_insn "movsf_internal"
1122   [(set (match_operand:SF 0 "nonimmed_operand"
1123                             "=f,f,U,D,D,R,a,f,a,a,a,U")
1124         (match_operand:SF 1 "non_const_move_operand"
1125                             "f,U,f,d,R,d,r,r,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])))"
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    %v1l32r\\t%0, %1
1141    %v1l32i\\t%0, %1
1142    %v0s32i\\t%1, %0"
1143   [(set_attr "type"     "farith,fload,fstore,move,load,store,move,farith,farith,load,load,store")
1144    (set_attr "mode"     "SF")
1145    (set_attr "length"   "3,3,3,2,2,2,3,3,3,3,3,3")])
1146
1147 (define_insn ""
1148   [(parallel
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   "*
1156 {
1157   if (TARGET_SERIALIZE_VOLATILE && volatile_refs_p (PATTERN (insn)))
1158     output_asm_insn (\"memw\", operands);
1159   return \"lsiu\\t%0, %1, %2\";
1160 }"
1161   [(set_attr "type"     "fload")
1162    (set_attr "mode"     "SF")
1163    (set_attr "length"   "3")])
1164
1165 (define_insn ""
1166   [(parallel
1167     [(set (mem:SF (plus:SI (match_operand:SI 0 "register_operand" "+a")
1168                            (match_operand:SI 1 "fpmem_offset_operand" "i")))
1169           (match_operand:SF 2 "register_operand" "f"))
1170      (set (match_dup 0)
1171           (plus:SI (match_dup 0) (match_dup 1)))])]
1172   "TARGET_HARD_FLOAT"
1173   "*
1174 {
1175   if (TARGET_SERIALIZE_VOLATILE && volatile_refs_p (PATTERN (insn)))
1176     output_asm_insn (\"memw\", operands);
1177   return \"ssiu\\t%2, %0, %1\";
1178 }"
1179   [(set_attr "type"     "fstore")
1180    (set_attr "mode"     "SF")
1181    (set_attr "length"   "3")])
1182
1183 ;; 64-bit floating point moves
1184
1185 (define_expand "movdf"
1186   [(set (match_operand:DF 0 "nonimmed_operand" "")
1187         (match_operand:DF 1 "general_operand" ""))]
1188   ""
1189   "
1190 {
1191   if (GET_CODE (operands[1]) == CONST_DOUBLE)
1192     operands[1] = force_const_mem (DFmode, operands[1]);
1193
1194   if (!(reload_in_progress | reload_completed))
1195     {
1196       if (!register_operand (operands[0], DFmode)
1197           && !register_operand (operands[1], DFmode))
1198         operands[1] = force_reg (DFmode, operands[1]);
1199
1200       if (a7_overlap_mentioned_p (operands[1]))
1201         {
1202           emit_insn (gen_movdf_internal (operands[0], operands[1]));
1203           emit_insn (gen_set_frame_ptr ());
1204           DONE;
1205         }
1206     }
1207 }")
1208
1209 (define_insn "movdf_internal"
1210   [(set (match_operand:DF 0 "nonimmed_operand" "=D,D,S,a,a,a,U")
1211         (match_operand:DF 1 "non_const_move_operand" "d,S,d,r,T,U,r"))]
1212   "register_operand (operands[0], DFmode)
1213    || register_operand (operands[1], DFmode)"
1214   "*
1215 {
1216   switch (which_alternative)
1217     {
1218     case 0: return \"mov.n\\t%0, %1\;mov.n\\t%D0, %D1\";
1219     case 2: return \"%v0s32i.n\\t%1, %0\;s32i.n\\t%D1, %N0\";
1220     case 3: return \"mov\\t%0, %1\;mov\\t%D0, %D1\";
1221     case 6: return \"%v0s32i\\t%1, %0\;s32i\\t%D1, %N0\";
1222
1223     case 1:
1224     case 4:
1225     case 5:
1226       {
1227         /* Check if the first half of the destination register is used
1228            in the source address.  If so, reverse the order of the loads
1229            so that the source address doesn't get clobbered until it is
1230            no longer needed. */
1231
1232         rtx dstreg = operands[0];
1233         if (GET_CODE (dstreg) == SUBREG)
1234           dstreg = SUBREG_REG (dstreg);
1235         if (GET_CODE (dstreg) != REG)
1236           abort ();
1237
1238         if (reg_mentioned_p (dstreg, operands[1]))
1239           {
1240             switch (which_alternative)
1241               {
1242               case 1: return \"%v1l32i.n\\t%D0, %N1\;l32i.n\\t%0, %1\";
1243               case 4: return \"%v1l32r\\t%D0, %N1\;l32r\\t%0, %1\";
1244               case 5: return \"%v1l32i\\t%D0, %N1\;l32i\\t%0, %1\";
1245               }
1246           }
1247         else
1248           {
1249             switch (which_alternative)
1250               {
1251               case 1: return \"%v1l32i.n\\t%0, %1\;l32i.n\\t%D0, %N1\";
1252               case 4: return \"%v1l32r\\t%0, %1\;l32r\\t%D0, %N1\";
1253               case 5: return \"%v1l32i\\t%0, %1\;l32i\\t%D0, %N1\";
1254               }
1255           }
1256       }
1257     }
1258   abort ();
1259   return \"\";
1260 }"
1261   [(set_attr "type"     "move,load,store,move,load,load,store")
1262    (set_attr "mode"     "DF")
1263    (set_attr "length"   "4,4,4,6,6,6,6")])
1264
1265 ;; Block moves
1266
1267 (define_expand "movstrsi"
1268   [(parallel [(set (match_operand:BLK 0 "" "")
1269                    (match_operand:BLK 1 "" ""))
1270               (use (match_operand:SI 2 "arith_operand" ""))
1271               (use (match_operand:SI 3 "const_int_operand" ""))])]
1272   ""
1273   "
1274 {
1275   if (!xtensa_expand_block_move (operands)) FAIL;
1276   DONE;
1277 }")
1278
1279 (define_insn "movstrsi_internal"
1280   [(parallel [(set (match_operand:BLK 0 "memory_operand" "=U")
1281                    (match_operand:BLK 1 "memory_operand" "U"))
1282               (use (match_operand:SI 2 "arith_operand" ""))
1283               (use (match_operand:SI 3 "const_int_operand" ""))
1284               (clobber (match_scratch:SI 4 "=&r"))
1285               (clobber (match_scratch:SI 5 "=&r"))])]
1286   ""
1287   "*
1288 {
1289   rtx tmpregs[2];
1290   tmpregs[0] = operands[4];
1291   tmpregs[1] = operands[5];
1292   xtensa_emit_block_move (operands, tmpregs, 1);
1293   return \"\";
1294 }"
1295   [(set_attr "type"     "multi")
1296    (set_attr "mode"     "none")
1297    (set_attr "length"   "300")])
1298
1299
1300 ;;
1301 ;;  ....................
1302 ;;
1303 ;;      SHIFTS
1304 ;;
1305 ;;  ....................
1306 ;;
1307
1308 (define_insn "ashlsi3"
1309   [(set (match_operand:SI 0 "register_operand" "=a,a")
1310         (ashift:SI (match_operand:SI 1 "register_operand" "r,r")
1311                    (match_operand:SI 2 "arith_operand" "J,r")))]
1312   ""      
1313   "@
1314    slli\\t%0, %1, %R2
1315    ssl\\t%2\;sll\\t%0, %1"
1316   [(set_attr "type"     "arith,arith")
1317    (set_attr "mode"     "SI")
1318    (set_attr "length"   "3,6")])
1319
1320 (define_insn "ashrsi3"
1321   [(set (match_operand:SI 0 "register_operand" "=a,a")
1322         (ashiftrt:SI (match_operand:SI 1 "register_operand" "r,r")
1323                      (match_operand:SI 2 "arith_operand" "J,r")))]
1324   ""
1325   "@
1326    srai\\t%0, %1, %R2
1327    ssr\\t%2\;sra\\t%0, %1"
1328   [(set_attr "type"     "arith,arith")
1329    (set_attr "mode"     "SI")
1330    (set_attr "length"   "3,6")])
1331
1332 (define_insn "lshrsi3"
1333   [(set (match_operand:SI 0 "register_operand" "=a,a")
1334         (lshiftrt:SI (match_operand:SI 1 "register_operand" "r,r")
1335                      (match_operand:SI 2 "arith_operand" "J,r")))]
1336   ""
1337   "*
1338 {
1339   if (which_alternative == 0)
1340     {
1341       if ((INTVAL (operands[2]) & 0x1f) < 16)
1342         return \"srli\\t%0, %1, %R2\";
1343       else
1344         return \"extui\\t%0, %1, %R2, %L2\";
1345     }
1346   return \"ssr\\t%2\;srl\\t%0, %1\";
1347 }"
1348   [(set_attr "type"     "arith,arith")
1349    (set_attr "mode"     "SI")
1350    (set_attr "length"   "3,6")])
1351
1352 (define_insn "rotlsi3"
1353   [(set (match_operand:SI 0 "register_operand" "=a,a")
1354         (rotate:SI (match_operand:SI 1 "register_operand" "r,r")
1355                      (match_operand:SI 2 "arith_operand" "J,r")))]
1356   ""
1357   "@
1358    ssai\\t%L2\;src\\t%0, %1, %1
1359    ssl\\t%2\;src\\t%0, %1, %1"
1360   [(set_attr "type"     "multi,multi")
1361    (set_attr "mode"     "SI")
1362    (set_attr "length"   "6,6")])
1363
1364 (define_insn "rotrsi3"
1365   [(set (match_operand:SI 0 "register_operand" "=a,a")
1366         (rotatert:SI (match_operand:SI 1 "register_operand" "r,r")
1367                      (match_operand:SI 2 "arith_operand" "J,r")))]
1368   ""
1369   "@
1370    ssai\\t%R2\;src\\t%0, %1, %1
1371    ssr\\t%2\;src\\t%0, %1, %1"
1372   [(set_attr "type"     "multi,multi")
1373    (set_attr "mode"     "SI")
1374    (set_attr "length"   "6,6")])
1375
1376 ;;
1377 ;;  ....................
1378 ;;
1379 ;;      COMPARISONS
1380 ;;
1381 ;;  ....................
1382 ;;
1383
1384 ;; Like the md files for MIPS and SPARC, we handle comparisons by stashing
1385 ;; away the operands and then using that information in the subsequent
1386 ;; conditional branch.
1387
1388 (define_expand "cmpsi"
1389   [(set (cc0)
1390         (compare:CC (match_operand:SI 0 "register_operand" "")
1391                     (match_operand:SI 1 "nonmemory_operand" "")))]
1392   ""
1393   "
1394 {
1395   branch_cmp[0] = operands[0];
1396   branch_cmp[1] = operands[1];
1397   branch_type = CMP_SI;
1398   DONE;
1399 }")
1400
1401 (define_expand "tstsi"
1402   [(set (cc0)
1403         (match_operand:SI 0 "register_operand" ""))]
1404   ""
1405   "
1406 {
1407   branch_cmp[0] = operands[0];
1408   branch_cmp[1] = const0_rtx;
1409   branch_type = CMP_SI;
1410   DONE;
1411 }")
1412
1413 (define_expand "cmpsf"
1414   [(set (cc0)
1415         (compare:CC (match_operand:SF 0 "register_operand" "")
1416                     (match_operand:SF 1 "register_operand" "")))]
1417   "TARGET_HARD_FLOAT"
1418   "
1419 {
1420   branch_cmp[0] = operands[0];
1421   branch_cmp[1] = operands[1];
1422   branch_type = CMP_SF;
1423   DONE;
1424 }")
1425
1426
1427 ;;
1428 ;;  ....................
1429 ;;
1430 ;;      CONDITIONAL BRANCHES
1431 ;;
1432 ;;  ....................
1433 ;;
1434
1435 (define_expand "beq"
1436   [(set (pc)
1437         (if_then_else (eq (cc0) (const_int 0))
1438                       (label_ref (match_operand 0 "" ""))
1439                       (pc)))]
1440   ""
1441   "
1442 {
1443   xtensa_expand_conditional_branch (operands, EQ);
1444   DONE;
1445 }")
1446
1447 (define_expand "bne"
1448   [(set (pc)
1449         (if_then_else (ne (cc0) (const_int 0))
1450                       (label_ref (match_operand 0 "" ""))
1451                       (pc)))]
1452   ""
1453   "
1454 {
1455   xtensa_expand_conditional_branch (operands, NE);
1456   DONE;
1457 }")
1458
1459 (define_expand "bgt"
1460   [(set (pc)
1461         (if_then_else (gt (cc0) (const_int 0))
1462                       (label_ref (match_operand 0 "" ""))
1463                       (pc)))]
1464   ""
1465   "
1466 {
1467   xtensa_expand_conditional_branch (operands, GT);
1468   DONE;
1469 }")
1470
1471 (define_expand "bge"
1472   [(set (pc)
1473         (if_then_else (ge (cc0) (const_int 0))
1474                       (label_ref (match_operand 0 "" ""))
1475                       (pc)))]
1476   ""
1477   "
1478 {
1479   xtensa_expand_conditional_branch (operands, GE);
1480   DONE;
1481 }")
1482
1483 (define_expand "blt"
1484   [(set (pc)
1485         (if_then_else (lt (cc0) (const_int 0))
1486                       (label_ref (match_operand 0 "" ""))
1487                       (pc)))]
1488   ""
1489   "
1490 {
1491   xtensa_expand_conditional_branch (operands, LT);
1492   DONE;
1493 }")
1494
1495 (define_expand "ble"
1496   [(set (pc)
1497         (if_then_else (le (cc0) (const_int 0))
1498                       (label_ref (match_operand 0 "" ""))
1499                       (pc)))]
1500   ""
1501   "
1502 {
1503   xtensa_expand_conditional_branch (operands, LE);
1504   DONE;
1505 }")
1506
1507 (define_expand "bgtu"
1508   [(set (pc)
1509         (if_then_else (gtu (cc0) (const_int 0))
1510                       (label_ref (match_operand 0 "" ""))
1511                       (pc)))]
1512   ""
1513   "
1514 {
1515   xtensa_expand_conditional_branch (operands, GTU);
1516   DONE;
1517 }")
1518
1519 (define_expand "bgeu"
1520   [(set (pc)
1521         (if_then_else (geu (cc0) (const_int 0))
1522                       (label_ref (match_operand 0 "" ""))
1523                       (pc)))]
1524   ""
1525   "
1526 {
1527   xtensa_expand_conditional_branch (operands, GEU);
1528   DONE;
1529 }")
1530
1531 (define_expand "bltu"
1532   [(set (pc)
1533         (if_then_else (ltu (cc0) (const_int 0))
1534                       (label_ref (match_operand 0 "" ""))
1535                       (pc)))]
1536   ""
1537   "
1538 {
1539   xtensa_expand_conditional_branch (operands, LTU);
1540   DONE;
1541 }")
1542
1543 (define_expand "bleu"
1544   [(set (pc)
1545         (if_then_else (leu (cc0) (const_int 0))
1546                       (label_ref (match_operand 0 "" ""))
1547                       (pc)))]
1548   ""
1549   "
1550 {
1551   xtensa_expand_conditional_branch (operands, LEU);
1552   DONE;
1553 }")
1554
1555 ;; Branch patterns for standard integer comparisons
1556
1557 (define_insn ""
1558   [(set (pc)
1559         (if_then_else (match_operator 3 "branch_operator"
1560                          [(match_operand:SI 0 "register_operand" "r,r")
1561                           (match_operand:SI 1 "branch_operand" "K,r")])
1562                       (label_ref (match_operand 2 "" ""))
1563                       (pc)))]
1564   ""
1565   "*
1566 {
1567   if (which_alternative == 1)
1568     {
1569       switch (GET_CODE (operands[3]))
1570         {
1571         case EQ:        return \"beq\\t%0, %1, %2\";
1572         case NE:        return \"bne\\t%0, %1, %2\";
1573         case LT:        return \"blt\\t%0, %1, %2\";
1574         case GE:        return \"bge\\t%0, %1, %2\";
1575         default:        break;
1576         }
1577     }
1578   else if (INTVAL (operands[1]) == 0)
1579     {
1580       switch (GET_CODE (operands[3]))
1581         {
1582         case EQ:        return (TARGET_DENSITY
1583                                 ? \"beqz.n\\t%0, %2\"
1584                                 : \"beqz\\t%0, %2\");
1585         case NE:        return (TARGET_DENSITY
1586                                 ? \"bnez.n\\t%0, %2\"
1587                                 : \"bnez\\t%0, %2\");
1588         case LT:        return \"bltz\\t%0, %2\";
1589         case GE:        return \"bgez\\t%0, %2\";
1590         default:        break;
1591         }
1592     }
1593   else
1594     {
1595       switch (GET_CODE (operands[3]))
1596         {
1597         case EQ:        return \"beqi\\t%0, %d1, %2\";
1598         case NE:        return \"bnei\\t%0, %d1, %2\";
1599         case LT:        return \"blti\\t%0, %d1, %2\";
1600         case GE:        return \"bgei\\t%0, %d1, %2\";
1601         default:        break;
1602         }
1603     }
1604   fatal_insn (\"unexpected branch operator\", operands[3]);
1605   return \"\";
1606 }"
1607   [(set_attr "type"     "jump,jump")
1608    (set_attr "mode"     "none")
1609    (set_attr "length"   "3,3")])
1610
1611 (define_insn ""
1612   [(set (pc)
1613         (if_then_else (match_operator 3 "branch_operator"
1614                          [(match_operand:SI 0 "register_operand" "r,r")
1615                           (match_operand:SI 1 "branch_operand" "K,r")])
1616                       (pc)
1617                       (label_ref (match_operand 2 "" ""))))]
1618   ""
1619   "*
1620 {
1621   if (which_alternative == 1)
1622     {
1623       switch (GET_CODE (operands[3]))
1624         {
1625         case EQ:        return \"bne\\t%0, %1, %2\";
1626         case NE:        return \"beq\\t%0, %1, %2\";
1627         case LT:        return \"bge\\t%0, %1, %2\";
1628         case GE:        return \"blt\\t%0, %1, %2\";
1629         default:        break;
1630         }
1631     }
1632   else if (INTVAL (operands[1]) == 0)
1633     {
1634       switch (GET_CODE (operands[3]))
1635         {
1636         case EQ:        return (TARGET_DENSITY
1637                                 ? \"bnez.n\\t%0, %2\"
1638                                 : \"bnez\\t%0, %2\");
1639         case NE:        return (TARGET_DENSITY
1640                                 ? \"beqz.n\\t%0, %2\"
1641                                 : \"beqz\\t%0, %2\");
1642         case LT:        return \"bgez\\t%0, %2\";
1643         case GE:        return \"bltz\\t%0, %2\";
1644         default:        break;
1645         }
1646     }
1647   else
1648     {
1649       switch (GET_CODE (operands[3]))
1650         {
1651         case EQ:        return \"bnei\\t%0, %d1, %2\";
1652         case NE:        return \"beqi\\t%0, %d1, %2\";
1653         case LT:        return \"bgei\\t%0, %d1, %2\";
1654         case GE:        return \"blti\\t%0, %d1, %2\";
1655         default:        break;
1656         }
1657     }
1658   fatal_insn (\"unexpected branch operator\", operands[3]);
1659   return \"\";
1660 }"
1661   [(set_attr "type"     "jump,jump")
1662    (set_attr "mode"     "none")
1663    (set_attr "length"   "3,3")])
1664
1665 (define_insn ""
1666   [(set (pc)
1667         (if_then_else (match_operator 3 "ubranch_operator"
1668                          [(match_operand:SI 0 "register_operand" "r,r")
1669                           (match_operand:SI 1 "ubranch_operand" "L,r")])
1670                       (label_ref (match_operand 2 "" ""))
1671                       (pc)))]
1672   ""
1673   "*
1674 {
1675   if (which_alternative == 1)
1676     {
1677       switch (GET_CODE (operands[3]))
1678         {
1679         case LTU:       return \"bltu\\t%0, %1, %2\";
1680         case GEU:       return \"bgeu\\t%0, %1, %2\";
1681         default:        break;
1682         }
1683     }
1684   else
1685     {
1686       switch (GET_CODE (operands[3]))
1687         {
1688         case LTU:       return \"bltui\\t%0, %d1, %2\";
1689         case GEU:       return \"bgeui\\t%0, %d1, %2\";
1690         default:        break;
1691         }
1692     }
1693   fatal_insn (\"unexpected branch operator\", operands[3]);
1694   return \"\";
1695 }"
1696   [(set_attr "type"     "jump,jump")
1697    (set_attr "mode"     "none")
1698    (set_attr "length"   "3,3")])
1699
1700 (define_insn ""
1701   [(set (pc)
1702         (if_then_else (match_operator 3 "ubranch_operator"
1703                          [(match_operand:SI 0 "register_operand" "r,r")
1704                           (match_operand:SI 1 "ubranch_operand" "L,r")])
1705                       (pc)
1706                       (label_ref (match_operand 2 "" ""))))]
1707   ""
1708   "*
1709 {
1710   if (which_alternative == 1)
1711     {
1712       switch (GET_CODE (operands[3]))
1713         {
1714         case LTU:       return \"bgeu\\t%0, %1, %2\";
1715         case GEU:       return \"bltu\\t%0, %1, %2\";
1716         default:        break;
1717         }
1718     }
1719   else
1720     {
1721       switch (GET_CODE (operands[3]))
1722         {
1723         case LTU:       return \"bgeui\\t%0, %d1, %2\";
1724         case GEU:       return \"bltui\\t%0, %d1, %2\";
1725         default:        break;
1726         }
1727     }
1728   fatal_insn (\"unexpected branch operator\", operands[3]);
1729   return \"\";
1730 }"
1731   [(set_attr "type"     "jump,jump")
1732    (set_attr "mode"     "none")
1733    (set_attr "length"   "3,3")])
1734
1735 ;; Branch patterns for bit testing
1736
1737 (define_insn ""
1738   [(set (pc)
1739         (if_then_else (match_operator 3 "boolean_operator"
1740                         [(zero_extract:SI
1741                             (match_operand:SI 0 "register_operand" "r,r")
1742                             (const_int 1)
1743                             (match_operand:SI 1 "arith_operand" "J,r"))
1744                          (const_int 0)])
1745                       (label_ref (match_operand 2 "" ""))
1746                       (pc)))]
1747   ""
1748   "*
1749 {
1750   if (which_alternative == 0)
1751     {
1752       unsigned bitnum = INTVAL(operands[1]) & 0x1f;
1753       operands[1] = GEN_INT(bitnum);
1754       switch (GET_CODE (operands[3]))
1755         {
1756         case EQ:        return \"bbci\\t%0, %d1, %2\";
1757         case NE:        return \"bbsi\\t%0, %d1, %2\";
1758         default:        break;
1759         }
1760     }
1761   else
1762     {
1763       switch (GET_CODE (operands[3]))
1764         {
1765         case EQ:        return \"bbc\\t%0, %1, %2\";
1766         case NE:        return \"bbs\\t%0, %1, %2\";
1767         default:        break;
1768         }
1769     }
1770   fatal_insn (\"unexpected branch operator\", operands[3]);
1771   return \"\";
1772 }"
1773   [(set_attr "type"     "jump")
1774    (set_attr "mode"     "none")
1775    (set_attr "length"   "3")])
1776
1777 (define_insn ""
1778   [(set (pc)
1779         (if_then_else (match_operator 3 "boolean_operator"
1780                         [(zero_extract:SI
1781                             (match_operand:SI 0 "register_operand" "r,r")
1782                             (const_int 1)
1783                             (match_operand:SI 1 "arith_operand" "J,r"))
1784                          (const_int 0)])
1785                       (pc)
1786                       (label_ref (match_operand 2 "" ""))))]
1787   ""
1788   "*
1789 {
1790   if (which_alternative == 0)
1791     {
1792       unsigned bitnum = INTVAL (operands[1]) & 0x1f;
1793       operands[1] = GEN_INT (bitnum);
1794       switch (GET_CODE (operands[3]))
1795         {
1796         case EQ:    return \"bbsi\\t%0, %d1, %2\";
1797         case NE:    return \"bbci\\t%0, %d1, %2\";
1798         default:    break;
1799         }
1800     }
1801   else
1802     {
1803       switch (GET_CODE (operands[3]))
1804         {
1805         case EQ:        return \"bbs\\t%0, %1, %2\";
1806         case NE:        return \"bbc\\t%0, %1, %2\";
1807         default:        break;
1808         }
1809     }
1810   fatal_insn (\"unexpected branch operator\", operands[3]);
1811   return \"\";
1812 }"
1813   [(set_attr "type"     "jump")
1814    (set_attr "mode"     "none")
1815    (set_attr "length"   "3")])
1816
1817 (define_insn ""
1818   [(set (pc)
1819         (if_then_else (match_operator 3 "boolean_operator"
1820                  [(and:SI (match_operand:SI 0 "register_operand" "r")
1821                           (match_operand:SI 1 "register_operand" "r"))
1822                   (const_int 0)])
1823                       (label_ref (match_operand 2 "" ""))
1824                       (pc)))]
1825   ""
1826   "*
1827 {
1828   switch (GET_CODE (operands[3]))
1829     {
1830     case EQ:    return \"bnone\\t%0, %1, %2\";
1831     case NE:    return \"bany\\t%0, %1, %2\";
1832     default:    break;
1833     }
1834   fatal_insn (\"unexpected branch operator\", operands[3]);
1835   return \"\";
1836 }"
1837   [(set_attr "type"     "jump")
1838    (set_attr "mode"     "none")
1839    (set_attr "length"   "3")])
1840
1841 (define_insn ""
1842   [(set (pc)
1843         (if_then_else (match_operator 3 "boolean_operator"
1844                  [(and:SI (match_operand:SI 0 "register_operand" "r")
1845                           (match_operand:SI 1 "register_operand" "r"))
1846                   (const_int 0)])
1847                       (pc)
1848                       (label_ref (match_operand 2 "" ""))))]
1849   ""
1850   "*
1851 {
1852   switch (GET_CODE (operands[3]))
1853     {
1854     case EQ:    return \"bany\\t%0, %1, %2\";
1855     case NE:    return \"bnone\\t%0, %1, %2\";
1856     default:    break;
1857     }
1858   fatal_insn (\"unexpected branch operator\", operands[3]);
1859   return \"\";
1860 }"
1861   [(set_attr "type"     "jump")
1862    (set_attr "mode"     "none")
1863    (set_attr "length"   "3")])
1864
1865
1866 ;; Define the loop insns that is used by bct optimization to represent the
1867 ;; start and end of a zero-overhead loop (in loop.c). This start template
1868 ;; generates the loop insn, the end template doesn't generate any instructions
1869 ;; since since loop end is handled in hardware.
1870
1871 (define_insn "zero_cost_loop_start"
1872   [(parallel [(set (pc) (if_then_else (eq (match_operand:SI 0 "register_operand" "a")
1873                                           (const_int 0))
1874                                       (label_ref (match_operand 1 "" ""))
1875                                       (pc)))
1876               (set (reg:SI 19)
1877                    (plus:SI (match_dup 0)
1878                             (const_int -1)))])]
1879   ""
1880   "loopnez %0, %l1"
1881   [(set_attr "type"     "jump")
1882    (set_attr "mode"     "none")
1883    (set_attr "length"   "3")])
1884
1885 (define_insn "zero_cost_loop_end"
1886   [(parallel [(set (pc) (if_then_else (ne (reg:SI 19)
1887                                           (const_int 0))
1888                                       (label_ref (match_operand 0 "" ""))
1889                                       (pc)))
1890               (set (reg:SI 19)
1891                    (plus:SI (reg:SI 19)
1892                             (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")])
1901
1902
1903 ;;
1904 ;;  ....................
1905 ;;
1906 ;;      SETTING A REGISTER FROM A COMPARISON
1907 ;;
1908 ;;  ....................
1909 ;;
1910
1911 (define_expand "seq"
1912   [(set (match_operand:SI 0 "register_operand" "")
1913         (match_dup 1))]
1914   ""
1915   "
1916 {
1917   operands[1] = gen_rtx (EQ, SImode, branch_cmp[0], branch_cmp[1]);
1918   if (!xtensa_expand_scc (operands)) FAIL;
1919   DONE;
1920 }")
1921
1922 (define_expand "sne"
1923   [(set (match_operand:SI 0 "register_operand" "")
1924         (match_dup 1))]
1925   ""
1926   "
1927 {
1928   operands[1] = gen_rtx (NE, SImode, branch_cmp[0], branch_cmp[1]);
1929   if (!xtensa_expand_scc (operands)) FAIL;
1930   DONE;
1931 }")
1932
1933 (define_expand "sgt"
1934   [(set (match_operand:SI 0 "register_operand" "")
1935         (match_dup 1))]
1936   ""
1937   "
1938 {
1939   operands[1] = gen_rtx (GT, SImode, branch_cmp[0], branch_cmp[1]);
1940   if (!xtensa_expand_scc (operands)) FAIL;
1941   DONE;
1942 }")
1943
1944 (define_expand "sge"
1945   [(set (match_operand:SI 0 "register_operand" "")
1946         (match_dup 1))]
1947   ""
1948   "
1949 {
1950   operands[1] = gen_rtx (GE, SImode, branch_cmp[0], branch_cmp[1]);
1951   if (!xtensa_expand_scc (operands)) FAIL;
1952   DONE;
1953 }")
1954
1955 (define_expand "slt"
1956   [(set (match_operand:SI 0 "register_operand" "")
1957         (match_dup 1))]
1958   ""
1959   "
1960 {
1961   operands[1] = gen_rtx (LT, SImode, branch_cmp[0], branch_cmp[1]);
1962   if (!xtensa_expand_scc (operands)) FAIL;
1963   DONE;
1964 }")
1965
1966 (define_expand "sle"
1967   [(set (match_operand:SI 0 "register_operand" "")
1968         (match_dup 1))]
1969   ""
1970   "
1971 {
1972   operands[1] = gen_rtx (LE, SImode, branch_cmp[0], branch_cmp[1]);
1973   if (!xtensa_expand_scc (operands)) FAIL;
1974   DONE;
1975 }")
1976
1977
1978 ;;
1979 ;;  ....................
1980 ;;
1981 ;;      CONDITIONAL MOVES
1982 ;;
1983 ;;  ....................
1984 ;;
1985
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   "
1993 {
1994   if (!xtensa_expand_conditional_move (operands, 0)) FAIL;
1995   DONE;
1996 }")
1997
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   "
2005 {
2006   if (!xtensa_expand_conditional_move (operands, 1)) FAIL;
2007   DONE;
2008 }")
2009
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   "*
2019 {
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 \"\";
2044 }"
2045   [(set_attr "type"     "move,move")
2046    (set_attr "mode"     "SI")
2047    (set_attr "length"   "3,3")])
2048
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   "*
2058 {
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 \"\";
2071 }"
2072   [(set_attr "type"     "move,move")
2073    (set_attr "mode"     "SI")
2074    (set_attr "length"   "3,3")])
2075
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   "*
2085 {
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 \"\";
2132 }"
2133   [(set_attr "type"     "move,move,move,move")
2134    (set_attr "mode"     "SF")
2135    (set_attr "length"   "3,3,3,3")])
2136
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   "*
2146 {
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 \"\";
2165 }"
2166   [(set_attr "type"     "move,move,move,move")
2167    (set_attr "mode"     "SF")
2168    (set_attr "length"   "3,3,3,3")])
2169
2170
2171 ;;
2172 ;;  ....................
2173 ;;
2174 ;;      FLOATING POINT COMPARISONS
2175 ;;
2176 ;;  ....................
2177 ;;
2178
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")])
2188
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")])
2198
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")])
2208
2209
2210 ;;
2211 ;;  ....................
2212 ;;
2213 ;;      UNCONDITIONAL BRANCHES
2214 ;;
2215 ;;  ....................
2216 ;;
2217
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")])
2226
2227 (define_expand "indirect_jump"
2228   [(set (pc) (match_operand 0 "register_operand" ""))]
2229   ""
2230   "
2231 {
2232   rtx dest = operands[0];
2233   if (GET_CODE (dest) != REG || GET_MODE (dest) != Pmode)
2234     operands[0] = copy_to_mode_reg (Pmode, dest);
2235
2236   emit_jump_insn (gen_indirect_jump_internal (dest));
2237   DONE;
2238 }")
2239
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")])
2247
2248
2249 (define_expand "tablejump"
2250   [(use (match_operand:SI 0 "register_operand" ""))
2251    (use (label_ref (match_operand 1 "" "")))]
2252    ""
2253    "
2254 {
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;
2266 }")
2267
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")])
2277
2278
2279 ;;
2280 ;;  ....................
2281 ;;
2282 ;;      FUNCTION CALLS
2283 ;;
2284 ;;  ....................
2285 ;;
2286
2287 (define_expand "sym_PLT"
2288   [(const (unspec [(match_operand:SI 0 "" "")] UNSPEC_PLT))]
2289   ""
2290   "")
2291
2292 (define_expand "call"
2293   [(call (match_operand 0 "memory_operand" "")
2294          (match_operand 1 "" ""))]
2295   ""
2296   "
2297 {
2298   rtx addr = XEXP (operands[0], 0);
2299   if (flag_pic && GET_CODE (addr) == SYMBOL_REF && !SYMBOL_REF_FLAG (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);
2303 }")
2304
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")])
2315
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   "
2322 {
2323   rtx addr = XEXP (operands[1], 0);
2324   if (flag_pic && GET_CODE (addr) == SYMBOL_REF && !SYMBOL_REF_FLAG (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);
2328 }")
2329
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")])
2347
2348 (define_insn "return"
2349   [(return)
2350    (use (reg:SI A0_REG))]
2351   "reload_completed"
2352   "*
2353 {
2354   return (TARGET_DENSITY ? \"retw.n\" : \"retw\");
2355 }"
2356   [(set_attr "type"     "jump")
2357    (set_attr "mode"     "none")
2358    (set_attr "length"   "2")])
2359
2360
2361 ;;
2362 ;;  ....................
2363 ;;
2364 ;;      MISC.
2365 ;;
2366 ;;  ....................
2367 ;;
2368
2369 (define_insn "nop"
2370   [(const_int 0)]
2371   ""
2372   "*
2373 {
2374   return (TARGET_DENSITY ? \"nop.n\" : \"nop\");
2375 }"
2376   [(set_attr "type"     "nop")
2377    (set_attr "mode"     "none")
2378    (set_attr "length"   "3")])
2379
2380 (define_expand "nonlocal_goto"
2381   [(match_operand:SI 0 "general_operand" "")
2382    (match_operand:SI 1 "general_operand" "")
2383    (match_operand:SI 2 "general_operand" "")
2384    (match_operand:SI 3 "" "")]
2385   ""
2386   "
2387 {
2388   xtensa_expand_nonlocal_goto (operands);
2389   DONE;
2390 }")
2391
2392 ;; Setting up a frame pointer is tricky for Xtensa because GCC doesn't
2393 ;; know if a frame pointer is required until the reload pass, and
2394 ;; because there may be an incoming argument value in the hard frame
2395 ;; pointer register (a7). If there is an incoming argument in that
2396 ;; register, the "set_frame_ptr" insn gets inserted immediately after
2397 ;; the insn that copies the incoming argument to a pseudo or to the
2398 ;; stack.  This serves several purposes here: (1) it keeps the
2399 ;; optimizer from copy-propagating or scheduling the use of a7 as an
2400 ;; incoming argument away from the beginning of the function; (2) we
2401 ;; can use a post-reload splitter to expand away the insn if a frame
2402 ;; pointer is not required, so that the post-reload scheduler can do
2403 ;; the right thing; and (3) it makes it easy for xtensa_reorg() to
2404 ;; search for this insn to determine whether it should add a new insn
2405 ;; to set up the frame pointer.
2406
2407 (define_insn "set_frame_ptr"
2408   [(unspec_volatile [(const_int 0)] UNSPECV_SET_FP)]
2409   ""
2410   "*
2411 {
2412   if (frame_pointer_needed)
2413     return \"mov\\ta7, sp\";
2414   return \"\";
2415 }"
2416   [(set_attr "type"     "move")
2417    (set_attr "mode"     "SI")
2418    (set_attr "length"   "3")])
2419
2420 ;; Post-reload splitter to remove fp assignment when it's not needed.
2421 (define_split
2422   [(unspec_volatile [(const_int 0)] UNSPECV_SET_FP)]
2423   "reload_completed && !frame_pointer_needed"
2424   [(unspec [(const_int 0)] UNSPEC_NOP)]
2425   "")
2426
2427 ;; The preceding splitter needs something to split the insn into;
2428 ;; things start breaking if the result is just a "use" so instead we
2429 ;; generate the following insn.
2430 (define_insn ""
2431   [(unspec [(const_int 0)] UNSPEC_NOP)]
2432   ""
2433   ""
2434   [(set_attr "type"     "nop")
2435    (set_attr "mode"     "none")
2436    (set_attr "length"   "0")])
2437
2438 ;;
2439 ;;  ....................
2440 ;;
2441 ;;      BOOLEANS
2442 ;;
2443 ;;  ....................
2444 ;;
2445
2446 ;; branch patterns
2447
2448 (define_insn ""
2449   [(set (pc)
2450         (if_then_else (match_operator 2 "boolean_operator"
2451                          [(match_operand:CC 0 "register_operand" "b")
2452                           (const_int 0)])
2453                       (label_ref (match_operand 1 "" ""))
2454                       (pc)))]
2455   "TARGET_BOOLEANS"
2456   "*
2457 {
2458   if (GET_CODE (operands[2]) == EQ)
2459     return \"bf\\t%0, %1\";
2460   else
2461     return \"bt\\t%0, %1\";
2462 }"
2463   [(set_attr "type"     "jump")
2464    (set_attr "mode"     "none")
2465    (set_attr "length"   "3")])
2466
2467 (define_insn ""
2468   [(set (pc)
2469         (if_then_else (match_operator 2 "boolean_operator"
2470                          [(match_operand:CC 0 "register_operand" "b")
2471                           (const_int 0)])
2472                       (pc)
2473                       (label_ref (match_operand 1 "" ""))))]
2474   "TARGET_BOOLEANS"
2475   "*
2476 {
2477   if (GET_CODE (operands[2]) == EQ)
2478     return \"bt\\t%0, %1\";
2479   else
2480     return \"bf\\t%0, %1\";
2481 }"
2482   [(set_attr "type"     "jump")
2483    (set_attr "mode"     "none")
2484    (set_attr "length"   "3")])