OSDN Git Service

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