OSDN Git Service

* i370.c (mvs_add_label): Change spacing for coding conventions.
[pf3gnuchains/gcc-fork.git] / gcc / config / i370 / i370.md
1 ;;- Machine description for GNU compiler -- System/370 version.
2 ;;  Copyright (C) 1989, 1993, 1994, 1995, 1997, 1998, 1999, 2000
3 ;;  Free Software Foundation, Inc.
4 ;;  Contributed by Jan Stein (jan@cd.chalmers.se).
5 ;;  Modified for OS/390 LanguageEnvironment C by Dave Pitts (dpitts@cozx.com)
6 ;;  Lots of Bug Fixes & Enhancements by Linas Vepstas (linas@linas.org)
7
8 ;; This file is part of GNU CC.
9
10 ;; GNU CC is free software; you can redistribute it and/or modify
11 ;; it under the terms of the GNU General Public License as published by
12 ;; the Free Software Foundation; either version 2, or (at your option)
13 ;; any later version.
14
15 ;; GNU CC is distributed in the hope that it will be useful,
16 ;; but WITHOUT ANY WARRANTY; without even the implied warranty of
17 ;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
18 ;; GNU General Public License for more details.
19
20 ;; You should have received a copy of the GNU General Public License
21 ;; along with GNU CC; see the file COPYING.  If not, write to
22 ;; the Free Software Foundation, 59 Temple Place - Suite 330,
23 ;; Boston, MA 02111-1307, USA.
24
25 ;; =======================================================================
26 ;; Condition codes for some of the instructions (in particular, for 
27 ;; add, sub, shift, abs, etc. are handled with the cpp macro NOTICE_UPDATE_CC 
28 ;;
29 ;; Special constraints for 370 machine description:
30 ;;
31 ;;    a -- Any address register from 1 to 15.
32 ;;    d -- Any register from 0 to 15.
33 ;;    I -- An 8-bit constant (0..255).
34 ;;    J -- A 12-bit constant (0..4095).
35 ;;    K -- A 16-bit constant (-32768..32767).
36 ;;    R -- a valid S operand in an RS, SI or SS instruction, or register
37 ;;    S -- a valid S operand in an RS, SI or SS instruction
38 ;;
39 ;; Note this well: 
40 ;; When defining an instruction, e.g. the movsi pattern:
41 ;; 
42 ;;    (define_insn ""
43 ;;        [(set (match_operand:SI 0 "r_or_s_operand" "=dm,d,dm")
44 ;;            (match_operand:SI 1 "r_or_s_operand" "diR,dim,*fF"))]
45 ;;
46 ;; The "r_or_s_operand" predicate is used to recognize the instruction;
47 ;; however, it is not further used to enforce a constraint at later stages.
48 ;; Thus, for example, although "r_or_s_operand" bars operands of the form
49 ;; base+index+displacement, such operands can none-the-less show up during
50 ;; post-instruction-recog processing: thus, for example, garbage like
51 ;; MVC     152(4,r13),0(r5,r13) might be generated if both op0 and op1 are 
52 ;; mem operands.   To avoid this, use the S constraint.
53 ;; 
54 ;;
55 ;; Special formats used for outputting 370 instructions.
56 ;;
57 ;;   %B -- Print a constant byte integer.
58 ;;   %H -- Print a signed 16-bit constant.
59 ;;   %K -- Print a signed 16-bit constant signed-extended to 32-bits.
60 ;;   %L -- Print least significant word of a CONST_DOUBLE.
61 ;;   %M -- Print most significant word of a CONST_DOUBLE.
62 ;;   %N -- Print next register (second word of a DImode reg).
63 ;;   %O -- Print the offset of a memory reference (PLUS (REG) (CONST_INT)).
64 ;;   %R -- Print the register of a memory reference (PLUS (REG) (CONST_INT)).
65 ;;   %X -- Print a constant byte integer in hex.
66 ;;   %W -- Print a signed 32-bit int sign-extended to 64-bits.
67 ;;
68 ;; We have a special constraint for pattern matching.
69 ;;
70 ;;   s_operand -- Matches a valid S operand in a RS, SI or SS type instruction.
71 ;;
72 ;;   r_or_s_operand -- Matches a register or a valid S operand in a RS, SI
73 ;;                     or SS type instruction or a register
74 ;;
75 ;; For MVS C/370 we use the following stack locations for:
76 ;;
77 ;;   136 - internal function result buffer
78 ;;   140 - numeric conversion buffer
79 ;;   144 - pointer to internal function result buffer
80 ;;   148 - start of automatic variables and function arguments
81 ;;
82 ;; To support programs larger than a page, 4096 bytes, PAGE_REGISTER points
83 ;; to a page origin table, all internal labels are generated to reload the
84 ;; BASE_REGISTER knowing what page it is on and all branch instructions go
85 ;; directly to the target if it is known that the target is on the current
86 ;; page (essentially backward references).  All forward references and off
87 ;; page references are handled by loading the address of target into a
88 ;; register and branching indirectly.
89 ;;
90 ;; Some *di patterns have been commented out per advice from RMS, as gcc
91 ;; will generate the right things to do.
92 ;;
93 ;; See the note in i370.h about register 14, clobbering it, and optimization.
94 ;; Basically, using clobber in egcs-1.1.1 will ruin ability to optimize around
95 ;; branches, so don't do it.
96 ;;
97 ;; We use the "length" attirbute to store the max possible code size of an
98 ;; insn.  We use this length to estimate the length of forward branches, to
99 ;; determine if they're on page or off.
100
101 (define_attr "length" "" (const_int 0))
102
103 ;;
104 ;;- Test instructions.
105 ;;
106
107 ;
108 ; tstdi instruction pattern(s).
109 ;
110
111 (define_insn "tstdi"
112   [(set (cc0)
113         (match_operand:DI 0 "register_operand" "d"))]
114   ""
115   "*
116 {
117   check_label_emit ();
118   mvs_check_page (0, 4, 0);
119   return \"SRDA %0,0\";
120 }"
121    [(set_attr "length" "4")]
122 )
123
124 ;
125 ; tstsi instruction pattern(s).
126 ;
127
128 (define_insn "tstsi"
129   [(set (cc0)
130         (match_operand:SI 0 "register_operand" "d"))]
131   ""
132   "*
133 {
134   check_label_emit ();
135   mvs_check_page (0, 2, 0);
136   return \"LTR  %0,%0\";
137 }"
138    [(set_attr "length" "2")]
139 )
140
141 ;
142 ; tsthi instruction pattern(s).
143 ;
144
145 (define_insn "tsthi"
146   [(set (cc0)
147         (match_operand:HI 0 "register_operand" "d"))]
148   ""
149   "*
150 {
151   check_label_emit ();
152   mvs_check_page (0, 4, 2);
153   return \"CH   %0,=H'0'\";
154 }"
155    [(set_attr "length" "4")]
156 )
157
158 ;
159 ; tstqi instruction pattern(s).
160 ;
161
162 (define_insn ""
163   [(set (cc0)
164         (match_operand:QI 0 "r_or_s_operand" "dm"))]
165   "unsigned_jump_follows_p (insn)"
166   "*
167 {
168   check_label_emit ();
169   if (REG_P (operands[0]))
170     {
171       /* an unsigned compare to zero is always zero/not-zero... */
172       mvs_check_page (0, 4, 4);
173       return \"N        %0,=XL4'000000FF'\";
174     }
175   mvs_check_page (0, 4, 0);
176   return \"CLI  %0,0\";
177 }"
178    [(set_attr "length" "4")]
179 )
180
181 (define_insn "tstqi"
182   [(set (cc0)
183      (match_operand:QI 0 "register_operand" "d"))]
184   ""
185   "*
186 {
187   check_label_emit ();
188   if (unsigned_jump_follows_p (insn))
189     {
190       /* an unsigned compare to zero is always zero/not-zero... */
191       mvs_check_page (0, 4, 4);
192       return \"N        %0,=XL4'000000FF'\";
193     }
194   mvs_check_page (0, 8, 0);
195   return \"SLL  %0,24\;SRA      %0,24\";
196 }"
197    [(set_attr "length" "8")]
198 )
199
200 ;
201 ; tstdf instruction pattern(s).
202 ;
203
204 (define_insn "tstdf"
205   [(set (cc0)
206         (match_operand:DF 0 "general_operand" "f"))]
207   ""
208   "*
209 {
210   check_label_emit ();
211   mvs_check_page (0, 2, 0);
212   return \"LTDR %0,%0\";
213 }"
214    [(set_attr "length" "2")]
215 )
216
217 ;
218 ; tstsf instruction pattern(s).
219 ;
220
221 (define_insn "tstsf"
222   [(set (cc0)
223         (match_operand:SF 0 "general_operand" "f"))]
224   ""
225   "*
226 {
227   check_label_emit ();
228   mvs_check_page (0, 2, 0);
229   return \"LTER %0,%0\";
230 }"
231    [(set_attr "length" "2")]
232 )
233
234 ;;
235 ;;- Compare instructions.
236 ;;
237
238 ;
239 ; cmpdi instruction pattern(s).
240 ;
241
242 ;(define_insn "cmpdi"
243 ;  [(set (cc0)
244 ;       (compare (match_operand:DI 0 "register_operand" "d")
245 ;                (match_operand:DI 1 "general_operand" "")))]
246 ;  ""
247 ;  "*
248 ;{
249 ;  check_label_emit ();
250 ;  if (REG_P (operands[1]))
251 ;    {
252 ;      mvs_check_page (0, 8, 0);
253 ;      if (unsigned_jump_follows_p (insn))
254 ;        return \"CLR   %0,%1\;BNE      *+6\;CLR        %N0,%N1\";
255 ;      return \"CR      %0,%1\;BNE      *+6\;CLR        %N0,%N1\";
256 ;    }
257 ;  mvs_check_page (0, 12, 0);
258 ;  if (unsigned_jump_follows_p (insn))
259 ;    return \"CL        %0,%M1\;BNE     *+8\;CL %N0,%L1\";
260 ;  return \"C   %0,%M1\;BNE     *+8\;CL %N0,%L1\";
261 ;}")
262
263 ;
264 ; cmpsi instruction pattern(s).
265 ;
266
267 (define_insn "cmpsi"
268   [(set (cc0)
269         (compare (match_operand:SI 0 "register_operand" "d")
270                  (match_operand:SI 1 "general_operand" "md")))]
271   ""
272   "*
273 {
274   check_label_emit ();
275   if (REG_P (operands[1]))
276     {
277       mvs_check_page (0, 2, 0);
278       if (unsigned_jump_follows_p (insn))
279         return \"CLR    %0,%1\";
280       return \"CR       %0,%1\";
281     }
282   if (GET_CODE (operands[1]) == CONST_INT)
283     {
284       mvs_check_page (0, 4, 4);
285       if (unsigned_jump_follows_p (insn))
286          return \"CL    %0,=F'%c1'\";
287       return \"C        %0,=F'%c1'\";
288     }
289   mvs_check_page (0, 4, 0);
290   if (unsigned_jump_follows_p (insn))
291     return \"CL %0,%1\";
292   return \"C    %0,%1\";
293 }"
294    [(set_attr "length" "4")]
295 )
296
297 ;
298 ; cmphi instruction pattern(s).
299 ;
300
301 ; depricate constraint d because it takes multiple instructions
302 ; and a memeory access ...
303 (define_insn "cmphi"
304   [(set (cc0)
305         (compare (match_operand:HI 0 "register_operand" "d")
306                  (match_operand:HI 1 "general_operand" "???dim")))]
307   ""
308   "*
309 {
310   check_label_emit ();
311   if (REG_P (operands[1]))
312     {
313       mvs_check_page (0, 8, 0);
314       if (unsigned_jump_follows_p (insn))
315         return \"STH    %1,140(,13)\;CLM        %0,3,140(13)\";
316       return \"STH      %1,140(,13)\;CH %0,140(,13)\";
317     }
318   if (GET_CODE (operands[1]) == CONST_INT)
319     {
320       mvs_check_page (0, 4, 0);
321       return \"CH       %0,%H1\";
322     }
323   mvs_check_page (0, 4, 0);
324   return \"CH   %0,%1\";
325 }"
326    [(set_attr "length" "8")]
327 )
328
329 ;
330 ; cmpqi instruction pattern(s).
331 ;
332
333 (define_insn ""
334   [(set (cc0)
335         (compare (match_operand:QI 0 "r_or_s_operand" "dS")
336                  (match_operand:QI 1 "r_or_s_operand" "diS")))]
337   "unsigned_jump_follows_p (insn)"
338   "*
339 {
340   check_label_emit ();
341   if (REG_P (operands[0]))
342     {
343       if (REG_P (operands[1]))
344         {
345           mvs_check_page (0, 8, 0);
346           return \"STC  %1,140(,13)\;CLM        %0,1,140(13)\";
347         }
348       if (GET_CODE (operands[1]) == CONST_INT)
349         {
350           mvs_check_page (0, 4, 1);
351           return \"CLM  %0,1,=XL1'%X1'\";
352         }
353       mvs_check_page (0, 4, 0);
354       return \"CLM      %0,1,%1\";
355     }
356   else if (GET_CODE (operands[0]) == CONST_INT)
357     {
358       cc_status.flags |= CC_REVERSED;
359       if (REG_P (operands[1]))
360         {
361           mvs_check_page (0, 4, 1);
362           return \"CLM  %1,1,=XL1'%X0'\";
363         }
364       mvs_check_page (0, 4, 0);
365       return \"CLI      %1,%B0\";
366     }
367   if (GET_CODE (operands[1]) == CONST_INT)
368     {
369       mvs_check_page (0, 4, 0);
370       return \"CLI      %0,%B1\";
371     }
372   if (GET_CODE (operands[1]) == MEM)
373     {
374       mvs_check_page (0, 6, 0);
375       return \"CLC      %O0(1,%R0),%1\";
376     }
377   cc_status.flags |= CC_REVERSED;
378   mvs_check_page (0, 4, 0);
379   return \"CLM  %1,1,%0\";
380 }"
381    [(set_attr "length" "8")]
382 )
383
384 (define_insn "cmpqi"
385   [(set (cc0)
386         (compare (match_operand:QI 0 "register_operand" "d")
387                  (match_operand:QI 1 "general_operand" "di")))]
388   ""
389   "*
390 {
391   check_label_emit ();
392   if (unsigned_jump_follows_p (insn))
393     {
394       if (GET_CODE (operands[1]) == CONST_INT)
395         {
396           mvs_check_page (0, 4, 1);
397           return \"CLM  %0,1,=XL1'%X1'\";
398         }
399       if (!(REG_P (operands[1])))
400         {
401           mvs_check_page (0, 4, 0);
402           return \"CLM  %0,1,%1\";
403         }
404       mvs_check_page (0, 8, 0);
405       return \"STC      %1,140(,13)\;CLM        %0,1,140(13)\";
406     }
407   if (REG_P (operands[1]))
408     {
409       mvs_check_page (0, 18, 0);
410       return \"SLL      %0,24\;SRA      %0,24\;SLL      %1,24\;SRA      %1,24\;CR       %0,%1\";
411     }
412   mvs_check_page (0, 12, 0);
413   return \"SLL  %0,24\;SRA      %0,24\;C        %0,%1\";
414 }"
415    [(set_attr "length" "18")]
416 )
417
418 ;
419 ; cmpdf instruction pattern(s).
420 ;
421
422 (define_insn "cmpdf"
423   [(set (cc0)
424         (compare (match_operand:DF 0 "general_operand" "f,mF")
425                  (match_operand:DF 1 "general_operand" "fmF,f")))]
426   ""
427   "*
428 {
429   check_label_emit ();
430   if (FP_REG_P (operands[0]))
431     {
432       if (FP_REG_P (operands[1]))
433         {
434           mvs_check_page (0, 2, 0);
435           return \"CDR  %0,%1\";
436         }
437       mvs_check_page (0, 4, 0);
438       return \"CD       %0,%1\";
439     }
440   cc_status.flags |= CC_REVERSED;
441   mvs_check_page (0, 4, 0);
442   return \"CD   %1,%0\";
443 }"
444    [(set_attr "length" "4")]
445 )
446
447 ;
448 ; cmpsf instruction pattern(s).
449 ;
450
451 (define_insn "cmpsf"
452   [(set (cc0)
453         (compare (match_operand:SF 0 "general_operand" "f,mF")
454                  (match_operand:SF 1 "general_operand" "fmF,f")))]
455   ""
456   "*
457 {
458 check_label_emit ();
459   if (FP_REG_P (operands[0]))
460     {
461       if (FP_REG_P (operands[1]))
462         {
463           mvs_check_page (0, 2, 0);
464           return \"CER  %0,%1\";
465         }
466       mvs_check_page (0, 4, 0);
467       return \"CE       %0,%1\";
468     }
469   cc_status.flags |= CC_REVERSED;
470   mvs_check_page (0, 4, 0);
471   return \"CE   %1,%0\";
472 }"
473    [(set_attr "length" "4")]
474 )
475
476 ;
477 ; cmpstrsi instruction pattern(s).
478 ;
479
480 (define_expand "cmpstrsi"
481   [(set (match_operand:SI 0 "general_operand" "")
482           (compare (match_operand:BLK 1 "general_operand" "")
483                    (match_operand:BLK 2 "general_operand" "")))
484      (use (match_operand:SI 3 "general_operand" ""))
485      (use (match_operand:SI 4 "" ""))]
486    ""
487    "
488 {
489   rtx op1, op2;
490
491   op1 = XEXP (operands[1], 0);
492   if (GET_CODE (op1) == REG
493       || (GET_CODE (op1) == PLUS && GET_CODE (XEXP (op1, 0)) == REG
494           && GET_CODE (XEXP (op1, 1)) == CONST_INT
495           && (unsigned) INTVAL (XEXP (op1, 1)) < 4096))
496     {
497       op1 = operands[1];
498     }
499   else
500     {
501       op1 = gen_rtx_MEM (BLKmode, copy_to_mode_reg (SImode, op1));
502     }
503
504   op2 = XEXP (operands[2], 0);
505   if (GET_CODE (op2) == REG
506       || (GET_CODE (op2) == PLUS && GET_CODE (XEXP (op2, 0)) == REG
507           && GET_CODE (XEXP (op2, 1)) == CONST_INT
508           && (unsigned) INTVAL (XEXP (op2, 1)) < 4096))
509     {
510       op2 = operands[2];
511     }
512   else
513     {
514       op2 = gen_rtx_MEM (BLKmode, copy_to_mode_reg (SImode, op2));
515     }
516       
517   if (GET_CODE (operands[3]) == CONST_INT && INTVAL (operands[3]) < 256)
518     {
519       emit_insn (gen_rtx_PARALLEL (VOIDmode, gen_rtvec (2,
520                 gen_rtx_SET (VOIDmode, operands[0], 
521                         gen_rtx_COMPARE (VOIDmode, op1, op2)),
522                 gen_rtx_USE (VOIDmode, operands[3]))));
523     }
524   else
525     {
526         /* implementation suggested by  Richard Henderson <rth@cygnus.com> */
527         rtx reg1 = gen_reg_rtx (DImode);
528         rtx reg2 = gen_reg_rtx (DImode);
529         rtx result = operands[0];
530         rtx mem1 = operands[1];
531         rtx mem2 = operands[2];
532         rtx len = operands[3];
533         if (!CONSTANT_P (len))
534           len = force_reg (SImode, len);
535
536         /* Load up the address+length pairs.  */
537         emit_insn (gen_rtx_CLOBBER (VOIDmode, reg1));
538         emit_move_insn (gen_rtx_SUBREG (SImode, reg1, 0),
539                         force_operand (XEXP (mem1, 0), NULL_RTX));
540         emit_move_insn (gen_rtx_SUBREG (SImode, reg1, 1), len);
541
542         emit_insn (gen_rtx_CLOBBER (VOIDmode, reg2));
543         emit_move_insn (gen_rtx_SUBREG (SImode, reg2, 0),
544                         force_operand (XEXP (mem2, 0), NULL_RTX));
545         emit_move_insn (gen_rtx_SUBREG (SImode, reg2, 1), len);
546
547         /* Compare! */
548         emit_insn (gen_cmpstrsi_1 (result, reg1, reg2));
549     }
550   DONE;
551 }")
552
553 ; Compare a block that is less than 256 bytes in length.
554
555 (define_insn ""
556   [(set (match_operand:SI 0 "register_operand" "=d")
557         (compare (match_operand:BLK 1 "s_operand" "m")
558                  (match_operand:BLK 2 "s_operand" "m")))
559    (use (match_operand:QI 3 "immediate_operand" "I"))]
560   "((unsigned) INTVAL (operands[3]) < 256)"
561   "*
562 {
563   check_label_emit ();
564   mvs_check_page (0, 22, 0);
565   return \"LA   %0,%1\;CLC      %O1(%c3,%R1),%2\;BH     *+12\;BL        *+6\;SLR        %0,%0\;LNR      %0,%0\";
566 }"
567    [(set_attr "length" "22")]
568 )
569
570 ; Compare a block that is larger than 255 bytes in length.
571
572 (define_insn "cmpstrsi_1"
573   [(set (match_operand:SI 0 "register_operand" "+d")
574         (compare
575         (mem:BLK (subreg:SI (match_operand:DI 1 "register_operand" "+d") 0))
576         (mem:BLK (subreg:SI (match_operand:DI 2 "register_operand" "+d") 0))))
577    (use (match_dup 1))
578    (use (match_dup 2))
579    (clobber (match_dup 1))
580    (clobber (match_dup 2))]
581   ""
582   "*
583 {
584   check_label_emit ();
585   mvs_check_page (0, 18, 0);
586   return \"LA   %0,1(0,0)\;CLCL %1,%2\;BH       *+12\;BL        *+6\;SLR        %0,%0\;LNR      %0,%0\";
587 }"
588    [(set_attr "length" "18")]
589 )
590
591 ;;
592 ;;- Move instructions.
593 ;;
594
595 ;
596 ; movdi instruction pattern(s).
597 ;
598
599 (define_insn ""
600 ;;  [(set (match_operand:DI 0 "r_or_s_operand" "=dm")
601 ;;        (match_operand:DI 1 "r_or_s_operand" "dim*fF"))]
602   [(set (match_operand:DI 0 "r_or_s_operand" "=dS,m")
603         (match_operand:DI 1 "r_or_s_operand" "diS*fF,d*fF"))]
604
605   "TARGET_CHAR_INSTRUCTIONS"
606   "*
607 {
608   check_label_emit ();
609   if (REG_P (operands[0]))
610     {
611       if (FP_REG_P (operands[1]))
612         {
613           mvs_check_page (0, 8, 0);
614           return \"STD  %1,140(,13)\;LM %0,%N0,140(13)\";
615         }
616       if (REG_P (operands[1]))
617         {
618           mvs_check_page (0, 4, 0);
619           return \"LR   %0,%1\;LR       %N0,%N1\";
620         }
621       if (operands[1] == const0_rtx)
622         {
623           CC_STATUS_INIT;
624           mvs_check_page (0, 4, 0);
625           return \"SLR  %0,%0\;SLR      %N0,%N0\";
626         }
627       if (GET_CODE (operands[1]) == CONST_INT
628           && (unsigned) INTVAL (operands[1]) < 4096)
629         {
630           CC_STATUS_INIT;
631           mvs_check_page (0, 6, 0);
632           return \"SLR  %0,%0\;LA       %N0,%c1(0,0)\";
633         }
634       if (GET_CODE (operands[1]) == CONST_INT)
635         {
636           CC_STATUS_SET (operands[0], operands[1]);
637           mvs_check_page (0, 8, 0);
638           return \"L    %0,%1\;SRDA     %0,32\";
639         }
640       mvs_check_page (0, 4, 0);
641       return \"LM       %0,%N0,%1\";
642     }
643   else if (FP_REG_P (operands[1]))
644     {
645       mvs_check_page (0, 4, 0);
646       return \"STD      %1,%0\";
647     }
648   else if (REG_P (operands[1]))
649     {
650       mvs_check_page (0, 4, 0);
651       return \"STM      %1,%N1,%0\"; 
652     }
653   mvs_check_page (0, 6, 0);
654   return \"MVC  %O0(8,%R0),%W1\";
655 }"
656    [(set_attr "length" "8")]
657 )
658
659 (define_insn "movdi"
660 ;;  [(set (match_operand:DI 0 "general_operand" "=d,dm")
661 ;;      (match_operand:DI 1 "general_operand" "dimF,*fd"))]
662   [(set (match_operand:DI 0 "general_operand" "=d,dm")
663         (match_operand:DI 1 "r_or_s_operand" "diSF,*fd"))]
664   ""
665   "*
666 {
667   check_label_emit ();
668   if (REG_P (operands[0]))
669     {
670       if (FP_REG_P (operands[1]))
671         {
672           mvs_check_page (0, 8, 0);
673           return \"STD  %1,140(,13)\;LM %0,%N0,140(13)\";
674         }
675       if (REG_P (operands[1]))
676         {
677           mvs_check_page (0, 4, 0);
678           return \"LR   %0,%1\;LR       %N0,%N1\";
679         }
680       if (operands[1] == const0_rtx)
681         {
682           CC_STATUS_INIT;
683           mvs_check_page (0, 4, 0);
684           return \"SLR  %0,%0\;SLR      %N0,%N0\";
685         }
686       if (GET_CODE (operands[1]) == CONST_INT
687           && (unsigned) INTVAL (operands[1]) < 4096)
688         {
689           CC_STATUS_INIT;
690           mvs_check_page (0, 6, 0);
691           return \"SLR  %0,%0\;LA       %N0,%c1(0,0)\";
692         }
693       if (GET_CODE (operands[1]) == CONST_INT)
694         {
695           CC_STATUS_SET (operands[0], operands[1]);
696           mvs_check_page (0, 8, 0);
697           return \"L    %0,%1\;SRDA     %0,32\";
698         }
699       mvs_check_page (0, 4, 0);
700       return \"LM       %0,%N0,%1\";
701     }
702   else if (FP_REG_P (operands[1]))
703     {
704       mvs_check_page (0, 4, 0);
705       return \"STD      %1,%0\";
706     }
707   mvs_check_page (0, 4, 0);
708   return \"STM  %1,%N1,%0\";
709 }"
710    [(set_attr "length" "8")]
711 )
712
713 ;; we have got to provide a movdi alternative that will go from 
714 ;; register to memory & back in its full glory.  However, we try to 
715 ;; discourage its use by listing this alternative last.
716 ;; The problem is that the instructions above only provide 
717 ;; S-form style (base + displacement) mem access, while the
718 ;; below provvides the full (base+index+displacement) RX-form.
719 ;; These are rarely needed, but when needed they're needed.
720
721 (define_insn ""
722   [(set (match_operand:DI 0 "general_operand" "=d,???m")
723         (match_operand:DI 1 "general_operand" "???m,d"))]
724
725   ""
726   "*
727 {
728   check_label_emit ();
729   if (REG_P (operands[0]))
730     {
731       mvs_check_page (0, 8, 0);
732       return \"LM       %0,%N0,%1\";
733     }
734   else if (REG_P (operands[1]))
735     {
736       mvs_check_page (0, 8, 0);
737       return \"STM      %1,%N1,%0\";
738     }
739   mvs_check_page (0, 6, 0);
740   return \"MVC  %O0(8,%R0),%1\";
741 }"
742    [(set_attr "length" "8")]
743 )
744
745 ;
746 ; movsi instruction pattern(s).
747 ;
748
749 (define_insn ""
750 ;;  [(set (match_operand:SI 0 "r_or_s_operand" "=dm,d,dm")
751 ;;        (match_operand:SI 1 "r_or_s_operand" "diR,dim,*fF"))]
752   [(set (match_operand:SI 0 "r_or_s_operand" "=d,dS,dm")
753         (match_operand:SI 1 "general_operand" "dim,diS,di*fF"))]
754
755   "TARGET_CHAR_INSTRUCTIONS"
756   "*
757 {
758   check_label_emit ();
759   if (REG_P (operands[0]))
760     {
761       if (FP_REG_P (operands[1]))
762         {
763           mvs_check_page (0, 8, 0);
764           return \"STE  %1,140(,13)\;L  %0,140(,13)\";
765         }
766       if (REG_P (operands[1]))
767         {
768           mvs_check_page (0, 2, 0);
769           return \"LR   %0,%1\";
770         }
771       if (operands[1] == const0_rtx)
772         {
773           CC_STATUS_INIT;
774           mvs_check_page (0, 2, 0);
775           return \"SLR  %0,%0\";
776         }
777       if (GET_CODE (operands[1]) == CONST_INT
778           && (unsigned) INTVAL (operands[1]) < 4096)
779         {
780           mvs_check_page (0, 4, 0);
781           return \"LA   %0,%c1(0,0)\";
782         }
783       mvs_check_page (0, 4, 0);
784       return \"L        %0,%1\";
785     }
786   else if (FP_REG_P (operands[1]))
787     {
788       mvs_check_page (0, 4, 0);
789       return \"STE      %1,%0\";
790     }
791   else if (REG_P (operands[1]))
792     {
793       mvs_check_page (0, 4, 0);
794       return \"ST       %1,%0\";
795     }
796   mvs_check_page (0, 6, 0);
797   return \"MVC  %O0(4,%R0),%1\";
798 }"
799    [(set_attr "length" "8")]
800 )
801
802 (define_insn "movsi"
803   [(set (match_operand:SI 0 "general_operand" "=d,dm")
804         (match_operand:SI 1 "general_operand" "dimF,*fd"))]
805   ""
806   "*
807 {
808   check_label_emit ();
809   if (REG_P (operands[0]))
810     {
811       if (FP_REG_P (operands[1]))
812         {
813           mvs_check_page (0, 8, 0);
814           return \"STE  %1,140(,13)\;L  %0,140(,13)\";
815         }
816       if (REG_P (operands[1]))
817         {
818           mvs_check_page (0, 2, 0);
819           return \"LR   %0,%1\";
820         }
821       if (operands[1] == const0_rtx)
822         {
823           CC_STATUS_INIT;
824           mvs_check_page (0, 2, 0);
825           return \"SLR  %0,%0\";
826         }
827       if (GET_CODE (operands[1]) == CONST_INT
828           && (unsigned) INTVAL (operands[1]) < 4096)
829         {
830           mvs_check_page (0, 4, 0);
831           return \"LA   %0,%c1(0,0)\";
832         }
833       mvs_check_page (0, 4, 0);
834       return \"L        %0,%1\";
835     }
836   else if (FP_REG_P (operands[1]))
837     {
838       mvs_check_page (0, 4, 0);
839       return \"STE      %1,%0\";
840     }
841   mvs_check_page (0, 4, 0);
842   return \"ST   %1,%0\";
843 }"
844    [(set_attr "length" "8")]
845 )
846
847 ;(define_expand "movsi"
848 ;  [(set (match_operand:SI 0 "general_operand" "=d,dm")
849 ;       (match_operand:SI 1 "general_operand" "dimF,*fd"))]
850 ;  ""
851 ;  "
852 ;{
853 ;  rtx op0, op1;
854 ;
855 ;  op0 = operands[0];
856 ;  if (GET_CODE (op0) == CONST
857 ;      && GET_CODE (XEXP (XEXP (op0, 0), 0)) == SYMBOL_REF
858 ;      && SYMBOL_REF_FLAG (XEXP (XEXP (op0, 0), 0)))
859 ;    {
860 ;      op0 = gen_rtx_MEM (SImode, copy_to_mode_reg (SImode, XEXP (op0, 0)));
861 ;    }
862 ;
863 ;  op1 = operands[1];
864 ;  if (GET_CODE (op1) == CONST
865 ;      && GET_CODE (XEXP (XEXP (op1, 0), 0)) == SYMBOL_REF
866 ;      && SYMBOL_REF_FLAG (XEXP (XEXP (op1, 0), 0)))
867 ;    {
868 ;      op1 = gen_rtx_MEM (SImode, copy_to_mode_reg (SImode, XEXP (op1, 0)));
869 ;    }
870 ;
871 ;  emit_insn (gen_rtx_SET (VOIDmode, op0, op1));
872 ;  DONE;
873 ;}")
874
875 ;
876 ; movhi instruction pattern(s).
877 ;
878
879 (define_insn ""
880   [(set (match_operand:HI 0 "r_or_s_operand" "=g")
881         (match_operand:HI 1 "r_or_s_operand" "g"))]
882   "TARGET_CHAR_INSTRUCTIONS"
883   "*
884 {
885   check_label_emit ();
886   if (REG_P (operands[0]))
887     {
888       if (REG_P (operands[1]))
889         {
890           mvs_check_page (0, 2, 0);
891           return \"LR   %0,%1\";
892         }
893       if (operands[1] == const0_rtx)
894         {
895           CC_STATUS_INIT;
896           mvs_check_page (0, 2, 0);
897           return \"SLR  %0,%0\";
898         }
899       if (GET_CODE (operands[1]) == CONST_INT
900           && (unsigned) INTVAL (operands[1]) < 4096)
901         {
902           mvs_check_page (0, 4, 0);
903           return \"LA   %0,%c1(0,0)\";
904         }
905       if (GET_CODE (operands[1]) == CONST_INT)
906         {
907           mvs_check_page (0, 4, 0);
908           return \"LH   %0,%H1\";
909         }
910       mvs_check_page (0, 4, 0);
911       return \"LH       %0,%1\";
912     }
913   else if (REG_P (operands[1]))
914     {
915       mvs_check_page (0, 4, 0);
916       return \"STH      %1,%0\";
917     }
918   if (GET_CODE (operands[1]) == CONST_INT)
919     {
920       mvs_check_page (0, 6, 0);
921       return \"MVC      %O0(2,%R0),%H1\";
922     }
923   mvs_check_page (0, 6, 0);
924   return \"MVC  %O0(2,%R0),%1\";
925 }"
926    [(set_attr "length" "6")]
927 )
928
929 (define_insn "movhi"
930   [(set (match_operand:HI 0 "general_operand" "=d,m")
931         (match_operand:HI 1 "general_operand" "g,d"))]
932   ""
933   "*
934 {
935   check_label_emit ();
936   if (REG_P (operands[0]))
937     {
938       if (REG_P (operands[1]))
939         {
940           mvs_check_page (0, 2, 0);
941           return \"LR   %0,%1\";
942         }
943       if (operands[1] == const0_rtx)
944         {
945           CC_STATUS_INIT;
946           mvs_check_page (0, 2, 0);
947           return \"SLR  %0,%0\";
948         }
949       if (GET_CODE (operands[1]) == CONST_INT
950           && (unsigned) INTVAL (operands[1]) < 4096)
951         {
952           mvs_check_page (0, 4, 0);
953           return \"LA   %0,%c1(0,0)\";
954         }
955       if (GET_CODE (operands[1]) == CONST_INT)
956         {
957           mvs_check_page (0, 4, 0);
958           return \"LH   %0,%H1\";
959         }
960       mvs_check_page (0, 4, 0);
961       return \"LH       %0,%1\";
962     }
963   mvs_check_page (0, 4, 0);
964   return \"STH  %1,%0\";
965 }"
966    [(set_attr "length" "4")]
967 )
968
969 ;
970 ; movqi instruction pattern(s).
971 ;
972
973 (define_insn ""
974   [(set (match_operand:QI 0 "r_or_s_operand" "=g")
975         (match_operand:QI 1 "r_or_s_operand" "g"))]
976   "TARGET_CHAR_INSTRUCTIONS"
977   "*
978 {
979   check_label_emit ();
980   if (REG_P (operands[0]))
981     {
982       if (REG_P (operands[1]))
983         {
984           mvs_check_page (0, 2, 0);
985           return \"LR   %0,%1\";
986         }
987       if (operands[1] == const0_rtx)
988         {
989           CC_STATUS_INIT;
990           mvs_check_page (0, 2, 0);
991           return \"SLR  %0,%0\";
992         }
993       if (GET_CODE (operands[1]) == CONST_INT)
994         {
995           if ((INTVAL (operands[1]) >= 0)
996               && (unsigned) INTVAL (operands[1]) < 4096)
997             {
998               mvs_check_page (0, 4, 0);
999               return \"LA       %0,%c1(0,0)\";
1000             }
1001           mvs_check_page (0, 4, 0);
1002           return \"L    %0,=F'%c1'\";
1003         }
1004       mvs_check_page (0, 4, 0);
1005       return \"IC       %0,%1\";
1006     }
1007   else if (REG_P (operands[1]))
1008     {
1009       mvs_check_page (0, 4, 0);
1010       return \"STC      %1,%0\";
1011     }
1012   else if (GET_CODE (operands[1]) == CONST_INT)
1013     {
1014       mvs_check_page (0, 4, 0);
1015       return \"MVI      %0,%B1\";
1016     }
1017   mvs_check_page (0, 6, 0);
1018   return \"MVC  %O0(1,%R0),%1\";
1019 }"
1020    [(set_attr "length" "6")]
1021 )
1022
1023 (define_insn "movqi"
1024   [(set (match_operand:QI 0 "general_operand" "=d,m")
1025         (match_operand:QI 1 "general_operand" "g,d"))]
1026   ""
1027   "*
1028 {
1029   check_label_emit ();
1030   if (REG_P (operands[0]))
1031     {
1032       if (REG_P (operands[1]))
1033         {
1034           mvs_check_page (0, 2, 0);
1035           return \"LR   %0,%1\";
1036         }
1037       if (operands[1] == const0_rtx)
1038         {
1039           CC_STATUS_INIT;
1040           mvs_check_page (0, 2, 0);
1041           return \"SLR  %0,%0\";
1042         }
1043       if (GET_CODE (operands[1]) == CONST_INT)
1044         {
1045           if ((INTVAL (operands[1]) >= 0)
1046               && (unsigned) INTVAL (operands[1]) < 4096)
1047             {
1048               mvs_check_page (0, 4, 0);
1049               return \"LA       %0,%c1(0,0)\";
1050             }
1051           mvs_check_page (0, 4, 0);
1052           return \"L    %0,=F'%c1'\";
1053         }
1054       mvs_check_page (0, 4, 0);
1055       return \"IC       %0,%1\";
1056     }
1057   mvs_check_page (0, 4, 0);
1058   return \"STC  %1,%0\";
1059 }"
1060    [(set_attr "length" "4")]
1061 )
1062
1063 ;
1064 ; movstrictqi instruction pattern(s).
1065 ;
1066
1067 (define_insn "movstrictqi"
1068   [(set (strict_low_part (match_operand:QI 0 "general_operand" "=d"))
1069         (match_operand:QI 1 "general_operand" "g"))]
1070   ""
1071   "*
1072 {
1073   check_label_emit ();
1074   if (REG_P (operands[1]))
1075     {
1076       mvs_check_page (0, 8, 0);
1077       return \"STC      %1,140(,13)\;IC %0,140(,13)\";
1078     }
1079   mvs_check_page (0, 4, 0);
1080   return \"IC   %0,%1\";
1081 }"
1082    [(set_attr "length" "8")]
1083 )
1084
1085 ;
1086 ; movstricthi instruction pattern(s).
1087 ;
1088
1089 (define_insn ""
1090   [(set (strict_low_part (match_operand:HI 0 "register_operand" "=d"))
1091         (match_operand:HI 1 "r_or_s_operand" "g"))]
1092   ""
1093   "*
1094 {
1095   check_label_emit ();
1096   if (REG_P (operands[1]))
1097     {
1098       mvs_check_page (0, 8, 0);
1099       return \"STH      %1,140(,13)\;ICM        %0,3,140(13)\";
1100     }
1101   else if (GET_CODE (operands[1]) == CONST_INT)
1102     {
1103       mvs_check_page (0, 4, 0);
1104       return \"ICM      %0,3,%H1\";
1105     }
1106   mvs_check_page (0, 4, 0);
1107   return \"ICM  %0,3,%1\";
1108 }"
1109    [(set_attr "length" "8")]
1110 )
1111
1112 (define_insn "movstricthi"
1113   [(set (strict_low_part (match_operand:HI 0 "general_operand" "=dm"))
1114         (match_operand:HI 1 "general_operand" "d"))]
1115   ""
1116   "*
1117 {
1118   check_label_emit ();
1119   if (REG_P (operands[0]))
1120     {
1121       mvs_check_page (0, 8, 0);
1122       return \"STH      %1,140(,13)\;ICM        %0,3,140(13)\";
1123     }
1124   mvs_check_page (0, 4, 0);
1125   return \"STH  %1,%0\";
1126 }"
1127    [(set_attr "length" "8")]
1128 )
1129
1130 ;
1131 ; movdf instruction pattern(s).
1132 ;
1133
1134 (define_insn ""
1135 ;;  [(set (match_operand:DF 0 "r_or_s_operand" "=fm,fm,*dm")
1136 ;;        (match_operand:DF 1 "r_or_s_operand" "fmF,*dm,fmF"))]
1137   [(set (match_operand:DF 0 "general_operand" "=f,m,fS,*dS,???d")
1138       (match_operand:DF 1 "general_operand" "fmF,fF,*dS,fSF,???d"))]
1139
1140   "TARGET_CHAR_INSTRUCTIONS"
1141   "*
1142 {
1143   check_label_emit ();
1144   if (FP_REG_P (operands[0]))
1145     {
1146       if (FP_REG_P (operands[1]))
1147         {
1148           mvs_check_page (0, 2, 0);
1149           return \"LDR  %0,%1\";
1150         }
1151       if (REG_P (operands[1]))
1152         {
1153           mvs_check_page (0, 8, 0);
1154           return \"STM  %1,%N1,140(13)\;LD      %0,140(,13)\";
1155         }
1156       if (operands[1] == const0_rtx)
1157         {
1158           CC_STATUS_SET (operands[0], operands[1]);
1159           mvs_check_page (0, 2, 0);
1160           return \"SDR  %0,%0\";
1161         }
1162       mvs_check_page (0, 4, 0);
1163       return \"LD       %0,%1\";
1164     }
1165   if (REG_P (operands[0]))
1166     {
1167       if (FP_REG_P (operands[1]))
1168         {
1169           mvs_check_page (0, 12, 0);
1170           return \"STD  %1,140(,13)\;LM %0,%N0,140(13)\";
1171         }
1172       if (REG_P (operands[1]))
1173         {
1174           mvs_check_page (0, 4, 0);
1175           return \"LR   %0,%1\;LR       %N0,%N1\";
1176         }
1177       mvs_check_page (0, 4, 0);
1178       return \"LM       %0,%N0,%1\";
1179     }
1180   else if (FP_REG_P (operands[1]))
1181     {
1182       mvs_check_page (0, 4, 0);
1183       return \"STD      %1,%0\";
1184     }
1185   else if (REG_P (operands[1]))
1186     {
1187       mvs_check_page (0, 4, 0);
1188       return \"STM      %1,%N1,%0\";
1189     }
1190   mvs_check_page (0, 6, 0);
1191   return \"MVC  %O0(8,%R0),%1\";
1192 }"
1193    [(set_attr "length" "12")]
1194 )
1195
1196 (define_insn "movdf"
1197 ;;  [(set (match_operand:DF 0 "general_operand" "=f,fm,m,*d")
1198 ;;      (match_operand:DF 1 "general_operand" "fmF,*d,f,fmF"))]
1199   [(set (match_operand:DF 0 "general_operand" "=f,m,fS,*d,???d")
1200       (match_operand:DF 1 "general_operand" "fmF,f,*d,SfF,???d"))]
1201
1202   ""
1203   "*
1204 {
1205   check_label_emit ();
1206   if (FP_REG_P (operands[0]))
1207     {
1208       if (FP_REG_P (operands[1]))
1209         {
1210           mvs_check_page (0, 2, 0);
1211           return \"LDR  %0,%1\";
1212         }
1213       if (REG_P (operands[1]))
1214         {
1215           mvs_check_page (0, 8, 0);
1216           return \"STM  %1,%N1,140(13)\;LD      %0,140(,13)\";
1217         }
1218       if (operands[1] == const0_rtx)
1219         {
1220           CC_STATUS_SET (operands[0], operands[1]);
1221           mvs_check_page (0, 2, 0);
1222           return \"SDR  %0,%0\";
1223         }
1224       mvs_check_page (0, 4, 0);
1225       return \"LD       %0,%1\";
1226     }
1227   else if (REG_P (operands[0]))
1228     {
1229       if (FP_REG_P (operands[1]))
1230         {
1231           mvs_check_page (0, 12, 0);
1232           return \"STD  %1,140(,13)\;LM %0,%N0,140(13)\";
1233         }
1234       if (REG_P (operands[1]))
1235         {
1236           mvs_check_page (0, 4, 0);
1237           return \"LR   %0,%1\;LR       %N0,%N1\";
1238         }
1239       mvs_check_page (0, 4, 0);
1240       return \"LM       %0,%N0,%1\";
1241     }
1242   else if (FP_REG_P (operands[1]))
1243     {
1244       mvs_check_page (0, 4, 0);
1245       return \"STD      %1,%0\";
1246     }
1247   mvs_check_page (0, 4, 0);
1248   return \"STM  %1,%N1,%0\";
1249 }"
1250    [(set_attr "length" "12")]
1251 )
1252
1253 ;
1254 ; movsf instruction pattern(s).
1255 ;
1256
1257 (define_insn ""
1258 ;;  [(set (match_operand:SF 0 "r_or_s_operand" "=fm,fm,*dm")
1259 ;;        (match_operand:SF 1 "r_or_s_operand" "fmF,*dm,fmF"))]
1260 ;;  [(set (match_operand:SF 0 "general_operand" "=f,m,fm,*d,S")
1261 ;;         (match_operand:SF 1 "general_operand" "fmF,fF,*d,fmF,S"))]
1262   [(set (match_operand:SF 0 "general_operand" "=f*d,fm,S,???d")
1263         (match_operand:SF 1 "general_operand" "fmF,fF*d,S,???d"))]
1264
1265   "TARGET_CHAR_INSTRUCTIONS"
1266   "*
1267 {
1268   check_label_emit ();
1269   if (FP_REG_P (operands[0]))
1270     {
1271       if (FP_REG_P (operands[1]))
1272         {
1273           mvs_check_page (0, 2, 0);
1274           return \"LER  %0,%1\";
1275         }
1276       if (REG_P (operands[1]))
1277         {
1278           mvs_check_page (0, 8, 0);
1279           return \"ST   %1,140(,13)\;LE %0,140(,13)\";
1280         }
1281       if (operands[1] == const0_rtx)
1282         {
1283           CC_STATUS_SET (operands[0], operands[1]);
1284           mvs_check_page (0, 2, 0);
1285           return \"SER  %0,%0\";
1286         }
1287       mvs_check_page (0, 4, 0);
1288       return \"LE       %0,%1\";
1289     }
1290   else if (REG_P (operands[0]))
1291     {
1292       if (FP_REG_P (operands[1]))
1293         {
1294           mvs_check_page (0, 8, 0);
1295           return \"STE  %1,140(,13)\;L  %0,140(,13)\";
1296         }
1297       if (REG_P (operands[1]))
1298         {
1299           mvs_check_page (0, 2, 0);
1300           return \"LR   %0,%1\";
1301         }
1302       mvs_check_page (0, 4, 0);
1303       return \"L        %0,%1\";
1304     }
1305   else if (FP_REG_P (operands[1]))
1306     {
1307       mvs_check_page (0, 4, 0);
1308       return \"STE      %1,%0\";
1309     }
1310   else if (REG_P (operands[1]))
1311     {
1312       mvs_check_page (0, 4, 0);
1313       return \"ST       %1,%0\";
1314     }
1315   mvs_check_page (0, 6, 0);
1316   return \"MVC  %O0(4,%R0),%1\";
1317 }"
1318    [(set_attr "length" "8")]
1319 )
1320
1321 (define_insn "movsf"
1322   [(set (match_operand:SF 0 "general_operand" "=f,fm,m,*d")
1323         (match_operand:SF 1 "general_operand" "fmF,*d,f,fmF"))]
1324   ""
1325   "*
1326 {
1327   check_label_emit ();
1328   if (FP_REG_P (operands[0]))
1329     {
1330       if (FP_REG_P (operands[1]))
1331         {
1332           mvs_check_page (0, 2, 0);
1333           return \"LER  %0,%1\";
1334         }
1335       if (REG_P (operands[1]))
1336         {
1337           mvs_check_page (0, 8, 0);
1338           return \"ST   %1,140(,13)\;LE %0,140(,13)\";
1339         }
1340       if (operands[1] == const0_rtx)
1341         {
1342           CC_STATUS_SET (operands[0], operands[1]);
1343           mvs_check_page (0, 2, 0);
1344           return \"SER  %0,%0\";
1345         }
1346       mvs_check_page (0, 4, 0);
1347       return \"LE       %0,%1\";
1348     }
1349   else if (REG_P (operands[0]))
1350     {
1351       if (FP_REG_P (operands[1]))
1352         {
1353           mvs_check_page (0, 8, 0);
1354           return \"STE  %1,140(,13)\;L  %0,140(,13)\";
1355         }
1356       mvs_check_page (0, 4, 0);
1357       return \"L        %0,%1\";
1358     }
1359   else if (FP_REG_P (operands[1]))
1360     {
1361       mvs_check_page (0, 4, 0);
1362       return \"STE      %1,%0\";
1363     }
1364   mvs_check_page (0, 4, 0);
1365   return \"ST   %1,%0\";
1366 }"
1367    [(set_attr "length" "8")]
1368 )
1369
1370 ;
1371 ; clrstrsi instruction pattern(s).
1372 ; memset a block of bytes to zero.
1373 ; block must be less than 16M (24 bits) in length
1374 ;
1375 (define_expand "clrstrsi"
1376   [(set (match_operand:BLK 0 "general_operand" "g")
1377         (const_int 0)) 
1378    (use (match_operand:SI  1 "general_operand" ""))
1379    (match_operand 2 "" "")]
1380    ""
1381    "
1382 {
1383 /*
1384   XXX bogus, i think, unless change_address has a side effet we need
1385   rtx op0;
1386
1387   op0 = XEXP (operands[0], 0);
1388   if (GET_CODE (op0) == REG
1389       || (GET_CODE (op0) == PLUS && GET_CODE (XEXP (op0, 0)) == REG
1390           && GET_CODE (XEXP (op0, 1)) == CONST_INT
1391           && (unsigned) INTVAL (XEXP (op0, 1)) < 4096))
1392     op0 = operands[0];
1393   else
1394     op0 = change_address (operands[0], VOIDmode,
1395                           copy_to_mode_reg (SImode, op0));
1396
1397 */
1398   {
1399         /* implementation suggested by  Richard Henderson <rth@cygnus.com> */
1400         rtx reg1 = gen_reg_rtx (DImode);
1401         rtx reg2 = gen_reg_rtx (DImode);
1402         rtx mem1 = operands[0];
1403         rtx zippo = gen_rtx_CONST_INT (SImode, 0);
1404         rtx len = operands[1];
1405         if (!CONSTANT_P (len))
1406           len = force_reg (SImode, len);
1407
1408         /* Load up the address+length pairs.  */
1409         emit_insn (gen_rtx_CLOBBER (VOIDmode, reg1));
1410         emit_move_insn (gen_rtx_SUBREG (SImode, reg1, 0),
1411                         force_operand (XEXP (mem1, 0), NULL_RTX));
1412         emit_move_insn (gen_rtx_SUBREG (SImode, reg1, 1), len);
1413
1414         emit_insn (gen_rtx_CLOBBER (VOIDmode, reg2));
1415         emit_move_insn (gen_rtx_SUBREG (SImode, reg2, 0), zippo);
1416         emit_move_insn (gen_rtx_SUBREG (SImode, reg2, 1), zippo);
1417
1418         /* Copy! */
1419         emit_insn (gen_movstrsi_1 (reg1, reg2));
1420   }
1421   DONE;
1422 }")
1423
1424 ;
1425 ; movstrsi instruction pattern(s).
1426 ; block must be less than 16M (24 bits) in length
1427
1428 (define_expand "movstrsi"
1429   [(set (match_operand:BLK 0 "general_operand" "")
1430         (match_operand:BLK 1 "general_operand" ""))
1431    (use (match_operand:SI  2 "general_operand" ""))
1432    (match_operand 3 "" "")]
1433    ""
1434    "
1435 {
1436   rtx op0, op1;
1437
1438   op0 = XEXP (operands[0], 0);
1439   if (GET_CODE (op0) == REG
1440       || (GET_CODE (op0) == PLUS && GET_CODE (XEXP (op0, 0)) == REG
1441           && GET_CODE (XEXP (op0, 1)) == CONST_INT
1442           && (unsigned) INTVAL (XEXP (op0, 1)) < 4096))
1443     op0 = operands[0];
1444   else
1445     op0 = change_address (operands[0], VOIDmode,
1446                           copy_to_mode_reg (SImode, op0));
1447
1448   op1 = XEXP (operands[1], 0);
1449   if (GET_CODE (op1) == REG
1450       || (GET_CODE (op1) == PLUS && GET_CODE (XEXP (op1, 0)) == REG
1451           && GET_CODE (XEXP (op1, 1)) == CONST_INT
1452           && (unsigned) INTVAL (XEXP (op1, 1)) < 4096))
1453     op1 = operands[1];
1454   else
1455     op1 = change_address (operands[1], VOIDmode,
1456                           copy_to_mode_reg (SImode, op1));
1457
1458   if (GET_CODE (operands[2]) == CONST_INT && INTVAL (operands[2]) < 256)
1459     emit_insn (gen_rtx_PARALLEL (VOIDmode,
1460                         gen_rtvec (2,
1461                                    gen_rtx_SET (VOIDmode, op0, op1),
1462                                    gen_rtx_USE (VOIDmode, operands[2]))));
1463
1464   else
1465     {
1466         /* implementation provided by  Richard Henderson <rth@cygnus.com> */
1467         rtx reg1 = gen_reg_rtx (DImode);
1468         rtx reg2 = gen_reg_rtx (DImode);
1469         rtx mem1 = operands[0];
1470         rtx mem2 = operands[1];
1471         rtx len = operands[2];
1472         if (!CONSTANT_P (len))
1473           len = force_reg (SImode, len);
1474
1475         /* Load up the address+length pairs.  */
1476         emit_insn (gen_rtx_CLOBBER (VOIDmode, reg1));
1477         emit_move_insn (gen_rtx_SUBREG (SImode, reg1, 0),
1478                         force_operand (XEXP (mem1, 0), NULL_RTX));
1479         emit_move_insn (gen_rtx_SUBREG (SImode, reg1, 1), len);
1480
1481         emit_insn (gen_rtx_CLOBBER (VOIDmode, reg2));
1482         emit_move_insn (gen_rtx_SUBREG (SImode, reg2, 0),
1483                         force_operand (XEXP (mem2, 0), NULL_RTX));
1484         emit_move_insn (gen_rtx_SUBREG (SImode, reg2, 1), len);
1485
1486         /* Copy! */
1487         emit_insn (gen_movstrsi_1 (reg1, reg2));
1488     }
1489   DONE;
1490 }")
1491
1492 ; Move a block that is less than 256 bytes in length.
1493
1494 (define_insn ""
1495   [(set (match_operand:BLK 0 "s_operand" "=m")
1496         (match_operand:BLK 1 "s_operand" "m"))
1497    (use (match_operand 2 "immediate_operand" "I"))]
1498   "((unsigned) INTVAL (operands[2]) < 256)"
1499   "*
1500 {
1501   check_label_emit ();
1502   mvs_check_page (0, 6, 0);
1503   return \"MVC  %O0(%c2,%R0),%1\";
1504 }"
1505    [(set_attr "length" "6")]
1506 )
1507
1508 ; Move a block that is larger than 255 bytes in length.
1509
1510 (define_insn "movstrsi_1"
1511   [(set (mem:BLK (subreg:SI (match_operand:DI 0 "register_operand" "+d") 0))
1512         (mem:BLK (subreg:SI (match_operand:DI 1 "register_operand" "+d") 0)))
1513    (use (match_dup 0))
1514    (use (match_dup 1))
1515    (clobber (match_dup 0))
1516    (clobber (match_dup 1))]
1517   ""
1518   "*
1519 {
1520   check_label_emit ();
1521   mvs_check_page (0, 2, 0);
1522   return \"MVCL %0,%1\";
1523 }"
1524    [(set_attr "length" "2")]
1525 )
1526
1527 ;;
1528 ;;- Conversion instructions.
1529 ;;
1530
1531 ;
1532 ; extendsidi2 instruction pattern(s).
1533 ;
1534
1535 (define_expand "extendsidi2"
1536   [(set (match_operand:DI 0 "register_operand" "=d")
1537         (sign_extend:DI (match_operand:SI 1 "general_operand" "")))]
1538   ""
1539   "
1540 {
1541   if (GET_CODE (operands[1]) != CONST_INT)
1542     {
1543       emit_insn (gen_rtx_SET (VOIDmode,
1544                   operand_subword (operands[0], 0, 1, DImode), operands[1]));
1545       emit_insn (gen_rtx_SET (VOIDmode, operands[0],
1546                         gen_rtx_ASHIFTRT (DImode, operands[0],
1547                                 gen_rtx_CONST_INT (SImode, 32))));
1548     }
1549   else
1550     {
1551       if (INTVAL (operands[1]) < 0)
1552         {
1553           emit_insn (gen_rtx_SET (VOIDmode,
1554                                   operand_subword (operands[0], 0, 1, DImode),
1555                                gen_rtx_CONST_INT (SImode, -1)));
1556         }
1557       else
1558         {
1559           emit_insn (gen_rtx_SET (VOIDmode,
1560                                 operand_subword (operands[0], 0, 1, DImode),
1561                                gen_rtx_CONST_INT (SImode, 0)));
1562         }
1563       emit_insn (gen_rtx_SET (VOIDmode, gen_lowpart (SImode, operands[0]),
1564                            operands[1]));
1565     }
1566   DONE;
1567 }")
1568
1569 ;
1570 ; extendhisi2 instruction pattern(s).
1571 ;
1572
1573 (define_insn "extendhisi2"
1574   [(set (match_operand:SI 0 "general_operand" "=d,m")
1575         (sign_extend:SI (match_operand:HI 1 "general_operand" "g,d")))]
1576   ""
1577   "*
1578 {
1579   check_label_emit ();
1580   if (REG_P (operands[0]))
1581     {
1582       if (REG_P (operands[1]))
1583       {
1584         if (REGNO (operands[0]) != REGNO (operands[1]))
1585           {
1586             mvs_check_page (0, 10, 0);
1587             return \"LR %0,%1\;SLL      %0,16\;SRA      %0,16\";
1588           }
1589         else
1590           return \"\"; /* Should be empty.  16-bits regs are always 32-bits.  */
1591       }
1592       if (operands[1] == const0_rtx)
1593         {
1594           CC_STATUS_INIT;
1595           mvs_check_page (0, 2, 0);
1596           return \"SLR  %0,%0\";
1597         }
1598       if (GET_CODE (operands[1]) == CONST_INT
1599           && (unsigned) INTVAL (operands[1]) < 4096)
1600         {
1601           mvs_check_page (0, 4, 0);
1602           return \"LA   %0,%c1(0,0)\";
1603         }
1604       if (GET_CODE (operands[1]) == CONST_INT)
1605         {
1606           mvs_check_page (0, 4, 0);
1607           return \"LH   %0,%H1\";
1608         }
1609       mvs_check_page (0, 4, 0);
1610       return \"LH       %0,%1\";
1611     }
1612   mvs_check_page (0, 12, 0);
1613   return \"SLL  %1,16\;SRA      %1,16\;ST       %1,%0\";
1614 }"
1615    [(set_attr "length" "12")]
1616 )
1617
1618 ;
1619 ; extendqisi2 instruction pattern(s).
1620 ;
1621
1622 (define_insn "extendqisi2"
1623   [(set (match_operand:SI 0 "general_operand" "=d")
1624         (sign_extend:SI (match_operand:QI 1 "general_operand" "0mi")))]
1625   ""
1626   "*
1627 {
1628   check_label_emit ();
1629   CC_STATUS_SET (operands[0], operands[1]);
1630   if (REG_P (operands[1]))
1631     {
1632       mvs_check_page (0, 8, 0);
1633       return \"SLL      %0,24\;SRA      %0,24\";
1634     }
1635   if (s_operand (operands[1], GET_MODE (operands[1])))
1636     {
1637       mvs_check_page (0, 8, 0);
1638       return \"ICM      %0,8,%1\;SRA    %0,24\";
1639     }
1640   mvs_check_page (0, 12, 0);
1641   return \"IC   %0,%1\;SLL      %0,24\;SRA      %0,24\";
1642 }"
1643    [(set_attr "length" "12")]
1644 )
1645
1646 ;
1647 ; extendqihi2 instruction pattern(s).
1648 ;
1649
1650 (define_insn "extendqihi2"
1651   [(set (match_operand:HI 0 "general_operand" "=d")
1652         (sign_extend:HI (match_operand:QI 1 "general_operand" "0m")))]
1653   ""
1654   "*
1655 {
1656   check_label_emit ();
1657   CC_STATUS_SET (operands[0], operands[1]);
1658   if (REG_P (operands[1]))
1659     {
1660       mvs_check_page (0, 8, 0);
1661       return \"SLL      %0,24\;SRA      %0,24\";
1662     }
1663   if (s_operand (operands[1], GET_MODE (operands[1])))
1664     {
1665       mvs_check_page (0, 8, 0);
1666       return \"ICM      %0,8,%1\;SRA    %0,24\";
1667     }
1668   mvs_check_page (0, 12, 0);
1669   return \"IC   %0,%1\;SLL      %0,24\;SRA      %0,24\";
1670 }"
1671    [(set_attr "length" "12")]
1672 )
1673
1674 ;
1675 ; zero_extendsidi2 instruction pattern(s).
1676 ;
1677
1678 (define_expand "zero_extendsidi2"
1679   [(set (match_operand:DI 0 "register_operand" "=d")
1680         (zero_extend:DI (match_operand:SI 1 "general_operand" "")))]
1681   ""
1682   "
1683 {
1684       emit_insn (gen_rtx_SET (VOIDmode,
1685                   operand_subword (operands[0], 0, 1, DImode), operands[1]));
1686       emit_insn (gen_rtx_SET (VOIDmode, operands[0],
1687                         gen_rtx_LSHIFTRT (DImode, operands[0],
1688                                 gen_rtx_CONST_INT (SImode, 32))));
1689   DONE;
1690 }")
1691
1692 ;
1693 ; zero_extendhisi2 instruction pattern(s).
1694 ;
1695
1696 (define_insn "zero_extendhisi2"
1697   [(set (match_operand:SI 0 "general_operand" "=d")
1698         (zero_extend:SI (match_operand:HI 1 "general_operand" "0")))]
1699   ""
1700   "*
1701 {
1702   check_label_emit ();
1703   /* AND only sets zero/not-zero bits not the arithmetic bits ... */
1704   CC_STATUS_INIT;
1705   mvs_check_page (0, 4, 4);
1706   return \"N    %1,=XL4'0000FFFF'\";
1707 }"
1708    [(set_attr "length" "4")]
1709 )
1710
1711 ;
1712 ; zero_extendqisi2 instruction pattern(s).
1713 ;
1714
1715 (define_insn "zero_extendqisi2"
1716   [(set (match_operand:SI 0 "general_operand" "=d,&d")
1717         (zero_extend:SI (match_operand:QI 1 "general_operand" "0i,m")))]
1718   ""
1719   "*
1720 {
1721   check_label_emit ();
1722   if (REG_P (operands[1]))
1723     {
1724       /* AND only sets zero/not-zero bits not the arithmetic bits ... */
1725       CC_STATUS_INIT;
1726       mvs_check_page (0, 4, 4);
1727       return \"N        %0,=XL4'000000FF'\";
1728     }
1729   if (GET_CODE (operands[1]) == CONST_INT)
1730     {
1731       mvs_check_page (0, 4, 0);
1732       return \"LA       %0,%c1(0,0)\";
1733     }
1734   CC_STATUS_INIT;
1735   mvs_check_page (0, 8, 0);
1736   return \"SLR  %0,%0\;IC       %0,%1\";
1737 }"
1738    [(set_attr "length" "8")]
1739 )
1740
1741 ;
1742 ; zero_extendqihi2 instruction pattern(s).
1743 ;
1744
1745 (define_insn "zero_extendqihi2"
1746   [(set (match_operand:HI 0 "general_operand" "=d,&d")
1747         (zero_extend:HI (match_operand:QI 1 "general_operand" "0i,m")))]
1748   ""
1749   "*
1750 {
1751   check_label_emit ();
1752   if (REG_P (operands[1]))
1753     {
1754       /* AND only sets zero/not-zero bits not the arithmetic bits ... */
1755       CC_STATUS_INIT;
1756       mvs_check_page (0, 4, 4);
1757       return \"N        %0,=XL4'000000FF'\";
1758     }
1759   if (GET_CODE (operands[1]) == CONST_INT)
1760     {
1761       mvs_check_page (0, 4, 0);
1762       return \"LA       %0,%c1(0,0)\";
1763     }
1764   CC_STATUS_INIT;
1765   mvs_check_page (0, 8, 0);
1766   return \"SLR  %0,%0\;IC       %0,%1\";
1767 }"
1768    [(set_attr "length" "8")]
1769 )
1770
1771 ;
1772 ; truncsihi2 instruction pattern(s).
1773 ;
1774
1775 (define_insn "truncsihi2"
1776   [(set (match_operand:HI 0 "general_operand" "=d,m")
1777         (truncate:HI (match_operand:SI 1 "general_operand" "0,d")))]
1778   ""
1779   "*
1780 {
1781   check_label_emit ();
1782   if (REG_P (operands[0]))
1783     {
1784       CC_STATUS_SET (operands[0], operands[1]);
1785       mvs_check_page (0, 8, 0);
1786       return \"SLL      %0,16\;SRA      %0,16\";
1787     }
1788   mvs_check_page (0, 4, 0);
1789   return \"STH  %1,%0\";
1790 }"
1791    [(set_attr "length" "8")]
1792 )
1793
1794 ;
1795 ; fix_truncdfsi2 instruction pattern(s).
1796 ;
1797
1798 (define_insn "fix_truncdfsi2"
1799   [(set (match_operand:SI 0 "general_operand" "=d")
1800         (fix:SI (truncate:DF (match_operand:DF 1 "general_operand" "+f"))))
1801         (clobber (reg:DF 16))]
1802   ""
1803   "*
1804 {
1805   check_label_emit ();
1806   CC_STATUS_INIT;
1807   if (REGNO (operands[1]) == 16)
1808     {
1809       mvs_check_page (0, 12, 8);
1810       return \"AD       0,=XL8'4F08000000000000'\;STD   0,140(,13)\;L   %0,144(,13)\";
1811     }
1812   mvs_check_page (0, 14, 8);
1813   return \"LDR  0,%1\;AD        0,=XL8'4F08000000000000'\;STD   0,140(,13)\;L   %0,144(,13)\";
1814 }"
1815    [(set_attr "length" "14")]
1816 )
1817
1818 ;
1819 ; floatsidf2 instruction pattern(s).
1820 ;
1821 ; LE/370 mode uses the float field of the TCA.
1822 ;
1823
1824 (define_insn "floatsidf2"
1825   [(set (match_operand:DF 0 "general_operand" "=f")
1826         (float:DF (match_operand:SI 1 "general_operand" "d")))]
1827   ""
1828   "*
1829 {
1830   check_label_emit ();
1831   CC_STATUS_INIT;
1832 #ifdef TARGET_ELF_ABI
1833   mvs_check_page (0, 22, 12);
1834   return \"MVC  140(4,13),=XL4'4E000000'\;ST    %1,144(,13)\;XI 144(13),128\;LD %0,140(,13)\;SD %0,=XL8'4E00000080000000'\";
1835 #else
1836   mvs_check_page (0, 16, 8);
1837   return \"ST   %1,508(,12)\;XI 508(12),128\;LD %0,504(,12)\;SD %0,=XL8'4E00000080000000'\";
1838 #endif
1839 }"
1840    [(set_attr "length" "22")]
1841 )
1842
1843 ;
1844 ; truncdfsf2 instruction pattern(s).
1845 ;
1846
1847 (define_insn "truncdfsf2"
1848   [(set (match_operand:SF 0 "general_operand" "=f")
1849         (float_truncate:SF (match_operand:DF 1 "general_operand" "f")))]
1850   ""
1851   "*
1852 {
1853   check_label_emit ();
1854   mvs_check_page (0, 2, 0);
1855   return \"LRER %0,%1\";
1856 }"
1857    [(set_attr "length" "2")]
1858 )
1859
1860 ;
1861 ; extendsfdf2 instruction pattern(s).
1862
1863
1864 (define_insn "extendsfdf2"
1865   [(set (match_operand:DF 0 "general_operand" "=f")
1866         (float_extend:DF (match_operand:SF 1 "general_operand" "fmF")))]
1867   ""
1868   "*
1869 {
1870   check_label_emit ();
1871   CC_STATUS_SET (0, const0_rtx);
1872   if (FP_REG_P (operands[1]))
1873     {
1874       if (REGNO (operands[0]) == REGNO (operands[1]))
1875         {
1876           mvs_check_page (0, 10, 0);
1877           return \"STE  %1,140(,13)\;SDR        %0,%0\;LE       %0,140(,13)\";
1878         }
1879       mvs_check_page (0, 4, 0);
1880       return \"SDR      %0,%0\;LER      %0,%1\";
1881     }
1882   mvs_check_page (0, 6, 0);
1883   return \"SDR  %0,%0\;LE       %0,%1\";
1884 }"
1885    [(set_attr "length" "10")]
1886 )
1887
1888 ;;
1889 ;;- Add instructions.
1890 ;;
1891
1892 ;
1893 ; adddi3 instruction pattern(s).
1894 ;
1895 ;
1896 ;(define_expand "adddi3"
1897 ;  [(set (match_operand:DI 0 "general_operand" "")
1898 ;       (plus:DI (match_operand:DI 1 "general_operand" "")
1899 ;                (match_operand:DI 2 "general_operand" "")))]
1900 ;  ""
1901 ;  "
1902 ;{
1903 ;  rtx label = gen_label_rtx ();
1904 ;  rtx op0_high = operand_subword (operands[0], 0, 1, DImode);
1905 ;  rtx op0_low = gen_lowpart (SImode, operands[0]);
1906 ;       
1907 ;  emit_insn (gen_rtx_SET (VOIDmode, op0_high,
1908 ;                   gen_rtx_PLUS (SImode,
1909 ;                           operand_subword (operands[1], 0, 1, DImode),
1910 ;                           operand_subword (operands[2], 0, 1, DImode))));
1911 ;  emit_jump_insn (gen_rtx_PARALLEL (VOIDmode, gen_rtvec (2,
1912 ;             gen_rtx_SET (VOIDmode, op0_low,
1913 ;                     gen_rtx_PLUS (SImode, gen_lowpart (SImode, operands[1]),
1914 ;                             gen_lowpart (SImode, operands[2]))),
1915 ;             gen_rtx_USE (VOIDmode, gen_rtx_LABEL_REF (VOIDmode, label)))));
1916 ;  emit_insn (gen_rtx_SET (VOIDmode, op0_high,
1917 ;                   gen_rtx_PLUS (SImode, op0_high,
1918 ;                           gen_rtx_CONST_INT (SImode, 1))));
1919 ;  emit_label (label);
1920 ;  DONE;
1921 ;}")
1922
1923 (define_insn ""
1924   [(set (match_operand:SI 0 "general_operand" "=d")
1925         (plus:SI (match_operand:SI 1 "general_operand" "%0")
1926                  (match_operand:SI 2 "general_operand" "g")))
1927    (use (label_ref (match_operand 3 "" "")))
1928 ;   (clobber (reg:SI 14))
1929    ]
1930   ""
1931   "*
1932 {
1933   int onpage;
1934
1935   check_label_emit ();
1936   onpage = mvs_check_label (CODE_LABEL_NUMBER (operands[3]));
1937   if (REG_P (operands[2]))
1938     {
1939       if (!onpage)
1940         {
1941           mvs_check_page (0, 8, 4);
1942           return \"ALR  %0,%2\;L        14,=A(%l3)\;BCR 12,14\";
1943         }
1944       if (mvs_check_page (0, 6, 0))
1945         {
1946           mvs_check_page (0, 2, 4);
1947           return \"ALR  %0,%2\;L        14,=A(%l3)\;BCR 12,14\";
1948         }
1949       return \"ALR      %0,%2\;BC       12,%l3\";
1950     }
1951   if (!onpage)
1952     {
1953       mvs_check_page (0, 10, 4);
1954       return \"AL       %0,%2\;L        14,=A(%l3)\;BCR 12,14\";
1955     }
1956   if (mvs_check_page (0, 8 ,0))
1957     {
1958       mvs_check_page (0, 2, 4);
1959       return \"AL       %0,%2\;L        14,=A(%l3)\;BCR 12,14\";
1960     }
1961   return \"AL   %0,%2\;BC       12,%l3\";
1962 }"
1963    [(set_attr "length" "10")]
1964 )
1965
1966 ;
1967 ; addsi3 instruction pattern(s).
1968 ;
1969 ; The following insn is used when it is known that operand one is an address,
1970 ; frame, stack or argument pointer, and operand two is a constant that is
1971 ; small enough to fit in the displacement field.
1972 ; Notice that we can't allow the frame pointer to used as a normal register
1973 ; because of this insn.
1974 ;
1975
1976 (define_insn ""
1977   [(set (match_operand:SI 0 "register_operand" "=d")
1978         (plus:SI (match_operand:SI 1 "general_operand" "%a")
1979                  (match_operand:SI 2 "immediate_operand" "J")))]
1980   "((REGNO (operands[1]) == FRAME_POINTER_REGNUM || REGNO (operands[1]) == ARG_POINTER_REGNUM || REGNO (operands[1]) == STACK_POINTER_REGNUM) && (unsigned) INTVAL (operands[2]) < 4096)"
1981   "*
1982 {
1983   check_label_emit ();
1984   CC_STATUS_INIT;  /* add assumes CC but LA doesnt set CC */
1985   mvs_check_page (0, 4, 0);
1986   return \"LA   %0,%c2(,%1)\";
1987 }"
1988    [(set_attr "length" "4")]
1989 )
1990
1991 ; This insn handles additions that are relative to the frame pointer.
1992
1993 (define_insn ""
1994   [(set (match_operand:SI 0 "register_operand" "=d")
1995          (plus:SI (match_operand:SI 1 "register_operand" "%a")
1996                   (match_operand:SI 2 "immediate_operand" "i")))]
1997   "REGNO (operands[1]) == FRAME_POINTER_REGNUM"
1998   "*
1999 {
2000   check_label_emit ();
2001   if ((unsigned) INTVAL (operands[2]) < 4096)
2002     {
2003       CC_STATUS_INIT;  /* add assumes CC but LA doesnt set CC */
2004       mvs_check_page (0, 4, 0);
2005       return \"LA       %0,%c2(,%1)\";
2006     }
2007   if (REGNO (operands[1]) == REGNO (operands[0]))
2008     {
2009       CC_STATUS_INIT;
2010       mvs_check_page (0, 4, 0);
2011       return \"A        %0,%2\";
2012     }
2013   mvs_check_page (0, 6, 0);
2014   return \"L    %0,%2\;AR       %0,%1\";
2015 }"
2016    [(set_attr "length" "6")]
2017 )
2018
2019 ;;
2020 ;; The CC status bits for the arithmetic instructions are handled
2021 ;; in the NOTICE_UPDATE_CC macro (yeah???) and so they do not need
2022 ;; to be set below.  They only need to be invalidated if *not* set 
2023 ;; (e.g. by BCTR) ... yeah I think that's right ...
2024 ;; 
2025
2026 (define_insn "addsi3"
2027   [(set (match_operand:SI 0 "general_operand" "=d")
2028         (plus:SI (match_operand:SI 1 "general_operand" "%0")
2029                  (match_operand:SI 2 "general_operand" "g")))]
2030   ""
2031   "*
2032 {
2033   check_label_emit ();
2034   if (REG_P (operands[2]))
2035     {
2036       mvs_check_page (0, 2, 0);
2037       return \"AR       %0,%2\";
2038     }
2039   if (GET_CODE (operands[2]) == CONST_INT)
2040     {
2041       if (INTVAL (operands[2]) == -1)
2042         {
2043           CC_STATUS_INIT;  /* add assumes CC but BCTR doesnt set CC */
2044           mvs_check_page (0, 2, 0);
2045           return \"BCTR %0,0\";
2046         }
2047     }
2048   mvs_check_page (0, 4, 0);
2049   return \"A    %0,%2\";
2050 }"
2051    [(set_attr "length" "4")]
2052 )
2053
2054 ;
2055 ; addhi3 instruction pattern(s).
2056 ;
2057
2058 (define_insn "addhi3"
2059   [(set (match_operand:HI 0 "general_operand" "=d")
2060         (plus:HI (match_operand:HI 1 "general_operand" "%0")
2061                  (match_operand:HI 2 "general_operand" "dmi")))]
2062   ""
2063   "*
2064 {
2065   check_label_emit ();
2066   if (REG_P (operands[2]))
2067     {
2068       mvs_check_page (0, 8, 0);
2069       return \"STH      %2,140(,13)\;AH %0,140(,13)\";
2070     }
2071   if (GET_CODE (operands[2]) == CONST_INT)
2072     {
2073       if (INTVAL (operands[2]) == -1)
2074         {
2075           CC_STATUS_INIT;  /* add assumes CC but BCTR doesnt set CC */
2076           mvs_check_page (0, 2, 0);
2077           return \"BCTR %0,0\";
2078         }
2079       mvs_check_page (0, 4, 0);
2080       return \"AH       %0,%H2\";
2081     }
2082   mvs_check_page (0, 4, 0);
2083   return \"AH   %0,%2\";
2084 }"
2085    [(set_attr "length" "8")]
2086 )
2087
2088 ;
2089 ; addqi3 instruction pattern(s).
2090 ;
2091
2092 (define_insn "addqi3"
2093   [(set (match_operand:QI 0 "general_operand" "=d")
2094         (plus:QI (match_operand:QI 1 "general_operand" "%a")
2095                  (match_operand:QI 2 "general_operand" "ai")))]
2096   ""
2097   "*
2098 {
2099   check_label_emit ();
2100   CC_STATUS_INIT;  /* add assumes CC but LA doesnt set CC */
2101   mvs_check_page (0, 4, 0);
2102   if (REG_P (operands[2]))
2103     return \"LA %0,0(%1,%2)\";
2104   return \"LA   %0,%B2(,%1)\";
2105 }"
2106    [(set_attr "length" "4")]
2107 )
2108
2109 ;
2110 ; adddf3 instruction pattern(s).
2111 ;
2112
2113 (define_insn "adddf3"
2114   [(set (match_operand:DF 0 "general_operand" "=f")
2115         (plus:DF (match_operand:DF 1 "general_operand" "%0")
2116                  (match_operand:DF 2 "general_operand" "fmF")))]
2117   ""
2118   "*
2119 {
2120   check_label_emit ();
2121   if (FP_REG_P (operands[2]))
2122     {
2123       mvs_check_page (0, 2, 0);
2124       return \"ADR      %0,%2\";
2125     }
2126   mvs_check_page (0, 4, 0);
2127   return \"AD   %0,%2\";
2128 }"
2129    [(set_attr "length" "4")]
2130 )
2131
2132 ;
2133 ; addsf3 instruction pattern(s).
2134 ;
2135
2136 (define_insn "addsf3"
2137   [(set (match_operand:SF 0 "general_operand" "=f")
2138         (plus:SF (match_operand:SF 1 "general_operand" "%0")
2139                  (match_operand:SF 2 "general_operand" "fmF")))]
2140   ""
2141   "*
2142 {
2143   check_label_emit ();
2144   if (FP_REG_P (operands[2]))
2145     {
2146       mvs_check_page (0, 2, 0);
2147       return \"AER      %0,%2\";
2148     }
2149   mvs_check_page (0, 4, 0);
2150   return \"AE   %0,%2\";
2151 }"
2152    [(set_attr "length" "4")]
2153 )
2154
2155 ;;
2156 ;;- Subtract instructions.
2157 ;;
2158
2159 ;
2160 ; subdi3 instruction pattern(s).
2161 ;
2162 ;
2163 ;(define_expand "subdi3"
2164 ;  [(set (match_operand:DI 0 "general_operand" "")
2165 ;       (minus:DI (match_operand:DI 1 "general_operand" "")
2166 ;                 (match_operand:DI 2 "general_operand" "")))]
2167 ;  ""
2168 ;  "
2169 ;{
2170 ;  rtx label = gen_label_rtx ();
2171 ;  rtx op0_high = operand_subword (operands[0], 0, 1, DImode);
2172 ;  rtx op0_low = gen_lowpart (SImode, operands[0]);
2173 ;       
2174 ;  emit_insn (gen_rtx_SET (VOIDmode, op0_high,
2175 ;                   gen_rtx_MINUS (SImode,
2176 ;                             operand_subword (operands[1], 0, 1, DImode),
2177 ;                             operand_subword (operands[2], 0, 1, DImode))));
2178 ;  emit_jump_insn (gen_rtx_PARALLEL (VOIDmode, gen_rtvec (2,
2179 ;                   gen_rtx_SET (VOIDmode, op0_low,
2180 ;                             gen_rtx_MINUS (SImode,
2181 ;                                     gen_lowpart (SImode, operands[1]),
2182 ;                                     gen_lowpart (SImode, operands[2]))),
2183 ;                   gen_rtx_USE (VOIDmode,
2184 ;                             gen_rtx_LABEL_REF (VOIDmode, label)))));
2185 ;  emit_insn (gen_rtx_SET (VOIDmode, op0_high,
2186 ;                     gen_rtx_MINUS (SImode, op0_high,
2187 ;                             gen_rtx_CONST_INT (SImode, 1))));
2188 ;  emit_label (label);
2189 ;  DONE;
2190 ;}")
2191
2192 (define_insn ""
2193   [(set (match_operand:SI 0 "general_operand" "=d")
2194         (minus:SI (match_operand:SI 1 "general_operand" "0")
2195                   (match_operand:SI 2 "general_operand" "g")))
2196    (use (label_ref (match_operand 3 "" "")))
2197 ;   (clobber (reg:SI 14))
2198    ]
2199   ""
2200   "*
2201 {
2202   int onpage;
2203
2204   check_label_emit ();
2205   CC_STATUS_INIT;
2206   onpage = mvs_check_label (CODE_LABEL_NUMBER (operands[3]));
2207   if (REG_P (operands[2]))
2208     {
2209       if (!onpage)
2210         {
2211           mvs_check_page (0, 8, 4);
2212           return \"SLR  %0,%2\;L        14,=A(%l3)\;BCR 12,14\";
2213         }
2214       if (mvs_check_page (0, 6, 0))
2215         {
2216           mvs_check_page (0, 2, 4);
2217           return \"SLR  %0,%2\;L        14,=A(%l3)\;BCR 12,14\";
2218         }
2219       return \"SLR      %0,%2\;BC       12,%l3\";
2220     }
2221   if (!onpage)
2222     {
2223       mvs_check_page (0, 10, 4);
2224       return \"SL       %0,%2\;L        14,=A(%l3)\;BCR 12,14\";
2225     }
2226   if (mvs_check_page (0, 8, 0))
2227     {
2228       mvs_check_page (0, 2, 4);
2229       return \"SL       %0,%2\;L        14,=A(%l3)\;BCR 12,14\";
2230     }
2231   return \"SL   %0,%2\;BC       12,%l3\";
2232 }"
2233    [(set_attr "length" "10")]
2234 )
2235
2236 ;
2237 ; subsi3 instruction pattern(s).
2238 ;
2239
2240 (define_insn "subsi3"
2241   [(set (match_operand:SI 0 "general_operand" "=d")
2242         (minus:SI (match_operand:SI 1 "general_operand" "0")
2243                   (match_operand:SI 2 "general_operand" "g")))]
2244   ""
2245   "*
2246 {
2247   check_label_emit ();
2248   if (REG_P (operands[2]))
2249     {
2250       mvs_check_page (0, 2, 0);
2251       return \"SR       %0,%2\";
2252     }
2253   if (operands[2] == const1_rtx)
2254     {
2255       CC_STATUS_INIT;  /* subtract assumes CC but BCTR doesnt set CC */
2256       mvs_check_page (0, 2, 0);
2257       return \"BCTR     %0,0\";
2258     }
2259   mvs_check_page (0, 4, 0);
2260   return \"S    %0,%2\";
2261 }"
2262    [(set_attr "length" "4")]
2263 )
2264
2265 ;
2266 ; subhi3 instruction pattern(s).
2267 ;
2268
2269 (define_insn "subhi3"
2270   [(set (match_operand:HI 0 "general_operand" "=d")
2271         (minus:HI (match_operand:HI 1 "general_operand" "0")
2272                   (match_operand:HI 2 "general_operand" "g")))]
2273   ""
2274   "*
2275 {
2276   check_label_emit ();
2277   if (REG_P (operands[2]))
2278     {
2279       mvs_check_page (0, 8, 0);
2280       return \"STH      %2,140(,13)\;SH %0,140(,13)\";
2281     }
2282   if (operands[2] == const1_rtx)
2283     {
2284       CC_STATUS_INIT;  /* subtract assumes CC but BCTR doesnt set CC */
2285       mvs_check_page (0, 2, 0);
2286       return \"BCTR     %0,0\";
2287     }
2288   if (GET_CODE (operands[2]) == CONST_INT)
2289     {
2290       mvs_check_page (0, 4, 0);
2291       return \"SH       %0,%H2\";
2292     }
2293   mvs_check_page (0, 4, 0);
2294   return \"SH   %0,%2\";
2295 }"
2296    [(set_attr "length" "8")]
2297 )
2298
2299 ;
2300 ; subqi3 instruction pattern(s).
2301 ;
2302
2303 (define_expand "subqi3"
2304   [(set (match_operand:QI 0 "general_operand" "=d")
2305         (minus:QI (match_operand:QI 1 "general_operand" "0")
2306                   (match_operand:QI 2 "general_operand" "di")))]
2307   ""
2308   "
2309 {
2310   if (REG_P (operands[2]))
2311     {
2312       emit_insn (gen_rtx_SET (VOIDmode, operands[0],
2313                         gen_rtx_MINUS (QImode, operands[1], operands[2])));
2314     }
2315   else
2316     {
2317       emit_insn (gen_rtx_SET (VOIDmode, operands[0],
2318                         gen_rtx_PLUS (QImode, operands[1],
2319                                  negate_rtx (QImode, operands[2]))));
2320     }
2321   DONE;
2322 }")
2323
2324 (define_insn ""
2325   [(set (match_operand:QI 0 "register_operand" "=d")
2326         (minus:QI (match_operand:QI 1 "register_operand" "0")
2327                  (match_operand:QI 2 "register_operand" "d")))]
2328   ""
2329   "*
2330 {
2331   check_label_emit ();
2332   mvs_check_page (0, 2, 0);
2333   return \"SR   %0,%2\";
2334 }"
2335    [(set_attr "length" "2")]
2336 )
2337
2338 ;
2339 ; subdf3 instruction pattern(s).
2340 ;
2341
2342 (define_insn "subdf3"
2343   [(set (match_operand:DF 0 "general_operand" "=f")
2344         (minus:DF (match_operand:DF 1 "general_operand" "0")
2345                   (match_operand:DF 2 "general_operand" "fmF")))]
2346   ""
2347   "*
2348 {
2349   check_label_emit ();
2350   if (FP_REG_P (operands[2]))
2351     {
2352       mvs_check_page (0, 2, 0);
2353       return \"SDR      %0,%2\";
2354     }
2355   mvs_check_page (0, 4, 0);
2356   return \"SD   %0,%2\";
2357 }"
2358    [(set_attr "length" "4")]
2359 )
2360
2361 ;
2362 ; subsf3 instruction pattern(s).
2363 ;
2364
2365 (define_insn "subsf3"
2366   [(set (match_operand:SF 0 "general_operand" "=f")
2367         (minus:SF (match_operand:SF 1 "general_operand" "0")
2368                   (match_operand:SF 2 "general_operand" "fmF")))]
2369   ""
2370   "*
2371 {
2372   check_label_emit ();
2373   if (FP_REG_P (operands[2]))
2374     {
2375       mvs_check_page (0, 2, 0);
2376       return \"SER      %0,%2\";
2377     }
2378   mvs_check_page (0, 4, 0);
2379   return \"SE   %0,%2\";
2380 }"
2381    [(set_attr "length" "4")]
2382 )
2383
2384 ;;
2385 ;;- Multiply instructions.
2386 ;;
2387
2388 ;
2389 ; mulsi3 instruction pattern(s).
2390 ;
2391
2392 (define_expand "mulsi3"
2393   [(set (match_operand:SI 0 "general_operand" "")
2394         (mult:SI (match_operand:SI 1 "general_operand" "")
2395                  (match_operand:SI 2 "general_operand" "")))]
2396   ""
2397   "
2398 {
2399   if (GET_CODE (operands[1]) == CONST_INT
2400       && CONST_OK_FOR_LETTER_P (INTVAL (operands[1]), 'K'))
2401     {
2402       emit_insn (gen_rtx_SET (VOIDmode, operands[0],
2403                           gen_rtx_MULT (SImode, operands[2], operands[1])));
2404     }
2405   else if (GET_CODE (operands[2]) == CONST_INT
2406            && CONST_OK_FOR_LETTER_P (INTVAL (operands[2]), 'K'))
2407     {
2408       emit_insn (gen_rtx_SET (VOIDmode, operands[0],
2409                           gen_rtx_MULT (SImode, operands[1], operands[2])));
2410     }
2411   else
2412     {
2413       rtx r = gen_reg_rtx (DImode);
2414
2415       /* XXX trouble.  Below we generate some rtx's that model what
2416        * is really supposed to happen with multiply on the 370/390
2417        * hardware, and that is all well & good.  However, during optimization
2418        * it can happen that the two operands are exchanged (after all, 
2419        * multiplication is commutitive), in which case the doubleword
2420        * ends up in memory and everything is hosed.  The gen_reg_rtx
2421        * should have kept it in a reg ...  We hack around this
2422        * below, in the M/MR isntruction pattern, and constrain it to
2423        * \"di\" instead of \"g\".  But this still ends up with lots & lots of
2424        * movement between registers & memory and is an awful waste.
2425        * Dunno how to untwist it elegantly; but it seems to work for now.
2426        */
2427       emit_insn (gen_rtx_SET (VOIDmode,
2428                           gen_rtx_SUBREG (SImode, r, 1), operands[1]));
2429       emit_insn (gen_rtx_SET (VOIDmode, r,
2430                           gen_rtx_MULT (SImode, r, operands[2])));
2431       emit_insn (gen_rtx_SET (VOIDmode, operands[0],
2432                           gen_rtx_SUBREG (SImode, r, 1)));
2433     }
2434   DONE;
2435 }")
2436
2437 (define_insn ""
2438   [(set (match_operand:SI 0 "general_operand" "=d")
2439         (mult:SI (match_operand:SI 1 "general_operand" "%0")
2440                  (match_operand:SI 2 "immediate_operand" "K")))]
2441   ""
2442   "*
2443 {
2444   check_label_emit ();
2445   mvs_check_page (0, 4, 0);
2446   return \"MH   %0,%H2\";
2447 }"
2448    [(set_attr "length" "4")]
2449 )
2450
2451 ;; XXX see comments in mulsi above.
2452 (define_insn ""
2453   [(set (match_operand:DI 0 "register_operand" "=d")
2454         (mult:DI (match_operand:DI 1 "general_operand" "%0")
2455 ;; XXX see above (match_operand:SI 2 "general_operand" "g")))]
2456                  (match_operand:SI 2 "general_operand" "di")))]
2457   ""
2458   "*
2459 {
2460   check_label_emit ();
2461   if (REG_P (operands[2]))
2462     {
2463       mvs_check_page (0, 2, 0);
2464       return \"MR       %0,%2\";
2465     }
2466   mvs_check_page (0, 4, 0);
2467   return \"M    %0,%2\";
2468 }"
2469    [(set_attr "length" "4")]
2470 )
2471
2472 ;
2473 ; muldf3 instruction pattern(s).
2474 ;
2475
2476 (define_insn "muldf3"
2477   [(set (match_operand:DF 0 "general_operand" "=f")
2478         (mult:DF (match_operand:DF 1 "general_operand" "%0")
2479                  (match_operand:DF 2 "general_operand" "fmF")))]
2480   ""
2481   "*
2482 {
2483   check_label_emit ();
2484   if (FP_REG_P (operands[2]))
2485     {
2486       mvs_check_page (0, 2, 0);
2487       return \"MDR      %0,%2\";
2488     }
2489   mvs_check_page (0, 4, 0);
2490   return \"MD   %0,%2\";
2491 }"
2492    [(set_attr "length" "4")]
2493 )
2494
2495 ;
2496 ; mulsf3 instruction pattern(s).
2497 ;
2498
2499 (define_insn "mulsf3"
2500   [(set (match_operand:SF 0 "general_operand" "=f")
2501         (mult:SF (match_operand:SF 1 "general_operand" "%0")
2502                  (match_operand:SF 2 "general_operand" "fmF")))]
2503   ""
2504   "*
2505 {
2506   check_label_emit ();
2507   if (FP_REG_P (operands[2]))
2508     {
2509       mvs_check_page (0, 2, 0);
2510       return \"MER      %0,%2\";
2511     }
2512   mvs_check_page (0, 4, 0);
2513   return \"ME   %0,%2\";
2514 }"
2515    [(set_attr "length" "4")]
2516 )
2517
2518 ;;
2519 ;;- Divide instructions.
2520 ;;
2521
2522 ;
2523 ; divsi3 instruction pattern(s).
2524 ;
2525
2526 (define_expand "divsi3"
2527   [(set (match_operand:SI 0 "general_operand" "")
2528         (div:SI (match_operand:SI 1 "general_operand" "")
2529                 (match_operand:SI 2 "general_operand" "")))]
2530   ""
2531   "
2532 {
2533   rtx r = gen_reg_rtx (DImode);
2534
2535   emit_insn (gen_extendsidi2 (r, operands[1]));
2536   emit_insn (gen_rtx_SET (VOIDmode, r,
2537                         gen_rtx_DIV (SImode, r, operands[2])));
2538   emit_insn (gen_rtx_SET (VOIDmode, operands[0],
2539                         gen_rtx_SUBREG (SImode, r, 1)));
2540   DONE;
2541 }")
2542
2543
2544 ;
2545 ; udivsi3 instruction pattern(s).
2546 ;
2547
2548 (define_expand "udivsi3"
2549   [(set (match_operand:SI 0 "general_operand" "")
2550         (udiv:SI (match_operand:SI 1 "general_operand" "")
2551                  (match_operand:SI 2 "general_operand" "")))]
2552   ""
2553   "
2554 {
2555   rtx dr = gen_reg_rtx (DImode);
2556   rtx dr_0 = gen_rtx_SUBREG (SImode, dr, 0);
2557   rtx dr_1 = gen_rtx_SUBREG (SImode, dr, 1);
2558
2559
2560   if (GET_CODE (operands[2]) == CONST_INT)
2561     {
2562       if (INTVAL (operands[2]) > 0)
2563         {
2564           emit_insn (gen_zero_extendsidi2 (dr, operands[1]));
2565           emit_insn (gen_rtx_SET (VOIDmode, dr,
2566                         gen_rtx_DIV (SImode, dr, operands[2])));
2567         }
2568       else
2569         {
2570           rtx label1 = gen_label_rtx ();
2571
2572           emit_insn (gen_rtx_SET (VOIDmode, dr_0, operands[1]));
2573           emit_insn (gen_rtx_SET (VOIDmode, dr_1, const0_rtx));
2574           emit_insn (gen_cmpsi (dr_0, operands[2]));
2575           emit_jump_insn (gen_bltu (label1));
2576           emit_insn (gen_rtx_SET (VOIDmode, dr_1, const1_rtx));
2577           emit_label (label1);
2578         }
2579     }
2580   else
2581     {
2582       rtx label1 = gen_label_rtx ();
2583       rtx label2 = gen_label_rtx ();
2584       rtx label3 = gen_label_rtx ();
2585       rtx sr = gen_reg_rtx (SImode);
2586
2587       emit_insn (gen_rtx_SET (VOIDmode, dr_0, operands[1]));
2588       emit_insn (gen_rtx_SET (VOIDmode, sr, operands[2]));
2589       emit_insn (gen_rtx_SET (VOIDmode, dr_1, const0_rtx));
2590       emit_insn (gen_cmpsi (sr, dr_0));
2591       emit_jump_insn (gen_bgtu (label3));
2592       emit_insn (gen_cmpsi (sr, const1_rtx));
2593       emit_jump_insn (gen_blt (label2));
2594       emit_insn (gen_cmpsi (sr, const1_rtx));
2595       emit_jump_insn (gen_beq (label1));
2596       emit_insn (gen_rtx_SET (VOIDmode, dr,
2597                           gen_rtx_LSHIFTRT (DImode, dr,
2598                                     gen_rtx_CONST_INT (SImode, 32))));
2599       emit_insn (gen_rtx_SET (VOIDmode, dr,
2600                     gen_rtx_DIV (SImode, dr, sr)));
2601       emit_jump_insn (gen_jump (label3));
2602       emit_label (label1);
2603       emit_insn (gen_rtx_SET (VOIDmode, dr_1, dr_0));
2604       emit_jump_insn (gen_jump (label3));
2605       emit_label (label2);
2606       emit_insn (gen_rtx_SET (VOIDmode, dr_1, const1_rtx));
2607       emit_label (label3);
2608     }
2609   emit_insn (gen_rtx_SET (VOIDmode, operands[0], dr_1));
2610
2611   DONE;
2612 }")
2613
2614 ; This is used by divsi3 & udivsi3.
2615
2616 (define_insn ""
2617   [(set (match_operand:DI 0 "register_operand" "=d")
2618         (div:DI (match_operand:DI 1 "register_operand" "0")
2619                 (match_operand:SI 2 "general_operand" "dm")))]
2620   ""
2621   "*
2622 {
2623   check_label_emit ();
2624   if (REG_P (operands[2]))
2625     {
2626       mvs_check_page (0, 2, 0);
2627       return \"DR       %0,%2\";
2628     }
2629   mvs_check_page (0, 4, 0);
2630   return \"D    %0,%2\";
2631 }"
2632    [(set_attr "length" "4")]
2633 )
2634
2635 ;
2636 ; divdf3 instruction pattern(s).
2637 ;
2638
2639 (define_insn "divdf3"
2640   [(set (match_operand:DF 0 "general_operand" "=f")
2641         (div:DF (match_operand:DF 1 "general_operand" "0")
2642                 (match_operand:DF 2 "general_operand" "fmF")))]
2643   ""
2644   "*
2645 {
2646   check_label_emit ();
2647   if (FP_REG_P (operands[2]))
2648     {
2649       mvs_check_page (0, 2, 0);
2650       return \"DDR      %0,%2\";
2651     }
2652   mvs_check_page (0, 4, 0);
2653   return \"DD   %0,%2\";
2654 }"
2655    [(set_attr "length" "4")]
2656 )
2657
2658 ;
2659 ; divsf3 instruction pattern(s).
2660 ;
2661
2662 (define_insn "divsf3"
2663   [(set (match_operand:SF 0 "general_operand" "=f")
2664         (div:SF (match_operand:SF 1 "general_operand" "0")
2665                 (match_operand:SF 2 "general_operand" "fmF")))]
2666   ""
2667   "*
2668 {
2669   check_label_emit ();
2670   if (FP_REG_P (operands[2]))
2671     {
2672       mvs_check_page (0, 2, 0);
2673       return \"DER      %0,%2\";
2674     }
2675   mvs_check_page (0, 4, 0);
2676   return \"DE   %0,%2\";
2677 }"
2678    [(set_attr "length" "4")]
2679 )
2680
2681 ;;
2682 ;;- Modulo instructions.
2683 ;;
2684
2685 ;
2686 ; modsi3 instruction pattern(s).
2687 ;
2688
2689 (define_expand "modsi3"
2690   [(set (match_operand:SI 0 "general_operand" "")
2691         (mod:SI (match_operand:SI 1 "general_operand" "")
2692                 (match_operand:SI 2 "general_operand" "")))]
2693   ""
2694   "
2695 {
2696   rtx r = gen_reg_rtx (DImode);
2697
2698   emit_insn (gen_extendsidi2 (r, operands[1]));
2699   emit_insn (gen_rtx_SET (VOIDmode, r,
2700                         gen_rtx_MOD (SImode, r, operands[2])));
2701   emit_insn (gen_rtx_SET (VOIDmode, operands[0],
2702                         gen_rtx_SUBREG (SImode, r, 0)));
2703   DONE;
2704 }")
2705
2706 ;
2707 ; umodsi3 instruction pattern(s).
2708 ;
2709
2710 (define_expand "umodsi3"
2711   [(set (match_operand:SI 0 "general_operand" "")
2712         (umod:SI (match_operand:SI 1 "general_operand" "")
2713                  (match_operand:SI 2 "general_operand" "")))]
2714   ""
2715   "
2716 {
2717   rtx dr = gen_reg_rtx (DImode);
2718   rtx dr_0 = gen_rtx_SUBREG (SImode, dr, 0);
2719
2720   emit_insn (gen_rtx_SET (VOIDmode, dr_0, operands[1]));
2721
2722   if (GET_CODE (operands[2]) == CONST_INT)
2723     {
2724       if (INTVAL (operands[2]) > 0)
2725         {
2726           emit_insn (gen_rtx_SET (VOIDmode, dr,
2727                               gen_rtx_LSHIFTRT (DImode, dr,
2728                                         gen_rtx_CONST_INT (SImode, 32))));
2729           emit_insn (gen_rtx_SET (VOIDmode, dr,
2730                         gen_rtx_MOD (SImode, dr, operands[2])));
2731         }
2732       else
2733         {
2734           rtx label1 = gen_label_rtx ();
2735           rtx sr = gen_reg_rtx (SImode);
2736
2737           emit_insn (gen_rtx_SET (VOIDmode, sr, operands[2]));
2738           emit_insn (gen_cmpsi (dr_0, sr));
2739           emit_jump_insn (gen_bltu (label1));
2740           emit_insn (gen_rtx_SET (VOIDmode, sr, gen_rtx_ABS (SImode, sr)));
2741           emit_insn (gen_rtx_SET (VOIDmode, dr_0,
2742                               gen_rtx_PLUS (SImode, dr_0, sr)));
2743           emit_label (label1);
2744         }
2745     }
2746   else
2747     {
2748       rtx label1 = gen_label_rtx ();
2749       rtx label2 = gen_label_rtx ();
2750       rtx label3 = gen_label_rtx ();
2751       rtx sr = gen_reg_rtx (SImode);
2752
2753       emit_insn (gen_rtx_SET (VOIDmode, dr_0, operands[1]));
2754       emit_insn (gen_rtx_SET (VOIDmode, sr, operands[2]));
2755       emit_insn (gen_cmpsi (sr, dr_0));
2756       emit_jump_insn (gen_bgtu (label3));
2757       emit_insn (gen_cmpsi (sr, const1_rtx));
2758       emit_jump_insn (gen_blt (label2));
2759       emit_insn (gen_cmpsi (sr, const1_rtx));
2760       emit_jump_insn (gen_beq (label1));
2761       emit_insn (gen_rtx_SET (VOIDmode, dr,
2762                           gen_rtx_LSHIFTRT (DImode, dr,
2763                                     gen_rtx_CONST_INT (SImode, 32))));
2764       emit_insn (gen_rtx_SET (VOIDmode, dr, gen_rtx_MOD (SImode, dr, sr)));
2765       emit_jump_insn (gen_jump (label3));
2766       emit_label (label1);
2767       emit_insn (gen_rtx_SET (VOIDmode, dr_0, const0_rtx));
2768       emit_jump_insn (gen_jump (label3));
2769       emit_label (label2);
2770       emit_insn (gen_rtx_SET (VOIDmode, dr_0,
2771                           gen_rtx_MINUS (SImode, dr_0, sr)));
2772       emit_label (label3);
2773
2774     }
2775   emit_insn (gen_rtx_SET (VOIDmode, operands[0], dr_0));
2776
2777   DONE;
2778 }")
2779
2780 ; This is used by modsi3 & umodsi3.
2781
2782 (define_insn ""
2783   [(set (match_operand:DI 0 "register_operand" "=d")
2784         (mod:DI (match_operand:DI 1 "register_operand" "0")
2785                 (match_operand:SI 2 "general_operand" "dm")))]
2786   ""
2787   "*
2788 {
2789   check_label_emit ();
2790   if (REG_P (operands[2]))
2791     {
2792       mvs_check_page (0, 2, 0);
2793       return \"DR       %0,%2\";
2794     }
2795   mvs_check_page (0, 4, 0);
2796   return \"D    %0,%2\";
2797 }"
2798    [(set_attr "length" "4")]
2799 )
2800
2801 ;;
2802 ;;- And instructions.
2803 ;;
2804
2805 ;
2806 ; anddi3 instruction pattern(s).
2807 ;
2808
2809 ;(define_expand "anddi3"
2810 ;  [(set (match_operand:DI 0 "general_operand" "")
2811 ;       (and:DI (match_operand:DI 1 "general_operand" "")
2812 ;               (match_operand:DI 2 "general_operand" "")))]
2813 ;  ""
2814 ;  "
2815 ;{
2816 ;  rtx gen_andsi3();
2817 ;
2818 ;  emit_insn (gen_andsi3 (operand_subword (operands[0], 0, 1, DImode),
2819 ;                        operand_subword (operands[1], 0, 1, DImode),
2820 ;                        operand_subword (operands[2], 0, 1, DImode)));
2821 ;  emit_insn (gen_andsi3 (gen_lowpart (SImode, operands[0]),
2822 ;                        gen_lowpart (SImode, operands[1]),
2823 ;                        gen_lowpart (SImode, operands[2])));
2824 ;  DONE;
2825 ;}")
2826
2827 ;
2828 ; andsi3 instruction pattern(s).
2829 ;
2830
2831 (define_insn ""
2832   [(set (match_operand:SI 0 "r_or_s_operand" "=d,m")
2833         (and:SI (match_operand:SI 1 "r_or_s_operand" "%0,0")
2834                 (match_operand:SI 2 "r_or_s_operand" "g,mi")))]
2835   "TARGET_CHAR_INSTRUCTIONS"
2836   "*
2837 {
2838   check_label_emit ();
2839   CC_STATUS_INIT;  /* and sets CC but not how we want it */
2840   if (REG_P (operands[2]))
2841     {
2842       mvs_check_page (0, 2, 0);
2843       return \"NR       %0,%2\";
2844     }
2845   if (REG_P (operands[0]))
2846     {
2847       mvs_check_page (0, 4, 0);
2848       return \"N        %0,%2\";
2849     }
2850   mvs_check_page (0, 6, 0);
2851   return \"NC   %O0(4,%R0),%2\";
2852 }"
2853    [(set_attr "length" "6")]
2854 )
2855
2856 (define_insn "andsi3"
2857   [(set (match_operand:SI 0 "general_operand" "=d")
2858         (and:SI (match_operand:SI 1 "general_operand" "%0")
2859                 (match_operand:SI 2 "general_operand" "g")))]
2860   ""
2861   "*
2862 {
2863   check_label_emit ();
2864   CC_STATUS_INIT;  /* and sets CC but not how we want it */
2865   if (REG_P (operands[2]))
2866     {
2867       mvs_check_page (0, 2, 0);
2868       return \"NR       %0,%2\";
2869     }
2870   mvs_check_page (0, 4, 0);
2871   return \"N    %0,%2\";
2872 }"
2873    [(set_attr "length" "4")]
2874 )
2875
2876 ;
2877 ; andhi3 instruction pattern(s).
2878 ;
2879
2880 (define_insn ""
2881   [(set (match_operand:HI 0 "r_or_s_operand" "=d,m")
2882         (and:HI (match_operand:HI 1 "r_or_s_operand" "%0,0")
2883                 (match_operand:HI 2 "r_or_s_operand" "di,mi")))]
2884   "TARGET_CHAR_INSTRUCTIONS"
2885   "*
2886 {
2887   check_label_emit ();
2888   CC_STATUS_INIT;  /* and sets CC but not how we want it */
2889   if (REG_P (operands[2]))
2890     {
2891       mvs_check_page (0, 2, 0);
2892       return \"NR       %0,%2\";
2893     }
2894   if (REG_P (operands[0]))
2895     {
2896       /* %K2 == sign extend operand to 32 bits so that CH works */
2897       mvs_check_page (0, 4, 0);
2898       if (GET_CODE (operands[2]) == CONST_INT)
2899          return \"N     %0,%K2\";
2900       return \"N        %0,%2\";
2901     }
2902   if (GET_CODE (operands[2]) == CONST_INT)
2903     {
2904       mvs_check_page (0, 6, 0);
2905       return \"NC       %O0(2,%R0),%H2\";
2906     }
2907   mvs_check_page (0, 6, 0);
2908   return \"NC   %O0(2,%R0),%2\";
2909 }"
2910    [(set_attr "length" "6")]
2911 )
2912
2913 (define_insn "andhi3"
2914   [(set (match_operand:HI 0 "general_operand" "=d")
2915         (and:HI (match_operand:HI 1 "general_operand" "%0")
2916                 (match_operand:HI 2 "general_operand" "di")))]
2917   ""
2918   "*
2919 {
2920   check_label_emit ();
2921   CC_STATUS_INIT;  /* and sets CC but not how we want it */
2922   if (GET_CODE (operands[2]) == CONST_INT)
2923     {
2924       /* %K2 == sign extend operand to 32 bits so that CH works */
2925       mvs_check_page (0, 4, 0);
2926       return \"N        %0,%K2\";
2927     }
2928   mvs_check_page (0, 2, 0);
2929   return \"NR   %0,%2\";
2930 }"
2931    [(set_attr "length" "4")]
2932 )
2933
2934 ;
2935 ; andqi3 instruction pattern(s).
2936 ;
2937
2938 (define_insn ""
2939   [(set (match_operand:QI 0 "r_or_s_operand" "=d,m")
2940         (and:QI (match_operand:QI 1 "r_or_s_operand" "%0,0")
2941                 (match_operand:QI 2 "r_or_s_operand" "di,mi")))]
2942   "TARGET_CHAR_INSTRUCTIONS"
2943   "*
2944 {
2945   check_label_emit ();
2946   CC_STATUS_INIT;  /* and sets CC but not how we want it */
2947   if (REG_P (operands[2]))
2948     {
2949       mvs_check_page (0, 2, 0);
2950       return \"NR       %0,%2\";
2951     }
2952   if (REG_P (operands[0]))
2953     {
2954       mvs_check_page (0, 4, 0);
2955       return \"N        %0,%2\";
2956     }
2957   if (GET_CODE (operands[2]) == CONST_INT)
2958     {
2959       mvs_check_page (0, 4, 0);
2960       return \"NI       %0,%B2\";
2961     }
2962   mvs_check_page (0, 6, 0);
2963   return \"NC   %O0(1,%R0),%2\";
2964 }"
2965    [(set_attr "length" "6")]
2966 )
2967
2968 (define_insn "andqi3"
2969   [(set (match_operand:QI 0 "general_operand" "=d")
2970         (and:QI (match_operand:QI 1 "general_operand" "%0")
2971                 (match_operand:QI 2 "general_operand" "di")))]
2972   ""
2973   "*
2974 {
2975   check_label_emit ();
2976   CC_STATUS_INIT;  /* and sets CC but not how we want it */
2977   if (GET_CODE (operands[2]) == CONST_INT)
2978     {
2979       mvs_check_page (0, 4, 0);
2980       return \"N        %0,%2\";
2981     }
2982   mvs_check_page (0, 2, 0);
2983   return \"NR   %0,%2\";
2984 }"
2985    [(set_attr "length" "4")]
2986 )
2987
2988 ;;
2989 ;;- Bit set (inclusive or) instructions.
2990 ;;
2991
2992 ;
2993 ; iordi3 instruction pattern(s).
2994 ;
2995
2996 ;(define_expand "iordi3"
2997 ;  [(set (match_operand:DI 0 "general_operand" "")
2998 ;       (ior:DI (match_operand:DI 1 "general_operand" "")
2999 ;               (match_operand:DI 2 "general_operand" "")))]
3000 ;  ""
3001 ;  "
3002 ;{
3003 ;  rtx gen_iorsi3();
3004 ;
3005 ;  emit_insn (gen_iorsi3 (operand_subword (operands[0], 0, 1, DImode),
3006 ;                        operand_subword (operands[1], 0, 1, DImode),
3007 ;                        operand_subword (operands[2], 0, 1, DImode)));
3008 ;  emit_insn (gen_iorsi3 (gen_lowpart (SImode, operands[0]),
3009 ;                        gen_lowpart (SImode, operands[1]),
3010 ;                        gen_lowpart (SImode, operands[2])));
3011 ;  DONE;
3012 ;}")
3013
3014 ;
3015 ; iorsi3 instruction pattern(s).
3016 ;
3017
3018 (define_insn ""
3019   [(set (match_operand:SI 0 "r_or_s_operand" "=d,m")
3020         (ior:SI (match_operand:SI 1 "r_or_s_operand" "%0,0")
3021                 (match_operand:SI 2 "r_or_s_operand" "g,Si")))]
3022   "TARGET_CHAR_INSTRUCTIONS"
3023   "*
3024 {
3025   check_label_emit ();
3026   CC_STATUS_INIT;  /* OR sets CC but not how we want it */
3027   if (REG_P (operands[2]))
3028     {
3029       mvs_check_page (0, 2, 0);
3030       return \"OR       %0,%2\";
3031     }
3032   if (REG_P (operands[0]))
3033     {
3034       mvs_check_page (0, 4, 0);
3035       return \"O        %0,%2\";
3036     }
3037   mvs_check_page (0, 6, 0);
3038   return \"OC   %O0(4,%R0),%2\";
3039 }"
3040   [(set_attr "length" "6")]
3041 )
3042
3043 (define_insn "iorsi3"
3044   [(set (match_operand:SI 0 "general_operand" "=d")
3045         (ior:SI (match_operand:SI 1 "general_operand" "%0")
3046                 (match_operand:SI 2 "general_operand" "g")))]
3047   ""
3048   "*
3049 {
3050   check_label_emit ();
3051   CC_STATUS_INIT;  /* OR sets CC but not how we want it */
3052   if (REG_P (operands[2]))
3053     {
3054       mvs_check_page (0, 2, 0);
3055       return \"OR       %0,%2\";
3056     }
3057   mvs_check_page (0, 4, 0);
3058   return \"O    %0,%2\";
3059 }"
3060    [(set_attr "length" "4")]
3061 )
3062
3063 ;
3064 ; iorhi3 instruction pattern(s).
3065 ;
3066
3067 (define_insn ""
3068   [(set (match_operand:HI 0 "r_or_s_operand" "=d,m")
3069         (ior:HI (match_operand:HI 1 "r_or_s_operand" "%0,0")
3070                 (match_operand:HI 2 "r_or_s_operand" "di,mi")))]
3071   "TARGET_CHAR_INSTRUCTIONS"
3072   "*
3073 {
3074   check_label_emit ();
3075   CC_STATUS_INIT;  /* OR sets CC but not how we want it */
3076   if (REG_P (operands[2]))
3077     {
3078       mvs_check_page (0, 2, 0);
3079       return \"OR       %0,%2\";
3080     }
3081   if (REG_P (operands[0]))
3082     {
3083       mvs_check_page (0, 4, 0);
3084       return \"O        %0,%2\";
3085     }
3086   if (GET_CODE (operands[2]) == CONST_INT)
3087     {
3088       mvs_check_page (0, 6, 0);
3089       return \"OC       %O0(2,%R0),%H2\";
3090     }
3091   mvs_check_page (0, 6, 0);
3092   return \"OC   %O0(2,%R0),%2\";
3093 }"
3094    [(set_attr "length" "6")]
3095 )
3096
3097 (define_insn "iorhi3"
3098   [(set (match_operand:HI 0 "general_operand" "=d")
3099         (ior:HI (match_operand:HI 1 "general_operand" "%0")
3100                 (match_operand:HI 2 "general_operand" "di")))]
3101   ""
3102   "*
3103 {
3104   check_label_emit ();
3105   CC_STATUS_INIT;  /* OR sets CC but not how we want it */
3106   if (GET_CODE (operands[2]) == CONST_INT)
3107     {
3108       mvs_check_page (0, 4, 0);
3109       return \"O        %0,%2\";
3110     }
3111   mvs_check_page (0, 2, 0);
3112   return \"OR   %0,%2\";
3113 }"
3114    [(set_attr "length" "4")]
3115 )
3116
3117 ;
3118 ; iorqi3 instruction pattern(s).
3119 ;
3120
3121 (define_insn ""
3122   [(set (match_operand:QI 0 "r_or_s_operand" "=d,m")
3123         (ior:QI (match_operand:QI 1 "r_or_s_operand" "%0,0")
3124                 (match_operand:QI 2 "r_or_s_operand" "di,mi")))]
3125   "TARGET_CHAR_INSTRUCTIONS"
3126   "*
3127 {
3128   check_label_emit ();
3129   CC_STATUS_INIT;  /* OR sets CC but not how we want it */
3130   if (REG_P (operands[2]))
3131     {
3132       mvs_check_page (0, 2, 0);
3133       return \"OR       %0,%2\";
3134     }
3135   if (REG_P (operands[0]))
3136     {
3137       mvs_check_page (0, 4, 0);
3138       return \"O        %0,%2\";
3139     }
3140   if (GET_CODE (operands[2]) == CONST_INT)
3141     {
3142       mvs_check_page (0, 4, 0);
3143       return \"OI       %0,%B2\";
3144     }
3145   mvs_check_page (0, 6, 0);
3146   return \"OC   %O0(1,%R0),%2\";
3147 }"
3148    [(set_attr "length" "6")]
3149 )
3150
3151 (define_insn "iorqi3"
3152   [(set (match_operand:QI 0 "general_operand" "=d")
3153         (ior:QI (match_operand:QI 1 "general_operand" "%0")
3154                 (match_operand:QI 2 "general_operand" "di")))]
3155   ""
3156   "*
3157 {
3158   check_label_emit ();
3159   CC_STATUS_INIT;  /* OR sets CC but not how we want it */
3160   if (GET_CODE (operands[2]) == CONST_INT)
3161     {
3162       mvs_check_page (0, 4, 0);
3163       return \"O        %0,%2\";
3164     }
3165   mvs_check_page (0, 2, 0);
3166   return \"OR   %0,%2\";
3167 }"
3168    [(set_attr "length" "4")]
3169 )
3170
3171 ;;
3172 ;;- Xor instructions.
3173 ;;
3174
3175 ;
3176 ; xordi3 instruction pattern(s).
3177 ;
3178
3179 ;(define_expand "xordi3"
3180 ;  [(set (match_operand:DI 0 "general_operand" "")
3181 ;       (xor:DI (match_operand:DI 1 "general_operand" "")
3182 ;               (match_operand:DI 2 "general_operand" "")))]
3183 ;  ""
3184 ;  "
3185 ;{
3186 ;  rtx gen_xorsi3();
3187 ;
3188 ;  emit_insn (gen_xorsi3 (operand_subword (operands[0], 0, 1, DImode),
3189 ;                        operand_subword (operands[1], 0, 1, DImode),
3190 ;                        operand_subword (operands[2], 0, 1, DImode)));
3191 ;  emit_insn (gen_xorsi3 (gen_lowpart (SImode, operands[0]),
3192 ;                        gen_lowpart (SImode, operands[1]),
3193 ;                        gen_lowpart (SImode, operands[2])));
3194 ;  DONE;
3195 ;}")
3196
3197 ;
3198 ; xorsi3 instruction pattern(s).
3199 ;
3200
3201 (define_insn ""
3202   [(set (match_operand:SI 0 "r_or_s_operand" "=d,m")
3203         (xor:SI (match_operand:SI 1 "r_or_s_operand" "%0,0")
3204                 (match_operand:SI 2 "r_or_s_operand" "g,mi")))]
3205   "TARGET_CHAR_INSTRUCTIONS"
3206   "*
3207 {
3208   check_label_emit ();
3209   CC_STATUS_INIT;  /* XOR sets CC but not how we want it */
3210   if (REG_P (operands[2]))
3211     {
3212       mvs_check_page (0, 2, 0);
3213       return \"XR       %0,%2\";
3214     }
3215   if (REG_P (operands[0]))
3216     {
3217       mvs_check_page (0, 4, 0);
3218       return \"X        %0,%2\";
3219     }
3220   mvs_check_page (0, 6, 0);
3221   return \"XC   %O0(4,%R0),%2\";
3222 }"
3223    [(set_attr "length" "6")]
3224 )
3225
3226 (define_insn "xorsi3"
3227   [(set (match_operand:SI 0 "general_operand" "=d")
3228         (xor:SI (match_operand:SI 1 "general_operand" "%0")
3229                 (match_operand:SI 2 "general_operand" "g")))]
3230   ""
3231   "*
3232 {
3233   check_label_emit ();
3234   CC_STATUS_INIT;  /* XOR sets CC but not how we want it */
3235   if (REG_P (operands[2]))
3236     {
3237       mvs_check_page (0, 2, 0);
3238       return \"XR       %0,%2\";
3239     }
3240   mvs_check_page (0, 4, 0);
3241   return \"X    %0,%2\";
3242 }"
3243   [(set_attr "length" "4")]
3244 )
3245
3246 ;
3247 ; xorhi3 instruction pattern(s).
3248 ;
3249
3250 (define_insn ""
3251   [(set (match_operand:HI 0 "r_or_s_operand" "=d,m")
3252         (xor:HI (match_operand:HI 1 "r_or_s_operand" "%0,0")
3253                 (match_operand:HI 2 "r_or_s_operand" "di,mi")))]
3254   "TARGET_CHAR_INSTRUCTIONS"
3255   "*
3256 {
3257   check_label_emit ();
3258   CC_STATUS_INIT;  /* XOR sets CC but not how we want it */
3259   if (REG_P (operands[2]))
3260     {
3261       mvs_check_page (0, 2, 0);
3262       return \"XR       %0,%2\";
3263     }
3264   if (REG_P (operands[0]))
3265     {
3266       mvs_check_page (0, 4, 0);
3267       return \"X        %0,%H2\";
3268     }
3269   if (GET_CODE (operands[2]) == CONST_INT)
3270     {
3271       mvs_check_page (0, 6, 0);
3272       return \"XC       %O0(2,%R0),%H2\";
3273     }
3274   mvs_check_page (0, 6, 0);
3275   return \"XC   %O0(2,%R0),%2\";
3276 }"
3277   [(set_attr "length" "6")]
3278 )
3279
3280 (define_insn "xorhi3"
3281   [(set (match_operand:HI 0 "general_operand" "=d")
3282         (xor:HI (match_operand:HI 1 "general_operand" "%0")
3283                 (match_operand:HI 2 "general_operand" "di")))]
3284   ""
3285   "*
3286 {
3287   check_label_emit ();
3288   CC_STATUS_INIT;  /* XOR sets CC but not how we want it */
3289   if (GET_CODE (operands[2]) == CONST_INT)
3290     {
3291       mvs_check_page (0, 4, 0);
3292       return \"X        %0,%H2\";
3293     }
3294   mvs_check_page (0, 2, 0);
3295   return \"XR   %0,%2\";
3296 }"
3297   [(set_attr "length" "4")]
3298 )
3299
3300 ;
3301 ; xorqi3 instruction pattern(s).
3302 ;
3303
3304 (define_insn ""
3305   [(set (match_operand:QI 0 "r_or_s_operand" "=d,m")
3306         (xor:QI (match_operand:QI 1 "r_or_s_operand" "%0,0")
3307                 (match_operand:QI 2 "r_or_s_operand" "di,mi")))]
3308   "TARGET_CHAR_INSTRUCTIONS"
3309   "*
3310 {
3311   check_label_emit ();
3312   CC_STATUS_INIT;  /* XOR sets CC but not how we want it */
3313   if (REG_P (operands[2]))
3314     {
3315       mvs_check_page (0, 2, 0);
3316       return \"XR       %0,%2\";
3317     }
3318   if (REG_P (operands[0]))
3319     {
3320       mvs_check_page (0, 4, 0);
3321       return \"X        %0,%2\";
3322     }
3323   if (GET_CODE (operands[2]) == CONST_INT)
3324     {
3325       mvs_check_page (0, 4, 0);
3326       return \"XI       %0,%B2\";
3327     }
3328   mvs_check_page (0, 6, 0);
3329   return \"XC   %O0(1,%R0),%2\";
3330 }"
3331   [(set_attr "length" "6")]
3332 )
3333
3334 (define_insn "xorqi3"
3335   [(set (match_operand:QI 0 "general_operand" "=d")
3336         (xor:QI (match_operand:QI 1 "general_operand" "%0")
3337                 (match_operand:QI 2 "general_operand" "di")))]
3338   ""
3339   "*
3340 {
3341   check_label_emit ();
3342   CC_STATUS_INIT;  /* XOR sets CC but not how we want it */
3343   if (GET_CODE (operands[2]) == CONST_INT)
3344     {
3345       mvs_check_page (0, 4, 0);
3346       return \"X        %0,%2\";
3347     }
3348   mvs_check_page (0, 2, 0);
3349   return \"XR   %0,%2\";
3350 }"
3351   [(set_attr "length" "4")]
3352 )
3353
3354 ;;
3355 ;;- Negate instructions.
3356 ;;
3357
3358 ;
3359 ; negsi2 instruction pattern(s).
3360 ;
3361
3362 (define_insn "negsi2"
3363   [(set (match_operand:SI 0 "general_operand" "=d")
3364         (neg:SI (match_operand:SI 1 "general_operand" "d")))]
3365   ""
3366   "*
3367 {
3368   check_label_emit ();
3369   mvs_check_page (0, 2, 0);
3370   return \"LCR  %0,%1\";
3371 }"
3372   [(set_attr "length" "2")]
3373 )
3374
3375 ;
3376 ; neghi2 instruction pattern(s).
3377 ;
3378
3379 (define_insn "neghi2"
3380   [(set (match_operand:HI 0 "general_operand" "=d")
3381         (neg:HI (match_operand:HI 1 "general_operand" "d")))]
3382   ""
3383   "*
3384 {
3385   check_label_emit ();
3386   mvs_check_page (0, 10, 0);
3387   return \"SLL  %1,16\;SRA      %1,16\;LCR      %0,%1\";
3388 }"
3389   [(set_attr "length" "10")]
3390 )
3391
3392 ;
3393 ; negdf2 instruction pattern(s).
3394 ;
3395
3396 (define_insn "negdf2"
3397   [(set (match_operand:DF 0 "general_operand" "=f")
3398         (neg:DF (match_operand:DF 1 "general_operand" "f")))]
3399   ""
3400   "*
3401 {
3402   check_label_emit ();
3403   mvs_check_page (0, 2, 0);
3404   return \"LCDR %0,%1\";
3405 }"
3406   [(set_attr "length" "2")]
3407 )
3408
3409 ;
3410 ; negsf2 instruction pattern(s).
3411 ;
3412
3413 (define_insn "negsf2"
3414   [(set (match_operand:SF 0 "general_operand" "=f")
3415         (neg:SF (match_operand:SF 1 "general_operand" "f")))]
3416   ""
3417   "*
3418 {
3419   check_label_emit ();
3420   mvs_check_page (0, 2, 0);
3421   return \"LCER %0,%1\";
3422 }"
3423   [(set_attr "length" "2")]
3424 )
3425
3426 ;;
3427 ;;- Absolute value instructions.
3428 ;;
3429
3430 ;
3431 ; abssi2 instruction pattern(s).
3432 ;
3433
3434 (define_insn "abssi2"
3435   [(set (match_operand:SI 0 "general_operand" "=d")
3436         (abs:SI (match_operand:SI 1 "general_operand" "d")))]
3437   ""
3438   "*
3439 {
3440   check_label_emit ();
3441   mvs_check_page (0, 2, 0);
3442   return \"LPR  %0,%1\";
3443 }"
3444   [(set_attr "length" "2")]
3445 )
3446
3447 ;
3448 ; abshi2 instruction pattern(s).
3449 ;
3450
3451 (define_insn "abshi2"
3452   [(set (match_operand:HI 0 "general_operand" "=d")
3453         (abs:HI (match_operand:HI 1 "general_operand" "d")))]
3454   ""
3455   "*
3456 {
3457   check_label_emit ();
3458   mvs_check_page (0, 10, 0);
3459   return \"SLL  %1,16\;SRA      %1,16\;LPR      %0,%1\";
3460 }"
3461   [(set_attr "length" "10")]
3462 )
3463
3464 ;
3465 ; absdf2 instruction pattern(s).
3466 ;
3467
3468 (define_insn "absdf2"
3469   [(set (match_operand:DF 0 "general_operand" "=f")
3470         (abs:DF (match_operand:DF 1 "general_operand" "f")))]
3471   ""
3472   "*
3473 {
3474   check_label_emit ();
3475   mvs_check_page (0, 2, 0);
3476   return \"LPDR %0,%1\";
3477 }"
3478   [(set_attr "length" "2")]
3479 )
3480
3481 ;
3482 ; abssf2 instruction pattern(s).
3483 ;
3484
3485 (define_insn "abssf2"
3486   [(set (match_operand:SF 0 "general_operand" "=f")
3487         (abs:SF (match_operand:SF 1 "general_operand" "f")))]
3488   ""
3489   "*
3490 {
3491   check_label_emit ();
3492   mvs_check_page (0, 2, 0);
3493   return \"LPER %0,%1\";
3494 }"
3495   [(set_attr "length" "2")]
3496 )
3497
3498 ;;
3499 ;;- One complement instructions.
3500 ;;
3501
3502 ;
3503 ; one_cmpldi2 instruction pattern(s).
3504 ;
3505
3506 ;(define_expand "one_cmpldi2"
3507 ;  [(set (match_operand:DI 0 "general_operand" "")
3508 ;       (not:DI (match_operand:DI 1 "general_operand" "")))]
3509 ;  ""
3510 ;  "
3511 ;{
3512 ;  rtx gen_one_cmplsi2();
3513 ;
3514 ;  emit_insn (gen_one_cmplsi2 (operand_subword (operands[0], 0, 1, DImode),
3515 ;                             operand_subword (operands[1], 0, 1, DImode)));
3516 ;  emit_insn (gen_one_cmplsi2 (gen_lowpart (SImode, operands[0]),
3517 ;                             gen_lowpart (SImode, operands[1])));
3518 ;  DONE;
3519 ;}")
3520
3521 ;
3522 ; one_cmplsi2 instruction pattern(s).
3523 ;
3524
3525 (define_insn ""
3526   [(set (match_operand:SI 0 "r_or_s_operand" "=dm")
3527         (not:SI (match_operand:SI 1 "r_or_s_operand" "0")))]
3528   "TARGET_CHAR_INSTRUCTIONS"
3529   "*
3530 {
3531   check_label_emit ();
3532   CC_STATUS_INIT;  /* XOR sets CC but not how we want it */
3533   if (REG_P (operands[0]))
3534     {
3535       mvs_check_page (0, 4, 4);
3536       return \"X        %0,=F'-1'\";
3537     }
3538   CC_STATUS_INIT;
3539   mvs_check_page (0, 6, 4);
3540   return \"XC   %O0(4,%R0),=F'-1'\";
3541 }"
3542   [(set_attr "length" "6")]
3543 )
3544
3545 (define_insn "one_cmplsi2"
3546   [(set (match_operand:SI 0 "general_operand" "=d")
3547         (not:SI (match_operand:SI 1 "general_operand" "0")))]
3548   ""
3549   "*
3550 {
3551   check_label_emit ();
3552   CC_STATUS_INIT;  /* XOR sets CC but not how we want it */
3553   mvs_check_page (0, 4, 4);
3554   return \"X    %0,=F'-1'\";
3555 }"
3556   [(set_attr "length" "4")]
3557 )
3558
3559 ;
3560 ; one_cmplhi2 instruction pattern(s).
3561 ;
3562
3563 (define_insn ""
3564   [(set (match_operand:HI 0 "r_or_s_operand" "=dm")
3565         (not:HI (match_operand:HI 1 "r_or_s_operand" "0")))]
3566   "TARGET_CHAR_INSTRUCTIONS"
3567   "*
3568 {
3569   check_label_emit ();
3570   CC_STATUS_INIT;  /* XOR sets CC but not how we want it */
3571   if (REG_P (operands[0]))
3572     {
3573       mvs_check_page (0, 4, 4);
3574       return \"X        %0,=F'-1'\";
3575     }
3576   mvs_check_page (0, 6, 4);
3577   return \"XC   %O0(2,%R0),=XL4'FFFF'\";
3578 }"
3579   [(set_attr "length" "6")]
3580 )
3581
3582 (define_insn "one_cmplhi2"
3583   [(set (match_operand:HI 0 "general_operand" "=d")
3584         (not:HI (match_operand:HI 1 "general_operand" "0")))]
3585   ""
3586   "*
3587 {
3588   check_label_emit ();
3589   CC_STATUS_INIT;  /* XOR sets CC but not how we want it */
3590   mvs_check_page (0, 4, 4);
3591   return \"X    %0,=F'-1'\";
3592 }"
3593   [(set_attr "length" "4")]
3594 )
3595
3596 ;
3597 ; one_cmplqi2 instruction pattern(s).
3598 ;
3599
3600 (define_insn ""
3601   [(set (match_operand:QI 0 "r_or_s_operand" "=dm")
3602         (not:QI (match_operand:QI 1 "r_or_s_operand" "0")))]
3603   "TARGET_CHAR_INSTRUCTIONS"
3604   "*
3605 {
3606   check_label_emit ();
3607   CC_STATUS_INIT;  /* XOR sets CC but not how we want it */
3608   if (REG_P (operands[0]))
3609     {
3610       mvs_check_page (0, 4, 4);
3611       return \"X        %0,=F'-1'\";
3612     }
3613   mvs_check_page (0, 4, 0);
3614   return \"XI   %0,255\";
3615 }"
3616   [(set_attr "length" "4")]
3617 )
3618
3619 (define_insn "one_cmplqi2"
3620   [(set (match_operand:QI 0 "general_operand" "=d")
3621         (not:QI (match_operand:QI 1 "general_operand" "0")))]
3622   ""
3623   "*
3624 {
3625   check_label_emit ();
3626   CC_STATUS_INIT;  /* XOR sets CC but not how we want it */
3627   mvs_check_page (0, 4, 4);
3628   return \"X    %0,=F'-1'\";
3629 }"
3630   [(set_attr "length" "4")]
3631 )
3632
3633 ;;
3634 ;;- Arithmetic shift instructions.
3635 ;;
3636
3637 ;
3638 ; ashldi3 instruction pattern(s).
3639 ;
3640
3641 (define_insn "ashldi3"
3642   [(set (match_operand:DI 0 "general_operand" "=d")
3643         (ashift:DI (match_operand:DI 1 "general_operand" "0")
3644                    (match_operand:SI 2 "general_operand" "Ja")))]
3645   ""
3646   "*
3647 {
3648   check_label_emit ();
3649   /* this status set seems not have the desired effect,
3650    * proably because the 64-bit long-long test is emulated ?! */
3651   CC_STATUS_SET (operands[0], operands[1]);
3652   mvs_check_page (0, 4, 0);
3653   if (REG_P (operands[2]))
3654     return \"SLDA       %0,0(%2)\";
3655   return \"SLDA %0,%c2\";
3656 }"
3657   [(set_attr "length" "4")]
3658 )
3659
3660 ;
3661 ; ashrdi3 instruction pattern(s).
3662 ;
3663
3664 (define_insn "ashrdi3"
3665   [(set (match_operand:DI 0 "register_operand" "=d")
3666         (ashiftrt:DI (match_operand:DI 1 "general_operand" "0")
3667                      (match_operand:SI 2 "general_operand" "Ja")))]
3668   ""
3669   "*
3670 {
3671   check_label_emit ();
3672   /* this status set seems not have the desired effect,
3673    * proably because the 64-bit long-long test is emulated ?! */
3674   CC_STATUS_SET (operands[0], operands[1]);
3675   mvs_check_page (0, 4, 0);
3676   if (REG_P (operands[2])) 
3677     return \"SRDA       %0,0(%2)\";
3678   return \"SRDA %0,%c2\";
3679 }"
3680   [(set_attr "length" "4")]
3681 )
3682
3683 ;
3684 ; ashlsi3 instruction pattern(s).
3685 ;
3686
3687 (define_insn "ashlsi3"
3688   [(set (match_operand:SI 0 "general_operand" "=d")
3689         (ashift:SI (match_operand:SI 1 "general_operand" "0")
3690                    (match_operand:SI 2 "general_operand" "Ja")))]
3691   ""
3692   "*
3693 {
3694   check_label_emit ();
3695   mvs_check_page (0, 4, 0);
3696   if (REG_P (operands[2])) 
3697     return \"SLL        %0,0(%2)\";
3698   return \"SLL  %0,%c2\";
3699 }"
3700   [(set_attr "length" "4")]
3701 )
3702
3703 ;
3704 ; ashrsi3 instruction pattern(s).
3705 ;
3706
3707 (define_insn "ashrsi3"
3708   [(set (match_operand:SI 0 "general_operand" "=d")
3709         (ashiftrt:SI (match_operand:SI 1 "general_operand" "0")
3710                      (match_operand:SI 2 "general_operand" "Ja")))]
3711   ""
3712   "*
3713 {
3714   check_label_emit ();
3715   CC_STATUS_SET (operands[0], operands[1]);
3716   mvs_check_page (0, 4, 0);
3717   if (REG_P (operands[2])) 
3718     return \"SRA        %0,0(%2)\";
3719   return \"SRA  %0,%c2\";
3720 }"
3721   [(set_attr "length" "4")]
3722 )
3723
3724 ;
3725 ; ashlhi3 instruction pattern(s).
3726 ;
3727
3728 (define_insn "ashlhi3"
3729   [(set (match_operand:HI 0 "general_operand" "=d")
3730         (ashift:HI (match_operand:HI 1 "general_operand" "0")
3731                    (match_operand:SI 2 "general_operand" "Ja")))]
3732   ""
3733   "*
3734 {
3735   check_label_emit ();
3736   mvs_check_page (0, 8, 0);
3737   if (REG_P (operands[2])) 
3738     return \"SLL        %0,16(%2)\;SRA  %0,16\";
3739   return \"SLL  %0,16+%c2\;SRA  %0,16\";
3740 }"
3741   [(set_attr "length" "8")]
3742 )
3743
3744 ;
3745 ; ashrhi3 instruction pattern(s).
3746 ;
3747
3748 (define_insn "ashrhi3"
3749   [(set (match_operand:HI 0 "general_operand" "=d")
3750         (ashiftrt:HI (match_operand:HI 1 "general_operand" "0")
3751                      (match_operand:SI 2 "general_operand" "Ja")))]
3752   ""
3753   "*
3754 {
3755   check_label_emit ();
3756   mvs_check_page (0, 8, 0);
3757   if (REG_P (operands[2])) 
3758     return \"SLL        %0,16\;SRA      %0,16(%2)\";
3759   return \"SLL  %0,16\;SRA      %0,16+%c2\";
3760 }"
3761   [(set_attr "length" "8")]
3762 )
3763
3764 ;
3765 ; ashlqi3 instruction pattern(s).
3766 ;
3767
3768 (define_insn "ashlqi3"
3769   [(set (match_operand:QI 0 "general_operand" "=d")
3770         (ashift:QI (match_operand:QI 1 "general_operand" "0")
3771                    (match_operand:SI 2 "general_operand" "Ja")))]
3772   ""
3773   "*
3774 {
3775   check_label_emit ();
3776   mvs_check_page (0, 4, 0);
3777   if (REG_P (operands[2])) 
3778     return \"SLL        %0,0(%2)\";
3779   return \"SLL  %0,%c2\";
3780 }"
3781   [(set_attr "length" "4")]
3782 )
3783
3784 ;
3785 ; ashrqi3 instruction pattern(s).
3786 ;
3787
3788 (define_insn "ashrqi3"
3789   [(set (match_operand:QI 0 "general_operand" "=d")
3790         (ashiftrt:QI (match_operand:QI 1 "general_operand" "0")
3791                      (match_operand:SI 2 "general_operand" "Ja")))]
3792   ""
3793   "*
3794 {
3795   check_label_emit ();
3796   mvs_check_page (0, 8, 0);
3797   if (REG_P (operands[2])) 
3798     return \"SLL        %0,24\;SRA      %0,24(%2)\";
3799   return \"SLL  %0,24\;SRA      %0,24+%c2\";
3800 }"
3801   [(set_attr "length" "8")]
3802 )
3803
3804 ;;
3805 ;;- Logical shift instructions.
3806 ;;
3807
3808 ;
3809 ; lshrdi3 instruction pattern(s).
3810 ;
3811
3812 (define_insn "lshrdi3"
3813   [(set (match_operand:DI 0 "general_operand" "=d")
3814         (lshiftrt:DI (match_operand:DI 1 "general_operand" "0")
3815                      (match_operand:SI 2 "general_operand" "Ja")))]
3816   ""
3817   "*
3818 {
3819   check_label_emit ();
3820   mvs_check_page (0, 4, 0);
3821   if (REG_P (operands[2])) 
3822     return \"SRDL       %0,0(%2)\";
3823   return \"SRDL %0,%c2\";
3824 }"
3825   [(set_attr "length" "4")]
3826 )
3827
3828
3829 ;
3830 ; lshrsi3 instruction pattern(s).
3831 ;
3832
3833 (define_insn "lshrsi3"
3834   [(set (match_operand:SI 0 "general_operand" "=d")
3835         (lshiftrt:SI (match_operand:SI 1 "general_operand" "0")
3836                      (match_operand:SI 2 "general_operand" "Ja")))]
3837   ""
3838   "*
3839 {
3840   check_label_emit ();
3841   mvs_check_page (0, 4, 0);
3842   if (REG_P (operands[2])) 
3843     return \"SRL        %0,0(%2)\";
3844   return \"SRL  %0,%c2\";
3845 }"
3846   [(set_attr "length" "4")]
3847 )
3848
3849 ;
3850 ; lshrhi3 instruction pattern(s).
3851 ;
3852
3853 (define_insn "lshrhi3"
3854   [(set (match_operand:HI 0 "general_operand" "=d")
3855         (lshiftrt:HI (match_operand:HI 1 "general_operand" "0")
3856                      (match_operand:SI 2 "general_operand" "Ja")))]
3857   ""
3858   "*
3859 {
3860   check_label_emit ();
3861   CC_STATUS_INIT; /* AND sets the CC but not how we want it */
3862   if (REG_P (operands[2]))
3863     {
3864       mvs_check_page (0, 8, 4);
3865       return \"N        %0,=XL4'0000FFFF'\;SRL  %0,0(%2)\";
3866     }
3867   mvs_check_page (0, 8, 4);
3868   return \"N    %0,=XL4'0000FFFF'\;SRL  %0,%c2\";
3869 }"
3870   [(set_attr "length" "8")]
3871 )
3872
3873 ;
3874 ; lshrqi3 instruction pattern(s).
3875 ;
3876
3877 (define_insn "lshrqi3"
3878   [(set (match_operand:QI 0 "general_operand" "=d")
3879         (lshiftrt:QI (match_operand:QI 1 "general_operand" "0")
3880                      (match_operand:SI 2 "general_operand" "Ja")))]
3881   ""
3882   "*
3883 {
3884   check_label_emit ();
3885   CC_STATUS_INIT; /* AND sets the CC but not how we want it */
3886   mvs_check_page (0, 8, 4);
3887   if (REG_P (operands[2])) 
3888     return \"N  %0,=XL4'000000FF'\;SRL  %0,0(%2)\";
3889   return \"N    %0,=XL4'000000FF'\;SRL  %0,%c2\";
3890 }"
3891   [(set_attr "length" "8")]
3892 )
3893
3894 ;; =======================================================================
3895 ;;- Conditional jump instructions.
3896 ;; =======================================================================
3897
3898 ;
3899 ; beq instruction pattern(s).
3900 ;
3901
3902 (define_insn "beq"
3903   [(set (pc)
3904         (if_then_else (eq (cc0)
3905                           (const_int 0))
3906                       (label_ref (match_operand 0 "" ""))
3907                       (pc)))
3908 ;   (clobber (reg:SI 14))
3909    ]
3910   ""
3911   "*
3912 {
3913   check_label_emit ();
3914   mvs_check_page (0, 4, 0);
3915   if (i370_short_branch(insn) || mvs_check_label (CODE_LABEL_NUMBER (operands[0])))
3916     { 
3917       return \"BE       %l0\";
3918     }
3919   mvs_check_page (0, 2, 4);
3920   return \"L    14,=A(%l0)\;BER 14\";
3921 }"
3922   [(set_attr "length" "6")]
3923 )
3924
3925 ;
3926 ; bne instruction pattern(s).
3927 ;
3928
3929 (define_insn "bne"
3930   [(set (pc)
3931         (if_then_else (ne (cc0)
3932                           (const_int 0))
3933                       (label_ref (match_operand 0 "" ""))
3934                       (pc)))
3935 ;   (clobber (reg:SI 14))
3936    ]
3937   ""
3938   "*
3939 {
3940   check_label_emit ();
3941   mvs_check_page (0, 4, 0);
3942   if (i370_short_branch(insn) || mvs_check_label (CODE_LABEL_NUMBER (operands[0])))
3943     { 
3944       return \"BNE      %l0\";
3945     }
3946   mvs_check_page (0, 2, 4);
3947   return \"L    14,=A(%l0)\;BNER        14\";
3948 }"
3949   [(set_attr "length" "6")]
3950 )
3951
3952 ;
3953 ; bgt instruction pattern(s).
3954 ;
3955
3956 (define_insn "bgt"
3957   [(set (pc)
3958         (if_then_else (gt (cc0)
3959                           (const_int 0))
3960                       (label_ref (match_operand 0 "" ""))
3961                       (pc)))
3962 ;   (clobber (reg:SI 14))
3963    ]
3964   ""
3965   "*
3966 {
3967   check_label_emit ();
3968   mvs_check_page (0, 4, 0);
3969   if (i370_short_branch(insn) || mvs_check_label (CODE_LABEL_NUMBER (operands[0])))
3970     { 
3971       return \"BH       %l0\";
3972     }
3973   mvs_check_page (0, 2, 4);
3974   return \"L    14,=A(%l0)\;BHR 14\";
3975 }"
3976   [(set_attr "length" "6")]
3977 )
3978
3979 ;
3980 ; bgtu instruction pattern(s).
3981 ;
3982
3983 (define_insn "bgtu"
3984   [(set (pc)
3985         (if_then_else (gtu (cc0)
3986                            (const_int 0))
3987                       (label_ref (match_operand 0 "" ""))
3988                       (pc)))
3989 ;   (clobber (reg:SI 14))
3990    ]
3991   ""
3992   "*
3993 {
3994   check_label_emit ();
3995   mvs_check_page (0, 4, 0);
3996   if (i370_short_branch(insn) || mvs_check_label (CODE_LABEL_NUMBER (operands[0])))
3997     { 
3998       return \"BH       %l0\";
3999     }
4000   mvs_check_page (0, 2, 4);
4001   return \"L    14,=A(%l0)\;BHR 14\";
4002 }"
4003   [(set_attr "length" "6")]
4004 )
4005
4006 ;
4007 ; blt instruction pattern(s).
4008 ;
4009
4010 (define_insn "blt"
4011   [(set (pc)
4012         (if_then_else (lt (cc0)
4013                           (const_int 0))
4014                       (label_ref (match_operand 0 "" ""))
4015                       (pc)))
4016 ;   (clobber (reg:SI 14))
4017    ]
4018   ""
4019   "*
4020 {
4021   check_label_emit ();
4022   mvs_check_page (0, 4, 0);
4023   if (i370_short_branch(insn) || mvs_check_label (CODE_LABEL_NUMBER (operands[0])))
4024     { 
4025       return \"BL       %l0\";
4026     }
4027   mvs_check_page (0, 2, 4);
4028   return \"L    14,=A(%l0)\;BLR 14\";
4029 }"
4030   [(set_attr "length" "6")]
4031 )
4032
4033 ;
4034 ; bltu instruction pattern(s).
4035 ;
4036
4037 (define_insn "bltu"
4038   [(set (pc)
4039         (if_then_else (ltu (cc0)
4040                            (const_int 0))
4041                       (label_ref (match_operand 0 "" ""))
4042                       (pc)))
4043 ;   (clobber (reg:SI 14))
4044    ]
4045   ""
4046   "*
4047 {
4048   check_label_emit ();
4049   mvs_check_page (0, 4, 0);
4050   if (i370_short_branch(insn) || mvs_check_label (CODE_LABEL_NUMBER (operands[0])))
4051     { 
4052       return \"BL       %l0\";
4053     }
4054   mvs_check_page (0, 2, 4);
4055   return \"L    14,=A(%l0)\;BLR 14\";
4056 }"
4057   [(set_attr "length" "6")]
4058 )
4059
4060 ;
4061 ; bge instruction pattern(s).
4062 ;
4063
4064 (define_insn "bge"
4065   [(set (pc)
4066         (if_then_else (ge (cc0)
4067                           (const_int 0))
4068                       (label_ref (match_operand 0 "" ""))
4069                       (pc)))
4070 ;   (clobber (reg:SI 14))
4071    ]
4072   ""
4073   "*
4074 {
4075   check_label_emit ();
4076   mvs_check_page (0, 4, 0);
4077   if (i370_short_branch(insn) || mvs_check_label (CODE_LABEL_NUMBER (operands[0])))
4078     { 
4079       return \"BNL      %l0\";
4080     }
4081   mvs_check_page (0, 2, 4);
4082   return \"L    14,=A(%l0)\;BNLR        14\";
4083 }"
4084   [(set_attr "length" "6")]
4085 )
4086
4087 ;
4088 ; bgeu instruction pattern(s).
4089 ;
4090
4091 (define_insn "bgeu"
4092   [(set (pc)
4093         (if_then_else (geu (cc0)
4094                            (const_int 0))
4095                       (label_ref (match_operand 0 "" ""))
4096                       (pc)))
4097 ;   (clobber (reg:SI 14))
4098    ]
4099   ""
4100   "*
4101 {
4102   check_label_emit ();
4103   mvs_check_page (0, 4, 0);
4104   if (i370_short_branch(insn) || mvs_check_label (CODE_LABEL_NUMBER (operands[0])))
4105     { 
4106       return \"BNL      %l0\";
4107     }
4108   mvs_check_page (0, 2, 4);
4109   return \"L    14,=A(%l0)\;BNLR        14\";
4110 }"
4111   [(set_attr "length" "6")]
4112 )
4113
4114 ;
4115 ; ble instruction pattern(s).
4116 ;
4117
4118 (define_insn "ble"
4119   [(set (pc)
4120         (if_then_else (le (cc0)
4121                           (const_int 0))
4122                       (label_ref (match_operand 0 "" ""))
4123                       (pc)))
4124 ;   (clobber (reg:SI 14))
4125    ]
4126   ""
4127   "*
4128 {
4129   check_label_emit ();
4130   mvs_check_page (0, 4, 0);
4131   if (i370_short_branch(insn) || mvs_check_label (CODE_LABEL_NUMBER (operands[0])))
4132     { 
4133       return \"BNH      %l0\";
4134     }
4135   mvs_check_page (0, 2, 4);
4136   return \"L    14,=A(%l0)\;BNHR        14\";
4137 }"
4138   [(set_attr "length" "6")]
4139 )
4140
4141 ;
4142 ; bleu instruction pattern(s).
4143 ;
4144
4145 (define_insn "bleu"
4146   [(set (pc)
4147         (if_then_else (leu (cc0)
4148                            (const_int 0))
4149                       (label_ref (match_operand 0 "" ""))
4150                       (pc)))
4151 ;   (clobber (reg:SI 14))
4152    ]
4153   ""
4154   "*
4155 {
4156   check_label_emit ();
4157   mvs_check_page (0, 4, 0);
4158   if (i370_short_branch(insn) || mvs_check_label (CODE_LABEL_NUMBER (operands[0])))
4159     { 
4160       return \"BNH      %l0\";
4161     }
4162   mvs_check_page (0, 2, 4);
4163   return \"L    14,=A(%l0)\;BNHR        14\";
4164 }"
4165   [(set_attr "length" "6")]
4166 )
4167
4168 ;;
4169 ;;- Negated conditional jump instructions.
4170 ;;
4171
4172 (define_insn ""
4173   [(set (pc)
4174         (if_then_else (eq (cc0)
4175                           (const_int 0))
4176                       (pc)
4177                       (label_ref (match_operand 0 "" ""))))
4178 ;   (clobber (reg:SI 14))
4179    ]
4180   ""
4181   "*
4182 {
4183   check_label_emit ();
4184   mvs_check_page (0, 4, 0);
4185   if (i370_short_branch(insn) || mvs_check_label (CODE_LABEL_NUMBER (operands[0])))
4186     { 
4187       return \"BNE      %l0\";
4188     }
4189   mvs_check_page (0, 2, 4);
4190   return \"L    14,=A(%l0)\;BNER        14\";
4191 }"
4192   [(set_attr "length" "6")]
4193 )
4194
4195 (define_insn ""
4196   [(set (pc)
4197         (if_then_else (ne (cc0)
4198                           (const_int 0))
4199                       (pc)
4200                       (label_ref (match_operand 0 "" ""))))
4201 ;   (clobber (reg:SI 14))
4202    ]
4203   ""
4204   "*
4205 {
4206   check_label_emit ();
4207   mvs_check_page (0, 4, 0);
4208   if (i370_short_branch(insn) || mvs_check_label (CODE_LABEL_NUMBER (operands[0])))
4209     { 
4210       return \"BE       %l0\";
4211     }
4212   mvs_check_page (0, 2, 4);
4213   return \"L    14,=A(%l0)\;BER 14\";
4214 }"
4215   [(set_attr "length" "6")]
4216 )
4217
4218 (define_insn ""
4219   [(set (pc)
4220         (if_then_else (gt (cc0)
4221                           (const_int 0))
4222                       (pc)
4223                       (label_ref (match_operand 0 "" ""))))
4224 ;   (clobber (reg:SI 14))
4225    ]
4226   ""
4227   "*
4228 {
4229   check_label_emit ();
4230   mvs_check_page (0, 4, 0);
4231   if (i370_short_branch(insn) || mvs_check_label (CODE_LABEL_NUMBER (operands[0])))
4232     { 
4233       return \"BNH      %l0\";
4234     }
4235   mvs_check_page (0, 2, 4);
4236   return \"L    14,=A(%l0)\;BNHR        14\";
4237 }"
4238   [(set_attr "length" "6")]
4239 )
4240
4241 (define_insn ""
4242   [(set (pc)
4243         (if_then_else (gtu (cc0)
4244                            (const_int 0))
4245                       (pc)
4246                       (label_ref (match_operand 0 "" ""))))
4247 ;   (clobber (reg:SI 14))
4248    ]
4249   ""
4250   "*
4251 {
4252   check_label_emit ();
4253   mvs_check_page (0, 4, 0);
4254   if (i370_short_branch(insn) || mvs_check_label (CODE_LABEL_NUMBER (operands[0])))
4255     { 
4256       return \"BNH      %l0\";
4257     }
4258   mvs_check_page (0, 2, 4);
4259   return \"L    14,=A(%l0)\;BNHR        14\";
4260 }"
4261   [(set_attr "length" "6")]
4262 )
4263
4264 (define_insn ""
4265   [(set (pc)
4266         (if_then_else (lt (cc0)
4267                           (const_int 0))
4268                       (pc)
4269                       (label_ref (match_operand 0 "" ""))))
4270 ;   (clobber (reg:SI 14))
4271    ]
4272   ""
4273   "*
4274 {
4275   check_label_emit ();
4276   mvs_check_page (0, 4, 0);
4277   if (i370_short_branch(insn) || mvs_check_label (CODE_LABEL_NUMBER (operands[0])))
4278     { 
4279       return \"BNL      %l0\";
4280     }
4281   mvs_check_page (0, 2, 4);
4282   return \"L    14,=A(%l0)\;BNLR        14\";
4283 }"
4284   [(set_attr "length" "6")]
4285 )
4286
4287 (define_insn ""
4288   [(set (pc)
4289         (if_then_else (ltu (cc0)
4290                            (const_int 0))
4291                       (pc)
4292                       (label_ref (match_operand 0 "" ""))))
4293 ;   (clobber (reg:SI 14))
4294    ]
4295   ""
4296   "*
4297 {
4298   check_label_emit ();
4299   mvs_check_page (0, 4, 0);
4300   if (i370_short_branch(insn) || mvs_check_label (CODE_LABEL_NUMBER (operands[0])))
4301     { 
4302       return \"BNL      %l0\";
4303     }
4304   mvs_check_page (0, 2, 4);
4305   return \"L    14,=A(%l0)\;BNLR        14\";
4306 }"
4307   [(set_attr "length" "6")]
4308 )
4309
4310 (define_insn ""
4311   [(set (pc)
4312         (if_then_else (ge (cc0)
4313                           (const_int 0))
4314                       (pc)
4315                       (label_ref (match_operand 0 "" ""))))
4316 ;   (clobber (reg:SI 14))
4317    ]
4318   ""
4319   "*
4320 {
4321   check_label_emit ();
4322   mvs_check_page (0, 4, 0);
4323   if (i370_short_branch(insn) || mvs_check_label (CODE_LABEL_NUMBER (operands[0])))
4324     { 
4325       return \"BL       %l0\";
4326     }
4327   mvs_check_page (0, 2, 4);
4328   return \"L    14,=A(%l0)\;BLR 14\";
4329 }"
4330   [(set_attr "length" "6")]
4331 )
4332
4333 (define_insn ""
4334   [(set (pc)
4335         (if_then_else (geu (cc0)
4336                            (const_int 0))
4337                       (pc)
4338                       (label_ref (match_operand 0 "" ""))))
4339 ;   (clobber (reg:SI 14))
4340    ]
4341   ""
4342   "*
4343 {
4344   check_label_emit ();
4345   mvs_check_page (0, 4, 0);
4346   if (i370_short_branch(insn) || mvs_check_label (CODE_LABEL_NUMBER (operands[0])))
4347     { 
4348       return \"BL       %l0\";
4349     }
4350   mvs_check_page (0, 2, 4);
4351   return \"L    14,=A(%l0)\;BLR 14\";
4352 }"
4353   [(set_attr "length" "6")]
4354 )
4355
4356 (define_insn ""
4357   [(set (pc)
4358         (if_then_else (le (cc0)
4359                           (const_int 0))
4360                       (pc)
4361                       (label_ref (match_operand 0 "" ""))))
4362 ;   (clobber (reg:SI 14))
4363    ]
4364   ""
4365   "*
4366 {
4367   check_label_emit ();
4368   mvs_check_page (0, 4, 0);
4369   if (i370_short_branch(insn) || mvs_check_label (CODE_LABEL_NUMBER (operands[0])))
4370     { 
4371       return \"BH       %l0\";
4372     }
4373   mvs_check_page (0, 2, 4);
4374   return \"L    14,=A(%l0)\;BHR 14\";
4375 }"
4376   [(set_attr "length" "6")]
4377 )
4378
4379 (define_insn ""
4380   [(set (pc)
4381         (if_then_else (leu (cc0)
4382                            (const_int 0))
4383                       (pc)
4384                       (label_ref (match_operand 0 "" ""))))
4385 ;   (clobber (reg:SI 14))
4386    ]
4387   ""
4388   "*
4389 {
4390   check_label_emit ();
4391   mvs_check_page (0, 4, 0);
4392   if (i370_short_branch(insn) || mvs_check_label (CODE_LABEL_NUMBER (operands[0])))
4393     { 
4394       return \"BH       %l0\";
4395     }
4396   mvs_check_page (0, 2, 4);
4397   return \"L    14,=A(%l0)\;BHR 14\";
4398 }"
4399   [(set_attr "length" "6")]
4400 )
4401
4402 ;; ==============================================================
4403 ;;- Subtract one and jump if not zero.
4404 ;; These insns seem to not be getting matched ...
4405 ;; XXX should fix this, as it would improve for loops
4406
4407 (define_insn ""
4408   [(set (pc)
4409         (if_then_else
4410          (ne (plus:SI (match_operand:SI 0 "register_operand" "+d")
4411                       (const_int -1))
4412              (const_int 0))
4413          (label_ref (match_operand 1 "" ""))
4414          (pc)))
4415    (set (match_dup 0)
4416         (plus:SI (match_dup 0)
4417                  (const_int -1)))
4418 ;   (clobber (reg:SI 14))
4419    ]
4420   ""
4421   "*
4422 {
4423   check_label_emit ();
4424   mvs_check_page (0, 4, 0);
4425   if (mvs_check_label (CODE_LABEL_NUMBER (operands[1])))
4426     {
4427       return \"BCT      %0,%l1\";
4428     }
4429   mvs_check_page (0, 2, 4);
4430   return \"L    14,=A(%l1)\;BCTR        %0,14\";
4431 }"
4432   [(set_attr "length" "6")]
4433 )
4434
4435 (define_insn ""
4436   [(set (pc)
4437         (if_then_else
4438          (eq (plus:SI (match_operand:SI 0 "register_operand" "+d")
4439                       (const_int -1))
4440              (const_int 0))
4441          (pc)
4442          (label_ref (match_operand 1 "" ""))))
4443    (set (match_dup 0)
4444         (plus:SI (match_dup 0)
4445                  (const_int -1)))
4446 ;   (clobber (reg:SI 14))
4447    ]
4448   ""
4449   "*
4450 {
4451   check_label_emit ();
4452   mvs_check_page (0, 4, 0);
4453   if (mvs_check_label (CODE_LABEL_NUMBER (operands[1])))
4454     {
4455       return \"BCT      %0,%l1\";
4456     }
4457   mvs_check_page (0, 2, 4);
4458   return \"L    14,=A(%l1)\;BCTR        %0,14\";
4459 }"
4460   [(set_attr "length" "6")]
4461 )
4462
4463 ;; =============================================================
4464 ;;- Unconditional jump instructions.
4465 ;;
4466
4467 ;
4468 ; jump instruction pattern(s).
4469 ;
4470
4471 (define_insn "jump"
4472   [(set (pc)
4473         (label_ref (match_operand 0 "" "")))
4474 ;   (clobber (reg:SI 14))
4475    ]
4476   ""
4477   "*
4478 {
4479   check_label_emit ();
4480   mvs_check_page (0, 4, 0);
4481   if (i370_short_branch(insn) || mvs_check_label (CODE_LABEL_NUMBER (operands[0])))
4482     {
4483       return \"B        %l0\";
4484     }
4485   mvs_check_page (0, 2, 4);
4486   return \"L    14,=A(%l0)\;BR  14\";
4487 }"
4488   [(set_attr "length" "6")]
4489 )
4490
4491 ;
4492 ; indirect-jump instruction pattern(s).
4493 ; hack alert -- should check that displacement is < 4096
4494
4495 (define_insn "indirect_jump"
4496   [(set (pc) (match_operand:SI 0 "general_operand" "rm"))]
4497   ""
4498   "*
4499 {
4500   check_label_emit ();
4501   if (REG_P (operands[0]))
4502     {
4503       mvs_check_page (0, 2, 0);
4504       return \"BR       %0\";
4505     }
4506   mvs_check_page (0, 4, 0);
4507   return \"B    %0\";
4508 }"
4509   [(set_attr "length" "4")]
4510 )
4511
4512 ;
4513 ; tablejump instruction pattern(s).
4514 ;
4515
4516 (define_insn "tablejump"
4517   [(set (pc)
4518         (match_operand:SI 0 "general_operand" "am"))
4519    (use (label_ref (match_operand 1 "" "")))
4520 ;   (clobber (reg:SI 14))
4521    ]
4522   ""
4523   "*
4524 {
4525   check_label_emit ();
4526   if (REG_P (operands[0]))
4527     {
4528       mvs_check_page (0, 6, 0);
4529       return \"BR       %0\;DS  0F\";
4530     }
4531   mvs_check_page (0, 10, 0);
4532   return \"L    14,%0\;BR       14\;DS  0F\";
4533 }"
4534   [(set_attr "length" "10")]
4535 )
4536
4537 ;;
4538 ;;- Jump to subroutine.
4539 ;;
4540 ;; For the C/370 environment the internal functions, ie. sqrt, are called with
4541 ;; a non-standard form.  So, we must fix it here.  There's no BM like IBM.
4542 ;;
4543 ;; The ELF ABI is different from the C/370 ABI because we have a simpler,
4544 ;; more powerful way of dealing with structure-value returns.  Basically, 
4545 ;; we use R1 to point at structure returns (64-bit and larger returns)
4546 ;; and R11 to point at the args.  Note that this handles double-precision
4547 ;; (64-bit) values just fine, in a less-kludged manner than the C/370 ABI.
4548 ;; Since R1 is used, we use R2 to pass the argument pointer to the routine.
4549
4550 ;
4551 ; call instruction pattern(s).
4552 ;
4553 ; We define four call instruction patterns below. The first two patterns,
4554 ; although general, end up matching (only?) calls through function pointers.  
4555 ; The last two, which require a symbol-ref to match, get used for all
4556 ; ordinary subroutine calls.
4557
4558 (define_insn "call"
4559   [(call (match_operand:QI 0 "memory_operand" "m")
4560          (match_operand:SI 1 "immediate_operand" "i"))
4561    (clobber (reg:SI 2))
4562    ]
4563   ""
4564   "*
4565 {
4566   static char temp[128];
4567   int i = STACK_POINTER_OFFSET;
4568   CC_STATUS_INIT;
4569
4570   check_label_emit ();
4571 #ifdef TARGET_ELF_ABI
4572   mvs_check_page (0, 10, 4);
4573   sprintf ( temp, \"LA  r2,%d(,sp)\;LA  15,%%0\;BASR    14,15\", i );
4574   return temp;
4575 #else
4576   if (mvs_function_check (XSTR (operands[0], 0)))
4577     {
4578       mvs_check_page (0, 22, 4);
4579       sprintf ( temp, \"LA      1,136(,13)\;ST  1,%d(,13)\;LA 1,%d(,13)\;LA     15,%%0\;BALR    14,15\;LD       0,136(,13)\",
4580              i - 4, i - 4 );
4581     }
4582   else
4583     {
4584       mvs_check_page (0, 10, 4);
4585       sprintf ( temp, \"LA      1,%d(,13)\;LA   15,%%0\;BALR    14,15\", i );
4586     }
4587   return temp;
4588 #endif
4589 }"
4590   [(set_attr "length" "22")]
4591 )
4592
4593 ;
4594 ; call_value instruction pattern(s).
4595 ;
4596
4597 (define_insn "call_value"
4598   [(set (match_operand 0 "" "=rf")
4599         (call (match_operand:QI 1 "memory_operand" "m")
4600               (match_operand:SI 2 "general_operand" "i")))
4601    (clobber (reg:SI 2))
4602    ]
4603   ""
4604   "*
4605 {
4606   static char temp[128];
4607   int i = STACK_POINTER_OFFSET;
4608   CC_STATUS_INIT;
4609
4610   check_label_emit ();
4611 #ifdef TARGET_ELF_ABI
4612   mvs_check_page (0, 10, 4);
4613   sprintf ( temp, \"LA  r2,%d(,sp)\;LA  15,%%1\;BASR    14,15\", i );
4614   return temp;
4615 #else
4616   if (mvs_function_check (XSTR (operands[1], 0)))
4617     {
4618       mvs_check_page (0, 22, 4);
4619       sprintf ( temp, \"LA      1,136(,13)\;ST  1,%d(,13)\;LA 1,%d(,13)\;LA     15,%%1\;BALR    14,15\;LD       0,136(,13)\",
4620            i - 4, i - 4 );
4621     }
4622   else
4623     {
4624       mvs_check_page (0, 10, 4);
4625       sprintf ( temp, \"LA      1,%d(,13)\;LA   15,%%1\;BALR    14,15\", i );
4626     }
4627   return temp;
4628 #endif
4629 }"
4630   [(set_attr "length" "22")]
4631 )
4632
4633 (define_insn ""
4634   [(call (mem:QI (match_operand:SI 0 "" "i"))
4635          (match_operand:SI 1 "general_operand" "g"))
4636    (clobber (reg:SI 2))
4637    ]
4638   "GET_CODE (operands[0]) == SYMBOL_REF"
4639   "*
4640 {
4641   static char temp[128];
4642   int i = STACK_POINTER_OFFSET;
4643   CC_STATUS_INIT;
4644
4645   check_label_emit ();
4646 #ifdef TARGET_ELF_ABI
4647   mvs_check_page (0, 10, 4);
4648   sprintf ( temp, \"LA  r2,%d(,sp)\;L   15,%%0\;BASR    14,15\", i );
4649   return temp;
4650 #else
4651   if (mvs_function_check (XSTR (operands[0], 0)))
4652     {
4653       mvs_check_page (0, 22, 4);
4654       sprintf ( temp, \"LA      1,136(,13)\;ST  1,%d(,13)\;LA   1,%d(,13)\;L    15,%%0\;BALR    14,15\;LD       0,136(,13)\",
4655            i - 4, i - 4 );
4656     }
4657   else
4658     {
4659       mvs_check_page (0, 10, 4);
4660       sprintf ( temp, \"LA      1,%d(,13)\;L    15,%%0\;BALR    14,15\", i );
4661     }
4662   return temp;
4663 #endif
4664 }"
4665   [(set_attr "length" "22")]
4666 )
4667
4668 (define_insn ""
4669   [(set (match_operand 0 "" "=rf")
4670         (call (mem:QI (match_operand:SI 1 "" "i"))
4671               (match_operand:SI 2 "general_operand" "g")))
4672    (clobber (reg:SI 2))
4673    ]
4674   "GET_CODE (operands[1]) == SYMBOL_REF"
4675   "*
4676 {
4677   static char temp[128];
4678   int i = STACK_POINTER_OFFSET;
4679   CC_STATUS_INIT;
4680
4681   check_label_emit ();
4682 #ifdef TARGET_ELF_ABI
4683   mvs_check_page (0, 10, 4);
4684   sprintf ( temp, \"LA  r2,%d(,sp)\;L   15,%%1\;BASR    14,15\", i );
4685   return temp;
4686 #else
4687   if (mvs_function_check (XSTR (operands[1], 0)))
4688     {
4689       mvs_check_page (0, 22, 4);
4690       sprintf ( temp, \"LA      1,136(,13)\;ST  1,%d(,13)\;LA   1,%d(,13)\;L    15,%%1\;BALR    14,15\;LD       0,136(,13)\",
4691            i - 4, i - 4 );
4692     }
4693   else
4694     {
4695       mvs_check_page (0, 10, 4);
4696       sprintf ( temp, \"LA      1,%d(,13)\;L    15,%%1\;BALR    14,15\", i );
4697     }
4698   return temp;
4699 #endif
4700 }"
4701   [(set_attr "length" "22")]
4702 )
4703
4704 ;;
4705 ;; Call subroutine returning any type.
4706 ;; This instruction pattern appears to be used only by the
4707 ;; expand_builtin_apply definition for __builtin_apply.  It is needed
4708 ;; since call_value might return an in in r15 or a float in fpr0 (r16)
4709 ;; and the builtin code calla abort since the reg is ambiguous. Well,
4710 ;; the below is probably broken anyway, we just want to go for now.
4711 ;;
4712 (define_expand "untyped_call"
4713 [(parallel [(call (match_operand 0 "" "")
4714                   (const_int 0))
4715               (match_operand 1 "" "")
4716               (match_operand 2 "" "")])]
4717   ""
4718   "
4719 {
4720   int i;
4721
4722   emit_call_insn (gen_call (operands[0], const0_rtx, const0_rtx, const0_rtx));
4723
4724   for (i = 0; i < XVECLEN (operands[2], 0); i++)
4725     {
4726       rtx set = XVECEXP (operands[2], 0, i);
4727       emit_move_insn (SET_DEST (set), SET_SRC (set));
4728     }
4729
4730   /* The optimizer does not know that the call sets the function value
4731      registers we stored in the result block.  We avoid problems by
4732      claiming that all hard registers are used and clobbered at this
4733      point.  */
4734   /* emit_insn (gen_blockage ()); */
4735
4736   DONE;
4737 }")
4738
4739
4740 ;;
4741 ;;- Miscellaneous instructions.
4742 ;;
4743
4744 ;
4745 ; nop instruction pattern(s).
4746 ;
4747
4748 (define_insn "nop"
4749   [(const_int 0)]
4750   ""
4751   "*
4752 {
4753   check_label_emit ();
4754   mvs_check_page (0, 2, 0);
4755   return \"LR   0,0\";
4756 }"
4757   [(set_attr "length" "2")]
4758 )