OSDN Git Service

2003-01-30 Ralf Corsepius <corsepiu@faw.uni-ulm.de>
[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   (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 "*addx2"
146   [(set (match_operand:SI 0 "register_operand" "=a")
147         (plus:SI (mult:SI (match_operand:SI 1 "register_operand" "r")
148                           (const_int 2))
149                  (match_operand:SI 2 "register_operand" "r")))]
150   ""
151   "addx2\\t%0, %1, %2"
152   [(set_attr "type"     "arith")
153    (set_attr "mode"     "SI")
154    (set_attr "length"   "3")])
155
156 (define_insn "*addx4"
157   [(set (match_operand:SI 0 "register_operand" "=a")
158         (plus:SI (mult:SI (match_operand:SI 1 "register_operand" "r")
159                           (const_int 4))
160                  (match_operand:SI 2 "register_operand" "r")))]
161   ""
162   "addx4\\t%0, %1, %2"
163   [(set_attr "type"     "arith")
164    (set_attr "mode"     "SI")
165    (set_attr "length"   "3")])
166
167 (define_insn "*addx8"
168   [(set (match_operand:SI 0 "register_operand" "=a")
169         (plus:SI (mult:SI (match_operand:SI 1 "register_operand" "r")
170                           (const_int 8))
171                  (match_operand:SI 2 "register_operand" "r")))]
172   ""
173   "addx8\\t%0, %1, %2"
174   [(set_attr "type"     "arith")
175    (set_attr "mode"     "SI")
176    (set_attr "length"   "3")])
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 "*subx2"
240   [(set (match_operand:SI 0 "register_operand" "=a")
241         (minus:SI (mult:SI (match_operand:SI 1 "register_operand" "r")
242                            (const_int 2))
243                   (match_operand:SI 2 "register_operand" "r")))]
244   ""
245   "subx2\\t%0, %1, %2"
246   [(set_attr "type"     "arith")
247    (set_attr "mode"     "SI")
248    (set_attr "length"   "3")])
249
250 (define_insn "*subx4"
251   [(set (match_operand:SI 0 "register_operand" "=a")
252         (minus:SI (mult:SI (match_operand:SI 1 "register_operand" "r")
253                            (const_int 4))
254                   (match_operand:SI 2 "register_operand" "r")))]
255   ""
256   "subx4\\t%0, %1, %2"
257   [(set_attr "type"     "arith")
258    (set_attr "mode"     "SI")
259    (set_attr "length"   "3")])
260
261 (define_insn "*subx8"
262   [(set (match_operand:SI 0 "register_operand" "=a")
263         (minus:SI (mult:SI (match_operand:SI 1 "register_operand" "r")
264                            (const_int 8))
265                   (match_operand:SI 2 "register_operand" "r")))]
266   ""
267   "subx8\\t%0, %1, %2"
268   [(set_attr "type"     "arith")
269    (set_attr "mode"     "SI")
270    (set_attr "length"   "3")])
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 "*recipsf2"
427   [(set (match_operand:SF 0 "register_operand" "=f")
428         (div:SF (match_operand:SF 1 "const_float_1_operand" "")
429                 (match_operand:SF 2 "register_operand" "f")))]
430   "TARGET_HARD_FLOAT_RECIP && flag_unsafe_math_optimizations"
431   "recip.s\\t%0, %2"
432   [(set_attr "type"     "fdiv")
433    (set_attr "mode"     "SF")
434    (set_attr "length"   "3")])
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 "*rsqrtsf2"
484   [(set (match_operand:SF 0 "register_operand" "=f")
485         (div:SF (match_operand:SF 1 "const_float_1_operand" "")
486                 (sqrt:SF (match_operand:SF 2 "register_operand" "f"))))]
487   "TARGET_HARD_FLOAT_RSQRT && flag_unsafe_math_optimizations"
488   "rsqrt.s\\t%0, %2"
489   [(set_attr "type"     "fsqrt")
490    (set_attr "mode"     "SF")
491    (set_attr "length"   "3")])
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 (xtensa_copy_incoming_a7 (operands, DImode))
933         DONE;
934     }
935 }")
936
937 (define_insn "movdi_internal"
938   [(set (match_operand:DI 0 "nonimmed_operand" "=D,D,S,a,a,a,U")
939         (match_operand:DI 1 "non_const_move_operand" "d,S,d,r,T,U,r"))]
940   "register_operand (operands[0], DImode)
941    || register_operand (operands[1], DImode)"
942   "*
943 {
944   switch (which_alternative)
945     {
946     case 0: return \"mov.n\\t%0, %1\;mov.n\\t%D0, %D1\";
947     case 2: return \"%v0s32i.n\\t%1, %0\;s32i.n\\t%D1, %N0\";
948     case 3: return \"mov\\t%0, %1\;mov\\t%D0, %D1\";
949     case 6: return \"%v0s32i\\t%1, %0\;s32i\\t%D1, %N0\";
950
951     case 1:
952     case 4:
953     case 5:
954       {
955         /* Check if the first half of the destination register is used
956            in the source address.  If so, reverse the order of the loads
957            so that the source address doesn't get clobbered until it is
958            no longer needed. */
959
960         rtx dstreg = operands[0];
961         if (GET_CODE (dstreg) == SUBREG)
962           dstreg = SUBREG_REG (dstreg);
963         if (GET_CODE (dstreg) != REG)
964           abort();
965
966         if (reg_mentioned_p (dstreg, operands[1]))
967           {
968             switch (which_alternative)
969               {
970               case 1: return \"%v1l32i.n\\t%D0, %N1\;l32i.n\\t%0, %1\";
971               case 4: return \"%v1l32r\\t%D0, %N1\;l32r\\t%0, %1\";
972               case 5: return \"%v1l32i\\t%D0, %N1\;l32i\\t%0, %1\";
973               }
974           }
975         else
976           {
977             switch (which_alternative)
978               {
979               case 1: return \"%v1l32i.n\\t%0, %1\;l32i.n\\t%D0, %N1\";
980               case 4: return \"%v1l32r\\t%0, %1\;l32r\\t%D0, %N1\";
981               case 5: return \"%v1l32i\\t%0, %1\;l32i\\t%D0, %N1\";
982               }
983           }
984       }
985     }
986   abort ();
987   return \"\";
988 }"
989   [(set_attr "type"     "move,load,store,move,load,load,store")
990    (set_attr "mode"     "DI")
991    (set_attr "length"   "4,4,4,6,6,6,6")])
992
993
994 ;; 32-bit Integer moves
995
996 (define_expand "movsi"
997   [(set (match_operand:SI 0 "nonimmed_operand" "")
998         (match_operand:SI 1 "general_operand" ""))]
999   ""
1000   "
1001 {
1002   if (xtensa_emit_move_sequence (operands, SImode))
1003     DONE;
1004 }")
1005
1006 (define_insn "movsi_internal"
1007   [(set (match_operand:SI 0 "nonimmed_operand" "=D,D,D,D,R,R,a,q,a,a,a,U,*a,*A")
1008         (match_operand:SI 1 "move_operand" "M,D,d,R,D,d,r,r,I,T,U,r,*A,*r"))]
1009   "xtensa_valid_move (SImode, operands)"
1010   "@
1011    movi.n\\t%0, %x1
1012    mov.n\\t%0, %1
1013    mov.n\\t%0, %1
1014    %v1l32i.n\\t%0, %1
1015    %v0s32i.n\\t%1, %0
1016    %v0s32i.n\\t%1, %0
1017    mov\\t%0, %1
1018    movsp\\t%0, %1
1019    movi\\t%0, %x1
1020    %v1l32r\\t%0, %1
1021    %v1l32i\\t%0, %1
1022    %v0s32i\\t%1, %0
1023    rsr\\t%0, 16 # ACCLO
1024    wsr\\t%1, 16 # ACCLO"
1025   [(set_attr "type"     "move,move,move,load,store,store,move,move,move,load,load,store,rsr,wsr")
1026    (set_attr "mode"     "SI")
1027    (set_attr "length"   "2,2,2,2,2,2,3,3,3,3,3,3,3,3")])
1028
1029 ;; 16-bit Integer moves
1030
1031 (define_expand "movhi"
1032   [(set (match_operand:HI 0 "nonimmed_operand" "")
1033         (match_operand:HI 1 "general_operand" ""))]
1034   ""
1035   "
1036 {
1037   if (xtensa_emit_move_sequence (operands, HImode))
1038     DONE;
1039 }")
1040
1041 (define_insn "movhi_internal"
1042   [(set (match_operand:HI 0 "nonimmed_operand" "=D,D,a,a,a,U,*a,*A")
1043         (match_operand:HI 1 "move_operand" "M,d,r,I,U,r,*A,*r"))]
1044   "xtensa_valid_move (HImode, operands)"
1045   "@
1046    movi.n\\t%0, %x1
1047    mov.n\\t%0, %1
1048    mov\\t%0, %1
1049    movi\\t%0, %x1
1050    %v1l16ui\\t%0, %1
1051    %v0s16i\\t%1, %0
1052    rsr\\t%0, 16 # ACCLO
1053    wsr\\t%1, 16 # ACCLO"
1054   [(set_attr "type"     "move,move,move,move,load,store,rsr,wsr")
1055    (set_attr "mode"     "HI")
1056    (set_attr "length"   "2,2,3,3,3,3,3,3")])
1057
1058 ;; 8-bit Integer moves
1059
1060 (define_expand "movqi"
1061   [(set (match_operand:QI 0 "nonimmed_operand" "")
1062         (match_operand:QI 1 "general_operand" ""))]
1063   ""
1064   "
1065 {
1066   if (xtensa_emit_move_sequence (operands, QImode))
1067     DONE;
1068 }")
1069
1070 (define_insn "movqi_internal"
1071   [(set (match_operand:QI 0 "nonimmed_operand" "=D,D,a,a,a,U,*a,*A")
1072         (match_operand:QI 1 "move_operand" "M,d,r,I,U,r,*A,*r"))]
1073   "xtensa_valid_move (QImode, operands)"
1074   "@
1075    movi.n\\t%0, %x1
1076    mov.n\\t%0, %1
1077    mov\\t%0, %1
1078    movi\\t%0, %x1
1079    %v1l8ui\\t%0, %1
1080    %v0s8i\\t%1, %0
1081    rsr\\t%0, 16 # ACCLO
1082    wsr\\t%1, 16 # ACCLO"
1083   [(set_attr "type"     "move,move,move,move,load,store,rsr,wsr")
1084    (set_attr "mode"     "QI")
1085    (set_attr "length"   "2,2,3,3,3,3,3,3")])
1086
1087 ;; 32-bit floating point moves
1088
1089 (define_expand "movsf"
1090   [(set (match_operand:SF 0 "nonimmed_operand" "")
1091         (match_operand:SF 1 "general_operand" ""))]
1092   ""
1093   "
1094 {
1095   if (GET_CODE (operands[1]) == CONST_DOUBLE)
1096     operands[1] = force_const_mem (SFmode, operands[1]);
1097
1098   if (!(reload_in_progress | reload_completed))
1099     {
1100       if (((!register_operand (operands[0], SFmode)
1101            && !register_operand (operands[1], SFmode))
1102           || (FP_REG_P (xt_true_regnum (operands[0]))
1103               && constantpool_mem_p (operands[1]))))
1104         operands[1] = force_reg (SFmode, operands[1]);
1105
1106       if (xtensa_copy_incoming_a7 (operands, SFmode))
1107         DONE;
1108     }
1109 }")
1110
1111 (define_insn "movsf_internal"
1112   [(set (match_operand:SF 0 "nonimmed_operand"
1113                             "=f,f,U,D,D,R,a,f,a,a,a,U")
1114         (match_operand:SF 1 "non_const_move_operand"
1115                             "f,U,f,d,R,d,r,r,f,T,U,r"))]
1116   "((register_operand (operands[0], SFmode)
1117      || register_operand (operands[1], SFmode))
1118     && (!FP_REG_P (xt_true_regnum (operands[0]))
1119         || !constantpool_mem_p (operands[1])))"
1120   "@
1121    mov.s\\t%0, %1
1122    %v1lsi\\t%0, %1
1123    %v0ssi\\t%1, %0
1124    mov.n\\t%0, %1
1125    %v1l32i.n\\t%0, %1
1126    %v0s32i.n\\t%1, %0
1127    mov\\t%0, %1
1128    wfr\\t%0, %1
1129    rfr\\t%0, %1
1130    %v1l32r\\t%0, %1
1131    %v1l32i\\t%0, %1
1132    %v0s32i\\t%1, %0"
1133   [(set_attr "type"     "farith,fload,fstore,move,load,store,move,farith,farith,load,load,store")
1134    (set_attr "mode"     "SF")
1135    (set_attr "length"   "3,3,3,2,2,2,3,3,3,3,3,3")])
1136
1137 (define_insn "*lsiu"
1138   [(set (match_operand:SF 0 "register_operand" "=f")
1139         (mem:SF (plus:SI (match_operand:SI 1 "register_operand" "+a")
1140                          (match_operand:SI 2 "fpmem_offset_operand" "i"))))
1141    (set (match_dup 1)
1142         (plus:SI (match_dup 1) (match_dup 2)))]
1143   "TARGET_HARD_FLOAT"
1144   "*
1145 {
1146   if (TARGET_SERIALIZE_VOLATILE && volatile_refs_p (PATTERN (insn)))
1147     output_asm_insn (\"memw\", operands);
1148   return \"lsiu\\t%0, %1, %2\";
1149 }"
1150   [(set_attr "type"     "fload")
1151    (set_attr "mode"     "SF")
1152    (set_attr "length"   "3")])
1153
1154 (define_insn "*ssiu"
1155   [(set (mem:SF (plus:SI (match_operand:SI 0 "register_operand" "+a")
1156                          (match_operand:SI 1 "fpmem_offset_operand" "i")))
1157         (match_operand:SF 2 "register_operand" "f"))
1158    (set (match_dup 0)
1159         (plus:SI (match_dup 0) (match_dup 1)))]
1160   "TARGET_HARD_FLOAT"
1161   "*
1162 {
1163   if (TARGET_SERIALIZE_VOLATILE && volatile_refs_p (PATTERN (insn)))
1164     output_asm_insn (\"memw\", operands);
1165   return \"ssiu\\t%2, %0, %1\";
1166 }"
1167   [(set_attr "type"     "fstore")
1168    (set_attr "mode"     "SF")
1169    (set_attr "length"   "3")])
1170
1171 ;; 64-bit floating point moves
1172
1173 (define_expand "movdf"
1174   [(set (match_operand:DF 0 "nonimmed_operand" "")
1175         (match_operand:DF 1 "general_operand" ""))]
1176   ""
1177   "
1178 {
1179   if (GET_CODE (operands[1]) == CONST_DOUBLE)
1180     operands[1] = force_const_mem (DFmode, operands[1]);
1181
1182   if (!(reload_in_progress | reload_completed))
1183     {
1184       if (!register_operand (operands[0], DFmode)
1185           && !register_operand (operands[1], DFmode))
1186         operands[1] = force_reg (DFmode, operands[1]);
1187
1188       if (xtensa_copy_incoming_a7 (operands, DFmode))
1189         DONE;
1190     }
1191 }")
1192
1193 (define_insn "movdf_internal"
1194   [(set (match_operand:DF 0 "nonimmed_operand" "=D,D,S,a,a,a,U")
1195         (match_operand:DF 1 "non_const_move_operand" "d,S,d,r,T,U,r"))]
1196   "register_operand (operands[0], DFmode)
1197    || register_operand (operands[1], DFmode)"
1198   "*
1199 {
1200   switch (which_alternative)
1201     {
1202     case 0: return \"mov.n\\t%0, %1\;mov.n\\t%D0, %D1\";
1203     case 2: return \"%v0s32i.n\\t%1, %0\;s32i.n\\t%D1, %N0\";
1204     case 3: return \"mov\\t%0, %1\;mov\\t%D0, %D1\";
1205     case 6: return \"%v0s32i\\t%1, %0\;s32i\\t%D1, %N0\";
1206
1207     case 1:
1208     case 4:
1209     case 5:
1210       {
1211         /* Check if the first half of the destination register is used
1212            in the source address.  If so, reverse the order of the loads
1213            so that the source address doesn't get clobbered until it is
1214            no longer needed. */
1215
1216         rtx dstreg = operands[0];
1217         if (GET_CODE (dstreg) == SUBREG)
1218           dstreg = SUBREG_REG (dstreg);
1219         if (GET_CODE (dstreg) != REG)
1220           abort ();
1221
1222         if (reg_mentioned_p (dstreg, operands[1]))
1223           {
1224             switch (which_alternative)
1225               {
1226               case 1: return \"%v1l32i.n\\t%D0, %N1\;l32i.n\\t%0, %1\";
1227               case 4: return \"%v1l32r\\t%D0, %N1\;l32r\\t%0, %1\";
1228               case 5: return \"%v1l32i\\t%D0, %N1\;l32i\\t%0, %1\";
1229               }
1230           }
1231         else
1232           {
1233             switch (which_alternative)
1234               {
1235               case 1: return \"%v1l32i.n\\t%0, %1\;l32i.n\\t%D0, %N1\";
1236               case 4: return \"%v1l32r\\t%0, %1\;l32r\\t%D0, %N1\";
1237               case 5: return \"%v1l32i\\t%0, %1\;l32i\\t%D0, %N1\";
1238               }
1239           }
1240       }
1241     }
1242   abort ();
1243   return \"\";
1244 }"
1245   [(set_attr "type"     "move,load,store,move,load,load,store")
1246    (set_attr "mode"     "DF")
1247    (set_attr "length"   "4,4,4,6,6,6,6")])
1248
1249 ;; Block moves
1250
1251 (define_expand "movstrsi"
1252   [(parallel [(set (match_operand:BLK 0 "" "")
1253                    (match_operand:BLK 1 "" ""))
1254               (use (match_operand:SI 2 "arith_operand" ""))
1255               (use (match_operand:SI 3 "const_int_operand" ""))])]
1256   ""
1257   "
1258 {
1259   if (!xtensa_expand_block_move (operands)) FAIL;
1260   DONE;
1261 }")
1262
1263 (define_insn "movstrsi_internal"
1264   [(set (match_operand:BLK 0 "memory_operand" "=U")
1265         (match_operand:BLK 1 "memory_operand" "U"))
1266    (use (match_operand:SI 2 "arith_operand" ""))
1267    (use (match_operand:SI 3 "const_int_operand" ""))
1268    (clobber (match_scratch:SI 4 "=&r"))
1269    (clobber (match_scratch:SI 5 "=&r"))]
1270   ""
1271   "*
1272 {
1273   rtx tmpregs[2];
1274   tmpregs[0] = operands[4];
1275   tmpregs[1] = operands[5];
1276   xtensa_emit_block_move (operands, tmpregs, 1);
1277   return \"\";
1278 }"
1279   [(set_attr "type"     "multi")
1280    (set_attr "mode"     "none")
1281    (set_attr "length"   "300")])
1282
1283
1284 ;;
1285 ;;  ....................
1286 ;;
1287 ;;      SHIFTS
1288 ;;
1289 ;;  ....................
1290 ;;
1291
1292 (define_insn "ashlsi3"
1293   [(set (match_operand:SI 0 "register_operand" "=a,a")
1294         (ashift:SI (match_operand:SI 1 "register_operand" "r,r")
1295                    (match_operand:SI 2 "arith_operand" "J,r")))]
1296   ""      
1297   "@
1298    slli\\t%0, %1, %R2
1299    ssl\\t%2\;sll\\t%0, %1"
1300   [(set_attr "type"     "arith,arith")
1301    (set_attr "mode"     "SI")
1302    (set_attr "length"   "3,6")])
1303
1304 (define_insn "ashrsi3"
1305   [(set (match_operand:SI 0 "register_operand" "=a,a")
1306         (ashiftrt:SI (match_operand:SI 1 "register_operand" "r,r")
1307                      (match_operand:SI 2 "arith_operand" "J,r")))]
1308   ""
1309   "@
1310    srai\\t%0, %1, %R2
1311    ssr\\t%2\;sra\\t%0, %1"
1312   [(set_attr "type"     "arith,arith")
1313    (set_attr "mode"     "SI")
1314    (set_attr "length"   "3,6")])
1315
1316 (define_insn "lshrsi3"
1317   [(set (match_operand:SI 0 "register_operand" "=a,a")
1318         (lshiftrt:SI (match_operand:SI 1 "register_operand" "r,r")
1319                      (match_operand:SI 2 "arith_operand" "J,r")))]
1320   ""
1321   "*
1322 {
1323   if (which_alternative == 0)
1324     {
1325       if ((INTVAL (operands[2]) & 0x1f) < 16)
1326         return \"srli\\t%0, %1, %R2\";
1327       else
1328         return \"extui\\t%0, %1, %R2, %L2\";
1329     }
1330   return \"ssr\\t%2\;srl\\t%0, %1\";
1331 }"
1332   [(set_attr "type"     "arith,arith")
1333    (set_attr "mode"     "SI")
1334    (set_attr "length"   "3,6")])
1335
1336 (define_insn "rotlsi3"
1337   [(set (match_operand:SI 0 "register_operand" "=a,a")
1338         (rotate:SI (match_operand:SI 1 "register_operand" "r,r")
1339                      (match_operand:SI 2 "arith_operand" "J,r")))]
1340   ""
1341   "@
1342    ssai\\t%L2\;src\\t%0, %1, %1
1343    ssl\\t%2\;src\\t%0, %1, %1"
1344   [(set_attr "type"     "multi,multi")
1345    (set_attr "mode"     "SI")
1346    (set_attr "length"   "6,6")])
1347
1348 (define_insn "rotrsi3"
1349   [(set (match_operand:SI 0 "register_operand" "=a,a")
1350         (rotatert:SI (match_operand:SI 1 "register_operand" "r,r")
1351                      (match_operand:SI 2 "arith_operand" "J,r")))]
1352   ""
1353   "@
1354    ssai\\t%R2\;src\\t%0, %1, %1
1355    ssr\\t%2\;src\\t%0, %1, %1"
1356   [(set_attr "type"     "multi,multi")
1357    (set_attr "mode"     "SI")
1358    (set_attr "length"   "6,6")])
1359
1360
1361 ;;
1362 ;;  ....................
1363 ;;
1364 ;;      COMPARISONS
1365 ;;
1366 ;;  ....................
1367 ;;
1368
1369 ;; Like the md files for MIPS and SPARC, we handle comparisons by stashing
1370 ;; away the operands and then using that information in the subsequent
1371 ;; conditional branch.
1372
1373 (define_expand "cmpsi"
1374   [(set (cc0)
1375         (compare:CC (match_operand:SI 0 "register_operand" "")
1376                     (match_operand:SI 1 "nonmemory_operand" "")))]
1377   ""
1378   "
1379 {
1380   branch_cmp[0] = operands[0];
1381   branch_cmp[1] = operands[1];
1382   branch_type = CMP_SI;
1383   DONE;
1384 }")
1385
1386 (define_expand "tstsi"
1387   [(set (cc0)
1388         (match_operand:SI 0 "register_operand" ""))]
1389   ""
1390   "
1391 {
1392   branch_cmp[0] = operands[0];
1393   branch_cmp[1] = const0_rtx;
1394   branch_type = CMP_SI;
1395   DONE;
1396 }")
1397
1398 (define_expand "cmpsf"
1399   [(set (cc0)
1400         (compare:CC (match_operand:SF 0 "register_operand" "")
1401                     (match_operand:SF 1 "register_operand" "")))]
1402   "TARGET_HARD_FLOAT"
1403   "
1404 {
1405   branch_cmp[0] = operands[0];
1406   branch_cmp[1] = operands[1];
1407   branch_type = CMP_SF;
1408   DONE;
1409 }")
1410
1411
1412 ;;
1413 ;;  ....................
1414 ;;
1415 ;;      CONDITIONAL BRANCHES
1416 ;;
1417 ;;  ....................
1418 ;;
1419
1420 (define_expand "beq"
1421   [(set (pc)
1422         (if_then_else (eq (cc0) (const_int 0))
1423                       (label_ref (match_operand 0 "" ""))
1424                       (pc)))]
1425   ""
1426   "
1427 {
1428   xtensa_expand_conditional_branch (operands, EQ);
1429   DONE;
1430 }")
1431
1432 (define_expand "bne"
1433   [(set (pc)
1434         (if_then_else (ne (cc0) (const_int 0))
1435                       (label_ref (match_operand 0 "" ""))
1436                       (pc)))]
1437   ""
1438   "
1439 {
1440   xtensa_expand_conditional_branch (operands, NE);
1441   DONE;
1442 }")
1443
1444 (define_expand "bgt"
1445   [(set (pc)
1446         (if_then_else (gt (cc0) (const_int 0))
1447                       (label_ref (match_operand 0 "" ""))
1448                       (pc)))]
1449   ""
1450   "
1451 {
1452   xtensa_expand_conditional_branch (operands, GT);
1453   DONE;
1454 }")
1455
1456 (define_expand "bge"
1457   [(set (pc)
1458         (if_then_else (ge (cc0) (const_int 0))
1459                       (label_ref (match_operand 0 "" ""))
1460                       (pc)))]
1461   ""
1462   "
1463 {
1464   xtensa_expand_conditional_branch (operands, GE);
1465   DONE;
1466 }")
1467
1468 (define_expand "blt"
1469   [(set (pc)
1470         (if_then_else (lt (cc0) (const_int 0))
1471                       (label_ref (match_operand 0 "" ""))
1472                       (pc)))]
1473   ""
1474   "
1475 {
1476   xtensa_expand_conditional_branch (operands, LT);
1477   DONE;
1478 }")
1479
1480 (define_expand "ble"
1481   [(set (pc)
1482         (if_then_else (le (cc0) (const_int 0))
1483                       (label_ref (match_operand 0 "" ""))
1484                       (pc)))]
1485   ""
1486   "
1487 {
1488   xtensa_expand_conditional_branch (operands, LE);
1489   DONE;
1490 }")
1491
1492 (define_expand "bgtu"
1493   [(set (pc)
1494         (if_then_else (gtu (cc0) (const_int 0))
1495                       (label_ref (match_operand 0 "" ""))
1496                       (pc)))]
1497   ""
1498   "
1499 {
1500   xtensa_expand_conditional_branch (operands, GTU);
1501   DONE;
1502 }")
1503
1504 (define_expand "bgeu"
1505   [(set (pc)
1506         (if_then_else (geu (cc0) (const_int 0))
1507                       (label_ref (match_operand 0 "" ""))
1508                       (pc)))]
1509   ""
1510   "
1511 {
1512   xtensa_expand_conditional_branch (operands, GEU);
1513   DONE;
1514 }")
1515
1516 (define_expand "bltu"
1517   [(set (pc)
1518         (if_then_else (ltu (cc0) (const_int 0))
1519                       (label_ref (match_operand 0 "" ""))
1520                       (pc)))]
1521   ""
1522   "
1523 {
1524   xtensa_expand_conditional_branch (operands, LTU);
1525   DONE;
1526 }")
1527
1528 (define_expand "bleu"
1529   [(set (pc)
1530         (if_then_else (leu (cc0) (const_int 0))
1531                       (label_ref (match_operand 0 "" ""))
1532                       (pc)))]
1533   ""
1534   "
1535 {
1536   xtensa_expand_conditional_branch (operands, LEU);
1537   DONE;
1538 }")
1539
1540 ;; Branch patterns for standard integer comparisons
1541
1542 (define_insn "*btrue"
1543   [(set (pc)
1544         (if_then_else (match_operator 3 "branch_operator"
1545                          [(match_operand:SI 0 "register_operand" "r,r")
1546                           (match_operand:SI 1 "branch_operand" "K,r")])
1547                       (label_ref (match_operand 2 "" ""))
1548                       (pc)))]
1549   ""
1550   "*
1551 {
1552   if (which_alternative == 1)
1553     {
1554       switch (GET_CODE (operands[3]))
1555         {
1556         case EQ:        return \"beq\\t%0, %1, %2\";
1557         case NE:        return \"bne\\t%0, %1, %2\";
1558         case LT:        return \"blt\\t%0, %1, %2\";
1559         case GE:        return \"bge\\t%0, %1, %2\";
1560         default:        break;
1561         }
1562     }
1563   else if (INTVAL (operands[1]) == 0)
1564     {
1565       switch (GET_CODE (operands[3]))
1566         {
1567         case EQ:        return (TARGET_DENSITY
1568                                 ? \"beqz.n\\t%0, %2\"
1569                                 : \"beqz\\t%0, %2\");
1570         case NE:        return (TARGET_DENSITY
1571                                 ? \"bnez.n\\t%0, %2\"
1572                                 : \"bnez\\t%0, %2\");
1573         case LT:        return \"bltz\\t%0, %2\";
1574         case GE:        return \"bgez\\t%0, %2\";
1575         default:        break;
1576         }
1577     }
1578   else
1579     {
1580       switch (GET_CODE (operands[3]))
1581         {
1582         case EQ:        return \"beqi\\t%0, %d1, %2\";
1583         case NE:        return \"bnei\\t%0, %d1, %2\";
1584         case LT:        return \"blti\\t%0, %d1, %2\";
1585         case GE:        return \"bgei\\t%0, %d1, %2\";
1586         default:        break;
1587         }
1588     }
1589   fatal_insn (\"unexpected branch operator\", operands[3]);
1590   return \"\";
1591 }"
1592   [(set_attr "type"     "jump,jump")
1593    (set_attr "mode"     "none")
1594    (set_attr "length"   "3,3")])
1595
1596 (define_insn "*bfalse"
1597   [(set (pc)
1598         (if_then_else (match_operator 3 "branch_operator"
1599                          [(match_operand:SI 0 "register_operand" "r,r")
1600                           (match_operand:SI 1 "branch_operand" "K,r")])
1601                       (pc)
1602                       (label_ref (match_operand 2 "" ""))))]
1603   ""
1604   "*
1605 {
1606   if (which_alternative == 1)
1607     {
1608       switch (GET_CODE (operands[3]))
1609         {
1610         case EQ:        return \"bne\\t%0, %1, %2\";
1611         case NE:        return \"beq\\t%0, %1, %2\";
1612         case LT:        return \"bge\\t%0, %1, %2\";
1613         case GE:        return \"blt\\t%0, %1, %2\";
1614         default:        break;
1615         }
1616     }
1617   else if (INTVAL (operands[1]) == 0)
1618     {
1619       switch (GET_CODE (operands[3]))
1620         {
1621         case EQ:        return (TARGET_DENSITY
1622                                 ? \"bnez.n\\t%0, %2\"
1623                                 : \"bnez\\t%0, %2\");
1624         case NE:        return (TARGET_DENSITY
1625                                 ? \"beqz.n\\t%0, %2\"
1626                                 : \"beqz\\t%0, %2\");
1627         case LT:        return \"bgez\\t%0, %2\";
1628         case GE:        return \"bltz\\t%0, %2\";
1629         default:        break;
1630         }
1631     }
1632   else
1633     {
1634       switch (GET_CODE (operands[3]))
1635         {
1636         case EQ:        return \"bnei\\t%0, %d1, %2\";
1637         case NE:        return \"beqi\\t%0, %d1, %2\";
1638         case LT:        return \"bgei\\t%0, %d1, %2\";
1639         case GE:        return \"blti\\t%0, %d1, %2\";
1640         default:        break;
1641         }
1642     }
1643   fatal_insn (\"unexpected branch operator\", operands[3]);
1644   return \"\";
1645 }"
1646   [(set_attr "type"     "jump,jump")
1647    (set_attr "mode"     "none")
1648    (set_attr "length"   "3,3")])
1649
1650 (define_insn "*ubtrue"
1651   [(set (pc)
1652         (if_then_else (match_operator 3 "ubranch_operator"
1653                          [(match_operand:SI 0 "register_operand" "r,r")
1654                           (match_operand:SI 1 "ubranch_operand" "L,r")])
1655                       (label_ref (match_operand 2 "" ""))
1656                       (pc)))]
1657   ""
1658   "*
1659 {
1660   if (which_alternative == 1)
1661     {
1662       switch (GET_CODE (operands[3]))
1663         {
1664         case LTU:       return \"bltu\\t%0, %1, %2\";
1665         case GEU:       return \"bgeu\\t%0, %1, %2\";
1666         default:        break;
1667         }
1668     }
1669   else
1670     {
1671       switch (GET_CODE (operands[3]))
1672         {
1673         case LTU:       return \"bltui\\t%0, %d1, %2\";
1674         case GEU:       return \"bgeui\\t%0, %d1, %2\";
1675         default:        break;
1676         }
1677     }
1678   fatal_insn (\"unexpected branch operator\", operands[3]);
1679   return \"\";
1680 }"
1681   [(set_attr "type"     "jump,jump")
1682    (set_attr "mode"     "none")
1683    (set_attr "length"   "3,3")])
1684
1685 (define_insn "*ubfalse"
1686   [(set (pc)
1687         (if_then_else (match_operator 3 "ubranch_operator"
1688                          [(match_operand:SI 0 "register_operand" "r,r")
1689                           (match_operand:SI 1 "ubranch_operand" "L,r")])
1690                       (pc)
1691                       (label_ref (match_operand 2 "" ""))))]
1692   ""
1693   "*
1694 {
1695   if (which_alternative == 1)
1696     {
1697       switch (GET_CODE (operands[3]))
1698         {
1699         case LTU:       return \"bgeu\\t%0, %1, %2\";
1700         case GEU:       return \"bltu\\t%0, %1, %2\";
1701         default:        break;
1702         }
1703     }
1704   else
1705     {
1706       switch (GET_CODE (operands[3]))
1707         {
1708         case LTU:       return \"bgeui\\t%0, %d1, %2\";
1709         case GEU:       return \"bltui\\t%0, %d1, %2\";
1710         default:        break;
1711         }
1712     }
1713   fatal_insn (\"unexpected branch operator\", operands[3]);
1714   return \"\";
1715 }"
1716   [(set_attr "type"     "jump,jump")
1717    (set_attr "mode"     "none")
1718    (set_attr "length"   "3,3")])
1719
1720 ;; Branch patterns for bit testing
1721
1722 (define_insn "*bittrue"
1723   [(set (pc)
1724         (if_then_else (match_operator 3 "boolean_operator"
1725                         [(zero_extract:SI
1726                             (match_operand:SI 0 "register_operand" "r,r")
1727                             (const_int 1)
1728                             (match_operand:SI 1 "arith_operand" "J,r"))
1729                          (const_int 0)])
1730                       (label_ref (match_operand 2 "" ""))
1731                       (pc)))]
1732   ""
1733   "*
1734 {
1735   if (which_alternative == 0)
1736     {
1737       unsigned bitnum = INTVAL(operands[1]) & 0x1f;
1738       operands[1] = GEN_INT(bitnum);
1739       switch (GET_CODE (operands[3]))
1740         {
1741         case EQ:        return \"bbci\\t%0, %d1, %2\";
1742         case NE:        return \"bbsi\\t%0, %d1, %2\";
1743         default:        break;
1744         }
1745     }
1746   else
1747     {
1748       switch (GET_CODE (operands[3]))
1749         {
1750         case EQ:        return \"bbc\\t%0, %1, %2\";
1751         case NE:        return \"bbs\\t%0, %1, %2\";
1752         default:        break;
1753         }
1754     }
1755   fatal_insn (\"unexpected branch operator\", operands[3]);
1756   return \"\";
1757 }"
1758   [(set_attr "type"     "jump")
1759    (set_attr "mode"     "none")
1760    (set_attr "length"   "3")])
1761
1762 (define_insn "*bitfalse"
1763   [(set (pc)
1764         (if_then_else (match_operator 3 "boolean_operator"
1765                         [(zero_extract:SI
1766                             (match_operand:SI 0 "register_operand" "r,r")
1767                             (const_int 1)
1768                             (match_operand:SI 1 "arith_operand" "J,r"))
1769                          (const_int 0)])
1770                       (pc)
1771                       (label_ref (match_operand 2 "" ""))))]
1772   ""
1773   "*
1774 {
1775   if (which_alternative == 0)
1776     {
1777       unsigned bitnum = INTVAL (operands[1]) & 0x1f;
1778       operands[1] = GEN_INT (bitnum);
1779       switch (GET_CODE (operands[3]))
1780         {
1781         case EQ:    return \"bbsi\\t%0, %d1, %2\";
1782         case NE:    return \"bbci\\t%0, %d1, %2\";
1783         default:    break;
1784         }
1785     }
1786   else
1787     {
1788       switch (GET_CODE (operands[3]))
1789         {
1790         case EQ:        return \"bbs\\t%0, %1, %2\";
1791         case NE:        return \"bbc\\t%0, %1, %2\";
1792         default:        break;
1793         }
1794     }
1795   fatal_insn (\"unexpected branch operator\", operands[3]);
1796   return \"\";
1797 }"
1798   [(set_attr "type"     "jump")
1799    (set_attr "mode"     "none")
1800    (set_attr "length"   "3")])
1801
1802 (define_insn "*masktrue"
1803   [(set (pc)
1804         (if_then_else (match_operator 3 "boolean_operator"
1805                  [(and:SI (match_operand:SI 0 "register_operand" "r")
1806                           (match_operand:SI 1 "register_operand" "r"))
1807                   (const_int 0)])
1808                       (label_ref (match_operand 2 "" ""))
1809                       (pc)))]
1810   ""
1811   "*
1812 {
1813   switch (GET_CODE (operands[3]))
1814     {
1815     case EQ:    return \"bnone\\t%0, %1, %2\";
1816     case NE:    return \"bany\\t%0, %1, %2\";
1817     default:    break;
1818     }
1819   fatal_insn (\"unexpected branch operator\", operands[3]);
1820   return \"\";
1821 }"
1822   [(set_attr "type"     "jump")
1823    (set_attr "mode"     "none")
1824    (set_attr "length"   "3")])
1825
1826 (define_insn "*maskfalse"
1827   [(set (pc)
1828         (if_then_else (match_operator 3 "boolean_operator"
1829                  [(and:SI (match_operand:SI 0 "register_operand" "r")
1830                           (match_operand:SI 1 "register_operand" "r"))
1831                   (const_int 0)])
1832                       (pc)
1833                       (label_ref (match_operand 2 "" ""))))]
1834   ""
1835   "*
1836 {
1837   switch (GET_CODE (operands[3]))
1838     {
1839     case EQ:    return \"bany\\t%0, %1, %2\";
1840     case NE:    return \"bnone\\t%0, %1, %2\";
1841     default:    break;
1842     }
1843   fatal_insn (\"unexpected branch operator\", operands[3]);
1844   return \"\";
1845 }"
1846   [(set_attr "type"     "jump")
1847    (set_attr "mode"     "none")
1848    (set_attr "length"   "3")])
1849
1850
1851 ;; Define the loop insns that is used by bct optimization to represent the
1852 ;; start and end of a zero-overhead loop (in loop.c). This start template
1853 ;; generates the loop insn, the end template doesn't generate any instructions
1854 ;; since since loop end is handled in hardware.
1855
1856 (define_insn "zero_cost_loop_start"
1857   [(set (pc) (if_then_else (eq (match_operand:SI 0 "register_operand" "a")
1858                                (const_int 0))
1859                            (label_ref (match_operand 1 "" ""))
1860                            (pc)))
1861    (set (reg:SI 19)
1862         (plus:SI (match_dup 0) (const_int -1)))]
1863   ""
1864   "loopnez %0, %l1"
1865   [(set_attr "type"     "jump")
1866    (set_attr "mode"     "none")
1867    (set_attr "length"   "3")])
1868
1869 (define_insn "zero_cost_loop_end"
1870   [(set (pc) (if_then_else (ne (reg:SI 19) (const_int 0))
1871                            (label_ref (match_operand 0 "" ""))
1872                            (pc)))
1873    (set (reg:SI 19)
1874         (plus:SI (reg:SI 19) (const_int -1)))]
1875   ""
1876   "*
1877     xtensa_emit_loop_end (insn, operands);
1878     return \"\";
1879   "
1880   [(set_attr "type"     "jump")
1881    (set_attr "mode"     "none")
1882    (set_attr "length"   "0")])
1883
1884
1885 ;;
1886 ;;  ....................
1887 ;;
1888 ;;      SETTING A REGISTER FROM A COMPARISON
1889 ;;
1890 ;;  ....................
1891 ;;
1892
1893 (define_expand "seq"
1894   [(set (match_operand:SI 0 "register_operand" "")
1895         (match_dup 1))]
1896   ""
1897   "
1898 {
1899   operands[1] = gen_rtx (EQ, SImode, branch_cmp[0], branch_cmp[1]);
1900   if (!xtensa_expand_scc (operands)) FAIL;
1901   DONE;
1902 }")
1903
1904 (define_expand "sne"
1905   [(set (match_operand:SI 0 "register_operand" "")
1906         (match_dup 1))]
1907   ""
1908   "
1909 {
1910   operands[1] = gen_rtx (NE, SImode, branch_cmp[0], branch_cmp[1]);
1911   if (!xtensa_expand_scc (operands)) FAIL;
1912   DONE;
1913 }")
1914
1915 (define_expand "sgt"
1916   [(set (match_operand:SI 0 "register_operand" "")
1917         (match_dup 1))]
1918   ""
1919   "
1920 {
1921   operands[1] = gen_rtx (GT, SImode, branch_cmp[0], branch_cmp[1]);
1922   if (!xtensa_expand_scc (operands)) FAIL;
1923   DONE;
1924 }")
1925
1926 (define_expand "sge"
1927   [(set (match_operand:SI 0 "register_operand" "")
1928         (match_dup 1))]
1929   ""
1930   "
1931 {
1932   operands[1] = gen_rtx (GE, SImode, branch_cmp[0], branch_cmp[1]);
1933   if (!xtensa_expand_scc (operands)) FAIL;
1934   DONE;
1935 }")
1936
1937 (define_expand "slt"
1938   [(set (match_operand:SI 0 "register_operand" "")
1939         (match_dup 1))]
1940   ""
1941   "
1942 {
1943   operands[1] = gen_rtx (LT, SImode, branch_cmp[0], branch_cmp[1]);
1944   if (!xtensa_expand_scc (operands)) FAIL;
1945   DONE;
1946 }")
1947
1948 (define_expand "sle"
1949   [(set (match_operand:SI 0 "register_operand" "")
1950         (match_dup 1))]
1951   ""
1952   "
1953 {
1954   operands[1] = gen_rtx (LE, SImode, branch_cmp[0], branch_cmp[1]);
1955   if (!xtensa_expand_scc (operands)) FAIL;
1956   DONE;
1957 }")
1958
1959
1960 ;;
1961 ;;  ....................
1962 ;;
1963 ;;      CONDITIONAL MOVES
1964 ;;
1965 ;;  ....................
1966 ;;
1967
1968 (define_expand "movsicc"
1969   [(set (match_operand:SI 0 "register_operand" "")
1970         (if_then_else:SI (match_operand 1 "comparison_operator" "")
1971                          (match_operand:SI 2 "register_operand" "")
1972                          (match_operand:SI 3 "register_operand" "")))]
1973   ""
1974   "
1975 {
1976   if (!xtensa_expand_conditional_move (operands, 0)) FAIL;
1977   DONE;
1978 }")
1979
1980 (define_expand "movsfcc"
1981   [(set (match_operand:SF 0 "register_operand" "")
1982         (if_then_else:SF (match_operand 1 "comparison_operator" "")
1983                          (match_operand:SF 2 "register_operand" "")
1984                          (match_operand:SF 3 "register_operand" "")))]
1985   ""
1986   "
1987 {
1988   if (!xtensa_expand_conditional_move (operands, 1)) FAIL;
1989   DONE;
1990 }")
1991
1992 (define_insn "movsicc_internal0"
1993   [(set (match_operand:SI 0 "register_operand" "=a,a")
1994         (if_then_else:SI (match_operator 4 "branch_operator"
1995                            [(match_operand:SI 1 "register_operand" "r,r")
1996                             (const_int 0)])
1997                          (match_operand:SI 2 "register_operand" "r,0")
1998                          (match_operand:SI 3 "register_operand" "0,r")))]
1999   ""
2000   "*
2001 {
2002   if (which_alternative == 0)
2003     {
2004       switch (GET_CODE (operands[4]))
2005         {
2006         case EQ:        return \"moveqz\\t%0, %2, %1\";
2007         case NE:        return \"movnez\\t%0, %2, %1\";
2008         case LT:        return \"movltz\\t%0, %2, %1\";
2009         case GE:        return \"movgez\\t%0, %2, %1\";
2010         default:        break;
2011         }
2012     }
2013   else
2014     {
2015       switch (GET_CODE (operands[4]))
2016         {
2017         case EQ:        return \"movnez\\t%0, %3, %1\";
2018         case NE:        return \"moveqz\\t%0, %3, %1\";
2019         case LT:        return \"movgez\\t%0, %3, %1\";
2020         case GE:        return \"movltz\\t%0, %3, %1\";
2021         default:        break;
2022         }
2023     }
2024   fatal_insn (\"unexpected cmov operator\", operands[4]);
2025   return \"\";
2026 }"
2027   [(set_attr "type"     "move,move")
2028    (set_attr "mode"     "SI")
2029    (set_attr "length"   "3,3")])
2030
2031 (define_insn "movsicc_internal1"
2032   [(set (match_operand:SI 0 "register_operand" "=a,a")
2033         (if_then_else:SI (match_operator 4 "boolean_operator"
2034                            [(match_operand:CC 1 "register_operand" "b,b")
2035                             (const_int 0)])
2036                          (match_operand:SI 2 "register_operand" "r,0")
2037                          (match_operand:SI 3 "register_operand" "0,r")))]
2038   "TARGET_BOOLEANS"
2039   "*
2040 {
2041   int isEq = (GET_CODE (operands[4]) == EQ);
2042   switch (which_alternative)
2043     {
2044     case 0:
2045       if (isEq) return \"movf\\t%0, %2, %1\";
2046       return \"movt\\t%0, %2, %1\";
2047     case 1:
2048       if (isEq) return \"movt\\t%0, %3, %1\";
2049       return \"movf\\t%0, %3, %1\";
2050     }
2051   abort ();
2052   return \"\";
2053 }"
2054   [(set_attr "type"     "move,move")
2055    (set_attr "mode"     "SI")
2056    (set_attr "length"   "3,3")])
2057
2058 (define_insn "movsfcc_internal0"
2059   [(set (match_operand:SF 0 "register_operand" "=a,a,f,f")
2060         (if_then_else:SF (match_operator 4 "branch_operator"
2061                            [(match_operand:SI 1 "register_operand" "r,r,r,r")
2062                             (const_int 0)])
2063                          (match_operand:SF 2 "register_operand" "r,0,f,0")
2064                          (match_operand:SF 3 "register_operand" "0,r,0,f")))]
2065   ""
2066   "*
2067 {
2068   if (which_alternative == 0)
2069     {
2070       switch (GET_CODE (operands[4]))
2071         {
2072         case EQ:        return \"moveqz\\t%0, %2, %1\";
2073         case NE:        return \"movnez\\t%0, %2, %1\";
2074         case LT:        return \"movltz\\t%0, %2, %1\";
2075         case GE:        return \"movgez\\t%0, %2, %1\";
2076         default:        break;
2077         }
2078     }
2079   else if (which_alternative == 1)
2080     {
2081       switch (GET_CODE (operands[4]))
2082         {
2083         case EQ:        return \"movnez\\t%0, %3, %1\";
2084         case NE:        return \"moveqz\\t%0, %3, %1\";
2085         case LT:        return \"movgez\\t%0, %3, %1\";
2086         case GE:        return \"movltz\\t%0, %3, %1\";
2087         default:        break;
2088         }
2089     }
2090   else if (which_alternative == 2)
2091     {
2092       switch (GET_CODE (operands[4]))
2093         {
2094         case EQ:        return \"moveqz.s %0, %2, %1\";
2095         case NE:        return \"movnez.s %0, %2, %1\";
2096         case LT:        return \"movltz.s %0, %2, %1\";
2097         case GE:        return \"movgez.s %0, %2, %1\";
2098         default:        break;
2099         }
2100     }
2101   else if (which_alternative == 3)
2102     {
2103       switch (GET_CODE (operands[4]))
2104         {
2105         case EQ:        return \"movnez.s %0, %3, %1\";
2106         case NE:        return \"moveqz.s %0, %3, %1\";
2107         case LT:        return \"movgez.s %0, %3, %1\";
2108         case GE:        return \"movltz.s %0, %3, %1\";
2109         default:        break;
2110         }
2111     }
2112   fatal_insn (\"unexpected cmov operator\", operands[4]);
2113   return \"\";
2114 }"
2115   [(set_attr "type"     "move,move,move,move")
2116    (set_attr "mode"     "SF")
2117    (set_attr "length"   "3,3,3,3")])
2118
2119 (define_insn "movsfcc_internal1"
2120   [(set (match_operand:SF 0 "register_operand" "=a,a,f,f")
2121         (if_then_else:SF (match_operator 4 "boolean_operator"
2122                            [(match_operand:CC 1 "register_operand" "b,b,b,b")
2123                             (const_int 0)])
2124                          (match_operand:SF 2 "register_operand" "r,0,f,0")
2125                          (match_operand:SF 3 "register_operand" "0,r,0,f")))]
2126   "TARGET_BOOLEANS"
2127   "*
2128 {
2129   int isEq = (GET_CODE (operands[4]) == EQ);
2130   switch (which_alternative)
2131     {
2132     case 0:
2133       if (isEq) return \"movf\\t%0, %2, %1\";
2134       return \"movt\\t%0, %2, %1\";
2135     case 1:
2136       if (isEq) return \"movt\\t%0, %3, %1\";
2137       return \"movf\\t%0, %3, %1\";
2138     case 2:
2139       if (isEq) return \"movf.s\\t%0, %2, %1\";
2140       return \"movt.s\\t%0, %2, %1\";
2141     case 3:
2142       if (isEq) return \"movt.s\\t%0, %3, %1\";
2143       return \"movf.s\\t%0, %3, %1\";
2144     }
2145   abort ();
2146   return \"\";
2147 }"
2148   [(set_attr "type"     "move,move,move,move")
2149    (set_attr "mode"     "SF")
2150    (set_attr "length"   "3,3,3,3")])
2151
2152
2153 ;;
2154 ;;  ....................
2155 ;;
2156 ;;      FLOATING POINT COMPARISONS
2157 ;;
2158 ;;  ....................
2159 ;;
2160
2161 (define_insn "seq_sf"
2162   [(set (match_operand:CC 0 "register_operand" "=b")
2163         (eq:CC (match_operand:SF 1 "register_operand" "f")
2164                (match_operand:SF 2 "register_operand" "f")))]
2165   "TARGET_HARD_FLOAT"
2166   "oeq.s\\t%0, %1, %2"
2167   [(set_attr "type"     "farith")
2168    (set_attr "mode"     "BL")
2169    (set_attr "length"   "3")])
2170
2171 (define_insn "slt_sf"
2172   [(set (match_operand:CC 0 "register_operand" "=b")
2173         (lt:CC (match_operand:SF 1 "register_operand" "f")
2174                (match_operand:SF 2 "register_operand" "f")))]
2175   "TARGET_HARD_FLOAT"
2176   "olt.s\\t%0, %1, %2"
2177   [(set_attr "type"     "farith")
2178    (set_attr "mode"     "BL")
2179    (set_attr "length"   "3")])
2180
2181 (define_insn "sle_sf"
2182   [(set (match_operand:CC 0 "register_operand" "=b")
2183         (le:CC (match_operand:SF 1 "register_operand" "f")
2184                (match_operand:SF 2 "register_operand" "f")))]
2185   "TARGET_HARD_FLOAT"
2186   "ole.s\\t%0, %1, %2"
2187   [(set_attr "type"     "farith")
2188    (set_attr "mode"     "BL")
2189    (set_attr "length"   "3")])
2190
2191
2192 ;;
2193 ;;  ....................
2194 ;;
2195 ;;      UNCONDITIONAL BRANCHES
2196 ;;
2197 ;;  ....................
2198 ;;
2199
2200 (define_insn "jump"
2201   [(set (pc)
2202         (label_ref (match_operand 0 "" "")))]
2203   ""
2204   "j\\t%l0"
2205   [(set_attr "type"     "jump")
2206    (set_attr "mode"     "none")
2207    (set_attr "length"   "3")])
2208
2209 (define_expand "indirect_jump"
2210   [(set (pc) (match_operand 0 "register_operand" ""))]
2211   ""
2212   "
2213 {
2214   rtx dest = operands[0];
2215   if (GET_CODE (dest) != REG || GET_MODE (dest) != Pmode)
2216     operands[0] = copy_to_mode_reg (Pmode, dest);
2217
2218   emit_jump_insn (gen_indirect_jump_internal (dest));
2219   DONE;
2220 }")
2221
2222 (define_insn "indirect_jump_internal"
2223   [(set (pc) (match_operand:SI 0 "register_operand" "r"))]
2224   ""
2225   "jx\\t%0"
2226   [(set_attr "type"     "jump")
2227    (set_attr "mode"     "none")
2228    (set_attr "length"   "3")])
2229
2230
2231 (define_expand "tablejump"
2232   [(use (match_operand:SI 0 "register_operand" ""))
2233    (use (label_ref (match_operand 1 "" "")))]
2234    ""
2235    "
2236 {
2237   rtx target = operands[0];
2238   if (flag_pic)
2239     {
2240       /* For PIC, the table entry is relative to the start of the table. */
2241       rtx label = gen_reg_rtx (SImode);
2242       target = gen_reg_rtx (SImode);
2243       emit_move_insn (label, gen_rtx_LABEL_REF (SImode, operands[1]));
2244       emit_insn (gen_addsi3 (target, operands[0], label));
2245     }
2246   emit_jump_insn (gen_tablejump_internal (target, operands[1]));
2247   DONE;
2248 }")
2249
2250 (define_insn "tablejump_internal"
2251   [(set (pc)
2252         (match_operand:SI 0 "register_operand" "r"))
2253    (use (label_ref (match_operand 1 "" "")))]
2254   ""
2255   "jx\\t%0"
2256   [(set_attr "type"     "jump")
2257    (set_attr "mode"     "none")
2258    (set_attr "length"   "3")])
2259
2260
2261 ;;
2262 ;;  ....................
2263 ;;
2264 ;;      FUNCTION CALLS
2265 ;;
2266 ;;  ....................
2267 ;;
2268
2269 (define_expand "sym_PLT"
2270   [(const (unspec [(match_operand:SI 0 "" "")] UNSPEC_PLT))]
2271   ""
2272   "")
2273
2274 (define_expand "call"
2275   [(call (match_operand 0 "memory_operand" "")
2276          (match_operand 1 "" ""))]
2277   ""
2278   "
2279 {
2280   rtx addr = XEXP (operands[0], 0);
2281   if (flag_pic && GET_CODE (addr) == SYMBOL_REF && !SYMBOL_REF_FLAG (addr))
2282     addr = gen_sym_PLT (addr);
2283   if (!call_insn_operand (addr, VOIDmode))
2284     XEXP (operands[0], 0) = copy_to_mode_reg (Pmode, addr);
2285 }")
2286
2287 (define_insn "call_internal"
2288   [(call (mem (match_operand:SI 0 "call_insn_operand" "n,i,r"))
2289          (match_operand 1 "" "i,i,i"))]
2290   ""
2291   "*
2292     return xtensa_emit_call (0, operands);
2293   "
2294   [(set_attr "type"     "call")
2295    (set_attr "mode"     "none")
2296    (set_attr "length"   "3")])
2297
2298 (define_expand "call_value"
2299   [(set (match_operand 0 "register_operand" "")
2300         (call (match_operand 1 "memory_operand" "")
2301               (match_operand 2 "" "")))]
2302   ""
2303   "
2304 {
2305   rtx addr = XEXP (operands[1], 0);
2306   if (flag_pic && GET_CODE (addr) == SYMBOL_REF && !SYMBOL_REF_FLAG (addr))
2307     addr = gen_sym_PLT (addr);
2308   if (!call_insn_operand (addr, VOIDmode))
2309     XEXP (operands[1], 0) = copy_to_mode_reg (Pmode, addr);
2310 }")
2311
2312 ;; cannot combine constraints for operand 0 into "afvb"
2313 ;; reload.c:find_reloads seems to assume that grouped constraints somehow
2314 ;; specify related register classes, and when they don't the constraints
2315 ;; fail to match. By not grouping the constraints, we get the correct
2316 ;; behavior.
2317 (define_insn "call_value_internal"
2318    [(set (match_operand 0 "register_operand" "=af,af,af,v,v,v,b,b,b")
2319          (call (mem (match_operand:SI 1 "call_insn_operand"
2320                                         "n,i,r,n,i,r,n,i,r"))
2321                (match_operand 2 "" "i,i,i,i,i,i,i,i,i")))]
2322   ""
2323   "*
2324     return xtensa_emit_call (1, operands);
2325   "
2326   [(set_attr "type"     "call")
2327    (set_attr "mode"     "none")
2328    (set_attr "length"   "3")])
2329
2330 (define_insn "return"
2331   [(return)
2332    (use (reg:SI A0_REG))]
2333   "reload_completed"
2334   "*
2335 {
2336   return (TARGET_DENSITY ? \"retw.n\" : \"retw\");
2337 }"
2338   [(set_attr "type"     "jump")
2339    (set_attr "mode"     "none")
2340    (set_attr "length"   "2")])
2341
2342
2343 ;;
2344 ;;  ....................
2345 ;;
2346 ;;      MISC.
2347 ;;
2348 ;;  ....................
2349 ;;
2350
2351 (define_insn "nop"
2352   [(const_int 0)]
2353   ""
2354   "*
2355 {
2356   return (TARGET_DENSITY ? \"nop.n\" : \"nop\");
2357 }"
2358   [(set_attr "type"     "nop")
2359    (set_attr "mode"     "none")
2360    (set_attr "length"   "3")])
2361
2362 (define_expand "nonlocal_goto"
2363   [(match_operand:SI 0 "general_operand" "")
2364    (match_operand:SI 1 "general_operand" "")
2365    (match_operand:SI 2 "general_operand" "")
2366    (match_operand:SI 3 "" "")]
2367   ""
2368   "
2369 {
2370   xtensa_expand_nonlocal_goto (operands);
2371   DONE;
2372 }")
2373
2374 ;; Setting up a frame pointer is tricky for Xtensa because GCC doesn't
2375 ;; know if a frame pointer is required until the reload pass, and
2376 ;; because there may be an incoming argument value in the hard frame
2377 ;; pointer register (a7). If there is an incoming argument in that
2378 ;; register, the "set_frame_ptr" insn gets inserted immediately after
2379 ;; the insn that copies the incoming argument to a pseudo or to the
2380 ;; stack.  This serves several purposes here: (1) it keeps the
2381 ;; optimizer from copy-propagating or scheduling the use of a7 as an
2382 ;; incoming argument away from the beginning of the function; (2) we
2383 ;; can use a post-reload splitter to expand away the insn if a frame
2384 ;; pointer is not required, so that the post-reload scheduler can do
2385 ;; the right thing; and (3) it makes it easy for xtensa_reorg() to
2386 ;; search for this insn to determine whether it should add a new insn
2387 ;; to set up the frame pointer.
2388
2389 (define_insn "set_frame_ptr"
2390   [(unspec_volatile [(const_int 0)] UNSPECV_SET_FP)]
2391   ""
2392   "*
2393 {
2394   if (frame_pointer_needed)
2395     return \"mov\\ta7, sp\";
2396   return \"\";
2397 }"
2398   [(set_attr "type"     "move")
2399    (set_attr "mode"     "SI")
2400    (set_attr "length"   "3")])
2401
2402 ;; Post-reload splitter to remove fp assignment when it's not needed.
2403 (define_split
2404   [(unspec_volatile [(const_int 0)] UNSPECV_SET_FP)]
2405   "reload_completed && !frame_pointer_needed"
2406   [(unspec [(const_int 0)] UNSPEC_NOP)]
2407   "")
2408
2409 ;; The preceding splitter needs something to split the insn into;
2410 ;; things start breaking if the result is just a "use" so instead we
2411 ;; generate the following insn.
2412 (define_insn "*unspec_nop"
2413   [(unspec [(const_int 0)] UNSPEC_NOP)]
2414   ""
2415   ""
2416   [(set_attr "type"     "nop")
2417    (set_attr "mode"     "none")
2418    (set_attr "length"   "0")])
2419
2420 ;; The fix_return_addr pattern sets the high 2 bits of an address in a
2421 ;; register to match the high bits of the current PC.
2422
2423 (define_insn "fix_return_addr"
2424   [(set (match_operand:SI 0 "register_operand" "=a")
2425         (unspec:SI [(match_operand:SI 1 "register_operand" "r")]
2426                    UNSPEC_RET_ADDR))
2427    (clobber (match_scratch:SI 2 "=r"))
2428    (clobber (match_scratch:SI 3 "=r"))]
2429   ""
2430   "mov\\t%2, a0\;call0\\t0f\;.align\\t4\;0:\;mov\\t%3, a0\;mov\\ta0, %2\;\
2431 srli\\t%3, %3, 30\;slli\\t%0, %1, 2\;ssai\\t2\;src\\t%0, %3, %0"
2432   [(set_attr "type"     "multi")
2433    (set_attr "mode"     "SI")
2434    (set_attr "length"   "24")])
2435
2436
2437 ;;
2438 ;;  ....................
2439 ;;
2440 ;;      BOOLEANS
2441 ;;
2442 ;;  ....................
2443 ;;
2444
2445 ;; branch patterns
2446
2447 (define_insn "*booltrue"
2448   [(set (pc)
2449         (if_then_else (match_operator 2 "boolean_operator"
2450                          [(match_operand:CC 0 "register_operand" "b")
2451                           (const_int 0)])
2452                       (label_ref (match_operand 1 "" ""))
2453                       (pc)))]
2454   "TARGET_BOOLEANS"
2455   "*
2456 {
2457   if (GET_CODE (operands[2]) == EQ)
2458     return \"bf\\t%0, %1\";
2459   else
2460     return \"bt\\t%0, %1\";
2461 }"
2462   [(set_attr "type"     "jump")
2463    (set_attr "mode"     "none")
2464    (set_attr "length"   "3")])
2465
2466 (define_insn "*boolfalse"
2467   [(set (pc)
2468         (if_then_else (match_operator 2 "boolean_operator"
2469                          [(match_operand:CC 0 "register_operand" "b")
2470                           (const_int 0)])
2471                       (pc)
2472                       (label_ref (match_operand 1 "" ""))))]
2473   "TARGET_BOOLEANS"
2474   "*
2475 {
2476   if (GET_CODE (operands[2]) == EQ)
2477     return \"bt\\t%0, %1\";
2478   else
2479     return \"bf\\t%0, %1\";
2480 }"
2481   [(set_attr "type"     "jump")
2482    (set_attr "mode"     "none")
2483    (set_attr "length"   "3")])