]> git.ipfire.org Git - thirdparty/gcc.git/blame - gcc/config/pdp11/pdp11.md
host-hpux.c: Change copyright header to refer to version 3 of the GNU General Public...
[thirdparty/gcc.git] / gcc / config / pdp11 / pdp11.md
CommitLineData
2c9c2489 1;;- Machine description for the pdp11 for GNU C compiler
9db9ab7e 2;; Copyright (C) 1994, 1995, 1997, 1998, 1999, 2000, 2001, 2004, 2005
2f83c7d6 3;; 2007 Free Software Foundation, Inc.
2c9c2489
RK
4;; Contributed by Michael K. Gschwind (mike@vlsivie.tuwien.ac.at).
5
7ec022b2 6;; This file is part of GCC.
2c9c2489 7
7ec022b2 8;; GCC is free software; you can redistribute it and/or modify
2c9c2489 9;; it under the terms of the GNU General Public License as published by
2f83c7d6 10;; the Free Software Foundation; either version 3, or (at your option)
2c9c2489
RK
11;; any later version.
12
7ec022b2 13;; GCC is distributed in the hope that it will be useful,
2c9c2489
RK
14;; but WITHOUT ANY WARRANTY; without even the implied warranty of
15;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
16;; GNU General Public License for more details.
17
18;; You should have received a copy of the GNU General Public License
2f83c7d6
NC
19;; along with GCC; see the file COPYING3. If not see
20;; <http://www.gnu.org/licenses/>.
2c9c2489
RK
21
22
23;; HI is 16 bit
24;; QI is 8 bit
25
26;;- See file "rtl.def" for documentation on define_insn, match_*, et. al.
27
28;;- cpp macro #define NOTICE_UPDATE_CC in file tm.h handles condition code
29;;- updates for most instructions.
30
31;;- Operand classes for the register allocator:
32\f
33;; Compare instructions.
34
35;; currently we only support df floats, which saves us quite some
36;; hassle switching the FP mode!
37;; we assume that CPU is always in long float mode, and
38;; 16 bit integer mode - currently, the prologue for main does this,
39;; but maybe we should just set up a NEW crt0 properly,
40;; -- and what about signal handling code?
41;; (we don't even let sf floats in the register file, so
42;; we only should have to worry about truncating and widening
43;; when going to memory)
44
45;; abort() call by g++ - must define libfunc for cmp_optab
46;; and ucmp_optab for mode SImode, because we don't have that!!!
47;; - yet since no libfunc is there, we abort ()
48
49;; The only thing that remains to be done then is output
50;; the floats in a way the assembler can handle it (and
51;; if you're really into it, use a PDP11 float emulation
3a598fbe 52;; library to do floating point constant folding - but
2c9c2489
RK
53;; I guess you'll get reasonable results even when not
54;; doing this)
55;; the last thing to do is fix the UPDATE_CC macro to check
56;; for floating point condition codes, and set cc_status
57;; properly, also setting the CC_IN_FCCR flag.
58
59;; define attributes
60;; currently type is only fpu or arith or unknown, maybe branch later ?
61;; default is arith
62(define_attr "type" "unknown,arith,fp" (const_string "arith"))
63
64;; length default is 1 word each
65(define_attr "length" "" (const_int 1))
66
ddd5a7c1 67;; a user's asm statement
2c9c2489
RK
68(define_asm_attributes
69 [(set_attr "type" "unknown")
70; all bets are off how long it is - make it 256, forces long jumps
71; whenever jumping around it !!!
72 (set_attr "length" "256")])
73
74;; define function units
75
76;; arithmetic - values here immediately when next insn issued
77;; or does it mean the number of cycles after this insn was issued?
78;; how do I say that fpu insns use cpu also? (pre-interaction phase)
79
80;(define_function_unit "cpu" 1 1 (eq_attr "type" "arith") 0 0)
81;(define_function_unit "fpu" 1 1 (eq_attr "type" "fp") 0 0)
82
83;; compare
84(define_insn "cmpdf"
85 [(set (cc0)
86 (compare (match_operand:DF 0 "general_operand" "fR,Q,F")
87 (match_operand:DF 1 "register_operand" "a,a,a")))]
88 "TARGET_FPU"
89 "*
90{
91 cc_status.flags = CC_IN_FPU;
af36a4d2 92 return \"{cmpd|cmpf} %0, %1\;cfcc\";
2c9c2489
RK
93}"
94 [(set_attr "length" "2,3,6")])
95
96;; a bit of brain damage, maybe inline later -
97;; problem is - gcc seems to NEED SImode because
98;; of the cmp weirdness - maybe change gcc to handle this?
99
100(define_expand "cmpsi"
101 [(set (reg:SI 0)
102 (match_operand:SI 0 "general_operand" "g"))
103 (set (reg:SI 2)
104 (match_operand:SI 1 "general_operand" "g"))
105 (parallel [(set (cc0)
106 (compare (reg:SI 0)
107 (reg:SI 2)))
108 (clobber (reg:SI 0))])]
109 "0" ;; disable for test
110 "")
111
112;; check for next insn for branch code - does this still
113;; work in gcc 2.* ?
114
115(define_insn ""
116 [(set (cc0)
117 (compare (reg:SI 0)
118 (reg:SI 2)))
119 (clobber (reg:SI 0))]
120 ""
121 "*
122{
123 rtx br_insn = NEXT_INSN (insn);
124 RTX_CODE br_code;
125
d35d9223 126 gcc_assert (GET_CODE (br_insn) == JUMP_INSN);
2c9c2489
RK
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
d35d9223 149 gcc_unreachable ();
2c9c2489
RK
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;
af36a4d2 182 return \"{tstd|tstf} %0\;cfcc\";
2c9c2489
RK
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
997718c7 225 (ne (plus:HI (match_operand:HI 0 "register_operand" "+r")
2c9c2489
RK
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
43b55a67 268;; make this valid for all jump distances!
2c9c2489
RK
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 ""
480ae58f 368 "* return output_jump(\"blo\", \"bhis\", get_attr_length(insn));"
2c9c2489
RK
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 ""
480ae58f 541 "* return output_jump(\"bhis\", \"blo\", get_attr_length(insn));"
2c9c2489
RK
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 ""
480ae58f 575 "* return output_jump(\"blo\", \"bhis\", get_attr_length(insn));"
2c9c2489
RK
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"
cf860dc2 622 [(set (match_operand:DI 0 "general_operand" "=g,rm,o")
e7f9979a 623 (match_operand:DI 1 "general_operand" "m,r,a"))]
2c9c2489
RK
624 ""
625 "* return output_move_quad (operands);"
626;; what's the mose expensive code - say twice movsi = 16
e7f9979a 627 [(set_attr "length" "16,16,16")])
2c9c2489
RK
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"
e7f9979a
NS
652 [(set (match_operand:QI 0 "nonimmediate_operand" "=g")
653 (match_operand:QI 1 "general_operand" "g"))]
2c9c2489
RK
654 ""
655 "*
656{
657 if (operands[1] == const0_rtx)
658 return \"clrb %0\";
659
660 return \"movb %1, %0\";
661}"
e7f9979a 662 [(set_attr "length" "1")])
2c9c2489
RK
663
664;; do we have to supply all these moves? e.g. to
665;; NO_LOAD_FPU_REGs ?
666(define_insn "movdf"
e7f9979a
NS
667 [(set (match_operand:DF 0 "general_operand" "=a,fR,a,Q,m")
668 (match_operand:DF 1 "general_operand" "fFR,a,Q,a,m"))]
2c9c2489 669 ""
e7f9979a
NS
670 "* if (which_alternative ==0)
671 return \"ldd %1, %0\";
672 else if (which_alternative == 1)
673 return \"std %1, %0\";
674 else
675 return output_move_quad (operands); "
2c9c2489 676;; just a guess..
e7f9979a 677 [(set_attr "length" "1,1,5,5,16")])
2c9c2489
RK
678
679(define_insn "movsf"
680 [(set (match_operand:SF 0 "general_operand" "=g,r,g")
681 (match_operand:SF 1 "general_operand" "r,rmF,g"))]
682 "TARGET_FPU"
683 "* return output_move_double (operands);"
684 [(set_attr "length" "8,8,8")])
685
686;; maybe fiddle a bit with move_ratio, then
ddd5a7c1 687;; let constraints only accept a register ...
2c9c2489 688
70128ad9 689(define_expand "movmemhi"
3a598fbe
JL
690 [(parallel [(set (match_operand:BLK 0 "general_operand" "=g,g")
691 (match_operand:BLK 1 "general_operand" "g,g"))
2c9c2489
RK
692 (use (match_operand:HI 2 "arith_operand" "n,&mr"))
693 (use (match_operand:HI 3 "immediate_operand" "i,i"))
694 (clobber (match_scratch:HI 4 "=&r,X"))
3a598fbe
JL
695 (clobber (match_dup 5))
696 (clobber (match_dup 6))
2c9c2489
RK
697 (clobber (match_dup 2))])]
698 "(TARGET_BCOPY_BUILTIN)"
699 "
700{
3a598fbe 701 operands[0]
792760b9
RK
702 = replace_equiv_address (operands[0],
703 copy_to_mode_reg (Pmode, XEXP (operands[0], 0)));
3a598fbe 704 operands[1]
792760b9
RK
705 = replace_equiv_address (operands[1],
706 copy_to_mode_reg (Pmode, XEXP (operands[1], 0)));
3a598fbe
JL
707
708 operands[5] = XEXP (operands[0], 0);
709 operands[6] = XEXP (operands[1], 0);
2c9c2489
RK
710}")
711
712
70128ad9 713(define_insn "" ; "movmemhi"
2c9c2489
RK
714 [(set (mem:BLK (match_operand:HI 0 "general_operand" "=r,r"))
715 (mem:BLK (match_operand:HI 1 "general_operand" "r,r")))
716 (use (match_operand:HI 2 "arith_operand" "n,&r"))
717 (use (match_operand:HI 3 "immediate_operand" "i,i"))
718 (clobber (match_scratch:HI 4 "=&r,X"))
719 (clobber (match_dup 0))
720 (clobber (match_dup 1))
721 (clobber (match_dup 2))]
722 "(TARGET_BCOPY_BUILTIN)"
723 "* return output_block_move (operands);"
724;;; just a guess
725 [(set_attr "length" "40")])
726
727
728\f
729;;- truncation instructions
730
731(define_insn "truncdfsf2"
e3be1b32
RK
732 [(set (match_operand:SF 0 "general_operand" "=r,R,Q")
733 (float_truncate:SF (match_operand:DF 1 "register_operand" "a,a,a")))]
2c9c2489 734 "TARGET_FPU"
e3be1b32
RK
735 "* if (which_alternative ==0)
736 {
af36a4d2 737 output_asm_insn(\"{stcdf|movfo} %1, -(sp)\", operands);
e3be1b32 738 output_asm_insn(\"mov (sp)+, %0\", operands);
c5c76735 739 operands[0] = gen_rtx_REG (HImode, REGNO (operands[0])+1);
e3be1b32
RK
740 output_asm_insn(\"mov (sp)+, %0\", operands);
741 return \"\";
742 }
743 else if (which_alternative == 1)
af36a4d2 744 return \"{stcdf|movfo} %1, %0\";
e3be1b32 745 else
af36a4d2 746 return \"{stcdf|movfo} %1, %0\";
e3be1b32
RK
747 "
748 [(set_attr "length" "3,1,2")])
749
2c9c2489
RK
750
751(define_expand "truncsihi2"
752 [(set (match_operand:HI 0 "general_operand" "=g")
753 (subreg:HI
754 (match_operand:SI 1 "general_operand" "or")
755 0))]
756 ""
757 "")
758
759\f
760;;- zero extension instructions
761
762(define_insn "zero_extendqihi2"
763 [(set (match_operand:HI 0 "general_operand" "=r")
764 (zero_extend:HI (match_operand:QI 1 "general_operand" "0")))]
765 ""
e7f9979a 766 "bic $0177400, %0"
2c9c2489
RK
767 [(set_attr "length" "2")])
768
769(define_expand "zero_extendhisi2"
770 [(set (subreg:HI
771 (match_dup 0)
ddef6bc7 772 2)
2c9c2489
RK
773 (match_operand:HI 1 "register_operand" "r"))
774 (set (subreg:HI
775 (match_operand:SI 0 "register_operand" "=r")
776 0)
777 (const_int 0))]
778 ""
779 "/* operands[1] = make_safe_from (operands[1], operands[0]); */")
780
781\f
782;;- sign extension instructions
783
784(define_insn "extendsfdf2"
e3be1b32 785 [(set (match_operand:DF 0 "register_operand" "=a,a,a")
a6a715ca 786 (float_extend:DF (match_operand:SF 1 "general_operand" "r,R,Q")))]
2c9c2489 787 "TARGET_FPU"
e3be1b32 788 "@
af36a4d2
JM
789 mov %1, -(sp)\;{ldcfd|movof} (sp)+,%0
790 {ldcfd|movof} %1, %0
791 {ldcfd|movof} %1, %0"
e3be1b32 792 [(set_attr "length" "2,1,2")])
2c9c2489
RK
793
794;; does movb sign extend in register-to-register move?
795(define_insn "extendqihi2"
796 [(set (match_operand:HI 0 "register_operand" "=r,r")
797 (sign_extend:HI (match_operand:QI 1 "general_operand" "rR,Q")))]
798 ""
799 "movb %1, %0"
800 [(set_attr "length" "1,2")])
801
802(define_insn "extendqisi2"
803 [(set (match_operand:SI 0 "register_operand" "=r,r")
804 (sign_extend:SI (match_operand:QI 1 "general_operand" "rR,Q")))]
805 "TARGET_40_PLUS"
806 "*
807{
808 rtx latehalf[2];
809
810 /* make register pair available */
811 latehalf[0] = operands[0];
c5c76735
JL
812 operands[0] = gen_rtx_REG (HImode, REGNO (operands[0])+ 1);
813
2c9c2489
RK
814 output_asm_insn(\"movb %1, %0\", operands);
815 output_asm_insn(\"sxt %0\", latehalf);
816
817 return \"\";
818}"
819 [(set_attr "length" "2,3")])
820
821;; maybe we have to use define_expand to say that we have the instruction,
822;; unconditionally, and then match dependent on CPU type:
823
824(define_expand "extendhisi2"
825 [(set (match_operand:SI 0 "general_operand" "=g")
826 (sign_extend:SI (match_operand:HI 1 "general_operand" "g")))]
827 ""
828 "")
829
830(define_insn "" ; "extendhisi2"
831 [(set (match_operand:SI 0 "general_operand" "=o,<,r")
832 (sign_extend:SI (match_operand:HI 1 "general_operand" "g,g,g")))]
833 "TARGET_40_PLUS"
834 "*
835{
836 rtx latehalf[2];
837
838 /* we don't want to mess with auto increment */
839
b72f00af 840 switch (which_alternative)
2c9c2489
RK
841 {
842 case 0:
843
844 latehalf[0] = operands[0];
b72f00af 845 operands[0] = adjust_address(operands[0], HImode, 2);
2c9c2489
RK
846
847 output_asm_insn(\"mov %1, %0\", operands);
848 output_asm_insn(\"sxt %0\", latehalf);
849
850 return \"\";
851
852 case 1:
853
854 /* - auto-decrement - right direction ;-) */
855 output_asm_insn(\"mov %1, %0\", operands);
856 output_asm_insn(\"sxt %0\", operands);
857
858 return \"\";
859
860 case 2:
861
862 /* make register pair available */
863 latehalf[0] = operands[0];
c5c76735 864 operands[0] = gen_rtx_REG (HImode, REGNO (operands[0]) + 1);
2c9c2489
RK
865
866 output_asm_insn(\"mov %1, %0\", operands);
867 output_asm_insn(\"sxt %0\", latehalf);
868
869 return \"\";
870
871 default:
872
d35d9223 873 gcc_unreachable ();
2c9c2489
RK
874 }
875}"
876 [(set_attr "length" "5,3,3")])
877
878
879(define_insn ""
880 [(set (match_operand:SI 0 "register_operand" "=r")
881 (sign_extend:SI (match_operand:HI 1 "general_operand" "0")))]
882 "(! TARGET_40_PLUS)"
883 "*
884{
09b893bb 885 static int count = 0;
2c9c2489
RK
886 char buf[100];
887 rtx lateoperands[2];
888
889 lateoperands[0] = operands[0];
c5c76735 890 operands[0] = gen_rtx_REG (HImode, REGNO (operands[0]) + 1);
2c9c2489
RK
891
892 output_asm_insn(\"tst %0\", operands);
893 sprintf(buf, \"bge extendhisi%d\", count);
894 output_asm_insn(buf, NULL);
895 output_asm_insn(\"mov -1, %0\", lateoperands);
896 sprintf(buf, \"bne extendhisi%d\", count+1);
897 output_asm_insn(buf, NULL);
898 sprintf(buf, \"\\nextendhisi%d:\", count);
899 output_asm_insn(buf, NULL);
900 output_asm_insn(\"clr %0\", lateoperands);
901 sprintf(buf, \"\\nextendhisi%d:\", count+1);
902 output_asm_insn(buf, NULL);
903
904 count += 2;
905
906 return \"\";
907}"
908 [(set_attr "length" "6")])
909
910;; make float to int and vice versa
ddd5a7c1 911;; using the cc_status.flag field we could probably cut down
2c9c2489
RK
912;; on seti and setl
913;; assume that we are normally in double and integer mode -
914;; what do pdp library routines do to fpu mode ?
915
916(define_insn "floatsidf2"
e3be1b32
RK
917 [(set (match_operand:DF 0 "register_operand" "=a,a,a")
918 (float:DF (match_operand:SI 1 "general_operand" "r,R,Q")))]
2c9c2489 919 "TARGET_FPU"
e3be1b32
RK
920 "* if (which_alternative ==0)
921 {
922 rtx latehalf[2];
923
924 latehalf[0] = NULL;
e7f9979a 925 latehalf[1] = gen_rtx_REG (HImode, REGNO (operands[1]) + 1);
e3be1b32
RK
926 output_asm_insn(\"mov %1, -(sp)\", latehalf);
927 output_asm_insn(\"mov %1, -(sp)\", operands);
928
929 output_asm_insn(\"setl\", operands);
af36a4d2 930 output_asm_insn(\"{ldcld|movif} (sp)+, %0\", operands);
e3be1b32
RK
931 output_asm_insn(\"seti\", operands);
932 return \"\";
933 }
934 else if (which_alternative == 1)
af36a4d2 935 return \"setl\;{ldcld|movif} %1, %0\;seti\";
e3be1b32 936 else
af36a4d2 937 return \"setl\;{ldcld|movif} %1, %0\;seti\";
e3be1b32
RK
938 "
939 [(set_attr "length" "5,3,4")])
2c9c2489
RK
940
941(define_insn "floathidf2"
942 [(set (match_operand:DF 0 "register_operand" "=a,a")
943 (float:DF (match_operand:HI 1 "general_operand" "rR,Qi")))]
944 "TARGET_FPU"
af36a4d2 945 "{ldcid|movif} %1, %0"
2c9c2489
RK
946 [(set_attr "length" "1,2")])
947
948;; cut float to int
949(define_insn "fix_truncdfsi2"
e3be1b32
RK
950 [(set (match_operand:SI 0 "general_operand" "=r,R,Q")
951 (fix:SI (fix:DF (match_operand:DF 1 "register_operand" "a,a,a"))))]
2c9c2489 952 "TARGET_FPU"
e3be1b32
RK
953 "* if (which_alternative ==0)
954 {
955 output_asm_insn(\"setl\", operands);
af36a4d2 956 output_asm_insn(\"{stcdl|movfi} %1, -(sp)\", operands);
e3be1b32
RK
957 output_asm_insn(\"seti\", operands);
958 output_asm_insn(\"mov (sp)+, %0\", operands);
c5c76735 959 operands[0] = gen_rtx_REG (HImode, REGNO (operands[0]) + 1);
e3be1b32
RK
960 output_asm_insn(\"mov (sp)+, %0\", operands);
961 return \"\";
962 }
963 else if (which_alternative == 1)
af36a4d2 964 return \"setl\;{stcdl|movfi} %1, %0\;seti\";
e3be1b32 965 else
af36a4d2 966 return \"setl\;{stcdl|movfi} %1, %0\;seti\";
e3be1b32
RK
967 "
968 [(set_attr "length" "5,3,4")])
2c9c2489
RK
969
970(define_insn "fix_truncdfhi2"
971 [(set (match_operand:HI 0 "general_operand" "=rR,Q")
972 (fix:HI (fix:DF (match_operand:DF 1 "register_operand" "a,a"))))]
973 "TARGET_FPU"
af36a4d2 974 "{stcdi|movfi} %1, %0"
2c9c2489
RK
975 [(set_attr "length" "1,2")])
976
977\f
978;;- arithmetic instructions
979;;- add instructions
980
981(define_insn "adddf3"
982 [(set (match_operand:DF 0 "register_operand" "=a,a,a")
983 (plus:DF (match_operand:DF 1 "register_operand" "%0,0,0")
984 (match_operand:DF 2 "general_operand" "fR,Q,F")))]
985 "TARGET_FPU"
af36a4d2 986 "{addd|addf} %2, %0"
2c9c2489
RK
987 [(set_attr "length" "1,2,5")])
988
989(define_insn "addsi3"
990 [(set (match_operand:SI 0 "general_operand" "=r,r,o,o,r,r,r,o,o,o")
991 (plus:SI (match_operand:SI 1 "general_operand" "%0,0,0,0,0,0,0,0,0,0")
992 (match_operand:SI 2 "general_operand" "r,o,r,o,I,J,K,I,J,K")))]
993 ""
994 "*
995{ /* Here we trust that operands don't overlap
996
997 or is lateoperands the low word?? - looks like it! */
998
2c9c2489
RK
999 rtx lateoperands[3];
1000
1001 lateoperands[0] = operands[0];
1002
1003 if (REG_P (operands[0]))
c5c76735 1004 operands[0] = gen_rtx_REG (HImode, REGNO (operands[0]) + 1);
2c9c2489 1005 else
b72f00af 1006 operands[0] = adjust_address (operands[0], HImode, 2);
2c9c2489
RK
1007
1008 if (! CONSTANT_P(operands[2]))
1009 {
1010 lateoperands[2] = operands[2];
1011
1012 if (REG_P (operands[2]))
c5c76735 1013 operands[2] = gen_rtx_REG (HImode, REGNO (operands[2]) + 1);
2c9c2489 1014 else
b72f00af 1015 operands[2] = adjust_address (operands[2], HImode, 2);
2c9c2489
RK
1016
1017 output_asm_insn (\"add %2, %0\", operands);
1018 output_asm_insn (\"adc %0\", lateoperands);
1019 output_asm_insn (\"add %2, %0\", lateoperands);
1020 return \"\";
1021 }
1022
b0106b24 1023 lateoperands[2] = GEN_INT ((INTVAL (operands[2]) >> 16) & 0xffff);
c5c76735 1024 operands[2] = GEN_INT (INTVAL (operands[2]) & 0xffff);
2c9c2489
RK
1025
1026 if (INTVAL(operands[2]))
1027 {
1028 output_asm_insn (\"add %2, %0\", operands);
1029 output_asm_insn (\"adc %0\", lateoperands);
1030 }
1031
1032 if (INTVAL(lateoperands[2]))
1033 output_asm_insn (\"add %2, %0\", lateoperands);
1034
1035 return \"\";
1036}"
1037 [(set_attr "length" "3,5,6,8,3,1,5,5,3,8")])
1038
1039(define_insn "addhi3"
1040 [(set (match_operand:HI 0 "general_operand" "=rR,rR,Q,Q")
1041 (plus:HI (match_operand:HI 1 "general_operand" "%0,0,0,0")
1042 (match_operand:HI 2 "general_operand" "rRLM,Qi,rRLM,Qi")))]
1043 ""
1044 "*
1045{
1046 if (GET_CODE (operands[2]) == CONST_INT)
09b893bb
JM
1047 {
1048 if (INTVAL(operands[2]) == 1)
1049 return \"inc %0\";
1050 else if (INTVAL(operands[2]) == -1)
1051 return \"dec %0\";
1052 }
2c9c2489
RK
1053
1054 return \"add %2, %0\";
1055}"
1056 [(set_attr "length" "1,2,2,3")])
1057
1058(define_insn "addqi3"
1059 [(set (match_operand:QI 0 "general_operand" "=rR,rR,Q,Q")
1060 (plus:QI (match_operand:QI 1 "general_operand" "%0,0,0,0")
1061 (match_operand:QI 2 "general_operand" "rRLM,Qi,rRLM,Qi")))]
1062 ""
1063 "*
1064{
1065 if (GET_CODE (operands[2]) == CONST_INT)
09b893bb
JM
1066 {
1067 if (INTVAL(operands[2]) == 1)
1068 return \"incb %0\";
1069 else if (INTVAL(operands[2]) == -1)
1070 return \"decb %0\";
1071 }
2c9c2489 1072
e7f9979a 1073 return \"add %2, %0\";
2c9c2489
RK
1074}"
1075 [(set_attr "length" "1,2,2,3")])
1076
1077\f
1078;;- subtract instructions
1079;; we don't have to care for constant second
ddd5a7c1 1080;; args, since they are canonical plus:xx now!
2c9c2489
RK
1081;; also for minus:DF ??
1082
1083(define_insn "subdf3"
1084 [(set (match_operand:DF 0 "register_operand" "=a,a")
1085 (minus:DF (match_operand:DF 1 "register_operand" "0,0")
1086 (match_operand:DF 2 "general_operand" "fR,Q")))]
1087 "TARGET_FPU"
af36a4d2 1088 "{subd|subf} %2, %0"
2c9c2489
RK
1089 [(set_attr "length" "1,2")])
1090
1091(define_insn "subsi3"
1092 [(set (match_operand:SI 0 "general_operand" "=r,r,o,o")
1093 (minus:SI (match_operand:SI 1 "general_operand" "0,0,0,0")
1094 (match_operand:SI 2 "general_operand" "r,o,r,o")))]
1095 ""
1096 "*
1097{ /* Here we trust that operands don't overlap
1098
1099 or is lateoperands the low word?? - looks like it! */
1100
2c9c2489
RK
1101 rtx lateoperands[3];
1102
1103 lateoperands[0] = operands[0];
1104
1105 if (REG_P (operands[0]))
c5c76735 1106 operands[0] = gen_rtx_REG (HImode, REGNO (operands[0]) + 1);
2c9c2489 1107 else
b72f00af 1108 operands[0] = adjust_address (operands[0], HImode, 2);
2c9c2489
RK
1109
1110 lateoperands[2] = operands[2];
1111
1112 if (REG_P (operands[2]))
c5c76735 1113 operands[2] = gen_rtx_REG (HImode, REGNO (operands[2]) + 1);
2c9c2489 1114 else
b72f00af 1115 operands[2] = adjust_address (operands[2], HImode, 2);
2c9c2489
RK
1116
1117 output_asm_insn (\"sub %2, %0\", operands);
1118 output_asm_insn (\"sbc %0\", lateoperands);
1119 output_asm_insn (\"sub %2, %0\", lateoperands);
1120 return \"\";
1121}"
ddd5a7c1 1122;; offsettable memory addresses always are expensive!!!
2c9c2489
RK
1123 [(set_attr "length" "3,5,6,8")])
1124
1125(define_insn "subhi3"
1126 [(set (match_operand:HI 0 "general_operand" "=rR,rR,Q,Q")
1127 (minus:HI (match_operand:HI 1 "general_operand" "0,0,0,0")
1128 (match_operand:HI 2 "general_operand" "rR,Qi,rR,Qi")))]
1129 ""
1130 "*
1131{
d35d9223 1132 gcc_assert (GET_CODE (operands[2]) != CONST_INT);
2c9c2489
RK
1133
1134 return \"sub %2, %0\";
1135}"
1136 [(set_attr "length" "1,2,2,3")])
1137
1138(define_insn "subqi3"
1139 [(set (match_operand:QI 0 "general_operand" "=rR,rR,Q,Q")
1140 (minus:QI (match_operand:QI 1 "general_operand" "0,0,0,0")
1141 (match_operand:QI 2 "general_operand" "rR,Qi,rR,Qi")))]
1142 ""
1143 "*
1144{
d35d9223 1145 gcc_assert (GET_CODE (operands[2]) != CONST_INT);
2c9c2489 1146
e7f9979a 1147 return \"sub %2, %0\";
2c9c2489
RK
1148}"
1149 [(set_attr "length" "1,2,2,3")])
1150
1151;;;;- and instructions
8aeea6e6 1152;; Bit-and on the pdp (like on the VAX) is done with a clear-bits insn.
2c9c2489 1153
e7f9979a 1154(define_insn "andsi3"
2c9c2489
RK
1155 [(set (match_operand:SI 0 "general_operand" "=r,r,o,o,r,r,r,o,o,o")
1156 (and:SI (match_operand:SI 1 "general_operand" "%0,0,0,0,0,0,0,0,0,0")
1157 (not:SI (match_operand:SI 2 "general_operand" "r,o,r,o,I,J,K,I,J,K"))))]
1158 ""
1159 "*
1160{ /* Here we trust that operands don't overlap
1161
1162 or is lateoperands the low word?? - looks like it! */
1163
2c9c2489
RK
1164 rtx lateoperands[3];
1165
1166 lateoperands[0] = operands[0];
1167
1168 if (REG_P (operands[0]))
c5c76735 1169 operands[0] = gen_rtx_REG (HImode, REGNO (operands[0]) + 1);
2c9c2489 1170 else
b72f00af 1171 operands[0] = adjust_address (operands[0], HImode, 2);
2c9c2489
RK
1172
1173 if (! CONSTANT_P(operands[2]))
1174 {
1175 lateoperands[2] = operands[2];
1176
1177 if (REG_P (operands[2]))
c5c76735 1178 operands[2] = gen_rtx_REG (HImode, REGNO (operands[2]) + 1);
2c9c2489 1179 else
b72f00af 1180 operands[2] = adjust_address (operands[2], HImode, 2);
2c9c2489
RK
1181
1182 output_asm_insn (\"bic %2, %0\", operands);
1183 output_asm_insn (\"bic %2, %0\", lateoperands);
1184 return \"\";
1185 }
1186
c5c76735
JL
1187 lateoperands[2] = GEN_INT ((INTVAL (operands[2]) >> 16) & 0xffff);
1188 operands[2] = GEN_INT (INTVAL (operands[2]) & 0xffff);
2c9c2489
RK
1189
1190 /* these have different lengths, so we should have
1191 different constraints! */
1192 if (INTVAL(operands[2]))
1193 output_asm_insn (\"bic %2, %0\", operands);
1194
1195 if (INTVAL(lateoperands[2]))
1196 output_asm_insn (\"bic %2, %0\", lateoperands);
1197
1198 return \"\";
1199}"
1200 [(set_attr "length" "2,4,4,6,2,2,4,3,3,6")])
1201
e7f9979a 1202(define_insn "andhi3"
2c9c2489
RK
1203 [(set (match_operand:HI 0 "general_operand" "=rR,rR,Q,Q")
1204 (and:HI (match_operand:HI 1 "general_operand" "0,0,0,0")
1205 (not:HI (match_operand:HI 2 "general_operand" "rR,Qi,rR,Qi"))))]
1206 ""
1207 "bic %2, %0"
1208 [(set_attr "length" "1,2,2,3")])
1209
e7f9979a 1210(define_insn "andqi3"
2c9c2489
RK
1211 [(set (match_operand:QI 0 "general_operand" "=rR,rR,Q,Q")
1212 (and:QI (match_operand:QI 1 "general_operand" "0,0,0,0")
1213 (not:QI (match_operand:QI 2 "general_operand" "rR,Qi,rR,Qi"))))]
1214 ""
1215 "bicb %2, %0"
1216 [(set_attr "length" "1,2,2,3")])
1217
1218;;- Bit set (inclusive or) instructions
1219(define_insn "iorsi3"
1220 [(set (match_operand:SI 0 "general_operand" "=r,r,o,o,r,r,r,o,o,o")
1221 (ior:SI (match_operand:SI 1 "general_operand" "%0,0,0,0,0,0,0,0,0,0")
1222 (match_operand:SI 2 "general_operand" "r,o,r,o,I,J,K,I,J,K")))]
1223 ""
1224 "*
1225{ /* Here we trust that operands don't overlap
1226
1227 or is lateoperands the low word?? - looks like it! */
1228
2c9c2489
RK
1229 rtx lateoperands[3];
1230
1231 lateoperands[0] = operands[0];
1232
1233 if (REG_P (operands[0]))
c5c76735 1234 operands[0] = gen_rtx_REG (HImode, REGNO (operands[0]) + 1);
2c9c2489 1235 else
b72f00af 1236 operands[0] = adjust_address (operands[0], HImode, 2);
2c9c2489
RK
1237
1238 if (! CONSTANT_P(operands[2]))
c5c76735
JL
1239 {
1240 lateoperands[2] = operands[2];
2c9c2489 1241
c5c76735
JL
1242 if (REG_P (operands[2]))
1243 operands[2] = gen_rtx_REG (HImode, REGNO (operands[2]) + 1);
1244 else
b72f00af 1245 operands[2] = adjust_address (operands[2], HImode, 2);
2c9c2489 1246
c5c76735
JL
1247 output_asm_insn (\"bis %2, %0\", operands);
1248 output_asm_insn (\"bis %2, %0\", lateoperands);
1249 return \"\";
1250 }
2c9c2489 1251
c5c76735
JL
1252 lateoperands[2] = GEN_INT ((INTVAL (operands[2]) >> 16) & 0xffff);
1253 operands[2] = GEN_INT (INTVAL (operands[2]) & 0xffff);
2c9c2489
RK
1254
1255 /* these have different lengths, so we should have
1256 different constraints! */
1257 if (INTVAL(operands[2]))
1258 output_asm_insn (\"bis %2, %0\", operands);
1259
1260 if (INTVAL(lateoperands[2]))
1261 output_asm_insn (\"bis %2, %0\", lateoperands);
1262
1263 return \"\";
1264}"
1265 [(set_attr "length" "2,4,4,6,2,2,4,3,3,6")])
1266
1267(define_insn "iorhi3"
1268 [(set (match_operand:HI 0 "general_operand" "=rR,rR,Q,Q")
1269 (ior:HI (match_operand:HI 1 "general_operand" "%0,0,0,0")
1270 (match_operand:HI 2 "general_operand" "rR,Qi,rR,Qi")))]
1271 ""
1272 "bis %2, %0"
1273 [(set_attr "length" "1,2,2,3")])
1274
1275(define_insn "iorqi3"
1276 [(set (match_operand:QI 0 "general_operand" "=rR,rR,Q,Q")
1277 (ior:QI (match_operand:QI 1 "general_operand" "%0,0,0,0")
1278 (match_operand:QI 2 "general_operand" "rR,Qi,rR,Qi")))]
1279 ""
1280 "bisb %2, %0")
1281
1282;;- xor instructions
1283(define_insn "xorsi3"
e7f9979a
NS
1284 [(set (match_operand:SI 0 "register_operand" "=r")
1285 (xor:SI (match_operand:SI 1 "register_operand" "%0")
1286 (match_operand:SI 2 "arith_operand" "r")))]
2c9c2489
RK
1287 "TARGET_40_PLUS"
1288 "*
1289{ /* Here we trust that operands don't overlap */
1290
2c9c2489
RK
1291 rtx lateoperands[3];
1292
1293 lateoperands[0] = operands[0];
c5c76735 1294 operands[0] = gen_rtx_REG (HImode, REGNO (operands[0]) + 1);
2c9c2489
RK
1295
1296 if (REG_P(operands[2]))
c5c76735
JL
1297 {
1298 lateoperands[2] = operands[2];
1299 operands[2] = gen_rtx_REG (HImode, REGNO (operands[2]) + 1);
2c9c2489 1300
c5c76735
JL
1301 output_asm_insn (\"xor %2, %0\", operands);
1302 output_asm_insn (\"xor %2, %0\", lateoperands);
2c9c2489 1303
c5c76735
JL
1304 return \"\";
1305 }
1306
2c9c2489 1307}"
e7f9979a 1308 [(set_attr "length" "2")])
2c9c2489
RK
1309
1310(define_insn "xorhi3"
1311 [(set (match_operand:HI 0 "general_operand" "=rR,Q")
1312 (xor:HI (match_operand:HI 1 "general_operand" "%0,0")
1313 (match_operand:HI 2 "register_operand" "r,r")))]
1314 "TARGET_40_PLUS"
1315 "xor %2, %0"
1316 [(set_attr "length" "1,2")])
1317
1318;;- one complement instructions
1319
1320(define_insn "one_cmplhi2"
1321 [(set (match_operand:HI 0 "general_operand" "=rR,Q")
1322 (not:HI (match_operand:HI 1 "general_operand" "0,0")))]
1323 ""
1324 "com %0"
1325 [(set_attr "length" "1,2")])
1326
1327(define_insn "one_cmplqi2"
e7f9979a
NS
1328 [(set (match_operand:QI 0 "general_operand" "=rR,rR")
1329 (not:QI (match_operand:QI 1 "general_operand" "0,g")))]
2c9c2489 1330 ""
e7f9979a
NS
1331 "@
1332 comb %0
1333 movb %1, %0\; comb %0"
2c9c2489
RK
1334 [(set_attr "length" "1,2")])
1335
1336;;- arithmetic shift instructions
1337(define_insn "ashlsi3"
1338 [(set (match_operand:SI 0 "register_operand" "=r,r")
1339 (ashift:SI (match_operand:SI 1 "register_operand" "0,0")
1340 (match_operand:HI 2 "general_operand" "rR,Qi")))]
1341 "TARGET_45"
1342 "ashc %2,%0"
1343 [(set_attr "length" "1,2")])
1344
1345;; Arithmetic right shift on the pdp works by negating the shift count.
1346(define_expand "ashrsi3"
1347 [(set (match_operand:SI 0 "register_operand" "=r")
1348 (ashift:SI (match_operand:SI 1 "register_operand" "0")
1349 (match_operand:HI 2 "general_operand" "g")))]
1350 ""
1351 "
1352{
1353 operands[2] = negate_rtx (HImode, operands[2]);
1354}")
1355
1356;; define asl aslb asr asrb - ashc missing!
1357
1358;; asl
1359(define_insn ""
1360 [(set (match_operand:HI 0 "general_operand" "=rR,Q")
1361 (ashift:HI (match_operand:HI 1 "general_operand" "0,0")
1362 (const_int 1)))]
1363 ""
1364 "asl %0"
1365 [(set_attr "length" "1,2")])
1366
1367;; and another possibility for asr is << -1
1368;; might cause problems since -1 can also be encoded as 65535!
1369;; not in gcc2 ???
1370
1371;; asr
1372(define_insn ""
1373 [(set (match_operand:HI 0 "general_operand" "=rR,Q")
1374 (ashift:HI (match_operand:HI 1 "general_operand" "0,0")
1375 (const_int -1)))]
1376 ""
1377 "asr %0"
1378 [(set_attr "length" "1,2")])
1379
e7f9979a
NS
1380;; lsr
1381(define_insn ""
1382 [(set (match_operand:HI 0 "general_operand" "=rR,Q")
1383 (lshiftrt:HI (match_operand:HI 1 "general_operand" "0,0")
1384 (const_int 1)))]
1385 ""
1386 "clc\;ror %0"
1387 [(set_attr "length" "1,2")])
1388
1389(define_insn "lshrsi3"
1390 [(set (match_operand:SI 0 "register_operand" "=r")
1391 (lshiftrt:SI (match_operand:SI 1 "general_operand" "0")
1392 (const_int 1)))]
1393 ""
cf860dc2 1394{
e7f9979a
NS
1395
1396 rtx lateoperands[2];
1397
1398 lateoperands[0] = operands[0];
1399 operands[0] = gen_rtx_REG (HImode, REGNO (operands[0]) + 1);
1400
1401 lateoperands[1] = operands[1];
1402 operands[1] = gen_rtx_REG (HImode, REGNO (operands[1]) + 1);
1403
1404 output_asm_insn (\"clc\", operands);
1405 output_asm_insn (\"ror %0\", lateoperands);
1406 output_asm_insn (\"ror %0\", operands);
1407
1408 return \"\";
1409}
1410 [(set_attr "length" "5")])
1411
2c9c2489
RK
1412;; shift is by arbitrary count is expensive,
1413;; shift by one cheap - so let's do that, if
1414;; space doesn't matter
1415(define_insn ""
1416 [(set (match_operand:HI 0 "general_operand" "=r")
1417 (ashift:HI (match_operand:HI 1 "general_operand" "0")
1418 (match_operand:HI 2 "expand_shift_operand" "O")))]
f4190acc 1419 "! optimize_size"
2c9c2489
RK
1420 "*
1421{
1422 register int i;
1423
1424 for (i = 1; i <= abs(INTVAL(operands[2])); i++)
1425 if (INTVAL(operands[2]) < 0)
1426 output_asm_insn(\"asr %0\", operands);
1427 else
1428 output_asm_insn(\"asl %0\", operands);
1429
1430 return \"\";
1431}"
1432;; longest is 4
1433 [(set (attr "length") (const_int 4))])
1434
1435;; aslb
1436(define_insn ""
1437 [(set (match_operand:QI 0 "general_operand" "=r,o")
1438 (ashift:QI (match_operand:QI 1 "general_operand" "0,0")
1439 (match_operand:HI 2 "const_immediate_operand" "n,n")))]
1440 ""
1441 "*
1442{ /* allowing predec or post_inc is possible, but hairy! */
1443 int i, cnt;
1444
1445 cnt = INTVAL(operands[2]) & 0x0007;
1446
1447 for (i=0 ; i < cnt ; i++)
1448 output_asm_insn(\"aslb %0\", operands);
1449
1450 return \"\";
1451}"
1452;; set attribute length ( match_dup 2 & 7 ) *(1 or 2) !!!
1453 [(set_attr_alternative "length"
1454 [(const_int 7)
1455 (const_int 14)])])
1456
1457;;; asr
1458;(define_insn ""
1459; [(set (match_operand:HI 0 "general_operand" "=rR,Q")
1460; (ashiftrt:HI (match_operand:HI 1 "general_operand" "0,0")
1461; (const_int 1)))]
1462; ""
1463; "asr %0"
1464; [(set_attr "length" "1,2")])
1465
1466;; asrb
1467(define_insn ""
1468 [(set (match_operand:QI 0 "general_operand" "=r,o")
1469 (ashiftrt:QI (match_operand:QI 1 "general_operand" "0,0")
1470 (match_operand:HI 2 "const_immediate_operand" "n,n")))]
1471 ""
1472 "*
1473{ /* allowing predec or post_inc is possible, but hairy! */
1474 int i, cnt;
1475
1476 cnt = INTVAL(operands[2]) & 0x0007;
1477
1478 for (i=0 ; i < cnt ; i++)
1479 output_asm_insn(\"asrb %0\", operands);
1480
1481 return \"\";
1482}"
1483 [(set_attr_alternative "length"
1484 [(const_int 7)
1485 (const_int 14)])])
1486
43b55a67 1487;; the following is invalid - too complex!!! - just say 14 !!!
2c9c2489
RK
1488; [(set (attr "length") (plus (and (match_dup 2)
1489; (const_int 7))
1490; (and (match_dup 2)
1491; (const_int 7))))])
1492
1493
1494
1495;; can we get +-1 in the next pattern? should
1496;; have been caught by previous patterns!
1497
1498(define_insn "ashlhi3"
1499 [(set (match_operand:HI 0 "register_operand" "=r,r")
1500 (ashift:HI (match_operand:HI 1 "register_operand" "0,0")
1501 (match_operand:HI 2 "general_operand" "rR,Qi")))]
1502 ""
1503 "*
1504{
1505 if (GET_CODE(operands[2]) == CONST_INT)
09b893bb
JM
1506 {
1507 if (INTVAL(operands[2]) == 1)
1508 return \"asl %0\";
1509 else if (INTVAL(operands[2]) == -1)
1510 return \"asr %0\";
1511 }
2c9c2489
RK
1512
1513 return \"ash %2,%0\";
1514}"
1515 [(set_attr "length" "1,2")])
1516
1517;; Arithmetic right shift on the pdp works by negating the shift count.
1518(define_expand "ashrhi3"
1519 [(set (match_operand:HI 0 "register_operand" "=r")
1520 (ashift:HI (match_operand:HI 1 "register_operand" "0")
1521 (match_operand:HI 2 "general_operand" "g")))]
1522 ""
1523 "
1524{
1525 operands[2] = negate_rtx (HImode, operands[2]);
1526}")
1527
1528;;;;- logical shift instructions
1529;;(define_insn "lshrsi3"
1530;; [(set (match_operand:HI 0 "register_operand" "=r")
1531;; (lshiftrt:HI (match_operand:HI 1 "register_operand" "0")
1532;; (match_operand:HI 2 "arith_operand" "rI")))]
1533;; ""
1534;; "srl %0,%2")
1535
1536;; absolute
1537
1538(define_insn "absdf2"
1539 [(set (match_operand:DF 0 "general_operand" "=fR,Q")
1540 (abs:DF (match_operand:DF 1 "general_operand" "0,0")))]
1541 "TARGET_FPU"
af36a4d2 1542 "{absd|absf} %0"
2c9c2489
RK
1543 [(set_attr "length" "1,2")])
1544
1545(define_insn "abshi2"
1546 [(set (match_operand:HI 0 "general_operand" "=r,o")
1547 (abs:HI (match_operand:HI 1 "general_operand" "0,0")))]
1548 "TARGET_ABSHI_BUILTIN"
1549 "*
1550{
09b893bb 1551 static int count = 0;
2c9c2489
RK
1552 char buf[200];
1553
1554 output_asm_insn(\"tst %0\", operands);
1555 sprintf(buf, \"bge abshi%d\", count);
1556 output_asm_insn(buf, NULL);
1557 output_asm_insn(\"neg %0\", operands);
1558 sprintf(buf, \"\\nabshi%d:\", count++);
1559 output_asm_insn(buf, NULL);
1560
1561 return \"\";
1562}"
1563 [(set_attr "length" "3,5")])
1564
1565
1566;; define expand abshi - is much better !!! - but
1567;; will it be optimized into an abshi2 ?
1568;; it will leave better code, because the tsthi might be
1569;; optimized away!!
1570; -- just a thought - don't have time to check
1571;
1572;(define_expand "abshi2"
1573; [(match_operand:HI 0 "general_operand" "")
1574; (match_operand:HI 1 "general_operand" "")]
1575; ""
1576; "
1577;{
1578; rtx label = gen_label_rtx ();
1579;
1580; /* do I need this? */
1581; do_pending_stack_adjust ();
1582;
1583; emit_move_insn (operands[0], operands[1]);
1584;
1585; emit_insn (gen_tsthi (operands[0]));
1586; emit_insn (gen_bge (label1));
1587;
1588; emit_insn (gen_neghi(operands[0], operands[0])
1589;
1590; emit_barrier ();
1591;
1592; emit_label (label);
1593;
1594; /* allow REG_NOTES to be set on last insn (labels don't have enough
1595; fields, and can't be used for REG_NOTES anyway). */
c5c76735 1596; emit_insn (gen_rtx_USE (VOIDmode, stack_pointer_rtx));
2c9c2489
RK
1597; DONE;
1598;}")
1599
1600;; negate insns
1601
1602(define_insn "negdf2"
1603 [(set (match_operand:DF 0 "general_operand" "=fR,Q")
1604 (neg:DF (match_operand:DF 1 "register_operand" "0,0")))]
1605 "TARGET_FPU"
af36a4d2 1606 "{negd|negf} %0"
2c9c2489
RK
1607 [(set_attr "length" "1,2")])
1608
e7f9979a
NS
1609(define_insn "negsi2"
1610 [(set (match_operand:SI 0 "register_operand" "=r")
1611 (neg:SI (match_operand:SI 1 "general_operand" "0")))]
1612 ""
cf860dc2 1613{
e7f9979a
NS
1614
1615 rtx lateoperands[2];
1616
1617 lateoperands[0] = operands[0];
1618 operands[0] = gen_rtx_REG (HImode, REGNO (operands[0]) + 1);
1619
1620 lateoperands[1] = operands[1];
1621 operands[1] = gen_rtx_REG (HImode, REGNO (operands[1]) + 1);
1622
1623 output_asm_insn (\"com %0\", operands);
1624 output_asm_insn (\"com %0\", lateoperands);
1625 output_asm_insn (\"inc %0\", operands);
1626 output_asm_insn (\"adc %0\", lateoperands);
1627
1628 return \"\";
1629}
1630 [(set_attr "length" "5")])
1631
2c9c2489
RK
1632(define_insn "neghi2"
1633 [(set (match_operand:HI 0 "general_operand" "=rR,Q")
1634 (neg:HI (match_operand:HI 1 "general_operand" "0,0")))]
1635 ""
1636 "neg %0"
1637 [(set_attr "length" "1,2")])
1638
1639(define_insn "negqi2"
1640 [(set (match_operand:QI 0 "general_operand" "=rR,Q")
1641 (neg:QI (match_operand:QI 1 "general_operand" "0,0")))]
1642 ""
1643 "negb %0"
1644 [(set_attr "length" "1,2")])
1645
1646
1647;; Unconditional and other jump instructions
1648(define_insn "jump"
1649 [(set (pc)
1650 (label_ref (match_operand 0 "" "")))]
1651 ""
1652 "jmp %l0"
1653 [(set_attr "length" "2")])
1654
1655(define_insn ""
1656 [(set (pc)
1657 (label_ref (match_operand 0 "" "")))
1658 (clobber (const_int 1))]
1659 ""
1660 "jmp %l0"
1661 [(set_attr "length" "2")])
1662
1663(define_insn "tablejump"
1664 [(set (pc) (match_operand:HI 0 "general_operand" "rR,Q"))
1665 (use (label_ref (match_operand 1 "" "")))]
1666 ""
1667 "jmp %0"
1668 [(set_attr "length" "1,2")])
1669
1670;; indirect jump - let's be conservative!
1671;; allow only register_operand, even though we could also
1672;; allow labels etc.
1673
1674(define_insn "indirect_jump"
1675 [(set (pc) (match_operand:HI 0 "register_operand" "r"))]
1676 ""
1677 "jmp (%0)")
1678
1679;;- jump to subroutine
1680
1681(define_insn "call"
e7f9979a 1682 [(call (match_operand:HI 0 "general_operand" "rR,Q")
2c9c2489
RK
1683 (match_operand:HI 1 "general_operand" "g,g"))
1684;; (use (reg:HI 0)) what was that ???
1685 ]
1686 ;;- Don't use operand 1 for most machines.
1687 ""
1688 "jsr pc, %0"
1689 [(set_attr "length" "1,2")])
1690
1691;;- jump to subroutine
1692(define_insn "call_value"
1693 [(set (match_operand 0 "" "")
e7f9979a 1694 (call (match_operand:HI 1 "general_operand" "rR,Q")
2c9c2489
RK
1695 (match_operand:HI 2 "general_operand" "g,g")))
1696;; (use (reg:HI 0)) - what was that ????
1697 ]
1698 ;;- Don't use operand 2 for most machines.
1699 ""
1700 "jsr pc, %1"
1701 [(set_attr "length" "1,2")])
1702
1703;;- nop instruction
1704(define_insn "nop"
1705 [(const_int 0)]
1706 ""
1707 "nop")
1708\f
1709
1710;;- multiply
1711
1712(define_insn "muldf3"
1713 [(set (match_operand:DF 0 "register_operand" "=a,a,a")
1714 (mult:DF (match_operand:DF 1 "register_operand" "%0,0,0")
1715 (match_operand:DF 2 "general_operand" "fR,Q,F")))]
1716 "TARGET_FPU"
af36a4d2 1717 "{muld|mulf} %2, %0"
2c9c2489
RK
1718 [(set_attr "length" "1,2,5")])
1719
1720;; 16 bit result multiply:
1721;; currently we multiply only into odd registers, so we don't use two
1722;; registers - but this is a bit inefficient at times. If we define
1723;; a register class for each register, then we can specify properly
1724;; which register need which scratch register ....
1725
1726(define_insn "mulhi3"
1727 [(set (match_operand:HI 0 "register_operand" "=d,d") ; multiply regs
1728 (mult:HI (match_operand:HI 1 "register_operand" "%0,0")
1729 (match_operand:HI 2 "general_operand" "rR,Qi")))]
1730 "TARGET_45"
1731 "mul %2, %0"
1732 [(set_attr "length" "1,2")])
1733
1734;; 32 bit result
781e6f76
RK
1735(define_expand "mulhisi3"
1736 [(set (match_dup 3)
1737 (match_operand:HI 1 "general_operand" "g,g"))
1738 (set (match_operand:SI 0 "register_operand" "=r,r") ; even numbered!
1739 (mult:SI (truncate:HI
1740 (match_dup 0))
1741 (match_operand:HI 2 "general_operand" "rR,Qi")))]
1742 "TARGET_45"
1743 "operands[3] = gen_lowpart(HImode, operands[1]);")
1744
1745(define_insn ""
2c9c2489 1746 [(set (match_operand:SI 0 "register_operand" "=r,r") ; even numbered!
781e6f76
RK
1747 (mult:SI (truncate:HI
1748 (match_operand:SI 1 "register_operand" "%0,0"))
2c9c2489
RK
1749 (match_operand:HI 2 "general_operand" "rR,Qi")))]
1750 "TARGET_45"
1751 "mul %2, %0"
1752 [(set_attr "length" "1,2")])
1753
781e6f76
RK
1754;(define_insn "mulhisi3"
1755; [(set (match_operand:SI 0 "register_operand" "=r,r") ; even numbered!
1756; (mult:SI (truncate:HI
1757; (match_operand:SI 1 "register_operand" "%0,0"))
1758; (match_operand:HI 2 "general_operand" "rR,Qi")))]
1759; "TARGET_45"
1760; "mul %2, %0"
1761; [(set_attr "length" "1,2")])
1762
2c9c2489 1763;;- divide
2c9c2489
RK
1764(define_insn "divdf3"
1765 [(set (match_operand:DF 0 "register_operand" "=a,a,a")
1766 (div:DF (match_operand:DF 1 "register_operand" "0,0,0")
1767 (match_operand:DF 2 "general_operand" "fR,Q,F")))]
1768 "TARGET_FPU"
af36a4d2 1769 "{divd|divf} %2, %0"
2c9c2489
RK
1770 [(set_attr "length" "1,2,5")])
1771
0c253776 1772
2c9c2489 1773(define_expand "divhi3"
0c253776
RK
1774 [(set (subreg:HI (match_dup 1) 0)
1775 (div:HI (match_operand:SI 1 "general_operand" "0")
1776 (match_operand:HI 2 "general_operand" "g")))
1777 (set (match_operand:HI 0 "general_operand" "=r")
1778 (subreg:HI (match_dup 1) 0))]
2c9c2489 1779 "TARGET_45"
0c253776 1780 "")
2c9c2489 1781
2c9c2489 1782(define_insn ""
0c253776
RK
1783 [(set (subreg:HI (match_operand:SI 0 "general_operand" "=r") 0)
1784 (div:HI (match_operand:SI 1 "general_operand" "0")
1785 (match_operand:HI 2 "general_operand" "g")))]
2c9c2489
RK
1786 "TARGET_45"
1787 "div %2,%0"
1788 [(set_attr "length" "2")])
1789
1790(define_expand "modhi3"
ddef6bc7 1791 [(set (subreg:HI (match_dup 1) 2)
0c253776
RK
1792 (mod:HI (match_operand:SI 1 "general_operand" "0")
1793 (match_operand:HI 2 "general_operand" "g")))
1794 (set (match_operand:HI 0 "general_operand" "=r")
ddef6bc7 1795 (subreg:HI (match_dup 1) 2))]
2c9c2489 1796 "TARGET_45"
0c253776 1797 "")
2c9c2489 1798
2c9c2489 1799(define_insn ""
e7f9979a 1800 [(set (subreg:HI (match_operand:SI 0 "general_operand" "=r") 2)
0c253776
RK
1801 (mod:HI (match_operand:SI 1 "general_operand" "0")
1802 (match_operand:HI 2 "general_operand" "g")))]
2c9c2489 1803 "TARGET_45"
0c253776 1804 "div %2,%0"
2c9c2489
RK
1805 [(set_attr "length" "2")])
1806
0c253776
RK
1807;(define_expand "divmodhi4"
1808; [(parallel [(set (subreg:HI (match_dup 1) 0)
1809; (div:HI (match_operand:SI 1 "general_operand" "0")
1810; (match_operand:HI 2 "general_operand" "g")))
ddef6bc7 1811; (set (subreg:HI (match_dup 1) 2)
0c253776
RK
1812; (mod:HI (match_dup 1)
1813; (match_dup 2)))])
1814; (set (match_operand:HI 3 "general_operand" "=r")
ddef6bc7 1815; (subreg:HI (match_dup 1) 2))
0c253776
RK
1816; (set (match_operand:HI 0 "general_operand" "=r")
1817; (subreg:HI (match_dup 1) 0))]
1818; "TARGET_45"
1819; "")
1820;
1821;(define_insn ""
1822; [(set (subreg:HI (match_operand:SI 0 "general_operand" "=r") 0)
1823; (div:HI (match_operand:SI 1 "general_operand" "0")
1824; (match_operand:HI 2 "general_operand" "g")))
ddef6bc7 1825; (set (subreg:HI (match_dup 0) 2)
0c253776
RK
1826; (mod:HI (match_dup 1)
1827; (match_dup 2)))]
1828; "TARGET_45"
1829; "div %2, %0")
1830;
2c9c2489
RK
1831
1832;; is rotate doing the right thing to be included here ????