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