1 ;; Machine Description for TI PRU.
2 ;; Copyright (C) 2014-2019 Free Software Foundation, Inc.
3 ;; Contributed by Dimitar Dimitrov <dimitar@dinux.eu>
4 ;; Based on the NIOS2 GCC port.
6 ;; This file is part of GCC.
8 ;; GCC is free software; you can redistribute it and/or modify
9 ;; it under the terms of the GNU General Public License as published by
10 ;; the Free Software Foundation; either version 3, or (at your option)
13 ;; GCC is distributed in the hope that it will be useful,
14 ;; but WITHOUT ANY WARRANTY; without even the implied warranty of
15 ;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
16 ;; GNU General Public License for more details.
18 ;; You should have received a copy of the GNU General Public License
19 ;; along with GCC; see the file COPYING3. If not see
20 ;; <http://www.gnu.org/licenses/>.
25 (FIRST_ARG_REGNUM 56) ; Argument registers.
26 (LAST_ARG_REGNUM 119) ;
27 (FIRST_RETVAL_REGNUM 56) ; Return value registers.
28 (LAST_RETVAL_REGNUM 60) ;
29 (FIRST_CALLEE_SAVED_REGNUM 12) ; Callee saved registers.
30 (LAST_CALEE_SAVED_REGNUM 55) ;
31 (PROLOGUE_TEMP_REGNUM 4) ; Temporary register to use in prologue.
33 (RA_REGNUM 14) ; Return address register r3.w2.
34 (FP_REGNUM 16) ; Frame pointer register.
35 (MULDST_REGNUM 104) ; Multiply destination register.
36 (MULSRC0_REGNUM 112) ; Multiply source register.
37 (MULSRC1_REGNUM 116) ; Multiply source register.
38 (LAST_NONIO_GP_REGNUM 119) ; Last non-I/O general purpose register.
39 (LOOPCNTR_REGNUM 128) ; internal LOOP counter register
40 (LAST_GP_REGNUM 132) ; Last general purpose register.
42 ;; Target register definitions.
43 (STACK_POINTER_REGNUM 8)
44 (HARD_FRAME_POINTER_REGNUM FP_REGNUM)
46 (FRAME_POINTER_REGNUM 136)
47 (ARG_POINTER_REGNUM 140)
48 (FIRST_PSEUDO_REGISTER 144)
52 ;; Enumeration of UNSPECs.
54 (define_c_enum "unspecv" [
55 UNSPECV_DELAY_CYCLES_START
56 UNSPECV_DELAY_CYCLES_END
57 UNSPECV_DELAY_CYCLES_2X_HI
58 UNSPECV_DELAY_CYCLES_2X_SI
59 UNSPECV_DELAY_CYCLES_1
67 ; Length of an instruction (in bytes).
68 (define_attr "length" "" (const_int 4))
70 "unknown,complex,control,alu,cond_alu,st,ld,shift"
71 (const_string "complex"))
73 (define_asm_attributes
74 [(set_attr "length" "4")
75 (set_attr "type" "complex")])
77 ; There is no pipeline, so our scheduling description is simple.
78 (define_automaton "pru")
79 (define_cpu_unit "cpu" "pru")
81 (define_insn_reservation "everything" 1 (match_test "true") "cpu")
83 (include "predicates.md")
84 (include "constraints.md")
86 ;; All supported direct move-modes
87 (define_mode_iterator MOV8_16_32 [QI QQ UQQ
89 SI SQ USQ SA USA SF SD])
91 (define_mode_iterator MOV8_16 [QI QQ UQQ
93 (define_mode_iterator MOV32 [SI SQ USQ SA USA SF SD])
94 (define_mode_iterator MOV64 [DI DF DD DQ UDQ])
95 (define_mode_iterator QISI [QI HI SI])
96 (define_mode_iterator HISI [HI SI])
97 (define_mode_iterator SFDF [SF DF])
99 ;; EQS0/1 for extension source 0/1 and EQD for extension destination patterns.
100 (define_mode_iterator EQS0 [QI HI SI])
101 (define_mode_iterator EQS1 [QI HI SI])
102 (define_mode_iterator EQD [QI HI SI])
104 ;; GCC sign-extends its integer constants. Hence 0x80 will be represented
105 ;; as -128 for QI mode and 128 for HI and SI modes. To cope with this,
106 ;; use different constraints to match UBYTE in different modes.
108 ;; Wherever this iterator is used, the corresponding operand has the 'u'
109 ;; print format modifier. That is how the QI signedness is cured, and
110 ;; the generated assembly contains unsigned constants.
112 ;; If the pattern has no QI operands, then this iterator need not be used.
114 ;; Note that we do not require "uhword_constr" since ALU instructions
115 ;; can use only UBYTE constants. The MOV patterns are already separately
116 ;; defined for each size, hence no need for an iterator.
117 (define_mode_attr ubyte_constr [(QI "O") (HI "I") (SI "I")])
121 (define_expand "mov<mode>"
122 [(set (match_operand:MOV8_16_32 0 "nonimmediate_operand")
123 (match_operand:MOV8_16_32 1 "general_operand"))]
126 /* It helps to split constant loading and memory access
127 early, so that the LDI/LDI32 instructions can be hoisted
128 outside a loop body. */
129 if (MEM_P (operands[0]))
130 operands[1] = force_reg (<MODE>mode, operands[1]);
133 ;; Keep a single pattern for 32 bit MOV operations. LRA requires that the
134 ;; movXX patterns be unified for any given mode.
136 ;; Note: Assume that Program Mem (T constraint) can fit in 16 bits!
137 (define_insn "prumov<mode>"
138 [(set (match_operand:MOV32 0 "nonimmediate_operand" "=m,r,r,r,r,r")
139 (match_operand:MOV32 1 "general_operand" "r,m,r,T,J,iF"))]
142 sb%B0o\\t%b1, %0, %S0
143 lb%B1o\\t%b0, %1, %S1
148 [(set_attr "type" "st,ld,alu,alu,alu,alu")
149 (set_attr "length" "4,4,4,4,4,8")])
152 ;; Separate pattern for 8 and 16 bit moves, since LDI32 pseudo instruction
153 ;; cannot handle byte and word-sized registers.
155 ;; Note: Constraint N is fine for both QI and HI mode, since it is used
156 ;; in the context of 16 bit constant integer.
157 (define_insn "prumov<mode>"
158 [(set (match_operand:MOV8_16 0 "nonimmediate_operand" "=m,r,r,r,r")
159 (match_operand:MOV8_16 1 "general_operand" "r,m,r,T,N"))]
162 sb%B0o\\t%b1, %0, %S0
163 lb%B1o\\t%b0, %1, %S1
166 ldi\\t%0, (%1) & 0xffff"
167 [(set_attr "type" "st,ld,alu,alu,alu")
168 (set_attr "length" "4")])
171 ; Pmode is 32 bits for PRU so symbolic constants cannot be 64 bits. Hence
172 ; this pattern handles only numeric constants.
174 ; Note: Unlike the arithmetics, here we cannot use "&" output modifier.
175 ; GCC expects to be able to move registers around "no matter what".
176 ; Forcing DI reg alignment (akin to microblaze's HARD_REGNO_MODE_OK)
177 ; does not seem efficient, and will violate TI ABI.
178 (define_insn "mov<mode>"
179 [(set (match_operand:MOV64 0 "nonimmediate_operand" "=m,r,r,r,r,r")
180 (match_operand:MOV64 1 "general_operand" "r,m,r,T,J,nF"))]
183 switch (which_alternative)
186 return "sb%B0o\\t%b1, %0, %S0";
188 return "lb%B1o\\t%b0, %1, %S1";
190 /* careful with overlapping source and destination regs. */
191 gcc_assert (GP_REG_P (REGNO (operands[0])));
192 gcc_assert (GP_REG_P (REGNO (operands[1])));
193 if (REGNO (operands[0]) == (REGNO (operands[1]) + 4))
194 return "mov\\t%N0, %N1\;mov\\t%F0, %F1";
196 return "mov\\t%F0, %F1\;mov\\t%N0, %N1";
198 return "ldi\\t%F0, %%pmem(%1)\;ldi\\t%N0, 0";
200 return "ldi\\t%F0, %1\;ldi\\t%N0, 0";
202 return "ldi32\\t%F0, %w1\;ldi32\\t%N0, %W1";
207 [(set_attr "type" "st,ld,alu,alu,alu,alu")
208 (set_attr "length" "4,4,8,8,8,16")])
211 ; load_multiple pattern(s).
213 ; ??? Due to reload problems with replacing registers inside match_parallel
214 ; we currently support load_multiple/store_multiple only after reload.
216 ; Idea taken from the s390 port.
218 (define_expand "load_multiple"
219 [(match_par_dup 3 [(set (match_operand 0 "")
220 (match_operand 1 ""))
221 (use (match_operand 2 ""))])]
228 poly_int64 base_offs;
231 /* Support only loading a constant number of fixed-point registers from
233 if (GET_CODE (operands[2]) != CONST_INT
234 || GET_CODE (operands[1]) != MEM
235 || GET_CODE (operands[0]) != REG)
238 count = INTVAL (operands[2]);
239 regno = REGNO (operands[0]);
240 mode = GET_MODE (operands[0]);
244 operands[3] = gen_rtx_PARALLEL (VOIDmode, rtvec_alloc (count));
246 gcc_assert (!can_create_pseudo_p ());
248 base_reg = strip_offset (XEXP (operands[1], 0), &base_offs);
249 if (GET_CODE (base_reg) != REG)
252 for (i = 0; i < count; i++)
253 XVECEXP (operands[3], 0, i)
254 = gen_rtx_SET (gen_rtx_REG (mode, regno + i),
255 change_address (operands[1], mode,
256 plus_constant (Pmode, base_reg,
257 base_offs + i * GET_MODE_SIZE (mode))));
260 (define_insn "*pru_load_multiple"
261 [(match_parallel 0 "load_multiple_operation"
262 [(set (match_operand:QI 1 "register_operand" "=r")
263 (match_operand:QI 2 "memory_operand" "m"))])]
266 int nregs = XVECLEN (operands[0], 0);
267 operands[0] = GEN_INT (nregs);
268 return "lb%B2o\\t%b1, %2, %0";
270 [(set_attr "type" "ld")])
273 ; store multiple pattern(s).
276 (define_expand "store_multiple"
277 [(match_par_dup 3 [(set (match_operand 0 "")
278 (match_operand 1 ""))
279 (use (match_operand 2 ""))])]
286 poly_int64 base_offs;
289 /* Support only storing a constant number of fixed-point registers to
291 if (GET_CODE (operands[2]) != CONST_INT
292 || GET_CODE (operands[0]) != MEM
293 || GET_CODE (operands[1]) != REG)
296 count = INTVAL (operands[2]);
297 regno = REGNO (operands[1]);
298 mode = GET_MODE (operands[1]);
302 operands[3] = gen_rtx_PARALLEL (VOIDmode, rtvec_alloc (count));
304 gcc_assert (!can_create_pseudo_p ());
306 base_reg = strip_offset (XEXP (operands[0], 0), &base_offs);
307 if (GET_CODE (base_reg) != REG)
310 for (i = 0; i < count; i++)
311 XVECEXP (operands[3], 0, i)
312 = gen_rtx_SET (change_address (operands[0], mode,
313 plus_constant (Pmode, base_reg,
314 base_offs + i * GET_MODE_SIZE (mode))),
315 gen_rtx_REG (mode, regno + i));
318 (define_insn "*pru_store_multiple"
319 [(match_parallel 0 "store_multiple_operation"
320 [(set (match_operand:QI 1 "memory_operand" "=m")
321 (match_operand:QI 2 "register_operand" "r"))])]
324 int nregs = XVECLEN (operands[0], 0);
325 operands[0] = GEN_INT (nregs);
326 return "sb%B1o\\t%b2, %1, %0";
328 [(set_attr "type" "st")])
330 ;; Zero extension patterns
332 ;; Unfortunately we cannot use lbbo to load AND zero-extent a value.
333 ;; The burst length parameter of the LBBO instruction designates not only
334 ;; the number of memory data bytes fetched, but also the number of register
335 ;; byte fields written.
336 (define_expand "zero_extend<EQS0:mode><EQD:mode>2"
337 [(set (match_operand:EQD 0 "register_operand")
338 (zero_extend:EQD (match_operand:EQS0 1 "register_operand")))]
342 (define_insn "*zero_extend<EQS0:mode><EQD:mode>2"
343 [(set (match_operand:EQD 0 "register_operand" "=r")
344 (zero_extend:EQD (match_operand:EQS0 1 "register_operand" "r")))]
347 [(set_attr "type" "alu")])
349 ;; Sign extension patterns. We have to emulate them due to lack of
350 ;; signed operations in PRU's ALU.
352 (define_insn "extend<EQS0:mode><EQD:mode>2"
353 [(set (match_operand:EQD 0 "register_operand" "=r")
354 (sign_extend:EQD (match_operand:EQS0 1 "register_operand" "r")))]
357 return pru_output_sign_extend (operands);
359 [(set_attr "type" "complex")
360 (set_attr "length" "12")])
363 ;; We define it solely to allow combine to choose SImode
364 ;; for word mode when trying to match our cbranch_qbbx_* insn.
366 ;; Check how combine.c:make_extraction() uses
367 ;; get_best_reg_extraction_insn() to select the op size.
368 (define_insn "extzv<mode>"
369 [(set (match_operand:QISI 0 "register_operand" "=r")
371 (match_operand:QISI 1 "register_operand" "r")
372 (match_operand:QISI 2 "const_int_operand" "i")
373 (match_operand:QISI 3 "const_int_operand" "i")))]
375 "lsl\\t%0, %1, (%S0 * 8 - %2 - %3)\;lsr\\t%0, %0, (%S0 * 8 - %2)"
376 [(set_attr "type" "complex")
377 (set_attr "length" "8")])
381 ;; Arithmetic Operations
383 (define_expand "add<mode>3"
384 [(set (match_operand:QISI 0 "register_operand")
385 (plus:QISI (match_operand:QISI 1 "register_operand")
386 (match_operand:QISI 2 "nonmemory_operand")))]
390 (define_insn "adddi3"
391 [(set (match_operand:DI 0 "register_operand" "=&r,&r,&r")
392 (plus:DI (match_operand:DI 1 "register_operand" "%r,r,r")
393 (match_operand:DI 2 "reg_or_ubyte_operand" "r,I,M")))]
396 add\\t%F0, %F1, %F2\;adc\\t%N0, %N1, %N2
397 add\\t%F0, %F1, %2\;adc\\t%N0, %N1, 0
398 sub\\t%F0, %F1, %n2\;suc\\t%N0, %N1, 0"
399 [(set_attr "type" "alu")
400 (set_attr "length" "8")])
402 (define_expand "sub<mode>3"
403 [(set (match_operand:QISI 0 "register_operand")
404 (minus:QISI (match_operand:QISI 1 "reg_or_ubyte_operand")
405 (match_operand:QISI 2 "reg_or_ubyte_operand")))]
409 (define_insn "subdi3"
410 [(set (match_operand:DI 0 "register_operand" "=&r,&r")
411 (minus:DI (match_operand:DI 1 "reg_or_ubyte_operand" "r,I")
412 (match_operand:DI 2 "register_operand" "r,r")))]
415 sub\\t%F0, %F1, %F2\;suc\\t%N0, %N1, %N2
416 rsb\\t%F0, %F2, %1\;rsc\\t%N0, %N2, 0"
417 [(set_attr "type" "alu")
418 (set_attr "length" "8")])
420 ;; Negate and ones complement
422 (define_expand "neg<mode>2"
423 [(set (match_operand:QISI 0 "register_operand")
424 (neg:QISI (match_operand:QISI 1 "register_operand")))]
428 (define_expand "one_cmpl<mode>2"
429 [(set (match_operand:QISI 0 "register_operand")
430 (not:QISI (match_operand:QISI 1 "register_operand")))]
434 ;; Integer logical Operations
436 ;; TODO - add optimized cases that exploit the fact that we can get away
437 ;; with a single machine op for special constants, e.g. UBYTE << (0/8/16/24)
439 (define_code_iterator LOGICAL [and ior xor umin umax])
440 (define_code_attr logical_asm [(and "and") (ior "or") (xor "xor") (umin "min") (umax "max")])
442 (define_code_iterator LOGICAL_BITOP [and ior xor])
443 (define_code_attr logical_bitop_asm [(and "and") (ior "or") (xor "xor")])
445 (define_expand "<code><mode>3"
446 [(set (match_operand:QISI 0 "register_operand")
447 (LOGICAL:QISI (match_operand:QISI 1 "register_operand")
448 (match_operand:QISI 2 "reg_or_ubyte_operand")))]
453 ;; Shift instructions
455 (define_code_iterator SHIFT [ashift lshiftrt])
456 (define_code_attr shift_op [(ashift "ashl") (lshiftrt "lshr")])
457 (define_code_attr shift_asm [(ashift "lsl") (lshiftrt "lsr")])
459 (define_expand "<shift_op><mode>3"
460 [(set (match_operand:QISI 0 "register_operand")
461 (SHIFT:QISI (match_operand:QISI 1 "register_operand")
462 (match_operand:QISI 2 "shift_operand")))]
466 ; Expand to a loop of single-position arithmetic shifts, which
467 ; we can handle. Pseudo code:
469 ; QImode cntr = nshifts & 0xff;
477 ; Note that the number of shifts is truncated to QImode. This is a fair
478 ; assumption for a loop-based shifting implementation.
479 (define_expand "ashr<mode>3"
480 [(set (match_operand:QISI 0 "register_operand")
482 (match_operand:QISI 1 "register_operand")
483 (match_operand:QI 2 "reg_or_const_1_operand")))]
486 rtx dst = operands[0];
487 rtx src = operands[1];
488 rtx nshifts = operands[2];
489 rtx_code_label *loop_label;
490 rtx_code_label *ashr_end_label;
491 rtx test, tmpval, cntr;
493 if (const_1_operand (nshifts, VOIDmode))
495 emit_insn (gen_ashr<mode>3_single (dst, src, nshifts));
499 tmpval = gen_reg_rtx (<MODE>mode);
500 emit_move_insn (tmpval, src);
502 cntr = gen_reg_rtx (QImode);
503 emit_move_insn (cntr, nshifts);
505 loop_label = gen_label_rtx ();
506 ashr_end_label = gen_label_rtx ();
508 emit_label (loop_label);
509 test = gen_rtx_EQ (VOIDmode, cntr, const0_rtx);
510 emit_jump_insn (gen_cbranchqi4 (test, cntr, const0_rtx, ashr_end_label));
512 emit_insn (gen_ashr<mode>3_single (tmpval, tmpval, const1_rtx));
513 emit_insn (gen_addqi3 (cntr, cntr, GEN_INT (-1)));
515 emit_jump_insn (gen_jump (loop_label));
516 JUMP_LABEL (get_last_insn ()) = loop_label;
517 LABEL_NUSES (loop_label)++;
520 emit_label (ashr_end_label);
522 emit_move_insn (dst, tmpval);
527 (define_insn "ashr<mode>3_single"
528 [(set (match_operand:QISI 0 "register_operand" "=r")
530 (match_operand:QISI 1 "register_operand" "r")
531 (match_operand:QI 2 "const_1_operand" "P")))]
533 "lsr\\t%0, %1, 1\;qbbc LSIGN%=, %0, (%S0 * 8) - 2\;set %0, %0, (%S0 * 8) - 1\;LSIGN%=:"
534 [(set_attr "type" "alu")
535 (set_attr "length" "12")])
538 ;; Include ALU patterns with zero-extension of operands. That's where
539 ;; the real insns are defined.
541 (include "alu-zext.md")
543 ;; DI logical ops could be automatically split into WORD-mode ops in
544 ;; expand_binop(). But then we'll miss an opportunity to use SI mode
545 ;; operations, since WORD mode for PRU is QI.
546 (define_insn "<code>di3"
547 [(set (match_operand:DI 0 "register_operand" "=&r,&r")
549 (match_operand:DI 1 "register_operand" "%r,r")
550 (match_operand:DI 2 "reg_or_ubyte_operand" "r,I")))]
553 <logical_bitop_asm>\\t%F0, %F1, %F2\;<logical_bitop_asm>\\t%N0, %N1, %N2
554 <logical_bitop_asm>\\t%F0, %F1, %2\;<logical_bitop_asm>\\t%N0, %N1, 0"
555 [(set_attr "type" "alu")
556 (set_attr "length" "8")])
559 (define_insn "one_cmpldi2"
560 [(set (match_operand:DI 0 "register_operand" "=r")
561 (not:DI (match_operand:DI 1 "register_operand" "r")))]
564 /* careful with overlapping source and destination regs. */
565 gcc_assert (GP_REG_P (REGNO (operands[0])));
566 gcc_assert (GP_REG_P (REGNO (operands[1])));
567 if (REGNO (operands[0]) == (REGNO (operands[1]) + 4))
568 return "not\\t%N0, %N1\;not\\t%F0, %F1";
570 return "not\\t%F0, %F1\;not\\t%N0, %N1";
572 [(set_attr "type" "alu")
573 (set_attr "length" "8")])
575 ;; Multiply instruction. The nop is required to ensure that Rmd0 and Rms0
576 ;; registers are sampled and multiplication is executed on those values.
577 ;; Only after that one cycle can xin obtain the result.
579 (define_insn "mulsi3"
580 [(set (match_operand:SI 0 "pru_muldst_operand" "=Rmd0")
581 (mult:SI (match_operand:SI 1 "pru_mulsrc0_operand" "%Rms0")
582 (match_operand:SI 2 "pru_mulsrc1_operand" "Rms1")))]
584 "nop\;xin\\t0, %0, 4"
585 [(set_attr "type" "alu")
586 (set_attr "length" "8")])
588 ;; Prologue, Epilogue and Return
590 (define_expand "prologue"
594 pru_expand_prologue ();
598 (define_expand "epilogue"
602 pru_expand_epilogue (false);
606 (define_expand "sibcall_epilogue"
610 pru_expand_epilogue (true);
614 (define_insn "return"
616 "pru_can_use_return_insn ()"
619 (define_insn "simple_return"
624 ;; Block any insns from being moved before this point, since the
625 ;; profiling call to mcount can use various registers that aren't
626 ;; saved or used to pass arguments.
628 (define_insn "blockage"
629 [(unspec_volatile [(const_int 0)] UNSPECV_BLOCKAGE)]
632 [(set_attr "type" "unknown")
633 (set_attr "length" "0")])
637 (define_insn "indirect_jump"
638 [(set (pc) (match_operand:SI 0 "register_operand" "r"))]
641 [(set_attr "type" "control")])
645 (label_ref (match_operand 0)))]
648 [(set_attr "type" "control")])
651 (define_expand "call"
652 [(parallel [(call (match_operand 0 "")
653 (match_operand 1 ""))
654 (clobber (reg:HI RA_REGNUM))])]
658 (define_expand "call_value"
659 [(parallel [(set (match_operand 0 "")
660 (call (match_operand 1 "")
661 (match_operand 2 "")))
662 (clobber (reg:HI RA_REGNUM))])]
667 [(call (mem:SI (match_operand:SI 0 "call_operand" "i,r"))
669 (clobber (reg:HI RA_REGNUM))]
674 [(set_attr "type" "control")])
676 (define_insn "*call_value"
677 [(set (match_operand 0)
678 (call (mem:SI (match_operand:SI 1 "call_operand" "i,r"))
680 (clobber (reg:HI RA_REGNUM))]
685 [(set_attr "type" "control")])
687 (define_expand "sibcall"
688 [(parallel [(call (match_operand 0 "")
689 (match_operand 1 ""))
694 (define_expand "sibcall_value"
695 [(parallel [(set (match_operand 0 "")
696 (call (match_operand 1 "")
697 (match_operand 2 "")))
702 (define_insn "*sibcall"
703 [(call (mem:SI (match_operand:SI 0 "call_operand" "i,Rsib"))
706 "SIBLING_CALL_P (insn)"
710 [(set_attr "type" "control")])
712 (define_insn "*sibcall_value"
713 [(set (match_operand 0 "register_operand" "")
714 (call (mem:SI (match_operand:SI 1 "call_operand" "i,Rsib"))
717 "SIBLING_CALL_P (insn)"
721 [(set_attr "type" "control")])
723 (define_insn "*tablejump"
725 (match_operand:SI 0 "register_operand" "r"))
726 (use (label_ref (match_operand 1)))]
729 [(set_attr "type" "control")])
731 ;; Expand the cbranch pattern in order to assign different constraints for
732 ;; signed and unsigned comparisons.
733 (define_expand "cbranch<mode>4"
736 (match_operator 0 "ordered_comparison_operator"
737 [(match_operand:QISI 1 "register_operand")
738 (match_operand:QISI 2 "reg_or_const_int_operand")])
739 (label_ref (match_operand 3 ""))
743 /* Ensure our patterns will be able to handle the particular const_int. */
744 if (CONST_INT_P (operands[2]))
746 HOST_WIDE_INT ival = INTVAL (operands[2]);
748 /* For signed comparisons, we cannot play games with the const_int's
749 sign. PRU patterns do not support negative integer constants. */
750 if (pru_signed_cmp_operator (operands[0], VOIDmode) && !UBYTE_INT (ival))
752 if (can_create_pseudo_p ())
753 operands[2] = force_reg (<MODE>mode, operands[2]);
758 /* For unsigned comparisons, be prepared to handle the QI quirk. */
759 if (pru_cmp_operator (operands[0], VOIDmode)
760 && !const_ubyte_operand (operands[2], <MODE>mode))
762 if (can_create_pseudo_p ())
763 operands[2] = force_reg (<MODE>mode, operands[2]);
770 (define_insn "cbranch<mode>4_unsigned"
773 (match_operator 0 "pru_cmp_operator"
774 [(match_operand:QISI 1 "register_operand" "r")
775 (match_operand:QISI 2 "reg_or_ubyte_operand" "r<QISI:ubyte_constr>")])
776 (label_ref (match_operand 3))
780 const bool is_near = (get_attr_length (insn) == 4);
782 /* PRU comparisons reverse the operand order (OP2 cmp OP1),
783 so swap the condition. */
785 return "qb%P0\t%l3, %1, %u2";
787 return "qb%Q0\t.+8, %1, %u2\;jmp\t%%label(%l3)";
789 [(set_attr "type" "control")
792 (and (ge (minus (match_dup 3) (pc)) (const_int -2040))
793 (le (minus (match_dup 3) (pc)) (const_int 2036)))
797 ;; Unlike ALU operations, the const_int's sign here is important. So we
798 ;; cannot use ubyte_constr.
800 ;; NOTE: The short branch check has no typo! We must be conservative and
801 ;; take into account the worst case of having a signed comparison with a
802 ;; "far taken branch" label, which amounts to 7 instructions.
803 (define_insn "cbranch<mode>4_signed"
806 (match_operator 0 "pru_signed_cmp_operator"
807 [(match_operand:QISI 1 "register_operand" "r,r,r")
808 (match_operand:QISI 2 "reg_or_ubyte_operand" "r,Z,I")])
809 (label_ref (match_operand 3))
813 const int length = (get_attr_length (insn));
814 const bool is_near = (length == 20);
815 enum rtx_code code = GET_CODE (operands[0]);
817 if (which_alternative == 0)
818 return pru_output_signed_cbranch (operands, is_near);
819 else if (which_alternative == 1 && (code == LT || code == GE))
820 return pru_output_signed_cbranch_zeroop2 (operands, is_near);
822 return pru_output_signed_cbranch_ubyteop2 (operands, is_near);
824 [(set_attr "type" "control")
827 (and (ge (minus (match_dup 3) (pc)) (const_int -2020))
828 (le (minus (match_dup 3) (pc)) (const_int 2016)))
832 (define_expand "cbranch<mode>4"
834 (if_then_else (match_operator 0 "pru_fp_comparison_operator"
835 [(match_operand:SFDF 1 "register_operand")
836 (match_operand:SFDF 2 "register_operand")])
837 (label_ref (match_operand 3 ""))
841 rtx t = pru_expand_fp_compare (operands[0], VOIDmode);
843 operands[1] = XEXP (t, 0);
844 operands[2] = XEXP (t, 1);
850 (define_code_iterator BIT_TEST [eq ne])
851 (define_code_attr qbbx_op [(eq "qbbc") (ne "qbbs")])
852 (define_code_attr qbbx_negop [(eq "qbbs") (ne "qbbc")])
854 (define_insn "cbranch_qbbx_<BIT_TEST:code><EQS0:mode><EQS1:mode><EQD:mode>4"
857 (BIT_TEST (zero_extract:EQD
858 (match_operand:EQS0 0 "register_operand" "r")
860 (match_operand:EQS1 1 "reg_or_ubyte_operand" "r<EQS1:ubyte_constr>"))
862 (label_ref (match_operand 2))
866 const int length = (get_attr_length (insn));
867 const bool is_near = (length == 4);
869 return "<BIT_TEST:qbbx_op>\\t%l2, %0, %u1";
871 return "<BIT_TEST:qbbx_negop>\\t.+8, %0, %u1\;jmp\\t%%label(%l2)";
873 [(set_attr "type" "control")
876 (and (ge (minus (match_dup 2) (pc)) (const_int -2048))
877 (le (minus (match_dup 2) (pc)) (const_int 2044)))
881 ;; ::::::::::::::::::::
883 ;; :: Low Overhead Looping - idea "borrowed" from MEP
885 ;; ::::::::::::::::::::
887 ;; This insn is volatile because we'd like it to stay in its original
888 ;; position, just before the loop header. If it stays there, we might
889 ;; be able to convert it into a "loop" insn.
890 (define_insn "doloop_begin_internal<mode>"
891 [(set (match_operand:HISI 0 "register_operand" "=r")
892 (unspec_volatile:HISI
893 [(match_operand:HISI 1 "reg_or_ubyte_operand" "rI")
894 (match_operand 2 "const_int_operand" "")] UNSPECV_LOOP_BEGIN))]
900 (define_expand "doloop_begin"
901 [(use (match_operand 0 "register_operand"))
902 (use (match_operand 1 ""))]
905 pru_emit_doloop (operands, 0);
909 ; Note: "JUMP_INSNs and CALL_INSNs are not allowed to have any output
910 ; reloads;". Hence this insn must be prepared for a counter that is
912 (define_insn "doloop_end_internal<mode>"
914 (if_then_else (ne (match_operand:HISI 0 "nonimmediate_operand" "+r,*m")
916 (label_ref (match_operand 1))
919 (plus:HISI (match_dup 0)
921 (unspec [(match_operand 2 "const_int_operand" "")] UNSPECV_LOOP_END)
922 (clobber (match_scratch:HISI 3 "=X,&r"))]
927 ;; Worst case length:
929 ;; lbbo op3_reg, op3_ptr 4'
930 ;; sub <op3_reg>, 1 4
931 ;; qbeq .+8, <op3_reg>, 0 4
933 ;; sbbo op3_reg, op3_ptr 4
934 [(set (attr "length")
936 (and (ge (minus (pc) (match_dup 1)) (const_int 0))
937 (le (minus (pc) (match_dup 1)) (const_int 1020)))
938 (cond [(eq_attr "alternative" "0") (const_int 4)]
940 (cond [(eq_attr "alternative" "0") (const_int 12)]
943 (define_expand "doloop_end"
944 [(use (match_operand 0 "nonimmediate_operand"))
945 (use (label_ref (match_operand 1 "")))]
948 if (GET_CODE (operands[0]) == REG && GET_MODE (operands[0]) == QImode)
950 pru_emit_doloop (operands, 1);
954 (define_insn "pruloop<mode>"
955 [(set (reg:HISI LOOPCNTR_REGNUM)
956 (unspec:HISI [(match_operand:HISI 0 "reg_or_ubyte_operand" "rI")
957 (label_ref (match_operand 1))]
958 UNSPECV_LOOP_BEGIN))]
962 (define_insn "pruloop_end"
963 [(unspec [(const_int 0)] UNSPECV_LOOP_END)]
966 [(set_attr "length" "0")])
971 (define_insn "delay_cycles_start"
972 [(unspec_volatile [(match_operand 0 "immediate_operand" "i")]
973 UNSPECV_DELAY_CYCLES_START)]
975 "/* Begin %0 cycle delay. */"
976 [(set_attr "length" "0")])
978 (define_insn "delay_cycles_end"
979 [(unspec_volatile [(match_operand 0 "immediate_operand" "i")]
980 UNSPECV_DELAY_CYCLES_END)]
982 "/* End %0 cycle delay. */"
983 [(set_attr "length" "0")])
986 (define_insn "delay_cycles_2x_plus1_hi"
987 [(unspec_volatile [(match_operand:SI 0 "const_uhword_operand" "J")]
988 UNSPECV_DELAY_CYCLES_2X_HI)
989 (clobber (match_scratch:SI 1 "=&r"))]
991 "ldi\\t%1, %0\;sub\\t%1, %1, 1\;qbne\\t.-4, %1, 0"
992 [(set_attr "length" "12")])
995 ; Do not use LDI32 here because we do not want
996 ; to accidentally loose one instruction cycle.
997 (define_insn "delay_cycles_2x_plus2_si"
998 [(unspec_volatile [(match_operand:SI 0 "const_int_operand" "n")]
999 UNSPECV_DELAY_CYCLES_2X_SI)
1000 (clobber (match_scratch:SI 1 "=&r"))]
1002 "ldi\\t%1.w0, %L0\;ldi\\t%1.w2, %H0\;sub\\t%1, %1, 1\;qbne\\t.-4, %1, 0"
1003 [(set_attr "length" "16")])
1005 (define_insn "delay_cycles_1"
1006 [(unspec_volatile [(const_int 0) ] UNSPECV_DELAY_CYCLES_1)]
1008 "nop\\t# delay_cycles_1"
1016 [(set_attr "type" "alu")])
1018 (define_insn "nop_loop_guard"
1021 "nop\\t# Loop end guard"
1022 [(set_attr "type" "alu")])