2013-10-22 Jan-Benedict Glaw <jbglaw@lug-owl.de>
[official-gcc.git] / gcc / config / xtensa / xtensa.md
blob2363693a67a9d2ad3621be13b35af42bfd7e568e
1 ;; GCC machine description for Tensilica's Xtensa architecture.
2 ;; Copyright (C) 2001-2013 Free Software Foundation, Inc.
3 ;; Contributed by Bob Wilson (bwilson@tensilica.com) at Tensilica.
5 ;; This file is part of GCC.
7 ;; GCC is free software; you can redistribute it and/or modify it
8 ;; under the terms of the GNU General Public License as published by
9 ;; the Free Software Foundation; either version 3, or (at your option)
10 ;; any later version.
12 ;; GCC is distributed in the hope that it will be useful, but WITHOUT
13 ;; ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
14 ;; or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public
15 ;; License for more details.
17 ;; You should have received a copy of the GNU General Public License
18 ;; along with GCC; see the file COPYING3.  If not see
19 ;; <http://www.gnu.org/licenses/>.
22 (define_constants [
23   (A0_REG               0)
24   (A1_REG               1)
25   (A7_REG               7)
26   (A8_REG               8)
28   (UNSPEC_NOP           2)
29   (UNSPEC_PLT           3)
30   (UNSPEC_RET_ADDR      4)
31   (UNSPEC_TPOFF         5)
32   (UNSPEC_DTPOFF        6)
33   (UNSPEC_TLS_FUNC      7)
34   (UNSPEC_TLS_ARG       8)
35   (UNSPEC_TLS_CALL      9)
36   (UNSPEC_TP            10)
37   (UNSPEC_MEMW          11)
39   (UNSPECV_SET_FP       1)
40   (UNSPECV_ENTRY        2)
41   (UNSPECV_S32RI        4)
42   (UNSPECV_S32C1I       5)
43   (UNSPECV_EH_RETURN    6)
44   (UNSPECV_SET_TP       7)
47 ;; This code iterator allows signed and unsigned widening multiplications
48 ;; to use the same template.
49 (define_code_iterator any_extend [sign_extend zero_extend])
51 ;; <u> expands to an empty string when doing a signed operation and
52 ;; "u" when doing an unsigned operation.
53 (define_code_attr u [(sign_extend "") (zero_extend "u")])
55 ;; <su> is like <u>, but the signed form expands to "s" rather than "".
56 (define_code_attr su [(sign_extend "s") (zero_extend "u")])
58 ;; This code iterator allows four integer min/max operations to be
59 ;; generated from one template.
60 (define_code_iterator any_minmax [smin umin smax umax])
62 ;; <minmax> expands to the opcode name for any_minmax operations.
63 (define_code_attr minmax [(smin "min") (umin "minu")
64                           (smax "max") (umax "maxu")])
66 ;; This code iterator is for floating-point comparisons.
67 (define_code_iterator any_scc_sf [eq lt le uneq unlt unle unordered])
68 (define_code_attr scc_sf [(eq "oeq") (lt "olt") (le "ole") 
69                           (uneq "ueq") (unlt "ult") (unle "ule")
70                           (unordered "un")])
72 ;; This iterator and attribute allow to combine most atomic operations.
73 (define_code_iterator ATOMIC [and ior xor plus minus mult])
74 (define_code_attr atomic [(and "and") (ior "ior") (xor "xor") 
75                           (plus "add") (minus "sub") (mult "nand")])
77 ;; This mode iterator allows the HI and QI patterns to be defined from
78 ;; the same template.
79 (define_mode_iterator HQI [HI QI])
82 ;; Attributes.
84 (define_attr "type"
85   "unknown,jump,call,load,store,move,arith,multi,nop,farith,fmadd,fdiv,fsqrt,fconv,fload,fstore,mul16,mul32,div32,mac16,rsr,wsr,entry"
86   (const_string "unknown"))
88 (define_attr "mode"
89   "unknown,none,QI,HI,SI,DI,SF,DF,BL"
90   (const_string "unknown"))
92 (define_attr "length" "" (const_int 1))
94 ;; Describe a user's asm statement.
95 (define_asm_attributes
96   [(set_attr "type" "multi")])
99 ;; Pipeline model.
101 ;; The Xtensa basically has simple 5-stage RISC pipeline.
102 ;; Most instructions complete in 1 cycle, and it is OK to assume that
103 ;; everything is fully pipelined.  The exceptions have special insn
104 ;; reservations in the pipeline description below.  The Xtensa can
105 ;; issue one instruction per cycle, so defining CPU units is unnecessary.
107 (define_insn_reservation "xtensa_any_insn" 1
108                          (eq_attr "type" "!load,fload,rsr,mul16,mul32,fmadd,fconv")
109                          "nothing")
111 (define_insn_reservation "xtensa_memory" 2
112                          (eq_attr "type" "load,fload")
113                          "nothing")
115 (define_insn_reservation "xtensa_sreg" 2
116                          (eq_attr "type" "rsr")
117                          "nothing")
119 (define_insn_reservation "xtensa_mul16" 2
120                          (eq_attr "type" "mul16")
121                          "nothing")
123 (define_insn_reservation "xtensa_mul32" 2
124                          (eq_attr "type" "mul32")
125                          "nothing")
127 (define_insn_reservation "xtensa_fmadd" 4
128                          (eq_attr "type" "fmadd")
129                          "nothing")
131 (define_insn_reservation "xtensa_fconv" 2
132                          (eq_attr "type" "fconv")
133                          "nothing")
135 ;; Include predicates and constraints.
137 (include "predicates.md")
138 (include "constraints.md")
141 ;; Addition.
143 (define_insn "addsi3"
144   [(set (match_operand:SI 0 "register_operand" "=D,D,a,a,a")
145         (plus:SI (match_operand:SI 1 "register_operand" "%d,d,r,r,r")
146                  (match_operand:SI 2 "add_operand" "d,O,r,J,N")))]
147   ""
148   "@
149    add.n\t%0, %1, %2
150    addi.n\t%0, %1, %d2
151    add\t%0, %1, %2
152    addi\t%0, %1, %d2
153    addmi\t%0, %1, %x2"
154   [(set_attr "type"     "arith,arith,arith,arith,arith")
155    (set_attr "mode"     "SI")
156    (set_attr "length"   "2,2,3,3,3")])
158 (define_insn "*addx"
159   [(set (match_operand:SI 0 "register_operand" "=a")
160         (plus:SI (mult:SI (match_operand:SI 1 "register_operand" "r")
161                           (match_operand:SI 3 "addsubx_operand" "i"))
162                  (match_operand:SI 2 "register_operand" "r")))]
163   "TARGET_ADDX"
164   "addx%3\t%0, %1, %2"
165   [(set_attr "type"     "arith")
166    (set_attr "mode"     "SI")
167    (set_attr "length"   "3")])
169 (define_insn "addsf3"
170   [(set (match_operand:SF 0 "register_operand" "=f")
171         (plus:SF (match_operand:SF 1 "register_operand" "%f")
172                  (match_operand:SF 2 "register_operand" "f")))]
173   "TARGET_HARD_FLOAT"
174   "add.s\t%0, %1, %2"
175   [(set_attr "type"     "fmadd")
176    (set_attr "mode"     "SF")
177    (set_attr "length"   "3")])
180 ;; Subtraction.
182 (define_insn "subsi3"
183   [(set (match_operand:SI 0 "register_operand" "=a")
184         (minus:SI (match_operand:SI 1 "register_operand" "r")
185                   (match_operand:SI 2 "register_operand" "r")))]
186   ""
187   "sub\t%0, %1, %2"
188   [(set_attr "type"     "arith")
189    (set_attr "mode"     "SI")
190    (set_attr "length"   "3")])
192 (define_insn "*subx"
193   [(set (match_operand:SI 0 "register_operand" "=a")
194         (minus:SI (mult:SI (match_operand:SI 1 "register_operand" "r")
195                            (match_operand:SI 3 "addsubx_operand" "i"))
196                   (match_operand:SI 2 "register_operand" "r")))]
197   "TARGET_ADDX"
198   "subx%3\t%0, %1, %2"
199   [(set_attr "type"     "arith")
200    (set_attr "mode"     "SI")
201    (set_attr "length"   "3")])
203 (define_insn "subsf3"
204   [(set (match_operand:SF 0 "register_operand" "=f")
205         (minus:SF (match_operand:SF 1 "register_operand" "f")
206                   (match_operand:SF 2 "register_operand" "f")))]
207   "TARGET_HARD_FLOAT"
208   "sub.s\t%0, %1, %2"
209   [(set_attr "type"     "fmadd")
210    (set_attr "mode"     "SF")
211    (set_attr "length"   "3")])
214 ;; Multiplication.
216 (define_expand "<u>mulsidi3"
217   [(set (match_operand:DI 0 "register_operand")
218         (mult:DI (any_extend:DI (match_operand:SI 1 "register_operand"))
219                  (any_extend:DI (match_operand:SI 2 "register_operand"))))]
220   "TARGET_MUL32_HIGH"
222   rtx temp = gen_reg_rtx (SImode);
223   emit_insn (gen_mulsi3 (temp, operands[1], operands[2]));
224   emit_insn (gen_<u>mulsi3_highpart (gen_highpart (SImode, operands[0]),
225                                      operands[1], operands[2]));
226   emit_insn (gen_movsi (gen_lowpart (SImode, operands[0]), temp));
227   DONE;
230 (define_insn "<u>mulsi3_highpart"
231   [(set (match_operand:SI 0 "register_operand" "=a")
232         (truncate:SI
233          (lshiftrt:DI
234           (mult:DI (any_extend:DI (match_operand:SI 1 "register_operand" "%r"))
235                    (any_extend:DI (match_operand:SI 2 "register_operand" "r")))
236           (const_int 32))))]
237   "TARGET_MUL32_HIGH"
238   "mul<su>h\t%0, %1, %2"
239   [(set_attr "type"     "mul32")
240    (set_attr "mode"     "SI")
241    (set_attr "length"   "3")])
243 (define_insn "mulsi3"
244   [(set (match_operand:SI 0 "register_operand" "=a")
245         (mult:SI (match_operand:SI 1 "register_operand" "%r")
246                  (match_operand:SI 2 "register_operand" "r")))]
247   "TARGET_MUL32"
248   "mull\t%0, %1, %2"
249   [(set_attr "type"     "mul32")
250    (set_attr "mode"     "SI")
251    (set_attr "length"   "3")])
253 (define_insn "mulhisi3"
254   [(set (match_operand:SI 0 "register_operand" "=C,A")
255         (mult:SI (sign_extend:SI
256                   (match_operand:HI 1 "register_operand" "%r,r"))
257                  (sign_extend:SI
258                   (match_operand:HI 2 "register_operand" "r,r"))))]
259   "TARGET_MUL16 || TARGET_MAC16"
260   "@
261    mul16s\t%0, %1, %2
262    mul.aa.ll\t%1, %2"
263   [(set_attr "type"     "mul16,mac16")
264    (set_attr "mode"     "SI")
265    (set_attr "length"   "3,3")])
267 (define_insn "umulhisi3"
268   [(set (match_operand:SI 0 "register_operand" "=C,A")
269         (mult:SI (zero_extend:SI
270                   (match_operand:HI 1 "register_operand" "%r,r"))
271                  (zero_extend:SI
272                   (match_operand:HI 2 "register_operand" "r,r"))))]
273   "TARGET_MUL16 || TARGET_MAC16"
274   "@
275    mul16u\t%0, %1, %2
276    umul.aa.ll\t%1, %2"
277   [(set_attr "type"     "mul16,mac16")
278    (set_attr "mode"     "SI")
279    (set_attr "length"   "3,3")])
281 (define_insn "muladdhisi"
282   [(set (match_operand:SI 0 "register_operand" "=A")
283         (plus:SI (mult:SI (sign_extend:SI
284                            (match_operand:HI 1 "register_operand" "%r"))
285                           (sign_extend:SI
286                            (match_operand:HI 2 "register_operand" "r")))
287                  (match_operand:SI 3 "register_operand" "0")))]
288   "TARGET_MAC16"
289   "mula.aa.ll\t%1, %2"
290   [(set_attr "type"     "mac16")
291    (set_attr "mode"     "SI")
292    (set_attr "length"   "3")])
294 (define_insn "mulsubhisi"
295   [(set (match_operand:SI 0 "register_operand" "=A")
296         (minus:SI (match_operand:SI 1 "register_operand" "0")
297                   (mult:SI (sign_extend:SI
298                             (match_operand:HI 2 "register_operand" "%r"))
299                            (sign_extend:SI
300                             (match_operand:HI 3 "register_operand" "r")))))]
301   "TARGET_MAC16"
302   "muls.aa.ll\t%2, %3"
303   [(set_attr "type"     "mac16")
304    (set_attr "mode"     "SI")
305    (set_attr "length"   "3")])
307 (define_insn "mulsf3"
308   [(set (match_operand:SF 0 "register_operand" "=f")
309         (mult:SF (match_operand:SF 1 "register_operand" "%f")
310                  (match_operand:SF 2 "register_operand" "f")))]
311   "TARGET_HARD_FLOAT"
312   "mul.s\t%0, %1, %2"
313   [(set_attr "type"     "fmadd")
314    (set_attr "mode"     "SF")
315    (set_attr "length"   "3")])
317 (define_insn "fmasf4"
318   [(set (match_operand:SF 0 "register_operand" "=f")
319         (fma:SF (match_operand:SF 1 "register_operand" "f")
320                 (match_operand:SF 2 "register_operand" "f")
321                 (match_operand:SF 3 "register_operand" "0")))]
322   "TARGET_HARD_FLOAT"
323   "madd.s\t%0, %1, %2"
324   [(set_attr "type"     "fmadd")
325    (set_attr "mode"     "SF")
326    (set_attr "length"   "3")])
328 ;; Note that (C - A*B) = (-A*B + C)
329 (define_insn "fnmasf4"
330   [(set (match_operand:SF 0 "register_operand" "=f")
331         (fma:SF (neg:SF (match_operand:SF 1 "register_operand" "f"))
332                 (match_operand:SF 2 "register_operand" "f")
333                 (match_operand:SF 3 "register_operand" "0")))]
334   "TARGET_HARD_FLOAT"
335   "msub.s\t%0, %1, %2"
336   [(set_attr "type"     "fmadd")
337    (set_attr "mode"     "SF")
338    (set_attr "length"   "3")])
341 ;; Division.
343 (define_insn "divsi3"
344   [(set (match_operand:SI 0 "register_operand" "=a")
345         (div:SI (match_operand:SI 1 "register_operand" "r")
346                 (match_operand:SI 2 "register_operand" "r")))]
347   "TARGET_DIV32"
348   "quos\t%0, %1, %2"
349   [(set_attr "type"     "div32")
350    (set_attr "mode"     "SI")
351    (set_attr "length"   "3")])
353 (define_insn "udivsi3"
354   [(set (match_operand:SI 0 "register_operand" "=a")
355         (udiv:SI (match_operand:SI 1 "register_operand" "r")
356                  (match_operand:SI 2 "register_operand" "r")))]
357   "TARGET_DIV32"
358   "quou\t%0, %1, %2"
359   [(set_attr "type"     "div32")
360    (set_attr "mode"     "SI")
361    (set_attr "length"   "3")])
363 (define_insn "divsf3"
364   [(set (match_operand:SF 0 "register_operand" "=f")
365         (div:SF (match_operand:SF 1 "register_operand" "f")
366                 (match_operand:SF 2 "register_operand" "f")))]
367   "TARGET_HARD_FLOAT_DIV"
368   "div.s\t%0, %1, %2"
369   [(set_attr "type"     "fdiv")
370    (set_attr "mode"     "SF")
371    (set_attr "length"   "3")])
373 (define_insn "*recipsf2"
374   [(set (match_operand:SF 0 "register_operand" "=f")
375         (div:SF (match_operand:SF 1 "const_float_1_operand" "")
376                 (match_operand:SF 2 "register_operand" "f")))]
377   "TARGET_HARD_FLOAT_RECIP && flag_unsafe_math_optimizations"
378   "recip.s\t%0, %2"
379   [(set_attr "type"     "fdiv")
380    (set_attr "mode"     "SF")
381    (set_attr "length"   "3")])
384 ;; Remainders.
386 (define_insn "modsi3"
387   [(set (match_operand:SI 0 "register_operand" "=a")
388         (mod:SI (match_operand:SI 1 "register_operand" "r")
389                 (match_operand:SI 2 "register_operand" "r")))]
390   "TARGET_DIV32"
391   "rems\t%0, %1, %2"
392   [(set_attr "type"     "div32")
393    (set_attr "mode"     "SI")
394    (set_attr "length"   "3")])
396 (define_insn "umodsi3"
397   [(set (match_operand:SI 0 "register_operand" "=a")
398         (umod:SI (match_operand:SI 1 "register_operand" "r")
399                  (match_operand:SI 2 "register_operand" "r")))]
400   "TARGET_DIV32"
401   "remu\t%0, %1, %2"
402   [(set_attr "type"     "div32")
403    (set_attr "mode"     "SI")
404    (set_attr "length"   "3")])
407 ;; Square roots.
409 (define_insn "sqrtsf2"
410   [(set (match_operand:SF 0 "register_operand" "=f")
411         (sqrt:SF (match_operand:SF 1 "register_operand" "f")))]
412   "TARGET_HARD_FLOAT_SQRT"
413   "sqrt.s\t%0, %1"
414   [(set_attr "type"     "fsqrt")
415    (set_attr "mode"     "SF")
416    (set_attr "length"   "3")])
418 (define_insn "*rsqrtsf2"
419   [(set (match_operand:SF 0 "register_operand" "=f")
420         (div:SF (match_operand:SF 1 "const_float_1_operand" "")
421                 (sqrt:SF (match_operand:SF 2 "register_operand" "f"))))]
422   "TARGET_HARD_FLOAT_RSQRT && flag_unsafe_math_optimizations"
423   "rsqrt.s\t%0, %2"
424   [(set_attr "type"     "fsqrt")
425    (set_attr "mode"     "SF")
426    (set_attr "length"   "3")])
429 ;; Absolute value.
431 (define_insn "abssi2"
432   [(set (match_operand:SI 0 "register_operand" "=a")
433         (abs:SI (match_operand:SI 1 "register_operand" "r")))]
434   "TARGET_ABS"
435   "abs\t%0, %1"
436   [(set_attr "type"     "arith")
437    (set_attr "mode"     "SI")
438    (set_attr "length"   "3")])
440 (define_insn "abssf2"
441   [(set (match_operand:SF 0 "register_operand" "=f")
442         (abs:SF (match_operand:SF 1 "register_operand" "f")))]
443   "TARGET_HARD_FLOAT"
444   "abs.s\t%0, %1"
445   [(set_attr "type"     "farith")
446    (set_attr "mode"     "SF")
447    (set_attr "length"   "3")])
450 ;; Min and max.
452 (define_insn "<code>si3"
453   [(set (match_operand:SI 0 "register_operand" "=a")
454         (any_minmax:SI (match_operand:SI 1 "register_operand" "%r")
455                        (match_operand:SI 2 "register_operand" "r")))]
456   "TARGET_MINMAX"
457   "<minmax>\t%0, %1, %2"
458   [(set_attr "type"     "arith")
459    (set_attr "mode"     "SI")
460    (set_attr "length"   "3")])
463 ;; Count leading/trailing zeros and find first bit.
465 (define_insn "clzsi2"
466   [(set (match_operand:SI 0 "register_operand" "=a")
467         (clz:SI (match_operand:SI 1 "register_operand" "r")))]
468   "TARGET_NSA"
469   "nsau\t%0, %1"
470   [(set_attr "type"     "arith")
471    (set_attr "mode"     "SI")
472    (set_attr "length"   "3")])
474 (define_expand "ctzsi2"
475   [(set (match_operand:SI 0 "register_operand" "")
476         (ctz:SI (match_operand:SI 1 "register_operand" "")))]
477   "TARGET_NSA"
479   rtx temp = gen_reg_rtx (SImode);
480   emit_insn (gen_negsi2 (temp, operands[1]));
481   emit_insn (gen_andsi3 (temp, temp, operands[1]));
482   emit_insn (gen_clzsi2 (temp, temp));
483   emit_insn (gen_negsi2 (temp, temp));
484   emit_insn (gen_addsi3 (operands[0], temp, GEN_INT (31)));
485   DONE;
488 (define_expand "ffssi2"
489   [(set (match_operand:SI 0 "register_operand" "")
490         (ffs:SI (match_operand:SI 1 "register_operand" "")))]
491   "TARGET_NSA"
493   rtx temp = gen_reg_rtx (SImode);
494   emit_insn (gen_negsi2 (temp, operands[1]));
495   emit_insn (gen_andsi3 (temp, temp, operands[1]));
496   emit_insn (gen_clzsi2 (temp, temp));
497   emit_insn (gen_negsi2 (temp, temp));
498   emit_insn (gen_addsi3 (operands[0], temp, GEN_INT (32)));
499   DONE;
503 ;; Negation and one's complement.
505 (define_insn "negsi2"
506   [(set (match_operand:SI 0 "register_operand" "=a")
507         (neg:SI (match_operand:SI 1 "register_operand" "r")))]
508   ""
509   "neg\t%0, %1"
510   [(set_attr "type"     "arith")
511    (set_attr "mode"     "SI")
512    (set_attr "length"   "3")])
514 (define_expand "one_cmplsi2"
515   [(set (match_operand:SI 0 "register_operand" "")
516         (not:SI (match_operand:SI 1 "register_operand" "")))]
517   ""
519   rtx temp = gen_reg_rtx (SImode);
520   emit_insn (gen_movsi (temp, constm1_rtx));
521   emit_insn (gen_xorsi3 (operands[0], temp, operands[1]));
522   DONE;
525 (define_insn "negsf2"
526   [(set (match_operand:SF 0 "register_operand" "=f")
527         (neg:SF (match_operand:SF 1 "register_operand" "f")))]
528   "TARGET_HARD_FLOAT"
529   "neg.s\t%0, %1"
530   [(set_attr "type"     "farith")
531    (set_attr "mode"     "SF")
532    (set_attr "length"   "3")])
535 ;; Logical instructions.
537 (define_insn "andsi3"
538   [(set (match_operand:SI 0 "register_operand" "=a,a")
539         (and:SI (match_operand:SI 1 "register_operand" "%r,r")
540                 (match_operand:SI 2 "mask_operand" "P,r")))]
541   ""
542   "@
543    extui\t%0, %1, 0, %K2
544    and\t%0, %1, %2"
545   [(set_attr "type"     "arith,arith")
546    (set_attr "mode"     "SI")
547    (set_attr "length"   "3,3")])
549 (define_insn "iorsi3"
550   [(set (match_operand:SI 0 "register_operand" "=a")
551         (ior:SI (match_operand:SI 1 "register_operand" "%r")
552                 (match_operand:SI 2 "register_operand" "r")))]
553   ""
554   "or\t%0, %1, %2"
555   [(set_attr "type"     "arith")
556    (set_attr "mode"     "SI")
557    (set_attr "length"   "3")])
559 (define_insn "xorsi3"
560   [(set (match_operand:SI 0 "register_operand" "=a")
561         (xor:SI (match_operand:SI 1 "register_operand" "%r")
562                 (match_operand:SI 2 "register_operand" "r")))]
563   ""
564   "xor\t%0, %1, %2"
565   [(set_attr "type"     "arith")
566    (set_attr "mode"     "SI")
567    (set_attr "length"   "3")])
570 ;; Zero-extend instructions.
572 (define_insn "zero_extendhisi2"
573   [(set (match_operand:SI 0 "register_operand" "=a,a")
574         (zero_extend:SI (match_operand:HI 1 "nonimmed_operand" "r,U")))]
575   ""
576   "@
577    extui\t%0, %1, 0, 16
578    l16ui\t%0, %1"
579   [(set_attr "type"     "arith,load")
580    (set_attr "mode"     "SI")
581    (set_attr "length"   "3,3")])
583 (define_insn "zero_extendqisi2"
584   [(set (match_operand:SI 0 "register_operand" "=a,a")
585         (zero_extend:SI (match_operand:QI 1 "nonimmed_operand" "r,U")))]
586   ""
587   "@
588    extui\t%0, %1, 0, 8
589    l8ui\t%0, %1"
590   [(set_attr "type"     "arith,load")
591    (set_attr "mode"     "SI")
592    (set_attr "length"   "3,3")])
595 ;; Sign-extend instructions.
597 (define_expand "extendhisi2"
598   [(set (match_operand:SI 0 "register_operand" "")
599         (sign_extend:SI (match_operand:HI 1 "register_operand" "")))]
600   ""
602   if (sext_operand (operands[1], HImode))
603     emit_insn (gen_extendhisi2_internal (operands[0], operands[1]));
604   else
605     xtensa_extend_reg (operands[0], operands[1]);
606   DONE;
609 (define_insn "extendhisi2_internal"
610   [(set (match_operand:SI 0 "register_operand" "=B,a")
611         (sign_extend:SI (match_operand:HI 1 "sext_operand" "r,U")))]
612   ""
613   "@
614    sext\t%0, %1, 15
615    l16si\t%0, %1"
616   [(set_attr "type"     "arith,load")
617    (set_attr "mode"     "SI")
618    (set_attr "length"   "3,3")])
620 (define_expand "extendqisi2"
621   [(set (match_operand:SI 0 "register_operand" "")
622         (sign_extend:SI (match_operand:QI 1 "register_operand" "")))]
623   ""
625   if (TARGET_SEXT)
626     emit_insn (gen_extendqisi2_internal (operands[0], operands[1]));
627   else
628     xtensa_extend_reg (operands[0], operands[1]);
629   DONE;
632 (define_insn "extendqisi2_internal"
633   [(set (match_operand:SI 0 "register_operand" "=B")
634         (sign_extend:SI (match_operand:QI 1 "register_operand" "r")))]
635   "TARGET_SEXT"
636   "sext\t%0, %1, 7"
637   [(set_attr "type"     "arith")
638    (set_attr "mode"     "SI")
639    (set_attr "length"   "3")])
642 ;; Field extract instructions.
644 (define_expand "extv"
645   [(set (match_operand:SI 0 "register_operand" "")
646         (sign_extract:SI (match_operand:SI 1 "register_operand" "")
647                          (match_operand:SI 2 "const_int_operand" "")
648                          (match_operand:SI 3 "const_int_operand" "")))]
649   "TARGET_SEXT"
651   if (!sext_fldsz_operand (operands[2], SImode))
652     FAIL;
654   /* We could expand to a right shift followed by SEXT but that's
655      no better than the standard left and right shift sequence.  */
656   if (!lsbitnum_operand (operands[3], SImode))
657     FAIL;
659   emit_insn (gen_extv_internal (operands[0], operands[1],
660                                 operands[2], operands[3]));
661   DONE;
664 (define_insn "extv_internal"
665   [(set (match_operand:SI 0 "register_operand" "=a")
666         (sign_extract:SI (match_operand:SI 1 "register_operand" "r")
667                          (match_operand:SI 2 "sext_fldsz_operand" "i")
668                          (match_operand:SI 3 "lsbitnum_operand" "i")))]
669   "TARGET_SEXT"
671   int fldsz = INTVAL (operands[2]);
672   operands[2] = GEN_INT (fldsz - 1);
673   return "sext\t%0, %1, %2";
675   [(set_attr "type"     "arith")
676    (set_attr "mode"     "SI")
677    (set_attr "length"   "3")])
679 (define_expand "extzv"
680   [(set (match_operand:SI 0 "register_operand" "")
681         (zero_extract:SI (match_operand:SI 1 "register_operand" "")
682                          (match_operand:SI 2 "const_int_operand" "")
683                          (match_operand:SI 3 "const_int_operand" "")))]
684   ""
686   if (!extui_fldsz_operand (operands[2], SImode))
687     FAIL;
688   emit_insn (gen_extzv_internal (operands[0], operands[1],
689                                  operands[2], operands[3]));
690   DONE;
693 (define_insn "extzv_internal"
694   [(set (match_operand:SI 0 "register_operand" "=a")
695         (zero_extract:SI (match_operand:SI 1 "register_operand" "r")
696                          (match_operand:SI 2 "extui_fldsz_operand" "i")
697                          (match_operand:SI 3 "const_int_operand" "i")))]
698   ""
700   int shift;
701   if (BITS_BIG_ENDIAN)
702     shift = (32 - (INTVAL (operands[2]) + INTVAL (operands[3]))) & 0x1f;
703   else
704     shift = INTVAL (operands[3]) & 0x1f;
705   operands[3] = GEN_INT (shift);
706   return "extui\t%0, %1, %3, %2";
708   [(set_attr "type"     "arith")
709    (set_attr "mode"     "SI")
710    (set_attr "length"   "3")])
713 ;; Conversions.
715 (define_insn "fix_truncsfsi2"
716   [(set (match_operand:SI 0 "register_operand" "=a")
717         (fix:SI (match_operand:SF 1 "register_operand" "f")))]
718   "TARGET_HARD_FLOAT"
719   "trunc.s\t%0, %1, 0"
720   [(set_attr "type"     "fconv")
721    (set_attr "mode"     "SF")
722    (set_attr "length"   "3")])
724 (define_insn "fixuns_truncsfsi2"
725   [(set (match_operand:SI 0 "register_operand" "=a")
726         (unsigned_fix:SI (match_operand:SF 1 "register_operand" "f")))]
727   "TARGET_HARD_FLOAT"
728   "utrunc.s\t%0, %1, 0"
729   [(set_attr "type"     "fconv")
730    (set_attr "mode"     "SF")
731    (set_attr "length"   "3")])
733 (define_insn "floatsisf2"
734   [(set (match_operand:SF 0 "register_operand" "=f")
735         (float:SF (match_operand:SI 1 "register_operand" "a")))]
736   "TARGET_HARD_FLOAT"
737   "float.s\t%0, %1, 0"
738   [(set_attr "type"     "fconv")
739    (set_attr "mode"     "SF")
740    (set_attr "length"   "3")])
742 (define_insn "floatunssisf2"
743   [(set (match_operand:SF 0 "register_operand" "=f")
744         (unsigned_float:SF (match_operand:SI 1 "register_operand" "a")))]
745   "TARGET_HARD_FLOAT"
746   "ufloat.s\t%0, %1, 0"
747   [(set_attr "type"     "fconv")
748    (set_attr "mode"     "SF")
749    (set_attr "length"   "3")])
752 ;; Data movement instructions.
754 ;; 64-bit Integer moves
756 (define_expand "movdi"
757   [(set (match_operand:DI 0 "nonimmed_operand" "")
758         (match_operand:DI 1 "general_operand" ""))]
759   ""
761   if (CONSTANT_P (operands[1]) && !TARGET_CONST16)
762     operands[1] = force_const_mem (DImode, operands[1]);
764   if (!register_operand (operands[0], DImode)
765       && !register_operand (operands[1], DImode))
766     operands[1] = force_reg (DImode, operands[1]);
768   operands[1] = xtensa_copy_incoming_a7 (operands[1]);
771 (define_insn_and_split "movdi_internal"
772   [(set (match_operand:DI 0 "nonimmed_operand" "=a,W,a,a,U")
773         (match_operand:DI 1 "move_operand" "r,i,T,U,r"))]
774   "register_operand (operands[0], DImode)
775    || register_operand (operands[1], DImode)"
776   "#"
777   "reload_completed"
778   [(set (match_dup 0) (match_dup 2))
779    (set (match_dup 1) (match_dup 3))]
781   xtensa_split_operand_pair (operands, SImode);
782   if (reg_overlap_mentioned_p (operands[0], operands[3]))
783     {
784       rtx tmp;
785       tmp = operands[0], operands[0] = operands[1], operands[1] = tmp;
786       tmp = operands[2], operands[2] = operands[3], operands[3] = tmp;
787     }
790 ;; 32-bit Integer moves
792 (define_expand "movsi"
793   [(set (match_operand:SI 0 "nonimmed_operand" "")
794         (match_operand:SI 1 "general_operand" ""))]
795   ""
797   if (xtensa_emit_move_sequence (operands, SImode))
798     DONE;
801 (define_insn "movsi_internal"
802   [(set (match_operand:SI 0 "nonimmed_operand" "=D,D,D,D,R,R,a,q,a,W,a,a,U,*a,*A")
803         (match_operand:SI 1 "move_operand" "M,D,d,R,D,d,r,r,I,i,T,U,r,*A,*r"))]
804   "xtensa_valid_move (SImode, operands)"
805   "@
806    movi.n\t%0, %x1
807    mov.n\t%0, %1
808    mov.n\t%0, %1
809    %v1l32i.n\t%0, %1
810    %v0s32i.n\t%1, %0
811    %v0s32i.n\t%1, %0
812    mov\t%0, %1
813    movsp\t%0, %1
814    movi\t%0, %x1
815    const16\t%0, %t1\;const16\t%0, %b1
816    %v1l32r\t%0, %1
817    %v1l32i\t%0, %1
818    %v0s32i\t%1, %0
819    rsr\t%0, ACCLO
820    wsr\t%1, ACCLO"
821   [(set_attr "type" "move,move,move,load,store,store,move,move,move,move,load,load,store,rsr,wsr")
822    (set_attr "mode"     "SI")
823    (set_attr "length"   "2,2,2,2,2,2,3,3,3,6,3,3,3,3,3")])
825 ;; 16-bit Integer moves
827 (define_expand "movhi"
828   [(set (match_operand:HI 0 "nonimmed_operand" "")
829         (match_operand:HI 1 "general_operand" ""))]
830   ""
832   if (xtensa_emit_move_sequence (operands, HImode))
833     DONE;
836 (define_insn "movhi_internal"
837   [(set (match_operand:HI 0 "nonimmed_operand" "=D,D,a,a,a,U,*a,*A")
838         (match_operand:HI 1 "move_operand" "M,d,r,I,U,r,*A,*r"))]
839   "xtensa_valid_move (HImode, operands)"
840   "@
841    movi.n\t%0, %x1
842    mov.n\t%0, %1
843    mov\t%0, %1
844    movi\t%0, %x1
845    %v1l16ui\t%0, %1
846    %v0s16i\t%1, %0
847    rsr\t%0, ACCLO
848    wsr\t%1, ACCLO"
849   [(set_attr "type"     "move,move,move,move,load,store,rsr,wsr")
850    (set_attr "mode"     "HI")
851    (set_attr "length"   "2,2,3,3,3,3,3,3")])
853 ;; 8-bit Integer moves
855 (define_expand "movqi"
856   [(set (match_operand:QI 0 "nonimmed_operand" "")
857         (match_operand:QI 1 "general_operand" ""))]
858   ""
860   if (xtensa_emit_move_sequence (operands, QImode))
861     DONE;
864 (define_insn "movqi_internal"
865   [(set (match_operand:QI 0 "nonimmed_operand" "=D,D,a,a,a,U,*a,*A")
866         (match_operand:QI 1 "move_operand" "M,d,r,I,U,r,*A,*r"))]
867   "xtensa_valid_move (QImode, operands)"
868   "@
869    movi.n\t%0, %x1
870    mov.n\t%0, %1
871    mov\t%0, %1
872    movi\t%0, %x1
873    %v1l8ui\t%0, %1
874    %v0s8i\t%1, %0
875    rsr\t%0, ACCLO
876    wsr\t%1, ACCLO"
877   [(set_attr "type"     "move,move,move,move,load,store,rsr,wsr")
878    (set_attr "mode"     "QI")
879    (set_attr "length"   "2,2,3,3,3,3,3,3")])
881 ;; Sub-word reloads from the constant pool.
883 (define_expand "reload<mode>_literal"
884   [(parallel [(match_operand:HQI 0 "register_operand" "=r")
885               (match_operand:HQI 1 "constantpool_operand" "")
886               (match_operand:SI 2 "register_operand" "=&r")])]
887   ""
889   rtx lit, scratch;
890   unsigned word_off, byte_off;
892   if (MEM_P (operands[1]))
893     {
894       lit = operands[1];
895       word_off = 0;
896       byte_off = 0;
897     }
898   else
899     {
900       gcc_assert (GET_CODE (operands[1]) == SUBREG);
901       lit = SUBREG_REG (operands[1]);
902       word_off = SUBREG_BYTE (operands[1]) & ~(UNITS_PER_WORD - 1);
903       byte_off = SUBREG_BYTE (operands[1]) - word_off;
904     }
906   lit = adjust_address (lit, SImode, word_off);
907   scratch = operands[2];
908   emit_insn (gen_movsi (scratch, lit));
909   emit_insn (gen_mov<mode> (operands[0],
910                             gen_rtx_SUBREG (<MODE>mode, scratch, byte_off)));
912   DONE;
915 ;; 32-bit floating point moves
917 (define_expand "movsf"
918   [(set (match_operand:SF 0 "nonimmed_operand" "")
919         (match_operand:SF 1 "general_operand" ""))]
920   ""
922   if (!TARGET_CONST16 && CONSTANT_P (operands[1]))
923     operands[1] = force_const_mem (SFmode, operands[1]);
925   if ((!register_operand (operands[0], SFmode)
926        && !register_operand (operands[1], SFmode))
927       || (FP_REG_P (xt_true_regnum (operands[0]))
928           && !(reload_in_progress | reload_completed)
929           && (constantpool_mem_p (operands[1])
930               || CONSTANT_P (operands[1]))))
931     operands[1] = force_reg (SFmode, operands[1]);
933   operands[1] = xtensa_copy_incoming_a7 (operands[1]);
936 (define_insn "movsf_internal"
937   [(set (match_operand:SF 0 "nonimmed_operand" "=f,f,U,D,D,R,a,f,a,W,a,a,U")
938         (match_operand:SF 1 "move_operand" "f,U,f,d,R,d,r,r,f,iF,T,U,r"))]
939   "((register_operand (operands[0], SFmode)
940      || register_operand (operands[1], SFmode))
941     && !(FP_REG_P (xt_true_regnum (operands[0]))
942          && (constantpool_mem_p (operands[1]) || CONSTANT_P (operands[1]))))"
943   "@
944    mov.s\t%0, %1
945    %v1lsi\t%0, %1
946    %v0ssi\t%1, %0
947    mov.n\t%0, %1
948    %v1l32i.n\t%0, %1
949    %v0s32i.n\t%1, %0
950    mov\t%0, %1
951    wfr\t%0, %1
952    rfr\t%0, %1
953    const16\t%0, %t1\;const16\t%0, %b1
954    %v1l32r\t%0, %1
955    %v1l32i\t%0, %1
956    %v0s32i\t%1, %0"
957   [(set_attr "type"     "farith,fload,fstore,move,load,store,move,farith,farith,move,load,load,store")
958    (set_attr "mode"     "SF")
959    (set_attr "length"   "3,3,3,2,2,2,3,3,3,6,3,3,3")])
961 (define_insn "*lsiu"
962   [(set (match_operand:SF 0 "register_operand" "=f")
963         (mem:SF (plus:SI (match_operand:SI 1 "register_operand" "+a")
964                          (match_operand:SI 2 "fpmem_offset_operand" "i"))))
965    (set (match_dup 1)
966         (plus:SI (match_dup 1) (match_dup 2)))]
967   "TARGET_HARD_FLOAT"
969   if (TARGET_SERIALIZE_VOLATILE && volatile_refs_p (PATTERN (insn)))
970     output_asm_insn ("memw", operands);
971   return "lsiu\t%0, %1, %2";
973   [(set_attr "type"     "fload")
974    (set_attr "mode"     "SF")
975    (set_attr "length"   "3")])
977 (define_insn "*ssiu"
978   [(set (mem:SF (plus:SI (match_operand:SI 0 "register_operand" "+a")
979                          (match_operand:SI 1 "fpmem_offset_operand" "i")))
980         (match_operand:SF 2 "register_operand" "f"))
981    (set (match_dup 0)
982         (plus:SI (match_dup 0) (match_dup 1)))]
983   "TARGET_HARD_FLOAT"
985   if (TARGET_SERIALIZE_VOLATILE && volatile_refs_p (PATTERN (insn)))
986     output_asm_insn ("memw", operands);
987   return "ssiu\t%2, %0, %1";
989   [(set_attr "type"     "fstore")
990    (set_attr "mode"     "SF")
991    (set_attr "length"   "3")])
993 ;; 64-bit floating point moves
995 (define_expand "movdf"
996   [(set (match_operand:DF 0 "nonimmed_operand" "")
997         (match_operand:DF 1 "general_operand" ""))]
998   ""
1000   if (CONSTANT_P (operands[1]) && !TARGET_CONST16)
1001     operands[1] = force_const_mem (DFmode, operands[1]);
1003   if (!register_operand (operands[0], DFmode)
1004       && !register_operand (operands[1], DFmode))
1005     operands[1] = force_reg (DFmode, operands[1]);
1007   operands[1] = xtensa_copy_incoming_a7 (operands[1]);
1010 (define_insn_and_split "movdf_internal"
1011   [(set (match_operand:DF 0 "nonimmed_operand" "=a,W,a,a,U")
1012         (match_operand:DF 1 "move_operand" "r,iF,T,U,r"))]
1013   "register_operand (operands[0], DFmode)
1014    || register_operand (operands[1], DFmode)"
1015   "#"
1016   "reload_completed"
1017   [(set (match_dup 0) (match_dup 2))
1018    (set (match_dup 1) (match_dup 3))]
1020   xtensa_split_operand_pair (operands, SFmode);
1021   if (reg_overlap_mentioned_p (operands[0], operands[3]))
1022     {
1023       rtx tmp;
1024       tmp = operands[0], operands[0] = operands[1], operands[1] = tmp;
1025       tmp = operands[2], operands[2] = operands[3], operands[3] = tmp;
1026     }
1029 ;; Block moves
1031 (define_expand "movmemsi"
1032   [(parallel [(set (match_operand:BLK 0 "" "")
1033                    (match_operand:BLK 1 "" ""))
1034               (use (match_operand:SI 2 "arith_operand" ""))
1035               (use (match_operand:SI 3 "const_int_operand" ""))])]
1036   ""
1038   if (!xtensa_expand_block_move (operands))
1039     FAIL;
1040   DONE;
1044 ;; Shift instructions.
1046 (define_expand "ashlsi3"
1047   [(set (match_operand:SI 0 "register_operand" "")
1048         (ashift:SI (match_operand:SI 1 "register_operand" "")
1049                    (match_operand:SI 2 "arith_operand" "")))]
1050   ""
1052   operands[1] = xtensa_copy_incoming_a7 (operands[1]);
1055 (define_insn "ashlsi3_internal"
1056   [(set (match_operand:SI 0 "register_operand" "=a,a")
1057         (ashift:SI (match_operand:SI 1 "register_operand" "r,r")
1058                    (match_operand:SI 2 "arith_operand" "J,r")))]
1059   ""      
1060   "@
1061    slli\t%0, %1, %R2
1062    ssl\t%2\;sll\t%0, %1"
1063   [(set_attr "type"     "arith,arith")
1064    (set_attr "mode"     "SI")
1065    (set_attr "length"   "3,6")])
1067 (define_insn "ashrsi3"
1068   [(set (match_operand:SI 0 "register_operand" "=a,a")
1069         (ashiftrt:SI (match_operand:SI 1 "register_operand" "r,r")
1070                      (match_operand:SI 2 "arith_operand" "J,r")))]
1071   ""
1072   "@
1073    srai\t%0, %1, %R2
1074    ssr\t%2\;sra\t%0, %1"
1075   [(set_attr "type"     "arith,arith")
1076    (set_attr "mode"     "SI")
1077    (set_attr "length"   "3,6")])
1079 (define_insn "lshrsi3"
1080   [(set (match_operand:SI 0 "register_operand" "=a,a")
1081         (lshiftrt:SI (match_operand:SI 1 "register_operand" "r,r")
1082                      (match_operand:SI 2 "arith_operand" "J,r")))]
1083   ""
1085   if (which_alternative == 0)
1086     {
1087       if ((INTVAL (operands[2]) & 0x1f) < 16)
1088         return "srli\t%0, %1, %R2";
1089       else
1090         return "extui\t%0, %1, %R2, %L2";
1091     }
1092   return "ssr\t%2\;srl\t%0, %1";
1094   [(set_attr "type"     "arith,arith")
1095    (set_attr "mode"     "SI")
1096    (set_attr "length"   "3,6")])
1098 (define_insn "rotlsi3"
1099   [(set (match_operand:SI 0 "register_operand" "=a,a")
1100         (rotate:SI (match_operand:SI 1 "register_operand" "r,r")
1101                      (match_operand:SI 2 "arith_operand" "J,r")))]
1102   ""
1103   "@
1104    ssai\t%L2\;src\t%0, %1, %1
1105    ssl\t%2\;src\t%0, %1, %1"
1106   [(set_attr "type"     "multi,multi")
1107    (set_attr "mode"     "SI")
1108    (set_attr "length"   "6,6")])
1110 (define_insn "rotrsi3"
1111   [(set (match_operand:SI 0 "register_operand" "=a,a")
1112         (rotatert:SI (match_operand:SI 1 "register_operand" "r,r")
1113                      (match_operand:SI 2 "arith_operand" "J,r")))]
1114   ""
1115   "@
1116    ssai\t%R2\;src\t%0, %1, %1
1117    ssr\t%2\;src\t%0, %1, %1"
1118   [(set_attr "type"     "multi,multi")
1119    (set_attr "mode"     "SI")
1120    (set_attr "length"   "6,6")])
1123 ;; Comparisons.
1125 ;; Conditional branches.
1127 (define_expand "cbranchsi4"
1128   [(match_operator 0 "comparison_operator"
1129     [(match_operand:SI 1 "register_operand")
1130      (match_operand:SI 2 "nonmemory_operand")])
1131    (match_operand 3 "")]
1132   ""
1134   xtensa_expand_conditional_branch (operands, SImode);
1135   DONE;
1138 (define_expand "cbranchsf4"
1139   [(match_operator 0 "comparison_operator"
1140     [(match_operand:SF 1 "register_operand")
1141      (match_operand:SF 2 "register_operand")])
1142    (match_operand 3 "")]
1143   "TARGET_HARD_FLOAT"
1145   xtensa_expand_conditional_branch (operands, SFmode);
1146   DONE;
1149 ;; Branch patterns for standard integer comparisons
1151 (define_insn "*btrue"
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                       (label_ref (match_operand 2 "" ""))
1157                       (pc)))]
1158   ""
1160   return xtensa_emit_branch (false, which_alternative == 0, operands);
1162   [(set_attr "type"     "jump,jump")
1163    (set_attr "mode"     "none")
1164    (set_attr "length"   "3,3")])
1166 (define_insn "*bfalse"
1167   [(set (pc)
1168         (if_then_else (match_operator 3 "branch_operator"
1169                        [(match_operand:SI 0 "register_operand" "r,r")
1170                         (match_operand:SI 1 "branch_operand" "K,r")])
1171                       (pc)
1172                       (label_ref (match_operand 2 "" ""))))]
1173   ""
1175   return xtensa_emit_branch (true, which_alternative == 0, operands);
1177   [(set_attr "type"     "jump,jump")
1178    (set_attr "mode"     "none")
1179    (set_attr "length"   "3,3")])
1181 (define_insn "*ubtrue"
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                       (label_ref (match_operand 2 "" ""))
1187                       (pc)))]
1188   ""
1190   return xtensa_emit_branch (false, which_alternative == 0, operands);
1192   [(set_attr "type"     "jump,jump")
1193    (set_attr "mode"     "none")
1194    (set_attr "length"   "3,3")])
1196 (define_insn "*ubfalse"
1197   [(set (pc)
1198         (if_then_else (match_operator 3 "ubranch_operator"
1199                          [(match_operand:SI 0 "register_operand" "r,r")
1200                           (match_operand:SI 1 "ubranch_operand" "L,r")])
1201                       (pc)
1202                       (label_ref (match_operand 2 "" ""))))]
1203   ""
1205   return xtensa_emit_branch (true, which_alternative == 0, operands);
1207   [(set_attr "type"     "jump,jump")
1208    (set_attr "mode"     "none")
1209    (set_attr "length"   "3,3")])
1211 ;; Branch patterns for bit testing
1213 (define_insn "*bittrue"
1214   [(set (pc)
1215         (if_then_else (match_operator 3 "boolean_operator"
1216                         [(zero_extract:SI
1217                             (match_operand:SI 0 "register_operand" "r,r")
1218                             (const_int 1)
1219                             (match_operand:SI 1 "arith_operand" "J,r"))
1220                          (const_int 0)])
1221                       (label_ref (match_operand 2 "" ""))
1222                       (pc)))]
1223   ""
1225   return xtensa_emit_bit_branch (false, which_alternative == 0, operands);
1227   [(set_attr "type"     "jump")
1228    (set_attr "mode"     "none")
1229    (set_attr "length"   "3")])
1231 (define_insn "*bitfalse"
1232   [(set (pc)
1233         (if_then_else (match_operator 3 "boolean_operator"
1234                         [(zero_extract:SI
1235                             (match_operand:SI 0 "register_operand" "r,r")
1236                             (const_int 1)
1237                             (match_operand:SI 1 "arith_operand" "J,r"))
1238                          (const_int 0)])
1239                       (pc)
1240                       (label_ref (match_operand 2 "" ""))))]
1241   ""
1243   return xtensa_emit_bit_branch (true, which_alternative == 0, operands);
1245   [(set_attr "type"     "jump")
1246    (set_attr "mode"     "none")
1247    (set_attr "length"   "3")])
1249 (define_insn "*masktrue"
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                       (label_ref (match_operand 2 "" ""))
1256                       (pc)))]
1257   ""
1259   switch (GET_CODE (operands[3]))
1260     {
1261     case EQ:            return "bnone\t%0, %1, %2";
1262     case NE:            return "bany\t%0, %1, %2";
1263     default:            gcc_unreachable ();
1264     }
1266   [(set_attr "type"     "jump")
1267    (set_attr "mode"     "none")
1268    (set_attr "length"   "3")])
1270 (define_insn "*maskfalse"
1271   [(set (pc)
1272         (if_then_else (match_operator 3 "boolean_operator"
1273                  [(and:SI (match_operand:SI 0 "register_operand" "r")
1274                           (match_operand:SI 1 "register_operand" "r"))
1275                   (const_int 0)])
1276                       (pc)
1277                       (label_ref (match_operand 2 "" ""))))]
1278   ""
1280   switch (GET_CODE (operands[3]))
1281     {
1282     case EQ:            return "bany\t%0, %1, %2";
1283     case NE:            return "bnone\t%0, %1, %2";
1284     default:            gcc_unreachable ();
1285     }
1287   [(set_attr "type"     "jump")
1288    (set_attr "mode"     "none")
1289    (set_attr "length"   "3")])
1292 ;; Define the loop insns used by bct optimization to represent the
1293 ;; start and end of a zero-overhead loop (in loop.c).  This start
1294 ;; template generates the loop insn; the end template doesn't generate
1295 ;; any instructions since loop end is handled in hardware.
1297 (define_insn "zero_cost_loop_start"
1298   [(set (pc)
1299         (if_then_else (eq (match_operand:SI 0 "register_operand" "a")
1300                           (const_int 0))
1301                       (label_ref (match_operand 1 "" ""))
1302                       (pc)))
1303    (set (reg:SI 19)
1304         (plus:SI (match_dup 0) (const_int -1)))]
1305   ""
1306   "loopnez\t%0, %l1"
1307   [(set_attr "type"     "jump")
1308    (set_attr "mode"     "none")
1309    (set_attr "length"   "3")])
1311 (define_insn "zero_cost_loop_end"
1312   [(set (pc)
1313         (if_then_else (ne (reg:SI 19) (const_int 0))
1314                       (label_ref (match_operand 0 "" ""))
1315                       (pc)))
1316    (set (reg:SI 19)
1317         (plus:SI (reg:SI 19) (const_int -1)))]
1318   ""
1320     xtensa_emit_loop_end (insn, operands);
1321     return "";
1323   [(set_attr "type"     "jump")
1324    (set_attr "mode"     "none")
1325    (set_attr "length"   "0")])
1328 ;; Setting a register from a comparison.
1330 (define_expand "cstoresi4"
1331   [(match_operand:SI 0 "register_operand")
1332    (match_operator 1 "xtensa_cstoresi_operator"
1333     [(match_operand:SI 2 "register_operand")
1334      (match_operand:SI 3 "nonmemory_operand")])]
1335   ""
1337   if (!xtensa_expand_scc (operands, SImode))
1338     FAIL;
1339   DONE;
1342 (define_expand "cstoresf4"
1343   [(match_operand:SI 0 "register_operand")
1344    (match_operator:SI 1 "comparison_operator"
1345     [(match_operand:SF 2 "register_operand")
1346      (match_operand:SF 3 "register_operand")])]
1347   "TARGET_HARD_FLOAT"
1349   if (!xtensa_expand_scc (operands, SFmode))
1350     FAIL;
1351   DONE;
1356 ;; Conditional moves.
1358 (define_expand "movsicc"
1359   [(set (match_operand:SI 0 "register_operand" "")
1360         (if_then_else:SI (match_operand 1 "comparison_operator" "")
1361                          (match_operand:SI 2 "register_operand" "")
1362                          (match_operand:SI 3 "register_operand" "")))]
1363   ""
1365   if (!xtensa_expand_conditional_move (operands, 0))
1366     FAIL;
1367   DONE;
1370 (define_expand "movsfcc"
1371   [(set (match_operand:SF 0 "register_operand" "")
1372         (if_then_else:SF (match_operand 1 "comparison_operator" "")
1373                          (match_operand:SF 2 "register_operand" "")
1374                          (match_operand:SF 3 "register_operand" "")))]
1375   ""
1377   if (!xtensa_expand_conditional_move (operands, 1))
1378     FAIL;
1379   DONE;
1382 (define_insn "movsicc_internal0"
1383   [(set (match_operand:SI 0 "register_operand" "=a,a")
1384         (if_then_else:SI (match_operator 4 "branch_operator"
1385                            [(match_operand:SI 1 "register_operand" "r,r")
1386                             (const_int 0)])
1387                          (match_operand:SI 2 "register_operand" "r,0")
1388                          (match_operand:SI 3 "register_operand" "0,r")))]
1389   ""
1391   return xtensa_emit_movcc (which_alternative == 1, false, false, operands);
1393   [(set_attr "type"     "move,move")
1394    (set_attr "mode"     "SI")
1395    (set_attr "length"   "3,3")])
1397 (define_insn "movsicc_internal1"
1398   [(set (match_operand:SI 0 "register_operand" "=a,a")
1399         (if_then_else:SI (match_operator 4 "boolean_operator"
1400                            [(match_operand:CC 1 "register_operand" "b,b")
1401                             (const_int 0)])
1402                          (match_operand:SI 2 "register_operand" "r,0")
1403                          (match_operand:SI 3 "register_operand" "0,r")))]
1404   "TARGET_BOOLEANS"
1406   return xtensa_emit_movcc (which_alternative == 1, false, true, operands);
1408   [(set_attr "type"     "move,move")
1409    (set_attr "mode"     "SI")
1410    (set_attr "length"   "3,3")])
1412 (define_insn "movsfcc_internal0"
1413   [(set (match_operand:SF 0 "register_operand" "=a,a,f,f")
1414         (if_then_else:SF (match_operator 4 "branch_operator"
1415                            [(match_operand:SI 1 "register_operand" "r,r,r,r")
1416                             (const_int 0)])
1417                          (match_operand:SF 2 "register_operand" "r,0,f,0")
1418                          (match_operand:SF 3 "register_operand" "0,r,0,f")))]
1419   ""
1421   return xtensa_emit_movcc ((which_alternative & 1) == 1,
1422                             which_alternative >= 2, false, operands);
1424   [(set_attr "type"     "move,move,move,move")
1425    (set_attr "mode"     "SF")
1426    (set_attr "length"   "3,3,3,3")])
1428 (define_insn "movsfcc_internal1"
1429   [(set (match_operand:SF 0 "register_operand" "=a,a,f,f")
1430         (if_then_else:SF (match_operator 4 "boolean_operator"
1431                            [(match_operand:CC 1 "register_operand" "b,b,b,b")
1432                             (const_int 0)])
1433                          (match_operand:SF 2 "register_operand" "r,0,f,0")
1434                          (match_operand:SF 3 "register_operand" "0,r,0,f")))]
1435   "TARGET_BOOLEANS"
1437   return xtensa_emit_movcc ((which_alternative & 1) == 1,
1438                             which_alternative >= 2, true, operands);
1440   [(set_attr "type"     "move,move,move,move")
1441    (set_attr "mode"     "SF")
1442    (set_attr "length"   "3,3,3,3")])
1445 ;; Floating-point comparisons.
1447 (define_insn "s<code>_sf"
1448   [(set (match_operand:CC 0 "register_operand" "=b")
1449         (any_scc_sf:CC (match_operand:SF 1 "register_operand" "f")
1450                        (match_operand:SF 2 "register_operand" "f")))]
1451   "TARGET_HARD_FLOAT"
1452   "<scc_sf>.s\t%0, %1, %2"
1453   [(set_attr "type"     "farith")
1454    (set_attr "mode"     "BL")
1455    (set_attr "length"   "3")])
1458 ;; Unconditional branches.
1460 (define_insn "jump"
1461   [(set (pc)
1462         (label_ref (match_operand 0 "" "")))]
1463   ""
1464   "j\t%l0"
1465   [(set_attr "type"     "jump")
1466    (set_attr "mode"     "none")
1467    (set_attr "length"   "3")])
1469 (define_expand "indirect_jump"
1470   [(set (pc)
1471         (match_operand 0 "register_operand" ""))]
1472   ""
1474   rtx dest = operands[0];
1475   if (GET_CODE (dest) != REG || GET_MODE (dest) != Pmode)
1476     operands[0] = copy_to_mode_reg (Pmode, dest);
1478   emit_jump_insn (gen_indirect_jump_internal (dest));
1479   DONE;
1482 (define_insn "indirect_jump_internal"
1483   [(set (pc) (match_operand:SI 0 "register_operand" "r"))]
1484   ""
1485   "jx\t%0"
1486   [(set_attr "type"     "jump")
1487    (set_attr "mode"     "none")
1488    (set_attr "length"   "3")])
1491 (define_expand "tablejump"
1492   [(use (match_operand:SI 0 "register_operand" ""))
1493    (use (label_ref (match_operand 1 "" "")))]
1494    ""
1496   rtx target = operands[0];
1497   if (flag_pic)
1498     {
1499       /* For PIC, the table entry is relative to the start of the table.  */
1500       rtx label = gen_reg_rtx (SImode);
1501       target = gen_reg_rtx (SImode);
1502       emit_move_insn (label, gen_rtx_LABEL_REF (SImode, operands[1]));
1503       emit_insn (gen_addsi3 (target, operands[0], label));
1504     }
1505   emit_jump_insn (gen_tablejump_internal (target, operands[1]));
1506   DONE;
1509 (define_insn "tablejump_internal"
1510   [(set (pc)
1511         (match_operand:SI 0 "register_operand" "r"))
1512    (use (label_ref (match_operand 1 "" "")))]
1513   ""
1514   "jx\t%0"
1515   [(set_attr "type"     "jump")
1516    (set_attr "mode"     "none")
1517    (set_attr "length"   "3")])
1520 ;; Function calls.
1522 (define_expand "sym_PLT"
1523   [(const (unspec [(match_operand:SI 0 "" "")] UNSPEC_PLT))]
1524   ""
1525   "")
1527 (define_expand "call"
1528   [(call (match_operand 0 "memory_operand" "")
1529          (match_operand 1 "" ""))]
1530   ""
1532   rtx addr = XEXP (operands[0], 0);
1533   if (flag_pic && GET_CODE (addr) == SYMBOL_REF
1534       && (!SYMBOL_REF_LOCAL_P (addr) || SYMBOL_REF_EXTERNAL_P (addr)))
1535     addr = gen_sym_PLT (addr);
1536   if (!call_insn_operand (addr, VOIDmode))
1537     XEXP (operands[0], 0) = copy_to_mode_reg (Pmode, addr);
1540 (define_insn "call_internal"
1541   [(call (mem (match_operand:SI 0 "call_insn_operand" "nir"))
1542          (match_operand 1 "" "i"))]
1543   ""
1545   return xtensa_emit_call (0, operands);
1547   [(set_attr "type"     "call")
1548    (set_attr "mode"     "none")
1549    (set_attr "length"   "3")])
1551 (define_expand "call_value"
1552   [(set (match_operand 0 "register_operand" "")
1553         (call (match_operand 1 "memory_operand" "")
1554               (match_operand 2 "" "")))]
1555   ""
1557   rtx addr = XEXP (operands[1], 0);
1558   if (flag_pic && GET_CODE (addr) == SYMBOL_REF
1559       && (!SYMBOL_REF_LOCAL_P (addr) || SYMBOL_REF_EXTERNAL_P (addr)))
1560     addr = gen_sym_PLT (addr);
1561   if (!call_insn_operand (addr, VOIDmode))
1562     XEXP (operands[1], 0) = copy_to_mode_reg (Pmode, addr);
1565 (define_insn "call_value_internal"
1566   [(set (match_operand 0 "register_operand" "=a")
1567         (call (mem (match_operand:SI 1 "call_insn_operand" "nir"))
1568               (match_operand 2 "" "i")))]
1569   ""
1571   return xtensa_emit_call (1, operands);
1573   [(set_attr "type"     "call")
1574    (set_attr "mode"     "none")
1575    (set_attr "length"   "3")])
1577 (define_insn "entry"
1578   [(set (reg:SI A1_REG)
1579         (unspec_volatile:SI [(match_operand:SI 0 "const_int_operand" "i")]
1580                             UNSPECV_ENTRY))]
1581   ""
1582   "entry\tsp, %0"
1583   [(set_attr "type"     "entry")
1584    (set_attr "mode"     "SI")
1585    (set_attr "length"   "3")])
1587 (define_insn "return"
1588   [(return)
1589    (use (reg:SI A0_REG))]
1590   "reload_completed"
1592   return (TARGET_DENSITY ? "retw.n" : "retw");
1594   [(set_attr "type"     "jump")
1595    (set_attr "mode"     "none")
1596    (set_attr "length"   "2")])
1599 ;; Miscellaneous instructions.
1601 (define_expand "prologue"
1602   [(const_int 0)]
1603   ""
1605   xtensa_expand_prologue ();
1606   DONE;
1609 (define_expand "epilogue"
1610   [(return)]
1611   ""
1613   emit_jump_insn (gen_return ());
1614   DONE;
1617 (define_insn "nop"
1618   [(const_int 0)]
1619   ""
1621   return (TARGET_DENSITY ? "nop.n" : "nop");
1623   [(set_attr "type"     "nop")
1624    (set_attr "mode"     "none")
1625    (set_attr "length"   "3")])
1627 (define_expand "nonlocal_goto"
1628   [(match_operand:SI 0 "general_operand" "")
1629    (match_operand:SI 1 "general_operand" "")
1630    (match_operand:SI 2 "general_operand" "")
1631    (match_operand:SI 3 "" "")]
1632   ""
1634   xtensa_expand_nonlocal_goto (operands);
1635   DONE;
1638 ;; Stuff an address into the return address register along with the window
1639 ;; size in the high bits.  Because we don't have the window size of the
1640 ;; previous frame, assume the function called out with a CALL8 since that
1641 ;; is what compilers always use.  Note: __builtin_frob_return_addr has
1642 ;; already been applied to the handler, but the generic version doesn't
1643 ;; allow us to frob it quite enough, so we just frob here.
1645 (define_insn_and_split "eh_return"
1646   [(set (reg:SI A0_REG)
1647         (unspec_volatile:SI [(match_operand:SI 0 "register_operand" "r")]
1648                             UNSPECV_EH_RETURN))
1649    (clobber (match_scratch:SI 1 "=r"))]
1650   ""
1651   "#"
1652   "reload_completed"
1653   [(set (match_dup 1) (ashift:SI (match_dup 0) (const_int 2)))
1654    (set (match_dup 1) (plus:SI (match_dup 1) (const_int 2)))
1655    (set (reg:SI A0_REG) (rotatert:SI (match_dup 1) (const_int 2)))]
1656   "")
1658 ;; Setting up a frame pointer is tricky for Xtensa because GCC doesn't
1659 ;; know if a frame pointer is required until the reload pass, and
1660 ;; because there may be an incoming argument value in the hard frame
1661 ;; pointer register (a7).  If there is an incoming argument in that
1662 ;; register, the "set_frame_ptr" insn gets inserted immediately after
1663 ;; the insn that copies the incoming argument to a pseudo or to the
1664 ;; stack.  This serves several purposes here: (1) it keeps the
1665 ;; optimizer from copy-propagating or scheduling the use of a7 as an
1666 ;; incoming argument away from the beginning of the function; (2) we
1667 ;; can use a post-reload splitter to expand away the insn if a frame
1668 ;; pointer is not required, so that the post-reload scheduler can do
1669 ;; the right thing; and (3) it makes it easy for the prologue expander
1670 ;; to search for this insn to determine whether it should add a new insn
1671 ;; to set up the frame pointer.
1673 (define_insn "set_frame_ptr"
1674   [(set (reg:SI A7_REG) (unspec_volatile:SI [(const_int 0)] UNSPECV_SET_FP))]
1675   ""
1677   if (frame_pointer_needed)
1678     return "mov\ta7, sp";
1679   return "";
1681   [(set_attr "type"     "move")
1682    (set_attr "mode"     "SI")
1683    (set_attr "length"   "3")])
1685 ;; Post-reload splitter to remove fp assignment when it's not needed.
1686 (define_split
1687   [(set (reg:SI A7_REG) (unspec_volatile:SI [(const_int 0)] UNSPECV_SET_FP))]
1688   "reload_completed && !frame_pointer_needed"
1689   [(unspec [(const_int 0)] UNSPEC_NOP)]
1690   "")
1692 ;; The preceding splitter needs something to split the insn into;
1693 ;; things start breaking if the result is just a "use" so instead we
1694 ;; generate the following insn.
1695 (define_insn "*unspec_nop"
1696   [(unspec [(const_int 0)] UNSPEC_NOP)]
1697   ""
1698   ""
1699   [(set_attr "type"     "nop")
1700    (set_attr "mode"     "none")
1701    (set_attr "length"   "0")])
1704 ;; TLS support
1706 (define_expand "sym_TPOFF"
1707   [(const (unspec [(match_operand:SI 0 "" "")] UNSPEC_TPOFF))]
1708   ""
1709   "")
1711 (define_expand "sym_DTPOFF"
1712   [(const (unspec [(match_operand:SI 0 "" "")] UNSPEC_DTPOFF))]
1713   ""
1714   "")
1716 (define_insn "get_thread_pointersi"
1717   [(set (match_operand:SI 0 "register_operand" "=a")
1718         (unspec:SI [(const_int 0)] UNSPEC_TP))]
1719   "TARGET_THREADPTR"
1720   "rur\t%0, THREADPTR"
1721   [(set_attr "type"     "rsr")
1722    (set_attr "mode"     "SI")
1723    (set_attr "length"   "3")])
1725 (define_insn "set_thread_pointersi"
1726   [(unspec_volatile [(match_operand:SI 0 "register_operand" "r")]
1727                     UNSPECV_SET_TP)]
1728   "TARGET_THREADPTR"
1729   "wur\t%0, THREADPTR"
1730   [(set_attr "type"     "wsr")
1731    (set_attr "mode"     "SI")
1732    (set_attr "length"   "3")])
1734 (define_insn "tls_func"
1735   [(set (match_operand:SI 0 "register_operand" "=a")
1736         (unspec:SI [(match_operand:SI 1 "tls_symbol_operand" "")]
1737                    UNSPEC_TLS_FUNC))]
1738   "TARGET_THREADPTR && HAVE_AS_TLS"
1739   "movi\t%0, %1@TLSFUNC"
1740   [(set_attr "type"     "load")
1741    (set_attr "mode"     "SI")
1742    (set_attr "length"   "3")])
1744 (define_insn "tls_arg"
1745   [(set (match_operand:SI 0 "register_operand" "=a")
1746         (unspec:SI [(match_operand:SI 1 "tls_symbol_operand" "")]
1747                    UNSPEC_TLS_ARG))]
1748   "TARGET_THREADPTR && HAVE_AS_TLS"
1749   "movi\t%0, %1@TLSARG"
1750   [(set_attr "type"     "load")
1751    (set_attr "mode"     "SI")
1752    (set_attr "length"   "3")])
1754 (define_insn "tls_call"
1755   [(set (match_operand:SI 0 "register_operand" "=a")
1756         (call (mem:SI (unspec:SI [(match_operand:SI 1 "register_operand" "r")
1757                                   (match_operand:SI 2 "tls_symbol_operand" "")]
1758                                   UNSPEC_TLS_CALL))
1759               (match_operand 3 "" "i")))]
1760   "TARGET_THREADPTR && HAVE_AS_TLS"
1761   "callx8.tls %1, %2@TLSCALL"
1762   [(set_attr "type"     "call")
1763    (set_attr "mode"     "none")
1764    (set_attr "length"   "3")])
1767 ;; Instructions for the Xtensa "boolean" option.
1769 (define_insn "*booltrue"
1770   [(set (pc)
1771         (if_then_else (match_operator 2 "boolean_operator"
1772                          [(match_operand:CC 0 "register_operand" "b")
1773                           (const_int 0)])
1774                       (label_ref (match_operand 1 "" ""))
1775                       (pc)))]
1776   "TARGET_BOOLEANS"
1778   if (GET_CODE (operands[2]) == EQ)
1779     return "bf\t%0, %1";
1780   else
1781     return "bt\t%0, %1";
1783   [(set_attr "type"     "jump")
1784    (set_attr "mode"     "none")
1785    (set_attr "length"   "3")])
1787 (define_insn "*boolfalse"
1788   [(set (pc)
1789         (if_then_else (match_operator 2 "boolean_operator"
1790                          [(match_operand:CC 0 "register_operand" "b")
1791                           (const_int 0)])
1792                       (pc)
1793                       (label_ref (match_operand 1 "" ""))))]
1794   "TARGET_BOOLEANS"
1796   if (GET_CODE (operands[2]) == EQ)
1797     return "bt\t%0, %1";
1798   else
1799     return "bf\t%0, %1";
1801   [(set_attr "type"     "jump")
1802    (set_attr "mode"     "none")
1803    (set_attr "length"   "3")])
1806 ;; Atomic operations
1808 (define_expand "memory_barrier"
1809   [(set (match_dup 0)
1810         (unspec:BLK [(match_dup 0)] UNSPEC_MEMW))]
1811   ""
1813   operands[0] = gen_rtx_MEM (BLKmode, gen_rtx_SCRATCH (Pmode));
1814   MEM_VOLATILE_P (operands[0]) = 1;
1817 (define_insn "*memory_barrier"
1818   [(set (match_operand:BLK 0 "" "")
1819         (unspec:BLK [(match_dup 0)] UNSPEC_MEMW))]
1820   ""
1821   "memw"
1822   [(set_attr "type"     "unknown")
1823    (set_attr "mode"     "none")
1824    (set_attr "length"   "3")])
1826 ;; sync_lock_release is only implemented for SImode.
1827 ;; For other modes, just use the default of a store with a memory_barrier.
1828 (define_insn "sync_lock_releasesi"
1829   [(set (match_operand:SI 0 "mem_operand" "=U")
1830         (unspec_volatile:SI
1831           [(match_operand:SI 1 "register_operand" "r")]
1832           UNSPECV_S32RI))]
1833   "TARGET_RELEASE_SYNC"
1834   "s32ri\t%1, %0"
1835   [(set_attr "type"     "store")
1836    (set_attr "mode"     "SI")
1837    (set_attr "length"   "3")])
1839 (define_insn "sync_compare_and_swapsi"
1840   [(parallel
1841     [(set (match_operand:SI 0 "register_operand" "=a")
1842           (match_operand:SI 1 "mem_operand" "+U"))
1843      (set (match_dup 1)
1844           (unspec_volatile:SI
1845             [(match_dup 1)
1846              (match_operand:SI 2 "register_operand" "r")
1847              (match_operand:SI 3 "register_operand" "0")]
1848             UNSPECV_S32C1I))])]
1849   "TARGET_S32C1I"
1850   "wsr\t%2, SCOMPARE1\;s32c1i\t%3, %1"
1851   [(set_attr "type"     "multi")
1852    (set_attr "mode"     "SI")
1853    (set_attr "length"   "6")])
1855 (define_expand "sync_compare_and_swap<mode>"
1856   [(parallel
1857     [(set (match_operand:HQI 0 "register_operand" "")
1858           (match_operand:HQI 1 "mem_operand" ""))
1859      (set (match_dup 1)
1860           (unspec_volatile:HQI
1861             [(match_dup 1)
1862              (match_operand:HQI 2 "register_operand" "")
1863              (match_operand:HQI 3 "register_operand" "")]
1864             UNSPECV_S32C1I))])]
1865   "TARGET_S32C1I"
1867   xtensa_expand_compare_and_swap (operands[0], operands[1],
1868                                   operands[2], operands[3]);
1869   DONE;
1872 (define_expand "sync_lock_test_and_set<mode>"
1873   [(match_operand:HQI 0 "register_operand")
1874    (match_operand:HQI 1 "memory_operand")
1875    (match_operand:HQI 2 "register_operand")]
1876   "TARGET_S32C1I"
1878   xtensa_expand_atomic (SET, operands[0], operands[1], operands[2], false);
1879   DONE;
1882 (define_expand "sync_<atomic><mode>"
1883   [(set (match_operand:HQI 0 "memory_operand")
1884         (ATOMIC:HQI (match_dup 0)
1885                     (match_operand:HQI 1 "register_operand")))]
1886   "TARGET_S32C1I"
1888   xtensa_expand_atomic (<CODE>, NULL_RTX, operands[0], operands[1], false);
1889   DONE;
1892 (define_expand "sync_old_<atomic><mode>"
1893   [(set (match_operand:HQI 0 "register_operand")
1894         (match_operand:HQI 1 "memory_operand"))
1895    (set (match_dup 1)
1896         (ATOMIC:HQI (match_dup 1)
1897                     (match_operand:HQI 2 "register_operand")))]
1898   "TARGET_S32C1I"
1900   xtensa_expand_atomic (<CODE>, operands[0], operands[1], operands[2], false);
1901   DONE;
1904 (define_expand "sync_new_<atomic><mode>"
1905   [(set (match_operand:HQI 0 "register_operand")
1906         (ATOMIC:HQI (match_operand:HQI 1 "memory_operand")
1907                     (match_operand:HQI 2 "register_operand"))) 
1908    (set (match_dup 1) (ATOMIC:HQI (match_dup 1) (match_dup 2)))]
1909   "TARGET_S32C1I"
1911   xtensa_expand_atomic (<CODE>, operands[0], operands[1], operands[2], true);
1912   DONE;