OSDN Git Service

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