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{
458check_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)
4740