OSDN Git Service

Merge in gcc2-ss-010999
[pf3gnuchains/gcc-fork.git] / gcc / config / pdp11 / pdp11.md
1 ;;- Machine description for the pdp11 for GNU C compiler
2 ;; Copyright (C) 1994, 1995, 1997, 1998, 1999 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, 59 Temple Place - Suite 330,
20 ;; Boston, MA 02111-1307, USA.
21
22
23 ;; HI is 16 bit
24 ;; QI is 8 bit 
25
26 ;;- See file "rtl.def" for documentation on define_insn, match_*, et. al.
27
28 ;;- cpp macro #define NOTICE_UPDATE_CC in file tm.h handles condition code
29 ;;- updates for most instructions.
30
31 ;;- Operand classes for the register allocator:
32 \f
33 ;; Compare instructions.
34
35 ;; currently we only support df floats, which saves us quite some
36 ;; hassle switching the FP mode! 
37 ;; we assume that CPU is always in long float mode, and 
38 ;; 16 bit integer mode - currently, the prologue for main does this,
39 ;; but maybe we should just set up a NEW crt0 properly, 
40 ;; -- and what about signal handling code?
41 ;; (we don't even let sf floats in the register file, so
42 ;; we only should have to worry about truncating and widening 
43 ;; when going to memory)
44
45 ;; abort() call by g++ - must define libfunc for cmp_optab
46 ;; and ucmp_optab for mode SImode, because we don't have that!!!
47 ;; - yet since no libfunc is there, we abort ()
48
49 ;; The only thing that remains to be done then is output 
50 ;; the floats in a way the assembler can handle it (and 
51 ;; if you're really into it, use a PDP11 float emulation
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. 
58
59 ;; define attributes
60 ;; currently type is only fpu or arith or unknown, maybe branch later ?
61 ;; default is arith
62 (define_attr "type" "unknown,arith,fp" (const_string "arith"))
63
64 ;; length default is 1 word each
65 (define_attr "length" "" (const_int 1))
66
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")])
73
74 ;; define function units
75
76 ;; arithmetic - values here immediately when next insn issued
77 ;; or does it mean the number of cycles after this insn was issued?
78 ;; how do I say that fpu insns use cpu also? (pre-interaction phase)
79
80 ;(define_function_unit "cpu" 1 1 (eq_attr "type" "arith") 0 0)
81 ;(define_function_unit "fpu" 1 1 (eq_attr "type" "fp") 0 0)
82
83 ;; compare
84 (define_insn "cmpdf"
85   [(set (cc0)
86         (compare (match_operand:DF 0 "general_operand" "fR,Q,F")
87                  (match_operand:DF 1 "register_operand" "a,a,a")))]
88   "TARGET_FPU"
89   "*
90 {
91   cc_status.flags = CC_IN_FPU;
92   return \"{cmpd|cmpf} %0, %1\;cfcc\";
93 }"
94   [(set_attr "length" "2,3,6")])
95
96 ;; a bit of brain damage, maybe inline later - 
97 ;; problem is - gcc seems to NEED SImode because 
98 ;; of the cmp weirdness - maybe change gcc to handle this?
99
100 (define_expand "cmpsi"
101   [(set (reg:SI 0)
102         (match_operand:SI 0 "general_operand" "g"))
103    (set (reg:SI 2)
104         (match_operand:SI 1 "general_operand" "g"))
105    (parallel [(set (cc0)
106                    (compare (reg:SI 0)
107                             (reg:SI 2)))
108               (clobber (reg:SI 0))])]
109   "0" ;; disable for test
110   "")
111
112 ;; check for next insn for branch code - does this still
113 ;; work in gcc 2.* ?
114
115 (define_insn ""
116   [(set (cc0)
117         (compare (reg:SI 0)
118                  (reg:SI 2)))
119    (clobber (reg:SI 0))]
120   ""
121   "*
122 {
123   rtx br_insn = NEXT_INSN (insn);
124   RTX_CODE br_code;
125
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\";
138
139     case GE:
140     case LT:
141     case GT:
142     case LE:
143     case EQ:
144     case NE:
145
146       return \"jsr pc, ___cmpsi\;tst r0\";
147
148     default:
149
150       abort();
151   }
152 }"
153   [(set_attr "length" "4")])
154
155
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")])
163
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                            
172
173 ;; We have to have this because cse can optimize the previous pattern
174 ;; into this one.
175
176 (define_insn "tstdf"
177   [(set (cc0)
178         (match_operand:DF 0 "general_operand" "fR,Q"))]
179   "TARGET_FPU"
180   "*
181 {
182   cc_status.flags = CC_IN_FPU;
183   return \"{tstd|tstf} %0\;cfcc\";
184 }"
185   [(set_attr "length" "2,3")])
186
187
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   "")
196
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")])
204
205
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")])
212
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")])
219
220 ;; sob instruction - we need an assembler which can make this instruction
221 ;; valid under _all_ circumstances!
222
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   "*
236 {
237  static int labelcount = 0;
238  static char buf[1000];
239
240  if (get_attr_length (insn) == 1)
241     return \"sob %0, %l1\";
242
243  /* emulate sob */
244  output_asm_insn (\"dec %0\", operands);
245  
246  sprintf (buf, \"bge LONG_SOB%d\", labelcount);
247  output_asm_insn (buf, NULL);
248
249  output_asm_insn (\"jmp %l1\", operands);
250  
251  sprintf (buf, \"LONG_SOB%d:\", labelcount++);
252  output_asm_insn (buf, NULL);
253
254  return \"\";
255 }"
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)))])
264
265 ;; These control RTL generation for conditional jump insns
266 ;; and match them for register allocation.
267
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!
271
272 ;; these must be changed to check for CC_IN_FCCR if float is to be 
273 ;; enabled
274
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)))])
291
292
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)))])
309
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)))])
326
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)))])
343
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)))])
360
361
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)))])
378
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)))])
395
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)))])
412
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)))])
429
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)))])
446
447 \f
448 ;; These match inverted jump insns for register allocation.
449
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)))])
466
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)))])
483
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)))])
500
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)))])
517
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)))])
534
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)))])
551
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)))])
568
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)))])
585
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)))])
602
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)))])
619 \f
620 ;; Move instructions
621
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")])
629
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")])
638
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   "*
644 {
645   if (operands[1] == const0_rtx)
646     return \"clr %0\";
647
648   return \"mov %1, %0\";
649 }"
650   [(set_attr "length" "1,2,2,3")])
651
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   "*
657 {
658   if (operands[1] == const0_rtx)
659     return \"clrb %0\";
660
661   return \"movb %1, %0\";
662 }"
663   [(set_attr "length" "1,2,2,3")])
664
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")])
674
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")])
681
682 ;; maybe fiddle a bit with move_ratio, then 
683 ;; let constraints only accept a register ...
684
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   "
696 {
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)));
703
704   operands[5] = XEXP (operands[0], 0);
705   operands[6] = XEXP (operands[1], 0);
706 }")
707
708
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    
723
724 \f
725 ;;- truncation instructions
726
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")])
745
746
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   "")
754
755 \f
756 ;;- zero extension instructions
757
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]); */")
776
777 \f
778 ;;- sign extension instructions
779
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")])
789
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")])
797
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   "*
803 {
804   rtx latehalf[2];
805
806   /* make register pair available */
807   latehalf[0] = operands[0];
808   operands[0] = gen_rtx_REG (HImode, REGNO (operands[0])+ 1);
809
810   output_asm_insn(\"movb %1, %0\", operands);
811   output_asm_insn(\"sxt %0\", latehalf);
812     
813   return \"\";
814 }"
815   [(set_attr "length" "2,3")])
816
817 ;; maybe we have to use define_expand to say that we have the instruction,
818 ;; unconditionally, and then match dependent on CPU type:
819
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   "*
831 {
832   rtx latehalf[2];
833
834   /* we don't want to mess with auto increment */
835   
836   switch(which_alternative)
837   {
838     case 0:
839
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);
845
846       return \"\";
847
848     case 1:
849
850       /* - auto-decrement - right direction ;-) */
851       output_asm_insn(\"mov %1, %0\", operands);
852       output_asm_insn(\"sxt %0\", operands);
853
854       return \"\";
855
856     case 2:
857
858       /* make register pair available */
859       latehalf[0] = operands[0];
860       operands[0] = gen_rtx_REG (HImode, REGNO (operands[0]) + 1);
861
862       output_asm_insn(\"mov %1, %0\", operands);
863       output_asm_insn(\"sxt %0\", latehalf);
864
865       return \"\";
866
867     default:
868
869       abort();
870   }
871 }"
872   [(set_attr "length" "5,3,3")])
873
874
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   "*
880 {
881   static int count = 0;
882   char buf[100];
883   rtx lateoperands[2];
884
885   lateoperands[0] = operands[0];
886   operands[0] = gen_rtx_REG (HImode, REGNO (operands[0]) + 1);
887
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);
899
900   count += 2;
901
902   return \"\";
903 }"
904   [(set_attr "length" "6")])
905
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 ?
911
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];
919
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")])
936
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")])
965
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")])
972
973 \f
974 ;;- arithmetic instructions
975 ;;- add instructions
976
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")])
984
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 
992
993      or is lateoperands the low word?? - looks like it! */
994
995   unsigned int i;
996   rtx lateoperands[3];
997   
998   lateoperands[0] = operands[0];
999
1000   if (REG_P (operands[0]))
1001     operands[0] = gen_rtx_REG (HImode, REGNO (operands[0]) + 1);
1002   else
1003     operands[0] = adj_offsettable_operand (operands[0], 2);
1004   
1005   if (! CONSTANT_P(operands[2]))
1006   {
1007     lateoperands[2] = operands[2];
1008
1009     if (REG_P (operands[2]))
1010       operands[2] = gen_rtx_REG (HImode, REGNO (operands[2]) + 1);
1011     else
1012       operands[2] = adj_offsettable_operand(operands[2], 2);
1013
1014     output_asm_insn (\"add %2, %0\", operands);
1015     output_asm_insn (\"adc %0\", lateoperands);
1016     output_asm_insn (\"add %2, %0\", lateoperands);
1017     return \"\";
1018   }
1019
1020   lateoperands[2] = GEN_INT (INTVAL (operands[2]) >> 16) & 0xffff);
1021   operands[2] = GEN_INT (INTVAL (operands[2]) & 0xffff);
1022   
1023   if (INTVAL(operands[2]))
1024   { 
1025     output_asm_insn (\"add %2, %0\", operands);
1026     output_asm_insn (\"adc %0\", lateoperands);
1027   }
1028
1029   if (INTVAL(lateoperands[2]))
1030     output_asm_insn (\"add %2, %0\", lateoperands);
1031
1032   return \"\";
1033 }"
1034   [(set_attr "length" "3,5,6,8,3,1,5,5,3,8")])
1035
1036 (define_insn "addhi3"
1037   [(set (match_operand:HI 0 "general_operand" "=rR,rR,Q,Q")
1038         (plus:HI (match_operand:HI 1 "general_operand" "%0,0,0,0")
1039                  (match_operand:HI 2 "general_operand" "rRLM,Qi,rRLM,Qi")))]
1040   ""
1041   "*
1042 {
1043   if (GET_CODE (operands[2]) == CONST_INT)
1044     {
1045       if (INTVAL(operands[2]) == 1)
1046         return \"inc %0\";
1047       else if (INTVAL(operands[2]) == -1)
1048         return \"dec %0\";
1049     }
1050
1051   return \"add %2, %0\";
1052 }"
1053   [(set_attr "length" "1,2,2,3")])
1054
1055 (define_insn "addqi3"
1056   [(set (match_operand:QI 0 "general_operand" "=rR,rR,Q,Q")
1057         (plus:QI (match_operand:QI 1 "general_operand" "%0,0,0,0")
1058                  (match_operand:QI 2 "general_operand" "rRLM,Qi,rRLM,Qi")))]
1059   ""
1060   "*
1061 {
1062   if (GET_CODE (operands[2]) == CONST_INT)
1063     {
1064       if (INTVAL(operands[2]) == 1)
1065         return \"incb %0\";
1066       else if (INTVAL(operands[2]) == -1)
1067         return \"decb %0\";
1068     }
1069
1070   return \"addb %2, %0\";
1071 }"
1072   [(set_attr "length" "1,2,2,3")])
1073
1074 \f
1075 ;;- subtract instructions
1076 ;; we don't have to care for constant second 
1077 ;; args, since they are canonical plus:xx now!
1078 ;; also for minus:DF ??
1079
1080 (define_insn "subdf3"
1081   [(set (match_operand:DF 0 "register_operand" "=a,a")
1082         (minus:DF (match_operand:DF 1 "register_operand" "0,0")
1083                   (match_operand:DF 2 "general_operand" "fR,Q")))]
1084   "TARGET_FPU"
1085   "{subd|subf} %2, %0"
1086   [(set_attr "length" "1,2")])
1087
1088 (define_insn "subsi3"
1089   [(set (match_operand:SI 0 "general_operand" "=r,r,o,o")
1090         (minus:SI (match_operand:SI 1 "general_operand" "0,0,0,0")
1091                   (match_operand:SI 2 "general_operand" "r,o,r,o")))]
1092   ""
1093   "*
1094 { /* Here we trust that operands don't overlap 
1095
1096      or is lateoperands the low word?? - looks like it! */
1097
1098   unsigned int i;
1099   rtx lateoperands[3];
1100   
1101   lateoperands[0] = operands[0];
1102
1103   if (REG_P (operands[0]))
1104     operands[0] = gen_rtx_REG (HImode, REGNO (operands[0]) + 1);
1105   else
1106     operands[0] = adj_offsettable_operand (operands[0], 2);
1107   
1108   lateoperands[2] = operands[2];
1109
1110   if (REG_P (operands[2]))
1111     operands[2] = gen_rtx_REG (HImode, REGNO (operands[2]) + 1);
1112   else
1113     operands[2] = adj_offsettable_operand(operands[2], 2);
1114
1115   output_asm_insn (\"sub %2, %0\", operands);
1116   output_asm_insn (\"sbc %0\", lateoperands);
1117   output_asm_insn (\"sub %2, %0\", lateoperands);
1118   return \"\";
1119 }"
1120 ;; offsettable memory addresses always are expensive!!!
1121   [(set_attr "length" "3,5,6,8")])
1122
1123 (define_insn "subhi3"
1124   [(set (match_operand:HI 0 "general_operand" "=rR,rR,Q,Q")
1125         (minus:HI (match_operand:HI 1 "general_operand" "0,0,0,0")
1126                   (match_operand:HI 2 "general_operand" "rR,Qi,rR,Qi")))]
1127   ""
1128   "*
1129 {
1130   if (GET_CODE (operands[2]) == CONST_INT)
1131     abort();
1132
1133   return \"sub %2, %0\";
1134 }"
1135   [(set_attr "length" "1,2,2,3")])
1136
1137 (define_insn "subqi3"
1138   [(set (match_operand:QI 0 "general_operand" "=rR,rR,Q,Q")
1139         (minus:QI (match_operand:QI 1 "general_operand" "0,0,0,0")
1140                   (match_operand:QI 2 "general_operand" "rR,Qi,rR,Qi")))]
1141   ""
1142   "*
1143 {
1144   if (GET_CODE (operands[2]) == CONST_INT)
1145     abort();
1146
1147   return \"subb %2, %0\";
1148 }"
1149   [(set_attr "length" "1,2,2,3")])
1150
1151 ;;;;- and instructions
1152 ;; Bit-and on the pdp (like on the vax) is done with a clear-bits insn.
1153 (define_expand "andsi3"
1154   [(set (match_operand:SI 0 "general_operand" "=g")
1155         (and:SI (match_operand:SI 1 "general_operand" "0")
1156                 (not:SI (match_operand:SI 2 "general_operand" "g"))))]
1157   ""
1158   "
1159 {
1160   extern rtx expand_unop ();
1161   if (GET_CODE (operands[2]) == CONST_INT)
1162     operands[2] = GEN_INT (~INTVAL (operands[2]));
1163   else
1164     operands[2] = expand_unop (SImode, one_cmpl_optab, operands[2], 0, 1);
1165 }")
1166
1167 (define_expand "andhi3"
1168   [(set (match_operand:HI 0 "general_operand" "=g")
1169         (and:HI (match_operand:HI 1 "general_operand" "0")
1170                 (not:HI (match_operand:HI 2 "general_operand" "g"))))]
1171   ""
1172   "
1173 {
1174   extern rtx expand_unop ();
1175   if (GET_CODE (operands[2]) == CONST_INT)
1176     operands[2] = GEN_INT (~INTVAL (operands[2]));
1177   else
1178     operands[2] = expand_unop (HImode, one_cmpl_optab, operands[2], 0, 1);
1179 }")
1180
1181 (define_expand "andqi3"
1182   [(set (match_operand:QI 0 "general_operand" "=g")
1183         (and:QI (match_operand:QI 1 "general_operand" "0")
1184                 (not:QI (match_operand:QI 2 "general_operand" "g"))))]
1185   ""
1186   "
1187 {
1188   extern rtx expand_unop ();
1189   rtx op = operands[2];
1190   if (GET_CODE (op) == CONST_INT)
1191     operands[2] = GEN_INT (((1 << 8) - 1) & ~INTVAL (op));
1192   else
1193     operands[2] = expand_unop (QImode, one_cmpl_optab, op, 0, 1);
1194 }")
1195
1196 (define_insn "andcbsi3"
1197   [(set (match_operand:SI 0 "general_operand" "=r,r,o,o,r,r,r,o,o,o")
1198         (and:SI (match_operand:SI 1 "general_operand" "%0,0,0,0,0,0,0,0,0,0")
1199                 (not:SI (match_operand:SI 2 "general_operand" "r,o,r,o,I,J,K,I,J,K"))))]
1200   ""
1201   "*
1202 { /* Here we trust that operands don't overlap 
1203
1204      or is lateoperands the low word?? - looks like it! */
1205
1206   unsigned int i;
1207   rtx lateoperands[3];
1208   
1209   lateoperands[0] = operands[0];
1210
1211   if (REG_P (operands[0]))
1212     operands[0] = gen_rtx_REG (HImode, REGNO (operands[0]) + 1);
1213   else
1214     operands[0] = adj_offsettable_operand (operands[0], 2);
1215   
1216   if (! CONSTANT_P(operands[2]))
1217   {
1218     lateoperands[2] = operands[2];
1219
1220     if (REG_P (operands[2]))
1221       operands[2] = gen_rtx_REG (HImode, REGNO (operands[2]) + 1);
1222     else
1223       operands[2] = adj_offsettable_operand(operands[2], 2);
1224
1225     output_asm_insn (\"bic %2, %0\", operands);
1226     output_asm_insn (\"bic %2, %0\", lateoperands);
1227     return \"\";
1228   }
1229
1230   lateoperands[2] = GEN_INT ((INTVAL (operands[2]) >> 16) & 0xffff);
1231   operands[2] = GEN_INT (INTVAL (operands[2]) & 0xffff);
1232   
1233   /* these have different lengths, so we should have 
1234      different constraints! */
1235   if (INTVAL(operands[2]))
1236     output_asm_insn (\"bic %2, %0\", operands);
1237
1238   if (INTVAL(lateoperands[2]))
1239     output_asm_insn (\"bic %2, %0\", lateoperands);
1240
1241   return \"\";
1242 }"
1243   [(set_attr "length" "2,4,4,6,2,2,4,3,3,6")])
1244
1245 (define_insn "andcbhi3"
1246   [(set (match_operand:HI 0 "general_operand" "=rR,rR,Q,Q")
1247         (and:HI (match_operand:HI 1 "general_operand" "0,0,0,0")
1248                 (not:HI (match_operand:HI 2 "general_operand" "rR,Qi,rR,Qi"))))]
1249   ""
1250   "bic %2, %0"
1251   [(set_attr "length" "1,2,2,3")])
1252
1253 (define_insn "andcbqi3"
1254   [(set (match_operand:QI 0 "general_operand" "=rR,rR,Q,Q")
1255         (and:QI (match_operand:QI 1 "general_operand" "0,0,0,0")
1256                 (not:QI (match_operand:QI 2 "general_operand" "rR,Qi,rR,Qi"))))]
1257   ""
1258   "bicb %2, %0"
1259   [(set_attr "length" "1,2,2,3")])
1260
1261 ;;- Bit set (inclusive or) instructions
1262 (define_insn "iorsi3"
1263   [(set (match_operand:SI 0 "general_operand" "=r,r,o,o,r,r,r,o,o,o")
1264         (ior:SI (match_operand:SI 1 "general_operand" "%0,0,0,0,0,0,0,0,0,0")
1265                   (match_operand:SI 2 "general_operand" "r,o,r,o,I,J,K,I,J,K")))]
1266   ""
1267   "*
1268 { /* Here we trust that operands don't overlap 
1269
1270      or is lateoperands the low word?? - looks like it! */
1271
1272   unsigned int i;
1273   rtx lateoperands[3];
1274   
1275   lateoperands[0] = operands[0];
1276
1277   if (REG_P (operands[0]))
1278     operands[0] = gen_rtx_REG (HImode, REGNO (operands[0]) + 1);
1279   else
1280     operands[0] = adj_offsettable_operand (operands[0], 2);
1281   
1282   if (! CONSTANT_P(operands[2]))
1283     {
1284       lateoperands[2] = operands[2];
1285
1286       if (REG_P (operands[2]))
1287         operands[2] = gen_rtx_REG (HImode, REGNO (operands[2]) + 1);
1288       else
1289         operands[2] = adj_offsettable_operand (operands[2], 2);
1290
1291       output_asm_insn (\"bis %2, %0\", operands);
1292       output_asm_insn (\"bis %2, %0\", lateoperands);
1293       return \"\";
1294     }
1295
1296   lateoperands[2] = GEN_INT ((INTVAL (operands[2]) >> 16) & 0xffff);
1297   operands[2] = GEN_INT (INTVAL (operands[2]) & 0xffff);
1298   
1299   /* these have different lengths, so we should have 
1300      different constraints! */
1301   if (INTVAL(operands[2]))
1302     output_asm_insn (\"bis %2, %0\", operands);
1303
1304   if (INTVAL(lateoperands[2]))
1305     output_asm_insn (\"bis %2, %0\", lateoperands);
1306
1307   return \"\";
1308 }"
1309   [(set_attr "length" "2,4,4,6,2,2,4,3,3,6")])
1310
1311 (define_insn "iorhi3"
1312   [(set (match_operand:HI 0 "general_operand" "=rR,rR,Q,Q")
1313         (ior:HI (match_operand:HI 1 "general_operand" "%0,0,0,0")
1314                 (match_operand:HI 2 "general_operand" "rR,Qi,rR,Qi")))]
1315   ""
1316   "bis %2, %0"
1317   [(set_attr "length" "1,2,2,3")])
1318
1319 (define_insn "iorqi3"
1320   [(set (match_operand:QI 0 "general_operand" "=rR,rR,Q,Q")
1321         (ior:QI (match_operand:QI 1 "general_operand" "%0,0,0,0")
1322                 (match_operand:QI 2 "general_operand" "rR,Qi,rR,Qi")))]
1323   ""
1324   "bisb %2, %0")
1325
1326 ;;- xor instructions
1327 (define_insn "xorsi3"
1328   [(set (match_operand:SI 0 "register_operand" "=r,r,r,r")
1329         (xor:SI (match_operand:SI 1 "register_operand" "%0,0,0,0")
1330                   (match_operand:SI 2 "arith_operand" "r,I,J,K")))]
1331   "TARGET_40_PLUS"
1332   "*
1333 { /* Here we trust that operands don't overlap */
1334
1335   unsigned int i;
1336   rtx lateoperands[3];
1337
1338   lateoperands[0] = operands[0];
1339   operands[0] = gen_rtx_REG (HImode, REGNO (operands[0]) + 1);
1340
1341   if (REG_P(operands[2]))
1342     {
1343       lateoperands[2] = operands[2];
1344       operands[2] = gen_rtx_REG (HImode, REGNO (operands[2]) + 1);
1345
1346       output_asm_insn (\"xor %2, %0\", operands);
1347       output_asm_insn (\"xor %2, %0\", lateoperands);
1348
1349       return \"\";
1350     }
1351
1352   lateoperands[2] = GEN_INT ((INTVAL (operands[2]) >> 16) & 0xffff);
1353   operands[2] = GEN_INT (INTVAL(operands[2]) & 0xffff);
1354   
1355   if (INTVAL (operands[2]))
1356     output_asm_insn (\"xor %2, %0\", operands);
1357
1358   if (INTVAL (lateoperands[2]))
1359     output_asm_insn (\"xor %2, %0\", lateoperands);
1360
1361   return \"\";
1362 }"
1363   [(set_attr "length" "2,1,1,2")])
1364
1365 (define_insn "xorhi3"
1366   [(set (match_operand:HI 0 "general_operand" "=rR,Q")
1367         (xor:HI (match_operand:HI 1 "general_operand" "%0,0")
1368                 (match_operand:HI 2 "register_operand" "r,r")))]
1369   "TARGET_40_PLUS"
1370   "xor %2, %0"
1371   [(set_attr "length" "1,2")])
1372
1373 ;;- one complement instructions
1374
1375 (define_insn "one_cmplhi2"
1376   [(set (match_operand:HI 0 "general_operand" "=rR,Q")
1377         (not:HI (match_operand:HI 1 "general_operand" "0,0")))]
1378   ""
1379   "com %0"
1380   [(set_attr "length" "1,2")])
1381
1382 (define_insn "one_cmplqi2"
1383   [(set (match_operand:QI 0 "general_operand" "=rR,Q")
1384         (not:QI (match_operand:QI 1 "general_operand" "0,0")))]
1385   ""
1386   "comb %0"
1387   [(set_attr "length" "1,2")])
1388
1389 ;;- arithmetic shift instructions
1390 (define_insn "ashlsi3"
1391   [(set (match_operand:SI 0 "register_operand" "=r,r")
1392         (ashift:SI (match_operand:SI 1 "register_operand" "0,0")
1393                    (match_operand:HI 2 "general_operand" "rR,Qi")))]
1394   "TARGET_45"
1395   "ashc %2,%0"
1396   [(set_attr "length" "1,2")])
1397
1398 ;; Arithmetic right shift on the pdp works by negating the shift count.
1399 (define_expand "ashrsi3"
1400   [(set (match_operand:SI 0 "register_operand" "=r")
1401         (ashift:SI (match_operand:SI 1 "register_operand" "0")
1402                    (match_operand:HI 2 "general_operand" "g")))]
1403   ""
1404   "
1405 {
1406   operands[2] = negate_rtx (HImode, operands[2]);
1407 }")
1408
1409 ;; define asl aslb asr asrb - ashc missing!
1410
1411 ;; asl 
1412 (define_insn "" 
1413   [(set (match_operand:HI 0 "general_operand" "=rR,Q")
1414         (ashift:HI (match_operand:HI 1 "general_operand" "0,0")
1415                    (const_int 1)))]
1416   ""
1417   "asl %0"
1418   [(set_attr "length" "1,2")])
1419
1420 ;; and another possibility for asr is << -1
1421 ;; might cause problems since -1 can also be encoded as 65535!
1422 ;; not in gcc2 ??? 
1423
1424 ;; asr
1425 (define_insn "" 
1426   [(set (match_operand:HI 0 "general_operand" "=rR,Q")
1427         (ashift:HI (match_operand:HI 1 "general_operand" "0,0")
1428                    (const_int -1)))]
1429   ""
1430   "asr %0"
1431   [(set_attr "length" "1,2")])
1432
1433 ;; shift is by arbitrary count is expensive, 
1434 ;; shift by one cheap - so let's do that, if
1435 ;; space doesn't matter
1436 (define_insn "" 
1437   [(set (match_operand:HI 0 "general_operand" "=r")
1438         (ashift:HI (match_operand:HI 1 "general_operand" "0")
1439                    (match_operand:HI 2 "expand_shift_operand" "O")))]
1440   "! optimize_size"
1441   "*
1442 {
1443   register int i;
1444
1445   for (i = 1; i <= abs(INTVAL(operands[2])); i++)
1446     if (INTVAL(operands[2]) < 0)
1447       output_asm_insn(\"asr %0\", operands);
1448     else
1449       output_asm_insn(\"asl %0\", operands);
1450       
1451   return \"\";
1452 }"
1453 ;; longest is 4
1454   [(set (attr "length") (const_int 4))])
1455
1456 ;; aslb
1457 (define_insn "" 
1458   [(set (match_operand:QI 0 "general_operand" "=r,o")
1459         (ashift:QI (match_operand:QI 1 "general_operand" "0,0")
1460                    (match_operand:HI 2 "const_immediate_operand" "n,n")))]
1461   ""
1462   "*
1463 { /* allowing predec or post_inc is possible, but hairy! */
1464   int i, cnt;
1465
1466   cnt = INTVAL(operands[2]) & 0x0007;
1467
1468   for (i=0 ; i < cnt ; i++)
1469        output_asm_insn(\"aslb %0\", operands);
1470
1471   return \"\";
1472 }"
1473 ;; set attribute length ( match_dup 2 & 7 ) *(1 or 2) !!!
1474   [(set_attr_alternative "length" 
1475                          [(const_int 7)
1476                           (const_int 14)])])
1477
1478 ;;; asr 
1479 ;(define_insn "" 
1480 ;  [(set (match_operand:HI 0 "general_operand" "=rR,Q")
1481 ;       (ashiftrt:HI (match_operand:HI 1 "general_operand" "0,0")
1482 ;                    (const_int 1)))]
1483 ;  ""
1484 ;  "asr %0"
1485 ;  [(set_attr "length" "1,2")])
1486
1487 ;; asrb
1488 (define_insn "" 
1489   [(set (match_operand:QI 0 "general_operand" "=r,o")
1490         (ashiftrt:QI (match_operand:QI 1 "general_operand" "0,0")
1491                      (match_operand:HI 2 "const_immediate_operand" "n,n")))]
1492   ""
1493   "*
1494 { /* allowing predec or post_inc is possible, but hairy! */
1495   int i, cnt;
1496
1497   cnt = INTVAL(operands[2]) & 0x0007;
1498
1499   for (i=0 ; i < cnt ; i++)
1500        output_asm_insn(\"asrb %0\", operands);
1501
1502   return \"\";
1503 }"
1504   [(set_attr_alternative "length" 
1505                          [(const_int 7)
1506                           (const_int 14)])])
1507
1508 ;; the following is invalid - too complex!!! - just say 14 !!!
1509 ;  [(set (attr "length") (plus (and (match_dup 2)
1510 ;                                   (const_int 7))
1511 ;                              (and (match_dup 2)
1512 ;                                   (const_int 7))))])
1513
1514
1515
1516 ;; can we get +-1 in the next pattern? should 
1517 ;; have been caught by previous patterns!
1518
1519 (define_insn "ashlhi3"
1520   [(set (match_operand:HI 0 "register_operand" "=r,r")
1521         (ashift:HI (match_operand:HI 1 "register_operand" "0,0")
1522                    (match_operand:HI 2 "general_operand" "rR,Qi")))]
1523   ""
1524   "*
1525 {
1526   if (GET_CODE(operands[2]) == CONST_INT)
1527     {
1528       if (INTVAL(operands[2]) == 1)
1529         return \"asl %0\";
1530       else if (INTVAL(operands[2]) == -1)
1531         return \"asr %0\";
1532     }
1533
1534   return \"ash %2,%0\";
1535 }"
1536   [(set_attr "length" "1,2")])
1537
1538 ;; Arithmetic right shift on the pdp works by negating the shift count.
1539 (define_expand "ashrhi3"
1540   [(set (match_operand:HI 0 "register_operand" "=r")
1541         (ashift:HI (match_operand:HI 1 "register_operand" "0")
1542                    (match_operand:HI 2 "general_operand" "g")))]
1543   ""
1544   "
1545 {
1546   operands[2] = negate_rtx (HImode, operands[2]);
1547 }")
1548
1549 ;;;;- logical shift instructions
1550 ;;(define_insn "lshrsi3"
1551 ;;  [(set (match_operand:HI 0 "register_operand" "=r")
1552 ;;      (lshiftrt:HI (match_operand:HI 1 "register_operand" "0")
1553 ;;                   (match_operand:HI 2 "arith_operand" "rI")))]
1554 ;;  ""
1555 ;;  "srl %0,%2")
1556
1557 ;; absolute 
1558
1559 (define_insn "absdf2"
1560   [(set (match_operand:DF 0 "general_operand" "=fR,Q")
1561         (abs:DF (match_operand:DF 1 "general_operand" "0,0")))]
1562   "TARGET_FPU"
1563   "{absd|absf} %0"
1564   [(set_attr "length" "1,2")])
1565
1566 (define_insn "abshi2"
1567   [(set (match_operand:HI 0 "general_operand" "=r,o")
1568         (abs:HI (match_operand:HI 1 "general_operand" "0,0")))]
1569   "TARGET_ABSHI_BUILTIN"
1570   "*
1571 {
1572   static int count = 0;
1573   char buf[200];
1574         
1575   output_asm_insn(\"tst %0\", operands);
1576   sprintf(buf, \"bge abshi%d\", count);
1577   output_asm_insn(buf, NULL);
1578   output_asm_insn(\"neg %0\", operands);
1579   sprintf(buf, \"\\nabshi%d:\", count++);
1580   output_asm_insn(buf, NULL);
1581
1582   return \"\";
1583 }"
1584   [(set_attr "length" "3,5")])
1585
1586
1587 ;; define expand abshi - is much better !!! - but
1588 ;; will it be optimized into an abshi2 ?
1589 ;; it will leave better code, because the tsthi might be 
1590 ;; optimized away!!
1591 ; -- just a thought - don't have time to check 
1592 ;
1593 ;(define_expand "abshi2"
1594 ;  [(match_operand:HI 0 "general_operand" "")
1595 ;   (match_operand:HI 1 "general_operand" "")]
1596 ;  ""
1597 ;  "
1598 ;{
1599 ;  rtx label = gen_label_rtx ();
1600 ;
1601 ;  /* do I need this? */
1602 ;  do_pending_stack_adjust ();
1603 ;
1604 ;  emit_move_insn (operands[0], operands[1]);
1605 ;
1606 ;  emit_insn (gen_tsthi (operands[0]));
1607 ;  emit_insn (gen_bge (label1));
1608 ;
1609 ;  emit_insn (gen_neghi(operands[0], operands[0])
1610 ;  
1611 ;  emit_barrier ();
1612 ;
1613 ;  emit_label (label);
1614 ;
1615 ;  /* allow REG_NOTES to be set on last insn (labels don't have enough
1616 ;     fields, and can't be used for REG_NOTES anyway).  */
1617 ;  emit_insn (gen_rtx_USE (VOIDmode, stack_pointer_rtx));
1618 ;  DONE;
1619 ;}")
1620
1621 ;; negate insns
1622
1623 (define_insn "negdf2"
1624   [(set (match_operand:DF 0 "general_operand" "=fR,Q")
1625         (neg:DF (match_operand:DF 1 "register_operand" "0,0")))]
1626   "TARGET_FPU"
1627   "{negd|negf} %0"
1628   [(set_attr "length" "1,2")])
1629
1630 (define_insn "neghi2"
1631   [(set (match_operand:HI 0 "general_operand" "=rR,Q")
1632         (neg:HI (match_operand:HI 1 "general_operand" "0,0")))]
1633   ""
1634   "neg %0"
1635   [(set_attr "length" "1,2")])
1636
1637 (define_insn "negqi2"
1638   [(set (match_operand:QI 0 "general_operand" "=rR,Q")
1639         (neg:QI (match_operand:QI 1 "general_operand" "0,0")))]
1640   ""
1641   "negb %0"
1642   [(set_attr "length" "1,2")])
1643
1644
1645 ;; Unconditional and other jump instructions
1646 (define_insn "jump"
1647   [(set (pc)
1648         (label_ref (match_operand 0 "" "")))]
1649   ""
1650   "jmp %l0"
1651   [(set_attr "length" "2")])
1652
1653 (define_insn ""
1654   [(set (pc)
1655     (label_ref (match_operand 0 "" "")))
1656    (clobber (const_int 1))]
1657   ""
1658   "jmp %l0"
1659   [(set_attr "length" "2")])
1660
1661 (define_insn "tablejump"
1662   [(set (pc) (match_operand:HI 0 "general_operand" "rR,Q"))
1663    (use (label_ref (match_operand 1 "" "")))]
1664   ""
1665   "jmp %0"
1666   [(set_attr "length" "1,2")])
1667
1668 ;; indirect jump - let's be conservative!
1669 ;; allow only register_operand, even though we could also 
1670 ;; allow labels etc.
1671
1672 (define_insn "indirect_jump"
1673   [(set (pc) (match_operand:HI 0 "register_operand" "r"))]
1674   ""
1675   "jmp (%0)")
1676
1677 ;;- jump to subroutine
1678
1679 (define_insn "call"
1680   [(call (match_operand:HI 0 "general_operand" "R,Q")
1681          (match_operand:HI 1 "general_operand" "g,g"))
1682 ;;   (use (reg:HI 0)) what was that ???
1683   ]
1684   ;;- Don't use operand 1 for most machines.
1685   ""
1686   "jsr pc, %0"
1687   [(set_attr "length" "1,2")])
1688
1689 ;;- jump to subroutine
1690 (define_insn "call_value"
1691   [(set (match_operand 0 "" "")
1692         (call (match_operand:HI 1 "general_operand" "R,Q")
1693               (match_operand:HI 2 "general_operand" "g,g")))
1694 ;;   (use (reg:HI 0)) - what was that ????
1695   ]
1696   ;;- Don't use operand 2 for most machines.
1697   ""
1698   "jsr pc, %1"
1699   [(set_attr "length" "1,2")])
1700
1701 ;;- nop instruction
1702 (define_insn "nop"
1703   [(const_int 0)]
1704   ""
1705   "nop")
1706 \f
1707
1708 ;;- multiply 
1709
1710 (define_insn "muldf3"
1711   [(set (match_operand:DF 0 "register_operand" "=a,a,a")
1712         (mult:DF (match_operand:DF 1 "register_operand" "%0,0,0")
1713                  (match_operand:DF 2 "general_operand" "fR,Q,F")))]
1714   "TARGET_FPU"
1715   "{muld|mulf} %2, %0"
1716   [(set_attr "length" "1,2,5")])
1717
1718 ;; 16 bit result multiply:
1719 ;; currently we multiply only into odd registers, so we don't use two 
1720 ;; registers - but this is a bit inefficient at times. If we define 
1721 ;; a register class for each register, then we can specify properly 
1722 ;; which register need which scratch register ....
1723
1724 (define_insn "mulhi3"
1725   [(set (match_operand:HI 0 "register_operand" "=d,d") ; multiply regs
1726         (mult:HI (match_operand:HI 1 "register_operand" "%0,0")
1727                  (match_operand:HI 2 "general_operand" "rR,Qi")))]
1728   "TARGET_45"
1729   "mul %2, %0"
1730   [(set_attr "length" "1,2")])
1731
1732 ;; 32 bit result
1733 (define_expand "mulhisi3"
1734   [(set (match_dup 3)
1735         (match_operand:HI 1 "general_operand" "g,g"))
1736    (set (match_operand:SI 0 "register_operand" "=r,r") ; even numbered!
1737         (mult:SI (truncate:HI 
1738                   (match_dup 0))
1739                  (match_operand:HI 2 "general_operand" "rR,Qi")))]
1740   "TARGET_45"
1741   "operands[3] = gen_lowpart(HImode, operands[1]);")
1742
1743 (define_insn ""
1744   [(set (match_operand:SI 0 "register_operand" "=r,r") ; even numbered!
1745         (mult:SI (truncate:HI 
1746                   (match_operand:SI 1 "register_operand" "%0,0"))
1747                  (match_operand:HI 2 "general_operand" "rR,Qi")))]
1748   "TARGET_45"
1749   "mul %2, %0"
1750   [(set_attr "length" "1,2")])
1751
1752 ;(define_insn "mulhisi3"
1753 ;  [(set (match_operand:SI 0 "register_operand" "=r,r") ; even numbered!
1754 ;       (mult:SI (truncate:HI 
1755 ;                  (match_operand:SI 1 "register_operand" "%0,0"))
1756 ;                (match_operand:HI 2 "general_operand" "rR,Qi")))]
1757 ;  "TARGET_45"
1758 ;  "mul %2, %0"
1759 ;  [(set_attr "length" "1,2")])
1760
1761 ;;- divide
1762 (define_insn "divdf3"
1763   [(set (match_operand:DF 0 "register_operand" "=a,a,a")
1764         (div:DF (match_operand:DF 1 "register_operand" "0,0,0")
1765                 (match_operand:DF 2 "general_operand" "fR,Q,F")))]
1766   "TARGET_FPU"
1767   "{divd|divf} %2, %0"
1768   [(set_attr "length" "1,2,5")])
1769
1770          
1771 (define_expand "divhi3"
1772   [(set (subreg:HI (match_dup 1) 0)
1773         (div:HI (match_operand:SI 1 "general_operand" "0")
1774                 (match_operand:HI 2 "general_operand" "g")))
1775    (set (match_operand:HI 0 "general_operand" "=r")
1776         (subreg:HI (match_dup 1) 0))]
1777   "TARGET_45"
1778   "")
1779
1780 (define_insn ""
1781   [(set (subreg:HI (match_operand:SI 0 "general_operand" "=r") 0)
1782         (div:HI (match_operand:SI 1 "general_operand" "0")
1783                 (match_operand:HI 2 "general_operand" "g")))]
1784   "TARGET_45"
1785   "div %2,%0"
1786   [(set_attr "length" "2")])
1787
1788 (define_expand "modhi3"
1789   [(set (subreg:HI (match_dup 1) 1)
1790         (mod:HI (match_operand:SI 1 "general_operand" "0")
1791                 (match_operand:HI 2 "general_operand" "g")))
1792    (set (match_operand:HI 0 "general_operand" "=r")
1793         (subreg:HI (match_dup 1) 1))]
1794   "TARGET_45"
1795   "")
1796
1797 (define_insn ""
1798   [(set (subreg:HI (match_operand:SI 0 "general_operand" "=r") 1)
1799         (mod:HI (match_operand:SI 1 "general_operand" "0")
1800                 (match_operand:HI 2 "general_operand" "g")))]
1801   "TARGET_45"
1802   "div %2,%0"
1803   [(set_attr "length" "2")])
1804
1805 ;(define_expand "divmodhi4"
1806 ;  [(parallel [(set (subreg:HI (match_dup 1) 0)
1807 ;                  (div:HI (match_operand:SI 1 "general_operand" "0")
1808 ;                          (match_operand:HI 2 "general_operand" "g")))
1809 ;              (set (subreg:HI (match_dup 1) 1)
1810 ;                  (mod:HI (match_dup 1)
1811 ;                          (match_dup 2)))])
1812 ;   (set (match_operand:HI 3 "general_operand" "=r")
1813 ;        (subreg:HI (match_dup 1) 1))
1814 ;   (set (match_operand:HI 0 "general_operand" "=r")
1815 ;        (subreg:HI (match_dup 1) 0))]
1816 ;  "TARGET_45"
1817 ;  "")
1818 ;
1819 ;(define_insn ""
1820 ;  [(set (subreg:HI (match_operand:SI 0 "general_operand" "=r") 0)
1821 ;                  (div:HI (match_operand:SI 1 "general_operand" "0")
1822 ;                          (match_operand:HI 2 "general_operand" "g")))
1823 ;   (set (subreg:HI (match_dup 0) 1)
1824 ;                  (mod:HI (match_dup 1)
1825 ;                          (match_dup 2)))]
1826 ;  "TARGET_45"
1827 ;  "div %2, %0")
1828 ;
1829    
1830 ;; is rotate doing the right thing to be included here ????