1 ;; GCC machine description for Tensilica's Xtensa architecture.
2 ;; Copyright (C) 2001 Free Software Foundation, Inc.
3 ;; Contributed by Bob Wilson (bwilson@tensilica.com) at Tensilica.
5 ;; This file is part of GCC.
7 ;; GCC is free software; you can redistribute it and/or modify it
8 ;; under the terms of the GNU General Public License as published by
9 ;; the Free Software Foundation; either version 2, or (at your option)
12 ;; GCC is distributed in the hope that it will be useful, but WITHOUT
13 ;; ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
14 ;; or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public
15 ;; License for more details.
17 ;; You should have received a copy of the GNU General Public License
18 ;; along with GCC; see the file COPYING. If not, write to the Free
19 ;; Software Foundation, 59 Temple Place - Suite 330, Boston, MA
23 ;; ....................
27 ;; ....................
41 ;; ....................
45 ;; ....................
49 "unknown,jump,call,load,store,move,arith,multi,nop,farith,fmadd,fdiv,fsqrt,fconv,fload,fstore,mul16,mul32,div32,mac16,rsr,wsr"
50 (const_string "unknown"))
53 "unknown,none,QI,HI,SI,DI,SF,DF,BL"
54 (const_string "unknown"))
56 (define_attr "length" "" (const_int 1))
58 ;; Describe a user's asm statement.
59 (define_asm_attributes
60 [(set_attr "type" "multi")])
64 ;; ....................
68 ;; ....................
71 (define_function_unit "memory" 1 0 (eq_attr "type" "load,fload") 2 0)
73 (define_function_unit "sreg" 1 1 (eq_attr "type" "rsr") 2 0)
75 (define_function_unit "mul16" 1 0 (eq_attr "type" "mul16") 2 0)
77 (define_function_unit "mul32" 1 0 (eq_attr "type" "mul32") 2 0)
79 (define_function_unit "fpmadd" 1 0 (eq_attr "type" "fmadd") 4 0)
81 (define_function_unit "fpconv" 1 0 (eq_attr "type" "fconv") 2 0)
85 ;; ....................
89 ;; ....................
92 (define_expand "adddi3"
93 [(set (match_operand:DI 0 "register_operand" "")
94 (plus:DI (match_operand:DI 1 "register_operand" "")
95 (match_operand:DI 2 "register_operand" "")))]
99 rtx dstlo = gen_lowpart (SImode, operands[0]);
100 rtx src1lo = gen_lowpart (SImode, operands[1]);
101 rtx src2lo = gen_lowpart (SImode, operands[2]);
103 rtx dsthi = gen_highpart (SImode, operands[0]);
104 rtx src1hi = gen_highpart (SImode, operands[1]);
105 rtx src2hi = gen_highpart (SImode, operands[2]);
107 emit_insn (gen_addsi3 (dstlo, src1lo, src2lo));
108 emit_insn (gen_addsi3 (dsthi, src1hi, src2hi));
109 emit_insn (gen_adddi_carry (dsthi, dstlo, src2lo));
113 ;; Represent the add-carry operation as an atomic operation instead of
114 ;; expanding it to a conditional branch. Otherwise, the edge
115 ;; profiling code breaks because inserting the count increment code
116 ;; causes a new jump insn to be added.
118 (define_insn "adddi_carry"
119 [(set (match_operand:SI 0 "register_operand" "+a")
120 (plus:SI (ltu:SI (match_operand:SI 1 "register_operand" "r")
121 (match_operand:SI 2 "register_operand" "r"))
124 "bgeu\\t%1, %2, 0f\;addi\\t%0, %0, 1\;0:"
125 [(set_attr "type" "multi")
126 (set_attr "mode" "SI")
127 (set_attr "length" "6")])
129 (define_insn "addsi3"
130 [(set (match_operand:SI 0 "register_operand" "=D,D,a,a,a")
131 (plus:SI (match_operand:SI 1 "register_operand" "%d,d,r,r,r")
132 (match_operand:SI 2 "add_operand" "d,O,r,J,N")))]
140 [(set_attr "type" "arith,arith,arith,arith,arith")
141 (set_attr "mode" "SI")
142 (set_attr "length" "2,2,3,3,3")])
145 [(set (match_operand:SI 0 "register_operand" "=a")
146 (plus:SI (mult:SI (match_operand:SI 1 "register_operand" "r")
148 (match_operand:SI 2 "register_operand" "r")))]
151 [(set_attr "type" "arith")
152 (set_attr "mode" "SI")
153 (set_attr "length" "3")])
156 [(set (match_operand:SI 0 "register_operand" "=a")
157 (plus:SI (mult:SI (match_operand:SI 1 "register_operand" "r")
159 (match_operand:SI 2 "register_operand" "r")))]
162 [(set_attr "type" "arith")
163 (set_attr "mode" "SI")
164 (set_attr "length" "3")])
167 [(set (match_operand:SI 0 "register_operand" "=a")
168 (plus:SI (mult:SI (match_operand:SI 1 "register_operand" "r")
170 (match_operand:SI 2 "register_operand" "r")))]
173 [(set_attr "type" "arith")
174 (set_attr "mode" "SI")
175 (set_attr "length" "3")])
177 (define_insn "addsf3"
178 [(set (match_operand:SF 0 "register_operand" "=f")
179 (plus:SF (match_operand:SF 1 "register_operand" "%f")
180 (match_operand:SF 2 "register_operand" "f")))]
183 [(set_attr "type" "fmadd")
184 (set_attr "mode" "SF")
185 (set_attr "length" "3")])
189 ;; ....................
193 ;; ....................
196 (define_expand "subdi3"
197 [(set (match_operand:DI 0 "register_operand" "")
198 (minus:DI (match_operand:DI 1 "register_operand" "")
199 (match_operand:DI 2 "register_operand" "")))]
203 rtx dstlo = gen_lowpart (SImode, operands[0]);
204 rtx src1lo = gen_lowpart (SImode, operands[1]);
205 rtx src2lo = gen_lowpart (SImode, operands[2]);
207 rtx dsthi = gen_highpart (SImode, operands[0]);
208 rtx src1hi = gen_highpart (SImode, operands[1]);
209 rtx src2hi = gen_highpart (SImode, operands[2]);
211 emit_insn (gen_subsi3 (dstlo, src1lo, src2lo));
212 emit_insn (gen_subsi3 (dsthi, src1hi, src2hi));
213 emit_insn (gen_subdi_carry (dsthi, src1lo, src2lo));
217 (define_insn "subdi_carry"
218 [(set (match_operand:SI 0 "register_operand" "+a")
219 (minus:SI (match_dup 0)
220 (ltu:SI (match_operand:SI 1 "register_operand" "r")
221 (match_operand:SI 2 "register_operand" "r"))))]
223 "bgeu\\t%1, %2, 0f\;addi\\t%0, %0, -1\;0:"
224 [(set_attr "type" "multi")
225 (set_attr "mode" "SI")
226 (set_attr "length" "6")])
228 (define_insn "subsi3"
229 [(set (match_operand:SI 0 "register_operand" "=a")
230 (minus:SI (match_operand:SI 1 "register_operand" "r")
231 (match_operand:SI 2 "register_operand" "r")))]
234 [(set_attr "type" "arith")
235 (set_attr "mode" "SI")
236 (set_attr "length" "3")])
239 [(set (match_operand:SI 0 "register_operand" "=a")
240 (minus:SI (mult:SI (match_operand:SI 1 "register_operand" "r")
242 (match_operand:SI 2 "register_operand" "r")))]
245 [(set_attr "type" "arith")
246 (set_attr "mode" "SI")
247 (set_attr "length" "3")])
250 [(set (match_operand:SI 0 "register_operand" "=a")
251 (minus:SI (mult:SI (match_operand:SI 1 "register_operand" "r")
253 (match_operand:SI 2 "register_operand" "r")))]
256 [(set_attr "type" "arith")
257 (set_attr "mode" "SI")
258 (set_attr "length" "3")])
261 [(set (match_operand:SI 0 "register_operand" "=a")
262 (minus:SI (mult:SI (match_operand:SI 1 "register_operand" "r")
264 (match_operand:SI 2 "register_operand" "r")))]
267 [(set_attr "type" "arith")
268 (set_attr "mode" "SI")
269 (set_attr "length" "3")])
271 (define_insn "subsf3"
272 [(set (match_operand:SF 0 "register_operand" "=f")
273 (minus:SF (match_operand:SF 1 "register_operand" "f")
274 (match_operand:SF 2 "register_operand" "f")))]
277 [(set_attr "type" "fmadd")
278 (set_attr "mode" "SF")
279 (set_attr "length" "3")])
283 ;; ....................
287 ;; ....................
290 (define_insn "mulsi3"
291 [(set (match_operand:SI 0 "register_operand" "=a")
292 (mult:SI (match_operand:SI 1 "register_operand" "%r")
293 (match_operand:SI 2 "register_operand" "r")))]
296 [(set_attr "type" "mul32")
297 (set_attr "mode" "SI")
298 (set_attr "length" "3")])
300 (define_insn "mulhisi3"
301 [(set (match_operand:SI 0 "register_operand" "=C,A")
302 (mult:SI (sign_extend:SI
303 (match_operand:HI 1 "register_operand" "%r,r"))
305 (match_operand:HI 2 "register_operand" "r,r"))))]
306 "TARGET_MUL16 || TARGET_MAC16"
310 [(set_attr "type" "mul16,mac16")
311 (set_attr "mode" "SI")
312 (set_attr "length" "3,3")])
314 (define_insn "umulhisi3"
315 [(set (match_operand:SI 0 "register_operand" "=C,A")
316 (mult:SI (zero_extend:SI
317 (match_operand:HI 1 "register_operand" "%r,r"))
319 (match_operand:HI 2 "register_operand" "r,r"))))]
320 "TARGET_MUL16 || TARGET_MAC16"
324 [(set_attr "type" "mul16,mac16")
325 (set_attr "mode" "SI")
326 (set_attr "length" "3,3")])
328 (define_insn "muladdhisi"
329 [(set (match_operand:SI 0 "register_operand" "=A")
330 (plus:SI (mult:SI (sign_extend:SI
331 (match_operand:HI 1 "register_operand" "%r"))
333 (match_operand:HI 2 "register_operand" "r")))
334 (match_operand:SI 3 "register_operand" "0")))]
336 "mula.aa.ll\\t%1, %2"
337 [(set_attr "type" "mac16")
338 (set_attr "mode" "SI")
339 (set_attr "length" "3")])
341 (define_insn "mulsubhisi"
342 [(set (match_operand:SI 0 "register_operand" "=A")
343 (minus:SI (match_operand:SI 1 "register_operand" "0")
344 (mult:SI (sign_extend:SI
345 (match_operand:HI 2 "register_operand" "%r"))
347 (match_operand:HI 3 "register_operand" "r")))))]
349 "muls.aa.ll\\t%2, %3"
350 [(set_attr "type" "mac16")
351 (set_attr "mode" "SI")
352 (set_attr "length" "3")])
354 (define_insn "mulsf3"
355 [(set (match_operand:SF 0 "register_operand" "=f")
356 (mult:SF (match_operand:SF 1 "register_operand" "%f")
357 (match_operand:SF 2 "register_operand" "f")))]
360 [(set_attr "type" "fmadd")
361 (set_attr "mode" "SF")
362 (set_attr "length" "3")])
364 (define_insn "muladdsf3"
365 [(set (match_operand:SF 0 "register_operand" "=f")
366 (plus:SF (mult:SF (match_operand:SF 1 "register_operand" "%f")
367 (match_operand:SF 2 "register_operand" "f"))
368 (match_operand:SF 3 "register_operand" "0")))]
369 "TARGET_HARD_FLOAT && !TARGET_NO_FUSED_MADD"
370 "madd.s\\t%0, %1, %2"
371 [(set_attr "type" "fmadd")
372 (set_attr "mode" "SF")
373 (set_attr "length" "3")])
375 (define_insn "mulsubsf3"
376 [(set (match_operand:SF 0 "register_operand" "=f")
377 (minus:SF (match_operand:SF 1 "register_operand" "0")
378 (mult:SF (match_operand:SF 2 "register_operand" "%f")
379 (match_operand:SF 3 "register_operand" "f"))))]
380 "TARGET_HARD_FLOAT && !TARGET_NO_FUSED_MADD"
381 "msub.s\\t%0, %2, %3"
382 [(set_attr "type" "fmadd")
383 (set_attr "mode" "SF")
384 (set_attr "length" "3")])
388 ;; ....................
392 ;; ....................
395 (define_insn "divsi3"
396 [(set (match_operand:SI 0 "register_operand" "=a")
397 (div:SI (match_operand:SI 1 "register_operand" "r")
398 (match_operand:SI 2 "register_operand" "r")))]
401 [(set_attr "type" "div32")
402 (set_attr "mode" "SI")
403 (set_attr "length" "3")])
405 (define_insn "udivsi3"
406 [(set (match_operand:SI 0 "register_operand" "=a")
407 (udiv:SI (match_operand:SI 1 "register_operand" "r")
408 (match_operand:SI 2 "register_operand" "r")))]
411 [(set_attr "type" "div32")
412 (set_attr "mode" "SI")
413 (set_attr "length" "3")])
415 (define_insn "divsf3"
416 [(set (match_operand:SF 0 "register_operand" "=f")
417 (div:SF (match_operand:SF 1 "register_operand" "f")
418 (match_operand:SF 2 "register_operand" "f")))]
419 "TARGET_HARD_FLOAT_DIV"
421 [(set_attr "type" "fdiv")
422 (set_attr "mode" "SF")
423 (set_attr "length" "3")])
426 [(set (match_operand:SF 0 "register_operand" "=f")
427 (div:SF (match_operand:SF 1 "const_float_1_operand" "")
428 (match_operand:SF 2 "register_operand" "f")))]
429 "TARGET_HARD_FLOAT_RECIP && flag_unsafe_math_optimizations"
431 [(set_attr "type" "fdiv")
432 (set_attr "mode" "SF")
433 (set_attr "length" "3")])
437 ;; ....................
441 ;; ....................
444 (define_insn "modsi3"
445 [(set (match_operand:SI 0 "register_operand" "=a")
446 (mod:SI (match_operand:SI 1 "register_operand" "r")
447 (match_operand:SI 2 "register_operand" "r")))]
450 [(set_attr "type" "div32")
451 (set_attr "mode" "SI")
452 (set_attr "length" "3")])
454 (define_insn "umodsi3"
455 [(set (match_operand:SI 0 "register_operand" "=a")
456 (umod:SI (match_operand:SI 1 "register_operand" "r")
457 (match_operand:SI 2 "register_operand" "r")))]
460 [(set_attr "type" "div32")
461 (set_attr "mode" "SI")
462 (set_attr "length" "3")])
466 ;; ....................
470 ;; ....................
473 (define_insn "sqrtsf2"
474 [(set (match_operand:SF 0 "register_operand" "=f")
475 (sqrt:SF (match_operand:SF 1 "register_operand" "f")))]
476 "TARGET_HARD_FLOAT_SQRT"
478 [(set_attr "type" "fsqrt")
479 (set_attr "mode" "SF")
480 (set_attr "length" "3")])
483 [(set (match_operand:SF 0 "register_operand" "=f")
484 (div:SF (match_operand:SF 1 "const_float_1_operand" "")
485 (sqrt:SF (match_operand:SF 2 "register_operand" "f"))))]
486 "TARGET_HARD_FLOAT_RSQRT && flag_unsafe_math_optimizations"
488 [(set_attr "type" "fsqrt")
489 (set_attr "mode" "SF")
490 (set_attr "length" "3")])
494 ;; ....................
498 ;; ....................
501 (define_insn "abssi2"
502 [(set (match_operand:SI 0 "register_operand" "=a")
503 (abs:SI (match_operand:SI 1 "register_operand" "r")))]
506 [(set_attr "type" "arith")
507 (set_attr "mode" "SI")
508 (set_attr "length" "3")])
510 (define_insn "abssf2"
511 [(set (match_operand:SF 0 "register_operand" "=f")
512 (abs:SF (match_operand:SF 1 "register_operand" "f")))]
515 [(set_attr "type" "farith")
516 (set_attr "mode" "SF")
517 (set_attr "length" "3")])
521 ;; ....................
523 ;; MIN AND MAX INSTRUCTIONS
525 ;; ....................
528 (define_insn "sminsi3"
529 [(set (match_operand:SI 0 "register_operand" "=a")
530 (smin:SI (match_operand:SI 1 "register_operand" "%r")
531 (match_operand:SI 2 "register_operand" "r")))]
534 [(set_attr "type" "arith")
535 (set_attr "mode" "SI")
536 (set_attr "length" "3")])
538 (define_insn "uminsi3"
539 [(set (match_operand:SI 0 "register_operand" "=a")
540 (umin:SI (match_operand:SI 1 "register_operand" "%r")
541 (match_operand:SI 2 "register_operand" "r")))]
544 [(set_attr "type" "arith")
545 (set_attr "mode" "SI")
546 (set_attr "length" "3")])
548 (define_insn "smaxsi3"
549 [(set (match_operand:SI 0 "register_operand" "=a")
550 (smax:SI (match_operand:SI 1 "register_operand" "%r")
551 (match_operand:SI 2 "register_operand" "r")))]
554 [(set_attr "type" "arith")
555 (set_attr "mode" "SI")
556 (set_attr "length" "3")])
558 (define_insn "umaxsi3"
559 [(set (match_operand:SI 0 "register_operand" "=a")
560 (umax:SI (match_operand:SI 1 "register_operand" "%r")
561 (match_operand:SI 2 "register_operand" "r")))]
564 [(set_attr "type" "arith")
565 (set_attr "mode" "SI")
566 (set_attr "length" "3")])
570 ;; ....................
572 ;; FIND FIRST BIT INSTRUCTION
574 ;; ....................
577 (define_expand "ffssi2"
578 [(set (match_operand:SI 0 "register_operand" "")
579 (ffs:SI (match_operand:SI 1 "register_operand" "")))]
583 rtx temp = gen_reg_rtx (SImode);
584 emit_insn (gen_negsi2 (temp, operands[1]));
585 emit_insn (gen_andsi3 (temp, temp, operands[1]));
586 emit_insn (gen_nsau (temp, temp));
587 emit_insn (gen_negsi2 (temp, temp));
588 emit_insn (gen_addsi3 (operands[0], temp, GEN_INT (32)));
592 ;; there is no RTL operator corresponding to NSAU
594 [(set (match_operand:SI 0 "register_operand" "=a")
595 (unspec:SI [(match_operand:SI 1 "register_operand" "r")] UNSPEC_NSAU))]
598 [(set_attr "type" "arith")
599 (set_attr "mode" "SI")
600 (set_attr "length" "3")])
604 ;; ....................
606 ;; NEGATION and ONE'S COMPLEMENT
608 ;; ....................
611 (define_insn "negsi2"
612 [(set (match_operand:SI 0 "register_operand" "=a")
613 (neg:SI (match_operand:SI 1 "register_operand" "r")))]
616 [(set_attr "type" "arith")
617 (set_attr "mode" "SI")
618 (set_attr "length" "3")])
620 (define_expand "one_cmplsi2"
621 [(set (match_operand:SI 0 "register_operand" "")
622 (not:SI (match_operand:SI 1 "register_operand" "")))]
626 rtx temp = gen_reg_rtx (SImode);
627 emit_insn (gen_movsi (temp, constm1_rtx));
628 emit_insn (gen_xorsi3 (operands[0], temp, operands[1]));
632 (define_insn "negsf2"
633 [(set (match_operand:SF 0 "register_operand" "=f")
634 (neg:SF (match_operand:SF 1 "register_operand" "f")))]
637 [(set_attr "type" "farith")
638 (set_attr "mode" "SF")
639 (set_attr "length" "3")])
643 ;; ....................
647 ;; ....................
650 (define_insn "andsi3"
651 [(set (match_operand:SI 0 "register_operand" "=a,a")
652 (and:SI (match_operand:SI 1 "register_operand" "%r,r")
653 (match_operand:SI 2 "mask_operand" "P,r")))]
656 extui\\t%0, %1, 0, %K2
658 [(set_attr "type" "arith,arith")
659 (set_attr "mode" "SI")
660 (set_attr "length" "3,3")])
662 (define_insn "iorsi3"
663 [(set (match_operand:SI 0 "register_operand" "=a")
664 (ior:SI (match_operand:SI 1 "register_operand" "%r")
665 (match_operand:SI 2 "register_operand" "r")))]
668 [(set_attr "type" "arith")
669 (set_attr "mode" "SI")
670 (set_attr "length" "3")])
672 (define_insn "xorsi3"
673 [(set (match_operand:SI 0 "register_operand" "=a")
674 (xor:SI (match_operand:SI 1 "register_operand" "%r")
675 (match_operand:SI 2 "register_operand" "r")))]
678 [(set_attr "type" "arith")
679 (set_attr "mode" "SI")
680 (set_attr "length" "3")])
684 ;; ....................
688 ;; ....................
691 (define_insn "zero_extendhisi2"
692 [(set (match_operand:SI 0 "register_operand" "=a,a")
693 (zero_extend:SI (match_operand:HI 1 "nonimmed_operand" "r,U")))]
696 extui\\t%0, %1, 0, 16
698 [(set_attr "type" "arith,load")
699 (set_attr "mode" "SI")
700 (set_attr "length" "3,3")])
702 (define_insn "zero_extendqisi2"
703 [(set (match_operand:SI 0 "register_operand" "=a,a")
704 (zero_extend:SI (match_operand:QI 1 "nonimmed_operand" "r,U")))]
709 [(set_attr "type" "arith,load")
710 (set_attr "mode" "SI")
711 (set_attr "length" "3,3")])
715 ;; ....................
719 ;; ....................
722 (define_expand "extendhisi2"
723 [(set (match_operand:SI 0 "register_operand" "")
724 (sign_extend:SI (match_operand:HI 1 "register_operand" "")))]
728 if (sext_operand (operands[1], HImode))
729 emit_insn (gen_extendhisi2_internal (operands[0], operands[1]));
731 xtensa_extend_reg (operands[0], operands[1]);
735 (define_insn "extendhisi2_internal"
736 [(set (match_operand:SI 0 "register_operand" "=B,a")
737 (sign_extend:SI (match_operand:HI 1 "sext_operand" "r,U")))]
742 [(set_attr "type" "arith,load")
743 (set_attr "mode" "SI")
744 (set_attr "length" "3,3")])
746 (define_expand "extendqisi2"
747 [(set (match_operand:SI 0 "register_operand" "")
748 (sign_extend:SI (match_operand:QI 1 "register_operand" "")))]
754 emit_insn (gen_extendqisi2_internal (operands[0], operands[1]));
757 xtensa_extend_reg (operands[0], operands[1]);
761 (define_insn "extendqisi2_internal"
762 [(set (match_operand:SI 0 "register_operand" "=B")
763 (sign_extend:SI (match_operand:QI 1 "register_operand" "r")))]
766 [(set_attr "type" "arith")
767 (set_attr "mode" "SI")
768 (set_attr "length" "3")])
772 ;; ....................
776 ;; ....................
779 (define_expand "extv"
780 [(set (match_operand:SI 0 "register_operand" "")
781 (sign_extract:SI (match_operand:SI 1 "register_operand" "")
782 (match_operand:SI 2 "const_int_operand" "")
783 (match_operand:SI 3 "const_int_operand" "")))]
787 if (!sext_fldsz_operand (operands[2], SImode)) FAIL;
788 /* we could expand to a right shift followed by sext but that's
789 no better than the standard left and right shift sequence */
790 if (!lsbitnum_operand (operands[3], SImode)) FAIL;
791 emit_insn (gen_extv_internal (operands[0], operands[1],
792 operands[2], operands[3]));
796 (define_insn "extv_internal"
797 [(set (match_operand:SI 0 "register_operand" "=a")
798 (sign_extract:SI (match_operand:SI 1 "register_operand" "r")
799 (match_operand:SI 2 "sext_fldsz_operand" "i")
800 (match_operand:SI 3 "lsbitnum_operand" "i")))]
804 int fldsz = INTVAL (operands[2]);
805 operands[2] = GEN_INT (fldsz - 1);
806 return \"sext\\t%0, %1, %2\";
808 [(set_attr "type" "arith")
809 (set_attr "mode" "SI")
810 (set_attr "length" "3")])
812 (define_expand "extzv"
813 [(set (match_operand:SI 0 "register_operand" "")
814 (zero_extract:SI (match_operand:SI 1 "register_operand" "")
815 (match_operand:SI 2 "const_int_operand" "")
816 (match_operand:SI 3 "const_int_operand" "")))]
820 if (!extui_fldsz_operand (operands[2], SImode)) FAIL;
821 emit_insn (gen_extzv_internal (operands[0], operands[1],
822 operands[2], operands[3]));
826 (define_insn "extzv_internal"
827 [(set (match_operand:SI 0 "register_operand" "=a")
828 (zero_extract:SI (match_operand:SI 1 "register_operand" "r")
829 (match_operand:SI 2 "extui_fldsz_operand" "i")
830 (match_operand:SI 3 "const_int_operand" "i")))]
836 shift = (32 - (INTVAL (operands[2]) + INTVAL (operands[3]))) & 0x1f;
838 shift = INTVAL (operands[3]) & 0x1f;
839 operands[3] = GEN_INT (shift);
840 return \"extui\\t%0, %1, %3, %2\";
842 [(set_attr "type" "arith")
843 (set_attr "mode" "SI")
844 (set_attr "length" "3")])
848 ;; ....................
852 ;; ....................
855 (define_insn "fix_truncsfsi2"
856 [(set (match_operand:SI 0 "register_operand" "=a")
857 (fix:SI (match_operand:SF 1 "register_operand" "f")))]
859 "trunc.s\\t%0, %1, 0"
860 [(set_attr "type" "fconv")
861 (set_attr "mode" "SF")
862 (set_attr "length" "3")])
864 (define_insn "fixuns_truncsfsi2"
865 [(set (match_operand:SI 0 "register_operand" "=a")
866 (unsigned_fix:SI (match_operand:SF 1 "register_operand" "f")))]
869 [(set_attr "type" "fconv")
870 (set_attr "mode" "SF")
871 (set_attr "length" "3")])
873 (define_insn "floatsisf2"
874 [(set (match_operand:SF 0 "register_operand" "=f")
875 (float:SF (match_operand:SI 1 "register_operand" "a")))]
877 "float.s\\t%0, %1, 0"
878 [(set_attr "type" "fconv")
879 (set_attr "mode" "SF")
880 (set_attr "length" "3")])
882 (define_insn "floatunssisf2"
883 [(set (match_operand:SF 0 "register_operand" "=f")
884 (unsigned_float:SF (match_operand:SI 1 "register_operand" "a")))]
887 [(set_attr "type" "fconv")
888 (set_attr "mode" "SF")
889 (set_attr "length" "3")])
893 ;; ....................
897 ;; ....................
900 ;; 64-bit Integer moves
902 (define_expand "movdi"
903 [(set (match_operand:DI 0 "nonimmed_operand" "")
904 (match_operand:DI 1 "general_operand" ""))]
908 if (CONSTANT_P (operands[1]))
910 rtx src0, src1, dst0, dst1;
911 if ((dst0 = operand_subword (operands[0], 0, 1, DImode))
912 && (src0 = operand_subword (operands[1], 0, 1, DImode))
913 && (dst1 = operand_subword (operands[0], 1, 1, DImode))
914 && (src1 = operand_subword (operands[1], 1, 1, DImode)))
916 emit_insn (gen_movsi (dst0, src0));
917 emit_insn (gen_movsi (dst1, src1));
921 /* any other constant will be loaded from memory */
922 operands[1] = force_const_mem (DImode, operands[1]);
925 if (!(reload_in_progress | reload_completed))
927 if (!register_operand (operands[0], DImode)
928 && !register_operand (operands[1], DImode))
929 operands[1] = force_reg (DImode, operands[1]);
931 if (a7_overlap_mentioned_p (operands[1]))
933 emit_insn (gen_movdi_internal (operands[0], operands[1]));
934 emit_insn (gen_set_frame_ptr ());
940 (define_insn "movdi_internal"
941 [(set (match_operand:DI 0 "nonimmed_operand" "=D,D,S,a,a,a,U")
942 (match_operand:DI 1 "non_const_move_operand" "d,S,d,r,T,U,r"))]
943 "register_operand (operands[0], DImode)
944 || register_operand (operands[1], DImode)"
947 switch (which_alternative)
949 case 0: return \"mov.n\\t%0, %1\;mov.n\\t%D0, %D1\";
950 case 2: return \"%v0s32i.n\\t%1, %0\;s32i.n\\t%D1, %N0\";
951 case 3: return \"mov\\t%0, %1\;mov\\t%D0, %D1\";
952 case 6: return \"%v0s32i\\t%1, %0\;s32i\\t%D1, %N0\";
958 /* Check if the first half of the destination register is used
959 in the source address. If so, reverse the order of the loads
960 so that the source address doesn't get clobbered until it is
963 rtx dstreg = operands[0];
964 if (GET_CODE (dstreg) == SUBREG)
965 dstreg = SUBREG_REG (dstreg);
966 if (GET_CODE (dstreg) != REG)
969 if (reg_mentioned_p (dstreg, operands[1]))
971 switch (which_alternative)
973 case 1: return \"%v1l32i.n\\t%D0, %N1\;l32i.n\\t%0, %1\";
974 case 4: return \"%v1l32r\\t%D0, %N1\;l32r\\t%0, %1\";
975 case 5: return \"%v1l32i\\t%D0, %N1\;l32i\\t%0, %1\";
980 switch (which_alternative)
982 case 1: return \"%v1l32i.n\\t%0, %1\;l32i.n\\t%D0, %N1\";
983 case 4: return \"%v1l32r\\t%0, %1\;l32r\\t%D0, %N1\";
984 case 5: return \"%v1l32i\\t%0, %1\;l32i\\t%D0, %N1\";
992 [(set_attr "type" "move,load,store,move,load,load,store")
993 (set_attr "mode" "DI")
994 (set_attr "length" "4,4,4,6,6,6,6")])
997 ;; 32-bit Integer moves
999 (define_expand "movsi"
1000 [(set (match_operand:SI 0 "nonimmed_operand" "")
1001 (match_operand:SI 1 "general_operand" ""))]
1005 if (xtensa_emit_move_sequence (operands, SImode))
1009 (define_insn "movsi_internal"
1010 [(set (match_operand:SI 0 "nonimmed_operand" "=D,D,D,D,R,R,a,q,a,a,a,U,*a,*A")
1011 (match_operand:SI 1 "move_operand" "M,D,d,R,D,d,r,r,I,T,U,r,*A,*r"))]
1012 "non_acc_reg_operand (operands[0], SImode)
1013 || non_acc_reg_operand (operands[1], SImode)"
1027 rsr\\t%0, 16 # ACCLO
1028 wsr\\t%1, 16 # ACCLO"
1029 [(set_attr "type" "move,move,move,load,store,store,move,move,move,load,load,store,rsr,wsr")
1030 (set_attr "mode" "SI")
1031 (set_attr "length" "2,2,2,2,2,2,3,3,3,3,3,3,3,3")])
1033 ;; 16-bit Integer moves
1035 (define_expand "movhi"
1036 [(set (match_operand:HI 0 "nonimmed_operand" "")
1037 (match_operand:HI 1 "general_operand" ""))]
1041 if (xtensa_emit_move_sequence (operands, HImode))
1045 (define_insn "movhi_internal"
1046 [(set (match_operand:HI 0 "nonimmed_operand" "=D,D,a,a,a,U,*a,*A")
1047 (match_operand:HI 1 "move_operand" "M,d,r,I,U,r,*A,*r"))]
1048 "non_acc_reg_operand (operands[0], HImode)
1049 || non_acc_reg_operand (operands[1], HImode)"
1057 rsr\\t%0, 16 # ACCLO
1058 wsr\\t%1, 16 # ACCLO"
1059 [(set_attr "type" "move,move,move,move,load,store,rsr,wsr")
1060 (set_attr "mode" "HI")
1061 (set_attr "length" "2,2,3,3,3,3,3,3")])
1063 ;; 8-bit Integer moves
1065 (define_expand "movqi"
1066 [(set (match_operand:QI 0 "nonimmed_operand" "")
1067 (match_operand:QI 1 "general_operand" ""))]
1071 if (xtensa_emit_move_sequence (operands, QImode))
1075 (define_insn "movqi_internal"
1076 [(set (match_operand:QI 0 "nonimmed_operand" "=D,D,a,a,a,U,*a,*A")
1077 (match_operand:QI 1 "move_operand" "M,d,r,I,U,r,*A,*r"))]
1078 "non_acc_reg_operand (operands[0], QImode)
1079 || non_acc_reg_operand (operands[1], QImode)"
1087 rsr\\t%0, 16 # ACCLO
1088 wsr\\t%1, 16 # ACCLO"
1089 [(set_attr "type" "move,move,move,move,load,store,rsr,wsr")
1090 (set_attr "mode" "QI")
1091 (set_attr "length" "2,2,3,3,3,3,3,3")])
1093 ;; 32-bit floating point moves
1095 (define_expand "movsf"
1096 [(set (match_operand:SF 0 "nonimmed_operand" "")
1097 (match_operand:SF 1 "general_operand" ""))]
1101 if (GET_CODE (operands[1]) == CONST_DOUBLE)
1102 operands[1] = force_const_mem (SFmode, operands[1]);
1104 if (!(reload_in_progress | reload_completed))
1106 if (((!register_operand (operands[0], SFmode)
1107 && !register_operand (operands[1], SFmode))
1108 || (FP_REG_P (xt_true_regnum (operands[0]))
1109 && constantpool_mem_p (operands[1]))))
1110 operands[1] = force_reg (SFmode, operands[1]);
1112 if (a7_overlap_mentioned_p (operands[1]))
1114 emit_insn (gen_movsf_internal (operands[0], operands[1]));
1115 emit_insn (gen_set_frame_ptr ());
1121 (define_insn "movsf_internal"
1122 [(set (match_operand:SF 0 "nonimmed_operand"
1123 "=f,f,U,D,D,R,a,f,a,a,a,U")
1124 (match_operand:SF 1 "non_const_move_operand"
1125 "f,U,f,d,R,d,r,r,f,T,U,r"))]
1126 "((register_operand (operands[0], SFmode)
1127 || register_operand (operands[1], SFmode))
1128 && (!FP_REG_P (xt_true_regnum (operands[0]))
1129 || !constantpool_mem_p (operands[1])))"
1143 [(set_attr "type" "farith,fload,fstore,move,load,store,move,farith,farith,load,load,store")
1144 (set_attr "mode" "SF")
1145 (set_attr "length" "3,3,3,2,2,2,3,3,3,3,3,3")])
1149 [(set (match_operand:SF 0 "register_operand" "=f")
1150 (mem:SF (plus:SI (match_operand:SI 1 "register_operand" "+a")
1151 (match_operand:SI 2 "fpmem_offset_operand" "i"))))
1153 (plus:SI (match_dup 1) (match_dup 2)))])]
1157 if (TARGET_SERIALIZE_VOLATILE && volatile_refs_p (PATTERN (insn)))
1158 output_asm_insn (\"memw\", operands);
1159 return \"lsiu\\t%0, %1, %2\";
1161 [(set_attr "type" "fload")
1162 (set_attr "mode" "SF")
1163 (set_attr "length" "3")])
1167 [(set (mem:SF (plus:SI (match_operand:SI 0 "register_operand" "+a")
1168 (match_operand:SI 1 "fpmem_offset_operand" "i")))
1169 (match_operand:SF 2 "register_operand" "f"))
1171 (plus:SI (match_dup 0) (match_dup 1)))])]
1175 if (TARGET_SERIALIZE_VOLATILE && volatile_refs_p (PATTERN (insn)))
1176 output_asm_insn (\"memw\", operands);
1177 return \"ssiu\\t%2, %0, %1\";
1179 [(set_attr "type" "fstore")
1180 (set_attr "mode" "SF")
1181 (set_attr "length" "3")])
1183 ;; 64-bit floating point moves
1185 (define_expand "movdf"
1186 [(set (match_operand:DF 0 "nonimmed_operand" "")
1187 (match_operand:DF 1 "general_operand" ""))]
1191 if (GET_CODE (operands[1]) == CONST_DOUBLE)
1192 operands[1] = force_const_mem (DFmode, operands[1]);
1194 if (!(reload_in_progress | reload_completed))
1196 if (!register_operand (operands[0], DFmode)
1197 && !register_operand (operands[1], DFmode))
1198 operands[1] = force_reg (DFmode, operands[1]);
1200 if (a7_overlap_mentioned_p (operands[1]))
1202 emit_insn (gen_movdf_internal (operands[0], operands[1]));
1203 emit_insn (gen_set_frame_ptr ());
1209 (define_insn "movdf_internal"
1210 [(set (match_operand:DF 0 "nonimmed_operand" "=D,D,S,a,a,a,U")
1211 (match_operand:DF 1 "non_const_move_operand" "d,S,d,r,T,U,r"))]
1212 "register_operand (operands[0], DFmode)
1213 || register_operand (operands[1], DFmode)"
1216 switch (which_alternative)
1218 case 0: return \"mov.n\\t%0, %1\;mov.n\\t%D0, %D1\";
1219 case 2: return \"%v0s32i.n\\t%1, %0\;s32i.n\\t%D1, %N0\";
1220 case 3: return \"mov\\t%0, %1\;mov\\t%D0, %D1\";
1221 case 6: return \"%v0s32i\\t%1, %0\;s32i\\t%D1, %N0\";
1227 /* Check if the first half of the destination register is used
1228 in the source address. If so, reverse the order of the loads
1229 so that the source address doesn't get clobbered until it is
1230 no longer needed. */
1232 rtx dstreg = operands[0];
1233 if (GET_CODE (dstreg) == SUBREG)
1234 dstreg = SUBREG_REG (dstreg);
1235 if (GET_CODE (dstreg) != REG)
1238 if (reg_mentioned_p (dstreg, operands[1]))
1240 switch (which_alternative)
1242 case 1: return \"%v1l32i.n\\t%D0, %N1\;l32i.n\\t%0, %1\";
1243 case 4: return \"%v1l32r\\t%D0, %N1\;l32r\\t%0, %1\";
1244 case 5: return \"%v1l32i\\t%D0, %N1\;l32i\\t%0, %1\";
1249 switch (which_alternative)
1251 case 1: return \"%v1l32i.n\\t%0, %1\;l32i.n\\t%D0, %N1\";
1252 case 4: return \"%v1l32r\\t%0, %1\;l32r\\t%D0, %N1\";
1253 case 5: return \"%v1l32i\\t%0, %1\;l32i\\t%D0, %N1\";
1261 [(set_attr "type" "move,load,store,move,load,load,store")
1262 (set_attr "mode" "DF")
1263 (set_attr "length" "4,4,4,6,6,6,6")])
1267 (define_expand "movstrsi"
1268 [(parallel [(set (match_operand:BLK 0 "" "")
1269 (match_operand:BLK 1 "" ""))
1270 (use (match_operand:SI 2 "arith_operand" ""))
1271 (use (match_operand:SI 3 "const_int_operand" ""))])]
1275 if (!xtensa_expand_block_move (operands)) FAIL;
1279 (define_insn "movstrsi_internal"
1280 [(parallel [(set (match_operand:BLK 0 "memory_operand" "=U")
1281 (match_operand:BLK 1 "memory_operand" "U"))
1282 (use (match_operand:SI 2 "arith_operand" ""))
1283 (use (match_operand:SI 3 "const_int_operand" ""))
1284 (clobber (match_scratch:SI 4 "=&r"))
1285 (clobber (match_scratch:SI 5 "=&r"))])]
1290 tmpregs[0] = operands[4];
1291 tmpregs[1] = operands[5];
1292 xtensa_emit_block_move (operands, tmpregs, 1);
1295 [(set_attr "type" "multi")
1296 (set_attr "mode" "none")
1297 (set_attr "length" "300")])
1301 ;; ....................
1305 ;; ....................
1308 (define_insn "ashlsi3"
1309 [(set (match_operand:SI 0 "register_operand" "=a,a")
1310 (ashift:SI (match_operand:SI 1 "register_operand" "r,r")
1311 (match_operand:SI 2 "arith_operand" "J,r")))]
1315 ssl\\t%2\;sll\\t%0, %1"
1316 [(set_attr "type" "arith,arith")
1317 (set_attr "mode" "SI")
1318 (set_attr "length" "3,6")])
1320 (define_insn "ashrsi3"
1321 [(set (match_operand:SI 0 "register_operand" "=a,a")
1322 (ashiftrt:SI (match_operand:SI 1 "register_operand" "r,r")
1323 (match_operand:SI 2 "arith_operand" "J,r")))]
1327 ssr\\t%2\;sra\\t%0, %1"
1328 [(set_attr "type" "arith,arith")
1329 (set_attr "mode" "SI")
1330 (set_attr "length" "3,6")])
1332 (define_insn "lshrsi3"
1333 [(set (match_operand:SI 0 "register_operand" "=a,a")
1334 (lshiftrt:SI (match_operand:SI 1 "register_operand" "r,r")
1335 (match_operand:SI 2 "arith_operand" "J,r")))]
1339 if (which_alternative == 0)
1341 if ((INTVAL (operands[2]) & 0x1f) < 16)
1342 return \"srli\\t%0, %1, %R2\";
1344 return \"extui\\t%0, %1, %R2, %L2\";
1346 return \"ssr\\t%2\;srl\\t%0, %1\";
1348 [(set_attr "type" "arith,arith")
1349 (set_attr "mode" "SI")
1350 (set_attr "length" "3,6")])
1352 (define_insn "rotlsi3"
1353 [(set (match_operand:SI 0 "register_operand" "=a,a")
1354 (rotate:SI (match_operand:SI 1 "register_operand" "r,r")
1355 (match_operand:SI 2 "arith_operand" "J,r")))]
1358 ssai\\t%L2\;src\\t%0, %1, %1
1359 ssl\\t%2\;src\\t%0, %1, %1"
1360 [(set_attr "type" "multi,multi")
1361 (set_attr "mode" "SI")
1362 (set_attr "length" "6,6")])
1364 (define_insn "rotrsi3"
1365 [(set (match_operand:SI 0 "register_operand" "=a,a")
1366 (rotatert:SI (match_operand:SI 1 "register_operand" "r,r")
1367 (match_operand:SI 2 "arith_operand" "J,r")))]
1370 ssai\\t%R2\;src\\t%0, %1, %1
1371 ssr\\t%2\;src\\t%0, %1, %1"
1372 [(set_attr "type" "multi,multi")
1373 (set_attr "mode" "SI")
1374 (set_attr "length" "6,6")])
1377 ;; ....................
1381 ;; ....................
1384 ;; Like the md files for MIPS and SPARC, we handle comparisons by stashing
1385 ;; away the operands and then using that information in the subsequent
1386 ;; conditional branch.
1388 (define_expand "cmpsi"
1390 (compare:CC (match_operand:SI 0 "register_operand" "")
1391 (match_operand:SI 1 "nonmemory_operand" "")))]
1395 branch_cmp[0] = operands[0];
1396 branch_cmp[1] = operands[1];
1397 branch_type = CMP_SI;
1401 (define_expand "tstsi"
1403 (match_operand:SI 0 "register_operand" ""))]
1407 branch_cmp[0] = operands[0];
1408 branch_cmp[1] = const0_rtx;
1409 branch_type = CMP_SI;
1413 (define_expand "cmpsf"
1415 (compare:CC (match_operand:SF 0 "register_operand" "")
1416 (match_operand:SF 1 "register_operand" "")))]
1420 branch_cmp[0] = operands[0];
1421 branch_cmp[1] = operands[1];
1422 branch_type = CMP_SF;
1428 ;; ....................
1430 ;; CONDITIONAL BRANCHES
1432 ;; ....................
1435 (define_expand "beq"
1437 (if_then_else (eq (cc0) (const_int 0))
1438 (label_ref (match_operand 0 "" ""))
1443 xtensa_expand_conditional_branch (operands, EQ);
1447 (define_expand "bne"
1449 (if_then_else (ne (cc0) (const_int 0))
1450 (label_ref (match_operand 0 "" ""))
1455 xtensa_expand_conditional_branch (operands, NE);
1459 (define_expand "bgt"
1461 (if_then_else (gt (cc0) (const_int 0))
1462 (label_ref (match_operand 0 "" ""))
1467 xtensa_expand_conditional_branch (operands, GT);
1471 (define_expand "bge"
1473 (if_then_else (ge (cc0) (const_int 0))
1474 (label_ref (match_operand 0 "" ""))
1479 xtensa_expand_conditional_branch (operands, GE);
1483 (define_expand "blt"
1485 (if_then_else (lt (cc0) (const_int 0))
1486 (label_ref (match_operand 0 "" ""))
1491 xtensa_expand_conditional_branch (operands, LT);
1495 (define_expand "ble"
1497 (if_then_else (le (cc0) (const_int 0))
1498 (label_ref (match_operand 0 "" ""))
1503 xtensa_expand_conditional_branch (operands, LE);
1507 (define_expand "bgtu"
1509 (if_then_else (gtu (cc0) (const_int 0))
1510 (label_ref (match_operand 0 "" ""))
1515 xtensa_expand_conditional_branch (operands, GTU);
1519 (define_expand "bgeu"
1521 (if_then_else (geu (cc0) (const_int 0))
1522 (label_ref (match_operand 0 "" ""))
1527 xtensa_expand_conditional_branch (operands, GEU);
1531 (define_expand "bltu"
1533 (if_then_else (ltu (cc0) (const_int 0))
1534 (label_ref (match_operand 0 "" ""))
1539 xtensa_expand_conditional_branch (operands, LTU);
1543 (define_expand "bleu"
1545 (if_then_else (leu (cc0) (const_int 0))
1546 (label_ref (match_operand 0 "" ""))
1551 xtensa_expand_conditional_branch (operands, LEU);
1555 ;; Branch patterns for standard integer comparisons
1559 (if_then_else (match_operator 3 "branch_operator"
1560 [(match_operand:SI 0 "register_operand" "r,r")
1561 (match_operand:SI 1 "branch_operand" "K,r")])
1562 (label_ref (match_operand 2 "" ""))
1567 if (which_alternative == 1)
1569 switch (GET_CODE (operands[3]))
1571 case EQ: return \"beq\\t%0, %1, %2\";
1572 case NE: return \"bne\\t%0, %1, %2\";
1573 case LT: return \"blt\\t%0, %1, %2\";
1574 case GE: return \"bge\\t%0, %1, %2\";
1578 else if (INTVAL (operands[1]) == 0)
1580 switch (GET_CODE (operands[3]))
1582 case EQ: return (TARGET_DENSITY
1583 ? \"beqz.n\\t%0, %2\"
1584 : \"beqz\\t%0, %2\");
1585 case NE: return (TARGET_DENSITY
1586 ? \"bnez.n\\t%0, %2\"
1587 : \"bnez\\t%0, %2\");
1588 case LT: return \"bltz\\t%0, %2\";
1589 case GE: return \"bgez\\t%0, %2\";
1595 switch (GET_CODE (operands[3]))
1597 case EQ: return \"beqi\\t%0, %d1, %2\";
1598 case NE: return \"bnei\\t%0, %d1, %2\";
1599 case LT: return \"blti\\t%0, %d1, %2\";
1600 case GE: return \"bgei\\t%0, %d1, %2\";
1604 fatal_insn (\"unexpected branch operator\", operands[3]);
1607 [(set_attr "type" "jump,jump")
1608 (set_attr "mode" "none")
1609 (set_attr "length" "3,3")])
1613 (if_then_else (match_operator 3 "branch_operator"
1614 [(match_operand:SI 0 "register_operand" "r,r")
1615 (match_operand:SI 1 "branch_operand" "K,r")])
1617 (label_ref (match_operand 2 "" ""))))]
1621 if (which_alternative == 1)
1623 switch (GET_CODE (operands[3]))
1625 case EQ: return \"bne\\t%0, %1, %2\";
1626 case NE: return \"beq\\t%0, %1, %2\";
1627 case LT: return \"bge\\t%0, %1, %2\";
1628 case GE: return \"blt\\t%0, %1, %2\";
1632 else if (INTVAL (operands[1]) == 0)
1634 switch (GET_CODE (operands[3]))
1636 case EQ: return (TARGET_DENSITY
1637 ? \"bnez.n\\t%0, %2\"
1638 : \"bnez\\t%0, %2\");
1639 case NE: return (TARGET_DENSITY
1640 ? \"beqz.n\\t%0, %2\"
1641 : \"beqz\\t%0, %2\");
1642 case LT: return \"bgez\\t%0, %2\";
1643 case GE: return \"bltz\\t%0, %2\";
1649 switch (GET_CODE (operands[3]))
1651 case EQ: return \"bnei\\t%0, %d1, %2\";
1652 case NE: return \"beqi\\t%0, %d1, %2\";
1653 case LT: return \"bgei\\t%0, %d1, %2\";
1654 case GE: return \"blti\\t%0, %d1, %2\";
1658 fatal_insn (\"unexpected branch operator\", operands[3]);
1661 [(set_attr "type" "jump,jump")
1662 (set_attr "mode" "none")
1663 (set_attr "length" "3,3")])
1667 (if_then_else (match_operator 3 "ubranch_operator"
1668 [(match_operand:SI 0 "register_operand" "r,r")
1669 (match_operand:SI 1 "ubranch_operand" "L,r")])
1670 (label_ref (match_operand 2 "" ""))
1675 if (which_alternative == 1)
1677 switch (GET_CODE (operands[3]))
1679 case LTU: return \"bltu\\t%0, %1, %2\";
1680 case GEU: return \"bgeu\\t%0, %1, %2\";
1686 switch (GET_CODE (operands[3]))
1688 case LTU: return \"bltui\\t%0, %d1, %2\";
1689 case GEU: return \"bgeui\\t%0, %d1, %2\";
1693 fatal_insn (\"unexpected branch operator\", operands[3]);
1696 [(set_attr "type" "jump,jump")
1697 (set_attr "mode" "none")
1698 (set_attr "length" "3,3")])
1702 (if_then_else (match_operator 3 "ubranch_operator"
1703 [(match_operand:SI 0 "register_operand" "r,r")
1704 (match_operand:SI 1 "ubranch_operand" "L,r")])
1706 (label_ref (match_operand 2 "" ""))))]
1710 if (which_alternative == 1)
1712 switch (GET_CODE (operands[3]))
1714 case LTU: return \"bgeu\\t%0, %1, %2\";
1715 case GEU: return \"bltu\\t%0, %1, %2\";
1721 switch (GET_CODE (operands[3]))
1723 case LTU: return \"bgeui\\t%0, %d1, %2\";
1724 case GEU: return \"bltui\\t%0, %d1, %2\";
1728 fatal_insn (\"unexpected branch operator\", operands[3]);
1731 [(set_attr "type" "jump,jump")
1732 (set_attr "mode" "none")
1733 (set_attr "length" "3,3")])
1735 ;; Branch patterns for bit testing
1739 (if_then_else (match_operator 3 "boolean_operator"
1741 (match_operand:SI 0 "register_operand" "r,r")
1743 (match_operand:SI 1 "arith_operand" "J,r"))
1745 (label_ref (match_operand 2 "" ""))
1750 if (which_alternative == 0)
1752 unsigned bitnum = INTVAL(operands[1]) & 0x1f;
1753 operands[1] = GEN_INT(bitnum);
1754 switch (GET_CODE (operands[3]))
1756 case EQ: return \"bbci\\t%0, %d1, %2\";
1757 case NE: return \"bbsi\\t%0, %d1, %2\";
1763 switch (GET_CODE (operands[3]))
1765 case EQ: return \"bbc\\t%0, %1, %2\";
1766 case NE: return \"bbs\\t%0, %1, %2\";
1770 fatal_insn (\"unexpected branch operator\", operands[3]);
1773 [(set_attr "type" "jump")
1774 (set_attr "mode" "none")
1775 (set_attr "length" "3")])
1779 (if_then_else (match_operator 3 "boolean_operator"
1781 (match_operand:SI 0 "register_operand" "r,r")
1783 (match_operand:SI 1 "arith_operand" "J,r"))
1786 (label_ref (match_operand 2 "" ""))))]
1790 if (which_alternative == 0)
1792 unsigned bitnum = INTVAL (operands[1]) & 0x1f;
1793 operands[1] = GEN_INT (bitnum);
1794 switch (GET_CODE (operands[3]))
1796 case EQ: return \"bbsi\\t%0, %d1, %2\";
1797 case NE: return \"bbci\\t%0, %d1, %2\";
1803 switch (GET_CODE (operands[3]))
1805 case EQ: return \"bbs\\t%0, %1, %2\";
1806 case NE: return \"bbc\\t%0, %1, %2\";
1810 fatal_insn (\"unexpected branch operator\", operands[3]);
1813 [(set_attr "type" "jump")
1814 (set_attr "mode" "none")
1815 (set_attr "length" "3")])
1819 (if_then_else (match_operator 3 "boolean_operator"
1820 [(and:SI (match_operand:SI 0 "register_operand" "r")
1821 (match_operand:SI 1 "register_operand" "r"))
1823 (label_ref (match_operand 2 "" ""))
1828 switch (GET_CODE (operands[3]))
1830 case EQ: return \"bnone\\t%0, %1, %2\";
1831 case NE: return \"bany\\t%0, %1, %2\";
1834 fatal_insn (\"unexpected branch operator\", operands[3]);
1837 [(set_attr "type" "jump")
1838 (set_attr "mode" "none")
1839 (set_attr "length" "3")])
1843 (if_then_else (match_operator 3 "boolean_operator"
1844 [(and:SI (match_operand:SI 0 "register_operand" "r")
1845 (match_operand:SI 1 "register_operand" "r"))
1848 (label_ref (match_operand 2 "" ""))))]
1852 switch (GET_CODE (operands[3]))
1854 case EQ: return \"bany\\t%0, %1, %2\";
1855 case NE: return \"bnone\\t%0, %1, %2\";
1858 fatal_insn (\"unexpected branch operator\", operands[3]);
1861 [(set_attr "type" "jump")
1862 (set_attr "mode" "none")
1863 (set_attr "length" "3")])
1866 ;; Define the loop insns that is used by bct optimization to represent the
1867 ;; start and end of a zero-overhead loop (in loop.c). This start template
1868 ;; generates the loop insn, the end template doesn't generate any instructions
1869 ;; since since loop end is handled in hardware.
1871 (define_insn "zero_cost_loop_start"
1872 [(parallel [(set (pc) (if_then_else (eq (match_operand:SI 0 "register_operand" "a")
1874 (label_ref (match_operand 1 "" ""))
1877 (plus:SI (match_dup 0)
1881 [(set_attr "type" "jump")
1882 (set_attr "mode" "none")
1883 (set_attr "length" "3")])
1885 (define_insn "zero_cost_loop_end"
1886 [(parallel [(set (pc) (if_then_else (ne (reg:SI 19)
1888 (label_ref (match_operand 0 "" ""))
1891 (plus:SI (reg:SI 19)
1895 xtensa_emit_loop_end (insn, operands);
1898 [(set_attr "type" "jump")
1899 (set_attr "mode" "none")
1900 (set_attr "length" "0")])
1904 ;; ....................
1906 ;; SETTING A REGISTER FROM A COMPARISON
1908 ;; ....................
1911 (define_expand "seq"
1912 [(set (match_operand:SI 0 "register_operand" "")
1917 operands[1] = gen_rtx (EQ, SImode, branch_cmp[0], branch_cmp[1]);
1918 if (!xtensa_expand_scc (operands)) FAIL;
1922 (define_expand "sne"
1923 [(set (match_operand:SI 0 "register_operand" "")
1928 operands[1] = gen_rtx (NE, SImode, branch_cmp[0], branch_cmp[1]);
1929 if (!xtensa_expand_scc (operands)) FAIL;
1933 (define_expand "sgt"
1934 [(set (match_operand:SI 0 "register_operand" "")
1939 operands[1] = gen_rtx (GT, SImode, branch_cmp[0], branch_cmp[1]);
1940 if (!xtensa_expand_scc (operands)) FAIL;
1944 (define_expand "sge"
1945 [(set (match_operand:SI 0 "register_operand" "")
1950 operands[1] = gen_rtx (GE, SImode, branch_cmp[0], branch_cmp[1]);
1951 if (!xtensa_expand_scc (operands)) FAIL;
1955 (define_expand "slt"
1956 [(set (match_operand:SI 0 "register_operand" "")
1961 operands[1] = gen_rtx (LT, SImode, branch_cmp[0], branch_cmp[1]);
1962 if (!xtensa_expand_scc (operands)) FAIL;
1966 (define_expand "sle"
1967 [(set (match_operand:SI 0 "register_operand" "")
1972 operands[1] = gen_rtx (LE, SImode, branch_cmp[0], branch_cmp[1]);
1973 if (!xtensa_expand_scc (operands)) FAIL;
1979 ;; ....................
1981 ;; CONDITIONAL MOVES
1983 ;; ....................
1986 (define_expand "movsicc"
1987 [(set (match_operand:SI 0 "register_operand" "")
1988 (if_then_else:SI (match_operand 1 "comparison_operator" "")
1989 (match_operand:SI 2 "register_operand" "")
1990 (match_operand:SI 3 "register_operand" "")))]
1994 if (!xtensa_expand_conditional_move (operands, 0)) FAIL;
1998 (define_expand "movsfcc"
1999 [(set (match_operand:SF 0 "register_operand" "")
2000 (if_then_else:SF (match_operand 1 "comparison_operator" "")
2001 (match_operand:SF 2 "register_operand" "")
2002 (match_operand:SF 3 "register_operand" "")))]
2006 if (!xtensa_expand_conditional_move (operands, 1)) FAIL;
2010 (define_insn "movsicc_internal0"
2011 [(set (match_operand:SI 0 "register_operand" "=a,a")
2012 (if_then_else:SI (match_operator 4 "branch_operator"
2013 [(match_operand:SI 1 "register_operand" "r,r")
2015 (match_operand:SI 2 "register_operand" "r,0")
2016 (match_operand:SI 3 "register_operand" "0,r")))]
2020 if (which_alternative == 0)
2022 switch (GET_CODE (operands[4]))
2024 case EQ: return \"moveqz\\t%0, %2, %1\";
2025 case NE: return \"movnez\\t%0, %2, %1\";
2026 case LT: return \"movltz\\t%0, %2, %1\";
2027 case GE: return \"movgez\\t%0, %2, %1\";
2033 switch (GET_CODE (operands[4]))
2035 case EQ: return \"movnez\\t%0, %3, %1\";
2036 case NE: return \"moveqz\\t%0, %3, %1\";
2037 case LT: return \"movgez\\t%0, %3, %1\";
2038 case GE: return \"movltz\\t%0, %3, %1\";
2042 fatal_insn (\"unexpected cmov operator\", operands[4]);
2045 [(set_attr "type" "move,move")
2046 (set_attr "mode" "SI")
2047 (set_attr "length" "3,3")])
2049 (define_insn "movsicc_internal1"
2050 [(set (match_operand:SI 0 "register_operand" "=a,a")
2051 (if_then_else:SI (match_operator 4 "boolean_operator"
2052 [(match_operand:CC 1 "register_operand" "b,b")
2054 (match_operand:SI 2 "register_operand" "r,0")
2055 (match_operand:SI 3 "register_operand" "0,r")))]
2059 int isEq = (GET_CODE (operands[4]) == EQ);
2060 switch (which_alternative)
2063 if (isEq) return \"movf\\t%0, %2, %1\";
2064 return \"movt\\t%0, %2, %1\";
2066 if (isEq) return \"movt\\t%0, %3, %1\";
2067 return \"movf\\t%0, %3, %1\";
2072 [(set_attr "type" "move,move")
2073 (set_attr "mode" "SI")
2074 (set_attr "length" "3,3")])
2076 (define_insn "movsfcc_internal0"
2077 [(set (match_operand:SF 0 "register_operand" "=a,a,f,f")
2078 (if_then_else:SF (match_operator 4 "branch_operator"
2079 [(match_operand:SI 1 "register_operand" "r,r,r,r")
2081 (match_operand:SF 2 "register_operand" "r,0,f,0")
2082 (match_operand:SF 3 "register_operand" "0,r,0,f")))]
2086 if (which_alternative == 0)
2088 switch (GET_CODE (operands[4]))
2090 case EQ: return \"moveqz\\t%0, %2, %1\";
2091 case NE: return \"movnez\\t%0, %2, %1\";
2092 case LT: return \"movltz\\t%0, %2, %1\";
2093 case GE: return \"movgez\\t%0, %2, %1\";
2097 else if (which_alternative == 1)
2099 switch (GET_CODE (operands[4]))
2101 case EQ: return \"movnez\\t%0, %3, %1\";
2102 case NE: return \"moveqz\\t%0, %3, %1\";
2103 case LT: return \"movgez\\t%0, %3, %1\";
2104 case GE: return \"movltz\\t%0, %3, %1\";
2108 else if (which_alternative == 2)
2110 switch (GET_CODE (operands[4]))
2112 case EQ: return \"moveqz.s %0, %2, %1\";
2113 case NE: return \"movnez.s %0, %2, %1\";
2114 case LT: return \"movltz.s %0, %2, %1\";
2115 case GE: return \"movgez.s %0, %2, %1\";
2119 else if (which_alternative == 3)
2121 switch (GET_CODE (operands[4]))
2123 case EQ: return \"movnez.s %0, %3, %1\";
2124 case NE: return \"moveqz.s %0, %3, %1\";
2125 case LT: return \"movgez.s %0, %3, %1\";
2126 case GE: return \"movltz.s %0, %3, %1\";
2130 fatal_insn (\"unexpected cmov operator\", operands[4]);
2133 [(set_attr "type" "move,move,move,move")
2134 (set_attr "mode" "SF")
2135 (set_attr "length" "3,3,3,3")])
2137 (define_insn "movsfcc_internal1"
2138 [(set (match_operand:SF 0 "register_operand" "=a,a,f,f")
2139 (if_then_else:SF (match_operator 4 "boolean_operator"
2140 [(match_operand:CC 1 "register_operand" "b,b,b,b")
2142 (match_operand:SF 2 "register_operand" "r,0,f,0")
2143 (match_operand:SF 3 "register_operand" "0,r,0,f")))]
2147 int isEq = (GET_CODE (operands[4]) == EQ);
2148 switch (which_alternative)
2151 if (isEq) return \"movf\\t%0, %2, %1\";
2152 return \"movt\\t%0, %2, %1\";
2154 if (isEq) return \"movt\\t%0, %3, %1\";
2155 return \"movf\\t%0, %3, %1\";
2157 if (isEq) return \"movf.s\\t%0, %2, %1\";
2158 return \"movt.s\\t%0, %2, %1\";
2160 if (isEq) return \"movt.s\\t%0, %3, %1\";
2161 return \"movf.s\\t%0, %3, %1\";
2166 [(set_attr "type" "move,move,move,move")
2167 (set_attr "mode" "SF")
2168 (set_attr "length" "3,3,3,3")])
2172 ;; ....................
2174 ;; FLOATING POINT COMPARISONS
2176 ;; ....................
2179 (define_insn "seq_sf"
2180 [(set (match_operand:CC 0 "register_operand" "=b")
2181 (eq:CC (match_operand:SF 1 "register_operand" "f")
2182 (match_operand:SF 2 "register_operand" "f")))]
2184 "oeq.s\\t%0, %1, %2"
2185 [(set_attr "type" "farith")
2186 (set_attr "mode" "BL")
2187 (set_attr "length" "3")])
2189 (define_insn "slt_sf"
2190 [(set (match_operand:CC 0 "register_operand" "=b")
2191 (lt:CC (match_operand:SF 1 "register_operand" "f")
2192 (match_operand:SF 2 "register_operand" "f")))]
2194 "olt.s\\t%0, %1, %2"
2195 [(set_attr "type" "farith")
2196 (set_attr "mode" "BL")
2197 (set_attr "length" "3")])
2199 (define_insn "sle_sf"
2200 [(set (match_operand:CC 0 "register_operand" "=b")
2201 (le:CC (match_operand:SF 1 "register_operand" "f")
2202 (match_operand:SF 2 "register_operand" "f")))]
2204 "ole.s\\t%0, %1, %2"
2205 [(set_attr "type" "farith")
2206 (set_attr "mode" "BL")
2207 (set_attr "length" "3")])
2211 ;; ....................
2213 ;; UNCONDITIONAL BRANCHES
2215 ;; ....................
2220 (label_ref (match_operand 0 "" "")))]
2223 [(set_attr "type" "jump")
2224 (set_attr "mode" "none")
2225 (set_attr "length" "3")])
2227 (define_expand "indirect_jump"
2228 [(set (pc) (match_operand 0 "register_operand" ""))]
2232 rtx dest = operands[0];
2233 if (GET_CODE (dest) != REG || GET_MODE (dest) != Pmode)
2234 operands[0] = copy_to_mode_reg (Pmode, dest);
2236 emit_jump_insn (gen_indirect_jump_internal (dest));
2240 (define_insn "indirect_jump_internal"
2241 [(set (pc) (match_operand:SI 0 "register_operand" "r"))]
2244 [(set_attr "type" "jump")
2245 (set_attr "mode" "none")
2246 (set_attr "length" "3")])
2249 (define_expand "tablejump"
2250 [(use (match_operand:SI 0 "register_operand" ""))
2251 (use (label_ref (match_operand 1 "" "")))]
2255 rtx target = operands[0];
2258 /* For PIC, the table entry is relative to the start of the table. */
2259 rtx label = gen_reg_rtx (SImode);
2260 target = gen_reg_rtx (SImode);
2261 emit_move_insn (label, gen_rtx_LABEL_REF (SImode, operands[1]));
2262 emit_insn (gen_addsi3 (target, operands[0], label));
2264 emit_jump_insn (gen_tablejump_internal (target, operands[1]));
2268 (define_insn "tablejump_internal"
2270 (match_operand:SI 0 "register_operand" "r"))
2271 (use (label_ref (match_operand 1 "" "")))]
2274 [(set_attr "type" "jump")
2275 (set_attr "mode" "none")
2276 (set_attr "length" "3")])
2280 ;; ....................
2284 ;; ....................
2287 (define_expand "sym_PLT"
2288 [(const (unspec [(match_operand:SI 0 "" "")] UNSPEC_PLT))]
2292 (define_expand "call"
2293 [(call (match_operand 0 "memory_operand" "")
2294 (match_operand 1 "" ""))]
2298 rtx addr = XEXP (operands[0], 0);
2299 if (flag_pic && GET_CODE (addr) == SYMBOL_REF && !SYMBOL_REF_FLAG (addr))
2300 addr = gen_sym_PLT (addr);
2301 if (!call_insn_operand (addr, VOIDmode))
2302 XEXP (operands[0], 0) = copy_to_mode_reg (Pmode, addr);
2305 (define_insn "call_internal"
2306 [(call (mem (match_operand:SI 0 "call_insn_operand" "n,i,r"))
2307 (match_operand 1 "" "i,i,i"))]
2310 return xtensa_emit_call (0, operands);
2312 [(set_attr "type" "call")
2313 (set_attr "mode" "none")
2314 (set_attr "length" "3")])
2316 (define_expand "call_value"
2317 [(set (match_operand 0 "register_operand" "")
2318 (call (match_operand 1 "memory_operand" "")
2319 (match_operand 2 "" "")))]
2323 rtx addr = XEXP (operands[1], 0);
2324 if (flag_pic && GET_CODE (addr) == SYMBOL_REF && !SYMBOL_REF_FLAG (addr))
2325 addr = gen_sym_PLT (addr);
2326 if (!call_insn_operand (addr, VOIDmode))
2327 XEXP (operands[1], 0) = copy_to_mode_reg (Pmode, addr);
2330 ;; cannot combine constraints for operand 0 into "afvb"
2331 ;; reload.c:find_reloads seems to assume that grouped constraints somehow
2332 ;; specify related register classes, and when they don't the constraints
2333 ;; fail to match. By not grouping the constraints, we get the correct
2335 (define_insn "call_value_internal"
2336 [(set (match_operand 0 "register_operand" "=af,af,af,v,v,v,b,b,b")
2337 (call (mem (match_operand:SI 1 "call_insn_operand"
2338 "n,i,r,n,i,r,n,i,r"))
2339 (match_operand 2 "" "i,i,i,i,i,i,i,i,i")))]
2342 return xtensa_emit_call (1, operands);
2344 [(set_attr "type" "call")
2345 (set_attr "mode" "none")
2346 (set_attr "length" "3")])
2348 (define_insn "return"
2350 (use (reg:SI A0_REG))]
2354 return (TARGET_DENSITY ? \"retw.n\" : \"retw\");
2356 [(set_attr "type" "jump")
2357 (set_attr "mode" "none")
2358 (set_attr "length" "2")])
2362 ;; ....................
2366 ;; ....................
2374 return (TARGET_DENSITY ? \"nop.n\" : \"nop\");
2376 [(set_attr "type" "nop")
2377 (set_attr "mode" "none")
2378 (set_attr "length" "3")])
2380 (define_expand "nonlocal_goto"
2381 [(match_operand:SI 0 "general_operand" "")
2382 (match_operand:SI 1 "general_operand" "")
2383 (match_operand:SI 2 "general_operand" "")
2384 (match_operand:SI 3 "" "")]
2388 xtensa_expand_nonlocal_goto (operands);
2392 ;; Setting up a frame pointer is tricky for Xtensa because GCC doesn't
2393 ;; know if a frame pointer is required until the reload pass, and
2394 ;; because there may be an incoming argument value in the hard frame
2395 ;; pointer register (a7). If there is an incoming argument in that
2396 ;; register, the "set_frame_ptr" insn gets inserted immediately after
2397 ;; the insn that copies the incoming argument to a pseudo or to the
2398 ;; stack. This serves several purposes here: (1) it keeps the
2399 ;; optimizer from copy-propagating or scheduling the use of a7 as an
2400 ;; incoming argument away from the beginning of the function; (2) we
2401 ;; can use a post-reload splitter to expand away the insn if a frame
2402 ;; pointer is not required, so that the post-reload scheduler can do
2403 ;; the right thing; and (3) it makes it easy for xtensa_reorg() to
2404 ;; search for this insn to determine whether it should add a new insn
2405 ;; to set up the frame pointer.
2407 (define_insn "set_frame_ptr"
2408 [(unspec_volatile [(const_int 0)] UNSPECV_SET_FP)]
2412 if (frame_pointer_needed)
2413 return \"mov\\ta7, sp\";
2416 [(set_attr "type" "move")
2417 (set_attr "mode" "SI")
2418 (set_attr "length" "3")])
2420 ;; Post-reload splitter to remove fp assignment when it's not needed.
2422 [(unspec_volatile [(const_int 0)] UNSPECV_SET_FP)]
2423 "reload_completed && !frame_pointer_needed"
2424 [(unspec [(const_int 0)] UNSPEC_NOP)]
2427 ;; The preceding splitter needs something to split the insn into;
2428 ;; things start breaking if the result is just a "use" so instead we
2429 ;; generate the following insn.
2431 [(unspec [(const_int 0)] UNSPEC_NOP)]
2434 [(set_attr "type" "nop")
2435 (set_attr "mode" "none")
2436 (set_attr "length" "0")])
2439 ;; ....................
2443 ;; ....................
2450 (if_then_else (match_operator 2 "boolean_operator"
2451 [(match_operand:CC 0 "register_operand" "b")
2453 (label_ref (match_operand 1 "" ""))
2458 if (GET_CODE (operands[2]) == EQ)
2459 return \"bf\\t%0, %1\";
2461 return \"bt\\t%0, %1\";
2463 [(set_attr "type" "jump")
2464 (set_attr "mode" "none")
2465 (set_attr "length" "3")])
2469 (if_then_else (match_operator 2 "boolean_operator"
2470 [(match_operand:CC 0 "register_operand" "b")
2473 (label_ref (match_operand 1 "" ""))))]
2477 if (GET_CODE (operands[2]) == EQ)
2478 return \"bt\\t%0, %1\";
2480 return \"bf\\t%0, %1\";
2482 [(set_attr "type" "jump")
2483 (set_attr "mode" "none")
2484 (set_attr "length" "3")])