OSDN Git Service

Imported from mainline FSF repositories
[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, 2002
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 GCC.
9
10 ;; GCC 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 ;; GCC 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 GCC; 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 ; deprecate 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 ; cmpmemsi instruction pattern(s).
478 ;
479
480 (define_expand "cmpmemsi"
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, GET_MODE_SIZE (SImode)), 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, GET_MODE_SIZE (SImode)), len);
546
547         /* Compare! */
548         emit_insn (gen_cmpmemsi_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 "cmpmemsi_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_EXTERNAL_P (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_EXTERNAL_P (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         /* implementation suggested by  Richard Henderson <rth@cygnus.com> */
1385         rtx reg1 = gen_reg_rtx (DImode);
1386         rtx reg2 = gen_reg_rtx (DImode);
1387         rtx mem1 = operands[0];
1388         rtx zippo = gen_rtx_CONST_INT (SImode, 0);
1389         rtx len = operands[1];
1390         if (!CONSTANT_P (len))
1391           len = force_reg (SImode, len);
1392
1393         /* Load up the address+length pairs.  */
1394         emit_insn (gen_rtx_CLOBBER (VOIDmode, reg1));
1395         emit_move_insn (gen_rtx_SUBREG (SImode, reg1, 0),
1396                         force_operand (XEXP (mem1, 0), NULL_RTX));
1397         emit_move_insn (gen_rtx_SUBREG (SImode, reg1, GET_MODE_SIZE (SImode)), len);
1398
1399         emit_insn (gen_rtx_CLOBBER (VOIDmode, reg2));
1400         emit_move_insn (gen_rtx_SUBREG (SImode, reg2, 0), zippo);
1401         emit_move_insn (gen_rtx_SUBREG (SImode, reg2, GET_MODE_SIZE (SImode)), zippo);
1402
1403         /* Copy! */
1404         emit_insn (gen_movstrsi_1 (reg1, reg2));
1405   }
1406   DONE;
1407 }")
1408
1409 ;
1410 ; movstrsi instruction pattern(s).
1411 ; block must be less than 16M (24 bits) in length
1412
1413 (define_expand "movstrsi"
1414   [(set (match_operand:BLK 0 "general_operand" "")
1415         (match_operand:BLK 1 "general_operand" ""))
1416    (use (match_operand:SI  2 "general_operand" ""))
1417    (match_operand 3 "" "")]
1418    ""
1419    "
1420 {
1421   rtx op0, op1;
1422
1423   op0 = XEXP (operands[0], 0);
1424   if (GET_CODE (op0) == REG
1425       || (GET_CODE (op0) == PLUS && GET_CODE (XEXP (op0, 0)) == REG
1426           && GET_CODE (XEXP (op0, 1)) == CONST_INT
1427           && (unsigned) INTVAL (XEXP (op0, 1)) < 4096))
1428     op0 = operands[0];
1429   else
1430     op0 = replace_equiv_address (operands[0], copy_to_mode_reg (SImode, op0));
1431
1432   op1 = XEXP (operands[1], 0);
1433   if (GET_CODE (op1) == REG
1434       || (GET_CODE (op1) == PLUS && GET_CODE (XEXP (op1, 0)) == REG
1435           && GET_CODE (XEXP (op1, 1)) == CONST_INT
1436           && (unsigned) INTVAL (XEXP (op1, 1)) < 4096))
1437     op1 = operands[1];
1438   else
1439     op1 = replace_equiv_address (operands[1], copy_to_mode_reg (SImode, op1));
1440
1441   if (GET_CODE (operands[2]) == CONST_INT && INTVAL (operands[2]) < 256)
1442     emit_insn (gen_rtx_PARALLEL (VOIDmode,
1443                         gen_rtvec (2,
1444                                    gen_rtx_SET (VOIDmode, op0, op1),
1445                                    gen_rtx_USE (VOIDmode, operands[2]))));
1446
1447   else
1448     {
1449         /* implementation provided by  Richard Henderson <rth@cygnus.com> */
1450         rtx reg1 = gen_reg_rtx (DImode);
1451         rtx reg2 = gen_reg_rtx (DImode);
1452         rtx mem1 = operands[0];
1453         rtx mem2 = operands[1];
1454         rtx len = operands[2];
1455         if (!CONSTANT_P (len))
1456           len = force_reg (SImode, len);
1457
1458         /* Load up the address+length pairs.  */
1459         emit_insn (gen_rtx_CLOBBER (VOIDmode, reg1));
1460         emit_move_insn (gen_rtx_SUBREG (SImode, reg1, 0),
1461                         force_operand (XEXP (mem1, 0), NULL_RTX));
1462         emit_move_insn (gen_rtx_SUBREG (SImode, reg1, GET_MODE_SIZE (SImode)), len);
1463
1464         emit_insn (gen_rtx_CLOBBER (VOIDmode, reg2));
1465         emit_move_insn (gen_rtx_SUBREG (SImode, reg2, 0),
1466                         force_operand (XEXP (mem2, 0), NULL_RTX));
1467         emit_move_insn (gen_rtx_SUBREG (SImode, reg2, GET_MODE_SIZE (SImode)), len);
1468
1469         /* Copy! */
1470         emit_insn (gen_movstrsi_1 (reg1, reg2));
1471     }
1472   DONE;
1473 }")
1474
1475 ; Move a block that is less than 256 bytes in length.
1476
1477 (define_insn ""
1478   [(set (match_operand:BLK 0 "s_operand" "=m")
1479         (match_operand:BLK 1 "s_operand" "m"))
1480    (use (match_operand 2 "immediate_operand" "I"))]
1481   "((unsigned) INTVAL (operands[2]) < 256)"
1482   "*
1483 {
1484   check_label_emit ();
1485   mvs_check_page (0, 6, 0);
1486   return \"MVC  %O0(%c2,%R0),%1\";
1487 }"
1488    [(set_attr "length" "6")]
1489 )
1490
1491 ; Move a block that is larger than 255 bytes in length.
1492
1493 (define_insn "movstrsi_1"
1494   [(set (mem:BLK (subreg:SI (match_operand:DI 0 "register_operand" "+d") 0))
1495         (mem:BLK (subreg:SI (match_operand:DI 1 "register_operand" "+d") 0)))
1496    (use (match_dup 0))
1497    (use (match_dup 1))
1498    (clobber (match_dup 0))
1499    (clobber (match_dup 1))]
1500   ""
1501   "*
1502 {
1503   check_label_emit ();
1504   mvs_check_page (0, 2, 0);
1505   return \"MVCL %0,%1\";
1506 }"
1507    [(set_attr "length" "2")]
1508 )
1509
1510 ;;
1511 ;;- Conversion instructions.
1512 ;;
1513
1514 ;
1515 ; extendsidi2 instruction pattern(s).
1516 ;
1517
1518 (define_expand "extendsidi2"
1519   [(set (match_operand:DI 0 "register_operand" "=d")
1520         (sign_extend:DI (match_operand:SI 1 "general_operand" "")))]
1521   ""
1522   "
1523 {
1524   if (GET_CODE (operands[1]) != CONST_INT)
1525     {
1526       emit_insn (gen_rtx_SET (VOIDmode,
1527                   operand_subword (operands[0], 0, 1, DImode), operands[1]));
1528       emit_insn (gen_rtx_SET (VOIDmode, operands[0],
1529                         gen_rtx_ASHIFTRT (DImode, operands[0],
1530                                 gen_rtx_CONST_INT (SImode, 32))));
1531     }
1532   else
1533     {
1534       if (INTVAL (operands[1]) < 0)
1535         {
1536           emit_insn (gen_rtx_SET (VOIDmode,
1537                                   operand_subword (operands[0], 0, 1, DImode),
1538                                gen_rtx_CONST_INT (SImode, -1)));
1539         }
1540       else
1541         {
1542           emit_insn (gen_rtx_SET (VOIDmode,
1543                                 operand_subword (operands[0], 0, 1, DImode),
1544                                gen_rtx_CONST_INT (SImode, 0)));
1545         }
1546       emit_insn (gen_rtx_SET (VOIDmode, gen_lowpart (SImode, operands[0]),
1547                            operands[1]));
1548     }
1549   DONE;
1550 }")
1551
1552 ;
1553 ; extendhisi2 instruction pattern(s).
1554 ;
1555
1556 (define_insn "extendhisi2"
1557   [(set (match_operand:SI 0 "general_operand" "=d,m")
1558         (sign_extend:SI (match_operand:HI 1 "general_operand" "g,d")))]
1559   ""
1560   "*
1561 {
1562   check_label_emit ();
1563   if (REG_P (operands[0]))
1564     {
1565       if (REG_P (operands[1]))
1566       {
1567         if (REGNO (operands[0]) != REGNO (operands[1]))
1568           {
1569             mvs_check_page (0, 10, 0);
1570             return \"LR %0,%1\;SLL      %0,16\;SRA      %0,16\";
1571           }
1572         else
1573           return \"\"; /* Should be empty.  16-bits regs are always 32-bits.  */
1574       }
1575       if (operands[1] == const0_rtx)
1576         {
1577           CC_STATUS_INIT;
1578           mvs_check_page (0, 2, 0);
1579           return \"SLR  %0,%0\";
1580         }
1581       if (GET_CODE (operands[1]) == CONST_INT
1582           && (unsigned) INTVAL (operands[1]) < 4096)
1583         {
1584           mvs_check_page (0, 4, 0);
1585           return \"LA   %0,%c1(0,0)\";
1586         }
1587       if (GET_CODE (operands[1]) == CONST_INT)
1588         {
1589           mvs_check_page (0, 4, 0);
1590           return \"LH   %0,%H1\";
1591         }
1592       mvs_check_page (0, 4, 0);
1593       return \"LH       %0,%1\";
1594     }
1595   mvs_check_page (0, 12, 0);
1596   return \"SLL  %1,16\;SRA      %1,16\;ST       %1,%0\";
1597 }"
1598    [(set_attr "length" "12")]
1599 )
1600
1601 ;
1602 ; extendqisi2 instruction pattern(s).
1603 ;
1604
1605 (define_insn "extendqisi2"
1606   [(set (match_operand:SI 0 "general_operand" "=d")
1607         (sign_extend:SI (match_operand:QI 1 "general_operand" "0mi")))]
1608   ""
1609   "*
1610 {
1611   check_label_emit ();
1612   CC_STATUS_SET (operands[0], operands[1]);
1613   if (REG_P (operands[1]))
1614     {
1615       mvs_check_page (0, 8, 0);
1616       return \"SLL      %0,24\;SRA      %0,24\";
1617     }
1618   if (s_operand (operands[1], GET_MODE (operands[1])))
1619     {
1620       mvs_check_page (0, 8, 0);
1621       return \"ICM      %0,8,%1\;SRA    %0,24\";
1622     }
1623   mvs_check_page (0, 12, 0);
1624   return \"IC   %0,%1\;SLL      %0,24\;SRA      %0,24\";
1625 }"
1626    [(set_attr "length" "12")]
1627 )
1628
1629 ;
1630 ; extendqihi2 instruction pattern(s).
1631 ;
1632
1633 (define_insn "extendqihi2"
1634   [(set (match_operand:HI 0 "general_operand" "=d")
1635         (sign_extend:HI (match_operand:QI 1 "general_operand" "0m")))]
1636   ""
1637   "*
1638 {
1639   check_label_emit ();
1640   CC_STATUS_SET (operands[0], operands[1]);
1641   if (REG_P (operands[1]))
1642     {
1643       mvs_check_page (0, 8, 0);
1644       return \"SLL      %0,24\;SRA      %0,24\";
1645     }
1646   if (s_operand (operands[1], GET_MODE (operands[1])))
1647     {
1648       mvs_check_page (0, 8, 0);
1649       return \"ICM      %0,8,%1\;SRA    %0,24\";
1650     }
1651   mvs_check_page (0, 12, 0);
1652   return \"IC   %0,%1\;SLL      %0,24\;SRA      %0,24\";
1653 }"
1654    [(set_attr "length" "12")]
1655 )
1656
1657 ;
1658 ; zero_extendsidi2 instruction pattern(s).
1659 ;
1660
1661 (define_expand "zero_extendsidi2"
1662   [(set (match_operand:DI 0 "register_operand" "=d")
1663         (zero_extend:DI (match_operand:SI 1 "general_operand" "")))]
1664   ""
1665   "
1666 {
1667       emit_insn (gen_rtx_SET (VOIDmode,
1668                   operand_subword (operands[0], 0, 1, DImode), operands[1]));
1669       emit_insn (gen_rtx_SET (VOIDmode, operands[0],
1670                         gen_rtx_LSHIFTRT (DImode, operands[0],
1671                                 gen_rtx_CONST_INT (SImode, 32))));
1672   DONE;
1673 }")
1674
1675 ;
1676 ; zero_extendhisi2 instruction pattern(s).
1677 ;
1678
1679 (define_insn "zero_extendhisi2"
1680   [(set (match_operand:SI 0 "general_operand" "=d")
1681         (zero_extend:SI (match_operand:HI 1 "general_operand" "0")))]
1682   ""
1683   "*
1684 {
1685   check_label_emit ();
1686   /* AND only sets zero/not-zero bits not the arithmetic bits ...  */
1687   CC_STATUS_INIT;
1688   mvs_check_page (0, 4, 4);
1689   return \"N    %1,=XL4'0000FFFF'\";
1690 }"
1691    [(set_attr "length" "4")]
1692 )
1693
1694 ;
1695 ; zero_extendqisi2 instruction pattern(s).
1696 ;
1697
1698 (define_insn "zero_extendqisi2"
1699   [(set (match_operand:SI 0 "general_operand" "=d,&d")
1700         (zero_extend:SI (match_operand:QI 1 "general_operand" "0i,m")))]
1701   ""
1702   "*
1703 {
1704   check_label_emit ();
1705   if (REG_P (operands[1]))
1706     {
1707       /* AND only sets zero/not-zero bits not the arithmetic bits ...  */
1708       CC_STATUS_INIT;
1709       mvs_check_page (0, 4, 4);
1710       return \"N        %0,=XL4'000000FF'\";
1711     }
1712   if (GET_CODE (operands[1]) == CONST_INT)
1713     {
1714       mvs_check_page (0, 4, 0);
1715       return \"LA       %0,%c1(0,0)\";
1716     }
1717   CC_STATUS_INIT;
1718   mvs_check_page (0, 8, 0);
1719   return \"SLR  %0,%0\;IC       %0,%1\";
1720 }"
1721    [(set_attr "length" "8")]
1722 )
1723
1724 ;
1725 ; zero_extendqihi2 instruction pattern(s).
1726 ;
1727
1728 (define_insn "zero_extendqihi2"
1729   [(set (match_operand:HI 0 "general_operand" "=d,&d")
1730         (zero_extend:HI (match_operand:QI 1 "general_operand" "0i,m")))]
1731   ""
1732   "*
1733 {
1734   check_label_emit ();
1735   if (REG_P (operands[1]))
1736     {
1737       /* AND only sets zero/not-zero bits not the arithmetic bits ...  */
1738       CC_STATUS_INIT;
1739       mvs_check_page (0, 4, 4);
1740       return \"N        %0,=XL4'000000FF'\";
1741     }
1742   if (GET_CODE (operands[1]) == CONST_INT)
1743     {
1744       mvs_check_page (0, 4, 0);
1745       return \"LA       %0,%c1(0,0)\";
1746     }
1747   CC_STATUS_INIT;
1748   mvs_check_page (0, 8, 0);
1749   return \"SLR  %0,%0\;IC       %0,%1\";
1750 }"
1751    [(set_attr "length" "8")]
1752 )
1753
1754 ;
1755 ; truncsihi2 instruction pattern(s).
1756 ;
1757
1758 (define_insn "truncsihi2"
1759   [(set (match_operand:HI 0 "general_operand" "=d,m")
1760         (truncate:HI (match_operand:SI 1 "general_operand" "0,d")))]
1761   ""
1762   "*
1763 {
1764   check_label_emit ();
1765   if (REG_P (operands[0]))
1766     {
1767       CC_STATUS_SET (operands[0], operands[1]);
1768       mvs_check_page (0, 8, 0);
1769       return \"SLL      %0,16\;SRA      %0,16\";
1770     }
1771   mvs_check_page (0, 4, 0);
1772   return \"STH  %1,%0\";
1773 }"
1774    [(set_attr "length" "8")]
1775 )
1776
1777 ;
1778 ; fix_truncdfsi2 instruction pattern(s).
1779 ;
1780
1781 (define_insn "fix_truncdfsi2"
1782   [(set (match_operand:SI 0 "general_operand" "=d")
1783         (fix:SI (truncate:DF (match_operand:DF 1 "general_operand" "+f"))))
1784         (clobber (reg:DF 16))]
1785   ""
1786   "*
1787 {
1788   check_label_emit ();
1789   CC_STATUS_INIT;
1790   if (REGNO (operands[1]) == 16)
1791     {
1792       mvs_check_page (0, 12, 8);
1793       return \"AD       0,=XL8'4F08000000000000'\;STD   0,140(,13)\;L   %0,144(,13)\";
1794     }
1795   mvs_check_page (0, 14, 8);
1796   return \"LDR  0,%1\;AD        0,=XL8'4F08000000000000'\;STD   0,140(,13)\;L   %0,144(,13)\";
1797 }"
1798    [(set_attr "length" "14")]
1799 )
1800
1801 ;
1802 ; floatsidf2 instruction pattern(s).
1803 ;
1804 ; LE/370 mode uses the float field of the TCA.
1805 ;
1806
1807 (define_insn "floatsidf2"
1808   [(set (match_operand:DF 0 "general_operand" "=f")
1809         (float:DF (match_operand:SI 1 "general_operand" "d")))]
1810   ""
1811   "*
1812 {
1813   check_label_emit ();
1814   CC_STATUS_INIT;
1815 #ifdef TARGET_ELF_ABI
1816   mvs_check_page (0, 22, 12);
1817   return \"MVC  140(4,13),=XL4'4E000000'\;ST    %1,144(,13)\;XI 144(13),128\;LD %0,140(,13)\;SD %0,=XL8'4E00000080000000'\";
1818 #else
1819   mvs_check_page (0, 16, 8);
1820   return \"ST   %1,508(,12)\;XI 508(12),128\;LD %0,504(,12)\;SD %0,=XL8'4E00000080000000'\";
1821 #endif
1822 }"
1823    [(set_attr "length" "22")]
1824 )
1825
1826 ;
1827 ; truncdfsf2 instruction pattern(s).
1828 ;
1829
1830 (define_insn "truncdfsf2"
1831   [(set (match_operand:SF 0 "general_operand" "=f")
1832         (float_truncate:SF (match_operand:DF 1 "general_operand" "f")))]
1833   ""
1834   "*
1835 {
1836   check_label_emit ();
1837   mvs_check_page (0, 2, 0);
1838   return \"LRER %0,%1\";
1839 }"
1840    [(set_attr "length" "2")]
1841 )
1842
1843 ;
1844 ; extendsfdf2 instruction pattern(s).
1845
1846
1847 (define_insn "extendsfdf2"
1848   [(set (match_operand:DF 0 "general_operand" "=f")
1849         (float_extend:DF (match_operand:SF 1 "general_operand" "fmF")))]
1850   ""
1851   "*
1852 {
1853   check_label_emit ();
1854   CC_STATUS_SET (0, const0_rtx);
1855   if (FP_REG_P (operands[1]))
1856     {
1857       if (REGNO (operands[0]) == REGNO (operands[1]))
1858         {
1859           mvs_check_page (0, 10, 0);
1860           return \"STE  %1,140(,13)\;SDR        %0,%0\;LE       %0,140(,13)\";
1861         }
1862       mvs_check_page (0, 4, 0);
1863       return \"SDR      %0,%0\;LER      %0,%1\";
1864     }
1865   mvs_check_page (0, 6, 0);
1866   return \"SDR  %0,%0\;LE       %0,%1\";
1867 }"
1868    [(set_attr "length" "10")]
1869 )
1870
1871 ;;
1872 ;;- Add instructions.
1873 ;;
1874
1875 ;
1876 ; adddi3 instruction pattern(s).
1877 ;
1878 ;
1879 ;(define_expand "adddi3"
1880 ;  [(set (match_operand:DI 0 "general_operand" "")
1881 ;       (plus:DI (match_operand:DI 1 "general_operand" "")
1882 ;                (match_operand:DI 2 "general_operand" "")))]
1883 ;  ""
1884 ;  "
1885 ;{
1886 ;  rtx label = gen_label_rtx ();
1887 ;  rtx op0_high = operand_subword (operands[0], 0, 1, DImode);
1888 ;  rtx op0_low = gen_lowpart (SImode, operands[0]);
1889 ;       
1890 ;  emit_insn (gen_rtx_SET (VOIDmode, op0_high,
1891 ;                   gen_rtx_PLUS (SImode,
1892 ;                           operand_subword (operands[1], 0, 1, DImode),
1893 ;                           operand_subword (operands[2], 0, 1, DImode))));
1894 ;  emit_jump_insn (gen_rtx_PARALLEL (VOIDmode, gen_rtvec (2,
1895 ;             gen_rtx_SET (VOIDmode, op0_low,
1896 ;                     gen_rtx_PLUS (SImode, gen_lowpart (SImode, operands[1]),
1897 ;                             gen_lowpart (SImode, operands[2]))),
1898 ;             gen_rtx_USE (VOIDmode, gen_rtx_LABEL_REF (VOIDmode, label)))));
1899 ;  emit_insn (gen_rtx_SET (VOIDmode, op0_high,
1900 ;                   gen_rtx_PLUS (SImode, op0_high,
1901 ;                           gen_rtx_CONST_INT (SImode, 1))));
1902 ;  emit_label (label);
1903 ;  DONE;
1904 ;}")
1905
1906 (define_insn ""
1907   [(set (match_operand:SI 0 "general_operand" "=d")
1908         (plus:SI (match_operand:SI 1 "general_operand" "%0")
1909                  (match_operand:SI 2 "general_operand" "g")))
1910    (use (label_ref (match_operand 3 "" "")))
1911 ;   (clobber (reg:SI 14))
1912    ]
1913   ""
1914   "*
1915 {
1916   int onpage;
1917
1918   check_label_emit ();
1919   onpage = mvs_check_label (CODE_LABEL_NUMBER (operands[3]));
1920   if (REG_P (operands[2]))
1921     {
1922       if (!onpage)
1923         {
1924           mvs_check_page (0, 8, 4);
1925           return \"ALR  %0,%2\;L        14,=A(%l3)\;BCR 12,14\";
1926         }
1927       if (mvs_check_page (0, 6, 0))
1928         {
1929           mvs_check_page (0, 2, 4);
1930           return \"ALR  %0,%2\;L        14,=A(%l3)\;BCR 12,14\";
1931         }
1932       return \"ALR      %0,%2\;BC       12,%l3\";
1933     }
1934   if (!onpage)
1935     {
1936       mvs_check_page (0, 10, 4);
1937       return \"AL       %0,%2\;L        14,=A(%l3)\;BCR 12,14\";
1938     }
1939   if (mvs_check_page (0, 8 ,0))
1940     {
1941       mvs_check_page (0, 2, 4);
1942       return \"AL       %0,%2\;L        14,=A(%l3)\;BCR 12,14\";
1943     }
1944   return \"AL   %0,%2\;BC       12,%l3\";
1945 }"
1946    [(set_attr "length" "10")]
1947 )
1948
1949 ;
1950 ; addsi3 instruction pattern(s).
1951 ;
1952 ; The following insn is used when it is known that operand one is an address,
1953 ; frame, stack or argument pointer, and operand two is a constant that is
1954 ; small enough to fit in the displacement field.
1955 ; Notice that we can't allow the frame pointer to used as a normal register
1956 ; because of this insn.
1957 ;
1958
1959 (define_insn ""
1960   [(set (match_operand:SI 0 "register_operand" "=d")
1961         (plus:SI (match_operand:SI 1 "general_operand" "%a")
1962                  (match_operand:SI 2 "immediate_operand" "J")))]
1963   "((REGNO (operands[1]) == FRAME_POINTER_REGNUM || REGNO (operands[1]) == ARG_POINTER_REGNUM || REGNO (operands[1]) == STACK_POINTER_REGNUM) && (unsigned) INTVAL (operands[2]) < 4096)"
1964   "*
1965 {
1966   check_label_emit ();
1967   CC_STATUS_INIT;  /* add assumes CC but LA doesn't set CC */
1968   mvs_check_page (0, 4, 0);
1969   return \"LA   %0,%c2(,%1)\";
1970 }"
1971    [(set_attr "length" "4")]
1972 )
1973
1974 ; This insn handles additions that are relative to the frame pointer.
1975
1976 (define_insn ""
1977   [(set (match_operand:SI 0 "register_operand" "=d")
1978          (plus:SI (match_operand:SI 1 "register_operand" "%a")
1979                   (match_operand:SI 2 "immediate_operand" "i")))]
1980   "REGNO (operands[1]) == FRAME_POINTER_REGNUM"
1981   "*
1982 {
1983   check_label_emit ();
1984   if ((unsigned) INTVAL (operands[2]) < 4096)
1985     {
1986       CC_STATUS_INIT;  /* add assumes CC but LA doesn't set CC */
1987       mvs_check_page (0, 4, 0);
1988       return \"LA       %0,%c2(,%1)\";
1989     }
1990   if (REGNO (operands[1]) == REGNO (operands[0]))
1991     {
1992       CC_STATUS_INIT;
1993       mvs_check_page (0, 4, 0);
1994       return \"A        %0,%2\";
1995     }
1996   mvs_check_page (0, 6, 0);
1997   return \"L    %0,%2\;AR       %0,%1\";
1998 }"
1999    [(set_attr "length" "6")]
2000 )
2001
2002 ;;
2003 ;; The CC status bits for the arithmetic instructions are handled
2004 ;; in the NOTICE_UPDATE_CC macro (yeah???) and so they do not need
2005 ;; to be set below.  They only need to be invalidated if *not* set 
2006 ;; (e.g. by BCTR) ... yeah I think that's right ...
2007 ;; 
2008
2009 (define_insn "addsi3"
2010   [(set (match_operand:SI 0 "general_operand" "=d")
2011         (plus:SI (match_operand:SI 1 "general_operand" "%0")
2012                  (match_operand:SI 2 "general_operand" "g")))]
2013   ""
2014   "*
2015 {
2016   check_label_emit ();
2017   if (REG_P (operands[2]))
2018     {
2019       mvs_check_page (0, 2, 0);
2020       return \"AR       %0,%2\";
2021     }
2022   if (GET_CODE (operands[2]) == CONST_INT)
2023     {
2024       if (INTVAL (operands[2]) == -1)
2025         {
2026           CC_STATUS_INIT;  /* add assumes CC but BCTR doesn't set CC */
2027           mvs_check_page (0, 2, 0);
2028           return \"BCTR %0,0\";
2029         }
2030     }
2031   mvs_check_page (0, 4, 0);
2032   return \"A    %0,%2\";
2033 }"
2034    [(set_attr "length" "4")]
2035 )
2036
2037 ;
2038 ; addhi3 instruction pattern(s).
2039 ;
2040
2041 (define_insn "addhi3"
2042   [(set (match_operand:HI 0 "general_operand" "=d")
2043         (plus:HI (match_operand:HI 1 "general_operand" "%0")
2044                  (match_operand:HI 2 "general_operand" "dmi")))]
2045   ""
2046   "*
2047 {
2048   check_label_emit ();
2049   if (REG_P (operands[2]))
2050     {
2051       mvs_check_page (0, 8, 0);
2052       return \"STH      %2,140(,13)\;AH %0,140(,13)\";
2053     }
2054   if (GET_CODE (operands[2]) == CONST_INT)
2055     {
2056       if (INTVAL (operands[2]) == -1)
2057         {
2058           CC_STATUS_INIT;  /* add assumes CC but BCTR doesn't set CC */
2059           mvs_check_page (0, 2, 0);
2060           return \"BCTR %0,0\";
2061         }
2062       mvs_check_page (0, 4, 0);
2063       return \"AH       %0,%H2\";
2064     }
2065   mvs_check_page (0, 4, 0);
2066   return \"AH   %0,%2\";
2067 }"
2068    [(set_attr "length" "8")]
2069 )
2070
2071 ;
2072 ; addqi3 instruction pattern(s).
2073 ;
2074
2075 (define_insn "addqi3"
2076   [(set (match_operand:QI 0 "general_operand" "=d")
2077         (plus:QI (match_operand:QI 1 "general_operand" "%a")
2078                  (match_operand:QI 2 "general_operand" "ai")))]
2079   ""
2080   "*
2081 {
2082   check_label_emit ();
2083   CC_STATUS_INIT;  /* add assumes CC but LA doesn't set CC */
2084   mvs_check_page (0, 4, 0);
2085   if (REG_P (operands[2]))
2086     return \"LA %0,0(%1,%2)\";
2087   return \"LA   %0,%B2(,%1)\";
2088 }"
2089    [(set_attr "length" "4")]
2090 )
2091
2092 ;
2093 ; adddf3 instruction pattern(s).
2094 ;
2095
2096 (define_insn "adddf3"
2097   [(set (match_operand:DF 0 "general_operand" "=f")
2098         (plus:DF (match_operand:DF 1 "general_operand" "%0")
2099                  (match_operand:DF 2 "general_operand" "fmF")))]
2100   ""
2101   "*
2102 {
2103   check_label_emit ();
2104   if (FP_REG_P (operands[2]))
2105     {
2106       mvs_check_page (0, 2, 0);
2107       return \"ADR      %0,%2\";
2108     }
2109   mvs_check_page (0, 4, 0);
2110   return \"AD   %0,%2\";
2111 }"
2112    [(set_attr "length" "4")]
2113 )
2114
2115 ;
2116 ; addsf3 instruction pattern(s).
2117 ;
2118
2119 (define_insn "addsf3"
2120   [(set (match_operand:SF 0 "general_operand" "=f")
2121         (plus:SF (match_operand:SF 1 "general_operand" "%0")
2122                  (match_operand:SF 2 "general_operand" "fmF")))]
2123   ""
2124   "*
2125 {
2126   check_label_emit ();
2127   if (FP_REG_P (operands[2]))
2128     {
2129       mvs_check_page (0, 2, 0);
2130       return \"AER      %0,%2\";
2131     }
2132   mvs_check_page (0, 4, 0);
2133   return \"AE   %0,%2\";
2134 }"
2135    [(set_attr "length" "4")]
2136 )
2137
2138 ;;
2139 ;;- Subtract instructions.
2140 ;;
2141
2142 ;
2143 ; subdi3 instruction pattern(s).
2144 ;
2145 ;
2146 ;(define_expand "subdi3"
2147 ;  [(set (match_operand:DI 0 "general_operand" "")
2148 ;       (minus:DI (match_operand:DI 1 "general_operand" "")
2149 ;                 (match_operand:DI 2 "general_operand" "")))]
2150 ;  ""
2151 ;  "
2152 ;{
2153 ;  rtx label = gen_label_rtx ();
2154 ;  rtx op0_high = operand_subword (operands[0], 0, 1, DImode);
2155 ;  rtx op0_low = gen_lowpart (SImode, operands[0]);
2156 ;       
2157 ;  emit_insn (gen_rtx_SET (VOIDmode, op0_high,
2158 ;                   gen_rtx_MINUS (SImode,
2159 ;                             operand_subword (operands[1], 0, 1, DImode),
2160 ;                             operand_subword (operands[2], 0, 1, DImode))));
2161 ;  emit_jump_insn (gen_rtx_PARALLEL (VOIDmode, gen_rtvec (2,
2162 ;                   gen_rtx_SET (VOIDmode, op0_low,
2163 ;                             gen_rtx_MINUS (SImode,
2164 ;                                     gen_lowpart (SImode, operands[1]),
2165 ;                                     gen_lowpart (SImode, operands[2]))),
2166 ;                   gen_rtx_USE (VOIDmode,
2167 ;                             gen_rtx_LABEL_REF (VOIDmode, label)))));
2168 ;  emit_insn (gen_rtx_SET (VOIDmode, op0_high,
2169 ;                     gen_rtx_MINUS (SImode, op0_high,
2170 ;                             gen_rtx_CONST_INT (SImode, 1))));
2171 ;  emit_label (label);
2172 ;  DONE;
2173 ;}")
2174
2175 (define_insn ""
2176   [(set (match_operand:SI 0 "general_operand" "=d")
2177         (minus:SI (match_operand:SI 1 "general_operand" "0")
2178                   (match_operand:SI 2 "general_operand" "g")))
2179    (use (label_ref (match_operand 3 "" "")))
2180 ;   (clobber (reg:SI 14))
2181    ]
2182   ""
2183   "*
2184 {
2185   int onpage;
2186
2187   check_label_emit ();
2188   CC_STATUS_INIT;
2189   onpage = mvs_check_label (CODE_LABEL_NUMBER (operands[3]));
2190   if (REG_P (operands[2]))
2191     {
2192       if (!onpage)
2193         {
2194           mvs_check_page (0, 8, 4);
2195           return \"SLR  %0,%2\;L        14,=A(%l3)\;BCR 12,14\";
2196         }
2197       if (mvs_check_page (0, 6, 0))
2198         {
2199           mvs_check_page (0, 2, 4);
2200           return \"SLR  %0,%2\;L        14,=A(%l3)\;BCR 12,14\";
2201         }
2202       return \"SLR      %0,%2\;BC       12,%l3\";
2203     }
2204   if (!onpage)
2205     {
2206       mvs_check_page (0, 10, 4);
2207       return \"SL       %0,%2\;L        14,=A(%l3)\;BCR 12,14\";
2208     }
2209   if (mvs_check_page (0, 8, 0))
2210     {
2211       mvs_check_page (0, 2, 4);
2212       return \"SL       %0,%2\;L        14,=A(%l3)\;BCR 12,14\";
2213     }
2214   return \"SL   %0,%2\;BC       12,%l3\";
2215 }"
2216    [(set_attr "length" "10")]
2217 )
2218
2219 ;
2220 ; subsi3 instruction pattern(s).
2221 ;
2222
2223 (define_insn "subsi3"
2224   [(set (match_operand:SI 0 "general_operand" "=d")
2225         (minus:SI (match_operand:SI 1 "general_operand" "0")
2226                   (match_operand:SI 2 "general_operand" "g")))]
2227   ""
2228   "*
2229 {
2230   check_label_emit ();
2231   if (REG_P (operands[2]))
2232     {
2233       mvs_check_page (0, 2, 0);
2234       return \"SR       %0,%2\";
2235     }
2236   if (operands[2] == const1_rtx)
2237     {
2238       CC_STATUS_INIT;  /* subtract assumes CC but BCTR doesn't set CC */
2239       mvs_check_page (0, 2, 0);
2240       return \"BCTR     %0,0\";
2241     }
2242   mvs_check_page (0, 4, 0);
2243   return \"S    %0,%2\";
2244 }"
2245    [(set_attr "length" "4")]
2246 )
2247
2248 ;
2249 ; subhi3 instruction pattern(s).
2250 ;
2251
2252 (define_insn "subhi3"
2253   [(set (match_operand:HI 0 "general_operand" "=d")
2254         (minus:HI (match_operand:HI 1 "general_operand" "0")
2255                   (match_operand:HI 2 "general_operand" "g")))]
2256   ""
2257   "*
2258 {
2259   check_label_emit ();
2260   if (REG_P (operands[2]))
2261     {
2262       mvs_check_page (0, 8, 0);
2263       return \"STH      %2,140(,13)\;SH %0,140(,13)\";
2264     }
2265   if (operands[2] == const1_rtx)
2266     {
2267       CC_STATUS_INIT;  /* subtract assumes CC but BCTR doesn't set CC */
2268       mvs_check_page (0, 2, 0);
2269       return \"BCTR     %0,0\";
2270     }
2271   if (GET_CODE (operands[2]) == CONST_INT)
2272     {
2273       mvs_check_page (0, 4, 0);
2274       return \"SH       %0,%H2\";
2275     }
2276   mvs_check_page (0, 4, 0);
2277   return \"SH   %0,%2\";
2278 }"
2279    [(set_attr "length" "8")]
2280 )
2281
2282 ;
2283 ; subqi3 instruction pattern(s).
2284 ;
2285
2286 (define_expand "subqi3"
2287   [(set (match_operand:QI 0 "general_operand" "=d")
2288         (minus:QI (match_operand:QI 1 "general_operand" "0")
2289                   (match_operand:QI 2 "general_operand" "di")))]
2290   ""
2291   "
2292 {
2293   if (REG_P (operands[2]))
2294     {
2295       emit_insn (gen_rtx_SET (VOIDmode, operands[0],
2296                         gen_rtx_MINUS (QImode, operands[1], operands[2])));
2297     }
2298   else
2299     {
2300       emit_insn (gen_rtx_SET (VOIDmode, operands[0],
2301                         gen_rtx_PLUS (QImode, operands[1],
2302                                  negate_rtx (QImode, operands[2]))));
2303     }
2304   DONE;
2305 }")
2306
2307 (define_insn ""
2308   [(set (match_operand:QI 0 "register_operand" "=d")
2309         (minus:QI (match_operand:QI 1 "register_operand" "0")
2310                  (match_operand:QI 2 "register_operand" "d")))]
2311   ""
2312   "*
2313 {
2314   check_label_emit ();
2315   mvs_check_page (0, 2, 0);
2316   return \"SR   %0,%2\";
2317 }"
2318    [(set_attr "length" "2")]
2319 )
2320
2321 ;
2322 ; subdf3 instruction pattern(s).
2323 ;
2324
2325 (define_insn "subdf3"
2326   [(set (match_operand:DF 0 "general_operand" "=f")
2327         (minus:DF (match_operand:DF 1 "general_operand" "0")
2328                   (match_operand:DF 2 "general_operand" "fmF")))]
2329   ""
2330   "*
2331 {
2332   check_label_emit ();
2333   if (FP_REG_P (operands[2]))
2334     {
2335       mvs_check_page (0, 2, 0);
2336       return \"SDR      %0,%2\";
2337     }
2338   mvs_check_page (0, 4, 0);
2339   return \"SD   %0,%2\";
2340 }"
2341    [(set_attr "length" "4")]
2342 )
2343
2344 ;
2345 ; subsf3 instruction pattern(s).
2346 ;
2347
2348 (define_insn "subsf3"
2349   [(set (match_operand:SF 0 "general_operand" "=f")
2350         (minus:SF (match_operand:SF 1 "general_operand" "0")
2351                   (match_operand:SF 2 "general_operand" "fmF")))]
2352   ""
2353   "*
2354 {
2355   check_label_emit ();
2356   if (FP_REG_P (operands[2]))
2357     {
2358       mvs_check_page (0, 2, 0);
2359       return \"SER      %0,%2\";
2360     }
2361   mvs_check_page (0, 4, 0);
2362   return \"SE   %0,%2\";
2363 }"
2364    [(set_attr "length" "4")]
2365 )
2366
2367 ;;
2368 ;;- Multiply instructions.
2369 ;;
2370
2371 ;
2372 ; mulsi3 instruction pattern(s).
2373 ;
2374
2375 (define_expand "mulsi3"
2376   [(set (match_operand:SI 0 "general_operand" "")
2377         (mult:SI (match_operand:SI 1 "general_operand" "")
2378                  (match_operand:SI 2 "general_operand" "")))]
2379   ""
2380   "
2381 {
2382   if (GET_CODE (operands[1]) == CONST_INT
2383       && CONST_OK_FOR_LETTER_P (INTVAL (operands[1]), 'K'))
2384     {
2385       emit_insn (gen_rtx_SET (VOIDmode, operands[0],
2386                           gen_rtx_MULT (SImode, operands[2], operands[1])));
2387     }
2388   else if (GET_CODE (operands[2]) == CONST_INT
2389            && CONST_OK_FOR_LETTER_P (INTVAL (operands[2]), 'K'))
2390     {
2391       emit_insn (gen_rtx_SET (VOIDmode, operands[0],
2392                           gen_rtx_MULT (SImode, operands[1], operands[2])));
2393     }
2394   else
2395     {
2396       rtx r = gen_reg_rtx (DImode);
2397
2398       /* XXX trouble.  Below we generate some rtx's that model what
2399        * is really supposed to happen with multiply on the 370/390
2400        * hardware, and that is all well & good.  However, during optimization
2401        * it can happen that the two operands are exchanged (after all, 
2402        * multiplication is commutitive), in which case the doubleword
2403        * ends up in memory and everything is hosed.  The gen_reg_rtx
2404        * should have kept it in a reg ...  We hack around this
2405        * below, in the M/MR isntruction pattern, and constrain it to
2406        * \"di\" instead of \"g\".  But this still ends up with lots & lots of
2407        * movement between registers & memory and is an awful waste.
2408        * Dunno how to untwist it elegantly; but it seems to work for now.
2409        */
2410       emit_insn (gen_rtx_SET (VOIDmode,
2411                           gen_rtx_SUBREG (SImode, r, GET_MODE_SIZE (SImode)),
2412                                           operands[1]));
2413       emit_insn (gen_rtx_SET (VOIDmode, r,
2414                           gen_rtx_MULT (DImode, r, operands[2])));
2415       emit_insn (gen_rtx_SET (VOIDmode, operands[0],
2416                           gen_rtx_SUBREG (SImode, r, GET_MODE_SIZE (SImode))));
2417     }
2418   DONE;
2419 }")
2420
2421 (define_insn ""
2422   [(set (match_operand:SI 0 "general_operand" "=d")
2423         (mult:SI (match_operand:SI 1 "general_operand" "%0")
2424                  (match_operand:SI 2 "immediate_operand" "K")))]
2425   ""
2426   "*
2427 {
2428   check_label_emit ();
2429   mvs_check_page (0, 4, 0);
2430   return \"MH   %0,%H2\";
2431 }"
2432    [(set_attr "length" "4")]
2433 )
2434
2435 (define_insn ""
2436   [(set (match_operand:DI 0 "register_operand" "=d")
2437         (mult:DI (match_operand:DI 1 "general_operand" "%0")
2438                  (match_operand:SI 2 "general_operand" "di")))]
2439   ""
2440   "*
2441 {
2442   check_label_emit ();
2443   if (REG_P (operands[2]))
2444     {
2445       mvs_check_page (0, 2, 0);
2446       return \"MR       %0,%2\";
2447     }
2448   mvs_check_page (0, 4, 0);
2449   return \"M    %0,%2\";
2450 }"
2451    [(set_attr "length" "4")]
2452 )
2453
2454 ;
2455 ; muldf3 instruction pattern(s).
2456 ;
2457
2458 (define_insn "muldf3"
2459   [(set (match_operand:DF 0 "general_operand" "=f")
2460         (mult:DF (match_operand:DF 1 "general_operand" "%0")
2461                  (match_operand:DF 2 "general_operand" "fmF")))]
2462   ""
2463   "*
2464 {
2465   check_label_emit ();
2466   if (FP_REG_P (operands[2]))
2467     {
2468       mvs_check_page (0, 2, 0);
2469       return \"MDR      %0,%2\";
2470     }
2471   mvs_check_page (0, 4, 0);
2472   return \"MD   %0,%2\";
2473 }"
2474    [(set_attr "length" "4")]
2475 )
2476
2477 ;
2478 ; mulsf3 instruction pattern(s).
2479 ;
2480
2481 (define_insn "mulsf3"
2482   [(set (match_operand:SF 0 "general_operand" "=f")
2483         (mult:SF (match_operand:SF 1 "general_operand" "%0")
2484                  (match_operand:SF 2 "general_operand" "fmF")))]
2485   ""
2486   "*
2487 {
2488   check_label_emit ();
2489   if (FP_REG_P (operands[2]))
2490     {
2491       mvs_check_page (0, 2, 0);
2492       return \"MER      %0,%2\";
2493     }
2494   mvs_check_page (0, 4, 0);
2495   return \"ME   %0,%2\";
2496 }"
2497    [(set_attr "length" "4")]
2498 )
2499
2500 ;;
2501 ;;- Divide instructions.
2502 ;;
2503
2504 ;
2505 ; divsi3 instruction pattern(s).
2506 ;
2507
2508 (define_expand "divsi3"
2509   [(set (match_operand:SI 0 "general_operand" "")
2510         (div:SI (match_operand:SI 1 "general_operand" "")
2511                 (match_operand:SI 2 "general_operand" "")))]
2512   ""
2513   "
2514 {
2515   rtx r = gen_reg_rtx (DImode);
2516
2517   emit_insn (gen_extendsidi2 (r, operands[1]));
2518   emit_insn (gen_rtx_SET (VOIDmode, r,
2519                         gen_rtx_DIV (DImode, r, operands[2])));
2520   emit_insn (gen_rtx_SET (VOIDmode, operands[0],
2521                         gen_rtx_SUBREG (SImode, r, GET_MODE_SIZE (SImode))));
2522   DONE;
2523 }")
2524
2525
2526 ;
2527 ; udivsi3 instruction pattern(s).
2528 ;
2529
2530 (define_expand "udivsi3"
2531   [(set (match_operand:SI 0 "general_operand" "")
2532         (udiv:SI (match_operand:SI 1 "general_operand" "")
2533                  (match_operand:SI 2 "general_operand" "")))]
2534   ""
2535   "
2536 {
2537   rtx dr = gen_reg_rtx (DImode);
2538   rtx dr_0 = gen_rtx_SUBREG (SImode, dr, 0);
2539   rtx dr_1 = gen_rtx_SUBREG (SImode, dr, GET_MODE_SIZE (SImode));
2540
2541
2542   if (GET_CODE (operands[2]) == CONST_INT)
2543     {
2544       if (INTVAL (operands[2]) > 0)
2545         {
2546           emit_insn (gen_zero_extendsidi2 (dr, operands[1]));
2547           emit_insn (gen_rtx_SET (VOIDmode, dr,
2548                         gen_rtx_DIV (DImode, dr, operands[2])));
2549         }
2550       else
2551         {
2552           rtx label1 = gen_label_rtx ();
2553
2554           emit_insn (gen_rtx_SET (VOIDmode, dr_0, operands[1]));
2555           emit_insn (gen_rtx_SET (VOIDmode, dr_1, const0_rtx));
2556           emit_insn (gen_cmpsi (dr_0, operands[2]));
2557           emit_jump_insn (gen_bltu (label1));
2558           emit_insn (gen_rtx_SET (VOIDmode, dr_1, const1_rtx));
2559           emit_label (label1);
2560         }
2561     }
2562   else
2563     {
2564       rtx label1 = gen_label_rtx ();
2565       rtx label2 = gen_label_rtx ();
2566       rtx label3 = gen_label_rtx ();
2567       rtx sr = gen_reg_rtx (SImode);
2568
2569       emit_insn (gen_rtx_SET (VOIDmode, dr_0, operands[1]));
2570       emit_insn (gen_rtx_SET (VOIDmode, sr, operands[2]));
2571       emit_insn (gen_rtx_SET (VOIDmode, dr_1, const0_rtx));
2572       emit_insn (gen_cmpsi (sr, dr_0));
2573       emit_jump_insn (gen_bgtu (label3));
2574       emit_insn (gen_cmpsi (sr, const1_rtx));
2575       emit_jump_insn (gen_blt (label2));
2576       emit_insn (gen_cmpsi (sr, const1_rtx));
2577       emit_jump_insn (gen_beq (label1));
2578       emit_insn (gen_rtx_SET (VOIDmode, dr,
2579                           gen_rtx_LSHIFTRT (DImode, dr,
2580                                     gen_rtx_CONST_INT (SImode, 32))));
2581       emit_insn (gen_rtx_SET (VOIDmode, dr,
2582                     gen_rtx_DIV (DImode, dr, sr)));
2583       emit_jump_insn (gen_jump (label3));
2584       emit_label (label1);
2585       emit_insn (gen_rtx_SET (VOIDmode, dr_1, dr_0));
2586       emit_jump_insn (gen_jump (label3));
2587       emit_label (label2);
2588       emit_insn (gen_rtx_SET (VOIDmode, dr_1, const1_rtx));
2589       emit_label (label3);
2590     }
2591   emit_insn (gen_rtx_SET (VOIDmode, operands[0], dr_1));
2592
2593   DONE;
2594 }")
2595
2596 ; This is used by divsi3 & udivsi3.
2597
2598 (define_insn ""
2599   [(set (match_operand:DI 0 "register_operand" "=d")
2600         (div:DI (match_operand:DI 1 "register_operand" "0")
2601                 (match_operand:SI 2 "general_operand" "dm")))]
2602   ""
2603   "*
2604 {
2605   check_label_emit ();
2606   if (REG_P (operands[2]))
2607     {
2608       mvs_check_page (0, 2, 0);
2609       return \"DR       %0,%2\";
2610     }
2611   mvs_check_page (0, 4, 0);
2612   return \"D    %0,%2\";
2613 }"
2614    [(set_attr "length" "4")]
2615 )
2616
2617 ;
2618 ; divdf3 instruction pattern(s).
2619 ;
2620
2621 (define_insn "divdf3"
2622   [(set (match_operand:DF 0 "general_operand" "=f")
2623         (div:DF (match_operand:DF 1 "general_operand" "0")
2624                 (match_operand:DF 2 "general_operand" "fmF")))]
2625   ""
2626   "*
2627 {
2628   check_label_emit ();
2629   if (FP_REG_P (operands[2]))
2630     {
2631       mvs_check_page (0, 2, 0);
2632       return \"DDR      %0,%2\";
2633     }
2634   mvs_check_page (0, 4, 0);
2635   return \"DD   %0,%2\";
2636 }"
2637    [(set_attr "length" "4")]
2638 )
2639
2640 ;
2641 ; divsf3 instruction pattern(s).
2642 ;
2643
2644 (define_insn "divsf3"
2645   [(set (match_operand:SF 0 "general_operand" "=f")
2646         (div:SF (match_operand:SF 1 "general_operand" "0")
2647                 (match_operand:SF 2 "general_operand" "fmF")))]
2648   ""
2649   "*
2650 {
2651   check_label_emit ();
2652   if (FP_REG_P (operands[2]))
2653     {
2654       mvs_check_page (0, 2, 0);
2655       return \"DER      %0,%2\";
2656     }
2657   mvs_check_page (0, 4, 0);
2658   return \"DE   %0,%2\";
2659 }"
2660    [(set_attr "length" "4")]
2661 )
2662
2663 ;;
2664 ;;- Modulo instructions.
2665 ;;
2666
2667 ;
2668 ; modsi3 instruction pattern(s).
2669 ;
2670
2671 (define_expand "modsi3"
2672   [(set (match_operand:SI 0 "general_operand" "")
2673         (mod:SI (match_operand:SI 1 "general_operand" "")
2674                 (match_operand:SI 2 "general_operand" "")))]
2675   ""
2676   "
2677 {
2678   rtx r = gen_reg_rtx (DImode);
2679
2680   emit_insn (gen_extendsidi2 (r, operands[1]));
2681   emit_insn (gen_rtx_SET (VOIDmode, r,
2682                         gen_rtx_MOD (DImode, r, operands[2])));
2683   emit_insn (gen_rtx_SET (VOIDmode, operands[0],
2684                         gen_rtx_SUBREG (SImode, r, 0)));
2685   DONE;
2686 }")
2687
2688 ;
2689 ; umodsi3 instruction pattern(s).
2690 ;
2691
2692 (define_expand "umodsi3"
2693   [(set (match_operand:SI 0 "general_operand" "")
2694         (umod:SI (match_operand:SI 1 "general_operand" "")
2695                  (match_operand:SI 2 "general_operand" "")))]
2696   ""
2697   "
2698 {
2699   rtx dr = gen_reg_rtx (DImode);
2700   rtx dr_0 = gen_rtx_SUBREG (SImode, dr, 0);
2701
2702   emit_insn (gen_rtx_SET (VOIDmode, dr_0, operands[1]));
2703
2704   if (GET_CODE (operands[2]) == CONST_INT)
2705     {
2706       if (INTVAL (operands[2]) > 0)
2707         {
2708           emit_insn (gen_rtx_SET (VOIDmode, dr,
2709                               gen_rtx_LSHIFTRT (DImode, dr,
2710                                         gen_rtx_CONST_INT (SImode, 32))));
2711           emit_insn (gen_rtx_SET (VOIDmode, dr,
2712                         gen_rtx_MOD (DImode, dr, operands[2])));
2713         }
2714       else
2715         {
2716           rtx label1 = gen_label_rtx ();
2717           rtx sr = gen_reg_rtx (SImode);
2718
2719           emit_insn (gen_rtx_SET (VOIDmode, sr, operands[2]));
2720           emit_insn (gen_cmpsi (dr_0, sr));
2721           emit_jump_insn (gen_bltu (label1));
2722           emit_insn (gen_rtx_SET (VOIDmode, sr, gen_rtx_ABS (SImode, sr)));
2723           emit_insn (gen_rtx_SET (VOIDmode, dr_0,
2724                               gen_rtx_PLUS (SImode, dr_0, sr)));
2725           emit_label (label1);
2726         }
2727     }
2728   else
2729     {
2730       rtx label1 = gen_label_rtx ();
2731       rtx label2 = gen_label_rtx ();
2732       rtx label3 = gen_label_rtx ();
2733       rtx sr = gen_reg_rtx (SImode);
2734
2735       emit_insn (gen_rtx_SET (VOIDmode, dr_0, operands[1]));
2736       emit_insn (gen_rtx_SET (VOIDmode, sr, operands[2]));
2737       emit_insn (gen_cmpsi (sr, dr_0));
2738       emit_jump_insn (gen_bgtu (label3));
2739       emit_insn (gen_cmpsi (sr, const1_rtx));
2740       emit_jump_insn (gen_blt (label2));
2741       emit_jump_insn (gen_beq (label1));
2742       emit_insn (gen_rtx_SET (VOIDmode, dr,
2743                           gen_rtx_LSHIFTRT (DImode, dr,
2744                                     gen_rtx_CONST_INT (SImode, 32))));
2745       emit_insn (gen_rtx_SET (VOIDmode, dr, gen_rtx_MOD (DImode, dr, sr)));
2746       emit_jump_insn (gen_jump (label3));
2747       emit_label (label1);
2748       emit_insn (gen_rtx_SET (VOIDmode, dr_0, const0_rtx));
2749       emit_jump_insn (gen_jump (label3));
2750       emit_label (label2);
2751       emit_insn (gen_rtx_SET (VOIDmode, dr_0,
2752                           gen_rtx_MINUS (SImode, dr_0, sr)));
2753       emit_label (label3);
2754
2755     }
2756   emit_insn (gen_rtx_SET (VOIDmode, operands[0], dr_0));
2757
2758   DONE;
2759 }")
2760
2761 ; This is used by modsi3 & umodsi3.
2762
2763 (define_insn ""
2764   [(set (match_operand:DI 0 "register_operand" "=d")
2765         (mod:DI (match_operand:DI 1 "register_operand" "0")
2766                 (match_operand:SI 2 "general_operand" "dm")))]
2767   ""
2768   "*
2769 {
2770   check_label_emit ();
2771   if (REG_P (operands[2]))
2772     {
2773       mvs_check_page (0, 2, 0);
2774       return \"DR       %0,%2\";
2775     }
2776   mvs_check_page (0, 4, 0);
2777   return \"D    %0,%2\";
2778 }"
2779    [(set_attr "length" "4")]
2780 )
2781
2782 ;;
2783 ;;- And instructions.
2784 ;;
2785
2786 ;
2787 ; anddi3 instruction pattern(s).
2788 ;
2789
2790 ;(define_expand "anddi3"
2791 ;  [(set (match_operand:DI 0 "general_operand" "")
2792 ;       (and:DI (match_operand:DI 1 "general_operand" "")
2793 ;               (match_operand:DI 2 "general_operand" "")))]
2794 ;  ""
2795 ;  "
2796 ;{
2797 ;  rtx gen_andsi3();
2798 ;
2799 ;  emit_insn (gen_andsi3 (operand_subword (operands[0], 0, 1, DImode),
2800 ;                        operand_subword (operands[1], 0, 1, DImode),
2801 ;                        operand_subword (operands[2], 0, 1, DImode)));
2802 ;  emit_insn (gen_andsi3 (gen_lowpart (SImode, operands[0]),
2803 ;                        gen_lowpart (SImode, operands[1]),
2804 ;                        gen_lowpart (SImode, operands[2])));
2805 ;  DONE;
2806 ;}")
2807
2808 ;
2809 ; andsi3 instruction pattern(s).
2810 ;
2811
2812 (define_insn ""
2813   [(set (match_operand:SI 0 "r_or_s_operand" "=d,m")
2814         (and:SI (match_operand:SI 1 "r_or_s_operand" "%0,0")
2815                 (match_operand:SI 2 "r_or_s_operand" "g,mi")))]
2816   "TARGET_CHAR_INSTRUCTIONS"
2817   "*
2818 {
2819   check_label_emit ();
2820   CC_STATUS_INIT;  /* and sets CC but not how we want it */
2821   if (REG_P (operands[2]))
2822     {
2823       mvs_check_page (0, 2, 0);
2824       return \"NR       %0,%2\";
2825     }
2826   if (REG_P (operands[0]))
2827     {
2828       mvs_check_page (0, 4, 0);
2829       return \"N        %0,%2\";
2830     }
2831   mvs_check_page (0, 6, 0);
2832   return \"NC   %O0(4,%R0),%2\";
2833 }"
2834    [(set_attr "length" "6")]
2835 )
2836
2837 (define_insn "andsi3"
2838   [(set (match_operand:SI 0 "general_operand" "=d")
2839         (and:SI (match_operand:SI 1 "general_operand" "%0")
2840                 (match_operand:SI 2 "general_operand" "g")))]
2841   ""
2842   "*
2843 {
2844   check_label_emit ();
2845   CC_STATUS_INIT;  /* and sets CC but not how we want it */
2846   if (REG_P (operands[2]))
2847     {
2848       mvs_check_page (0, 2, 0);
2849       return \"NR       %0,%2\";
2850     }
2851   mvs_check_page (0, 4, 0);
2852   return \"N    %0,%2\";
2853 }"
2854    [(set_attr "length" "4")]
2855 )
2856
2857 ;
2858 ; andhi3 instruction pattern(s).
2859 ;
2860
2861 (define_insn ""
2862   [(set (match_operand:HI 0 "r_or_s_operand" "=d,m")
2863         (and:HI (match_operand:HI 1 "r_or_s_operand" "%0,0")
2864                 (match_operand:HI 2 "r_or_s_operand" "di,mi")))]
2865   "TARGET_CHAR_INSTRUCTIONS"
2866   "*
2867 {
2868   check_label_emit ();
2869   CC_STATUS_INIT;  /* and sets CC but not how we want it */
2870   if (REG_P (operands[2]))
2871     {
2872       mvs_check_page (0, 2, 0);
2873       return \"NR       %0,%2\";
2874     }
2875   if (REG_P (operands[0]))
2876     {
2877       /* %K2 == sign extend operand to 32 bits so that CH works */
2878       mvs_check_page (0, 4, 0);
2879       if (GET_CODE (operands[2]) == CONST_INT)
2880          return \"N     %0,%K2\";
2881       return \"N        %0,%2\";
2882     }
2883   if (GET_CODE (operands[2]) == CONST_INT)
2884     {
2885       mvs_check_page (0, 6, 0);
2886       return \"NC       %O0(2,%R0),%H2\";
2887     }
2888   mvs_check_page (0, 6, 0);
2889   return \"NC   %O0(2,%R0),%2\";
2890 }"
2891    [(set_attr "length" "6")]
2892 )
2893
2894 (define_insn "andhi3"
2895   [(set (match_operand:HI 0 "general_operand" "=d")
2896         (and:HI (match_operand:HI 1 "general_operand" "%0")
2897                 (match_operand:HI 2 "general_operand" "di")))]
2898   ""
2899   "*
2900 {
2901   check_label_emit ();
2902   CC_STATUS_INIT;  /* and sets CC but not how we want it */
2903   if (GET_CODE (operands[2]) == CONST_INT)
2904     {
2905       /* %K2 == sign extend operand to 32 bits so that CH works */
2906       mvs_check_page (0, 4, 0);
2907       return \"N        %0,%K2\";
2908     }
2909   mvs_check_page (0, 2, 0);
2910   return \"NR   %0,%2\";
2911 }"
2912    [(set_attr "length" "4")]
2913 )
2914
2915 ;
2916 ; andqi3 instruction pattern(s).
2917 ;
2918
2919 (define_insn ""
2920   [(set (match_operand:QI 0 "r_or_s_operand" "=d,m")
2921         (and:QI (match_operand:QI 1 "r_or_s_operand" "%0,0")
2922                 (match_operand:QI 2 "r_or_s_operand" "di,mi")))]
2923   "TARGET_CHAR_INSTRUCTIONS"
2924   "*
2925 {
2926   check_label_emit ();
2927   CC_STATUS_INIT;  /* and sets CC but not how we want it */
2928   if (REG_P (operands[2]))
2929     {
2930       mvs_check_page (0, 2, 0);
2931       return \"NR       %0,%2\";
2932     }
2933   if (REG_P (operands[0]))
2934     {
2935       mvs_check_page (0, 4, 0);
2936       return \"N        %0,%2\";
2937     }
2938   if (GET_CODE (operands[2]) == CONST_INT)
2939     {
2940       mvs_check_page (0, 4, 0);
2941       return \"NI       %0,%B2\";
2942     }
2943   mvs_check_page (0, 6, 0);
2944   return \"NC   %O0(1,%R0),%2\";
2945 }"
2946    [(set_attr "length" "6")]
2947 )
2948
2949 (define_insn "andqi3"
2950   [(set (match_operand:QI 0 "general_operand" "=d")
2951         (and:QI (match_operand:QI 1 "general_operand" "%0")
2952                 (match_operand:QI 2 "general_operand" "di")))]
2953   ""
2954   "*
2955 {
2956   check_label_emit ();
2957   CC_STATUS_INIT;  /* and sets CC but not how we want it */
2958   if (GET_CODE (operands[2]) == CONST_INT)
2959     {
2960       mvs_check_page (0, 4, 0);
2961       return \"N        %0,%2\";
2962     }
2963   mvs_check_page (0, 2, 0);
2964   return \"NR   %0,%2\";
2965 }"
2966    [(set_attr "length" "4")]
2967 )
2968
2969 ;;
2970 ;;- Bit set (inclusive or) instructions.
2971 ;;
2972
2973 ;
2974 ; iordi3 instruction pattern(s).
2975 ;
2976
2977 ;(define_expand "iordi3"
2978 ;  [(set (match_operand:DI 0 "general_operand" "")
2979 ;       (ior:DI (match_operand:DI 1 "general_operand" "")
2980 ;               (match_operand:DI 2 "general_operand" "")))]
2981 ;  ""
2982 ;  "
2983 ;{
2984 ;  rtx gen_iorsi3();
2985 ;
2986 ;  emit_insn (gen_iorsi3 (operand_subword (operands[0], 0, 1, DImode),
2987 ;                        operand_subword (operands[1], 0, 1, DImode),
2988 ;                        operand_subword (operands[2], 0, 1, DImode)));
2989 ;  emit_insn (gen_iorsi3 (gen_lowpart (SImode, operands[0]),
2990 ;                        gen_lowpart (SImode, operands[1]),
2991 ;                        gen_lowpart (SImode, operands[2])));
2992 ;  DONE;
2993 ;}")
2994
2995 ;
2996 ; iorsi3 instruction pattern(s).
2997 ;
2998
2999 (define_insn ""
3000   [(set (match_operand:SI 0 "r_or_s_operand" "=d,m")
3001         (ior:SI (match_operand:SI 1 "r_or_s_operand" "%0,0")
3002                 (match_operand:SI 2 "r_or_s_operand" "g,Si")))]
3003   "TARGET_CHAR_INSTRUCTIONS"
3004   "*
3005 {
3006   check_label_emit ();
3007   CC_STATUS_INIT;  /* OR sets CC but not how we want it */
3008   if (REG_P (operands[2]))
3009     {
3010       mvs_check_page (0, 2, 0);
3011       return \"OR       %0,%2\";
3012     }
3013   if (REG_P (operands[0]))
3014     {
3015       mvs_check_page (0, 4, 0);
3016       return \"O        %0,%2\";
3017     }
3018   mvs_check_page (0, 6, 0);
3019   return \"OC   %O0(4,%R0),%2\";
3020 }"
3021   [(set_attr "length" "6")]
3022 )
3023
3024 (define_insn "iorsi3"
3025   [(set (match_operand:SI 0 "general_operand" "=d")
3026         (ior:SI (match_operand:SI 1 "general_operand" "%0")
3027                 (match_operand:SI 2 "general_operand" "g")))]
3028   ""
3029   "*
3030 {
3031   check_label_emit ();
3032   CC_STATUS_INIT;  /* OR sets CC but not how we want it */
3033   if (REG_P (operands[2]))
3034     {
3035       mvs_check_page (0, 2, 0);
3036       return \"OR       %0,%2\";
3037     }
3038   mvs_check_page (0, 4, 0);
3039   return \"O    %0,%2\";
3040 }"
3041    [(set_attr "length" "4")]
3042 )
3043
3044 ;
3045 ; iorhi3 instruction pattern(s).
3046 ;
3047
3048 (define_insn ""
3049   [(set (match_operand:HI 0 "r_or_s_operand" "=d,m")
3050         (ior:HI (match_operand:HI 1 "r_or_s_operand" "%0,0")
3051                 (match_operand:HI 2 "r_or_s_operand" "di,mi")))]
3052   "TARGET_CHAR_INSTRUCTIONS"
3053   "*
3054 {
3055   check_label_emit ();
3056   CC_STATUS_INIT;  /* OR sets CC but not how we want it */
3057   if (REG_P (operands[2]))
3058     {
3059       mvs_check_page (0, 2, 0);
3060       return \"OR       %0,%2\";
3061     }
3062   if (REG_P (operands[0]))
3063     {
3064       mvs_check_page (0, 4, 0);
3065       return \"O        %0,%2\";
3066     }
3067   if (GET_CODE (operands[2]) == CONST_INT)
3068     {
3069       mvs_check_page (0, 6, 2);
3070       return \"OC       %O0(2,%R0),%H2\";
3071     }
3072   mvs_check_page (0, 6, 0);
3073   return \"OC   %O0(2,%R0),%2\";
3074 }"
3075    [(set_attr "length" "6")]
3076 )
3077
3078 (define_insn "iorhi3"
3079   [(set (match_operand:HI 0 "general_operand" "=d")
3080         (ior:HI (match_operand:HI 1 "general_operand" "%0")
3081                 (match_operand:HI 2 "general_operand" "di")))]
3082   ""
3083   "*
3084 {
3085   check_label_emit ();
3086   CC_STATUS_INIT;  /* OR sets CC but not how we want it */
3087   if (GET_CODE (operands[2]) == CONST_INT)
3088     {
3089       mvs_check_page (0, 4, 0);
3090       return \"O        %0,%2\";
3091     }
3092   mvs_check_page (0, 2, 0);
3093   return \"OR   %0,%2\";
3094 }"
3095    [(set_attr "length" "4")]
3096 )
3097
3098 ;
3099 ; iorqi3 instruction pattern(s).
3100 ;
3101
3102 (define_insn ""
3103   [(set (match_operand:QI 0 "r_or_s_operand" "=d,m")
3104         (ior:QI (match_operand:QI 1 "r_or_s_operand" "%0,0")
3105                 (match_operand:QI 2 "r_or_s_operand" "di,mi")))]
3106   "TARGET_CHAR_INSTRUCTIONS"
3107   "*
3108 {
3109   check_label_emit ();
3110   CC_STATUS_INIT;  /* OR sets CC but not how we want it */
3111   if (REG_P (operands[2]))
3112     {
3113       mvs_check_page (0, 2, 0);
3114       return \"OR       %0,%2\";
3115     }
3116   if (REG_P (operands[0]))
3117     {
3118       mvs_check_page (0, 4, 0);
3119       return \"O        %0,%2\";
3120     }
3121   if (GET_CODE (operands[2]) == CONST_INT)
3122     {
3123       mvs_check_page (0, 4, 0);
3124       return \"OI       %0,%B2\";
3125     }
3126   mvs_check_page (0, 6, 0);
3127   return \"OC   %O0(1,%R0),%2\";
3128 }"
3129    [(set_attr "length" "6")]
3130 )
3131
3132 (define_insn "iorqi3"
3133   [(set (match_operand:QI 0 "general_operand" "=d")
3134         (ior:QI (match_operand:QI 1 "general_operand" "%0")
3135                 (match_operand:QI 2 "general_operand" "di")))]
3136   ""
3137   "*
3138 {
3139   check_label_emit ();
3140   CC_STATUS_INIT;  /* OR sets CC but not how we want it */
3141   if (GET_CODE (operands[2]) == CONST_INT)
3142     {
3143       mvs_check_page (0, 4, 0);
3144       return \"O        %0,%2\";
3145     }
3146   mvs_check_page (0, 2, 0);
3147   return \"OR   %0,%2\";
3148 }"
3149    [(set_attr "length" "4")]
3150 )
3151
3152 ;;
3153 ;;- Xor instructions.
3154 ;;
3155
3156 ;
3157 ; xordi3 instruction pattern(s).
3158 ;
3159
3160 ;(define_expand "xordi3"
3161 ;  [(set (match_operand:DI 0 "general_operand" "")
3162 ;       (xor:DI (match_operand:DI 1 "general_operand" "")
3163 ;               (match_operand:DI 2 "general_operand" "")))]
3164 ;  ""
3165 ;  "
3166 ;{
3167 ;  rtx gen_xorsi3();
3168 ;
3169 ;  emit_insn (gen_xorsi3 (operand_subword (operands[0], 0, 1, DImode),
3170 ;                        operand_subword (operands[1], 0, 1, DImode),
3171 ;                        operand_subword (operands[2], 0, 1, DImode)));
3172 ;  emit_insn (gen_xorsi3 (gen_lowpart (SImode, operands[0]),
3173 ;                        gen_lowpart (SImode, operands[1]),
3174 ;                        gen_lowpart (SImode, operands[2])));
3175 ;  DONE;
3176 ;}")
3177
3178 ;
3179 ; xorsi3 instruction pattern(s).
3180 ;
3181
3182 (define_insn ""
3183   [(set (match_operand:SI 0 "r_or_s_operand" "=d,m")
3184         (xor:SI (match_operand:SI 1 "r_or_s_operand" "%0,0")
3185                 (match_operand:SI 2 "r_or_s_operand" "g,mi")))]
3186   "TARGET_CHAR_INSTRUCTIONS"
3187   "*
3188 {
3189   check_label_emit ();
3190   CC_STATUS_INIT;  /* XOR sets CC but not how we want it */
3191   if (REG_P (operands[2]))
3192     {
3193       mvs_check_page (0, 2, 0);
3194       return \"XR       %0,%2\";
3195     }
3196   if (REG_P (operands[0]))
3197     {
3198       mvs_check_page (0, 4, 0);
3199       return \"X        %0,%2\";
3200     }
3201   mvs_check_page (0, 6, 0);
3202   return \"XC   %O0(4,%R0),%2\";
3203 }"
3204    [(set_attr "length" "6")]
3205 )
3206
3207 (define_insn "xorsi3"
3208   [(set (match_operand:SI 0 "general_operand" "=d")
3209         (xor:SI (match_operand:SI 1 "general_operand" "%0")
3210                 (match_operand:SI 2 "general_operand" "g")))]
3211   ""
3212   "*
3213 {
3214   check_label_emit ();
3215   CC_STATUS_INIT;  /* XOR sets CC but not how we want it */
3216   if (REG_P (operands[2]))
3217     {
3218       mvs_check_page (0, 2, 0);
3219       return \"XR       %0,%2\";
3220     }
3221   mvs_check_page (0, 4, 0);
3222   return \"X    %0,%2\";
3223 }"
3224   [(set_attr "length" "4")]
3225 )
3226
3227 ;
3228 ; xorhi3 instruction pattern(s).
3229 ;
3230
3231 (define_insn ""
3232   [(set (match_operand:HI 0 "r_or_s_operand" "=d,m")
3233         (xor:HI (match_operand:HI 1 "r_or_s_operand" "%0,0")
3234                 (match_operand:HI 2 "r_or_s_operand" "di,mi")))]
3235   "TARGET_CHAR_INSTRUCTIONS"
3236   "*
3237 {
3238   check_label_emit ();
3239   CC_STATUS_INIT;  /* XOR sets CC but not how we want it */
3240   if (REG_P (operands[2]))
3241     {
3242       mvs_check_page (0, 2, 0);
3243       return \"XR       %0,%2\";
3244     }
3245   if (REG_P (operands[0]))
3246     {
3247       mvs_check_page (0, 4, 0);
3248       return \"X        %0,%H2\";
3249     }
3250   if (GET_CODE (operands[2]) == CONST_INT)
3251     {
3252       mvs_check_page (0, 6, 0);
3253       return \"XC       %O0(2,%R0),%H2\";
3254     }
3255   mvs_check_page (0, 6, 0);
3256   return \"XC   %O0(2,%R0),%2\";
3257 }"
3258   [(set_attr "length" "6")]
3259 )
3260
3261 (define_insn "xorhi3"
3262   [(set (match_operand:HI 0 "general_operand" "=d")
3263         (xor:HI (match_operand:HI 1 "general_operand" "%0")
3264                 (match_operand:HI 2 "general_operand" "di")))]
3265   ""
3266   "*
3267 {
3268   check_label_emit ();
3269   CC_STATUS_INIT;  /* XOR sets CC but not how we want it */
3270   if (GET_CODE (operands[2]) == CONST_INT)
3271     {
3272       mvs_check_page (0, 4, 0);
3273       return \"X        %0,%H2\";
3274     }
3275   mvs_check_page (0, 2, 0);
3276   return \"XR   %0,%2\";
3277 }"
3278   [(set_attr "length" "4")]
3279 )
3280
3281 ;
3282 ; xorqi3 instruction pattern(s).
3283 ;
3284
3285 (define_insn ""
3286   [(set (match_operand:QI 0 "r_or_s_operand" "=d,m")
3287         (xor:QI (match_operand:QI 1 "r_or_s_operand" "%0,0")
3288                 (match_operand:QI 2 "r_or_s_operand" "di,mi")))]
3289   "TARGET_CHAR_INSTRUCTIONS"
3290   "*
3291 {
3292   check_label_emit ();
3293   CC_STATUS_INIT;  /* XOR sets CC but not how we want it */
3294   if (REG_P (operands[2]))
3295     {
3296       mvs_check_page (0, 2, 0);
3297       return \"XR       %0,%2\";
3298     }
3299   if (REG_P (operands[0]))
3300     {
3301       mvs_check_page (0, 4, 0);
3302       return \"X        %0,%2\";
3303     }
3304   if (GET_CODE (operands[2]) == CONST_INT)
3305     {
3306       mvs_check_page (0, 4, 0);
3307       return \"XI       %0,%B2\";
3308     }
3309   mvs_check_page (0, 6, 0);
3310   return \"XC   %O0(1,%R0),%2\";
3311 }"
3312   [(set_attr "length" "6")]
3313 )
3314
3315 (define_insn "xorqi3"
3316   [(set (match_operand:QI 0 "general_operand" "=d")
3317         (xor:QI (match_operand:QI 1 "general_operand" "%0")
3318                 (match_operand:QI 2 "general_operand" "di")))]
3319   ""
3320   "*
3321 {
3322   check_label_emit ();
3323   CC_STATUS_INIT;  /* XOR sets CC but not how we want it */
3324   if (GET_CODE (operands[2]) == CONST_INT)
3325     {
3326       mvs_check_page (0, 4, 0);
3327       return \"X        %0,%2\";
3328     }
3329   mvs_check_page (0, 2, 0);
3330   return \"XR   %0,%2\";
3331 }"
3332   [(set_attr "length" "4")]
3333 )
3334
3335 ;;
3336 ;;- Negate instructions.
3337 ;;
3338
3339 ;
3340 ; negsi2 instruction pattern(s).
3341 ;
3342
3343 (define_insn "negsi2"
3344   [(set (match_operand:SI 0 "general_operand" "=d")
3345         (neg:SI (match_operand:SI 1 "general_operand" "d")))]
3346   ""
3347   "*
3348 {
3349   check_label_emit ();
3350   mvs_check_page (0, 2, 0);
3351   return \"LCR  %0,%1\";
3352 }"
3353   [(set_attr "length" "2")]
3354 )
3355
3356 ;
3357 ; neghi2 instruction pattern(s).
3358 ;
3359
3360 (define_insn "neghi2"
3361   [(set (match_operand:HI 0 "general_operand" "=d")
3362         (neg:HI (match_operand:HI 1 "general_operand" "d")))]
3363   ""
3364   "*
3365 {
3366   check_label_emit ();
3367   mvs_check_page (0, 10, 0);
3368   return \"SLL  %1,16\;SRA      %1,16\;LCR      %0,%1\";
3369 }"
3370   [(set_attr "length" "10")]
3371 )
3372
3373 ;
3374 ; negdf2 instruction pattern(s).
3375 ;
3376
3377 (define_insn "negdf2"
3378   [(set (match_operand:DF 0 "general_operand" "=f")
3379         (neg:DF (match_operand:DF 1 "general_operand" "f")))]
3380   ""
3381   "*
3382 {
3383   check_label_emit ();
3384   mvs_check_page (0, 2, 0);
3385   return \"LCDR %0,%1\";
3386 }"
3387   [(set_attr "length" "2")]
3388 )
3389
3390 ;
3391 ; negsf2 instruction pattern(s).
3392 ;
3393
3394 (define_insn "negsf2"
3395   [(set (match_operand:SF 0 "general_operand" "=f")
3396         (neg:SF (match_operand:SF 1 "general_operand" "f")))]
3397   ""
3398   "*
3399 {
3400   check_label_emit ();
3401   mvs_check_page (0, 2, 0);
3402   return \"LCER %0,%1\";
3403 }"
3404   [(set_attr "length" "2")]
3405 )
3406
3407 ;;
3408 ;;- Absolute value instructions.
3409 ;;
3410
3411 ;
3412 ; abssi2 instruction pattern(s).
3413 ;
3414
3415 (define_insn "abssi2"
3416   [(set (match_operand:SI 0 "general_operand" "=d")
3417         (abs:SI (match_operand:SI 1 "general_operand" "d")))]
3418   ""
3419   "*
3420 {
3421   check_label_emit ();
3422   mvs_check_page (0, 2, 0);
3423   return \"LPR  %0,%1\";
3424 }"
3425   [(set_attr "length" "2")]
3426 )
3427
3428 ;
3429 ; abshi2 instruction pattern(s).
3430 ;
3431
3432 (define_insn "abshi2"
3433   [(set (match_operand:HI 0 "general_operand" "=d")
3434         (abs:HI (match_operand:HI 1 "general_operand" "d")))]
3435   ""
3436   "*
3437 {
3438   check_label_emit ();
3439   mvs_check_page (0, 10, 0);
3440   return \"SLL  %1,16\;SRA      %1,16\;LPR      %0,%1\";
3441 }"
3442   [(set_attr "length" "10")]
3443 )
3444
3445 ;
3446 ; absdf2 instruction pattern(s).
3447 ;
3448
3449 (define_insn "absdf2"
3450   [(set (match_operand:DF 0 "general_operand" "=f")
3451         (abs:DF (match_operand:DF 1 "general_operand" "f")))]
3452   ""
3453   "*
3454 {
3455   check_label_emit ();
3456   mvs_check_page (0, 2, 0);
3457   return \"LPDR %0,%1\";
3458 }"
3459   [(set_attr "length" "2")]
3460 )
3461
3462 ;
3463 ; abssf2 instruction pattern(s).
3464 ;
3465
3466 (define_insn "abssf2"
3467   [(set (match_operand:SF 0 "general_operand" "=f")
3468         (abs:SF (match_operand:SF 1 "general_operand" "f")))]
3469   ""
3470   "*
3471 {
3472   check_label_emit ();
3473   mvs_check_page (0, 2, 0);
3474   return \"LPER %0,%1\";
3475 }"
3476   [(set_attr "length" "2")]
3477 )
3478
3479 ;;
3480 ;;- One complement instructions.
3481 ;;
3482
3483 ;
3484 ; one_cmpldi2 instruction pattern(s).
3485 ;
3486
3487 ;(define_expand "one_cmpldi2"
3488 ;  [(set (match_operand:DI 0 "general_operand" "")
3489 ;       (not:DI (match_operand:DI 1 "general_operand" "")))]
3490 ;  ""
3491 ;  "
3492 ;{
3493 ;  rtx gen_one_cmplsi2();
3494 ;
3495 ;  emit_insn (gen_one_cmplsi2 (operand_subword (operands[0], 0, 1, DImode),
3496 ;                             operand_subword (operands[1], 0, 1, DImode)));
3497 ;  emit_insn (gen_one_cmplsi2 (gen_lowpart (SImode, operands[0]),
3498 ;                             gen_lowpart (SImode, operands[1])));
3499 ;  DONE;
3500 ;}")
3501
3502 ;
3503 ; one_cmplsi2 instruction pattern(s).
3504 ;
3505
3506 (define_insn ""
3507   [(set (match_operand:SI 0 "r_or_s_operand" "=dm")
3508         (not:SI (match_operand:SI 1 "r_or_s_operand" "0")))]
3509   "TARGET_CHAR_INSTRUCTIONS"
3510   "*
3511 {
3512   check_label_emit ();
3513   CC_STATUS_INIT;  /* XOR sets CC but not how we want it */
3514   if (REG_P (operands[0]))
3515     {
3516       mvs_check_page (0, 4, 4);
3517       return \"X        %0,=F'-1'\";
3518     }
3519   CC_STATUS_INIT;
3520   mvs_check_page (0, 6, 4);
3521   return \"XC   %O0(4,%R0),=F'-1'\";
3522 }"
3523   [(set_attr "length" "6")]
3524 )
3525
3526 (define_insn "one_cmplsi2"
3527   [(set (match_operand:SI 0 "general_operand" "=d")
3528         (not:SI (match_operand:SI 1 "general_operand" "0")))]
3529   ""
3530   "*
3531 {
3532   check_label_emit ();
3533   CC_STATUS_INIT;  /* XOR sets CC but not how we want it */
3534   mvs_check_page (0, 4, 4);
3535   return \"X    %0,=F'-1'\";
3536 }"
3537   [(set_attr "length" "4")]
3538 )
3539
3540 ;
3541 ; one_cmplhi2 instruction pattern(s).
3542 ;
3543
3544 (define_insn ""
3545   [(set (match_operand:HI 0 "r_or_s_operand" "=dm")
3546         (not:HI (match_operand:HI 1 "r_or_s_operand" "0")))]
3547   "TARGET_CHAR_INSTRUCTIONS"
3548   "*
3549 {
3550   check_label_emit ();
3551   CC_STATUS_INIT;  /* XOR sets CC but not how we want it */
3552   if (REG_P (operands[0]))
3553     {
3554       mvs_check_page (0, 4, 4);
3555       return \"X        %0,=F'-1'\";
3556     }
3557   mvs_check_page (0, 6, 4);
3558   return \"XC   %O0(2,%R0),=XL4'FFFF'\";
3559 }"
3560   [(set_attr "length" "6")]
3561 )
3562
3563 (define_insn "one_cmplhi2"
3564   [(set (match_operand:HI 0 "general_operand" "=d")
3565         (not:HI (match_operand:HI 1 "general_operand" "0")))]
3566   ""
3567   "*
3568 {
3569   check_label_emit ();
3570   CC_STATUS_INIT;  /* XOR sets CC but not how we want it */
3571   mvs_check_page (0, 4, 4);
3572   return \"X    %0,=F'-1'\";
3573 }"
3574   [(set_attr "length" "4")]
3575 )
3576
3577 ;
3578 ; one_cmplqi2 instruction pattern(s).
3579 ;
3580
3581 (define_insn ""
3582   [(set (match_operand:QI 0 "r_or_s_operand" "=dm")
3583         (not:QI (match_operand:QI 1 "r_or_s_operand" "0")))]
3584   "TARGET_CHAR_INSTRUCTIONS"
3585   "*
3586 {
3587   check_label_emit ();
3588   CC_STATUS_INIT;  /* XOR sets CC but not how we want it */
3589   if (REG_P (operands[0]))
3590     {
3591       mvs_check_page (0, 4, 4);
3592       return \"X        %0,=F'-1'\";
3593     }
3594   mvs_check_page (0, 4, 0);
3595   return \"XI   %0,255\";
3596 }"
3597   [(set_attr "length" "4")]
3598 )
3599
3600 (define_insn "one_cmplqi2"
3601   [(set (match_operand:QI 0 "general_operand" "=d")
3602         (not:QI (match_operand:QI 1 "general_operand" "0")))]
3603   ""
3604   "*
3605 {
3606   check_label_emit ();
3607   CC_STATUS_INIT;  /* XOR sets CC but not how we want it */
3608   mvs_check_page (0, 4, 4);
3609   return \"X    %0,=F'-1'\";
3610 }"
3611   [(set_attr "length" "4")]
3612 )
3613
3614 ;;
3615 ;;- Arithmetic shift instructions.
3616 ;;
3617
3618 ;
3619 ; ashldi3 instruction pattern(s).
3620 ;
3621
3622 (define_insn "ashldi3"
3623   [(set (match_operand:DI 0 "general_operand" "=d")
3624         (ashift:DI (match_operand:DI 1 "general_operand" "0")
3625                    (match_operand:SI 2 "general_operand" "Ja")))]
3626   ""
3627   "*
3628 {
3629   check_label_emit ();
3630   /* this status set seems not have the desired effect,
3631    * proably because the 64-bit long-long test is emulated ?! */
3632   CC_STATUS_SET (operands[0], operands[1]);
3633   mvs_check_page (0, 4, 0);
3634   if (REG_P (operands[2]))
3635     return \"SLDA       %0,0(%2)\";
3636   return \"SLDA %0,%c2\";
3637 }"
3638   [(set_attr "length" "4")]
3639 )
3640
3641 ;
3642 ; ashrdi3 instruction pattern(s).
3643 ;
3644
3645 (define_insn "ashrdi3"
3646   [(set (match_operand:DI 0 "register_operand" "=d")
3647         (ashiftrt:DI (match_operand:DI 1 "general_operand" "0")
3648                      (match_operand:SI 2 "general_operand" "Ja")))]
3649   ""
3650   "*
3651 {
3652   check_label_emit ();
3653   /* this status set seems not have the desired effect,
3654    * proably because the 64-bit long-long test is emulated ?! */
3655   CC_STATUS_SET (operands[0], operands[1]);
3656   mvs_check_page (0, 4, 0);
3657   if (REG_P (operands[2])) 
3658     return \"SRDA       %0,0(%2)\";
3659   return \"SRDA %0,%c2\";
3660 }"
3661   [(set_attr "length" "4")]
3662 )
3663
3664 ;
3665 ; ashlsi3 instruction pattern(s).
3666 ;
3667
3668 (define_insn "ashlsi3"
3669   [(set (match_operand:SI 0 "general_operand" "=d")
3670         (ashift:SI (match_operand:SI 1 "general_operand" "0")
3671                    (match_operand:SI 2 "general_operand" "Ja")))]
3672   ""
3673   "*
3674 {
3675   check_label_emit ();
3676   mvs_check_page (0, 4, 0);
3677   if (REG_P (operands[2])) 
3678     return \"SLL        %0,0(%2)\";
3679   return \"SLL  %0,%c2\";
3680 }"
3681   [(set_attr "length" "4")]
3682 )
3683
3684 ;
3685 ; ashrsi3 instruction pattern(s).
3686 ;
3687
3688 (define_insn "ashrsi3"
3689   [(set (match_operand:SI 0 "general_operand" "=d")
3690         (ashiftrt:SI (match_operand:SI 1 "general_operand" "0")
3691                      (match_operand:SI 2 "general_operand" "Ja")))]
3692   ""
3693   "*
3694 {
3695   check_label_emit ();
3696   CC_STATUS_SET (operands[0], operands[1]);
3697   mvs_check_page (0, 4, 0);
3698   if (REG_P (operands[2])) 
3699     return \"SRA        %0,0(%2)\";
3700   return \"SRA  %0,%c2\";
3701 }"
3702   [(set_attr "length" "4")]
3703 )
3704
3705 ;
3706 ; ashlhi3 instruction pattern(s).
3707 ;
3708
3709 (define_insn "ashlhi3"
3710   [(set (match_operand:HI 0 "general_operand" "=d")
3711         (ashift:HI (match_operand:HI 1 "general_operand" "0")
3712                    (match_operand:SI 2 "general_operand" "Ja")))]
3713   ""
3714   "*
3715 {
3716   check_label_emit ();
3717   mvs_check_page (0, 8, 0);
3718   if (REG_P (operands[2])) 
3719     return \"SLL        %0,16(%2)\;SRA  %0,16\";
3720   return \"SLL  %0,16+%c2\;SRA  %0,16\";
3721 }"
3722   [(set_attr "length" "8")]
3723 )
3724
3725 ;
3726 ; ashrhi3 instruction pattern(s).
3727 ;
3728
3729 (define_insn "ashrhi3"
3730   [(set (match_operand:HI 0 "general_operand" "=d")
3731         (ashiftrt:HI (match_operand:HI 1 "general_operand" "0")
3732                      (match_operand:SI 2 "general_operand" "Ja")))]
3733   ""
3734   "*
3735 {
3736   check_label_emit ();
3737   mvs_check_page (0, 8, 0);
3738   if (REG_P (operands[2])) 
3739     return \"SLL        %0,16\;SRA      %0,16(%2)\";
3740   return \"SLL  %0,16\;SRA      %0,16+%c2\";
3741 }"
3742   [(set_attr "length" "8")]
3743 )
3744
3745 ;
3746 ; ashlqi3 instruction pattern(s).
3747 ;
3748
3749 (define_insn "ashlqi3"
3750   [(set (match_operand:QI 0 "general_operand" "=d")
3751         (ashift:QI (match_operand:QI 1 "general_operand" "0")
3752                    (match_operand:SI 2 "general_operand" "Ja")))]
3753   ""
3754   "*
3755 {
3756   check_label_emit ();
3757   mvs_check_page (0, 4, 0);
3758   if (REG_P (operands[2])) 
3759     return \"SLL        %0,0(%2)\";
3760   return \"SLL  %0,%c2\";
3761 }"
3762   [(set_attr "length" "4")]
3763 )
3764
3765 ;
3766 ; ashrqi3 instruction pattern(s).
3767 ;
3768
3769 (define_insn "ashrqi3"
3770   [(set (match_operand:QI 0 "general_operand" "=d")
3771         (ashiftrt:QI (match_operand:QI 1 "general_operand" "0")
3772                      (match_operand:SI 2 "general_operand" "Ja")))]
3773   ""
3774   "*
3775 {
3776   check_label_emit ();
3777   mvs_check_page (0, 8, 0);
3778   if (REG_P (operands[2])) 
3779     return \"SLL        %0,24\;SRA      %0,24(%2)\";
3780   return \"SLL  %0,24\;SRA      %0,24+%c2\";
3781 }"
3782   [(set_attr "length" "8")]
3783 )
3784
3785 ;;
3786 ;;- Logical shift instructions.
3787 ;;
3788
3789 ;
3790 ; lshrdi3 instruction pattern(s).
3791 ;
3792
3793 (define_insn "lshrdi3"
3794   [(set (match_operand:DI 0 "general_operand" "=d")
3795         (lshiftrt:DI (match_operand:DI 1 "general_operand" "0")
3796                      (match_operand:SI 2 "general_operand" "Ja")))]
3797   ""
3798   "*
3799 {
3800   check_label_emit ();
3801   mvs_check_page (0, 4, 0);
3802   if (REG_P (operands[2])) 
3803     return \"SRDL       %0,0(%2)\";
3804   return \"SRDL %0,%c2\";
3805 }"
3806   [(set_attr "length" "4")]
3807 )
3808
3809
3810 ;
3811 ; lshrsi3 instruction pattern(s).
3812 ;
3813
3814 (define_insn "lshrsi3"
3815   [(set (match_operand:SI 0 "general_operand" "=d")
3816         (lshiftrt:SI (match_operand:SI 1 "general_operand" "0")
3817                      (match_operand:SI 2 "general_operand" "Ja")))]
3818   ""
3819   "*
3820 {
3821   check_label_emit ();
3822   mvs_check_page (0, 4, 0);
3823   if (REG_P (operands[2])) 
3824     return \"SRL        %0,0(%2)\";
3825   return \"SRL  %0,%c2\";
3826 }"
3827   [(set_attr "length" "4")]
3828 )
3829
3830 ;
3831 ; lshrhi3 instruction pattern(s).
3832 ;
3833
3834 (define_insn "lshrhi3"
3835   [(set (match_operand:HI 0 "general_operand" "=d")
3836         (lshiftrt:HI (match_operand:HI 1 "general_operand" "0")
3837                      (match_operand:SI 2 "general_operand" "Ja")))]
3838   ""
3839   "*
3840 {
3841   check_label_emit ();
3842   CC_STATUS_INIT; /* AND sets the CC but not how we want it */
3843   if (REG_P (operands[2]))
3844     {
3845       mvs_check_page (0, 8, 4);
3846       return \"N        %0,=XL4'0000FFFF'\;SRL  %0,0(%2)\";
3847     }
3848   mvs_check_page (0, 8, 4);
3849   return \"N    %0,=XL4'0000FFFF'\;SRL  %0,%c2\";
3850 }"
3851   [(set_attr "length" "8")]
3852 )
3853
3854 ;
3855 ; lshrqi3 instruction pattern(s).
3856 ;
3857
3858 (define_insn "lshrqi3"
3859   [(set (match_operand:QI 0 "general_operand" "=d")
3860         (lshiftrt:QI (match_operand:QI 1 "general_operand" "0")
3861                      (match_operand:SI 2 "general_operand" "Ja")))]
3862   ""
3863   "*
3864 {
3865   check_label_emit ();
3866   CC_STATUS_INIT; /* AND sets the CC but not how we want it */
3867   mvs_check_page (0, 8, 4);
3868   if (REG_P (operands[2])) 
3869     return \"N  %0,=XL4'000000FF'\;SRL  %0,0(%2)\";
3870   return \"N    %0,=XL4'000000FF'\;SRL  %0,%c2\";
3871 }"
3872   [(set_attr "length" "8")]
3873 )
3874
3875 ;; =======================================================================
3876 ;;- Conditional jump instructions.
3877 ;; =======================================================================
3878
3879 ;
3880 ; beq instruction pattern(s).
3881 ;
3882
3883 (define_insn "beq"
3884   [(set (pc)
3885         (if_then_else (eq (cc0)
3886                           (const_int 0))
3887                       (label_ref (match_operand 0 "" ""))
3888                       (pc)))
3889 ;   (clobber (reg:SI 14))
3890    ]
3891   ""
3892   "*
3893 {
3894   check_label_emit ();
3895   mvs_check_page (0, 4, 0);
3896   if (i370_short_branch(insn) || mvs_check_label (CODE_LABEL_NUMBER (operands[0])))
3897     { 
3898       return \"BE       %l0\";
3899     }
3900   mvs_check_page (0, 2, 4);
3901   return \"L    14,=A(%l0)\;BER 14\";
3902 }"
3903   [(set_attr "length" "6")]
3904 )
3905
3906 ;
3907 ; bne instruction pattern(s).
3908 ;
3909
3910 (define_insn "bne"
3911   [(set (pc)
3912         (if_then_else (ne (cc0)
3913                           (const_int 0))
3914                       (label_ref (match_operand 0 "" ""))
3915                       (pc)))
3916 ;   (clobber (reg:SI 14))
3917    ]
3918   ""
3919   "*
3920 {
3921   check_label_emit ();
3922   mvs_check_page (0, 4, 0);
3923   if (i370_short_branch(insn) || mvs_check_label (CODE_LABEL_NUMBER (operands[0])))
3924     { 
3925       return \"BNE      %l0\";
3926     }
3927   mvs_check_page (0, 2, 4);
3928   return \"L    14,=A(%l0)\;BNER        14\";
3929 }"
3930   [(set_attr "length" "6")]
3931 )
3932
3933 ;
3934 ; bgt instruction pattern(s).
3935 ;
3936
3937 (define_insn "bgt"
3938   [(set (pc)
3939         (if_then_else (gt (cc0)
3940                           (const_int 0))
3941                       (label_ref (match_operand 0 "" ""))
3942                       (pc)))
3943 ;   (clobber (reg:SI 14))
3944    ]
3945   ""
3946   "*
3947 {
3948   check_label_emit ();
3949   mvs_check_page (0, 4, 0);
3950   if (i370_short_branch(insn) || mvs_check_label (CODE_LABEL_NUMBER (operands[0])))
3951     { 
3952       return \"BH       %l0\";
3953     }
3954   mvs_check_page (0, 2, 4);
3955   return \"L    14,=A(%l0)\;BHR 14\";
3956 }"
3957   [(set_attr "length" "6")]
3958 )
3959
3960 ;
3961 ; bgtu instruction pattern(s).
3962 ;
3963
3964 (define_insn "bgtu"
3965   [(set (pc)
3966         (if_then_else (gtu (cc0)
3967                            (const_int 0))
3968                       (label_ref (match_operand 0 "" ""))
3969                       (pc)))
3970 ;   (clobber (reg:SI 14))
3971    ]
3972   ""
3973   "*
3974 {
3975   check_label_emit ();
3976   mvs_check_page (0, 4, 0);
3977   if (i370_short_branch(insn) || mvs_check_label (CODE_LABEL_NUMBER (operands[0])))
3978     { 
3979       return \"BH       %l0\";
3980     }
3981   mvs_check_page (0, 2, 4);
3982   return \"L    14,=A(%l0)\;BHR 14\";
3983 }"
3984   [(set_attr "length" "6")]
3985 )
3986
3987 ;
3988 ; blt instruction pattern(s).
3989 ;
3990
3991 (define_insn "blt"
3992   [(set (pc)
3993         (if_then_else (lt (cc0)
3994                           (const_int 0))
3995                       (label_ref (match_operand 0 "" ""))
3996                       (pc)))
3997 ;   (clobber (reg:SI 14))
3998    ]
3999   ""
4000   "*
4001 {
4002   check_label_emit ();
4003   mvs_check_page (0, 4, 0);
4004   if (i370_short_branch(insn) || mvs_check_label (CODE_LABEL_NUMBER (operands[0])))
4005     { 
4006       return \"BL       %l0\";
4007     }
4008   mvs_check_page (0, 2, 4);
4009   return \"L    14,=A(%l0)\;BLR 14\";
4010 }"
4011   [(set_attr "length" "6")]
4012 )
4013
4014 ;
4015 ; bltu instruction pattern(s).
4016 ;
4017
4018 (define_insn "bltu"
4019   [(set (pc)
4020         (if_then_else (ltu (cc0)
4021                            (const_int 0))
4022                       (label_ref (match_operand 0 "" ""))
4023                       (pc)))
4024 ;   (clobber (reg:SI 14))
4025    ]
4026   ""
4027   "*
4028 {
4029   check_label_emit ();
4030   mvs_check_page (0, 4, 0);
4031   if (i370_short_branch(insn) || mvs_check_label (CODE_LABEL_NUMBER (operands[0])))
4032     { 
4033       return \"BL       %l0\";
4034     }
4035   mvs_check_page (0, 2, 4);
4036   return \"L    14,=A(%l0)\;BLR 14\";
4037 }"
4038   [(set_attr "length" "6")]
4039 )
4040
4041 ;
4042 ; bge instruction pattern(s).
4043 ;
4044
4045 (define_insn "bge"
4046   [(set (pc)
4047         (if_then_else (ge (cc0)
4048                           (const_int 0))
4049                       (label_ref (match_operand 0 "" ""))
4050                       (pc)))
4051 ;   (clobber (reg:SI 14))
4052    ]
4053   ""
4054   "*
4055 {
4056   check_label_emit ();
4057   mvs_check_page (0, 4, 0);
4058   if (i370_short_branch(insn) || mvs_check_label (CODE_LABEL_NUMBER (operands[0])))
4059     { 
4060       return \"BNL      %l0\";
4061     }
4062   mvs_check_page (0, 2, 4);
4063   return \"L    14,=A(%l0)\;BNLR        14\";
4064 }"
4065   [(set_attr "length" "6")]
4066 )
4067
4068 ;
4069 ; bgeu instruction pattern(s).
4070 ;
4071
4072 (define_insn "bgeu"
4073   [(set (pc)
4074         (if_then_else (geu (cc0)
4075                            (const_int 0))
4076                       (label_ref (match_operand 0 "" ""))
4077                       (pc)))
4078 ;   (clobber (reg:SI 14))
4079    ]
4080   ""
4081   "*
4082 {
4083   check_label_emit ();
4084   mvs_check_page (0, 4, 0);
4085   if (i370_short_branch(insn) || mvs_check_label (CODE_LABEL_NUMBER (operands[0])))
4086     { 
4087       return \"BNL      %l0\";
4088     }
4089   mvs_check_page (0, 2, 4);
4090   return \"L    14,=A(%l0)\;BNLR        14\";
4091 }"
4092   [(set_attr "length" "6")]
4093 )
4094
4095 ;
4096 ; ble instruction pattern(s).
4097 ;
4098
4099 (define_insn "ble"
4100   [(set (pc)
4101         (if_then_else (le (cc0)
4102                           (const_int 0))
4103                       (label_ref (match_operand 0 "" ""))
4104                       (pc)))
4105 ;   (clobber (reg:SI 14))
4106    ]
4107   ""
4108   "*
4109 {
4110   check_label_emit ();
4111   mvs_check_page (0, 4, 0);
4112   if (i370_short_branch(insn) || mvs_check_label (CODE_LABEL_NUMBER (operands[0])))
4113     { 
4114       return \"BNH      %l0\";
4115     }
4116   mvs_check_page (0, 2, 4);
4117   return \"L    14,=A(%l0)\;BNHR        14\";
4118 }"
4119   [(set_attr "length" "6")]
4120 )
4121
4122 ;
4123 ; bleu instruction pattern(s).
4124 ;
4125
4126 (define_insn "bleu"
4127   [(set (pc)
4128         (if_then_else (leu (cc0)
4129                            (const_int 0))
4130                       (label_ref (match_operand 0 "" ""))
4131                       (pc)))
4132 ;   (clobber (reg:SI 14))
4133    ]
4134   ""
4135   "*
4136 {
4137   check_label_emit ();
4138   mvs_check_page (0, 4, 0);
4139   if (i370_short_branch(insn) || mvs_check_label (CODE_LABEL_NUMBER (operands[0])))
4140     { 
4141       return \"BNH      %l0\";
4142     }
4143   mvs_check_page (0, 2, 4);
4144   return \"L    14,=A(%l0)\;BNHR        14\";
4145 }"
4146   [(set_attr "length" "6")]
4147 )
4148
4149 ;;
4150 ;;- Negated conditional jump instructions.
4151 ;;
4152
4153 (define_insn ""
4154   [(set (pc)
4155         (if_then_else (eq (cc0)
4156                           (const_int 0))
4157                       (pc)
4158                       (label_ref (match_operand 0 "" ""))))
4159 ;   (clobber (reg:SI 14))
4160    ]
4161   ""
4162   "*
4163 {
4164   check_label_emit ();
4165   mvs_check_page (0, 4, 0);
4166   if (i370_short_branch(insn) || mvs_check_label (CODE_LABEL_NUMBER (operands[0])))
4167     { 
4168       return \"BNE      %l0\";
4169     }
4170   mvs_check_page (0, 2, 4);
4171   return \"L    14,=A(%l0)\;BNER        14\";
4172 }"
4173   [(set_attr "length" "6")]
4174 )
4175
4176 (define_insn ""
4177   [(set (pc)
4178         (if_then_else (ne (cc0)
4179                           (const_int 0))
4180                       (pc)
4181                       (label_ref (match_operand 0 "" ""))))
4182 ;   (clobber (reg:SI 14))
4183    ]
4184   ""
4185   "*
4186 {
4187   check_label_emit ();
4188   mvs_check_page (0, 4, 0);
4189   if (i370_short_branch(insn) || mvs_check_label (CODE_LABEL_NUMBER (operands[0])))
4190     { 
4191       return \"BE       %l0\";
4192     }
4193   mvs_check_page (0, 2, 4);
4194   return \"L    14,=A(%l0)\;BER 14\";
4195 }"
4196   [(set_attr "length" "6")]
4197 )
4198
4199 (define_insn ""
4200   [(set (pc)
4201         (if_then_else (gt (cc0)
4202                           (const_int 0))
4203                       (pc)
4204                       (label_ref (match_operand 0 "" ""))))
4205 ;   (clobber (reg:SI 14))
4206    ]
4207   ""
4208   "*
4209 {
4210   check_label_emit ();
4211   mvs_check_page (0, 4, 0);
4212   if (i370_short_branch(insn) || mvs_check_label (CODE_LABEL_NUMBER (operands[0])))
4213     { 
4214       return \"BNH      %l0\";
4215     }
4216   mvs_check_page (0, 2, 4);
4217   return \"L    14,=A(%l0)\;BNHR        14\";
4218 }"
4219   [(set_attr "length" "6")]
4220 )
4221
4222 (define_insn ""
4223   [(set (pc)
4224         (if_then_else (gtu (cc0)
4225                            (const_int 0))
4226                       (pc)
4227                       (label_ref (match_operand 0 "" ""))))
4228 ;   (clobber (reg:SI 14))
4229    ]
4230   ""
4231   "*
4232 {
4233   check_label_emit ();
4234   mvs_check_page (0, 4, 0);
4235   if (i370_short_branch(insn) || mvs_check_label (CODE_LABEL_NUMBER (operands[0])))
4236     { 
4237       return \"BNH      %l0\";
4238     }
4239   mvs_check_page (0, 2, 4);
4240   return \"L    14,=A(%l0)\;BNHR        14\";
4241 }"
4242   [(set_attr "length" "6")]
4243 )
4244
4245 (define_insn ""
4246   [(set (pc)
4247         (if_then_else (lt (cc0)
4248                           (const_int 0))
4249                       (pc)
4250                       (label_ref (match_operand 0 "" ""))))
4251 ;   (clobber (reg:SI 14))
4252    ]
4253   ""
4254   "*
4255 {
4256   check_label_emit ();
4257   mvs_check_page (0, 4, 0);
4258   if (i370_short_branch(insn) || mvs_check_label (CODE_LABEL_NUMBER (operands[0])))
4259     { 
4260       return \"BNL      %l0\";
4261     }
4262   mvs_check_page (0, 2, 4);
4263   return \"L    14,=A(%l0)\;BNLR        14\";
4264 }"
4265   [(set_attr "length" "6")]
4266 )
4267
4268 (define_insn ""
4269   [(set (pc)
4270         (if_then_else (ltu (cc0)
4271                            (const_int 0))
4272                       (pc)
4273                       (label_ref (match_operand 0 "" ""))))
4274 ;   (clobber (reg:SI 14))
4275    ]
4276   ""
4277   "*
4278 {
4279   check_label_emit ();
4280   mvs_check_page (0, 4, 0);
4281   if (i370_short_branch(insn) || mvs_check_label (CODE_LABEL_NUMBER (operands[0])))
4282     { 
4283       return \"BNL      %l0\";
4284     }
4285   mvs_check_page (0, 2, 4);
4286   return \"L    14,=A(%l0)\;BNLR        14\";
4287 }"
4288   [(set_attr "length" "6")]
4289 )
4290
4291 (define_insn ""
4292   [(set (pc)
4293         (if_then_else (ge (cc0)
4294                           (const_int 0))
4295                       (pc)
4296                       (label_ref (match_operand 0 "" ""))))
4297 ;   (clobber (reg:SI 14))
4298    ]
4299   ""
4300   "*
4301 {
4302   check_label_emit ();
4303   mvs_check_page (0, 4, 0);
4304   if (i370_short_branch(insn) || mvs_check_label (CODE_LABEL_NUMBER (operands[0])))
4305     { 
4306       return \"BL       %l0\";
4307     }
4308   mvs_check_page (0, 2, 4);
4309   return \"L    14,=A(%l0)\;BLR 14\";
4310 }"
4311   [(set_attr "length" "6")]
4312 )
4313
4314 (define_insn ""
4315   [(set (pc)
4316         (if_then_else (geu (cc0)
4317                            (const_int 0))
4318                       (pc)
4319                       (label_ref (match_operand 0 "" ""))))
4320 ;   (clobber (reg:SI 14))
4321    ]
4322   ""
4323   "*
4324 {
4325   check_label_emit ();
4326   mvs_check_page (0, 4, 0);
4327   if (i370_short_branch(insn) || mvs_check_label (CODE_LABEL_NUMBER (operands[0])))
4328     { 
4329       return \"BL       %l0\";
4330     }
4331   mvs_check_page (0, 2, 4);
4332   return \"L    14,=A(%l0)\;BLR 14\";
4333 }"
4334   [(set_attr "length" "6")]
4335 )
4336
4337 (define_insn ""
4338   [(set (pc)
4339         (if_then_else (le (cc0)
4340                           (const_int 0))
4341                       (pc)
4342                       (label_ref (match_operand 0 "" ""))))
4343 ;   (clobber (reg:SI 14))
4344    ]
4345   ""
4346   "*
4347 {
4348   check_label_emit ();
4349   mvs_check_page (0, 4, 0);
4350   if (i370_short_branch(insn) || mvs_check_label (CODE_LABEL_NUMBER (operands[0])))
4351     { 
4352       return \"BH       %l0\";
4353     }
4354   mvs_check_page (0, 2, 4);
4355   return \"L    14,=A(%l0)\;BHR 14\";
4356 }"
4357   [(set_attr "length" "6")]
4358 )
4359
4360 (define_insn ""
4361   [(set (pc)
4362         (if_then_else (leu (cc0)
4363                            (const_int 0))
4364                       (pc)
4365                       (label_ref (match_operand 0 "" ""))))
4366 ;   (clobber (reg:SI 14))
4367    ]
4368   ""
4369   "*
4370 {
4371   check_label_emit ();
4372   mvs_check_page (0, 4, 0);
4373   if (i370_short_branch(insn) || mvs_check_label (CODE_LABEL_NUMBER (operands[0])))
4374     { 
4375       return \"BH       %l0\";
4376     }
4377   mvs_check_page (0, 2, 4);
4378   return \"L    14,=A(%l0)\;BHR 14\";
4379 }"
4380   [(set_attr "length" "6")]
4381 )
4382
4383 ;; ==============================================================
4384 ;;- Subtract one and jump if not zero.
4385 ;; These insns seem to not be getting matched ...
4386 ;; XXX should fix this, as it would improve for loops
4387
4388 (define_insn ""
4389   [(set (pc)
4390         (if_then_else
4391          (ne (plus:SI (match_operand:SI 0 "register_operand" "+d")
4392                       (const_int -1))
4393              (const_int 0))
4394          (label_ref (match_operand 1 "" ""))
4395          (pc)))
4396    (set (match_dup 0)
4397         (plus:SI (match_dup 0)
4398                  (const_int -1)))
4399 ;   (clobber (reg:SI 14))
4400    ]
4401   ""
4402   "*
4403 {
4404   check_label_emit ();
4405   mvs_check_page (0, 4, 0);
4406   if (mvs_check_label (CODE_LABEL_NUMBER (operands[1])))
4407     {
4408       return \"BCT      %0,%l1\";
4409     }
4410   mvs_check_page (0, 2, 4);
4411   return \"L    14,=A(%l1)\;BCTR        %0,14\";
4412 }"
4413   [(set_attr "length" "6")]
4414 )
4415
4416 (define_insn ""
4417   [(set (pc)
4418         (if_then_else
4419          (eq (plus:SI (match_operand:SI 0 "register_operand" "+d")
4420                       (const_int -1))
4421              (const_int 0))
4422          (pc)
4423          (label_ref (match_operand 1 "" ""))))
4424    (set (match_dup 0)
4425         (plus:SI (match_dup 0)
4426                  (const_int -1)))
4427 ;   (clobber (reg:SI 14))
4428    ]
4429   ""
4430   "*
4431 {
4432   check_label_emit ();
4433   mvs_check_page (0, 4, 0);
4434   if (mvs_check_label (CODE_LABEL_NUMBER (operands[1])))
4435     {
4436       return \"BCT      %0,%l1\";
4437     }
4438   mvs_check_page (0, 2, 4);
4439   return \"L    14,=A(%l1)\;BCTR        %0,14\";
4440 }"
4441   [(set_attr "length" "6")]
4442 )
4443
4444 ;; =============================================================
4445 ;;- Unconditional jump instructions.
4446 ;;
4447
4448 ;
4449 ; jump instruction pattern(s).
4450 ;
4451
4452 (define_insn "jump"
4453   [(set (pc)
4454         (label_ref (match_operand 0 "" "")))
4455 ;   (clobber (reg:SI 14))
4456    ]
4457   ""
4458   "*
4459 {
4460   check_label_emit ();
4461   mvs_check_page (0, 4, 0);
4462   if (i370_short_branch(insn) || mvs_check_label (CODE_LABEL_NUMBER (operands[0])))
4463     {
4464       return \"B        %l0\";
4465     }
4466   mvs_check_page (0, 2, 4);
4467   return \"L    14,=A(%l0)\;BR  14\";
4468 }"
4469   [(set_attr "length" "6")]
4470 )
4471
4472 ;
4473 ; indirect-jump instruction pattern(s).
4474 ; hack alert -- should check that displacement is < 4096
4475
4476 (define_insn "indirect_jump"
4477   [(set (pc) (match_operand:SI 0 "general_operand" "rm"))]
4478   ""
4479   "*
4480 {
4481   check_label_emit ();
4482   if (REG_P (operands[0]))
4483     {
4484       mvs_check_page (0, 2, 0);
4485       return \"BR       %0\";
4486     }
4487   mvs_check_page (0, 4, 0);
4488   return \"B    %0\";
4489 }"
4490   [(set_attr "length" "4")]
4491 )
4492
4493 ;
4494 ; tablejump instruction pattern(s).
4495 ;
4496
4497 (define_insn "tablejump"
4498   [(set (pc)
4499         (match_operand:SI 0 "general_operand" "am"))
4500    (use (label_ref (match_operand 1 "" "")))
4501 ;   (clobber (reg:SI 14))
4502    ]
4503   ""
4504   "*
4505 {
4506   check_label_emit ();
4507   if (REG_P (operands[0]))
4508     {
4509       mvs_check_page (0, 6, 0);
4510       return \"BR       %0\;DS  0F\";
4511     }
4512   mvs_check_page (0, 10, 0);
4513   return \"L    14,%0\;BR       14\;DS  0F\";
4514 }"
4515   [(set_attr "length" "10")]
4516 )
4517
4518 ;;
4519 ;;- Jump to subroutine.
4520 ;;
4521 ;; For the C/370 environment the internal functions, ie. sqrt, are called with
4522 ;; a non-standard form.  So, we must fix it here.  There's no BM like IBM.
4523 ;;
4524 ;; The ELF ABI is different from the C/370 ABI because we have a simpler,
4525 ;; more powerful way of dealing with structure-value returns.  Basically, 
4526 ;; we use R1 to point at structure returns (64-bit and larger returns)
4527 ;; and R11 to point at the args.  Note that this handles double-precision
4528 ;; (64-bit) values just fine, in a less-kludged manner than the C/370 ABI.
4529 ;; Since R1 is used, we use R2 to pass the argument pointer to the routine.
4530
4531 ;
4532 ; call instruction pattern(s).
4533 ;
4534 ; We define four call instruction patterns below. The first two patterns,
4535 ; although general, end up matching (only?) calls through function pointers.  
4536 ; The last two, which require a symbol-ref to match, get used for all
4537 ; ordinary subroutine calls.
4538
4539 (define_insn "call"
4540   [(call (match_operand:QI 0 "memory_operand" "m")
4541          (match_operand:SI 1 "immediate_operand" "i"))
4542    (clobber (reg:SI 2))
4543    ]
4544   ""
4545   "*
4546 {
4547   static char temp[128];
4548   int i = STACK_POINTER_OFFSET;
4549   CC_STATUS_INIT;
4550
4551   check_label_emit ();
4552 #ifdef TARGET_ELF_ABI
4553   mvs_check_page (0, 10, 4);
4554   sprintf ( temp, \"LA  r2,%d(,sp)\;LA  15,%%0\;BASR    14,15\", i );
4555   return temp;
4556 #else
4557   if (mvs_function_check (XSTR (operands[0], 0)))
4558     {
4559       mvs_check_page (0, 22, 4);
4560       sprintf ( temp, \"LA      1,136(,13)\;ST  1,%d(,13)\;LA 1,%d(,13)\;LA     15,%%0\;BALR    14,15\;LD       0,136(,13)\",
4561              i - 4, i - 4 );
4562     }
4563   else
4564     {
4565       mvs_check_page (0, 10, 4);
4566       sprintf ( temp, \"LA      1,%d(,13)\;LA   15,%%0\;BALR    14,15\", i );
4567     }
4568   return temp;
4569 #endif
4570 }"
4571   [(set_attr "length" "22")]
4572 )
4573
4574 ;
4575 ; call_value instruction pattern(s).
4576 ;
4577
4578 (define_insn "call_value"
4579   [(set (match_operand 0 "" "=rf")
4580         (call (match_operand:QI 1 "memory_operand" "m")
4581               (match_operand:SI 2 "general_operand" "i")))
4582    (clobber (reg:SI 2))
4583    ]
4584   ""
4585   "*
4586 {
4587   static char temp[128];
4588   int i = STACK_POINTER_OFFSET;
4589   CC_STATUS_INIT;
4590
4591   check_label_emit ();
4592 #ifdef TARGET_ELF_ABI
4593   mvs_check_page (0, 10, 4);
4594   sprintf ( temp, \"LA  r2,%d(,sp)\;LA  15,%%1\;BASR    14,15\", i );
4595   return temp;
4596 #else
4597   if (mvs_function_check (XSTR (operands[1], 0)))
4598     {
4599       mvs_check_page (0, 22, 4);
4600       sprintf ( temp, \"LA      1,136(,13)\;ST  1,%d(,13)\;LA 1,%d(,13)\;LA     15,%%1\;BALR    14,15\;LD       0,136(,13)\",
4601            i - 4, i - 4 );
4602     }
4603   else
4604     {
4605       mvs_check_page (0, 10, 4);
4606       sprintf ( temp, \"LA      1,%d(,13)\;LA   15,%%1\;BALR    14,15\", i );
4607     }
4608   return temp;
4609 #endif
4610 }"
4611   [(set_attr "length" "22")]
4612 )
4613
4614 (define_insn ""
4615   [(call (mem:QI (match_operand:SI 0 "" "i"))
4616          (match_operand:SI 1 "general_operand" "g"))
4617    (clobber (reg:SI 2))
4618    ]
4619   "GET_CODE (operands[0]) == SYMBOL_REF"
4620   "*
4621 {
4622   static char temp[128];
4623   int i = STACK_POINTER_OFFSET;
4624   CC_STATUS_INIT;
4625
4626   check_label_emit ();
4627 #ifdef TARGET_ELF_ABI
4628   mvs_check_page (0, 10, 4);
4629   sprintf ( temp, \"LA  r2,%d(,sp)\;L   15,%%0\;BASR    14,15\", i );
4630   return temp;
4631 #else
4632   if (mvs_function_check (XSTR (operands[0], 0)))
4633     {
4634       mvs_check_page (0, 22, 4);
4635       sprintf ( temp, \"LA      1,136(,13)\;ST  1,%d(,13)\;LA   1,%d(,13)\;L    15,%%0\;BALR    14,15\;LD       0,136(,13)\",
4636            i - 4, i - 4 );
4637     }
4638   else
4639     {
4640       mvs_check_page (0, 10, 4);
4641       sprintf ( temp, \"LA      1,%d(,13)\;L    15,%%0\;BALR    14,15\", i );
4642     }
4643   return temp;
4644 #endif
4645 }"
4646   [(set_attr "length" "22")]
4647 )
4648
4649 (define_insn ""
4650   [(set (match_operand 0 "" "=rf")
4651         (call (mem:QI (match_operand:SI 1 "" "i"))
4652               (match_operand:SI 2 "general_operand" "g")))
4653    (clobber (reg:SI 2))
4654    ]
4655   "GET_CODE (operands[1]) == SYMBOL_REF"
4656   "*
4657 {
4658   static char temp[128];
4659   int i = STACK_POINTER_OFFSET;
4660   CC_STATUS_INIT;
4661
4662   check_label_emit ();
4663 #ifdef TARGET_ELF_ABI
4664   mvs_check_page (0, 10, 4);
4665   sprintf ( temp, \"LA  r2,%d(,sp)\;L   15,%%1\;BASR    14,15\", i );
4666   return temp;
4667 #else
4668   if (mvs_function_check (XSTR (operands[1], 0)))
4669     {
4670       mvs_check_page (0, 22, 4);
4671       sprintf ( temp, \"LA      1,136(,13)\;ST  1,%d(,13)\;LA   1,%d(,13)\;L    15,%%1\;BALR    14,15\;LD       0,136(,13)\",
4672            i - 4, i - 4 );
4673     }
4674   else
4675     {
4676       mvs_check_page (0, 10, 4);
4677       sprintf ( temp, \"LA      1,%d(,13)\;L    15,%%1\;BALR    14,15\", i );
4678     }
4679   return temp;
4680 #endif
4681 }"
4682   [(set_attr "length" "22")]
4683 )
4684
4685 ;;
4686 ;; Call subroutine returning any type.
4687 ;; This instruction pattern appears to be used only by the
4688 ;; expand_builtin_apply definition for __builtin_apply.  It is needed
4689 ;; since call_value might return an int in r15 or a float in fpr0 (r16)
4690 ;; and the builtin code calls abort since the reg is ambiguous. Well,
4691 ;; the below is probably broken anyway, we just want to go for now.
4692 ;;
4693 (define_expand "untyped_call"
4694 [(parallel [(call (match_operand 0 "" "")
4695                   (const_int 0))
4696               (match_operand 1 "" "")
4697               (match_operand 2 "" "")])]
4698   ""
4699   "
4700 {
4701   int i;
4702
4703   emit_call_insn (GEN_CALL (operands[0], const0_rtx, const0_rtx, const0_rtx));
4704
4705   for (i = 0; i < XVECLEN (operands[2], 0); i++)
4706     {
4707       rtx set = XVECEXP (operands[2], 0, i);
4708       emit_move_insn (SET_DEST (set), SET_SRC (set));
4709     }
4710
4711   /* The optimizer does not know that the call sets the function value
4712      registers we stored in the result block.  We avoid problems by
4713      claiming that all hard registers are used and clobbered at this
4714      point.  */
4715   /* emit_insn (gen_blockage ()); */
4716
4717   DONE;
4718 }")
4719
4720
4721 ;;
4722 ;;- Miscellaneous instructions.
4723 ;;
4724
4725 ;
4726 ; nop instruction pattern(s).
4727 ;
4728
4729 (define_insn "nop"
4730   [(const_int 0)]
4731   ""
4732   "*
4733 {
4734   check_label_emit ();
4735   mvs_check_page (0, 2, 0);
4736   return \"LR   0,0\";
4737 }"
4738   [(set_attr "length" "2")]
4739 )