* gcc-interface/trans.c (process_freeze_entity): Be prepared for a
[official-gcc.git] / gcc / config / xtensa / xtensa.md
blobd5596e25d8287d0c140c5b4e3f5ee555d85ba483
1 ;; GCC machine description for Tensilica's Xtensa architecture.
2 ;; Copyright (C) 2001-2017 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)
27   (A9_REG               9)
29   (UNSPEC_NOP           2)
30   (UNSPEC_PLT           3)
31   (UNSPEC_RET_ADDR      4)
32   (UNSPEC_TPOFF         5)
33   (UNSPEC_DTPOFF        6)
34   (UNSPEC_TLS_FUNC      7)
35   (UNSPEC_TLS_ARG       8)
36   (UNSPEC_TLS_CALL      9)
37   (UNSPEC_TP            10)
38   (UNSPEC_MEMW          11)
39   (UNSPEC_LSETUP_START  12)
40   (UNSPEC_LSETUP_END    13)
42   (UNSPECV_SET_FP       1)
43   (UNSPECV_ENTRY        2)
44   (UNSPECV_S32RI        4)
45   (UNSPECV_S32C1I       5)
46   (UNSPECV_EH_RETURN    6)
47   (UNSPECV_SET_TP       7)
48   (UNSPECV_BLOCKAGE     8)
51 ;; This code iterator allows signed and unsigned widening multiplications
52 ;; to use the same template.
53 (define_code_iterator any_extend [sign_extend zero_extend])
55 ;; <u> expands to an empty string when doing a signed operation and
56 ;; "u" when doing an unsigned operation.
57 (define_code_attr u [(sign_extend "") (zero_extend "u")])
59 ;; <su> is like <u>, but the signed form expands to "s" rather than "".
60 (define_code_attr su [(sign_extend "s") (zero_extend "u")])
62 ;; This code iterator allows four integer min/max operations to be
63 ;; generated from one template.
64 (define_code_iterator any_minmax [smin umin smax umax])
66 ;; <minmax> expands to the opcode name for any_minmax operations.
67 (define_code_attr minmax [(smin "min") (umin "minu")
68                           (smax "max") (umax "maxu")])
70 ;; This code iterator is for floating-point comparisons.
71 (define_code_iterator any_scc_sf [eq lt le uneq unlt unle unordered])
72 (define_code_attr scc_sf [(eq "oeq") (lt "olt") (le "ole") 
73                           (uneq "ueq") (unlt "ult") (unle "ule")
74                           (unordered "un")])
76 ;; This iterator and attribute allow to combine most atomic operations.
77 (define_code_iterator ATOMIC [and ior xor plus minus mult])
78 (define_code_attr atomic [(and "and") (ior "ior") (xor "xor") 
79                           (plus "add") (minus "sub") (mult "nand")])
81 ;; This mode iterator allows the HI and QI patterns to be defined from
82 ;; the same template.
83 (define_mode_iterator HQI [HI QI])
86 ;; Attributes.
88 (define_attr "type"
89   "unknown,jump,call,load,store,move,arith,multi,nop,farith,fmadd,fconv,fload,fstore,mul16,mul32,div32,mac16,rsr,wsr,entry,trap"
90   (const_string "unknown"))
92 (define_attr "mode"
93   "unknown,none,QI,HI,SI,DI,SF,DF,BL"
94   (const_string "unknown"))
96 (define_attr "length" "" (const_int 1))
98 ;; Describe a user's asm statement.
99 (define_asm_attributes
100   [(set_attr "type" "multi")])
103 ;; Pipeline model.
105 ;; The Xtensa basically has simple 5-stage RISC pipeline.
106 ;; Most instructions complete in 1 cycle, and it is OK to assume that
107 ;; everything is fully pipelined.  The exceptions have special insn
108 ;; reservations in the pipeline description below.  The Xtensa can
109 ;; issue one instruction per cycle, so defining CPU units is unnecessary.
111 (define_insn_reservation "xtensa_any_insn" 1
112                          (eq_attr "type" "!load,fload,rsr,mul16,mul32,fmadd,fconv")
113                          "nothing")
115 (define_insn_reservation "xtensa_memory" 2
116                          (eq_attr "type" "load,fload")
117                          "nothing")
119 (define_insn_reservation "xtensa_sreg" 2
120                          (eq_attr "type" "rsr")
121                          "nothing")
123 (define_insn_reservation "xtensa_mul16" 2
124                          (eq_attr "type" "mul16")
125                          "nothing")
127 (define_insn_reservation "xtensa_mul32" 2
128                          (eq_attr "type" "mul32")
129                          "nothing")
131 (define_insn_reservation "xtensa_fmadd" 4
132                          (eq_attr "type" "fmadd")
133                          "nothing")
135 (define_insn_reservation "xtensa_fconv" 2
136                          (eq_attr "type" "fconv")
137                          "nothing")
139 ;; Include predicates and constraints.
141 (include "predicates.md")
142 (include "constraints.md")
145 ;; Addition.
147 (define_insn "addsi3"
148   [(set (match_operand:SI 0 "register_operand" "=D,D,a,a,a")
149         (plus:SI (match_operand:SI 1 "register_operand" "%d,d,r,r,r")
150                  (match_operand:SI 2 "add_operand" "d,O,r,J,N")))]
151   ""
152   "@
153    add.n\t%0, %1, %2
154    addi.n\t%0, %1, %d2
155    add\t%0, %1, %2
156    addi\t%0, %1, %d2
157    addmi\t%0, %1, %x2"
158   [(set_attr "type"     "arith,arith,arith,arith,arith")
159    (set_attr "mode"     "SI")
160    (set_attr "length"   "2,2,3,3,3")])
162 (define_insn "*addx"
163   [(set (match_operand:SI 0 "register_operand" "=a")
164         (plus:SI (mult:SI (match_operand:SI 1 "register_operand" "r")
165                           (match_operand:SI 3 "addsubx_operand" "i"))
166                  (match_operand:SI 2 "register_operand" "r")))]
167   "TARGET_ADDX"
168   "addx%3\t%0, %1, %2"
169   [(set_attr "type"     "arith")
170    (set_attr "mode"     "SI")
171    (set_attr "length"   "3")])
173 (define_insn "addsf3"
174   [(set (match_operand:SF 0 "register_operand" "=f")
175         (plus:SF (match_operand:SF 1 "register_operand" "%f")
176                  (match_operand:SF 2 "register_operand" "f")))]
177   "TARGET_HARD_FLOAT"
178   "add.s\t%0, %1, %2"
179   [(set_attr "type"     "fmadd")
180    (set_attr "mode"     "SF")
181    (set_attr "length"   "3")])
184 ;; Subtraction.
186 (define_insn "subsi3"
187   [(set (match_operand:SI 0 "register_operand" "=a")
188         (minus:SI (match_operand:SI 1 "register_operand" "r")
189                   (match_operand:SI 2 "register_operand" "r")))]
190   ""
191   "sub\t%0, %1, %2"
192   [(set_attr "type"     "arith")
193    (set_attr "mode"     "SI")
194    (set_attr "length"   "3")])
196 (define_insn "*subx"
197   [(set (match_operand:SI 0 "register_operand" "=a")
198         (minus:SI (mult:SI (match_operand:SI 1 "register_operand" "r")
199                            (match_operand:SI 3 "addsubx_operand" "i"))
200                   (match_operand:SI 2 "register_operand" "r")))]
201   "TARGET_ADDX"
202   "subx%3\t%0, %1, %2"
203   [(set_attr "type"     "arith")
204    (set_attr "mode"     "SI")
205    (set_attr "length"   "3")])
207 (define_insn "subsf3"
208   [(set (match_operand:SF 0 "register_operand" "=f")
209         (minus:SF (match_operand:SF 1 "register_operand" "f")
210                   (match_operand:SF 2 "register_operand" "f")))]
211   "TARGET_HARD_FLOAT"
212   "sub.s\t%0, %1, %2"
213   [(set_attr "type"     "fmadd")
214    (set_attr "mode"     "SF")
215    (set_attr "length"   "3")])
218 ;; Multiplication.
220 (define_expand "<u>mulsidi3"
221   [(set (match_operand:DI 0 "register_operand")
222         (mult:DI (any_extend:DI (match_operand:SI 1 "register_operand"))
223                  (any_extend:DI (match_operand:SI 2 "register_operand"))))]
224   "TARGET_MUL32_HIGH"
226   rtx temp = gen_reg_rtx (SImode);
227   emit_insn (gen_mulsi3 (temp, operands[1], operands[2]));
228   emit_insn (gen_<u>mulsi3_highpart (gen_highpart (SImode, operands[0]),
229                                      operands[1], operands[2]));
230   emit_insn (gen_movsi (gen_lowpart (SImode, operands[0]), temp));
231   DONE;
234 (define_insn "<u>mulsi3_highpart"
235   [(set (match_operand:SI 0 "register_operand" "=a")
236         (truncate:SI
237          (lshiftrt:DI
238           (mult:DI (any_extend:DI (match_operand:SI 1 "register_operand" "%r"))
239                    (any_extend:DI (match_operand:SI 2 "register_operand" "r")))
240           (const_int 32))))]
241   "TARGET_MUL32_HIGH"
242   "mul<su>h\t%0, %1, %2"
243   [(set_attr "type"     "mul32")
244    (set_attr "mode"     "SI")
245    (set_attr "length"   "3")])
247 (define_insn "mulsi3"
248   [(set (match_operand:SI 0 "register_operand" "=a")
249         (mult:SI (match_operand:SI 1 "register_operand" "%r")
250                  (match_operand:SI 2 "register_operand" "r")))]
251   "TARGET_MUL32"
252   "mull\t%0, %1, %2"
253   [(set_attr "type"     "mul32")
254    (set_attr "mode"     "SI")
255    (set_attr "length"   "3")])
257 (define_insn "mulhisi3"
258   [(set (match_operand:SI 0 "register_operand" "=C,A")
259         (mult:SI (sign_extend:SI
260                   (match_operand:HI 1 "register_operand" "%r,r"))
261                  (sign_extend:SI
262                   (match_operand:HI 2 "register_operand" "r,r"))))]
263   "TARGET_MUL16 || TARGET_MAC16"
264   "@
265    mul16s\t%0, %1, %2
266    mul.aa.ll\t%1, %2"
267   [(set_attr "type"     "mul16,mac16")
268    (set_attr "mode"     "SI")
269    (set_attr "length"   "3,3")])
271 (define_insn "umulhisi3"
272   [(set (match_operand:SI 0 "register_operand" "=C,A")
273         (mult:SI (zero_extend:SI
274                   (match_operand:HI 1 "register_operand" "%r,r"))
275                  (zero_extend:SI
276                   (match_operand:HI 2 "register_operand" "r,r"))))]
277   "TARGET_MUL16 || TARGET_MAC16"
278   "@
279    mul16u\t%0, %1, %2
280    umul.aa.ll\t%1, %2"
281   [(set_attr "type"     "mul16,mac16")
282    (set_attr "mode"     "SI")
283    (set_attr "length"   "3,3")])
285 (define_insn "muladdhisi"
286   [(set (match_operand:SI 0 "register_operand" "=A")
287         (plus:SI (mult:SI (sign_extend:SI
288                            (match_operand:HI 1 "register_operand" "%r"))
289                           (sign_extend:SI
290                            (match_operand:HI 2 "register_operand" "r")))
291                  (match_operand:SI 3 "register_operand" "0")))]
292   "TARGET_MAC16"
293   "mula.aa.ll\t%1, %2"
294   [(set_attr "type"     "mac16")
295    (set_attr "mode"     "SI")
296    (set_attr "length"   "3")])
298 (define_insn "mulsubhisi"
299   [(set (match_operand:SI 0 "register_operand" "=A")
300         (minus:SI (match_operand:SI 1 "register_operand" "0")
301                   (mult:SI (sign_extend:SI
302                             (match_operand:HI 2 "register_operand" "%r"))
303                            (sign_extend:SI
304                             (match_operand:HI 3 "register_operand" "r")))))]
305   "TARGET_MAC16"
306   "muls.aa.ll\t%2, %3"
307   [(set_attr "type"     "mac16")
308    (set_attr "mode"     "SI")
309    (set_attr "length"   "3")])
311 (define_insn "mulsf3"
312   [(set (match_operand:SF 0 "register_operand" "=f")
313         (mult:SF (match_operand:SF 1 "register_operand" "%f")
314                  (match_operand:SF 2 "register_operand" "f")))]
315   "TARGET_HARD_FLOAT"
316   "mul.s\t%0, %1, %2"
317   [(set_attr "type"     "fmadd")
318    (set_attr "mode"     "SF")
319    (set_attr "length"   "3")])
321 (define_insn "fmasf4"
322   [(set (match_operand:SF 0 "register_operand" "=f")
323         (fma:SF (match_operand:SF 1 "register_operand" "f")
324                 (match_operand:SF 2 "register_operand" "f")
325                 (match_operand:SF 3 "register_operand" "0")))]
326   "TARGET_HARD_FLOAT"
327   "madd.s\t%0, %1, %2"
328   [(set_attr "type"     "fmadd")
329    (set_attr "mode"     "SF")
330    (set_attr "length"   "3")])
332 ;; Note that (C - A*B) = (-A*B + C)
333 (define_insn "fnmasf4"
334   [(set (match_operand:SF 0 "register_operand" "=f")
335         (fma:SF (neg:SF (match_operand:SF 1 "register_operand" "f"))
336                 (match_operand:SF 2 "register_operand" "f")
337                 (match_operand:SF 3 "register_operand" "0")))]
338   "TARGET_HARD_FLOAT"
339   "msub.s\t%0, %1, %2"
340   [(set_attr "type"     "fmadd")
341    (set_attr "mode"     "SF")
342    (set_attr "length"   "3")])
345 ;; Division.
347 (define_insn "divsi3"
348   [(set (match_operand:SI 0 "register_operand" "=a")
349         (div:SI (match_operand:SI 1 "register_operand" "r")
350                 (match_operand:SI 2 "register_operand" "r")))]
351   "TARGET_DIV32"
352   "quos\t%0, %1, %2"
353   [(set_attr "type"     "div32")
354    (set_attr "mode"     "SI")
355    (set_attr "length"   "3")])
357 (define_insn "udivsi3"
358   [(set (match_operand:SI 0 "register_operand" "=a")
359         (udiv:SI (match_operand:SI 1 "register_operand" "r")
360                  (match_operand:SI 2 "register_operand" "r")))]
361   "TARGET_DIV32"
362   "quou\t%0, %1, %2"
363   [(set_attr "type"     "div32")
364    (set_attr "mode"     "SI")
365    (set_attr "length"   "3")])
368 ;; Remainders.
370 (define_insn "modsi3"
371   [(set (match_operand:SI 0 "register_operand" "=a")
372         (mod:SI (match_operand:SI 1 "register_operand" "r")
373                 (match_operand:SI 2 "register_operand" "r")))]
374   "TARGET_DIV32"
375   "rems\t%0, %1, %2"
376   [(set_attr "type"     "div32")
377    (set_attr "mode"     "SI")
378    (set_attr "length"   "3")])
380 (define_insn "umodsi3"
381   [(set (match_operand:SI 0 "register_operand" "=a")
382         (umod:SI (match_operand:SI 1 "register_operand" "r")
383                  (match_operand:SI 2 "register_operand" "r")))]
384   "TARGET_DIV32"
385   "remu\t%0, %1, %2"
386   [(set_attr "type"     "div32")
387    (set_attr "mode"     "SI")
388    (set_attr "length"   "3")])
391 ;; Absolute value.
393 (define_insn "abssi2"
394   [(set (match_operand:SI 0 "register_operand" "=a")
395         (abs:SI (match_operand:SI 1 "register_operand" "r")))]
396   "TARGET_ABS"
397   "abs\t%0, %1"
398   [(set_attr "type"     "arith")
399    (set_attr "mode"     "SI")
400    (set_attr "length"   "3")])
402 (define_insn "abssf2"
403   [(set (match_operand:SF 0 "register_operand" "=f")
404         (abs:SF (match_operand:SF 1 "register_operand" "f")))]
405   "TARGET_HARD_FLOAT"
406   "abs.s\t%0, %1"
407   [(set_attr "type"     "farith")
408    (set_attr "mode"     "SF")
409    (set_attr "length"   "3")])
412 ;; Min and max.
414 (define_insn "<code>si3"
415   [(set (match_operand:SI 0 "register_operand" "=a")
416         (any_minmax:SI (match_operand:SI 1 "register_operand" "%r")
417                        (match_operand:SI 2 "register_operand" "r")))]
418   "TARGET_MINMAX"
419   "<minmax>\t%0, %1, %2"
420   [(set_attr "type"     "arith")
421    (set_attr "mode"     "SI")
422    (set_attr "length"   "3")])
425 ;; Count leading/trailing zeros and find first bit.
427 (define_insn "clzsi2"
428   [(set (match_operand:SI 0 "register_operand" "=a")
429         (clz:SI (match_operand:SI 1 "register_operand" "r")))]
430   "TARGET_NSA"
431   "nsau\t%0, %1"
432   [(set_attr "type"     "arith")
433    (set_attr "mode"     "SI")
434    (set_attr "length"   "3")])
436 (define_expand "ctzsi2"
437   [(set (match_operand:SI 0 "register_operand" "")
438         (ctz:SI (match_operand:SI 1 "register_operand" "")))]
439   "TARGET_NSA"
441   rtx temp = gen_reg_rtx (SImode);
442   emit_insn (gen_negsi2 (temp, operands[1]));
443   emit_insn (gen_andsi3 (temp, temp, operands[1]));
444   emit_insn (gen_clzsi2 (temp, temp));
445   emit_insn (gen_negsi2 (temp, temp));
446   emit_insn (gen_addsi3 (operands[0], temp, GEN_INT (31)));
447   DONE;
450 (define_expand "ffssi2"
451   [(set (match_operand:SI 0 "register_operand" "")
452         (ffs:SI (match_operand:SI 1 "register_operand" "")))]
453   "TARGET_NSA"
455   rtx temp = gen_reg_rtx (SImode);
456   emit_insn (gen_negsi2 (temp, operands[1]));
457   emit_insn (gen_andsi3 (temp, temp, operands[1]));
458   emit_insn (gen_clzsi2 (temp, temp));
459   emit_insn (gen_negsi2 (temp, temp));
460   emit_insn (gen_addsi3 (operands[0], temp, GEN_INT (32)));
461   DONE;
465 ;; Negation and one's complement.
467 (define_insn "negsi2"
468   [(set (match_operand:SI 0 "register_operand" "=a")
469         (neg:SI (match_operand:SI 1 "register_operand" "r")))]
470   ""
471   "neg\t%0, %1"
472   [(set_attr "type"     "arith")
473    (set_attr "mode"     "SI")
474    (set_attr "length"   "3")])
476 (define_expand "one_cmplsi2"
477   [(set (match_operand:SI 0 "register_operand" "")
478         (not:SI (match_operand:SI 1 "register_operand" "")))]
479   ""
481   rtx temp = gen_reg_rtx (SImode);
482   emit_insn (gen_movsi (temp, constm1_rtx));
483   emit_insn (gen_xorsi3 (operands[0], temp, operands[1]));
484   DONE;
487 (define_insn "negsf2"
488   [(set (match_operand:SF 0 "register_operand" "=f")
489         (neg:SF (match_operand:SF 1 "register_operand" "f")))]
490   "TARGET_HARD_FLOAT"
491   "neg.s\t%0, %1"
492   [(set_attr "type"     "farith")
493    (set_attr "mode"     "SF")
494    (set_attr "length"   "3")])
497 ;; Logical instructions.
499 (define_insn "andsi3"
500   [(set (match_operand:SI 0 "register_operand" "=a,a")
501         (and:SI (match_operand:SI 1 "register_operand" "%r,r")
502                 (match_operand:SI 2 "mask_operand" "P,r")))]
503   ""
504   "@
505    extui\t%0, %1, 0, %K2
506    and\t%0, %1, %2"
507   [(set_attr "type"     "arith,arith")
508    (set_attr "mode"     "SI")
509    (set_attr "length"   "3,3")])
511 (define_insn "iorsi3"
512   [(set (match_operand:SI 0 "register_operand" "=a")
513         (ior:SI (match_operand:SI 1 "register_operand" "%r")
514                 (match_operand:SI 2 "register_operand" "r")))]
515   ""
516   "or\t%0, %1, %2"
517   [(set_attr "type"     "arith")
518    (set_attr "mode"     "SI")
519    (set_attr "length"   "3")])
521 (define_insn "xorsi3"
522   [(set (match_operand:SI 0 "register_operand" "=a")
523         (xor:SI (match_operand:SI 1 "register_operand" "%r")
524                 (match_operand:SI 2 "register_operand" "r")))]
525   ""
526   "xor\t%0, %1, %2"
527   [(set_attr "type"     "arith")
528    (set_attr "mode"     "SI")
529    (set_attr "length"   "3")])
532 ;; Zero-extend instructions.
534 (define_insn "zero_extendhisi2"
535   [(set (match_operand:SI 0 "register_operand" "=a,a")
536         (zero_extend:SI (match_operand:HI 1 "nonimmed_operand" "r,U")))]
537   ""
538   "@
539    extui\t%0, %1, 0, 16
540    l16ui\t%0, %1"
541   [(set_attr "type"     "arith,load")
542    (set_attr "mode"     "SI")
543    (set_attr "length"   "3,3")])
545 (define_insn "zero_extendqisi2"
546   [(set (match_operand:SI 0 "register_operand" "=a,a")
547         (zero_extend:SI (match_operand:QI 1 "nonimmed_operand" "r,U")))]
548   ""
549   "@
550    extui\t%0, %1, 0, 8
551    l8ui\t%0, %1"
552   [(set_attr "type"     "arith,load")
553    (set_attr "mode"     "SI")
554    (set_attr "length"   "3,3")])
557 ;; Sign-extend instructions.
559 (define_expand "extendhisi2"
560   [(set (match_operand:SI 0 "register_operand" "")
561         (sign_extend:SI (match_operand:HI 1 "register_operand" "")))]
562   ""
564   if (sext_operand (operands[1], HImode))
565     emit_insn (gen_extendhisi2_internal (operands[0], operands[1]));
566   else
567     xtensa_extend_reg (operands[0], operands[1]);
568   DONE;
571 (define_insn "extendhisi2_internal"
572   [(set (match_operand:SI 0 "register_operand" "=B,a")
573         (sign_extend:SI (match_operand:HI 1 "sext_operand" "r,U")))]
574   ""
575   "@
576    sext\t%0, %1, 15
577    l16si\t%0, %1"
578   [(set_attr "type"     "arith,load")
579    (set_attr "mode"     "SI")
580    (set_attr "length"   "3,3")])
582 (define_expand "extendqisi2"
583   [(set (match_operand:SI 0 "register_operand" "")
584         (sign_extend:SI (match_operand:QI 1 "register_operand" "")))]
585   ""
587   if (TARGET_SEXT)
588     emit_insn (gen_extendqisi2_internal (operands[0], operands[1]));
589   else
590     xtensa_extend_reg (operands[0], operands[1]);
591   DONE;
594 (define_insn "extendqisi2_internal"
595   [(set (match_operand:SI 0 "register_operand" "=B")
596         (sign_extend:SI (match_operand:QI 1 "register_operand" "r")))]
597   "TARGET_SEXT"
598   "sext\t%0, %1, 7"
599   [(set_attr "type"     "arith")
600    (set_attr "mode"     "SI")
601    (set_attr "length"   "3")])
604 ;; Field extract instructions.
606 (define_expand "extv"
607   [(set (match_operand:SI 0 "register_operand" "")
608         (sign_extract:SI (match_operand:SI 1 "register_operand" "")
609                          (match_operand:SI 2 "const_int_operand" "")
610                          (match_operand:SI 3 "const_int_operand" "")))]
611   "TARGET_SEXT"
613   if (!sext_fldsz_operand (operands[2], SImode))
614     FAIL;
616   /* We could expand to a right shift followed by SEXT but that's
617      no better than the standard left and right shift sequence.  */
618   if (!lsbitnum_operand (operands[3], SImode))
619     FAIL;
621   emit_insn (gen_extv_internal (operands[0], operands[1],
622                                 operands[2], operands[3]));
623   DONE;
626 (define_insn "extv_internal"
627   [(set (match_operand:SI 0 "register_operand" "=a")
628         (sign_extract:SI (match_operand:SI 1 "register_operand" "r")
629                          (match_operand:SI 2 "sext_fldsz_operand" "i")
630                          (match_operand:SI 3 "lsbitnum_operand" "i")))]
631   "TARGET_SEXT"
633   int fldsz = INTVAL (operands[2]);
634   operands[2] = GEN_INT (fldsz - 1);
635   return "sext\t%0, %1, %2";
637   [(set_attr "type"     "arith")
638    (set_attr "mode"     "SI")
639    (set_attr "length"   "3")])
641 (define_expand "extzv"
642   [(set (match_operand:SI 0 "register_operand" "")
643         (zero_extract:SI (match_operand:SI 1 "register_operand" "")
644                          (match_operand:SI 2 "const_int_operand" "")
645                          (match_operand:SI 3 "const_int_operand" "")))]
646   ""
648   if (!extui_fldsz_operand (operands[2], SImode))
649     FAIL;
650   emit_insn (gen_extzv_internal (operands[0], operands[1],
651                                  operands[2], operands[3]));
652   DONE;
655 (define_insn "extzv_internal"
656   [(set (match_operand:SI 0 "register_operand" "=a")
657         (zero_extract:SI (match_operand:SI 1 "register_operand" "r")
658                          (match_operand:SI 2 "extui_fldsz_operand" "i")
659                          (match_operand:SI 3 "const_int_operand" "i")))]
660   ""
662   int shift;
663   if (BITS_BIG_ENDIAN)
664     shift = (32 - (INTVAL (operands[2]) + INTVAL (operands[3]))) & 0x1f;
665   else
666     shift = INTVAL (operands[3]) & 0x1f;
667   operands[3] = GEN_INT (shift);
668   return "extui\t%0, %1, %3, %2";
670   [(set_attr "type"     "arith")
671    (set_attr "mode"     "SI")
672    (set_attr "length"   "3")])
675 ;; Conversions.
677 (define_insn "fix_truncsfsi2"
678   [(set (match_operand:SI 0 "register_operand" "=a")
679         (fix:SI (match_operand:SF 1 "register_operand" "f")))]
680   "TARGET_HARD_FLOAT"
681   "trunc.s\t%0, %1, 0"
682   [(set_attr "type"     "fconv")
683    (set_attr "mode"     "SF")
684    (set_attr "length"   "3")])
686 (define_insn "fixuns_truncsfsi2"
687   [(set (match_operand:SI 0 "register_operand" "=a")
688         (unsigned_fix:SI (match_operand:SF 1 "register_operand" "f")))]
689   "TARGET_HARD_FLOAT"
690   "utrunc.s\t%0, %1, 0"
691   [(set_attr "type"     "fconv")
692    (set_attr "mode"     "SF")
693    (set_attr "length"   "3")])
695 (define_insn "floatsisf2"
696   [(set (match_operand:SF 0 "register_operand" "=f")
697         (float:SF (match_operand:SI 1 "register_operand" "a")))]
698   "TARGET_HARD_FLOAT"
699   "float.s\t%0, %1, 0"
700   [(set_attr "type"     "fconv")
701    (set_attr "mode"     "SF")
702    (set_attr "length"   "3")])
704 (define_insn "floatunssisf2"
705   [(set (match_operand:SF 0 "register_operand" "=f")
706         (unsigned_float:SF (match_operand:SI 1 "register_operand" "a")))]
707   "TARGET_HARD_FLOAT"
708   "ufloat.s\t%0, %1, 0"
709   [(set_attr "type"     "fconv")
710    (set_attr "mode"     "SF")
711    (set_attr "length"   "3")])
714 ;; Data movement instructions.
716 ;; 64-bit Integer moves
718 (define_expand "movdi"
719   [(set (match_operand:DI 0 "nonimmed_operand" "")
720         (match_operand:DI 1 "general_operand" ""))]
721   ""
723   if (CONSTANT_P (operands[1]) && !TARGET_CONST16)
724     operands[1] = force_const_mem (DImode, operands[1]);
726   if (!register_operand (operands[0], DImode)
727       && !register_operand (operands[1], DImode))
728     operands[1] = force_reg (DImode, operands[1]);
730   operands[1] = xtensa_copy_incoming_a7 (operands[1]);
733 (define_insn_and_split "movdi_internal"
734   [(set (match_operand:DI 0 "nonimmed_operand" "=a,W,a,a,U")
735         (match_operand:DI 1 "move_operand" "r,i,T,U,r"))]
736   "register_operand (operands[0], DImode)
737    || register_operand (operands[1], DImode)"
738   "#"
739   "reload_completed"
740   [(set (match_dup 0) (match_dup 2))
741    (set (match_dup 1) (match_dup 3))]
743   xtensa_split_operand_pair (operands, SImode);
744   if (reg_overlap_mentioned_p (operands[0], operands[3]))
745     {
746       rtx tmp;
747       tmp = operands[0], operands[0] = operands[1], operands[1] = tmp;
748       tmp = operands[2], operands[2] = operands[3], operands[3] = tmp;
749     }
752 ;; 32-bit Integer moves
754 (define_expand "movsi"
755   [(set (match_operand:SI 0 "nonimmed_operand" "")
756         (match_operand:SI 1 "general_operand" ""))]
757   ""
759   if (xtensa_emit_move_sequence (operands, SImode))
760     DONE;
763 (define_insn "movsi_internal"
764   [(set (match_operand:SI 0 "nonimmed_operand" "=D,D,D,D,R,R,a,q,a,a,W,a,a,U,*a,*A")
765         (match_operand:SI 1 "move_operand" "M,D,d,R,D,d,r,r,I,Y,i,T,U,r,*A,*r"))]
766   "xtensa_valid_move (SImode, operands)"
767   "@
768    movi.n\t%0, %x1
769    mov.n\t%0, %1
770    mov.n\t%0, %1
771    %v1l32i.n\t%0, %1
772    %v0s32i.n\t%1, %0
773    %v0s32i.n\t%1, %0
774    mov\t%0, %1
775    movsp\t%0, %1
776    movi\t%0, %x1
777    movi\t%0, %1
778    const16\t%0, %t1\;const16\t%0, %b1
779    %v1l32r\t%0, %1
780    %v1l32i\t%0, %1
781    %v0s32i\t%1, %0
782    rsr\t%0, ACCLO
783    wsr\t%1, ACCLO"
784   [(set_attr "type" "move,move,move,load,store,store,move,move,move,move,move,load,load,store,rsr,wsr")
785    (set_attr "mode"     "SI")
786    (set_attr "length"   "2,2,2,2,2,2,3,3,3,3,6,3,3,3,3,3")])
788 ;; 16-bit Integer moves
790 (define_expand "movhi"
791   [(set (match_operand:HI 0 "nonimmed_operand" "")
792         (match_operand:HI 1 "general_operand" ""))]
793   ""
795   if (xtensa_emit_move_sequence (operands, HImode))
796     DONE;
799 (define_insn "movhi_internal"
800   [(set (match_operand:HI 0 "nonimmed_operand" "=D,D,a,a,a,a,U,*a,*A")
801         (match_operand:HI 1 "move_operand" "M,d,r,I,Y,U,r,*A,*r"))]
802   "xtensa_valid_move (HImode, operands)"
803   "@
804    movi.n\t%0, %x1
805    mov.n\t%0, %1
806    mov\t%0, %1
807    movi\t%0, %x1
808    movi\t%0, %1
809    %v1l16ui\t%0, %1
810    %v0s16i\t%1, %0
811    rsr\t%0, ACCLO
812    wsr\t%1, ACCLO"
813   [(set_attr "type"     "move,move,move,move,move,load,store,rsr,wsr")
814    (set_attr "mode"     "HI")
815    (set_attr "length"   "2,2,3,3,3,3,3,3,3")])
817 ;; 8-bit Integer moves
819 (define_expand "movqi"
820   [(set (match_operand:QI 0 "nonimmed_operand" "")
821         (match_operand:QI 1 "general_operand" ""))]
822   ""
824   if (xtensa_emit_move_sequence (operands, QImode))
825     DONE;
828 (define_insn "movqi_internal"
829   [(set (match_operand:QI 0 "nonimmed_operand" "=D,D,a,a,a,U,*a,*A")
830         (match_operand:QI 1 "move_operand" "M,d,r,I,U,r,*A,*r"))]
831   "xtensa_valid_move (QImode, operands)"
832   "@
833    movi.n\t%0, %x1
834    mov.n\t%0, %1
835    mov\t%0, %1
836    movi\t%0, %x1
837    %v1l8ui\t%0, %1
838    %v0s8i\t%1, %0
839    rsr\t%0, ACCLO
840    wsr\t%1, ACCLO"
841   [(set_attr "type"     "move,move,move,move,load,store,rsr,wsr")
842    (set_attr "mode"     "QI")
843    (set_attr "length"   "2,2,3,3,3,3,3,3")])
845 ;; Sub-word reloads from the constant pool.
847 (define_expand "reload<mode>_literal"
848   [(parallel [(match_operand:HQI 0 "register_operand" "=r")
849               (match_operand:HQI 1 "constantpool_operand" "")
850               (match_operand:SI 2 "register_operand" "=&r")])]
851   ""
853   rtx lit, scratch;
854   unsigned word_off, byte_off;
856   if (MEM_P (operands[1]))
857     {
858       lit = operands[1];
859       word_off = 0;
860       byte_off = 0;
861     }
862   else
863     {
864       gcc_assert (GET_CODE (operands[1]) == SUBREG);
865       lit = SUBREG_REG (operands[1]);
866       word_off = SUBREG_BYTE (operands[1]) & ~(UNITS_PER_WORD - 1);
867       byte_off = SUBREG_BYTE (operands[1]) - word_off;
868     }
870   lit = adjust_address (lit, SImode, word_off);
871   scratch = operands[2];
872   emit_insn (gen_movsi (scratch, lit));
873   emit_insn (gen_mov<mode> (operands[0],
874                             gen_rtx_SUBREG (<MODE>mode, scratch, byte_off)));
876   DONE;
879 ;; 32-bit floating point moves
881 (define_expand "movsf"
882   [(set (match_operand:SF 0 "nonimmed_operand" "")
883         (match_operand:SF 1 "general_operand" ""))]
884   ""
886   if (!TARGET_CONST16 && !TARGET_AUTO_LITPOOLS && CONSTANT_P (operands[1]))
887     operands[1] = force_const_mem (SFmode, operands[1]);
889   if ((!register_operand (operands[0], SFmode)
890        && !register_operand (operands[1], SFmode))
891       || (FP_REG_P (xt_true_regnum (operands[0]))
892           && !(reload_in_progress | reload_completed)
893           && (constantpool_mem_p (operands[1])
894               || CONSTANT_P (operands[1]))))
895     operands[1] = force_reg (SFmode, operands[1]);
897   operands[1] = xtensa_copy_incoming_a7 (operands[1]);
900 (define_insn "movsf_internal"
901   [(set (match_operand:SF 0 "nonimmed_operand" "=f,f,U,D,D,R,a,f,a,a,W,a,a,U")
902         (match_operand:SF 1 "move_operand" "f,U,f,d,R,d,r,r,f,Y,iF,T,U,r"))]
903   "((register_operand (operands[0], SFmode)
904      || register_operand (operands[1], SFmode))
905     && !(FP_REG_P (xt_true_regnum (operands[0]))
906          && (constantpool_mem_p (operands[1]) || CONSTANT_P (operands[1]))))"
907   "@
908    mov.s\t%0, %1
909    %v1lsi\t%0, %1
910    %v0ssi\t%1, %0
911    mov.n\t%0, %1
912    %v1l32i.n\t%0, %1
913    %v0s32i.n\t%1, %0
914    mov\t%0, %1
915    wfr\t%0, %1
916    rfr\t%0, %1
917    movi\t%0, %y1
918    const16\t%0, %t1\;const16\t%0, %b1
919    %v1l32r\t%0, %1
920    %v1l32i\t%0, %1
921    %v0s32i\t%1, %0"
922   [(set_attr "type"     "farith,fload,fstore,move,load,store,move,farith,farith,move,move,load,load,store")
923    (set_attr "mode"     "SF")
924    (set_attr "length"   "3,3,3,2,2,2,3,3,3,3,6,3,3,3")])
926 (define_insn "*lsiu"
927   [(set (match_operand:SF 0 "register_operand" "=f")
928         (mem:SF (plus:SI (match_operand:SI 1 "register_operand" "+a")
929                          (match_operand:SI 2 "fpmem_offset_operand" "i"))))
930    (set (match_dup 1)
931         (plus:SI (match_dup 1) (match_dup 2)))]
932   "TARGET_HARD_FLOAT && !TARGET_HARD_FLOAT_POSTINC"
934   if (TARGET_SERIALIZE_VOLATILE && volatile_refs_p (PATTERN (insn)))
935     output_asm_insn ("memw", operands);
936   return "lsiu\t%0, %1, %2";
938   [(set_attr "type"     "fload")
939    (set_attr "mode"     "SF")
940    (set_attr "length"   "3")])
942 (define_insn "*ssiu"
943   [(set (mem:SF (plus:SI (match_operand:SI 0 "register_operand" "+a")
944                          (match_operand:SI 1 "fpmem_offset_operand" "i")))
945         (match_operand:SF 2 "register_operand" "f"))
946    (set (match_dup 0)
947         (plus:SI (match_dup 0) (match_dup 1)))]
948   "TARGET_HARD_FLOAT && !TARGET_HARD_FLOAT_POSTINC"
950   if (TARGET_SERIALIZE_VOLATILE && volatile_refs_p (PATTERN (insn)))
951     output_asm_insn ("memw", operands);
952   return "ssiu\t%2, %0, %1";
954   [(set_attr "type"     "fstore")
955    (set_attr "mode"     "SF")
956    (set_attr "length"   "3")])
958 (define_insn "*lsip"
959   [(set (match_operand:SF 0 "register_operand" "=f")
960         (mem:SF (match_operand:SI 1 "register_operand" "+a")))
961    (set (match_dup 1)
962         (plus:SI (match_dup 1)
963                  (match_operand:SI 2 "fpmem_offset_operand" "i")))]
964   "TARGET_HARD_FLOAT && TARGET_HARD_FLOAT_POSTINC"
966   if (TARGET_SERIALIZE_VOLATILE && volatile_refs_p (PATTERN (insn)))
967     output_asm_insn ("memw", operands);
968   return "lsip\t%0, %1, %2";
970   [(set_attr "type"     "fload")
971    (set_attr "mode"     "SF")
972    (set_attr "length"   "3")])
974 (define_insn "*ssip"
975   [(set (mem:SF (match_operand:SI 0 "register_operand" "+a"))
976         (match_operand:SF 1 "register_operand" "f"))
977    (set (match_dup 0)
978         (plus:SI (match_dup 0)
979                  (match_operand:SI 2 "fpmem_offset_operand" "i")))]
980   "TARGET_HARD_FLOAT && TARGET_HARD_FLOAT_POSTINC"
982   if (TARGET_SERIALIZE_VOLATILE && volatile_refs_p (PATTERN (insn)))
983     output_asm_insn ("memw", operands);
984   return "ssip\t%1, %0, %2";
986   [(set_attr "type"     "fstore")
987    (set_attr "mode"     "SF")
988    (set_attr "length"   "3")])
990 ;; 64-bit floating point moves
992 (define_expand "movdf"
993   [(set (match_operand:DF 0 "nonimmed_operand" "")
994         (match_operand:DF 1 "general_operand" ""))]
995   ""
997   if (CONSTANT_P (operands[1]) && !TARGET_CONST16 && !TARGET_AUTO_LITPOOLS)
998     operands[1] = force_const_mem (DFmode, operands[1]);
1000   if (!register_operand (operands[0], DFmode)
1001       && !register_operand (operands[1], DFmode))
1002     operands[1] = force_reg (DFmode, operands[1]);
1004   operands[1] = xtensa_copy_incoming_a7 (operands[1]);
1007 (define_insn_and_split "movdf_internal"
1008   [(set (match_operand:DF 0 "nonimmed_operand" "=a,a,W,a,a,U")
1009         (match_operand:DF 1 "move_operand" "r,Y,iF,T,U,r"))]
1010   "register_operand (operands[0], DFmode)
1011    || register_operand (operands[1], DFmode)"
1012   "#"
1013   "reload_completed"
1014   [(set (match_dup 0) (match_dup 2))
1015    (set (match_dup 1) (match_dup 3))]
1017   xtensa_split_operand_pair (operands, SFmode);
1018   if (reg_overlap_mentioned_p (operands[0], operands[3]))
1019     {
1020       rtx tmp;
1021       tmp = operands[0], operands[0] = operands[1], operands[1] = tmp;
1022       tmp = operands[2], operands[2] = operands[3], operands[3] = tmp;
1023     }
1026 ;; Block moves
1028 (define_expand "movmemsi"
1029   [(parallel [(set (match_operand:BLK 0 "" "")
1030                    (match_operand:BLK 1 "" ""))
1031               (use (match_operand:SI 2 "arith_operand" ""))
1032               (use (match_operand:SI 3 "const_int_operand" ""))])]
1033   ""
1035   if (!xtensa_expand_block_move (operands))
1036     FAIL;
1037   DONE;
1041 ;; Shift instructions.
1043 (define_expand "ashlsi3"
1044   [(set (match_operand:SI 0 "register_operand" "")
1045         (ashift:SI (match_operand:SI 1 "register_operand" "")
1046                    (match_operand:SI 2 "arith_operand" "")))]
1047   ""
1049   operands[1] = xtensa_copy_incoming_a7 (operands[1]);
1052 (define_insn "ashlsi3_internal"
1053   [(set (match_operand:SI 0 "register_operand" "=a,a")
1054         (ashift:SI (match_operand:SI 1 "register_operand" "r,r")
1055                    (match_operand:SI 2 "arith_operand" "J,r")))]
1056   ""      
1057   "@
1058    slli\t%0, %1, %R2
1059    ssl\t%2\;sll\t%0, %1"
1060   [(set_attr "type"     "arith,arith")
1061    (set_attr "mode"     "SI")
1062    (set_attr "length"   "3,6")])
1064 (define_insn "ashrsi3"
1065   [(set (match_operand:SI 0 "register_operand" "=a,a")
1066         (ashiftrt:SI (match_operand:SI 1 "register_operand" "r,r")
1067                      (match_operand:SI 2 "arith_operand" "J,r")))]
1068   ""
1069   "@
1070    srai\t%0, %1, %R2
1071    ssr\t%2\;sra\t%0, %1"
1072   [(set_attr "type"     "arith,arith")
1073    (set_attr "mode"     "SI")
1074    (set_attr "length"   "3,6")])
1076 (define_insn "lshrsi3"
1077   [(set (match_operand:SI 0 "register_operand" "=a,a")
1078         (lshiftrt:SI (match_operand:SI 1 "register_operand" "r,r")
1079                      (match_operand:SI 2 "arith_operand" "J,r")))]
1080   ""
1082   if (which_alternative == 0)
1083     {
1084       if ((INTVAL (operands[2]) & 0x1f) < 16)
1085         return "srli\t%0, %1, %R2";
1086       else
1087         return "extui\t%0, %1, %R2, %L2";
1088     }
1089   return "ssr\t%2\;srl\t%0, %1";
1091   [(set_attr "type"     "arith,arith")
1092    (set_attr "mode"     "SI")
1093    (set_attr "length"   "3,6")])
1095 (define_insn "rotlsi3"
1096   [(set (match_operand:SI 0 "register_operand" "=a,a")
1097         (rotate:SI (match_operand:SI 1 "register_operand" "r,r")
1098                      (match_operand:SI 2 "arith_operand" "J,r")))]
1099   ""
1100   "@
1101    ssai\t%L2\;src\t%0, %1, %1
1102    ssl\t%2\;src\t%0, %1, %1"
1103   [(set_attr "type"     "multi,multi")
1104    (set_attr "mode"     "SI")
1105    (set_attr "length"   "6,6")])
1107 (define_insn "rotrsi3"
1108   [(set (match_operand:SI 0 "register_operand" "=a,a")
1109         (rotatert:SI (match_operand:SI 1 "register_operand" "r,r")
1110                      (match_operand:SI 2 "arith_operand" "J,r")))]
1111   ""
1112   "@
1113    ssai\t%R2\;src\t%0, %1, %1
1114    ssr\t%2\;src\t%0, %1, %1"
1115   [(set_attr "type"     "multi,multi")
1116    (set_attr "mode"     "SI")
1117    (set_attr "length"   "6,6")])
1120 ;; Comparisons.
1122 ;; Conditional branches.
1124 (define_expand "cbranchsi4"
1125   [(match_operator 0 "comparison_operator"
1126     [(match_operand:SI 1 "register_operand")
1127      (match_operand:SI 2 "nonmemory_operand")])
1128    (match_operand 3 "")]
1129   ""
1131   xtensa_expand_conditional_branch (operands, SImode);
1132   DONE;
1135 (define_expand "cbranchsf4"
1136   [(match_operator 0 "comparison_operator"
1137     [(match_operand:SF 1 "register_operand")
1138      (match_operand:SF 2 "register_operand")])
1139    (match_operand 3 "")]
1140   "TARGET_HARD_FLOAT"
1142   xtensa_expand_conditional_branch (operands, SFmode);
1143   DONE;
1146 ;; Branch patterns for standard integer comparisons
1148 (define_insn "*btrue"
1149   [(set (pc)
1150         (if_then_else (match_operator 3 "branch_operator"
1151                        [(match_operand:SI 0 "register_operand" "r,r")
1152                         (match_operand:SI 1 "branch_operand" "K,r")])
1153                       (label_ref (match_operand 2 "" ""))
1154                       (pc)))]
1155   ""
1157   return xtensa_emit_branch (false, which_alternative == 0, operands);
1159   [(set_attr "type"     "jump,jump")
1160    (set_attr "mode"     "none")
1161    (set_attr "length"   "3,3")])
1163 (define_insn "*bfalse"
1164   [(set (pc)
1165         (if_then_else (match_operator 3 "branch_operator"
1166                        [(match_operand:SI 0 "register_operand" "r,r")
1167                         (match_operand:SI 1 "branch_operand" "K,r")])
1168                       (pc)
1169                       (label_ref (match_operand 2 "" ""))))]
1170   ""
1172   return xtensa_emit_branch (true, which_alternative == 0, operands);
1174   [(set_attr "type"     "jump,jump")
1175    (set_attr "mode"     "none")
1176    (set_attr "length"   "3,3")])
1178 (define_insn "*ubtrue"
1179   [(set (pc)
1180         (if_then_else (match_operator 3 "ubranch_operator"
1181                        [(match_operand:SI 0 "register_operand" "r,r")
1182                         (match_operand:SI 1 "ubranch_operand" "L,r")])
1183                       (label_ref (match_operand 2 "" ""))
1184                       (pc)))]
1185   ""
1187   return xtensa_emit_branch (false, which_alternative == 0, operands);
1189   [(set_attr "type"     "jump,jump")
1190    (set_attr "mode"     "none")
1191    (set_attr "length"   "3,3")])
1193 (define_insn "*ubfalse"
1194   [(set (pc)
1195         (if_then_else (match_operator 3 "ubranch_operator"
1196                          [(match_operand:SI 0 "register_operand" "r,r")
1197                           (match_operand:SI 1 "ubranch_operand" "L,r")])
1198                       (pc)
1199                       (label_ref (match_operand 2 "" ""))))]
1200   ""
1202   return xtensa_emit_branch (true, which_alternative == 0, operands);
1204   [(set_attr "type"     "jump,jump")
1205    (set_attr "mode"     "none")
1206    (set_attr "length"   "3,3")])
1208 ;; Branch patterns for bit testing
1210 (define_insn "*bittrue"
1211   [(set (pc)
1212         (if_then_else (match_operator 3 "boolean_operator"
1213                         [(zero_extract:SI
1214                             (match_operand:SI 0 "register_operand" "r,r")
1215                             (const_int 1)
1216                             (match_operand:SI 1 "arith_operand" "J,r"))
1217                          (const_int 0)])
1218                       (label_ref (match_operand 2 "" ""))
1219                       (pc)))]
1220   ""
1222   return xtensa_emit_bit_branch (false, which_alternative == 0, operands);
1224   [(set_attr "type"     "jump")
1225    (set_attr "mode"     "none")
1226    (set_attr "length"   "3")])
1228 (define_insn "*bitfalse"
1229   [(set (pc)
1230         (if_then_else (match_operator 3 "boolean_operator"
1231                         [(zero_extract:SI
1232                             (match_operand:SI 0 "register_operand" "r,r")
1233                             (const_int 1)
1234                             (match_operand:SI 1 "arith_operand" "J,r"))
1235                          (const_int 0)])
1236                       (pc)
1237                       (label_ref (match_operand 2 "" ""))))]
1238   ""
1240   return xtensa_emit_bit_branch (true, which_alternative == 0, operands);
1242   [(set_attr "type"     "jump")
1243    (set_attr "mode"     "none")
1244    (set_attr "length"   "3")])
1246 (define_insn "*masktrue"
1247   [(set (pc)
1248         (if_then_else (match_operator 3 "boolean_operator"
1249                  [(and:SI (match_operand:SI 0 "register_operand" "r")
1250                           (match_operand:SI 1 "register_operand" "r"))
1251                   (const_int 0)])
1252                       (label_ref (match_operand 2 "" ""))
1253                       (pc)))]
1254   ""
1256   switch (GET_CODE (operands[3]))
1257     {
1258     case EQ:            return "bnone\t%0, %1, %2";
1259     case NE:            return "bany\t%0, %1, %2";
1260     default:            gcc_unreachable ();
1261     }
1263   [(set_attr "type"     "jump")
1264    (set_attr "mode"     "none")
1265    (set_attr "length"   "3")])
1267 (define_insn "*maskfalse"
1268   [(set (pc)
1269         (if_then_else (match_operator 3 "boolean_operator"
1270                  [(and:SI (match_operand:SI 0 "register_operand" "r")
1271                           (match_operand:SI 1 "register_operand" "r"))
1272                   (const_int 0)])
1273                       (pc)
1274                       (label_ref (match_operand 2 "" ""))))]
1275   ""
1277   switch (GET_CODE (operands[3]))
1278     {
1279     case EQ:            return "bany\t%0, %1, %2";
1280     case NE:            return "bnone\t%0, %1, %2";
1281     default:            gcc_unreachable ();
1282     }
1284   [(set_attr "type"     "jump")
1285    (set_attr "mode"     "none")
1286    (set_attr "length"   "3")])
1289 ;; Zero-overhead looping support.
1291 ;; Define the loop insns used by bct optimization to represent the
1292 ;; start and end of a zero-overhead loop.  This start template generates
1293 ;; the loop insn; the end template doesn't generate any instructions since
1294 ;; loop end is handled in hardware.
1296 (define_insn "zero_cost_loop_start"
1297   [(set (pc)
1298         (if_then_else (ne (match_operand:SI 2 "register_operand" "0")
1299                           (const_int 1))
1300                       (label_ref (match_operand 1 "" ""))
1301                       (pc)))
1302    (set (match_operand:SI 0 "register_operand" "=a")
1303         (plus (match_dup 0)
1304               (const_int -1)))
1305    (unspec [(const_int 0)] UNSPEC_LSETUP_START)]
1306   "TARGET_LOOPS && optimize"
1307   "loop\t%0, %l1_LEND"
1308   [(set_attr "type"     "jump")
1309    (set_attr "mode"     "none")
1310    (set_attr "length"   "3")])
1312 (define_insn "zero_cost_loop_end"
1313   [(set (pc)
1314         (if_then_else (ne (match_operand:SI 2 "nonimmediate_operand" "0,0")
1315                           (const_int 1))
1316                       (label_ref (match_operand 1 "" ""))
1317                       (pc)))
1318    (set (match_operand:SI 0 "nonimmediate_operand" "=a,m")
1319         (plus (match_dup 0)
1320               (const_int -1)))
1321    (unspec [(const_int 0)] UNSPEC_LSETUP_END)
1322    (clobber (match_scratch:SI 3 "=X,&r"))]
1323   "TARGET_LOOPS && optimize"
1324   "#"
1325   [(set_attr "type"     "jump")
1326    (set_attr "mode"     "none")
1327    (set_attr "length"   "0")])
1329 (define_insn "loop_end"
1330   [(set (pc)
1331         (if_then_else (ne (match_operand:SI 2 "register_operand" "0")
1332                           (const_int 1))
1333                       (label_ref (match_operand 1 "" ""))
1334                       (pc)))
1335    (set (match_operand:SI 0 "register_operand" "=a")
1336         (plus (match_dup 0)
1337               (const_int -1)))
1338    (unspec [(const_int 0)] UNSPEC_LSETUP_END)]
1339   "TARGET_LOOPS && optimize"
1341   xtensa_emit_loop_end (insn, operands);
1342   return "";
1344   [(set_attr "type"     "jump")
1345    (set_attr "mode"     "none")
1346    (set_attr "length"   "0")])
1348 (define_split
1349   [(set (pc)
1350         (if_then_else (ne (match_operand:SI 0 "nonimmediate_operand" "")
1351                           (const_int 1))
1352                       (label_ref (match_operand 1 "" ""))
1353                       (pc)))
1354    (set (match_operand:SI 2 "nonimmediate_operand" "")
1355         (plus:SI (match_dup 0)
1356                  (const_int -1)))
1357    (unspec [(const_int 0)] UNSPEC_LSETUP_END)
1358    (clobber (match_scratch 3))]
1359   "TARGET_LOOPS && optimize && reload_completed"
1360   [(const_int 0)]
1362   if (!REG_P (operands[0]))
1363     {
1364       rtx test;
1366       /* Fallback into a normal conditional branch insn.  */
1367       emit_move_insn (operands[3], operands[0]);
1368       emit_insn (gen_addsi3 (operands[3], operands[3], constm1_rtx));
1369       emit_move_insn (operands[0], operands[3]);
1370       test = gen_rtx_NE (VOIDmode, operands[3], const0_rtx);
1371       emit_jump_insn (gen_cbranchsi4 (test, operands[3],
1372                                       const0_rtx, operands[1]));
1373     }
1374   else
1375     {
1376       emit_jump_insn (gen_loop_end (operands[0], operands[1], operands[2]));
1377     }
1379   DONE;
1382 ; operand 0 is the loop count pseudo register
1383 ; operand 1 is the label to jump to at the top of the loop
1384 (define_expand "doloop_end"
1385   [(parallel [(set (pc) (if_then_else
1386                           (ne (match_operand:SI 0 "" "")
1387                               (const_int 1))
1388                           (label_ref (match_operand 1 "" ""))
1389                           (pc)))
1390               (set (match_dup 0)
1391                    (plus:SI (match_dup 0)
1392                             (const_int -1)))
1393               (unspec [(const_int 0)] UNSPEC_LSETUP_END)
1394               (clobber (match_dup 2))])] ; match_scratch
1395   "TARGET_LOOPS && optimize"
1397   /* The loop optimizer doesn't check the predicates... */
1398   if (GET_MODE (operands[0]) != SImode)
1399     FAIL;
1400   operands[2] = gen_rtx_SCRATCH (SImode);
1404 ;; Setting a register from a comparison.
1406 (define_expand "cstoresi4"
1407   [(match_operand:SI 0 "register_operand")
1408    (match_operator 1 "xtensa_cstoresi_operator"
1409     [(match_operand:SI 2 "register_operand")
1410      (match_operand:SI 3 "nonmemory_operand")])]
1411   ""
1413   if (!xtensa_expand_scc (operands, SImode))
1414     FAIL;
1415   DONE;
1418 (define_expand "cstoresf4"
1419   [(match_operand:SI 0 "register_operand")
1420    (match_operator:SI 1 "comparison_operator"
1421     [(match_operand:SF 2 "register_operand")
1422      (match_operand:SF 3 "register_operand")])]
1423   "TARGET_HARD_FLOAT"
1425   if (!xtensa_expand_scc (operands, SFmode))
1426     FAIL;
1427   DONE;
1432 ;; Conditional moves.
1434 (define_expand "movsicc"
1435   [(set (match_operand:SI 0 "register_operand" "")
1436         (if_then_else:SI (match_operand 1 "comparison_operator" "")
1437                          (match_operand:SI 2 "register_operand" "")
1438                          (match_operand:SI 3 "register_operand" "")))]
1439   ""
1441   if (!xtensa_expand_conditional_move (operands, 0))
1442     FAIL;
1443   DONE;
1446 (define_expand "movsfcc"
1447   [(set (match_operand:SF 0 "register_operand" "")
1448         (if_then_else:SF (match_operand 1 "comparison_operator" "")
1449                          (match_operand:SF 2 "register_operand" "")
1450                          (match_operand:SF 3 "register_operand" "")))]
1451   ""
1453   if (!xtensa_expand_conditional_move (operands, 1))
1454     FAIL;
1455   DONE;
1458 (define_insn "movsicc_internal0"
1459   [(set (match_operand:SI 0 "register_operand" "=a,a")
1460         (if_then_else:SI (match_operator 4 "branch_operator"
1461                            [(match_operand:SI 1 "register_operand" "r,r")
1462                             (const_int 0)])
1463                          (match_operand:SI 2 "register_operand" "r,0")
1464                          (match_operand:SI 3 "register_operand" "0,r")))]
1465   ""
1467   return xtensa_emit_movcc (which_alternative == 1, false, false, operands);
1469   [(set_attr "type"     "move,move")
1470    (set_attr "mode"     "SI")
1471    (set_attr "length"   "3,3")])
1473 (define_insn "movsicc_internal1"
1474   [(set (match_operand:SI 0 "register_operand" "=a,a")
1475         (if_then_else:SI (match_operator 4 "boolean_operator"
1476                            [(match_operand:CC 1 "register_operand" "b,b")
1477                             (const_int 0)])
1478                          (match_operand:SI 2 "register_operand" "r,0")
1479                          (match_operand:SI 3 "register_operand" "0,r")))]
1480   "TARGET_BOOLEANS"
1482   return xtensa_emit_movcc (which_alternative == 1, false, true, operands);
1484   [(set_attr "type"     "move,move")
1485    (set_attr "mode"     "SI")
1486    (set_attr "length"   "3,3")])
1488 (define_insn "movsfcc_internal0"
1489   [(set (match_operand:SF 0 "register_operand" "=a,a,f,f")
1490         (if_then_else:SF (match_operator 4 "branch_operator"
1491                            [(match_operand:SI 1 "register_operand" "r,r,r,r")
1492                             (const_int 0)])
1493                          (match_operand:SF 2 "register_operand" "r,0,f,0")
1494                          (match_operand:SF 3 "register_operand" "0,r,0,f")))]
1495   ""
1497   return xtensa_emit_movcc ((which_alternative & 1) == 1,
1498                             which_alternative >= 2, false, operands);
1500   [(set_attr "type"     "move,move,move,move")
1501    (set_attr "mode"     "SF")
1502    (set_attr "length"   "3,3,3,3")])
1504 (define_insn "movsfcc_internal1"
1505   [(set (match_operand:SF 0 "register_operand" "=a,a,f,f")
1506         (if_then_else:SF (match_operator 4 "boolean_operator"
1507                            [(match_operand:CC 1 "register_operand" "b,b,b,b")
1508                             (const_int 0)])
1509                          (match_operand:SF 2 "register_operand" "r,0,f,0")
1510                          (match_operand:SF 3 "register_operand" "0,r,0,f")))]
1511   "TARGET_BOOLEANS"
1513   return xtensa_emit_movcc ((which_alternative & 1) == 1,
1514                             which_alternative >= 2, true, operands);
1516   [(set_attr "type"     "move,move,move,move")
1517    (set_attr "mode"     "SF")
1518    (set_attr "length"   "3,3,3,3")])
1521 ;; Floating-point comparisons.
1523 (define_insn "s<code>_sf"
1524   [(set (match_operand:CC 0 "register_operand" "=b")
1525         (any_scc_sf:CC (match_operand:SF 1 "register_operand" "f")
1526                        (match_operand:SF 2 "register_operand" "f")))]
1527   "TARGET_HARD_FLOAT"
1528   "<scc_sf>.s\t%0, %1, %2"
1529   [(set_attr "type"     "farith")
1530    (set_attr "mode"     "BL")
1531    (set_attr "length"   "3")])
1534 ;; Unconditional branches.
1536 (define_insn "jump"
1537   [(set (pc)
1538         (label_ref (match_operand 0 "" "")))]
1539   ""
1540   "j\t%l0"
1541   [(set_attr "type"     "jump")
1542    (set_attr "mode"     "none")
1543    (set_attr "length"   "3")])
1545 (define_expand "indirect_jump"
1546   [(set (pc)
1547         (match_operand 0 "register_operand" ""))]
1548   ""
1550   rtx dest = operands[0];
1551   if (GET_CODE (dest) != REG || GET_MODE (dest) != Pmode)
1552     operands[0] = copy_to_mode_reg (Pmode, dest);
1554   emit_jump_insn (gen_indirect_jump_internal (dest));
1555   DONE;
1558 (define_insn "indirect_jump_internal"
1559   [(set (pc) (match_operand:SI 0 "register_operand" "r"))]
1560   ""
1561   "jx\t%0"
1562   [(set_attr "type"     "jump")
1563    (set_attr "mode"     "none")
1564    (set_attr "length"   "3")])
1567 (define_expand "tablejump"
1568   [(use (match_operand:SI 0 "register_operand" ""))
1569    (use (label_ref (match_operand 1 "" "")))]
1570    ""
1572   rtx target = operands[0];
1573   if (flag_pic)
1574     {
1575       /* For PIC, the table entry is relative to the start of the table.  */
1576       rtx label = gen_reg_rtx (SImode);
1577       target = gen_reg_rtx (SImode);
1578       emit_move_insn (label, gen_rtx_LABEL_REF (SImode, operands[1]));
1579       emit_insn (gen_addsi3 (target, operands[0], label));
1580     }
1581   emit_jump_insn (gen_tablejump_internal (target, operands[1]));
1582   DONE;
1585 (define_insn "tablejump_internal"
1586   [(set (pc)
1587         (match_operand:SI 0 "register_operand" "r"))
1588    (use (label_ref (match_operand 1 "" "")))]
1589   ""
1590   "jx\t%0"
1591   [(set_attr "type"     "jump")
1592    (set_attr "mode"     "none")
1593    (set_attr "length"   "3")])
1596 ;; Function calls.
1598 (define_expand "sym_PLT"
1599   [(const (unspec [(match_operand:SI 0 "" "")] UNSPEC_PLT))]
1600   ""
1601   "")
1603 (define_expand "call"
1604   [(call (match_operand 0 "memory_operand" "")
1605          (match_operand 1 "" ""))]
1606   ""
1608   rtx addr = XEXP (operands[0], 0);
1609   if (flag_pic && GET_CODE (addr) == SYMBOL_REF
1610       && (!SYMBOL_REF_LOCAL_P (addr) || SYMBOL_REF_EXTERNAL_P (addr)))
1611     addr = gen_sym_PLT (addr);
1612   if (!call_insn_operand (addr, VOIDmode))
1613     XEXP (operands[0], 0) = copy_to_mode_reg (Pmode, addr);
1616 (define_insn "call_internal"
1617   [(call (mem (match_operand:SI 0 "call_insn_operand" "nir"))
1618          (match_operand 1 "" "i"))]
1619   ""
1621   return xtensa_emit_call (0, operands);
1623   [(set_attr "type"     "call")
1624    (set_attr "mode"     "none")
1625    (set_attr "length"   "3")])
1627 (define_expand "call_value"
1628   [(set (match_operand 0 "register_operand" "")
1629         (call (match_operand 1 "memory_operand" "")
1630               (match_operand 2 "" "")))]
1631   ""
1633   rtx addr = XEXP (operands[1], 0);
1634   if (flag_pic && GET_CODE (addr) == SYMBOL_REF
1635       && (!SYMBOL_REF_LOCAL_P (addr) || SYMBOL_REF_EXTERNAL_P (addr)))
1636     addr = gen_sym_PLT (addr);
1637   if (!call_insn_operand (addr, VOIDmode))
1638     XEXP (operands[1], 0) = copy_to_mode_reg (Pmode, addr);
1641 (define_insn "call_value_internal"
1642   [(set (match_operand 0 "register_operand" "=a")
1643         (call (mem (match_operand:SI 1 "call_insn_operand" "nir"))
1644               (match_operand 2 "" "i")))]
1645   ""
1647   return xtensa_emit_call (1, operands);
1649   [(set_attr "type"     "call")
1650    (set_attr "mode"     "none")
1651    (set_attr "length"   "3")])
1653 (define_insn "entry"
1654   [(set (reg:SI A1_REG)
1655         (unspec_volatile:SI [(match_operand:SI 0 "const_int_operand" "i")]
1656                             UNSPECV_ENTRY))]
1657   ""
1658   "entry\tsp, %0"
1659   [(set_attr "type"     "entry")
1660    (set_attr "mode"     "SI")
1661    (set_attr "length"   "3")])
1663 (define_insn "return"
1664   [(return)
1665    (use (reg:SI A0_REG))]
1666   "xtensa_use_return_instruction_p ()"
1668   return TARGET_WINDOWED_ABI ?
1669       (TARGET_DENSITY ? "retw.n" : "retw") :
1670       (TARGET_DENSITY ? "ret.n" : "ret");
1672   [(set_attr "type"     "jump")
1673    (set_attr "mode"     "none")
1674    (set_attr "length"   "2")])
1677 ;; Miscellaneous instructions.
1679 (define_expand "prologue"
1680   [(const_int 0)]
1681   ""
1683   xtensa_expand_prologue ();
1684   DONE;
1687 (define_expand "epilogue"
1688   [(return)]
1689   ""
1691   xtensa_expand_epilogue ();
1692   DONE;
1695 (define_insn "nop"
1696   [(const_int 0)]
1697   ""
1699   return (TARGET_DENSITY ? "nop.n" : "nop");
1701   [(set_attr "type"     "nop")
1702    (set_attr "mode"     "none")
1703    (set_attr "length"   "3")])
1705 (define_expand "nonlocal_goto"
1706   [(match_operand:SI 0 "general_operand" "")
1707    (match_operand:SI 1 "general_operand" "")
1708    (match_operand:SI 2 "general_operand" "")
1709    (match_operand:SI 3 "" "")]
1710   "TARGET_WINDOWED_ABI"
1712   xtensa_expand_nonlocal_goto (operands);
1713   DONE;
1716 ;; Stuff an address into the return address register along with the window
1717 ;; size in the high bits.  Because we don't have the window size of the
1718 ;; previous frame, assume the function called out with a CALL8 since that
1719 ;; is what compilers always use.  Note: __builtin_frob_return_addr has
1720 ;; already been applied to the handler, but the generic version doesn't
1721 ;; allow us to frob it quite enough, so we just frob here.
1723 (define_expand "eh_return"
1724   [(use (match_operand 0 "general_operand"))]
1725   ""
1727   if (TARGET_WINDOWED_ABI)
1728     emit_insn (gen_eh_set_a0_windowed (operands[0]));
1729   else
1730     emit_insn (gen_eh_set_a0_call0 (operands[0]));
1731   DONE;
1734 (define_insn_and_split "eh_set_a0_windowed"
1735   [(set (reg:SI A0_REG)
1736         (unspec_volatile:SI [(match_operand:SI 0 "register_operand" "r")]
1737                             UNSPECV_EH_RETURN))
1738    (clobber (match_scratch:SI 1 "=r"))]
1739   ""
1740   "#"
1741   "reload_completed"
1742   [(set (match_dup 1) (ashift:SI (match_dup 0) (const_int 2)))
1743    (set (match_dup 1) (plus:SI (match_dup 1) (const_int 2)))
1744    (set (reg:SI A0_REG) (rotatert:SI (match_dup 1) (const_int 2)))]
1745   "")
1747 (define_insn_and_split "eh_set_a0_call0"
1748   [(unspec_volatile [(match_operand:SI 0 "register_operand" "r")]
1749                     UNSPECV_EH_RETURN)
1750    (clobber (match_scratch:SI 1 "=r"))]
1751   ""
1752   "#"
1753   "reload_completed"
1754   [(const_int 0)]
1756   xtensa_set_return_address (operands[0], operands[1]);
1757   DONE;
1760 ;; UNSPEC_VOLATILE is considered to use and clobber all hard registers and
1761 ;; all of memory.  This blocks insns from being moved across this point.
1763 (define_insn "blockage"
1764   [(unspec_volatile [(const_int 0)] UNSPECV_BLOCKAGE)]
1765   ""
1766   ""
1767   [(set_attr "length" "0")
1768    (set_attr "type" "nop")])
1770 (define_insn "trap"
1771   [(trap_if (const_int 1) (const_int 0))]
1772   ""
1774   if (TARGET_DEBUG)
1775     return "break\t1, 15";
1776   else
1777     return (TARGET_DENSITY ? "ill.n" : "ill");
1779   [(set_attr "type"     "trap")
1780    (set_attr "mode"     "none")
1781    (set_attr "length"   "3")])
1783 ;; Setting up a frame pointer is tricky for Xtensa because GCC doesn't
1784 ;; know if a frame pointer is required until the reload pass, and
1785 ;; because there may be an incoming argument value in the hard frame
1786 ;; pointer register (a7).  If there is an incoming argument in that
1787 ;; register, the "set_frame_ptr" insn gets inserted immediately after
1788 ;; the insn that copies the incoming argument to a pseudo or to the
1789 ;; stack.  This serves several purposes here: (1) it keeps the
1790 ;; optimizer from copy-propagating or scheduling the use of a7 as an
1791 ;; incoming argument away from the beginning of the function; (2) we
1792 ;; can use a post-reload splitter to expand away the insn if a frame
1793 ;; pointer is not required, so that the post-reload scheduler can do
1794 ;; the right thing; and (3) it makes it easy for the prologue expander
1795 ;; to search for this insn to determine whether it should add a new insn
1796 ;; to set up the frame pointer.
1798 (define_insn "set_frame_ptr"
1799   [(set (reg:SI A7_REG) (unspec_volatile:SI [(const_int 0)] UNSPECV_SET_FP))]
1800   ""
1802   if (frame_pointer_needed)
1803     return "mov\ta7, sp";
1804   return "";
1806   [(set_attr "type"     "move")
1807    (set_attr "mode"     "SI")
1808    (set_attr "length"   "3")])
1810 ;; Post-reload splitter to remove fp assignment when it's not needed.
1811 (define_split
1812   [(set (reg:SI A7_REG) (unspec_volatile:SI [(const_int 0)] UNSPECV_SET_FP))]
1813   "reload_completed && !frame_pointer_needed"
1814   [(unspec [(const_int 0)] UNSPEC_NOP)]
1815   "")
1817 ;; The preceding splitter needs something to split the insn into;
1818 ;; things start breaking if the result is just a "use" so instead we
1819 ;; generate the following insn.
1820 (define_insn "*unspec_nop"
1821   [(unspec [(const_int 0)] UNSPEC_NOP)]
1822   ""
1823   ""
1824   [(set_attr "type"     "nop")
1825    (set_attr "mode"     "none")
1826    (set_attr "length"   "0")])
1829 ;; TLS support
1831 (define_expand "sym_TPOFF"
1832   [(const (unspec [(match_operand:SI 0 "" "")] UNSPEC_TPOFF))]
1833   ""
1834   "")
1836 (define_expand "sym_DTPOFF"
1837   [(const (unspec [(match_operand:SI 0 "" "")] UNSPEC_DTPOFF))]
1838   ""
1839   "")
1841 (define_insn "get_thread_pointersi"
1842   [(set (match_operand:SI 0 "register_operand" "=a")
1843         (unspec:SI [(const_int 0)] UNSPEC_TP))]
1844   "TARGET_THREADPTR"
1845   "rur\t%0, THREADPTR"
1846   [(set_attr "type"     "rsr")
1847    (set_attr "mode"     "SI")
1848    (set_attr "length"   "3")])
1850 (define_insn "set_thread_pointersi"
1851   [(unspec_volatile [(match_operand:SI 0 "register_operand" "r")]
1852                     UNSPECV_SET_TP)]
1853   "TARGET_THREADPTR"
1854   "wur\t%0, THREADPTR"
1855   [(set_attr "type"     "wsr")
1856    (set_attr "mode"     "SI")
1857    (set_attr "length"   "3")])
1859 (define_insn "tls_func"
1860   [(set (match_operand:SI 0 "register_operand" "=a")
1861         (unspec:SI [(match_operand:SI 1 "tls_symbol_operand" "")]
1862                    UNSPEC_TLS_FUNC))]
1863   "TARGET_THREADPTR && HAVE_AS_TLS"
1864   "movi\t%0, %1@TLSFUNC"
1865   [(set_attr "type"     "load")
1866    (set_attr "mode"     "SI")
1867    (set_attr "length"   "3")])
1869 (define_insn "tls_arg"
1870   [(set (match_operand:SI 0 "register_operand" "=a")
1871         (unspec:SI [(match_operand:SI 1 "tls_symbol_operand" "")]
1872                    UNSPEC_TLS_ARG))]
1873   "TARGET_THREADPTR && HAVE_AS_TLS"
1874   "movi\t%0, %1@TLSARG"
1875   [(set_attr "type"     "load")
1876    (set_attr "mode"     "SI")
1877    (set_attr "length"   "3")])
1879 (define_insn "tls_call"
1880   [(set (match_operand:SI 0 "register_operand" "=a")
1881         (call (mem:SI (unspec:SI [(match_operand:SI 1 "register_operand" "r")
1882                                   (match_operand:SI 2 "tls_symbol_operand" "")]
1883                                   UNSPEC_TLS_CALL))
1884               (match_operand 3 "" "i")))]
1885   "TARGET_THREADPTR && HAVE_AS_TLS"
1887   if (TARGET_WINDOWED_ABI)
1888     return "callx8.tls %1, %2@TLSCALL";
1889   else
1890     return "callx0.tls %1, %2@TLSCALL";
1892   [(set_attr "type"     "call")
1893    (set_attr "mode"     "none")
1894    (set_attr "length"   "3")])
1897 ;; Instructions for the Xtensa "boolean" option.
1899 (define_insn "*booltrue"
1900   [(set (pc)
1901         (if_then_else (match_operator 2 "boolean_operator"
1902                          [(match_operand:CC 0 "register_operand" "b")
1903                           (const_int 0)])
1904                       (label_ref (match_operand 1 "" ""))
1905                       (pc)))]
1906   "TARGET_BOOLEANS"
1908   if (GET_CODE (operands[2]) == EQ)
1909     return "bf\t%0, %1";
1910   else
1911     return "bt\t%0, %1";
1913   [(set_attr "type"     "jump")
1914    (set_attr "mode"     "none")
1915    (set_attr "length"   "3")])
1917 (define_insn "*boolfalse"
1918   [(set (pc)
1919         (if_then_else (match_operator 2 "boolean_operator"
1920                          [(match_operand:CC 0 "register_operand" "b")
1921                           (const_int 0)])
1922                       (pc)
1923                       (label_ref (match_operand 1 "" ""))))]
1924   "TARGET_BOOLEANS"
1926   if (GET_CODE (operands[2]) == EQ)
1927     return "bt\t%0, %1";
1928   else
1929     return "bf\t%0, %1";
1931   [(set_attr "type"     "jump")
1932    (set_attr "mode"     "none")
1933    (set_attr "length"   "3")])
1936 ;; Atomic operations
1938 (define_expand "memory_barrier"
1939   [(set (match_dup 0)
1940         (unspec:BLK [(match_dup 0)] UNSPEC_MEMW))]
1941   ""
1943   operands[0] = gen_rtx_MEM (BLKmode, gen_rtx_SCRATCH (Pmode));
1944   MEM_VOLATILE_P (operands[0]) = 1;
1947 (define_insn "*memory_barrier"
1948   [(set (match_operand:BLK 0 "" "")
1949         (unspec:BLK [(match_dup 0)] UNSPEC_MEMW))]
1950   ""
1951   "memw"
1952   [(set_attr "type"     "unknown")
1953    (set_attr "mode"     "none")
1954    (set_attr "length"   "3")])
1956 ;; sync_lock_release is only implemented for SImode.
1957 ;; For other modes, just use the default of a store with a memory_barrier.
1958 (define_insn "sync_lock_releasesi"
1959   [(set (match_operand:SI 0 "mem_operand" "=U")
1960         (unspec_volatile:SI
1961           [(match_operand:SI 1 "register_operand" "r")]
1962           UNSPECV_S32RI))]
1963   "TARGET_RELEASE_SYNC"
1964   "s32ri\t%1, %0"
1965   [(set_attr "type"     "store")
1966    (set_attr "mode"     "SI")
1967    (set_attr "length"   "3")])
1969 (define_insn "sync_compare_and_swapsi"
1970   [(parallel
1971     [(set (match_operand:SI 0 "register_operand" "=a")
1972           (match_operand:SI 1 "mem_operand" "+U"))
1973      (set (match_dup 1)
1974           (unspec_volatile:SI
1975             [(match_dup 1)
1976              (match_operand:SI 2 "register_operand" "r")
1977              (match_operand:SI 3 "register_operand" "0")]
1978             UNSPECV_S32C1I))])]
1979   "TARGET_S32C1I"
1980   "wsr\t%2, SCOMPARE1\;s32c1i\t%3, %1"
1981   [(set_attr "type"     "multi")
1982    (set_attr "mode"     "SI")
1983    (set_attr "length"   "6")])
1985 (define_expand "sync_compare_and_swap<mode>"
1986   [(parallel
1987     [(set (match_operand:HQI 0 "register_operand" "")
1988           (match_operand:HQI 1 "mem_operand" ""))
1989      (set (match_dup 1)
1990           (unspec_volatile:HQI
1991             [(match_dup 1)
1992              (match_operand:HQI 2 "register_operand" "")
1993              (match_operand:HQI 3 "register_operand" "")]
1994             UNSPECV_S32C1I))])]
1995   "TARGET_S32C1I"
1997   xtensa_expand_compare_and_swap (operands[0], operands[1],
1998                                   operands[2], operands[3]);
1999   DONE;
2002 (define_expand "sync_lock_test_and_set<mode>"
2003   [(match_operand:HQI 0 "register_operand")
2004    (match_operand:HQI 1 "memory_operand")
2005    (match_operand:HQI 2 "register_operand")]
2006   "TARGET_S32C1I"
2008   xtensa_expand_atomic (SET, operands[0], operands[1], operands[2], false);
2009   DONE;
2012 (define_expand "sync_<atomic><mode>"
2013   [(set (match_operand:HQI 0 "memory_operand")
2014         (ATOMIC:HQI (match_dup 0)
2015                     (match_operand:HQI 1 "register_operand")))]
2016   "TARGET_S32C1I"
2018   xtensa_expand_atomic (<CODE>, NULL_RTX, operands[0], operands[1], false);
2019   DONE;
2022 (define_expand "sync_old_<atomic><mode>"
2023   [(set (match_operand:HQI 0 "register_operand")
2024         (match_operand:HQI 1 "memory_operand"))
2025    (set (match_dup 1)
2026         (ATOMIC:HQI (match_dup 1)
2027                     (match_operand:HQI 2 "register_operand")))]
2028   "TARGET_S32C1I"
2030   xtensa_expand_atomic (<CODE>, operands[0], operands[1], operands[2], false);
2031   DONE;
2034 (define_expand "sync_new_<atomic><mode>"
2035   [(set (match_operand:HQI 0 "register_operand")
2036         (ATOMIC:HQI (match_operand:HQI 1 "memory_operand")
2037                     (match_operand:HQI 2 "register_operand"))) 
2038    (set (match_dup 1) (ATOMIC:HQI (match_dup 1) (match_dup 2)))]
2039   "TARGET_S32C1I"
2041   xtensa_expand_atomic (<CODE>, operands[0], operands[1], operands[2], true);
2042   DONE;