xref: /netbsd-src/external/gpl3/gcc.old/dist/gcc/config/pru/pru.md (revision 8feb0f0b7eaff0608f8350bbfa3098827b4bb91b)
1;; Machine Description for TI PRU.
2;; Copyright (C) 2014-2020 Free Software Foundation, Inc.
3;; Contributed by Dimitar Dimitrov <dimitar@dinux.eu>
4;; Based on the NIOS2 GCC port.
5;;
6;; This file is part of GCC.
7;;
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)
11;; any later version.
12;;
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.
17;;
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/>.
21
22;; Register numbers.
23(define_constants
24  [
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.
32
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.
41
42   ;; Target register definitions.
43   (STACK_POINTER_REGNUM	8)
44   (HARD_FRAME_POINTER_REGNUM	FP_REGNUM)
45   (PC_REGNUM			132)
46   (FRAME_POINTER_REGNUM	136)
47   (ARG_POINTER_REGNUM		140)
48   (FIRST_PSEUDO_REGISTER	144)
49  ]
50)
51
52;; Enumeration of UNSPECs.
53
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
60
61  UNSPECV_LOOP_BEGIN
62  UNSPECV_LOOP_END
63
64  UNSPECV_BLOCKAGE
65])
66
67; Length of an instruction (in bytes).
68(define_attr "length" "" (const_int 4))
69(define_attr "type"
70  "unknown,complex,control,alu,cond_alu,st,ld,shift"
71  (const_string "complex"))
72
73(define_asm_attributes
74 [(set_attr "length" "4")
75  (set_attr "type" "complex")])
76
77; There is no pipeline, so our scheduling description is simple.
78(define_automaton "pru")
79(define_cpu_unit "cpu" "pru")
80
81(define_insn_reservation "everything" 1 (match_test "true") "cpu")
82
83(include "predicates.md")
84(include "constraints.md")
85
86;; All supported direct move-modes
87(define_mode_iterator MOV8_16_32 [QI QQ UQQ
88				  HI HQ UHQ HA UHA
89				  SI SQ USQ SA USA SF SD])
90
91(define_mode_iterator MOV8_16 [QI QQ UQQ
92			       HI HQ UHQ HA UHA])
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])
98
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])
103
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.
107;;
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.
111;;
112;; If the pattern has no QI operands, then this iterator need not be used.
113;;
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")])
118
119;; Move instructions
120
121(define_expand "mov<mode>"
122  [(set (match_operand:MOV8_16_32 0 "nonimmediate_operand")
123	(match_operand:MOV8_16_32 1 "general_operand"))]
124  ""
125{
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]);
131})
132
133;; Keep a single pattern for 32 bit MOV operations.  LRA requires that the
134;; movXX patterns be unified for any given mode.
135;;
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"))]
140  ""
141  "@
142    sb%B0o\\t%b1, %0, %S0
143    lb%B1o\\t%b0, %1, %S1
144    mov\\t%0, %1
145    ldi\\t%0, %%pmem(%1)
146    ldi\\t%0, %1
147    ldi32\\t%0, %1"
148  [(set_attr "type" "st,ld,alu,alu,alu,alu")
149   (set_attr "length" "4,4,4,4,4,8")])
150
151
152;; Separate pattern for 8 and 16 bit moves, since LDI32 pseudo instruction
153;; cannot handle byte and word-sized registers.
154;;
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"))]
160  ""
161  "@
162    sb%B0o\\t%b1, %0, %S0
163    lb%B1o\\t%b0, %1, %S1
164    mov\\t%0, %1
165    ldi\\t%0, %%pmem(%1)
166    ldi\\t%0, (%1) & 0xffff"
167  [(set_attr "type" "st,ld,alu,alu,alu")
168   (set_attr "length" "4")])
169
170
171; Pmode is 32 bits for PRU so symbolic constants cannot be 64 bits.  Hence
172; this pattern handles only numeric constants.
173;
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"))]
181  ""
182{
183  switch (which_alternative)
184    {
185    case 0:
186      return "sb%B0o\\t%b1, %0, %S0";
187    case 1:
188      return "lb%B1o\\t%b0, %1, %S1";
189    case 2:
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";
195      else
196	return "mov\\t%F0, %F1\;mov\\t%N0, %N1";
197    case 3:
198      return "ldi\\t%F0, %%pmem(%1)\;ldi\\t%N0, 0";
199    case 4:
200      return "ldi\\t%F0, %1\;ldi\\t%N0, 0";
201    case 5:
202      return "ldi32\\t%F0, %w1\;ldi32\\t%N0, %W1";
203    default:
204      gcc_unreachable ();
205  }
206}
207  [(set_attr "type" "st,ld,alu,alu,alu,alu")
208   (set_attr "length" "4,4,8,8,8,16")])
209
210;
211; load_multiple pattern(s).
212;
213; ??? Due to reload problems with replacing registers inside match_parallel
214; we currently support load_multiple/store_multiple only after reload.
215;
216; Idea taken from the s390 port.
217
218(define_expand "load_multiple"
219  [(match_par_dup 3 [(set (match_operand 0 "")
220			  (match_operand 1 ""))
221		     (use (match_operand 2 ""))])]
222  "reload_completed"
223{
224  machine_mode mode;
225  int regno;
226  int count;
227  rtx base_reg;
228  poly_int64 base_offs;
229  int i;
230
231  /* Support only loading a constant number of fixed-point registers from
232     memory.  */
233  if (GET_CODE (operands[2]) != CONST_INT
234      || GET_CODE (operands[1]) != MEM
235      || GET_CODE (operands[0]) != REG)
236    FAIL;
237
238  count = INTVAL (operands[2]);
239  regno = REGNO (operands[0]);
240  mode = GET_MODE (operands[0]);
241  if (mode != QImode)
242    FAIL;
243
244  operands[3] = gen_rtx_PARALLEL (VOIDmode, rtvec_alloc (count));
245
246  gcc_assert (!can_create_pseudo_p ());
247
248  base_reg = strip_offset (XEXP (operands[1], 0), &base_offs);
249  if (GET_CODE (base_reg) != REG)
250    FAIL;
251
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))));
258})
259
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"))])]
264  "reload_completed"
265{
266  int nregs = XVECLEN (operands[0], 0);
267  operands[0] = GEN_INT (nregs);
268  return "lb%B2o\\t%b1, %2, %0";
269}
270  [(set_attr "type" "ld")])
271
272;
273; store multiple pattern(s).
274;
275
276(define_expand "store_multiple"
277  [(match_par_dup 3 [(set (match_operand 0 "")
278			  (match_operand 1 ""))
279		     (use (match_operand 2 ""))])]
280  "reload_completed"
281{
282  machine_mode mode;
283  int regno;
284  int count;
285  rtx base_reg;
286  poly_int64 base_offs;
287  int i;
288
289  /* Support only storing a constant number of fixed-point registers to
290     memory.  */
291  if (GET_CODE (operands[2]) != CONST_INT
292      || GET_CODE (operands[0]) != MEM
293      || GET_CODE (operands[1]) != REG)
294    FAIL;
295
296  count = INTVAL (operands[2]);
297  regno = REGNO (operands[1]);
298  mode = GET_MODE (operands[1]);
299  if (mode != QImode)
300    FAIL;
301
302  operands[3] = gen_rtx_PARALLEL (VOIDmode, rtvec_alloc (count));
303
304  gcc_assert (!can_create_pseudo_p ());
305
306  base_reg = strip_offset (XEXP (operands[0], 0), &base_offs);
307  if (GET_CODE (base_reg) != REG)
308    FAIL;
309
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));
316})
317
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"))])]
322  "reload_completed"
323{
324  int nregs = XVECLEN (operands[0], 0);
325  operands[0] = GEN_INT (nregs);
326  return "sb%B1o\\t%b2, %1, %0";
327}
328  [(set_attr "type" "st")])
329
330;; Zero extension patterns
331;;
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")))]
339  ""
340  "")
341
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")))]
345  ""
346  "mov\\t%0, %1"
347  [(set_attr "type"     "alu")])
348
349;; Sign extension patterns.  We have to emulate them due to lack of
350;; signed operations in PRU's ALU.
351
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")))]
355  ""
356{
357  return pru_output_sign_extend (operands);
358}
359  [(set_attr "type" "complex")
360   (set_attr "length" "12")])
361
362;; Bit extraction
363;; We define it solely to allow combine to choose SImode
364;; for word mode when trying to match our cbranch_qbbx_* insn.
365;;
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")
370	  (zero_extract:QISI
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")))]
374  ""
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")])
378
379
380
381;; Arithmetic Operations
382
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")))]
387  ""
388  "")
389
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")))]
394  ""
395  "@
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")])
401
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")))]
406  ""
407  "")
408
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")))]
413  ""
414  "@
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")])
419
420;;  Negate and ones complement
421
422(define_expand "neg<mode>2"
423  [(set (match_operand:QISI 0 "register_operand")
424	(neg:QISI (match_operand:QISI 1 "register_operand")))]
425  ""
426  "")
427
428(define_expand "one_cmpl<mode>2"
429  [(set (match_operand:QISI 0 "register_operand")
430	(not:QISI (match_operand:QISI 1 "register_operand")))]
431  ""
432  "")
433
434;;  Integer logical Operations
435;;
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)
438
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")])
441
442(define_code_iterator LOGICAL_BITOP [and ior xor])
443(define_code_attr logical_bitop_asm [(and "and") (ior "or") (xor "xor")])
444
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")))]
449  ""
450  "")
451
452
453;;  Shift instructions
454
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")])
458
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")))]
463  ""
464  "")
465
466; Expand to a loop of single-position arithmetic shifts, which
467; we can handle.  Pseudo code:
468;     tmpval = src;
469;     QImode cntr = nshifts & 0xff;
470;     while (cntr)
471;       {
472;         tmpval >>= 1;
473;         cntr--;
474;       }
475;     dst = tmpval;
476;
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")
481	  (ashiftrt:QISI
482	    (match_operand:QISI 1 "register_operand")
483	    (match_operand:QI 2 "reg_or_const_1_operand")))]
484  ""
485{
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;
492
493  if (const_1_operand (nshifts, VOIDmode))
494    {
495      emit_insn (gen_ashr<mode>3_single (dst, src, nshifts));
496      DONE;
497    }
498
499  tmpval = gen_reg_rtx (<MODE>mode);
500  emit_move_insn (tmpval, src);
501
502  cntr = gen_reg_rtx (QImode);
503  emit_move_insn (cntr, nshifts);
504
505  loop_label = gen_label_rtx ();
506  ashr_end_label = gen_label_rtx ();
507
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));
511
512  emit_insn (gen_ashr<mode>3_single (tmpval, tmpval, const1_rtx));
513  emit_insn (gen_addqi3 (cntr, cntr, GEN_INT (-1)));
514
515  emit_jump_insn (gen_jump (loop_label));
516  JUMP_LABEL (get_last_insn ()) = loop_label;
517  LABEL_NUSES (loop_label)++;
518  emit_barrier ();
519
520  emit_label (ashr_end_label);
521
522  emit_move_insn (dst, tmpval);
523
524  DONE;
525})
526
527(define_insn "ashr<mode>3_single"
528  [(set (match_operand:QISI 0 "register_operand"	"=r")
529	  (ashiftrt:QISI
530	    (match_operand:QISI 1 "register_operand"	"r")
531	    (match_operand:QI 2 "const_1_operand"	"P")))]
532  ""
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")])
536
537
538;; Include ALU patterns with zero-extension of operands.  That's where
539;; the real insns are defined.
540
541(include "alu-zext.md")
542
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")
548	  (LOGICAL_BITOP:DI
549	    (match_operand:DI 1 "register_operand"	"%r,r")
550	    (match_operand:DI 2 "reg_or_ubyte_operand"	"r,I")))]
551  ""
552  "@
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")])
557
558
559(define_insn "one_cmpldi2"
560  [(set (match_operand:DI 0 "register_operand"		"=r")
561	(not:DI (match_operand:DI 1 "register_operand"	"r")))]
562  ""
563{
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";
569  else
570    return "not\\t%F0, %F1\;not\\t%N0, %N1";
571}
572  [(set_attr "type" "alu")
573   (set_attr "length" "8")])
574
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.
578
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")))]
583  ""
584  "nop\;xin\\t0, %0, 4"
585  [(set_attr "type" "alu")
586   (set_attr "length" "8")])
587
588;; Prologue, Epilogue and Return
589
590(define_expand "prologue"
591  [(const_int 1)]
592  ""
593{
594  pru_expand_prologue ();
595  DONE;
596})
597
598(define_expand "epilogue"
599  [(return)]
600  ""
601{
602  pru_expand_epilogue (false);
603  DONE;
604})
605
606(define_expand "sibcall_epilogue"
607  [(return)]
608  ""
609{
610  pru_expand_epilogue (true);
611  DONE;
612})
613
614(define_insn "return"
615  [(simple_return)]
616  "pru_can_use_return_insn ()"
617  "ret")
618
619(define_insn "simple_return"
620  [(simple_return)]
621  ""
622  "ret")
623
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.
627
628(define_insn "blockage"
629  [(unspec_volatile [(const_int 0)] UNSPECV_BLOCKAGE)]
630  ""
631  ""
632  [(set_attr "type" "unknown")
633   (set_attr "length" "0")])
634
635;;  Jumps and calls
636
637(define_insn "indirect_jump"
638  [(set (pc) (match_operand:SI 0 "register_operand" "r"))]
639  ""
640  "jmp\\t%0"
641  [(set_attr "type" "control")])
642
643(define_insn "jump"
644  [(set (pc)
645	(label_ref (match_operand 0)))]
646  ""
647  "jmp\\t%%label(%l0)"
648  [(set_attr "type" "control")])
649
650
651(define_expand "call"
652  [(parallel [(call (match_operand 0 "")
653		    (match_operand 1 ""))
654	      (clobber (reg:HI RA_REGNUM))])]
655  ""
656  "")
657
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))])]
663  ""
664  "")
665
666(define_insn "*call"
667  [(call (mem:SI (match_operand:SI 0 "call_operand" "i,r"))
668	 (match_operand 1))
669   (clobber (reg:HI RA_REGNUM))]
670  ""
671  "@
672    call\\t%%label(%0)
673    call\\t%0"
674  [(set_attr "type" "control")])
675
676(define_insn "*call_value"
677  [(set (match_operand 0)
678	(call (mem:SI (match_operand:SI 1 "call_operand" "i,r"))
679	      (match_operand 2)))
680   (clobber (reg:HI RA_REGNUM))]
681  ""
682  "@
683    call\\t%%label(%1)
684    call\\t%1"
685  [(set_attr "type" "control")])
686
687(define_expand "sibcall"
688  [(parallel [(call (match_operand 0 "")
689		    (match_operand 1 ""))
690	      (return)])]
691  ""
692  "")
693
694(define_expand "sibcall_value"
695  [(parallel [(set (match_operand 0 "")
696		   (call (match_operand 1 "")
697			 (match_operand 2 "")))
698	      (return)])]
699  ""
700  "")
701
702(define_insn "*sibcall"
703 [(call (mem:SI (match_operand:SI 0 "call_operand" "i,Rsib"))
704	(match_operand 1))
705  (return)]
706  "SIBLING_CALL_P (insn)"
707  "@
708    jmp\\t%%label(%0)
709    jmp\\t%0"
710  [(set_attr "type" "control")])
711
712(define_insn "*sibcall_value"
713 [(set (match_operand 0 "register_operand" "")
714       (call (mem:SI (match_operand:SI 1 "call_operand" "i,Rsib"))
715	     (match_operand 2)))
716  (return)]
717  "SIBLING_CALL_P (insn)"
718  "@
719    jmp\\t%%label(%1)
720    jmp\\t%1"
721  [(set_attr "type" "control")])
722
723(define_insn "*tablejump"
724  [(set (pc)
725	(match_operand:SI 0 "register_operand" "r"))
726   (use (label_ref (match_operand 1)))]
727  ""
728  "jmp\\t%0"
729  [(set_attr "type" "control")])
730
731;; Expand the cbranch pattern in order to assign different constraints for
732;; signed and unsigned comparisons.
733(define_expand "cbranch<mode>4"
734  [(set (pc)
735     (if_then_else
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 ""))
740       (pc)))]
741  ""
742{
743  /* Ensure our patterns will be able to handle the particular const_int.  */
744  if (CONST_INT_P (operands[2]))
745    {
746      HOST_WIDE_INT ival = INTVAL (operands[2]);
747
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))
751	{
752	  if (can_create_pseudo_p ())
753	    operands[2] = force_reg (<MODE>mode, operands[2]);
754	  else
755	    FAIL;
756	}
757
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))
761	{
762	  if (can_create_pseudo_p ())
763	    operands[2] = force_reg (<MODE>mode, operands[2]);
764	  else
765	    FAIL;
766	}
767    }
768})
769
770(define_insn "cbranch<mode>4_unsigned"
771  [(set (pc)
772     (if_then_else
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))
777       (pc)))]
778  ""
779{
780  const bool is_near = (get_attr_length (insn) == 4);
781
782  /* PRU comparisons reverse the operand order (OP2 cmp OP1),
783     so swap the condition.  */
784  if (is_near)
785    return "qb%P0\t%l3, %1, %u2";
786  else
787    return "qb%Q0\t.+8, %1, %u2\;jmp\t%%label(%l3)";
788}
789  [(set_attr "type" "control")
790   (set (attr "length")
791	(if_then_else
792	    (and (ge (minus (match_dup 3) (pc)) (const_int -2040))
793		 (le (minus (match_dup 3) (pc)) (const_int 2036)))
794	    (const_int 4)
795	    (const_int 8)))])
796
797;; Unlike ALU operations, the const_int's sign here is important.  So we
798;; cannot use ubyte_constr.
799;;
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"
804  [(set (pc)
805     (if_then_else
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))
810       (pc)))]
811  ""
812{
813  const int length = (get_attr_length (insn));
814  const bool is_near = (length == 20);
815  enum rtx_code code = GET_CODE (operands[0]);
816
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);
821  else
822    return pru_output_signed_cbranch_ubyteop2 (operands, is_near);
823}
824  [(set_attr "type" "control")
825   (set (attr "length")
826	(if_then_else
827	    (and (ge (minus (match_dup 3) (pc)) (const_int -2020))
828		 (le (minus (match_dup 3) (pc)) (const_int 2016)))
829	    (const_int 20)
830	    (const_int 28)))])
831
832(define_expand "cbranch<mode>4"
833  [(set (pc)
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 ""))
838		      (pc)))]
839  ""
840{
841  rtx t = pru_expand_fp_compare (operands[0], VOIDmode);
842  operands[0] = t;
843  operands[1] = XEXP (t, 0);
844  operands[2] = XEXP (t, 1);
845})
846
847;
848; Bit test branch
849
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")])
853
854(define_insn "cbranch_qbbx_<BIT_TEST:code><EQS0:mode><EQS1:mode><EQD:mode>4"
855 [(set (pc)
856   (if_then_else
857    (BIT_TEST (zero_extract:EQD
858	 (match_operand:EQS0 0 "register_operand" "r")
859	 (const_int 1)
860	 (match_operand:EQS1 1 "reg_or_ubyte_operand" "r<EQS1:ubyte_constr>"))
861     (const_int 0))
862    (label_ref (match_operand 2))
863    (pc)))]
864  ""
865{
866  const int length = (get_attr_length (insn));
867  const bool is_near = (length == 4);
868  if (is_near)
869    return "<BIT_TEST:qbbx_op>\\t%l2, %0, %u1";
870  else
871    return "<BIT_TEST:qbbx_negop>\\t.+8, %0, %u1\;jmp\\t%%label(%l2)";
872}
873  [(set_attr "type" "control")
874   (set (attr "length")
875      (if_then_else
876	  (and (ge (minus (match_dup 2) (pc)) (const_int -2048))
877	       (le (minus (match_dup 2) (pc)) (const_int 2044)))
878	  (const_int 4)
879	  (const_int 8)))])
880
881;; ::::::::::::::::::::
882;; ::
883;; :: Low Overhead Looping - idea "borrowed" from MEP
884;; ::
885;; ::::::::::::::::::::
886
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))]
895  ""
896{
897  gcc_unreachable ();
898})
899
900(define_expand "doloop_begin"
901  [(use (match_operand 0 "register_operand"))
902   (use (match_operand 1 ""))]
903  "TARGET_OPT_LOOP"
904{
905  pru_emit_doloop (operands, 0);
906  DONE;
907})
908
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
911; not a register.
912(define_insn "doloop_end_internal<mode>"
913  [(set (pc)
914	(if_then_else (ne (match_operand:HISI 0 "nonimmediate_operand" "+r,*m")
915			  (const_int 1))
916		      (label_ref (match_operand 1))
917		      (pc)))
918   (set (match_dup 0)
919	(plus:HISI (match_dup 0)
920		 (const_int -1)))
921   (unspec [(match_operand 2 "const_int_operand" "")] UNSPECV_LOOP_END)
922   (clobber (match_scratch:HISI 3 "=X,&r"))]
923  ""
924{
925  gcc_unreachable ();
926}
927  ;; Worst case length:
928  ;;
929  ;;	  lbbo op3_reg, op3_ptr	  4'
930  ;;	  sub <op3_reg>, 1	  4
931  ;;	  qbeq .+8, <op3_reg>, 0  4
932  ;;	  jmp <op1>		  4
933  ;;	  sbbo op3_reg, op3_ptr	  4
934  [(set (attr "length")
935      (if_then_else
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)]
939	       (const_int 12))
940	(cond [(eq_attr "alternative" "0") (const_int 12)]
941	       (const_int 20))))])
942
943(define_expand "doloop_end"
944  [(use (match_operand 0 "nonimmediate_operand"))
945   (use (label_ref (match_operand 1 "")))]
946  "TARGET_OPT_LOOP"
947{
948  if (GET_CODE (operands[0]) == REG && GET_MODE (operands[0]) == QImode)
949    FAIL;
950  pru_emit_doloop (operands, 1);
951  DONE;
952})
953
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))]
959  ""
960  "loop\\t%l1, %0")
961
962(define_insn "pruloop_end"
963  [(unspec [(const_int 0)] UNSPECV_LOOP_END)]
964  ""
965  "# loop end"
966  [(set_attr "length" "0")])
967
968
969;;  Misc patterns
970
971(define_insn "delay_cycles_start"
972  [(unspec_volatile [(match_operand 0 "immediate_operand" "i")]
973		    UNSPECV_DELAY_CYCLES_START)]
974  ""
975  "/* Begin %0 cycle delay.  */"
976  [(set_attr "length" "0")])
977
978(define_insn "delay_cycles_end"
979  [(unspec_volatile [(match_operand 0 "immediate_operand" "i")]
980		    UNSPECV_DELAY_CYCLES_END)]
981  ""
982  "/* End %0 cycle delay.  */"
983  [(set_attr "length" "0")])
984
985
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"))]
990  ""
991  "ldi\\t%1, %0\;sub\\t%1, %1, 1\;qbne\\t.-4, %1, 0"
992  [(set_attr "length" "12")])
993
994
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"))]
1001  ""
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")])
1004
1005(define_insn "delay_cycles_1"
1006  [(unspec_volatile [(const_int 0) ] UNSPECV_DELAY_CYCLES_1)]
1007  ""
1008  "nop\\t# delay_cycles_1"
1009)
1010
1011
1012(define_insn "nop"
1013  [(const_int 0)]
1014  ""
1015  "nop"
1016  [(set_attr "type" "alu")])
1017
1018(define_insn "nop_loop_guard"
1019  [(const_int 0)]
1020  ""
1021  "nop\\t# Loop end guard"
1022  [(set_attr "type" "alu")])
1023