]> gcc.gnu.org Git - gcc.git/blob - gcc/config/picochip/picochip.md
Update Copyright years for files modified in 2010.
[gcc.git] / gcc / config / picochip / picochip.md
1 ;; GCC machine description for picochip
2 ;; Copyright (C) 2008, 2009, 2010 Free Software Foundation, Inc.
3 ;; Contributed by Picochip Ltd (http://www.picochip.com)
4 ;; Maintained by Daniel Towner (dant@picochip.com) and Hariharan
5 ;; Sandanagobalane (hariharan@picochip.com)
6 ;;
7 ;; This file is part of GCC.
8 ;;
9 ;; GCC is free software; you can redistribute it and/or modify
10 ;; it under the terms of the GNU General Public License as published by
11 ;; the Free Software Foundation; either version 3, or (at your option)
12 ;; any later version.
13 ;;
14 ;; GCC is distributed in the hope that it will be useful,
15 ;; but WITHOUT ANY WARRANTY; without even the implied warranty of
16 ;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
17 ;; GNU General Public License for more details.
18 ;;
19 ;; You should have received a copy of the GNU General Public License
20 ;; along with GCC; see the file COPYING3. If not, see
21 ;; <http://www.gnu.org/licenses/>.
22
23 ;; -------------------------------------------------------------------------
24
25 ;; In addition to the normal output operand formats, the following
26 ;; letter formats are also available:
27 ;;
28 ;; The following can be used for constants, or the constant part of a
29 ;; memory offset.
30 ;; Q - Output constant unaltered (byte mode).
31 ;; M - Alias for Q, which only works with memory operands.
32 ;; H - Divide constant by 2 (i.e., HImode is 2 bytes)
33 ;; S - Divide constant by 4 (i.e., SImode is 4 bytes)
34 ;;
35 ;; The following can be used for two part addresses (i.e., base +
36 ;; offset or base[offset]).
37 ;; o - Output offset only.
38 ;; b - Output base only.
39 ;;
40 ;; The following are used on SI registers and constants
41 ;; R - Output register pair (i.e., R[n:m])
42 ;; L - Output lower word/register
43 ;; U - Output upper word/register
44 ;;
45 ;; The following are used on DI mode registers.
46 ;; X - Output 3rd register
47 ;; Y - Output 4th register
48 ;;
49 ;; Miscellaneous
50 ;; | - Output VLIW separator
51 ;; r - Output register value of memory operand.
52 ;; I - Output an opcode (e.g., ADD for plus, LSL for lshift)
53 ;; i - Output an opcode in symbolic notation (e.g., + for plus)
54
55 ;; Define the length of an instruction. Used to allow different types
56 ;; of branches to be used for different branch offsets. Default to 6
57 ;; bytes, which is the longest possible single instruction.
58 (define_attr "length" "" (const_int 6))
59
60 ;; Define some constants which are used in conjuction with branch
61 ;; scheduling. Branches must be 10-bit signed, which equates to
62 ;; [-512,511]. However, to compensate for the lack of branch alignment
63 ;; these offsets are reduced by a factor of 2.
64
65 (define_constants
66 [
67 (MIN_BRANCH_OFFSET -256)
68 (MAX_BRANCH_OFFSET 255)
69 (SHORT_BRANCH_LENGTH 6) ; The size of a schedulable short branch.
70 (LONG_BRANCH_LENGTH 16) ; The size of an expanded JMP?? macro.
71 ]
72 )
73
74 ;; Define identifiers for various special instructions. These
75 ;; instructions may then be used in RTL expansions, or builtins.
76 (define_constants
77 [
78 ; Special instruction builtins.
79 (UNSPEC_SBC 0) ; Sign-bit count
80 (UNSPEC_ADDS 1) ; Saturating addition
81 (UNSPEC_SUBS 2) ; Saturating subtraction
82 (UNSPEC_BREV 3) ; Bit reversal
83
84 ; Special internal instructions (only used by compiler)
85 (UNSPEC_COPYSW 5) ; Get status word
86 (UNSPEC_ADDC 6) ; Add with carry.
87
88 ; Scalar port communication builtins
89 (UNSPEC_PUT 7) ; Communication (put): port[op0] := op1
90 (UNSPEC_GET 8) ; Communication (get): op0 := get_port[op1]
91 (UNSPEC_TESTPORT 9) ; Communication (test): op0 := testport[op1]
92
93 ; Array port communication builtins. These all take extra
94 ; arguments giving information about the array access being used.
95 (UNSPEC_PUT_ARRAY 10) ; Array put
96 (UNSPEC_GET_ARRAY 11) ; Array get
97 (UNSPEC_TESTPORT_ARRAY 12) ; Array test port
98
99 ;; Array port expansions
100 (UNSPEC_CALL_GET_ARRAY 13) ;
101 (UNSPEC_CALL_PUT_ARRAY 14) ;
102 (UNSPEC_CALL_TESTPORT_ARRAY 15) ;
103
104 ; Array port low-level fn calls
105 (UNSPEC_CALL_GET_FN 16)
106 (UNSPEC_CALL_TESTPORT_FN 17)
107
108 ; Halt instruction.
109 (UNSPEC_HALT 18)
110
111 ; Internal TSTPORT instruction, used to generate a single TSTPORT
112 ; instruction for use in the testport branch split.
113 (UNSPEC_INTERNAL_TESTPORT 19)
114 ]
115 )
116
117 ;; Register ID's
118 (define_constants
119 [
120 (LINK_REGNUM 12) ; Function link register.
121 (CC_REGNUM 17) ; Condition flags.
122 (ACC_REGNUM 16) ; Condition flags.
123 ]
124 )
125
126 ;;============================================================================
127 ;; Predicates and constraints
128 ;;============================================================================
129
130 (include "predicates.md")
131 (include "constraints.md")
132
133 ;;============================================================================
134 ;; First operand shifting patterns. These allow certain instructions
135 ;; (e.g., add, and, or, xor, sub) to apply a shift-by-constant to
136 ;; their first operand.
137 ;;
138 ;; Note that only the first operand is matched by the shift, to ensure
139 ;; that non-commutative instructions (like subtract) work
140 ;; properly. When a commutative instruction, with a shift in the
141 ;; second operand is found, the compiler will reorder the operands to
142 ;; match.
143 ;;============================================================================
144
145 (define_insn "*firstOpGenericAshift"
146 [(set (match_operand:HI 0 "register_operand" "=r")
147 (match_operator:HI 1 "picochip_first_op_shift_operator"
148 [(ashift:HI
149 (match_operand:HI 2 "register_operand" "r")
150 (match_operand:HI 3 "picochip_J_operand" "J"))
151 (match_operand:HI 4 "picochip_register_or_immediate_operand" "ri")]))
152 (clobber (reg:CC CC_REGNUM))]
153 ""
154 "%I1.0 [LSL %2,%3],%4,%0\t// %0 := (%2 << %3) %i1 %4"
155 [(set_attr "type" "picoAlu")
156 ;; A long constant must be used if the operator instruction doesn't
157 ;; accept immediates, or if the constant is too big to fit the
158 ;; immediate. Note that the following condition is written in the
159 ;; way which uses the least number of predicates.
160 (set (attr "longConstant")
161 (cond [(ior (match_operand 4 "register_operand")
162 (and (match_operand 1 "picochip_first_op_shift_operator_imm")
163 (match_operand 1 "picochip_J_operand")))
164 (const_string "false")]
165 (const_string "true")))])
166
167 ;; During combine, ashift gets converted into a multiply, necessitating the following pattern.
168 ;; Note that we do a log_2(imm) to get the actual LSL operand.
169
170 (define_insn "*firstOpGenericAshift"
171 [(set (match_operand:HI 0 "register_operand" "=r")
172 (match_operator:HI 1 "picochip_first_op_shift_operator"
173 [(mult:HI
174 (match_operand:HI 2 "register_operand" "r")
175 (match_operand:HI 3 "power_of_2_imm_operand" "n"))
176 (match_operand:HI 4 "picochip_register_or_immediate_operand" "ri")]))
177 (clobber (reg:CC CC_REGNUM))]
178 ""
179 "%I1.0 [LSL %2,%P3],%4,%0\t// %0 := (%2 << %3) %i1 %4"
180 [(set_attr "type" "picoAlu")
181 ;; A long constant must be used if the operator instruction doesn't
182 ;; accept immediates, or if the constant is too big to fit the
183 ;; immediate. Note that the following condition is written in the
184 ;; way which uses the least number of predicates.
185 (set (attr "longConstant")
186 (cond [(ior (match_operand 4 "register_operand")
187 (and (match_operand 1 "picochip_first_op_shift_operator_imm")
188 (match_operand 1 "picochip_J_operand")))
189 (const_string "false")]
190 (const_string "true")))])
191
192 (define_insn "*firstOpGenericAshiftrt"
193 [(set (match_operand:HI 0 "register_operand" "=r")
194 (match_operator:HI 1 "picochip_first_op_shift_operator"
195 [(ashiftrt:HI
196 (match_operand:HI 2 "register_operand" "r")
197 (match_operand:HI 3 "picochip_J_operand" "J"))
198 (match_operand:HI 4 "picochip_register_or_immediate_operand" "ri")]))
199 (clobber (reg:CC CC_REGNUM))]
200 ""
201 "%I1.0 [ASR %2,%3],%4,%0\t// %0 := (%2 >>{arith} %3) %i1 %4"
202 [(set_attr "type" "picoAlu")
203 ;; A long constant must be used if the operator instruction doesn't
204 ;; accept immediates, or if the constant is too big to fit the
205 ;; immediate. Note that the following condition is written in the
206 ;; way which uses the least number of predicates.
207 (set (attr "longConstant")
208 (cond [(ior (match_operand 4 "register_operand")
209 (and (match_operand 1 "picochip_first_op_shift_operator_imm")
210 (match_operand 1 "picochip_J_operand")))
211 (const_string "false")]
212 (const_string "true")))])
213
214 (define_insn "*firstOpGenericLshiftrt"
215 [(set (match_operand:HI 0 "register_operand" "=r")
216 (match_operator:HI 1 "picochip_first_op_shift_operator"
217 [(lshiftrt:HI
218 (match_operand:HI 2 "register_operand" "r")
219 (match_operand:HI 3 "picochip_J_operand" "J"))
220 (match_operand:HI 4 "picochip_register_or_immediate_operand" "ri")]))
221 (clobber (reg:CC CC_REGNUM))]
222 ""
223 "%I1.0 [LSR %2,%3],%4,%0\t// %0 := (%2 >> %3) %i1 %4"
224 [(set_attr "type" "picoAlu")
225 ;; A long constant must be used if the operator instruction doesn't
226 ;; accept immediates, or if the constant is too big to fit the
227 ;; immediate. Note that the following condition is written in the
228 ;; way which uses the least number of predicates.
229 (set (attr "longConstant")
230 (cond [(ior (match_operand 4 "register_operand")
231 (and (match_operand 1 "picochip_first_op_shift_operator_imm")
232 (match_operand 1 "picochip_J_operand")))
233 (const_string "false")]
234 (const_string "true")))])
235
236 ;;===========================================================================
237 ;; Jump instructions.
238 ;;===========================================================================
239
240 (define_insn "indirect_jump"
241 [(set (pc) (match_operand:HI 0 "register_operand" "r"))]
242 ""
243 "JR (%0)\t// Indirect_jump to %0 %>"
244 [(set_attr "type" "realBranch")
245 (set_attr "length" "3")])
246
247 (define_insn "jump"
248 [(set (pc)
249 (label_ref (match_operand 0 "" "")))]
250 ""
251 "* return picochip_output_jump(insn);"
252 [(set (attr "length")
253 (if_then_else
254 (and (ge (minus (match_dup 0) (pc)) (const_int MIN_BRANCH_OFFSET))
255 (le (minus (match_dup 0) (pc)) (const_int MAX_BRANCH_OFFSET)))
256 (const_int SHORT_BRANCH_LENGTH)
257 (const_int LONG_BRANCH_LENGTH)))
258 (set (attr "type")
259 (if_then_else
260 (eq_attr "length" "6")
261 (const_string "realBranch")
262 (const_string "unknown")))])
263
264 (define_insn "*fn_return"
265 [(return)
266 (use (reg:HI LINK_REGNUM))]
267 ""
268 "JR (R12)\t// Return to caller %>"
269 [(set_attr "length" "2")
270 (set_attr "type" "realBranch")
271 (set_attr "longConstant" "false")])
272
273 ;; Peephole either 2 LDWs or STWs into LDL/STL.
274 (define_peephole2
275 [(set (match_operand:HI 0 "register_operand" "")
276 (match_operand:HI 1 "memory_operand" ""))
277 (set (match_operand:HI 2 "register_operand" "")
278 (match_operand:HI 3 "memory_operand" ""))]
279 "ok_to_peephole_ldw(operands[0],operands[1],operands[2],operands[3])"
280 [(set (match_dup 4) (match_dup 5))]
281 "{
282 operands[4] = gen_min_reg(operands[0],operands[2]);
283 operands[5] = gen_SImode_mem(operands[1],operands[3]);
284 }")
285
286 (define_peephole2
287 [(set (match_operand:HI 0 "memory_operand" "")
288 (match_operand:HI 1 "register_operand" ""))
289 (set (match_operand:HI 2 "memory_operand" "")
290 (match_operand:HI 3 "register_operand" ""))]
291 "ok_to_peephole_stw(operands[0],operands[1],operands[2],operands[3])"
292 [(set (match_dup 4) (match_dup 5))]
293 "{
294 operands[4] = gen_SImode_mem(operands[0],operands[2]);
295 operands[5] = gen_min_reg(operands[1],operands[3]);
296 }")
297
298
299 ;; We have instructions like add,subtract,ior,and that set condition
300 ;; codes if they are executed on slot 0. If we have
301 ;; add a = b + c
302 ;; if (a!=0)
303 ;; {}
304 ;; We would have RTL sequence like
305 ;; add.# rb,rc,ra # will be replaced by slot no, after scheduling
306 ;; sub.0 ra,0,r15
307 ;; bnz
308 ;; Instead, we can just do
309 ;; add.0 rb,rc,ra
310 ;; bnz
311
312 (define_peephole2
313 [(parallel [(set (match_operand:HI 0 "register_operand" "")
314 (plus:HI (match_operand:HI 1 "register_operand" "")
315 (match_operand:HI 2 "general_operand" "")))
316 (clobber (reg:CC CC_REGNUM))])
317 (parallel [(set (pc)
318 (if_then_else
319 (match_operator:CC 3 "picochip_peephole_comparison_operator"
320 [(match_dup 0) (const_int 0)])
321 (label_ref (match_operand 6 "" ""))
322 (pc)))
323 (clobber (reg:CC CC_REGNUM))])]
324 ""
325 [(parallel [(set (match_dup 0)
326 (plus:HI (match_dup 1) (match_dup 2)))
327 (set (reg:CC CC_REGNUM)
328 (match_op_dup 3 [(const_int 0) (const_int 0)]))])
329 (parallel [(set (pc)
330 (if_then_else
331 (match_op_dup:HI 3 [(reg:CC CC_REGNUM) (const_int 0)])
332 (label_ref (match_dup 6))
333 (pc)))
334 (use (match_dup 7))])]
335 "{
336 operands[7] = GEN_INT(0);
337 }")
338
339 (define_peephole2
340 [(parallel [(set (match_operand:HI 0 "register_operand" "")
341 (plus:HI (match_operand:HI 1 "register_operand" "")
342 (match_operand:HI 2 "general_operand" "")))
343 (clobber (reg:CC CC_REGNUM))])
344 (set (reg:CC CC_REGNUM)
345 (match_operator:CC 3 "picochip_peephole_comparison_operator"
346 [(match_dup 0) (const_int 0)]))
347 (parallel [(set (pc)
348 (if_then_else
349 (match_operator 4 "comparison_operator"
350 [(reg:CC CC_REGNUM) (const_int 0)])
351 (label_ref (match_operand 5 "" ""))
352 (pc)))
353 (use (match_operand:HI 6 "const_int_operand" ""))])]
354 ""
355 [(parallel [(set (match_dup 0)
356 (plus:HI (match_dup 1) (match_dup 2)))
357 (set (reg:CC CC_REGNUM)
358 (match_op_dup 3 [(const_int 0) (const_int 0)]))])
359 (parallel [(set (pc)
360 (if_then_else (match_op_dup:HI 4 [(reg:CC CC_REGNUM) (const_int 0)])
361 (label_ref (match_dup 5))
362 (pc)))
363 (use (match_dup 6))])]
364 "{
365 operands[7] = GEN_INT(0);
366 }")
367
368
369 ;; If peephole happens before the cbranch split
370
371 (define_peephole2
372 [(parallel [(set (match_operand:HI 0 "register_operand" "")
373 (minus:HI (match_operand:HI 1 "general_operand" "")
374 (match_operand:HI 2 "register_operand" "")))
375 (clobber (reg:CC CC_REGNUM))])
376 (parallel [(set (pc)
377 (if_then_else
378 (match_operator:CC 3 "picochip_peephole_comparison_operator"
379 [(match_dup 0) (const_int 0)])
380 (label_ref (match_operand 6 "" ""))
381 (pc)))
382 (clobber (reg:CC CC_REGNUM))])]
383 ""
384 [(parallel [(set (match_dup 0)
385 (minus:HI (match_dup 1) (match_dup 2)))
386 (set (reg:CC CC_REGNUM)
387 (match_op_dup 3 [(const_int 0) (const_int 0)]))])
388 (parallel [(set (pc)
389 (if_then_else
390 (match_op_dup:HI 3 [(reg:CC CC_REGNUM) (const_int 0)])
391 (label_ref (match_dup 6))
392 (pc)))
393 (use (match_dup 7))])]
394 "{
395 operands[7] = GEN_INT(0);
396 }")
397
398
399 ;; If peephole happens after the cbranch split
400
401 (define_peephole2
402 [(parallel [(set (match_operand:HI 0 "register_operand" "")
403 (minus:HI (match_operand:HI 1 "general_operand" "")
404 (match_operand:HI 2 "register_operand" "")))
405 (clobber (reg:CC CC_REGNUM))])
406 (set (reg:CC CC_REGNUM)
407 (match_operator:CC 3 "picochip_peephole_comparison_operator"
408 [(match_dup 0) (const_int 0)]))
409 (parallel [(set (pc)
410 (if_then_else
411 (match_operator 4 "comparison_operator"
412 [(reg:CC CC_REGNUM) (const_int 0)])
413 (label_ref (match_operand 5 "" ""))
414 (pc)))
415 (use (match_operand:HI 6 "const_int_operand" ""))])]
416 ""
417 [(parallel [(set (match_dup 0)
418 (minus:HI (match_dup 1) (match_dup 2)))
419 (set (reg:CC CC_REGNUM)
420 (match_op_dup 3 [(const_int 0) (const_int 0)]))])
421 (parallel [(set (pc)
422 (if_then_else (match_op_dup:HI 4 [(reg:CC CC_REGNUM) (const_int 0)])
423 (label_ref (match_dup 5))
424 (pc)))
425 (use (match_dup 6))])]
426 "{
427 operands[7] = GEN_INT(0);
428 }")
429
430 ;; If peephole happens before the cbranch split
431
432 (define_peephole2
433 [(parallel[(set (match_operand:HI 0 "register_operand" "")
434 (and:HI (match_operand:HI 1 "register_operand" "")
435 (match_operand:HI 2 "general_operand" "")))
436 (clobber (reg:CC CC_REGNUM))])
437 (parallel [(set (pc)
438 (if_then_else
439 (match_operator:CC 3 "picochip_peephole_comparison_operator"
440 [(match_dup 0) (const_int 0)])
441 (label_ref (match_operand 6 "" ""))
442 (pc)))
443 (clobber (reg:CC CC_REGNUM))])]
444 ""
445 [(parallel [(set (match_dup 0)
446 (and:HI (match_dup 1) (match_dup 2)))
447 (set (reg:CC CC_REGNUM)
448 (match_op_dup 3 [(const_int 0) (const_int 0)]))])
449 (parallel [(set (pc)
450 (if_then_else
451 (match_op_dup:HI 3 [(reg:CC CC_REGNUM) (const_int 0)])
452 (label_ref (match_dup 6))
453 (pc)))
454 (use (match_dup 7))])]
455 "{
456 operands[7] = GEN_INT(0);
457 }")
458
459 (define_peephole2
460 [(parallel[(set (match_operand:HI 0 "register_operand" "")
461 (and:HI (match_operand:HI 1 "register_operand" "")
462 (match_operand:HI 2 "general_operand" "")))
463 (clobber (reg:CC CC_REGNUM))])
464 (set (reg:CC CC_REGNUM)
465 (match_operator:CC 3 "picochip_peephole_comparison_operator"
466 [(match_dup 0) (const_int 0)]))
467 (parallel [(set (pc)
468 (if_then_else
469 (match_operator 4 "comparison_operator"
470 [(reg:CC CC_REGNUM) (const_int 0)])
471 (label_ref (match_operand 5 "" ""))
472 (pc)))
473 (use (match_operand:HI 6 "const_int_operand" ""))])]
474 ""
475 [(parallel [(set (match_dup 0)
476 (and:HI (match_dup 1) (match_dup 2)))
477 (set (reg:CC CC_REGNUM)
478 (match_op_dup 3 [(const_int 0) (const_int 0)]))])
479 (parallel [(set (pc)
480 (if_then_else (match_op_dup:HI 4 [(reg:CC CC_REGNUM) (const_int 0)])
481 (label_ref (match_dup 5))
482 (pc)))
483 (use (match_dup 6))])]
484 "{
485 operands[7] = GEN_INT(0);
486 }")
487
488 ;; If peephole happens before the cbranch split
489
490 (define_peephole2
491 [(parallel[(set (match_operand:HI 0 "register_operand" "")
492 (ior:HI (match_operand:HI 1 "register_operand" "")
493 (match_operand:HI 2 "general_operand" "")))
494 (clobber (reg:CC CC_REGNUM))])
495 (parallel [(set (pc)
496 (if_then_else
497 (match_operator:CC 3 "picochip_peephole_comparison_operator"
498 [(match_dup 0) (const_int 0)])
499 (label_ref (match_operand 6 "" ""))
500 (pc)))
501 (clobber (reg:CC CC_REGNUM))])]
502 ""
503 [(parallel [(set (match_dup 0)
504 (ior:HI (match_dup 1) (match_dup 2)))
505 (set (reg:CC CC_REGNUM)
506 (match_op_dup 3 [(const_int 0) (const_int 0)]))])
507 (parallel [(set (pc)
508 (if_then_else
509 (match_op_dup:HI 3 [(reg:CC CC_REGNUM) (const_int 0)])
510 (label_ref (match_dup 6))
511 (pc)))
512 (use (match_dup 7))])]
513 "{
514 operands[7] = GEN_INT(0);
515 }")
516
517 (define_peephole2
518 [(parallel[(set (match_operand:HI 0 "register_operand" "")
519 (ior:HI (match_operand:HI 1 "register_operand" "")
520 (match_operand:HI 2 "general_operand" "")))
521 (clobber (reg:CC CC_REGNUM))])
522 (set (reg:CC CC_REGNUM)
523 (match_operator:CC 3 "picochip_peephole_comparison_operator"
524 [(match_dup 0) (const_int 0)]))
525 (parallel [(set (pc)
526 (if_then_else
527 (match_operator 4 "comparison_operator"
528 [(reg:CC CC_REGNUM) (const_int 0)])
529 (label_ref (match_operand 5 "" ""))
530 (pc)))
531 (use (match_operand:HI 6 "const_int_operand" ""))])]
532 ""
533 [(parallel [(set (match_dup 0)
534 (ior:HI (match_dup 1) (match_dup 2)))
535 (set (reg:CC CC_REGNUM)
536 (match_op_dup 3 [(const_int 0) (const_int 0)]))])
537 (parallel [(set (pc)
538 (if_then_else (match_op_dup:HI 4 [(reg:CC CC_REGNUM) (const_int 0)])
539 (label_ref (match_dup 5))
540 (pc)))
541 (use (match_dup 6))])]
542 "{
543 operands[7] = GEN_INT(0);
544 }")
545
546 ;; Conditional branch (HI). This is split into separate compare and
547 ;; branch instructions if scheduling is enabled. The branch
548 ;; instruction is supplied with the type of comparison on which the
549 ;; branch should occur.
550
551 (define_insn_and_split "cbranchhi4"
552 [(set (pc)
553 (if_then_else
554 (match_operator:CC 0 "ordered_comparison_operator"
555 [(match_operand:HI 1 "register_operand" "r")
556 (match_operand:HI 2 "picochip_comparison_operand" "ri")])
557 (label_ref (match_operand 3 "" ""))
558 (pc)))
559 (clobber (reg:CC CC_REGNUM))]
560 ""
561 "* return picochip_output_cbranch(operands);"
562 "reload_completed
563 && (picochip_schedule_type != DFA_TYPE_NONE || flag_delayed_branch)"
564 [(set (reg:CC CC_REGNUM) (match_dup 0))
565 (parallel [(set (pc)
566 (if_then_else (match_op_dup:HI 0 [(reg:CC CC_REGNUM) (const_int 0)])
567 (label_ref (match_dup 3))
568 (pc)))
569 (use (match_dup 4))])]
570 "{
571 operands[4] = GEN_INT(GET_CODE(operands[0]));
572 }")
573
574 ;; The only difference between this and the next pattern is that the next pattern
575 ;; might introduce subtracts whose first operand is a constant. This would have to
576 ;; be a longConstant. But, we know that such a situation wouldnt arise for supported
577 ;; comparison operator and hence this pattern assumes that the second constraint combo
578 ;; would still generate a normal instruction.
579
580 (define_insn "*supported_compare"
581 [(set (reg:CC CC_REGNUM)
582 (match_operator:CC 0 "picochip_supported_comparison_operator"
583 [(match_operand:HI 1 "register_operand" "r,r,r")
584 (match_operand:HI 2 "picochip_comparison_operand" "r,J,i")]))]
585 ""
586 "* return picochip_output_compare(operands);"
587 [; Must be picoAlu because it sets the condition flags.
588 (set_attr "type" "picoAlu,picoAlu,picoAlu")
589 (set_attr "longConstant" "false,false,true")
590 (set_attr "length" "2,2,4")
591 ])
592
593 ;; This pattern was added to match the previous pattern. When doing if-convert
594 ;; the pattern generated using movhicc does not have a eq:CC but only a eq for
595 ;; operator. If this pattern were not to be there, Gcc decides not to use
596 ;; movhicc at all. Whereas, in Gcc 4.4, it seems to be cleverer.
597 (define_insn "*supported_compare1"
598 [(set (reg:CC CC_REGNUM)
599 (match_operator 0 "picochip_supported_comparison_operator"
600 [(match_operand:HI 1 "register_operand" "r,r,r")
601 (match_operand:HI 2 "picochip_comparison_operand" "r,J,i")]))]
602 ""
603 "* return picochip_output_compare(operands);"
604 [; Must be picoAlu because it sets the condition flags.
605 (set_attr "type" "picoAlu,picoAlu,picoAlu")
606 (set_attr "longConstant" "false,false,true")
607 (set_attr "length" "2,2,4")
608 ])
609
610 (define_insn "*compare"
611 [(set (reg:CC CC_REGNUM)
612 (match_operator:CC 0 "comparison_operator"
613 [(match_operand:HI 1 "register_operand" "r,r,r")
614 (match_operand:HI 2 "picochip_comparison_operand" "r,M,i")]))]
615 ""
616 "* return picochip_output_compare(operands);"
617 [; Must be picoAlu because it sets the condition flags.
618 (set_attr "type" "picoAlu,picoAlu,picoAlu")
619 (set_attr "longConstant" "false,true,true")
620 (set_attr "length" "2,4,4")
621 ])
622
623 ; Match a branch instruction, created from a tstport/cbranch split.
624 ; We use a "use" clause so GCC doesnt try to use this pattern generally.
625 (define_insn "branch"
626 [(set (pc)
627 (if_then_else
628 (match_operator 2 "comparison_operator"
629 [(reg:CC CC_REGNUM) (const_int 0)])
630 (label_ref (match_operand 0 "" ""))
631 (pc)))
632 (use (match_operand:HI 1 "const_int_operand" ""))]
633 ""
634 "* return picochip_output_branch(operands, insn);"
635 [(set (attr "length")
636 (if_then_else
637 (and (ge (minus (match_dup 0) (pc)) (const_int MIN_BRANCH_OFFSET))
638 (le (minus (match_dup 0) (pc)) (const_int MAX_BRANCH_OFFSET)))
639 (const_int SHORT_BRANCH_LENGTH)
640 (const_int LONG_BRANCH_LENGTH)))
641 (set (attr "type")
642 (if_then_else
643 (eq_attr "length" "6")
644 (const_string "realBranch")
645 (const_string "unknown")))])
646
647 ;; If a movqi is used which accesses memory on a machine which doesn't
648 ;; have byte addressing, synthesise the instruction using word load/store
649 ;; operations. The movqi's that are required during reload phase are
650 ;; handled using reload_inqi/reload_outqi.
651
652 (define_expand "movqi"
653 [(set (match_operand:QI 0 "nonimmediate_operand" "")
654 (match_operand:QI 1 "general_operand" ""))]
655 ""
656 {
657
658 if (!reload_completed &&
659 !TARGET_HAS_BYTE_ACCESS &&
660 (MEM == GET_CODE(operands[0]) || MEM == GET_CODE(operands[1])))
661 {
662 rtx address;
663 rtx wordAddress;
664 rtx const1;
665 rtx shiftVal;
666 rtx loadedValue;
667 rtx addressMask;
668 rtx topByteValue;
669 rtx signExtendedValue;
670
671
672 warn_of_byte_access();
673
674 /* Load the constant 1 into a register. */
675 const1 = gen_reg_rtx(HImode);
676 emit_insn(gen_rtx_SET(HImode, const1, GEN_INT(1)));
677
678 /* Load the address mask with the bitwise complement of 1. */
679 addressMask = gen_reg_rtx(HImode);
680 emit_insn(gen_rtx_SET(HImode, addressMask, GEN_INT(-2)));
681
682 /* Handle loads first, in case we are dealing with a mem := mem
683 * instruction. */
684 if (MEM == GET_CODE(operands[1]))
685 {
686 /* Loads work as follows. The entire word containing the desired byte
687 * is loaded. The bottom bit of the address indicates which
688 * byte is required. The desired byte is moved into the most
689 * significant byte, and then an arithmetic shift right
690 * invoked to achieve sign extension. The desired byte is
691 * moved to the MSB by XOR'ing the bottom address bit by 1,
692 * multiplying the result by 8, and then shifting left by
693 * that amount. Note that shifts only operate on the bottom
694 * 4-bits of the source offset, so although the XOR may
695 * produce a value which has its upper bits set, only bit 4
696 * (i.e., the inverted, shifted bottom address bit) actually
697 * gets used.
698 */
699
700 /* Ensure the address is in a register. */
701 address = gen_reg_rtx(HImode);
702 emit_insn(gen_rtx_SET(HImode, address, XEXP(operands[1], 0)));
703
704 /* Compute the word address by masking out the bottom bit. */
705 wordAddress = gen_reg_rtx(HImode);
706 emit_insn(gen_andhi3(wordAddress, address, addressMask));
707
708 /* Compute the shift value. This is the bottom address bit,
709 * inverted, and multiplied by 8. */
710 shiftVal = gen_reg_rtx(HImode);
711 emit_insn(gen_xorhi3(shiftVal, address, const1));
712 emit_insn(gen_ashlhi3(shiftVal, shiftVal, GEN_INT(3)));
713
714 /* Emit the memory load. */
715 loadedValue = gen_reg_rtx(HImode);
716 emit_insn(gen_rtx_SET(HImode, loadedValue, gen_rtx_MEM(HImode, wordAddress)));
717
718 /* Shift the desired byte to the most significant byte. */
719 topByteValue = gen_reg_rtx (HImode);
720 emit_insn (gen_ashlhi3 (topByteValue, loadedValue, shiftVal));
721
722 /* Sign extend the top-byte back into the bottom byte. */
723 signExtendedValue = gen_reg_rtx(HImode);
724 emit_insn(gen_ashrhi3(signExtendedValue, topByteValue, GEN_INT(8)));
725
726 /* Final extraction of QI mode register. */
727 operands[1] = gen_rtx_SUBREG(QImode, signExtendedValue, 0);
728
729 }
730
731 if (MEM == GET_CODE(operands[0]) && GET_CODE(operands[1]) != MEM)
732 {
733 rtx zeroingByteMask;
734 rtx temp;
735 rtx tempHiMode;
736 rtx lsbByteMask;
737
738 /* Get the address. */
739 address = gen_reg_rtx(HImode);
740 emit_insn(gen_rtx_SET(HImode, address, XEXP(operands[0], 0)));
741
742 /* Compute the word aligned address. */
743 wordAddress = gen_reg_rtx(HImode);
744 emit_insn(gen_andhi3(wordAddress, address, addressMask));
745
746 /* Compute the shift value. */
747 shiftVal = gen_reg_rtx(HImode);
748 emit_insn(gen_andhi3(shiftVal, address, const1));
749 emit_insn(gen_ashlhi3(shiftVal, shiftVal, GEN_INT(3)));
750
751 /* Emit the memory load. */
752 loadedValue = gen_reg_rtx(HImode);
753 emit_insn(gen_rtx_SET(HImode, loadedValue, gen_rtx_MEM(HImode, wordAddress)));
754
755 /* Zero out the destination bits by AND'ing with 0xFF00
756 * shifted appropriately. */
757 zeroingByteMask = gen_reg_rtx(HImode);
758 emit_insn(gen_rtx_SET(HImode, zeroingByteMask, GEN_INT(-256)));
759 emit_insn(gen_lshrhi3(zeroingByteMask, zeroingByteMask, shiftVal));
760 emit_insn(gen_andhi3(loadedValue, loadedValue, zeroingByteMask));
761
762 /* Grab the incoming QI register, and ensure that the top bits
763 * are zeroed out. This is because the register may be
764 * storing a signed value, in which case the top-bits will be
765 * sign bits. These must be removed to ensure that the
766 * read-modify-write (which uses an OR) doesn't pick up those
767 * bits, instead of the original memory value which is being
768 * modified.
769 */
770 tempHiMode = simplify_gen_subreg(HImode, operands[1], QImode, 0);
771 temp = gen_reg_rtx(HImode);
772 emit_insn(gen_rtx_SET(HImode, temp, tempHiMode));
773 lsbByteMask = gen_reg_rtx (HImode);
774 emit_insn (gen_rtx_SET (HImode, lsbByteMask, GEN_INT (0xFF)));
775 emit_insn (gen_andhi3 (temp, temp, lsbByteMask));
776
777 /* Shift the incoming byte value by the appropriate amount,
778 * and OR into the load value. */
779 emit_insn(gen_ashlhi3(temp, temp, shiftVal));
780 emit_insn(gen_iorhi3(loadedValue, loadedValue, temp));
781
782 /* Rewrite the original assignment, to assign the new value
783 * to the word address. */
784 operands[0] = gen_rtx_MEM(HImode, wordAddress);
785 operands[1] = loadedValue;
786
787 }
788
789 }
790 })
791
792 (define_insn "*movqi_sign_extend"
793 [(set (match_operand:HI 0 "register_operand" "=r,r")
794 (sign_extend:HI (match_operand:QI 1 "memory_operand" "a,m")))]
795 "TARGET_HAS_BYTE_ACCESS"
796 "@
797 LDB (%a1),%0\t\t// %0 = Mem(%a1)
798 LDB %a1,%0\t\t// %0 = Mem(%M1{byte})"
799 [(set_attr "type" "mem,mem")
800 (set_attr "longConstant" "true,false")
801 (set_attr "length" "4,4")])
802
803 ;; movqi instructions for machines with and without byte access.
804 (define_insn "*movqi_byte"
805 [(set (match_operand:QI 0 "nonimmediate_operand" "=r,r,r,r,r,a,m")
806 (match_operand:QI 1 "general_operand" "r,a,m,I,i,r,r"))]
807 "TARGET_HAS_BYTE_ACCESS"
808 "@
809 COPY.%# %1, %0\t// %0 := %1
810 LDB (%a1),%0\t\t// %0 = Mem(%a1)
811 LDB %a1,%0\t\t// %0 = Mem(%M1{byte})
812 COPY.%# %1,%0\t\t// %0 := #%1 (QI) (short constant)
813 COPY.%# %1,%0\t\t// %0 := #%1 (QI) (long constant)
814 STB %1,(%a0)\t\t// Mem(%a0) := %1
815 STB %1,%a0\t\t// Mem(%M0{byte}) := %1"
816 [(set_attr "type" "basicAlu,mem,mem,basicAlu,basicAlu,mem,mem")
817 (set_attr "longConstant" "false,true,false,false,true,true,false")
818 (set_attr "length" "2,4,4,2,4,4,4")])
819
820 ;; Machines which don't have byte access can copy registers, and load
821 ;; constants, but can't access memory. The define_expand for movqi
822 ;; should already have rewritten memory accesses using word
823 ;; operations. The exception is qi reloads, which are handled using
824 ;; the reload_? patterns.
825 (define_insn "*movqi_nobyte"
826 [(set (match_operand:QI 0 "register_operand" "=r,r")
827 (match_operand:QI 1 "picochip_register_or_immediate_operand" "r,i"))]
828 "!TARGET_HAS_BYTE_ACCESS"
829 "@
830 COPY.%# %1,%0\t// %0 := %1
831 COPY.%# %1,%0\t\t// %0 := #%1 (QI)")
832
833 (define_insn "movhi"
834 [(set (match_operand:HI 0 "nonimmediate_operand" "=r,r,r,a,m,r,r")
835 (match_operand:HI 1 "general_operand" "r,a,m,r,r,I,i"))]
836 ""
837 "@
838 COPY.%# %1,%0\t\t// %0 := %1
839 LDW (%a1),%0\t\t// %0 := Mem(%a1)
840 LDW %a1,%0\t\t// %0 = Mem(%M1{byte})
841 STW %1,(%a0)\t\t// Mem(%a0) := %1
842 STW %1,%a0\t\t// Mem(%M0{byte}) := %1
843 COPY.%# %1,%0\t// %0 := %1 (short constant)
844 COPY.%# %1,%0\t// %0 := %1 (long constant)"
845 [(set_attr "type" "basicAlu,mem,mem,mem,mem,basicAlu,basicAlu")
846 (set_attr "longConstant" "false,true,false,true,false,false,true")
847 (set_attr "length" "2,4,4,4,4,2,4")])
848
849 (define_insn "movsi"
850 [(set (match_operand:SI 0 "nonimmediate_operand" "=r,r,r,r,a,m")
851 (match_operand:SI 1 "general_operand" "r,a,m,i,r,r"))]
852 ""
853 "@
854 // %R0 := %R1 (SI)\n\tCOPY.%# %L1,%L0 %| COPY.1 %U1,%U0
855 LDL (%a1),%R0\t\t// %R0 = Mem(%a1)
856 LDL %a1,%R0\t\t// %R0 = Mem(%M1{byte})
857 // %R0 := #%1 (SI)\n\tCOPY.%# %L1,%L0 %| COPY.%# %U1,%U0
858 STL %R1,(%a0)\t\t// Mem(%a0) := %R1
859 STL %R1,%a0\t\t// Mem(%M0{byte}) := %R1"
860 [(set_attr "type" "unknown,mem,mem,unknown,mem,mem")
861 (set_attr "longConstant" "false,true,false,true,false,false")
862 (set_attr "length" "4,4,4,6,4,4")])
863
864 ; Split an SI mode register copy into separate HI mode copies, which
865 ; can be VLIW'd with other instructions. Only split the instruction
866 ; when VLIW scheduling is enabled. Splitting the instruction saves
867 ; some code space.
868 ;
869 ; This is predicated in reload_completed. This ensures that the
870 ; instructions aren't broken up too early which can result in the
871 ; SImode code being converted into inefficient HI mode code.
872
873 (define_split
874 [(set (match_operand:SI 0 "register_operand" "")
875 (match_operand:SI 1 "register_operand" ""))]
876 "reload_completed && picochip_schedule_type == DFA_TYPE_SPEED"
877 [(set (match_dup 2) (match_dup 3))
878 (set (match_dup 4) (match_dup 5))]
879 "{
880 operands[2] = gen_lowpart (HImode, operands[0]);
881 operands[3] = gen_lowpart (HImode, operands[1]);
882 operands[4] = gen_highpart (HImode, operands[0]);
883 operands[5] = gen_highpart (HImode, operands[1]);
884 }")
885
886 ; SI Mode split for load constant.
887 (define_split
888 [(set (match_operand:SI 0 "register_operand" "")
889 (match_operand:SI 1 "const_int_operand" ""))]
890 "reload_completed"
891 [(set (match_dup 2) (match_dup 3))
892 (set (match_dup 4) (match_dup 5))]
893 "{
894 operands[2] = gen_lowpart (HImode, operands[0]);
895 operands[3] = picochip_get_low_const(operands[1]);
896 operands[4] = gen_highpart (HImode, operands[0]);
897 operands[5] = picochip_get_high_const(operands[1]);
898 }")
899
900 (define_insn "movsf"
901 [(set (match_operand:SF 0 "nonimmediate_operand" "=r,r,r,m")
902 (match_operand:SF 1 "general_operand" "r,m,i,r"))]
903 ""
904 "@
905 // %R0 := %R1 (SF)\n\tCOPY.%# %L1,%L0 %| COPY.1 %U1,%U0
906 LDL %a1,%R0\t\t// %R0 :={SF} Mem(%M1{byte})
907 // %R0 := #%1 (SF)\n\tCOPY.%# %L1,%L0\n\tCOPY.%# %U1,%U0
908 STL %R1,%a0\t\t// Mem(%M0{byte}) :={SF} %R1")
909
910 ;; memcpy pattern
911 ;; 0 = destination (mem:BLK ...)
912 ;; 1 = source (mem:BLK ...)
913 ;; 2 = count
914 ;; 3 = alignment
915 (define_expand "movmemhi"
916 [(match_operand 0 "memory_operand" "")
917 (match_operand 1 "memory_operand" "")
918 (match_operand:HI 2 "immediate_operand" "")
919 (match_operand 3 "" "")]
920 "picochip_schedule_type != DFA_TYPE_NONE"
921 "if (picochip_expand_movmemhi(operands)) DONE; FAIL;"
922 )
923
924 ;;===========================================================================
925 ;; NOP
926 ;;===========================================================================
927
928 ;; No-operation (NOP)
929 (define_insn "nop"
930 [(const_int 0)]
931 ""
932 "NOP\t// nop"
933 [(set_attr "length" "1")])
934
935 ;;===========================================================================
936 ;; Function Calls. Define expands are used to ensure that the correct
937 ;; type of pattern is emitted, and then the define_insn's match the
938 ;; pattern using the correct types.
939 ;;
940 ;; Note: The comments output as part of these instructions are detected by
941 ;; the linker. Don't change the comments!
942 ;;===========================================================================
943
944 (define_expand "call"
945 [(parallel [(call (match_operand:QI 0 "memory_operand" "")
946 (match_operand 1 "const_int_operand" ""))
947 (clobber (reg:HI LINK_REGNUM))])]
948 ""
949 "")
950
951 (define_insn "call_for_divmod"
952 [(call (match_operand:QI 0 "memory_operand" "")
953 (match_operand 1 "const_int_operand" ""))]
954 ""
955 "JL (%M0)\t// fn_call %M0%>"
956 [(set_attr "length" "4")
957 (set_attr "type" "realBranch")
958 (set_attr "longConstant" "true")])
959
960 (define_insn "*call_using_symbol"
961 [(call (mem:QI (match_operand:HI 0 "immediate_operand" "i"))
962 (match_operand 1 "const_int_operand" ""))
963 (clobber (reg:HI LINK_REGNUM))]
964 ""
965 "JL (%M0)\t// fn_call %M0%>"
966 [(set_attr "length" "4")
967 (set_attr "type" "realBranch")
968 (set_attr "longConstant" "true")])
969
970 (define_insn "*call_using_register"
971 [(call (mem:QI (match_operand:HI 0 "register_operand" "r"))
972 (match_operand 1 "const_int_operand" ""))
973 (clobber (reg:HI LINK_REGNUM))]
974 ""
975 "JL (%r0)\t// fn_call_unknown %r0%>"
976 [(set_attr "length" "2")
977 (set_attr "type" "realBranch")
978 (set_attr "longConstant" "false")])
979
980 (define_expand "call_value"
981 [(parallel [(set (match_operand:HI 0 "" "")
982 (call:HI (match_operand:QI 1 "memory_operand" "g")
983 (match_operand 2 "const_int_operand" "")))
984 (clobber (reg:HI LINK_REGNUM))])]
985 ""
986 "")
987
988 (define_insn "*call_value_using_symbol"
989 [(set (match_operand:HI 0 "" "")
990 (call:HI (mem:QI (match_operand:HI 1 "immediate_operand" "i"))
991 (match_operand 2 "const_int_operand" "")))
992 (clobber (reg:HI LINK_REGNUM))]
993 ""
994 "JL (%M1)\t// fn_call %M1 (value return)%>"
995 [(set_attr "length" "4")
996 (set_attr "type" "realBranch")
997 (set_attr "longConstant" "true")])
998
999 (define_insn "*call_value_using_register"
1000 [(set (match_operand:HI 0 "" "")
1001 (call:HI (mem:QI (match_operand:HI 1 "register_operand" "r"))
1002 (match_operand 2 "const_int_operand" "")))
1003 (clobber (reg:HI LINK_REGNUM))]
1004 ""
1005 "JL (%r1)// fn_call_unknown %r1 (value return)%>"
1006 [(set_attr "length" "2")
1007 (set_attr "type" "realBranch")
1008 (set_attr "longConstant" "false")])
1009
1010 ;;===========================================================================
1011 ;; Addition
1012 ;;===========================================================================
1013
1014 ;; Note that the addition of a negative value is transformed into the
1015 ;; subtraction of a positive value, so that the add/sub immediate slot
1016 ;; can make better use of the 4-bit range.
1017
1018 (define_insn "addhi3"
1019 [(set (match_operand:HI 0 "register_operand" "=r,r,r,r")
1020 (plus:HI (match_operand:HI 1 "register_operand" "r,r,r,r")
1021 (match_operand:HI 2 "general_operand" "r,M,n,i")))
1022 (clobber (reg:CC CC_REGNUM))]
1023 ""
1024 { if (CONST_INT == GET_CODE(operands[2]) &&
1025 INTVAL(operands[2]) > -16 &&
1026 INTVAL(operands[2]) < 0)
1027 return "SUB.%# %1,-(%2),%0\t// %0 := %1 + %2 (HI)";
1028 else
1029 return "ADD.%# %1,%2,%0\t// %0 := %1 + %2 (HI)";
1030 }
1031 [(set_attr "type" "basicAlu,basicAlu,basicAlu,basicAlu")
1032 (set_attr "longConstant" "false,false,true,true")
1033 (set_attr "length" "2,2,4,4")]
1034 )
1035
1036
1037 ;; If we peepholed the compare instruction out, we need to make sure the add
1038 ;; goes in slot 0. This pattern is just to accomplish that.
1039
1040 (define_insn "addhi3_with_use_clause"
1041 [(set (match_operand:HI 0 "register_operand" "=r,r,r,r")
1042 (plus:HI (match_operand:HI 1 "register_operand" "r,r,r,r")
1043 (match_operand:HI 2 "general_operand" "r,M,n,i")))
1044 (set (reg:CC CC_REGNUM)
1045 (match_operator:CC 3 "picochip_peephole_comparison_operator"
1046 [(const_int 0)
1047 (const_int 0)]))]
1048 ""
1049 { if (CONST_INT == GET_CODE(operands[2]) &&
1050 INTVAL(operands[2]) > -16 &&
1051 INTVAL(operands[2]) < 0)
1052 return "SUB.0 %1,-(%2),%0\t// %0 := %1 + %2 (HI)";
1053 else
1054 return "ADD.0 %1,%2,%0\t// %0 := %1 + %2 (HI)";
1055 }
1056 [(set_attr "type" "picoAlu,picoAlu,picoAlu,picoAlu")
1057 (set_attr "longConstant" "false,false,true,true")
1058 (set_attr "length" "2,2,4,4")]
1059 )
1060
1061 ;; Match an addition in which the first operand has been shifted
1062 ;; (e.g., the comms array functions can emit such instructions).
1063 (define_insn "*addWith1stOpShift"
1064 [(set (match_operand:HI 0 "register_operand" "=r,r")
1065 (plus:HI (ashift:HI (match_operand:HI 1 "register_operand" "r,r")
1066 (match_operand:HI 2 "const_int_operand" ""))
1067 (match_operand:HI 3 "immediate_operand" "I,i")))
1068 (clobber (reg:CC CC_REGNUM))]
1069 ""
1070 "ADD.0 [LSL %1,%2],%3,%0\t// %0 := (%1 << %2) + %3"
1071 [(set_attr "type" "picoAlu,picoAlu")
1072 (set_attr "longConstant" "false,true")])
1073
1074 (define_insn_and_split "addsi3"
1075 [(set (match_operand:SI 0 "register_operand" "=r,r")
1076 (plus:SI (match_operand:SI 1 "register_operand" "r,r")
1077 (match_operand:SI 2 "general_operand" "r,i")))
1078 (clobber (reg:CC CC_REGNUM))]
1079 ""
1080 "// %0 := %1 + %2 (SI)\n\tADD.0 %L1,%L2,%L0\n\tADDC.0 %U1,%U2,%U0"
1081 "reload_completed && picochip_schedule_type != DFA_TYPE_NONE"
1082 [(match_dup 4)
1083 (match_dup 5)]
1084 "
1085 {
1086 rtx op0_high = gen_highpart (HImode, operands[0]);
1087 rtx op1_high = gen_highpart (HImode, operands[1]);
1088 rtx op0_low = gen_lowpart (HImode, operands[0]);
1089 rtx op1_low = gen_lowpart (HImode, operands[1]);
1090 rtx op2_high, op2_low;
1091
1092 if (CONST_INT == GET_CODE(operands[2]))
1093 {
1094 op2_high = picochip_get_high_const(operands[2]);
1095 op2_low = picochip_get_low_const(operands[2]);
1096 } else {
1097 op2_high = gen_highpart (HImode, operands[2]);
1098 op2_low = gen_lowpart (HImode, operands[2]);
1099 }
1100
1101 operands[4] = gen_add_multi_lower (op0_low, op1_low, op2_low);
1102 operands[5] = gen_add_multi_upper (op0_high, op1_high, op2_high);
1103
1104 }")
1105
1106 ;; Perform the lowest part of a multi-part addition (SI/DI). This sets
1107 ;; the flags, so is an picoAlu instruction (we could use a
1108 ;; conventional addhi, but the addhi is better off being a treated as
1109 ;; a basicAlu instruction, rather than a picoAlu instruction).
1110 (define_insn "add_multi_lower"
1111 [(set (match_operand:HI 0 "register_operand" "=r,r,r")
1112 (plus:HI (match_operand:HI 1 "register_operand" "r,r,r")
1113 (match_operand:HI 2 "general_operand" "r,M,i")))
1114 (set (reg:CC CC_REGNUM)
1115 (compare:CC (plus:HI (match_dup 1)
1116 (match_dup 2))
1117 (const_int 0)))]
1118 ""
1119 { if (CONST_INT == GET_CODE(operands[2]) &&
1120 INTVAL(operands[2]) > -16 &&
1121 INTVAL(operands[2]) < 0)
1122 return "SUB.%# %1,-(%2),%0\t// %0+carry := %1 + %2 (low multi-part)";
1123 else
1124 return "ADD.%# %1,%2,%0\t// %0+carry := %1 + %2 (low multi-part)";
1125 }
1126 [(set_attr "type" "picoAlu,picoAlu,picoAlu")
1127 (set_attr "longConstant" "false,false,true")
1128 (set_attr "length" "2,2,4")])
1129
1130 ;; Perform the central part of a multi-part addition (DI). This uses
1131 ;; the CC register, and also sets the CC register, so needs to be
1132 ;; placed in the first ALU slot. Note that the ADDC must
1133 ;; use the long constant to represent immediates.
1134 (define_insn "add_multi_mid"
1135 [(set (match_operand:HI 0 "register_operand" "=r,r")
1136 (plus:HI (match_operand:HI 1 "register_operand" "r,r")
1137 (plus:HI (match_operand:HI 2 "general_operand" "r,i")
1138 (reg:CC CC_REGNUM))))
1139 (set (reg:CC CC_REGNUM)
1140 (compare:CC (plus:HI (match_dup 1)
1141 (match_dup 2))
1142 (const_int 0)))]
1143 ""
1144 "ADDC.%# %1,%2,%0\t// %0+carry := carry + %1 + %2 (mid multi-part)"
1145 [(set_attr "type" "picoAlu,picoAlu")
1146 (set_attr "longConstant" "false,true")
1147 (set_attr "length" "2,4")])
1148
1149 ;; Perform the highest part of a multi-part addition (SI/DI). This
1150 ;; uses the CC register, but doesn't require any registers to be set,
1151 ;; so may be scheduled in either of the ALU's. Note that the ADDC must
1152 ;; use the long constant to represent immediates.
1153 (define_insn "add_multi_upper"
1154 [(set (match_operand:HI 0 "register_operand" "=r,r")
1155 (plus:HI (match_operand:HI 1 "register_operand" "r,r")
1156 (plus:HI (match_operand:HI 2 "general_operand" "r,i")
1157 (reg:CC CC_REGNUM))))
1158 (clobber (reg:CC CC_REGNUM))]
1159 ""
1160 "ADDC.%# %1,%2,%0\t// %0 := carry + %1 + %2 (high multi-part)"
1161 [(set_attr "type" "basicAlu,basicAlu")
1162 (set_attr "longConstant" "false,true")
1163 (set_attr "length" "2,4")])
1164
1165 ;; The lea instruction is a special type of add operation, which looks
1166 ;; like a movhi (reg := address). It expands into reg := fp +
1167 ;; offset. Ideally there should be two variants, which take different
1168 ;; sized offsets (i.e., using the long constant, or not, as
1169 ;; appropriate). However, the address operand may have arbitrary
1170 ;; values added to it later (i.e., the AP will be eliminated, possibly
1171 ;; converting a small offset into a long offset), so a long offset is
1172 ;; always assumed.
1173
1174 ;; Note that the lea can use an addition, and hence may modify the CC
1175 ;; register. This upsets scheduling, so instead the lea is placed in
1176 ;; ALU 1 where it cannot modify CC.
1177
1178 (define_insn "*lea_add"
1179 [(set (match_operand:HI 0 "nonimmediate_operand" "=r")
1180 (plus:HI (match_operand:HI 1 "register_operand" "r")
1181 (match_operand:HI 2 "immediate_operand" "i")))]
1182 ""
1183 "ADD.1 %1,%2,%0\t// lea (add)")
1184
1185 ;; Note that, though this instruction looks similar to movhi pattern,
1186 ;; "p" constraint cannot be specified for operands other than
1187 ;; address_operand, hence the extra pattern below.
1188 (define_insn "*lea_move"
1189 [(set (match_operand:HI 0 "nonimmediate_operand" "=r")
1190 (match_operand:HI 1 "address_operand" "p"))]
1191 ""
1192 {
1193 if (REG == GET_CODE(operands[1]))
1194 return "COPY.1 %1,%0\t// %0 := %1 (lea)";
1195 else
1196 return "ADD.1 %b1,%o1,%0\t\t// %0 := %b1 + %o1 (lea)";
1197 }
1198 [(set_attr "type" "nonCcAlu")
1199 (set_attr "longConstant" "true")
1200 (set_attr "length" "4")])
1201
1202
1203 ;;===========================================================================
1204 ;; Subtraction. Note that these patterns never take immediate second
1205 ;; operands, since those cases are handled by canonicalising the
1206 ;; instruction into the addition of a negative costant.
1207 ;; But, if the first operand needs to be a negative constant, it
1208 ;; is supported here.
1209 ;;===========================================================================
1210
1211 (define_insn "subhi3"
1212 [(set (match_operand:HI 0 "register_operand" "=r,r,r")
1213 (minus:HI (match_operand:HI 1 "general_operand" "r,I,i")
1214 (match_operand:HI 2 "register_operand" "r,r,r")))
1215 (clobber (reg:CC CC_REGNUM))]
1216 ""
1217 "SUB.%# %1,%2,%0 // %0 := %1 - %2 (HI)"
1218 [(set_attr "type" "basicAlu,basicAlu,basicAlu")
1219 (set_attr "longConstant" "false,true,true")
1220 (set_attr "length" "2,4,4")])
1221
1222 ;; If we peepholed the compare instruction out, we need to make sure the
1223 ;; sub goes in slot 0. This pattern is just to accomplish that.
1224
1225 (define_insn "subhi3_with_use_clause"
1226 [(set (match_operand:HI 0 "register_operand" "=r,r,r")
1227 (minus:HI (match_operand:HI 1 "general_operand" "r,I,i")
1228 (match_operand:HI 2 "register_operand" "r,r,r")))
1229 (set (reg:CC CC_REGNUM)
1230 (match_operator:CC 3 "picochip_peephole_comparison_operator"
1231 [(const_int 0)
1232 (const_int 0)]))]
1233 ""
1234 "SUB.0 %1,%2,%0 // %0 := %1 - %2 (HI)"
1235 [(set_attr "type" "picoAlu,picoAlu,picoAlu")
1236 (set_attr "longConstant" "false,true,true")
1237 (set_attr "length" "2,4,4")])
1238
1239 (define_insn_and_split "subsi3"
1240 [(set (match_operand:SI 0 "register_operand" "=r,r")
1241 (minus:SI (match_operand:SI 1 "general_operand" "r,i")
1242 (match_operand:SI 2 "register_operand" "r,r")))
1243 (clobber (reg:CC CC_REGNUM))]
1244 ""
1245 "// %0 := %1 - %2 (SI)\n\tSUB.%# %L1,%L2,%L0\n\tSUBB.%# %U1,%U2,%U0"
1246 "reload_completed && picochip_schedule_type != DFA_TYPE_NONE"
1247 [(match_dup 4)
1248 (match_dup 5)]
1249 "
1250 {
1251 rtx op0_high = gen_highpart (HImode, operands[0]);
1252 rtx op0_low = gen_lowpart (HImode, operands[0]);
1253 rtx op2_high = gen_highpart (HImode, operands[2]);
1254 rtx op2_low = gen_lowpart (HImode, operands[2]);
1255 rtx op1_high,op1_low;
1256
1257 if (CONST_INT == GET_CODE(operands[1]))
1258 {
1259 op1_high = picochip_get_high_const(operands[1]);
1260 op1_low = picochip_get_low_const(operands[1]);
1261 } else {
1262 op1_high = gen_highpart (HImode, operands[1]);
1263 op1_low = gen_lowpart (HImode, operands[1]);
1264 }
1265
1266
1267 operands[4] = gen_sub_multi_lower (op0_low, op1_low, op2_low);
1268 operands[5] = gen_sub_multi_upper (op0_high, op1_high, op2_high);
1269
1270 }")
1271
1272 ;; Match the patterns emitted by the multi-part subtraction splitting.
1273 ;; This sets the CC register, so it needs to go into slot 0.
1274 (define_insn "sub_multi_lower"
1275 [(set (match_operand:HI 0 "register_operand" "=r,r")
1276 (minus:HI (match_operand:HI 1 "general_operand" "r,i")
1277 (match_operand:HI 2 "register_operand" "r,r")))
1278 (set (reg:CC CC_REGNUM)
1279 (compare:CC (minus:HI (match_dup 1) (match_dup 2))
1280 (const_int 0)))]
1281 ""
1282 "SUB.%# %1,%2,%0\t// %0+carry := %1 - %2 (lower SI)"
1283 [(set_attr "type" "picoAlu,picoAlu")
1284 (set_attr "longConstant" "false,true")
1285 (set_attr "length" "2,4")])
1286
1287 ;; Perform the central part of a multi-part addition (DI). This uses
1288 ;; the CC register, and also sets the CC register, so needs to be
1289 ;; placed in the first ALU.
1290 (define_insn "sub_multi_mid"
1291 [(set (match_operand:HI 0 "register_operand" "=r,r")
1292 (minus:HI (match_operand:HI 1 "general_operand" "r,i")
1293 (minus:HI (match_operand:HI 2 "register_operand" "r,r")
1294 (reg:CC CC_REGNUM))))
1295 (set (reg:CC CC_REGNUM)
1296 (compare:CC (minus:HI (match_dup 1)
1297 (match_dup 2))
1298 (const_int 0)))]
1299 ""
1300 "SUBB.%# %1,%2,%0\t// %0+carry := carry - %1 - %2 (mid multi-part)"
1301 [(set_attr "type" "picoAlu,picoAlu")
1302 (set_attr "longConstant" "false,true")
1303 (set_attr "length" "2,4")])
1304
1305 (define_insn "sub_multi_upper"
1306 [(set (match_operand:HI 0 "register_operand" "=r,r")
1307 (minus:HI (match_operand:HI 1 "general_operand" "r,i")
1308 (minus:HI (match_operand:HI 2 "register_operand" "r,r")
1309 (reg:CC CC_REGNUM))))
1310 (clobber (reg:CC CC_REGNUM))]
1311 ""
1312 "SUBB.%# %1,%2,%0\t// %0 := carry - %1 - %2 (upper SI)"
1313 [(set_attr "type" "basicAlu,basicAlu")
1314 (set_attr "longConstant" "false,true")
1315 (set_attr "length" "2,4")])
1316
1317 ;;===========================================================================
1318 ;; Multiplication (signed)
1319 ;;===========================================================================
1320
1321 (define_insn "multiply_machi"
1322 [(set (reg:HI ACC_REGNUM)
1323 (mult:HI (match_operand:HI 0 "register_operand" "r,r")
1324 (match_operand:HI 1
1325 "picochip_register_or_immediate_operand" "r,i")))]
1326 "TARGET_HAS_MAC_UNIT"
1327 "MUL %0,%1,acc0\t// acc0 := %0 * %1 (signed)"
1328 [(set_attr "length" "3,5")
1329 (set_attr "type" "mac,mac")
1330 (set_attr "longConstant" "false,true")])
1331
1332 (define_expand "mulhi3"
1333 [(set (match_operand:HI 0 "register_operand" "")
1334 (mult:HI (match_operand:HI 1 "register_operand" "")
1335 (match_operand:HI 2 "picochip_register_or_immediate_operand" "")))]
1336 "TARGET_HAS_MULTIPLY"
1337 "")
1338
1339 ;; Different types of mulhi, depending on the AE type. If the AE has MUL unit,
1340 ;; use the following pattern.
1341 (define_insn "*mulhi3_mul"
1342 [(set (match_operand:HI 0 "register_operand" "=r,r")
1343 (mult:HI (match_operand:HI 1 "register_operand" "r,r")
1344 (match_operand:HI 2
1345 "picochip_register_or_immediate_operand" "r,i")))]
1346 "TARGET_HAS_MUL_UNIT"
1347 "MULL %1,%2,%0 // %0 := %1 * %2 (HI)"
1348 [(set_attr "length" "3,5")
1349 (set_attr "type" "mul,mul")
1350 (set_attr "longConstant" "false,true")])
1351
1352 ;; If the AE has MAC unit, instead, use the following pattern.
1353 (define_insn_and_split "*mulhi3_mac"
1354 [(set (match_operand:HI 0 "register_operand" "=r,r")
1355 (mult:HI (match_operand:HI 1 "register_operand" "r,r")
1356 (match_operand:HI 2
1357 "picochip_register_or_immediate_operand" "r,i")))]
1358 "TARGET_HAS_MAC_UNIT"
1359 "// %0 := %1 * %2\n\tMUL %1,%2,acc0\n\tREADACC acc0,frac,%0"
1360 "TARGET_HAS_MAC_UNIT && reload_completed"
1361 [(match_dup 3)
1362 (match_dup 4)]
1363 "
1364 {
1365 rtx const_rtx = GEN_INT(0);
1366 operands[3] = (gen_multiply_machi(operands[1], operands[2]));
1367 operands[4] = (gen_movhi_mac(operands[0],const_rtx));
1368 } "
1369 )
1370
1371 (define_insn "umultiply_machisi"
1372 [(set (reg:SI ACC_REGNUM)
1373 (mult:SI (zero_extend:SI (match_operand:HI 0 "register_operand" "r"))
1374 (zero_extend:SI (match_operand:HI 1 "register_operand" "r"))))]
1375 "TARGET_HAS_MAC_UNIT"
1376 "MULUU %0,%1,acc0\t// acc0 := %0 * %1 (unsigned)"
1377 [(set_attr "length" "3")
1378 (set_attr "type" "mac")
1379 (set_attr "longConstant" "false")])
1380
1381 (define_insn "multiply_machisi"
1382 [(set (reg:SI ACC_REGNUM)
1383 (mult:SI (sign_extend:SI (match_operand:HI 0 "register_operand" "r,r"))
1384 (sign_extend:SI (match_operand:HI 1
1385 "picochip_register_or_immediate_operand" "r,i"))))]
1386 "TARGET_HAS_MAC_UNIT"
1387 "MUL %0,%1,acc0\t// acc0 := %0 * %1 (signed)"
1388 [(set_attr "length" "3,5")
1389 (set_attr "type" "mac,mac")
1390 (set_attr "longConstant" "false,true")])
1391
1392 ;; We want to prevent GCC from thinking ACC is a normal register and using
1393 ;; this pattern. We want it to be used only when you use MAC unit
1394 ;; multiplication. Added a "use" clause for that sake.
1395 (define_insn "movsi_mac"
1396 [(set (match_operand:SI 0 "register_operand" "=r")
1397 (reg:SI ACC_REGNUM))
1398 (use (match_operand:SI 1 "const_int_operand" ""))]
1399 "TARGET_HAS_MAC_UNIT"
1400 "READACC32 acc0,%R0 \t// %0 := acc0 "
1401 [(set_attr "length" "3")
1402 (set_attr "type" "mac")
1403 (set_attr "longConstant" "false")])
1404
1405 ;; We want to prevent GCC from thinking ACC is a normal register and using
1406 ;; this pattern. We want it to be used only when you use MAC unit
1407 ;; multiplication. Added a "use" clause for that sake.
1408 (define_insn "movhi_mac"
1409 [(set (match_operand:HI 0 "register_operand" "=r")
1410 (reg:HI ACC_REGNUM) )
1411 (use (match_operand:HI 1 "const_int_operand" ""))]
1412 "TARGET_HAS_MAC_UNIT"
1413 "READACC acc0,frac,%0 \t// %0 := acc0 "
1414 [(set_attr "length" "3")
1415 (set_attr "type" "mac")
1416 (set_attr "longConstant" "false")])
1417
1418 ;; 16-bit to 32-bit widening signed multiplication.
1419 (define_expand "mulhisi3"
1420 [(set (match_operand:SI 0 "register_operand" "=&r")
1421 (mult:SI (sign_extend:SI (match_operand:HI 1 "register_operand" "r"))
1422 (sign_extend:SI (match_operand:HI 2 "register_operand" "r"))))]
1423 "TARGET_HAS_MULTIPLY"
1424 ""
1425 )
1426
1427 (define_insn_and_split "*mulhisi3_mul"
1428 [(set (match_operand:SI 0 "register_operand" "=&r")
1429 (mult:SI (sign_extend:SI (match_operand:HI 1 "register_operand" "r"))
1430 (sign_extend:SI (match_operand:HI 2 "register_operand" "r"))))]
1431 "TARGET_HAS_MUL_UNIT"
1432 "// %0 := %1 * %2 (HI->SI)\;MULL %1,%2,%L0\;MULH %1,%2,%U0";
1433 "TARGET_HAS_MUL_UNIT && reload_completed && picochip_schedule_type != DFA_TYPE_NONE"
1434 [(match_dup 3)
1435 (match_dup 4)]
1436 "
1437 {
1438 rtx op0_high = gen_highpart (HImode, operands[0]);
1439 rtx op0_low = gen_lowpart (HImode, operands[0]);
1440 operands[3] = gen_mulhisi3_mul_lower(op0_low,operands[1],operands[2]);
1441 operands[4] = gen_mulhisi3_mul_higher(op0_high,operands[1],operands[2]);
1442 }
1443 "
1444 )
1445
1446 (define_insn "mulhisi3_mul_lower"
1447 [(set (match_operand:HI 0 "register_operand" "=&r")
1448 (subreg:HI
1449 (mult:SI
1450 (sign_extend:SI (match_operand:HI 1 "register_operand" "r"))
1451 (sign_extend:SI (match_operand:HI 2 "register_operand" "r"))) 0))]
1452 "TARGET_HAS_MUL_UNIT"
1453 "MULL %1,%2,%0"
1454 [(set_attr "length" "3")
1455 (set_attr "type" "mul")
1456 (set_attr "longConstant" "false")])
1457
1458 (define_insn "mulhisi3_mul_higher"
1459 [(set (match_operand:HI 0 "register_operand" "=&r")
1460 (subreg:HI
1461 (mult:SI
1462 (sign_extend:SI (match_operand:HI 1 "register_operand" "r"))
1463 (sign_extend:SI (match_operand:HI 2 "register_operand" "r"))) 2))]
1464 "TARGET_HAS_MUL_UNIT"
1465 "MULH %1,%2,%0"
1466 [(set_attr "length" "3")
1467 (set_attr "type" "mul")
1468 (set_attr "longConstant" "false")])
1469
1470 (define_insn_and_split "*mulhisi3_mac"
1471 [(set (match_operand:SI 0 "register_operand" "=&r")
1472 (mult:SI (sign_extend:SI (match_operand:HI 1 "register_operand" "r"))
1473 (sign_extend:SI (match_operand:HI 2 "register_operand" "r"))))]
1474 "TARGET_HAS_MAC_UNIT"
1475 "// %0 := %1 * %2 (HI->SI) STAN2\;MUL %1,%2,acc0\;READACC32 acc0,%R0";
1476 "TARGET_HAS_MAC_UNIT && reload_completed"
1477 [(match_dup 3)
1478 (match_dup 4)]
1479 "
1480 {
1481 rtx const_rtx = gen_int_mode(0,SImode);
1482 operands[3] = (gen_multiply_machisi(operands[1], operands[2]));
1483 operands[4] = (gen_movsi_mac(operands[0],const_rtx));
1484 } "
1485 )
1486
1487 ;;===========================================================================
1488 ;; Widening multiplication (unsigned)
1489 ;;===========================================================================
1490
1491 (define_expand "umulhisi3"
1492 [(set (match_operand:SI 0 "register_operand" "=&r")
1493 (mult:SI (zero_extend:SI (match_operand:HI 1 "register_operand" "r"))
1494 (zero_extend:SI (match_operand:HI 2 "register_operand" "r"))))]
1495 "TARGET_HAS_MULTIPLY"
1496 ""
1497 )
1498
1499 (define_insn_and_split "*umulhisi3_mul"
1500 [(set (match_operand:SI 0 "register_operand" "=&r")
1501 (mult:SI (zero_extend:SI (match_operand:HI 1 "register_operand" "r"))
1502 (zero_extend:SI (match_operand:HI 2 "register_operand" "r"))))]
1503 "TARGET_HAS_MUL_UNIT"
1504 "// %0 := %1 * %2 (uHI->uSI Type 1)\;MULUL %1,%2,%L0\n\tMULUH %1,%2,%U0";
1505 "TARGET_HAS_MUL_UNIT && reload_completed && picochip_schedule_type != DFA_TYPE_NONE"
1506 [(match_dup 3)
1507 (match_dup 4)]
1508 "
1509 {
1510 rtx op0_high = gen_highpart (HImode, operands[0]);
1511 rtx op0_low = gen_lowpart (HImode, operands[0]);
1512 operands[3] = gen_umulhisi3_mul_lower(op0_low,operands[1],operands[2]);
1513 operands[4] = gen_umulhisi3_mul_higher(op0_high,operands[1],operands[2]);
1514 }
1515 "
1516 )
1517
1518 (define_insn "umulhisi3_mul_lower"
1519 [(set (match_operand:HI 0 "register_operand" "=&r")
1520 (subreg:HI
1521 (mult:SI
1522 (zero_extend:SI (match_operand:HI 1 "register_operand" "r"))
1523 (zero_extend:SI (match_operand:HI 2 "register_operand" "r"))) 0))]
1524 "TARGET_HAS_MUL_UNIT"
1525 "MULUL %1,%2,%0"
1526 [(set_attr "length" "3")
1527 (set_attr "type" "mul")
1528 (set_attr "longConstant" "false")])
1529
1530 (define_insn "umulhisi3_mul_higher"
1531 [(set (match_operand:HI 0 "register_operand" "=&r")
1532 (subreg:HI
1533 (mult:SI
1534 (zero_extend:SI (match_operand:HI 1 "register_operand" "r"))
1535 (zero_extend:SI (match_operand:HI 2 "register_operand" "r"))) 2))]
1536 "TARGET_HAS_MUL_UNIT"
1537 "MULUH %1,%2,%0"
1538 [(set_attr "length" "3")
1539 (set_attr "type" "mul")
1540 (set_attr "longConstant" "false")])
1541
1542 (define_insn_and_split "*umulhisi3_mac"
1543 [(set (match_operand:SI 0 "register_operand" "=&r")
1544 (mult:SI (zero_extend:SI (match_operand:HI 1 "register_operand" "r"))
1545 (zero_extend:SI (match_operand:HI 2 "register_operand" "r"))))]
1546 "TARGET_HAS_MAC_UNIT"
1547 "// %0 := %1 * %2 (uHI->uSI Type 3)\;MULUU %1,%2,acc0\;READACC32 acc0,%R0";
1548 "TARGET_HAS_MAC_UNIT && reload_completed"
1549 [(match_dup 3)
1550 (match_dup 4)]
1551 "
1552 {
1553 rtx const_rtx = gen_int_mode(0,SImode);
1554 operands[3] = (gen_umultiply_machisi(operands[1], operands[2]));
1555 operands[4] = (gen_movsi_mac(operands[0],const_rtx));
1556 } "
1557 )
1558
1559 ;;===========================================================================
1560 ;; Division (signed)
1561 ;;===========================================================================
1562
1563 ;; Perform a divmod operation as a function call. This results in some
1564 ;; registers being clobbered (r0-6, r12 - ignore r13,14 as these are
1565 ;; known not to be affected).
1566 (define_expand "divmodhi4"
1567 [
1568 ; Copy the inputs to r0 and r1.
1569 (set (reg:HI 0) (match_operand:HI 1 "register_operand" ""))
1570 (set (reg:HI 1) (match_operand:HI 2 "register_operand" ""))
1571 ; Make the function call - note that r12 (link) is clobbered. Note also
1572 ; that an explicit call is generated. This ensures that gcc notices that
1573 ; any function containing a div/mod is not a leaf function.
1574 (parallel [(match_dup 4)
1575 (set (reg:HI 0) (div:HI (reg:HI 0) (reg:HI 1)))
1576 (set (reg:HI 1) (mod:HI (reg:HI 0) (reg:HI 1)))
1577 (clobber (reg:HI 2))
1578 (clobber (reg:HI 3))
1579 (clobber (reg:HI 4))
1580 (clobber (reg:HI 5))
1581 (clobber (reg:HI 12))
1582 (clobber (reg:CC CC_REGNUM))
1583 ])
1584 ; Set the quotient (returned in register 0)
1585 (set (match_operand:HI 0 "register_operand" "") (reg:HI 0))
1586 ; Set the remainder (returned in register 1)
1587 (set (match_operand:HI 3 "register_operand" "") (reg:HI 1))]
1588 ""
1589 {
1590 rtx fnName = gen_rtx_SYMBOL_REF (HImode, "_divmodhi4");
1591 operands[4] = gen_call_for_divmod (gen_rtx_MEM (QImode, fnName), GEN_INT(0));
1592 })
1593
1594 ; Match a call to divmodhi4. As this is a call, the link register
1595 ; (r12), and registers r0-5 must be clobbered. Ignore clobbering of
1596 ; r13/4 as these aren't used by the divide function).
1597 (define_insn "*divmodhi4_call"
1598 [(call (mem:QI (match_operand:HI 0 "immediate_operand" "i"))
1599 (match_operand 1 "const_int_operand" ""))
1600 (set (reg:HI 0) (div:HI (reg:HI 0) (reg:HI 1)))
1601 (set (reg:HI 1) (mod:HI (reg:HI 0) (reg:HI 1)))
1602 (clobber (reg:HI 2))
1603 (clobber (reg:HI 3))
1604 (clobber (reg:HI 4))
1605 (clobber (reg:HI 5))
1606 (clobber (reg:HI 12))
1607 (clobber (reg:CC CC_REGNUM))
1608 ]
1609 ""
1610 "JL (%0)\t// call %0%>"
1611 [(set_attr "length" "4")
1612 (set_attr "longConstant" "true")
1613 (set_attr "type" "call")])
1614
1615 ;; Perform a udivmod operation as a function call. This results in some
1616 ;; registers being clobbered (r0-6, r12 - ignore r13,14 as these are
1617 ;; known not to be affected).
1618 (define_expand "udivmodhi4"
1619 [
1620 ; Copy the inputs to r0 and r1.
1621 (set (reg:HI 0) (match_operand:HI 1 "register_operand" ""))
1622 (set (reg:HI 1) (match_operand:HI 2 "register_operand" ""))
1623 ; Make the function call - note that r12 (link) is clobbered. Note also
1624 ; that an explicit call is generated. This ensures that gcc notices that
1625 ; any function containing a div/mod is not a leaf function.
1626 (parallel [(match_dup 4)
1627 (set (reg:HI 0) (udiv:HI (reg:HI 0) (reg:HI 1)))
1628 (set (reg:HI 1) (umod:HI (reg:HI 0) (reg:HI 1)))
1629 (clobber (reg:HI 2))
1630 (clobber (reg:HI 3))
1631 (clobber (reg:HI 4))
1632 (clobber (reg:HI 5))
1633 (clobber (reg:HI 12))
1634 (clobber (reg:CC CC_REGNUM))
1635 ])
1636 ; Set the quotient (returned in register 0)
1637 (set (match_operand:HI 0 "register_operand" "") (reg:HI 0))
1638 ; Set the remainder (returned in register 1)
1639 (set (match_operand:HI 3 "register_operand" "") (reg:HI 1))]
1640 ""
1641 {
1642 rtx fnName = gen_rtx_SYMBOL_REF (HImode, "_udivmodhi4");
1643 operands[4] = gen_call_for_divmod (gen_rtx_MEM (QImode, fnName), GEN_INT(0));
1644 })
1645
1646 ; Match a call to udivmodhi4. As this is a call, the link register
1647 ; (r12), and registers r0-5 must be clobbered. Ignore clobbering of
1648 ; r13/4 as these aren't used by the divide function).
1649 (define_insn "*udivmodhi4_call"
1650 [(call (mem:QI (match_operand:HI 0 "immediate_operand" "i"))
1651 (match_operand 1 "const_int_operand" ""))
1652 (set (reg:HI 0) (udiv:HI (reg:HI 0) (reg:HI 1)))
1653 (set (reg:HI 1) (umod:HI (reg:HI 0) (reg:HI 1)))
1654 (clobber (reg:HI 2))
1655 (clobber (reg:HI 3))
1656 (clobber (reg:HI 4))
1657 (clobber (reg:HI 5))
1658 (clobber (reg:HI 12))
1659 (clobber (reg:CC CC_REGNUM))]
1660 ""
1661 "JL (%0)\t// call %0%>"
1662 [(set_attr "length" "4")
1663 (set_attr "longConstant" "true")
1664 (set_attr "type" "call")])
1665
1666 (define_expand "udivmodsi4"
1667 [
1668 ; Make the function call
1669 (set (reg:SI 0) (match_operand:SI 1 "register_operand" ""))
1670 (set (reg:SI 2) (match_operand:SI 2 "register_operand" ""))
1671 (parallel [
1672 (match_dup 4)
1673 (set (reg:SI 4) (udiv:SI (reg:SI 0) (reg:SI 2)))
1674 (set (reg:SI 6) (umod:SI (reg:SI 0) (reg:SI 2)))
1675 (clobber (reg:SI 0))
1676 (clobber (reg:SI 2))
1677 (clobber (reg:HI 12))
1678 (clobber (reg:CC CC_REGNUM))])
1679 (set (match_operand:SI 0 "register_operand" "") (reg:SI 4))
1680 (set (match_operand:SI 3 "register_operand" "") (reg:SI 6))]
1681 ""
1682 {
1683 rtx fnName = gen_rtx_SYMBOL_REF (HImode, "_udivmodsi4");
1684 operands[4] = gen_call_for_divmod (gen_rtx_MEM (QImode, fnName), GEN_INT(0));
1685 })
1686
1687 (define_insn "*udivmodsi4_call"
1688 [(call (mem:QI (match_operand:HI 0 "immediate_operand" "i"))
1689 (match_operand 1 "const_int_operand" ""))
1690 (set (reg:SI 4) (udiv:SI (reg:SI 0) (reg:SI 2)))
1691 (set (reg:SI 6) (umod:SI (reg:SI 0) (reg:SI 2)))
1692 (clobber (reg:SI 0))
1693 (clobber (reg:SI 2))
1694 (clobber (reg:HI 12))
1695 (clobber (reg:CC CC_REGNUM))]
1696 ""
1697 "JL (%0)\t// call %0%>"
1698 [(set_attr "length" "4")
1699 (set_attr "longConstant" "true")
1700 (set_attr "type" "call")])
1701
1702 (define_expand "divmodsi4"
1703 [
1704 ; Make the function call
1705 (set (reg:SI 0) (match_operand:SI 1 "register_operand" ""))
1706 (set (reg:SI 2) (match_operand:SI 2 "register_operand" ""))
1707 (parallel [
1708 (match_dup 4)
1709 (set (reg:SI 4) (div:SI (reg:SI 0) (reg:SI 2)))
1710 (set (reg:SI 6) (mod:SI (reg:SI 0) (reg:SI 2)))
1711 (clobber (reg:SI 0))
1712 (clobber (reg:SI 2))
1713 (clobber (reg:HI 12))
1714 (clobber (reg:CC CC_REGNUM))])
1715 (set (match_operand:SI 0 "register_operand" "") (reg:SI 4))
1716 (set (match_operand:SI 3 "register_operand" "") (reg:SI 6))]
1717 ""
1718 {
1719 rtx fnName = gen_rtx_SYMBOL_REF (HImode, "_divmodsi4");
1720 operands[4] = gen_call_for_divmod (gen_rtx_MEM (QImode, fnName), GEN_INT(0));
1721 })
1722
1723 (define_insn "*divmodsi4_call"
1724 [(call (mem:QI (match_operand:HI 0 "immediate_operand" "i"))
1725 (match_operand 1 "const_int_operand" ""))
1726 (set (reg:SI 4) (div:SI (reg:SI 0) (reg:SI 2)))
1727 (set (reg:SI 6) (mod:SI (reg:SI 0) (reg:SI 2)))
1728 (clobber (reg:SI 0))
1729 (clobber (reg:SI 2))
1730 (clobber (reg:HI 12))
1731 (clobber (reg:CC CC_REGNUM))]
1732 ""
1733 "JL (%0)\t// call %0%>"
1734 [(set_attr "length" "4")
1735 (set_attr "longConstant" "true")
1736 (set_attr "type" "call")])
1737
1738 ;;===========================================================================
1739 ;; Bitwise AND. The QI/SI mode instructions are automatically
1740 ;; synthesised from the HI mode instruction.
1741 ;;===========================================================================
1742
1743 (define_insn "andhi3"
1744 [(set (match_operand:HI 0 "register_operand" "=r,r")
1745 (and:HI (match_operand:HI 1 "register_operand" "r,r")
1746 (match_operand:HI 2 "general_operand" "r,n")))
1747 (clobber (reg:CC CC_REGNUM))]
1748 ""
1749 "AND.%# %1,%2,%0 // %0 := %1 AND %2 (HI)"
1750 [(set_attr "type" "basicAlu,basicAlu")
1751 (set_attr "longConstant" "false,true")
1752 (set_attr "length" "3,5")])
1753
1754 ;; If we peepholed the compare instruction out, we need to make sure the
1755 ;; "and" goes in slot 0. This pattern is just to accomplish that.
1756
1757 (define_insn "andhi3_with_use_clause"
1758 [(set (match_operand:HI 0 "register_operand" "=r,r")
1759 (and:HI (match_operand:HI 1 "register_operand" "r,r")
1760 (match_operand:HI 2 "general_operand" "r,n")))
1761 (set (reg:CC CC_REGNUM)
1762 (match_operator:CC 3 "picochip_peephole_comparison_operator"
1763 [(const_int 0)
1764 (const_int 0)]))]
1765 ""
1766 "AND.0 %1,%2,%0 // %0 := %1 AND %2 (HI)"
1767 [(set_attr "type" "picoAlu,picoAlu")
1768 (set_attr "longConstant" "false,true")
1769 (set_attr "length" "3,5")])
1770
1771 ;;===========================================================================
1772 ;; Bitwise inclusive-OR. The QI mode instruction is automatically
1773 ;; synthesised from the HI mode instruction.
1774 ;;===========================================================================
1775
1776 (define_insn "iorhi3"
1777 [(set (match_operand:HI 0 "register_operand" "=r,r")
1778 (ior:HI (match_operand:HI 1 "register_operand" "r,r")
1779 (match_operand:HI 2 "register_operand" "r,n")))
1780 (clobber (reg:CC CC_REGNUM))]
1781 ""
1782 "OR.%# %1,%2,%0 // %0 := %1 IOR %2 (HI)"
1783 [(set_attr "type" "basicAlu,basicAlu")
1784 (set_attr "longConstant" "false,true")
1785 (set_attr "length" "3,5")])
1786
1787 (define_insn "iorhi3_with_use_clause"
1788 [(set (match_operand:HI 0 "register_operand" "=r,r")
1789 (ior:HI (match_operand:HI 1 "register_operand" "r,r")
1790 (match_operand:HI 2 "general_operand" "r,n")))
1791 (set (reg:CC CC_REGNUM)
1792 (match_operator:CC 3 "picochip_peephole_comparison_operator"
1793 [(const_int 0)
1794 (const_int 0)]))]
1795 ""
1796 "OR.0 %1,%2,%0 // %0 := %1 IOR %2 (HI)"
1797 [(set_attr "type" "picoAlu,picoAlu")
1798 (set_attr "longConstant" "false,true")
1799 (set_attr "length" "3,5")])
1800
1801 ;;===========================================================================
1802 ;; Bitwise exclusive-OR. The QI/SI mode instructions are automatically
1803 ;; synthesised from the HI mode instruction.
1804 ;;===========================================================================
1805
1806 (define_insn "xorhi3"
1807 [(set (match_operand:HI 0 "register_operand" "=r,r")
1808 (xor:HI (match_operand:HI 1 "register_operand" "r,r")
1809 (match_operand:HI 2 "picochip_register_or_immediate_operand" "r,n")))
1810 (clobber (reg:CC CC_REGNUM))]
1811 ""
1812 "XOR.%# %1,%2,%0 // %0 := %1 XOR %2 (HI)"
1813 [(set_attr "type" "basicAlu,basicAlu")
1814 (set_attr "longConstant" "false,true")
1815 (set_attr "length" "3,5")])
1816
1817 ;;===========================================================================
1818 ;; Arithmetic shift left.
1819 ;;===========================================================================
1820
1821 (define_insn "ashlhi3"
1822 [(set (match_operand:HI 0 "register_operand" "=r,r")
1823 (ashift:HI (match_operand:HI 1 "register_operand" "r,r")
1824 (match_operand:HI 2 "general_operand" "r,J")))]
1825 ""
1826 "LSL.%# %1,%2,%0 // %0 := %1 << %2"
1827 [(set_attr "type" "picoAlu,basicAlu")
1828 (set_attr "length" "3,3")])
1829
1830 ;;===========================================================================
1831 ;; Arithmetic shift right.
1832 ;;===========================================================================
1833
1834 (define_insn "builtin_asri"
1835 [(set (match_operand:HI 0 "register_operand" "=r")
1836 (ashiftrt:HI (match_operand:HI 1 "register_operand" "r")
1837 (match_operand:HI 2 "immediate_operand" "")))
1838 (clobber (reg:CC CC_REGNUM))]
1839 ""
1840 "ASR.%# %1,%2,%0\t// %0 = %1 >>{arith} %2"
1841 [(set_attr "type" "basicAlu")
1842 (set_attr "length" "3")])
1843
1844 ;; The picoChip ISA doesn't have a variable arithmetic shift right, so
1845 ;; synthesise it. Shifts by constants are directly supported.
1846
1847 (define_expand "ashrhi3"
1848 [(match_operand:HI 0 "register_operand" "")
1849 (match_operand:HI 1 "register_operand" "")
1850 (match_operand:HI 2 "picochip_register_or_immediate_operand" "")]
1851 ""
1852 {
1853 if (GET_CODE(operands[2]) == CONST_INT)
1854 /* Shift by constant is easy. */
1855 emit_insn (gen_builtin_asri (operands[0], operands[1], operands[2]));
1856 else
1857 {
1858 /* Synthesise a variable shift. */
1859
1860 rtx tmp1;
1861 rtx tmp2;
1862 rtx tmp3;
1863 rtx minus_one;
1864 rtx tmp4;
1865
1866 /* Fill a temporary with the sign bits. */
1867 tmp1 = gen_reg_rtx (HImode);
1868 emit_insn (gen_builtin_asri (tmp1, operands[1], GEN_INT(15)));
1869
1870 /* Shift the unsigned value. */
1871 tmp2 = gen_reg_rtx (HImode);
1872 emit_insn (gen_lshrhi3 (tmp2, operands[1], operands[2]));
1873
1874 /* The word of sign bits must be shifted back to the left, to zero
1875 * out the unwanted lower bits. The amount to shift left by is (15 -
1876 * count). Since the shifts are computed modulo 16 (i.e., only the
1877 * lower 4 bits of the count are used), the shift amount (15 - count)
1878 * is equivalent to !count. */
1879 tmp3 = gen_reg_rtx (HImode);
1880 minus_one = GEN_INT (-1);
1881 emit_insn (gen_xorhi3 (tmp3, operands[2], minus_one));
1882 tmp4 = gen_reg_rtx (HImode);
1883 emit_insn (gen_ashlhi3 (tmp4, tmp1, tmp3));
1884
1885 /* Combine the sign bits with the shifted value. */
1886 emit_insn (gen_iorhi3 (operands[0], tmp2, tmp4));
1887
1888 }
1889 DONE;
1890 })
1891
1892 ;;===========================================================================
1893 ;; Logical shift right.
1894 ;;===========================================================================
1895
1896 (define_insn "lshrhi3"
1897 [(set (match_operand:HI 0 "register_operand" "=r,r")
1898 (lshiftrt:HI (match_operand:HI 1 "register_operand" "r,r")
1899 (match_operand:HI 2 "general_operand" "r,J")))]
1900 ""
1901 "LSR.%# %1,%2,%0 // %0 := %1 >> %2"
1902 [(set_attr "type" "picoAlu,basicAlu")
1903 (set_attr "length" "3,3")])
1904
1905 ;;===========================================================================
1906 ;; Negate.
1907 ;;===========================================================================
1908
1909 ;; Negations are performed by subtracting from the constant 0, which
1910 ;; is loaded into a register. By using a register containing 0, the
1911 ;; chances of being able to CSE with another 0 value are increased.
1912
1913 (define_expand "neghi2"
1914 [(set (match_dup 2) (match_dup 3))
1915 (parallel [(set (match_operand:HI 0 "register_operand" "=r")
1916 (minus:HI (match_dup 2)
1917 (match_operand:HI 1 "register_operand" "r")))
1918 (clobber (reg:CC CC_REGNUM))])]
1919 ""
1920 "operands[2] = gen_reg_rtx(HImode);
1921 operands[3] = GEN_INT(0x00000000);")
1922
1923 (define_expand "negsi2"
1924 [(set (match_dup 2) (match_dup 3))
1925 (parallel [(set (match_operand:SI 0 "register_operand" "=r")
1926 (minus:SI (match_dup 2)
1927 (match_operand:SI 1 "register_operand" "r")))
1928 (clobber (reg:CC CC_REGNUM))])]
1929 ""
1930 "operands[2] = gen_reg_rtx(SImode);
1931 operands[3] = GEN_INT(0x00000000);")
1932
1933 ;;===========================================================================
1934 ;; Absolute value. Taken from the Hacker's Delight, page 17. The second of the
1935 ;; four options given there produces the smallest, fastest code.
1936 ;;===========================================================================
1937
1938 (define_insn_and_split "abshi2"
1939 [(set (match_operand:HI 0 "register_operand" "")
1940 (abs:HI (match_operand:HI 1 "register_operand" "")))]
1941 ""
1942 "#"
1943 ""
1944 [(parallel [(set (match_dup 2)
1945 (plus:HI (ashiftrt:HI (match_dup 1) (const_int 15))
1946 (match_dup 1)))
1947 (clobber (reg:CC CC_REGNUM))])
1948 (parallel [(set (match_dup 0)
1949 (xor:HI (ashiftrt:HI (match_dup 1) (const_int 15))
1950 (match_dup 2)))
1951 (clobber (reg:CC CC_REGNUM))])]
1952 {
1953 operands[2] = gen_reg_rtx (HImode);
1954 })
1955
1956 ;;===========================================================================
1957 ;; Bitwise complement. Use auto-synthesised variant for SI mode. Though this
1958 ;; internally uses xor, the compiler doesnt automatically synthesize it using
1959 ;; xor, if this pattern was removed.
1960 ;;===========================================================================
1961
1962 (define_insn "one_cmplhi2"
1963 [(set (match_operand:HI 0 "register_operand" "=r")
1964 (not:HI (match_operand:HI 1 "register_operand" "0")))
1965 (clobber (reg:CC CC_REGNUM))]
1966 ""
1967 "XOR.%# %1,-1,%0 // %0 := ~%1"
1968 [(set_attr "type" "basicAlu")
1969 (set_attr "longConstant" "true")
1970 (set_attr "length" "5")])
1971
1972 ;;===========================================================================
1973 ;; Count leading zeros. The special sign-bit-count instruction can be used
1974 ;; to help us here.
1975 ;; op1:=clz(op1)
1976 ;; The code works by checking to see if the top bit is set. If it is,
1977 ;; then there are no leading zeros. If the top bit is cleared, then
1978 ;; the SBC instruction is used to determine how many more leading
1979 ;; zeros are present, and adding one more for the initial zero.
1980 ;;===========================================================================
1981
1982 (define_insn "clzhi2"
1983 [(set (match_operand:HI 0 "register_operand" "=&r")
1984 (clz:HI (match_operand:HI 1 "register_operand" "r")))]
1985 ""
1986 "// Count leading zeros\;SBC %1,%0\;ASR.0 %1,15,r15 %| ADD.1 %0,1,%0\;COPYNE 0,%0"
1987 [(set_attr "length" "11")])
1988
1989 ;;===========================================================================
1990 ;; Count trailing zeros. This can be achieved efficiently by reversing
1991 ;; using the bitrev instruction, and then counting the leading zeros as
1992 ;; described above.
1993 ;;===========================================================================
1994
1995 (define_insn "ctzhi2"
1996 [(set (match_operand:HI 0 "register_operand" "=&r")
1997 (ctz:HI (match_operand:HI 1 "register_operand" "r")))]
1998 ""
1999 "// Count trailing zeros\;BREV %1,%0\;SBC %0,%0\;AND.0 %1,0x0001,r15 %| ADD.1 %0,1,%0\;COPYNE 0,%0"
2000 [(set_attr "length" "15")])
2001
2002 ;;===========================================================================
2003 ;; Find the first set bit, starting from the least significant bit position.
2004 ;; This is very similar to the ctz function, except that the bit index is one
2005 ;; greater than the number of trailing zeros (i.e., SBC + 2), and the
2006 ;; result of ffs on the zero value is defined.
2007 ;;===========================================================================
2008
2009 (define_insn "ffshi2"
2010 [(set (match_operand:HI 0 "register_operand" "=&r")
2011 (ffs:HI (match_operand:HI 1 "register_operand" "r")))]
2012 ""
2013 "// First first bit\;BREV %1,%0\;SBC %0,%0\;AND.0 %1,0x0001,r15 %| ADD.1 %0,2,%0\;COPYNE 1,%0\;SUB.0 %1,0x0000,r15\;COPYEQ 0,%0"
2014 [(set_attr "length" "20")])
2015
2016 ;;===========================================================================
2017 ;; Tablejump Instruction. Jump to an absolute address.
2018 ;;===========================================================================
2019
2020 (define_insn "tablejump"
2021 [(set (pc) (unspec:HI [(match_operand:HI 0 "register_operand" "r")] 1))
2022 (use (label_ref (match_operand 1 "" "")))
2023 (clobber (match_dup 0))]
2024 ""
2025 "JR (%0)\t // Table jump to %0 %>"
2026 [(set_attr "length" "2")
2027 (set_attr "type" "realBranch")])
2028
2029 ;; Given the memory address of a QImode value, and a scratch register,
2030 ;; store the memory operand into the given output operand. The scratch
2031 ;; operand will not conflict with either of the operands. The other
2032 ;; two operands may conflict with each other.
2033
2034 (define_insn "synthesised_loadqi_unaligned"
2035 [(set (match_operand:QI 0 "register_operand" "=r")
2036 (match_operand:QI 1 "memory_operand" "m"))
2037 (clobber (match_operand:HI 2 "register_operand" "=&r"))
2038 (clobber (reg:CC CC_REGNUM))]
2039 ""
2040 "// Synthesised loadqi %0 = Mem(%1) (Scratch %2)\n\tAND.0 %1,-2,%2\n\tLDW (%2)0,%0 %| AND.0 %1,1,%2\n\tLSL.0 %2,3,%2\n\tSUB.0 8,%2,%2\n\tLSL.0 %0,%2,%0\n\tASR.0 %0,8,%0"
2041 ; Approximate length only. Probably a little shorter than this.
2042 [(set_attr "length" "40")])
2043
2044 ;; Given a memory operand whose alignment is known (the HImode aligned
2045 ;; base is operand 0, and the number of bits by which to shift is in
2046 ;; operand 5),
2047 (define_expand "synthesised_storeqi_aligned"
2048 [; s1 = mem_op
2049 (set (match_operand:HI 2 "register_operand" "")
2050 (match_operand:HI 0 "memory_operand" ""))
2051 ; s1 = s1 and mask
2052 (parallel [(set (match_dup 2) (and:HI (match_dup 2) (match_dup 5)))
2053 (clobber (reg:CC CC_REGNUM))])
2054 ; s2 = source << bitShift
2055 (set (match_dup 3)
2056 (ashift:HI (subreg:HI (match_operand:QI 1 "register_operand" "") 0)
2057 (match_operand:HI 4 "const_int_operand" "")))
2058 ; s1 = s1 or s2
2059 (parallel [(set (match_dup 2) (ior:HI (match_dup 2) (match_dup 3)))
2060 (clobber (reg:CC CC_REGNUM))])
2061 ; mem_op = s1
2062 (set (match_dup 0) (match_dup 2))]
2063 "!TARGET_HAS_BYTE_ACCESS"
2064 {
2065 /* Create the byte mask 0xFF00. */
2066 operands[5] = gen_int_mode(((~0xFF) >> INTVAL (operands[4])), HImode);
2067 })
2068
2069 ;; Reload instructions. See picochip_secondary_reload for an
2070 ;; explanation of why an SI mode register is used as a scratch. The
2071 ;; memory operand must be stored in a register (i.e., it can't be an
2072 ;; offset to another register - this would require another scratch
2073 ;; register into which the address of the offset could be computed).
2074
2075 (define_expand "reload_inqi"
2076 [(parallel [(match_operand:QI 0 "register_operand" "=&r")
2077 (match_operand:QI 1 "memory_operand" "m")
2078 (match_operand:SI 2 "register_operand" "=&r")])]
2079 "!TARGET_HAS_BYTE_ACCESS"
2080 {
2081 rtx scratch, seq;
2082
2083 /* Get the scratch register. Given an SI mode value, we have a
2084 choice of two HI mode scratch registers, so we can be sure that at
2085 least one of the scratch registers will be different to the output
2086 register, operand[0]. */
2087
2088 if (REGNO (operands[0]) == REGNO (operands[2]))
2089 scratch = gen_rtx_REG (HImode, REGNO (operands[2]) + 1);
2090 else
2091 scratch = gen_rtx_REG (HImode, REGNO (operands[2]));
2092
2093 /* Ensure that the scratch doesn't overlap either of the other
2094 two operands - however, the other two may overlap each
2095 other. */
2096 gcc_assert (REGNO(scratch) != REGNO(operands[0]));
2097 gcc_assert (REGNO(scratch) != REGNO(operands[1]));
2098
2099 gcc_assert (GET_CODE (operands[1]) == MEM);
2100
2101 if (picochip_word_aligned_memory_reference(XEXP(operands[1], 0)))
2102 {
2103 /* Aligned reloads are easy, since they can use word-loads. */
2104 seq = gen_synthesised_loadqi_aligned(operands[0], operands[1], scratch);
2105 }
2106 else
2107 {
2108 /* Emit the instruction using a define_insn. */
2109 seq = gen_synthesised_loadqi_unaligned(operands[0], operands[1], scratch);
2110 }
2111 emit_insn (seq);
2112
2113 DONE;
2114
2115 })
2116
2117 (define_expand "reload_outqi"
2118 [(parallel [(match_operand 0 "memory_operand" "=m")
2119 (match_operand:QI 1 "register_operand" "r")
2120 (match_operand:SI 2 "register_operand" "=&r")])]
2121 "!TARGET_HAS_BYTE_ACCESS"
2122 {
2123 rtx scratch1 = gen_rtx_REG(HImode, REGNO(operands[2]));
2124 rtx scratch2 = gen_rtx_REG(HImode, REGNO(operands[2]) + 1);
2125 rtx seq;
2126
2127 gcc_assert (GET_CODE (operands[0]) == MEM);
2128
2129 if (picochip_word_aligned_memory_reference(XEXP(operands[0], 0)))
2130 {
2131 rtx alignedAddr, bitShift;
2132
2133 /* Convert the address of the known alignment into two operands
2134 * representing the aligned base address, and the number of shift bits
2135 * required to access the required value. */
2136 picochip_get_hi_aligned_mem(operands[0], &alignedAddr, &bitShift);
2137
2138 /* Emit an aligned store of the source, with the given bit offset. */
2139 seq = gen_synthesised_storeqi_aligned(alignedAddr, operands[1], scratch1, scratch2, bitShift);
2140
2141 }
2142 else
2143 {
2144 /* This isnt exercised at all. Moreover, with new devices, byte access
2145 is available in all variants. */
2146 gcc_unreachable();
2147 }
2148
2149 emit_insn (seq);
2150 DONE;
2151
2152 })
2153
2154 ;; Perform a byte load of an alignable memory operand.
2155 ; op0 = register to load. op1 = memory operand from which to load
2156 ; op2 = op1, aligned to HI, op3 = const bit shift required to extract byte,
2157 ; op4 = INTVAL(8 - op3)
2158 (define_expand "synthesised_loadqi_aligned"
2159 [; Load memory operand into register
2160 (set (match_operand:HI 2 "register_operand" "=r")
2161 (match_dup 3))
2162 ; Shift required byte into top byte of word.
2163 (set (match_dup 2)
2164 (ashift:HI (match_dup 2)
2165 (match_dup 4)))
2166 ; Arithmetic shift of byte to sign extend, and move to lowest register.
2167 (parallel[(set (subreg:HI (match_dup 0) 0)
2168 (ashiftrt:HI (match_dup 2)
2169 (const_int 8)))
2170 (clobber (reg:CC CC_REGNUM))])
2171 (use (match_operand:QI 1 "picochip_alignable_memory_operand" "g"))]
2172 "!TARGET_HAS_BYTE_ACCESS"
2173 {
2174 rtx alignedAddr, bitShift;
2175
2176 /* Convert the address of the known alignment into two operands
2177 * representing the aligned base address, and the number of shift bits
2178 * required to access the required value. */
2179 picochip_get_hi_aligned_mem(operands[1], &alignedAddr, &bitShift);
2180
2181 operands[3] = alignedAddr;
2182 operands[4] = GEN_INT(8 - INTVAL(bitShift));
2183 })
2184
2185 ;;============================================================================
2186 ;; Special instructions.
2187 ;;============================================================================
2188
2189 ; Count sign-bits.
2190 (define_insn "sbc"
2191 [(set (match_operand:HI 0 "register_operand" "=r")
2192 (unspec:HI [(match_operand:HI 1 "register_operand" "r")]
2193 UNSPEC_SBC))]
2194 ""
2195 "SBC %1,%0\t\t// %0 := SBC(%1)"
2196 [(set_attr "type" "picoAlu")
2197 (set_attr "length" "2")])
2198
2199 ; Bit reversal.
2200 (define_insn "brev"
2201 [(set (match_operand:HI 0 "register_operand" "=r")
2202 (unspec:HI [(match_operand:HI 1 "register_operand" "r")]
2203 UNSPEC_BREV))]
2204 ""
2205 "BREV %1,%0\t\t// %0 := BREV(%1)"
2206 [(set_attr "length" "2")
2207 (set_attr "type" "picoAlu")])
2208
2209 ; Byte swap.
2210 (define_insn "bswaphi2"
2211 [(set (match_operand:HI 0 "register_operand" "=r")
2212 (bswap:HI (match_operand:HI 1 "register_operand" "r")))]
2213 ""
2214 "BYTESWAP %1,%0\t\t// %0 := ByteSwap(%1)"
2215 [(set_attr "length" "2")
2216 (set_attr "type" "picoAlu")])
2217
2218 ; Read status word.
2219 (define_insn "copysw"
2220 [(set (match_operand:HI 0 "register_operand" "=r")
2221 (unspec_volatile:HI [(reg:CC CC_REGNUM)] UNSPEC_COPYSW))]
2222 ""
2223 "COPYSW.%# %0\t// %0 := Flags"
2224 [(set_attr "type" "basicAlu")
2225 (set_attr "length" "2")])
2226
2227 ; Saturating addition.
2228 (define_insn "sataddhi3"
2229 [(set (match_operand:HI 0 "register_operand" "=r")
2230 (unspec:HI [(match_operand:HI 1 "register_operand" "r")
2231 (match_operand:HI 2 "register_operand" "r")]
2232 UNSPEC_ADDS))
2233 (clobber (reg:CC CC_REGNUM))]
2234 ""
2235 "ADDS %1,%2,%0\t// %0 := sat(%1 + %2)"
2236 [(set_attr "type" "picoAlu")
2237 (set_attr "length" "3")])
2238
2239 ; Saturating subtraction.
2240 (define_insn "satsubhi3"
2241 [(set (match_operand:HI 0 "register_operand" "=r")
2242 (unspec:HI [(match_operand:HI 1 "register_operand" "r")
2243 (match_operand:HI 2 "register_operand" "r")]
2244 UNSPEC_SUBS))
2245 (clobber (reg:CC CC_REGNUM))]
2246 ""
2247 "SUBS %1,%2,%0\t// %0 := sat(%1 - %2)"
2248 [(set_attr "type" "picoAlu")
2249 (set_attr "length" "3")])
2250
2251 (define_insn "halt"
2252 [(unspec_volatile [(match_operand:HI 0 "const_int_operand" "i")]
2253 UNSPEC_HALT)]
2254 ""
2255 "HALT\t// (id %0)"
2256 [(set_attr "length" "1")
2257 (set_attr "type" "unknown")])
2258
2259 (define_insn "internal_testport"
2260 [(set (reg:CC CC_REGNUM)
2261 (unspec_volatile:CC [(match_operand:HI 0 "const_int_operand" "i")]
2262 UNSPEC_INTERNAL_TESTPORT))]
2263 ""
2264 "TSTPORT %0"
2265 [(set_attr "length" "2")
2266 (set_attr "longConstant" "false")
2267 (set_attr "type" "picoAlu")])
2268
2269 ;;============================================================================
2270 ;; Communications builtins.
2271 ;;
2272 ;; Each builtin comes in two forms: a single port version, which maps
2273 ;; to a single instruction, and an array port version. The array port
2274 ;; version is treated as a special type of instruction, which is then
2275 ;; split into a number of smaller instructions, if the index of the
2276 ;; port can't be converted into a constant. When the RTL split is
2277 ;; performed, a function call is emitted, in which the index of the
2278 ;; port to use is used to compute the address of the function to call
2279 ;; (i.e., each array port is a function in its own right, and the
2280 ;; functions are stored as an array which is then indexed to determine
2281 ;; the correct function). The communication function port array is
2282 ;; created by the linker if and only if it is required (in a
2283 ;; collect2-like manner).
2284 ;;============================================================================
2285
2286 ; Simple scalar get.
2287 (define_insn "commsGet"
2288 [(set (match_operand:SI 0 "register_operand" "=r")
2289 (unspec_volatile:SI
2290 [(match_operand:HI 1 "immediate_operand" "n")]
2291 UNSPEC_GET))]
2292 ""
2293 "GET %1,%R0\t// %R0 := PORT(%1)"
2294 [(set_attr "type" "comms")
2295 (set_attr "length" "2")])
2296
2297 ; Entry point for array get (the actual port index is computed as the
2298 ; sum of the index, and the base).
2299 ;
2300 ; op0 - Destination
2301 ; op1 - Requested port index
2302 ; op2 - size of port array (constant)
2303 ; op3 - base index of port array (constant)
2304
2305 (define_expand "commsArrayGet"
2306 [(parallel
2307 [(set (reg:SI 0)
2308 (unspec_volatile:SI [(match_operand:HI 1 "general_operand" "")
2309 (match_operand:HI 2 "immediate_operand" "")
2310 (match_operand:HI 3 "immediate_operand" "")]
2311 UNSPEC_CALL_GET_ARRAY))
2312 (clobber (reg:HI LINK_REGNUM))])
2313 (set (match_operand:SI 0 "register_operand" "") (reg:SI 0))]
2314 ""
2315 "")
2316
2317 ;; The actual array get instruction. When the array index is a constant,
2318 ;; an exact instruction may be generated. When the index is variable,
2319 ;; a call to a special function is generated. This code could be
2320 ;; split into individual RTL instructions, but it is so rarely
2321 ;; used, that we won't bother.
2322 (define_insn "*commsArrayGetInstruction"
2323 [(set (reg:SI 0)
2324 (unspec_volatile:SI [(match_operand:HI 0 "general_operand" "r,i")
2325 (match_operand:HI 1 "immediate_operand" "")
2326 (match_operand:HI 2 "immediate_operand" "")]
2327 UNSPEC_CALL_GET_ARRAY))
2328 (clobber (reg:HI LINK_REGNUM))]
2329 ""
2330 {
2331 return picochip_output_get_array (which_alternative, operands);
2332 })
2333
2334 ; Scalar Put instruction.
2335 (define_insn "commsPut"
2336 [(unspec_volatile [(match_operand:HI 0 "const_int_operand" "")
2337 (match_operand:SI 1 "register_operand" "r")]
2338 UNSPEC_PUT)]
2339 ""
2340 "PUT %R1,%0\t// PORT(%0) := %R1"
2341 [(set_attr "type" "comms")
2342 (set_attr "length" "2")])
2343
2344 ; Entry point for array put. The operands accepted are:
2345 ; op0 - Value to put
2346 ; op1 - Requested port index
2347 ; op2 - size of port array
2348 ; op3 - base index of port array
2349 ; The arguments are marshalled into the fixed registers, so that
2350 ; the actual put instruction can expand into a call if necessary
2351 ; (e.g., if the index is variable at run-time).
2352
2353 (define_expand "commsArrayPut"
2354 [(set (reg:SI 0) (match_operand:SI 0 "general_operand" ""))
2355 (parallel
2356 [(unspec_volatile [(match_operand:HI 1 "general_operand" "")
2357 (match_operand:HI 2 "immediate_operand" "")
2358 (match_operand:HI 3 "immediate_operand" "")]
2359 UNSPEC_CALL_PUT_ARRAY)
2360 (use (reg:SI 0))
2361 (clobber (reg:HI LINK_REGNUM))])]
2362 ""
2363 "")
2364
2365 ;; The actual array put instruction. When the array index is a constant,
2366 ;; an exact instruction may be generated. When the index is variable,
2367 ;; a call to a special function is generated. This code could be
2368 ;; split into individual RTL instructions, but it is so rarely
2369 ;; used, that we won't bother.
2370 (define_insn "*commsArrayPutInstruction"
2371 [(unspec_volatile [(match_operand:HI 0 "general_operand" "r,i")
2372 (match_operand:HI 1 "immediate_operand" "")
2373 (match_operand:HI 2 "immediate_operand" "")]
2374 UNSPEC_CALL_PUT_ARRAY)
2375 (use (reg:SI 0))
2376 (clobber (reg:HI LINK_REGNUM))]
2377 ""
2378 {
2379 return picochip_output_put_array (which_alternative, operands);
2380 })
2381
2382 ;; Scalar test port instruction.
2383 (define_insn "commsTestPort"
2384 [(set (match_operand:HI 0 "register_operand" "=r")
2385 (unspec_volatile:HI [(match_operand:HI 1 "const_int_operand" "")]
2386 UNSPEC_TESTPORT))
2387 (clobber (reg:CC CC_REGNUM))]
2388 ""
2389 "// %0 := TestPort(%1)\;COPY.1 0,%0 %| TSTPORT %1\;COPYEQ 1,%0"
2390 [(set_attr "length" "9")])
2391
2392 ; Entry point for array tstport (the actual port index is computed as the
2393 ; sum of the index, and the base).
2394 ;
2395 ; op0 - Test value.
2396 ; op1 - Requested port index
2397 ; op2 - size of port array (constant)
2398 ; op3 - base index of port array (constant)
2399
2400 (define_expand "commsArrayTestPort"
2401 [(parallel
2402 [(set (match_operand:HI 0 "register_operand" "")
2403 (unspec_volatile:HI [(match_operand:HI 1 "general_operand" "")
2404 (match_operand:HI 2 "immediate_operand" "")
2405 (match_operand:HI 3 "immediate_operand" "")]
2406 UNSPEC_CALL_TESTPORT_ARRAY))
2407 (clobber (reg:HI LINK_REGNUM))])]
2408 ""
2409 "")
2410
2411 ;; The actual array testport instruction. When the array index is a constant,
2412 ;; an exact instruction may be generated. When the index is variable,
2413 ;; a call to a special function is generated. This code could be
2414 ;; split into individual RTL instructions, but it is so rarely
2415 ;; used, that we won't bother.
2416 (define_insn "*commsArrayTestportInstruction"
2417 [(set (match_operand:HI 0 "register_operand" "=r,r")
2418 (unspec_volatile:HI [(match_operand:HI 1 "general_operand" "r,i")
2419 (match_operand:HI 2 "immediate_operand" "")
2420 (match_operand:HI 3 "immediate_operand" "")]
2421 UNSPEC_CALL_TESTPORT_ARRAY))
2422 (clobber (reg:HI LINK_REGNUM))]
2423 ""
2424 {
2425 return picochip_output_testport_array (which_alternative, operands);
2426 })
2427
2428 ;; Merge a TSTPORT instruction with the branch to which it
2429 ;; relates. Often the TSTPORT function (generated by a built-in), is
2430 ;; used to control conditional execution. The normal sequence of
2431 ;; instructions would be:
2432 ;; TSTPORT p
2433 ;; COPYSW temp
2434 ;; AND temp, 0x0008, temp
2435 ;; SUB temp,0,discard
2436 ;; BEQ label
2437 ;; This can be made more efficient by detecting the special case where
2438 ;; the result of a TSTPORT is used to branch, to allow the following
2439 ;; RTL sequence to be generated instead:
2440 ;; TSTPORT p
2441 ;; BEQ label
2442 ;; A big saving in cycles and bytes!
2443
2444 (define_insn_and_split "tstport_branch"
2445 [(set (pc)
2446 (if_then_else
2447 (match_operator 0 "comparison_operator"
2448 [(unspec_volatile:HI
2449 [(match_operand:HI 1 "const_int_operand" "")]
2450 UNSPEC_TESTPORT)
2451 (const_int 0)])
2452 (label_ref (match_operand 2 "" ""))
2453 (pc)))
2454 (clobber (reg:CC CC_REGNUM))]
2455 ""
2456 "#"
2457 ""
2458 [(set (reg:CC CC_REGNUM)
2459 (unspec_volatile:CC [(match_dup 1)] UNSPEC_INTERNAL_TESTPORT))
2460 (parallel [(set (pc)
2461 (if_then_else
2462 (match_op_dup:HI 4 [(reg:CC CC_REGNUM) (const_int 0)])
2463 (label_ref (match_dup 2))
2464 (pc)))
2465 (use (match_dup 3))])]
2466 "{
2467 /* Note that the sense of the branch is reversed, since we are
2468 * comparing flag != 0. */
2469 gcc_assert (GET_CODE(operands[0]) == NE || GET_CODE(operands[0]) == EQ);
2470 operands[4] = gen_rtx_fmt_ee(reverse_condition(GET_CODE(operands[0])),
2471 GET_MODE(operands[0]), XEXP(operands[0], 0), XEXP(operands[0], 1));
2472 operands[3] = GEN_INT (0);
2473 }")
2474
2475 ;;============================================================================
2476 ;; Epilogue/Epilogue expansion.
2477 ;;============================================================================
2478
2479 (define_expand "prologue"
2480 [(clobber (const_int 0))]
2481 ""
2482 {
2483 picochip_expand_prologue ();
2484 DONE;
2485 })
2486
2487 (define_expand "epilogue"
2488 [(use (const_int 0))]
2489 ""
2490 {
2491 picochip_expand_epilogue (FALSE);
2492 DONE;
2493 })
2494
2495 ;;============================================================================
2496 ;; Trap instruction. This is used to indicate an error. For the
2497 ;; picoChip processors this is handled by calling a HALT instruction,
2498 ;; which stops the processor.
2499 ;;============================================================================
2500
2501 (define_insn "trap"
2502 [(trap_if (const_int 1) (const_int 6))]
2503 ""
2504 "HALT\t// (Trap)"
2505 [(set_attr "length" "2")])
2506
2507 ;;============================================================================
2508 ;; Conditional copy instructions. Only equal/not-equal comparisons are
2509 ;; supported. All other types of comparison remain as branch
2510 ;; sequences.
2511 ;;============================================================================
2512
2513 ;; Define expand seems to consider the resulting two instructions to be
2514 ;; independent. With a split, guarded by reload, it works correctly.
2515 (define_expand "movhicc"
2516 [(set (match_operand:HI 0 "register_operand" "=r,r")
2517 (if_then_else:HI (match_operand:HI 1 "" "")
2518 (match_operand:HI 2 "register_operand" "0,0")
2519 (match_operand:HI 3 "picochip_register_or_immediate_operand" "r,i")))]
2520 ""
2521 {if (!picochip_check_conditional_copy (operands))
2522 FAIL;
2523 })
2524
2525 (define_insn_and_split "*checked_movhicc"
2526 [(set (match_operand:HI 0 "register_operand" "=r,r")
2527 (if_then_else:HI (match_operator 1 "picochip_peephole_comparison_operator"
2528 [(match_operand:HI 4 "register_operand" "r,r")
2529 (match_operand:HI 5 "picochip_comparison_operand" "r,i")])
2530 (match_operand:HI 2 "register_operand" "0,0")
2531 (match_operand:HI 3 "picochip_register_or_immediate_operand" "r,i")))]
2532 ""
2533 "#"
2534 "reload_completed"
2535 [(set (reg:CC CC_REGNUM) (match_dup 1))
2536 (parallel [(set (match_operand:HI 0 "register_operand" "=r,r")
2537 (if_then_else:HI (match_op_dup:HI 1 [(reg:CC CC_REGNUM) (const_int 0)])
2538 (match_operand:HI 2 "picochip_register_or_immediate_operand" "0,0")
2539 (match_operand:HI 3 "picochip_register_or_immediate_operand" "r,i")))
2540 (use (match_dup 6))])]
2541 "{
2542 operands[6] = GEN_INT(GET_CODE(operands[0]));
2543 }")
2544
2545 ;; We dont do any checks here. But this pattern is used only when movhicc
2546 ;; was checked. Put a "use" clause to make sure.
2547 (define_insn "*conditional_copy"
2548 [(set (match_operand:HI 0 "register_operand" "=r,r")
2549 (if_then_else:HI
2550 (match_operator:HI 4 "picochip_peephole_comparison_operator"
2551 [(reg:CC CC_REGNUM) (const_int 0)])
2552 (match_operand:HI 1 "register_operand" "0,0")
2553 (match_operand:HI 2 "picochip_register_or_immediate_operand" "r,i")))
2554 (use (match_operand:HI 3 "const_int_operand" ""))]
2555 ""
2556 {
2557
2558 gcc_assert (GET_CODE(operands[4]) == EQ || GET_CODE(operands[4]) == NE);
2559 /* Note that the comparison is reversed as the pattern matches
2560 the *else* part of the if_then_else */
2561 switch (GET_CODE(operands[4]))
2562 {
2563 case EQ: return "COPYNE %2,%0\t// if (NE) %0 := %2";
2564 case NE: return "COPYEQ %2,%0\t// if (EQ) %0 := %2";
2565 default:
2566 gcc_unreachable();
2567 }
2568 }
2569 [(set_attr "length" "2")
2570 (set_attr "type" "picoAlu,picoAlu")
2571 (set_attr "longConstant" "false,true")])
2572
2573 ;;============================================================================
2574 ;; Scheduling, including delay slot scheduling.
2575 ;;============================================================================
2576
2577 (automata_option "v")
2578 (automata_option "ndfa")
2579
2580 ;; Define each VLIW slot as a CPU resource. Note the three flavours of
2581 ;; branch. `realBranch' is an actual branch instruction. `macroBranch'
2582 ;; is a directive to the assembler, which may expand into multiple
2583 ;; instructions. `call' is an actual branch instruction, but one which
2584 ;; sets the link register, and hence can't be scheduled alongside
2585 ;; other instructions which set the link register. When the DFA
2586 ;; scheduler is fixed to prevent it scheduling a JL with an R12
2587 ;; setting register, the call type branches can be replaced by
2588 ;; realBranch types instead.
2589
2590 (define_attr "type"
2591 "picoAlu,basicAlu,nonCcAlu,mem,call,realBranch,macroBranch,mul,mac,app,comms,unknown"
2592 (const_string "unknown"))
2593
2594 (define_attr "schedType" "none,space,speed"
2595 (const (symbol_ref "(enum attr_schedType) picochip_schedule_type")))
2596
2597 ;; Define whether an instruction uses a long constant.
2598
2599 (define_attr "longConstant"
2600 "true,false" (const_string "false"))
2601
2602 ;; Define three EU slots.
2603 (define_query_cpu_unit "slot0,slot1,slot2")
2604
2605 ;; Pull in the pipeline descriptions for speed or space scheduling.
2606 (include "dfa_speed.md")
2607 (include "dfa_space.md")
2608
2609 ; Unknown instructions are assumed to take a single cycle, and use all
2610 ; slots. This enables them to actually output a sequence of
2611 ; instructions without any limitation. For the purposes of
2612 ; scheduling, unknown instructions are a pain, and should be removed
2613 ; completely. This means that RTL patterns should always be used to
2614 ; reduce complex sequences of instructions to individual instructions.
2615 (define_insn_reservation "unknownInsn" 1
2616 (eq_attr "type" "unknown")
2617 "(slot0+slot1+slot2)")
2618
2619 ; Allow any non-branch instructions to be placed in the branch
2620 ; slot. Branch slots are always executed.
2621 (define_delay (eq_attr "type" "realBranch,call")
2622 [(eq_attr "type" "!realBranch,macroBranch,call,unknown") (nil) (nil)])
This page took 0.157114 seconds and 5 git commands to generate.