1 ;; GCC machine description for Tensilica's Xtensa architecture.
2 ;; Copyright (C) 2001, 2002, 2003, 2004, 2005, 2006, 2007, 2008
3 ;; Free Software Foundation, Inc.
4 ;; Contributed by Bob Wilson (bwilson@tensilica.com) at Tensilica.
6 ;; This file is part of GCC.
8 ;; GCC is free software; you can redistribute it and/or modify it
9 ;; under the terms of the GNU General Public License as published by
10 ;; the Free Software Foundation; either version 3, or (at your option)
13 ;; GCC is distributed in the hope that it will be useful, but WITHOUT
14 ;; ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
15 ;; or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public
16 ;; License for more details.
18 ;; You should have received a copy of the GNU General Public License
19 ;; along with GCC; see the file COPYING3. If not see
20 ;; <http://www.gnu.org/licenses/>.
41 ;; This code iterator allows signed and unsigned widening multiplications
42 ;; to use the same template.
43 (define_code_iterator any_extend [sign_extend zero_extend])
45 ;; <u> expands to an empty string when doing a signed operation and
46 ;; "u" when doing an unsigned operation.
47 (define_code_attr u [(sign_extend "") (zero_extend "u")])
49 ;; <su> is like <u>, but the signed form expands to "s" rather than "".
50 (define_code_attr su [(sign_extend "s") (zero_extend "u")])
52 ;; This code iterator allows four integer min/max operations to be
53 ;; generated from one template.
54 (define_code_iterator any_minmax [smin umin smax umax])
56 ;; <minmax> expands to the opcode name for any_minmax operations.
57 (define_code_attr minmax [(smin "min") (umin "minu")
58 (smax "max") (umax "maxu")])
60 ;; This code iterator allows all branch instructions to be generated from
61 ;; a single define_expand template.
62 (define_code_iterator any_cond [eq ne gt ge lt le gtu geu ltu leu
63 uneq ltgt ungt unge unlt unle
66 ;; This code iterator is for setting a register from a comparison.
67 (define_code_iterator any_scc [eq ne gt ge lt le])
69 ;; This code iterator is for floating-point comparisons.
70 (define_code_iterator any_scc_sf [eq lt le uneq unlt unle unordered])
71 (define_code_attr scc_sf [(eq "oeq") (lt "olt") (le "ole")
72 (uneq "ueq") (unlt "ult") (unle "ule")
75 ;; This iterator and attribute allow to combine most atomic operations.
76 (define_code_iterator ATOMIC [and ior xor plus minus mult])
77 (define_code_attr atomic [(and "and") (ior "ior") (xor "xor")
78 (plus "add") (minus "sub") (mult "nand")])
80 ;; This mode iterator allows the HI and QI patterns to be defined from
82 (define_mode_iterator HQI [HI QI])
88 "unknown,jump,call,load,store,move,arith,multi,nop,farith,fmadd,fdiv,fsqrt,fconv,fload,fstore,mul16,mul32,div32,mac16,rsr,wsr,entry"
89 (const_string "unknown"))
92 "unknown,none,QI,HI,SI,DI,SF,DF,BL"
93 (const_string "unknown"))
95 (define_attr "length" "" (const_int 1))
97 ;; Describe a user's asm statement.
98 (define_asm_attributes
99 [(set_attr "type" "multi")])
104 ;; The Xtensa basically has simple 5-stage RISC pipeline.
105 ;; Most instructions complete in 1 cycle, and it is OK to assume that
106 ;; everything is fully pipelined. The exceptions have special insn
107 ;; reservations in the pipeline description below. The Xtensa can
108 ;; issue one instruction per cycle, so defining CPU units is unnecessary.
110 (define_insn_reservation "xtensa_any_insn" 1
111 (eq_attr "type" "!load,fload,rsr,mul16,mul32,fmadd,fconv")
114 (define_insn_reservation "xtensa_memory" 2
115 (eq_attr "type" "load,fload")
118 (define_insn_reservation "xtensa_sreg" 2
119 (eq_attr "type" "rsr")
122 (define_insn_reservation "xtensa_mul16" 2
123 (eq_attr "type" "mul16")
126 (define_insn_reservation "xtensa_mul32" 2
127 (eq_attr "type" "mul32")
130 (define_insn_reservation "xtensa_fmadd" 4
131 (eq_attr "type" "fmadd")
134 (define_insn_reservation "xtensa_fconv" 2
135 (eq_attr "type" "fconv")
138 ;; Include predicates and constraints.
140 (include "predicates.md")
141 (include "constraints.md")
146 (define_insn "addsi3"
147 [(set (match_operand:SI 0 "register_operand" "=D,D,a,a,a")
148 (plus:SI (match_operand:SI 1 "register_operand" "%d,d,r,r,r")
149 (match_operand:SI 2 "add_operand" "d,O,r,J,N")))]
157 [(set_attr "type" "arith,arith,arith,arith,arith")
158 (set_attr "mode" "SI")
159 (set_attr "length" "2,2,3,3,3")])
162 [(set (match_operand:SI 0 "register_operand" "=a")
163 (plus:SI (mult:SI (match_operand:SI 1 "register_operand" "r")
164 (match_operand:SI 3 "addsubx_operand" "i"))
165 (match_operand:SI 2 "register_operand" "r")))]
168 [(set_attr "type" "arith")
169 (set_attr "mode" "SI")
170 (set_attr "length" "3")])
172 (define_insn "addsf3"
173 [(set (match_operand:SF 0 "register_operand" "=f")
174 (plus:SF (match_operand:SF 1 "register_operand" "%f")
175 (match_operand:SF 2 "register_operand" "f")))]
178 [(set_attr "type" "fmadd")
179 (set_attr "mode" "SF")
180 (set_attr "length" "3")])
185 (define_insn "subsi3"
186 [(set (match_operand:SI 0 "register_operand" "=a")
187 (minus:SI (match_operand:SI 1 "register_operand" "r")
188 (match_operand:SI 2 "register_operand" "r")))]
191 [(set_attr "type" "arith")
192 (set_attr "mode" "SI")
193 (set_attr "length" "3")])
196 [(set (match_operand:SI 0 "register_operand" "=a")
197 (minus:SI (mult:SI (match_operand:SI 1 "register_operand" "r")
198 (match_operand:SI 3 "addsubx_operand" "i"))
199 (match_operand:SI 2 "register_operand" "r")))]
202 [(set_attr "type" "arith")
203 (set_attr "mode" "SI")
204 (set_attr "length" "3")])
206 (define_insn "subsf3"
207 [(set (match_operand:SF 0 "register_operand" "=f")
208 (minus:SF (match_operand:SF 1 "register_operand" "f")
209 (match_operand:SF 2 "register_operand" "f")))]
212 [(set_attr "type" "fmadd")
213 (set_attr "mode" "SF")
214 (set_attr "length" "3")])
219 (define_expand "<u>mulsidi3"
220 [(set (match_operand:DI 0 "register_operand")
221 (mult:DI (any_extend:DI (match_operand:SI 1 "register_operand"))
222 (any_extend:DI (match_operand:SI 2 "register_operand"))))]
225 rtx temp = gen_reg_rtx (SImode);
226 emit_insn (gen_mulsi3 (temp, operands[1], operands[2]));
227 emit_insn (gen_<u>mulsi3_highpart (gen_highpart (SImode, operands[0]),
228 operands[1], operands[2]));
229 emit_insn (gen_movsi (gen_lowpart (SImode, operands[0]), temp));
233 (define_insn "<u>mulsi3_highpart"
234 [(set (match_operand:SI 0 "register_operand" "=a")
237 (mult:DI (any_extend:DI (match_operand:SI 1 "register_operand" "%r"))
238 (any_extend:DI (match_operand:SI 2 "register_operand" "r")))
241 "mul<su>h\t%0, %1, %2"
242 [(set_attr "type" "mul32")
243 (set_attr "mode" "SI")
244 (set_attr "length" "3")])
246 (define_insn "mulsi3"
247 [(set (match_operand:SI 0 "register_operand" "=a")
248 (mult:SI (match_operand:SI 1 "register_operand" "%r")
249 (match_operand:SI 2 "register_operand" "r")))]
252 [(set_attr "type" "mul32")
253 (set_attr "mode" "SI")
254 (set_attr "length" "3")])
256 (define_insn "mulhisi3"
257 [(set (match_operand:SI 0 "register_operand" "=C,A")
258 (mult:SI (sign_extend:SI
259 (match_operand:HI 1 "register_operand" "%r,r"))
261 (match_operand:HI 2 "register_operand" "r,r"))))]
262 "TARGET_MUL16 || TARGET_MAC16"
266 [(set_attr "type" "mul16,mac16")
267 (set_attr "mode" "SI")
268 (set_attr "length" "3,3")])
270 (define_insn "umulhisi3"
271 [(set (match_operand:SI 0 "register_operand" "=C,A")
272 (mult:SI (zero_extend:SI
273 (match_operand:HI 1 "register_operand" "%r,r"))
275 (match_operand:HI 2 "register_operand" "r,r"))))]
276 "TARGET_MUL16 || TARGET_MAC16"
280 [(set_attr "type" "mul16,mac16")
281 (set_attr "mode" "SI")
282 (set_attr "length" "3,3")])
284 (define_insn "muladdhisi"
285 [(set (match_operand:SI 0 "register_operand" "=A")
286 (plus:SI (mult:SI (sign_extend:SI
287 (match_operand:HI 1 "register_operand" "%r"))
289 (match_operand:HI 2 "register_operand" "r")))
290 (match_operand:SI 3 "register_operand" "0")))]
293 [(set_attr "type" "mac16")
294 (set_attr "mode" "SI")
295 (set_attr "length" "3")])
297 (define_insn "mulsubhisi"
298 [(set (match_operand:SI 0 "register_operand" "=A")
299 (minus:SI (match_operand:SI 1 "register_operand" "0")
300 (mult:SI (sign_extend:SI
301 (match_operand:HI 2 "register_operand" "%r"))
303 (match_operand:HI 3 "register_operand" "r")))))]
306 [(set_attr "type" "mac16")
307 (set_attr "mode" "SI")
308 (set_attr "length" "3")])
310 (define_insn "mulsf3"
311 [(set (match_operand:SF 0 "register_operand" "=f")
312 (mult:SF (match_operand:SF 1 "register_operand" "%f")
313 (match_operand:SF 2 "register_operand" "f")))]
316 [(set_attr "type" "fmadd")
317 (set_attr "mode" "SF")
318 (set_attr "length" "3")])
320 (define_insn "muladdsf3"
321 [(set (match_operand:SF 0 "register_operand" "=f")
322 (plus:SF (mult:SF (match_operand:SF 1 "register_operand" "%f")
323 (match_operand:SF 2 "register_operand" "f"))
324 (match_operand:SF 3 "register_operand" "0")))]
325 "TARGET_HARD_FLOAT && TARGET_FUSED_MADD"
327 [(set_attr "type" "fmadd")
328 (set_attr "mode" "SF")
329 (set_attr "length" "3")])
331 (define_insn "mulsubsf3"
332 [(set (match_operand:SF 0 "register_operand" "=f")
333 (minus:SF (match_operand:SF 1 "register_operand" "0")
334 (mult:SF (match_operand:SF 2 "register_operand" "%f")
335 (match_operand:SF 3 "register_operand" "f"))))]
336 "TARGET_HARD_FLOAT && TARGET_FUSED_MADD"
338 [(set_attr "type" "fmadd")
339 (set_attr "mode" "SF")
340 (set_attr "length" "3")])
345 (define_insn "divsi3"
346 [(set (match_operand:SI 0 "register_operand" "=a")
347 (div:SI (match_operand:SI 1 "register_operand" "r")
348 (match_operand:SI 2 "register_operand" "r")))]
351 [(set_attr "type" "div32")
352 (set_attr "mode" "SI")
353 (set_attr "length" "3")])
355 (define_insn "udivsi3"
356 [(set (match_operand:SI 0 "register_operand" "=a")
357 (udiv:SI (match_operand:SI 1 "register_operand" "r")
358 (match_operand:SI 2 "register_operand" "r")))]
361 [(set_attr "type" "div32")
362 (set_attr "mode" "SI")
363 (set_attr "length" "3")])
365 (define_insn "divsf3"
366 [(set (match_operand:SF 0 "register_operand" "=f")
367 (div:SF (match_operand:SF 1 "register_operand" "f")
368 (match_operand:SF 2 "register_operand" "f")))]
369 "TARGET_HARD_FLOAT_DIV"
371 [(set_attr "type" "fdiv")
372 (set_attr "mode" "SF")
373 (set_attr "length" "3")])
375 (define_insn "*recipsf2"
376 [(set (match_operand:SF 0 "register_operand" "=f")
377 (div:SF (match_operand:SF 1 "const_float_1_operand" "")
378 (match_operand:SF 2 "register_operand" "f")))]
379 "TARGET_HARD_FLOAT_RECIP && flag_unsafe_math_optimizations"
381 [(set_attr "type" "fdiv")
382 (set_attr "mode" "SF")
383 (set_attr "length" "3")])
388 (define_insn "modsi3"
389 [(set (match_operand:SI 0 "register_operand" "=a")
390 (mod:SI (match_operand:SI 1 "register_operand" "r")
391 (match_operand:SI 2 "register_operand" "r")))]
394 [(set_attr "type" "div32")
395 (set_attr "mode" "SI")
396 (set_attr "length" "3")])
398 (define_insn "umodsi3"
399 [(set (match_operand:SI 0 "register_operand" "=a")
400 (umod:SI (match_operand:SI 1 "register_operand" "r")
401 (match_operand:SI 2 "register_operand" "r")))]
404 [(set_attr "type" "div32")
405 (set_attr "mode" "SI")
406 (set_attr "length" "3")])
411 (define_insn "sqrtsf2"
412 [(set (match_operand:SF 0 "register_operand" "=f")
413 (sqrt:SF (match_operand:SF 1 "register_operand" "f")))]
414 "TARGET_HARD_FLOAT_SQRT"
416 [(set_attr "type" "fsqrt")
417 (set_attr "mode" "SF")
418 (set_attr "length" "3")])
420 (define_insn "*rsqrtsf2"
421 [(set (match_operand:SF 0 "register_operand" "=f")
422 (div:SF (match_operand:SF 1 "const_float_1_operand" "")
423 (sqrt:SF (match_operand:SF 2 "register_operand" "f"))))]
424 "TARGET_HARD_FLOAT_RSQRT && flag_unsafe_math_optimizations"
426 [(set_attr "type" "fsqrt")
427 (set_attr "mode" "SF")
428 (set_attr "length" "3")])
433 (define_insn "abssi2"
434 [(set (match_operand:SI 0 "register_operand" "=a")
435 (abs:SI (match_operand:SI 1 "register_operand" "r")))]
438 [(set_attr "type" "arith")
439 (set_attr "mode" "SI")
440 (set_attr "length" "3")])
442 (define_insn "abssf2"
443 [(set (match_operand:SF 0 "register_operand" "=f")
444 (abs:SF (match_operand:SF 1 "register_operand" "f")))]
447 [(set_attr "type" "farith")
448 (set_attr "mode" "SF")
449 (set_attr "length" "3")])
454 (define_insn "<code>si3"
455 [(set (match_operand:SI 0 "register_operand" "=a")
456 (any_minmax:SI (match_operand:SI 1 "register_operand" "%r")
457 (match_operand:SI 2 "register_operand" "r")))]
459 "<minmax>\t%0, %1, %2"
460 [(set_attr "type" "arith")
461 (set_attr "mode" "SI")
462 (set_attr "length" "3")])
465 ;; Count leading/trailing zeros and find first bit.
467 (define_insn "clzsi2"
468 [(set (match_operand:SI 0 "register_operand" "=a")
469 (clz:SI (match_operand:SI 1 "register_operand" "r")))]
472 [(set_attr "type" "arith")
473 (set_attr "mode" "SI")
474 (set_attr "length" "3")])
476 (define_expand "ctzsi2"
477 [(set (match_operand:SI 0 "register_operand" "")
478 (ctz:SI (match_operand:SI 1 "register_operand" "")))]
481 rtx temp = gen_reg_rtx (SImode);
482 emit_insn (gen_negsi2 (temp, operands[1]));
483 emit_insn (gen_andsi3 (temp, temp, operands[1]));
484 emit_insn (gen_clzsi2 (temp, temp));
485 emit_insn (gen_negsi2 (temp, temp));
486 emit_insn (gen_addsi3 (operands[0], temp, GEN_INT (31)));
490 (define_expand "ffssi2"
491 [(set (match_operand:SI 0 "register_operand" "")
492 (ffs:SI (match_operand:SI 1 "register_operand" "")))]
495 rtx temp = gen_reg_rtx (SImode);
496 emit_insn (gen_negsi2 (temp, operands[1]));
497 emit_insn (gen_andsi3 (temp, temp, operands[1]));
498 emit_insn (gen_clzsi2 (temp, temp));
499 emit_insn (gen_negsi2 (temp, temp));
500 emit_insn (gen_addsi3 (operands[0], temp, GEN_INT (32)));
505 ;; Negation and one's complement.
507 (define_insn "negsi2"
508 [(set (match_operand:SI 0 "register_operand" "=a")
509 (neg:SI (match_operand:SI 1 "register_operand" "r")))]
512 [(set_attr "type" "arith")
513 (set_attr "mode" "SI")
514 (set_attr "length" "3")])
516 (define_expand "one_cmplsi2"
517 [(set (match_operand:SI 0 "register_operand" "")
518 (not:SI (match_operand:SI 1 "register_operand" "")))]
521 rtx temp = gen_reg_rtx (SImode);
522 emit_insn (gen_movsi (temp, constm1_rtx));
523 emit_insn (gen_xorsi3 (operands[0], temp, operands[1]));
527 (define_insn "negsf2"
528 [(set (match_operand:SF 0 "register_operand" "=f")
529 (neg:SF (match_operand:SF 1 "register_operand" "f")))]
532 [(set_attr "type" "farith")
533 (set_attr "mode" "SF")
534 (set_attr "length" "3")])
537 ;; Logical instructions.
539 (define_insn "andsi3"
540 [(set (match_operand:SI 0 "register_operand" "=a,a")
541 (and:SI (match_operand:SI 1 "register_operand" "%r,r")
542 (match_operand:SI 2 "mask_operand" "P,r")))]
545 extui\t%0, %1, 0, %K2
547 [(set_attr "type" "arith,arith")
548 (set_attr "mode" "SI")
549 (set_attr "length" "3,3")])
551 (define_insn "iorsi3"
552 [(set (match_operand:SI 0 "register_operand" "=a")
553 (ior:SI (match_operand:SI 1 "register_operand" "%r")
554 (match_operand:SI 2 "register_operand" "r")))]
557 [(set_attr "type" "arith")
558 (set_attr "mode" "SI")
559 (set_attr "length" "3")])
561 (define_insn "xorsi3"
562 [(set (match_operand:SI 0 "register_operand" "=a")
563 (xor:SI (match_operand:SI 1 "register_operand" "%r")
564 (match_operand:SI 2 "register_operand" "r")))]
567 [(set_attr "type" "arith")
568 (set_attr "mode" "SI")
569 (set_attr "length" "3")])
572 ;; Zero-extend instructions.
574 (define_insn "zero_extendhisi2"
575 [(set (match_operand:SI 0 "register_operand" "=a,a")
576 (zero_extend:SI (match_operand:HI 1 "nonimmed_operand" "r,U")))]
581 [(set_attr "type" "arith,load")
582 (set_attr "mode" "SI")
583 (set_attr "length" "3,3")])
585 (define_insn "zero_extendqisi2"
586 [(set (match_operand:SI 0 "register_operand" "=a,a")
587 (zero_extend:SI (match_operand:QI 1 "nonimmed_operand" "r,U")))]
592 [(set_attr "type" "arith,load")
593 (set_attr "mode" "SI")
594 (set_attr "length" "3,3")])
597 ;; Sign-extend instructions.
599 (define_expand "extendhisi2"
600 [(set (match_operand:SI 0 "register_operand" "")
601 (sign_extend:SI (match_operand:HI 1 "register_operand" "")))]
604 if (sext_operand (operands[1], HImode))
605 emit_insn (gen_extendhisi2_internal (operands[0], operands[1]));
607 xtensa_extend_reg (operands[0], operands[1]);
611 (define_insn "extendhisi2_internal"
612 [(set (match_operand:SI 0 "register_operand" "=B,a")
613 (sign_extend:SI (match_operand:HI 1 "sext_operand" "r,U")))]
618 [(set_attr "type" "arith,load")
619 (set_attr "mode" "SI")
620 (set_attr "length" "3,3")])
622 (define_expand "extendqisi2"
623 [(set (match_operand:SI 0 "register_operand" "")
624 (sign_extend:SI (match_operand:QI 1 "register_operand" "")))]
628 emit_insn (gen_extendqisi2_internal (operands[0], operands[1]));
630 xtensa_extend_reg (operands[0], operands[1]);
634 (define_insn "extendqisi2_internal"
635 [(set (match_operand:SI 0 "register_operand" "=B")
636 (sign_extend:SI (match_operand:QI 1 "register_operand" "r")))]
639 [(set_attr "type" "arith")
640 (set_attr "mode" "SI")
641 (set_attr "length" "3")])
644 ;; Field extract instructions.
646 (define_expand "extv"
647 [(set (match_operand:SI 0 "register_operand" "")
648 (sign_extract:SI (match_operand:SI 1 "register_operand" "")
649 (match_operand:SI 2 "const_int_operand" "")
650 (match_operand:SI 3 "const_int_operand" "")))]
653 if (!sext_fldsz_operand (operands[2], SImode))
656 /* We could expand to a right shift followed by SEXT but that's
657 no better than the standard left and right shift sequence. */
658 if (!lsbitnum_operand (operands[3], SImode))
661 emit_insn (gen_extv_internal (operands[0], operands[1],
662 operands[2], operands[3]));
666 (define_insn "extv_internal"
667 [(set (match_operand:SI 0 "register_operand" "=a")
668 (sign_extract:SI (match_operand:SI 1 "register_operand" "r")
669 (match_operand:SI 2 "sext_fldsz_operand" "i")
670 (match_operand:SI 3 "lsbitnum_operand" "i")))]
673 int fldsz = INTVAL (operands[2]);
674 operands[2] = GEN_INT (fldsz - 1);
675 return "sext\t%0, %1, %2";
677 [(set_attr "type" "arith")
678 (set_attr "mode" "SI")
679 (set_attr "length" "3")])
681 (define_expand "extzv"
682 [(set (match_operand:SI 0 "register_operand" "")
683 (zero_extract:SI (match_operand:SI 1 "register_operand" "")
684 (match_operand:SI 2 "const_int_operand" "")
685 (match_operand:SI 3 "const_int_operand" "")))]
688 if (!extui_fldsz_operand (operands[2], SImode))
690 emit_insn (gen_extzv_internal (operands[0], operands[1],
691 operands[2], operands[3]));
695 (define_insn "extzv_internal"
696 [(set (match_operand:SI 0 "register_operand" "=a")
697 (zero_extract:SI (match_operand:SI 1 "register_operand" "r")
698 (match_operand:SI 2 "extui_fldsz_operand" "i")
699 (match_operand:SI 3 "const_int_operand" "i")))]
704 shift = (32 - (INTVAL (operands[2]) + INTVAL (operands[3]))) & 0x1f;
706 shift = INTVAL (operands[3]) & 0x1f;
707 operands[3] = GEN_INT (shift);
708 return "extui\t%0, %1, %3, %2";
710 [(set_attr "type" "arith")
711 (set_attr "mode" "SI")
712 (set_attr "length" "3")])
717 (define_insn "fix_truncsfsi2"
718 [(set (match_operand:SI 0 "register_operand" "=a")
719 (fix:SI (match_operand:SF 1 "register_operand" "f")))]
722 [(set_attr "type" "fconv")
723 (set_attr "mode" "SF")
724 (set_attr "length" "3")])
726 (define_insn "fixuns_truncsfsi2"
727 [(set (match_operand:SI 0 "register_operand" "=a")
728 (unsigned_fix:SI (match_operand:SF 1 "register_operand" "f")))]
730 "utrunc.s\t%0, %1, 0"
731 [(set_attr "type" "fconv")
732 (set_attr "mode" "SF")
733 (set_attr "length" "3")])
735 (define_insn "floatsisf2"
736 [(set (match_operand:SF 0 "register_operand" "=f")
737 (float:SF (match_operand:SI 1 "register_operand" "a")))]
740 [(set_attr "type" "fconv")
741 (set_attr "mode" "SF")
742 (set_attr "length" "3")])
744 (define_insn "floatunssisf2"
745 [(set (match_operand:SF 0 "register_operand" "=f")
746 (unsigned_float:SF (match_operand:SI 1 "register_operand" "a")))]
748 "ufloat.s\t%0, %1, 0"
749 [(set_attr "type" "fconv")
750 (set_attr "mode" "SF")
751 (set_attr "length" "3")])
754 ;; Data movement instructions.
756 ;; 64-bit Integer moves
758 (define_expand "movdi"
759 [(set (match_operand:DI 0 "nonimmed_operand" "")
760 (match_operand:DI 1 "general_operand" ""))]
763 if (CONSTANT_P (operands[1]) && !TARGET_CONST16)
764 operands[1] = force_const_mem (DImode, operands[1]);
766 if (!register_operand (operands[0], DImode)
767 && !register_operand (operands[1], DImode))
768 operands[1] = force_reg (DImode, operands[1]);
770 operands[1] = xtensa_copy_incoming_a7 (operands[1]);
773 (define_insn_and_split "movdi_internal"
774 [(set (match_operand:DI 0 "nonimmed_operand" "=a,W,a,a,U")
775 (match_operand:DI 1 "move_operand" "r,i,T,U,r"))]
776 "register_operand (operands[0], DImode)
777 || register_operand (operands[1], DImode)"
780 [(set (match_dup 0) (match_dup 2))
781 (set (match_dup 1) (match_dup 3))]
783 xtensa_split_operand_pair (operands, SImode);
784 if (reg_overlap_mentioned_p (operands[0], operands[3]))
787 tmp = operands[0], operands[0] = operands[1], operands[1] = tmp;
788 tmp = operands[2], operands[2] = operands[3], operands[3] = tmp;
792 ;; 32-bit Integer moves
794 (define_expand "movsi"
795 [(set (match_operand:SI 0 "nonimmed_operand" "")
796 (match_operand:SI 1 "general_operand" ""))]
799 if (xtensa_emit_move_sequence (operands, SImode))
803 (define_insn "movsi_internal"
804 [(set (match_operand:SI 0 "nonimmed_operand" "=D,D,D,D,R,R,a,q,a,W,a,a,U,*a,*A")
805 (match_operand:SI 1 "move_operand" "M,D,d,R,D,d,r,r,I,i,T,U,r,*A,*r"))]
806 "xtensa_valid_move (SImode, operands)"
817 const16\t%0, %t1\;const16\t%0, %b1
823 [(set_attr "type" "move,move,move,load,store,store,move,move,move,move,load,load,store,rsr,wsr")
824 (set_attr "mode" "SI")
825 (set_attr "length" "2,2,2,2,2,2,3,3,3,6,3,3,3,3,3")])
827 ;; 16-bit Integer moves
829 (define_expand "movhi"
830 [(set (match_operand:HI 0 "nonimmed_operand" "")
831 (match_operand:HI 1 "general_operand" ""))]
834 if (xtensa_emit_move_sequence (operands, HImode))
838 (define_insn "movhi_internal"
839 [(set (match_operand:HI 0 "nonimmed_operand" "=D,D,a,a,a,U,*a,*A")
840 (match_operand:HI 1 "move_operand" "M,d,r,I,U,r,*A,*r"))]
841 "xtensa_valid_move (HImode, operands)"
851 [(set_attr "type" "move,move,move,move,load,store,rsr,wsr")
852 (set_attr "mode" "HI")
853 (set_attr "length" "2,2,3,3,3,3,3,3")])
855 ;; 8-bit Integer moves
857 (define_expand "movqi"
858 [(set (match_operand:QI 0 "nonimmed_operand" "")
859 (match_operand:QI 1 "general_operand" ""))]
862 if (xtensa_emit_move_sequence (operands, QImode))
866 (define_insn "movqi_internal"
867 [(set (match_operand:QI 0 "nonimmed_operand" "=D,D,a,a,a,U,*a,*A")
868 (match_operand:QI 1 "move_operand" "M,d,r,I,U,r,*A,*r"))]
869 "xtensa_valid_move (QImode, operands)"
879 [(set_attr "type" "move,move,move,move,load,store,rsr,wsr")
880 (set_attr "mode" "QI")
881 (set_attr "length" "2,2,3,3,3,3,3,3")])
883 ;; 32-bit floating point moves
885 (define_expand "movsf"
886 [(set (match_operand:SF 0 "nonimmed_operand" "")
887 (match_operand:SF 1 "general_operand" ""))]
890 if (!TARGET_CONST16 && CONSTANT_P (operands[1]))
891 operands[1] = force_const_mem (SFmode, operands[1]);
893 if ((!register_operand (operands[0], SFmode)
894 && !register_operand (operands[1], SFmode))
895 || (FP_REG_P (xt_true_regnum (operands[0]))
896 && !(reload_in_progress | reload_completed)
897 && (constantpool_mem_p (operands[1])
898 || CONSTANT_P (operands[1]))))
899 operands[1] = force_reg (SFmode, operands[1]);
901 operands[1] = xtensa_copy_incoming_a7 (operands[1]);
904 (define_insn "movsf_internal"
905 [(set (match_operand:SF 0 "nonimmed_operand" "=f,f,U,D,D,R,a,f,a,W,a,a,U")
906 (match_operand:SF 1 "move_operand" "f,U,f,d,R,d,r,r,f,iF,T,U,r"))]
907 "((register_operand (operands[0], SFmode)
908 || register_operand (operands[1], SFmode))
909 && !(FP_REG_P (xt_true_regnum (operands[0]))
910 && (constantpool_mem_p (operands[1]) || CONSTANT_P (operands[1]))))"
921 const16\t%0, %t1\;const16\t%0, %b1
925 [(set_attr "type" "farith,fload,fstore,move,load,store,move,farith,farith,move,load,load,store")
926 (set_attr "mode" "SF")
927 (set_attr "length" "3,3,3,2,2,2,3,3,3,6,3,3,3")])
930 [(set (match_operand:SF 0 "register_operand" "=f")
931 (mem:SF (plus:SI (match_operand:SI 1 "register_operand" "+a")
932 (match_operand:SI 2 "fpmem_offset_operand" "i"))))
934 (plus:SI (match_dup 1) (match_dup 2)))]
937 if (TARGET_SERIALIZE_VOLATILE && volatile_refs_p (PATTERN (insn)))
938 output_asm_insn ("memw", operands);
939 return "lsiu\t%0, %1, %2";
941 [(set_attr "type" "fload")
942 (set_attr "mode" "SF")
943 (set_attr "length" "3")])
946 [(set (mem:SF (plus:SI (match_operand:SI 0 "register_operand" "+a")
947 (match_operand:SI 1 "fpmem_offset_operand" "i")))
948 (match_operand:SF 2 "register_operand" "f"))
950 (plus:SI (match_dup 0) (match_dup 1)))]
953 if (TARGET_SERIALIZE_VOLATILE && volatile_refs_p (PATTERN (insn)))
954 output_asm_insn ("memw", operands);
955 return "ssiu\t%2, %0, %1";
957 [(set_attr "type" "fstore")
958 (set_attr "mode" "SF")
959 (set_attr "length" "3")])
961 ;; 64-bit floating point moves
963 (define_expand "movdf"
964 [(set (match_operand:DF 0 "nonimmed_operand" "")
965 (match_operand:DF 1 "general_operand" ""))]
968 if (CONSTANT_P (operands[1]) && !TARGET_CONST16)
969 operands[1] = force_const_mem (DFmode, operands[1]);
971 if (!register_operand (operands[0], DFmode)
972 && !register_operand (operands[1], DFmode))
973 operands[1] = force_reg (DFmode, operands[1]);
975 operands[1] = xtensa_copy_incoming_a7 (operands[1]);
978 (define_insn_and_split "movdf_internal"
979 [(set (match_operand:DF 0 "nonimmed_operand" "=a,W,a,a,U")
980 (match_operand:DF 1 "move_operand" "r,iF,T,U,r"))]
981 "register_operand (operands[0], DFmode)
982 || register_operand (operands[1], DFmode)"
985 [(set (match_dup 0) (match_dup 2))
986 (set (match_dup 1) (match_dup 3))]
988 xtensa_split_operand_pair (operands, SFmode);
989 if (reg_overlap_mentioned_p (operands[0], operands[3]))
992 tmp = operands[0], operands[0] = operands[1], operands[1] = tmp;
993 tmp = operands[2], operands[2] = operands[3], operands[3] = tmp;
999 (define_expand "movmemsi"
1000 [(parallel [(set (match_operand:BLK 0 "" "")
1001 (match_operand:BLK 1 "" ""))
1002 (use (match_operand:SI 2 "arith_operand" ""))
1003 (use (match_operand:SI 3 "const_int_operand" ""))])]
1006 if (!xtensa_expand_block_move (operands))
1012 ;; Shift instructions.
1014 (define_expand "ashlsi3"
1015 [(set (match_operand:SI 0 "register_operand" "")
1016 (ashift:SI (match_operand:SI 1 "register_operand" "")
1017 (match_operand:SI 2 "arith_operand" "")))]
1020 operands[1] = xtensa_copy_incoming_a7 (operands[1]);
1023 (define_insn "ashlsi3_internal"
1024 [(set (match_operand:SI 0 "register_operand" "=a,a")
1025 (ashift:SI (match_operand:SI 1 "register_operand" "r,r")
1026 (match_operand:SI 2 "arith_operand" "J,r")))]
1030 ssl\t%2\;sll\t%0, %1"
1031 [(set_attr "type" "arith,arith")
1032 (set_attr "mode" "SI")
1033 (set_attr "length" "3,6")])
1035 (define_insn "ashrsi3"
1036 [(set (match_operand:SI 0 "register_operand" "=a,a")
1037 (ashiftrt:SI (match_operand:SI 1 "register_operand" "r,r")
1038 (match_operand:SI 2 "arith_operand" "J,r")))]
1042 ssr\t%2\;sra\t%0, %1"
1043 [(set_attr "type" "arith,arith")
1044 (set_attr "mode" "SI")
1045 (set_attr "length" "3,6")])
1047 (define_insn "lshrsi3"
1048 [(set (match_operand:SI 0 "register_operand" "=a,a")
1049 (lshiftrt:SI (match_operand:SI 1 "register_operand" "r,r")
1050 (match_operand:SI 2 "arith_operand" "J,r")))]
1053 if (which_alternative == 0)
1055 if ((INTVAL (operands[2]) & 0x1f) < 16)
1056 return "srli\t%0, %1, %R2";
1058 return "extui\t%0, %1, %R2, %L2";
1060 return "ssr\t%2\;srl\t%0, %1";
1062 [(set_attr "type" "arith,arith")
1063 (set_attr "mode" "SI")
1064 (set_attr "length" "3,6")])
1066 (define_insn "rotlsi3"
1067 [(set (match_operand:SI 0 "register_operand" "=a,a")
1068 (rotate:SI (match_operand:SI 1 "register_operand" "r,r")
1069 (match_operand:SI 2 "arith_operand" "J,r")))]
1072 ssai\t%L2\;src\t%0, %1, %1
1073 ssl\t%2\;src\t%0, %1, %1"
1074 [(set_attr "type" "multi,multi")
1075 (set_attr "mode" "SI")
1076 (set_attr "length" "6,6")])
1078 (define_insn "rotrsi3"
1079 [(set (match_operand:SI 0 "register_operand" "=a,a")
1080 (rotatert:SI (match_operand:SI 1 "register_operand" "r,r")
1081 (match_operand:SI 2 "arith_operand" "J,r")))]
1084 ssai\t%R2\;src\t%0, %1, %1
1085 ssr\t%2\;src\t%0, %1, %1"
1086 [(set_attr "type" "multi,multi")
1087 (set_attr "mode" "SI")
1088 (set_attr "length" "6,6")])
1093 ;; Handle comparisons by stashing away the operands and then using that
1094 ;; information in the subsequent conditional branch.
1096 (define_expand "cmpsi"
1098 (compare:CC (match_operand:SI 0 "register_operand" "")
1099 (match_operand:SI 1 "nonmemory_operand" "")))]
1102 branch_cmp[0] = operands[0];
1103 branch_cmp[1] = operands[1];
1104 branch_type = CMP_SI;
1108 (define_expand "cmpsf"
1110 (compare:CC (match_operand:SF 0 "register_operand" "")
1111 (match_operand:SF 1 "register_operand" "")))]
1114 branch_cmp[0] = operands[0];
1115 branch_cmp[1] = operands[1];
1116 branch_type = CMP_SF;
1121 ;; Conditional branches.
1123 (define_expand "b<code>"
1125 (if_then_else (any_cond (cc0) (const_int 0))
1126 (label_ref (match_operand 0 "" ""))
1130 xtensa_expand_conditional_branch (operands, <CODE>);
1134 ;; Branch patterns for standard integer comparisons
1136 (define_insn "*btrue"
1138 (if_then_else (match_operator 3 "branch_operator"
1139 [(match_operand:SI 0 "register_operand" "r,r")
1140 (match_operand:SI 1 "branch_operand" "K,r")])
1141 (label_ref (match_operand 2 "" ""))
1145 return xtensa_emit_branch (false, which_alternative == 0, operands);
1147 [(set_attr "type" "jump,jump")
1148 (set_attr "mode" "none")
1149 (set_attr "length" "3,3")])
1151 (define_insn "*bfalse"
1153 (if_then_else (match_operator 3 "branch_operator"
1154 [(match_operand:SI 0 "register_operand" "r,r")
1155 (match_operand:SI 1 "branch_operand" "K,r")])
1157 (label_ref (match_operand 2 "" ""))))]
1160 return xtensa_emit_branch (true, which_alternative == 0, operands);
1162 [(set_attr "type" "jump,jump")
1163 (set_attr "mode" "none")
1164 (set_attr "length" "3,3")])
1166 (define_insn "*ubtrue"
1168 (if_then_else (match_operator 3 "ubranch_operator"
1169 [(match_operand:SI 0 "register_operand" "r,r")
1170 (match_operand:SI 1 "ubranch_operand" "L,r")])
1171 (label_ref (match_operand 2 "" ""))
1175 return xtensa_emit_branch (false, which_alternative == 0, operands);
1177 [(set_attr "type" "jump,jump")
1178 (set_attr "mode" "none")
1179 (set_attr "length" "3,3")])
1181 (define_insn "*ubfalse"
1183 (if_then_else (match_operator 3 "ubranch_operator"
1184 [(match_operand:SI 0 "register_operand" "r,r")
1185 (match_operand:SI 1 "ubranch_operand" "L,r")])
1187 (label_ref (match_operand 2 "" ""))))]
1190 return xtensa_emit_branch (true, which_alternative == 0, operands);
1192 [(set_attr "type" "jump,jump")
1193 (set_attr "mode" "none")
1194 (set_attr "length" "3,3")])
1196 ;; Branch patterns for bit testing
1198 (define_insn "*bittrue"
1200 (if_then_else (match_operator 3 "boolean_operator"
1202 (match_operand:SI 0 "register_operand" "r,r")
1204 (match_operand:SI 1 "arith_operand" "J,r"))
1206 (label_ref (match_operand 2 "" ""))
1210 return xtensa_emit_bit_branch (false, which_alternative == 0, operands);
1212 [(set_attr "type" "jump")
1213 (set_attr "mode" "none")
1214 (set_attr "length" "3")])
1216 (define_insn "*bitfalse"
1218 (if_then_else (match_operator 3 "boolean_operator"
1220 (match_operand:SI 0 "register_operand" "r,r")
1222 (match_operand:SI 1 "arith_operand" "J,r"))
1225 (label_ref (match_operand 2 "" ""))))]
1228 return xtensa_emit_bit_branch (true, which_alternative == 0, operands);
1230 [(set_attr "type" "jump")
1231 (set_attr "mode" "none")
1232 (set_attr "length" "3")])
1234 (define_insn "*masktrue"
1236 (if_then_else (match_operator 3 "boolean_operator"
1237 [(and:SI (match_operand:SI 0 "register_operand" "r")
1238 (match_operand:SI 1 "register_operand" "r"))
1240 (label_ref (match_operand 2 "" ""))
1244 switch (GET_CODE (operands[3]))
1246 case EQ: return "bnone\t%0, %1, %2";
1247 case NE: return "bany\t%0, %1, %2";
1248 default: gcc_unreachable ();
1251 [(set_attr "type" "jump")
1252 (set_attr "mode" "none")
1253 (set_attr "length" "3")])
1255 (define_insn "*maskfalse"
1257 (if_then_else (match_operator 3 "boolean_operator"
1258 [(and:SI (match_operand:SI 0 "register_operand" "r")
1259 (match_operand:SI 1 "register_operand" "r"))
1262 (label_ref (match_operand 2 "" ""))))]
1265 switch (GET_CODE (operands[3]))
1267 case EQ: return "bany\t%0, %1, %2";
1268 case NE: return "bnone\t%0, %1, %2";
1269 default: gcc_unreachable ();
1272 [(set_attr "type" "jump")
1273 (set_attr "mode" "none")
1274 (set_attr "length" "3")])
1277 ;; Define the loop insns used by bct optimization to represent the
1278 ;; start and end of a zero-overhead loop (in loop.c). This start
1279 ;; template generates the loop insn; the end template doesn't generate
1280 ;; any instructions since loop end is handled in hardware.
1282 (define_insn "zero_cost_loop_start"
1284 (if_then_else (eq (match_operand:SI 0 "register_operand" "a")
1286 (label_ref (match_operand 1 "" ""))
1289 (plus:SI (match_dup 0) (const_int -1)))]
1292 [(set_attr "type" "jump")
1293 (set_attr "mode" "none")
1294 (set_attr "length" "3")])
1296 (define_insn "zero_cost_loop_end"
1298 (if_then_else (ne (reg:SI 19) (const_int 0))
1299 (label_ref (match_operand 0 "" ""))
1302 (plus:SI (reg:SI 19) (const_int -1)))]
1305 xtensa_emit_loop_end (insn, operands);
1308 [(set_attr "type" "jump")
1309 (set_attr "mode" "none")
1310 (set_attr "length" "0")])
1313 ;; Setting a register from a comparison.
1315 (define_expand "s<code>"
1316 [(set (match_operand:SI 0 "register_operand" "")
1317 (any_scc:SI (match_dup 1)
1321 operands[1] = gen_rtx_<CODE> (SImode, branch_cmp[0], branch_cmp[1]);
1322 if (!xtensa_expand_scc (operands))
1328 ;; Conditional moves.
1330 (define_expand "movsicc"
1331 [(set (match_operand:SI 0 "register_operand" "")
1332 (if_then_else:SI (match_operand 1 "comparison_operator" "")
1333 (match_operand:SI 2 "register_operand" "")
1334 (match_operand:SI 3 "register_operand" "")))]
1337 if (!xtensa_expand_conditional_move (operands, 0))
1342 (define_expand "movsfcc"
1343 [(set (match_operand:SF 0 "register_operand" "")
1344 (if_then_else:SF (match_operand 1 "comparison_operator" "")
1345 (match_operand:SF 2 "register_operand" "")
1346 (match_operand:SF 3 "register_operand" "")))]
1349 if (!xtensa_expand_conditional_move (operands, 1))
1354 (define_insn "movsicc_internal0"
1355 [(set (match_operand:SI 0 "register_operand" "=a,a")
1356 (if_then_else:SI (match_operator 4 "branch_operator"
1357 [(match_operand:SI 1 "register_operand" "r,r")
1359 (match_operand:SI 2 "register_operand" "r,0")
1360 (match_operand:SI 3 "register_operand" "0,r")))]
1363 return xtensa_emit_movcc (which_alternative == 1, false, false, operands);
1365 [(set_attr "type" "move,move")
1366 (set_attr "mode" "SI")
1367 (set_attr "length" "3,3")])
1369 (define_insn "movsicc_internal1"
1370 [(set (match_operand:SI 0 "register_operand" "=a,a")
1371 (if_then_else:SI (match_operator 4 "boolean_operator"
1372 [(match_operand:CC 1 "register_operand" "b,b")
1374 (match_operand:SI 2 "register_operand" "r,0")
1375 (match_operand:SI 3 "register_operand" "0,r")))]
1378 return xtensa_emit_movcc (which_alternative == 1, false, true, operands);
1380 [(set_attr "type" "move,move")
1381 (set_attr "mode" "SI")
1382 (set_attr "length" "3,3")])
1384 (define_insn "movsfcc_internal0"
1385 [(set (match_operand:SF 0 "register_operand" "=a,a,f,f")
1386 (if_then_else:SF (match_operator 4 "branch_operator"
1387 [(match_operand:SI 1 "register_operand" "r,r,r,r")
1389 (match_operand:SF 2 "register_operand" "r,0,f,0")
1390 (match_operand:SF 3 "register_operand" "0,r,0,f")))]
1393 return xtensa_emit_movcc ((which_alternative & 1) == 1,
1394 which_alternative >= 2, false, operands);
1396 [(set_attr "type" "move,move,move,move")
1397 (set_attr "mode" "SF")
1398 (set_attr "length" "3,3,3,3")])
1400 (define_insn "movsfcc_internal1"
1401 [(set (match_operand:SF 0 "register_operand" "=a,a,f,f")
1402 (if_then_else:SF (match_operator 4 "boolean_operator"
1403 [(match_operand:CC 1 "register_operand" "b,b,b,b")
1405 (match_operand:SF 2 "register_operand" "r,0,f,0")
1406 (match_operand:SF 3 "register_operand" "0,r,0,f")))]
1409 return xtensa_emit_movcc ((which_alternative & 1) == 1,
1410 which_alternative >= 2, true, operands);
1412 [(set_attr "type" "move,move,move,move")
1413 (set_attr "mode" "SF")
1414 (set_attr "length" "3,3,3,3")])
1417 ;; Floating-point comparisons.
1419 (define_insn "s<code>_sf"
1420 [(set (match_operand:CC 0 "register_operand" "=b")
1421 (any_scc_sf:CC (match_operand:SF 1 "register_operand" "f")
1422 (match_operand:SF 2 "register_operand" "f")))]
1424 "<scc_sf>.s\t%0, %1, %2"
1425 [(set_attr "type" "farith")
1426 (set_attr "mode" "BL")
1427 (set_attr "length" "3")])
1430 ;; Unconditional branches.
1434 (label_ref (match_operand 0 "" "")))]
1437 [(set_attr "type" "jump")
1438 (set_attr "mode" "none")
1439 (set_attr "length" "3")])
1441 (define_expand "indirect_jump"
1443 (match_operand 0 "register_operand" ""))]
1446 rtx dest = operands[0];
1447 if (GET_CODE (dest) != REG || GET_MODE (dest) != Pmode)
1448 operands[0] = copy_to_mode_reg (Pmode, dest);
1450 emit_jump_insn (gen_indirect_jump_internal (dest));
1454 (define_insn "indirect_jump_internal"
1455 [(set (pc) (match_operand:SI 0 "register_operand" "r"))]
1458 [(set_attr "type" "jump")
1459 (set_attr "mode" "none")
1460 (set_attr "length" "3")])
1463 (define_expand "tablejump"
1464 [(use (match_operand:SI 0 "register_operand" ""))
1465 (use (label_ref (match_operand 1 "" "")))]
1468 rtx target = operands[0];
1471 /* For PIC, the table entry is relative to the start of the table. */
1472 rtx label = gen_reg_rtx (SImode);
1473 target = gen_reg_rtx (SImode);
1474 emit_move_insn (label, gen_rtx_LABEL_REF (SImode, operands[1]));
1475 emit_insn (gen_addsi3 (target, operands[0], label));
1477 emit_jump_insn (gen_tablejump_internal (target, operands[1]));
1481 (define_insn "tablejump_internal"
1483 (match_operand:SI 0 "register_operand" "r"))
1484 (use (label_ref (match_operand 1 "" "")))]
1487 [(set_attr "type" "jump")
1488 (set_attr "mode" "none")
1489 (set_attr "length" "3")])
1494 (define_expand "sym_PLT"
1495 [(const (unspec [(match_operand:SI 0 "" "")] UNSPEC_PLT))]
1499 (define_expand "call"
1500 [(call (match_operand 0 "memory_operand" "")
1501 (match_operand 1 "" ""))]
1504 rtx addr = XEXP (operands[0], 0);
1505 if (flag_pic && GET_CODE (addr) == SYMBOL_REF
1506 && (!SYMBOL_REF_LOCAL_P (addr) || SYMBOL_REF_EXTERNAL_P (addr)))
1507 addr = gen_sym_PLT (addr);
1508 if (!call_insn_operand (addr, VOIDmode))
1509 XEXP (operands[0], 0) = copy_to_mode_reg (Pmode, addr);
1512 (define_insn "call_internal"
1513 [(call (mem (match_operand:SI 0 "call_insn_operand" "nir"))
1514 (match_operand 1 "" "i"))]
1517 return xtensa_emit_call (0, operands);
1519 [(set_attr "type" "call")
1520 (set_attr "mode" "none")
1521 (set_attr "length" "3")])
1523 (define_expand "call_value"
1524 [(set (match_operand 0 "register_operand" "")
1525 (call (match_operand 1 "memory_operand" "")
1526 (match_operand 2 "" "")))]
1529 rtx addr = XEXP (operands[1], 0);
1530 if (flag_pic && GET_CODE (addr) == SYMBOL_REF
1531 && (!SYMBOL_REF_LOCAL_P (addr) || SYMBOL_REF_EXTERNAL_P (addr)))
1532 addr = gen_sym_PLT (addr);
1533 if (!call_insn_operand (addr, VOIDmode))
1534 XEXP (operands[1], 0) = copy_to_mode_reg (Pmode, addr);
1537 (define_insn "call_value_internal"
1538 [(set (match_operand 0 "register_operand" "=a")
1539 (call (mem (match_operand:SI 1 "call_insn_operand" "nir"))
1540 (match_operand 2 "" "i")))]
1543 return xtensa_emit_call (1, operands);
1545 [(set_attr "type" "call")
1546 (set_attr "mode" "none")
1547 (set_attr "length" "3")])
1549 (define_insn "entry"
1550 [(set (reg:SI A1_REG)
1551 (unspec_volatile:SI [(match_operand:SI 0 "const_int_operand" "i")]
1555 [(set_attr "type" "entry")
1556 (set_attr "mode" "SI")
1557 (set_attr "length" "3")])
1559 (define_insn "return"
1561 (use (reg:SI A0_REG))]
1564 return (TARGET_DENSITY ? "retw.n" : "retw");
1566 [(set_attr "type" "jump")
1567 (set_attr "mode" "none")
1568 (set_attr "length" "2")])
1571 ;; Miscellaneous instructions.
1573 (define_expand "prologue"
1577 xtensa_expand_prologue ();
1581 (define_expand "epilogue"
1585 emit_jump_insn (gen_return ());
1593 return (TARGET_DENSITY ? "nop.n" : "nop");
1595 [(set_attr "type" "nop")
1596 (set_attr "mode" "none")
1597 (set_attr "length" "3")])
1599 (define_expand "nonlocal_goto"
1600 [(match_operand:SI 0 "general_operand" "")
1601 (match_operand:SI 1 "general_operand" "")
1602 (match_operand:SI 2 "general_operand" "")
1603 (match_operand:SI 3 "" "")]
1606 xtensa_expand_nonlocal_goto (operands);
1610 ;; Stuff an address into the return address register along with the window
1611 ;; size in the high bits. Because we don't have the window size of the
1612 ;; previous frame, assume the function called out with a CALL8 since that
1613 ;; is what compilers always use. Note: __builtin_frob_return_addr has
1614 ;; already been applied to the handler, but the generic version doesn't
1615 ;; allow us to frob it quite enough, so we just frob here.
1617 (define_insn_and_split "eh_return"
1618 [(set (reg:SI A0_REG)
1619 (unspec_volatile:SI [(match_operand:SI 0 "register_operand" "r")]
1621 (clobber (match_scratch:SI 1 "=r"))]
1625 [(set (match_dup 1) (ashift:SI (match_dup 0) (const_int 2)))
1626 (set (match_dup 1) (plus:SI (match_dup 1) (const_int 2)))
1627 (set (reg:SI A0_REG) (rotatert:SI (match_dup 1) (const_int 2)))]
1630 ;; Setting up a frame pointer is tricky for Xtensa because GCC doesn't
1631 ;; know if a frame pointer is required until the reload pass, and
1632 ;; because there may be an incoming argument value in the hard frame
1633 ;; pointer register (a7). If there is an incoming argument in that
1634 ;; register, the "set_frame_ptr" insn gets inserted immediately after
1635 ;; the insn that copies the incoming argument to a pseudo or to the
1636 ;; stack. This serves several purposes here: (1) it keeps the
1637 ;; optimizer from copy-propagating or scheduling the use of a7 as an
1638 ;; incoming argument away from the beginning of the function; (2) we
1639 ;; can use a post-reload splitter to expand away the insn if a frame
1640 ;; pointer is not required, so that the post-reload scheduler can do
1641 ;; the right thing; and (3) it makes it easy for the prologue expander
1642 ;; to search for this insn to determine whether it should add a new insn
1643 ;; to set up the frame pointer.
1645 (define_insn "set_frame_ptr"
1646 [(set (reg:SI A7_REG) (unspec_volatile:SI [(const_int 0)] UNSPECV_SET_FP))]
1649 if (frame_pointer_needed)
1650 return "mov\ta7, sp";
1653 [(set_attr "type" "move")
1654 (set_attr "mode" "SI")
1655 (set_attr "length" "3")])
1657 ;; Post-reload splitter to remove fp assignment when it's not needed.
1659 [(set (reg:SI A7_REG) (unspec_volatile:SI [(const_int 0)] UNSPECV_SET_FP))]
1660 "reload_completed && !frame_pointer_needed"
1661 [(unspec [(const_int 0)] UNSPEC_NOP)]
1664 ;; The preceding splitter needs something to split the insn into;
1665 ;; things start breaking if the result is just a "use" so instead we
1666 ;; generate the following insn.
1667 (define_insn "*unspec_nop"
1668 [(unspec [(const_int 0)] UNSPEC_NOP)]
1671 [(set_attr "type" "nop")
1672 (set_attr "mode" "none")
1673 (set_attr "length" "0")])
1676 ;; Instructions for the Xtensa "boolean" option.
1678 (define_insn "*booltrue"
1680 (if_then_else (match_operator 2 "boolean_operator"
1681 [(match_operand:CC 0 "register_operand" "b")
1683 (label_ref (match_operand 1 "" ""))
1687 if (GET_CODE (operands[2]) == EQ)
1688 return "bf\t%0, %1";
1690 return "bt\t%0, %1";
1692 [(set_attr "type" "jump")
1693 (set_attr "mode" "none")
1694 (set_attr "length" "3")])
1696 (define_insn "*boolfalse"
1698 (if_then_else (match_operator 2 "boolean_operator"
1699 [(match_operand:CC 0 "register_operand" "b")
1702 (label_ref (match_operand 1 "" ""))))]
1705 if (GET_CODE (operands[2]) == EQ)
1706 return "bt\t%0, %1";
1708 return "bf\t%0, %1";
1710 [(set_attr "type" "jump")
1711 (set_attr "mode" "none")
1712 (set_attr "length" "3")])
1715 ;; Atomic operations
1717 (define_expand "memory_barrier"
1718 [(set (mem:BLK (match_dup 0))
1719 (unspec_volatile:BLK [(mem:BLK (match_dup 0))] UNSPECV_MEMW))]
1722 operands[0] = gen_rtx_MEM (BLKmode, gen_rtx_SCRATCH (SImode));
1723 MEM_VOLATILE_P (operands[0]) = 1;
1726 (define_insn "*memory_barrier"
1727 [(set (match_operand:BLK 0 "" "")
1728 (unspec_volatile:BLK [(match_operand:BLK 1 "" "")] UNSPECV_MEMW))]
1731 [(set_attr "type" "unknown")
1732 (set_attr "mode" "none")
1733 (set_attr "length" "3")])
1735 ;; sync_lock_release is only implemented for SImode.
1736 ;; For other modes, just use the default of a store with a memory_barrier.
1737 (define_insn "sync_lock_releasesi"
1738 [(set (match_operand:SI 0 "mem_operand" "=U")
1740 [(match_operand:SI 1 "register_operand" "r")]
1742 "TARGET_RELEASE_SYNC"
1744 [(set_attr "type" "store")
1745 (set_attr "mode" "SI")
1746 (set_attr "length" "3")])
1748 (define_insn "sync_compare_and_swapsi"
1750 [(set (match_operand:SI 0 "register_operand" "=a")
1751 (match_operand:SI 1 "mem_operand" "+U"))
1755 (match_operand:SI 2 "register_operand" "r")
1756 (match_operand:SI 3 "register_operand" "0")]
1759 "wsr\t%2, SCOMPARE1\;s32c1i\t%3, %1"
1760 [(set_attr "type" "multi")
1761 (set_attr "mode" "SI")
1762 (set_attr "length" "6")])
1764 (define_expand "sync_compare_and_swap<mode>"
1766 [(set (match_operand:HQI 0 "register_operand" "")
1767 (match_operand:HQI 1 "mem_operand" ""))
1769 (unspec_volatile:HQI
1771 (match_operand:HQI 2 "register_operand" "")
1772 (match_operand:HQI 3 "register_operand" "")]
1776 xtensa_expand_compare_and_swap (operands[0], operands[1],
1777 operands[2], operands[3]);
1781 (define_expand "sync_lock_test_and_set<mode>"
1782 [(match_operand:HQI 0 "register_operand")
1783 (match_operand:HQI 1 "memory_operand")
1784 (match_operand:HQI 2 "register_operand")]
1787 xtensa_expand_atomic (SET, operands[0], operands[1], operands[2], false);
1791 (define_expand "sync_<atomic><mode>"
1792 [(set (match_operand:HQI 0 "memory_operand")
1793 (ATOMIC:HQI (match_dup 0)
1794 (match_operand:HQI 1 "register_operand")))]
1797 xtensa_expand_atomic (<CODE>, NULL_RTX, operands[0], operands[1], false);
1801 (define_expand "sync_old_<atomic><mode>"
1802 [(set (match_operand:HQI 0 "register_operand")
1803 (match_operand:HQI 1 "memory_operand"))
1805 (ATOMIC:HQI (match_dup 1)
1806 (match_operand:HQI 2 "register_operand")))]
1809 xtensa_expand_atomic (<CODE>, operands[0], operands[1], operands[2], false);
1813 (define_expand "sync_new_<atomic><mode>"
1814 [(set (match_operand:HQI 0 "register_operand")
1815 (ATOMIC:HQI (match_operand:HQI 1 "memory_operand")
1816 (match_operand:HQI 2 "register_operand")))
1817 (set (match_dup 1) (ATOMIC:HQI (match_dup 1) (match_dup 2)))]
1820 xtensa_expand_atomic (<CODE>, operands[0], operands[1], operands[2], true);