update copyrights in config dir.
[official-gcc.git] / gcc / config / pdp11 / pdp11.md
blobd917d01fd69be2d5eb67f305bcf49027665b8694
1 ;;- Machine description for the pdp11 for GNU C compiler
2 ;; Copyright (C) 1994, 95, 97-99, 2000 Free Software Foundation, Inc.
3 ;; Contributed by Michael K. Gschwind (mike@vlsivie.tuwien.ac.at).
5 ;; This file is part of GNU CC.
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.
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.
17 ;; You should have received a copy of the GNU General Public License
18 ;; along with GNU CC; see the file COPYING.  If not, write to
19 ;; the Free Software Foundation, 59 Temple Place - Suite 330,
20 ;; Boston, MA 02111-1307, USA.
23 ;; HI is 16 bit
24 ;; QI is 8 bit 
26 ;;- See file "rtl.def" for documentation on define_insn, match_*, et. al.
28 ;;- cpp macro #define NOTICE_UPDATE_CC in file tm.h handles condition code
29 ;;- updates for most instructions.
31 ;;- Operand classes for the register allocator:
33 ;; Compare instructions.
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)
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 ()
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
52 ;; library to do floating point constant folding - but 
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. 
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"))
64 ;; length default is 1 word each
65 (define_attr "length" "" (const_int 1))
67 ;; a user's asm statement
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")])
74 ;; define function units
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)
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)
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   "*
91   cc_status.flags = CC_IN_FPU;
92   return \"{cmpd|cmpf} %0, %1\;cfcc\";
94   [(set_attr "length" "2,3,6")])
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?
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   "")
112 ;; check for next insn for branch code - does this still
113 ;; work in gcc 2.* ?
115 (define_insn ""
116   [(set (cc0)
117         (compare (reg:SI 0)
118                  (reg:SI 2)))
119    (clobber (reg:SI 0))]
120   ""
121   "*
123   rtx br_insn = NEXT_INSN (insn);
124   RTX_CODE br_code;
126   if (GET_CODE (br_insn) != JUMP_INSN)
127     abort();
128   br_code =  GET_CODE (XEXP (XEXP (PATTERN (br_insn), 1), 0));
129   
130   switch(br_code)
131   {
132     case GEU:
133     case LTU:
134     case GTU:
135     case LEU:
136       
137       return \"jsr pc, ___ucmpsi\;cmp $1,r0\";
139     case GE:
140     case LT:
141     case GT:
142     case LE:
143     case EQ:
144     case NE:
146       return \"jsr pc, ___cmpsi\;tst r0\";
148     default:
150       abort();
151   }
153   [(set_attr "length" "4")])
156 (define_insn "cmphi"
157   [(set (cc0)
158         (compare (match_operand:HI 0 "general_operand" "rR,rR,Qi,Qi")
159                  (match_operand:HI 1 "general_operand" "rR,Qi,rR,Qi")))]
160   ""
161   "cmp %0,%1"
162   [(set_attr "length" "1,2,2,3")])
164 (define_insn "cmpqi"
165   [(set (cc0)
166         (compare (match_operand:QI 0 "general_operand" "rR,rR,Qi,Qi")
167                  (match_operand:QI 1 "general_operand" "rR,Qi,rR,Qi")))]
168   ""
169   "cmpb %0,%1"
170   [(set_attr "length" "1,2,2,3")])
171                            
173 ;; We have to have this because cse can optimize the previous pattern
174 ;; into this one.
176 (define_insn "tstdf"
177   [(set (cc0)
178         (match_operand:DF 0 "general_operand" "fR,Q"))]
179   "TARGET_FPU"
180   "*
182   cc_status.flags = CC_IN_FPU;
183   return \"{tstd|tstf} %0\;cfcc\";
185   [(set_attr "length" "2,3")])
188 (define_expand "tstsi"
189   [(set (reg:SI 0)
190         (match_operand:SI 0 "general_operand" "g"))
191    (parallel [(set (cc0)
192                    (reg:SI 0))
193               (clobber (reg:SI 0))])]
194   "0" ;; disable for test
195   "")
197 (define_insn ""
198   [(set (cc0)
199         (reg:SI 0))
200    (clobber (reg:SI 0))]
201   ""
202   "jsr pc, ___tstsi\;tst r0"
203   [(set_attr "length" "3")])
206 (define_insn "tsthi"
207   [(set (cc0)
208         (match_operand:HI 0 "general_operand" "rR,Q"))]
209   ""
210   "tst %0"
211   [(set_attr "length" "1,2")])
213 (define_insn "tstqi"
214   [(set (cc0)
215         (match_operand:QI 0 "general_operand" "rR,Q"))]
216   ""
217   "tstb %0"
218   [(set_attr "length" "1,2")])
220 ;; sob instruction - we need an assembler which can make this instruction
221 ;; valid under _all_ circumstances!
223 (define_insn ""
224   [(set (pc)
225         (if_then_else
226          (ne (plus:HI (match_operand:HI 0 "register_operand" "+r")
227                       (const_int -1))
228              (const_int 0))
229          (label_ref (match_operand 1 "" ""))
230          (pc)))
231    (set (match_dup 0)
232         (plus:HI (match_dup 0)
233                  (const_int -1)))]
234   "TARGET_40_PLUS"
235   "*
237  static int labelcount = 0;
238  static char buf[1000];
240  if (get_attr_length (insn) == 1)
241     return \"sob %0, %l1\";
243  /* emulate sob */
244  output_asm_insn (\"dec %0\", operands);
246  sprintf (buf, \"bge LONG_SOB%d\", labelcount);
247  output_asm_insn (buf, NULL);
249  output_asm_insn (\"jmp %l1\", operands);
251  sprintf (buf, \"LONG_SOB%d:\", labelcount++);
252  output_asm_insn (buf, NULL);
254  return \"\";
256   [(set (attr "length") (if_then_else (ior (le (minus (match_dup 0)
257                                                        (pc))
258                                                 (const_int -256))
259                                            (ge (minus (match_dup 0)
260                                                        (pc))
261                                                 (const_int 0)))
262                                       (const_int 4)
263                                       (const_int 1)))])
265 ;; These control RTL generation for conditional jump insns
266 ;; and match them for register allocation.
268 ;; problem with too short jump distance! we need an assembler which can 
269 ;; make this valid for all jump distances!
270 ;; e.g. gas!
272 ;; these must be changed to check for CC_IN_FCCR if float is to be 
273 ;; enabled
275 (define_insn "beq"
276   [(set (pc)
277         (if_then_else (eq (cc0)
278                           (const_int 0))
279                       (label_ref (match_operand 0 "" ""))
280                       (pc)))]
281   ""
282   "* return output_jump(\"beq\", \"bne\", get_attr_length(insn));"
283   [(set (attr "length") (if_then_else (ior (le (minus (match_dup 0)
284                                                       (pc))
285                                                (const_int -128))
286                                            (ge (minus (match_dup 0)
287                                                       (pc))
288                                                (const_int 128)))
289                                       (const_int 3)
290                                       (const_int 1)))])
293 (define_insn "bne"
294   [(set (pc)
295         (if_then_else (ne (cc0)
296                           (const_int 0))
297                       (label_ref (match_operand 0 "" ""))
298                       (pc)))]
299   ""
300   "* return output_jump(\"bne\", \"beq\", get_attr_length(insn));"
301   [(set (attr "length") (if_then_else (ior (le (minus (match_dup 0)
302                                                       (pc))
303                                                (const_int -128))
304                                            (ge (minus (match_dup 0)
305                                                       (pc))
306                                                (const_int 128)))
307                                       (const_int 3)
308                                       (const_int 1)))])
310 (define_insn "bgt"
311   [(set (pc)
312         (if_then_else (gt (cc0)
313                           (const_int 0))
314                       (label_ref (match_operand 0 "" ""))
315                       (pc)))]
316   ""
317   "* return output_jump(\"bgt\", \"ble\", get_attr_length(insn));"
318   [(set (attr "length") (if_then_else (ior (le (minus (match_dup 0)
319                                                       (pc))
320                                                (const_int -128))
321                                            (ge (minus (match_dup 0)
322                                                       (pc))
323                                                (const_int 128)))
324                                       (const_int 3)
325                                       (const_int 1)))])
327 (define_insn "bgtu"
328   [(set (pc)
329         (if_then_else (gtu (cc0)
330                            (const_int 0))
331                       (label_ref (match_operand 0 "" ""))
332                       (pc)))]
333   ""
334   "* return output_jump(\"bhi\", \"blos\", get_attr_length(insn));"
335   [(set (attr "length") (if_then_else (ior (le (minus (match_dup 0)
336                                                       (pc))
337                                                (const_int -128))
338                                            (ge (minus (match_dup 0)
339                                                       (pc))
340                                                (const_int 128)))
341                                       (const_int 3)
342                                       (const_int 1)))])
344 (define_insn "blt"
345   [(set (pc)
346         (if_then_else (lt (cc0)
347                           (const_int 0))
348                       (label_ref (match_operand 0 "" ""))
349                       (pc)))]
350   ""
351   "* return output_jump(\"blt\", \"bge\", get_attr_length(insn));"
352   [(set (attr "length") (if_then_else (ior (le (minus (match_dup 0)
353                                                       (pc))
354                                                (const_int -128))
355                                            (ge (minus (match_dup 0)
356                                                       (pc))
357                                                (const_int 128)))
358                                       (const_int 3)
359                                       (const_int 1)))])
362 (define_insn "bltu"
363   [(set (pc)
364         (if_then_else (ltu (cc0)
365                            (const_int 0))
366                       (label_ref (match_operand 0 "" ""))
367                       (pc)))]
368   ""
369   "* return output_jump(\"blo\", \"bhis\", get_attr_length(insn));"
370   [(set (attr "length") (if_then_else (ior (le (minus (match_dup 0)
371                                                       (pc))
372                                                (const_int -128))
373                                            (ge (minus (match_dup 0)
374                                                       (pc))
375                                                (const_int 128)))
376                                       (const_int 3)
377                                       (const_int 1)))])
379 (define_insn "bge"
380   [(set (pc)
381         (if_then_else (ge (cc0)
382                           (const_int 0))
383                       (label_ref (match_operand 0 "" ""))
384                       (pc)))]
385   ""
386   "* return output_jump(\"bge\", \"blt\", get_attr_length(insn));"
387   [(set (attr "length") (if_then_else (ior (le (minus (match_dup 0)
388                                                       (pc))
389                                                (const_int -128))
390                                            (ge (minus (match_dup 0)
391                                                       (pc))
392                                                (const_int 128)))
393                                       (const_int 3)
394                                       (const_int 1)))])
396 (define_insn "bgeu"
397   [(set (pc)
398         (if_then_else (geu (cc0)
399                            (const_int 0))
400                       (label_ref (match_operand 0 "" ""))
401                       (pc)))]
402   ""
403   "* return output_jump(\"bhis\", \"blo\", get_attr_length(insn));"
404   [(set (attr "length") (if_then_else (ior (le (minus (match_dup 0)
405                                                       (pc))
406                                                (const_int -128))
407                                            (ge (minus (match_dup 0)
408                                                       (pc))
409                                                (const_int 128)))
410                                       (const_int 3)
411                                       (const_int 1)))])
413 (define_insn "ble"
414   [(set (pc)
415         (if_then_else (le (cc0)
416                           (const_int 0))
417                       (label_ref (match_operand 0 "" ""))
418                       (pc)))]
419   ""
420   "* return output_jump(\"ble\", \"bgt\", get_attr_length(insn));"
421   [(set (attr "length") (if_then_else (ior (le (minus (match_dup 0)
422                                                       (pc))
423                                                (const_int -128))
424                                            (ge (minus (match_dup 0)
425                                                       (pc))
426                                                (const_int 128)))
427                                       (const_int 3)
428                                       (const_int 1)))])
430 (define_insn "bleu"
431   [(set (pc)
432         (if_then_else (leu (cc0)
433                            (const_int 0))
434                       (label_ref (match_operand 0 "" ""))
435                       (pc)))]
436   ""
437   "* return output_jump(\"blos\", \"bhi\", get_attr_length(insn));"
438   [(set (attr "length") (if_then_else (ior (le (minus (match_dup 0)
439                                                       (pc))
440                                                (const_int -128))
441                                            (ge (minus (match_dup 0)
442                                                       (pc))
443                                                (const_int 128)))
444                                       (const_int 3)
445                                       (const_int 1)))])
448 ;; These match inverted jump insns for register allocation.
450 (define_insn ""
451   [(set (pc)
452         (if_then_else (eq (cc0)
453                           (const_int 0))
454                       (pc)
455                       (label_ref (match_operand 0 "" ""))))]
456   ""
457   "* return output_jump(\"bne\", \"beq\", get_attr_length(insn));"
458   [(set (attr "length") (if_then_else (ior (le (minus (match_dup 0)
459                                                       (pc))
460                                                (const_int -128))
461                                            (ge (minus (match_dup 0)
462                                                       (pc))
463                                                (const_int 128)))
464                                       (const_int 3)
465                                       (const_int 1)))])
467 (define_insn ""
468   [(set (pc)
469         (if_then_else (ne (cc0)
470                           (const_int 0))
471                       (pc)
472                       (label_ref (match_operand 0 "" ""))))]
473   ""
474   "* return output_jump(\"beq\", \"bne\", get_attr_length(insn));"
475   [(set (attr "length") (if_then_else (ior (le (minus (match_dup 0)
476                                                       (pc))
477                                                (const_int -128))
478                                            (ge (minus (match_dup 0)
479                                                       (pc))
480                                                (const_int 128)))
481                                       (const_int 3)
482                                       (const_int 1)))])
484 (define_insn ""
485   [(set (pc)
486         (if_then_else (gt (cc0)
487                           (const_int 0))
488                       (pc)
489                       (label_ref (match_operand 0 "" ""))))]
490   ""
491   "* return output_jump(\"ble\", \"bgt\", get_attr_length(insn));"
492   [(set (attr "length") (if_then_else (ior (le (minus (match_dup 0)
493                                                       (pc))
494                                                (const_int -128))
495                                            (ge (minus (match_dup 0)
496                                                       (pc))
497                                                (const_int 128)))
498                                       (const_int 3)
499                                       (const_int 1)))])
501 (define_insn ""
502   [(set (pc)
503         (if_then_else (gtu (cc0)
504                            (const_int 0))
505                       (pc)
506                       (label_ref (match_operand 0 "" ""))))]
507   ""
508   "* return output_jump(\"blos\", \"bhi\", get_attr_length(insn));"
509   [(set (attr "length") (if_then_else (ior (le (minus (match_dup 0)
510                                                       (pc))
511                                                (const_int -128))
512                                            (ge (minus (match_dup 0)
513                                                       (pc))
514                                                (const_int 128)))
515                                       (const_int 3)
516                                       (const_int 1)))])
518 (define_insn ""
519   [(set (pc)
520         (if_then_else (lt (cc0)
521                           (const_int 0))
522                       (pc)
523                       (label_ref (match_operand 0 "" ""))))]
524   ""
525   "* return output_jump(\"bge\", \"blt\", get_attr_length(insn));"
526   [(set (attr "length") (if_then_else (ior (le (minus (match_dup 0)
527                                                       (pc))
528                                                (const_int -128))
529                                            (ge (minus (match_dup 0)
530                                                       (pc))
531                                                (const_int 128)))
532                                       (const_int 3)
533                                       (const_int 1)))])
535 (define_insn ""
536   [(set (pc)
537         (if_then_else (ltu (cc0)
538                            (const_int 0))
539                       (pc)
540                       (label_ref (match_operand 0 "" ""))))]
541   ""
542   "* return output_jump(\"bhis\", \"blo\", get_attr_length(insn));"
543   [(set (attr "length") (if_then_else (ior (le (minus (match_dup 0)
544                                                       (pc))
545                                                (const_int -128))
546                                            (ge (minus (match_dup 0)
547                                                       (pc))
548                                                (const_int 128)))
549                                       (const_int 3)
550                                       (const_int 1)))])
552 (define_insn ""
553   [(set (pc)
554         (if_then_else (ge (cc0)
555                           (const_int 0))
556                       (pc)
557                       (label_ref (match_operand 0 "" ""))))]
558   ""  
559   "* return output_jump(\"blt\", \"bge\", get_attr_length(insn));"
560   [(set (attr "length") (if_then_else (ior (le (minus (match_dup 0)
561                                                       (pc))
562                                                (const_int -128))
563                                            (ge (minus (match_dup 0)
564                                                       (pc))
565                                                (const_int 128)))
566                                       (const_int 3)
567                                       (const_int 1)))])
569 (define_insn ""
570   [(set (pc)
571         (if_then_else (geu (cc0)
572                            (const_int 0))
573                       (pc)
574                       (label_ref (match_operand 0 "" ""))))]
575   ""
576   "* return output_jump(\"blo\", \"bhis\", get_attr_length(insn));"
577   [(set (attr "length") (if_then_else (ior (le (minus (match_dup 0)
578                                                       (pc))
579                                                (const_int -128))
580                                            (ge (minus (match_dup 0)
581                                                       (pc))
582                                                (const_int 128)))
583                                       (const_int 3)
584                                       (const_int 1)))])
586 (define_insn ""
587   [(set (pc)
588         (if_then_else (le (cc0)
589                           (const_int 0))
590                       (pc)
591                       (label_ref (match_operand 0 "" ""))))]
592   ""
593   "* return output_jump(\"bgt\", \"ble\", get_attr_length(insn));"
594   [(set (attr "length") (if_then_else (ior (le (minus (match_dup 0)
595                                                       (pc))
596                                                (const_int -128))
597                                            (ge (minus (match_dup 0)
598                                                       (pc))
599                                                (const_int 128)))
600                                       (const_int 3)
601                                       (const_int 1)))])
603 (define_insn ""
604   [(set (pc)
605         (if_then_else (leu (cc0)
606                            (const_int 0))
607                       (pc)
608                       (label_ref (match_operand 0 "" ""))))]
609   ""
610   "* return output_jump(\"bhi\", \"blos\", get_attr_length(insn));"
611   [(set (attr "length") (if_then_else (ior (le (minus (match_dup 0)
612                                                       (pc))
613                                                (const_int -128))
614                                            (ge (minus (match_dup 0)
615                                                       (pc))
616                                                (const_int 128)))
617                                       (const_int 3)
618                                       (const_int 1)))])
620 ;; Move instructions
622 (define_insn "movdi"
623   [(set (match_operand:DI 0 "general_operand" "=g")
624         (match_operand:DI 1 "general_operand" "g"))]
625   ""
626   "* return output_move_quad (operands);"
627 ;; what's the mose expensive code - say twice movsi = 16
628   [(set_attr "length" "16")])
630 (define_insn "movsi"
631   [(set (match_operand:SI 0 "general_operand" "=r,r,r,rm,m")
632         (match_operand:SI 1 "general_operand" "rN,IJ,K,m,r"))]
633   ""
634   "* return output_move_double (operands);"
635 ;; what's the most expensive code ? - I think 8!
636 ;; we could split it up and make several sub-cases...
637   [(set_attr "length" "2,3,4,8,8")])
639 (define_insn "movhi"
640   [(set (match_operand:HI 0 "general_operand" "=rR,rR,Q,Q")
641         (match_operand:HI 1 "general_operand" "rRN,Qi,rRN,Qi"))]
642   ""
643   "*
645   if (operands[1] == const0_rtx)
646     return \"clr %0\";
648   return \"mov %1, %0\";
650   [(set_attr "length" "1,2,2,3")])
652 (define_insn "movqi"
653   [(set (match_operand:QI 0 "general_operand" "=rR,rR,Q,Q")
654         (match_operand:QI 1 "general_operand" "rRN,Qi,rRN,Qi"))]
655   ""
656   "*
658   if (operands[1] == const0_rtx)
659     return \"clrb %0\";
661   return \"movb %1, %0\";
663   [(set_attr "length" "1,2,2,3")])
665 ;; do we have to supply all these moves? e.g. to 
666 ;; NO_LOAD_FPU_REGs ? 
667 (define_insn "movdf"
668   [(set (match_operand:DF 0 "general_operand" "=f,R,f,Q,f,m")
669         (match_operand:DF 1 "general_operand" "fR,f,Q,f,F,m"))]
670   ""
671   "* return output_move_quad (operands);"
672 ;; just a guess..
673   [(set_attr "length" "1,1,2,2,5,16")])
675 (define_insn "movsf"
676   [(set (match_operand:SF 0 "general_operand" "=g,r,g")
677         (match_operand:SF 1 "general_operand" "r,rmF,g"))]
678   "TARGET_FPU"
679   "* return output_move_double (operands);"
680   [(set_attr "length" "8,8,8")])
682 ;; maybe fiddle a bit with move_ratio, then 
683 ;; let constraints only accept a register ...
685 (define_expand "movstrhi"
686   [(parallel [(set (match_operand:BLK 0 "general_operand" "=g,g")
687                    (match_operand:BLK 1 "general_operand" "g,g"))
688               (use (match_operand:HI 2 "arith_operand" "n,&mr"))
689               (use (match_operand:HI 3 "immediate_operand" "i,i"))
690               (clobber (match_scratch:HI 4 "=&r,X"))
691               (clobber (match_dup 5))
692               (clobber (match_dup 6))
693               (clobber (match_dup 2))])]
694   "(TARGET_BCOPY_BUILTIN)"
695   "
697   operands[0]
698     = change_address (operands[0], VOIDmode,
699                       copy_to_mode_reg (Pmode, XEXP (operands[0], 0)));
700   operands[1]
701     = change_address (operands[1], VOIDmode,
702                       copy_to_mode_reg (Pmode, XEXP (operands[1], 0)));
704   operands[5] = XEXP (operands[0], 0);
705   operands[6] = XEXP (operands[1], 0);
709 (define_insn "" ; "movstrhi"
710   [(set (mem:BLK (match_operand:HI 0 "general_operand" "=r,r"))
711         (mem:BLK (match_operand:HI 1 "general_operand" "r,r")))
712    (use (match_operand:HI 2 "arith_operand" "n,&r"))
713    (use (match_operand:HI 3 "immediate_operand" "i,i"))
714    (clobber (match_scratch:HI 4 "=&r,X"))
715    (clobber (match_dup 0))
716    (clobber (match_dup 1))
717    (clobber (match_dup 2))]
718   "(TARGET_BCOPY_BUILTIN)"
719   "* return output_block_move (operands);"
720 ;;; just a guess
721   [(set_attr "length" "40")])
722    
725 ;;- truncation instructions
727 (define_insn  "truncdfsf2"
728   [(set (match_operand:SF 0 "general_operand" "=r,R,Q")
729         (float_truncate:SF (match_operand:DF 1 "register_operand" "a,a,a")))]
730   "TARGET_FPU"
731   "* if (which_alternative ==0)
732      {
733        output_asm_insn(\"{stcdf|movfo} %1, -(sp)\", operands);
734        output_asm_insn(\"mov (sp)+, %0\", operands);
735        operands[0] = gen_rtx_REG (HImode, REGNO (operands[0])+1);
736        output_asm_insn(\"mov (sp)+, %0\", operands);
737        return \"\";
738      }
739      else if (which_alternative == 1)
740        return \"{stcdf|movfo} %1, %0\";
741      else 
742        return \"{stcdf|movfo} %1, %0\";
743   "
744   [(set_attr "length" "3,1,2")])
747 (define_expand "truncsihi2"
748   [(set (match_operand:HI 0 "general_operand" "=g")
749         (subreg:HI 
750           (match_operand:SI 1 "general_operand" "or")
751           0))]
752   ""
753   "")
756 ;;- zero extension instructions
758 (define_insn "zero_extendqihi2"
759   [(set (match_operand:HI 0 "general_operand" "=r")
760         (zero_extend:HI (match_operand:QI 1 "general_operand" "0")))]
761   ""
762   "bic $(256*255), %0"
763   [(set_attr "length" "2")])
764                          
765 (define_expand "zero_extendhisi2"
766   [(set (subreg:HI 
767           (match_dup 0)
768           1)
769         (match_operand:HI 1 "register_operand" "r"))
770    (set (subreg:HI 
771           (match_operand:SI 0 "register_operand" "=r")
772           0)
773         (const_int 0))]
774   ""
775   "/* operands[1] = make_safe_from (operands[1], operands[0]); */")
778 ;;- sign extension instructions
780 (define_insn "extendsfdf2"
781   [(set (match_operand:DF 0 "register_operand" "=a,a,a")
782         (float_extend:DF (match_operand:SF 1 "general_operand" "r,R,Q")))]
783   "TARGET_FPU"
784   "@
785    mov %1, -(sp)\;{ldcfd|movof} (sp)+,%0
786    {ldcfd|movof} %1, %0
787    {ldcfd|movof} %1, %0"
788   [(set_attr "length" "2,1,2")])
790 ;; does movb sign extend in register-to-register move?
791 (define_insn "extendqihi2"
792   [(set (match_operand:HI 0 "register_operand" "=r,r")
793         (sign_extend:HI (match_operand:QI 1 "general_operand" "rR,Q")))]
794   ""
795   "movb %1, %0"
796   [(set_attr "length" "1,2")])
798 (define_insn "extendqisi2"
799   [(set (match_operand:SI 0 "register_operand" "=r,r")
800         (sign_extend:SI (match_operand:QI 1 "general_operand" "rR,Q")))]
801   "TARGET_40_PLUS"
802   "*
804   rtx latehalf[2];
806   /* make register pair available */
807   latehalf[0] = operands[0];
808   operands[0] = gen_rtx_REG (HImode, REGNO (operands[0])+ 1);
810   output_asm_insn(\"movb %1, %0\", operands);
811   output_asm_insn(\"sxt %0\", latehalf);
812     
813   return \"\";
815   [(set_attr "length" "2,3")])
817 ;; maybe we have to use define_expand to say that we have the instruction,
818 ;; unconditionally, and then match dependent on CPU type:
820 (define_expand "extendhisi2"
821   [(set (match_operand:SI 0 "general_operand" "=g")
822         (sign_extend:SI (match_operand:HI 1 "general_operand" "g")))]
823   ""
824   "")
825   
826 (define_insn "" ; "extendhisi2"
827   [(set (match_operand:SI 0 "general_operand" "=o,<,r")
828         (sign_extend:SI (match_operand:HI 1 "general_operand" "g,g,g")))]
829   "TARGET_40_PLUS"
830   "*
832   rtx latehalf[2];
834   /* we don't want to mess with auto increment */
835   
836   switch(which_alternative)
837   {
838     case 0:
840       latehalf[0] = operands[0];
841       operands[0] = adj_offsettable_operand(operands[0], 2);
842   
843       output_asm_insn(\"mov %1, %0\", operands);
844       output_asm_insn(\"sxt %0\", latehalf);
846       return \"\";
848     case 1:
850       /* - auto-decrement - right direction ;-) */
851       output_asm_insn(\"mov %1, %0\", operands);
852       output_asm_insn(\"sxt %0\", operands);
854       return \"\";
856     case 2:
858       /* make register pair available */
859       latehalf[0] = operands[0];
860       operands[0] = gen_rtx_REG (HImode, REGNO (operands[0]) + 1);
862       output_asm_insn(\"mov %1, %0\", operands);
863       output_asm_insn(\"sxt %0\", latehalf);
865       return \"\";
867     default:
869       abort();
870   }
872   [(set_attr "length" "5,3,3")])
875 (define_insn ""
876   [(set (match_operand:SI 0 "register_operand" "=r")
877         (sign_extend:SI (match_operand:HI 1 "general_operand" "0")))]
878   "(! TARGET_40_PLUS)"
879   "*
881   static int count = 0;
882   char buf[100];
883   rtx lateoperands[2];
885   lateoperands[0] = operands[0];
886   operands[0] = gen_rtx_REG (HImode, REGNO (operands[0]) + 1);
888   output_asm_insn(\"tst %0\", operands);
889   sprintf(buf, \"bge extendhisi%d\", count);
890   output_asm_insn(buf, NULL);
891   output_asm_insn(\"mov -1, %0\", lateoperands);
892   sprintf(buf, \"bne extendhisi%d\", count+1);
893   output_asm_insn(buf, NULL);
894   sprintf(buf, \"\\nextendhisi%d:\", count);
895   output_asm_insn(buf, NULL);
896   output_asm_insn(\"clr %0\", lateoperands);
897   sprintf(buf, \"\\nextendhisi%d:\", count+1);
898   output_asm_insn(buf, NULL);
900   count += 2;
902   return \"\";
904   [(set_attr "length" "6")])
906 ;; make float to int and vice versa 
907 ;; using the cc_status.flag field we could probably cut down
908 ;; on seti and setl
909 ;; assume that we are normally in double and integer mode -
910 ;; what do pdp library routines do to fpu mode ?
912 (define_insn "floatsidf2"
913   [(set (match_operand:DF 0 "register_operand" "=a,a,a")
914         (float:DF (match_operand:SI 1 "general_operand" "r,R,Q")))]
915   "TARGET_FPU"
916   "* if (which_alternative ==0)
917      {
918        rtx latehalf[2];
920        latehalf[0] = NULL; 
921        latehalf[1] = gen_rtx_REG (HImode, REGNO (operands[0]) + 1);
922        output_asm_insn(\"mov %1, -(sp)\", latehalf);
923        output_asm_insn(\"mov %1, -(sp)\", operands);
924        
925        output_asm_insn(\"setl\", operands);
926        output_asm_insn(\"{ldcld|movif} (sp)+, %0\", operands);
927        output_asm_insn(\"seti\", operands);
928        return \"\";
929      }
930      else if (which_alternative == 1)
931        return \"setl\;{ldcld|movif} %1, %0\;seti\";
932      else 
933        return \"setl\;{ldcld|movif} %1, %0\;seti\";
934   "
935   [(set_attr "length" "5,3,4")])
937 (define_insn "floathidf2"
938   [(set (match_operand:DF 0 "register_operand" "=a,a")
939         (float:DF (match_operand:HI 1 "general_operand" "rR,Qi")))]
940   "TARGET_FPU"
941   "{ldcid|movif} %1, %0"
942   [(set_attr "length" "1,2")])
943         
944 ;; cut float to int
945 (define_insn "fix_truncdfsi2"
946   [(set (match_operand:SI 0 "general_operand" "=r,R,Q")
947         (fix:SI (fix:DF (match_operand:DF 1 "register_operand" "a,a,a"))))]
948   "TARGET_FPU"
949   "* if (which_alternative ==0)
950      {
951        output_asm_insn(\"setl\", operands);
952        output_asm_insn(\"{stcdl|movfi} %1, -(sp)\", operands);
953        output_asm_insn(\"seti\", operands);
954        output_asm_insn(\"mov (sp)+, %0\", operands);
955        operands[0] = gen_rtx_REG (HImode, REGNO (operands[0]) + 1);
956        output_asm_insn(\"mov (sp)+, %0\", operands);
957        return \"\";
958      }
959      else if (which_alternative == 1)
960        return \"setl\;{stcdl|movfi} %1, %0\;seti\";
961      else 
962        return \"setl\;{stcdl|movfi} %1, %0\;seti\";
963   "
964   [(set_attr "length" "5,3,4")])
966 (define_insn "fix_truncdfhi2"
967   [(set (match_operand:HI 0 "general_operand" "=rR,Q")
968         (fix:HI (fix:DF (match_operand:DF 1 "register_operand" "a,a"))))]
969   "TARGET_FPU"
970   "{stcdi|movfi} %1, %0"
971   [(set_attr "length" "1,2")])
974 ;;- arithmetic instructions
975 ;;- add instructions
977 (define_insn "adddf3"
978   [(set (match_operand:DF 0 "register_operand" "=a,a,a")
979         (plus:DF (match_operand:DF 1 "register_operand" "%0,0,0")
980                  (match_operand:DF 2 "general_operand" "fR,Q,F")))]
981   "TARGET_FPU"
982   "{addd|addf} %2, %0"
983   [(set_attr "length" "1,2,5")])
985 (define_insn "addsi3"
986   [(set (match_operand:SI 0 "general_operand" "=r,r,o,o,r,r,r,o,o,o")
987         (plus:SI (match_operand:SI 1 "general_operand" "%0,0,0,0,0,0,0,0,0,0")
988                  (match_operand:SI 2 "general_operand" "r,o,r,o,I,J,K,I,J,K")))]
989   ""
990   "*
991 { /* Here we trust that operands don't overlap 
993      or is lateoperands the low word?? - looks like it! */
995   rtx lateoperands[3];
996   
997   lateoperands[0] = operands[0];
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];
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);
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   }
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   }
1028   if (INTVAL(lateoperands[2]))
1029     output_asm_insn (\"add %2, %0\", lateoperands);
1031   return \"\";
1033   [(set_attr "length" "3,5,6,8,3,1,5,5,3,8")])
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   "*
1042   if (GET_CODE (operands[2]) == CONST_INT)
1043     {
1044       if (INTVAL(operands[2]) == 1)
1045         return \"inc %0\";
1046       else if (INTVAL(operands[2]) == -1)
1047         return \"dec %0\";
1048     }
1050   return \"add %2, %0\";
1052   [(set_attr "length" "1,2,2,3")])
1054 (define_insn "addqi3"
1055   [(set (match_operand:QI 0 "general_operand" "=rR,rR,Q,Q")
1056         (plus:QI (match_operand:QI 1 "general_operand" "%0,0,0,0")
1057                  (match_operand:QI 2 "general_operand" "rRLM,Qi,rRLM,Qi")))]
1058   ""
1059   "*
1061   if (GET_CODE (operands[2]) == CONST_INT)
1062     {
1063       if (INTVAL(operands[2]) == 1)
1064         return \"incb %0\";
1065       else if (INTVAL(operands[2]) == -1)
1066         return \"decb %0\";
1067     }
1069   return \"addb %2, %0\";
1071   [(set_attr "length" "1,2,2,3")])
1074 ;;- subtract instructions
1075 ;; we don't have to care for constant second 
1076 ;; args, since they are canonical plus:xx now!
1077 ;; also for minus:DF ??
1079 (define_insn "subdf3"
1080   [(set (match_operand:DF 0 "register_operand" "=a,a")
1081         (minus:DF (match_operand:DF 1 "register_operand" "0,0")
1082                   (match_operand:DF 2 "general_operand" "fR,Q")))]
1083   "TARGET_FPU"
1084   "{subd|subf} %2, %0"
1085   [(set_attr "length" "1,2")])
1087 (define_insn "subsi3"
1088   [(set (match_operand:SI 0 "general_operand" "=r,r,o,o")
1089         (minus:SI (match_operand:SI 1 "general_operand" "0,0,0,0")
1090                   (match_operand:SI 2 "general_operand" "r,o,r,o")))]
1091   ""
1092   "*
1093 { /* Here we trust that operands don't overlap 
1095      or is lateoperands the low word?? - looks like it! */
1097   rtx lateoperands[3];
1098   
1099   lateoperands[0] = operands[0];
1101   if (REG_P (operands[0]))
1102     operands[0] = gen_rtx_REG (HImode, REGNO (operands[0]) + 1);
1103   else
1104     operands[0] = adj_offsettable_operand (operands[0], 2);
1105   
1106   lateoperands[2] = operands[2];
1108   if (REG_P (operands[2]))
1109     operands[2] = gen_rtx_REG (HImode, REGNO (operands[2]) + 1);
1110   else
1111     operands[2] = adj_offsettable_operand(operands[2], 2);
1113   output_asm_insn (\"sub %2, %0\", operands);
1114   output_asm_insn (\"sbc %0\", lateoperands);
1115   output_asm_insn (\"sub %2, %0\", lateoperands);
1116   return \"\";
1118 ;; offsettable memory addresses always are expensive!!!
1119   [(set_attr "length" "3,5,6,8")])
1121 (define_insn "subhi3"
1122   [(set (match_operand:HI 0 "general_operand" "=rR,rR,Q,Q")
1123         (minus:HI (match_operand:HI 1 "general_operand" "0,0,0,0")
1124                   (match_operand:HI 2 "general_operand" "rR,Qi,rR,Qi")))]
1125   ""
1126   "*
1128   if (GET_CODE (operands[2]) == CONST_INT)
1129     abort();
1131   return \"sub %2, %0\";
1133   [(set_attr "length" "1,2,2,3")])
1135 (define_insn "subqi3"
1136   [(set (match_operand:QI 0 "general_operand" "=rR,rR,Q,Q")
1137         (minus:QI (match_operand:QI 1 "general_operand" "0,0,0,0")
1138                   (match_operand:QI 2 "general_operand" "rR,Qi,rR,Qi")))]
1139   ""
1140   "*
1142   if (GET_CODE (operands[2]) == CONST_INT)
1143     abort();
1145   return \"subb %2, %0\";
1147   [(set_attr "length" "1,2,2,3")])
1149 ;;;;- and instructions
1150 ;; Bit-and on the pdp (like on the vax) is done with a clear-bits insn.
1151 (define_expand "andsi3"
1152   [(set (match_operand:SI 0 "general_operand" "=g")
1153         (and:SI (match_operand:SI 1 "general_operand" "0")
1154                 (not:SI (match_operand:SI 2 "general_operand" "g"))))]
1155   ""
1156   "
1158   extern rtx expand_unop ();
1159   if (GET_CODE (operands[2]) == CONST_INT)
1160     operands[2] = GEN_INT (~INTVAL (operands[2]));
1161   else
1162     operands[2] = expand_unop (SImode, one_cmpl_optab, operands[2], 0, 1);
1165 (define_expand "andhi3"
1166   [(set (match_operand:HI 0 "general_operand" "=g")
1167         (and:HI (match_operand:HI 1 "general_operand" "0")
1168                 (not:HI (match_operand:HI 2 "general_operand" "g"))))]
1169   ""
1170   "
1172   extern rtx expand_unop ();
1173   if (GET_CODE (operands[2]) == CONST_INT)
1174     operands[2] = GEN_INT (~INTVAL (operands[2]));
1175   else
1176     operands[2] = expand_unop (HImode, one_cmpl_optab, operands[2], 0, 1);
1179 (define_expand "andqi3"
1180   [(set (match_operand:QI 0 "general_operand" "=g")
1181         (and:QI (match_operand:QI 1 "general_operand" "0")
1182                 (not:QI (match_operand:QI 2 "general_operand" "g"))))]
1183   ""
1184   "
1186   extern rtx expand_unop ();
1187   rtx op = operands[2];
1188   if (GET_CODE (op) == CONST_INT)
1189     operands[2] = GEN_INT (((1 << 8) - 1) & ~INTVAL (op));
1190   else
1191     operands[2] = expand_unop (QImode, one_cmpl_optab, op, 0, 1);
1194 (define_insn "andcbsi3"
1195   [(set (match_operand:SI 0 "general_operand" "=r,r,o,o,r,r,r,o,o,o")
1196         (and:SI (match_operand:SI 1 "general_operand" "%0,0,0,0,0,0,0,0,0,0")
1197                 (not:SI (match_operand:SI 2 "general_operand" "r,o,r,o,I,J,K,I,J,K"))))]
1198   ""
1199   "*
1200 { /* Here we trust that operands don't overlap 
1202      or is lateoperands the low word?? - looks like it! */
1204   rtx lateoperands[3];
1205   
1206   lateoperands[0] = operands[0];
1208   if (REG_P (operands[0]))
1209     operands[0] = gen_rtx_REG (HImode, REGNO (operands[0]) + 1);
1210   else
1211     operands[0] = adj_offsettable_operand (operands[0], 2);
1212   
1213   if (! CONSTANT_P(operands[2]))
1214   {
1215     lateoperands[2] = operands[2];
1217     if (REG_P (operands[2]))
1218       operands[2] = gen_rtx_REG (HImode, REGNO (operands[2]) + 1);
1219     else
1220       operands[2] = adj_offsettable_operand(operands[2], 2);
1222     output_asm_insn (\"bic %2, %0\", operands);
1223     output_asm_insn (\"bic %2, %0\", lateoperands);
1224     return \"\";
1225   }
1227   lateoperands[2] = GEN_INT ((INTVAL (operands[2]) >> 16) & 0xffff);
1228   operands[2] = GEN_INT (INTVAL (operands[2]) & 0xffff);
1229   
1230   /* these have different lengths, so we should have 
1231      different constraints! */
1232   if (INTVAL(operands[2]))
1233     output_asm_insn (\"bic %2, %0\", operands);
1235   if (INTVAL(lateoperands[2]))
1236     output_asm_insn (\"bic %2, %0\", lateoperands);
1238   return \"\";
1240   [(set_attr "length" "2,4,4,6,2,2,4,3,3,6")])
1242 (define_insn "andcbhi3"
1243   [(set (match_operand:HI 0 "general_operand" "=rR,rR,Q,Q")
1244         (and:HI (match_operand:HI 1 "general_operand" "0,0,0,0")
1245                 (not:HI (match_operand:HI 2 "general_operand" "rR,Qi,rR,Qi"))))]
1246   ""
1247   "bic %2, %0"
1248   [(set_attr "length" "1,2,2,3")])
1250 (define_insn "andcbqi3"
1251   [(set (match_operand:QI 0 "general_operand" "=rR,rR,Q,Q")
1252         (and:QI (match_operand:QI 1 "general_operand" "0,0,0,0")
1253                 (not:QI (match_operand:QI 2 "general_operand" "rR,Qi,rR,Qi"))))]
1254   ""
1255   "bicb %2, %0"
1256   [(set_attr "length" "1,2,2,3")])
1258 ;;- Bit set (inclusive or) instructions
1259 (define_insn "iorsi3"
1260   [(set (match_operand:SI 0 "general_operand" "=r,r,o,o,r,r,r,o,o,o")
1261         (ior:SI (match_operand:SI 1 "general_operand" "%0,0,0,0,0,0,0,0,0,0")
1262                   (match_operand:SI 2 "general_operand" "r,o,r,o,I,J,K,I,J,K")))]
1263   ""
1264   "*
1265 { /* Here we trust that operands don't overlap 
1267      or is lateoperands the low word?? - looks like it! */
1269   rtx lateoperands[3];
1270   
1271   lateoperands[0] = operands[0];
1273   if (REG_P (operands[0]))
1274     operands[0] = gen_rtx_REG (HImode, REGNO (operands[0]) + 1);
1275   else
1276     operands[0] = adj_offsettable_operand (operands[0], 2);
1277   
1278   if (! CONSTANT_P(operands[2]))
1279     {
1280       lateoperands[2] = operands[2];
1282       if (REG_P (operands[2]))
1283         operands[2] = gen_rtx_REG (HImode, REGNO (operands[2]) + 1);
1284       else
1285         operands[2] = adj_offsettable_operand (operands[2], 2);
1287       output_asm_insn (\"bis %2, %0\", operands);
1288       output_asm_insn (\"bis %2, %0\", lateoperands);
1289       return \"\";
1290     }
1292   lateoperands[2] = GEN_INT ((INTVAL (operands[2]) >> 16) & 0xffff);
1293   operands[2] = GEN_INT (INTVAL (operands[2]) & 0xffff);
1294   
1295   /* these have different lengths, so we should have 
1296      different constraints! */
1297   if (INTVAL(operands[2]))
1298     output_asm_insn (\"bis %2, %0\", operands);
1300   if (INTVAL(lateoperands[2]))
1301     output_asm_insn (\"bis %2, %0\", lateoperands);
1303   return \"\";
1305   [(set_attr "length" "2,4,4,6,2,2,4,3,3,6")])
1307 (define_insn "iorhi3"
1308   [(set (match_operand:HI 0 "general_operand" "=rR,rR,Q,Q")
1309         (ior:HI (match_operand:HI 1 "general_operand" "%0,0,0,0")
1310                 (match_operand:HI 2 "general_operand" "rR,Qi,rR,Qi")))]
1311   ""
1312   "bis %2, %0"
1313   [(set_attr "length" "1,2,2,3")])
1315 (define_insn "iorqi3"
1316   [(set (match_operand:QI 0 "general_operand" "=rR,rR,Q,Q")
1317         (ior:QI (match_operand:QI 1 "general_operand" "%0,0,0,0")
1318                 (match_operand:QI 2 "general_operand" "rR,Qi,rR,Qi")))]
1319   ""
1320   "bisb %2, %0")
1322 ;;- xor instructions
1323 (define_insn "xorsi3"
1324   [(set (match_operand:SI 0 "register_operand" "=r,r,r,r")
1325         (xor:SI (match_operand:SI 1 "register_operand" "%0,0,0,0")
1326                   (match_operand:SI 2 "arith_operand" "r,I,J,K")))]
1327   "TARGET_40_PLUS"
1328   "*
1329 { /* Here we trust that operands don't overlap */
1331   rtx lateoperands[3];
1333   lateoperands[0] = operands[0];
1334   operands[0] = gen_rtx_REG (HImode, REGNO (operands[0]) + 1);
1336   if (REG_P(operands[2]))
1337     {
1338       lateoperands[2] = operands[2];
1339       operands[2] = gen_rtx_REG (HImode, REGNO (operands[2]) + 1);
1341       output_asm_insn (\"xor %2, %0\", operands);
1342       output_asm_insn (\"xor %2, %0\", lateoperands);
1344       return \"\";
1345     }
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);
1353   if (INTVAL (lateoperands[2]))
1354     output_asm_insn (\"xor %2, %0\", lateoperands);
1356   return \"\";
1358   [(set_attr "length" "2,1,1,2")])
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")])
1368 ;;- one complement instructions
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")])
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")])
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")])
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   "
1401   operands[2] = negate_rtx (HImode, operands[2]);
1404 ;; define asl aslb asr asrb - ashc missing!
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")])
1415 ;; and another possibility for asr is << -1
1416 ;; might cause problems since -1 can also be encoded as 65535!
1417 ;; not in gcc2 ??? 
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")])
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   "! optimize_size"
1436   "*
1438   register int i;
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 \"\";
1448 ;; longest is 4
1449   [(set (attr "length") (const_int 4))])
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;
1461   cnt = INTVAL(operands[2]) & 0x0007;
1463   for (i=0 ; i < cnt ; i++)
1464        output_asm_insn(\"aslb %0\", operands);
1466   return \"\";
1468 ;; set attribute length ( match_dup 2 & 7 ) *(1 or 2) !!!
1469   [(set_attr_alternative "length" 
1470                          [(const_int 7)
1471                           (const_int 14)])])
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")])
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;
1492   cnt = INTVAL(operands[2]) & 0x0007;
1494   for (i=0 ; i < cnt ; i++)
1495        output_asm_insn(\"asrb %0\", operands);
1497   return \"\";
1499   [(set_attr_alternative "length" 
1500                          [(const_int 7)
1501                           (const_int 14)])])
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))))])
1511 ;; can we get +-1 in the next pattern? should 
1512 ;; have been caught by previous patterns!
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   "*
1521   if (GET_CODE(operands[2]) == CONST_INT)
1522     {
1523       if (INTVAL(operands[2]) == 1)
1524         return \"asl %0\";
1525       else if (INTVAL(operands[2]) == -1)
1526         return \"asr %0\";
1527     }
1529   return \"ash %2,%0\";
1531   [(set_attr "length" "1,2")])
1533 ;; Arithmetic right shift on the pdp works by negating the shift count.
1534 (define_expand "ashrhi3"
1535   [(set (match_operand:HI 0 "register_operand" "=r")
1536         (ashift:HI (match_operand:HI 1 "register_operand" "0")
1537                    (match_operand:HI 2 "general_operand" "g")))]
1538   ""
1539   "
1541   operands[2] = negate_rtx (HImode, operands[2]);
1544 ;;;;- logical shift instructions
1545 ;;(define_insn "lshrsi3"
1546 ;;  [(set (match_operand:HI 0 "register_operand" "=r")
1547 ;;      (lshiftrt:HI (match_operand:HI 1 "register_operand" "0")
1548 ;;                   (match_operand:HI 2 "arith_operand" "rI")))]
1549 ;;  ""
1550 ;;  "srl %0,%2")
1552 ;; absolute 
1554 (define_insn "absdf2"
1555   [(set (match_operand:DF 0 "general_operand" "=fR,Q")
1556         (abs:DF (match_operand:DF 1 "general_operand" "0,0")))]
1557   "TARGET_FPU"
1558   "{absd|absf} %0"
1559   [(set_attr "length" "1,2")])
1561 (define_insn "abshi2"
1562   [(set (match_operand:HI 0 "general_operand" "=r,o")
1563         (abs:HI (match_operand:HI 1 "general_operand" "0,0")))]
1564   "TARGET_ABSHI_BUILTIN"
1565   "*
1567   static int count = 0;
1568   char buf[200];
1569         
1570   output_asm_insn(\"tst %0\", operands);
1571   sprintf(buf, \"bge abshi%d\", count);
1572   output_asm_insn(buf, NULL);
1573   output_asm_insn(\"neg %0\", operands);
1574   sprintf(buf, \"\\nabshi%d:\", count++);
1575   output_asm_insn(buf, NULL);
1577   return \"\";
1579   [(set_attr "length" "3,5")])
1582 ;; define expand abshi - is much better !!! - but
1583 ;; will it be optimized into an abshi2 ?
1584 ;; it will leave better code, because the tsthi might be 
1585 ;; optimized away!!
1586 ; -- just a thought - don't have time to check 
1588 ;(define_expand "abshi2"
1589 ;  [(match_operand:HI 0 "general_operand" "")
1590 ;   (match_operand:HI 1 "general_operand" "")]
1591 ;  ""
1592 ;  "
1594 ;  rtx label = gen_label_rtx ();
1596 ;  /* do I need this? */
1597 ;  do_pending_stack_adjust ();
1599 ;  emit_move_insn (operands[0], operands[1]);
1601 ;  emit_insn (gen_tsthi (operands[0]));
1602 ;  emit_insn (gen_bge (label1));
1604 ;  emit_insn (gen_neghi(operands[0], operands[0])
1605 ;  
1606 ;  emit_barrier ();
1608 ;  emit_label (label);
1610 ;  /* allow REG_NOTES to be set on last insn (labels don't have enough
1611 ;     fields, and can't be used for REG_NOTES anyway).  */
1612 ;  emit_insn (gen_rtx_USE (VOIDmode, stack_pointer_rtx));
1613 ;  DONE;
1614 ;}")
1616 ;; negate insns
1618 (define_insn "negdf2"
1619   [(set (match_operand:DF 0 "general_operand" "=fR,Q")
1620         (neg:DF (match_operand:DF 1 "register_operand" "0,0")))]
1621   "TARGET_FPU"
1622   "{negd|negf} %0"
1623   [(set_attr "length" "1,2")])
1625 (define_insn "neghi2"
1626   [(set (match_operand:HI 0 "general_operand" "=rR,Q")
1627         (neg:HI (match_operand:HI 1 "general_operand" "0,0")))]
1628   ""
1629   "neg %0"
1630   [(set_attr "length" "1,2")])
1632 (define_insn "negqi2"
1633   [(set (match_operand:QI 0 "general_operand" "=rR,Q")
1634         (neg:QI (match_operand:QI 1 "general_operand" "0,0")))]
1635   ""
1636   "negb %0"
1637   [(set_attr "length" "1,2")])
1640 ;; Unconditional and other jump instructions
1641 (define_insn "jump"
1642   [(set (pc)
1643         (label_ref (match_operand 0 "" "")))]
1644   ""
1645   "jmp %l0"
1646   [(set_attr "length" "2")])
1648 (define_insn ""
1649   [(set (pc)
1650     (label_ref (match_operand 0 "" "")))
1651    (clobber (const_int 1))]
1652   ""
1653   "jmp %l0"
1654   [(set_attr "length" "2")])
1656 (define_insn "tablejump"
1657   [(set (pc) (match_operand:HI 0 "general_operand" "rR,Q"))
1658    (use (label_ref (match_operand 1 "" "")))]
1659   ""
1660   "jmp %0"
1661   [(set_attr "length" "1,2")])
1663 ;; indirect jump - let's be conservative!
1664 ;; allow only register_operand, even though we could also 
1665 ;; allow labels etc.
1667 (define_insn "indirect_jump"
1668   [(set (pc) (match_operand:HI 0 "register_operand" "r"))]
1669   ""
1670   "jmp (%0)")
1672 ;;- jump to subroutine
1674 (define_insn "call"
1675   [(call (match_operand:HI 0 "general_operand" "R,Q")
1676          (match_operand:HI 1 "general_operand" "g,g"))
1677 ;;   (use (reg:HI 0)) what was that ???
1678   ]
1679   ;;- Don't use operand 1 for most machines.
1680   ""
1681   "jsr pc, %0"
1682   [(set_attr "length" "1,2")])
1684 ;;- jump to subroutine
1685 (define_insn "call_value"
1686   [(set (match_operand 0 "" "")
1687         (call (match_operand:HI 1 "general_operand" "R,Q")
1688               (match_operand:HI 2 "general_operand" "g,g")))
1689 ;;   (use (reg:HI 0)) - what was that ????
1690   ]
1691   ;;- Don't use operand 2 for most machines.
1692   ""
1693   "jsr pc, %1"
1694   [(set_attr "length" "1,2")])
1696 ;;- nop instruction
1697 (define_insn "nop"
1698   [(const_int 0)]
1699   ""
1700   "nop")
1703 ;;- multiply 
1705 (define_insn "muldf3"
1706   [(set (match_operand:DF 0 "register_operand" "=a,a,a")
1707         (mult:DF (match_operand:DF 1 "register_operand" "%0,0,0")
1708                  (match_operand:DF 2 "general_operand" "fR,Q,F")))]
1709   "TARGET_FPU"
1710   "{muld|mulf} %2, %0"
1711   [(set_attr "length" "1,2,5")])
1713 ;; 16 bit result multiply:
1714 ;; currently we multiply only into odd registers, so we don't use two 
1715 ;; registers - but this is a bit inefficient at times. If we define 
1716 ;; a register class for each register, then we can specify properly 
1717 ;; which register need which scratch register ....
1719 (define_insn "mulhi3"
1720   [(set (match_operand:HI 0 "register_operand" "=d,d") ; multiply regs
1721         (mult:HI (match_operand:HI 1 "register_operand" "%0,0")
1722                  (match_operand:HI 2 "general_operand" "rR,Qi")))]
1723   "TARGET_45"
1724   "mul %2, %0"
1725   [(set_attr "length" "1,2")])
1727 ;; 32 bit result
1728 (define_expand "mulhisi3"
1729   [(set (match_dup 3)
1730         (match_operand:HI 1 "general_operand" "g,g"))
1731    (set (match_operand:SI 0 "register_operand" "=r,r") ; even numbered!
1732         (mult:SI (truncate:HI 
1733                   (match_dup 0))
1734                  (match_operand:HI 2 "general_operand" "rR,Qi")))]
1735   "TARGET_45"
1736   "operands[3] = gen_lowpart(HImode, operands[1]);")
1738 (define_insn ""
1739   [(set (match_operand:SI 0 "register_operand" "=r,r") ; even numbered!
1740         (mult:SI (truncate:HI 
1741                   (match_operand:SI 1 "register_operand" "%0,0"))
1742                  (match_operand:HI 2 "general_operand" "rR,Qi")))]
1743   "TARGET_45"
1744   "mul %2, %0"
1745   [(set_attr "length" "1,2")])
1747 ;(define_insn "mulhisi3"
1748 ;  [(set (match_operand:SI 0 "register_operand" "=r,r") ; even numbered!
1749 ;       (mult:SI (truncate:HI 
1750 ;                  (match_operand:SI 1 "register_operand" "%0,0"))
1751 ;                (match_operand:HI 2 "general_operand" "rR,Qi")))]
1752 ;  "TARGET_45"
1753 ;  "mul %2, %0"
1754 ;  [(set_attr "length" "1,2")])
1756 ;;- divide
1757 (define_insn "divdf3"
1758   [(set (match_operand:DF 0 "register_operand" "=a,a,a")
1759         (div:DF (match_operand:DF 1 "register_operand" "0,0,0")
1760                 (match_operand:DF 2 "general_operand" "fR,Q,F")))]
1761   "TARGET_FPU"
1762   "{divd|divf} %2, %0"
1763   [(set_attr "length" "1,2,5")])
1765          
1766 (define_expand "divhi3"
1767   [(set (subreg:HI (match_dup 1) 0)
1768         (div:HI (match_operand:SI 1 "general_operand" "0")
1769                 (match_operand:HI 2 "general_operand" "g")))
1770    (set (match_operand:HI 0 "general_operand" "=r")
1771         (subreg:HI (match_dup 1) 0))]
1772   "TARGET_45"
1773   "")
1775 (define_insn ""
1776   [(set (subreg:HI (match_operand:SI 0 "general_operand" "=r") 0)
1777         (div:HI (match_operand:SI 1 "general_operand" "0")
1778                 (match_operand:HI 2 "general_operand" "g")))]
1779   "TARGET_45"
1780   "div %2,%0"
1781   [(set_attr "length" "2")])
1783 (define_expand "modhi3"
1784   [(set (subreg:HI (match_dup 1) 1)
1785         (mod:HI (match_operand:SI 1 "general_operand" "0")
1786                 (match_operand:HI 2 "general_operand" "g")))
1787    (set (match_operand:HI 0 "general_operand" "=r")
1788         (subreg:HI (match_dup 1) 1))]
1789   "TARGET_45"
1790   "")
1792 (define_insn ""
1793   [(set (subreg:HI (match_operand:SI 0 "general_operand" "=r") 1)
1794         (mod:HI (match_operand:SI 1 "general_operand" "0")
1795                 (match_operand:HI 2 "general_operand" "g")))]
1796   "TARGET_45"
1797   "div %2,%0"
1798   [(set_attr "length" "2")])
1800 ;(define_expand "divmodhi4"
1801 ;  [(parallel [(set (subreg:HI (match_dup 1) 0)
1802 ;                  (div:HI (match_operand:SI 1 "general_operand" "0")
1803 ;                          (match_operand:HI 2 "general_operand" "g")))
1804 ;              (set (subreg:HI (match_dup 1) 1)
1805 ;                  (mod:HI (match_dup 1)
1806 ;                          (match_dup 2)))])
1807 ;   (set (match_operand:HI 3 "general_operand" "=r")
1808 ;        (subreg:HI (match_dup 1) 1))
1809 ;   (set (match_operand:HI 0 "general_operand" "=r")
1810 ;        (subreg:HI (match_dup 1) 0))]
1811 ;  "TARGET_45"
1812 ;  "")
1814 ;(define_insn ""
1815 ;  [(set (subreg:HI (match_operand:SI 0 "general_operand" "=r") 0)
1816 ;                  (div:HI (match_operand:SI 1 "general_operand" "0")
1817 ;                          (match_operand:HI 2 "general_operand" "g")))
1818 ;   (set (subreg:HI (match_dup 0) 1)
1819 ;                  (mod:HI (match_dup 1)
1820 ;                          (match_dup 2)))]
1821 ;  "TARGET_45"
1822 ;  "div %2, %0")
1824    
1825 ;; is rotate doing the right thing to be included here ????