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 ;; ....................
45 ;; ....................
49 ;; ....................
53 "unknown,jump,call,load,store,move,arith,multi,nop,farith,fmadd,fdiv,fsqrt,fconv,fload,fstore,mul16,mul32,div32,mac16,rsr,wsr"
54 (const_string "unknown"))
57 "unknown,none,QI,HI,SI,DI,SF,DF,BL"
58 (const_string "unknown"))
60 (define_attr "length" "" (const_int 1))
62 ;; Describe a user's asm statement.
63 (define_asm_attributes
64 [(set_attr "type" "multi")])
68 ;; ....................
72 ;; ....................
75 (define_function_unit "memory" 1 0 (eq_attr "type" "load,fload") 2 0)
77 (define_function_unit "sreg" 1 1 (eq_attr "type" "rsr") 2 0)
79 (define_function_unit "mul16" 1 0 (eq_attr "type" "mul16") 2 0)
81 (define_function_unit "mul32" 1 0 (eq_attr "type" "mul32") 2 0)
83 (define_function_unit "fpmadd" 1 0 (eq_attr "type" "fmadd") 4 0)
85 (define_function_unit "fpconv" 1 0 (eq_attr "type" "fconv") 2 0)
89 ;; ....................
93 ;; ....................
96 (define_expand "adddi3"
97 [(set (match_operand:DI 0 "register_operand" "")
98 (plus:DI (match_operand:DI 1 "register_operand" "")
99 (match_operand:DI 2 "register_operand" "")))]
104 rtx dstlo = gen_lowpart (SImode, operands[0]);
105 rtx src1lo = gen_lowpart (SImode, operands[1]);
106 rtx src2lo = gen_lowpart (SImode, operands[2]);
108 rtx dsthi = gen_highpart (SImode, operands[0]);
109 rtx src1hi = gen_highpart (SImode, operands[1]);
110 rtx src2hi = gen_highpart (SImode, operands[2]);
112 /* Either source can be used for overflow checking, as long as it's
113 not clobbered by the first addition. */
114 if (!rtx_equal_p (dstlo, src1lo))
116 else if (!rtx_equal_p (dstlo, src2lo))
120 srclo = gen_reg_rtx (SImode);
121 emit_move_insn (srclo, src1lo);
124 emit_insn (gen_addsi3 (dstlo, src1lo, src2lo));
125 emit_insn (gen_addsi3 (dsthi, src1hi, src2hi));
126 emit_insn (gen_adddi_carry (dsthi, dstlo, srclo));
130 ;; Represent the add-carry operation as an atomic operation instead of
131 ;; expanding it to a conditional branch. Otherwise, the edge
132 ;; profiling code breaks because inserting the count increment code
133 ;; causes a new jump insn to be added.
135 (define_insn "adddi_carry"
136 [(set (match_operand:SI 0 "register_operand" "+a")
137 (plus:SI (ltu:SI (match_operand:SI 1 "register_operand" "r")
138 (match_operand:SI 2 "register_operand" "r"))
141 "bgeu\\t%1, %2, 0f\;addi\\t%0, %0, 1\;0:"
142 [(set_attr "type" "multi")
143 (set_attr "mode" "SI")
144 (set_attr "length" "6")])
146 (define_insn "addsi3"
147 [(set (match_operand:SI 0 "register_operand" "=D,D,a,a,a")
148 (plus:SI (match_operand:SI 1 "register_operand" "%d,d,r,r,r")
149 (match_operand:SI 2 "add_operand" "d,O,r,J,N")))]
157 [(set_attr "type" "arith,arith,arith,arith,arith")
158 (set_attr "mode" "SI")
159 (set_attr "length" "2,2,3,3,3")])
161 (define_insn "*addx2"
162 [(set (match_operand:SI 0 "register_operand" "=a")
163 (plus:SI (mult:SI (match_operand:SI 1 "register_operand" "r")
165 (match_operand:SI 2 "register_operand" "r")))]
168 [(set_attr "type" "arith")
169 (set_attr "mode" "SI")
170 (set_attr "length" "3")])
172 (define_insn "*addx4"
173 [(set (match_operand:SI 0 "register_operand" "=a")
174 (plus:SI (mult:SI (match_operand:SI 1 "register_operand" "r")
176 (match_operand:SI 2 "register_operand" "r")))]
179 [(set_attr "type" "arith")
180 (set_attr "mode" "SI")
181 (set_attr "length" "3")])
183 (define_insn "*addx8"
184 [(set (match_operand:SI 0 "register_operand" "=a")
185 (plus:SI (mult:SI (match_operand:SI 1 "register_operand" "r")
187 (match_operand:SI 2 "register_operand" "r")))]
190 [(set_attr "type" "arith")
191 (set_attr "mode" "SI")
192 (set_attr "length" "3")])
194 (define_insn "addsf3"
195 [(set (match_operand:SF 0 "register_operand" "=f")
196 (plus:SF (match_operand:SF 1 "register_operand" "%f")
197 (match_operand:SF 2 "register_operand" "f")))]
200 [(set_attr "type" "fmadd")
201 (set_attr "mode" "SF")
202 (set_attr "length" "3")])
206 ;; ....................
210 ;; ....................
213 (define_expand "subdi3"
214 [(set (match_operand:DI 0 "register_operand" "")
215 (minus:DI (match_operand:DI 1 "register_operand" "")
216 (match_operand:DI 2 "register_operand" "")))]
220 rtx dstlo = gen_lowpart (SImode, operands[0]);
221 rtx src1lo = gen_lowpart (SImode, operands[1]);
222 rtx src2lo = gen_lowpart (SImode, operands[2]);
224 rtx dsthi = gen_highpart (SImode, operands[0]);
225 rtx src1hi = gen_highpart (SImode, operands[1]);
226 rtx src2hi = gen_highpart (SImode, operands[2]);
228 emit_insn (gen_subsi3 (dsthi, src1hi, src2hi));
229 emit_insn (gen_subdi_carry (dsthi, src1lo, src2lo));
230 emit_insn (gen_subsi3 (dstlo, src1lo, src2lo));
234 (define_insn "subdi_carry"
235 [(set (match_operand:SI 0 "register_operand" "+a")
236 (minus:SI (match_dup 0)
237 (ltu:SI (match_operand:SI 1 "register_operand" "r")
238 (match_operand:SI 2 "register_operand" "r"))))]
240 "bgeu\\t%1, %2, 0f\;addi\\t%0, %0, -1\;0:"
241 [(set_attr "type" "multi")
242 (set_attr "mode" "SI")
243 (set_attr "length" "6")])
245 (define_insn "subsi3"
246 [(set (match_operand:SI 0 "register_operand" "=a")
247 (minus:SI (match_operand:SI 1 "register_operand" "r")
248 (match_operand:SI 2 "register_operand" "r")))]
251 [(set_attr "type" "arith")
252 (set_attr "mode" "SI")
253 (set_attr "length" "3")])
255 (define_insn "*subx2"
256 [(set (match_operand:SI 0 "register_operand" "=a")
257 (minus:SI (mult:SI (match_operand:SI 1 "register_operand" "r")
259 (match_operand:SI 2 "register_operand" "r")))]
262 [(set_attr "type" "arith")
263 (set_attr "mode" "SI")
264 (set_attr "length" "3")])
266 (define_insn "*subx4"
267 [(set (match_operand:SI 0 "register_operand" "=a")
268 (minus:SI (mult:SI (match_operand:SI 1 "register_operand" "r")
270 (match_operand:SI 2 "register_operand" "r")))]
273 [(set_attr "type" "arith")
274 (set_attr "mode" "SI")
275 (set_attr "length" "3")])
277 (define_insn "*subx8"
278 [(set (match_operand:SI 0 "register_operand" "=a")
279 (minus:SI (mult:SI (match_operand:SI 1 "register_operand" "r")
281 (match_operand:SI 2 "register_operand" "r")))]
284 [(set_attr "type" "arith")
285 (set_attr "mode" "SI")
286 (set_attr "length" "3")])
288 (define_insn "subsf3"
289 [(set (match_operand:SF 0 "register_operand" "=f")
290 (minus:SF (match_operand:SF 1 "register_operand" "f")
291 (match_operand:SF 2 "register_operand" "f")))]
294 [(set_attr "type" "fmadd")
295 (set_attr "mode" "SF")
296 (set_attr "length" "3")])
300 ;; ....................
304 ;; ....................
307 (define_insn "mulsi3"
308 [(set (match_operand:SI 0 "register_operand" "=a")
309 (mult:SI (match_operand:SI 1 "register_operand" "%r")
310 (match_operand:SI 2 "register_operand" "r")))]
313 [(set_attr "type" "mul32")
314 (set_attr "mode" "SI")
315 (set_attr "length" "3")])
317 (define_insn "mulhisi3"
318 [(set (match_operand:SI 0 "register_operand" "=C,A")
319 (mult:SI (sign_extend:SI
320 (match_operand:HI 1 "register_operand" "%r,r"))
322 (match_operand:HI 2 "register_operand" "r,r"))))]
323 "TARGET_MUL16 || TARGET_MAC16"
327 [(set_attr "type" "mul16,mac16")
328 (set_attr "mode" "SI")
329 (set_attr "length" "3,3")])
331 (define_insn "umulhisi3"
332 [(set (match_operand:SI 0 "register_operand" "=C,A")
333 (mult:SI (zero_extend:SI
334 (match_operand:HI 1 "register_operand" "%r,r"))
336 (match_operand:HI 2 "register_operand" "r,r"))))]
337 "TARGET_MUL16 || TARGET_MAC16"
341 [(set_attr "type" "mul16,mac16")
342 (set_attr "mode" "SI")
343 (set_attr "length" "3,3")])
345 (define_insn "muladdhisi"
346 [(set (match_operand:SI 0 "register_operand" "=A")
347 (plus:SI (mult:SI (sign_extend:SI
348 (match_operand:HI 1 "register_operand" "%r"))
350 (match_operand:HI 2 "register_operand" "r")))
351 (match_operand:SI 3 "register_operand" "0")))]
353 "mula.aa.ll\\t%1, %2"
354 [(set_attr "type" "mac16")
355 (set_attr "mode" "SI")
356 (set_attr "length" "3")])
358 (define_insn "mulsubhisi"
359 [(set (match_operand:SI 0 "register_operand" "=A")
360 (minus:SI (match_operand:SI 1 "register_operand" "0")
361 (mult:SI (sign_extend:SI
362 (match_operand:HI 2 "register_operand" "%r"))
364 (match_operand:HI 3 "register_operand" "r")))))]
366 "muls.aa.ll\\t%2, %3"
367 [(set_attr "type" "mac16")
368 (set_attr "mode" "SI")
369 (set_attr "length" "3")])
371 (define_insn "mulsf3"
372 [(set (match_operand:SF 0 "register_operand" "=f")
373 (mult:SF (match_operand:SF 1 "register_operand" "%f")
374 (match_operand:SF 2 "register_operand" "f")))]
377 [(set_attr "type" "fmadd")
378 (set_attr "mode" "SF")
379 (set_attr "length" "3")])
381 (define_insn "muladdsf3"
382 [(set (match_operand:SF 0 "register_operand" "=f")
383 (plus:SF (mult:SF (match_operand:SF 1 "register_operand" "%f")
384 (match_operand:SF 2 "register_operand" "f"))
385 (match_operand:SF 3 "register_operand" "0")))]
386 "TARGET_HARD_FLOAT && !TARGET_NO_FUSED_MADD"
387 "madd.s\\t%0, %1, %2"
388 [(set_attr "type" "fmadd")
389 (set_attr "mode" "SF")
390 (set_attr "length" "3")])
392 (define_insn "mulsubsf3"
393 [(set (match_operand:SF 0 "register_operand" "=f")
394 (minus:SF (match_operand:SF 1 "register_operand" "0")
395 (mult:SF (match_operand:SF 2 "register_operand" "%f")
396 (match_operand:SF 3 "register_operand" "f"))))]
397 "TARGET_HARD_FLOAT && !TARGET_NO_FUSED_MADD"
398 "msub.s\\t%0, %2, %3"
399 [(set_attr "type" "fmadd")
400 (set_attr "mode" "SF")
401 (set_attr "length" "3")])
405 ;; ....................
409 ;; ....................
412 (define_insn "divsi3"
413 [(set (match_operand:SI 0 "register_operand" "=a")
414 (div:SI (match_operand:SI 1 "register_operand" "r")
415 (match_operand:SI 2 "register_operand" "r")))]
418 [(set_attr "type" "div32")
419 (set_attr "mode" "SI")
420 (set_attr "length" "3")])
422 (define_insn "udivsi3"
423 [(set (match_operand:SI 0 "register_operand" "=a")
424 (udiv:SI (match_operand:SI 1 "register_operand" "r")
425 (match_operand:SI 2 "register_operand" "r")))]
428 [(set_attr "type" "div32")
429 (set_attr "mode" "SI")
430 (set_attr "length" "3")])
432 (define_insn "divsf3"
433 [(set (match_operand:SF 0 "register_operand" "=f")
434 (div:SF (match_operand:SF 1 "register_operand" "f")
435 (match_operand:SF 2 "register_operand" "f")))]
436 "TARGET_HARD_FLOAT_DIV"
438 [(set_attr "type" "fdiv")
439 (set_attr "mode" "SF")
440 (set_attr "length" "3")])
442 (define_insn "*recipsf2"
443 [(set (match_operand:SF 0 "register_operand" "=f")
444 (div:SF (match_operand:SF 1 "const_float_1_operand" "")
445 (match_operand:SF 2 "register_operand" "f")))]
446 "TARGET_HARD_FLOAT_RECIP && flag_unsafe_math_optimizations"
448 [(set_attr "type" "fdiv")
449 (set_attr "mode" "SF")
450 (set_attr "length" "3")])
454 ;; ....................
458 ;; ....................
461 (define_insn "modsi3"
462 [(set (match_operand:SI 0 "register_operand" "=a")
463 (mod:SI (match_operand:SI 1 "register_operand" "r")
464 (match_operand:SI 2 "register_operand" "r")))]
467 [(set_attr "type" "div32")
468 (set_attr "mode" "SI")
469 (set_attr "length" "3")])
471 (define_insn "umodsi3"
472 [(set (match_operand:SI 0 "register_operand" "=a")
473 (umod:SI (match_operand:SI 1 "register_operand" "r")
474 (match_operand:SI 2 "register_operand" "r")))]
477 [(set_attr "type" "div32")
478 (set_attr "mode" "SI")
479 (set_attr "length" "3")])
483 ;; ....................
487 ;; ....................
490 (define_insn "sqrtsf2"
491 [(set (match_operand:SF 0 "register_operand" "=f")
492 (sqrt:SF (match_operand:SF 1 "register_operand" "f")))]
493 "TARGET_HARD_FLOAT_SQRT"
495 [(set_attr "type" "fsqrt")
496 (set_attr "mode" "SF")
497 (set_attr "length" "3")])
499 (define_insn "*rsqrtsf2"
500 [(set (match_operand:SF 0 "register_operand" "=f")
501 (div:SF (match_operand:SF 1 "const_float_1_operand" "")
502 (sqrt:SF (match_operand:SF 2 "register_operand" "f"))))]
503 "TARGET_HARD_FLOAT_RSQRT && flag_unsafe_math_optimizations"
505 [(set_attr "type" "fsqrt")
506 (set_attr "mode" "SF")
507 (set_attr "length" "3")])
511 ;; ....................
515 ;; ....................
518 (define_insn "abssi2"
519 [(set (match_operand:SI 0 "register_operand" "=a")
520 (abs:SI (match_operand:SI 1 "register_operand" "r")))]
523 [(set_attr "type" "arith")
524 (set_attr "mode" "SI")
525 (set_attr "length" "3")])
527 (define_insn "abssf2"
528 [(set (match_operand:SF 0 "register_operand" "=f")
529 (abs:SF (match_operand:SF 1 "register_operand" "f")))]
532 [(set_attr "type" "farith")
533 (set_attr "mode" "SF")
534 (set_attr "length" "3")])
538 ;; ....................
540 ;; MIN AND MAX INSTRUCTIONS
542 ;; ....................
545 (define_insn "sminsi3"
546 [(set (match_operand:SI 0 "register_operand" "=a")
547 (smin:SI (match_operand:SI 1 "register_operand" "%r")
548 (match_operand:SI 2 "register_operand" "r")))]
551 [(set_attr "type" "arith")
552 (set_attr "mode" "SI")
553 (set_attr "length" "3")])
555 (define_insn "uminsi3"
556 [(set (match_operand:SI 0 "register_operand" "=a")
557 (umin:SI (match_operand:SI 1 "register_operand" "%r")
558 (match_operand:SI 2 "register_operand" "r")))]
561 [(set_attr "type" "arith")
562 (set_attr "mode" "SI")
563 (set_attr "length" "3")])
565 (define_insn "smaxsi3"
566 [(set (match_operand:SI 0 "register_operand" "=a")
567 (smax:SI (match_operand:SI 1 "register_operand" "%r")
568 (match_operand:SI 2 "register_operand" "r")))]
571 [(set_attr "type" "arith")
572 (set_attr "mode" "SI")
573 (set_attr "length" "3")])
575 (define_insn "umaxsi3"
576 [(set (match_operand:SI 0 "register_operand" "=a")
577 (umax:SI (match_operand:SI 1 "register_operand" "%r")
578 (match_operand:SI 2 "register_operand" "r")))]
581 [(set_attr "type" "arith")
582 (set_attr "mode" "SI")
583 (set_attr "length" "3")])
587 ;; ....................
589 ;; FIND FIRST BIT INSTRUCTION
591 ;; ....................
594 (define_expand "ffssi2"
595 [(set (match_operand:SI 0 "register_operand" "")
596 (ffs:SI (match_operand:SI 1 "register_operand" "")))]
600 rtx temp = gen_reg_rtx (SImode);
601 emit_insn (gen_negsi2 (temp, operands[1]));
602 emit_insn (gen_andsi3 (temp, temp, operands[1]));
603 emit_insn (gen_nsau (temp, temp));
604 emit_insn (gen_negsi2 (temp, temp));
605 emit_insn (gen_addsi3 (operands[0], temp, GEN_INT (32)));
609 ;; there is no RTL operator corresponding to NSAU
611 [(set (match_operand:SI 0 "register_operand" "=a")
612 (unspec:SI [(match_operand:SI 1 "register_operand" "r")] UNSPEC_NSAU))]
615 [(set_attr "type" "arith")
616 (set_attr "mode" "SI")
617 (set_attr "length" "3")])
621 ;; ....................
623 ;; NEGATION and ONE'S COMPLEMENT
625 ;; ....................
628 (define_insn "negsi2"
629 [(set (match_operand:SI 0 "register_operand" "=a")
630 (neg:SI (match_operand:SI 1 "register_operand" "r")))]
633 [(set_attr "type" "arith")
634 (set_attr "mode" "SI")
635 (set_attr "length" "3")])
637 (define_expand "one_cmplsi2"
638 [(set (match_operand:SI 0 "register_operand" "")
639 (not:SI (match_operand:SI 1 "register_operand" "")))]
643 rtx temp = gen_reg_rtx (SImode);
644 emit_insn (gen_movsi (temp, constm1_rtx));
645 emit_insn (gen_xorsi3 (operands[0], temp, operands[1]));
649 (define_insn "negsf2"
650 [(set (match_operand:SF 0 "register_operand" "=f")
651 (neg:SF (match_operand:SF 1 "register_operand" "f")))]
654 [(set_attr "type" "farith")
655 (set_attr "mode" "SF")
656 (set_attr "length" "3")])
660 ;; ....................
664 ;; ....................
667 (define_insn "andsi3"
668 [(set (match_operand:SI 0 "register_operand" "=a,a")
669 (and:SI (match_operand:SI 1 "register_operand" "%r,r")
670 (match_operand:SI 2 "mask_operand" "P,r")))]
673 extui\\t%0, %1, 0, %K2
675 [(set_attr "type" "arith,arith")
676 (set_attr "mode" "SI")
677 (set_attr "length" "3,3")])
679 (define_insn "iorsi3"
680 [(set (match_operand:SI 0 "register_operand" "=a")
681 (ior:SI (match_operand:SI 1 "register_operand" "%r")
682 (match_operand:SI 2 "register_operand" "r")))]
685 [(set_attr "type" "arith")
686 (set_attr "mode" "SI")
687 (set_attr "length" "3")])
689 (define_insn "xorsi3"
690 [(set (match_operand:SI 0 "register_operand" "=a")
691 (xor:SI (match_operand:SI 1 "register_operand" "%r")
692 (match_operand:SI 2 "register_operand" "r")))]
695 [(set_attr "type" "arith")
696 (set_attr "mode" "SI")
697 (set_attr "length" "3")])
701 ;; ....................
705 ;; ....................
708 (define_insn "zero_extendhisi2"
709 [(set (match_operand:SI 0 "register_operand" "=a,a")
710 (zero_extend:SI (match_operand:HI 1 "nonimmed_operand" "r,U")))]
713 extui\\t%0, %1, 0, 16
715 [(set_attr "type" "arith,load")
716 (set_attr "mode" "SI")
717 (set_attr "length" "3,3")])
719 (define_insn "zero_extendqisi2"
720 [(set (match_operand:SI 0 "register_operand" "=a,a")
721 (zero_extend:SI (match_operand:QI 1 "nonimmed_operand" "r,U")))]
726 [(set_attr "type" "arith,load")
727 (set_attr "mode" "SI")
728 (set_attr "length" "3,3")])
732 ;; ....................
736 ;; ....................
739 (define_expand "extendhisi2"
740 [(set (match_operand:SI 0 "register_operand" "")
741 (sign_extend:SI (match_operand:HI 1 "register_operand" "")))]
745 if (sext_operand (operands[1], HImode))
746 emit_insn (gen_extendhisi2_internal (operands[0], operands[1]));
748 xtensa_extend_reg (operands[0], operands[1]);
752 (define_insn "extendhisi2_internal"
753 [(set (match_operand:SI 0 "register_operand" "=B,a")
754 (sign_extend:SI (match_operand:HI 1 "sext_operand" "r,U")))]
759 [(set_attr "type" "arith,load")
760 (set_attr "mode" "SI")
761 (set_attr "length" "3,3")])
763 (define_expand "extendqisi2"
764 [(set (match_operand:SI 0 "register_operand" "")
765 (sign_extend:SI (match_operand:QI 1 "register_operand" "")))]
771 emit_insn (gen_extendqisi2_internal (operands[0], operands[1]));
774 xtensa_extend_reg (operands[0], operands[1]);
778 (define_insn "extendqisi2_internal"
779 [(set (match_operand:SI 0 "register_operand" "=B")
780 (sign_extend:SI (match_operand:QI 1 "register_operand" "r")))]
783 [(set_attr "type" "arith")
784 (set_attr "mode" "SI")
785 (set_attr "length" "3")])
789 ;; ....................
793 ;; ....................
796 (define_expand "extv"
797 [(set (match_operand:SI 0 "register_operand" "")
798 (sign_extract:SI (match_operand:SI 1 "register_operand" "")
799 (match_operand:SI 2 "const_int_operand" "")
800 (match_operand:SI 3 "const_int_operand" "")))]
804 if (!sext_fldsz_operand (operands[2], SImode)) FAIL;
805 /* we could expand to a right shift followed by sext but that's
806 no better than the standard left and right shift sequence */
807 if (!lsbitnum_operand (operands[3], SImode)) FAIL;
808 emit_insn (gen_extv_internal (operands[0], operands[1],
809 operands[2], operands[3]));
813 (define_insn "extv_internal"
814 [(set (match_operand:SI 0 "register_operand" "=a")
815 (sign_extract:SI (match_operand:SI 1 "register_operand" "r")
816 (match_operand:SI 2 "sext_fldsz_operand" "i")
817 (match_operand:SI 3 "lsbitnum_operand" "i")))]
821 int fldsz = INTVAL (operands[2]);
822 operands[2] = GEN_INT (fldsz - 1);
823 return \"sext\\t%0, %1, %2\";
825 [(set_attr "type" "arith")
826 (set_attr "mode" "SI")
827 (set_attr "length" "3")])
829 (define_expand "extzv"
830 [(set (match_operand:SI 0 "register_operand" "")
831 (zero_extract:SI (match_operand:SI 1 "register_operand" "")
832 (match_operand:SI 2 "const_int_operand" "")
833 (match_operand:SI 3 "const_int_operand" "")))]
837 if (!extui_fldsz_operand (operands[2], SImode)) FAIL;
838 emit_insn (gen_extzv_internal (operands[0], operands[1],
839 operands[2], operands[3]));
843 (define_insn "extzv_internal"
844 [(set (match_operand:SI 0 "register_operand" "=a")
845 (zero_extract:SI (match_operand:SI 1 "register_operand" "r")
846 (match_operand:SI 2 "extui_fldsz_operand" "i")
847 (match_operand:SI 3 "const_int_operand" "i")))]
853 shift = (32 - (INTVAL (operands[2]) + INTVAL (operands[3]))) & 0x1f;
855 shift = INTVAL (operands[3]) & 0x1f;
856 operands[3] = GEN_INT (shift);
857 return \"extui\\t%0, %1, %3, %2\";
859 [(set_attr "type" "arith")
860 (set_attr "mode" "SI")
861 (set_attr "length" "3")])
865 ;; ....................
869 ;; ....................
872 (define_insn "fix_truncsfsi2"
873 [(set (match_operand:SI 0 "register_operand" "=a")
874 (fix:SI (match_operand:SF 1 "register_operand" "f")))]
876 "trunc.s\\t%0, %1, 0"
877 [(set_attr "type" "fconv")
878 (set_attr "mode" "SF")
879 (set_attr "length" "3")])
881 (define_insn "fixuns_truncsfsi2"
882 [(set (match_operand:SI 0 "register_operand" "=a")
883 (unsigned_fix:SI (match_operand:SF 1 "register_operand" "f")))]
886 [(set_attr "type" "fconv")
887 (set_attr "mode" "SF")
888 (set_attr "length" "3")])
890 (define_insn "floatsisf2"
891 [(set (match_operand:SF 0 "register_operand" "=f")
892 (float:SF (match_operand:SI 1 "register_operand" "a")))]
894 "float.s\\t%0, %1, 0"
895 [(set_attr "type" "fconv")
896 (set_attr "mode" "SF")
897 (set_attr "length" "3")])
899 (define_insn "floatunssisf2"
900 [(set (match_operand:SF 0 "register_operand" "=f")
901 (unsigned_float:SF (match_operand:SI 1 "register_operand" "a")))]
904 [(set_attr "type" "fconv")
905 (set_attr "mode" "SF")
906 (set_attr "length" "3")])
910 ;; ....................
914 ;; ....................
917 ;; 64-bit Integer moves
919 (define_expand "movdi"
920 [(set (match_operand:DI 0 "nonimmed_operand" "")
921 (match_operand:DI 1 "general_operand" ""))]
925 if (CONSTANT_P (operands[1]) && !TARGET_CONST16)
926 operands[1] = force_const_mem (DImode, operands[1]);
928 if (!register_operand (operands[0], DImode)
929 && !register_operand (operands[1], DImode))
930 operands[1] = force_reg (DImode, operands[1]);
932 if (xtensa_copy_incoming_a7 (operands, DImode))
936 (define_insn_and_split "movdi_internal"
937 [(set (match_operand:DI 0 "nonimmed_operand" "=a,W,a,a,U")
938 (match_operand:DI 1 "move_operand" "r,i,T,U,r"))]
939 "register_operand (operands[0], DImode)
940 || register_operand (operands[1], DImode)"
943 [(set (match_dup 0) (match_dup 2))
944 (set (match_dup 1) (match_dup 3))]
946 xtensa_split_operand_pair (operands, SImode);
947 if (reg_overlap_mentioned_p (operands[0], operands[3]))
950 tmp = operands[0], operands[0] = operands[1], operands[1] = tmp;
951 tmp = operands[2], operands[2] = operands[3], operands[3] = tmp;
956 ;; 32-bit Integer moves
958 (define_expand "movsi"
959 [(set (match_operand:SI 0 "nonimmed_operand" "")
960 (match_operand:SI 1 "general_operand" ""))]
964 if (xtensa_emit_move_sequence (operands, SImode))
968 (define_insn "movsi_internal"
969 [(set (match_operand:SI 0 "nonimmed_operand" "=D,D,D,D,R,R,a,q,a,W,a,a,U,*a,*A")
970 (match_operand:SI 1 "move_operand" "M,D,d,R,D,d,r,r,I,i,T,U,r,*A,*r"))]
971 "xtensa_valid_move (SImode, operands)"
982 const16\\t%0, %t1\;const16\\t%0, %b1
987 wsr\\t%1, 16 # ACCLO"
988 [(set_attr "type" "move,move,move,load,store,store,move,move,move,move,load,load,store,rsr,wsr")
989 (set_attr "mode" "SI")
990 (set_attr "length" "2,2,2,2,2,2,3,3,3,6,3,3,3,3,3")])
992 ;; 16-bit Integer moves
994 (define_expand "movhi"
995 [(set (match_operand:HI 0 "nonimmed_operand" "")
996 (match_operand:HI 1 "general_operand" ""))]
1000 if (xtensa_emit_move_sequence (operands, HImode))
1004 (define_insn "movhi_internal"
1005 [(set (match_operand:HI 0 "nonimmed_operand" "=D,D,a,a,a,U,*a,*A")
1006 (match_operand:HI 1 "move_operand" "M,d,r,I,U,r,*A,*r"))]
1007 "xtensa_valid_move (HImode, operands)"
1015 rsr\\t%0, 16 # ACCLO
1016 wsr\\t%1, 16 # ACCLO"
1017 [(set_attr "type" "move,move,move,move,load,store,rsr,wsr")
1018 (set_attr "mode" "HI")
1019 (set_attr "length" "2,2,3,3,3,3,3,3")])
1021 ;; 8-bit Integer moves
1023 (define_expand "movqi"
1024 [(set (match_operand:QI 0 "nonimmed_operand" "")
1025 (match_operand:QI 1 "general_operand" ""))]
1029 if (xtensa_emit_move_sequence (operands, QImode))
1033 (define_insn "movqi_internal"
1034 [(set (match_operand:QI 0 "nonimmed_operand" "=D,D,a,a,a,U,*a,*A")
1035 (match_operand:QI 1 "move_operand" "M,d,r,I,U,r,*A,*r"))]
1036 "xtensa_valid_move (QImode, operands)"
1044 rsr\\t%0, 16 # ACCLO
1045 wsr\\t%1, 16 # ACCLO"
1046 [(set_attr "type" "move,move,move,move,load,store,rsr,wsr")
1047 (set_attr "mode" "QI")
1048 (set_attr "length" "2,2,3,3,3,3,3,3")])
1050 ;; 32-bit floating point moves
1052 (define_expand "movsf"
1053 [(set (match_operand:SF 0 "nonimmed_operand" "")
1054 (match_operand:SF 1 "general_operand" ""))]
1058 if (!TARGET_CONST16 && CONSTANT_P (operands[1]))
1059 operands[1] = force_const_mem (SFmode, operands[1]);
1061 if (!(reload_in_progress | reload_completed))
1063 if ((!register_operand (operands[0], SFmode)
1064 && !register_operand (operands[1], SFmode))
1065 || (FP_REG_P (xt_true_regnum (operands[0]))
1066 && (constantpool_mem_p (operands[1])
1067 || CONSTANT_P (operands[1]))))
1068 operands[1] = force_reg (SFmode, operands[1]);
1070 if (xtensa_copy_incoming_a7 (operands, SFmode))
1075 (define_insn "movsf_internal"
1076 [(set (match_operand:SF 0 "nonimmed_operand" "=f,f,U,D,D,R,a,f,a,W,a,a,U")
1077 (match_operand:SF 1 "move_operand" "f,U,f,d,R,d,r,r,f,iF,T,U,r"))]
1078 "((register_operand (operands[0], SFmode)
1079 || register_operand (operands[1], SFmode))
1080 && !(FP_REG_P (xt_true_regnum (operands[0]))
1081 && (constantpool_mem_p (operands[1]) || CONSTANT_P (operands[1]))))"
1092 const16\\t%0, %t1\;const16\\t%0, %b1
1096 [(set_attr "type" "farith,fload,fstore,move,load,store,move,farith,farith,move,load,load,store")
1097 (set_attr "mode" "SF")
1098 (set_attr "length" "3,3,3,2,2,2,3,3,3,6,3,3,3")])
1100 (define_insn "*lsiu"
1101 [(set (match_operand:SF 0 "register_operand" "=f")
1102 (mem:SF (plus:SI (match_operand:SI 1 "register_operand" "+a")
1103 (match_operand:SI 2 "fpmem_offset_operand" "i"))))
1105 (plus:SI (match_dup 1) (match_dup 2)))]
1109 if (volatile_refs_p (PATTERN (insn)))
1110 output_asm_insn (\"memw\", operands);
1111 return \"lsiu\\t%0, %1, %2\";
1113 [(set_attr "type" "fload")
1114 (set_attr "mode" "SF")
1115 (set_attr "length" "3")])
1117 (define_insn "*ssiu"
1118 [(set (mem:SF (plus:SI (match_operand:SI 0 "register_operand" "+a")
1119 (match_operand:SI 1 "fpmem_offset_operand" "i")))
1120 (match_operand:SF 2 "register_operand" "f"))
1122 (plus:SI (match_dup 0) (match_dup 1)))]
1126 if (volatile_refs_p (PATTERN (insn)))
1127 output_asm_insn (\"memw\", operands);
1128 return \"ssiu\\t%2, %0, %1\";
1130 [(set_attr "type" "fstore")
1131 (set_attr "mode" "SF")
1132 (set_attr "length" "3")])
1134 ;; 64-bit floating point moves
1136 (define_expand "movdf"
1137 [(set (match_operand:DF 0 "nonimmed_operand" "")
1138 (match_operand:DF 1 "general_operand" ""))]
1142 if (CONSTANT_P (operands[1]) && !TARGET_CONST16)
1143 operands[1] = force_const_mem (DFmode, operands[1]);
1145 if (!register_operand (operands[0], DFmode)
1146 && !register_operand (operands[1], DFmode))
1147 operands[1] = force_reg (DFmode, operands[1]);
1149 if (xtensa_copy_incoming_a7 (operands, DFmode))
1153 (define_insn_and_split "movdf_internal"
1154 [(set (match_operand:DF 0 "nonimmed_operand" "=a,W,a,a,U")
1155 (match_operand:DF 1 "move_operand" "r,iF,T,U,r"))]
1156 "register_operand (operands[0], DFmode)
1157 || register_operand (operands[1], DFmode)"
1160 [(set (match_dup 0) (match_dup 2))
1161 (set (match_dup 1) (match_dup 3))]
1163 xtensa_split_operand_pair (operands, SFmode);
1164 if (reg_overlap_mentioned_p (operands[0], operands[3]))
1167 tmp = operands[0], operands[0] = operands[1], operands[1] = tmp;
1168 tmp = operands[2], operands[2] = operands[3], operands[3] = tmp;
1175 (define_expand "movstrsi"
1176 [(parallel [(set (match_operand:BLK 0 "" "")
1177 (match_operand:BLK 1 "" ""))
1178 (use (match_operand:SI 2 "arith_operand" ""))
1179 (use (match_operand:SI 3 "const_int_operand" ""))])]
1183 if (!xtensa_expand_block_move (operands)) FAIL;
1187 (define_insn "movstrsi_internal"
1188 [(set (match_operand:BLK 0 "memory_operand" "=U")
1189 (match_operand:BLK 1 "memory_operand" "U"))
1190 (use (match_operand:SI 2 "arith_operand" ""))
1191 (use (match_operand:SI 3 "const_int_operand" ""))
1192 (clobber (match_scratch:SI 4 "=&r"))
1193 (clobber (match_scratch:SI 5 "=&r"))]
1198 tmpregs[0] = operands[4];
1199 tmpregs[1] = operands[5];
1200 xtensa_emit_block_move (operands, tmpregs, 1);
1203 [(set_attr "type" "multi")
1204 (set_attr "mode" "none")
1205 (set_attr "length" "300")])
1209 ;; ....................
1213 ;; ....................
1216 (define_insn "ashlsi3"
1217 [(set (match_operand:SI 0 "register_operand" "=a,a")
1218 (ashift:SI (match_operand:SI 1 "register_operand" "r,r")
1219 (match_operand:SI 2 "arith_operand" "J,r")))]
1223 ssl\\t%2\;sll\\t%0, %1"
1224 [(set_attr "type" "arith,arith")
1225 (set_attr "mode" "SI")
1226 (set_attr "length" "3,6")])
1228 (define_insn "ashrsi3"
1229 [(set (match_operand:SI 0 "register_operand" "=a,a")
1230 (ashiftrt:SI (match_operand:SI 1 "register_operand" "r,r")
1231 (match_operand:SI 2 "arith_operand" "J,r")))]
1235 ssr\\t%2\;sra\\t%0, %1"
1236 [(set_attr "type" "arith,arith")
1237 (set_attr "mode" "SI")
1238 (set_attr "length" "3,6")])
1240 (define_insn "lshrsi3"
1241 [(set (match_operand:SI 0 "register_operand" "=a,a")
1242 (lshiftrt:SI (match_operand:SI 1 "register_operand" "r,r")
1243 (match_operand:SI 2 "arith_operand" "J,r")))]
1247 if (which_alternative == 0)
1249 if ((INTVAL (operands[2]) & 0x1f) < 16)
1250 return \"srli\\t%0, %1, %R2\";
1252 return \"extui\\t%0, %1, %R2, %L2\";
1254 return \"ssr\\t%2\;srl\\t%0, %1\";
1256 [(set_attr "type" "arith,arith")
1257 (set_attr "mode" "SI")
1258 (set_attr "length" "3,6")])
1260 (define_insn "rotlsi3"
1261 [(set (match_operand:SI 0 "register_operand" "=a,a")
1262 (rotate:SI (match_operand:SI 1 "register_operand" "r,r")
1263 (match_operand:SI 2 "arith_operand" "J,r")))]
1266 ssai\\t%L2\;src\\t%0, %1, %1
1267 ssl\\t%2\;src\\t%0, %1, %1"
1268 [(set_attr "type" "multi,multi")
1269 (set_attr "mode" "SI")
1270 (set_attr "length" "6,6")])
1272 (define_insn "rotrsi3"
1273 [(set (match_operand:SI 0 "register_operand" "=a,a")
1274 (rotatert:SI (match_operand:SI 1 "register_operand" "r,r")
1275 (match_operand:SI 2 "arith_operand" "J,r")))]
1278 ssai\\t%R2\;src\\t%0, %1, %1
1279 ssr\\t%2\;src\\t%0, %1, %1"
1280 [(set_attr "type" "multi,multi")
1281 (set_attr "mode" "SI")
1282 (set_attr "length" "6,6")])
1286 ;; ....................
1290 ;; ....................
1293 ;; Like the md files for MIPS and SPARC, we handle comparisons by stashing
1294 ;; away the operands and then using that information in the subsequent
1295 ;; conditional branch.
1297 (define_expand "cmpsi"
1299 (compare:CC (match_operand:SI 0 "register_operand" "")
1300 (match_operand:SI 1 "nonmemory_operand" "")))]
1304 branch_cmp[0] = operands[0];
1305 branch_cmp[1] = operands[1];
1306 branch_type = CMP_SI;
1310 (define_expand "tstsi"
1312 (match_operand:SI 0 "register_operand" ""))]
1316 branch_cmp[0] = operands[0];
1317 branch_cmp[1] = const0_rtx;
1318 branch_type = CMP_SI;
1322 (define_expand "cmpsf"
1324 (compare:CC (match_operand:SF 0 "register_operand" "")
1325 (match_operand:SF 1 "register_operand" "")))]
1329 branch_cmp[0] = operands[0];
1330 branch_cmp[1] = operands[1];
1331 branch_type = CMP_SF;
1337 ;; ....................
1339 ;; CONDITIONAL BRANCHES
1341 ;; ....................
1344 (define_expand "beq"
1346 (if_then_else (eq (cc0) (const_int 0))
1347 (label_ref (match_operand 0 "" ""))
1352 xtensa_expand_conditional_branch (operands, EQ);
1356 (define_expand "bne"
1358 (if_then_else (ne (cc0) (const_int 0))
1359 (label_ref (match_operand 0 "" ""))
1364 xtensa_expand_conditional_branch (operands, NE);
1368 (define_expand "bgt"
1370 (if_then_else (gt (cc0) (const_int 0))
1371 (label_ref (match_operand 0 "" ""))
1376 xtensa_expand_conditional_branch (operands, GT);
1380 (define_expand "bge"
1382 (if_then_else (ge (cc0) (const_int 0))
1383 (label_ref (match_operand 0 "" ""))
1388 xtensa_expand_conditional_branch (operands, GE);
1392 (define_expand "blt"
1394 (if_then_else (lt (cc0) (const_int 0))
1395 (label_ref (match_operand 0 "" ""))
1400 xtensa_expand_conditional_branch (operands, LT);
1404 (define_expand "ble"
1406 (if_then_else (le (cc0) (const_int 0))
1407 (label_ref (match_operand 0 "" ""))
1412 xtensa_expand_conditional_branch (operands, LE);
1416 (define_expand "bgtu"
1418 (if_then_else (gtu (cc0) (const_int 0))
1419 (label_ref (match_operand 0 "" ""))
1424 xtensa_expand_conditional_branch (operands, GTU);
1428 (define_expand "bgeu"
1430 (if_then_else (geu (cc0) (const_int 0))
1431 (label_ref (match_operand 0 "" ""))
1436 xtensa_expand_conditional_branch (operands, GEU);
1440 (define_expand "bltu"
1442 (if_then_else (ltu (cc0) (const_int 0))
1443 (label_ref (match_operand 0 "" ""))
1448 xtensa_expand_conditional_branch (operands, LTU);
1452 (define_expand "bleu"
1454 (if_then_else (leu (cc0) (const_int 0))
1455 (label_ref (match_operand 0 "" ""))
1460 xtensa_expand_conditional_branch (operands, LEU);
1464 ;; Branch patterns for standard integer comparisons
1466 (define_insn "*btrue"
1468 (if_then_else (match_operator 3 "branch_operator"
1469 [(match_operand:SI 0 "register_operand" "r,r")
1470 (match_operand:SI 1 "branch_operand" "K,r")])
1471 (label_ref (match_operand 2 "" ""))
1476 if (which_alternative == 1)
1478 switch (GET_CODE (operands[3]))
1480 case EQ: return \"beq\\t%0, %1, %2\";
1481 case NE: return \"bne\\t%0, %1, %2\";
1482 case LT: return \"blt\\t%0, %1, %2\";
1483 case GE: return \"bge\\t%0, %1, %2\";
1487 else if (INTVAL (operands[1]) == 0)
1489 switch (GET_CODE (operands[3]))
1491 case EQ: return (TARGET_DENSITY
1492 ? \"beqz.n\\t%0, %2\"
1493 : \"beqz\\t%0, %2\");
1494 case NE: return (TARGET_DENSITY
1495 ? \"bnez.n\\t%0, %2\"
1496 : \"bnez\\t%0, %2\");
1497 case LT: return \"bltz\\t%0, %2\";
1498 case GE: return \"bgez\\t%0, %2\";
1504 switch (GET_CODE (operands[3]))
1506 case EQ: return \"beqi\\t%0, %d1, %2\";
1507 case NE: return \"bnei\\t%0, %d1, %2\";
1508 case LT: return \"blti\\t%0, %d1, %2\";
1509 case GE: return \"bgei\\t%0, %d1, %2\";
1513 fatal_insn (\"unexpected branch operator\", operands[3]);
1516 [(set_attr "type" "jump,jump")
1517 (set_attr "mode" "none")
1518 (set_attr "length" "3,3")])
1520 (define_insn "*bfalse"
1522 (if_then_else (match_operator 3 "branch_operator"
1523 [(match_operand:SI 0 "register_operand" "r,r")
1524 (match_operand:SI 1 "branch_operand" "K,r")])
1526 (label_ref (match_operand 2 "" ""))))]
1530 if (which_alternative == 1)
1532 switch (GET_CODE (operands[3]))
1534 case EQ: return \"bne\\t%0, %1, %2\";
1535 case NE: return \"beq\\t%0, %1, %2\";
1536 case LT: return \"bge\\t%0, %1, %2\";
1537 case GE: return \"blt\\t%0, %1, %2\";
1541 else if (INTVAL (operands[1]) == 0)
1543 switch (GET_CODE (operands[3]))
1545 case EQ: return (TARGET_DENSITY
1546 ? \"bnez.n\\t%0, %2\"
1547 : \"bnez\\t%0, %2\");
1548 case NE: return (TARGET_DENSITY
1549 ? \"beqz.n\\t%0, %2\"
1550 : \"beqz\\t%0, %2\");
1551 case LT: return \"bgez\\t%0, %2\";
1552 case GE: return \"bltz\\t%0, %2\";
1558 switch (GET_CODE (operands[3]))
1560 case EQ: return \"bnei\\t%0, %d1, %2\";
1561 case NE: return \"beqi\\t%0, %d1, %2\";
1562 case LT: return \"bgei\\t%0, %d1, %2\";
1563 case GE: return \"blti\\t%0, %d1, %2\";
1567 fatal_insn (\"unexpected branch operator\", operands[3]);
1570 [(set_attr "type" "jump,jump")
1571 (set_attr "mode" "none")
1572 (set_attr "length" "3,3")])
1574 (define_insn "*ubtrue"
1576 (if_then_else (match_operator 3 "ubranch_operator"
1577 [(match_operand:SI 0 "register_operand" "r,r")
1578 (match_operand:SI 1 "ubranch_operand" "L,r")])
1579 (label_ref (match_operand 2 "" ""))
1584 if (which_alternative == 1)
1586 switch (GET_CODE (operands[3]))
1588 case LTU: return \"bltu\\t%0, %1, %2\";
1589 case GEU: return \"bgeu\\t%0, %1, %2\";
1595 switch (GET_CODE (operands[3]))
1597 case LTU: return \"bltui\\t%0, %d1, %2\";
1598 case GEU: return \"bgeui\\t%0, %d1, %2\";
1602 fatal_insn (\"unexpected branch operator\", operands[3]);
1605 [(set_attr "type" "jump,jump")
1606 (set_attr "mode" "none")
1607 (set_attr "length" "3,3")])
1609 (define_insn "*ubfalse"
1611 (if_then_else (match_operator 3 "ubranch_operator"
1612 [(match_operand:SI 0 "register_operand" "r,r")
1613 (match_operand:SI 1 "ubranch_operand" "L,r")])
1615 (label_ref (match_operand 2 "" ""))))]
1619 if (which_alternative == 1)
1621 switch (GET_CODE (operands[3]))
1623 case LTU: return \"bgeu\\t%0, %1, %2\";
1624 case GEU: return \"bltu\\t%0, %1, %2\";
1630 switch (GET_CODE (operands[3]))
1632 case LTU: return \"bgeui\\t%0, %d1, %2\";
1633 case GEU: return \"bltui\\t%0, %d1, %2\";
1637 fatal_insn (\"unexpected branch operator\", operands[3]);
1640 [(set_attr "type" "jump,jump")
1641 (set_attr "mode" "none")
1642 (set_attr "length" "3,3")])
1644 ;; Branch patterns for bit testing
1646 (define_insn "*bittrue"
1648 (if_then_else (match_operator 3 "boolean_operator"
1650 (match_operand:SI 0 "register_operand" "r,r")
1652 (match_operand:SI 1 "arith_operand" "J,r"))
1654 (label_ref (match_operand 2 "" ""))
1659 if (which_alternative == 0)
1661 unsigned bitnum = INTVAL(operands[1]) & 0x1f;
1662 operands[1] = GEN_INT(bitnum);
1663 switch (GET_CODE (operands[3]))
1665 case EQ: return \"bbci\\t%0, %d1, %2\";
1666 case NE: return \"bbsi\\t%0, %d1, %2\";
1672 switch (GET_CODE (operands[3]))
1674 case EQ: return \"bbc\\t%0, %1, %2\";
1675 case NE: return \"bbs\\t%0, %1, %2\";
1679 fatal_insn (\"unexpected branch operator\", operands[3]);
1682 [(set_attr "type" "jump")
1683 (set_attr "mode" "none")
1684 (set_attr "length" "3")])
1686 (define_insn "*bitfalse"
1688 (if_then_else (match_operator 3 "boolean_operator"
1690 (match_operand:SI 0 "register_operand" "r,r")
1692 (match_operand:SI 1 "arith_operand" "J,r"))
1695 (label_ref (match_operand 2 "" ""))))]
1699 if (which_alternative == 0)
1701 unsigned bitnum = INTVAL (operands[1]) & 0x1f;
1702 operands[1] = GEN_INT (bitnum);
1703 switch (GET_CODE (operands[3]))
1705 case EQ: return \"bbsi\\t%0, %d1, %2\";
1706 case NE: return \"bbci\\t%0, %d1, %2\";
1712 switch (GET_CODE (operands[3]))
1714 case EQ: return \"bbs\\t%0, %1, %2\";
1715 case NE: return \"bbc\\t%0, %1, %2\";
1719 fatal_insn (\"unexpected branch operator\", operands[3]);
1722 [(set_attr "type" "jump")
1723 (set_attr "mode" "none")
1724 (set_attr "length" "3")])
1726 (define_insn "*masktrue"
1728 (if_then_else (match_operator 3 "boolean_operator"
1729 [(and:SI (match_operand:SI 0 "register_operand" "r")
1730 (match_operand:SI 1 "register_operand" "r"))
1732 (label_ref (match_operand 2 "" ""))
1737 switch (GET_CODE (operands[3]))
1739 case EQ: return \"bnone\\t%0, %1, %2\";
1740 case NE: return \"bany\\t%0, %1, %2\";
1743 fatal_insn (\"unexpected branch operator\", operands[3]);
1746 [(set_attr "type" "jump")
1747 (set_attr "mode" "none")
1748 (set_attr "length" "3")])
1750 (define_insn "*maskfalse"
1752 (if_then_else (match_operator 3 "boolean_operator"
1753 [(and:SI (match_operand:SI 0 "register_operand" "r")
1754 (match_operand:SI 1 "register_operand" "r"))
1757 (label_ref (match_operand 2 "" ""))))]
1761 switch (GET_CODE (operands[3]))
1763 case EQ: return \"bany\\t%0, %1, %2\";
1764 case NE: return \"bnone\\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")])
1775 ;; Define the loop insns that is used by bct optimization to represent the
1776 ;; start and end of a zero-overhead loop (in loop.c). This start template
1777 ;; generates the loop insn, the end template doesn't generate any instructions
1778 ;; since since loop end is handled in hardware.
1780 (define_insn "zero_cost_loop_start"
1781 [(set (pc) (if_then_else (eq (match_operand:SI 0 "register_operand" "a")
1783 (label_ref (match_operand 1 "" ""))
1786 (plus:SI (match_dup 0) (const_int -1)))]
1789 [(set_attr "type" "jump")
1790 (set_attr "mode" "none")
1791 (set_attr "length" "3")])
1793 (define_insn "zero_cost_loop_end"
1794 [(set (pc) (if_then_else (ne (reg:SI 19) (const_int 0))
1795 (label_ref (match_operand 0 "" ""))
1798 (plus:SI (reg:SI 19) (const_int -1)))]
1801 xtensa_emit_loop_end (insn, operands);
1804 [(set_attr "type" "jump")
1805 (set_attr "mode" "none")
1806 (set_attr "length" "0")])
1810 ;; ....................
1812 ;; SETTING A REGISTER FROM A COMPARISON
1814 ;; ....................
1817 (define_expand "seq"
1818 [(set (match_operand:SI 0 "register_operand" "")
1823 operands[1] = gen_rtx (EQ, SImode, branch_cmp[0], branch_cmp[1]);
1824 if (!xtensa_expand_scc (operands)) FAIL;
1828 (define_expand "sne"
1829 [(set (match_operand:SI 0 "register_operand" "")
1834 operands[1] = gen_rtx (NE, SImode, branch_cmp[0], branch_cmp[1]);
1835 if (!xtensa_expand_scc (operands)) FAIL;
1839 (define_expand "sgt"
1840 [(set (match_operand:SI 0 "register_operand" "")
1845 operands[1] = gen_rtx (GT, SImode, branch_cmp[0], branch_cmp[1]);
1846 if (!xtensa_expand_scc (operands)) FAIL;
1850 (define_expand "sge"
1851 [(set (match_operand:SI 0 "register_operand" "")
1856 operands[1] = gen_rtx (GE, SImode, branch_cmp[0], branch_cmp[1]);
1857 if (!xtensa_expand_scc (operands)) FAIL;
1861 (define_expand "slt"
1862 [(set (match_operand:SI 0 "register_operand" "")
1867 operands[1] = gen_rtx (LT, SImode, branch_cmp[0], branch_cmp[1]);
1868 if (!xtensa_expand_scc (operands)) FAIL;
1872 (define_expand "sle"
1873 [(set (match_operand:SI 0 "register_operand" "")
1878 operands[1] = gen_rtx (LE, SImode, branch_cmp[0], branch_cmp[1]);
1879 if (!xtensa_expand_scc (operands)) FAIL;
1885 ;; ....................
1887 ;; CONDITIONAL MOVES
1889 ;; ....................
1892 (define_expand "movsicc"
1893 [(set (match_operand:SI 0 "register_operand" "")
1894 (if_then_else:SI (match_operand 1 "comparison_operator" "")
1895 (match_operand:SI 2 "register_operand" "")
1896 (match_operand:SI 3 "register_operand" "")))]
1900 if (!xtensa_expand_conditional_move (operands, 0)) FAIL;
1904 (define_expand "movsfcc"
1905 [(set (match_operand:SF 0 "register_operand" "")
1906 (if_then_else:SF (match_operand 1 "comparison_operator" "")
1907 (match_operand:SF 2 "register_operand" "")
1908 (match_operand:SF 3 "register_operand" "")))]
1912 if (!xtensa_expand_conditional_move (operands, 1)) FAIL;
1916 (define_insn "movsicc_internal0"
1917 [(set (match_operand:SI 0 "register_operand" "=a,a")
1918 (if_then_else:SI (match_operator 4 "branch_operator"
1919 [(match_operand:SI 1 "register_operand" "r,r")
1921 (match_operand:SI 2 "register_operand" "r,0")
1922 (match_operand:SI 3 "register_operand" "0,r")))]
1926 if (which_alternative == 0)
1928 switch (GET_CODE (operands[4]))
1930 case EQ: return \"moveqz\\t%0, %2, %1\";
1931 case NE: return \"movnez\\t%0, %2, %1\";
1932 case LT: return \"movltz\\t%0, %2, %1\";
1933 case GE: return \"movgez\\t%0, %2, %1\";
1939 switch (GET_CODE (operands[4]))
1941 case EQ: return \"movnez\\t%0, %3, %1\";
1942 case NE: return \"moveqz\\t%0, %3, %1\";
1943 case LT: return \"movgez\\t%0, %3, %1\";
1944 case GE: return \"movltz\\t%0, %3, %1\";
1948 fatal_insn (\"unexpected cmov operator\", operands[4]);
1951 [(set_attr "type" "move,move")
1952 (set_attr "mode" "SI")
1953 (set_attr "length" "3,3")])
1955 (define_insn "movsicc_internal1"
1956 [(set (match_operand:SI 0 "register_operand" "=a,a")
1957 (if_then_else:SI (match_operator 4 "boolean_operator"
1958 [(match_operand:CC 1 "register_operand" "b,b")
1960 (match_operand:SI 2 "register_operand" "r,0")
1961 (match_operand:SI 3 "register_operand" "0,r")))]
1965 int isEq = (GET_CODE (operands[4]) == EQ);
1966 switch (which_alternative)
1969 if (isEq) return \"movf\\t%0, %2, %1\";
1970 return \"movt\\t%0, %2, %1\";
1972 if (isEq) return \"movt\\t%0, %3, %1\";
1973 return \"movf\\t%0, %3, %1\";
1978 [(set_attr "type" "move,move")
1979 (set_attr "mode" "SI")
1980 (set_attr "length" "3,3")])
1982 (define_insn "movsfcc_internal0"
1983 [(set (match_operand:SF 0 "register_operand" "=a,a,f,f")
1984 (if_then_else:SF (match_operator 4 "branch_operator"
1985 [(match_operand:SI 1 "register_operand" "r,r,r,r")
1987 (match_operand:SF 2 "register_operand" "r,0,f,0")
1988 (match_operand:SF 3 "register_operand" "0,r,0,f")))]
1992 if (which_alternative == 0)
1994 switch (GET_CODE (operands[4]))
1996 case EQ: return \"moveqz\\t%0, %2, %1\";
1997 case NE: return \"movnez\\t%0, %2, %1\";
1998 case LT: return \"movltz\\t%0, %2, %1\";
1999 case GE: return \"movgez\\t%0, %2, %1\";
2003 else if (which_alternative == 1)
2005 switch (GET_CODE (operands[4]))
2007 case EQ: return \"movnez\\t%0, %3, %1\";
2008 case NE: return \"moveqz\\t%0, %3, %1\";
2009 case LT: return \"movgez\\t%0, %3, %1\";
2010 case GE: return \"movltz\\t%0, %3, %1\";
2014 else if (which_alternative == 2)
2016 switch (GET_CODE (operands[4]))
2018 case EQ: return \"moveqz.s %0, %2, %1\";
2019 case NE: return \"movnez.s %0, %2, %1\";
2020 case LT: return \"movltz.s %0, %2, %1\";
2021 case GE: return \"movgez.s %0, %2, %1\";
2025 else if (which_alternative == 3)
2027 switch (GET_CODE (operands[4]))
2029 case EQ: return \"movnez.s %0, %3, %1\";
2030 case NE: return \"moveqz.s %0, %3, %1\";
2031 case LT: return \"movgez.s %0, %3, %1\";
2032 case GE: return \"movltz.s %0, %3, %1\";
2036 fatal_insn (\"unexpected cmov operator\", operands[4]);
2039 [(set_attr "type" "move,move,move,move")
2040 (set_attr "mode" "SF")
2041 (set_attr "length" "3,3,3,3")])
2043 (define_insn "movsfcc_internal1"
2044 [(set (match_operand:SF 0 "register_operand" "=a,a,f,f")
2045 (if_then_else:SF (match_operator 4 "boolean_operator"
2046 [(match_operand:CC 1 "register_operand" "b,b,b,b")
2048 (match_operand:SF 2 "register_operand" "r,0,f,0")
2049 (match_operand:SF 3 "register_operand" "0,r,0,f")))]
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\";
2063 if (isEq) return \"movf.s\\t%0, %2, %1\";
2064 return \"movt.s\\t%0, %2, %1\";
2066 if (isEq) return \"movt.s\\t%0, %3, %1\";
2067 return \"movf.s\\t%0, %3, %1\";
2072 [(set_attr "type" "move,move,move,move")
2073 (set_attr "mode" "SF")
2074 (set_attr "length" "3,3,3,3")])
2078 ;; ....................
2080 ;; FLOATING POINT COMPARISONS
2082 ;; ....................
2085 (define_insn "seq_sf"
2086 [(set (match_operand:CC 0 "register_operand" "=b")
2087 (eq:CC (match_operand:SF 1 "register_operand" "f")
2088 (match_operand:SF 2 "register_operand" "f")))]
2090 "oeq.s\\t%0, %1, %2"
2091 [(set_attr "type" "farith")
2092 (set_attr "mode" "BL")
2093 (set_attr "length" "3")])
2095 (define_insn "slt_sf"
2096 [(set (match_operand:CC 0 "register_operand" "=b")
2097 (lt:CC (match_operand:SF 1 "register_operand" "f")
2098 (match_operand:SF 2 "register_operand" "f")))]
2100 "olt.s\\t%0, %1, %2"
2101 [(set_attr "type" "farith")
2102 (set_attr "mode" "BL")
2103 (set_attr "length" "3")])
2105 (define_insn "sle_sf"
2106 [(set (match_operand:CC 0 "register_operand" "=b")
2107 (le:CC (match_operand:SF 1 "register_operand" "f")
2108 (match_operand:SF 2 "register_operand" "f")))]
2110 "ole.s\\t%0, %1, %2"
2111 [(set_attr "type" "farith")
2112 (set_attr "mode" "BL")
2113 (set_attr "length" "3")])
2117 ;; ....................
2119 ;; UNCONDITIONAL BRANCHES
2121 ;; ....................
2126 (label_ref (match_operand 0 "" "")))]
2129 [(set_attr "type" "jump")
2130 (set_attr "mode" "none")
2131 (set_attr "length" "3")])
2133 (define_expand "indirect_jump"
2134 [(set (pc) (match_operand 0 "register_operand" ""))]
2138 rtx dest = operands[0];
2139 if (GET_CODE (dest) != REG || GET_MODE (dest) != Pmode)
2140 operands[0] = copy_to_mode_reg (Pmode, dest);
2142 emit_jump_insn (gen_indirect_jump_internal (dest));
2146 (define_insn "indirect_jump_internal"
2147 [(set (pc) (match_operand:SI 0 "register_operand" "r"))]
2150 [(set_attr "type" "jump")
2151 (set_attr "mode" "none")
2152 (set_attr "length" "3")])
2155 (define_expand "tablejump"
2156 [(use (match_operand:SI 0 "register_operand" ""))
2157 (use (label_ref (match_operand 1 "" "")))]
2161 rtx target = operands[0];
2164 /* For PIC, the table entry is relative to the start of the table. */
2165 rtx label = gen_reg_rtx (SImode);
2166 target = gen_reg_rtx (SImode);
2167 emit_move_insn (label, gen_rtx_LABEL_REF (SImode, operands[1]));
2168 emit_insn (gen_addsi3 (target, operands[0], label));
2170 emit_jump_insn (gen_tablejump_internal (target, operands[1]));
2174 (define_insn "tablejump_internal"
2176 (match_operand:SI 0 "register_operand" "r"))
2177 (use (label_ref (match_operand 1 "" "")))]
2180 [(set_attr "type" "jump")
2181 (set_attr "mode" "none")
2182 (set_attr "length" "3")])
2186 ;; ....................
2190 ;; ....................
2193 (define_expand "sym_PLT"
2194 [(const (unspec [(match_operand:SI 0 "" "")] UNSPEC_PLT))]
2198 (define_expand "call"
2199 [(call (match_operand 0 "memory_operand" "")
2200 (match_operand 1 "" ""))]
2204 rtx addr = XEXP (operands[0], 0);
2205 if (flag_pic && GET_CODE (addr) == SYMBOL_REF && !SYMBOL_REF_LOCAL_P (addr))
2206 addr = gen_sym_PLT (addr);
2207 if (!call_insn_operand (addr, VOIDmode))
2208 XEXP (operands[0], 0) = copy_to_mode_reg (Pmode, addr);
2211 (define_insn "call_internal"
2212 [(call (mem (match_operand:SI 0 "call_insn_operand" "n,i,r"))
2213 (match_operand 1 "" "i,i,i"))]
2216 return xtensa_emit_call (0, operands);
2218 [(set_attr "type" "call")
2219 (set_attr "mode" "none")
2220 (set_attr "length" "3")])
2222 (define_expand "call_value"
2223 [(set (match_operand 0 "register_operand" "")
2224 (call (match_operand 1 "memory_operand" "")
2225 (match_operand 2 "" "")))]
2229 rtx addr = XEXP (operands[1], 0);
2230 if (flag_pic && GET_CODE (addr) == SYMBOL_REF && !SYMBOL_REF_LOCAL_P (addr))
2231 addr = gen_sym_PLT (addr);
2232 if (!call_insn_operand (addr, VOIDmode))
2233 XEXP (operands[1], 0) = copy_to_mode_reg (Pmode, addr);
2236 ;; cannot combine constraints for operand 0 into "afvb"
2237 ;; reload.c:find_reloads seems to assume that grouped constraints somehow
2238 ;; specify related register classes, and when they don't the constraints
2239 ;; fail to match. By not grouping the constraints, we get the correct
2241 (define_insn "call_value_internal"
2242 [(set (match_operand 0 "register_operand" "=af,af,af,v,v,v,b,b,b")
2243 (call (mem (match_operand:SI 1 "call_insn_operand"
2244 "n,i,r,n,i,r,n,i,r"))
2245 (match_operand 2 "" "i,i,i,i,i,i,i,i,i")))]
2248 return xtensa_emit_call (1, operands);
2250 [(set_attr "type" "call")
2251 (set_attr "mode" "none")
2252 (set_attr "length" "3")])
2254 (define_insn "entry"
2255 [(set (reg:SI A1_REG)
2256 (unspec_volatile:SI [(match_operand:SI 0 "const_int_operand" "i")
2257 (match_operand:SI 1 "const_int_operand" "i")]
2262 if (frame_pointer_needed)
2263 output_asm_insn (\".frame\\ta7, %0\", operands);
2265 output_asm_insn (\".frame\\tsp, %0\", operands);
2266 return \"entry\\tsp, %1\";
2268 [(set_attr "type" "move")
2269 (set_attr "mode" "SI")
2270 (set_attr "length" "3")])
2272 (define_insn "return"
2274 (use (reg:SI A0_REG))]
2278 return (TARGET_DENSITY ? \"retw.n\" : \"retw\");
2280 [(set_attr "type" "jump")
2281 (set_attr "mode" "none")
2282 (set_attr "length" "2")])
2286 ;; ....................
2290 ;; ....................
2293 (define_expand "prologue"
2298 xtensa_expand_prologue ();
2302 (define_expand "epilogue"
2307 emit_jump_insn (gen_return ());
2316 return (TARGET_DENSITY ? \"nop.n\" : \"nop\");
2318 [(set_attr "type" "nop")
2319 (set_attr "mode" "none")
2320 (set_attr "length" "3")])
2322 (define_expand "nonlocal_goto"
2323 [(match_operand:SI 0 "general_operand" "")
2324 (match_operand:SI 1 "general_operand" "")
2325 (match_operand:SI 2 "general_operand" "")
2326 (match_operand:SI 3 "" "")]
2330 xtensa_expand_nonlocal_goto (operands);
2334 ;; Setting up a frame pointer is tricky for Xtensa because GCC doesn't
2335 ;; know if a frame pointer is required until the reload pass, and
2336 ;; because there may be an incoming argument value in the hard frame
2337 ;; pointer register (a7). If there is an incoming argument in that
2338 ;; register, the "set_frame_ptr" insn gets inserted immediately after
2339 ;; the insn that copies the incoming argument to a pseudo or to the
2340 ;; stack. This serves several purposes here: (1) it keeps the
2341 ;; optimizer from copy-propagating or scheduling the use of a7 as an
2342 ;; incoming argument away from the beginning of the function; (2) we
2343 ;; can use a post-reload splitter to expand away the insn if a frame
2344 ;; pointer is not required, so that the post-reload scheduler can do
2345 ;; the right thing; and (3) it makes it easy for xtensa_reorg() to
2346 ;; search for this insn to determine whether it should add a new insn
2347 ;; to set up the frame pointer.
2349 (define_insn "set_frame_ptr"
2350 [(set (reg:SI A7_REG) (unspec_volatile:SI [(const_int 0)] UNSPECV_SET_FP))]
2354 if (frame_pointer_needed)
2355 return \"mov\\ta7, sp\";
2358 [(set_attr "type" "move")
2359 (set_attr "mode" "SI")
2360 (set_attr "length" "3")])
2362 ;; Post-reload splitter to remove fp assignment when it's not needed.
2364 [(set (reg:SI A7_REG) (unspec_volatile:SI [(const_int 0)] UNSPECV_SET_FP))]
2365 "reload_completed && !frame_pointer_needed"
2366 [(unspec [(const_int 0)] UNSPEC_NOP)]
2369 ;; The preceding splitter needs something to split the insn into;
2370 ;; things start breaking if the result is just a "use" so instead we
2371 ;; generate the following insn.
2372 (define_insn "*unspec_nop"
2373 [(unspec [(const_int 0)] UNSPEC_NOP)]
2376 [(set_attr "type" "nop")
2377 (set_attr "mode" "none")
2378 (set_attr "length" "0")])
2380 ;; The fix_return_addr pattern sets the high 2 bits of an address in a
2381 ;; register to match the high bits of the current PC.
2383 (define_insn "fix_return_addr"
2384 [(set (match_operand:SI 0 "register_operand" "=a")
2385 (unspec:SI [(match_operand:SI 1 "register_operand" "r")]
2387 (clobber (match_scratch:SI 2 "=r"))
2388 (clobber (match_scratch:SI 3 "=r"))]
2390 "mov\\t%2, a0\;call0\\t0f\;.align\\t4\;0:\;mov\\t%3, a0\;mov\\ta0, %2\;\
2391 srli\\t%3, %3, 30\;slli\\t%0, %1, 2\;ssai\\t2\;src\\t%0, %3, %0"
2392 [(set_attr "type" "multi")
2393 (set_attr "mode" "SI")
2394 (set_attr "length" "24")])
2398 ;; ....................
2402 ;; ....................
2407 (define_insn "*booltrue"
2409 (if_then_else (match_operator 2 "boolean_operator"
2410 [(match_operand:CC 0 "register_operand" "b")
2412 (label_ref (match_operand 1 "" ""))
2417 if (GET_CODE (operands[2]) == EQ)
2418 return \"bf\\t%0, %1\";
2420 return \"bt\\t%0, %1\";
2422 [(set_attr "type" "jump")
2423 (set_attr "mode" "none")
2424 (set_attr "length" "3")])
2426 (define_insn "*boolfalse"
2428 (if_then_else (match_operator 2 "boolean_operator"
2429 [(match_operand:CC 0 "register_operand" "b")
2432 (label_ref (match_operand 1 "" ""))))]
2436 if (GET_CODE (operands[2]) == EQ)
2437 return \"bt\\t%0, %1\";
2439 return \"bf\\t%0, %1\";
2441 [(set_attr "type" "jump")
2442 (set_attr "mode" "none")
2443 (set_attr "length" "3")])