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