Remove outermost loop parameter.
[official-gcc/graphite-test-results.git] / gcc / config / pdp11 / pdp11.md
blob64d57e056b3976169cfe74d390ad8c40e1326b44
1 ;;- Machine description for the pdp11 for GNU C compiler
2 ;; Copyright (C) 1994, 1995, 1997, 1998, 1999, 2000, 2001, 2004, 2005
3 ;; 2007, 2008 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 3, 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 COPYING3.  If not see
20 ;; <http://www.gnu.org/licenses/>.
22 ;; Match CONST_DOUBLE zero for tstd/tstf.
23 (define_predicate "register_or_const0_operand"
24   (ior (match_operand 0 "register_operand")
25        (match_test "op == CONST0_RTX (GET_MODE (op))")))
28 ;; HI is 16 bit
29 ;; QI is 8 bit 
31 ;;- See file "rtl.def" for documentation on define_insn, match_*, et. al.
33 ;;- cpp macro #define NOTICE_UPDATE_CC in file tm.h handles condition code
34 ;;- updates for most instructions.
36 ;;- Operand classes for the register allocator:
38 ;; Compare instructions.
40 ;; currently we only support df floats, which saves us quite some
41 ;; hassle switching the FP mode! 
42 ;; we assume that CPU is always in long float mode, and 
43 ;; 16 bit integer mode - currently, the prologue for main does this,
44 ;; but maybe we should just set up a NEW crt0 properly, 
45 ;; -- and what about signal handling code?
46 ;; (we don't even let sf floats in the register file, so
47 ;; we only should have to worry about truncating and widening 
48 ;; when going to memory)
50 ;; abort() call by g++ - must define libfunc for cmp_optab
51 ;; and ucmp_optab for mode SImode, because we don't have that!!!
52 ;; - yet since no libfunc is there, we abort ()
54 ;; The only thing that remains to be done then is output 
55 ;; the floats in a way the assembler can handle it (and 
56 ;; if you're really into it, use a PDP11 float emulation
57 ;; library to do floating point constant folding - but 
58 ;; I guess you'll get reasonable results even when not
59 ;; doing this)
60 ;; the last thing to do is fix the UPDATE_CC macro to check
61 ;; for floating point condition codes, and set cc_status
62 ;; properly, also setting the CC_IN_FCCR flag. 
64 ;; define attributes
65 ;; currently type is only fpu or arith or unknown, maybe branch later ?
66 ;; default is arith
67 (define_attr "type" "unknown,arith,fp" (const_string "arith"))
69 ;; length default is 1 word each
70 (define_attr "length" "" (const_int 1))
72 ;; a user's asm statement
73 (define_asm_attributes
74   [(set_attr "type" "unknown")
75 ; all bets are off how long it is - make it 256, forces long jumps 
76 ; whenever jumping around it !!!
77    (set_attr "length" "256")])
79 ;; define function units
81 ;; arithmetic - values here immediately when next insn issued
82 ;; or does it mean the number of cycles after this insn was issued?
83 ;; how do I say that fpu insns use cpu also? (pre-interaction phase)
85 ;(define_function_unit "cpu" 1 1 (eq_attr "type" "arith") 0 0)
86 ;(define_function_unit "fpu" 1 1 (eq_attr "type" "fp") 0 0)
88 ;; compare
89 (define_insn "*cmpdf"
90   [(set (cc0)
91         (compare (match_operand:DF 0 "general_operand" "fR,fR,Q,Q,F")
92                  (match_operand:DF 1 "register_or_const0_operand" "G,a,G,a,a")))]
93   "TARGET_FPU"
94   "*
96   cc_status.flags = CC_IN_FPU;
97   if (which_alternative == 0 || which_alternative == 2)
98     return \"{tstd|tstf} %0, %1\;cfcc\";
99   else
100     return \"{cmpd|cmpf} %0, %1\;cfcc\";
102   [(set_attr "length" "2,2,3,3,6")]) 
104 (define_insn "*cmphi"
105   [(set (cc0)
106         (compare (match_operand:HI 0 "general_operand" "rR,rR,rR,Q,Qi,Qi")
107                  (match_operand:HI 1 "general_operand" "N,rR,Qi,N,rR,Qi")))]
108   ""
109   "@
110    tst %0
111    cmp %0,%1
112    cmp %0,%1
113    tst %0
114    cmp %0,%1
115    cmp %0,%1"
116   [(set_attr "length" "1,1,2,2,2,3")])
118 (define_insn "*cmpqi"
119   [(set (cc0)
120         (compare (match_operand:QI 0 "general_operand" "rR,rR,rR,Q,Qi,Qi")
121                  (match_operand:QI 1 "general_operand" "N,rR,Qi,N,rR,Qi")))]
122   ""
123   "@
124    tstb %0
125    cmpb %0,%1
126    cmpb %0,%1
127    tstb %0
128    cmpb %0,%1
129    cmpb %0,%1"
130   [(set_attr "length" "1,1,2,2,2,3")])
131                            
133 ;; sob instruction - we need an assembler which can make this instruction
134 ;; valid under _all_ circumstances!
136 (define_insn ""
137   [(set (pc)
138         (if_then_else
139          (ne (plus:HI (match_operand:HI 0 "register_operand" "+r")
140                       (const_int -1))
141              (const_int 0))
142          (label_ref (match_operand 1 "" ""))
143          (pc)))
144    (set (match_dup 0)
145         (plus:HI (match_dup 0)
146                  (const_int -1)))]
147   "TARGET_40_PLUS"
148   "*
150  static int labelcount = 0;
151  static char buf[1000];
153  if (get_attr_length (insn) == 1)
154     return \"sob %0, %l1\";
156  /* emulate sob */
157  output_asm_insn (\"dec %0\", operands);
159  sprintf (buf, \"bge LONG_SOB%d\", labelcount);
160  output_asm_insn (buf, NULL);
162  output_asm_insn (\"jmp %l1\", operands);
164  sprintf (buf, \"LONG_SOB%d:\", labelcount++);
165  output_asm_insn (buf, NULL);
167  return \"\";
169   [(set (attr "length") (if_then_else (ior (le (minus (match_dup 0)
170                                                        (pc))
171                                                 (const_int -256))
172                                            (ge (minus (match_dup 0)
173                                                        (pc))
174                                                 (const_int 0)))
175                                       (const_int 4)
176                                       (const_int 1)))])
178 ;; These control RTL generation for conditional jump insns
179 ;; and match them for register allocation.
181 (define_expand "cbranchdf4"
182   [(set (cc0)
183         (compare (match_operand:DF 1 "general_operand")
184                  (match_operand:DF 2 "general_operand")))
185    (set (pc)
186         (if_then_else (match_operator 0 "ordered_comparison_operator"
187                        [(cc0) (const_int 0)])
188                       (label_ref (match_operand 3 "" ""))
189                       (pc)))]
190   ""
191   "")
193 (define_expand "cbranchhi4"
194   [(set (cc0)
195         (compare (match_operand:HI 1 "general_operand")
196                  (match_operand:HI 2 "general_operand")))
197    (set (pc)
198         (if_then_else (match_operator 0 "ordered_comparison_operator"
199                        [(cc0) (const_int 0)])
200                       (label_ref (match_operand 3 "" ""))
201                       (pc)))]
202   ""
203   "")
205 (define_expand "cbranchqi4"
206   [(set (cc0)
207         (compare (match_operand:QI 1 "general_operand")
208                  (match_operand:QI 2 "general_operand")))
209    (set (pc)
210         (if_then_else (match_operator 0 "ordered_comparison_operator"
211                        [(cc0) (const_int 0)])
212                       (label_ref (match_operand 3 "" ""))
213                       (pc)))]
214   ""
215   "")
217 ;; problem with too short jump distance! we need an assembler which can 
218 ;; make this valid for all jump distances!
219 ;; e.g. gas!
221 ;; these must be changed to check for CC_IN_FCCR if float is to be 
222 ;; enabled
224 (define_insn "*branch"
225   [(set (pc)
226         (if_then_else (match_operator 0 "ordered_comparison_operator"
227                        [(cc0) (const_int 0)])
228                       (label_ref (match_operand 1 "" ""))
229                       (pc)))]
230   ""
231   "* return output_jump(GET_CODE (operands[0]), 0, get_attr_length(insn));"
232   [(set (attr "length") (if_then_else (ior (le (minus (match_dup 1)
233                                                       (pc))
234                                                (const_int -128))
235                                            (ge (minus (match_dup 1)
236                                                       (pc))
237                                                (const_int 128)))
238                                       (const_int 3)
239                                       (const_int 1)))])
242 ;; These match inverted jump insns for register allocation.
244 (define_insn "*branch_inverted"
245   [(set (pc)
246         (if_then_else (match_operator 0 "ordered_comparison_operator"
247                        [(cc0) (const_int 0)])
248                       (pc)
249                       (label_ref (match_operand 1 "" ""))))]
250   ""
251   "* return output_jump(GET_CODE (operands[0]), 1, get_attr_length(insn));"
252   [(set (attr "length") (if_then_else (ior (le (minus (match_dup 1)
253                                                       (pc))
254                                                (const_int -128))
255                                            (ge (minus (match_dup 1)
256                                                       (pc))
257                                                (const_int 128)))
258                                       (const_int 3)
259                                       (const_int 1)))])
261 ;; Move instructions
263 (define_insn "movdi"
264   [(set (match_operand:DI 0 "general_operand" "=g,rm,o")
265         (match_operand:DI 1 "general_operand" "m,r,a"))]
266   ""
267   "* return output_move_quad (operands);"
268 ;; what's the mose expensive code - say twice movsi = 16
269   [(set_attr "length" "16,16,16")])
271 (define_insn "movsi"
272   [(set (match_operand:SI 0 "general_operand" "=r,r,r,rm,m")
273         (match_operand:SI 1 "general_operand" "rN,IJ,K,m,r"))]
274   ""
275   "* return output_move_double (operands);"
276 ;; what's the most expensive code ? - I think 8!
277 ;; we could split it up and make several sub-cases...
278   [(set_attr "length" "2,3,4,8,8")])
280 (define_insn "movhi"
281   [(set (match_operand:HI 0 "general_operand" "=rR,rR,Q,Q")
282         (match_operand:HI 1 "general_operand" "rRN,Qi,rRN,Qi"))]
283   ""
284   "*
286   if (operands[1] == const0_rtx)
287     return \"clr %0\";
289   return \"mov %1, %0\";
291   [(set_attr "length" "1,2,2,3")])
293 (define_insn "movqi"
294   [(set (match_operand:QI 0 "nonimmediate_operand" "=g")
295         (match_operand:QI 1 "general_operand" "g"))]
296   ""
297   "*
299   if (operands[1] == const0_rtx)
300     return \"clrb %0\";
302   return \"movb %1, %0\";
304   [(set_attr "length" "1")])
306 ;; do we have to supply all these moves? e.g. to 
307 ;; NO_LOAD_FPU_REGs ? 
308 (define_insn "movdf"
309   [(set (match_operand:DF 0 "general_operand" "=a,fR,a,Q,m")
310         (match_operand:DF 1 "general_operand" "fFR,a,Q,a,m"))]
311   ""
312   "* if (which_alternative ==0)
313        return \"ldd %1, %0\";
314      else if (which_alternative == 1)
315        return \"std %1, %0\";
316      else 
317        return output_move_quad (operands); "
318 ;; just a guess..
319   [(set_attr "length" "1,1,5,5,16")])
321 (define_insn "movsf"
322   [(set (match_operand:SF 0 "general_operand" "=g,r,g")
323         (match_operand:SF 1 "general_operand" "r,rmF,g"))]
324   "TARGET_FPU"
325   "* return output_move_double (operands);"
326   [(set_attr "length" "8,8,8")])
328 ;; maybe fiddle a bit with move_ratio, then 
329 ;; let constraints only accept a register ...
331 (define_expand "movmemhi"
332   [(parallel [(set (match_operand:BLK 0 "general_operand" "=g,g")
333                    (match_operand:BLK 1 "general_operand" "g,g"))
334               (use (match_operand:HI 2 "arith_operand" "n,&mr"))
335               (use (match_operand:HI 3 "immediate_operand" "i,i"))
336               (clobber (match_scratch:HI 4 "=&r,X"))
337               (clobber (match_dup 5))
338               (clobber (match_dup 6))
339               (clobber (match_dup 2))])]
340   "(TARGET_BCOPY_BUILTIN)"
341   "
343   operands[0]
344     = replace_equiv_address (operands[0],
345                              copy_to_mode_reg (Pmode, XEXP (operands[0], 0)));
346   operands[1]
347     = replace_equiv_address (operands[1],
348                              copy_to_mode_reg (Pmode, XEXP (operands[1], 0)));
350   operands[5] = XEXP (operands[0], 0);
351   operands[6] = XEXP (operands[1], 0);
355 (define_insn "" ; "movmemhi"
356   [(set (mem:BLK (match_operand:HI 0 "general_operand" "=r,r"))
357         (mem:BLK (match_operand:HI 1 "general_operand" "r,r")))
358    (use (match_operand:HI 2 "arith_operand" "n,&r"))
359    (use (match_operand:HI 3 "immediate_operand" "i,i"))
360    (clobber (match_scratch:HI 4 "=&r,X"))
361    (clobber (match_dup 0))
362    (clobber (match_dup 1))
363    (clobber (match_dup 2))]
364   "(TARGET_BCOPY_BUILTIN)"
365   "* return output_block_move (operands);"
366 ;;; just a guess
367   [(set_attr "length" "40")])
368    
371 ;;- truncation instructions
373 (define_insn  "truncdfsf2"
374   [(set (match_operand:SF 0 "general_operand" "=r,R,Q")
375         (float_truncate:SF (match_operand:DF 1 "register_operand" "a,a,a")))]
376   "TARGET_FPU"
377   "* if (which_alternative ==0)
378      {
379        output_asm_insn(\"{stcdf|movfo} %1, -(sp)\", operands);
380        output_asm_insn(\"mov (sp)+, %0\", operands);
381        operands[0] = gen_rtx_REG (HImode, REGNO (operands[0])+1);
382        output_asm_insn(\"mov (sp)+, %0\", operands);
383        return \"\";
384      }
385      else if (which_alternative == 1)
386        return \"{stcdf|movfo} %1, %0\";
387      else 
388        return \"{stcdf|movfo} %1, %0\";
389   "
390   [(set_attr "length" "3,1,2")])
393 (define_expand "truncsihi2"
394   [(set (match_operand:HI 0 "general_operand" "=g")
395         (subreg:HI 
396           (match_operand:SI 1 "general_operand" "or")
397           0))]
398   ""
399   "")
402 ;;- zero extension instructions
404 (define_insn "zero_extendqihi2"
405   [(set (match_operand:HI 0 "general_operand" "=r")
406         (zero_extend:HI (match_operand:QI 1 "general_operand" "0")))]
407   ""
408   "bic $0177400, %0"
409   [(set_attr "length" "2")])
410                          
411 (define_expand "zero_extendhisi2"
412   [(set (subreg:HI 
413           (match_dup 0)
414           2)
415         (match_operand:HI 1 "register_operand" "r"))
416    (set (subreg:HI 
417           (match_operand:SI 0 "register_operand" "=r")
418           0)
419         (const_int 0))]
420   ""
421   "/* operands[1] = make_safe_from (operands[1], operands[0]); */")
424 ;;- sign extension instructions
426 (define_insn "extendsfdf2"
427   [(set (match_operand:DF 0 "register_operand" "=a,a,a")
428         (float_extend:DF (match_operand:SF 1 "general_operand" "r,R,Q")))]
429   "TARGET_FPU"
430   "@
431    mov %1, -(sp)\;{ldcfd|movof} (sp)+,%0
432    {ldcfd|movof} %1, %0
433    {ldcfd|movof} %1, %0"
434   [(set_attr "length" "2,1,2")])
436 ;; does movb sign extend in register-to-register move?
437 (define_insn "extendqihi2"
438   [(set (match_operand:HI 0 "register_operand" "=r,r")
439         (sign_extend:HI (match_operand:QI 1 "general_operand" "rR,Q")))]
440   ""
441   "movb %1, %0"
442   [(set_attr "length" "1,2")])
444 (define_insn "extendqisi2"
445   [(set (match_operand:SI 0 "register_operand" "=r,r")
446         (sign_extend:SI (match_operand:QI 1 "general_operand" "rR,Q")))]
447   "TARGET_40_PLUS"
448   "*
450   rtx latehalf[2];
452   /* make register pair available */
453   latehalf[0] = operands[0];
454   operands[0] = gen_rtx_REG (HImode, REGNO (operands[0])+ 1);
456   output_asm_insn(\"movb %1, %0\", operands);
457   output_asm_insn(\"sxt %0\", latehalf);
458     
459   return \"\";
461   [(set_attr "length" "2,3")])
463 ;; maybe we have to use define_expand to say that we have the instruction,
464 ;; unconditionally, and then match dependent on CPU type:
466 (define_expand "extendhisi2"
467   [(set (match_operand:SI 0 "general_operand" "=g")
468         (sign_extend:SI (match_operand:HI 1 "general_operand" "g")))]
469   ""
470   "")
471   
472 (define_insn "" ; "extendhisi2"
473   [(set (match_operand:SI 0 "general_operand" "=o,<,r")
474         (sign_extend:SI (match_operand:HI 1 "general_operand" "g,g,g")))]
475   "TARGET_40_PLUS"
476   "*
478   rtx latehalf[2];
480   /* we don't want to mess with auto increment */
481   
482   switch (which_alternative)
483   {
484     case 0:
486       latehalf[0] = operands[0];
487       operands[0] = adjust_address(operands[0], HImode, 2);
488   
489       output_asm_insn(\"mov %1, %0\", operands);
490       output_asm_insn(\"sxt %0\", latehalf);
492       return \"\";
494     case 1:
496       /* - auto-decrement - right direction ;-) */
497       output_asm_insn(\"mov %1, %0\", operands);
498       output_asm_insn(\"sxt %0\", operands);
500       return \"\";
502     case 2:
504       /* make register pair available */
505       latehalf[0] = operands[0];
506       operands[0] = gen_rtx_REG (HImode, REGNO (operands[0]) + 1);
508       output_asm_insn(\"mov %1, %0\", operands);
509       output_asm_insn(\"sxt %0\", latehalf);
511       return \"\";
513     default:
515       gcc_unreachable ();
516   }
518   [(set_attr "length" "5,3,3")])
521 (define_insn ""
522   [(set (match_operand:SI 0 "register_operand" "=r")
523         (sign_extend:SI (match_operand:HI 1 "general_operand" "0")))]
524   "(! TARGET_40_PLUS)"
525   "*
527   static int count = 0;
528   char buf[100];
529   rtx lateoperands[2];
531   lateoperands[0] = operands[0];
532   operands[0] = gen_rtx_REG (HImode, REGNO (operands[0]) + 1);
534   output_asm_insn(\"tst %0\", operands);
535   sprintf(buf, \"bge extendhisi%d\", count);
536   output_asm_insn(buf, NULL);
537   output_asm_insn(\"mov -1, %0\", lateoperands);
538   sprintf(buf, \"bne extendhisi%d\", count+1);
539   output_asm_insn(buf, NULL);
540   sprintf(buf, \"\\nextendhisi%d:\", count);
541   output_asm_insn(buf, NULL);
542   output_asm_insn(\"clr %0\", lateoperands);
543   sprintf(buf, \"\\nextendhisi%d:\", count+1);
544   output_asm_insn(buf, NULL);
546   count += 2;
548   return \"\";
550   [(set_attr "length" "6")])
552 ;; make float to int and vice versa 
553 ;; using the cc_status.flag field we could probably cut down
554 ;; on seti and setl
555 ;; assume that we are normally in double and integer mode -
556 ;; what do pdp library routines do to fpu mode ?
558 (define_insn "floatsidf2"
559   [(set (match_operand:DF 0 "register_operand" "=a,a,a")
560         (float:DF (match_operand:SI 1 "general_operand" "r,R,Q")))]
561   "TARGET_FPU"
562   "* if (which_alternative ==0)
563      {
564        rtx latehalf[2];
566        latehalf[0] = NULL; 
567        latehalf[1] = gen_rtx_REG (HImode, REGNO (operands[1]) + 1);
568        output_asm_insn(\"mov %1, -(sp)\", latehalf);
569        output_asm_insn(\"mov %1, -(sp)\", operands);
570        
571        output_asm_insn(\"setl\", operands);
572        output_asm_insn(\"{ldcld|movif} (sp)+, %0\", operands);
573        output_asm_insn(\"seti\", operands);
574        return \"\";
575      }
576      else if (which_alternative == 1)
577        return \"setl\;{ldcld|movif} %1, %0\;seti\";
578      else 
579        return \"setl\;{ldcld|movif} %1, %0\;seti\";
580   "
581   [(set_attr "length" "5,3,4")])
583 (define_insn "floathidf2"
584   [(set (match_operand:DF 0 "register_operand" "=a,a")
585         (float:DF (match_operand:HI 1 "general_operand" "rR,Qi")))]
586   "TARGET_FPU"
587   "{ldcid|movif} %1, %0"
588   [(set_attr "length" "1,2")])
589         
590 ;; cut float to int
591 (define_insn "fix_truncdfsi2"
592   [(set (match_operand:SI 0 "general_operand" "=r,R,Q")
593         (fix:SI (fix:DF (match_operand:DF 1 "register_operand" "a,a,a"))))]
594   "TARGET_FPU"
595   "* if (which_alternative ==0)
596      {
597        output_asm_insn(\"setl\", operands);
598        output_asm_insn(\"{stcdl|movfi} %1, -(sp)\", operands);
599        output_asm_insn(\"seti\", operands);
600        output_asm_insn(\"mov (sp)+, %0\", operands);
601        operands[0] = gen_rtx_REG (HImode, REGNO (operands[0]) + 1);
602        output_asm_insn(\"mov (sp)+, %0\", operands);
603        return \"\";
604      }
605      else if (which_alternative == 1)
606        return \"setl\;{stcdl|movfi} %1, %0\;seti\";
607      else 
608        return \"setl\;{stcdl|movfi} %1, %0\;seti\";
609   "
610   [(set_attr "length" "5,3,4")])
612 (define_insn "fix_truncdfhi2"
613   [(set (match_operand:HI 0 "general_operand" "=rR,Q")
614         (fix:HI (fix:DF (match_operand:DF 1 "register_operand" "a,a"))))]
615   "TARGET_FPU"
616   "{stcdi|movfi} %1, %0"
617   [(set_attr "length" "1,2")])
620 ;;- arithmetic instructions
621 ;;- add instructions
623 (define_insn "adddf3"
624   [(set (match_operand:DF 0 "register_operand" "=a,a,a")
625         (plus:DF (match_operand:DF 1 "register_operand" "%0,0,0")
626                  (match_operand:DF 2 "general_operand" "fR,Q,F")))]
627   "TARGET_FPU"
628   "{addd|addf} %2, %0"
629   [(set_attr "length" "1,2,5")])
631 (define_insn "addsi3"
632   [(set (match_operand:SI 0 "general_operand" "=r,r,o,o,r,r,r,o,o,o")
633         (plus:SI (match_operand:SI 1 "general_operand" "%0,0,0,0,0,0,0,0,0,0")
634                  (match_operand:SI 2 "general_operand" "r,o,r,o,I,J,K,I,J,K")))]
635   ""
636   "*
637 { /* Here we trust that operands don't overlap 
639      or is lateoperands the low word?? - looks like it! */
641   rtx lateoperands[3];
642   
643   lateoperands[0] = operands[0];
645   if (REG_P (operands[0]))
646     operands[0] = gen_rtx_REG (HImode, REGNO (operands[0]) + 1);
647   else
648     operands[0] = adjust_address (operands[0], HImode, 2);
649   
650   if (! CONSTANT_P(operands[2]))
651   {
652     lateoperands[2] = operands[2];
654     if (REG_P (operands[2]))
655       operands[2] = gen_rtx_REG (HImode, REGNO (operands[2]) + 1);
656     else
657       operands[2] = adjust_address (operands[2], HImode, 2);
659     output_asm_insn (\"add %2, %0\", operands);
660     output_asm_insn (\"adc %0\", lateoperands);
661     output_asm_insn (\"add %2, %0\", lateoperands);
662     return \"\";
663   }
665   lateoperands[2] = GEN_INT ((INTVAL (operands[2]) >> 16) & 0xffff);
666   operands[2] = GEN_INT (INTVAL (operands[2]) & 0xffff);
667   
668   if (INTVAL(operands[2]))
669   { 
670     output_asm_insn (\"add %2, %0\", operands);
671     output_asm_insn (\"adc %0\", lateoperands);
672   }
674   if (INTVAL(lateoperands[2]))
675     output_asm_insn (\"add %2, %0\", lateoperands);
677   return \"\";
679   [(set_attr "length" "3,5,6,8,3,1,5,5,3,8")])
681 (define_insn "addhi3"
682   [(set (match_operand:HI 0 "general_operand" "=rR,rR,Q,Q")
683         (plus:HI (match_operand:HI 1 "general_operand" "%0,0,0,0")
684                  (match_operand:HI 2 "general_operand" "rRLM,Qi,rRLM,Qi")))]
685   ""
686   "*
688   if (GET_CODE (operands[2]) == CONST_INT)
689     {
690       if (INTVAL(operands[2]) == 1)
691         return \"inc %0\";
692       else if (INTVAL(operands[2]) == -1)
693         return \"dec %0\";
694     }
696   return \"add %2, %0\";
698   [(set_attr "length" "1,2,2,3")])
700 (define_insn "addqi3"
701   [(set (match_operand:QI 0 "general_operand" "=rR,rR,Q,Q")
702         (plus:QI (match_operand:QI 1 "general_operand" "%0,0,0,0")
703                  (match_operand:QI 2 "general_operand" "rRLM,Qi,rRLM,Qi")))]
704   ""
705   "*
707   if (GET_CODE (operands[2]) == CONST_INT)
708     {
709       if (INTVAL(operands[2]) == 1)
710         return \"incb %0\";
711       else if (INTVAL(operands[2]) == -1)
712         return \"decb %0\";
713     }
715   return \"add %2, %0\";
717   [(set_attr "length" "1,2,2,3")])
720 ;;- subtract instructions
721 ;; we don't have to care for constant second 
722 ;; args, since they are canonical plus:xx now!
723 ;; also for minus:DF ??
725 (define_insn "subdf3"
726   [(set (match_operand:DF 0 "register_operand" "=a,a")
727         (minus:DF (match_operand:DF 1 "register_operand" "0,0")
728                   (match_operand:DF 2 "general_operand" "fR,Q")))]
729   "TARGET_FPU"
730   "{subd|subf} %2, %0"
731   [(set_attr "length" "1,2")])
733 (define_insn "subsi3"
734   [(set (match_operand:SI 0 "general_operand" "=r,r,o,o")
735         (minus:SI (match_operand:SI 1 "general_operand" "0,0,0,0")
736                   (match_operand:SI 2 "general_operand" "r,o,r,o")))]
737   ""
738   "*
739 { /* Here we trust that operands don't overlap 
741      or is lateoperands the low word?? - looks like it! */
743   rtx lateoperands[3];
744   
745   lateoperands[0] = operands[0];
747   if (REG_P (operands[0]))
748     operands[0] = gen_rtx_REG (HImode, REGNO (operands[0]) + 1);
749   else
750     operands[0] = adjust_address (operands[0], HImode, 2);
751   
752   lateoperands[2] = operands[2];
754   if (REG_P (operands[2]))
755     operands[2] = gen_rtx_REG (HImode, REGNO (operands[2]) + 1);
756   else
757     operands[2] = adjust_address (operands[2], HImode, 2);
759   output_asm_insn (\"sub %2, %0\", operands);
760   output_asm_insn (\"sbc %0\", lateoperands);
761   output_asm_insn (\"sub %2, %0\", lateoperands);
762   return \"\";
764 ;; offsettable memory addresses always are expensive!!!
765   [(set_attr "length" "3,5,6,8")])
767 (define_insn "subhi3"
768   [(set (match_operand:HI 0 "general_operand" "=rR,rR,Q,Q")
769         (minus:HI (match_operand:HI 1 "general_operand" "0,0,0,0")
770                   (match_operand:HI 2 "general_operand" "rR,Qi,rR,Qi")))]
771   ""
772   "*
774   gcc_assert (GET_CODE (operands[2]) != CONST_INT);
776   return \"sub %2, %0\";
778   [(set_attr "length" "1,2,2,3")])
780 (define_insn "subqi3"
781   [(set (match_operand:QI 0 "general_operand" "=rR,rR,Q,Q")
782         (minus:QI (match_operand:QI 1 "general_operand" "0,0,0,0")
783                   (match_operand:QI 2 "general_operand" "rR,Qi,rR,Qi")))]
784   ""
785   "*
787   gcc_assert (GET_CODE (operands[2]) != CONST_INT);
789   return \"sub %2, %0\";
791   [(set_attr "length" "1,2,2,3")])
793 ;;;;- and instructions
794 ;; Bit-and on the pdp (like on the VAX) is done with a clear-bits insn.
796 (define_insn "andsi3"
797   [(set (match_operand:SI 0 "general_operand" "=r,r,o,o,r,r,r,o,o,o")
798         (and:SI (match_operand:SI 1 "general_operand" "%0,0,0,0,0,0,0,0,0,0")
799                 (not:SI (match_operand:SI 2 "general_operand" "r,o,r,o,I,J,K,I,J,K"))))]
800   ""
801   "*
802 { /* Here we trust that operands don't overlap 
804      or is lateoperands the low word?? - looks like it! */
806   rtx lateoperands[3];
807   
808   lateoperands[0] = operands[0];
810   if (REG_P (operands[0]))
811     operands[0] = gen_rtx_REG (HImode, REGNO (operands[0]) + 1);
812   else
813     operands[0] = adjust_address (operands[0], HImode, 2);
814   
815   if (! CONSTANT_P(operands[2]))
816   {
817     lateoperands[2] = operands[2];
819     if (REG_P (operands[2]))
820       operands[2] = gen_rtx_REG (HImode, REGNO (operands[2]) + 1);
821     else
822       operands[2] = adjust_address (operands[2], HImode, 2);
824     output_asm_insn (\"bic %2, %0\", operands);
825     output_asm_insn (\"bic %2, %0\", lateoperands);
826     return \"\";
827   }
829   lateoperands[2] = GEN_INT ((INTVAL (operands[2]) >> 16) & 0xffff);
830   operands[2] = GEN_INT (INTVAL (operands[2]) & 0xffff);
831   
832   /* these have different lengths, so we should have 
833      different constraints! */
834   if (INTVAL(operands[2]))
835     output_asm_insn (\"bic %2, %0\", operands);
837   if (INTVAL(lateoperands[2]))
838     output_asm_insn (\"bic %2, %0\", lateoperands);
840   return \"\";
842   [(set_attr "length" "2,4,4,6,2,2,4,3,3,6")])
844 (define_insn "andhi3"
845   [(set (match_operand:HI 0 "general_operand" "=rR,rR,Q,Q")
846         (and:HI (match_operand:HI 1 "general_operand" "0,0,0,0")
847                 (not:HI (match_operand:HI 2 "general_operand" "rR,Qi,rR,Qi"))))]
848   ""
849   "bic %2, %0"
850   [(set_attr "length" "1,2,2,3")])
852 (define_insn "andqi3"
853   [(set (match_operand:QI 0 "general_operand" "=rR,rR,Q,Q")
854         (and:QI (match_operand:QI 1 "general_operand" "0,0,0,0")
855                 (not:QI (match_operand:QI 2 "general_operand" "rR,Qi,rR,Qi"))))]
856   ""
857   "bicb %2, %0"
858   [(set_attr "length" "1,2,2,3")])
860 ;;- Bit set (inclusive or) instructions
861 (define_insn "iorsi3"
862   [(set (match_operand:SI 0 "general_operand" "=r,r,o,o,r,r,r,o,o,o")
863         (ior:SI (match_operand:SI 1 "general_operand" "%0,0,0,0,0,0,0,0,0,0")
864                   (match_operand:SI 2 "general_operand" "r,o,r,o,I,J,K,I,J,K")))]
865   ""
866   "*
867 { /* Here we trust that operands don't overlap 
869      or is lateoperands the low word?? - looks like it! */
871   rtx lateoperands[3];
872   
873   lateoperands[0] = operands[0];
875   if (REG_P (operands[0]))
876     operands[0] = gen_rtx_REG (HImode, REGNO (operands[0]) + 1);
877   else
878     operands[0] = adjust_address (operands[0], HImode, 2);
879   
880   if (! CONSTANT_P(operands[2]))
881     {
882       lateoperands[2] = operands[2];
884       if (REG_P (operands[2]))
885         operands[2] = gen_rtx_REG (HImode, REGNO (operands[2]) + 1);
886       else
887         operands[2] = adjust_address (operands[2], HImode, 2);
889       output_asm_insn (\"bis %2, %0\", operands);
890       output_asm_insn (\"bis %2, %0\", lateoperands);
891       return \"\";
892     }
894   lateoperands[2] = GEN_INT ((INTVAL (operands[2]) >> 16) & 0xffff);
895   operands[2] = GEN_INT (INTVAL (operands[2]) & 0xffff);
896   
897   /* these have different lengths, so we should have 
898      different constraints! */
899   if (INTVAL(operands[2]))
900     output_asm_insn (\"bis %2, %0\", operands);
902   if (INTVAL(lateoperands[2]))
903     output_asm_insn (\"bis %2, %0\", lateoperands);
905   return \"\";
907   [(set_attr "length" "2,4,4,6,2,2,4,3,3,6")])
909 (define_insn "iorhi3"
910   [(set (match_operand:HI 0 "general_operand" "=rR,rR,Q,Q")
911         (ior:HI (match_operand:HI 1 "general_operand" "%0,0,0,0")
912                 (match_operand:HI 2 "general_operand" "rR,Qi,rR,Qi")))]
913   ""
914   "bis %2, %0"
915   [(set_attr "length" "1,2,2,3")])
917 (define_insn "iorqi3"
918   [(set (match_operand:QI 0 "general_operand" "=rR,rR,Q,Q")
919         (ior:QI (match_operand:QI 1 "general_operand" "%0,0,0,0")
920                 (match_operand:QI 2 "general_operand" "rR,Qi,rR,Qi")))]
921   ""
922   "bisb %2, %0")
924 ;;- xor instructions
925 (define_insn "xorsi3"
926   [(set (match_operand:SI 0 "register_operand" "=r")
927         (xor:SI (match_operand:SI 1 "register_operand" "%0")
928                 (match_operand:SI 2 "arith_operand" "r")))]
929   "TARGET_40_PLUS"
930   "*
931 { /* Here we trust that operands don't overlap */
933   rtx lateoperands[3];
935   lateoperands[0] = operands[0];
936   operands[0] = gen_rtx_REG (HImode, REGNO (operands[0]) + 1);
938   if (REG_P(operands[2]))
939     {
940       lateoperands[2] = operands[2];
941       operands[2] = gen_rtx_REG (HImode, REGNO (operands[2]) + 1);
943       output_asm_insn (\"xor %2, %0\", operands);
944       output_asm_insn (\"xor %2, %0\", lateoperands);
946       return \"\";
947     }
950   [(set_attr "length" "2")])
952 (define_insn "xorhi3"
953   [(set (match_operand:HI 0 "general_operand" "=rR,Q")
954         (xor:HI (match_operand:HI 1 "general_operand" "%0,0")
955                 (match_operand:HI 2 "register_operand" "r,r")))]
956   "TARGET_40_PLUS"
957   "xor %2, %0"
958   [(set_attr "length" "1,2")])
960 ;;- one complement instructions
962 (define_insn "one_cmplhi2"
963   [(set (match_operand:HI 0 "general_operand" "=rR,Q")
964         (not:HI (match_operand:HI 1 "general_operand" "0,0")))]
965   ""
966   "com %0"
967   [(set_attr "length" "1,2")])
969 (define_insn "one_cmplqi2"
970   [(set (match_operand:QI 0 "general_operand" "=rR,rR")
971         (not:QI (match_operand:QI 1 "general_operand" "0,g")))]
972   ""
973   "@
974   comb %0
975   movb %1, %0\; comb %0"
976   [(set_attr "length" "1,2")])
978 ;;- arithmetic shift instructions
979 (define_insn "ashlsi3"
980   [(set (match_operand:SI 0 "register_operand" "=r,r")
981         (ashift:SI (match_operand:SI 1 "register_operand" "0,0")
982                    (match_operand:HI 2 "general_operand" "rR,Qi")))]
983   "TARGET_45"
984   "ashc %2,%0"
985   [(set_attr "length" "1,2")])
987 ;; Arithmetic right shift on the pdp works by negating the shift count.
988 (define_expand "ashrsi3"
989   [(set (match_operand:SI 0 "register_operand" "=r")
990         (ashift:SI (match_operand:SI 1 "register_operand" "0")
991                    (match_operand:HI 2 "general_operand" "g")))]
992   ""
993   "
995   operands[2] = negate_rtx (HImode, operands[2]);
998 ;; define asl aslb asr asrb - ashc missing!
1000 ;; asl 
1001 (define_insn "" 
1002   [(set (match_operand:HI 0 "general_operand" "=rR,Q")
1003         (ashift:HI (match_operand:HI 1 "general_operand" "0,0")
1004                    (const_int 1)))]
1005   ""
1006   "asl %0"
1007   [(set_attr "length" "1,2")])
1009 ;; and another possibility for asr is << -1
1010 ;; might cause problems since -1 can also be encoded as 65535!
1011 ;; not in gcc2 ??? 
1013 ;; asr
1014 (define_insn "" 
1015   [(set (match_operand:HI 0 "general_operand" "=rR,Q")
1016         (ashift:HI (match_operand:HI 1 "general_operand" "0,0")
1017                    (const_int -1)))]
1018   ""
1019   "asr %0"
1020   [(set_attr "length" "1,2")])
1022 ;; lsr
1023 (define_insn "" 
1024   [(set (match_operand:HI 0 "general_operand" "=rR,Q")
1025         (lshiftrt:HI (match_operand:HI 1 "general_operand" "0,0")
1026                    (const_int 1)))]
1027   ""
1028   "clc\;ror %0"
1029   [(set_attr "length" "1,2")])
1031 (define_insn "lshrsi3"
1032   [(set (match_operand:SI 0 "register_operand" "=r")
1033         (lshiftrt:SI (match_operand:SI 1 "general_operand" "0")
1034                    (const_int 1)))]
1035   ""
1038   rtx lateoperands[2];
1040   lateoperands[0] = operands[0];
1041   operands[0] = gen_rtx_REG (HImode, REGNO (operands[0]) + 1);
1043   lateoperands[1] = operands[1];
1044   operands[1] = gen_rtx_REG (HImode, REGNO (operands[1]) + 1);
1046   output_asm_insn (\"clc\", operands);
1047   output_asm_insn (\"ror %0\", lateoperands);
1048   output_asm_insn (\"ror %0\", operands);
1050   return \"\";
1052   [(set_attr "length" "5")])
1054 ;; shift is by arbitrary count is expensive, 
1055 ;; shift by one cheap - so let's do that, if
1056 ;; space doesn't matter
1057 (define_insn "" 
1058   [(set (match_operand:HI 0 "general_operand" "=r")
1059         (ashift:HI (match_operand:HI 1 "general_operand" "0")
1060                    (match_operand:HI 2 "expand_shift_operand" "O")))]
1061   "! optimize_size"
1062   "*
1064   register int i;
1066   for (i = 1; i <= abs(INTVAL(operands[2])); i++)
1067     if (INTVAL(operands[2]) < 0)
1068       output_asm_insn(\"asr %0\", operands);
1069     else
1070       output_asm_insn(\"asl %0\", operands);
1071       
1072   return \"\";
1074 ;; longest is 4
1075   [(set (attr "length") (const_int 4))])
1077 ;; aslb
1078 (define_insn "" 
1079   [(set (match_operand:QI 0 "general_operand" "=r,o")
1080         (ashift:QI (match_operand:QI 1 "general_operand" "0,0")
1081                    (match_operand:HI 2 "const_immediate_operand" "n,n")))]
1082   ""
1083   "*
1084 { /* allowing predec or post_inc is possible, but hairy! */
1085   int i, cnt;
1087   cnt = INTVAL(operands[2]) & 0x0007;
1089   for (i=0 ; i < cnt ; i++)
1090        output_asm_insn(\"aslb %0\", operands);
1092   return \"\";
1094 ;; set attribute length ( match_dup 2 & 7 ) *(1 or 2) !!!
1095   [(set_attr_alternative "length" 
1096                          [(const_int 7)
1097                           (const_int 14)])])
1099 ;;; asr 
1100 ;(define_insn "" 
1101 ;  [(set (match_operand:HI 0 "general_operand" "=rR,Q")
1102 ;       (ashiftrt:HI (match_operand:HI 1 "general_operand" "0,0")
1103 ;                    (const_int 1)))]
1104 ;  ""
1105 ;  "asr %0"
1106 ;  [(set_attr "length" "1,2")])
1108 ;; asrb
1109 (define_insn "" 
1110   [(set (match_operand:QI 0 "general_operand" "=r,o")
1111         (ashiftrt:QI (match_operand:QI 1 "general_operand" "0,0")
1112                      (match_operand:HI 2 "const_immediate_operand" "n,n")))]
1113   ""
1114   "*
1115 { /* allowing predec or post_inc is possible, but hairy! */
1116   int i, cnt;
1118   cnt = INTVAL(operands[2]) & 0x0007;
1120   for (i=0 ; i < cnt ; i++)
1121        output_asm_insn(\"asrb %0\", operands);
1123   return \"\";
1125   [(set_attr_alternative "length" 
1126                          [(const_int 7)
1127                           (const_int 14)])])
1129 ;; the following is invalid - too complex!!! - just say 14 !!!
1130 ;  [(set (attr "length") (plus (and (match_dup 2)
1131 ;                                   (const_int 7))
1132 ;                              (and (match_dup 2)
1133 ;                                   (const_int 7))))])
1137 ;; can we get +-1 in the next pattern? should 
1138 ;; have been caught by previous patterns!
1140 (define_insn "ashlhi3"
1141   [(set (match_operand:HI 0 "register_operand" "=r,r")
1142         (ashift:HI (match_operand:HI 1 "register_operand" "0,0")
1143                    (match_operand:HI 2 "general_operand" "rR,Qi")))]
1144   ""
1145   "*
1147   if (GET_CODE(operands[2]) == CONST_INT)
1148     {
1149       if (INTVAL(operands[2]) == 1)
1150         return \"asl %0\";
1151       else if (INTVAL(operands[2]) == -1)
1152         return \"asr %0\";
1153     }
1155   return \"ash %2,%0\";
1157   [(set_attr "length" "1,2")])
1159 ;; Arithmetic right shift on the pdp works by negating the shift count.
1160 (define_expand "ashrhi3"
1161   [(set (match_operand:HI 0 "register_operand" "=r")
1162         (ashift:HI (match_operand:HI 1 "register_operand" "0")
1163                    (match_operand:HI 2 "general_operand" "g")))]
1164   ""
1165   "
1167   operands[2] = negate_rtx (HImode, operands[2]);
1170 ;;;;- logical shift instructions
1171 ;;(define_insn "lshrsi3"
1172 ;;  [(set (match_operand:HI 0 "register_operand" "=r")
1173 ;;      (lshiftrt:HI (match_operand:HI 1 "register_operand" "0")
1174 ;;                   (match_operand:HI 2 "arith_operand" "rI")))]
1175 ;;  ""
1176 ;;  "srl %0,%2")
1178 ;; absolute 
1180 (define_insn "absdf2"
1181   [(set (match_operand:DF 0 "general_operand" "=fR,Q")
1182         (abs:DF (match_operand:DF 1 "general_operand" "0,0")))]
1183   "TARGET_FPU"
1184   "{absd|absf} %0"
1185   [(set_attr "length" "1,2")])
1187 (define_insn "abshi2"
1188   [(set (match_operand:HI 0 "general_operand" "=r,o")
1189         (abs:HI (match_operand:HI 1 "general_operand" "0,0")))]
1190   "TARGET_ABSHI_BUILTIN"
1191   "*
1193   static int count = 0;
1194   char buf[200];
1195         
1196   output_asm_insn(\"tst %0\", operands);
1197   sprintf(buf, \"bge abshi%d\", count);
1198   output_asm_insn(buf, NULL);
1199   output_asm_insn(\"neg %0\", operands);
1200   sprintf(buf, \"\\nabshi%d:\", count++);
1201   output_asm_insn(buf, NULL);
1203   return \"\";
1205   [(set_attr "length" "3,5")])
1208 ;; define expand abshi - is much better !!! - but
1209 ;; will it be optimized into an abshi2 ?
1210 ;; it will leave better code, because the tsthi might be 
1211 ;; optimized away!!
1212 ; -- just a thought - don't have time to check 
1214 ;(define_expand "abshi2"
1215 ;  [(match_operand:HI 0 "general_operand" "")
1216 ;   (match_operand:HI 1 "general_operand" "")]
1217 ;  ""
1218 ;  "
1220 ;  rtx label = gen_label_rtx ();
1222 ;  /* do I need this? */
1223 ;  do_pending_stack_adjust ();
1225 ;  emit_move_insn (operands[0], operands[1]);
1227 ;  emit_insn (gen_tsthi (operands[0]));
1228 ;  emit_insn (gen_bge (label1));
1230 ;  emit_insn (gen_neghi(operands[0], operands[0])
1231 ;  
1232 ;  emit_barrier ();
1234 ;  emit_label (label);
1236 ;  /* allow REG_NOTES to be set on last insn (labels don't have enough
1237 ;     fields, and can't be used for REG_NOTES anyway).  */
1238 ;  emit_use (stack_pointer_rtx);
1239 ;  DONE;
1240 ;}")
1242 ;; negate insns
1244 (define_insn "negdf2"
1245   [(set (match_operand:DF 0 "general_operand" "=fR,Q")
1246         (neg:DF (match_operand:DF 1 "register_operand" "0,0")))]
1247   "TARGET_FPU"
1248   "{negd|negf} %0"
1249   [(set_attr "length" "1,2")])
1251 (define_insn "negsi2"
1252   [(set (match_operand:SI 0 "register_operand" "=r")
1253         (neg:SI (match_operand:SI 1 "general_operand" "0")))]
1254   ""
1257   rtx lateoperands[2];
1259   lateoperands[0] = operands[0];
1260   operands[0] = gen_rtx_REG (HImode, REGNO (operands[0]) + 1);
1262   lateoperands[1] = operands[1];
1263   operands[1] = gen_rtx_REG (HImode, REGNO (operands[1]) + 1);
1265   output_asm_insn (\"com %0\", operands);
1266   output_asm_insn (\"com %0\", lateoperands);
1267   output_asm_insn (\"inc %0\", operands);
1268   output_asm_insn (\"adc %0\", lateoperands);
1270   return \"\";
1272   [(set_attr "length" "5")])
1274 (define_insn "neghi2"
1275   [(set (match_operand:HI 0 "general_operand" "=rR,Q")
1276         (neg:HI (match_operand:HI 1 "general_operand" "0,0")))]
1277   ""
1278   "neg %0"
1279   [(set_attr "length" "1,2")])
1281 (define_insn "negqi2"
1282   [(set (match_operand:QI 0 "general_operand" "=rR,Q")
1283         (neg:QI (match_operand:QI 1 "general_operand" "0,0")))]
1284   ""
1285   "negb %0"
1286   [(set_attr "length" "1,2")])
1289 ;; Unconditional and other jump instructions
1290 (define_insn "jump"
1291   [(set (pc)
1292         (label_ref (match_operand 0 "" "")))]
1293   ""
1294   "jmp %l0"
1295   [(set_attr "length" "2")])
1297 (define_insn ""
1298   [(set (pc)
1299     (label_ref (match_operand 0 "" "")))
1300    (clobber (const_int 1))]
1301   ""
1302   "jmp %l0"
1303   [(set_attr "length" "2")])
1305 (define_insn "tablejump"
1306   [(set (pc) (match_operand:HI 0 "general_operand" "rR,Q"))
1307    (use (label_ref (match_operand 1 "" "")))]
1308   ""
1309   "jmp %0"
1310   [(set_attr "length" "1,2")])
1312 ;; indirect jump - let's be conservative!
1313 ;; allow only register_operand, even though we could also 
1314 ;; allow labels etc.
1316 (define_insn "indirect_jump"
1317   [(set (pc) (match_operand:HI 0 "register_operand" "r"))]
1318   ""
1319   "jmp (%0)")
1321 ;;- jump to subroutine
1323 (define_insn "call"
1324   [(call (match_operand:HI 0 "general_operand" "rR,Q")
1325          (match_operand:HI 1 "general_operand" "g,g"))
1326 ;;   (use (reg:HI 0)) what was that ???
1327   ]
1328   ;;- Don't use operand 1 for most machines.
1329   ""
1330   "jsr pc, %0"
1331   [(set_attr "length" "1,2")])
1333 ;;- jump to subroutine
1334 (define_insn "call_value"
1335   [(set (match_operand 0 "" "")
1336         (call (match_operand:HI 1 "general_operand" "rR,Q")
1337               (match_operand:HI 2 "general_operand" "g,g")))
1338 ;;   (use (reg:HI 0)) - what was that ????
1339   ]
1340   ;;- Don't use operand 2 for most machines.
1341   ""
1342   "jsr pc, %1"
1343   [(set_attr "length" "1,2")])
1345 ;;- nop instruction
1346 (define_insn "nop"
1347   [(const_int 0)]
1348   ""
1349   "nop")
1352 ;;- multiply 
1354 (define_insn "muldf3"
1355   [(set (match_operand:DF 0 "register_operand" "=a,a,a")
1356         (mult:DF (match_operand:DF 1 "register_operand" "%0,0,0")
1357                  (match_operand:DF 2 "general_operand" "fR,Q,F")))]
1358   "TARGET_FPU"
1359   "{muld|mulf} %2, %0"
1360   [(set_attr "length" "1,2,5")])
1362 ;; 16 bit result multiply:
1363 ;; currently we multiply only into odd registers, so we don't use two 
1364 ;; registers - but this is a bit inefficient at times. If we define 
1365 ;; a register class for each register, then we can specify properly 
1366 ;; which register need which scratch register ....
1368 (define_insn "mulhi3"
1369   [(set (match_operand:HI 0 "register_operand" "=d,d") ; multiply regs
1370         (mult:HI (match_operand:HI 1 "register_operand" "%0,0")
1371                  (match_operand:HI 2 "general_operand" "rR,Qi")))]
1372   "TARGET_45"
1373   "mul %2, %0"
1374   [(set_attr "length" "1,2")])
1376 ;; 32 bit result
1377 (define_expand "mulhisi3"
1378   [(set (match_dup 3)
1379         (match_operand:HI 1 "general_operand" "g,g"))
1380    (set (match_operand:SI 0 "register_operand" "=r,r") ; even numbered!
1381         (mult:SI (truncate:HI 
1382                   (match_dup 0))
1383                  (match_operand:HI 2 "general_operand" "rR,Qi")))]
1384   "TARGET_45"
1385   "operands[3] = gen_lowpart(HImode, operands[1]);")
1387 (define_insn ""
1388   [(set (match_operand:SI 0 "register_operand" "=r,r") ; even numbered!
1389         (mult:SI (truncate:HI 
1390                   (match_operand:SI 1 "register_operand" "%0,0"))
1391                  (match_operand:HI 2 "general_operand" "rR,Qi")))]
1392   "TARGET_45"
1393   "mul %2, %0"
1394   [(set_attr "length" "1,2")])
1396 ;(define_insn "mulhisi3"
1397 ;  [(set (match_operand:SI 0 "register_operand" "=r,r") ; even numbered!
1398 ;       (mult:SI (truncate:HI 
1399 ;                  (match_operand:SI 1 "register_operand" "%0,0"))
1400 ;                (match_operand:HI 2 "general_operand" "rR,Qi")))]
1401 ;  "TARGET_45"
1402 ;  "mul %2, %0"
1403 ;  [(set_attr "length" "1,2")])
1405 ;;- divide
1406 (define_insn "divdf3"
1407   [(set (match_operand:DF 0 "register_operand" "=a,a,a")
1408         (div:DF (match_operand:DF 1 "register_operand" "0,0,0")
1409                 (match_operand:DF 2 "general_operand" "fR,Q,F")))]
1410   "TARGET_FPU"
1411   "{divd|divf} %2, %0"
1412   [(set_attr "length" "1,2,5")])
1414          
1415 (define_expand "divhi3"
1416   [(set (subreg:HI (match_dup 1) 0)
1417         (div:HI (match_operand:SI 1 "general_operand" "0")
1418                 (match_operand:HI 2 "general_operand" "g")))
1419    (set (match_operand:HI 0 "general_operand" "=r")
1420         (subreg:HI (match_dup 1) 0))]
1421   "TARGET_45"
1422   "")
1424 (define_insn ""
1425   [(set (subreg:HI (match_operand:SI 0 "general_operand" "=r") 0)
1426         (div:HI (match_operand:SI 1 "general_operand" "0")
1427                 (match_operand:HI 2 "general_operand" "g")))]
1428   "TARGET_45"
1429   "div %2,%0"
1430   [(set_attr "length" "2")])
1432 (define_expand "modhi3"
1433   [(set (subreg:HI (match_dup 1) 2)
1434         (mod:HI (match_operand:SI 1 "general_operand" "0")
1435                 (match_operand:HI 2 "general_operand" "g")))
1436    (set (match_operand:HI 0 "general_operand" "=r")
1437         (subreg:HI (match_dup 1) 2))]
1438   "TARGET_45"
1439   "")
1441 (define_insn ""
1442   [(set (subreg:HI (match_operand:SI 0 "general_operand" "=r") 2)
1443         (mod:HI (match_operand:SI 1 "general_operand" "0")
1444                 (match_operand:HI 2 "general_operand" "g")))]
1445   "TARGET_45"
1446   "div %2,%0"
1447   [(set_attr "length" "2")])
1449 ;(define_expand "divmodhi4"
1450 ;  [(parallel [(set (subreg:HI (match_dup 1) 0)
1451 ;                  (div:HI (match_operand:SI 1 "general_operand" "0")
1452 ;                          (match_operand:HI 2 "general_operand" "g")))
1453 ;              (set (subreg:HI (match_dup 1) 2)
1454 ;                  (mod:HI (match_dup 1)
1455 ;                          (match_dup 2)))])
1456 ;   (set (match_operand:HI 3 "general_operand" "=r")
1457 ;        (subreg:HI (match_dup 1) 2))
1458 ;   (set (match_operand:HI 0 "general_operand" "=r")
1459 ;        (subreg:HI (match_dup 1) 0))]
1460 ;  "TARGET_45"
1461 ;  "")
1463 ;(define_insn ""
1464 ;  [(set (subreg:HI (match_operand:SI 0 "general_operand" "=r") 0)
1465 ;                  (div:HI (match_operand:SI 1 "general_operand" "0")
1466 ;                          (match_operand:HI 2 "general_operand" "g")))
1467 ;   (set (subreg:HI (match_dup 0) 2)
1468 ;                  (mod:HI (match_dup 1)
1469 ;                          (match_dup 2)))]
1470 ;  "TARGET_45"
1471 ;  "div %2, %0")
1473    
1474 ;; is rotate doing the right thing to be included here ????