OSDN Git Service

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