1 ;;- Machine description for GNU compiler -- S/390 / zSeries version.
2 ;; Copyright (C) 1999-2024 Free Software Foundation, Inc.
3 ;; Contributed by Hartmut Penner (hpenner@de.ibm.com) and
4 ;; Ulrich Weigand (uweigand@de.ibm.com) and
5 ;; Andreas Krebbel (Andreas.Krebbel@de.ibm.com)
7 ;; This file is part of GCC.
9 ;; GCC is free software; you can redistribute it and/or modify it under
10 ;; the terms of the GNU General Public License as published by the Free
11 ;; Software Foundation; either version 3, or (at your option) any later
14 ;; GCC is distributed in the hope that it will be useful, but WITHOUT ANY
15 ;; WARRANTY; without even the implied warranty of MERCHANTABILITY or
16 ;; FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
19 ;; You should have received a copy of the GNU General Public License
20 ;; along with GCC; see the file COPYING3. If not see
21 ;; <http://www.gnu.org/licenses/>.
24 ;; See constraints.md for a description of constraints specific to s390.
27 ;; Special formats used for outputting 390 instructions.
29 ;; %C: print opcode suffix for branch condition.
30 ;; %D: print opcode suffix for inverse branch condition.
31 ;; %J: print tls_load/tls_gdcall/tls_ldcall suffix
32 ;; %G: print the size of the operand in bytes.
33 ;; %O: print only the displacement of a memory reference.
34 ;; %R: print only the base register of a memory reference.
35 ;; %S: print S-type memory reference (base+displacement).
36 ;; %N: print the second word of a DImode operand.
37 ;; %M: print the second word of a TImode operand.
38 ;; %Y: print shift count operand.
40 ;; %b: print integer X as if it's an unsigned byte.
41 ;; %c: print integer X as if it's an signed byte.
42 ;; %x: print integer X as if it's an unsigned halfword.
43 ;; %h: print integer X as if it's a signed halfword.
44 ;; %i: print the first nonzero HImode part of X.
45 ;; %j: print the first HImode part unequal to -1 of X.
46 ;; %k: print the first nonzero SImode part of X.
47 ;; %m: print the first SImode part unequal to -1 of X.
48 ;; %o: print integer X as if it's an unsigned 32bit word.
50 ;; We have a special constraint for pattern matching.
52 ;; s_operand -- Matches a valid S operand in a RS, SI or SS type instruction.
59 (define_c_enum "unspec" [
66 ; Convert CC into a str comparison result and copy it into an
68 ; cc0->0, cc1->1, cc2->-1, (cc3->-1)
69 UNSPEC_STRCMPCC_TO_INT
71 ; Copy CC as is into the lower 2 bits of an integer register
74 ; The right hand side of an setmem
77 ; GOT/PLT and lt-relative accesses
98 ; TLS relocation specifiers
115 ; Stack Smashing Protector
119 ; Split stack support
122 ; Test Data Class (TDC)
125 ; Byte-wise Population Count
133 UNSPEC_FPINT_NEARBYINT
142 UNSPEC_VEC_SMULT_EVEN
143 UNSPEC_VEC_UMULT_EVEN
156 UNSPEC_VEC_INSERT_AND_ZERO
157 UNSPEC_VEC_LOAD_BNDRY
159 UNSPEC_VEC_LOAD_LEN_R
161 UNSPEC_VEC_PACK_SATURATE
162 UNSPEC_VEC_PACK_SATURATE_CC
163 UNSPEC_VEC_PACK_SATURATE_GENCC
164 UNSPEC_VEC_PACK_UNSIGNED_SATURATE
165 UNSPEC_VEC_PACK_UNSIGNED_SATURATE_CC
166 UNSPEC_VEC_PACK_UNSIGNED_SATURATE_GENCC
170 UNSPEC_VEC_STORE_LEN_R
178 UNSPEC_VEC_ADDEC_U128
183 UNSPEC_VEC_GFMSUM_128
184 UNSPEC_VEC_GFMSUM_ACCUM
185 UNSPEC_VEC_GFMSUM_ACCUM_128
204 UNSPEC_VEC_SUBEC_U128
233 UNSPEC_VEC_VFLL ; vector fp load lengthened
234 UNSPEC_VEC_VFLR ; vector fp load rounded
246 UNSPEC_NNPA_VCLFNHS_V8HI
247 UNSPEC_NNPA_VCLFNLS_V8HI
248 UNSPEC_NNPA_VCRNFS_V8HI
250 UNSPEC_NNPA_VCFN_V8HI
251 UNSPEC_NNPA_VCNF_V8HI
255 ;; UNSPEC_VOLATILE usage
258 (define_c_enum "unspecv" [
280 ; Non-branch nops used for compare-and-branch adjustments on z10
284 ; Hotpatching (unremovable NOPs)
289 ; Transactional Execution support
299 ; Set and get floating point control register
303 ; Split stack support
304 UNSPECV_SPLIT_STACK_CALL
313 ; Registers with special meaning
317 ; Sibling call register.
319 ; A call-clobbered reg which can be used in indirect branch thunks
320 (INDIRECT_BRANCH_THUNK_REGNUM 1)
321 ; Literal pool base register.
323 ; Return address register.
325 ; Stack pointer register.
327 ; Condition code register.
329 ; Thread local storage pointer register.
333 ; Hardware register names
337 ; General purpose registers
342 ; Floating point registers.
366 ; Rounding modes for binary floating point numbers
369 (BFP_RND_NEAREST_TIE_AWAY_FROM_0 1)
370 (BFP_RND_PREP_FOR_SHORT_PREC 3)
371 (BFP_RND_NEAREST_TIE_TO_EVEN 4)
373 (BFP_RND_TOWARD_INF 6)
374 (BFP_RND_TOWARD_MINF 7)])
376 ; Rounding modes for decimal floating point numbers
377 ; 1-7 were introduced with the floating point extension facility
378 ; available with z196
379 ; With these rounding modes (1-7) a quantum exception might occur
380 ; which is suppressed for the other modes.
383 (DFP_RND_NEAREST_TIE_AWAY_FROM_0_QUANTEXC 1)
384 (DFP_RND_CURRENT_QUANTEXC 2)
385 (DFP_RND_PREP_FOR_SHORT_PREC_QUANTEXC 3)
386 (DFP_RND_NEAREST_TIE_TO_EVEN_QUANTEXC 4)
387 (DFP_RND_TOWARD_0_QUANTEXC 5)
388 (DFP_RND_TOWARD_INF_QUANTEXC 6)
389 (DFP_RND_TOWARD_MINF_QUANTEXC 7)
390 (DFP_RND_NEAREST_TIE_TO_EVEN 8)
392 (DFP_RND_TOWARD_INF 10)
393 (DFP_RND_TOWARD_MINF 11)
394 (DFP_RND_NEAREST_TIE_AWAY_FROM_0 12)
395 (DFP_RND_NEAREST_TIE_TO_0 13)
396 (DFP_RND_AWAY_FROM_0 14)
397 (DFP_RND_PREP_FOR_SHORT_PREC 15)])
400 ;; PFPO GPR0 argument format
405 ; PFPO operation type
406 (PFPO_CONVERT 0x1000000)
408 (PFPO_OP_TYPE_SF 0x5)
409 (PFPO_OP_TYPE_DF 0x6)
410 (PFPO_OP_TYPE_TF 0x7)
411 (PFPO_OP_TYPE_FPRX2 0x7)
412 (PFPO_OP_TYPE_SD 0x8)
413 (PFPO_OP_TYPE_DD 0x9)
414 (PFPO_OP_TYPE_TD 0xa)
415 ; Bitposition of operand types
416 (PFPO_OP0_TYPE_SHIFT 16)
417 (PFPO_OP1_TYPE_SHIFT 8)
418 ; Decide whether current DFP or BFD rounding mode should be used
419 ; for the conversion.
420 (PFPO_RND_MODE_DFP 0)
421 (PFPO_RND_MODE_BFP 1)
426 ; Immediate values which can be used as the third operand to the
427 ; perform processor assist instruction
431 (PPA_OOO_BARRIER 15)])
433 ; Immediate operands for tbegin and tbeginc
434 (define_constants [(TBEGIN_MASK 65292)]) ; 0xff0c
435 (define_constants [(TBEGINC_MASK 65288)]) ; 0xff08
437 ;; Instruction operand type as used in the Principles of Operation.
438 ;; Used to determine defaults for length and other attribute values.
440 (define_attr "op_type"
441 "NN,E,RR,RRE,RX,RS,RSI,RI,SI,S,SS,SSE,RXE,RSE,RIL,RIE,RXY,RSY,SIY,RRF,SIL,RRS,RIS,VRI,VRR,VRS,VRV,VRX,VSI"
444 ;; Instruction type attribute used for scheduling.
446 (define_attr "type" "none,integer,load,lr,la,larl,lm,stm,
447 cs,vs,store,sem,idiv,
448 imulhi,imulsi,imuldi,
449 branch,jsr,fsimptf,fsimpdf,fsimpsf,fhex,
450 floadtf,floaddf,floadsf,fstoredf,fstoresf,
451 fmultf,fmuldf,fmulsf,fdivtf,fdivdf,fdivsf,
452 ftoi,fsqrttf,fsqrtdf,fsqrtsf,
454 ftrunctf,ftruncdf, ftruncsd, ftruncdd,
455 itoftf, itofdf, itofsf, itofdd, itoftd,
456 fdivdd, fdivtd, floaddd, floadsd, fmuldd, fmultd,
457 fsimpdd, fsimpsd, fsimptd, fstoredd, fstoresd,
459 (cond [(eq_attr "op_type" "NN") (const_string "other")
460 (eq_attr "op_type" "SS") (const_string "cs")]
461 (const_string "integer")))
463 ;; Another attribute used for scheduling purposes:
464 ;; agen: Instruction uses the address generation unit
465 ;; reg: Instruction does not use the agen unit
467 (define_attr "atype" "agen,reg"
468 (if_then_else (eq_attr "op_type" "E,RR,RI,RRE,RSI,RIL,RIE,RRF")
470 (const_string "agen")))
472 ;; Properties concerning Z10 execution grouping and value forwarding.
473 ;; z10_super: instruction is superscalar.
474 ;; z10_super_c: instruction is superscalar and meets the condition of z10_c.
475 ;; z10_fwd: The instruction reads the value of an operand and stores it into a
476 ;; target register. It can forward this value to a second instruction that reads
477 ;; the same register if that second instruction is issued in the same group.
478 ;; z10_rec: The instruction is in the T pipeline and reads a register. If the
479 ;; instruction in the S pipe writes to the register, then the T instruction
480 ;; can immediately read the new value.
481 ;; z10_fr: union of Z10_fwd and z10_rec.
482 ;; z10_c: second operand of instruction is a register and read with complemented bits.
484 ;; An additional suffix A1, A3, or E1 indicates the respective AGI bypass.
487 (define_attr "z10prop" "none,
488 z10_super, z10_super_E1, z10_super_A1, z10_super_c, z10_super_c_E1,
489 z10_fwd, z10_fwd_A1, z10_fwd_A3, z10_fwd_E1,
491 z10_fr, z10_fr_A3, z10_fr_E1,
493 (const_string "none"))
495 ;; Properties concerning Z196 decoding
496 ;; z196_alone: must group alone
497 ;; z196_end: ends a group
498 ;; z196_cracked: instruction is cracked or expanded
499 (define_attr "z196prop" "none,
500 z196_alone, z196_ends,
502 (const_string "none"))
504 ; mnemonics which only get defined through if_then_else currently
505 ; don't get added to the list values automatically and hence need to
507 (define_attr "mnemonic" "b,bas,basr,bc,bcr_flush,unknown" (const_string "unknown"))
511 (define_attr "length" ""
512 (cond [(eq_attr "op_type" "E,RR") (const_int 2)
513 (eq_attr "op_type" "RX,RI,RRE,RS,RSI,S,SI,RRF") (const_int 4)]
517 ;; Processor type. This attribute must exactly match the processor_type
518 ;; enumeration in s390.h.
520 (define_attr "cpu" "z900,z990,z9_109,z9_ec,z10,z196,zEC12,z13,z14,z15,z16"
521 (const (symbol_ref "s390_tune_attr")))
523 (define_attr "cpu_facility"
524 "standard,ieee,zarch,cpu_zarch,longdisp,extimm,dfp,z10,z196,zEC12,vx,z13,z14,vxe,z15,vxe2,z16,nnpa"
525 (const_string "standard"))
527 (define_attr "enabled" ""
528 (cond [(eq_attr "cpu_facility" "standard")
531 (and (eq_attr "cpu_facility" "ieee")
532 (match_test "TARGET_CPU_IEEE_FLOAT"))
535 (and (eq_attr "cpu_facility" "zarch")
536 (match_test "TARGET_ZARCH"))
539 (and (eq_attr "cpu_facility" "longdisp")
540 (match_test "TARGET_LONG_DISPLACEMENT"))
543 (and (eq_attr "cpu_facility" "extimm")
544 (match_test "TARGET_EXTIMM"))
547 (and (eq_attr "cpu_facility" "dfp")
548 (match_test "TARGET_DFP"))
551 (eq_attr "cpu_facility" "cpu_zarch")
554 (and (eq_attr "cpu_facility" "z10")
555 (match_test "TARGET_Z10"))
558 (and (eq_attr "cpu_facility" "z196")
559 (match_test "TARGET_Z196"))
562 (and (eq_attr "cpu_facility" "zEC12")
563 (match_test "TARGET_ZEC12"))
566 (and (eq_attr "cpu_facility" "vx")
567 (match_test "TARGET_VX"))
570 (and (eq_attr "cpu_facility" "z13")
571 (match_test "TARGET_Z13"))
574 (and (eq_attr "cpu_facility" "z14")
575 (match_test "TARGET_Z14"))
578 (and (eq_attr "cpu_facility" "vxe")
579 (match_test "TARGET_VXE"))
582 (and (eq_attr "cpu_facility" "z15")
583 (match_test "TARGET_Z15"))
586 (and (eq_attr "cpu_facility" "vxe2")
587 (match_test "TARGET_VXE2"))
590 (and (eq_attr "cpu_facility" "z16")
591 (match_test "TARGET_Z16"))
594 (and (eq_attr "cpu_facility" "nnpa")
595 (match_test "TARGET_NNPA"))
600 ;; Whether an instruction supports relative long addressing.
601 ;; Currently this corresponds to RIL-b and RIL-c instruction formats,
602 ;; but having a separate attribute, as opposed to reusing op_type,
603 ;; provides additional flexibility.
605 (define_attr "relative_long" "no,yes" (const_string "no"))
607 (define_code_attr extend_insn [(sign_extend "extend") (zero_extend "zero_extend")])
608 (define_code_attr zero_extend [(sign_extend "") (zero_extend "l")])
609 (define_code_iterator any_extend [sign_extend zero_extend])
611 ;; Pipeline description for z900.
614 ;; Pipeline description for z990, z9-109 and z9-ec.
617 ;; Pipeline description for z10
620 ;; Pipeline description for z196
623 ;; Pipeline description for zEC12
626 ;; Pipeline description for z13
629 ;; Pipeline description for z14
632 ;; Pipeline description for z15
635 ;; Pipeline description for z16
639 (include "predicates.md")
641 ;; Constraint definitions
642 (include "constraints.md")
649 (define_mode_iterator ALL [TI DI SI HI QI TF FPRX2 DF SF TD DD SD V1QI V2QI
650 V4QI V8QI V16QI V1HI V2HI V4HI V8HI V1SI V2SI V4SI
651 V1DI V2DI V1SF V2SF V4SF V1TI V1DF V2DF V1TF])
653 ;; These mode iterators allow floating point patterns to be generated from the
655 (define_mode_iterator FP_ALL [(TF "!TARGET_VXE") (FPRX2 "TARGET_VXE") DF SF
656 (TD "TARGET_HARD_DFP") (DD "TARGET_HARD_DFP")
657 (SD "TARGET_HARD_DFP")])
658 (define_mode_iterator FP [(TF "!TARGET_VXE") (FPRX2 "TARGET_VXE") DF SF
659 (TD "TARGET_HARD_DFP") (DD "TARGET_HARD_DFP")])
660 ;; Like FP, but without a condition on TF. Useful for expanders that must be
661 ;; the same for FP and VR variants of TF.
662 (define_mode_iterator FP_ANYTF [TF (FPRX2 "TARGET_VXE") DF SF
663 (TD "TARGET_HARD_DFP")
664 (DD "TARGET_HARD_DFP")])
665 (define_mode_iterator BFP [(TF "!TARGET_VXE") (FPRX2 "TARGET_VXE") DF SF])
666 (define_mode_iterator DFP [TD DD])
667 (define_mode_iterator DFP_ALL [TD DD SD])
668 (define_mode_iterator DSF [DF SF])
669 (define_mode_iterator SD_SF [SF SD])
670 (define_mode_iterator DD_DF [DF DD])
671 (define_mode_iterator TD_TF [(TF "!TARGET_VXE") (FPRX2 "TARGET_VXE") TD])
673 ; 32 bit int<->fp conversion instructions are available since VXE2 (z15).
674 (define_mode_iterator VX_CONV_BFP [DF (SF "TARGET_VXE2")])
676 ;; These mode iterators allow 31-bit and 64-bit GPR patterns to be generated
677 ;; from the same template.
678 (define_mode_iterator GPR [(DI "TARGET_ZARCH") SI])
679 (define_mode_iterator DGPR [(TI "TARGET_ZARCH") DI SI])
680 (define_mode_iterator DSI [DI SI])
681 (define_mode_iterator TDI [TI DI])
683 ;; These mode iterators allow :P to be used for patterns that operate on
684 ;; pointer-sized quantities. Exactly one of the two alternatives will match.
685 (define_mode_iterator P [(DI "TARGET_64BIT") (SI "!TARGET_64BIT")])
687 ;; These macros refer to the actual word_mode of the configuration.
688 ;; This is equal to Pmode except on 31-bit machines in zarch mode.
689 (define_mode_iterator DW [(TI "TARGET_ZARCH") (DI "!TARGET_ZARCH")])
690 (define_mode_iterator W [(DI "TARGET_ZARCH") (SI "!TARGET_ZARCH")])
692 ;; Used by the umul pattern to express modes having half the size.
693 (define_mode_attr DWH [(TI "DI") (DI "SI")])
694 (define_mode_attr dwh [(TI "di") (DI "si")])
696 ;; This mode iterator allows the QI and HI patterns to be defined from
697 ;; the same template.
698 (define_mode_iterator HQI [HI QI])
700 ;; This mode iterator allows the integer patterns to be defined from the
702 (define_mode_iterator INT [(DI "TARGET_ZARCH") SI HI QI])
703 (define_mode_iterator DINT [(TI "TARGET_ZARCH") DI SI HI QI])
704 (define_mode_iterator SINT [SI HI QI])
706 ;; This iterator allows some 'ashift' and 'lshiftrt' pattern to be defined from
707 ;; the same template.
708 (define_code_iterator SHIFT [ashift lshiftrt])
710 ;; This iterator allows r[ox]sbg to be defined with the same template
711 (define_code_iterator IXOR [ior xor])
713 ;; This is used for merging the nand/nor and and/or with complement patterns
714 (define_code_iterator ANDOR [and ior])
715 (define_code_attr bitops_name [(and "and") (ior "or")])
716 (define_code_attr inv_bitops_name [(and "or") (ior "and")])
717 (define_code_attr inv_no [(and "o") (ior "n")])
719 ;; This iterator is used to expand the patterns for the nearest
720 ;; integer functions.
721 (define_int_iterator FPINT [UNSPEC_FPINT_FLOOR UNSPEC_FPINT_BTRUNC
722 UNSPEC_FPINT_ROUND UNSPEC_FPINT_CEIL
723 UNSPEC_FPINT_NEARBYINT])
724 (define_int_attr fpint_name [(UNSPEC_FPINT_FLOOR "floor")
725 (UNSPEC_FPINT_BTRUNC "btrunc")
726 (UNSPEC_FPINT_ROUND "round")
727 (UNSPEC_FPINT_CEIL "ceil")
728 (UNSPEC_FPINT_NEARBYINT "nearbyint")])
729 (define_int_attr fpint_roundingmode [(UNSPEC_FPINT_FLOOR "7")
730 (UNSPEC_FPINT_BTRUNC "5")
731 (UNSPEC_FPINT_ROUND "1")
732 (UNSPEC_FPINT_CEIL "6")
733 (UNSPEC_FPINT_NEARBYINT "0")])
735 ;; This iterator and attribute allow to combine most atomic operations.
736 (define_code_iterator ATOMIC [and ior xor plus minus mult])
737 (define_code_iterator ATOMIC_Z196 [and ior xor plus])
738 (define_code_attr atomic [(and "and") (ior "or") (xor "xor")
739 (plus "add") (minus "sub") (mult "nand")])
740 (define_code_attr noxa [(and "n") (ior "o") (xor "x") (plus "a")])
742 ;; In FP templates, a string like "lt<de>br" will expand to "ltxbr" in
743 ;; TF/TDmode, "ltdbr" in DF/DDmode, and "ltebr" in SF/SDmode.
744 (define_mode_attr xde [(TF "x") (FPRX2 "x") (DF "d") (SF "e") (TD "x")
745 (DD "d") (SD "e") (V4SF "e") (V2DF "d")])
747 ;; In FP templates, a <dee> in "m<dee><bt>r" will expand to "mx<bt>r" in
748 ;; TF/TDmode, "md<bt>r" in DF/DDmode, "mee<bt>r" in SFmode and "me<bt>r in
750 (define_mode_attr xdee [(TF "x") (FPRX2 "x") (DF "d") (SF "ee") (TD "x") (DD "d") (SD "e")])
752 ;; The decimal floating point variants of add, sub, div and mul support 3
753 ;; fp register operands. The following attributes allow to merge the bfp and
754 ;; dfp variants in a single insn definition.
756 ;; These mode attributes are supposed to be used in the `enabled' insn
757 ;; attribute to disable certain alternatives for certain modes.
758 (define_mode_attr nBFP [(TF "0") (FPRX2 "0") (DF "0") (SF "0") (TD "*")
760 (define_mode_attr nDFP [(TF "*") (FPRX2 "*") (DF "*") (SF "*") (TD "0")
762 (define_mode_attr DSF [(TF "0") (FPRX2 "0") (DF "*") (SF "*") (TD "0")
764 (define_mode_attr DFDI [(TF "0") (FPRX2 "0") (DF "*") (SF "0")
765 (TD "0") (DD "0") (DD "0")
766 (TI "0") (DI "*") (SI "0")])
767 (define_mode_attr SFSI [(TF "0") (FPRX2 "0") (DF "0") (SF "*")
768 (TD "0") (DD "0") (DD "0")
769 (TI "0") (DI "0") (SI "*")])
770 (define_mode_attr DF [(TF "0") (FPRX2 "0") (DF "*") (SF "0")
771 (TD "0") (DD "0") (DD "0")
772 (TI "0") (DI "0") (SI "0")])
773 (define_mode_attr SF [(TF "0") (FPRX2 "0") (DF "0") (SF "*")
774 (TD "0") (DD "0") (DD "0")
775 (TI "0") (DI "0") (SI "0")])
777 ;; This attribute is used in the operand constraint list
778 ;; for instructions dealing with the sign bit of 32 or 64bit fp values.
779 ;; TFmode values are represented by a fp register pair. Since the
780 ;; sign bit instructions only handle single source and target fp registers
781 ;; these instructions can only be used for TFmode values if the source and
782 ;; target operand uses the same fp register.
783 (define_mode_attr fT0 [(TF "0") (FPRX2 "0") (DF "f") (SF "f")])
785 ;; This attribute adds b for bfp instructions and t for dfp instructions and is used
786 ;; within instruction mnemonics.
787 (define_mode_attr bt [(TF "b") (FPRX2 "b") (DF "b") (SF "b") (TD "t") (DD "t")
790 ;; This attribute is used within instruction mnemonics. It evaluates to d for dfp
791 ;; modes and to an empty string for bfp modes.
792 (define_mode_attr _d [(TF "") (FPRX2 "") (DF "") (SF "") (TD "d") (DD "d")
795 ;; In GPR and P templates, a constraint like "<d0>" will expand to "d" in DImode
796 ;; and "0" in SImode. This allows to combine instructions of which the 31bit
797 ;; version only operates on one register.
798 (define_mode_attr d0 [(DI "d") (SI "0")])
800 ;; In combination with d0 this allows to combine instructions of which the 31bit
801 ;; version only operates on one register. The DImode version needs an additional
802 ;; register for the assembler output.
803 (define_mode_attr 1 [(DI "%1,") (SI "")])
805 ;; In SHIFT templates, a string like "s<lr>dl" will expand to "sldl" in
806 ;; 'ashift' and "srdl" in 'lshiftrt'.
807 (define_code_attr lr [(ashift "l") (lshiftrt "r")])
809 ;; In SHIFT templates, this attribute holds the correct standard name for the
810 ;; pattern itself and the corresponding function calls.
811 (define_code_attr shift [(ashift "ashl") (lshiftrt "lshr")])
813 ;; This attribute handles differences in the instruction 'type' and will result
814 ;; in "RRE" for DImode and "RR" for SImode.
815 (define_mode_attr E [(DI "E") (SI "")])
817 ;; This attribute handles differences in the instruction 'type' and makes RX<Y>
818 ;; to result in "RXY" for DImode and "RX" for SImode.
819 (define_mode_attr Y [(DI "Y") (SI "")])
821 ;; This attribute handles differences in the instruction 'type' and will result
822 ;; in "RSE" for TImode and "RS" for DImode.
823 (define_mode_attr TE [(TI "E") (DI "")])
825 ;; In GPR templates, a string like "lc<g>r" will expand to "lcgr" in DImode
826 ;; and "lcr" in SImode.
827 (define_mode_attr g [(DI "g") (SI "")])
829 ;; In GPR templates, a string like "sl<y>" will expand to "slg" in DImode
830 ;; and "sly" in SImode. This is useful because on 64bit the ..g instructions
831 ;; were enhanced with long displacements whereas 31bit instructions got a ..y
832 ;; variant for long displacements.
833 (define_mode_attr y [(DI "g") (SI "y")])
835 ;; In DW templates, a string like "cds<g>" will expand to "cdsg" in TImode
836 ;; and "cds" in DImode.
837 (define_mode_attr tg [(TI "g") (DI "")])
839 ;; In TDI templates, a string like "c<d>sg".
840 (define_mode_attr td [(TI "d") (DI "")])
842 ;; In GPR templates, a string like "c<gf>dbr" will expand to "cgdbr" in DImode
843 ;; and "cfdbr" in SImode.
844 (define_mode_attr gf [(DI "g") (SI "f") (DF "g") (SF "f")])
846 ;; In GPR templates, a string like sll<gk> will expand to sllg for DI
847 ;; and sllk for SI. This way it is possible to merge the new z196 SI
848 ;; 3 operands shift instructions into the existing patterns.
849 (define_mode_attr gk [(DI "g") (SI "k")])
851 ;; ICM mask required to load MODE value into the lowest subreg
852 ;; of a SImode register.
853 (define_mode_attr icm_lo [(HI "3") (QI "1")])
855 ;; In HQI templates, a string like "llg<hc>" will expand to "llgh" in
856 ;; HImode and "llgc" in QImode.
857 (define_mode_attr hc [(HI "h") (QI "c")])
859 ;; In P templates, the mode <DBL> will expand to "TI" in DImode and "DI"
861 (define_mode_attr DBL [(DI "TI") (SI "DI")])
863 ;; This attribute expands to DF for TFmode and to DD for TDmode . It is
864 ;; used for Txmode splitters splitting a Txmode copy into 2 Dxmode copies.
865 (define_mode_attr HALF_TMODE [(TF "DF") (FPRX2 "DF") (TD "DD")])
867 ;; Maximum unsigned integer that fits in MODE.
868 (define_mode_attr max_uint [(HI "65535") (QI "255")])
870 ;; Start and end field computations for RISBG et al.
871 (define_mode_attr bfstart [(DI "s") (SI "t")])
872 (define_mode_attr bfend [(DI "e") (SI "f")])
874 ;; In place of GET_MODE_BITSIZE (<MODE>mode)
875 (define_mode_attr bitsize [(DI "64") (SI "32") (HI "16") (QI "8")])
877 (define_mode_attr bitoff [(DI "0") (SI "32") (HI "48") (QI "56")])
878 (define_mode_attr bitoff_plus [(DI "") (SI "32+") (HI "48+") (QI "56+")])
880 ;; In place of GET_MODE_SIZE (<MODE>mode)
881 (define_mode_attr modesize [(DI "8") (SI "4")])
883 ;; Allow return and simple_return to be defined from a single template.
884 (define_code_iterator ANY_RETURN [return simple_return])
886 ;; Facilitate dispatching TFmode expanders on z14+.
887 (define_mode_attr tf_fpr [(TF "_fpr") (FPRX2 "") (DF "") (SF "") (TD "")
890 ;; Mode names as seen in type mode_attr values.
891 (define_mode_attr type [(TF "tf") (FPRX2 "tf") (DF "df") (SF "sf") (TD "td")
892 (DD "dd") (SD "sd")])
895 ; Condition code modes generated by vector fp comparisons. These will
896 ; be used also in single element mode.
897 (define_mode_iterator VFCMP [CCVEQ CCVFH CCVFHE])
898 ; Used with VFCMP to expand part of the mnemonic
899 ; For fp we have a mismatch: eq in the insn name - e in asm
900 (define_mode_attr asm_fcmp [(CCVEQ "e") (CCVFH "h") (CCVFHE "he")])
901 (define_mode_attr insn_cmp [(CCVEQ "eq") (CCVIH "h") (CCVIHU "hl") (CCVFH "h") (CCVFHE "he")])
903 ; Analogue to TOINTVEC / tointvec
904 (define_mode_attr TOINT [(TF "TI") (DF "DI") (SF "SI")])
905 (define_mode_attr toint [(TF "ti") (DF "di") (SF "si")])
907 ;; Subst pattern definitions
910 (include "vector.md")
913 ;;- Compare instructions.
916 ; Test-under-Mask instructions
918 (define_insn "*tmqi_mem"
919 [(set (reg CC_REGNUM)
920 (compare (and:QI (match_operand:QI 0 "memory_operand" "Q,S")
921 (match_operand:QI 1 "immediate_operand" "n,n"))
922 (match_operand:QI 2 "immediate_operand" "n,n")))]
923 "s390_match_ccmode (insn, s390_tm_ccmode (operands[1], operands[2], false))"
927 [(set_attr "op_type" "SI,SIY")
928 (set_attr "cpu_facility" "*,longdisp")
929 (set_attr "z10prop" "z10_super,z10_super")])
931 (define_insn "*tmdi_reg"
932 [(set (reg CC_REGNUM)
933 (compare (and:DI (match_operand:DI 0 "nonimmediate_operand" "d,d,d,d")
934 (match_operand:DI 1 "immediate_operand"
935 "N0HD0,N1HD0,N2HD0,N3HD0"))
936 (match_operand:DI 2 "immediate_operand" "n,n,n,n")))]
938 && s390_match_ccmode (insn, s390_tm_ccmode (operands[1], operands[2], true))
939 && s390_single_part (operands[1], DImode, HImode, 0) >= 0"
945 [(set_attr "op_type" "RI")
946 (set_attr "z10prop" "z10_super,z10_super,z10_super,z10_super")])
948 (define_insn "*tmsi_reg"
949 [(set (reg CC_REGNUM)
950 (compare (and:SI (match_operand:SI 0 "nonimmediate_operand" "d,d")
951 (match_operand:SI 1 "immediate_operand" "N0HS0,N1HS0"))
952 (match_operand:SI 2 "immediate_operand" "n,n")))]
953 "s390_match_ccmode (insn, s390_tm_ccmode (operands[1], operands[2], true))
954 && s390_single_part (operands[1], SImode, HImode, 0) >= 0"
958 [(set_attr "op_type" "RI")
959 (set_attr "z10prop" "z10_super,z10_super")])
961 (define_insn "*tm<mode>_full"
962 [(set (reg CC_REGNUM)
963 (compare (match_operand:HQI 0 "register_operand" "d")
964 (match_operand:HQI 1 "immediate_operand" "n")))]
965 "s390_match_ccmode (insn, s390_tm_ccmode (constm1_rtx, operands[1], true))"
967 [(set_attr "op_type" "RI")
968 (set_attr "z10prop" "z10_super")])
972 ; Load-and-Test instructions
975 ; tst(di|si) instruction pattern(s).
977 (define_insn "*tstdi_sign"
978 [(set (reg CC_REGNUM)
982 (subreg:DI (match_operand:SI 0 "nonimmediate_operand" "d,T") 0)
983 (const_int 32)) (const_int 32))
984 (match_operand:DI 1 "const0_operand" "")))
985 (set (match_operand:DI 2 "register_operand" "=d,d")
986 (sign_extend:DI (match_dup 0)))]
987 "s390_match_ccmode(insn, CCSmode) && TARGET_ZARCH"
990 [(set_attr "op_type" "RRE,RXY")
991 (set_attr "cpu_facility" "*,z10")
992 (set_attr "z10prop" "z10_super_E1,z10_super_E1") ])
995 (define_insn "*tst<mode>_extimm"
996 [(set (reg CC_REGNUM)
997 (compare (match_operand:GPR 0 "nonimmediate_operand" "d,T")
998 (match_operand:GPR 1 "const0_operand" "")))
999 (set (match_operand:GPR 2 "register_operand" "=d,d")
1001 "s390_match_ccmode(insn, CCSmode) && TARGET_EXTIMM"
1005 [(set_attr "op_type" "RR<E>,RXY")
1006 (set_attr "z10prop" "z10_fr_E1,z10_fwd_A3") ])
1008 ; Peephole to combine a load-and-test from volatile memory which combine does
1011 [(set (match_operand:GPR 0 "register_operand")
1012 (match_operand:GPR 2 "memory_operand"))
1013 (set (reg CC_REGNUM)
1014 (compare (match_dup 0) (match_operand:GPR 1 "const0_operand")))]
1015 "s390_match_ccmode (peep2_next_insn (1), CCSmode) && TARGET_EXTIMM
1016 && GENERAL_REG_P (operands[0])
1017 && satisfies_constraint_T (operands[2])
1018 && !contains_constant_pool_address_p (operands[2])"
1020 [(set (reg:CCS CC_REGNUM)
1021 (compare:CCS (match_dup 2) (match_dup 1)))
1022 (set (match_dup 0) (match_dup 2))])])
1024 ; ltr, lt, ltgr, ltg
1025 (define_insn "*tst<mode>_cconly_extimm"
1026 [(set (reg CC_REGNUM)
1027 (compare (match_operand:GPR 0 "nonimmediate_operand" "d,T")
1028 (match_operand:GPR 1 "const0_operand" "")))
1029 (clobber (match_scratch:GPR 2 "=X,d"))]
1030 "s390_match_ccmode(insn, CCSmode) && TARGET_EXTIMM"
1034 [(set_attr "op_type" "RR<E>,RXY")
1035 (set_attr "z10prop" "z10_fr_E1,z10_fwd_A3")])
1037 (define_insn "*tstdi"
1038 [(set (reg CC_REGNUM)
1039 (compare (match_operand:DI 0 "register_operand" "d")
1040 (match_operand:DI 1 "const0_operand" "")))
1041 (set (match_operand:DI 2 "register_operand" "=d")
1043 "s390_match_ccmode(insn, CCSmode) && TARGET_ZARCH && !TARGET_EXTIMM"
1045 [(set_attr "op_type" "RRE")
1046 (set_attr "z10prop" "z10_fr_E1")])
1048 (define_insn "*tstsi"
1049 [(set (reg CC_REGNUM)
1050 (compare (match_operand:SI 0 "nonimmediate_operand" "d,Q,S")
1051 (match_operand:SI 1 "const0_operand" "")))
1052 (set (match_operand:SI 2 "register_operand" "=d,d,d")
1054 "s390_match_ccmode(insn, CCSmode) && !TARGET_EXTIMM"
1059 [(set_attr "op_type" "RR,RS,RSY")
1060 (set_attr "cpu_facility" "*,*,longdisp")
1061 (set_attr "z10prop" "z10_fr_E1,z10_super_E1,z10_super_E1")])
1063 (define_insn "*tstsi_cconly"
1064 [(set (reg CC_REGNUM)
1065 (compare (match_operand:SI 0 "nonimmediate_operand" "d,Q,S")
1066 (match_operand:SI 1 "const0_operand" "")))
1067 (clobber (match_scratch:SI 2 "=X,d,d"))]
1068 "s390_match_ccmode(insn, CCSmode)"
1073 [(set_attr "op_type" "RR,RS,RSY")
1074 (set_attr "cpu_facility" "*,*,longdisp")
1075 (set_attr "z10prop" "z10_fr_E1,z10_super_E1,z10_super_E1")])
1077 (define_insn "*tstdi_cconly_31"
1078 [(set (reg CC_REGNUM)
1079 (compare (match_operand:DI 0 "register_operand" "d")
1080 (match_operand:DI 1 "const0_operand" "")))]
1081 "s390_match_ccmode(insn, CCSmode) && !TARGET_ZARCH"
1083 [(set_attr "op_type" "RS")
1084 (set_attr "atype" "reg")])
1087 (define_insn "*tst<mode>_cconly2"
1088 [(set (reg CC_REGNUM)
1089 (compare (match_operand:GPR 0 "register_operand" "d")
1090 (match_operand:GPR 1 "const0_operand" "")))]
1091 "s390_match_ccmode(insn, CCSmode)"
1093 [(set_attr "op_type" "RR<E>")
1094 (set_attr "z10prop" "z10_fr_E1")])
1096 ; tst(hi|qi) instruction pattern(s).
1098 (define_insn "*tst<mode>CCT"
1099 [(set (reg CC_REGNUM)
1100 (compare (match_operand:HQI 0 "nonimmediate_operand" "?Q,?S,d")
1101 (match_operand:HQI 1 "const0_operand" "")))
1102 (set (match_operand:HQI 2 "register_operand" "=d,d,0")
1104 "s390_match_ccmode(insn, CCTmode)"
1106 icm\t%2,<icm_lo>,%S0
1107 icmy\t%2,<icm_lo>,%S0
1109 [(set_attr "op_type" "RS,RSY,RI")
1110 (set_attr "cpu_facility" "*,longdisp,*")
1111 (set_attr "z10prop" "z10_super_E1,z10_super_E1,z10_super")])
1113 (define_insn "*tsthiCCT_cconly"
1114 [(set (reg CC_REGNUM)
1115 (compare (match_operand:HI 0 "nonimmediate_operand" "Q,S,d")
1116 (match_operand:HI 1 "const0_operand" "")))
1117 (clobber (match_scratch:HI 2 "=d,d,X"))]
1118 "s390_match_ccmode(insn, CCTmode)"
1123 [(set_attr "op_type" "RS,RSY,RI")
1124 (set_attr "cpu_facility" "*,longdisp,*")
1125 (set_attr "z10prop" "z10_super_E1,z10_super_E1,z10_super")])
1127 (define_insn "*tstqiCCT_cconly"
1128 [(set (reg CC_REGNUM)
1129 (compare (match_operand:QI 0 "nonimmediate_operand" "?Q,?S,d")
1130 (match_operand:QI 1 "const0_operand" "")))]
1131 "s390_match_ccmode(insn, CCTmode)"
1136 [(set_attr "op_type" "SI,SIY,RI")
1137 (set_attr "cpu_facility" "*,longdisp,*")
1138 (set_attr "z10prop" "z10_super,z10_super,z10_super")])
1140 (define_insn "*tst<mode>"
1141 [(set (reg CC_REGNUM)
1142 (compare (match_operand:HQI 0 "s_operand" "Q,S")
1143 (match_operand:HQI 1 "const0_operand" "")))
1144 (set (match_operand:HQI 2 "register_operand" "=d,d")
1146 "s390_match_ccmode(insn, CCSmode)"
1148 icm\t%2,<icm_lo>,%S0
1149 icmy\t%2,<icm_lo>,%S0"
1150 [(set_attr "op_type" "RS,RSY")
1151 (set_attr "cpu_facility" "*,longdisp")
1152 (set_attr "z10prop" "z10_super_E1,z10_super_E1")])
1154 (define_insn "*tst<mode>_cconly"
1155 [(set (reg CC_REGNUM)
1156 (compare (match_operand:HQI 0 "s_operand" "Q,S")
1157 (match_operand:HQI 1 "const0_operand" "")))
1158 (clobber (match_scratch:HQI 2 "=d,d"))]
1159 "s390_match_ccmode(insn, CCSmode)"
1161 icm\t%2,<icm_lo>,%S0
1162 icmy\t%2,<icm_lo>,%S0"
1163 [(set_attr "op_type" "RS,RSY")
1164 (set_attr "cpu_facility" "*,longdisp")
1165 (set_attr "z10prop" "z10_super_E1,z10_super_E1")])
1168 ; Compare (equality) instructions
1170 (define_insn "*cmpdi_cct"
1171 [(set (reg CC_REGNUM)
1172 (compare (match_operand:DI 0 "nonimmediate_operand" "%d,d,d,d,Q")
1173 (match_operand:DI 1 "general_operand" "d,K,Os,T,BQ")))]
1174 "s390_match_ccmode (insn, CCTmode) && TARGET_ZARCH"
1181 [(set_attr "op_type" "RRE,RI,RIL,RXY,SS")
1182 (set_attr "z10prop" "z10_super_c,z10_super,z10_super,z10_super,*")])
1184 (define_insn "*cmpsi_cct"
1185 [(set (reg CC_REGNUM)
1186 (compare (match_operand:SI 0 "nonimmediate_operand" "%d,d,d,d,d,Q")
1187 (match_operand:SI 1 "general_operand" "d,K,Os,R,T,BQ")))]
1188 "s390_match_ccmode (insn, CCTmode)"
1196 [(set_attr "op_type" "RR,RI,RIL,RX,RXY,SS")
1197 (set_attr "cpu_facility" "*,*,*,*,longdisp,*")
1198 (set_attr "z10prop" "z10_super_c,z10_super,z10_super,z10_super,z10_super,*")])
1200 ; Compare (signed) instructions
1202 (define_insn "*cmpdi_ccs_sign"
1203 [(set (reg CC_REGNUM)
1204 (compare (sign_extend:DI (match_operand:SI 1 "nonimmediate_operand"
1206 (match_operand:DI 0 "register_operand" "d, d,d")))]
1207 "s390_match_ccmode(insn, CCSRmode) && TARGET_ZARCH"
1212 [(set_attr "op_type" "RRE,RXY,RIL")
1213 (set_attr "z10prop" "z10_c,*,*")
1214 (set_attr "type" "*,*,larl")
1215 (set_attr "relative_long" "*,*,yes")])
1219 (define_insn "*cmpsi_ccs_sign"
1220 [(set (reg CC_REGNUM)
1221 (compare (sign_extend:SI (match_operand:HI 1 "memory_operand" "R,T,b"))
1222 (match_operand:SI 0 "register_operand" "d,d,d")))]
1223 "s390_match_ccmode(insn, CCSRmode)"
1228 [(set_attr "op_type" "RX,RXY,RIL")
1229 (set_attr "cpu_facility" "*,longdisp,z10")
1230 (set_attr "type" "*,*,larl")
1231 (set_attr "z196prop" "z196_cracked,z196_cracked,z196_cracked")
1232 (set_attr "relative_long" "*,*,yes")])
1234 (define_insn "*cmphi_ccs_z10"
1235 [(set (reg CC_REGNUM)
1236 (compare (match_operand:HI 0 "s_operand" "Q")
1237 (match_operand:HI 1 "immediate_operand" "K")))]
1238 "s390_match_ccmode(insn, CCSmode) && TARGET_Z10"
1240 [(set_attr "op_type" "SIL")
1241 (set_attr "z196prop" "z196_cracked")])
1243 (define_insn "*cmpdi_ccs_signhi_rl"
1244 [(set (reg CC_REGNUM)
1245 (compare (sign_extend:DI (match_operand:HI 1 "memory_operand" "T,b"))
1246 (match_operand:GPR 0 "register_operand" "d,d")))]
1247 "s390_match_ccmode(insn, CCSRmode) && TARGET_Z10"
1251 [(set_attr "op_type" "RXY,RIL")
1252 (set_attr "type" "*,larl")
1253 (set_attr "relative_long" "*,yes")])
1255 ; cr, chi, cfi, c, cy, cgr, cghi, cgfi, cg, chsi, cghsi, crl, cgrl
1256 (define_insn "*cmp<mode>_ccs"
1257 [(set (reg CC_REGNUM)
1258 (compare (match_operand:GPR 0 "nonimmediate_operand"
1260 (match_operand:GPR 1 "general_operand"
1261 "d,K,K,Os,R,T,b")))]
1262 "s390_match_ccmode(insn, CCSmode)"
1271 [(set_attr "op_type" "RR<E>,RI,SIL,RIL,RX<Y>,RXY,RIL")
1272 (set_attr "cpu_facility" "*,*,z10,extimm,*,longdisp,z10")
1273 (set_attr "type" "*,*,*,*,*,*,larl")
1274 (set_attr "z10prop" "z10_super_c,z10_super,z10_super,z10_super,z10_super,z10_super,z10_super")
1275 (set_attr "relative_long" "*,*,*,*,*,*,yes")])
1278 ; Compare (unsigned) instructions
1280 (define_insn "*cmpsi_ccu_zerohi_rlsi"
1281 [(set (reg CC_REGNUM)
1282 (compare (zero_extend:SI (mem:HI (match_operand:SI 1
1283 "larl_operand" "X")))
1284 (match_operand:SI 0 "register_operand" "d")))]
1285 "s390_match_ccmode(insn, CCURmode) && TARGET_Z10"
1287 [(set_attr "op_type" "RIL")
1288 (set_attr "type" "larl")
1289 (set_attr "z10prop" "z10_super")
1290 (set_attr "relative_long" "yes")])
1293 (define_insn "*cmp<GPR:mode>_ccu_zerohi_rldi"
1294 [(set (reg CC_REGNUM)
1295 (compare (zero_extend:GPR (mem:HI (match_operand:DI 1
1296 "larl_operand" "X")))
1297 (match_operand:GPR 0 "register_operand" "d")))]
1298 "s390_match_ccmode(insn, CCURmode) && TARGET_Z10"
1300 [(set_attr "op_type" "RIL")
1301 (set_attr "type" "larl")
1302 (set_attr "z10prop" "z10_super")
1303 (set_attr "relative_long" "yes")])
1305 (define_insn "*cmpdi_ccu_zero"
1306 [(set (reg CC_REGNUM)
1307 (compare (zero_extend:DI (match_operand:SI 1 "nonimmediate_operand"
1309 (match_operand:DI 0 "register_operand" "d,d,d")))]
1310 "s390_match_ccmode (insn, CCURmode) && TARGET_ZARCH"
1315 [(set_attr "op_type" "RRE,RXY,RIL")
1316 (set_attr "cpu_facility" "*,*,z10")
1317 (set_attr "type" "*,*,larl")
1318 (set_attr "z10prop" "z10_super_c,z10_super_E1,z10_super")
1319 (set_attr "relative_long" "*,*,yes")])
1321 (define_insn "*cmpdi_ccu"
1322 [(set (reg CC_REGNUM)
1323 (compare (match_operand:DI 0 "nonimmediate_operand"
1325 (match_operand:DI 1 "general_operand"
1326 "d,Op,b,D,T,BQ,Q")))]
1327 "s390_match_ccmode (insn, CCUmode) && TARGET_ZARCH"
1336 [(set_attr "op_type" "RRE,RIL,RIL,SIL,RXY,SS,SS")
1337 (set_attr "cpu_facility" "*,extimm,z10,z10,*,*,*")
1338 (set_attr "type" "*,*,larl,*,*,*,*")
1339 (set_attr "z10prop" "z10_super_c,z10_super,z10_super,z10_super,z10_super,*,*")
1340 (set_attr "relative_long" "*,*,yes,*,*,*,*")])
1342 (define_insn "*cmpsi_ccu"
1343 [(set (reg CC_REGNUM)
1344 (compare (match_operand:SI 0 "nonimmediate_operand" "d, d,d,Q,d,d, Q,BQ")
1345 (match_operand:SI 1 "general_operand" "d,Os,b,D,R,T,BQ, Q")))]
1346 "s390_match_ccmode (insn, CCUmode)"
1356 [(set_attr "op_type" "RR,RIL,RIL,SIL,RX,RXY,SS,SS")
1357 (set_attr "cpu_facility" "*,extimm,z10,z10,*,longdisp,*,*")
1358 (set_attr "type" "*,*,larl,*,*,*,*,*")
1359 (set_attr "z10prop" "z10_super_c,z10_super,z10_super,z10_super,z10_super,z10_super,*,*")
1360 (set_attr "relative_long" "*,*,yes,*,*,*,*,*")])
1362 (define_insn "*cmphi_ccu"
1363 [(set (reg CC_REGNUM)
1364 (compare (match_operand:HI 0 "nonimmediate_operand" "d,d,Q,Q,BQ")
1365 (match_operand:HI 1 "general_operand" "Q,S,n,BQ,Q")))]
1366 "s390_match_ccmode (insn, CCUmode)
1367 && !register_operand (operands[1], HImode)"
1374 [(set_attr "op_type" "RS,RSY,SIL,SS,SS")
1375 (set_attr "cpu_facility" "*,longdisp,z10,*,*")
1376 (set_attr "z10prop" "*,*,z10_super,*,*")])
1378 (define_insn "*cmpqi_ccu"
1379 [(set (reg CC_REGNUM)
1380 (compare (match_operand:QI 0 "nonimmediate_operand" "d,d,Q,S,Q,BQ")
1381 (match_operand:QI 1 "general_operand" "Q,S,n,n,BQ,Q")))]
1382 "s390_match_ccmode (insn, CCUmode)
1383 && !register_operand (operands[1], QImode)"
1391 [(set_attr "op_type" "RS,RSY,SI,SIY,SS,SS")
1392 (set_attr "cpu_facility" "*,longdisp,*,longdisp,*,*")
1393 (set_attr "z10prop" "*,*,z10_super,z10_super,*,*")])
1396 ; Block compare (CLC) instruction patterns.
1399 [(set (reg CC_REGNUM)
1400 (compare (match_operand:BLK 0 "memory_operand" "Q")
1401 (match_operand:BLK 1 "memory_operand" "Q")))
1402 (use (match_operand 2 "const_int_operand" "n"))]
1403 "s390_match_ccmode (insn, CCUmode)
1404 && INTVAL (operands[2]) >= 1 && INTVAL (operands[2]) <= 256"
1405 "clc\t%O0(%2,%R0),%S1"
1406 [(set_attr "op_type" "SS")])
1409 [(set (reg CC_REGNUM)
1410 (compare (match_operand 0 "memory_operand" "")
1411 (match_operand 1 "memory_operand" "")))]
1413 && s390_match_ccmode (insn, CCUmode)
1414 && GET_MODE (operands[0]) == GET_MODE (operands[1])
1415 && GET_MODE_SIZE (GET_MODE (operands[0])) > 0"
1417 [(set (match_dup 0) (match_dup 1))
1418 (use (match_dup 2))])]
1420 operands[2] = GEN_INT (GET_MODE_SIZE (GET_MODE (operands[0])));
1421 operands[0] = adjust_address (operands[0], BLKmode, 0);
1422 operands[1] = adjust_address (operands[1], BLKmode, 0);
1424 operands[1] = gen_rtx_COMPARE (GET_MODE (SET_DEST (PATTERN (curr_insn))),
1425 operands[0], operands[1]);
1426 operands[0] = SET_DEST (PATTERN (curr_insn));
1430 ; (TF|DF|SF|TD|DD|SD) instructions
1433 ; load and test instructions turn a signaling NaN into a quiet NaN. Thus they
1434 ; may only be used if the target register is dead afterwards or if fast math
1435 ; is enabled. The former is done via a peephole optimization. Note, load and
1436 ; test instructions may only be used for (in)equality comparisons because
1437 ; relational comparisons must treat a quiet NaN like a signaling NaN which is
1438 ; not the case for load and test instructions. For fast math insn
1439 ; "cmp<mode>_ccs_0_fastmath" applies.
1440 ; See testcases load-and-test-fp-{1,2}.c
1443 [(set (match_operand:FP 0 "register_operand")
1444 (match_operand:FP 1 "const0_operand"))
1445 (set (reg:CCZ CC_REGNUM)
1446 (compare:CCZ (match_operand:FP 2 "register_operand")
1447 (match_operand:FP 3 "register_operand")))]
1449 && FP_REG_P (operands[2])
1450 && REGNO (operands[0]) == REGNO (operands[3])
1451 && peep2_reg_dead_p (2, operands[0])
1452 && peep2_reg_dead_p (2, operands[2])"
1454 [(set (reg:CCZ CC_REGNUM)
1455 (compare:CCZ (match_dup 2) (match_dup 1)))
1456 (clobber (match_dup 2))])]
1459 ; ltxbr, ltdbr, ltebr, ltxtr, ltdtr
1460 (define_insn "*cmp<mode>_ccz_0"
1461 [(set (reg:CCZ CC_REGNUM)
1462 (compare:CCZ (match_operand:FP 0 "register_operand" "f")
1463 (match_operand:FP 1 "const0_operand")))
1464 (clobber (match_operand:FP 2 "register_operand" "=0"))]
1466 "lt<xde><bt>r\t%0,%0"
1467 [(set_attr "op_type" "RRE")
1468 (set_attr "type" "fsimp<type>")])
1470 (define_insn "*cmp<mode>_ccs_0_fastmath"
1471 [(set (reg CC_REGNUM)
1472 (compare (match_operand:FP 0 "register_operand" "f")
1473 (match_operand:FP 1 "const0_operand")))]
1474 "s390_match_ccmode (insn, CCSmode)
1475 && TARGET_HARD_FLOAT
1476 && !flag_trapping_math
1477 && !flag_signaling_nans"
1478 "lt<xde><bt>r\t%0,%0"
1479 [(set_attr "op_type" "RRE")
1480 (set_attr "type" "fsimp<type>")])
1482 ; VX: TFmode in FPR pairs: use cxbr instead of wfcxb
1483 ; cxtr, cdtr, cxbr, cdbr, cebr, cdb, ceb, wfcsb, wfcdb
1484 (define_insn "*cmp<mode>_ccs"
1485 [(set (reg CC_REGNUM)
1486 (compare (match_operand:FP 0 "register_operand" "f,f,v,v")
1487 (match_operand:FP 1 "general_operand" "f,R,v,v")))]
1488 "s390_match_ccmode(insn, CCSmode) && TARGET_HARD_FLOAT"
1494 [(set_attr "op_type" "RRE,RXE,VRR,VRR")
1495 (set_attr "cpu_facility" "*,*,vx,vxe")
1496 (set_attr "enabled" "*,<DSF>,<DF>,<SF>")])
1498 ; VX: TFmode in VR: use wfcxb
1499 (define_insn "*cmptf_ccs"
1500 [(set (reg CC_REGNUM)
1501 (compare (match_operand:TF 0 "register_operand" "v")
1502 (match_operand:TF 1 "register_operand" "v")))]
1503 "s390_match_ccmode(insn, CCSmode) && TARGET_VXE"
1505 [(set_attr "op_type" "VRR")
1506 (set_attr "cpu_facility" "vxe")])
1508 ; VX: TFmode in FPR pairs: use kxbr instead of wfkxb
1509 ; kxtr, kdtr, kxbr, kdbr, kebr, kdb, keb, wfksb, wfkdb
1510 (define_insn "*cmp<mode>_ccsfps"
1511 [(set (reg CC_REGNUM)
1512 (compare (match_operand:FP 0 "register_operand" "f,f,v,v")
1513 (match_operand:FP 1 "general_operand" "f,R,v,v")))]
1514 "s390_match_ccmode (insn, CCSFPSmode) && TARGET_HARD_FLOAT"
1520 [(set_attr "op_type" "RRE,RXE,VRR,VRR")
1521 (set_attr "cpu_facility" "*,*,vx,vxe")
1522 (set_attr "enabled" "*,<DSF>,<DF>,<SF>")])
1524 ; VX: TFmode in VR: use wfkxb
1525 (define_insn "*cmptf_ccsfps"
1526 [(set (reg CC_REGNUM)
1527 (compare (match_operand:TF 0 "register_operand" "v")
1528 (match_operand:TF 1 "register_operand" "v")))]
1529 "s390_match_ccmode (insn, CCSFPSmode) && TARGET_VXE"
1531 [(set_attr "op_type" "VRR")
1532 (set_attr "cpu_facility" "vxe")])
1534 ; Compare and Branch instructions
1536 ; cij, cgij, crj, cgrj, cfi, cgfi, cr, cgr
1537 ; The following instructions do a complementary access of their second
1538 ; operand (z01 only): crj_c, cgrjc, cr, cgr
1539 (define_insn "*cmp_and_br_signed_<mode>"
1541 (if_then_else (match_operator 0 "s390_signed_integer_comparison"
1542 [(match_operand:GPR 1 "register_operand" "d,d")
1543 (match_operand:GPR 2 "nonmemory_operand" "d,C")])
1544 (label_ref (match_operand 3 "" ""))
1546 (clobber (reg:CC CC_REGNUM))]
1547 "TARGET_Z10 && !TARGET_AVOID_CMP_AND_BRANCH"
1549 if (get_attr_length (insn) == 6)
1550 return which_alternative ?
1551 "c<g>ij%C0\t%1,%c2,%l3" : "c<g>rj%C0\t%1,%2,%l3";
1553 return which_alternative ?
1554 "c<g>fi\t%1,%c2\;jg%C0\t%l3" : "c<g>r\t%1,%2\;jg%C0\t%l3";
1556 [(set_attr "op_type" "RIE")
1557 (set_attr "type" "branch")
1558 (set_attr "z10prop" "z10_super_c,z10_super")
1559 (set (attr "length")
1560 (if_then_else (lt (abs (minus (pc) (match_dup 3))) (const_int 60000))
1561 (const_int 6) (const_int 12)))]) ; 8 byte for cr/jg
1562 ; 10 byte for cgr/jg
1564 ; clij, clgij, clrj, clgrj, clfi, clgfi, clr, clgr
1565 ; The following instructions do a complementary access of their second
1566 ; operand (z10 only): clrj, clgrj, clr, clgr
1567 (define_insn "*cmp_and_br_unsigned_<mode>"
1569 (if_then_else (match_operator 0 "s390_unsigned_integer_comparison"
1570 [(match_operand:GPR 1 "register_operand" "d,d")
1571 (match_operand:GPR 2 "nonmemory_operand" "d,I")])
1572 (label_ref (match_operand 3 "" ""))
1574 (clobber (reg:CC CC_REGNUM))]
1575 "TARGET_Z10 && !TARGET_AVOID_CMP_AND_BRANCH"
1577 if (get_attr_length (insn) == 6)
1578 return which_alternative ?
1579 "cl<g>ij%C0\t%1,%b2,%l3" : "cl<g>rj%C0\t%1,%2,%l3";
1581 return which_alternative ?
1582 "cl<g>fi\t%1,%b2\;jg%C0\t%l3" : "cl<g>r\t%1,%2\;jg%C0\t%l3";
1584 [(set_attr "op_type" "RIE")
1585 (set_attr "type" "branch")
1586 (set_attr "z10prop" "z10_super_c,z10_super")
1587 (set (attr "length")
1588 (if_then_else (lt (abs (minus (pc) (match_dup 3))) (const_int 60000))
1589 (const_int 6) (const_int 12)))]) ; 8 byte for clr/jg
1590 ; 10 byte for clgr/jg
1592 ; And now the same two patterns as above but with a negated CC mask.
1594 ; cij, cgij, crj, cgrj, cfi, cgfi, cr, cgr
1595 ; The following instructions do a complementary access of their second
1596 ; operand (z01 only): crj_c, cgrjc, cr, cgr
1597 (define_insn "*icmp_and_br_signed_<mode>"
1599 (if_then_else (match_operator 0 "s390_signed_integer_comparison"
1600 [(match_operand:GPR 1 "register_operand" "d,d")
1601 (match_operand:GPR 2 "nonmemory_operand" "d,C")])
1603 (label_ref (match_operand 3 "" ""))))
1604 (clobber (reg:CC CC_REGNUM))]
1605 "TARGET_Z10 && !TARGET_AVOID_CMP_AND_BRANCH"
1607 if (get_attr_length (insn) == 6)
1608 return which_alternative ?
1609 "c<g>ij%D0\t%1,%c2,%l3" : "c<g>rj%D0\t%1,%2,%l3";
1611 return which_alternative ?
1612 "c<g>fi\t%1,%c2\;jg%D0\t%l3" : "c<g>r\t%1,%2\;jg%D0\t%l3";
1614 [(set_attr "op_type" "RIE")
1615 (set_attr "type" "branch")
1616 (set_attr "z10prop" "z10_super_c,z10_super")
1617 (set (attr "length")
1618 (if_then_else (lt (abs (minus (pc) (match_dup 3))) (const_int 60000))
1619 (const_int 6) (const_int 12)))]) ; 8 byte for cr/jg
1620 ; 10 byte for cgr/jg
1622 ; clij, clgij, clrj, clgrj, clfi, clgfi, clr, clgr
1623 ; The following instructions do a complementary access of their second
1624 ; operand (z10 only): clrj, clgrj, clr, clgr
1625 (define_insn "*icmp_and_br_unsigned_<mode>"
1627 (if_then_else (match_operator 0 "s390_unsigned_integer_comparison"
1628 [(match_operand:GPR 1 "register_operand" "d,d")
1629 (match_operand:GPR 2 "nonmemory_operand" "d,I")])
1631 (label_ref (match_operand 3 "" ""))))
1632 (clobber (reg:CC CC_REGNUM))]
1633 "TARGET_Z10 && !TARGET_AVOID_CMP_AND_BRANCH"
1635 if (get_attr_length (insn) == 6)
1636 return which_alternative ?
1637 "cl<g>ij%D0\t%1,%b2,%l3" : "cl<g>rj%D0\t%1,%2,%l3";
1639 return which_alternative ?
1640 "cl<g>fi\t%1,%b2\;jg%D0\t%l3" : "cl<g>r\t%1,%2\;jg%D0\t%l3";
1642 [(set_attr "op_type" "RIE")
1643 (set_attr "type" "branch")
1644 (set_attr "z10prop" "z10_super_c,z10_super")
1645 (set (attr "length")
1646 (if_then_else (lt (abs (minus (pc) (match_dup 3))) (const_int 60000))
1647 (const_int 6) (const_int 12)))]) ; 8 byte for clr/jg
1648 ; 10 byte for clgr/jg
1651 ;;- Move instructions.
1655 ; movti instruction pattern(s).
1659 ; Separate out the register pair alternative since constraints (P) are
1660 ; not able to deal with const_wide_int's. But predicates do.
1661 (define_insn "*movti_bigconst"
1662 [(set (match_operand:TI 0 "register_operand" "=d")
1663 (match_operand:TI 1 "reload_const_wide_int_operand" ""))]
1667 ; FIXME: More constants are possible by enabling jxx, jyy constraints
1668 ; for TImode (use double-int for the calculations)
1669 (define_insn "movti"
1670 [(set (match_operand:TI 0 "nonimmediate_operand" "=d,S,v, v, v, v, v, v,v,d,v,R,d, d, d, d, d,o")
1671 (match_operand:TI 1 "general_operand" " S,d,v,j00,jm1,jyy,jxx,jzz,d,v,R,v,K,NxHD0,Os,NxSD0,dT,d"))]
1692 [(set_attr "op_type" "RSY,RSY,VRR,VRI,VRI,VRI,VRI,VRI,VRR,*,VRX,VRX,*,*,*,*,*,*")
1693 (set_attr "type" "lm,stm,*,*,*,*,*,*,*,*,*,*,*,*,*,*,*,*")
1694 (set_attr "cpu_facility" "*,*,vx,vx,vx,vx,vx,vx,vx,vx,vx,vx,*,*,*,extimm,*,*")])
1697 [(set (match_operand:TI 0 "nonimmediate_operand" "")
1698 (match_operand:TI 1 "general_operand" ""))]
1699 "TARGET_ZARCH && reload_completed
1700 && s390_split_ok_p (operands[0], operands[1], TImode, 0)"
1701 [(set (match_dup 2) (match_dup 4))
1702 (set (match_dup 3) (match_dup 5))]
1704 operands[2] = operand_subword (operands[0], 0, 0, TImode);
1705 operands[3] = operand_subword (operands[0], 1, 0, TImode);
1706 operands[4] = operand_subword (operands[1], 0, 0, TImode);
1707 operands[5] = operand_subword (operands[1], 1, 0, TImode);
1711 [(set (match_operand:TI 0 "nonimmediate_operand" "")
1712 (match_operand:TI 1 "general_operand" ""))]
1713 "TARGET_ZARCH && reload_completed
1714 && s390_split_ok_p (operands[0], operands[1], TImode, 1)"
1715 [(set (match_dup 2) (match_dup 4))
1716 (set (match_dup 3) (match_dup 5))]
1718 operands[2] = operand_subword (operands[0], 1, 0, TImode);
1719 operands[3] = operand_subword (operands[0], 0, 0, TImode);
1720 operands[4] = operand_subword (operands[1], 1, 0, TImode);
1721 operands[5] = operand_subword (operands[1], 0, 0, TImode);
1724 ; Use part of the TImode target reg to perform the address
1725 ; calculation. If the TImode value is supposed to be copied into a VR
1726 ; this splitter is not necessary.
1728 [(set (match_operand:TI 0 "register_operand" "")
1729 (match_operand:TI 1 "memory_operand" ""))]
1730 "TARGET_ZARCH && reload_completed
1731 && !VECTOR_REG_P (operands[0])
1732 && !s_operand (operands[1], VOIDmode)"
1733 [(set (match_dup 0) (match_dup 1))]
1735 rtx addr = operand_subword (operands[0], 1, 0, TImode);
1736 addr = gen_lowpart (Pmode, addr);
1737 s390_load_address (addr, XEXP (operands[1], 0));
1738 operands[1] = replace_equiv_address (operands[1], addr);
1742 ; Split a VR -> GPR TImode move into 2 vector load GR from VR element.
1743 ; For the higher order bits we do simply a DImode move while the
1744 ; second part is done via vec extract. Both will end up as vlgvg.
1746 [(set (match_operand:TI 0 "register_operand" "")
1747 (match_operand:TI 1 "register_operand" ""))]
1748 "TARGET_VX && reload_completed
1749 && GENERAL_REG_P (operands[0])
1750 && VECTOR_REG_P (operands[1])"
1751 [(set (match_dup 2) (match_dup 4))
1752 (set (match_dup 3) (vec_select:DI (match_dup 5)
1753 (parallel [(const_int 1)])))]
1755 operands[2] = operand_subword (operands[0], 0, 0, TImode);
1756 operands[3] = operand_subword (operands[0], 1, 0, TImode);
1757 operands[4] = gen_rtx_REG (DImode, REGNO (operands[1]));
1758 operands[5] = gen_rtx_REG (V2DImode, REGNO (operands[1]));
1762 ; Patterns used for secondary reloads
1765 ; z10 provides move instructions accepting larl memory operands.
1766 ; Unfortunately there is no such variant for QI, TI and FP mode moves.
1767 ; These patterns are also used for unaligned SI and DI accesses.
1769 (define_expand "reload<ALL:mode><P:mode>_tomem_z10"
1770 [(parallel [(match_operand:ALL 0 "memory_operand" "")
1771 (match_operand:ALL 1 "register_operand" "=d")
1772 (match_operand:P 2 "register_operand" "=&a")])]
1775 s390_reload_symref_address (operands[1], operands[0], operands[2], 1);
1779 (define_expand "reload<ALL:mode><P:mode>_toreg_z10"
1780 [(parallel [(match_operand:ALL 0 "register_operand" "=d")
1781 (match_operand:ALL 1 "memory_operand" "")
1782 (match_operand:P 2 "register_operand" "=a")])]
1785 s390_reload_symref_address (operands[0], operands[1], operands[2], 0);
1789 (define_expand "reload<P:mode>_larl_odd_addend_z10"
1790 [(parallel [(match_operand:P 0 "register_operand" "=d")
1791 (match_operand:P 1 "larl_operand" "")
1792 (match_operand:P 2 "register_operand" "=a")])]
1795 s390_reload_larl_operand (operands[0], operands[1], operands[2]);
1799 ; Handles loading a PLUS (load address) expression
1801 (define_expand "reload<mode>_plus"
1802 [(parallel [(match_operand:P 0 "register_operand" "=a")
1803 (match_operand:P 1 "s390_plus_operand" "")
1804 (match_operand:P 2 "register_operand" "=&a")])]
1807 s390_expand_plus_operand (operands[0], operands[1], operands[2]);
1811 ; Not all the indirect memory access instructions support the full
1812 ; format (long disp + index + base). So whenever a move from/to such
1813 ; an address is required and the instruction cannot deal with it we do
1814 ; a load address into a scratch register first and use this as the new
1816 ; This in particular is used for:
1817 ; - non-offsetable memory accesses for multiword moves
1818 ; - full vector reg moves with long displacements
1820 (define_expand "reload<mode>_la_in"
1821 [(parallel [(match_operand 0 "register_operand" "")
1822 (match_operand 1 "" "")
1823 (match_operand:P 2 "register_operand" "=&a")])]
1826 gcc_assert (MEM_P (operands[1]));
1827 s390_load_address (operands[2], find_replacement (&XEXP (operands[1], 0)));
1828 operands[1] = replace_equiv_address (operands[1], operands[2]);
1829 emit_move_insn (operands[0], operands[1]);
1833 (define_expand "reload<mode>_la_out"
1834 [(parallel [(match_operand 0 "" "")
1835 (match_operand 1 "register_operand" "")
1836 (match_operand:P 2 "register_operand" "=&a")])]
1839 gcc_assert (MEM_P (operands[0]));
1840 s390_load_address (operands[2], find_replacement (&XEXP (operands[0], 0)));
1841 operands[0] = replace_equiv_address (operands[0], operands[2]);
1842 emit_move_insn (operands[0], operands[1]);
1846 (define_expand "reload<mode>_PIC_addr"
1847 [(parallel [(match_operand 0 "register_operand" "=d")
1848 (match_operand 1 "larl_operand" "")
1849 (match_operand:P 2 "register_operand" "=a")])]
1852 rtx new_rtx = legitimize_pic_address (operands[1], operands[2]);
1853 emit_move_insn (operands[0], new_rtx);
1857 ; movdi instruction pattern(s).
1860 (define_expand "movdi"
1861 [(set (match_operand:DI 0 "general_operand" "")
1862 (match_operand:DI 1 "general_operand" ""))]
1865 /* Handle symbolic constants. */
1867 && (SYMBOLIC_CONST (operands[1])
1868 || (GET_CODE (operands[1]) == PLUS
1869 && XEXP (operands[1], 0) == pic_offset_table_rtx
1870 && SYMBOLIC_CONST (XEXP (operands[1], 1)))))
1871 emit_symbolic_move (operands);
1874 (define_insn "*movdi_64"
1875 [(set (match_operand:DI 0 "nonimmediate_operand"
1876 "=d, d, d, d, d, d, d, d,f,d,!*f,d,d,d,d,T,!*f,!*f,!*f,!R,!T,b,Q,d,t,Q,t,v,v,v,d,v,R,d")
1877 (match_operand:DI 1 "general_operand"
1878 " K,N0HD0,N1HD0,N2HD0,N3HD0,Os,N0SD0,N1SD0,d,f,j00,L,b,d,T,d, *f, R, T,*f,*f,d,K,t,d,t,Q,K,v,d,v,R,v,ZL"))]
1915 [(set_attr "op_type" "RI,RI,RI,RI,RI,RIL,RIL,RIL,RRE,RRE,RRE,RXY,RIL,RRE,RXY,
1916 RXY,RR,RX,RXY,RX,RXY,RIL,SIL,*,*,RS,RS,VRI,VRR,VRS,VRS,
1918 (set_attr "type" "*,*,*,*,*,*,*,*,floaddf,floaddf,fsimpdf,la,larl,lr,load,store,
1919 floaddf,floaddf,floaddf,fstoredf,fstoredf,larl,*,*,*,*,
1920 *,*,*,*,*,*,*,larl")
1921 (set_attr "cpu_facility" "*,*,*,*,*,extimm,extimm,extimm,dfp,dfp,*,longdisp,
1922 z10,*,*,*,*,*,longdisp,*,longdisp,
1923 z10,z10,*,*,*,*,vx,vx,vx,vx,vx,vx,*")
1924 (set_attr "z10prop" "z10_fwd_A1,
1952 (set_attr "relative_long" "*,*,*,*,*,*,*,*,*,*,*,
1953 *,yes,*,*,*,*,*,*,*,*,
1954 yes,*,*,*,*,*,*,*,*,*,
1958 ; Splitters for loading TLS pointer from UNSPEC_GET_TP.
1959 ; UNSPEC_GET_TP is used instead of %a0:P, since the latter is a hard register,
1960 ; and those are not handled by Partial Redundancy Elimination (gcse.cc), which
1961 ; results in generation of redundant thread pointer loads.
1963 (define_insn_and_split "*get_tp_31"
1964 [(set (match_operand:SI 0 "register_operand" "=r")
1965 (unspec:SI [(match_operand:SI 1 "register_operand" "t")]
1969 "&& reload_completed"
1970 [(set (match_dup 0) (match_dup 1))])
1972 (define_insn_and_split "*get_tp_64"
1973 [(set (match_operand:DI 0 "register_operand" "=r")
1974 (unspec:DI [(match_operand:DI 1 "register_operand" "t")]
1978 "&& reload_completed"
1979 [(set (match_dup 2) (match_dup 3))
1980 (set (match_dup 0) (ashift:DI (match_dup 0) (const_int 32)))
1981 (set (strict_low_part (match_dup 2)) (match_dup 4))]
1982 "operands[2] = gen_lowpart (SImode, operands[0]);
1983 s390_split_access_reg (operands[1], &operands[4], &operands[3]);")
1985 ; Splitters for storing TLS pointer to %a0:DI.
1988 [(set (match_operand:DI 0 "register_operand" "")
1989 (match_operand:DI 1 "register_operand" ""))]
1990 "TARGET_ZARCH && ACCESS_REG_P (operands[0]) && reload_completed
1991 && dead_or_set_p (insn, operands[1])"
1992 [(set (match_dup 3) (match_dup 2))
1993 (set (match_dup 1) (lshiftrt:DI (match_dup 1) (const_int 32)))
1994 (set (match_dup 4) (match_dup 2))]
1995 "operands[2] = gen_lowpart (SImode, operands[1]);
1996 s390_split_access_reg (operands[0], &operands[3], &operands[4]);")
1999 [(set (match_operand:DI 0 "register_operand" "")
2000 (match_operand:DI 1 "register_operand" ""))]
2001 "TARGET_ZARCH && ACCESS_REG_P (operands[0]) && reload_completed
2002 && !dead_or_set_p (insn, operands[1])"
2003 [(set (match_dup 3) (match_dup 2))
2004 (set (match_dup 1) (rotate:DI (match_dup 1) (const_int 32)))
2005 (set (match_dup 4) (match_dup 2))
2006 (set (match_dup 1) (rotate:DI (match_dup 1) (const_int 32)))]
2007 "operands[2] = gen_lowpart (SImode, operands[1]);
2008 s390_split_access_reg (operands[0], &operands[3], &operands[4]);")
2010 (define_insn "*movdi_31"
2011 [(set (match_operand:DI 0 "nonimmediate_operand"
2012 "=d,d,Q,S,d ,o,!*f,!*f,!*f,!*f,!R,!T,d")
2013 (match_operand:DI 1 "general_operand"
2014 " Q,S,d,d,dPT,d, *f, R, T,j00,*f,*f,b"))]
2030 [(set_attr "op_type" "RS,RSY,RS,RSY,*,*,RR,RX,RXY,RRE,RX,RXY,*")
2031 (set_attr "type" "lm,lm,stm,stm,*,*,floaddf,floaddf,floaddf,fsimpdf,fstoredf,fstoredf,*")
2032 (set_attr "cpu_facility" "*,longdisp,*,longdisp,*,*,*,*,longdisp,*,*,longdisp,z10")])
2034 ; For a load from a symbol ref we can use one of the target registers
2035 ; together with larl to load the address.
2037 [(set (match_operand:DI 0 "register_operand" "")
2038 (match_operand:DI 1 "memory_operand" ""))]
2039 "!TARGET_ZARCH && reload_completed && TARGET_Z10
2040 && larl_operand (XEXP (operands[1], 0), SImode)"
2041 [(set (match_dup 2) (match_dup 3))
2042 (set (match_dup 0) (match_dup 1))]
2044 operands[2] = operand_subword (operands[0], 1, 0, DImode);
2045 operands[3] = XEXP (operands[1], 0);
2046 operands[1] = replace_equiv_address (operands[1], operands[2]);
2050 [(set (match_operand:DI 0 "nonimmediate_operand" "")
2051 (match_operand:DI 1 "general_operand" ""))]
2052 "!TARGET_ZARCH && reload_completed
2053 && !s_operand (operands[0], DImode)
2054 && !s_operand (operands[1], DImode)
2055 && s390_split_ok_p (operands[0], operands[1], DImode, 0)"
2056 [(set (match_dup 2) (match_dup 4))
2057 (set (match_dup 3) (match_dup 5))]
2059 operands[2] = operand_subword (operands[0], 0, 0, DImode);
2060 operands[3] = operand_subword (operands[0], 1, 0, DImode);
2061 operands[4] = operand_subword (operands[1], 0, 0, DImode);
2062 operands[5] = operand_subword (operands[1], 1, 0, DImode);
2066 [(set (match_operand:DI 0 "nonimmediate_operand" "")
2067 (match_operand:DI 1 "general_operand" ""))]
2068 "!TARGET_ZARCH && reload_completed
2069 && !s_operand (operands[0], DImode)
2070 && !s_operand (operands[1], DImode)
2071 && s390_split_ok_p (operands[0], operands[1], DImode, 1)"
2072 [(set (match_dup 2) (match_dup 4))
2073 (set (match_dup 3) (match_dup 5))]
2075 operands[2] = operand_subword (operands[0], 1, 0, DImode);
2076 operands[3] = operand_subword (operands[0], 0, 0, DImode);
2077 operands[4] = operand_subword (operands[1], 1, 0, DImode);
2078 operands[5] = operand_subword (operands[1], 0, 0, DImode);
2082 [(set (match_operand:DI 0 "register_operand" "")
2083 (match_operand:DI 1 "memory_operand" ""))]
2084 "!TARGET_ZARCH && reload_completed
2085 && !FP_REG_P (operands[0])
2086 && !s_operand (operands[1], VOIDmode)"
2087 [(set (match_dup 0) (match_dup 1))]
2089 rtx addr = operand_subword (operands[0], 1, 0, DImode);
2090 s390_load_address (addr, XEXP (operands[1], 0));
2091 operands[1] = replace_equiv_address (operands[1], addr);
2095 [(set (match_operand:DI 0 "register_operand" "")
2096 (mem:DI (match_operand 1 "address_operand" "")))]
2098 && !FP_REG_P (operands[0])
2099 && GET_CODE (operands[1]) == SYMBOL_REF
2100 && CONSTANT_POOL_ADDRESS_P (operands[1])
2101 && get_pool_mode (operands[1]) == DImode
2102 && legitimate_reload_constant_p (get_pool_constant (operands[1]))"
2103 [(set (match_dup 0) (match_dup 2))]
2104 "operands[2] = get_pool_constant (operands[1]);")
2106 (define_insn "*la_64"
2107 [(set (match_operand:DI 0 "register_operand" "=d,d")
2108 (match_operand:QI 1 "address_operand" "ZR,ZT"))]
2113 [(set_attr "op_type" "RX,RXY")
2114 (set_attr "type" "la")
2115 (set_attr "cpu_facility" "*,longdisp")
2116 (set_attr "z10prop" "z10_fwd_A1,z10_fwd_A1")])
2120 [(set (match_operand:DI 0 "register_operand" "")
2121 (match_operand:QI 1 "address_operand" ""))
2122 (clobber (reg:CC CC_REGNUM))])]
2124 && preferred_la_operand_p (operands[1], const0_rtx)"
2125 [(set (match_dup 0) (match_dup 1))]
2129 [(set (match_operand:DI 0 "register_operand" "")
2130 (match_operand:DI 1 "register_operand" ""))
2133 (plus:DI (match_dup 0)
2134 (match_operand:DI 2 "nonmemory_operand" "")))
2135 (clobber (reg:CC CC_REGNUM))])]
2137 && !reg_overlap_mentioned_p (operands[0], operands[2])
2138 && preferred_la_operand_p (operands[1], operands[2])"
2139 [(set (match_dup 0) (plus:DI (match_dup 1) (match_dup 2)))]
2142 ; Split loading of 64-bit constants into GPRs into llihf + oilf -
2143 ; counterintuitively, using oilf is faster than iilf. oilf clobbers
2144 ; cc, so cc must be dead.
2146 [(set (match_operand:DI 0 "register_operand" "")
2147 (match_operand:DI 1 "memory_operand" ""))]
2150 && GENERAL_REG_P (operands[0])
2151 && s390_const_int_pool_entry_p (operands[1], nullptr)
2152 && peep2_reg_dead_p (1, gen_rtx_REG (CCmode, CC_REGNUM))"
2153 [(set (match_dup 0) (match_dup 2))
2155 [(set (match_dup 0) (ior:DI (match_dup 0) (match_dup 3)))
2156 (clobber (reg:CC CC_REGNUM))])]
2159 bool ok = s390_const_int_pool_entry_p (operands[1], &val);
2161 operands[2] = GEN_INT (val & 0xFFFFFFFF00000000ULL);
2162 operands[3] = GEN_INT (val & 0x00000000FFFFFFFFULL);
2163 if (operands[2] == const0_rtx)
2165 emit_move_insn (operands[0], operands[3]);
2168 else if (operands[3] == const0_rtx)
2170 emit_move_insn (operands[0], operands[2]);
2176 ; movsi instruction pattern(s).
2179 (define_expand "movsi"
2180 [(set (match_operand:SI 0 "general_operand" "")
2181 (match_operand:SI 1 "general_operand" ""))]
2184 /* Handle symbolic constants. */
2186 && (SYMBOLIC_CONST (operands[1])
2187 || (GET_CODE (operands[1]) == PLUS
2188 && XEXP (operands[1], 0) == pic_offset_table_rtx
2189 && SYMBOLIC_CONST (XEXP(operands[1], 1)))))
2190 emit_symbolic_move (operands);
2193 (define_insn "*movsi_larl"
2194 [(set (match_operand:SI 0 "register_operand" "=d")
2195 (match_operand:SI 1 "larl_operand" "X"))]
2197 && !FP_REG_P (operands[0])"
2199 [(set_attr "op_type" "RIL")
2200 (set_attr "type" "larl")
2201 (set_attr "z10prop" "z10_fwd_A1")
2202 (set_attr "relative_long" "yes")])
2204 (define_insn "*movsi_zarch"
2205 [(set (match_operand:SI 0 "nonimmediate_operand"
2206 "=d, d, d, d,d,d,d,d,d,R,T,!*f,!*f,!*f,!*f,!*f,!R,!T,d,t,Q,b,Q,t,v,v,v,d,v,R")
2207 (match_operand:SI 1 "general_operand"
2208 " K,N0HS0,N1HS0,Os,L,b,d,R,T,d,d, *f, *f, R, R, T,*f,*f,t,d,t,d,K,Q,K,v,d,v,R,v"))]
2241 [(set_attr "op_type" "RI,RI,RI,RIL,RXY,RIL,RR,RX,RXY,RX,RXY,
2242 RR,RR,RXE,RX,RXY,RX,RXY,RRE,RRE,RS,RIL,SIL,RS,VRI,VRR,VRS,VRS,VRX,VRX")
2243 (set_attr "type" "*,
2267 (set_attr "cpu_facility" "*,*,*,extimm,longdisp,z10,*,*,longdisp,*,longdisp,
2268 vx,*,vx,*,longdisp,*,longdisp,*,*,*,z10,z10,*,vx,vx,vx,vx,vx,vx")
2269 (set_attr "z10prop" "z10_fwd_A1,
2293 (set_attr "relative_long" "*,*,*,*,*,yes,*,*,*,*,
2294 *,*,*,*,*,*,*,*,*,*,
2295 *,yes,*,*,*,*,*,*,*,*")])
2297 (define_insn "*movsi_esa"
2298 [(set (match_operand:SI 0 "nonimmediate_operand" "=d,d,d,R,!*f,!*f,!*f,!*f,!R,d,t,Q,t")
2299 (match_operand:SI 1 "general_operand" "K,d,R,d, *f, *f, R, R,*f,t,d,t,Q"))]
2315 [(set_attr "op_type" "RI,RR,RX,RX,RR,RR,RXE,RX,RX,RRE,RRE,RS,RS")
2316 (set_attr "type" "*,lr,load,store,floadsf,floadsf,floadsf,floadsf,fstoresf,*,*,*,*")
2317 (set_attr "z10prop" "z10_fwd_A1,z10_fr_E1,z10_fwd_A3,z10_rec,*,*,*,*,*,z10_super_E1,
2319 (set_attr "cpu_facility" "*,*,*,*,vx,*,vx,*,*,*,*,*,*")
2323 [(set (match_operand:SI 0 "register_operand" "")
2324 (mem:SI (match_operand 1 "address_operand" "")))]
2325 "!FP_REG_P (operands[0])
2326 && GET_CODE (operands[1]) == SYMBOL_REF
2327 && CONSTANT_POOL_ADDRESS_P (operands[1])
2328 && get_pool_mode (operands[1]) == SImode
2329 && legitimate_reload_constant_p (get_pool_constant (operands[1]))"
2330 [(set (match_dup 0) (match_dup 2))]
2331 "operands[2] = get_pool_constant (operands[1]);")
2333 (define_insn "*la_31"
2334 [(set (match_operand:SI 0 "register_operand" "=d,d")
2335 (match_operand:QI 1 "address_operand" "ZR,ZT"))]
2336 "!TARGET_64BIT && legitimate_la_operand_p (operands[1])"
2340 [(set_attr "op_type" "RX,RXY")
2341 (set_attr "type" "la")
2342 (set_attr "cpu_facility" "*,longdisp")
2343 (set_attr "z10prop" "z10_fwd_A1,z10_fwd_A1")])
2347 [(set (match_operand:SI 0 "register_operand" "")
2348 (match_operand:QI 1 "address_operand" ""))
2349 (clobber (reg:CC CC_REGNUM))])]
2351 && preferred_la_operand_p (operands[1], const0_rtx)"
2352 [(set (match_dup 0) (match_dup 1))]
2356 [(set (match_operand:SI 0 "register_operand" "")
2357 (match_operand:SI 1 "register_operand" ""))
2360 (plus:SI (match_dup 0)
2361 (match_operand:SI 2 "nonmemory_operand" "")))
2362 (clobber (reg:CC CC_REGNUM))])]
2364 && !reg_overlap_mentioned_p (operands[0], operands[2])
2365 && preferred_la_operand_p (operands[1], operands[2])"
2366 [(set (match_dup 0) (plus:SI (match_dup 1) (match_dup 2)))]
2369 (define_insn "*la_31_and"
2370 [(set (match_operand:SI 0 "register_operand" "=d,d")
2371 (and:SI (match_operand:QI 1 "address_operand" "ZR,ZT")
2372 (const_int 2147483647)))]
2377 [(set_attr "op_type" "RX,RXY")
2378 (set_attr "type" "la")
2379 (set_attr "cpu_facility" "*,longdisp")
2380 (set_attr "z10prop" "z10_fwd_A1,z10_fwd_A1")])
2382 (define_insn_and_split "*la_31_and_cc"
2383 [(set (match_operand:SI 0 "register_operand" "=d")
2384 (and:SI (match_operand:QI 1 "address_operand" "p")
2385 (const_int 2147483647)))
2386 (clobber (reg:CC CC_REGNUM))]
2389 "&& reload_completed"
2391 (and:SI (match_dup 1) (const_int 2147483647)))]
2393 [(set_attr "op_type" "RX")
2394 (set_attr "type" "la")])
2396 (define_insn "force_la_31"
2397 [(set (match_operand:SI 0 "register_operand" "=d,d")
2398 (match_operand:QI 1 "address_operand" "ZR,ZT"))
2399 (use (const_int 0))]
2404 [(set_attr "op_type" "RX")
2405 (set_attr "type" "la")
2406 (set_attr "cpu_facility" "*,longdisp")
2407 (set_attr "z10prop" "z10_fwd_A1,z10_fwd_A1")])
2410 ; movhi instruction pattern(s).
2413 (define_expand "movhi"
2414 [(set (match_operand:HI 0 "nonimmediate_operand" "")
2415 (match_operand:HI 1 "general_operand" ""))]
2418 /* Make it explicit that loading a register from memory
2419 always sign-extends (at least) to SImode. */
2420 if (optimize && can_create_pseudo_p ()
2421 && register_operand (operands[0], VOIDmode)
2422 && GET_CODE (operands[1]) == MEM)
2424 rtx tmp = gen_reg_rtx (SImode);
2425 rtx ext = gen_rtx_SIGN_EXTEND (SImode, operands[1]);
2426 emit_insn (gen_rtx_SET (tmp, ext));
2427 operands[1] = gen_lowpart (HImode, tmp);
2431 (define_insn "*movhi"
2432 [(set (match_operand:HI 0 "nonimmediate_operand" "=d,d,d,d,d,R,T,b,Q,v,v,v,d,v,R")
2433 (match_operand:HI 1 "general_operand" " d,n,R,T,b,d,d,d,K,K,v,d,v,R,v"))]
2451 [(set_attr "op_type" "RR,RI,RX,RXY,RIL,RX,RXY,RIL,SIL,VRI,VRR,VRS,VRS,VRX,VRX")
2452 (set_attr "type" "lr,*,*,*,larl,store,store,store,*,*,*,*,*,*,*")
2453 (set_attr "cpu_facility" "*,*,*,longdisp,z10,*,longdisp,z10,z10,vx,vx,vx,vx,vx,vx")
2454 (set_attr "z10prop" "z10_fr_E1,
2462 z10_super,*,*,*,*,*,*")
2463 (set_attr "relative_long" "*,*,*,*,yes,*,*,yes,*,*,*,*,*,*,*")])
2466 [(set (match_operand:HI 0 "register_operand" "")
2467 (mem:HI (match_operand 1 "address_operand" "")))]
2468 "GET_CODE (operands[1]) == SYMBOL_REF
2469 && CONSTANT_POOL_ADDRESS_P (operands[1])
2470 && get_pool_mode (operands[1]) == HImode
2471 && GET_CODE (get_pool_constant (operands[1])) == CONST_INT"
2472 [(set (match_dup 0) (match_dup 2))]
2473 "operands[2] = get_pool_constant (operands[1]);")
2476 ; movqi instruction pattern(s).
2479 (define_expand "movqi"
2480 [(set (match_operand:QI 0 "nonimmediate_operand" "")
2481 (match_operand:QI 1 "general_operand" ""))]
2484 /* On z/Architecture, zero-extending from memory to register
2485 is just as fast as a QImode load. */
2486 if (TARGET_ZARCH && optimize && can_create_pseudo_p ()
2487 && register_operand (operands[0], VOIDmode)
2488 && GET_CODE (operands[1]) == MEM)
2490 rtx tmp = gen_reg_rtx (DImode);
2491 rtx ext = gen_rtx_ZERO_EXTEND (DImode, operands[1]);
2492 emit_insn (gen_rtx_SET (tmp, ext));
2493 operands[1] = gen_lowpart (QImode, tmp);
2497 (define_insn "*movqi"
2498 [(set (match_operand:QI 0 "nonimmediate_operand" "=d,d,d,d,R,T,Q,S,?Q,v,v,v,d,v,R")
2499 (match_operand:QI 1 "general_operand" " d,n,R,T,d,d,n,n,?Q,K,v,d,v,R,v"))]
2517 [(set_attr "op_type" "RR,RI,RX,RXY,RX,RXY,SI,SIY,SS,VRI,VRR,VRS,VRS,VRX,VRX")
2518 (set_attr "type" "lr,*,*,*,store,store,store,store,*,*,*,*,*,*,*")
2519 (set_attr "cpu_facility" "*,*,*,longdisp,*,longdisp,*,longdisp,*,vx,vx,vx,vx,vx,vx")
2520 (set_attr "z10prop" "z10_fr_E1,
2531 [(set (match_operand:QI 0 "nonimmediate_operand" "")
2532 (mem:QI (match_operand 1 "address_operand" "")))]
2533 "GET_CODE (operands[1]) == SYMBOL_REF
2534 && CONSTANT_POOL_ADDRESS_P (operands[1])
2535 && get_pool_mode (operands[1]) == QImode
2536 && GET_CODE (get_pool_constant (operands[1])) == CONST_INT"
2537 [(set (match_dup 0) (match_dup 2))]
2538 "operands[2] = get_pool_constant (operands[1]);")
2542 ; movstrict instruction pattern(s).
2545 (define_insn "movstrictqi"
2546 [(set (strict_low_part (match_operand:QI 0 "subreg_register_operand" "+d,d"))
2547 (match_operand:QI 1 "memory_operand" "R,T"))]
2552 [(set_attr "op_type" "RX,RXY")
2553 (set_attr "cpu_facility" "*,longdisp")
2554 (set_attr "z10prop" "z10_super_E1,z10_super_E1")])
2556 (define_insn "movstricthi"
2557 [(set (strict_low_part (match_operand:HI 0 "subreg_register_operand" "+d,d"))
2558 (match_operand:HI 1 "memory_operand" "Q,S"))
2559 (clobber (reg:CC CC_REGNUM))]
2564 [(set_attr "op_type" "RS,RSY")
2565 (set_attr "cpu_facility" "*,longdisp")
2566 (set_attr "z10prop" "z10_super_E1,z10_super_E1")])
2568 (define_insn "movstrictsi"
2569 [(set (strict_low_part (match_operand:SI 0 "subreg_register_operand" "+d,d,d,d"))
2570 (match_operand:SI 1 "general_operand" "d,R,T,t"))]
2577 [(set_attr "op_type" "RR,RX,RXY,RRE")
2578 (set_attr "type" "lr,load,load,*")
2579 (set_attr "cpu_facility" "*,*,longdisp,*")
2580 (set_attr "z10prop" "z10_fr_E1,z10_fwd_A3,z10_fwd_A3,z10_super_E1")])
2583 ; mov(tf|td) instruction pattern(s).
2586 (define_expand "mov<mode><tf_fpr>"
2587 [(set (match_operand:TD_TF 0 "nonimmediate_operand" "")
2588 (match_operand:TD_TF 1 "general_operand" ""))]
2592 (define_insn "*mov<mode>_64"
2593 [(set (match_operand:TD_TF 0 "nonimmediate_operand" "=f,f,f,o,d,S, d,o")
2594 (match_operand:TD_TF 1 "general_operand" " G,f,o,f,S,d,dT,d"))]
2605 [(set_attr "op_type" "RRE,RRE,*,*,RSY,RSY,*,*")
2606 (set_attr "type" "fsimptf,fsimptf,*,*,lm,stm,*,*")
2607 (set_attr "cpu_facility" "z196,*,*,*,*,*,*,*")])
2609 (define_insn "*mov<mode>_31"
2610 [(set (match_operand:TD_TF 0 "nonimmediate_operand" "=f,f,f,o")
2611 (match_operand:TD_TF 1 "general_operand" " G,f,o,f"))]
2618 [(set_attr "op_type" "RRE,RRE,*,*")
2619 (set_attr "type" "fsimptf,fsimptf,*,*")
2620 (set_attr "cpu_facility" "z196,*,*,*")])
2622 ; TFmode in GPRs splitters
2625 [(set (match_operand:TD_TF 0 "nonimmediate_operand" "")
2626 (match_operand:TD_TF 1 "general_operand" ""))]
2627 "TARGET_ZARCH && reload_completed
2628 && !s_operand (operands[0], <MODE>mode)
2629 && !s_operand (operands[1], <MODE>mode)
2630 && s390_split_ok_p (operands[0], operands[1], <MODE>mode, 0)"
2631 [(set (match_dup 2) (match_dup 4))
2632 (set (match_dup 3) (match_dup 5))]
2634 operands[2] = operand_subword (operands[0], 0, 0, <MODE>mode);
2635 operands[3] = operand_subword (operands[0], 1, 0, <MODE>mode);
2636 operands[4] = operand_subword (operands[1], 0, 0, <MODE>mode);
2637 operands[5] = operand_subword (operands[1], 1, 0, <MODE>mode);
2641 [(set (match_operand:TD_TF 0 "nonimmediate_operand" "")
2642 (match_operand:TD_TF 1 "general_operand" ""))]
2643 "TARGET_ZARCH && reload_completed
2644 && !s_operand (operands[0], <MODE>mode)
2645 && !s_operand (operands[1], <MODE>mode)
2646 && s390_split_ok_p (operands[0], operands[1], <MODE>mode, 1)"
2647 [(set (match_dup 2) (match_dup 4))
2648 (set (match_dup 3) (match_dup 5))]
2650 operands[2] = operand_subword (operands[0], 1, 0, <MODE>mode);
2651 operands[3] = operand_subword (operands[0], 0, 0, <MODE>mode);
2652 operands[4] = operand_subword (operands[1], 1, 0, <MODE>mode);
2653 operands[5] = operand_subword (operands[1], 0, 0, <MODE>mode);
2657 [(set (match_operand:TD_TF 0 "register_operand" "")
2658 (match_operand:TD_TF 1 "memory_operand" ""))]
2659 "TARGET_ZARCH && reload_completed
2660 && GENERAL_REG_P (operands[0])
2661 && !s_operand (operands[1], VOIDmode)"
2662 [(set (match_dup 0) (match_dup 1))]
2664 rtx addr = operand_subword (operands[0], 1, 0, <MODE>mode);
2665 addr = gen_lowpart (Pmode, addr);
2666 s390_load_address (addr, XEXP (operands[1], 0));
2667 operands[1] = replace_equiv_address (operands[1], addr);
2670 ; TFmode in BFPs splitters
2673 [(set (match_operand:TD_TF 0 "register_operand" "")
2674 (match_operand:TD_TF 1 "memory_operand" ""))]
2675 "reload_completed && offsettable_memref_p (operands[1])
2676 && FP_REG_P (operands[0])"
2677 [(set (match_dup 2) (match_dup 4))
2678 (set (match_dup 3) (match_dup 5))]
2680 operands[2] = simplify_gen_subreg (<HALF_TMODE>mode, operands[0],
2682 operands[3] = simplify_gen_subreg (<HALF_TMODE>mode, operands[0],
2684 operands[4] = adjust_address_nv (operands[1], <HALF_TMODE>mode, 0);
2685 operands[5] = adjust_address_nv (operands[1], <HALF_TMODE>mode, 8);
2689 [(set (match_operand:TD_TF 0 "memory_operand" "")
2690 (match_operand:TD_TF 1 "register_operand" ""))]
2691 "reload_completed && offsettable_memref_p (operands[0])
2692 && FP_REG_P (operands[1])"
2693 [(set (match_dup 2) (match_dup 4))
2694 (set (match_dup 3) (match_dup 5))]
2696 operands[2] = adjust_address_nv (operands[0], <HALF_TMODE>mode, 0);
2697 operands[3] = adjust_address_nv (operands[0], <HALF_TMODE>mode, 8);
2698 operands[4] = simplify_gen_subreg (<HALF_TMODE>mode, operands[1],
2700 operands[5] = simplify_gen_subreg (<HALF_TMODE>mode, operands[1],
2705 ; mov(df|dd) instruction pattern(s).
2708 (define_expand "mov<mode>"
2709 [(set (match_operand:DD_DF 0 "nonimmediate_operand" "")
2710 (match_operand:DD_DF 1 "general_operand" ""))]
2714 (define_insn "*mov<mode>_64dfp"
2715 [(set (match_operand:DD_DF 0 "nonimmediate_operand"
2716 "=f,f,f,d,f,f,R,T,d,d,d,d,b,T,v,v,v,d,v,R")
2717 (match_operand:DD_DF 1 "general_operand"
2718 " G,f,d,f,R,T,f,f,G,d,b,T,d,d,v,G,d,v,R,v"))]
2741 [(set_attr "op_type" "RRE,RR,RRE,RRE,RX,RXY,RX,RXY,RI,RRE,RIL,RXY,RIL,RXY,VRR,VRI,VRS,VRS,VRX,VRX")
2742 (set_attr "type" "fsimpdf,floaddf,floaddf,floaddf,floaddf,floaddf,
2743 fstoredf,fstoredf,*,lr,load,load,store,store,*,*,*,*,load,store")
2744 (set_attr "z10prop" "*,*,*,*,*,*,*,*,z10_fwd_A1,z10_fr_E1,z10_fwd_A3,z10_fwd_A3,z10_rec,z10_rec,*,*,*,*,*,*")
2745 (set_attr "cpu_facility" "z196,*,*,*,*,longdisp,*,longdisp,*,*,z10,*,z10,*,vx,vx,vx,vx,vx,vx")
2746 (set_attr "relative_long" "*,*,*,*,*,*,*,*,*,*,yes,*,yes,*,*,*,*,*,*,*")])
2748 (define_insn "*mov<mode>_64"
2749 [(set (match_operand:DD_DF 0 "nonimmediate_operand" "=f,f,f,f,R,T,d,d,d,d,b,T")
2750 (match_operand:DD_DF 1 "general_operand" " G,f,R,T,f,f,G,d,b,T,d,d"))]
2765 [(set_attr "op_type" "RRE,RR,RX,RXY,RX,RXY,RI,RRE,RIL,RXY,RIL,RXY")
2766 (set_attr "type" "fsimpdf,fload<mode>,fload<mode>,fload<mode>,
2767 fstore<mode>,fstore<mode>,*,lr,load,load,store,store")
2768 (set_attr "z10prop" "*,*,*,*,*,*,z10_fwd_A1,z10_fr_E1,z10_fwd_A3,z10_fwd_A3,z10_rec,z10_rec")
2769 (set_attr "cpu_facility" "z196,*,*,longdisp,*,longdisp,*,*,z10,*,z10,*")
2770 (set_attr "relative_long" "*,*,*,*,*,*,*,*,yes,*,*,*")])
2772 (define_insn "*mov<mode>_31"
2773 [(set (match_operand:DD_DF 0 "nonimmediate_operand"
2774 "=f,f,f,f,R,T,d,d,Q,S, d,o")
2775 (match_operand:DD_DF 1 "general_operand"
2776 " G,f,R,T,f,f,Q,S,d,d,dPT,d"))]
2791 [(set_attr "op_type" "RRE,RR,RX,RXY,RX,RXY,RS,RSY,RS,RSY,*,*")
2792 (set_attr "type" "fsimpdf,fload<mode>,fload<mode>,fload<mode>,
2793 fstore<mode>,fstore<mode>,lm,lm,stm,stm,*,*")
2794 (set_attr "cpu_facility" "z196,*,*,longdisp,*,longdisp,*,longdisp,*,longdisp,*,*")])
2797 [(set (match_operand:DD_DF 0 "nonimmediate_operand" "")
2798 (match_operand:DD_DF 1 "general_operand" ""))]
2799 "!TARGET_ZARCH && reload_completed
2800 && !s_operand (operands[0], <MODE>mode)
2801 && !s_operand (operands[1], <MODE>mode)
2802 && s390_split_ok_p (operands[0], operands[1], <MODE>mode, 0)"
2803 [(set (match_dup 2) (match_dup 4))
2804 (set (match_dup 3) (match_dup 5))]
2806 operands[2] = operand_subword (operands[0], 0, 0, <MODE>mode);
2807 operands[3] = operand_subword (operands[0], 1, 0, <MODE>mode);
2808 operands[4] = operand_subword (operands[1], 0, 0, <MODE>mode);
2809 operands[5] = operand_subword (operands[1], 1, 0, <MODE>mode);
2813 [(set (match_operand:DD_DF 0 "nonimmediate_operand" "")
2814 (match_operand:DD_DF 1 "general_operand" ""))]
2815 "!TARGET_ZARCH && reload_completed
2816 && !s_operand (operands[0], <MODE>mode)
2817 && !s_operand (operands[1], <MODE>mode)
2818 && s390_split_ok_p (operands[0], operands[1], <MODE>mode, 1)"
2819 [(set (match_dup 2) (match_dup 4))
2820 (set (match_dup 3) (match_dup 5))]
2822 operands[2] = operand_subword (operands[0], 1, 0, <MODE>mode);
2823 operands[3] = operand_subword (operands[0], 0, 0, <MODE>mode);
2824 operands[4] = operand_subword (operands[1], 1, 0, <MODE>mode);
2825 operands[5] = operand_subword (operands[1], 0, 0, <MODE>mode);
2829 [(set (match_operand:DD_DF 0 "register_operand" "")
2830 (match_operand:DD_DF 1 "memory_operand" ""))]
2831 "!TARGET_ZARCH && reload_completed
2832 && !FP_REG_P (operands[0])
2833 && !s_operand (operands[1], VOIDmode)"
2834 [(set (match_dup 0) (match_dup 1))]
2836 rtx addr = operand_subword (operands[0], 1, 0, <MODE>mode);
2837 s390_load_address (addr, XEXP (operands[1], 0));
2838 operands[1] = replace_equiv_address (operands[1], addr);
2842 ; mov(sf|sd) instruction pattern(s).
2845 (define_insn "mov<mode>"
2846 [(set (match_operand:SD_SF 0 "nonimmediate_operand"
2847 "=f,f,f,f,f,f,R,T,d,d,d,d,d,b,R,T,v,v,v,d,v,R")
2848 (match_operand:SD_SF 1 "general_operand"
2849 " G,f,f,R,R,T,f,f,G,d,b,R,T,d,d,d,v,G,d,v,R,v"))]
2874 [(set_attr "op_type" "RRE,RR,RR,RXE,RX,RXY,RX,RXY,RI,RR,RIL,RX,RXY,RIL,RX,RXY,VRR,VRI,VRS,VRS,VRX,VRX")
2875 (set_attr "type" "fsimpsf,fsimpsf,fload<mode>,fload<mode>,fload<mode>,fload<mode>,
2876 fstore<mode>,fstore<mode>,*,lr,load,load,load,store,store,store,*,*,*,*,load,store")
2877 (set_attr "z10prop" "*,*,*,*,*,*,*,*,z10_fwd_A1,z10_fr_E1,z10_fr_E1,z10_fwd_A3,z10_fwd_A3,z10_rec,z10_rec,z10_rec,*,*,*,*,*,*")
2878 (set_attr "cpu_facility" "z196,vx,*,vx,*,longdisp,*,longdisp,*,*,z10,*,longdisp,z10,*,longdisp,vx,vx,vx,vx,vx,vx")
2879 (set_attr "relative_long" "*,*,*,*,*,*,*,*,*,*,yes,*,*,yes,*,*,*,*,*,*,*,*")])
2882 ; movcc instruction pattern
2885 (define_insn "movcc"
2886 [(set (match_operand:CC 0 "nonimmediate_operand" "=d,c,d,d,d,R,T")
2887 (match_operand:CC 1 "nonimmediate_operand" " d,d,c,R,T,d,d"))]
2897 [(set_attr "op_type" "RR,RI,RRE,RX,RXY,RX,RXY")
2898 (set_attr "type" "lr,*,*,load,load,store,store")
2899 (set_attr "cpu_facility" "*,*,*,*,longdisp,*,longdisp")
2900 (set_attr "z10prop" "z10_fr_E1,z10_super,*,z10_fwd_A3,z10_fwd_A3,z10_rec,z10_rec")
2901 (set_attr "z196prop" "*,*,z196_ends,*,*,*,*")])
2904 ; Block move (MVC) patterns.
2908 [(set (match_operand:BLK 0 "memory_operand" "=Q")
2909 (match_operand:BLK 1 "memory_operand" "Q"))
2910 (use (match_operand 2 "const_int_operand" "n"))]
2911 "INTVAL (operands[2]) >= 1 && INTVAL (operands[2]) <= 256"
2912 "mvc\t%O0(%2,%R0),%S1"
2913 [(set_attr "op_type" "SS")])
2915 ; This splitter converts a QI to QI mode copy into a BLK mode copy in
2916 ; order to have it implemented with mvc.
2919 [(set (match_operand:QI 0 "memory_operand" "")
2920 (match_operand:QI 1 "memory_operand" ""))]
2923 [(set (match_dup 0) (match_dup 1))
2924 (use (const_int 1))])]
2926 operands[0] = adjust_address (operands[0], BLKmode, 0);
2927 operands[1] = adjust_address (operands[1], BLKmode, 0);
2933 [(set (match_operand:BLK 0 "memory_operand" "")
2934 (match_operand:BLK 1 "memory_operand" ""))
2935 (use (match_operand 2 "const_int_operand" ""))])
2937 [(set (match_operand:BLK 3 "memory_operand" "")
2938 (match_operand:BLK 4 "memory_operand" ""))
2939 (use (match_operand 5 "const_int_operand" ""))])]
2940 "((INTVAL (operands[2]) > 16 && INTVAL (operands[5]) > 16)
2941 || (INTVAL (operands[2]) + INTVAL (operands[5]) <= 16))
2942 && s390_offset_p (operands[0], operands[3], operands[2])
2943 && s390_offset_p (operands[1], operands[4], operands[2])
2944 && !s390_overlap_p (operands[0], operands[1],
2945 INTVAL (operands[2]) + INTVAL (operands[5]))
2946 && INTVAL (operands[2]) + INTVAL (operands[5]) <= 256"
2948 [(set (match_dup 6) (match_dup 7))
2949 (use (match_dup 8))])]
2950 "operands[6] = gen_rtx_MEM (BLKmode, XEXP (operands[0], 0));
2951 operands[7] = gen_rtx_MEM (BLKmode, XEXP (operands[1], 0));
2952 operands[8] = GEN_INT (INTVAL (operands[2]) + INTVAL (operands[5]));")
2956 [(set (match_operand:BLK 0 "plus16_Q_operand" "")
2957 (match_operand:BLK 1 "plus16_Q_operand" ""))
2958 (use (match_operand 2 "const_int_operand" ""))])]
2959 "INTVAL (operands[2]) > 16 && INTVAL (operands[2]) <= 32"
2961 [(set (match_dup 0) (match_dup 1))
2962 (use (const_int 16))])
2964 [(set (match_dup 3) (match_dup 4))
2965 (use (match_dup 5))])]
2966 "operands[3] = change_address (operands[0], VOIDmode,
2967 plus_constant (Pmode, XEXP (operands[0], 0), 16));
2968 operands[4] = change_address (operands[1], VOIDmode,
2969 plus_constant (Pmode, XEXP (operands[1], 0), 16));
2970 operands[5] = GEN_INT (INTVAL (operands[2]) - 16);")
2974 ; load_multiple pattern(s).
2976 ; ??? Due to reload problems with replacing registers inside match_parallel
2977 ; we currently support load_multiple/store_multiple only after reload.
2980 (define_expand "load_multiple"
2981 [(match_par_dup 3 [(set (match_operand 0 "" "")
2982 (match_operand 1 "" ""))
2983 (use (match_operand 2 "" ""))])]
2992 /* Support only loading a constant number of fixed-point registers from
2993 memory and only bother with this if more than two */
2994 if (GET_CODE (operands[2]) != CONST_INT
2995 || INTVAL (operands[2]) < 2
2996 || INTVAL (operands[2]) > 16
2997 || GET_CODE (operands[1]) != MEM
2998 || GET_CODE (operands[0]) != REG
2999 || REGNO (operands[0]) >= 16)
3002 count = INTVAL (operands[2]);
3003 regno = REGNO (operands[0]);
3004 mode = GET_MODE (operands[0]);
3005 if (mode != SImode && (!TARGET_ZARCH || mode != DImode))
3008 operands[3] = gen_rtx_PARALLEL (VOIDmode, rtvec_alloc (count));
3009 if (!can_create_pseudo_p ())
3011 if (GET_CODE (XEXP (operands[1], 0)) == REG)
3013 from = XEXP (operands[1], 0);
3016 else if (GET_CODE (XEXP (operands[1], 0)) == PLUS
3017 && GET_CODE (XEXP (XEXP (operands[1], 0), 0)) == REG
3018 && GET_CODE (XEXP (XEXP (operands[1], 0), 1)) == CONST_INT)
3020 from = XEXP (XEXP (operands[1], 0), 0);
3021 off = INTVAL (XEXP (XEXP (operands[1], 0), 1));
3028 from = force_reg (Pmode, XEXP (operands[1], 0));
3032 for (i = 0; i < count; i++)
3033 XVECEXP (operands[3], 0, i)
3034 = gen_rtx_SET (gen_rtx_REG (mode, regno + i),
3035 change_address (operands[1], mode,
3036 plus_constant (Pmode, from,
3037 off + i * GET_MODE_SIZE (mode))));
3040 (define_insn "*load_multiple_di"
3041 [(match_parallel 0 "load_multiple_operation"
3042 [(set (match_operand:DI 1 "register_operand" "=r")
3043 (match_operand:DI 2 "s_operand" "S"))])]
3044 "reload_completed && TARGET_ZARCH"
3046 int words = XVECLEN (operands[0], 0);
3047 operands[0] = gen_rtx_REG (DImode, REGNO (operands[1]) + words - 1);
3048 return "lmg\t%1,%0,%S2";
3050 [(set_attr "op_type" "RSY")
3051 (set_attr "type" "lm")])
3053 (define_insn "*load_multiple_si"
3054 [(match_parallel 0 "load_multiple_operation"
3055 [(set (match_operand:SI 1 "register_operand" "=r,r")
3056 (match_operand:SI 2 "s_operand" "Q,S"))])]
3059 int words = XVECLEN (operands[0], 0);
3060 operands[0] = gen_rtx_REG (SImode, REGNO (operands[1]) + words - 1);
3061 return which_alternative == 0 ? "lm\t%1,%0,%S2" : "lmy\t%1,%0,%S2";
3063 [(set_attr "op_type" "RS,RSY")
3064 (set_attr "cpu_facility" "*,longdisp")
3065 (set_attr "type" "lm")])
3068 ; store multiple pattern(s).
3071 (define_expand "store_multiple"
3072 [(match_par_dup 3 [(set (match_operand 0 "" "")
3073 (match_operand 1 "" ""))
3074 (use (match_operand 2 "" ""))])]
3083 /* Support only storing a constant number of fixed-point registers to
3084 memory and only bother with this if more than two. */
3085 if (GET_CODE (operands[2]) != CONST_INT
3086 || INTVAL (operands[2]) < 2
3087 || INTVAL (operands[2]) > 16
3088 || GET_CODE (operands[0]) != MEM
3089 || GET_CODE (operands[1]) != REG
3090 || REGNO (operands[1]) >= 16)
3093 count = INTVAL (operands[2]);
3094 regno = REGNO (operands[1]);
3095 mode = GET_MODE (operands[1]);
3096 if (mode != SImode && (!TARGET_ZARCH || mode != DImode))
3099 operands[3] = gen_rtx_PARALLEL (VOIDmode, rtvec_alloc (count));
3101 if (!can_create_pseudo_p ())
3103 if (GET_CODE (XEXP (operands[0], 0)) == REG)
3105 to = XEXP (operands[0], 0);
3108 else if (GET_CODE (XEXP (operands[0], 0)) == PLUS
3109 && GET_CODE (XEXP (XEXP (operands[0], 0), 0)) == REG
3110 && GET_CODE (XEXP (XEXP (operands[0], 0), 1)) == CONST_INT)
3112 to = XEXP (XEXP (operands[0], 0), 0);
3113 off = INTVAL (XEXP (XEXP (operands[0], 0), 1));
3120 to = force_reg (Pmode, XEXP (operands[0], 0));
3124 for (i = 0; i < count; i++)
3125 XVECEXP (operands[3], 0, i)
3126 = gen_rtx_SET (change_address (operands[0], mode,
3127 plus_constant (Pmode, to,
3128 off + i * GET_MODE_SIZE (mode))),
3129 gen_rtx_REG (mode, regno + i));
3132 (define_insn "*store_multiple_di"
3133 [(match_parallel 0 "store_multiple_operation"
3134 [(set (match_operand:DI 1 "s_operand" "=S")
3135 (match_operand:DI 2 "register_operand" "r"))])]
3136 "reload_completed && TARGET_ZARCH"
3138 int words = XVECLEN (operands[0], 0);
3139 operands[0] = gen_rtx_REG (DImode, REGNO (operands[2]) + words - 1);
3140 return "stmg\t%2,%0,%S1";
3142 [(set_attr "op_type" "RSY")
3143 (set_attr "type" "stm")])
3146 (define_insn "*store_multiple_si"
3147 [(match_parallel 0 "store_multiple_operation"
3148 [(set (match_operand:SI 1 "s_operand" "=Q,S")
3149 (match_operand:SI 2 "register_operand" "r,r"))])]
3152 int words = XVECLEN (operands[0], 0);
3153 operands[0] = gen_rtx_REG (SImode, REGNO (operands[2]) + words - 1);
3154 return which_alternative == 0 ? "stm\t%2,%0,%S1" : "stmy\t%2,%0,%S1";
3156 [(set_attr "op_type" "RS,RSY")
3157 (set_attr "cpu_facility" "*,longdisp")
3158 (set_attr "type" "stm")])
3161 ;; String instructions.
3164 (define_insn "*execute_rl"
3165 [(match_parallel 0 "execute_operation"
3166 [(unspec [(match_operand 1 "register_operand" "a")
3167 (match_operand 2 "" "")
3168 (match_operand:SI 3 "larl_operand" "X")] UNSPEC_EXECUTE)])]
3169 "TARGET_Z10 && GET_MODE_CLASS (GET_MODE (operands[1])) == MODE_INT
3170 && GET_MODE_SIZE (GET_MODE (operands[1])) <= UNITS_PER_WORD"
3172 [(set_attr "op_type" "RIL")
3173 (set_attr "type" "cs")
3174 (set_attr "relative_long" "yes")])
3176 (define_insn "*execute"
3177 [(match_parallel 0 "execute_operation"
3178 [(unspec [(match_operand 1 "register_operand" "a")
3179 (match_operand:BLK 2 "memory_operand" "R")
3180 (match_operand 3 "" "")] UNSPEC_EXECUTE)])]
3181 "GET_MODE_CLASS (GET_MODE (operands[1])) == MODE_INT
3182 && GET_MODE_SIZE (GET_MODE (operands[1])) <= UNITS_PER_WORD"
3184 [(set_attr "op_type" "RX")
3185 (set_attr "type" "cs")])
3189 ; strlenM instruction pattern(s).
3192 (define_expand "strlen<mode>"
3193 [(match_operand:P 0 "register_operand" "") ; result
3194 (match_operand:BLK 1 "memory_operand" "") ; input string
3195 (match_operand:SI 2 "immediate_operand" "") ; search character
3196 (match_operand:SI 3 "immediate_operand" "")] ; known alignment
3199 if (!TARGET_VX || operands[2] != const0_rtx)
3200 emit_insn (gen_strlen_srst<mode> (operands[0], operands[1],
3201 operands[2], operands[3]));
3203 s390_expand_vec_strlen (operands[0], operands[1], operands[3]);
3208 (define_expand "strlen_srst<mode>"
3209 [(set (reg:SI 0) (match_operand:SI 2 "immediate_operand" ""))
3212 (unspec:P [(const_int 0)
3213 (match_operand:BLK 1 "memory_operand" "")
3215 (match_operand 3 "immediate_operand" "")] UNSPEC_SRST))
3216 (clobber (scratch:P))
3217 (clobber (reg:CC CC_REGNUM))])
3219 [(set (match_operand:P 0 "register_operand" "")
3220 (minus:P (match_dup 4) (match_dup 5)))
3221 (clobber (reg:CC CC_REGNUM))])]
3224 operands[4] = gen_reg_rtx (Pmode);
3225 operands[5] = gen_reg_rtx (Pmode);
3226 emit_move_insn (operands[5], force_operand (XEXP (operands[1], 0), NULL_RTX));
3227 operands[1] = replace_equiv_address (operands[1], operands[5]);
3230 (define_insn "*strlen<mode>"
3231 [(set (match_operand:P 0 "register_operand" "=a")
3232 (unspec:P [(match_operand:P 2 "general_operand" "0")
3233 (mem:BLK (match_operand:P 3 "register_operand" "1"))
3235 (match_operand 4 "immediate_operand" "")] UNSPEC_SRST))
3236 (clobber (match_scratch:P 1 "=a"))
3237 (clobber (reg:CC CC_REGNUM))]
3239 "srst\t%0,%1\;jo\t.-4"
3240 [(set_attr "length" "8")
3241 (set_attr "type" "vs")])
3244 ; cmpstrM instruction pattern(s).
3247 (define_expand "cmpstrsi"
3248 [(set (reg:SI 0) (const_int 0))
3250 [(clobber (match_operand 3 "" ""))
3251 (clobber (match_dup 4))
3252 (set (reg:CCU CC_REGNUM)
3253 (compare:CCU (match_operand:BLK 1 "memory_operand" "")
3254 (match_operand:BLK 2 "memory_operand" "")))
3257 [(set (match_operand:SI 0 "register_operand" "=d")
3258 (unspec:SI [(reg:CCU CC_REGNUM)] UNSPEC_STRCMPCC_TO_INT))
3259 (clobber (reg:CC CC_REGNUM))])]
3262 /* As the result of CMPINT is inverted compared to what we need,
3263 we have to swap the operands. */
3264 rtx op1 = operands[2];
3265 rtx op2 = operands[1];
3266 rtx addr1 = gen_reg_rtx (Pmode);
3267 rtx addr2 = gen_reg_rtx (Pmode);
3269 emit_move_insn (addr1, force_operand (XEXP (op1, 0), NULL_RTX));
3270 emit_move_insn (addr2, force_operand (XEXP (op2, 0), NULL_RTX));
3271 operands[1] = replace_equiv_address_nv (op1, addr1);
3272 operands[2] = replace_equiv_address_nv (op2, addr2);
3273 operands[3] = addr1;
3274 operands[4] = addr2;
3277 (define_insn "*cmpstr<mode>"
3278 [(clobber (match_operand:P 0 "register_operand" "=d"))
3279 (clobber (match_operand:P 1 "register_operand" "=d"))
3280 (set (reg:CCU CC_REGNUM)
3281 (compare:CCU (mem:BLK (match_operand:P 2 "register_operand" "0"))
3282 (mem:BLK (match_operand:P 3 "register_operand" "1"))))
3285 "clst\t%0,%1\;jo\t.-4"
3286 [(set_attr "length" "8")
3287 (set_attr "type" "vs")])
3290 ; movstr instruction pattern.
3293 (define_expand "movstr"
3294 [(match_operand 0 "register_operand" "")
3295 (match_operand 1 "memory_operand" "")
3296 (match_operand 2 "memory_operand" "")]
3300 emit_insn (gen_movstrdi (operands[0], operands[1], operands[2]));
3302 emit_insn (gen_movstrsi (operands[0], operands[1], operands[2]));
3306 (define_expand "movstr<P:mode>"
3307 [(set (reg:SI 0) (const_int 0))
3309 [(clobber (match_dup 3))
3310 (set (match_operand:BLK 1 "memory_operand" "")
3311 (match_operand:BLK 2 "memory_operand" ""))
3312 (set (match_operand:P 0 "register_operand" "")
3313 (unspec:P [(match_dup 1)
3315 (reg:SI 0)] UNSPEC_MVST))
3316 (clobber (reg:CC CC_REGNUM))])]
3321 if (TARGET_VX && optimize_function_for_speed_p (cfun))
3323 s390_expand_vec_movstr (operands[0], operands[1], operands[2]);
3327 addr1 = gen_reg_rtx (Pmode);
3328 addr2 = gen_reg_rtx (Pmode);
3330 emit_move_insn (addr1, force_operand (XEXP (operands[1], 0), NULL_RTX));
3331 emit_move_insn (addr2, force_operand (XEXP (operands[2], 0), NULL_RTX));
3332 operands[1] = replace_equiv_address_nv (operands[1], addr1);
3333 operands[2] = replace_equiv_address_nv (operands[2], addr2);
3334 operands[3] = addr2;
3337 (define_insn "*movstr"
3338 [(clobber (match_operand:P 2 "register_operand" "=d"))
3339 (set (mem:BLK (match_operand:P 1 "register_operand" "0"))
3340 (mem:BLK (match_operand:P 3 "register_operand" "2")))
3341 (set (match_operand:P 0 "register_operand" "=d")
3342 (unspec:P [(mem:BLK (match_dup 1))
3343 (mem:BLK (match_dup 3))
3344 (reg:SI 0)] UNSPEC_MVST))
3345 (clobber (reg:CC CC_REGNUM))]
3347 "mvst\t%1,%2\;jo\t.-4"
3348 [(set_attr "length" "8")
3349 (set_attr "type" "vs")])
3353 ; cpymemM instruction pattern(s).
3356 (define_expand "cpymem<mode>"
3357 [(set (match_operand:BLK 0 "memory_operand" "") ; destination
3358 (match_operand:BLK 1 "memory_operand" "")) ; source
3359 (use (match_operand:GPR 2 "general_operand" "")) ; size
3360 (match_operand 3 "") ; align
3361 (match_operand 4 "") ; expected align
3362 (match_operand 5 "") ; expected size
3363 (match_operand 6 "") ; minimal size
3364 (match_operand 7 "")] ; maximal size
3367 if (s390_expand_cpymem (operands[0], operands[1], operands[2], operands[6], operands[7]))
3373 ; Move a block that is up to 256 bytes in length.
3374 ; The block length is taken as (operands[2] % 256) + 1.
3376 (define_expand "cpymem_short"
3378 [(set (match_operand:BLK 0 "memory_operand" "")
3379 (match_operand:BLK 1 "memory_operand" ""))
3380 (use (match_operand 2 "nonmemory_operand" ""))
3381 (use (const:BLK (unspec:BLK [(const_int 0)] UNSPEC_INSN)))
3382 (clobber (match_dup 3))])]
3384 "operands[3] = gen_rtx_SCRATCH (Pmode);")
3386 (define_insn "*cpymem_short"
3387 [(set (match_operand:BLK 0 "memory_operand" "=Q,Q,Q,Q")
3388 (match_operand:BLK 1 "memory_operand" "Q,Q,Q,Q"))
3389 (use (match_operand 2 "nonmemory_operand" "n,a,a,a"))
3390 (use (match_operand 3 "immediate_operand" "X,R,X,X"))
3391 (clobber (match_scratch:P 4 "=X,X,X,&a"))]
3392 "(GET_MODE (operands[2]) == Pmode || GET_MODE (operands[2]) == VOIDmode)"
3394 [(set_attr "type" "cs")
3395 (set_attr "cpu_facility" "*,*,z10,cpu_zarch")])
3398 [(set (match_operand:BLK 0 "memory_operand" "")
3399 (match_operand:BLK 1 "memory_operand" ""))
3400 (use (match_operand 2 "const_int_operand" ""))
3401 (use (match_operand 3 "immediate_operand" ""))
3402 (clobber (scratch))]
3405 [(set (match_dup 0) (match_dup 1))
3406 (use (match_dup 2))])]
3407 "operands[2] = GEN_INT ((INTVAL (operands[2]) & 0xff) + 1);")
3410 [(set (match_operand:BLK 0 "memory_operand" "")
3411 (match_operand:BLK 1 "memory_operand" ""))
3412 (use (match_operand 2 "register_operand" ""))
3413 (use (match_operand 3 "memory_operand" ""))
3414 (clobber (scratch))]
3417 [(unspec [(match_dup 2) (match_dup 3)
3418 (const_int 0)] UNSPEC_EXECUTE)
3419 (set (match_dup 0) (match_dup 1))
3420 (use (const_int 1))])]
3424 [(set (match_operand:BLK 0 "memory_operand" "")
3425 (match_operand:BLK 1 "memory_operand" ""))
3426 (use (match_operand 2 "register_operand" ""))
3427 (use (const:BLK (unspec:BLK [(const_int 0)] UNSPEC_INSN)))
3428 (clobber (scratch))]
3429 "TARGET_Z10 && reload_completed"
3431 [(unspec [(match_dup 2) (const_int 0)
3432 (label_ref (match_dup 3))] UNSPEC_EXECUTE)
3433 (set (match_dup 0) (match_dup 1))
3434 (use (const_int 1))])]
3435 "operands[3] = gen_label_rtx ();")
3438 [(set (match_operand:BLK 0 "memory_operand" "")
3439 (match_operand:BLK 1 "memory_operand" ""))
3440 (use (match_operand 2 "register_operand" ""))
3441 (use (const:BLK (unspec:BLK [(const_int 0)] UNSPEC_INSN)))
3442 (clobber (match_operand 3 "register_operand" ""))]
3444 [(set (match_dup 3) (label_ref (match_dup 4)))
3446 [(unspec [(match_dup 2) (mem:BLK (match_dup 3))
3447 (label_ref (match_dup 4))] UNSPEC_EXECUTE)
3448 (set (match_dup 0) (match_dup 1))
3449 (use (const_int 1))])]
3450 "operands[4] = gen_label_rtx ();")
3452 ; Move a block of arbitrary length.
3454 (define_expand "cpymem_long"
3456 [(clobber (match_dup 2))
3457 (clobber (match_dup 3))
3458 (set (match_operand:BLK 0 "memory_operand" "")
3459 (match_operand:BLK 1 "memory_operand" ""))
3460 (use (match_operand 2 "general_operand" ""))
3462 (clobber (reg:CC CC_REGNUM))])]
3465 machine_mode sreg_mode = TARGET_ZARCH ? DImode : SImode;
3466 machine_mode dreg_mode = TARGET_ZARCH ? TImode : DImode;
3467 rtx reg0 = gen_reg_rtx (dreg_mode);
3468 rtx reg1 = gen_reg_rtx (dreg_mode);
3469 rtx addr0 = gen_lowpart (Pmode, gen_highpart (sreg_mode, reg0));
3470 rtx addr1 = gen_lowpart (Pmode, gen_highpart (sreg_mode, reg1));
3471 rtx len0 = gen_lowpart (Pmode, reg0);
3472 rtx len1 = gen_lowpart (Pmode, reg1);
3474 emit_clobber (reg0);
3475 emit_move_insn (addr0, force_operand (XEXP (operands[0], 0), NULL_RTX));
3476 emit_move_insn (len0, operands[2]);
3478 emit_clobber (reg1);
3479 emit_move_insn (addr1, force_operand (XEXP (operands[1], 0), NULL_RTX));
3480 emit_move_insn (len1, operands[2]);
3482 operands[0] = replace_equiv_address_nv (operands[0], addr0);
3483 operands[1] = replace_equiv_address_nv (operands[1], addr1);
3488 (define_insn "*cpymem_long"
3489 [(clobber (match_operand:<DBL> 0 "register_operand" "=d"))
3490 (clobber (match_operand:<DBL> 1 "register_operand" "=d"))
3491 (set (mem:BLK (subreg:P (match_operand:<DBL> 2 "register_operand" "0") 0))
3492 (mem:BLK (subreg:P (match_operand:<DBL> 3 "register_operand" "1") 0)))
3495 (clobber (reg:CC CC_REGNUM))]
3496 "TARGET_64BIT || !TARGET_ZARCH"
3497 "mvcle\t%0,%1,0\;jo\t.-4"
3498 [(set_attr "length" "8")
3499 (set_attr "type" "vs")])
3501 (define_insn "*cpymem_long_31z"
3502 [(clobber (match_operand:TI 0 "register_operand" "=d"))
3503 (clobber (match_operand:TI 1 "register_operand" "=d"))
3504 (set (mem:BLK (subreg:SI (match_operand:TI 2 "register_operand" "0") 4))
3505 (mem:BLK (subreg:SI (match_operand:TI 3 "register_operand" "1") 4)))
3508 (clobber (reg:CC CC_REGNUM))]
3509 "!TARGET_64BIT && TARGET_ZARCH"
3510 "mvcle\t%0,%1,0\;jo\t.-4"
3511 [(set_attr "length" "8")
3512 (set_attr "type" "vs")])
3514 (define_expand "movmem<mode>"
3515 [(set (match_operand:BLK 0 "memory_operand") ; destination
3516 (match_operand:BLK 1 "memory_operand")) ; source
3517 (use (match_operand:GPR 2 "general_operand")) ; size
3518 (match_operand 3 "") ; align
3519 (match_operand 4 "") ; expected align
3520 (match_operand 5 "") ; expected size
3521 (match_operand 6 "") ; minimal size
3522 (match_operand 7 "")] ; maximal size
3525 if (s390_expand_movmem (operands[0], operands[1], operands[2], operands[6], operands[7]))
3531 (define_insn "*mvcrl"
3532 [(set (match_operand:BLK 0 "memory_operand" "=Q")
3533 (unspec:BLK [(match_operand:BLK 1 "memory_operand" "Q")
3534 (reg:SI GPR0_REGNUM)]
3538 [(set_attr "op_type" "SSE")])
3540 (define_expand "mvcrl"
3541 [(set (reg:SI GPR0_REGNUM) (match_operand:SI 2 "general_operand"))
3542 (set (match_operand:BLK 0 "memory_operand" "=Q")
3543 (unspec:BLK [(match_operand:BLK 1 "memory_operand" "Q")
3544 (reg:SI GPR0_REGNUM)]
3553 (define_expand "signbit<mode>2<tf_fpr>"
3554 [(set (reg:CCZ CC_REGNUM)
3555 (unspec:CCZ [(match_operand:FP_ALL 1 "register_operand" "f")
3558 (set (match_operand:SI 0 "register_operand" "=d")
3559 (unspec:SI [(reg:CCZ CC_REGNUM)] UNSPEC_CC_TO_INT))]
3562 operands[2] = GEN_INT (S390_TDC_SIGNBIT_SET);
3565 (define_expand "isinf<mode>2<tf_fpr>"
3566 [(set (reg:CCZ CC_REGNUM)
3567 (unspec:CCZ [(match_operand:FP_ALL 1 "register_operand" "f")
3570 (set (match_operand:SI 0 "register_operand" "=d")
3571 (unspec:SI [(reg:CCZ CC_REGNUM)] UNSPEC_CC_TO_INT))]
3574 operands[2] = GEN_INT (S390_TDC_INFINITY);
3577 ; This extracts CC into a GPR properly shifted. The actual IPM
3578 ; instruction will be issued by reload. The constraint of operand 1
3579 ; forces reload to use a GPR. So reload will issue a movcc insn for
3580 ; copying CC into a GPR first.
3581 (define_insn_and_split "*cc_to_int"
3582 [(set (match_operand:SI 0 "nonimmediate_operand" "=d")
3583 (unspec:SI [(match_operand 1 "register_operand" "0")]
3588 [(set (match_dup 0) (lshiftrt:SI (match_dup 0) (const_int 28)))])
3590 ; This insn is used to generate all variants of the Test Data Class
3591 ; instruction, namely tcxb, tcdb, and tceb. The insn's first operand
3592 ; is the register to be tested and the second one is the bit mask
3593 ; specifying the required test(s).
3595 ; tcxb, tcdb, tceb, tdcxt, tdcdt, tdcet
3596 (define_insn "*TDC_insn_<mode>"
3597 [(set (reg:CCZ CC_REGNUM)
3598 (unspec:CCZ [(match_operand:FP_ALL 0 "register_operand" "f")
3599 (match_operand:SI 1 "const_int_operand")] UNSPEC_TDC_INSN))]
3601 "t<_d>c<xde><bt>\t%0,%1"
3602 [(set_attr "op_type" "RXE")
3603 (set_attr "type" "fsimp<type>")])
3608 ; setmemM instruction pattern(s).
3611 (define_expand "setmem<mode>"
3612 [(set (match_operand:BLK 0 "memory_operand" "") ; destination
3613 (match_operand:QI 2 "general_operand" "")) ; value
3614 (use (match_operand:GPR 1 "general_operand" "")) ; size
3615 (match_operand 3 "") ; align
3616 (match_operand 4 "") ; expected align
3617 (match_operand 5 "") ; expected size
3618 (match_operand 6 "") ; minimal size
3619 (match_operand 7 "")] ; maximal size
3621 "s390_expand_setmem (operands[0], operands[1], operands[2], operands[6], operands[7]); DONE;")
3623 ; Clear a block that is up to 256 bytes in length.
3624 ; The block length is taken as (operands[1] % 256) + 1.
3626 (define_expand "clrmem_short"
3628 [(set (match_operand:BLK 0 "memory_operand" "")
3630 (use (match_operand 1 "nonmemory_operand" ""))
3631 (use (const:BLK (unspec:BLK [(const_int 0)] UNSPEC_INSN)))
3632 (clobber (match_dup 2))
3633 (clobber (reg:CC CC_REGNUM))])]
3635 "operands[2] = gen_rtx_SCRATCH (Pmode);")
3637 (define_insn "*clrmem_short"
3638 [(set (match_operand:BLK 0 "memory_operand" "=Q,Q,Q,Q")
3640 (use (match_operand 1 "nonmemory_operand" "n,a,a,a"))
3641 (use (match_operand 2 "immediate_operand" "X,R,X,X"))
3642 (clobber (match_scratch:P 3 "=X,X,X,&a"))
3643 (clobber (reg:CC CC_REGNUM))]
3644 "(GET_MODE (operands[1]) == Pmode || GET_MODE (operands[1]) == VOIDmode)"
3646 [(set_attr "type" "cs")
3647 (set_attr "cpu_facility" "*,*,z10,cpu_zarch")])
3650 [(set (match_operand:BLK 0 "memory_operand" "")
3652 (use (match_operand 1 "const_int_operand" ""))
3653 (use (match_operand 2 "immediate_operand" ""))
3655 (clobber (reg:CC CC_REGNUM))]
3658 [(set (match_dup 0) (const_int 0))
3660 (clobber (reg:CC CC_REGNUM))])]
3661 "operands[1] = GEN_INT ((INTVAL (operands[1]) & 0xff) + 1);")
3664 [(set (match_operand:BLK 0 "memory_operand" "")
3666 (use (match_operand 1 "register_operand" ""))
3667 (use (match_operand 2 "memory_operand" ""))
3669 (clobber (reg:CC CC_REGNUM))]
3672 [(unspec [(match_dup 1) (match_dup 2)
3673 (const_int 0)] UNSPEC_EXECUTE)
3674 (set (match_dup 0) (const_int 0))
3676 (clobber (reg:CC CC_REGNUM))])]
3680 [(set (match_operand:BLK 0 "memory_operand" "")
3682 (use (match_operand 1 "register_operand" ""))
3683 (use (const:BLK (unspec:BLK [(const_int 0)] UNSPEC_INSN)))
3685 (clobber (reg:CC CC_REGNUM))]
3686 "TARGET_Z10 && reload_completed"
3688 [(unspec [(match_dup 1) (const_int 0)
3689 (label_ref (match_dup 3))] UNSPEC_EXECUTE)
3690 (set (match_dup 0) (const_int 0))
3692 (clobber (reg:CC CC_REGNUM))])]
3693 "operands[3] = gen_label_rtx ();")
3696 [(set (match_operand:BLK 0 "memory_operand" "")
3698 (use (match_operand 1 "register_operand" ""))
3699 (use (const:BLK (unspec:BLK [(const_int 0)] UNSPEC_INSN)))
3700 (clobber (match_operand 2 "register_operand" ""))
3701 (clobber (reg:CC CC_REGNUM))]
3703 [(set (match_dup 2) (label_ref (match_dup 3)))
3705 [(unspec [(match_dup 1) (mem:BLK (match_dup 2))
3706 (label_ref (match_dup 3))] UNSPEC_EXECUTE)
3707 (set (match_dup 0) (const_int 0))
3709 (clobber (reg:CC CC_REGNUM))])]
3710 "operands[3] = gen_label_rtx ();")
3712 ; Initialize a block of arbitrary length with (operands[2] % 256).
3714 (define_expand "setmem_long_<P:mode>"
3716 [(clobber (match_dup 1))
3717 (set (match_operand:BLK 0 "memory_operand" "")
3718 (unspec:BLK [(match_operand:P 2 "setmem_operand" "")
3719 (match_dup 4)] UNSPEC_REPLICATE_BYTE))
3721 (clobber (reg:CC CC_REGNUM))])]
3724 machine_mode sreg_mode = TARGET_ZARCH ? DImode : SImode;
3725 machine_mode dreg_mode = TARGET_ZARCH ? TImode : DImode;
3726 rtx reg0 = gen_reg_rtx (dreg_mode);
3727 rtx reg1 = gen_reg_rtx (dreg_mode);
3728 rtx addr0 = gen_lowpart (Pmode, gen_highpart (sreg_mode, reg0));
3729 rtx len0 = gen_lowpart (Pmode, reg0);
3731 emit_clobber (reg0);
3732 emit_move_insn (addr0, force_operand (XEXP (operands[0], 0), NULL_RTX));
3733 emit_move_insn (len0, operands[1]);
3735 emit_move_insn (reg1, const0_rtx);
3737 operands[0] = replace_equiv_address_nv (operands[0], addr0);
3740 operands[4] = gen_lowpart (Pmode, operands[1]);
3743 ; Patterns for 31 bit + Esa and 64 bit + Zarch.
3745 (define_insn "*setmem_long"
3746 [(clobber (match_operand:<DBL> 0 "register_operand" "=d"))
3747 (set (mem:BLK (subreg:P (match_operand:<DBL> 3 "register_operand" "0") 0))
3748 (unspec:BLK [(match_operand:P 2 "setmem_operand" "Y")
3749 (subreg:P (match_dup 3) <modesize>)]
3750 UNSPEC_REPLICATE_BYTE))
3751 (use (match_operand:<DBL> 1 "register_operand" "d"))
3752 (clobber (reg:CC CC_REGNUM))]
3753 "TARGET_64BIT || !TARGET_ZARCH"
3754 "mvcle\t%0,%1,%Y2\;jo\t.-4"
3755 [(set_attr "length" "8")
3756 (set_attr "type" "vs")])
3758 (define_insn "*setmem_long_and"
3759 [(clobber (match_operand:<DBL> 0 "register_operand" "=d"))
3760 (set (mem:BLK (subreg:P (match_operand:<DBL> 3 "register_operand" "0") 0))
3761 (unspec:BLK [(zero_extend:P (match_operand:QI 2 "setmem_operand" "Y"))
3762 (subreg:P (match_dup 3) <modesize>)]
3763 UNSPEC_REPLICATE_BYTE))
3764 (use (match_operand:<DBL> 1 "register_operand" "d"))
3765 (clobber (reg:CC CC_REGNUM))]
3766 "(TARGET_64BIT || !TARGET_ZARCH)"
3767 "mvcle\t%0,%1,%Y2\;jo\t.-4"
3768 [(set_attr "length" "8")
3769 (set_attr "type" "vs")])
3771 ; Variants for 31 bit + Zarch, necessary because of the odd in-register offsets
3772 ; of the SImode subregs.
3774 (define_insn "*setmem_long_31z"
3775 [(clobber (match_operand:TI 0 "register_operand" "=d"))
3776 (set (mem:BLK (subreg:SI (match_operand:TI 3 "register_operand" "0") 4))
3777 (unspec:BLK [(match_operand:SI 2 "setmem_operand" "Y")
3778 (subreg:SI (match_dup 3) 12)] UNSPEC_REPLICATE_BYTE))
3779 (use (match_operand:TI 1 "register_operand" "d"))
3780 (clobber (reg:CC CC_REGNUM))]
3781 "!TARGET_64BIT && TARGET_ZARCH"
3782 "mvcle\t%0,%1,%Y2\;jo\t.-4"
3783 [(set_attr "length" "8")
3784 (set_attr "type" "vs")])
3786 (define_insn "*setmem_long_and_31z"
3787 [(clobber (match_operand:TI 0 "register_operand" "=d"))
3788 (set (mem:BLK (subreg:SI (match_operand:TI 3 "register_operand" "0") 4))
3789 (unspec:BLK [(zero_extend:SI (match_operand:QI 2 "setmem_operand" "Y"))
3790 (subreg:SI (match_dup 3) 12)] UNSPEC_REPLICATE_BYTE))
3791 (use (match_operand:TI 1 "register_operand" "d"))
3792 (clobber (reg:CC CC_REGNUM))]
3793 "(!TARGET_64BIT && TARGET_ZARCH)"
3794 "mvcle\t%0,%1,%Y2\;jo\t.-4"
3795 [(set_attr "length" "8")
3796 (set_attr "type" "vs")])
3799 ; cmpmemM instruction pattern(s).
3802 (define_expand "cmpmemsi"
3803 [(set (match_operand:SI 0 "register_operand" "")
3804 (compare:SI (match_operand:BLK 1 "memory_operand" "")
3805 (match_operand:BLK 2 "memory_operand" "") ) )
3806 (use (match_operand:SI 3 "general_operand" ""))
3807 (use (match_operand:SI 4 "" ""))]
3810 if (s390_expand_cmpmem (operands[0], operands[1],
3811 operands[2], operands[3]))
3817 ; Compare a block that is up to 256 bytes in length.
3818 ; The block length is taken as (operands[2] % 256) + 1.
3820 (define_expand "cmpmem_short"
3822 [(set (reg:CCU CC_REGNUM)
3823 (compare:CCU (match_operand:BLK 0 "memory_operand" "")
3824 (match_operand:BLK 1 "memory_operand" "")))
3825 (use (match_operand 2 "nonmemory_operand" ""))
3826 (use (const:BLK (unspec:BLK [(const_int 0)] UNSPEC_INSN)))
3827 (clobber (match_dup 3))])]
3829 "operands[3] = gen_rtx_SCRATCH (Pmode);")
3831 (define_insn "*cmpmem_short"
3832 [(set (reg:CCU CC_REGNUM)
3833 (compare:CCU (match_operand:BLK 0 "memory_operand" "Q,Q,Q,Q")
3834 (match_operand:BLK 1 "memory_operand" "Q,Q,Q,Q")))
3835 (use (match_operand 2 "nonmemory_operand" "n,a,a,a"))
3836 (use (match_operand 3 "immediate_operand" "X,R,X,X"))
3837 (clobber (match_scratch:P 4 "=X,X,X,&a"))]
3838 "(GET_MODE (operands[2]) == Pmode || GET_MODE (operands[2]) == VOIDmode)"
3840 [(set_attr "type" "cs")
3841 (set_attr "cpu_facility" "*,*,z10,cpu_zarch")])
3844 [(set (reg:CCU CC_REGNUM)
3845 (compare:CCU (match_operand:BLK 0 "memory_operand" "")
3846 (match_operand:BLK 1 "memory_operand" "")))
3847 (use (match_operand 2 "const_int_operand" ""))
3848 (use (match_operand 3 "immediate_operand" ""))
3849 (clobber (scratch))]
3852 [(set (reg:CCU CC_REGNUM) (compare:CCU (match_dup 0) (match_dup 1)))
3853 (use (match_dup 2))])]
3854 "operands[2] = GEN_INT ((INTVAL (operands[2]) & 0xff) + 1);")
3857 [(set (reg:CCU CC_REGNUM)
3858 (compare:CCU (match_operand:BLK 0 "memory_operand" "")
3859 (match_operand:BLK 1 "memory_operand" "")))
3860 (use (match_operand 2 "register_operand" ""))
3861 (use (match_operand 3 "memory_operand" ""))
3862 (clobber (scratch))]
3865 [(unspec [(match_dup 2) (match_dup 3)
3866 (const_int 0)] UNSPEC_EXECUTE)
3867 (set (reg:CCU CC_REGNUM) (compare:CCU (match_dup 0) (match_dup 1)))
3868 (use (const_int 1))])]
3872 [(set (reg:CCU CC_REGNUM)
3873 (compare:CCU (match_operand:BLK 0 "memory_operand" "")
3874 (match_operand:BLK 1 "memory_operand" "")))
3875 (use (match_operand 2 "register_operand" ""))
3876 (use (const:BLK (unspec:BLK [(const_int 0)] UNSPEC_INSN)))
3877 (clobber (scratch))]
3878 "TARGET_Z10 && reload_completed"
3880 [(unspec [(match_dup 2) (const_int 0)
3881 (label_ref (match_dup 4))] UNSPEC_EXECUTE)
3882 (set (reg:CCU CC_REGNUM) (compare:CCU (match_dup 0) (match_dup 1)))
3883 (use (const_int 1))])]
3884 "operands[4] = gen_label_rtx ();")
3887 [(set (reg:CCU CC_REGNUM)
3888 (compare:CCU (match_operand:BLK 0 "memory_operand" "")
3889 (match_operand:BLK 1 "memory_operand" "")))
3890 (use (match_operand 2 "register_operand" ""))
3891 (use (const:BLK (unspec:BLK [(const_int 0)] UNSPEC_INSN)))
3892 (clobber (match_operand 3 "register_operand" ""))]
3894 [(set (match_dup 3) (label_ref (match_dup 4)))
3896 [(unspec [(match_dup 2) (mem:BLK (match_dup 3))
3897 (label_ref (match_dup 4))] UNSPEC_EXECUTE)
3898 (set (reg:CCU CC_REGNUM) (compare:CCU (match_dup 0) (match_dup 1)))
3899 (use (const_int 1))])]
3900 "operands[4] = gen_label_rtx ();")
3902 ; Compare a block of arbitrary length.
3904 (define_expand "cmpmem_long"
3906 [(clobber (match_dup 2))
3907 (clobber (match_dup 3))
3908 (set (reg:CCU CC_REGNUM)
3909 (compare:CCU (match_operand:BLK 0 "memory_operand" "")
3910 (match_operand:BLK 1 "memory_operand" "")))
3911 (use (match_operand 2 "general_operand" ""))
3912 (use (match_dup 3))])]
3915 machine_mode sreg_mode = TARGET_ZARCH ? DImode : SImode;
3916 machine_mode dreg_mode = TARGET_ZARCH ? TImode : DImode;
3917 rtx reg0 = gen_reg_rtx (dreg_mode);
3918 rtx reg1 = gen_reg_rtx (dreg_mode);
3919 rtx addr0 = gen_lowpart (Pmode, gen_highpart (sreg_mode, reg0));
3920 rtx addr1 = gen_lowpart (Pmode, gen_highpart (sreg_mode, reg1));
3921 rtx len0 = gen_lowpart (Pmode, reg0);
3922 rtx len1 = gen_lowpart (Pmode, reg1);
3924 emit_clobber (reg0);
3925 emit_move_insn (addr0, force_operand (XEXP (operands[0], 0), NULL_RTX));
3926 emit_move_insn (len0, operands[2]);
3928 emit_clobber (reg1);
3929 emit_move_insn (addr1, force_operand (XEXP (operands[1], 0), NULL_RTX));
3930 emit_move_insn (len1, operands[2]);
3932 operands[0] = replace_equiv_address_nv (operands[0], addr0);
3933 operands[1] = replace_equiv_address_nv (operands[1], addr1);
3938 (define_insn "*cmpmem_long"
3939 [(clobber (match_operand:<DBL> 0 "register_operand" "=d"))
3940 (clobber (match_operand:<DBL> 1 "register_operand" "=d"))
3941 (set (reg:CCU CC_REGNUM)
3942 (compare:CCU (mem:BLK (subreg:P (match_operand:<DBL> 2 "register_operand" "0") 0))
3943 (mem:BLK (subreg:P (match_operand:<DBL> 3 "register_operand" "1") 0))))
3945 (use (match_dup 3))]
3946 "TARGET_64BIT || !TARGET_ZARCH"
3947 "clcle\t%0,%1,0\;jo\t.-4"
3948 [(set_attr "length" "8")
3949 (set_attr "type" "vs")])
3951 (define_insn "*cmpmem_long_31z"
3952 [(clobber (match_operand:TI 0 "register_operand" "=d"))
3953 (clobber (match_operand:TI 1 "register_operand" "=d"))
3954 (set (reg:CCU CC_REGNUM)
3955 (compare:CCU (mem:BLK (subreg:SI (match_operand:TI 2 "register_operand" "0") 4))
3956 (mem:BLK (subreg:SI (match_operand:TI 3 "register_operand" "1") 4))))
3958 (use (match_dup 3))]
3959 "!TARGET_64BIT && TARGET_ZARCH"
3960 "clcle\t%0,%1,0\;jo\t.-4"
3961 [(set_attr "op_type" "NN")
3962 (set_attr "type" "vs")
3963 (set_attr "length" "8")])
3965 ; Convert CCUmode condition code to integer.
3966 ; Result is zero if EQ, positive if LTU, negative if GTU.
3968 (define_insn_and_split "cmpint"
3969 [(set (match_operand:SI 0 "register_operand" "=d")
3970 (unspec:SI [(match_operand:CCU 1 "register_operand" "0")]
3971 UNSPEC_STRCMPCC_TO_INT))
3972 (clobber (reg:CC CC_REGNUM))]
3976 [(set (match_dup 0) (ashift:SI (match_dup 0) (const_int 2)))
3978 [(set (match_dup 0) (ashiftrt:SI (match_dup 0) (const_int 30)))
3979 (clobber (reg:CC CC_REGNUM))])])
3981 (define_insn_and_split "*cmpint_cc"
3982 [(set (reg CC_REGNUM)
3983 (compare (unspec:SI [(match_operand:CCU 1 "register_operand" "0")]
3984 UNSPEC_STRCMPCC_TO_INT)
3986 (set (match_operand:SI 0 "register_operand" "=d")
3987 (unspec:SI [(match_dup 1)] UNSPEC_STRCMPCC_TO_INT))]
3988 "s390_match_ccmode (insn, CCSmode)"
3990 "&& reload_completed"
3991 [(set (match_dup 0) (ashift:SI (match_dup 0) (const_int 2)))
3993 [(set (match_dup 2) (match_dup 3))
3994 (set (match_dup 0) (ashiftrt:SI (match_dup 0) (const_int 30)))])]
3996 rtx result = gen_rtx_ASHIFTRT (SImode, operands[0], GEN_INT (30));
3997 operands[2] = SET_DEST (XVECEXP (PATTERN (curr_insn), 0, 0));
3998 operands[3] = gen_rtx_COMPARE (GET_MODE (operands[2]), result, const0_rtx);
4001 (define_insn_and_split "*cmpint_sign"
4002 [(set (match_operand:DI 0 "register_operand" "=d")
4003 (sign_extend:DI (unspec:SI [(match_operand:CCU 1 "register_operand" "0")]
4004 UNSPEC_STRCMPCC_TO_INT)))
4005 (clobber (reg:CC CC_REGNUM))]
4008 "&& reload_completed"
4009 [(set (match_dup 0) (ashift:DI (match_dup 0) (const_int 34)))
4011 [(set (match_dup 0) (ashiftrt:DI (match_dup 0) (const_int 62)))
4012 (clobber (reg:CC CC_REGNUM))])])
4014 (define_insn_and_split "*cmpint_sign_cc"
4015 [(set (reg CC_REGNUM)
4016 (compare (ashiftrt:DI (ashift:DI (subreg:DI
4017 (unspec:SI [(match_operand:CCU 1 "register_operand" "0")]
4018 UNSPEC_STRCMPCC_TO_INT) 0)
4019 (const_int 32)) (const_int 32))
4021 (set (match_operand:DI 0 "register_operand" "=d")
4022 (sign_extend:DI (unspec:SI [(match_dup 1)] UNSPEC_STRCMPCC_TO_INT)))]
4023 "s390_match_ccmode (insn, CCSmode) && TARGET_ZARCH"
4025 "&& reload_completed"
4026 [(set (match_dup 0) (ashift:DI (match_dup 0) (const_int 34)))
4028 [(set (match_dup 2) (match_dup 3))
4029 (set (match_dup 0) (ashiftrt:DI (match_dup 0) (const_int 62)))])]
4031 rtx result = gen_rtx_ASHIFTRT (DImode, operands[0], GEN_INT (62));
4032 operands[2] = SET_DEST (XVECEXP (PATTERN (curr_insn), 0, 0));
4033 operands[3] = gen_rtx_COMPARE (GET_MODE (operands[2]), result, const0_rtx);
4038 ;;- Conversion instructions.
4041 (define_insn "*sethighpartsi"
4042 [(set (match_operand:SI 0 "register_operand" "=d,d")
4043 (unspec:SI [(match_operand:BLK 1 "s_operand" "Q,S")
4044 (match_operand 2 "const_int_operand" "n,n")] UNSPEC_ICM))
4045 (clobber (reg:CC CC_REGNUM))]
4050 [(set_attr "op_type" "RS,RSY")
4051 (set_attr "cpu_facility" "*,longdisp")
4052 (set_attr "z10prop" "z10_super_E1,z10_super_E1")])
4054 (define_insn "*sethighpartdi_64"
4055 [(set (match_operand:DI 0 "register_operand" "=d")
4056 (unspec:DI [(match_operand:BLK 1 "s_operand" "S")
4057 (match_operand 2 "const_int_operand" "n")] UNSPEC_ICM))
4058 (clobber (reg:CC CC_REGNUM))]
4061 [(set_attr "op_type" "RSY")
4062 (set_attr "z10prop" "z10_super")])
4064 (define_insn "*sethighpartdi_31"
4065 [(set (match_operand:DI 0 "register_operand" "=d,d")
4066 (unspec:DI [(match_operand:BLK 1 "s_operand" "Q,S")
4067 (match_operand 2 "const_int_operand" "n,n")] UNSPEC_ICM))
4068 (clobber (reg:CC CC_REGNUM))]
4073 [(set_attr "op_type" "RS,RSY")
4074 (set_attr "cpu_facility" "*,longdisp")
4075 (set_attr "z10prop" "z10_super_E1,z10_super_E1")])
4078 ; extv instruction patterns
4081 ; FIXME: This expander needs to be converted from DI to GPR as well
4082 ; after resolving some issues with it.
4084 (define_expand "extzv"
4086 [(set (match_operand:DI 0 "register_operand" "=d")
4088 (match_operand:DI 1 "register_operand" "d")
4089 (match_operand 2 "const_int_operand" "") ; size
4090 (match_operand 3 "const_int_operand" ""))) ; start
4091 (clobber (reg:CC CC_REGNUM))])]
4094 if (! EXTRACT_ARGS_IN_RANGE (INTVAL (operands[2]), INTVAL (operands[3]), 64))
4096 /* Starting with zEC12 there is risbgn not clobbering CC. */
4099 emit_move_insn (operands[0],
4100 gen_rtx_ZERO_EXTRACT (DImode,
4108 (define_insn "*extzv<mode><clobbercc_or_nocc>"
4109 [(set (match_operand:GPR 0 "register_operand" "=d")
4111 (match_operand:GPR 1 "register_operand" "d")
4112 (match_operand 2 "const_int_operand" "") ; size
4113 (match_operand 3 "const_int_operand" ""))) ; start
4115 "<z10_or_zEC12_cond>
4116 && EXTRACT_ARGS_IN_RANGE (INTVAL (operands[2]), INTVAL (operands[3]),
4117 GET_MODE_BITSIZE (<MODE>mode))"
4118 "<risbg_n>\t%0,%1,64-%2,128+63,<bitoff_plus>%3+%2" ; dst, src, start, end, shift
4119 [(set_attr "op_type" "RIE")
4120 (set_attr "z10prop" "z10_super_E1")])
4122 ; 64 bit: (a & -16) | ((b >> 8) & 15)
4123 (define_insn "*extzvdi<clobbercc_or_nocc>_lshiftrt"
4124 [(set (zero_extract:DI (match_operand:DI 0 "register_operand" "+d")
4125 (match_operand 1 "const_int_operand" "") ; size
4126 (match_operand 2 "const_int_operand" "")) ; start
4127 (lshiftrt:DI (match_operand:DI 3 "register_operand" "d")
4128 (match_operand:DI 4 "nonzero_shift_count_operand" "")))]
4129 "<z10_or_zEC12_cond>
4130 && EXTRACT_ARGS_IN_RANGE (INTVAL (operands[1]), INTVAL (operands[2]), 64)
4131 && 64 - UINTVAL (operands[4]) >= UINTVAL (operands[1])"
4132 "<risbg_n>\t%0,%3,%2,%2+%1-1,128-%2-%1-%4"
4133 [(set_attr "op_type" "RIE")
4134 (set_attr "z10prop" "z10_super_E1")])
4136 ; (a & -16) | ((b >> 8) & 15)
4137 (define_insn "*<risbg_n>_ior_and_sr_ze<mode>"
4138 [(set (match_operand:DSI 0 "register_operand" "=d")
4140 (match_operand:DSI 1 "register_operand" "0")
4141 (match_operand:DSI 2 "const_int_operand" ""))
4143 (match_operand:DSI 3 "register_operand" "d")
4144 (match_operand 4 "const_int_operand" "") ; size
4145 (match_operand 5 "const_int_operand" "")) ; start
4147 "<z10_or_zEC12_cond>
4148 && EXTRACT_ARGS_IN_RANGE (INTVAL (operands[4]), INTVAL (operands[5]), <DSI:bitsize>)
4149 && UINTVAL (operands[2]) == (HOST_WIDE_INT_M1U << UINTVAL (operands[4]))"
4150 "<risbg_n>\t%0,%3,64-%4,63,(64-<DSI:bitsize>)+%4+%5"
4151 [(set_attr "op_type" "RIE")
4152 (set_attr "z10prop" "z10_super_E1")])
4154 ; ((int)foo >> 10) & 1;
4155 (define_insn "*extract1bitdi<clobbercc_or_nocc>"
4156 [(set (match_operand:DI 0 "register_operand" "=d")
4157 (ne:DI (zero_extract:DI
4158 (match_operand:DI 1 "register_operand" "d")
4159 (const_int 1) ; size
4160 (match_operand 2 "const_int_operand" "")) ; start
4162 "<z10_or_zEC12_cond>
4163 && EXTRACT_ARGS_IN_RANGE (1, INTVAL (operands[2]), 64)"
4164 "<risbg_n>\t%0,%1,64-1,128+63,%2+1" ; dst, src, start, end, shift
4165 [(set_attr "op_type" "RIE")
4166 (set_attr "z10prop" "z10_super_E1")])
4168 (define_insn "*<risbg_n>_and_subregdi_rotr"
4169 [(set (match_operand:DI 0 "register_operand" "=d")
4171 (rotate:SINT (match_operand:SINT 1 "register_operand" "d")
4172 (match_operand:SINT 2 "const_int_operand" "")) 0)
4173 (match_operand:DI 3 "contiguous_bitmask_operand" "")))]
4174 "<z10_or_zEC12_cond>
4175 && (UINTVAL (operands[3])
4176 < (HOST_WIDE_INT_1U << (UINTVAL (operands[2]) & 0x3f)))"
4177 "<risbg_n>\t%0,%1,%s3,128+%e3,<bitoff_plus>%2" ; dst, src, start, end, shift
4178 [(set_attr "op_type" "RIE")
4179 (set_attr "z10prop" "z10_super_E1")])
4181 (define_insn "*<risbg_n>_and_subregdi_rotl"
4182 [(set (match_operand:DI 0 "register_operand" "=d")
4184 (rotate:SINT (match_operand:SINT 1 "register_operand" "d")
4185 (match_operand:SINT 2 "const_int_operand" "")) 0)
4186 (match_operand:DI 3 "contiguous_bitmask_operand" "")))]
4187 "<z10_or_zEC12_cond>
4188 && !(UINTVAL (operands[3])
4189 & ((HOST_WIDE_INT_1U << (UINTVAL (operands[2]) & 0x3f)) - 1))"
4190 "<risbg_n>\t%0,%1,%s3,128+%e3,%2" ; dst, src, start, end, shift
4191 [(set_attr "op_type" "RIE")
4192 (set_attr "z10prop" "z10_super_E1")])
4194 (define_insn "*<risbg_n>_di_and_rot"
4195 [(set (match_operand:DI 0 "register_operand" "=d")
4196 (and:DI (rotate:DI (match_operand:DI 1 "register_operand" "d")
4197 (match_operand:DI 2 "const_int_operand" ""))
4198 (match_operand:DI 3 "contiguous_bitmask_operand" "")))]
4199 "<z10_or_zEC12_cond>"
4200 "<risbg_n>\t%0,%1,%s3,128+%e3,%2" ; dst, src, start, end, shift
4201 [(set_attr "op_type" "RIE")
4202 (set_attr "z10prop" "z10_super_E1")])
4204 (define_insn_and_split "*pre_z10_extzv<mode>"
4205 [(set (match_operand:GPR 0 "register_operand" "=d")
4206 (zero_extract:GPR (match_operand:QI 1 "s_operand" "S")
4207 (match_operand 2 "nonzero_shift_count_operand" "")
4209 (clobber (reg:CC CC_REGNUM))]
4212 "&& reload_completed"
4214 [(set (match_dup 0) (unspec:GPR [(match_dup 1) (match_dup 3)] UNSPEC_ICM))
4215 (clobber (reg:CC CC_REGNUM))])
4216 (set (match_dup 0) (lshiftrt:GPR (match_dup 0) (match_dup 2)))]
4218 int bitsize = INTVAL (operands[2]);
4219 int size = (bitsize - 1) / BITS_PER_UNIT + 1; /* round up */
4220 unsigned HOST_WIDE_INT mask
4221 = ((HOST_WIDE_INT_1U << size) - 1) << (GET_MODE_SIZE (SImode) - size);
4223 operands[1] = adjust_address (operands[1], BLKmode, 0);
4224 set_mem_size (operands[1], size);
4225 operands[2] = GEN_INT (<GPR:bitsize> - bitsize);
4226 operands[3] = GEN_INT (mask);
4229 (define_insn_and_split "*pre_z10_extv<mode>"
4230 [(set (match_operand:GPR 0 "register_operand" "=d")
4231 (sign_extract:GPR (match_operand:QI 1 "s_operand" "S")
4232 (match_operand 2 "nonzero_shift_count_operand" "")
4234 (clobber (reg:CC CC_REGNUM))]
4237 "&& reload_completed"
4239 [(set (match_dup 0) (unspec:GPR [(match_dup 1) (match_dup 3)] UNSPEC_ICM))
4240 (clobber (reg:CC CC_REGNUM))])
4242 [(set (match_dup 0) (ashiftrt:GPR (match_dup 0) (match_dup 2)))
4243 (clobber (reg:CC CC_REGNUM))])]
4245 int bitsize = INTVAL (operands[2]);
4246 int size = (bitsize - 1) / BITS_PER_UNIT + 1; /* round up */
4247 unsigned HOST_WIDE_INT mask
4248 = ((HOST_WIDE_INT_1U << size) - 1) << (GET_MODE_SIZE (SImode) - size);
4250 operands[1] = adjust_address (operands[1], BLKmode, 0);
4251 set_mem_size (operands[1], size);
4252 operands[2] = GEN_INT (<GPR:bitsize> - bitsize);
4253 operands[3] = GEN_INT (mask);
4257 ; insv instruction patterns
4260 (define_expand "insv"
4261 [(set (zero_extract (match_operand 0 "nonimmediate_operand" "")
4262 (match_operand 1 "const_int_operand" "")
4263 (match_operand 2 "const_int_operand" ""))
4264 (match_operand 3 "general_operand" ""))]
4267 if (s390_expand_insv (operands[0], operands[1], operands[2], operands[3]))
4273 ; The normal RTL expansion will never generate a zero_extract where
4274 ; the location operand isn't word mode. However, we do this in the
4275 ; back-end when generating atomic operations. See s390_two_part_insv.
4276 (define_insn "*insv<mode><clobbercc_or_nocc>"
4277 [(set (zero_extract:GPR (match_operand:GPR 0 "nonimmediate_operand" "+d")
4278 (match_operand 1 "const_int_operand" "I") ; size
4279 (match_operand 2 "const_int_operand" "I")) ; pos
4280 (match_operand:GPR 3 "nonimmediate_operand" "d"))]
4281 "<z10_or_zEC12_cond>
4282 && EXTRACT_ARGS_IN_RANGE (INTVAL (operands[1]), INTVAL (operands[2]),
4283 GET_MODE_BITSIZE (<MODE>mode))
4284 && (INTVAL (operands[1]) + INTVAL (operands[2])) <= <bitsize>"
4285 "<risbg_n>\t%0,%3,<bitoff_plus>%2,<bitoff_plus>%2+%1-1,<bitsize>-%2-%1"
4286 [(set_attr "op_type" "RIE")
4287 (set_attr "z10prop" "z10_super_E1")])
4289 ; and op1 with a mask being 1 for the selected bits and 0 for the rest
4290 ; and op3=op0 with a mask being 0 for the selected bits and 1 for the rest
4291 (define_insn "*insv<mode><clobbercc_or_nocc>_noshift"
4292 [(set (match_operand:GPR 0 "nonimmediate_operand" "=d,d")
4293 (ior:GPR (and:GPR (match_operand:GPR 1 "nonimmediate_operand" "d,0")
4294 (match_operand:GPR 2 "contiguous_bitmask_operand" ""))
4295 (and:GPR (match_operand:GPR 3 "nonimmediate_operand" "0,d")
4296 (match_operand:GPR 4 "const_int_operand" ""))))]
4297 "<z10_or_zEC12_cond> && INTVAL (operands[2]) == ~INTVAL (operands[4])"
4299 <risbg_n>\t%0,%1,%<bfstart>2,%<bfend>2,0
4300 <risbg_n>\t%0,%3,%<bfstart>4,%<bfend>4,0"
4301 [(set_attr "op_type" "RIE")
4302 (set_attr "z10prop" "z10_super_E1")])
4304 (define_insn "*insv_z10_noshift_cc"
4305 [(set (reg CC_REGNUM)
4308 (and:DI (match_operand:DI 1 "nonimmediate_operand" "d,0")
4309 (match_operand:DI 2 "contiguous_bitmask_operand" ""))
4310 (and:DI (match_operand:DI 3 "nonimmediate_operand" "0,d")
4311 (match_operand:DI 4 "const_int_operand" "")))
4313 (set (match_operand:DI 0 "nonimmediate_operand" "=d,d")
4314 (ior:DI (and:DI (match_dup 1) (match_dup 2))
4315 (and:DI (match_dup 3) (match_dup 4))))]
4316 "TARGET_Z10 && s390_match_ccmode (insn, CCSmode)
4317 && INTVAL (operands[2]) == ~INTVAL (operands[4])"
4319 risbg\t%0,%1,%s2,%e2,0
4320 risbg\t%0,%3,%s4,%e4,0"
4321 [(set_attr "op_type" "RIE")
4322 (set_attr "z10prop" "z10_super_E1")])
4324 (define_insn "*insv_z10_noshift_cconly"
4329 (and:DI (match_operand:DI 1 "nonimmediate_operand" "d,0")
4330 (match_operand:DI 2 "contiguous_bitmask_operand" ""))
4331 (and:DI (match_operand:DI 3 "nonimmediate_operand" "0,d")
4332 (match_operand:DI 4 "const_int_operand" "")))
4334 (clobber (match_scratch:DI 0 "=d,d"))]
4335 "TARGET_Z10 && s390_match_ccmode (insn, CCSmode)
4336 && INTVAL (operands[2]) == ~INTVAL (operands[4])"
4338 risbg\t%0,%1,%s2,%e2,0
4339 risbg\t%0,%3,%s4,%e4,0"
4340 [(set_attr "op_type" "RIE")
4341 (set_attr "z10prop" "z10_super_E1")])
4343 ; Implement appending Y on the left of S bits of X
4344 ; x = (y << s) | (x & ((1 << s) - 1))
4345 (define_insn "*insv<mode><clobbercc_or_nocc>_appendbitsleft"
4346 [(set (match_operand:GPR 0 "nonimmediate_operand" "=d")
4347 (ior:GPR (and:GPR (match_operand:GPR 1 "nonimmediate_operand" "0")
4348 (match_operand:GPR 2 "immediate_operand" ""))
4349 (ashift:GPR (match_operand:GPR 3 "nonimmediate_operand" "d")
4350 (match_operand:GPR 4 "nonzero_shift_count_operand" ""))))]
4351 "<z10_or_zEC12_cond>
4352 && UINTVAL (operands[2]) == (HOST_WIDE_INT_1U << UINTVAL (operands[4])) - 1"
4353 "<risbg_n>\t%0,%3,<bitoff>,64-%4-1,%4"
4354 [(set_attr "op_type" "RIE")
4355 (set_attr "z10prop" "z10_super_E1")])
4357 ; a = ((i32)a & -16777216) | (((ui32)b) >> 8)
4358 (define_insn "*<risbg_n>_<mode>_ior_and_lshiftrt"
4359 [(set (match_operand:GPR 0 "register_operand" "=d")
4361 (match_operand:GPR 1 "register_operand" "0")
4362 (match_operand:GPR 2 "const_int_operand" ""))
4364 (match_operand:GPR 3 "register_operand" "d")
4365 (match_operand:GPR 4 "nonzero_shift_count_operand" ""))))]
4366 "<z10_or_zEC12_cond> && UINTVAL (operands[2])
4367 == (HOST_WIDE_INT_M1U
4368 << (GET_MODE_BITSIZE (<MODE>mode) - UINTVAL (operands[4])))"
4369 "<risbg_n>\t%0,%3,<bitoff_plus>%4,63,64-%4"
4370 [(set_attr "op_type" "RIE")
4371 (set_attr "z10prop" "z10_super_E1")])
4373 ; (ui32)(((ui64)x) >> 48) | ((i32)y & -65536);
4374 (define_insn "*<risbg_n>_sidi_ior_and_lshiftrt"
4375 [(set (match_operand:SI 0 "register_operand" "=d")
4377 (match_operand:SI 1 "register_operand" "0")
4378 (match_operand:SI 2 "const_int_operand" ""))
4381 (match_operand:DI 3 "register_operand" "d")
4382 (match_operand:DI 4 "nonzero_shift_count_operand" "")) 4)))]
4383 "<z10_or_zEC12_cond>
4384 && UINTVAL (operands[2]) == ~(HOST_WIDE_INT_M1U >> UINTVAL (operands[4]))"
4385 "<risbg_n>\t%0,%3,%4,63,64-%4"
4386 [(set_attr "op_type" "RIE")
4387 (set_attr "z10prop" "z10_super_E1")])
4389 ; (ui32)(((ui64)x) >> 12) & -4
4390 (define_insn "*trunc_sidi_and_subreg_lshrt<clobbercc_or_nocc>"
4391 [(set (match_operand:SI 0 "register_operand" "=d")
4393 (subreg:SI (lshiftrt:DI
4394 (match_operand:DI 1 "register_operand" "d")
4395 (match_operand:DI 2 "nonzero_shift_count_operand" "")) 4)
4396 (match_operand:SI 3 "contiguous_bitmask_nowrap_operand" "")))]
4397 "<z10_or_zEC12_cond>"
4398 "<risbg_n>\t%0,%1,%t3,128+%f3,64-%2"
4399 [(set_attr "op_type" "RIE")
4400 (set_attr "z10prop" "z10_super_E1")])
4402 ; (ui32)(((ui64)x) >> 12) & -4
4403 (define_insn "*trunc_sidi_and_subreg_ze<clobbercc_or_nocc>"
4404 [(set (match_operand:SI 0 "register_operand" "=d")
4406 (subreg:SI (zero_extract:DI
4407 (match_operand:DI 1 "register_operand" "d")
4409 (match_operand:SI 2 "nonzero_shift_count_operand" "")) 4)
4410 (match_operand:SI 3 "contiguous_bitmask_nowrap_operand" "")))]
4411 "<z10_or_zEC12_cond>"
4412 "<risbg_n>\t%0,%1,%t3,128+%f3,32+%2"
4413 [(set_attr "op_type" "RIE")
4414 (set_attr "z10prop" "z10_super_E1")])
4416 ; z = (x << c) | (y >> d) with (x << c) and (y >> d) not overlapping after shifting
4417 ; -> z = y >> d; z = (x << c) | (z & ((1 << c) - 1))
4418 ; -> z = y >> d; z = risbg;
4421 [(set (match_operand:GPR 0 "nonimmediate_operand" "")
4422 (ior:GPR (lshiftrt:GPR (match_operand:GPR 1 "nonimmediate_operand" "")
4423 (match_operand:GPR 2 "nonzero_shift_count_operand" ""))
4424 (ashift:GPR (match_operand:GPR 3 "nonimmediate_operand" "")
4425 (match_operand:GPR 4 "nonzero_shift_count_operand" ""))))]
4426 "TARGET_ZEC12 && UINTVAL (operands[2]) + UINTVAL (operands[4]) >= <bitsize>"
4428 (lshiftrt:GPR (match_dup 1) (match_dup 2)))
4430 (ior:GPR (and:GPR (match_dup 6) (match_dup 5))
4431 (ashift:GPR (match_dup 3) (match_dup 4))))]
4433 operands[5] = GEN_INT ((HOST_WIDE_INT_1U << UINTVAL (operands[4])) - 1);
4434 if (reg_overlap_mentioned_p (operands[0], operands[3]))
4436 if (!can_create_pseudo_p ())
4438 operands[6] = gen_reg_rtx (<MODE>mode);
4441 operands[6] = operands[0];
4446 [(set (match_operand:GPR 0 "nonimmediate_operand" "")
4447 (ior:GPR (lshiftrt:GPR (match_operand:GPR 1 "nonimmediate_operand" "")
4448 (match_operand:GPR 2 "nonzero_shift_count_operand" ""))
4449 (ashift:GPR (match_operand:GPR 3 "nonimmediate_operand" "")
4450 (match_operand:GPR 4 "nonzero_shift_count_operand" ""))))
4451 (clobber (reg:CC CC_REGNUM))])]
4452 "TARGET_Z10 && !TARGET_ZEC12 && UINTVAL (operands[2]) + UINTVAL (operands[4]) >= <bitsize>"
4454 (lshiftrt:GPR (match_dup 1) (match_dup 2)))
4457 (ior:GPR (and:GPR (match_dup 6) (match_dup 5))
4458 (ashift:GPR (match_dup 3) (match_dup 4))))
4459 (clobber (reg:CC CC_REGNUM))])]
4461 operands[5] = GEN_INT ((HOST_WIDE_INT_1U << UINTVAL (operands[4])) - 1);
4462 if (reg_overlap_mentioned_p (operands[0], operands[3]))
4464 if (!can_create_pseudo_p ())
4466 operands[6] = gen_reg_rtx (<MODE>mode);
4469 operands[6] = operands[0];
4473 (define_insn "*r<noxa>sbg_<mode>_noshift"
4474 [(set (match_operand:GPR 0 "nonimmediate_operand" "=d")
4476 (and:GPR (match_operand:GPR 1 "nonimmediate_operand" "d")
4477 (match_operand:GPR 2 "contiguous_bitmask_operand" ""))
4478 (match_operand:GPR 3 "nonimmediate_operand" "0")))
4479 (clobber (reg:CC CC_REGNUM))]
4481 "r<noxa>sbg\t%0,%1,%<bfstart>2,%<bfend>2,0"
4482 [(set_attr "op_type" "RIE")])
4485 (define_insn "*r<noxa>sbg_di_rotl"
4486 [(set (match_operand:DI 0 "nonimmediate_operand" "=d")
4490 (match_operand:DI 1 "nonimmediate_operand" "d")
4491 (match_operand:DI 3 "const_int_operand" ""))
4492 (match_operand:DI 2 "contiguous_bitmask_operand" ""))
4493 (match_operand:DI 4 "nonimmediate_operand" "0")))
4494 (clobber (reg:CC CC_REGNUM))]
4496 "r<noxa>sbg\t%0,%1,%s2,%e2,%b3"
4497 [(set_attr "op_type" "RIE")])
4500 (define_insn "*r<noxa>sbg_<mode>_srl_bitmask"
4501 [(set (match_operand:GPR 0 "nonimmediate_operand" "=d")
4505 (match_operand:GPR 1 "nonimmediate_operand" "d")
4506 (match_operand:GPR 3 "nonzero_shift_count_operand" ""))
4507 (match_operand:GPR 2 "contiguous_bitmask_nowrap_operand" ""))
4508 (match_operand:GPR 4 "nonimmediate_operand" "0")))
4509 (clobber (reg:CC CC_REGNUM))]
4511 && s390_extzv_shift_ok (<bitsize>, 64 - INTVAL (operands[3]),
4512 INTVAL (operands[2]))"
4514 operands[3] = GEN_INT (64 - INTVAL (operands[3]));
4515 return "r<noxa>sbg\t%0,%1,%<bfstart>2,%<bfend>2,%3";
4517 [(set_attr "op_type" "RIE")])
4520 (define_insn "*r<noxa>sbg_<mode>_sll_bitmask"
4521 [(set (match_operand:GPR 0 "nonimmediate_operand" "=d")
4525 (match_operand:GPR 1 "nonimmediate_operand" "d")
4526 (match_operand:GPR 3 "nonzero_shift_count_operand" ""))
4527 (match_operand:GPR 2 "contiguous_bitmask_nowrap_operand" ""))
4528 (match_operand:GPR 4 "nonimmediate_operand" "0")))
4529 (clobber (reg:CC CC_REGNUM))]
4531 && s390_extzv_shift_ok (<bitsize>, INTVAL (operands[3]),
4532 INTVAL (operands[2]))"
4533 "r<noxa>sbg\t%0,%1,%<bfstart>2,%<bfend>2,%3"
4534 [(set_attr "op_type" "RIE")])
4536 ;; unsigned {int,long} a, b
4537 ;; a = a | (b << const_int)
4538 ;; a = a ^ (b << const_int)
4540 (define_insn "*r<noxa>sbg_<mode>_sll"
4541 [(set (match_operand:GPR 0 "nonimmediate_operand" "=d")
4544 (match_operand:GPR 1 "nonimmediate_operand" "d")
4545 (match_operand:GPR 2 "nonzero_shift_count_operand" ""))
4546 (match_operand:GPR 3 "nonimmediate_operand" "0")))
4547 (clobber (reg:CC CC_REGNUM))]
4550 operands[3] = GEN_INT (63 - INTVAL (operands[2]));
4551 return "r<noxa>sbg\t%0,%1,<bitoff>,%3,%2";
4553 [(set_attr "op_type" "RIE")])
4555 ;; unsigned {int,long} a, b
4556 ;; a = a | (b >> const_int)
4557 ;; a = a ^ (b >> const_int)
4559 (define_insn "*r<noxa>sbg_<mode>_srl"
4560 [(set (match_operand:GPR 0 "nonimmediate_operand" "=d")
4563 (match_operand:GPR 1 "nonimmediate_operand" "d")
4564 (match_operand:GPR 2 "nonzero_shift_count_operand" ""))
4565 (match_operand:GPR 3 "nonimmediate_operand" "0")))
4566 (clobber (reg:CC CC_REGNUM))]
4569 operands[3] = GEN_INT (64 - INTVAL (operands[2]));
4570 operands[2] = GEN_INT (<bitoff_plus> INTVAL (operands[2]));
4571 return "r<noxa>sbg\t%0,%1,%2,63,%3";
4573 [(set_attr "op_type" "RIE")])
4576 (define_insn "*r<noxa>sbg_sidi_srl"
4577 [(set (match_operand:SI 0 "nonimmediate_operand" "=d")
4581 (match_operand:DI 1 "nonimmediate_operand" "d")
4583 (match_operand:DI 2 "immediate_operand" ""))
4585 (match_operand:SI 3 "nonimmediate_operand" "0")))
4586 (clobber (reg:CC CC_REGNUM))]
4589 operands[2] = GEN_INT (32 + INTVAL (operands[2]));
4590 return "r<noxa>sbg\t%0,%1,32,63,%2";
4592 [(set_attr "op_type" "RIE")])
4594 ;; These two are generated by combine for s.bf &= val.
4595 ;; ??? For bitfields smaller than 32-bits, we wind up with SImode
4596 ;; shifts and ands, which results in some truly awful patterns
4597 ;; including subregs of operations. Rather unnecessisarily, IMO.
4600 ;; (set (zero_extract:DI (reg/v:DI 50 [ s ])
4601 ;; (const_int 24 [0x18])
4602 ;; (const_int 0 [0]))
4603 ;; (subreg:DI (and:SI (subreg:SI (lshiftrt:DI (reg/v:DI 50 [ s ])
4604 ;; (const_int 40 [0x28])) 4)
4605 ;; (reg:SI 4 %r4 [ y+4 ])) 0))
4607 ;; we should instead generate
4609 ;; (set (zero_extract:DI (reg/v:DI 50 [ s ])
4610 ;; (const_int 24 [0x18])
4611 ;; (const_int 0 [0]))
4612 ;; (and:DI (lshiftrt:DI (reg/v:DI 50 [ s ])
4613 ;; (const_int 40 [0x28]))
4614 ;; (subreg:DI (reg:SI 4 %r4 [ y+4 ]) 0)))
4616 ;; by noticing that we can push down the outer paradoxical subreg
4617 ;; into the operation.
4619 (define_insn "*insv_rnsbg_noshift"
4620 [(set (zero_extract:DI
4621 (match_operand:DI 0 "nonimmediate_operand" "+d")
4622 (match_operand 1 "const_int_operand" "")
4623 (match_operand 2 "const_int_operand" ""))
4626 (match_operand:DI 3 "nonimmediate_operand" "d")))
4627 (clobber (reg:CC CC_REGNUM))]
4629 && EXTRACT_ARGS_IN_RANGE (INTVAL (operands[1]), INTVAL (operands[2]), 64)
4630 && INTVAL (operands[1]) + INTVAL (operands[2]) == 64"
4631 "rnsbg\t%0,%3,%2,63,0"
4632 [(set_attr "op_type" "RIE")])
4634 (define_insn "*insv_rnsbg_srl"
4635 [(set (zero_extract:DI
4636 (match_operand:DI 0 "nonimmediate_operand" "+d")
4637 (match_operand 1 "const_int_operand" "")
4638 (match_operand 2 "const_int_operand" ""))
4642 (match_operand 3 "const_int_operand" ""))
4643 (match_operand:DI 4 "nonimmediate_operand" "d")))
4644 (clobber (reg:CC CC_REGNUM))]
4646 && EXTRACT_ARGS_IN_RANGE (INTVAL (operands[1]), INTVAL (operands[2]), 64)
4647 && INTVAL (operands[3]) == 64 - INTVAL (operands[1]) - INTVAL (operands[2])"
4648 "rnsbg\t%0,%4,%2,%2+%1-1,%3"
4649 [(set_attr "op_type" "RIE")])
4651 (define_insn "*insv<mode>_mem_reg"
4652 [(set (zero_extract:W (match_operand:QI 0 "memory_operand" "+Q,S")
4653 (match_operand 1 "const_int_operand" "n,n")
4655 (match_operand:W 2 "register_operand" "d,d"))]
4656 "EXTRACT_ARGS_IN_RANGE (INTVAL (operands[1]), 0, 64)
4657 && INTVAL (operands[1]) > 0
4658 && INTVAL (operands[1]) <= GET_MODE_BITSIZE (SImode)
4659 && INTVAL (operands[1]) % BITS_PER_UNIT == 0"
4661 int size = INTVAL (operands[1]) / BITS_PER_UNIT;
4663 operands[1] = GEN_INT ((HOST_WIDE_INT_1U << size) - 1);
4664 return (which_alternative == 0) ? "stcm\t%2,%1,%S0"
4665 : "stcmy\t%2,%1,%S0";
4667 [(set_attr "op_type" "RS,RSY")
4668 (set_attr "cpu_facility" "*,longdisp")
4669 (set_attr "z10prop" "z10_super,z10_super")])
4671 (define_insn "*insvdi_mem_reghigh"
4672 [(set (zero_extract:DI (match_operand:QI 0 "memory_operand" "+S")
4673 (match_operand 1 "const_int_operand" "n")
4675 (lshiftrt:DI (match_operand:DI 2 "register_operand" "d")
4678 && EXTRACT_ARGS_IN_RANGE (INTVAL (operands[1]), 0, 64)
4679 && INTVAL (operands[1]) > 0
4680 && INTVAL (operands[1]) <= GET_MODE_BITSIZE (SImode)
4681 && INTVAL (operands[1]) % BITS_PER_UNIT == 0"
4683 int size = INTVAL (operands[1]) / BITS_PER_UNIT;
4685 operands[1] = GEN_INT ((HOST_WIDE_INT_1U << size) - 1);
4686 return "stcmh\t%2,%1,%S0";
4688 [(set_attr "op_type" "RSY")
4689 (set_attr "z10prop" "z10_super")])
4691 (define_insn "*insvdi_reg_imm"
4692 [(set (zero_extract:DI (match_operand:DI 0 "register_operand" "+d")
4694 (match_operand 1 "const_int_operand" "n"))
4695 (match_operand:DI 2 "const_int_operand" "n"))]
4697 && EXTRACT_ARGS_IN_RANGE (16, INTVAL (operands[1]), 64)
4698 && INTVAL (operands[1]) >= 0
4699 && INTVAL (operands[1]) < BITS_PER_WORD
4700 && INTVAL (operands[1]) % 16 == 0"
4702 switch (BITS_PER_WORD - INTVAL (operands[1]))
4704 case 64: return "iihh\t%0,%x2"; break;
4705 case 48: return "iihl\t%0,%x2"; break;
4706 case 32: return "iilh\t%0,%x2"; break;
4707 case 16: return "iill\t%0,%x2"; break;
4708 default: gcc_unreachable();
4711 [(set_attr "op_type" "RI")
4712 (set_attr "z10prop" "z10_super_E1")])
4714 ; Update the left-most 32 bit of a DI.
4715 (define_insn "*insv_h_di_reg_extimm"
4716 [(set (zero_extract:DI (match_operand:DI 0 "register_operand" "+d")
4719 (match_operand:DI 1 "const_int_operand" "n"))]
4722 [(set_attr "op_type" "RIL")
4723 (set_attr "z10prop" "z10_fwd_E1")])
4725 ; Update the right-most 32 bit of a DI.
4726 (define_insn "*insv_l_di_reg_extimm"
4727 [(set (zero_extract:DI (match_operand:DI 0 "register_operand" "+d")
4730 (match_operand:DI 1 "const_int_operand" "n"))]
4733 [(set_attr "op_type" "RIL")
4734 (set_attr "z10prop" "z10_fwd_A1")])
4737 ; extendsidi2 instruction pattern(s).
4740 (define_expand "extendsidi2"
4741 [(set (match_operand:DI 0 "register_operand" "")
4742 (sign_extend:DI (match_operand:SI 1 "nonimmediate_operand" "")))]
4747 emit_clobber (operands[0]);
4748 emit_move_insn (gen_highpart (SImode, operands[0]), operands[1]);
4749 emit_move_insn (gen_lowpart (SImode, operands[0]), const0_rtx);
4750 emit_insn (gen_ashrdi3 (operands[0], operands[0], GEN_INT (32)));
4755 (define_insn "*extendsidi2"
4756 [(set (match_operand:DI 0 "register_operand" "=d,d,d")
4757 (sign_extend:DI (match_operand:SI 1 "nonimmediate_operand" "d,T,b")))]
4763 [(set_attr "op_type" "RRE,RXY,RIL")
4764 (set_attr "type" "*,*,larl")
4765 (set_attr "cpu_facility" "*,*,z10")
4766 (set_attr "z10prop" "z10_super_E1,z10_super_E1,z10_super_E1")
4767 (set_attr "relative_long" "*,*,yes")])
4770 ; extend(hi|qi)(si|di)2 instruction pattern(s).
4773 (define_expand "extend<HQI:mode><DSI:mode>2"
4774 [(set (match_operand:DSI 0 "register_operand" "")
4775 (sign_extend:DSI (match_operand:HQI 1 "nonimmediate_operand" "")))]
4778 if (<DSI:MODE>mode == DImode && !TARGET_ZARCH)
4780 rtx tmp = gen_reg_rtx (SImode);
4781 emit_insn (gen_extend<HQI:mode>si2 (tmp, operands[1]));
4782 emit_insn (gen_extendsidi2 (operands[0], tmp));
4785 else if (!TARGET_EXTIMM)
4787 rtx bitcount = GEN_INT (<DSI:bitsize> - <HQI:bitsize>);
4789 operands[1] = gen_lowpart (<DSI:MODE>mode, operands[1]);
4790 emit_insn (gen_ashl<DSI:mode>3 (operands[0], operands[1], bitcount));
4791 emit_insn (gen_ashr<DSI:mode>3 (operands[0], operands[0], bitcount));
4797 ; extendhidi2 instruction pattern(s).
4800 (define_insn "*extendhidi2_extimm"
4801 [(set (match_operand:DI 0 "register_operand" "=d,d,d")
4802 (sign_extend:DI (match_operand:HI 1 "general_operand" "d,T,b")))]
4803 "TARGET_ZARCH && TARGET_EXTIMM"
4808 [(set_attr "op_type" "RRE,RXY,RIL")
4809 (set_attr "type" "*,*,larl")
4810 (set_attr "cpu_facility" "extimm,extimm,z10")
4811 (set_attr "z10prop" "z10_super_E1,z10_super_E1,z10_super_E1")
4812 (set_attr "relative_long" "*,*,yes")])
4814 (define_insn "*extendhidi2"
4815 [(set (match_operand:DI 0 "register_operand" "=d")
4816 (sign_extend:DI (match_operand:HI 1 "memory_operand" "T")))]
4819 [(set_attr "op_type" "RXY")
4820 (set_attr "z10prop" "z10_super_E1")])
4823 ; extendhisi2 instruction pattern(s).
4826 (define_insn "*extendhisi2_extimm"
4827 [(set (match_operand:SI 0 "register_operand" "=d,d,d,d")
4828 (sign_extend:SI (match_operand:HI 1 "nonimmediate_operand" " d,R,T,b")))]
4835 [(set_attr "op_type" "RRE,RX,RXY,RIL")
4836 (set_attr "type" "*,*,*,larl")
4837 (set_attr "cpu_facility" "extimm,extimm,extimm,z10")
4838 (set_attr "z10prop" "z10_super_E1,z10_super_E1,z10_super_E1,z10_super_E1")
4839 (set_attr "relative_long" "*,*,*,yes")])
4841 (define_insn "*extendhisi2"
4842 [(set (match_operand:SI 0 "register_operand" "=d,d")
4843 (sign_extend:SI (match_operand:HI 1 "memory_operand" "R,T")))]
4848 [(set_attr "op_type" "RX,RXY")
4849 (set_attr "cpu_facility" "*,longdisp")
4850 (set_attr "z10prop" "z10_super_E1,z10_super_E1")])
4853 ; extendqi(si|di)2 instruction pattern(s).
4856 ; lbr, lgbr, lb, lgb
4857 (define_insn "*extendqi<mode>2_extimm"
4858 [(set (match_operand:GPR 0 "register_operand" "=d,d")
4859 (sign_extend:GPR (match_operand:QI 1 "nonimmediate_operand" "d,T")))]
4864 [(set_attr "op_type" "RRE,RXY")
4865 (set_attr "z10prop" "z10_super_E1,z10_super_E1")])
4868 (define_insn "*extendqi<mode>2"
4869 [(set (match_operand:GPR 0 "register_operand" "=d")
4870 (sign_extend:GPR (match_operand:QI 1 "memory_operand" "T")))]
4871 "!TARGET_EXTIMM && TARGET_LONG_DISPLACEMENT"
4873 [(set_attr "op_type" "RXY")
4874 (set_attr "z10prop" "z10_super_E1")])
4876 (define_insn_and_split "*extendqi<mode>2_short_displ"
4877 [(set (match_operand:GPR 0 "register_operand" "=d")
4878 (sign_extend:GPR (match_operand:QI 1 "s_operand" "Q")))
4879 (clobber (reg:CC CC_REGNUM))]
4880 "!TARGET_EXTIMM && !TARGET_LONG_DISPLACEMENT"
4882 "&& reload_completed"
4884 [(set (match_dup 0) (unspec:GPR [(match_dup 1) (const_int 8)] UNSPEC_ICM))
4885 (clobber (reg:CC CC_REGNUM))])
4887 [(set (match_dup 0) (ashiftrt:GPR (match_dup 0) (match_dup 2)))
4888 (clobber (reg:CC CC_REGNUM))])]
4890 operands[1] = adjust_address (operands[1], BLKmode, 0);
4891 set_mem_size (operands[1], GET_MODE_SIZE (QImode));
4892 operands[2] = GEN_INT (<GPR:bitsize> - BITS_PER_UNIT);
4896 ; zero_extendsidi2 instruction pattern(s).
4899 (define_expand "zero_extendsidi2"
4900 [(set (match_operand:DI 0 "register_operand" "")
4901 (zero_extend:DI (match_operand:SI 1 "nonimmediate_operand" "")))]
4906 emit_clobber (operands[0]);
4907 emit_move_insn (gen_lowpart (SImode, operands[0]), operands[1]);
4908 emit_move_insn (gen_highpart (SImode, operands[0]), const0_rtx);
4913 (define_insn "*zero_extendsidi2"
4914 [(set (match_operand:DI 0 "register_operand" "=d,d,d")
4915 (zero_extend:DI (match_operand:SI 1 "nonimmediate_operand" "d,T,b")))]
4921 [(set_attr "op_type" "RRE,RXY,RIL")
4922 (set_attr "type" "*,*,larl")
4923 (set_attr "cpu_facility" "*,*,z10")
4924 (set_attr "z10prop" "z10_fwd_E1,z10_fwd_A3,z10_fwd_A3")
4925 (set_attr "relative_long" "*,*,yes")])
4928 ; LLGT-type instructions (zero-extend from 31 bit to 64 bit).
4931 (define_insn "*llgt_sidi"
4932 [(set (match_operand:DI 0 "register_operand" "=d")
4933 (and:DI (subreg:DI (match_operand:SI 1 "memory_operand" "T") 0)
4934 (const_int 2147483647)))]
4937 [(set_attr "op_type" "RXE")
4938 (set_attr "z10prop" "z10_super_E1")])
4940 (define_insn_and_split "*llgt_sidi_split"
4941 [(set (match_operand:DI 0 "register_operand" "=d")
4942 (and:DI (subreg:DI (match_operand:SI 1 "memory_operand" "T") 0)
4943 (const_int 2147483647)))
4944 (clobber (reg:CC CC_REGNUM))]
4947 "&& reload_completed"
4949 (and:DI (subreg:DI (match_dup 1) 0)
4950 (const_int 2147483647)))]
4953 (define_insn "*llgt_sisi"
4954 [(set (match_operand:SI 0 "register_operand" "=d,d")
4955 (and:SI (match_operand:SI 1 "nonimmediate_operand" "d,T")
4956 (const_int 2147483647)))]
4961 [(set_attr "op_type" "RRE,RXE")
4962 (set_attr "z10prop" "z10_super_E1,z10_super_E1")])
4964 (define_insn "*llgt_didi"
4965 [(set (match_operand:DI 0 "register_operand" "=d,d")
4966 (and:DI (match_operand:DI 1 "nonimmediate_operand" "d,o")
4967 (const_int 2147483647)))]
4972 [(set_attr "op_type" "RRE,RXE")
4973 (set_attr "z10prop" "z10_super_E1,z10_super_E1")])
4976 [(set (match_operand:DSI 0 "register_operand" "")
4977 (and:DSI (match_operand:DSI 1 "nonimmediate_operand" "")
4978 (const_int 2147483647)))
4979 (clobber (reg:CC CC_REGNUM))]
4980 "TARGET_ZARCH && reload_completed"
4982 (and:DSI (match_dup 1)
4983 (const_int 2147483647)))]
4987 ; zero_extend(hi|qi)(si|di)2 instruction pattern(s).
4990 (define_expand "zero_extend<mode>di2"
4991 [(set (match_operand:DI 0 "register_operand" "")
4992 (zero_extend:DI (match_operand:HQI 1 "nonimmediate_operand" "")))]
4997 rtx tmp = gen_reg_rtx (SImode);
4998 emit_insn (gen_zero_extend<mode>si2 (tmp, operands[1]));
4999 emit_insn (gen_zero_extendsidi2 (operands[0], tmp));
5002 else if (!TARGET_EXTIMM)
5004 rtx bitcount = GEN_INT (64 - <HQI:bitsize>);
5005 operands[1] = gen_lowpart (DImode, operands[1]);
5006 emit_insn (gen_ashldi3 (operands[0], operands[1], bitcount));
5007 emit_insn (gen_lshrdi3 (operands[0], operands[0], bitcount));
5012 (define_expand "zero_extend<mode>si2"
5013 [(set (match_operand:SI 0 "register_operand" "")
5014 (zero_extend:SI (match_operand:HQI 1 "nonimmediate_operand" "")))]
5019 operands[1] = gen_lowpart (SImode, operands[1]);
5020 emit_insn (gen_andsi3 (operands[0], operands[1],
5021 GEN_INT ((1 << <HQI:bitsize>) - 1)));
5027 (define_insn "*zero_extendhi<mode>2_z10"
5028 [(set (match_operand:GPR 0 "register_operand" "=d,d,d")
5029 (zero_extend:GPR (match_operand:HI 1 "nonimmediate_operand" "d,T,b")))]
5035 [(set_attr "op_type" "RXY,RRE,RIL")
5036 (set_attr "type" "*,*,larl")
5037 (set_attr "cpu_facility" "*,*,z10")
5038 (set_attr "z10prop" "z10_super_E1,z10_fwd_A3,z10_fwd_A3")
5039 (set_attr "relative_long" "*,*,yes")])
5041 ; llhr, llcr, llghr, llgcr, llh, llc, llgh, llgc
5042 (define_insn "*zero_extend<HQI:mode><GPR:mode>2_extimm"
5043 [(set (match_operand:GPR 0 "register_operand" "=d,d")
5044 (zero_extend:GPR (match_operand:HQI 1 "nonimmediate_operand" "d,T")))]
5049 [(set_attr "op_type" "RRE,RXY")
5050 (set_attr "z10prop" "z10_super_E1,z10_fwd_A3")])
5053 (define_insn "*zero_extend<HQI:mode><GPR:mode>2"
5054 [(set (match_operand:GPR 0 "register_operand" "=d")
5055 (zero_extend:GPR (match_operand:HQI 1 "memory_operand" "T")))]
5056 "TARGET_ZARCH && !TARGET_EXTIMM"
5058 [(set_attr "op_type" "RXY")
5059 (set_attr "z10prop" "z10_fwd_A3")])
5061 (define_insn_and_split "*zero_extendhisi2_31"
5062 [(set (match_operand:SI 0 "register_operand" "=&d")
5063 (zero_extend:SI (match_operand:HI 1 "s_operand" "S")))
5064 (clobber (reg:CC CC_REGNUM))]
5067 "&& reload_completed"
5068 [(set (match_dup 0) (const_int 0))
5070 [(set (strict_low_part (match_dup 2)) (match_dup 1))
5071 (clobber (reg:CC CC_REGNUM))])]
5072 "operands[2] = gen_lowpart (HImode, operands[0]);")
5074 (define_insn_and_split "*zero_extendqisi2_31"
5075 [(set (match_operand:SI 0 "register_operand" "=&d")
5076 (zero_extend:SI (match_operand:QI 1 "memory_operand" "T")))]
5079 "&& reload_completed"
5080 [(set (match_dup 0) (const_int 0))
5081 (set (strict_low_part (match_dup 2)) (match_dup 1))]
5082 "operands[2] = gen_lowpart (QImode, operands[0]);")
5085 ; zero_extendqihi2 instruction pattern(s).
5088 (define_expand "zero_extendqihi2"
5089 [(set (match_operand:HI 0 "register_operand" "")
5090 (zero_extend:HI (match_operand:QI 1 "register_operand" "")))]
5091 "TARGET_ZARCH && !TARGET_EXTIMM"
5093 operands[1] = gen_lowpart (HImode, operands[1]);
5094 emit_insn (gen_andhi3 (operands[0], operands[1], GEN_INT (0xff)));
5098 (define_insn "*zero_extendqihi2_64"
5099 [(set (match_operand:HI 0 "register_operand" "=d")
5100 (zero_extend:HI (match_operand:QI 1 "memory_operand" "T")))]
5101 "TARGET_ZARCH && !TARGET_EXTIMM"
5103 [(set_attr "op_type" "RXY")
5104 (set_attr "z10prop" "z10_fwd_A3")])
5106 (define_insn_and_split "*zero_extendqihi2_31"
5107 [(set (match_operand:HI 0 "register_operand" "=&d")
5108 (zero_extend:HI (match_operand:QI 1 "memory_operand" "T")))]
5111 "&& reload_completed"
5112 [(set (match_dup 0) (const_int 0))
5113 (set (strict_low_part (match_dup 2)) (match_dup 1))]
5114 "operands[2] = gen_lowpart (QImode, operands[0]);")
5117 ; fixuns_trunc(dd|td|sf|df|tf)(si|di)2 expander
5120 ; This is the only entry point for fixuns_trunc. It multiplexes the
5121 ; expansion to either the *_emu expanders below for pre z196 machines
5122 ; or emits the default pattern otherwise.
5123 (define_expand "fixuns_trunc<FP:mode><GPR:mode>2<FP:tf_fpr>"
5125 [(set (match_operand:GPR 0 "register_operand" "")
5126 (unsigned_fix:GPR (match_operand:FP 1 "register_operand" "")))
5127 (unspec:GPR [(match_dup 2)] UNSPEC_ROUND)
5128 (clobber (reg:CC CC_REGNUM))])]
5133 /* We don't provide emulation for TD|DD->SI. */
5134 if (GET_MODE_CLASS (<FP:MODE>mode) == MODE_DECIMAL_FLOAT
5135 && <GPR:MODE>mode == SImode)
5137 emit_insn (gen_fixuns_trunc<FP:mode><GPR:mode>2_emu (operands[0],
5142 if (GET_MODE_CLASS (<FP:MODE>mode) == MODE_DECIMAL_FLOAT)
5143 operands[2] = GEN_INT (DFP_RND_TOWARD_0);
5145 operands[2] = GEN_INT (BFP_RND_TOWARD_0);
5148 ; (sf|df|tf)->unsigned (si|di)
5150 ; Emulate the unsigned conversion with the signed version for pre z196
5152 (define_expand "fixuns_trunc<BFP:mode><GPR:mode>2_emu"
5154 [(set (match_operand:GPR 0 "register_operand" "")
5155 (unsigned_fix:GPR (match_operand:BFP 1 "register_operand" "")))
5156 (unspec:GPR [(const_int BFP_RND_TOWARD_0)] UNSPEC_ROUND)
5157 (clobber (reg:CC CC_REGNUM))])]
5158 "!TARGET_Z196 && TARGET_HARD_FLOAT"
5160 rtx_code_label *label1 = gen_label_rtx ();
5161 rtx_code_label *label2 = gen_label_rtx ();
5162 rtx temp = gen_reg_rtx (<BFP:MODE>mode);
5163 REAL_VALUE_TYPE cmp, sub;
5165 operands[1] = force_reg (<BFP:MODE>mode, operands[1]);
5166 real_2expN (&cmp, <GPR:bitsize> - 1, <BFP:MODE>mode);
5167 real_2expN (&sub, <GPR:bitsize>, <BFP:MODE>mode);
5169 emit_cmp_and_jump_insns (operands[1],
5170 const_double_from_real_value (cmp, <BFP:MODE>mode),
5171 LT, NULL_RTX, VOIDmode, 0, label1);
5172 emit_insn (gen_sub<BFP:mode>3 (temp, operands[1],
5173 const_double_from_real_value (sub, <BFP:MODE>mode)));
5174 emit_insn (gen_fix_trunc<BFP:mode><GPR:mode>2_bfp (operands[0], temp,
5175 GEN_INT (BFP_RND_TOWARD_MINF)));
5178 emit_label (label1);
5179 emit_insn (gen_fix_trunc<BFP:mode><GPR:mode>2_bfp (operands[0],
5181 GEN_INT (BFP_RND_TOWARD_0)));
5182 emit_label (label2);
5188 ; Emulate the unsigned conversion with the signed version for pre z196
5190 (define_expand "fixuns_truncdddi2_emu"
5192 [(set (match_operand:DI 0 "register_operand" "")
5193 (unsigned_fix:DI (match_operand:DD 1 "register_operand" "")))
5194 (unspec:DI [(const_int DFP_RND_TOWARD_0)] UNSPEC_ROUND)
5195 (clobber (reg:CC CC_REGNUM))])]
5197 "!TARGET_Z196 && TARGET_HARD_DFP"
5199 rtx_code_label *label1 = gen_label_rtx ();
5200 rtx_code_label *label2 = gen_label_rtx ();
5201 rtx temp = gen_reg_rtx (TDmode);
5202 REAL_VALUE_TYPE cmp, sub;
5204 decimal_real_from_string (&cmp, "9223372036854775808.0"); /* 2^63 */
5205 decimal_real_from_string (&sub, "18446744073709551616.0"); /* 2^64 */
5207 /* 2^63 can't be represented as 64bit DFP number with full precision. The
5208 solution is doing the check and the subtraction in TD mode and using a
5209 TD -> DI convert afterwards. */
5210 emit_insn (gen_extendddtd2 (temp, operands[1]));
5211 temp = force_reg (TDmode, temp);
5212 emit_cmp_and_jump_insns (temp,
5213 const_double_from_real_value (cmp, TDmode),
5214 LT, NULL_RTX, VOIDmode, 0, label1);
5215 emit_insn (gen_subtd3 (temp, temp,
5216 const_double_from_real_value (sub, TDmode)));
5217 emit_insn (gen_fix_trunctddi2_dfp (operands[0], temp,
5218 GEN_INT (DFP_RND_TOWARD_MINF)));
5221 emit_label (label1);
5222 emit_insn (gen_fix_truncdddi2_dfp (operands[0], operands[1],
5223 GEN_INT (DFP_RND_TOWARD_0)));
5224 emit_label (label2);
5230 ; Emulate the unsigned conversion with the signed version for pre z196
5232 (define_expand "fixuns_trunctddi2_emu"
5234 [(set (match_operand:DI 0 "register_operand" "")
5235 (unsigned_fix:DI (match_operand:TD 1 "register_operand" "")))
5236 (unspec:DI [(const_int DFP_RND_TOWARD_0)] UNSPEC_ROUND)
5237 (clobber (reg:CC CC_REGNUM))])]
5239 "!TARGET_Z196 && TARGET_HARD_DFP"
5241 rtx_code_label *label1 = gen_label_rtx ();
5242 rtx_code_label *label2 = gen_label_rtx ();
5243 rtx temp = gen_reg_rtx (TDmode);
5244 REAL_VALUE_TYPE cmp, sub;
5246 operands[1] = force_reg (TDmode, operands[1]);
5247 decimal_real_from_string (&cmp, "9223372036854775808.0"); /* 2^63 */
5248 decimal_real_from_string (&sub, "18446744073709551616.0"); /* 2^64 */
5250 emit_cmp_and_jump_insns (operands[1],
5251 const_double_from_real_value (cmp, TDmode),
5252 LT, NULL_RTX, VOIDmode, 0, label1);
5253 emit_insn (gen_subtd3 (temp, operands[1],
5254 const_double_from_real_value (sub, TDmode)));
5255 emit_insn (gen_fix_trunctddi2_dfp (operands[0], temp,
5256 GEN_INT (DFP_RND_TOWARD_MINF)));
5259 emit_label (label1);
5260 emit_insn (gen_fix_trunctddi2_dfp (operands[0], operands[1],
5261 GEN_INT (DFP_RND_TOWARD_0)));
5262 emit_label (label2);
5266 ; Just a dummy to make the code in the first expander a bit easier.
5267 (define_expand "fixuns_trunc<mode>si2_emu"
5269 [(set (match_operand:SI 0 "register_operand" "")
5270 (unsigned_fix:SI (match_operand:DFP 1 "register_operand" "")))
5271 (unspec:DI [(const_int DFP_RND_TOWARD_0)] UNSPEC_ROUND)
5272 (clobber (reg:CC CC_REGNUM))])]
5274 "!TARGET_Z196 && TARGET_HARD_DFP"
5280 ; fixuns_trunc(tf|df|sf|td|dd)(di|si)2 instruction patterns.
5282 ; df -> unsigned di, vxe2: sf -> unsigned si
5283 ; clgdbr, clfebr, wclgdb, wclfeb
5284 (define_insn "*fixuns_trunc<mode><toint>2_z13"
5285 [(set (match_operand:<TOINT> 0 "register_operand" "=d,v")
5286 (unsigned_fix:<TOINT> (match_operand:VX_CONV_BFP 1 "register_operand" "f,v")))
5287 (unspec:DI [(match_operand:DI 2 "immediate_operand" "K,K")] UNSPEC_ROUND)
5288 (clobber (reg:CC CC_REGNUM))]
5289 "TARGET_VX && TARGET_HARD_FLOAT"
5291 cl<gf><xde>br\t%0,%h2,%1,0
5292 wcl<gf><xde>b\t%v0,%v1,0,%h2"
5293 [(set_attr "op_type" "RRF,VRR")
5294 (set_attr "type" "ftoi")])
5296 ; (dd|td|sf|df|tf)->unsigned (di|si)
5297 ; clfebr, clfdbr, clfxbr, clgebr, clgdbr, clgxbr
5298 ; clfdtr, clfxtr, clgdtr, clgxtr
5299 (define_insn "*fixuns_trunc<FP:mode><GPR:mode>2_z196"
5300 [(set (match_operand:GPR 0 "register_operand" "=d")
5301 (unsigned_fix:GPR (match_operand:FP 1 "register_operand" "f")))
5302 (unspec:GPR [(match_operand:GPR 2 "immediate_operand" "K")] UNSPEC_ROUND)
5303 (clobber (reg:CC CC_REGNUM))]
5304 "TARGET_Z196 && TARGET_HARD_FLOAT
5305 && (!TARGET_VX || <GPR:MODE>mode != DImode || <FP:MODE>mode != DFmode)"
5306 "cl<GPR:gf><FP:xde><FP:bt>r\t%0,%h2,%1,0"
5307 [(set_attr "op_type" "RRF")
5308 (set_attr "type" "ftoi")])
5310 (define_expand "fix_trunc<DSF:mode><GPR:mode>2"
5311 [(set (match_operand:GPR 0 "register_operand" "")
5312 (fix:GPR (match_operand:DSF 1 "register_operand" "")))]
5315 emit_insn (gen_fix_trunc<DSF:mode><GPR:mode>2_bfp (operands[0], operands[1],
5316 GEN_INT (BFP_RND_TOWARD_0)));
5320 ; df -> signed di, vxe2: sf -> signed si
5321 ; cgdbr, cfebr, wcgdb, wcfeb
5322 (define_insn "*fix_trunc<mode><toint>2_bfp_z13"
5323 [(set (match_operand:<TOINT> 0 "register_operand" "=d,v")
5324 (fix:<TOINT> (match_operand:VX_CONV_BFP 1 "register_operand" "f,v")))
5325 (unspec:<TOINT> [(match_operand:<TOINT> 2 "immediate_operand" "K,K")] UNSPEC_ROUND)
5326 (clobber (reg:CC CC_REGNUM))]
5327 "TARGET_VX && TARGET_HARD_FLOAT"
5329 c<gf><xde>br\t%0,%h2,%1
5330 wc<gf><xde>b\t%v0,%v1,0,%h2"
5331 [(set_attr "op_type" "RRE,VRR")
5332 (set_attr "type" "ftoi")])
5334 ; cgxbr, cgdbr, cgebr, cfxbr, cfdbr, cfebr
5335 (define_insn "*fix_trunc<BFP:mode><GPR:mode>2_bfp"
5336 [(set (match_operand:GPR 0 "register_operand" "=d")
5337 (fix:GPR (match_operand:BFP 1 "register_operand" "f")))
5338 (unspec:GPR [(match_operand:GPR 2 "immediate_operand" "K")] UNSPEC_ROUND)
5339 (clobber (reg:CC CC_REGNUM))]
5341 && (!TARGET_VX || <GPR:MODE>mode != DImode || <BFP:MODE>mode != DFmode)"
5342 "c<GPR:gf><BFP:xde>br\t%0,%h2,%1"
5343 [(set_attr "op_type" "RRE")
5344 (set_attr "type" "ftoi")])
5346 (define_expand "fix_trunc<BFP:mode><GPR:mode>2_bfp"
5348 [(set (match_operand:GPR 0 "register_operand" "=d")
5349 (fix:GPR (match_operand:BFP 1 "register_operand" "f")))
5350 (unspec:GPR [(match_operand:GPR 2 "immediate_operand" "K")] UNSPEC_ROUND)
5351 (clobber (reg:CC CC_REGNUM))])]
5352 "TARGET_HARD_FLOAT")
5354 ; fix_trunc(td|dd)di2 instruction pattern(s).
5357 (define_expand "fix_trunc<mode>di2"
5358 [(set (match_operand:DI 0 "register_operand" "")
5359 (fix:DI (match_operand:DFP 1 "nonimmediate_operand" "")))]
5360 "TARGET_ZARCH && TARGET_HARD_DFP"
5362 operands[1] = force_reg (<MODE>mode, operands[1]);
5363 emit_insn (gen_fix_trunc<mode>di2_dfp (operands[0], operands[1],
5364 GEN_INT (DFP_RND_TOWARD_0)));
5369 (define_insn "fix_trunc<DFP:mode>di2_dfp"
5370 [(set (match_operand:DI 0 "register_operand" "=d")
5371 (fix:DI (match_operand:DFP 1 "register_operand" "f")))
5372 (unspec:DI [(match_operand:DI 2 "immediate_operand" "K")] UNSPEC_ROUND)
5373 (clobber (reg:CC CC_REGNUM))]
5374 "TARGET_ZARCH && TARGET_HARD_DFP"
5375 "cg<DFP:xde>tr\t%0,%h2,%1"
5376 [(set_attr "op_type" "RRF")
5377 (set_attr "type" "ftoidfp")])
5381 ; fix_trunctf(si|di)2 instruction pattern(s).
5384 (define_expand "fix_trunctf<mode>2_fpr"
5385 [(parallel [(set (match_operand:GPR 0 "register_operand" "")
5386 (fix:GPR (match_operand:TF 1 "register_operand" "")))
5387 (unspec:GPR [(const_int BFP_RND_TOWARD_0)] UNSPEC_ROUND)
5388 (clobber (reg:CC CC_REGNUM))])]
5389 "TARGET_HARD_FLOAT && !TARGET_VXE"
5394 ; float(si|di)(tf|df|sf|td|dd)2 instruction pattern(s).
5397 ; cxgbr, cdgbr, cegbr, cxgtr, cdgtr
5398 (define_insn "floatdi<mode>2<tf_fpr>"
5399 [(set (match_operand:FP 0 "register_operand" "=f,v")
5400 (float:FP (match_operand:DI 1 "register_operand" "d,v")))]
5401 "TARGET_ZARCH && TARGET_HARD_FLOAT"
5405 [(set_attr "op_type" "RRE,VRR")
5406 (set_attr "type" "itof<type>" )
5407 (set_attr "cpu_facility" "*,vx")
5408 (set_attr "enabled" "*,<DFDI>")])
5410 ; cxfbr, cdfbr, cefbr, wcefb
5411 (define_insn "floatsi<mode>2<tf_fpr>"
5412 [(set (match_operand:BFP 0 "register_operand" "=f,v")
5413 (float:BFP (match_operand:SI 1 "register_operand" "d,v")))]
5418 [(set_attr "op_type" "RRE,VRR")
5419 (set_attr "type" "itof<type>" )
5420 (set_attr "cpu_facility" "*,vxe2")
5421 (set_attr "enabled" "*,<SFSI>")])
5424 (define_insn "floatsi<mode>2"
5425 [(set (match_operand:DFP 0 "register_operand" "=f")
5426 (float:DFP (match_operand:SI 1 "register_operand" "d")))]
5427 "TARGET_Z196 && TARGET_HARD_FLOAT"
5428 "c<xde>ftr\t%0,0,%1,0"
5429 [(set_attr "op_type" "RRE")
5430 (set_attr "type" "itof<type>")])
5433 ; floatuns(si|di)(tf|df|sf|td|dd)2 instruction pattern(s).
5436 (define_insn "*floatuns<toint><mode>2_z13"
5437 [(set (match_operand:VX_CONV_BFP 0 "register_operand" "=f,v")
5438 (unsigned_float:VX_CONV_BFP (match_operand:<TOINT> 1 "register_operand" "d,v")))]
5439 "TARGET_VX && TARGET_HARD_FLOAT"
5441 c<xde>l<gf>br\t%0,0,%1,0
5442 wc<xde>l<gf>b\t%v0,%v1,0,0"
5443 [(set_attr "op_type" "RRE,VRR")
5444 (set_attr "type" "itofdf")])
5446 ; cxlgbr, cdlgbr, celgbr, cxlgtr, cdlgtr
5447 ; cxlfbr, cdlfbr, celfbr, cxlftr, cdlftr
5448 (define_insn "*floatuns<GPR:mode><FP:mode>2"
5449 [(set (match_operand:FP 0 "register_operand" "=f")
5450 (unsigned_float:FP (match_operand:GPR 1 "register_operand" "d")))]
5451 "TARGET_Z196 && TARGET_HARD_FLOAT
5452 && (!TARGET_VX || <FP:MODE>mode != DFmode || <GPR:MODE>mode != DImode)"
5453 "c<FP:xde>l<GPR:gf><FP:bt>r\t%0,0,%1,0"
5454 [(set_attr "op_type" "RRE")
5455 (set_attr "type" "itof<FP:type>")])
5457 (define_expand "floatuns<GPR:mode><FP:mode>2<tf_fpr>"
5458 [(set (match_operand:FP 0 "register_operand" "")
5459 (unsigned_float:FP (match_operand:GPR 1 "register_operand" "")))]
5460 "TARGET_Z196 && TARGET_HARD_FLOAT")
5463 ; truncdfsf2 instruction pattern(s).
5466 (define_insn "truncdfsf2"
5467 [(set (match_operand:SF 0 "register_operand" "=f,v")
5468 (float_truncate:SF (match_operand:DF 1 "register_operand" "f,v")))]
5472 wledb\t%v0,%v1,0,0" ; IEEE inexact exception not suppressed
5473 ; According to BFP rounding mode
5474 [(set_attr "op_type" "RRE,VRR")
5475 (set_attr "type" "ftruncdf")
5476 (set_attr "cpu_facility" "*,vx")])
5479 ; trunctf(df|sf)2 instruction pattern(s).
5483 (define_insn "trunctf<mode>2_fpr"
5484 [(set (match_operand:DSF 0 "register_operand" "=f")
5485 (float_truncate:DSF (match_operand:TF 1 "register_operand" "f")))
5486 (clobber (match_scratch:TF 2 "=f"))]
5488 "l<xde>xbr\t%2,%1\;l<xde>r\t%0,%2"
5489 [(set_attr "length" "6")
5490 (set_attr "type" "ftrunctf")])
5493 ; trunctddd2 and truncddsd2 instruction pattern(s).
5497 (define_expand "trunctddd2"
5499 [(set (match_operand:DD 0 "register_operand" "")
5500 (float_truncate:DD (match_operand:TD 1 "register_operand" "")))
5501 (unspec:DI [(const_int DFP_RND_CURRENT)] UNSPEC_ROUND)
5502 (clobber (scratch:TD))])]
5505 (define_insn "*trunctddd2"
5506 [(set (match_operand:DD 0 "register_operand" "=f")
5507 (float_truncate:DD (match_operand:TD 1 "register_operand" "f")))
5508 (unspec:DI [(match_operand:DI 2 "const_mask_operand" "I")] UNSPEC_ROUND)
5509 (clobber (match_scratch:TD 3 "=f"))]
5511 "ldxtr\t%3,%2,%1,0\;ldr\t%0,%3"
5512 [(set_attr "length" "6")
5513 (set_attr "type" "ftruncdd")])
5515 (define_insn "truncddsd2"
5516 [(set (match_operand:SD 0 "register_operand" "=f")
5517 (float_truncate:SD (match_operand:DD 1 "register_operand" "f")))]
5520 [(set_attr "op_type" "RRF")
5521 (set_attr "type" "ftruncsd")])
5523 (define_expand "trunctdsd2"
5526 (float_truncate:DD (match_operand:TD 1 "register_operand" "")))
5527 (unspec:DI [(const_int DFP_RND_PREP_FOR_SHORT_PREC)] UNSPEC_ROUND)
5528 (clobber (match_scratch:TD 3 ""))])
5529 (set (match_operand:SD 0 "register_operand" "")
5530 (float_truncate:SD (match_dup 2)))]
5533 operands[2] = gen_reg_rtx (DDmode);
5537 ; extend(sf|df)(df|tf)2 instruction pattern(s).
5541 (define_insn "*extendsfdf2_z13"
5542 [(set (match_operand:DF 0 "register_operand" "=f,f,v")
5543 (float_extend:DF (match_operand:SF 1 "nonimmediate_operand" "f,R,v")))]
5544 "TARGET_VX && TARGET_HARD_FLOAT"
5549 [(set_attr "op_type" "RRE,RXE,VRR")
5550 (set_attr "type" "fsimpdf, floaddf,fsimpdf")])
5552 ; ldebr, ldeb, lxdbr, lxdb, lxebr, lxeb
5553 (define_insn "*extend<DSF:mode><BFP:mode>2"
5554 [(set (match_operand:BFP 0 "register_operand" "=f,f")
5555 (float_extend:BFP (match_operand:DSF 1 "nonimmediate_operand" "f,R")))]
5557 && GET_MODE_SIZE (<BFP:MODE>mode) > GET_MODE_SIZE (<DSF:MODE>mode)
5558 && (!TARGET_VX || <BFP:MODE>mode != DFmode || <DSF:MODE>mode != SFmode)"
5560 l<BFP:xde><DSF:xde>br\t%0,%1
5561 l<BFP:xde><DSF:xde>b\t%0,%1"
5562 [(set_attr "op_type" "RRE,RXE")
5563 (set_attr "type" "fsimp<BFP:type>, fload<BFP:type>")])
5565 (define_expand "extend<DSF:mode><BFP:mode>2<BFP:tf_fpr>"
5566 [(set (match_operand:BFP 0 "register_operand" "")
5567 (float_extend:BFP (match_operand:DSF 1 "nonimmediate_operand" "")))]
5569 && GET_MODE_SIZE (<BFP:MODE>mode) > GET_MODE_SIZE (<DSF:MODE>mode)")
5572 ; extendddtd2 and extendsddd2 instruction pattern(s).
5575 (define_insn "extendddtd2"
5576 [(set (match_operand:TD 0 "register_operand" "=f")
5577 (float_extend:TD (match_operand:DD 1 "register_operand" "f")))]
5580 [(set_attr "op_type" "RRF")
5581 (set_attr "type" "fsimptf")])
5583 (define_insn "extendsddd2"
5584 [(set (match_operand:DD 0 "register_operand" "=f")
5585 (float_extend:DD (match_operand:SD 1 "register_operand" "f")))]
5588 [(set_attr "op_type" "RRF")
5589 (set_attr "type" "fsimptf")])
5591 (define_expand "extendsdtd2"
5593 (float_extend:DD (match_operand:SD 1 "register_operand" "")))
5594 (set (match_operand:TD 0 "register_operand" "")
5595 (float_extend:TD (match_dup 2)))]
5598 operands[2] = gen_reg_rtx (DDmode);
5601 ; Binary Floating Point - load fp integer
5603 ; Expanders for: floor, btrunc, round, ceil, and nearbyint
5604 ; For all of them the inexact exceptions are suppressed.
5606 ; fiebra, fidbra, fixbra
5607 (define_insn "<FPINT:fpint_name><BFP:mode>2<BFP:tf_fpr>"
5608 [(set (match_operand:BFP 0 "register_operand" "=f")
5609 (unspec:BFP [(match_operand:BFP 1 "register_operand" "f")]
5612 "fi<BFP:xde>bra\t%0,<FPINT:fpint_roundingmode>,%1,4"
5613 [(set_attr "op_type" "RRF")
5614 (set_attr "type" "fsimp<BFP:type>")])
5616 ; rint is supposed to raise an inexact exception so we can use the
5617 ; older instructions.
5619 ; fiebr, fidbr, fixbr
5620 (define_insn "rint<BFP:mode>2<BFP:tf_fpr>"
5621 [(set (match_operand:BFP 0 "register_operand" "=f")
5622 (unspec:BFP [(match_operand:BFP 1 "register_operand" "f")]
5623 UNSPEC_FPINT_RINT))]
5625 "fi<BFP:xde>br\t%0,0,%1"
5626 [(set_attr "op_type" "RRF")
5627 (set_attr "type" "fsimp<BFP:type>")])
5630 ; Decimal Floating Point - load fp integer
5633 (define_insn "<FPINT:fpint_name><DFP:mode>2"
5634 [(set (match_operand:DFP 0 "register_operand" "=f")
5635 (unspec:DFP [(match_operand:DFP 1 "register_operand" "f")]
5638 "fi<DFP:xde>tr\t%0,<FPINT:fpint_roundingmode>,%1,4"
5639 [(set_attr "op_type" "RRF")
5640 (set_attr "type" "fsimp<DFP:type>")])
5643 (define_insn "rint<DFP:mode>2"
5644 [(set (match_operand:DFP 0 "register_operand" "=f")
5645 (unspec:DFP [(match_operand:DFP 1 "register_operand" "f")]
5646 UNSPEC_FPINT_RINT))]
5648 "fi<DFP:xde>tr\t%0,0,%1,0"
5649 [(set_attr "op_type" "RRF")
5650 (set_attr "type" "fsimp<DFP:type>")])
5653 ; Binary <-> Decimal floating point trunc patterns
5656 (define_insn "*trunc<BFP:mode><DFP_ALL:mode>2"
5657 [(set (reg:DFP_ALL FPR0_REGNUM)
5658 (float_truncate:DFP_ALL (reg:BFP FPR4_REGNUM)))
5659 (use (reg:SI GPR0_REGNUM))
5660 (clobber (reg:CC CC_REGNUM))
5661 (clobber (reg:SI GPR1_REGNUM))]
5665 (define_insn "*trunc<DFP_ALL:mode><BFP:mode>2"
5666 [(set (reg:BFP FPR0_REGNUM)
5667 (float_truncate:BFP (reg:DFP_ALL FPR4_REGNUM)))
5668 (use (reg:SI GPR0_REGNUM))
5669 (clobber (reg:CC CC_REGNUM))
5670 (clobber (reg:SI GPR1_REGNUM))]
5674 (define_expand "trunc<BFP:mode><DFP_ALL:mode>2<BFP:tf_fpr>"
5675 [(set (reg:BFP FPR4_REGNUM) (match_operand:BFP 1 "nonimmediate_operand" ""))
5676 (set (reg:SI GPR0_REGNUM) (match_dup 2))
5678 [(set (reg:DFP_ALL FPR0_REGNUM)
5679 (float_truncate:DFP_ALL (reg:BFP FPR4_REGNUM)))
5680 (use (reg:SI GPR0_REGNUM))
5681 (clobber (reg:CC CC_REGNUM))
5682 (clobber (reg:SI GPR1_REGNUM))])
5683 (set (match_operand:DFP_ALL 0 "nonimmediate_operand" "")
5684 (reg:DFP_ALL FPR0_REGNUM))]
5686 && GET_MODE_SIZE (<BFP:MODE>mode) > GET_MODE_SIZE (<DFP_ALL:MODE>mode)"
5688 HOST_WIDE_INT flags;
5690 /* According to IEEE 754 2008 4.3 'Rounding-direction attributes' the
5691 rounding mode of the target format needs to be used. */
5693 flags = (PFPO_CONVERT |
5694 PFPO_OP_TYPE_<DFP_ALL:MODE> << PFPO_OP0_TYPE_SHIFT |
5695 PFPO_OP_TYPE_<BFP:MODE> << PFPO_OP1_TYPE_SHIFT |
5698 operands[2] = GEN_INT (flags);
5701 (define_expand "trunc<DFP_ALL:mode><BFP:mode>2<BFP:tf_fpr>"
5702 [(set (reg:DFP_ALL FPR4_REGNUM)
5703 (match_operand:DFP_ALL 1 "nonimmediate_operand" ""))
5704 (set (reg:SI GPR0_REGNUM) (match_dup 2))
5706 [(set (reg:BFP FPR0_REGNUM) (float_truncate:BFP (reg:DFP_ALL FPR4_REGNUM)))
5707 (use (reg:SI GPR0_REGNUM))
5708 (clobber (reg:CC CC_REGNUM))
5709 (clobber (reg:SI GPR1_REGNUM))])
5710 (set (match_operand:BFP 0 "nonimmediate_operand" "") (reg:BFP FPR0_REGNUM))]
5712 && GET_MODE_SIZE (<DFP_ALL:MODE>mode) >= GET_MODE_SIZE (<BFP:MODE>mode)"
5714 HOST_WIDE_INT flags;
5716 /* According to IEEE 754 2008 4.3 'Rounding-direction attributes' the
5717 rounding mode of the target format needs to be used. */
5719 flags = (PFPO_CONVERT |
5720 PFPO_OP_TYPE_<BFP:MODE> << PFPO_OP0_TYPE_SHIFT |
5721 PFPO_OP_TYPE_<DFP_ALL:MODE> << PFPO_OP1_TYPE_SHIFT |
5724 operands[2] = GEN_INT (flags);
5728 ; Binary <-> Decimal floating point extend patterns
5731 (define_insn "*extend<BFP:mode><DFP_ALL:mode>2"
5732 [(set (reg:DFP_ALL FPR0_REGNUM) (float_extend:DFP_ALL (reg:BFP FPR4_REGNUM)))
5733 (use (reg:SI GPR0_REGNUM))
5734 (clobber (reg:CC CC_REGNUM))
5735 (clobber (reg:SI GPR1_REGNUM))]
5739 (define_insn "*extend<DFP_ALL:mode><BFP:mode>2"
5740 [(set (reg:BFP FPR0_REGNUM) (float_extend:BFP (reg:DFP_ALL FPR4_REGNUM)))
5741 (use (reg:SI GPR0_REGNUM))
5742 (clobber (reg:CC CC_REGNUM))
5743 (clobber (reg:SI GPR1_REGNUM))]
5747 (define_expand "extend<BFP:mode><DFP_ALL:mode>2<BFP:tf_fpr>"
5748 [(set (reg:BFP FPR4_REGNUM) (match_operand:BFP 1 "nonimmediate_operand" ""))
5749 (set (reg:SI GPR0_REGNUM) (match_dup 2))
5751 [(set (reg:DFP_ALL FPR0_REGNUM)
5752 (float_extend:DFP_ALL (reg:BFP FPR4_REGNUM)))
5753 (use (reg:SI GPR0_REGNUM))
5754 (clobber (reg:CC CC_REGNUM))
5755 (clobber (reg:SI GPR1_REGNUM))])
5756 (set (match_operand:DFP_ALL 0 "nonimmediate_operand" "")
5757 (reg:DFP_ALL FPR0_REGNUM))]
5759 && GET_MODE_SIZE (<BFP:MODE>mode) <= GET_MODE_SIZE (<DFP_ALL:MODE>mode)"
5761 HOST_WIDE_INT flags;
5763 /* According to IEEE 754 2008 4.3 'Rounding-direction attributes' the
5764 rounding mode of the target format needs to be used. */
5766 flags = (PFPO_CONVERT |
5767 PFPO_OP_TYPE_<DFP_ALL:MODE> << PFPO_OP0_TYPE_SHIFT |
5768 PFPO_OP_TYPE_<BFP:MODE> << PFPO_OP1_TYPE_SHIFT |
5771 operands[2] = GEN_INT (flags);
5774 (define_expand "extend<DFP_ALL:mode><BFP:mode>2<BFP:tf_fpr>"
5775 [(set (reg:DFP_ALL FPR4_REGNUM)
5776 (match_operand:DFP_ALL 1 "nonimmediate_operand" ""))
5777 (set (reg:SI GPR0_REGNUM) (match_dup 2))
5779 [(set (reg:BFP FPR0_REGNUM) (float_extend:BFP (reg:DFP_ALL FPR4_REGNUM)))
5780 (use (reg:SI GPR0_REGNUM))
5781 (clobber (reg:CC CC_REGNUM))
5782 (clobber (reg:SI GPR1_REGNUM))])
5783 (set (match_operand:BFP 0 "nonimmediate_operand" "") (reg:BFP FPR0_REGNUM))]
5785 && GET_MODE_SIZE (<DFP_ALL:MODE>mode) < GET_MODE_SIZE (<BFP:MODE>mode)"
5787 HOST_WIDE_INT flags;
5789 /* According to IEEE 754 2008 4.3 'Rounding-direction attributes' the
5790 rounding mode of the target format needs to be used. */
5792 flags = (PFPO_CONVERT |
5793 PFPO_OP_TYPE_<BFP:MODE> << PFPO_OP0_TYPE_SHIFT |
5794 PFPO_OP_TYPE_<DFP_ALL:MODE> << PFPO_OP1_TYPE_SHIFT |
5797 operands[2] = GEN_INT (flags);
5802 ;; ARITHMETIC OPERATIONS
5804 ; arithmetic operations set the ConditionCode,
5805 ; because of unpredictable Bits in Register for Halfword and Byte
5806 ; the ConditionCode can be set wrong in operations for Halfword and Byte
5809 ;;- Add instructions.
5813 ; addti3 instruction pattern(s).
5816 (define_expand "addti3"
5818 [(set (match_operand:TI 0 "register_operand" "")
5819 (plus:TI (match_operand:TI 1 "nonimmediate_operand" "")
5820 (match_operand:TI 2 "general_operand" "") ) )
5821 (clobber (reg:CC CC_REGNUM))])]
5824 /* For z13 we have vaq which doesn't set CC. */
5827 emit_insn (gen_rtx_SET (operands[0],
5828 gen_rtx_PLUS (TImode,
5829 copy_to_mode_reg (TImode, operands[1]),
5830 copy_to_mode_reg (TImode, operands[2]))));
5835 (define_insn_and_split "*addti3"
5836 [(set (match_operand:TI 0 "register_operand" "=&d")
5837 (plus:TI (match_operand:TI 1 "nonimmediate_operand" "%0")
5838 (match_operand:TI 2 "general_operand" "do") ) )
5839 (clobber (reg:CC CC_REGNUM))]
5842 "&& reload_completed"
5844 [(set (reg:CCL1 CC_REGNUM)
5845 (compare:CCL1 (plus:DI (match_dup 7) (match_dup 8))
5847 (set (match_dup 6) (plus:DI (match_dup 7) (match_dup 8)))])
5849 [(set (match_dup 3) (plus:DI
5850 (plus:DI (ltu:DI (reg:CCL1 CC_REGNUM) (const_int 0))
5851 (match_dup 4)) (match_dup 5)))
5852 (clobber (reg:CC CC_REGNUM))])]
5853 "operands[3] = operand_subword (operands[0], 0, 0, TImode);
5854 operands[4] = operand_subword (operands[1], 0, 0, TImode);
5855 operands[5] = operand_subword (operands[2], 0, 0, TImode);
5856 operands[6] = operand_subword (operands[0], 1, 0, TImode);
5857 operands[7] = operand_subword (operands[1], 1, 0, TImode);
5858 operands[8] = operand_subword (operands[2], 1, 0, TImode);"
5859 [(set_attr "op_type" "*")
5860 (set_attr "cpu_facility" "*")])
5863 ; adddi3 instruction pattern(s).
5866 (define_expand "adddi3"
5868 [(set (match_operand:DI 0 "nonimmediate_operand" "")
5869 (plus:DI (match_operand:DI 1 "nonimmediate_operand" "")
5870 (match_operand:DI 2 "general_operand" "")))
5871 (clobber (reg:CC CC_REGNUM))])]
5875 (define_insn "*adddi3_sign"
5876 [(set (match_operand:DI 0 "register_operand" "=d,d")
5877 (plus:DI (sign_extend:DI (match_operand:SI 2 "general_operand" "d,T"))
5878 (match_operand:DI 1 "register_operand" "0,0")))
5879 (clobber (reg:CC CC_REGNUM))]
5884 [(set_attr "op_type" "RRE,RXY")
5885 (set_attr "z196prop" "z196_cracked,z196_cracked")])
5887 (define_insn "*adddi3_zero_cc"
5888 [(set (reg CC_REGNUM)
5889 (compare (plus:DI (zero_extend:DI (match_operand:SI 2 "general_operand" "d,T"))
5890 (match_operand:DI 1 "register_operand" "0,0"))
5892 (set (match_operand:DI 0 "register_operand" "=d,d")
5893 (plus:DI (zero_extend:DI (match_dup 2)) (match_dup 1)))]
5894 "s390_match_ccmode (insn, CCLmode) && TARGET_ZARCH"
5898 [(set_attr "op_type" "RRE,RXY")
5899 (set_attr "z10prop" "z10_super_E1,z10_super_E1")])
5901 (define_insn "*adddi3_zero_cconly"
5902 [(set (reg CC_REGNUM)
5903 (compare (plus:DI (zero_extend:DI (match_operand:SI 2 "general_operand" "d,T"))
5904 (match_operand:DI 1 "register_operand" "0,0"))
5906 (clobber (match_scratch:DI 0 "=d,d"))]
5907 "s390_match_ccmode (insn, CCLmode) && TARGET_ZARCH"
5911 [(set_attr "op_type" "RRE,RXY")
5912 (set_attr "z10prop" "z10_super_E1,z10_super_E1")])
5914 (define_insn "*adddi3_zero"
5915 [(set (match_operand:DI 0 "register_operand" "=d,d")
5916 (plus:DI (zero_extend:DI (match_operand:SI 2 "general_operand" "d,T"))
5917 (match_operand:DI 1 "register_operand" "0,0")))
5918 (clobber (reg:CC CC_REGNUM))]
5923 [(set_attr "op_type" "RRE,RXY")
5924 (set_attr "z10prop" "z10_super_E1,z10_super_E1")])
5926 (define_insn_and_split "*adddi3_31z"
5927 [(set (match_operand:DI 0 "nonimmediate_operand" "=&d")
5928 (plus:DI (match_operand:DI 1 "nonimmediate_operand" "%0")
5929 (match_operand:DI 2 "general_operand" "do") ) )
5930 (clobber (reg:CC CC_REGNUM))]
5933 "&& reload_completed"
5935 [(set (reg:CCL1 CC_REGNUM)
5936 (compare:CCL1 (plus:SI (match_dup 7) (match_dup 8))
5938 (set (match_dup 6) (plus:SI (match_dup 7) (match_dup 8)))])
5940 [(set (match_dup 3) (plus:SI
5941 (plus:SI (ltu:SI (reg:CCL1 CC_REGNUM) (const_int 0))
5942 (match_dup 4)) (match_dup 5)))
5943 (clobber (reg:CC CC_REGNUM))])]
5944 "operands[3] = operand_subword (operands[0], 0, 0, DImode);
5945 operands[4] = operand_subword (operands[1], 0, 0, DImode);
5946 operands[5] = operand_subword (operands[2], 0, 0, DImode);
5947 operands[6] = operand_subword (operands[0], 1, 0, DImode);
5948 operands[7] = operand_subword (operands[1], 1, 0, DImode);
5949 operands[8] = operand_subword (operands[2], 1, 0, DImode);")
5952 ; addsi3 instruction pattern(s).
5955 (define_expand "addsi3"
5957 [(set (match_operand:SI 0 "nonimmediate_operand" "")
5958 (plus:SI (match_operand:SI 1 "nonimmediate_operand" "")
5959 (match_operand:SI 2 "general_operand" "")))
5960 (clobber (reg:CC CC_REGNUM))])]
5964 (define_insn "*addsi3_sign"
5965 [(set (match_operand:SI 0 "register_operand" "=d,d")
5966 (plus:SI (sign_extend:SI (match_operand:HI 2 "memory_operand" "R,T"))
5967 (match_operand:SI 1 "register_operand" "0,0")))
5968 (clobber (reg:CC CC_REGNUM))]
5973 [(set_attr "op_type" "RX,RXY")
5974 (set_attr "cpu_facility" "*,longdisp")
5975 (set_attr "z196prop" "z196_cracked,z196_cracked")])
5978 ; add(di|si)3 instruction pattern(s).
5981 ; ark, agrk, ar, ahi, ahik, aghik, alfi, slfi, a, ay, agr, aghi, algfi, slgfi, ag, asi, agsi
5982 (define_insn "*add<mode>3"
5983 [(set (match_operand:GPR 0 "nonimmediate_operand" "=d,d,d,d, d, d,d,d,S")
5984 (plus:GPR (match_operand:GPR 1 "nonimmediate_operand" "%0,d,0,d, 0, 0,0,0,0")
5985 (match_operand:GPR 2 "general_operand" " d,d,K,K,Op,On,R,T,C") ) )
5986 (clobber (reg:CC CC_REGNUM))]
5998 [(set_attr "op_type" "RR<E>,RRF,RI,RIE,RIL,RIL,RX<Y>,RXY,SIY")
5999 (set_attr "cpu_facility" "*,z196,*,z196,extimm,extimm,*,longdisp,z10")
6000 (set_attr "z10prop" "z10_super_E1,*,z10_super_E1,*,z10_super_E1,z10_super_E1,
6001 z10_super_E1,z10_super_E1,z10_super_E1")])
6003 ; alr, alfi, slfi, al, aly, alrk, alhsik, algr, algfi, slgfi, alg, alsi, algsi, algrk, alghsik
6004 (define_insn "*add<mode>3_carry1_cc"
6005 [(set (reg CC_REGNUM)
6006 (compare (plus:GPR (match_operand:GPR 1 "nonimmediate_operand" "%0,d, 0, 0,d,0,0,0")
6007 (match_operand:GPR 2 "general_operand" " d,d,Op,On,K,R,T,C"))
6009 (set (match_operand:GPR 0 "nonimmediate_operand" "=d,d, d, d,d,d,d,d")
6010 (plus:GPR (match_dup 1) (match_dup 2)))]
6011 "s390_match_ccmode (insn, CCL1mode)"
6017 al<g>hsik\t%0,%1,%h2
6021 [(set_attr "op_type" "RR<E>,RRF,RIL,RIL,RIE,RX<Y>,RXY,SIY")
6022 (set_attr "cpu_facility" "*,z196,extimm,extimm,z196,*,longdisp,z10")
6023 (set_attr "z10prop" "z10_super_E1,*,z10_super_E1,z10_super_E1,*,
6024 z10_super_E1,z10_super_E1,z10_super_E1")])
6026 ; alr, al, aly, algr, alg, alrk, algrk
6027 (define_insn "*add<mode>3_carry1_cconly"
6028 [(set (reg CC_REGNUM)
6029 (compare (plus:GPR (match_operand:GPR 1 "nonimmediate_operand" "%0,d,0,0")
6030 (match_operand:GPR 2 "general_operand" "d,d,R,T"))
6032 (clobber (match_scratch:GPR 0 "=d,d,d,d"))]
6033 "s390_match_ccmode (insn, CCL1mode)"
6039 [(set_attr "op_type" "RR<E>,RRF,RX<Y>,RXY")
6040 (set_attr "cpu_facility" "*,z196,*,longdisp")
6041 (set_attr "z10prop" "z10_super_E1,*,z10_super_E1,z10_super_E1")])
6043 ; alr, alfi, slfi, al, aly, algr, algfi, slgfi, alg, alsi, algsi, alrk, algrk, alhsik, alghsik
6044 (define_insn "*add<mode>3_carry2_cc"
6045 [(set (reg CC_REGNUM)
6046 (compare (plus:GPR (match_operand:GPR 1 "nonimmediate_operand" "%0,d, 0, 0,d,0,0,0")
6047 (match_operand:GPR 2 "general_operand" " d,d,Op,On,K,R,T,C"))
6049 (set (match_operand:GPR 0 "nonimmediate_operand" "=d,d, d, d,d,d,d,S")
6050 (plus:GPR (match_dup 1) (match_dup 2)))]
6051 "s390_match_ccmode (insn, CCL1mode)"
6057 al<g>hsik\t%0,%1,%h2
6061 [(set_attr "op_type" "RR<E>,RRF,RIL,RIL,RIE,RX<Y>,RXY,SIY")
6062 (set_attr "cpu_facility" "*,z196,extimm,extimm,z196,*,longdisp,z10")
6063 (set_attr "z10prop" "z10_super_E1,*,z10_super_E1,z10_super_E1,*,
6064 z10_super_E1,z10_super_E1,z10_super_E1")])
6066 ; alr, al, aly, algr, alg, alrk, algrk
6067 (define_insn "*add<mode>3_carry2_cconly"
6068 [(set (reg CC_REGNUM)
6069 (compare (plus:GPR (match_operand:GPR 1 "nonimmediate_operand" "%0,d,0,0")
6070 (match_operand:GPR 2 "general_operand" "d,d,R,T"))
6072 (clobber (match_scratch:GPR 0 "=d,d,d,d"))]
6073 "s390_match_ccmode (insn, CCL1mode)"
6079 [(set_attr "op_type" "RR<E>,RRF,RX<Y>,RXY")
6080 (set_attr "cpu_facility" "*,z196,*,longdisp")
6081 (set_attr "z10prop" "z10_super_E1,*,z10_super_E1,z10_super_E1")])
6083 ; alr, alfi, slfi, al, aly, algr, algfi, slgfi, alg, alsi, algsi, alrk, algrk, alhsik, alghsik
6084 (define_insn "*add<mode>3_cc"
6085 [(set (reg CC_REGNUM)
6086 (compare (plus:GPR (match_operand:GPR 1 "nonimmediate_operand" "%0,d, 0, 0,d,0,0,0")
6087 (match_operand:GPR 2 "general_operand" " d,d,Op,On,K,R,T,C"))
6089 (set (match_operand:GPR 0 "nonimmediate_operand" "=d,d, d, d,d,d,d,S")
6090 (plus:GPR (match_dup 1) (match_dup 2)))]
6091 "s390_match_ccmode (insn, CCLmode)"
6097 al<g>hsik\t%0,%1,%h2
6101 [(set_attr "op_type" "RR<E>,RRF,RIL,RIL,RIE,RX<Y>,RXY,SIY")
6102 (set_attr "cpu_facility" "*,z196,extimm,extimm,z196,*,longdisp,z10")
6103 (set_attr "z10prop" "z10_super_E1,*,z10_super_E1,z10_super_E1,
6104 *,z10_super_E1,z10_super_E1,z10_super_E1")])
6106 ; alr, al, aly, algr, alg, alrk, algrk
6107 (define_insn "*add<mode>3_cconly"
6108 [(set (reg CC_REGNUM)
6109 (compare (plus:GPR (match_operand:GPR 1 "nonimmediate_operand" "%0,d,0,0")
6110 (match_operand:GPR 2 "general_operand" "d,d,R,T"))
6112 (clobber (match_scratch:GPR 0 "=d,d,d,d"))]
6113 "s390_match_ccmode (insn, CCLmode)"
6119 [(set_attr "op_type" "RR<E>,RRF,RX<Y>,RXY")
6120 (set_attr "cpu_facility" "*,z196,*,longdisp")
6121 (set_attr "z10prop" "z10_super_E1,*,z10_super_E1,z10_super_E1")])
6123 ; alr, al, aly, algr, alg, alrk, algrk
6124 (define_insn "*add<mode>3_cconly2"
6125 [(set (reg CC_REGNUM)
6126 (compare (match_operand:GPR 1 "nonimmediate_operand" "%0,d,0,0")
6127 (neg:GPR (match_operand:GPR 2 "general_operand" "d,d,R,T"))))
6128 (clobber (match_scratch:GPR 0 "=d,d,d,d"))]
6129 "s390_match_ccmode(insn, CCLmode)"
6135 [(set_attr "op_type" "RR<E>,RRF,RX<Y>,RXY")
6136 (set_attr "cpu_facility" "*,z196,*,longdisp")
6137 (set_attr "z10prop" "z10_super_E1,*,z10_super_E1,z10_super_E1")])
6139 ; ahi, afi, aghi, agfi, asi, agsi
6140 (define_insn "*add<mode>3_imm_cc"
6141 [(set (reg CC_REGNUM)
6142 (compare (plus:GPR (match_operand:GPR 1 "nonimmediate_operand" " 0, d,0, 0")
6143 (match_operand:GPR 2 "const_int_operand" " K, K,Os,C"))
6145 (set (match_operand:GPR 0 "nonimmediate_operand" "=d, d,d, S")
6146 (plus:GPR (match_dup 1) (match_dup 2)))]
6147 "s390_match_ccmode (insn, CCAmode)
6148 && (CONST_OK_FOR_CONSTRAINT_P (INTVAL (operands[2]), 'K', \"K\")
6149 || (CONST_OK_FOR_CONSTRAINT_P (INTVAL (operands[2]), 'O', \"Os\")
6150 /* Avoid INT32_MIN on 32 bit. */
6151 && (!TARGET_ZARCH || INTVAL (operands[2]) != -0x7fffffff - 1)))"
6157 [(set_attr "op_type" "RI,RIE,RIL,SIY")
6158 (set_attr "cpu_facility" "*,z196,extimm,z10")
6159 (set_attr "z10prop" "z10_super_E1,*,z10_super_E1,z10_super_E1")])
6161 (define_insn "*adddi3_sign"
6162 [(set (match_operand:DI 0 "register_operand" "=d")
6163 (plus:DI (sign_extend:DI (match_operand:HI 2 "memory_operand" "T"))
6164 (match_operand:DI 1 "register_operand" "0")))
6165 (clobber (reg:CC CC_REGNUM))]
6168 [(set_attr "op_type" "RXY")])
6171 ; Jump to label OP3 if OP1 + OP2 results in a signed overflow
6173 ; addv_const_operand accepts all constants which can be handled
6174 ; without reloads. These will be handled primarily by
6175 ; "*addv<mode>3_ccoverflow_const" which doesn't provide a register
6176 ; alternative. Hence we have to match the operand exactly.
6177 ; For immediates we have to avoid the SIGN_EXTEND around OP2.
6178 (define_expand "addv<mode>4"
6180 [(set (reg:CCO CC_REGNUM)
6181 (compare:CCO (plus:<DBL>
6182 (sign_extend:<DBL> (match_operand:GPR 1 "nonimmediate_operand"))
6184 (sign_extend:<DBL> (plus:GPR (match_dup 1)
6185 (match_operand:GPR 2 "general_operand")))))
6186 (set (match_operand:GPR 0 "nonimmediate_operand")
6187 (plus:GPR (match_dup 1) (match_dup 2)))])
6189 (if_then_else (ne (reg:CCO CC_REGNUM) (const_int 0))
6190 (label_ref (match_operand 3))
6194 if (CONSTANT_P (operands[2])
6195 && !addv_const_operand (operands[2], GET_MODE (operands[2])))
6196 operands[2] = force_reg (<GPR:MODE>mode, operands[2]);
6198 if (GET_MODE (operands[2]) != VOIDmode)
6199 operands[4] = gen_rtx_SIGN_EXTEND (<DBL>mode, operands[2]);
6201 /* This is what CSE does when propagating a constant into the pattern. */
6202 operands[4] = simplify_unary_operation (SIGN_EXTEND, <GPR:DBL>mode, operands[2], <GPR:MODE>mode);
6205 ; ark, agrk, ar, ahi, ahik, aghik, a, ay, agr, aghi, ag, asi, agsi
6206 (define_insn "*addv<mode>3_ccoverflow"
6207 [(set (reg CC_REGNUM)
6208 (compare (plus:<DBL>
6209 (sign_extend:<DBL> (match_operand:GPR 1 "nonimmediate_operand" "%0,d,0,d,0,0,0"))
6210 (sign_extend:<DBL> (match_operand:GPR 2 "general_operand" " d,d,K,K,R,T,C")))
6211 (sign_extend:<DBL> (plus:GPR (match_dup 1) (match_dup 2)))))
6212 (set (match_operand:GPR 0 "nonimmediate_operand" "=d,d,d,d,d,d,S")
6213 (plus:GPR (match_dup 1) (match_dup 2)))]
6214 "s390_match_ccmode (insn, CCOmode)"
6223 [(set_attr "op_type" "RR<E>,RRF,RI,RIE,RX<Y>,RXY,SIY")
6224 (set_attr "cpu_facility" "*,z196,*,z196,*,longdisp,z10")
6225 (set_attr "z10prop" "z10_super_E1,*,z10_super_E1,*,
6226 z10_super_E1,z10_super_E1,z10_super_E1")])
6228 ; ahi, aghi, ahik, aghik, asi, agsi
6229 (define_insn "*addv<mode>3_ccoverflow_const"
6230 [(set (reg CC_REGNUM)
6231 (compare (plus:<DBL>
6232 (sign_extend:<DBL> (match_operand:GPR 1 "nonimmediate_operand" "%0,d,0"))
6233 (match_operand:<DBL> 2 "addv_const_operand" "K,K,C"))
6234 (sign_extend:<DBL> (plus:GPR (match_dup 1) (match_dup 2)))))
6235 (set (match_operand:GPR 0 "nonimmediate_operand" "=d,d,S")
6236 (plus:GPR (match_dup 1) (match_dup 2)))]
6237 "s390_match_ccmode (insn, CCOmode)"
6242 [(set_attr "op_type" "RI,RIE,SIY")
6243 (set_attr "cpu_facility" "*,z196,z10")
6244 (set_attr "z10prop" "z10_super_E1,*,z10_super_E1")])
6248 ; add(tf|df|sf|td|dd)3 instruction pattern(s).
6251 ; axbr, adbr, aebr, axb, adb, aeb, adtr, axtr
6252 ; FIXME: wfadb does not clobber cc
6253 (define_insn "add<mode>3<tf_fpr>"
6254 [(set (match_operand:FP 0 "register_operand" "=f,f,f,v,v")
6255 (plus:FP (match_operand:FP 1 "nonimmediate_operand" "%f,0,0,v,v")
6256 (match_operand:FP 2 "general_operand" "f,f,R,v,v")))
6257 (clobber (reg:CC CC_REGNUM))]
6265 [(set_attr "op_type" "RRF,RRE,RXE,VRR,VRR")
6266 (set_attr "type" "fsimp<type>")
6267 (set_attr "cpu_facility" "*,*,*,vx,vxe")
6268 (set_attr "enabled" "<nBFP>,<nDFP>,<DSF>,<DF>,<SF>")])
6270 ; axbr, adbr, aebr, axb, adb, aeb, adtr, axtr
6271 (define_insn "*add<mode>3_cc"
6272 [(set (reg CC_REGNUM)
6273 (compare (plus:FP (match_operand:FP 1 "nonimmediate_operand" "%f,0,0")
6274 (match_operand:FP 2 "general_operand" "f,f,R"))
6275 (match_operand:FP 3 "const0_operand" "")))
6276 (set (match_operand:FP 0 "register_operand" "=f,f,f")
6277 (plus:FP (match_dup 1) (match_dup 2)))]
6278 "s390_match_ccmode (insn, CCSmode) && TARGET_HARD_FLOAT"
6283 [(set_attr "op_type" "RRF,RRE,RXE")
6284 (set_attr "type" "fsimp<type>")
6285 (set_attr "enabled" "<nBFP>,<nDFP>,<DSF>")])
6287 ; axbr, adbr, aebr, axb, adb, aeb, adtr, axtr
6288 (define_insn "*add<mode>3_cconly"
6289 [(set (reg CC_REGNUM)
6290 (compare (plus:FP (match_operand:FP 1 "nonimmediate_operand" "%f,0,0")
6291 (match_operand:FP 2 "general_operand" "f,f,R"))
6292 (match_operand:FP 3 "const0_operand" "")))
6293 (clobber (match_scratch:FP 0 "=f,f,f"))]
6294 "s390_match_ccmode (insn, CCSmode) && TARGET_HARD_FLOAT"
6299 [(set_attr "op_type" "RRF,RRE,RXE")
6300 (set_attr "type" "fsimp<type>")
6301 (set_attr "enabled" "<nBFP>,<nDFP>,<DSF>")])
6304 ; Pointer add instruction patterns
6307 ; This will match "*la_64"
6308 (define_expand "addptrdi3"
6309 [(set (match_operand:DI 0 "register_operand" "")
6310 (plus:DI (match_operand:DI 1 "register_operand" "")
6311 (match_operand:DI 2 "nonmemory_operand" "")))]
6314 if (GET_CODE (operands[2]) == CONST_INT)
6316 HOST_WIDE_INT c = INTVAL (operands[2]);
6318 if (!CONST_OK_FOR_CONSTRAINT_P (c, 'K', "K")
6319 && !CONST_OK_FOR_CONSTRAINT_P (c, 'O', "Os"))
6321 operands[2] = force_const_mem (DImode, operands[2]);
6322 operands[2] = force_reg (DImode, operands[2]);
6324 else if (!DISP_IN_RANGE (INTVAL (operands[2])))
6325 operands[2] = force_reg (DImode, operands[2]);
6329 ; For 31 bit we have to prevent the generated pattern from matching
6330 ; normal ADDs since la only does a 31 bit add. This is supposed to
6331 ; match "force_la_31".
6332 (define_expand "addptrsi3"
6334 [(set (match_operand:SI 0 "register_operand" "")
6335 (plus:SI (match_operand:SI 1 "register_operand" "")
6336 (match_operand:SI 2 "nonmemory_operand" "")))
6337 (use (const_int 0))])]
6340 if (GET_CODE (operands[2]) == CONST_INT)
6342 HOST_WIDE_INT c = INTVAL (operands[2]);
6344 if (!CONST_OK_FOR_CONSTRAINT_P (c, 'K', "K")
6345 && !CONST_OK_FOR_CONSTRAINT_P (c, 'O', "Os"))
6347 operands[2] = force_const_mem (SImode, operands[2]);
6348 operands[2] = force_reg (SImode, operands[2]);
6350 else if (!DISP_IN_RANGE (INTVAL (operands[2])))
6351 operands[2] = force_reg (SImode, operands[2]);
6356 ;;- Subtract instructions.
6360 ; subti3 instruction pattern(s).
6363 (define_expand "subti3"
6365 [(set (match_operand:TI 0 "register_operand" "")
6366 (minus:TI (match_operand:TI 1 "register_operand" "")
6367 (match_operand:TI 2 "general_operand" "") ) )
6368 (clobber (reg:CC CC_REGNUM))])]
6371 /* For z13 we have vsq which doesn't set CC. */
6374 emit_insn (gen_rtx_SET (operands[0],
6375 gen_rtx_MINUS (TImode,
6377 copy_to_mode_reg (TImode, operands[2]))));
6382 (define_insn_and_split "*subti3"
6383 [(set (match_operand:TI 0 "register_operand" "=&d")
6384 (minus:TI (match_operand:TI 1 "register_operand" "0")
6385 (match_operand:TI 2 "general_operand" "do") ) )
6386 (clobber (reg:CC CC_REGNUM))]
6389 "&& reload_completed"
6391 [(set (reg:CCL2 CC_REGNUM)
6392 (compare:CCL2 (minus:DI (match_dup 7) (match_dup 8))
6394 (set (match_dup 6) (minus:DI (match_dup 7) (match_dup 8)))])
6396 [(set (match_dup 3) (minus:DI (minus:DI (match_dup 4) (match_dup 5))
6397 (gtu:DI (reg:CCL2 CC_REGNUM) (const_int 0))))
6398 (clobber (reg:CC CC_REGNUM))])]
6399 "operands[3] = operand_subword (operands[0], 0, 0, TImode);
6400 operands[4] = operand_subword (operands[1], 0, 0, TImode);
6401 operands[5] = operand_subword (operands[2], 0, 0, TImode);
6402 operands[6] = operand_subword (operands[0], 1, 0, TImode);
6403 operands[7] = operand_subword (operands[1], 1, 0, TImode);
6404 operands[8] = operand_subword (operands[2], 1, 0, TImode);"
6405 [(set_attr "op_type" "*")
6406 (set_attr "cpu_facility" "*")])
6409 ; subdi3 instruction pattern(s).
6412 (define_expand "subdi3"
6414 [(set (match_operand:DI 0 "register_operand" "")
6415 (minus:DI (match_operand:DI 1 "register_operand" "")
6416 (match_operand:DI 2 "general_operand" "")))
6417 (clobber (reg:CC CC_REGNUM))])]
6421 (define_insn "*subdi3_sign"
6422 [(set (match_operand:DI 0 "register_operand" "=d,d")
6423 (minus:DI (match_operand:DI 1 "register_operand" "0,0")
6424 (sign_extend:DI (match_operand:SI 2 "general_operand" "d,T"))))
6425 (clobber (reg:CC CC_REGNUM))]
6430 [(set_attr "op_type" "RRE,RXY")
6431 (set_attr "z10prop" "z10_c,*")
6432 (set_attr "z196prop" "z196_cracked")])
6434 (define_insn "*subdi3_zero_cc"
6435 [(set (reg CC_REGNUM)
6436 (compare (minus:DI (match_operand:DI 1 "register_operand" "0,0")
6437 (zero_extend:DI (match_operand:SI 2 "general_operand" "d,T")))
6439 (set (match_operand:DI 0 "register_operand" "=d,d")
6440 (minus:DI (match_dup 1) (zero_extend:DI (match_dup 2))))]
6441 "s390_match_ccmode (insn, CCLmode) && TARGET_ZARCH"
6445 [(set_attr "op_type" "RRE,RXY")
6446 (set_attr "z10prop" "z10_super_c_E1,z10_super_E1")])
6448 (define_insn "*subdi3_zero_cconly"
6449 [(set (reg CC_REGNUM)
6450 (compare (minus:DI (match_operand:DI 1 "register_operand" "0,0")
6451 (zero_extend:DI (match_operand:SI 2 "general_operand" "d,T")))
6453 (clobber (match_scratch:DI 0 "=d,d"))]
6454 "s390_match_ccmode (insn, CCLmode) && TARGET_ZARCH"
6458 [(set_attr "op_type" "RRE,RXY")
6459 (set_attr "z10prop" "z10_super_c_E1,z10_super_E1")])
6461 (define_insn "*subdi3_zero"
6462 [(set (match_operand:DI 0 "register_operand" "=d,d")
6463 (minus:DI (match_operand:DI 1 "register_operand" "0,0")
6464 (zero_extend:DI (match_operand:SI 2 "general_operand" "d,T"))))
6465 (clobber (reg:CC CC_REGNUM))]
6470 [(set_attr "op_type" "RRE,RXY")
6471 (set_attr "z10prop" "z10_super_c_E1,z10_super_E1")])
6473 (define_insn_and_split "*subdi3_31z"
6474 [(set (match_operand:DI 0 "register_operand" "=&d")
6475 (minus:DI (match_operand:DI 1 "register_operand" "0")
6476 (match_operand:DI 2 "general_operand" "do") ) )
6477 (clobber (reg:CC CC_REGNUM))]
6480 "&& reload_completed"
6482 [(set (reg:CCL2 CC_REGNUM)
6483 (compare:CCL2 (minus:SI (match_dup 7) (match_dup 8))
6485 (set (match_dup 6) (minus:SI (match_dup 7) (match_dup 8)))])
6487 [(set (match_dup 3) (minus:SI (minus:SI (match_dup 4) (match_dup 5))
6488 (gtu:SI (reg:CCL2 CC_REGNUM) (const_int 0))))
6489 (clobber (reg:CC CC_REGNUM))])]
6490 "operands[3] = operand_subword (operands[0], 0, 0, DImode);
6491 operands[4] = operand_subword (operands[1], 0, 0, DImode);
6492 operands[5] = operand_subword (operands[2], 0, 0, DImode);
6493 operands[6] = operand_subword (operands[0], 1, 0, DImode);
6494 operands[7] = operand_subword (operands[1], 1, 0, DImode);
6495 operands[8] = operand_subword (operands[2], 1, 0, DImode);")
6498 ; subsi3 instruction pattern(s).
6501 (define_expand "subsi3"
6503 [(set (match_operand:SI 0 "register_operand" "")
6504 (minus:SI (match_operand:SI 1 "register_operand" "")
6505 (match_operand:SI 2 "general_operand" "")))
6506 (clobber (reg:CC CC_REGNUM))])]
6510 (define_insn "*subsi3_sign"
6511 [(set (match_operand:SI 0 "register_operand" "=d,d")
6512 (minus:SI (match_operand:SI 1 "register_operand" "0,0")
6513 (sign_extend:SI (match_operand:HI 2 "memory_operand" "R,T"))))
6514 (clobber (reg:CC CC_REGNUM))]
6519 [(set_attr "op_type" "RX,RXY")
6520 (set_attr "cpu_facility" "*,longdisp")
6521 (set_attr "z196prop" "z196_cracked,z196_cracked")])
6524 ; sub(di|si)3 instruction pattern(s).
6527 ; sr, s, sy, sgr, sg, srk, sgrk
6528 (define_insn "*sub<mode>3"
6529 [(set (match_operand:GPR 0 "register_operand" "=d,d,d,d")
6530 (minus:GPR (match_operand:GPR 1 "register_operand" "0,d,0,0")
6531 (match_operand:GPR 2 "general_operand" "d,d,R,T") ) )
6532 (clobber (reg:CC CC_REGNUM))]
6539 [(set_attr "op_type" "RR<E>,RRF,RX<Y>,RXY")
6540 (set_attr "cpu_facility" "*,z196,*,longdisp")
6541 (set_attr "z10prop" "z10_super_c_E1,*,z10_super_E1,z10_super_E1")])
6543 ; slr, sl, sly, slgr, slg, slrk, slgrk
6544 (define_insn "*sub<mode>3_borrow_cc"
6545 [(set (reg CC_REGNUM)
6546 (compare (minus:GPR (match_operand:GPR 1 "register_operand" "0,d,0,0")
6547 (match_operand:GPR 2 "general_operand" "d,d,R,T"))
6549 (set (match_operand:GPR 0 "register_operand" "=d,d,d,d")
6550 (minus:GPR (match_dup 1) (match_dup 2)))]
6551 "s390_match_ccmode (insn, CCL2mode)"
6557 [(set_attr "op_type" "RR<E>,RRF,RX<Y>,RXY")
6558 (set_attr "cpu_facility" "*,z196,*,longdisp")
6559 (set_attr "z10prop" "z10_super_c_E1,*,z10_super_E1,z10_super_E1")])
6561 ; slr, sl, sly, slgr, slg, slrk, slgrk
6562 (define_insn "*sub<mode>3_borrow_cconly"
6563 [(set (reg CC_REGNUM)
6564 (compare (minus:GPR (match_operand:GPR 1 "register_operand" "0,d,0,0")
6565 (match_operand:GPR 2 "general_operand" "d,d,R,T"))
6567 (clobber (match_scratch:GPR 0 "=d,d,d,d"))]
6568 "s390_match_ccmode (insn, CCL2mode)"
6574 [(set_attr "op_type" "RR<E>,RRF,RX<Y>,RXY")
6575 (set_attr "cpu_facility" "*,z196,*,longdisp")
6576 (set_attr "z10prop" "z10_super_c_E1,*,z10_super_E1,z10_super_E1")])
6578 ; slr, sl, sly, slgr, slg, slrk, slgrk
6579 (define_insn "*sub<mode>3_cc"
6580 [(set (reg CC_REGNUM)
6581 (compare (minus:GPR (match_operand:GPR 1 "register_operand" "0,d,0,0")
6582 (match_operand:GPR 2 "general_operand" "d,d,R,T"))
6584 (set (match_operand:GPR 0 "register_operand" "=d,d,d,d")
6585 (minus:GPR (match_dup 1) (match_dup 2)))]
6586 "s390_match_ccmode (insn, CCLmode)"
6592 [(set_attr "op_type" "RR<E>,RRF,RX<Y>,RXY")
6593 (set_attr "cpu_facility" "*,z196,*,longdisp")
6594 (set_attr "z10prop" "z10_super_c_E1,*,z10_super_E1,z10_super_E1")])
6596 ; slr, sl, sly, slgr, slg, slrk, slgrk
6597 (define_insn "*sub<mode>3_cc2"
6598 [(set (reg CC_REGNUM)
6599 (compare (match_operand:GPR 1 "register_operand" "0,d,0,0")
6600 (match_operand:GPR 2 "general_operand" "d,d,R,T")))
6601 (set (match_operand:GPR 0 "register_operand" "=d,d,d,d")
6602 (minus:GPR (match_dup 1) (match_dup 2)))]
6603 "s390_match_ccmode (insn, CCL3mode)"
6609 [(set_attr "op_type" "RR<E>,RRF,RX<Y>,RXY")
6610 (set_attr "cpu_facility" "*,z196,*,longdisp")
6611 (set_attr "z10prop" "z10_super_c_E1,*,z10_super_E1,z10_super_E1")])
6613 ; slr, sl, sly, slgr, slg, slrk, slgrk
6614 (define_insn "*sub<mode>3_cconly"
6615 [(set (reg CC_REGNUM)
6616 (compare (minus:GPR (match_operand:GPR 1 "register_operand" "0,d,0,0")
6617 (match_operand:GPR 2 "general_operand" "d,d,R,T"))
6619 (clobber (match_scratch:GPR 0 "=d,d,d,d"))]
6620 "s390_match_ccmode (insn, CCLmode)"
6626 [(set_attr "op_type" "RR<E>,RRF,RX<Y>,RXY")
6627 (set_attr "cpu_facility" "*,z196,*,longdisp")
6628 (set_attr "z10prop" "z10_super_c_E1,*,z10_super_E1,z10_super_E1")])
6631 ; slr, sl, sly, slgr, slg, slrk, slgrk
6632 (define_insn "*sub<mode>3_cconly2"
6633 [(set (reg CC_REGNUM)
6634 (compare (match_operand:GPR 1 "register_operand" "0,d,0,0")
6635 (match_operand:GPR 2 "general_operand" "d,d,R,T")))
6636 (clobber (match_scratch:GPR 0 "=d,d,d,d"))]
6637 "s390_match_ccmode (insn, CCL3mode)"
6643 [(set_attr "op_type" "RR<E>,RRF,RX<Y>,RXY")
6644 (set_attr "cpu_facility" "*,z196,*,longdisp")
6645 (set_attr "z10prop" "z10_super_c_E1,*,z10_super_E1,z10_super_E1")])
6647 (define_insn "*subdi3_sign"
6648 [(set (match_operand:DI 0 "register_operand" "=d")
6649 (minus:DI (match_operand:DI 1 "register_operand" "0")
6650 (sign_extend:DI (match_operand:HI 2 "memory_operand" "T"))))
6651 (clobber (reg:CC CC_REGNUM))]
6654 [(set_attr "op_type" "RXY")])
6656 ; Jump to label OP3 if OP1 - OP2 results in a signed overflow
6657 (define_expand "subv<mode>4"
6659 [(set (reg:CCO CC_REGNUM)
6660 (compare:CCO (minus:<DBL>
6661 (sign_extend:<DBL> (match_operand:GPR 1 "nonimmediate_operand"))
6662 (sign_extend:<DBL> (match_operand:GPR 2 "nonimmediate_operand")))
6663 (sign_extend:<DBL> (minus:GPR (match_dup 1) (match_dup 2)))))
6664 (set (match_operand:GPR 0 "nonimmediate_operand")
6665 (minus:GPR (match_dup 1) (match_dup 2)))])
6667 (if_then_else (ne (reg:CCO CC_REGNUM) (const_int 0))
6668 (label_ref (match_operand 3))
6672 ; sr, s, sy, sgr, sg, srk, sgrk
6673 (define_insn "*subv<mode>3_ccoverflow"
6674 [(set (reg CC_REGNUM)
6675 (compare (minus:<DBL>
6676 (sign_extend:<DBL> (match_operand:GPR 1 "nonimmediate_operand" "0,d,0,0"))
6677 (sign_extend:<DBL> (match_operand:GPR 2 "nonimmediate_operand" "d,d,R,T")))
6678 (sign_extend:<DBL> (minus:GPR (match_dup 1) (match_dup 2)))))
6679 (set (match_operand:GPR 0 "register_operand" "=d,d,d,d")
6680 (minus:GPR (match_dup 1) (match_dup 2)))]
6681 "s390_match_ccmode (insn, CCOmode)"
6687 [(set_attr "op_type" "RR<E>,RRF,RX<Y>,RXY")
6688 (set_attr "cpu_facility" "*,z196,*,longdisp")
6689 (set_attr "z10prop" "z10_super_c_E1,*,z10_super_E1,z10_super_E1")])
6693 ; sub(tf|df|sf|td|dd)3 instruction pattern(s).
6696 ; FIXME: (clobber (match_scratch:CC 3 "=c,c,c,X,X")) does not work - why?
6697 ; sxbr, sdbr, sebr, sdb, seb, sxtr, sdtr
6698 (define_insn "sub<mode>3<tf_fpr>"
6699 [(set (match_operand:FP 0 "register_operand" "=f,f,f,v,v")
6700 (minus:FP (match_operand:FP 1 "register_operand" "f,0,0,v,v")
6701 (match_operand:FP 2 "general_operand" "f,f,R,v,v")))
6702 (clobber (reg:CC CC_REGNUM))]
6710 [(set_attr "op_type" "RRF,RRE,RXE,VRR,VRR")
6711 (set_attr "type" "fsimp<type>")
6712 (set_attr "cpu_facility" "*,*,*,vx,vxe")
6713 (set_attr "enabled" "<nBFP>,<nDFP>,<DSF>,<DF>,<SF>")])
6715 ; sxbr, sdbr, sebr, sdb, seb, sxtr, sdtr
6716 (define_insn "*sub<mode>3_cc"
6717 [(set (reg CC_REGNUM)
6718 (compare (minus:FP (match_operand:FP 1 "nonimmediate_operand" "f,0,0")
6719 (match_operand:FP 2 "general_operand" "f,f,R"))
6720 (match_operand:FP 3 "const0_operand" "")))
6721 (set (match_operand:FP 0 "register_operand" "=f,f,f")
6722 (minus:FP (match_dup 1) (match_dup 2)))]
6723 "s390_match_ccmode (insn, CCSmode) && TARGET_HARD_FLOAT"
6728 [(set_attr "op_type" "RRF,RRE,RXE")
6729 (set_attr "type" "fsimp<type>")
6730 (set_attr "enabled" "<nBFP>,<nDFP>,<DSF>")])
6732 ; sxbr, sdbr, sebr, sdb, seb, sxtr, sdtr
6733 (define_insn "*sub<mode>3_cconly"
6734 [(set (reg CC_REGNUM)
6735 (compare (minus:FP (match_operand:FP 1 "nonimmediate_operand" "f,0,0")
6736 (match_operand:FP 2 "general_operand" "f,f,R"))
6737 (match_operand:FP 3 "const0_operand" "")))
6738 (clobber (match_scratch:FP 0 "=f,f,f"))]
6739 "s390_match_ccmode (insn, CCSmode) && TARGET_HARD_FLOAT"
6744 [(set_attr "op_type" "RRF,RRE,RXE")
6745 (set_attr "type" "fsimp<type>")
6746 (set_attr "enabled" "<nBFP>,<nDFP>,<DSF>")])
6750 ;;- Conditional add/subtract instructions.
6754 ; add(di|si)cc instruction pattern(s).
6757 ; the following 4 patterns are used when the result of an add with
6758 ; carry is checked for an overflow condition
6760 ; op1 + op2 + c < op1
6762 ; alcr, alc, alcgr, alcg
6763 (define_insn "*add<mode>3_alc_carry1_cc"
6764 [(set (reg CC_REGNUM)
6766 (plus:GPR (plus:GPR (match_operand:GPR 3 "s390_alc_comparison" "")
6767 (match_operand:GPR 1 "nonimmediate_operand" "%0,0"))
6768 (match_operand:GPR 2 "general_operand" "d,T"))
6770 (set (match_operand:GPR 0 "register_operand" "=d,d")
6771 (plus:GPR (plus:GPR (match_dup 3) (match_dup 1)) (match_dup 2)))]
6772 "s390_match_ccmode (insn, CCL1mode)"
6776 [(set_attr "op_type" "RRE,RXY")
6777 (set_attr "z196prop" "z196_alone,z196_alone")])
6779 ; alcr, alc, alcgr, alcg
6780 (define_insn "*add<mode>3_alc_carry1_cconly"
6781 [(set (reg CC_REGNUM)
6783 (plus:GPR (plus:GPR (match_operand:GPR 3 "s390_alc_comparison" "")
6784 (match_operand:GPR 1 "nonimmediate_operand" "%0,0"))
6785 (match_operand:GPR 2 "general_operand" "d,T"))
6787 (clobber (match_scratch:GPR 0 "=d,d"))]
6788 "s390_match_ccmode (insn, CCL1mode)"
6792 [(set_attr "op_type" "RRE,RXY")
6793 (set_attr "z196prop" "z196_alone,z196_alone")])
6795 ; op1 + op2 + c < op2
6797 ; alcr, alc, alcgr, alcg
6798 (define_insn "*add<mode>3_alc_carry2_cc"
6799 [(set (reg CC_REGNUM)
6801 (plus:GPR (plus:GPR (match_operand:GPR 3 "s390_alc_comparison" "")
6802 (match_operand:GPR 1 "nonimmediate_operand" "%0,0"))
6803 (match_operand:GPR 2 "general_operand" "d,T"))
6805 (set (match_operand:GPR 0 "register_operand" "=d,d")
6806 (plus:GPR (plus:GPR (match_dup 3) (match_dup 1)) (match_dup 2)))]
6807 "s390_match_ccmode (insn, CCL1mode)"
6811 [(set_attr "op_type" "RRE,RXY")])
6813 ; alcr, alc, alcgr, alcg
6814 (define_insn "*add<mode>3_alc_carry2_cconly"
6815 [(set (reg CC_REGNUM)
6817 (plus:GPR (plus:GPR (match_operand:GPR 3 "s390_alc_comparison" "")
6818 (match_operand:GPR 1 "nonimmediate_operand" "%0,0"))
6819 (match_operand:GPR 2 "general_operand" "d,T"))
6821 (clobber (match_scratch:GPR 0 "=d,d"))]
6822 "s390_match_ccmode (insn, CCL1mode)"
6826 [(set_attr "op_type" "RRE,RXY")])
6828 ; alcr, alc, alcgr, alcg
6829 (define_insn "*add<mode>3_alc_cc"
6830 [(set (reg CC_REGNUM)
6832 (plus:GPR (plus:GPR (match_operand:GPR 3 "s390_alc_comparison" "")
6833 (match_operand:GPR 1 "nonimmediate_operand" "%0,0"))
6834 (match_operand:GPR 2 "general_operand" "d,T"))
6836 (set (match_operand:GPR 0 "register_operand" "=d,d")
6837 (plus:GPR (plus:GPR (match_dup 3) (match_dup 1)) (match_dup 2)))]
6838 "s390_match_ccmode (insn, CCLmode)"
6842 [(set_attr "op_type" "RRE,RXY")])
6844 ; alcr, alc, alcgr, alcg
6845 (define_insn "*add<mode>3_alc"
6846 [(set (match_operand:GPR 0 "register_operand" "=d,d")
6847 (plus:GPR (plus:GPR (match_operand:GPR 3 "s390_alc_comparison" "")
6848 (match_operand:GPR 1 "nonimmediate_operand" "%0,0"))
6849 (match_operand:GPR 2 "general_operand" "d,T")))
6850 (clobber (reg:CC CC_REGNUM))]
6855 [(set_attr "op_type" "RRE,RXY")])
6857 ; slbr, slb, slbgr, slbg
6858 (define_insn "*sub<mode>3_slb_cc"
6859 [(set (reg CC_REGNUM)
6861 (minus:GPR (minus:GPR (match_operand:GPR 1 "nonimmediate_operand" "0,0")
6862 (match_operand:GPR 2 "general_operand" "d,T"))
6863 (match_operand:GPR 3 "s390_slb_comparison" ""))
6865 (set (match_operand:GPR 0 "register_operand" "=d,d")
6866 (minus:GPR (minus:GPR (match_dup 1) (match_dup 2)) (match_dup 3)))]
6867 "s390_match_ccmode (insn, CCLmode)"
6871 [(set_attr "op_type" "RRE,RXY")
6872 (set_attr "z10prop" "z10_c,*")])
6874 ; slbr, slb, slbgr, slbg
6875 (define_insn "*sub<mode>3_slb"
6876 [(set (match_operand:GPR 0 "register_operand" "=d,d")
6877 (minus:GPR (minus:GPR (match_operand:GPR 1 "nonimmediate_operand" "0,0")
6878 (match_operand:GPR 2 "general_operand" "d,T"))
6879 (match_operand:GPR 3 "s390_slb_comparison" "")))
6880 (clobber (reg:CC CC_REGNUM))]
6885 [(set_attr "op_type" "RRE,RXY")
6886 (set_attr "z10prop" "z10_c,*")])
6888 (define_expand "add<mode>cc"
6889 [(match_operand:GPR 0 "register_operand" "")
6890 (match_operand 1 "comparison_operator" "")
6891 (match_operand:GPR 2 "register_operand" "")
6892 (match_operand:GPR 3 "const_int_operand" "")]
6894 "if (!s390_expand_addcc (GET_CODE (operands[1]),
6895 XEXP (operands[1], 0), XEXP (operands[1], 1),
6896 operands[0], operands[2],
6897 operands[3])) FAIL; DONE;")
6900 ; scond instruction pattern(s).
6903 (define_insn_and_split "*scond<mode>"
6904 [(set (match_operand:GPR 0 "register_operand" "=&d")
6905 (match_operand:GPR 1 "s390_alc_comparison" ""))
6906 (clobber (reg:CC CC_REGNUM))]
6909 "&& reload_completed"
6910 [(set (match_dup 0) (const_int 0))
6912 [(set (match_dup 0) (plus:GPR (plus:GPR (match_dup 1) (match_dup 0))
6914 (clobber (reg:CC CC_REGNUM))])]
6917 (define_insn_and_split "*scond<mode>_neg"
6918 [(set (match_operand:GPR 0 "register_operand" "=&d")
6919 (match_operand:GPR 1 "s390_slb_comparison" ""))
6920 (clobber (reg:CC CC_REGNUM))]
6923 "&& reload_completed"
6924 [(set (match_dup 0) (const_int 0))
6926 [(set (match_dup 0) (minus:GPR (minus:GPR (match_dup 0) (match_dup 0))
6928 (clobber (reg:CC CC_REGNUM))])
6930 [(set (match_dup 0) (neg:GPR (match_dup 0)))
6931 (clobber (reg:CC CC_REGNUM))])]
6935 (define_expand "cstore<mode>4"
6936 [(set (match_operand:SI 0 "register_operand" "")
6937 (match_operator:SI 1 "s390_scond_operator"
6938 [(match_operand:GPR 2 "register_operand" "")
6939 (match_operand:GPR 3 "general_operand" "")]))]
6941 "if (!s390_expand_addcc (GET_CODE (operands[1]), operands[2], operands[3],
6942 operands[0], const0_rtx, const1_rtx)) FAIL; DONE;")
6944 (define_expand "cstorecc4"
6946 [(set (match_operand:SI 0 "register_operand" "")
6947 (match_operator:SI 1 "s390_eqne_operator"
6948 [(match_operand 2 "cc_reg_operand")
6949 (match_operand 3 "const_mask_operand")]))
6950 (clobber (reg:CC CC_REGNUM))])]
6952 "machine_mode mode = GET_MODE (operands[2]);
6957 if (GET_CODE (operands[1]) == NE)
6958 cond = gen_rtx_NE (VOIDmode, operands[2], operands[3]);
6960 cond = gen_rtx_EQ (VOIDmode, operands[2], operands[3]);
6961 ite = gen_rtx_IF_THEN_ELSE (SImode, cond, const1_rtx, const0_rtx);
6962 emit_insn (gen_rtx_SET (operands[0], ite));
6966 if (mode != CCZ1mode || operands[3] != const0_rtx)
6968 emit_insn (gen_sne (operands[0], operands[2]));
6969 if (GET_CODE (operands[1]) == EQ)
6970 emit_insn (gen_xorsi3 (operands[0], operands[0], const1_rtx));
6974 (define_insn_and_split "sne"
6975 [(set (match_operand:SI 0 "register_operand" "=d")
6976 (ne:SI (match_operand:CCZ1 1 "register_operand" "0")
6978 (clobber (reg:CC CC_REGNUM))]
6983 [(set (match_dup 0) (ashiftrt:SI (match_dup 0) (const_int 28)))
6984 (clobber (reg:CC CC_REGNUM))])])
6986 ; Such patterns get directly emitted by noce_emit_store_flag.
6987 (define_insn_and_split "*cstorecc<mode>_z13"
6988 [(set (match_operand:GPR 0 "register_operand" "=&d")
6989 (match_operator:GPR 1 "s390_comparison"
6990 [(match_operand 2 "cc_reg_operand" "c")
6991 (match_operand 3 "const_int_operand" "")]))]
6995 [(set (match_dup 0) (const_int 0))
6998 (match_op_dup 1 [(match_dup 2) (match_dup 3)])
7003 ;; - Conditional move instructions (introduced with z196)
7006 (define_expand "mov<mode>cc"
7007 [(set (match_operand:GPR 0 "nonimmediate_operand" "")
7008 (if_then_else:GPR (match_operand 1 "comparison_operator" "")
7009 (match_operand:GPR 2 "loc_operand" "")
7010 (match_operand:GPR 3 "loc_operand" "")))]
7013 if (!TARGET_Z13 && CONSTANT_P (operands[2]))
7014 operands[2] = force_reg (<MODE>mode, operands[2]);
7016 if (!TARGET_Z13 && CONSTANT_P (operands[3]))
7017 operands[3] = force_reg (<MODE>mode, operands[3]);
7019 /* Emit the comparison insn in case we do not already have a comparison result. */
7020 if (!s390_comparison (operands[1], VOIDmode))
7021 operands[1] = s390_emit_compare (GET_CODE (operands[1]),
7022 XEXP (operands[1], 0),
7023 XEXP (operands[1], 1));
7027 ;; - We do not have instructions for QImode or HImode but still
7028 ;; enable load on condition/if conversion for them.
7029 (define_expand "mov<mode>cc"
7030 [(set (match_operand:HQI 0 "nonimmediate_operand" "")
7031 (if_then_else:HQI (match_operand 1 "comparison_operator" "")
7032 (match_operand:HQI 2 "loc_operand" "")
7033 (match_operand:HQI 3 "loc_operand" "")))]
7036 /* Emit the comparison insn in case we do not already have a comparison
7038 if (!s390_comparison (operands[1], VOIDmode))
7039 operands[1] = s390_emit_compare (GET_CODE (operands[1]),
7040 XEXP (operands[1], 0),
7041 XEXP (operands[1], 1));
7043 rtx then = operands[2];
7044 rtx els = operands[3];
7046 if ((!TARGET_Z13 && CONSTANT_P (then)) || MEM_P (then))
7047 then = force_reg (<MODE>mode, then);
7048 if ((!TARGET_Z13 && CONSTANT_P (els)) || MEM_P (els))
7049 els = force_reg (<MODE>mode, els);
7051 if (!CONSTANT_P (then))
7052 then = simplify_gen_subreg (E_SImode, then, <MODE>mode, 0);
7053 if (!CONSTANT_P (els))
7054 els = simplify_gen_subreg (E_SImode, els, <MODE>mode, 0);
7056 rtx tmp_target = simplify_gen_subreg (E_SImode, operands[0], <MODE>mode, 0);
7058 emit_insn (gen_movsicc (tmp_target, operands[1], then, els));
7064 ; locr, loc, stoc, locgr, locg, stocg, lochi, locghi, selr, selgr
7065 (define_insn "*mov<mode>cc"
7066 [(set (match_operand:GPR 0 "nonimmediate_operand" "=d,d,d,d,d,d,d,S,S")
7068 (match_operator 1 "s390_comparison"
7069 [(match_operand 2 "cc_reg_operand" " c,c,c,c,c,c,c,c,c")
7070 (match_operand 5 "const_int_operand" "")])
7071 (match_operand:GPR 3 "loc_operand" " d,0,d,S,0,K,0,d,0")
7072 (match_operand:GPR 4 "loc_operand" " 0,d,d,0,S,0,K,0,d")))]
7077 sel<g>r%C1\t%0,%3,%4
7084 [(set_attr "op_type" "RRF,RRF,RRF,RSY,RSY,RIE,RIE,RSY,RSY")
7085 (set_attr "cpu_facility" "*,*,z15,*,*,z13,z13,*,*")])
7088 ;;- Multiply instructions.
7092 ; muldi3 instruction pattern(s).
7095 (define_expand "muldi3"
7097 [(set (match_operand:DI 0 "register_operand")
7098 (mult:DI (match_operand:DI 1 "nonimmediate_operand")
7099 (match_operand:DI 2 "general_operand")))
7100 (clobber (reg:CC CC_REGNUM))])]
7103 (define_insn "*muldi3_sign"
7104 [(set (match_operand:DI 0 "register_operand" "=d,d")
7105 (mult:DI (sign_extend:DI (match_operand:SI 2 "general_operand" "d,T"))
7106 (match_operand:DI 1 "register_operand" "0,0")))]
7111 [(set_attr "op_type" "RRE,RXY")
7112 (set_attr "type" "imuldi")])
7114 (define_insn "*muldi3"
7115 [(set (match_operand:DI 0 "register_operand" "=d,d,d,d,d")
7116 (mult:DI (match_operand:DI 1 "nonimmediate_operand" "%0,d,0,0,0")
7117 (match_operand:DI 2 "general_operand" "d,d,K,T,Os")))
7118 (clobber (match_scratch:CC 3 "=X,c,X,X,X"))]
7126 [(set_attr "op_type" "RRE,RRF,RI,RXY,RIL")
7127 (set_attr "type" "imuldi")
7128 (set_attr "cpu_facility" "*,z14,*,*,z10")])
7130 (define_insn "mulditi3"
7131 [(set (match_operand:TI 0 "register_operand" "=d,d")
7132 (mult:TI (sign_extend:TI
7133 (match_operand:DI 1 "register_operand" "%d,0"))
7135 (match_operand:DI 2 "nonimmediate_operand" " d,T"))))]
7140 [(set_attr "op_type" "RRF,RXY")])
7142 ; Combine likes op1 and op2 to be swapped sometimes.
7143 (define_insn "mulditi3_2"
7144 [(set (match_operand:TI 0 "register_operand" "=d,d")
7145 (mult:TI (sign_extend:TI
7146 (match_operand:DI 1 "nonimmediate_operand" "%d,T"))
7148 (match_operand:DI 2 "register_operand" " d,0"))))]
7153 [(set_attr "op_type" "RRF,RXY")])
7155 (define_insn "*muldi3_sign"
7156 [(set (match_operand:DI 0 "register_operand" "=d")
7157 (mult:DI (sign_extend:DI (match_operand:HI 2 "memory_operand" "T"))
7158 (match_operand:DI 1 "register_operand" "0")))]
7161 [(set_attr "op_type" "RXY")])
7165 ; mulsi3 instruction pattern(s).
7168 (define_expand "mulsi3"
7170 [(set (match_operand:SI 0 "register_operand" "=d,d,d,d,d,d")
7171 (mult:SI (match_operand:SI 1 "nonimmediate_operand" "%0,d,0,0,0,0")
7172 (match_operand:SI 2 "general_operand" "d,d,K,R,T,Os")))
7173 (clobber (reg:CC CC_REGNUM))])]
7176 (define_insn "*mulsi3_sign"
7177 [(set (match_operand:SI 0 "register_operand" "=d,d")
7178 (mult:SI (sign_extend:SI (match_operand:HI 2 "memory_operand" "R,T"))
7179 (match_operand:SI 1 "register_operand" "0,0")))]
7184 [(set_attr "op_type" "RX,RXY")
7185 (set_attr "type" "imulhi")
7186 (set_attr "cpu_facility" "*,z10")])
7188 (define_insn "*mulsi3"
7189 [(set (match_operand:SI 0 "register_operand" "=d,d,d,d,d,d")
7190 (mult:SI (match_operand:SI 1 "nonimmediate_operand" "%0,d,0,0,0,0")
7191 (match_operand:SI 2 "general_operand" "d,d,K,R,T,Os")))
7192 (clobber (match_scratch:CC 3 "=X,c,X,X,X,X"))]
7201 [(set_attr "op_type" "RRE,RRF,RI,RX,RXY,RIL")
7202 (set_attr "type" "imulsi,*,imulhi,imulsi,imulsi,imulsi")
7203 (set_attr "cpu_facility" "*,z14,*,*,longdisp,z10")])
7206 ; mulsidi3 instruction pattern(s).
7209 (define_insn "mulsidi3"
7210 [(set (match_operand:DI 0 "register_operand" "=d,d,d")
7211 (mult:DI (sign_extend:DI
7212 (match_operand:SI 1 "register_operand" "%0,0,0"))
7214 (match_operand:SI 2 "nonimmediate_operand" "d,R,T"))))]
7220 [(set_attr "op_type" "RR,RX,RXY")
7221 (set_attr "type" "imulsi")
7222 (set_attr "cpu_facility" "*,*,z10")])
7224 ; Jump to label OP3 if OP1 * OP2 results in a signed overflow
7225 (define_expand "mulv<mode>4"
7227 [(set (reg:CCO CC_REGNUM)
7228 (compare:CCO (mult:<DBL>
7229 (sign_extend:<DBL> (match_operand:GPR 1 "register_operand"))
7230 (sign_extend:<DBL> (match_operand:GPR 2 "nonimmediate_operand")))
7231 (sign_extend:<DBL> (mult:GPR (match_dup 1) (match_dup 2)))))
7232 (set (match_operand:GPR 0 "register_operand")
7233 (mult:GPR (match_dup 1) (match_dup 2)))])
7235 (if_then_else (ne (reg:CCO CC_REGNUM) (const_int 0))
7236 (label_ref (match_operand 3))
7240 ; msrkc, msc, msgrkc, msgc
7241 (define_insn "*mulv<mode>3_ccoverflow"
7242 [(set (reg CC_REGNUM)
7243 (compare (mult:<DBL>
7244 (sign_extend:<DBL> (match_operand:GPR 1 "register_operand" "%d,0"))
7245 (sign_extend:<DBL> (match_operand:GPR 2 "nonimmediate_operand" " d,T")))
7246 (sign_extend:<DBL> (mult:GPR (match_dup 1) (match_dup 2)))))
7247 (set (match_operand:GPR 0 "register_operand" "=d,d")
7248 (mult:GPR (match_dup 1) (match_dup 2)))]
7249 "s390_match_ccmode (insn, CCOmode) && TARGET_Z14"
7253 [(set_attr "op_type" "RRF,RXY")])
7257 ; umul instruction pattern(s).
7260 ; mlr, ml, mlgr, mlg
7261 (define_insn "umul<dwh><mode>3"
7262 [(set (match_operand:DW 0 "register_operand" "=d,d")
7263 (mult:DW (zero_extend:DW
7264 (match_operand:<DWH> 1 "register_operand" "%0,0"))
7266 (match_operand:<DWH> 2 "nonimmediate_operand" " d,T"))))]
7271 [(set_attr "op_type" "RRE,RXY")
7272 (set_attr "type" "imul<dwh>")])
7275 ; mul(tf|df|sf|td|dd)3 instruction pattern(s).
7278 ; mxbr, mdbr, meebr, mxb, mxb, meeb, mdtr, mxtr
7279 (define_insn "mul<mode>3<tf_fpr>"
7280 [(set (match_operand:FP 0 "register_operand" "=f,f,f,v,v")
7281 (mult:FP (match_operand:FP 1 "nonimmediate_operand" "%f,0,0,v,v")
7282 (match_operand:FP 2 "general_operand" "f,f,R,v,v")))]
7290 [(set_attr "op_type" "RRF,RRE,RXE,VRR,VRR")
7291 (set_attr "type" "fmul<type>")
7292 (set_attr "cpu_facility" "*,*,*,vx,vxe")
7293 (set_attr "enabled" "<nBFP>,<nDFP>,<DSF>,<DF>,<SF>")])
7295 ; madbr, maebr, maxb, madb, maeb
7296 (define_insn "fma<mode>4"
7297 [(set (match_operand:DSF 0 "register_operand" "=f,f,v,v")
7298 (fma:DSF (match_operand:DSF 1 "nonimmediate_operand" "%f,f,v,v")
7299 (match_operand:DSF 2 "nonimmediate_operand" "f,R,v,v")
7300 (match_operand:DSF 3 "register_operand" "0,0,v,v")))]
7301 "TARGET_HARD_FLOAT && s390_fma_allowed_p (<MODE>mode)"
7305 wfmadb\t%v0,%v1,%v2,%v3
7306 wfmasb\t%v0,%v1,%v2,%v3"
7307 [(set_attr "op_type" "RRE,RXE,VRR,VRR")
7308 (set_attr "type" "fmadd<mode>")
7309 (set_attr "cpu_facility" "*,*,vx,vxe")
7310 (set_attr "enabled" "*,*,<DF>,<SF>")])
7312 ; msxbr, msdbr, msebr, msxb, msdb, mseb
7313 (define_insn "fms<mode>4"
7314 [(set (match_operand:DSF 0 "register_operand" "=f,f,v,v")
7315 (fma:DSF (match_operand:DSF 1 "nonimmediate_operand" "%f,f,v,v")
7316 (match_operand:DSF 2 "nonimmediate_operand" "f,R,v,v")
7317 (neg:DSF (match_operand:DSF 3 "register_operand" "0,0,v,v"))))]
7318 "TARGET_HARD_FLOAT && s390_fma_allowed_p (<MODE>mode)"
7322 wfmsdb\t%v0,%v1,%v2,%v3
7323 wfmssb\t%v0,%v1,%v2,%v3"
7324 [(set_attr "op_type" "RRE,RXE,VRR,VRR")
7325 (set_attr "type" "fmadd<mode>")
7326 (set_attr "cpu_facility" "*,*,vx,vxe")
7327 (set_attr "enabled" "*,*,<DF>,<SF>")])
7330 ;;- Divide and modulo instructions.
7334 ; divmoddi4 instruction pattern(s).
7337 (define_expand "divmoddi4"
7338 [(parallel [(set (match_operand:DI 0 "general_operand" "")
7339 (div:DI (match_operand:DI 1 "register_operand" "")
7340 (match_operand:DI 2 "general_operand" "")))
7341 (set (match_operand:DI 3 "general_operand" "")
7342 (mod:DI (match_dup 1) (match_dup 2)))])
7343 (clobber (match_dup 4))]
7346 rtx div_equal, mod_equal;
7349 div_equal = gen_rtx_DIV (DImode, operands[1], operands[2]);
7350 mod_equal = gen_rtx_MOD (DImode, operands[1], operands[2]);
7352 operands[4] = gen_reg_rtx(TImode);
7353 emit_insn (gen_divmodtidi3 (operands[4], operands[1], operands[2]));
7355 insn = emit_move_insn (operands[0], gen_lowpart (DImode, operands[4]));
7356 set_unique_reg_note (insn, REG_EQUAL, div_equal);
7358 insn = emit_move_insn (operands[3], gen_highpart (DImode, operands[4]));
7359 set_unique_reg_note (insn, REG_EQUAL, mod_equal);
7364 (define_insn "divmodtidi3"
7365 [(set (match_operand:TI 0 "register_operand" "=d,d")
7369 (mod:DI (match_operand:DI 1 "register_operand" "0,0")
7370 (match_operand:DI 2 "general_operand" "d,T")))
7372 (zero_extend:TI (div:DI (match_dup 1) (match_dup 2)))))]
7377 [(set_attr "op_type" "RRE,RXY")
7378 (set_attr "type" "idiv")])
7380 (define_insn "divmodtisi3"
7381 [(set (match_operand:TI 0 "register_operand" "=d,d")
7385 (mod:DI (match_operand:DI 1 "register_operand" "0,0")
7387 (match_operand:SI 2 "nonimmediate_operand" "d,T"))))
7390 (div:DI (match_dup 1) (sign_extend:DI (match_dup 2))))))]
7395 [(set_attr "op_type" "RRE,RXY")
7396 (set_attr "type" "idiv")])
7399 ; udivmoddi4 instruction pattern(s).
7402 (define_expand "udivmoddi4"
7403 [(parallel [(set (match_operand:DI 0 "general_operand" "")
7404 (udiv:DI (match_operand:DI 1 "general_operand" "")
7405 (match_operand:DI 2 "nonimmediate_operand" "")))
7406 (set (match_operand:DI 3 "general_operand" "")
7407 (umod:DI (match_dup 1) (match_dup 2)))])
7408 (clobber (match_dup 4))]
7411 rtx div_equal, mod_equal, equal;
7414 div_equal = gen_rtx_UDIV (DImode, operands[1], operands[2]);
7415 mod_equal = gen_rtx_UMOD (DImode, operands[1], operands[2]);
7416 equal = gen_rtx_IOR (TImode,
7417 gen_rtx_ASHIFT (TImode,
7418 gen_rtx_ZERO_EXTEND (TImode, mod_equal),
7420 gen_rtx_ZERO_EXTEND (TImode, div_equal));
7422 operands[4] = gen_reg_rtx(TImode);
7423 emit_clobber (operands[4]);
7424 emit_move_insn (gen_lowpart (DImode, operands[4]), operands[1]);
7425 emit_move_insn (gen_highpart (DImode, operands[4]), const0_rtx);
7427 insn = emit_insn (gen_udivmodtidi3 (operands[4], operands[4], operands[2]));
7428 set_unique_reg_note (insn, REG_EQUAL, equal);
7430 insn = emit_move_insn (operands[0], gen_lowpart (DImode, operands[4]));
7431 set_unique_reg_note (insn, REG_EQUAL, div_equal);
7433 insn = emit_move_insn (operands[3], gen_highpart (DImode, operands[4]));
7434 set_unique_reg_note (insn, REG_EQUAL, mod_equal);
7439 (define_insn "udivmodtidi3"
7440 [(set (match_operand:TI 0 "register_operand" "=d,d")
7445 (umod:TI (match_operand:TI 1 "register_operand" "0,0")
7447 (match_operand:DI 2 "nonimmediate_operand" "d,T")))))
7451 (udiv:TI (match_dup 1) (zero_extend:TI (match_dup 2)))))))]
7456 [(set_attr "op_type" "RRE,RXY")
7457 (set_attr "type" "idiv")])
7460 ; divmodsi4 instruction pattern(s).
7463 (define_expand "divmodsi4"
7464 [(parallel [(set (match_operand:SI 0 "general_operand" "")
7465 (div:SI (match_operand:SI 1 "general_operand" "")
7466 (match_operand:SI 2 "nonimmediate_operand" "")))
7467 (set (match_operand:SI 3 "general_operand" "")
7468 (mod:SI (match_dup 1) (match_dup 2)))])
7469 (clobber (match_dup 4))]
7472 rtx div_equal, mod_equal, equal;
7475 div_equal = gen_rtx_DIV (SImode, operands[1], operands[2]);
7476 mod_equal = gen_rtx_MOD (SImode, operands[1], operands[2]);
7477 equal = gen_rtx_IOR (DImode,
7478 gen_rtx_ASHIFT (DImode,
7479 gen_rtx_ZERO_EXTEND (DImode, mod_equal),
7481 gen_rtx_ZERO_EXTEND (DImode, div_equal));
7483 operands[4] = gen_reg_rtx(DImode);
7484 emit_insn (gen_extendsidi2 (operands[4], operands[1]));
7486 insn = emit_insn (gen_divmoddisi3 (operands[4], operands[4], operands[2]));
7487 set_unique_reg_note (insn, REG_EQUAL, equal);
7489 insn = emit_move_insn (operands[0], gen_lowpart (SImode, operands[4]));
7490 set_unique_reg_note (insn, REG_EQUAL, div_equal);
7492 insn = emit_move_insn (operands[3], gen_highpart (SImode, operands[4]));
7493 set_unique_reg_note (insn, REG_EQUAL, mod_equal);
7498 (define_insn "divmoddisi3"
7499 [(set (match_operand:DI 0 "register_operand" "=d,d")
7504 (mod:DI (match_operand:DI 1 "register_operand" "0,0")
7506 (match_operand:SI 2 "nonimmediate_operand" "d,R")))))
7510 (div:DI (match_dup 1) (sign_extend:DI (match_dup 2)))))))]
7515 [(set_attr "op_type" "RR,RX")
7516 (set_attr "type" "idiv")])
7519 ; udivsi3 and umodsi3 instruction pattern(s).
7522 (define_expand "udivmodsi4"
7523 [(parallel [(set (match_operand:SI 0 "general_operand" "")
7524 (udiv:SI (match_operand:SI 1 "general_operand" "")
7525 (match_operand:SI 2 "nonimmediate_operand" "")))
7526 (set (match_operand:SI 3 "general_operand" "")
7527 (umod:SI (match_dup 1) (match_dup 2)))])
7528 (clobber (match_dup 4))]
7531 rtx div_equal, mod_equal, equal;
7534 div_equal = gen_rtx_UDIV (SImode, operands[1], operands[2]);
7535 mod_equal = gen_rtx_UMOD (SImode, operands[1], operands[2]);
7536 equal = gen_rtx_IOR (DImode,
7537 gen_rtx_ASHIFT (DImode,
7538 gen_rtx_ZERO_EXTEND (DImode, mod_equal),
7540 gen_rtx_ZERO_EXTEND (DImode, div_equal));
7542 operands[4] = gen_reg_rtx(DImode);
7543 emit_clobber (operands[4]);
7544 emit_move_insn (gen_lowpart (SImode, operands[4]), operands[1]);
7545 emit_move_insn (gen_highpart (SImode, operands[4]), const0_rtx);
7547 insn = emit_insn (gen_udivmoddisi3 (operands[4], operands[4], operands[2]));
7548 set_unique_reg_note (insn, REG_EQUAL, equal);
7550 insn = emit_move_insn (operands[0], gen_lowpart (SImode, operands[4]));
7551 set_unique_reg_note (insn, REG_EQUAL, div_equal);
7553 insn = emit_move_insn (operands[3], gen_highpart (SImode, operands[4]));
7554 set_unique_reg_note (insn, REG_EQUAL, mod_equal);
7559 (define_insn "udivmoddisi3"
7560 [(set (match_operand:DI 0 "register_operand" "=d,d")
7565 (umod:DI (match_operand:DI 1 "register_operand" "0,0")
7567 (match_operand:SI 2 "nonimmediate_operand" "d,T")))))
7571 (udiv:DI (match_dup 1) (zero_extend:DI (match_dup 2)))))))]
7576 [(set_attr "op_type" "RRE,RXY")
7577 (set_attr "type" "idiv")])
7580 ; div(df|sf)3 instruction pattern(s).
7583 ; dxbr, ddbr, debr, ddb, deb, ddtr, dxtr
7584 (define_insn "div<mode>3<tf_fpr>"
7585 [(set (match_operand:FP 0 "register_operand" "=f,f,f,v,v")
7586 (div:FP (match_operand:FP 1 "register_operand" "f,0,0,v,v")
7587 (match_operand:FP 2 "general_operand" "f,f,R,v,v")))]
7595 [(set_attr "op_type" "RRF,RRE,RXE,VRR,VRR")
7596 (set_attr "type" "fdiv<type>")
7597 (set_attr "cpu_facility" "*,*,*,vx,vxe")
7598 (set_attr "enabled" "<nBFP>,<nDFP>,<DSF>,<DF>,<SF>")])
7602 ;;- And instructions.
7605 (define_expand "and<mode>3"
7606 [(set (match_operand:INT 0 "nonimmediate_operand" "")
7607 (and:INT (match_operand:INT 1 "nonimmediate_operand" "")
7608 (match_operand:INT 2 "general_operand" "")))
7609 (clobber (reg:CC CC_REGNUM))]
7611 "s390_expand_logical_operator (AND, <MODE>mode, operands); DONE;")
7614 ; anddi3 instruction pattern(s).
7617 (define_insn "*anddi3_cc"
7618 [(set (reg CC_REGNUM)
7620 (and:DI (match_operand:DI 1 "nonimmediate_operand" "%0,d,0, d")
7621 (match_operand:DI 2 "general_operand" " d,d,T,NxxDw"))
7623 (set (match_operand:DI 0 "register_operand" "=d,d,d, d")
7624 (and:DI (match_dup 1) (match_dup 2)))]
7625 "TARGET_ZARCH && s390_match_ccmode(insn, CCTmode)"
7630 risbg\t%0,%1,%s2,128+%e2,0"
7631 [(set_attr "op_type" "RRE,RRF,RXY,RIE")
7632 (set_attr "cpu_facility" "*,z196,*,z10")
7633 (set_attr "z10prop" "z10_super_E1,*,z10_super_E1,z10_super_E1")])
7635 (define_insn "*anddi3_cconly"
7636 [(set (reg CC_REGNUM)
7638 (and:DI (match_operand:DI 1 "nonimmediate_operand" "%0,d,0, d")
7639 (match_operand:DI 2 "general_operand" " d,d,T,NxxDw"))
7641 (clobber (match_scratch:DI 0 "=d,d,d, d"))]
7643 && s390_match_ccmode(insn, CCTmode)
7644 /* Do not steal TM patterns. */
7645 && s390_single_part (operands[2], DImode, HImode, 0) < 0"
7650 risbg\t%0,%1,%s2,128+%e2,0"
7651 [(set_attr "op_type" "RRE,RRF,RXY,RIE")
7652 (set_attr "cpu_facility" "*,z196,*,z10")
7653 (set_attr "z10prop" "z10_super_E1,*,z10_super_E1,z10_super_E1")])
7655 (define_insn "*anddi3"
7656 [(set (match_operand:DI 0 "nonimmediate_operand"
7657 "=d,d, d, d, d, d, d, d,d,d,d, d, AQ,Q")
7659 (match_operand:DI 1 "nonimmediate_operand"
7660 "%d,o, 0, 0, 0, 0, 0, 0,0,d,0, d, 0,0")
7661 (match_operand:DI 2 "general_operand"
7662 "M, M,N0HDF,N1HDF,N2HDF,N3HDF,N0SDF,N1SDF,d,d,T,NxxDw,NxQDF,Q")))
7663 (clobber (reg:CC CC_REGNUM))]
7664 "TARGET_ZARCH && s390_logical_operator_ok_p (operands)"
7677 risbg\t%0,%1,%s2,128+%e2,0
7680 [(set_attr "op_type" "RRE,RXE,RI,RI,RI,RI,RIL,RIL,RRE,RRF,RXY,RIE,SI,SS")
7681 (set_attr "cpu_facility" "*,*,*,*,*,*,extimm,extimm,*,z196,*,z10,*,*")
7682 (set_attr "z10prop" "*,
7698 [(set (match_operand:DI 0 "s_operand" "")
7699 (and:DI (match_dup 0) (match_operand:DI 1 "immediate_operand" "")))
7700 (clobber (reg:CC CC_REGNUM))]
7703 [(set (match_dup 0) (and:QI (match_dup 0) (match_dup 1)))
7704 (clobber (reg:CC CC_REGNUM))])]
7705 "s390_narrow_logical_operator (AND, &operands[0], &operands[1]);")
7707 ;; These two are what combine generates for (ashift (zero_extract)).
7708 (define_insn "*extzv_<mode>_srl<clobbercc_or_nocc>"
7709 [(set (match_operand:GPR 0 "register_operand" "=d")
7710 (and:GPR (lshiftrt:GPR
7711 (match_operand:GPR 1 "register_operand" "d")
7712 (match_operand:GPR 2 "nonzero_shift_count_operand" ""))
7713 (match_operand:GPR 3 "contiguous_bitmask_nowrap_operand" "")))]
7714 "<z10_or_zEC12_cond>
7715 /* Note that even for the SImode pattern, the rotate is always DImode. */
7716 && s390_extzv_shift_ok (<bitsize>, -INTVAL (operands[2]),
7717 INTVAL (operands[3]))"
7718 "<risbg_n>\t%0,%1,%<bfstart>3,128+%<bfend>3,64-%2"
7719 [(set_attr "op_type" "RIE")
7720 (set_attr "z10prop" "z10_super_E1")])
7722 (define_insn "*extzv_<mode>_sll<clobbercc_or_nocc>"
7723 [(set (match_operand:GPR 0 "register_operand" "=d")
7724 (and:GPR (ashift:GPR
7725 (match_operand:GPR 1 "register_operand" "d")
7726 (match_operand:GPR 2 "nonzero_shift_count_operand" ""))
7727 (match_operand:GPR 3 "contiguous_bitmask_nowrap_operand" "")))]
7728 "<z10_or_zEC12_cond>
7729 && s390_extzv_shift_ok (<bitsize>, INTVAL (operands[2]),
7730 INTVAL (operands[3]))"
7731 "<risbg_n>\t%0,%1,%<bfstart>3,128+%<bfend>3,%2"
7732 [(set_attr "op_type" "RIE")
7733 (set_attr "z10prop" "z10_super_E1")])
7737 ; andsi3 instruction pattern(s).
7740 (define_insn "*andsi3_cc"
7741 [(set (reg CC_REGNUM)
7744 (match_operand:SI 1 "nonimmediate_operand" "%0,0,d,0,0, d")
7745 (match_operand:SI 2 "general_operand" "Os,d,d,R,T,NxxSq"))
7747 (set (match_operand:SI 0 "register_operand" "=d,d,d,d,d, d")
7748 (and:SI (match_dup 1) (match_dup 2)))]
7749 "s390_match_ccmode(insn, CCTmode)"
7756 risbg\t%0,%1,%t2,128+%f2,0"
7757 [(set_attr "op_type" "RIL,RR,RRF,RX,RXY,RIE")
7758 (set_attr "cpu_facility" "*,*,z196,*,longdisp,z10")
7759 (set_attr "z10prop" "z10_super_E1,z10_super_E1,*,
7760 z10_super_E1,z10_super_E1,z10_super_E1")])
7762 (define_insn "*andsi3_cconly"
7763 [(set (reg CC_REGNUM)
7766 (match_operand:SI 1 "nonimmediate_operand" "%0,0,d,0,0, d")
7767 (match_operand:SI 2 "general_operand" "Os,d,d,R,T,NxxSq"))
7769 (clobber (match_scratch:SI 0 "=d,d,d,d,d, d"))]
7770 "s390_match_ccmode(insn, CCTmode)
7771 /* Do not steal TM patterns. */
7772 && s390_single_part (operands[2], SImode, HImode, 0) < 0"
7779 risbg\t%0,%1,%t2,128+%f2,0"
7780 [(set_attr "op_type" "RIL,RR,RRF,RX,RXY,RIE")
7781 (set_attr "cpu_facility" "*,*,z196,*,longdisp,z10")
7782 (set_attr "z10prop" "z10_super_E1,z10_super_E1,*,
7783 z10_super_E1,z10_super_E1,z10_super_E1")])
7785 (define_insn "*andsi3_zarch"
7786 [(set (match_operand:SI 0 "nonimmediate_operand"
7787 "=d,d, d, d, d,d,d,d,d, d, AQ,Q")
7788 (and:SI (match_operand:SI 1 "nonimmediate_operand"
7789 "%d,o, 0, 0, 0,0,d,0,0, d, 0,0")
7790 (match_operand:SI 2 "general_operand"
7791 " M,M,N0HSF,N1HSF,Os,d,d,R,T,NxxSw,NxQSF,Q")))
7792 (clobber (reg:CC CC_REGNUM))]
7793 "TARGET_ZARCH && s390_logical_operator_ok_p (operands)"
7804 risbg\t%0,%1,%t2,128+%f2,0
7807 [(set_attr "op_type" "RRE,RXE,RI,RI,RIL,RR,RRF,RX,RXY,RIE,SI,SS")
7808 (set_attr "cpu_facility" "*,*,*,*,*,*,z196,*,longdisp,z10,*,*")
7809 (set_attr "z10prop" "*,
7822 (define_insn "*andsi3_esa"
7823 [(set (match_operand:SI 0 "nonimmediate_operand" "=d,d, AQ,Q")
7824 (and:SI (match_operand:SI 1 "nonimmediate_operand" "%0,0, 0,0")
7825 (match_operand:SI 2 "general_operand" " d,R,NxQSF,Q")))
7826 (clobber (reg:CC CC_REGNUM))]
7827 "!TARGET_ZARCH && s390_logical_operator_ok_p (operands)"
7833 [(set_attr "op_type" "RR,RX,SI,SS")
7834 (set_attr "z10prop" "z10_super_E1,z10_super_E1,*,*")])
7838 [(set (match_operand:SI 0 "s_operand" "")
7839 (and:SI (match_dup 0) (match_operand:SI 1 "immediate_operand" "")))
7840 (clobber (reg:CC CC_REGNUM))]
7843 [(set (match_dup 0) (and:QI (match_dup 0) (match_dup 1)))
7844 (clobber (reg:CC CC_REGNUM))])]
7845 "s390_narrow_logical_operator (AND, &operands[0], &operands[1]);")
7848 ; andhi3 instruction pattern(s).
7851 (define_insn "*andhi3_zarch"
7852 [(set (match_operand:HI 0 "nonimmediate_operand" "=d,d,d, AQ,Q")
7853 (and:HI (match_operand:HI 1 "nonimmediate_operand" "%0,d,0, 0,0")
7854 (match_operand:HI 2 "general_operand" " d,d,n,NxQHF,Q")))
7855 (clobber (reg:CC CC_REGNUM))]
7856 "TARGET_ZARCH && s390_logical_operator_ok_p (operands)"
7863 [(set_attr "op_type" "RR,RRF,RI,SI,SS")
7864 (set_attr "cpu_facility" "*,z196,*,*,*")
7865 (set_attr "z10prop" "z10_super_E1,*,z10_super_E1,*,*")
7868 (define_insn "*andhi3_esa"
7869 [(set (match_operand:HI 0 "nonimmediate_operand" "=d,AQ,Q")
7870 (and:HI (match_operand:HI 1 "nonimmediate_operand" "%0,0,0")
7871 (match_operand:HI 2 "general_operand" "d,NxQHF,Q")))
7872 (clobber (reg:CC CC_REGNUM))]
7873 "!TARGET_ZARCH && s390_logical_operator_ok_p (operands)"
7878 [(set_attr "op_type" "RR,SI,SS")
7879 (set_attr "z10prop" "z10_super_E1,*,*")
7883 [(set (match_operand:HI 0 "s_operand" "")
7884 (and:HI (match_dup 0) (match_operand:HI 1 "immediate_operand" "")))
7885 (clobber (reg:CC CC_REGNUM))]
7888 [(set (match_dup 0) (and:QI (match_dup 0) (match_dup 1)))
7889 (clobber (reg:CC CC_REGNUM))])]
7890 "s390_narrow_logical_operator (AND, &operands[0], &operands[1]);")
7893 ; andqi3 instruction pattern(s).
7896 (define_insn "*andqi3_zarch"
7897 [(set (match_operand:QI 0 "nonimmediate_operand" "=d,d,d,Q,S,Q")
7898 (and:QI (match_operand:QI 1 "nonimmediate_operand" "%0,d,0,0,0,0")
7899 (match_operand:QI 2 "general_operand" " d,d,n,n,n,Q")))
7900 (clobber (reg:CC CC_REGNUM))]
7901 "TARGET_ZARCH && s390_logical_operator_ok_p (operands)"
7909 [(set_attr "op_type" "RR,RRF,RI,SI,SIY,SS")
7910 (set_attr "cpu_facility" "*,z196,*,*,longdisp,*")
7911 (set_attr "z10prop" "z10_super_E1,*,z10_super_E1,z10_super,z10_super,*")])
7913 (define_insn "*andqi3_esa"
7914 [(set (match_operand:QI 0 "nonimmediate_operand" "=d,Q,Q")
7915 (and:QI (match_operand:QI 1 "nonimmediate_operand" "%0,0,0")
7916 (match_operand:QI 2 "general_operand" "d,n,Q")))
7917 (clobber (reg:CC CC_REGNUM))]
7918 "!TARGET_ZARCH && s390_logical_operator_ok_p (operands)"
7923 [(set_attr "op_type" "RR,SI,SS")
7924 (set_attr "z10prop" "z10_super_E1,z10_super,*")])
7927 ; And with complement
7929 ; c = ~b & a = (b & a) ^ a
7931 (define_insn_and_split "*andc_split_<mode>"
7932 [(set (match_operand:GPR 0 "nonimmediate_operand" "")
7933 (and:GPR (not:GPR (match_operand:GPR 1 "nonimmediate_operand" ""))
7934 (match_operand:GPR 2 "general_operand" "")))
7935 (clobber (reg:CC CC_REGNUM))]
7937 && ! reload_completed
7938 && (GET_CODE (operands[0]) != MEM
7939 /* Ensure that s390_logical_operator_ok_p will succeed even
7940 on the split xor if (b & a) is stored into a pseudo. */
7941 || rtx_equal_p (operands[0], operands[2]))"
7946 [(set (match_dup 3) (and:GPR (match_dup 1) (match_dup 2)))
7947 (clobber (reg:CC CC_REGNUM))])
7949 [(set (match_dup 0) (xor:GPR (match_dup 3) (match_dup 2)))
7950 (clobber (reg:CC CC_REGNUM))])]
7952 if (reg_overlap_mentioned_p (operands[0], operands[2]))
7953 operands[3] = gen_reg_rtx (<MODE>mode);
7955 operands[3] = operands[0];
7959 ; Block and (NC) patterns.
7963 [(set (match_operand:BLK 0 "memory_operand" "=Q")
7964 (and:BLK (match_dup 0)
7965 (match_operand:BLK 1 "memory_operand" "Q")))
7966 (use (match_operand 2 "const_int_operand" "n"))
7967 (clobber (reg:CC CC_REGNUM))]
7968 "INTVAL (operands[2]) >= 1 && INTVAL (operands[2]) <= 256"
7969 "nc\t%O0(%2,%R0),%S1"
7970 [(set_attr "op_type" "SS")
7971 (set_attr "z196prop" "z196_cracked")])
7974 [(set (match_operand 0 "memory_operand" "")
7976 (match_operand 1 "memory_operand" "")))
7977 (clobber (reg:CC CC_REGNUM))]
7979 && GET_MODE (operands[0]) == GET_MODE (operands[1])
7980 && GET_MODE_SIZE (GET_MODE (operands[0])) > 0"
7982 [(set (match_dup 0) (and:BLK (match_dup 0) (match_dup 1)))
7984 (clobber (reg:CC CC_REGNUM))])]
7986 operands[2] = GEN_INT (GET_MODE_SIZE (GET_MODE (operands[0])));
7987 operands[0] = adjust_address (operands[0], BLKmode, 0);
7988 operands[1] = adjust_address (operands[1], BLKmode, 0);
7993 [(set (match_operand:BLK 0 "memory_operand" "")
7994 (and:BLK (match_dup 0)
7995 (match_operand:BLK 1 "memory_operand" "")))
7996 (use (match_operand 2 "const_int_operand" ""))
7997 (clobber (reg:CC CC_REGNUM))])
7999 [(set (match_operand:BLK 3 "memory_operand" "")
8000 (and:BLK (match_dup 3)
8001 (match_operand:BLK 4 "memory_operand" "")))
8002 (use (match_operand 5 "const_int_operand" ""))
8003 (clobber (reg:CC CC_REGNUM))])]
8004 "s390_offset_p (operands[0], operands[3], operands[2])
8005 && s390_offset_p (operands[1], operands[4], operands[2])
8006 && !s390_overlap_p (operands[0], operands[1],
8007 INTVAL (operands[2]) + INTVAL (operands[5]))
8008 && INTVAL (operands[2]) + INTVAL (operands[5]) <= 256"
8010 [(set (match_dup 6) (and:BLK (match_dup 6) (match_dup 7)))
8012 (clobber (reg:CC CC_REGNUM))])]
8013 "operands[6] = gen_rtx_MEM (BLKmode, XEXP (operands[0], 0));
8014 operands[7] = gen_rtx_MEM (BLKmode, XEXP (operands[1], 0));
8015 operands[8] = GEN_INT (INTVAL (operands[2]) + INTVAL (operands[5]));")
8019 ;;- Bit set (inclusive or) instructions.
8022 (define_expand "ior<mode>3"
8023 [(set (match_operand:INT 0 "nonimmediate_operand" "")
8024 (ior:INT (match_operand:INT 1 "nonimmediate_operand" "")
8025 (match_operand:INT 2 "general_operand" "")))
8026 (clobber (reg:CC CC_REGNUM))]
8028 "s390_expand_logical_operator (IOR, <MODE>mode, operands); DONE;")
8031 ; iordi3 instruction pattern(s).
8034 (define_insn "*iordi3_cc"
8035 [(set (reg CC_REGNUM)
8036 (compare (ior:DI (match_operand:DI 1 "nonimmediate_operand" "%0,d,0")
8037 (match_operand:DI 2 "general_operand" " d,d,T"))
8039 (set (match_operand:DI 0 "register_operand" "=d,d,d")
8040 (ior:DI (match_dup 1) (match_dup 2)))]
8041 "s390_match_ccmode(insn, CCTmode) && TARGET_ZARCH"
8046 [(set_attr "op_type" "RRE,RRF,RXY")
8047 (set_attr "cpu_facility" "*,z196,*")
8048 (set_attr "z10prop" "z10_super_E1,*,z10_super_E1")])
8050 (define_insn "*iordi3_cconly"
8051 [(set (reg CC_REGNUM)
8052 (compare (ior:DI (match_operand:DI 1 "nonimmediate_operand" "%0,d,0")
8053 (match_operand:DI 2 "general_operand" " d,d,T"))
8055 (clobber (match_scratch:DI 0 "=d,d,d"))]
8056 "s390_match_ccmode(insn, CCTmode) && TARGET_ZARCH"
8061 [(set_attr "op_type" "RRE,RRF,RXY")
8062 (set_attr "cpu_facility" "*,z196,*")
8063 (set_attr "z10prop" "z10_super_E1,*,z10_super_E1")])
8065 (define_insn "*iordi3"
8066 [(set (match_operand:DI 0 "nonimmediate_operand"
8067 "=d, d, d, d, d, d,d,d,d, AQ,Q")
8068 (ior:DI (match_operand:DI 1 "nonimmediate_operand"
8069 " %0, 0, 0, 0, 0, 0,0,d,0, 0,0")
8070 (match_operand:DI 2 "general_operand"
8071 "N0HD0,N1HD0,N2HD0,N3HD0,N0SD0,N1SD0,d,d,T,NxQD0,Q")))
8072 (clobber (reg:CC CC_REGNUM))]
8073 "TARGET_ZARCH && s390_logical_operator_ok_p (operands)"
8086 [(set_attr "op_type" "RI,RI,RI,RI,RIL,RIL,RRE,RRF,RXY,SI,SS")
8087 (set_attr "cpu_facility" "*,*,*,*,extimm,extimm,*,z196,*,*,*")
8088 (set_attr "z10prop" "z10_super_E1,
8101 [(set (match_operand:DI 0 "s_operand" "")
8102 (ior:DI (match_dup 0) (match_operand:DI 1 "immediate_operand" "")))
8103 (clobber (reg:CC CC_REGNUM))]
8106 [(set (match_dup 0) (ior:QI (match_dup 0) (match_dup 1)))
8107 (clobber (reg:CC CC_REGNUM))])]
8108 "s390_narrow_logical_operator (IOR, &operands[0], &operands[1]);")
8111 ; iorsi3 instruction pattern(s).
8114 (define_insn "*iorsi3_cc"
8115 [(set (reg CC_REGNUM)
8116 (compare (ior:SI (match_operand:SI 1 "nonimmediate_operand" "%0,0,d,0,0")
8117 (match_operand:SI 2 "general_operand" "Os,d,d,R,T"))
8119 (set (match_operand:SI 0 "register_operand" "=d,d,d,d,d")
8120 (ior:SI (match_dup 1) (match_dup 2)))]
8121 "s390_match_ccmode(insn, CCTmode)"
8128 [(set_attr "op_type" "RIL,RR,RRF,RX,RXY")
8129 (set_attr "cpu_facility" "*,*,z196,*,longdisp")
8130 (set_attr "z10prop" "z10_super_E1,z10_super_E1,*,z10_super_E1,z10_super_E1")])
8132 (define_insn "*iorsi3_cconly"
8133 [(set (reg CC_REGNUM)
8134 (compare (ior:SI (match_operand:SI 1 "nonimmediate_operand" "%0,0,d,0,0")
8135 (match_operand:SI 2 "general_operand" "Os,d,d,R,T"))
8137 (clobber (match_scratch:SI 0 "=d,d,d,d,d"))]
8138 "s390_match_ccmode(insn, CCTmode)"
8145 [(set_attr "op_type" "RIL,RR,RRF,RX,RXY")
8146 (set_attr "cpu_facility" "*,*,z196,*,longdisp")
8147 (set_attr "z10prop" "z10_super_E1,z10_super_E1,*,z10_super_E1,z10_super_E1")])
8149 (define_insn "*iorsi3_zarch"
8150 [(set (match_operand:SI 0 "nonimmediate_operand" "=d, d, d,d,d,d,d, AQ,Q")
8151 (ior:SI (match_operand:SI 1 "nonimmediate_operand" "%0, 0, 0,0,d,0,0, 0,0")
8152 (match_operand:SI 2 "general_operand" "N0HS0,N1HS0,Os,d,d,R,T,NxQS0,Q")))
8153 (clobber (reg:CC CC_REGNUM))]
8154 "TARGET_ZARCH && s390_logical_operator_ok_p (operands)"
8165 [(set_attr "op_type" "RI,RI,RIL,RR,RRF,RX,RXY,SI,SS")
8166 (set_attr "cpu_facility" "*,*,*,*,z196,*,longdisp,*,*")
8167 (set_attr "z10prop" "z10_super_E1,
8177 (define_insn "*iorsi3_esa"
8178 [(set (match_operand:SI 0 "nonimmediate_operand" "=d,d,AQ,Q")
8179 (ior:SI (match_operand:SI 1 "nonimmediate_operand" "%0,0,0,0")
8180 (match_operand:SI 2 "general_operand" "d,R,NxQS0,Q")))
8181 (clobber (reg:CC CC_REGNUM))]
8182 "!TARGET_ZARCH && s390_logical_operator_ok_p (operands)"
8188 [(set_attr "op_type" "RR,RX,SI,SS")
8189 (set_attr "z10prop" "z10_super_E1,z10_super_E1,*,*")])
8192 [(set (match_operand:SI 0 "s_operand" "")
8193 (ior:SI (match_dup 0) (match_operand:SI 1 "immediate_operand" "")))
8194 (clobber (reg:CC CC_REGNUM))]
8197 [(set (match_dup 0) (ior:QI (match_dup 0) (match_dup 1)))
8198 (clobber (reg:CC CC_REGNUM))])]
8199 "s390_narrow_logical_operator (IOR, &operands[0], &operands[1]);")
8202 ; iorhi3 instruction pattern(s).
8205 (define_insn "*iorhi3_zarch"
8206 [(set (match_operand:HI 0 "nonimmediate_operand" "=d,d,d, AQ,Q")
8207 (ior:HI (match_operand:HI 1 "nonimmediate_operand" "%0,d,0, 0,0")
8208 (match_operand:HI 2 "general_operand" " d,d,n,NxQH0,Q")))
8209 (clobber (reg:CC CC_REGNUM))]
8210 "TARGET_ZARCH && s390_logical_operator_ok_p (operands)"
8217 [(set_attr "op_type" "RR,RRF,RI,SI,SS")
8218 (set_attr "cpu_facility" "*,z196,*,*,*")
8219 (set_attr "z10prop" "z10_super_E1,*,z10_super_E1,*,*")])
8221 (define_insn "*iorhi3_esa"
8222 [(set (match_operand:HI 0 "nonimmediate_operand" "=d,AQ,Q")
8223 (ior:HI (match_operand:HI 1 "nonimmediate_operand" "%0,0,0")
8224 (match_operand:HI 2 "general_operand" "d,NxQH0,Q")))
8225 (clobber (reg:CC CC_REGNUM))]
8226 "!TARGET_ZARCH && s390_logical_operator_ok_p (operands)"
8231 [(set_attr "op_type" "RR,SI,SS")
8232 (set_attr "z10prop" "z10_super_E1,*,*")])
8235 [(set (match_operand:HI 0 "s_operand" "")
8236 (ior:HI (match_dup 0) (match_operand:HI 1 "immediate_operand" "")))
8237 (clobber (reg:CC CC_REGNUM))]
8240 [(set (match_dup 0) (ior:QI (match_dup 0) (match_dup 1)))
8241 (clobber (reg:CC CC_REGNUM))])]
8242 "s390_narrow_logical_operator (IOR, &operands[0], &operands[1]);")
8245 ; iorqi3 instruction pattern(s).
8248 (define_insn "*iorqi3_zarch"
8249 [(set (match_operand:QI 0 "nonimmediate_operand" "=d,d,d,Q,S,Q")
8250 (ior:QI (match_operand:QI 1 "nonimmediate_operand" "%0,d,0,0,0,0")
8251 (match_operand:QI 2 "general_operand" " d,d,n,n,n,Q")))
8252 (clobber (reg:CC CC_REGNUM))]
8253 "TARGET_ZARCH && s390_logical_operator_ok_p (operands)"
8261 [(set_attr "op_type" "RR,RRF,RI,SI,SIY,SS")
8262 (set_attr "cpu_facility" "*,z196,*,*,longdisp,*")
8263 (set_attr "z10prop" "z10_super_E1,*,z10_super_E1,
8264 z10_super,z10_super,*")])
8266 (define_insn "*iorqi3_esa"
8267 [(set (match_operand:QI 0 "nonimmediate_operand" "=d,Q,Q")
8268 (ior:QI (match_operand:QI 1 "nonimmediate_operand" "%0,0,0")
8269 (match_operand:QI 2 "general_operand" "d,n,Q")))
8270 (clobber (reg:CC CC_REGNUM))]
8271 "!TARGET_ZARCH && s390_logical_operator_ok_p (operands)"
8276 [(set_attr "op_type" "RR,SI,SS")
8277 (set_attr "z10prop" "z10_super_E1,z10_super,*")])
8280 ; And/Or with complement
8283 ; ncrk, ncgrk, ocrk, ocgrk
8284 (define_insn "*<ANDOR:bitops_name>c<GPR:mode>_cc"
8285 [(set (reg CC_REGNUM)
8287 (ANDOR:GPR (not:GPR (match_operand:GPR 1 "register_operand" "d"))
8288 (match_operand:GPR 2 "register_operand" "d"))
8290 (set (match_operand:GPR 0 "register_operand" "=d")
8291 (ANDOR:GPR (not:GPR (match_dup 1))
8293 "TARGET_Z15 && s390_match_ccmode(insn, CCTmode)"
8294 "<ANDOR:noxa>c<GPR:g>rk\t%0,%2,%1"
8295 [(set_attr "op_type" "RRF")])
8297 ; ncrk, ncgrk, ocrk, ocgrk
8298 (define_insn "*<ANDOR:bitops_name>c<GPR:mode>_cconly"
8299 [(set (reg CC_REGNUM)
8301 (ANDOR:GPR (not:GPR (match_operand:GPR 1 "register_operand" "d"))
8302 (match_operand:GPR 2 "register_operand" "d"))
8304 (clobber (match_scratch:GPR 0 "=d"))]
8305 "TARGET_Z15 && s390_match_ccmode(insn, CCTmode)"
8306 "<ANDOR:noxa>c<GPR:g>rk\t%0,%2,%1"
8307 [(set_attr "op_type" "RRF")])
8309 ; ncrk, ncgrk, ocrk, ocgrk
8310 (define_insn "*<ANDOR:bitops_name>c<GPR:mode>"
8311 [(set (match_operand:GPR 0 "register_operand" "=d")
8312 (ANDOR:GPR (not:GPR (match_operand:GPR 1 "register_operand" "d"))
8313 (match_operand:GPR 2 "register_operand" "d")))
8314 (clobber (reg:CC CC_REGNUM))]
8316 "<ANDOR:noxa>c<GPR:g>rk\t%0,%2,%1"
8317 [(set_attr "op_type" "RRF")])
8320 ;- Nand/Nor instructions.
8323 ; nnrk, nngrk, nork, nogrk
8324 (define_insn "*n<ANDOR:inv_bitops_name><GPR:mode>_cc"
8325 [(set (reg CC_REGNUM)
8327 (ANDOR:GPR (not:GPR (match_operand:GPR 1 "register_operand" "d"))
8328 (not:GPR (match_operand:GPR 2 "register_operand" "d")))
8330 (set (match_operand:GPR 0 "register_operand" "=d")
8331 (ANDOR:GPR (not:GPR (match_dup 1))
8332 (not:GPR (match_dup 2))))]
8333 "TARGET_Z15 && s390_match_ccmode(insn, CCTmode)"
8334 "n<ANDOR:inv_no><GPR:g>rk\t%0,%1,%2"
8335 [(set_attr "op_type" "RRF")])
8337 ; nnrk, nngrk, nork, nogrk
8338 (define_insn "*n<ANDOR:inv_bitops_name><mode>_cconly"
8339 [(set (reg CC_REGNUM)
8341 (ANDOR:GPR (not:GPR (match_operand:GPR 1 "register_operand" "d"))
8342 (not:GPR (match_operand:GPR 2 "register_operand" "d")))
8344 (clobber (match_scratch:GPR 0 "=d"))]
8345 "TARGET_Z15 && s390_match_ccmode(insn, CCTmode)"
8346 "n<ANDOR:inv_no><GPR:g>rk\t%0,%1,%2"
8347 [(set_attr "op_type" "RRF")])
8349 ; nnrk, nngrk, nork, nogrk
8350 (define_insn "*n<ANDOR:inv_bitops_name><mode>"
8351 [(set (match_operand:GPR 0 "register_operand" "=d")
8352 (ANDOR:GPR (not:GPR (match_operand:GPR 1 "register_operand" "d"))
8353 (not:GPR (match_operand:GPR 2 "register_operand" "d"))))
8354 (clobber (reg:CC CC_REGNUM))]
8356 "n<ANDOR:inv_no><GPR:g>rk\t%0,%1,%2"
8357 [(set_attr "op_type" "RRF")])
8359 ; Use NAND for bit inversion
8360 (define_insn "*not<mode>"
8361 [(set (match_operand:GPR 0 "register_operand" "=d")
8362 (not:GPR (match_operand:GPR 1 "register_operand" "d")))
8363 (clobber (reg:CC CC_REGNUM))]
8365 "nn<GPR:g>rk\t%0,%1,%1"
8366 [(set_attr "op_type" "RRF")])
8369 ; Block inclusive or (OC) patterns.
8373 [(set (match_operand:BLK 0 "memory_operand" "=Q")
8374 (ior:BLK (match_dup 0)
8375 (match_operand:BLK 1 "memory_operand" "Q")))
8376 (use (match_operand 2 "const_int_operand" "n"))
8377 (clobber (reg:CC CC_REGNUM))]
8378 "INTVAL (operands[2]) >= 1 && INTVAL (operands[2]) <= 256"
8379 "oc\t%O0(%2,%R0),%S1"
8380 [(set_attr "op_type" "SS")
8381 (set_attr "z196prop" "z196_cracked")])
8384 [(set (match_operand 0 "memory_operand" "")
8386 (match_operand 1 "memory_operand" "")))
8387 (clobber (reg:CC CC_REGNUM))]
8389 && GET_MODE (operands[0]) == GET_MODE (operands[1])
8390 && GET_MODE_SIZE (GET_MODE (operands[0])) > 0"
8392 [(set (match_dup 0) (ior:BLK (match_dup 0) (match_dup 1)))
8394 (clobber (reg:CC CC_REGNUM))])]
8396 operands[2] = GEN_INT (GET_MODE_SIZE (GET_MODE (operands[0])));
8397 operands[0] = adjust_address (operands[0], BLKmode, 0);
8398 operands[1] = adjust_address (operands[1], BLKmode, 0);
8403 [(set (match_operand:BLK 0 "memory_operand" "")
8404 (ior:BLK (match_dup 0)
8405 (match_operand:BLK 1 "memory_operand" "")))
8406 (use (match_operand 2 "const_int_operand" ""))
8407 (clobber (reg:CC CC_REGNUM))])
8409 [(set (match_operand:BLK 3 "memory_operand" "")
8410 (ior:BLK (match_dup 3)
8411 (match_operand:BLK 4 "memory_operand" "")))
8412 (use (match_operand 5 "const_int_operand" ""))
8413 (clobber (reg:CC CC_REGNUM))])]
8414 "s390_offset_p (operands[0], operands[3], operands[2])
8415 && s390_offset_p (operands[1], operands[4], operands[2])
8416 && !s390_overlap_p (operands[0], operands[1],
8417 INTVAL (operands[2]) + INTVAL (operands[5]))
8418 && INTVAL (operands[2]) + INTVAL (operands[5]) <= 256"
8420 [(set (match_dup 6) (ior:BLK (match_dup 6) (match_dup 7)))
8422 (clobber (reg:CC CC_REGNUM))])]
8423 "operands[6] = gen_rtx_MEM (BLKmode, XEXP (operands[0], 0));
8424 operands[7] = gen_rtx_MEM (BLKmode, XEXP (operands[1], 0));
8425 operands[8] = GEN_INT (INTVAL (operands[2]) + INTVAL (operands[5]));")
8429 ;;- Xor instructions.
8432 (define_expand "xor<mode>3"
8433 [(set (match_operand:INT 0 "nonimmediate_operand" "")
8434 (xor:INT (match_operand:INT 1 "nonimmediate_operand" "")
8435 (match_operand:INT 2 "general_operand" "")))
8436 (clobber (reg:CC CC_REGNUM))]
8438 "s390_expand_logical_operator (XOR, <MODE>mode, operands); DONE;")
8440 ; Combine replaces (xor (x) (const_int -1)) with (not (x)) when doing
8441 ; simplifications. So its better to have something matching.
8443 [(set (match_operand:INT 0 "nonimmediate_operand" "")
8444 (not:INT (match_operand:INT 1 "nonimmediate_operand" "")))]
8447 [(set (match_dup 0) (xor:INT (match_dup 1) (match_dup 2)))
8448 (clobber (reg:CC CC_REGNUM))])]
8450 operands[2] = constm1_rtx;
8451 if (!s390_logical_operator_ok_p (operands))
8456 ; xordi3 instruction pattern(s).
8459 (define_insn "*xordi3_cc"
8460 [(set (reg CC_REGNUM)
8461 (compare (xor:DI (match_operand:DI 1 "nonimmediate_operand" "%0,d,0")
8462 (match_operand:DI 2 "general_operand" " d,d,T"))
8464 (set (match_operand:DI 0 "register_operand" "=d,d,d")
8465 (xor:DI (match_dup 1) (match_dup 2)))]
8466 "s390_match_ccmode(insn, CCTmode) && TARGET_ZARCH"
8471 [(set_attr "op_type" "RRE,RRF,RXY")
8472 (set_attr "cpu_facility" "*,z196,*")
8473 (set_attr "z10prop" "z10_super_E1,*,z10_super_E1")])
8475 (define_insn "*xordi3_cconly"
8476 [(set (reg CC_REGNUM)
8477 (compare (xor:DI (match_operand:DI 1 "nonimmediate_operand" "%0,d,0")
8478 (match_operand:DI 2 "general_operand" " d,d,T"))
8480 (clobber (match_scratch:DI 0 "=d,d,d"))]
8481 "s390_match_ccmode(insn, CCTmode) && TARGET_ZARCH"
8486 [(set_attr "op_type" "RRE,RRF,RXY")
8487 (set_attr "cpu_facility" "*,z196,*")
8488 (set_attr "z10prop" "z10_super_E1,*,z10_super_E1")])
8490 (define_insn "*xordi3"
8491 [(set (match_operand:DI 0 "nonimmediate_operand" "=d, d,d,d,d, AQ,Q")
8492 (xor:DI (match_operand:DI 1 "nonimmediate_operand" "%0, 0,0,d,0, 0,0")
8493 (match_operand:DI 2 "general_operand" "N0SD0,N1SD0,d,d,T,NxQD0,Q")))
8494 (clobber (reg:CC CC_REGNUM))]
8495 "TARGET_ZARCH && s390_logical_operator_ok_p (operands)"
8504 [(set_attr "op_type" "RIL,RIL,RRE,RRF,RXY,SI,SS")
8505 (set_attr "cpu_facility" "extimm,extimm,*,z196,*,*,*")
8506 (set_attr "z10prop" "z10_super_E1,z10_super_E1,z10_super_E1,
8507 *,z10_super_E1,*,*")])
8510 [(set (match_operand:DI 0 "s_operand" "")
8511 (xor:DI (match_dup 0) (match_operand:DI 1 "immediate_operand" "")))
8512 (clobber (reg:CC CC_REGNUM))]
8515 [(set (match_dup 0) (xor:QI (match_dup 0) (match_dup 1)))
8516 (clobber (reg:CC CC_REGNUM))])]
8517 "s390_narrow_logical_operator (XOR, &operands[0], &operands[1]);")
8520 ; xorsi3 instruction pattern(s).
8523 (define_insn "*xorsi3_cc"
8524 [(set (reg CC_REGNUM)
8525 (compare (xor:SI (match_operand:SI 1 "nonimmediate_operand" "%0,0,d,0,0")
8526 (match_operand:SI 2 "general_operand" "Os,d,d,R,T"))
8528 (set (match_operand:SI 0 "register_operand" "=d,d,d,d,d")
8529 (xor:SI (match_dup 1) (match_dup 2)))]
8530 "s390_match_ccmode(insn, CCTmode)"
8537 [(set_attr "op_type" "RIL,RR,RRF,RX,RXY")
8538 (set_attr "cpu_facility" "*,*,z196,*,longdisp")
8539 (set_attr "z10prop" "z10_super_E1,z10_super_E1,*,
8540 z10_super_E1,z10_super_E1")])
8542 (define_insn "*xorsi3_cconly"
8543 [(set (reg CC_REGNUM)
8544 (compare (xor:SI (match_operand:SI 1 "nonimmediate_operand" "%0,0,d,0,0")
8545 (match_operand:SI 2 "general_operand" "Os,d,d,R,T"))
8547 (clobber (match_scratch:SI 0 "=d,d,d,d,d"))]
8548 "s390_match_ccmode(insn, CCTmode)"
8555 [(set_attr "op_type" "RIL,RR,RRF,RX,RXY")
8556 (set_attr "cpu_facility" "*,*,z196,*,longdisp")
8557 (set_attr "z10prop" "z10_super_E1,z10_super_E1,*,
8558 z10_super_E1,z10_super_E1")])
8560 (define_insn "*xorsi3"
8561 [(set (match_operand:SI 0 "nonimmediate_operand" "=d,d,d,d,d, AQ,Q")
8562 (xor:SI (match_operand:SI 1 "nonimmediate_operand" "%0,0,d,0,0, 0,0")
8563 (match_operand:SI 2 "general_operand" "Os,d,d,R,T,NxQS0,Q")))
8564 (clobber (reg:CC CC_REGNUM))]
8565 "s390_logical_operator_ok_p (operands)"
8574 [(set_attr "op_type" "RIL,RR,RRF,RX,RXY,SI,SS")
8575 (set_attr "cpu_facility" "*,*,z196,*,longdisp,*,*")
8576 (set_attr "z10prop" "z10_super_E1,z10_super_E1,*,
8577 z10_super_E1,z10_super_E1,*,*")])
8580 [(set (match_operand:SI 0 "s_operand" "")
8581 (xor:SI (match_dup 0) (match_operand:SI 1 "immediate_operand" "")))
8582 (clobber (reg:CC CC_REGNUM))]
8585 [(set (match_dup 0) (xor:QI (match_dup 0) (match_dup 1)))
8586 (clobber (reg:CC CC_REGNUM))])]
8587 "s390_narrow_logical_operator (XOR, &operands[0], &operands[1]);")
8590 ; xorhi3 instruction pattern(s).
8593 (define_insn "*xorhi3"
8594 [(set (match_operand:HI 0 "nonimmediate_operand" "=d,d,d, AQ,Q")
8595 (xor:HI (match_operand:HI 1 "nonimmediate_operand" "%0,0,d, 0,0")
8596 (match_operand:HI 2 "general_operand" "Os,d,d,NxQH0,Q")))
8597 (clobber (reg:CC CC_REGNUM))]
8598 "s390_logical_operator_ok_p (operands)"
8605 [(set_attr "op_type" "RIL,RR,RRF,SI,SS")
8606 (set_attr "cpu_facility" "*,*,z196,*,*")
8607 (set_attr "z10prop" "z10_super_E1,z10_super_E1,*,*,*")])
8610 [(set (match_operand:HI 0 "s_operand" "")
8611 (xor:HI (match_dup 0) (match_operand:HI 1 "immediate_operand" "")))
8612 (clobber (reg:CC CC_REGNUM))]
8615 [(set (match_dup 0) (xor:QI (match_dup 0) (match_dup 1)))
8616 (clobber (reg:CC CC_REGNUM))])]
8617 "s390_narrow_logical_operator (XOR, &operands[0], &operands[1]);")
8620 ; xorqi3 instruction pattern(s).
8623 (define_insn "*xorqi3"
8624 [(set (match_operand:QI 0 "nonimmediate_operand" "=d,d,d,Q,S,Q")
8625 (xor:QI (match_operand:QI 1 "nonimmediate_operand" "%0,0,d,0,0,0")
8626 (match_operand:QI 2 "general_operand" "Os,d,d,n,n,Q")))
8627 (clobber (reg:CC CC_REGNUM))]
8628 "s390_logical_operator_ok_p (operands)"
8636 [(set_attr "op_type" "RIL,RR,RRF,SI,SIY,SS")
8637 (set_attr "cpu_facility" "*,*,z196,*,longdisp,*")
8638 (set_attr "z10prop" "z10_super_E1,z10_super_E1,*,z10_super,z10_super,*")])
8642 ; Block exclusive or (XC) patterns.
8646 [(set (match_operand:BLK 0 "memory_operand" "=Q")
8647 (xor:BLK (match_dup 0)
8648 (match_operand:BLK 1 "memory_operand" "Q")))
8649 (use (match_operand 2 "const_int_operand" "n"))
8650 (clobber (reg:CC CC_REGNUM))]
8651 "INTVAL (operands[2]) >= 1 && INTVAL (operands[2]) <= 256"
8652 "xc\t%O0(%2,%R0),%S1"
8653 [(set_attr "op_type" "SS")])
8656 [(set (match_operand 0 "memory_operand" "")
8658 (match_operand 1 "memory_operand" "")))
8659 (clobber (reg:CC CC_REGNUM))]
8661 && GET_MODE (operands[0]) == GET_MODE (operands[1])
8662 && GET_MODE_SIZE (GET_MODE (operands[0])) > 0"
8664 [(set (match_dup 0) (xor:BLK (match_dup 0) (match_dup 1)))
8666 (clobber (reg:CC CC_REGNUM))])]
8668 operands[2] = GEN_INT (GET_MODE_SIZE (GET_MODE (operands[0])));
8669 operands[0] = adjust_address (operands[0], BLKmode, 0);
8670 operands[1] = adjust_address (operands[1], BLKmode, 0);
8675 [(set (match_operand:BLK 0 "memory_operand" "")
8676 (xor:BLK (match_dup 0)
8677 (match_operand:BLK 1 "memory_operand" "")))
8678 (use (match_operand 2 "const_int_operand" ""))
8679 (clobber (reg:CC CC_REGNUM))])
8681 [(set (match_operand:BLK 3 "memory_operand" "")
8682 (xor:BLK (match_dup 3)
8683 (match_operand:BLK 4 "memory_operand" "")))
8684 (use (match_operand 5 "const_int_operand" ""))
8685 (clobber (reg:CC CC_REGNUM))])]
8686 "s390_offset_p (operands[0], operands[3], operands[2])
8687 && s390_offset_p (operands[1], operands[4], operands[2])
8688 && !s390_overlap_p (operands[0], operands[1],
8689 INTVAL (operands[2]) + INTVAL (operands[5]))
8690 && INTVAL (operands[2]) + INTVAL (operands[5]) <= 256"
8692 [(set (match_dup 6) (xor:BLK (match_dup 6) (match_dup 7)))
8694 (clobber (reg:CC CC_REGNUM))])]
8695 "operands[6] = gen_rtx_MEM (BLKmode, XEXP (operands[0], 0));
8696 operands[7] = gen_rtx_MEM (BLKmode, XEXP (operands[1], 0));
8697 operands[8] = GEN_INT (INTVAL (operands[2]) + INTVAL (operands[5]));")
8700 ; Block xor (XC) patterns with src == dest.
8703 (define_insn "*xc_zero"
8704 [(set (match_operand:BLK 0 "memory_operand" "=Q")
8706 (use (match_operand 1 "const_int_operand" "n"))
8707 (clobber (reg:CC CC_REGNUM))]
8708 "INTVAL (operands[1]) >= 1 && INTVAL (operands[1]) <= 256"
8709 "xc\t%O0(%1,%R0),%S0"
8710 [(set_attr "op_type" "SS")
8711 (set_attr "z196prop" "z196_cracked")])
8715 [(set (match_operand:BLK 0 "memory_operand" "")
8717 (use (match_operand 1 "const_int_operand" ""))
8718 (clobber (reg:CC CC_REGNUM))])
8720 [(set (match_operand:BLK 2 "memory_operand" "")
8722 (use (match_operand 3 "const_int_operand" ""))
8723 (clobber (reg:CC CC_REGNUM))])]
8724 "s390_offset_p (operands[0], operands[2], operands[1])
8725 && INTVAL (operands[1]) + INTVAL (operands[3]) <= 256"
8727 [(set (match_dup 4) (const_int 0))
8729 (clobber (reg:CC CC_REGNUM))])]
8730 "operands[4] = gen_rtx_MEM (BLKmode, XEXP (operands[0], 0));
8731 operands[5] = GEN_INT (INTVAL (operands[1]) + INTVAL (operands[3]));")
8734 ;- Nxor instructions.
8738 (define_insn "*nxor<GPR:mode>_cc"
8739 [(set (reg CC_REGNUM)
8741 (not:GPR (xor:GPR (match_operand:GPR 1 "register_operand" "d")
8742 (match_operand:GPR 2 "register_operand" "d")))
8744 (set (match_operand:GPR 0 "register_operand" "=d")
8745 (xor:GPR (not:GPR (match_dup 1))
8747 "TARGET_Z15 && s390_match_ccmode(insn, CCTmode)"
8748 "nx<GPR:g>rk\t%0,%1,%2"
8749 [(set_attr "op_type" "RRF")])
8752 (define_insn "*nxor<mode>_cconly"
8753 [(set (reg CC_REGNUM)
8755 (not:GPR (xor:GPR (match_operand:GPR 1 "register_operand" "d")
8756 (match_operand:GPR 2 "register_operand" "d")))
8758 (clobber (match_scratch:GPR 0 "=d"))]
8759 "TARGET_Z15 && s390_match_ccmode(insn, CCTmode)"
8760 "nx<GPR:g>rk\t%0,%1,%2"
8761 [(set_attr "op_type" "RRF")])
8764 (define_insn "*nxor<mode>"
8765 [(set (match_operand:GPR 0 "register_operand" "=d")
8766 (not:GPR (xor:GPR (match_operand:GPR 1 "register_operand" "d")
8767 (match_operand:GPR 2 "register_operand" "d"))))
8768 (clobber (reg:CC CC_REGNUM))]
8770 "nx<GPR:g>rk\t%0,%1,%2"
8771 [(set_attr "op_type" "RRF")])
8774 ;;- Negate instructions.
8778 ; neg(di|si)2 instruction pattern(s).
8781 (define_expand "neg<mode>2"
8783 [(set (match_operand:DSI 0 "register_operand" "=d")
8784 (neg:DSI (match_operand:DSI 1 "register_operand" "d")))
8785 (clobber (reg:CC CC_REGNUM))])]
8789 (define_insn "*negdi2_sign_cc"
8790 [(set (reg CC_REGNUM)
8791 (compare (neg:DI (ashiftrt:DI (ashift:DI (subreg:DI
8792 (match_operand:SI 1 "register_operand" "d") 0)
8793 (const_int 32)) (const_int 32)))
8795 (set (match_operand:DI 0 "register_operand" "=d")
8796 (neg:DI (sign_extend:DI (match_dup 1))))]
8797 "TARGET_ZARCH && s390_match_ccmode (insn, CCAmode)"
8799 [(set_attr "op_type" "RRE")
8800 (set_attr "z10prop" "z10_c")])
8802 (define_insn "*negdi2_sign"
8803 [(set (match_operand:DI 0 "register_operand" "=d")
8804 (neg:DI (sign_extend:DI (match_operand:SI 1 "register_operand" "d"))))
8805 (clobber (reg:CC CC_REGNUM))]
8808 [(set_attr "op_type" "RRE")
8809 (set_attr "z10prop" "z10_c")])
8812 (define_insn "*neg<mode>2_cc"
8813 [(set (reg CC_REGNUM)
8814 (compare (neg:GPR (match_operand:GPR 1 "register_operand" "d"))
8816 (set (match_operand:GPR 0 "register_operand" "=d")
8817 (neg:GPR (match_dup 1)))]
8818 "s390_match_ccmode (insn, CCAmode)"
8820 [(set_attr "op_type" "RR<E>")
8821 (set_attr "z10prop" "z10_super_c_E1")])
8824 (define_insn "*neg<mode>2_cconly"
8825 [(set (reg CC_REGNUM)
8826 (compare (neg:GPR (match_operand:GPR 1 "register_operand" "d"))
8828 (clobber (match_scratch:GPR 0 "=d"))]
8829 "s390_match_ccmode (insn, CCAmode)"
8831 [(set_attr "op_type" "RR<E>")
8832 (set_attr "z10prop" "z10_super_c_E1")])
8835 (define_insn "*neg<mode>2"
8836 [(set (match_operand:GPR 0 "register_operand" "=d")
8837 (neg:GPR (match_operand:GPR 1 "register_operand" "d")))
8838 (clobber (reg:CC CC_REGNUM))]
8841 [(set_attr "op_type" "RR<E>")
8842 (set_attr "z10prop" "z10_super_c_E1")])
8844 (define_insn "*negdi2_31"
8845 [(set (match_operand:DI 0 "register_operand" "=d")
8846 (neg:DI (match_operand:DI 1 "register_operand" "d")))
8847 (clobber (reg:CC CC_REGNUM))]
8851 ; Split a DImode NEG on 31bit into 2 SImode NEGs
8853 ; Doing the twos complement separately on the SImode parts does an
8854 ; unwanted +1 on the high part which needs to be subtracted afterwards
8855 ; ... unless the +1 on the low part created an overflow.
8858 [(set (match_operand:DI 0 "register_operand" "")
8859 (neg:DI (match_operand:DI 1 "register_operand" "")))
8860 (clobber (reg:CC CC_REGNUM))]
8863 && ((REG_P (operands[0]) && REG_P (operands[1])
8864 && REGNO (operands[0]) == REGNO (operands[1]))
8865 || s390_split_ok_p (operands[0], operands[1], DImode, 0))"
8867 [(set (match_dup 2) (neg:SI (match_dup 3)))
8868 (clobber (reg:CC CC_REGNUM))])
8870 [(set (reg:CCAP CC_REGNUM)
8871 (compare:CCAP (neg:SI (match_dup 5)) (const_int 0)))
8872 (set (match_dup 4) (neg:SI (match_dup 5)))])
8874 (if_then_else (ne (reg:CCAP CC_REGNUM) (const_int 0))
8876 (label_ref (match_dup 6))))
8878 [(set (match_dup 2) (plus:SI (match_dup 2) (const_int -1)))
8879 (clobber (reg:CC CC_REGNUM))])
8881 "operands[2] = operand_subword (operands[0], 0, 0, DImode);
8882 operands[3] = operand_subword (operands[1], 0, 0, DImode);
8883 operands[4] = operand_subword (operands[0], 1, 0, DImode);
8884 operands[5] = operand_subword (operands[1], 1, 0, DImode);
8885 operands[6] = gen_label_rtx ();")
8887 ; Like above but first make a copy of the low part of the src operand
8888 ; since it might overlap with the high part of the destination.
8891 [(set (match_operand:DI 0 "register_operand" "")
8892 (neg:DI (match_operand:DI 1 "register_operand" "")))
8893 (clobber (reg:CC CC_REGNUM))]
8895 && s390_split_ok_p (operands[0], operands[1], DImode, 1)
8896 && reload_completed"
8897 [; Make a backup of op5 first
8898 (set (match_dup 4) (match_dup 5))
8899 ; Setting op2 here might clobber op5
8901 [(set (match_dup 2) (neg:SI (match_dup 3)))
8902 (clobber (reg:CC CC_REGNUM))])
8904 [(set (reg:CCAP CC_REGNUM)
8905 (compare:CCAP (neg:SI (match_dup 4)) (const_int 0)))
8906 (set (match_dup 4) (neg:SI (match_dup 4)))])
8908 (if_then_else (ne (reg:CCAP CC_REGNUM) (const_int 0))
8910 (label_ref (match_dup 6))))
8912 [(set (match_dup 2) (plus:SI (match_dup 2) (const_int -1)))
8913 (clobber (reg:CC CC_REGNUM))])
8915 "operands[2] = operand_subword (operands[0], 0, 0, DImode);
8916 operands[3] = operand_subword (operands[1], 0, 0, DImode);
8917 operands[4] = operand_subword (operands[0], 1, 0, DImode);
8918 operands[5] = operand_subword (operands[1], 1, 0, DImode);
8919 operands[6] = gen_label_rtx ();")
8922 ; neg(tf|df|sf)2 instruction pattern(s).
8925 (define_expand "neg<mode>2<tf_fpr>"
8927 [(set (match_operand:BFP 0 "register_operand")
8928 (neg:BFP (match_operand:BFP 1 "register_operand")))
8929 (clobber (reg:CC CC_REGNUM))])]
8930 "TARGET_HARD_FLOAT")
8932 ; lcxbr, lcdbr, lcebr
8933 (define_insn "*neg<mode>2_cc"
8934 [(set (reg CC_REGNUM)
8935 (compare (neg:BFP (match_operand:BFP 1 "register_operand" "f"))
8936 (match_operand:BFP 2 "const0_operand" "")))
8937 (set (match_operand:BFP 0 "register_operand" "=f")
8938 (neg:BFP (match_dup 1)))]
8939 "s390_match_ccmode (insn, CCSmode) && TARGET_HARD_FLOAT"
8941 [(set_attr "op_type" "RRE")
8942 (set_attr "type" "fsimp<type>")])
8944 ; lcxbr, lcdbr, lcebr
8945 (define_insn "*neg<mode>2_cconly"
8946 [(set (reg CC_REGNUM)
8947 (compare (neg:BFP (match_operand:BFP 1 "register_operand" "f"))
8948 (match_operand:BFP 2 "const0_operand" "")))
8949 (clobber (match_scratch:BFP 0 "=f"))]
8950 "s390_match_ccmode (insn, CCSmode) && TARGET_HARD_FLOAT"
8952 [(set_attr "op_type" "RRE")
8953 (set_attr "type" "fsimp<type>")])
8956 (define_insn "*neg<mode>2_nocc"
8957 [(set (match_operand:FP 0 "register_operand" "=f")
8958 (neg:FP (match_operand:FP 1 "register_operand" "<fT0>")))]
8961 [(set_attr "op_type" "RRE")
8962 (set_attr "type" "fsimp<type>")])
8964 ; lcxbr, lcdbr, lcebr
8965 ; FIXME: wflcdb does not clobber cc
8966 ; FIXME: Does wflcdb ever match here?
8967 (define_insn "*neg<mode>2"
8968 [(set (match_operand:BFP 0 "register_operand" "=f,v,v")
8969 (neg:BFP (match_operand:BFP 1 "register_operand" "f,v,v")))
8970 (clobber (reg:CC CC_REGNUM))]
8976 [(set_attr "op_type" "RRE,VRR,VRR")
8977 (set_attr "cpu_facility" "*,vx,vxe")
8978 (set_attr "type" "fsimp<type>,*,*")
8979 (set_attr "enabled" "*,<DF>,<SF>")])
8983 ;;- Absolute value instructions.
8987 ; abs(di|si)2 instruction pattern(s).
8990 (define_insn "*absdi2_sign_cc"
8991 [(set (reg CC_REGNUM)
8992 (compare (abs:DI (ashiftrt:DI (ashift:DI (subreg:DI
8993 (match_operand:SI 1 "register_operand" "d") 0)
8994 (const_int 32)) (const_int 32)))
8996 (set (match_operand:DI 0 "register_operand" "=d")
8997 (abs:DI (sign_extend:DI (match_dup 1))))]
8998 "TARGET_ZARCH && s390_match_ccmode (insn, CCAmode)"
9000 [(set_attr "op_type" "RRE")
9001 (set_attr "z10prop" "z10_c")])
9003 (define_insn "*absdi2_sign"
9004 [(set (match_operand:DI 0 "register_operand" "=d")
9005 (abs:DI (sign_extend:DI (match_operand:SI 1 "register_operand" "d"))))
9006 (clobber (reg:CC CC_REGNUM))]
9009 [(set_attr "op_type" "RRE")
9010 (set_attr "z10prop" "z10_c")])
9013 (define_insn "*abs<mode>2_cc"
9014 [(set (reg CC_REGNUM)
9015 (compare (abs:GPR (match_operand:DI 1 "register_operand" "d"))
9017 (set (match_operand:GPR 0 "register_operand" "=d")
9018 (abs:GPR (match_dup 1)))]
9019 "s390_match_ccmode (insn, CCAmode)"
9021 [(set_attr "op_type" "RR<E>")
9022 (set_attr "z10prop" "z10_c")])
9025 (define_insn "*abs<mode>2_cconly"
9026 [(set (reg CC_REGNUM)
9027 (compare (abs:GPR (match_operand:GPR 1 "register_operand" "d"))
9029 (clobber (match_scratch:GPR 0 "=d"))]
9030 "s390_match_ccmode (insn, CCAmode)"
9032 [(set_attr "op_type" "RR<E>")
9033 (set_attr "z10prop" "z10_c")])
9036 (define_insn "abs<mode>2"
9037 [(set (match_operand:GPR 0 "register_operand" "=d")
9038 (abs:GPR (match_operand:GPR 1 "register_operand" "d")))
9039 (clobber (reg:CC CC_REGNUM))]
9042 [(set_attr "op_type" "RR<E>")
9043 (set_attr "z10prop" "z10_c")])
9046 ; abs(tf|df|sf)2 instruction pattern(s).
9049 (define_expand "abs<mode>2<tf_fpr>"
9051 [(set (match_operand:BFP 0 "register_operand" "=f")
9052 (abs:BFP (match_operand:BFP 1 "register_operand" "f")))
9053 (clobber (reg:CC CC_REGNUM))])]
9057 ; lpxbr, lpdbr, lpebr
9058 (define_insn "*abs<mode>2_cc"
9059 [(set (reg CC_REGNUM)
9060 (compare (abs:BFP (match_operand:BFP 1 "register_operand" "f"))
9061 (match_operand:BFP 2 "const0_operand" "")))
9062 (set (match_operand:BFP 0 "register_operand" "=f")
9063 (abs:BFP (match_dup 1)))]
9064 "s390_match_ccmode (insn, CCSmode) && TARGET_HARD_FLOAT"
9066 [(set_attr "op_type" "RRE")
9067 (set_attr "type" "fsimp<type>")])
9069 ; lpxbr, lpdbr, lpebr
9070 (define_insn "*abs<mode>2_cconly"
9071 [(set (reg CC_REGNUM)
9072 (compare (abs:BFP (match_operand:BFP 1 "register_operand" "f"))
9073 (match_operand:BFP 2 "const0_operand" "")))
9074 (clobber (match_scratch:BFP 0 "=f"))]
9075 "s390_match_ccmode (insn, CCSmode) && TARGET_HARD_FLOAT"
9077 [(set_attr "op_type" "RRE")
9078 (set_attr "type" "fsimp<type>")])
9081 (define_insn "*abs<mode>2_nocc"
9082 [(set (match_operand:FP 0 "register_operand" "=f")
9083 (abs:FP (match_operand:FP 1 "register_operand" "<fT0>")))]
9086 [(set_attr "op_type" "RRE")
9087 (set_attr "type" "fsimp<type>")])
9089 ; lpxbr, lpdbr, lpebr
9090 ; FIXME: wflpdb does not clobber cc
9091 (define_insn "*abs<mode>2"
9092 [(set (match_operand:BFP 0 "register_operand" "=f,v")
9093 (abs:BFP (match_operand:BFP 1 "register_operand" "f,v")))
9094 (clobber (reg:CC CC_REGNUM))]
9099 [(set_attr "op_type" "RRE,VRR")
9100 (set_attr "cpu_facility" "*,vx")
9101 (set_attr "type" "fsimp<type>,*")
9102 (set_attr "enabled" "*,<DFDI>")])
9106 ;;- Negated absolute value instructions
9113 (define_insn "*negabsdi2_sign_cc"
9114 [(set (reg CC_REGNUM)
9115 (compare (neg:DI (abs:DI (ashiftrt:DI (ashift:DI (subreg:DI
9116 (match_operand:SI 1 "register_operand" "d") 0)
9117 (const_int 32)) (const_int 32))))
9119 (set (match_operand:DI 0 "register_operand" "=d")
9120 (neg:DI (abs:DI (sign_extend:DI (match_dup 1)))))]
9121 "TARGET_ZARCH && s390_match_ccmode (insn, CCAmode)"
9123 [(set_attr "op_type" "RRE")
9124 (set_attr "z10prop" "z10_c")])
9126 (define_insn "*negabsdi2_sign"
9127 [(set (match_operand:DI 0 "register_operand" "=d")
9128 (neg:DI (abs:DI (sign_extend:DI
9129 (match_operand:SI 1 "register_operand" "d")))))
9130 (clobber (reg:CC CC_REGNUM))]
9133 [(set_attr "op_type" "RRE")
9134 (set_attr "z10prop" "z10_c")])
9137 (define_insn "*negabs<mode>2_cc"
9138 [(set (reg CC_REGNUM)
9139 (compare (neg:GPR (abs:GPR (match_operand:GPR 1 "register_operand" "d")))
9141 (set (match_operand:GPR 0 "register_operand" "=d")
9142 (neg:GPR (abs:GPR (match_dup 1))))]
9143 "s390_match_ccmode (insn, CCAmode)"
9145 [(set_attr "op_type" "RR<E>")
9146 (set_attr "z10prop" "z10_c")])
9149 (define_insn "*negabs<mode>2_cconly"
9150 [(set (reg CC_REGNUM)
9151 (compare (neg:GPR (abs:GPR (match_operand:GPR 1 "register_operand" "d")))
9153 (clobber (match_scratch:GPR 0 "=d"))]
9154 "s390_match_ccmode (insn, CCAmode)"
9156 [(set_attr "op_type" "RR<E>")
9157 (set_attr "z10prop" "z10_c")])
9160 (define_insn "*negabs<mode>2"
9161 [(set (match_operand:GPR 0 "register_operand" "=d")
9162 (neg:GPR (abs:GPR (match_operand:GPR 1 "register_operand" "d"))))
9163 (clobber (reg:CC CC_REGNUM))]
9166 [(set_attr "op_type" "RR<E>")
9167 (set_attr "z10prop" "z10_c")])
9173 ; lnxbr, lndbr, lnebr
9174 (define_insn "*negabs<mode>2_cc"
9175 [(set (reg CC_REGNUM)
9176 (compare (neg:BFP (abs:BFP (match_operand:BFP 1 "register_operand" "f")))
9177 (match_operand:BFP 2 "const0_operand" "")))
9178 (set (match_operand:BFP 0 "register_operand" "=f")
9179 (neg:BFP (abs:BFP (match_dup 1))))]
9180 "s390_match_ccmode (insn, CCSmode) && TARGET_HARD_FLOAT"
9182 [(set_attr "op_type" "RRE")
9183 (set_attr "type" "fsimp<type>")])
9185 ; lnxbr, lndbr, lnebr
9186 (define_insn "*negabs<mode>2_cconly"
9187 [(set (reg CC_REGNUM)
9188 (compare (neg:BFP (abs:BFP (match_operand:BFP 1 "register_operand" "f")))
9189 (match_operand:BFP 2 "const0_operand" "")))
9190 (clobber (match_scratch:BFP 0 "=f"))]
9191 "s390_match_ccmode (insn, CCSmode) && TARGET_HARD_FLOAT"
9193 [(set_attr "op_type" "RRE")
9194 (set_attr "type" "fsimp<type>")])
9197 (define_insn "*negabs<mode>2_nocc"
9198 [(set (match_operand:FP 0 "register_operand" "=f")
9199 (neg:FP (abs:FP (match_operand:FP 1 "register_operand" "<fT0>"))))]
9202 [(set_attr "op_type" "RRE")
9203 (set_attr "type" "fsimp<type>")])
9205 ; lnxbr, lndbr, lnebr
9206 ; FIXME: wflndb does not clobber cc
9207 (define_insn "*negabs<mode>2"
9208 [(set (match_operand:BFP 0 "register_operand" "=f,v")
9209 (neg:BFP (abs:BFP (match_operand:BFP 1 "register_operand" "f,v"))))
9210 (clobber (reg:CC CC_REGNUM))]
9215 [(set_attr "op_type" "RRE,VRR")
9216 (set_attr "cpu_facility" "*,vx")
9217 (set_attr "type" "fsimp<type>,*")
9218 (set_attr "enabled" "*,<DFDI>")])
9221 ;;- Square root instructions.
9225 ; sqrt(df|sf)2 instruction pattern(s).
9228 ; sqxbr, sqdbr, sqebr, sqdb, sqeb
9229 (define_insn "sqrt<mode>2<tf_fpr>"
9230 [(set (match_operand:BFP 0 "register_operand" "=f,f,v")
9231 (sqrt:BFP (match_operand:BFP 1 "general_operand" "f,R,v")))]
9237 [(set_attr "op_type" "RRE,RXE,VRR")
9238 (set_attr "type" "fsqrt<type>")
9239 (set_attr "cpu_facility" "*,*,vx")
9240 (set_attr "enabled" "*,<DSF>,<DFDI>")])
9244 ;;- One complement instructions.
9248 ; one_cmpl(di|si|hi|qi)2 instruction pattern(s).
9251 (define_expand "one_cmpl<mode>2"
9253 [(set (match_operand:INT 0 "register_operand" "")
9254 (xor:INT (match_operand:INT 1 "register_operand" "")
9256 (clobber (reg:CC CC_REGNUM))])]
9262 ;; Find leftmost bit instructions.
9265 (define_expand "clzdi2"
9266 [(set (match_operand:DI 0 "register_operand" "=d")
9267 (clz:DI (match_operand:DI 1 "register_operand" "d")))]
9268 "TARGET_EXTIMM && TARGET_ZARCH"
9272 rtx wide_reg = gen_reg_rtx (TImode);
9273 rtx msb = gen_rtx_CONST_INT (DImode, HOST_WIDE_INT_1U << 63);
9275 clz_equal = gen_rtx_CLZ (DImode, operands[1]);
9277 emit_insn (gen_clztidi2 (wide_reg, operands[1], msb));
9279 insn = emit_move_insn (operands[0], gen_highpart (DImode, wide_reg));
9280 set_unique_reg_note (insn, REG_EQUAL, clz_equal);
9285 ; CLZ result is in hard reg op0 - this is the high part of the target operand
9286 ; The source with the left-most one bit cleared is in hard reg op0 + 1 - the low part
9287 (define_insn "clztidi2"
9288 [(set (match_operand:TI 0 "register_operand" "=d")
9290 (ashift:TI (zero_extend:TI (clz:DI (match_operand:DI 1 "register_operand" "d")))
9293 (xor:DI (match_dup 1)
9294 (lshiftrt (match_operand:DI 2 "const_int_operand" "")
9295 (subreg:SI (clz:DI (match_dup 1)) 4))))))
9296 (clobber (reg:CC CC_REGNUM))]
9297 "UINTVAL (operands[2]) == HOST_WIDE_INT_1U << 63
9298 && TARGET_EXTIMM && TARGET_ZARCH"
9300 [(set_attr "op_type" "RRE")])
9304 ;;- Rotate instructions.
9308 ; rotl(di|si)3 instruction pattern(s).
9311 (define_expand "rotl<mode>3"
9312 [(set (match_operand:GPR 0 "register_operand" "")
9313 (rotate:GPR (match_operand:GPR 1 "register_operand" "")
9314 (match_operand:QI 2 "shift_count_operand" "")))]
9319 (define_insn "*rotl<mode>3"
9320 [(set (match_operand:GPR 0 "register_operand" "=d")
9321 (rotate:GPR (match_operand:GPR 1 "register_operand" "d")
9322 (match_operand:QI 2 "shift_count_operand" "jsc")))]
9325 [(set_attr "op_type" "RSE")
9326 (set_attr "atype" "reg")
9327 (set_attr "z10prop" "z10_super_E1")])
9331 ;;- Shift instructions.
9335 ; (ashl|lshr)(di|si)3 instruction pattern(s).
9336 ; Left shifts and logical right shifts
9338 (define_expand "<shift><mode>3"
9339 [(set (match_operand:DSI 0 "register_operand" "")
9340 (SHIFT:DSI (match_operand:DSI 1 "register_operand" "")
9341 (match_operand:QI 2 "shift_count_operand" "")))]
9345 ; ESA 64 bit register pair shift with reg or imm shift count
9347 (define_insn "*<shift>di3_31"
9348 [(set (match_operand:DI 0 "register_operand" "=d")
9349 (SHIFT:DI (match_operand:DI 1 "register_operand" "0")
9350 (match_operand:QI 2 "shift_count_operand" "jsc")))]
9353 [(set_attr "op_type" "RS")
9354 (set_attr "atype" "reg")
9355 (set_attr "z196prop" "z196_cracked")])
9358 ; 64 bit register shift with reg or imm shift count
9359 ; sll, srl, sllg, srlg, sllk, srlk
9360 (define_insn "*<shift><mode>3"
9361 [(set (match_operand:GPR 0 "register_operand" "=d, d")
9362 (SHIFT:GPR (match_operand:GPR 1 "register_operand" "<d0>, d")
9363 (match_operand:QI 2 "shift_count_operand" "jsc,jsc")))]
9366 s<lr>l<g>\t%0,<1>%Y2
9367 s<lr>l<gk>\t%0,%1,%Y2"
9368 [(set_attr "op_type" "RS<E>,RSY")
9369 (set_attr "atype" "reg,reg")
9370 (set_attr "cpu_facility" "*,z196")
9371 (set_attr "z10prop" "z10_super_E1,*")])
9375 ; ashr(di|si)3 instruction pattern(s).
9376 ; Arithmetic right shifts
9378 (define_expand "ashr<mode>3"
9380 [(set (match_operand:DSI 0 "register_operand" "")
9381 (ashiftrt:DSI (match_operand:DSI 1 "register_operand" "")
9382 (match_operand:QI 2 "shift_count_operand" "")))
9383 (clobber (reg:CC CC_REGNUM))])]
9387 (define_insn "*ashrdi3_31<setcc><cconly>"
9388 [(set (match_operand:DI 0 "register_operand" "=d")
9389 (ashiftrt:DI (match_operand:DI 1 "register_operand" "0")
9390 (match_operand:QI 2 "shift_count_operand" "jsc")))
9391 (clobber (reg:CC CC_REGNUM))]
9394 [(set_attr "op_type" "RS")
9395 (set_attr "atype" "reg")])
9399 (define_insn "*ashr<mode>3<setcc><cconly>"
9400 [(set (match_operand:GPR 0 "register_operand" "=d, d")
9401 (ashiftrt:GPR (match_operand:GPR 1 "register_operand" "<d0>, d")
9402 (match_operand:QI 2 "shift_count_operand" "jsc,jsc")))
9403 (clobber (reg:CC CC_REGNUM))]
9408 [(set_attr "op_type" "RS<E>,RSY")
9409 (set_attr "atype" "reg")
9410 (set_attr "cpu_facility" "*,z196")
9411 (set_attr "z10prop" "z10_super_E1,*")])
9415 ;; Branch instruction patterns.
9418 (define_expand "cbranch<mode>4"
9420 (if_then_else (match_operator 0 "comparison_operator"
9421 [(match_operand:GPR 1 "register_operand" "")
9422 (match_operand:GPR 2 "general_operand" "")])
9423 (label_ref (match_operand 3 "" ""))
9426 "s390_emit_jump (operands[3],
9427 s390_emit_compare (GET_CODE (operands[0]), operands[1], operands[2]));
9430 (define_expand "cbranch<mode>4"
9432 (if_then_else (match_operator 0 "comparison_operator"
9433 [(match_operand:FP_ANYTF 1 "register_operand" "")
9434 (match_operand:FP_ANYTF 2 "general_operand" "")])
9435 (label_ref (match_operand 3 "" ""))
9438 "s390_emit_jump (operands[3],
9439 s390_emit_compare (GET_CODE (operands[0]), operands[1], operands[2]));
9442 (define_expand "cbranchcc4"
9444 (if_then_else (match_operator 0 "s390_comparison"
9445 [(match_operand 1 "cc_reg_operand" "")
9446 (match_operand 2 "const_int_operand" "")])
9447 (label_ref (match_operand 3 "" ""))
9454 ;;- Conditional jump instructions.
9457 (define_insn "*cjump_64"
9460 (match_operator 1 "s390_comparison" [(reg CC_REGNUM)
9461 (match_operand 2 "const_int_operand" "")])
9462 (label_ref (match_operand 0 "" ""))
9466 if (get_attr_length (insn) == 4)
9469 return "jg%C1\t%l0";
9471 [(set_attr "op_type" "RI")
9472 (set_attr "type" "branch")
9473 (set (attr "length")
9474 (if_then_else (lt (abs (minus (pc) (match_dup 0))) (const_int 60000))
9475 (const_int 4) (const_int 6)))])
9477 (define_insn "*cjump_long"
9480 (match_operator 1 "s390_comparison" [(reg CC_REGNUM) (const_int 0)])
9481 (match_operand 0 "address_operand" "ZQZR")
9483 "!TARGET_INDIRECT_BRANCH_NOBP_JUMP"
9485 if (get_attr_op_type (insn) == OP_TYPE_RR)
9490 [(set (attr "op_type")
9491 (if_then_else (match_operand 0 "register_operand" "")
9492 (const_string "RR") (const_string "RX")))
9493 (set (attr "mnemonic")
9494 (if_then_else (match_operand 0 "register_operand" "")
9495 (const_string "bcr") (const_string "bc")))
9496 (set_attr "type" "branch")
9497 (set_attr "atype" "agen")])
9499 ;; A conditional return instruction.
9500 (define_insn "*c<code>"
9503 (match_operator 0 "s390_comparison" [(reg CC_REGNUM) (const_int 0)])
9506 "s390_can_use_<code>_insn ()"
9508 if (TARGET_INDIRECT_BRANCH_NOBP_RET)
9510 s390_indirect_branch_via_thunk (RETURN_REGNUM,
9513 s390_indirect_branch_type_return);
9517 return "b%C0r\t%%r14";
9519 [(set (attr "op_type")
9520 (if_then_else (match_test "TARGET_INDIRECT_BRANCH_NOBP_RET")
9521 (const_string "RIL")
9522 (const_string "RR")))
9523 (set (attr "mnemonic")
9524 (if_then_else (match_test "TARGET_INDIRECT_BRANCH_NOBP_RET")
9525 (const_string "brcl")
9526 (const_string "bcr")))
9527 (set_attr "type" "jsr")
9528 (set_attr "atype" "agen")])
9531 ;;- Negated conditional jump instructions.
9534 (define_insn "*icjump_64"
9537 (match_operator 1 "s390_comparison" [(reg CC_REGNUM)
9538 (match_operand 2 "const_int_operand" "")])
9540 (label_ref (match_operand 0 "" ""))))]
9543 if (get_attr_length (insn) == 4)
9546 return "jg%D1\t%l0";
9548 [(set_attr "op_type" "RI")
9549 (set_attr "type" "branch")
9550 (set (attr "length")
9551 (if_then_else (lt (abs (minus (pc) (match_dup 0))) (const_int 60000))
9552 (const_int 4) (const_int 6)))])
9554 (define_insn "*icjump_long"
9557 (match_operator 1 "s390_comparison" [(reg CC_REGNUM) (const_int 0)])
9559 (match_operand 0 "address_operand" "ZQZR")))]
9560 "!TARGET_INDIRECT_BRANCH_NOBP_JUMP"
9562 if (get_attr_op_type (insn) == OP_TYPE_RR)
9567 [(set (attr "op_type")
9568 (if_then_else (match_operand 0 "register_operand" "")
9569 (const_string "RR") (const_string "RX")))
9570 (set (attr "mnemonic")
9571 (if_then_else (match_operand 0 "register_operand" "")
9572 (const_string "bcr") (const_string "bc")))
9573 (set_attr "type" "branch")
9574 (set_attr "atype" "agen")])
9577 ;;- Trap instructions.
9581 [(trap_if (const_int 1) (const_int 0))]
9584 [(set_attr "op_type" "RI")
9585 (set_attr "type" "branch")])
9587 (define_expand "ctrap<mode>4"
9588 [(trap_if (match_operator 0 "comparison_operator"
9589 [(match_operand:GPR 1 "register_operand" "")
9590 (match_operand:GPR 2 "general_operand" "")])
9591 (match_operand 3 "const0_operand" ""))]
9594 rtx cond = s390_emit_compare (GET_CODE (operands[0]),
9595 operands[1], operands[2]);
9596 emit_insn (gen_condtrap (cond, XEXP (cond, 0)));
9600 (define_expand "ctrap<mode>4"
9601 [(trap_if (match_operator 0 "comparison_operator"
9602 [(match_operand:FP 1 "register_operand" "")
9603 (match_operand:FP 2 "general_operand" "")])
9604 (match_operand 3 "const0_operand" ""))]
9607 rtx cond = s390_emit_compare (GET_CODE (operands[0]),
9608 operands[1], operands[2]);
9609 emit_insn (gen_condtrap (cond, XEXP (cond, 0)));
9613 (define_insn "condtrap"
9614 [(trap_if (match_operator 0 "s390_comparison"
9615 [(match_operand 1 "cc_reg_operand" "c")
9620 [(set_attr "op_type" "RI")
9621 (set_attr "type" "branch")])
9623 ; crt, cgrt, cit, cgit
9624 (define_insn "*cmp_and_trap_signed_int<mode>"
9625 [(trap_if (match_operator 0 "s390_signed_integer_comparison"
9626 [(match_operand:GPR 1 "register_operand" "d,d")
9627 (match_operand:GPR 2 "nonmemory_operand" "d,K")])
9633 [(set_attr "op_type" "RRF,RIE")
9634 (set_attr "type" "branch")
9635 (set_attr "z10prop" "z10_super_c,z10_super")])
9637 ; clrt, clgrt, clfit, clgit, clt, clgt
9638 (define_insn "*cmp_and_trap_unsigned_int<mode>"
9639 [(trap_if (match_operator 0 "s390_unsigned_integer_comparison"
9640 [(match_operand:GPR 1 "register_operand" "d,d,d")
9641 (match_operand:GPR 2 "general_operand" "d,D,S")])
9648 [(set_attr "op_type" "RRF,RIE,RSY")
9649 (set_attr "type" "branch")
9650 (set_attr "z10prop" "z10_super_c,z10_super,*")
9651 (set_attr "cpu_facility" "z10,z10,zEC12")])
9654 (define_insn "*load_and_trap<mode>"
9655 [(trap_if (eq (match_operand:GPR 0 "memory_operand" "T")
9658 (set (match_operand:GPR 1 "register_operand" "=d")
9662 [(set_attr "op_type" "RXY")])
9666 ;;- Loop instructions.
9668 ;; This is all complicated by the fact that since this is a jump insn
9669 ;; we must handle our own output reloads.
9673 ; This splitter will be matched by combine and has to add the 2 moves
9674 ; necessary to load the compare and the increment values into a
9675 ; register pair as needed by brxle.
9677 (define_insn_and_split "*brx_stage1_<GPR:mode>"
9680 (match_operator 6 "s390_brx_operator"
9681 [(plus:GPR (match_operand:GPR 1 "register_operand" "")
9682 (match_operand:GPR 2 "general_operand" ""))
9683 (match_operand:GPR 3 "register_operand" "")])
9684 (label_ref (match_operand 0 "" ""))
9686 (set (match_operand:GPR 4 "nonimmediate_operand" "")
9687 (plus:GPR (match_dup 1) (match_dup 2)))
9688 (clobber (match_scratch:GPR 5 ""))]
9691 "!reload_completed && !reload_in_progress"
9692 [(set (match_dup 7) (match_dup 2)) ; the increment
9693 (set (match_dup 8) (match_dup 3)) ; the comparison value
9694 (parallel [(set (pc)
9697 [(plus:GPR (match_dup 1) (match_dup 7))
9699 (label_ref (match_dup 0))
9702 (plus:GPR (match_dup 1) (match_dup 7)))
9703 (clobber (match_dup 5))
9704 (clobber (reg:CC CC_REGNUM))])]
9706 rtx dreg = gen_reg_rtx (word_mode == DImode ? TImode : DImode);
9707 operands[7] = gen_lowpart (<GPR:MODE>mode,
9708 gen_highpart (word_mode, dreg));
9709 operands[8] = gen_lowpart (<GPR:MODE>mode,
9710 gen_lowpart (word_mode, dreg));
9715 (define_insn_and_split "*brxg_64bit"
9718 (match_operator 5 "s390_brx_operator"
9719 [(plus:DI (match_operand:DI 1 "register_operand" "d,d,d")
9720 (subreg:DI (match_operand:TI 2 "register_operand" "d,d,d") 0))
9721 (subreg:DI (match_dup 2) 8)])
9722 (label_ref (match_operand 0 "" ""))
9724 (set (match_operand:DI 3 "nonimmediate_operand" "=1,?X,?X")
9725 (plus:DI (match_dup 1)
9726 (subreg:DI (match_dup 2) 0)))
9727 (clobber (match_scratch:DI 4 "=X,&1,&?d"))
9728 (clobber (reg:CC CC_REGNUM))]
9731 if (which_alternative != 0)
9733 else if (get_attr_length (insn) == 6)
9734 return "brx%E5g\t%1,%2,%l0";
9736 return "agr\t%1,%2\;cgr\t%1,%M2\;jg%C5\t%l0";
9738 "&& reload_completed
9739 && (!REG_P (operands[3])
9740 || !rtx_equal_p (operands[1], operands[3]))"
9741 [(set (match_dup 4) (match_dup 1))
9742 (parallel [(set (match_dup 4) (plus:DI (match_dup 4) (subreg:DI (match_dup 2) 0)))
9743 (clobber (reg:CC CC_REGNUM))])
9744 (set (reg:CCS CC_REGNUM) (compare:CCS (match_dup 4) (subreg:DI (match_dup 2) 8)))
9745 (set (match_dup 3) (match_dup 4))
9746 (set (pc) (if_then_else (match_op_dup 5 [(reg:CCS CC_REGNUM) (const_int 0)])
9747 (label_ref (match_dup 0))
9750 [(set_attr "op_type" "RIE")
9751 (set_attr "type" "branch")
9752 (set (attr "length")
9753 (if_then_else (lt (abs (minus (pc) (match_dup 0))) (const_int 60000))
9754 (const_int 6) (const_int 16)))])
9758 (define_insn_and_split "*brx_64bit"
9761 (match_operator 5 "s390_brx_operator"
9762 [(plus:SI (match_operand:SI 1 "register_operand" "d,d,d")
9763 (subreg:SI (match_operand:TI 2 "register_operand" "d,d,d") 4))
9764 (subreg:SI (match_dup 2) 12)])
9765 (label_ref (match_operand 0 "" ""))
9767 (set (match_operand:SI 3 "nonimmediate_operand" "=1,?X,?X")
9768 (plus:SI (match_dup 1)
9769 (subreg:SI (match_dup 2) 4)))
9770 (clobber (match_scratch:SI 4 "=X,&1,&?d"))
9771 (clobber (reg:CC CC_REGNUM))]
9774 if (which_alternative != 0)
9776 else if (get_attr_length (insn) == 6)
9777 return "brx%C5\t%1,%2,%l0";
9779 return "ar\t%1,%2\;cr\t%1,%M2\;jg%C5\t%l0";
9781 "&& reload_completed
9782 && (!REG_P (operands[3])
9783 || !rtx_equal_p (operands[1], operands[3]))"
9784 [(set (match_dup 4) (match_dup 1))
9785 (parallel [(set (match_dup 4) (plus:SI (match_dup 4) (subreg:SI (match_dup 2) 4)))
9786 (clobber (reg:CC CC_REGNUM))])
9787 (set (reg:CCS CC_REGNUM) (compare:CCS (match_dup 4) (subreg:SI (match_dup 2) 12)))
9788 (set (match_dup 3) (match_dup 4))
9789 (set (pc) (if_then_else (match_op_dup 5 [(reg:CCS CC_REGNUM) (const_int 0)])
9790 (label_ref (match_dup 0))
9793 [(set_attr "op_type" "RSI")
9794 (set_attr "type" "branch")
9795 (set (attr "length")
9796 (if_then_else (lt (abs (minus (pc) (match_dup 0))) (const_int 60000))
9797 (const_int 6) (const_int 14)))])
9801 (define_insn_and_split "*brx_31bit"
9804 (match_operator 5 "s390_brx_operator"
9805 [(plus:SI (match_operand:SI 1 "register_operand" "d,d,d")
9806 (subreg:SI (match_operand:DI 2 "register_operand" "d,d,d") 0))
9807 (subreg:SI (match_dup 2) 4)])
9808 (label_ref (match_operand 0 "" ""))
9810 (set (match_operand:SI 3 "nonimmediate_operand" "=1,?X,?X")
9811 (plus:SI (match_dup 1)
9812 (subreg:SI (match_dup 2) 0)))
9813 (clobber (match_scratch:SI 4 "=X,&1,&?d"))
9814 (clobber (reg:CC CC_REGNUM))]
9817 if (which_alternative != 0)
9819 else if (get_attr_length (insn) == 6)
9820 return "brx%C5\t%1,%2,%l0";
9822 return "ar\t%1,%2\;cr\t%1,%M2\;jg%C5\t%l0";
9824 "&& reload_completed
9825 && (!REG_P (operands[3])
9826 || !rtx_equal_p (operands[1], operands[3]))"
9827 [(set (match_dup 4) (match_dup 1))
9828 (parallel [(set (match_dup 4) (plus:SI (match_dup 4) (subreg:SI (match_dup 2) 0)))
9829 (clobber (reg:CC CC_REGNUM))])
9830 (set (reg:CCS CC_REGNUM) (compare:CCS (match_dup 4) (subreg:SI (match_dup 2) 4)))
9831 (set (match_dup 3) (match_dup 4))
9832 (set (pc) (if_then_else (match_op_dup 5 [(reg:CCS CC_REGNUM) (const_int 0)])
9833 (label_ref (match_dup 0))
9836 [(set_attr "op_type" "RSI")
9837 (set_attr "type" "branch")
9838 (set (attr "length")
9839 (if_then_else (lt (abs (minus (pc) (match_dup 0))) (const_int 60000))
9840 (const_int 6) (const_int 14)))])
9845 (define_expand "doloop_end"
9846 [(use (match_operand 0 "" "")) ; loop pseudo
9847 (use (match_operand 1 "" ""))] ; label
9850 if (GET_MODE (operands[0]) == SImode)
9851 emit_jump_insn (gen_doloop_si64 (operands[1], operands[0], operands[0]));
9852 else if (GET_MODE (operands[0]) == DImode && TARGET_ZARCH)
9853 emit_jump_insn (gen_doloop_di (operands[1], operands[0], operands[0]));
9860 (define_insn_and_split "doloop_si64"
9863 (ne (match_operand:SI 1 "register_operand" "d,d,d")
9865 (label_ref (match_operand 0 "" ""))
9867 (set (match_operand:SI 2 "nonimmediate_operand" "=1,?X,?X")
9868 (plus:SI (match_dup 1) (const_int -1)))
9869 (clobber (match_scratch:SI 3 "=X,&1,&?d"))
9870 (clobber (reg:CC CC_REGNUM))]
9873 if (which_alternative != 0)
9875 else if (get_attr_length (insn) == 4)
9876 return "brct\t%1,%l0";
9878 return "ahi\t%1,-1\;jgne\t%l0";
9880 "&& reload_completed
9881 && (! REG_P (operands[2])
9882 || ! rtx_equal_p (operands[1], operands[2]))"
9883 [(set (match_dup 3) (match_dup 1))
9884 (parallel [(set (reg:CCAN CC_REGNUM)
9885 (compare:CCAN (plus:SI (match_dup 3) (const_int -1))
9887 (set (match_dup 3) (plus:SI (match_dup 3) (const_int -1)))])
9888 (set (match_dup 2) (match_dup 3))
9889 (set (pc) (if_then_else (ne (reg:CCAN CC_REGNUM) (const_int 0))
9890 (label_ref (match_dup 0))
9893 [(set_attr "op_type" "RI")
9894 ; Strictly speaking, the z10 properties are valid for brct only, however, it does not
9895 ; hurt us in the (rare) case of ahi.
9896 (set_attr "z10prop" "z10_super_E1")
9897 (set_attr "type" "branch")
9898 (set (attr "length")
9899 (if_then_else (lt (abs (minus (pc) (match_dup 0))) (const_int 60000))
9900 (const_int 4) (const_int 10)))])
9902 (define_insn_and_split "doloop_di"
9905 (ne (match_operand:DI 1 "register_operand" "d,d,d")
9907 (label_ref (match_operand 0 "" ""))
9909 (set (match_operand:DI 2 "nonimmediate_operand" "=1,?X,?X")
9910 (plus:DI (match_dup 1) (const_int -1)))
9911 (clobber (match_scratch:DI 3 "=X,&1,&?d"))
9912 (clobber (reg:CC CC_REGNUM))]
9915 if (which_alternative != 0)
9917 else if (get_attr_length (insn) == 4)
9918 return "brctg\t%1,%l0";
9920 return "aghi\t%1,-1\;jgne\t%l0";
9922 "&& reload_completed
9923 && (! REG_P (operands[2])
9924 || ! rtx_equal_p (operands[1], operands[2]))"
9925 [(set (match_dup 3) (match_dup 1))
9926 (parallel [(set (reg:CCAN CC_REGNUM)
9927 (compare:CCAN (plus:DI (match_dup 3) (const_int -1))
9929 (set (match_dup 3) (plus:DI (match_dup 3) (const_int -1)))])
9930 (set (match_dup 2) (match_dup 3))
9931 (set (pc) (if_then_else (ne (reg:CCAN CC_REGNUM) (const_int 0))
9932 (label_ref (match_dup 0))
9935 [(set_attr "op_type" "RI")
9936 ; Strictly speaking, the z10 properties are valid for brct only, however, it does not
9937 ; hurt us in the (rare) case of ahi.
9938 (set_attr "z10prop" "z10_super_E1")
9939 (set_attr "type" "branch")
9940 (set (attr "length")
9941 (if_then_else (lt (abs (minus (pc) (match_dup 0))) (const_int 60000))
9942 (const_int 4) (const_int 10)))])
9945 ;;- Unconditional jump instructions.
9949 ; jump instruction pattern(s).
9952 (define_expand "jump"
9953 [(match_operand 0 "" "")]
9955 "s390_emit_jump (operands[0], NULL_RTX); DONE;")
9957 (define_insn "*jump64"
9958 [(set (pc) (label_ref (match_operand 0 "" "")))]
9961 if (get_attr_length (insn) == 4)
9966 [(set_attr "op_type" "RI")
9967 (set_attr "type" "branch")
9968 (set (attr "length")
9969 (if_then_else (lt (abs (minus (pc) (match_dup 0))) (const_int 60000))
9970 (const_int 4) (const_int 6)))])
9973 ; indirect-jump instruction pattern(s).
9976 (define_expand "indirect_jump"
9977 [(set (pc) (match_operand 0 "nonimmediate_operand" ""))]
9980 if (address_operand (operands[0], GET_MODE (operands[0])))
9983 && GET_MODE (operands[0]) == Pmode
9984 && memory_operand (operands[0], Pmode))
9987 operands[0] = force_reg (Pmode, operands[0]);
9989 if (TARGET_INDIRECT_BRANCH_NOBP_JUMP_THUNK)
9991 operands[0] = force_reg (Pmode, operands[0]);
9995 emit_jump_insn (gen_indirect_jump_via_thunkdi_z10 (operands[0]));
9997 emit_jump_insn (gen_indirect_jump_via_thunksi_z10 (operands[0]));
10002 emit_jump_insn (gen_indirect_jump_via_thunkdi (operands[0]));
10004 emit_jump_insn (gen_indirect_jump_via_thunksi (operands[0]));
10009 if (TARGET_INDIRECT_BRANCH_NOBP_JUMP_INLINE_THUNK)
10011 operands[0] = force_reg (Pmode, operands[0]);
10012 rtx label_ref = gen_rtx_LABEL_REF (VOIDmode, gen_label_rtx ());
10013 if (TARGET_CPU_Z10)
10016 emit_jump_insn (gen_indirect_jump_via_inlinethunkdi_z10 (operands[0],
10019 emit_jump_insn (gen_indirect_jump_via_inlinethunksi_z10 (operands[0],
10025 emit_jump_insn (gen_indirect_jump_via_inlinethunkdi (operands[0],
10027 force_reg (Pmode, label_ref)));
10029 emit_jump_insn (gen_indirect_jump_via_inlinethunksi (operands[0],
10031 force_reg (Pmode, label_ref)));
10037 (define_insn "*indirect_jump"
10039 (match_operand 0 "address_operand" "ZR"))]
10040 "!TARGET_INDIRECT_BRANCH_NOBP_JUMP_THUNK"
10042 if (get_attr_op_type (insn) == OP_TYPE_RR)
10047 [(set (attr "op_type")
10048 (if_then_else (match_operand 0 "register_operand" "")
10049 (const_string "RR") (const_string "RX")))
10050 (set (attr "mnemonic")
10051 (if_then_else (match_operand 0 "register_operand" "")
10052 (const_string "br") (const_string "b")))
10053 (set_attr "type" "branch")
10054 (set_attr "atype" "agen")])
10056 (define_insn "indirect_jump_via_thunk<mode>_z10"
10058 (match_operand:P 0 "register_operand" "a"))]
10059 "TARGET_INDIRECT_BRANCH_NOBP_JUMP_THUNK
10062 s390_indirect_branch_via_thunk (REGNO (operands[0]),
10065 s390_indirect_branch_type_jump);
10068 [(set_attr "op_type" "RIL")
10069 (set_attr "mnemonic" "jg")
10070 (set_attr "type" "branch")
10071 (set_attr "atype" "agen")])
10073 (define_insn "indirect_jump_via_thunk<mode>"
10075 (match_operand:P 0 "register_operand" " a"))
10076 (clobber (reg:P INDIRECT_BRANCH_THUNK_REGNUM))]
10077 "TARGET_INDIRECT_BRANCH_NOBP_JUMP_THUNK
10078 && !TARGET_CPU_Z10"
10080 s390_indirect_branch_via_thunk (REGNO (operands[0]),
10083 s390_indirect_branch_type_jump);
10086 [(set_attr "op_type" "RIL")
10087 (set_attr "mnemonic" "jg")
10088 (set_attr "type" "branch")
10089 (set_attr "atype" "agen")])
10092 ; The label_ref is wrapped into an if_then_else in order to hide it
10093 ; from mark_jump_label. Without this the label_ref would become the
10094 ; ONLY jump target of that jump breaking the control flow graph.
10095 (define_insn "indirect_jump_via_inlinethunk<mode>_z10"
10096 [(unspec [(if_then_else (match_operand:P 1 "larl_operand" "X")
10099 (const_int 0)] UNSPEC_EXECUTE_JUMP)
10100 (set (pc) (match_operand:P 0 "register_operand" "a"))]
10101 "TARGET_INDIRECT_BRANCH_NOBP_JUMP_INLINE_THUNK
10104 s390_indirect_branch_via_inline_thunk (operands[1]);
10107 [(set_attr "op_type" "RIL")
10108 (set_attr "type" "branch")
10109 (set_attr "length" "10")])
10111 (define_insn "indirect_jump_via_inlinethunk<mode>"
10112 [(unspec [(if_then_else (match_operand:P 1 "larl_operand" "X")
10115 (match_operand:P 2 "register_operand" "a")] UNSPEC_EXECUTE_JUMP)
10116 (set (pc) (match_operand:P 0 "register_operand" "a"))]
10117 "TARGET_INDIRECT_BRANCH_NOBP_JUMP_INLINE_THUNK
10118 && !TARGET_CPU_Z10"
10120 s390_indirect_branch_via_inline_thunk (operands[2]);
10123 [(set_attr "op_type" "RX")
10124 (set_attr "type" "branch")
10125 (set_attr "length" "8")])
10127 ; FIXME: LRA does not appear to be able to deal with MEMs being
10128 ; checked against address constraints like ZR above. So make this a
10129 ; separate pattern for now.
10130 (define_insn "*indirect2_jump"
10132 (match_operand 0 "nonimmediate_operand" "a,T"))]
10133 "!TARGET_INDIRECT_BRANCH_NOBP_JUMP"
10137 [(set_attr "op_type" "RR,RXY")
10138 (set_attr "type" "branch")
10139 (set_attr "atype" "agen")
10140 (set_attr "cpu_facility" "*,z14")])
10143 ; casesi instruction pattern(s).
10146 (define_expand "casesi_jump"
10148 [(set (pc) (match_operand 0 "address_operand"))
10149 (use (label_ref (match_operand 1 "")))])]
10152 if (TARGET_INDIRECT_BRANCH_NOBP_JUMP_THUNK)
10154 operands[0] = force_reg (GET_MODE (operands[0]), operands[0]);
10156 if (TARGET_CPU_Z10)
10159 emit_jump_insn (gen_casesi_jump_via_thunkdi_z10 (operands[0],
10162 emit_jump_insn (gen_casesi_jump_via_thunksi_z10 (operands[0],
10168 emit_jump_insn (gen_casesi_jump_via_thunkdi (operands[0],
10171 emit_jump_insn (gen_casesi_jump_via_thunksi (operands[0],
10177 if (TARGET_INDIRECT_BRANCH_NOBP_JUMP_INLINE_THUNK)
10179 operands[0] = force_reg (Pmode, operands[0]);
10180 rtx label_ref = gen_rtx_LABEL_REF (VOIDmode, gen_label_rtx ());
10181 if (TARGET_CPU_Z10)
10184 emit_jump_insn (gen_casesi_jump_via_inlinethunkdi_z10 (operands[0],
10188 emit_jump_insn (gen_casesi_jump_via_inlinethunksi_z10 (operands[0],
10195 emit_jump_insn (gen_casesi_jump_via_inlinethunkdi (operands[0],
10198 force_reg (Pmode, label_ref)));
10200 emit_jump_insn (gen_casesi_jump_via_inlinethunksi (operands[0],
10203 force_reg (Pmode, label_ref)));
10209 (define_insn "*casesi_jump"
10210 [(set (pc) (match_operand 0 "address_operand" "ZR"))
10211 (use (label_ref (match_operand 1 "" "")))]
10212 "!TARGET_INDIRECT_BRANCH_NOBP_JUMP_THUNK"
10214 if (get_attr_op_type (insn) == OP_TYPE_RR)
10219 [(set (attr "op_type")
10220 (if_then_else (match_operand 0 "register_operand" "")
10221 (const_string "RR") (const_string "RX")))
10222 (set (attr "mnemonic")
10223 (if_then_else (match_operand 0 "register_operand" "")
10224 (const_string "br") (const_string "b")))
10225 (set_attr "type" "branch")
10226 (set_attr "atype" "agen")])
10228 (define_insn "casesi_jump_via_thunk<mode>_z10"
10229 [(set (pc) (match_operand:P 0 "register_operand" "a"))
10230 (use (label_ref (match_operand 1 "" "")))]
10231 "TARGET_INDIRECT_BRANCH_NOBP_JUMP_THUNK
10234 s390_indirect_branch_via_thunk (REGNO (operands[0]),
10237 s390_indirect_branch_type_jump);
10240 [(set_attr "op_type" "RIL")
10241 (set_attr "mnemonic" "jg")
10242 (set_attr "type" "branch")
10243 (set_attr "atype" "agen")])
10245 (define_insn "casesi_jump_via_thunk<mode>"
10246 [(set (pc) (match_operand:P 0 "register_operand" "a"))
10247 (use (label_ref (match_operand 1 "" "")))
10248 (clobber (reg:P INDIRECT_BRANCH_THUNK_REGNUM))]
10249 "TARGET_INDIRECT_BRANCH_NOBP_JUMP_THUNK
10250 && !TARGET_CPU_Z10"
10252 s390_indirect_branch_via_thunk (REGNO (operands[0]),
10255 s390_indirect_branch_type_jump);
10258 [(set_attr "op_type" "RIL")
10259 (set_attr "mnemonic" "jg")
10260 (set_attr "type" "branch")
10261 (set_attr "atype" "agen")])
10264 ; The label_ref is wrapped into an if_then_else in order to hide it
10265 ; from mark_jump_label. Without this the label_ref would become the
10266 ; ONLY jump target of that jump breaking the control flow graph.
10267 (define_insn "casesi_jump_via_inlinethunk<mode>_z10"
10268 [(unspec [(if_then_else (match_operand:P 2 "larl_operand" "X")
10271 (const_int 0)] UNSPEC_EXECUTE_JUMP)
10272 (set (pc) (match_operand:P 0 "register_operand" "a"))
10273 (use (label_ref (match_operand 1 "" "")))]
10274 "TARGET_INDIRECT_BRANCH_NOBP_JUMP_INLINE_THUNK
10277 s390_indirect_branch_via_inline_thunk (operands[2]);
10280 [(set_attr "op_type" "RIL")
10281 (set_attr "type" "cs")
10282 (set_attr "length" "10")])
10284 (define_insn "casesi_jump_via_inlinethunk<mode>"
10285 [(unspec [(if_then_else (match_operand:P 2 "larl_operand" "X")
10288 (match_operand:P 3 "register_operand" "a")] UNSPEC_EXECUTE_JUMP)
10289 (set (pc) (match_operand:P 0 "register_operand" "a"))
10290 (use (label_ref (match_operand 1 "" "")))]
10291 "TARGET_INDIRECT_BRANCH_NOBP_JUMP_INLINE_THUNK
10292 && !TARGET_CPU_Z10"
10294 s390_indirect_branch_via_inline_thunk (operands[3]);
10297 [(set_attr "op_type" "RX")
10298 (set_attr "type" "cs")
10299 (set_attr "length" "8")])
10301 (define_expand "casesi"
10302 [(match_operand:SI 0 "general_operand" "")
10303 (match_operand:SI 1 "general_operand" "")
10304 (match_operand:SI 2 "general_operand" "")
10305 (label_ref (match_operand 3 "" ""))
10306 (label_ref (match_operand 4 "" ""))]
10309 rtx index = gen_reg_rtx (SImode);
10310 rtx base = gen_reg_rtx (Pmode);
10311 rtx target = gen_reg_rtx (Pmode);
10313 emit_move_insn (index, operands[0]);
10314 emit_insn (gen_subsi3 (index, index, operands[1]));
10315 emit_cmp_and_jump_insns (index, operands[2], GTU, NULL_RTX, SImode, 1,
10318 if (Pmode != SImode)
10319 index = convert_to_mode (Pmode, index, 1);
10320 if (GET_CODE (index) != REG)
10321 index = copy_to_mode_reg (Pmode, index);
10324 emit_insn (gen_ashldi3 (index, index, GEN_INT (3)));
10326 emit_insn (gen_ashlsi3 (index, index, const2_rtx));
10328 emit_move_insn (base, gen_rtx_LABEL_REF (Pmode, operands[3]));
10330 index = gen_const_mem (Pmode, gen_rtx_PLUS (Pmode, base, index));
10331 emit_move_insn (target, index);
10334 target = gen_rtx_PLUS (Pmode, base, target);
10335 emit_jump_insn (gen_casesi_jump (target, operands[3]));
10342 ;;- Jump to subroutine.
10347 ; untyped call instruction pattern(s).
10350 ;; Call subroutine returning any type.
10351 (define_expand "untyped_call"
10352 [(parallel [(call (match_operand 0 "" "")
10354 (match_operand 1 "" "")
10355 (match_operand 2 "" "")])]
10360 emit_call_insn (gen_call (operands[0], const0_rtx, const0_rtx));
10362 for (i = 0; i < XVECLEN (operands[2], 0); i++)
10364 rtx set = XVECEXP (operands[2], 0, i);
10365 emit_move_insn (SET_DEST (set), SET_SRC (set));
10368 /* The optimizer does not know that the call sets the function value
10369 registers we stored in the result block. We avoid problems by
10370 claiming that all hard registers are used and clobbered at this
10372 emit_insn (gen_blockage ());
10377 ;; UNSPEC_VOLATILE is considered to use and clobber all hard registers and
10378 ;; all of memory. This blocks insns from being moved across this point.
10380 (define_insn "blockage"
10381 [(unspec_volatile [(const_int 0)] UNSPECV_BLOCKAGE)]
10384 [(set_attr "type" "none")
10385 (set_attr "length" "0")])
10391 (define_expand "sibcall"
10392 [(call (match_operand 0 "" "")
10393 (match_operand 1 "" ""))]
10396 s390_emit_call (XEXP (operands[0], 0), NULL_RTX, NULL_RTX, NULL_RTX);
10400 (define_insn "*sibcall_br"
10401 [(call (mem:QI (reg SIBCALL_REGNUM))
10402 (match_operand 0 "const_int_operand" "n"))]
10403 "SIBLING_CALL_P (insn)
10404 && GET_MODE (XEXP (XEXP (PATTERN (insn), 0), 0)) == Pmode"
10406 if (TARGET_INDIRECT_BRANCH_NOBP_CALL)
10408 gcc_assert (TARGET_CPU_Z10);
10409 s390_indirect_branch_via_thunk (SIBCALL_REGNUM,
10412 s390_indirect_branch_type_call);
10418 [(set (attr "op_type")
10419 (if_then_else (match_test "TARGET_INDIRECT_BRANCH_NOBP_CALL")
10420 (const_string "RIL")
10421 (const_string "RR")))
10422 (set (attr "mnemonic")
10423 (if_then_else (match_test "TARGET_INDIRECT_BRANCH_NOBP_CALL")
10424 (const_string "jg")
10425 (const_string "br")))
10426 (set_attr "type" "branch")
10427 (set_attr "atype" "agen")])
10429 (define_insn "*sibcall_brc"
10430 [(call (mem:QI (match_operand 0 "bras_sym_operand" "X"))
10431 (match_operand 1 "const_int_operand" "n"))]
10432 "SIBLING_CALL_P (insn) && TARGET_SMALL_EXEC"
10434 [(set_attr "op_type" "RI")
10435 (set_attr "type" "branch")])
10437 (define_insn "*sibcall_brcl"
10438 [(call (mem:QI (match_operand 0 "bras_sym_operand" "X"))
10439 (match_operand 1 "const_int_operand" "n"))]
10440 "SIBLING_CALL_P (insn)"
10442 [(set_attr "op_type" "RIL")
10443 (set_attr "type" "branch")])
10446 ; sibcall_value patterns
10449 (define_expand "sibcall_value"
10450 [(set (match_operand 0 "" "")
10451 (call (match_operand 1 "" "")
10452 (match_operand 2 "" "")))]
10455 s390_emit_call (XEXP (operands[1], 0), NULL_RTX, operands[0], NULL_RTX);
10459 (define_insn "*sibcall_value_br"
10460 [(set (match_operand 0 "" "")
10461 (call (mem:QI (reg SIBCALL_REGNUM))
10462 (match_operand 1 "const_int_operand" "n")))]
10463 "SIBLING_CALL_P (insn)
10464 && GET_MODE (XEXP (XEXP (XEXP (PATTERN (insn), 1), 0), 0)) == Pmode"
10466 if (TARGET_INDIRECT_BRANCH_NOBP_CALL)
10468 gcc_assert (TARGET_CPU_Z10);
10469 s390_indirect_branch_via_thunk (SIBCALL_REGNUM,
10472 s390_indirect_branch_type_call);
10478 [(set (attr "op_type")
10479 (if_then_else (match_test "TARGET_INDIRECT_BRANCH_NOBP_CALL")
10480 (const_string "RIL")
10481 (const_string "RR")))
10482 (set (attr "mnemonic")
10483 (if_then_else (match_test "TARGET_INDIRECT_BRANCH_NOBP_CALL")
10484 (const_string "jg")
10485 (const_string "br")))
10486 (set_attr "type" "branch")
10487 (set_attr "atype" "agen")])
10489 (define_insn "*sibcall_value_brc"
10490 [(set (match_operand 0 "" "")
10491 (call (mem:QI (match_operand 1 "bras_sym_operand" "X"))
10492 (match_operand 2 "const_int_operand" "n")))]
10493 "SIBLING_CALL_P (insn) && TARGET_SMALL_EXEC"
10495 [(set_attr "op_type" "RI")
10496 (set_attr "type" "branch")])
10498 (define_insn "*sibcall_value_brcl"
10499 [(set (match_operand 0 "" "")
10500 (call (mem:QI (match_operand 1 "bras_sym_operand" "X"))
10501 (match_operand 2 "const_int_operand" "n")))]
10502 "SIBLING_CALL_P (insn)"
10504 [(set_attr "op_type" "RIL")
10505 (set_attr "type" "branch")])
10509 ; call instruction pattern(s).
10512 (define_expand "call"
10513 [(call (match_operand 0 "" "")
10514 (match_operand 1 "" ""))
10515 (use (match_operand 2 "" ""))]
10518 s390_emit_call (XEXP (operands[0], 0), NULL_RTX, NULL_RTX,
10519 gen_rtx_REG (Pmode, RETURN_REGNUM));
10523 (define_insn "*bras"
10524 [(call (mem:QI (match_operand 0 "bras_sym_operand" "X"))
10525 (match_operand 1 "const_int_operand" "n"))
10526 (clobber (match_operand 2 "register_operand" "=r"))]
10527 "!SIBLING_CALL_P (insn)
10528 && TARGET_SMALL_EXEC
10529 && GET_MODE (operands[2]) == Pmode"
10531 [(set_attr "op_type" "RI")
10532 (set_attr "type" "jsr")
10533 (set_attr "z196prop" "z196_cracked")])
10535 (define_insn "*brasl"
10536 [(call (mem:QI (match_operand 0 "bras_sym_operand" "X"))
10537 (match_operand 1 "const_int_operand" "n"))
10538 (clobber (match_operand 2 "register_operand" "=r"))]
10539 "!SIBLING_CALL_P (insn)
10541 && GET_MODE (operands[2]) == Pmode"
10543 [(set_attr "op_type" "RIL")
10544 (set_attr "type" "jsr")
10545 (set_attr "z196prop" "z196_cracked")
10546 (set_attr "relative_long" "yes")])
10548 (define_insn "*basr"
10549 [(call (mem:QI (match_operand 0 "address_operand" "ZR"))
10550 (match_operand 1 "const_int_operand" "n"))
10551 (clobber (match_operand 2 "register_operand" "=r"))]
10552 "!TARGET_INDIRECT_BRANCH_NOBP_CALL
10553 && !SIBLING_CALL_P (insn)
10554 && GET_MODE (operands[2]) == Pmode"
10556 if (get_attr_op_type (insn) == OP_TYPE_RR)
10557 return "basr\t%2,%0";
10559 return "bas\t%2,%a0";
10561 [(set (attr "op_type")
10562 (if_then_else (match_operand 0 "register_operand" "")
10563 (const_string "RR") (const_string "RX")))
10564 (set (attr "mnemonic")
10565 (if_then_else (match_operand 0 "register_operand" "")
10566 (const_string "basr") (const_string "bas")))
10567 (set_attr "type" "jsr")
10568 (set_attr "atype" "agen")
10569 (set_attr "z196prop" "z196_cracked")])
10571 (define_insn "*basr_via_thunk<mode>_z10"
10572 [(call (mem:QI (match_operand:P 0 "register_operand" "a"))
10573 (match_operand 1 "const_int_operand" "n"))
10574 (clobber (match_operand:P 2 "register_operand" "=&r"))]
10575 "TARGET_INDIRECT_BRANCH_NOBP_CALL
10577 && !SIBLING_CALL_P (insn)"
10579 s390_indirect_branch_via_thunk (REGNO (operands[0]),
10580 REGNO (operands[2]),
10582 s390_indirect_branch_type_call);
10585 [(set_attr "op_type" "RIL")
10586 (set_attr "mnemonic" "brasl")
10587 (set_attr "type" "jsr")
10588 (set_attr "atype" "agen")
10589 (set_attr "z196prop" "z196_cracked")])
10591 (define_insn "*basr_via_thunk<mode>"
10592 [(call (mem:QI (match_operand:P 0 "register_operand" "a"))
10593 (match_operand 1 "const_int_operand" "n"))
10594 (clobber (match_operand:P 2 "register_operand" "=&r"))
10595 (clobber (reg:P INDIRECT_BRANCH_THUNK_REGNUM))]
10596 "TARGET_INDIRECT_BRANCH_NOBP_CALL
10598 && !SIBLING_CALL_P (insn)"
10600 s390_indirect_branch_via_thunk (REGNO (operands[0]),
10601 REGNO (operands[2]),
10603 s390_indirect_branch_type_call);
10606 [(set_attr "op_type" "RIL")
10607 (set_attr "mnemonic" "brasl")
10608 (set_attr "type" "jsr")
10609 (set_attr "atype" "agen")
10610 (set_attr "z196prop" "z196_cracked")])
10613 ; call_value instruction pattern(s).
10616 (define_expand "call_value"
10617 [(set (match_operand 0 "" "")
10618 (call (match_operand 1 "" "")
10619 (match_operand 2 "" "")))
10620 (use (match_operand 3 "" ""))]
10623 s390_emit_call (XEXP (operands[1], 0), NULL_RTX, operands[0],
10624 gen_rtx_REG (Pmode, RETURN_REGNUM));
10628 (define_insn "*bras_r"
10629 [(set (match_operand 0 "" "")
10630 (call (mem:QI (match_operand 1 "bras_sym_operand" "X"))
10631 (match_operand:SI 2 "const_int_operand" "n")))
10632 (clobber (match_operand 3 "register_operand" "=r"))]
10633 "!SIBLING_CALL_P (insn)
10634 && TARGET_SMALL_EXEC
10635 && GET_MODE (operands[3]) == Pmode"
10637 [(set_attr "op_type" "RI")
10638 (set_attr "type" "jsr")
10639 (set_attr "z196prop" "z196_cracked")])
10641 (define_insn "*brasl_r"
10642 [(set (match_operand 0 "" "")
10643 (call (mem:QI (match_operand 1 "bras_sym_operand" "X"))
10644 (match_operand 2 "const_int_operand" "n")))
10645 (clobber (match_operand 3 "register_operand" "=r"))]
10646 "!SIBLING_CALL_P (insn)
10648 && GET_MODE (operands[3]) == Pmode"
10650 [(set_attr "op_type" "RIL")
10651 (set_attr "type" "jsr")
10652 (set_attr "z196prop" "z196_cracked")
10653 (set_attr "relative_long" "yes")])
10655 (define_insn "*basr_r"
10656 [(set (match_operand 0 "" "")
10657 (call (mem:QI (match_operand 1 "address_operand" "ZR"))
10658 (match_operand 2 "const_int_operand" "n")))
10659 (clobber (match_operand 3 "register_operand" "=r"))]
10660 "!TARGET_INDIRECT_BRANCH_NOBP_CALL
10661 && !SIBLING_CALL_P (insn)
10662 && GET_MODE (operands[3]) == Pmode"
10664 if (get_attr_op_type (insn) == OP_TYPE_RR)
10665 return "basr\t%3,%1";
10667 return "bas\t%3,%a1";
10669 [(set (attr "op_type")
10670 (if_then_else (match_operand 1 "register_operand" "")
10671 (const_string "RR") (const_string "RX")))
10672 (set (attr "mnemonic")
10673 (if_then_else (match_operand 1 "register_operand" "")
10674 (const_string "basr") (const_string "bas")))
10675 (set_attr "type" "jsr")
10676 (set_attr "atype" "agen")
10677 (set_attr "z196prop" "z196_cracked")])
10679 (define_insn "*basr_r_via_thunk_z10"
10680 [(set (match_operand 0 "" "")
10681 (call (mem:QI (match_operand 1 "register_operand" "a"))
10682 (match_operand 2 "const_int_operand" "n")))
10683 (clobber (match_operand 3 "register_operand" "=&r"))]
10684 "TARGET_INDIRECT_BRANCH_NOBP_CALL
10686 && !SIBLING_CALL_P (insn)
10687 && GET_MODE (operands[3]) == Pmode"
10689 s390_indirect_branch_via_thunk (REGNO (operands[1]),
10690 REGNO (operands[3]),
10692 s390_indirect_branch_type_call);
10695 [(set_attr "op_type" "RIL")
10696 (set_attr "mnemonic" "brasl")
10697 (set_attr "type" "jsr")
10698 (set_attr "atype" "agen")
10699 (set_attr "z196prop" "z196_cracked")])
10701 (define_insn "*basr_r_via_thunk"
10702 [(set (match_operand 0 "" "")
10703 (call (mem:QI (match_operand 1 "register_operand" "a"))
10704 (match_operand 2 "const_int_operand" "n")))
10705 (clobber (match_operand 3 "register_operand" "=&r"))
10706 (clobber (reg:P INDIRECT_BRANCH_THUNK_REGNUM))]
10707 "TARGET_INDIRECT_BRANCH_NOBP_CALL
10709 && !SIBLING_CALL_P (insn)
10710 && GET_MODE (operands[3]) == Pmode"
10712 s390_indirect_branch_via_thunk (REGNO (operands[1]),
10713 REGNO (operands[3]),
10715 s390_indirect_branch_type_call);
10718 [(set_attr "op_type" "RIL")
10719 (set_attr "mnemonic" "brasl")
10720 (set_attr "type" "jsr")
10721 (set_attr "atype" "agen")
10722 (set_attr "z196prop" "z196_cracked")])
10725 ;;- Thread-local storage support.
10728 (define_expand "@get_thread_pointer<mode>"
10729 [(set (match_operand:P 0 "nonimmediate_operand" "")
10730 (unspec:P [(reg:P TP_REGNUM)] UNSPEC_GET_TP))]
10734 (define_expand "set_thread_pointer<mode>"
10735 [(set (reg:P TP_REGNUM) (match_operand:P 0 "nonimmediate_operand" ""))
10736 (set (reg:P TP_REGNUM) (unspec_volatile:P [(reg:P TP_REGNUM)] UNSPECV_SET_TP))]
10740 (define_insn "*set_tp"
10741 [(set (reg TP_REGNUM) (unspec_volatile [(reg TP_REGNUM)] UNSPECV_SET_TP))]
10744 [(set_attr "type" "none")
10745 (set_attr "length" "0")])
10747 (define_insn "*tls_load_64"
10748 [(set (match_operand:DI 0 "register_operand" "=d")
10749 (unspec:DI [(match_operand:DI 1 "memory_operand" "T")
10750 (match_operand:DI 2 "" "")]
10754 [(set_attr "op_type" "RXE")
10755 (set_attr "z10prop" "z10_fwd_A3")])
10757 (define_insn "*tls_load_31"
10758 [(set (match_operand:SI 0 "register_operand" "=d,d")
10759 (unspec:SI [(match_operand:SI 1 "memory_operand" "R,T")
10760 (match_operand:SI 2 "" "")]
10766 [(set_attr "op_type" "RX,RXY")
10767 (set_attr "type" "load")
10768 (set_attr "cpu_facility" "*,longdisp")
10769 (set_attr "z10prop" "z10_fwd_A3,z10_fwd_A3")])
10771 (define_insn "*bras_tls"
10772 [(set (match_operand 0 "" "")
10773 (call (mem:QI (match_operand 1 "bras_sym_operand" "X"))
10774 (match_operand 2 "const_int_operand" "n")))
10775 (clobber (match_operand 3 "register_operand" "=r"))
10776 (use (match_operand 4 "" ""))]
10777 "!SIBLING_CALL_P (insn)
10778 && TARGET_SMALL_EXEC
10779 && GET_MODE (operands[3]) == Pmode"
10780 "bras\t%3,%1%K1%J4"
10781 [(set_attr "op_type" "RI")
10782 (set_attr "type" "jsr")
10783 (set_attr "z196prop" "z196_cracked")])
10785 (define_insn "*brasl_tls"
10786 [(set (match_operand 0 "" "")
10787 (call (mem:QI (match_operand 1 "bras_sym_operand" "X"))
10788 (match_operand 2 "const_int_operand" "n")))
10789 (clobber (match_operand 3 "register_operand" "=r"))
10790 (use (match_operand 4 "" ""))]
10791 "!SIBLING_CALL_P (insn)
10793 && GET_MODE (operands[3]) == Pmode"
10794 "brasl\t%3,%1%K1%J4"
10795 [(set_attr "op_type" "RIL")
10796 (set_attr "type" "jsr")
10797 (set_attr "z196prop" "z196_cracked")
10798 (set_attr "relative_long" "yes")])
10800 (define_insn "*basr_tls"
10801 [(set (match_operand 0 "" "")
10802 (call (mem:QI (match_operand 1 "address_operand" "ZR"))
10803 (match_operand 2 "const_int_operand" "n")))
10804 (clobber (match_operand 3 "register_operand" "=r"))
10805 (use (match_operand 4 "" ""))]
10806 "!SIBLING_CALL_P (insn) && GET_MODE (operands[3]) == Pmode"
10808 if (get_attr_op_type (insn) == OP_TYPE_RR)
10809 return "basr\t%3,%1%J4";
10811 return "bas\t%3,%a1%J4";
10813 [(set (attr "op_type")
10814 (if_then_else (match_operand 1 "register_operand" "")
10815 (const_string "RR") (const_string "RX")))
10816 (set_attr "type" "jsr")
10817 (set_attr "atype" "agen")
10818 (set_attr "z196prop" "z196_cracked")])
10821 ;;- Atomic operations
10825 ; memory barrier patterns.
10828 (define_expand "mem_thread_fence"
10829 [(match_operand:SI 0 "const_int_operand")] ;; model
10832 /* Unless this is a SEQ_CST fence, the s390 memory model is strong
10833 enough not to require barriers of any kind. */
10834 if (is_mm_seq_cst (memmodel_from_int (INTVAL (operands[0]))))
10836 rtx mem = gen_rtx_MEM (BLKmode, gen_rtx_SCRATCH (Pmode));
10837 MEM_VOLATILE_P (mem) = 1;
10838 emit_insn (gen_mem_thread_fence_1 (mem));
10843 ; Although bcr is superscalar on Z10, this variant will never
10844 ; become part of an execution group.
10845 ; With z196 we can make use of the fast-BCR-serialization facility.
10846 ; This allows for a slightly faster sync which is sufficient for our
10848 (define_insn "mem_thread_fence_1"
10849 [(set (match_operand:BLK 0 "" "")
10850 (unspec:BLK [(match_dup 0)] UNSPEC_MB))]
10854 return "bcr\t14,0";
10856 return "bcr\t15,0";
10858 [(set_attr "op_type" "RR")
10859 (set_attr "mnemonic" "bcr_flush")
10860 (set_attr "z196prop" "z196_alone")])
10863 ; atomic load/store operations
10866 ; Atomic loads need not examine the memory model at all.
10867 (define_expand "atomic_load<mode>"
10868 [(match_operand:DINT 0 "register_operand") ;; output
10869 (match_operand:DINT 1 "memory_operand") ;; memory
10870 (match_operand:SI 2 "const_int_operand")] ;; model
10873 if (MEM_ALIGN (operands[1]) < GET_MODE_BITSIZE (GET_MODE (operands[1])))
10876 if (<MODE>mode == TImode)
10877 emit_insn (gen_atomic_loadti_1 (operands[0], operands[1]));
10878 else if (<MODE>mode == DImode && !TARGET_ZARCH)
10879 emit_insn (gen_atomic_loaddi_1 (operands[0], operands[1]));
10881 emit_move_insn (operands[0], operands[1]);
10885 ; Different from movdi_31 in that we want no splitters.
10886 (define_insn "atomic_loaddi_1"
10887 [(set (match_operand:DI 0 "register_operand" "=d,d,!*f,!*f")
10888 (unspec:DI [(match_operand:DI 1 "memory_operand" "Q,S,R,T")]
10896 [(set_attr "op_type" "RS,RSY,RS,RSY")
10897 (set_attr "cpu_facility" "*,longdisp,*,longdisp")
10898 (set_attr "type" "lm,lm,floaddf,floaddf")])
10900 (define_insn "atomic_loadti_1"
10901 [(set (match_operand:TI 0 "register_operand" "=r")
10902 (unspec:TI [(match_operand:TI 1 "memory_operand" "T")]
10906 [(set_attr "op_type" "RXY")
10907 (set_attr "type" "other")])
10909 ; Atomic stores must(?) enforce sequential consistency.
10910 (define_expand "atomic_store<mode>"
10911 [(match_operand:DINT 0 "memory_operand") ;; memory
10912 (match_operand:DINT 1 "register_operand") ;; input
10913 (match_operand:SI 2 "const_int_operand")] ;; model
10916 enum memmodel model = memmodel_from_int (INTVAL (operands[2]));
10918 if (MEM_ALIGN (operands[0]) < GET_MODE_BITSIZE (GET_MODE (operands[0])))
10921 if (<MODE>mode == TImode)
10922 emit_insn (gen_atomic_storeti_1 (operands[0], operands[1]));
10923 else if (<MODE>mode == DImode && !TARGET_ZARCH)
10924 emit_insn (gen_atomic_storedi_1 (operands[0], operands[1]));
10926 emit_move_insn (operands[0], operands[1]);
10927 if (is_mm_seq_cst (model))
10928 emit_insn (gen_mem_thread_fence (operands[2]));
10932 ; Different from movdi_31 in that we want no splitters.
10933 (define_insn "atomic_storedi_1"
10934 [(set (match_operand:DI 0 "memory_operand" "=Q,S,R,T")
10935 (unspec:DI [(match_operand:DI 1 "register_operand" "d,d,!*f,!*f")]
10943 [(set_attr "op_type" "RS,RSY,RS,RSY")
10944 (set_attr "cpu_facility" "*,longdisp,*,longdisp")
10945 (set_attr "type" "stm,stm,fstoredf,fstoredf")])
10947 (define_insn "atomic_storeti_1"
10948 [(set (match_operand:TI 0 "memory_operand" "=T")
10949 (unspec:TI [(match_operand:TI 1 "register_operand" "r")]
10953 [(set_attr "op_type" "RXY")
10954 (set_attr "type" "other")])
10957 ; compare and swap patterns.
10960 (define_expand "atomic_compare_and_swap<mode>"
10961 [(match_operand:SI 0 "register_operand") ;; bool success output
10962 (match_operand:DINT 1 "nonimmediate_operand");; oldval output
10963 (match_operand:DINT 2 "s_operand") ;; memory
10964 (match_operand:DINT 3 "general_operand") ;; expected intput
10965 (match_operand:DINT 4 "general_operand") ;; newval intput
10966 (match_operand:SI 5 "const_int_operand") ;; is_weak
10967 (match_operand:SI 6 "const_int_operand") ;; success model
10968 (match_operand:SI 7 "const_int_operand")] ;; failure model
10971 if (GET_MODE_BITSIZE (<MODE>mode) >= 16
10972 && GET_MODE_BITSIZE (<MODE>mode) > MEM_ALIGN (operands[2]))
10975 s390_expand_cs (<MODE>mode, operands[0], operands[1], operands[2],
10976 operands[3], operands[4], INTVAL (operands[5]));
10979 (define_expand "atomic_compare_and_swap<mode>_internal"
10981 [(set (match_operand:DGPR 0 "register_operand")
10982 (match_operand:DGPR 1 "s_operand"))
10984 (unspec_volatile:DGPR
10986 (match_operand:DGPR 2 "register_operand")
10987 (match_operand:DGPR 3 "register_operand")]
10989 (set (match_operand 4 "cc_reg_operand")
10991 "GET_MODE (operands[4]) == CCZmode
10992 || GET_MODE (operands[4]) == CCZ1mode"
10995 = gen_rtx_COMPARE (GET_MODE (operands[4]), operands[1], operands[2]);
10999 (define_insn "*atomic_compare_and_swap<mode>_1"
11000 [(set (match_operand:TDI 0 "register_operand" "=r")
11001 (match_operand:TDI 1 "nonsym_memory_operand" "+S"))
11003 (unspec_volatile:TDI
11005 (match_operand:TDI 2 "register_operand" "0")
11006 (match_operand:TDI 3 "register_operand" "r")]
11008 (set (reg CC_REGNUM)
11009 (compare (match_dup 1) (match_dup 2)))]
11011 && s390_match_ccmode (insn, CCZ1mode)"
11012 "c<td>sg\t%0,%3,%S1"
11013 [(set_attr "op_type" "RSY")
11014 (set_attr "type" "sem")])
11017 (define_insn "*atomic_compare_and_swapdi_2"
11018 [(set (match_operand:DI 0 "register_operand" "=r,r")
11019 (match_operand:DI 1 "nonsym_memory_operand" "+Q,S"))
11021 (unspec_volatile:DI
11023 (match_operand:DI 2 "register_operand" "0,0")
11024 (match_operand:DI 3 "register_operand" "r,r")]
11026 (set (reg CC_REGNUM)
11027 (compare (match_dup 1) (match_dup 2)))]
11029 && s390_match_ccmode (insn, CCZ1mode)"
11033 [(set_attr "op_type" "RS,RSY")
11034 (set_attr "cpu_facility" "*,longdisp")
11035 (set_attr "type" "sem")])
11038 (define_insn "*atomic_compare_and_swapsi_3"
11039 [(set (match_operand:SI 0 "register_operand" "=r,r")
11040 (match_operand:SI 1 "nonsym_memory_operand" "+Q,S"))
11042 (unspec_volatile:SI
11044 (match_operand:SI 2 "register_operand" "0,0")
11045 (match_operand:SI 3 "register_operand" "r,r")]
11047 (set (reg CC_REGNUM)
11048 (compare (match_dup 1) (match_dup 2)))]
11049 "s390_match_ccmode (insn, CCZ1mode)"
11053 [(set_attr "op_type" "RS,RSY")
11054 (set_attr "cpu_facility" "*,longdisp")
11055 (set_attr "type" "sem")])
11058 ; Other atomic instruction patterns.
11061 ; z196 load and add, xor, or and and instructions
11063 (define_expand "atomic_fetch_<atomic><mode>"
11064 [(match_operand:GPR 0 "register_operand") ;; val out
11066 (match_operand:GPR 1 "memory_operand") ;; memory
11067 (match_operand:GPR 2 "register_operand")) ;; val in
11068 (match_operand:SI 3 "const_int_operand")] ;; model
11071 if (MEM_ALIGN (operands[1]) < GET_MODE_BITSIZE (GET_MODE (operands[1])))
11074 emit_insn (gen_atomic_fetch_<atomic><mode>_iaf
11075 (operands[0], operands[1], operands[2]));
11079 ; lan, lang, lao, laog, lax, laxg, laa, laag
11080 (define_insn "atomic_fetch_<atomic><mode>_iaf"
11081 [(set (match_operand:GPR 0 "register_operand" "=d")
11082 (match_operand:GPR 1 "memory_operand" "+S"))
11084 (unspec_volatile:GPR
11085 [(ATOMIC_Z196:GPR (match_dup 1)
11086 (match_operand:GPR 2 "general_operand" "d"))]
11087 UNSPECV_ATOMIC_OP))
11088 (clobber (reg:CC CC_REGNUM))]
11090 "la<noxa><g>\t%0,%2,%1"
11091 [(set_attr "op_type" "RSY")
11092 (set_attr "type" "sem")])
11094 ;; For SImode and larger, the optabs.cc code will do just fine in
11095 ;; expanding a compare-and-swap loop. For QI/HImode, we can do
11096 ;; better by expanding our own loop.
11098 (define_expand "atomic_<atomic><mode>"
11100 (match_operand:HQI 0 "memory_operand") ;; memory
11101 (match_operand:HQI 1 "general_operand")) ;; val in
11102 (match_operand:SI 2 "const_int_operand")] ;; model
11105 s390_expand_atomic (<MODE>mode, <CODE>, NULL_RTX, operands[0],
11106 operands[1], false);
11110 (define_expand "atomic_fetch_<atomic><mode>"
11111 [(match_operand:HQI 0 "register_operand") ;; val out
11113 (match_operand:HQI 1 "memory_operand") ;; memory
11114 (match_operand:HQI 2 "general_operand")) ;; val in
11115 (match_operand:SI 3 "const_int_operand")] ;; model
11118 s390_expand_atomic (<MODE>mode, <CODE>, operands[0], operands[1],
11119 operands[2], false);
11123 (define_expand "atomic_<atomic>_fetch<mode>"
11124 [(match_operand:HQI 0 "register_operand") ;; val out
11126 (match_operand:HQI 1 "memory_operand") ;; memory
11127 (match_operand:HQI 2 "general_operand")) ;; val in
11128 (match_operand:SI 3 "const_int_operand")] ;; model
11131 s390_expand_atomic (<MODE>mode, <CODE>, operands[0], operands[1],
11132 operands[2], true);
11136 ;; Pattern to implement atomic_exchange with a compare-and-swap loop. The code
11137 ;; generated by the middleend is not good.
11138 (define_expand "atomic_exchange<mode>"
11139 [(match_operand:DINT 0 "register_operand") ;; val out
11140 (match_operand:DINT 1 "s_operand") ;; memory
11141 (match_operand:DINT 2 "general_operand") ;; val in
11142 (match_operand:SI 3 "const_int_operand")] ;; model
11145 if (<MODE>mode != QImode
11146 && MEM_ALIGN (operands[1]) < GET_MODE_BITSIZE (<MODE>mode))
11148 if (<MODE>mode == HImode || <MODE>mode == QImode)
11149 s390_expand_atomic (<MODE>mode, SET, operands[0], operands[1], operands[2],
11151 else if (<MODE>mode == SImode || TARGET_ZARCH)
11152 s390_expand_atomic_exchange_tdsi (operands[0], operands[1], operands[2]);
11159 ;;- Miscellaneous instructions.
11163 ; allocate stack instruction pattern(s).
11166 (define_expand "allocate_stack"
11167 [(match_operand 0 "general_operand" "")
11168 (match_operand 1 "general_operand" "")]
11171 rtx temp = gen_reg_rtx (Pmode);
11173 emit_move_insn (temp, s390_back_chain_rtx ());
11175 if (flag_stack_clash_protection)
11176 anti_adjust_stack_and_probe_stack_clash (operands[1]);
11178 anti_adjust_stack (operands[1]);
11180 emit_move_insn (s390_back_chain_rtx (), temp);
11182 emit_move_insn (operands[0], virtual_stack_dynamic_rtx);
11186 (define_expand "@probe_stack2<mode>"
11187 [(set (reg:CCZ CC_REGNUM)
11188 (compare:CCZ (reg:W 0)
11189 (match_operand:W 0 "memory_operand")))
11190 (unspec_volatile [(const_int 0)] UNSPECV_BLOCKAGE)]
11193 (define_expand "probe_stack"
11194 [(match_operand 0 "memory_operand")]
11197 emit_insn (gen_probe_stack2 (word_mode, operands[0]));
11202 ; setjmp instruction pattern.
11205 (define_expand "builtin_setjmp_receiver"
11206 [(match_operand 0 "" "")]
11209 emit_insn (s390_load_got ());
11210 emit_use (pic_offset_table_rtx);
11214 ;; These patterns say how to save and restore the stack pointer. We need not
11215 ;; save the stack pointer at function level since we are careful to
11216 ;; preserve the backchain. At block level, we have to restore the backchain
11217 ;; when we restore the stack pointer.
11219 ;; For nonlocal gotos, we must save both the stack pointer and its
11220 ;; backchain and restore both. Note that in the nonlocal case, the
11221 ;; save area is a memory location.
11223 (define_expand "save_stack_function"
11224 [(match_operand 0 "general_operand" "")
11225 (match_operand 1 "general_operand" "")]
11229 (define_expand "restore_stack_function"
11230 [(match_operand 0 "general_operand" "")
11231 (match_operand 1 "general_operand" "")]
11235 (define_expand "restore_stack_block"
11236 [(match_operand 0 "register_operand" "")
11237 (match_operand 1 "register_operand" "")]
11240 rtx temp = gen_reg_rtx (Pmode);
11242 emit_move_insn (temp, s390_back_chain_rtx ());
11243 emit_move_insn (operands[0], operands[1]);
11244 emit_move_insn (s390_back_chain_rtx (), temp);
11249 (define_expand "save_stack_nonlocal"
11250 [(match_operand 0 "memory_operand" "")
11251 (match_operand 1 "register_operand" "")]
11254 rtx base = gen_rtx_REG (Pmode, BASE_REGNUM);
11256 /* Copy the backchain to the first word, sp to the second and the
11257 literal pool base to the third. */
11259 rtx save_bc = adjust_address (operands[0], Pmode, 0);
11260 rtx save_sp = adjust_address (operands[0], Pmode, GET_MODE_SIZE (Pmode));
11261 rtx save_bp = adjust_address (operands[0], Pmode, 2 * GET_MODE_SIZE (Pmode));
11263 if (TARGET_BACKCHAIN)
11264 emit_move_insn (save_bc, force_reg (Pmode, s390_back_chain_rtx ()));
11266 emit_move_insn (save_sp, operands[1]);
11267 emit_move_insn (save_bp, base);
11272 (define_expand "restore_stack_nonlocal"
11273 [(match_operand 0 "register_operand" "")
11274 (match_operand 1 "memory_operand" "")]
11277 rtx base = gen_rtx_REG (Pmode, BASE_REGNUM);
11278 rtx temp = NULL_RTX;
11280 /* Restore the backchain from the first word, sp from the second and the
11281 literal pool base from the third. */
11283 rtx save_bc = adjust_address (operands[1], Pmode, 0);
11284 rtx save_sp = adjust_address (operands[1], Pmode, GET_MODE_SIZE (Pmode));
11285 rtx save_bp = adjust_address (operands[1], Pmode, 2 * GET_MODE_SIZE (Pmode));
11287 if (TARGET_BACKCHAIN)
11288 temp = force_reg (Pmode, save_bc);
11290 emit_move_insn (base, save_bp);
11291 emit_move_insn (operands[0], save_sp);
11294 emit_move_insn (s390_back_chain_rtx (), temp);
11300 (define_expand "exception_receiver"
11304 s390_set_has_landing_pad_p (true);
11309 ; nop instruction pattern(s).
11316 [(set_attr "op_type" "RR")])
11318 ; non-branch NOPs required for optimizing compare-and-branch patterns
11321 (define_insn "nop_lr0"
11322 [(unspec_volatile [(const_int 0)] UNSPECV_NOP_LR_0)]
11325 [(set_attr "op_type" "RR")
11326 (set_attr "z10prop" "z10_fr_E1")])
11328 (define_insn "nop_lr1"
11329 [(unspec_volatile [(const_int 0)] UNSPECV_NOP_LR_1)]
11332 [(set_attr "op_type" "RR")])
11334 ;;- Undeletable nops (used for hotpatching)
11336 (define_insn "nop_2_byte"
11337 [(unspec_volatile [(const_int 0)] UNSPECV_NOP_2_BYTE)]
11340 [(set_attr "op_type" "RR")])
11342 (define_insn "nop_4_byte"
11343 [(unspec_volatile [(const_int 0)] UNSPECV_NOP_4_BYTE)]
11346 [(set_attr "op_type" "RX")])
11348 (define_insn "nop_6_byte"
11349 [(unspec_volatile [(const_int 0)] UNSPECV_NOP_6_BYTE)]
11352 [(set_attr "op_type" "RIL")
11353 (set_attr "relative_long" "yes")])
11357 ; Special literal pool access instruction pattern(s).
11360 (define_insn "*pool_entry"
11361 [(unspec_volatile [(match_operand 0 "consttable_operand" "X")]
11362 UNSPECV_POOL_ENTRY)]
11365 machine_mode mode = GET_MODE (PATTERN (insn));
11366 unsigned int align = GET_MODE_BITSIZE (mode);
11367 s390_output_pool_entry (operands[0], mode, align);
11370 [(set (attr "length")
11371 (symbol_ref "GET_MODE_SIZE (GET_MODE (PATTERN (insn)))"))])
11373 (define_insn "pool_align"
11374 [(unspec_volatile [(match_operand 0 "const_int_operand" "n")]
11375 UNSPECV_POOL_ALIGN)]
11378 [(set (attr "length") (symbol_ref "INTVAL (operands[0])"))])
11380 (define_insn "pool_section_start"
11381 [(unspec_volatile [(const_int 1)] UNSPECV_POOL_SECTION)]
11384 switch_to_section (targetm.asm_out.function_rodata_section
11385 (current_function_decl, false));
11388 [(set_attr "length" "0")])
11390 (define_insn "pool_section_end"
11391 [(unspec_volatile [(const_int 0)] UNSPECV_POOL_SECTION)]
11394 switch_to_section (current_function_section ());
11397 [(set_attr "length" "0")])
11399 (define_insn "main_base_64"
11400 [(set (match_operand 0 "register_operand" "=a")
11401 (unspec [(label_ref (match_operand 1 "" ""))] UNSPEC_MAIN_BASE))]
11402 "GET_MODE (operands[0]) == Pmode"
11404 [(set_attr "op_type" "RIL")
11405 (set_attr "type" "larl")
11406 (set_attr "z10prop" "z10_fwd_A1")
11407 (set_attr "relative_long" "yes")])
11409 (define_insn "main_pool"
11410 [(set (match_operand 0 "register_operand" "=a")
11411 (unspec_volatile [(const_int 0)] UNSPECV_MAIN_POOL))]
11412 "GET_MODE (operands[0]) == Pmode"
11414 gcc_unreachable ();
11416 [(set (attr "type")
11417 (const_string "larl"))])
11419 (define_insn "reload_base_64"
11420 [(set (match_operand 0 "register_operand" "=a")
11421 (unspec [(label_ref (match_operand 1 "" ""))] UNSPEC_RELOAD_BASE))]
11422 "GET_MODE (operands[0]) == Pmode"
11424 [(set_attr "op_type" "RIL")
11425 (set_attr "type" "larl")
11426 (set_attr "z10prop" "z10_fwd_A1")])
11428 (define_insn "pool"
11429 [(unspec_volatile [(match_operand 0 "const_int_operand" "n")] UNSPECV_POOL)]
11432 gcc_unreachable ();
11434 [(set (attr "length") (symbol_ref "INTVAL (operands[0])"))])
11437 ;; Insns related to generating the function prologue and epilogue.
11441 (define_expand "prologue"
11442 [(use (const_int 0))]
11444 "s390_emit_prologue (); DONE;")
11446 (define_expand "epilogue"
11447 [(use (const_int 1))]
11449 "s390_emit_epilogue (false); DONE;")
11451 (define_expand "sibcall_epilogue"
11452 [(use (const_int 0))]
11454 "s390_emit_epilogue (true); DONE;")
11456 ;; A direct return instruction, without using an epilogue.
11457 (define_insn "<code>"
11459 "s390_can_use_<code>_insn ()"
11461 if (TARGET_INDIRECT_BRANCH_NOBP_RET)
11463 /* The target is always r14 so there is no clobber
11464 of r1 needed for pre z10 targets. */
11465 s390_indirect_branch_via_thunk (RETURN_REGNUM,
11468 s390_indirect_branch_type_return);
11472 return "br\t%%r14";
11474 [(set (attr "op_type")
11475 (if_then_else (match_test "TARGET_INDIRECT_BRANCH_NOBP_RET")
11476 (const_string "RIL")
11477 (const_string "RR")))
11478 (set (attr "mnemonic")
11479 (if_then_else (match_test "TARGET_INDIRECT_BRANCH_NOBP_RET")
11480 (const_string "jg")
11481 (const_string "br")))
11482 (set_attr "type" "jsr")
11483 (set_attr "atype" "agen")])
11486 (define_expand "return_use"
11489 (use (match_operand 0 "register_operand" "a"))])]
11492 if (!TARGET_CPU_Z10
11493 && TARGET_INDIRECT_BRANCH_NOBP_RET_OPTION)
11496 emit_jump_insn (gen_returndi_prez10 (operands[0]));
11498 emit_jump_insn (gen_returnsi_prez10 (operands[0]));
11503 (define_insn "*return<mode>"
11505 (use (match_operand:P 0 "register_operand" "a"))]
11506 "TARGET_CPU_Z10 || !TARGET_INDIRECT_BRANCH_NOBP_RET_OPTION"
11508 if (TARGET_INDIRECT_BRANCH_NOBP_RET)
11510 s390_indirect_branch_via_thunk (REGNO (operands[0]),
11513 s390_indirect_branch_type_return);
11519 [(set (attr "op_type")
11520 (if_then_else (match_test "TARGET_INDIRECT_BRANCH_NOBP_RET")
11521 (const_string "RIL")
11522 (const_string "RR")))
11523 (set (attr "mnemonic")
11524 (if_then_else (match_test "TARGET_INDIRECT_BRANCH_NOBP_RET")
11525 (const_string "jg")
11526 (const_string "br")))
11527 (set_attr "type" "jsr")
11528 (set_attr "atype" "agen")])
11530 (define_insn "return<mode>_prez10"
11532 (use (match_operand:P 0 "register_operand" "a"))
11533 (clobber (reg:P INDIRECT_BRANCH_THUNK_REGNUM))]
11534 "!TARGET_CPU_Z10 && TARGET_INDIRECT_BRANCH_NOBP_RET_OPTION"
11536 if (TARGET_INDIRECT_BRANCH_NOBP_RET)
11538 s390_indirect_branch_via_thunk (REGNO (operands[0]),
11541 s390_indirect_branch_type_return);
11547 [(set (attr "op_type")
11548 (if_then_else (match_test "TARGET_INDIRECT_BRANCH_NOBP_RET")
11549 (const_string "RIL")
11550 (const_string "RR")))
11551 (set (attr "mnemonic")
11552 (if_then_else (match_test "TARGET_INDIRECT_BRANCH_NOBP_RET")
11553 (const_string "jg")
11554 (const_string "br")))
11555 (set_attr "type" "jsr")
11556 (set_attr "atype" "agen")])
11559 ;; Instruction definition to extend a 31-bit pointer into a 64-bit
11560 ;; pointer. This is used for compatibility.
11562 (define_expand "ptr_extend"
11563 [(set (match_operand:DI 0 "register_operand" "=r")
11564 (match_operand:SI 1 "register_operand" "r"))]
11567 emit_insn (gen_anddi3 (operands[0],
11568 gen_lowpart (DImode, operands[1]),
11569 GEN_INT (0x7fffffff)));
11573 ;; Instruction definition to expand eh_return macro to support
11574 ;; swapping in special linkage return addresses.
11576 (define_expand "eh_return"
11577 [(use (match_operand 0 "register_operand" ""))]
11580 s390_emit_tpf_eh_return (operands[0]);
11585 ; Stack Protector Patterns
11588 (define_expand "stack_protect_set"
11589 [(set (match_operand 0 "memory_operand" "")
11590 (match_operand 1 "memory_operand" ""))]
11593 #ifdef TARGET_THREAD_SSP_OFFSET
11595 = gen_rtx_MEM (Pmode, gen_rtx_PLUS (Pmode, s390_get_thread_pointer (),
11596 GEN_INT (TARGET_THREAD_SSP_OFFSET)));
11599 emit_insn (gen_stack_protect_setdi (operands[0], operands[1]));
11601 emit_insn (gen_stack_protect_setsi (operands[0], operands[1]));
11606 (define_insn "stack_protect_set<mode>"
11607 [(set (match_operand:DSI 0 "memory_operand" "=Q")
11608 (unspec:DSI [(match_operand:DSI 1 "memory_operand" "Q")] UNSPEC_SP_SET))]
11610 "mvc\t%O0(%G0,%R0),%S1"
11611 [(set_attr "op_type" "SS")])
11613 (define_expand "stack_protect_test"
11614 [(set (reg:CC CC_REGNUM)
11615 (compare (match_operand 0 "memory_operand" "")
11616 (match_operand 1 "memory_operand" "")))
11617 (match_operand 2 "" "")]
11621 #ifdef TARGET_THREAD_SSP_OFFSET
11623 = gen_rtx_MEM (Pmode, gen_rtx_PLUS (Pmode, s390_get_thread_pointer (),
11624 GEN_INT (TARGET_THREAD_SSP_OFFSET)));
11627 emit_insn (gen_stack_protect_testdi (operands[0], operands[1]));
11629 emit_insn (gen_stack_protect_testsi (operands[0], operands[1]));
11631 cc_reg = gen_rtx_REG (CCZmode, CC_REGNUM);
11632 test = gen_rtx_EQ (VOIDmode, cc_reg, const0_rtx);
11633 emit_jump_insn (gen_cbranchcc4 (test, cc_reg, const0_rtx, operands[2]));
11637 (define_insn "stack_protect_test<mode>"
11638 [(set (reg:CCZ CC_REGNUM)
11639 (unspec:CCZ [(match_operand:DSI 0 "memory_operand" "Q")
11640 (match_operand:DSI 1 "memory_operand" "Q")] UNSPEC_SP_TEST))]
11642 "clc\t%O0(%G0,%R0),%S1"
11643 [(set_attr "op_type" "SS")])
11645 ; This is used in s390_emit_prologue in order to prevent insns
11646 ; adjusting the stack pointer to be moved over insns writing stack
11647 ; slots using a copy of the stack pointer in a different register.
11648 (define_insn "@stack_tie<mode>"
11649 [(set (match_operand:BLK 0 "memory_operand" "+m")
11650 (unspec:BLK [(match_dup 0)
11651 (match_operand:P 1 "register_operand" "r")] UNSPEC_TIE))]
11654 [(set_attr "length" "0")])
11657 (define_insn "stack_restore_from_fpr"
11658 [(set (reg:DI STACK_REGNUM)
11659 (match_operand:DI 0 "register_operand" "f"))
11660 (clobber (mem:BLK (scratch)))]
11663 [(set_attr "op_type" "RRE")])
11666 ; Data prefetch patterns
11669 (define_insn "prefetch"
11670 [(prefetch (match_operand 0 "address_operand" "ZT,X")
11671 (match_operand:SI 1 "const_int_operand" " n,n")
11672 (match_operand:SI 2 "const_int_operand" " n,n"))]
11675 switch (which_alternative)
11678 return INTVAL (operands[1]) == 1 ? "pfd\t2,%a0" : "pfd\t1,%a0";
11680 if (larl_operand (operands[0], Pmode))
11681 return INTVAL (operands[1]) == 1 ? "pfdrl\t2,%a0" : "pfdrl\t1,%a0";
11685 /* This might be reached for symbolic operands with an odd
11686 addend. We simply omit the prefetch for such rare cases. */
11691 [(set_attr "type" "load,larl")
11692 (set_attr "op_type" "RXY,RIL")
11693 (set_attr "z10prop" "z10_super")
11694 (set_attr "z196prop" "z196_alone")
11695 (set_attr "relative_long" "yes")])
11699 ; Byte swap instructions
11702 ; FIXME: There is also mvcin but we cannot use it since src and target
11704 ; lrvr, lrv, strv, lrvgr, lrvg, strvg
11705 (define_insn "bswap<mode>2"
11706 [(set (match_operand:GPR 0 "nonimmediate_operand" "=d,d,T")
11707 (bswap:GPR (match_operand:GPR 1 "nonimmediate_operand" " d,T,d")))]
11713 [(set_attr "type" "*,load,store")
11714 (set_attr "op_type" "RRE,RXY,RXY")
11715 (set_attr "z10prop" "z10_super")])
11717 (define_insn "bswaphi2"
11718 [(set (match_operand:HI 0 "nonimmediate_operand" "=d,d,T")
11719 (bswap:HI (match_operand:HI 1 "nonimmediate_operand" " d,T,d")))]
11725 [(set_attr "type" "*,load,store")
11726 (set_attr "op_type" "RRE,RXY,RXY")
11727 (set_attr "z10prop" "z10_super")])
11730 [(set (match_operand:HI 0 "register_operand" "")
11731 (bswap:HI (match_operand:HI 1 "register_operand" "")))]
11733 [(set (match_dup 2) (bswap:SI (match_dup 3)))
11734 (set (match_dup 2) (lshiftrt:SI (match_dup 2) (const_int 16)))]
11736 operands[2] = simplify_gen_subreg (SImode, operands[0], HImode, 0);
11737 operands[3] = simplify_gen_subreg (SImode, operands[1], HImode, 0);
11742 ; Population count instruction
11745 (define_insn "*popcountdi_z15_cc"
11746 [(set (reg CC_REGNUM)
11747 (compare (popcount:DI (match_operand:DI 1 "register_operand" "d"))
11749 (set (match_operand:DI 0 "register_operand" "=d")
11751 "TARGET_Z15 && s390_match_ccmode (insn, CCTmode)"
11753 [(set_attr "op_type" "RRF")])
11755 (define_insn "*popcountdi_z15_cconly"
11756 [(set (reg CC_REGNUM)
11757 (compare (popcount:DI (match_operand:DI 1 "register_operand" "d"))
11759 (clobber (match_scratch:DI 0 "=d"))]
11760 "TARGET_Z15 && s390_match_ccmode(insn, CCTmode)"
11762 [(set_attr "op_type" "RRF")])
11764 (define_insn "*popcountdi_z15"
11765 [(set (match_operand:DI 0 "register_operand" "=d")
11766 (popcount:DI (match_operand:DI 1 "register_operand" "d")))
11767 (clobber (reg:CC CC_REGNUM))]
11770 [(set_attr "op_type" "RRF")])
11772 ; The pre-z15 popcount instruction counts the bits of op1 in 8 byte
11773 ; portions and stores the result in the corresponding bytes in op0.
11774 (define_insn "*popcount<mode>_z196"
11775 [(set (match_operand:INT 0 "register_operand" "=d")
11776 (unspec:INT [(match_operand:INT 1 "register_operand" "d")] UNSPEC_POPCNT))
11777 (clobber (reg:CC CC_REGNUM))]
11780 [(set_attr "op_type" "RRE")])
11782 (define_expand "popcountdi2_z196"
11784 (parallel [(set (match_operand:DI 0 "register_operand" "")
11785 (unspec:DI [(match_operand:DI 1 "register_operand")]
11787 (clobber (reg:CC CC_REGNUM))])
11788 ; sllg op2, op0, 32
11789 (set (match_dup 2) (ashift:DI (match_dup 0) (const_int 32)))
11791 (parallel [(set (match_dup 0) (plus:DI (match_dup 0) (match_dup 2)))
11792 (clobber (reg:CC CC_REGNUM))])
11793 ; sllg op2, op0, 16
11795 (ashift:DI (match_dup 0) (const_int 16)))
11797 (parallel [(set (match_dup 0) (plus:DI (match_dup 0) (match_dup 2)))
11798 (clobber (reg:CC CC_REGNUM))])
11800 (set (match_dup 2) (ashift:DI (match_dup 0) (const_int 8)))
11802 (parallel [(set (match_dup 0) (plus:DI (match_dup 0) (match_dup 2)))
11803 (clobber (reg:CC CC_REGNUM))])
11804 ; srlg op0, op0, 56
11805 (set (match_dup 0) (lshiftrt:DI (match_dup 0) (const_int 56)))]
11807 "operands[2] = gen_reg_rtx (DImode);")
11809 (define_expand "popcountdi2"
11811 [(set (match_operand:DI 0 "register_operand" "")
11812 (popcount:DI (match_operand:DI 1 "register_operand")))
11813 (clobber (reg:CC CC_REGNUM))])]
11818 emit_insn (gen_popcountdi2_z196 (operands[0], operands[1]));
11823 (define_expand "popcountsi2_z196"
11825 (parallel [(set (match_operand:SI 0 "register_operand" "")
11826 (unspec:SI [(match_operand:SI 1 "register_operand")]
11828 (clobber (reg:CC CC_REGNUM))])
11829 ; sllk op2, op0, 16
11831 (ashift:SI (match_dup 0) (const_int 16)))
11833 (parallel [(set (match_dup 0) (plus:SI (match_dup 0) (match_dup 2)))
11834 (clobber (reg:CC CC_REGNUM))])
11836 (set (match_dup 2) (ashift:SI (match_dup 0) (const_int 8)))
11838 (parallel [(set (match_dup 0) (plus:SI (match_dup 0) (match_dup 2)))
11839 (clobber (reg:CC CC_REGNUM))])
11841 (set (match_dup 0) (lshiftrt:SI (match_dup 0) (const_int 24)))]
11843 "operands[2] = gen_reg_rtx (SImode);")
11845 ; popcount always counts on the full 64 bit. With the z196 version
11846 ; counting bits per byte we just ignore the upper 4 bytes. With the
11847 ; z15 version we have to zero out the upper 32 bits first.
11848 (define_expand "popcountsi2"
11849 [(set (match_dup 2)
11850 (zero_extend:DI (match_operand:SI 1 "register_operand")))
11851 (parallel [(set (match_dup 3) (popcount:DI (match_dup 2)))
11852 (clobber (reg:CC CC_REGNUM))])
11853 (set (match_operand:SI 0 "register_operand")
11854 (subreg:SI (match_dup 3) 4))]
11859 emit_insn (gen_popcountsi2_z196 (operands[0], operands[1]));
11864 operands[2] = gen_reg_rtx (DImode);
11865 operands[3] = gen_reg_rtx (DImode);
11869 (define_expand "popcounthi2_z196"
11871 (parallel [(set (match_dup 2)
11872 (unspec:HI [(match_operand:HI 1 "register_operand")]
11874 (clobber (reg:CC CC_REGNUM))])
11876 (set (match_dup 3) (subreg:SI (match_dup 2) 0))
11878 (set (match_dup 4) (lshiftrt:SI (match_dup 3) (const_int 8)))
11880 (parallel [(set (match_dup 3) (plus:SI (match_dup 3) (match_dup 4)))
11881 (clobber (reg:CC CC_REGNUM))])
11883 (parallel [(set (match_operand:HI 0 "register_operand" "")
11884 (and:HI (subreg:HI (match_dup 3) 2) (const_int 255)))
11885 (clobber (reg:CC CC_REGNUM))])]
11888 operands[2] = gen_reg_rtx (HImode);
11889 operands[3] = gen_reg_rtx (SImode);
11890 operands[4] = gen_reg_rtx (SImode);
11893 (define_expand "popcounthi2"
11894 [(set (match_dup 2)
11895 (zero_extend:DI (match_operand:HI 1 "register_operand")))
11896 (parallel [(set (match_dup 3) (popcount:DI (match_dup 2)))
11897 (clobber (reg:CC CC_REGNUM))])
11898 (set (match_operand:HI 0 "register_operand")
11899 (subreg:HI (match_dup 3) 6))]
11904 emit_insn (gen_popcounthi2_z196 (operands[0], operands[1]));
11909 operands[2] = gen_reg_rtx (DImode);
11910 operands[3] = gen_reg_rtx (DImode);
11914 ; For popcount on a single byte the old z196 style popcount
11915 ; instruction is ideal. Since it anyway does a byte-wise popcount we
11916 ; just use it instead of zero extending the QImode input to DImode and
11917 ; using the z15 popcount variant.
11918 (define_expand "popcountqi2"
11920 (parallel [(set (match_operand:QI 0 "register_operand" "")
11921 (unspec:QI [(match_operand:QI 1 "register_operand")]
11923 (clobber (reg:CC CC_REGNUM))])]
11928 ;;- Copy sign instructions
11931 (define_insn "copysign<mode>3<tf_fpr>"
11932 [(set (match_operand:FP 0 "register_operand" "=f")
11933 (copysign:FP (match_operand:FP 1 "register_operand" "<fT0>")
11934 (match_operand:FP 2 "register_operand" "f")))]
11937 [(set_attr "op_type" "RRF")
11938 (set_attr "type" "fsimp<type>")])
11942 ;;- Transactional execution instructions
11945 ; This splitter helps combine to make use of CC directly when
11946 ; comparing the integer result of a tbegin builtin with a constant.
11947 ; The unspec is already removed by canonicalize_comparison. So this
11948 ; splitters only job is to turn the PARALLEL into separate insns
11949 ; again. Unfortunately this only works with the very first cc/int
11950 ; compare since combine is not able to deal with data flow across
11951 ; basic block boundaries.
11953 ; It needs to be an insn pattern as well since combine does not apply
11954 ; the splitter directly. Combine would only use it if it actually
11955 ; would reduce the number of instructions.
11956 (define_insn_and_split "*ccraw_to_int"
11959 (match_operator 0 "s390_eqne_operator"
11960 [(reg:CCRAW CC_REGNUM)
11961 (match_operand 1 "const_int_operand" "")])
11962 (label_ref (match_operand 2 "" ""))
11964 (set (match_operand:SI 3 "register_operand" "=d")
11965 (unspec:SI [(reg:CCRAW CC_REGNUM)] UNSPEC_CC_TO_INT))]
11969 [(set (match_dup 3)
11970 (unspec:SI [(reg:CCRAW CC_REGNUM)] UNSPEC_CC_TO_INT))
11972 (if_then_else (match_op_dup 0 [(reg:CCRAW CC_REGNUM) (match_dup 1)])
11973 (label_ref (match_dup 2))
11977 ; Non-constrained transaction begin
11979 (define_expand "tbegin"
11980 [(match_operand:SI 0 "register_operand" "")
11981 (match_operand:BLK 1 "memory_operand" "")]
11984 s390_expand_tbegin (operands[0], operands[1], NULL_RTX, true);
11988 (define_expand "tbegin_nofloat"
11989 [(match_operand:SI 0 "register_operand" "")
11990 (match_operand:BLK 1 "memory_operand" "")]
11993 s390_expand_tbegin (operands[0], operands[1], NULL_RTX, false);
11997 (define_expand "tbegin_retry"
11998 [(match_operand:SI 0 "register_operand" "")
11999 (match_operand:BLK 1 "memory_operand" "")
12000 (match_operand:SI 2 "general_operand" "")]
12003 s390_expand_tbegin (operands[0], operands[1], operands[2], true);
12007 (define_expand "tbegin_retry_nofloat"
12008 [(match_operand:SI 0 "register_operand" "")
12009 (match_operand:BLK 1 "memory_operand" "")
12010 (match_operand:SI 2 "general_operand" "")]
12013 s390_expand_tbegin (operands[0], operands[1], operands[2], false);
12017 ; Clobber VRs since they don't get restored
12018 (define_insn "tbegin_1_z13"
12019 [(set (reg:CCRAW CC_REGNUM)
12020 (unspec_volatile:CCRAW [(match_operand 0 "const_int_operand" "D")]
12022 (set (match_operand:BLK 1 "memory_operand" "=Q")
12023 (unspec_volatile:BLK [(match_dup 0)] UNSPECV_TBEGIN_TDB))
12024 (clobber (reg:TI 16)) (clobber (reg:TI 38))
12025 (clobber (reg:TI 17)) (clobber (reg:TI 39))
12026 (clobber (reg:TI 18)) (clobber (reg:TI 40))
12027 (clobber (reg:TI 19)) (clobber (reg:TI 41))
12028 (clobber (reg:TI 20)) (clobber (reg:TI 42))
12029 (clobber (reg:TI 21)) (clobber (reg:TI 43))
12030 (clobber (reg:TI 22)) (clobber (reg:TI 44))
12031 (clobber (reg:TI 23)) (clobber (reg:TI 45))
12032 (clobber (reg:TI 24)) (clobber (reg:TI 46))
12033 (clobber (reg:TI 25)) (clobber (reg:TI 47))
12034 (clobber (reg:TI 26)) (clobber (reg:TI 48))
12035 (clobber (reg:TI 27)) (clobber (reg:TI 49))
12036 (clobber (reg:TI 28)) (clobber (reg:TI 50))
12037 (clobber (reg:TI 29)) (clobber (reg:TI 51))
12038 (clobber (reg:TI 30)) (clobber (reg:TI 52))
12039 (clobber (reg:TI 31)) (clobber (reg:TI 53))]
12040 ; CONST_OK_FOR_CONSTRAINT_P does not work with D constraint since D is
12041 ; not supposed to be used for immediates (see genpreds.cc).
12042 "TARGET_VX && INTVAL (operands[0]) >= 0 && INTVAL (operands[0]) <= 0xffff"
12044 [(set_attr "op_type" "SIL")])
12046 (define_insn "tbegin_1"
12047 [(set (reg:CCRAW CC_REGNUM)
12048 (unspec_volatile:CCRAW [(match_operand 0 "const_int_operand" "D")]
12050 (set (match_operand:BLK 1 "memory_operand" "=Q")
12051 (unspec_volatile:BLK [(match_dup 0)] UNSPECV_TBEGIN_TDB))
12052 (clobber (reg:DF 16))
12053 (clobber (reg:DF 17))
12054 (clobber (reg:DF 18))
12055 (clobber (reg:DF 19))
12056 (clobber (reg:DF 20))
12057 (clobber (reg:DF 21))
12058 (clobber (reg:DF 22))
12059 (clobber (reg:DF 23))
12060 (clobber (reg:DF 24))
12061 (clobber (reg:DF 25))
12062 (clobber (reg:DF 26))
12063 (clobber (reg:DF 27))
12064 (clobber (reg:DF 28))
12065 (clobber (reg:DF 29))
12066 (clobber (reg:DF 30))
12067 (clobber (reg:DF 31))]
12068 ; CONST_OK_FOR_CONSTRAINT_P does not work with D constraint since D is
12069 ; not supposed to be used for immediates (see genpreds.cc).
12070 "TARGET_HTM && INTVAL (operands[0]) >= 0 && INTVAL (operands[0]) <= 0xffff"
12072 [(set_attr "op_type" "SIL")])
12074 ; Same as above but without the FPR clobbers
12075 (define_insn "tbegin_nofloat_1"
12076 [(set (reg:CCRAW CC_REGNUM)
12077 (unspec_volatile:CCRAW [(match_operand 0 "const_int_operand" "D")]
12079 (set (match_operand:BLK 1 "memory_operand" "=Q")
12080 (unspec_volatile:BLK [(match_dup 0)] UNSPECV_TBEGIN_TDB))]
12081 "TARGET_HTM && INTVAL (operands[0]) >= 0 && INTVAL (operands[0]) <= 0xffff"
12083 [(set_attr "op_type" "SIL")])
12086 ; Constrained transaction begin
12088 (define_expand "tbeginc"
12089 [(set (reg:CCRAW CC_REGNUM)
12090 (unspec_volatile:CCRAW [(const_int TBEGINC_MASK)]
12095 (define_insn "*tbeginc_1"
12096 [(set (reg:CCRAW CC_REGNUM)
12097 (unspec_volatile:CCRAW [(match_operand 0 "const_int_operand" " D")]
12099 "TARGET_HTM && INTVAL (operands[0]) >= 0 && INTVAL (operands[0]) <= 0xffff"
12101 [(set_attr "op_type" "SIL")])
12105 (define_expand "tend"
12106 [(set (reg:CCRAW CC_REGNUM)
12107 (unspec_volatile:CCRAW [(const_int 0)] UNSPECV_TEND))
12108 (set (match_operand:SI 0 "register_operand" "")
12109 (unspec:SI [(reg:CCRAW CC_REGNUM)] UNSPEC_CC_TO_INT))]
12113 (define_insn "*tend_1"
12114 [(set (reg:CCRAW CC_REGNUM)
12115 (unspec_volatile:CCRAW [(const_int 0)] UNSPECV_TEND))]
12118 [(set_attr "op_type" "S")])
12120 ; Transaction abort
12122 (define_expand "tabort"
12123 [(unspec_volatile [(match_operand:SI 0 "nonmemory_operand" "")]
12127 if (CONST_INT_P (operands[0])
12128 && INTVAL (operands[0]) >= 0 && INTVAL (operands[0]) <= 255)
12130 error ("invalid transaction abort code: %wd (values in range 0 "
12131 "through 255 are reserved)", INTVAL (operands[0]));
12136 (define_insn "*tabort_1"
12137 [(unspec_volatile [(match_operand:SI 0 "nonmemory_operand" "aJ")]
12141 [(set_attr "op_type" "S")])
12143 (define_insn "*tabort_1_plus"
12144 [(unspec_volatile [(plus:SI (match_operand:SI 0 "register_operand" "a")
12145 (match_operand:SI 1 "const_int_operand" "J"))]
12147 "TARGET_HTM && CONST_OK_FOR_CONSTRAINT_P (INTVAL (operands[1]), 'J', \"J\")"
12149 [(set_attr "op_type" "S")])
12151 ; Transaction extract nesting depth
12153 (define_insn "etnd"
12154 [(set (match_operand:SI 0 "register_operand" "=d")
12155 (unspec_volatile:SI [(const_int 0)] UNSPECV_ETND))]
12158 [(set_attr "op_type" "RRE")])
12160 ; Non-transactional store
12162 (define_insn "ntstg"
12163 [(set (match_operand:DI 0 "memory_operand" "=T")
12164 (unspec_volatile:DI [(match_operand:DI 1 "register_operand" "d")]
12168 [(set_attr "op_type" "RXY")])
12170 ; Transaction perform processor assist
12172 (define_expand "tx_assist"
12173 [(unspec_volatile [(match_operand:SI 0 "register_operand" "")
12174 (reg:SI GPR0_REGNUM)
12175 (const_int PPA_TX_ABORT)]
12180 (define_insn "*ppa"
12181 [(unspec_volatile [(match_operand:SI 0 "register_operand" "d")
12182 (match_operand:SI 1 "register_operand" "d")
12183 (match_operand 2 "const_int_operand" "I")]
12185 "(TARGET_ZEC12 || TARGET_HTM) && INTVAL (operands[2]) < 16"
12187 [(set_attr "op_type" "RRF")])
12190 ; Set and get floating point control register
12192 (define_insn "sfpc"
12193 [(unspec_volatile [(match_operand:SI 0 "register_operand" "d")]
12195 "TARGET_HARD_FLOAT"
12198 (define_insn "efpc"
12199 [(set (match_operand:SI 0 "register_operand" "=d")
12200 (unspec_volatile:SI [(const_int 0)] UNSPECV_EFPC))]
12201 "TARGET_HARD_FLOAT"
12205 ; Load count to block boundary
12207 (define_insn "lcbb"
12208 [(set (match_operand:SI 0 "register_operand" "=d")
12209 (unspec:SI [(match_operand 1 "address_operand" "ZR")
12210 (match_operand:SI 2 "immediate_operand" "C")] UNSPEC_LCBB))
12211 (clobber (reg:CC CC_REGNUM))]
12214 [(set_attr "op_type" "VRX")])
12216 ; Handle -fsplit-stack.
12218 (define_expand "split_stack_prologue"
12222 s390_expand_split_stack_prologue ();
12226 ;; If there are operand 0 bytes available on the stack, jump to
12229 (define_expand "split_stack_space_check"
12230 [(set (pc) (if_then_else
12231 (ltu (minus (reg 15)
12232 (match_operand 0 "register_operand"))
12233 (unspec [(const_int 0)] UNSPEC_STACK_CHECK))
12234 (label_ref (match_operand 1))
12238 /* Offset from thread pointer to __private_ss. */
12239 int psso = TARGET_64BIT ? 0x38 : 0x20;
12240 rtx tp = s390_get_thread_pointer ();
12241 rtx guard = gen_rtx_MEM (Pmode, plus_constant (Pmode, tp, psso));
12242 rtx reg = gen_reg_rtx (Pmode);
12245 emit_insn (gen_subdi3 (reg, stack_pointer_rtx, operands[0]));
12247 emit_insn (gen_subsi3 (reg, stack_pointer_rtx, operands[0]));
12248 cc = s390_emit_compare (GT, reg, guard);
12249 s390_emit_jump (operands[1], cc);
12254 ;; Call to __morestack used by the split stack support
12256 ; The insn has 3 parts:
12257 ; 1. A jump to the call done label. The jump will be done as part of
12258 ; __morestack and will not be explicitly emitted to the insn stream.
12259 ; 2. The call of __morestack including a use for r1 which is supposed to
12260 ; point to the parameter block for __morestack.
12261 ; 3. 3 USES whose values together with the call done label will be
12262 ; used to emit the parameter block to the .rodata section. This
12263 ; needs to be tied into the same insn as 1. since the call done
12264 ; label is emitted also as part of the parm block. In order to
12265 ; allow the edge to the BB with the call done label to be
12266 ; redirected both need to make use of the same label_ref.
12268 (define_insn "@split_stack_call<mode>"
12269 [(set (pc) (label_ref (match_operand 2 "" ""))) ; call done label
12270 (set (reg:P 1) (unspec_volatile:P [(match_operand 0 "bras_sym_operand" "X")
12272 UNSPECV_SPLIT_STACK_CALL))
12273 (use (label_ref (match_operand 1 "" "X"))) ; parm block label
12274 (use (match_operand 3 "const_int_operand" "X")) ; frame size
12275 (use (match_operand 4 "const_int_operand" "X"))] ; arg size
12278 s390_output_split_stack_data (operands[1], operands[2], operands[3], operands[4]);
12279 return "jg\t%0%K0";
12281 [(set_attr "op_type" "RIL")
12282 (set_attr "type" "branch")])
12284 ; As above but with a conditional jump
12286 (define_insn "@split_stack_cond_call<mode>"
12289 (match_operand 5 "" "") ; condition
12290 (label_ref (match_operand 2 "" "")) ; call done label
12292 (set (reg:P 1) (unspec_volatile:P [(match_operand 0 "bras_sym_operand" "X")
12294 UNSPECV_SPLIT_STACK_CALL))
12295 (use (label_ref (match_operand 1 "" "X"))) ; parm block label
12296 (use (match_operand 3 "const_int_operand" "X")) ; frame size
12297 (use (match_operand 4 "const_int_operand" "X"))] ; arg size
12300 s390_output_split_stack_data (operands[1], operands[2], operands[3], operands[4]);
12301 return "jg%C5\t%0";
12303 [(set_attr "op_type" "RIL")
12304 (set_attr "type" "branch")])
12307 (define_insn "osc_break"
12308 [(unspec_volatile [(const_int 0)] UNSPECV_OSC_BREAK)]
12311 [(set_attr "op_type" "RR")])
12313 (define_expand "speculation_barrier"
12314 [(unspec_volatile [(reg:SI GPR0_REGNUM)
12315 (reg:SI GPR0_REGNUM)
12316 (const_int PPA_OOO_BARRIER)]
12321 (define_expand "rawmemchr<SINT:mode>"
12322 [(match_operand 0 "register_operand")
12323 (match_operand 1 "memory_operand")
12324 (match_operand:SINT 2 "const_int_operand")]
12326 "s390_rawmemchr(<SINT:MODE>mode, operands[0], operands[1], operands[2]); DONE;")