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)
7 ;; This file is part of GCC.
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)
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.
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/>.
23 ;; -------------------------------------------------------------------------
25 ;; In addition to the normal output operand formats, the following
26 ;; letter formats are also available:
28 ;; The following can be used for constants, or the constant part of a
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)
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.
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
45 ;; The following are used on DI mode registers.
46 ;; X - Output 3rd register
47 ;; Y - Output 4th register
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)
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))
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.
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.
74 ;; Define identifiers for various special instructions. These
75 ;; instructions may then be used in RTL expansions, or builtins.
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
84 ; Special internal instructions (only used by compiler)
85 (UNSPEC_COPYSW 5) ; Get status word
86 (UNSPEC_ADDC 6) ; Add with carry.
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]
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
99 ;; Array port expansions
100 (UNSPEC_CALL_GET_ARRAY 13) ;
101 (UNSPEC_CALL_PUT_ARRAY 14) ;
102 (UNSPEC_CALL_TESTPORT_ARRAY 15) ;
104 ; Array port low-level fn calls
105 (UNSPEC_CALL_GET_FN 16)
106 (UNSPEC_CALL_TESTPORT_FN 17)
111 ; Internal TSTPORT instruction, used to generate a single TSTPORT
112 ; instruction for use in the testport branch split.
113 (UNSPEC_INTERNAL_TESTPORT 19)
120 (LINK_REGNUM 12) ; Function link register.
121 (CC_REGNUM 17) ; Condition flags.
122 (ACC_REGNUM 16) ; Condition flags.
126 ;;============================================================================
127 ;; Predicates and constraints
128 ;;============================================================================
130 (include "predicates.md")
131 (include "constraints.md")
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.
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
143 ;;============================================================================
145 (define_insn "*firstOpGenericAshift"
146 [(set (match_operand:HI 0 "register_operand" "=r")
147 (match_operator:HI 1 "picochip_first_op_shift_operator"
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))]
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")))])
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.
170 (define_insn "*firstOpGenericAshift"
171 [(set (match_operand:HI 0 "register_operand" "=r")
172 (match_operator:HI 1 "picochip_first_op_shift_operator"
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))]
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")))])
192 (define_insn "*firstOpGenericAshiftrt"
193 [(set (match_operand:HI 0 "register_operand" "=r")
194 (match_operator:HI 1 "picochip_first_op_shift_operator"
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))]
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")))])
214 (define_insn "*firstOpGenericLshiftrt"
215 [(set (match_operand:HI 0 "register_operand" "=r")
216 (match_operator:HI 1 "picochip_first_op_shift_operator"
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))]
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")))])
236 ;;===========================================================================
237 ;; Jump instructions.
238 ;;===========================================================================
240 (define_insn "indirect_jump"
241 [(set (pc) (match_operand:HI 0 "register_operand" "r"))]
243 "JR (%0)\t// Indirect_jump to %0 %>"
244 [(set_attr "type" "realBranch")
245 (set_attr "length" "3")])
249 (label_ref (match_operand 0 "" "")))]
251 "* return picochip_output_jump(insn);"
252 [(set (attr "length")
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)))
260 (eq_attr "length" "6")
261 (const_string "realBranch")
262 (const_string "unknown")))])
264 (define_insn "*fn_return"
266 (use (reg:HI LINK_REGNUM))]
268 "JR (R12)\t// Return to caller %>"
269 [(set_attr "length" "2")
270 (set_attr "type" "realBranch")
271 (set_attr "longConstant" "false")])
273 ;; Peephole either 2 LDWs or STWs into LDL/STL.
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))]
282 operands[4] = gen_min_reg(operands[0],operands[2]);
283 operands[5] = gen_SImode_mem(operands[1],operands[3]);
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))]
294 operands[4] = gen_SImode_mem(operands[0],operands[2]);
295 operands[5] = gen_min_reg(operands[1],operands[3]);
299 ;; We have instructions like add,subtract,ior,and that set condition
300 ;; codes if they are executed on slot 0. If we have
304 ;; We would have RTL sequence like
305 ;; add.# rb,rc,ra # will be replaced by slot no, after scheduling
308 ;; Instead, we can just do
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))])
319 (match_operator:CC 3 "picochip_peephole_comparison_operator"
320 [(match_dup 0) (const_int 0)])
321 (label_ref (match_operand 6 "" ""))
323 (clobber (reg:CC CC_REGNUM))])]
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)]))])
331 (match_op_dup:HI 3 [(reg:CC CC_REGNUM) (const_int 0)])
332 (label_ref (match_dup 6))
334 (use (match_dup 7))])]
336 operands[7] = GEN_INT(0);
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)]))
349 (match_operator 4 "comparison_operator"
350 [(reg:CC CC_REGNUM) (const_int 0)])
351 (label_ref (match_operand 5 "" ""))
353 (use (match_operand:HI 6 "const_int_operand" ""))])]
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)]))])
360 (if_then_else (match_op_dup:HI 4 [(reg:CC CC_REGNUM) (const_int 0)])
361 (label_ref (match_dup 5))
363 (use (match_dup 6))])]
365 operands[7] = GEN_INT(0);
369 ;; If peephole happens before the cbranch split
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))])
378 (match_operator:CC 3 "picochip_peephole_comparison_operator"
379 [(match_dup 0) (const_int 0)])
380 (label_ref (match_operand 6 "" ""))
382 (clobber (reg:CC CC_REGNUM))])]
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)]))])
390 (match_op_dup:HI 3 [(reg:CC CC_REGNUM) (const_int 0)])
391 (label_ref (match_dup 6))
393 (use (match_dup 7))])]
395 operands[7] = GEN_INT(0);
399 ;; If peephole happens after the cbranch split
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)]))
411 (match_operator 4 "comparison_operator"
412 [(reg:CC CC_REGNUM) (const_int 0)])
413 (label_ref (match_operand 5 "" ""))
415 (use (match_operand:HI 6 "const_int_operand" ""))])]
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)]))])
422 (if_then_else (match_op_dup:HI 4 [(reg:CC CC_REGNUM) (const_int 0)])
423 (label_ref (match_dup 5))
425 (use (match_dup 6))])]
427 operands[7] = GEN_INT(0);
430 ;; If peephole happens before the cbranch split
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))])
439 (match_operator:CC 3 "picochip_peephole_comparison_operator"
440 [(match_dup 0) (const_int 0)])
441 (label_ref (match_operand 6 "" ""))
443 (clobber (reg:CC CC_REGNUM))])]
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)]))])
451 (match_op_dup:HI 3 [(reg:CC CC_REGNUM) (const_int 0)])
452 (label_ref (match_dup 6))
454 (use (match_dup 7))])]
456 operands[7] = GEN_INT(0);
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)]))
469 (match_operator 4 "comparison_operator"
470 [(reg:CC CC_REGNUM) (const_int 0)])
471 (label_ref (match_operand 5 "" ""))
473 (use (match_operand:HI 6 "const_int_operand" ""))])]
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)]))])
480 (if_then_else (match_op_dup:HI 4 [(reg:CC CC_REGNUM) (const_int 0)])
481 (label_ref (match_dup 5))
483 (use (match_dup 6))])]
485 operands[7] = GEN_INT(0);
488 ;; If peephole happens before the cbranch split
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))])
497 (match_operator:CC 3 "picochip_peephole_comparison_operator"
498 [(match_dup 0) (const_int 0)])
499 (label_ref (match_operand 6 "" ""))
501 (clobber (reg:CC CC_REGNUM))])]
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)]))])
509 (match_op_dup:HI 3 [(reg:CC CC_REGNUM) (const_int 0)])
510 (label_ref (match_dup 6))
512 (use (match_dup 7))])]
514 operands[7] = GEN_INT(0);
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)]))
527 (match_operator 4 "comparison_operator"
528 [(reg:CC CC_REGNUM) (const_int 0)])
529 (label_ref (match_operand 5 "" ""))
531 (use (match_operand:HI 6 "const_int_operand" ""))])]
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)]))])
538 (if_then_else (match_op_dup:HI 4 [(reg:CC CC_REGNUM) (const_int 0)])
539 (label_ref (match_dup 5))
541 (use (match_dup 6))])]
543 operands[7] = GEN_INT(0);
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.
551 (define_insn_and_split "cbranchhi4"
554 (match_operator:CC 0 "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 "" ""))
559 (clobber (reg:CC CC_REGNUM))]
561 "* return picochip_output_cbranch(operands);"
563 && (picochip_schedule_type != DFA_TYPE_NONE || flag_delayed_branch)"
564 [(set (reg:CC CC_REGNUM) (match_dup 0))
566 (if_then_else (match_op_dup:HI 0 [(reg:CC CC_REGNUM) (const_int 0)])
567 (label_ref (match_dup 3))
569 (use (match_dup 4))])]
571 operands[4] = GEN_INT(GET_CODE(operands[0]));
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.
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")]))]
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")
593 (define_insn "*compare"
594 [(set (reg:CC CC_REGNUM)
595 (match_operator:CC 0 "comparison_operator"
596 [(match_operand:HI 1 "register_operand" "r,r,r")
597 (match_operand:HI 2 "picochip_comparison_operand" "r,M,i")]))]
599 "* return picochip_output_compare(operands);"
600 [; Must be picoAlu because it sets the condition flags.
601 (set_attr "type" "picoAlu,picoAlu,picoAlu")
602 (set_attr "longConstant" "false,true,true")
603 (set_attr "length" "2,4,4")
606 ; Match a branch instruction, created from a tstport/cbranch split.
607 ; We use a "use" clause so GCC doesnt try to use this pattern generally.
608 (define_insn "*branch"
611 (match_operator 2 "comparison_operator"
612 [(reg:CC CC_REGNUM) (const_int 0)])
613 (label_ref (match_operand 0 "" ""))
615 (use (match_operand:HI 1 "const_int_operand" ""))]
617 "* return picochip_output_branch(operands, insn);"
618 [(set (attr "length")
620 (and (ge (minus (match_dup 0) (pc)) (const_int MIN_BRANCH_OFFSET))
621 (le (minus (match_dup 0) (pc)) (const_int MAX_BRANCH_OFFSET)))
622 (const_int SHORT_BRANCH_LENGTH)
623 (const_int LONG_BRANCH_LENGTH)))
626 (eq_attr "length" "6")
627 (const_string "realBranch")
628 (const_string "unknown")))])
630 ;; If a movqi is used which accesses memory on a machine which doesn't
631 ;; have byte addressing, synthesise the instruction using word load/store
632 ;; operations. The movqi's that are required during reload phase are
633 ;; handled using reload_inqi/reload_outqi.
635 (define_expand "movqi"
636 [(set (match_operand:QI 0 "nonimmediate_operand" "")
637 (match_operand:QI 1 "general_operand" ""))]
641 if (!reload_completed &&
642 !TARGET_HAS_BYTE_ACCESS &&
643 (MEM == GET_CODE(operands[0]) || MEM == GET_CODE(operands[1])))
652 warn_of_byte_access();
654 /* Load the constant 1 into a register. */
655 const1 = gen_reg_rtx(HImode);
656 emit_insn(gen_rtx_SET(HImode, const1, GEN_INT(1)));
658 /* Load the address mask with the bitwise complement of 1. */
659 addressMask = gen_reg_rtx(HImode);
660 emit_insn(gen_rtx_SET(HImode, addressMask, GEN_INT(-2)));
662 /* Handle loads first, in case we are dealing with a mem := mem
664 if (MEM == GET_CODE(operands[1]))
666 /* Loads work as follows. The entire word containing the desired byte
667 * is loaded. The bottom bit of the address indicates which
668 * byte is required. The desired byte is moved into the most
669 * significant byte, and then an arithmetic shift right
670 * invoked to achieve sign extension. The desired byte is
671 * moved to the MSB by XOR'ing the bottom address bit by 1,
672 * multiplying the result by 8, and then shifting left by
673 * that amount. Note that shifts only operate on the bottom
674 * 4-bits of the source offset, so although the XOR may
675 * produce a value which has its upper bits set, only bit 4
676 * (i.e., the inverted, shifted bottom address bit) actually
680 /* Ensure the address is in a register. */
681 address = gen_reg_rtx(HImode);
682 emit_insn(gen_rtx_SET(HImode, address, XEXP(operands[1], 0)));
684 /* Compute the word address by masking out the bottom bit. */
685 wordAddress = gen_reg_rtx(HImode);
686 emit_insn(gen_andhi3(wordAddress, address, addressMask));
688 /* Compute the shift value. This is the bottom address bit,
689 * inverted, and multiplied by 8. */
690 shiftVal = gen_reg_rtx(HImode);
691 emit_insn(gen_xorhi3(shiftVal, address, const1));
692 emit_insn(gen_ashlhi3(shiftVal, shiftVal, GEN_INT(3)));
694 /* Emit the memory load. */
695 loadedValue = gen_reg_rtx(HImode);
696 emit_insn(gen_rtx_SET(HImode, loadedValue, gen_rtx_MEM(HImode, wordAddress)));
698 /* Shift the desired byte to the most significant byte. */
699 rtx topByteValue = gen_reg_rtx (HImode);
700 emit_insn (gen_ashlhi3 (topByteValue, loadedValue, shiftVal));
702 /* Sign extend the top-byte back into the bottom byte. */
703 rtx signExtendedValue = gen_reg_rtx(HImode);
704 emit_insn(gen_ashrhi3(signExtendedValue, topByteValue, GEN_INT(8)));
706 /* Final extraction of QI mode register. */
707 operands[1] = gen_rtx_SUBREG(QImode, signExtendedValue, 0);
711 if (MEM == GET_CODE(operands[0]) && GET_CODE(operands[1]) != MEM)
718 /* Get the address. */
719 address = gen_reg_rtx(HImode);
720 emit_insn(gen_rtx_SET(HImode, address, XEXP(operands[0], 0)));
722 /* Compute the word aligned address. */
723 wordAddress = gen_reg_rtx(HImode);
724 emit_insn(gen_andhi3(wordAddress, address, addressMask));
726 /* Compute the shift value. */
727 shiftVal = gen_reg_rtx(HImode);
728 emit_insn(gen_andhi3(shiftVal, address, const1));
729 emit_insn(gen_ashlhi3(shiftVal, shiftVal, GEN_INT(3)));
731 /* Emit the memory load. */
732 loadedValue = gen_reg_rtx(HImode);
733 emit_insn(gen_rtx_SET(HImode, loadedValue, gen_rtx_MEM(HImode, wordAddress)));
735 /* Zero out the destination bits by AND'ing with 0xFF00
736 * shifted appropriately. */
737 zeroingByteMask = gen_reg_rtx(HImode);
738 emit_insn(gen_rtx_SET(HImode, zeroingByteMask, GEN_INT(-256)));
739 emit_insn(gen_lshrhi3(zeroingByteMask, zeroingByteMask, shiftVal));
740 emit_insn(gen_andhi3(loadedValue, loadedValue, zeroingByteMask));
742 /* Grab the incoming QI register, and ensure that the top bits
743 * are zeroed out. This is because the register may be
744 * storing a signed value, in which case the top-bits will be
745 * sign bits. These must be removed to ensure that the
746 * read-modify-write (which uses an OR) doesn't pick up those
747 * bits, instead of the original memory value which is being
750 /*if (register_operand(operands[1],QImode))
752 tempHiMode = XEXP(operands[1], 0);
756 tempHiMode = operands[1];
758 //tempHiMode = force_reg(QImode, operands[1]);
759 tempHiMode = simplify_gen_subreg(HImode, operands[1], QImode, 0);
760 temp = gen_reg_rtx(HImode);
761 emit_insn(gen_rtx_SET(HImode, temp, tempHiMode));
762 rtx lsbByteMask = gen_reg_rtx (HImode);
763 emit_insn (gen_rtx_SET (HImode, lsbByteMask, GEN_INT (0xFF)));
764 emit_insn (gen_andhi3 (temp, temp, lsbByteMask));
766 /* Shift the incoming byte value by the appropriate amount,
767 * and OR into the load value. */
768 emit_insn(gen_ashlhi3(temp, temp, shiftVal));
769 emit_insn(gen_iorhi3(loadedValue, loadedValue, temp));
771 /* Rewrite the original assignment, to assign the new value
772 * to the word address. */
773 operands[0] = gen_rtx_MEM(HImode, wordAddress);
774 operands[1] = loadedValue;
781 (define_insn "*movqi_sign_extend"
782 [(set (match_operand:HI 0 "register_operand" "=r,r")
783 (sign_extend:HI (match_operand:QI 1 "memory_operand" "a,m")))]
784 "TARGET_HAS_BYTE_ACCESS"
786 LDB (%a1),%0\t\t// %0 = Mem(%a1)
787 LDB %a1,%0\t\t// %0 = Mem(%M1{byte})"
788 [(set_attr "type" "mem,mem")
789 (set_attr "longConstant" "true,false")
790 (set_attr "length" "4,4")])
792 ;; movqi instructions for machines with and without byte access.
793 (define_insn "*movqi_byte"
794 [(set (match_operand:QI 0 "nonimmediate_operand" "=r,r,r,r,r,a,m")
795 (match_operand:QI 1 "general_operand" "r,a,m,I,i,r,r"))]
796 "TARGET_HAS_BYTE_ACCESS"
798 COPY.%# %1, %0\t// %0 := %1
799 LDB (%a1),%0\t\t// %0 = Mem(%a1)
800 LDB %a1,%0\t\t// %0 = Mem(%M1{byte})
801 COPY.%# %1,%0\t\t// %0 := #%1 (QI) (short constant)
802 COPY.%# %1,%0\t\t// %0 := #%1 (QI) (long constant)
803 STB %1,(%a0)\t\t// Mem(%a0) := %1
804 STB %1,%a0\t\t// Mem(%M0{byte}) := %1"
805 [(set_attr "type" "basicAlu,mem,mem,basicAlu,basicAlu,mem,mem")
806 (set_attr "longConstant" "false,true,false,false,true,true,false")
807 (set_attr "length" "2,4,4,2,4,4,4")])
809 ;; Machines which don't have byte access can copy registers, and load
810 ;; constants, but can't access memory. The define_expand for movqi
811 ;; should already have rewritten memory accesses using word
812 ;; operations. The exception is qi reloads, which are handled using
813 ;; the reload_? patterns.
814 (define_insn "*movqi_nobyte"
815 [(set (match_operand:QI 0 "register_operand" "=r,r")
816 (match_operand:QI 1 "picochip_register_or_immediate_operand" "r,i"))]
817 "!TARGET_HAS_BYTE_ACCESS"
819 COPY.%# %1,%0\t// %0 := %1
820 COPY.%# %1,%0\t\t// %0 := #%1 (QI)")
823 [(set (match_operand:HI 0 "nonimmediate_operand" "=r,r,r,a,m,r,r")
824 (match_operand:HI 1 "general_operand" "r,a,m,r,r,I,i"))]
827 COPY.%# %1,%0\t\t// %0 := %1
828 LDW (%a1),%0\t\t// %0 := Mem(%a1)
829 LDW %a1,%0\t\t// %0 = Mem(%M1{byte})
830 STW %1,(%a0)\t\t// Mem(%a0) := %1
831 STW %1,%a0\t\t// Mem(%M0{byte}) := %1
832 COPY.%# %1,%0\t// %0 := %1 (short constant)
833 COPY.%# %1,%0\t// %0 := %1 (long constant)"
834 [(set_attr "type" "basicAlu,mem,mem,mem,mem,basicAlu,basicAlu")
835 (set_attr "longConstant" "false,true,false,true,false,false,true")
836 (set_attr "length" "2,4,4,4,4,2,4")])
839 [(set (match_operand:SI 0 "nonimmediate_operand" "=r,r,r,r,a,m")
840 (match_operand:SI 1 "general_operand" "r,a,m,i,r,r"))]
843 // %R0 := %R1 (SI)\n\tCOPY.%# %L1,%L0 %| COPY.1 %U1,%U0
844 LDL (%a1),%R0\t\t// %R0 = Mem(%a1)
845 LDL %a1,%R0\t\t// %R0 = Mem(%M1{byte})
846 // %R0 := #%1 (SI)\n\tCOPY.%# %L1,%L0 %| COPY.%# %U1,%U0
847 STL %R1,(%a0)\t\t// Mem(%a0) := %R1
848 STL %R1,%a0\t\t// Mem(%M0{byte}) := %R1"
849 [(set_attr "type" "unknown,mem,mem,unknown,mem,mem")
850 (set_attr "longConstant" "false,true,false,true,false,false")
851 (set_attr "length" "4,4,4,6,4,4")])
853 ; Split an SI mode register copy into separate HI mode copies, which
854 ; can be VLIW'd with other instructions. Only split the instruction
855 ; when VLIW scheduling is enabled. Splitting the instruction saves
858 ; This is predicated in reload_completed. This ensures that the
859 ; instructions aren't broken up too early which can result in the
860 ; SImode code being converted into inefficient HI mode code.
863 [(set (match_operand:SI 0 "register_operand" "")
864 (match_operand:SI 1 "register_operand" ""))]
865 "reload_completed && picochip_schedule_type == DFA_TYPE_SPEED"
866 [(set (match_dup 2) (match_dup 3))
867 (set (match_dup 4) (match_dup 5))]
869 operands[2] = gen_lowpart (HImode, operands[0]);
870 operands[3] = gen_lowpart (HImode, operands[1]);
871 operands[4] = gen_highpart (HImode, operands[0]);
872 operands[5] = gen_highpart (HImode, operands[1]);
875 ; SI Mode split for load constant.
877 [(set (match_operand:SI 0 "register_operand" "")
878 (match_operand:SI 1 "const_int_operand" ""))]
880 [(set (match_dup 2) (match_dup 3))
881 (set (match_dup 4) (match_dup 5))]
883 operands[2] = gen_lowpart (HImode, operands[0]);
884 operands[3] = picochip_get_low_const(operands[1]);
885 operands[4] = gen_highpart (HImode, operands[0]);
886 operands[5] = picochip_get_high_const(operands[1]);
890 [(set (match_operand:SF 0 "nonimmediate_operand" "=r,r,r,m")
891 (match_operand:SF 1 "general_operand" "r,m,i,r"))]
894 // %R0 := %R1 (SF)\n\tCOPY.%# %L1,%L0 %| COPY.1 %U1,%U0
895 LDL %a1,%R0\t\t// %R0 :={SF} Mem(%M1{byte})
896 // %R0 := #%1 (SF)\n\tCOPY.%# %L1,%L0\n\tCOPY.%# %U1,%U0
897 STL %R1,%a0\t\t// Mem(%M0{byte}) :={SF} %R1")
899 ;;===========================================================================
901 ;;===========================================================================
903 ;; No-operation (NOP)
908 [(set_attr "length" "1")])
910 ;;===========================================================================
911 ;; Function Calls. Define expands are used to ensure that the correct
912 ;; type of pattern is emitted, and then the define_insn's match the
913 ;; pattern using the correct types.
915 ;; Note: The comments output as part of these instructions are detected by
916 ;; the linker. Don't change the comments!
917 ;;===========================================================================
919 (define_expand "call"
920 [(parallel [(call (match_operand:QI 0 "memory_operand" "")
921 (match_operand 1 "const_int_operand" ""))
922 (clobber (reg:HI LINK_REGNUM))])]
926 (define_insn "call_for_divmod"
927 [(call (match_operand:QI 0 "memory_operand" "")
928 (match_operand 1 "const_int_operand" ""))]
930 "JL (%M0)\t// fn_call %M0%>"
931 [(set_attr "length" "4")
932 (set_attr "type" "realBranch")
933 (set_attr "longConstant" "true")])
935 (define_insn "*call_using_symbol"
936 [(call (mem:QI (match_operand:HI 0 "immediate_operand" "i"))
937 (match_operand 1 "const_int_operand" ""))
938 (clobber (reg:HI LINK_REGNUM))]
940 "JL (%M0)\t// fn_call %M0%>"
941 [(set_attr "length" "4")
942 (set_attr "type" "realBranch")
943 (set_attr "longConstant" "true")])
945 (define_insn "*call_using_register"
946 [(call (mem:QI (match_operand:HI 0 "register_operand" "r"))
947 (match_operand 1 "const_int_operand" ""))
948 (clobber (reg:HI LINK_REGNUM))]
950 "JL (%r0)\t// fn_call_unknown %r0%>"
951 [(set_attr "length" "2")
952 (set_attr "type" "realBranch")
953 (set_attr "longConstant" "false")])
955 (define_expand "call_value"
956 [(parallel [(set (match_operand:HI 0 "" "")
957 (call:HI (match_operand:QI 1 "memory_operand" "g")
958 (match_operand 2 "const_int_operand" "")))
959 (clobber (reg:HI LINK_REGNUM))])]
963 (define_insn "*call_value_using_symbol"
964 [(set (match_operand:HI 0 "" "")
965 (call:HI (mem:QI (match_operand:HI 1 "immediate_operand" "i"))
966 (match_operand 2 "const_int_operand" "")))
967 (clobber (reg:HI LINK_REGNUM))]
969 "JL (%M1)\t// fn_call %M1 (value return)%>"
970 [(set_attr "length" "4")
971 (set_attr "type" "realBranch")
972 (set_attr "longConstant" "true")])
974 (define_insn "*call_value_using_register"
975 [(set (match_operand:HI 0 "" "")
976 (call:HI (mem:QI (match_operand:HI 1 "register_operand" "r"))
977 (match_operand 2 "const_int_operand" "")))
978 (clobber (reg:HI LINK_REGNUM))]
980 "JL (%r1)// fn_call_unknown %r1 (value return)%>"
981 [(set_attr "length" "2")
982 (set_attr "type" "realBranch")
983 (set_attr "longConstant" "false")])
985 ;;===========================================================================
987 ;;===========================================================================
989 ;; Note that the addition of a negative value is transformed into the
990 ;; subtraction of a positive value, so that the add/sub immediate slot
991 ;; can make better use of the 4-bit range.
993 (define_insn "addhi3"
994 [(set (match_operand:HI 0 "register_operand" "=r,r,r,r")
995 (plus:HI (match_operand:HI 1 "register_operand" "r,r,r,r")
996 (match_operand:HI 2 "general_operand" "r,M,n,i")))
997 (clobber (reg:CC CC_REGNUM))]
999 { if (CONST_INT == GET_CODE(operands[2]) &&
1000 INTVAL(operands[2]) > -16 &&
1001 INTVAL(operands[2]) < 0)
1002 return "SUB.%# %1,-(%2),%0\t// %0 := %1 + %2 (HI)";
1004 return "ADD.%# %1,%2,%0\t// %0 := %1 + %2 (HI)";
1006 [(set_attr "type" "basicAlu,basicAlu,basicAlu,basicAlu")
1007 (set_attr "longConstant" "false,false,true,true")
1008 (set_attr "length" "2,2,4,4")]
1012 ;; If we peepholed the compare instruction out, we need to make sure the add
1013 ;; goes in slot 0. This pattern is just to accomplish that.
1015 (define_insn "addhi3_with_use_clause"
1016 [(set (match_operand:HI 0 "register_operand" "=r,r,r,r")
1017 (plus:HI (match_operand:HI 1 "register_operand" "r,r,r,r")
1018 (match_operand:HI 2 "general_operand" "r,M,n,i")))
1019 (set (reg:CC CC_REGNUM)
1020 (match_operator:CC 3 "picochip_peephole_comparison_operator"
1024 { if (CONST_INT == GET_CODE(operands[2]) &&
1025 INTVAL(operands[2]) > -16 &&
1026 INTVAL(operands[2]) < 0)
1027 return "SUB.0 %1,-(%2),%0\t// %0 := %1 + %2 (HI)";
1029 return "ADD.0 %1,%2,%0\t// %0 := %1 + %2 (HI)";
1031 [(set_attr "type" "picoAlu,picoAlu,picoAlu,picoAlu")
1032 (set_attr "longConstant" "false,false,true,true")
1033 (set_attr "length" "2,2,4,4")]
1036 ;; Match an addition in which the first operand has been shifted
1037 ;; (e.g., the comms array functions can emit such instructions).
1038 (define_insn "*addWith1stOpShift"
1039 [(set (match_operand:HI 0 "register_operand" "=r,r")
1040 (plus:HI (ashift:HI (match_operand:HI 1 "register_operand" "r,r")
1041 (match_operand:HI 2 "const_int_operand" ""))
1042 (match_operand:HI 3 "immediate_operand" "I,i")))
1043 (clobber (reg:CC CC_REGNUM))]
1045 "ADD.0 [LSL %1,%2],%3,%0\t// %0 := (%1 << %2) + %3"
1046 [(set_attr "type" "picoAlu,picoAlu")
1047 (set_attr "longConstant" "false,true")])
1049 (define_insn_and_split "addsi3"
1050 [(set (match_operand:SI 0 "register_operand" "=r,r")
1051 (plus:SI (match_operand:SI 1 "register_operand" "r,r")
1052 (match_operand:SI 2 "general_operand" "r,i")))
1053 (clobber (reg:CC CC_REGNUM))]
1055 "// %0 := %1 + %2 (SI)\n\tADD.0 %L1,%L2,%L0\n\tADDC.0 %U1,%U2,%U0"
1056 "reload_completed && picochip_schedule_type != DFA_TYPE_NONE"
1061 rtx op0_high = gen_highpart (HImode, operands[0]);
1062 rtx op1_high = gen_highpart (HImode, operands[1]);
1063 rtx op0_low = gen_lowpart (HImode, operands[0]);
1064 rtx op1_low = gen_lowpart (HImode, operands[1]);
1065 rtx op2_high, op2_low;
1067 if (CONST_INT == GET_CODE(operands[2]))
1069 op2_high = picochip_get_high_const(operands[2]);
1070 op2_low = picochip_get_low_const(operands[2]);
1072 op2_high = gen_highpart (HImode, operands[2]);
1073 op2_low = gen_lowpart (HImode, operands[2]);
1076 operands[4] = gen_add_multi_lower (op0_low, op1_low, op2_low);
1077 operands[5] = gen_add_multi_upper (op0_high, op1_high, op2_high);
1081 ;; Perform the lowest part of a multi-part addition (SI/DI). This sets
1082 ;; the flags, so is an picoAlu instruction (we could use a
1083 ;; conventional addhi, but the addhi is better off being a treated as
1084 ;; a basicAlu instruction, rather than a picoAlu instruction).
1085 (define_insn "add_multi_lower"
1086 [(set (match_operand:HI 0 "register_operand" "=r,r,r")
1087 (plus:HI (match_operand:HI 1 "register_operand" "r,r,r")
1088 (match_operand:HI 2 "general_operand" "r,M,i")))
1089 (set (reg:CC CC_REGNUM)
1090 (compare:CC (plus:HI (match_dup 1)
1094 { if (CONST_INT == GET_CODE(operands[2]) &&
1095 INTVAL(operands[2]) > -16 &&
1096 INTVAL(operands[2]) < 0)
1097 return "SUB.%# %1,-(%2),%0\t// %0+carry := %1 + %2 (low multi-part)";
1099 return "ADD.%# %1,%2,%0\t// %0+carry := %1 + %2 (low multi-part)";
1101 [(set_attr "type" "picoAlu,picoAlu,picoAlu")
1102 (set_attr "longConstant" "false,false,true")
1103 (set_attr "length" "2,2,4")])
1105 ;; Perform the central part of a multi-part addition (DI). This uses
1106 ;; the CC register, and also sets the CC register, so needs to be
1107 ;; placed in the first ALU slot. Note that the ADDC must
1108 ;; use the long constant to represent immediates.
1109 (define_insn "add_multi_mid"
1110 [(set (match_operand:HI 0 "register_operand" "=r,r")
1111 (plus:HI (match_operand:HI 1 "register_operand" "r,r")
1112 (plus:HI (match_operand:HI 2 "general_operand" "r,i")
1113 (reg:CC CC_REGNUM))))
1114 (set (reg:CC CC_REGNUM)
1115 (compare:CC (plus:HI (match_dup 1)
1119 "ADDC.%# %1,%2,%0\t// %0+carry := carry + %1 + %2 (mid multi-part)"
1120 [(set_attr "type" "picoAlu,picoAlu")
1121 (set_attr "longConstant" "false,true")
1122 (set_attr "length" "2,4")])
1124 ;; Perform the highest part of a multi-part addition (SI/DI). This
1125 ;; uses the CC register, but doesn't require any registers to be set,
1126 ;; so may be scheduled in either of the ALU's. Note that the ADDC must
1127 ;; use the long constant to represent immediates.
1128 (define_insn "add_multi_upper"
1129 [(set (match_operand:HI 0 "register_operand" "=r,r")
1130 (plus:HI (match_operand:HI 1 "register_operand" "r,r")
1131 (plus:HI (match_operand:HI 2 "general_operand" "r,i")
1132 (reg:CC CC_REGNUM))))
1133 (clobber (reg:CC CC_REGNUM))]
1135 "ADDC.%# %1,%2,%0\t// %0 := carry + %1 + %2 (high multi-part)"
1136 [(set_attr "type" "basicAlu,basicAlu")
1137 (set_attr "longConstant" "false,true")
1138 (set_attr "length" "2,4")])
1140 ;; The lea instruction is a special type of add operation, which looks
1141 ;; like a movhi (reg := address). It expands into reg := fp +
1142 ;; offset. Ideally there should be two variants, which take different
1143 ;; sized offsets (i.e., using the long constant, or not, as
1144 ;; appropriate). However, the address operand may have arbitrary
1145 ;; values added to it later (i.e., the AP will be eliminated, possibly
1146 ;; converting a small offset into a long offset), so a long offset is
1149 ;; Note that the lea can use an addition, and hence may modify the CC
1150 ;; register. This upsets scheduling, so instead the lea is placed in
1151 ;; ALU 1 where it cannot modify CC.
1153 (define_insn "*lea_add"
1154 [(set (match_operand:HI 0 "nonimmediate_operand" "=r")
1155 (plus:HI (match_operand:HI 1 "register_operand" "r")
1156 (match_operand:HI 2 "immediate_operand" "i")))]
1158 "ADD.1 %1,%2,%0\t// lea (add)")
1160 ;; Note that, though this instruction looks similar to movhi pattern,
1161 ;; "p" constraint cannot be specified for operands other than
1162 ;; address_operand, hence the extra pattern below.
1163 (define_insn "*lea_move"
1164 [(set (match_operand:HI 0 "nonimmediate_operand" "=r")
1165 (match_operand:HI 1 "address_operand" "p"))]
1168 if (REG == GET_CODE(operands[1]))
1169 return "COPY.1 %1,%0\t// %0 := %1 (lea)";
1171 return "ADD.1 %b1,%o1,%0\t\t// %0 := %b1 + %o1 (lea)";
1173 [(set_attr "type" "nonCcAlu")
1174 (set_attr "longConstant" "true")
1175 (set_attr "length" "4")])
1178 ;;===========================================================================
1179 ;; Subtraction. Note that these patterns never take immediate second
1180 ;; operands, since those cases are handled by canonicalising the
1181 ;; instruction into the addition of a negative costant.
1182 ;; But, if the first operand needs to be a negative constant, it
1183 ;; is supported here.
1184 ;;===========================================================================
1186 (define_insn "subhi3"
1187 [(set (match_operand:HI 0 "register_operand" "=r,r,r")
1188 (minus:HI (match_operand:HI 1 "general_operand" "r,I,i")
1189 (match_operand:HI 2 "register_operand" "r,r,r")))
1190 (clobber (reg:CC CC_REGNUM))]
1192 "SUB.%# %1,%2,%0 // %0 := %1 - %2 (HI)"
1193 [(set_attr "type" "basicAlu,basicAlu,basicAlu")
1194 (set_attr "longConstant" "false,true,true")
1195 (set_attr "length" "2,4,4")])
1197 ;; If we peepholed the compare instruction out, we need to make sure the
1198 ;; sub goes in slot 0. This pattern is just to accomplish that.
1200 (define_insn "subhi3_with_use_clause"
1201 [(set (match_operand:HI 0 "register_operand" "=r,r,r")
1202 (minus:HI (match_operand:HI 1 "general_operand" "r,I,i")
1203 (match_operand:HI 2 "register_operand" "r,r,r")))
1204 (set (reg:CC CC_REGNUM)
1205 (match_operator:CC 3 "picochip_peephole_comparison_operator"
1209 "SUB.0 %1,%2,%0 // %0 := %1 - %2 (HI)"
1210 [(set_attr "type" "picoAlu,picoAlu,picoAlu")
1211 (set_attr "longConstant" "false,true,true")
1212 (set_attr "length" "2,4,4")])
1214 (define_insn_and_split "subsi3"
1215 [(set (match_operand:SI 0 "register_operand" "=r,r")
1216 (minus:SI (match_operand:SI 1 "general_operand" "r,i")
1217 (match_operand:SI 2 "register_operand" "r,r")))
1218 (clobber (reg:CC CC_REGNUM))]
1220 "// %0 := %1 - %2 (SI)\n\tSUB.%# %L1,%L2,%L0\n\tSUBB.%# %U1,%U2,%U0"
1221 "reload_completed && picochip_schedule_type != DFA_TYPE_NONE"
1226 rtx op0_high = gen_highpart (HImode, operands[0]);
1227 rtx op0_low = gen_lowpart (HImode, operands[0]);
1228 rtx op2_high = gen_highpart (HImode, operands[2]);
1229 rtx op2_low = gen_lowpart (HImode, operands[2]);
1230 rtx op1_high,op1_low;
1232 if (CONST_INT == GET_CODE(operands[1]))
1234 op1_high = picochip_get_high_const(operands[1]);
1235 op1_low = picochip_get_low_const(operands[1]);
1237 op1_high = gen_highpart (HImode, operands[1]);
1238 op1_low = gen_lowpart (HImode, operands[1]);
1242 operands[4] = gen_sub_multi_lower (op0_low, op1_low, op2_low);
1243 operands[5] = gen_sub_multi_upper (op0_high, op1_high, op2_high);
1247 ;; Match the patterns emitted by the multi-part subtraction splitting.
1248 ;; This sets the CC register, so it needs to go into slot 0.
1249 (define_insn "sub_multi_lower"
1250 [(set (match_operand:HI 0 "register_operand" "=r,r")
1251 (minus:HI (match_operand:HI 1 "general_operand" "r,i")
1252 (match_operand:HI 2 "register_operand" "r,r")))
1253 (set (reg:CC CC_REGNUM)
1254 (compare:CC (minus:HI (match_dup 1) (match_dup 2))
1257 "SUB.%# %1,%2,%0\t// %0+carry := %1 - %2 (lower SI)"
1258 [(set_attr "type" "picoAlu,picoAlu")
1259 (set_attr "longConstant" "false,true")
1260 (set_attr "length" "2,4")])
1262 ;; Perform the central part of a multi-part addition (DI). This uses
1263 ;; the CC register, and also sets the CC register, so needs to be
1264 ;; placed in the first ALU.
1265 (define_insn "sub_multi_mid"
1266 [(set (match_operand:HI 0 "register_operand" "=r,r")
1267 (minus:HI (match_operand:HI 1 "general_operand" "r,i")
1268 (minus:HI (match_operand:HI 2 "register_operand" "r,r")
1269 (reg:CC CC_REGNUM))))
1270 (set (reg:CC CC_REGNUM)
1271 (compare:CC (minus:HI (match_dup 1)
1275 "SUBB.%# %1,%2,%0\t// %0+carry := carry - %1 - %2 (mid multi-part)"
1276 [(set_attr "type" "picoAlu,picoAlu")
1277 (set_attr "longConstant" "false,true")
1278 (set_attr "length" "2,4")])
1280 (define_insn "sub_multi_upper"
1281 [(set (match_operand:HI 0 "register_operand" "=r,r")
1282 (minus:HI (match_operand:HI 1 "general_operand" "r,i")
1283 (minus:HI (match_operand:HI 2 "register_operand" "r,r")
1284 (reg:CC CC_REGNUM))))
1285 (clobber (reg:CC CC_REGNUM))]
1287 "SUBB.%# %1,%2,%0\t// %0 := carry - %1 - %2 (upper SI)"
1288 [(set_attr "type" "basicAlu,basicAlu")
1289 (set_attr "longConstant" "false,true")
1290 (set_attr "length" "2,4")])
1292 ;;===========================================================================
1293 ;; Multiplication (signed)
1294 ;;===========================================================================
1296 (define_insn "multiply_machi"
1297 [(set (reg:HI ACC_REGNUM)
1298 (mult:HI (match_operand:HI 0 "register_operand" "r,r")
1300 "picochip_register_or_immediate_operand" "r,i")))]
1301 "TARGET_HAS_MAC_UNIT"
1302 "MUL %0,%1,acc0\t// acc0 := %0 * %1 (signed)"
1303 [(set_attr "length" "3,5")
1304 (set_attr "type" "mac,mac")
1305 (set_attr "longConstant" "false,true")])
1307 (define_expand "mulhi3"
1308 [(set (match_operand:HI 0 "register_operand" "")
1309 (mult:HI (match_operand:HI 1 "register_operand" "")
1310 (match_operand:HI 2 "picochip_register_or_immediate_operand" "")))]
1311 "TARGET_HAS_MULTIPLY"
1314 ;; Different types of mulhi, depending on the AE type. If the AE has MUL unit,
1315 ;; use the following pattern.
1316 (define_insn "*mulhi3_mul"
1317 [(set (match_operand:HI 0 "register_operand" "=r,r")
1318 (mult:HI (match_operand:HI 1 "register_operand" "r,r")
1320 "picochip_register_or_immediate_operand" "r,i")))]
1321 "TARGET_HAS_MUL_UNIT"
1322 "MULL %1,%2,%0 // %0 := %1 * %2 (HI)"
1323 [(set_attr "length" "3,5")
1324 (set_attr "type" "mul,mul")
1325 (set_attr "longConstant" "false,true")])
1327 ;; If the AE has MAC unit, instead, use the following pattern.
1328 (define_insn_and_split "*mulhi3_mac"
1329 [(set (match_operand:HI 0 "register_operand" "=r,r")
1330 (mult:HI (match_operand:HI 1 "register_operand" "r,r")
1332 "picochip_register_or_immediate_operand" "r,i")))]
1333 "TARGET_HAS_MAC_UNIT"
1334 "// %0 := %1 * %2\n\tMUL %1,%2,acc0\n\tREADACC acc0,frac,%0"
1335 "TARGET_HAS_MAC_UNIT && reload_completed"
1340 rtx const_rtx = GEN_INT(0);
1341 operands[3] = (gen_multiply_machi(operands[1], operands[2]));
1342 operands[4] = (gen_movhi_mac(operands[0],const_rtx));
1346 (define_insn "umultiply_machisi"
1347 [(set (reg:SI ACC_REGNUM)
1348 (mult:SI (zero_extend:SI (match_operand:HI 0 "register_operand" "r"))
1349 (zero_extend:SI (match_operand:HI 1 "register_operand" "r"))))]
1350 "TARGET_HAS_MAC_UNIT"
1351 "MULUU %0,%1,acc0\t// acc0 := %0 * %1 (unsigned)"
1352 [(set_attr "length" "3")
1353 (set_attr "type" "mac")
1354 (set_attr "longConstant" "false")])
1356 (define_insn "multiply_machisi"
1357 [(set (reg:SI ACC_REGNUM)
1358 (mult:SI (sign_extend:SI (match_operand:HI 0 "register_operand" "r,r"))
1359 (sign_extend:SI (match_operand:HI 1
1360 "picochip_register_or_immediate_operand" "r,i"))))]
1361 "TARGET_HAS_MAC_UNIT"
1362 "MUL %0,%1,acc0\t// acc0 := %0 * %1 (signed)"
1363 [(set_attr "length" "3,5")
1364 (set_attr "type" "mac,mac")
1365 (set_attr "longConstant" "false,true")])
1367 ;; We want to prevent GCC from thinking ACC is a normal register and using
1368 ;; this pattern. We want it to be used only when you use MAC unit
1369 ;; multiplication. Added a "use" clause for that sake.
1370 (define_insn "movsi_mac"
1371 [(set (match_operand:SI 0 "register_operand" "=r")
1372 (reg:SI ACC_REGNUM))
1373 (use (match_operand:SI 1 "const_int_operand" ""))]
1374 "TARGET_HAS_MAC_UNIT"
1375 "READACC32 acc0,%R0 \t// %0 := acc0 "
1376 [(set_attr "length" "3")
1377 (set_attr "type" "mac")
1378 (set_attr "longConstant" "false")])
1380 ;; We want to prevent GCC from thinking ACC is a normal register and using
1381 ;; this pattern. We want it to be used only when you use MAC unit
1382 ;; multiplication. Added a "use" clause for that sake.
1383 (define_insn "movhi_mac"
1384 [(set (match_operand:HI 0 "register_operand" "=r")
1385 (reg:HI ACC_REGNUM) )
1386 (use (match_operand:HI 1 "const_int_operand" ""))]
1387 "TARGET_HAS_MAC_UNIT"
1388 "READACC acc0,frac,%0 \t// %0 := acc0 "
1389 [(set_attr "length" "3")
1390 (set_attr "type" "mac")
1391 (set_attr "longConstant" "false")])
1393 ;; 16-bit to 32-bit widening signed multiplication.
1394 (define_expand "mulhisi3"
1395 [(set (match_operand:SI 0 "register_operand" "=&r")
1396 (mult:SI (sign_extend:SI (match_operand:HI 1 "register_operand" "r"))
1397 (sign_extend:SI (match_operand:HI 2 "register_operand" "r"))))]
1398 "TARGET_HAS_MULTIPLY"
1402 (define_insn_and_split "*mulhisi3_mul"
1403 [(set (match_operand:SI 0 "register_operand" "=&r")
1404 (mult:SI (sign_extend:SI (match_operand:HI 1 "register_operand" "r"))
1405 (sign_extend:SI (match_operand:HI 2 "register_operand" "r"))))]
1406 "TARGET_HAS_MUL_UNIT"
1407 "// %0 := %1 * %2 (HI->SI)\;MULL %1,%2,%L0\;MULH %1,%2,%U0";
1408 "TARGET_HAS_MUL_UNIT && reload_completed && picochip_schedule_type != DFA_TYPE_NONE"
1413 rtx op0_high = gen_highpart (HImode, operands[0]);
1414 rtx op0_low = gen_lowpart (HImode, operands[0]);
1415 operands[3] = gen_mulhisi3_mul_lower(op0_low,operands[1],operands[2]);
1416 operands[4] = gen_mulhisi3_mul_higher(op0_high,operands[1],operands[2]);
1421 (define_insn "mulhisi3_mul_lower"
1422 [(set (match_operand:HI 0 "register_operand" "=&r")
1425 (sign_extend:SI (match_operand:HI 1 "register_operand" "r"))
1426 (sign_extend:SI (match_operand:HI 2 "register_operand" "r"))) 0))]
1427 "TARGET_HAS_MUL_UNIT"
1429 [(set_attr "length" "3")
1430 (set_attr "type" "mul")
1431 (set_attr "longConstant" "false")])
1433 (define_insn "mulhisi3_mul_higher"
1434 [(set (match_operand:HI 0 "register_operand" "=&r")
1437 (sign_extend:SI (match_operand:HI 1 "register_operand" "r"))
1438 (sign_extend:SI (match_operand:HI 2 "register_operand" "r"))) 2))]
1439 "TARGET_HAS_MUL_UNIT"
1441 [(set_attr "length" "3")
1442 (set_attr "type" "mul")
1443 (set_attr "longConstant" "false")])
1445 (define_insn_and_split "*mulhisi3_mac"
1446 [(set (match_operand:SI 0 "register_operand" "=&r")
1447 (mult:SI (sign_extend:SI (match_operand:HI 1 "register_operand" "r"))
1448 (sign_extend:SI (match_operand:HI 2 "register_operand" "r"))))]
1449 "TARGET_HAS_MAC_UNIT"
1450 "// %0 := %1 * %2 (HI->SI) STAN2\;MUL %1,%2,acc0\;READACC32 acc0,%R0";
1451 "TARGET_HAS_MAC_UNIT && reload_completed"
1456 rtx const_rtx = gen_int_mode(0,SImode);
1457 operands[3] = (gen_multiply_machisi(operands[1], operands[2]));
1458 operands[4] = (gen_movsi_mac(operands[0],const_rtx));
1462 ;;===========================================================================
1463 ;; Widening multiplication (unsigned)
1464 ;;===========================================================================
1466 (define_expand "umulhisi3"
1467 [(set (match_operand:SI 0 "register_operand" "=&r")
1468 (mult:SI (zero_extend:SI (match_operand:HI 1 "register_operand" "r"))
1469 (zero_extend:SI (match_operand:HI 2 "register_operand" "r"))))]
1470 "TARGET_HAS_MULTIPLY"
1474 (define_insn_and_split "*umulhisi3_mul"
1475 [(set (match_operand:SI 0 "register_operand" "=&r")
1476 (mult:SI (zero_extend:SI (match_operand:HI 1 "register_operand" "r"))
1477 (zero_extend:SI (match_operand:HI 2 "register_operand" "r"))))]
1478 "TARGET_HAS_MUL_UNIT"
1479 "// %0 := %1 * %2 (uHI->uSI Type 1)\;MULUL %1,%2,%L0\n\tMULUH %1,%2,%U0";
1480 "TARGET_HAS_MUL_UNIT && reload_completed && picochip_schedule_type != DFA_TYPE_NONE"
1485 rtx op0_high = gen_highpart (HImode, operands[0]);
1486 rtx op0_low = gen_lowpart (HImode, operands[0]);
1487 operands[3] = gen_umulhisi3_mul_lower(op0_low,operands[1],operands[2]);
1488 operands[4] = gen_umulhisi3_mul_higher(op0_high,operands[1],operands[2]);
1493 (define_insn "umulhisi3_mul_lower"
1494 [(set (match_operand:HI 0 "register_operand" "=&r")
1497 (zero_extend:SI (match_operand:HI 1 "register_operand" "r"))
1498 (zero_extend:SI (match_operand:HI 2 "register_operand" "r"))) 0))]
1499 "TARGET_HAS_MUL_UNIT"
1501 [(set_attr "length" "3")
1502 (set_attr "type" "mul")
1503 (set_attr "longConstant" "false")])
1505 (define_insn "umulhisi3_mul_higher"
1506 [(set (match_operand:HI 0 "register_operand" "=&r")
1509 (zero_extend:SI (match_operand:HI 1 "register_operand" "r"))
1510 (zero_extend:SI (match_operand:HI 2 "register_operand" "r"))) 2))]
1511 "TARGET_HAS_MUL_UNIT"
1513 [(set_attr "length" "3")
1514 (set_attr "type" "mul")
1515 (set_attr "longConstant" "false")])
1517 (define_insn_and_split "*umulhisi3_mac"
1518 [(set (match_operand:SI 0 "register_operand" "=&r")
1519 (mult:SI (zero_extend:SI (match_operand:HI 1 "register_operand" "r"))
1520 (zero_extend:SI (match_operand:HI 2 "register_operand" "r"))))]
1521 "TARGET_HAS_MAC_UNIT"
1522 "// %0 := %1 * %2 (uHI->uSI Type 3)\;MULUU %1,%2,acc0\;READACC32 acc0,%R0";
1523 "TARGET_HAS_MAC_UNIT && reload_completed"
1528 rtx const_rtx = gen_int_mode(0,SImode);
1529 operands[3] = (gen_umultiply_machisi(operands[1], operands[2]));
1530 operands[4] = (gen_movsi_mac(operands[0],const_rtx));
1534 ;;===========================================================================
1535 ;; Division (signed)
1536 ;;===========================================================================
1538 ;; Perform a divmod operation as a function call. This results in some
1539 ;; registers being clobbered (r0-6, r12 - ignore r13,14 as these are
1540 ;; known not to be affected).
1541 (define_expand "divmodhi4"
1543 ; Copy the inputs to r0 and r1.
1544 (set (reg:HI 0) (match_operand:HI 1 "register_operand" ""))
1545 (set (reg:HI 1) (match_operand:HI 2 "register_operand" ""))
1546 ; Make the function call - note that r12 (link) is clobbered. Note also
1547 ; that an explicit call is generated. This ensures that gcc notices that
1548 ; any function containing a div/mod is not a leaf function.
1549 (parallel [(match_dup 4)
1550 (set (reg:HI 0) (div:HI (reg:HI 0) (reg:HI 1)))
1551 (set (reg:HI 1) (mod:HI (reg:HI 0) (reg:HI 1)))
1552 (clobber (reg:HI 2))
1553 (clobber (reg:HI 3))
1554 (clobber (reg:HI 4))
1555 (clobber (reg:HI 5))
1556 (clobber (reg:HI 12))
1557 (clobber (reg:CC CC_REGNUM))
1559 ; Set the quotient (returned in register 0)
1560 (set (match_operand:HI 0 "register_operand" "") (reg:HI 0))
1561 ; Set the remainder (returned in register 1)
1562 (set (match_operand:HI 3 "register_operand" "") (reg:HI 1))]
1565 rtx fnName = gen_rtx_SYMBOL_REF (HImode, "_divmodhi4");
1566 operands[4] = gen_call_for_divmod (gen_rtx_MEM (QImode, fnName), GEN_INT(0));
1569 ; Match a call to divmodhi4. As this is a call, the link register
1570 ; (r12), and registers r0-5 must be clobbered. Ignore clobbering of
1571 ; r13/4 as these aren't used by the divide function).
1572 (define_insn "*divmodhi4_call"
1573 [(call (mem:QI (match_operand:HI 0 "immediate_operand" "i"))
1574 (match_operand 1 "const_int_operand" ""))
1575 (set (reg:HI 0) (div:HI (reg:HI 0) (reg:HI 1)))
1576 (set (reg:HI 1) (mod:HI (reg:HI 0) (reg:HI 1)))
1577 (clobber (reg:HI 2))
1578 (clobber (reg:HI 3))
1579 (clobber (reg:HI 4))
1580 (clobber (reg:HI 5))
1581 (clobber (reg:HI 12))
1582 (clobber (reg:CC CC_REGNUM))
1585 "JL (%0)\t// call %0%>"
1586 [(set_attr "length" "4")
1587 (set_attr "longConstant" "true")
1588 (set_attr "type" "call")])
1590 ;; Perform a udivmod operation as a function call. This results in some
1591 ;; registers being clobbered (r0-6, r12 - ignore r13,14 as these are
1592 ;; known not to be affected).
1593 (define_expand "udivmodhi4"
1595 ; Copy the inputs to r0 and r1.
1596 (set (reg:HI 0) (match_operand:HI 1 "register_operand" ""))
1597 (set (reg:HI 1) (match_operand:HI 2 "register_operand" ""))
1598 ; Make the function call - note that r12 (link) is clobbered. Note also
1599 ; that an explicit call is generated. This ensures that gcc notices that
1600 ; any function containing a div/mod is not a leaf function.
1601 (parallel [(match_dup 4)
1602 (set (reg:HI 0) (udiv:HI (reg:HI 0) (reg:HI 1)))
1603 (set (reg:HI 1) (umod:HI (reg:HI 0) (reg:HI 1)))
1604 (clobber (reg:HI 2))
1605 (clobber (reg:HI 3))
1606 (clobber (reg:HI 4))
1607 (clobber (reg:HI 5))
1608 (clobber (reg:HI 12))
1609 (clobber (reg:CC CC_REGNUM))
1611 ; Set the quotient (returned in register 0)
1612 (set (match_operand:HI 0 "register_operand" "") (reg:HI 0))
1613 ; Set the remainder (returned in register 1)
1614 (set (match_operand:HI 3 "register_operand" "") (reg:HI 1))]
1617 rtx fnName = gen_rtx_SYMBOL_REF (HImode, "_udivmodhi4");
1618 operands[4] = gen_call_for_divmod (gen_rtx_MEM (QImode, fnName), GEN_INT(0));
1621 ; Match a call to udivmodhi4. As this is a call, the link register
1622 ; (r12), and registers r0-5 must be clobbered. Ignore clobbering of
1623 ; r13/4 as these aren't used by the divide function).
1624 (define_insn "*udivmodhi4_call"
1625 [(call (mem:QI (match_operand:HI 0 "immediate_operand" "i"))
1626 (match_operand 1 "const_int_operand" ""))
1627 (set (reg:HI 0) (udiv:HI (reg:HI 0) (reg:HI 1)))
1628 (set (reg:HI 1) (umod:HI (reg:HI 0) (reg:HI 1)))
1629 (clobber (reg:HI 2))
1630 (clobber (reg:HI 3))
1631 (clobber (reg:HI 4))
1632 (clobber (reg:HI 5))
1633 (clobber (reg:HI 12))
1634 (clobber (reg:CC CC_REGNUM))]
1636 "JL (%0)\t// call %0%>"
1637 [(set_attr "length" "4")
1638 (set_attr "longConstant" "true")
1639 (set_attr "type" "call")])
1641 (define_expand "udivmodsi4"
1643 ; Make the function call
1644 (set (reg:SI 0) (match_operand:SI 1 "register_operand" ""))
1645 (set (reg:SI 2) (match_operand:SI 2 "register_operand" ""))
1648 (set (reg:SI 4) (udiv:SI (reg:SI 0) (reg:SI 2)))
1649 (set (reg:SI 6) (umod:SI (reg:SI 0) (reg:SI 2)))
1650 (clobber (reg:SI 0))
1651 (clobber (reg:SI 2))
1652 (clobber (reg:HI 12))
1653 (clobber (reg:CC CC_REGNUM))])
1654 (set (match_operand:SI 0 "register_operand" "") (reg:SI 4))
1655 (set (match_operand:SI 3 "register_operand" "") (reg:SI 6))]
1658 rtx fnName = gen_rtx_SYMBOL_REF (HImode, "_udivmodsi4");
1659 operands[4] = gen_call_for_divmod (gen_rtx_MEM (QImode, fnName), GEN_INT(0));
1662 (define_insn "*udivmodsi4_call"
1663 [(call (mem:QI (match_operand:HI 0 "immediate_operand" "i"))
1664 (match_operand 1 "const_int_operand" ""))
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))]
1672 "JL (%0)\t// call %0%>"
1673 [(set_attr "length" "4")
1674 (set_attr "longConstant" "true")
1675 (set_attr "type" "call")])
1677 (define_expand "divmodsi4"
1679 ; Make the function call
1680 (set (reg:SI 0) (match_operand:SI 1 "register_operand" ""))
1681 (set (reg:SI 2) (match_operand:SI 2 "register_operand" ""))
1684 (set (reg:SI 4) (div:SI (reg:SI 0) (reg:SI 2)))
1685 (set (reg:SI 6) (mod:SI (reg:SI 0) (reg:SI 2)))
1686 (clobber (reg:SI 0))
1687 (clobber (reg:SI 2))
1688 (clobber (reg:HI 12))
1689 (clobber (reg:CC CC_REGNUM))])
1690 (set (match_operand:SI 0 "register_operand" "") (reg:SI 4))
1691 (set (match_operand:SI 3 "register_operand" "") (reg:SI 6))]
1694 rtx fnName = gen_rtx_SYMBOL_REF (HImode, "_divmodsi4");
1695 operands[4] = gen_call_for_divmod (gen_rtx_MEM (QImode, fnName), GEN_INT(0));
1698 (define_insn "*divmodsi4_call"
1699 [(call (mem:QI (match_operand:HI 0 "immediate_operand" "i"))
1700 (match_operand 1 "const_int_operand" ""))
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))]
1708 "JL (%0)\t// call %0%>"
1709 [(set_attr "length" "4")
1710 (set_attr "longConstant" "true")
1711 (set_attr "type" "call")])
1713 ;;===========================================================================
1714 ;; Bitwise AND. The QI/SI mode instructions are automatically
1715 ;; synthesised from the HI mode instruction.
1716 ;;===========================================================================
1718 (define_insn "andhi3"
1719 [(set (match_operand:HI 0 "register_operand" "=r,r")
1720 (and:HI (match_operand:HI 1 "register_operand" "r,r")
1721 (match_operand:HI 2 "general_operand" "r,n")))
1722 (clobber (reg:CC CC_REGNUM))]
1724 "AND.%# %1,%2,%0 // %0 := %1 AND %2 (HI)"
1725 [(set_attr "type" "basicAlu,basicAlu")
1726 (set_attr "longConstant" "false,true")
1727 (set_attr "length" "3,5")])
1729 ;; If we peepholed the compare instruction out, we need to make sure the
1730 ;; "and" goes in slot 0. This pattern is just to accomplish that.
1732 (define_insn "andhi3_with_use_clause"
1733 [(set (match_operand:HI 0 "register_operand" "=r,r")
1734 (and:HI (match_operand:HI 1 "register_operand" "r,r")
1735 (match_operand:HI 2 "general_operand" "r,n")))
1736 (set (reg:CC CC_REGNUM)
1737 (match_operator:CC 3 "picochip_peephole_comparison_operator"
1741 "AND.0 %1,%2,%0 // %0 := %1 AND %2 (HI)"
1742 [(set_attr "type" "picoAlu,picoAlu")
1743 (set_attr "longConstant" "false,true")
1744 (set_attr "length" "3,5")])
1746 ;;===========================================================================
1747 ;; Bitwise inclusive-OR. The QI mode instruction is automatically
1748 ;; synthesised from the HI mode instruction.
1749 ;;===========================================================================
1751 (define_insn "iorhi3"
1752 [(set (match_operand:HI 0 "register_operand" "=r,r")
1753 (ior:HI (match_operand:HI 1 "register_operand" "r,r")
1754 (match_operand:HI 2 "register_operand" "r,n")))
1755 (clobber (reg:CC CC_REGNUM))]
1757 "OR.%# %1,%2,%0 // %0 := %1 IOR %2 (HI)"
1758 [(set_attr "type" "basicAlu,basicAlu")
1759 (set_attr "longConstant" "false,true")
1760 (set_attr "length" "3,5")])
1762 (define_insn "iorhi3_with_use_clause"
1763 [(set (match_operand:HI 0 "register_operand" "=r,r")
1764 (ior:HI (match_operand:HI 1 "register_operand" "r,r")
1765 (match_operand:HI 2 "general_operand" "r,n")))
1766 (set (reg:CC CC_REGNUM)
1767 (match_operator:CC 3 "picochip_peephole_comparison_operator"
1771 "OR.0 %1,%2,%0 // %0 := %1 IOR %2 (HI)"
1772 [(set_attr "type" "picoAlu,picoAlu")
1773 (set_attr "longConstant" "false,true")
1774 (set_attr "length" "3,5")])
1776 ;;===========================================================================
1777 ;; Bitwise exclusive-OR. The QI/SI mode instructions are automatically
1778 ;; synthesised from the HI mode instruction.
1779 ;;===========================================================================
1781 (define_insn "xorhi3"
1782 [(set (match_operand:HI 0 "register_operand" "=r,r")
1783 (xor:HI (match_operand:HI 1 "register_operand" "r,r")
1784 (match_operand:HI 2 "picochip_register_or_immediate_operand" "r,n")))
1785 (clobber (reg:CC CC_REGNUM))]
1787 "XOR.%# %1,%2,%0 // %0 := %1 XOR %2 (HI)"
1788 [(set_attr "type" "basicAlu,basicAlu")
1789 (set_attr "longConstant" "false,true")
1790 (set_attr "length" "3,5")])
1792 ;;===========================================================================
1793 ;; Arithmetic shift left.
1794 ;;===========================================================================
1796 (define_insn "ashlhi3"
1797 [(set (match_operand:HI 0 "register_operand" "=r,r")
1798 (ashift:HI (match_operand:HI 1 "register_operand" "r,r")
1799 (match_operand:HI 2 "general_operand" "r,J")))]
1801 "LSL.%# %1,%2,%0 // %0 := %1 << %2"
1802 [(set_attr "type" "picoAlu,basicAlu")
1803 (set_attr "length" "3,3")])
1805 ;;===========================================================================
1806 ;; Arithmetic shift right.
1807 ;;===========================================================================
1809 (define_insn "builtin_asri"
1810 [(set (match_operand:HI 0 "register_operand" "=r")
1811 (ashiftrt:HI (match_operand:HI 1 "register_operand" "r")
1812 (match_operand:HI 2 "immediate_operand" "")))
1813 (clobber (reg:CC CC_REGNUM))]
1815 "ASR.%# %1,%2,%0\t// %0 = %1 >>{arith} %2"
1816 [(set_attr "type" "basicAlu")
1817 (set_attr "length" "3")])
1819 ;; The picoChip ISA doesn't have a variable arithmetic shift right, so
1820 ;; synthesise it. Shifts by constants are directly supported.
1822 (define_expand "ashrhi3"
1823 [(match_operand:HI 0 "register_operand" "")
1824 (match_operand:HI 1 "register_operand" "")
1825 (match_operand:HI 2 "picochip_register_or_immediate_operand" "")]
1828 if (GET_CODE(operands[2]) == CONST_INT)
1829 /* Shift by constant is easy. */
1830 emit_insn (gen_builtin_asri (operands[0], operands[1], operands[2]));
1833 /* Synthesise a variable shift. */
1835 /* Fill a temporary with the sign bits. */
1836 rtx tmp1 = gen_reg_rtx (HImode);
1837 emit_insn (gen_builtin_asri (tmp1, operands[1], GEN_INT(15)));
1839 /* Shift the unsigned value. */
1840 rtx tmp2 = gen_reg_rtx (HImode);
1841 emit_insn (gen_lshrhi3 (tmp2, operands[1], operands[2]));
1843 /* The word of sign bits must be shifted back to the left, to zero
1844 * out the unwanted lower bits. The amount to shift left by is (15 -
1845 * count). Since the shifts are computed modulo 16 (i.e., only the
1846 * lower 4 bits of the count are used), the shift amount (15 - count)
1847 * is equivalent to !count. */
1848 rtx tmp3 = gen_reg_rtx (HImode);
1849 rtx tmp3_1 = GEN_INT (-1);
1850 emit_insn (gen_xorhi3 (tmp3, operands[2], tmp3_1));
1851 rtx tmp4 = gen_reg_rtx (HImode);
1852 emit_insn (gen_ashlhi3 (tmp4, tmp1, tmp3));
1854 /* Combine the sign bits with the shifted value. */
1855 emit_insn (gen_iorhi3 (operands[0], tmp2, tmp4));
1861 ;;===========================================================================
1862 ;; Logical shift right.
1863 ;;===========================================================================
1865 (define_insn "lshrhi3"
1866 [(set (match_operand:HI 0 "register_operand" "=r,r")
1867 (lshiftrt:HI (match_operand:HI 1 "register_operand" "r,r")
1868 (match_operand:HI 2 "general_operand" "r,J")))]
1870 "LSR.%# %1,%2,%0 // %0 := %1 >> %2"
1871 [(set_attr "type" "picoAlu,basicAlu")
1872 (set_attr "length" "3,3")])
1874 ;;===========================================================================
1876 ;;===========================================================================
1878 ;; Negations are performed by subtracting from the constant 0, which
1879 ;; is loaded into a register. By using a register containing 0, the
1880 ;; chances of being able to CSE with another 0 value are increased.
1882 (define_expand "neghi2"
1883 [(set (match_dup 2) (match_dup 3))
1884 (parallel [(set (match_operand:HI 0 "register_operand" "=r")
1885 (minus:HI (match_dup 2)
1886 (match_operand:HI 1 "register_operand" "r")))
1887 (clobber (reg:CC CC_REGNUM))])]
1889 "operands[2] = gen_reg_rtx(HImode);
1890 operands[3] = GEN_INT(0x00000000);")
1892 (define_expand "negsi2"
1893 [(set (match_dup 2) (match_dup 3))
1894 (parallel [(set (match_operand:SI 0 "register_operand" "=r")
1895 (minus:SI (match_dup 2)
1896 (match_operand:SI 1 "register_operand" "r")))
1897 (clobber (reg:CC CC_REGNUM))])]
1899 "operands[2] = gen_reg_rtx(SImode);
1900 operands[3] = GEN_INT(0x00000000);")
1902 ;;===========================================================================
1903 ;; Absolute value. Taken from the Hacker's Delight, page 17. The second of the
1904 ;; four options given there produces the smallest, fastest code.
1905 ;;===========================================================================
1907 (define_insn_and_split "abshi2"
1908 [(set (match_operand:HI 0 "register_operand" "")
1909 (abs:HI (match_operand:HI 1 "register_operand" "")))]
1913 [(parallel [(set (match_dup 2)
1914 (plus:HI (ashiftrt:HI (match_dup 1) (const_int 15))
1916 (clobber (reg:CC CC_REGNUM))])
1917 (parallel [(set (match_dup 0)
1918 (xor:HI (ashiftrt:HI (match_dup 1) (const_int 15))
1920 (clobber (reg:CC CC_REGNUM))])]
1922 operands[2] = gen_reg_rtx (HImode);
1925 ;;===========================================================================
1926 ;; Bitwise complement. Use auto-synthesised variant for SI mode. Though this
1927 ;; internally uses xor, the compiler doesnt automatically synthesize it using
1928 ;; xor, if this pattern was removed.
1929 ;;===========================================================================
1931 (define_insn "one_cmplhi2"
1932 [(set (match_operand:HI 0 "register_operand" "=r")
1933 (not:HI (match_operand:HI 1 "register_operand" "0")))
1934 (clobber (reg:CC CC_REGNUM))]
1936 "XOR.%# %1,-1,%0 // %0 := ~%1"
1937 [(set_attr "type" "basicAlu")
1938 (set_attr "longConstant" "true")
1939 (set_attr "length" "5")])
1941 ;;===========================================================================
1942 ;; Count leading zeros. The special sign-bit-count instruction can be used
1945 ;; The code works by checking to see if the top bit is set. If it is,
1946 ;; then there are no leading zeros. If the top bit is cleared, then
1947 ;; the SBC instruction is used to determine how many more leading
1948 ;; zeros are present, and adding one more for the initial zero.
1949 ;;===========================================================================
1951 (define_insn "clzhi2"
1952 [(set (match_operand:HI 0 "register_operand" "=&r")
1953 (clz:HI (match_operand:HI 1 "register_operand" "r")))]
1955 "// Count leading zeros\;SBC %1,%0\;ASR.0 %1,15,r15 %| ADD.1 %0,1,%0\;COPYNE 0,%0"
1956 [(set_attr "length" "11")])
1958 ;;===========================================================================
1959 ;; Count trailing zeros. This can be achieved efficiently by reversing
1960 ;; using the bitrev instruction, and then counting the leading zeros as
1962 ;;===========================================================================
1964 (define_insn "ctzhi2"
1965 [(set (match_operand:HI 0 "register_operand" "=&r")
1966 (ctz:HI (match_operand:HI 1 "register_operand" "r")))]
1968 "// Count trailing zeros\;BREV %1,%0\;SBC %0,%0\;AND.0 %1,0x0001,r15 %| ADD.1 %0,1,%0\;COPYNE 0,%0"
1969 [(set_attr "length" "15")])
1971 ;;===========================================================================
1972 ;; Find the first set bit, starting from the least significant bit position.
1973 ;; This is very similar to the ctz function, except that the bit index is one
1974 ;; greater than the number of trailing zeros (i.e., SBC + 2), and the
1975 ;; result of ffs on the zero value is defined.
1976 ;;===========================================================================
1978 (define_insn "ffshi2"
1979 [(set (match_operand:HI 0 "register_operand" "=&r")
1980 (ffs:HI (match_operand:HI 1 "register_operand" "r")))]
1982 "// 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"
1983 [(set_attr "length" "20")])
1985 ;;===========================================================================
1986 ;; Tablejump Instruction. Jump to an absolute address.
1987 ;;===========================================================================
1989 (define_insn "tablejump"
1990 [(set (pc) (unspec:HI [(match_operand:HI 0 "register_operand" "r")] 1))
1991 (use (label_ref (match_operand 1 "" "")))
1992 (clobber (match_dup 0))]
1994 "JR (%0)\t // Table jump to %0 %>"
1995 [(set_attr "length" "2")
1996 (set_attr "type" "realBranch")])
1998 ;; Given the memory address of a QImode value, and a scratch register,
1999 ;; store the memory operand into the given output operand. The scratch
2000 ;; operand will not conflict with either of the operands. The other
2001 ;; two operands may conflict with each other.
2003 (define_insn "synthesised_loadqi_unaligned"
2004 [(set (match_operand:QI 0 "register_operand" "=r")
2005 (match_operand:QI 1 "memory_operand" "m"))
2006 (clobber (match_operand:HI 2 "register_operand" "=&r"))
2007 (clobber (reg:CC CC_REGNUM))]
2009 "// 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"
2010 ; Approximate length only. Probably a little shorter than this.
2011 [(set_attr "length" "40")])
2013 ;; Given a memory operand whose alignment is known (the HImode aligned
2014 ;; base is operand 0, and the number of bits by which to shift is in
2016 (define_expand "synthesised_storeqi_aligned"
2018 (set (match_operand:HI 2 "register_operand" "")
2019 (match_operand:HI 0 "memory_operand" ""))
2021 (parallel [(set (match_dup 2) (and:HI (match_dup 2) (match_dup 5)))
2022 (clobber (reg:CC CC_REGNUM))])
2023 ; s2 = source << bitShift
2025 (ashift:HI (subreg:HI (match_operand:QI 1 "register_operand" "") 0)
2026 (match_operand:HI 4 "const_int_operand" "")))
2028 (parallel [(set (match_dup 2) (ior:HI (match_dup 2) (match_dup 3)))
2029 (clobber (reg:CC CC_REGNUM))])
2031 (set (match_dup 0) (match_dup 2))]
2032 "!TARGET_HAS_BYTE_ACCESS"
2034 /* Create the byte mask 0xFF00. */
2035 operands[5] = gen_int_mode(((~0xFF) >> INTVAL (operands[4])), HImode);
2038 ;; Reload instructions. See picochip_secondary_reload for an
2039 ;; explanation of why an SI mode register is used as a scratch. The
2040 ;; memory operand must be stored in a register (i.e., it can't be an
2041 ;; offset to another register - this would require another scratch
2042 ;; register into which the address of the offset could be computed).
2044 (define_expand "reload_inqi"
2045 [(parallel [(match_operand:QI 0 "register_operand" "=&r")
2046 (match_operand:QI 1 "memory_operand" "m")
2047 (match_operand:SI 2 "register_operand" "=&r")])]
2048 "!TARGET_HAS_BYTE_ACCESS"
2052 /* Get the scratch register. Given an SI mode value, we have a
2053 choice of two HI mode scratch registers, so we can be sure that at
2054 least one of the scratch registers will be different to the output
2055 register, operand[0]. */
2057 if (REGNO (operands[0]) == REGNO (operands[2]))
2058 scratch = gen_rtx_REG (HImode, REGNO (operands[2]) + 1);
2060 scratch = gen_rtx_REG (HImode, REGNO (operands[2]));
2062 /* Ensure that the scratch doesn't overlap either of the other
2063 two operands - however, the other two may overlap each
2065 gcc_assert (REGNO(scratch) != REGNO(operands[0]));
2066 gcc_assert (REGNO(scratch) != REGNO(operands[1]));
2068 gcc_assert (GET_CODE (operands[1]) == MEM);
2070 if (picochip_word_aligned_memory_reference(XEXP(operands[1], 0)))
2072 /* Aligned reloads are easy, since they can use word-loads. */
2073 seq = gen_synthesised_loadqi_aligned(operands[0], operands[1], scratch);
2077 /* Emit the instruction using a define_insn. */
2078 seq = gen_synthesised_loadqi_unaligned(operands[0], operands[1], scratch);
2086 (define_expand "reload_outqi"
2087 [(parallel [(match_operand 0 "memory_operand" "=m")
2088 (match_operand:QI 1 "register_operand" "r")
2089 (match_operand:SI 2 "register_operand" "=&r")])]
2090 "!TARGET_HAS_BYTE_ACCESS"
2092 rtx scratch1 = gen_rtx_REG(HImode, REGNO(operands[2]));
2093 rtx scratch2 = gen_rtx_REG(HImode, REGNO(operands[2]) + 1);
2096 gcc_assert (GET_CODE (operands[0]) == MEM);
2098 if (picochip_word_aligned_memory_reference(XEXP(operands[0], 0)))
2100 rtx alignedAddr, bitShift;
2102 /* Convert the address of the known alignment into two operands
2103 * representing the aligned base address, and the number of shift bits
2104 * required to access the required value. */
2105 picochip_get_hi_aligned_mem(operands[0], &alignedAddr, &bitShift);
2107 /* Emit an aligned store of the source, with the given bit offset. */
2108 seq = gen_synthesised_storeqi_aligned(alignedAddr, operands[1], scratch1, scratch2, bitShift);
2113 /* This isnt exercised at all. Moreover, with new devices, byte access
2114 is available in all variants. */
2123 ;; Perform a byte load of an alignable memory operand.
2124 ; op0 = register to load. op1 = memory operand from which to load
2125 ; op2 = op1, aligned to HI, op3 = const bit shift required to extract byte,
2126 ; op4 = INTVAL(8 - op3)
2127 (define_expand "synthesised_loadqi_aligned"
2128 [; Load memory operand into register
2129 (set (match_operand:HI 2 "register_operand" "=r")
2131 ; Shift required byte into top byte of word.
2133 (ashift:HI (match_dup 2)
2135 ; Arithmetic shift of byte to sign extend, and move to lowest register.
2136 (parallel[(set (subreg:HI (match_dup 0) 0)
2137 (ashiftrt:HI (match_dup 2)
2139 (clobber (reg:CC CC_REGNUM))])
2140 (use (match_operand:QI 1 "picochip_alignable_memory_operand" "g"))]
2141 "!TARGET_HAS_BYTE_ACCESS"
2143 rtx alignedAddr, bitShift;
2145 /* Convert the address of the known alignment into two operands
2146 * representing the aligned base address, and the number of shift bits
2147 * required to access the required value. */
2148 picochip_get_hi_aligned_mem(operands[1], &alignedAddr, &bitShift);
2150 operands[3] = alignedAddr;
2151 operands[4] = GEN_INT(8 - INTVAL(bitShift));
2154 ;;============================================================================
2155 ;; Special instructions.
2156 ;;============================================================================
2160 [(set (match_operand:HI 0 "register_operand" "=r")
2161 (unspec:HI [(match_operand:HI 1 "register_operand" "r")]
2164 "SBC %1,%0\t\t// %0 := SBC(%1)"
2165 [(set_attr "type" "picoAlu")
2166 (set_attr "length" "2")])
2170 [(set (match_operand:HI 0 "register_operand" "=r")
2171 (unspec:HI [(match_operand:HI 1 "register_operand" "r")]
2174 "BREV %1,%0\t\t// %0 := BREV(%1)"
2175 [(set_attr "length" "2")
2176 (set_attr "type" "picoAlu")])
2179 (define_insn "bswaphi2"
2180 [(set (match_operand:HI 0 "register_operand" "=r")
2181 (bswap:HI (match_operand:HI 1 "register_operand" "r")))]
2183 "BYTESWAP %1,%0\t\t// %0 := ByteSwap(%1)"
2184 [(set_attr "length" "2")
2185 (set_attr "type" "picoAlu")])
2188 (define_insn "copysw"
2189 [(set (match_operand:HI 0 "register_operand" "=r")
2190 (unspec_volatile:HI [(reg:CC CC_REGNUM)] UNSPEC_COPYSW))]
2192 "COPYSW.%# %0\t// %0 := Flags"
2193 [(set_attr "type" "basicAlu")
2194 (set_attr "length" "2")])
2196 ; Saturating addition.
2197 (define_insn "sataddhi3"
2198 [(set (match_operand:HI 0 "register_operand" "=r")
2199 (unspec:HI [(match_operand:HI 1 "register_operand" "r")
2200 (match_operand:HI 2 "register_operand" "r")]
2202 (clobber (reg:CC CC_REGNUM))]
2204 "ADDS %1,%2,%0\t// %0 := sat(%1 + %2)"
2205 [(set_attr "type" "picoAlu")
2206 (set_attr "length" "3")])
2208 ; Saturating subtraction.
2209 (define_insn "satsubhi3"
2210 [(set (match_operand:HI 0 "register_operand" "=r")
2211 (unspec:HI [(match_operand:HI 1 "register_operand" "r")
2212 (match_operand:HI 2 "register_operand" "r")]
2214 (clobber (reg:CC CC_REGNUM))]
2216 "SUBS %1,%2,%0\t// %0 := sat(%1 - %2)"
2217 [(set_attr "type" "picoAlu")
2218 (set_attr "length" "3")])
2221 [(unspec_volatile [(match_operand:HI 0 "const_int_operand" "i")]
2225 [(set_attr "length" "1")
2226 (set_attr "type" "unknown")])
2228 (define_insn "internal_testport"
2229 [(set (reg:CC CC_REGNUM)
2230 (unspec_volatile:CC [(match_operand:HI 0 "const_int_operand" "i")]
2231 UNSPEC_INTERNAL_TESTPORT))]
2234 [(set_attr "length" "2")
2235 (set_attr "longConstant" "false")
2236 (set_attr "type" "picoAlu")])
2238 ;;============================================================================
2239 ;; Communications builtins.
2241 ;; Each builtin comes in two forms: a single port version, which maps
2242 ;; to a single instruction, and an array port version. The array port
2243 ;; version is treated as a special type of instruction, which is then
2244 ;; split into a number of smaller instructions, if the index of the
2245 ;; port can't be converted into a constant. When the RTL split is
2246 ;; performed, a function call is emitted, in which the index of the
2247 ;; port to use is used to compute the address of the function to call
2248 ;; (i.e., each array port is a function in its own right, and the
2249 ;; functions are stored as an array which is then indexed to determine
2250 ;; the correct function). The communication function port array is
2251 ;; created by the linker if and only if it is required (in a
2252 ;; collect2-like manner).
2253 ;;============================================================================
2255 ; Simple scalar get.
2256 (define_insn "commsGet"
2257 [(set (match_operand:SI 0 "register_operand" "=r")
2259 [(match_operand:HI 1 "immediate_operand" "n")]
2262 "GET %1,%R0\t// %R0 := PORT(%1)"
2263 [(set_attr "type" "comms")
2264 (set_attr "length" "2")])
2266 ; Entry point for array get (the actual port index is computed as the
2267 ; sum of the index, and the base).
2270 ; op1 - Requested port index
2271 ; op2 - size of port array (constant)
2272 ; op3 - base index of port array (constant)
2274 (define_expand "commsArrayGet"
2277 (unspec_volatile:SI [(match_operand:HI 1 "general_operand" "")
2278 (match_operand:HI 2 "immediate_operand" "")
2279 (match_operand:HI 3 "immediate_operand" "")]
2280 UNSPEC_CALL_GET_ARRAY))
2281 (clobber (reg:HI LINK_REGNUM))])
2282 (set (match_operand:SI 0 "register_operand" "") (reg:SI 0))]
2286 ;; The actual array get instruction. When the array index is a constant,
2287 ;; an exact instruction may be generated. When the index is variable,
2288 ;; a call to a special function is generated. This code could be
2289 ;; split into individual RTL instructions, but it is so rarely
2290 ;; used, that we won't bother.
2291 (define_insn "*commsArrayGetInstruction"
2293 (unspec_volatile:SI [(match_operand:HI 0 "general_operand" "r,i")
2294 (match_operand:HI 1 "immediate_operand" "")
2295 (match_operand:HI 2 "immediate_operand" "")]
2296 UNSPEC_CALL_GET_ARRAY))
2297 (clobber (reg:HI LINK_REGNUM))]
2300 return picochip_output_get_array (which_alternative, operands);
2303 ; Scalar Put instruction.
2304 (define_insn "commsPut"
2305 [(unspec_volatile [(match_operand:HI 0 "const_int_operand" "")
2306 (match_operand:SI 1 "register_operand" "r")]
2309 "PUT %R1,%0\t// PORT(%0) := %R1"
2310 [(set_attr "type" "comms")
2311 (set_attr "length" "2")])
2313 ; Entry point for array put. The operands accepted are:
2314 ; op0 - Value to put
2315 ; op1 - Requested port index
2316 ; op2 - size of port array
2317 ; op3 - base index of port array
2318 ; The arguments are marshalled into the fixed registers, so that
2319 ; the actual put instruction can expand into a call if necessary
2320 ; (e.g., if the index is variable at run-time).
2322 (define_expand "commsArrayPut"
2323 [(set (reg:SI 0) (match_operand:SI 0 "general_operand" ""))
2325 [(unspec_volatile [(match_operand:HI 1 "general_operand" "")
2326 (match_operand:HI 2 "immediate_operand" "")
2327 (match_operand:HI 3 "immediate_operand" "")]
2328 UNSPEC_CALL_PUT_ARRAY)
2330 (clobber (reg:HI LINK_REGNUM))])]
2334 ;; The actual array put instruction. When the array index is a constant,
2335 ;; an exact instruction may be generated. When the index is variable,
2336 ;; a call to a special function is generated. This code could be
2337 ;; split into individual RTL instructions, but it is so rarely
2338 ;; used, that we won't bother.
2339 (define_insn "*commsArrayPutInstruction"
2340 [(unspec_volatile [(match_operand:HI 0 "general_operand" "r,i")
2341 (match_operand:HI 1 "immediate_operand" "")
2342 (match_operand:HI 2 "immediate_operand" "")]
2343 UNSPEC_CALL_PUT_ARRAY)
2345 (clobber (reg:HI LINK_REGNUM))]
2348 return picochip_output_put_array (which_alternative, operands);
2351 ;; Scalar test port instruction.
2352 (define_insn "commsTestPort"
2353 [(set (match_operand:HI 0 "register_operand" "=r")
2354 (unspec_volatile:HI [(match_operand:HI 1 "const_int_operand" "")]
2356 (clobber (reg:CC CC_REGNUM))]
2358 "// %0 := TestPort(%1)\;TSTPORT %1\;COPYSW.0 %0\;AND.0 %0,8,%0"
2359 [(set_attr "length" "9")])
2361 ; Entry point for array tstport (the actual port index is computed as the
2362 ; sum of the index, and the base).
2365 ; op1 - Requested port index
2366 ; op2 - size of port array (constant)
2367 ; op3 - base index of port array (constant)
2369 (define_expand "commsArrayTestPort"
2371 [(set (match_operand:HI 0 "register_operand" "")
2372 (unspec_volatile:HI [(match_operand:HI 1 "general_operand" "")
2373 (match_operand:HI 2 "immediate_operand" "")
2374 (match_operand:HI 3 "immediate_operand" "")]
2375 UNSPEC_CALL_TESTPORT_ARRAY))
2376 (clobber (reg:HI LINK_REGNUM))])]
2380 ;; The actual array testport instruction. When the array index is a constant,
2381 ;; an exact instruction may be generated. When the index is variable,
2382 ;; a call to a special function is generated. This code could be
2383 ;; split into individual RTL instructions, but it is so rarely
2384 ;; used, that we won't bother.
2385 (define_insn "*commsArrayTestportInstruction"
2386 [(set (match_operand:HI 0 "register_operand" "=r,r")
2387 (unspec_volatile:HI [(match_operand:HI 1 "general_operand" "r,i")
2388 (match_operand:HI 2 "immediate_operand" "")
2389 (match_operand:HI 3 "immediate_operand" "")]
2390 UNSPEC_CALL_TESTPORT_ARRAY))
2391 (clobber (reg:HI LINK_REGNUM))]
2394 return picochip_output_testport_array (which_alternative, operands);
2397 ;; Merge a TSTPORT instruction with the branch to which it
2398 ;; relates. Often the TSTPORT function (generated by a built-in), is
2399 ;; used to control conditional execution. The normal sequence of
2400 ;; instructions would be:
2403 ;; AND temp, 0x0008, temp
2404 ;; SUB temp,0,discard
2406 ;; This can be made more efficient by detecting the special case where
2407 ;; the result of a TSTPORT is used to branch, to allow the following
2408 ;; RTL sequence to be generated instead:
2411 ;; A big saving in cycles and bytes!
2413 (define_insn_and_split "tstport_branch"
2416 (match_operator 0 "comparison_operator"
2417 [(unspec_volatile:HI
2418 [(match_operand:HI 1 "const_int_operand" "")]
2421 (label_ref (match_operand 2 "" ""))
2423 (clobber (reg:CC CC_REGNUM))]
2427 [(set (reg:CC CC_REGNUM)
2428 (unspec_volatile:CC [(match_dup 1)] UNSPEC_INTERNAL_TESTPORT))
2429 (parallel [(set (pc)
2431 (match_op_dup:HI 4 [(reg:CC CC_REGNUM) (const_int 0)])
2432 (label_ref (match_dup 2))
2434 (use (match_dup 3))])]
2436 /* Note that the sense of the branch is reversed, since we are
2437 * comparing flag != 0. */
2438 gcc_assert (GET_CODE(operands[0]) == NE || GET_CODE(operands[0]) == EQ);
2439 operands[4] = gen_rtx_fmt_ee(reverse_condition(GET_CODE(operands[0])),
2440 GET_MODE(operands[0]), XEXP(operands[0], 0), XEXP(operands[0], 1));
2441 operands[3] = GEN_INT (0);
2444 ;;============================================================================
2445 ;; Epilogue/Epilogue expansion.
2446 ;;============================================================================
2448 (define_expand "prologue"
2449 [(clobber (const_int 0))]
2452 picochip_expand_prologue ();
2456 (define_expand "epilogue"
2457 [(use (const_int 0))]
2460 picochip_expand_epilogue (FALSE);
2464 ;;============================================================================
2465 ;; Trap instruction. This is used to indicate an error. For the
2466 ;; picoChip processors this is handled by calling a HALT instruction,
2467 ;; which stops the processor.
2468 ;;============================================================================
2471 [(trap_if (const_int 1) (const_int 6))]
2474 [(set_attr "length" "2")])
2476 ;;============================================================================
2477 ;; Conditional copy instructions. Only equal/not-equal comparisons are
2478 ;; supported. All other types of comparison remain as branch
2480 ;;============================================================================
2482 ;; Define expand seems to consider the resulting two instructions to be
2483 ;; independent. It was moving the actual copy instruction further down
2484 ;; with a call instruction in between. The call was clobbering the CC
2485 ;; and hence the cond_copy was wrong. With a split, it works correctly.
2486 (define_expand "movhicc"
2487 [(set (reg:CC CC_REGNUM) (match_operand 1 "comparison_operator" ""))
2488 (parallel [(set (match_operand:HI 0 "register_operand" "=r,r")
2489 (if_then_else:HI (match_op_dup:HI 1 [(reg:CC CC_REGNUM) (const_int 0)])
2490 (match_operand:HI 2 "picochip_register_or_immediate_operand" "0,0")
2491 (match_operand:HI 3 "picochip_register_or_immediate_operand" "r,i")))
2492 (use (match_dup 4))])]
2494 {if (!picochip_check_conditional_copy (operands))
2496 operands[4] = GEN_INT(GET_CODE(operands[1]));
2499 ;; We dont do any checks here. But this pattern is used only when movhicc
2500 ;; was checked. Put a "use" clause to make sure.
2501 (define_insn "*conditional_copy"
2502 [(set (match_operand:HI 0 "register_operand" "=r,r")
2504 (match_operator:HI 4 "picochip_peephole_comparison_operator"
2505 [(reg:CC CC_REGNUM) (const_int 0)])
2506 (match_operand:HI 1 "picochip_register_or_immediate_operand" "0,0")
2507 (match_operand:HI 2 "picochip_register_or_immediate_operand" "r,i")))
2508 (use (match_operand:HI 3 "const_int_operand" ""))]
2512 gcc_assert (GET_CODE(operands[4]) == EQ || GET_CODE(operands[4]) == NE);
2513 /* Note that the comparison is reversed as the pattern matches
2514 the *else* part of the if_then_else */
2515 switch (GET_CODE(operands[4]))
2517 case EQ: return "COPYNE %2,%0\t// if (NE) %0 := %2";
2518 case NE: return "COPYEQ %2,%0\t// if (EQ) %0 := %2";
2523 [(set_attr "length" "2")
2524 (set_attr "type" "picoAlu,picoAlu")
2525 (set_attr "longConstant" "false,true")])
2527 ;; cmphi - This needs to be defined, to ensure that the conditional
2528 ;; move works properly (because the if-cvt code uses this pattern to
2529 ;; build the conditional move, even though normally we use cbranch to
2530 ;; directly generate the instructions).
2532 (define_expand "cmphi"
2533 [(match_operand:HI 0 "general_operand" "g")
2534 (match_operand:HI 1 "general_operand" "g")]
2538 ;;============================================================================
2539 ;; Branch patterns - needed for conditional moves. This is because
2540 ;; they result in the bcc_gen_fctn array being initialised with the
2541 ;; code to define_expand the following, and this in turn means that
2542 ;; when noce_emit_cmove is called, the correct pattern can be
2543 ;; generated, based upon the assumed presence of the following. The
2544 ;; following are never actually used, because the earlier cbranch
2545 ;; patterns take precendence.
2546 ;;============================================================================
2548 (define_expand "bne"
2551 (ne (reg:CC CC_REGNUM) (const_int 0))
2552 (label_ref (match_operand 0 "" ""))
2555 "gcc_unreachable();")
2557 (define_expand "beq"
2560 (eq (reg:CC CC_REGNUM) (const_int 0))
2561 (label_ref (match_operand 0 "" ""))
2564 "gcc_unreachable();")
2566 (define_expand "blt"
2569 (lt (reg:CC CC_REGNUM) (const_int 0))
2570 (label_ref (match_operand 0 "" ""))
2573 "gcc_unreachable();")
2575 (define_expand "bge"
2578 (ge (reg:CC CC_REGNUM) (const_int 0))
2579 (label_ref (match_operand 0 "" ""))
2582 "gcc_unreachable();")
2584 (define_expand "bgeu"
2587 (geu (reg:CC CC_REGNUM) (const_int 0))
2588 (label_ref (match_operand 0 "" ""))
2591 "gcc_unreachable();")
2593 (define_expand "bltu"
2596 (ltu (reg:CC CC_REGNUM) (const_int 0))
2597 (label_ref (match_operand 0 "" ""))
2600 "gcc_unreachable();")
2602 (define_expand "ble"
2605 (le (reg:CC CC_REGNUM) (const_int 0))
2606 (label_ref (match_operand 0 "" ""))
2609 "gcc_unreachable();")
2611 (define_expand "bgt"
2614 (gt (reg:CC CC_REGNUM) (const_int 0))
2615 (label_ref (match_operand 0 "" ""))
2618 "gcc_unreachable();")
2620 (define_expand "bleu"
2623 (leu (reg:CC CC_REGNUM) (const_int 0))
2624 (label_ref (match_operand 0 "" ""))
2627 "gcc_unreachable();")
2629 (define_expand "bgtu"
2632 (gtu (reg:CC CC_REGNUM) (const_int 0))
2633 (label_ref (match_operand 0 "" ""))
2636 "gcc_unreachable();")
2638 ;;============================================================================
2639 ;; Scheduling, including delay slot scheduling.
2640 ;;============================================================================
2642 (automata_option "v")
2643 (automata_option "ndfa")
2645 ;; Define each VLIW slot as a CPU resource. Note the three flavours of
2646 ;; branch. `realBranch' is an actual branch instruction. `macroBranch'
2647 ;; is a directive to the assembler, which may expand into multiple
2648 ;; instructions. `call' is an actual branch instruction, but one which
2649 ;; sets the link register, and hence can't be scheduled alongside
2650 ;; other instructions which set the link register. When the DFA
2651 ;; scheduler is fixed to prevent it scheduling a JL with an R12
2652 ;; setting register, the call type branches can be replaced by
2653 ;; realBranch types instead.
2656 "picoAlu,basicAlu,nonCcAlu,mem,call,realBranch,macroBranch,mul,mac,app,comms,unknown"
2657 (const_string "unknown"))
2659 (define_attr "schedType" "none,space,speed"
2660 (const (symbol_ref "picochip_schedule_type")))
2662 ;; Define whether an instruction uses a long constant.
2664 (define_attr "longConstant"
2665 "true,false" (const_string "false"))
2667 ;; Define three EU slots.
2668 (define_query_cpu_unit "slot0,slot1,slot2")
2670 ;; Pull in the pipeline descriptions for speed or space scheduling.
2671 (include "dfa_speed.md")
2672 (include "dfa_space.md")
2674 ; Unknown instructions are assumed to take a single cycle, and use all
2675 ; slots. This enables them to actually output a sequence of
2676 ; instructions without any limitation. For the purposes of
2677 ; scheduling, unknown instructions are a pain, and should be removed
2678 ; completely. This means that RTL patterns should always be used to
2679 ; reduce complex sequences of instructions to individual instructions.
2680 (define_insn_reservation "unknownInsn" 1
2681 (eq_attr "type" "unknown")
2682 "(slot0+slot1+slot2)")
2684 ; Allow any non-branch instructions to be placed in the branch
2685 ; slot. Branch slots are always executed.
2686 (define_delay (eq_attr "type" "realBranch,call")
2687 [(eq_attr "type" "!realBranch,macroBranch,call,unknown") (nil) (nil)])