]> git.ipfire.org Git - thirdparty/gcc.git/blob - gcc/config/pdp11/pdp11.md
* pdp11.md (extendsfdf2): Fix mode mismatch in SET.
[thirdparty/gcc.git] / gcc / config / pdp11 / pdp11.md
1 ;;- Machine description for the pdp11 for GNU C compiler
2 ;; Copyright (C) 1994, 1995, 1997 Free Software Foundation, Inc.
3 ;; Contributed by Michael K. Gschwind (mike@vlsivie.tuwien.ac.at).
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 1, 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, 675 Mass Ave, Cambridge, MA 02139, USA.
20
21
22 ;; HI is 16 bit
23 ;; QI is 8 bit
24
25 ;;- See file "rtl.def" for documentation on define_insn, match_*, et. al.
26
27 ;;- cpp macro #define NOTICE_UPDATE_CC in file tm.h handles condition code
28 ;;- updates for most instructions.
29
30 ;;- Operand classes for the register allocator:
31 \f
32 ;; Compare instructions.
33
34 ;; currently we only support df floats, which saves us quite some
35 ;; hassle switching the FP mode!
36 ;; we assume that CPU is always in long float mode, and
37 ;; 16 bit integer mode - currently, the prologue for main does this,
38 ;; but maybe we should just set up a NEW crt0 properly,
39 ;; -- and what about signal handling code?
40 ;; (we don't even let sf floats in the register file, so
41 ;; we only should have to worry about truncating and widening
42 ;; when going to memory)
43
44 ;; abort() call by g++ - must define libfunc for cmp_optab
45 ;; and ucmp_optab for mode SImode, because we don't have that!!!
46 ;; - yet since no libfunc is there, we abort ()
47
48 ;; The only thing that remains to be done then is output
49 ;; the floats in a way the assembler can handle it (and
50 ;; if you're really into it, use a PDP11 float emulation
51 ;; library to do floating point constant folding - but
52 ;; I guess you'll get reasonable results even when not
53 ;; doing this)
54 ;; the last thing to do is fix the UPDATE_CC macro to check
55 ;; for floating point condition codes, and set cc_status
56 ;; properly, also setting the CC_IN_FCCR flag.
57
58 ;; define attributes
59 ;; currently type is only fpu or arith or unknown, maybe branch later ?
60 ;; default is arith
61 (define_attr "type" "unknown,arith,fp" (const_string "arith"))
62
63 ;; length default is 1 word each
64 (define_attr "length" "" (const_int 1))
65
66 ;; a user's asm statement
67 (define_asm_attributes
68 [(set_attr "type" "unknown")
69 ; all bets are off how long it is - make it 256, forces long jumps
70 ; whenever jumping around it !!!
71 (set_attr "length" "256")])
72
73 ;; define function units
74
75 ;; arithmetic - values here immediately when next insn issued
76 ;; or does it mean the number of cycles after this insn was issued?
77 ;; how do I say that fpu insns use cpu also? (pre-interaction phase)
78
79 ;(define_function_unit "cpu" 1 1 (eq_attr "type" "arith") 0 0)
80 ;(define_function_unit "fpu" 1 1 (eq_attr "type" "fp") 0 0)
81
82 ;; compare
83 (define_insn "cmpdf"
84 [(set (cc0)
85 (compare (match_operand:DF 0 "general_operand" "fR,Q,F")
86 (match_operand:DF 1 "register_operand" "a,a,a")))]
87 "TARGET_FPU"
88 "*
89 {
90 cc_status.flags = CC_IN_FPU;
91 return \"cmpd %0, %1\;cfcc\";
92 }"
93 [(set_attr "length" "2,3,6")])
94
95 ;; a bit of brain damage, maybe inline later -
96 ;; problem is - gcc seems to NEED SImode because
97 ;; of the cmp weirdness - maybe change gcc to handle this?
98
99 (define_expand "cmpsi"
100 [(set (reg:SI 0)
101 (match_operand:SI 0 "general_operand" "g"))
102 (set (reg:SI 2)
103 (match_operand:SI 1 "general_operand" "g"))
104 (parallel [(set (cc0)
105 (compare (reg:SI 0)
106 (reg:SI 2)))
107 (clobber (reg:SI 0))])]
108 "0" ;; disable for test
109 "")
110
111 ;; check for next insn for branch code - does this still
112 ;; work in gcc 2.* ?
113
114 (define_insn ""
115 [(set (cc0)
116 (compare (reg:SI 0)
117 (reg:SI 2)))
118 (clobber (reg:SI 0))]
119 ""
120 "*
121 {
122 rtx br_insn = NEXT_INSN (insn);
123 RTX_CODE br_code;
124
125 if (GET_CODE (br_insn) != JUMP_INSN)
126 abort();
127 br_code = GET_CODE (XEXP (XEXP (PATTERN (br_insn), 1), 0));
128
129 switch(br_code)
130 {
131 case GEU:
132 case LTU:
133 case GTU:
134 case LEU:
135
136 return \"jsr pc, ___ucmpsi\;cmp $1,r0\";
137
138 case GE:
139 case LT:
140 case GT:
141 case LE:
142 case EQ:
143 case NE:
144
145 return \"jsr pc, ___cmpsi\;tst r0\";
146
147 default:
148
149 abort();
150 }
151 }"
152 [(set_attr "length" "4")])
153
154
155 (define_insn "cmphi"
156 [(set (cc0)
157 (compare (match_operand:HI 0 "general_operand" "rR,rR,Qi,Qi")
158 (match_operand:HI 1 "general_operand" "rR,Qi,rR,Qi")))]
159 ""
160 "cmp %0,%1"
161 [(set_attr "length" "1,2,2,3")])
162
163 (define_insn "cmpqi"
164 [(set (cc0)
165 (compare (match_operand:QI 0 "general_operand" "rR,rR,Qi,Qi")
166 (match_operand:QI 1 "general_operand" "rR,Qi,rR,Qi")))]
167 ""
168 "cmpb %0,%1"
169 [(set_attr "length" "1,2,2,3")])
170
171
172 ;; We have to have this because cse can optimize the previous pattern
173 ;; into this one.
174
175 (define_insn "tstdf"
176 [(set (cc0)
177 (match_operand:DF 0 "general_operand" "fR,Q"))]
178 "TARGET_FPU"
179 "*
180 {
181 cc_status.flags = CC_IN_FPU;
182 return \"tstd %0\;cfcc\";
183 }"
184 [(set_attr "length" "2,3")])
185
186
187 (define_expand "tstsi"
188 [(set (reg:SI 0)
189 (match_operand:SI 0 "general_operand" "g"))
190 (parallel [(set (cc0)
191 (reg:SI 0))
192 (clobber (reg:SI 0))])]
193 "0" ;; disable for test
194 "")
195
196 (define_insn ""
197 [(set (cc0)
198 (reg:SI 0))
199 (clobber (reg:SI 0))]
200 ""
201 "jsr pc, ___tstsi\;tst r0"
202 [(set_attr "length" "3")])
203
204
205 (define_insn "tsthi"
206 [(set (cc0)
207 (match_operand:HI 0 "general_operand" "rR,Q"))]
208 ""
209 "tst %0"
210 [(set_attr "length" "1,2")])
211
212 (define_insn "tstqi"
213 [(set (cc0)
214 (match_operand:QI 0 "general_operand" "rR,Q"))]
215 ""
216 "tstb %0"
217 [(set_attr "length" "1,2")])
218
219 ;; sob instruction - we need an assembler which can make this instruction
220 ;; valid under _all_ circumstances!
221
222 (define_insn ""
223 [(set (pc)
224 (if_then_else
225 (ne (plus:HI (match_operand:HI 0 "register_operand" "r")
226 (const_int -1))
227 (const_int 0))
228 (label_ref (match_operand 1 "" ""))
229 (pc)))
230 (set (match_dup 0)
231 (plus:HI (match_dup 0)
232 (const_int -1)))]
233 "TARGET_40_PLUS"
234 "*
235 {
236 static int labelcount = 0;
237 static char buf[1000];
238
239 if (get_attr_length (insn) == 1)
240 return \"sob %0, %l1\";
241
242 /* emulate sob */
243 output_asm_insn (\"dec %0\", operands);
244
245 sprintf (buf, \"bge LONG_SOB%d\", labelcount);
246 output_asm_insn (buf, NULL);
247
248 output_asm_insn (\"jmp %l1\", operands);
249
250 sprintf (buf, \"LONG_SOB%d:\", labelcount++);
251 output_asm_insn (buf, NULL);
252
253 return \"\";
254 }"
255 [(set (attr "length") (if_then_else (ior (le (minus (match_dup 0)
256 (pc))
257 (const_int -256))
258 (ge (minus (match_dup 0)
259 (pc))
260 (const_int 0)))
261 (const_int 4)
262 (const_int 1)))])
263
264 ;; These control RTL generation for conditional jump insns
265 ;; and match them for register allocation.
266
267 ;; problem with too short jump distance! we need an assembler which can
268 ;; make this valid for all jump distances!
269 ;; e.g. gas!
270
271 ;; these must be changed to check for CC_IN_FCCR if float is to be
272 ;; enabled
273
274 (define_insn "beq"
275 [(set (pc)
276 (if_then_else (eq (cc0)
277 (const_int 0))
278 (label_ref (match_operand 0 "" ""))
279 (pc)))]
280 ""
281 "* return output_jump(\"beq\", \"bne\", get_attr_length(insn));"
282 [(set (attr "length") (if_then_else (ior (le (minus (match_dup 0)
283 (pc))
284 (const_int -128))
285 (ge (minus (match_dup 0)
286 (pc))
287 (const_int 128)))
288 (const_int 3)
289 (const_int 1)))])
290
291
292 (define_insn "bne"
293 [(set (pc)
294 (if_then_else (ne (cc0)
295 (const_int 0))
296 (label_ref (match_operand 0 "" ""))
297 (pc)))]
298 ""
299 "* return output_jump(\"bne\", \"beq\", get_attr_length(insn));"
300 [(set (attr "length") (if_then_else (ior (le (minus (match_dup 0)
301 (pc))
302 (const_int -128))
303 (ge (minus (match_dup 0)
304 (pc))
305 (const_int 128)))
306 (const_int 3)
307 (const_int 1)))])
308
309 (define_insn "bgt"
310 [(set (pc)
311 (if_then_else (gt (cc0)
312 (const_int 0))
313 (label_ref (match_operand 0 "" ""))
314 (pc)))]
315 ""
316 "* return output_jump(\"bgt\", \"ble\", get_attr_length(insn));"
317 [(set (attr "length") (if_then_else (ior (le (minus (match_dup 0)
318 (pc))
319 (const_int -128))
320 (ge (minus (match_dup 0)
321 (pc))
322 (const_int 128)))
323 (const_int 3)
324 (const_int 1)))])
325
326 (define_insn "bgtu"
327 [(set (pc)
328 (if_then_else (gtu (cc0)
329 (const_int 0))
330 (label_ref (match_operand 0 "" ""))
331 (pc)))]
332 ""
333 "* return output_jump(\"bhi\", \"blos\", get_attr_length(insn));"
334 [(set (attr "length") (if_then_else (ior (le (minus (match_dup 0)
335 (pc))
336 (const_int -128))
337 (ge (minus (match_dup 0)
338 (pc))
339 (const_int 128)))
340 (const_int 3)
341 (const_int 1)))])
342
343 (define_insn "blt"
344 [(set (pc)
345 (if_then_else (lt (cc0)
346 (const_int 0))
347 (label_ref (match_operand 0 "" ""))
348 (pc)))]
349 ""
350 "* return output_jump(\"blt\", \"bge\", get_attr_length(insn));"
351 [(set (attr "length") (if_then_else (ior (le (minus (match_dup 0)
352 (pc))
353 (const_int -128))
354 (ge (minus (match_dup 0)
355 (pc))
356 (const_int 128)))
357 (const_int 3)
358 (const_int 1)))])
359
360
361 (define_insn "bltu"
362 [(set (pc)
363 (if_then_else (ltu (cc0)
364 (const_int 0))
365 (label_ref (match_operand 0 "" ""))
366 (pc)))]
367 ""
368 "* return output_jump(\"blo\", \"bhis\", get_attr_length(insn));"
369 [(set (attr "length") (if_then_else (ior (le (minus (match_dup 0)
370 (pc))
371 (const_int -128))
372 (ge (minus (match_dup 0)
373 (pc))
374 (const_int 128)))
375 (const_int 3)
376 (const_int 1)))])
377
378 (define_insn "bge"
379 [(set (pc)
380 (if_then_else (ge (cc0)
381 (const_int 0))
382 (label_ref (match_operand 0 "" ""))
383 (pc)))]
384 ""
385 "* return output_jump(\"bge\", \"blt\", get_attr_length(insn));"
386 [(set (attr "length") (if_then_else (ior (le (minus (match_dup 0)
387 (pc))
388 (const_int -128))
389 (ge (minus (match_dup 0)
390 (pc))
391 (const_int 128)))
392 (const_int 3)
393 (const_int 1)))])
394
395 (define_insn "bgeu"
396 [(set (pc)
397 (if_then_else (geu (cc0)
398 (const_int 0))
399 (label_ref (match_operand 0 "" ""))
400 (pc)))]
401 ""
402 "* return output_jump(\"bhis\", \"blo\", get_attr_length(insn));"
403 [(set (attr "length") (if_then_else (ior (le (minus (match_dup 0)
404 (pc))
405 (const_int -128))
406 (ge (minus (match_dup 0)
407 (pc))
408 (const_int 128)))
409 (const_int 3)
410 (const_int 1)))])
411
412 (define_insn "ble"
413 [(set (pc)
414 (if_then_else (le (cc0)
415 (const_int 0))
416 (label_ref (match_operand 0 "" ""))
417 (pc)))]
418 ""
419 "* return output_jump(\"ble\", \"bgt\", get_attr_length(insn));"
420 [(set (attr "length") (if_then_else (ior (le (minus (match_dup 0)
421 (pc))
422 (const_int -128))
423 (ge (minus (match_dup 0)
424 (pc))
425 (const_int 128)))
426 (const_int 3)
427 (const_int 1)))])
428
429 (define_insn "bleu"
430 [(set (pc)
431 (if_then_else (leu (cc0)
432 (const_int 0))
433 (label_ref (match_operand 0 "" ""))
434 (pc)))]
435 ""
436 "* return output_jump(\"blos\", \"bhi\", get_attr_length(insn));"
437 [(set (attr "length") (if_then_else (ior (le (minus (match_dup 0)
438 (pc))
439 (const_int -128))
440 (ge (minus (match_dup 0)
441 (pc))
442 (const_int 128)))
443 (const_int 3)
444 (const_int 1)))])
445
446 \f
447 ;; These match inverted jump insns for register allocation.
448
449 (define_insn ""
450 [(set (pc)
451 (if_then_else (eq (cc0)
452 (const_int 0))
453 (pc)
454 (label_ref (match_operand 0 "" ""))))]
455 ""
456 "* return output_jump(\"bne\", \"beq\", get_attr_length(insn));"
457 [(set (attr "length") (if_then_else (ior (le (minus (match_dup 0)
458 (pc))
459 (const_int -128))
460 (ge (minus (match_dup 0)
461 (pc))
462 (const_int 128)))
463 (const_int 3)
464 (const_int 1)))])
465
466 (define_insn ""
467 [(set (pc)
468 (if_then_else (ne (cc0)
469 (const_int 0))
470 (pc)
471 (label_ref (match_operand 0 "" ""))))]
472 ""
473 "* return output_jump(\"beq\", \"bne\", get_attr_length(insn));"
474 [(set (attr "length") (if_then_else (ior (le (minus (match_dup 0)
475 (pc))
476 (const_int -128))
477 (ge (minus (match_dup 0)
478 (pc))
479 (const_int 128)))
480 (const_int 3)
481 (const_int 1)))])
482
483 (define_insn ""
484 [(set (pc)
485 (if_then_else (gt (cc0)
486 (const_int 0))
487 (pc)
488 (label_ref (match_operand 0 "" ""))))]
489 ""
490 "* return output_jump(\"ble\", \"bgt\", get_attr_length(insn));"
491 [(set (attr "length") (if_then_else (ior (le (minus (match_dup 0)
492 (pc))
493 (const_int -128))
494 (ge (minus (match_dup 0)
495 (pc))
496 (const_int 128)))
497 (const_int 3)
498 (const_int 1)))])
499
500 (define_insn ""
501 [(set (pc)
502 (if_then_else (gtu (cc0)
503 (const_int 0))
504 (pc)
505 (label_ref (match_operand 0 "" ""))))]
506 ""
507 "* return output_jump(\"blos\", \"bhi\", get_attr_length(insn));"
508 [(set (attr "length") (if_then_else (ior (le (minus (match_dup 0)
509 (pc))
510 (const_int -128))
511 (ge (minus (match_dup 0)
512 (pc))
513 (const_int 128)))
514 (const_int 3)
515 (const_int 1)))])
516
517 (define_insn ""
518 [(set (pc)
519 (if_then_else (lt (cc0)
520 (const_int 0))
521 (pc)
522 (label_ref (match_operand 0 "" ""))))]
523 ""
524 "* return output_jump(\"bge\", \"blt\", get_attr_length(insn));"
525 [(set (attr "length") (if_then_else (ior (le (minus (match_dup 0)
526 (pc))
527 (const_int -128))
528 (ge (minus (match_dup 0)
529 (pc))
530 (const_int 128)))
531 (const_int 3)
532 (const_int 1)))])
533
534 (define_insn ""
535 [(set (pc)
536 (if_then_else (ltu (cc0)
537 (const_int 0))
538 (pc)
539 (label_ref (match_operand 0 "" ""))))]
540 ""
541 "* return output_jump(\"bhis\", \"blo\", get_attr_length(insn));"
542 [(set (attr "length") (if_then_else (ior (le (minus (match_dup 0)
543 (pc))
544 (const_int -128))
545 (ge (minus (match_dup 0)
546 (pc))
547 (const_int 128)))
548 (const_int 3)
549 (const_int 1)))])
550
551 (define_insn ""
552 [(set (pc)
553 (if_then_else (ge (cc0)
554 (const_int 0))
555 (pc)
556 (label_ref (match_operand 0 "" ""))))]
557 ""
558 "* return output_jump(\"blt\", \"bge\", get_attr_length(insn));"
559 [(set (attr "length") (if_then_else (ior (le (minus (match_dup 0)
560 (pc))
561 (const_int -128))
562 (ge (minus (match_dup 0)
563 (pc))
564 (const_int 128)))
565 (const_int 3)
566 (const_int 1)))])
567
568 (define_insn ""
569 [(set (pc)
570 (if_then_else (geu (cc0)
571 (const_int 0))
572 (pc)
573 (label_ref (match_operand 0 "" ""))))]
574 ""
575 "* return output_jump(\"blo\", \"bhis\", get_attr_length(insn));"
576 [(set (attr "length") (if_then_else (ior (le (minus (match_dup 0)
577 (pc))
578 (const_int -128))
579 (ge (minus (match_dup 0)
580 (pc))
581 (const_int 128)))
582 (const_int 3)
583 (const_int 1)))])
584
585 (define_insn ""
586 [(set (pc)
587 (if_then_else (le (cc0)
588 (const_int 0))
589 (pc)
590 (label_ref (match_operand 0 "" ""))))]
591 ""
592 "* return output_jump(\"bgt\", \"ble\", get_attr_length(insn));"
593 [(set (attr "length") (if_then_else (ior (le (minus (match_dup 0)
594 (pc))
595 (const_int -128))
596 (ge (minus (match_dup 0)
597 (pc))
598 (const_int 128)))
599 (const_int 3)
600 (const_int 1)))])
601
602 (define_insn ""
603 [(set (pc)
604 (if_then_else (leu (cc0)
605 (const_int 0))
606 (pc)
607 (label_ref (match_operand 0 "" ""))))]
608 ""
609 "* return output_jump(\"bhi\", \"blos\", get_attr_length(insn));"
610 [(set (attr "length") (if_then_else (ior (le (minus (match_dup 0)
611 (pc))
612 (const_int -128))
613 (ge (minus (match_dup 0)
614 (pc))
615 (const_int 128)))
616 (const_int 3)
617 (const_int 1)))])
618 \f
619 ;; Move instructions
620
621 (define_insn "movdi"
622 [(set (match_operand:DI 0 "general_operand" "=g")
623 (match_operand:DI 1 "general_operand" "g"))]
624 ""
625 "* return output_move_quad (operands);"
626 ;; what's the mose expensive code - say twice movsi = 16
627 [(set_attr "length" "16")])
628
629 (define_insn "movsi"
630 [(set (match_operand:SI 0 "general_operand" "=r,r,r,rm,m")
631 (match_operand:SI 1 "general_operand" "rN,IJ,K,m,r"))]
632 ""
633 "* return output_move_double (operands);"
634 ;; what's the most expensive code ? - I think 8!
635 ;; we could split it up and make several sub-cases...
636 [(set_attr "length" "2,3,4,8,8")])
637
638 (define_insn "movhi"
639 [(set (match_operand:HI 0 "general_operand" "=rR,rR,Q,Q")
640 (match_operand:HI 1 "general_operand" "rRN,Qi,rRN,Qi"))]
641 ""
642 "*
643 {
644 if (operands[1] == const0_rtx)
645 return \"clr %0\";
646
647 return \"mov %1, %0\";
648 }"
649 [(set_attr "length" "1,2,2,3")])
650
651 (define_insn "movqi"
652 [(set (match_operand:QI 0 "general_operand" "=rR,rR,Q,Q")
653 (match_operand:QI 1 "general_operand" "rRN,Qi,rRN,Qi"))]
654 ""
655 "*
656 {
657 if (operands[1] == const0_rtx)
658 return \"clrb %0\";
659
660 return \"movb %1, %0\";
661 }"
662 [(set_attr "length" "1,2,2,3")])
663
664 ;; do we have to supply all these moves? e.g. to
665 ;; NO_LOAD_FPU_REGs ?
666 (define_insn "movdf"
667 [(set (match_operand:DF 0 "general_operand" "=f,R,f,Q,f,m")
668 (match_operand:DF 1 "general_operand" "fR,f,Q,f,F,m"))]
669 ""
670 "* return output_move_quad (operands);"
671 ;; just a guess..
672 [(set_attr "length" "1,1,2,2,5,16")])
673
674 (define_insn "movsf"
675 [(set (match_operand:SF 0 "general_operand" "=g,r,g")
676 (match_operand:SF 1 "general_operand" "r,rmF,g"))]
677 "TARGET_FPU"
678 "* return output_move_double (operands);"
679 [(set_attr "length" "8,8,8")])
680
681 ;; maybe fiddle a bit with move_ratio, then
682 ;; let constraints only accept a register ...
683
684 (define_expand "movstrhi"
685 [(parallel [(set (match_operand:BLK 0 "general_operand" "=g,g")
686 (match_operand:BLK 1 "general_operand" "g,g"))
687 (use (match_operand:HI 2 "arith_operand" "n,&mr"))
688 (use (match_operand:HI 3 "immediate_operand" "i,i"))
689 (clobber (match_scratch:HI 4 "=&r,X"))
690 (clobber (match_dup 5))
691 (clobber (match_dup 6))
692 (clobber (match_dup 2))])]
693 "(TARGET_BCOPY_BUILTIN)"
694 "
695 {
696 operands[0]
697 = change_address (operands[0], VOIDmode,
698 copy_to_mode_reg (Pmode, XEXP (operands[0], 0)));
699 operands[1]
700 = change_address (operands[1], VOIDmode,
701 copy_to_mode_reg (Pmode, XEXP (operands[1], 0)));
702
703 operands[5] = XEXP (operands[0], 0);
704 operands[6] = XEXP (operands[1], 0);
705 }")
706
707
708 (define_insn "" ; "movstrhi"
709 [(set (mem:BLK (match_operand:HI 0 "general_operand" "=r,r"))
710 (mem:BLK (match_operand:HI 1 "general_operand" "r,r")))
711 (use (match_operand:HI 2 "arith_operand" "n,&r"))
712 (use (match_operand:HI 3 "immediate_operand" "i,i"))
713 (clobber (match_scratch:HI 4 "=&r,X"))
714 (clobber (match_dup 0))
715 (clobber (match_dup 1))
716 (clobber (match_dup 2))]
717 "(TARGET_BCOPY_BUILTIN)"
718 "* return output_block_move (operands);"
719 ;;; just a guess
720 [(set_attr "length" "40")])
721
722
723 \f
724 ;;- truncation instructions
725
726 (define_insn "truncdfsf2"
727 [(set (match_operand:SF 0 "general_operand" "=r,R,Q")
728 (float_truncate:SF (match_operand:DF 1 "register_operand" "a,a,a")))]
729 "TARGET_FPU"
730 "* if (which_alternative ==0)
731 {
732 output_asm_insn(\"stcdf %1, -(sp)\", operands);
733 output_asm_insn(\"mov (sp)+, %0\", operands);
734 operands[0] = gen_rtx(REG, HImode, REGNO (operands[0])+1);
735 output_asm_insn(\"mov (sp)+, %0\", operands);
736 return \"\";
737 }
738 else if (which_alternative == 1)
739 return \"stcdf %1, %0\";
740 else
741 return \"stcdf %1, %0\";
742 "
743 [(set_attr "length" "3,1,2")])
744
745
746 (define_expand "truncsihi2"
747 [(set (match_operand:HI 0 "general_operand" "=g")
748 (subreg:HI
749 (match_operand:SI 1 "general_operand" "or")
750 0))]
751 ""
752 "")
753
754 \f
755 ;;- zero extension instructions
756
757 (define_insn "zero_extendqihi2"
758 [(set (match_operand:HI 0 "general_operand" "=r")
759 (zero_extend:HI (match_operand:QI 1 "general_operand" "0")))]
760 ""
761 "bic $(256*255), %0"
762 [(set_attr "length" "2")])
763
764 (define_expand "zero_extendhisi2"
765 [(set (subreg:HI
766 (match_dup 0)
767 1)
768 (match_operand:HI 1 "register_operand" "r"))
769 (set (subreg:HI
770 (match_operand:SI 0 "register_operand" "=r")
771 0)
772 (const_int 0))]
773 ""
774 "/* operands[1] = make_safe_from (operands[1], operands[0]); */")
775
776 \f
777 ;;- sign extension instructions
778
779 (define_insn "extendsfdf2"
780 [(set (match_operand:DF 0 "register_operand" "=a,a,a")
781 (float_extend:DF (match_operand:SF 1 "general_operand" "r,R,Q")))]
782 "TARGET_FPU"
783 "@
784 mov %1, -(sp)\;ldcfd (sp)+,%0
785 ldcfd %1, %0
786 ldcfd %1, %0"
787 [(set_attr "length" "2,1,2")])
788
789 ;; does movb sign extend in register-to-register move?
790 (define_insn "extendqihi2"
791 [(set (match_operand:HI 0 "register_operand" "=r,r")
792 (sign_extend:HI (match_operand:QI 1 "general_operand" "rR,Q")))]
793 ""
794 "movb %1, %0"
795 [(set_attr "length" "1,2")])
796
797 (define_insn "extendqisi2"
798 [(set (match_operand:SI 0 "register_operand" "=r,r")
799 (sign_extend:SI (match_operand:QI 1 "general_operand" "rR,Q")))]
800 "TARGET_40_PLUS"
801 "*
802 {
803 rtx latehalf[2];
804
805 /* make register pair available */
806 latehalf[0] = operands[0];
807 operands[0] = gen_rtx(REG, HImode, REGNO (operands[0])+1);
808
809 output_asm_insn(\"movb %1, %0\", operands);
810 output_asm_insn(\"sxt %0\", latehalf);
811
812 return \"\";
813 }"
814 [(set_attr "length" "2,3")])
815
816 ;; maybe we have to use define_expand to say that we have the instruction,
817 ;; unconditionally, and then match dependent on CPU type:
818
819 (define_expand "extendhisi2"
820 [(set (match_operand:SI 0 "general_operand" "=g")
821 (sign_extend:SI (match_operand:HI 1 "general_operand" "g")))]
822 ""
823 "")
824
825 (define_insn "" ; "extendhisi2"
826 [(set (match_operand:SI 0 "general_operand" "=o,<,r")
827 (sign_extend:SI (match_operand:HI 1 "general_operand" "g,g,g")))]
828 "TARGET_40_PLUS"
829 "*
830 {
831 rtx latehalf[2];
832
833 /* we don't want to mess with auto increment */
834
835 switch(which_alternative)
836 {
837 case 0:
838
839 latehalf[0] = operands[0];
840 operands[0] = adj_offsettable_operand(operands[0], 2);
841
842 output_asm_insn(\"mov %1, %0\", operands);
843 output_asm_insn(\"sxt %0\", latehalf);
844
845 return \"\";
846
847 case 1:
848
849 /* - auto-decrement - right direction ;-) */
850 output_asm_insn(\"mov %1, %0\", operands);
851 output_asm_insn(\"sxt %0\", operands);
852
853 return \"\";
854
855 case 2:
856
857 /* make register pair available */
858 latehalf[0] = operands[0];
859 operands[0] = gen_rtx(REG, HImode, REGNO (operands[0])+1);
860
861 output_asm_insn(\"mov %1, %0\", operands);
862 output_asm_insn(\"sxt %0\", latehalf);
863
864 return \"\";
865
866 default:
867
868 abort();
869 }
870 }"
871 [(set_attr "length" "5,3,3")])
872
873
874 (define_insn ""
875 [(set (match_operand:SI 0 "register_operand" "=r")
876 (sign_extend:SI (match_operand:HI 1 "general_operand" "0")))]
877 "(! TARGET_40_PLUS)"
878 "*
879 {
880 static count = 0;
881 char buf[100];
882 rtx lateoperands[2];
883
884 lateoperands[0] = operands[0];
885 operands[0] = gen_rtx(REG, HImode, REGNO (operands[0])+1);
886
887 output_asm_insn(\"tst %0\", operands);
888 sprintf(buf, \"bge extendhisi%d\", count);
889 output_asm_insn(buf, NULL);
890 output_asm_insn(\"mov -1, %0\", lateoperands);
891 sprintf(buf, \"bne extendhisi%d\", count+1);
892 output_asm_insn(buf, NULL);
893 sprintf(buf, \"\\nextendhisi%d:\", count);
894 output_asm_insn(buf, NULL);
895 output_asm_insn(\"clr %0\", lateoperands);
896 sprintf(buf, \"\\nextendhisi%d:\", count+1);
897 output_asm_insn(buf, NULL);
898
899 count += 2;
900
901 return \"\";
902 }"
903 [(set_attr "length" "6")])
904
905 ;; make float to int and vice versa
906 ;; using the cc_status.flag field we could probably cut down
907 ;; on seti and setl
908 ;; assume that we are normally in double and integer mode -
909 ;; what do pdp library routines do to fpu mode ?
910
911 (define_insn "floatsidf2"
912 [(set (match_operand:DF 0 "register_operand" "=a,a,a")
913 (float:DF (match_operand:SI 1 "general_operand" "r,R,Q")))]
914 "TARGET_FPU"
915 "* if (which_alternative ==0)
916 {
917 rtx latehalf[2];
918
919 latehalf[0] = NULL;
920 latehalf[1] = gen_rtx(REG, HImode, REGNO (operands[0])+1);
921 output_asm_insn(\"mov %1, -(sp)\", latehalf);
922 output_asm_insn(\"mov %1, -(sp)\", operands);
923
924 output_asm_insn(\"setl\", operands);
925 output_asm_insn(\"ldcld (sp)+, %0\", operands);
926 output_asm_insn(\"seti\", operands);
927 return \"\";
928 }
929 else if (which_alternative == 1)
930 return \"setl\;ldcld %1, %0\;seti\";
931 else
932 return \"setl\;ldcld %1, %0\;seti\";
933 "
934 [(set_attr "length" "5,3,4")])
935
936 (define_insn "floathidf2"
937 [(set (match_operand:DF 0 "register_operand" "=a,a")
938 (float:DF (match_operand:HI 1 "general_operand" "rR,Qi")))]
939 "TARGET_FPU"
940 "ldcid %1, %0"
941 [(set_attr "length" "1,2")])
942
943 ;; cut float to int
944 (define_insn "fix_truncdfsi2"
945 [(set (match_operand:SI 0 "general_operand" "=r,R,Q")
946 (fix:SI (fix:DF (match_operand:DF 1 "register_operand" "a,a,a"))))]
947 "TARGET_FPU"
948 "* if (which_alternative ==0)
949 {
950 output_asm_insn(\"setl\", operands);
951 output_asm_insn(\"stcdl %1, -(sp)\", operands);
952 output_asm_insn(\"seti\", operands);
953 output_asm_insn(\"mov (sp)+, %0\", operands);
954 operands[0] = gen_rtx(REG, HImode, REGNO (operands[0])+1);
955 output_asm_insn(\"mov (sp)+, %0\", operands);
956 return \"\";
957 }
958 else if (which_alternative == 1)
959 return \"setl\;stcdl %1, %0\;seti\";
960 else
961 return \"setl\;stcdl %1, %0\;seti\";
962 "
963 [(set_attr "length" "5,3,4")])
964
965 (define_insn "fix_truncdfhi2"
966 [(set (match_operand:HI 0 "general_operand" "=rR,Q")
967 (fix:HI (fix:DF (match_operand:DF 1 "register_operand" "a,a"))))]
968 "TARGET_FPU"
969 "stcdi %1, %0"
970 [(set_attr "length" "1,2")])
971
972 \f
973 ;;- arithmetic instructions
974 ;;- add instructions
975
976 (define_insn "adddf3"
977 [(set (match_operand:DF 0 "register_operand" "=a,a,a")
978 (plus:DF (match_operand:DF 1 "register_operand" "%0,0,0")
979 (match_operand:DF 2 "general_operand" "fR,Q,F")))]
980 "TARGET_FPU"
981 "addd %2, %0"
982 [(set_attr "length" "1,2,5")])
983
984 (define_insn "addsi3"
985 [(set (match_operand:SI 0 "general_operand" "=r,r,o,o,r,r,r,o,o,o")
986 (plus:SI (match_operand:SI 1 "general_operand" "%0,0,0,0,0,0,0,0,0,0")
987 (match_operand:SI 2 "general_operand" "r,o,r,o,I,J,K,I,J,K")))]
988 ""
989 "*
990 { /* Here we trust that operands don't overlap
991
992 or is lateoperands the low word?? - looks like it! */
993
994 unsigned int i;
995 rtx lateoperands[3];
996
997 lateoperands[0] = operands[0];
998
999 if (REG_P (operands[0]))
1000 operands[0] = gen_rtx(REG, HImode, REGNO(operands[0]) + 1);
1001 else
1002 operands[0] = adj_offsettable_operand (operands[0], 2);
1003
1004 if (! CONSTANT_P(operands[2]))
1005 {
1006 lateoperands[2] = operands[2];
1007
1008 if (REG_P (operands[2]))
1009 operands[2] = gen_rtx(REG, HImode, REGNO(operands[2]) + 1);
1010 else
1011 operands[2] = adj_offsettable_operand(operands[2], 2);
1012
1013 output_asm_insn (\"add %2, %0\", operands);
1014 output_asm_insn (\"adc %0\", lateoperands);
1015 output_asm_insn (\"add %2, %0\", lateoperands);
1016 return \"\";
1017 }
1018
1019 lateoperands[2] = GEN_INT ((INTVAL(operands[2]) >> 16) & 0xffff);
1020 operands[2] = GEN_INT (INTVAL(operands[2]) & 0xffff);
1021
1022 if (INTVAL(operands[2]))
1023 {
1024 output_asm_insn (\"add %2, %0\", operands);
1025 output_asm_insn (\"adc %0\", lateoperands);
1026 }
1027
1028 if (INTVAL(lateoperands[2]))
1029 output_asm_insn (\"add %2, %0\", lateoperands);
1030
1031 return \"\";
1032 }"
1033 [(set_attr "length" "3,5,6,8,3,1,5,5,3,8")])
1034
1035 (define_insn "addhi3"
1036 [(set (match_operand:HI 0 "general_operand" "=rR,rR,Q,Q")
1037 (plus:HI (match_operand:HI 1 "general_operand" "%0,0,0,0")
1038 (match_operand:HI 2 "general_operand" "rRLM,Qi,rRLM,Qi")))]
1039 ""
1040 "*
1041 {
1042 if (GET_CODE (operands[2]) == CONST_INT)
1043 if (INTVAL(operands[2]) == 1)
1044 return \"inc %0\";
1045 else if (INTVAL(operands[2]) == -1)
1046 return \"dec %0\";
1047
1048 return \"add %2, %0\";
1049 }"
1050 [(set_attr "length" "1,2,2,3")])
1051
1052 (define_insn "addqi3"
1053 [(set (match_operand:QI 0 "general_operand" "=rR,rR,Q,Q")
1054 (plus:QI (match_operand:QI 1 "general_operand" "%0,0,0,0")
1055 (match_operand:QI 2 "general_operand" "rRLM,Qi,rRLM,Qi")))]
1056 ""
1057 "*
1058 {
1059 if (GET_CODE (operands[2]) == CONST_INT)
1060 if (INTVAL(operands[2]) == 1)
1061 return \"incb %0\";
1062 else if (INTVAL(operands[2]) == -1)
1063 return \"decb %0\";
1064
1065 return \"addb %2, %0\";
1066 }"
1067 [(set_attr "length" "1,2,2,3")])
1068
1069 \f
1070 ;;- subtract instructions
1071 ;; we don't have to care for constant second
1072 ;; args, since they are canonical plus:xx now!
1073 ;; also for minus:DF ??
1074
1075 (define_insn "subdf3"
1076 [(set (match_operand:DF 0 "register_operand" "=a,a")
1077 (minus:DF (match_operand:DF 1 "register_operand" "0,0")
1078 (match_operand:DF 2 "general_operand" "fR,Q")))]
1079 "TARGET_FPU"
1080 "subd %2, %0"
1081 [(set_attr "length" "1,2")])
1082
1083 (define_insn "subsi3"
1084 [(set (match_operand:SI 0 "general_operand" "=r,r,o,o")
1085 (minus:SI (match_operand:SI 1 "general_operand" "0,0,0,0")
1086 (match_operand:SI 2 "general_operand" "r,o,r,o")))]
1087 ""
1088 "*
1089 { /* Here we trust that operands don't overlap
1090
1091 or is lateoperands the low word?? - looks like it! */
1092
1093 unsigned int i;
1094 rtx lateoperands[3];
1095
1096 lateoperands[0] = operands[0];
1097
1098 if (REG_P (operands[0]))
1099 operands[0] = gen_rtx(REG, HImode, REGNO(operands[0]) + 1);
1100 else
1101 operands[0] = adj_offsettable_operand (operands[0], 2);
1102
1103 lateoperands[2] = operands[2];
1104
1105 if (REG_P (operands[2]))
1106 operands[2] = gen_rtx(REG, HImode, REGNO(operands[2]) + 1);
1107 else
1108 operands[2] = adj_offsettable_operand(operands[2], 2);
1109
1110 output_asm_insn (\"sub %2, %0\", operands);
1111 output_asm_insn (\"sbc %0\", lateoperands);
1112 output_asm_insn (\"sub %2, %0\", lateoperands);
1113 return \"\";
1114 }"
1115 ;; offsettable memory addresses always are expensive!!!
1116 [(set_attr "length" "3,5,6,8")])
1117
1118 (define_insn "subhi3"
1119 [(set (match_operand:HI 0 "general_operand" "=rR,rR,Q,Q")
1120 (minus:HI (match_operand:HI 1 "general_operand" "0,0,0,0")
1121 (match_operand:HI 2 "general_operand" "rR,Qi,rR,Qi")))]
1122 ""
1123 "*
1124 {
1125 if (GET_CODE (operands[2]) == CONST_INT)
1126 abort();
1127
1128 return \"sub %2, %0\";
1129 }"
1130 [(set_attr "length" "1,2,2,3")])
1131
1132 (define_insn "subqi3"
1133 [(set (match_operand:QI 0 "general_operand" "=rR,rR,Q,Q")
1134 (minus:QI (match_operand:QI 1 "general_operand" "0,0,0,0")
1135 (match_operand:QI 2 "general_operand" "rR,Qi,rR,Qi")))]
1136 ""
1137 "*
1138 {
1139 if (GET_CODE (operands[2]) == CONST_INT)
1140 abort();
1141
1142 return \"subb %2, %0\";
1143 }"
1144 [(set_attr "length" "1,2,2,3")])
1145
1146 ;;;;- and instructions
1147 ;; Bit-and on the pdp (like on the vax) is done with a clear-bits insn.
1148 (define_expand "andsi3"
1149 [(set (match_operand:SI 0 "general_operand" "=g")
1150 (and:SI (match_operand:SI 1 "general_operand" "0")
1151 (not:SI (match_operand:SI 2 "general_operand" "g"))))]
1152 ""
1153 "
1154 {
1155 extern rtx expand_unop ();
1156 if (GET_CODE (operands[2]) == CONST_INT)
1157 operands[2] = GEN_INT (~INTVAL (operands[2]));
1158 else
1159 operands[2] = expand_unop (SImode, one_cmpl_optab, operands[2], 0, 1);
1160 }")
1161
1162 (define_expand "andhi3"
1163 [(set (match_operand:HI 0 "general_operand" "=g")
1164 (and:HI (match_operand:HI 1 "general_operand" "0")
1165 (not:HI (match_operand:HI 2 "general_operand" "g"))))]
1166 ""
1167 "
1168 {
1169 extern rtx expand_unop ();
1170 if (GET_CODE (operands[2]) == CONST_INT)
1171 operands[2] = GEN_INT (~INTVAL (operands[2]));
1172 else
1173 operands[2] = expand_unop (HImode, one_cmpl_optab, operands[2], 0, 1);
1174 }")
1175
1176 (define_expand "andqi3"
1177 [(set (match_operand:QI 0 "general_operand" "=g")
1178 (and:QI (match_operand:QI 1 "general_operand" "0")
1179 (not:QI (match_operand:QI 2 "general_operand" "g"))))]
1180 ""
1181 "
1182 {
1183 extern rtx expand_unop ();
1184 rtx op = operands[2];
1185 if (GET_CODE (op) == CONST_INT)
1186 operands[2] = GEN_INT (((1 << 8) - 1) & ~INTVAL (op));
1187 else
1188 operands[2] = expand_unop (QImode, one_cmpl_optab, op, 0, 1);
1189 }")
1190
1191 (define_insn "andcbsi3"
1192 [(set (match_operand:SI 0 "general_operand" "=r,r,o,o,r,r,r,o,o,o")
1193 (and:SI (match_operand:SI 1 "general_operand" "%0,0,0,0,0,0,0,0,0,0")
1194 (not:SI (match_operand:SI 2 "general_operand" "r,o,r,o,I,J,K,I,J,K"))))]
1195 ""
1196 "*
1197 { /* Here we trust that operands don't overlap
1198
1199 or is lateoperands the low word?? - looks like it! */
1200
1201 unsigned int i;
1202 rtx lateoperands[3];
1203
1204 lateoperands[0] = operands[0];
1205
1206 if (REG_P (operands[0]))
1207 operands[0] = gen_rtx(REG, HImode, REGNO(operands[0]) + 1);
1208 else
1209 operands[0] = adj_offsettable_operand (operands[0], 2);
1210
1211 if (! CONSTANT_P(operands[2]))
1212 {
1213 lateoperands[2] = operands[2];
1214
1215 if (REG_P (operands[2]))
1216 operands[2] = gen_rtx(REG, HImode, REGNO(operands[2]) + 1);
1217 else
1218 operands[2] = adj_offsettable_operand(operands[2], 2);
1219
1220 output_asm_insn (\"bic %2, %0\", operands);
1221 output_asm_insn (\"bic %2, %0\", lateoperands);
1222 return \"\";
1223 }
1224
1225 lateoperands[2] = GEN_INT ((INTVAL(operands[2]) >> 16) & 0xffff);
1226 operands[2] = GEN_INT (INTVAL(operands[2]) & 0xffff);
1227
1228 /* these have different lengths, so we should have
1229 different constraints! */
1230 if (INTVAL(operands[2]))
1231 output_asm_insn (\"bic %2, %0\", operands);
1232
1233 if (INTVAL(lateoperands[2]))
1234 output_asm_insn (\"bic %2, %0\", lateoperands);
1235
1236 return \"\";
1237 }"
1238 [(set_attr "length" "2,4,4,6,2,2,4,3,3,6")])
1239
1240 (define_insn "andcbhi3"
1241 [(set (match_operand:HI 0 "general_operand" "=rR,rR,Q,Q")
1242 (and:HI (match_operand:HI 1 "general_operand" "0,0,0,0")
1243 (not:HI (match_operand:HI 2 "general_operand" "rR,Qi,rR,Qi"))))]
1244 ""
1245 "bic %2, %0"
1246 [(set_attr "length" "1,2,2,3")])
1247
1248 (define_insn "andcbqi3"
1249 [(set (match_operand:QI 0 "general_operand" "=rR,rR,Q,Q")
1250 (and:QI (match_operand:QI 1 "general_operand" "0,0,0,0")
1251 (not:QI (match_operand:QI 2 "general_operand" "rR,Qi,rR,Qi"))))]
1252 ""
1253 "bicb %2, %0"
1254 [(set_attr "length" "1,2,2,3")])
1255
1256 ;;- Bit set (inclusive or) instructions
1257 (define_insn "iorsi3"
1258 [(set (match_operand:SI 0 "general_operand" "=r,r,o,o,r,r,r,o,o,o")
1259 (ior:SI (match_operand:SI 1 "general_operand" "%0,0,0,0,0,0,0,0,0,0")
1260 (match_operand:SI 2 "general_operand" "r,o,r,o,I,J,K,I,J,K")))]
1261 ""
1262 "*
1263 { /* Here we trust that operands don't overlap
1264
1265 or is lateoperands the low word?? - looks like it! */
1266
1267 unsigned int i;
1268 rtx lateoperands[3];
1269
1270 lateoperands[0] = operands[0];
1271
1272 if (REG_P (operands[0]))
1273 operands[0] = gen_rtx(REG, HImode, REGNO(operands[0]) + 1);
1274 else
1275 operands[0] = adj_offsettable_operand (operands[0], 2);
1276
1277 if (! CONSTANT_P(operands[2]))
1278 {
1279 lateoperands[2] = operands[2];
1280
1281 if (REG_P (operands[2]))
1282 operands[2] = gen_rtx(REG, HImode, REGNO(operands[2]) + 1);
1283 else
1284 operands[2] = adj_offsettable_operand(operands[2], 2);
1285
1286 output_asm_insn (\"bis %2, %0\", operands);
1287 output_asm_insn (\"bis %2, %0\", lateoperands);
1288 return \"\";
1289 }
1290
1291 lateoperands[2] = GEN_INT ((INTVAL(operands[2]) >> 16) & 0xffff);
1292 operands[2] = GEN_INT (INTVAL(operands[2]) & 0xffff);
1293
1294 /* these have different lengths, so we should have
1295 different constraints! */
1296 if (INTVAL(operands[2]))
1297 output_asm_insn (\"bis %2, %0\", operands);
1298
1299 if (INTVAL(lateoperands[2]))
1300 output_asm_insn (\"bis %2, %0\", lateoperands);
1301
1302 return \"\";
1303 }"
1304 [(set_attr "length" "2,4,4,6,2,2,4,3,3,6")])
1305
1306 (define_insn "iorhi3"
1307 [(set (match_operand:HI 0 "general_operand" "=rR,rR,Q,Q")
1308 (ior:HI (match_operand:HI 1 "general_operand" "%0,0,0,0")
1309 (match_operand:HI 2 "general_operand" "rR,Qi,rR,Qi")))]
1310 ""
1311 "bis %2, %0"
1312 [(set_attr "length" "1,2,2,3")])
1313
1314 (define_insn "iorqi3"
1315 [(set (match_operand:QI 0 "general_operand" "=rR,rR,Q,Q")
1316 (ior:QI (match_operand:QI 1 "general_operand" "%0,0,0,0")
1317 (match_operand:QI 2 "general_operand" "rR,Qi,rR,Qi")))]
1318 ""
1319 "bisb %2, %0")
1320
1321 ;;- xor instructions
1322 (define_insn "xorsi3"
1323 [(set (match_operand:SI 0 "register_operand" "=r,r,r,r")
1324 (xor:SI (match_operand:SI 1 "register_operand" "%0,0,0,0")
1325 (match_operand:SI 2 "arith_operand" "r,I,J,K")))]
1326 "TARGET_40_PLUS"
1327 "*
1328 { /* Here we trust that operands don't overlap */
1329
1330 unsigned int i;
1331 rtx lateoperands[3];
1332
1333 lateoperands[0] = operands[0];
1334 operands[0] = gen_rtx(REG, HImode, REGNO(operands[0]) + 1);
1335
1336 if (REG_P(operands[2]))
1337 {
1338 lateoperands[2] = operands[2];
1339 operands[2] = gen_rtx(REG, HImode, REGNO(operands[2]) + 1);
1340
1341 output_asm_insn (\"xor %2, %0\", operands);
1342 output_asm_insn (\"xor %2, %0\", lateoperands);
1343
1344 return \"\";
1345 }
1346
1347 lateoperands[2] = GEN_INT ((INTVAL(operands[2]) >> 16) & 0xffff);
1348 operands[2] = GEN_INT (INTVAL(operands[2]) & 0xffff);
1349
1350 if (INTVAL(operands[2]))
1351 output_asm_insn (\"xor %2, %0\", operands);
1352
1353 if (INTVAL(lateoperands[2]))
1354 output_asm_insn (\"xor %2, %0\", lateoperands);
1355
1356 return \"\";
1357 }"
1358 [(set_attr "length" "2,1,1,2")])
1359
1360 (define_insn "xorhi3"
1361 [(set (match_operand:HI 0 "general_operand" "=rR,Q")
1362 (xor:HI (match_operand:HI 1 "general_operand" "%0,0")
1363 (match_operand:HI 2 "register_operand" "r,r")))]
1364 "TARGET_40_PLUS"
1365 "xor %2, %0"
1366 [(set_attr "length" "1,2")])
1367
1368 ;;- one complement instructions
1369
1370 (define_insn "one_cmplhi2"
1371 [(set (match_operand:HI 0 "general_operand" "=rR,Q")
1372 (not:HI (match_operand:HI 1 "general_operand" "0,0")))]
1373 ""
1374 "com %0"
1375 [(set_attr "length" "1,2")])
1376
1377 (define_insn "one_cmplqi2"
1378 [(set (match_operand:QI 0 "general_operand" "=rR,Q")
1379 (not:QI (match_operand:QI 1 "general_operand" "0,0")))]
1380 ""
1381 "comb %0"
1382 [(set_attr "length" "1,2")])
1383
1384 ;;- arithmetic shift instructions
1385 (define_insn "ashlsi3"
1386 [(set (match_operand:SI 0 "register_operand" "=r,r")
1387 (ashift:SI (match_operand:SI 1 "register_operand" "0,0")
1388 (match_operand:HI 2 "general_operand" "rR,Qi")))]
1389 "TARGET_45"
1390 "ashc %2,%0"
1391 [(set_attr "length" "1,2")])
1392
1393 ;; Arithmetic right shift on the pdp works by negating the shift count.
1394 (define_expand "ashrsi3"
1395 [(set (match_operand:SI 0 "register_operand" "=r")
1396 (ashift:SI (match_operand:SI 1 "register_operand" "0")
1397 (match_operand:HI 2 "general_operand" "g")))]
1398 ""
1399 "
1400 {
1401 operands[2] = negate_rtx (HImode, operands[2]);
1402 }")
1403
1404 ;; define asl aslb asr asrb - ashc missing!
1405
1406 ;; asl
1407 (define_insn ""
1408 [(set (match_operand:HI 0 "general_operand" "=rR,Q")
1409 (ashift:HI (match_operand:HI 1 "general_operand" "0,0")
1410 (const_int 1)))]
1411 ""
1412 "asl %0"
1413 [(set_attr "length" "1,2")])
1414
1415 ;; and another possibility for asr is << -1
1416 ;; might cause problems since -1 can also be encoded as 65535!
1417 ;; not in gcc2 ???
1418
1419 ;; asr
1420 (define_insn ""
1421 [(set (match_operand:HI 0 "general_operand" "=rR,Q")
1422 (ashift:HI (match_operand:HI 1 "general_operand" "0,0")
1423 (const_int -1)))]
1424 ""
1425 "asr %0"
1426 [(set_attr "length" "1,2")])
1427
1428 ;; shift is by arbitrary count is expensive,
1429 ;; shift by one cheap - so let's do that, if
1430 ;; space doesn't matter
1431 (define_insn ""
1432 [(set (match_operand:HI 0 "general_operand" "=r")
1433 (ashift:HI (match_operand:HI 1 "general_operand" "0")
1434 (match_operand:HI 2 "expand_shift_operand" "O")))]
1435 "TARGET_TIME"
1436 "*
1437 {
1438 register int i;
1439
1440 for (i = 1; i <= abs(INTVAL(operands[2])); i++)
1441 if (INTVAL(operands[2]) < 0)
1442 output_asm_insn(\"asr %0\", operands);
1443 else
1444 output_asm_insn(\"asl %0\", operands);
1445
1446 return \"\";
1447 }"
1448 ;; longest is 4
1449 [(set (attr "length") (const_int 4))])
1450
1451 ;; aslb
1452 (define_insn ""
1453 [(set (match_operand:QI 0 "general_operand" "=r,o")
1454 (ashift:QI (match_operand:QI 1 "general_operand" "0,0")
1455 (match_operand:HI 2 "const_immediate_operand" "n,n")))]
1456 ""
1457 "*
1458 { /* allowing predec or post_inc is possible, but hairy! */
1459 int i, cnt;
1460
1461 cnt = INTVAL(operands[2]) & 0x0007;
1462
1463 for (i=0 ; i < cnt ; i++)
1464 output_asm_insn(\"aslb %0\", operands);
1465
1466 return \"\";
1467 }"
1468 ;; set attribute length ( match_dup 2 & 7 ) *(1 or 2) !!!
1469 [(set_attr_alternative "length"
1470 [(const_int 7)
1471 (const_int 14)])])
1472
1473 ;;; asr
1474 ;(define_insn ""
1475 ; [(set (match_operand:HI 0 "general_operand" "=rR,Q")
1476 ; (ashiftrt:HI (match_operand:HI 1 "general_operand" "0,0")
1477 ; (const_int 1)))]
1478 ; ""
1479 ; "asr %0"
1480 ; [(set_attr "length" "1,2")])
1481
1482 ;; asrb
1483 (define_insn ""
1484 [(set (match_operand:QI 0 "general_operand" "=r,o")
1485 (ashiftrt:QI (match_operand:QI 1 "general_operand" "0,0")
1486 (match_operand:HI 2 "const_immediate_operand" "n,n")))]
1487 ""
1488 "*
1489 { /* allowing predec or post_inc is possible, but hairy! */
1490 int i, cnt;
1491
1492 cnt = INTVAL(operands[2]) & 0x0007;
1493
1494 for (i=0 ; i < cnt ; i++)
1495 output_asm_insn(\"asrb %0\", operands);
1496
1497 return \"\";
1498 }"
1499 [(set_attr_alternative "length"
1500 [(const_int 7)
1501 (const_int 14)])])
1502
1503 ;; the following is invalid - too complex!!! - just say 14 !!!
1504 ; [(set (attr "length") (plus (and (match_dup 2)
1505 ; (const_int 7))
1506 ; (and (match_dup 2)
1507 ; (const_int 7))))])
1508
1509
1510
1511 ;; can we get +-1 in the next pattern? should
1512 ;; have been caught by previous patterns!
1513
1514 (define_insn "ashlhi3"
1515 [(set (match_operand:HI 0 "register_operand" "=r,r")
1516 (ashift:HI (match_operand:HI 1 "register_operand" "0,0")
1517 (match_operand:HI 2 "general_operand" "rR,Qi")))]
1518 ""
1519 "*
1520 {
1521 if (GET_CODE(operands[2]) == CONST_INT)
1522 if (INTVAL(operands[2]) == 1)
1523 return \"asl %0\";
1524 else if (INTVAL(operands[2]) == -1)
1525 return \"asr %0\";
1526
1527 return \"ash %2,%0\";
1528 }"
1529 [(set_attr "length" "1,2")])
1530
1531 ;; Arithmetic right shift on the pdp works by negating the shift count.
1532 (define_expand "ashrhi3"
1533 [(set (match_operand:HI 0 "register_operand" "=r")
1534 (ashift:HI (match_operand:HI 1 "register_operand" "0")
1535 (match_operand:HI 2 "general_operand" "g")))]
1536 ""
1537 "
1538 {
1539 operands[2] = negate_rtx (HImode, operands[2]);
1540 }")
1541
1542 ;;;;- logical shift instructions
1543 ;;(define_insn "lshrsi3"
1544 ;; [(set (match_operand:HI 0 "register_operand" "=r")
1545 ;; (lshiftrt:HI (match_operand:HI 1 "register_operand" "0")
1546 ;; (match_operand:HI 2 "arith_operand" "rI")))]
1547 ;; ""
1548 ;; "srl %0,%2")
1549
1550 ;; absolute
1551
1552 (define_insn "absdf2"
1553 [(set (match_operand:DF 0 "general_operand" "=fR,Q")
1554 (abs:DF (match_operand:DF 1 "general_operand" "0,0")))]
1555 "TARGET_FPU"
1556 "absd %0"
1557 [(set_attr "length" "1,2")])
1558
1559 (define_insn "abshi2"
1560 [(set (match_operand:HI 0 "general_operand" "=r,o")
1561 (abs:HI (match_operand:HI 1 "general_operand" "0,0")))]
1562 "TARGET_ABSHI_BUILTIN"
1563 "*
1564 {
1565 static count = 0;
1566 char buf[200];
1567
1568 output_asm_insn(\"tst %0\", operands);
1569 sprintf(buf, \"bge abshi%d\", count);
1570 output_asm_insn(buf, NULL);
1571 output_asm_insn(\"neg %0\", operands);
1572 sprintf(buf, \"\\nabshi%d:\", count++);
1573 output_asm_insn(buf, NULL);
1574
1575 return \"\";
1576 }"
1577 [(set_attr "length" "3,5")])
1578
1579
1580 ;; define expand abshi - is much better !!! - but
1581 ;; will it be optimized into an abshi2 ?
1582 ;; it will leave better code, because the tsthi might be
1583 ;; optimized away!!
1584 ; -- just a thought - don't have time to check
1585 ;
1586 ;(define_expand "abshi2"
1587 ; [(match_operand:HI 0 "general_operand" "")
1588 ; (match_operand:HI 1 "general_operand" "")]
1589 ; ""
1590 ; "
1591 ;{
1592 ; rtx label = gen_label_rtx ();
1593 ;
1594 ; /* do I need this? */
1595 ; do_pending_stack_adjust ();
1596 ;
1597 ; emit_move_insn (operands[0], operands[1]);
1598 ;
1599 ; emit_insn (gen_tsthi (operands[0]));
1600 ; emit_insn (gen_bge (label1));
1601 ;
1602 ; emit_insn (gen_neghi(operands[0], operands[0])
1603 ;
1604 ; emit_barrier ();
1605 ;
1606 ; emit_label (label);
1607 ;
1608 ; /* allow REG_NOTES to be set on last insn (labels don't have enough
1609 ; fields, and can't be used for REG_NOTES anyway). */
1610 ; emit_insn (gen_rtx (USE, VOIDmode, stack_pointer_rtx));
1611 ; DONE;
1612 ;}")
1613
1614 ;; negate insns
1615
1616 (define_insn "negdf2"
1617 [(set (match_operand:DF 0 "general_operand" "=fR,Q")
1618 (neg:DF (match_operand:DF 1 "register_operand" "0,0")))]
1619 "TARGET_FPU"
1620 "negd %0"
1621 [(set_attr "length" "1,2")])
1622
1623 (define_insn "neghi2"
1624 [(set (match_operand:HI 0 "general_operand" "=rR,Q")
1625 (neg:HI (match_operand:HI 1 "general_operand" "0,0")))]
1626 ""
1627 "neg %0"
1628 [(set_attr "length" "1,2")])
1629
1630 (define_insn "negqi2"
1631 [(set (match_operand:QI 0 "general_operand" "=rR,Q")
1632 (neg:QI (match_operand:QI 1 "general_operand" "0,0")))]
1633 ""
1634 "negb %0"
1635 [(set_attr "length" "1,2")])
1636
1637
1638 ;; Unconditional and other jump instructions
1639 (define_insn "jump"
1640 [(set (pc)
1641 (label_ref (match_operand 0 "" "")))]
1642 ""
1643 "jmp %l0"
1644 [(set_attr "length" "2")])
1645
1646 (define_insn ""
1647 [(set (pc)
1648 (label_ref (match_operand 0 "" "")))
1649 (clobber (const_int 1))]
1650 ""
1651 "jmp %l0"
1652 [(set_attr "length" "2")])
1653
1654 (define_insn "tablejump"
1655 [(set (pc) (match_operand:HI 0 "general_operand" "rR,Q"))
1656 (use (label_ref (match_operand 1 "" "")))]
1657 ""
1658 "jmp %0"
1659 [(set_attr "length" "1,2")])
1660
1661 ;; indirect jump - let's be conservative!
1662 ;; allow only register_operand, even though we could also
1663 ;; allow labels etc.
1664
1665 (define_insn "indirect_jump"
1666 [(set (pc) (match_operand:HI 0 "register_operand" "r"))]
1667 ""
1668 "jmp (%0)")
1669
1670 ;;- jump to subroutine
1671
1672 (define_insn "call"
1673 [(call (match_operand:HI 0 "general_operand" "R,Q")
1674 (match_operand:HI 1 "general_operand" "g,g"))
1675 ;; (use (reg:HI 0)) what was that ???
1676 ]
1677 ;;- Don't use operand 1 for most machines.
1678 ""
1679 "jsr pc, %0"
1680 [(set_attr "length" "1,2")])
1681
1682 ;;- jump to subroutine
1683 (define_insn "call_value"
1684 [(set (match_operand 0 "" "")
1685 (call (match_operand:HI 1 "general_operand" "R,Q")
1686 (match_operand:HI 2 "general_operand" "g,g")))
1687 ;; (use (reg:HI 0)) - what was that ????
1688 ]
1689 ;;- Don't use operand 2 for most machines.
1690 ""
1691 "jsr pc, %1"
1692 [(set_attr "length" "1,2")])
1693
1694 ;;- nop instruction
1695 (define_insn "nop"
1696 [(const_int 0)]
1697 ""
1698 "nop")
1699 \f
1700
1701 ;;- multiply
1702
1703 (define_insn "muldf3"
1704 [(set (match_operand:DF 0 "register_operand" "=a,a,a")
1705 (mult:DF (match_operand:DF 1 "register_operand" "%0,0,0")
1706 (match_operand:DF 2 "general_operand" "fR,Q,F")))]
1707 "TARGET_FPU"
1708 "muld %2, %0"
1709 [(set_attr "length" "1,2,5")])
1710
1711 ;; 16 bit result multiply:
1712 ;; currently we multiply only into odd registers, so we don't use two
1713 ;; registers - but this is a bit inefficient at times. If we define
1714 ;; a register class for each register, then we can specify properly
1715 ;; which register need which scratch register ....
1716
1717 (define_insn "mulhi3"
1718 [(set (match_operand:HI 0 "register_operand" "=d,d") ; multiply regs
1719 (mult:HI (match_operand:HI 1 "register_operand" "%0,0")
1720 (match_operand:HI 2 "general_operand" "rR,Qi")))]
1721 "TARGET_45"
1722 "mul %2, %0"
1723 [(set_attr "length" "1,2")])
1724
1725 ;; 32 bit result
1726 (define_expand "mulhisi3"
1727 [(set (match_dup 3)
1728 (match_operand:HI 1 "general_operand" "g,g"))
1729 (set (match_operand:SI 0 "register_operand" "=r,r") ; even numbered!
1730 (mult:SI (truncate:HI
1731 (match_dup 0))
1732 (match_operand:HI 2 "general_operand" "rR,Qi")))]
1733 "TARGET_45"
1734 "operands[3] = gen_lowpart(HImode, operands[1]);")
1735
1736 (define_insn ""
1737 [(set (match_operand:SI 0 "register_operand" "=r,r") ; even numbered!
1738 (mult:SI (truncate:HI
1739 (match_operand:SI 1 "register_operand" "%0,0"))
1740 (match_operand:HI 2 "general_operand" "rR,Qi")))]
1741 "TARGET_45"
1742 "mul %2, %0"
1743 [(set_attr "length" "1,2")])
1744
1745 ;(define_insn "mulhisi3"
1746 ; [(set (match_operand:SI 0 "register_operand" "=r,r") ; even numbered!
1747 ; (mult:SI (truncate:HI
1748 ; (match_operand:SI 1 "register_operand" "%0,0"))
1749 ; (match_operand:HI 2 "general_operand" "rR,Qi")))]
1750 ; "TARGET_45"
1751 ; "mul %2, %0"
1752 ; [(set_attr "length" "1,2")])
1753
1754 ;;- divide
1755 (define_insn "divdf3"
1756 [(set (match_operand:DF 0 "register_operand" "=a,a,a")
1757 (div:DF (match_operand:DF 1 "register_operand" "0,0,0")
1758 (match_operand:DF 2 "general_operand" "fR,Q,F")))]
1759 "TARGET_FPU"
1760 "divd %2, %0"
1761 [(set_attr "length" "1,2,5")])
1762
1763
1764 (define_expand "divhi3"
1765 [(set (subreg:HI (match_dup 1) 0)
1766 (div:HI (match_operand:SI 1 "general_operand" "0")
1767 (match_operand:HI 2 "general_operand" "g")))
1768 (set (match_operand:HI 0 "general_operand" "=r")
1769 (subreg:HI (match_dup 1) 0))]
1770 "TARGET_45"
1771 "")
1772
1773 (define_insn ""
1774 [(set (subreg:HI (match_operand:SI 0 "general_operand" "=r") 0)
1775 (div:HI (match_operand:SI 1 "general_operand" "0")
1776 (match_operand:HI 2 "general_operand" "g")))]
1777 "TARGET_45"
1778 "div %2,%0"
1779 [(set_attr "length" "2")])
1780
1781 (define_expand "modhi3"
1782 [(set (subreg:HI (match_dup 1) 1)
1783 (mod:HI (match_operand:SI 1 "general_operand" "0")
1784 (match_operand:HI 2 "general_operand" "g")))
1785 (set (match_operand:HI 0 "general_operand" "=r")
1786 (subreg:HI (match_dup 1) 1))]
1787 "TARGET_45"
1788 "")
1789
1790 (define_insn ""
1791 [(set (subreg:HI (match_operand:SI 0 "general_operand" "=r") 1)
1792 (mod:HI (match_operand:SI 1 "general_operand" "0")
1793 (match_operand:HI 2 "general_operand" "g")))]
1794 "TARGET_45"
1795 "div %2,%0"
1796 [(set_attr "length" "2")])
1797
1798 ;(define_expand "divmodhi4"
1799 ; [(parallel [(set (subreg:HI (match_dup 1) 0)
1800 ; (div:HI (match_operand:SI 1 "general_operand" "0")
1801 ; (match_operand:HI 2 "general_operand" "g")))
1802 ; (set (subreg:HI (match_dup 1) 1)
1803 ; (mod:HI (match_dup 1)
1804 ; (match_dup 2)))])
1805 ; (set (match_operand:HI 3 "general_operand" "=r")
1806 ; (subreg:HI (match_dup 1) 1))
1807 ; (set (match_operand:HI 0 "general_operand" "=r")
1808 ; (subreg:HI (match_dup 1) 0))]
1809 ; "TARGET_45"
1810 ; "")
1811 ;
1812 ;(define_insn ""
1813 ; [(set (subreg:HI (match_operand:SI 0 "general_operand" "=r") 0)
1814 ; (div:HI (match_operand:SI 1 "general_operand" "0")
1815 ; (match_operand:HI 2 "general_operand" "g")))
1816 ; (set (subreg:HI (match_dup 0) 1)
1817 ; (mod:HI (match_dup 1)
1818 ; (match_dup 2)))]
1819 ; "TARGET_45"
1820 ; "div %2, %0")
1821 ;
1822
1823 ;; is rotate doing the right thing to be included here ????