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