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 "xtensa_valid_move (SImode, operands)"
1026 rsr\\t%0, 16 # ACCLO
1027 wsr\\t%1, 16 # ACCLO"
1028 [(set_attr "type" "move,move,move,load,store,store,move,move,move,load,load,store,rsr,wsr")
1029 (set_attr "mode" "SI")
1030 (set_attr "length" "2,2,2,2,2,2,3,3,3,3,3,3,3,3")])
1032 ;; 16-bit Integer moves
1034 (define_expand "movhi"
1035 [(set (match_operand:HI 0 "nonimmed_operand" "")
1036 (match_operand:HI 1 "general_operand" ""))]
1040 if (xtensa_emit_move_sequence (operands, HImode))
1044 (define_insn "movhi_internal"
1045 [(set (match_operand:HI 0 "nonimmed_operand" "=D,D,a,a,a,U,*a,*A")
1046 (match_operand:HI 1 "move_operand" "M,d,r,I,U,r,*A,*r"))]
1047 "xtensa_valid_move (HImode, operands)"
1055 rsr\\t%0, 16 # ACCLO
1056 wsr\\t%1, 16 # ACCLO"
1057 [(set_attr "type" "move,move,move,move,load,store,rsr,wsr")
1058 (set_attr "mode" "HI")
1059 (set_attr "length" "2,2,3,3,3,3,3,3")])
1061 ;; 8-bit Integer moves
1063 (define_expand "movqi"
1064 [(set (match_operand:QI 0 "nonimmed_operand" "")
1065 (match_operand:QI 1 "general_operand" ""))]
1069 if (xtensa_emit_move_sequence (operands, QImode))
1073 (define_insn "movqi_internal"
1074 [(set (match_operand:QI 0 "nonimmed_operand" "=D,D,a,a,a,U,*a,*A")
1075 (match_operand:QI 1 "move_operand" "M,d,r,I,U,r,*A,*r"))]
1076 "xtensa_valid_move (QImode, operands)"
1084 rsr\\t%0, 16 # ACCLO
1085 wsr\\t%1, 16 # ACCLO"
1086 [(set_attr "type" "move,move,move,move,load,store,rsr,wsr")
1087 (set_attr "mode" "QI")
1088 (set_attr "length" "2,2,3,3,3,3,3,3")])
1090 ;; 32-bit floating point moves
1092 (define_expand "movsf"
1093 [(set (match_operand:SF 0 "nonimmed_operand" "")
1094 (match_operand:SF 1 "general_operand" ""))]
1098 if (GET_CODE (operands[1]) == CONST_DOUBLE)
1099 operands[1] = force_const_mem (SFmode, operands[1]);
1101 if (!(reload_in_progress | reload_completed))
1103 if (((!register_operand (operands[0], SFmode)
1104 && !register_operand (operands[1], SFmode))
1105 || (FP_REG_P (xt_true_regnum (operands[0]))
1106 && constantpool_mem_p (operands[1]))))
1107 operands[1] = force_reg (SFmode, operands[1]);
1109 if (a7_overlap_mentioned_p (operands[1]))
1111 emit_insn (gen_movsf_internal (operands[0], operands[1]));
1112 emit_insn (gen_set_frame_ptr ());
1118 (define_insn "movsf_internal"
1119 [(set (match_operand:SF 0 "nonimmed_operand"
1120 "=f,f,U,D,D,R,a,f,a,a,a,U")
1121 (match_operand:SF 1 "non_const_move_operand"
1122 "f,U,f,d,R,d,r,r,f,T,U,r"))]
1123 "((register_operand (operands[0], SFmode)
1124 || register_operand (operands[1], SFmode))
1125 && (!FP_REG_P (xt_true_regnum (operands[0]))
1126 || !constantpool_mem_p (operands[1])))"
1140 [(set_attr "type" "farith,fload,fstore,move,load,store,move,farith,farith,load,load,store")
1141 (set_attr "mode" "SF")
1142 (set_attr "length" "3,3,3,2,2,2,3,3,3,3,3,3")])
1146 [(set (match_operand:SF 0 "register_operand" "=f")
1147 (mem:SF (plus:SI (match_operand:SI 1 "register_operand" "+a")
1148 (match_operand:SI 2 "fpmem_offset_operand" "i"))))
1150 (plus:SI (match_dup 1) (match_dup 2)))])]
1154 if (TARGET_SERIALIZE_VOLATILE && volatile_refs_p (PATTERN (insn)))
1155 output_asm_insn (\"memw\", operands);
1156 return \"lsiu\\t%0, %1, %2\";
1158 [(set_attr "type" "fload")
1159 (set_attr "mode" "SF")
1160 (set_attr "length" "3")])
1164 [(set (mem:SF (plus:SI (match_operand:SI 0 "register_operand" "+a")
1165 (match_operand:SI 1 "fpmem_offset_operand" "i")))
1166 (match_operand:SF 2 "register_operand" "f"))
1168 (plus:SI (match_dup 0) (match_dup 1)))])]
1172 if (TARGET_SERIALIZE_VOLATILE && volatile_refs_p (PATTERN (insn)))
1173 output_asm_insn (\"memw\", operands);
1174 return \"ssiu\\t%2, %0, %1\";
1176 [(set_attr "type" "fstore")
1177 (set_attr "mode" "SF")
1178 (set_attr "length" "3")])
1180 ;; 64-bit floating point moves
1182 (define_expand "movdf"
1183 [(set (match_operand:DF 0 "nonimmed_operand" "")
1184 (match_operand:DF 1 "general_operand" ""))]
1188 if (GET_CODE (operands[1]) == CONST_DOUBLE)
1189 operands[1] = force_const_mem (DFmode, operands[1]);
1191 if (!(reload_in_progress | reload_completed))
1193 if (!register_operand (operands[0], DFmode)
1194 && !register_operand (operands[1], DFmode))
1195 operands[1] = force_reg (DFmode, operands[1]);
1197 if (a7_overlap_mentioned_p (operands[1]))
1199 emit_insn (gen_movdf_internal (operands[0], operands[1]));
1200 emit_insn (gen_set_frame_ptr ());
1206 (define_insn "movdf_internal"
1207 [(set (match_operand:DF 0 "nonimmed_operand" "=D,D,S,a,a,a,U")
1208 (match_operand:DF 1 "non_const_move_operand" "d,S,d,r,T,U,r"))]
1209 "register_operand (operands[0], DFmode)
1210 || register_operand (operands[1], DFmode)"
1213 switch (which_alternative)
1215 case 0: return \"mov.n\\t%0, %1\;mov.n\\t%D0, %D1\";
1216 case 2: return \"%v0s32i.n\\t%1, %0\;s32i.n\\t%D1, %N0\";
1217 case 3: return \"mov\\t%0, %1\;mov\\t%D0, %D1\";
1218 case 6: return \"%v0s32i\\t%1, %0\;s32i\\t%D1, %N0\";
1224 /* Check if the first half of the destination register is used
1225 in the source address. If so, reverse the order of the loads
1226 so that the source address doesn't get clobbered until it is
1227 no longer needed. */
1229 rtx dstreg = operands[0];
1230 if (GET_CODE (dstreg) == SUBREG)
1231 dstreg = SUBREG_REG (dstreg);
1232 if (GET_CODE (dstreg) != REG)
1235 if (reg_mentioned_p (dstreg, operands[1]))
1237 switch (which_alternative)
1239 case 1: return \"%v1l32i.n\\t%D0, %N1\;l32i.n\\t%0, %1\";
1240 case 4: return \"%v1l32r\\t%D0, %N1\;l32r\\t%0, %1\";
1241 case 5: return \"%v1l32i\\t%D0, %N1\;l32i\\t%0, %1\";
1246 switch (which_alternative)
1248 case 1: return \"%v1l32i.n\\t%0, %1\;l32i.n\\t%D0, %N1\";
1249 case 4: return \"%v1l32r\\t%0, %1\;l32r\\t%D0, %N1\";
1250 case 5: return \"%v1l32i\\t%0, %1\;l32i\\t%D0, %N1\";
1258 [(set_attr "type" "move,load,store,move,load,load,store")
1259 (set_attr "mode" "DF")
1260 (set_attr "length" "4,4,4,6,6,6,6")])
1264 (define_expand "movstrsi"
1265 [(parallel [(set (match_operand:BLK 0 "" "")
1266 (match_operand:BLK 1 "" ""))
1267 (use (match_operand:SI 2 "arith_operand" ""))
1268 (use (match_operand:SI 3 "const_int_operand" ""))])]
1272 if (!xtensa_expand_block_move (operands)) FAIL;
1276 (define_insn "movstrsi_internal"
1277 [(parallel [(set (match_operand:BLK 0 "memory_operand" "=U")
1278 (match_operand:BLK 1 "memory_operand" "U"))
1279 (use (match_operand:SI 2 "arith_operand" ""))
1280 (use (match_operand:SI 3 "const_int_operand" ""))
1281 (clobber (match_scratch:SI 4 "=&r"))
1282 (clobber (match_scratch:SI 5 "=&r"))])]
1287 tmpregs[0] = operands[4];
1288 tmpregs[1] = operands[5];
1289 xtensa_emit_block_move (operands, tmpregs, 1);
1292 [(set_attr "type" "multi")
1293 (set_attr "mode" "none")
1294 (set_attr "length" "300")])
1298 ;; ....................
1302 ;; ....................
1305 (define_insn "ashlsi3"
1306 [(set (match_operand:SI 0 "register_operand" "=a,a")
1307 (ashift:SI (match_operand:SI 1 "register_operand" "r,r")
1308 (match_operand:SI 2 "arith_operand" "J,r")))]
1312 ssl\\t%2\;sll\\t%0, %1"
1313 [(set_attr "type" "arith,arith")
1314 (set_attr "mode" "SI")
1315 (set_attr "length" "3,6")])
1317 (define_insn "ashrsi3"
1318 [(set (match_operand:SI 0 "register_operand" "=a,a")
1319 (ashiftrt:SI (match_operand:SI 1 "register_operand" "r,r")
1320 (match_operand:SI 2 "arith_operand" "J,r")))]
1324 ssr\\t%2\;sra\\t%0, %1"
1325 [(set_attr "type" "arith,arith")
1326 (set_attr "mode" "SI")
1327 (set_attr "length" "3,6")])
1329 (define_insn "lshrsi3"
1330 [(set (match_operand:SI 0 "register_operand" "=a,a")
1331 (lshiftrt:SI (match_operand:SI 1 "register_operand" "r,r")
1332 (match_operand:SI 2 "arith_operand" "J,r")))]
1336 if (which_alternative == 0)
1338 if ((INTVAL (operands[2]) & 0x1f) < 16)
1339 return \"srli\\t%0, %1, %R2\";
1341 return \"extui\\t%0, %1, %R2, %L2\";
1343 return \"ssr\\t%2\;srl\\t%0, %1\";
1345 [(set_attr "type" "arith,arith")
1346 (set_attr "mode" "SI")
1347 (set_attr "length" "3,6")])
1349 (define_insn "rotlsi3"
1350 [(set (match_operand:SI 0 "register_operand" "=a,a")
1351 (rotate:SI (match_operand:SI 1 "register_operand" "r,r")
1352 (match_operand:SI 2 "arith_operand" "J,r")))]
1355 ssai\\t%L2\;src\\t%0, %1, %1
1356 ssl\\t%2\;src\\t%0, %1, %1"
1357 [(set_attr "type" "multi,multi")
1358 (set_attr "mode" "SI")
1359 (set_attr "length" "6,6")])
1361 (define_insn "rotrsi3"
1362 [(set (match_operand:SI 0 "register_operand" "=a,a")
1363 (rotatert:SI (match_operand:SI 1 "register_operand" "r,r")
1364 (match_operand:SI 2 "arith_operand" "J,r")))]
1367 ssai\\t%R2\;src\\t%0, %1, %1
1368 ssr\\t%2\;src\\t%0, %1, %1"
1369 [(set_attr "type" "multi,multi")
1370 (set_attr "mode" "SI")
1371 (set_attr "length" "6,6")])
1374 ;; ....................
1378 ;; ....................
1381 ;; Like the md files for MIPS and SPARC, we handle comparisons by stashing
1382 ;; away the operands and then using that information in the subsequent
1383 ;; conditional branch.
1385 (define_expand "cmpsi"
1387 (compare:CC (match_operand:SI 0 "register_operand" "")
1388 (match_operand:SI 1 "nonmemory_operand" "")))]
1392 branch_cmp[0] = operands[0];
1393 branch_cmp[1] = operands[1];
1394 branch_type = CMP_SI;
1398 (define_expand "tstsi"
1400 (match_operand:SI 0 "register_operand" ""))]
1404 branch_cmp[0] = operands[0];
1405 branch_cmp[1] = const0_rtx;
1406 branch_type = CMP_SI;
1410 (define_expand "cmpsf"
1412 (compare:CC (match_operand:SF 0 "register_operand" "")
1413 (match_operand:SF 1 "register_operand" "")))]
1417 branch_cmp[0] = operands[0];
1418 branch_cmp[1] = operands[1];
1419 branch_type = CMP_SF;
1425 ;; ....................
1427 ;; CONDITIONAL BRANCHES
1429 ;; ....................
1432 (define_expand "beq"
1434 (if_then_else (eq (cc0) (const_int 0))
1435 (label_ref (match_operand 0 "" ""))
1440 xtensa_expand_conditional_branch (operands, EQ);
1444 (define_expand "bne"
1446 (if_then_else (ne (cc0) (const_int 0))
1447 (label_ref (match_operand 0 "" ""))
1452 xtensa_expand_conditional_branch (operands, NE);
1456 (define_expand "bgt"
1458 (if_then_else (gt (cc0) (const_int 0))
1459 (label_ref (match_operand 0 "" ""))
1464 xtensa_expand_conditional_branch (operands, GT);
1468 (define_expand "bge"
1470 (if_then_else (ge (cc0) (const_int 0))
1471 (label_ref (match_operand 0 "" ""))
1476 xtensa_expand_conditional_branch (operands, GE);
1480 (define_expand "blt"
1482 (if_then_else (lt (cc0) (const_int 0))
1483 (label_ref (match_operand 0 "" ""))
1488 xtensa_expand_conditional_branch (operands, LT);
1492 (define_expand "ble"
1494 (if_then_else (le (cc0) (const_int 0))
1495 (label_ref (match_operand 0 "" ""))
1500 xtensa_expand_conditional_branch (operands, LE);
1504 (define_expand "bgtu"
1506 (if_then_else (gtu (cc0) (const_int 0))
1507 (label_ref (match_operand 0 "" ""))
1512 xtensa_expand_conditional_branch (operands, GTU);
1516 (define_expand "bgeu"
1518 (if_then_else (geu (cc0) (const_int 0))
1519 (label_ref (match_operand 0 "" ""))
1524 xtensa_expand_conditional_branch (operands, GEU);
1528 (define_expand "bltu"
1530 (if_then_else (ltu (cc0) (const_int 0))
1531 (label_ref (match_operand 0 "" ""))
1536 xtensa_expand_conditional_branch (operands, LTU);
1540 (define_expand "bleu"
1542 (if_then_else (leu (cc0) (const_int 0))
1543 (label_ref (match_operand 0 "" ""))
1548 xtensa_expand_conditional_branch (operands, LEU);
1552 ;; Branch patterns for standard integer comparisons
1556 (if_then_else (match_operator 3 "branch_operator"
1557 [(match_operand:SI 0 "register_operand" "r,r")
1558 (match_operand:SI 1 "branch_operand" "K,r")])
1559 (label_ref (match_operand 2 "" ""))
1564 if (which_alternative == 1)
1566 switch (GET_CODE (operands[3]))
1568 case EQ: return \"beq\\t%0, %1, %2\";
1569 case NE: return \"bne\\t%0, %1, %2\";
1570 case LT: return \"blt\\t%0, %1, %2\";
1571 case GE: return \"bge\\t%0, %1, %2\";
1575 else if (INTVAL (operands[1]) == 0)
1577 switch (GET_CODE (operands[3]))
1579 case EQ: return (TARGET_DENSITY
1580 ? \"beqz.n\\t%0, %2\"
1581 : \"beqz\\t%0, %2\");
1582 case NE: return (TARGET_DENSITY
1583 ? \"bnez.n\\t%0, %2\"
1584 : \"bnez\\t%0, %2\");
1585 case LT: return \"bltz\\t%0, %2\";
1586 case GE: return \"bgez\\t%0, %2\";
1592 switch (GET_CODE (operands[3]))
1594 case EQ: return \"beqi\\t%0, %d1, %2\";
1595 case NE: return \"bnei\\t%0, %d1, %2\";
1596 case LT: return \"blti\\t%0, %d1, %2\";
1597 case GE: return \"bgei\\t%0, %d1, %2\";
1601 fatal_insn (\"unexpected branch operator\", operands[3]);
1604 [(set_attr "type" "jump,jump")
1605 (set_attr "mode" "none")
1606 (set_attr "length" "3,3")])
1610 (if_then_else (match_operator 3 "branch_operator"
1611 [(match_operand:SI 0 "register_operand" "r,r")
1612 (match_operand:SI 1 "branch_operand" "K,r")])
1614 (label_ref (match_operand 2 "" ""))))]
1618 if (which_alternative == 1)
1620 switch (GET_CODE (operands[3]))
1622 case EQ: return \"bne\\t%0, %1, %2\";
1623 case NE: return \"beq\\t%0, %1, %2\";
1624 case LT: return \"bge\\t%0, %1, %2\";
1625 case GE: return \"blt\\t%0, %1, %2\";
1629 else if (INTVAL (operands[1]) == 0)
1631 switch (GET_CODE (operands[3]))
1633 case EQ: return (TARGET_DENSITY
1634 ? \"bnez.n\\t%0, %2\"
1635 : \"bnez\\t%0, %2\");
1636 case NE: return (TARGET_DENSITY
1637 ? \"beqz.n\\t%0, %2\"
1638 : \"beqz\\t%0, %2\");
1639 case LT: return \"bgez\\t%0, %2\";
1640 case GE: return \"bltz\\t%0, %2\";
1646 switch (GET_CODE (operands[3]))
1648 case EQ: return \"bnei\\t%0, %d1, %2\";
1649 case NE: return \"beqi\\t%0, %d1, %2\";
1650 case LT: return \"bgei\\t%0, %d1, %2\";
1651 case GE: return \"blti\\t%0, %d1, %2\";
1655 fatal_insn (\"unexpected branch operator\", operands[3]);
1658 [(set_attr "type" "jump,jump")
1659 (set_attr "mode" "none")
1660 (set_attr "length" "3,3")])
1664 (if_then_else (match_operator 3 "ubranch_operator"
1665 [(match_operand:SI 0 "register_operand" "r,r")
1666 (match_operand:SI 1 "ubranch_operand" "L,r")])
1667 (label_ref (match_operand 2 "" ""))
1672 if (which_alternative == 1)
1674 switch (GET_CODE (operands[3]))
1676 case LTU: return \"bltu\\t%0, %1, %2\";
1677 case GEU: return \"bgeu\\t%0, %1, %2\";
1683 switch (GET_CODE (operands[3]))
1685 case LTU: return \"bltui\\t%0, %d1, %2\";
1686 case GEU: return \"bgeui\\t%0, %d1, %2\";
1690 fatal_insn (\"unexpected branch operator\", operands[3]);
1693 [(set_attr "type" "jump,jump")
1694 (set_attr "mode" "none")
1695 (set_attr "length" "3,3")])
1699 (if_then_else (match_operator 3 "ubranch_operator"
1700 [(match_operand:SI 0 "register_operand" "r,r")
1701 (match_operand:SI 1 "ubranch_operand" "L,r")])
1703 (label_ref (match_operand 2 "" ""))))]
1707 if (which_alternative == 1)
1709 switch (GET_CODE (operands[3]))
1711 case LTU: return \"bgeu\\t%0, %1, %2\";
1712 case GEU: return \"bltu\\t%0, %1, %2\";
1718 switch (GET_CODE (operands[3]))
1720 case LTU: return \"bgeui\\t%0, %d1, %2\";
1721 case GEU: return \"bltui\\t%0, %d1, %2\";
1725 fatal_insn (\"unexpected branch operator\", operands[3]);
1728 [(set_attr "type" "jump,jump")
1729 (set_attr "mode" "none")
1730 (set_attr "length" "3,3")])
1732 ;; Branch patterns for bit testing
1736 (if_then_else (match_operator 3 "boolean_operator"
1738 (match_operand:SI 0 "register_operand" "r,r")
1740 (match_operand:SI 1 "arith_operand" "J,r"))
1742 (label_ref (match_operand 2 "" ""))
1747 if (which_alternative == 0)
1749 unsigned bitnum = INTVAL(operands[1]) & 0x1f;
1750 operands[1] = GEN_INT(bitnum);
1751 switch (GET_CODE (operands[3]))
1753 case EQ: return \"bbci\\t%0, %d1, %2\";
1754 case NE: return \"bbsi\\t%0, %d1, %2\";
1760 switch (GET_CODE (operands[3]))
1762 case EQ: return \"bbc\\t%0, %1, %2\";
1763 case NE: return \"bbs\\t%0, %1, %2\";
1767 fatal_insn (\"unexpected branch operator\", operands[3]);
1770 [(set_attr "type" "jump")
1771 (set_attr "mode" "none")
1772 (set_attr "length" "3")])
1776 (if_then_else (match_operator 3 "boolean_operator"
1778 (match_operand:SI 0 "register_operand" "r,r")
1780 (match_operand:SI 1 "arith_operand" "J,r"))
1783 (label_ref (match_operand 2 "" ""))))]
1787 if (which_alternative == 0)
1789 unsigned bitnum = INTVAL (operands[1]) & 0x1f;
1790 operands[1] = GEN_INT (bitnum);
1791 switch (GET_CODE (operands[3]))
1793 case EQ: return \"bbsi\\t%0, %d1, %2\";
1794 case NE: return \"bbci\\t%0, %d1, %2\";
1800 switch (GET_CODE (operands[3]))
1802 case EQ: return \"bbs\\t%0, %1, %2\";
1803 case NE: return \"bbc\\t%0, %1, %2\";
1807 fatal_insn (\"unexpected branch operator\", operands[3]);
1810 [(set_attr "type" "jump")
1811 (set_attr "mode" "none")
1812 (set_attr "length" "3")])
1816 (if_then_else (match_operator 3 "boolean_operator"
1817 [(and:SI (match_operand:SI 0 "register_operand" "r")
1818 (match_operand:SI 1 "register_operand" "r"))
1820 (label_ref (match_operand 2 "" ""))
1825 switch (GET_CODE (operands[3]))
1827 case EQ: return \"bnone\\t%0, %1, %2\";
1828 case NE: return \"bany\\t%0, %1, %2\";
1831 fatal_insn (\"unexpected branch operator\", operands[3]);
1834 [(set_attr "type" "jump")
1835 (set_attr "mode" "none")
1836 (set_attr "length" "3")])
1840 (if_then_else (match_operator 3 "boolean_operator"
1841 [(and:SI (match_operand:SI 0 "register_operand" "r")
1842 (match_operand:SI 1 "register_operand" "r"))
1845 (label_ref (match_operand 2 "" ""))))]
1849 switch (GET_CODE (operands[3]))
1851 case EQ: return \"bany\\t%0, %1, %2\";
1852 case NE: return \"bnone\\t%0, %1, %2\";
1855 fatal_insn (\"unexpected branch operator\", operands[3]);
1858 [(set_attr "type" "jump")
1859 (set_attr "mode" "none")
1860 (set_attr "length" "3")])
1863 ;; Define the loop insns that is used by bct optimization to represent the
1864 ;; start and end of a zero-overhead loop (in loop.c). This start template
1865 ;; generates the loop insn, the end template doesn't generate any instructions
1866 ;; since since loop end is handled in hardware.
1868 (define_insn "zero_cost_loop_start"
1869 [(parallel [(set (pc) (if_then_else (eq (match_operand:SI 0 "register_operand" "a")
1871 (label_ref (match_operand 1 "" ""))
1874 (plus:SI (match_dup 0)
1878 [(set_attr "type" "jump")
1879 (set_attr "mode" "none")
1880 (set_attr "length" "3")])
1882 (define_insn "zero_cost_loop_end"
1883 [(parallel [(set (pc) (if_then_else (ne (reg:SI 19)
1885 (label_ref (match_operand 0 "" ""))
1888 (plus:SI (reg:SI 19)
1892 xtensa_emit_loop_end (insn, operands);
1895 [(set_attr "type" "jump")
1896 (set_attr "mode" "none")
1897 (set_attr "length" "0")])
1901 ;; ....................
1903 ;; SETTING A REGISTER FROM A COMPARISON
1905 ;; ....................
1908 (define_expand "seq"
1909 [(set (match_operand:SI 0 "register_operand" "")
1914 operands[1] = gen_rtx (EQ, SImode, branch_cmp[0], branch_cmp[1]);
1915 if (!xtensa_expand_scc (operands)) FAIL;
1919 (define_expand "sne"
1920 [(set (match_operand:SI 0 "register_operand" "")
1925 operands[1] = gen_rtx (NE, SImode, branch_cmp[0], branch_cmp[1]);
1926 if (!xtensa_expand_scc (operands)) FAIL;
1930 (define_expand "sgt"
1931 [(set (match_operand:SI 0 "register_operand" "")
1936 operands[1] = gen_rtx (GT, SImode, branch_cmp[0], branch_cmp[1]);
1937 if (!xtensa_expand_scc (operands)) FAIL;
1941 (define_expand "sge"
1942 [(set (match_operand:SI 0 "register_operand" "")
1947 operands[1] = gen_rtx (GE, SImode, branch_cmp[0], branch_cmp[1]);
1948 if (!xtensa_expand_scc (operands)) FAIL;
1952 (define_expand "slt"
1953 [(set (match_operand:SI 0 "register_operand" "")
1958 operands[1] = gen_rtx (LT, SImode, branch_cmp[0], branch_cmp[1]);
1959 if (!xtensa_expand_scc (operands)) FAIL;
1963 (define_expand "sle"
1964 [(set (match_operand:SI 0 "register_operand" "")
1969 operands[1] = gen_rtx (LE, SImode, branch_cmp[0], branch_cmp[1]);
1970 if (!xtensa_expand_scc (operands)) FAIL;
1976 ;; ....................
1978 ;; CONDITIONAL MOVES
1980 ;; ....................
1983 (define_expand "movsicc"
1984 [(set (match_operand:SI 0 "register_operand" "")
1985 (if_then_else:SI (match_operand 1 "comparison_operator" "")
1986 (match_operand:SI 2 "register_operand" "")
1987 (match_operand:SI 3 "register_operand" "")))]
1991 if (!xtensa_expand_conditional_move (operands, 0)) FAIL;
1995 (define_expand "movsfcc"
1996 [(set (match_operand:SF 0 "register_operand" "")
1997 (if_then_else:SF (match_operand 1 "comparison_operator" "")
1998 (match_operand:SF 2 "register_operand" "")
1999 (match_operand:SF 3 "register_operand" "")))]
2003 if (!xtensa_expand_conditional_move (operands, 1)) FAIL;
2007 (define_insn "movsicc_internal0"
2008 [(set (match_operand:SI 0 "register_operand" "=a,a")
2009 (if_then_else:SI (match_operator 4 "branch_operator"
2010 [(match_operand:SI 1 "register_operand" "r,r")
2012 (match_operand:SI 2 "register_operand" "r,0")
2013 (match_operand:SI 3 "register_operand" "0,r")))]
2017 if (which_alternative == 0)
2019 switch (GET_CODE (operands[4]))
2021 case EQ: return \"moveqz\\t%0, %2, %1\";
2022 case NE: return \"movnez\\t%0, %2, %1\";
2023 case LT: return \"movltz\\t%0, %2, %1\";
2024 case GE: return \"movgez\\t%0, %2, %1\";
2030 switch (GET_CODE (operands[4]))
2032 case EQ: return \"movnez\\t%0, %3, %1\";
2033 case NE: return \"moveqz\\t%0, %3, %1\";
2034 case LT: return \"movgez\\t%0, %3, %1\";
2035 case GE: return \"movltz\\t%0, %3, %1\";
2039 fatal_insn (\"unexpected cmov operator\", operands[4]);
2042 [(set_attr "type" "move,move")
2043 (set_attr "mode" "SI")
2044 (set_attr "length" "3,3")])
2046 (define_insn "movsicc_internal1"
2047 [(set (match_operand:SI 0 "register_operand" "=a,a")
2048 (if_then_else:SI (match_operator 4 "boolean_operator"
2049 [(match_operand:CC 1 "register_operand" "b,b")
2051 (match_operand:SI 2 "register_operand" "r,0")
2052 (match_operand:SI 3 "register_operand" "0,r")))]
2056 int isEq = (GET_CODE (operands[4]) == EQ);
2057 switch (which_alternative)
2060 if (isEq) return \"movf\\t%0, %2, %1\";
2061 return \"movt\\t%0, %2, %1\";
2063 if (isEq) return \"movt\\t%0, %3, %1\";
2064 return \"movf\\t%0, %3, %1\";
2069 [(set_attr "type" "move,move")
2070 (set_attr "mode" "SI")
2071 (set_attr "length" "3,3")])
2073 (define_insn "movsfcc_internal0"
2074 [(set (match_operand:SF 0 "register_operand" "=a,a,f,f")
2075 (if_then_else:SF (match_operator 4 "branch_operator"
2076 [(match_operand:SI 1 "register_operand" "r,r,r,r")
2078 (match_operand:SF 2 "register_operand" "r,0,f,0")
2079 (match_operand:SF 3 "register_operand" "0,r,0,f")))]
2083 if (which_alternative == 0)
2085 switch (GET_CODE (operands[4]))
2087 case EQ: return \"moveqz\\t%0, %2, %1\";
2088 case NE: return \"movnez\\t%0, %2, %1\";
2089 case LT: return \"movltz\\t%0, %2, %1\";
2090 case GE: return \"movgez\\t%0, %2, %1\";
2094 else if (which_alternative == 1)
2096 switch (GET_CODE (operands[4]))
2098 case EQ: return \"movnez\\t%0, %3, %1\";
2099 case NE: return \"moveqz\\t%0, %3, %1\";
2100 case LT: return \"movgez\\t%0, %3, %1\";
2101 case GE: return \"movltz\\t%0, %3, %1\";
2105 else if (which_alternative == 2)
2107 switch (GET_CODE (operands[4]))
2109 case EQ: return \"moveqz.s %0, %2, %1\";
2110 case NE: return \"movnez.s %0, %2, %1\";
2111 case LT: return \"movltz.s %0, %2, %1\";
2112 case GE: return \"movgez.s %0, %2, %1\";
2116 else if (which_alternative == 3)
2118 switch (GET_CODE (operands[4]))
2120 case EQ: return \"movnez.s %0, %3, %1\";
2121 case NE: return \"moveqz.s %0, %3, %1\";
2122 case LT: return \"movgez.s %0, %3, %1\";
2123 case GE: return \"movltz.s %0, %3, %1\";
2127 fatal_insn (\"unexpected cmov operator\", operands[4]);
2130 [(set_attr "type" "move,move,move,move")
2131 (set_attr "mode" "SF")
2132 (set_attr "length" "3,3,3,3")])
2134 (define_insn "movsfcc_internal1"
2135 [(set (match_operand:SF 0 "register_operand" "=a,a,f,f")
2136 (if_then_else:SF (match_operator 4 "boolean_operator"
2137 [(match_operand:CC 1 "register_operand" "b,b,b,b")
2139 (match_operand:SF 2 "register_operand" "r,0,f,0")
2140 (match_operand:SF 3 "register_operand" "0,r,0,f")))]
2144 int isEq = (GET_CODE (operands[4]) == EQ);
2145 switch (which_alternative)
2148 if (isEq) return \"movf\\t%0, %2, %1\";
2149 return \"movt\\t%0, %2, %1\";
2151 if (isEq) return \"movt\\t%0, %3, %1\";
2152 return \"movf\\t%0, %3, %1\";
2154 if (isEq) return \"movf.s\\t%0, %2, %1\";
2155 return \"movt.s\\t%0, %2, %1\";
2157 if (isEq) return \"movt.s\\t%0, %3, %1\";
2158 return \"movf.s\\t%0, %3, %1\";
2163 [(set_attr "type" "move,move,move,move")
2164 (set_attr "mode" "SF")
2165 (set_attr "length" "3,3,3,3")])
2169 ;; ....................
2171 ;; FLOATING POINT COMPARISONS
2173 ;; ....................
2176 (define_insn "seq_sf"
2177 [(set (match_operand:CC 0 "register_operand" "=b")
2178 (eq:CC (match_operand:SF 1 "register_operand" "f")
2179 (match_operand:SF 2 "register_operand" "f")))]
2181 "oeq.s\\t%0, %1, %2"
2182 [(set_attr "type" "farith")
2183 (set_attr "mode" "BL")
2184 (set_attr "length" "3")])
2186 (define_insn "slt_sf"
2187 [(set (match_operand:CC 0 "register_operand" "=b")
2188 (lt:CC (match_operand:SF 1 "register_operand" "f")
2189 (match_operand:SF 2 "register_operand" "f")))]
2191 "olt.s\\t%0, %1, %2"
2192 [(set_attr "type" "farith")
2193 (set_attr "mode" "BL")
2194 (set_attr "length" "3")])
2196 (define_insn "sle_sf"
2197 [(set (match_operand:CC 0 "register_operand" "=b")
2198 (le:CC (match_operand:SF 1 "register_operand" "f")
2199 (match_operand:SF 2 "register_operand" "f")))]
2201 "ole.s\\t%0, %1, %2"
2202 [(set_attr "type" "farith")
2203 (set_attr "mode" "BL")
2204 (set_attr "length" "3")])
2208 ;; ....................
2210 ;; UNCONDITIONAL BRANCHES
2212 ;; ....................
2217 (label_ref (match_operand 0 "" "")))]
2220 [(set_attr "type" "jump")
2221 (set_attr "mode" "none")
2222 (set_attr "length" "3")])
2224 (define_expand "indirect_jump"
2225 [(set (pc) (match_operand 0 "register_operand" ""))]
2229 rtx dest = operands[0];
2230 if (GET_CODE (dest) != REG || GET_MODE (dest) != Pmode)
2231 operands[0] = copy_to_mode_reg (Pmode, dest);
2233 emit_jump_insn (gen_indirect_jump_internal (dest));
2237 (define_insn "indirect_jump_internal"
2238 [(set (pc) (match_operand:SI 0 "register_operand" "r"))]
2241 [(set_attr "type" "jump")
2242 (set_attr "mode" "none")
2243 (set_attr "length" "3")])
2246 (define_expand "tablejump"
2247 [(use (match_operand:SI 0 "register_operand" ""))
2248 (use (label_ref (match_operand 1 "" "")))]
2252 rtx target = operands[0];
2255 /* For PIC, the table entry is relative to the start of the table. */
2256 rtx label = gen_reg_rtx (SImode);
2257 target = gen_reg_rtx (SImode);
2258 emit_move_insn (label, gen_rtx_LABEL_REF (SImode, operands[1]));
2259 emit_insn (gen_addsi3 (target, operands[0], label));
2261 emit_jump_insn (gen_tablejump_internal (target, operands[1]));
2265 (define_insn "tablejump_internal"
2267 (match_operand:SI 0 "register_operand" "r"))
2268 (use (label_ref (match_operand 1 "" "")))]
2271 [(set_attr "type" "jump")
2272 (set_attr "mode" "none")
2273 (set_attr "length" "3")])
2277 ;; ....................
2281 ;; ....................
2284 (define_expand "sym_PLT"
2285 [(const (unspec [(match_operand:SI 0 "" "")] UNSPEC_PLT))]
2289 (define_expand "call"
2290 [(call (match_operand 0 "memory_operand" "")
2291 (match_operand 1 "" ""))]
2295 rtx addr = XEXP (operands[0], 0);
2296 if (flag_pic && GET_CODE (addr) == SYMBOL_REF && !SYMBOL_REF_FLAG (addr))
2297 addr = gen_sym_PLT (addr);
2298 if (!call_insn_operand (addr, VOIDmode))
2299 XEXP (operands[0], 0) = copy_to_mode_reg (Pmode, addr);
2302 (define_insn "call_internal"
2303 [(call (mem (match_operand:SI 0 "call_insn_operand" "n,i,r"))
2304 (match_operand 1 "" "i,i,i"))]
2307 return xtensa_emit_call (0, operands);
2309 [(set_attr "type" "call")
2310 (set_attr "mode" "none")
2311 (set_attr "length" "3")])
2313 (define_expand "call_value"
2314 [(set (match_operand 0 "register_operand" "")
2315 (call (match_operand 1 "memory_operand" "")
2316 (match_operand 2 "" "")))]
2320 rtx addr = XEXP (operands[1], 0);
2321 if (flag_pic && GET_CODE (addr) == SYMBOL_REF && !SYMBOL_REF_FLAG (addr))
2322 addr = gen_sym_PLT (addr);
2323 if (!call_insn_operand (addr, VOIDmode))
2324 XEXP (operands[1], 0) = copy_to_mode_reg (Pmode, addr);
2327 ;; cannot combine constraints for operand 0 into "afvb"
2328 ;; reload.c:find_reloads seems to assume that grouped constraints somehow
2329 ;; specify related register classes, and when they don't the constraints
2330 ;; fail to match. By not grouping the constraints, we get the correct
2332 (define_insn "call_value_internal"
2333 [(set (match_operand 0 "register_operand" "=af,af,af,v,v,v,b,b,b")
2334 (call (mem (match_operand:SI 1 "call_insn_operand"
2335 "n,i,r,n,i,r,n,i,r"))
2336 (match_operand 2 "" "i,i,i,i,i,i,i,i,i")))]
2339 return xtensa_emit_call (1, operands);
2341 [(set_attr "type" "call")
2342 (set_attr "mode" "none")
2343 (set_attr "length" "3")])
2345 (define_insn "return"
2347 (use (reg:SI A0_REG))]
2351 return (TARGET_DENSITY ? \"retw.n\" : \"retw\");
2353 [(set_attr "type" "jump")
2354 (set_attr "mode" "none")
2355 (set_attr "length" "2")])
2359 ;; ....................
2363 ;; ....................
2371 return (TARGET_DENSITY ? \"nop.n\" : \"nop\");
2373 [(set_attr "type" "nop")
2374 (set_attr "mode" "none")
2375 (set_attr "length" "3")])
2377 (define_expand "nonlocal_goto"
2378 [(match_operand:SI 0 "general_operand" "")
2379 (match_operand:SI 1 "general_operand" "")
2380 (match_operand:SI 2 "general_operand" "")
2381 (match_operand:SI 3 "" "")]
2385 xtensa_expand_nonlocal_goto (operands);
2389 ;; Setting up a frame pointer is tricky for Xtensa because GCC doesn't
2390 ;; know if a frame pointer is required until the reload pass, and
2391 ;; because there may be an incoming argument value in the hard frame
2392 ;; pointer register (a7). If there is an incoming argument in that
2393 ;; register, the "set_frame_ptr" insn gets inserted immediately after
2394 ;; the insn that copies the incoming argument to a pseudo or to the
2395 ;; stack. This serves several purposes here: (1) it keeps the
2396 ;; optimizer from copy-propagating or scheduling the use of a7 as an
2397 ;; incoming argument away from the beginning of the function; (2) we
2398 ;; can use a post-reload splitter to expand away the insn if a frame
2399 ;; pointer is not required, so that the post-reload scheduler can do
2400 ;; the right thing; and (3) it makes it easy for xtensa_reorg() to
2401 ;; search for this insn to determine whether it should add a new insn
2402 ;; to set up the frame pointer.
2404 (define_insn "set_frame_ptr"
2405 [(unspec_volatile [(const_int 0)] UNSPECV_SET_FP)]
2409 if (frame_pointer_needed)
2410 return \"mov\\ta7, sp\";
2413 [(set_attr "type" "move")
2414 (set_attr "mode" "SI")
2415 (set_attr "length" "3")])
2417 ;; Post-reload splitter to remove fp assignment when it's not needed.
2419 [(unspec_volatile [(const_int 0)] UNSPECV_SET_FP)]
2420 "reload_completed && !frame_pointer_needed"
2421 [(unspec [(const_int 0)] UNSPEC_NOP)]
2424 ;; The preceding splitter needs something to split the insn into;
2425 ;; things start breaking if the result is just a "use" so instead we
2426 ;; generate the following insn.
2428 [(unspec [(const_int 0)] UNSPEC_NOP)]
2431 [(set_attr "type" "nop")
2432 (set_attr "mode" "none")
2433 (set_attr "length" "0")])
2436 ;; ....................
2440 ;; ....................
2447 (if_then_else (match_operator 2 "boolean_operator"
2448 [(match_operand:CC 0 "register_operand" "b")
2450 (label_ref (match_operand 1 "" ""))
2455 if (GET_CODE (operands[2]) == EQ)
2456 return \"bf\\t%0, %1\";
2458 return \"bt\\t%0, %1\";
2460 [(set_attr "type" "jump")
2461 (set_attr "mode" "none")
2462 (set_attr "length" "3")])
2466 (if_then_else (match_operator 2 "boolean_operator"
2467 [(match_operand:CC 0 "register_operand" "b")
2470 (label_ref (match_operand 1 "" ""))))]
2474 if (GET_CODE (operands[2]) == EQ)
2475 return \"bt\\t%0, %1\";
2477 return \"bf\\t%0, %1\";
2479 [(set_attr "type" "jump")
2480 (set_attr "mode" "none")
2481 (set_attr "length" "3")])