OSDN Git Service

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