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