Add gfc_class_set_vptr.
[official-gcc.git] / gcc / config / xtensa / xtensa.md
blob8709ef6d7a7dca196e509bd25e2505cbaf4acd77
1 ;; GCC machine description for Tensilica's Xtensa architecture.
2 ;; Copyright (C) 2001-2024 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)
30 (define_c_enum "unspec" [
31   UNSPEC_NOP
32   UNSPEC_PLT
33   UNSPEC_RET_ADDR
34   UNSPEC_TPOFF
35   UNSPEC_DTPOFF
36   UNSPEC_TLS_FUNC
37   UNSPEC_TLS_ARG
38   UNSPEC_TLS_CALL
39   UNSPEC_TP
40   UNSPEC_MEMW
41   UNSPEC_LSETUP_START
42   UNSPEC_LSETUP_END
43   UNSPEC_FRAME_BLOCKAGE
46 (define_c_enum "unspecv" [
47   UNSPECV_SET_FP
48   UNSPECV_ENTRY
49   UNSPECV_S32RI
50   UNSPECV_S32C1I
51   UNSPECV_EH_RETURN
52   UNSPECV_SET_TP
53   UNSPECV_BLOCKAGE
56 ;; This code iterator allows signed and unsigned widening multiplications
57 ;; to use the same template.
58 (define_code_iterator any_extend [sign_extend zero_extend])
60 ;; <u> expands to an empty string when doing a signed operation and
61 ;; "u" when doing an unsigned operation.
62 (define_code_attr u [(sign_extend "") (zero_extend "u")])
64 ;; <su> is like <u>, but the signed form expands to "s" rather than "".
65 (define_code_attr su [(sign_extend "s") (zero_extend "u")])
67 ;; This code iterator allows four integer min/max operations to be
68 ;; generated from one template.
69 (define_code_iterator any_minmax [smin umin smax umax])
71 ;; <minmax> expands to the opcode name for any_minmax operations.
72 (define_code_attr minmax [(smin "min") (umin "minu")
73                           (smax "max") (umax "maxu")])
75 ;; This code iterator is for floating-point comparisons.
76 (define_code_iterator any_scc_sf [eq lt le uneq unlt unle unordered])
77 (define_code_attr scc_sf [(eq "oeq") (lt "olt") (le "ole")
78                           (uneq "ueq") (unlt "ult") (unle "ule")
79                           (unordered "un")])
81 ;; This iterator and attribute allow to combine most atomic operations.
82 (define_code_iterator ATOMIC [and ior xor plus minus mult])
83 (define_code_attr atomic [(and "and") (ior "ior") (xor "xor")
84                           (plus "add") (minus "sub") (mult "nand")])
86 ;; This mode iterator allows the HI and QI patterns to be defined from
87 ;; the same template.
88 (define_mode_iterator HQI [HI QI])
90 ;; This mode iterator allows the SI and HI patterns to be defined from
91 ;; the same template.
92 (define_mode_iterator SHI [SI HI])
95 ;; Attributes.
97 (define_attr "type"
98   "unknown,jump,call,load,store,move,arith,multi,nop,farith,fmadd,fconv,fload,fstore,mul16,mul32,div32,mac16,rsr,wsr,entry,trap"
99   (const_string "unknown"))
101 (define_attr "mode"
102   "unknown,none,QI,HI,SI,DI,SF,DF,BL"
103   (const_string "unknown"))
105 (define_attr "length" "" (const_int 1))
107 ;; Describe a user's asm statement.
108 (define_asm_attributes
109   [(set_attr "type"     "multi")
110    (set_attr "mode"     "none")
111    (set_attr "length"   "3")])  ;; Should be the maximum possible length
112                                 ;; of a single machine instruction.
115 ;; Pipeline model.
117 ;; The Xtensa basically has simple 5-stage RISC pipeline.
118 ;; Most instructions complete in 1 cycle, and it is OK to assume that
119 ;; everything is fully pipelined.  The exceptions have special insn
120 ;; reservations in the pipeline description below.  The Xtensa can
121 ;; issue one instruction per cycle, so defining CPU units is unnecessary.
123 (define_insn_reservation "xtensa_any_insn" 1
124                          (eq_attr "type" "!load,fload,rsr,mul16,mul32,fmadd,fconv")
125                          "nothing")
127 (define_insn_reservation "xtensa_memory" 2
128                          (eq_attr "type" "load,fload")
129                          "nothing")
131 (define_insn_reservation "xtensa_sreg" 2
132                          (eq_attr "type" "rsr")
133                          "nothing")
135 (define_insn_reservation "xtensa_mul16" 2
136                          (eq_attr "type" "mul16")
137                          "nothing")
139 (define_insn_reservation "xtensa_mul32" 2
140                          (eq_attr "type" "mul32")
141                          "nothing")
143 (define_insn_reservation "xtensa_fmadd" 4
144                          (eq_attr "type" "fmadd")
145                          "nothing")
147 (define_insn_reservation "xtensa_fconv" 2
148                          (eq_attr "type" "fconv")
149                          "nothing")
151 ;; Include predicates and constraints.
153 (include "predicates.md")
154 (include "constraints.md")
157 ;; Addition.
159 (define_insn "addsi3"
160   [(set (match_operand:SI 0 "register_operand" "=D,D,a,a,a")
161         (plus:SI (match_operand:SI 1 "register_operand" "%d,d,r,r,r")
162                  (match_operand:SI 2 "add_operand" "d,O,r,J,N")))]
163   ""
164   "@
165    add.n\t%0, %1, %2
166    addi.n\t%0, %1, %d2
167    add\t%0, %1, %2
168    addi\t%0, %1, %d2
169    addmi\t%0, %1, %x2"
170   [(set_attr "type"     "arith,arith,arith,arith,arith")
171    (set_attr "mode"     "SI")
172    (set_attr "length"   "2,2,3,3,3")])
174 (define_insn "*addsubx"
175   [(set (match_operand:SI 0 "register_operand" "=a")
176         (match_operator:SI 4 "addsub_operator"
177                 [(ashift:SI (match_operand:SI 1 "register_operand" "r")
178                             (match_operand:SI 3 "addsubx_operand" "i"))
179                  (match_operand:SI 2 "register_operand" "r")]))]
180   "TARGET_ADDX"
182   operands[3] = GEN_INT (1 << INTVAL (operands[3]));
183   return GET_CODE (operands[4]) == PLUS
184           ? "addx%3\t%0, %1, %2" : "subx%3\t%0, %1, %2";
186   [(set_attr "type"     "arith")
187    (set_attr "mode"     "SI")
188    (set_attr "length"   "3")])
190 (define_split
191   [(set (match_operand:SI 0 "register_operand")
192         (plus:SI (ashift:SI (match_operand:SI 1 "register_operand")
193                             (match_operand:SI 3 "addsubx_operand"))
194                  (match_operand:SI 2 "const_int_operand")))]
195   "TARGET_ADDX && can_create_pseudo_p ()"
196   [(set (match_dup 0)
197         (plus:SI (ashift:SI (match_dup 1)
198                             (match_dup 3))
199                  (match_dup 2)))]
201   operands[2] = force_reg (SImode, operands[2]);
204 (define_expand "adddi3"
205   [(set (match_operand:DI 0 "register_operand")
206         (plus:DI (match_operand:DI 1 "register_operand")
207                  (match_operand:DI 2 "register_operand")))]
208   ""
210   rtx lo_dest, hi_dest, lo_op0, hi_op0, lo_op1, hi_op1;
211   rtx_code_label *label;
212   if (rtx_equal_p (operands[0], operands[1])
213       || rtx_equal_p (operands[0], operands[2])
214       || ! REG_P (operands[1]) || ! REG_P (operands[2]))
215     FAIL;
216   lo_dest = gen_lowpart (SImode, operands[0]);
217   hi_dest = gen_highpart (SImode, operands[0]);
218   lo_op0 = gen_lowpart (SImode, operands[1]);
219   hi_op0 = gen_highpart (SImode, operands[1]);
220   lo_op1 = gen_lowpart (SImode, operands[2]);
221   hi_op1 = gen_highpart (SImode, operands[2]);
222   emit_insn (gen_addsi3 (hi_dest, hi_op0, hi_op1));
223   emit_insn (gen_addsi3 (lo_dest, lo_op0, lo_op1));
224   emit_cmp_and_jump_insns (lo_dest,
225                            (REGNO (operands[1]) < REGNO (operands[2])
226                             ? lo_op1 : lo_op0), GEU, const0_rtx,
227                            SImode, true, label = gen_label_rtx ());
228   emit_insn (gen_addsi3 (hi_dest, hi_dest, const1_rtx));
229   emit_label (label);
230   DONE;
233 (define_insn "addsf3"
234   [(set (match_operand:SF 0 "register_operand" "=f")
235         (plus:SF (match_operand:SF 1 "register_operand" "%f")
236                  (match_operand:SF 2 "register_operand" "f")))]
237   "TARGET_HARD_FLOAT"
238   "add.s\t%0, %1, %2"
239   [(set_attr "type"     "fmadd")
240    (set_attr "mode"     "SF")
241    (set_attr "length"   "3")])
244 ;; Subtraction.
246 (define_insn "subsi3"
247   [(set (match_operand:SI 0 "register_operand" "=a")
248         (minus:SI (match_operand:SI 1 "register_operand" "r")
249                   (match_operand:SI 2 "register_operand" "r")))]
250   ""
251   "sub\t%0, %1, %2"
252   [(set_attr "type"     "arith")
253    (set_attr "mode"     "SI")
254    (set_attr "length"   "3")])
256 (define_insn_and_split "*subsi3_from_const"
257   [(set (match_operand:SI 0 "register_operand" "=a")
258         (minus:SI (match_operand:SI 1 "const_int_operand" "i")
259                   (match_operand:SI 2 "register_operand" "r")))]
260   "xtensa_simm8 (-INTVAL (operands[1]))
261    || xtensa_simm8x256 (-INTVAL (operands[1]))"
262   "#"
263   "&& 1"
264   [(set (match_dup 0)
265         (plus:SI (match_dup 2)
266                  (match_dup 1)))
267    (set (match_dup 0)
268         (neg:SI (match_dup 0)))]
270   operands[1] = GEN_INT (-INTVAL (operands[1]));
272   [(set_attr "type"     "arith")
273    (set_attr "mode"     "SI")
274    (set (attr "length")
275         (if_then_else (match_test "TARGET_DENSITY
276                                    && xtensa_m1_or_1_thru_15 (-INTVAL (operands[1]))")
277                       (const_int 5)
278                       (const_int 6)))])
280 (define_expand "subdi3"
281   [(set (match_operand:DI 0 "register_operand")
282         (minus:DI (match_operand:DI 1 "register_operand")
283                   (match_operand:DI 2 "register_operand")))]
284   ""
286   rtx lo_dest, hi_dest, lo_op0, hi_op0, lo_op1, hi_op1;
287   rtx_code_label *label;
288   lo_dest = gen_lowpart (SImode, operands[0]);
289   hi_dest = gen_highpart (SImode, operands[0]);
290   lo_op0 = gen_lowpart (SImode, operands[1]);
291   hi_op0 = gen_highpart (SImode, operands[1]);
292   lo_op1 = gen_lowpart (SImode, operands[2]);
293   hi_op1 = gen_highpart (SImode, operands[2]);
294   emit_insn (gen_subsi3 (hi_dest, hi_op0, hi_op1));
295   emit_cmp_and_jump_insns (lo_op0, lo_op1, GEU, const0_rtx,
296                            SImode, true, label = gen_label_rtx ());
297   emit_insn (gen_addsi3 (hi_dest, hi_dest, constm1_rtx));
298   emit_label (label);
299   emit_insn (gen_subsi3 (lo_dest, lo_op0, lo_op1));
300   DONE;
303 (define_insn "subsf3"
304   [(set (match_operand:SF 0 "register_operand" "=f")
305         (minus:SF (match_operand:SF 1 "register_operand" "f")
306                   (match_operand:SF 2 "register_operand" "f")))]
307   "TARGET_HARD_FLOAT"
308   "sub.s\t%0, %1, %2"
309   [(set_attr "type"     "fmadd")
310    (set_attr "mode"     "SF")
311    (set_attr "length"   "3")])
314 ;; Multiplication.
316 (define_expand "mulsidi3"
317   [(set (match_operand:DI 0 "register_operand")
318         (mult:DI (sign_extend:DI (match_operand:SI 1 "register_operand"))
319                  (sign_extend:DI (match_operand:SI 2 "register_operand"))))]
320   "TARGET_MUL32_HIGH"
322   rtx temp = gen_reg_rtx (SImode);
323   emit_insn (gen_mulsi3 (temp, operands[1], operands[2]));
324   emit_insn (gen_mulsi3_highpart (gen_highpart (SImode, operands[0]),
325                                   operands[1], operands[2]));
326   emit_insn (gen_movsi (gen_lowpart (SImode, operands[0]), temp));
327   DONE;
330 (define_expand "umulsidi3"
331   [(set (match_operand:DI 0 "register_operand")
332         (mult:DI (zero_extend:DI (match_operand:SI 1 "register_operand"))
333                  (zero_extend:DI (match_operand:SI 2 "register_operand"))))]
334   ""
336   if (TARGET_MUL32_HIGH)
337     {
338       rtx temp = gen_reg_rtx (SImode);
339       emit_insn (gen_mulsi3 (temp, operands[1], operands[2]));
340       emit_insn (gen_umulsi3_highpart (gen_highpart (SImode, operands[0]),
341                                        operands[1], operands[2]));
342       emit_insn (gen_movsi (gen_lowpart (SImode, operands[0]), temp));
343     }
344   else
345     emit_library_call_value (gen_rtx_SYMBOL_REF (Pmode, "__umulsidi3"),
346                              operands[0], LCT_NORMAL, DImode,
347                              operands[1], SImode,
348                              operands[2], SImode);
349    DONE;
352 (define_insn "<u>mulsi3_highpart"
353   [(set (match_operand:SI 0 "register_operand" "=a")
354         (truncate:SI
355          (lshiftrt:DI
356           (mult:DI (any_extend:DI (match_operand:SI 1 "register_operand" "%r"))
357                    (any_extend:DI (match_operand:SI 2 "register_operand" "r")))
358           (const_int 32))))]
359   "TARGET_MUL32_HIGH"
360   "mul<su>h\t%0, %1, %2"
361   [(set_attr "type"     "mul32")
362    (set_attr "mode"     "SI")
363    (set_attr "length"   "3")])
365 (define_insn "mulsi3"
366   [(set (match_operand:SI 0 "register_operand" "=a")
367         (mult:SI (match_operand:SI 1 "register_operand" "%r")
368                  (match_operand:SI 2 "register_operand" "r")))]
369   "TARGET_MUL32"
370   "mull\t%0, %1, %2"
371   [(set_attr "type"     "mul32")
372    (set_attr "mode"     "SI")
373    (set_attr "length"   "3")])
375 (define_insn "<u>mulhisi3"
376   [(set (match_operand:SI 0 "register_operand" "=C,A")
377         (mult:SI (any_extend:SI
378                   (match_operand:HI 1 "register_operand" "%r,r"))
379                  (any_extend:SI
380                   (match_operand:HI 2 "register_operand" "r,r"))))]
381   "TARGET_MUL16 || TARGET_MAC16"
382   "@
383    mul16<su>\t%0, %1, %2
384    <u>mul.aa.ll\t%1, %2"
385   [(set_attr "type"     "mul16,mac16")
386    (set_attr "mode"     "SI")
387    (set_attr "length"   "3,3")])
389 (define_insn "muladdhisi"
390   [(set (match_operand:SI 0 "register_operand" "=A")
391         (plus:SI (mult:SI (sign_extend:SI
392                            (match_operand:HI 1 "register_operand" "%r"))
393                           (sign_extend:SI
394                            (match_operand:HI 2 "register_operand" "r")))
395                  (match_operand:SI 3 "register_operand" "0")))]
396   "TARGET_MAC16"
397   "mula.aa.ll\t%1, %2"
398   [(set_attr "type"     "mac16")
399    (set_attr "mode"     "SI")
400    (set_attr "length"   "3")])
402 (define_insn "mulsubhisi"
403   [(set (match_operand:SI 0 "register_operand" "=A")
404         (minus:SI (match_operand:SI 1 "register_operand" "0")
405                   (mult:SI (sign_extend:SI
406                             (match_operand:HI 2 "register_operand" "%r"))
407                            (sign_extend:SI
408                             (match_operand:HI 3 "register_operand" "r")))))]
409   "TARGET_MAC16"
410   "muls.aa.ll\t%2, %3"
411   [(set_attr "type"     "mac16")
412    (set_attr "mode"     "SI")
413    (set_attr "length"   "3")])
415 (define_insn "mulsf3"
416   [(set (match_operand:SF 0 "register_operand" "=f")
417         (mult:SF (match_operand:SF 1 "register_operand" "%f")
418                  (match_operand:SF 2 "register_operand" "f")))]
419   "TARGET_HARD_FLOAT"
420   "mul.s\t%0, %1, %2"
421   [(set_attr "type"     "fmadd")
422    (set_attr "mode"     "SF")
423    (set_attr "length"   "3")])
425 (define_insn "fmasf4"
426   [(set (match_operand:SF 0 "register_operand" "=f")
427         (fma:SF (match_operand:SF 1 "register_operand" "f")
428                 (match_operand:SF 2 "register_operand" "f")
429                 (match_operand:SF 3 "register_operand" "0")))]
430   "TARGET_HARD_FLOAT"
431   "madd.s\t%0, %1, %2"
432   [(set_attr "type"     "fmadd")
433    (set_attr "mode"     "SF")
434    (set_attr "length"   "3")])
436 ;; Note that (C - A*B) = (-A*B + C)
437 (define_insn "fnmasf4"
438   [(set (match_operand:SF 0 "register_operand" "=f")
439         (fma:SF (neg:SF (match_operand:SF 1 "register_operand" "f"))
440                 (match_operand:SF 2 "register_operand" "f")
441                 (match_operand:SF 3 "register_operand" "0")))]
442   "TARGET_HARD_FLOAT"
443   "msub.s\t%0, %1, %2"
444   [(set_attr "type"     "fmadd")
445    (set_attr "mode"     "SF")
446    (set_attr "length"   "3")])
449 ;; Division.
451 (define_insn "divsi3"
452   [(set (match_operand:SI 0 "register_operand" "=a")
453         (div:SI (match_operand:SI 1 "register_operand" "r")
454                 (match_operand:SI 2 "register_operand" "r")))]
455   "TARGET_DIV32"
456   "quos\t%0, %1, %2"
457   [(set_attr "type"     "div32")
458    (set_attr "mode"     "SI")
459    (set_attr "length"   "3")])
461 (define_insn "udivsi3"
462   [(set (match_operand:SI 0 "register_operand" "=a")
463         (udiv:SI (match_operand:SI 1 "register_operand" "r")
464                  (match_operand:SI 2 "register_operand" "r")))]
465   "TARGET_DIV32"
466   "quou\t%0, %1, %2"
467   [(set_attr "type"     "div32")
468    (set_attr "mode"     "SI")
469    (set_attr "length"   "3")])
472 ;; Remainders.
474 (define_insn "modsi3"
475   [(set (match_operand:SI 0 "register_operand" "=a")
476         (mod:SI (match_operand:SI 1 "register_operand" "r")
477                 (match_operand:SI 2 "register_operand" "r")))]
478   "TARGET_DIV32"
479   "rems\t%0, %1, %2"
480   [(set_attr "type"     "div32")
481    (set_attr "mode"     "SI")
482    (set_attr "length"   "3")])
484 (define_insn "umodsi3"
485   [(set (match_operand:SI 0 "register_operand" "=a")
486         (umod:SI (match_operand:SI 1 "register_operand" "r")
487                  (match_operand:SI 2 "register_operand" "r")))]
488   "TARGET_DIV32"
489   "remu\t%0, %1, %2"
490   [(set_attr "type"     "div32")
491    (set_attr "mode"     "SI")
492    (set_attr "length"   "3")])
495 ;; Absolute value.
497 (define_insn "abssi2"
498   [(set (match_operand:SI 0 "register_operand" "=a")
499         (abs:SI (match_operand:SI 1 "register_operand" "r")))]
500   "TARGET_ABS"
501   "abs\t%0, %1"
502   [(set_attr "type"     "arith")
503    (set_attr "mode"     "SI")
504    (set_attr "length"   "3")])
506 (define_insn "abssf2"
507   [(set (match_operand:SF 0 "register_operand" "=f")
508         (abs:SF (match_operand:SF 1 "register_operand" "f")))]
509   "TARGET_HARD_FLOAT"
510   "abs.s\t%0, %1"
511   [(set_attr "type"     "farith")
512    (set_attr "mode"     "SF")
513    (set_attr "length"   "3")])
516 ;; Min and max.
518 (define_insn "<code>si3"
519   [(set (match_operand:SI 0 "register_operand" "=a")
520         (any_minmax:SI (match_operand:SI 1 "register_operand" "%r")
521                        (match_operand:SI 2 "register_operand" "r")))]
522   "TARGET_MINMAX"
523   "<minmax>\t%0, %1, %2"
524   [(set_attr "type"     "arith")
525    (set_attr "mode"     "SI")
526    (set_attr "length"   "3")])
529 ;; Signed clamp.
531 (define_insn "*xtensa_clamps"
532   [(set (match_operand:SI 0 "register_operand" "=a")
533         (match_operator:SI 5 "xtensa_sminmax_operator"
534           [(match_operator:SI 4 "xtensa_sminmax_operator"
535             [(match_operand:SI 1 "register_operand" "r")
536              (match_operand:SI 2 "const_int_operand" "i")])
537            (match_operand:SI 3 "const_int_operand" "i")]))]
538   "TARGET_MINMAX && TARGET_CLAMPS
539    && INTVAL (operands[2]) + INTVAL (operands[3]) == -1
540    && ((GET_CODE (operands[5]) == SMIN && GET_CODE (operands[4]) == SMAX
541         && IN_RANGE (exact_log2 (-INTVAL (operands[2])), 7, 22))
542        || (GET_CODE (operands[5]) == SMAX && GET_CODE (operands[4]) == SMIN
543            && IN_RANGE (exact_log2 (-INTVAL (operands[3])), 7, 22)))"
545   static char result[64];
546   rtx bound = operands[GET_CODE (operands[4]) == SMAX ? 2 : 3];
547   sprintf (result, "clamps\t%%0, %%1, %d", floor_log2 (-INTVAL (bound)));
548   return result;
550   [(set_attr "type"     "arith")
551    (set_attr "mode"     "SI")
552    (set_attr "length"   "3")])
555 ;; Count redundant leading sign bits and leading/trailing zeros,
556 ;; and find first bit.
558 (define_insn "clrsbsi2"
559   [(set (match_operand:SI 0 "register_operand" "=a")
560         (clrsb:SI (match_operand:SI 1 "register_operand" "r")))]
561   "TARGET_NSA"
562   "nsa\t%0, %1"
563   [(set_attr "type"     "arith")
564    (set_attr "mode"     "SI")
565    (set_attr "length"   "3")])
567 (define_insn "clzsi2"
568   [(set (match_operand:SI 0 "register_operand" "=a")
569         (clz:SI (match_operand:SI 1 "register_operand" "r")))]
570   "TARGET_NSA"
571   "nsau\t%0, %1"
572   [(set_attr "type"     "arith")
573    (set_attr "mode"     "SI")
574    (set_attr "length"   "3")])
576 (define_expand "ctzsi2"
577   [(set (match_operand:SI 0 "register_operand" "")
578         (ctz:SI (match_operand:SI 1 "register_operand" "")))]
579   "TARGET_NSA"
581   rtx temp = gen_reg_rtx (SImode);
582   emit_insn (gen_negsi2 (temp, operands[1]));
583   emit_insn (gen_andsi3 (temp, temp, operands[1]));
584   emit_insn (gen_clzsi2 (temp, temp));
585   emit_move_insn (operands[0], GEN_INT (31));
586   emit_insn (gen_subsi3 (operands[0], operands[0], temp));
587   DONE;
590 (define_expand "ffssi2"
591   [(set (match_operand:SI 0 "register_operand" "")
592         (ffs:SI (match_operand:SI 1 "register_operand" "")))]
593   "TARGET_NSA"
595   rtx temp = gen_reg_rtx (SImode);
596   emit_insn (gen_negsi2 (temp, operands[1]));
597   emit_insn (gen_andsi3 (temp, temp, operands[1]));
598   emit_insn (gen_clzsi2 (temp, temp));
599   emit_move_insn (operands[0], GEN_INT (32));
600   emit_insn (gen_subsi3 (operands[0], operands[0], temp));
601   DONE;
605 ;; Byte swap.
607 (define_insn "bswaphi2"
608   [(set (match_operand:HI 0 "register_operand" "=a")
609         (bswap:HI (match_operand:HI 1 "register_operand" "r")))
610    (clobber (match_scratch:HI 2 "=&a"))]
611   ""
612   "extui\t%2, %1, 8, 8\;slli\t%0, %1, 8\;or\t%0, %0, %2"
613    [(set_attr "type"    "arith")
614     (set_attr "mode"    "HI")
615     (set_attr "length"  "9")])
617 (define_expand "bswapsi2"
618   [(set (match_operand:SI 0 "register_operand" "")
619         (bswap:SI (match_operand:SI 1 "register_operand" "")))]
620   "!optimize_debug && optimize > 1"
622   /* GIMPLE manual byte-swapping recognition is now activated.
623      For both built-in and manual bswaps, emit corresponding library call
624      if optimizing for size, or a series of dedicated machine instructions
625      if otherwise.  */
626   if (optimize_size)
627     emit_library_call_value (optab_libfunc (bswap_optab, SImode),
628                              operands[0], LCT_NORMAL, SImode,
629                              operands[1], SImode);
630   else
631     emit_insn (gen_bswapsi2_internal (operands[0], operands[1]));
632   DONE;
635 (define_insn "bswapsi2_internal"
636   [(set (match_operand:SI 0 "register_operand" "=a,&a")
637         (bswap:SI (match_operand:SI 1 "register_operand" "0,r")))
638    (clobber (match_scratch:SI 2 "=&a,X"))]
639   "!optimize_debug && optimize > 1 && !optimize_size"
641   rtx_insn *prev_insn = prev_nonnote_nondebug_insn (insn);
642   const char *init = "ssai\t8\;";
643   static char result[128];
644   if (prev_insn && NONJUMP_INSN_P (prev_insn))
645     {
646       rtx x = PATTERN (prev_insn);
647       if (GET_CODE (x) == PARALLEL && XVECLEN (x, 0) == 2
648           && GET_CODE (XVECEXP (x, 0, 0)) == SET
649           && GET_CODE (XVECEXP (x, 0, 1)) == CLOBBER)
650         {
651           x = XEXP (XVECEXP (x, 0, 0), 1);
652           if (GET_CODE (x) == BSWAP && GET_MODE (x) == SImode)
653             init = "";
654         }
655     }
656   sprintf (result,
657            (which_alternative == 0)
658            ? "%s" "srli\t%%2, %%1, 16\;src\t%%2, %%2, %%1\;src\t%%2, %%2, %%2\;src\t%%0, %%1, %%2"
659            : "%s" "srli\t%%0, %%1, 16\;src\t%%0, %%0, %%1\;src\t%%0, %%0, %%0\;src\t%%0, %%1, %%0",
660            init);
661   return result;
663    [(set_attr "type"    "arith,arith")
664     (set_attr "mode"    "SI")
665     (set_attr "length"  "15,15")])
667 (define_expand "bswapdi2"
668   [(set (match_operand:DI 0 "register_operand" "")
669         (bswap:DI (match_operand:DI 1 "register_operand" "")))]
670   "!optimize_debug && optimize > 1 && optimize_size"
672   /* Replace with a single DImode library call.
673      Without this, two SImode library calls are emitted.  */
674   emit_library_call_value (optab_libfunc (bswap_optab, DImode),
675                            operands[0], LCT_NORMAL, DImode,
676                            operands[1], DImode);
677   DONE;
681 ;; Negation and one's complement.
683 (define_insn "negsi2"
684   [(set (match_operand:SI 0 "register_operand" "=a")
685         (neg:SI (match_operand:SI 1 "register_operand" "r")))]
686   ""
687   "neg\t%0, %1"
688   [(set_attr "type"     "arith")
689    (set_attr "mode"     "SI")
690    (set_attr "length"   "3")])
692 (define_insn_and_split "one_cmplsi2"
693   [(set (match_operand:SI 0 "register_operand" "=a")
694         (not:SI (match_operand:SI 1 "register_operand" "r")))]
695   ""
696   "#"
697   "&& can_create_pseudo_p ()"
698   [(set (match_dup 2)
699         (const_int -1))
700    (set (match_dup 0)
701         (xor:SI (match_dup 1)
702                 (match_dup 2)))]
704   operands[2] = gen_reg_rtx (SImode);
706   [(set_attr "type"     "arith")
707    (set_attr "mode"     "SI")
708    (set (attr "length")
709         (if_then_else (match_test "TARGET_DENSITY")
710                       (const_int 5)
711                       (const_int 6)))])
713 (define_insn "negsf2"
714   [(set (match_operand:SF 0 "register_operand" "=f")
715         (neg:SF (match_operand:SF 1 "register_operand" "f")))]
716   "TARGET_HARD_FLOAT"
717   "neg.s\t%0, %1"
718   [(set_attr "type"     "farith")
719    (set_attr "mode"     "SF")
720    (set_attr "length"   "3")])
723 ;; Logical instructions.
725 (define_insn "andsi3"
726   [(set (match_operand:SI 0 "register_operand" "=a,a")
727         (and:SI (match_operand:SI 1 "register_operand" "%r,r")
728                 (match_operand:SI 2 "mask_operand" "P,r")))]
729   ""
730   "@
731    extui\t%0, %1, 0, %K2
732    and\t%0, %1, %2"
733   [(set_attr "type"     "arith,arith")
734    (set_attr "mode"     "SI")
735    (set_attr "length"   "3,3")])
737 (define_insn_and_split "*andsi3_bitcmpl"
738   [(set (match_operand:SI 0 "register_operand" "=a")
739         (and:SI (not:SI (match_operand:SI 1 "register_operand" "r"))
740                 (match_operand:SI 2 "register_operand" "r")))]
741   ""
742   "#"
743   "&& can_create_pseudo_p ()"
744   [(set (match_dup 3)
745         (and:SI (match_dup 1)
746                 (match_dup 2)))
747    (set (match_dup 0)
748         (xor:SI (match_dup 3)
749                 (match_dup 2)))]
751   operands[3] = gen_reg_rtx (SImode);
753   [(set_attr "type"     "arith")
754    (set_attr "mode"     "SI")
755    (set_attr "length"   "6")])
757 (define_insn_and_split "*andsi3_const_pow2_minus_one"
758   [(set (match_operand:SI 0 "register_operand" "=a")
759         (and:SI (match_operand:SI 1 "register_operand" "r")
760                 (match_operand:SI 2 "const_int_operand" "i")))]
761   "IN_RANGE (exact_log2 (INTVAL (operands[2]) + 1), 17, 31)"
762   "#"
763   "&& 1"
764   [(set (match_dup 0)
765         (ashift:SI (match_dup 1)
766                    (match_dup 2)))
767    (set (match_dup 0)
768         (lshiftrt:SI (match_dup 0)
769                      (match_dup 2)))]
771   operands[2] = GEN_INT (32 - floor_log2 (INTVAL (operands[2]) + 1));
773   [(set_attr "type"     "arith")
774    (set_attr "mode"     "SI")
775    (set (attr "length")
776         (if_then_else (match_test "TARGET_DENSITY
777                                    && INTVAL (operands[2]) == 0x7FFFFFFF")
778                       (const_int 5)
779                       (const_int 6)))])
781 (define_insn_and_split "*andsi3_const_negative_pow2"
782   [(set (match_operand:SI 0 "register_operand" "=a")
783         (and:SI (match_operand:SI 1 "register_operand" "r")
784                 (match_operand:SI 2 "const_int_operand" "i")))]
785   "IN_RANGE (exact_log2 (-INTVAL (operands[2])), 12, 31)"
786   "#"
787   "&& 1"
788   [(set (match_dup 0)
789         (lshiftrt:SI (match_dup 1)
790                      (match_dup 2)))
791    (set (match_dup 0)
792         (ashift:SI (match_dup 0)
793                    (match_dup 2)))]
795   operands[2] = GEN_INT (floor_log2 (-INTVAL (operands[2])));
797   [(set_attr "type"     "arith")
798    (set_attr "mode"     "SI")
799    (set_attr "length"   "6")])
801 (define_insn_and_split "*andsi3_const_shifted_mask"
802   [(set (match_operand:SI 0 "register_operand" "=a")
803         (and:SI (match_operand:SI 1 "register_operand" "r")
804                 (match_operand:SI 2 "shifted_mask_operand" "i")))]
805   "! xtensa_simm12b (INTVAL (operands[2]))"
806   "#"
807   "&& 1"
808   [(set (match_dup 0)
809         (zero_extract:SI (match_dup 1)
810                          (match_dup 3)
811                          (match_dup 4)))
812    (set (match_dup 0)
813         (ashift:SI (match_dup 0)
814                    (match_dup 2)))]
816   HOST_WIDE_INT mask = INTVAL (operands[2]);
817   int shift = ctz_hwi (mask);
818   int mask_size = floor_log2 (((uint32_t)mask >> shift) + 1);
819   int mask_pos = shift;
820   if (BITS_BIG_ENDIAN)
821     mask_pos = (32 - (mask_size + shift)) & 0x1f;
822   operands[2] = GEN_INT (shift);
823   operands[3] = GEN_INT (mask_size);
824   operands[4] = GEN_INT (mask_pos);
826   [(set_attr "type"     "arith")
827    (set_attr "mode"     "SI")
828    (set (attr "length")
829         (if_then_else (match_test "TARGET_DENSITY
830                                    && ctz_hwi (INTVAL (operands[2])) == 1")
831                       (const_int 5)
832                       (const_int 6)))])
834 (define_insn "iorsi3"
835   [(set (match_operand:SI 0 "register_operand" "=a")
836         (ior:SI (match_operand:SI 1 "register_operand" "%r")
837                 (match_operand:SI 2 "register_operand" "r")))]
838   ""
839   "or\t%0, %1, %2"
840   [(set_attr "type"     "arith")
841    (set_attr "mode"     "SI")
842    (set_attr "length"   "3")])
844 (define_expand "xorsi3"
845   [(set (match_operand:SI 0 "register_operand")
846         (xor:SI (match_operand:SI 1 "register_operand")
847                 (match_operand:SI 2 "nonmemory_operand")))]
848   ""
850   if (register_operand (operands[2], SImode))
851     emit_insn (gen_xorsi3_internal (operands[0], operands[1],
852                                     operands[2]));
853   else
854     {
855       rtx (*gen_op)(rtx, rtx, rtx);
856       if (TARGET_DENSITY
857           && CONST_INT_P (operands[2])
858           && INTVAL (operands[2]) == -2147483648L)
859         gen_op = gen_addsi3;
860       else
861         gen_op = gen_xorsi3_internal;
862       emit_insn (gen_op (operands[0], operands[1],
863                          force_reg (SImode, operands[2])));
864     }
865   DONE;
868 (define_insn "xorsi3_internal"
869   [(set (match_operand:SI 0 "register_operand" "=a")
870         (xor:SI (match_operand:SI 1 "register_operand" "%r")
871                 (match_operand:SI 2 "register_operand" "r")))]
872   ""
873   "xor\t%0, %1, %2"
874   [(set_attr "type"     "arith")
875    (set_attr "mode"     "SI")
876    (set_attr "length"   "3")])
878 (define_insn_and_split "*splice_bits"
879   [(set (match_operand:SI 0 "register_operand" "=a")
880         (ior:SI (and:SI (match_operand:SI 1 "register_operand" "r")
881                         (match_operand:SI 3 "const_int_operand" "i"))
882                 (and:SI (match_operand:SI 2 "register_operand" "r")
883                         (match_operand:SI 4 "const_int_operand" "i"))))]
885   "!optimize_debug && optimize
886    && INTVAL (operands[3]) + INTVAL (operands[4]) == -1
887    && (exact_log2 (INTVAL (operands[3]) + 1) > 16
888        || exact_log2 (INTVAL (operands[4]) + 1) > 16)"
889   "#"
890   "&& can_create_pseudo_p ()"
891   [(set (match_dup 5)
892         (ashift:SI (match_dup 1)
893                    (match_dup 4)))
894    (set (match_dup 6)
895         (lshiftrt:SI (match_dup 2)
896                      (match_dup 3)))
897    (set (match_dup 0)
898         (ior:SI (lshiftrt:SI (match_dup 5)
899                              (match_dup 4))
900                 (ashift:SI (match_dup 6)
901                            (match_dup 3))))]
903   int shift;
904   if (INTVAL (operands[3]) < 0)
905     {
906       rtx x;
907       x = operands[1], operands[1] = operands[2], operands[2] = x;
908       x = operands[3], operands[3] = operands[4], operands[4] = x;
909     }
910   shift = floor_log2 (INTVAL (operands[3]) + 1);
911   operands[3] = GEN_INT (shift);
912   operands[4] = GEN_INT (32 - shift);
913   operands[5] = gen_reg_rtx (SImode);
914   operands[6] = gen_reg_rtx (SImode);
916   [(set_attr "type"     "arith")
917    (set_attr "mode"     "SI")
918    (set (attr "length")
919         (if_then_else (match_test "TARGET_DENSITY
920                                    && (INTVAL (operands[3]) == 0x7FFFFFFF
921                                        || INTVAL (operands[4]) == 0x7FFFFFFF)")
922                       (const_int 11)
923                       (const_int 12)))])
926 ;; Zero-extend instructions.
928 (define_insn "zero_extendhisi2"
929   [(set (match_operand:SI 0 "register_operand" "=a,a")
930         (zero_extend:SI (match_operand:HI 1 "nonimmed_operand" "r,U")))]
931   ""
932   "@
933    extui\t%0, %1, 0, 16
934    %v1l16ui\t%0, %1"
935   [(set_attr "type"     "arith,load")
936    (set_attr "mode"     "SI")
937    (set_attr "length"   "3,3")])
939 (define_insn "zero_extendqisi2"
940   [(set (match_operand:SI 0 "register_operand" "=a,a")
941         (zero_extend:SI (match_operand:QI 1 "nonimmed_operand" "r,U")))]
942   ""
943   "@
944    extui\t%0, %1, 0, 8
945    %v1l8ui\t%0, %1"
946   [(set_attr "type"     "arith,load")
947    (set_attr "mode"     "SI")
948    (set_attr "length"   "3,3")])
951 ;; Sign-extend instructions.
953 (define_expand "extendhisi2"
954   [(set (match_operand:SI 0 "register_operand" "")
955         (sign_extend:SI (match_operand:HI 1 "register_operand" "")))]
956   ""
958   if (sext_operand (operands[1], HImode))
959     emit_insn (gen_extendhisi2_internal (operands[0], operands[1]));
960   else
961     xtensa_extend_reg (operands[0], operands[1]);
962   DONE;
965 (define_insn "extendhisi2_internal"
966   [(set (match_operand:SI 0 "register_operand" "=B,a")
967         (sign_extend:SI (match_operand:HI 1 "sext_operand" "r,U")))]
968   ""
969   "@
970    sext\t%0, %1, 15
971    %v1l16si\t%0, %1"
972   [(set_attr "type"     "arith,load")
973    (set_attr "mode"     "SI")
974    (set_attr "length"   "3,3")])
976 (define_expand "extendqisi2"
977   [(set (match_operand:SI 0 "register_operand" "")
978         (sign_extend:SI (match_operand:QI 1 "register_operand" "")))]
979   ""
981   if (TARGET_SEXT)
982     emit_insn (gen_extendqisi2_internal (operands[0], operands[1]));
983   else
984     xtensa_extend_reg (operands[0], operands[1]);
985   DONE;
988 (define_insn "extendqisi2_internal"
989   [(set (match_operand:SI 0 "register_operand" "=B")
990         (sign_extend:SI (match_operand:QI 1 "register_operand" "r")))]
991   "TARGET_SEXT"
992   "sext\t%0, %1, 7"
993   [(set_attr "type"     "arith")
994    (set_attr "mode"     "SI")
995    (set_attr "length"   "3")])
998 ;; Field extract instructions.
1000 (define_expand "extvsi"
1001   [(set (match_operand:SI 0 "register_operand" "")
1002         (sign_extract:SI (match_operand:SI 1 "register_operand" "")
1003                          (match_operand:SI 2 "const_int_operand" "")
1004                          (match_operand:SI 3 "const_int_operand" "")))]
1005   "TARGET_SEXT"
1007   if (!sext_fldsz_operand (operands[2], SImode))
1008     FAIL;
1010   /* We could expand to a right shift followed by SEXT but that's
1011      no better than the standard left and right shift sequence.  */
1012   if (!lsbitnum_operand (operands[3], SImode))
1013     FAIL;
1015   emit_insn (gen_extvsi_internal (operands[0], operands[1],
1016                                   operands[2], operands[3]));
1017   DONE;
1020 (define_insn "extvsi_internal"
1021   [(set (match_operand:SI 0 "register_operand" "=a")
1022         (sign_extract:SI (match_operand:SI 1 "register_operand" "r")
1023                          (match_operand:SI 2 "sext_fldsz_operand" "i")
1024                          (match_operand:SI 3 "lsbitnum_operand" "i")))]
1025   "TARGET_SEXT"
1027   int fldsz = INTVAL (operands[2]);
1028   operands[2] = GEN_INT (fldsz - 1);
1029   return "sext\t%0, %1, %2";
1031   [(set_attr "type"     "arith")
1032    (set_attr "mode"     "SI")
1033    (set_attr "length"   "3")])
1035 (define_expand "extzvsi"
1036   [(set (match_operand:SI 0 "register_operand" "")
1037         (zero_extract:SI (match_operand:SI 1 "register_operand" "")
1038                          (match_operand:SI 2 "const_int_operand" "")
1039                          (match_operand:SI 3 "const_int_operand" "")))]
1040   ""
1042   if (!extui_fldsz_operand (operands[2], SImode))
1043     FAIL;
1044   emit_insn (gen_extzvsi_internal (operands[0], operands[1],
1045                                    operands[2], operands[3]));
1046   DONE;
1049 (define_insn "extzvsi_internal"
1050   [(set (match_operand:SI 0 "register_operand" "=a")
1051         (zero_extract:SI (match_operand:SI 1 "register_operand" "r")
1052                          (match_operand:SI 2 "extui_fldsz_operand" "i")
1053                          (match_operand:SI 3 "const_int_operand" "i")))]
1054   ""
1056   int shift;
1057   if (BITS_BIG_ENDIAN)
1058     shift = (32 - (INTVAL (operands[2]) + INTVAL (operands[3]))) & 0x1f;
1059   else
1060     shift = INTVAL (operands[3]) & 0x1f;
1061   operands[3] = GEN_INT (shift);
1062   return "extui\t%0, %1, %3, %2";
1064   [(set_attr "type"     "arith")
1065    (set_attr "mode"     "SI")
1066    (set_attr "length"   "3")])
1068 (define_insn_and_split "*extzvsi-1bit_ashlsi3"
1069   [(set (match_operand:SI 0 "register_operand" "=a")
1070         (and:SI (match_operator:SI 4 "logical_shift_operator"
1071                         [(match_operand:SI 1 "register_operand" "r")
1072                          (match_operand:SI 2 "const_int_operand" "i")])
1073                 (match_operand:SI 3 "const_int_operand" "i")))]
1074   "exact_log2 (INTVAL (operands[3])) > 0"
1075   "#"
1076   "&& 1"
1077   [(set (match_dup 0)
1078         (zero_extract:SI (match_dup 1)
1079                          (const_int 1)
1080                          (match_dup 2)))
1081    (set (match_dup 0)
1082         (ashift:SI (match_dup 0)
1083                    (match_dup 3)))]
1085   int pos = INTVAL (operands[2]), shift = floor_log2 (INTVAL (operands[3]));
1086   pos = GET_CODE (operands[4]) == ASHIFT ? shift - pos : shift + pos;
1087   if (BITS_BIG_ENDIAN)
1088     pos = (32 - (1 + pos)) & 0x1f;
1089   operands[2] = GEN_INT (pos);
1090   operands[3] = GEN_INT (shift);
1092   [(set_attr "type"     "arith")
1093    (set_attr "mode"     "SI")
1094    (set (attr "length")
1095         (if_then_else (match_test "TARGET_DENSITY && INTVAL (operands[3]) == 2")
1096                       (const_int 5)
1097                       (const_int 6)))])
1099 (define_insn_and_split "*extzvsi-1bit_addsubx"
1100   [(set (match_operand:SI 0 "register_operand" "=a")
1101         (match_operator:SI 5 "addsub_operator"
1102                 [(and:SI (match_operator:SI 6 "logical_shift_operator"
1103                                 [(match_operand:SI 1 "register_operand" "r")
1104                                  (match_operand:SI 3 "const_int_operand" "i")])
1105                          (match_operand:SI 4 "const_int_operand" "i"))
1106                  (match_operand:SI 2 "register_operand" "r")]))]
1107   "TARGET_ADDX
1108    && IN_RANGE (exact_log2 (INTVAL (operands[4])), 1, 3)"
1109   "#"
1110   "&& 1"
1111   [(set (match_dup 0)
1112         (zero_extract:SI (match_dup 1)
1113                          (const_int 1)
1114                          (match_dup 3)))
1115    (set (match_dup 0)
1116         (match_op_dup 5
1117                 [(ashift:SI (match_dup 0)
1118                             (match_dup 4))
1119                  (match_dup 2)]))]
1121   int pos = INTVAL (operands[3]), shift = floor_log2 (INTVAL (operands[4]));
1122   pos = GET_CODE (operands[6]) == ASHIFT ? shift - pos : shift + pos;
1123   if (BITS_BIG_ENDIAN)
1124     pos = (32 - (1 + pos)) & 0x1f;
1125   operands[3] = GEN_INT (pos);
1126   operands[4] = GEN_INT (shift);
1128   [(set_attr "type"     "arith")
1129    (set_attr "mode"     "SI")
1130    (set_attr "length"   "6")])
1133 ;; Conversions.
1135 (define_insn "fix_truncsfsi2"
1136   [(set (match_operand:SI 0 "register_operand" "=a")
1137         (fix:SI (match_operand:SF 1 "register_operand" "f")))]
1138   "TARGET_HARD_FLOAT"
1139   "trunc.s\t%0, %1, 0"
1140   [(set_attr "type"     "fconv")
1141    (set_attr "mode"     "SF")
1142    (set_attr "length"   "3")])
1144 (define_insn "fixuns_truncsfsi2"
1145   [(set (match_operand:SI 0 "register_operand" "=a")
1146         (unsigned_fix:SI (match_operand:SF 1 "register_operand" "f")))]
1147   "TARGET_HARD_FLOAT"
1148   "utrunc.s\t%0, %1, 0"
1149   [(set_attr "type"     "fconv")
1150    (set_attr "mode"     "SF")
1151    (set_attr "length"   "3")])
1153 (define_insn "floatsisf2"
1154   [(set (match_operand:SF 0 "register_operand" "=f")
1155         (float:SF (match_operand:SI 1 "register_operand" "a")))]
1156   "TARGET_HARD_FLOAT"
1157   "float.s\t%0, %1, 0"
1158   [(set_attr "type"     "fconv")
1159    (set_attr "mode"     "SF")
1160    (set_attr "length"   "3")])
1162 (define_insn "floatunssisf2"
1163   [(set (match_operand:SF 0 "register_operand" "=f")
1164         (unsigned_float:SF (match_operand:SI 1 "register_operand" "a")))]
1165   "TARGET_HARD_FLOAT"
1166   "ufloat.s\t%0, %1, 0"
1167   [(set_attr "type"     "fconv")
1168    (set_attr "mode"     "SF")
1169    (set_attr "length"   "3")])
1172 ;; Data movement instructions.
1174 ;; 64-bit Integer moves
1176 (define_expand "movdi"
1177   [(set (match_operand:DI 0 "nonimmed_operand" "")
1178         (match_operand:DI 1 "general_operand" ""))]
1179   ""
1181   if (CONSTANT_P (operands[1]))
1182     {
1183       /* Split in halves if 64-bit Const-to-Reg moves
1184          because of offering further optimization opportunities.  */
1185       if (register_operand (operands[0], DImode))
1186         {
1187           rtx ops[4] = { operands[0], operands[1] };
1188           xtensa_split_DI_reg_imm (ops);
1189           emit_move_insn (ops[0], ops[1]);
1190           emit_move_insn (ops[2], ops[3]);
1191           DONE;
1192         }
1194       if (!TARGET_CONST16)
1195         operands[1] = force_const_mem (DImode, operands[1]);
1196     }
1198   if (!register_operand (operands[0], DImode)
1199       && !register_operand (operands[1], DImode))
1200     operands[1] = force_reg (DImode, operands[1]);
1202   operands[1] = xtensa_copy_incoming_a7 (operands[1]);
1205 (define_insn_and_split "movdi_internal"
1206   [(set (match_operand:DI 0 "nonimmed_operand" "=a,W,a,a,U")
1207         (match_operand:DI 1 "move_operand" "r,i,T,U,r"))]
1208   "register_operand (operands[0], DImode)
1209    || register_operand (operands[1], DImode)"
1210   "#"
1211   "&& reload_completed"
1212   [(set (match_dup 0) (match_dup 2))
1213    (set (match_dup 1) (match_dup 3))]
1215   xtensa_split_operand_pair (operands, SImode);
1216   if (reg_overlap_mentioned_p (operands[0], operands[3]))
1217     {
1218       rtx tmp;
1219       tmp = operands[0], operands[0] = operands[1], operands[1] = tmp;
1220       tmp = operands[2], operands[2] = operands[3], operands[3] = tmp;
1221     }
1224 (define_split
1225   [(set (match_operand:DI 0 "register_operand")
1226         (match_operand:DI 1 "const_int_operand"))]
1227   "!TARGET_CONST16
1228    && ! xtensa_split1_finished_p ()"
1229   [(set (match_dup 0)
1230         (match_dup 1))
1231    (set (match_dup 2)
1232         (match_dup 3))]
1234   xtensa_split_DI_reg_imm (operands);
1237 ;; 32-bit Integer moves
1239 (define_expand "movsi"
1240   [(set (match_operand:SI 0 "nonimmed_operand" "")
1241         (match_operand:SI 1 "general_operand" ""))]
1242   ""
1244   if (xtensa_emit_move_sequence (operands, SImode))
1245     DONE;
1248 (define_insn "movsi_internal"
1249   [(set (match_operand:SI 0 "nonimmed_operand" "=D,D,D,a,U,D,R,R,a,q,a,a,W,a,*a,*A")
1250         (match_operand:SI 1 "move_operand" "M,D,d,U,r,R,D,d,r,r,I,Y,i,T,*A,*r"))]
1251   "xtensa_valid_move (SImode, operands)"
1252   "@
1253    movi.n\t%0, %x1
1254    mov.n\t%0, %1
1255    mov.n\t%0, %1
1256    %v1l32i\t%0, %1
1257    %v0s32i\t%1, %0
1258    %v1l32i.n\t%0, %1
1259    %v0s32i.n\t%1, %0
1260    %v0s32i.n\t%1, %0
1261    mov\t%0, %1
1262    movsp\t%0, %1
1263    movi\t%0, %x1
1264    movi\t%0, %1
1265    const16\t%0, %t1\;const16\t%0, %b1
1266    %v1l32r\t%0, %1
1267    rsr\t%0, ACCLO
1268    wsr\t%1, ACCLO"
1269   [(set_attr "type"     "move,move,move,load,store,load,store,store,move,move,move,move,move,load,rsr,wsr")
1270    (set_attr "mode"     "SI")
1271    (set_attr "length"   "2,2,2,3,3,2,2,2,3,3,3,3,6,3,3,3")])
1273 (define_split
1274   [(set (match_operand:SHI 0 "register_operand")
1275         (match_operand:SHI 1 "const_int_operand"))]
1276   "!TARGET_CONST16 && !TARGET_AUTO_LITPOOLS
1277    && ! xtensa_split1_finished_p ()
1278    && ! xtensa_simm12b (INTVAL (operands[1]))"
1279   [(set (match_dup 0)
1280         (match_dup 1))]
1282   operands[1] = force_const_mem (<MODE>mode, operands[1]);
1285 (define_split
1286   [(set (match_operand:SHI 0 "register_operand")
1287         (match_operand:SHI 1 "constantpool_operand"))]
1288   "!optimize_debug && reload_completed"
1289   [(const_int 0)]
1291   if (xtensa_constantsynth (operands[0], operands[1]))
1292     DONE;
1293   FAIL;
1296 (define_split
1297   [(set (match_operand:SHI 0 "register_operand")
1298         (match_operand:SHI 1 "const_int_operand"))]
1299   "!optimize_debug && reload_completed
1300    && !TARGET_CONST16 && TARGET_AUTO_LITPOOLS
1301    && ! xtensa_simm12b (INTVAL (operands[1]))"
1302   [(const_int 0)]
1304   if (xtensa_constantsynth (operands[0], operands[1]))
1305     DONE;
1306   FAIL;
1309 ;; 16-bit Integer moves
1311 (define_expand "movhi"
1312   [(set (match_operand:HI 0 "nonimmed_operand" "")
1313         (match_operand:HI 1 "general_operand" ""))]
1314   ""
1316   if (xtensa_emit_move_sequence (operands, HImode))
1317     DONE;
1320 (define_insn "movhi_internal"
1321   [(set (match_operand:HI 0 "nonimmed_operand" "=D,D,a,a,a,a,a,U,*a,*A")
1322         (match_operand:HI 1 "move_operand" "M,d,r,I,Y,T,U,r,*A,*r"))]
1323   "xtensa_valid_move (HImode, operands)"
1324   "@
1325    movi.n\t%0, %x1
1326    mov.n\t%0, %1
1327    mov\t%0, %1
1328    movi\t%0, %x1
1329    movi\t%0, %1
1330    %v1l32r\t%0, %1
1331    %v1l16ui\t%0, %1
1332    %v0s16i\t%1, %0
1333    rsr\t%0, ACCLO
1334    wsr\t%1, ACCLO"
1335   [(set_attr "type"     "move,move,move,move,move,load,load,store,rsr,wsr")
1336    (set_attr "mode"     "HI")
1337    (set_attr "length"   "2,2,3,3,3,3,3,3,3,3")])
1339 ;; 8-bit Integer moves
1341 (define_expand "movqi"
1342   [(set (match_operand:QI 0 "nonimmed_operand" "")
1343         (match_operand:QI 1 "general_operand" ""))]
1344   ""
1346   if (xtensa_emit_move_sequence (operands, QImode))
1347     DONE;
1350 (define_insn "movqi_internal"
1351   [(set (match_operand:QI 0 "nonimmed_operand" "=D,D,a,a,a,U,*a,*A")
1352         (match_operand:QI 1 "move_operand" "M,d,r,I,U,r,*A,*r"))]
1353   "xtensa_valid_move (QImode, operands)"
1354   "@
1355    movi.n\t%0, %x1
1356    mov.n\t%0, %1
1357    mov\t%0, %1
1358    movi\t%0, %x1
1359    %v1l8ui\t%0, %1
1360    %v0s8i\t%1, %0
1361    rsr\t%0, ACCLO
1362    wsr\t%1, ACCLO"
1363   [(set_attr "type"     "move,move,move,move,load,store,rsr,wsr")
1364    (set_attr "mode"     "QI")
1365    (set_attr "length"   "2,2,3,3,3,3,3,3")])
1367 ;; Sub-word reloads from the constant pool.
1369 (define_expand "reload<mode>_literal"
1370   [(parallel [(match_operand:HQI 0 "register_operand" "=r")
1371               (match_operand:HQI 1 "constantpool_operand" "")
1372               (match_operand:SI 2 "register_operand" "=&r")])]
1373   ""
1375   rtx lit, scratch;
1376   unsigned word_off, byte_off;
1378   if (MEM_P (operands[1]))
1379     {
1380       lit = operands[1];
1381       word_off = 0;
1382       byte_off = 0;
1383     }
1384   else
1385     {
1386       gcc_assert (SUBREG_P (operands[1]));
1387       lit = SUBREG_REG (operands[1]);
1388       word_off = SUBREG_BYTE (operands[1]) & ~(UNITS_PER_WORD - 1);
1389       byte_off = SUBREG_BYTE (operands[1]) - word_off;
1390     }
1392   lit = adjust_address (lit, SImode, word_off);
1393   scratch = operands[2];
1394   emit_insn (gen_movsi (scratch, lit));
1395   emit_insn (gen_mov<mode> (operands[0],
1396                             gen_rtx_SUBREG (<MODE>mode, scratch, byte_off)));
1398   DONE;
1401 ;; 32-bit floating point moves
1403 (define_expand "movsf"
1404   [(set (match_operand:SF 0 "nonimmed_operand" "")
1405         (match_operand:SF 1 "general_operand" ""))]
1406   ""
1408   if (!TARGET_CONST16 && !TARGET_AUTO_LITPOOLS && CONSTANT_P (operands[1]))
1409     operands[1] = force_const_mem (SFmode, operands[1]);
1411   if ((!register_operand (operands[0], SFmode)
1412        && !register_operand (operands[1], SFmode))
1413       || (FP_REG_P (xt_true_regnum (operands[0]))
1414           && can_create_pseudo_p ()
1415           && (constantpool_mem_p (operands[1])
1416               || CONSTANT_P (operands[1]))))
1417     operands[1] = force_reg (SFmode, operands[1]);
1419   operands[1] = xtensa_copy_incoming_a7 (operands[1]);
1422 (define_insn "movsf_internal"
1423   [(set (match_operand:SF 0 "nonimmed_operand" "=f,f,U,D,D,R,a,f,a,a,W,a,a,U")
1424         (match_operand:SF 1 "move_operand" "f,U,f,d,R,d,r,r,f,Y,iF,T,U,r"))]
1425   "((register_operand (operands[0], SFmode)
1426      || register_operand (operands[1], SFmode))
1427     && !(FP_REG_P (xt_true_regnum (operands[0]))
1428          && (constantpool_mem_p (operands[1]) || CONSTANT_P (operands[1]))))"
1429   "@
1430    mov.s\t%0, %1
1431    %v1lsi\t%0, %1
1432    %v0ssi\t%1, %0
1433    mov.n\t%0, %1
1434    %v1l32i.n\t%0, %1
1435    %v0s32i.n\t%1, %0
1436    mov\t%0, %1
1437    wfr\t%0, %1
1438    rfr\t%0, %1
1439    movi\t%0, %y1
1440    const16\t%0, %t1\;const16\t%0, %b1
1441    %v1l32r\t%0, %1
1442    %v1l32i\t%0, %1
1443    %v0s32i\t%1, %0"
1444   [(set_attr "type"     "farith,fload,fstore,move,load,store,move,farith,farith,move,move,load,load,store")
1445    (set_attr "mode"     "SF")
1446    (set_attr "length"   "3,3,3,2,2,2,3,3,3,3,6,3,3,3")])
1448 (define_insn "*lsiu"
1449   [(set (match_operand:SF 0 "register_operand" "=f")
1450         (mem:SF (plus:SI (match_operand:SI 1 "register_operand" "+a")
1451                          (match_operand:SI 2 "fpmem_offset_operand" "i"))))
1452    (set (match_dup 1)
1453         (plus:SI (match_dup 1) (match_dup 2)))]
1454   "TARGET_HARD_FLOAT && !TARGET_HARD_FLOAT_POSTINC"
1456   if (TARGET_SERIALIZE_VOLATILE && volatile_refs_p (PATTERN (insn)))
1457     output_asm_insn ("memw", operands);
1458   return "lsiu\t%0, %1, %2";
1460   [(set_attr "type"     "fload")
1461    (set_attr "mode"     "SF")
1462    (set_attr "length"   "3")])
1464 (define_insn "*ssiu"
1465   [(set (mem:SF (plus:SI (match_operand:SI 0 "register_operand" "+a")
1466                          (match_operand:SI 1 "fpmem_offset_operand" "i")))
1467         (match_operand:SF 2 "register_operand" "f"))
1468    (set (match_dup 0)
1469         (plus:SI (match_dup 0) (match_dup 1)))]
1470   "TARGET_HARD_FLOAT && !TARGET_HARD_FLOAT_POSTINC"
1472   if (TARGET_SERIALIZE_VOLATILE && volatile_refs_p (PATTERN (insn)))
1473     output_asm_insn ("memw", operands);
1474   return "ssiu\t%2, %0, %1";
1476   [(set_attr "type"     "fstore")
1477    (set_attr "mode"     "SF")
1478    (set_attr "length"   "3")])
1480 (define_insn "*lsip"
1481   [(set (match_operand:SF 0 "register_operand" "=f")
1482         (mem:SF (match_operand:SI 1 "register_operand" "+a")))
1483    (set (match_dup 1)
1484         (plus:SI (match_dup 1)
1485                  (match_operand:SI 2 "fpmem_offset_operand" "i")))]
1486   "TARGET_HARD_FLOAT && TARGET_HARD_FLOAT_POSTINC"
1488   if (TARGET_SERIALIZE_VOLATILE && volatile_refs_p (PATTERN (insn)))
1489     output_asm_insn ("memw", operands);
1490   return "lsip\t%0, %1, %2";
1492   [(set_attr "type"     "fload")
1493    (set_attr "mode"     "SF")
1494    (set_attr "length"   "3")])
1496 (define_insn "*ssip"
1497   [(set (mem:SF (match_operand:SI 0 "register_operand" "+a"))
1498         (match_operand:SF 1 "register_operand" "f"))
1499    (set (match_dup 0)
1500         (plus:SI (match_dup 0)
1501                  (match_operand:SI 2 "fpmem_offset_operand" "i")))]
1502   "TARGET_HARD_FLOAT && TARGET_HARD_FLOAT_POSTINC"
1504   if (TARGET_SERIALIZE_VOLATILE && volatile_refs_p (PATTERN (insn)))
1505     output_asm_insn ("memw", operands);
1506   return "ssip\t%1, %0, %2";
1508   [(set_attr "type"     "fstore")
1509    (set_attr "mode"     "SF")
1510    (set_attr "length"   "3")])
1512 (define_split
1513   [(set (match_operand:SF 0 "register_operand")
1514         (match_operand 1 "constantpool_operand"))]
1515   "!optimize_debug && reload_completed"
1516   [(const_int 0)]
1518   if (xtensa_constantsynth (operands[0], operands[1]))
1519     DONE;
1520   FAIL;
1523 (define_split
1524   [(set (match_operand:SF 0 "register_operand")
1525         (match_operand 1 "const_double_operand"))]
1526   "!optimize_debug && reload_completed
1527    && !TARGET_CONST16 && TARGET_AUTO_LITPOOLS"
1528   [(const_int 0)]
1530   if (xtensa_constantsynth (operands[0], operands[1]))
1531     DONE;
1532   FAIL;
1535 ;; 64-bit floating point moves
1537 (define_expand "movdf"
1538   [(set (match_operand:DF 0 "nonimmed_operand" "")
1539         (match_operand:DF 1 "general_operand" ""))]
1540   ""
1542   if (CONSTANT_P (operands[1]) && !TARGET_CONST16 && !TARGET_AUTO_LITPOOLS)
1543     operands[1] = force_const_mem (DFmode, operands[1]);
1545   if (!register_operand (operands[0], DFmode)
1546       && !register_operand (operands[1], DFmode))
1547     operands[1] = force_reg (DFmode, operands[1]);
1549   operands[1] = xtensa_copy_incoming_a7 (operands[1]);
1552 (define_insn_and_split "movdf_internal"
1553   [(set (match_operand:DF 0 "nonimmed_operand" "=a,a,W,a,a,U")
1554         (match_operand:DF 1 "move_operand" "r,Y,iF,T,U,r"))]
1555   "register_operand (operands[0], DFmode)
1556    || register_operand (operands[1], DFmode)"
1557   "#"
1558   "&& reload_completed"
1559   [(set (match_dup 0) (match_dup 2))
1560    (set (match_dup 1) (match_dup 3))]
1562   xtensa_split_operand_pair (operands, SFmode);
1563   if (reg_overlap_mentioned_p (operands[0], operands[3]))
1564     {
1565       rtx tmp;
1566       tmp = operands[0], operands[0] = operands[1], operands[1] = tmp;
1567       tmp = operands[2], operands[2] = operands[3], operands[3] = tmp;
1568     }
1571 ;; Block moves
1573 (define_expand "cpymemsi"
1574   [(parallel [(set (match_operand:BLK 0 "" "")
1575                    (match_operand:BLK 1 "" ""))
1576               (use (match_operand:SI 2 "arith_operand" ""))
1577               (use (match_operand:SI 3 "const_int_operand" ""))])]
1578   ""
1580   if (!xtensa_expand_block_move (operands))
1581     FAIL;
1582   DONE;
1585 ;; Block sets
1587 (define_expand "setmemsi"
1588   [(match_operand:BLK 0 "memory_operand")
1589    (match_operand:SI 1 "")
1590    (match_operand:SI 2 "")
1591    (match_operand:SI 3 "const_int_operand")]
1592   "!optimize_debug && optimize"
1594   if (xtensa_expand_block_set (operands))
1595     DONE;
1596   FAIL;
1600 ;; Shift instructions.
1602 (define_expand "ashlsi3"
1603   [(set (match_operand:SI 0 "register_operand" "")
1604         (ashift:SI (match_operand:SI 1 "register_operand" "")
1605                    (match_operand:SI 2 "arith_operand" "")))]
1606   ""
1608   operands[1] = xtensa_copy_incoming_a7 (operands[1]);
1611 (define_insn "ashlsi3_internal"
1612   [(set (match_operand:SI 0 "register_operand" "=a,a")
1613         (ashift:SI (match_operand:SI 1 "register_operand" "r,r")
1614                    (match_operand:SI 2 "arith_operand" "J,r")))]
1615   ""
1616   "@
1617    slli\t%0, %1, %R2
1618    ssl\t%2\;sll\t%0, %1"
1619   [(set_attr "type"     "arith,arith")
1620    (set_attr "mode"     "SI")
1621    (set_attr "length"   "3,6")])
1623 (define_split
1624   [(set (match_operand:SI 0 "register_operand")
1625         (ashift:SI (match_operand:SI 1 "register_operand")
1626                    (const_int 1)))]
1627   "TARGET_DENSITY"
1628   [(set (match_dup 0)
1629         (plus:SI (match_dup 1)
1630                  (match_dup 1)))])
1632 (define_insn "ashrsi3"
1633   [(set (match_operand:SI 0 "register_operand" "=a,a")
1634         (ashiftrt:SI (match_operand:SI 1 "register_operand" "r,r")
1635                      (match_operand:SI 2 "arith_operand" "J,r")))]
1636   ""
1637   "@
1638    srai\t%0, %1, %R2
1639    ssr\t%2\;sra\t%0, %1"
1640   [(set_attr "type"     "arith,arith")
1641    (set_attr "mode"     "SI")
1642    (set_attr "length"   "3,6")])
1644 (define_insn "lshrsi3"
1645   [(set (match_operand:SI 0 "register_operand" "=a,a")
1646         (lshiftrt:SI (match_operand:SI 1 "register_operand" "r,r")
1647                      (match_operand:SI 2 "arith_operand" "J,r")))]
1648   ""
1650   if (which_alternative == 0)
1651     {
1652       if ((INTVAL (operands[2]) & 0x1f) < 16)
1653         return "srli\t%0, %1, %R2";
1654       else
1655         return "extui\t%0, %1, %R2, %L2";
1656     }
1657   return "ssr\t%2\;srl\t%0, %1";
1659   [(set_attr "type"     "arith,arith")
1660    (set_attr "mode"     "SI")
1661    (set_attr "length"   "3,6")])
1663 (define_insn "*shift_per_byte"
1664   [(set (match_operand:SI 0 "register_operand" "=a")
1665         (match_operator:SI 3 "xtensa_shift_per_byte_operator"
1666                 [(match_operand:SI 1 "register_operand" "r")
1667                  (ashift:SI (match_operand:SI 2 "register_operand" "r")
1668                             (const_int 3))]))]
1669   "!optimize_debug && optimize"
1671   switch (GET_CODE (operands[3]))
1672     {
1673     case ASHIFT:        return "ssa8b\t%2\;sll\t%0, %1";
1674     case ASHIFTRT:      return "ssa8l\t%2\;sra\t%0, %1";
1675     case LSHIFTRT:      return "ssa8l\t%2\;srl\t%0, %1";
1676     default:            gcc_unreachable ();
1677     }
1679   [(set_attr "type"     "arith")
1680    (set_attr "mode"     "SI")
1681    (set_attr "length"   "6")])
1683 (define_insn_and_split "*shift_per_byte_omit_AND_0"
1684   [(set (match_operand:SI 0 "register_operand" "=a")
1685         (match_operator:SI 4 "xtensa_shift_per_byte_operator"
1686                 [(match_operand:SI 1 "register_operand" "r")
1687                  (and:SI (ashift:SI (match_operand:SI 2 "register_operand" "r")
1688                                     (const_int 3))
1689                          (match_operand:SI 3 "const_int_operand" "i"))]))]
1690   "!optimize_debug && optimize
1691    && (INTVAL (operands[3]) & 0x1f) == 3 << 3"
1692   "#"
1693   "&& 1"
1694   [(set (match_dup 0)
1695         (match_op_dup 4
1696                 [(match_dup 1)
1697                  (ashift:SI (match_dup 2)
1698                             (const_int 3))]))]
1699   ""
1700   [(set_attr "type"     "arith")
1701    (set_attr "mode"     "SI")
1702    (set_attr "length"   "6")])
1704 (define_insn_and_split "*shift_per_byte_omit_AND_1"
1705   [(set (match_operand:SI 0 "register_operand" "=a")
1706         (match_operator:SI 4 "xtensa_shift_per_byte_operator"
1707                 [(match_operand:SI 1 "register_operand" "r")
1708                  (neg:SI (and:SI (ashift:SI (match_operand:SI 2 "register_operand" "r")
1709                                             (const_int 3))
1710                                  (match_operand:SI 3 "const_int_operand" "i")))]))]
1711   "!optimize_debug && optimize
1712    && (INTVAL (operands[3]) & 0x1f) == 3 << 3"
1713   "#"
1714   "&& can_create_pseudo_p ()"
1715   [(set (match_dup 5)
1716         (neg:SI (match_dup 2)))
1717    (set (match_dup 0)
1718         (match_op_dup 4
1719                 [(match_dup 1)
1720                  (ashift:SI (match_dup 5)
1721                             (const_int 3))]))]
1723   operands[5] = gen_reg_rtx (SImode);
1725   [(set_attr "type"     "arith")
1726    (set_attr "mode"     "SI")
1727    (set_attr "length"   "9")])
1729 (define_insn "*shlrd_reg"
1730   [(set (match_operand:SI 0 "register_operand" "=a")
1731         (match_operator:SI 6 "xtensa_bit_join_operator"
1732                 [(match_operator:SI 4 "logical_shift_operator"
1733                         [(match_operand:SI 1 "register_operand" "r")
1734                          (match_operand:SI 3 "register_operand" "r")])
1735                  (match_operator:SI 5 "logical_shift_operator"
1736                         [(match_operand:SI 2 "register_operand" "r")
1737                          (neg:SI (match_dup 3))])]))]
1738   "!optimize_debug && optimize
1739    && xtensa_shlrd_which_direction (operands[4], operands[5]) != UNKNOWN"
1741   switch (xtensa_shlrd_which_direction (operands[4], operands[5]))
1742     {
1743     case ASHIFT:        return "ssl\t%3\;src\t%0, %1, %2";
1744     case LSHIFTRT:      return "ssr\t%3\;src\t%0, %2, %1";
1745     default:            gcc_unreachable ();
1746     }
1748   [(set_attr "type"     "arith")
1749    (set_attr "mode"     "SI")
1750    (set_attr "length"   "6")])
1752 (define_insn_and_split "*shlrd_reg"
1753   [(set (match_operand:SI 0 "register_operand" "=a")
1754         (match_operator:SI 6 "xtensa_bit_join_operator"
1755                 [(match_operator:SI 4 "logical_shift_operator"
1756                         [(match_operand:SI 1 "register_operand" "r")
1757                          (neg:SI (match_operand:SI 3 "register_operand" "r"))])
1758                  (match_operator:SI 5 "logical_shift_operator"
1759                         [(match_operand:SI 2 "register_operand" "r")
1760                          (match_dup 3)])]))]
1761   "!optimize_debug && optimize
1762    && xtensa_shlrd_which_direction (operands[5], operands[4]) != UNKNOWN"
1763   "#"
1764   "&& 1"
1765   [(set (match_dup 0)
1766         (match_op_dup 6
1767                 [(match_op_dup 5
1768                         [(match_dup 2)
1769                          (match_dup 3)])
1770                  (match_op_dup 4
1771                         [(match_dup 1)
1772                          (neg:SI (match_dup 3))])]))]
1773   ""
1774   [(set_attr "type"     "arith")
1775    (set_attr "mode"     "SI")
1776    (set_attr "length"   "6")])
1779 (define_insn "*shlrd_const"
1780   [(set (match_operand:SI 0 "register_operand" "=a")
1781         (match_operator:SI 7 "xtensa_bit_join_operator"
1782                 [(match_operator:SI 5 "logical_shift_operator"
1783                         [(match_operand:SI 1 "register_operand" "r")
1784                          (match_operand:SI 3 "const_int_operand" "i")])
1785                  (match_operator:SI 6 "logical_shift_operator"
1786                         [(match_operand:SI 2 "register_operand" "r")
1787                          (match_operand:SI 4 "const_int_operand" "i")])]))]
1788   "!optimize_debug && optimize
1789    && xtensa_shlrd_which_direction (operands[5], operands[6]) != UNKNOWN
1790    && IN_RANGE (INTVAL (operands[3]), 1, 31)
1791    && IN_RANGE (INTVAL (operands[4]), 1, 31)
1792    && INTVAL (operands[3]) + INTVAL (operands[4]) == 32"
1794   switch (xtensa_shlrd_which_direction (operands[5], operands[6]))
1795     {
1796     case ASHIFT:        return "ssai\t%L3\;src\t%0, %1, %2";
1797     case LSHIFTRT:      return "ssai\t%R3\;src\t%0, %2, %1";
1798     default:            gcc_unreachable ();
1799     }
1801   [(set_attr "type"     "arith")
1802    (set_attr "mode"     "SI")
1803    (set_attr "length"   "6")])
1805 (define_insn "*shlrd_per_byte"
1806   [(set (match_operand:SI 0 "register_operand" "=a")
1807         (match_operator:SI 6 "xtensa_bit_join_operator"
1808                 [(match_operator:SI 4 "logical_shift_operator"
1809                         [(match_operand:SI 1 "register_operand" "r")
1810                          (ashift:SI (match_operand:SI 2 "register_operand" "r")
1811                                     (const_int 3))])
1812                  (match_operator:SI 5 "logical_shift_operator"
1813                         [(match_operand:SI 3 "register_operand" "r")
1814                          (neg:SI (ashift:SI (match_dup 2)
1815                                             (const_int 3)))])]))]
1816   "!optimize_debug && optimize
1817    && xtensa_shlrd_which_direction (operands[4], operands[5]) != UNKNOWN"
1819   switch (xtensa_shlrd_which_direction (operands[4], operands[5]))
1820     {
1821     case ASHIFT:        return "ssa8b\t%2\;src\t%0, %1, %3";
1822     case LSHIFTRT:      return "ssa8l\t%2\;src\t%0, %3, %1";
1823     default:            gcc_unreachable ();
1824     }
1826   [(set_attr "type"     "arith")
1827    (set_attr "mode"     "SI")
1828    (set_attr "length"   "6")])
1830 (define_insn_and_split "*shlrd_per_byte_omit_AND"
1831   [(set (match_operand:SI 0 "register_operand" "=a")
1832         (match_operator:SI 7 "xtensa_bit_join_operator"
1833                 [(match_operator:SI 5 "logical_shift_operator"
1834                         [(match_operand:SI 1 "register_operand" "r")
1835                          (and:SI (ashift:SI (match_operand:SI 2 "register_operand" "r")
1836                                             (const_int 3))
1837                                  (match_operand:SI 4 "const_int_operand" "i"))])
1838                  (match_operator:SI 6 "logical_shift_operator"
1839                         [(match_operand:SI 3 "register_operand" "r")
1840                          (neg:SI (and:SI (ashift:SI (match_dup 2)
1841                                                     (const_int 3))
1842                                          (match_dup 4)))])]))]
1843   "!optimize_debug && optimize
1844    && xtensa_shlrd_which_direction (operands[5], operands[6]) != UNKNOWN
1845    && (INTVAL (operands[4]) & 0x1f) == 3 << 3"
1846   "#"
1847   "&& 1"
1848   [(set (match_dup 0)
1849         (match_op_dup 7
1850                 [(match_op_dup 5
1851                         [(match_dup 1)
1852                          (ashift:SI (match_dup 2)
1853                                     (const_int 3))])
1854                  (match_op_dup 6
1855                         [(match_dup 3)
1856                          (neg:SI (ashift:SI (match_dup 2)
1857                                             (const_int 3)))])]))]
1858   ""
1859   [(set_attr "type"     "arith")
1860    (set_attr "mode"     "SI")
1861    (set_attr "length"   "6")])
1863 (define_insn "rotlsi3"
1864   [(set (match_operand:SI 0 "register_operand" "=a,a")
1865         (rotate:SI (match_operand:SI 1 "register_operand" "r,r")
1866                      (match_operand:SI 2 "arith_operand" "J,r")))]
1867   ""
1868   "@
1869    ssai\t%L2\;src\t%0, %1, %1
1870    ssl\t%2\;src\t%0, %1, %1"
1871   [(set_attr "type"     "multi,multi")
1872    (set_attr "mode"     "SI")
1873    (set_attr "length"   "6,6")])
1875 (define_insn "rotrsi3"
1876   [(set (match_operand:SI 0 "register_operand" "=a,a")
1877         (rotatert:SI (match_operand:SI 1 "register_operand" "r,r")
1878                      (match_operand:SI 2 "arith_operand" "J,r")))]
1879   ""
1880   "@
1881    ssai\t%R2\;src\t%0, %1, %1
1882    ssr\t%2\;src\t%0, %1, %1"
1883   [(set_attr "type"     "multi,multi")
1884    (set_attr "mode"     "SI")
1885    (set_attr "length"   "6,6")])
1888 ;; Comparisons.
1890 ;; Conditional branches.
1892 (define_expand "cbranchsi4"
1893   [(match_operator 0 "comparison_operator"
1894     [(match_operand:SI 1 "register_operand")
1895      (match_operand:SI 2 "nonmemory_operand")])
1896    (match_operand 3 "")]
1897   ""
1899   xtensa_expand_conditional_branch (operands, SImode);
1900   DONE;
1903 (define_expand "cbranchsf4"
1904   [(match_operator 0 "comparison_operator"
1905     [(match_operand:SF 1 "register_operand")
1906      (match_operand:SF 2 "register_operand")])
1907    (match_operand 3 "")]
1908   "TARGET_HARD_FLOAT"
1910   xtensa_expand_conditional_branch (operands, SFmode);
1911   DONE;
1914 ;; Branch patterns for standard integer comparisons
1916 (define_insn "*btrue"
1917   [(set (pc)
1918         (if_then_else (match_operator 3 "branch_operator"
1919                         [(match_operand:SI 0 "register_operand" "r,r")
1920                          (match_operand:SI 1 "branch_operand" "K,?r")])
1921                       (label_ref (match_operand 2 "" ""))
1922                       (pc)))]
1923   ""
1925   return xtensa_emit_branch (which_alternative == 0, operands);
1927   [(set_attr "type"     "jump,jump")
1928    (set_attr "mode"     "none")
1929    (set (attr "length")
1930         (if_then_else (match_test "TARGET_DENSITY
1931                                    && CONST_INT_P (operands[1])
1932                                    && INTVAL (operands[1]) == 0
1933                                    && (GET_CODE (operands[3]) == EQ
1934                                        || GET_CODE (operands[3]) == NE)")
1935                       (const_int 2)
1936                       (const_int 3)))])
1938 (define_insn_and_split "*btrue_INT_MIN"
1939   [(set (pc)
1940         (if_then_else (match_operator 2 "boolean_operator"
1941                         [(match_operand:SI 0 "register_operand" "r")
1942                          (const_int -2147483648)])
1943                       (label_ref (match_operand 1 ""))
1944                       (pc)))]
1945   "TARGET_ABS"
1946   "#"
1947   "&& can_create_pseudo_p ()"
1948   [(set (match_dup 3)
1949         (abs:SI (match_dup 0)))
1950    (set (pc)
1951         (if_then_else (match_op_dup 2
1952                         [(zero_extract:SI (match_dup 3)
1953                                           (const_int 1)
1954                                           (match_dup 4))
1955                          (const_int 0)])
1956                       (label_ref (match_dup 1))
1957                       (pc)))]
1959   operands[3] = gen_reg_rtx (SImode);
1960   operands[4] = GEN_INT (BITS_BIG_ENDIAN ? 0 : 31);
1961   operands[2] = gen_rtx_fmt_ee (reverse_condition (GET_CODE (operands[2])),
1962                                 VOIDmode, XEXP (operands[2], 0),
1963                                 const0_rtx);
1965   [(set_attr "type"     "jump")
1966    (set_attr "mode"     "none")
1967    (set_attr "length"   "6")])
1969 (define_insn "*ubtrue"
1970   [(set (pc)
1971         (if_then_else (match_operator 3 "ubranch_operator"
1972                         [(match_operand:SI 0 "register_operand" "r,r")
1973                          (match_operand:SI 1 "ubranch_operand" "L,r")])
1974                       (label_ref (match_operand 2 "" ""))
1975                       (pc)))]
1976   ""
1978   return xtensa_emit_branch (which_alternative == 0, operands);
1980   [(set_attr "type"     "jump,jump")
1981    (set_attr "mode"     "none")
1982    (set_attr "length"   "3,3")])
1984 ;; Branch patterns for bit testing
1986 (define_insn "*bittrue"
1987   [(set (pc)
1988         (if_then_else (match_operator 3 "boolean_operator"
1989                         [(zero_extract:SI (match_operand:SI 0 "register_operand" "r,r")
1990                                           (const_int 1)
1991                                           (match_operand:SI 1 "arith_operand" "J,r"))
1992                          (const_int 0)])
1993                       (label_ref (match_operand 2 "" ""))
1994                       (pc)))]
1995   ""
1997   static char result[64];
1998   char op;
1999   switch (GET_CODE (operands[3]))
2000     {
2001     case EQ:    op = 'c'; break;
2002     case NE:    op = 's'; break;
2003     default:    gcc_unreachable ();
2004     }
2005   if (which_alternative == 0)
2006     {
2007       operands[1] = GEN_INT (INTVAL (operands[1]) & 0x1f);
2008       sprintf (result, "bb%ci\t%%0, %%d1, %%2", op);
2009     }
2010   else
2011     sprintf (result, "bb%c\t%%0, %%1, %%2", op);
2012   return result;
2014   [(set_attr "type"     "jump")
2015    (set_attr "mode"     "none")
2016    (set_attr "length"   "3")])
2018 (define_insn "*masktrue"
2019   [(set (pc)
2020         (if_then_else (match_operator 3 "boolean_operator"
2021                         [(and:SI (match_operand:SI 0 "register_operand" "r")
2022                                  (match_operand:SI 1 "register_operand" "r"))
2023                          (const_int 0)])
2024                       (label_ref (match_operand 2 "" ""))
2025                       (pc)))]
2026   ""
2028   switch (GET_CODE (operands[3]))
2029     {
2030     case EQ:    return "bnone\t%0, %1, %2";
2031     case NE:    return "bany\t%0, %1, %2";
2032     default:    gcc_unreachable ();
2033     }
2035   [(set_attr "type"     "jump")
2036    (set_attr "mode"     "none")
2037    (set_attr "length"   "3")])
2039 (define_insn "*masktrue_bitcmpl"
2040   [(set (pc)
2041         (if_then_else (match_operator 3 "boolean_operator"
2042                         [(and:SI (not:SI (match_operand:SI 0 "register_operand" "r"))
2043                                  (match_operand:SI 1 "register_operand" "r"))
2044                          (const_int 0)])
2045                       (label_ref (match_operand 2 "" ""))
2046                       (pc)))]
2047   ""
2049   switch (GET_CODE (operands[3]))
2050     {
2051     case EQ:    return "ball\t%0, %1, %2";
2052     case NE:    return "bnall\t%0, %1, %2";
2053     default:    gcc_unreachable ();
2054     }
2056   [(set_attr "type"     "jump")
2057    (set_attr "mode"     "none")
2058    (set_attr "length"   "3")])
2060 (define_insn_and_split "*masktrue_const_bitcmpl"
2061   [(set (pc)
2062         (if_then_else (match_operator 3 "boolean_operator"
2063                         [(and:SI (not:SI (match_operand:SI 0 "register_operand" "r"))
2064                                  (match_operand:SI 1 "const_int_operand" "i"))
2065                          (const_int 0)])
2066                       (label_ref (match_operand 2 "" ""))
2067                       (pc)))]
2068   "exact_log2 (INTVAL (operands[1])) < 0"
2069   "#"
2070   "&& can_create_pseudo_p ()"
2071   [(set (match_dup 4)
2072         (match_dup 1))
2073    (set (pc)
2074         (if_then_else (match_op_dup 3
2075                         [(and:SI (not:SI (match_dup 0))
2076                                  (match_dup 4))
2077                          (const_int 0)])
2078                       (label_ref (match_dup 2))
2079                       (pc)))]
2081   operands[4] = gen_reg_rtx (SImode);
2083   [(set_attr "type"     "jump")
2084    (set_attr "mode"     "none")
2085    (set (attr "length")
2086         (if_then_else (match_test "TARGET_DENSITY
2087                                    && IN_RANGE (INTVAL (operands[1]), -32, 95)")
2088                       (const_int 5)
2089                       (if_then_else (match_test "xtensa_simm12b (INTVAL (operands[1]))")
2090                                     (const_int 6)
2091                                     (const_int 10))))])
2093 (define_split
2094   [(set (pc)
2095         (if_then_else (match_operator 2 "boolean_operator"
2096                         [(match_operator 3 "subreg_HQI_lowpart_operator"
2097                            [(not:SI (match_operand:SI 0 "register_operand"))])
2098                          (const_int 0)])
2099                       (label_ref (match_operand 1 ""))
2100                       (pc)))]
2101   ""
2102   [(set (pc)
2103         (if_then_else (match_op_dup 2
2104                         [(and:SI (not:SI (match_dup 0))
2105                                  (match_dup 3))
2106                          (const_int 0)])
2107                       (label_ref (match_dup 1))
2108                       (pc)))]
2110   operands[3] = GEN_INT ((1 << GET_MODE_BITSIZE (GET_MODE (operands[3]))) - 1);
2113 (define_insn_and_split "*masktrue_const_pow2_minus_one"
2114   [(set (pc)
2115         (if_then_else (match_operator 4 "boolean_operator"
2116                         [(and:SI (match_operand:SI 0 "register_operand" "r")
2117                                  (match_operand:SI 1 "const_int_operand" "i"))
2118                          (match_operand:SI 2 "const_int_operand" "i")])
2119                       (label_ref (match_operand 3 "" ""))
2120                       (pc)))]
2121   "IN_RANGE (exact_log2 (INTVAL (operands[1]) + 1), 17, 31)
2122    /* && (~INTVAL (operands[1]) & INTVAL (operands[2])) == 0  // can be omitted */
2123    && xtensa_b4const_or_zero (INTVAL (operands[2]) << (32 - floor_log2 (INTVAL (operands[1]) + 1)))"
2124   "#"
2125   "&& can_create_pseudo_p ()"
2126   [(set (match_dup 5)
2127         (ashift:SI (match_dup 0)
2128                    (match_dup 1)))
2129    (set (pc)
2130         (if_then_else (match_op_dup 4
2131                         [(match_dup 5)
2132                          (match_dup 2)])
2133                       (label_ref (match_dup 3))
2134                       (pc)))]
2136   int shift = 32 - floor_log2 (INTVAL (operands[1]) + 1);
2137   operands[1] = GEN_INT (shift);
2138   operands[2] = GEN_INT (INTVAL (operands[2]) << shift);
2139   operands[5] = gen_reg_rtx (SImode);
2141   [(set_attr "type"     "jump")
2142    (set_attr "mode"     "none")
2143    (set (attr "length")
2144         (if_then_else (match_test "(TARGET_DENSITY && INTVAL (operands[1]) == 0x7FFFFFFF)
2145                                    && INTVAL (operands[2]) == 0")
2146                       (const_int 4)
2147                       (if_then_else (match_test "TARGET_DENSITY
2148                                                  && (INTVAL (operands[1]) == 0x7FFFFFFF
2149                                                      || INTVAL (operands[2]) == 0)")
2150                                     (const_int 5)
2151                                     (const_int 6))))])
2153 (define_insn_and_split "*masktrue_const_negative_pow2"
2154   [(set (pc)
2155         (if_then_else (match_operator 4 "boolean_operator"
2156                         [(and:SI (match_operand:SI 0 "register_operand" "r")
2157                                  (match_operand:SI 1 "const_int_operand" "i"))
2158                          (match_operand:SI 2 "const_int_operand" "i")])
2159                       (label_ref (match_operand 3 "" ""))
2160                       (pc)))]
2161   "IN_RANGE (exact_log2 (-INTVAL (operands[1])), 1, 30)
2162    /* && (~INTVAL (operands[1]) & INTVAL (operands[2])) == 0  // can be omitted */
2163    && xtensa_b4const_or_zero (INTVAL (operands[2]) >> floor_log2 (-INTVAL (operands[1])))"
2164   "#"
2165   "&& can_create_pseudo_p ()"
2166   [(set (match_dup 5)
2167         (lshiftrt:SI (match_dup 0)
2168                      (match_dup 1)))
2169    (set (pc)
2170         (if_then_else (match_op_dup 4
2171                         [(match_dup 5)
2172                          (match_dup 2)])
2173                       (label_ref (match_dup 3))
2174                       (pc)))]
2176   int shift = floor_log2 (-INTVAL (operands[1]));
2177   operands[1] = GEN_INT (shift);
2178   operands[2] = GEN_INT (INTVAL (operands[2]) >> shift);
2179   operands[5] = gen_reg_rtx (SImode);
2181   [(set_attr "type"     "jump")
2182    (set_attr "mode"     "none")
2183    (set (attr "length")
2184         (if_then_else (match_test "TARGET_DENSITY && INTVAL (operands[2]) == 0")
2185                       (const_int 5)
2186                       (const_int 6)))])
2188 (define_insn_and_split "*masktrue_const_shifted_mask"
2189   [(set (pc)
2190         (if_then_else (match_operator 4 "boolean_operator"
2191                         [(and:SI (match_operand:SI 0 "register_operand" "r")
2192                                  (match_operand:SI 1 "shifted_mask_operand" "i"))
2193                          (match_operand:SI 2 "const_int_operand" "i")])
2194                       (label_ref (match_operand 3 "" ""))
2195                       (pc)))]
2196   "/* (INTVAL (operands[2]) & ((1 << ctz_hwi (INTVAL (operands[1]))) - 1)) == 0  // can be omitted
2197    && */ xtensa_b4const_or_zero ((uint32_t)INTVAL (operands[2]) >> ctz_hwi (INTVAL (operands[1])))"
2198   "#"
2199   "&& can_create_pseudo_p ()"
2200   [(set (match_dup 6)
2201         (zero_extract:SI (match_dup 0)
2202                          (match_dup 5)
2203                          (match_dup 1)))
2204    (set (pc)
2205         (if_then_else (match_op_dup 4
2206                         [(match_dup 6)
2207                          (match_dup 2)])
2208                       (label_ref (match_dup 3))
2209                       (pc)))]
2211   HOST_WIDE_INT mask = INTVAL (operands[1]);
2212   int shift = ctz_hwi (mask);
2213   int mask_size = floor_log2 (((uint32_t)mask >> shift) + 1);
2214   int mask_pos = shift;
2215   if (BITS_BIG_ENDIAN)
2216     mask_pos = (32 - (mask_size + shift)) & 0x1f;
2217   operands[1] = GEN_INT (mask_pos);
2218   operands[2] = GEN_INT ((uint32_t)INTVAL (operands[2]) >> shift);
2219   operands[5] = GEN_INT (mask_size);
2220   operands[6] = gen_reg_rtx (SImode);
2222   [(set_attr "type"     "jump")
2223    (set_attr "mode"     "none")
2224    (set (attr "length")
2225         (if_then_else (match_test "TARGET_DENSITY
2226                                    && (uint32_t)INTVAL (operands[2]) >> ctz_hwi (INTVAL (operands[1])) == 0")
2227                       (const_int 5)
2228                       (const_int 6)))])
2231 ;; Zero-overhead looping support.
2233 ;; Define the loop insns used by bct optimization to represent the
2234 ;; start and end of a zero-overhead loop.  This start template generates
2235 ;; the loop insn; the end template doesn't generate any instructions since
2236 ;; loop end is handled in hardware.
2238 (define_insn "zero_cost_loop_start"
2239   [(set (pc)
2240         (if_then_else (ne (match_operand:SI 2 "register_operand" "0")
2241                           (const_int 1))
2242                       (label_ref (match_operand 1 "" ""))
2243                       (pc)))
2244    (set (match_operand:SI 0 "register_operand" "=a")
2245         (plus:SI (match_dup 0)
2246                  (const_int -1)))
2247    (unspec [(const_int 0)] UNSPEC_LSETUP_START)]
2248   "TARGET_LOOPS && optimize"
2249   "loop\t%0, %l1_LEND"
2250   [(set_attr "type"     "jump")
2251    (set_attr "mode"     "none")
2252    (set_attr "length"   "3")])
2254 (define_insn "zero_cost_loop_end"
2255   [(set (pc)
2256         (if_then_else (ne (match_operand:SI 2 "nonimmediate_operand" "0,0")
2257                           (const_int 1))
2258                       (label_ref (match_operand 1 "" ""))
2259                       (pc)))
2260    (set (match_operand:SI 0 "nonimmediate_operand" "=a,m")
2261         (plus:SI (match_dup 0)
2262                  (const_int -1)))
2263    (unspec [(const_int 0)] UNSPEC_LSETUP_END)
2264    (clobber (match_scratch:SI 3 "=X,&r"))]
2265   "TARGET_LOOPS && optimize"
2266   "#"
2267   [(set_attr "type"     "jump")
2268    (set_attr "mode"     "none")
2269    (set_attr "length"   "0")])
2271 (define_insn "loop_end"
2272   [(set (pc)
2273         (if_then_else (ne (match_operand:SI 2 "register_operand" "0")
2274                           (const_int 1))
2275                       (label_ref (match_operand 1 "" ""))
2276                       (pc)))
2277    (set (match_operand:SI 0 "register_operand" "=a")
2278         (plus:SI (match_dup 0)
2279                  (const_int -1)))
2280    (unspec [(const_int 0)] UNSPEC_LSETUP_END)]
2281   "TARGET_LOOPS && optimize"
2283   xtensa_emit_loop_end (insn, operands);
2284   return "";
2286   [(set_attr "type"     "jump")
2287    (set_attr "mode"     "none")
2288    (set_attr "length"   "0")])
2290 (define_split
2291   [(set (pc)
2292         (if_then_else (ne (match_operand:SI 0 "nonimmediate_operand" "")
2293                           (const_int 1))
2294                       (label_ref (match_operand 1 "" ""))
2295                       (pc)))
2296    (set (match_operand:SI 2 "nonimmediate_operand" "")
2297         (plus:SI (match_dup 0)
2298                  (const_int -1)))
2299    (unspec [(const_int 0)] UNSPEC_LSETUP_END)
2300    (clobber (match_scratch 3))]
2301   "TARGET_LOOPS && optimize && reload_completed"
2302   [(const_int 0)]
2304   if (!REG_P (operands[0]))
2305     {
2306       rtx test;
2308       /* Fallback into a normal conditional branch insn.  */
2309       emit_move_insn (operands[3], operands[0]);
2310       emit_insn (gen_addsi3 (operands[3], operands[3], constm1_rtx));
2311       emit_move_insn (operands[0], operands[3]);
2312       test = gen_rtx_NE (VOIDmode, operands[3], const0_rtx);
2313       emit_jump_insn (gen_cbranchsi4 (test, operands[3],
2314                                       const0_rtx, operands[1]));
2315     }
2316   else
2317     {
2318       emit_jump_insn (gen_loop_end (operands[0], operands[1], operands[2]));
2319     }
2321   DONE;
2324 ; operand 0 is the loop count pseudo register
2325 ; operand 1 is the label to jump to at the top of the loop
2326 (define_expand "doloop_end"
2327   [(parallel [(set (pc) (if_then_else
2328                           (ne (match_operand:SI 0 "" "")
2329                               (const_int 1))
2330                           (label_ref (match_operand 1 "" ""))
2331                           (pc)))
2332               (set (match_dup 0)
2333                    (plus:SI (match_dup 0)
2334                             (const_int -1)))
2335               (unspec [(const_int 0)] UNSPEC_LSETUP_END)])]
2336   "TARGET_LOOPS && optimize"
2338   /* The loop optimizer doesn't check the predicates... */
2339   if (GET_MODE (operands[0]) != SImode)
2340     FAIL;
2344 ;; Setting a register from a comparison.
2346 (define_expand "cstoresi4"
2347   [(match_operand:SI 0 "register_operand")
2348    (match_operator 1 "xtensa_cstoresi_operator"
2349     [(match_operand:SI 2 "register_operand")
2350      (match_operand:SI 3 "nonmemory_operand")])]
2351   ""
2353   if (!xtensa_expand_scc (operands, SImode))
2354     FAIL;
2355   DONE;
2358 (define_insn "salt"
2359   [(set (match_operand:SI 0 "register_operand" "=a")
2360         (lt:SI (match_operand:SI 1 "register_operand" "r")
2361                (match_operand:SI 2 "register_operand" "r")))]
2362   "TARGET_SALT"
2363   "salt\t%0, %1, %2"
2364   [(set_attr "type"     "arith")
2365    (set_attr "mode"     "SI")
2366    (set_attr "length"   "3")])
2368 (define_insn "saltu"
2369   [(set (match_operand:SI 0 "register_operand" "=a")
2370         (ltu:SI (match_operand:SI 1 "register_operand" "r")
2371                 (match_operand:SI 2 "register_operand" "r")))]
2372   "TARGET_SALT"
2373   "saltu\t%0, %1, %2"
2374   [(set_attr "type"     "arith")
2375    (set_attr "mode"     "SI")
2376    (set_attr "length"   "3")])
2378 (define_expand "cstoresf4"
2379   [(match_operand:SI 0 "register_operand")
2380    (match_operator:SI 1 "comparison_operator"
2381     [(match_operand:SF 2 "register_operand")
2382      (match_operand:SF 3 "register_operand")])]
2383   "TARGET_HARD_FLOAT"
2385   if (!xtensa_expand_scc (operands, SFmode))
2386     FAIL;
2387   DONE;
2392 ;; Conditional moves.
2394 (define_expand "movsicc"
2395   [(set (match_operand:SI 0 "register_operand" "")
2396         (if_then_else:SI (match_operand 1 "comparison_operator" "")
2397                          (match_operand:SI 2 "register_operand" "")
2398                          (match_operand:SI 3 "register_operand" "")))]
2399   ""
2401   if (!xtensa_expand_conditional_move (operands, 0))
2402     FAIL;
2403   DONE;
2406 (define_expand "movsfcc"
2407   [(set (match_operand:SF 0 "register_operand" "")
2408         (if_then_else:SF (match_operand 1 "comparison_operator" "")
2409                          (match_operand:SF 2 "register_operand" "")
2410                          (match_operand:SF 3 "register_operand" "")))]
2411   ""
2413   if (!xtensa_expand_conditional_move (operands, 1))
2414     FAIL;
2415   DONE;
2418 (define_insn "movsicc_internal0"
2419   [(set (match_operand:SI 0 "register_operand" "=a,a")
2420         (if_then_else:SI (match_operator 4 "branch_operator"
2421                            [(match_operand:SI 1 "register_operand" "r,r")
2422                             (const_int 0)])
2423                          (match_operand:SI 2 "register_operand" "r,0")
2424                          (match_operand:SI 3 "register_operand" "0,r")))]
2425   ""
2427   return xtensa_emit_movcc (which_alternative == 1, false, false, operands);
2429   [(set_attr "type"     "move,move")
2430    (set_attr "mode"     "SI")
2431    (set_attr "length"   "3,3")])
2433 (define_insn "movsicc_internal1"
2434   [(set (match_operand:SI 0 "register_operand" "=a,a")
2435         (if_then_else:SI (match_operator 4 "boolean_operator"
2436                            [(match_operand:CC 1 "register_operand" "b,b")
2437                             (const_int 0)])
2438                          (match_operand:SI 2 "register_operand" "r,0")
2439                          (match_operand:SI 3 "register_operand" "0,r")))]
2440   "TARGET_BOOLEANS"
2442   return xtensa_emit_movcc (which_alternative == 1, false, true, operands);
2444   [(set_attr "type"     "move,move")
2445    (set_attr "mode"     "SI")
2446    (set_attr "length"   "3,3")])
2448 (define_insn "movsfcc_internal0"
2449   [(set (match_operand:SF 0 "register_operand" "=a,a,f,f")
2450         (if_then_else:SF (match_operator 4 "branch_operator"
2451                            [(match_operand:SI 1 "register_operand" "r,r,r,r")
2452                             (const_int 0)])
2453                          (match_operand:SF 2 "register_operand" "r,0,f,0")
2454                          (match_operand:SF 3 "register_operand" "0,r,0,f")))]
2455   ""
2457   return xtensa_emit_movcc ((which_alternative & 1) == 1,
2458                             which_alternative >= 2, false, operands);
2460   [(set_attr "type"     "move,move,move,move")
2461    (set_attr "mode"     "SF")
2462    (set_attr "length"   "3,3,3,3")])
2464 (define_insn "movsfcc_internal1"
2465   [(set (match_operand:SF 0 "register_operand" "=a,a,f,f")
2466         (if_then_else:SF (match_operator 4 "boolean_operator"
2467                            [(match_operand:CC 1 "register_operand" "b,b,b,b")
2468                             (const_int 0)])
2469                          (match_operand:SF 2 "register_operand" "r,0,f,0")
2470                          (match_operand:SF 3 "register_operand" "0,r,0,f")))]
2471   "TARGET_BOOLEANS"
2473   return xtensa_emit_movcc ((which_alternative & 1) == 1,
2474                             which_alternative >= 2, true, operands);
2476   [(set_attr "type"     "move,move,move,move")
2477    (set_attr "mode"     "SF")
2478    (set_attr "length"   "3,3,3,3")])
2481 ;; Floating-point comparisons.
2483 (define_insn "s<code>_sf"
2484   [(set (match_operand:CC 0 "register_operand" "=b")
2485         (any_scc_sf:CC (match_operand:SF 1 "register_operand" "f")
2486                        (match_operand:SF 2 "register_operand" "f")))]
2487   "TARGET_HARD_FLOAT"
2488   "<scc_sf>.s\t%0, %1, %2"
2489   [(set_attr "type"     "farith")
2490    (set_attr "mode"     "BL")
2491    (set_attr "length"   "3")])
2494 ;; Unconditional branches.
2496 (define_insn "jump"
2497   [(set (pc)
2498         (label_ref (match_operand 0 "" "")))]
2499   ""
2500   "j\t%l0"
2501   [(set_attr "type"     "jump")
2502    (set_attr "mode"     "none")
2503    (set_attr "length"   "3")])
2505 (define_expand "indirect_jump"
2506   [(set (pc)
2507         (match_operand 0 "register_operand" ""))]
2508   ""
2510   rtx dest = operands[0];
2511   if (! REG_P (dest) || GET_MODE (dest) != Pmode)
2512     operands[0] = copy_to_mode_reg (Pmode, dest);
2514   emit_jump_insn (gen_indirect_jump_internal (dest));
2515   DONE;
2518 (define_insn "indirect_jump_internal"
2519   [(set (pc) (match_operand:SI 0 "register_operand" "r"))]
2520   ""
2521   "jx\t%0"
2522   [(set_attr "type"     "jump")
2523    (set_attr "mode"     "none")
2524    (set_attr "length"   "3")])
2527 (define_expand "tablejump"
2528   [(use (match_operand:SI 0 "register_operand" ""))
2529    (use (label_ref (match_operand 1 "" "")))]
2530    ""
2532   rtx target = operands[0];
2533   if (flag_pic)
2534     {
2535       /* For PIC, the table entry is relative to the start of the table.  */
2536       rtx label = gen_reg_rtx (SImode);
2537       target = gen_reg_rtx (SImode);
2538       emit_move_insn (label, gen_rtx_LABEL_REF (SImode, operands[1]));
2539       emit_insn (gen_addsi3 (target, operands[0], label));
2540     }
2541   emit_jump_insn (gen_tablejump_internal (target, operands[1]));
2542   DONE;
2545 (define_insn "tablejump_internal"
2546   [(set (pc)
2547         (match_operand:SI 0 "register_operand" "r"))
2548    (use (label_ref (match_operand 1 "" "")))]
2549   ""
2550   "jx\t%0"
2551   [(set_attr "type"     "jump")
2552    (set_attr "mode"     "none")
2553    (set_attr "length"   "3")])
2556 ;; Function calls.
2558 (define_expand "sym_PLT"
2559   [(const (unspec [(match_operand:SI 0 "" "")] UNSPEC_PLT))]
2560   ""
2561   "")
2563 (define_expand "call"
2564   [(call (match_operand 0 "memory_operand" "")
2565          (match_operand 1 "" ""))]
2566   ""
2568   xtensa_expand_call (0, operands, false);
2569   DONE;
2572 (define_insn "call_internal"
2573   [(call (mem (match_operand:SI 0 "call_insn_operand" "nir"))
2574          (match_operand 1 "" "i"))]
2575   "!SIBLING_CALL_P (insn)"
2577   return xtensa_emit_call (0, operands);
2579   [(set_attr "type"     "call")
2580    (set_attr "mode"     "none")
2581    (set_attr "length"   "3")])
2583 (define_expand "call_value"
2584   [(set (match_operand 0 "register_operand" "")
2585         (call (match_operand 1 "memory_operand" "")
2586               (match_operand 2 "" "")))]
2587   ""
2589   xtensa_expand_call (1, operands, false);
2590   DONE;
2593 (define_insn "call_value_internal"
2594   [(set (match_operand 0 "register_operand" "=a")
2595         (call (mem (match_operand:SI 1 "call_insn_operand" "nir"))
2596               (match_operand 2 "" "i")))]
2597   "!SIBLING_CALL_P (insn)"
2599   return xtensa_emit_call (1, operands);
2601   [(set_attr "type"     "call")
2602    (set_attr "mode"     "none")
2603    (set_attr "length"   "3")])
2605 (define_expand "sibcall"
2606   [(call (match_operand 0 "memory_operand" "")
2607          (match_operand 1 "" ""))]
2608   "!TARGET_WINDOWED_ABI"
2610   xtensa_expand_call (0, operands, true);
2611   DONE;
2614 (define_insn "sibcall_internal"
2615   [(call (mem:SI (match_operand:SI 0 "call_insn_operand" "nic"))
2616          (match_operand 1 "" "i"))]
2617   "!TARGET_WINDOWED_ABI && SIBLING_CALL_P (insn)"
2619   return xtensa_emit_sibcall (0, operands);
2621   [(set_attr "type"     "call")
2622    (set_attr "mode"     "none")
2623    (set_attr "length"   "3")])
2625 (define_expand "sibcall_value"
2626   [(set (match_operand 0 "register_operand" "")
2627         (call (match_operand 1 "memory_operand" "")
2628               (match_operand 2 "" "")))]
2629   "!TARGET_WINDOWED_ABI"
2631   xtensa_expand_call (1, operands, true);
2632   DONE;
2635 (define_insn "sibcall_value_internal"
2636   [(set (match_operand 0 "register_operand" "=a")
2637         (call (mem:SI (match_operand:SI 1 "call_insn_operand" "nic"))
2638               (match_operand 2 "" "i")))]
2639   "!TARGET_WINDOWED_ABI && SIBLING_CALL_P (insn)"
2641   return xtensa_emit_sibcall (1, operands);
2643   [(set_attr "type"     "call")
2644    (set_attr "mode"     "none")
2645    (set_attr "length"   "3")])
2647 (define_expand "untyped_call"
2648   [(parallel [(call (match_operand 0 "")
2649                     (const_int 0))
2650               (match_operand 1 "")
2651               (match_operand 2 "")])]
2652   ""
2654   int i;
2656   emit_call_insn (gen_call (operands[0], const0_rtx));
2658   for (i = 0; i < XVECLEN (operands[2], 0); i++)
2659     {
2660       rtx set = XVECEXP (operands[2], 0, i);
2661       emit_move_insn (SET_DEST (set), SET_SRC (set));
2662     }
2664   emit_insn (gen_blockage ());
2665   DONE;
2668 (define_insn "entry"
2669   [(set (reg:SI A1_REG)
2670         (unspec_volatile:SI [(match_operand:SI 0 "const_int_operand" "i")]
2671                             UNSPECV_ENTRY))]
2672   ""
2673   "entry\tsp, %0"
2674   [(set_attr "type"     "entry")
2675    (set_attr "mode"     "SI")
2676    (set_attr "length"   "3")])
2678 (define_insn "return"
2679   [(return)
2680    (use (reg:SI A0_REG))]
2681   "reload_completed
2682    && (TARGET_WINDOWED_ABI
2683        || compute_frame_size (get_frame_size ()) == 0
2684        || epilogue_completed)"
2686   return TARGET_WINDOWED_ABI ?
2687       (TARGET_DENSITY ? "retw.n" : "retw") :
2688       (TARGET_DENSITY ? "ret.n" : "ret");
2690   [(set_attr "type"     "jump")
2691    (set_attr "mode"     "none")
2692    (set (attr "length")
2693         (if_then_else (match_test "TARGET_DENSITY")
2694                       (const_int 2)
2695                       (const_int 3)))])
2698 ;; Miscellaneous instructions.
2700 ;; In windowed ABI stack pointer adjustment must happen before any access
2701 ;; to the space allocated on stack is allowed, otherwise register spill
2702 ;; area may be clobbered.  That's what frame blockage is supposed to enforce.
2704 (define_expand "allocate_stack"
2705   [(set (match_operand 0 "nonimmed_operand")
2706         (minus (reg A1_REG) (match_operand 1 "add_operand")))
2707    (set (reg A1_REG)
2708         (minus (reg A1_REG) (match_dup 1)))]
2709   "TARGET_WINDOWED_ABI"
2711   if (CONST_INT_P (operands[1]))
2712     {
2713       rtx neg_op0 = GEN_INT (-INTVAL (operands[1]));
2714       emit_insn (gen_addsi3 (stack_pointer_rtx, stack_pointer_rtx, neg_op0));
2715     }
2716   else
2717     {
2718       emit_insn (gen_subsi3 (stack_pointer_rtx, stack_pointer_rtx,
2719                              operands[1]));
2720     }
2721   emit_move_insn (operands[0], virtual_stack_dynamic_rtx);
2722   emit_insn (gen_frame_blockage ());
2723   DONE;
2726 (define_expand "prologue"
2727   [(const_int 0)]
2728   ""
2730   xtensa_expand_prologue ();
2731   DONE;
2734 (define_expand "epilogue"
2735   [(return)]
2736   ""
2738   xtensa_expand_epilogue ();
2739   emit_jump_insn (gen_return ());
2740   DONE;
2743 (define_expand "sibcall_epilogue"
2744   [(return)]
2745   "!TARGET_WINDOWED_ABI"
2747   xtensa_expand_epilogue ();
2748   DONE;
2751 (define_insn "nop"
2752   [(const_int 0)]
2753   ""
2755   return (TARGET_DENSITY ? "nop.n" : "nop");
2757   [(set_attr "type"     "nop")
2758    (set_attr "mode"     "none")
2759    (set (attr "length")
2760         (if_then_else (match_test "TARGET_DENSITY")
2761                       (const_int 2)
2762                       (const_int 3)))])
2764 (define_expand "nonlocal_goto"
2765   [(match_operand:SI 0 "general_operand" "")
2766    (match_operand:SI 1 "general_operand" "")
2767    (match_operand:SI 2 "general_operand" "")
2768    (match_operand:SI 3 "" "")]
2769   "TARGET_WINDOWED_ABI"
2771   xtensa_expand_nonlocal_goto (operands);
2772   DONE;
2775 ;; Stuff an address into the return address register along with the window
2776 ;; size in the high bits.  Because we don't have the window size of the
2777 ;; previous frame, assume the function called out with a CALL8 since that
2778 ;; is what compilers always use.  Note: __builtin_frob_return_addr has
2779 ;; already been applied to the handler, but the generic version doesn't
2780 ;; allow us to frob it quite enough, so we just frob here.
2782 (define_expand "eh_return"
2783   [(use (match_operand 0 "general_operand"))]
2784   ""
2786   if (TARGET_WINDOWED_ABI)
2787     emit_insn (gen_eh_set_a0_windowed (operands[0]));
2788   else
2789     emit_insn (gen_eh_set_a0_call0 (operands[0]));
2790   DONE;
2793 (define_insn_and_split "eh_set_a0_windowed"
2794   [(set (reg:SI A0_REG)
2795         (unspec_volatile:SI [(match_operand:SI 0 "register_operand" "r")]
2796                             UNSPECV_EH_RETURN))
2797    (clobber (match_scratch:SI 1 "=r"))]
2798   ""
2799   "#"
2800   "reload_completed"
2801   [(set (match_dup 1) (ashift:SI (match_dup 0) (const_int 2)))
2802    (set (match_dup 1) (plus:SI (match_dup 1) (const_int 2)))
2803    (set (reg:SI A0_REG) (rotatert:SI (match_dup 1) (const_int 2)))]
2804   "")
2806 (define_insn_and_split "eh_set_a0_call0"
2807   [(unspec_volatile [(match_operand:SI 0 "register_operand" "r")]
2808                     UNSPECV_EH_RETURN)
2809    (clobber (match_scratch:SI 1 "=r"))]
2810   ""
2811   "#"
2812   "reload_completed"
2813   [(const_int 0)]
2815   xtensa_set_return_address (operands[0], operands[1]);
2816   DONE;
2819 ;; UNSPEC_VOLATILE is considered to use and clobber all hard registers and
2820 ;; all of memory.  This blocks insns from being moved across this point.
2822 (define_insn "blockage"
2823   [(unspec_volatile [(const_int 0)] UNSPECV_BLOCKAGE)]
2824   ""
2825   ""
2826   [(set_attr "type"     "nop")
2827    (set_attr "mode"     "none")
2828    (set_attr "length"   "0")])
2830 ;; Do not schedule instructions accessing memory before this point.
2832 (define_expand "frame_blockage"
2833   [(set (match_dup 0)
2834         (unspec:BLK [(match_dup 1)] UNSPEC_FRAME_BLOCKAGE))]
2835   ""
2837   operands[0] = gen_rtx_MEM (BLKmode, gen_rtx_SCRATCH (Pmode));
2838   MEM_VOLATILE_P (operands[0]) = 1;
2839   operands[1] = stack_pointer_rtx;
2842 (define_insn "*frame_blockage"
2843   [(set (match_operand:BLK 0 "" "")
2844         (unspec:BLK [(match_operand:SI 1 "" "")] UNSPEC_FRAME_BLOCKAGE))]
2845   ""
2846   ""
2847   [(set_attr "type"     "nop")
2848    (set_attr "mode"     "none")
2849    (set_attr "length"   "0")])
2851 (define_insn "trap"
2852   [(trap_if (const_int 1) (const_int 0))]
2853   ""
2855   if (TARGET_DEBUG)
2856     return "break\t1, 15";
2857   else
2858     return (TARGET_DENSITY ? "ill.n" : "ill");
2860   [(set_attr "type"     "trap")
2861    (set_attr "mode"     "none")
2862    (set (attr "length")
2863         (if_then_else (match_test "!TARGET_DEBUG && TARGET_DENSITY")
2864                       (const_int 2)
2865                       (const_int 3)))])
2867 ;; Setting up a frame pointer is tricky for Xtensa because GCC doesn't
2868 ;; know if a frame pointer is required until the reload pass, and
2869 ;; because there may be an incoming argument value in the hard frame
2870 ;; pointer register (a7).  If there is an incoming argument in that
2871 ;; register, the "set_frame_ptr" insn gets inserted immediately after
2872 ;; the insn that copies the incoming argument to a pseudo or to the
2873 ;; stack.  This serves several purposes here: (1) it keeps the
2874 ;; optimizer from copy-propagating or scheduling the use of a7 as an
2875 ;; incoming argument away from the beginning of the function; (2) we
2876 ;; can use a post-reload splitter to expand away the insn if a frame
2877 ;; pointer is not required, so that the post-reload scheduler can do
2878 ;; the right thing; and (3) it makes it easy for the prologue expander
2879 ;; to search for this insn to determine whether it should add a new insn
2880 ;; to set up the frame pointer.
2882 (define_insn "set_frame_ptr"
2883   [(set (reg:SI A7_REG) (unspec_volatile:SI [(const_int 0)] UNSPECV_SET_FP))]
2884   ""
2886   if (frame_pointer_needed)
2887     return (TARGET_DENSITY ? "mov.n\ta7, sp" : "mov\ta7, sp");
2888   return "";
2890   [(set_attr "type"     "move")
2891    (set_attr "mode"     "SI")
2892    (set (attr "length")
2893         (if_then_else (match_test "TARGET_DENSITY")
2894                       (const_int 2)
2895                       (const_int 3)))])
2897 ;; Post-reload splitter to remove fp assignment when it's not needed.
2898 (define_split
2899   [(set (reg:SI A7_REG) (unspec_volatile:SI [(const_int 0)] UNSPECV_SET_FP))]
2900   "reload_completed && !frame_pointer_needed"
2901   [(unspec [(const_int 0)] UNSPEC_NOP)]
2902   "")
2904 ;; The preceding splitter needs something to split the insn into;
2905 ;; things start breaking if the result is just a "use" so instead we
2906 ;; generate the following insn.
2907 (define_insn "*unspec_nop"
2908   [(unspec [(const_int 0)] UNSPEC_NOP)]
2909   ""
2910   ""
2911   [(set_attr "type"     "nop")
2912    (set_attr "mode"     "none")
2913    (set_attr "length"   "0")])
2916 ;; TLS support
2918 (define_expand "sym_TPOFF"
2919   [(const (unspec [(match_operand:SI 0 "" "")] UNSPEC_TPOFF))]
2920   ""
2921   "")
2923 (define_expand "sym_DTPOFF"
2924   [(const (unspec [(match_operand:SI 0 "" "")] UNSPEC_DTPOFF))]
2925   ""
2926   "")
2928 (define_insn "get_thread_pointersi"
2929   [(set (match_operand:SI 0 "register_operand" "=a")
2930         (unspec:SI [(const_int 0)] UNSPEC_TP))]
2931   "TARGET_THREADPTR"
2932   "rur\t%0, THREADPTR"
2933   [(set_attr "type"     "rsr")
2934    (set_attr "mode"     "SI")
2935    (set_attr "length"   "3")])
2937 (define_insn "set_thread_pointersi"
2938   [(unspec_volatile [(match_operand:SI 0 "register_operand" "r")]
2939                     UNSPECV_SET_TP)]
2940   "TARGET_THREADPTR"
2941   "wur\t%0, THREADPTR"
2942   [(set_attr "type"     "wsr")
2943    (set_attr "mode"     "SI")
2944    (set_attr "length"   "3")])
2946 (define_insn "tls_func"
2947   [(set (match_operand:SI 0 "register_operand" "=a")
2948         (unspec:SI [(match_operand:SI 1 "tls_symbol_operand" "")]
2949                    UNSPEC_TLS_FUNC))]
2950   "TARGET_THREADPTR && HAVE_AS_TLS"
2951   "movi\t%0, %1@TLSFUNC"
2952   [(set_attr "type"     "load")
2953    (set_attr "mode"     "SI")
2954    (set_attr "length"   "3")])
2956 (define_insn "tls_arg"
2957   [(set (match_operand:SI 0 "register_operand" "=a")
2958         (unspec:SI [(match_operand:SI 1 "tls_symbol_operand" "")]
2959                    UNSPEC_TLS_ARG))]
2960   "TARGET_THREADPTR && HAVE_AS_TLS"
2961   "movi\t%0, %1@TLSARG"
2962   [(set_attr "type"     "load")
2963    (set_attr "mode"     "SI")
2964    (set_attr "length"   "3")])
2966 (define_insn "tls_call"
2967   [(set (match_operand:SI 0 "register_operand" "=a")
2968         (call (mem:SI (unspec:SI [(match_operand:SI 1 "register_operand" "r")
2969                                   (match_operand:SI 2 "tls_symbol_operand" "")]
2970                                   UNSPEC_TLS_CALL))
2971               (match_operand 3 "" "i")))]
2972   "TARGET_THREADPTR && HAVE_AS_TLS"
2974   if (TARGET_WINDOWED_ABI)
2975     return "callx8.tls %1, %2@TLSCALL";
2976   else
2977     return "callx0.tls %1, %2@TLSCALL";
2979   [(set_attr "type"     "call")
2980    (set_attr "mode"     "none")
2981    (set_attr "length"   "3")])
2984 ;; Instructions for the Xtensa "boolean" option.
2986 (define_insn "*booltrue"
2987   [(set (pc)
2988         (if_then_else (match_operator 2 "boolean_operator"
2989                          [(match_operand:CC 0 "register_operand" "b")
2990                           (const_int 0)])
2991                       (label_ref (match_operand 1 "" ""))
2992                       (pc)))]
2993   "TARGET_BOOLEANS"
2995   if (GET_CODE (operands[2]) == EQ)
2996     return "bf\t%0, %1";
2997   else
2998     return "bt\t%0, %1";
3000   [(set_attr "type"     "jump")
3001    (set_attr "mode"     "none")
3002    (set_attr "length"   "3")])
3004 (define_insn "*boolfalse"
3005   [(set (pc)
3006         (if_then_else (match_operator 2 "boolean_operator"
3007                          [(match_operand:CC 0 "register_operand" "b")
3008                           (const_int 0)])
3009                       (pc)
3010                       (label_ref (match_operand 1 "" ""))))]
3011   "TARGET_BOOLEANS"
3013   if (GET_CODE (operands[2]) == EQ)
3014     return "bt\t%0, %1";
3015   else
3016     return "bf\t%0, %1";
3018   [(set_attr "type"     "jump")
3019    (set_attr "mode"     "none")
3020    (set_attr "length"   "3")])
3023 ;; Atomic operations
3025 (define_expand "memory_barrier"
3026   [(set (match_dup 0)
3027         (unspec:BLK [(match_dup 0)] UNSPEC_MEMW))]
3028   ""
3030   operands[0] = gen_rtx_MEM (BLKmode, gen_rtx_SCRATCH (Pmode));
3031   MEM_VOLATILE_P (operands[0]) = 1;
3034 (define_insn "*memory_barrier"
3035   [(set (match_operand:BLK 0 "" "")
3036         (unspec:BLK [(match_dup 0)] UNSPEC_MEMW))]
3037   ""
3038   "memw"
3039   [(set_attr "type"     "unknown")
3040    (set_attr "mode"     "none")
3041    (set_attr "length"   "3")])
3043 ;; sync_lock_release is only implemented for SImode.
3044 ;; For other modes, just use the default of a store with a memory_barrier.
3045 (define_insn "sync_lock_releasesi"
3046   [(set (match_operand:SI 0 "mem_operand" "=U")
3047         (unspec_volatile:SI
3048           [(match_operand:SI 1 "register_operand" "r")]
3049           UNSPECV_S32RI))]
3050   "TARGET_RELEASE_SYNC"
3051   "s32ri\t%1, %0"
3052   [(set_attr "type"     "store")
3053    (set_attr "mode"     "SI")
3054    (set_attr "length"   "3")])
3056 (define_insn "sync_compare_and_swapsi"
3057   [(parallel
3058     [(set (match_operand:SI 0 "register_operand" "=a")
3059           (match_operand:SI 1 "mem_operand" "+U"))
3060      (set (match_dup 1)
3061           (unspec_volatile:SI
3062             [(match_dup 1)
3063              (match_operand:SI 2 "register_operand" "r")
3064              (match_operand:SI 3 "register_operand" "0")]
3065             UNSPECV_S32C1I))])]
3066   "TARGET_S32C1I"
3067   "wsr\t%2, SCOMPARE1\;s32c1i\t%3, %1"
3068   [(set_attr "type"     "multi")
3069    (set_attr "mode"     "SI")
3070    (set_attr "length"   "6")])
3072 (define_expand "sync_compare_and_swap<mode>"
3073   [(parallel
3074     [(set (match_operand:HQI 0 "register_operand" "")
3075           (match_operand:HQI 1 "mem_operand" ""))
3076      (set (match_dup 1)
3077           (unspec_volatile:HQI
3078             [(match_dup 1)
3079              (match_operand:HQI 2 "register_operand" "")
3080              (match_operand:HQI 3 "register_operand" "")]
3081             UNSPECV_S32C1I))])]
3082   "TARGET_S32C1I"
3084   xtensa_expand_compare_and_swap (operands[0], operands[1],
3085                                   operands[2], operands[3]);
3086   DONE;
3089 (define_expand "sync_lock_test_and_set<mode>"
3090   [(match_operand:HQI 0 "register_operand")
3091    (match_operand:HQI 1 "memory_operand")
3092    (match_operand:HQI 2 "register_operand")]
3093   "TARGET_S32C1I"
3095   xtensa_expand_atomic (SET, operands[0], operands[1], operands[2], false);
3096   DONE;
3099 (define_expand "sync_<atomic><mode>"
3100   [(set (match_operand:HQI 0 "memory_operand")
3101         (ATOMIC:HQI (match_dup 0)
3102                     (match_operand:HQI 1 "register_operand")))]
3103   "TARGET_S32C1I"
3105   xtensa_expand_atomic (<CODE>, NULL_RTX, operands[0], operands[1], false);
3106   DONE;
3109 (define_expand "sync_old_<atomic><mode>"
3110   [(set (match_operand:HQI 0 "register_operand")
3111         (match_operand:HQI 1 "memory_operand"))
3112    (set (match_dup 1)
3113         (ATOMIC:HQI (match_dup 1)
3114                     (match_operand:HQI 2 "register_operand")))]
3115   "TARGET_S32C1I"
3117   xtensa_expand_atomic (<CODE>, operands[0], operands[1], operands[2], false);
3118   DONE;
3121 (define_expand "sync_new_<atomic><mode>"
3122   [(set (match_operand:HQI 0 "register_operand")
3123         (ATOMIC:HQI (match_operand:HQI 1 "memory_operand")
3124                     (match_operand:HQI 2 "register_operand")))
3125    (set (match_dup 1) (ATOMIC:HQI (match_dup 1) (match_dup 2)))]
3126   "TARGET_S32C1I"
3128   xtensa_expand_atomic (<CODE>, operands[0], operands[1], operands[2], true);
3129   DONE;
3132 (define_insn_and_split "*round_up_to_even"
3133   [(set (match_operand:SI 0 "register_operand" "=a")
3134         (and:SI (plus:SI (match_operand:SI 1 "register_operand" "r")
3135                          (const_int 1))
3136                 (const_int -2)))]
3137   ""
3138   "#"
3139   "can_create_pseudo_p ()"
3140   [(set (match_dup 2)
3141         (and:SI (match_dup 1)
3142                 (const_int 1)))
3143    (set (match_dup 0)
3144         (plus:SI (match_dup 2)
3145                  (match_dup 1)))]
3147   operands[2] = gen_reg_rtx (SImode);
3149   [(set_attr "type"     "arith")
3150    (set_attr "mode"     "SI")
3151    (set (attr "length")
3152         (if_then_else (match_test "TARGET_DENSITY")
3153                       (const_int 5)
3154                       (const_int 6)))])
3156 (define_insn_and_split "*signed_ge_zero"
3157   [(set (match_operand:SI 0 "register_operand" "=a")
3158         (ge:SI (match_operand:SI 1 "register_operand" "r")
3159                (const_int 0)))]
3160   ""
3161   "#"
3162   ""
3163   [(set (match_dup 0)
3164         (ashiftrt:SI (match_dup 1)
3165                      (const_int 31)))
3166    (set (match_dup 0)
3167         (plus:SI (match_dup 0)
3168                  (const_int 1)))]
3169   ""
3170   [(set_attr "type"     "arith")
3171    (set_attr "mode"     "SI")
3172    (set (attr "length")
3173         (if_then_else (match_test "TARGET_DENSITY")
3174                       (const_int 5)
3175                       (const_int 6)))])
3177 (define_insn_and_split "eq_zero_NSA"
3178   [(set (match_operand:SI 0 "register_operand" "=a")
3179         (eq:SI (match_operand:SI 1 "register_operand" "r")
3180                (const_int 0)))]
3181   "TARGET_NSA"
3182   "#"
3183   "&& 1"
3184   [(set (match_dup 0)
3185         (clz:SI (match_dup 1)))
3186    (set (match_dup 0)
3187         (lshiftrt:SI (match_dup 0)
3188                      (const_int 5)))]
3189   ""
3190   [(set_attr "type"     "move")
3191    (set_attr "mode"     "SI")
3192    (set_attr "length"   "6")])
3194 (define_insn_and_split "eqne_zero"
3195   [(set (match_operand:SI 0 "register_operand" "=a,&a")
3196         (match_operator:SI 2 "boolean_operator"
3197                 [(match_operand:SI 1 "register_operand" "0,r")
3198                  (const_int 0)]))
3199    (clobber (match_scratch:SI 3 "=&a,X"))]
3200   ""
3201   "#"
3202   "&& reload_completed"
3203   [(const_int 0)]
3205   enum rtx_code code = GET_CODE (operands[2]);
3206   int same_p = REGNO (operands[0]) == REGNO (operands[1]);
3207   emit_move_insn (same_p ? operands[3] : operands[0],
3208                   code == EQ ? constm1_rtx : const1_rtx);
3209   emit_insn (gen_movsicc_internal0 (operands[0], operands[1],
3210                                     same_p ? operands[3] : operands[1],
3211                                     operands[0],
3212                                     gen_rtx_fmt_ee (same_p ? NE : EQ,
3213                                                     VOIDmode,
3214                                                     operands[1],
3215                                                     const0_rtx)));
3216   if (code == EQ)
3217     emit_insn (gen_addsi3 (operands[0], operands[0], const1_rtx));
3218   DONE;
3220   [(set_attr "type"     "move")
3221    (set_attr "mode"     "SI")
3222    (set (attr "length")
3223         (if_then_else (match_test "GET_CODE (operands[2]) == EQ")
3224                       (if_then_else (match_test "TARGET_DENSITY")
3225                                     (const_int 7)
3226                                     (const_int 9))
3227                       (if_then_else (match_test "TARGET_DENSITY")
3228                                     (const_int 5)
3229                                     (const_int 6))))])
3231 (define_insn_and_split "*eqne_zero_masked_bits"
3232   [(set (match_operand:SI 0 "register_operand" "=a")
3233         (match_operator:SI 3 "boolean_operator"
3234                 [(and:SI (match_operand:SI 1 "register_operand" "r")
3235                          (match_operand:SI 2 "const_int_operand" "i"))
3236                  (const_int 0)]))]
3237   "IN_RANGE (exact_log2 (INTVAL (operands[2]) + 1), 17, 31)
3238    || IN_RANGE (exact_log2 (-INTVAL (operands[2])), 1, 30)"
3239   "#"
3240   "&& 1"
3241   [(const_int 0)]
3243   HOST_WIDE_INT mask = INTVAL (operands[2]);
3244   int n;
3245   enum rtx_code code = GET_CODE (operands[3]);
3246   if (IN_RANGE (n = exact_log2 (mask + 1), 17, 31))
3247     emit_insn (gen_ashlsi3 (operands[0], operands[1], GEN_INT (32 - n)));
3248   else
3249     emit_insn (gen_lshrsi3 (operands[0], operands[1],
3250                             GEN_INT (floor_log2 (-mask))));
3251   if (TARGET_NSA && code == EQ)
3252     emit_insn (gen_eq_zero_NSA (operands[0], operands[0]));
3253   else
3254     emit_insn (gen_eqne_zero (operands[0], operands[0],
3255                               gen_rtx_fmt_ee (code, VOIDmode,
3256                                               operands[0], const0_rtx)));
3257   DONE;
3260 (define_insn_and_split "*eqne_INT_MIN"
3261   [(set (match_operand:SI 0 "register_operand" "=a")
3262         (match_operator:SI 2 "boolean_operator"
3263                 [(match_operand:SI 1 "register_operand" "r")
3264                  (const_int -2147483648)]))]
3265   "TARGET_ABS"
3266   "#"
3267   "&& 1"
3268   [(const_int 0)]
3270   emit_insn (gen_abssi2 (operands[0], operands[1]));
3271   if (GET_CODE (operands[2]) == EQ)
3272     emit_insn (gen_lshrsi3 (operands[0], operands[0], GEN_INT (31)));
3273   else
3274     {
3275       emit_insn (gen_ashrsi3 (operands[0], operands[0], GEN_INT (31)));
3276       emit_insn (gen_addsi3 (operands[0], operands[0], const1_rtx));
3277     }
3278   DONE;
3280   [(set_attr "type"     "move")
3281    (set_attr "mode"     "SI")
3282    (set (attr "length")
3283         (if_then_else (match_test "GET_CODE (operands[2]) == EQ")
3284                       (const_int 6)
3285                       (if_then_else (match_test "TARGET_DENSITY")
3286                                     (const_int 8)
3287                                     (const_int 9))))])
3289 (define_peephole2
3290   [(set (match_operand:SI 0 "register_operand")
3291         (match_operand:SI 6 "reload_operand"))
3292    (set (match_operand:SI 1 "register_operand")
3293         (match_operand:SI 7 "reload_operand"))
3294    (set (match_operand:SF 2 "register_operand")
3295         (match_operand:SF 4 "register_operand"))
3296    (set (match_operand:SF 3 "register_operand")
3297         (match_operand:SF 5 "register_operand"))]
3298   "REGNO (operands[0]) == REGNO (operands[4])
3299    && REGNO (operands[1]) == REGNO (operands[5])
3300    && peep2_reg_dead_p (4, operands[0])
3301    && peep2_reg_dead_p (4, operands[1])"
3302   [(set (match_dup 2)
3303         (match_dup 6))
3304    (set (match_dup 3)
3305         (match_dup 7))]
3307   HARD_REG_SET regs;
3308   int i;
3309   CLEAR_HARD_REG_SET (regs);
3310   for (i = 0; i <= 3; ++i)
3311     if (TEST_HARD_REG_BIT (regs, REGNO (operands[i])))
3312       FAIL;
3313     else
3314       SET_HARD_REG_BIT (regs, REGNO (operands[i]));
3315   operands[6] = gen_rtx_MEM (SFmode, XEXP (operands[6], 0));
3316   operands[7] = gen_rtx_MEM (SFmode, XEXP (operands[7], 0));
3319 (define_split
3320   [(clobber (match_operand 0 "register_operand"))]
3321   "HARD_REGISTER_P (operands[0])
3322    && COMPLEX_MODE_P (GET_MODE (operands[0]))"
3323   [(const_int 0)]
3325   auto_sbitmap bmp (FIRST_PSEUDO_REGISTER);
3326   rtx_insn *insn;
3327   rtx reg = gen_rtx_REG (SImode, 0), dest;
3328   unsigned int regno;
3329   sbitmap_iterator iter;
3330   bitmap_set_range (bmp, REGNO (operands[0]), REG_NREGS (operands[0]));
3331   for (insn = next_nonnote_nondebug_insn_bb (curr_insn);
3332        insn; insn = next_nonnote_nondebug_insn_bb (insn))
3333     if (NONJUMP_INSN_P (insn))
3334       {
3335         EXECUTE_IF_SET_IN_BITMAP (bmp, 2, regno, iter)
3336           {
3337             set_regno_raw (reg, regno, REG_NREGS (reg));
3338             if (reg_referenced_p (reg, PATTERN (insn)))
3339               goto ABORT;
3340           }
3341         if (GET_CODE (PATTERN (insn)) == SET
3342             || GET_CODE (PATTERN (insn)) == CLOBBER)
3343           {
3344             dest = SET_DEST (PATTERN (insn));
3345             if (REG_P (dest) && HARD_REGISTER_P (dest))
3346               bitmap_clear_range (bmp, REGNO (dest), REG_NREGS (dest));
3347             else if (SUBREG_P (dest)
3348                      && HARD_REGISTER_P (SUBREG_REG (dest)))
3349               {
3350                 struct subreg_info info;
3351                 subreg_get_info (regno = REGNO (SUBREG_REG (dest)),
3352                                  GET_MODE (SUBREG_REG (dest)),
3353                                  SUBREG_BYTE (dest), GET_MODE (dest),
3354                                  &info);
3355                 if (!info.representable_p)
3356                   break;
3357                 bitmap_clear_range (bmp, regno + info.offset, info.nregs);
3358               }
3359           }
3360         if (bitmap_empty_p (bmp))
3361           goto FALLTHRU;
3362       }
3363     else if (CALL_P (insn))
3364       EXECUTE_IF_SET_IN_BITMAP (bmp, 2, regno, iter)
3365         if (call_used_or_fixed_reg_p (regno))
3366           goto ABORT;
3367 ABORT:
3368   FAIL;
3369 FALLTHRU:;
3372 (define_peephole2
3373   [(set (match_operand:SI 0 "register_operand")
3374         (match_operand:SI 1 "const_int_operand"))
3375    (set (match_dup 0)
3376         (plus:SI (match_dup 0)
3377                  (match_operand:SI 2 "const_int_operand")))
3378    (set (match_operand:SI 3 "register_operand")
3379         (plus:SI (match_operand:SI 4 "register_operand")
3380                  (match_dup 0)))]
3381   "IN_RANGE (INTVAL (operands[1]) + INTVAL (operands[2]),
3382              (-128 - 32768), (127 + 32512))
3383    && REGNO (operands[0]) != REGNO (operands[3])
3384    && REGNO (operands[0]) != REGNO (operands[4])
3385    && peep2_reg_dead_p (3, operands[0])"
3386   [(set (match_dup 3)
3387         (plus:SI (match_dup 4)
3388                  (match_dup 1)))
3389    (set (match_dup 3)
3390         (plus:SI (match_dup 3)
3391                  (match_dup 2)))]
3393   HOST_WIDE_INT value = INTVAL (operands[1]) + INTVAL (operands[2]);
3394   int imm0, imm1;
3395   value += 128;
3396   if (value > 32512)
3397     imm1 = 32512;
3398   else
3399     imm1 = value & ~255;
3400   imm0 = value - imm1 - 128;
3401   operands[1] = GEN_INT (imm0);
3402   operands[2] = GEN_INT (imm1);
3405 (define_peephole2
3406   [(set (match_operand 0 "register_operand")
3407         (match_operand 1 "register_operand"))]
3408   "REG_NREGS (operands[0]) == 1 && GP_REG_P (REGNO (operands[0]))
3409    && REG_NREGS (operands[1]) == 1 && GP_REG_P (REGNO (operands[1]))
3410    && peep2_reg_dead_p (1, operands[1])"
3411   [(const_int 0)]
3413   basic_block bb = BLOCK_FOR_INSN (curr_insn);
3414   rtx_insn *head = BB_HEAD (bb), *insn;
3415   rtx dest = operands[0], src = operands[1], pattern, t_dest, dest_orig;
3416   for (insn = PREV_INSN (curr_insn);
3417        insn && insn != head;
3418        insn = PREV_INSN (insn))
3419     if (CALL_P (insn))
3420       break;
3421     else if (INSN_P (insn))
3422       {
3423         if (GET_CODE (pattern = PATTERN (insn)) == SET
3424             && REG_P (t_dest = SET_DEST (pattern))
3425             && REG_NREGS (t_dest) == 1
3426             && REGNO (t_dest) == REGNO (src))
3427         {
3428           dest_orig = SET_DEST (pattern);
3429           SET_DEST (pattern) = gen_rtx_REG (GET_MODE (t_dest),
3430                                             REGNO (dest));
3431           extract_insn (insn);
3432           if (!constrain_operands (true, get_enabled_alternatives (insn)))
3433             {
3434               SET_DEST (pattern) = dest_orig;
3435               goto ABORT;
3436             }
3437           df_insn_rescan (insn);
3438           goto FALLTHRU;
3439         }
3440         if (reg_overlap_mentioned_p (dest, pattern)
3441             || reg_overlap_mentioned_p (src, pattern)
3442             || set_of (dest, insn)
3443             || set_of (src, insn))
3444           break;
3445       }
3446 ABORT:
3447   FAIL;
3448 FALLTHRU:;