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 (xtensa_copy_incoming_a7 (operands, DImode))
937 (define_insn "movdi_internal"
938 [(set (match_operand:DI 0 "nonimmed_operand" "=D,D,S,a,a,a,U")
939 (match_operand:DI 1 "non_const_move_operand" "d,S,d,r,T,U,r"))]
940 "register_operand (operands[0], DImode)
941 || register_operand (operands[1], DImode)"
944 switch (which_alternative)
946 case 0: return \"mov.n\\t%0, %1\;mov.n\\t%D0, %D1\";
947 case 2: return \"%v0s32i.n\\t%1, %0\;s32i.n\\t%D1, %N0\";
948 case 3: return \"mov\\t%0, %1\;mov\\t%D0, %D1\";
949 case 6: return \"%v0s32i\\t%1, %0\;s32i\\t%D1, %N0\";
955 /* Check if the first half of the destination register is used
956 in the source address. If so, reverse the order of the loads
957 so that the source address doesn't get clobbered until it is
960 rtx dstreg = operands[0];
961 if (GET_CODE (dstreg) == SUBREG)
962 dstreg = SUBREG_REG (dstreg);
963 if (GET_CODE (dstreg) != REG)
966 if (reg_mentioned_p (dstreg, operands[1]))
968 switch (which_alternative)
970 case 1: return \"%v1l32i.n\\t%D0, %N1\;l32i.n\\t%0, %1\";
971 case 4: return \"%v1l32r\\t%D0, %N1\;l32r\\t%0, %1\";
972 case 5: return \"%v1l32i\\t%D0, %N1\;l32i\\t%0, %1\";
977 switch (which_alternative)
979 case 1: return \"%v1l32i.n\\t%0, %1\;l32i.n\\t%D0, %N1\";
980 case 4: return \"%v1l32r\\t%0, %1\;l32r\\t%D0, %N1\";
981 case 5: return \"%v1l32i\\t%0, %1\;l32i\\t%D0, %N1\";
989 [(set_attr "type" "move,load,store,move,load,load,store")
990 (set_attr "mode" "DI")
991 (set_attr "length" "4,4,4,6,6,6,6")])
994 ;; 32-bit Integer moves
996 (define_expand "movsi"
997 [(set (match_operand:SI 0 "nonimmed_operand" "")
998 (match_operand:SI 1 "general_operand" ""))]
1002 if (xtensa_emit_move_sequence (operands, SImode))
1006 (define_insn "movsi_internal"
1007 [(set (match_operand:SI 0 "nonimmed_operand" "=D,D,D,D,R,R,a,q,a,a,a,U,*a,*A")
1008 (match_operand:SI 1 "move_operand" "M,D,d,R,D,d,r,r,I,T,U,r,*A,*r"))]
1009 "xtensa_valid_move (SImode, operands)"
1023 rsr\\t%0, 16 # ACCLO
1024 wsr\\t%1, 16 # ACCLO"
1025 [(set_attr "type" "move,move,move,load,store,store,move,move,move,load,load,store,rsr,wsr")
1026 (set_attr "mode" "SI")
1027 (set_attr "length" "2,2,2,2,2,2,3,3,3,3,3,3,3,3")])
1029 ;; 16-bit Integer moves
1031 (define_expand "movhi"
1032 [(set (match_operand:HI 0 "nonimmed_operand" "")
1033 (match_operand:HI 1 "general_operand" ""))]
1037 if (xtensa_emit_move_sequence (operands, HImode))
1041 (define_insn "movhi_internal"
1042 [(set (match_operand:HI 0 "nonimmed_operand" "=D,D,a,a,a,U,*a,*A")
1043 (match_operand:HI 1 "move_operand" "M,d,r,I,U,r,*A,*r"))]
1044 "xtensa_valid_move (HImode, operands)"
1052 rsr\\t%0, 16 # ACCLO
1053 wsr\\t%1, 16 # ACCLO"
1054 [(set_attr "type" "move,move,move,move,load,store,rsr,wsr")
1055 (set_attr "mode" "HI")
1056 (set_attr "length" "2,2,3,3,3,3,3,3")])
1058 ;; 8-bit Integer moves
1060 (define_expand "movqi"
1061 [(set (match_operand:QI 0 "nonimmed_operand" "")
1062 (match_operand:QI 1 "general_operand" ""))]
1066 if (xtensa_emit_move_sequence (operands, QImode))
1070 (define_insn "movqi_internal"
1071 [(set (match_operand:QI 0 "nonimmed_operand" "=D,D,a,a,a,U,*a,*A")
1072 (match_operand:QI 1 "move_operand" "M,d,r,I,U,r,*A,*r"))]
1073 "xtensa_valid_move (QImode, operands)"
1081 rsr\\t%0, 16 # ACCLO
1082 wsr\\t%1, 16 # ACCLO"
1083 [(set_attr "type" "move,move,move,move,load,store,rsr,wsr")
1084 (set_attr "mode" "QI")
1085 (set_attr "length" "2,2,3,3,3,3,3,3")])
1087 ;; 32-bit floating point moves
1089 (define_expand "movsf"
1090 [(set (match_operand:SF 0 "nonimmed_operand" "")
1091 (match_operand:SF 1 "general_operand" ""))]
1095 if (GET_CODE (operands[1]) == CONST_DOUBLE)
1096 operands[1] = force_const_mem (SFmode, operands[1]);
1098 if (!(reload_in_progress | reload_completed))
1100 if (((!register_operand (operands[0], SFmode)
1101 && !register_operand (operands[1], SFmode))
1102 || (FP_REG_P (xt_true_regnum (operands[0]))
1103 && constantpool_mem_p (operands[1]))))
1104 operands[1] = force_reg (SFmode, operands[1]);
1106 if (xtensa_copy_incoming_a7 (operands, SFmode))
1111 (define_insn "movsf_internal"
1112 [(set (match_operand:SF 0 "nonimmed_operand"
1113 "=f,f,U,D,D,R,a,f,a,a,a,U")
1114 (match_operand:SF 1 "non_const_move_operand"
1115 "f,U,f,d,R,d,r,r,f,T,U,r"))]
1116 "((register_operand (operands[0], SFmode)
1117 || register_operand (operands[1], SFmode))
1118 && (!FP_REG_P (xt_true_regnum (operands[0]))
1119 || !constantpool_mem_p (operands[1])))"
1133 [(set_attr "type" "farith,fload,fstore,move,load,store,move,farith,farith,load,load,store")
1134 (set_attr "mode" "SF")
1135 (set_attr "length" "3,3,3,2,2,2,3,3,3,3,3,3")])
1137 (define_insn "*lsiu"
1138 [(set (match_operand:SF 0 "register_operand" "=f")
1139 (mem:SF (plus:SI (match_operand:SI 1 "register_operand" "+a")
1140 (match_operand:SI 2 "fpmem_offset_operand" "i"))))
1142 (plus:SI (match_dup 1) (match_dup 2)))]
1146 if (TARGET_SERIALIZE_VOLATILE && volatile_refs_p (PATTERN (insn)))
1147 output_asm_insn (\"memw\", operands);
1148 return \"lsiu\\t%0, %1, %2\";
1150 [(set_attr "type" "fload")
1151 (set_attr "mode" "SF")
1152 (set_attr "length" "3")])
1154 (define_insn "*ssiu"
1155 [(set (mem:SF (plus:SI (match_operand:SI 0 "register_operand" "+a")
1156 (match_operand:SI 1 "fpmem_offset_operand" "i")))
1157 (match_operand:SF 2 "register_operand" "f"))
1159 (plus:SI (match_dup 0) (match_dup 1)))]
1163 if (TARGET_SERIALIZE_VOLATILE && volatile_refs_p (PATTERN (insn)))
1164 output_asm_insn (\"memw\", operands);
1165 return \"ssiu\\t%2, %0, %1\";
1167 [(set_attr "type" "fstore")
1168 (set_attr "mode" "SF")
1169 (set_attr "length" "3")])
1171 ;; 64-bit floating point moves
1173 (define_expand "movdf"
1174 [(set (match_operand:DF 0 "nonimmed_operand" "")
1175 (match_operand:DF 1 "general_operand" ""))]
1179 if (GET_CODE (operands[1]) == CONST_DOUBLE)
1180 operands[1] = force_const_mem (DFmode, operands[1]);
1182 if (!(reload_in_progress | reload_completed))
1184 if (!register_operand (operands[0], DFmode)
1185 && !register_operand (operands[1], DFmode))
1186 operands[1] = force_reg (DFmode, operands[1]);
1188 if (xtensa_copy_incoming_a7 (operands, DFmode))
1193 (define_insn "movdf_internal"
1194 [(set (match_operand:DF 0 "nonimmed_operand" "=D,D,S,a,a,a,U")
1195 (match_operand:DF 1 "non_const_move_operand" "d,S,d,r,T,U,r"))]
1196 "register_operand (operands[0], DFmode)
1197 || register_operand (operands[1], DFmode)"
1200 switch (which_alternative)
1202 case 0: return \"mov.n\\t%0, %1\;mov.n\\t%D0, %D1\";
1203 case 2: return \"%v0s32i.n\\t%1, %0\;s32i.n\\t%D1, %N0\";
1204 case 3: return \"mov\\t%0, %1\;mov\\t%D0, %D1\";
1205 case 6: return \"%v0s32i\\t%1, %0\;s32i\\t%D1, %N0\";
1211 /* Check if the first half of the destination register is used
1212 in the source address. If so, reverse the order of the loads
1213 so that the source address doesn't get clobbered until it is
1214 no longer needed. */
1216 rtx dstreg = operands[0];
1217 if (GET_CODE (dstreg) == SUBREG)
1218 dstreg = SUBREG_REG (dstreg);
1219 if (GET_CODE (dstreg) != REG)
1222 if (reg_mentioned_p (dstreg, operands[1]))
1224 switch (which_alternative)
1226 case 1: return \"%v1l32i.n\\t%D0, %N1\;l32i.n\\t%0, %1\";
1227 case 4: return \"%v1l32r\\t%D0, %N1\;l32r\\t%0, %1\";
1228 case 5: return \"%v1l32i\\t%D0, %N1\;l32i\\t%0, %1\";
1233 switch (which_alternative)
1235 case 1: return \"%v1l32i.n\\t%0, %1\;l32i.n\\t%D0, %N1\";
1236 case 4: return \"%v1l32r\\t%0, %1\;l32r\\t%D0, %N1\";
1237 case 5: return \"%v1l32i\\t%0, %1\;l32i\\t%D0, %N1\";
1245 [(set_attr "type" "move,load,store,move,load,load,store")
1246 (set_attr "mode" "DF")
1247 (set_attr "length" "4,4,4,6,6,6,6")])
1251 (define_expand "movstrsi"
1252 [(parallel [(set (match_operand:BLK 0 "" "")
1253 (match_operand:BLK 1 "" ""))
1254 (use (match_operand:SI 2 "arith_operand" ""))
1255 (use (match_operand:SI 3 "const_int_operand" ""))])]
1259 if (!xtensa_expand_block_move (operands)) FAIL;
1263 (define_insn "movstrsi_internal"
1264 [(set (match_operand:BLK 0 "memory_operand" "=U")
1265 (match_operand:BLK 1 "memory_operand" "U"))
1266 (use (match_operand:SI 2 "arith_operand" ""))
1267 (use (match_operand:SI 3 "const_int_operand" ""))
1268 (clobber (match_scratch:SI 4 "=&r"))
1269 (clobber (match_scratch:SI 5 "=&r"))]
1274 tmpregs[0] = operands[4];
1275 tmpregs[1] = operands[5];
1276 xtensa_emit_block_move (operands, tmpregs, 1);
1279 [(set_attr "type" "multi")
1280 (set_attr "mode" "none")
1281 (set_attr "length" "300")])
1285 ;; ....................
1289 ;; ....................
1292 (define_insn "ashlsi3"
1293 [(set (match_operand:SI 0 "register_operand" "=a,a")
1294 (ashift:SI (match_operand:SI 1 "register_operand" "r,r")
1295 (match_operand:SI 2 "arith_operand" "J,r")))]
1299 ssl\\t%2\;sll\\t%0, %1"
1300 [(set_attr "type" "arith,arith")
1301 (set_attr "mode" "SI")
1302 (set_attr "length" "3,6")])
1304 (define_insn "ashrsi3"
1305 [(set (match_operand:SI 0 "register_operand" "=a,a")
1306 (ashiftrt:SI (match_operand:SI 1 "register_operand" "r,r")
1307 (match_operand:SI 2 "arith_operand" "J,r")))]
1311 ssr\\t%2\;sra\\t%0, %1"
1312 [(set_attr "type" "arith,arith")
1313 (set_attr "mode" "SI")
1314 (set_attr "length" "3,6")])
1316 (define_insn "lshrsi3"
1317 [(set (match_operand:SI 0 "register_operand" "=a,a")
1318 (lshiftrt:SI (match_operand:SI 1 "register_operand" "r,r")
1319 (match_operand:SI 2 "arith_operand" "J,r")))]
1323 if (which_alternative == 0)
1325 if ((INTVAL (operands[2]) & 0x1f) < 16)
1326 return \"srli\\t%0, %1, %R2\";
1328 return \"extui\\t%0, %1, %R2, %L2\";
1330 return \"ssr\\t%2\;srl\\t%0, %1\";
1332 [(set_attr "type" "arith,arith")
1333 (set_attr "mode" "SI")
1334 (set_attr "length" "3,6")])
1336 (define_insn "rotlsi3"
1337 [(set (match_operand:SI 0 "register_operand" "=a,a")
1338 (rotate:SI (match_operand:SI 1 "register_operand" "r,r")
1339 (match_operand:SI 2 "arith_operand" "J,r")))]
1342 ssai\\t%L2\;src\\t%0, %1, %1
1343 ssl\\t%2\;src\\t%0, %1, %1"
1344 [(set_attr "type" "multi,multi")
1345 (set_attr "mode" "SI")
1346 (set_attr "length" "6,6")])
1348 (define_insn "rotrsi3"
1349 [(set (match_operand:SI 0 "register_operand" "=a,a")
1350 (rotatert:SI (match_operand:SI 1 "register_operand" "r,r")
1351 (match_operand:SI 2 "arith_operand" "J,r")))]
1354 ssai\\t%R2\;src\\t%0, %1, %1
1355 ssr\\t%2\;src\\t%0, %1, %1"
1356 [(set_attr "type" "multi,multi")
1357 (set_attr "mode" "SI")
1358 (set_attr "length" "6,6")])
1362 ;; ....................
1366 ;; ....................
1369 ;; Like the md files for MIPS and SPARC, we handle comparisons by stashing
1370 ;; away the operands and then using that information in the subsequent
1371 ;; conditional branch.
1373 (define_expand "cmpsi"
1375 (compare:CC (match_operand:SI 0 "register_operand" "")
1376 (match_operand:SI 1 "nonmemory_operand" "")))]
1380 branch_cmp[0] = operands[0];
1381 branch_cmp[1] = operands[1];
1382 branch_type = CMP_SI;
1386 (define_expand "tstsi"
1388 (match_operand:SI 0 "register_operand" ""))]
1392 branch_cmp[0] = operands[0];
1393 branch_cmp[1] = const0_rtx;
1394 branch_type = CMP_SI;
1398 (define_expand "cmpsf"
1400 (compare:CC (match_operand:SF 0 "register_operand" "")
1401 (match_operand:SF 1 "register_operand" "")))]
1405 branch_cmp[0] = operands[0];
1406 branch_cmp[1] = operands[1];
1407 branch_type = CMP_SF;
1413 ;; ....................
1415 ;; CONDITIONAL BRANCHES
1417 ;; ....................
1420 (define_expand "beq"
1422 (if_then_else (eq (cc0) (const_int 0))
1423 (label_ref (match_operand 0 "" ""))
1428 xtensa_expand_conditional_branch (operands, EQ);
1432 (define_expand "bne"
1434 (if_then_else (ne (cc0) (const_int 0))
1435 (label_ref (match_operand 0 "" ""))
1440 xtensa_expand_conditional_branch (operands, NE);
1444 (define_expand "bgt"
1446 (if_then_else (gt (cc0) (const_int 0))
1447 (label_ref (match_operand 0 "" ""))
1452 xtensa_expand_conditional_branch (operands, GT);
1456 (define_expand "bge"
1458 (if_then_else (ge (cc0) (const_int 0))
1459 (label_ref (match_operand 0 "" ""))
1464 xtensa_expand_conditional_branch (operands, GE);
1468 (define_expand "blt"
1470 (if_then_else (lt (cc0) (const_int 0))
1471 (label_ref (match_operand 0 "" ""))
1476 xtensa_expand_conditional_branch (operands, LT);
1480 (define_expand "ble"
1482 (if_then_else (le (cc0) (const_int 0))
1483 (label_ref (match_operand 0 "" ""))
1488 xtensa_expand_conditional_branch (operands, LE);
1492 (define_expand "bgtu"
1494 (if_then_else (gtu (cc0) (const_int 0))
1495 (label_ref (match_operand 0 "" ""))
1500 xtensa_expand_conditional_branch (operands, GTU);
1504 (define_expand "bgeu"
1506 (if_then_else (geu (cc0) (const_int 0))
1507 (label_ref (match_operand 0 "" ""))
1512 xtensa_expand_conditional_branch (operands, GEU);
1516 (define_expand "bltu"
1518 (if_then_else (ltu (cc0) (const_int 0))
1519 (label_ref (match_operand 0 "" ""))
1524 xtensa_expand_conditional_branch (operands, LTU);
1528 (define_expand "bleu"
1530 (if_then_else (leu (cc0) (const_int 0))
1531 (label_ref (match_operand 0 "" ""))
1536 xtensa_expand_conditional_branch (operands, LEU);
1540 ;; Branch patterns for standard integer comparisons
1542 (define_insn "*btrue"
1544 (if_then_else (match_operator 3 "branch_operator"
1545 [(match_operand:SI 0 "register_operand" "r,r")
1546 (match_operand:SI 1 "branch_operand" "K,r")])
1547 (label_ref (match_operand 2 "" ""))
1552 if (which_alternative == 1)
1554 switch (GET_CODE (operands[3]))
1556 case EQ: return \"beq\\t%0, %1, %2\";
1557 case NE: return \"bne\\t%0, %1, %2\";
1558 case LT: return \"blt\\t%0, %1, %2\";
1559 case GE: return \"bge\\t%0, %1, %2\";
1563 else if (INTVAL (operands[1]) == 0)
1565 switch (GET_CODE (operands[3]))
1567 case EQ: return (TARGET_DENSITY
1568 ? \"beqz.n\\t%0, %2\"
1569 : \"beqz\\t%0, %2\");
1570 case NE: return (TARGET_DENSITY
1571 ? \"bnez.n\\t%0, %2\"
1572 : \"bnez\\t%0, %2\");
1573 case LT: return \"bltz\\t%0, %2\";
1574 case GE: return \"bgez\\t%0, %2\";
1580 switch (GET_CODE (operands[3]))
1582 case EQ: return \"beqi\\t%0, %d1, %2\";
1583 case NE: return \"bnei\\t%0, %d1, %2\";
1584 case LT: return \"blti\\t%0, %d1, %2\";
1585 case GE: return \"bgei\\t%0, %d1, %2\";
1589 fatal_insn (\"unexpected branch operator\", operands[3]);
1592 [(set_attr "type" "jump,jump")
1593 (set_attr "mode" "none")
1594 (set_attr "length" "3,3")])
1596 (define_insn "*bfalse"
1598 (if_then_else (match_operator 3 "branch_operator"
1599 [(match_operand:SI 0 "register_operand" "r,r")
1600 (match_operand:SI 1 "branch_operand" "K,r")])
1602 (label_ref (match_operand 2 "" ""))))]
1606 if (which_alternative == 1)
1608 switch (GET_CODE (operands[3]))
1610 case EQ: return \"bne\\t%0, %1, %2\";
1611 case NE: return \"beq\\t%0, %1, %2\";
1612 case LT: return \"bge\\t%0, %1, %2\";
1613 case GE: return \"blt\\t%0, %1, %2\";
1617 else if (INTVAL (operands[1]) == 0)
1619 switch (GET_CODE (operands[3]))
1621 case EQ: return (TARGET_DENSITY
1622 ? \"bnez.n\\t%0, %2\"
1623 : \"bnez\\t%0, %2\");
1624 case NE: return (TARGET_DENSITY
1625 ? \"beqz.n\\t%0, %2\"
1626 : \"beqz\\t%0, %2\");
1627 case LT: return \"bgez\\t%0, %2\";
1628 case GE: return \"bltz\\t%0, %2\";
1634 switch (GET_CODE (operands[3]))
1636 case EQ: return \"bnei\\t%0, %d1, %2\";
1637 case NE: return \"beqi\\t%0, %d1, %2\";
1638 case LT: return \"bgei\\t%0, %d1, %2\";
1639 case GE: return \"blti\\t%0, %d1, %2\";
1643 fatal_insn (\"unexpected branch operator\", operands[3]);
1646 [(set_attr "type" "jump,jump")
1647 (set_attr "mode" "none")
1648 (set_attr "length" "3,3")])
1650 (define_insn "*ubtrue"
1652 (if_then_else (match_operator 3 "ubranch_operator"
1653 [(match_operand:SI 0 "register_operand" "r,r")
1654 (match_operand:SI 1 "ubranch_operand" "L,r")])
1655 (label_ref (match_operand 2 "" ""))
1660 if (which_alternative == 1)
1662 switch (GET_CODE (operands[3]))
1664 case LTU: return \"bltu\\t%0, %1, %2\";
1665 case GEU: return \"bgeu\\t%0, %1, %2\";
1671 switch (GET_CODE (operands[3]))
1673 case LTU: return \"bltui\\t%0, %d1, %2\";
1674 case GEU: return \"bgeui\\t%0, %d1, %2\";
1678 fatal_insn (\"unexpected branch operator\", operands[3]);
1681 [(set_attr "type" "jump,jump")
1682 (set_attr "mode" "none")
1683 (set_attr "length" "3,3")])
1685 (define_insn "*ubfalse"
1687 (if_then_else (match_operator 3 "ubranch_operator"
1688 [(match_operand:SI 0 "register_operand" "r,r")
1689 (match_operand:SI 1 "ubranch_operand" "L,r")])
1691 (label_ref (match_operand 2 "" ""))))]
1695 if (which_alternative == 1)
1697 switch (GET_CODE (operands[3]))
1699 case LTU: return \"bgeu\\t%0, %1, %2\";
1700 case GEU: return \"bltu\\t%0, %1, %2\";
1706 switch (GET_CODE (operands[3]))
1708 case LTU: return \"bgeui\\t%0, %d1, %2\";
1709 case GEU: return \"bltui\\t%0, %d1, %2\";
1713 fatal_insn (\"unexpected branch operator\", operands[3]);
1716 [(set_attr "type" "jump,jump")
1717 (set_attr "mode" "none")
1718 (set_attr "length" "3,3")])
1720 ;; Branch patterns for bit testing
1722 (define_insn "*bittrue"
1724 (if_then_else (match_operator 3 "boolean_operator"
1726 (match_operand:SI 0 "register_operand" "r,r")
1728 (match_operand:SI 1 "arith_operand" "J,r"))
1730 (label_ref (match_operand 2 "" ""))
1735 if (which_alternative == 0)
1737 unsigned bitnum = INTVAL(operands[1]) & 0x1f;
1738 operands[1] = GEN_INT(bitnum);
1739 switch (GET_CODE (operands[3]))
1741 case EQ: return \"bbci\\t%0, %d1, %2\";
1742 case NE: return \"bbsi\\t%0, %d1, %2\";
1748 switch (GET_CODE (operands[3]))
1750 case EQ: return \"bbc\\t%0, %1, %2\";
1751 case NE: return \"bbs\\t%0, %1, %2\";
1755 fatal_insn (\"unexpected branch operator\", operands[3]);
1758 [(set_attr "type" "jump")
1759 (set_attr "mode" "none")
1760 (set_attr "length" "3")])
1762 (define_insn "*bitfalse"
1764 (if_then_else (match_operator 3 "boolean_operator"
1766 (match_operand:SI 0 "register_operand" "r,r")
1768 (match_operand:SI 1 "arith_operand" "J,r"))
1771 (label_ref (match_operand 2 "" ""))))]
1775 if (which_alternative == 0)
1777 unsigned bitnum = INTVAL (operands[1]) & 0x1f;
1778 operands[1] = GEN_INT (bitnum);
1779 switch (GET_CODE (operands[3]))
1781 case EQ: return \"bbsi\\t%0, %d1, %2\";
1782 case NE: return \"bbci\\t%0, %d1, %2\";
1788 switch (GET_CODE (operands[3]))
1790 case EQ: return \"bbs\\t%0, %1, %2\";
1791 case NE: return \"bbc\\t%0, %1, %2\";
1795 fatal_insn (\"unexpected branch operator\", operands[3]);
1798 [(set_attr "type" "jump")
1799 (set_attr "mode" "none")
1800 (set_attr "length" "3")])
1802 (define_insn "*masktrue"
1804 (if_then_else (match_operator 3 "boolean_operator"
1805 [(and:SI (match_operand:SI 0 "register_operand" "r")
1806 (match_operand:SI 1 "register_operand" "r"))
1808 (label_ref (match_operand 2 "" ""))
1813 switch (GET_CODE (operands[3]))
1815 case EQ: return \"bnone\\t%0, %1, %2\";
1816 case NE: return \"bany\\t%0, %1, %2\";
1819 fatal_insn (\"unexpected branch operator\", operands[3]);
1822 [(set_attr "type" "jump")
1823 (set_attr "mode" "none")
1824 (set_attr "length" "3")])
1826 (define_insn "*maskfalse"
1828 (if_then_else (match_operator 3 "boolean_operator"
1829 [(and:SI (match_operand:SI 0 "register_operand" "r")
1830 (match_operand:SI 1 "register_operand" "r"))
1833 (label_ref (match_operand 2 "" ""))))]
1837 switch (GET_CODE (operands[3]))
1839 case EQ: return \"bany\\t%0, %1, %2\";
1840 case NE: return \"bnone\\t%0, %1, %2\";
1843 fatal_insn (\"unexpected branch operator\", operands[3]);
1846 [(set_attr "type" "jump")
1847 (set_attr "mode" "none")
1848 (set_attr "length" "3")])
1851 ;; Define the loop insns that is used by bct optimization to represent the
1852 ;; start and end of a zero-overhead loop (in loop.c). This start template
1853 ;; generates the loop insn, the end template doesn't generate any instructions
1854 ;; since since loop end is handled in hardware.
1856 (define_insn "zero_cost_loop_start"
1857 [(set (pc) (if_then_else (eq (match_operand:SI 0 "register_operand" "a")
1859 (label_ref (match_operand 1 "" ""))
1862 (plus:SI (match_dup 0) (const_int -1)))]
1865 [(set_attr "type" "jump")
1866 (set_attr "mode" "none")
1867 (set_attr "length" "3")])
1869 (define_insn "zero_cost_loop_end"
1870 [(set (pc) (if_then_else (ne (reg:SI 19) (const_int 0))
1871 (label_ref (match_operand 0 "" ""))
1874 (plus:SI (reg:SI 19) (const_int -1)))]
1877 xtensa_emit_loop_end (insn, operands);
1880 [(set_attr "type" "jump")
1881 (set_attr "mode" "none")
1882 (set_attr "length" "0")])
1886 ;; ....................
1888 ;; SETTING A REGISTER FROM A COMPARISON
1890 ;; ....................
1893 (define_expand "seq"
1894 [(set (match_operand:SI 0 "register_operand" "")
1899 operands[1] = gen_rtx (EQ, SImode, branch_cmp[0], branch_cmp[1]);
1900 if (!xtensa_expand_scc (operands)) FAIL;
1904 (define_expand "sne"
1905 [(set (match_operand:SI 0 "register_operand" "")
1910 operands[1] = gen_rtx (NE, SImode, branch_cmp[0], branch_cmp[1]);
1911 if (!xtensa_expand_scc (operands)) FAIL;
1915 (define_expand "sgt"
1916 [(set (match_operand:SI 0 "register_operand" "")
1921 operands[1] = gen_rtx (GT, SImode, branch_cmp[0], branch_cmp[1]);
1922 if (!xtensa_expand_scc (operands)) FAIL;
1926 (define_expand "sge"
1927 [(set (match_operand:SI 0 "register_operand" "")
1932 operands[1] = gen_rtx (GE, SImode, branch_cmp[0], branch_cmp[1]);
1933 if (!xtensa_expand_scc (operands)) FAIL;
1937 (define_expand "slt"
1938 [(set (match_operand:SI 0 "register_operand" "")
1943 operands[1] = gen_rtx (LT, SImode, branch_cmp[0], branch_cmp[1]);
1944 if (!xtensa_expand_scc (operands)) FAIL;
1948 (define_expand "sle"
1949 [(set (match_operand:SI 0 "register_operand" "")
1954 operands[1] = gen_rtx (LE, SImode, branch_cmp[0], branch_cmp[1]);
1955 if (!xtensa_expand_scc (operands)) FAIL;
1961 ;; ....................
1963 ;; CONDITIONAL MOVES
1965 ;; ....................
1968 (define_expand "movsicc"
1969 [(set (match_operand:SI 0 "register_operand" "")
1970 (if_then_else:SI (match_operand 1 "comparison_operator" "")
1971 (match_operand:SI 2 "register_operand" "")
1972 (match_operand:SI 3 "register_operand" "")))]
1976 if (!xtensa_expand_conditional_move (operands, 0)) FAIL;
1980 (define_expand "movsfcc"
1981 [(set (match_operand:SF 0 "register_operand" "")
1982 (if_then_else:SF (match_operand 1 "comparison_operator" "")
1983 (match_operand:SF 2 "register_operand" "")
1984 (match_operand:SF 3 "register_operand" "")))]
1988 if (!xtensa_expand_conditional_move (operands, 1)) FAIL;
1992 (define_insn "movsicc_internal0"
1993 [(set (match_operand:SI 0 "register_operand" "=a,a")
1994 (if_then_else:SI (match_operator 4 "branch_operator"
1995 [(match_operand:SI 1 "register_operand" "r,r")
1997 (match_operand:SI 2 "register_operand" "r,0")
1998 (match_operand:SI 3 "register_operand" "0,r")))]
2002 if (which_alternative == 0)
2004 switch (GET_CODE (operands[4]))
2006 case EQ: return \"moveqz\\t%0, %2, %1\";
2007 case NE: return \"movnez\\t%0, %2, %1\";
2008 case LT: return \"movltz\\t%0, %2, %1\";
2009 case GE: return \"movgez\\t%0, %2, %1\";
2015 switch (GET_CODE (operands[4]))
2017 case EQ: return \"movnez\\t%0, %3, %1\";
2018 case NE: return \"moveqz\\t%0, %3, %1\";
2019 case LT: return \"movgez\\t%0, %3, %1\";
2020 case GE: return \"movltz\\t%0, %3, %1\";
2024 fatal_insn (\"unexpected cmov operator\", operands[4]);
2027 [(set_attr "type" "move,move")
2028 (set_attr "mode" "SI")
2029 (set_attr "length" "3,3")])
2031 (define_insn "movsicc_internal1"
2032 [(set (match_operand:SI 0 "register_operand" "=a,a")
2033 (if_then_else:SI (match_operator 4 "boolean_operator"
2034 [(match_operand:CC 1 "register_operand" "b,b")
2036 (match_operand:SI 2 "register_operand" "r,0")
2037 (match_operand:SI 3 "register_operand" "0,r")))]
2041 int isEq = (GET_CODE (operands[4]) == EQ);
2042 switch (which_alternative)
2045 if (isEq) return \"movf\\t%0, %2, %1\";
2046 return \"movt\\t%0, %2, %1\";
2048 if (isEq) return \"movt\\t%0, %3, %1\";
2049 return \"movf\\t%0, %3, %1\";
2054 [(set_attr "type" "move,move")
2055 (set_attr "mode" "SI")
2056 (set_attr "length" "3,3")])
2058 (define_insn "movsfcc_internal0"
2059 [(set (match_operand:SF 0 "register_operand" "=a,a,f,f")
2060 (if_then_else:SF (match_operator 4 "branch_operator"
2061 [(match_operand:SI 1 "register_operand" "r,r,r,r")
2063 (match_operand:SF 2 "register_operand" "r,0,f,0")
2064 (match_operand:SF 3 "register_operand" "0,r,0,f")))]
2068 if (which_alternative == 0)
2070 switch (GET_CODE (operands[4]))
2072 case EQ: return \"moveqz\\t%0, %2, %1\";
2073 case NE: return \"movnez\\t%0, %2, %1\";
2074 case LT: return \"movltz\\t%0, %2, %1\";
2075 case GE: return \"movgez\\t%0, %2, %1\";
2079 else if (which_alternative == 1)
2081 switch (GET_CODE (operands[4]))
2083 case EQ: return \"movnez\\t%0, %3, %1\";
2084 case NE: return \"moveqz\\t%0, %3, %1\";
2085 case LT: return \"movgez\\t%0, %3, %1\";
2086 case GE: return \"movltz\\t%0, %3, %1\";
2090 else if (which_alternative == 2)
2092 switch (GET_CODE (operands[4]))
2094 case EQ: return \"moveqz.s %0, %2, %1\";
2095 case NE: return \"movnez.s %0, %2, %1\";
2096 case LT: return \"movltz.s %0, %2, %1\";
2097 case GE: return \"movgez.s %0, %2, %1\";
2101 else if (which_alternative == 3)
2103 switch (GET_CODE (operands[4]))
2105 case EQ: return \"movnez.s %0, %3, %1\";
2106 case NE: return \"moveqz.s %0, %3, %1\";
2107 case LT: return \"movgez.s %0, %3, %1\";
2108 case GE: return \"movltz.s %0, %3, %1\";
2112 fatal_insn (\"unexpected cmov operator\", operands[4]);
2115 [(set_attr "type" "move,move,move,move")
2116 (set_attr "mode" "SF")
2117 (set_attr "length" "3,3,3,3")])
2119 (define_insn "movsfcc_internal1"
2120 [(set (match_operand:SF 0 "register_operand" "=a,a,f,f")
2121 (if_then_else:SF (match_operator 4 "boolean_operator"
2122 [(match_operand:CC 1 "register_operand" "b,b,b,b")
2124 (match_operand:SF 2 "register_operand" "r,0,f,0")
2125 (match_operand:SF 3 "register_operand" "0,r,0,f")))]
2129 int isEq = (GET_CODE (operands[4]) == EQ);
2130 switch (which_alternative)
2133 if (isEq) return \"movf\\t%0, %2, %1\";
2134 return \"movt\\t%0, %2, %1\";
2136 if (isEq) return \"movt\\t%0, %3, %1\";
2137 return \"movf\\t%0, %3, %1\";
2139 if (isEq) return \"movf.s\\t%0, %2, %1\";
2140 return \"movt.s\\t%0, %2, %1\";
2142 if (isEq) return \"movt.s\\t%0, %3, %1\";
2143 return \"movf.s\\t%0, %3, %1\";
2148 [(set_attr "type" "move,move,move,move")
2149 (set_attr "mode" "SF")
2150 (set_attr "length" "3,3,3,3")])
2154 ;; ....................
2156 ;; FLOATING POINT COMPARISONS
2158 ;; ....................
2161 (define_insn "seq_sf"
2162 [(set (match_operand:CC 0 "register_operand" "=b")
2163 (eq:CC (match_operand:SF 1 "register_operand" "f")
2164 (match_operand:SF 2 "register_operand" "f")))]
2166 "oeq.s\\t%0, %1, %2"
2167 [(set_attr "type" "farith")
2168 (set_attr "mode" "BL")
2169 (set_attr "length" "3")])
2171 (define_insn "slt_sf"
2172 [(set (match_operand:CC 0 "register_operand" "=b")
2173 (lt:CC (match_operand:SF 1 "register_operand" "f")
2174 (match_operand:SF 2 "register_operand" "f")))]
2176 "olt.s\\t%0, %1, %2"
2177 [(set_attr "type" "farith")
2178 (set_attr "mode" "BL")
2179 (set_attr "length" "3")])
2181 (define_insn "sle_sf"
2182 [(set (match_operand:CC 0 "register_operand" "=b")
2183 (le:CC (match_operand:SF 1 "register_operand" "f")
2184 (match_operand:SF 2 "register_operand" "f")))]
2186 "ole.s\\t%0, %1, %2"
2187 [(set_attr "type" "farith")
2188 (set_attr "mode" "BL")
2189 (set_attr "length" "3")])
2193 ;; ....................
2195 ;; UNCONDITIONAL BRANCHES
2197 ;; ....................
2202 (label_ref (match_operand 0 "" "")))]
2205 [(set_attr "type" "jump")
2206 (set_attr "mode" "none")
2207 (set_attr "length" "3")])
2209 (define_expand "indirect_jump"
2210 [(set (pc) (match_operand 0 "register_operand" ""))]
2214 rtx dest = operands[0];
2215 if (GET_CODE (dest) != REG || GET_MODE (dest) != Pmode)
2216 operands[0] = copy_to_mode_reg (Pmode, dest);
2218 emit_jump_insn (gen_indirect_jump_internal (dest));
2222 (define_insn "indirect_jump_internal"
2223 [(set (pc) (match_operand:SI 0 "register_operand" "r"))]
2226 [(set_attr "type" "jump")
2227 (set_attr "mode" "none")
2228 (set_attr "length" "3")])
2231 (define_expand "tablejump"
2232 [(use (match_operand:SI 0 "register_operand" ""))
2233 (use (label_ref (match_operand 1 "" "")))]
2237 rtx target = operands[0];
2240 /* For PIC, the table entry is relative to the start of the table. */
2241 rtx label = gen_reg_rtx (SImode);
2242 target = gen_reg_rtx (SImode);
2243 emit_move_insn (label, gen_rtx_LABEL_REF (SImode, operands[1]));
2244 emit_insn (gen_addsi3 (target, operands[0], label));
2246 emit_jump_insn (gen_tablejump_internal (target, operands[1]));
2250 (define_insn "tablejump_internal"
2252 (match_operand:SI 0 "register_operand" "r"))
2253 (use (label_ref (match_operand 1 "" "")))]
2256 [(set_attr "type" "jump")
2257 (set_attr "mode" "none")
2258 (set_attr "length" "3")])
2262 ;; ....................
2266 ;; ....................
2269 (define_expand "sym_PLT"
2270 [(const (unspec [(match_operand:SI 0 "" "")] UNSPEC_PLT))]
2274 (define_expand "call"
2275 [(call (match_operand 0 "memory_operand" "")
2276 (match_operand 1 "" ""))]
2280 rtx addr = XEXP (operands[0], 0);
2281 if (flag_pic && GET_CODE (addr) == SYMBOL_REF && !SYMBOL_REF_FLAG (addr))
2282 addr = gen_sym_PLT (addr);
2283 if (!call_insn_operand (addr, VOIDmode))
2284 XEXP (operands[0], 0) = copy_to_mode_reg (Pmode, addr);
2287 (define_insn "call_internal"
2288 [(call (mem (match_operand:SI 0 "call_insn_operand" "n,i,r"))
2289 (match_operand 1 "" "i,i,i"))]
2292 return xtensa_emit_call (0, operands);
2294 [(set_attr "type" "call")
2295 (set_attr "mode" "none")
2296 (set_attr "length" "3")])
2298 (define_expand "call_value"
2299 [(set (match_operand 0 "register_operand" "")
2300 (call (match_operand 1 "memory_operand" "")
2301 (match_operand 2 "" "")))]
2305 rtx addr = XEXP (operands[1], 0);
2306 if (flag_pic && GET_CODE (addr) == SYMBOL_REF && !SYMBOL_REF_FLAG (addr))
2307 addr = gen_sym_PLT (addr);
2308 if (!call_insn_operand (addr, VOIDmode))
2309 XEXP (operands[1], 0) = copy_to_mode_reg (Pmode, addr);
2312 ;; cannot combine constraints for operand 0 into "afvb"
2313 ;; reload.c:find_reloads seems to assume that grouped constraints somehow
2314 ;; specify related register classes, and when they don't the constraints
2315 ;; fail to match. By not grouping the constraints, we get the correct
2317 (define_insn "call_value_internal"
2318 [(set (match_operand 0 "register_operand" "=af,af,af,v,v,v,b,b,b")
2319 (call (mem (match_operand:SI 1 "call_insn_operand"
2320 "n,i,r,n,i,r,n,i,r"))
2321 (match_operand 2 "" "i,i,i,i,i,i,i,i,i")))]
2324 return xtensa_emit_call (1, operands);
2326 [(set_attr "type" "call")
2327 (set_attr "mode" "none")
2328 (set_attr "length" "3")])
2330 (define_insn "return"
2332 (use (reg:SI A0_REG))]
2336 return (TARGET_DENSITY ? \"retw.n\" : \"retw\");
2338 [(set_attr "type" "jump")
2339 (set_attr "mode" "none")
2340 (set_attr "length" "2")])
2344 ;; ....................
2348 ;; ....................
2356 return (TARGET_DENSITY ? \"nop.n\" : \"nop\");
2358 [(set_attr "type" "nop")
2359 (set_attr "mode" "none")
2360 (set_attr "length" "3")])
2362 (define_expand "nonlocal_goto"
2363 [(match_operand:SI 0 "general_operand" "")
2364 (match_operand:SI 1 "general_operand" "")
2365 (match_operand:SI 2 "general_operand" "")
2366 (match_operand:SI 3 "" "")]
2370 xtensa_expand_nonlocal_goto (operands);
2374 ;; Setting up a frame pointer is tricky for Xtensa because GCC doesn't
2375 ;; know if a frame pointer is required until the reload pass, and
2376 ;; because there may be an incoming argument value in the hard frame
2377 ;; pointer register (a7). If there is an incoming argument in that
2378 ;; register, the "set_frame_ptr" insn gets inserted immediately after
2379 ;; the insn that copies the incoming argument to a pseudo or to the
2380 ;; stack. This serves several purposes here: (1) it keeps the
2381 ;; optimizer from copy-propagating or scheduling the use of a7 as an
2382 ;; incoming argument away from the beginning of the function; (2) we
2383 ;; can use a post-reload splitter to expand away the insn if a frame
2384 ;; pointer is not required, so that the post-reload scheduler can do
2385 ;; the right thing; and (3) it makes it easy for xtensa_reorg() to
2386 ;; search for this insn to determine whether it should add a new insn
2387 ;; to set up the frame pointer.
2389 (define_insn "set_frame_ptr"
2390 [(unspec_volatile [(const_int 0)] UNSPECV_SET_FP)]
2394 if (frame_pointer_needed)
2395 return \"mov\\ta7, sp\";
2398 [(set_attr "type" "move")
2399 (set_attr "mode" "SI")
2400 (set_attr "length" "3")])
2402 ;; Post-reload splitter to remove fp assignment when it's not needed.
2404 [(unspec_volatile [(const_int 0)] UNSPECV_SET_FP)]
2405 "reload_completed && !frame_pointer_needed"
2406 [(unspec [(const_int 0)] UNSPEC_NOP)]
2409 ;; The preceding splitter needs something to split the insn into;
2410 ;; things start breaking if the result is just a "use" so instead we
2411 ;; generate the following insn.
2412 (define_insn "*unspec_nop"
2413 [(unspec [(const_int 0)] UNSPEC_NOP)]
2416 [(set_attr "type" "nop")
2417 (set_attr "mode" "none")
2418 (set_attr "length" "0")])
2420 ;; The fix_return_addr pattern sets the high 2 bits of an address in a
2421 ;; register to match the high bits of the current PC.
2423 (define_insn "fix_return_addr"
2424 [(set (match_operand:SI 0 "register_operand" "=a")
2425 (unspec:SI [(match_operand:SI 1 "register_operand" "r")]
2427 (clobber (match_scratch:SI 2 "=r"))
2428 (clobber (match_scratch:SI 3 "=r"))]
2430 "mov\\t%2, a0\;call0\\t0f\;.align\\t4\;0:\;mov\\t%3, a0\;mov\\ta0, %2\;\
2431 srli\\t%3, %3, 30\;slli\\t%0, %1, 2\;ssai\\t2\;src\\t%0, %3, %0"
2432 [(set_attr "type" "multi")
2433 (set_attr "mode" "SI")
2434 (set_attr "length" "24")])
2438 ;; ....................
2442 ;; ....................
2447 (define_insn "*booltrue"
2449 (if_then_else (match_operator 2 "boolean_operator"
2450 [(match_operand:CC 0 "register_operand" "b")
2452 (label_ref (match_operand 1 "" ""))
2457 if (GET_CODE (operands[2]) == EQ)
2458 return \"bf\\t%0, %1\";
2460 return \"bt\\t%0, %1\";
2462 [(set_attr "type" "jump")
2463 (set_attr "mode" "none")
2464 (set_attr "length" "3")])
2466 (define_insn "*boolfalse"
2468 (if_then_else (match_operator 2 "boolean_operator"
2469 [(match_operand:CC 0 "register_operand" "b")
2472 (label_ref (match_operand 1 "" ""))))]
2476 if (GET_CODE (operands[2]) == EQ)
2477 return \"bt\\t%0, %1\";
2479 return \"bf\\t%0, %1\";
2481 [(set_attr "type" "jump")
2482 (set_attr "mode" "none")
2483 (set_attr "length" "3")])