]> git.ipfire.org Git - thirdparty/gcc.git/blob - gcc/config/pru/pru.md
Initial TI PRU GCC port
[thirdparty/gcc.git] / gcc / config / pru / pru.md
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.
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 \f
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 \f
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 \f
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 \f
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 \f
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 \f
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 \f
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 \f
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 \f
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 \f
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 \f
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 \f
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 \f
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 \f
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 \f
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 \f
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")])