OSDN Git Service

(divhi3, modhi3, divmodhi4): Rewrite.
[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 "memory_operand" "=R,Q")
722         (float_truncate:SF (match_operand:DF 1 "register_operand" "a,a")))]
723   "TARGET_FPU"
724   "stcdf %1, %0"
725   [(set_attr "length" "1,2")])
726
727 (define_expand "truncsihi2"
728   [(set (match_operand:HI 0 "general_operand" "=g")
729         (subreg:HI 
730           (match_operand:SI 1 "general_operand" "or")
731           0))]
732   ""
733   "")
734
735 \f
736 ;;- zero extension instructions
737
738 (define_insn "zero_extendqihi2"
739   [(set (match_operand:HI 0 "general_operand" "=r")
740         (zero_extend:HI (match_operand:QI 1 "general_operand" "0")))]
741   ""
742   "bic $(256*255), %0"
743   [(set_attr "length" "2")])
744                          
745 (define_expand "zero_extendhisi2"
746   [(set (subreg:HI 
747           (match_dup 0)
748           1)
749         (match_operand:HI 1 "register_operand" "r"))
750    (set (subreg:HI 
751           (match_operand:SI 0 "register_operand" "=r")
752           0)
753         (const_int 0))]
754   ""
755   "/* operands[1] = make_safe_from (operands[1], operands[0]); */")
756
757 \f
758 ;;- sign extension instructions
759
760 (define_insn "extendsfdf2"
761   [(set (match_operand:DF 0 "register_operand" "=a,a")
762         (float_extend:SF (match_operand:SF 1 "memory_operand" "R,Q")))]
763   "TARGET_FPU"
764   "ldcfd %1, %0"
765   [(set_attr "length" "1,2")])
766
767 ;; does movb sign extend in register-to-register move?
768 (define_insn "extendqihi2"
769   [(set (match_operand:HI 0 "register_operand" "=r,r")
770         (sign_extend:HI (match_operand:QI 1 "general_operand" "rR,Q")))]
771   ""
772   "movb %1, %0"
773   [(set_attr "length" "1,2")])
774
775 (define_insn "extendqisi2"
776   [(set (match_operand:SI 0 "register_operand" "=r,r")
777         (sign_extend:SI (match_operand:QI 1 "general_operand" "rR,Q")))]
778   "TARGET_40_PLUS"
779   "*
780 {
781   rtx latehalf[2];
782
783   /* make register pair available */
784   latehalf[0] = operands[0];
785   operands[0] = gen_rtx(REG, HImode, REGNO (operands[0])+1);
786     
787   output_asm_insn(\"movb %1, %0\", operands);
788   output_asm_insn(\"sxt %0\", latehalf);
789     
790   return \"\";
791 }"
792   [(set_attr "length" "2,3")])
793
794 ;; maybe we have to use define_expand to say that we have the instruction,
795 ;; unconditionally, and then match dependent on CPU type:
796
797 (define_expand "extendhisi2"
798   [(set (match_operand:SI 0 "general_operand" "=g")
799         (sign_extend:SI (match_operand:HI 1 "general_operand" "g")))]
800   ""
801   "")
802   
803 (define_insn "" ; "extendhisi2"
804   [(set (match_operand:SI 0 "general_operand" "=o,<,r")
805         (sign_extend:SI (match_operand:HI 1 "general_operand" "g,g,g")))]
806   "TARGET_40_PLUS"
807   "*
808 {
809   rtx latehalf[2];
810
811   /* we don't want to mess with auto increment */
812   
813   switch(which_alternative)
814   {
815     case 0:
816
817       latehalf[0] = operands[0];
818       operands[0] = adj_offsettable_operand(operands[0], 2);
819   
820       output_asm_insn(\"mov %1, %0\", operands);
821       output_asm_insn(\"sxt %0\", latehalf);
822
823       return \"\";
824
825     case 1:
826
827       /* - auto-decrement - right direction ;-) */
828       output_asm_insn(\"mov %1, %0\", operands);
829       output_asm_insn(\"sxt %0\", operands);
830
831       return \"\";
832
833     case 2:
834
835       /* make register pair available */
836       latehalf[0] = operands[0];
837       operands[0] = gen_rtx(REG, HImode, REGNO (operands[0])+1);
838
839       output_asm_insn(\"mov %1, %0\", operands);
840       output_asm_insn(\"sxt %0\", latehalf);
841
842       return \"\";
843
844     default:
845
846       abort();
847   }
848 }"
849   [(set_attr "length" "5,3,3")])
850
851
852 (define_insn ""
853   [(set (match_operand:SI 0 "register_operand" "=r")
854         (sign_extend:SI (match_operand:HI 1 "general_operand" "0")))]
855   "(! TARGET_40_PLUS)"
856   "*
857 {
858   static count = 0;
859   char buf[100];
860   rtx lateoperands[2];
861
862   lateoperands[0] = operands[0];
863   operands[0] = gen_rtx(REG, HImode, REGNO (operands[0])+1);
864
865   output_asm_insn(\"tst %0\", operands);
866   sprintf(buf, \"bge extendhisi%d\", count);
867   output_asm_insn(buf, NULL);
868   output_asm_insn(\"mov -1, %0\", lateoperands);
869   sprintf(buf, \"bne extendhisi%d\", count+1);
870   output_asm_insn(buf, NULL);
871   sprintf(buf, \"\\nextendhisi%d:\", count);
872   output_asm_insn(buf, NULL);
873   output_asm_insn(\"clr %0\", lateoperands);
874   sprintf(buf, \"\\nextendhisi%d:\", count+1);
875   output_asm_insn(buf, NULL);
876
877   count += 2;
878
879   return \"\";
880 }"
881   [(set_attr "length" "6")])
882
883 ;; make float to int and vice versa 
884 ;; using the cc_status.flag field we could probably cut down
885 ;; on seti and setl
886 ;; assume that we are normally in double and integer mode -
887 ;; what do pdp library routines do to fpu mode ?
888
889 (define_insn "floatsidf2"
890   [(set (match_operand:DF 0 "register_operand" "=a,a")
891         (float:DF (match_operand:SI 1 "memory_operand" "R,Q")))]
892   "TARGET_FPU"
893   "setl\;ldcld %1, %0\;seti"
894   [(set_attr "length" "3,4")])
895
896 (define_insn "floathidf2"
897   [(set (match_operand:DF 0 "register_operand" "=a,a")
898         (float:DF (match_operand:HI 1 "general_operand" "rR,Qi")))]
899   "TARGET_FPU"
900   "ldcid %1, %0"
901   [(set_attr "length" "1,2")])
902         
903 ;; cut float to int
904 (define_insn "fix_truncdfsi2"
905   [(set (match_operand:SI 0 "memory_operand" "=R,Q")
906         (fix:SI (fix:DF (match_operand:DF 1 "register_operand" "a,a"))))]
907   "TARGET_FPU"
908   "setl\;stcdl %1, %0\;seti"
909   [(set_attr "length" "3,4")])
910
911 (define_insn "fix_truncdfhi2"
912   [(set (match_operand:HI 0 "general_operand" "=rR,Q")
913         (fix:HI (fix:DF (match_operand:DF 1 "register_operand" "a,a"))))]
914   "TARGET_FPU"
915   "stcdi %1, %0"
916   [(set_attr "length" "1,2")])
917
918 \f
919 ;;- arithmetic instructions
920 ;;- add instructions
921
922 (define_insn "adddf3"
923   [(set (match_operand:DF 0 "register_operand" "=a,a,a")
924         (plus:DF (match_operand:DF 1 "register_operand" "%0,0,0")
925                  (match_operand:DF 2 "general_operand" "fR,Q,F")))]
926   "TARGET_FPU"
927   "addd %2, %0"
928   [(set_attr "length" "1,2,5")])
929
930 (define_insn "addsi3"
931   [(set (match_operand:SI 0 "general_operand" "=r,r,o,o,r,r,r,o,o,o")
932         (plus:SI (match_operand:SI 1 "general_operand" "%0,0,0,0,0,0,0,0,0,0")
933                  (match_operand:SI 2 "general_operand" "r,o,r,o,I,J,K,I,J,K")))]
934   ""
935   "*
936 { /* Here we trust that operands don't overlap 
937
938      or is lateoperands the low word?? - looks like it! */
939
940   unsigned int i;
941   rtx lateoperands[3];
942   
943   lateoperands[0] = operands[0];
944
945   if (REG_P (operands[0]))
946     operands[0] = gen_rtx(REG, HImode, REGNO(operands[0]) + 1);
947   else
948     operands[0] = adj_offsettable_operand (operands[0], 2);
949   
950   if (! CONSTANT_P(operands[2]))
951   {
952     lateoperands[2] = operands[2];
953
954     if (REG_P (operands[2]))
955       operands[2] = gen_rtx(REG, HImode, REGNO(operands[2]) + 1);
956     else
957       operands[2] = adj_offsettable_operand(operands[2], 2);
958
959     output_asm_insn (\"add %2, %0\", operands);
960     output_asm_insn (\"adc %0\", lateoperands);
961     output_asm_insn (\"add %2, %0\", lateoperands);
962     return \"\";
963   }
964
965   lateoperands[2] = gen_rtx(CONST_INT, VOIDmode, (INTVAL(operands[2]) >> 16) & 0xffff);
966   operands[2] = gen_rtx(CONST_INT, VOIDmode, INTVAL(operands[2]) & 0xffff);
967   
968   if (INTVAL(operands[2]))
969   { 
970     output_asm_insn (\"add %2, %0\", operands);
971     output_asm_insn (\"adc %0\", lateoperands);
972   }
973
974   if (INTVAL(lateoperands[2]))
975     output_asm_insn (\"add %2, %0\", lateoperands);
976
977   return \"\";
978 }"
979   [(set_attr "length" "3,5,6,8,3,1,5,5,3,8")])
980
981 (define_insn "addhi3"
982   [(set (match_operand:HI 0 "general_operand" "=rR,rR,Q,Q")
983         (plus:HI (match_operand:HI 1 "general_operand" "%0,0,0,0")
984                  (match_operand:HI 2 "general_operand" "rRLM,Qi,rRLM,Qi")))]
985   ""
986   "*
987 {
988   if (GET_CODE (operands[2]) == CONST_INT)
989     if (INTVAL(operands[2]) == 1)
990       return \"inc %0\";
991     else if (INTVAL(operands[2]) == -1)
992       return \"dec %0\";
993
994   return \"add %2, %0\";
995 }"
996   [(set_attr "length" "1,2,2,3")])
997
998 (define_insn "addqi3"
999   [(set (match_operand:QI 0 "general_operand" "=rR,rR,Q,Q")
1000         (plus:QI (match_operand:QI 1 "general_operand" "%0,0,0,0")
1001                  (match_operand:QI 2 "general_operand" "rRLM,Qi,rRLM,Qi")))]
1002   ""
1003   "*
1004 {
1005   if (GET_CODE (operands[2]) == CONST_INT)
1006     if (INTVAL(operands[2]) == 1)
1007       return \"incb %0\";
1008     else if (INTVAL(operands[2]) == -1)
1009       return \"decb %0\";
1010
1011   return \"addb %2, %0\";
1012 }"
1013   [(set_attr "length" "1,2,2,3")])
1014
1015 \f
1016 ;;- subtract instructions
1017 ;; we don't have to care for constant second 
1018 ;; args, since they are canonical plus:xx now!
1019 ;; also for minus:DF ??
1020
1021 (define_insn "subdf3"
1022   [(set (match_operand:DF 0 "register_operand" "=a,a")
1023         (minus:DF (match_operand:DF 1 "register_operand" "0,0")
1024                   (match_operand:DF 2 "general_operand" "fR,Q")))]
1025   "TARGET_FPU"
1026   "subd %2, %0"
1027   [(set_attr "length" "1,2")])
1028
1029 (define_insn "subsi3"
1030   [(set (match_operand:SI 0 "general_operand" "=r,r,o,o")
1031         (minus:SI (match_operand:SI 1 "general_operand" "0,0,0,0")
1032                   (match_operand:SI 2 "general_operand" "r,o,r,o")))]
1033   ""
1034   "*
1035 { /* Here we trust that operands don't overlap 
1036
1037      or is lateoperands the low word?? - looks like it! */
1038
1039   unsigned int i;
1040   rtx lateoperands[3];
1041   
1042   lateoperands[0] = operands[0];
1043
1044   if (REG_P (operands[0]))
1045     operands[0] = gen_rtx(REG, HImode, REGNO(operands[0]) + 1);
1046   else
1047     operands[0] = adj_offsettable_operand (operands[0], 2);
1048   
1049   lateoperands[2] = operands[2];
1050
1051   if (REG_P (operands[2]))
1052     operands[2] = gen_rtx(REG, HImode, REGNO(operands[2]) + 1);
1053   else
1054     operands[2] = adj_offsettable_operand(operands[2], 2);
1055
1056   output_asm_insn (\"sub %2, %0\", operands);
1057   output_asm_insn (\"sbc %0\", lateoperands);
1058   output_asm_insn (\"sub %2, %0\", lateoperands);
1059   return \"\";
1060 }"
1061 ;; offsettable memory addresses always are expensive!!!
1062   [(set_attr "length" "3,5,6,8")])
1063
1064 (define_insn "subhi3"
1065   [(set (match_operand:HI 0 "general_operand" "=rR,rR,Q,Q")
1066         (minus:HI (match_operand:HI 1 "general_operand" "0,0,0,0")
1067                   (match_operand:HI 2 "general_operand" "rR,Qi,rR,Qi")))]
1068   ""
1069   "*
1070 {
1071   if (GET_CODE (operands[2]) == CONST_INT)
1072     abort();
1073
1074   return \"sub %2, %0\";
1075 }"
1076   [(set_attr "length" "1,2,2,3")])
1077
1078 (define_insn "subqi3"
1079   [(set (match_operand:QI 0 "general_operand" "=rR,rR,Q,Q")
1080         (minus:QI (match_operand:QI 1 "general_operand" "0,0,0,0")
1081                   (match_operand:QI 2 "general_operand" "rR,Qi,rR,Qi")))]
1082   ""
1083   "*
1084 {
1085   if (GET_CODE (operands[2]) == CONST_INT)
1086     abort();
1087
1088   return \"subb %2, %0\";
1089 }"
1090   [(set_attr "length" "1,2,2,3")])
1091
1092 ;;;;- and instructions
1093 ;; Bit-and on the pdp (like on the vax) is done with a clear-bits insn.
1094 (define_expand "andsi3"
1095   [(set (match_operand:SI 0 "general_operand" "=g")
1096         (and:SI (match_operand:SI 1 "general_operand" "0")
1097                 (not:SI (match_operand:SI 2 "general_operand" "g"))))]
1098   ""
1099   "
1100 {
1101   extern rtx expand_unop ();
1102   if (GET_CODE (operands[2]) == CONST_INT)
1103     operands[2] = gen_rtx (CONST_INT, VOIDmode, ~INTVAL (operands[2]));
1104   else
1105     operands[2] = expand_unop (SImode, one_cmpl_optab, operands[2], 0, 1);
1106 }")
1107
1108 (define_expand "andhi3"
1109   [(set (match_operand:HI 0 "general_operand" "=g")
1110         (and:HI (match_operand:HI 1 "general_operand" "0")
1111                 (not:HI (match_operand:HI 2 "general_operand" "g"))))]
1112   ""
1113   "
1114 {
1115   extern rtx expand_unop ();
1116   if (GET_CODE (operands[2]) == CONST_INT)
1117     operands[2] = gen_rtx (CONST_INT, VOIDmode, ~INTVAL (operands[2]));
1118   else
1119     operands[2] = expand_unop (HImode, one_cmpl_optab, operands[2], 0, 1);
1120 }")
1121
1122 (define_expand "andqi3"
1123   [(set (match_operand:QI 0 "general_operand" "=g")
1124         (and:QI (match_operand:QI 1 "general_operand" "0")
1125                 (not:QI (match_operand:QI 2 "general_operand" "g"))))]
1126   ""
1127   "
1128 {
1129   extern rtx expand_unop ();
1130   rtx op = operands[2];
1131   if (GET_CODE (op) == CONST_INT)
1132     operands[2] = gen_rtx (CONST_INT, VOIDmode,
1133                            ((1 << 8) - 1) & ~INTVAL (op));
1134   else
1135     operands[2] = expand_unop (QImode, one_cmpl_optab, op, 0, 1);
1136 }")
1137
1138 (define_insn "andcbsi3"
1139   [(set (match_operand:SI 0 "general_operand" "=r,r,o,o,r,r,r,o,o,o")
1140         (and:SI (match_operand:SI 1 "general_operand" "%0,0,0,0,0,0,0,0,0,0")
1141                 (not:SI (match_operand:SI 2 "general_operand" "r,o,r,o,I,J,K,I,J,K"))))]
1142   ""
1143   "*
1144 { /* Here we trust that operands don't overlap 
1145
1146      or is lateoperands the low word?? - looks like it! */
1147
1148   unsigned int i;
1149   rtx lateoperands[3];
1150   
1151   lateoperands[0] = operands[0];
1152
1153   if (REG_P (operands[0]))
1154     operands[0] = gen_rtx(REG, HImode, REGNO(operands[0]) + 1);
1155   else
1156     operands[0] = adj_offsettable_operand (operands[0], 2);
1157   
1158   if (! CONSTANT_P(operands[2]))
1159   {
1160     lateoperands[2] = operands[2];
1161
1162     if (REG_P (operands[2]))
1163       operands[2] = gen_rtx(REG, HImode, REGNO(operands[2]) + 1);
1164     else
1165       operands[2] = adj_offsettable_operand(operands[2], 2);
1166
1167     output_asm_insn (\"bic %2, %0\", operands);
1168     output_asm_insn (\"bic %2, %0\", lateoperands);
1169     return \"\";
1170   }
1171
1172   lateoperands[2] = gen_rtx(CONST_INT, VOIDmode, (INTVAL(operands[2]) >> 16) & 0xffff);
1173   operands[2] = gen_rtx(CONST_INT, VOIDmode, INTVAL(operands[2]) & 0xffff);
1174   
1175   /* these have different lengths, so we should have 
1176      different constraints! */
1177   if (INTVAL(operands[2]))
1178     output_asm_insn (\"bic %2, %0\", operands);
1179
1180   if (INTVAL(lateoperands[2]))
1181     output_asm_insn (\"bic %2, %0\", lateoperands);
1182
1183   return \"\";
1184 }"
1185   [(set_attr "length" "2,4,4,6,2,2,4,3,3,6")])
1186
1187 (define_insn "andcbhi3"
1188   [(set (match_operand:HI 0 "general_operand" "=rR,rR,Q,Q")
1189         (and:HI (match_operand:HI 1 "general_operand" "0,0,0,0")
1190                 (not:HI (match_operand:HI 2 "general_operand" "rR,Qi,rR,Qi"))))]
1191   ""
1192   "bic %2, %0"
1193   [(set_attr "length" "1,2,2,3")])
1194
1195 (define_insn "andcbqi3"
1196   [(set (match_operand:QI 0 "general_operand" "=rR,rR,Q,Q")
1197         (and:QI (match_operand:QI 1 "general_operand" "0,0,0,0")
1198                 (not:QI (match_operand:QI 2 "general_operand" "rR,Qi,rR,Qi"))))]
1199   ""
1200   "bicb %2, %0"
1201   [(set_attr "length" "1,2,2,3")])
1202
1203 ;;- Bit set (inclusive or) instructions
1204 (define_insn "iorsi3"
1205   [(set (match_operand:SI 0 "general_operand" "=r,r,o,o,r,r,r,o,o,o")
1206         (ior:SI (match_operand:SI 1 "general_operand" "%0,0,0,0,0,0,0,0,0,0")
1207                   (match_operand:SI 2 "general_operand" "r,o,r,o,I,J,K,I,J,K")))]
1208   ""
1209   "*
1210 { /* Here we trust that operands don't overlap 
1211
1212      or is lateoperands the low word?? - looks like it! */
1213
1214   unsigned int i;
1215   rtx lateoperands[3];
1216   
1217   lateoperands[0] = operands[0];
1218
1219   if (REG_P (operands[0]))
1220     operands[0] = gen_rtx(REG, HImode, REGNO(operands[0]) + 1);
1221   else
1222     operands[0] = adj_offsettable_operand (operands[0], 2);
1223   
1224   if (! CONSTANT_P(operands[2]))
1225   {
1226     lateoperands[2] = operands[2];
1227
1228     if (REG_P (operands[2]))
1229       operands[2] = gen_rtx(REG, HImode, REGNO(operands[2]) + 1);
1230     else
1231       operands[2] = adj_offsettable_operand(operands[2], 2);
1232
1233     output_asm_insn (\"bis %2, %0\", operands);
1234     output_asm_insn (\"bis %2, %0\", lateoperands);
1235     return \"\";
1236   }
1237
1238   lateoperands[2] = gen_rtx(CONST_INT, VOIDmode, (INTVAL(operands[2]) >> 16) & 0xffff);
1239   operands[2] = gen_rtx(CONST_INT, VOIDmode, INTVAL(operands[2]) & 0xffff);
1240   
1241   /* these have different lengths, so we should have 
1242      different constraints! */
1243   if (INTVAL(operands[2]))
1244     output_asm_insn (\"bis %2, %0\", operands);
1245
1246   if (INTVAL(lateoperands[2]))
1247     output_asm_insn (\"bis %2, %0\", lateoperands);
1248
1249   return \"\";
1250 }"
1251   [(set_attr "length" "2,4,4,6,2,2,4,3,3,6")])
1252
1253 (define_insn "iorhi3"
1254   [(set (match_operand:HI 0 "general_operand" "=rR,rR,Q,Q")
1255         (ior:HI (match_operand:HI 1 "general_operand" "%0,0,0,0")
1256                 (match_operand:HI 2 "general_operand" "rR,Qi,rR,Qi")))]
1257   ""
1258   "bis %2, %0"
1259   [(set_attr "length" "1,2,2,3")])
1260
1261 (define_insn "iorqi3"
1262   [(set (match_operand:QI 0 "general_operand" "=rR,rR,Q,Q")
1263         (ior:QI (match_operand:QI 1 "general_operand" "%0,0,0,0")
1264                 (match_operand:QI 2 "general_operand" "rR,Qi,rR,Qi")))]
1265   ""
1266   "bisb %2, %0")
1267
1268 ;;- xor instructions
1269 (define_insn "xorsi3"
1270   [(set (match_operand:SI 0 "register_operand" "=r,r,r,r")
1271         (xor:SI (match_operand:SI 1 "register_operand" "%0,0,0,0")
1272                   (match_operand:SI 2 "arith_operand" "r,I,J,K")))]
1273   "TARGET_40_PLUS"
1274   "*
1275 { /* Here we trust that operands don't overlap */
1276
1277   unsigned int i;
1278   rtx lateoperands[3];
1279
1280   lateoperands[0] = operands[0];
1281   operands[0] = gen_rtx(REG, HImode, REGNO(operands[0]) + 1);
1282
1283   if (REG_P(operands[2]))
1284   {
1285     lateoperands[2] = operands[2];
1286     operands[2] = gen_rtx(REG, HImode, REGNO(operands[2]) + 1);
1287     
1288     output_asm_insn (\"xor %2, %0\", operands);
1289     output_asm_insn (\"xor %2, %0\", lateoperands);
1290
1291     return \"\";
1292   }
1293
1294   lateoperands[2] = gen_rtx(CONST_INT, VOIDmode, (INTVAL(operands[2]) >> 16) & 0xffff);
1295   operands[2] = gen_rtx(CONST_INT, VOIDmode, INTVAL(operands[2]) & 0xffff);
1296   
1297   if (INTVAL(operands[2]))
1298     output_asm_insn (\"xor %2, %0\", operands);
1299
1300   if (INTVAL(lateoperands[2]))
1301     output_asm_insn (\"xor %2, %0\", lateoperands);
1302
1303   return \"\";
1304 }"
1305   [(set_attr "length" "2,1,1,2")])
1306
1307 (define_insn "xorhi3"
1308   [(set (match_operand:HI 0 "general_operand" "=rR,Q")
1309         (xor:HI (match_operand:HI 1 "general_operand" "%0,0")
1310                 (match_operand:HI 2 "register_operand" "r,r")))]
1311   "TARGET_40_PLUS"
1312   "xor %2, %0"
1313   [(set_attr "length" "1,2")])
1314
1315 ;;- one complement instructions
1316
1317 (define_insn "one_cmplhi2"
1318   [(set (match_operand:HI 0 "general_operand" "=rR,Q")
1319         (not:HI (match_operand:HI 1 "general_operand" "0,0")))]
1320   ""
1321   "com %0"
1322   [(set_attr "length" "1,2")])
1323
1324 (define_insn "one_cmplqi2"
1325   [(set (match_operand:QI 0 "general_operand" "=rR,Q")
1326         (not:QI (match_operand:QI 1 "general_operand" "0,0")))]
1327   ""
1328   "comb %0"
1329   [(set_attr "length" "1,2")])
1330
1331 ;;- arithmetic shift instructions
1332 (define_insn "ashlsi3"
1333   [(set (match_operand:SI 0 "register_operand" "=r,r")
1334         (ashift:SI (match_operand:SI 1 "register_operand" "0,0")
1335                    (match_operand:HI 2 "general_operand" "rR,Qi")))]
1336   "TARGET_45"
1337   "ashc %2,%0"
1338   [(set_attr "length" "1,2")])
1339
1340 ;; Arithmetic right shift on the pdp works by negating the shift count.
1341 (define_expand "ashrsi3"
1342   [(set (match_operand:SI 0 "register_operand" "=r")
1343         (ashift:SI (match_operand:SI 1 "register_operand" "0")
1344                    (match_operand:HI 2 "general_operand" "g")))]
1345   ""
1346   "
1347 {
1348   operands[2] = negate_rtx (HImode, operands[2]);
1349 }")
1350
1351 ;; define asl aslb asr asrb - ashc missing!
1352
1353 ;; asl 
1354 (define_insn "" 
1355   [(set (match_operand:HI 0 "general_operand" "=rR,Q")
1356         (ashift:HI (match_operand:HI 1 "general_operand" "0,0")
1357                    (const_int 1)))]
1358   ""
1359   "asl %0"
1360   [(set_attr "length" "1,2")])
1361
1362 ;; and another possibility for asr is << -1
1363 ;; might cause problems since -1 can also be encoded as 65535!
1364 ;; not in gcc2 ??? 
1365
1366 ;; asr
1367 (define_insn "" 
1368   [(set (match_operand:HI 0 "general_operand" "=rR,Q")
1369         (ashift:HI (match_operand:HI 1 "general_operand" "0,0")
1370                    (const_int -1)))]
1371   ""
1372   "asr %0"
1373   [(set_attr "length" "1,2")])
1374
1375 ;; shift is by arbitrary count is expensive, 
1376 ;; shift by one cheap - so let's do that, if
1377 ;; space doesn't matter
1378 (define_insn "" 
1379   [(set (match_operand:HI 0 "general_operand" "=r")
1380         (ashift:HI (match_operand:HI 1 "general_operand" "0")
1381                    (match_operand:HI 2 "expand_shift_operand" "O")))]
1382   "TARGET_TIME"
1383   "*
1384 {
1385   register int i;
1386
1387   for (i = 1; i <= abs(INTVAL(operands[2])); i++)
1388     if (INTVAL(operands[2]) < 0)
1389       output_asm_insn(\"asr %0\", operands);
1390     else
1391       output_asm_insn(\"asl %0\", operands);
1392       
1393   return \"\";
1394 }"
1395 ;; longest is 4
1396   [(set (attr "length") (const_int 4))])
1397
1398 ;; aslb
1399 (define_insn "" 
1400   [(set (match_operand:QI 0 "general_operand" "=r,o")
1401         (ashift:QI (match_operand:QI 1 "general_operand" "0,0")
1402                    (match_operand:HI 2 "const_immediate_operand" "n,n")))]
1403   ""
1404   "*
1405 { /* allowing predec or post_inc is possible, but hairy! */
1406   int i, cnt;
1407
1408   cnt = INTVAL(operands[2]) & 0x0007;
1409
1410   for (i=0 ; i < cnt ; i++)
1411        output_asm_insn(\"aslb %0\", operands);
1412
1413   return \"\";
1414 }"
1415 ;; set attribute length ( match_dup 2 & 7 ) *(1 or 2) !!!
1416   [(set_attr_alternative "length" 
1417                          [(const_int 7)
1418                           (const_int 14)])])
1419
1420 ;;; asr 
1421 ;(define_insn "" 
1422 ;  [(set (match_operand:HI 0 "general_operand" "=rR,Q")
1423 ;       (ashiftrt:HI (match_operand:HI 1 "general_operand" "0,0")
1424 ;                    (const_int 1)))]
1425 ;  ""
1426 ;  "asr %0"
1427 ;  [(set_attr "length" "1,2")])
1428
1429 ;; asrb
1430 (define_insn "" 
1431   [(set (match_operand:QI 0 "general_operand" "=r,o")
1432         (ashiftrt:QI (match_operand:QI 1 "general_operand" "0,0")
1433                      (match_operand:HI 2 "const_immediate_operand" "n,n")))]
1434   ""
1435   "*
1436 { /* allowing predec or post_inc is possible, but hairy! */
1437   int i, cnt;
1438
1439   cnt = INTVAL(operands[2]) & 0x0007;
1440
1441   for (i=0 ; i < cnt ; i++)
1442        output_asm_insn(\"asrb %0\", operands);
1443
1444   return \"\";
1445 }"
1446   [(set_attr_alternative "length" 
1447                          [(const_int 7)
1448                           (const_int 14)])])
1449
1450 ;; the following is invalid - too complex!!! - just say 14 !!!
1451 ;  [(set (attr "length") (plus (and (match_dup 2)
1452 ;                                   (const_int 7))
1453 ;                              (and (match_dup 2)
1454 ;                                   (const_int 7))))])
1455
1456
1457
1458 ;; can we get +-1 in the next pattern? should 
1459 ;; have been caught by previous patterns!
1460
1461 (define_insn "ashlhi3"
1462   [(set (match_operand:HI 0 "register_operand" "=r,r")
1463         (ashift:HI (match_operand:HI 1 "register_operand" "0,0")
1464                    (match_operand:HI 2 "general_operand" "rR,Qi")))]
1465   ""
1466   "*
1467 {
1468   if (GET_CODE(operands[2]) == CONST_INT)
1469     if (INTVAL(operands[2]) == 1)
1470       return \"asl %0\";
1471     else if (INTVAL(operands[2]) == -1)
1472       return \"asr %0\";
1473
1474   return \"ash %2,%0\";
1475 }"
1476   [(set_attr "length" "1,2")])
1477
1478 ;; Arithmetic right shift on the pdp works by negating the shift count.
1479 (define_expand "ashrhi3"
1480   [(set (match_operand:HI 0 "register_operand" "=r")
1481         (ashift:HI (match_operand:HI 1 "register_operand" "0")
1482                    (match_operand:HI 2 "general_operand" "g")))]
1483   ""
1484   "
1485 {
1486   operands[2] = negate_rtx (HImode, operands[2]);
1487 }")
1488
1489 ;;;;- logical shift instructions
1490 ;;(define_insn "lshrsi3"
1491 ;;  [(set (match_operand:HI 0 "register_operand" "=r")
1492 ;;      (lshiftrt:HI (match_operand:HI 1 "register_operand" "0")
1493 ;;                   (match_operand:HI 2 "arith_operand" "rI")))]
1494 ;;  ""
1495 ;;  "srl %0,%2")
1496
1497 ;; absolute 
1498
1499 (define_insn "absdf2"
1500   [(set (match_operand:DF 0 "general_operand" "=fR,Q")
1501         (abs:DF (match_operand:DF 1 "general_operand" "0,0")))]
1502   "TARGET_FPU"
1503   "absd %0"
1504   [(set_attr "length" "1,2")])
1505
1506 (define_insn "abshi2"
1507   [(set (match_operand:HI 0 "general_operand" "=r,o")
1508         (abs:HI (match_operand:HI 1 "general_operand" "0,0")))]
1509   "TARGET_ABSHI_BUILTIN"
1510   "*
1511 {
1512   static count = 0;
1513   char buf[200];
1514         
1515   output_asm_insn(\"tst %0\", operands);
1516   sprintf(buf, \"bge abshi%d\", count);
1517   output_asm_insn(buf, NULL);
1518   output_asm_insn(\"neg %0\", operands);
1519   sprintf(buf, \"\\nabshi%d:\", count++);
1520   output_asm_insn(buf, NULL);
1521
1522   return \"\";
1523 }"
1524   [(set_attr "length" "3,5")])
1525
1526
1527 ;; define expand abshi - is much better !!! - but
1528 ;; will it be optimized into an abshi2 ?
1529 ;; it will leave better code, because the tsthi might be 
1530 ;; optimized away!!
1531 ; -- just a thought - don't have time to check 
1532 ;
1533 ;(define_expand "abshi2"
1534 ;  [(match_operand:HI 0 "general_operand" "")
1535 ;   (match_operand:HI 1 "general_operand" "")]
1536 ;  ""
1537 ;  "
1538 ;{
1539 ;  rtx label = gen_label_rtx ();
1540 ;
1541 ;  /* do I need this? */
1542 ;  do_pending_stack_adjust ();
1543 ;
1544 ;  emit_move_insn (operands[0], operands[1]);
1545 ;
1546 ;  emit_insn (gen_tsthi (operands[0]));
1547 ;  emit_insn (gen_bge (label1));
1548 ;
1549 ;  emit_insn (gen_neghi(operands[0], operands[0])
1550 ;  
1551 ;  emit_barrier ();
1552 ;
1553 ;  emit_label (label);
1554 ;
1555 ;  /* allow REG_NOTES to be set on last insn (labels don't have enough
1556 ;     fields, and can't be used for REG_NOTES anyway).  */
1557 ;  emit_insn (gen_rtx (USE, VOIDmode, stack_pointer_rtx));
1558 ;  DONE;
1559 ;}")
1560
1561 ;; negate insns
1562
1563 (define_insn "negdf2"
1564   [(set (match_operand:DF 0 "general_operand" "=fR,Q")
1565         (neg:DF (match_operand:DF 1 "register_operand" "0,0")))]
1566   "TARGET_FPU"
1567   "negd %0"
1568   [(set_attr "length" "1,2")])
1569
1570 (define_insn "neghi2"
1571   [(set (match_operand:HI 0 "general_operand" "=rR,Q")
1572         (neg:HI (match_operand:HI 1 "general_operand" "0,0")))]
1573   ""
1574   "neg %0"
1575   [(set_attr "length" "1,2")])
1576
1577 (define_insn "negqi2"
1578   [(set (match_operand:QI 0 "general_operand" "=rR,Q")
1579         (neg:QI (match_operand:QI 1 "general_operand" "0,0")))]
1580   ""
1581   "negb %0"
1582   [(set_attr "length" "1,2")])
1583
1584
1585 ;; Unconditional and other jump instructions
1586 (define_insn "jump"
1587   [(set (pc)
1588         (label_ref (match_operand 0 "" "")))]
1589   ""
1590   "jmp %l0"
1591   [(set_attr "length" "2")])
1592
1593 (define_insn ""
1594   [(set (pc)
1595     (label_ref (match_operand 0 "" "")))
1596    (clobber (const_int 1))]
1597   ""
1598   "jmp %l0"
1599   [(set_attr "length" "2")])
1600
1601 (define_insn "tablejump"
1602   [(set (pc) (match_operand:HI 0 "general_operand" "rR,Q"))
1603    (use (label_ref (match_operand 1 "" "")))]
1604   ""
1605   "jmp %0"
1606   [(set_attr "length" "1,2")])
1607
1608 ;; indirect jump - let's be conservative!
1609 ;; allow only register_operand, even though we could also 
1610 ;; allow labels etc.
1611
1612 (define_insn "indirect_jump"
1613   [(set (pc) (match_operand:HI 0 "register_operand" "r"))]
1614   ""
1615   "jmp (%0)")
1616
1617 ;;- jump to subroutine
1618
1619 (define_insn "call"
1620   [(call (match_operand:HI 0 "general_operand" "R,Q")
1621          (match_operand:HI 1 "general_operand" "g,g"))
1622 ;;   (use (reg:HI 0)) what was that ???
1623   ]
1624   ;;- Don't use operand 1 for most machines.
1625   ""
1626   "jsr pc, %0"
1627   [(set_attr "length" "1,2")])
1628
1629 ;;- jump to subroutine
1630 (define_insn "call_value"
1631   [(set (match_operand 0 "" "")
1632         (call (match_operand:HI 1 "general_operand" "R,Q")
1633               (match_operand:HI 2 "general_operand" "g,g")))
1634 ;;   (use (reg:HI 0)) - what was that ????
1635   ]
1636   ;;- Don't use operand 2 for most machines.
1637   ""
1638   "jsr pc, %1"
1639   [(set_attr "length" "1,2")])
1640
1641 ;;- nop instruction
1642 (define_insn "nop"
1643   [(const_int 0)]
1644   ""
1645   "nop")
1646 \f
1647
1648 ;;- multiply 
1649
1650 (define_insn "muldf3"
1651   [(set (match_operand:DF 0 "register_operand" "=a,a,a")
1652         (mult:DF (match_operand:DF 1 "register_operand" "%0,0,0")
1653                  (match_operand:DF 2 "general_operand" "fR,Q,F")))]
1654   "TARGET_FPU"
1655   "muld %2, %0"
1656   [(set_attr "length" "1,2,5")])
1657
1658 ;; 16 bit result multiply:
1659 ;; currently we multiply only into odd registers, so we don't use two 
1660 ;; registers - but this is a bit inefficient at times. If we define 
1661 ;; a register class for each register, then we can specify properly 
1662 ;; which register need which scratch register ....
1663
1664 (define_insn "mulhi3"
1665   [(set (match_operand:HI 0 "register_operand" "=d,d") ; multiply regs
1666         (mult:HI (match_operand:HI 1 "register_operand" "%0,0")
1667                  (match_operand:HI 2 "general_operand" "rR,Qi")))]
1668   "TARGET_45"
1669   "mul %2, %0"
1670   [(set_attr "length" "1,2")])
1671
1672 ;; 32 bit result
1673 (define_expand "mulhisi3"
1674   [(set (match_dup 3)
1675         (match_operand:HI 1 "general_operand" "g,g"))
1676    (set (match_operand:SI 0 "register_operand" "=r,r") ; even numbered!
1677         (mult:SI (truncate:HI 
1678                   (match_dup 0))
1679                  (match_operand:HI 2 "general_operand" "rR,Qi")))]
1680   "TARGET_45"
1681   "operands[3] = gen_lowpart(HImode, operands[1]);")
1682
1683 (define_insn ""
1684   [(set (match_operand:SI 0 "register_operand" "=r,r") ; even numbered!
1685         (mult:SI (truncate:HI 
1686                   (match_operand:SI 1 "register_operand" "%0,0"))
1687                  (match_operand:HI 2 "general_operand" "rR,Qi")))]
1688   "TARGET_45"
1689   "mul %2, %0"
1690   [(set_attr "length" "1,2")])
1691
1692 ;(define_insn "mulhisi3"
1693 ;  [(set (match_operand:SI 0 "register_operand" "=r,r") ; even numbered!
1694 ;       (mult:SI (truncate:HI 
1695 ;                  (match_operand:SI 1 "register_operand" "%0,0"))
1696 ;                (match_operand:HI 2 "general_operand" "rR,Qi")))]
1697 ;  "TARGET_45"
1698 ;  "mul %2, %0"
1699 ;  [(set_attr "length" "1,2")])
1700
1701 ;;- divide
1702 (define_insn "divdf3"
1703   [(set (match_operand:DF 0 "register_operand" "=a,a,a")
1704         (div:DF (match_operand:DF 1 "register_operand" "0,0,0")
1705                 (match_operand:DF 2 "general_operand" "fR,Q,F")))]
1706   "TARGET_FPU"
1707   "divd %2, %0"
1708   [(set_attr "length" "1,2,5")])
1709
1710          
1711 (define_expand "divhi3"
1712   [(set (subreg:HI (match_dup 1) 0)
1713         (div:HI (match_operand:SI 1 "general_operand" "0")
1714                 (match_operand:HI 2 "general_operand" "g")))
1715    (set (match_operand:HI 0 "general_operand" "=r")
1716         (subreg:HI (match_dup 1) 0))]
1717   "TARGET_45"
1718   "")
1719
1720 (define_insn ""
1721   [(set (subreg:HI (match_operand:SI 0 "general_operand" "=r") 0)
1722         (div:HI (match_operand:SI 1 "general_operand" "0")
1723                 (match_operand:HI 2 "general_operand" "g")))]
1724   "TARGET_45"
1725   "div %2,%0"
1726   [(set_attr "length" "2")])
1727
1728 (define_expand "modhi3"
1729   [(set (subreg:HI (match_dup 1) 1)
1730         (mod:HI (match_operand:SI 1 "general_operand" "0")
1731                 (match_operand:HI 2 "general_operand" "g")))
1732    (set (match_operand:HI 0 "general_operand" "=r")
1733         (subreg:HI (match_dup 1) 1))]
1734   "TARGET_45"
1735   "")
1736
1737 (define_insn ""
1738   [(set (subreg:HI (match_operand:SI 0 "general_operand" "=r") 1)
1739         (mod:HI (match_operand:SI 1 "general_operand" "0")
1740                 (match_operand:HI 2 "general_operand" "g")))]
1741   "TARGET_45"
1742   "div %2,%0"
1743   [(set_attr "length" "2")])
1744
1745 ;(define_expand "divmodhi4"
1746 ;  [(parallel [(set (subreg:HI (match_dup 1) 0)
1747 ;                  (div:HI (match_operand:SI 1 "general_operand" "0")
1748 ;                          (match_operand:HI 2 "general_operand" "g")))
1749 ;              (set (subreg:HI (match_dup 1) 1)
1750 ;                  (mod:HI (match_dup 1)
1751 ;                          (match_dup 2)))])
1752 ;   (set (match_operand:HI 3 "general_operand" "=r")
1753 ;        (subreg:HI (match_dup 1) 1))
1754 ;   (set (match_operand:HI 0 "general_operand" "=r")
1755 ;        (subreg:HI (match_dup 1) 0))]
1756 ;  "TARGET_45"
1757 ;  "")
1758 ;
1759 ;(define_insn ""
1760 ;  [(set (subreg:HI (match_operand:SI 0 "general_operand" "=r") 0)
1761 ;                  (div:HI (match_operand:SI 1 "general_operand" "0")
1762 ;                          (match_operand:HI 2 "general_operand" "g")))
1763 ;   (set (subreg:HI (match_dup 0) 1)
1764 ;                  (mod:HI (match_dup 1)
1765 ;                          (match_dup 2)))]
1766 ;  "TARGET_45"
1767 ;  "div %2, %0")
1768 ;
1769    
1770 ;; is rotate doing the right thing to be included here ????