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