]> git.ipfire.org Git - thirdparty/gcc.git/blob - gcc/config/dsp16xx/dsp16xx.md
Merge in gcc2-ss-010999
[thirdparty/gcc.git] / gcc / config / dsp16xx / dsp16xx.md
1 ;;- Machine description for the AT&T DSP1600 for GNU C compiler
2 ;; Copyright (C) 1994, 1995, 1997, 1998 Free Software Foundation, Inc.
3 ;; Contributed by Michael Collison (collison@world.std.com).
4
5 ;; This file is part of GNU CC.
6
7 ;; GNU CC is free software; you can redistribute it and/or modify
8 ;; it under the terms of the GNU General Public License as published by
9 ;; the Free Software Foundation; either version 2, or (at your option)
10 ;; any later version.
11
12 ;; GNU CC is distributed in the hope that it will be useful,
13 ;; but WITHOUT ANY WARRANTY; without even the implied warranty of
14 ;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15 ;; GNU General Public License for more details.
16
17 ;; You should have received a copy of the GNU General Public License
18 ;; along with GNU CC; see the file COPYING. If not, write to
19 ;; the Free Software Foundation, 59 Temple Place - Suite 330,
20 ;; Boston, MA 02111-1307, USA.
21
22
23 ;;- See file "rtl.def" for documentation on define_insn, match_*, et. al.
24 \f
25 ;; Attribute specifications
26
27 ; Type of each instruction. Default is arithmetic.
28 ; I'd like to write the list as this, but genattrtab won't accept it.
29 ;
30 ; "jump,cond_jump,call, ; flow-control instructions
31 ; load_i,load, store, move ; Y space address arithmetic instructions
32 ; malu,special,f3_alu,f3_alu_i ; data arithmetic unit instructions
33 ; shift_i,shift, bfield_i, bfield ; bit manipulation unit instructions
34 ; arith, ; integer unit instructions
35 ; nop
36
37 ; Classification of each insn. Some insns of TYPE_BRANCH are multi-word.
38 (define_attr "type"
39 "jump,cond_jump,call,load_i,load,move,store,malu,malu_mul,special,f3_alu,f3_alu_i,shift_i,shift,bfield_i,bfield,nop,ld_short_i"
40 (const_string "malu"))
41
42 ; Length in # of instructions of each insn. The values are not exact, but
43 ; are safe.
44 (define_attr "length" ""
45 (cond [(eq_attr "type" "cond_jump,f3_alu_i,shift_i,bfield_i,load_i")
46 (const_int 2)]
47 (const_int 1)))
48
49 \f
50 ;; ....................
51 ;;
52 ;; Test against 0 instructions
53 ;;
54 ;; ....................
55
56 (define_expand "tsthi"
57 [(set (cc0)
58 (match_operand:HI 0 "register_operand" ""))]
59 ""
60 "
61 {
62 dsp16xx_compare_gen = gen_tst_reg;
63 dsp16xx_compare_op0 = operands[0];
64 dsp16xx_compare_op1 = const0_rtx;
65 DONE;
66 }")
67
68 (define_insn "tsthi_1"
69 [(set (cc0)
70 (match_operand:HI 0 "register_operand" "A"))]
71 ""
72 "%0=%0"
73 [(set_attr "type" "malu")])
74
75 (define_expand "tstqi"
76 [(set (cc0)
77 (match_operand:QI 0 "register_operand" ""))]
78 ""
79 "
80 {
81 dsp16xx_compare_gen = gen_tst_reg;
82 dsp16xx_compare_op0 = operands[0];
83 dsp16xx_compare_op1 = const0_rtx;
84 DONE;
85 }")
86
87 (define_insn "tstqi_1"
88 [(set (cc0)
89 (match_operand:QI 0 "register_operand" "j,q"))
90 (clobber (match_scratch:QI 1 "=k,u"))]
91 ""
92 "@
93 %1=0\;%b0-0
94 %1=0\;%b0-0"
95 [(set_attr "type" "malu,malu")])
96
97 \f
98 ;;
99 ;; ....................
100 ;;
101 ;; Bit test instructions
102 ;;
103 ;; ....................
104
105 (define_insn ""
106 [(set (cc0)
107 (and:HI (match_operand:HI 0 "register_operand" "A,!A,A")
108 (match_operand:HI 1 "nonmemory_operand" "Z,A,I")))]
109 ""
110 "*
111 {
112 switch (which_alternative)
113 {
114 case 0:
115 case 1:
116 return \"%0&%1\";
117
118 case 2:
119 return \"%0&%H1\";
120 }
121 }"
122 [(set_attr "type" "f3_alu,malu,f3_alu_i")])
123
124
125 ;;(define_insn ""
126 ;; [(set (cc0)
127 ;; (and:QI (match_operand:QI 0 "register_operand" "h")
128 ;; (match_operand:QI 1 "const_int_operand" "I")))]
129 ;; ""
130 ;; "%b0&%H1"
131 ;; [(set_attr "type" "f3_alu_i")])
132 \f
133 ;;
134 ;;
135 ;; Compare Instructions
136 ;;
137
138 (define_expand "cmphi"
139 [(parallel [(set (cc0)
140 (compare (match_operand:HI 0 "general_operand" "")
141 (match_operand:HI 1 "general_operand" "")))
142 (clobber (match_scratch:QI 2 ""))
143 (clobber (match_scratch:QI 3 ""))
144 (clobber (match_scratch:QI 4 ""))
145 (clobber (match_scratch:QI 5 ""))])]
146 ""
147 "
148 {
149 if (GET_CODE (operands[1]) == CONST_INT)
150 operands[1] = force_reg (HImode, operands[1]);
151
152 dsp16xx_compare_gen = gen_compare_reg;
153 dsp16xx_compare_op0 = operands[0];
154 dsp16xx_compare_op1 = operands[1];
155 DONE;
156 }")
157
158 (define_insn ""
159 [(set (cc0)
160 (compare (match_operand:HI 0 "general_operand" "Z*r*m*i")
161 (match_operand:HI 1 "general_operand" "Z*r*m*i")))
162 (clobber (match_scratch:QI 2 "=&A"))
163 (clobber (match_scratch:QI 3 "=&A"))
164 (clobber (match_scratch:QI 4 "=&A"))
165 (clobber (match_scratch:QI 5 "=&A"))]
166 "next_cc_user_unsigned (insn)"
167 "*
168 {
169 if (GET_CODE(operands[0]) == REG)
170 {
171 if (REGNO (operands[0]) == REG_Y ||
172 REGNO (operands[0]) == REG_PROD)
173 {
174 output_asm_insn (\"a0=%0\", operands);
175 }
176 else if (IS_YBASE_REGISTER_WINDOW (REGNO(operands[0])))
177 {
178 output_asm_insn (\"a0=%u0\;a0l=%w0\", operands);
179 }
180 else
181 dsp16xx_invalid_register_for_compare ();
182 }
183 else if (GET_CODE(operands[0]) == CONST_INT)
184 {
185 output_asm_insn (\"a0=%U0\;a0l=%H0\", operands);
186 }
187 else if (GET_CODE (operands[0]) == MEM)
188 {
189 rtx xoperands[2];
190
191 xoperands[0] = gen_rtx_REG (HImode, REG_A0);
192 xoperands[1] = operands[0];
193 double_reg_from_memory (xoperands);
194 }
195
196 if (GET_CODE(operands[1]) == REG)
197 {
198 if (REGNO (operands[1]) == REG_Y
199 || REGNO (operands[1]) == REG_PROD)
200 {
201 output_asm_insn (\"a1=%1\", operands);
202 }
203 else if (IS_YBASE_REGISTER_WINDOW (REGNO(operands[1])))
204 {
205 output_asm_insn (\"a1=%u1\;a1l=%w1\", operands);
206 }
207 else
208 dsp16xx_invalid_register_for_compare ();
209 }
210 else if (GET_CODE (operands[1]) == MEM)
211 {
212 rtx xoperands[2];
213
214 xoperands[0] = gen_rtx_REG (HImode, REG_A1);
215 xoperands[1] = operands[1];
216 double_reg_from_memory (xoperands);
217 }
218 else if (GET_CODE(operands[1]) == CONST_INT)
219 {
220 output_asm_insn (\"a1=%U1\;a1l=%H1\", operands);
221 }
222
223 return \"psw = 0\;a0 - a1\";
224 }")
225
226 (define_insn ""
227 [(set (cc0) (compare (match_operand:HI 0 "register_operand" "A,!A")
228 (match_operand:HI 1 "register_operand" "Z,*A")))]
229 ""
230 "@
231 %0-%1
232 %0-%1"
233 [(set_attr "type" "malu,f3_alu")])
234
235 (define_expand "cmpqi"
236 [(parallel [(set (cc0)
237 (compare (match_operand:QI 0 "register_operand" "")
238 (match_operand:QI 1 "nonmemory_operand" "")))
239 (clobber (match_operand:QI 2 "register_operand" ""))
240 (clobber (match_operand:QI 3 "register_operand" ""))])]
241 ""
242 "
243 {
244 if (operands[0]) /* Avoid unused code warning */
245 {
246 dsp16xx_compare_gen = gen_compare_reg;
247 dsp16xx_compare_op0 = operands[0];
248 dsp16xx_compare_op1 = operands[1];
249 DONE;
250 }
251 }")
252
253 (define_insn ""
254 [(set (cc0) (compare (match_operand:QI 0 "register_operand" "k,k,!k,k,u,u,!u,u")
255 (match_operand:QI 1 "nonmemory_operand" "w,z,u,i,w,z,k,i")))
256 (clobber (match_scratch:QI 2 "=j,j,j,j,q,q,q,q"))
257 (clobber (match_scratch:QI 3 "=v,y,q,X,v,y,j,X"))]
258 "next_cc_user_unsigned (insn)"
259 "@
260 %2=0\;%3=0\;%2-%3
261 %2=0\;%3=0\;%2-%3
262 %2=0\;%3=0\;%2-%3
263 %2=0\;%0-%H1
264 %2=0\;%3=0\;%2-%3
265 %2=0\;%3=0\;%2-%3
266 %2=0\;%3=0\;%2-%3
267 %2=0\;%0-%H1")
268
269
270 (define_insn ""
271 [(set (cc0) (compare (match_operand:QI 0 "register_operand" "j,j,!j,j,q,q,!q,q")
272 (match_operand:QI 1 "nonmemory_operand" "v,y,q,i,v,y,j,i")))
273 (clobber (match_scratch:QI 2 "=k,k,k,k,u,u,u,u"))
274 (clobber (match_scratch:QI 3 "=w,z,u,X,w,z,k,X"))]
275 ""
276 "@
277 %2=0\;%3=0\;%0-%1
278 %2=0\;%3=0\;%0-%1
279 %2=0\;%3=0\;%0-%1
280 %2=0\;%b0-%H1
281 %2=0\;%3=0\;%0-%1
282 %2=0\;%3=0\;%0-%1
283 %2=0\;%3=0\;%0-%1
284 %2=0\;%b0-%H1")
285
286
287 (define_expand "cmphf"
288 [(set (cc0)
289 (compare (match_operand:HF 0 "register_operand" "")
290 (match_operand:HF 1 "nonmemory_operand" "")))]
291 ""
292 "
293 {
294 if (!dsp16xx_cmphf3_libcall)
295 dsp16xx_cmphf3_libcall = gen_rtx_SYMBOL_REF (Pmode, CMPHF3_LIBCALL);
296
297 dsp16xx_compare_gen = gen_compare_reg;
298 dsp16xx_compare_op0 = operands[0];
299 dsp16xx_compare_op1 = operands[1];
300 emit_library_call (dsp16xx_cmphf3_libcall, 1, HImode, 2,
301 operands[0], HFmode,
302 operands[1], HFmode);
303 emit_insn (gen_tsthi_1 (copy_to_reg(hard_libcall_value (HImode))));
304 DONE;
305 }")
306
307 \f
308 ;; ....................
309 ;;
310 ;; Add instructions
311 ;;
312 ;; ....................
313
314
315 (define_insn "addhi3"
316 [(set (match_operand:HI 0 "register_operand" "=A,A,A")
317 (plus:HI (match_operand:HI 1 "register_operand" "%A,A,A")
318 (match_operand:HI 2 "nonmemory_operand" "Z,d,i")))]
319 ""
320 "@
321 %0=%1+%2
322 %0=%1+%2
323 %0=%w1+%H2\;%0=%b0+%U2"
324 [(set_attr "type" "malu,malu,f3_alu_i")])
325
326 (define_insn ""
327 [(set (match_operand:QI 0 "register_operand" "=k,u,!k,!u")
328 (plus:QI (plus:QI (match_operand:QI 1 "register_operand" "uk,uk,uk,uk")
329 (match_operand:QI 2 "register_operand" "wz,wz,uk,uk"))
330 (match_operand:QI 3 "immediate_operand" "i,i,i,i")))
331 (clobber (match_scratch:QI 4 "=j,q,j,q"))]
332 ""
333 "@
334 %m0=%m1+%m2\;%m0=%0+%H3
335 %m0=%m1+%m2\;%m0=%0+%H3
336 %m0=%m1+%m2\;%m0=%0+%H3
337 %m0=%m1+%m2\;%m0=%0+%H3")
338
339 (define_expand "addqi3"
340 [(parallel [(set (match_operand:QI 0 "register_operand" "")
341 (plus:QI (match_operand:QI 1 "register_operand" "")
342 (match_operand:QI 2 "nonmemory_operand" "")))
343 (clobber (match_scratch:QI 3 ""))])]
344 ""
345 "
346 {
347 if (reload_in_progress)
348 {
349 if (REG_P (operands[1]) &&
350 (REGNO(operands[1]) == STACK_POINTER_REGNUM ||
351 REGNO(operands[1]) == FRAME_POINTER_REGNUM) &&
352 GET_CODE (operands[2]) == CONST_INT)
353 {
354 if (REG_P (operands[0]) && IS_ACCUM_REG(REGNO(operands[0])))
355 emit_move_insn (operands[0], operands[1]);
356
357 operands[1] = operands[0];
358 }
359 }
360 }")
361
362
363 (define_insn "match_addqi3"
364 [(set (match_operand:QI 0 "register_operand" "=!a,!a,k,u,!k,!u,h,!a")
365 (plus:QI (match_operand:QI 1 "register_operand" "0,0,uk,uk,uk,uk,h,0")
366 (match_operand:QI 2 "nonmemory_operand" "W,N,wzi,wzi,uk,uk,i,n")))
367 (clobber (match_scratch:QI 3 "=X,X,j,q,j,q,X,W"))]
368 ""
369 "*
370 {
371 switch (which_alternative)
372 {
373 case 0:
374 return \"*%0++%2\";
375
376 case 1:
377 switch (INTVAL (operands[2]))
378 {
379 case -1:
380 return \"*%0--\";
381
382 case 1:
383 return \"*%0++\";
384
385 case -2:
386 return \"*%0--\;*%0--\";
387
388 case 2:
389 return \"*%0++\;*%0++\";
390 }
391
392 case 2:
393 case 3:
394 if (!CONSTANT_P(operands[2]))
395 return \"%m0=%m1+%m2\";
396 else
397 return \"%m0=%1+%H2\";
398
399 case 4:
400 case 5:
401 return \"%m0=%m1+%m2\";
402
403 case 6:
404 return \"%0=%b1+%H2\";
405
406 case 7:
407 return \"%3=%2\;*%0++%3\";
408 }
409 }")
410
411 (define_expand "addhf3"
412 [(set (match_operand:HF 0 "register_operand" "")
413 (plus:HF (match_operand:HF 1 "register_operand" "")
414 (match_operand:HF 2 "nonmemory_operand" "")))]
415 ""
416 "
417 {
418 if (!dsp16xx_addhf3_libcall)
419 dsp16xx_addhf3_libcall = gen_rtx_SYMBOL_REF (Pmode, ADDHF3_LIBCALL);
420
421 emit_library_call (dsp16xx_addhf3_libcall, 1, HFmode, 2,
422 operands[1], HFmode,
423 operands[2], HFmode);
424 emit_move_insn (operands[0], hard_libcall_value(HFmode));
425 DONE;
426 }")
427
428 \f
429 ;;
430 ;; ....................
431 ;;
432 ;; Subtract instructions
433 ;;
434 ;; ....................
435
436 (define_insn "subhi3"
437 [(set (match_operand:HI 0 "register_operand" "=A,A,A")
438 (minus:HI (match_operand:HI 1 "register_operand" "A,A,A")
439 (match_operand:HI 2 "nonmemory_operand" "Z,d,i")))]
440 ""
441 "@
442 %0=%1-%2
443 %0=%1-%2
444 %0=%w1-%H2\;%0=%b0-%U2"
445 [(set_attr "type" "malu,malu,f3_alu_i")])
446
447 (define_insn "subqi3"
448 [(set (match_operand:QI 0 "register_operand" "=?*a,k,u,!k,!u")
449 (minus:QI (match_operand:QI 1 "register_operand" "0,uk,uk,uk,uk")
450 (match_operand:QI 2 "nonmemory_operand" "n,wzi,wzi,uk,uk")))
451 (clobber (match_scratch:QI 3 "=W,j,q,j,q"))]
452 ""
453 "*
454 {
455 switch (which_alternative)
456 {
457 case 0:
458 switch (INTVAL (operands[2]))
459 {
460 case 0:
461 return \"\";
462
463 case 1:
464 return \"*%0--\";
465
466 case -1:
467 return \"*%0++\";
468
469 default:
470 operands[2] = GEN_INT (-INTVAL (operands[2]));
471
472 if (SHORT_IMMEDIATE(operands[2]))
473 return \"set %3=%H2\;*%0++%3\";
474 else
475 return \"%3=%H2\;*%0++%3\";
476 }
477
478 case 1:
479 case 2:
480 if (!CONSTANT_P(operands[2]))
481 return \"%m0=%m1-%m2\";
482 else
483 return \"%m0=%1-%H2\";
484
485 case 3:
486 case 4:
487 return \"%m0=%m1-%m2\";
488 }
489 }")
490
491 (define_expand "subhf3"
492 [(set (match_operand:HF 0 "register_operand" "")
493 (minus:HF (match_operand:HF 1 "register_operand" "")
494 (match_operand:HF 2 "nonmemory_operand" "")))]
495 ""
496 "
497 {
498 if (!dsp16xx_subhf3_libcall)
499 dsp16xx_subhf3_libcall = gen_rtx_SYMBOL_REF (Pmode, SUBHF3_LIBCALL);
500
501 emit_library_call (dsp16xx_subhf3_libcall, 1, HFmode, 2,
502 operands[1], HFmode,
503 operands[2], HFmode);
504 emit_move_insn (operands[0], hard_libcall_value(HFmode));
505 DONE;
506 }")
507
508 (define_insn "neghi2"
509 [(set (match_operand:HI 0 "register_operand" "=A")
510 (neg:HI (match_operand:HI 1 "register_operand" "A")))]
511 ""
512 "%0=-%1"
513 [(set_attr "type" "special")])
514
515 (define_expand "neghf2"
516 [(set (match_operand:HF 0 "general_operand" "")
517 (neg:HF (match_operand:HF 1 "general_operand" "")))]
518 ""
519 "
520 {
521 if (!dsp16xx_neghf2_libcall)
522 dsp16xx_neghf2_libcall = gen_rtx_SYMBOL_REF (Pmode, NEGHF2_LIBCALL);
523
524 emit_library_call (dsp16xx_neghf2_libcall, 1, HFmode, 1,
525 operands[1], HFmode);
526 emit_move_insn (operands[0], hard_libcall_value(HFmode));
527 DONE;
528 }")
529
530
531
532 ;;
533 ;; ....................
534 ;;
535 ;; Multiply instructions
536 ;;
537
538 (define_expand "mulhi3"
539 [(set (match_operand:HI 0 "register_operand" "")
540 (mult:HI (match_operand:HI 1 "register_operand" "")
541 (match_operand:HI 2 "nonmemory_operand" "")))]
542 ""
543 "
544 {
545 if (!dsp16xx_mulhi3_libcall)
546 dsp16xx_mulhi3_libcall = gen_rtx_SYMBOL_REF (Pmode, MULHI3_LIBCALL);
547
548 emit_library_call (dsp16xx_mulhi3_libcall, 1, HImode, 2,
549 operands[1], HImode,
550 operands[2], HImode);
551 emit_move_insn (operands[0], hard_libcall_value(HImode));
552 DONE;
553 }")
554
555 (define_insn "mulqi3"
556 [(set (match_operand:QI 0 "register_operand" "=w")
557 (mult:QI (match_operand:QI 1 "register_operand" "%x")
558 (match_operand:QI 2 "register_operand" "y")))
559 (clobber (match_scratch:QI 3 "=v"))]
560 ""
561 "%m0=%1*%2"
562 [(set_attr "type" "malu_mul")])
563
564 (define_insn "mulqihi3"
565 [(set (match_operand:HI 0 "register_operand" "=t")
566 (mult:HI (sign_extend:HI (match_operand:QI 1 "register_operand" "%x"))
567 (sign_extend:HI (match_operand:QI 2 "register_operand" "y"))))]
568 ""
569 "%0=%1*%2"
570 [(set_attr "type" "malu_mul")])
571
572 (define_insn "umulqihi3"
573 [(set (match_operand:HI 0 "register_operand" "=t")
574 (mult:HI (zero_extend:HI (match_operand:QI 1 "register_operand" "%x"))
575 (zero_extend:HI (match_operand:QI 2 "register_operand" "y"))))]
576 ""
577 "%0=%1*%2"
578 [(set_attr "type" "malu_mul")])
579
580 (define_expand "mulhf3"
581 [(set (match_operand:HF 0 "register_operand" "")
582 (mult:HF (match_operand:HF 1 "register_operand" "")
583 (match_operand:HF 2 "nonmemory_operand" "")))]
584 ""
585 "
586 {
587 if (!dsp16xx_mulhf3_libcall)
588 dsp16xx_mulhf3_libcall = gen_rtx_SYMBOL_REF (Pmode, MULHF3_LIBCALL);
589
590 emit_library_call (dsp16xx_mulhf3_libcall, 1, HFmode, 2,
591 operands[1], HFmode,
592 operands[2], HFmode);
593 emit_move_insn (operands[0], hard_libcall_value(HFmode));
594 DONE;
595 }")
596
597 \f
598
599 ;;
600 ;; *******************
601 ;;
602 ;; Divide Instructions
603 ;;
604
605 (define_expand "divhi3"
606 [(set (match_operand:HI 0 "register_operand" "")
607 (div:HI (match_operand:HI 1 "register_operand" "")
608 (match_operand:HI 2 "nonmemory_operand" "")))]
609 ""
610 "
611 {
612 if (!dsp16xx_divhi3_libcall)
613 dsp16xx_divhi3_libcall = gen_rtx_SYMBOL_REF (Pmode, DIVHI3_LIBCALL);
614
615 emit_library_call (dsp16xx_divhi3_libcall, 1, HImode, 2,
616 operands[1], HImode,
617 operands[2], HImode);
618 emit_move_insn (operands[0], hard_libcall_value(HImode));
619 DONE;
620 }")
621
622 (define_expand "udivhi3"
623 [(set (match_operand:HI 0 "register_operand" "")
624 (udiv:HI (match_operand:HI 1 "register_operand" "")
625 (match_operand:HI 2 "nonmemory_operand" "")))]
626 ""
627 "
628 {
629 if (!dsp16xx_udivhi3_libcall)
630 dsp16xx_udivhi3_libcall = gen_rtx_SYMBOL_REF (Pmode, UDIVHI3_LIBCALL);
631
632 emit_library_call (dsp16xx_udivhi3_libcall, 1, HImode, 2,
633 operands[1], HImode,
634 operands[2], HImode);
635 emit_move_insn (operands[0], hard_libcall_value(HImode));
636 DONE;
637 }")
638
639 (define_expand "divqi3"
640 [(set (match_operand:QI 0 "register_operand" "")
641 (div:QI (match_operand:QI 1 "register_operand" "")
642 (match_operand:QI 2 "nonmemory_operand" "")))]
643 ""
644 "
645 {
646 if (!dsp16xx_divqi3_libcall)
647 dsp16xx_divqi3_libcall = gen_rtx_SYMBOL_REF (Pmode, DIVQI3_LIBCALL);
648
649 emit_library_call (dsp16xx_divqi3_libcall, 1, QImode, 2,
650 operands[1], QImode,
651 operands[2], QImode);
652 emit_move_insn (operands[0], hard_libcall_value(QImode));
653 DONE;
654 }")
655
656 (define_expand "udivqi3"
657 [(set (match_operand:QI 0 "register_operand" "")
658 (udiv:QI (match_operand:QI 1 "register_operand" "")
659 (match_operand:QI 2 "nonmemory_operand" "")))]
660 ""
661 "
662 {
663 if (!dsp16xx_udivqi3_libcall)
664 dsp16xx_udivqi3_libcall = gen_rtx_SYMBOL_REF (Pmode, UDIVQI3_LIBCALL);
665
666 emit_library_call (dsp16xx_udivqi3_libcall, 1, QImode, 2,
667 operands[1], QImode,
668 operands[2], QImode);
669 emit_move_insn (operands[0], hard_libcall_value(QImode));
670 DONE;
671 }")
672 \f
673 ;;
674 ;; ....................
675 ;;
676 ;; Modulo instructions
677 ;;
678 ;; ....................
679
680 (define_expand "modhi3"
681 [(set (match_operand:HI 0 "register_operand" "")
682 (mod:HI (match_operand:HI 1 "register_operand" "")
683 (match_operand:HI 2 "nonmemory_operand" "")))]
684 ""
685 "
686 {
687 if (!dsp16xx_modhi3_libcall)
688 dsp16xx_modhi3_libcall = gen_rtx_SYMBOL_REF (Pmode, MODHI3_LIBCALL);
689
690 emit_library_call (dsp16xx_modhi3_libcall, 1, HImode, 2,
691 operands[1], HImode,
692 operands[2], HImode);
693 emit_move_insn (operands[0], hard_libcall_value(HImode));
694 DONE;
695 }")
696
697 (define_expand "umodhi3"
698 [(set (match_operand:HI 0 "register_operand" "")
699 (umod:HI (match_operand:HI 1 "register_operand" "")
700 (match_operand:HI 2 "nonmemory_operand" "")))]
701 ""
702 "
703 {
704 if (!dsp16xx_umodhi3_libcall)
705 dsp16xx_umodhi3_libcall = gen_rtx_SYMBOL_REF (Pmode, UMODHI3_LIBCALL);
706
707 emit_library_call (dsp16xx_umodhi3_libcall, 1, HImode, 2,
708 operands[1], HImode,
709 operands[2], HImode);
710 emit_move_insn (operands[0], hard_libcall_value(HImode));
711 DONE;
712 }")
713
714 (define_expand "modqi3"
715 [(set (match_operand:QI 0 "register_operand" "")
716 (mod:QI (match_operand:QI 1 "register_operand" "")
717 (match_operand:QI 2 "nonmemory_operand" "")))]
718 ""
719 "
720 {
721 if (!dsp16xx_modqi3_libcall)
722 dsp16xx_modqi3_libcall = gen_rtx_SYMBOL_REF (Pmode, MODQI3_LIBCALL);
723
724 emit_library_call (dsp16xx_modqi3_libcall, 1, QImode, 2,
725 operands[1], QImode,
726 operands[2], QImode);
727 emit_move_insn (operands[0], hard_libcall_value(QImode));
728 DONE;
729 }")
730
731 (define_expand "umodqi3"
732 [(set (match_operand:QI 0 "register_operand" "")
733 (umod:QI (match_operand:QI 1 "register_operand" "")
734 (match_operand:QI 2 "nonmemory_operand" "")))]
735 ""
736 "
737 {
738 if (!dsp16xx_umodqi3_libcall)
739 dsp16xx_umodqi3_libcall = gen_rtx_SYMBOL_REF (Pmode, UMODQI3_LIBCALL);
740
741 emit_library_call (dsp16xx_umodqi3_libcall, 1, QImode, 2,
742 operands[1], QImode,
743 operands[2], QImode);
744 emit_move_insn (operands[0], hard_libcall_value(QImode));
745 DONE;
746 }")
747
748 (define_expand "divhf3"
749 [(set (match_operand:HF 0 "register_operand" "")
750 (div:HF (match_operand:HF 1 "register_operand" "")
751 (match_operand:HF 2 "nonmemory_operand" "")))]
752 ""
753 "
754 {
755 if (!dsp16xx_divhf3_libcall)
756 dsp16xx_divhf3_libcall = gen_rtx_SYMBOL_REF (Pmode, DIVHF3_LIBCALL);
757
758 emit_library_call (dsp16xx_divhf3_libcall, 1, HFmode, 2,
759 operands[1], HFmode,
760 operands[2], HFmode);
761 emit_move_insn (operands[0], hard_libcall_value(HFmode));
762 DONE;
763 }")
764
765 \f
766
767 ;;
768 ;; ********************
769 ;;
770 ;; Logical Instructions
771 ;;
772
773 (define_insn "andhi3"
774 [(set (match_operand:HI 0 "register_operand" "=A,A,?A")
775 (and:HI (match_operand:HI 1 "register_operand" "%A,!A,A")
776 (match_operand:HI 2 "nonmemory_operand" "Z,A,i")))]
777 ""
778 "@
779 %0=%1&%2
780 %0=%1&%2
781 %0=%w1&%H2\;%0=%b0&%U2"
782 [(set_attr "type" "f3_alu,f3_alu,f3_alu_i")])
783
784 (define_insn "andqi3"
785 [(set (match_operand:QI 0 "register_operand" "=k,u,uk,!k,!u,j,q,jq,!j,!q")
786 (and:QI (match_operand:QI 1 "register_operand" "uk,uk,uk,uk,uk,jq,jq,jq,jq,jq")
787 (match_operand:QI 2 "nonmemory_operand" "wz,wz,i,uk,uk,yv,yv,i,jq,jq")))
788 (clobber (match_scratch:QI 3 "=j,q,X,j,q,k,u,X,k,u"))]
789 ""
790 "@
791 %m0=%m1&%m2
792 %m0=%m1&%m2
793 %m0=%1&%H2
794 %m0=%m1&%m2
795 %m0=%m1&%m2
796 %m0=%m1&%m2
797 %m0=%m1&%m2
798 %m0=%b1&%H2
799 %m0=%m1&%m2
800 %m0=%m1&%m2")
801
802 (define_insn "iorhi3"
803 [(set (match_operand:HI 0 "register_operand" "=A,A,A,?A")
804 (ior:HI (match_operand:HI 1 "register_operand" "%A,!A,A,A")
805 (match_operand:HI 2 "nonmemory_operand" "Z,A,I,i")))]
806 ""
807 "@
808 %0=%u1|%u2
809 %0=%u1|%u2
810 %0=%w1|%H2
811 %0=%w1|%H2\;%0=%b0|%U2"
812 [(set_attr "type" "f3_alu,f3_alu,f3_alu_i,f3_alu_i")])
813
814 (define_insn "iorqi3"
815 [(set (match_operand:QI 0 "register_operand" "=k,u,uk,!k,!u,j,q,jq,!j,!q")
816 (ior:QI (match_operand:QI 1 "register_operand" "uk,uk,uk,uk,uk,jq,jq,jq,jq,jq")
817 (match_operand:QI 2 "nonmemory_operand" "wz,wz,i,uk,uk,yv,yv,i,jq,jq")))
818 (clobber (match_scratch:QI 3 "=j,q,X,j,q,k,u,X,k,u"))]
819 ""
820 "@
821 %m0=%m1|%m2
822 %m0=%m1|%m2
823 %m0=%1|%H2
824 %m0=%m1|%m2
825 %m0=%m1|%m2
826 %m0=%m1|%m2
827 %m0=%m1|%m2
828 %m0=%b1|%H2
829 %m0=%m1|%m2
830 %m0=%m1|%m2")
831
832 (define_insn "xorhi3"
833 [(set (match_operand:HI 0 "register_operand" "=A,A,A,?A")
834 (xor:HI (match_operand:HI 1 "register_operand" "%A,!A,A,A")
835 (match_operand:HI 2 "nonmemory_operand" "Z,A,I,i")))]
836 ""
837 "@
838 %0=%1^%2
839 %0=%1^%2
840 %0=%w1^%H2
841 %0=%w1^%H2\;%0=%b0^%U2"
842 [(set_attr "type" "f3_alu,f3_alu,f3_alu_i,f3_alu_i")])
843
844 (define_insn "xorqi3"
845 [(set (match_operand:QI 0 "register_operand" "=k,u,uk,!k,!u,j,q,jq,!j,!q")
846 (xor:QI (match_operand:QI 1 "register_operand" "uk,uk,uk,uk,uk,jq,jq,jq,jq,jq")
847 (match_operand:QI 2 "nonmemory_operand" "wz,wz,i,uk,uk,yv,yv,i,jq,jq")))
848 (clobber (match_scratch:QI 3 "=j,q,X,j,q,k,u,X,k,u"))]
849 ""
850 "@
851 %m0=%m1^%m2
852 %m0=%m1^%m2
853 %m0=%1^%H2
854 %m0=%m1^%m2
855 %m0=%m1^%m2
856 %m0=%m1^%m2
857 %m0=%m1^%m2
858 %m0=%b1^%H2
859 %m0=%m1^%m2
860 %m0=%m1^%m2")
861
862 (define_insn "one_cmplhi2"
863 [(set (match_operand:HI 0 "register_operand" "=A")
864 (not:HI (match_operand:HI 1 "register_operand" "A")))]
865 ""
866 "%0= ~%1"
867 [(set_attr "type" "special")])
868
869 (define_insn "one_cmplqi2"
870 [(set (match_operand:QI 0 "register_operand" "=ku,jq")
871 (not:QI (match_operand:QI 1 "register_operand" "ku,jq")))]
872 ""
873 "@
874 %m0= %1 ^ 0xffff
875 %m0= %b1 ^ 0xffff"
876 [(set_attr "type" "special")])
877
878 \f
879 ;;
880 ;; MOVE INSTRUCTIONS
881 ;;
882
883 (define_expand "movhi"
884 [(set (match_operand:HI 0 "general_operand" "")
885 (match_operand:HI 1 "general_operand" ""))]
886 ""
887 "
888 {
889 if (emit_move_sequence (operands, HImode))
890 DONE;
891 }")
892
893
894 (define_insn "match_movhi1"
895 [(set (match_operand:HI 0 "nonimmediate_operand" "=A,Z,A,d,d,m,?d,*Y,t,f")
896 (match_operand:HI 1 "general_operand" "d,A,K,i,m,d,*Y,?d,t,f"))]
897 "register_operand(operands[0], HImode)
898 || register_operand(operands[1], HImode)"
899 "*
900 {
901 switch (which_alternative)
902 {
903 /* register to accumulator */
904 case 0:
905 return \"%0=%1\";
906 case 1:
907 return \"%u0=%u1\;%w0=%w1\";
908 case 2:
909 return \"%0=%0^%0\";
910 case 3:
911 return \"%u0=%U1\;%w0=%H1\";
912 case 4:
913 double_reg_from_memory(operands);
914 return \"\";
915 case 5:
916 double_reg_to_memory(operands);
917 return \"\";
918 case 6:
919 case 7:
920 return \"%u0=%u1\;%w0=%w1\";
921 case 8:
922 case 9:
923 return \"\";
924 }
925 }"
926 [(set_attr "type" "move,move,load_i,load_i,load,store,load,store,move,move")])
927
928
929 ;; NOTE: It is cheaper to do 'y = *r0', than 'r0 = *r0'.
930
931 (define_expand "movqi"
932 [(set (match_operand:QI 0 "nonimmediate_operand" "")
933 (match_operand:QI 1 "general_operand" ""))]
934 ""
935 "
936 {
937 if (emit_move_sequence (operands, QImode))
938 DONE;
939 }")
940
941 ;; The movqi pattern with the parallel is used for addqi insns (which have a parallel)
942 ;; that are turned into moveqi insns by the flow phase. This happens when a auto-increment
943 ;; is detected.
944
945 (define_insn "match_movqi1"
946 [(parallel [(set (match_operand:QI 0 "nonimmediate_operand" "=A,r,aW,c,?D,m<>,e,Y,r,xyz,m<>")
947 (match_operand:QI 1 "general_operand" "r,A,J,i,m<>,D,Y,e,0,m<>,xyz"))
948 (clobber (match_scratch:QI 2 "=X,X,X,X,X,X,X,X,X,X,X"))])]
949 "register_operand(operands[0], QImode)
950 || register_operand(operands[1], QImode)"
951 "*
952 {
953 switch (which_alternative)
954 {
955 case 0:
956 /* We have to use the move mnemonic otherwise the 1610 will
957 attempt to transfer all 32-bits of 'y', 'p' or an accumulator
958 , which we don't want */
959 if (REGNO(operands[1]) == REG_Y || REGNO(operands[1]) == REG_PROD
960 || IS_ACCUM_REG(REGNO(operands[1])))
961 return \"move %0=%1\";
962 else
963 return \"%0=%1\";
964
965 case 1:
966 return \"%0=%1\";
967
968 case 2:
969 return \"set %0=%H1\";
970
971 case 3:
972 return \"%0=%H1\";
973
974 case 4:
975 return \"%0=%1\";
976
977 case 5:
978 case 6:
979 return \"%0=%1\";
980
981 case 7:
982 return \"%0=%1\";
983
984 case 8:
985 return \"\";
986
987 case 9: case 10:
988 return \"%0=%1\";
989 }
990 }")
991
992 (define_insn "match_movqi2"
993 [(set (match_operand:QI 0 "nonimmediate_operand" "=A,r,aW,c,?D,m<>,e,Y,r,xyz,m<>")
994 (match_operand:QI 1 "general_operand" "r,A,J,i,m<>,D,Y,e,0,m<>,xyz"))]
995 "register_operand(operands[0], QImode)
996 || register_operand(operands[1], QImode)"
997 "*
998 {
999 switch (which_alternative)
1000 {
1001 case 0:
1002 /* We have to use the move mnemonic otherwise the 1610 will
1003 attempt to transfer all 32-bits of 'y', 'p' or an accumulator
1004 , which we don't want */
1005 if (REGNO(operands[1]) == REG_Y || REGNO(operands[1]) == REG_PROD
1006 || IS_ACCUM_REG(REGNO(operands[1])))
1007 return \"move %0=%1\";
1008 else
1009 return \"%0=%1\";
1010
1011 case 1:
1012 return \"%0=%1\";
1013
1014 case 2:
1015 return \"set %0=%H1\";
1016
1017 case 3:
1018 return \"%0=%H1\";
1019
1020 case 4:
1021 return \"%0=%1\";
1022
1023 case 5:
1024 case 6:
1025 return \"%0=%1\";
1026
1027 case 7:
1028 return \"%0=%1\";
1029
1030 case 8:
1031 return \"\";
1032
1033 case 9: case 10:
1034 return \"%0=%1\";
1035 }
1036 }")
1037
1038 (define_expand "reload_inqi"
1039 [(set (match_operand:QI 0 "register_operand" "=u")
1040 (match_operand:QI 1 "sp_operand" ""))
1041 (clobber (match_operand:QI 2 "register_operand" "=&q"))]
1042 ""
1043 "
1044 {
1045 rtx addr_reg = XEXP (operands[1], 0);
1046 rtx offset = XEXP (operands[1], 1);
1047
1048 /* First, move the frame or stack pointer to the accumulator */
1049 emit_move_insn (operands[0], addr_reg);
1050
1051 /* Then generate the add insn */
1052 emit_insn (gen_rtx_PARALLEL
1053 (VOIDmode,
1054 gen_rtvec (2,
1055 gen_rtx_SET (VOIDmode, operands[0],
1056 gen_rtx_PLUS (QImode, operands[0],
1057 offset)),
1058 gen_rtx_CLOBBER (VOIDmode, operands[2]))));
1059 DONE;
1060 }")
1061
1062 (define_expand "reload_inhi"
1063 [(set (match_operand:HI 0 "register_operand" "=r")
1064 (match_operand:HI 1 "register_operand" "r"))
1065 (clobber (match_operand:QI 2 "register_operand" "=&h"))]
1066 ""
1067 "
1068 {
1069 /* Check for an overlap of operand 2 (an accumulator) with
1070 the msw of operand 0. If we have an overlap we must reverse
1071 the order of the moves. */
1072
1073 if (REGNO(operands[2]) == REGNO(operands[0]))
1074 {
1075 emit_move_insn (operands[2], operand_subword (operands[1], 1, 0, HImode));
1076 emit_move_insn (operand_subword (operands[0], 1, 0, HImode), operands[2]);
1077 emit_move_insn (operands[2], operand_subword (operands[1], 0, 0, HImode));
1078 emit_move_insn (operand_subword (operands[0], 0, 0, HImode), operands[2]);
1079 }
1080 else
1081 {
1082 emit_move_insn (operands[2], operand_subword (operands[1], 0, 0, HImode));
1083 emit_move_insn (operand_subword (operands[0], 0, 0, HImode), operands[2]);
1084 emit_move_insn (operands[2], operand_subword (operands[1], 1, 0, HImode));
1085 emit_move_insn (operand_subword (operands[0], 1, 0, HImode), operands[2]);
1086 }
1087
1088 DONE;
1089 }")
1090
1091
1092 (define_expand "reload_outhi"
1093 [(set (match_operand:HI 0 "register_operand" "=r")
1094 (match_operand:HI 1 "register_operand" "r"))
1095 (clobber (match_operand:QI 2 "register_operand" "=&h"))]
1096 ""
1097 "
1098 {
1099 emit_move_insn (operands[2], operand_subword (operands[1], 0, 0, HImode));
1100 emit_move_insn (operand_subword (operands[0], 0, 0, HImode), operands[2]);
1101 emit_move_insn (operands[2], operand_subword (operands[1], 1, 0, HImode));
1102 emit_move_insn (operand_subword (operands[0], 1, 0, HImode), operands[2]);
1103 DONE;
1104 }")
1105
1106 (define_expand "movstrqi"
1107 [(parallel [(set (match_operand:BLK 0 "memory_operand" "")
1108 (match_operand:BLK 1 "memory_operand" ""))
1109 (use (match_operand:QI 2 "const_int_operand" ""))
1110 (use (match_operand:QI 3 "const_int_operand" ""))
1111 (clobber (match_scratch:QI 4 ""))
1112 (clobber (match_dup 5))
1113 (clobber (match_dup 6))])]
1114 ""
1115 "
1116 {
1117 rtx addr0, addr1;
1118
1119 if (GET_CODE (operands[2]) != CONST_INT)
1120 FAIL;
1121
1122 if (INTVAL(operands[2]) > 127)
1123 FAIL;
1124
1125 addr0 = copy_to_mode_reg (Pmode, XEXP (operands[0], 0));
1126 addr1 = copy_to_mode_reg (Pmode, XEXP (operands[1], 0));
1127
1128 operands[5] = addr0;
1129 operands[6] = addr1;
1130
1131 operands[0] = change_address (operands[0], VOIDmode, addr0);
1132 operands[1] = change_address (operands[1], VOIDmode, addr1);
1133 }")
1134
1135 (define_insn ""
1136 [(set (mem:BLK (match_operand:QI 0 "register_operand" "a"))
1137 (mem:BLK (match_operand:QI 1 "register_operand" "a")))
1138 (use (match_operand:QI 2 "const_int_operand" "n"))
1139 (use (match_operand:QI 3 "immediate_operand" "i"))
1140 (clobber (match_scratch:QI 4 "=x"))
1141 (clobber (match_dup 0))
1142 (clobber (match_dup 1))]
1143 ""
1144 "*
1145 { return output_block_move (operands); }")
1146
1147 \f
1148 ;; Floating point move insns
1149
1150
1151 (define_expand "movhf"
1152 [(set (match_operand:HF 0 "general_operand" "")
1153 (match_operand:HF 1 "general_operand" ""))]
1154 ""
1155 "
1156 {
1157 if (emit_move_sequence (operands, HFmode))
1158 DONE;
1159 }")
1160
1161 (define_insn "match_movhf"
1162 [(set (match_operand:HF 0 "nonimmediate_operand" "=A,Z,d,d,m,d,Y")
1163 (match_operand:HF 1 "general_operand" "d,A,F,m,d,Y,d"))]
1164 ""
1165 "*
1166 {
1167 /* NOTE: When loading the register 16 bits at a time we
1168 MUST load the high half FIRST (because the 1610 zeros
1169 the low half) and then load the low half */
1170
1171 switch (which_alternative)
1172 {
1173 /* register to accumulator */
1174 case 0:
1175 return \"%0=%1\";
1176 case 1:
1177 return \"%u0=%u1\;%w0=%w1\";
1178 case 2:
1179 output_dsp16xx_float_const(operands);
1180 return \"\";
1181 case 3:
1182 double_reg_from_memory(operands);
1183 return \"\";
1184 case 4:
1185 double_reg_to_memory(operands);
1186 return \"\";
1187 case 5:
1188 case 6:
1189 return \"%u0=%u1\;%w0=%w1\";
1190 }
1191 }"
1192 [(set_attr "type" "move,move,load_i,load,store,load,store")])
1193
1194
1195
1196 (define_expand "reload_inhf"
1197 [(set (match_operand:HF 0 "register_operand" "=r")
1198 (match_operand:HF 1 "register_operand" "r"))
1199 (clobber (match_operand:QI 2 "register_operand" "=&h"))]
1200 ""
1201 "
1202 {
1203 /* Check for an overlap of operand 2 (an accumulator) with
1204 the msw of operand 0. If we have an overlap we must reverse
1205 the order of the moves. */
1206
1207 if (REGNO(operands[2]) == REGNO(operands[0]))
1208 {
1209 emit_move_insn (operands[2], operand_subword (operands[1], 1, 0, HFmode));
1210 emit_move_insn (operand_subword (operands[0], 1, 0, HFmode), operands[2]);
1211 emit_move_insn (operands[2], operand_subword (operands[1], 0, 0, HFmode));
1212 emit_move_insn (operand_subword (operands[0], 0, 0, HFmode), operands[2]);
1213 }
1214 else
1215 {
1216 emit_move_insn (operands[2], operand_subword (operands[1], 0, 0, HFmode));
1217 emit_move_insn (operand_subword (operands[0], 0, 0, HFmode), operands[2]);
1218 emit_move_insn (operands[2], operand_subword (operands[1], 1, 0, HFmode));
1219 emit_move_insn (operand_subword (operands[0], 1, 0, HFmode), operands[2]);
1220 }
1221
1222 DONE;
1223 }")
1224
1225 (define_expand "reload_outhf"
1226 [(set (match_operand:HF 0 "register_operand" "=r")
1227 (match_operand:HF 1 "register_operand" "r"))
1228 (clobber (match_operand:QI 2 "register_operand" "=&h"))]
1229 ""
1230 "
1231 {
1232 emit_move_insn (operands[2], operand_subword (operands[1], 0, 0, HFmode));
1233 emit_move_insn (operand_subword (operands[0], 0, 0, HFmode), operands[2]);
1234 emit_move_insn (operands[2], operand_subword (operands[1], 1, 0, HFmode));
1235 emit_move_insn (operand_subword (operands[0], 1, 0, HFmode), operands[2]);
1236 DONE;
1237 }")
1238
1239 \f
1240 ;;
1241 ;; CONVERSION INSTRUCTIONS
1242 ;;
1243
1244 (define_expand "extendqihi2"
1245 [(clobber (match_dup 2))
1246 (set (match_dup 3) (match_operand:QI 1 "register_operand" ""))
1247 (set (match_operand:HI 0 "register_operand" "")
1248 (ashift:HI (match_dup 2)
1249 (const_int 16)))
1250 (set (match_dup 0)
1251 (ashiftrt:HI (match_dup 0) (const_int 16)))]
1252 ""
1253 "
1254 {
1255 operands[2] = gen_reg_rtx (HImode);
1256 operands[3] = gen_rtx_SUBREG (QImode, operands[2], 1);
1257 }")
1258
1259 ;;(define_insn "extendqihi2"
1260 ;; [(set (match_operand:HI 0 "register_operand" "=A")
1261 ;; (sign_extend:HI (match_operand:QI 1 "register_operand" "h")))]
1262 ;; ""
1263 ;; "%0 = %1 >> 16")
1264
1265 ;;(define_insn "zero_extendqihi2"
1266 ;; [(set (match_operand:HI 0 "register_operand" "=t,f,A,?d,?A")
1267 ;; (zero_extend:HI (match_operand:QI 1 "register_operand" "w,z,ku,A,r")))]
1268 ;; ""
1269 ;; "*
1270 ;; {
1271 ;; switch (which_alternative)
1272 ;; {
1273 ;; case 0:
1274 ;; case 1:
1275 ;; return \"%0=0\";
1276 ;;
1277 ;; case 2:
1278 ;; if (REGNO(operands[1]) == (REGNO(operands[0]) + 1))
1279 ;; return \"%0=0\";
1280 ;; else
1281 ;; return \"%w0=%1\;%0=0\";
1282 ;; case 3:
1283 ;; return \"%w0=%1\;%0=0\";
1284 ;;
1285 ;; case 4:
1286 ;; if (REGNO(operands[1]) == REG_Y || REGNO(operands[1]) == REG_PROD
1287 ;; || IS_ACCUM_REG(REGNO(operands[1])))
1288 ;; return \"move %w0=%1\;%0=0\";
1289 ;; else
1290 ;; return \"%w0=%1\;%0=0\";
1291 ;; }
1292 ;; }")
1293
1294 (define_expand "zero_extendqihi2"
1295 [(clobber (match_dup 2))
1296 (set (match_dup 3) (match_operand:QI 1 "register_operand" ""))
1297 (set (match_operand:HI 0 "register_operand" "")
1298 (ashift:HI (match_dup 2)
1299 (const_int 16)))
1300 (set (match_dup 0)
1301 (lshiftrt:HI (match_dup 0) (const_int 16)))]
1302 ""
1303 "
1304 {
1305 operands[2] = gen_reg_rtx (HImode);
1306 operands[3] = gen_rtx_SUBREG (QImode, operands[2], 1);
1307 }")
1308
1309
1310 (define_expand "floathihf2"
1311 [(set (match_operand:HF 0 "register_operand" "")
1312 (float:HF (match_operand:HI 1 "register_operand" "")))]
1313 ""
1314 "
1315 {
1316 if (!dsp16xx_floathihf2_libcall)
1317 dsp16xx_floathihf2_libcall = gen_rtx_SYMBOL_REF (Pmode, FLOATHIHF2_LIBCALL);
1318
1319 emit_library_call (dsp16xx_floathihf2_libcall, 1, HFmode, 1,
1320 operands[1], HImode);
1321 emit_move_insn (operands[0], hard_libcall_value(HFmode));
1322 DONE;
1323 }")
1324
1325 (define_expand "fix_trunchfhi2"
1326 [(set (match_operand:HI 0 "register_operand" "")
1327 (fix:HI (match_operand:HF 1 "register_operand" "")))]
1328 ""
1329 "
1330 {
1331 if (!dsp16xx_fixhfhi2_libcall)
1332 dsp16xx_fixhfhi2_libcall = gen_rtx_SYMBOL_REF (Pmode, FIXHFHI2_LIBCALL);
1333
1334 emit_library_call (dsp16xx_fixhfhi2_libcall, 1, HImode, 1,
1335 operands[1], HFmode);
1336 emit_move_insn (operands[0], hard_libcall_value(HImode));
1337 DONE;
1338 }")
1339
1340 (define_expand "fixuns_trunchfhi2"
1341 [(set (match_operand:HI 0 "register_operand" "")
1342 (unsigned_fix:HI (match_operand:HF 1 "register_operand" "")))]
1343 ""
1344 "
1345 {
1346 rtx reg1 = gen_reg_rtx (HFmode);
1347 rtx reg2 = gen_reg_rtx (HFmode);
1348 rtx reg3 = gen_reg_rtx (HImode);
1349 rtx label1 = gen_label_rtx ();
1350 rtx label2 = gen_label_rtx ();
1351 REAL_VALUE_TYPE offset = REAL_VALUE_LDEXP (1.0, 31);
1352
1353 if (reg1) /* turn off complaints about unreached code */
1354 {
1355 emit_move_insn (reg1, immed_real_const_1 (offset, HFmode));
1356 do_pending_stack_adjust ();
1357
1358 emit_insn (gen_cmphf (operands[1], reg1));
1359 emit_jump_insn (gen_bge (label1));
1360
1361 emit_insn (gen_fix_trunchfhi2 (operands[0], operands[1]));
1362 emit_jump_insn (gen_rtx_SET (VOIDmode, pc_rtx,
1363 gen_rtx_LABEL_REF (VOIDmode, label2)));
1364 emit_barrier ();
1365
1366 emit_label (label1);
1367 emit_insn (gen_subhf3 (reg2, operands[1], reg1));
1368 emit_move_insn (reg3, GEN_INT (0x80000000));;
1369
1370 emit_insn (gen_fix_trunchfhi2 (operands[0], reg2));
1371 emit_insn (gen_iorhi3 (operands[0], operands[0], reg3));
1372
1373 emit_label (label2);
1374
1375 /* allow REG_NOTES to be set on last insn (labels don't have enough
1376 fields, and can't be used for REG_NOTES anyway). */
1377 emit_insn (gen_rtx_USE (VOIDmode, stack_pointer_rtx));
1378 DONE;
1379 }
1380 }")
1381
1382 ;;
1383 ;; SHIFT INSTRUCTIONS
1384 ;;
1385
1386 (define_insn ""
1387 [(set (match_operand:HI 0 "register_operand" "=A")
1388 (ashiftrt:HI (match_operand:HI 1 "register_operand" "A")
1389 (const_int 1)))]
1390 ""
1391 "%0=%1>>1"
1392 [(set_attr "type" "special")])
1393
1394 (define_insn ""
1395 [(set (match_operand:HI 0 "register_operand" "=A")
1396 (ashiftrt:HI (match_operand:HI 1 "register_operand" "A")
1397 (const_int 4)))]
1398 ""
1399 "%0=%1>>4"
1400 [(set_attr "type" "special")])
1401
1402 (define_insn ""
1403 [(set (match_operand:HI 0 "register_operand" "=A")
1404 (ashiftrt:HI (match_operand:HI 1 "register_operand" "A")
1405 (const_int 8)))]
1406 ""
1407 "%0=%1>>8"
1408 [(set_attr "type" "special")])
1409
1410 (define_insn ""
1411 [(set (match_operand:HI 0 "register_operand" "=A")
1412 (ashiftrt:HI (match_operand:HI 1 "register_operand" "A")
1413 (const_int 16)))]
1414 ""
1415 "%0=%1>>16"
1416 [(set_attr "type" "special")])
1417 \f
1418 ;;
1419 ;; Arithmetic Right shift
1420
1421 (define_expand "ashrhi3"
1422 [(set (match_operand:HI 0 "register_operand" "")
1423 (ashiftrt:HI (match_operand:HI 1 "register_operand" "")
1424 (match_operand:QI 2 "nonmemory_operand" "")))]
1425 ""
1426 "
1427 {
1428 if (!TARGET_BMU)
1429 {
1430 /* If we are shifting by a constant we can do it in 1 or more
1431 1600 core shift instructions. The core instructions can
1432 shift by 1, 4, 8, or 16. */
1433
1434 if (GET_CODE(operands[2]) == CONST_INT)
1435 ;
1436 else
1437 {
1438 rtx label1 = gen_label_rtx ();
1439 rtx label2 = gen_label_rtx ();
1440
1441 #if 0
1442 if (!dsp16xx_ashrhi3_libcall)
1443 dsp16xx_ashrhi3_libcall
1444 = gen_rtx_SYMBOL_REF (Pmode, ASHRHI3_LIBCALL);
1445
1446 emit_library_call (dsp16xx_ashrhi3_libcall, 1, HImode, 2,
1447 operands[1], HImode,
1448 operands[2], QImode);
1449 emit_move_insn (operands[0], hard_libcall_value(HImode));
1450 DONE;
1451 #else
1452 do_pending_stack_adjust ();
1453 emit_insn (gen_tstqi (operands[2]));
1454 emit_jump_insn (gen_bne (label1));
1455 emit_move_insn (operands[0], operands[1]);
1456 emit_jump_insn (gen_jump (label2));
1457 emit_barrier ();
1458 emit_label (label1);
1459
1460 if (GET_CODE(operands[2]) != MEM)
1461 {
1462 rtx stack_slot;
1463
1464 stack_slot = assign_stack_temp (QImode, GET_MODE_SIZE(QImode), 0);
1465 stack_slot = change_address (stack_slot, VOIDmode, XEXP (stack_slot, 0));
1466 emit_move_insn (stack_slot, operands[2]);
1467 operands[2] = stack_slot;
1468 }
1469
1470 emit_insn (gen_match_ashrhi3_nobmu (operands[0], operands[1], operands[2]));
1471 emit_label (label2);
1472 DONE;
1473 #endif
1474 }
1475 }
1476 }")
1477
1478 (define_insn "match_ashrhi3_bmu"
1479 [(set (match_operand:HI 0 "register_operand" "=A,A,A")
1480 (ashiftrt:HI (match_operand:HI 1 "register_operand" "A,A,!A")
1481 (match_operand:QI 2 "nonmemory_operand" "B,I,h")))]
1482 "TARGET_BMU"
1483 "@
1484 %0=%1>>%2
1485 %0=%1>>%H2
1486 %0=%1>>%2"
1487 [(set_attr "type" "shift,shift_i,shift")])
1488
1489 (define_insn "match_ashrhi3_nobmu"
1490 [(set (match_operand:HI 0 "register_operand" "=A,A")
1491 (ashiftrt:HI (match_operand:HI 1 "register_operand" "A,0")
1492 (match_operand:QI 2 "general_operand" "n,m")))]
1493 "!TARGET_BMU"
1494 "*
1495 {
1496 if (which_alternative == 0)
1497 {
1498 emit_1600_core_shift (ASHIFTRT, operands, INTVAL(operands[2]));
1499 return \"\";
1500 }
1501 else
1502 {
1503 output_asm_insn (\"cloop=%2\", operands);
1504 output_asm_insn (\"do 0 \{\", operands);
1505 output_asm_insn (\"%0=%0>>1\", operands);
1506 return \"\}\";
1507 }
1508 }")
1509
1510
1511 \f
1512 ;;
1513 ;; Logical Right Shift
1514
1515 (define_insn ""
1516 [(set (match_operand:HI 0 "register_operand" "=A")
1517 (lshiftrt:HI (match_operand:HI 1 "register_operand" "A")
1518 (const_int 1)))]
1519 ""
1520 "%0=%1>>1\;%0=%b0&0x7fff"
1521 [(set_attr "type" "special")])
1522
1523 (define_insn ""
1524 [(set (match_operand:HI 0 "register_operand" "=A")
1525 (lshiftrt:HI (match_operand:HI 1 "register_operand" "A")
1526 (const_int 4)))]
1527 ""
1528 "%0=%1>>4\;%0=%b0&0x0fff"
1529 [(set_attr "type" "special")])
1530
1531 (define_insn ""
1532 [(set (match_operand:HI 0 "register_operand" "=A")
1533 (lshiftrt:HI (match_operand:HI 1 "register_operand" "A")
1534 (const_int 8)))]
1535 ""
1536 "%0=%1>>8\;%0=%b0&0x00ff"
1537 [(set_attr "type" "special")])
1538
1539 (define_insn ""
1540 [(set (match_operand:HI 0 "register_operand" "=A")
1541 (lshiftrt:HI (match_operand:HI 1 "register_operand" "A")
1542 (const_int 16)))]
1543 ""
1544 "%0=%1>>16\;%0=%b0&0x0000"
1545 [(set_attr "type" "special")])
1546
1547 (define_expand "lshrhi3"
1548 [(set (match_operand:HI 0 "register_operand" "")
1549 (lshiftrt:HI (match_operand:HI 1 "register_operand" "")
1550 (match_operand:QI 2 "nonmemory_operand" "")))]
1551 ""
1552 "
1553 {
1554 if (!TARGET_BMU)
1555 {
1556 /* If we are shifting by a constant we can do it in 1 or more
1557 1600 core shift instructions. The core instructions can
1558 shift by 1, 4, 8, or 16. */
1559
1560 if (GET_CODE(operands[2]) == CONST_INT)
1561 emit_insn (gen_match_lshrhi3_nobmu (operands[0], operands[1], operands[2]));
1562 else
1563 {
1564 rtx label1 = gen_label_rtx ();
1565 rtx label2 = gen_label_rtx ();
1566 #if 0
1567 if (!dsp16xx_lshrhi3_libcall)
1568 dsp16xx_lshrhi3_libcall
1569 = gen_rtx_SYMBOL_REF (Pmode, LSHRHI3_LIBCALL);
1570
1571 emit_library_call (dsp16xx_lshrhi3_libcall, 1, HImode, 2,
1572 operands[1], HImode,
1573 operands[2], QImode);
1574 emit_move_insn (operands[0], hard_libcall_value(HImode));
1575 DONE;
1576 #else
1577 do_pending_stack_adjust ();
1578 emit_insn (gen_tstqi (operands[2]));
1579 emit_jump_insn (gen_bne (label1));
1580 emit_move_insn (operands[0], operands[1]);
1581 emit_jump_insn (gen_jump (label2));
1582 emit_barrier ();
1583 emit_label (label1);
1584
1585 if (GET_CODE(operands[2]) != MEM)
1586 {
1587 rtx stack_slot;
1588
1589 stack_slot = assign_stack_temp (QImode, GET_MODE_SIZE(QImode), 0);
1590 stack_slot = change_address (stack_slot, VOIDmode, XEXP (stack_slot, 0));
1591 emit_move_insn (stack_slot, operands[2]);
1592 operands[2] = stack_slot;
1593 }
1594
1595 emit_insn (gen_match_lshrhi3_nobmu (operands[0], operands[1], operands[2]));
1596 emit_label (label2);
1597 DONE;
1598 #endif
1599 }
1600 }
1601 }")
1602
1603 (define_insn "match_lshrhi3"
1604 [(set (match_operand:HI 0 "register_operand" "=A,A,A")
1605 (lshiftrt:HI (match_operand:HI 1 "register_operand" "A,A,!A")
1606 (match_operand:QI 2 "nonmemory_operand" "B,I,h")))]
1607 "TARGET_BMU"
1608 "@
1609 %0=%1>>>%2
1610 %0=%1>>>%H2
1611 %0=%1>>>%2"
1612 [(set_attr "type" "shift,shift_i,shift")])
1613
1614 (define_insn "match_lshrhi3_nobmu"
1615 [(set (match_operand:HI 0 "register_operand" "=A,A")
1616 (lshiftrt:HI (match_operand:HI 1 "register_operand" "A,0")
1617 (match_operand:QI 2 "general_operand" "n,m")))
1618 (clobber (match_scratch:QI 3 "=X,Y"))]
1619 "!TARGET_BMU"
1620 "*
1621 {
1622 if (which_alternative == 0)
1623 {
1624 emit_1600_core_shift (LSHIFTRT, operands, INTVAL(operands[2]));
1625 return \"\";
1626 }
1627 else
1628 {
1629 output_asm_insn (\"%3=psw\;psw=0\",operands);
1630 output_asm_insn (\"cloop=%2\", operands);
1631 output_asm_insn (\"do 0 \{\", operands);
1632 output_asm_insn (\"%0=%0>>1\", operands);
1633 output_asm_insn (\"\}\", operands);
1634 return \"psw=%3\";
1635 }
1636 }")
1637
1638 \f
1639 ;;
1640 ;; Arithmetic Left shift
1641
1642 ;; Start off with special case arithmetic left shift by 1,4,8 or 16.
1643
1644
1645 (define_insn ""
1646 [(set (match_operand:HI 0 "register_operand" "=A")
1647 (ashift:HI (match_operand:HI 1 "register_operand" "A")
1648 (const_int 1)))]
1649 ""
1650 "%0=%1<<1"
1651 [(set_attr "type" "special")])
1652
1653 (define_insn ""
1654 [(set (match_operand:HI 0 "register_operand" "=A")
1655 (ashift:HI (match_operand:HI 1 "register_operand" "A")
1656 (const_int 4)))]
1657 ""
1658 "%0=%1<<4"
1659 [(set_attr "type" "special")])
1660
1661 (define_insn ""
1662 [(set (match_operand:HI 0 "register_operand" "=A")
1663 (ashift:HI (match_operand:HI 1 "register_operand" "A")
1664 (const_int 8)))]
1665 ""
1666 "%0=%1<<8"
1667 [(set_attr "type" "special")])
1668
1669 (define_insn ""
1670 [(set (match_operand:HI 0 "register_operand" "=A")
1671 (ashift:HI (zero_extend:HI (match_operand:QI 1 "register_operand" "A"))
1672 (const_int 16)))]
1673 ""
1674 "%0=%1<<16"
1675 [(set_attr "type" "special")])
1676
1677 (define_insn ""
1678 [(set (match_operand:HI 0 "register_operand" "=A")
1679 (ashift:HI (match_operand:HI 1 "general_operand" "A")
1680 (const_int 16)))]
1681 ""
1682 "%0=%1<<16"
1683 [(set_attr "type" "special")])
1684
1685
1686 \f
1687 ;; Normal Arithmetic Shift Left
1688
1689
1690 (define_expand "ashlhi3"
1691 [(set (match_operand:HI 0 "register_operand" "")
1692 (ashift:HI (match_operand:HI 1 "register_operand" "")
1693 (match_operand:QI 2 "nonmemory_operand" "")))]
1694 ""
1695 "
1696 {
1697 if (!TARGET_BMU)
1698 {
1699 /* If we are shifting by a constant we can do it in 1 or more
1700 1600 core shift instructions. The core instructions can
1701 shift by 1, 4, 8, or 16. */
1702
1703 if (GET_CODE(operands[2]) == CONST_INT)
1704 ;
1705 else
1706 {
1707 rtx label1 = gen_label_rtx ();
1708 rtx label2 = gen_label_rtx ();
1709 #if 0
1710 if (!dsp16xx_ashlhi3_libcall)
1711 dsp16xx_ashlhi3_libcall
1712 = gen_rtx_SYMBOL_REF (Pmode, ASHLHI3_LIBCALL);
1713
1714 emit_library_call (dsp16xx_ashlhi3_libcall, 1, HImode, 2,
1715 operands[1], HImode, operands[2], QImode);
1716 emit_move_insn (operands[0], hard_libcall_value(HImode));
1717 DONE;
1718 #else
1719 do_pending_stack_adjust ();
1720 emit_insn (gen_tstqi (operands[2]));
1721 emit_jump_insn (gen_bne (label1));
1722 emit_move_insn (operands[0], operands[1]);
1723 emit_jump_insn (gen_jump (label2));
1724 emit_barrier ();
1725 emit_label (label1);
1726
1727 if (GET_CODE(operands[2]) != MEM)
1728 {
1729 rtx stack_slot;
1730
1731 stack_slot = assign_stack_temp (QImode, GET_MODE_SIZE(QImode), 0);
1732 stack_slot = change_address (stack_slot, VOIDmode, XEXP (stack_slot, 0));
1733 emit_move_insn (stack_slot, operands[2]);
1734 operands[2] = stack_slot;
1735 }
1736 emit_insn (gen_match_ashlhi3_nobmu (operands[0], operands[1], operands[2]));
1737 emit_label (label2);
1738 DONE;
1739 #endif
1740 }
1741 }
1742 }")
1743
1744 (define_insn "match_ashlhi3"
1745 [(set (match_operand:HI 0 "register_operand" "=A,A,A")
1746 (ashift:HI (match_operand:HI 1 "register_operand" "A,A,A")
1747 (match_operand:QI 2 "nonmemory_operand" "B,I,!h")))]
1748 "TARGET_BMU"
1749 "@
1750 %0=%1<<%2\;move %u0=%u0
1751 %0=%1<<%H2\;move %u0=%u0
1752 %0=%1<<%2\;move %u0=%u0"
1753 [(set_attr "type" "shift,shift_i,shift")])
1754
1755 (define_insn "match_ashlhi3_nobmu"
1756 [(set (match_operand:HI 0 "register_operand" "=A,A")
1757 (ashift:HI (match_operand:HI 1 "register_operand" "A,0")
1758 (match_operand:QI 2 "general_operand" "n,m")))]
1759 "!TARGET_BMU"
1760 "*
1761 {
1762 if (which_alternative == 0)
1763 {
1764 emit_1600_core_shift (ASHIFT, operands, INTVAL(operands[2]));
1765 return \"\";
1766 }
1767 else
1768 {
1769 output_asm_insn (\"cloop=%2\", operands);
1770 output_asm_insn (\"do 0 \{\", operands);
1771 output_asm_insn (\"%0=%0<<1\", operands);
1772 return \"\}\";
1773 }
1774 }")
1775
1776 \f
1777
1778 ;;
1779 ;; Jump Instructions
1780 ;;
1781
1782 (define_expand "beq"
1783 [(set (pc)
1784 (if_then_else (eq (match_dup 1)
1785 (const_int 0))
1786 (label_ref (match_operand 0 "" ""))
1787 (pc)))]
1788 ""
1789 "
1790 {
1791 if (dsp16xx_compare_gen == gen_compare_reg)
1792 operands[1] = (*dsp16xx_compare_gen)(EQ, dsp16xx_compare_op0, dsp16xx_compare_op1);
1793 else
1794 operands[1] = (*dsp16xx_compare_gen)(dsp16xx_compare_op0);
1795 }")
1796
1797 (define_expand "bne"
1798 [(set (pc)
1799 (if_then_else (ne (match_dup 1)
1800 (const_int 0))
1801 (label_ref (match_operand 0 "" ""))
1802 (pc)))]
1803 ""
1804 "
1805 {
1806 if (dsp16xx_compare_gen == gen_compare_reg)
1807 operands[1] = (*dsp16xx_compare_gen)(NE, dsp16xx_compare_op0, dsp16xx_compare_op1);
1808 else
1809 operands[1] = (*dsp16xx_compare_gen)(dsp16xx_compare_op0);
1810 }")
1811
1812
1813 (define_expand "bgt"
1814 [(set (pc)
1815 (if_then_else (gt (match_dup 1)
1816 (const_int 0))
1817 (label_ref (match_operand 0 "" ""))
1818 (pc)))]
1819 ""
1820 "
1821 {
1822 if (dsp16xx_compare_gen == gen_compare_reg)
1823 operands[1] = (*dsp16xx_compare_gen)(GT, dsp16xx_compare_op0, dsp16xx_compare_op1);
1824 else
1825 operands[1] = (*dsp16xx_compare_gen)(dsp16xx_compare_op0);
1826 }")
1827
1828
1829 (define_expand "bge"
1830 [(set (pc)
1831 (if_then_else (ge (match_dup 1)
1832 (const_int 0))
1833 (label_ref (match_operand 0 "" ""))
1834 (pc)))]
1835 ""
1836 "
1837 {
1838 if (dsp16xx_compare_gen == gen_compare_reg)
1839 operands[1] = (*dsp16xx_compare_gen)(GE, dsp16xx_compare_op0, dsp16xx_compare_op1);
1840 else
1841 operands[1] = (*dsp16xx_compare_gen)(dsp16xx_compare_op0);
1842 }")
1843
1844
1845 (define_expand "blt"
1846 [(set (pc)
1847 (if_then_else (lt (match_dup 1)
1848 (const_int 0))
1849 (label_ref (match_operand 0 "" ""))
1850 (pc)))]
1851 ""
1852 "
1853 {
1854 if (dsp16xx_compare_gen == gen_compare_reg)
1855 operands[1] = (*dsp16xx_compare_gen)(LT, dsp16xx_compare_op0, dsp16xx_compare_op1);
1856 else
1857 operands[1] = (*dsp16xx_compare_gen)(dsp16xx_compare_op0);
1858 }")
1859
1860
1861 (define_expand "ble"
1862 [(set (pc)
1863 (if_then_else (le (match_dup 1)
1864 (const_int 0))
1865 (label_ref (match_operand 0 "" ""))
1866 (pc)))]
1867 ""
1868 "
1869 {
1870 if (dsp16xx_compare_gen == gen_compare_reg)
1871 operands[1] = (*dsp16xx_compare_gen)(LE, dsp16xx_compare_op0, dsp16xx_compare_op1);
1872 else
1873 operands[1] = (*dsp16xx_compare_gen)(dsp16xx_compare_op0);
1874 }")
1875
1876
1877 (define_expand "bgtu"
1878 [(set (pc)
1879 (if_then_else (gtu (match_dup 1)
1880 (const_int 0))
1881 (label_ref (match_operand 0 "" ""))
1882 (pc)))]
1883 ""
1884 "
1885 {
1886 if (dsp16xx_compare_gen == gen_compare_reg)
1887 operands[1] = (*dsp16xx_compare_gen)(GTU, dsp16xx_compare_op0, dsp16xx_compare_op1);
1888 else
1889 operands[1] = (*dsp16xx_compare_gen)(dsp16xx_compare_op0);
1890 }")
1891
1892
1893 (define_expand "bgeu"
1894 [(set (pc)
1895 (if_then_else (geu (match_dup 1)
1896 (const_int 0))
1897 (label_ref (match_operand 0 "" ""))
1898 (pc)))]
1899 ""
1900 "
1901 {
1902 if (dsp16xx_compare_gen == gen_compare_reg)
1903 operands[1] = (*dsp16xx_compare_gen)(GEU, dsp16xx_compare_op0, dsp16xx_compare_op1);
1904 else
1905 operands[1] = (*dsp16xx_compare_gen)(dsp16xx_compare_op0);
1906 }")
1907
1908
1909 (define_expand "bltu"
1910 [(set (pc)
1911 (if_then_else (ltu (match_dup 1)
1912 (const_int 0))
1913 (label_ref (match_operand 0 "" ""))
1914 (pc)))]
1915 ""
1916 "
1917 {
1918 if (dsp16xx_compare_gen == gen_compare_reg)
1919 operands[1] = (*dsp16xx_compare_gen)(LTU, dsp16xx_compare_op0, dsp16xx_compare_op1);
1920 else
1921 operands[1] = (*dsp16xx_compare_gen)(dsp16xx_compare_op0);
1922 }")
1923
1924
1925 (define_expand "bleu"
1926 [(set (pc)
1927 (if_then_else (leu (match_dup 1)
1928 (const_int 0))
1929 (label_ref (match_operand 0 "" ""))
1930 (pc)))]
1931 ""
1932 "
1933 {
1934 if (dsp16xx_compare_gen == gen_compare_reg)
1935 operands[1] = (*dsp16xx_compare_gen)(LEU, dsp16xx_compare_op0, dsp16xx_compare_op1);
1936 else
1937 operands[1] = (*dsp16xx_compare_gen)(dsp16xx_compare_op0);
1938 }")
1939
1940
1941 (define_insn ""
1942 [(set (pc)
1943 (if_then_else (match_operator 1 "comparison_operator"
1944 [(cc0) (const_int 0)])
1945 (label_ref (match_operand 0 "" ""))
1946 (pc)))]
1947 "!TARGET_NEAR_JUMP"
1948 "pt=%l0\;if %C1 goto pt"
1949 [(set_attr "type" "cond_jump")])
1950
1951 (define_insn ""
1952 [(set (pc)
1953 (if_then_else (match_operator 1 "comparison_operator"
1954 [(cc0) (const_int 0)])
1955 (label_ref (match_operand 0 "" ""))
1956 (pc)))]
1957 "TARGET_NEAR_JUMP"
1958 "if %C1 goto %l0"
1959 [(set_attr "type" "cond_jump")])
1960 \f
1961 ;;
1962 ;; Negated conditional jump instructions.
1963 ;; These are necessary because jump optimization can turn
1964 ;; direct-conditional branches into reverse-conditional
1965 ;; branches.
1966
1967 (define_insn ""
1968 [(set (pc)
1969 (if_then_else (match_operator 1 "comparison_operator"
1970 [(cc0) (const_int 0)])
1971 (pc)
1972 (label_ref (match_operand 0 "" ""))))]
1973 "!TARGET_NEAR_JUMP"
1974 "pt=%l0\;if %I1 goto pt"
1975 [(set_attr "type" "cond_jump")])
1976
1977 (define_insn ""
1978 [(set (pc)
1979 (if_then_else (match_operator 1 "comparison_operator"
1980 [(cc0) (const_int 0)])
1981 (pc)
1982 (label_ref (match_operand 0 "" ""))))]
1983 "TARGET_NEAR_JUMP"
1984 "if %I1 goto %l0"
1985 [(set_attr "type" "cond_jump")])
1986
1987
1988 ;;
1989 ;; JUMPS
1990 ;;
1991
1992 (define_insn "jump"
1993 [(set (pc)
1994 (label_ref (match_operand 0 "" "")))]
1995 ""
1996 "*
1997 {
1998 if (TARGET_NEAR_JUMP)
1999 return \"goto %l0\";
2000 else
2001 return \"pt=%l0\;goto pt\";
2002 }"
2003 [(set_attr "type" "jump")])
2004
2005
2006 (define_insn "indirect_jump"
2007 [(set (pc) (match_operand:QI 0 "register_operand" "A"))]
2008 ""
2009 "pt=%0\;goto pt"
2010 [(set_attr "type" "jump")])
2011
2012 (define_insn "tablejump"
2013 [(set (pc) (match_operand:QI 0 "register_operand" "A"))
2014 (use (label_ref (match_operand 1 "" "")))]
2015 ""
2016 "pt=%0\;goto pt"
2017 [(set_attr "type" "jump")])
2018 \f
2019 ;;
2020 ;; FUNCTION CALLS
2021 ;;
2022
2023 ;; Call subroutine with no return value.
2024
2025
2026 (define_expand "call"
2027 [(parallel [(call (match_operand:QI 0 "" "")
2028 (match_operand 1 "" ""))
2029 (clobber (reg:QI 24))])]
2030 ""
2031 "
2032 {
2033 if (GET_CODE (operands[0]) == MEM
2034 && ! call_address_operand (XEXP (operands[0], 0), QImode))
2035 operands[0] = gen_rtx_MEM (GET_MODE (operands[0]),
2036 force_reg (Pmode, XEXP (operands[0], 0)));
2037 }")
2038
2039 (define_insn ""
2040 [(parallel [(call (mem:QI (match_operand:QI 0 "call_address_operand" "hR"))
2041 (match_operand 1 "" ""))
2042 (clobber (reg:QI 24))])]
2043 ""
2044 "*
2045 {
2046 if (GET_CODE (operands[0]) == REG ||
2047 (GET_CODE(operands[0]) == SYMBOL_REF && !TARGET_NEAR_CALL))
2048 return \"pt=%0\;call pt\";
2049 else
2050 return \"call %0\";
2051 }"
2052 [(set_attr "type" "call")])
2053
2054 ;; Call subroutine with return value.
2055
2056 (define_expand "call_value"
2057 [(parallel [(set (match_operand 0 "register_operand" "=f")
2058 (call (match_operand:QI 1 "call_address_operand" "hR")
2059 (match_operand:QI 2 "" "")))
2060 (clobber (reg:QI 24))])]
2061 ""
2062 "
2063 {
2064 if (GET_CODE (operands[1]) == MEM
2065 && ! call_address_operand (XEXP (operands[1], 0), QImode))
2066 operands[1] = gen_rtx_MEM (GET_MODE (operands[1]),
2067 force_reg (Pmode, XEXP (operands[1], 0)));
2068 }")
2069
2070 (define_insn ""
2071 [(parallel [(set (match_operand 0 "register_operand" "=f")
2072 (call (mem:QI (match_operand:QI 1 "call_address_operand" "hR"))
2073 (match_operand:QI 2 "" "")))
2074 (clobber (reg:QI 24))])]
2075 ""
2076 "*
2077 {
2078 if (GET_CODE (operands[1]) == REG ||
2079 (GET_CODE(operands[1]) == SYMBOL_REF && !TARGET_NEAR_CALL))
2080 return \"pt=%1\;call pt\";
2081 else
2082 return \"call %1\";
2083 }"
2084 [(set_attr "type" "call")])
2085
2086
2087 (define_expand "untyped_call"
2088 [(parallel [(call (match_operand 0 "" "")
2089 (const_int 0))
2090 (match_operand 1 "" "")
2091 (match_operand 2 "" "")])]
2092 ""
2093 "
2094 {
2095 int i;
2096
2097 emit_call_insn (gen_call (operands[0], const0_rtx, NULL, const0_rtx));
2098
2099 for (i = 0; i < XVECLEN (operands[2], 0); i++)
2100 {
2101 rtx set = XVECEXP (operands[2], 0, i);
2102 emit_move_insn (SET_DEST (set), SET_SRC (set));
2103 }
2104
2105 /* The optimizer does not know that the call sets the function value
2106 registers we stored in the result block. We avoid problems by
2107 claiming that all hard registers are used and clobbered at this
2108 point. */
2109 emit_insn (gen_blockage ());
2110
2111 DONE;
2112 }")
2113
2114 ;; UNSPEC_VOLATILE is considered to use and clobber all hard registers and
2115 ;; all of memory. This blocks insns from being moved across this point.
2116
2117 (define_insn "blockage"
2118 [(unspec_volatile [(const_int 0)] 0)]
2119 ""
2120 "")
2121
2122 (define_insn "nop"
2123 [(const_int 0)]
2124 ""
2125 "nop"
2126 [(set_attr "type" "nop")])
2127 \f
2128 ;;
2129 ;; PEEPHOLE PATTERNS
2130 ;;
2131
2132
2133 (define_peephole
2134 [(set (match_operand:QI 0 "register_operand" "=A")
2135 (reg:QI 16))
2136 (call (mem:QI (match_dup 0))
2137 (match_operand 1 "" "i"))]
2138 ""
2139 "call pt")
2140
2141
2142 (define_peephole
2143 [(set (match_operand:QI 0 "register_operand" "=A")
2144 (reg:QI 16))
2145 (set (match_operand 1 "" "")
2146 (call (mem:QI (match_dup 0))
2147 (match_operand 2 "" "i")))]
2148 ""
2149 "call pt")
2150
2151 (define_peephole
2152 [(set (match_operand:HI 0 "register_operand" "=A")
2153 (ashift:HI (match_operand:HI 1 "register_operand" "A")
2154 (const_int 16)))
2155 (set (match_operand:HI 2 "register_operand" "")
2156 (match_dup 0))
2157 (set (match_dup 0)
2158 (ashiftrt:HI (match_dup 0) (const_int 16)))
2159 (set (match_dup 2)
2160 (match_dup 0))]
2161 ""
2162 "%0=%1<<16\;%0=%0>>16\;%u2=%u0\;%w2=%w0")
2163
2164 (define_peephole
2165 [(set (match_operand:HI 0 "register_operand" "=A")
2166 (ashift:HI (match_operand:HI 1 "register_operand" "A")
2167 (const_int 16)))
2168 (set (match_operand:HI 2 "register_operand" "")
2169 (match_dup 0))
2170 (set (match_dup 0)
2171 (lshiftrt:HI (match_dup 0) (const_int 16)))
2172 (set (match_dup 2)
2173 (match_dup 0))]
2174 ""
2175 "%0=%1<<16\;%0=%0>>16\;%0=%b0&0x0000\;%u2=%u0\;%w2=%w0")