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