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