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