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 ;; ....................
42 ;; ....................
46 ;; ....................
50 "unknown,jump,call,load,store,move,arith,multi,nop,farith,fmadd,fdiv,fsqrt,fconv,fload,fstore,mul16,mul32,div32,mac16,rsr,wsr"
51 (const_string "unknown"))
54 "unknown,none,QI,HI,SI,DI,SF,DF,BL"
55 (const_string "unknown"))
57 (define_attr "length" "" (const_int 1))
59 ;; Describe a user's asm statement.
60 (define_asm_attributes
61 [(set_attr "type" "multi")])
65 ;; ....................
69 ;; ....................
72 (define_function_unit "memory" 1 0 (eq_attr "type" "load,fload") 2 0)
74 (define_function_unit "sreg" 1 1 (eq_attr "type" "rsr") 2 0)
76 (define_function_unit "mul16" 1 0 (eq_attr "type" "mul16") 2 0)
78 (define_function_unit "mul32" 1 0 (eq_attr "type" "mul32") 2 0)
80 (define_function_unit "fpmadd" 1 0 (eq_attr "type" "fmadd") 4 0)
82 (define_function_unit "fpconv" 1 0 (eq_attr "type" "fconv") 2 0)
86 ;; ....................
90 ;; ....................
93 (define_expand "adddi3"
94 [(set (match_operand:DI 0 "register_operand" "")
95 (plus:DI (match_operand:DI 1 "register_operand" "")
96 (match_operand:DI 2 "register_operand" "")))]
100 rtx dstlo = gen_lowpart (SImode, operands[0]);
101 rtx src1lo = gen_lowpart (SImode, operands[1]);
102 rtx src2lo = gen_lowpart (SImode, operands[2]);
104 rtx dsthi = gen_highpart (SImode, operands[0]);
105 rtx src1hi = gen_highpart (SImode, operands[1]);
106 rtx src2hi = gen_highpart (SImode, operands[2]);
108 emit_insn (gen_addsi3 (dstlo, src1lo, src2lo));
109 emit_insn (gen_addsi3 (dsthi, src1hi, src2hi));
110 emit_insn (gen_adddi_carry (dsthi, dstlo, src2lo));
114 ;; Represent the add-carry operation as an atomic operation instead of
115 ;; expanding it to a conditional branch. Otherwise, the edge
116 ;; profiling code breaks because inserting the count increment code
117 ;; causes a new jump insn to be added.
119 (define_insn "adddi_carry"
120 [(set (match_operand:SI 0 "register_operand" "+a")
121 (plus:SI (ltu:SI (match_operand:SI 1 "register_operand" "r")
122 (match_operand:SI 2 "register_operand" "r"))
125 "bgeu\\t%1, %2, 0f\;addi\\t%0, %0, 1\;0:"
126 [(set_attr "type" "multi")
127 (set_attr "mode" "SI")
128 (set_attr "length" "6")])
130 (define_insn "addsi3"
131 [(set (match_operand:SI 0 "register_operand" "=D,D,a,a,a")
132 (plus:SI (match_operand:SI 1 "register_operand" "%d,d,r,r,r")
133 (match_operand:SI 2 "add_operand" "d,O,r,J,N")))]
141 [(set_attr "type" "arith,arith,arith,arith,arith")
142 (set_attr "mode" "SI")
143 (set_attr "length" "2,2,3,3,3")])
146 [(set (match_operand:SI 0 "register_operand" "=a")
147 (plus:SI (mult:SI (match_operand:SI 1 "register_operand" "r")
149 (match_operand:SI 2 "register_operand" "r")))]
152 [(set_attr "type" "arith")
153 (set_attr "mode" "SI")
154 (set_attr "length" "3")])
157 [(set (match_operand:SI 0 "register_operand" "=a")
158 (plus:SI (mult:SI (match_operand:SI 1 "register_operand" "r")
160 (match_operand:SI 2 "register_operand" "r")))]
163 [(set_attr "type" "arith")
164 (set_attr "mode" "SI")
165 (set_attr "length" "3")])
168 [(set (match_operand:SI 0 "register_operand" "=a")
169 (plus:SI (mult:SI (match_operand:SI 1 "register_operand" "r")
171 (match_operand:SI 2 "register_operand" "r")))]
174 [(set_attr "type" "arith")
175 (set_attr "mode" "SI")
176 (set_attr "length" "3")])
178 (define_insn "addsf3"
179 [(set (match_operand:SF 0 "register_operand" "=f")
180 (plus:SF (match_operand:SF 1 "register_operand" "%f")
181 (match_operand:SF 2 "register_operand" "f")))]
184 [(set_attr "type" "fmadd")
185 (set_attr "mode" "SF")
186 (set_attr "length" "3")])
190 ;; ....................
194 ;; ....................
197 (define_expand "subdi3"
198 [(set (match_operand:DI 0 "register_operand" "")
199 (minus:DI (match_operand:DI 1 "register_operand" "")
200 (match_operand:DI 2 "register_operand" "")))]
204 rtx dstlo = gen_lowpart (SImode, operands[0]);
205 rtx src1lo = gen_lowpart (SImode, operands[1]);
206 rtx src2lo = gen_lowpart (SImode, operands[2]);
208 rtx dsthi = gen_highpart (SImode, operands[0]);
209 rtx src1hi = gen_highpart (SImode, operands[1]);
210 rtx src2hi = gen_highpart (SImode, operands[2]);
212 emit_insn (gen_subsi3 (dstlo, src1lo, src2lo));
213 emit_insn (gen_subsi3 (dsthi, src1hi, src2hi));
214 emit_insn (gen_subdi_carry (dsthi, src1lo, src2lo));
218 (define_insn "subdi_carry"
219 [(set (match_operand:SI 0 "register_operand" "+a")
220 (minus:SI (match_dup 0)
221 (ltu:SI (match_operand:SI 1 "register_operand" "r")
222 (match_operand:SI 2 "register_operand" "r"))))]
224 "bgeu\\t%1, %2, 0f\;addi\\t%0, %0, -1\;0:"
225 [(set_attr "type" "multi")
226 (set_attr "mode" "SI")
227 (set_attr "length" "6")])
229 (define_insn "subsi3"
230 [(set (match_operand:SI 0 "register_operand" "=a")
231 (minus:SI (match_operand:SI 1 "register_operand" "r")
232 (match_operand:SI 2 "register_operand" "r")))]
235 [(set_attr "type" "arith")
236 (set_attr "mode" "SI")
237 (set_attr "length" "3")])
240 [(set (match_operand:SI 0 "register_operand" "=a")
241 (minus:SI (mult:SI (match_operand:SI 1 "register_operand" "r")
243 (match_operand:SI 2 "register_operand" "r")))]
246 [(set_attr "type" "arith")
247 (set_attr "mode" "SI")
248 (set_attr "length" "3")])
251 [(set (match_operand:SI 0 "register_operand" "=a")
252 (minus:SI (mult:SI (match_operand:SI 1 "register_operand" "r")
254 (match_operand:SI 2 "register_operand" "r")))]
257 [(set_attr "type" "arith")
258 (set_attr "mode" "SI")
259 (set_attr "length" "3")])
262 [(set (match_operand:SI 0 "register_operand" "=a")
263 (minus:SI (mult:SI (match_operand:SI 1 "register_operand" "r")
265 (match_operand:SI 2 "register_operand" "r")))]
268 [(set_attr "type" "arith")
269 (set_attr "mode" "SI")
270 (set_attr "length" "3")])
272 (define_insn "subsf3"
273 [(set (match_operand:SF 0 "register_operand" "=f")
274 (minus:SF (match_operand:SF 1 "register_operand" "f")
275 (match_operand:SF 2 "register_operand" "f")))]
278 [(set_attr "type" "fmadd")
279 (set_attr "mode" "SF")
280 (set_attr "length" "3")])
284 ;; ....................
288 ;; ....................
291 (define_insn "mulsi3"
292 [(set (match_operand:SI 0 "register_operand" "=a")
293 (mult:SI (match_operand:SI 1 "register_operand" "%r")
294 (match_operand:SI 2 "register_operand" "r")))]
297 [(set_attr "type" "mul32")
298 (set_attr "mode" "SI")
299 (set_attr "length" "3")])
301 (define_insn "mulhisi3"
302 [(set (match_operand:SI 0 "register_operand" "=C,A")
303 (mult:SI (sign_extend:SI
304 (match_operand:HI 1 "register_operand" "%r,r"))
306 (match_operand:HI 2 "register_operand" "r,r"))))]
307 "TARGET_MUL16 || TARGET_MAC16"
311 [(set_attr "type" "mul16,mac16")
312 (set_attr "mode" "SI")
313 (set_attr "length" "3,3")])
315 (define_insn "umulhisi3"
316 [(set (match_operand:SI 0 "register_operand" "=C,A")
317 (mult:SI (zero_extend:SI
318 (match_operand:HI 1 "register_operand" "%r,r"))
320 (match_operand:HI 2 "register_operand" "r,r"))))]
321 "TARGET_MUL16 || TARGET_MAC16"
325 [(set_attr "type" "mul16,mac16")
326 (set_attr "mode" "SI")
327 (set_attr "length" "3,3")])
329 (define_insn "muladdhisi"
330 [(set (match_operand:SI 0 "register_operand" "=A")
331 (plus:SI (mult:SI (sign_extend:SI
332 (match_operand:HI 1 "register_operand" "%r"))
334 (match_operand:HI 2 "register_operand" "r")))
335 (match_operand:SI 3 "register_operand" "0")))]
337 "mula.aa.ll\\t%1, %2"
338 [(set_attr "type" "mac16")
339 (set_attr "mode" "SI")
340 (set_attr "length" "3")])
342 (define_insn "mulsubhisi"
343 [(set (match_operand:SI 0 "register_operand" "=A")
344 (minus:SI (match_operand:SI 1 "register_operand" "0")
345 (mult:SI (sign_extend:SI
346 (match_operand:HI 2 "register_operand" "%r"))
348 (match_operand:HI 3 "register_operand" "r")))))]
350 "muls.aa.ll\\t%2, %3"
351 [(set_attr "type" "mac16")
352 (set_attr "mode" "SI")
353 (set_attr "length" "3")])
355 (define_insn "mulsf3"
356 [(set (match_operand:SF 0 "register_operand" "=f")
357 (mult:SF (match_operand:SF 1 "register_operand" "%f")
358 (match_operand:SF 2 "register_operand" "f")))]
361 [(set_attr "type" "fmadd")
362 (set_attr "mode" "SF")
363 (set_attr "length" "3")])
365 (define_insn "muladdsf3"
366 [(set (match_operand:SF 0 "register_operand" "=f")
367 (plus:SF (mult:SF (match_operand:SF 1 "register_operand" "%f")
368 (match_operand:SF 2 "register_operand" "f"))
369 (match_operand:SF 3 "register_operand" "0")))]
370 "TARGET_HARD_FLOAT && !TARGET_NO_FUSED_MADD"
371 "madd.s\\t%0, %1, %2"
372 [(set_attr "type" "fmadd")
373 (set_attr "mode" "SF")
374 (set_attr "length" "3")])
376 (define_insn "mulsubsf3"
377 [(set (match_operand:SF 0 "register_operand" "=f")
378 (minus:SF (match_operand:SF 1 "register_operand" "0")
379 (mult:SF (match_operand:SF 2 "register_operand" "%f")
380 (match_operand:SF 3 "register_operand" "f"))))]
381 "TARGET_HARD_FLOAT && !TARGET_NO_FUSED_MADD"
382 "msub.s\\t%0, %2, %3"
383 [(set_attr "type" "fmadd")
384 (set_attr "mode" "SF")
385 (set_attr "length" "3")])
389 ;; ....................
393 ;; ....................
396 (define_insn "divsi3"
397 [(set (match_operand:SI 0 "register_operand" "=a")
398 (div:SI (match_operand:SI 1 "register_operand" "r")
399 (match_operand:SI 2 "register_operand" "r")))]
402 [(set_attr "type" "div32")
403 (set_attr "mode" "SI")
404 (set_attr "length" "3")])
406 (define_insn "udivsi3"
407 [(set (match_operand:SI 0 "register_operand" "=a")
408 (udiv:SI (match_operand:SI 1 "register_operand" "r")
409 (match_operand:SI 2 "register_operand" "r")))]
412 [(set_attr "type" "div32")
413 (set_attr "mode" "SI")
414 (set_attr "length" "3")])
416 (define_insn "divsf3"
417 [(set (match_operand:SF 0 "register_operand" "=f")
418 (div:SF (match_operand:SF 1 "register_operand" "f")
419 (match_operand:SF 2 "register_operand" "f")))]
420 "TARGET_HARD_FLOAT_DIV"
422 [(set_attr "type" "fdiv")
423 (set_attr "mode" "SF")
424 (set_attr "length" "3")])
427 [(set (match_operand:SF 0 "register_operand" "=f")
428 (div:SF (match_operand:SF 1 "const_float_1_operand" "")
429 (match_operand:SF 2 "register_operand" "f")))]
430 "TARGET_HARD_FLOAT_RECIP && flag_unsafe_math_optimizations"
432 [(set_attr "type" "fdiv")
433 (set_attr "mode" "SF")
434 (set_attr "length" "3")])
438 ;; ....................
442 ;; ....................
445 (define_insn "modsi3"
446 [(set (match_operand:SI 0 "register_operand" "=a")
447 (mod:SI (match_operand:SI 1 "register_operand" "r")
448 (match_operand:SI 2 "register_operand" "r")))]
451 [(set_attr "type" "div32")
452 (set_attr "mode" "SI")
453 (set_attr "length" "3")])
455 (define_insn "umodsi3"
456 [(set (match_operand:SI 0 "register_operand" "=a")
457 (umod:SI (match_operand:SI 1 "register_operand" "r")
458 (match_operand:SI 2 "register_operand" "r")))]
461 [(set_attr "type" "div32")
462 (set_attr "mode" "SI")
463 (set_attr "length" "3")])
467 ;; ....................
471 ;; ....................
474 (define_insn "sqrtsf2"
475 [(set (match_operand:SF 0 "register_operand" "=f")
476 (sqrt:SF (match_operand:SF 1 "register_operand" "f")))]
477 "TARGET_HARD_FLOAT_SQRT"
479 [(set_attr "type" "fsqrt")
480 (set_attr "mode" "SF")
481 (set_attr "length" "3")])
484 [(set (match_operand:SF 0 "register_operand" "=f")
485 (div:SF (match_operand:SF 1 "const_float_1_operand" "")
486 (sqrt:SF (match_operand:SF 2 "register_operand" "f"))))]
487 "TARGET_HARD_FLOAT_RSQRT && flag_unsafe_math_optimizations"
489 [(set_attr "type" "fsqrt")
490 (set_attr "mode" "SF")
491 (set_attr "length" "3")])
495 ;; ....................
499 ;; ....................
502 (define_insn "abssi2"
503 [(set (match_operand:SI 0 "register_operand" "=a")
504 (abs:SI (match_operand:SI 1 "register_operand" "r")))]
507 [(set_attr "type" "arith")
508 (set_attr "mode" "SI")
509 (set_attr "length" "3")])
511 (define_insn "abssf2"
512 [(set (match_operand:SF 0 "register_operand" "=f")
513 (abs:SF (match_operand:SF 1 "register_operand" "f")))]
516 [(set_attr "type" "farith")
517 (set_attr "mode" "SF")
518 (set_attr "length" "3")])
522 ;; ....................
524 ;; MIN AND MAX INSTRUCTIONS
526 ;; ....................
529 (define_insn "sminsi3"
530 [(set (match_operand:SI 0 "register_operand" "=a")
531 (smin:SI (match_operand:SI 1 "register_operand" "%r")
532 (match_operand:SI 2 "register_operand" "r")))]
535 [(set_attr "type" "arith")
536 (set_attr "mode" "SI")
537 (set_attr "length" "3")])
539 (define_insn "uminsi3"
540 [(set (match_operand:SI 0 "register_operand" "=a")
541 (umin:SI (match_operand:SI 1 "register_operand" "%r")
542 (match_operand:SI 2 "register_operand" "r")))]
545 [(set_attr "type" "arith")
546 (set_attr "mode" "SI")
547 (set_attr "length" "3")])
549 (define_insn "smaxsi3"
550 [(set (match_operand:SI 0 "register_operand" "=a")
551 (smax:SI (match_operand:SI 1 "register_operand" "%r")
552 (match_operand:SI 2 "register_operand" "r")))]
555 [(set_attr "type" "arith")
556 (set_attr "mode" "SI")
557 (set_attr "length" "3")])
559 (define_insn "umaxsi3"
560 [(set (match_operand:SI 0 "register_operand" "=a")
561 (umax:SI (match_operand:SI 1 "register_operand" "%r")
562 (match_operand:SI 2 "register_operand" "r")))]
565 [(set_attr "type" "arith")
566 (set_attr "mode" "SI")
567 (set_attr "length" "3")])
571 ;; ....................
573 ;; FIND FIRST BIT INSTRUCTION
575 ;; ....................
578 (define_expand "ffssi2"
579 [(set (match_operand:SI 0 "register_operand" "")
580 (ffs:SI (match_operand:SI 1 "register_operand" "")))]
584 rtx temp = gen_reg_rtx (SImode);
585 emit_insn (gen_negsi2 (temp, operands[1]));
586 emit_insn (gen_andsi3 (temp, temp, operands[1]));
587 emit_insn (gen_nsau (temp, temp));
588 emit_insn (gen_negsi2 (temp, temp));
589 emit_insn (gen_addsi3 (operands[0], temp, GEN_INT (32)));
593 ;; there is no RTL operator corresponding to NSAU
595 [(set (match_operand:SI 0 "register_operand" "=a")
596 (unspec:SI [(match_operand:SI 1 "register_operand" "r")] UNSPEC_NSAU))]
599 [(set_attr "type" "arith")
600 (set_attr "mode" "SI")
601 (set_attr "length" "3")])
605 ;; ....................
607 ;; NEGATION and ONE'S COMPLEMENT
609 ;; ....................
612 (define_insn "negsi2"
613 [(set (match_operand:SI 0 "register_operand" "=a")
614 (neg:SI (match_operand:SI 1 "register_operand" "r")))]
617 [(set_attr "type" "arith")
618 (set_attr "mode" "SI")
619 (set_attr "length" "3")])
621 (define_expand "one_cmplsi2"
622 [(set (match_operand:SI 0 "register_operand" "")
623 (not:SI (match_operand:SI 1 "register_operand" "")))]
627 rtx temp = gen_reg_rtx (SImode);
628 emit_insn (gen_movsi (temp, constm1_rtx));
629 emit_insn (gen_xorsi3 (operands[0], temp, operands[1]));
633 (define_insn "negsf2"
634 [(set (match_operand:SF 0 "register_operand" "=f")
635 (neg:SF (match_operand:SF 1 "register_operand" "f")))]
638 [(set_attr "type" "farith")
639 (set_attr "mode" "SF")
640 (set_attr "length" "3")])
644 ;; ....................
648 ;; ....................
651 (define_insn "andsi3"
652 [(set (match_operand:SI 0 "register_operand" "=a,a")
653 (and:SI (match_operand:SI 1 "register_operand" "%r,r")
654 (match_operand:SI 2 "mask_operand" "P,r")))]
657 extui\\t%0, %1, 0, %K2
659 [(set_attr "type" "arith,arith")
660 (set_attr "mode" "SI")
661 (set_attr "length" "3,3")])
663 (define_insn "iorsi3"
664 [(set (match_operand:SI 0 "register_operand" "=a")
665 (ior:SI (match_operand:SI 1 "register_operand" "%r")
666 (match_operand:SI 2 "register_operand" "r")))]
669 [(set_attr "type" "arith")
670 (set_attr "mode" "SI")
671 (set_attr "length" "3")])
673 (define_insn "xorsi3"
674 [(set (match_operand:SI 0 "register_operand" "=a")
675 (xor:SI (match_operand:SI 1 "register_operand" "%r")
676 (match_operand:SI 2 "register_operand" "r")))]
679 [(set_attr "type" "arith")
680 (set_attr "mode" "SI")
681 (set_attr "length" "3")])
685 ;; ....................
689 ;; ....................
692 (define_insn "zero_extendhisi2"
693 [(set (match_operand:SI 0 "register_operand" "=a,a")
694 (zero_extend:SI (match_operand:HI 1 "nonimmed_operand" "r,U")))]
697 extui\\t%0, %1, 0, 16
699 [(set_attr "type" "arith,load")
700 (set_attr "mode" "SI")
701 (set_attr "length" "3,3")])
703 (define_insn "zero_extendqisi2"
704 [(set (match_operand:SI 0 "register_operand" "=a,a")
705 (zero_extend:SI (match_operand:QI 1 "nonimmed_operand" "r,U")))]
710 [(set_attr "type" "arith,load")
711 (set_attr "mode" "SI")
712 (set_attr "length" "3,3")])
716 ;; ....................
720 ;; ....................
723 (define_expand "extendhisi2"
724 [(set (match_operand:SI 0 "register_operand" "")
725 (sign_extend:SI (match_operand:HI 1 "register_operand" "")))]
729 if (sext_operand (operands[1], HImode))
730 emit_insn (gen_extendhisi2_internal (operands[0], operands[1]));
732 xtensa_extend_reg (operands[0], operands[1]);
736 (define_insn "extendhisi2_internal"
737 [(set (match_operand:SI 0 "register_operand" "=B,a")
738 (sign_extend:SI (match_operand:HI 1 "sext_operand" "r,U")))]
743 [(set_attr "type" "arith,load")
744 (set_attr "mode" "SI")
745 (set_attr "length" "3,3")])
747 (define_expand "extendqisi2"
748 [(set (match_operand:SI 0 "register_operand" "")
749 (sign_extend:SI (match_operand:QI 1 "register_operand" "")))]
755 emit_insn (gen_extendqisi2_internal (operands[0], operands[1]));
758 xtensa_extend_reg (operands[0], operands[1]);
762 (define_insn "extendqisi2_internal"
763 [(set (match_operand:SI 0 "register_operand" "=B")
764 (sign_extend:SI (match_operand:QI 1 "register_operand" "r")))]
767 [(set_attr "type" "arith")
768 (set_attr "mode" "SI")
769 (set_attr "length" "3")])
773 ;; ....................
777 ;; ....................
780 (define_expand "extv"
781 [(set (match_operand:SI 0 "register_operand" "")
782 (sign_extract:SI (match_operand:SI 1 "register_operand" "")
783 (match_operand:SI 2 "const_int_operand" "")
784 (match_operand:SI 3 "const_int_operand" "")))]
788 if (!sext_fldsz_operand (operands[2], SImode)) FAIL;
789 /* we could expand to a right shift followed by sext but that's
790 no better than the standard left and right shift sequence */
791 if (!lsbitnum_operand (operands[3], SImode)) FAIL;
792 emit_insn (gen_extv_internal (operands[0], operands[1],
793 operands[2], operands[3]));
797 (define_insn "extv_internal"
798 [(set (match_operand:SI 0 "register_operand" "=a")
799 (sign_extract:SI (match_operand:SI 1 "register_operand" "r")
800 (match_operand:SI 2 "sext_fldsz_operand" "i")
801 (match_operand:SI 3 "lsbitnum_operand" "i")))]
805 int fldsz = INTVAL (operands[2]);
806 operands[2] = GEN_INT (fldsz - 1);
807 return \"sext\\t%0, %1, %2\";
809 [(set_attr "type" "arith")
810 (set_attr "mode" "SI")
811 (set_attr "length" "3")])
813 (define_expand "extzv"
814 [(set (match_operand:SI 0 "register_operand" "")
815 (zero_extract:SI (match_operand:SI 1 "register_operand" "")
816 (match_operand:SI 2 "const_int_operand" "")
817 (match_operand:SI 3 "const_int_operand" "")))]
821 if (!extui_fldsz_operand (operands[2], SImode)) FAIL;
822 emit_insn (gen_extzv_internal (operands[0], operands[1],
823 operands[2], operands[3]));
827 (define_insn "extzv_internal"
828 [(set (match_operand:SI 0 "register_operand" "=a")
829 (zero_extract:SI (match_operand:SI 1 "register_operand" "r")
830 (match_operand:SI 2 "extui_fldsz_operand" "i")
831 (match_operand:SI 3 "const_int_operand" "i")))]
837 shift = (32 - (INTVAL (operands[2]) + INTVAL (operands[3]))) & 0x1f;
839 shift = INTVAL (operands[3]) & 0x1f;
840 operands[3] = GEN_INT (shift);
841 return \"extui\\t%0, %1, %3, %2\";
843 [(set_attr "type" "arith")
844 (set_attr "mode" "SI")
845 (set_attr "length" "3")])
849 ;; ....................
853 ;; ....................
856 (define_insn "fix_truncsfsi2"
857 [(set (match_operand:SI 0 "register_operand" "=a")
858 (fix:SI (match_operand:SF 1 "register_operand" "f")))]
860 "trunc.s\\t%0, %1, 0"
861 [(set_attr "type" "fconv")
862 (set_attr "mode" "SF")
863 (set_attr "length" "3")])
865 (define_insn "fixuns_truncsfsi2"
866 [(set (match_operand:SI 0 "register_operand" "=a")
867 (unsigned_fix:SI (match_operand:SF 1 "register_operand" "f")))]
870 [(set_attr "type" "fconv")
871 (set_attr "mode" "SF")
872 (set_attr "length" "3")])
874 (define_insn "floatsisf2"
875 [(set (match_operand:SF 0 "register_operand" "=f")
876 (float:SF (match_operand:SI 1 "register_operand" "a")))]
878 "float.s\\t%0, %1, 0"
879 [(set_attr "type" "fconv")
880 (set_attr "mode" "SF")
881 (set_attr "length" "3")])
883 (define_insn "floatunssisf2"
884 [(set (match_operand:SF 0 "register_operand" "=f")
885 (unsigned_float:SF (match_operand:SI 1 "register_operand" "a")))]
888 [(set_attr "type" "fconv")
889 (set_attr "mode" "SF")
890 (set_attr "length" "3")])
894 ;; ....................
898 ;; ....................
901 ;; 64-bit Integer moves
903 (define_expand "movdi"
904 [(set (match_operand:DI 0 "nonimmed_operand" "")
905 (match_operand:DI 1 "general_operand" ""))]
909 if (CONSTANT_P (operands[1]))
911 rtx src0, src1, dst0, dst1;
912 if ((dst0 = operand_subword (operands[0], 0, 1, DImode))
913 && (src0 = operand_subword (operands[1], 0, 1, DImode))
914 && (dst1 = operand_subword (operands[0], 1, 1, DImode))
915 && (src1 = operand_subword (operands[1], 1, 1, DImode)))
917 emit_insn (gen_movsi (dst0, src0));
918 emit_insn (gen_movsi (dst1, src1));
922 /* any other constant will be loaded from memory */
923 operands[1] = force_const_mem (DImode, operands[1]);
926 if (!(reload_in_progress | reload_completed))
928 if (!register_operand (operands[0], DImode)
929 && !register_operand (operands[1], DImode))
930 operands[1] = force_reg (DImode, operands[1]);
932 if (a7_overlap_mentioned_p (operands[1]))
934 emit_insn (gen_movdi_internal (operands[0], operands[1]));
935 emit_insn (gen_set_frame_ptr ());
941 (define_insn "movdi_internal"
942 [(set (match_operand:DI 0 "nonimmed_operand" "=D,D,S,a,a,a,U")
943 (match_operand:DI 1 "non_const_move_operand" "d,S,d,r,T,U,r"))]
944 "register_operand (operands[0], DImode)
945 || register_operand (operands[1], DImode)"
948 switch (which_alternative)
950 case 0: return \"mov.n\\t%0, %1\;mov.n\\t%D0, %D1\";
951 case 2: return \"%v0s32i.n\\t%1, %0\;s32i.n\\t%D1, %N0\";
952 case 3: return \"mov\\t%0, %1\;mov\\t%D0, %D1\";
953 case 6: return \"%v0s32i\\t%1, %0\;s32i\\t%D1, %N0\";
959 /* Check if the first half of the destination register is used
960 in the source address. If so, reverse the order of the loads
961 so that the source address doesn't get clobbered until it is
964 rtx dstreg = operands[0];
965 if (GET_CODE (dstreg) == SUBREG)
966 dstreg = SUBREG_REG (dstreg);
967 if (GET_CODE (dstreg) != REG)
970 if (reg_mentioned_p (dstreg, operands[1]))
972 switch (which_alternative)
974 case 1: return \"%v1l32i.n\\t%D0, %N1\;l32i.n\\t%0, %1\";
975 case 4: return \"%v1l32r\\t%D0, %N1\;l32r\\t%0, %1\";
976 case 5: return \"%v1l32i\\t%D0, %N1\;l32i\\t%0, %1\";
981 switch (which_alternative)
983 case 1: return \"%v1l32i.n\\t%0, %1\;l32i.n\\t%D0, %N1\";
984 case 4: return \"%v1l32r\\t%0, %1\;l32r\\t%D0, %N1\";
985 case 5: return \"%v1l32i\\t%0, %1\;l32i\\t%D0, %N1\";
993 [(set_attr "type" "move,load,store,move,load,load,store")
994 (set_attr "mode" "DI")
995 (set_attr "length" "4,4,4,6,6,6,6")])
998 ;; 32-bit Integer moves
1000 (define_expand "movsi"
1001 [(set (match_operand:SI 0 "nonimmed_operand" "")
1002 (match_operand:SI 1 "general_operand" ""))]
1006 if (xtensa_emit_move_sequence (operands, SImode))
1010 (define_insn "movsi_internal"
1011 [(set (match_operand:SI 0 "nonimmed_operand" "=D,D,D,D,R,R,a,q,a,a,a,U,*a,*A")
1012 (match_operand:SI 1 "move_operand" "M,D,d,R,D,d,r,r,I,T,U,r,*A,*r"))]
1013 "xtensa_valid_move (SImode, operands)"
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 "xtensa_valid_move (HImode, operands)"
1056 rsr\\t%0, 16 # ACCLO
1057 wsr\\t%1, 16 # ACCLO"
1058 [(set_attr "type" "move,move,move,move,load,store,rsr,wsr")
1059 (set_attr "mode" "HI")
1060 (set_attr "length" "2,2,3,3,3,3,3,3")])
1062 ;; 8-bit Integer moves
1064 (define_expand "movqi"
1065 [(set (match_operand:QI 0 "nonimmed_operand" "")
1066 (match_operand:QI 1 "general_operand" ""))]
1070 if (xtensa_emit_move_sequence (operands, QImode))
1074 (define_insn "movqi_internal"
1075 [(set (match_operand:QI 0 "nonimmed_operand" "=D,D,a,a,a,U,*a,*A")
1076 (match_operand:QI 1 "move_operand" "M,d,r,I,U,r,*A,*r"))]
1077 "xtensa_valid_move (QImode, operands)"
1085 rsr\\t%0, 16 # ACCLO
1086 wsr\\t%1, 16 # ACCLO"
1087 [(set_attr "type" "move,move,move,move,load,store,rsr,wsr")
1088 (set_attr "mode" "QI")
1089 (set_attr "length" "2,2,3,3,3,3,3,3")])
1091 ;; 32-bit floating point moves
1093 (define_expand "movsf"
1094 [(set (match_operand:SF 0 "nonimmed_operand" "")
1095 (match_operand:SF 1 "general_operand" ""))]
1099 if (GET_CODE (operands[1]) == CONST_DOUBLE)
1100 operands[1] = force_const_mem (SFmode, operands[1]);
1102 if (!(reload_in_progress | reload_completed))
1104 if (((!register_operand (operands[0], SFmode)
1105 && !register_operand (operands[1], SFmode))
1106 || (FP_REG_P (xt_true_regnum (operands[0]))
1107 && constantpool_mem_p (operands[1]))))
1108 operands[1] = force_reg (SFmode, operands[1]);
1110 if (a7_overlap_mentioned_p (operands[1]))
1112 emit_insn (gen_movsf_internal (operands[0], operands[1]));
1113 emit_insn (gen_set_frame_ptr ());
1119 (define_insn "movsf_internal"
1120 [(set (match_operand:SF 0 "nonimmed_operand"
1121 "=f,f,U,D,D,R,a,f,a,a,a,U")
1122 (match_operand:SF 1 "non_const_move_operand"
1123 "f,U,f,d,R,d,r,r,f,T,U,r"))]
1124 "((register_operand (operands[0], SFmode)
1125 || register_operand (operands[1], SFmode))
1126 && (!FP_REG_P (xt_true_regnum (operands[0]))
1127 || !constantpool_mem_p (operands[1])))"
1141 [(set_attr "type" "farith,fload,fstore,move,load,store,move,farith,farith,load,load,store")
1142 (set_attr "mode" "SF")
1143 (set_attr "length" "3,3,3,2,2,2,3,3,3,3,3,3")])
1147 [(set (match_operand:SF 0 "register_operand" "=f")
1148 (mem:SF (plus:SI (match_operand:SI 1 "register_operand" "+a")
1149 (match_operand:SI 2 "fpmem_offset_operand" "i"))))
1151 (plus:SI (match_dup 1) (match_dup 2)))])]
1155 if (TARGET_SERIALIZE_VOLATILE && volatile_refs_p (PATTERN (insn)))
1156 output_asm_insn (\"memw\", operands);
1157 return \"lsiu\\t%0, %1, %2\";
1159 [(set_attr "type" "fload")
1160 (set_attr "mode" "SF")
1161 (set_attr "length" "3")])
1165 [(set (mem:SF (plus:SI (match_operand:SI 0 "register_operand" "+a")
1166 (match_operand:SI 1 "fpmem_offset_operand" "i")))
1167 (match_operand:SF 2 "register_operand" "f"))
1169 (plus:SI (match_dup 0) (match_dup 1)))])]
1173 if (TARGET_SERIALIZE_VOLATILE && volatile_refs_p (PATTERN (insn)))
1174 output_asm_insn (\"memw\", operands);
1175 return \"ssiu\\t%2, %0, %1\";
1177 [(set_attr "type" "fstore")
1178 (set_attr "mode" "SF")
1179 (set_attr "length" "3")])
1181 ;; 64-bit floating point moves
1183 (define_expand "movdf"
1184 [(set (match_operand:DF 0 "nonimmed_operand" "")
1185 (match_operand:DF 1 "general_operand" ""))]
1189 if (GET_CODE (operands[1]) == CONST_DOUBLE)
1190 operands[1] = force_const_mem (DFmode, operands[1]);
1192 if (!(reload_in_progress | reload_completed))
1194 if (!register_operand (operands[0], DFmode)
1195 && !register_operand (operands[1], DFmode))
1196 operands[1] = force_reg (DFmode, operands[1]);
1198 if (a7_overlap_mentioned_p (operands[1]))
1200 emit_insn (gen_movdf_internal (operands[0], operands[1]));
1201 emit_insn (gen_set_frame_ptr ());
1207 (define_insn "movdf_internal"
1208 [(set (match_operand:DF 0 "nonimmed_operand" "=D,D,S,a,a,a,U")
1209 (match_operand:DF 1 "non_const_move_operand" "d,S,d,r,T,U,r"))]
1210 "register_operand (operands[0], DFmode)
1211 || register_operand (operands[1], DFmode)"
1214 switch (which_alternative)
1216 case 0: return \"mov.n\\t%0, %1\;mov.n\\t%D0, %D1\";
1217 case 2: return \"%v0s32i.n\\t%1, %0\;s32i.n\\t%D1, %N0\";
1218 case 3: return \"mov\\t%0, %1\;mov\\t%D0, %D1\";
1219 case 6: return \"%v0s32i\\t%1, %0\;s32i\\t%D1, %N0\";
1225 /* Check if the first half of the destination register is used
1226 in the source address. If so, reverse the order of the loads
1227 so that the source address doesn't get clobbered until it is
1228 no longer needed. */
1230 rtx dstreg = operands[0];
1231 if (GET_CODE (dstreg) == SUBREG)
1232 dstreg = SUBREG_REG (dstreg);
1233 if (GET_CODE (dstreg) != REG)
1236 if (reg_mentioned_p (dstreg, operands[1]))
1238 switch (which_alternative)
1240 case 1: return \"%v1l32i.n\\t%D0, %N1\;l32i.n\\t%0, %1\";
1241 case 4: return \"%v1l32r\\t%D0, %N1\;l32r\\t%0, %1\";
1242 case 5: return \"%v1l32i\\t%D0, %N1\;l32i\\t%0, %1\";
1247 switch (which_alternative)
1249 case 1: return \"%v1l32i.n\\t%0, %1\;l32i.n\\t%D0, %N1\";
1250 case 4: return \"%v1l32r\\t%0, %1\;l32r\\t%D0, %N1\";
1251 case 5: return \"%v1l32i\\t%0, %1\;l32i\\t%D0, %N1\";
1259 [(set_attr "type" "move,load,store,move,load,load,store")
1260 (set_attr "mode" "DF")
1261 (set_attr "length" "4,4,4,6,6,6,6")])
1265 (define_expand "movstrsi"
1266 [(parallel [(set (match_operand:BLK 0 "" "")
1267 (match_operand:BLK 1 "" ""))
1268 (use (match_operand:SI 2 "arith_operand" ""))
1269 (use (match_operand:SI 3 "const_int_operand" ""))])]
1273 if (!xtensa_expand_block_move (operands)) FAIL;
1277 (define_insn "movstrsi_internal"
1278 [(parallel [(set (match_operand:BLK 0 "memory_operand" "=U")
1279 (match_operand:BLK 1 "memory_operand" "U"))
1280 (use (match_operand:SI 2 "arith_operand" ""))
1281 (use (match_operand:SI 3 "const_int_operand" ""))
1282 (clobber (match_scratch:SI 4 "=&r"))
1283 (clobber (match_scratch:SI 5 "=&r"))])]
1288 tmpregs[0] = operands[4];
1289 tmpregs[1] = operands[5];
1290 xtensa_emit_block_move (operands, tmpregs, 1);
1293 [(set_attr "type" "multi")
1294 (set_attr "mode" "none")
1295 (set_attr "length" "300")])
1299 ;; ....................
1303 ;; ....................
1306 (define_insn "ashlsi3"
1307 [(set (match_operand:SI 0 "register_operand" "=a,a")
1308 (ashift:SI (match_operand:SI 1 "register_operand" "r,r")
1309 (match_operand:SI 2 "arith_operand" "J,r")))]
1313 ssl\\t%2\;sll\\t%0, %1"
1314 [(set_attr "type" "arith,arith")
1315 (set_attr "mode" "SI")
1316 (set_attr "length" "3,6")])
1318 (define_insn "ashrsi3"
1319 [(set (match_operand:SI 0 "register_operand" "=a,a")
1320 (ashiftrt:SI (match_operand:SI 1 "register_operand" "r,r")
1321 (match_operand:SI 2 "arith_operand" "J,r")))]
1325 ssr\\t%2\;sra\\t%0, %1"
1326 [(set_attr "type" "arith,arith")
1327 (set_attr "mode" "SI")
1328 (set_attr "length" "3,6")])
1330 (define_insn "lshrsi3"
1331 [(set (match_operand:SI 0 "register_operand" "=a,a")
1332 (lshiftrt:SI (match_operand:SI 1 "register_operand" "r,r")
1333 (match_operand:SI 2 "arith_operand" "J,r")))]
1337 if (which_alternative == 0)
1339 if ((INTVAL (operands[2]) & 0x1f) < 16)
1340 return \"srli\\t%0, %1, %R2\";
1342 return \"extui\\t%0, %1, %R2, %L2\";
1344 return \"ssr\\t%2\;srl\\t%0, %1\";
1346 [(set_attr "type" "arith,arith")
1347 (set_attr "mode" "SI")
1348 (set_attr "length" "3,6")])
1350 (define_insn "rotlsi3"
1351 [(set (match_operand:SI 0 "register_operand" "=a,a")
1352 (rotate:SI (match_operand:SI 1 "register_operand" "r,r")
1353 (match_operand:SI 2 "arith_operand" "J,r")))]
1356 ssai\\t%L2\;src\\t%0, %1, %1
1357 ssl\\t%2\;src\\t%0, %1, %1"
1358 [(set_attr "type" "multi,multi")
1359 (set_attr "mode" "SI")
1360 (set_attr "length" "6,6")])
1362 (define_insn "rotrsi3"
1363 [(set (match_operand:SI 0 "register_operand" "=a,a")
1364 (rotatert:SI (match_operand:SI 1 "register_operand" "r,r")
1365 (match_operand:SI 2 "arith_operand" "J,r")))]
1368 ssai\\t%R2\;src\\t%0, %1, %1
1369 ssr\\t%2\;src\\t%0, %1, %1"
1370 [(set_attr "type" "multi,multi")
1371 (set_attr "mode" "SI")
1372 (set_attr "length" "6,6")])
1376 ;; ....................
1380 ;; ....................
1383 ;; Like the md files for MIPS and SPARC, we handle comparisons by stashing
1384 ;; away the operands and then using that information in the subsequent
1385 ;; conditional branch.
1387 (define_expand "cmpsi"
1389 (compare:CC (match_operand:SI 0 "register_operand" "")
1390 (match_operand:SI 1 "nonmemory_operand" "")))]
1394 branch_cmp[0] = operands[0];
1395 branch_cmp[1] = operands[1];
1396 branch_type = CMP_SI;
1400 (define_expand "tstsi"
1402 (match_operand:SI 0 "register_operand" ""))]
1406 branch_cmp[0] = operands[0];
1407 branch_cmp[1] = const0_rtx;
1408 branch_type = CMP_SI;
1412 (define_expand "cmpsf"
1414 (compare:CC (match_operand:SF 0 "register_operand" "")
1415 (match_operand:SF 1 "register_operand" "")))]
1419 branch_cmp[0] = operands[0];
1420 branch_cmp[1] = operands[1];
1421 branch_type = CMP_SF;
1427 ;; ....................
1429 ;; CONDITIONAL BRANCHES
1431 ;; ....................
1434 (define_expand "beq"
1436 (if_then_else (eq (cc0) (const_int 0))
1437 (label_ref (match_operand 0 "" ""))
1442 xtensa_expand_conditional_branch (operands, EQ);
1446 (define_expand "bne"
1448 (if_then_else (ne (cc0) (const_int 0))
1449 (label_ref (match_operand 0 "" ""))
1454 xtensa_expand_conditional_branch (operands, NE);
1458 (define_expand "bgt"
1460 (if_then_else (gt (cc0) (const_int 0))
1461 (label_ref (match_operand 0 "" ""))
1466 xtensa_expand_conditional_branch (operands, GT);
1470 (define_expand "bge"
1472 (if_then_else (ge (cc0) (const_int 0))
1473 (label_ref (match_operand 0 "" ""))
1478 xtensa_expand_conditional_branch (operands, GE);
1482 (define_expand "blt"
1484 (if_then_else (lt (cc0) (const_int 0))
1485 (label_ref (match_operand 0 "" ""))
1490 xtensa_expand_conditional_branch (operands, LT);
1494 (define_expand "ble"
1496 (if_then_else (le (cc0) (const_int 0))
1497 (label_ref (match_operand 0 "" ""))
1502 xtensa_expand_conditional_branch (operands, LE);
1506 (define_expand "bgtu"
1508 (if_then_else (gtu (cc0) (const_int 0))
1509 (label_ref (match_operand 0 "" ""))
1514 xtensa_expand_conditional_branch (operands, GTU);
1518 (define_expand "bgeu"
1520 (if_then_else (geu (cc0) (const_int 0))
1521 (label_ref (match_operand 0 "" ""))
1526 xtensa_expand_conditional_branch (operands, GEU);
1530 (define_expand "bltu"
1532 (if_then_else (ltu (cc0) (const_int 0))
1533 (label_ref (match_operand 0 "" ""))
1538 xtensa_expand_conditional_branch (operands, LTU);
1542 (define_expand "bleu"
1544 (if_then_else (leu (cc0) (const_int 0))
1545 (label_ref (match_operand 0 "" ""))
1550 xtensa_expand_conditional_branch (operands, LEU);
1554 ;; Branch patterns for standard integer comparisons
1558 (if_then_else (match_operator 3 "branch_operator"
1559 [(match_operand:SI 0 "register_operand" "r,r")
1560 (match_operand:SI 1 "branch_operand" "K,r")])
1561 (label_ref (match_operand 2 "" ""))
1566 if (which_alternative == 1)
1568 switch (GET_CODE (operands[3]))
1570 case EQ: return \"beq\\t%0, %1, %2\";
1571 case NE: return \"bne\\t%0, %1, %2\";
1572 case LT: return \"blt\\t%0, %1, %2\";
1573 case GE: return \"bge\\t%0, %1, %2\";
1577 else if (INTVAL (operands[1]) == 0)
1579 switch (GET_CODE (operands[3]))
1581 case EQ: return (TARGET_DENSITY
1582 ? \"beqz.n\\t%0, %2\"
1583 : \"beqz\\t%0, %2\");
1584 case NE: return (TARGET_DENSITY
1585 ? \"bnez.n\\t%0, %2\"
1586 : \"bnez\\t%0, %2\");
1587 case LT: return \"bltz\\t%0, %2\";
1588 case GE: return \"bgez\\t%0, %2\";
1594 switch (GET_CODE (operands[3]))
1596 case EQ: return \"beqi\\t%0, %d1, %2\";
1597 case NE: return \"bnei\\t%0, %d1, %2\";
1598 case LT: return \"blti\\t%0, %d1, %2\";
1599 case GE: return \"bgei\\t%0, %d1, %2\";
1603 fatal_insn (\"unexpected branch operator\", operands[3]);
1606 [(set_attr "type" "jump,jump")
1607 (set_attr "mode" "none")
1608 (set_attr "length" "3,3")])
1612 (if_then_else (match_operator 3 "branch_operator"
1613 [(match_operand:SI 0 "register_operand" "r,r")
1614 (match_operand:SI 1 "branch_operand" "K,r")])
1616 (label_ref (match_operand 2 "" ""))))]
1620 if (which_alternative == 1)
1622 switch (GET_CODE (operands[3]))
1624 case EQ: return \"bne\\t%0, %1, %2\";
1625 case NE: return \"beq\\t%0, %1, %2\";
1626 case LT: return \"bge\\t%0, %1, %2\";
1627 case GE: return \"blt\\t%0, %1, %2\";
1631 else if (INTVAL (operands[1]) == 0)
1633 switch (GET_CODE (operands[3]))
1635 case EQ: return (TARGET_DENSITY
1636 ? \"bnez.n\\t%0, %2\"
1637 : \"bnez\\t%0, %2\");
1638 case NE: return (TARGET_DENSITY
1639 ? \"beqz.n\\t%0, %2\"
1640 : \"beqz\\t%0, %2\");
1641 case LT: return \"bgez\\t%0, %2\";
1642 case GE: return \"bltz\\t%0, %2\";
1648 switch (GET_CODE (operands[3]))
1650 case EQ: return \"bnei\\t%0, %d1, %2\";
1651 case NE: return \"beqi\\t%0, %d1, %2\";
1652 case LT: return \"bgei\\t%0, %d1, %2\";
1653 case GE: return \"blti\\t%0, %d1, %2\";
1657 fatal_insn (\"unexpected branch operator\", operands[3]);
1660 [(set_attr "type" "jump,jump")
1661 (set_attr "mode" "none")
1662 (set_attr "length" "3,3")])
1666 (if_then_else (match_operator 3 "ubranch_operator"
1667 [(match_operand:SI 0 "register_operand" "r,r")
1668 (match_operand:SI 1 "ubranch_operand" "L,r")])
1669 (label_ref (match_operand 2 "" ""))
1674 if (which_alternative == 1)
1676 switch (GET_CODE (operands[3]))
1678 case LTU: return \"bltu\\t%0, %1, %2\";
1679 case GEU: return \"bgeu\\t%0, %1, %2\";
1685 switch (GET_CODE (operands[3]))
1687 case LTU: return \"bltui\\t%0, %d1, %2\";
1688 case GEU: return \"bgeui\\t%0, %d1, %2\";
1692 fatal_insn (\"unexpected branch operator\", operands[3]);
1695 [(set_attr "type" "jump,jump")
1696 (set_attr "mode" "none")
1697 (set_attr "length" "3,3")])
1701 (if_then_else (match_operator 3 "ubranch_operator"
1702 [(match_operand:SI 0 "register_operand" "r,r")
1703 (match_operand:SI 1 "ubranch_operand" "L,r")])
1705 (label_ref (match_operand 2 "" ""))))]
1709 if (which_alternative == 1)
1711 switch (GET_CODE (operands[3]))
1713 case LTU: return \"bgeu\\t%0, %1, %2\";
1714 case GEU: return \"bltu\\t%0, %1, %2\";
1720 switch (GET_CODE (operands[3]))
1722 case LTU: return \"bgeui\\t%0, %d1, %2\";
1723 case GEU: return \"bltui\\t%0, %d1, %2\";
1727 fatal_insn (\"unexpected branch operator\", operands[3]);
1730 [(set_attr "type" "jump,jump")
1731 (set_attr "mode" "none")
1732 (set_attr "length" "3,3")])
1734 ;; Branch patterns for bit testing
1738 (if_then_else (match_operator 3 "boolean_operator"
1740 (match_operand:SI 0 "register_operand" "r,r")
1742 (match_operand:SI 1 "arith_operand" "J,r"))
1744 (label_ref (match_operand 2 "" ""))
1749 if (which_alternative == 0)
1751 unsigned bitnum = INTVAL(operands[1]) & 0x1f;
1752 operands[1] = GEN_INT(bitnum);
1753 switch (GET_CODE (operands[3]))
1755 case EQ: return \"bbci\\t%0, %d1, %2\";
1756 case NE: return \"bbsi\\t%0, %d1, %2\";
1762 switch (GET_CODE (operands[3]))
1764 case EQ: return \"bbc\\t%0, %1, %2\";
1765 case NE: return \"bbs\\t%0, %1, %2\";
1769 fatal_insn (\"unexpected branch operator\", operands[3]);
1772 [(set_attr "type" "jump")
1773 (set_attr "mode" "none")
1774 (set_attr "length" "3")])
1778 (if_then_else (match_operator 3 "boolean_operator"
1780 (match_operand:SI 0 "register_operand" "r,r")
1782 (match_operand:SI 1 "arith_operand" "J,r"))
1785 (label_ref (match_operand 2 "" ""))))]
1789 if (which_alternative == 0)
1791 unsigned bitnum = INTVAL (operands[1]) & 0x1f;
1792 operands[1] = GEN_INT (bitnum);
1793 switch (GET_CODE (operands[3]))
1795 case EQ: return \"bbsi\\t%0, %d1, %2\";
1796 case NE: return \"bbci\\t%0, %d1, %2\";
1802 switch (GET_CODE (operands[3]))
1804 case EQ: return \"bbs\\t%0, %1, %2\";
1805 case NE: return \"bbc\\t%0, %1, %2\";
1809 fatal_insn (\"unexpected branch operator\", operands[3]);
1812 [(set_attr "type" "jump")
1813 (set_attr "mode" "none")
1814 (set_attr "length" "3")])
1818 (if_then_else (match_operator 3 "boolean_operator"
1819 [(and:SI (match_operand:SI 0 "register_operand" "r")
1820 (match_operand:SI 1 "register_operand" "r"))
1822 (label_ref (match_operand 2 "" ""))
1827 switch (GET_CODE (operands[3]))
1829 case EQ: return \"bnone\\t%0, %1, %2\";
1830 case NE: return \"bany\\t%0, %1, %2\";
1833 fatal_insn (\"unexpected branch operator\", operands[3]);
1836 [(set_attr "type" "jump")
1837 (set_attr "mode" "none")
1838 (set_attr "length" "3")])
1842 (if_then_else (match_operator 3 "boolean_operator"
1843 [(and:SI (match_operand:SI 0 "register_operand" "r")
1844 (match_operand:SI 1 "register_operand" "r"))
1847 (label_ref (match_operand 2 "" ""))))]
1851 switch (GET_CODE (operands[3]))
1853 case EQ: return \"bany\\t%0, %1, %2\";
1854 case NE: return \"bnone\\t%0, %1, %2\";
1857 fatal_insn (\"unexpected branch operator\", operands[3]);
1860 [(set_attr "type" "jump")
1861 (set_attr "mode" "none")
1862 (set_attr "length" "3")])
1865 ;; Define the loop insns that is used by bct optimization to represent the
1866 ;; start and end of a zero-overhead loop (in loop.c). This start template
1867 ;; generates the loop insn, the end template doesn't generate any instructions
1868 ;; since since loop end is handled in hardware.
1870 (define_insn "zero_cost_loop_start"
1871 [(parallel [(set (pc) (if_then_else (eq (match_operand:SI 0 "register_operand" "a")
1873 (label_ref (match_operand 1 "" ""))
1876 (plus:SI (match_dup 0)
1880 [(set_attr "type" "jump")
1881 (set_attr "mode" "none")
1882 (set_attr "length" "3")])
1884 (define_insn "zero_cost_loop_end"
1885 [(parallel [(set (pc) (if_then_else (ne (reg:SI 19)
1887 (label_ref (match_operand 0 "" ""))
1890 (plus:SI (reg:SI 19)
1894 xtensa_emit_loop_end (insn, operands);
1897 [(set_attr "type" "jump")
1898 (set_attr "mode" "none")
1899 (set_attr "length" "0")])
1903 ;; ....................
1905 ;; SETTING A REGISTER FROM A COMPARISON
1907 ;; ....................
1910 (define_expand "seq"
1911 [(set (match_operand:SI 0 "register_operand" "")
1916 operands[1] = gen_rtx (EQ, SImode, branch_cmp[0], branch_cmp[1]);
1917 if (!xtensa_expand_scc (operands)) FAIL;
1921 (define_expand "sne"
1922 [(set (match_operand:SI 0 "register_operand" "")
1927 operands[1] = gen_rtx (NE, SImode, branch_cmp[0], branch_cmp[1]);
1928 if (!xtensa_expand_scc (operands)) FAIL;
1932 (define_expand "sgt"
1933 [(set (match_operand:SI 0 "register_operand" "")
1938 operands[1] = gen_rtx (GT, SImode, branch_cmp[0], branch_cmp[1]);
1939 if (!xtensa_expand_scc (operands)) FAIL;
1943 (define_expand "sge"
1944 [(set (match_operand:SI 0 "register_operand" "")
1949 operands[1] = gen_rtx (GE, SImode, branch_cmp[0], branch_cmp[1]);
1950 if (!xtensa_expand_scc (operands)) FAIL;
1954 (define_expand "slt"
1955 [(set (match_operand:SI 0 "register_operand" "")
1960 operands[1] = gen_rtx (LT, SImode, branch_cmp[0], branch_cmp[1]);
1961 if (!xtensa_expand_scc (operands)) FAIL;
1965 (define_expand "sle"
1966 [(set (match_operand:SI 0 "register_operand" "")
1971 operands[1] = gen_rtx (LE, SImode, branch_cmp[0], branch_cmp[1]);
1972 if (!xtensa_expand_scc (operands)) FAIL;
1978 ;; ....................
1980 ;; CONDITIONAL MOVES
1982 ;; ....................
1985 (define_expand "movsicc"
1986 [(set (match_operand:SI 0 "register_operand" "")
1987 (if_then_else:SI (match_operand 1 "comparison_operator" "")
1988 (match_operand:SI 2 "register_operand" "")
1989 (match_operand:SI 3 "register_operand" "")))]
1993 if (!xtensa_expand_conditional_move (operands, 0)) FAIL;
1997 (define_expand "movsfcc"
1998 [(set (match_operand:SF 0 "register_operand" "")
1999 (if_then_else:SF (match_operand 1 "comparison_operator" "")
2000 (match_operand:SF 2 "register_operand" "")
2001 (match_operand:SF 3 "register_operand" "")))]
2005 if (!xtensa_expand_conditional_move (operands, 1)) FAIL;
2009 (define_insn "movsicc_internal0"
2010 [(set (match_operand:SI 0 "register_operand" "=a,a")
2011 (if_then_else:SI (match_operator 4 "branch_operator"
2012 [(match_operand:SI 1 "register_operand" "r,r")
2014 (match_operand:SI 2 "register_operand" "r,0")
2015 (match_operand:SI 3 "register_operand" "0,r")))]
2019 if (which_alternative == 0)
2021 switch (GET_CODE (operands[4]))
2023 case EQ: return \"moveqz\\t%0, %2, %1\";
2024 case NE: return \"movnez\\t%0, %2, %1\";
2025 case LT: return \"movltz\\t%0, %2, %1\";
2026 case GE: return \"movgez\\t%0, %2, %1\";
2032 switch (GET_CODE (operands[4]))
2034 case EQ: return \"movnez\\t%0, %3, %1\";
2035 case NE: return \"moveqz\\t%0, %3, %1\";
2036 case LT: return \"movgez\\t%0, %3, %1\";
2037 case GE: return \"movltz\\t%0, %3, %1\";
2041 fatal_insn (\"unexpected cmov operator\", operands[4]);
2044 [(set_attr "type" "move,move")
2045 (set_attr "mode" "SI")
2046 (set_attr "length" "3,3")])
2048 (define_insn "movsicc_internal1"
2049 [(set (match_operand:SI 0 "register_operand" "=a,a")
2050 (if_then_else:SI (match_operator 4 "boolean_operator"
2051 [(match_operand:CC 1 "register_operand" "b,b")
2053 (match_operand:SI 2 "register_operand" "r,0")
2054 (match_operand:SI 3 "register_operand" "0,r")))]
2058 int isEq = (GET_CODE (operands[4]) == EQ);
2059 switch (which_alternative)
2062 if (isEq) return \"movf\\t%0, %2, %1\";
2063 return \"movt\\t%0, %2, %1\";
2065 if (isEq) return \"movt\\t%0, %3, %1\";
2066 return \"movf\\t%0, %3, %1\";
2071 [(set_attr "type" "move,move")
2072 (set_attr "mode" "SI")
2073 (set_attr "length" "3,3")])
2075 (define_insn "movsfcc_internal0"
2076 [(set (match_operand:SF 0 "register_operand" "=a,a,f,f")
2077 (if_then_else:SF (match_operator 4 "branch_operator"
2078 [(match_operand:SI 1 "register_operand" "r,r,r,r")
2080 (match_operand:SF 2 "register_operand" "r,0,f,0")
2081 (match_operand:SF 3 "register_operand" "0,r,0,f")))]
2085 if (which_alternative == 0)
2087 switch (GET_CODE (operands[4]))
2089 case EQ: return \"moveqz\\t%0, %2, %1\";
2090 case NE: return \"movnez\\t%0, %2, %1\";
2091 case LT: return \"movltz\\t%0, %2, %1\";
2092 case GE: return \"movgez\\t%0, %2, %1\";
2096 else if (which_alternative == 1)
2098 switch (GET_CODE (operands[4]))
2100 case EQ: return \"movnez\\t%0, %3, %1\";
2101 case NE: return \"moveqz\\t%0, %3, %1\";
2102 case LT: return \"movgez\\t%0, %3, %1\";
2103 case GE: return \"movltz\\t%0, %3, %1\";
2107 else if (which_alternative == 2)
2109 switch (GET_CODE (operands[4]))
2111 case EQ: return \"moveqz.s %0, %2, %1\";
2112 case NE: return \"movnez.s %0, %2, %1\";
2113 case LT: return \"movltz.s %0, %2, %1\";
2114 case GE: return \"movgez.s %0, %2, %1\";
2118 else if (which_alternative == 3)
2120 switch (GET_CODE (operands[4]))
2122 case EQ: return \"movnez.s %0, %3, %1\";
2123 case NE: return \"moveqz.s %0, %3, %1\";
2124 case LT: return \"movgez.s %0, %3, %1\";
2125 case GE: return \"movltz.s %0, %3, %1\";
2129 fatal_insn (\"unexpected cmov operator\", operands[4]);
2132 [(set_attr "type" "move,move,move,move")
2133 (set_attr "mode" "SF")
2134 (set_attr "length" "3,3,3,3")])
2136 (define_insn "movsfcc_internal1"
2137 [(set (match_operand:SF 0 "register_operand" "=a,a,f,f")
2138 (if_then_else:SF (match_operator 4 "boolean_operator"
2139 [(match_operand:CC 1 "register_operand" "b,b,b,b")
2141 (match_operand:SF 2 "register_operand" "r,0,f,0")
2142 (match_operand:SF 3 "register_operand" "0,r,0,f")))]
2146 int isEq = (GET_CODE (operands[4]) == EQ);
2147 switch (which_alternative)
2150 if (isEq) return \"movf\\t%0, %2, %1\";
2151 return \"movt\\t%0, %2, %1\";
2153 if (isEq) return \"movt\\t%0, %3, %1\";
2154 return \"movf\\t%0, %3, %1\";
2156 if (isEq) return \"movf.s\\t%0, %2, %1\";
2157 return \"movt.s\\t%0, %2, %1\";
2159 if (isEq) return \"movt.s\\t%0, %3, %1\";
2160 return \"movf.s\\t%0, %3, %1\";
2165 [(set_attr "type" "move,move,move,move")
2166 (set_attr "mode" "SF")
2167 (set_attr "length" "3,3,3,3")])
2171 ;; ....................
2173 ;; FLOATING POINT COMPARISONS
2175 ;; ....................
2178 (define_insn "seq_sf"
2179 [(set (match_operand:CC 0 "register_operand" "=b")
2180 (eq:CC (match_operand:SF 1 "register_operand" "f")
2181 (match_operand:SF 2 "register_operand" "f")))]
2183 "oeq.s\\t%0, %1, %2"
2184 [(set_attr "type" "farith")
2185 (set_attr "mode" "BL")
2186 (set_attr "length" "3")])
2188 (define_insn "slt_sf"
2189 [(set (match_operand:CC 0 "register_operand" "=b")
2190 (lt:CC (match_operand:SF 1 "register_operand" "f")
2191 (match_operand:SF 2 "register_operand" "f")))]
2193 "olt.s\\t%0, %1, %2"
2194 [(set_attr "type" "farith")
2195 (set_attr "mode" "BL")
2196 (set_attr "length" "3")])
2198 (define_insn "sle_sf"
2199 [(set (match_operand:CC 0 "register_operand" "=b")
2200 (le:CC (match_operand:SF 1 "register_operand" "f")
2201 (match_operand:SF 2 "register_operand" "f")))]
2203 "ole.s\\t%0, %1, %2"
2204 [(set_attr "type" "farith")
2205 (set_attr "mode" "BL")
2206 (set_attr "length" "3")])
2210 ;; ....................
2212 ;; UNCONDITIONAL BRANCHES
2214 ;; ....................
2219 (label_ref (match_operand 0 "" "")))]
2222 [(set_attr "type" "jump")
2223 (set_attr "mode" "none")
2224 (set_attr "length" "3")])
2226 (define_expand "indirect_jump"
2227 [(set (pc) (match_operand 0 "register_operand" ""))]
2231 rtx dest = operands[0];
2232 if (GET_CODE (dest) != REG || GET_MODE (dest) != Pmode)
2233 operands[0] = copy_to_mode_reg (Pmode, dest);
2235 emit_jump_insn (gen_indirect_jump_internal (dest));
2239 (define_insn "indirect_jump_internal"
2240 [(set (pc) (match_operand:SI 0 "register_operand" "r"))]
2243 [(set_attr "type" "jump")
2244 (set_attr "mode" "none")
2245 (set_attr "length" "3")])
2248 (define_expand "tablejump"
2249 [(use (match_operand:SI 0 "register_operand" ""))
2250 (use (label_ref (match_operand 1 "" "")))]
2254 rtx target = operands[0];
2257 /* For PIC, the table entry is relative to the start of the table. */
2258 rtx label = gen_reg_rtx (SImode);
2259 target = gen_reg_rtx (SImode);
2260 emit_move_insn (label, gen_rtx_LABEL_REF (SImode, operands[1]));
2261 emit_insn (gen_addsi3 (target, operands[0], label));
2263 emit_jump_insn (gen_tablejump_internal (target, operands[1]));
2267 (define_insn "tablejump_internal"
2269 (match_operand:SI 0 "register_operand" "r"))
2270 (use (label_ref (match_operand 1 "" "")))]
2273 [(set_attr "type" "jump")
2274 (set_attr "mode" "none")
2275 (set_attr "length" "3")])
2279 ;; ....................
2283 ;; ....................
2286 (define_expand "sym_PLT"
2287 [(const (unspec [(match_operand:SI 0 "" "")] UNSPEC_PLT))]
2291 (define_expand "call"
2292 [(call (match_operand 0 "memory_operand" "")
2293 (match_operand 1 "" ""))]
2297 rtx addr = XEXP (operands[0], 0);
2298 if (flag_pic && GET_CODE (addr) == SYMBOL_REF && !SYMBOL_REF_FLAG (addr))
2299 addr = gen_sym_PLT (addr);
2300 if (!call_insn_operand (addr, VOIDmode))
2301 XEXP (operands[0], 0) = copy_to_mode_reg (Pmode, addr);
2304 (define_insn "call_internal"
2305 [(call (mem (match_operand:SI 0 "call_insn_operand" "n,i,r"))
2306 (match_operand 1 "" "i,i,i"))]
2309 return xtensa_emit_call (0, operands);
2311 [(set_attr "type" "call")
2312 (set_attr "mode" "none")
2313 (set_attr "length" "3")])
2315 (define_expand "call_value"
2316 [(set (match_operand 0 "register_operand" "")
2317 (call (match_operand 1 "memory_operand" "")
2318 (match_operand 2 "" "")))]
2322 rtx addr = XEXP (operands[1], 0);
2323 if (flag_pic && GET_CODE (addr) == SYMBOL_REF && !SYMBOL_REF_FLAG (addr))
2324 addr = gen_sym_PLT (addr);
2325 if (!call_insn_operand (addr, VOIDmode))
2326 XEXP (operands[1], 0) = copy_to_mode_reg (Pmode, addr);
2329 ;; cannot combine constraints for operand 0 into "afvb"
2330 ;; reload.c:find_reloads seems to assume that grouped constraints somehow
2331 ;; specify related register classes, and when they don't the constraints
2332 ;; fail to match. By not grouping the constraints, we get the correct
2334 (define_insn "call_value_internal"
2335 [(set (match_operand 0 "register_operand" "=af,af,af,v,v,v,b,b,b")
2336 (call (mem (match_operand:SI 1 "call_insn_operand"
2337 "n,i,r,n,i,r,n,i,r"))
2338 (match_operand 2 "" "i,i,i,i,i,i,i,i,i")))]
2341 return xtensa_emit_call (1, operands);
2343 [(set_attr "type" "call")
2344 (set_attr "mode" "none")
2345 (set_attr "length" "3")])
2347 (define_insn "return"
2349 (use (reg:SI A0_REG))]
2353 return (TARGET_DENSITY ? \"retw.n\" : \"retw\");
2355 [(set_attr "type" "jump")
2356 (set_attr "mode" "none")
2357 (set_attr "length" "2")])
2361 ;; ....................
2365 ;; ....................
2373 return (TARGET_DENSITY ? \"nop.n\" : \"nop\");
2375 [(set_attr "type" "nop")
2376 (set_attr "mode" "none")
2377 (set_attr "length" "3")])
2379 (define_expand "nonlocal_goto"
2380 [(match_operand:SI 0 "general_operand" "")
2381 (match_operand:SI 1 "general_operand" "")
2382 (match_operand:SI 2 "general_operand" "")
2383 (match_operand:SI 3 "" "")]
2387 xtensa_expand_nonlocal_goto (operands);
2391 ;; Setting up a frame pointer is tricky for Xtensa because GCC doesn't
2392 ;; know if a frame pointer is required until the reload pass, and
2393 ;; because there may be an incoming argument value in the hard frame
2394 ;; pointer register (a7). If there is an incoming argument in that
2395 ;; register, the "set_frame_ptr" insn gets inserted immediately after
2396 ;; the insn that copies the incoming argument to a pseudo or to the
2397 ;; stack. This serves several purposes here: (1) it keeps the
2398 ;; optimizer from copy-propagating or scheduling the use of a7 as an
2399 ;; incoming argument away from the beginning of the function; (2) we
2400 ;; can use a post-reload splitter to expand away the insn if a frame
2401 ;; pointer is not required, so that the post-reload scheduler can do
2402 ;; the right thing; and (3) it makes it easy for xtensa_reorg() to
2403 ;; search for this insn to determine whether it should add a new insn
2404 ;; to set up the frame pointer.
2406 (define_insn "set_frame_ptr"
2407 [(unspec_volatile [(const_int 0)] UNSPECV_SET_FP)]
2411 if (frame_pointer_needed)
2412 return \"mov\\ta7, sp\";
2415 [(set_attr "type" "move")
2416 (set_attr "mode" "SI")
2417 (set_attr "length" "3")])
2419 ;; Post-reload splitter to remove fp assignment when it's not needed.
2421 [(unspec_volatile [(const_int 0)] UNSPECV_SET_FP)]
2422 "reload_completed && !frame_pointer_needed"
2423 [(unspec [(const_int 0)] UNSPEC_NOP)]
2426 ;; The preceding splitter needs something to split the insn into;
2427 ;; things start breaking if the result is just a "use" so instead we
2428 ;; generate the following insn.
2430 [(unspec [(const_int 0)] UNSPEC_NOP)]
2433 [(set_attr "type" "nop")
2434 (set_attr "mode" "none")
2435 (set_attr "length" "0")])
2437 ;; The fix_return_addr pattern sets the high 2 bits of an address in a
2438 ;; register to match the high bits of the current PC.
2440 (define_insn "fix_return_addr"
2441 [(set (match_operand:SI 0 "register_operand" "=a")
2442 (unspec:SI [(match_operand:SI 1 "register_operand" "r")]
2444 (clobber (match_scratch:SI 2 "=r"))
2445 (clobber (match_scratch:SI 3 "=r"))]
2447 "mov\\t%2, a0\;call0\\t0f\;.align\\t4\;0:\;mov\\t%3, a0\;mov\\ta0, %2\;\
2448 srli\\t%3, %3, 30\;slli\\t%0, %1, 2\;ssai\\t2\;src\\t%0, %3, %0"
2449 [(set_attr "type" "multi")
2450 (set_attr "mode" "SI")
2451 (set_attr "length" "24")])
2455 ;; ....................
2459 ;; ....................
2466 (if_then_else (match_operator 2 "boolean_operator"
2467 [(match_operand:CC 0 "register_operand" "b")
2469 (label_ref (match_operand 1 "" ""))
2474 if (GET_CODE (operands[2]) == EQ)
2475 return \"bf\\t%0, %1\";
2477 return \"bt\\t%0, %1\";
2479 [(set_attr "type" "jump")
2480 (set_attr "mode" "none")
2481 (set_attr "length" "3")])
2485 (if_then_else (match_operator 2 "boolean_operator"
2486 [(match_operand:CC 0 "register_operand" "b")
2489 (label_ref (match_operand 1 "" ""))))]
2493 if (GET_CODE (operands[2]) == EQ)
2494 return \"bt\\t%0, %1\";
2496 return \"bf\\t%0, %1\";
2498 [(set_attr "type" "jump")
2499 (set_attr "mode" "none")
2500 (set_attr "length" "3")])