OSDN Git Service

* doc/invoke.texi (Option Summary, Xtensa Options): Document
[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, 2007, 2008
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 3, 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 COPYING3.  If not see
20 ;; <http://www.gnu.org/licenses/>.
21
22
23 (define_constants [
24   (A0_REG               0)
25   (A1_REG               1)
26   (A7_REG               7)
27   (A8_REG               8)
28
29   (UNSPEC_NOP           2)
30   (UNSPEC_PLT           3)
31   (UNSPEC_RET_ADDR      4)
32
33   (UNSPECV_SET_FP       1)
34   (UNSPECV_ENTRY        2)
35   (UNSPECV_MEMW         3)
36   (UNSPECV_S32RI        4)
37   (UNSPECV_S32C1I       5)
38   (UNSPECV_EH_RETURN    6)
39 ])
40
41 ;; This code iterator allows signed and unsigned widening multiplications
42 ;; to use the same template.
43 (define_code_iterator any_extend [sign_extend zero_extend])
44
45 ;; <u> expands to an empty string when doing a signed operation and
46 ;; "u" when doing an unsigned operation.
47 (define_code_attr u [(sign_extend "") (zero_extend "u")])
48
49 ;; <su> is like <u>, but the signed form expands to "s" rather than "".
50 (define_code_attr su [(sign_extend "s") (zero_extend "u")])
51
52 ;; This code iterator allows four integer min/max operations to be
53 ;; generated from one template.
54 (define_code_iterator any_minmax [smin umin smax umax])
55
56 ;; <minmax> expands to the opcode name for any_minmax operations.
57 (define_code_attr minmax [(smin "min") (umin "minu")
58                           (smax "max") (umax "maxu")])
59
60 ;; This code iterator allows all branch instructions to be generated from
61 ;; a single define_expand template.
62 (define_code_iterator any_cond [eq ne gt ge lt le gtu geu ltu leu])
63
64 ;; This code iterator is for setting a register from a comparison.
65 (define_code_iterator any_scc [eq ne gt ge lt le])
66
67 ;; This code iterator is for floating-point comparisons.
68 (define_code_iterator any_scc_sf [eq lt le])
69
70 ;; This iterator and attribute allow to combine most atomic operations.
71 (define_code_iterator ATOMIC [and ior xor plus minus mult])
72 (define_code_attr atomic [(and "and") (ior "ior") (xor "xor") 
73                           (plus "add") (minus "sub") (mult "nand")])
74
75 ;; This mode iterator allows the HI and QI patterns to be defined from
76 ;; the same template.
77 (define_mode_iterator HQI [HI QI])
78
79 \f
80 ;; Attributes.
81
82 (define_attr "type"
83   "unknown,jump,call,load,store,move,arith,multi,nop,farith,fmadd,fdiv,fsqrt,fconv,fload,fstore,mul16,mul32,div32,mac16,rsr,wsr,entry"
84   (const_string "unknown"))
85
86 (define_attr "mode"
87   "unknown,none,QI,HI,SI,DI,SF,DF,BL"
88   (const_string "unknown"))
89
90 (define_attr "length" "" (const_int 1))
91
92 ;; Describe a user's asm statement.
93 (define_asm_attributes
94   [(set_attr "type" "multi")])
95
96 \f
97 ;; Pipeline model.
98
99 ;; The Xtensa basically has simple 5-stage RISC pipeline.
100 ;; Most instructions complete in 1 cycle, and it is OK to assume that
101 ;; everything is fully pipelined.  The exceptions have special insn
102 ;; reservations in the pipeline description below.  The Xtensa can
103 ;; issue one instruction per cycle, so defining CPU units is unnecessary.
104
105 (define_insn_reservation "xtensa_any_insn" 1
106                          (eq_attr "type" "!load,fload,rsr,mul16,mul32,fmadd,fconv")
107                          "nothing")
108
109 (define_insn_reservation "xtensa_memory" 2
110                          (eq_attr "type" "load,fload")
111                          "nothing")
112
113 (define_insn_reservation "xtensa_sreg" 2
114                          (eq_attr "type" "rsr")
115                          "nothing")
116
117 (define_insn_reservation "xtensa_mul16" 2
118                          (eq_attr "type" "mul16")
119                          "nothing")
120
121 (define_insn_reservation "xtensa_mul32" 2
122                          (eq_attr "type" "mul32")
123                          "nothing")
124
125 (define_insn_reservation "xtensa_fmadd" 4
126                          (eq_attr "type" "fmadd")
127                          "nothing")
128
129 (define_insn_reservation "xtensa_fconv" 2
130                          (eq_attr "type" "fconv")
131                          "nothing")
132 \f
133 ;; Include predicates and constraints.
134
135 (include "predicates.md")
136 (include "constraints.md")
137
138 \f
139 ;; Addition.
140
141 (define_insn "addsi3"
142   [(set (match_operand:SI 0 "register_operand" "=D,D,a,a,a")
143         (plus:SI (match_operand:SI 1 "register_operand" "%d,d,r,r,r")
144                  (match_operand:SI 2 "add_operand" "d,O,r,J,N")))]
145   ""
146   "@
147    add.n\t%0, %1, %2
148    addi.n\t%0, %1, %d2
149    add\t%0, %1, %2
150    addi\t%0, %1, %d2
151    addmi\t%0, %1, %x2"
152   [(set_attr "type"     "arith,arith,arith,arith,arith")
153    (set_attr "mode"     "SI")
154    (set_attr "length"   "2,2,3,3,3")])
155
156 (define_insn "*addx"
157   [(set (match_operand:SI 0 "register_operand" "=a")
158         (plus:SI (mult:SI (match_operand:SI 1 "register_operand" "r")
159                           (match_operand:SI 3 "addsubx_operand" "i"))
160                  (match_operand:SI 2 "register_operand" "r")))]
161   "TARGET_ADDX"
162   "addx%3\t%0, %1, %2"
163   [(set_attr "type"     "arith")
164    (set_attr "mode"     "SI")
165    (set_attr "length"   "3")])
166
167 (define_insn "addsf3"
168   [(set (match_operand:SF 0 "register_operand" "=f")
169         (plus:SF (match_operand:SF 1 "register_operand" "%f")
170                  (match_operand:SF 2 "register_operand" "f")))]
171   "TARGET_HARD_FLOAT"
172   "add.s\t%0, %1, %2"
173   [(set_attr "type"     "fmadd")
174    (set_attr "mode"     "SF")
175    (set_attr "length"   "3")])
176
177 \f
178 ;; Subtraction.
179
180 (define_insn "subsi3"
181   [(set (match_operand:SI 0 "register_operand" "=a")
182         (minus:SI (match_operand:SI 1 "register_operand" "r")
183                   (match_operand:SI 2 "register_operand" "r")))]
184   ""
185   "sub\t%0, %1, %2"
186   [(set_attr "type"     "arith")
187    (set_attr "mode"     "SI")
188    (set_attr "length"   "3")])
189
190 (define_insn "*subx"
191   [(set (match_operand:SI 0 "register_operand" "=a")
192         (minus:SI (mult:SI (match_operand:SI 1 "register_operand" "r")
193                            (match_operand:SI 3 "addsubx_operand" "i"))
194                   (match_operand:SI 2 "register_operand" "r")))]
195   "TARGET_ADDX"
196   "subx%3\t%0, %1, %2"
197   [(set_attr "type"     "arith")
198    (set_attr "mode"     "SI")
199    (set_attr "length"   "3")])
200
201 (define_insn "subsf3"
202   [(set (match_operand:SF 0 "register_operand" "=f")
203         (minus:SF (match_operand:SF 1 "register_operand" "f")
204                   (match_operand:SF 2 "register_operand" "f")))]
205   "TARGET_HARD_FLOAT"
206   "sub.s\t%0, %1, %2"
207   [(set_attr "type"     "fmadd")
208    (set_attr "mode"     "SF")
209    (set_attr "length"   "3")])
210
211 \f
212 ;; Multiplication.
213
214 (define_expand "<u>mulsidi3"
215   [(set (match_operand:DI 0 "register_operand")
216         (mult:DI (any_extend:DI (match_operand:SI 1 "register_operand"))
217                  (any_extend:DI (match_operand:SI 2 "register_operand"))))]
218   "TARGET_MUL32_HIGH"
219 {
220   emit_insn (gen_mulsi3 (gen_lowpart (SImode, operands[0]),
221                          operands[1], operands[2]));
222   emit_insn (gen_<u>mulsi3_highpart (gen_highpart (SImode, operands[0]),
223                                      operands[1], operands[2]));
224   DONE;
225 })
226
227 (define_insn "<u>mulsi3_highpart"
228   [(set (match_operand:SI 0 "register_operand" "=a")
229         (truncate:SI
230          (lshiftrt:DI
231           (mult:DI (any_extend:DI (match_operand:SI 1 "register_operand" "%r"))
232                    (any_extend:DI (match_operand:SI 2 "register_operand" "r")))
233           (const_int 32))))]
234   "TARGET_MUL32_HIGH"
235   "mul<su>h\t%0, %1, %2"
236   [(set_attr "type"     "mul32")
237    (set_attr "mode"     "SI")
238    (set_attr "length"   "3")])
239
240 (define_insn "mulsi3"
241   [(set (match_operand:SI 0 "register_operand" "=a")
242         (mult:SI (match_operand:SI 1 "register_operand" "%r")
243                  (match_operand:SI 2 "register_operand" "r")))]
244   "TARGET_MUL32"
245   "mull\t%0, %1, %2"
246   [(set_attr "type"     "mul32")
247    (set_attr "mode"     "SI")
248    (set_attr "length"   "3")])
249
250 (define_insn "mulhisi3"
251   [(set (match_operand:SI 0 "register_operand" "=C,A")
252         (mult:SI (sign_extend:SI
253                   (match_operand:HI 1 "register_operand" "%r,r"))
254                  (sign_extend:SI
255                   (match_operand:HI 2 "register_operand" "r,r"))))]
256   "TARGET_MUL16 || TARGET_MAC16"
257   "@
258    mul16s\t%0, %1, %2
259    mul.aa.ll\t%1, %2"
260   [(set_attr "type"     "mul16,mac16")
261    (set_attr "mode"     "SI")
262    (set_attr "length"   "3,3")])
263
264 (define_insn "umulhisi3"
265   [(set (match_operand:SI 0 "register_operand" "=C,A")
266         (mult:SI (zero_extend:SI
267                   (match_operand:HI 1 "register_operand" "%r,r"))
268                  (zero_extend:SI
269                   (match_operand:HI 2 "register_operand" "r,r"))))]
270   "TARGET_MUL16 || TARGET_MAC16"
271   "@
272    mul16u\t%0, %1, %2
273    umul.aa.ll\t%1, %2"
274   [(set_attr "type"     "mul16,mac16")
275    (set_attr "mode"     "SI")
276    (set_attr "length"   "3,3")])
277
278 (define_insn "muladdhisi"
279   [(set (match_operand:SI 0 "register_operand" "=A")
280         (plus:SI (mult:SI (sign_extend:SI
281                            (match_operand:HI 1 "register_operand" "%r"))
282                           (sign_extend:SI
283                            (match_operand:HI 2 "register_operand" "r")))
284                  (match_operand:SI 3 "register_operand" "0")))]
285   "TARGET_MAC16"
286   "mula.aa.ll\t%1, %2"
287   [(set_attr "type"     "mac16")
288    (set_attr "mode"     "SI")
289    (set_attr "length"   "3")])
290
291 (define_insn "mulsubhisi"
292   [(set (match_operand:SI 0 "register_operand" "=A")
293         (minus:SI (match_operand:SI 1 "register_operand" "0")
294                   (mult:SI (sign_extend:SI
295                             (match_operand:HI 2 "register_operand" "%r"))
296                            (sign_extend:SI
297                             (match_operand:HI 3 "register_operand" "r")))))]
298   "TARGET_MAC16"
299   "muls.aa.ll\t%2, %3"
300   [(set_attr "type"     "mac16")
301    (set_attr "mode"     "SI")
302    (set_attr "length"   "3")])
303
304 (define_insn "mulsf3"
305   [(set (match_operand:SF 0 "register_operand" "=f")
306         (mult:SF (match_operand:SF 1 "register_operand" "%f")
307                  (match_operand:SF 2 "register_operand" "f")))]
308   "TARGET_HARD_FLOAT"
309   "mul.s\t%0, %1, %2"
310   [(set_attr "type"     "fmadd")
311    (set_attr "mode"     "SF")
312    (set_attr "length"   "3")])
313
314 (define_insn "muladdsf3"
315   [(set (match_operand:SF 0 "register_operand" "=f")
316         (plus:SF (mult:SF (match_operand:SF 1 "register_operand" "%f")
317                           (match_operand:SF 2 "register_operand" "f"))
318                  (match_operand:SF 3 "register_operand" "0")))]
319   "TARGET_HARD_FLOAT && TARGET_FUSED_MADD"
320   "madd.s\t%0, %1, %2"
321   [(set_attr "type"     "fmadd")
322    (set_attr "mode"     "SF")
323    (set_attr "length"   "3")])
324
325 (define_insn "mulsubsf3"
326   [(set (match_operand:SF 0 "register_operand" "=f")
327         (minus:SF (match_operand:SF 1 "register_operand" "0")
328                   (mult:SF (match_operand:SF 2 "register_operand" "%f")
329                            (match_operand:SF 3 "register_operand" "f"))))]
330   "TARGET_HARD_FLOAT && TARGET_FUSED_MADD"
331   "msub.s\t%0, %2, %3"
332   [(set_attr "type"     "fmadd")
333    (set_attr "mode"     "SF")
334    (set_attr "length"   "3")])
335
336 \f
337 ;; Division.
338
339 (define_insn "divsi3"
340   [(set (match_operand:SI 0 "register_operand" "=a")
341         (div:SI (match_operand:SI 1 "register_operand" "r")
342                 (match_operand:SI 2 "register_operand" "r")))]
343   "TARGET_DIV32"
344   "quos\t%0, %1, %2"
345   [(set_attr "type"     "div32")
346    (set_attr "mode"     "SI")
347    (set_attr "length"   "3")])
348
349 (define_insn "udivsi3"
350   [(set (match_operand:SI 0 "register_operand" "=a")
351         (udiv:SI (match_operand:SI 1 "register_operand" "r")
352                  (match_operand:SI 2 "register_operand" "r")))]
353   "TARGET_DIV32"
354   "quou\t%0, %1, %2"
355   [(set_attr "type"     "div32")
356    (set_attr "mode"     "SI")
357    (set_attr "length"   "3")])
358
359 (define_insn "divsf3"
360   [(set (match_operand:SF 0 "register_operand" "=f")
361         (div:SF (match_operand:SF 1 "register_operand" "f")
362                 (match_operand:SF 2 "register_operand" "f")))]
363   "TARGET_HARD_FLOAT_DIV"
364   "div.s\t%0, %1, %2"
365   [(set_attr "type"     "fdiv")
366    (set_attr "mode"     "SF")
367    (set_attr "length"   "3")])
368
369 (define_insn "*recipsf2"
370   [(set (match_operand:SF 0 "register_operand" "=f")
371         (div:SF (match_operand:SF 1 "const_float_1_operand" "")
372                 (match_operand:SF 2 "register_operand" "f")))]
373   "TARGET_HARD_FLOAT_RECIP && flag_unsafe_math_optimizations"
374   "recip.s\t%0, %2"
375   [(set_attr "type"     "fdiv")
376    (set_attr "mode"     "SF")
377    (set_attr "length"   "3")])
378
379 \f
380 ;; Remainders.
381
382 (define_insn "modsi3"
383   [(set (match_operand:SI 0 "register_operand" "=a")
384         (mod:SI (match_operand:SI 1 "register_operand" "r")
385                 (match_operand:SI 2 "register_operand" "r")))]
386   "TARGET_DIV32"
387   "rems\t%0, %1, %2"
388   [(set_attr "type"     "div32")
389    (set_attr "mode"     "SI")
390    (set_attr "length"   "3")])
391
392 (define_insn "umodsi3"
393   [(set (match_operand:SI 0 "register_operand" "=a")
394         (umod:SI (match_operand:SI 1 "register_operand" "r")
395                  (match_operand:SI 2 "register_operand" "r")))]
396   "TARGET_DIV32"
397   "remu\t%0, %1, %2"
398   [(set_attr "type"     "div32")
399    (set_attr "mode"     "SI")
400    (set_attr "length"   "3")])
401
402 \f
403 ;; Square roots.
404
405 (define_insn "sqrtsf2"
406   [(set (match_operand:SF 0 "register_operand" "=f")
407         (sqrt:SF (match_operand:SF 1 "register_operand" "f")))]
408   "TARGET_HARD_FLOAT_SQRT"
409   "sqrt.s\t%0, %1"
410   [(set_attr "type"     "fsqrt")
411    (set_attr "mode"     "SF")
412    (set_attr "length"   "3")])
413
414 (define_insn "*rsqrtsf2"
415   [(set (match_operand:SF 0 "register_operand" "=f")
416         (div:SF (match_operand:SF 1 "const_float_1_operand" "")
417                 (sqrt:SF (match_operand:SF 2 "register_operand" "f"))))]
418   "TARGET_HARD_FLOAT_RSQRT && flag_unsafe_math_optimizations"
419   "rsqrt.s\t%0, %2"
420   [(set_attr "type"     "fsqrt")
421    (set_attr "mode"     "SF")
422    (set_attr "length"   "3")])
423
424 \f
425 ;; Absolute value.
426
427 (define_insn "abssi2"
428   [(set (match_operand:SI 0 "register_operand" "=a")
429         (abs:SI (match_operand:SI 1 "register_operand" "r")))]
430   "TARGET_ABS"
431   "abs\t%0, %1"
432   [(set_attr "type"     "arith")
433    (set_attr "mode"     "SI")
434    (set_attr "length"   "3")])
435
436 (define_insn "abssf2"
437   [(set (match_operand:SF 0 "register_operand" "=f")
438         (abs:SF (match_operand:SF 1 "register_operand" "f")))]
439   "TARGET_HARD_FLOAT"
440   "abs.s\t%0, %1"
441   [(set_attr "type"     "farith")
442    (set_attr "mode"     "SF")
443    (set_attr "length"   "3")])
444
445 \f
446 ;; Min and max.
447
448 (define_insn "<code>si3"
449   [(set (match_operand:SI 0 "register_operand" "=a")
450         (any_minmax:SI (match_operand:SI 1 "register_operand" "%r")
451                        (match_operand:SI 2 "register_operand" "r")))]
452   "TARGET_MINMAX"
453   "<minmax>\t%0, %1, %2"
454   [(set_attr "type"     "arith")
455    (set_attr "mode"     "SI")
456    (set_attr "length"   "3")])
457
458 \f
459 ;; Count leading/trailing zeros and find first bit.
460
461 (define_insn "clzsi2"
462   [(set (match_operand:SI 0 "register_operand" "=a")
463         (clz:SI (match_operand:SI 1 "register_operand" "r")))]
464   "TARGET_NSA"
465   "nsau\t%0, %1"
466   [(set_attr "type"     "arith")
467    (set_attr "mode"     "SI")
468    (set_attr "length"   "3")])
469
470 (define_expand "ctzsi2"
471   [(set (match_operand:SI 0 "register_operand" "")
472         (ctz:SI (match_operand:SI 1 "register_operand" "")))]
473   "TARGET_NSA"
474 {
475   rtx temp = gen_reg_rtx (SImode);
476   emit_insn (gen_negsi2 (temp, operands[1]));
477   emit_insn (gen_andsi3 (temp, temp, operands[1]));
478   emit_insn (gen_clzsi2 (temp, temp));
479   emit_insn (gen_negsi2 (temp, temp));
480   emit_insn (gen_addsi3 (operands[0], temp, GEN_INT (31)));
481   DONE;
482 })
483
484 (define_expand "ffssi2"
485   [(set (match_operand:SI 0 "register_operand" "")
486         (ffs:SI (match_operand:SI 1 "register_operand" "")))]
487   "TARGET_NSA"
488 {
489   rtx temp = gen_reg_rtx (SImode);
490   emit_insn (gen_negsi2 (temp, operands[1]));
491   emit_insn (gen_andsi3 (temp, temp, operands[1]));
492   emit_insn (gen_clzsi2 (temp, temp));
493   emit_insn (gen_negsi2 (temp, temp));
494   emit_insn (gen_addsi3 (operands[0], temp, GEN_INT (32)));
495   DONE;
496 })
497
498 \f
499 ;; Negation and one's complement.
500
501 (define_insn "negsi2"
502   [(set (match_operand:SI 0 "register_operand" "=a")
503         (neg:SI (match_operand:SI 1 "register_operand" "r")))]
504   ""
505   "neg\t%0, %1"
506   [(set_attr "type"     "arith")
507    (set_attr "mode"     "SI")
508    (set_attr "length"   "3")])
509
510 (define_expand "one_cmplsi2"
511   [(set (match_operand:SI 0 "register_operand" "")
512         (not:SI (match_operand:SI 1 "register_operand" "")))]
513   ""
514 {
515   rtx temp = gen_reg_rtx (SImode);
516   emit_insn (gen_movsi (temp, constm1_rtx));
517   emit_insn (gen_xorsi3 (operands[0], temp, operands[1]));
518   DONE;
519 })
520
521 (define_insn "negsf2"
522   [(set (match_operand:SF 0 "register_operand" "=f")
523         (neg:SF (match_operand:SF 1 "register_operand" "f")))]
524   "TARGET_HARD_FLOAT"
525   "neg.s\t%0, %1"
526   [(set_attr "type"     "farith")
527    (set_attr "mode"     "SF")
528    (set_attr "length"   "3")])
529
530 \f
531 ;; Logical instructions.
532
533 (define_insn "andsi3"
534   [(set (match_operand:SI 0 "register_operand" "=a,a")
535         (and:SI (match_operand:SI 1 "register_operand" "%r,r")
536                 (match_operand:SI 2 "mask_operand" "P,r")))]
537   ""
538   "@
539    extui\t%0, %1, 0, %K2
540    and\t%0, %1, %2"
541   [(set_attr "type"     "arith,arith")
542    (set_attr "mode"     "SI")
543    (set_attr "length"   "3,3")])
544
545 (define_insn "iorsi3"
546   [(set (match_operand:SI 0 "register_operand" "=a")
547         (ior:SI (match_operand:SI 1 "register_operand" "%r")
548                 (match_operand:SI 2 "register_operand" "r")))]
549   ""
550   "or\t%0, %1, %2"
551   [(set_attr "type"     "arith")
552    (set_attr "mode"     "SI")
553    (set_attr "length"   "3")])
554
555 (define_insn "xorsi3"
556   [(set (match_operand:SI 0 "register_operand" "=a")
557         (xor:SI (match_operand:SI 1 "register_operand" "%r")
558                 (match_operand:SI 2 "register_operand" "r")))]
559   ""
560   "xor\t%0, %1, %2"
561   [(set_attr "type"     "arith")
562    (set_attr "mode"     "SI")
563    (set_attr "length"   "3")])
564
565 \f
566 ;; Zero-extend instructions.
567
568 (define_insn "zero_extendhisi2"
569   [(set (match_operand:SI 0 "register_operand" "=a,a")
570         (zero_extend:SI (match_operand:HI 1 "nonimmed_operand" "r,U")))]
571   ""
572   "@
573    extui\t%0, %1, 0, 16
574    l16ui\t%0, %1"
575   [(set_attr "type"     "arith,load")
576    (set_attr "mode"     "SI")
577    (set_attr "length"   "3,3")])
578
579 (define_insn "zero_extendqisi2"
580   [(set (match_operand:SI 0 "register_operand" "=a,a")
581         (zero_extend:SI (match_operand:QI 1 "nonimmed_operand" "r,U")))]
582   ""
583   "@
584    extui\t%0, %1, 0, 8
585    l8ui\t%0, %1"
586   [(set_attr "type"     "arith,load")
587    (set_attr "mode"     "SI")
588    (set_attr "length"   "3,3")])
589
590 \f
591 ;; Sign-extend instructions.
592
593 (define_expand "extendhisi2"
594   [(set (match_operand:SI 0 "register_operand" "")
595         (sign_extend:SI (match_operand:HI 1 "register_operand" "")))]
596   ""
597 {
598   if (sext_operand (operands[1], HImode))
599     emit_insn (gen_extendhisi2_internal (operands[0], operands[1]));
600   else
601     xtensa_extend_reg (operands[0], operands[1]);
602   DONE;
603 })
604
605 (define_insn "extendhisi2_internal"
606   [(set (match_operand:SI 0 "register_operand" "=B,a")
607         (sign_extend:SI (match_operand:HI 1 "sext_operand" "r,U")))]
608   ""
609   "@
610    sext\t%0, %1, 15
611    l16si\t%0, %1"
612   [(set_attr "type"     "arith,load")
613    (set_attr "mode"     "SI")
614    (set_attr "length"   "3,3")])
615
616 (define_expand "extendqisi2"
617   [(set (match_operand:SI 0 "register_operand" "")
618         (sign_extend:SI (match_operand:QI 1 "register_operand" "")))]
619   ""
620 {
621   if (TARGET_SEXT)
622     emit_insn (gen_extendqisi2_internal (operands[0], operands[1]));
623   else
624     xtensa_extend_reg (operands[0], operands[1]);
625   DONE;
626 })
627
628 (define_insn "extendqisi2_internal"
629   [(set (match_operand:SI 0 "register_operand" "=B")
630         (sign_extend:SI (match_operand:QI 1 "register_operand" "r")))]
631   "TARGET_SEXT"
632   "sext\t%0, %1, 7"
633   [(set_attr "type"     "arith")
634    (set_attr "mode"     "SI")
635    (set_attr "length"   "3")])
636
637 \f
638 ;; Field extract instructions.
639
640 (define_expand "extv"
641   [(set (match_operand:SI 0 "register_operand" "")
642         (sign_extract:SI (match_operand:SI 1 "register_operand" "")
643                          (match_operand:SI 2 "const_int_operand" "")
644                          (match_operand:SI 3 "const_int_operand" "")))]
645   "TARGET_SEXT"
646 {
647   if (!sext_fldsz_operand (operands[2], SImode))
648     FAIL;
649
650   /* We could expand to a right shift followed by SEXT but that's
651      no better than the standard left and right shift sequence.  */
652   if (!lsbitnum_operand (operands[3], SImode))
653     FAIL;
654
655   emit_insn (gen_extv_internal (operands[0], operands[1],
656                                 operands[2], operands[3]));
657   DONE;
658 })
659
660 (define_insn "extv_internal"
661   [(set (match_operand:SI 0 "register_operand" "=a")
662         (sign_extract:SI (match_operand:SI 1 "register_operand" "r")
663                          (match_operand:SI 2 "sext_fldsz_operand" "i")
664                          (match_operand:SI 3 "lsbitnum_operand" "i")))]
665   "TARGET_SEXT"
666 {
667   int fldsz = INTVAL (operands[2]);
668   operands[2] = GEN_INT (fldsz - 1);
669   return "sext\t%0, %1, %2";
670 }
671   [(set_attr "type"     "arith")
672    (set_attr "mode"     "SI")
673    (set_attr "length"   "3")])
674
675 (define_expand "extzv"
676   [(set (match_operand:SI 0 "register_operand" "")
677         (zero_extract:SI (match_operand:SI 1 "register_operand" "")
678                          (match_operand:SI 2 "const_int_operand" "")
679                          (match_operand:SI 3 "const_int_operand" "")))]
680   ""
681 {
682   if (!extui_fldsz_operand (operands[2], SImode))
683     FAIL;
684   emit_insn (gen_extzv_internal (operands[0], operands[1],
685                                  operands[2], operands[3]));
686   DONE;
687 })
688
689 (define_insn "extzv_internal"
690   [(set (match_operand:SI 0 "register_operand" "=a")
691         (zero_extract:SI (match_operand:SI 1 "register_operand" "r")
692                          (match_operand:SI 2 "extui_fldsz_operand" "i")
693                          (match_operand:SI 3 "const_int_operand" "i")))]
694   ""
695 {
696   int shift;
697   if (BITS_BIG_ENDIAN)
698     shift = (32 - (INTVAL (operands[2]) + INTVAL (operands[3]))) & 0x1f;
699   else
700     shift = INTVAL (operands[3]) & 0x1f;
701   operands[3] = GEN_INT (shift);
702   return "extui\t%0, %1, %3, %2";
703 }
704   [(set_attr "type"     "arith")
705    (set_attr "mode"     "SI")
706    (set_attr "length"   "3")])
707
708 \f
709 ;; Conversions.
710
711 (define_insn "fix_truncsfsi2"
712   [(set (match_operand:SI 0 "register_operand" "=a")
713         (fix:SI (match_operand:SF 1 "register_operand" "f")))]
714   "TARGET_HARD_FLOAT"
715   "trunc.s\t%0, %1, 0"
716   [(set_attr "type"     "fconv")
717    (set_attr "mode"     "SF")
718    (set_attr "length"   "3")])
719
720 (define_insn "fixuns_truncsfsi2"
721   [(set (match_operand:SI 0 "register_operand" "=a")
722         (unsigned_fix:SI (match_operand:SF 1 "register_operand" "f")))]
723   "TARGET_HARD_FLOAT"
724   "utrunc.s\t%0, %1, 0"
725   [(set_attr "type"     "fconv")
726    (set_attr "mode"     "SF")
727    (set_attr "length"   "3")])
728
729 (define_insn "floatsisf2"
730   [(set (match_operand:SF 0 "register_operand" "=f")
731         (float:SF (match_operand:SI 1 "register_operand" "a")))]
732   "TARGET_HARD_FLOAT"
733   "float.s\t%0, %1, 0"
734   [(set_attr "type"     "fconv")
735    (set_attr "mode"     "SF")
736    (set_attr "length"   "3")])
737
738 (define_insn "floatunssisf2"
739   [(set (match_operand:SF 0 "register_operand" "=f")
740         (unsigned_float:SF (match_operand:SI 1 "register_operand" "a")))]
741   "TARGET_HARD_FLOAT"
742   "ufloat.s\t%0, %1, 0"
743   [(set_attr "type"     "fconv")
744    (set_attr "mode"     "SF")
745    (set_attr "length"   "3")])
746
747 \f
748 ;; Data movement instructions.
749
750 ;; 64-bit Integer moves
751
752 (define_expand "movdi"
753   [(set (match_operand:DI 0 "nonimmed_operand" "")
754         (match_operand:DI 1 "general_operand" ""))]
755   ""
756 {
757   if (CONSTANT_P (operands[1]) && !TARGET_CONST16)
758     operands[1] = force_const_mem (DImode, operands[1]);
759
760   if (!register_operand (operands[0], DImode)
761       && !register_operand (operands[1], DImode))
762     operands[1] = force_reg (DImode, operands[1]);
763
764   operands[1] = xtensa_copy_incoming_a7 (operands[1]);
765 })
766
767 (define_insn_and_split "movdi_internal"
768   [(set (match_operand:DI 0 "nonimmed_operand" "=a,W,a,a,U")
769         (match_operand:DI 1 "move_operand" "r,i,T,U,r"))]
770   "register_operand (operands[0], DImode)
771    || register_operand (operands[1], DImode)"
772   "#"
773   "reload_completed"
774   [(set (match_dup 0) (match_dup 2))
775    (set (match_dup 1) (match_dup 3))]
776 {
777   xtensa_split_operand_pair (operands, SImode);
778   if (reg_overlap_mentioned_p (operands[0], operands[3]))
779     {
780       rtx tmp;
781       tmp = operands[0], operands[0] = operands[1], operands[1] = tmp;
782       tmp = operands[2], operands[2] = operands[3], operands[3] = tmp;
783     }
784 })
785
786 ;; 32-bit Integer moves
787
788 (define_expand "movsi"
789   [(set (match_operand:SI 0 "nonimmed_operand" "")
790         (match_operand:SI 1 "general_operand" ""))]
791   ""
792 {
793   if (xtensa_emit_move_sequence (operands, SImode))
794     DONE;
795 })
796
797 (define_insn "movsi_internal"
798   [(set (match_operand:SI 0 "nonimmed_operand" "=D,D,D,D,R,R,a,q,a,W,a,a,U,*a,*A")
799         (match_operand:SI 1 "move_operand" "M,D,d,R,D,d,r,r,I,i,T,U,r,*A,*r"))]
800   "xtensa_valid_move (SImode, operands)"
801   "@
802    movi.n\t%0, %x1
803    mov.n\t%0, %1
804    mov.n\t%0, %1
805    %v1l32i.n\t%0, %1
806    %v0s32i.n\t%1, %0
807    %v0s32i.n\t%1, %0
808    mov\t%0, %1
809    movsp\t%0, %1
810    movi\t%0, %x1
811    const16\t%0, %t1\;const16\t%0, %b1
812    %v1l32r\t%0, %1
813    %v1l32i\t%0, %1
814    %v0s32i\t%1, %0
815    rsr\t%0, ACCLO
816    wsr\t%1, ACCLO"
817   [(set_attr "type" "move,move,move,load,store,store,move,move,move,move,load,load,store,rsr,wsr")
818    (set_attr "mode"     "SI")
819    (set_attr "length"   "2,2,2,2,2,2,3,3,3,6,3,3,3,3,3")])
820
821 ;; 16-bit Integer moves
822
823 (define_expand "movhi"
824   [(set (match_operand:HI 0 "nonimmed_operand" "")
825         (match_operand:HI 1 "general_operand" ""))]
826   ""
827 {
828   if (xtensa_emit_move_sequence (operands, HImode))
829     DONE;
830 })
831
832 (define_insn "movhi_internal"
833   [(set (match_operand:HI 0 "nonimmed_operand" "=D,D,a,a,a,U,*a,*A")
834         (match_operand:HI 1 "move_operand" "M,d,r,I,U,r,*A,*r"))]
835   "xtensa_valid_move (HImode, operands)"
836   "@
837    movi.n\t%0, %x1
838    mov.n\t%0, %1
839    mov\t%0, %1
840    movi\t%0, %x1
841    %v1l16ui\t%0, %1
842    %v0s16i\t%1, %0
843    rsr\t%0, ACCLO
844    wsr\t%1, ACCLO"
845   [(set_attr "type"     "move,move,move,move,load,store,rsr,wsr")
846    (set_attr "mode"     "HI")
847    (set_attr "length"   "2,2,3,3,3,3,3,3")])
848
849 ;; 8-bit Integer moves
850
851 (define_expand "movqi"
852   [(set (match_operand:QI 0 "nonimmed_operand" "")
853         (match_operand:QI 1 "general_operand" ""))]
854   ""
855 {
856   if (xtensa_emit_move_sequence (operands, QImode))
857     DONE;
858 })
859
860 (define_insn "movqi_internal"
861   [(set (match_operand:QI 0 "nonimmed_operand" "=D,D,a,a,a,U,*a,*A")
862         (match_operand:QI 1 "move_operand" "M,d,r,I,U,r,*A,*r"))]
863   "xtensa_valid_move (QImode, operands)"
864   "@
865    movi.n\t%0, %x1
866    mov.n\t%0, %1
867    mov\t%0, %1
868    movi\t%0, %x1
869    %v1l8ui\t%0, %1
870    %v0s8i\t%1, %0
871    rsr\t%0, ACCLO
872    wsr\t%1, ACCLO"
873   [(set_attr "type"     "move,move,move,move,load,store,rsr,wsr")
874    (set_attr "mode"     "QI")
875    (set_attr "length"   "2,2,3,3,3,3,3,3")])
876
877 ;; 32-bit floating point moves
878
879 (define_expand "movsf"
880   [(set (match_operand:SF 0 "nonimmed_operand" "")
881         (match_operand:SF 1 "general_operand" ""))]
882   ""
883 {
884   if (!TARGET_CONST16 && CONSTANT_P (operands[1]))
885     operands[1] = force_const_mem (SFmode, operands[1]);
886
887   if ((!register_operand (operands[0], SFmode)
888        && !register_operand (operands[1], SFmode))
889       || (FP_REG_P (xt_true_regnum (operands[0]))
890           && !(reload_in_progress | reload_completed)
891           && (constantpool_mem_p (operands[1])
892               || CONSTANT_P (operands[1]))))
893     operands[1] = force_reg (SFmode, operands[1]);
894
895   operands[1] = xtensa_copy_incoming_a7 (operands[1]);
896 })
897
898 (define_insn "movsf_internal"
899   [(set (match_operand:SF 0 "nonimmed_operand" "=f,f,U,D,D,R,a,f,a,W,a,a,U")
900         (match_operand:SF 1 "move_operand" "f,U,f,d,R,d,r,r,f,iF,T,U,r"))]
901   "((register_operand (operands[0], SFmode)
902      || register_operand (operands[1], SFmode))
903     && !(FP_REG_P (xt_true_regnum (operands[0]))
904          && (constantpool_mem_p (operands[1]) || CONSTANT_P (operands[1]))))"
905   "@
906    mov.s\t%0, %1
907    %v1lsi\t%0, %1
908    %v0ssi\t%1, %0
909    mov.n\t%0, %1
910    %v1l32i.n\t%0, %1
911    %v0s32i.n\t%1, %0
912    mov\t%0, %1
913    wfr\t%0, %1
914    rfr\t%0, %1
915    const16\t%0, %t1\;const16\t%0, %b1
916    %v1l32r\t%0, %1
917    %v1l32i\t%0, %1
918    %v0s32i\t%1, %0"
919   [(set_attr "type"     "farith,fload,fstore,move,load,store,move,farith,farith,move,load,load,store")
920    (set_attr "mode"     "SF")
921    (set_attr "length"   "3,3,3,2,2,2,3,3,3,6,3,3,3")])
922
923 (define_insn "*lsiu"
924   [(set (match_operand:SF 0 "register_operand" "=f")
925         (mem:SF (plus:SI (match_operand:SI 1 "register_operand" "+a")
926                          (match_operand:SI 2 "fpmem_offset_operand" "i"))))
927    (set (match_dup 1)
928         (plus:SI (match_dup 1) (match_dup 2)))]
929   "TARGET_HARD_FLOAT"
930 {
931   if (TARGET_SERIALIZE_VOLATILE && volatile_refs_p (PATTERN (insn)))
932     output_asm_insn ("memw", operands);
933   return "lsiu\t%0, %1, %2";
934 }
935   [(set_attr "type"     "fload")
936    (set_attr "mode"     "SF")
937    (set_attr "length"   "3")])
938
939 (define_insn "*ssiu"
940   [(set (mem:SF (plus:SI (match_operand:SI 0 "register_operand" "+a")
941                          (match_operand:SI 1 "fpmem_offset_operand" "i")))
942         (match_operand:SF 2 "register_operand" "f"))
943    (set (match_dup 0)
944         (plus:SI (match_dup 0) (match_dup 1)))]
945   "TARGET_HARD_FLOAT"
946 {
947   if (TARGET_SERIALIZE_VOLATILE && volatile_refs_p (PATTERN (insn)))
948     output_asm_insn ("memw", operands);
949   return "ssiu\t%2, %0, %1";
950 }
951   [(set_attr "type"     "fstore")
952    (set_attr "mode"     "SF")
953    (set_attr "length"   "3")])
954
955 ;; 64-bit floating point moves
956
957 (define_expand "movdf"
958   [(set (match_operand:DF 0 "nonimmed_operand" "")
959         (match_operand:DF 1 "general_operand" ""))]
960   ""
961 {
962   if (CONSTANT_P (operands[1]) && !TARGET_CONST16)
963     operands[1] = force_const_mem (DFmode, operands[1]);
964
965   if (!register_operand (operands[0], DFmode)
966       && !register_operand (operands[1], DFmode))
967     operands[1] = force_reg (DFmode, operands[1]);
968
969   operands[1] = xtensa_copy_incoming_a7 (operands[1]);
970 })
971
972 (define_insn_and_split "movdf_internal"
973   [(set (match_operand:DF 0 "nonimmed_operand" "=a,W,a,a,U")
974         (match_operand:DF 1 "move_operand" "r,iF,T,U,r"))]
975   "register_operand (operands[0], DFmode)
976    || register_operand (operands[1], DFmode)"
977   "#"
978   "reload_completed"
979   [(set (match_dup 0) (match_dup 2))
980    (set (match_dup 1) (match_dup 3))]
981 {
982   xtensa_split_operand_pair (operands, SFmode);
983   if (reg_overlap_mentioned_p (operands[0], operands[3]))
984     {
985       rtx tmp;
986       tmp = operands[0], operands[0] = operands[1], operands[1] = tmp;
987       tmp = operands[2], operands[2] = operands[3], operands[3] = tmp;
988     }
989 })
990
991 ;; Block moves
992
993 (define_expand "movmemsi"
994   [(parallel [(set (match_operand:BLK 0 "" "")
995                    (match_operand:BLK 1 "" ""))
996               (use (match_operand:SI 2 "arith_operand" ""))
997               (use (match_operand:SI 3 "const_int_operand" ""))])]
998   ""
999 {
1000   if (!xtensa_expand_block_move (operands))
1001     FAIL;
1002   DONE;
1003 })
1004
1005 \f
1006 ;; Shift instructions.
1007
1008 (define_expand "ashlsi3"
1009   [(set (match_operand:SI 0 "register_operand" "")
1010         (ashift:SI (match_operand:SI 1 "register_operand" "")
1011                    (match_operand:SI 2 "arith_operand" "")))]
1012   ""
1013 {
1014   operands[1] = xtensa_copy_incoming_a7 (operands[1]);
1015 })
1016
1017 (define_insn "ashlsi3_internal"
1018   [(set (match_operand:SI 0 "register_operand" "=a,a")
1019         (ashift:SI (match_operand:SI 1 "register_operand" "r,r")
1020                    (match_operand:SI 2 "arith_operand" "J,r")))]
1021   ""      
1022   "@
1023    slli\t%0, %1, %R2
1024    ssl\t%2\;sll\t%0, %1"
1025   [(set_attr "type"     "arith,arith")
1026    (set_attr "mode"     "SI")
1027    (set_attr "length"   "3,6")])
1028
1029 (define_insn "ashrsi3"
1030   [(set (match_operand:SI 0 "register_operand" "=a,a")
1031         (ashiftrt:SI (match_operand:SI 1 "register_operand" "r,r")
1032                      (match_operand:SI 2 "arith_operand" "J,r")))]
1033   ""
1034   "@
1035    srai\t%0, %1, %R2
1036    ssr\t%2\;sra\t%0, %1"
1037   [(set_attr "type"     "arith,arith")
1038    (set_attr "mode"     "SI")
1039    (set_attr "length"   "3,6")])
1040
1041 (define_insn "lshrsi3"
1042   [(set (match_operand:SI 0 "register_operand" "=a,a")
1043         (lshiftrt:SI (match_operand:SI 1 "register_operand" "r,r")
1044                      (match_operand:SI 2 "arith_operand" "J,r")))]
1045   ""
1046 {
1047   if (which_alternative == 0)
1048     {
1049       if ((INTVAL (operands[2]) & 0x1f) < 16)
1050         return "srli\t%0, %1, %R2";
1051       else
1052         return "extui\t%0, %1, %R2, %L2";
1053     }
1054   return "ssr\t%2\;srl\t%0, %1";
1055 }
1056   [(set_attr "type"     "arith,arith")
1057    (set_attr "mode"     "SI")
1058    (set_attr "length"   "3,6")])
1059
1060 (define_insn "rotlsi3"
1061   [(set (match_operand:SI 0 "register_operand" "=a,a")
1062         (rotate:SI (match_operand:SI 1 "register_operand" "r,r")
1063                      (match_operand:SI 2 "arith_operand" "J,r")))]
1064   ""
1065   "@
1066    ssai\t%L2\;src\t%0, %1, %1
1067    ssl\t%2\;src\t%0, %1, %1"
1068   [(set_attr "type"     "multi,multi")
1069    (set_attr "mode"     "SI")
1070    (set_attr "length"   "6,6")])
1071
1072 (define_insn "rotrsi3"
1073   [(set (match_operand:SI 0 "register_operand" "=a,a")
1074         (rotatert:SI (match_operand:SI 1 "register_operand" "r,r")
1075                      (match_operand:SI 2 "arith_operand" "J,r")))]
1076   ""
1077   "@
1078    ssai\t%R2\;src\t%0, %1, %1
1079    ssr\t%2\;src\t%0, %1, %1"
1080   [(set_attr "type"     "multi,multi")
1081    (set_attr "mode"     "SI")
1082    (set_attr "length"   "6,6")])
1083
1084 \f
1085 ;; Comparisons.
1086
1087 ;; Handle comparisons by stashing away the operands and then using that
1088 ;; information in the subsequent conditional branch.
1089
1090 (define_expand "cmpsi"
1091   [(set (cc0)
1092         (compare:CC (match_operand:SI 0 "register_operand" "")
1093                     (match_operand:SI 1 "nonmemory_operand" "")))]
1094   ""
1095 {
1096   branch_cmp[0] = operands[0];
1097   branch_cmp[1] = operands[1];
1098   branch_type = CMP_SI;
1099   DONE;
1100 })
1101
1102 (define_expand "cmpsf"
1103   [(set (cc0)
1104         (compare:CC (match_operand:SF 0 "register_operand" "")
1105                     (match_operand:SF 1 "register_operand" "")))]
1106   "TARGET_HARD_FLOAT"
1107 {
1108   branch_cmp[0] = operands[0];
1109   branch_cmp[1] = operands[1];
1110   branch_type = CMP_SF;
1111   DONE;
1112 })
1113
1114 \f
1115 ;; Conditional branches.
1116
1117 (define_expand "b<code>"
1118   [(set (pc)
1119         (if_then_else (any_cond (cc0) (const_int 0))
1120                       (label_ref (match_operand 0 "" ""))
1121                       (pc)))]
1122   ""
1123 {
1124   xtensa_expand_conditional_branch (operands, <CODE>);
1125   DONE;
1126 })
1127
1128 ;; Branch patterns for standard integer comparisons
1129
1130 (define_insn "*btrue"
1131   [(set (pc)
1132         (if_then_else (match_operator 3 "branch_operator"
1133                        [(match_operand:SI 0 "register_operand" "r,r")
1134                         (match_operand:SI 1 "branch_operand" "K,r")])
1135                       (label_ref (match_operand 2 "" ""))
1136                       (pc)))]
1137   ""
1138 {
1139   return xtensa_emit_branch (false, which_alternative == 0, operands);
1140 }
1141   [(set_attr "type"     "jump,jump")
1142    (set_attr "mode"     "none")
1143    (set_attr "length"   "3,3")])
1144
1145 (define_insn "*bfalse"
1146   [(set (pc)
1147         (if_then_else (match_operator 3 "branch_operator"
1148                        [(match_operand:SI 0 "register_operand" "r,r")
1149                         (match_operand:SI 1 "branch_operand" "K,r")])
1150                       (pc)
1151                       (label_ref (match_operand 2 "" ""))))]
1152   ""
1153 {
1154   return xtensa_emit_branch (true, which_alternative == 0, operands);
1155 }
1156   [(set_attr "type"     "jump,jump")
1157    (set_attr "mode"     "none")
1158    (set_attr "length"   "3,3")])
1159
1160 (define_insn "*ubtrue"
1161   [(set (pc)
1162         (if_then_else (match_operator 3 "ubranch_operator"
1163                        [(match_operand:SI 0 "register_operand" "r,r")
1164                         (match_operand:SI 1 "ubranch_operand" "L,r")])
1165                       (label_ref (match_operand 2 "" ""))
1166                       (pc)))]
1167   ""
1168 {
1169   return xtensa_emit_branch (false, which_alternative == 0, operands);
1170 }
1171   [(set_attr "type"     "jump,jump")
1172    (set_attr "mode"     "none")
1173    (set_attr "length"   "3,3")])
1174
1175 (define_insn "*ubfalse"
1176   [(set (pc)
1177         (if_then_else (match_operator 3 "ubranch_operator"
1178                          [(match_operand:SI 0 "register_operand" "r,r")
1179                           (match_operand:SI 1 "ubranch_operand" "L,r")])
1180                       (pc)
1181                       (label_ref (match_operand 2 "" ""))))]
1182   ""
1183 {
1184   return xtensa_emit_branch (true, which_alternative == 0, operands);
1185 }
1186   [(set_attr "type"     "jump,jump")
1187    (set_attr "mode"     "none")
1188    (set_attr "length"   "3,3")])
1189
1190 ;; Branch patterns for bit testing
1191
1192 (define_insn "*bittrue"
1193   [(set (pc)
1194         (if_then_else (match_operator 3 "boolean_operator"
1195                         [(zero_extract:SI
1196                             (match_operand:SI 0 "register_operand" "r,r")
1197                             (const_int 1)
1198                             (match_operand:SI 1 "arith_operand" "J,r"))
1199                          (const_int 0)])
1200                       (label_ref (match_operand 2 "" ""))
1201                       (pc)))]
1202   ""
1203 {
1204   return xtensa_emit_bit_branch (false, which_alternative == 0, operands);
1205 }
1206   [(set_attr "type"     "jump")
1207    (set_attr "mode"     "none")
1208    (set_attr "length"   "3")])
1209
1210 (define_insn "*bitfalse"
1211   [(set (pc)
1212         (if_then_else (match_operator 3 "boolean_operator"
1213                         [(zero_extract:SI
1214                             (match_operand:SI 0 "register_operand" "r,r")
1215                             (const_int 1)
1216                             (match_operand:SI 1 "arith_operand" "J,r"))
1217                          (const_int 0)])
1218                       (pc)
1219                       (label_ref (match_operand 2 "" ""))))]
1220   ""
1221 {
1222   return xtensa_emit_bit_branch (true, which_alternative == 0, operands);
1223 }
1224   [(set_attr "type"     "jump")
1225    (set_attr "mode"     "none")
1226    (set_attr "length"   "3")])
1227
1228 (define_insn "*masktrue"
1229   [(set (pc)
1230         (if_then_else (match_operator 3 "boolean_operator"
1231                  [(and:SI (match_operand:SI 0 "register_operand" "r")
1232                           (match_operand:SI 1 "register_operand" "r"))
1233                   (const_int 0)])
1234                       (label_ref (match_operand 2 "" ""))
1235                       (pc)))]
1236   ""
1237 {
1238   switch (GET_CODE (operands[3]))
1239     {
1240     case EQ:            return "bnone\t%0, %1, %2";
1241     case NE:            return "bany\t%0, %1, %2";
1242     default:            gcc_unreachable ();
1243     }
1244 }
1245   [(set_attr "type"     "jump")
1246    (set_attr "mode"     "none")
1247    (set_attr "length"   "3")])
1248
1249 (define_insn "*maskfalse"
1250   [(set (pc)
1251         (if_then_else (match_operator 3 "boolean_operator"
1252                  [(and:SI (match_operand:SI 0 "register_operand" "r")
1253                           (match_operand:SI 1 "register_operand" "r"))
1254                   (const_int 0)])
1255                       (pc)
1256                       (label_ref (match_operand 2 "" ""))))]
1257   ""
1258 {
1259   switch (GET_CODE (operands[3]))
1260     {
1261     case EQ:            return "bany\t%0, %1, %2";
1262     case NE:            return "bnone\t%0, %1, %2";
1263     default:            gcc_unreachable ();
1264     }
1265 }
1266   [(set_attr "type"     "jump")
1267    (set_attr "mode"     "none")
1268    (set_attr "length"   "3")])
1269
1270
1271 ;; Define the loop insns used by bct optimization to represent the
1272 ;; start and end of a zero-overhead loop (in loop.c).  This start
1273 ;; template generates the loop insn; the end template doesn't generate
1274 ;; any instructions since loop end is handled in hardware.
1275
1276 (define_insn "zero_cost_loop_start"
1277   [(set (pc)
1278         (if_then_else (eq (match_operand:SI 0 "register_operand" "a")
1279                           (const_int 0))
1280                       (label_ref (match_operand 1 "" ""))
1281                       (pc)))
1282    (set (reg:SI 19)
1283         (plus:SI (match_dup 0) (const_int -1)))]
1284   ""
1285   "loopnez\t%0, %l1"
1286   [(set_attr "type"     "jump")
1287    (set_attr "mode"     "none")
1288    (set_attr "length"   "3")])
1289
1290 (define_insn "zero_cost_loop_end"
1291   [(set (pc)
1292         (if_then_else (ne (reg:SI 19) (const_int 0))
1293                       (label_ref (match_operand 0 "" ""))
1294                       (pc)))
1295    (set (reg:SI 19)
1296         (plus:SI (reg:SI 19) (const_int -1)))]
1297   ""
1298 {
1299     xtensa_emit_loop_end (insn, operands);
1300     return "";
1301 }
1302   [(set_attr "type"     "jump")
1303    (set_attr "mode"     "none")
1304    (set_attr "length"   "0")])
1305
1306 \f
1307 ;; Setting a register from a comparison.
1308
1309 (define_expand "s<code>"
1310   [(set (match_operand:SI 0 "register_operand" "")
1311         (any_scc:SI (match_dup 1)
1312                     (match_dup 2)))]
1313   ""
1314 {
1315   operands[1] = gen_rtx_<CODE> (SImode, branch_cmp[0], branch_cmp[1]);
1316   if (!xtensa_expand_scc (operands))
1317     FAIL;
1318   DONE;
1319 })
1320
1321 \f
1322 ;; Conditional moves.
1323
1324 (define_expand "movsicc"
1325   [(set (match_operand:SI 0 "register_operand" "")
1326         (if_then_else:SI (match_operand 1 "comparison_operator" "")
1327                          (match_operand:SI 2 "register_operand" "")
1328                          (match_operand:SI 3 "register_operand" "")))]
1329   ""
1330 {
1331   if (!xtensa_expand_conditional_move (operands, 0))
1332     FAIL;
1333   DONE;
1334 })
1335
1336 (define_expand "movsfcc"
1337   [(set (match_operand:SF 0 "register_operand" "")
1338         (if_then_else:SF (match_operand 1 "comparison_operator" "")
1339                          (match_operand:SF 2 "register_operand" "")
1340                          (match_operand:SF 3 "register_operand" "")))]
1341   ""
1342 {
1343   if (!xtensa_expand_conditional_move (operands, 1))
1344     FAIL;
1345   DONE;
1346 })
1347
1348 (define_insn "movsicc_internal0"
1349   [(set (match_operand:SI 0 "register_operand" "=a,a")
1350         (if_then_else:SI (match_operator 4 "branch_operator"
1351                            [(match_operand:SI 1 "register_operand" "r,r")
1352                             (const_int 0)])
1353                          (match_operand:SI 2 "register_operand" "r,0")
1354                          (match_operand:SI 3 "register_operand" "0,r")))]
1355   ""
1356 {
1357   return xtensa_emit_movcc (which_alternative == 1, false, false, operands);
1358 }
1359   [(set_attr "type"     "move,move")
1360    (set_attr "mode"     "SI")
1361    (set_attr "length"   "3,3")])
1362
1363 (define_insn "movsicc_internal1"
1364   [(set (match_operand:SI 0 "register_operand" "=a,a")
1365         (if_then_else:SI (match_operator 4 "boolean_operator"
1366                            [(match_operand:CC 1 "register_operand" "b,b")
1367                             (const_int 0)])
1368                          (match_operand:SI 2 "register_operand" "r,0")
1369                          (match_operand:SI 3 "register_operand" "0,r")))]
1370   "TARGET_BOOLEANS"
1371 {
1372   return xtensa_emit_movcc (which_alternative == 1, false, true, operands);
1373 }
1374   [(set_attr "type"     "move,move")
1375    (set_attr "mode"     "SI")
1376    (set_attr "length"   "3,3")])
1377
1378 (define_insn "movsfcc_internal0"
1379   [(set (match_operand:SF 0 "register_operand" "=a,a,f,f")
1380         (if_then_else:SF (match_operator 4 "branch_operator"
1381                            [(match_operand:SI 1 "register_operand" "r,r,r,r")
1382                             (const_int 0)])
1383                          (match_operand:SF 2 "register_operand" "r,0,f,0")
1384                          (match_operand:SF 3 "register_operand" "0,r,0,f")))]
1385   ""
1386 {
1387   return xtensa_emit_movcc ((which_alternative & 1) == 1,
1388                             which_alternative >= 2, false, operands);
1389 }
1390   [(set_attr "type"     "move,move,move,move")
1391    (set_attr "mode"     "SF")
1392    (set_attr "length"   "3,3,3,3")])
1393
1394 (define_insn "movsfcc_internal1"
1395   [(set (match_operand:SF 0 "register_operand" "=a,a,f,f")
1396         (if_then_else:SF (match_operator 4 "boolean_operator"
1397                            [(match_operand:CC 1 "register_operand" "b,b,b,b")
1398                             (const_int 0)])
1399                          (match_operand:SF 2 "register_operand" "r,0,f,0")
1400                          (match_operand:SF 3 "register_operand" "0,r,0,f")))]
1401   "TARGET_BOOLEANS"
1402 {
1403   return xtensa_emit_movcc ((which_alternative & 1) == 1,
1404                             which_alternative >= 2, true, operands);
1405 }
1406   [(set_attr "type"     "move,move,move,move")
1407    (set_attr "mode"     "SF")
1408    (set_attr "length"   "3,3,3,3")])
1409
1410 \f
1411 ;; Floating-point comparisons.
1412
1413 (define_insn "s<code>_sf"
1414   [(set (match_operand:CC 0 "register_operand" "=b")
1415         (any_scc_sf:CC (match_operand:SF 1 "register_operand" "f")
1416                        (match_operand:SF 2 "register_operand" "f")))]
1417   "TARGET_HARD_FLOAT"
1418   "o<code>.s\t%0, %1, %2"
1419   [(set_attr "type"     "farith")
1420    (set_attr "mode"     "BL")
1421    (set_attr "length"   "3")])
1422
1423 \f
1424 ;; Unconditional branches.
1425
1426 (define_insn "jump"
1427   [(set (pc)
1428         (label_ref (match_operand 0 "" "")))]
1429   ""
1430   "j\t%l0"
1431   [(set_attr "type"     "jump")
1432    (set_attr "mode"     "none")
1433    (set_attr "length"   "3")])
1434
1435 (define_expand "indirect_jump"
1436   [(set (pc)
1437         (match_operand 0 "register_operand" ""))]
1438   ""
1439 {
1440   rtx dest = operands[0];
1441   if (GET_CODE (dest) != REG || GET_MODE (dest) != Pmode)
1442     operands[0] = copy_to_mode_reg (Pmode, dest);
1443
1444   emit_jump_insn (gen_indirect_jump_internal (dest));
1445   DONE;
1446 })
1447
1448 (define_insn "indirect_jump_internal"
1449   [(set (pc) (match_operand:SI 0 "register_operand" "r"))]
1450   ""
1451   "jx\t%0"
1452   [(set_attr "type"     "jump")
1453    (set_attr "mode"     "none")
1454    (set_attr "length"   "3")])
1455
1456
1457 (define_expand "tablejump"
1458   [(use (match_operand:SI 0 "register_operand" ""))
1459    (use (label_ref (match_operand 1 "" "")))]
1460    ""
1461 {
1462   rtx target = operands[0];
1463   if (flag_pic)
1464     {
1465       /* For PIC, the table entry is relative to the start of the table.  */
1466       rtx label = gen_reg_rtx (SImode);
1467       target = gen_reg_rtx (SImode);
1468       emit_move_insn (label, gen_rtx_LABEL_REF (SImode, operands[1]));
1469       emit_insn (gen_addsi3 (target, operands[0], label));
1470     }
1471   emit_jump_insn (gen_tablejump_internal (target, operands[1]));
1472   DONE;
1473 })
1474
1475 (define_insn "tablejump_internal"
1476   [(set (pc)
1477         (match_operand:SI 0 "register_operand" "r"))
1478    (use (label_ref (match_operand 1 "" "")))]
1479   ""
1480   "jx\t%0"
1481   [(set_attr "type"     "jump")
1482    (set_attr "mode"     "none")
1483    (set_attr "length"   "3")])
1484
1485 \f
1486 ;; Function calls.
1487
1488 (define_expand "sym_PLT"
1489   [(const (unspec [(match_operand:SI 0 "" "")] UNSPEC_PLT))]
1490   ""
1491   "")
1492
1493 (define_expand "call"
1494   [(call (match_operand 0 "memory_operand" "")
1495          (match_operand 1 "" ""))]
1496   ""
1497 {
1498   rtx addr = XEXP (operands[0], 0);
1499   if (flag_pic && GET_CODE (addr) == SYMBOL_REF
1500       && (!SYMBOL_REF_LOCAL_P (addr) || SYMBOL_REF_EXTERNAL_P (addr)))
1501     addr = gen_sym_PLT (addr);
1502   if (!call_insn_operand (addr, VOIDmode))
1503     XEXP (operands[0], 0) = copy_to_mode_reg (Pmode, addr);
1504 })
1505
1506 (define_insn "call_internal"
1507   [(call (mem (match_operand:SI 0 "call_insn_operand" "nir"))
1508          (match_operand 1 "" "i"))]
1509   ""
1510 {
1511   return xtensa_emit_call (0, operands);
1512 }
1513   [(set_attr "type"     "call")
1514    (set_attr "mode"     "none")
1515    (set_attr "length"   "3")])
1516
1517 (define_expand "call_value"
1518   [(set (match_operand 0 "register_operand" "")
1519         (call (match_operand 1 "memory_operand" "")
1520               (match_operand 2 "" "")))]
1521   ""
1522 {
1523   rtx addr = XEXP (operands[1], 0);
1524   if (flag_pic && GET_CODE (addr) == SYMBOL_REF
1525       && (!SYMBOL_REF_LOCAL_P (addr) || SYMBOL_REF_EXTERNAL_P (addr)))
1526     addr = gen_sym_PLT (addr);
1527   if (!call_insn_operand (addr, VOIDmode))
1528     XEXP (operands[1], 0) = copy_to_mode_reg (Pmode, addr);
1529 })
1530
1531 (define_insn "call_value_internal"
1532    [(set (match_operand 0 "register_operand" "=a")
1533          (call (mem (match_operand:SI 1 "call_insn_operand" "nir"))
1534                (match_operand 2 "" "i")))]
1535   ""
1536 {
1537   return xtensa_emit_call (1, operands);
1538 }
1539   [(set_attr "type"     "call")
1540    (set_attr "mode"     "none")
1541    (set_attr "length"   "3")])
1542
1543 (define_insn "entry"
1544   [(set (reg:SI A1_REG)
1545         (unspec_volatile:SI [(match_operand:SI 0 "const_int_operand" "i")]
1546                             UNSPECV_ENTRY))]
1547   ""
1548   "entry\tsp, %0"
1549   [(set_attr "type"     "entry")
1550    (set_attr "mode"     "SI")
1551    (set_attr "length"   "3")])
1552
1553 (define_insn "return"
1554   [(return)
1555    (use (reg:SI A0_REG))]
1556   "reload_completed"
1557 {
1558   return (TARGET_DENSITY ? "retw.n" : "retw");
1559 }
1560   [(set_attr "type"     "jump")
1561    (set_attr "mode"     "none")
1562    (set_attr "length"   "2")])
1563
1564 \f
1565 ;; Miscellaneous instructions.
1566
1567 (define_expand "prologue"
1568   [(const_int 0)]
1569   ""
1570 {
1571   xtensa_expand_prologue ();
1572   DONE;
1573 })
1574
1575 (define_expand "epilogue"
1576   [(return)]
1577   ""
1578 {
1579   emit_jump_insn (gen_return ());
1580   DONE;
1581 })
1582
1583 (define_insn "nop"
1584   [(const_int 0)]
1585   ""
1586 {
1587   return (TARGET_DENSITY ? "nop.n" : "nop");
1588 }
1589   [(set_attr "type"     "nop")
1590    (set_attr "mode"     "none")
1591    (set_attr "length"   "3")])
1592
1593 (define_expand "nonlocal_goto"
1594   [(match_operand:SI 0 "general_operand" "")
1595    (match_operand:SI 1 "general_operand" "")
1596    (match_operand:SI 2 "general_operand" "")
1597    (match_operand:SI 3 "" "")]
1598   ""
1599 {
1600   xtensa_expand_nonlocal_goto (operands);
1601   DONE;
1602 })
1603
1604 ;; Stuff an address into the return address register along with the window
1605 ;; size in the high bits.  Because we don't have the window size of the
1606 ;; previous frame, assume the function called out with a CALL8 since that
1607 ;; is what compilers always use.  Note: __builtin_frob_return_addr has
1608 ;; already been applied to the handler, but the generic version doesn't
1609 ;; allow us to frob it quite enough, so we just frob here.
1610
1611 (define_insn_and_split "eh_return"
1612   [(set (reg:SI A0_REG)
1613         (unspec_volatile:SI [(match_operand:SI 0 "register_operand" "r")]
1614                             UNSPECV_EH_RETURN))
1615    (clobber (match_scratch:SI 1 "=r"))]
1616   ""
1617   "#"
1618   "reload_completed"
1619   [(set (match_dup 1) (ashift:SI (match_dup 0) (const_int 2)))
1620    (set (match_dup 1) (plus:SI (match_dup 1) (const_int 2)))
1621    (set (reg:SI A0_REG) (rotatert:SI (match_dup 1) (const_int 2)))]
1622   "")
1623
1624 ;; Setting up a frame pointer is tricky for Xtensa because GCC doesn't
1625 ;; know if a frame pointer is required until the reload pass, and
1626 ;; because there may be an incoming argument value in the hard frame
1627 ;; pointer register (a7).  If there is an incoming argument in that
1628 ;; register, the "set_frame_ptr" insn gets inserted immediately after
1629 ;; the insn that copies the incoming argument to a pseudo or to the
1630 ;; stack.  This serves several purposes here: (1) it keeps the
1631 ;; optimizer from copy-propagating or scheduling the use of a7 as an
1632 ;; incoming argument away from the beginning of the function; (2) we
1633 ;; can use a post-reload splitter to expand away the insn if a frame
1634 ;; pointer is not required, so that the post-reload scheduler can do
1635 ;; the right thing; and (3) it makes it easy for the prologue expander
1636 ;; to search for this insn to determine whether it should add a new insn
1637 ;; to set up the frame pointer.
1638
1639 (define_insn "set_frame_ptr"
1640   [(set (reg:SI A7_REG) (unspec_volatile:SI [(const_int 0)] UNSPECV_SET_FP))]
1641   ""
1642 {
1643   if (frame_pointer_needed)
1644     return "mov\ta7, sp";
1645   return "";
1646 }
1647   [(set_attr "type"     "move")
1648    (set_attr "mode"     "SI")
1649    (set_attr "length"   "3")])
1650
1651 ;; Post-reload splitter to remove fp assignment when it's not needed.
1652 (define_split
1653   [(set (reg:SI A7_REG) (unspec_volatile:SI [(const_int 0)] UNSPECV_SET_FP))]
1654   "reload_completed && !frame_pointer_needed"
1655   [(unspec [(const_int 0)] UNSPEC_NOP)]
1656   "")
1657
1658 ;; The preceding splitter needs something to split the insn into;
1659 ;; things start breaking if the result is just a "use" so instead we
1660 ;; generate the following insn.
1661 (define_insn "*unspec_nop"
1662   [(unspec [(const_int 0)] UNSPEC_NOP)]
1663   ""
1664   ""
1665   [(set_attr "type"     "nop")
1666    (set_attr "mode"     "none")
1667    (set_attr "length"   "0")])
1668
1669 \f
1670 ;; Instructions for the Xtensa "boolean" option.
1671
1672 (define_insn "*booltrue"
1673   [(set (pc)
1674         (if_then_else (match_operator 2 "boolean_operator"
1675                          [(match_operand:CC 0 "register_operand" "b")
1676                           (const_int 0)])
1677                       (label_ref (match_operand 1 "" ""))
1678                       (pc)))]
1679   "TARGET_BOOLEANS"
1680 {
1681   if (GET_CODE (operands[2]) == EQ)
1682     return "bf\t%0, %1";
1683   else
1684     return "bt\t%0, %1";
1685 }
1686   [(set_attr "type"     "jump")
1687    (set_attr "mode"     "none")
1688    (set_attr "length"   "3")])
1689
1690 (define_insn "*boolfalse"
1691   [(set (pc)
1692         (if_then_else (match_operator 2 "boolean_operator"
1693                          [(match_operand:CC 0 "register_operand" "b")
1694                           (const_int 0)])
1695                       (pc)
1696                       (label_ref (match_operand 1 "" ""))))]
1697   "TARGET_BOOLEANS"
1698 {
1699   if (GET_CODE (operands[2]) == EQ)
1700     return "bt\t%0, %1";
1701   else
1702     return "bf\t%0, %1";
1703 }
1704   [(set_attr "type"     "jump")
1705    (set_attr "mode"     "none")
1706    (set_attr "length"   "3")])
1707
1708 \f
1709 ;; Atomic operations
1710
1711 (define_expand "memory_barrier"
1712   [(set (mem:BLK (match_dup 0))
1713         (unspec_volatile:BLK [(mem:BLK (match_dup 0))] UNSPECV_MEMW))]
1714   ""
1715 {
1716   operands[0] = gen_rtx_MEM (BLKmode, gen_rtx_SCRATCH (SImode));
1717   MEM_VOLATILE_P (operands[0]) = 1;
1718 })
1719
1720 (define_insn "*memory_barrier"
1721   [(set (match_operand:BLK 0 "" "")
1722         (unspec_volatile:BLK [(match_operand:BLK 1 "" "")] UNSPECV_MEMW))]
1723   ""
1724   "memw"
1725   [(set_attr "type"     "unknown")
1726    (set_attr "mode"     "none")
1727    (set_attr "length"   "3")])
1728
1729 ;; sync_lock_release is only implemented for SImode.
1730 ;; For other modes, just use the default of a store with a memory_barrier.
1731 (define_insn "sync_lock_releasesi"
1732   [(set (match_operand:SI 0 "mem_operand" "=U")
1733         (unspec_volatile:SI
1734           [(match_operand:SI 1 "register_operand" "r")]
1735           UNSPECV_S32RI))]
1736   "TARGET_RELEASE_SYNC"
1737   "s32ri\t%1, %0"
1738   [(set_attr "type"     "store")
1739    (set_attr "mode"     "SI")
1740    (set_attr "length"   "3")])
1741
1742 (define_insn "sync_compare_and_swapsi"
1743   [(parallel
1744     [(set (match_operand:SI 0 "register_operand" "=a")
1745           (match_operand:SI 1 "mem_operand" "+U"))
1746      (set (match_dup 1)
1747           (unspec_volatile:SI
1748             [(match_dup 1)
1749              (match_operand:SI 2 "register_operand" "r")
1750              (match_operand:SI 3 "register_operand" "0")]
1751             UNSPECV_S32C1I))])]
1752   "TARGET_S32C1I"
1753   "wsr\t%2, SCOMPARE1\;s32c1i\t%3, %1"
1754   [(set_attr "type"     "multi")
1755    (set_attr "mode"     "SI")
1756    (set_attr "length"   "6")])
1757
1758 (define_expand "sync_compare_and_swap<mode>"
1759   [(parallel
1760     [(set (match_operand:HQI 0 "register_operand" "")
1761           (match_operand:HQI 1 "mem_operand" ""))
1762      (set (match_dup 1)
1763           (unspec_volatile:HQI
1764             [(match_dup 1)
1765              (match_operand:HQI 2 "register_operand" "")
1766              (match_operand:HQI 3 "register_operand" "")]
1767             UNSPECV_S32C1I))])]
1768   "TARGET_S32C1I"
1769 {
1770   xtensa_expand_compare_and_swap (operands[0], operands[1],
1771                                   operands[2], operands[3]);
1772   DONE;
1773 })
1774
1775 (define_expand "sync_lock_test_and_set<mode>"
1776   [(match_operand:HQI 0 "register_operand")
1777    (match_operand:HQI 1 "memory_operand")
1778    (match_operand:HQI 2 "register_operand")]
1779   "TARGET_S32C1I"
1780 {
1781   xtensa_expand_atomic (SET, operands[0], operands[1], operands[2], false);
1782   DONE;
1783 })
1784
1785 (define_expand "sync_<atomic><mode>"
1786   [(set (match_operand:HQI 0 "memory_operand")
1787         (ATOMIC:HQI (match_dup 0)
1788                     (match_operand:HQI 1 "register_operand")))]
1789   "TARGET_S32C1I"
1790 {
1791   xtensa_expand_atomic (<CODE>, NULL_RTX, operands[0], operands[1], false);
1792   DONE;
1793 })
1794
1795 (define_expand "sync_old_<atomic><mode>"
1796   [(set (match_operand:HQI 0 "register_operand")
1797         (match_operand:HQI 1 "memory_operand"))
1798    (set (match_dup 1)
1799         (ATOMIC:HQI (match_dup 1)
1800                     (match_operand:HQI 2 "register_operand")))]
1801   "TARGET_S32C1I"
1802 {
1803   xtensa_expand_atomic (<CODE>, operands[0], operands[1], operands[2], false);
1804   DONE;
1805 })
1806
1807 (define_expand "sync_new_<atomic><mode>"
1808   [(set (match_operand:HQI 0 "register_operand")
1809         (ATOMIC:HQI (match_operand:HQI 1 "memory_operand")
1810                     (match_operand:HQI 2 "register_operand"))) 
1811    (set (match_dup 1) (ATOMIC:HQI (match_dup 1) (match_dup 2)))]
1812   "TARGET_S32C1I"
1813 {
1814   xtensa_expand_atomic (<CODE>, operands[0], operands[1], operands[2], true);
1815   DONE;
1816 })