1 ;;- Machine description for GNU compiler -- S/390 / zSeries version.
2 ;; Copyright (C) 1999-2018 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" [
65 ; Convert CC into a str comparison result and copy it into an
67 ; cc0->0, cc1->1, cc2->-1, (cc3->-1)
68 UNSPEC_STRCMPCC_TO_INT
70 ; Copy CC as is into the lower 2 bits of an integer register
73 ; The right hand side of an setmem
76 ; GOT/PLT and lt-relative accesses
97 ; TLS relocation specifiers
113 ; Stack Smashing Protector
117 ; Split stack support
120 ; Test Data Class (TDC)
132 UNSPEC_FPINT_NEARBYINT
141 UNSPEC_VEC_SMULT_EVEN
142 UNSPEC_VEC_UMULT_EVEN
156 UNSPEC_VEC_INSERT_AND_ZERO
157 UNSPEC_VEC_LOAD_BNDRY
159 UNSPEC_VEC_LOAD_LEN_R
163 UNSPEC_VEC_PACK_SATURATE
164 UNSPEC_VEC_PACK_SATURATE_CC
165 UNSPEC_VEC_PACK_SATURATE_GENCC
166 UNSPEC_VEC_PACK_UNSIGNED_SATURATE
167 UNSPEC_VEC_PACK_UNSIGNED_SATURATE_CC
168 UNSPEC_VEC_PACK_UNSIGNED_SATURATE_GENCC
173 UNSPEC_VEC_STORE_LEN_R
181 UNSPEC_VEC_ADDEC_U128
186 UNSPEC_VEC_GFMSUM_128
187 UNSPEC_VEC_GFMSUM_ACCUM
188 UNSPEC_VEC_GFMSUM_ACCUM_128
205 UNSPEC_VEC_SUBEC_U128
231 UNSPEC_VEC_VFLL ; vector fp load lengthened
232 UNSPEC_VEC_VFLR ; vector fp load rounded
244 ;; UNSPEC_VOLATILE usage
247 (define_c_enum "unspecv" [
269 ; Non-branch nops used for compare-and-branch adjustments on z10
273 ; Hotpatching (unremovable NOPs)
278 ; Transactional Execution support
288 ; Set and get floating point control register
292 ; Split stack support
293 UNSPECV_SPLIT_STACK_CALL
294 UNSPECV_SPLIT_STACK_DATA
303 ; Registers with special meaning
307 ; Sibling call register.
309 ; A call-clobbered reg which can be used in indirect branch thunks
310 (INDIRECT_BRANCH_THUNK_REGNUM 1)
311 ; Literal pool base register.
313 ; Return address register.
315 ; Stack pointer register.
317 ; Condition code register.
319 ; Thread local storage pointer register.
323 ; Hardware register names
327 ; General purpose registers
332 ; Floating point registers.
356 ; Rounding modes for binary floating point numbers
359 (BFP_RND_NEAREST_TIE_AWAY_FROM_0 1)
360 (BFP_RND_PREP_FOR_SHORT_PREC 3)
361 (BFP_RND_NEAREST_TIE_TO_EVEN 4)
363 (BFP_RND_TOWARD_INF 6)
364 (BFP_RND_TOWARD_MINF 7)])
366 ; Rounding modes for decimal floating point numbers
367 ; 1-7 were introduced with the floating point extension facility
368 ; available with z196
369 ; With these rounding modes (1-7) a quantum exception might occur
370 ; which is suppressed for the other modes.
373 (DFP_RND_NEAREST_TIE_AWAY_FROM_0_QUANTEXC 1)
374 (DFP_RND_CURRENT_QUANTEXC 2)
375 (DFP_RND_PREP_FOR_SHORT_PREC_QUANTEXC 3)
376 (DFP_RND_NEAREST_TIE_TO_EVEN_QUANTEXC 4)
377 (DFP_RND_TOWARD_0_QUANTEXC 5)
378 (DFP_RND_TOWARD_INF_QUANTEXC 6)
379 (DFP_RND_TOWARD_MINF_QUANTEXC 7)
380 (DFP_RND_NEAREST_TIE_TO_EVEN 8)
382 (DFP_RND_TOWARD_INF 10)
383 (DFP_RND_TOWARD_MINF 11)
384 (DFP_RND_NEAREST_TIE_AWAY_FROM_0 12)
385 (DFP_RND_NEAREST_TIE_TO_0 13)
386 (DFP_RND_AWAY_FROM_0 14)
387 (DFP_RND_PREP_FOR_SHORT_PREC 15)])
390 ;; PFPO GPR0 argument format
395 ; PFPO operation type
396 (PFPO_CONVERT 0x1000000)
398 (PFPO_OP_TYPE_SF 0x5)
399 (PFPO_OP_TYPE_DF 0x6)
400 (PFPO_OP_TYPE_TF 0x7)
401 (PFPO_OP_TYPE_SD 0x8)
402 (PFPO_OP_TYPE_DD 0x9)
403 (PFPO_OP_TYPE_TD 0xa)
404 ; Bitposition of operand types
405 (PFPO_OP0_TYPE_SHIFT 16)
406 (PFPO_OP1_TYPE_SHIFT 8)
407 ; Decide whether current DFP or BFD rounding mode should be used
408 ; for the conversion.
409 (PFPO_RND_MODE_DFP 0)
410 (PFPO_RND_MODE_BFP 1)
415 ; Immediate values which can be used as the third operand to the
416 ; perform processor assist instruction
420 (PPA_OOO_BARRIER 15)])
422 ; Immediate operands for tbegin and tbeginc
423 (define_constants [(TBEGIN_MASK 65292)]) ; 0xff0c
424 (define_constants [(TBEGINC_MASK 65288)]) ; 0xff08
426 ;; Instruction operand type as used in the Principles of Operation.
427 ;; Used to determine defaults for length and other attribute values.
429 (define_attr "op_type"
430 "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"
433 ;; Instruction type attribute used for scheduling.
435 (define_attr "type" "none,integer,load,lr,la,larl,lm,stm,
436 cs,vs,store,sem,idiv,
437 imulhi,imulsi,imuldi,
438 branch,jsr,fsimptf,fsimpdf,fsimpsf,fhex,
439 floadtf,floaddf,floadsf,fstoredf,fstoresf,
440 fmultf,fmuldf,fmulsf,fdivtf,fdivdf,fdivsf,
441 ftoi,fsqrttf,fsqrtdf,fsqrtsf,
443 ftrunctf,ftruncdf, ftruncsd, ftruncdd,
444 itoftf, itofdf, itofsf, itofdd, itoftd,
445 fdivdd, fdivtd, floaddd, floadsd, fmuldd, fmultd,
446 fsimpdd, fsimpsd, fsimptd, fstoredd, fstoresd,
448 (cond [(eq_attr "op_type" "NN") (const_string "other")
449 (eq_attr "op_type" "SS") (const_string "cs")]
450 (const_string "integer")))
452 ;; Another attribute used for scheduling purposes:
453 ;; agen: Instruction uses the address generation unit
454 ;; reg: Instruction does not use the agen unit
456 (define_attr "atype" "agen,reg"
457 (if_then_else (eq_attr "op_type" "E,RR,RI,RRE,RSI,RIL,RIE,RRF")
459 (const_string "agen")))
461 ;; Properties concerning Z10 execution grouping and value forwarding.
462 ;; z10_super: instruction is superscalar.
463 ;; z10_super_c: instruction is superscalar and meets the condition of z10_c.
464 ;; z10_fwd: The instruction reads the value of an operand and stores it into a
465 ;; target register. It can forward this value to a second instruction that reads
466 ;; the same register if that second instruction is issued in the same group.
467 ;; z10_rec: The instruction is in the T pipeline and reads a register. If the
468 ;; instruction in the S pipe writes to the register, then the T instruction
469 ;; can immediately read the new value.
470 ;; z10_fr: union of Z10_fwd and z10_rec.
471 ;; z10_c: second operand of instruction is a register and read with complemented bits.
473 ;; An additional suffix A1, A3, or E1 indicates the respective AGI bypass.
476 (define_attr "z10prop" "none,
477 z10_super, z10_super_E1, z10_super_A1, z10_super_c, z10_super_c_E1,
478 z10_fwd, z10_fwd_A1, z10_fwd_A3, z10_fwd_E1,
480 z10_fr, z10_fr_A3, z10_fr_E1,
482 (const_string "none"))
484 ;; Properties concerning Z196 decoding
485 ;; z196_alone: must group alone
486 ;; z196_end: ends a group
487 ;; z196_cracked: instruction is cracked or expanded
488 (define_attr "z196prop" "none,
489 z196_alone, z196_ends,
491 (const_string "none"))
493 ; mnemonics which only get defined through if_then_else currently
494 ; don't get added to the list values automatically and hence need to
496 (define_attr "mnemonic" "b,bas,basr,bc,bcr_flush,unknown" (const_string "unknown"))
500 (define_attr "length" ""
501 (cond [(eq_attr "op_type" "E,RR") (const_int 2)
502 (eq_attr "op_type" "RX,RI,RRE,RS,RSI,S,SI,RRF") (const_int 4)]
506 ;; Processor type. This attribute must exactly match the processor_type
507 ;; enumeration in s390.h.
509 (define_attr "cpu" "z900,z990,z9_109,z9_ec,z10,z196,zEC12,z13,z14"
510 (const (symbol_ref "s390_tune_attr")))
512 (define_attr "cpu_facility"
513 "standard,ieee,zarch,cpu_zarch,longdisp,extimm,dfp,z10,z196,zEC12,vx,z13,z14,vxe"
514 (const_string "standard"))
516 (define_attr "enabled" ""
517 (cond [(eq_attr "cpu_facility" "standard")
520 (and (eq_attr "cpu_facility" "ieee")
521 (match_test "TARGET_CPU_IEEE_FLOAT"))
524 (and (eq_attr "cpu_facility" "zarch")
525 (match_test "TARGET_ZARCH"))
528 (and (eq_attr "cpu_facility" "longdisp")
529 (match_test "TARGET_LONG_DISPLACEMENT"))
532 (and (eq_attr "cpu_facility" "extimm")
533 (match_test "TARGET_EXTIMM"))
536 (and (eq_attr "cpu_facility" "dfp")
537 (match_test "TARGET_DFP"))
540 (eq_attr "cpu_facility" "cpu_zarch")
543 (and (eq_attr "cpu_facility" "z10")
544 (match_test "TARGET_Z10"))
547 (and (eq_attr "cpu_facility" "z196")
548 (match_test "TARGET_Z196"))
551 (and (eq_attr "cpu_facility" "zEC12")
552 (match_test "TARGET_ZEC12"))
555 (and (eq_attr "cpu_facility" "vx")
556 (match_test "TARGET_VX"))
559 (and (eq_attr "cpu_facility" "z13")
560 (match_test "TARGET_Z13"))
563 (and (eq_attr "cpu_facility" "z14")
564 (match_test "TARGET_Z14"))
567 (and (eq_attr "cpu_facility" "vxe")
568 (match_test "TARGET_VXE"))
573 ;; Whether an instruction supports relative long addressing.
574 ;; Currently this corresponds to RIL-b and RIL-c instruction formats,
575 ;; but having a separate attribute, as opposed to reusing op_type,
576 ;; provides additional flexibility.
578 (define_attr "relative_long" "no,yes" (const_string "no"))
580 ;; Pipeline description for z900.
583 ;; Pipeline description for z990, z9-109 and z9-ec.
586 ;; Pipeline description for z10
589 ;; Pipeline description for z196
592 ;; Pipeline description for zEC12
595 ;; Pipeline description for z13
599 (include "predicates.md")
601 ;; Constraint definitions
602 (include "constraints.md")
609 (define_mode_iterator ALL [TI DI SI HI QI TF DF SF TD DD SD V1QI V2QI V4QI V8QI V16QI V1HI V2HI V4HI V8HI V1SI V2SI V4SI V1DI V2DI V1SF V2SF V4SF V1TI V1DF V2DF V1TF])
611 ;; These mode iterators allow floating point patterns to be generated from the
613 (define_mode_iterator FP_ALL [TF DF SF (TD "TARGET_HARD_DFP") (DD "TARGET_HARD_DFP")
614 (SD "TARGET_HARD_DFP")])
615 (define_mode_iterator FP [TF DF SF (TD "TARGET_HARD_DFP") (DD "TARGET_HARD_DFP")])
616 (define_mode_iterator BFP [TF DF SF])
617 (define_mode_iterator DFP [TD DD])
618 (define_mode_iterator DFP_ALL [TD DD SD])
619 (define_mode_iterator DSF [DF SF])
620 (define_mode_iterator SD_SF [SF SD])
621 (define_mode_iterator DD_DF [DF DD])
622 (define_mode_iterator TD_TF [TF TD])
624 ;; These mode iterators allow 31-bit and 64-bit GPR patterns to be generated
625 ;; from the same template.
626 (define_mode_iterator GPR [(DI "TARGET_ZARCH") SI])
627 (define_mode_iterator DGPR [(TI "TARGET_ZARCH") DI SI])
628 (define_mode_iterator DSI [DI SI])
629 (define_mode_iterator TDI [TI DI])
631 ;; These mode iterators allow :P to be used for patterns that operate on
632 ;; pointer-sized quantities. Exactly one of the two alternatives will match.
633 (define_mode_iterator P [(DI "TARGET_64BIT") (SI "!TARGET_64BIT")])
635 ;; These macros refer to the actual word_mode of the configuration.
636 ;; This is equal to Pmode except on 31-bit machines in zarch mode.
637 (define_mode_iterator DW [(TI "TARGET_ZARCH") (DI "!TARGET_ZARCH")])
638 (define_mode_iterator W [(DI "TARGET_ZARCH") (SI "!TARGET_ZARCH")])
640 ;; Used by the umul pattern to express modes having half the size.
641 (define_mode_attr DWH [(TI "DI") (DI "SI")])
642 (define_mode_attr dwh [(TI "di") (DI "si")])
644 ;; This mode iterator allows the QI and HI patterns to be defined from
645 ;; the same template.
646 (define_mode_iterator HQI [HI QI])
648 ;; This mode iterator allows the integer patterns to be defined from the
650 (define_mode_iterator INT [(DI "TARGET_ZARCH") SI HI QI])
651 (define_mode_iterator DINT [(TI "TARGET_ZARCH") DI SI HI QI])
652 (define_mode_iterator SINT [SI HI QI])
654 ;; This iterator allows some 'ashift' and 'lshiftrt' pattern to be defined from
655 ;; the same template.
656 (define_code_iterator SHIFT [ashift lshiftrt])
658 ;; This iterator allows r[ox]sbg to be defined with the same template
659 (define_code_iterator IXOR [ior xor])
661 ;; This iterator is used to expand the patterns for the nearest
662 ;; integer functions.
663 (define_int_iterator FPINT [UNSPEC_FPINT_FLOOR UNSPEC_FPINT_BTRUNC
664 UNSPEC_FPINT_ROUND UNSPEC_FPINT_CEIL
665 UNSPEC_FPINT_NEARBYINT])
666 (define_int_attr fpint_name [(UNSPEC_FPINT_FLOOR "floor")
667 (UNSPEC_FPINT_BTRUNC "btrunc")
668 (UNSPEC_FPINT_ROUND "round")
669 (UNSPEC_FPINT_CEIL "ceil")
670 (UNSPEC_FPINT_NEARBYINT "nearbyint")])
671 (define_int_attr fpint_roundingmode [(UNSPEC_FPINT_FLOOR "7")
672 (UNSPEC_FPINT_BTRUNC "5")
673 (UNSPEC_FPINT_ROUND "1")
674 (UNSPEC_FPINT_CEIL "6")
675 (UNSPEC_FPINT_NEARBYINT "0")])
677 ;; This iterator and attribute allow to combine most atomic operations.
678 (define_code_iterator ATOMIC [and ior xor plus minus mult])
679 (define_code_iterator ATOMIC_Z196 [and ior xor plus])
680 (define_code_attr atomic [(and "and") (ior "or") (xor "xor")
681 (plus "add") (minus "sub") (mult "nand")])
682 (define_code_attr noxa [(and "n") (ior "o") (xor "x") (plus "a")])
684 ;; In FP templates, a string like "lt<de>br" will expand to "ltxbr" in
685 ;; TF/TDmode, "ltdbr" in DF/DDmode, and "ltebr" in SF/SDmode.
686 (define_mode_attr xde [(TF "x") (DF "d") (SF "e") (TD "x") (DD "d") (SD "e")])
688 ;; In FP templates, a <dee> in "m<dee><bt>r" will expand to "mx<bt>r" in
689 ;; TF/TDmode, "md<bt>r" in DF/DDmode, "mee<bt>r" in SFmode and "me<bt>r in
691 (define_mode_attr xdee [(TF "x") (DF "d") (SF "ee") (TD "x") (DD "d") (SD "e")])
693 ;; In FP templates, "<RRe>" will expand to "RRE" in TFmode and "RR" otherwise.
694 ;; Likewise for "<RXe>".
695 (define_mode_attr RRe [(TF "RRE") (DF "RR") (SF "RR")])
696 (define_mode_attr RXe [(TF "RXE") (DF "RX") (SF "RX")])
698 ;; The decimal floating point variants of add, sub, div and mul support 3
699 ;; fp register operands. The following attributes allow to merge the bfp and
700 ;; dfp variants in a single insn definition.
702 ;; These mode attributes are supposed to be used in the `enabled' insn
703 ;; attribute to disable certain alternatives for certain modes.
704 (define_mode_attr nBFP [(TF "0") (DF "0") (SF "0") (TD "*") (DD "*") (DD "*")])
705 (define_mode_attr nDFP [(TF "*") (DF "*") (SF "*") (TD "0") (DD "0") (DD "0")])
706 (define_mode_attr DSF [(TF "0") (DF "*") (SF "*") (TD "0") (DD "0") (SD "0")])
707 (define_mode_attr DFDI [(TF "0") (DF "*") (SF "0")
708 (TD "0") (DD "0") (DD "0")
709 (TI "0") (DI "*") (SI "0")])
710 (define_mode_attr DF [(TF "0") (DF "*") (SF "0")
711 (TD "0") (DD "0") (DD "0")
712 (TI "0") (DI "0") (SI "0")])
713 (define_mode_attr SF [(TF "0") (DF "0") (SF "*")
714 (TD "0") (DD "0") (DD "0")
715 (TI "0") (DI "0") (SI "0")])
717 ;; This attribute is used in the operand constraint list
718 ;; for instructions dealing with the sign bit of 32 or 64bit fp values.
719 ;; TFmode values are represented by a fp register pair. Since the
720 ;; sign bit instructions only handle single source and target fp registers
721 ;; these instructions can only be used for TFmode values if the source and
722 ;; target operand uses the same fp register.
723 (define_mode_attr fT0 [(TF "0") (DF "f") (SF "f")])
725 ;; This attribute adds b for bfp instructions and t for dfp instructions and is used
726 ;; within instruction mnemonics.
727 (define_mode_attr bt [(TF "b") (DF "b") (SF "b") (TD "t") (DD "t") (SD "t")])
729 ;; This attribute is used within instruction mnemonics. It evaluates to d for dfp
730 ;; modes and to an empty string for bfp modes.
731 (define_mode_attr _d [(TF "") (DF "") (SF "") (TD "d") (DD "d") (SD "d")])
733 ;; In GPR and P templates, a constraint like "<d0>" will expand to "d" in DImode
734 ;; and "0" in SImode. This allows to combine instructions of which the 31bit
735 ;; version only operates on one register.
736 (define_mode_attr d0 [(DI "d") (SI "0")])
738 ;; In combination with d0 this allows to combine instructions of which the 31bit
739 ;; version only operates on one register. The DImode version needs an additional
740 ;; register for the assembler output.
741 (define_mode_attr 1 [(DI "%1,") (SI "")])
743 ;; In SHIFT templates, a string like "s<lr>dl" will expand to "sldl" in
744 ;; 'ashift' and "srdl" in 'lshiftrt'.
745 (define_code_attr lr [(ashift "l") (lshiftrt "r")])
747 ;; In SHIFT templates, this attribute holds the correct standard name for the
748 ;; pattern itself and the corresponding function calls.
749 (define_code_attr shift [(ashift "ashl") (lshiftrt "lshr")])
751 ;; This attribute handles differences in the instruction 'type' and will result
752 ;; in "RRE" for DImode and "RR" for SImode.
753 (define_mode_attr E [(DI "E") (SI "")])
755 ;; This attribute handles differences in the instruction 'type' and makes RX<Y>
756 ;; to result in "RXY" for DImode and "RX" for SImode.
757 (define_mode_attr Y [(DI "Y") (SI "")])
759 ;; This attribute handles differences in the instruction 'type' and will result
760 ;; in "RSE" for TImode and "RS" for DImode.
761 (define_mode_attr TE [(TI "E") (DI "")])
763 ;; In GPR templates, a string like "lc<g>r" will expand to "lcgr" in DImode
764 ;; and "lcr" in SImode.
765 (define_mode_attr g [(DI "g") (SI "")])
767 ;; In GPR templates, a string like "sl<y>" will expand to "slg" in DImode
768 ;; and "sly" in SImode. This is useful because on 64bit the ..g instructions
769 ;; were enhanced with long displacements whereas 31bit instructions got a ..y
770 ;; variant for long displacements.
771 (define_mode_attr y [(DI "g") (SI "y")])
773 ;; In DW templates, a string like "cds<g>" will expand to "cdsg" in TImode
774 ;; and "cds" in DImode.
775 (define_mode_attr tg [(TI "g") (DI "")])
777 ;; In TDI templates, a string like "c<d>sg".
778 (define_mode_attr td [(TI "d") (DI "")])
780 ;; In GPR templates, a string like "c<gf>dbr" will expand to "cgdbr" in DImode
781 ;; and "cfdbr" in SImode.
782 (define_mode_attr gf [(DI "g") (SI "f")])
784 ;; In GPR templates, a string like sll<gk> will expand to sllg for DI
785 ;; and sllk for SI. This way it is possible to merge the new z196 SI
786 ;; 3 operands shift instructions into the existing patterns.
787 (define_mode_attr gk [(DI "g") (SI "k")])
789 ;; ICM mask required to load MODE value into the lowest subreg
790 ;; of a SImode register.
791 (define_mode_attr icm_lo [(HI "3") (QI "1")])
793 ;; In HQI templates, a string like "llg<hc>" will expand to "llgh" in
794 ;; HImode and "llgc" in QImode.
795 (define_mode_attr hc [(HI "h") (QI "c")])
797 ;; In P templates, the mode <DBL> will expand to "TI" in DImode and "DI"
799 (define_mode_attr DBL [(DI "TI") (SI "DI")])
801 ;; This attribute expands to DF for TFmode and to DD for TDmode . It is
802 ;; used for Txmode splitters splitting a Txmode copy into 2 Dxmode copies.
803 (define_mode_attr HALF_TMODE [(TF "DF") (TD "DD")])
805 ;; Maximum unsigned integer that fits in MODE.
806 (define_mode_attr max_uint [(HI "65535") (QI "255")])
808 ;; Start and end field computations for RISBG et al.
809 (define_mode_attr bfstart [(DI "s") (SI "t")])
810 (define_mode_attr bfend [(DI "e") (SI "f")])
812 ;; In place of GET_MODE_BITSIZE (<MODE>mode)
813 (define_mode_attr bitsize [(DI "64") (SI "32") (HI "16") (QI "8")])
815 (define_mode_attr bitoff [(DI "0") (SI "32") (HI "48") (QI "56")])
816 (define_mode_attr bitoff_plus [(DI "") (SI "32+") (HI "48+") (QI "56+")])
818 ;; In place of GET_MODE_SIZE (<MODE>mode)
819 (define_mode_attr modesize [(DI "8") (SI "4")])
821 ;; Allow return and simple_return to be defined from a single template.
822 (define_code_iterator ANY_RETURN [return simple_return])
826 ; Condition code modes generated by vector fp comparisons. These will
827 ; be used also in single element mode.
828 (define_mode_iterator VFCMP [CCVEQ CCVFH CCVFHE])
829 ; Used with VFCMP to expand part of the mnemonic
830 ; For fp we have a mismatch: eq in the insn name - e in asm
831 (define_mode_attr asm_fcmp [(CCVEQ "e") (CCVFH "h") (CCVFHE "he")])
832 (define_mode_attr insn_cmp [(CCVEQ "eq") (CCVIH "h") (CCVIHU "hl") (CCVFH "h") (CCVFHE "he")])
834 ;; Subst pattern definitions
837 (include "vector.md")
840 ;;- Compare instructions.
843 ; Test-under-Mask instructions
845 (define_insn "*tmqi_mem"
846 [(set (reg CC_REGNUM)
847 (compare (and:QI (match_operand:QI 0 "memory_operand" "Q,S")
848 (match_operand:QI 1 "immediate_operand" "n,n"))
849 (match_operand:QI 2 "immediate_operand" "n,n")))]
850 "s390_match_ccmode (insn, s390_tm_ccmode (operands[1], operands[2], false))"
854 [(set_attr "op_type" "SI,SIY")
855 (set_attr "cpu_facility" "*,longdisp")
856 (set_attr "z10prop" "z10_super,z10_super")])
858 (define_insn "*tmdi_reg"
859 [(set (reg CC_REGNUM)
860 (compare (and:DI (match_operand:DI 0 "nonimmediate_operand" "d,d,d,d")
861 (match_operand:DI 1 "immediate_operand"
862 "N0HD0,N1HD0,N2HD0,N3HD0"))
863 (match_operand:DI 2 "immediate_operand" "n,n,n,n")))]
865 && s390_match_ccmode (insn, s390_tm_ccmode (operands[1], operands[2], true))
866 && s390_single_part (operands[1], DImode, HImode, 0) >= 0"
872 [(set_attr "op_type" "RI")
873 (set_attr "z10prop" "z10_super,z10_super,z10_super,z10_super")])
875 (define_insn "*tmsi_reg"
876 [(set (reg CC_REGNUM)
877 (compare (and:SI (match_operand:SI 0 "nonimmediate_operand" "d,d")
878 (match_operand:SI 1 "immediate_operand" "N0HS0,N1HS0"))
879 (match_operand:SI 2 "immediate_operand" "n,n")))]
880 "s390_match_ccmode (insn, s390_tm_ccmode (operands[1], operands[2], true))
881 && s390_single_part (operands[1], SImode, HImode, 0) >= 0"
885 [(set_attr "op_type" "RI")
886 (set_attr "z10prop" "z10_super,z10_super")])
888 (define_insn "*tm<mode>_full"
889 [(set (reg CC_REGNUM)
890 (compare (match_operand:HQI 0 "register_operand" "d")
891 (match_operand:HQI 1 "immediate_operand" "n")))]
892 "s390_match_ccmode (insn, s390_tm_ccmode (constm1_rtx, operands[1], true))"
894 [(set_attr "op_type" "RI")
895 (set_attr "z10prop" "z10_super")])
899 ; Load-and-Test instructions
902 ; tst(di|si) instruction pattern(s).
904 (define_insn "*tstdi_sign"
905 [(set (reg CC_REGNUM)
909 (subreg:DI (match_operand:SI 0 "nonimmediate_operand" "d,T") 0)
910 (const_int 32)) (const_int 32))
911 (match_operand:DI 1 "const0_operand" "")))
912 (set (match_operand:DI 2 "register_operand" "=d,d")
913 (sign_extend:DI (match_dup 0)))]
914 "s390_match_ccmode(insn, CCSmode) && TARGET_ZARCH"
917 [(set_attr "op_type" "RRE,RXY")
918 (set_attr "cpu_facility" "*,z10")
919 (set_attr "z10prop" "z10_super_E1,z10_super_E1") ])
922 (define_insn "*tst<mode>_extimm"
923 [(set (reg CC_REGNUM)
924 (compare (match_operand:GPR 0 "nonimmediate_operand" "d,T")
925 (match_operand:GPR 1 "const0_operand" "")))
926 (set (match_operand:GPR 2 "register_operand" "=d,d")
928 "s390_match_ccmode(insn, CCSmode) && TARGET_EXTIMM"
932 [(set_attr "op_type" "RR<E>,RXY")
933 (set_attr "z10prop" "z10_fr_E1,z10_fwd_A3") ])
935 ; Peephole to combine a load-and-test from volatile memory which combine does
938 [(set (match_operand:GPR 0 "register_operand")
939 (match_operand:GPR 2 "memory_operand"))
941 (compare (match_dup 0) (match_operand:GPR 1 "const0_operand")))]
942 "s390_match_ccmode(insn, CCSmode) && TARGET_EXTIMM
943 && GENERAL_REG_P (operands[0])
944 && satisfies_constraint_T (operands[2])"
946 [(set (reg:CCS CC_REGNUM)
947 (compare:CCS (match_dup 2) (match_dup 1)))
948 (set (match_dup 0) (match_dup 2))])])
951 (define_insn "*tst<mode>_cconly_extimm"
952 [(set (reg CC_REGNUM)
953 (compare (match_operand:GPR 0 "nonimmediate_operand" "d,T")
954 (match_operand:GPR 1 "const0_operand" "")))
955 (clobber (match_scratch:GPR 2 "=X,d"))]
956 "s390_match_ccmode(insn, CCSmode) && TARGET_EXTIMM"
960 [(set_attr "op_type" "RR<E>,RXY")
961 (set_attr "z10prop" "z10_fr_E1,z10_fwd_A3")])
963 (define_insn "*tstdi"
964 [(set (reg CC_REGNUM)
965 (compare (match_operand:DI 0 "register_operand" "d")
966 (match_operand:DI 1 "const0_operand" "")))
967 (set (match_operand:DI 2 "register_operand" "=d")
969 "s390_match_ccmode(insn, CCSmode) && TARGET_ZARCH && !TARGET_EXTIMM"
971 [(set_attr "op_type" "RRE")
972 (set_attr "z10prop" "z10_fr_E1")])
974 (define_insn "*tstsi"
975 [(set (reg CC_REGNUM)
976 (compare (match_operand:SI 0 "nonimmediate_operand" "d,Q,S")
977 (match_operand:SI 1 "const0_operand" "")))
978 (set (match_operand:SI 2 "register_operand" "=d,d,d")
980 "s390_match_ccmode(insn, CCSmode) && !TARGET_EXTIMM"
985 [(set_attr "op_type" "RR,RS,RSY")
986 (set_attr "cpu_facility" "*,*,longdisp")
987 (set_attr "z10prop" "z10_fr_E1,z10_super_E1,z10_super_E1")])
989 (define_insn "*tstsi_cconly"
990 [(set (reg CC_REGNUM)
991 (compare (match_operand:SI 0 "nonimmediate_operand" "d,Q,S")
992 (match_operand:SI 1 "const0_operand" "")))
993 (clobber (match_scratch:SI 2 "=X,d,d"))]
994 "s390_match_ccmode(insn, CCSmode)"
999 [(set_attr "op_type" "RR,RS,RSY")
1000 (set_attr "cpu_facility" "*,*,longdisp")
1001 (set_attr "z10prop" "z10_fr_E1,z10_super_E1,z10_super_E1")])
1003 (define_insn "*tstdi_cconly_31"
1004 [(set (reg CC_REGNUM)
1005 (compare (match_operand:DI 0 "register_operand" "d")
1006 (match_operand:DI 1 "const0_operand" "")))]
1007 "s390_match_ccmode(insn, CCSmode) && !TARGET_ZARCH"
1009 [(set_attr "op_type" "RS")
1010 (set_attr "atype" "reg")])
1013 (define_insn "*tst<mode>_cconly2"
1014 [(set (reg CC_REGNUM)
1015 (compare (match_operand:GPR 0 "register_operand" "d")
1016 (match_operand:GPR 1 "const0_operand" "")))]
1017 "s390_match_ccmode(insn, CCSmode)"
1019 [(set_attr "op_type" "RR<E>")
1020 (set_attr "z10prop" "z10_fr_E1")])
1022 ; tst(hi|qi) instruction pattern(s).
1024 (define_insn "*tst<mode>CCT"
1025 [(set (reg CC_REGNUM)
1026 (compare (match_operand:HQI 0 "nonimmediate_operand" "?Q,?S,d")
1027 (match_operand:HQI 1 "const0_operand" "")))
1028 (set (match_operand:HQI 2 "register_operand" "=d,d,0")
1030 "s390_match_ccmode(insn, CCTmode)"
1032 icm\t%2,<icm_lo>,%S0
1033 icmy\t%2,<icm_lo>,%S0
1035 [(set_attr "op_type" "RS,RSY,RI")
1036 (set_attr "cpu_facility" "*,longdisp,*")
1037 (set_attr "z10prop" "z10_super_E1,z10_super_E1,z10_super")])
1039 (define_insn "*tsthiCCT_cconly"
1040 [(set (reg CC_REGNUM)
1041 (compare (match_operand:HI 0 "nonimmediate_operand" "Q,S,d")
1042 (match_operand:HI 1 "const0_operand" "")))
1043 (clobber (match_scratch:HI 2 "=d,d,X"))]
1044 "s390_match_ccmode(insn, CCTmode)"
1049 [(set_attr "op_type" "RS,RSY,RI")
1050 (set_attr "cpu_facility" "*,longdisp,*")
1051 (set_attr "z10prop" "z10_super_E1,z10_super_E1,z10_super")])
1053 (define_insn "*tstqiCCT_cconly"
1054 [(set (reg CC_REGNUM)
1055 (compare (match_operand:QI 0 "nonimmediate_operand" "?Q,?S,d")
1056 (match_operand:QI 1 "const0_operand" "")))]
1057 "s390_match_ccmode(insn, CCTmode)"
1062 [(set_attr "op_type" "SI,SIY,RI")
1063 (set_attr "cpu_facility" "*,longdisp,*")
1064 (set_attr "z10prop" "z10_super,z10_super,z10_super")])
1066 (define_insn "*tst<mode>"
1067 [(set (reg CC_REGNUM)
1068 (compare (match_operand:HQI 0 "s_operand" "Q,S")
1069 (match_operand:HQI 1 "const0_operand" "")))
1070 (set (match_operand:HQI 2 "register_operand" "=d,d")
1072 "s390_match_ccmode(insn, CCSmode)"
1074 icm\t%2,<icm_lo>,%S0
1075 icmy\t%2,<icm_lo>,%S0"
1076 [(set_attr "op_type" "RS,RSY")
1077 (set_attr "cpu_facility" "*,longdisp")
1078 (set_attr "z10prop" "z10_super_E1,z10_super_E1")])
1080 (define_insn "*tst<mode>_cconly"
1081 [(set (reg CC_REGNUM)
1082 (compare (match_operand:HQI 0 "s_operand" "Q,S")
1083 (match_operand:HQI 1 "const0_operand" "")))
1084 (clobber (match_scratch:HQI 2 "=d,d"))]
1085 "s390_match_ccmode(insn, CCSmode)"
1087 icm\t%2,<icm_lo>,%S0
1088 icmy\t%2,<icm_lo>,%S0"
1089 [(set_attr "op_type" "RS,RSY")
1090 (set_attr "cpu_facility" "*,longdisp")
1091 (set_attr "z10prop" "z10_super_E1,z10_super_E1")])
1094 ; Compare (equality) instructions
1096 (define_insn "*cmpdi_cct"
1097 [(set (reg CC_REGNUM)
1098 (compare (match_operand:DI 0 "nonimmediate_operand" "%d,d,d,d,Q")
1099 (match_operand:DI 1 "general_operand" "d,K,Os,T,BQ")))]
1100 "s390_match_ccmode (insn, CCTmode) && TARGET_ZARCH"
1107 [(set_attr "op_type" "RRE,RI,RIL,RXY,SS")
1108 (set_attr "z10prop" "z10_super_c,z10_super,z10_super,z10_super,*")])
1110 (define_insn "*cmpsi_cct"
1111 [(set (reg CC_REGNUM)
1112 (compare (match_operand:SI 0 "nonimmediate_operand" "%d,d,d,d,d,Q")
1113 (match_operand:SI 1 "general_operand" "d,K,Os,R,T,BQ")))]
1114 "s390_match_ccmode (insn, CCTmode)"
1122 [(set_attr "op_type" "RR,RI,RIL,RX,RXY,SS")
1123 (set_attr "cpu_facility" "*,*,*,*,longdisp,*")
1124 (set_attr "z10prop" "z10_super_c,z10_super,z10_super,z10_super,z10_super,*")])
1126 ; Compare (signed) instructions
1128 (define_insn "*cmpdi_ccs_sign"
1129 [(set (reg CC_REGNUM)
1130 (compare (sign_extend:DI (match_operand:SI 1 "nonimmediate_operand"
1132 (match_operand:DI 0 "register_operand" "d, d,d")))]
1133 "s390_match_ccmode(insn, CCSRmode) && TARGET_ZARCH"
1138 [(set_attr "op_type" "RRE,RXY,RIL")
1139 (set_attr "z10prop" "z10_c,*,*")
1140 (set_attr "type" "*,*,larl")
1141 (set_attr "relative_long" "*,*,yes")])
1145 (define_insn "*cmpsi_ccs_sign"
1146 [(set (reg CC_REGNUM)
1147 (compare (sign_extend:SI (match_operand:HI 1 "memory_operand" "R,T,b"))
1148 (match_operand:SI 0 "register_operand" "d,d,d")))]
1149 "s390_match_ccmode(insn, CCSRmode)"
1154 [(set_attr "op_type" "RX,RXY,RIL")
1155 (set_attr "cpu_facility" "*,longdisp,z10")
1156 (set_attr "type" "*,*,larl")
1157 (set_attr "z196prop" "z196_cracked,z196_cracked,z196_cracked")
1158 (set_attr "relative_long" "*,*,yes")])
1160 (define_insn "*cmphi_ccs_z10"
1161 [(set (reg CC_REGNUM)
1162 (compare (match_operand:HI 0 "s_operand" "Q")
1163 (match_operand:HI 1 "immediate_operand" "K")))]
1164 "s390_match_ccmode(insn, CCSmode) && TARGET_Z10"
1166 [(set_attr "op_type" "SIL")
1167 (set_attr "z196prop" "z196_cracked")])
1169 (define_insn "*cmpdi_ccs_signhi_rl"
1170 [(set (reg CC_REGNUM)
1171 (compare (sign_extend:DI (match_operand:HI 1 "memory_operand" "T,b"))
1172 (match_operand:GPR 0 "register_operand" "d,d")))]
1173 "s390_match_ccmode(insn, CCSRmode) && TARGET_Z10"
1177 [(set_attr "op_type" "RXY,RIL")
1178 (set_attr "type" "*,larl")
1179 (set_attr "relative_long" "*,yes")])
1181 ; cr, chi, cfi, c, cy, cgr, cghi, cgfi, cg, chsi, cghsi, crl, cgrl
1182 (define_insn "*cmp<mode>_ccs"
1183 [(set (reg CC_REGNUM)
1184 (compare (match_operand:GPR 0 "nonimmediate_operand"
1186 (match_operand:GPR 1 "general_operand"
1187 "d,K,K,Os,R,T,b")))]
1188 "s390_match_ccmode(insn, CCSmode)"
1197 [(set_attr "op_type" "RR<E>,RI,SIL,RIL,RX<Y>,RXY,RIL")
1198 (set_attr "cpu_facility" "*,*,z10,extimm,*,longdisp,z10")
1199 (set_attr "type" "*,*,*,*,*,*,larl")
1200 (set_attr "z10prop" "z10_super_c,z10_super,z10_super,z10_super,z10_super,z10_super,z10_super")
1201 (set_attr "relative_long" "*,*,*,*,*,*,yes")])
1204 ; Compare (unsigned) instructions
1206 (define_insn "*cmpsi_ccu_zerohi_rlsi"
1207 [(set (reg CC_REGNUM)
1208 (compare (zero_extend:SI (mem:HI (match_operand:SI 1
1209 "larl_operand" "X")))
1210 (match_operand:SI 0 "register_operand" "d")))]
1211 "s390_match_ccmode(insn, CCURmode) && TARGET_Z10"
1213 [(set_attr "op_type" "RIL")
1214 (set_attr "type" "larl")
1215 (set_attr "z10prop" "z10_super")
1216 (set_attr "relative_long" "yes")])
1219 (define_insn "*cmp<GPR:mode>_ccu_zerohi_rldi"
1220 [(set (reg CC_REGNUM)
1221 (compare (zero_extend:GPR (mem:HI (match_operand:DI 1
1222 "larl_operand" "X")))
1223 (match_operand:GPR 0 "register_operand" "d")))]
1224 "s390_match_ccmode(insn, CCURmode) && TARGET_Z10"
1226 [(set_attr "op_type" "RIL")
1227 (set_attr "type" "larl")
1228 (set_attr "z10prop" "z10_super")
1229 (set_attr "relative_long" "yes")])
1231 (define_insn "*cmpdi_ccu_zero"
1232 [(set (reg CC_REGNUM)
1233 (compare (zero_extend:DI (match_operand:SI 1 "nonimmediate_operand"
1235 (match_operand:DI 0 "register_operand" "d,d,d")))]
1236 "s390_match_ccmode (insn, CCURmode) && TARGET_ZARCH"
1241 [(set_attr "op_type" "RRE,RXY,RIL")
1242 (set_attr "cpu_facility" "*,*,z10")
1243 (set_attr "type" "*,*,larl")
1244 (set_attr "z10prop" "z10_super_c,z10_super_E1,z10_super")
1245 (set_attr "relative_long" "*,*,yes")])
1247 (define_insn "*cmpdi_ccu"
1248 [(set (reg CC_REGNUM)
1249 (compare (match_operand:DI 0 "nonimmediate_operand"
1251 (match_operand:DI 1 "general_operand"
1252 "d,Op,b,D,T,BQ,Q")))]
1253 "s390_match_ccmode (insn, CCUmode) && TARGET_ZARCH"
1262 [(set_attr "op_type" "RRE,RIL,RIL,SIL,RXY,SS,SS")
1263 (set_attr "cpu_facility" "*,extimm,z10,z10,*,*,*")
1264 (set_attr "type" "*,*,larl,*,*,*,*")
1265 (set_attr "z10prop" "z10_super_c,z10_super,z10_super,z10_super,z10_super,*,*")
1266 (set_attr "relative_long" "*,*,yes,*,*,*,*")])
1268 (define_insn "*cmpsi_ccu"
1269 [(set (reg CC_REGNUM)
1270 (compare (match_operand:SI 0 "nonimmediate_operand" "d, d,d,Q,d,d, Q,BQ")
1271 (match_operand:SI 1 "general_operand" "d,Os,b,D,R,T,BQ, Q")))]
1272 "s390_match_ccmode (insn, CCUmode)"
1282 [(set_attr "op_type" "RR,RIL,RIL,SIL,RX,RXY,SS,SS")
1283 (set_attr "cpu_facility" "*,extimm,z10,z10,*,longdisp,*,*")
1284 (set_attr "type" "*,*,larl,*,*,*,*,*")
1285 (set_attr "z10prop" "z10_super_c,z10_super,z10_super,z10_super,z10_super,z10_super,*,*")
1286 (set_attr "relative_long" "*,*,yes,*,*,*,*,*")])
1288 (define_insn "*cmphi_ccu"
1289 [(set (reg CC_REGNUM)
1290 (compare (match_operand:HI 0 "nonimmediate_operand" "d,d,Q,Q,BQ")
1291 (match_operand:HI 1 "general_operand" "Q,S,D,BQ,Q")))]
1292 "s390_match_ccmode (insn, CCUmode)
1293 && !register_operand (operands[1], HImode)"
1300 [(set_attr "op_type" "RS,RSY,SIL,SS,SS")
1301 (set_attr "cpu_facility" "*,longdisp,z10,*,*")
1302 (set_attr "z10prop" "*,*,z10_super,*,*")])
1304 (define_insn "*cmpqi_ccu"
1305 [(set (reg CC_REGNUM)
1306 (compare (match_operand:QI 0 "nonimmediate_operand" "d,d,Q,S,Q,BQ")
1307 (match_operand:QI 1 "general_operand" "Q,S,n,n,BQ,Q")))]
1308 "s390_match_ccmode (insn, CCUmode)
1309 && !register_operand (operands[1], QImode)"
1317 [(set_attr "op_type" "RS,RSY,SI,SIY,SS,SS")
1318 (set_attr "cpu_facility" "*,longdisp,*,longdisp,*,*")
1319 (set_attr "z10prop" "*,*,z10_super,z10_super,*,*")])
1322 ; Block compare (CLC) instruction patterns.
1325 [(set (reg CC_REGNUM)
1326 (compare (match_operand:BLK 0 "memory_operand" "Q")
1327 (match_operand:BLK 1 "memory_operand" "Q")))
1328 (use (match_operand 2 "const_int_operand" "n"))]
1329 "s390_match_ccmode (insn, CCUmode)
1330 && INTVAL (operands[2]) >= 1 && INTVAL (operands[2]) <= 256"
1331 "clc\t%O0(%2,%R0),%S1"
1332 [(set_attr "op_type" "SS")])
1335 [(set (reg CC_REGNUM)
1336 (compare (match_operand 0 "memory_operand" "")
1337 (match_operand 1 "memory_operand" "")))]
1339 && s390_match_ccmode (insn, CCUmode)
1340 && GET_MODE (operands[0]) == GET_MODE (operands[1])
1341 && GET_MODE_SIZE (GET_MODE (operands[0])) > 0"
1343 [(set (match_dup 0) (match_dup 1))
1344 (use (match_dup 2))])]
1346 operands[2] = GEN_INT (GET_MODE_SIZE (GET_MODE (operands[0])));
1347 operands[0] = adjust_address (operands[0], BLKmode, 0);
1348 operands[1] = adjust_address (operands[1], BLKmode, 0);
1350 operands[1] = gen_rtx_COMPARE (GET_MODE (SET_DEST (PATTERN (curr_insn))),
1351 operands[0], operands[1]);
1352 operands[0] = SET_DEST (PATTERN (curr_insn));
1356 ; (TF|DF|SF|TD|DD|SD) instructions
1359 ; load and test instructions turn SNaN into QNaN what is not
1360 ; acceptable if the target will be used afterwards. On the other hand
1361 ; they are quite convenient for implementing comparisons with 0.0. So
1362 ; try to enable them via splitter if the value isn't needed anymore.
1364 ; ltxbr, ltdbr, ltebr, ltxtr, ltdtr
1365 (define_insn "*cmp<mode>_ccs_0"
1366 [(set (reg CC_REGNUM)
1367 (compare (match_operand:FP 0 "register_operand" "f")
1368 (match_operand:FP 1 "const0_operand" "")))
1369 (clobber (match_operand:FP 2 "register_operand" "=0"))]
1370 "s390_match_ccmode(insn, CCSmode) && TARGET_HARD_FLOAT"
1371 "lt<xde><bt>r\t%0,%0"
1372 [(set_attr "op_type" "RRE")
1373 (set_attr "type" "fsimp<mode>")])
1376 [(set (match_operand 0 "cc_reg_operand")
1377 (compare (match_operand:FP 1 "register_operand")
1378 (match_operand:FP 2 "const0_operand")))]
1379 "TARGET_HARD_FLOAT && REG_P (operands[1]) && dead_or_set_p (insn, operands[1])"
1381 [(set (match_dup 0) (match_dup 3))
1382 (clobber (match_dup 1))])]
1384 /* s390_match_ccmode requires the compare to have the same CC mode
1385 as the CC destination register. */
1386 operands[3] = gen_rtx_COMPARE (GET_MODE (operands[0]),
1387 operands[1], operands[2]);
1391 ; VX: TFmode in FPR pairs: use cxbr instead of wfcxb
1392 ; cxtr, cdtr, cxbr, cdbr, cebr, cdb, ceb, wfcsb, wfcdb
1393 (define_insn "*cmp<mode>_ccs"
1394 [(set (reg CC_REGNUM)
1395 (compare (match_operand:FP 0 "register_operand" "f,f,v,v")
1396 (match_operand:FP 1 "general_operand" "f,R,v,v")))]
1397 "s390_match_ccmode(insn, CCSmode) && TARGET_HARD_FLOAT"
1403 [(set_attr "op_type" "RRE,RXE,VRR,VRR")
1404 (set_attr "cpu_facility" "*,*,vx,vxe")
1405 (set_attr "enabled" "*,<DSF>,<DF>,<SF>")])
1407 ; Compare and Branch instructions
1409 ; cij, cgij, crj, cgrj, cfi, cgfi, cr, cgr
1410 ; The following instructions do a complementary access of their second
1411 ; operand (z01 only): crj_c, cgrjc, cr, cgr
1412 (define_insn "*cmp_and_br_signed_<mode>"
1414 (if_then_else (match_operator 0 "s390_signed_integer_comparison"
1415 [(match_operand:GPR 1 "register_operand" "d,d")
1416 (match_operand:GPR 2 "nonmemory_operand" "d,C")])
1417 (label_ref (match_operand 3 "" ""))
1419 (clobber (reg:CC CC_REGNUM))]
1420 "TARGET_Z10 && !TARGET_AVOID_CMP_AND_BRANCH"
1422 if (get_attr_length (insn) == 6)
1423 return which_alternative ?
1424 "c<g>ij%C0\t%1,%c2,%l3" : "c<g>rj%C0\t%1,%2,%l3";
1426 return which_alternative ?
1427 "c<g>fi\t%1,%c2\;jg%C0\t%l3" : "c<g>r\t%1,%2\;jg%C0\t%l3";
1429 [(set_attr "op_type" "RIE")
1430 (set_attr "type" "branch")
1431 (set_attr "z10prop" "z10_super_c,z10_super")
1432 (set (attr "length")
1433 (if_then_else (lt (abs (minus (pc) (match_dup 3))) (const_int 60000))
1434 (const_int 6) (const_int 12)))]) ; 8 byte for cr/jg
1435 ; 10 byte for cgr/jg
1437 ; clij, clgij, clrj, clgrj, clfi, clgfi, clr, clgr
1438 ; The following instructions do a complementary access of their second
1439 ; operand (z10 only): clrj, clgrj, clr, clgr
1440 (define_insn "*cmp_and_br_unsigned_<mode>"
1442 (if_then_else (match_operator 0 "s390_unsigned_integer_comparison"
1443 [(match_operand:GPR 1 "register_operand" "d,d")
1444 (match_operand:GPR 2 "nonmemory_operand" "d,I")])
1445 (label_ref (match_operand 3 "" ""))
1447 (clobber (reg:CC CC_REGNUM))]
1448 "TARGET_Z10 && !TARGET_AVOID_CMP_AND_BRANCH"
1450 if (get_attr_length (insn) == 6)
1451 return which_alternative ?
1452 "cl<g>ij%C0\t%1,%b2,%l3" : "cl<g>rj%C0\t%1,%2,%l3";
1454 return which_alternative ?
1455 "cl<g>fi\t%1,%b2\;jg%C0\t%l3" : "cl<g>r\t%1,%2\;jg%C0\t%l3";
1457 [(set_attr "op_type" "RIE")
1458 (set_attr "type" "branch")
1459 (set_attr "z10prop" "z10_super_c,z10_super")
1460 (set (attr "length")
1461 (if_then_else (lt (abs (minus (pc) (match_dup 3))) (const_int 60000))
1462 (const_int 6) (const_int 12)))]) ; 8 byte for clr/jg
1463 ; 10 byte for clgr/jg
1465 ; And now the same two patterns as above but with a negated CC mask.
1467 ; cij, cgij, crj, cgrj, cfi, cgfi, cr, cgr
1468 ; The following instructions do a complementary access of their second
1469 ; operand (z01 only): crj_c, cgrjc, cr, cgr
1470 (define_insn "*icmp_and_br_signed_<mode>"
1472 (if_then_else (match_operator 0 "s390_signed_integer_comparison"
1473 [(match_operand:GPR 1 "register_operand" "d,d")
1474 (match_operand:GPR 2 "nonmemory_operand" "d,C")])
1476 (label_ref (match_operand 3 "" ""))))
1477 (clobber (reg:CC CC_REGNUM))]
1478 "TARGET_Z10 && !TARGET_AVOID_CMP_AND_BRANCH"
1480 if (get_attr_length (insn) == 6)
1481 return which_alternative ?
1482 "c<g>ij%D0\t%1,%c2,%l3" : "c<g>rj%D0\t%1,%2,%l3";
1484 return which_alternative ?
1485 "c<g>fi\t%1,%c2\;jg%D0\t%l3" : "c<g>r\t%1,%2\;jg%D0\t%l3";
1487 [(set_attr "op_type" "RIE")
1488 (set_attr "type" "branch")
1489 (set_attr "z10prop" "z10_super_c,z10_super")
1490 (set (attr "length")
1491 (if_then_else (lt (abs (minus (pc) (match_dup 3))) (const_int 60000))
1492 (const_int 6) (const_int 12)))]) ; 8 byte for cr/jg
1493 ; 10 byte for cgr/jg
1495 ; clij, clgij, clrj, clgrj, clfi, clgfi, clr, clgr
1496 ; The following instructions do a complementary access of their second
1497 ; operand (z10 only): clrj, clgrj, clr, clgr
1498 (define_insn "*icmp_and_br_unsigned_<mode>"
1500 (if_then_else (match_operator 0 "s390_unsigned_integer_comparison"
1501 [(match_operand:GPR 1 "register_operand" "d,d")
1502 (match_operand:GPR 2 "nonmemory_operand" "d,I")])
1504 (label_ref (match_operand 3 "" ""))))
1505 (clobber (reg:CC CC_REGNUM))]
1506 "TARGET_Z10 && !TARGET_AVOID_CMP_AND_BRANCH"
1508 if (get_attr_length (insn) == 6)
1509 return which_alternative ?
1510 "cl<g>ij%D0\t%1,%b2,%l3" : "cl<g>rj%D0\t%1,%2,%l3";
1512 return which_alternative ?
1513 "cl<g>fi\t%1,%b2\;jg%D0\t%l3" : "cl<g>r\t%1,%2\;jg%D0\t%l3";
1515 [(set_attr "op_type" "RIE")
1516 (set_attr "type" "branch")
1517 (set_attr "z10prop" "z10_super_c,z10_super")
1518 (set (attr "length")
1519 (if_then_else (lt (abs (minus (pc) (match_dup 3))) (const_int 60000))
1520 (const_int 6) (const_int 12)))]) ; 8 byte for clr/jg
1521 ; 10 byte for clgr/jg
1524 ;;- Move instructions.
1528 ; movti instruction pattern(s).
1532 ; Separate out the register pair alternative since constraints (P) are
1533 ; not able to deal with const_wide_int's. But predicates do.
1534 (define_insn "*movti_bigconst"
1535 [(set (match_operand:TI 0 "register_operand" "=d")
1536 (match_operand:TI 1 "reload_const_wide_int_operand" ""))]
1540 ; FIXME: More constants are possible by enabling jxx, jyy constraints
1541 ; for TImode (use double-int for the calculations)
1542 (define_insn "movti"
1543 [(set (match_operand:TI 0 "nonimmediate_operand" "=d,S,v, v, v,v,d,v,R,d, d, d, d, d,o")
1544 (match_operand:TI 1 "general_operand" " S,d,v,j00,jm1,d,v,R,v,K,NxHD0,Os,NxSD0,dT,d"))]
1562 [(set_attr "op_type" "RSY,RSY,VRR,VRI,VRI,VRR,*,VRX,VRX,*,*,*,*,*,*")
1563 (set_attr "type" "lm,stm,*,*,*,*,*,*,*,*,*,*,*,*,*")
1564 (set_attr "cpu_facility" "*,*,vx,vx,vx,vx,vx,vx,vx,*,*,*,extimm,*,*")])
1567 [(set (match_operand:TI 0 "nonimmediate_operand" "")
1568 (match_operand:TI 1 "general_operand" ""))]
1569 "TARGET_ZARCH && reload_completed
1570 && !s_operand (operands[0], TImode)
1571 && !s_operand (operands[1], TImode)
1572 && s390_split_ok_p (operands[0], operands[1], TImode, 0)"
1573 [(set (match_dup 2) (match_dup 4))
1574 (set (match_dup 3) (match_dup 5))]
1576 operands[2] = operand_subword (operands[0], 0, 0, TImode);
1577 operands[3] = operand_subword (operands[0], 1, 0, TImode);
1578 operands[4] = operand_subword (operands[1], 0, 0, TImode);
1579 operands[5] = operand_subword (operands[1], 1, 0, TImode);
1583 [(set (match_operand:TI 0 "nonimmediate_operand" "")
1584 (match_operand:TI 1 "general_operand" ""))]
1585 "TARGET_ZARCH && reload_completed
1586 && !s_operand (operands[0], TImode)
1587 && !s_operand (operands[1], TImode)
1588 && s390_split_ok_p (operands[0], operands[1], TImode, 1)"
1589 [(set (match_dup 2) (match_dup 4))
1590 (set (match_dup 3) (match_dup 5))]
1592 operands[2] = operand_subword (operands[0], 1, 0, TImode);
1593 operands[3] = operand_subword (operands[0], 0, 0, TImode);
1594 operands[4] = operand_subword (operands[1], 1, 0, TImode);
1595 operands[5] = operand_subword (operands[1], 0, 0, TImode);
1598 ; Use part of the TImode target reg to perform the address
1599 ; calculation. If the TImode value is supposed to be copied into a VR
1600 ; this splitter is not necessary.
1602 [(set (match_operand:TI 0 "register_operand" "")
1603 (match_operand:TI 1 "memory_operand" ""))]
1604 "TARGET_ZARCH && reload_completed
1605 && !VECTOR_REG_P (operands[0])
1606 && !s_operand (operands[1], VOIDmode)"
1607 [(set (match_dup 0) (match_dup 1))]
1609 rtx addr = operand_subword (operands[0], 1, 0, TImode);
1610 addr = gen_lowpart (Pmode, addr);
1611 s390_load_address (addr, XEXP (operands[1], 0));
1612 operands[1] = replace_equiv_address (operands[1], addr);
1616 ; Split a VR -> GPR TImode move into 2 vector load GR from VR element.
1617 ; For the higher order bits we do simply a DImode move while the
1618 ; second part is done via vec extract. Both will end up as vlgvg.
1620 [(set (match_operand:TI 0 "register_operand" "")
1621 (match_operand:TI 1 "register_operand" ""))]
1622 "TARGET_VX && reload_completed
1623 && GENERAL_REG_P (operands[0])
1624 && VECTOR_REG_P (operands[1])"
1625 [(set (match_dup 2) (match_dup 4))
1626 (set (match_dup 3) (unspec:DI [(match_dup 5) (const_int 1)]
1627 UNSPEC_VEC_EXTRACT))]
1629 operands[2] = operand_subword (operands[0], 0, 0, TImode);
1630 operands[3] = operand_subword (operands[0], 1, 0, TImode);
1631 operands[4] = gen_rtx_REG (DImode, REGNO (operands[1]));
1632 operands[5] = gen_rtx_REG (V2DImode, REGNO (operands[1]));
1636 ; Patterns used for secondary reloads
1639 ; z10 provides move instructions accepting larl memory operands.
1640 ; Unfortunately there is no such variant for QI, TI and FP mode moves.
1641 ; These patterns are also used for unaligned SI and DI accesses.
1643 (define_expand "reload<ALL:mode><P:mode>_tomem_z10"
1644 [(parallel [(match_operand:ALL 0 "memory_operand" "")
1645 (match_operand:ALL 1 "register_operand" "=d")
1646 (match_operand:P 2 "register_operand" "=&a")])]
1649 s390_reload_symref_address (operands[1], operands[0], operands[2], 1);
1653 (define_expand "reload<ALL:mode><P:mode>_toreg_z10"
1654 [(parallel [(match_operand:ALL 0 "register_operand" "=d")
1655 (match_operand:ALL 1 "memory_operand" "")
1656 (match_operand:P 2 "register_operand" "=a")])]
1659 s390_reload_symref_address (operands[0], operands[1], operands[2], 0);
1663 (define_expand "reload<P:mode>_larl_odd_addend_z10"
1664 [(parallel [(match_operand:P 0 "register_operand" "=d")
1665 (match_operand:P 1 "larl_operand" "")
1666 (match_operand:P 2 "register_operand" "=a")])]
1669 s390_reload_larl_operand (operands[0], operands[1], operands[2]);
1673 ; Handles loading a PLUS (load address) expression
1675 (define_expand "reload<mode>_plus"
1676 [(parallel [(match_operand:P 0 "register_operand" "=a")
1677 (match_operand:P 1 "s390_plus_operand" "")
1678 (match_operand:P 2 "register_operand" "=&a")])]
1681 s390_expand_plus_operand (operands[0], operands[1], operands[2]);
1685 ; Not all the indirect memory access instructions support the full
1686 ; format (long disp + index + base). So whenever a move from/to such
1687 ; an address is required and the instruction cannot deal with it we do
1688 ; a load address into a scratch register first and use this as the new
1690 ; This in particular is used for:
1691 ; - non-offsetable memory accesses for multiword moves
1692 ; - full vector reg moves with long displacements
1694 (define_expand "reload<mode>_la_in"
1695 [(parallel [(match_operand 0 "register_operand" "")
1696 (match_operand 1 "" "")
1697 (match_operand:P 2 "register_operand" "=&a")])]
1700 gcc_assert (MEM_P (operands[1]));
1701 s390_load_address (operands[2], find_replacement (&XEXP (operands[1], 0)));
1702 operands[1] = replace_equiv_address (operands[1], operands[2]);
1703 emit_move_insn (operands[0], operands[1]);
1707 (define_expand "reload<mode>_la_out"
1708 [(parallel [(match_operand 0 "" "")
1709 (match_operand 1 "register_operand" "")
1710 (match_operand:P 2 "register_operand" "=&a")])]
1713 gcc_assert (MEM_P (operands[0]));
1714 s390_load_address (operands[2], find_replacement (&XEXP (operands[0], 0)));
1715 operands[0] = replace_equiv_address (operands[0], operands[2]);
1716 emit_move_insn (operands[0], operands[1]);
1720 (define_expand "reload<mode>_PIC_addr"
1721 [(parallel [(match_operand 0 "register_operand" "=d")
1722 (match_operand 1 "larl_operand" "")
1723 (match_operand:P 2 "register_operand" "=a")])]
1726 rtx new_rtx = legitimize_pic_address (operands[1], operands[2]);
1727 emit_move_insn (operands[0], new_rtx);
1731 ; movdi instruction pattern(s).
1734 (define_expand "movdi"
1735 [(set (match_operand:DI 0 "general_operand" "")
1736 (match_operand:DI 1 "general_operand" ""))]
1739 /* Handle symbolic constants. */
1741 && (SYMBOLIC_CONST (operands[1])
1742 || (GET_CODE (operands[1]) == PLUS
1743 && XEXP (operands[1], 0) == pic_offset_table_rtx
1744 && SYMBOLIC_CONST (XEXP (operands[1], 1)))))
1745 emit_symbolic_move (operands);
1748 (define_insn "*movdi_64"
1749 [(set (match_operand:DI 0 "nonimmediate_operand"
1750 "=d, d, d, d, d, d, d, d,f,d,d,d,d,d,T,!*f,!*f,!*f,!R,!T,b,Q,d,t,Q,t,v,v,v,d,v,R,d")
1751 (match_operand:DI 1 "general_operand"
1752 " K,N0HD0,N1HD0,N2HD0,N3HD0,Os,N0SD0,N1SD0,d,f,L,b,d,T,d, *f, R, T,*f,*f,d,K,t,d,t,Q,K,v,d,v,R,v,ZL"))]
1788 [(set_attr "op_type" "RI,RI,RI,RI,RI,RIL,RIL,RIL,RRE,RRE,RXY,RIL,RRE,RXY,
1789 RXY,RR,RX,RXY,RX,RXY,RIL,SIL,*,*,RS,RS,VRI,VRR,VRS,VRS,
1791 (set_attr "type" "*,*,*,*,*,*,*,*,floaddf,floaddf,la,larl,lr,load,store,
1792 floaddf,floaddf,floaddf,fstoredf,fstoredf,larl,*,*,*,*,
1793 *,*,*,*,*,*,*,larl")
1794 (set_attr "cpu_facility" "*,*,*,*,*,extimm,extimm,extimm,dfp,dfp,longdisp,
1795 z10,*,*,*,*,*,longdisp,*,longdisp,
1796 z10,z10,*,*,*,*,vx,vx,vx,vx,vx,vx,*")
1797 (set_attr "z10prop" "z10_fwd_A1,
1824 (set_attr "relative_long" "*,*,*,*,*,*,*,*,*,*,
1825 *,yes,*,*,*,*,*,*,*,*,
1826 yes,*,*,*,*,*,*,*,*,*,
1831 [(set (match_operand:DI 0 "register_operand" "")
1832 (match_operand:DI 1 "register_operand" ""))]
1833 "TARGET_ZARCH && ACCESS_REG_P (operands[1])"
1834 [(set (match_dup 2) (match_dup 3))
1835 (set (match_dup 0) (ashift:DI (match_dup 0) (const_int 32)))
1836 (set (strict_low_part (match_dup 2)) (match_dup 4))]
1837 "operands[2] = gen_lowpart (SImode, operands[0]);
1838 s390_split_access_reg (operands[1], &operands[4], &operands[3]);")
1841 [(set (match_operand:DI 0 "register_operand" "")
1842 (match_operand:DI 1 "register_operand" ""))]
1843 "TARGET_ZARCH && ACCESS_REG_P (operands[0])
1844 && dead_or_set_p (insn, operands[1])"
1845 [(set (match_dup 3) (match_dup 2))
1846 (set (match_dup 1) (lshiftrt:DI (match_dup 1) (const_int 32)))
1847 (set (match_dup 4) (match_dup 2))]
1848 "operands[2] = gen_lowpart (SImode, operands[1]);
1849 s390_split_access_reg (operands[0], &operands[3], &operands[4]);")
1852 [(set (match_operand:DI 0 "register_operand" "")
1853 (match_operand:DI 1 "register_operand" ""))]
1854 "TARGET_ZARCH && ACCESS_REG_P (operands[0])
1855 && !dead_or_set_p (insn, operands[1])"
1856 [(set (match_dup 3) (match_dup 2))
1857 (set (match_dup 1) (rotate:DI (match_dup 1) (const_int 32)))
1858 (set (match_dup 4) (match_dup 2))
1859 (set (match_dup 1) (rotate:DI (match_dup 1) (const_int 32)))]
1860 "operands[2] = gen_lowpart (SImode, operands[1]);
1861 s390_split_access_reg (operands[0], &operands[3], &operands[4]);")
1863 (define_insn "*movdi_31"
1864 [(set (match_operand:DI 0 "nonimmediate_operand"
1865 "=d,d,Q,S,d ,o,!*f,!*f,!*f,!R,!T,d")
1866 (match_operand:DI 1 "general_operand"
1867 " Q,S,d,d,dPT,d, *f, R, T,*f,*f,b"))]
1882 [(set_attr "op_type" "RS,RSY,RS,RSY,*,*,RR,RX,RXY,RX,RXY,*")
1883 (set_attr "type" "lm,lm,stm,stm,*,*,floaddf,floaddf,floaddf,fstoredf,fstoredf,*")
1884 (set_attr "cpu_facility" "*,longdisp,*,longdisp,*,*,*,*,longdisp,*,longdisp,z10")])
1886 ; For a load from a symbol ref we can use one of the target registers
1887 ; together with larl to load the address.
1889 [(set (match_operand:DI 0 "register_operand" "")
1890 (match_operand:DI 1 "memory_operand" ""))]
1891 "!TARGET_ZARCH && reload_completed && TARGET_Z10
1892 && larl_operand (XEXP (operands[1], 0), SImode)"
1893 [(set (match_dup 2) (match_dup 3))
1894 (set (match_dup 0) (match_dup 1))]
1896 operands[2] = operand_subword (operands[0], 1, 0, DImode);
1897 operands[3] = XEXP (operands[1], 0);
1898 operands[1] = replace_equiv_address (operands[1], operands[2]);
1902 [(set (match_operand:DI 0 "nonimmediate_operand" "")
1903 (match_operand:DI 1 "general_operand" ""))]
1904 "!TARGET_ZARCH && reload_completed
1905 && !s_operand (operands[0], DImode)
1906 && !s_operand (operands[1], DImode)
1907 && s390_split_ok_p (operands[0], operands[1], DImode, 0)"
1908 [(set (match_dup 2) (match_dup 4))
1909 (set (match_dup 3) (match_dup 5))]
1911 operands[2] = operand_subword (operands[0], 0, 0, DImode);
1912 operands[3] = operand_subword (operands[0], 1, 0, DImode);
1913 operands[4] = operand_subword (operands[1], 0, 0, DImode);
1914 operands[5] = operand_subword (operands[1], 1, 0, DImode);
1918 [(set (match_operand:DI 0 "nonimmediate_operand" "")
1919 (match_operand:DI 1 "general_operand" ""))]
1920 "!TARGET_ZARCH && reload_completed
1921 && !s_operand (operands[0], DImode)
1922 && !s_operand (operands[1], DImode)
1923 && s390_split_ok_p (operands[0], operands[1], DImode, 1)"
1924 [(set (match_dup 2) (match_dup 4))
1925 (set (match_dup 3) (match_dup 5))]
1927 operands[2] = operand_subword (operands[0], 1, 0, DImode);
1928 operands[3] = operand_subword (operands[0], 0, 0, DImode);
1929 operands[4] = operand_subword (operands[1], 1, 0, DImode);
1930 operands[5] = operand_subword (operands[1], 0, 0, DImode);
1934 [(set (match_operand:DI 0 "register_operand" "")
1935 (match_operand:DI 1 "memory_operand" ""))]
1936 "!TARGET_ZARCH && reload_completed
1937 && !FP_REG_P (operands[0])
1938 && !s_operand (operands[1], VOIDmode)"
1939 [(set (match_dup 0) (match_dup 1))]
1941 rtx addr = operand_subword (operands[0], 1, 0, DImode);
1942 s390_load_address (addr, XEXP (operands[1], 0));
1943 operands[1] = replace_equiv_address (operands[1], addr);
1947 [(set (match_operand:DI 0 "register_operand" "")
1948 (mem:DI (match_operand 1 "address_operand" "")))]
1950 && !FP_REG_P (operands[0])
1951 && GET_CODE (operands[1]) == SYMBOL_REF
1952 && CONSTANT_POOL_ADDRESS_P (operands[1])
1953 && get_pool_mode (operands[1]) == DImode
1954 && legitimate_reload_constant_p (get_pool_constant (operands[1]))"
1955 [(set (match_dup 0) (match_dup 2))]
1956 "operands[2] = get_pool_constant (operands[1]);")
1958 (define_insn "*la_64"
1959 [(set (match_operand:DI 0 "register_operand" "=d,d")
1960 (match_operand:QI 1 "address_operand" "ZR,ZT"))]
1965 [(set_attr "op_type" "RX,RXY")
1966 (set_attr "type" "la")
1967 (set_attr "cpu_facility" "*,longdisp")
1968 (set_attr "z10prop" "z10_fwd_A1,z10_fwd_A1")])
1972 [(set (match_operand:DI 0 "register_operand" "")
1973 (match_operand:QI 1 "address_operand" ""))
1974 (clobber (reg:CC CC_REGNUM))])]
1976 && preferred_la_operand_p (operands[1], const0_rtx)"
1977 [(set (match_dup 0) (match_dup 1))]
1981 [(set (match_operand:DI 0 "register_operand" "")
1982 (match_operand:DI 1 "register_operand" ""))
1985 (plus:DI (match_dup 0)
1986 (match_operand:DI 2 "nonmemory_operand" "")))
1987 (clobber (reg:CC CC_REGNUM))])]
1989 && !reg_overlap_mentioned_p (operands[0], operands[2])
1990 && preferred_la_operand_p (operands[1], operands[2])"
1991 [(set (match_dup 0) (plus:DI (match_dup 1) (match_dup 2)))]
1995 ; movsi instruction pattern(s).
1998 (define_expand "movsi"
1999 [(set (match_operand:SI 0 "general_operand" "")
2000 (match_operand:SI 1 "general_operand" ""))]
2003 /* Handle symbolic constants. */
2005 && (SYMBOLIC_CONST (operands[1])
2006 || (GET_CODE (operands[1]) == PLUS
2007 && XEXP (operands[1], 0) == pic_offset_table_rtx
2008 && SYMBOLIC_CONST (XEXP(operands[1], 1)))))
2009 emit_symbolic_move (operands);
2012 (define_insn "*movsi_larl"
2013 [(set (match_operand:SI 0 "register_operand" "=d")
2014 (match_operand:SI 1 "larl_operand" "X"))]
2016 && !FP_REG_P (operands[0])"
2018 [(set_attr "op_type" "RIL")
2019 (set_attr "type" "larl")
2020 (set_attr "z10prop" "z10_fwd_A1")
2021 (set_attr "relative_long" "yes")])
2023 (define_insn "*movsi_zarch"
2024 [(set (match_operand:SI 0 "nonimmediate_operand"
2025 "=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")
2026 (match_operand:SI 1 "general_operand"
2027 " 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"))]
2060 [(set_attr "op_type" "RI,RI,RI,RIL,RXY,RIL,RR,RX,RXY,RX,RXY,
2061 RR,RR,RXE,RX,RXY,RX,RXY,RRE,RRE,RS,RIL,SIL,RS,VRI,VRR,VRS,VRS,VRX,VRX")
2062 (set_attr "type" "*,
2086 (set_attr "cpu_facility" "*,*,*,extimm,longdisp,z10,*,*,longdisp,*,longdisp,
2087 vx,*,vx,*,longdisp,*,longdisp,*,*,*,z10,z10,*,vx,vx,vx,vx,vx,vx")
2088 (set_attr "z10prop" "z10_fwd_A1,
2112 (set_attr "relative_long" "*,*,*,*,*,yes,*,*,*,*,
2113 *,*,*,*,*,*,*,*,*,*,
2114 *,yes,*,*,*,*,*,*,*,*")])
2116 (define_insn "*movsi_esa"
2117 [(set (match_operand:SI 0 "nonimmediate_operand" "=d,d,d,R,!*f,!*f,!*f,!*f,!R,d,t,Q,t")
2118 (match_operand:SI 1 "general_operand" "K,d,R,d, *f, *f, R, R,*f,t,d,t,Q"))]
2134 [(set_attr "op_type" "RI,RR,RX,RX,RR,RR,RXE,RX,RX,RRE,RRE,RS,RS")
2135 (set_attr "type" "*,lr,load,store,floadsf,floadsf,floadsf,floadsf,fstoresf,*,*,*,*")
2136 (set_attr "z10prop" "z10_fwd_A1,z10_fr_E1,z10_fwd_A3,z10_rec,*,*,*,*,*,z10_super_E1,
2138 (set_attr "cpu_facility" "*,*,*,*,vx,*,vx,*,*,*,*,*,*")
2142 [(set (match_operand:SI 0 "register_operand" "")
2143 (mem:SI (match_operand 1 "address_operand" "")))]
2144 "!FP_REG_P (operands[0])
2145 && GET_CODE (operands[1]) == SYMBOL_REF
2146 && CONSTANT_POOL_ADDRESS_P (operands[1])
2147 && get_pool_mode (operands[1]) == SImode
2148 && legitimate_reload_constant_p (get_pool_constant (operands[1]))"
2149 [(set (match_dup 0) (match_dup 2))]
2150 "operands[2] = get_pool_constant (operands[1]);")
2152 (define_insn "*la_31"
2153 [(set (match_operand:SI 0 "register_operand" "=d,d")
2154 (match_operand:QI 1 "address_operand" "ZR,ZT"))]
2155 "!TARGET_64BIT && legitimate_la_operand_p (operands[1])"
2159 [(set_attr "op_type" "RX,RXY")
2160 (set_attr "type" "la")
2161 (set_attr "cpu_facility" "*,longdisp")
2162 (set_attr "z10prop" "z10_fwd_A1,z10_fwd_A1")])
2166 [(set (match_operand:SI 0 "register_operand" "")
2167 (match_operand:QI 1 "address_operand" ""))
2168 (clobber (reg:CC CC_REGNUM))])]
2170 && preferred_la_operand_p (operands[1], const0_rtx)"
2171 [(set (match_dup 0) (match_dup 1))]
2175 [(set (match_operand:SI 0 "register_operand" "")
2176 (match_operand:SI 1 "register_operand" ""))
2179 (plus:SI (match_dup 0)
2180 (match_operand:SI 2 "nonmemory_operand" "")))
2181 (clobber (reg:CC CC_REGNUM))])]
2183 && !reg_overlap_mentioned_p (operands[0], operands[2])
2184 && preferred_la_operand_p (operands[1], operands[2])"
2185 [(set (match_dup 0) (plus:SI (match_dup 1) (match_dup 2)))]
2188 (define_insn "*la_31_and"
2189 [(set (match_operand:SI 0 "register_operand" "=d,d")
2190 (and:SI (match_operand:QI 1 "address_operand" "ZR,ZT")
2191 (const_int 2147483647)))]
2196 [(set_attr "op_type" "RX,RXY")
2197 (set_attr "type" "la")
2198 (set_attr "cpu_facility" "*,longdisp")
2199 (set_attr "z10prop" "z10_fwd_A1,z10_fwd_A1")])
2201 (define_insn_and_split "*la_31_and_cc"
2202 [(set (match_operand:SI 0 "register_operand" "=d")
2203 (and:SI (match_operand:QI 1 "address_operand" "p")
2204 (const_int 2147483647)))
2205 (clobber (reg:CC CC_REGNUM))]
2208 "&& reload_completed"
2210 (and:SI (match_dup 1) (const_int 2147483647)))]
2212 [(set_attr "op_type" "RX")
2213 (set_attr "type" "la")])
2215 (define_insn "force_la_31"
2216 [(set (match_operand:SI 0 "register_operand" "=d,d")
2217 (match_operand:QI 1 "address_operand" "ZR,ZT"))
2218 (use (const_int 0))]
2223 [(set_attr "op_type" "RX")
2224 (set_attr "type" "la")
2225 (set_attr "cpu_facility" "*,longdisp")
2226 (set_attr "z10prop" "z10_fwd_A1,z10_fwd_A1")])
2229 ; movhi instruction pattern(s).
2232 (define_expand "movhi"
2233 [(set (match_operand:HI 0 "nonimmediate_operand" "")
2234 (match_operand:HI 1 "general_operand" ""))]
2237 /* Make it explicit that loading a register from memory
2238 always sign-extends (at least) to SImode. */
2239 if (optimize && can_create_pseudo_p ()
2240 && register_operand (operands[0], VOIDmode)
2241 && GET_CODE (operands[1]) == MEM)
2243 rtx tmp = gen_reg_rtx (SImode);
2244 rtx ext = gen_rtx_SIGN_EXTEND (SImode, operands[1]);
2245 emit_insn (gen_rtx_SET (tmp, ext));
2246 operands[1] = gen_lowpart (HImode, tmp);
2250 (define_insn "*movhi"
2251 [(set (match_operand:HI 0 "nonimmediate_operand" "=d,d,d,d,d,R,T,b,Q,v,v,v,d,v,R")
2252 (match_operand:HI 1 "general_operand" " d,n,R,T,b,d,d,d,K,K,v,d,v,R,v"))]
2270 [(set_attr "op_type" "RR,RI,RX,RXY,RIL,RX,RXY,RIL,SIL,VRI,VRR,VRS,VRS,VRX,VRX")
2271 (set_attr "type" "lr,*,*,*,larl,store,store,store,*,*,*,*,*,*,*")
2272 (set_attr "cpu_facility" "*,*,*,longdisp,z10,*,longdisp,z10,z10,vx,vx,vx,vx,vx,vx")
2273 (set_attr "z10prop" "z10_fr_E1,
2281 z10_super,*,*,*,*,*,*")
2282 (set_attr "relative_long" "*,*,*,*,yes,*,*,yes,*,*,*,*,*,*,*")])
2285 [(set (match_operand:HI 0 "register_operand" "")
2286 (mem:HI (match_operand 1 "address_operand" "")))]
2287 "GET_CODE (operands[1]) == SYMBOL_REF
2288 && CONSTANT_POOL_ADDRESS_P (operands[1])
2289 && get_pool_mode (operands[1]) == HImode
2290 && GET_CODE (get_pool_constant (operands[1])) == CONST_INT"
2291 [(set (match_dup 0) (match_dup 2))]
2292 "operands[2] = get_pool_constant (operands[1]);")
2295 ; movqi instruction pattern(s).
2298 (define_expand "movqi"
2299 [(set (match_operand:QI 0 "nonimmediate_operand" "")
2300 (match_operand:QI 1 "general_operand" ""))]
2303 /* On z/Architecture, zero-extending from memory to register
2304 is just as fast as a QImode load. */
2305 if (TARGET_ZARCH && optimize && can_create_pseudo_p ()
2306 && register_operand (operands[0], VOIDmode)
2307 && GET_CODE (operands[1]) == MEM)
2309 rtx tmp = gen_reg_rtx (DImode);
2310 rtx ext = gen_rtx_ZERO_EXTEND (DImode, operands[1]);
2311 emit_insn (gen_rtx_SET (tmp, ext));
2312 operands[1] = gen_lowpart (QImode, tmp);
2316 (define_insn "*movqi"
2317 [(set (match_operand:QI 0 "nonimmediate_operand" "=d,d,d,d,R,T,Q,S,?Q,v,v,v,d,v,R")
2318 (match_operand:QI 1 "general_operand" " d,n,R,T,d,d,n,n,?Q,K,v,d,v,R,v"))]
2336 [(set_attr "op_type" "RR,RI,RX,RXY,RX,RXY,SI,SIY,SS,VRI,VRR,VRS,VRS,VRX,VRX")
2337 (set_attr "type" "lr,*,*,*,store,store,store,store,*,*,*,*,*,*,*")
2338 (set_attr "cpu_facility" "*,*,*,longdisp,*,longdisp,*,longdisp,*,vx,vx,vx,vx,vx,vx")
2339 (set_attr "z10prop" "z10_fr_E1,
2350 [(set (match_operand:QI 0 "nonimmediate_operand" "")
2351 (mem:QI (match_operand 1 "address_operand" "")))]
2352 "GET_CODE (operands[1]) == SYMBOL_REF
2353 && CONSTANT_POOL_ADDRESS_P (operands[1])
2354 && get_pool_mode (operands[1]) == QImode
2355 && GET_CODE (get_pool_constant (operands[1])) == CONST_INT"
2356 [(set (match_dup 0) (match_dup 2))]
2357 "operands[2] = get_pool_constant (operands[1]);")
2360 ; movstrictqi instruction pattern(s).
2363 (define_insn "*movstrictqi"
2364 [(set (strict_low_part (match_operand:QI 0 "register_operand" "+d,d"))
2365 (match_operand:QI 1 "memory_operand" "R,T"))]
2370 [(set_attr "op_type" "RX,RXY")
2371 (set_attr "cpu_facility" "*,longdisp")
2372 (set_attr "z10prop" "z10_super_E1,z10_super_E1")])
2375 ; movstricthi instruction pattern(s).
2378 (define_insn "*movstricthi"
2379 [(set (strict_low_part (match_operand:HI 0 "register_operand" "+d,d"))
2380 (match_operand:HI 1 "memory_operand" "Q,S"))
2381 (clobber (reg:CC CC_REGNUM))]
2386 [(set_attr "op_type" "RS,RSY")
2387 (set_attr "cpu_facility" "*,longdisp")
2388 (set_attr "z10prop" "z10_super_E1,z10_super_E1")])
2391 ; movstrictsi instruction pattern(s).
2394 (define_insn "movstrictsi"
2395 [(set (strict_low_part (match_operand:SI 0 "register_operand" "+d,d,d,d"))
2396 (match_operand:SI 1 "general_operand" "d,R,T,t"))]
2403 [(set_attr "op_type" "RR,RX,RXY,RRE")
2404 (set_attr "type" "lr,load,load,*")
2405 (set_attr "cpu_facility" "*,*,longdisp,*")
2406 (set_attr "z10prop" "z10_fr_E1,z10_fwd_A3,z10_fwd_A3,z10_super_E1")])
2409 ; mov(tf|td) instruction pattern(s).
2412 (define_expand "mov<mode>"
2413 [(set (match_operand:TD_TF 0 "nonimmediate_operand" "")
2414 (match_operand:TD_TF 1 "general_operand" ""))]
2418 (define_insn "*mov<mode>_64"
2419 [(set (match_operand:TD_TF 0 "nonimmediate_operand" "=f,f,f,o,d,S, d,o")
2420 (match_operand:TD_TF 1 "general_operand" " G,f,o,f,S,d,dT,d"))]
2431 [(set_attr "op_type" "RRE,RRE,*,*,RSY,RSY,*,*")
2432 (set_attr "type" "fsimptf,fsimptf,*,*,lm,stm,*,*")
2433 (set_attr "cpu_facility" "z196,*,*,*,*,*,*,*")])
2435 (define_insn "*mov<mode>_31"
2436 [(set (match_operand:TD_TF 0 "nonimmediate_operand" "=f,f,f,o")
2437 (match_operand:TD_TF 1 "general_operand" " G,f,o,f"))]
2444 [(set_attr "op_type" "RRE,RRE,*,*")
2445 (set_attr "type" "fsimptf,fsimptf,*,*")
2446 (set_attr "cpu_facility" "z196,*,*,*")])
2448 ; TFmode in GPRs splitters
2451 [(set (match_operand:TD_TF 0 "nonimmediate_operand" "")
2452 (match_operand:TD_TF 1 "general_operand" ""))]
2453 "TARGET_ZARCH && reload_completed
2454 && !s_operand (operands[0], <MODE>mode)
2455 && !s_operand (operands[1], <MODE>mode)
2456 && s390_split_ok_p (operands[0], operands[1], <MODE>mode, 0)"
2457 [(set (match_dup 2) (match_dup 4))
2458 (set (match_dup 3) (match_dup 5))]
2460 operands[2] = operand_subword (operands[0], 0, 0, <MODE>mode);
2461 operands[3] = operand_subword (operands[0], 1, 0, <MODE>mode);
2462 operands[4] = operand_subword (operands[1], 0, 0, <MODE>mode);
2463 operands[5] = operand_subword (operands[1], 1, 0, <MODE>mode);
2467 [(set (match_operand:TD_TF 0 "nonimmediate_operand" "")
2468 (match_operand:TD_TF 1 "general_operand" ""))]
2469 "TARGET_ZARCH && reload_completed
2470 && !s_operand (operands[0], <MODE>mode)
2471 && !s_operand (operands[1], <MODE>mode)
2472 && s390_split_ok_p (operands[0], operands[1], <MODE>mode, 1)"
2473 [(set (match_dup 2) (match_dup 4))
2474 (set (match_dup 3) (match_dup 5))]
2476 operands[2] = operand_subword (operands[0], 1, 0, <MODE>mode);
2477 operands[3] = operand_subword (operands[0], 0, 0, <MODE>mode);
2478 operands[4] = operand_subword (operands[1], 1, 0, <MODE>mode);
2479 operands[5] = operand_subword (operands[1], 0, 0, <MODE>mode);
2483 [(set (match_operand:TD_TF 0 "register_operand" "")
2484 (match_operand:TD_TF 1 "memory_operand" ""))]
2485 "TARGET_ZARCH && reload_completed
2486 && GENERAL_REG_P (operands[0])
2487 && !s_operand (operands[1], VOIDmode)"
2488 [(set (match_dup 0) (match_dup 1))]
2490 rtx addr = operand_subword (operands[0], 1, 0, <MODE>mode);
2491 addr = gen_lowpart (Pmode, addr);
2492 s390_load_address (addr, XEXP (operands[1], 0));
2493 operands[1] = replace_equiv_address (operands[1], addr);
2496 ; TFmode in BFPs splitters
2499 [(set (match_operand:TD_TF 0 "register_operand" "")
2500 (match_operand:TD_TF 1 "memory_operand" ""))]
2501 "reload_completed && offsettable_memref_p (operands[1])
2502 && FP_REG_P (operands[0])"
2503 [(set (match_dup 2) (match_dup 4))
2504 (set (match_dup 3) (match_dup 5))]
2506 operands[2] = simplify_gen_subreg (<HALF_TMODE>mode, operands[0],
2508 operands[3] = simplify_gen_subreg (<HALF_TMODE>mode, operands[0],
2510 operands[4] = adjust_address_nv (operands[1], <HALF_TMODE>mode, 0);
2511 operands[5] = adjust_address_nv (operands[1], <HALF_TMODE>mode, 8);
2515 [(set (match_operand:TD_TF 0 "memory_operand" "")
2516 (match_operand:TD_TF 1 "register_operand" ""))]
2517 "reload_completed && offsettable_memref_p (operands[0])
2518 && FP_REG_P (operands[1])"
2519 [(set (match_dup 2) (match_dup 4))
2520 (set (match_dup 3) (match_dup 5))]
2522 operands[2] = adjust_address_nv (operands[0], <HALF_TMODE>mode, 0);
2523 operands[3] = adjust_address_nv (operands[0], <HALF_TMODE>mode, 8);
2524 operands[4] = simplify_gen_subreg (<HALF_TMODE>mode, operands[1],
2526 operands[5] = simplify_gen_subreg (<HALF_TMODE>mode, operands[1],
2531 ; mov(df|dd) instruction pattern(s).
2534 (define_expand "mov<mode>"
2535 [(set (match_operand:DD_DF 0 "nonimmediate_operand" "")
2536 (match_operand:DD_DF 1 "general_operand" ""))]
2540 (define_insn "*mov<mode>_64dfp"
2541 [(set (match_operand:DD_DF 0 "nonimmediate_operand"
2542 "=f,f,f,d,f,f,R,T,d,d,d,d,b,T,v,v,v,d,v,R")
2543 (match_operand:DD_DF 1 "general_operand"
2544 " G,f,d,f,R,T,f,f,G,d,b,T,d,d,v,G,d,v,R,v"))]
2567 [(set_attr "op_type" "RRE,RR,RRE,RRE,RX,RXY,RX,RXY,RI,RRE,RIL,RXY,RIL,RXY,VRR,VRI,VRS,VRS,VRX,VRX")
2568 (set_attr "type" "fsimpdf,floaddf,floaddf,floaddf,floaddf,floaddf,
2569 fstoredf,fstoredf,*,lr,load,load,store,store,*,*,*,*,load,store")
2570 (set_attr "z10prop" "*,*,*,*,*,*,*,*,z10_fwd_A1,z10_fr_E1,z10_fwd_A3,z10_fwd_A3,z10_rec,z10_rec,*,*,*,*,*,*")
2571 (set_attr "cpu_facility" "z196,*,*,*,*,longdisp,*,longdisp,*,*,z10,*,z10,*,vx,vx,vx,vx,vx,vx")
2572 (set_attr "relative_long" "*,*,*,*,*,*,*,*,*,*,yes,*,yes,*,*,*,*,*,*,*")])
2574 (define_insn "*mov<mode>_64"
2575 [(set (match_operand:DD_DF 0 "nonimmediate_operand" "=f,f,f,f,R,T,d,d,d,d,b,T")
2576 (match_operand:DD_DF 1 "general_operand" " G,f,R,T,f,f,G,d,b,T,d,d"))]
2591 [(set_attr "op_type" "RRE,RR,RX,RXY,RX,RXY,RI,RRE,RIL,RXY,RIL,RXY")
2592 (set_attr "type" "fsimpdf,fload<mode>,fload<mode>,fload<mode>,
2593 fstore<mode>,fstore<mode>,*,lr,load,load,store,store")
2594 (set_attr "z10prop" "*,*,*,*,*,*,z10_fwd_A1,z10_fr_E1,z10_fwd_A3,z10_fwd_A3,z10_rec,z10_rec")
2595 (set_attr "cpu_facility" "z196,*,*,longdisp,*,longdisp,*,*,z10,*,z10,*")
2596 (set_attr "relative_long" "*,*,*,*,*,*,*,*,yes,*,*,*")])
2598 (define_insn "*mov<mode>_31"
2599 [(set (match_operand:DD_DF 0 "nonimmediate_operand"
2600 "=f,f,f,f,R,T,d,d,Q,S, d,o")
2601 (match_operand:DD_DF 1 "general_operand"
2602 " G,f,R,T,f,f,Q,S,d,d,dPT,d"))]
2617 [(set_attr "op_type" "RRE,RR,RX,RXY,RX,RXY,RS,RSY,RS,RSY,*,*")
2618 (set_attr "type" "fsimpdf,fload<mode>,fload<mode>,fload<mode>,
2619 fstore<mode>,fstore<mode>,lm,lm,stm,stm,*,*")
2620 (set_attr "cpu_facility" "z196,*,*,longdisp,*,longdisp,*,longdisp,*,longdisp,*,*")])
2623 [(set (match_operand:DD_DF 0 "nonimmediate_operand" "")
2624 (match_operand:DD_DF 1 "general_operand" ""))]
2625 "!TARGET_ZARCH && reload_completed
2626 && !s_operand (operands[0], <MODE>mode)
2627 && !s_operand (operands[1], <MODE>mode)
2628 && s390_split_ok_p (operands[0], operands[1], <MODE>mode, 0)"
2629 [(set (match_dup 2) (match_dup 4))
2630 (set (match_dup 3) (match_dup 5))]
2632 operands[2] = operand_subword (operands[0], 0, 0, <MODE>mode);
2633 operands[3] = operand_subword (operands[0], 1, 0, <MODE>mode);
2634 operands[4] = operand_subword (operands[1], 0, 0, <MODE>mode);
2635 operands[5] = operand_subword (operands[1], 1, 0, <MODE>mode);
2639 [(set (match_operand:DD_DF 0 "nonimmediate_operand" "")
2640 (match_operand:DD_DF 1 "general_operand" ""))]
2641 "!TARGET_ZARCH && reload_completed
2642 && !s_operand (operands[0], <MODE>mode)
2643 && !s_operand (operands[1], <MODE>mode)
2644 && s390_split_ok_p (operands[0], operands[1], <MODE>mode, 1)"
2645 [(set (match_dup 2) (match_dup 4))
2646 (set (match_dup 3) (match_dup 5))]
2648 operands[2] = operand_subword (operands[0], 1, 0, <MODE>mode);
2649 operands[3] = operand_subword (operands[0], 0, 0, <MODE>mode);
2650 operands[4] = operand_subword (operands[1], 1, 0, <MODE>mode);
2651 operands[5] = operand_subword (operands[1], 0, 0, <MODE>mode);
2655 [(set (match_operand:DD_DF 0 "register_operand" "")
2656 (match_operand:DD_DF 1 "memory_operand" ""))]
2657 "!TARGET_ZARCH && reload_completed
2658 && !FP_REG_P (operands[0])
2659 && !s_operand (operands[1], VOIDmode)"
2660 [(set (match_dup 0) (match_dup 1))]
2662 rtx addr = operand_subword (operands[0], 1, 0, <MODE>mode);
2663 s390_load_address (addr, XEXP (operands[1], 0));
2664 operands[1] = replace_equiv_address (operands[1], addr);
2668 ; mov(sf|sd) instruction pattern(s).
2671 (define_insn "mov<mode>"
2672 [(set (match_operand:SD_SF 0 "nonimmediate_operand"
2673 "=f,f,f,f,f,f,R,T,d,d,d,d,d,b,R,T,v,v,v,d,v,R")
2674 (match_operand:SD_SF 1 "general_operand"
2675 " G,f,f,R,R,T,f,f,G,d,b,R,T,d,d,d,v,G,d,v,R,v"))]
2700 [(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")
2701 (set_attr "type" "fsimpsf,fsimpsf,fload<mode>,fload<mode>,fload<mode>,fload<mode>,
2702 fstore<mode>,fstore<mode>,*,lr,load,load,load,store,store,store,*,*,*,*,load,store")
2703 (set_attr "z10prop" "*,*,*,*,*,*,*,*,z10_fwd_A1,z10_fr_E1,z10_fr_E1,z10_fwd_A3,z10_fwd_A3,z10_rec,z10_rec,z10_rec,*,*,*,*,*,*")
2704 (set_attr "cpu_facility" "z196,vx,*,vx,*,longdisp,*,longdisp,*,*,z10,*,longdisp,z10,*,longdisp,vx,vx,vx,vx,vx,vx")
2705 (set_attr "relative_long" "*,*,*,*,*,*,*,*,*,*,yes,*,*,yes,*,*,*,*,*,*,*,*")])
2708 ; movcc instruction pattern
2711 (define_insn "movcc"
2712 [(set (match_operand:CC 0 "nonimmediate_operand" "=d,c,d,d,d,R,T")
2713 (match_operand:CC 1 "nonimmediate_operand" " d,d,c,R,T,d,d"))]
2723 [(set_attr "op_type" "RR,RI,RRE,RX,RXY,RX,RXY")
2724 (set_attr "type" "lr,*,*,load,load,store,store")
2725 (set_attr "cpu_facility" "*,*,*,*,longdisp,*,longdisp")
2726 (set_attr "z10prop" "z10_fr_E1,z10_super,*,z10_fwd_A3,z10_fwd_A3,z10_rec,z10_rec")
2727 (set_attr "z196prop" "*,*,z196_ends,*,*,*,*")])
2730 ; Block move (MVC) patterns.
2734 [(set (match_operand:BLK 0 "memory_operand" "=Q")
2735 (match_operand:BLK 1 "memory_operand" "Q"))
2736 (use (match_operand 2 "const_int_operand" "n"))]
2737 "INTVAL (operands[2]) >= 1 && INTVAL (operands[2]) <= 256"
2738 "mvc\t%O0(%2,%R0),%S1"
2739 [(set_attr "op_type" "SS")])
2741 ; This splitter converts a QI to QI mode copy into a BLK mode copy in
2742 ; order to have it implemented with mvc.
2745 [(set (match_operand:QI 0 "memory_operand" "")
2746 (match_operand:QI 1 "memory_operand" ""))]
2749 [(set (match_dup 0) (match_dup 1))
2750 (use (const_int 1))])]
2752 operands[0] = adjust_address (operands[0], BLKmode, 0);
2753 operands[1] = adjust_address (operands[1], BLKmode, 0);
2759 [(set (match_operand:BLK 0 "memory_operand" "")
2760 (match_operand:BLK 1 "memory_operand" ""))
2761 (use (match_operand 2 "const_int_operand" ""))])
2763 [(set (match_operand:BLK 3 "memory_operand" "")
2764 (match_operand:BLK 4 "memory_operand" ""))
2765 (use (match_operand 5 "const_int_operand" ""))])]
2766 "((INTVAL (operands[2]) > 16 && INTVAL (operands[5]) > 16)
2767 || (INTVAL (operands[2]) + INTVAL (operands[5]) <= 16))
2768 && s390_offset_p (operands[0], operands[3], operands[2])
2769 && s390_offset_p (operands[1], operands[4], operands[2])
2770 && !s390_overlap_p (operands[0], operands[1],
2771 INTVAL (operands[2]) + INTVAL (operands[5]))
2772 && INTVAL (operands[2]) + INTVAL (operands[5]) <= 256"
2774 [(set (match_dup 6) (match_dup 7))
2775 (use (match_dup 8))])]
2776 "operands[6] = gen_rtx_MEM (BLKmode, XEXP (operands[0], 0));
2777 operands[7] = gen_rtx_MEM (BLKmode, XEXP (operands[1], 0));
2778 operands[8] = GEN_INT (INTVAL (operands[2]) + INTVAL (operands[5]));")
2782 [(set (match_operand:BLK 0 "plus16_Q_operand" "")
2783 (match_operand:BLK 1 "plus16_Q_operand" ""))
2784 (use (match_operand 2 "const_int_operand" ""))])]
2785 "INTVAL (operands[2]) > 16 && INTVAL (operands[2]) <= 32"
2787 [(set (match_dup 0) (match_dup 1))
2788 (use (const_int 16))])
2790 [(set (match_dup 3) (match_dup 4))
2791 (use (match_dup 5))])]
2792 "operands[3] = change_address (operands[0], VOIDmode,
2793 plus_constant (Pmode, XEXP (operands[0], 0), 16));
2794 operands[4] = change_address (operands[1], VOIDmode,
2795 plus_constant (Pmode, XEXP (operands[1], 0), 16));
2796 operands[5] = GEN_INT (INTVAL (operands[2]) - 16);")
2800 ; load_multiple pattern(s).
2802 ; ??? Due to reload problems with replacing registers inside match_parallel
2803 ; we currently support load_multiple/store_multiple only after reload.
2806 (define_expand "load_multiple"
2807 [(match_par_dup 3 [(set (match_operand 0 "" "")
2808 (match_operand 1 "" ""))
2809 (use (match_operand 2 "" ""))])]
2818 /* Support only loading a constant number of fixed-point registers from
2819 memory and only bother with this if more than two */
2820 if (GET_CODE (operands[2]) != CONST_INT
2821 || INTVAL (operands[2]) < 2
2822 || INTVAL (operands[2]) > 16
2823 || GET_CODE (operands[1]) != MEM
2824 || GET_CODE (operands[0]) != REG
2825 || REGNO (operands[0]) >= 16)
2828 count = INTVAL (operands[2]);
2829 regno = REGNO (operands[0]);
2830 mode = GET_MODE (operands[0]);
2831 if (mode != SImode && (!TARGET_ZARCH || mode != DImode))
2834 operands[3] = gen_rtx_PARALLEL (VOIDmode, rtvec_alloc (count));
2835 if (!can_create_pseudo_p ())
2837 if (GET_CODE (XEXP (operands[1], 0)) == REG)
2839 from = XEXP (operands[1], 0);
2842 else if (GET_CODE (XEXP (operands[1], 0)) == PLUS
2843 && GET_CODE (XEXP (XEXP (operands[1], 0), 0)) == REG
2844 && GET_CODE (XEXP (XEXP (operands[1], 0), 1)) == CONST_INT)
2846 from = XEXP (XEXP (operands[1], 0), 0);
2847 off = INTVAL (XEXP (XEXP (operands[1], 0), 1));
2854 from = force_reg (Pmode, XEXP (operands[1], 0));
2858 for (i = 0; i < count; i++)
2859 XVECEXP (operands[3], 0, i)
2860 = gen_rtx_SET (gen_rtx_REG (mode, regno + i),
2861 change_address (operands[1], mode,
2862 plus_constant (Pmode, from,
2863 off + i * GET_MODE_SIZE (mode))));
2866 (define_insn "*load_multiple_di"
2867 [(match_parallel 0 "load_multiple_operation"
2868 [(set (match_operand:DI 1 "register_operand" "=r")
2869 (match_operand:DI 2 "s_operand" "S"))])]
2870 "reload_completed && TARGET_ZARCH"
2872 int words = XVECLEN (operands[0], 0);
2873 operands[0] = gen_rtx_REG (DImode, REGNO (operands[1]) + words - 1);
2874 return "lmg\t%1,%0,%S2";
2876 [(set_attr "op_type" "RSY")
2877 (set_attr "type" "lm")])
2879 (define_insn "*load_multiple_si"
2880 [(match_parallel 0 "load_multiple_operation"
2881 [(set (match_operand:SI 1 "register_operand" "=r,r")
2882 (match_operand:SI 2 "s_operand" "Q,S"))])]
2885 int words = XVECLEN (operands[0], 0);
2886 operands[0] = gen_rtx_REG (SImode, REGNO (operands[1]) + words - 1);
2887 return which_alternative == 0 ? "lm\t%1,%0,%S2" : "lmy\t%1,%0,%S2";
2889 [(set_attr "op_type" "RS,RSY")
2890 (set_attr "cpu_facility" "*,longdisp")
2891 (set_attr "type" "lm")])
2894 ; store multiple pattern(s).
2897 (define_expand "store_multiple"
2898 [(match_par_dup 3 [(set (match_operand 0 "" "")
2899 (match_operand 1 "" ""))
2900 (use (match_operand 2 "" ""))])]
2909 /* Support only storing a constant number of fixed-point registers to
2910 memory and only bother with this if more than two. */
2911 if (GET_CODE (operands[2]) != CONST_INT
2912 || INTVAL (operands[2]) < 2
2913 || INTVAL (operands[2]) > 16
2914 || GET_CODE (operands[0]) != MEM
2915 || GET_CODE (operands[1]) != REG
2916 || REGNO (operands[1]) >= 16)
2919 count = INTVAL (operands[2]);
2920 regno = REGNO (operands[1]);
2921 mode = GET_MODE (operands[1]);
2922 if (mode != SImode && (!TARGET_ZARCH || mode != DImode))
2925 operands[3] = gen_rtx_PARALLEL (VOIDmode, rtvec_alloc (count));
2927 if (!can_create_pseudo_p ())
2929 if (GET_CODE (XEXP (operands[0], 0)) == REG)
2931 to = XEXP (operands[0], 0);
2934 else if (GET_CODE (XEXP (operands[0], 0)) == PLUS
2935 && GET_CODE (XEXP (XEXP (operands[0], 0), 0)) == REG
2936 && GET_CODE (XEXP (XEXP (operands[0], 0), 1)) == CONST_INT)
2938 to = XEXP (XEXP (operands[0], 0), 0);
2939 off = INTVAL (XEXP (XEXP (operands[0], 0), 1));
2946 to = force_reg (Pmode, XEXP (operands[0], 0));
2950 for (i = 0; i < count; i++)
2951 XVECEXP (operands[3], 0, i)
2952 = gen_rtx_SET (change_address (operands[0], mode,
2953 plus_constant (Pmode, to,
2954 off + i * GET_MODE_SIZE (mode))),
2955 gen_rtx_REG (mode, regno + i));
2958 (define_insn "*store_multiple_di"
2959 [(match_parallel 0 "store_multiple_operation"
2960 [(set (match_operand:DI 1 "s_operand" "=S")
2961 (match_operand:DI 2 "register_operand" "r"))])]
2962 "reload_completed && TARGET_ZARCH"
2964 int words = XVECLEN (operands[0], 0);
2965 operands[0] = gen_rtx_REG (DImode, REGNO (operands[2]) + words - 1);
2966 return "stmg\t%2,%0,%S1";
2968 [(set_attr "op_type" "RSY")
2969 (set_attr "type" "stm")])
2972 (define_insn "*store_multiple_si"
2973 [(match_parallel 0 "store_multiple_operation"
2974 [(set (match_operand:SI 1 "s_operand" "=Q,S")
2975 (match_operand:SI 2 "register_operand" "r,r"))])]
2978 int words = XVECLEN (operands[0], 0);
2979 operands[0] = gen_rtx_REG (SImode, REGNO (operands[2]) + words - 1);
2980 return which_alternative == 0 ? "stm\t%2,%0,%S1" : "stmy\t%2,%0,%S1";
2982 [(set_attr "op_type" "RS,RSY")
2983 (set_attr "cpu_facility" "*,longdisp")
2984 (set_attr "type" "stm")])
2987 ;; String instructions.
2990 (define_insn "*execute_rl"
2991 [(match_parallel 0 "execute_operation"
2992 [(unspec [(match_operand 1 "register_operand" "a")
2993 (match_operand 2 "" "")
2994 (match_operand:SI 3 "larl_operand" "X")] UNSPEC_EXECUTE)])]
2995 "TARGET_Z10 && GET_MODE_CLASS (GET_MODE (operands[1])) == MODE_INT
2996 && GET_MODE_SIZE (GET_MODE (operands[1])) <= UNITS_PER_WORD"
2998 [(set_attr "op_type" "RIL")
2999 (set_attr "type" "cs")
3000 (set_attr "relative_long" "yes")])
3002 (define_insn "*execute"
3003 [(match_parallel 0 "execute_operation"
3004 [(unspec [(match_operand 1 "register_operand" "a")
3005 (match_operand:BLK 2 "memory_operand" "R")
3006 (match_operand 3 "" "")] UNSPEC_EXECUTE)])]
3007 "GET_MODE_CLASS (GET_MODE (operands[1])) == MODE_INT
3008 && GET_MODE_SIZE (GET_MODE (operands[1])) <= UNITS_PER_WORD"
3010 [(set_attr "op_type" "RX")
3011 (set_attr "type" "cs")])
3015 ; strlenM instruction pattern(s).
3018 (define_expand "strlen<mode>"
3019 [(match_operand:P 0 "register_operand" "") ; result
3020 (match_operand:BLK 1 "memory_operand" "") ; input string
3021 (match_operand:SI 2 "immediate_operand" "") ; search character
3022 (match_operand:SI 3 "immediate_operand" "")] ; known alignment
3025 if (!TARGET_VX || operands[2] != const0_rtx)
3026 emit_insn (gen_strlen_srst<mode> (operands[0], operands[1],
3027 operands[2], operands[3]));
3029 s390_expand_vec_strlen (operands[0], operands[1], operands[3]);
3034 (define_expand "strlen_srst<mode>"
3035 [(set (reg:SI 0) (match_operand:SI 2 "immediate_operand" ""))
3038 (unspec:P [(const_int 0)
3039 (match_operand:BLK 1 "memory_operand" "")
3041 (match_operand 3 "immediate_operand" "")] UNSPEC_SRST))
3042 (clobber (scratch:P))
3043 (clobber (reg:CC CC_REGNUM))])
3045 [(set (match_operand:P 0 "register_operand" "")
3046 (minus:P (match_dup 4) (match_dup 5)))
3047 (clobber (reg:CC CC_REGNUM))])]
3050 operands[4] = gen_reg_rtx (Pmode);
3051 operands[5] = gen_reg_rtx (Pmode);
3052 emit_move_insn (operands[5], force_operand (XEXP (operands[1], 0), NULL_RTX));
3053 operands[1] = replace_equiv_address (operands[1], operands[5]);
3056 (define_insn "*strlen<mode>"
3057 [(set (match_operand:P 0 "register_operand" "=a")
3058 (unspec:P [(match_operand:P 2 "general_operand" "0")
3059 (mem:BLK (match_operand:P 3 "register_operand" "1"))
3061 (match_operand 4 "immediate_operand" "")] UNSPEC_SRST))
3062 (clobber (match_scratch:P 1 "=a"))
3063 (clobber (reg:CC CC_REGNUM))]
3065 "srst\t%0,%1\;jo\t.-4"
3066 [(set_attr "length" "8")
3067 (set_attr "type" "vs")])
3070 ; cmpstrM instruction pattern(s).
3073 (define_expand "cmpstrsi"
3074 [(set (reg:SI 0) (const_int 0))
3076 [(clobber (match_operand 3 "" ""))
3077 (clobber (match_dup 4))
3078 (set (reg:CCU CC_REGNUM)
3079 (compare:CCU (match_operand:BLK 1 "memory_operand" "")
3080 (match_operand:BLK 2 "memory_operand" "")))
3083 [(set (match_operand:SI 0 "register_operand" "=d")
3084 (unspec:SI [(reg:CCU CC_REGNUM)] UNSPEC_STRCMPCC_TO_INT))
3085 (clobber (reg:CC CC_REGNUM))])]
3088 /* As the result of CMPINT is inverted compared to what we need,
3089 we have to swap the operands. */
3090 rtx op1 = operands[2];
3091 rtx op2 = operands[1];
3092 rtx addr1 = gen_reg_rtx (Pmode);
3093 rtx addr2 = gen_reg_rtx (Pmode);
3095 emit_move_insn (addr1, force_operand (XEXP (op1, 0), NULL_RTX));
3096 emit_move_insn (addr2, force_operand (XEXP (op2, 0), NULL_RTX));
3097 operands[1] = replace_equiv_address_nv (op1, addr1);
3098 operands[2] = replace_equiv_address_nv (op2, addr2);
3099 operands[3] = addr1;
3100 operands[4] = addr2;
3103 (define_insn "*cmpstr<mode>"
3104 [(clobber (match_operand:P 0 "register_operand" "=d"))
3105 (clobber (match_operand:P 1 "register_operand" "=d"))
3106 (set (reg:CCU CC_REGNUM)
3107 (compare:CCU (mem:BLK (match_operand:P 2 "register_operand" "0"))
3108 (mem:BLK (match_operand:P 3 "register_operand" "1"))))
3111 "clst\t%0,%1\;jo\t.-4"
3112 [(set_attr "length" "8")
3113 (set_attr "type" "vs")])
3116 ; movstr instruction pattern.
3119 (define_expand "movstr"
3120 [(match_operand 0 "register_operand" "")
3121 (match_operand 1 "memory_operand" "")
3122 (match_operand 2 "memory_operand" "")]
3126 emit_insn (gen_movstrdi (operands[0], operands[1], operands[2]));
3128 emit_insn (gen_movstrsi (operands[0], operands[1], operands[2]));
3132 (define_expand "movstr<P:mode>"
3133 [(set (reg:SI 0) (const_int 0))
3135 [(clobber (match_dup 3))
3136 (set (match_operand:BLK 1 "memory_operand" "")
3137 (match_operand:BLK 2 "memory_operand" ""))
3138 (set (match_operand:P 0 "register_operand" "")
3139 (unspec:P [(match_dup 1)
3141 (reg:SI 0)] UNSPEC_MVST))
3142 (clobber (reg:CC CC_REGNUM))])]
3147 if (TARGET_VX && optimize_function_for_speed_p (cfun))
3149 s390_expand_vec_movstr (operands[0], operands[1], operands[2]);
3153 addr1 = gen_reg_rtx (Pmode);
3154 addr2 = gen_reg_rtx (Pmode);
3156 emit_move_insn (addr1, force_operand (XEXP (operands[1], 0), NULL_RTX));
3157 emit_move_insn (addr2, force_operand (XEXP (operands[2], 0), NULL_RTX));
3158 operands[1] = replace_equiv_address_nv (operands[1], addr1);
3159 operands[2] = replace_equiv_address_nv (operands[2], addr2);
3160 operands[3] = addr2;
3163 (define_insn "*movstr"
3164 [(clobber (match_operand:P 2 "register_operand" "=d"))
3165 (set (mem:BLK (match_operand:P 1 "register_operand" "0"))
3166 (mem:BLK (match_operand:P 3 "register_operand" "2")))
3167 (set (match_operand:P 0 "register_operand" "=d")
3168 (unspec:P [(mem:BLK (match_dup 1))
3169 (mem:BLK (match_dup 3))
3170 (reg:SI 0)] UNSPEC_MVST))
3171 (clobber (reg:CC CC_REGNUM))]
3173 "mvst\t%1,%2\;jo\t.-4"
3174 [(set_attr "length" "8")
3175 (set_attr "type" "vs")])
3179 ; movmemM instruction pattern(s).
3182 (define_expand "movmem<mode>"
3183 [(set (match_operand:BLK 0 "memory_operand" "") ; destination
3184 (match_operand:BLK 1 "memory_operand" "")) ; source
3185 (use (match_operand:GPR 2 "general_operand" "")) ; count
3186 (match_operand 3 "" "")]
3189 if (s390_expand_movmem (operands[0], operands[1], operands[2]))
3195 ; Move a block that is up to 256 bytes in length.
3196 ; The block length is taken as (operands[2] % 256) + 1.
3198 (define_expand "movmem_short"
3200 [(set (match_operand:BLK 0 "memory_operand" "")
3201 (match_operand:BLK 1 "memory_operand" ""))
3202 (use (match_operand 2 "nonmemory_operand" ""))
3203 (use (const:BLK (unspec:BLK [(const_int 0)] UNSPEC_INSN)))
3204 (clobber (match_dup 3))])]
3206 "operands[3] = gen_rtx_SCRATCH (Pmode);")
3208 (define_insn "*movmem_short"
3209 [(set (match_operand:BLK 0 "memory_operand" "=Q,Q,Q,Q")
3210 (match_operand:BLK 1 "memory_operand" "Q,Q,Q,Q"))
3211 (use (match_operand 2 "nonmemory_operand" "n,a,a,a"))
3212 (use (match_operand 3 "immediate_operand" "X,R,X,X"))
3213 (clobber (match_scratch:P 4 "=X,X,X,&a"))]
3214 "(GET_MODE (operands[2]) == Pmode || GET_MODE (operands[2]) == VOIDmode)"
3216 [(set_attr "type" "cs")
3217 (set_attr "cpu_facility" "*,*,z10,cpu_zarch")])
3220 [(set (match_operand:BLK 0 "memory_operand" "")
3221 (match_operand:BLK 1 "memory_operand" ""))
3222 (use (match_operand 2 "const_int_operand" ""))
3223 (use (match_operand 3 "immediate_operand" ""))
3224 (clobber (scratch))]
3227 [(set (match_dup 0) (match_dup 1))
3228 (use (match_dup 2))])]
3229 "operands[2] = GEN_INT ((INTVAL (operands[2]) & 0xff) + 1);")
3232 [(set (match_operand:BLK 0 "memory_operand" "")
3233 (match_operand:BLK 1 "memory_operand" ""))
3234 (use (match_operand 2 "register_operand" ""))
3235 (use (match_operand 3 "memory_operand" ""))
3236 (clobber (scratch))]
3239 [(unspec [(match_dup 2) (match_dup 3)
3240 (const_int 0)] UNSPEC_EXECUTE)
3241 (set (match_dup 0) (match_dup 1))
3242 (use (const_int 1))])]
3246 [(set (match_operand:BLK 0 "memory_operand" "")
3247 (match_operand:BLK 1 "memory_operand" ""))
3248 (use (match_operand 2 "register_operand" ""))
3249 (use (const:BLK (unspec:BLK [(const_int 0)] UNSPEC_INSN)))
3250 (clobber (scratch))]
3251 "TARGET_Z10 && reload_completed"
3253 [(unspec [(match_dup 2) (const_int 0)
3254 (label_ref (match_dup 3))] UNSPEC_EXECUTE)
3255 (set (match_dup 0) (match_dup 1))
3256 (use (const_int 1))])]
3257 "operands[3] = gen_label_rtx ();")
3260 [(set (match_operand:BLK 0 "memory_operand" "")
3261 (match_operand:BLK 1 "memory_operand" ""))
3262 (use (match_operand 2 "register_operand" ""))
3263 (use (const:BLK (unspec:BLK [(const_int 0)] UNSPEC_INSN)))
3264 (clobber (match_operand 3 "register_operand" ""))]
3266 [(set (match_dup 3) (label_ref (match_dup 4)))
3268 [(unspec [(match_dup 2) (mem:BLK (match_dup 3))
3269 (label_ref (match_dup 4))] UNSPEC_EXECUTE)
3270 (set (match_dup 0) (match_dup 1))
3271 (use (const_int 1))])]
3272 "operands[4] = gen_label_rtx ();")
3274 ; Move a block of arbitrary length.
3276 (define_expand "movmem_long"
3278 [(clobber (match_dup 2))
3279 (clobber (match_dup 3))
3280 (set (match_operand:BLK 0 "memory_operand" "")
3281 (match_operand:BLK 1 "memory_operand" ""))
3282 (use (match_operand 2 "general_operand" ""))
3284 (clobber (reg:CC CC_REGNUM))])]
3287 machine_mode sreg_mode = TARGET_ZARCH ? DImode : SImode;
3288 machine_mode dreg_mode = TARGET_ZARCH ? TImode : DImode;
3289 rtx reg0 = gen_reg_rtx (dreg_mode);
3290 rtx reg1 = gen_reg_rtx (dreg_mode);
3291 rtx addr0 = gen_lowpart (Pmode, gen_highpart (sreg_mode, reg0));
3292 rtx addr1 = gen_lowpart (Pmode, gen_highpart (sreg_mode, reg1));
3293 rtx len0 = gen_lowpart (Pmode, reg0);
3294 rtx len1 = gen_lowpart (Pmode, reg1);
3296 emit_clobber (reg0);
3297 emit_move_insn (addr0, force_operand (XEXP (operands[0], 0), NULL_RTX));
3298 emit_move_insn (len0, operands[2]);
3300 emit_clobber (reg1);
3301 emit_move_insn (addr1, force_operand (XEXP (operands[1], 0), NULL_RTX));
3302 emit_move_insn (len1, operands[2]);
3304 operands[0] = replace_equiv_address_nv (operands[0], addr0);
3305 operands[1] = replace_equiv_address_nv (operands[1], addr1);
3310 (define_insn "*movmem_long"
3311 [(clobber (match_operand:<DBL> 0 "register_operand" "=d"))
3312 (clobber (match_operand:<DBL> 1 "register_operand" "=d"))
3313 (set (mem:BLK (subreg:P (match_operand:<DBL> 2 "register_operand" "0") 0))
3314 (mem:BLK (subreg:P (match_operand:<DBL> 3 "register_operand" "1") 0)))
3317 (clobber (reg:CC CC_REGNUM))]
3318 "TARGET_64BIT || !TARGET_ZARCH"
3319 "mvcle\t%0,%1,0\;jo\t.-4"
3320 [(set_attr "length" "8")
3321 (set_attr "type" "vs")])
3323 (define_insn "*movmem_long_31z"
3324 [(clobber (match_operand:TI 0 "register_operand" "=d"))
3325 (clobber (match_operand:TI 1 "register_operand" "=d"))
3326 (set (mem:BLK (subreg:SI (match_operand:TI 2 "register_operand" "0") 4))
3327 (mem:BLK (subreg:SI (match_operand:TI 3 "register_operand" "1") 4)))
3330 (clobber (reg:CC CC_REGNUM))]
3331 "!TARGET_64BIT && TARGET_ZARCH"
3332 "mvcle\t%0,%1,0\;jo\t.-4"
3333 [(set_attr "length" "8")
3334 (set_attr "type" "vs")])
3341 (define_expand "signbit<mode>2"
3342 [(set (reg:CCZ CC_REGNUM)
3343 (unspec:CCZ [(match_operand:FP_ALL 1 "register_operand" "f")
3346 (set (match_operand:SI 0 "register_operand" "=d")
3347 (unspec:SI [(reg:CCZ CC_REGNUM)] UNSPEC_CC_TO_INT))]
3350 operands[2] = GEN_INT (S390_TDC_SIGNBIT_SET);
3353 (define_expand "isinf<mode>2"
3354 [(set (reg:CCZ CC_REGNUM)
3355 (unspec:CCZ [(match_operand:FP_ALL 1 "register_operand" "f")
3358 (set (match_operand:SI 0 "register_operand" "=d")
3359 (unspec:SI [(reg:CCZ CC_REGNUM)] UNSPEC_CC_TO_INT))]
3362 operands[2] = GEN_INT (S390_TDC_INFINITY);
3365 ; This extracts CC into a GPR properly shifted. The actual IPM
3366 ; instruction will be issued by reload. The constraint of operand 1
3367 ; forces reload to use a GPR. So reload will issue a movcc insn for
3368 ; copying CC into a GPR first.
3369 (define_insn_and_split "*cc_to_int"
3370 [(set (match_operand:SI 0 "nonimmediate_operand" "=d")
3371 (unspec:SI [(match_operand 1 "register_operand" "0")]
3376 [(set (match_dup 0) (lshiftrt:SI (match_dup 0) (const_int 28)))])
3378 ; This insn is used to generate all variants of the Test Data Class
3379 ; instruction, namely tcxb, tcdb, and tceb. The insn's first operand
3380 ; is the register to be tested and the second one is the bit mask
3381 ; specifying the required test(s).
3383 ; tcxb, tcdb, tceb, tdcxt, tdcdt, tdcet
3384 (define_insn "*TDC_insn_<mode>"
3385 [(set (reg:CCZ CC_REGNUM)
3386 (unspec:CCZ [(match_operand:FP_ALL 0 "register_operand" "f")
3387 (match_operand:SI 1 "const_int_operand")] UNSPEC_TDC_INSN))]
3389 "t<_d>c<xde><bt>\t%0,%1"
3390 [(set_attr "op_type" "RXE")
3391 (set_attr "type" "fsimp<mode>")])
3396 ; setmemM instruction pattern(s).
3399 (define_expand "setmem<mode>"
3400 [(set (match_operand:BLK 0 "memory_operand" "")
3401 (match_operand:QI 2 "general_operand" ""))
3402 (use (match_operand:GPR 1 "general_operand" ""))
3403 (match_operand 3 "" "")]
3405 "s390_expand_setmem (operands[0], operands[1], operands[2]); DONE;")
3407 ; Clear a block that is up to 256 bytes in length.
3408 ; The block length is taken as (operands[1] % 256) + 1.
3410 (define_expand "clrmem_short"
3412 [(set (match_operand:BLK 0 "memory_operand" "")
3414 (use (match_operand 1 "nonmemory_operand" ""))
3415 (use (const:BLK (unspec:BLK [(const_int 0)] UNSPEC_INSN)))
3416 (clobber (match_dup 2))
3417 (clobber (reg:CC CC_REGNUM))])]
3419 "operands[2] = gen_rtx_SCRATCH (Pmode);")
3421 (define_insn "*clrmem_short"
3422 [(set (match_operand:BLK 0 "memory_operand" "=Q,Q,Q,Q")
3424 (use (match_operand 1 "nonmemory_operand" "n,a,a,a"))
3425 (use (match_operand 2 "immediate_operand" "X,R,X,X"))
3426 (clobber (match_scratch:P 3 "=X,X,X,&a"))
3427 (clobber (reg:CC CC_REGNUM))]
3428 "(GET_MODE (operands[1]) == Pmode || GET_MODE (operands[1]) == VOIDmode)"
3430 [(set_attr "type" "cs")
3431 (set_attr "cpu_facility" "*,*,z10,cpu_zarch")])
3434 [(set (match_operand:BLK 0 "memory_operand" "")
3436 (use (match_operand 1 "const_int_operand" ""))
3437 (use (match_operand 2 "immediate_operand" ""))
3439 (clobber (reg:CC CC_REGNUM))]
3442 [(set (match_dup 0) (const_int 0))
3444 (clobber (reg:CC CC_REGNUM))])]
3445 "operands[1] = GEN_INT ((INTVAL (operands[1]) & 0xff) + 1);")
3448 [(set (match_operand:BLK 0 "memory_operand" "")
3450 (use (match_operand 1 "register_operand" ""))
3451 (use (match_operand 2 "memory_operand" ""))
3453 (clobber (reg:CC CC_REGNUM))]
3456 [(unspec [(match_dup 1) (match_dup 2)
3457 (const_int 0)] UNSPEC_EXECUTE)
3458 (set (match_dup 0) (const_int 0))
3460 (clobber (reg:CC CC_REGNUM))])]
3464 [(set (match_operand:BLK 0 "memory_operand" "")
3466 (use (match_operand 1 "register_operand" ""))
3467 (use (const:BLK (unspec:BLK [(const_int 0)] UNSPEC_INSN)))
3469 (clobber (reg:CC CC_REGNUM))]
3470 "TARGET_Z10 && reload_completed"
3472 [(unspec [(match_dup 1) (const_int 0)
3473 (label_ref (match_dup 3))] UNSPEC_EXECUTE)
3474 (set (match_dup 0) (const_int 0))
3476 (clobber (reg:CC CC_REGNUM))])]
3477 "operands[3] = gen_label_rtx ();")
3480 [(set (match_operand:BLK 0 "memory_operand" "")
3482 (use (match_operand 1 "register_operand" ""))
3483 (use (const:BLK (unspec:BLK [(const_int 0)] UNSPEC_INSN)))
3484 (clobber (match_operand 2 "register_operand" ""))
3485 (clobber (reg:CC CC_REGNUM))]
3487 [(set (match_dup 2) (label_ref (match_dup 3)))
3489 [(unspec [(match_dup 1) (mem:BLK (match_dup 2))
3490 (label_ref (match_dup 3))] UNSPEC_EXECUTE)
3491 (set (match_dup 0) (const_int 0))
3493 (clobber (reg:CC CC_REGNUM))])]
3494 "operands[3] = gen_label_rtx ();")
3496 ; Initialize a block of arbitrary length with (operands[2] % 256).
3498 (define_expand "setmem_long_<P:mode>"
3500 [(clobber (match_dup 1))
3501 (set (match_operand:BLK 0 "memory_operand" "")
3502 (unspec:BLK [(match_operand:P 2 "setmem_operand" "")
3503 (match_dup 4)] UNSPEC_REPLICATE_BYTE))
3505 (clobber (reg:CC CC_REGNUM))])]
3508 machine_mode sreg_mode = TARGET_ZARCH ? DImode : SImode;
3509 machine_mode dreg_mode = TARGET_ZARCH ? TImode : DImode;
3510 rtx reg0 = gen_reg_rtx (dreg_mode);
3511 rtx reg1 = gen_reg_rtx (dreg_mode);
3512 rtx addr0 = gen_lowpart (Pmode, gen_highpart (sreg_mode, reg0));
3513 rtx len0 = gen_lowpart (Pmode, reg0);
3515 emit_clobber (reg0);
3516 emit_move_insn (addr0, force_operand (XEXP (operands[0], 0), NULL_RTX));
3517 emit_move_insn (len0, operands[1]);
3519 emit_move_insn (reg1, const0_rtx);
3521 operands[0] = replace_equiv_address_nv (operands[0], addr0);
3524 operands[4] = gen_lowpart (Pmode, operands[1]);
3527 ; Patterns for 31 bit + Esa and 64 bit + Zarch.
3529 (define_insn "*setmem_long"
3530 [(clobber (match_operand:<DBL> 0 "register_operand" "=d"))
3531 (set (mem:BLK (subreg:P (match_operand:<DBL> 3 "register_operand" "0") 0))
3532 (unspec:BLK [(match_operand:P 2 "setmem_operand" "Y")
3533 (subreg:P (match_dup 3) <modesize>)]
3534 UNSPEC_REPLICATE_BYTE))
3535 (use (match_operand:<DBL> 1 "register_operand" "d"))
3536 (clobber (reg:CC CC_REGNUM))]
3537 "TARGET_64BIT || !TARGET_ZARCH"
3538 "mvcle\t%0,%1,%Y2\;jo\t.-4"
3539 [(set_attr "length" "8")
3540 (set_attr "type" "vs")])
3542 (define_insn "*setmem_long_and"
3543 [(clobber (match_operand:<DBL> 0 "register_operand" "=d"))
3544 (set (mem:BLK (subreg:P (match_operand:<DBL> 3 "register_operand" "0") 0))
3545 (unspec:BLK [(zero_extend:P (match_operand:QI 2 "setmem_operand" "Y"))
3546 (subreg:P (match_dup 3) <modesize>)]
3547 UNSPEC_REPLICATE_BYTE))
3548 (use (match_operand:<DBL> 1 "register_operand" "d"))
3549 (clobber (reg:CC CC_REGNUM))]
3550 "(TARGET_64BIT || !TARGET_ZARCH)"
3551 "mvcle\t%0,%1,%Y2\;jo\t.-4"
3552 [(set_attr "length" "8")
3553 (set_attr "type" "vs")])
3555 ; Variants for 31 bit + Zarch, necessary because of the odd in-register offsets
3556 ; of the SImode subregs.
3558 (define_insn "*setmem_long_31z"
3559 [(clobber (match_operand:TI 0 "register_operand" "=d"))
3560 (set (mem:BLK (subreg:SI (match_operand:TI 3 "register_operand" "0") 4))
3561 (unspec:BLK [(match_operand:SI 2 "setmem_operand" "Y")
3562 (subreg:SI (match_dup 3) 12)] UNSPEC_REPLICATE_BYTE))
3563 (use (match_operand:TI 1 "register_operand" "d"))
3564 (clobber (reg:CC CC_REGNUM))]
3565 "!TARGET_64BIT && TARGET_ZARCH"
3566 "mvcle\t%0,%1,%Y2\;jo\t.-4"
3567 [(set_attr "length" "8")
3568 (set_attr "type" "vs")])
3570 (define_insn "*setmem_long_and_31z"
3571 [(clobber (match_operand:TI 0 "register_operand" "=d"))
3572 (set (mem:BLK (subreg:SI (match_operand:TI 3 "register_operand" "0") 4))
3573 (unspec:BLK [(zero_extend:SI (match_operand:QI 2 "setmem_operand" "Y"))
3574 (subreg:SI (match_dup 3) 12)] UNSPEC_REPLICATE_BYTE))
3575 (use (match_operand:TI 1 "register_operand" "d"))
3576 (clobber (reg:CC CC_REGNUM))]
3577 "(!TARGET_64BIT && TARGET_ZARCH)"
3578 "mvcle\t%0,%1,%Y2\;jo\t.-4"
3579 [(set_attr "length" "8")
3580 (set_attr "type" "vs")])
3583 ; cmpmemM instruction pattern(s).
3586 (define_expand "cmpmemsi"
3587 [(set (match_operand:SI 0 "register_operand" "")
3588 (compare:SI (match_operand:BLK 1 "memory_operand" "")
3589 (match_operand:BLK 2 "memory_operand" "") ) )
3590 (use (match_operand:SI 3 "general_operand" ""))
3591 (use (match_operand:SI 4 "" ""))]
3594 if (s390_expand_cmpmem (operands[0], operands[1],
3595 operands[2], operands[3]))
3601 ; Compare a block that is up to 256 bytes in length.
3602 ; The block length is taken as (operands[2] % 256) + 1.
3604 (define_expand "cmpmem_short"
3606 [(set (reg:CCU CC_REGNUM)
3607 (compare:CCU (match_operand:BLK 0 "memory_operand" "")
3608 (match_operand:BLK 1 "memory_operand" "")))
3609 (use (match_operand 2 "nonmemory_operand" ""))
3610 (use (const:BLK (unspec:BLK [(const_int 0)] UNSPEC_INSN)))
3611 (clobber (match_dup 3))])]
3613 "operands[3] = gen_rtx_SCRATCH (Pmode);")
3615 (define_insn "*cmpmem_short"
3616 [(set (reg:CCU CC_REGNUM)
3617 (compare:CCU (match_operand:BLK 0 "memory_operand" "Q,Q,Q,Q")
3618 (match_operand:BLK 1 "memory_operand" "Q,Q,Q,Q")))
3619 (use (match_operand 2 "nonmemory_operand" "n,a,a,a"))
3620 (use (match_operand 3 "immediate_operand" "X,R,X,X"))
3621 (clobber (match_scratch:P 4 "=X,X,X,&a"))]
3622 "(GET_MODE (operands[2]) == Pmode || GET_MODE (operands[2]) == VOIDmode)"
3624 [(set_attr "type" "cs")
3625 (set_attr "cpu_facility" "*,*,z10,cpu_zarch")])
3628 [(set (reg:CCU CC_REGNUM)
3629 (compare:CCU (match_operand:BLK 0 "memory_operand" "")
3630 (match_operand:BLK 1 "memory_operand" "")))
3631 (use (match_operand 2 "const_int_operand" ""))
3632 (use (match_operand 3 "immediate_operand" ""))
3633 (clobber (scratch))]
3636 [(set (reg:CCU CC_REGNUM) (compare:CCU (match_dup 0) (match_dup 1)))
3637 (use (match_dup 2))])]
3638 "operands[2] = GEN_INT ((INTVAL (operands[2]) & 0xff) + 1);")
3641 [(set (reg:CCU CC_REGNUM)
3642 (compare:CCU (match_operand:BLK 0 "memory_operand" "")
3643 (match_operand:BLK 1 "memory_operand" "")))
3644 (use (match_operand 2 "register_operand" ""))
3645 (use (match_operand 3 "memory_operand" ""))
3646 (clobber (scratch))]
3649 [(unspec [(match_dup 2) (match_dup 3)
3650 (const_int 0)] UNSPEC_EXECUTE)
3651 (set (reg:CCU CC_REGNUM) (compare:CCU (match_dup 0) (match_dup 1)))
3652 (use (const_int 1))])]
3656 [(set (reg:CCU CC_REGNUM)
3657 (compare:CCU (match_operand:BLK 0 "memory_operand" "")
3658 (match_operand:BLK 1 "memory_operand" "")))
3659 (use (match_operand 2 "register_operand" ""))
3660 (use (const:BLK (unspec:BLK [(const_int 0)] UNSPEC_INSN)))
3661 (clobber (scratch))]
3662 "TARGET_Z10 && reload_completed"
3664 [(unspec [(match_dup 2) (const_int 0)
3665 (label_ref (match_dup 4))] UNSPEC_EXECUTE)
3666 (set (reg:CCU CC_REGNUM) (compare:CCU (match_dup 0) (match_dup 1)))
3667 (use (const_int 1))])]
3668 "operands[4] = gen_label_rtx ();")
3671 [(set (reg:CCU CC_REGNUM)
3672 (compare:CCU (match_operand:BLK 0 "memory_operand" "")
3673 (match_operand:BLK 1 "memory_operand" "")))
3674 (use (match_operand 2 "register_operand" ""))
3675 (use (const:BLK (unspec:BLK [(const_int 0)] UNSPEC_INSN)))
3676 (clobber (match_operand 3 "register_operand" ""))]
3678 [(set (match_dup 3) (label_ref (match_dup 4)))
3680 [(unspec [(match_dup 2) (mem:BLK (match_dup 3))
3681 (label_ref (match_dup 4))] UNSPEC_EXECUTE)
3682 (set (reg:CCU CC_REGNUM) (compare:CCU (match_dup 0) (match_dup 1)))
3683 (use (const_int 1))])]
3684 "operands[4] = gen_label_rtx ();")
3686 ; Compare a block of arbitrary length.
3688 (define_expand "cmpmem_long"
3690 [(clobber (match_dup 2))
3691 (clobber (match_dup 3))
3692 (set (reg:CCU CC_REGNUM)
3693 (compare:CCU (match_operand:BLK 0 "memory_operand" "")
3694 (match_operand:BLK 1 "memory_operand" "")))
3695 (use (match_operand 2 "general_operand" ""))
3696 (use (match_dup 3))])]
3699 machine_mode sreg_mode = TARGET_ZARCH ? DImode : SImode;
3700 machine_mode dreg_mode = TARGET_ZARCH ? TImode : DImode;
3701 rtx reg0 = gen_reg_rtx (dreg_mode);
3702 rtx reg1 = gen_reg_rtx (dreg_mode);
3703 rtx addr0 = gen_lowpart (Pmode, gen_highpart (sreg_mode, reg0));
3704 rtx addr1 = gen_lowpart (Pmode, gen_highpart (sreg_mode, reg1));
3705 rtx len0 = gen_lowpart (Pmode, reg0);
3706 rtx len1 = gen_lowpart (Pmode, reg1);
3708 emit_clobber (reg0);
3709 emit_move_insn (addr0, force_operand (XEXP (operands[0], 0), NULL_RTX));
3710 emit_move_insn (len0, operands[2]);
3712 emit_clobber (reg1);
3713 emit_move_insn (addr1, force_operand (XEXP (operands[1], 0), NULL_RTX));
3714 emit_move_insn (len1, operands[2]);
3716 operands[0] = replace_equiv_address_nv (operands[0], addr0);
3717 operands[1] = replace_equiv_address_nv (operands[1], addr1);
3722 (define_insn "*cmpmem_long"
3723 [(clobber (match_operand:<DBL> 0 "register_operand" "=d"))
3724 (clobber (match_operand:<DBL> 1 "register_operand" "=d"))
3725 (set (reg:CCU CC_REGNUM)
3726 (compare:CCU (mem:BLK (subreg:P (match_operand:<DBL> 2 "register_operand" "0") 0))
3727 (mem:BLK (subreg:P (match_operand:<DBL> 3 "register_operand" "1") 0))))
3729 (use (match_dup 3))]
3730 "TARGET_64BIT || !TARGET_ZARCH"
3731 "clcle\t%0,%1,0\;jo\t.-4"
3732 [(set_attr "length" "8")
3733 (set_attr "type" "vs")])
3735 (define_insn "*cmpmem_long_31z"
3736 [(clobber (match_operand:TI 0 "register_operand" "=d"))
3737 (clobber (match_operand:TI 1 "register_operand" "=d"))
3738 (set (reg:CCU CC_REGNUM)
3739 (compare:CCU (mem:BLK (subreg:SI (match_operand:TI 2 "register_operand" "0") 4))
3740 (mem:BLK (subreg:SI (match_operand:TI 3 "register_operand" "1") 4))))
3742 (use (match_dup 3))]
3743 "!TARGET_64BIT && TARGET_ZARCH"
3744 "clcle\t%0,%1,0\;jo\t.-4"
3745 [(set_attr "op_type" "NN")
3746 (set_attr "type" "vs")
3747 (set_attr "length" "8")])
3749 ; Convert CCUmode condition code to integer.
3750 ; Result is zero if EQ, positive if LTU, negative if GTU.
3752 (define_insn_and_split "cmpint"
3753 [(set (match_operand:SI 0 "register_operand" "=d")
3754 (unspec:SI [(match_operand:CCU 1 "register_operand" "0")]
3755 UNSPEC_STRCMPCC_TO_INT))
3756 (clobber (reg:CC CC_REGNUM))]
3760 [(set (match_dup 0) (ashift:SI (match_dup 0) (const_int 2)))
3762 [(set (match_dup 0) (ashiftrt:SI (match_dup 0) (const_int 30)))
3763 (clobber (reg:CC CC_REGNUM))])])
3765 (define_insn_and_split "*cmpint_cc"
3766 [(set (reg CC_REGNUM)
3767 (compare (unspec:SI [(match_operand:CCU 1 "register_operand" "0")]
3768 UNSPEC_STRCMPCC_TO_INT)
3770 (set (match_operand:SI 0 "register_operand" "=d")
3771 (unspec:SI [(match_dup 1)] UNSPEC_STRCMPCC_TO_INT))]
3772 "s390_match_ccmode (insn, CCSmode)"
3774 "&& reload_completed"
3775 [(set (match_dup 0) (ashift:SI (match_dup 0) (const_int 2)))
3777 [(set (match_dup 2) (match_dup 3))
3778 (set (match_dup 0) (ashiftrt:SI (match_dup 0) (const_int 30)))])]
3780 rtx result = gen_rtx_ASHIFTRT (SImode, operands[0], GEN_INT (30));
3781 operands[2] = SET_DEST (XVECEXP (PATTERN (curr_insn), 0, 0));
3782 operands[3] = gen_rtx_COMPARE (GET_MODE (operands[2]), result, const0_rtx);
3785 (define_insn_and_split "*cmpint_sign"
3786 [(set (match_operand:DI 0 "register_operand" "=d")
3787 (sign_extend:DI (unspec:SI [(match_operand:CCU 1 "register_operand" "0")]
3788 UNSPEC_STRCMPCC_TO_INT)))
3789 (clobber (reg:CC CC_REGNUM))]
3792 "&& reload_completed"
3793 [(set (match_dup 0) (ashift:DI (match_dup 0) (const_int 34)))
3795 [(set (match_dup 0) (ashiftrt:DI (match_dup 0) (const_int 62)))
3796 (clobber (reg:CC CC_REGNUM))])])
3798 (define_insn_and_split "*cmpint_sign_cc"
3799 [(set (reg CC_REGNUM)
3800 (compare (ashiftrt:DI (ashift:DI (subreg:DI
3801 (unspec:SI [(match_operand:CCU 1 "register_operand" "0")]
3802 UNSPEC_STRCMPCC_TO_INT) 0)
3803 (const_int 32)) (const_int 32))
3805 (set (match_operand:DI 0 "register_operand" "=d")
3806 (sign_extend:DI (unspec:SI [(match_dup 1)] UNSPEC_STRCMPCC_TO_INT)))]
3807 "s390_match_ccmode (insn, CCSmode) && TARGET_ZARCH"
3809 "&& reload_completed"
3810 [(set (match_dup 0) (ashift:DI (match_dup 0) (const_int 34)))
3812 [(set (match_dup 2) (match_dup 3))
3813 (set (match_dup 0) (ashiftrt:DI (match_dup 0) (const_int 62)))])]
3815 rtx result = gen_rtx_ASHIFTRT (DImode, operands[0], GEN_INT (62));
3816 operands[2] = SET_DEST (XVECEXP (PATTERN (curr_insn), 0, 0));
3817 operands[3] = gen_rtx_COMPARE (GET_MODE (operands[2]), result, const0_rtx);
3822 ;;- Conversion instructions.
3825 (define_insn "*sethighpartsi"
3826 [(set (match_operand:SI 0 "register_operand" "=d,d")
3827 (unspec:SI [(match_operand:BLK 1 "s_operand" "Q,S")
3828 (match_operand 2 "const_int_operand" "n,n")] UNSPEC_ICM))
3829 (clobber (reg:CC CC_REGNUM))]
3834 [(set_attr "op_type" "RS,RSY")
3835 (set_attr "cpu_facility" "*,longdisp")
3836 (set_attr "z10prop" "z10_super_E1,z10_super_E1")])
3838 (define_insn "*sethighpartdi_64"
3839 [(set (match_operand:DI 0 "register_operand" "=d")
3840 (unspec:DI [(match_operand:BLK 1 "s_operand" "S")
3841 (match_operand 2 "const_int_operand" "n")] UNSPEC_ICM))
3842 (clobber (reg:CC CC_REGNUM))]
3845 [(set_attr "op_type" "RSY")
3846 (set_attr "z10prop" "z10_super")])
3848 (define_insn "*sethighpartdi_31"
3849 [(set (match_operand:DI 0 "register_operand" "=d,d")
3850 (unspec:DI [(match_operand:BLK 1 "s_operand" "Q,S")
3851 (match_operand 2 "const_int_operand" "n,n")] UNSPEC_ICM))
3852 (clobber (reg:CC CC_REGNUM))]
3857 [(set_attr "op_type" "RS,RSY")
3858 (set_attr "cpu_facility" "*,longdisp")
3859 (set_attr "z10prop" "z10_super_E1,z10_super_E1")])
3862 ; extv instruction patterns
3865 ; FIXME: This expander needs to be converted from DI to GPR as well
3866 ; after resolving some issues with it.
3868 (define_expand "extzv"
3870 [(set (match_operand:DI 0 "register_operand" "=d")
3872 (match_operand:DI 1 "register_operand" "d")
3873 (match_operand 2 "const_int_operand" "") ; size
3874 (match_operand 3 "const_int_operand" ""))) ; start
3875 (clobber (reg:CC CC_REGNUM))])]
3878 if (! EXTRACT_ARGS_IN_RANGE (INTVAL (operands[2]), INTVAL (operands[3]), 64))
3880 /* Starting with zEC12 there is risbgn not clobbering CC. */
3883 emit_move_insn (operands[0],
3884 gen_rtx_ZERO_EXTRACT (DImode,
3892 (define_insn "*extzv<mode><clobbercc_or_nocc>"
3893 [(set (match_operand:GPR 0 "register_operand" "=d")
3895 (match_operand:GPR 1 "register_operand" "d")
3896 (match_operand 2 "const_int_operand" "") ; size
3897 (match_operand 3 "const_int_operand" ""))) ; start
3899 "<z10_or_zEC12_cond>
3900 && EXTRACT_ARGS_IN_RANGE (INTVAL (operands[2]), INTVAL (operands[3]),
3901 GET_MODE_BITSIZE (<MODE>mode))"
3902 "<risbg_n>\t%0,%1,64-%2,128+63,<bitoff_plus>%3+%2" ; dst, src, start, end, shift
3903 [(set_attr "op_type" "RIE")
3904 (set_attr "z10prop" "z10_super_E1")])
3906 ; 64 bit: (a & -16) | ((b >> 8) & 15)
3907 (define_insn "*extzvdi<clobbercc_or_nocc>_lshiftrt"
3908 [(set (zero_extract:DI (match_operand:DI 0 "register_operand" "+d")
3909 (match_operand 1 "const_int_operand" "") ; size
3910 (match_operand 2 "const_int_operand" "")) ; start
3911 (lshiftrt:DI (match_operand:DI 3 "register_operand" "d")
3912 (match_operand:DI 4 "nonzero_shift_count_operand" "")))]
3913 "<z10_or_zEC12_cond>
3914 && EXTRACT_ARGS_IN_RANGE (INTVAL (operands[1]), INTVAL (operands[2]), 64)
3915 && 64 - UINTVAL (operands[4]) >= UINTVAL (operands[1])"
3916 "<risbg_n>\t%0,%3,%2,%2+%1-1,128-%2-%1-%4"
3917 [(set_attr "op_type" "RIE")
3918 (set_attr "z10prop" "z10_super_E1")])
3920 ; 32 bit: (a & -16) | ((b >> 8) & 15)
3921 (define_insn "*<risbg_n>_ior_and_sr_ze"
3922 [(set (match_operand:SI 0 "register_operand" "=d")
3924 (match_operand:SI 1 "register_operand" "0")
3925 (match_operand:SI 2 "const_int_operand" ""))
3928 (match_operand:DI 3 "register_operand" "d")
3929 (match_operand 4 "const_int_operand" "") ; size
3930 (match_operand 5 "const_int_operand" "")) ; start
3932 "<z10_or_zEC12_cond>
3933 && EXTRACT_ARGS_IN_RANGE (INTVAL (operands[4]), INTVAL (operands[5]), 64)
3934 && UINTVAL (operands[2]) == (~(0ULL) << UINTVAL (operands[4]))"
3935 "<risbg_n>\t%0,%3,64-%4,63,%4+%5"
3936 [(set_attr "op_type" "RIE")
3937 (set_attr "z10prop" "z10_super_E1")])
3939 ; ((int)foo >> 10) & 1;
3940 (define_insn "*extract1bitdi<clobbercc_or_nocc>"
3941 [(set (match_operand:DI 0 "register_operand" "=d")
3942 (ne:DI (zero_extract:DI
3943 (match_operand:DI 1 "register_operand" "d")
3944 (const_int 1) ; size
3945 (match_operand 2 "const_int_operand" "")) ; start
3947 "<z10_or_zEC12_cond>
3948 && EXTRACT_ARGS_IN_RANGE (1, INTVAL (operands[2]), 64)"
3949 "<risbg_n>\t%0,%1,64-1,128+63,%2+1" ; dst, src, start, end, shift
3950 [(set_attr "op_type" "RIE")
3951 (set_attr "z10prop" "z10_super_E1")])
3953 (define_insn "*<risbg_n>_and_subregdi_rotr"
3954 [(set (match_operand:DI 0 "register_operand" "=d")
3956 (rotate:SINT (match_operand:SINT 1 "register_operand" "d")
3957 (match_operand:SINT 2 "const_int_operand" "")) 0)
3958 (match_operand:DI 3 "contiguous_bitmask_operand" "")))]
3959 "<z10_or_zEC12_cond>
3960 && UINTVAL (operands[3]) < (1ULL << (UINTVAL (operands[2]) & 0x3f))"
3961 "<risbg_n>\t%0,%1,%s3,128+%e3,<bitoff_plus>%2" ; dst, src, start, end, shift
3962 [(set_attr "op_type" "RIE")
3963 (set_attr "z10prop" "z10_super_E1")])
3965 (define_insn "*<risbg_n>_and_subregdi_rotl"
3966 [(set (match_operand:DI 0 "register_operand" "=d")
3968 (rotate:SINT (match_operand:SINT 1 "register_operand" "d")
3969 (match_operand:SINT 2 "const_int_operand" "")) 0)
3970 (match_operand:DI 3 "contiguous_bitmask_operand" "")))]
3971 "<z10_or_zEC12_cond>
3972 && !(UINTVAL (operands[3]) & ((1ULL << (UINTVAL (operands[2]) & 0x3f)) - 1))"
3973 "<risbg_n>\t%0,%1,%s3,128+%e3,%2" ; dst, src, start, end, shift
3974 [(set_attr "op_type" "RIE")
3975 (set_attr "z10prop" "z10_super_E1")])
3977 (define_insn "*<risbg_n>_di_and_rot"
3978 [(set (match_operand:DI 0 "register_operand" "=d")
3979 (and:DI (rotate:DI (match_operand:DI 1 "register_operand" "d")
3980 (match_operand:DI 2 "const_int_operand" ""))
3981 (match_operand:DI 3 "contiguous_bitmask_operand" "")))]
3982 "<z10_or_zEC12_cond>"
3983 "<risbg_n>\t%0,%1,%s3,128+%e3,%2" ; dst, src, start, end, shift
3984 [(set_attr "op_type" "RIE")
3985 (set_attr "z10prop" "z10_super_E1")])
3987 (define_insn_and_split "*pre_z10_extzv<mode>"
3988 [(set (match_operand:GPR 0 "register_operand" "=d")
3989 (zero_extract:GPR (match_operand:QI 1 "s_operand" "S")
3990 (match_operand 2 "nonzero_shift_count_operand" "")
3992 (clobber (reg:CC CC_REGNUM))]
3995 "&& reload_completed"
3997 [(set (match_dup 0) (unspec:GPR [(match_dup 1) (match_dup 3)] UNSPEC_ICM))
3998 (clobber (reg:CC CC_REGNUM))])
3999 (set (match_dup 0) (lshiftrt:GPR (match_dup 0) (match_dup 2)))]
4001 int bitsize = INTVAL (operands[2]);
4002 int size = (bitsize - 1) / BITS_PER_UNIT + 1; /* round up */
4003 int mask = ((1ul << size) - 1) << (GET_MODE_SIZE (SImode) - size);
4005 operands[1] = adjust_address (operands[1], BLKmode, 0);
4006 set_mem_size (operands[1], size);
4007 operands[2] = GEN_INT (<GPR:bitsize> - bitsize);
4008 operands[3] = GEN_INT (mask);
4011 (define_insn_and_split "*pre_z10_extv<mode>"
4012 [(set (match_operand:GPR 0 "register_operand" "=d")
4013 (sign_extract:GPR (match_operand:QI 1 "s_operand" "S")
4014 (match_operand 2 "nonzero_shift_count_operand" "")
4016 (clobber (reg:CC CC_REGNUM))]
4019 "&& reload_completed"
4021 [(set (match_dup 0) (unspec:GPR [(match_dup 1) (match_dup 3)] UNSPEC_ICM))
4022 (clobber (reg:CC CC_REGNUM))])
4024 [(set (match_dup 0) (ashiftrt:GPR (match_dup 0) (match_dup 2)))
4025 (clobber (reg:CC CC_REGNUM))])]
4027 int bitsize = INTVAL (operands[2]);
4028 int size = (bitsize - 1) / BITS_PER_UNIT + 1; /* round up */
4029 int mask = ((1ul << size) - 1) << (GET_MODE_SIZE (SImode) - size);
4031 operands[1] = adjust_address (operands[1], BLKmode, 0);
4032 set_mem_size (operands[1], size);
4033 operands[2] = GEN_INT (<GPR:bitsize> - bitsize);
4034 operands[3] = GEN_INT (mask);
4038 ; insv instruction patterns
4041 (define_expand "insv"
4042 [(set (zero_extract (match_operand 0 "nonimmediate_operand" "")
4043 (match_operand 1 "const_int_operand" "")
4044 (match_operand 2 "const_int_operand" ""))
4045 (match_operand 3 "general_operand" ""))]
4048 if (s390_expand_insv (operands[0], operands[1], operands[2], operands[3]))
4054 ; The normal RTL expansion will never generate a zero_extract where
4055 ; the location operand isn't word mode. However, we do this in the
4056 ; back-end when generating atomic operations. See s390_two_part_insv.
4057 (define_insn "*insv<mode><clobbercc_or_nocc>"
4058 [(set (zero_extract:GPR (match_operand:GPR 0 "nonimmediate_operand" "+d")
4059 (match_operand 1 "const_int_operand" "I") ; size
4060 (match_operand 2 "const_int_operand" "I")) ; pos
4061 (match_operand:GPR 3 "nonimmediate_operand" "d"))]
4062 "<z10_or_zEC12_cond>
4063 && EXTRACT_ARGS_IN_RANGE (INTVAL (operands[1]), INTVAL (operands[2]),
4064 GET_MODE_BITSIZE (<MODE>mode))
4065 && (INTVAL (operands[1]) + INTVAL (operands[2])) <= <bitsize>"
4066 "<risbg_n>\t%0,%3,<bitoff_plus>%2,<bitoff_plus>%2+%1-1,<bitsize>-%2-%1"
4067 [(set_attr "op_type" "RIE")
4068 (set_attr "z10prop" "z10_super_E1")])
4070 ; and op1 with a mask being 1 for the selected bits and 0 for the rest
4071 ; and op3=op0 with a mask being 0 for the selected bits and 1 for the rest
4072 (define_insn "*insv<mode><clobbercc_or_nocc>_noshift"
4073 [(set (match_operand:GPR 0 "nonimmediate_operand" "=d,d")
4074 (ior:GPR (and:GPR (match_operand:GPR 1 "nonimmediate_operand" "d,0")
4075 (match_operand:GPR 2 "contiguous_bitmask_operand" ""))
4076 (and:GPR (match_operand:GPR 3 "nonimmediate_operand" "0,d")
4077 (match_operand:GPR 4 "const_int_operand" ""))))]
4078 "<z10_or_zEC12_cond> && INTVAL (operands[2]) == ~INTVAL (operands[4])"
4080 <risbg_n>\t%0,%1,%<bfstart>2,%<bfend>2,0
4081 <risbg_n>\t%0,%3,%<bfstart>4,%<bfend>4,0"
4082 [(set_attr "op_type" "RIE")
4083 (set_attr "z10prop" "z10_super_E1")])
4085 (define_insn "*insv_z10_noshift_cc"
4086 [(set (reg CC_REGNUM)
4089 (and:DI (match_operand:DI 1 "nonimmediate_operand" "d,0")
4090 (match_operand:DI 2 "contiguous_bitmask_operand" ""))
4091 (and:DI (match_operand:DI 3 "nonimmediate_operand" "0,d")
4092 (match_operand:DI 4 "const_int_operand" "")))
4094 (set (match_operand:DI 0 "nonimmediate_operand" "=d,d")
4095 (ior:DI (and:DI (match_dup 1) (match_dup 2))
4096 (and:DI (match_dup 3) (match_dup 4))))]
4097 "TARGET_Z10 && s390_match_ccmode (insn, CCSmode)
4098 && INTVAL (operands[2]) == ~INTVAL (operands[4])"
4100 risbg\t%0,%1,%s2,%e2,0
4101 risbg\t%0,%3,%s4,%e4,0"
4102 [(set_attr "op_type" "RIE")
4103 (set_attr "z10prop" "z10_super_E1")])
4105 (define_insn "*insv_z10_noshift_cconly"
4110 (and:DI (match_operand:DI 1 "nonimmediate_operand" "d,0")
4111 (match_operand:DI 2 "contiguous_bitmask_operand" ""))
4112 (and:DI (match_operand:DI 3 "nonimmediate_operand" "0,d")
4113 (match_operand:DI 4 "const_int_operand" "")))
4115 (clobber (match_scratch:DI 0 "=d,d"))]
4116 "TARGET_Z10 && s390_match_ccmode (insn, CCSmode)
4117 && INTVAL (operands[2]) == ~INTVAL (operands[4])"
4119 risbg\t%0,%1,%s2,%e2,0
4120 risbg\t%0,%3,%s4,%e4,0"
4121 [(set_attr "op_type" "RIE")
4122 (set_attr "z10prop" "z10_super_E1")])
4124 ; Implement appending Y on the left of S bits of X
4125 ; x = (y << s) | (x & ((1 << s) - 1))
4126 (define_insn "*insv<mode><clobbercc_or_nocc>_appendbitsleft"
4127 [(set (match_operand:GPR 0 "nonimmediate_operand" "=d")
4128 (ior:GPR (and:GPR (match_operand:GPR 1 "nonimmediate_operand" "0")
4129 (match_operand:GPR 2 "immediate_operand" ""))
4130 (ashift:GPR (match_operand:GPR 3 "nonimmediate_operand" "d")
4131 (match_operand:GPR 4 "nonzero_shift_count_operand" ""))))]
4132 "<z10_or_zEC12_cond>
4133 && UINTVAL (operands[2]) == (1UL << UINTVAL (operands[4])) - 1"
4134 "<risbg_n>\t%0,%3,<bitoff>,64-%4-1,%4"
4135 [(set_attr "op_type" "RIE")
4136 (set_attr "z10prop" "z10_super_E1")])
4138 ; a = ((i32)a & -16777216) | (((ui32)b) >> 8)
4139 (define_insn "*<risbg_n>_<mode>_ior_and_lshiftrt"
4140 [(set (match_operand:GPR 0 "register_operand" "=d")
4142 (match_operand:GPR 1 "register_operand" "0")
4143 (match_operand:GPR 2 "const_int_operand" ""))
4145 (match_operand:GPR 3 "register_operand" "d")
4146 (match_operand:GPR 4 "nonzero_shift_count_operand" ""))))]
4147 "<z10_or_zEC12_cond> && UINTVAL (operands[2])
4148 == (~(0ULL) << (GET_MODE_BITSIZE (<MODE>mode) - UINTVAL (operands[4])))"
4149 "<risbg_n>\t%0,%3,<bitoff_plus>%4,63,64-%4"
4150 [(set_attr "op_type" "RIE")
4151 (set_attr "z10prop" "z10_super_E1")])
4153 ; (ui32)(((ui64)x) >> 48) | ((i32)y & -65536);
4154 (define_insn "*<risbg_n>_sidi_ior_and_lshiftrt"
4155 [(set (match_operand:SI 0 "register_operand" "=d")
4157 (match_operand:SI 1 "register_operand" "0")
4158 (match_operand:SI 2 "const_int_operand" ""))
4161 (match_operand:DI 3 "register_operand" "d")
4162 (match_operand:DI 4 "nonzero_shift_count_operand" "")) 4)))]
4163 "<z10_or_zEC12_cond>
4164 && UINTVAL (operands[2]) == ~(~(0ULL) >> UINTVAL (operands[4]))"
4165 "<risbg_n>\t%0,%3,%4,63,64-%4"
4166 [(set_attr "op_type" "RIE")
4167 (set_attr "z10prop" "z10_super_E1")])
4169 ; (ui32)(((ui64)x) >> 12) & -4
4170 (define_insn "*trunc_sidi_and_subreg_lshrt<clobbercc_or_nocc>"
4171 [(set (match_operand:SI 0 "register_operand" "=d")
4173 (subreg:SI (lshiftrt:DI
4174 (match_operand:DI 1 "register_operand" "d")
4175 (match_operand:DI 2 "nonzero_shift_count_operand" "")) 4)
4176 (match_operand:SI 3 "contiguous_bitmask_nowrap_operand" "")))]
4177 "<z10_or_zEC12_cond>"
4178 "<risbg_n>\t%0,%1,%t3,128+%f3,64-%2"
4179 [(set_attr "op_type" "RIE")
4180 (set_attr "z10prop" "z10_super_E1")])
4182 ; z = (x << c) | (y >> d) with (x << c) and (y >> d) not overlapping after shifting
4183 ; -> z = y >> d; z = (x << c) | (z & ((1 << c) - 1))
4184 ; -> z = y >> d; z = risbg;
4187 [(set (match_operand:GPR 0 "nonimmediate_operand" "")
4188 (ior:GPR (lshiftrt:GPR (match_operand:GPR 1 "nonimmediate_operand" "")
4189 (match_operand:GPR 2 "nonzero_shift_count_operand" ""))
4190 (ashift:GPR (match_operand:GPR 3 "nonimmediate_operand" "")
4191 (match_operand:GPR 4 "nonzero_shift_count_operand" ""))))]
4192 "TARGET_ZEC12 && UINTVAL (operands[2]) + UINTVAL (operands[4]) >= <bitsize>"
4194 (lshiftrt:GPR (match_dup 1) (match_dup 2)))
4196 (ior:GPR (and:GPR (match_dup 6) (match_dup 5))
4197 (ashift:GPR (match_dup 3) (match_dup 4))))]
4199 operands[5] = GEN_INT ((1UL << UINTVAL (operands[4])) - 1);
4200 if (reg_overlap_mentioned_p (operands[0], operands[3]))
4202 if (!can_create_pseudo_p ())
4204 operands[6] = gen_reg_rtx (<MODE>mode);
4207 operands[6] = operands[0];
4212 [(set (match_operand:GPR 0 "nonimmediate_operand" "")
4213 (ior:GPR (lshiftrt:GPR (match_operand:GPR 1 "nonimmediate_operand" "")
4214 (match_operand:GPR 2 "nonzero_shift_count_operand" ""))
4215 (ashift:GPR (match_operand:GPR 3 "nonimmediate_operand" "")
4216 (match_operand:GPR 4 "nonzero_shift_count_operand" ""))))
4217 (clobber (reg:CC CC_REGNUM))])]
4218 "TARGET_Z10 && !TARGET_ZEC12 && UINTVAL (operands[2]) + UINTVAL (operands[4]) >= <bitsize>"
4220 (lshiftrt:GPR (match_dup 1) (match_dup 2)))
4223 (ior:GPR (and:GPR (match_dup 6) (match_dup 5))
4224 (ashift:GPR (match_dup 3) (match_dup 4))))
4225 (clobber (reg:CC CC_REGNUM))])]
4227 operands[5] = GEN_INT ((1UL << UINTVAL (operands[4])) - 1);
4228 if (reg_overlap_mentioned_p (operands[0], operands[3]))
4230 if (!can_create_pseudo_p ())
4232 operands[6] = gen_reg_rtx (<MODE>mode);
4235 operands[6] = operands[0];
4239 (define_insn "*r<noxa>sbg_<mode>_noshift"
4240 [(set (match_operand:GPR 0 "nonimmediate_operand" "=d")
4242 (and:GPR (match_operand:GPR 1 "nonimmediate_operand" "d")
4243 (match_operand:GPR 2 "contiguous_bitmask_operand" ""))
4244 (match_operand:GPR 3 "nonimmediate_operand" "0")))
4245 (clobber (reg:CC CC_REGNUM))]
4247 "r<noxa>sbg\t%0,%1,%<bfstart>2,%<bfend>2,0"
4248 [(set_attr "op_type" "RIE")])
4251 (define_insn "*r<noxa>sbg_di_rotl"
4252 [(set (match_operand:DI 0 "nonimmediate_operand" "=d")
4256 (match_operand:DI 1 "nonimmediate_operand" "d")
4257 (match_operand:DI 3 "const_int_operand" ""))
4258 (match_operand:DI 2 "contiguous_bitmask_operand" ""))
4259 (match_operand:DI 4 "nonimmediate_operand" "0")))
4260 (clobber (reg:CC CC_REGNUM))]
4262 "r<noxa>sbg\t%0,%1,%s2,%e2,%b3"
4263 [(set_attr "op_type" "RIE")])
4266 (define_insn "*r<noxa>sbg_<mode>_srl_bitmask"
4267 [(set (match_operand:GPR 0 "nonimmediate_operand" "=d")
4271 (match_operand:GPR 1 "nonimmediate_operand" "d")
4272 (match_operand:GPR 3 "nonzero_shift_count_operand" ""))
4273 (match_operand:GPR 2 "contiguous_bitmask_nowrap_operand" ""))
4274 (match_operand:GPR 4 "nonimmediate_operand" "0")))
4275 (clobber (reg:CC CC_REGNUM))]
4277 && s390_extzv_shift_ok (<bitsize>, 64 - INTVAL (operands[3]),
4278 INTVAL (operands[2]))"
4279 "r<noxa>sbg\t%0,%1,%<bfstart>2,%<bfend>2,64-%3"
4280 [(set_attr "op_type" "RIE")])
4283 (define_insn "*r<noxa>sbg_<mode>_sll_bitmask"
4284 [(set (match_operand:GPR 0 "nonimmediate_operand" "=d")
4288 (match_operand:GPR 1 "nonimmediate_operand" "d")
4289 (match_operand:GPR 3 "nonzero_shift_count_operand" ""))
4290 (match_operand:GPR 2 "contiguous_bitmask_nowrap_operand" ""))
4291 (match_operand:GPR 4 "nonimmediate_operand" "0")))
4292 (clobber (reg:CC CC_REGNUM))]
4294 && s390_extzv_shift_ok (<bitsize>, INTVAL (operands[3]),
4295 INTVAL (operands[2]))"
4296 "r<noxa>sbg\t%0,%1,%<bfstart>2,%<bfend>2,%3"
4297 [(set_attr "op_type" "RIE")])
4299 ;; unsigned {int,long} a, b
4300 ;; a = a | (b << const_int)
4301 ;; a = a ^ (b << const_int)
4303 (define_insn "*r<noxa>sbg_<mode>_sll"
4304 [(set (match_operand:GPR 0 "nonimmediate_operand" "=d")
4307 (match_operand:GPR 1 "nonimmediate_operand" "d")
4308 (match_operand:GPR 2 "nonzero_shift_count_operand" ""))
4309 (match_operand:GPR 3 "nonimmediate_operand" "0")))
4310 (clobber (reg:CC CC_REGNUM))]
4312 "r<noxa>sbg\t%0,%1,<bitoff>,63-%2,%2"
4313 [(set_attr "op_type" "RIE")])
4315 ;; unsigned {int,long} a, b
4316 ;; a = a | (b >> const_int)
4317 ;; a = a ^ (b >> const_int)
4319 (define_insn "*r<noxa>sbg_<mode>_srl"
4320 [(set (match_operand:GPR 0 "nonimmediate_operand" "=d")
4323 (match_operand:GPR 1 "nonimmediate_operand" "d")
4324 (match_operand:GPR 2 "nonzero_shift_count_operand" ""))
4325 (match_operand:GPR 3 "nonimmediate_operand" "0")))
4326 (clobber (reg:CC CC_REGNUM))]
4328 "r<noxa>sbg\t%0,%1,<bitoff_plus>%2,63,64-%2"
4329 [(set_attr "op_type" "RIE")])
4331 ;; These two are generated by combine for s.bf &= val.
4332 ;; ??? For bitfields smaller than 32-bits, we wind up with SImode
4333 ;; shifts and ands, which results in some truly awful patterns
4334 ;; including subregs of operations. Rather unnecessisarily, IMO.
4337 ;; (set (zero_extract:DI (reg/v:DI 50 [ s ])
4338 ;; (const_int 24 [0x18])
4339 ;; (const_int 0 [0]))
4340 ;; (subreg:DI (and:SI (subreg:SI (lshiftrt:DI (reg/v:DI 50 [ s ])
4341 ;; (const_int 40 [0x28])) 4)
4342 ;; (reg:SI 4 %r4 [ y+4 ])) 0))
4344 ;; we should instead generate
4346 ;; (set (zero_extract:DI (reg/v:DI 50 [ s ])
4347 ;; (const_int 24 [0x18])
4348 ;; (const_int 0 [0]))
4349 ;; (and:DI (lshiftrt:DI (reg/v:DI 50 [ s ])
4350 ;; (const_int 40 [0x28]))
4351 ;; (subreg:DI (reg:SI 4 %r4 [ y+4 ]) 0)))
4353 ;; by noticing that we can push down the outer paradoxical subreg
4354 ;; into the operation.
4356 (define_insn "*insv_rnsbg_noshift"
4357 [(set (zero_extract:DI
4358 (match_operand:DI 0 "nonimmediate_operand" "+d")
4359 (match_operand 1 "const_int_operand" "")
4360 (match_operand 2 "const_int_operand" ""))
4363 (match_operand:DI 3 "nonimmediate_operand" "d")))
4364 (clobber (reg:CC CC_REGNUM))]
4366 && EXTRACT_ARGS_IN_RANGE (INTVAL (operands[1]), INTVAL (operands[2]), 64)
4367 && INTVAL (operands[1]) + INTVAL (operands[2]) == 64"
4368 "rnsbg\t%0,%3,%2,63,0"
4369 [(set_attr "op_type" "RIE")])
4371 (define_insn "*insv_rnsbg_srl"
4372 [(set (zero_extract:DI
4373 (match_operand:DI 0 "nonimmediate_operand" "+d")
4374 (match_operand 1 "const_int_operand" "")
4375 (match_operand 2 "const_int_operand" ""))
4379 (match_operand 3 "const_int_operand" ""))
4380 (match_operand:DI 4 "nonimmediate_operand" "d")))
4381 (clobber (reg:CC CC_REGNUM))]
4383 && EXTRACT_ARGS_IN_RANGE (INTVAL (operands[1]), INTVAL (operands[2]), 64)
4384 && INTVAL (operands[3]) == 64 - INTVAL (operands[1]) - INTVAL (operands[2])"
4385 "rnsbg\t%0,%4,%2,%2+%1-1,%3"
4386 [(set_attr "op_type" "RIE")])
4388 (define_insn "*insv<mode>_mem_reg"
4389 [(set (zero_extract:W (match_operand:QI 0 "memory_operand" "+Q,S")
4390 (match_operand 1 "const_int_operand" "n,n")
4392 (match_operand:W 2 "register_operand" "d,d"))]
4393 "EXTRACT_ARGS_IN_RANGE (INTVAL (operands[1]), 0, 64)
4394 && INTVAL (operands[1]) > 0
4395 && INTVAL (operands[1]) <= GET_MODE_BITSIZE (SImode)
4396 && INTVAL (operands[1]) % BITS_PER_UNIT == 0"
4398 int size = INTVAL (operands[1]) / BITS_PER_UNIT;
4400 operands[1] = GEN_INT ((1ul << size) - 1);
4401 return (which_alternative == 0) ? "stcm\t%2,%1,%S0"
4402 : "stcmy\t%2,%1,%S0";
4404 [(set_attr "op_type" "RS,RSY")
4405 (set_attr "cpu_facility" "*,longdisp")
4406 (set_attr "z10prop" "z10_super,z10_super")])
4408 (define_insn "*insvdi_mem_reghigh"
4409 [(set (zero_extract:DI (match_operand:QI 0 "memory_operand" "+S")
4410 (match_operand 1 "const_int_operand" "n")
4412 (lshiftrt:DI (match_operand:DI 2 "register_operand" "d")
4415 && EXTRACT_ARGS_IN_RANGE (INTVAL (operands[1]), 0, 64)
4416 && INTVAL (operands[1]) > 0
4417 && INTVAL (operands[1]) <= GET_MODE_BITSIZE (SImode)
4418 && INTVAL (operands[1]) % BITS_PER_UNIT == 0"
4420 int size = INTVAL (operands[1]) / BITS_PER_UNIT;
4422 operands[1] = GEN_INT ((1ul << size) - 1);
4423 return "stcmh\t%2,%1,%S0";
4425 [(set_attr "op_type" "RSY")
4426 (set_attr "z10prop" "z10_super")])
4428 (define_insn "*insvdi_reg_imm"
4429 [(set (zero_extract:DI (match_operand:DI 0 "register_operand" "+d")
4431 (match_operand 1 "const_int_operand" "n"))
4432 (match_operand:DI 2 "const_int_operand" "n"))]
4434 && EXTRACT_ARGS_IN_RANGE (16, INTVAL (operands[1]), 64)
4435 && INTVAL (operands[1]) >= 0
4436 && INTVAL (operands[1]) < BITS_PER_WORD
4437 && INTVAL (operands[1]) % 16 == 0"
4439 switch (BITS_PER_WORD - INTVAL (operands[1]))
4441 case 64: return "iihh\t%0,%x2"; break;
4442 case 48: return "iihl\t%0,%x2"; break;
4443 case 32: return "iilh\t%0,%x2"; break;
4444 case 16: return "iill\t%0,%x2"; break;
4445 default: gcc_unreachable();
4448 [(set_attr "op_type" "RI")
4449 (set_attr "z10prop" "z10_super_E1")])
4451 ; Update the left-most 32 bit of a DI.
4452 (define_insn "*insv_h_di_reg_extimm"
4453 [(set (zero_extract:DI (match_operand:DI 0 "register_operand" "+d")
4456 (match_operand:DI 1 "const_int_operand" "n"))]
4459 [(set_attr "op_type" "RIL")
4460 (set_attr "z10prop" "z10_fwd_E1")])
4462 ; Update the right-most 32 bit of a DI.
4463 (define_insn "*insv_l_di_reg_extimm"
4464 [(set (zero_extract:DI (match_operand:DI 0 "register_operand" "+d")
4467 (match_operand:DI 1 "const_int_operand" "n"))]
4470 [(set_attr "op_type" "RIL")
4471 (set_attr "z10prop" "z10_fwd_A1")])
4474 ; extendsidi2 instruction pattern(s).
4477 (define_expand "extendsidi2"
4478 [(set (match_operand:DI 0 "register_operand" "")
4479 (sign_extend:DI (match_operand:SI 1 "nonimmediate_operand" "")))]
4484 emit_clobber (operands[0]);
4485 emit_move_insn (gen_highpart (SImode, operands[0]), operands[1]);
4486 emit_move_insn (gen_lowpart (SImode, operands[0]), const0_rtx);
4487 emit_insn (gen_ashrdi3 (operands[0], operands[0], GEN_INT (32)));
4492 (define_insn "*extendsidi2"
4493 [(set (match_operand:DI 0 "register_operand" "=d,d,d")
4494 (sign_extend:DI (match_operand:SI 1 "nonimmediate_operand" "d,T,b")))]
4500 [(set_attr "op_type" "RRE,RXY,RIL")
4501 (set_attr "type" "*,*,larl")
4502 (set_attr "cpu_facility" "*,*,z10")
4503 (set_attr "z10prop" "z10_super_E1,z10_super_E1,z10_super_E1")
4504 (set_attr "relative_long" "*,*,yes")])
4507 ; extend(hi|qi)(si|di)2 instruction pattern(s).
4510 (define_expand "extend<HQI:mode><DSI:mode>2"
4511 [(set (match_operand:DSI 0 "register_operand" "")
4512 (sign_extend:DSI (match_operand:HQI 1 "nonimmediate_operand" "")))]
4515 if (<DSI:MODE>mode == DImode && !TARGET_ZARCH)
4517 rtx tmp = gen_reg_rtx (SImode);
4518 emit_insn (gen_extend<HQI:mode>si2 (tmp, operands[1]));
4519 emit_insn (gen_extendsidi2 (operands[0], tmp));
4522 else if (!TARGET_EXTIMM)
4524 rtx bitcount = GEN_INT (<DSI:bitsize> - <HQI:bitsize>);
4526 operands[1] = gen_lowpart (<DSI:MODE>mode, operands[1]);
4527 emit_insn (gen_ashl<DSI:mode>3 (operands[0], operands[1], bitcount));
4528 emit_insn (gen_ashr<DSI:mode>3 (operands[0], operands[0], bitcount));
4534 ; extendhidi2 instruction pattern(s).
4537 (define_insn "*extendhidi2_extimm"
4538 [(set (match_operand:DI 0 "register_operand" "=d,d,d")
4539 (sign_extend:DI (match_operand:HI 1 "general_operand" "d,T,b")))]
4540 "TARGET_ZARCH && TARGET_EXTIMM"
4545 [(set_attr "op_type" "RRE,RXY,RIL")
4546 (set_attr "type" "*,*,larl")
4547 (set_attr "cpu_facility" "extimm,extimm,z10")
4548 (set_attr "z10prop" "z10_super_E1,z10_super_E1,z10_super_E1")
4549 (set_attr "relative_long" "*,*,yes")])
4551 (define_insn "*extendhidi2"
4552 [(set (match_operand:DI 0 "register_operand" "=d")
4553 (sign_extend:DI (match_operand:HI 1 "memory_operand" "T")))]
4556 [(set_attr "op_type" "RXY")
4557 (set_attr "z10prop" "z10_super_E1")])
4560 ; extendhisi2 instruction pattern(s).
4563 (define_insn "*extendhisi2_extimm"
4564 [(set (match_operand:SI 0 "register_operand" "=d,d,d,d")
4565 (sign_extend:SI (match_operand:HI 1 "nonimmediate_operand" " d,R,T,b")))]
4572 [(set_attr "op_type" "RRE,RX,RXY,RIL")
4573 (set_attr "type" "*,*,*,larl")
4574 (set_attr "cpu_facility" "extimm,extimm,extimm,z10")
4575 (set_attr "z10prop" "z10_super_E1,z10_super_E1,z10_super_E1,z10_super_E1")
4576 (set_attr "relative_long" "*,*,*,yes")])
4578 (define_insn "*extendhisi2"
4579 [(set (match_operand:SI 0 "register_operand" "=d,d")
4580 (sign_extend:SI (match_operand:HI 1 "memory_operand" "R,T")))]
4585 [(set_attr "op_type" "RX,RXY")
4586 (set_attr "cpu_facility" "*,longdisp")
4587 (set_attr "z10prop" "z10_super_E1,z10_super_E1")])
4590 ; extendqi(si|di)2 instruction pattern(s).
4593 ; lbr, lgbr, lb, lgb
4594 (define_insn "*extendqi<mode>2_extimm"
4595 [(set (match_operand:GPR 0 "register_operand" "=d,d")
4596 (sign_extend:GPR (match_operand:QI 1 "nonimmediate_operand" "d,T")))]
4601 [(set_attr "op_type" "RRE,RXY")
4602 (set_attr "z10prop" "z10_super_E1,z10_super_E1")])
4605 (define_insn "*extendqi<mode>2"
4606 [(set (match_operand:GPR 0 "register_operand" "=d")
4607 (sign_extend:GPR (match_operand:QI 1 "memory_operand" "T")))]
4608 "!TARGET_EXTIMM && TARGET_LONG_DISPLACEMENT"
4610 [(set_attr "op_type" "RXY")
4611 (set_attr "z10prop" "z10_super_E1")])
4613 (define_insn_and_split "*extendqi<mode>2_short_displ"
4614 [(set (match_operand:GPR 0 "register_operand" "=d")
4615 (sign_extend:GPR (match_operand:QI 1 "s_operand" "Q")))
4616 (clobber (reg:CC CC_REGNUM))]
4617 "!TARGET_EXTIMM && !TARGET_LONG_DISPLACEMENT"
4619 "&& reload_completed"
4621 [(set (match_dup 0) (unspec:GPR [(match_dup 1) (const_int 8)] UNSPEC_ICM))
4622 (clobber (reg:CC CC_REGNUM))])
4624 [(set (match_dup 0) (ashiftrt:GPR (match_dup 0) (match_dup 2)))
4625 (clobber (reg:CC CC_REGNUM))])]
4627 operands[1] = adjust_address (operands[1], BLKmode, 0);
4628 set_mem_size (operands[1], GET_MODE_SIZE (QImode));
4629 operands[2] = GEN_INT (<GPR:bitsize> - BITS_PER_UNIT);
4633 ; zero_extendsidi2 instruction pattern(s).
4636 (define_expand "zero_extendsidi2"
4637 [(set (match_operand:DI 0 "register_operand" "")
4638 (zero_extend:DI (match_operand:SI 1 "nonimmediate_operand" "")))]
4643 emit_clobber (operands[0]);
4644 emit_move_insn (gen_lowpart (SImode, operands[0]), operands[1]);
4645 emit_move_insn (gen_highpart (SImode, operands[0]), const0_rtx);
4650 (define_insn "*zero_extendsidi2"
4651 [(set (match_operand:DI 0 "register_operand" "=d,d,d")
4652 (zero_extend:DI (match_operand:SI 1 "nonimmediate_operand" "d,T,b")))]
4658 [(set_attr "op_type" "RRE,RXY,RIL")
4659 (set_attr "type" "*,*,larl")
4660 (set_attr "cpu_facility" "*,*,z10")
4661 (set_attr "z10prop" "z10_fwd_E1,z10_fwd_A3,z10_fwd_A3")
4662 (set_attr "relative_long" "*,*,yes")])
4665 ; LLGT-type instructions (zero-extend from 31 bit to 64 bit).
4668 (define_insn "*llgt_sidi"
4669 [(set (match_operand:DI 0 "register_operand" "=d")
4670 (and:DI (subreg:DI (match_operand:SI 1 "memory_operand" "T") 0)
4671 (const_int 2147483647)))]
4674 [(set_attr "op_type" "RXE")
4675 (set_attr "z10prop" "z10_super_E1")])
4677 (define_insn_and_split "*llgt_sidi_split"
4678 [(set (match_operand:DI 0 "register_operand" "=d")
4679 (and:DI (subreg:DI (match_operand:SI 1 "memory_operand" "T") 0)
4680 (const_int 2147483647)))
4681 (clobber (reg:CC CC_REGNUM))]
4684 "&& reload_completed"
4686 (and:DI (subreg:DI (match_dup 1) 0)
4687 (const_int 2147483647)))]
4690 (define_insn "*llgt_sisi"
4691 [(set (match_operand:SI 0 "register_operand" "=d,d")
4692 (and:SI (match_operand:SI 1 "nonimmediate_operand" "d,T")
4693 (const_int 2147483647)))]
4698 [(set_attr "op_type" "RRE,RXE")
4699 (set_attr "z10prop" "z10_super_E1,z10_super_E1")])
4701 (define_insn "*llgt_didi"
4702 [(set (match_operand:DI 0 "register_operand" "=d,d")
4703 (and:DI (match_operand:DI 1 "nonimmediate_operand" "d,o")
4704 (const_int 2147483647)))]
4709 [(set_attr "op_type" "RRE,RXE")
4710 (set_attr "z10prop" "z10_super_E1,z10_super_E1")])
4713 [(set (match_operand:DSI 0 "register_operand" "")
4714 (and:DSI (match_operand:DSI 1 "nonimmediate_operand" "")
4715 (const_int 2147483647)))
4716 (clobber (reg:CC CC_REGNUM))]
4717 "TARGET_ZARCH && reload_completed"
4719 (and:DSI (match_dup 1)
4720 (const_int 2147483647)))]
4724 ; zero_extend(hi|qi)(si|di)2 instruction pattern(s).
4727 (define_expand "zero_extend<mode>di2"
4728 [(set (match_operand:DI 0 "register_operand" "")
4729 (zero_extend:DI (match_operand:HQI 1 "nonimmediate_operand" "")))]
4734 rtx tmp = gen_reg_rtx (SImode);
4735 emit_insn (gen_zero_extend<mode>si2 (tmp, operands[1]));
4736 emit_insn (gen_zero_extendsidi2 (operands[0], tmp));
4739 else if (!TARGET_EXTIMM)
4741 rtx bitcount = GEN_INT (64 - <HQI:bitsize>);
4742 operands[1] = gen_lowpart (DImode, operands[1]);
4743 emit_insn (gen_ashldi3 (operands[0], operands[1], bitcount));
4744 emit_insn (gen_lshrdi3 (operands[0], operands[0], bitcount));
4749 (define_expand "zero_extend<mode>si2"
4750 [(set (match_operand:SI 0 "register_operand" "")
4751 (zero_extend:SI (match_operand:HQI 1 "nonimmediate_operand" "")))]
4756 operands[1] = gen_lowpart (SImode, operands[1]);
4757 emit_insn (gen_andsi3 (operands[0], operands[1],
4758 GEN_INT ((1 << <HQI:bitsize>) - 1)));
4764 (define_insn "*zero_extendhi<mode>2_z10"
4765 [(set (match_operand:GPR 0 "register_operand" "=d,d,d")
4766 (zero_extend:GPR (match_operand:HI 1 "nonimmediate_operand" "d,T,b")))]
4772 [(set_attr "op_type" "RXY,RRE,RIL")
4773 (set_attr "type" "*,*,larl")
4774 (set_attr "cpu_facility" "*,*,z10")
4775 (set_attr "z10prop" "z10_super_E1,z10_fwd_A3,z10_fwd_A3")
4776 (set_attr "relative_long" "*,*,yes")])
4778 ; llhr, llcr, llghr, llgcr, llh, llc, llgh, llgc
4779 (define_insn "*zero_extend<HQI:mode><GPR:mode>2_extimm"
4780 [(set (match_operand:GPR 0 "register_operand" "=d,d")
4781 (zero_extend:GPR (match_operand:HQI 1 "nonimmediate_operand" "d,T")))]
4786 [(set_attr "op_type" "RRE,RXY")
4787 (set_attr "z10prop" "z10_super_E1,z10_fwd_A3")])
4790 (define_insn "*zero_extend<HQI:mode><GPR:mode>2"
4791 [(set (match_operand:GPR 0 "register_operand" "=d")
4792 (zero_extend:GPR (match_operand:HQI 1 "memory_operand" "T")))]
4793 "TARGET_ZARCH && !TARGET_EXTIMM"
4795 [(set_attr "op_type" "RXY")
4796 (set_attr "z10prop" "z10_fwd_A3")])
4798 (define_insn_and_split "*zero_extendhisi2_31"
4799 [(set (match_operand:SI 0 "register_operand" "=&d")
4800 (zero_extend:SI (match_operand:HI 1 "s_operand" "S")))
4801 (clobber (reg:CC CC_REGNUM))]
4804 "&& reload_completed"
4805 [(set (match_dup 0) (const_int 0))
4807 [(set (strict_low_part (match_dup 2)) (match_dup 1))
4808 (clobber (reg:CC CC_REGNUM))])]
4809 "operands[2] = gen_lowpart (HImode, operands[0]);")
4811 (define_insn_and_split "*zero_extendqisi2_31"
4812 [(set (match_operand:SI 0 "register_operand" "=&d")
4813 (zero_extend:SI (match_operand:QI 1 "memory_operand" "T")))]
4816 "&& reload_completed"
4817 [(set (match_dup 0) (const_int 0))
4818 (set (strict_low_part (match_dup 2)) (match_dup 1))]
4819 "operands[2] = gen_lowpart (QImode, operands[0]);")
4822 ; zero_extendqihi2 instruction pattern(s).
4825 (define_expand "zero_extendqihi2"
4826 [(set (match_operand:HI 0 "register_operand" "")
4827 (zero_extend:HI (match_operand:QI 1 "register_operand" "")))]
4828 "TARGET_ZARCH && !TARGET_EXTIMM"
4830 operands[1] = gen_lowpart (HImode, operands[1]);
4831 emit_insn (gen_andhi3 (operands[0], operands[1], GEN_INT (0xff)));
4835 (define_insn "*zero_extendqihi2_64"
4836 [(set (match_operand:HI 0 "register_operand" "=d")
4837 (zero_extend:HI (match_operand:QI 1 "memory_operand" "T")))]
4838 "TARGET_ZARCH && !TARGET_EXTIMM"
4840 [(set_attr "op_type" "RXY")
4841 (set_attr "z10prop" "z10_fwd_A3")])
4843 (define_insn_and_split "*zero_extendqihi2_31"
4844 [(set (match_operand:HI 0 "register_operand" "=&d")
4845 (zero_extend:HI (match_operand:QI 1 "memory_operand" "T")))]
4848 "&& reload_completed"
4849 [(set (match_dup 0) (const_int 0))
4850 (set (strict_low_part (match_dup 2)) (match_dup 1))]
4851 "operands[2] = gen_lowpart (QImode, operands[0]);")
4854 ; fixuns_trunc(dd|td|sf|df|tf)(si|di)2 expander
4857 ; This is the only entry point for fixuns_trunc. It multiplexes the
4858 ; expansion to either the *_emu expanders below for pre z196 machines
4859 ; or emits the default pattern otherwise.
4860 (define_expand "fixuns_trunc<FP:mode><GPR:mode>2"
4862 [(set (match_operand:GPR 0 "register_operand" "")
4863 (unsigned_fix:GPR (match_operand:FP 1 "register_operand" "")))
4864 (unspec:GPR [(match_dup 2)] UNSPEC_ROUND)
4865 (clobber (reg:CC CC_REGNUM))])]
4870 /* We don't provide emulation for TD|DD->SI. */
4871 if (GET_MODE_CLASS (<FP:MODE>mode) == MODE_DECIMAL_FLOAT
4872 && <GPR:MODE>mode == SImode)
4874 emit_insn (gen_fixuns_trunc<FP:mode><GPR:mode>2_emu (operands[0],
4879 if (GET_MODE_CLASS (<FP:MODE>mode) == MODE_DECIMAL_FLOAT)
4880 operands[2] = GEN_INT (DFP_RND_TOWARD_0);
4882 operands[2] = GEN_INT (BFP_RND_TOWARD_0);
4885 ; (sf|df|tf)->unsigned (si|di)
4887 ; Emulate the unsigned conversion with the signed version for pre z196
4889 (define_expand "fixuns_trunc<BFP:mode><GPR:mode>2_emu"
4891 [(set (match_operand:GPR 0 "register_operand" "")
4892 (unsigned_fix:GPR (match_operand:BFP 1 "register_operand" "")))
4893 (unspec:GPR [(const_int BFP_RND_TOWARD_0)] UNSPEC_ROUND)
4894 (clobber (reg:CC CC_REGNUM))])]
4895 "!TARGET_Z196 && TARGET_HARD_FLOAT"
4897 rtx_code_label *label1 = gen_label_rtx ();
4898 rtx_code_label *label2 = gen_label_rtx ();
4899 rtx temp = gen_reg_rtx (<BFP:MODE>mode);
4900 REAL_VALUE_TYPE cmp, sub;
4902 operands[1] = force_reg (<BFP:MODE>mode, operands[1]);
4903 real_2expN (&cmp, <GPR:bitsize> - 1, <BFP:MODE>mode);
4904 real_2expN (&sub, <GPR:bitsize>, <BFP:MODE>mode);
4906 emit_cmp_and_jump_insns (operands[1],
4907 const_double_from_real_value (cmp, <BFP:MODE>mode),
4908 LT, NULL_RTX, VOIDmode, 0, label1);
4909 emit_insn (gen_sub<BFP:mode>3 (temp, operands[1],
4910 const_double_from_real_value (sub, <BFP:MODE>mode)));
4911 emit_insn (gen_fix_trunc<BFP:mode><GPR:mode>2_bfp (operands[0], temp,
4912 GEN_INT (BFP_RND_TOWARD_MINF)));
4915 emit_label (label1);
4916 emit_insn (gen_fix_trunc<BFP:mode><GPR:mode>2_bfp (operands[0],
4918 GEN_INT (BFP_RND_TOWARD_0)));
4919 emit_label (label2);
4925 ; Emulate the unsigned conversion with the signed version for pre z196
4927 (define_expand "fixuns_truncdddi2_emu"
4929 [(set (match_operand:DI 0 "register_operand" "")
4930 (unsigned_fix:DI (match_operand:DD 1 "register_operand" "")))
4931 (unspec:DI [(const_int DFP_RND_TOWARD_0)] UNSPEC_ROUND)
4932 (clobber (reg:CC CC_REGNUM))])]
4934 "!TARGET_Z196 && TARGET_HARD_DFP"
4936 rtx_code_label *label1 = gen_label_rtx ();
4937 rtx_code_label *label2 = gen_label_rtx ();
4938 rtx temp = gen_reg_rtx (TDmode);
4939 REAL_VALUE_TYPE cmp, sub;
4941 decimal_real_from_string (&cmp, "9223372036854775808.0"); /* 2^63 */
4942 decimal_real_from_string (&sub, "18446744073709551616.0"); /* 2^64 */
4944 /* 2^63 can't be represented as 64bit DFP number with full precision. The
4945 solution is doing the check and the subtraction in TD mode and using a
4946 TD -> DI convert afterwards. */
4947 emit_insn (gen_extendddtd2 (temp, operands[1]));
4948 temp = force_reg (TDmode, temp);
4949 emit_cmp_and_jump_insns (temp,
4950 const_double_from_real_value (cmp, TDmode),
4951 LT, NULL_RTX, VOIDmode, 0, label1);
4952 emit_insn (gen_subtd3 (temp, temp,
4953 const_double_from_real_value (sub, TDmode)));
4954 emit_insn (gen_fix_trunctddi2_dfp (operands[0], temp,
4955 GEN_INT (DFP_RND_TOWARD_MINF)));
4958 emit_label (label1);
4959 emit_insn (gen_fix_truncdddi2_dfp (operands[0], operands[1],
4960 GEN_INT (DFP_RND_TOWARD_0)));
4961 emit_label (label2);
4967 ; Emulate the unsigned conversion with the signed version for pre z196
4969 (define_expand "fixuns_trunctddi2_emu"
4971 [(set (match_operand:DI 0 "register_operand" "")
4972 (unsigned_fix:DI (match_operand:TD 1 "register_operand" "")))
4973 (unspec:DI [(const_int DFP_RND_TOWARD_0)] UNSPEC_ROUND)
4974 (clobber (reg:CC CC_REGNUM))])]
4976 "!TARGET_Z196 && TARGET_HARD_DFP"
4978 rtx_code_label *label1 = gen_label_rtx ();
4979 rtx_code_label *label2 = gen_label_rtx ();
4980 rtx temp = gen_reg_rtx (TDmode);
4981 REAL_VALUE_TYPE cmp, sub;
4983 operands[1] = force_reg (TDmode, operands[1]);
4984 decimal_real_from_string (&cmp, "9223372036854775808.0"); /* 2^63 */
4985 decimal_real_from_string (&sub, "18446744073709551616.0"); /* 2^64 */
4987 emit_cmp_and_jump_insns (operands[1],
4988 const_double_from_real_value (cmp, TDmode),
4989 LT, NULL_RTX, VOIDmode, 0, label1);
4990 emit_insn (gen_subtd3 (temp, operands[1],
4991 const_double_from_real_value (sub, TDmode)));
4992 emit_insn (gen_fix_trunctddi2_dfp (operands[0], temp,
4993 GEN_INT (DFP_RND_TOWARD_MINF)));
4996 emit_label (label1);
4997 emit_insn (gen_fix_trunctddi2_dfp (operands[0], operands[1],
4998 GEN_INT (DFP_RND_TOWARD_0)));
4999 emit_label (label2);
5003 ; Just a dummy to make the code in the first expander a bit easier.
5004 (define_expand "fixuns_trunc<mode>si2_emu"
5006 [(set (match_operand:SI 0 "register_operand" "")
5007 (unsigned_fix:SI (match_operand:DFP 1 "register_operand" "")))
5008 (unspec:DI [(const_int DFP_RND_TOWARD_0)] UNSPEC_ROUND)
5009 (clobber (reg:CC CC_REGNUM))])]
5011 "!TARGET_Z196 && TARGET_HARD_DFP"
5017 ; fixuns_trunc(tf|df|sf|td|dd)(di|si)2 instruction patterns.
5020 (define_insn "*fixuns_truncdfdi2_vx"
5021 [(set (match_operand:DI 0 "register_operand" "=d,v")
5022 (unsigned_fix:DI (match_operand:DF 1 "register_operand" "f,v")))
5023 (unspec:DI [(match_operand:DI 2 "immediate_operand" "K,K")] UNSPEC_ROUND)
5024 (clobber (reg:CC CC_REGNUM))]
5025 "TARGET_VX && TARGET_HARD_FLOAT"
5028 wclgdb\t%v0,%v1,0,%h2"
5029 [(set_attr "op_type" "RRF,VRR")
5030 (set_attr "type" "ftoi")])
5032 ; (dd|td|sf|df|tf)->unsigned (di|si)
5033 ; clfebr, clfdbr, clfxbr, clgebr, clgdbr, clgxbr
5034 ; clfdtr, clfxtr, clgdtr, clgxtr
5035 (define_insn "*fixuns_trunc<FP:mode><GPR:mode>2_z196"
5036 [(set (match_operand:GPR 0 "register_operand" "=d")
5037 (unsigned_fix:GPR (match_operand:FP 1 "register_operand" "f")))
5038 (unspec:GPR [(match_operand:GPR 2 "immediate_operand" "K")] UNSPEC_ROUND)
5039 (clobber (reg:CC CC_REGNUM))]
5040 "TARGET_Z196 && TARGET_HARD_FLOAT
5041 && (!TARGET_VX || <GPR:MODE>mode != DImode || <FP:MODE>mode != DFmode)"
5042 "cl<GPR:gf><FP:xde><FP:bt>r\t%0,%h2,%1,0"
5043 [(set_attr "op_type" "RRF")
5044 (set_attr "type" "ftoi")])
5046 (define_expand "fix_trunc<DSF:mode><GPR:mode>2"
5047 [(set (match_operand:GPR 0 "register_operand" "")
5048 (fix:GPR (match_operand:DSF 1 "register_operand" "")))]
5051 emit_insn (gen_fix_trunc<DSF:mode><GPR:mode>2_bfp (operands[0], operands[1],
5052 GEN_INT (BFP_RND_TOWARD_0)));
5056 (define_insn "*fix_truncdfdi2_bfp_z13"
5057 [(set (match_operand:DI 0 "register_operand" "=d,v")
5058 (fix:DI (match_operand:DF 1 "register_operand" "f,v")))
5059 (unspec:DI [(match_operand:DI 2 "immediate_operand" "K,K")] UNSPEC_ROUND)
5060 (clobber (reg:CC CC_REGNUM))]
5061 "TARGET_VX && TARGET_HARD_FLOAT"
5064 wcgdb\t%v0,%v1,0,%h2"
5065 [(set_attr "op_type" "RRE,VRR")
5066 (set_attr "type" "ftoi")])
5068 ; cgxbr, cgdbr, cgebr, cfxbr, cfdbr, cfebr
5069 (define_insn "*fix_trunc<BFP:mode><GPR:mode>2_bfp"
5070 [(set (match_operand:GPR 0 "register_operand" "=d")
5071 (fix:GPR (match_operand:BFP 1 "register_operand" "f")))
5072 (unspec:GPR [(match_operand:GPR 2 "immediate_operand" "K")] UNSPEC_ROUND)
5073 (clobber (reg:CC CC_REGNUM))]
5075 && (!TARGET_VX || <GPR:MODE>mode != DImode || <BFP:MODE>mode != DFmode)"
5076 "c<GPR:gf><BFP:xde>br\t%0,%h2,%1"
5077 [(set_attr "op_type" "RRE")
5078 (set_attr "type" "ftoi")])
5080 (define_expand "fix_trunc<BFP:mode><GPR:mode>2_bfp"
5082 [(set (match_operand:GPR 0 "register_operand" "=d")
5083 (fix:GPR (match_operand:BFP 1 "register_operand" "f")))
5084 (unspec:GPR [(match_operand:GPR 2 "immediate_operand" "K")] UNSPEC_ROUND)
5085 (clobber (reg:CC CC_REGNUM))])]
5086 "TARGET_HARD_FLOAT")
5088 ; fix_trunc(td|dd)di2 instruction pattern(s).
5091 (define_expand "fix_trunc<mode>di2"
5092 [(set (match_operand:DI 0 "register_operand" "")
5093 (fix:DI (match_operand:DFP 1 "nonimmediate_operand" "")))]
5094 "TARGET_ZARCH && TARGET_HARD_DFP"
5096 operands[1] = force_reg (<MODE>mode, operands[1]);
5097 emit_insn (gen_fix_trunc<mode>di2_dfp (operands[0], operands[1],
5098 GEN_INT (DFP_RND_TOWARD_0)));
5103 (define_insn "fix_trunc<DFP:mode>di2_dfp"
5104 [(set (match_operand:DI 0 "register_operand" "=d")
5105 (fix:DI (match_operand:DFP 1 "register_operand" "f")))
5106 (unspec:DI [(match_operand:DI 2 "immediate_operand" "K")] UNSPEC_ROUND)
5107 (clobber (reg:CC CC_REGNUM))]
5108 "TARGET_ZARCH && TARGET_HARD_DFP"
5109 "cg<DFP:xde>tr\t%0,%h2,%1"
5110 [(set_attr "op_type" "RRF")
5111 (set_attr "type" "ftoidfp")])
5115 ; fix_trunctf(si|di)2 instruction pattern(s).
5118 (define_expand "fix_trunctf<mode>2"
5119 [(parallel [(set (match_operand:GPR 0 "register_operand" "")
5120 (fix:GPR (match_operand:TF 1 "register_operand" "")))
5121 (unspec:GPR [(const_int BFP_RND_TOWARD_0)] UNSPEC_ROUND)
5122 (clobber (reg:CC CC_REGNUM))])]
5128 ; float(si|di)(tf|df|sf|td|dd)2 instruction pattern(s).
5131 ; cxgbr, cdgbr, cegbr, cxgtr, cdgtr
5132 (define_insn "floatdi<mode>2"
5133 [(set (match_operand:FP 0 "register_operand" "=f,v")
5134 (float:FP (match_operand:DI 1 "register_operand" "d,v")))]
5135 "TARGET_ZARCH && TARGET_HARD_FLOAT"
5139 [(set_attr "op_type" "RRE,VRR")
5140 (set_attr "type" "itof<mode>" )
5141 (set_attr "cpu_facility" "*,vx")
5142 (set_attr "enabled" "*,<DFDI>")])
5144 ; cxfbr, cdfbr, cefbr
5145 (define_insn "floatsi<mode>2"
5146 [(set (match_operand:BFP 0 "register_operand" "=f")
5147 (float:BFP (match_operand:SI 1 "register_operand" "d")))]
5150 [(set_attr "op_type" "RRE")
5151 (set_attr "type" "itof<mode>" )])
5154 (define_insn "floatsi<mode>2"
5155 [(set (match_operand:DFP 0 "register_operand" "=f")
5156 (float:DFP (match_operand:SI 1 "register_operand" "d")))]
5157 "TARGET_Z196 && TARGET_HARD_FLOAT"
5158 "c<xde>ftr\t%0,0,%1,0"
5159 [(set_attr "op_type" "RRE")
5160 (set_attr "type" "itof<mode>" )])
5163 ; floatuns(si|di)(tf|df|sf|td|dd)2 instruction pattern(s).
5166 (define_insn "*floatunsdidf2_z13"
5167 [(set (match_operand:DF 0 "register_operand" "=f,v")
5168 (unsigned_float:DF (match_operand:DI 1 "register_operand" "d,v")))]
5169 "TARGET_VX && TARGET_HARD_FLOAT"
5172 wcdlgb\t%v0,%v1,0,0"
5173 [(set_attr "op_type" "RRE,VRR")
5174 (set_attr "type" "itofdf")])
5176 ; cxlgbr, cdlgbr, celgbr, cxlgtr, cdlgtr
5177 ; cxlfbr, cdlfbr, celfbr, cxlftr, cdlftr
5178 (define_insn "*floatuns<GPR:mode><FP:mode>2"
5179 [(set (match_operand:FP 0 "register_operand" "=f")
5180 (unsigned_float:FP (match_operand:GPR 1 "register_operand" "d")))]
5181 "TARGET_Z196 && TARGET_HARD_FLOAT
5182 && (!TARGET_VX || <FP:MODE>mode != DFmode || <GPR:MODE>mode != DImode)"
5183 "c<FP:xde>l<GPR:gf><FP:bt>r\t%0,0,%1,0"
5184 [(set_attr "op_type" "RRE")
5185 (set_attr "type" "itof<FP:mode>")])
5187 (define_expand "floatuns<GPR:mode><FP:mode>2"
5188 [(set (match_operand:FP 0 "register_operand" "")
5189 (unsigned_float:FP (match_operand:GPR 1 "register_operand" "")))]
5190 "TARGET_Z196 && TARGET_HARD_FLOAT")
5193 ; truncdfsf2 instruction pattern(s).
5196 (define_insn "truncdfsf2"
5197 [(set (match_operand:SF 0 "register_operand" "=f,v")
5198 (float_truncate:SF (match_operand:DF 1 "register_operand" "f,v")))]
5202 wledb\t%v0,%v1,0,0" ; IEEE inexact exception not suppressed
5203 ; According to BFP rounding mode
5204 [(set_attr "op_type" "RRE,VRR")
5205 (set_attr "type" "ftruncdf")
5206 (set_attr "cpu_facility" "*,vx")])
5209 ; trunctf(df|sf)2 instruction pattern(s).
5213 (define_insn "trunctf<mode>2"
5214 [(set (match_operand:DSF 0 "register_operand" "=f")
5215 (float_truncate:DSF (match_operand:TF 1 "register_operand" "f")))
5216 (clobber (match_scratch:TF 2 "=f"))]
5218 "l<xde>xbr\t%2,%1\;l<xde>r\t%0,%2"
5219 [(set_attr "length" "6")
5220 (set_attr "type" "ftrunctf")])
5223 ; trunctddd2 and truncddsd2 instruction pattern(s).
5227 (define_expand "trunctddd2"
5229 [(set (match_operand:DD 0 "register_operand" "")
5230 (float_truncate:DD (match_operand:TD 1 "register_operand" "")))
5231 (unspec:DI [(const_int DFP_RND_CURRENT)] UNSPEC_ROUND)
5232 (clobber (scratch:TD))])]
5235 (define_insn "*trunctddd2"
5236 [(set (match_operand:DD 0 "register_operand" "=f")
5237 (float_truncate:DD (match_operand:TD 1 "register_operand" "f")))
5238 (unspec:DI [(match_operand:DI 2 "const_mask_operand" "I")] UNSPEC_ROUND)
5239 (clobber (match_scratch:TD 3 "=f"))]
5241 "ldxtr\t%3,%2,%1,0\;ldr\t%0,%3"
5242 [(set_attr "length" "6")
5243 (set_attr "type" "ftruncdd")])
5245 (define_insn "truncddsd2"
5246 [(set (match_operand:SD 0 "register_operand" "=f")
5247 (float_truncate:SD (match_operand:DD 1 "register_operand" "f")))]
5250 [(set_attr "op_type" "RRF")
5251 (set_attr "type" "ftruncsd")])
5253 (define_expand "trunctdsd2"
5256 (float_truncate:DD (match_operand:TD 1 "register_operand" "")))
5257 (unspec:DI [(const_int DFP_RND_PREP_FOR_SHORT_PREC)] UNSPEC_ROUND)
5258 (clobber (match_scratch:TD 3 ""))])
5259 (set (match_operand:SD 0 "register_operand" "")
5260 (float_truncate:SD (match_dup 2)))]
5263 operands[2] = gen_reg_rtx (DDmode);
5267 ; extend(sf|df)(df|tf)2 instruction pattern(s).
5271 (define_insn "*extendsfdf2_z13"
5272 [(set (match_operand:DF 0 "register_operand" "=f,f,v")
5273 (float_extend:DF (match_operand:SF 1 "nonimmediate_operand" "f,R,v")))]
5274 "TARGET_VX && TARGET_HARD_FLOAT"
5279 [(set_attr "op_type" "RRE,RXE,VRR")
5280 (set_attr "type" "fsimpdf, floaddf,fsimpdf")])
5282 ; ldebr, ldeb, lxdbr, lxdb, lxebr, lxeb
5283 (define_insn "*extend<DSF:mode><BFP:mode>2"
5284 [(set (match_operand:BFP 0 "register_operand" "=f,f")
5285 (float_extend:BFP (match_operand:DSF 1 "nonimmediate_operand" "f,R")))]
5287 && GET_MODE_SIZE (<BFP:MODE>mode) > GET_MODE_SIZE (<DSF:MODE>mode)
5288 && (!TARGET_VX || <BFP:MODE>mode != DFmode || <DSF:MODE>mode != SFmode)"
5290 l<BFP:xde><DSF:xde>br\t%0,%1
5291 l<BFP:xde><DSF:xde>b\t%0,%1"
5292 [(set_attr "op_type" "RRE,RXE")
5293 (set_attr "type" "fsimp<BFP:mode>, fload<BFP:mode>")])
5295 (define_expand "extend<DSF:mode><BFP:mode>2"
5296 [(set (match_operand:BFP 0 "register_operand" "")
5297 (float_extend:BFP (match_operand:DSF 1 "nonimmediate_operand" "")))]
5299 && GET_MODE_SIZE (<BFP:MODE>mode) > GET_MODE_SIZE (<DSF:MODE>mode)")
5302 ; extendddtd2 and extendsddd2 instruction pattern(s).
5305 (define_insn "extendddtd2"
5306 [(set (match_operand:TD 0 "register_operand" "=f")
5307 (float_extend:TD (match_operand:DD 1 "register_operand" "f")))]
5310 [(set_attr "op_type" "RRF")
5311 (set_attr "type" "fsimptf")])
5313 (define_insn "extendsddd2"
5314 [(set (match_operand:DD 0 "register_operand" "=f")
5315 (float_extend:DD (match_operand:SD 1 "register_operand" "f")))]
5318 [(set_attr "op_type" "RRF")
5319 (set_attr "type" "fsimptf")])
5321 (define_expand "extendsdtd2"
5323 (float_extend:DD (match_operand:SD 1 "register_operand" "")))
5324 (set (match_operand:TD 0 "register_operand" "")
5325 (float_extend:TD (match_dup 2)))]
5328 operands[2] = gen_reg_rtx (DDmode);
5331 ; Binary Floating Point - load fp integer
5333 ; Expanders for: floor, btrunc, round, ceil, and nearbyint
5334 ; For all of them the inexact exceptions are suppressed.
5336 ; fiebra, fidbra, fixbra
5337 (define_insn "<FPINT:fpint_name><BFP:mode>2"
5338 [(set (match_operand:BFP 0 "register_operand" "=f")
5339 (unspec:BFP [(match_operand:BFP 1 "register_operand" "f")]
5342 "fi<BFP:xde>bra\t%0,<FPINT:fpint_roundingmode>,%1,4"
5343 [(set_attr "op_type" "RRF")
5344 (set_attr "type" "fsimp<BFP:mode>")])
5346 ; rint is supposed to raise an inexact exception so we can use the
5347 ; older instructions.
5349 ; fiebr, fidbr, fixbr
5350 (define_insn "rint<BFP:mode>2"
5351 [(set (match_operand:BFP 0 "register_operand" "=f")
5352 (unspec:BFP [(match_operand:BFP 1 "register_operand" "f")]
5353 UNSPEC_FPINT_RINT))]
5355 "fi<BFP:xde>br\t%0,0,%1"
5356 [(set_attr "op_type" "RRF")
5357 (set_attr "type" "fsimp<BFP:mode>")])
5360 ; Decimal Floating Point - load fp integer
5363 (define_insn "<FPINT:fpint_name><DFP:mode>2"
5364 [(set (match_operand:DFP 0 "register_operand" "=f")
5365 (unspec:DFP [(match_operand:DFP 1 "register_operand" "f")]
5368 "fi<DFP:xde>tr\t%0,<FPINT:fpint_roundingmode>,%1,4"
5369 [(set_attr "op_type" "RRF")
5370 (set_attr "type" "fsimp<DFP:mode>")])
5373 (define_insn "rint<DFP:mode>2"
5374 [(set (match_operand:DFP 0 "register_operand" "=f")
5375 (unspec:DFP [(match_operand:DFP 1 "register_operand" "f")]
5376 UNSPEC_FPINT_RINT))]
5378 "fi<DFP:xde>tr\t%0,0,%1,0"
5379 [(set_attr "op_type" "RRF")
5380 (set_attr "type" "fsimp<DFP:mode>")])
5383 ; Binary <-> Decimal floating point trunc patterns
5386 (define_insn "*trunc<BFP:mode><DFP_ALL:mode>2"
5387 [(set (reg:DFP_ALL FPR0_REGNUM)
5388 (float_truncate:DFP_ALL (reg:BFP FPR4_REGNUM)))
5389 (use (reg:SI GPR0_REGNUM))
5390 (clobber (reg:CC CC_REGNUM))
5391 (clobber (reg:SI GPR1_REGNUM))]
5395 (define_insn "*trunc<DFP_ALL:mode><BFP:mode>2"
5396 [(set (reg:BFP FPR0_REGNUM)
5397 (float_truncate:BFP (reg:DFP_ALL FPR4_REGNUM)))
5398 (use (reg:SI GPR0_REGNUM))
5399 (clobber (reg:CC CC_REGNUM))
5400 (clobber (reg:SI GPR1_REGNUM))]
5404 (define_expand "trunc<BFP:mode><DFP_ALL:mode>2"
5405 [(set (reg:BFP FPR4_REGNUM) (match_operand:BFP 1 "nonimmediate_operand" ""))
5406 (set (reg:SI GPR0_REGNUM) (match_dup 2))
5408 [(set (reg:DFP_ALL FPR0_REGNUM)
5409 (float_truncate:DFP_ALL (reg:BFP FPR4_REGNUM)))
5410 (use (reg:SI GPR0_REGNUM))
5411 (clobber (reg:CC CC_REGNUM))
5412 (clobber (reg:SI GPR1_REGNUM))])
5413 (set (match_operand:DFP_ALL 0 "nonimmediate_operand" "")
5414 (reg:DFP_ALL FPR0_REGNUM))]
5416 && GET_MODE_SIZE (<BFP:MODE>mode) > GET_MODE_SIZE (<DFP_ALL:MODE>mode)"
5418 HOST_WIDE_INT flags;
5420 /* According to IEEE 754 2008 4.3 'Rounding-direction attributes' the
5421 rounding mode of the target format needs to be used. */
5423 flags = (PFPO_CONVERT |
5424 PFPO_OP_TYPE_<DFP_ALL:MODE> << PFPO_OP0_TYPE_SHIFT |
5425 PFPO_OP_TYPE_<BFP:MODE> << PFPO_OP1_TYPE_SHIFT |
5428 operands[2] = GEN_INT (flags);
5431 (define_expand "trunc<DFP_ALL:mode><BFP:mode>2"
5432 [(set (reg:DFP_ALL FPR4_REGNUM)
5433 (match_operand:DFP_ALL 1 "nonimmediate_operand" ""))
5434 (set (reg:SI GPR0_REGNUM) (match_dup 2))
5436 [(set (reg:BFP FPR0_REGNUM) (float_truncate:BFP (reg:DFP_ALL FPR4_REGNUM)))
5437 (use (reg:SI GPR0_REGNUM))
5438 (clobber (reg:CC CC_REGNUM))
5439 (clobber (reg:SI GPR1_REGNUM))])
5440 (set (match_operand:BFP 0 "nonimmediate_operand" "") (reg:BFP FPR0_REGNUM))]
5442 && GET_MODE_SIZE (<DFP_ALL:MODE>mode) >= GET_MODE_SIZE (<BFP:MODE>mode)"
5444 HOST_WIDE_INT flags;
5446 /* According to IEEE 754 2008 4.3 'Rounding-direction attributes' the
5447 rounding mode of the target format needs to be used. */
5449 flags = (PFPO_CONVERT |
5450 PFPO_OP_TYPE_<BFP:MODE> << PFPO_OP0_TYPE_SHIFT |
5451 PFPO_OP_TYPE_<DFP_ALL:MODE> << PFPO_OP1_TYPE_SHIFT |
5454 operands[2] = GEN_INT (flags);
5458 ; Binary <-> Decimal floating point extend patterns
5461 (define_insn "*extend<BFP:mode><DFP_ALL:mode>2"
5462 [(set (reg:DFP_ALL FPR0_REGNUM) (float_extend:DFP_ALL (reg:BFP FPR4_REGNUM)))
5463 (use (reg:SI GPR0_REGNUM))
5464 (clobber (reg:CC CC_REGNUM))
5465 (clobber (reg:SI GPR1_REGNUM))]
5469 (define_insn "*extend<DFP_ALL:mode><BFP:mode>2"
5470 [(set (reg:BFP FPR0_REGNUM) (float_extend:BFP (reg:DFP_ALL FPR4_REGNUM)))
5471 (use (reg:SI GPR0_REGNUM))
5472 (clobber (reg:CC CC_REGNUM))
5473 (clobber (reg:SI GPR1_REGNUM))]
5477 (define_expand "extend<BFP:mode><DFP_ALL:mode>2"
5478 [(set (reg:BFP FPR4_REGNUM) (match_operand:BFP 1 "nonimmediate_operand" ""))
5479 (set (reg:SI GPR0_REGNUM) (match_dup 2))
5481 [(set (reg:DFP_ALL FPR0_REGNUM)
5482 (float_extend:DFP_ALL (reg:BFP FPR4_REGNUM)))
5483 (use (reg:SI GPR0_REGNUM))
5484 (clobber (reg:CC CC_REGNUM))
5485 (clobber (reg:SI GPR1_REGNUM))])
5486 (set (match_operand:DFP_ALL 0 "nonimmediate_operand" "")
5487 (reg:DFP_ALL FPR0_REGNUM))]
5489 && GET_MODE_SIZE (<BFP:MODE>mode) <= GET_MODE_SIZE (<DFP_ALL:MODE>mode)"
5491 HOST_WIDE_INT flags;
5493 /* According to IEEE 754 2008 4.3 'Rounding-direction attributes' the
5494 rounding mode of the target format needs to be used. */
5496 flags = (PFPO_CONVERT |
5497 PFPO_OP_TYPE_<DFP_ALL:MODE> << PFPO_OP0_TYPE_SHIFT |
5498 PFPO_OP_TYPE_<BFP:MODE> << PFPO_OP1_TYPE_SHIFT |
5501 operands[2] = GEN_INT (flags);
5504 (define_expand "extend<DFP_ALL:mode><BFP:mode>2"
5505 [(set (reg:DFP_ALL FPR4_REGNUM)
5506 (match_operand:DFP_ALL 1 "nonimmediate_operand" ""))
5507 (set (reg:SI GPR0_REGNUM) (match_dup 2))
5509 [(set (reg:BFP FPR0_REGNUM) (float_extend:BFP (reg:DFP_ALL FPR4_REGNUM)))
5510 (use (reg:SI GPR0_REGNUM))
5511 (clobber (reg:CC CC_REGNUM))
5512 (clobber (reg:SI GPR1_REGNUM))])
5513 (set (match_operand:BFP 0 "nonimmediate_operand" "") (reg:BFP FPR0_REGNUM))]
5515 && GET_MODE_SIZE (<DFP_ALL:MODE>mode) < GET_MODE_SIZE (<BFP:MODE>mode)"
5517 HOST_WIDE_INT flags;
5519 /* According to IEEE 754 2008 4.3 'Rounding-direction attributes' the
5520 rounding mode of the target format needs to be used. */
5522 flags = (PFPO_CONVERT |
5523 PFPO_OP_TYPE_<BFP:MODE> << PFPO_OP0_TYPE_SHIFT |
5524 PFPO_OP_TYPE_<DFP_ALL:MODE> << PFPO_OP1_TYPE_SHIFT |
5527 operands[2] = GEN_INT (flags);
5532 ;; ARITHMETIC OPERATIONS
5534 ; arithmetic operations set the ConditionCode,
5535 ; because of unpredictable Bits in Register for Halfword and Byte
5536 ; the ConditionCode can be set wrong in operations for Halfword and Byte
5539 ;;- Add instructions.
5543 ; addti3 instruction pattern(s).
5546 (define_expand "addti3"
5548 [(set (match_operand:TI 0 "register_operand" "")
5549 (plus:TI (match_operand:TI 1 "nonimmediate_operand" "")
5550 (match_operand:TI 2 "general_operand" "") ) )
5551 (clobber (reg:CC CC_REGNUM))])]
5554 /* For z13 we have vaq which doesn't set CC. */
5557 emit_insn (gen_rtx_SET (operands[0],
5558 gen_rtx_PLUS (TImode,
5559 copy_to_mode_reg (TImode, operands[1]),
5560 copy_to_mode_reg (TImode, operands[2]))));
5565 (define_insn_and_split "*addti3"
5566 [(set (match_operand:TI 0 "register_operand" "=&d")
5567 (plus:TI (match_operand:TI 1 "nonimmediate_operand" "%0")
5568 (match_operand:TI 2 "general_operand" "do") ) )
5569 (clobber (reg:CC CC_REGNUM))]
5572 "&& reload_completed"
5574 [(set (reg:CCL1 CC_REGNUM)
5575 (compare:CCL1 (plus:DI (match_dup 7) (match_dup 8))
5577 (set (match_dup 6) (plus:DI (match_dup 7) (match_dup 8)))])
5579 [(set (match_dup 3) (plus:DI
5580 (plus:DI (ltu:DI (reg:CCL1 CC_REGNUM) (const_int 0))
5581 (match_dup 4)) (match_dup 5)))
5582 (clobber (reg:CC CC_REGNUM))])]
5583 "operands[3] = operand_subword (operands[0], 0, 0, TImode);
5584 operands[4] = operand_subword (operands[1], 0, 0, TImode);
5585 operands[5] = operand_subword (operands[2], 0, 0, TImode);
5586 operands[6] = operand_subword (operands[0], 1, 0, TImode);
5587 operands[7] = operand_subword (operands[1], 1, 0, TImode);
5588 operands[8] = operand_subword (operands[2], 1, 0, TImode);"
5589 [(set_attr "op_type" "*")
5590 (set_attr "cpu_facility" "*")])
5593 ; adddi3 instruction pattern(s).
5596 (define_expand "adddi3"
5598 [(set (match_operand:DI 0 "nonimmediate_operand" "")
5599 (plus:DI (match_operand:DI 1 "nonimmediate_operand" "")
5600 (match_operand:DI 2 "general_operand" "")))
5601 (clobber (reg:CC CC_REGNUM))])]
5605 (define_insn "*adddi3_sign"
5606 [(set (match_operand:DI 0 "register_operand" "=d,d")
5607 (plus:DI (sign_extend:DI (match_operand:SI 2 "general_operand" "d,T"))
5608 (match_operand:DI 1 "register_operand" "0,0")))
5609 (clobber (reg:CC CC_REGNUM))]
5614 [(set_attr "op_type" "RRE,RXY")
5615 (set_attr "z196prop" "z196_cracked,z196_cracked")])
5617 (define_insn "*adddi3_zero_cc"
5618 [(set (reg CC_REGNUM)
5619 (compare (plus:DI (zero_extend:DI (match_operand:SI 2 "general_operand" "d,T"))
5620 (match_operand:DI 1 "register_operand" "0,0"))
5622 (set (match_operand:DI 0 "register_operand" "=d,d")
5623 (plus:DI (zero_extend:DI (match_dup 2)) (match_dup 1)))]
5624 "s390_match_ccmode (insn, CCLmode) && TARGET_ZARCH"
5628 [(set_attr "op_type" "RRE,RXY")
5629 (set_attr "z10prop" "z10_super_E1,z10_super_E1")])
5631 (define_insn "*adddi3_zero_cconly"
5632 [(set (reg CC_REGNUM)
5633 (compare (plus:DI (zero_extend:DI (match_operand:SI 2 "general_operand" "d,T"))
5634 (match_operand:DI 1 "register_operand" "0,0"))
5636 (clobber (match_scratch:DI 0 "=d,d"))]
5637 "s390_match_ccmode (insn, CCLmode) && TARGET_ZARCH"
5641 [(set_attr "op_type" "RRE,RXY")
5642 (set_attr "z10prop" "z10_super_E1,z10_super_E1")])
5644 (define_insn "*adddi3_zero"
5645 [(set (match_operand:DI 0 "register_operand" "=d,d")
5646 (plus:DI (zero_extend:DI (match_operand:SI 2 "general_operand" "d,T"))
5647 (match_operand:DI 1 "register_operand" "0,0")))
5648 (clobber (reg:CC CC_REGNUM))]
5653 [(set_attr "op_type" "RRE,RXY")
5654 (set_attr "z10prop" "z10_super_E1,z10_super_E1")])
5656 (define_insn_and_split "*adddi3_31z"
5657 [(set (match_operand:DI 0 "nonimmediate_operand" "=&d")
5658 (plus:DI (match_operand:DI 1 "nonimmediate_operand" "%0")
5659 (match_operand:DI 2 "general_operand" "do") ) )
5660 (clobber (reg:CC CC_REGNUM))]
5663 "&& reload_completed"
5665 [(set (reg:CCL1 CC_REGNUM)
5666 (compare:CCL1 (plus:SI (match_dup 7) (match_dup 8))
5668 (set (match_dup 6) (plus:SI (match_dup 7) (match_dup 8)))])
5670 [(set (match_dup 3) (plus:SI
5671 (plus:SI (ltu:SI (reg:CCL1 CC_REGNUM) (const_int 0))
5672 (match_dup 4)) (match_dup 5)))
5673 (clobber (reg:CC CC_REGNUM))])]
5674 "operands[3] = operand_subword (operands[0], 0, 0, DImode);
5675 operands[4] = operand_subword (operands[1], 0, 0, DImode);
5676 operands[5] = operand_subword (operands[2], 0, 0, DImode);
5677 operands[6] = operand_subword (operands[0], 1, 0, DImode);
5678 operands[7] = operand_subword (operands[1], 1, 0, DImode);
5679 operands[8] = operand_subword (operands[2], 1, 0, DImode);")
5682 ; addsi3 instruction pattern(s).
5685 (define_expand "addsi3"
5687 [(set (match_operand:SI 0 "nonimmediate_operand" "")
5688 (plus:SI (match_operand:SI 1 "nonimmediate_operand" "")
5689 (match_operand:SI 2 "general_operand" "")))
5690 (clobber (reg:CC CC_REGNUM))])]
5694 (define_insn "*addsi3_sign"
5695 [(set (match_operand:SI 0 "register_operand" "=d,d")
5696 (plus:SI (sign_extend:SI (match_operand:HI 2 "memory_operand" "R,T"))
5697 (match_operand:SI 1 "register_operand" "0,0")))
5698 (clobber (reg:CC CC_REGNUM))]
5703 [(set_attr "op_type" "RX,RXY")
5704 (set_attr "cpu_facility" "*,longdisp")
5705 (set_attr "z196prop" "z196_cracked,z196_cracked")])
5708 ; add(di|si)3 instruction pattern(s).
5711 ; ark, agrk, ar, ahi, ahik, aghik, alfi, slfi, a, ay, agr, aghi, algfi, slgfi, ag, asi, agsi
5712 (define_insn "*add<mode>3"
5713 [(set (match_operand:GPR 0 "nonimmediate_operand" "=d,d,d,d, d, d,d,d,S")
5714 (plus:GPR (match_operand:GPR 1 "nonimmediate_operand" "%0,d,0,d, 0, 0,0,0,0")
5715 (match_operand:GPR 2 "general_operand" " d,d,K,K,Op,On,R,T,C") ) )
5716 (clobber (reg:CC CC_REGNUM))]
5728 [(set_attr "op_type" "RR<E>,RRF,RI,RIE,RIL,RIL,RX<Y>,RXY,SIY")
5729 (set_attr "cpu_facility" "*,z196,*,z196,extimm,extimm,*,longdisp,z10")
5730 (set_attr "z10prop" "z10_super_E1,*,z10_super_E1,*,z10_super_E1,z10_super_E1,
5731 z10_super_E1,z10_super_E1,z10_super_E1")])
5733 ; alr, alfi, slfi, al, aly, alrk, alhsik, algr, algfi, slgfi, alg, alsi, algsi, algrk, alghsik
5734 (define_insn "*add<mode>3_carry1_cc"
5735 [(set (reg CC_REGNUM)
5736 (compare (plus:GPR (match_operand:GPR 1 "nonimmediate_operand" "%0,d, 0, 0,d,0,0,0")
5737 (match_operand:GPR 2 "general_operand" " d,d,Op,On,K,R,T,C"))
5739 (set (match_operand:GPR 0 "nonimmediate_operand" "=d,d, d, d,d,d,d,d")
5740 (plus:GPR (match_dup 1) (match_dup 2)))]
5741 "s390_match_ccmode (insn, CCL1mode)"
5747 al<g>hsik\t%0,%1,%h2
5751 [(set_attr "op_type" "RR<E>,RRF,RIL,RIL,RIE,RX<Y>,RXY,SIY")
5752 (set_attr "cpu_facility" "*,z196,extimm,extimm,z196,*,longdisp,z10")
5753 (set_attr "z10prop" "z10_super_E1,*,z10_super_E1,z10_super_E1,*,
5754 z10_super_E1,z10_super_E1,z10_super_E1")])
5756 ; alr, al, aly, algr, alg, alrk, algrk
5757 (define_insn "*add<mode>3_carry1_cconly"
5758 [(set (reg CC_REGNUM)
5759 (compare (plus:GPR (match_operand:GPR 1 "nonimmediate_operand" "%0,d,0,0")
5760 (match_operand:GPR 2 "general_operand" "d,d,R,T"))
5762 (clobber (match_scratch:GPR 0 "=d,d,d,d"))]
5763 "s390_match_ccmode (insn, CCL1mode)"
5769 [(set_attr "op_type" "RR<E>,RRF,RX<Y>,RXY")
5770 (set_attr "cpu_facility" "*,z196,*,longdisp")
5771 (set_attr "z10prop" "z10_super_E1,*,z10_super_E1,z10_super_E1")])
5773 ; alr, alfi, slfi, al, aly, algr, algfi, slgfi, alg, alsi, algsi, alrk, algrk, alhsik, alghsik
5774 (define_insn "*add<mode>3_carry2_cc"
5775 [(set (reg CC_REGNUM)
5776 (compare (plus:GPR (match_operand:GPR 1 "nonimmediate_operand" "%0,d, 0, 0,d,0,0,0")
5777 (match_operand:GPR 2 "general_operand" " d,d,Op,On,K,R,T,C"))
5779 (set (match_operand:GPR 0 "nonimmediate_operand" "=d,d, d, d,d,d,d,S")
5780 (plus:GPR (match_dup 1) (match_dup 2)))]
5781 "s390_match_ccmode (insn, CCL1mode)"
5787 al<g>hsik\t%0,%1,%h2
5791 [(set_attr "op_type" "RR<E>,RRF,RIL,RIL,RIE,RX<Y>,RXY,SIY")
5792 (set_attr "cpu_facility" "*,z196,extimm,extimm,z196,*,longdisp,z10")
5793 (set_attr "z10prop" "z10_super_E1,*,z10_super_E1,z10_super_E1,*,
5794 z10_super_E1,z10_super_E1,z10_super_E1")])
5796 ; alr, al, aly, algr, alg, alrk, algrk
5797 (define_insn "*add<mode>3_carry2_cconly"
5798 [(set (reg CC_REGNUM)
5799 (compare (plus:GPR (match_operand:GPR 1 "nonimmediate_operand" "%0,d,0,0")
5800 (match_operand:GPR 2 "general_operand" "d,d,R,T"))
5802 (clobber (match_scratch:GPR 0 "=d,d,d,d"))]
5803 "s390_match_ccmode (insn, CCL1mode)"
5809 [(set_attr "op_type" "RR<E>,RRF,RX<Y>,RXY")
5810 (set_attr "cpu_facility" "*,z196,*,longdisp")
5811 (set_attr "z10prop" "z10_super_E1,*,z10_super_E1,z10_super_E1")])
5813 ; alr, alfi, slfi, al, aly, algr, algfi, slgfi, alg, alsi, algsi, alrk, algrk, alhsik, alghsik
5814 (define_insn "*add<mode>3_cc"
5815 [(set (reg CC_REGNUM)
5816 (compare (plus:GPR (match_operand:GPR 1 "nonimmediate_operand" "%0,d, 0, 0,d,0,0,0")
5817 (match_operand:GPR 2 "general_operand" " d,d,Op,On,K,R,T,C"))
5819 (set (match_operand:GPR 0 "nonimmediate_operand" "=d,d, d, d,d,d,d,S")
5820 (plus:GPR (match_dup 1) (match_dup 2)))]
5821 "s390_match_ccmode (insn, CCLmode)"
5827 al<g>hsik\t%0,%1,%h2
5831 [(set_attr "op_type" "RR<E>,RRF,RIL,RIL,RIE,RX<Y>,RXY,SIY")
5832 (set_attr "cpu_facility" "*,z196,extimm,extimm,z196,*,longdisp,z10")
5833 (set_attr "z10prop" "z10_super_E1,*,z10_super_E1,z10_super_E1,
5834 *,z10_super_E1,z10_super_E1,z10_super_E1")])
5836 ; alr, al, aly, algr, alg, alrk, algrk
5837 (define_insn "*add<mode>3_cconly"
5838 [(set (reg CC_REGNUM)
5839 (compare (plus:GPR (match_operand:GPR 1 "nonimmediate_operand" "%0,d,0,0")
5840 (match_operand:GPR 2 "general_operand" "d,d,R,T"))
5842 (clobber (match_scratch:GPR 0 "=d,d,d,d"))]
5843 "s390_match_ccmode (insn, CCLmode)"
5849 [(set_attr "op_type" "RR<E>,RRF,RX<Y>,RXY")
5850 (set_attr "cpu_facility" "*,z196,*,longdisp")
5851 (set_attr "z10prop" "z10_super_E1,*,z10_super_E1,z10_super_E1")])
5853 ; alr, al, aly, algr, alg, alrk, algrk
5854 (define_insn "*add<mode>3_cconly2"
5855 [(set (reg CC_REGNUM)
5856 (compare (match_operand:GPR 1 "nonimmediate_operand" "%0,d,0,0")
5857 (neg:GPR (match_operand:GPR 2 "general_operand" "d,d,R,T"))))
5858 (clobber (match_scratch:GPR 0 "=d,d,d,d"))]
5859 "s390_match_ccmode(insn, CCLmode)"
5865 [(set_attr "op_type" "RR<E>,RRF,RX<Y>,RXY")
5866 (set_attr "cpu_facility" "*,z196,*,longdisp")
5867 (set_attr "z10prop" "z10_super_E1,*,z10_super_E1,z10_super_E1")])
5869 ; ahi, afi, aghi, agfi, asi, agsi
5870 (define_insn "*add<mode>3_imm_cc"
5871 [(set (reg CC_REGNUM)
5872 (compare (plus:GPR (match_operand:GPR 1 "nonimmediate_operand" " 0, d,0, 0")
5873 (match_operand:GPR 2 "const_int_operand" " K, K,Os,C"))
5875 (set (match_operand:GPR 0 "nonimmediate_operand" "=d, d,d, S")
5876 (plus:GPR (match_dup 1) (match_dup 2)))]
5877 "s390_match_ccmode (insn, CCAmode)
5878 && (CONST_OK_FOR_CONSTRAINT_P (INTVAL (operands[2]), 'K', \"K\")
5879 || (CONST_OK_FOR_CONSTRAINT_P (INTVAL (operands[2]), 'O', \"Os\")
5880 /* Avoid INT32_MIN on 32 bit. */
5881 && (!TARGET_ZARCH || INTVAL (operands[2]) != -0x7fffffff - 1)))"
5887 [(set_attr "op_type" "RI,RIE,RIL,SIY")
5888 (set_attr "cpu_facility" "*,z196,extimm,z10")
5889 (set_attr "z10prop" "z10_super_E1,*,z10_super_E1,z10_super_E1")])
5891 (define_insn "*adddi3_sign"
5892 [(set (match_operand:DI 0 "register_operand" "=d")
5893 (plus:DI (sign_extend:DI (match_operand:HI 2 "memory_operand" "T"))
5894 (match_operand:DI 1 "register_operand" "0")))
5895 (clobber (reg:CC CC_REGNUM))]
5898 [(set_attr "op_type" "RXY")])
5901 ; add(tf|df|sf|td|dd)3 instruction pattern(s).
5904 ; axbr, adbr, aebr, axb, adb, aeb, adtr, axtr
5905 ; FIXME: wfadb does not clobber cc
5906 (define_insn "add<mode>3"
5907 [(set (match_operand:FP 0 "register_operand" "=f,f,f,v,v")
5908 (plus:FP (match_operand:FP 1 "nonimmediate_operand" "%f,0,0,v,v")
5909 (match_operand:FP 2 "general_operand" "f,f,R,v,v")))
5910 (clobber (reg:CC CC_REGNUM))]
5918 [(set_attr "op_type" "RRF,RRE,RXE,VRR,VRR")
5919 (set_attr "type" "fsimp<mode>")
5920 (set_attr "cpu_facility" "*,*,*,vx,vxe")
5921 (set_attr "enabled" "<nBFP>,<nDFP>,<DSF>,<DF>,<SF>")])
5923 ; axbr, adbr, aebr, axb, adb, aeb, adtr, axtr
5924 (define_insn "*add<mode>3_cc"
5925 [(set (reg CC_REGNUM)
5926 (compare (plus:FP (match_operand:FP 1 "nonimmediate_operand" "%f,0,0")
5927 (match_operand:FP 2 "general_operand" "f,f,R"))
5928 (match_operand:FP 3 "const0_operand" "")))
5929 (set (match_operand:FP 0 "register_operand" "=f,f,f")
5930 (plus:FP (match_dup 1) (match_dup 2)))]
5931 "s390_match_ccmode (insn, CCSmode) && TARGET_HARD_FLOAT"
5936 [(set_attr "op_type" "RRF,RRE,RXE")
5937 (set_attr "type" "fsimp<mode>")
5938 (set_attr "enabled" "<nBFP>,<nDFP>,<DSF>")])
5940 ; axbr, adbr, aebr, axb, adb, aeb, adtr, axtr
5941 (define_insn "*add<mode>3_cconly"
5942 [(set (reg CC_REGNUM)
5943 (compare (plus:FP (match_operand:FP 1 "nonimmediate_operand" "%f,0,0")
5944 (match_operand:FP 2 "general_operand" "f,f,R"))
5945 (match_operand:FP 3 "const0_operand" "")))
5946 (clobber (match_scratch:FP 0 "=f,f,f"))]
5947 "s390_match_ccmode (insn, CCSmode) && TARGET_HARD_FLOAT"
5952 [(set_attr "op_type" "RRF,RRE,RXE")
5953 (set_attr "type" "fsimp<mode>")
5954 (set_attr "enabled" "<nBFP>,<nDFP>,<DSF>")])
5957 ; Pointer add instruction patterns
5960 ; This will match "*la_64"
5961 (define_expand "addptrdi3"
5962 [(set (match_operand:DI 0 "register_operand" "")
5963 (plus:DI (match_operand:DI 1 "register_operand" "")
5964 (match_operand:DI 2 "nonmemory_operand" "")))]
5967 if (GET_CODE (operands[2]) == CONST_INT)
5969 HOST_WIDE_INT c = INTVAL (operands[2]);
5971 if (!CONST_OK_FOR_CONSTRAINT_P (c, 'K', "K")
5972 && !CONST_OK_FOR_CONSTRAINT_P (c, 'O', "Os"))
5974 operands[2] = force_const_mem (DImode, operands[2]);
5975 operands[2] = force_reg (DImode, operands[2]);
5977 else if (!DISP_IN_RANGE (INTVAL (operands[2])))
5978 operands[2] = force_reg (DImode, operands[2]);
5982 ; For 31 bit we have to prevent the generated pattern from matching
5983 ; normal ADDs since la only does a 31 bit add. This is supposed to
5984 ; match "force_la_31".
5985 (define_expand "addptrsi3"
5987 [(set (match_operand:SI 0 "register_operand" "")
5988 (plus:SI (match_operand:SI 1 "register_operand" "")
5989 (match_operand:SI 2 "nonmemory_operand" "")))
5990 (use (const_int 0))])]
5993 if (GET_CODE (operands[2]) == CONST_INT)
5995 HOST_WIDE_INT c = INTVAL (operands[2]);
5997 if (!CONST_OK_FOR_CONSTRAINT_P (c, 'K', "K")
5998 && !CONST_OK_FOR_CONSTRAINT_P (c, 'O', "Os"))
6000 operands[2] = force_const_mem (SImode, operands[2]);
6001 operands[2] = force_reg (SImode, operands[2]);
6003 else if (!DISP_IN_RANGE (INTVAL (operands[2])))
6004 operands[2] = force_reg (SImode, operands[2]);
6009 ;;- Subtract instructions.
6013 ; subti3 instruction pattern(s).
6016 (define_expand "subti3"
6018 [(set (match_operand:TI 0 "register_operand" "")
6019 (minus:TI (match_operand:TI 1 "register_operand" "")
6020 (match_operand:TI 2 "general_operand" "") ) )
6021 (clobber (reg:CC CC_REGNUM))])]
6024 /* For z13 we have vsq which doesn't set CC. */
6027 emit_insn (gen_rtx_SET (operands[0],
6028 gen_rtx_MINUS (TImode,
6030 copy_to_mode_reg (TImode, operands[2]))));
6035 (define_insn_and_split "*subti3"
6036 [(set (match_operand:TI 0 "register_operand" "=&d")
6037 (minus:TI (match_operand:TI 1 "register_operand" "0")
6038 (match_operand:TI 2 "general_operand" "do") ) )
6039 (clobber (reg:CC CC_REGNUM))]
6042 "&& reload_completed"
6044 [(set (reg:CCL2 CC_REGNUM)
6045 (compare:CCL2 (minus:DI (match_dup 7) (match_dup 8))
6047 (set (match_dup 6) (minus:DI (match_dup 7) (match_dup 8)))])
6049 [(set (match_dup 3) (minus:DI (minus:DI (match_dup 4) (match_dup 5))
6050 (gtu:DI (reg:CCL2 CC_REGNUM) (const_int 0))))
6051 (clobber (reg:CC CC_REGNUM))])]
6052 "operands[3] = operand_subword (operands[0], 0, 0, TImode);
6053 operands[4] = operand_subword (operands[1], 0, 0, TImode);
6054 operands[5] = operand_subword (operands[2], 0, 0, TImode);
6055 operands[6] = operand_subword (operands[0], 1, 0, TImode);
6056 operands[7] = operand_subword (operands[1], 1, 0, TImode);
6057 operands[8] = operand_subword (operands[2], 1, 0, TImode);"
6058 [(set_attr "op_type" "*")
6059 (set_attr "cpu_facility" "*")])
6062 ; subdi3 instruction pattern(s).
6065 (define_expand "subdi3"
6067 [(set (match_operand:DI 0 "register_operand" "")
6068 (minus:DI (match_operand:DI 1 "register_operand" "")
6069 (match_operand:DI 2 "general_operand" "")))
6070 (clobber (reg:CC CC_REGNUM))])]
6074 (define_insn "*subdi3_sign"
6075 [(set (match_operand:DI 0 "register_operand" "=d,d")
6076 (minus:DI (match_operand:DI 1 "register_operand" "0,0")
6077 (sign_extend:DI (match_operand:SI 2 "general_operand" "d,T"))))
6078 (clobber (reg:CC CC_REGNUM))]
6083 [(set_attr "op_type" "RRE,RXY")
6084 (set_attr "z10prop" "z10_c,*")
6085 (set_attr "z196prop" "z196_cracked")])
6087 (define_insn "*subdi3_zero_cc"
6088 [(set (reg CC_REGNUM)
6089 (compare (minus:DI (match_operand:DI 1 "register_operand" "0,0")
6090 (zero_extend:DI (match_operand:SI 2 "general_operand" "d,T")))
6092 (set (match_operand:DI 0 "register_operand" "=d,d")
6093 (minus:DI (match_dup 1) (zero_extend:DI (match_dup 2))))]
6094 "s390_match_ccmode (insn, CCLmode) && TARGET_ZARCH"
6098 [(set_attr "op_type" "RRE,RXY")
6099 (set_attr "z10prop" "z10_super_c_E1,z10_super_E1")])
6101 (define_insn "*subdi3_zero_cconly"
6102 [(set (reg CC_REGNUM)
6103 (compare (minus:DI (match_operand:DI 1 "register_operand" "0,0")
6104 (zero_extend:DI (match_operand:SI 2 "general_operand" "d,T")))
6106 (clobber (match_scratch:DI 0 "=d,d"))]
6107 "s390_match_ccmode (insn, CCLmode) && TARGET_ZARCH"
6111 [(set_attr "op_type" "RRE,RXY")
6112 (set_attr "z10prop" "z10_super_c_E1,z10_super_E1")])
6114 (define_insn "*subdi3_zero"
6115 [(set (match_operand:DI 0 "register_operand" "=d,d")
6116 (minus:DI (match_operand:DI 1 "register_operand" "0,0")
6117 (zero_extend:DI (match_operand:SI 2 "general_operand" "d,T"))))
6118 (clobber (reg:CC CC_REGNUM))]
6123 [(set_attr "op_type" "RRE,RXY")
6124 (set_attr "z10prop" "z10_super_c_E1,z10_super_E1")])
6126 (define_insn_and_split "*subdi3_31z"
6127 [(set (match_operand:DI 0 "register_operand" "=&d")
6128 (minus:DI (match_operand:DI 1 "register_operand" "0")
6129 (match_operand:DI 2 "general_operand" "do") ) )
6130 (clobber (reg:CC CC_REGNUM))]
6133 "&& reload_completed"
6135 [(set (reg:CCL2 CC_REGNUM)
6136 (compare:CCL2 (minus:SI (match_dup 7) (match_dup 8))
6138 (set (match_dup 6) (minus:SI (match_dup 7) (match_dup 8)))])
6140 [(set (match_dup 3) (minus:SI (minus:SI (match_dup 4) (match_dup 5))
6141 (gtu:SI (reg:CCL2 CC_REGNUM) (const_int 0))))
6142 (clobber (reg:CC CC_REGNUM))])]
6143 "operands[3] = operand_subword (operands[0], 0, 0, DImode);
6144 operands[4] = operand_subword (operands[1], 0, 0, DImode);
6145 operands[5] = operand_subword (operands[2], 0, 0, DImode);
6146 operands[6] = operand_subword (operands[0], 1, 0, DImode);
6147 operands[7] = operand_subword (operands[1], 1, 0, DImode);
6148 operands[8] = operand_subword (operands[2], 1, 0, DImode);")
6151 ; subsi3 instruction pattern(s).
6154 (define_expand "subsi3"
6156 [(set (match_operand:SI 0 "register_operand" "")
6157 (minus:SI (match_operand:SI 1 "register_operand" "")
6158 (match_operand:SI 2 "general_operand" "")))
6159 (clobber (reg:CC CC_REGNUM))])]
6163 (define_insn "*subsi3_sign"
6164 [(set (match_operand:SI 0 "register_operand" "=d,d")
6165 (minus:SI (match_operand:SI 1 "register_operand" "0,0")
6166 (sign_extend:SI (match_operand:HI 2 "memory_operand" "R,T"))))
6167 (clobber (reg:CC CC_REGNUM))]
6172 [(set_attr "op_type" "RX,RXY")
6173 (set_attr "cpu_facility" "*,longdisp")
6174 (set_attr "z196prop" "z196_cracked,z196_cracked")])
6177 ; sub(di|si)3 instruction pattern(s).
6180 ; sr, s, sy, sgr, sg, srk, sgrk
6181 (define_insn "*sub<mode>3"
6182 [(set (match_operand:GPR 0 "register_operand" "=d,d,d,d")
6183 (minus:GPR (match_operand:GPR 1 "register_operand" "0,d,0,0")
6184 (match_operand:GPR 2 "general_operand" "d,d,R,T") ) )
6185 (clobber (reg:CC CC_REGNUM))]
6192 [(set_attr "op_type" "RR<E>,RRF,RX<Y>,RXY")
6193 (set_attr "cpu_facility" "*,z196,*,longdisp")
6194 (set_attr "z10prop" "z10_super_c_E1,*,z10_super_E1,z10_super_E1")])
6196 ; slr, sl, sly, slgr, slg, slrk, slgrk
6197 (define_insn "*sub<mode>3_borrow_cc"
6198 [(set (reg CC_REGNUM)
6199 (compare (minus:GPR (match_operand:GPR 1 "register_operand" "0,d,0,0")
6200 (match_operand:GPR 2 "general_operand" "d,d,R,T"))
6202 (set (match_operand:GPR 0 "register_operand" "=d,d,d,d")
6203 (minus:GPR (match_dup 1) (match_dup 2)))]
6204 "s390_match_ccmode (insn, CCL2mode)"
6210 [(set_attr "op_type" "RR<E>,RRF,RX<Y>,RXY")
6211 (set_attr "cpu_facility" "*,z196,*,longdisp")
6212 (set_attr "z10prop" "z10_super_c_E1,*,z10_super_E1,z10_super_E1")])
6214 ; slr, sl, sly, slgr, slg, slrk, slgrk
6215 (define_insn "*sub<mode>3_borrow_cconly"
6216 [(set (reg CC_REGNUM)
6217 (compare (minus:GPR (match_operand:GPR 1 "register_operand" "0,d,0,0")
6218 (match_operand:GPR 2 "general_operand" "d,d,R,T"))
6220 (clobber (match_scratch:GPR 0 "=d,d,d,d"))]
6221 "s390_match_ccmode (insn, CCL2mode)"
6227 [(set_attr "op_type" "RR<E>,RRF,RX<Y>,RXY")
6228 (set_attr "cpu_facility" "*,z196,*,longdisp")
6229 (set_attr "z10prop" "z10_super_c_E1,*,z10_super_E1,z10_super_E1")])
6231 ; slr, sl, sly, slgr, slg, slrk, slgrk
6232 (define_insn "*sub<mode>3_cc"
6233 [(set (reg CC_REGNUM)
6234 (compare (minus:GPR (match_operand:GPR 1 "register_operand" "0,d,0,0")
6235 (match_operand:GPR 2 "general_operand" "d,d,R,T"))
6237 (set (match_operand:GPR 0 "register_operand" "=d,d,d,d")
6238 (minus:GPR (match_dup 1) (match_dup 2)))]
6239 "s390_match_ccmode (insn, CCLmode)"
6245 [(set_attr "op_type" "RR<E>,RRF,RX<Y>,RXY")
6246 (set_attr "cpu_facility" "*,z196,*,longdisp")
6247 (set_attr "z10prop" "z10_super_c_E1,*,z10_super_E1,z10_super_E1")])
6249 ; slr, sl, sly, slgr, slg, slrk, slgrk
6250 (define_insn "*sub<mode>3_cc2"
6251 [(set (reg CC_REGNUM)
6252 (compare (match_operand:GPR 1 "register_operand" "0,d,0,0")
6253 (match_operand:GPR 2 "general_operand" "d,d,R,T")))
6254 (set (match_operand:GPR 0 "register_operand" "=d,d,d,d")
6255 (minus:GPR (match_dup 1) (match_dup 2)))]
6256 "s390_match_ccmode (insn, CCL3mode)"
6262 [(set_attr "op_type" "RR<E>,RRF,RX<Y>,RXY")
6263 (set_attr "cpu_facility" "*,z196,*,longdisp")
6264 (set_attr "z10prop" "z10_super_c_E1,*,z10_super_E1,z10_super_E1")])
6266 ; slr, sl, sly, slgr, slg, slrk, slgrk
6267 (define_insn "*sub<mode>3_cconly"
6268 [(set (reg CC_REGNUM)
6269 (compare (minus:GPR (match_operand:GPR 1 "register_operand" "0,d,0,0")
6270 (match_operand:GPR 2 "general_operand" "d,d,R,T"))
6272 (clobber (match_scratch:GPR 0 "=d,d,d,d"))]
6273 "s390_match_ccmode (insn, CCLmode)"
6279 [(set_attr "op_type" "RR<E>,RRF,RX<Y>,RXY")
6280 (set_attr "cpu_facility" "*,z196,*,longdisp")
6281 (set_attr "z10prop" "z10_super_c_E1,*,z10_super_E1,z10_super_E1")])
6284 ; slr, sl, sly, slgr, slg, slrk, slgrk
6285 (define_insn "*sub<mode>3_cconly2"
6286 [(set (reg CC_REGNUM)
6287 (compare (match_operand:GPR 1 "register_operand" "0,d,0,0")
6288 (match_operand:GPR 2 "general_operand" "d,d,R,T")))
6289 (clobber (match_scratch:GPR 0 "=d,d,d,d"))]
6290 "s390_match_ccmode (insn, CCL3mode)"
6296 [(set_attr "op_type" "RR<E>,RRF,RX<Y>,RXY")
6297 (set_attr "cpu_facility" "*,z196,*,longdisp")
6298 (set_attr "z10prop" "z10_super_c_E1,*,z10_super_E1,z10_super_E1")])
6300 (define_insn "*subdi3_sign"
6301 [(set (match_operand:DI 0 "register_operand" "=d")
6302 (minus:DI (match_operand:DI 1 "register_operand" "0")
6303 (sign_extend:DI (match_operand:HI 2 "memory_operand" "T"))))
6304 (clobber (reg:CC CC_REGNUM))]
6307 [(set_attr "op_type" "RXY")])
6311 ; sub(tf|df|sf|td|dd)3 instruction pattern(s).
6314 ; FIXME: (clobber (match_scratch:CC 3 "=c,c,c,X,X")) does not work - why?
6315 ; sxbr, sdbr, sebr, sdb, seb, sxtr, sdtr
6316 (define_insn "sub<mode>3"
6317 [(set (match_operand:FP 0 "register_operand" "=f,f,f,v,v")
6318 (minus:FP (match_operand:FP 1 "register_operand" "f,0,0,v,v")
6319 (match_operand:FP 2 "general_operand" "f,f,R,v,v")))
6320 (clobber (reg:CC CC_REGNUM))]
6328 [(set_attr "op_type" "RRF,RRE,RXE,VRR,VRR")
6329 (set_attr "type" "fsimp<mode>")
6330 (set_attr "cpu_facility" "*,*,*,vx,vxe")
6331 (set_attr "enabled" "<nBFP>,<nDFP>,<DSF>,<DF>,<SF>")])
6333 ; sxbr, sdbr, sebr, sdb, seb, sxtr, sdtr
6334 (define_insn "*sub<mode>3_cc"
6335 [(set (reg CC_REGNUM)
6336 (compare (minus:FP (match_operand:FP 1 "nonimmediate_operand" "f,0,0")
6337 (match_operand:FP 2 "general_operand" "f,f,R"))
6338 (match_operand:FP 3 "const0_operand" "")))
6339 (set (match_operand:FP 0 "register_operand" "=f,f,f")
6340 (minus:FP (match_dup 1) (match_dup 2)))]
6341 "s390_match_ccmode (insn, CCSmode) && TARGET_HARD_FLOAT"
6346 [(set_attr "op_type" "RRF,RRE,RXE")
6347 (set_attr "type" "fsimp<mode>")
6348 (set_attr "enabled" "<nBFP>,<nDFP>,<DSF>")])
6350 ; sxbr, sdbr, sebr, sdb, seb, sxtr, sdtr
6351 (define_insn "*sub<mode>3_cconly"
6352 [(set (reg CC_REGNUM)
6353 (compare (minus:FP (match_operand:FP 1 "nonimmediate_operand" "f,0,0")
6354 (match_operand:FP 2 "general_operand" "f,f,R"))
6355 (match_operand:FP 3 "const0_operand" "")))
6356 (clobber (match_scratch:FP 0 "=f,f,f"))]
6357 "s390_match_ccmode (insn, CCSmode) && TARGET_HARD_FLOAT"
6362 [(set_attr "op_type" "RRF,RRE,RXE")
6363 (set_attr "type" "fsimp<mode>")
6364 (set_attr "enabled" "<nBFP>,<nDFP>,<DSF>")])
6368 ;;- Conditional add/subtract instructions.
6372 ; add(di|si)cc instruction pattern(s).
6375 ; the following 4 patterns are used when the result of an add with
6376 ; carry is checked for an overflow condition
6378 ; op1 + op2 + c < op1
6380 ; alcr, alc, alcgr, alcg
6381 (define_insn "*add<mode>3_alc_carry1_cc"
6382 [(set (reg CC_REGNUM)
6384 (plus:GPR (plus:GPR (match_operand:GPR 3 "s390_alc_comparison" "")
6385 (match_operand:GPR 1 "nonimmediate_operand" "%0,0"))
6386 (match_operand:GPR 2 "general_operand" "d,T"))
6388 (set (match_operand:GPR 0 "register_operand" "=d,d")
6389 (plus:GPR (plus:GPR (match_dup 3) (match_dup 1)) (match_dup 2)))]
6390 "s390_match_ccmode (insn, CCL1mode)"
6394 [(set_attr "op_type" "RRE,RXY")
6395 (set_attr "z196prop" "z196_alone,z196_alone")])
6397 ; alcr, alc, alcgr, alcg
6398 (define_insn "*add<mode>3_alc_carry1_cconly"
6399 [(set (reg CC_REGNUM)
6401 (plus:GPR (plus:GPR (match_operand:GPR 3 "s390_alc_comparison" "")
6402 (match_operand:GPR 1 "nonimmediate_operand" "%0,0"))
6403 (match_operand:GPR 2 "general_operand" "d,T"))
6405 (clobber (match_scratch:GPR 0 "=d,d"))]
6406 "s390_match_ccmode (insn, CCL1mode)"
6410 [(set_attr "op_type" "RRE,RXY")
6411 (set_attr "z196prop" "z196_alone,z196_alone")])
6413 ; op1 + op2 + c < op2
6415 ; alcr, alc, alcgr, alcg
6416 (define_insn "*add<mode>3_alc_carry2_cc"
6417 [(set (reg CC_REGNUM)
6419 (plus:GPR (plus:GPR (match_operand:GPR 3 "s390_alc_comparison" "")
6420 (match_operand:GPR 1 "nonimmediate_operand" "%0,0"))
6421 (match_operand:GPR 2 "general_operand" "d,T"))
6423 (set (match_operand:GPR 0 "register_operand" "=d,d")
6424 (plus:GPR (plus:GPR (match_dup 3) (match_dup 1)) (match_dup 2)))]
6425 "s390_match_ccmode (insn, CCL1mode)"
6429 [(set_attr "op_type" "RRE,RXY")])
6431 ; alcr, alc, alcgr, alcg
6432 (define_insn "*add<mode>3_alc_carry2_cconly"
6433 [(set (reg CC_REGNUM)
6435 (plus:GPR (plus:GPR (match_operand:GPR 3 "s390_alc_comparison" "")
6436 (match_operand:GPR 1 "nonimmediate_operand" "%0,0"))
6437 (match_operand:GPR 2 "general_operand" "d,T"))
6439 (clobber (match_scratch:GPR 0 "=d,d"))]
6440 "s390_match_ccmode (insn, CCL1mode)"
6444 [(set_attr "op_type" "RRE,RXY")])
6446 ; alcr, alc, alcgr, alcg
6447 (define_insn "*add<mode>3_alc_cc"
6448 [(set (reg CC_REGNUM)
6450 (plus:GPR (plus:GPR (match_operand:GPR 3 "s390_alc_comparison" "")
6451 (match_operand:GPR 1 "nonimmediate_operand" "%0,0"))
6452 (match_operand:GPR 2 "general_operand" "d,T"))
6454 (set (match_operand:GPR 0 "register_operand" "=d,d")
6455 (plus:GPR (plus:GPR (match_dup 3) (match_dup 1)) (match_dup 2)))]
6456 "s390_match_ccmode (insn, CCLmode)"
6460 [(set_attr "op_type" "RRE,RXY")])
6462 ; alcr, alc, alcgr, alcg
6463 (define_insn "*add<mode>3_alc"
6464 [(set (match_operand:GPR 0 "register_operand" "=d,d")
6465 (plus:GPR (plus:GPR (match_operand:GPR 3 "s390_alc_comparison" "")
6466 (match_operand:GPR 1 "nonimmediate_operand" "%0,0"))
6467 (match_operand:GPR 2 "general_operand" "d,T")))
6468 (clobber (reg:CC CC_REGNUM))]
6473 [(set_attr "op_type" "RRE,RXY")])
6475 ; slbr, slb, slbgr, slbg
6476 (define_insn "*sub<mode>3_slb_cc"
6477 [(set (reg CC_REGNUM)
6479 (minus:GPR (minus:GPR (match_operand:GPR 1 "nonimmediate_operand" "0,0")
6480 (match_operand:GPR 2 "general_operand" "d,T"))
6481 (match_operand:GPR 3 "s390_slb_comparison" ""))
6483 (set (match_operand:GPR 0 "register_operand" "=d,d")
6484 (minus:GPR (minus:GPR (match_dup 1) (match_dup 2)) (match_dup 3)))]
6485 "s390_match_ccmode (insn, CCLmode)"
6489 [(set_attr "op_type" "RRE,RXY")
6490 (set_attr "z10prop" "z10_c,*")])
6492 ; slbr, slb, slbgr, slbg
6493 (define_insn "*sub<mode>3_slb"
6494 [(set (match_operand:GPR 0 "register_operand" "=d,d")
6495 (minus:GPR (minus:GPR (match_operand:GPR 1 "nonimmediate_operand" "0,0")
6496 (match_operand:GPR 2 "general_operand" "d,T"))
6497 (match_operand:GPR 3 "s390_slb_comparison" "")))
6498 (clobber (reg:CC CC_REGNUM))]
6503 [(set_attr "op_type" "RRE,RXY")
6504 (set_attr "z10prop" "z10_c,*")])
6506 (define_expand "add<mode>cc"
6507 [(match_operand:GPR 0 "register_operand" "")
6508 (match_operand 1 "comparison_operator" "")
6509 (match_operand:GPR 2 "register_operand" "")
6510 (match_operand:GPR 3 "const_int_operand" "")]
6512 "if (!s390_expand_addcc (GET_CODE (operands[1]),
6513 XEXP (operands[1], 0), XEXP (operands[1], 1),
6514 operands[0], operands[2],
6515 operands[3])) FAIL; DONE;")
6518 ; scond instruction pattern(s).
6521 (define_insn_and_split "*scond<mode>"
6522 [(set (match_operand:GPR 0 "register_operand" "=&d")
6523 (match_operand:GPR 1 "s390_alc_comparison" ""))
6524 (clobber (reg:CC CC_REGNUM))]
6527 "&& reload_completed"
6528 [(set (match_dup 0) (const_int 0))
6530 [(set (match_dup 0) (plus:GPR (plus:GPR (match_dup 1) (match_dup 0))
6532 (clobber (reg:CC CC_REGNUM))])]
6535 (define_insn_and_split "*scond<mode>_neg"
6536 [(set (match_operand:GPR 0 "register_operand" "=&d")
6537 (match_operand:GPR 1 "s390_slb_comparison" ""))
6538 (clobber (reg:CC CC_REGNUM))]
6541 "&& reload_completed"
6542 [(set (match_dup 0) (const_int 0))
6544 [(set (match_dup 0) (minus:GPR (minus:GPR (match_dup 0) (match_dup 0))
6546 (clobber (reg:CC CC_REGNUM))])
6548 [(set (match_dup 0) (neg:GPR (match_dup 0)))
6549 (clobber (reg:CC CC_REGNUM))])]
6553 (define_expand "cstore<mode>4"
6554 [(set (match_operand:SI 0 "register_operand" "")
6555 (match_operator:SI 1 "s390_scond_operator"
6556 [(match_operand:GPR 2 "register_operand" "")
6557 (match_operand:GPR 3 "general_operand" "")]))]
6559 "if (!s390_expand_addcc (GET_CODE (operands[1]), operands[2], operands[3],
6560 operands[0], const0_rtx, const1_rtx)) FAIL; DONE;")
6562 (define_expand "cstorecc4"
6564 [(set (match_operand:SI 0 "register_operand" "")
6565 (match_operator:SI 1 "s390_eqne_operator"
6566 [(match_operand 2 "cc_reg_operand")
6567 (match_operand 3 "const0_operand")]))
6568 (clobber (reg:CC CC_REGNUM))])]
6570 "machine_mode mode = GET_MODE (operands[2]);
6575 if (GET_CODE (operands[1]) == NE)
6576 cond = gen_rtx_NE (VOIDmode, operands[2], const0_rtx);
6578 cond = gen_rtx_EQ (VOIDmode, operands[2], const0_rtx);
6579 ite = gen_rtx_IF_THEN_ELSE (SImode, cond, const1_rtx, const0_rtx);
6580 emit_insn (gen_rtx_SET (operands[0], ite));
6584 if (mode != CCZ1mode)
6586 emit_insn (gen_sne (operands[0], operands[2]));
6587 if (GET_CODE (operands[1]) == EQ)
6588 emit_insn (gen_xorsi3 (operands[0], operands[0], const1_rtx));
6592 (define_insn_and_split "sne"
6593 [(set (match_operand:SI 0 "register_operand" "=d")
6594 (ne:SI (match_operand:CCZ1 1 "register_operand" "0")
6596 (clobber (reg:CC CC_REGNUM))]
6601 [(set (match_dup 0) (ashiftrt:SI (match_dup 0) (const_int 28)))
6602 (clobber (reg:CC CC_REGNUM))])])
6606 ;; - Conditional move instructions (introduced with z196)
6609 (define_expand "mov<mode>cc"
6610 [(set (match_operand:GPR 0 "nonimmediate_operand" "")
6611 (if_then_else:GPR (match_operand 1 "comparison_operator" "")
6612 (match_operand:GPR 2 "loc_operand" "")
6613 (match_operand:GPR 3 "loc_operand" "")))]
6616 if (!TARGET_Z13 && CONSTANT_P (operands[2]))
6617 operands[2] = force_reg (<MODE>mode, operands[2]);
6619 if (!TARGET_Z13 && CONSTANT_P (operands[3]))
6620 operands[3] = force_reg (<MODE>mode, operands[3]);
6622 /* Emit the comparison insn in case we do not already have a comparison result. */
6623 if (!s390_comparison (operands[1], VOIDmode))
6624 operands[1] = s390_emit_compare (GET_CODE (operands[1]),
6625 XEXP (operands[1], 0),
6626 XEXP (operands[1], 1));
6630 ;; - We do not have instructions for QImode or HImode but still
6631 ;; enable load on condition/if conversion for them.
6632 (define_expand "mov<mode>cc"
6633 [(set (match_operand:HQI 0 "nonimmediate_operand" "")
6634 (if_then_else:HQI (match_operand 1 "comparison_operator" "")
6635 (match_operand:HQI 2 "loc_operand" "")
6636 (match_operand:HQI 3 "loc_operand" "")))]
6639 /* Emit the comparison insn in case we do not already have a comparison
6641 if (!s390_comparison (operands[1], VOIDmode))
6642 operands[1] = s390_emit_compare (GET_CODE (operands[1]),
6643 XEXP (operands[1], 0),
6644 XEXP (operands[1], 1));
6646 rtx then = operands[2];
6647 rtx els = operands[3];
6649 if ((!TARGET_Z13 && CONSTANT_P (then)) || MEM_P (then))
6650 then = force_reg (<MODE>mode, then);
6651 if ((!TARGET_Z13 && CONSTANT_P (els)) || MEM_P (els))
6652 els = force_reg (<MODE>mode, els);
6654 if (!CONSTANT_P (then))
6655 then = simplify_gen_subreg (E_SImode, then, <MODE>mode, 0);
6656 if (!CONSTANT_P (els))
6657 els = simplify_gen_subreg (E_SImode, els, <MODE>mode, 0);
6659 rtx tmp_target = gen_reg_rtx (E_SImode);
6660 emit_insn (gen_movsicc (tmp_target, operands[1], then, els));
6661 emit_move_insn (operands[0], gen_lowpart (<MODE>mode, tmp_target));
6667 ; locr, loc, stoc, locgr, locg, stocg, lochi, locghi
6668 (define_insn "*mov<mode>cc"
6669 [(set (match_operand:GPR 0 "nonimmediate_operand" "=d,d,d,d,d,d,S,S")
6671 (match_operator 1 "s390_comparison"
6672 [(match_operand 2 "cc_reg_operand" " c,c,c,c,c,c,c,c")
6673 (match_operand 5 "const_int_operand" "")])
6674 (match_operand:GPR 3 "loc_operand" " d,0,S,0,K,0,d,0")
6675 (match_operand:GPR 4 "loc_operand" " 0,d,0,S,0,K,0,d")))]
6686 [(set_attr "op_type" "RRF,RRF,RSY,RSY,RIE,RIE,RSY,RSY")
6687 (set_attr "cpu_facility" "*,*,*,*,z13,z13,*,*")])
6690 ;;- Multiply instructions.
6694 ; muldi3 instruction pattern(s).
6697 (define_expand "muldi3"
6699 [(set (match_operand:DI 0 "register_operand")
6700 (mult:DI (match_operand:DI 1 "nonimmediate_operand")
6701 (match_operand:DI 2 "general_operand")))
6702 (clobber (reg:CC CC_REGNUM))])]
6705 (define_insn "*muldi3_sign"
6706 [(set (match_operand:DI 0 "register_operand" "=d,d")
6707 (mult:DI (sign_extend:DI (match_operand:SI 2 "general_operand" "d,T"))
6708 (match_operand:DI 1 "register_operand" "0,0")))]
6713 [(set_attr "op_type" "RRE,RXY")
6714 (set_attr "type" "imuldi")])
6716 (define_insn "*muldi3"
6717 [(set (match_operand:DI 0 "register_operand" "=d,d,d,d,d")
6718 (mult:DI (match_operand:DI 1 "nonimmediate_operand" "%0,d,0,0,0")
6719 (match_operand:DI 2 "general_operand" "d,d,K,T,Os")))
6720 (clobber (match_scratch:CC 3 "=X,c,X,X,X"))]
6728 [(set_attr "op_type" "RRE,RRF,RI,RXY,RIL")
6729 (set_attr "type" "imuldi")
6730 (set_attr "cpu_facility" "*,z14,*,*,z10")])
6732 (define_insn "mulditi3"
6733 [(set (match_operand:TI 0 "register_operand" "=d,d")
6734 (mult:TI (sign_extend:TI
6735 (match_operand:DI 1 "register_operand" "%d,0"))
6737 (match_operand:DI 2 "nonimmediate_operand" " d,T"))))]
6742 [(set_attr "op_type" "RRF,RXY")])
6744 ; Combine likes op1 and op2 to be swapped sometimes.
6745 (define_insn "mulditi3_2"
6746 [(set (match_operand:TI 0 "register_operand" "=d,d")
6747 (mult:TI (sign_extend:TI
6748 (match_operand:DI 1 "nonimmediate_operand" "%d,T"))
6750 (match_operand:DI 2 "register_operand" " d,0"))))]
6755 [(set_attr "op_type" "RRF,RXY")])
6757 (define_insn "*muldi3_sign"
6758 [(set (match_operand:DI 0 "register_operand" "=d")
6759 (mult:DI (sign_extend:DI (match_operand:HI 2 "memory_operand" "T"))
6760 (match_operand:DI 1 "register_operand" "0")))]
6763 [(set_attr "op_type" "RXY")])
6767 ; mulsi3 instruction pattern(s).
6770 (define_expand "mulsi3"
6772 [(set (match_operand:SI 0 "register_operand" "=d,d,d,d,d,d")
6773 (mult:SI (match_operand:SI 1 "nonimmediate_operand" "%0,d,0,0,0,0")
6774 (match_operand:SI 2 "general_operand" "d,d,K,R,T,Os")))
6775 (clobber (reg:CC CC_REGNUM))])]
6778 (define_insn "*mulsi3_sign"
6779 [(set (match_operand:SI 0 "register_operand" "=d,d")
6780 (mult:SI (sign_extend:SI (match_operand:HI 2 "memory_operand" "R,T"))
6781 (match_operand:SI 1 "register_operand" "0,0")))]
6786 [(set_attr "op_type" "RX,RXY")
6787 (set_attr "type" "imulhi")
6788 (set_attr "cpu_facility" "*,z10")])
6790 (define_insn "*mulsi3"
6791 [(set (match_operand:SI 0 "register_operand" "=d,d,d,d,d,d")
6792 (mult:SI (match_operand:SI 1 "nonimmediate_operand" "%0,d,0,0,0,0")
6793 (match_operand:SI 2 "general_operand" "d,d,K,R,T,Os")))
6794 (clobber (match_scratch:CC 3 "=X,c,X,X,X,X"))]
6803 [(set_attr "op_type" "RRE,RRF,RI,RX,RXY,RIL")
6804 (set_attr "type" "imulsi,*,imulhi,imulsi,imulsi,imulsi")
6805 (set_attr "cpu_facility" "*,z14,*,*,longdisp,z10")])
6808 ; mulsidi3 instruction pattern(s).
6811 (define_insn "mulsidi3"
6812 [(set (match_operand:DI 0 "register_operand" "=d,d,d")
6813 (mult:DI (sign_extend:DI
6814 (match_operand:SI 1 "register_operand" "%0,0,0"))
6816 (match_operand:SI 2 "nonimmediate_operand" "d,R,T"))))]
6822 [(set_attr "op_type" "RR,RX,RXY")
6823 (set_attr "type" "imulsi")
6824 (set_attr "cpu_facility" "*,*,z10")])
6827 ; umul instruction pattern(s).
6830 ; mlr, ml, mlgr, mlg
6831 (define_insn "umul<dwh><mode>3"
6832 [(set (match_operand:DW 0 "register_operand" "=d,d")
6833 (mult:DW (zero_extend:DW
6834 (match_operand:<DWH> 1 "register_operand" "%0,0"))
6836 (match_operand:<DWH> 2 "nonimmediate_operand" " d,T"))))]
6841 [(set_attr "op_type" "RRE,RXY")
6842 (set_attr "type" "imul<dwh>")])
6845 ; mul(tf|df|sf|td|dd)3 instruction pattern(s).
6848 ; mxbr, mdbr, meebr, mxb, mxb, meeb, mdtr, mxtr
6849 (define_insn "mul<mode>3"
6850 [(set (match_operand:FP 0 "register_operand" "=f,f,f,v,v")
6851 (mult:FP (match_operand:FP 1 "nonimmediate_operand" "%f,0,0,v,v")
6852 (match_operand:FP 2 "general_operand" "f,f,R,v,v")))]
6860 [(set_attr "op_type" "RRF,RRE,RXE,VRR,VRR")
6861 (set_attr "type" "fmul<mode>")
6862 (set_attr "cpu_facility" "*,*,*,vx,vxe")
6863 (set_attr "enabled" "<nBFP>,<nDFP>,<DSF>,<DF>,<SF>")])
6865 ; madbr, maebr, maxb, madb, maeb
6866 (define_insn "fma<mode>4"
6867 [(set (match_operand:DSF 0 "register_operand" "=f,f,v,v")
6868 (fma:DSF (match_operand:DSF 1 "nonimmediate_operand" "%f,f,v,v")
6869 (match_operand:DSF 2 "nonimmediate_operand" "f,R,v,v")
6870 (match_operand:DSF 3 "register_operand" "0,0,v,v")))]
6875 wfmadb\t%v0,%v1,%v2,%v3
6876 wfmasb\t%v0,%v1,%v2,%v3"
6877 [(set_attr "op_type" "RRE,RXE,VRR,VRR")
6878 (set_attr "type" "fmadd<mode>")
6879 (set_attr "cpu_facility" "*,*,vx,vxe")
6880 (set_attr "enabled" "*,*,<DF>,<SF>")])
6882 ; msxbr, msdbr, msebr, msxb, msdb, mseb
6883 (define_insn "fms<mode>4"
6884 [(set (match_operand:DSF 0 "register_operand" "=f,f,v,v")
6885 (fma:DSF (match_operand:DSF 1 "nonimmediate_operand" "%f,f,v,v")
6886 (match_operand:DSF 2 "nonimmediate_operand" "f,R,v,v")
6887 (neg:DSF (match_operand:DSF 3 "register_operand" "0,0,v,v"))))]
6892 wfmsdb\t%v0,%v1,%v2,%v3
6893 wfmssb\t%v0,%v1,%v2,%v3"
6894 [(set_attr "op_type" "RRE,RXE,VRR,VRR")
6895 (set_attr "type" "fmadd<mode>")
6896 (set_attr "cpu_facility" "*,*,vx,vxe")
6897 (set_attr "enabled" "*,*,<DF>,<SF>")])
6900 ;;- Divide and modulo instructions.
6904 ; divmoddi4 instruction pattern(s).
6907 (define_expand "divmoddi4"
6908 [(parallel [(set (match_operand:DI 0 "general_operand" "")
6909 (div:DI (match_operand:DI 1 "register_operand" "")
6910 (match_operand:DI 2 "general_operand" "")))
6911 (set (match_operand:DI 3 "general_operand" "")
6912 (mod:DI (match_dup 1) (match_dup 2)))])
6913 (clobber (match_dup 4))]
6916 rtx div_equal, mod_equal;
6919 div_equal = gen_rtx_DIV (DImode, operands[1], operands[2]);
6920 mod_equal = gen_rtx_MOD (DImode, operands[1], operands[2]);
6922 operands[4] = gen_reg_rtx(TImode);
6923 emit_insn (gen_divmodtidi3 (operands[4], operands[1], operands[2]));
6925 insn = emit_move_insn (operands[0], gen_lowpart (DImode, operands[4]));
6926 set_unique_reg_note (insn, REG_EQUAL, div_equal);
6928 insn = emit_move_insn (operands[3], gen_highpart (DImode, operands[4]));
6929 set_unique_reg_note (insn, REG_EQUAL, mod_equal);
6934 (define_insn "divmodtidi3"
6935 [(set (match_operand:TI 0 "register_operand" "=d,d")
6939 (mod:DI (match_operand:DI 1 "register_operand" "0,0")
6940 (match_operand:DI 2 "general_operand" "d,T")))
6942 (zero_extend:TI (div:DI (match_dup 1) (match_dup 2)))))]
6947 [(set_attr "op_type" "RRE,RXY")
6948 (set_attr "type" "idiv")])
6950 (define_insn "divmodtisi3"
6951 [(set (match_operand:TI 0 "register_operand" "=d,d")
6955 (mod:DI (match_operand:DI 1 "register_operand" "0,0")
6957 (match_operand:SI 2 "nonimmediate_operand" "d,T"))))
6960 (div:DI (match_dup 1) (sign_extend:DI (match_dup 2))))))]
6965 [(set_attr "op_type" "RRE,RXY")
6966 (set_attr "type" "idiv")])
6969 ; udivmoddi4 instruction pattern(s).
6972 (define_expand "udivmoddi4"
6973 [(parallel [(set (match_operand:DI 0 "general_operand" "")
6974 (udiv:DI (match_operand:DI 1 "general_operand" "")
6975 (match_operand:DI 2 "nonimmediate_operand" "")))
6976 (set (match_operand:DI 3 "general_operand" "")
6977 (umod:DI (match_dup 1) (match_dup 2)))])
6978 (clobber (match_dup 4))]
6981 rtx div_equal, mod_equal, equal;
6984 div_equal = gen_rtx_UDIV (DImode, operands[1], operands[2]);
6985 mod_equal = gen_rtx_UMOD (DImode, operands[1], operands[2]);
6986 equal = gen_rtx_IOR (TImode,
6987 gen_rtx_ASHIFT (TImode,
6988 gen_rtx_ZERO_EXTEND (TImode, mod_equal),
6990 gen_rtx_ZERO_EXTEND (TImode, div_equal));
6992 operands[4] = gen_reg_rtx(TImode);
6993 emit_clobber (operands[4]);
6994 emit_move_insn (gen_lowpart (DImode, operands[4]), operands[1]);
6995 emit_move_insn (gen_highpart (DImode, operands[4]), const0_rtx);
6997 insn = emit_insn (gen_udivmodtidi3 (operands[4], operands[4], operands[2]));
6998 set_unique_reg_note (insn, REG_EQUAL, equal);
7000 insn = emit_move_insn (operands[0], gen_lowpart (DImode, operands[4]));
7001 set_unique_reg_note (insn, REG_EQUAL, div_equal);
7003 insn = emit_move_insn (operands[3], gen_highpart (DImode, operands[4]));
7004 set_unique_reg_note (insn, REG_EQUAL, mod_equal);
7009 (define_insn "udivmodtidi3"
7010 [(set (match_operand:TI 0 "register_operand" "=d,d")
7015 (umod:TI (match_operand:TI 1 "register_operand" "0,0")
7017 (match_operand:DI 2 "nonimmediate_operand" "d,T")))))
7021 (udiv:TI (match_dup 1) (zero_extend:TI (match_dup 2)))))))]
7026 [(set_attr "op_type" "RRE,RXY")
7027 (set_attr "type" "idiv")])
7030 ; divmodsi4 instruction pattern(s).
7033 (define_expand "divmodsi4"
7034 [(parallel [(set (match_operand:SI 0 "general_operand" "")
7035 (div:SI (match_operand:SI 1 "general_operand" "")
7036 (match_operand:SI 2 "nonimmediate_operand" "")))
7037 (set (match_operand:SI 3 "general_operand" "")
7038 (mod:SI (match_dup 1) (match_dup 2)))])
7039 (clobber (match_dup 4))]
7042 rtx div_equal, mod_equal, equal;
7045 div_equal = gen_rtx_DIV (SImode, operands[1], operands[2]);
7046 mod_equal = gen_rtx_MOD (SImode, operands[1], operands[2]);
7047 equal = gen_rtx_IOR (DImode,
7048 gen_rtx_ASHIFT (DImode,
7049 gen_rtx_ZERO_EXTEND (DImode, mod_equal),
7051 gen_rtx_ZERO_EXTEND (DImode, div_equal));
7053 operands[4] = gen_reg_rtx(DImode);
7054 emit_insn (gen_extendsidi2 (operands[4], operands[1]));
7056 insn = emit_insn (gen_divmoddisi3 (operands[4], operands[4], operands[2]));
7057 set_unique_reg_note (insn, REG_EQUAL, equal);
7059 insn = emit_move_insn (operands[0], gen_lowpart (SImode, operands[4]));
7060 set_unique_reg_note (insn, REG_EQUAL, div_equal);
7062 insn = emit_move_insn (operands[3], gen_highpart (SImode, operands[4]));
7063 set_unique_reg_note (insn, REG_EQUAL, mod_equal);
7068 (define_insn "divmoddisi3"
7069 [(set (match_operand:DI 0 "register_operand" "=d,d")
7074 (mod:DI (match_operand:DI 1 "register_operand" "0,0")
7076 (match_operand:SI 2 "nonimmediate_operand" "d,R")))))
7080 (div:DI (match_dup 1) (sign_extend:DI (match_dup 2)))))))]
7085 [(set_attr "op_type" "RR,RX")
7086 (set_attr "type" "idiv")])
7089 ; udivsi3 and umodsi3 instruction pattern(s).
7092 (define_expand "udivmodsi4"
7093 [(parallel [(set (match_operand:SI 0 "general_operand" "")
7094 (udiv:SI (match_operand:SI 1 "general_operand" "")
7095 (match_operand:SI 2 "nonimmediate_operand" "")))
7096 (set (match_operand:SI 3 "general_operand" "")
7097 (umod:SI (match_dup 1) (match_dup 2)))])
7098 (clobber (match_dup 4))]
7101 rtx div_equal, mod_equal, equal;
7104 div_equal = gen_rtx_UDIV (SImode, operands[1], operands[2]);
7105 mod_equal = gen_rtx_UMOD (SImode, operands[1], operands[2]);
7106 equal = gen_rtx_IOR (DImode,
7107 gen_rtx_ASHIFT (DImode,
7108 gen_rtx_ZERO_EXTEND (DImode, mod_equal),
7110 gen_rtx_ZERO_EXTEND (DImode, div_equal));
7112 operands[4] = gen_reg_rtx(DImode);
7113 emit_clobber (operands[4]);
7114 emit_move_insn (gen_lowpart (SImode, operands[4]), operands[1]);
7115 emit_move_insn (gen_highpart (SImode, operands[4]), const0_rtx);
7117 insn = emit_insn (gen_udivmoddisi3 (operands[4], operands[4], operands[2]));
7118 set_unique_reg_note (insn, REG_EQUAL, equal);
7120 insn = emit_move_insn (operands[0], gen_lowpart (SImode, operands[4]));
7121 set_unique_reg_note (insn, REG_EQUAL, div_equal);
7123 insn = emit_move_insn (operands[3], gen_highpart (SImode, operands[4]));
7124 set_unique_reg_note (insn, REG_EQUAL, mod_equal);
7129 (define_insn "udivmoddisi3"
7130 [(set (match_operand:DI 0 "register_operand" "=d,d")
7135 (umod:DI (match_operand:DI 1 "register_operand" "0,0")
7137 (match_operand:SI 2 "nonimmediate_operand" "d,T")))))
7141 (udiv:DI (match_dup 1) (zero_extend:DI (match_dup 2)))))))]
7146 [(set_attr "op_type" "RRE,RXY")
7147 (set_attr "type" "idiv")])
7150 ; div(df|sf)3 instruction pattern(s).
7153 ; dxbr, ddbr, debr, dxb, ddb, deb, ddtr, dxtr
7154 (define_insn "div<mode>3"
7155 [(set (match_operand:FP 0 "register_operand" "=f,f,f,v,v")
7156 (div:FP (match_operand:FP 1 "register_operand" "f,0,0,v,v")
7157 (match_operand:FP 2 "general_operand" "f,f,R,v,v")))]
7165 [(set_attr "op_type" "RRF,RRE,RXE,VRR,VRR")
7166 (set_attr "type" "fdiv<mode>")
7167 (set_attr "cpu_facility" "*,*,*,vx,vxe")
7168 (set_attr "enabled" "<nBFP>,<nDFP>,<DSF>,<DF>,<SF>")])
7172 ;;- And instructions.
7175 (define_expand "and<mode>3"
7176 [(set (match_operand:INT 0 "nonimmediate_operand" "")
7177 (and:INT (match_operand:INT 1 "nonimmediate_operand" "")
7178 (match_operand:INT 2 "general_operand" "")))
7179 (clobber (reg:CC CC_REGNUM))]
7181 "s390_expand_logical_operator (AND, <MODE>mode, operands); DONE;")
7184 ; anddi3 instruction pattern(s).
7187 (define_insn "*anddi3_cc"
7188 [(set (reg CC_REGNUM)
7190 (and:DI (match_operand:DI 1 "nonimmediate_operand" "%0,d,0, d")
7191 (match_operand:DI 2 "general_operand" " d,d,T,NxxDw"))
7193 (set (match_operand:DI 0 "register_operand" "=d,d,d, d")
7194 (and:DI (match_dup 1) (match_dup 2)))]
7195 "TARGET_ZARCH && s390_match_ccmode(insn, CCTmode)"
7200 risbg\t%0,%1,%s2,128+%e2,0"
7201 [(set_attr "op_type" "RRE,RRF,RXY,RIE")
7202 (set_attr "cpu_facility" "*,z196,*,z10")
7203 (set_attr "z10prop" "z10_super_E1,*,z10_super_E1,z10_super_E1")])
7205 (define_insn "*anddi3_cconly"
7206 [(set (reg CC_REGNUM)
7208 (and:DI (match_operand:DI 1 "nonimmediate_operand" "%0,d,0, d")
7209 (match_operand:DI 2 "general_operand" " d,d,T,NxxDw"))
7211 (clobber (match_scratch:DI 0 "=d,d,d, d"))]
7213 && s390_match_ccmode(insn, CCTmode)
7214 /* Do not steal TM patterns. */
7215 && s390_single_part (operands[2], DImode, HImode, 0) < 0"
7220 risbg\t%0,%1,%s2,128+%e2,0"
7221 [(set_attr "op_type" "RRE,RRF,RXY,RIE")
7222 (set_attr "cpu_facility" "*,z196,*,z10")
7223 (set_attr "z10prop" "z10_super_E1,*,z10_super_E1,z10_super_E1")])
7225 (define_insn "*anddi3"
7226 [(set (match_operand:DI 0 "nonimmediate_operand"
7227 "=d,d, d, d, d, d, d, d,d,d,d, d, AQ,Q")
7229 (match_operand:DI 1 "nonimmediate_operand"
7230 "%d,o, 0, 0, 0, 0, 0, 0,0,d,0, d, 0,0")
7231 (match_operand:DI 2 "general_operand"
7232 "M, M,N0HDF,N1HDF,N2HDF,N3HDF,N0SDF,N1SDF,d,d,T,NxxDw,NxQDF,Q")))
7233 (clobber (reg:CC CC_REGNUM))]
7234 "TARGET_ZARCH && s390_logical_operator_ok_p (operands)"
7247 risbg\t%0,%1,%s2,128+%e2,0
7250 [(set_attr "op_type" "RRE,RXE,RI,RI,RI,RI,RIL,RIL,RRE,RRF,RXY,RIE,SI,SS")
7251 (set_attr "cpu_facility" "*,*,*,*,*,*,extimm,extimm,*,z196,*,z10,*,*")
7252 (set_attr "z10prop" "*,
7268 [(set (match_operand:DI 0 "s_operand" "")
7269 (and:DI (match_dup 0) (match_operand:DI 1 "immediate_operand" "")))
7270 (clobber (reg:CC CC_REGNUM))]
7273 [(set (match_dup 0) (and:QI (match_dup 0) (match_dup 1)))
7274 (clobber (reg:CC CC_REGNUM))])]
7275 "s390_narrow_logical_operator (AND, &operands[0], &operands[1]);")
7277 ;; These two are what combine generates for (ashift (zero_extract)).
7278 (define_insn "*extzv_<mode>_srl<clobbercc_or_nocc>"
7279 [(set (match_operand:GPR 0 "register_operand" "=d")
7280 (and:GPR (lshiftrt:GPR
7281 (match_operand:GPR 1 "register_operand" "d")
7282 (match_operand:GPR 2 "nonzero_shift_count_operand" ""))
7283 (match_operand:GPR 3 "contiguous_bitmask_nowrap_operand" "")))]
7284 "<z10_or_zEC12_cond>
7285 /* Note that even for the SImode pattern, the rotate is always DImode. */
7286 && s390_extzv_shift_ok (<bitsize>, -INTVAL (operands[2]),
7287 INTVAL (operands[3]))"
7288 "<risbg_n>\t%0,%1,%<bfstart>3,128+%<bfend>3,64-%2"
7289 [(set_attr "op_type" "RIE")
7290 (set_attr "z10prop" "z10_super_E1")])
7292 (define_insn "*extzv_<mode>_sll<clobbercc_or_nocc>"
7293 [(set (match_operand:GPR 0 "register_operand" "=d")
7294 (and:GPR (ashift:GPR
7295 (match_operand:GPR 1 "register_operand" "d")
7296 (match_operand:GPR 2 "nonzero_shift_count_operand" ""))
7297 (match_operand:GPR 3 "contiguous_bitmask_nowrap_operand" "")))]
7298 "<z10_or_zEC12_cond>
7299 && s390_extzv_shift_ok (<bitsize>, INTVAL (operands[2]),
7300 INTVAL (operands[3]))"
7301 "<risbg_n>\t%0,%1,%<bfstart>3,128+%<bfend>3,%2"
7302 [(set_attr "op_type" "RIE")
7303 (set_attr "z10prop" "z10_super_E1")])
7307 ; andsi3 instruction pattern(s).
7310 (define_insn "*andsi3_cc"
7311 [(set (reg CC_REGNUM)
7314 (match_operand:SI 1 "nonimmediate_operand" "%0,0,d,0,0, d")
7315 (match_operand:SI 2 "general_operand" "Os,d,d,R,T,NxxSq"))
7317 (set (match_operand:SI 0 "register_operand" "=d,d,d,d,d, d")
7318 (and:SI (match_dup 1) (match_dup 2)))]
7319 "s390_match_ccmode(insn, CCTmode)"
7326 risbg\t%0,%1,%t2,128+%f2,0"
7327 [(set_attr "op_type" "RIL,RR,RRF,RX,RXY,RIE")
7328 (set_attr "cpu_facility" "*,*,z196,*,longdisp,z10")
7329 (set_attr "z10prop" "z10_super_E1,z10_super_E1,*,
7330 z10_super_E1,z10_super_E1,z10_super_E1")])
7332 (define_insn "*andsi3_cconly"
7333 [(set (reg CC_REGNUM)
7336 (match_operand:SI 1 "nonimmediate_operand" "%0,0,d,0,0, d")
7337 (match_operand:SI 2 "general_operand" "Os,d,d,R,T,NxxSq"))
7339 (clobber (match_scratch:SI 0 "=d,d,d,d,d, d"))]
7340 "s390_match_ccmode(insn, CCTmode)
7341 /* Do not steal TM patterns. */
7342 && s390_single_part (operands[2], SImode, HImode, 0) < 0"
7349 risbg\t%0,%1,%t2,128+%f2,0"
7350 [(set_attr "op_type" "RIL,RR,RRF,RX,RXY,RIE")
7351 (set_attr "cpu_facility" "*,*,z196,*,longdisp,z10")
7352 (set_attr "z10prop" "z10_super_E1,z10_super_E1,*,
7353 z10_super_E1,z10_super_E1,z10_super_E1")])
7355 (define_insn "*andsi3_zarch"
7356 [(set (match_operand:SI 0 "nonimmediate_operand"
7357 "=d,d, d, d, d,d,d,d,d, d, AQ,Q")
7358 (and:SI (match_operand:SI 1 "nonimmediate_operand"
7359 "%d,o, 0, 0, 0,0,d,0,0, d, 0,0")
7360 (match_operand:SI 2 "general_operand"
7361 " M,M,N0HSF,N1HSF,Os,d,d,R,T,NxxSw,NxQSF,Q")))
7362 (clobber (reg:CC CC_REGNUM))]
7363 "TARGET_ZARCH && s390_logical_operator_ok_p (operands)"
7374 risbg\t%0,%1,%t2,128+%f2,0
7377 [(set_attr "op_type" "RRE,RXE,RI,RI,RIL,RR,RRF,RX,RXY,RIE,SI,SS")
7378 (set_attr "cpu_facility" "*,*,*,*,*,*,z196,*,longdisp,z10,*,*")
7379 (set_attr "z10prop" "*,
7392 (define_insn "*andsi3_esa"
7393 [(set (match_operand:SI 0 "nonimmediate_operand" "=d,d, AQ,Q")
7394 (and:SI (match_operand:SI 1 "nonimmediate_operand" "%0,0, 0,0")
7395 (match_operand:SI 2 "general_operand" " d,R,NxQSF,Q")))
7396 (clobber (reg:CC CC_REGNUM))]
7397 "!TARGET_ZARCH && s390_logical_operator_ok_p (operands)"
7403 [(set_attr "op_type" "RR,RX,SI,SS")
7404 (set_attr "z10prop" "z10_super_E1,z10_super_E1,*,*")])
7408 [(set (match_operand:SI 0 "s_operand" "")
7409 (and:SI (match_dup 0) (match_operand:SI 1 "immediate_operand" "")))
7410 (clobber (reg:CC CC_REGNUM))]
7413 [(set (match_dup 0) (and:QI (match_dup 0) (match_dup 1)))
7414 (clobber (reg:CC CC_REGNUM))])]
7415 "s390_narrow_logical_operator (AND, &operands[0], &operands[1]);")
7418 ; andhi3 instruction pattern(s).
7421 (define_insn "*andhi3_zarch"
7422 [(set (match_operand:HI 0 "nonimmediate_operand" "=d,d,d, AQ,Q")
7423 (and:HI (match_operand:HI 1 "nonimmediate_operand" "%0,d,0, 0,0")
7424 (match_operand:HI 2 "general_operand" " d,d,n,NxQHF,Q")))
7425 (clobber (reg:CC CC_REGNUM))]
7426 "TARGET_ZARCH && s390_logical_operator_ok_p (operands)"
7433 [(set_attr "op_type" "RR,RRF,RI,SI,SS")
7434 (set_attr "cpu_facility" "*,z196,*,*,*")
7435 (set_attr "z10prop" "z10_super_E1,*,z10_super_E1,*,*")
7438 (define_insn "*andhi3_esa"
7439 [(set (match_operand:HI 0 "nonimmediate_operand" "=d,AQ,Q")
7440 (and:HI (match_operand:HI 1 "nonimmediate_operand" "%0,0,0")
7441 (match_operand:HI 2 "general_operand" "d,NxQHF,Q")))
7442 (clobber (reg:CC CC_REGNUM))]
7443 "!TARGET_ZARCH && s390_logical_operator_ok_p (operands)"
7448 [(set_attr "op_type" "RR,SI,SS")
7449 (set_attr "z10prop" "z10_super_E1,*,*")
7453 [(set (match_operand:HI 0 "s_operand" "")
7454 (and:HI (match_dup 0) (match_operand:HI 1 "immediate_operand" "")))
7455 (clobber (reg:CC CC_REGNUM))]
7458 [(set (match_dup 0) (and:QI (match_dup 0) (match_dup 1)))
7459 (clobber (reg:CC CC_REGNUM))])]
7460 "s390_narrow_logical_operator (AND, &operands[0], &operands[1]);")
7463 ; andqi3 instruction pattern(s).
7466 (define_insn "*andqi3_zarch"
7467 [(set (match_operand:QI 0 "nonimmediate_operand" "=d,d,d,Q,S,Q")
7468 (and:QI (match_operand:QI 1 "nonimmediate_operand" "%0,d,0,0,0,0")
7469 (match_operand:QI 2 "general_operand" " d,d,n,n,n,Q")))
7470 (clobber (reg:CC CC_REGNUM))]
7471 "TARGET_ZARCH && s390_logical_operator_ok_p (operands)"
7479 [(set_attr "op_type" "RR,RRF,RI,SI,SIY,SS")
7480 (set_attr "cpu_facility" "*,z196,*,*,longdisp,*")
7481 (set_attr "z10prop" "z10_super_E1,*,z10_super_E1,z10_super,z10_super,*")])
7483 (define_insn "*andqi3_esa"
7484 [(set (match_operand:QI 0 "nonimmediate_operand" "=d,Q,Q")
7485 (and:QI (match_operand:QI 1 "nonimmediate_operand" "%0,0,0")
7486 (match_operand:QI 2 "general_operand" "d,n,Q")))
7487 (clobber (reg:CC CC_REGNUM))]
7488 "!TARGET_ZARCH && s390_logical_operator_ok_p (operands)"
7493 [(set_attr "op_type" "RR,SI,SS")
7494 (set_attr "z10prop" "z10_super_E1,z10_super,*")])
7497 ; And with complement
7499 ; c = ~b & a = (b & a) ^ a
7501 (define_insn_and_split "*andc_split_<mode>"
7502 [(set (match_operand:GPR 0 "nonimmediate_operand" "")
7503 (and:GPR (not:GPR (match_operand:GPR 1 "nonimmediate_operand" ""))
7504 (match_operand:GPR 2 "general_operand" "")))
7505 (clobber (reg:CC CC_REGNUM))]
7507 && (GET_CODE (operands[0]) != MEM
7508 /* Ensure that s390_logical_operator_ok_p will succeed even
7509 on the split xor if (b & a) is stored into a pseudo. */
7510 || rtx_equal_p (operands[0], operands[2]))"
7515 [(set (match_dup 3) (and:GPR (match_dup 1) (match_dup 2)))
7516 (clobber (reg:CC CC_REGNUM))])
7518 [(set (match_dup 0) (xor:GPR (match_dup 3) (match_dup 2)))
7519 (clobber (reg:CC CC_REGNUM))])]
7521 if (reg_overlap_mentioned_p (operands[0], operands[2]))
7522 operands[3] = gen_reg_rtx (<MODE>mode);
7524 operands[3] = operands[0];
7528 ; Block and (NC) patterns.
7532 [(set (match_operand:BLK 0 "memory_operand" "=Q")
7533 (and:BLK (match_dup 0)
7534 (match_operand:BLK 1 "memory_operand" "Q")))
7535 (use (match_operand 2 "const_int_operand" "n"))
7536 (clobber (reg:CC CC_REGNUM))]
7537 "INTVAL (operands[2]) >= 1 && INTVAL (operands[2]) <= 256"
7538 "nc\t%O0(%2,%R0),%S1"
7539 [(set_attr "op_type" "SS")
7540 (set_attr "z196prop" "z196_cracked")])
7543 [(set (match_operand 0 "memory_operand" "")
7545 (match_operand 1 "memory_operand" "")))
7546 (clobber (reg:CC CC_REGNUM))]
7548 && GET_MODE (operands[0]) == GET_MODE (operands[1])
7549 && GET_MODE_SIZE (GET_MODE (operands[0])) > 0"
7551 [(set (match_dup 0) (and:BLK (match_dup 0) (match_dup 1)))
7553 (clobber (reg:CC CC_REGNUM))])]
7555 operands[2] = GEN_INT (GET_MODE_SIZE (GET_MODE (operands[0])));
7556 operands[0] = adjust_address (operands[0], BLKmode, 0);
7557 operands[1] = adjust_address (operands[1], BLKmode, 0);
7562 [(set (match_operand:BLK 0 "memory_operand" "")
7563 (and:BLK (match_dup 0)
7564 (match_operand:BLK 1 "memory_operand" "")))
7565 (use (match_operand 2 "const_int_operand" ""))
7566 (clobber (reg:CC CC_REGNUM))])
7568 [(set (match_operand:BLK 3 "memory_operand" "")
7569 (and:BLK (match_dup 3)
7570 (match_operand:BLK 4 "memory_operand" "")))
7571 (use (match_operand 5 "const_int_operand" ""))
7572 (clobber (reg:CC CC_REGNUM))])]
7573 "s390_offset_p (operands[0], operands[3], operands[2])
7574 && s390_offset_p (operands[1], operands[4], operands[2])
7575 && !s390_overlap_p (operands[0], operands[1],
7576 INTVAL (operands[2]) + INTVAL (operands[5]))
7577 && INTVAL (operands[2]) + INTVAL (operands[5]) <= 256"
7579 [(set (match_dup 6) (and:BLK (match_dup 6) (match_dup 7)))
7581 (clobber (reg:CC CC_REGNUM))])]
7582 "operands[6] = gen_rtx_MEM (BLKmode, XEXP (operands[0], 0));
7583 operands[7] = gen_rtx_MEM (BLKmode, XEXP (operands[1], 0));
7584 operands[8] = GEN_INT (INTVAL (operands[2]) + INTVAL (operands[5]));")
7588 ;;- Bit set (inclusive or) instructions.
7591 (define_expand "ior<mode>3"
7592 [(set (match_operand:INT 0 "nonimmediate_operand" "")
7593 (ior:INT (match_operand:INT 1 "nonimmediate_operand" "")
7594 (match_operand:INT 2 "general_operand" "")))
7595 (clobber (reg:CC CC_REGNUM))]
7597 "s390_expand_logical_operator (IOR, <MODE>mode, operands); DONE;")
7600 ; iordi3 instruction pattern(s).
7603 (define_insn "*iordi3_cc"
7604 [(set (reg CC_REGNUM)
7605 (compare (ior:DI (match_operand:DI 1 "nonimmediate_operand" "%0,d,0")
7606 (match_operand:DI 2 "general_operand" " d,d,T"))
7608 (set (match_operand:DI 0 "register_operand" "=d,d,d")
7609 (ior:DI (match_dup 1) (match_dup 2)))]
7610 "s390_match_ccmode(insn, CCTmode) && TARGET_ZARCH"
7615 [(set_attr "op_type" "RRE,RRF,RXY")
7616 (set_attr "cpu_facility" "*,z196,*")
7617 (set_attr "z10prop" "z10_super_E1,*,z10_super_E1")])
7619 (define_insn "*iordi3_cconly"
7620 [(set (reg CC_REGNUM)
7621 (compare (ior:DI (match_operand:DI 1 "nonimmediate_operand" "%0,d,0")
7622 (match_operand:DI 2 "general_operand" " d,d,T"))
7624 (clobber (match_scratch:DI 0 "=d,d,d"))]
7625 "s390_match_ccmode(insn, CCTmode) && TARGET_ZARCH"
7630 [(set_attr "op_type" "RRE,RRF,RXY")
7631 (set_attr "cpu_facility" "*,z196,*")
7632 (set_attr "z10prop" "z10_super_E1,*,z10_super_E1")])
7634 (define_insn "*iordi3"
7635 [(set (match_operand:DI 0 "nonimmediate_operand"
7636 "=d, d, d, d, d, d,d,d,d, AQ,Q")
7637 (ior:DI (match_operand:DI 1 "nonimmediate_operand"
7638 " %0, 0, 0, 0, 0, 0,0,d,0, 0,0")
7639 (match_operand:DI 2 "general_operand"
7640 "N0HD0,N1HD0,N2HD0,N3HD0,N0SD0,N1SD0,d,d,T,NxQD0,Q")))
7641 (clobber (reg:CC CC_REGNUM))]
7642 "TARGET_ZARCH && s390_logical_operator_ok_p (operands)"
7655 [(set_attr "op_type" "RI,RI,RI,RI,RIL,RIL,RRE,RRF,RXY,SI,SS")
7656 (set_attr "cpu_facility" "*,*,*,*,extimm,extimm,*,z196,*,*,*")
7657 (set_attr "z10prop" "z10_super_E1,
7670 [(set (match_operand:DI 0 "s_operand" "")
7671 (ior:DI (match_dup 0) (match_operand:DI 1 "immediate_operand" "")))
7672 (clobber (reg:CC CC_REGNUM))]
7675 [(set (match_dup 0) (ior:QI (match_dup 0) (match_dup 1)))
7676 (clobber (reg:CC CC_REGNUM))])]
7677 "s390_narrow_logical_operator (IOR, &operands[0], &operands[1]);")
7680 ; iorsi3 instruction pattern(s).
7683 (define_insn "*iorsi3_cc"
7684 [(set (reg CC_REGNUM)
7685 (compare (ior:SI (match_operand:SI 1 "nonimmediate_operand" "%0,0,d,0,0")
7686 (match_operand:SI 2 "general_operand" "Os,d,d,R,T"))
7688 (set (match_operand:SI 0 "register_operand" "=d,d,d,d,d")
7689 (ior:SI (match_dup 1) (match_dup 2)))]
7690 "s390_match_ccmode(insn, CCTmode)"
7697 [(set_attr "op_type" "RIL,RR,RRF,RX,RXY")
7698 (set_attr "cpu_facility" "*,*,z196,*,longdisp")
7699 (set_attr "z10prop" "z10_super_E1,z10_super_E1,*,z10_super_E1,z10_super_E1")])
7701 (define_insn "*iorsi3_cconly"
7702 [(set (reg CC_REGNUM)
7703 (compare (ior:SI (match_operand:SI 1 "nonimmediate_operand" "%0,0,d,0,0")
7704 (match_operand:SI 2 "general_operand" "Os,d,d,R,T"))
7706 (clobber (match_scratch:SI 0 "=d,d,d,d,d"))]
7707 "s390_match_ccmode(insn, CCTmode)"
7714 [(set_attr "op_type" "RIL,RR,RRF,RX,RXY")
7715 (set_attr "cpu_facility" "*,*,z196,*,longdisp")
7716 (set_attr "z10prop" "z10_super_E1,z10_super_E1,*,z10_super_E1,z10_super_E1")])
7718 (define_insn "*iorsi3_zarch"
7719 [(set (match_operand:SI 0 "nonimmediate_operand" "=d, d, d,d,d,d,d, AQ,Q")
7720 (ior:SI (match_operand:SI 1 "nonimmediate_operand" "%0, 0, 0,0,d,0,0, 0,0")
7721 (match_operand:SI 2 "general_operand" "N0HS0,N1HS0,Os,d,d,R,T,NxQS0,Q")))
7722 (clobber (reg:CC CC_REGNUM))]
7723 "TARGET_ZARCH && s390_logical_operator_ok_p (operands)"
7734 [(set_attr "op_type" "RI,RI,RIL,RR,RRF,RX,RXY,SI,SS")
7735 (set_attr "cpu_facility" "*,*,*,*,z196,*,longdisp,*,*")
7736 (set_attr "z10prop" "z10_super_E1,
7746 (define_insn "*iorsi3_esa"
7747 [(set (match_operand:SI 0 "nonimmediate_operand" "=d,d,AQ,Q")
7748 (ior:SI (match_operand:SI 1 "nonimmediate_operand" "%0,0,0,0")
7749 (match_operand:SI 2 "general_operand" "d,R,NxQS0,Q")))
7750 (clobber (reg:CC CC_REGNUM))]
7751 "!TARGET_ZARCH && s390_logical_operator_ok_p (operands)"
7757 [(set_attr "op_type" "RR,RX,SI,SS")
7758 (set_attr "z10prop" "z10_super_E1,z10_super_E1,*,*")])
7761 [(set (match_operand:SI 0 "s_operand" "")
7762 (ior:SI (match_dup 0) (match_operand:SI 1 "immediate_operand" "")))
7763 (clobber (reg:CC CC_REGNUM))]
7766 [(set (match_dup 0) (ior:QI (match_dup 0) (match_dup 1)))
7767 (clobber (reg:CC CC_REGNUM))])]
7768 "s390_narrow_logical_operator (IOR, &operands[0], &operands[1]);")
7771 ; iorhi3 instruction pattern(s).
7774 (define_insn "*iorhi3_zarch"
7775 [(set (match_operand:HI 0 "nonimmediate_operand" "=d,d,d, AQ,Q")
7776 (ior:HI (match_operand:HI 1 "nonimmediate_operand" "%0,d,0, 0,0")
7777 (match_operand:HI 2 "general_operand" " d,d,n,NxQH0,Q")))
7778 (clobber (reg:CC CC_REGNUM))]
7779 "TARGET_ZARCH && s390_logical_operator_ok_p (operands)"
7786 [(set_attr "op_type" "RR,RRF,RI,SI,SS")
7787 (set_attr "cpu_facility" "*,z196,*,*,*")
7788 (set_attr "z10prop" "z10_super_E1,*,z10_super_E1,*,*")])
7790 (define_insn "*iorhi3_esa"
7791 [(set (match_operand:HI 0 "nonimmediate_operand" "=d,AQ,Q")
7792 (ior:HI (match_operand:HI 1 "nonimmediate_operand" "%0,0,0")
7793 (match_operand:HI 2 "general_operand" "d,NxQH0,Q")))
7794 (clobber (reg:CC CC_REGNUM))]
7795 "!TARGET_ZARCH && s390_logical_operator_ok_p (operands)"
7800 [(set_attr "op_type" "RR,SI,SS")
7801 (set_attr "z10prop" "z10_super_E1,*,*")])
7804 [(set (match_operand:HI 0 "s_operand" "")
7805 (ior:HI (match_dup 0) (match_operand:HI 1 "immediate_operand" "")))
7806 (clobber (reg:CC CC_REGNUM))]
7809 [(set (match_dup 0) (ior:QI (match_dup 0) (match_dup 1)))
7810 (clobber (reg:CC CC_REGNUM))])]
7811 "s390_narrow_logical_operator (IOR, &operands[0], &operands[1]);")
7814 ; iorqi3 instruction pattern(s).
7817 (define_insn "*iorqi3_zarch"
7818 [(set (match_operand:QI 0 "nonimmediate_operand" "=d,d,d,Q,S,Q")
7819 (ior:QI (match_operand:QI 1 "nonimmediate_operand" "%0,d,0,0,0,0")
7820 (match_operand:QI 2 "general_operand" " d,d,n,n,n,Q")))
7821 (clobber (reg:CC CC_REGNUM))]
7822 "TARGET_ZARCH && s390_logical_operator_ok_p (operands)"
7830 [(set_attr "op_type" "RR,RRF,RI,SI,SIY,SS")
7831 (set_attr "cpu_facility" "*,z196,*,*,longdisp,*")
7832 (set_attr "z10prop" "z10_super_E1,*,z10_super_E1,
7833 z10_super,z10_super,*")])
7835 (define_insn "*iorqi3_esa"
7836 [(set (match_operand:QI 0 "nonimmediate_operand" "=d,Q,Q")
7837 (ior:QI (match_operand:QI 1 "nonimmediate_operand" "%0,0,0")
7838 (match_operand:QI 2 "general_operand" "d,n,Q")))
7839 (clobber (reg:CC CC_REGNUM))]
7840 "!TARGET_ZARCH && s390_logical_operator_ok_p (operands)"
7845 [(set_attr "op_type" "RR,SI,SS")
7846 (set_attr "z10prop" "z10_super_E1,z10_super,*")])
7849 ; Block inclusive or (OC) patterns.
7853 [(set (match_operand:BLK 0 "memory_operand" "=Q")
7854 (ior:BLK (match_dup 0)
7855 (match_operand:BLK 1 "memory_operand" "Q")))
7856 (use (match_operand 2 "const_int_operand" "n"))
7857 (clobber (reg:CC CC_REGNUM))]
7858 "INTVAL (operands[2]) >= 1 && INTVAL (operands[2]) <= 256"
7859 "oc\t%O0(%2,%R0),%S1"
7860 [(set_attr "op_type" "SS")
7861 (set_attr "z196prop" "z196_cracked")])
7864 [(set (match_operand 0 "memory_operand" "")
7866 (match_operand 1 "memory_operand" "")))
7867 (clobber (reg:CC CC_REGNUM))]
7869 && GET_MODE (operands[0]) == GET_MODE (operands[1])
7870 && GET_MODE_SIZE (GET_MODE (operands[0])) > 0"
7872 [(set (match_dup 0) (ior:BLK (match_dup 0) (match_dup 1)))
7874 (clobber (reg:CC CC_REGNUM))])]
7876 operands[2] = GEN_INT (GET_MODE_SIZE (GET_MODE (operands[0])));
7877 operands[0] = adjust_address (operands[0], BLKmode, 0);
7878 operands[1] = adjust_address (operands[1], BLKmode, 0);
7883 [(set (match_operand:BLK 0 "memory_operand" "")
7884 (ior:BLK (match_dup 0)
7885 (match_operand:BLK 1 "memory_operand" "")))
7886 (use (match_operand 2 "const_int_operand" ""))
7887 (clobber (reg:CC CC_REGNUM))])
7889 [(set (match_operand:BLK 3 "memory_operand" "")
7890 (ior:BLK (match_dup 3)
7891 (match_operand:BLK 4 "memory_operand" "")))
7892 (use (match_operand 5 "const_int_operand" ""))
7893 (clobber (reg:CC CC_REGNUM))])]
7894 "s390_offset_p (operands[0], operands[3], operands[2])
7895 && s390_offset_p (operands[1], operands[4], operands[2])
7896 && !s390_overlap_p (operands[0], operands[1],
7897 INTVAL (operands[2]) + INTVAL (operands[5]))
7898 && INTVAL (operands[2]) + INTVAL (operands[5]) <= 256"
7900 [(set (match_dup 6) (ior:BLK (match_dup 6) (match_dup 7)))
7902 (clobber (reg:CC CC_REGNUM))])]
7903 "operands[6] = gen_rtx_MEM (BLKmode, XEXP (operands[0], 0));
7904 operands[7] = gen_rtx_MEM (BLKmode, XEXP (operands[1], 0));
7905 operands[8] = GEN_INT (INTVAL (operands[2]) + INTVAL (operands[5]));")
7909 ;;- Xor instructions.
7912 (define_expand "xor<mode>3"
7913 [(set (match_operand:INT 0 "nonimmediate_operand" "")
7914 (xor:INT (match_operand:INT 1 "nonimmediate_operand" "")
7915 (match_operand:INT 2 "general_operand" "")))
7916 (clobber (reg:CC CC_REGNUM))]
7918 "s390_expand_logical_operator (XOR, <MODE>mode, operands); DONE;")
7920 ; Combine replaces (xor (x) (const_int -1)) with (not (x)) when doing
7921 ; simplifications. So its better to have something matching.
7923 [(set (match_operand:INT 0 "nonimmediate_operand" "")
7924 (not:INT (match_operand:INT 1 "nonimmediate_operand" "")))]
7927 [(set (match_dup 0) (xor:INT (match_dup 1) (match_dup 2)))
7928 (clobber (reg:CC CC_REGNUM))])]
7930 operands[2] = constm1_rtx;
7931 if (!s390_logical_operator_ok_p (operands))
7936 ; xordi3 instruction pattern(s).
7939 (define_insn "*xordi3_cc"
7940 [(set (reg CC_REGNUM)
7941 (compare (xor:DI (match_operand:DI 1 "nonimmediate_operand" "%0,d,0")
7942 (match_operand:DI 2 "general_operand" " d,d,T"))
7944 (set (match_operand:DI 0 "register_operand" "=d,d,d")
7945 (xor:DI (match_dup 1) (match_dup 2)))]
7946 "s390_match_ccmode(insn, CCTmode) && TARGET_ZARCH"
7951 [(set_attr "op_type" "RRE,RRF,RXY")
7952 (set_attr "cpu_facility" "*,z196,*")
7953 (set_attr "z10prop" "z10_super_E1,*,z10_super_E1")])
7955 (define_insn "*xordi3_cconly"
7956 [(set (reg CC_REGNUM)
7957 (compare (xor:DI (match_operand:DI 1 "nonimmediate_operand" "%0,d,0")
7958 (match_operand:DI 2 "general_operand" " d,d,T"))
7960 (clobber (match_scratch:DI 0 "=d,d,d"))]
7961 "s390_match_ccmode(insn, CCTmode) && TARGET_ZARCH"
7966 [(set_attr "op_type" "RRE,RRF,RXY")
7967 (set_attr "cpu_facility" "*,z196,*")
7968 (set_attr "z10prop" "z10_super_E1,*,z10_super_E1")])
7970 (define_insn "*xordi3"
7971 [(set (match_operand:DI 0 "nonimmediate_operand" "=d, d,d,d,d, AQ,Q")
7972 (xor:DI (match_operand:DI 1 "nonimmediate_operand" "%0, 0,0,d,0, 0,0")
7973 (match_operand:DI 2 "general_operand" "N0SD0,N1SD0,d,d,T,NxQD0,Q")))
7974 (clobber (reg:CC CC_REGNUM))]
7975 "TARGET_ZARCH && s390_logical_operator_ok_p (operands)"
7984 [(set_attr "op_type" "RIL,RIL,RRE,RRF,RXY,SI,SS")
7985 (set_attr "cpu_facility" "extimm,extimm,*,z196,*,*,*")
7986 (set_attr "z10prop" "z10_super_E1,z10_super_E1,z10_super_E1,
7987 *,z10_super_E1,*,*")])
7990 [(set (match_operand:DI 0 "s_operand" "")
7991 (xor:DI (match_dup 0) (match_operand:DI 1 "immediate_operand" "")))
7992 (clobber (reg:CC CC_REGNUM))]
7995 [(set (match_dup 0) (xor:QI (match_dup 0) (match_dup 1)))
7996 (clobber (reg:CC CC_REGNUM))])]
7997 "s390_narrow_logical_operator (XOR, &operands[0], &operands[1]);")
8000 ; xorsi3 instruction pattern(s).
8003 (define_insn "*xorsi3_cc"
8004 [(set (reg CC_REGNUM)
8005 (compare (xor:SI (match_operand:SI 1 "nonimmediate_operand" "%0,0,d,0,0")
8006 (match_operand:SI 2 "general_operand" "Os,d,d,R,T"))
8008 (set (match_operand:SI 0 "register_operand" "=d,d,d,d,d")
8009 (xor:SI (match_dup 1) (match_dup 2)))]
8010 "s390_match_ccmode(insn, CCTmode)"
8017 [(set_attr "op_type" "RIL,RR,RRF,RX,RXY")
8018 (set_attr "cpu_facility" "*,*,z196,*,longdisp")
8019 (set_attr "z10prop" "z10_super_E1,z10_super_E1,*,
8020 z10_super_E1,z10_super_E1")])
8022 (define_insn "*xorsi3_cconly"
8023 [(set (reg CC_REGNUM)
8024 (compare (xor:SI (match_operand:SI 1 "nonimmediate_operand" "%0,0,d,0,0")
8025 (match_operand:SI 2 "general_operand" "Os,d,d,R,T"))
8027 (clobber (match_scratch:SI 0 "=d,d,d,d,d"))]
8028 "s390_match_ccmode(insn, CCTmode)"
8035 [(set_attr "op_type" "RIL,RR,RRF,RX,RXY")
8036 (set_attr "cpu_facility" "*,*,z196,*,longdisp")
8037 (set_attr "z10prop" "z10_super_E1,z10_super_E1,*,
8038 z10_super_E1,z10_super_E1")])
8040 (define_insn "*xorsi3"
8041 [(set (match_operand:SI 0 "nonimmediate_operand" "=d,d,d,d,d, AQ,Q")
8042 (xor:SI (match_operand:SI 1 "nonimmediate_operand" "%0,0,d,0,0, 0,0")
8043 (match_operand:SI 2 "general_operand" "Os,d,d,R,T,NxQS0,Q")))
8044 (clobber (reg:CC CC_REGNUM))]
8045 "s390_logical_operator_ok_p (operands)"
8054 [(set_attr "op_type" "RIL,RR,RRF,RX,RXY,SI,SS")
8055 (set_attr "cpu_facility" "*,*,z196,*,longdisp,*,*")
8056 (set_attr "z10prop" "z10_super_E1,z10_super_E1,*,
8057 z10_super_E1,z10_super_E1,*,*")])
8060 [(set (match_operand:SI 0 "s_operand" "")
8061 (xor:SI (match_dup 0) (match_operand:SI 1 "immediate_operand" "")))
8062 (clobber (reg:CC CC_REGNUM))]
8065 [(set (match_dup 0) (xor:QI (match_dup 0) (match_dup 1)))
8066 (clobber (reg:CC CC_REGNUM))])]
8067 "s390_narrow_logical_operator (XOR, &operands[0], &operands[1]);")
8070 ; xorhi3 instruction pattern(s).
8073 (define_insn "*xorhi3"
8074 [(set (match_operand:HI 0 "nonimmediate_operand" "=d,d,d, AQ,Q")
8075 (xor:HI (match_operand:HI 1 "nonimmediate_operand" "%0,0,d, 0,0")
8076 (match_operand:HI 2 "general_operand" "Os,d,d,NxQH0,Q")))
8077 (clobber (reg:CC CC_REGNUM))]
8078 "s390_logical_operator_ok_p (operands)"
8085 [(set_attr "op_type" "RIL,RR,RRF,SI,SS")
8086 (set_attr "cpu_facility" "*,*,z196,*,*")
8087 (set_attr "z10prop" "z10_super_E1,z10_super_E1,*,*,*")])
8090 [(set (match_operand:HI 0 "s_operand" "")
8091 (xor:HI (match_dup 0) (match_operand:HI 1 "immediate_operand" "")))
8092 (clobber (reg:CC CC_REGNUM))]
8095 [(set (match_dup 0) (xor:QI (match_dup 0) (match_dup 1)))
8096 (clobber (reg:CC CC_REGNUM))])]
8097 "s390_narrow_logical_operator (XOR, &operands[0], &operands[1]);")
8100 ; xorqi3 instruction pattern(s).
8103 (define_insn "*xorqi3"
8104 [(set (match_operand:QI 0 "nonimmediate_operand" "=d,d,d,Q,S,Q")
8105 (xor:QI (match_operand:QI 1 "nonimmediate_operand" "%0,0,d,0,0,0")
8106 (match_operand:QI 2 "general_operand" "Os,d,d,n,n,Q")))
8107 (clobber (reg:CC CC_REGNUM))]
8108 "s390_logical_operator_ok_p (operands)"
8116 [(set_attr "op_type" "RIL,RR,RRF,SI,SIY,SS")
8117 (set_attr "cpu_facility" "*,*,z196,*,longdisp,*")
8118 (set_attr "z10prop" "z10_super_E1,z10_super_E1,*,z10_super,z10_super,*")])
8122 ; Block exclusive or (XC) patterns.
8126 [(set (match_operand:BLK 0 "memory_operand" "=Q")
8127 (xor:BLK (match_dup 0)
8128 (match_operand:BLK 1 "memory_operand" "Q")))
8129 (use (match_operand 2 "const_int_operand" "n"))
8130 (clobber (reg:CC CC_REGNUM))]
8131 "INTVAL (operands[2]) >= 1 && INTVAL (operands[2]) <= 256"
8132 "xc\t%O0(%2,%R0),%S1"
8133 [(set_attr "op_type" "SS")])
8136 [(set (match_operand 0 "memory_operand" "")
8138 (match_operand 1 "memory_operand" "")))
8139 (clobber (reg:CC CC_REGNUM))]
8141 && GET_MODE (operands[0]) == GET_MODE (operands[1])
8142 && GET_MODE_SIZE (GET_MODE (operands[0])) > 0"
8144 [(set (match_dup 0) (xor:BLK (match_dup 0) (match_dup 1)))
8146 (clobber (reg:CC CC_REGNUM))])]
8148 operands[2] = GEN_INT (GET_MODE_SIZE (GET_MODE (operands[0])));
8149 operands[0] = adjust_address (operands[0], BLKmode, 0);
8150 operands[1] = adjust_address (operands[1], BLKmode, 0);
8155 [(set (match_operand:BLK 0 "memory_operand" "")
8156 (xor:BLK (match_dup 0)
8157 (match_operand:BLK 1 "memory_operand" "")))
8158 (use (match_operand 2 "const_int_operand" ""))
8159 (clobber (reg:CC CC_REGNUM))])
8161 [(set (match_operand:BLK 3 "memory_operand" "")
8162 (xor:BLK (match_dup 3)
8163 (match_operand:BLK 4 "memory_operand" "")))
8164 (use (match_operand 5 "const_int_operand" ""))
8165 (clobber (reg:CC CC_REGNUM))])]
8166 "s390_offset_p (operands[0], operands[3], operands[2])
8167 && s390_offset_p (operands[1], operands[4], operands[2])
8168 && !s390_overlap_p (operands[0], operands[1],
8169 INTVAL (operands[2]) + INTVAL (operands[5]))
8170 && INTVAL (operands[2]) + INTVAL (operands[5]) <= 256"
8172 [(set (match_dup 6) (xor:BLK (match_dup 6) (match_dup 7)))
8174 (clobber (reg:CC CC_REGNUM))])]
8175 "operands[6] = gen_rtx_MEM (BLKmode, XEXP (operands[0], 0));
8176 operands[7] = gen_rtx_MEM (BLKmode, XEXP (operands[1], 0));
8177 operands[8] = GEN_INT (INTVAL (operands[2]) + INTVAL (operands[5]));")
8180 ; Block xor (XC) patterns with src == dest.
8183 (define_insn "*xc_zero"
8184 [(set (match_operand:BLK 0 "memory_operand" "=Q")
8186 (use (match_operand 1 "const_int_operand" "n"))
8187 (clobber (reg:CC CC_REGNUM))]
8188 "INTVAL (operands[1]) >= 1 && INTVAL (operands[1]) <= 256"
8189 "xc\t%O0(%1,%R0),%S0"
8190 [(set_attr "op_type" "SS")
8191 (set_attr "z196prop" "z196_cracked")])
8195 [(set (match_operand:BLK 0 "memory_operand" "")
8197 (use (match_operand 1 "const_int_operand" ""))
8198 (clobber (reg:CC CC_REGNUM))])
8200 [(set (match_operand:BLK 2 "memory_operand" "")
8202 (use (match_operand 3 "const_int_operand" ""))
8203 (clobber (reg:CC CC_REGNUM))])]
8204 "s390_offset_p (operands[0], operands[2], operands[1])
8205 && INTVAL (operands[1]) + INTVAL (operands[3]) <= 256"
8207 [(set (match_dup 4) (const_int 0))
8209 (clobber (reg:CC CC_REGNUM))])]
8210 "operands[4] = gen_rtx_MEM (BLKmode, XEXP (operands[0], 0));
8211 operands[5] = GEN_INT (INTVAL (operands[1]) + INTVAL (operands[3]));")
8215 ;;- Negate instructions.
8219 ; neg(di|si)2 instruction pattern(s).
8222 (define_expand "neg<mode>2"
8224 [(set (match_operand:DSI 0 "register_operand" "=d")
8225 (neg:DSI (match_operand:DSI 1 "register_operand" "d")))
8226 (clobber (reg:CC CC_REGNUM))])]
8230 (define_insn "*negdi2_sign_cc"
8231 [(set (reg CC_REGNUM)
8232 (compare (neg:DI (ashiftrt:DI (ashift:DI (subreg:DI
8233 (match_operand:SI 1 "register_operand" "d") 0)
8234 (const_int 32)) (const_int 32)))
8236 (set (match_operand:DI 0 "register_operand" "=d")
8237 (neg:DI (sign_extend:DI (match_dup 1))))]
8238 "TARGET_ZARCH && s390_match_ccmode (insn, CCAmode)"
8240 [(set_attr "op_type" "RRE")
8241 (set_attr "z10prop" "z10_c")])
8243 (define_insn "*negdi2_sign"
8244 [(set (match_operand:DI 0 "register_operand" "=d")
8245 (neg:DI (sign_extend:DI (match_operand:SI 1 "register_operand" "d"))))
8246 (clobber (reg:CC CC_REGNUM))]
8249 [(set_attr "op_type" "RRE")
8250 (set_attr "z10prop" "z10_c")])
8253 (define_insn "*neg<mode>2_cc"
8254 [(set (reg CC_REGNUM)
8255 (compare (neg:GPR (match_operand:GPR 1 "register_operand" "d"))
8257 (set (match_operand:GPR 0 "register_operand" "=d")
8258 (neg:GPR (match_dup 1)))]
8259 "s390_match_ccmode (insn, CCAmode)"
8261 [(set_attr "op_type" "RR<E>")
8262 (set_attr "z10prop" "z10_super_c_E1")])
8265 (define_insn "*neg<mode>2_cconly"
8266 [(set (reg CC_REGNUM)
8267 (compare (neg:GPR (match_operand:GPR 1 "register_operand" "d"))
8269 (clobber (match_scratch:GPR 0 "=d"))]
8270 "s390_match_ccmode (insn, CCAmode)"
8272 [(set_attr "op_type" "RR<E>")
8273 (set_attr "z10prop" "z10_super_c_E1")])
8276 (define_insn "*neg<mode>2"
8277 [(set (match_operand:GPR 0 "register_operand" "=d")
8278 (neg:GPR (match_operand:GPR 1 "register_operand" "d")))
8279 (clobber (reg:CC CC_REGNUM))]
8282 [(set_attr "op_type" "RR<E>")
8283 (set_attr "z10prop" "z10_super_c_E1")])
8285 (define_insn "*negdi2_31"
8286 [(set (match_operand:DI 0 "register_operand" "=d")
8287 (neg:DI (match_operand:DI 1 "register_operand" "d")))
8288 (clobber (reg:CC CC_REGNUM))]
8292 ; Split a DImode NEG on 31bit into 2 SImode NEGs
8294 ; Doing the twos complement separately on the SImode parts does an
8295 ; unwanted +1 on the high part which needs to be subtracted afterwards
8296 ; ... unless the +1 on the low part created an overflow.
8299 [(set (match_operand:DI 0 "register_operand" "")
8300 (neg:DI (match_operand:DI 1 "register_operand" "")))
8301 (clobber (reg:CC CC_REGNUM))]
8303 && (REGNO (operands[0]) == REGNO (operands[1])
8304 || s390_split_ok_p (operands[0], operands[1], DImode, 0))
8305 && reload_completed"
8307 [(set (match_dup 2) (neg:SI (match_dup 3)))
8308 (clobber (reg:CC CC_REGNUM))])
8310 [(set (reg:CCAP CC_REGNUM)
8311 (compare:CCAP (neg:SI (match_dup 5)) (const_int 0)))
8312 (set (match_dup 4) (neg:SI (match_dup 5)))])
8314 (if_then_else (ne (reg:CCAP CC_REGNUM) (const_int 0))
8316 (label_ref (match_dup 6))))
8318 [(set (match_dup 2) (plus:SI (match_dup 2) (const_int -1)))
8319 (clobber (reg:CC CC_REGNUM))])
8321 "operands[2] = operand_subword (operands[0], 0, 0, DImode);
8322 operands[3] = operand_subword (operands[1], 0, 0, DImode);
8323 operands[4] = operand_subword (operands[0], 1, 0, DImode);
8324 operands[5] = operand_subword (operands[1], 1, 0, DImode);
8325 operands[6] = gen_label_rtx ();")
8327 ; Like above but first make a copy of the low part of the src operand
8328 ; since it might overlap with the high part of the destination.
8331 [(set (match_operand:DI 0 "register_operand" "")
8332 (neg:DI (match_operand:DI 1 "register_operand" "")))
8333 (clobber (reg:CC CC_REGNUM))]
8335 && s390_split_ok_p (operands[0], operands[1], DImode, 1)
8336 && reload_completed"
8337 [; Make a backup of op5 first
8338 (set (match_dup 4) (match_dup 5))
8339 ; Setting op2 here might clobber op5
8341 [(set (match_dup 2) (neg:SI (match_dup 3)))
8342 (clobber (reg:CC CC_REGNUM))])
8344 [(set (reg:CCAP CC_REGNUM)
8345 (compare:CCAP (neg:SI (match_dup 4)) (const_int 0)))
8346 (set (match_dup 4) (neg:SI (match_dup 4)))])
8348 (if_then_else (ne (reg:CCAP CC_REGNUM) (const_int 0))
8350 (label_ref (match_dup 6))))
8352 [(set (match_dup 2) (plus:SI (match_dup 2) (const_int -1)))
8353 (clobber (reg:CC CC_REGNUM))])
8355 "operands[2] = operand_subword (operands[0], 0, 0, DImode);
8356 operands[3] = operand_subword (operands[1], 0, 0, DImode);
8357 operands[4] = operand_subword (operands[0], 1, 0, DImode);
8358 operands[5] = operand_subword (operands[1], 1, 0, DImode);
8359 operands[6] = gen_label_rtx ();")
8362 ; neg(df|sf)2 instruction pattern(s).
8365 (define_expand "neg<mode>2"
8367 [(set (match_operand:BFP 0 "register_operand")
8368 (neg:BFP (match_operand:BFP 1 "register_operand")))
8369 (clobber (reg:CC CC_REGNUM))])]
8370 "TARGET_HARD_FLOAT")
8372 ; lcxbr, lcdbr, lcebr
8373 (define_insn "*neg<mode>2_cc"
8374 [(set (reg CC_REGNUM)
8375 (compare (neg:BFP (match_operand:BFP 1 "register_operand" "f"))
8376 (match_operand:BFP 2 "const0_operand" "")))
8377 (set (match_operand:BFP 0 "register_operand" "=f")
8378 (neg:BFP (match_dup 1)))]
8379 "s390_match_ccmode (insn, CCSmode) && TARGET_HARD_FLOAT"
8381 [(set_attr "op_type" "RRE")
8382 (set_attr "type" "fsimp<mode>")])
8384 ; lcxbr, lcdbr, lcebr
8385 (define_insn "*neg<mode>2_cconly"
8386 [(set (reg CC_REGNUM)
8387 (compare (neg:BFP (match_operand:BFP 1 "register_operand" "f"))
8388 (match_operand:BFP 2 "const0_operand" "")))
8389 (clobber (match_scratch:BFP 0 "=f"))]
8390 "s390_match_ccmode (insn, CCSmode) && TARGET_HARD_FLOAT"
8392 [(set_attr "op_type" "RRE")
8393 (set_attr "type" "fsimp<mode>")])
8396 (define_insn "*neg<mode>2_nocc"
8397 [(set (match_operand:FP 0 "register_operand" "=f")
8398 (neg:FP (match_operand:FP 1 "register_operand" "<fT0>")))]
8401 [(set_attr "op_type" "RRE")
8402 (set_attr "type" "fsimp<mode>")])
8404 ; lcxbr, lcdbr, lcebr
8405 ; FIXME: wflcdb does not clobber cc
8406 ; FIXME: Does wflcdb ever match here?
8407 (define_insn "*neg<mode>2"
8408 [(set (match_operand:BFP 0 "register_operand" "=f,v,v")
8409 (neg:BFP (match_operand:BFP 1 "register_operand" "f,v,v")))
8410 (clobber (reg:CC CC_REGNUM))]
8416 [(set_attr "op_type" "RRE,VRR,VRR")
8417 (set_attr "cpu_facility" "*,vx,vxe")
8418 (set_attr "type" "fsimp<mode>,*,*")
8419 (set_attr "enabled" "*,<DF>,<SF>")])
8423 ;;- Absolute value instructions.
8427 ; abs(di|si)2 instruction pattern(s).
8430 (define_insn "*absdi2_sign_cc"
8431 [(set (reg CC_REGNUM)
8432 (compare (abs:DI (ashiftrt:DI (ashift:DI (subreg:DI
8433 (match_operand:SI 1 "register_operand" "d") 0)
8434 (const_int 32)) (const_int 32)))
8436 (set (match_operand:DI 0 "register_operand" "=d")
8437 (abs:DI (sign_extend:DI (match_dup 1))))]
8438 "TARGET_ZARCH && s390_match_ccmode (insn, CCAmode)"
8440 [(set_attr "op_type" "RRE")
8441 (set_attr "z10prop" "z10_c")])
8443 (define_insn "*absdi2_sign"
8444 [(set (match_operand:DI 0 "register_operand" "=d")
8445 (abs:DI (sign_extend:DI (match_operand:SI 1 "register_operand" "d"))))
8446 (clobber (reg:CC CC_REGNUM))]
8449 [(set_attr "op_type" "RRE")
8450 (set_attr "z10prop" "z10_c")])
8453 (define_insn "*abs<mode>2_cc"
8454 [(set (reg CC_REGNUM)
8455 (compare (abs:GPR (match_operand:DI 1 "register_operand" "d"))
8457 (set (match_operand:GPR 0 "register_operand" "=d")
8458 (abs:GPR (match_dup 1)))]
8459 "s390_match_ccmode (insn, CCAmode)"
8461 [(set_attr "op_type" "RR<E>")
8462 (set_attr "z10prop" "z10_c")])
8465 (define_insn "*abs<mode>2_cconly"
8466 [(set (reg CC_REGNUM)
8467 (compare (abs:GPR (match_operand:GPR 1 "register_operand" "d"))
8469 (clobber (match_scratch:GPR 0 "=d"))]
8470 "s390_match_ccmode (insn, CCAmode)"
8472 [(set_attr "op_type" "RR<E>")
8473 (set_attr "z10prop" "z10_c")])
8476 (define_insn "abs<mode>2"
8477 [(set (match_operand:GPR 0 "register_operand" "=d")
8478 (abs:GPR (match_operand:GPR 1 "register_operand" "d")))
8479 (clobber (reg:CC CC_REGNUM))]
8482 [(set_attr "op_type" "RR<E>")
8483 (set_attr "z10prop" "z10_c")])
8486 ; abs(df|sf)2 instruction pattern(s).
8489 (define_expand "abs<mode>2"
8491 [(set (match_operand:BFP 0 "register_operand" "=f")
8492 (abs:BFP (match_operand:BFP 1 "register_operand" "f")))
8493 (clobber (reg:CC CC_REGNUM))])]
8497 ; lpxbr, lpdbr, lpebr
8498 (define_insn "*abs<mode>2_cc"
8499 [(set (reg CC_REGNUM)
8500 (compare (abs:BFP (match_operand:BFP 1 "register_operand" "f"))
8501 (match_operand:BFP 2 "const0_operand" "")))
8502 (set (match_operand:BFP 0 "register_operand" "=f")
8503 (abs:BFP (match_dup 1)))]
8504 "s390_match_ccmode (insn, CCSmode) && TARGET_HARD_FLOAT"
8506 [(set_attr "op_type" "RRE")
8507 (set_attr "type" "fsimp<mode>")])
8509 ; lpxbr, lpdbr, lpebr
8510 (define_insn "*abs<mode>2_cconly"
8511 [(set (reg CC_REGNUM)
8512 (compare (abs:BFP (match_operand:BFP 1 "register_operand" "f"))
8513 (match_operand:BFP 2 "const0_operand" "")))
8514 (clobber (match_scratch:BFP 0 "=f"))]
8515 "s390_match_ccmode (insn, CCSmode) && TARGET_HARD_FLOAT"
8517 [(set_attr "op_type" "RRE")
8518 (set_attr "type" "fsimp<mode>")])
8521 (define_insn "*abs<mode>2_nocc"
8522 [(set (match_operand:FP 0 "register_operand" "=f")
8523 (abs:FP (match_operand:FP 1 "register_operand" "<fT0>")))]
8526 [(set_attr "op_type" "RRE")
8527 (set_attr "type" "fsimp<mode>")])
8529 ; lpxbr, lpdbr, lpebr
8530 ; FIXME: wflpdb does not clobber cc
8531 (define_insn "*abs<mode>2"
8532 [(set (match_operand:BFP 0 "register_operand" "=f,v")
8533 (abs:BFP (match_operand:BFP 1 "register_operand" "f,v")))
8534 (clobber (reg:CC CC_REGNUM))]
8539 [(set_attr "op_type" "RRE,VRR")
8540 (set_attr "cpu_facility" "*,vx")
8541 (set_attr "type" "fsimp<mode>,*")
8542 (set_attr "enabled" "*,<DFDI>")])
8546 ;;- Negated absolute value instructions
8553 (define_insn "*negabsdi2_sign_cc"
8554 [(set (reg CC_REGNUM)
8555 (compare (neg:DI (abs:DI (ashiftrt:DI (ashift:DI (subreg:DI
8556 (match_operand:SI 1 "register_operand" "d") 0)
8557 (const_int 32)) (const_int 32))))
8559 (set (match_operand:DI 0 "register_operand" "=d")
8560 (neg:DI (abs:DI (sign_extend:DI (match_dup 1)))))]
8561 "TARGET_ZARCH && s390_match_ccmode (insn, CCAmode)"
8563 [(set_attr "op_type" "RRE")
8564 (set_attr "z10prop" "z10_c")])
8566 (define_insn "*negabsdi2_sign"
8567 [(set (match_operand:DI 0 "register_operand" "=d")
8568 (neg:DI (abs:DI (sign_extend:DI
8569 (match_operand:SI 1 "register_operand" "d")))))
8570 (clobber (reg:CC CC_REGNUM))]
8573 [(set_attr "op_type" "RRE")
8574 (set_attr "z10prop" "z10_c")])
8577 (define_insn "*negabs<mode>2_cc"
8578 [(set (reg CC_REGNUM)
8579 (compare (neg:GPR (abs:GPR (match_operand:GPR 1 "register_operand" "d")))
8581 (set (match_operand:GPR 0 "register_operand" "=d")
8582 (neg:GPR (abs:GPR (match_dup 1))))]
8583 "s390_match_ccmode (insn, CCAmode)"
8585 [(set_attr "op_type" "RR<E>")
8586 (set_attr "z10prop" "z10_c")])
8589 (define_insn "*negabs<mode>2_cconly"
8590 [(set (reg CC_REGNUM)
8591 (compare (neg:GPR (abs:GPR (match_operand:GPR 1 "register_operand" "d")))
8593 (clobber (match_scratch:GPR 0 "=d"))]
8594 "s390_match_ccmode (insn, CCAmode)"
8596 [(set_attr "op_type" "RR<E>")
8597 (set_attr "z10prop" "z10_c")])
8600 (define_insn "*negabs<mode>2"
8601 [(set (match_operand:GPR 0 "register_operand" "=d")
8602 (neg:GPR (abs:GPR (match_operand:GPR 1 "register_operand" "d"))))
8603 (clobber (reg:CC CC_REGNUM))]
8606 [(set_attr "op_type" "RR<E>")
8607 (set_attr "z10prop" "z10_c")])
8613 ; lnxbr, lndbr, lnebr
8614 (define_insn "*negabs<mode>2_cc"
8615 [(set (reg CC_REGNUM)
8616 (compare (neg:BFP (abs:BFP (match_operand:BFP 1 "register_operand" "f")))
8617 (match_operand:BFP 2 "const0_operand" "")))
8618 (set (match_operand:BFP 0 "register_operand" "=f")
8619 (neg:BFP (abs:BFP (match_dup 1))))]
8620 "s390_match_ccmode (insn, CCSmode) && TARGET_HARD_FLOAT"
8622 [(set_attr "op_type" "RRE")
8623 (set_attr "type" "fsimp<mode>")])
8625 ; lnxbr, lndbr, lnebr
8626 (define_insn "*negabs<mode>2_cconly"
8627 [(set (reg CC_REGNUM)
8628 (compare (neg:BFP (abs:BFP (match_operand:BFP 1 "register_operand" "f")))
8629 (match_operand:BFP 2 "const0_operand" "")))
8630 (clobber (match_scratch:BFP 0 "=f"))]
8631 "s390_match_ccmode (insn, CCSmode) && TARGET_HARD_FLOAT"
8633 [(set_attr "op_type" "RRE")
8634 (set_attr "type" "fsimp<mode>")])
8637 (define_insn "*negabs<mode>2_nocc"
8638 [(set (match_operand:FP 0 "register_operand" "=f")
8639 (neg:FP (abs:FP (match_operand:BFP 1 "register_operand" "<fT0>"))))]
8642 [(set_attr "op_type" "RRE")
8643 (set_attr "type" "fsimp<mode>")])
8645 ; lnxbr, lndbr, lnebr
8646 ; FIXME: wflndb does not clobber cc
8647 (define_insn "*negabs<mode>2"
8648 [(set (match_operand:BFP 0 "register_operand" "=f,v")
8649 (neg:BFP (abs:BFP (match_operand:BFP 1 "register_operand" "f,v"))))
8650 (clobber (reg:CC CC_REGNUM))]
8655 [(set_attr "op_type" "RRE,VRR")
8656 (set_attr "cpu_facility" "*,vx")
8657 (set_attr "type" "fsimp<mode>,*")
8658 (set_attr "enabled" "*,<DFDI>")])
8661 ;;- Square root instructions.
8665 ; sqrt(df|sf)2 instruction pattern(s).
8668 ; sqxbr, sqdbr, sqebr, sqdb, sqeb
8669 (define_insn "sqrt<mode>2"
8670 [(set (match_operand:BFP 0 "register_operand" "=f,f,v")
8671 (sqrt:BFP (match_operand:BFP 1 "general_operand" "f,R,v")))]
8677 [(set_attr "op_type" "RRE,RXE,VRR")
8678 (set_attr "type" "fsqrt<mode>")
8679 (set_attr "cpu_facility" "*,*,vx")
8680 (set_attr "enabled" "*,<DSF>,<DFDI>")])
8684 ;;- One complement instructions.
8688 ; one_cmpl(di|si|hi|qi)2 instruction pattern(s).
8691 (define_expand "one_cmpl<mode>2"
8693 [(set (match_operand:INT 0 "register_operand" "")
8694 (xor:INT (match_operand:INT 1 "register_operand" "")
8696 (clobber (reg:CC CC_REGNUM))])]
8702 ;; Find leftmost bit instructions.
8705 (define_expand "clzdi2"
8706 [(set (match_operand:DI 0 "register_operand" "=d")
8707 (clz:DI (match_operand:DI 1 "register_operand" "d")))]
8708 "TARGET_EXTIMM && TARGET_ZARCH"
8712 rtx wide_reg = gen_reg_rtx (TImode);
8713 rtx msb = gen_rtx_CONST_INT (DImode, HOST_WIDE_INT_1U << 63);
8715 clz_equal = gen_rtx_CLZ (DImode, operands[1]);
8717 emit_insn (gen_clztidi2 (wide_reg, operands[1], msb));
8719 insn = emit_move_insn (operands[0], gen_highpart (DImode, wide_reg));
8720 set_unique_reg_note (insn, REG_EQUAL, clz_equal);
8725 (define_insn "clztidi2"
8726 [(set (match_operand:TI 0 "register_operand" "=d")
8730 (xor:DI (match_operand:DI 1 "register_operand" "d")
8731 (lshiftrt (match_operand:DI 2 "const_int_operand" "")
8732 (subreg:SI (clz:DI (match_dup 1)) 4))))
8735 (zero_extend:TI (clz:DI (match_dup 1)))))
8736 (clobber (reg:CC CC_REGNUM))]
8737 "UINTVAL (operands[2]) == HOST_WIDE_INT_1U << 63
8738 && TARGET_EXTIMM && TARGET_ZARCH"
8740 [(set_attr "op_type" "RRE")])
8744 ;;- Rotate instructions.
8748 ; rotl(di|si)3 instruction pattern(s).
8751 (define_expand "rotl<mode>3"
8752 [(set (match_operand:GPR 0 "register_operand" "")
8753 (rotate:GPR (match_operand:GPR 1 "register_operand" "")
8754 (match_operand:SI 2 "nonmemory_operand" "")))]
8759 (define_insn "*rotl<mode>3<addr_style_op><masked_op>"
8760 [(set (match_operand:GPR 0 "register_operand" "=d")
8761 (rotate:GPR (match_operand:GPR 1 "register_operand" "d")
8762 (match_operand:SI 2 "nonmemory_operand" "an")))]
8764 "rll<g>\t%0,%1,<addr_style_op_ops>"
8765 [(set_attr "op_type" "RSE")
8766 (set_attr "atype" "reg")
8767 (set_attr "z10prop" "z10_super_E1")])
8771 ;;- Shift instructions.
8775 ; (ashl|lshr)(di|si)3 instruction pattern(s).
8776 ; Left shifts and logical right shifts
8778 (define_expand "<shift><mode>3"
8779 [(set (match_operand:DSI 0 "register_operand" "")
8780 (SHIFT:DSI (match_operand:DSI 1 "register_operand" "")
8781 (match_operand:SI 2 "nonmemory_operand" "")))]
8785 ; ESA 64 bit register pair shift with reg or imm shift count
8787 (define_insn "*<shift>di3_31<addr_style_op><masked_op>"
8788 [(set (match_operand:DI 0 "register_operand" "=d")
8789 (SHIFT:DI (match_operand:DI 1 "register_operand" "0")
8790 (match_operand:SI 2 "nonmemory_operand" "an")))]
8792 "s<lr>dl\t%0,<addr_style_op_ops>"
8793 [(set_attr "op_type" "RS")
8794 (set_attr "atype" "reg")
8795 (set_attr "z196prop" "z196_cracked")])
8798 ; 64 bit register shift with reg or imm shift count
8799 ; sll, srl, sllg, srlg, sllk, srlk
8800 (define_insn "*<shift><mode>3<addr_style_op><masked_op>"
8801 [(set (match_operand:GPR 0 "register_operand" "=d, d")
8802 (SHIFT:GPR (match_operand:GPR 1 "register_operand" "<d0>, d")
8803 (match_operand:SI 2 "nonmemory_operand" "an,an")))]
8806 s<lr>l<g>\t%0,<1><addr_style_op_ops>
8807 s<lr>l<gk>\t%0,%1,<addr_style_op_ops>"
8808 [(set_attr "op_type" "RS<E>,RSY")
8809 (set_attr "atype" "reg,reg")
8810 (set_attr "cpu_facility" "*,z196")
8811 (set_attr "z10prop" "z10_super_E1,*")])
8814 ; ashr(di|si)3 instruction pattern(s).
8815 ; Arithmetic right shifts
8817 (define_expand "ashr<mode>3"
8819 [(set (match_operand:DSI 0 "register_operand" "")
8820 (ashiftrt:DSI (match_operand:DSI 1 "register_operand" "")
8821 (match_operand:SI 2 "nonmemory_operand" "")))
8822 (clobber (reg:CC CC_REGNUM))])]
8826 ; FIXME: The number of alternatives is doubled here to match the fix
8827 ; number of 2 in the subst pattern for the (clobber (match_scratch...
8828 ; The right fix should be to support match_scratch in the output
8829 ; pattern of a define_subst.
8830 (define_insn "*ashrdi3_31<addr_style_op_cc><masked_op_cc><setcc><cconly>"
8831 [(set (match_operand:DI 0 "register_operand" "=d, d")
8832 (ashiftrt:DI (match_operand:DI 1 "register_operand" "0, 0")
8833 (match_operand:SI 2 "nonmemory_operand" "an,an")))
8834 (clobber (reg:CC CC_REGNUM))]
8837 srda\t%0,<addr_style_op_cc_ops>
8838 srda\t%0,<addr_style_op_cc_ops>"
8839 [(set_attr "op_type" "RS")
8840 (set_attr "atype" "reg")])
8844 (define_insn "*ashr<mode>3<addr_style_op_cc><masked_op_cc><setcc><cconly>"
8845 [(set (match_operand:GPR 0 "register_operand" "=d, d")
8846 (ashiftrt:GPR (match_operand:GPR 1 "register_operand" "<d0>, d")
8847 (match_operand:SI 2 "nonmemory_operand" "an,an")))
8848 (clobber (reg:CC CC_REGNUM))]
8851 sra<g>\t%0,<1><addr_style_op_cc_ops>
8852 sra<gk>\t%0,%1,<addr_style_op_cc_ops>"
8853 [(set_attr "op_type" "RS<E>,RSY")
8854 (set_attr "atype" "reg")
8855 (set_attr "cpu_facility" "*,z196")
8856 (set_attr "z10prop" "z10_super_E1,*")])
8860 ;; Branch instruction patterns.
8863 (define_expand "cbranch<mode>4"
8865 (if_then_else (match_operator 0 "comparison_operator"
8866 [(match_operand:GPR 1 "register_operand" "")
8867 (match_operand:GPR 2 "general_operand" "")])
8868 (label_ref (match_operand 3 "" ""))
8871 "s390_emit_jump (operands[3],
8872 s390_emit_compare (GET_CODE (operands[0]), operands[1], operands[2]));
8875 (define_expand "cbranch<mode>4"
8877 (if_then_else (match_operator 0 "comparison_operator"
8878 [(match_operand:FP 1 "register_operand" "")
8879 (match_operand:FP 2 "general_operand" "")])
8880 (label_ref (match_operand 3 "" ""))
8883 "s390_emit_jump (operands[3],
8884 s390_emit_compare (GET_CODE (operands[0]), operands[1], operands[2]));
8887 (define_expand "cbranchcc4"
8889 (if_then_else (match_operator 0 "s390_comparison"
8890 [(match_operand 1 "cc_reg_operand" "")
8891 (match_operand 2 "const_int_operand" "")])
8892 (label_ref (match_operand 3 "" ""))
8899 ;;- Conditional jump instructions.
8902 (define_insn "*cjump_64"
8905 (match_operator 1 "s390_comparison" [(reg CC_REGNUM)
8906 (match_operand 2 "const_int_operand" "")])
8907 (label_ref (match_operand 0 "" ""))
8911 if (get_attr_length (insn) == 4)
8914 return "jg%C1\t%l0";
8916 [(set_attr "op_type" "RI")
8917 (set_attr "type" "branch")
8918 (set (attr "length")
8919 (if_then_else (lt (abs (minus (pc) (match_dup 0))) (const_int 60000))
8920 (const_int 4) (const_int 6)))])
8922 (define_insn "*cjump_long"
8925 (match_operator 1 "s390_comparison" [(reg CC_REGNUM) (const_int 0)])
8926 (match_operand 0 "address_operand" "ZQZR")
8928 "!TARGET_INDIRECT_BRANCH_NOBP_JUMP"
8930 if (get_attr_op_type (insn) == OP_TYPE_RR)
8935 [(set (attr "op_type")
8936 (if_then_else (match_operand 0 "register_operand" "")
8937 (const_string "RR") (const_string "RX")))
8938 (set (attr "mnemonic")
8939 (if_then_else (match_operand 0 "register_operand" "")
8940 (const_string "bcr") (const_string "bc")))
8941 (set_attr "type" "branch")
8942 (set_attr "atype" "agen")])
8944 ;; A conditional return instruction.
8945 (define_insn "*c<code>"
8948 (match_operator 0 "s390_comparison" [(reg CC_REGNUM) (const_int 0)])
8951 "s390_can_use_<code>_insn ()"
8953 if (TARGET_INDIRECT_BRANCH_NOBP_RET)
8955 s390_indirect_branch_via_thunk (RETURN_REGNUM,
8958 s390_indirect_branch_type_return);
8962 return "b%C0r\t%%r14";
8964 [(set (attr "op_type")
8965 (if_then_else (match_test "TARGET_INDIRECT_BRANCH_NOBP_RET")
8966 (const_string "RIL")
8967 (const_string "RR")))
8968 (set (attr "mnemonic")
8969 (if_then_else (match_test "TARGET_INDIRECT_BRANCH_NOBP_RET")
8970 (const_string "brcl")
8971 (const_string "bcr")))
8972 (set_attr "type" "jsr")
8973 (set_attr "atype" "agen")])
8976 ;;- Negated conditional jump instructions.
8979 (define_insn "*icjump_64"
8982 (match_operator 1 "s390_comparison" [(reg CC_REGNUM) (const_int 0)])
8984 (label_ref (match_operand 0 "" ""))))]
8987 if (get_attr_length (insn) == 4)
8990 return "jg%D1\t%l0";
8992 [(set_attr "op_type" "RI")
8993 (set_attr "type" "branch")
8994 (set (attr "length")
8995 (if_then_else (lt (abs (minus (pc) (match_dup 0))) (const_int 60000))
8996 (const_int 4) (const_int 6)))])
8998 (define_insn "*icjump_long"
9001 (match_operator 1 "s390_comparison" [(reg CC_REGNUM) (const_int 0)])
9003 (match_operand 0 "address_operand" "ZQZR")))]
9004 "!TARGET_INDIRECT_BRANCH_NOBP_JUMP"
9006 if (get_attr_op_type (insn) == OP_TYPE_RR)
9011 [(set (attr "op_type")
9012 (if_then_else (match_operand 0 "register_operand" "")
9013 (const_string "RR") (const_string "RX")))
9014 (set (attr "mnemonic")
9015 (if_then_else (match_operand 0 "register_operand" "")
9016 (const_string "bcr") (const_string "bc")))
9017 (set_attr "type" "branch")
9018 (set_attr "atype" "agen")])
9021 ;;- Trap instructions.
9025 [(trap_if (const_int 1) (const_int 0))]
9028 [(set_attr "op_type" "RI")
9029 (set_attr "type" "branch")])
9031 (define_expand "ctrap<mode>4"
9032 [(trap_if (match_operator 0 "comparison_operator"
9033 [(match_operand:GPR 1 "register_operand" "")
9034 (match_operand:GPR 2 "general_operand" "")])
9035 (match_operand 3 "const0_operand" ""))]
9038 rtx cond = s390_emit_compare (GET_CODE (operands[0]),
9039 operands[1], operands[2]);
9040 emit_insn (gen_condtrap (cond, XEXP (cond, 0)));
9044 (define_expand "ctrap<mode>4"
9045 [(trap_if (match_operator 0 "comparison_operator"
9046 [(match_operand:FP 1 "register_operand" "")
9047 (match_operand:FP 2 "general_operand" "")])
9048 (match_operand 3 "const0_operand" ""))]
9051 rtx cond = s390_emit_compare (GET_CODE (operands[0]),
9052 operands[1], operands[2]);
9053 emit_insn (gen_condtrap (cond, XEXP (cond, 0)));
9057 (define_insn "condtrap"
9058 [(trap_if (match_operator 0 "s390_comparison"
9059 [(match_operand 1 "cc_reg_operand" "c")
9064 [(set_attr "op_type" "RI")
9065 (set_attr "type" "branch")])
9067 ; crt, cgrt, cit, cgit
9068 (define_insn "*cmp_and_trap_signed_int<mode>"
9069 [(trap_if (match_operator 0 "s390_signed_integer_comparison"
9070 [(match_operand:GPR 1 "register_operand" "d,d")
9071 (match_operand:GPR 2 "nonmemory_operand" "d,K")])
9077 [(set_attr "op_type" "RRF,RIE")
9078 (set_attr "type" "branch")
9079 (set_attr "z10prop" "z10_super_c,z10_super")])
9081 ; clrt, clgrt, clfit, clgit, clt, clgt
9082 (define_insn "*cmp_and_trap_unsigned_int<mode>"
9083 [(trap_if (match_operator 0 "s390_unsigned_integer_comparison"
9084 [(match_operand:GPR 1 "register_operand" "d,d,d")
9085 (match_operand:GPR 2 "general_operand" "d,D,T")])
9092 [(set_attr "op_type" "RRF,RIE,RSY")
9093 (set_attr "type" "branch")
9094 (set_attr "z10prop" "z10_super_c,z10_super,*")
9095 (set_attr "cpu_facility" "z10,z10,zEC12")])
9098 (define_insn "*load_and_trap<mode>"
9099 [(trap_if (eq (match_operand:GPR 0 "memory_operand" "T")
9102 (set (match_operand:GPR 1 "register_operand" "=d")
9106 [(set_attr "op_type" "RXY")])
9110 ;;- Loop instructions.
9112 ;; This is all complicated by the fact that since this is a jump insn
9113 ;; we must handle our own output reloads.
9117 ; This splitter will be matched by combine and has to add the 2 moves
9118 ; necessary to load the compare and the increment values into a
9119 ; register pair as needed by brxle.
9121 (define_insn_and_split "*brx_stage1_<GPR:mode>"
9124 (match_operator 6 "s390_brx_operator"
9125 [(plus:GPR (match_operand:GPR 1 "register_operand" "")
9126 (match_operand:GPR 2 "general_operand" ""))
9127 (match_operand:GPR 3 "register_operand" "")])
9128 (label_ref (match_operand 0 "" ""))
9130 (set (match_operand:GPR 4 "nonimmediate_operand" "")
9131 (plus:GPR (match_dup 1) (match_dup 2)))
9132 (clobber (match_scratch:GPR 5 ""))]
9135 "!reload_completed && !reload_in_progress"
9136 [(set (match_dup 7) (match_dup 2)) ; the increment
9137 (set (match_dup 8) (match_dup 3)) ; the comparison value
9138 (parallel [(set (pc)
9141 [(plus:GPR (match_dup 1) (match_dup 7))
9143 (label_ref (match_dup 0))
9146 (plus:GPR (match_dup 1) (match_dup 7)))
9147 (clobber (match_dup 5))
9148 (clobber (reg:CC CC_REGNUM))])]
9150 rtx dreg = gen_reg_rtx (word_mode == DImode ? TImode : DImode);
9151 operands[7] = gen_lowpart (<GPR:MODE>mode,
9152 gen_highpart (word_mode, dreg));
9153 operands[8] = gen_lowpart (<GPR:MODE>mode,
9154 gen_lowpart (word_mode, dreg));
9159 (define_insn_and_split "*brxg_64bit"
9162 (match_operator 5 "s390_brx_operator"
9163 [(plus:DI (match_operand:DI 1 "register_operand" "d,d,d")
9164 (subreg:DI (match_operand:TI 2 "register_operand" "d,d,d") 0))
9165 (subreg:DI (match_dup 2) 8)])
9166 (label_ref (match_operand 0 "" ""))
9168 (set (match_operand:DI 3 "nonimmediate_operand" "=1,?X,?X")
9169 (plus:DI (match_dup 1)
9170 (subreg:DI (match_dup 2) 0)))
9171 (clobber (match_scratch:DI 4 "=X,&1,&?d"))
9172 (clobber (reg:CC CC_REGNUM))]
9175 if (which_alternative != 0)
9177 else if (get_attr_length (insn) == 6)
9178 return "brx%E5g\t%1,%2,%l0";
9180 return "agr\t%1,%2\;cgr\t%1,%M2\;jg%C5\t%l0";
9182 "&& reload_completed
9183 && (!REG_P (operands[3])
9184 || !rtx_equal_p (operands[1], operands[3]))"
9185 [(set (match_dup 4) (match_dup 1))
9186 (parallel [(set (match_dup 4) (plus:DI (match_dup 4) (subreg:DI (match_dup 2) 0)))
9187 (clobber (reg:CC CC_REGNUM))])
9188 (set (reg:CCS CC_REGNUM) (compare:CCS (match_dup 4) (subreg:DI (match_dup 2) 8)))
9189 (set (match_dup 3) (match_dup 4))
9190 (set (pc) (if_then_else (match_op_dup 5 [(reg:CCS CC_REGNUM) (const_int 0)])
9191 (label_ref (match_dup 0))
9194 [(set_attr "op_type" "RIE")
9195 (set_attr "type" "branch")
9196 (set (attr "length")
9197 (if_then_else (lt (abs (minus (pc) (match_dup 0))) (const_int 60000))
9198 (const_int 6) (const_int 16)))])
9202 (define_insn_and_split "*brx_64bit"
9205 (match_operator 5 "s390_brx_operator"
9206 [(plus:SI (match_operand:SI 1 "register_operand" "d,d,d")
9207 (subreg:SI (match_operand:TI 2 "register_operand" "d,d,d") 4))
9208 (subreg:SI (match_dup 2) 12)])
9209 (label_ref (match_operand 0 "" ""))
9211 (set (match_operand:SI 3 "nonimmediate_operand" "=1,?X,?X")
9212 (plus:SI (match_dup 1)
9213 (subreg:SI (match_dup 2) 4)))
9214 (clobber (match_scratch:SI 4 "=X,&1,&?d"))
9215 (clobber (reg:CC CC_REGNUM))]
9218 if (which_alternative != 0)
9220 else if (get_attr_length (insn) == 6)
9221 return "brx%C5\t%1,%2,%l0";
9223 return "ar\t%1,%2\;cr\t%1,%M2\;jg%C5\t%l0";
9225 "&& reload_completed
9226 && (!REG_P (operands[3])
9227 || !rtx_equal_p (operands[1], operands[3]))"
9228 [(set (match_dup 4) (match_dup 1))
9229 (parallel [(set (match_dup 4) (plus:SI (match_dup 4) (subreg:SI (match_dup 2) 4)))
9230 (clobber (reg:CC CC_REGNUM))])
9231 (set (reg:CCS CC_REGNUM) (compare:CCS (match_dup 4) (subreg:SI (match_dup 2) 12)))
9232 (set (match_dup 3) (match_dup 4))
9233 (set (pc) (if_then_else (match_op_dup 5 [(reg:CCS CC_REGNUM) (const_int 0)])
9234 (label_ref (match_dup 0))
9237 [(set_attr "op_type" "RSI")
9238 (set_attr "type" "branch")
9239 (set (attr "length")
9240 (if_then_else (lt (abs (minus (pc) (match_dup 0))) (const_int 60000))
9241 (const_int 6) (const_int 14)))])
9245 (define_insn_and_split "*brx_31bit"
9248 (match_operator 5 "s390_brx_operator"
9249 [(plus:SI (match_operand:SI 1 "register_operand" "d,d,d")
9250 (subreg:SI (match_operand:DI 2 "register_operand" "d,d,d") 0))
9251 (subreg:SI (match_dup 2) 4)])
9252 (label_ref (match_operand 0 "" ""))
9254 (set (match_operand:SI 3 "nonimmediate_operand" "=1,?X,?X")
9255 (plus:SI (match_dup 1)
9256 (subreg:SI (match_dup 2) 0)))
9257 (clobber (match_scratch:SI 4 "=X,&1,&?d"))
9258 (clobber (reg:CC CC_REGNUM))]
9261 if (which_alternative != 0)
9263 else if (get_attr_length (insn) == 6)
9264 return "brx%C5\t%1,%2,%l0";
9266 return "ar\t%1,%2\;cr\t%1,%M2\;jg%C5\t%l0";
9268 "&& reload_completed
9269 && (!REG_P (operands[3])
9270 || !rtx_equal_p (operands[1], operands[3]))"
9271 [(set (match_dup 4) (match_dup 1))
9272 (parallel [(set (match_dup 4) (plus:SI (match_dup 4) (subreg:SI (match_dup 2) 0)))
9273 (clobber (reg:CC CC_REGNUM))])
9274 (set (reg:CCS CC_REGNUM) (compare:CCS (match_dup 4) (subreg:SI (match_dup 2) 4)))
9275 (set (match_dup 3) (match_dup 4))
9276 (set (pc) (if_then_else (match_op_dup 5 [(reg:CCS CC_REGNUM) (const_int 0)])
9277 (label_ref (match_dup 0))
9280 [(set_attr "op_type" "RSI")
9281 (set_attr "type" "branch")
9282 (set (attr "length")
9283 (if_then_else (lt (abs (minus (pc) (match_dup 0))) (const_int 60000))
9284 (const_int 6) (const_int 14)))])
9289 (define_expand "doloop_end"
9290 [(use (match_operand 0 "" "")) ; loop pseudo
9291 (use (match_operand 1 "" ""))] ; label
9294 if (GET_MODE (operands[0]) == SImode)
9295 emit_jump_insn (gen_doloop_si64 (operands[1], operands[0], operands[0]));
9296 else if (GET_MODE (operands[0]) == DImode && TARGET_ZARCH)
9297 emit_jump_insn (gen_doloop_di (operands[1], operands[0], operands[0]));
9304 (define_insn_and_split "doloop_si64"
9307 (ne (match_operand:SI 1 "register_operand" "d,d,d")
9309 (label_ref (match_operand 0 "" ""))
9311 (set (match_operand:SI 2 "nonimmediate_operand" "=1,?X,?X")
9312 (plus:SI (match_dup 1) (const_int -1)))
9313 (clobber (match_scratch:SI 3 "=X,&1,&?d"))
9314 (clobber (reg:CC CC_REGNUM))]
9317 if (which_alternative != 0)
9319 else if (get_attr_length (insn) == 4)
9320 return "brct\t%1,%l0";
9322 return "ahi\t%1,-1\;jgne\t%l0";
9324 "&& reload_completed
9325 && (! REG_P (operands[2])
9326 || ! rtx_equal_p (operands[1], operands[2]))"
9327 [(set (match_dup 3) (match_dup 1))
9328 (parallel [(set (reg:CCAN CC_REGNUM)
9329 (compare:CCAN (plus:SI (match_dup 3) (const_int -1))
9331 (set (match_dup 3) (plus:SI (match_dup 3) (const_int -1)))])
9332 (set (match_dup 2) (match_dup 3))
9333 (set (pc) (if_then_else (ne (reg:CCAN CC_REGNUM) (const_int 0))
9334 (label_ref (match_dup 0))
9337 [(set_attr "op_type" "RI")
9338 ; Strictly speaking, the z10 properties are valid for brct only, however, it does not
9339 ; hurt us in the (rare) case of ahi.
9340 (set_attr "z10prop" "z10_super_E1")
9341 (set_attr "type" "branch")
9342 (set (attr "length")
9343 (if_then_else (lt (abs (minus (pc) (match_dup 0))) (const_int 60000))
9344 (const_int 4) (const_int 10)))])
9346 (define_insn_and_split "doloop_di"
9349 (ne (match_operand:DI 1 "register_operand" "d,d,d")
9351 (label_ref (match_operand 0 "" ""))
9353 (set (match_operand:DI 2 "nonimmediate_operand" "=1,?X,?X")
9354 (plus:DI (match_dup 1) (const_int -1)))
9355 (clobber (match_scratch:DI 3 "=X,&1,&?d"))
9356 (clobber (reg:CC CC_REGNUM))]
9359 if (which_alternative != 0)
9361 else if (get_attr_length (insn) == 4)
9362 return "brctg\t%1,%l0";
9364 return "aghi\t%1,-1\;jgne\t%l0";
9366 "&& reload_completed
9367 && (! REG_P (operands[2])
9368 || ! rtx_equal_p (operands[1], operands[2]))"
9369 [(set (match_dup 3) (match_dup 1))
9370 (parallel [(set (reg:CCAN CC_REGNUM)
9371 (compare:CCAN (plus:DI (match_dup 3) (const_int -1))
9373 (set (match_dup 3) (plus:DI (match_dup 3) (const_int -1)))])
9374 (set (match_dup 2) (match_dup 3))
9375 (set (pc) (if_then_else (ne (reg:CCAN CC_REGNUM) (const_int 0))
9376 (label_ref (match_dup 0))
9379 [(set_attr "op_type" "RI")
9380 ; Strictly speaking, the z10 properties are valid for brct only, however, it does not
9381 ; hurt us in the (rare) case of ahi.
9382 (set_attr "z10prop" "z10_super_E1")
9383 (set_attr "type" "branch")
9384 (set (attr "length")
9385 (if_then_else (lt (abs (minus (pc) (match_dup 0))) (const_int 60000))
9386 (const_int 4) (const_int 10)))])
9389 ;;- Unconditional jump instructions.
9393 ; jump instruction pattern(s).
9396 (define_expand "jump"
9397 [(match_operand 0 "" "")]
9399 "s390_emit_jump (operands[0], NULL_RTX); DONE;")
9401 (define_insn "*jump64"
9402 [(set (pc) (label_ref (match_operand 0 "" "")))]
9405 if (get_attr_length (insn) == 4)
9410 [(set_attr "op_type" "RI")
9411 (set_attr "type" "branch")
9412 (set (attr "length")
9413 (if_then_else (lt (abs (minus (pc) (match_dup 0))) (const_int 60000))
9414 (const_int 4) (const_int 6)))])
9417 ; indirect-jump instruction pattern(s).
9420 (define_expand "indirect_jump"
9421 [(set (pc) (match_operand 0 "nonimmediate_operand" ""))]
9424 if (address_operand (operands[0], GET_MODE (operands[0])))
9427 && GET_MODE (operands[0]) == Pmode
9428 && memory_operand (operands[0], Pmode))
9431 operands[0] = force_reg (Pmode, operands[0]);
9433 if (TARGET_INDIRECT_BRANCH_NOBP_JUMP_THUNK)
9435 operands[0] = force_reg (Pmode, operands[0]);
9439 emit_jump_insn (gen_indirect_jump_via_thunkdi_z10 (operands[0]));
9441 emit_jump_insn (gen_indirect_jump_via_thunksi_z10 (operands[0]));
9446 emit_jump_insn (gen_indirect_jump_via_thunkdi (operands[0]));
9448 emit_jump_insn (gen_indirect_jump_via_thunksi (operands[0]));
9453 if (TARGET_INDIRECT_BRANCH_NOBP_JUMP_INLINE_THUNK)
9455 operands[0] = force_reg (Pmode, operands[0]);
9456 rtx label_ref = gen_rtx_LABEL_REF (VOIDmode, gen_label_rtx ());
9460 emit_jump_insn (gen_indirect_jump_via_inlinethunkdi_z10 (operands[0],
9463 emit_jump_insn (gen_indirect_jump_via_inlinethunksi_z10 (operands[0],
9469 emit_jump_insn (gen_indirect_jump_via_inlinethunkdi (operands[0],
9471 force_reg (Pmode, label_ref)));
9473 emit_jump_insn (gen_indirect_jump_via_inlinethunksi (operands[0],
9475 force_reg (Pmode, label_ref)));
9481 (define_insn "*indirect_jump"
9483 (match_operand 0 "address_operand" "ZR"))]
9484 "!TARGET_INDIRECT_BRANCH_NOBP_JUMP_THUNK"
9486 if (get_attr_op_type (insn) == OP_TYPE_RR)
9491 [(set (attr "op_type")
9492 (if_then_else (match_operand 0 "register_operand" "")
9493 (const_string "RR") (const_string "RX")))
9494 (set (attr "mnemonic")
9495 (if_then_else (match_operand 0 "register_operand" "")
9496 (const_string "br") (const_string "b")))
9497 (set_attr "type" "branch")
9498 (set_attr "atype" "agen")])
9500 (define_insn "indirect_jump_via_thunk<mode>_z10"
9502 (match_operand:P 0 "register_operand" "a"))]
9503 "TARGET_INDIRECT_BRANCH_NOBP_JUMP_THUNK
9506 s390_indirect_branch_via_thunk (REGNO (operands[0]),
9509 s390_indirect_branch_type_jump);
9512 [(set_attr "op_type" "RIL")
9513 (set_attr "mnemonic" "jg")
9514 (set_attr "type" "branch")
9515 (set_attr "atype" "agen")])
9517 (define_insn "indirect_jump_via_thunk<mode>"
9519 (match_operand:P 0 "register_operand" " a"))
9520 (clobber (reg:P INDIRECT_BRANCH_THUNK_REGNUM))]
9521 "TARGET_INDIRECT_BRANCH_NOBP_JUMP_THUNK
9524 s390_indirect_branch_via_thunk (REGNO (operands[0]),
9527 s390_indirect_branch_type_jump);
9530 [(set_attr "op_type" "RIL")
9531 (set_attr "mnemonic" "jg")
9532 (set_attr "type" "branch")
9533 (set_attr "atype" "agen")])
9536 ; The label_ref is wrapped into an if_then_else in order to hide it
9537 ; from mark_jump_label. Without this the label_ref would become the
9538 ; ONLY jump target of that jump breaking the control flow graph.
9539 (define_insn "indirect_jump_via_inlinethunk<mode>_z10"
9540 [(unspec [(if_then_else (match_operand:P 1 "larl_operand" "X")
9543 (const_int 0)] UNSPEC_EXECUTE_JUMP)
9544 (set (pc) (match_operand:P 0 "register_operand" "a"))]
9545 "TARGET_INDIRECT_BRANCH_NOBP_JUMP_INLINE_THUNK
9548 s390_indirect_branch_via_inline_thunk (operands[1]);
9551 [(set_attr "op_type" "RIL")
9552 (set_attr "type" "branch")
9553 (set_attr "length" "10")])
9555 (define_insn "indirect_jump_via_inlinethunk<mode>"
9556 [(unspec [(if_then_else (match_operand:P 1 "larl_operand" "X")
9559 (match_operand:P 2 "register_operand" "a")] UNSPEC_EXECUTE_JUMP)
9560 (set (pc) (match_operand:P 0 "register_operand" "a"))]
9561 "TARGET_INDIRECT_BRANCH_NOBP_JUMP_INLINE_THUNK
9564 s390_indirect_branch_via_inline_thunk (operands[2]);
9567 [(set_attr "op_type" "RX")
9568 (set_attr "type" "branch")
9569 (set_attr "length" "8")])
9571 ; FIXME: LRA does not appear to be able to deal with MEMs being
9572 ; checked against address constraints like ZR above. So make this a
9573 ; separate pattern for now.
9574 (define_insn "*indirect2_jump"
9576 (match_operand 0 "nonimmediate_operand" "a,T"))]
9577 "!TARGET_INDIRECT_BRANCH_NOBP_JUMP"
9581 [(set_attr "op_type" "RR,RXY")
9582 (set_attr "type" "branch")
9583 (set_attr "atype" "agen")
9584 (set_attr "cpu_facility" "*,z14")])
9587 ; casesi instruction pattern(s).
9590 (define_expand "casesi_jump"
9592 [(set (pc) (match_operand 0 "address_operand"))
9593 (use (label_ref (match_operand 1 "")))])]
9596 if (TARGET_INDIRECT_BRANCH_NOBP_JUMP_THUNK)
9598 operands[0] = force_reg (GET_MODE (operands[0]), operands[0]);
9603 emit_jump_insn (gen_casesi_jump_via_thunkdi_z10 (operands[0],
9606 emit_jump_insn (gen_casesi_jump_via_thunksi_z10 (operands[0],
9612 emit_jump_insn (gen_casesi_jump_via_thunkdi (operands[0],
9615 emit_jump_insn (gen_casesi_jump_via_thunksi (operands[0],
9621 if (TARGET_INDIRECT_BRANCH_NOBP_JUMP_INLINE_THUNK)
9623 operands[0] = force_reg (Pmode, operands[0]);
9624 rtx label_ref = gen_rtx_LABEL_REF (VOIDmode, gen_label_rtx ());
9628 emit_jump_insn (gen_casesi_jump_via_inlinethunkdi_z10 (operands[0],
9632 emit_jump_insn (gen_casesi_jump_via_inlinethunksi_z10 (operands[0],
9639 emit_jump_insn (gen_casesi_jump_via_inlinethunkdi (operands[0],
9642 force_reg (Pmode, label_ref)));
9644 emit_jump_insn (gen_casesi_jump_via_inlinethunksi (operands[0],
9647 force_reg (Pmode, label_ref)));
9653 (define_insn "*casesi_jump"
9654 [(set (pc) (match_operand 0 "address_operand" "ZR"))
9655 (use (label_ref (match_operand 1 "" "")))]
9656 "!TARGET_INDIRECT_BRANCH_NOBP_JUMP_THUNK"
9658 if (get_attr_op_type (insn) == OP_TYPE_RR)
9663 [(set (attr "op_type")
9664 (if_then_else (match_operand 0 "register_operand" "")
9665 (const_string "RR") (const_string "RX")))
9666 (set (attr "mnemonic")
9667 (if_then_else (match_operand 0 "register_operand" "")
9668 (const_string "br") (const_string "b")))
9669 (set_attr "type" "branch")
9670 (set_attr "atype" "agen")])
9672 (define_insn "casesi_jump_via_thunk<mode>_z10"
9673 [(set (pc) (match_operand:P 0 "register_operand" "a"))
9674 (use (label_ref (match_operand 1 "" "")))]
9675 "TARGET_INDIRECT_BRANCH_NOBP_JUMP_THUNK
9678 s390_indirect_branch_via_thunk (REGNO (operands[0]),
9681 s390_indirect_branch_type_jump);
9684 [(set_attr "op_type" "RIL")
9685 (set_attr "mnemonic" "jg")
9686 (set_attr "type" "branch")
9687 (set_attr "atype" "agen")])
9689 (define_insn "casesi_jump_via_thunk<mode>"
9690 [(set (pc) (match_operand:P 0 "register_operand" "a"))
9691 (use (label_ref (match_operand 1 "" "")))
9692 (clobber (reg:P INDIRECT_BRANCH_THUNK_REGNUM))]
9693 "TARGET_INDIRECT_BRANCH_NOBP_JUMP_THUNK
9696 s390_indirect_branch_via_thunk (REGNO (operands[0]),
9699 s390_indirect_branch_type_jump);
9702 [(set_attr "op_type" "RIL")
9703 (set_attr "mnemonic" "jg")
9704 (set_attr "type" "branch")
9705 (set_attr "atype" "agen")])
9708 ; The label_ref is wrapped into an if_then_else in order to hide it
9709 ; from mark_jump_label. Without this the label_ref would become the
9710 ; ONLY jump target of that jump breaking the control flow graph.
9711 (define_insn "casesi_jump_via_inlinethunk<mode>_z10"
9712 [(unspec [(if_then_else (match_operand:P 2 "larl_operand" "X")
9715 (const_int 0)] UNSPEC_EXECUTE_JUMP)
9716 (set (pc) (match_operand:P 0 "register_operand" "a"))
9717 (use (label_ref (match_operand 1 "" "")))]
9718 "TARGET_INDIRECT_BRANCH_NOBP_JUMP_INLINE_THUNK
9721 s390_indirect_branch_via_inline_thunk (operands[2]);
9724 [(set_attr "op_type" "RIL")
9725 (set_attr "type" "cs")
9726 (set_attr "length" "10")])
9728 (define_insn "casesi_jump_via_inlinethunk<mode>"
9729 [(unspec [(if_then_else (match_operand:P 2 "larl_operand" "X")
9732 (match_operand:P 3 "register_operand" "a")] UNSPEC_EXECUTE_JUMP)
9733 (set (pc) (match_operand:P 0 "register_operand" "a"))
9734 (use (label_ref (match_operand 1 "" "")))]
9735 "TARGET_INDIRECT_BRANCH_NOBP_JUMP_INLINE_THUNK
9738 s390_indirect_branch_via_inline_thunk (operands[3]);
9741 [(set_attr "op_type" "RX")
9742 (set_attr "type" "cs")
9743 (set_attr "length" "8")])
9745 (define_expand "casesi"
9746 [(match_operand:SI 0 "general_operand" "")
9747 (match_operand:SI 1 "general_operand" "")
9748 (match_operand:SI 2 "general_operand" "")
9749 (label_ref (match_operand 3 "" ""))
9750 (label_ref (match_operand 4 "" ""))]
9753 rtx index = gen_reg_rtx (SImode);
9754 rtx base = gen_reg_rtx (Pmode);
9755 rtx target = gen_reg_rtx (Pmode);
9757 emit_move_insn (index, operands[0]);
9758 emit_insn (gen_subsi3 (index, index, operands[1]));
9759 emit_cmp_and_jump_insns (index, operands[2], GTU, NULL_RTX, SImode, 1,
9762 if (Pmode != SImode)
9763 index = convert_to_mode (Pmode, index, 1);
9764 if (GET_CODE (index) != REG)
9765 index = copy_to_mode_reg (Pmode, index);
9768 emit_insn (gen_ashldi3 (index, index, GEN_INT (3)));
9770 emit_insn (gen_ashlsi3 (index, index, const2_rtx));
9772 emit_move_insn (base, gen_rtx_LABEL_REF (Pmode, operands[3]));
9774 index = gen_const_mem (Pmode, gen_rtx_PLUS (Pmode, base, index));
9775 emit_move_insn (target, index);
9778 target = gen_rtx_PLUS (Pmode, base, target);
9779 emit_jump_insn (gen_casesi_jump (target, operands[3]));
9786 ;;- Jump to subroutine.
9791 ; untyped call instruction pattern(s).
9794 ;; Call subroutine returning any type.
9795 (define_expand "untyped_call"
9796 [(parallel [(call (match_operand 0 "" "")
9798 (match_operand 1 "" "")
9799 (match_operand 2 "" "")])]
9804 emit_call_insn (gen_call (operands[0], const0_rtx, const0_rtx));
9806 for (i = 0; i < XVECLEN (operands[2], 0); i++)
9808 rtx set = XVECEXP (operands[2], 0, i);
9809 emit_move_insn (SET_DEST (set), SET_SRC (set));
9812 /* The optimizer does not know that the call sets the function value
9813 registers we stored in the result block. We avoid problems by
9814 claiming that all hard registers are used and clobbered at this
9816 emit_insn (gen_blockage ());
9821 ;; UNSPEC_VOLATILE is considered to use and clobber all hard registers and
9822 ;; all of memory. This blocks insns from being moved across this point.
9824 (define_insn "blockage"
9825 [(unspec_volatile [(const_int 0)] UNSPECV_BLOCKAGE)]
9828 [(set_attr "type" "none")
9829 (set_attr "length" "0")])
9835 (define_expand "sibcall"
9836 [(call (match_operand 0 "" "")
9837 (match_operand 1 "" ""))]
9840 s390_emit_call (XEXP (operands[0], 0), NULL_RTX, NULL_RTX, NULL_RTX);
9844 (define_insn "*sibcall_br"
9845 [(call (mem:QI (reg SIBCALL_REGNUM))
9846 (match_operand 0 "const_int_operand" "n"))]
9847 "SIBLING_CALL_P (insn)
9848 && GET_MODE (XEXP (XEXP (PATTERN (insn), 0), 0)) == Pmode"
9850 if (TARGET_INDIRECT_BRANCH_NOBP_CALL)
9852 gcc_assert (TARGET_CPU_Z10);
9853 s390_indirect_branch_via_thunk (SIBCALL_REGNUM,
9856 s390_indirect_branch_type_call);
9862 [(set (attr "op_type")
9863 (if_then_else (match_test "TARGET_INDIRECT_BRANCH_NOBP_CALL")
9864 (const_string "RIL")
9865 (const_string "RR")))
9866 (set (attr "mnemonic")
9867 (if_then_else (match_test "TARGET_INDIRECT_BRANCH_NOBP_CALL")
9869 (const_string "br")))
9870 (set_attr "type" "branch")
9871 (set_attr "atype" "agen")])
9873 (define_insn "*sibcall_brc"
9874 [(call (mem:QI (match_operand 0 "bras_sym_operand" "X"))
9875 (match_operand 1 "const_int_operand" "n"))]
9876 "SIBLING_CALL_P (insn) && TARGET_SMALL_EXEC"
9878 [(set_attr "op_type" "RI")
9879 (set_attr "type" "branch")])
9881 (define_insn "*sibcall_brcl"
9882 [(call (mem:QI (match_operand 0 "bras_sym_operand" "X"))
9883 (match_operand 1 "const_int_operand" "n"))]
9884 "SIBLING_CALL_P (insn)"
9886 [(set_attr "op_type" "RIL")
9887 (set_attr "type" "branch")])
9890 ; sibcall_value patterns
9893 (define_expand "sibcall_value"
9894 [(set (match_operand 0 "" "")
9895 (call (match_operand 1 "" "")
9896 (match_operand 2 "" "")))]
9899 s390_emit_call (XEXP (operands[1], 0), NULL_RTX, operands[0], NULL_RTX);
9903 (define_insn "*sibcall_value_br"
9904 [(set (match_operand 0 "" "")
9905 (call (mem:QI (reg SIBCALL_REGNUM))
9906 (match_operand 1 "const_int_operand" "n")))]
9907 "SIBLING_CALL_P (insn)
9908 && GET_MODE (XEXP (XEXP (XEXP (PATTERN (insn), 1), 0), 0)) == Pmode"
9910 if (TARGET_INDIRECT_BRANCH_NOBP_CALL)
9912 gcc_assert (TARGET_CPU_Z10);
9913 s390_indirect_branch_via_thunk (SIBCALL_REGNUM,
9916 s390_indirect_branch_type_call);
9922 [(set (attr "op_type")
9923 (if_then_else (match_test "TARGET_INDIRECT_BRANCH_NOBP_CALL")
9924 (const_string "RIL")
9925 (const_string "RR")))
9926 (set (attr "mnemonic")
9927 (if_then_else (match_test "TARGET_INDIRECT_BRANCH_NOBP_CALL")
9929 (const_string "br")))
9930 (set_attr "type" "branch")
9931 (set_attr "atype" "agen")])
9933 (define_insn "*sibcall_value_brc"
9934 [(set (match_operand 0 "" "")
9935 (call (mem:QI (match_operand 1 "bras_sym_operand" "X"))
9936 (match_operand 2 "const_int_operand" "n")))]
9937 "SIBLING_CALL_P (insn) && TARGET_SMALL_EXEC"
9939 [(set_attr "op_type" "RI")
9940 (set_attr "type" "branch")])
9942 (define_insn "*sibcall_value_brcl"
9943 [(set (match_operand 0 "" "")
9944 (call (mem:QI (match_operand 1 "bras_sym_operand" "X"))
9945 (match_operand 2 "const_int_operand" "n")))]
9946 "SIBLING_CALL_P (insn)"
9948 [(set_attr "op_type" "RIL")
9949 (set_attr "type" "branch")])
9953 ; call instruction pattern(s).
9956 (define_expand "call"
9957 [(call (match_operand 0 "" "")
9958 (match_operand 1 "" ""))
9959 (use (match_operand 2 "" ""))]
9962 s390_emit_call (XEXP (operands[0], 0), NULL_RTX, NULL_RTX,
9963 gen_rtx_REG (Pmode, RETURN_REGNUM));
9967 (define_insn "*bras"
9968 [(call (mem:QI (match_operand 0 "bras_sym_operand" "X"))
9969 (match_operand 1 "const_int_operand" "n"))
9970 (clobber (match_operand 2 "register_operand" "=r"))]
9971 "!SIBLING_CALL_P (insn)
9972 && TARGET_SMALL_EXEC
9973 && GET_MODE (operands[2]) == Pmode"
9975 [(set_attr "op_type" "RI")
9976 (set_attr "type" "jsr")
9977 (set_attr "z196prop" "z196_cracked")])
9979 (define_insn "*brasl"
9980 [(call (mem:QI (match_operand 0 "bras_sym_operand" "X"))
9981 (match_operand 1 "const_int_operand" "n"))
9982 (clobber (match_operand 2 "register_operand" "=r"))]
9983 "!SIBLING_CALL_P (insn)
9985 && GET_MODE (operands[2]) == Pmode"
9987 [(set_attr "op_type" "RIL")
9988 (set_attr "type" "jsr")
9989 (set_attr "z196prop" "z196_cracked")
9990 (set_attr "relative_long" "yes")])
9992 (define_insn "*basr"
9993 [(call (mem:QI (match_operand 0 "address_operand" "ZR"))
9994 (match_operand 1 "const_int_operand" "n"))
9995 (clobber (match_operand 2 "register_operand" "=r"))]
9996 "!TARGET_INDIRECT_BRANCH_NOBP_CALL
9997 && !SIBLING_CALL_P (insn)
9998 && GET_MODE (operands[2]) == Pmode"
10000 if (get_attr_op_type (insn) == OP_TYPE_RR)
10001 return "basr\t%2,%0";
10003 return "bas\t%2,%a0";
10005 [(set (attr "op_type")
10006 (if_then_else (match_operand 0 "register_operand" "")
10007 (const_string "RR") (const_string "RX")))
10008 (set (attr "mnemonic")
10009 (if_then_else (match_operand 0 "register_operand" "")
10010 (const_string "basr") (const_string "bas")))
10011 (set_attr "type" "jsr")
10012 (set_attr "atype" "agen")
10013 (set_attr "z196prop" "z196_cracked")])
10015 (define_insn "*basr_via_thunk<mode>_z10"
10016 [(call (mem:QI (match_operand:P 0 "register_operand" "a"))
10017 (match_operand 1 "const_int_operand" "n"))
10018 (clobber (match_operand:P 2 "register_operand" "=&r"))]
10019 "TARGET_INDIRECT_BRANCH_NOBP_CALL
10021 && !SIBLING_CALL_P (insn)"
10023 s390_indirect_branch_via_thunk (REGNO (operands[0]),
10024 REGNO (operands[2]),
10026 s390_indirect_branch_type_call);
10029 [(set_attr "op_type" "RIL")
10030 (set_attr "mnemonic" "brasl")
10031 (set_attr "type" "jsr")
10032 (set_attr "atype" "agen")
10033 (set_attr "z196prop" "z196_cracked")])
10035 (define_insn "*basr_via_thunk<mode>"
10036 [(call (mem:QI (match_operand:P 0 "register_operand" "a"))
10037 (match_operand 1 "const_int_operand" "n"))
10038 (clobber (match_operand:P 2 "register_operand" "=&r"))
10039 (clobber (reg:P INDIRECT_BRANCH_THUNK_REGNUM))]
10040 "TARGET_INDIRECT_BRANCH_NOBP_CALL
10042 && !SIBLING_CALL_P (insn)"
10044 s390_indirect_branch_via_thunk (REGNO (operands[0]),
10045 REGNO (operands[2]),
10047 s390_indirect_branch_type_call);
10050 [(set_attr "op_type" "RIL")
10051 (set_attr "mnemonic" "brasl")
10052 (set_attr "type" "jsr")
10053 (set_attr "atype" "agen")
10054 (set_attr "z196prop" "z196_cracked")])
10057 ; call_value instruction pattern(s).
10060 (define_expand "call_value"
10061 [(set (match_operand 0 "" "")
10062 (call (match_operand 1 "" "")
10063 (match_operand 2 "" "")))
10064 (use (match_operand 3 "" ""))]
10067 s390_emit_call (XEXP (operands[1], 0), NULL_RTX, operands[0],
10068 gen_rtx_REG (Pmode, RETURN_REGNUM));
10072 (define_insn "*bras_r"
10073 [(set (match_operand 0 "" "")
10074 (call (mem:QI (match_operand 1 "bras_sym_operand" "X"))
10075 (match_operand:SI 2 "const_int_operand" "n")))
10076 (clobber (match_operand 3 "register_operand" "=r"))]
10077 "!SIBLING_CALL_P (insn)
10078 && TARGET_SMALL_EXEC
10079 && GET_MODE (operands[3]) == Pmode"
10081 [(set_attr "op_type" "RI")
10082 (set_attr "type" "jsr")
10083 (set_attr "z196prop" "z196_cracked")])
10085 (define_insn "*brasl_r"
10086 [(set (match_operand 0 "" "")
10087 (call (mem:QI (match_operand 1 "bras_sym_operand" "X"))
10088 (match_operand 2 "const_int_operand" "n")))
10089 (clobber (match_operand 3 "register_operand" "=r"))]
10090 "!SIBLING_CALL_P (insn)
10092 && GET_MODE (operands[3]) == Pmode"
10094 [(set_attr "op_type" "RIL")
10095 (set_attr "type" "jsr")
10096 (set_attr "z196prop" "z196_cracked")
10097 (set_attr "relative_long" "yes")])
10099 (define_insn "*basr_r"
10100 [(set (match_operand 0 "" "")
10101 (call (mem:QI (match_operand 1 "address_operand" "ZR"))
10102 (match_operand 2 "const_int_operand" "n")))
10103 (clobber (match_operand 3 "register_operand" "=r"))]
10104 "!TARGET_INDIRECT_BRANCH_NOBP_CALL
10105 && !SIBLING_CALL_P (insn)
10106 && GET_MODE (operands[3]) == Pmode"
10108 if (get_attr_op_type (insn) == OP_TYPE_RR)
10109 return "basr\t%3,%1";
10111 return "bas\t%3,%a1";
10113 [(set (attr "op_type")
10114 (if_then_else (match_operand 1 "register_operand" "")
10115 (const_string "RR") (const_string "RX")))
10116 (set (attr "mnemonic")
10117 (if_then_else (match_operand 1 "register_operand" "")
10118 (const_string "basr") (const_string "bas")))
10119 (set_attr "type" "jsr")
10120 (set_attr "atype" "agen")
10121 (set_attr "z196prop" "z196_cracked")])
10123 (define_insn "*basr_r_via_thunk_z10"
10124 [(set (match_operand 0 "" "")
10125 (call (mem:QI (match_operand 1 "register_operand" "a"))
10126 (match_operand 2 "const_int_operand" "n")))
10127 (clobber (match_operand 3 "register_operand" "=&r"))]
10128 "TARGET_INDIRECT_BRANCH_NOBP_CALL
10130 && !SIBLING_CALL_P (insn)
10131 && GET_MODE (operands[3]) == Pmode"
10133 s390_indirect_branch_via_thunk (REGNO (operands[1]),
10134 REGNO (operands[3]),
10136 s390_indirect_branch_type_call);
10139 [(set_attr "op_type" "RIL")
10140 (set_attr "mnemonic" "brasl")
10141 (set_attr "type" "jsr")
10142 (set_attr "atype" "agen")
10143 (set_attr "z196prop" "z196_cracked")])
10145 (define_insn "*basr_r_via_thunk"
10146 [(set (match_operand 0 "" "")
10147 (call (mem:QI (match_operand 1 "register_operand" "a"))
10148 (match_operand 2 "const_int_operand" "n")))
10149 (clobber (match_operand 3 "register_operand" "=&r"))
10150 (clobber (reg:P INDIRECT_BRANCH_THUNK_REGNUM))]
10151 "TARGET_INDIRECT_BRANCH_NOBP_CALL
10153 && !SIBLING_CALL_P (insn)
10154 && GET_MODE (operands[3]) == Pmode"
10156 s390_indirect_branch_via_thunk (REGNO (operands[1]),
10157 REGNO (operands[3]),
10159 s390_indirect_branch_type_call);
10162 [(set_attr "op_type" "RIL")
10163 (set_attr "mnemonic" "brasl")
10164 (set_attr "type" "jsr")
10165 (set_attr "atype" "agen")
10166 (set_attr "z196prop" "z196_cracked")])
10169 ;;- Thread-local storage support.
10172 (define_expand "get_thread_pointer<mode>"
10173 [(set (match_operand:P 0 "nonimmediate_operand" "") (reg:P TP_REGNUM))]
10177 (define_expand "set_thread_pointer<mode>"
10178 [(set (reg:P TP_REGNUM) (match_operand:P 0 "nonimmediate_operand" ""))
10179 (set (reg:P TP_REGNUM) (unspec_volatile:P [(reg:P TP_REGNUM)] UNSPECV_SET_TP))]
10183 (define_insn "*set_tp"
10184 [(set (reg TP_REGNUM) (unspec_volatile [(reg TP_REGNUM)] UNSPECV_SET_TP))]
10187 [(set_attr "type" "none")
10188 (set_attr "length" "0")])
10190 (define_insn "*tls_load_64"
10191 [(set (match_operand:DI 0 "register_operand" "=d")
10192 (unspec:DI [(match_operand:DI 1 "memory_operand" "T")
10193 (match_operand:DI 2 "" "")]
10197 [(set_attr "op_type" "RXE")
10198 (set_attr "z10prop" "z10_fwd_A3")])
10200 (define_insn "*tls_load_31"
10201 [(set (match_operand:SI 0 "register_operand" "=d,d")
10202 (unspec:SI [(match_operand:SI 1 "memory_operand" "R,T")
10203 (match_operand:SI 2 "" "")]
10209 [(set_attr "op_type" "RX,RXY")
10210 (set_attr "type" "load")
10211 (set_attr "cpu_facility" "*,longdisp")
10212 (set_attr "z10prop" "z10_fwd_A3,z10_fwd_A3")])
10214 (define_insn "*bras_tls"
10215 [(set (match_operand 0 "" "")
10216 (call (mem:QI (match_operand 1 "bras_sym_operand" "X"))
10217 (match_operand 2 "const_int_operand" "n")))
10218 (clobber (match_operand 3 "register_operand" "=r"))
10219 (use (match_operand 4 "" ""))]
10220 "!SIBLING_CALL_P (insn)
10221 && TARGET_SMALL_EXEC
10222 && GET_MODE (operands[3]) == Pmode"
10224 [(set_attr "op_type" "RI")
10225 (set_attr "type" "jsr")
10226 (set_attr "z196prop" "z196_cracked")])
10228 (define_insn "*brasl_tls"
10229 [(set (match_operand 0 "" "")
10230 (call (mem:QI (match_operand 1 "bras_sym_operand" "X"))
10231 (match_operand 2 "const_int_operand" "n")))
10232 (clobber (match_operand 3 "register_operand" "=r"))
10233 (use (match_operand 4 "" ""))]
10234 "!SIBLING_CALL_P (insn)
10236 && GET_MODE (operands[3]) == Pmode"
10238 [(set_attr "op_type" "RIL")
10239 (set_attr "type" "jsr")
10240 (set_attr "z196prop" "z196_cracked")
10241 (set_attr "relative_long" "yes")])
10243 (define_insn "*basr_tls"
10244 [(set (match_operand 0 "" "")
10245 (call (mem:QI (match_operand 1 "address_operand" "ZR"))
10246 (match_operand 2 "const_int_operand" "n")))
10247 (clobber (match_operand 3 "register_operand" "=r"))
10248 (use (match_operand 4 "" ""))]
10249 "!SIBLING_CALL_P (insn) && GET_MODE (operands[3]) == Pmode"
10251 if (get_attr_op_type (insn) == OP_TYPE_RR)
10252 return "basr\t%3,%1%J4";
10254 return "bas\t%3,%a1%J4";
10256 [(set (attr "op_type")
10257 (if_then_else (match_operand 1 "register_operand" "")
10258 (const_string "RR") (const_string "RX")))
10259 (set_attr "type" "jsr")
10260 (set_attr "atype" "agen")
10261 (set_attr "z196prop" "z196_cracked")])
10264 ;;- Atomic operations
10268 ; memory barrier patterns.
10271 (define_expand "mem_thread_fence"
10272 [(match_operand:SI 0 "const_int_operand")] ;; model
10275 /* Unless this is a SEQ_CST fence, the s390 memory model is strong
10276 enough not to require barriers of any kind. */
10277 if (is_mm_seq_cst (memmodel_from_int (INTVAL (operands[0]))))
10279 rtx mem = gen_rtx_MEM (BLKmode, gen_rtx_SCRATCH (Pmode));
10280 MEM_VOLATILE_P (mem) = 1;
10281 emit_insn (gen_mem_thread_fence_1 (mem));
10286 ; Although bcr is superscalar on Z10, this variant will never
10287 ; become part of an execution group.
10288 ; With z196 we can make use of the fast-BCR-serialization facility.
10289 ; This allows for a slightly faster sync which is sufficient for our
10291 (define_insn "mem_thread_fence_1"
10292 [(set (match_operand:BLK 0 "" "")
10293 (unspec:BLK [(match_dup 0)] UNSPEC_MB))]
10297 return "bcr\t14,0";
10299 return "bcr\t15,0";
10301 [(set_attr "op_type" "RR")
10302 (set_attr "mnemonic" "bcr_flush")
10303 (set_attr "z196prop" "z196_alone")])
10306 ; atomic load/store operations
10309 ; Atomic loads need not examine the memory model at all.
10310 (define_expand "atomic_load<mode>"
10311 [(match_operand:DINT 0 "register_operand") ;; output
10312 (match_operand:DINT 1 "memory_operand") ;; memory
10313 (match_operand:SI 2 "const_int_operand")] ;; model
10316 if (MEM_ALIGN (operands[1]) < GET_MODE_BITSIZE (GET_MODE (operands[1])))
10319 if (<MODE>mode == TImode)
10320 emit_insn (gen_atomic_loadti_1 (operands[0], operands[1]));
10321 else if (<MODE>mode == DImode && !TARGET_ZARCH)
10322 emit_insn (gen_atomic_loaddi_1 (operands[0], operands[1]));
10324 emit_move_insn (operands[0], operands[1]);
10328 ; Different from movdi_31 in that we want no splitters.
10329 (define_insn "atomic_loaddi_1"
10330 [(set (match_operand:DI 0 "register_operand" "=d,d,!*f,!*f")
10331 (unspec:DI [(match_operand:DI 1 "memory_operand" "Q,S,R,T")]
10339 [(set_attr "op_type" "RS,RSY,RS,RSY")
10340 (set_attr "cpu_facility" "*,longdisp,*,longdisp")
10341 (set_attr "type" "lm,lm,floaddf,floaddf")])
10343 (define_insn "atomic_loadti_1"
10344 [(set (match_operand:TI 0 "register_operand" "=r")
10345 (unspec:TI [(match_operand:TI 1 "memory_operand" "T")]
10349 [(set_attr "op_type" "RXY")
10350 (set_attr "type" "other")])
10352 ; Atomic stores must(?) enforce sequential consistency.
10353 (define_expand "atomic_store<mode>"
10354 [(match_operand:DINT 0 "memory_operand") ;; memory
10355 (match_operand:DINT 1 "register_operand") ;; input
10356 (match_operand:SI 2 "const_int_operand")] ;; model
10359 enum memmodel model = memmodel_from_int (INTVAL (operands[2]));
10361 if (MEM_ALIGN (operands[0]) < GET_MODE_BITSIZE (GET_MODE (operands[0])))
10364 if (<MODE>mode == TImode)
10365 emit_insn (gen_atomic_storeti_1 (operands[0], operands[1]));
10366 else if (<MODE>mode == DImode && !TARGET_ZARCH)
10367 emit_insn (gen_atomic_storedi_1 (operands[0], operands[1]));
10369 emit_move_insn (operands[0], operands[1]);
10370 if (is_mm_seq_cst (model))
10371 emit_insn (gen_mem_thread_fence (operands[2]));
10375 ; Different from movdi_31 in that we want no splitters.
10376 (define_insn "atomic_storedi_1"
10377 [(set (match_operand:DI 0 "memory_operand" "=Q,S,R,T")
10378 (unspec:DI [(match_operand:DI 1 "register_operand" "d,d,!*f,!*f")]
10386 [(set_attr "op_type" "RS,RSY,RS,RSY")
10387 (set_attr "cpu_facility" "*,longdisp,*,longdisp")
10388 (set_attr "type" "stm,stm,fstoredf,fstoredf")])
10390 (define_insn "atomic_storeti_1"
10391 [(set (match_operand:TI 0 "memory_operand" "=T")
10392 (unspec:TI [(match_operand:TI 1 "register_operand" "r")]
10396 [(set_attr "op_type" "RXY")
10397 (set_attr "type" "other")])
10400 ; compare and swap patterns.
10403 (define_expand "atomic_compare_and_swap<mode>"
10404 [(match_operand:SI 0 "register_operand") ;; bool success output
10405 (match_operand:DINT 1 "nonimmediate_operand");; oldval output
10406 (match_operand:DINT 2 "s_operand") ;; memory
10407 (match_operand:DINT 3 "general_operand") ;; expected intput
10408 (match_operand:DINT 4 "general_operand") ;; newval intput
10409 (match_operand:SI 5 "const_int_operand") ;; is_weak
10410 (match_operand:SI 6 "const_int_operand") ;; success model
10411 (match_operand:SI 7 "const_int_operand")] ;; failure model
10414 if (GET_MODE_BITSIZE (<MODE>mode) >= 16
10415 && GET_MODE_BITSIZE (<MODE>mode) > MEM_ALIGN (operands[2]))
10418 s390_expand_cs (<MODE>mode, operands[0], operands[1], operands[2],
10419 operands[3], operands[4], INTVAL (operands[5]));
10422 (define_expand "atomic_compare_and_swap<mode>_internal"
10424 [(set (match_operand:DGPR 0 "register_operand")
10425 (match_operand:DGPR 1 "s_operand"))
10427 (unspec_volatile:DGPR
10429 (match_operand:DGPR 2 "register_operand")
10430 (match_operand:DGPR 3 "register_operand")]
10432 (set (match_operand 4 "cc_reg_operand")
10434 "GET_MODE (operands[4]) == CCZmode
10435 || GET_MODE (operands[4]) == CCZ1mode"
10438 = gen_rtx_COMPARE (GET_MODE (operands[4]), operands[1], operands[2]);
10442 (define_insn "*atomic_compare_and_swap<mode>_1"
10443 [(set (match_operand:TDI 0 "register_operand" "=r")
10444 (match_operand:TDI 1 "nonsym_memory_operand" "+S"))
10446 (unspec_volatile:TDI
10448 (match_operand:TDI 2 "register_operand" "0")
10449 (match_operand:TDI 3 "register_operand" "r")]
10451 (set (reg CC_REGNUM)
10452 (compare (match_dup 1) (match_dup 2)))]
10454 && s390_match_ccmode (insn, CCZ1mode)"
10455 "c<td>sg\t%0,%3,%S1"
10456 [(set_attr "op_type" "RSY")
10457 (set_attr "type" "sem")])
10460 (define_insn "*atomic_compare_and_swapdi_2"
10461 [(set (match_operand:DI 0 "register_operand" "=r,r")
10462 (match_operand:DI 1 "nonsym_memory_operand" "+Q,S"))
10464 (unspec_volatile:DI
10466 (match_operand:DI 2 "register_operand" "0,0")
10467 (match_operand:DI 3 "register_operand" "r,r")]
10469 (set (reg CC_REGNUM)
10470 (compare (match_dup 1) (match_dup 2)))]
10472 && s390_match_ccmode (insn, CCZ1mode)"
10476 [(set_attr "op_type" "RS,RSY")
10477 (set_attr "cpu_facility" "*,longdisp")
10478 (set_attr "type" "sem")])
10481 (define_insn "*atomic_compare_and_swapsi_3"
10482 [(set (match_operand:SI 0 "register_operand" "=r,r")
10483 (match_operand:SI 1 "nonsym_memory_operand" "+Q,S"))
10485 (unspec_volatile:SI
10487 (match_operand:SI 2 "register_operand" "0,0")
10488 (match_operand:SI 3 "register_operand" "r,r")]
10490 (set (reg CC_REGNUM)
10491 (compare (match_dup 1) (match_dup 2)))]
10492 "s390_match_ccmode (insn, CCZ1mode)"
10496 [(set_attr "op_type" "RS,RSY")
10497 (set_attr "cpu_facility" "*,longdisp")
10498 (set_attr "type" "sem")])
10501 ; Other atomic instruction patterns.
10504 ; z196 load and add, xor, or and and instructions
10506 (define_expand "atomic_fetch_<atomic><mode>"
10507 [(match_operand:GPR 0 "register_operand") ;; val out
10509 (match_operand:GPR 1 "memory_operand") ;; memory
10510 (match_operand:GPR 2 "register_operand")) ;; val in
10511 (match_operand:SI 3 "const_int_operand")] ;; model
10514 if (MEM_ALIGN (operands[1]) < GET_MODE_BITSIZE (GET_MODE (operands[1])))
10517 emit_insn (gen_atomic_fetch_<atomic><mode>_iaf
10518 (operands[0], operands[1], operands[2]));
10522 ; lan, lang, lao, laog, lax, laxg, laa, laag
10523 (define_insn "atomic_fetch_<atomic><mode>_iaf"
10524 [(set (match_operand:GPR 0 "register_operand" "=d")
10525 (match_operand:GPR 1 "memory_operand" "+S"))
10527 (unspec_volatile:GPR
10528 [(ATOMIC_Z196:GPR (match_dup 1)
10529 (match_operand:GPR 2 "general_operand" "d"))]
10530 UNSPECV_ATOMIC_OP))
10531 (clobber (reg:CC CC_REGNUM))]
10533 "la<noxa><g>\t%0,%2,%1"
10534 [(set_attr "op_type" "RSY")
10535 (set_attr "type" "sem")])
10537 ;; For SImode and larger, the optabs.c code will do just fine in
10538 ;; expanding a compare-and-swap loop. For QI/HImode, we can do
10539 ;; better by expanding our own loop.
10541 (define_expand "atomic_<atomic><mode>"
10543 (match_operand:HQI 0 "memory_operand") ;; memory
10544 (match_operand:HQI 1 "general_operand")) ;; val in
10545 (match_operand:SI 2 "const_int_operand")] ;; model
10548 s390_expand_atomic (<MODE>mode, <CODE>, NULL_RTX, operands[0],
10549 operands[1], false);
10553 (define_expand "atomic_fetch_<atomic><mode>"
10554 [(match_operand:HQI 0 "register_operand") ;; val out
10556 (match_operand:HQI 1 "memory_operand") ;; memory
10557 (match_operand:HQI 2 "general_operand")) ;; val in
10558 (match_operand:SI 3 "const_int_operand")] ;; model
10561 s390_expand_atomic (<MODE>mode, <CODE>, operands[0], operands[1],
10562 operands[2], false);
10566 (define_expand "atomic_<atomic>_fetch<mode>"
10567 [(match_operand:HQI 0 "register_operand") ;; val out
10569 (match_operand:HQI 1 "memory_operand") ;; memory
10570 (match_operand:HQI 2 "general_operand")) ;; val in
10571 (match_operand:SI 3 "const_int_operand")] ;; model
10574 s390_expand_atomic (<MODE>mode, <CODE>, operands[0], operands[1],
10575 operands[2], true);
10579 ;; Pattern to implement atomic_exchange with a compare-and-swap loop. The code
10580 ;; generated by the middleend is not good.
10581 (define_expand "atomic_exchange<mode>"
10582 [(match_operand:DINT 0 "register_operand") ;; val out
10583 (match_operand:DINT 1 "s_operand") ;; memory
10584 (match_operand:DINT 2 "general_operand") ;; val in
10585 (match_operand:SI 3 "const_int_operand")] ;; model
10588 if (<MODE>mode != QImode
10589 && MEM_ALIGN (operands[1]) < GET_MODE_BITSIZE (<MODE>mode))
10591 if (<MODE>mode == HImode || <MODE>mode == QImode)
10592 s390_expand_atomic (<MODE>mode, SET, operands[0], operands[1], operands[2],
10594 else if (<MODE>mode == SImode || TARGET_ZARCH)
10595 s390_expand_atomic_exchange_tdsi (operands[0], operands[1], operands[2]);
10602 ;;- Miscellaneous instructions.
10606 ; allocate stack instruction pattern(s).
10609 (define_expand "allocate_stack"
10610 [(match_operand 0 "general_operand" "")
10611 (match_operand 1 "general_operand" "")]
10614 rtx temp = gen_reg_rtx (Pmode);
10616 emit_move_insn (temp, s390_back_chain_rtx ());
10617 anti_adjust_stack (operands[1]);
10618 emit_move_insn (s390_back_chain_rtx (), temp);
10620 emit_move_insn (operands[0], virtual_stack_dynamic_rtx);
10626 ; setjmp instruction pattern.
10629 (define_expand "builtin_setjmp_receiver"
10630 [(match_operand 0 "" "")]
10633 emit_insn (s390_load_got ());
10634 emit_use (pic_offset_table_rtx);
10638 ;; These patterns say how to save and restore the stack pointer. We need not
10639 ;; save the stack pointer at function level since we are careful to
10640 ;; preserve the backchain. At block level, we have to restore the backchain
10641 ;; when we restore the stack pointer.
10643 ;; For nonlocal gotos, we must save both the stack pointer and its
10644 ;; backchain and restore both. Note that in the nonlocal case, the
10645 ;; save area is a memory location.
10647 (define_expand "save_stack_function"
10648 [(match_operand 0 "general_operand" "")
10649 (match_operand 1 "general_operand" "")]
10653 (define_expand "restore_stack_function"
10654 [(match_operand 0 "general_operand" "")
10655 (match_operand 1 "general_operand" "")]
10659 (define_expand "restore_stack_block"
10660 [(match_operand 0 "register_operand" "")
10661 (match_operand 1 "register_operand" "")]
10664 rtx temp = gen_reg_rtx (Pmode);
10666 emit_move_insn (temp, s390_back_chain_rtx ());
10667 emit_move_insn (operands[0], operands[1]);
10668 emit_move_insn (s390_back_chain_rtx (), temp);
10673 (define_expand "save_stack_nonlocal"
10674 [(match_operand 0 "memory_operand" "")
10675 (match_operand 1 "register_operand" "")]
10678 rtx base = gen_rtx_REG (Pmode, BASE_REGNUM);
10680 /* Copy the backchain to the first word, sp to the second and the
10681 literal pool base to the third. */
10683 rtx save_bc = adjust_address (operands[0], Pmode, 0);
10684 rtx save_sp = adjust_address (operands[0], Pmode, GET_MODE_SIZE (Pmode));
10685 rtx save_bp = adjust_address (operands[0], Pmode, 2 * GET_MODE_SIZE (Pmode));
10687 if (TARGET_BACKCHAIN)
10688 emit_move_insn (save_bc, force_reg (Pmode, s390_back_chain_rtx ()));
10690 emit_move_insn (save_sp, operands[1]);
10691 emit_move_insn (save_bp, base);
10696 (define_expand "restore_stack_nonlocal"
10697 [(match_operand 0 "register_operand" "")
10698 (match_operand 1 "memory_operand" "")]
10701 rtx base = gen_rtx_REG (Pmode, BASE_REGNUM);
10702 rtx temp = NULL_RTX;
10704 /* Restore the backchain from the first word, sp from the second and the
10705 literal pool base from the third. */
10707 rtx save_bc = adjust_address (operands[1], Pmode, 0);
10708 rtx save_sp = adjust_address (operands[1], Pmode, GET_MODE_SIZE (Pmode));
10709 rtx save_bp = adjust_address (operands[1], Pmode, 2 * GET_MODE_SIZE (Pmode));
10711 if (TARGET_BACKCHAIN)
10712 temp = force_reg (Pmode, save_bc);
10714 emit_move_insn (base, save_bp);
10715 emit_move_insn (operands[0], save_sp);
10718 emit_move_insn (s390_back_chain_rtx (), temp);
10724 (define_expand "exception_receiver"
10728 s390_set_has_landing_pad_p (true);
10733 ; nop instruction pattern(s).
10740 [(set_attr "op_type" "RR")])
10742 ; non-branch NOPs required for optimizing compare-and-branch patterns
10745 (define_insn "nop_lr0"
10746 [(unspec_volatile [(const_int 0)] UNSPECV_NOP_LR_0)]
10749 [(set_attr "op_type" "RR")
10750 (set_attr "z10prop" "z10_fr_E1")])
10752 (define_insn "nop_lr1"
10753 [(unspec_volatile [(const_int 0)] UNSPECV_NOP_LR_1)]
10756 [(set_attr "op_type" "RR")])
10758 ;;- Undeletable nops (used for hotpatching)
10760 (define_insn "nop_2_byte"
10761 [(unspec_volatile [(const_int 0)] UNSPECV_NOP_2_BYTE)]
10764 [(set_attr "op_type" "RR")])
10766 (define_insn "nop_4_byte"
10767 [(unspec_volatile [(const_int 0)] UNSPECV_NOP_4_BYTE)]
10770 [(set_attr "op_type" "RX")])
10772 (define_insn "nop_6_byte"
10773 [(unspec_volatile [(const_int 0)] UNSPECV_NOP_6_BYTE)]
10776 [(set_attr "op_type" "RIL")
10777 (set_attr "relative_long" "yes")])
10781 ; Special literal pool access instruction pattern(s).
10784 (define_insn "*pool_entry"
10785 [(unspec_volatile [(match_operand 0 "consttable_operand" "X")]
10786 UNSPECV_POOL_ENTRY)]
10789 machine_mode mode = GET_MODE (PATTERN (insn));
10790 unsigned int align = GET_MODE_BITSIZE (mode);
10791 s390_output_pool_entry (operands[0], mode, align);
10794 [(set (attr "length")
10795 (symbol_ref "GET_MODE_SIZE (GET_MODE (PATTERN (insn)))"))])
10797 (define_insn "pool_align"
10798 [(unspec_volatile [(match_operand 0 "const_int_operand" "n")]
10799 UNSPECV_POOL_ALIGN)]
10802 [(set (attr "length") (symbol_ref "INTVAL (operands[0])"))])
10804 (define_insn "pool_section_start"
10805 [(unspec_volatile [(const_int 1)] UNSPECV_POOL_SECTION)]
10808 switch_to_section (targetm.asm_out.function_rodata_section
10809 (current_function_decl));
10812 [(set_attr "length" "0")])
10814 (define_insn "pool_section_end"
10815 [(unspec_volatile [(const_int 0)] UNSPECV_POOL_SECTION)]
10818 switch_to_section (current_function_section ());
10821 [(set_attr "length" "0")])
10823 (define_insn "main_base_64"
10824 [(set (match_operand 0 "register_operand" "=a")
10825 (unspec [(label_ref (match_operand 1 "" ""))] UNSPEC_MAIN_BASE))]
10826 "GET_MODE (operands[0]) == Pmode"
10828 [(set_attr "op_type" "RIL")
10829 (set_attr "type" "larl")
10830 (set_attr "z10prop" "z10_fwd_A1")
10831 (set_attr "relative_long" "yes")])
10833 (define_insn "main_pool"
10834 [(set (match_operand 0 "register_operand" "=a")
10835 (unspec_volatile [(const_int 0)] UNSPECV_MAIN_POOL))]
10836 "GET_MODE (operands[0]) == Pmode"
10838 gcc_unreachable ();
10840 [(set (attr "type")
10841 (const_string "larl"))])
10843 (define_insn "reload_base_64"
10844 [(set (match_operand 0 "register_operand" "=a")
10845 (unspec [(label_ref (match_operand 1 "" ""))] UNSPEC_RELOAD_BASE))]
10846 "GET_MODE (operands[0]) == Pmode"
10848 [(set_attr "op_type" "RIL")
10849 (set_attr "type" "larl")
10850 (set_attr "z10prop" "z10_fwd_A1")])
10852 (define_insn "pool"
10853 [(unspec_volatile [(match_operand 0 "const_int_operand" "n")] UNSPECV_POOL)]
10856 gcc_unreachable ();
10858 [(set (attr "length") (symbol_ref "INTVAL (operands[0])"))])
10861 ;; Insns related to generating the function prologue and epilogue.
10865 (define_expand "prologue"
10866 [(use (const_int 0))]
10868 "s390_emit_prologue (); DONE;")
10870 (define_expand "epilogue"
10871 [(use (const_int 1))]
10873 "s390_emit_epilogue (false); DONE;")
10875 (define_expand "sibcall_epilogue"
10876 [(use (const_int 0))]
10878 "s390_emit_epilogue (true); DONE;")
10880 ;; A direct return instruction, without using an epilogue.
10881 (define_insn "<code>"
10883 "s390_can_use_<code>_insn ()"
10885 if (TARGET_INDIRECT_BRANCH_NOBP_RET)
10887 /* The target is always r14 so there is no clobber
10888 of r1 needed for pre z10 targets. */
10889 s390_indirect_branch_via_thunk (RETURN_REGNUM,
10892 s390_indirect_branch_type_return);
10896 return "br\t%%r14";
10898 [(set (attr "op_type")
10899 (if_then_else (match_test "TARGET_INDIRECT_BRANCH_NOBP_RET")
10900 (const_string "RIL")
10901 (const_string "RR")))
10902 (set (attr "mnemonic")
10903 (if_then_else (match_test "TARGET_INDIRECT_BRANCH_NOBP_RET")
10904 (const_string "jg")
10905 (const_string "br")))
10906 (set_attr "type" "jsr")
10907 (set_attr "atype" "agen")])
10910 (define_expand "return_use"
10913 (use (match_operand 0 "register_operand" "a"))])]
10916 if (!TARGET_CPU_Z10
10917 && TARGET_INDIRECT_BRANCH_NOBP_RET_OPTION)
10920 emit_jump_insn (gen_returndi_prez10 (operands[0]));
10922 emit_jump_insn (gen_returnsi_prez10 (operands[0]));
10927 (define_insn "*return<mode>"
10929 (use (match_operand:P 0 "register_operand" "a"))]
10930 "TARGET_CPU_Z10 || !TARGET_INDIRECT_BRANCH_NOBP_RET_OPTION"
10932 if (TARGET_INDIRECT_BRANCH_NOBP_RET)
10934 s390_indirect_branch_via_thunk (REGNO (operands[0]),
10937 s390_indirect_branch_type_return);
10943 [(set (attr "op_type")
10944 (if_then_else (match_test "TARGET_INDIRECT_BRANCH_NOBP_RET")
10945 (const_string "RIL")
10946 (const_string "RR")))
10947 (set (attr "mnemonic")
10948 (if_then_else (match_test "TARGET_INDIRECT_BRANCH_NOBP_RET")
10949 (const_string "jg")
10950 (const_string "br")))
10951 (set_attr "type" "jsr")
10952 (set_attr "atype" "agen")])
10954 (define_insn "return<mode>_prez10"
10956 (use (match_operand:P 0 "register_operand" "a"))
10957 (clobber (reg:P INDIRECT_BRANCH_THUNK_REGNUM))]
10958 "!TARGET_CPU_Z10 && TARGET_INDIRECT_BRANCH_NOBP_RET_OPTION"
10960 if (TARGET_INDIRECT_BRANCH_NOBP_RET)
10962 s390_indirect_branch_via_thunk (REGNO (operands[0]),
10965 s390_indirect_branch_type_return);
10971 [(set (attr "op_type")
10972 (if_then_else (match_test "TARGET_INDIRECT_BRANCH_NOBP_RET")
10973 (const_string "RIL")
10974 (const_string "RR")))
10975 (set (attr "mnemonic")
10976 (if_then_else (match_test "TARGET_INDIRECT_BRANCH_NOBP_RET")
10977 (const_string "jg")
10978 (const_string "br")))
10979 (set_attr "type" "jsr")
10980 (set_attr "atype" "agen")])
10983 ;; Instruction definition to extend a 31-bit pointer into a 64-bit
10984 ;; pointer. This is used for compatibility.
10986 (define_expand "ptr_extend"
10987 [(set (match_operand:DI 0 "register_operand" "=r")
10988 (match_operand:SI 1 "register_operand" "r"))]
10991 emit_insn (gen_anddi3 (operands[0],
10992 gen_lowpart (DImode, operands[1]),
10993 GEN_INT (0x7fffffff)));
10997 ;; Instruction definition to expand eh_return macro to support
10998 ;; swapping in special linkage return addresses.
11000 (define_expand "eh_return"
11001 [(use (match_operand 0 "register_operand" ""))]
11004 s390_emit_tpf_eh_return (operands[0]);
11009 ; Stack Protector Patterns
11012 (define_expand "stack_protect_set"
11013 [(set (match_operand 0 "memory_operand" "")
11014 (match_operand 1 "memory_operand" ""))]
11017 #ifdef TARGET_THREAD_SSP_OFFSET
11019 = gen_rtx_MEM (Pmode, gen_rtx_PLUS (Pmode, s390_get_thread_pointer (),
11020 GEN_INT (TARGET_THREAD_SSP_OFFSET)));
11023 emit_insn (gen_stack_protect_setdi (operands[0], operands[1]));
11025 emit_insn (gen_stack_protect_setsi (operands[0], operands[1]));
11030 (define_insn "stack_protect_set<mode>"
11031 [(set (match_operand:DSI 0 "memory_operand" "=Q")
11032 (unspec:DSI [(match_operand:DSI 1 "memory_operand" "Q")] UNSPEC_SP_SET))]
11034 "mvc\t%O0(%G0,%R0),%S1"
11035 [(set_attr "op_type" "SS")])
11037 (define_expand "stack_protect_test"
11038 [(set (reg:CC CC_REGNUM)
11039 (compare (match_operand 0 "memory_operand" "")
11040 (match_operand 1 "memory_operand" "")))
11041 (match_operand 2 "" "")]
11045 #ifdef TARGET_THREAD_SSP_OFFSET
11047 = gen_rtx_MEM (Pmode, gen_rtx_PLUS (Pmode, s390_get_thread_pointer (),
11048 GEN_INT (TARGET_THREAD_SSP_OFFSET)));
11051 emit_insn (gen_stack_protect_testdi (operands[0], operands[1]));
11053 emit_insn (gen_stack_protect_testsi (operands[0], operands[1]));
11055 cc_reg = gen_rtx_REG (CCZmode, CC_REGNUM);
11056 test = gen_rtx_EQ (VOIDmode, cc_reg, const0_rtx);
11057 emit_jump_insn (gen_cbranchcc4 (test, cc_reg, const0_rtx, operands[2]));
11061 (define_insn "stack_protect_test<mode>"
11062 [(set (reg:CCZ CC_REGNUM)
11063 (unspec:CCZ [(match_operand:DSI 0 "memory_operand" "Q")
11064 (match_operand:DSI 1 "memory_operand" "Q")] UNSPEC_SP_TEST))]
11066 "clc\t%O0(%G0,%R0),%S1"
11067 [(set_attr "op_type" "SS")])
11069 ; This is used in s390_emit_prologue in order to prevent insns
11070 ; adjusting the stack pointer to be moved over insns writing stack
11071 ; slots using a copy of the stack pointer in a different register.
11072 (define_insn "stack_tie"
11073 [(set (match_operand:BLK 0 "memory_operand" "+m")
11074 (unspec:BLK [(match_dup 0)] UNSPEC_TIE))]
11077 [(set_attr "length" "0")])
11080 (define_insn "stack_restore_from_fpr"
11081 [(set (reg:DI STACK_REGNUM)
11082 (match_operand:DI 0 "register_operand" "f"))
11083 (clobber (mem:BLK (scratch)))]
11086 [(set_attr "op_type" "RRE")])
11089 ; Data prefetch patterns
11092 (define_insn "prefetch"
11093 [(prefetch (match_operand 0 "address_operand" "ZT,X")
11094 (match_operand:SI 1 "const_int_operand" " n,n")
11095 (match_operand:SI 2 "const_int_operand" " n,n"))]
11098 switch (which_alternative)
11101 return INTVAL (operands[1]) == 1 ? "pfd\t2,%a0" : "pfd\t1,%a0";
11103 if (larl_operand (operands[0], Pmode))
11104 return INTVAL (operands[1]) == 1 ? "pfdrl\t2,%a0" : "pfdrl\t1,%a0";
11108 /* This might be reached for symbolic operands with an odd
11109 addend. We simply omit the prefetch for such rare cases. */
11114 [(set_attr "type" "load,larl")
11115 (set_attr "op_type" "RXY,RIL")
11116 (set_attr "z10prop" "z10_super")
11117 (set_attr "z196prop" "z196_alone")
11118 (set_attr "relative_long" "yes")])
11122 ; Byte swap instructions
11125 ; FIXME: There is also mvcin but we cannot use it since src and target
11127 ; lrvr, lrv, strv, lrvgr, lrvg, strvg
11128 (define_insn "bswap<mode>2"
11129 [(set (match_operand:GPR 0 "nonimmediate_operand" "=d,d,T")
11130 (bswap:GPR (match_operand:GPR 1 "nonimmediate_operand" " d,T,d")))]
11136 [(set_attr "type" "*,load,store")
11137 (set_attr "op_type" "RRE,RXY,RXY")
11138 (set_attr "z10prop" "z10_super")])
11140 (define_insn "bswaphi2"
11141 [(set (match_operand:HI 0 "nonimmediate_operand" "=d,d,T")
11142 (bswap:HI (match_operand:HI 1 "nonimmediate_operand" " d,T,d")))]
11148 [(set_attr "type" "*,load,store")
11149 (set_attr "op_type" "RRE,RXY,RXY")
11150 (set_attr "z10prop" "z10_super")])
11153 [(set (match_operand:HI 0 "register_operand" "")
11154 (bswap:HI (match_operand:HI 1 "register_operand" "")))]
11156 [(set (match_dup 2) (bswap:SI (match_dup 3)))
11157 (set (match_dup 2) (lshiftrt:SI (match_dup 2) (const_int 16)))]
11159 operands[2] = simplify_gen_subreg (SImode, operands[0], HImode, 0);
11160 operands[3] = simplify_gen_subreg (SImode, operands[1], HImode, 0);
11165 ; Population count instruction
11168 ; The S/390 popcount instruction counts the bits of op1 in 8 byte
11169 ; portions and stores the result in the corresponding bytes in op0.
11170 (define_insn "*popcount<mode>"
11171 [(set (match_operand:INT 0 "register_operand" "=d")
11172 (unspec:INT [(match_operand:INT 1 "register_operand" "d")] UNSPEC_POPCNT))
11173 (clobber (reg:CC CC_REGNUM))]
11176 [(set_attr "op_type" "RRE")])
11178 (define_expand "popcountdi2"
11180 (parallel [(set (match_operand:DI 0 "register_operand" "")
11181 (unspec:DI [(match_operand:DI 1 "register_operand")]
11183 (clobber (reg:CC CC_REGNUM))])
11184 ; sllg op2, op0, 32
11185 (set (match_dup 2) (ashift:DI (match_dup 0) (const_int 32)))
11187 (parallel [(set (match_dup 0) (plus:DI (match_dup 0) (match_dup 2)))
11188 (clobber (reg:CC CC_REGNUM))])
11189 ; sllg op2, op0, 16
11191 (ashift:DI (match_dup 0) (const_int 16)))
11193 (parallel [(set (match_dup 0) (plus:DI (match_dup 0) (match_dup 2)))
11194 (clobber (reg:CC CC_REGNUM))])
11196 (set (match_dup 2) (ashift:DI (match_dup 0) (const_int 8)))
11198 (parallel [(set (match_dup 0) (plus:DI (match_dup 0) (match_dup 2)))
11199 (clobber (reg:CC CC_REGNUM))])
11200 ; srlg op0, op0, 56
11201 (set (match_dup 0) (lshiftrt:DI (match_dup 0) (const_int 56)))]
11202 "TARGET_Z196 && TARGET_64BIT"
11203 "operands[2] = gen_reg_rtx (DImode);")
11205 (define_expand "popcountsi2"
11207 (parallel [(set (match_operand:SI 0 "register_operand" "")
11208 (unspec:SI [(match_operand:SI 1 "register_operand")]
11210 (clobber (reg:CC CC_REGNUM))])
11211 ; sllk op2, op0, 16
11213 (ashift:SI (match_dup 0) (const_int 16)))
11215 (parallel [(set (match_dup 0) (plus:SI (match_dup 0) (match_dup 2)))
11216 (clobber (reg:CC CC_REGNUM))])
11218 (set (match_dup 2) (ashift:SI (match_dup 0) (const_int 8)))
11220 (parallel [(set (match_dup 0) (plus:SI (match_dup 0) (match_dup 2)))
11221 (clobber (reg:CC CC_REGNUM))])
11223 (set (match_dup 0) (lshiftrt:SI (match_dup 0) (const_int 24)))]
11225 "operands[2] = gen_reg_rtx (SImode);")
11227 (define_expand "popcounthi2"
11229 (parallel [(set (match_operand:HI 0 "register_operand" "")
11230 (unspec:HI [(match_operand:HI 1 "register_operand")]
11232 (clobber (reg:CC CC_REGNUM))])
11235 (ashift:SI (match_dup 0) (const_int 8)))
11237 (parallel [(set (match_dup 0) (plus:SI (match_dup 0) (match_dup 2)))
11238 (clobber (reg:CC CC_REGNUM))])
11240 (set (match_dup 0) (lshiftrt:HI (match_dup 0) (const_int 8)))]
11242 "operands[2] = gen_reg_rtx (SImode);")
11244 (define_expand "popcountqi2"
11246 (parallel [(set (match_operand:QI 0 "register_operand" "")
11247 (unspec:QI [(match_operand:QI 1 "register_operand")]
11249 (clobber (reg:CC CC_REGNUM))])]
11254 ;;- Copy sign instructions
11257 (define_insn "copysign<mode>3"
11258 [(set (match_operand:FP 0 "register_operand" "=f")
11259 (unspec:FP [(match_operand:FP 1 "register_operand" "<fT0>")
11260 (match_operand:FP 2 "register_operand" "f")]
11264 [(set_attr "op_type" "RRF")
11265 (set_attr "type" "fsimp<mode>")])
11269 ;;- Transactional execution instructions
11272 ; This splitter helps combine to make use of CC directly when
11273 ; comparing the integer result of a tbegin builtin with a constant.
11274 ; The unspec is already removed by canonicalize_comparison. So this
11275 ; splitters only job is to turn the PARALLEL into separate insns
11276 ; again. Unfortunately this only works with the very first cc/int
11277 ; compare since combine is not able to deal with data flow across
11278 ; basic block boundaries.
11280 ; It needs to be an insn pattern as well since combine does not apply
11281 ; the splitter directly. Combine would only use it if it actually
11282 ; would reduce the number of instructions.
11283 (define_insn_and_split "*ccraw_to_int"
11286 (match_operator 0 "s390_eqne_operator"
11287 [(reg:CCRAW CC_REGNUM)
11288 (match_operand 1 "const_int_operand" "")])
11289 (label_ref (match_operand 2 "" ""))
11291 (set (match_operand:SI 3 "register_operand" "=d")
11292 (unspec:SI [(reg:CCRAW CC_REGNUM)] UNSPEC_CC_TO_INT))]
11296 [(set (match_dup 3)
11297 (unspec:SI [(reg:CCRAW CC_REGNUM)] UNSPEC_CC_TO_INT))
11299 (if_then_else (match_op_dup 0 [(reg:CCRAW CC_REGNUM) (match_dup 1)])
11300 (label_ref (match_dup 2))
11304 ; Non-constrained transaction begin
11306 (define_expand "tbegin"
11307 [(match_operand:SI 0 "register_operand" "")
11308 (match_operand:BLK 1 "memory_operand" "")]
11311 s390_expand_tbegin (operands[0], operands[1], NULL_RTX, true);
11315 (define_expand "tbegin_nofloat"
11316 [(match_operand:SI 0 "register_operand" "")
11317 (match_operand:BLK 1 "memory_operand" "")]
11320 s390_expand_tbegin (operands[0], operands[1], NULL_RTX, false);
11324 (define_expand "tbegin_retry"
11325 [(match_operand:SI 0 "register_operand" "")
11326 (match_operand:BLK 1 "memory_operand" "")
11327 (match_operand:SI 2 "general_operand" "")]
11330 s390_expand_tbegin (operands[0], operands[1], operands[2], true);
11334 (define_expand "tbegin_retry_nofloat"
11335 [(match_operand:SI 0 "register_operand" "")
11336 (match_operand:BLK 1 "memory_operand" "")
11337 (match_operand:SI 2 "general_operand" "")]
11340 s390_expand_tbegin (operands[0], operands[1], operands[2], false);
11344 ; Clobber VRs since they don't get restored
11345 (define_insn "tbegin_1_z13"
11346 [(set (reg:CCRAW CC_REGNUM)
11347 (unspec_volatile:CCRAW [(match_operand 0 "const_int_operand" "D")]
11349 (set (match_operand:BLK 1 "memory_operand" "=Q")
11350 (unspec_volatile:BLK [(match_dup 0)] UNSPECV_TBEGIN_TDB))
11351 (clobber (reg:TI 16)) (clobber (reg:TI 38))
11352 (clobber (reg:TI 17)) (clobber (reg:TI 39))
11353 (clobber (reg:TI 18)) (clobber (reg:TI 40))
11354 (clobber (reg:TI 19)) (clobber (reg:TI 41))
11355 (clobber (reg:TI 20)) (clobber (reg:TI 42))
11356 (clobber (reg:TI 21)) (clobber (reg:TI 43))
11357 (clobber (reg:TI 22)) (clobber (reg:TI 44))
11358 (clobber (reg:TI 23)) (clobber (reg:TI 45))
11359 (clobber (reg:TI 24)) (clobber (reg:TI 46))
11360 (clobber (reg:TI 25)) (clobber (reg:TI 47))
11361 (clobber (reg:TI 26)) (clobber (reg:TI 48))
11362 (clobber (reg:TI 27)) (clobber (reg:TI 49))
11363 (clobber (reg:TI 28)) (clobber (reg:TI 50))
11364 (clobber (reg:TI 29)) (clobber (reg:TI 51))
11365 (clobber (reg:TI 30)) (clobber (reg:TI 52))
11366 (clobber (reg:TI 31)) (clobber (reg:TI 53))]
11367 ; CONST_OK_FOR_CONSTRAINT_P does not work with D constraint since D is
11368 ; not supposed to be used for immediates (see genpreds.c).
11369 "TARGET_VX && INTVAL (operands[0]) >= 0 && INTVAL (operands[0]) <= 0xffff"
11371 [(set_attr "op_type" "SIL")])
11373 (define_insn "tbegin_1"
11374 [(set (reg:CCRAW CC_REGNUM)
11375 (unspec_volatile:CCRAW [(match_operand 0 "const_int_operand" "D")]
11377 (set (match_operand:BLK 1 "memory_operand" "=Q")
11378 (unspec_volatile:BLK [(match_dup 0)] UNSPECV_TBEGIN_TDB))
11379 (clobber (reg:DF 16))
11380 (clobber (reg:DF 17))
11381 (clobber (reg:DF 18))
11382 (clobber (reg:DF 19))
11383 (clobber (reg:DF 20))
11384 (clobber (reg:DF 21))
11385 (clobber (reg:DF 22))
11386 (clobber (reg:DF 23))
11387 (clobber (reg:DF 24))
11388 (clobber (reg:DF 25))
11389 (clobber (reg:DF 26))
11390 (clobber (reg:DF 27))
11391 (clobber (reg:DF 28))
11392 (clobber (reg:DF 29))
11393 (clobber (reg:DF 30))
11394 (clobber (reg:DF 31))]
11395 ; CONST_OK_FOR_CONSTRAINT_P does not work with D constraint since D is
11396 ; not supposed to be used for immediates (see genpreds.c).
11397 "TARGET_HTM && INTVAL (operands[0]) >= 0 && INTVAL (operands[0]) <= 0xffff"
11399 [(set_attr "op_type" "SIL")])
11401 ; Same as above but without the FPR clobbers
11402 (define_insn "tbegin_nofloat_1"
11403 [(set (reg:CCRAW CC_REGNUM)
11404 (unspec_volatile:CCRAW [(match_operand 0 "const_int_operand" "D")]
11406 (set (match_operand:BLK 1 "memory_operand" "=Q")
11407 (unspec_volatile:BLK [(match_dup 0)] UNSPECV_TBEGIN_TDB))]
11408 "TARGET_HTM && INTVAL (operands[0]) >= 0 && INTVAL (operands[0]) <= 0xffff"
11410 [(set_attr "op_type" "SIL")])
11413 ; Constrained transaction begin
11415 (define_expand "tbeginc"
11416 [(set (reg:CCRAW CC_REGNUM)
11417 (unspec_volatile:CCRAW [(const_int TBEGINC_MASK)]
11422 (define_insn "*tbeginc_1"
11423 [(set (reg:CCRAW CC_REGNUM)
11424 (unspec_volatile:CCRAW [(match_operand 0 "const_int_operand" " D")]
11426 "TARGET_HTM && INTVAL (operands[0]) >= 0 && INTVAL (operands[0]) <= 0xffff"
11428 [(set_attr "op_type" "SIL")])
11432 (define_expand "tend"
11433 [(set (reg:CCRAW CC_REGNUM)
11434 (unspec_volatile:CCRAW [(const_int 0)] UNSPECV_TEND))
11435 (set (match_operand:SI 0 "register_operand" "")
11436 (unspec:SI [(reg:CCRAW CC_REGNUM)] UNSPEC_CC_TO_INT))]
11440 (define_insn "*tend_1"
11441 [(set (reg:CCRAW CC_REGNUM)
11442 (unspec_volatile:CCRAW [(const_int 0)] UNSPECV_TEND))]
11445 [(set_attr "op_type" "S")])
11447 ; Transaction abort
11449 (define_expand "tabort"
11450 [(unspec_volatile [(match_operand:SI 0 "nonmemory_operand" "")]
11452 "TARGET_HTM && operands != NULL"
11454 if (CONST_INT_P (operands[0])
11455 && INTVAL (operands[0]) >= 0 && INTVAL (operands[0]) <= 255)
11457 error ("invalid transaction abort code: " HOST_WIDE_INT_PRINT_DEC
11458 ". Values in range 0 through 255 are reserved.",
11459 INTVAL (operands[0]));
11464 (define_insn "*tabort_1"
11465 [(unspec_volatile [(match_operand:SI 0 "nonmemory_operand" "aJ")]
11467 "TARGET_HTM && operands != NULL"
11469 [(set_attr "op_type" "S")])
11471 (define_insn "*tabort_1_plus"
11472 [(unspec_volatile [(plus:SI (match_operand:SI 0 "register_operand" "a")
11473 (match_operand:SI 1 "const_int_operand" "J"))]
11475 "TARGET_HTM && operands != NULL
11476 && CONST_OK_FOR_CONSTRAINT_P (INTVAL (operands[1]), 'J', \"J\")"
11478 [(set_attr "op_type" "S")])
11480 ; Transaction extract nesting depth
11482 (define_insn "etnd"
11483 [(set (match_operand:SI 0 "register_operand" "=d")
11484 (unspec_volatile:SI [(const_int 0)] UNSPECV_ETND))]
11487 [(set_attr "op_type" "RRE")])
11489 ; Non-transactional store
11491 (define_insn "ntstg"
11492 [(set (match_operand:DI 0 "memory_operand" "=T")
11493 (unspec_volatile:DI [(match_operand:DI 1 "register_operand" "d")]
11497 [(set_attr "op_type" "RXY")])
11499 ; Transaction perform processor assist
11501 (define_expand "tx_assist"
11502 [(unspec_volatile [(match_operand:SI 0 "register_operand" "")
11503 (reg:SI GPR0_REGNUM)
11504 (const_int PPA_TX_ABORT)]
11509 (define_insn "*ppa"
11510 [(unspec_volatile [(match_operand:SI 0 "register_operand" "d")
11511 (match_operand:SI 1 "register_operand" "d")
11512 (match_operand 2 "const_int_operand" "I")]
11514 "(TARGET_ZEC12 || TARGET_HTM) && INTVAL (operands[2]) < 16"
11516 [(set_attr "op_type" "RRF")])
11519 ; Set and get floating point control register
11521 (define_insn "sfpc"
11522 [(unspec_volatile [(match_operand:SI 0 "register_operand" "d")]
11524 "TARGET_HARD_FLOAT"
11527 (define_insn "efpc"
11528 [(set (match_operand:SI 0 "register_operand" "=d")
11529 (unspec_volatile:SI [(const_int 0)] UNSPECV_EFPC))]
11530 "TARGET_HARD_FLOAT"
11534 ; Load count to block boundary
11536 (define_insn "lcbb"
11537 [(set (match_operand:SI 0 "register_operand" "=d")
11538 (unspec:SI [(match_operand 1 "address_operand" "ZR")
11539 (match_operand:SI 2 "immediate_operand" "C")] UNSPEC_LCBB))
11540 (clobber (reg:CC CC_REGNUM))]
11543 [(set_attr "op_type" "VRX")])
11545 ; Handle -fsplit-stack.
11547 (define_expand "split_stack_prologue"
11551 s390_expand_split_stack_prologue ();
11555 ;; If there are operand 0 bytes available on the stack, jump to
11558 (define_expand "split_stack_space_check"
11559 [(set (pc) (if_then_else
11560 (ltu (minus (reg 15)
11561 (match_operand 0 "register_operand"))
11562 (unspec [(const_int 0)] UNSPEC_STACK_CHECK))
11563 (label_ref (match_operand 1))
11567 /* Offset from thread pointer to __private_ss. */
11568 int psso = TARGET_64BIT ? 0x38 : 0x20;
11569 rtx tp = s390_get_thread_pointer ();
11570 rtx guard = gen_rtx_MEM (Pmode, plus_constant (Pmode, tp, psso));
11571 rtx reg = gen_reg_rtx (Pmode);
11574 emit_insn (gen_subdi3 (reg, stack_pointer_rtx, operands[0]));
11576 emit_insn (gen_subsi3 (reg, stack_pointer_rtx, operands[0]));
11577 cc = s390_emit_compare (GT, reg, guard);
11578 s390_emit_jump (operands[1], cc);
11583 ;; __morestack parameter block for split stack prologue. Parameters are:
11584 ;; parameter block label, label to be called by __morestack, frame size,
11585 ;; stack parameter size.
11587 (define_insn "split_stack_data"
11588 [(unspec_volatile [(match_operand 0 "" "X")
11589 (match_operand 1 "" "X")
11590 (match_operand 2 "const_int_operand" "X")
11591 (match_operand 3 "const_int_operand" "X")]
11592 UNSPECV_SPLIT_STACK_DATA)]
11595 switch_to_section (targetm.asm_out.function_rodata_section
11596 (current_function_decl));
11599 output_asm_insn (".align\t8", operands);
11601 output_asm_insn (".align\t4", operands);
11602 (*targetm.asm_out.internal_label) (asm_out_file, "L",
11603 CODE_LABEL_NUMBER (operands[0]));
11606 output_asm_insn (".quad\t%2", operands);
11607 output_asm_insn (".quad\t%3", operands);
11608 output_asm_insn (".quad\t%1-%0", operands);
11612 output_asm_insn (".long\t%2", operands);
11613 output_asm_insn (".long\t%3", operands);
11614 output_asm_insn (".long\t%1-%0", operands);
11617 switch_to_section (current_function_section ());
11620 [(set_attr "length" "0")])
11623 ;; A jg with minimal fuss for use in split stack prologue.
11625 (define_expand "split_stack_call"
11626 [(match_operand 0 "bras_sym_operand" "X")
11627 (match_operand 1 "" "")]
11631 emit_jump_insn (gen_split_stack_call_di (operands[0], operands[1]));
11633 emit_jump_insn (gen_split_stack_call_si (operands[0], operands[1]));
11637 (define_insn "split_stack_call_<mode>"
11638 [(set (pc) (label_ref (match_operand 1 "" "")))
11639 (set (reg:P 1) (unspec_volatile [(match_operand 0 "bras_sym_operand" "X")
11641 UNSPECV_SPLIT_STACK_CALL))]
11644 [(set_attr "op_type" "RIL")
11645 (set_attr "type" "branch")])
11647 ;; Also a conditional one.
11649 (define_expand "split_stack_cond_call"
11650 [(match_operand 0 "bras_sym_operand" "X")
11651 (match_operand 1 "" "")
11652 (match_operand 2 "" "")]
11656 emit_jump_insn (gen_split_stack_cond_call_di (operands[0], operands[1], operands[2]));
11658 emit_jump_insn (gen_split_stack_cond_call_si (operands[0], operands[1], operands[2]));
11662 (define_insn "split_stack_cond_call_<mode>"
11665 (match_operand 1 "" "")
11666 (label_ref (match_operand 2 "" ""))
11668 (set (reg:P 1) (unspec_volatile [(match_operand 0 "bras_sym_operand" "X")
11670 UNSPECV_SPLIT_STACK_CALL))]
11673 [(set_attr "op_type" "RIL")
11674 (set_attr "type" "branch")])
11676 (define_insn "osc_break"
11677 [(unspec_volatile [(const_int 0)] UNSPECV_OSC_BREAK)]
11680 [(set_attr "op_type" "RR")])
11682 (define_expand "speculation_barrier"
11683 [(unspec_volatile [(reg:SI GPR0_REGNUM)
11684 (reg:SI GPR0_REGNUM)
11685 (const_int PPA_OOO_BARRIER)]