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")])
145 (define_insn "*addx2"
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")])
156 (define_insn "*addx4"
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")])
167 (define_insn "*addx8"
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")])
239 (define_insn "*subx2"
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")])
250 (define_insn "*subx4"
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")])
261 (define_insn "*subx8"
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")])
426 (define_insn "*recipsf2"
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")])
483 (define_insn "*rsqrtsf2"
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")])
1145 (define_insn "*lsiu"
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")])
1162 (define_insn "*ssiu"
1163 [(set (mem:SF (plus:SI (match_operand:SI 0 "register_operand" "+a")
1164 (match_operand:SI 1 "fpmem_offset_operand" "i")))
1165 (match_operand:SF 2 "register_operand" "f"))
1167 (plus:SI (match_dup 0) (match_dup 1)))]
1171 if (TARGET_SERIALIZE_VOLATILE && volatile_refs_p (PATTERN (insn)))
1172 output_asm_insn (\"memw\", operands);
1173 return \"ssiu\\t%2, %0, %1\";
1175 [(set_attr "type" "fstore")
1176 (set_attr "mode" "SF")
1177 (set_attr "length" "3")])
1179 ;; 64-bit floating point moves
1181 (define_expand "movdf"
1182 [(set (match_operand:DF 0 "nonimmed_operand" "")
1183 (match_operand:DF 1 "general_operand" ""))]
1187 if (GET_CODE (operands[1]) == CONST_DOUBLE)
1188 operands[1] = force_const_mem (DFmode, operands[1]);
1190 if (!(reload_in_progress | reload_completed))
1192 if (!register_operand (operands[0], DFmode)
1193 && !register_operand (operands[1], DFmode))
1194 operands[1] = force_reg (DFmode, operands[1]);
1196 if (a7_overlap_mentioned_p (operands[1]))
1198 emit_insn (gen_movdf_internal (operands[0], operands[1]));
1199 emit_insn (gen_set_frame_ptr ());
1205 (define_insn "movdf_internal"
1206 [(set (match_operand:DF 0 "nonimmed_operand" "=D,D,S,a,a,a,U")
1207 (match_operand:DF 1 "non_const_move_operand" "d,S,d,r,T,U,r"))]
1208 "register_operand (operands[0], DFmode)
1209 || register_operand (operands[1], DFmode)"
1212 switch (which_alternative)
1214 case 0: return \"mov.n\\t%0, %1\;mov.n\\t%D0, %D1\";
1215 case 2: return \"%v0s32i.n\\t%1, %0\;s32i.n\\t%D1, %N0\";
1216 case 3: return \"mov\\t%0, %1\;mov\\t%D0, %D1\";
1217 case 6: return \"%v0s32i\\t%1, %0\;s32i\\t%D1, %N0\";
1223 /* Check if the first half of the destination register is used
1224 in the source address. If so, reverse the order of the loads
1225 so that the source address doesn't get clobbered until it is
1226 no longer needed. */
1228 rtx dstreg = operands[0];
1229 if (GET_CODE (dstreg) == SUBREG)
1230 dstreg = SUBREG_REG (dstreg);
1231 if (GET_CODE (dstreg) != REG)
1234 if (reg_mentioned_p (dstreg, operands[1]))
1236 switch (which_alternative)
1238 case 1: return \"%v1l32i.n\\t%D0, %N1\;l32i.n\\t%0, %1\";
1239 case 4: return \"%v1l32r\\t%D0, %N1\;l32r\\t%0, %1\";
1240 case 5: return \"%v1l32i\\t%D0, %N1\;l32i\\t%0, %1\";
1245 switch (which_alternative)
1247 case 1: return \"%v1l32i.n\\t%0, %1\;l32i.n\\t%D0, %N1\";
1248 case 4: return \"%v1l32r\\t%0, %1\;l32r\\t%D0, %N1\";
1249 case 5: return \"%v1l32i\\t%0, %1\;l32i\\t%D0, %N1\";
1257 [(set_attr "type" "move,load,store,move,load,load,store")
1258 (set_attr "mode" "DF")
1259 (set_attr "length" "4,4,4,6,6,6,6")])
1263 (define_expand "movstrsi"
1264 [(parallel [(set (match_operand:BLK 0 "" "")
1265 (match_operand:BLK 1 "" ""))
1266 (use (match_operand:SI 2 "arith_operand" ""))
1267 (use (match_operand:SI 3 "const_int_operand" ""))])]
1271 if (!xtensa_expand_block_move (operands)) FAIL;
1275 (define_insn "movstrsi_internal"
1276 [(set (match_operand:BLK 0 "memory_operand" "=U")
1277 (match_operand:BLK 1 "memory_operand" "U"))
1278 (use (match_operand:SI 2 "arith_operand" ""))
1279 (use (match_operand:SI 3 "const_int_operand" ""))
1280 (clobber (match_scratch:SI 4 "=&r"))
1281 (clobber (match_scratch:SI 5 "=&r"))]
1286 tmpregs[0] = operands[4];
1287 tmpregs[1] = operands[5];
1288 xtensa_emit_block_move (operands, tmpregs, 1);
1291 [(set_attr "type" "multi")
1292 (set_attr "mode" "none")
1293 (set_attr "length" "300")])
1297 ;; ....................
1301 ;; ....................
1304 (define_insn "ashlsi3"
1305 [(set (match_operand:SI 0 "register_operand" "=a,a")
1306 (ashift:SI (match_operand:SI 1 "register_operand" "r,r")
1307 (match_operand:SI 2 "arith_operand" "J,r")))]
1311 ssl\\t%2\;sll\\t%0, %1"
1312 [(set_attr "type" "arith,arith")
1313 (set_attr "mode" "SI")
1314 (set_attr "length" "3,6")])
1316 (define_insn "ashrsi3"
1317 [(set (match_operand:SI 0 "register_operand" "=a,a")
1318 (ashiftrt:SI (match_operand:SI 1 "register_operand" "r,r")
1319 (match_operand:SI 2 "arith_operand" "J,r")))]
1323 ssr\\t%2\;sra\\t%0, %1"
1324 [(set_attr "type" "arith,arith")
1325 (set_attr "mode" "SI")
1326 (set_attr "length" "3,6")])
1328 (define_insn "lshrsi3"
1329 [(set (match_operand:SI 0 "register_operand" "=a,a")
1330 (lshiftrt:SI (match_operand:SI 1 "register_operand" "r,r")
1331 (match_operand:SI 2 "arith_operand" "J,r")))]
1335 if (which_alternative == 0)
1337 if ((INTVAL (operands[2]) & 0x1f) < 16)
1338 return \"srli\\t%0, %1, %R2\";
1340 return \"extui\\t%0, %1, %R2, %L2\";
1342 return \"ssr\\t%2\;srl\\t%0, %1\";
1344 [(set_attr "type" "arith,arith")
1345 (set_attr "mode" "SI")
1346 (set_attr "length" "3,6")])
1348 (define_insn "rotlsi3"
1349 [(set (match_operand:SI 0 "register_operand" "=a,a")
1350 (rotate:SI (match_operand:SI 1 "register_operand" "r,r")
1351 (match_operand:SI 2 "arith_operand" "J,r")))]
1354 ssai\\t%L2\;src\\t%0, %1, %1
1355 ssl\\t%2\;src\\t%0, %1, %1"
1356 [(set_attr "type" "multi,multi")
1357 (set_attr "mode" "SI")
1358 (set_attr "length" "6,6")])
1360 (define_insn "rotrsi3"
1361 [(set (match_operand:SI 0 "register_operand" "=a,a")
1362 (rotatert:SI (match_operand:SI 1 "register_operand" "r,r")
1363 (match_operand:SI 2 "arith_operand" "J,r")))]
1366 ssai\\t%R2\;src\\t%0, %1, %1
1367 ssr\\t%2\;src\\t%0, %1, %1"
1368 [(set_attr "type" "multi,multi")
1369 (set_attr "mode" "SI")
1370 (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
1554 (define_insn "*btrue"
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")])
1608 (define_insn "*bfalse"
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")])
1662 (define_insn "*ubtrue"
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")])
1697 (define_insn "*ubfalse"
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
1734 (define_insn "*bittrue"
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")])
1774 (define_insn "*bitfalse"
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")])
1814 (define_insn "*masktrue"
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")])
1838 (define_insn "*maskfalse"
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 [(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) (const_int -1)))]
1877 [(set_attr "type" "jump")
1878 (set_attr "mode" "none")
1879 (set_attr "length" "3")])
1881 (define_insn "zero_cost_loop_end"
1882 [(set (pc) (if_then_else (ne (reg:SI 19) (const_int 0))
1883 (label_ref (match_operand 0 "" ""))
1886 (plus:SI (reg:SI 19) (const_int -1)))]
1889 xtensa_emit_loop_end (insn, operands);
1892 [(set_attr "type" "jump")
1893 (set_attr "mode" "none")
1894 (set_attr "length" "0")])
1898 ;; ....................
1900 ;; SETTING A REGISTER FROM A COMPARISON
1902 ;; ....................
1905 (define_expand "seq"
1906 [(set (match_operand:SI 0 "register_operand" "")
1911 operands[1] = gen_rtx (EQ, SImode, branch_cmp[0], branch_cmp[1]);
1912 if (!xtensa_expand_scc (operands)) FAIL;
1916 (define_expand "sne"
1917 [(set (match_operand:SI 0 "register_operand" "")
1922 operands[1] = gen_rtx (NE, SImode, branch_cmp[0], branch_cmp[1]);
1923 if (!xtensa_expand_scc (operands)) FAIL;
1927 (define_expand "sgt"
1928 [(set (match_operand:SI 0 "register_operand" "")
1933 operands[1] = gen_rtx (GT, SImode, branch_cmp[0], branch_cmp[1]);
1934 if (!xtensa_expand_scc (operands)) FAIL;
1938 (define_expand "sge"
1939 [(set (match_operand:SI 0 "register_operand" "")
1944 operands[1] = gen_rtx (GE, SImode, branch_cmp[0], branch_cmp[1]);
1945 if (!xtensa_expand_scc (operands)) FAIL;
1949 (define_expand "slt"
1950 [(set (match_operand:SI 0 "register_operand" "")
1955 operands[1] = gen_rtx (LT, SImode, branch_cmp[0], branch_cmp[1]);
1956 if (!xtensa_expand_scc (operands)) FAIL;
1960 (define_expand "sle"
1961 [(set (match_operand:SI 0 "register_operand" "")
1966 operands[1] = gen_rtx (LE, SImode, branch_cmp[0], branch_cmp[1]);
1967 if (!xtensa_expand_scc (operands)) FAIL;
1973 ;; ....................
1975 ;; CONDITIONAL MOVES
1977 ;; ....................
1980 (define_expand "movsicc"
1981 [(set (match_operand:SI 0 "register_operand" "")
1982 (if_then_else:SI (match_operand 1 "comparison_operator" "")
1983 (match_operand:SI 2 "register_operand" "")
1984 (match_operand:SI 3 "register_operand" "")))]
1988 if (!xtensa_expand_conditional_move (operands, 0)) FAIL;
1992 (define_expand "movsfcc"
1993 [(set (match_operand:SF 0 "register_operand" "")
1994 (if_then_else:SF (match_operand 1 "comparison_operator" "")
1995 (match_operand:SF 2 "register_operand" "")
1996 (match_operand:SF 3 "register_operand" "")))]
2000 if (!xtensa_expand_conditional_move (operands, 1)) FAIL;
2004 (define_insn "movsicc_internal0"
2005 [(set (match_operand:SI 0 "register_operand" "=a,a")
2006 (if_then_else:SI (match_operator 4 "branch_operator"
2007 [(match_operand:SI 1 "register_operand" "r,r")
2009 (match_operand:SI 2 "register_operand" "r,0")
2010 (match_operand:SI 3 "register_operand" "0,r")))]
2014 if (which_alternative == 0)
2016 switch (GET_CODE (operands[4]))
2018 case EQ: return \"moveqz\\t%0, %2, %1\";
2019 case NE: return \"movnez\\t%0, %2, %1\";
2020 case LT: return \"movltz\\t%0, %2, %1\";
2021 case GE: return \"movgez\\t%0, %2, %1\";
2027 switch (GET_CODE (operands[4]))
2029 case EQ: return \"movnez\\t%0, %3, %1\";
2030 case NE: return \"moveqz\\t%0, %3, %1\";
2031 case LT: return \"movgez\\t%0, %3, %1\";
2032 case GE: return \"movltz\\t%0, %3, %1\";
2036 fatal_insn (\"unexpected cmov operator\", operands[4]);
2039 [(set_attr "type" "move,move")
2040 (set_attr "mode" "SI")
2041 (set_attr "length" "3,3")])
2043 (define_insn "movsicc_internal1"
2044 [(set (match_operand:SI 0 "register_operand" "=a,a")
2045 (if_then_else:SI (match_operator 4 "boolean_operator"
2046 [(match_operand:CC 1 "register_operand" "b,b")
2048 (match_operand:SI 2 "register_operand" "r,0")
2049 (match_operand:SI 3 "register_operand" "0,r")))]
2053 int isEq = (GET_CODE (operands[4]) == EQ);
2054 switch (which_alternative)
2057 if (isEq) return \"movf\\t%0, %2, %1\";
2058 return \"movt\\t%0, %2, %1\";
2060 if (isEq) return \"movt\\t%0, %3, %1\";
2061 return \"movf\\t%0, %3, %1\";
2066 [(set_attr "type" "move,move")
2067 (set_attr "mode" "SI")
2068 (set_attr "length" "3,3")])
2070 (define_insn "movsfcc_internal0"
2071 [(set (match_operand:SF 0 "register_operand" "=a,a,f,f")
2072 (if_then_else:SF (match_operator 4 "branch_operator"
2073 [(match_operand:SI 1 "register_operand" "r,r,r,r")
2075 (match_operand:SF 2 "register_operand" "r,0,f,0")
2076 (match_operand:SF 3 "register_operand" "0,r,0,f")))]
2080 if (which_alternative == 0)
2082 switch (GET_CODE (operands[4]))
2084 case EQ: return \"moveqz\\t%0, %2, %1\";
2085 case NE: return \"movnez\\t%0, %2, %1\";
2086 case LT: return \"movltz\\t%0, %2, %1\";
2087 case GE: return \"movgez\\t%0, %2, %1\";
2091 else if (which_alternative == 1)
2093 switch (GET_CODE (operands[4]))
2095 case EQ: return \"movnez\\t%0, %3, %1\";
2096 case NE: return \"moveqz\\t%0, %3, %1\";
2097 case LT: return \"movgez\\t%0, %3, %1\";
2098 case GE: return \"movltz\\t%0, %3, %1\";
2102 else if (which_alternative == 2)
2104 switch (GET_CODE (operands[4]))
2106 case EQ: return \"moveqz.s %0, %2, %1\";
2107 case NE: return \"movnez.s %0, %2, %1\";
2108 case LT: return \"movltz.s %0, %2, %1\";
2109 case GE: return \"movgez.s %0, %2, %1\";
2113 else if (which_alternative == 3)
2115 switch (GET_CODE (operands[4]))
2117 case EQ: return \"movnez.s %0, %3, %1\";
2118 case NE: return \"moveqz.s %0, %3, %1\";
2119 case LT: return \"movgez.s %0, %3, %1\";
2120 case GE: return \"movltz.s %0, %3, %1\";
2124 fatal_insn (\"unexpected cmov operator\", operands[4]);
2127 [(set_attr "type" "move,move,move,move")
2128 (set_attr "mode" "SF")
2129 (set_attr "length" "3,3,3,3")])
2131 (define_insn "movsfcc_internal1"
2132 [(set (match_operand:SF 0 "register_operand" "=a,a,f,f")
2133 (if_then_else:SF (match_operator 4 "boolean_operator"
2134 [(match_operand:CC 1 "register_operand" "b,b,b,b")
2136 (match_operand:SF 2 "register_operand" "r,0,f,0")
2137 (match_operand:SF 3 "register_operand" "0,r,0,f")))]
2141 int isEq = (GET_CODE (operands[4]) == EQ);
2142 switch (which_alternative)
2145 if (isEq) return \"movf\\t%0, %2, %1\";
2146 return \"movt\\t%0, %2, %1\";
2148 if (isEq) return \"movt\\t%0, %3, %1\";
2149 return \"movf\\t%0, %3, %1\";
2151 if (isEq) return \"movf.s\\t%0, %2, %1\";
2152 return \"movt.s\\t%0, %2, %1\";
2154 if (isEq) return \"movt.s\\t%0, %3, %1\";
2155 return \"movf.s\\t%0, %3, %1\";
2160 [(set_attr "type" "move,move,move,move")
2161 (set_attr "mode" "SF")
2162 (set_attr "length" "3,3,3,3")])
2166 ;; ....................
2168 ;; FLOATING POINT COMPARISONS
2170 ;; ....................
2173 (define_insn "seq_sf"
2174 [(set (match_operand:CC 0 "register_operand" "=b")
2175 (eq:CC (match_operand:SF 1 "register_operand" "f")
2176 (match_operand:SF 2 "register_operand" "f")))]
2178 "oeq.s\\t%0, %1, %2"
2179 [(set_attr "type" "farith")
2180 (set_attr "mode" "BL")
2181 (set_attr "length" "3")])
2183 (define_insn "slt_sf"
2184 [(set (match_operand:CC 0 "register_operand" "=b")
2185 (lt:CC (match_operand:SF 1 "register_operand" "f")
2186 (match_operand:SF 2 "register_operand" "f")))]
2188 "olt.s\\t%0, %1, %2"
2189 [(set_attr "type" "farith")
2190 (set_attr "mode" "BL")
2191 (set_attr "length" "3")])
2193 (define_insn "sle_sf"
2194 [(set (match_operand:CC 0 "register_operand" "=b")
2195 (le:CC (match_operand:SF 1 "register_operand" "f")
2196 (match_operand:SF 2 "register_operand" "f")))]
2198 "ole.s\\t%0, %1, %2"
2199 [(set_attr "type" "farith")
2200 (set_attr "mode" "BL")
2201 (set_attr "length" "3")])
2205 ;; ....................
2207 ;; UNCONDITIONAL BRANCHES
2209 ;; ....................
2214 (label_ref (match_operand 0 "" "")))]
2217 [(set_attr "type" "jump")
2218 (set_attr "mode" "none")
2219 (set_attr "length" "3")])
2221 (define_expand "indirect_jump"
2222 [(set (pc) (match_operand 0 "register_operand" ""))]
2226 rtx dest = operands[0];
2227 if (GET_CODE (dest) != REG || GET_MODE (dest) != Pmode)
2228 operands[0] = copy_to_mode_reg (Pmode, dest);
2230 emit_jump_insn (gen_indirect_jump_internal (dest));
2234 (define_insn "indirect_jump_internal"
2235 [(set (pc) (match_operand:SI 0 "register_operand" "r"))]
2238 [(set_attr "type" "jump")
2239 (set_attr "mode" "none")
2240 (set_attr "length" "3")])
2243 (define_expand "tablejump"
2244 [(use (match_operand:SI 0 "register_operand" ""))
2245 (use (label_ref (match_operand 1 "" "")))]
2249 rtx target = operands[0];
2252 /* For PIC, the table entry is relative to the start of the table. */
2253 rtx label = gen_reg_rtx (SImode);
2254 target = gen_reg_rtx (SImode);
2255 emit_move_insn (label, gen_rtx_LABEL_REF (SImode, operands[1]));
2256 emit_insn (gen_addsi3 (target, operands[0], label));
2258 emit_jump_insn (gen_tablejump_internal (target, operands[1]));
2262 (define_insn "tablejump_internal"
2264 (match_operand:SI 0 "register_operand" "r"))
2265 (use (label_ref (match_operand 1 "" "")))]
2268 [(set_attr "type" "jump")
2269 (set_attr "mode" "none")
2270 (set_attr "length" "3")])
2274 ;; ....................
2278 ;; ....................
2281 (define_expand "sym_PLT"
2282 [(const (unspec [(match_operand:SI 0 "" "")] UNSPEC_PLT))]
2286 (define_expand "call"
2287 [(call (match_operand 0 "memory_operand" "")
2288 (match_operand 1 "" ""))]
2292 rtx addr = XEXP (operands[0], 0);
2293 if (flag_pic && GET_CODE (addr) == SYMBOL_REF && !SYMBOL_REF_FLAG (addr))
2294 addr = gen_sym_PLT (addr);
2295 if (!call_insn_operand (addr, VOIDmode))
2296 XEXP (operands[0], 0) = copy_to_mode_reg (Pmode, addr);
2299 (define_insn "call_internal"
2300 [(call (mem (match_operand:SI 0 "call_insn_operand" "n,i,r"))
2301 (match_operand 1 "" "i,i,i"))]
2304 return xtensa_emit_call (0, operands);
2306 [(set_attr "type" "call")
2307 (set_attr "mode" "none")
2308 (set_attr "length" "3")])
2310 (define_expand "call_value"
2311 [(set (match_operand 0 "register_operand" "")
2312 (call (match_operand 1 "memory_operand" "")
2313 (match_operand 2 "" "")))]
2317 rtx addr = XEXP (operands[1], 0);
2318 if (flag_pic && GET_CODE (addr) == SYMBOL_REF && !SYMBOL_REF_FLAG (addr))
2319 addr = gen_sym_PLT (addr);
2320 if (!call_insn_operand (addr, VOIDmode))
2321 XEXP (operands[1], 0) = copy_to_mode_reg (Pmode, addr);
2324 ;; cannot combine constraints for operand 0 into "afvb"
2325 ;; reload.c:find_reloads seems to assume that grouped constraints somehow
2326 ;; specify related register classes, and when they don't the constraints
2327 ;; fail to match. By not grouping the constraints, we get the correct
2329 (define_insn "call_value_internal"
2330 [(set (match_operand 0 "register_operand" "=af,af,af,v,v,v,b,b,b")
2331 (call (mem (match_operand:SI 1 "call_insn_operand"
2332 "n,i,r,n,i,r,n,i,r"))
2333 (match_operand 2 "" "i,i,i,i,i,i,i,i,i")))]
2336 return xtensa_emit_call (1, operands);
2338 [(set_attr "type" "call")
2339 (set_attr "mode" "none")
2340 (set_attr "length" "3")])
2342 (define_insn "return"
2344 (use (reg:SI A0_REG))]
2348 return (TARGET_DENSITY ? \"retw.n\" : \"retw\");
2350 [(set_attr "type" "jump")
2351 (set_attr "mode" "none")
2352 (set_attr "length" "2")])
2356 ;; ....................
2360 ;; ....................
2368 return (TARGET_DENSITY ? \"nop.n\" : \"nop\");
2370 [(set_attr "type" "nop")
2371 (set_attr "mode" "none")
2372 (set_attr "length" "3")])
2374 (define_expand "nonlocal_goto"
2375 [(match_operand:SI 0 "general_operand" "")
2376 (match_operand:SI 1 "general_operand" "")
2377 (match_operand:SI 2 "general_operand" "")
2378 (match_operand:SI 3 "" "")]
2382 xtensa_expand_nonlocal_goto (operands);
2386 ;; Setting up a frame pointer is tricky for Xtensa because GCC doesn't
2387 ;; know if a frame pointer is required until the reload pass, and
2388 ;; because there may be an incoming argument value in the hard frame
2389 ;; pointer register (a7). If there is an incoming argument in that
2390 ;; register, the "set_frame_ptr" insn gets inserted immediately after
2391 ;; the insn that copies the incoming argument to a pseudo or to the
2392 ;; stack. This serves several purposes here: (1) it keeps the
2393 ;; optimizer from copy-propagating or scheduling the use of a7 as an
2394 ;; incoming argument away from the beginning of the function; (2) we
2395 ;; can use a post-reload splitter to expand away the insn if a frame
2396 ;; pointer is not required, so that the post-reload scheduler can do
2397 ;; the right thing; and (3) it makes it easy for xtensa_reorg() to
2398 ;; search for this insn to determine whether it should add a new insn
2399 ;; to set up the frame pointer.
2401 (define_insn "set_frame_ptr"
2402 [(unspec_volatile [(const_int 0)] UNSPECV_SET_FP)]
2406 if (frame_pointer_needed)
2407 return \"mov\\ta7, sp\";
2410 [(set_attr "type" "move")
2411 (set_attr "mode" "SI")
2412 (set_attr "length" "3")])
2414 ;; Post-reload splitter to remove fp assignment when it's not needed.
2416 [(unspec_volatile [(const_int 0)] UNSPECV_SET_FP)]
2417 "reload_completed && !frame_pointer_needed"
2418 [(unspec [(const_int 0)] UNSPEC_NOP)]
2421 ;; The preceding splitter needs something to split the insn into;
2422 ;; things start breaking if the result is just a "use" so instead we
2423 ;; generate the following insn.
2424 (define_insn "*unspec_nop"
2425 [(unspec [(const_int 0)] UNSPEC_NOP)]
2428 [(set_attr "type" "nop")
2429 (set_attr "mode" "none")
2430 (set_attr "length" "0")])
2432 ;; The fix_return_addr pattern sets the high 2 bits of an address in a
2433 ;; register to match the high bits of the current PC.
2435 (define_insn "fix_return_addr"
2436 [(set (match_operand:SI 0 "register_operand" "=a")
2437 (unspec:SI [(match_operand:SI 1 "register_operand" "r")]
2439 (clobber (match_scratch:SI 2 "=r"))
2440 (clobber (match_scratch:SI 3 "=r"))]
2442 "mov\\t%2, a0\;call0\\t0f\;.align\\t4\;0:\;mov\\t%3, a0\;mov\\ta0, %2\;\
2443 srli\\t%3, %3, 30\;slli\\t%0, %1, 2\;ssai\\t2\;src\\t%0, %3, %0"
2444 [(set_attr "type" "multi")
2445 (set_attr "mode" "SI")
2446 (set_attr "length" "24")])
2450 ;; ....................
2454 ;; ....................
2459 (define_insn "*booltrue"
2461 (if_then_else (match_operator 2 "boolean_operator"
2462 [(match_operand:CC 0 "register_operand" "b")
2464 (label_ref (match_operand 1 "" ""))
2469 if (GET_CODE (operands[2]) == EQ)
2470 return \"bf\\t%0, %1\";
2472 return \"bt\\t%0, %1\";
2474 [(set_attr "type" "jump")
2475 (set_attr "mode" "none")
2476 (set_attr "length" "3")])
2478 (define_insn "*boolfalse"
2480 (if_then_else (match_operator 2 "boolean_operator"
2481 [(match_operand:CC 0 "register_operand" "b")
2484 (label_ref (match_operand 1 "" ""))))]
2488 if (GET_CODE (operands[2]) == EQ)
2489 return \"bt\\t%0, %1\";
2491 return \"bf\\t%0, %1\";
2493 [(set_attr "type" "jump")
2494 (set_attr "mode" "none")
2495 (set_attr "length" "3")])