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
98 ; TLS relocation specifiers
114 ; Stack Smashing Protector
118 ; Split stack support
121 ; Test Data Class (TDC)
133 UNSPEC_FPINT_NEARBYINT
142 UNSPEC_VEC_SMULT_EVEN
143 UNSPEC_VEC_UMULT_EVEN
157 UNSPEC_VEC_INSERT_AND_ZERO
158 UNSPEC_VEC_LOAD_BNDRY
160 UNSPEC_VEC_LOAD_LEN_R
164 UNSPEC_VEC_PACK_SATURATE
165 UNSPEC_VEC_PACK_SATURATE_CC
166 UNSPEC_VEC_PACK_SATURATE_GENCC
167 UNSPEC_VEC_PACK_UNSIGNED_SATURATE
168 UNSPEC_VEC_PACK_UNSIGNED_SATURATE_CC
169 UNSPEC_VEC_PACK_UNSIGNED_SATURATE_GENCC
174 UNSPEC_VEC_STORE_LEN_R
182 UNSPEC_VEC_ADDEC_U128
187 UNSPEC_VEC_GFMSUM_128
188 UNSPEC_VEC_GFMSUM_ACCUM
189 UNSPEC_VEC_GFMSUM_ACCUM_128
206 UNSPEC_VEC_SUBEC_U128
232 UNSPEC_VEC_VFLL ; vector fp load lengthened
233 UNSPEC_VEC_VFLR ; vector fp load rounded
245 ;; UNSPEC_VOLATILE usage
248 (define_c_enum "unspecv" [
270 ; Non-branch nops used for compare-and-branch adjustments on z10
274 ; Hotpatching (unremovable NOPs)
279 ; Transactional Execution support
289 ; Set and get floating point control register
293 ; Split stack support
294 UNSPECV_SPLIT_STACK_CALL
295 UNSPECV_SPLIT_STACK_DATA
304 ; Registers with special meaning
308 ; Sibling call register.
310 ; A call-clobbered reg which can be used in indirect branch thunks
311 (INDIRECT_BRANCH_THUNK_REGNUM 1)
312 ; Literal pool base register.
314 ; Return address register.
316 ; Stack pointer register.
318 ; Condition code register.
320 ; Thread local storage pointer register.
324 ; Hardware register names
328 ; General purpose registers
333 ; Floating point registers.
357 ; Rounding modes for binary floating point numbers
360 (BFP_RND_NEAREST_TIE_AWAY_FROM_0 1)
361 (BFP_RND_PREP_FOR_SHORT_PREC 3)
362 (BFP_RND_NEAREST_TIE_TO_EVEN 4)
364 (BFP_RND_TOWARD_INF 6)
365 (BFP_RND_TOWARD_MINF 7)])
367 ; Rounding modes for decimal floating point numbers
368 ; 1-7 were introduced with the floating point extension facility
369 ; available with z196
370 ; With these rounding modes (1-7) a quantum exception might occur
371 ; which is suppressed for the other modes.
374 (DFP_RND_NEAREST_TIE_AWAY_FROM_0_QUANTEXC 1)
375 (DFP_RND_CURRENT_QUANTEXC 2)
376 (DFP_RND_PREP_FOR_SHORT_PREC_QUANTEXC 3)
377 (DFP_RND_NEAREST_TIE_TO_EVEN_QUANTEXC 4)
378 (DFP_RND_TOWARD_0_QUANTEXC 5)
379 (DFP_RND_TOWARD_INF_QUANTEXC 6)
380 (DFP_RND_TOWARD_MINF_QUANTEXC 7)
381 (DFP_RND_NEAREST_TIE_TO_EVEN 8)
383 (DFP_RND_TOWARD_INF 10)
384 (DFP_RND_TOWARD_MINF 11)
385 (DFP_RND_NEAREST_TIE_AWAY_FROM_0 12)
386 (DFP_RND_NEAREST_TIE_TO_0 13)
387 (DFP_RND_AWAY_FROM_0 14)
388 (DFP_RND_PREP_FOR_SHORT_PREC 15)])
391 ;; PFPO GPR0 argument format
396 ; PFPO operation type
397 (PFPO_CONVERT 0x1000000)
399 (PFPO_OP_TYPE_SF 0x5)
400 (PFPO_OP_TYPE_DF 0x6)
401 (PFPO_OP_TYPE_TF 0x7)
402 (PFPO_OP_TYPE_SD 0x8)
403 (PFPO_OP_TYPE_DD 0x9)
404 (PFPO_OP_TYPE_TD 0xa)
405 ; Bitposition of operand types
406 (PFPO_OP0_TYPE_SHIFT 16)
407 (PFPO_OP1_TYPE_SHIFT 8)
410 ; Immediate operands for tbegin and tbeginc
411 (define_constants [(TBEGIN_MASK 65292)]) ; 0xff0c
412 (define_constants [(TBEGINC_MASK 65288)]) ; 0xff08
414 ;; Instruction operand type as used in the Principles of Operation.
415 ;; Used to determine defaults for length and other attribute values.
417 (define_attr "op_type"
418 "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"
421 ;; Instruction type attribute used for scheduling.
423 (define_attr "type" "none,integer,load,lr,la,larl,lm,stm,
424 cs,vs,store,sem,idiv,
425 imulhi,imulsi,imuldi,
426 branch,jsr,fsimptf,fsimpdf,fsimpsf,fhex,
427 floadtf,floaddf,floadsf,fstoredf,fstoresf,
428 fmultf,fmuldf,fmulsf,fdivtf,fdivdf,fdivsf,
429 ftoi,fsqrttf,fsqrtdf,fsqrtsf,
431 ftrunctf,ftruncdf, ftruncsd, ftruncdd,
432 itoftf, itofdf, itofsf, itofdd, itoftd,
433 fdivdd, fdivtd, floaddd, floadsd, fmuldd, fmultd,
434 fsimpdd, fsimpsd, fsimptd, fstoredd, fstoresd,
436 (cond [(eq_attr "op_type" "NN") (const_string "other")
437 (eq_attr "op_type" "SS") (const_string "cs")]
438 (const_string "integer")))
440 ;; Another attribute used for scheduling purposes:
441 ;; agen: Instruction uses the address generation unit
442 ;; reg: Instruction does not use the agen unit
444 (define_attr "atype" "agen,reg"
445 (if_then_else (eq_attr "op_type" "E,RR,RI,RRE,RSI,RIL,RIE,RRF")
447 (const_string "agen")))
449 ;; Properties concerning Z10 execution grouping and value forwarding.
450 ;; z10_super: instruction is superscalar.
451 ;; z10_super_c: instruction is superscalar and meets the condition of z10_c.
452 ;; z10_fwd: The instruction reads the value of an operand and stores it into a
453 ;; target register. It can forward this value to a second instruction that reads
454 ;; the same register if that second instruction is issued in the same group.
455 ;; z10_rec: The instruction is in the T pipeline and reads a register. If the
456 ;; instruction in the S pipe writes to the register, then the T instruction
457 ;; can immediately read the new value.
458 ;; z10_fr: union of Z10_fwd and z10_rec.
459 ;; z10_c: second operand of instruction is a register and read with complemented bits.
461 ;; An additional suffix A1, A3, or E1 indicates the respective AGI bypass.
464 (define_attr "z10prop" "none,
465 z10_super, z10_super_E1, z10_super_A1, z10_super_c, z10_super_c_E1,
466 z10_fwd, z10_fwd_A1, z10_fwd_A3, z10_fwd_E1,
468 z10_fr, z10_fr_A3, z10_fr_E1,
470 (const_string "none"))
472 ;; Properties concerning Z196 decoding
473 ;; z196_alone: must group alone
474 ;; z196_end: ends a group
475 ;; z196_cracked: instruction is cracked or expanded
476 (define_attr "z196prop" "none,
477 z196_alone, z196_ends,
479 (const_string "none"))
481 ; mnemonics which only get defined through if_then_else currently
482 ; don't get added to the list values automatically and hence need to
484 (define_attr "mnemonic" "b,bas,bc,bcr_flush,unknown" (const_string "unknown"))
488 (define_attr "length" ""
489 (cond [(eq_attr "op_type" "E,RR") (const_int 2)
490 (eq_attr "op_type" "RX,RI,RRE,RS,RSI,S,SI,RRF") (const_int 4)]
494 ;; Processor type. This attribute must exactly match the processor_type
495 ;; enumeration in s390.h. The current machine description does not
496 ;; distinguish between g5 and g6, but there are differences between the two
497 ;; CPUs could in theory be modeled.
499 (define_attr "cpu" "g5,g6,z900,z990,z9_109,z9_ec,z10,z196,zEC12,z13,arch12"
500 (const (symbol_ref "s390_tune_attr")))
502 (define_attr "cpu_facility"
503 "standard,ieee,zarch,cpu_zarch,longdisp,extimm,dfp,z10,z196,zEC12,vx,z13,arch12,vxe"
504 (const_string "standard"))
506 (define_attr "enabled" ""
507 (cond [(eq_attr "cpu_facility" "standard")
510 (and (eq_attr "cpu_facility" "ieee")
511 (match_test "TARGET_CPU_IEEE_FLOAT"))
514 (and (eq_attr "cpu_facility" "zarch")
515 (match_test "TARGET_ZARCH"))
518 (and (eq_attr "cpu_facility" "longdisp")
519 (match_test "TARGET_LONG_DISPLACEMENT"))
522 (and (eq_attr "cpu_facility" "extimm")
523 (match_test "TARGET_EXTIMM"))
526 (and (eq_attr "cpu_facility" "dfp")
527 (match_test "TARGET_DFP"))
530 (and (eq_attr "cpu_facility" "cpu_zarch")
531 (match_test "TARGET_CPU_ZARCH"))
534 (and (eq_attr "cpu_facility" "z10")
535 (match_test "TARGET_Z10"))
538 (and (eq_attr "cpu_facility" "z196")
539 (match_test "TARGET_Z196"))
542 (and (eq_attr "cpu_facility" "zEC12")
543 (match_test "TARGET_ZEC12"))
546 (and (eq_attr "cpu_facility" "vx")
547 (match_test "TARGET_VX"))
550 (and (eq_attr "cpu_facility" "z13")
551 (match_test "TARGET_Z13"))
554 (and (eq_attr "cpu_facility" "arch12")
555 (match_test "TARGET_ARCH12"))
558 (and (eq_attr "cpu_facility" "vxe")
559 (match_test "TARGET_VXE"))
564 ;; Pipeline description for z900. For lack of anything better,
565 ;; this description is also used for the g5 and g6.
568 ;; Pipeline description for z990, z9-109 and z9-ec.
571 ;; Pipeline description for z10
574 ;; Pipeline description for z196
577 ;; Pipeline description for zEC12
580 ;; Pipeline description for z13
584 (include "predicates.md")
586 ;; Constraint definitions
587 (include "constraints.md")
594 (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])
596 ;; These mode iterators allow floating point patterns to be generated from the
598 (define_mode_iterator FP_ALL [TF DF SF (TD "TARGET_HARD_DFP") (DD "TARGET_HARD_DFP")
599 (SD "TARGET_HARD_DFP")])
600 (define_mode_iterator FP [TF DF SF (TD "TARGET_HARD_DFP") (DD "TARGET_HARD_DFP")])
601 (define_mode_iterator BFP [TF DF SF])
602 (define_mode_iterator DFP [TD DD])
603 (define_mode_iterator DFP_ALL [TD DD SD])
604 (define_mode_iterator DSF [DF SF])
605 (define_mode_iterator SD_SF [SF SD])
606 (define_mode_iterator DD_DF [DF DD])
607 (define_mode_iterator TD_TF [TF TD])
609 ;; These mode iterators allow 31-bit and 64-bit GPR patterns to be generated
610 ;; from the same template.
611 (define_mode_iterator GPR [(DI "TARGET_ZARCH") SI])
612 (define_mode_iterator DGPR [(TI "TARGET_ZARCH") DI SI])
613 (define_mode_iterator DSI [DI SI])
614 (define_mode_iterator TDI [TI DI])
616 ;; These mode iterators allow :P to be used for patterns that operate on
617 ;; pointer-sized quantities. Exactly one of the two alternatives will match.
618 (define_mode_iterator P [(DI "TARGET_64BIT") (SI "!TARGET_64BIT")])
620 ;; These macros refer to the actual word_mode of the configuration.
621 ;; This is equal to Pmode except on 31-bit machines in zarch mode.
622 (define_mode_iterator DW [(TI "TARGET_ZARCH") (DI "!TARGET_ZARCH")])
623 (define_mode_iterator W [(DI "TARGET_ZARCH") (SI "!TARGET_ZARCH")])
625 ;; Used by the umul pattern to express modes having half the size.
626 (define_mode_attr DWH [(TI "DI") (DI "SI")])
627 (define_mode_attr dwh [(TI "di") (DI "si")])
629 ;; This mode iterator allows the QI and HI patterns to be defined from
630 ;; the same template.
631 (define_mode_iterator HQI [HI QI])
633 ;; This mode iterator allows the integer patterns to be defined from the
635 (define_mode_iterator INT [(DI "TARGET_ZARCH") SI HI QI])
636 (define_mode_iterator DINT [(TI "TARGET_ZARCH") DI SI HI QI])
637 (define_mode_iterator SINT [SI HI QI])
639 ;; This iterator allows some 'ashift' and 'lshiftrt' pattern to be defined from
640 ;; the same template.
641 (define_code_iterator SHIFT [ashift lshiftrt])
643 ;; This iterator allows r[ox]sbg to be defined with the same template
644 (define_code_iterator IXOR [ior xor])
646 ;; This iterator is used to expand the patterns for the nearest
647 ;; integer functions.
648 (define_int_iterator FPINT [UNSPEC_FPINT_FLOOR UNSPEC_FPINT_BTRUNC
649 UNSPEC_FPINT_ROUND UNSPEC_FPINT_CEIL
650 UNSPEC_FPINT_NEARBYINT])
651 (define_int_attr fpint_name [(UNSPEC_FPINT_FLOOR "floor")
652 (UNSPEC_FPINT_BTRUNC "btrunc")
653 (UNSPEC_FPINT_ROUND "round")
654 (UNSPEC_FPINT_CEIL "ceil")
655 (UNSPEC_FPINT_NEARBYINT "nearbyint")])
656 (define_int_attr fpint_roundingmode [(UNSPEC_FPINT_FLOOR "7")
657 (UNSPEC_FPINT_BTRUNC "5")
658 (UNSPEC_FPINT_ROUND "1")
659 (UNSPEC_FPINT_CEIL "6")
660 (UNSPEC_FPINT_NEARBYINT "0")])
662 ;; This iterator and attribute allow to combine most atomic operations.
663 (define_code_iterator ATOMIC [and ior xor plus minus mult])
664 (define_code_iterator ATOMIC_Z196 [and ior xor plus])
665 (define_code_attr atomic [(and "and") (ior "or") (xor "xor")
666 (plus "add") (minus "sub") (mult "nand")])
667 (define_code_attr noxa [(and "n") (ior "o") (xor "x") (plus "a")])
669 ;; In FP templates, a string like "lt<de>br" will expand to "ltxbr" in
670 ;; TF/TDmode, "ltdbr" in DF/DDmode, and "ltebr" in SF/SDmode.
671 (define_mode_attr xde [(TF "x") (DF "d") (SF "e") (TD "x") (DD "d") (SD "e")])
673 ;; In FP templates, a <dee> in "m<dee><bt>r" will expand to "mx<bt>r" in
674 ;; TF/TDmode, "md<bt>r" in DF/DDmode, "mee<bt>r" in SFmode and "me<bt>r in
676 (define_mode_attr xdee [(TF "x") (DF "d") (SF "ee") (TD "x") (DD "d") (SD "e")])
678 ;; In FP templates, "<RRe>" will expand to "RRE" in TFmode and "RR" otherwise.
679 ;; Likewise for "<RXe>".
680 (define_mode_attr RRe [(TF "RRE") (DF "RR") (SF "RR")])
681 (define_mode_attr RXe [(TF "RXE") (DF "RX") (SF "RX")])
683 ;; The decimal floating point variants of add, sub, div and mul support 3
684 ;; fp register operands. The following attributes allow to merge the bfp and
685 ;; dfp variants in a single insn definition.
687 ;; These mode attributes are supposed to be used in the `enabled' insn
688 ;; attribute to disable certain alternatives for certain modes.
689 (define_mode_attr nBFP [(TF "0") (DF "0") (SF "0") (TD "*") (DD "*") (DD "*")])
690 (define_mode_attr nDFP [(TF "*") (DF "*") (SF "*") (TD "0") (DD "0") (DD "0")])
691 (define_mode_attr DSF [(TF "0") (DF "*") (SF "*") (TD "0") (DD "0") (SD "0")])
692 (define_mode_attr DFDI [(TF "0") (DF "*") (SF "0")
693 (TD "0") (DD "0") (DD "0")
694 (TI "0") (DI "*") (SI "0")])
695 (define_mode_attr DF [(TF "0") (DF "*") (SF "0")
696 (TD "0") (DD "0") (DD "0")
697 (TI "0") (DI "0") (SI "0")])
698 (define_mode_attr SF [(TF "0") (DF "0") (SF "*")
699 (TD "0") (DD "0") (DD "0")
700 (TI "0") (DI "0") (SI "0")])
702 ;; This attribute is used in the operand constraint list
703 ;; for instructions dealing with the sign bit of 32 or 64bit fp values.
704 ;; TFmode values are represented by a fp register pair. Since the
705 ;; sign bit instructions only handle single source and target fp registers
706 ;; these instructions can only be used for TFmode values if the source and
707 ;; target operand uses the same fp register.
708 (define_mode_attr fT0 [(TF "0") (DF "f") (SF "f")])
710 ;; This attribute adds b for bfp instructions and t for dfp instructions and is used
711 ;; within instruction mnemonics.
712 (define_mode_attr bt [(TF "b") (DF "b") (SF "b") (TD "t") (DD "t") (SD "t")])
714 ;; This attribute is used within instruction mnemonics. It evaluates to d for dfp
715 ;; modes and to an empty string for bfp modes.
716 (define_mode_attr _d [(TF "") (DF "") (SF "") (TD "d") (DD "d") (SD "d")])
718 ;; In GPR and P templates, a constraint like "<d0>" will expand to "d" in DImode
719 ;; and "0" in SImode. This allows to combine instructions of which the 31bit
720 ;; version only operates on one register.
721 (define_mode_attr d0 [(DI "d") (SI "0")])
723 ;; In combination with d0 this allows to combine instructions of which the 31bit
724 ;; version only operates on one register. The DImode version needs an additional
725 ;; register for the assembler output.
726 (define_mode_attr 1 [(DI "%1,") (SI "")])
728 ;; In SHIFT templates, a string like "s<lr>dl" will expand to "sldl" in
729 ;; 'ashift' and "srdl" in 'lshiftrt'.
730 (define_code_attr lr [(ashift "l") (lshiftrt "r")])
732 ;; In SHIFT templates, this attribute holds the correct standard name for the
733 ;; pattern itself and the corresponding function calls.
734 (define_code_attr shift [(ashift "ashl") (lshiftrt "lshr")])
736 ;; This attribute handles differences in the instruction 'type' and will result
737 ;; in "RRE" for DImode and "RR" for SImode.
738 (define_mode_attr E [(DI "E") (SI "")])
740 ;; This attribute handles differences in the instruction 'type' and makes RX<Y>
741 ;; to result in "RXY" for DImode and "RX" for SImode.
742 (define_mode_attr Y [(DI "Y") (SI "")])
744 ;; This attribute handles differences in the instruction 'type' and will result
745 ;; in "RSE" for TImode and "RS" for DImode.
746 (define_mode_attr TE [(TI "E") (DI "")])
748 ;; In GPR templates, a string like "lc<g>r" will expand to "lcgr" in DImode
749 ;; and "lcr" in SImode.
750 (define_mode_attr g [(DI "g") (SI "")])
752 ;; In GPR templates, a string like "sl<y>" will expand to "slg" in DImode
753 ;; and "sly" in SImode. This is useful because on 64bit the ..g instructions
754 ;; were enhanced with long displacements whereas 31bit instructions got a ..y
755 ;; variant for long displacements.
756 (define_mode_attr y [(DI "g") (SI "y")])
758 ;; In DW templates, a string like "cds<g>" will expand to "cdsg" in TImode
759 ;; and "cds" in DImode.
760 (define_mode_attr tg [(TI "g") (DI "")])
762 ;; In TDI templates, a string like "c<d>sg".
763 (define_mode_attr td [(TI "d") (DI "")])
765 ;; In GPR templates, a string like "c<gf>dbr" will expand to "cgdbr" in DImode
766 ;; and "cfdbr" in SImode.
767 (define_mode_attr gf [(DI "g") (SI "f")])
769 ;; In GPR templates, a string like sll<gk> will expand to sllg for DI
770 ;; and sllk for SI. This way it is possible to merge the new z196 SI
771 ;; 3 operands shift instructions into the existing patterns.
772 (define_mode_attr gk [(DI "g") (SI "k")])
774 ;; ICM mask required to load MODE value into the lowest subreg
775 ;; of a SImode register.
776 (define_mode_attr icm_lo [(HI "3") (QI "1")])
778 ;; In HQI templates, a string like "llg<hc>" will expand to "llgh" in
779 ;; HImode and "llgc" in QImode.
780 (define_mode_attr hc [(HI "h") (QI "c")])
782 ;; In P templates, the mode <DBL> will expand to "TI" in DImode and "DI"
784 (define_mode_attr DBL [(DI "TI") (SI "DI")])
786 ;; This attribute expands to DF for TFmode and to DD for TDmode . It is
787 ;; used for Txmode splitters splitting a Txmode copy into 2 Dxmode copies.
788 (define_mode_attr HALF_TMODE [(TF "DF") (TD "DD")])
790 ;; Maximum unsigned integer that fits in MODE.
791 (define_mode_attr max_uint [(HI "65535") (QI "255")])
793 ;; Start and end field computations for RISBG et al.
794 (define_mode_attr bfstart [(DI "s") (SI "t")])
795 (define_mode_attr bfend [(DI "e") (SI "f")])
797 ;; In place of GET_MODE_BITSIZE (<MODE>mode)
798 (define_mode_attr bitsize [(DI "64") (SI "32") (HI "16") (QI "8")])
800 (define_mode_attr bitoff [(DI "0") (SI "32") (HI "48") (QI "56")])
801 (define_mode_attr bitoff_plus [(DI "") (SI "32+") (HI "48+") (QI "56+")])
803 ;; In place of GET_MODE_SIZE (<MODE>mode)
804 (define_mode_attr modesize [(DI "8") (SI "4")])
806 ;; Allow return and simple_return to be defined from a single template.
807 (define_code_iterator ANY_RETURN [return simple_return])
811 ; Condition code modes generated by vector fp comparisons. These will
812 ; be used also in single element mode.
813 (define_mode_iterator VFCMP [CCVEQ CCVFH CCVFHE])
814 ; Used with VFCMP to expand part of the mnemonic
815 ; For fp we have a mismatch: eq in the insn name - e in asm
816 (define_mode_attr asm_fcmp [(CCVEQ "e") (CCVFH "h") (CCVFHE "he")])
817 (define_mode_attr insn_cmp [(CCVEQ "eq") (CCVIH "h") (CCVIHU "hl") (CCVFH "h") (CCVFHE "he")])
819 ;; Subst pattern definitions
822 (include "vector.md")
825 ;;- Compare instructions.
828 ; Test-under-Mask instructions
830 (define_insn "*tmqi_mem"
831 [(set (reg CC_REGNUM)
832 (compare (and:QI (match_operand:QI 0 "memory_operand" "Q,S")
833 (match_operand:QI 1 "immediate_operand" "n,n"))
834 (match_operand:QI 2 "immediate_operand" "n,n")))]
835 "s390_match_ccmode (insn, s390_tm_ccmode (operands[1], operands[2], false))"
839 [(set_attr "op_type" "SI,SIY")
840 (set_attr "cpu_facility" "*,longdisp")
841 (set_attr "z10prop" "z10_super,z10_super")])
843 (define_insn "*tmdi_reg"
844 [(set (reg CC_REGNUM)
845 (compare (and:DI (match_operand:DI 0 "nonimmediate_operand" "d,d,d,d")
846 (match_operand:DI 1 "immediate_operand"
847 "N0HD0,N1HD0,N2HD0,N3HD0"))
848 (match_operand:DI 2 "immediate_operand" "n,n,n,n")))]
850 && s390_match_ccmode (insn, s390_tm_ccmode (operands[1], operands[2], true))
851 && s390_single_part (operands[1], DImode, HImode, 0) >= 0"
857 [(set_attr "op_type" "RI")
858 (set_attr "z10prop" "z10_super,z10_super,z10_super,z10_super")])
860 (define_insn "*tmsi_reg"
861 [(set (reg CC_REGNUM)
862 (compare (and:SI (match_operand:SI 0 "nonimmediate_operand" "d,d")
863 (match_operand:SI 1 "immediate_operand" "N0HS0,N1HS0"))
864 (match_operand:SI 2 "immediate_operand" "n,n")))]
865 "s390_match_ccmode (insn, s390_tm_ccmode (operands[1], operands[2], true))
866 && s390_single_part (operands[1], SImode, HImode, 0) >= 0"
870 [(set_attr "op_type" "RI")
871 (set_attr "z10prop" "z10_super,z10_super")])
873 (define_insn "*tm<mode>_full"
874 [(set (reg CC_REGNUM)
875 (compare (match_operand:HQI 0 "register_operand" "d")
876 (match_operand:HQI 1 "immediate_operand" "n")))]
877 "s390_match_ccmode (insn, s390_tm_ccmode (constm1_rtx, operands[1], true))"
879 [(set_attr "op_type" "RI")
880 (set_attr "z10prop" "z10_super")])
884 ; Load-and-Test instructions
887 ; tst(di|si) instruction pattern(s).
889 (define_insn "*tstdi_sign"
890 [(set (reg CC_REGNUM)
894 (subreg:DI (match_operand:SI 0 "nonimmediate_operand" "d,T") 0)
895 (const_int 32)) (const_int 32))
896 (match_operand:DI 1 "const0_operand" "")))
897 (set (match_operand:DI 2 "register_operand" "=d,d")
898 (sign_extend:DI (match_dup 0)))]
899 "s390_match_ccmode(insn, CCSmode) && TARGET_ZARCH"
902 [(set_attr "op_type" "RRE,RXY")
903 (set_attr "cpu_facility" "*,z10")
904 (set_attr "z10prop" "z10_super_E1,z10_super_E1") ])
907 (define_insn "*tst<mode>_extimm"
908 [(set (reg CC_REGNUM)
909 (compare (match_operand:GPR 0 "nonimmediate_operand" "d,T")
910 (match_operand:GPR 1 "const0_operand" "")))
911 (set (match_operand:GPR 2 "register_operand" "=d,d")
913 "s390_match_ccmode(insn, CCSmode) && TARGET_EXTIMM"
917 [(set_attr "op_type" "RR<E>,RXY")
918 (set_attr "z10prop" "z10_fr_E1,z10_fwd_A3") ])
920 ; Peephole to combine a load-and-test from volatile memory which combine does
923 [(set (match_operand:GPR 0 "register_operand")
924 (match_operand:GPR 2 "memory_operand"))
926 (compare (match_dup 0) (match_operand:GPR 1 "const0_operand")))]
927 "s390_match_ccmode(insn, CCSmode) && TARGET_EXTIMM
928 && GENERAL_REG_P (operands[0])
929 && satisfies_constraint_T (operands[2])"
931 [(set (reg:CCS CC_REGNUM)
932 (compare:CCS (match_dup 2) (match_dup 1)))
933 (set (match_dup 0) (match_dup 2))])])
936 (define_insn "*tst<mode>_cconly_extimm"
937 [(set (reg CC_REGNUM)
938 (compare (match_operand:GPR 0 "nonimmediate_operand" "d,T")
939 (match_operand:GPR 1 "const0_operand" "")))
940 (clobber (match_scratch:GPR 2 "=X,d"))]
941 "s390_match_ccmode(insn, CCSmode) && TARGET_EXTIMM"
945 [(set_attr "op_type" "RR<E>,RXY")
946 (set_attr "z10prop" "z10_fr_E1,z10_fwd_A3")])
948 (define_insn "*tstdi"
949 [(set (reg CC_REGNUM)
950 (compare (match_operand:DI 0 "register_operand" "d")
951 (match_operand:DI 1 "const0_operand" "")))
952 (set (match_operand:DI 2 "register_operand" "=d")
954 "s390_match_ccmode(insn, CCSmode) && TARGET_ZARCH && !TARGET_EXTIMM"
956 [(set_attr "op_type" "RRE")
957 (set_attr "z10prop" "z10_fr_E1")])
959 (define_insn "*tstsi"
960 [(set (reg CC_REGNUM)
961 (compare (match_operand:SI 0 "nonimmediate_operand" "d,Q,S")
962 (match_operand:SI 1 "const0_operand" "")))
963 (set (match_operand:SI 2 "register_operand" "=d,d,d")
965 "s390_match_ccmode(insn, CCSmode) && !TARGET_EXTIMM"
970 [(set_attr "op_type" "RR,RS,RSY")
971 (set_attr "cpu_facility" "*,*,longdisp")
972 (set_attr "z10prop" "z10_fr_E1,z10_super_E1,z10_super_E1")])
974 (define_insn "*tstsi_cconly"
975 [(set (reg CC_REGNUM)
976 (compare (match_operand:SI 0 "nonimmediate_operand" "d,Q,S")
977 (match_operand:SI 1 "const0_operand" "")))
978 (clobber (match_scratch:SI 2 "=X,d,d"))]
979 "s390_match_ccmode(insn, CCSmode)"
984 [(set_attr "op_type" "RR,RS,RSY")
985 (set_attr "cpu_facility" "*,*,longdisp")
986 (set_attr "z10prop" "z10_fr_E1,z10_super_E1,z10_super_E1")])
988 (define_insn "*tstdi_cconly_31"
989 [(set (reg CC_REGNUM)
990 (compare (match_operand:DI 0 "register_operand" "d")
991 (match_operand:DI 1 "const0_operand" "")))]
992 "s390_match_ccmode(insn, CCSmode) && !TARGET_ZARCH"
994 [(set_attr "op_type" "RS")
995 (set_attr "atype" "reg")])
998 (define_insn "*tst<mode>_cconly2"
999 [(set (reg CC_REGNUM)
1000 (compare (match_operand:GPR 0 "register_operand" "d")
1001 (match_operand:GPR 1 "const0_operand" "")))]
1002 "s390_match_ccmode(insn, CCSmode)"
1004 [(set_attr "op_type" "RR<E>")
1005 (set_attr "z10prop" "z10_fr_E1")])
1007 ; tst(hi|qi) instruction pattern(s).
1009 (define_insn "*tst<mode>CCT"
1010 [(set (reg CC_REGNUM)
1011 (compare (match_operand:HQI 0 "nonimmediate_operand" "?Q,?S,d")
1012 (match_operand:HQI 1 "const0_operand" "")))
1013 (set (match_operand:HQI 2 "register_operand" "=d,d,0")
1015 "s390_match_ccmode(insn, CCTmode)"
1017 icm\t%2,<icm_lo>,%S0
1018 icmy\t%2,<icm_lo>,%S0
1020 [(set_attr "op_type" "RS,RSY,RI")
1021 (set_attr "cpu_facility" "*,longdisp,*")
1022 (set_attr "z10prop" "z10_super_E1,z10_super_E1,z10_super")])
1024 (define_insn "*tsthiCCT_cconly"
1025 [(set (reg CC_REGNUM)
1026 (compare (match_operand:HI 0 "nonimmediate_operand" "Q,S,d")
1027 (match_operand:HI 1 "const0_operand" "")))
1028 (clobber (match_scratch:HI 2 "=d,d,X"))]
1029 "s390_match_ccmode(insn, CCTmode)"
1034 [(set_attr "op_type" "RS,RSY,RI")
1035 (set_attr "cpu_facility" "*,longdisp,*")
1036 (set_attr "z10prop" "z10_super_E1,z10_super_E1,z10_super")])
1038 (define_insn "*tstqiCCT_cconly"
1039 [(set (reg CC_REGNUM)
1040 (compare (match_operand:QI 0 "nonimmediate_operand" "?Q,?S,d")
1041 (match_operand:QI 1 "const0_operand" "")))]
1042 "s390_match_ccmode(insn, CCTmode)"
1047 [(set_attr "op_type" "SI,SIY,RI")
1048 (set_attr "cpu_facility" "*,longdisp,*")
1049 (set_attr "z10prop" "z10_super,z10_super,z10_super")])
1051 (define_insn "*tst<mode>"
1052 [(set (reg CC_REGNUM)
1053 (compare (match_operand:HQI 0 "s_operand" "Q,S")
1054 (match_operand:HQI 1 "const0_operand" "")))
1055 (set (match_operand:HQI 2 "register_operand" "=d,d")
1057 "s390_match_ccmode(insn, CCSmode)"
1059 icm\t%2,<icm_lo>,%S0
1060 icmy\t%2,<icm_lo>,%S0"
1061 [(set_attr "op_type" "RS,RSY")
1062 (set_attr "cpu_facility" "*,longdisp")
1063 (set_attr "z10prop" "z10_super_E1,z10_super_E1")])
1065 (define_insn "*tst<mode>_cconly"
1066 [(set (reg CC_REGNUM)
1067 (compare (match_operand:HQI 0 "s_operand" "Q,S")
1068 (match_operand:HQI 1 "const0_operand" "")))
1069 (clobber (match_scratch:HQI 2 "=d,d"))]
1070 "s390_match_ccmode(insn, CCSmode)"
1072 icm\t%2,<icm_lo>,%S0
1073 icmy\t%2,<icm_lo>,%S0"
1074 [(set_attr "op_type" "RS,RSY")
1075 (set_attr "cpu_facility" "*,longdisp")
1076 (set_attr "z10prop" "z10_super_E1,z10_super_E1")])
1079 ; Compare (equality) instructions
1081 (define_insn "*cmpdi_cct"
1082 [(set (reg CC_REGNUM)
1083 (compare (match_operand:DI 0 "nonimmediate_operand" "%d,d,d,d,Q")
1084 (match_operand:DI 1 "general_operand" "d,K,Os,T,BQ")))]
1085 "s390_match_ccmode (insn, CCTmode) && TARGET_ZARCH"
1092 [(set_attr "op_type" "RRE,RI,RIL,RXY,SS")
1093 (set_attr "z10prop" "z10_super_c,z10_super,z10_super,z10_super,*")])
1095 (define_insn "*cmpsi_cct"
1096 [(set (reg CC_REGNUM)
1097 (compare (match_operand:SI 0 "nonimmediate_operand" "%d,d,d,d,d,Q")
1098 (match_operand:SI 1 "general_operand" "d,K,Os,R,T,BQ")))]
1099 "s390_match_ccmode (insn, CCTmode)"
1107 [(set_attr "op_type" "RR,RI,RIL,RX,RXY,SS")
1108 (set_attr "cpu_facility" "*,*,*,*,longdisp,*")
1109 (set_attr "z10prop" "z10_super_c,z10_super,z10_super,z10_super,z10_super,*")])
1111 ; Compare (signed) instructions
1113 (define_insn "*cmpdi_ccs_sign"
1114 [(set (reg CC_REGNUM)
1115 (compare (sign_extend:DI (match_operand:SI 1 "nonimmediate_operand"
1117 (match_operand:DI 0 "register_operand" "d, d,d")))]
1118 "s390_match_ccmode(insn, CCSRmode) && TARGET_ZARCH"
1123 [(set_attr "op_type" "RRE,RXY,RIL")
1124 (set_attr "z10prop" "z10_c,*,*")
1125 (set_attr "type" "*,*,larl")])
1129 (define_insn "*cmpsi_ccs_sign"
1130 [(set (reg CC_REGNUM)
1131 (compare (sign_extend:SI (match_operand:HI 1 "memory_operand" "R,T,b"))
1132 (match_operand:SI 0 "register_operand" "d,d,d")))]
1133 "s390_match_ccmode(insn, CCSRmode)"
1138 [(set_attr "op_type" "RX,RXY,RIL")
1139 (set_attr "cpu_facility" "*,longdisp,z10")
1140 (set_attr "type" "*,*,larl")
1141 (set_attr "z196prop" "z196_cracked,z196_cracked,z196_cracked")])
1143 (define_insn "*cmphi_ccs_z10"
1144 [(set (reg CC_REGNUM)
1145 (compare (match_operand:HI 0 "s_operand" "Q")
1146 (match_operand:HI 1 "immediate_operand" "K")))]
1147 "s390_match_ccmode(insn, CCSmode) && TARGET_Z10"
1149 [(set_attr "op_type" "SIL")
1150 (set_attr "z196prop" "z196_cracked")])
1152 (define_insn "*cmpdi_ccs_signhi_rl"
1153 [(set (reg CC_REGNUM)
1154 (compare (sign_extend:DI (match_operand:HI 1 "memory_operand" "T,b"))
1155 (match_operand:GPR 0 "register_operand" "d,d")))]
1156 "s390_match_ccmode(insn, CCSRmode) && TARGET_Z10"
1160 [(set_attr "op_type" "RXY,RIL")
1161 (set_attr "type" "*,larl")])
1163 ; cr, chi, cfi, c, cy, cgr, cghi, cgfi, cg, chsi, cghsi, crl, cgrl
1164 (define_insn "*cmp<mode>_ccs"
1165 [(set (reg CC_REGNUM)
1166 (compare (match_operand:GPR 0 "nonimmediate_operand"
1168 (match_operand:GPR 1 "general_operand"
1169 "d,K,K,Os,R,T,b")))]
1170 "s390_match_ccmode(insn, CCSmode)"
1179 [(set_attr "op_type" "RR<E>,RI,SIL,RIL,RX<Y>,RXY,RIL")
1180 (set_attr "cpu_facility" "*,*,z10,extimm,*,longdisp,z10")
1181 (set_attr "type" "*,*,*,*,*,*,larl")
1182 (set_attr "z10prop" "z10_super_c,z10_super,z10_super,z10_super,z10_super,z10_super,z10_super")])
1185 ; Compare (unsigned) instructions
1187 (define_insn "*cmpsi_ccu_zerohi_rlsi"
1188 [(set (reg CC_REGNUM)
1189 (compare (zero_extend:SI (mem:HI (match_operand:SI 1
1190 "larl_operand" "X")))
1191 (match_operand:SI 0 "register_operand" "d")))]
1192 "s390_match_ccmode(insn, CCURmode) && TARGET_Z10"
1194 [(set_attr "op_type" "RIL")
1195 (set_attr "type" "larl")
1196 (set_attr "z10prop" "z10_super")])
1199 (define_insn "*cmp<GPR:mode>_ccu_zerohi_rldi"
1200 [(set (reg CC_REGNUM)
1201 (compare (zero_extend:GPR (mem:HI (match_operand:DI 1
1202 "larl_operand" "X")))
1203 (match_operand:GPR 0 "register_operand" "d")))]
1204 "s390_match_ccmode(insn, CCURmode) && TARGET_Z10"
1206 [(set_attr "op_type" "RIL")
1207 (set_attr "type" "larl")
1208 (set_attr "z10prop" "z10_super")])
1210 (define_insn "*cmpdi_ccu_zero"
1211 [(set (reg CC_REGNUM)
1212 (compare (zero_extend:DI (match_operand:SI 1 "nonimmediate_operand"
1214 (match_operand:DI 0 "register_operand" "d,d,d")))]
1215 "s390_match_ccmode (insn, CCURmode) && TARGET_ZARCH"
1220 [(set_attr "op_type" "RRE,RXY,RIL")
1221 (set_attr "cpu_facility" "*,*,z10")
1222 (set_attr "type" "*,*,larl")
1223 (set_attr "z10prop" "z10_super_c,z10_super_E1,z10_super")])
1225 (define_insn "*cmpdi_ccu"
1226 [(set (reg CC_REGNUM)
1227 (compare (match_operand:DI 0 "nonimmediate_operand"
1229 (match_operand:DI 1 "general_operand"
1230 "d,Op,b,D,T,BQ,Q")))]
1231 "s390_match_ccmode (insn, CCUmode) && TARGET_ZARCH"
1240 [(set_attr "op_type" "RRE,RIL,RIL,SIL,RXY,SS,SS")
1241 (set_attr "cpu_facility" "*,extimm,z10,z10,*,*,*")
1242 (set_attr "type" "*,*,larl,*,*,*,*")
1243 (set_attr "z10prop" "z10_super_c,z10_super,z10_super,z10_super,z10_super,*,*")])
1245 (define_insn "*cmpsi_ccu"
1246 [(set (reg CC_REGNUM)
1247 (compare (match_operand:SI 0 "nonimmediate_operand" "d, d,d,Q,d,d, Q,BQ")
1248 (match_operand:SI 1 "general_operand" "d,Os,b,D,R,T,BQ, Q")))]
1249 "s390_match_ccmode (insn, CCUmode)"
1259 [(set_attr "op_type" "RR,RIL,RIL,SIL,RX,RXY,SS,SS")
1260 (set_attr "cpu_facility" "*,extimm,z10,z10,*,longdisp,*,*")
1261 (set_attr "type" "*,*,larl,*,*,*,*,*")
1262 (set_attr "z10prop" "z10_super_c,z10_super,z10_super,z10_super,z10_super,z10_super,*,*")])
1264 (define_insn "*cmphi_ccu"
1265 [(set (reg CC_REGNUM)
1266 (compare (match_operand:HI 0 "nonimmediate_operand" "d,d,Q,Q,BQ")
1267 (match_operand:HI 1 "general_operand" "Q,S,D,BQ,Q")))]
1268 "s390_match_ccmode (insn, CCUmode)
1269 && !register_operand (operands[1], HImode)"
1276 [(set_attr "op_type" "RS,RSY,SIL,SS,SS")
1277 (set_attr "cpu_facility" "*,longdisp,z10,*,*")
1278 (set_attr "z10prop" "*,*,z10_super,*,*")])
1280 (define_insn "*cmpqi_ccu"
1281 [(set (reg CC_REGNUM)
1282 (compare (match_operand:QI 0 "nonimmediate_operand" "d,d,Q,S,Q,BQ")
1283 (match_operand:QI 1 "general_operand" "Q,S,n,n,BQ,Q")))]
1284 "s390_match_ccmode (insn, CCUmode)
1285 && !register_operand (operands[1], QImode)"
1293 [(set_attr "op_type" "RS,RSY,SI,SIY,SS,SS")
1294 (set_attr "cpu_facility" "*,longdisp,*,longdisp,*,*")
1295 (set_attr "z10prop" "*,*,z10_super,z10_super,*,*")])
1298 ; Block compare (CLC) instruction patterns.
1301 [(set (reg CC_REGNUM)
1302 (compare (match_operand:BLK 0 "memory_operand" "Q")
1303 (match_operand:BLK 1 "memory_operand" "Q")))
1304 (use (match_operand 2 "const_int_operand" "n"))]
1305 "s390_match_ccmode (insn, CCUmode)
1306 && INTVAL (operands[2]) >= 1 && INTVAL (operands[2]) <= 256"
1307 "clc\t%O0(%2,%R0),%S1"
1308 [(set_attr "op_type" "SS")])
1311 [(set (reg CC_REGNUM)
1312 (compare (match_operand 0 "memory_operand" "")
1313 (match_operand 1 "memory_operand" "")))]
1315 && s390_match_ccmode (insn, CCUmode)
1316 && GET_MODE (operands[0]) == GET_MODE (operands[1])
1317 && GET_MODE_SIZE (GET_MODE (operands[0])) > 0"
1319 [(set (match_dup 0) (match_dup 1))
1320 (use (match_dup 2))])]
1322 operands[2] = GEN_INT (GET_MODE_SIZE (GET_MODE (operands[0])));
1323 operands[0] = adjust_address (operands[0], BLKmode, 0);
1324 operands[1] = adjust_address (operands[1], BLKmode, 0);
1326 operands[1] = gen_rtx_COMPARE (GET_MODE (SET_DEST (PATTERN (curr_insn))),
1327 operands[0], operands[1]);
1328 operands[0] = SET_DEST (PATTERN (curr_insn));
1332 ; (TF|DF|SF|TD|DD|SD) instructions
1335 ; load and test instructions turn SNaN into QNaN what is not
1336 ; acceptable if the target will be used afterwards. On the other hand
1337 ; they are quite convenient for implementing comparisons with 0.0. So
1338 ; try to enable them via splitter if the value isn't needed anymore.
1340 ; ltxbr, ltdbr, ltebr, ltxtr, ltdtr
1341 (define_insn "*cmp<mode>_ccs_0"
1342 [(set (reg CC_REGNUM)
1343 (compare (match_operand:FP 0 "register_operand" "f")
1344 (match_operand:FP 1 "const0_operand" "")))
1345 (clobber (match_operand:FP 2 "register_operand" "=0"))]
1346 "s390_match_ccmode(insn, CCSmode) && TARGET_HARD_FLOAT"
1347 "lt<xde><bt>r\t%0,%0"
1348 [(set_attr "op_type" "RRE")
1349 (set_attr "type" "fsimp<mode>")])
1352 [(set (match_operand 0 "cc_reg_operand")
1353 (compare (match_operand:FP 1 "register_operand")
1354 (match_operand:FP 2 "const0_operand")))]
1355 "TARGET_HARD_FLOAT && REG_P (operands[1]) && dead_or_set_p (insn, operands[1])"
1357 [(set (match_dup 0) (match_dup 3))
1358 (clobber (match_dup 1))])]
1360 /* s390_match_ccmode requires the compare to have the same CC mode
1361 as the CC destination register. */
1362 operands[3] = gen_rtx_COMPARE (GET_MODE (operands[0]),
1363 operands[1], operands[2]);
1367 ; VX: TFmode in FPR pairs: use cxbr instead of wfcxb
1368 ; cxtr, cdtr, cxbr, cdbr, cebr, cdb, ceb, wfcsb, wfcdb
1369 (define_insn "*cmp<mode>_ccs"
1370 [(set (reg CC_REGNUM)
1371 (compare (match_operand:FP 0 "register_operand" "f,f,v,v")
1372 (match_operand:FP 1 "general_operand" "f,R,v,v")))]
1373 "s390_match_ccmode(insn, CCSmode) && TARGET_HARD_FLOAT"
1379 [(set_attr "op_type" "RRE,RXE,VRR,VRR")
1380 (set_attr "cpu_facility" "*,*,vx,vxe")
1381 (set_attr "enabled" "*,<DSF>,<DF>,<SF>")])
1383 ; Compare and Branch instructions
1385 ; cij, cgij, crj, cgrj, cfi, cgfi, cr, cgr
1386 ; The following instructions do a complementary access of their second
1387 ; operand (z01 only): crj_c, cgrjc, cr, cgr
1388 (define_insn "*cmp_and_br_signed_<mode>"
1390 (if_then_else (match_operator 0 "s390_signed_integer_comparison"
1391 [(match_operand:GPR 1 "register_operand" "d,d")
1392 (match_operand:GPR 2 "nonmemory_operand" "d,C")])
1393 (label_ref (match_operand 3 "" ""))
1395 (clobber (reg:CC CC_REGNUM))]
1396 "TARGET_Z10 && !TARGET_AVOID_CMP_AND_BRANCH"
1398 if (get_attr_length (insn) == 6)
1399 return which_alternative ?
1400 "c<g>ij%C0\t%1,%c2,%l3" : "c<g>rj%C0\t%1,%2,%l3";
1402 return which_alternative ?
1403 "c<g>fi\t%1,%c2\;jg%C0\t%l3" : "c<g>r\t%1,%2\;jg%C0\t%l3";
1405 [(set_attr "op_type" "RIE")
1406 (set_attr "type" "branch")
1407 (set_attr "z10prop" "z10_super_c,z10_super")
1408 (set (attr "length")
1409 (if_then_else (lt (abs (minus (pc) (match_dup 3))) (const_int 60000))
1410 (const_int 6) (const_int 12)))]) ; 8 byte for cr/jg
1411 ; 10 byte for cgr/jg
1413 ; clij, clgij, clrj, clgrj, clfi, clgfi, clr, clgr
1414 ; The following instructions do a complementary access of their second
1415 ; operand (z10 only): clrj, clgrj, clr, clgr
1416 (define_insn "*cmp_and_br_unsigned_<mode>"
1418 (if_then_else (match_operator 0 "s390_unsigned_integer_comparison"
1419 [(match_operand:GPR 1 "register_operand" "d,d")
1420 (match_operand:GPR 2 "nonmemory_operand" "d,I")])
1421 (label_ref (match_operand 3 "" ""))
1423 (clobber (reg:CC CC_REGNUM))]
1424 "TARGET_Z10 && !TARGET_AVOID_CMP_AND_BRANCH"
1426 if (get_attr_length (insn) == 6)
1427 return which_alternative ?
1428 "cl<g>ij%C0\t%1,%b2,%l3" : "cl<g>rj%C0\t%1,%2,%l3";
1430 return which_alternative ?
1431 "cl<g>fi\t%1,%b2\;jg%C0\t%l3" : "cl<g>r\t%1,%2\;jg%C0\t%l3";
1433 [(set_attr "op_type" "RIE")
1434 (set_attr "type" "branch")
1435 (set_attr "z10prop" "z10_super_c,z10_super")
1436 (set (attr "length")
1437 (if_then_else (lt (abs (minus (pc) (match_dup 3))) (const_int 60000))
1438 (const_int 6) (const_int 12)))]) ; 8 byte for clr/jg
1439 ; 10 byte for clgr/jg
1441 ; And now the same two patterns as above but with a negated CC mask.
1443 ; cij, cgij, crj, cgrj, cfi, cgfi, cr, cgr
1444 ; The following instructions do a complementary access of their second
1445 ; operand (z01 only): crj_c, cgrjc, cr, cgr
1446 (define_insn "*icmp_and_br_signed_<mode>"
1448 (if_then_else (match_operator 0 "s390_signed_integer_comparison"
1449 [(match_operand:GPR 1 "register_operand" "d,d")
1450 (match_operand:GPR 2 "nonmemory_operand" "d,C")])
1452 (label_ref (match_operand 3 "" ""))))
1453 (clobber (reg:CC CC_REGNUM))]
1454 "TARGET_Z10 && !TARGET_AVOID_CMP_AND_BRANCH"
1456 if (get_attr_length (insn) == 6)
1457 return which_alternative ?
1458 "c<g>ij%D0\t%1,%c2,%l3" : "c<g>rj%D0\t%1,%2,%l3";
1460 return which_alternative ?
1461 "c<g>fi\t%1,%c2\;jg%D0\t%l3" : "c<g>r\t%1,%2\;jg%D0\t%l3";
1463 [(set_attr "op_type" "RIE")
1464 (set_attr "type" "branch")
1465 (set_attr "z10prop" "z10_super_c,z10_super")
1466 (set (attr "length")
1467 (if_then_else (lt (abs (minus (pc) (match_dup 3))) (const_int 60000))
1468 (const_int 6) (const_int 12)))]) ; 8 byte for cr/jg
1469 ; 10 byte for cgr/jg
1471 ; clij, clgij, clrj, clgrj, clfi, clgfi, clr, clgr
1472 ; The following instructions do a complementary access of their second
1473 ; operand (z10 only): clrj, clgrj, clr, clgr
1474 (define_insn "*icmp_and_br_unsigned_<mode>"
1476 (if_then_else (match_operator 0 "s390_unsigned_integer_comparison"
1477 [(match_operand:GPR 1 "register_operand" "d,d")
1478 (match_operand:GPR 2 "nonmemory_operand" "d,I")])
1480 (label_ref (match_operand 3 "" ""))))
1481 (clobber (reg:CC CC_REGNUM))]
1482 "TARGET_Z10 && !TARGET_AVOID_CMP_AND_BRANCH"
1484 if (get_attr_length (insn) == 6)
1485 return which_alternative ?
1486 "cl<g>ij%D0\t%1,%b2,%l3" : "cl<g>rj%D0\t%1,%2,%l3";
1488 return which_alternative ?
1489 "cl<g>fi\t%1,%b2\;jg%D0\t%l3" : "cl<g>r\t%1,%2\;jg%D0\t%l3";
1491 [(set_attr "op_type" "RIE")
1492 (set_attr "type" "branch")
1493 (set_attr "z10prop" "z10_super_c,z10_super")
1494 (set (attr "length")
1495 (if_then_else (lt (abs (minus (pc) (match_dup 3))) (const_int 60000))
1496 (const_int 6) (const_int 12)))]) ; 8 byte for clr/jg
1497 ; 10 byte for clgr/jg
1500 ;;- Move instructions.
1504 ; movti instruction pattern(s).
1508 ; Separate out the register pair alternative since constraints (P) are
1509 ; not able to deal with const_wide_int's. But predicates do.
1510 (define_insn "*movti_bigconst"
1511 [(set (match_operand:TI 0 "register_operand" "=d")
1512 (match_operand:TI 1 "reload_const_wide_int_operand" ""))]
1516 ; FIXME: More constants are possible by enabling jxx, jyy constraints
1517 ; for TImode (use double-int for the calculations)
1518 (define_insn "movti"
1519 [(set (match_operand:TI 0 "nonimmediate_operand" "=d,S,v, v, v,v,d,v,R, d,o")
1520 (match_operand:TI 1 "general_operand" " S,d,v,j00,jm1,d,v,R,v,dT,d"))]
1534 [(set_attr "op_type" "RSY,RSY,VRR,VRI,VRI,VRR,*,VRX,VRX,*,*")
1535 (set_attr "type" "lm,stm,*,*,*,*,*,*,*,*,*")
1536 (set_attr "cpu_facility" "*,*,vx,vx,vx,vx,vx,vx,vx,*,*")])
1539 [(set (match_operand:TI 0 "nonimmediate_operand" "")
1540 (match_operand:TI 1 "general_operand" ""))]
1541 "TARGET_ZARCH && reload_completed
1542 && !s_operand (operands[0], TImode)
1543 && !s_operand (operands[1], TImode)
1544 && s390_split_ok_p (operands[0], operands[1], TImode, 0)"
1545 [(set (match_dup 2) (match_dup 4))
1546 (set (match_dup 3) (match_dup 5))]
1548 operands[2] = operand_subword (operands[0], 0, 0, TImode);
1549 operands[3] = operand_subword (operands[0], 1, 0, TImode);
1550 operands[4] = operand_subword (operands[1], 0, 0, TImode);
1551 operands[5] = operand_subword (operands[1], 1, 0, TImode);
1555 [(set (match_operand:TI 0 "nonimmediate_operand" "")
1556 (match_operand:TI 1 "general_operand" ""))]
1557 "TARGET_ZARCH && reload_completed
1558 && !s_operand (operands[0], TImode)
1559 && !s_operand (operands[1], TImode)
1560 && s390_split_ok_p (operands[0], operands[1], TImode, 1)"
1561 [(set (match_dup 2) (match_dup 4))
1562 (set (match_dup 3) (match_dup 5))]
1564 operands[2] = operand_subword (operands[0], 1, 0, TImode);
1565 operands[3] = operand_subword (operands[0], 0, 0, TImode);
1566 operands[4] = operand_subword (operands[1], 1, 0, TImode);
1567 operands[5] = operand_subword (operands[1], 0, 0, TImode);
1570 ; Use part of the TImode target reg to perform the address
1571 ; calculation. If the TImode value is supposed to be copied into a VR
1572 ; this splitter is not necessary.
1574 [(set (match_operand:TI 0 "register_operand" "")
1575 (match_operand:TI 1 "memory_operand" ""))]
1576 "TARGET_ZARCH && reload_completed
1577 && !VECTOR_REG_P (operands[0])
1578 && !s_operand (operands[1], VOIDmode)"
1579 [(set (match_dup 0) (match_dup 1))]
1581 rtx addr = operand_subword (operands[0], 1, 0, TImode);
1582 addr = gen_lowpart (Pmode, addr);
1583 s390_load_address (addr, XEXP (operands[1], 0));
1584 operands[1] = replace_equiv_address (operands[1], addr);
1588 ; Split a VR -> GPR TImode move into 2 vector load GR from VR element.
1589 ; For the higher order bits we do simply a DImode move while the
1590 ; second part is done via vec extract. Both will end up as vlgvg.
1592 [(set (match_operand:TI 0 "register_operand" "")
1593 (match_operand:TI 1 "register_operand" ""))]
1594 "TARGET_VX && reload_completed
1595 && GENERAL_REG_P (operands[0])
1596 && VECTOR_REG_P (operands[1])"
1597 [(set (match_dup 2) (match_dup 4))
1598 (set (match_dup 3) (unspec:DI [(match_dup 5) (const_int 1)]
1599 UNSPEC_VEC_EXTRACT))]
1601 operands[2] = operand_subword (operands[0], 0, 0, TImode);
1602 operands[3] = operand_subword (operands[0], 1, 0, TImode);
1603 operands[4] = gen_rtx_REG (DImode, REGNO (operands[1]));
1604 operands[5] = gen_rtx_REG (V2DImode, REGNO (operands[1]));
1608 ; Patterns used for secondary reloads
1611 ; z10 provides move instructions accepting larl memory operands.
1612 ; Unfortunately there is no such variant for QI, TI and FP mode moves.
1613 ; These patterns are also used for unaligned SI and DI accesses.
1615 (define_expand "reload<ALL:mode><P:mode>_tomem_z10"
1616 [(parallel [(match_operand:ALL 0 "memory_operand" "")
1617 (match_operand:ALL 1 "register_operand" "=d")
1618 (match_operand:P 2 "register_operand" "=&a")])]
1621 s390_reload_symref_address (operands[1], operands[0], operands[2], 1);
1625 (define_expand "reload<ALL:mode><P:mode>_toreg_z10"
1626 [(parallel [(match_operand:ALL 0 "register_operand" "=d")
1627 (match_operand:ALL 1 "memory_operand" "")
1628 (match_operand:P 2 "register_operand" "=a")])]
1631 s390_reload_symref_address (operands[0], operands[1], operands[2], 0);
1635 (define_expand "reload<P:mode>_larl_odd_addend_z10"
1636 [(parallel [(match_operand:P 0 "register_operand" "=d")
1637 (match_operand:P 1 "larl_operand" "")
1638 (match_operand:P 2 "register_operand" "=a")])]
1641 s390_reload_larl_operand (operands[0], operands[1], operands[2]);
1645 ; Handles loading a PLUS (load address) expression
1647 (define_expand "reload<mode>_plus"
1648 [(parallel [(match_operand:P 0 "register_operand" "=a")
1649 (match_operand:P 1 "s390_plus_operand" "")
1650 (match_operand:P 2 "register_operand" "=&a")])]
1653 s390_expand_plus_operand (operands[0], operands[1], operands[2]);
1657 ; Not all the indirect memory access instructions support the full
1658 ; format (long disp + index + base). So whenever a move from/to such
1659 ; an address is required and the instruction cannot deal with it we do
1660 ; a load address into a scratch register first and use this as the new
1662 ; This in particular is used for:
1663 ; - non-offsetable memory accesses for multiword moves
1664 ; - full vector reg moves with long displacements
1666 (define_expand "reload<mode>_la_in"
1667 [(parallel [(match_operand 0 "register_operand" "")
1668 (match_operand 1 "" "")
1669 (match_operand:P 2 "register_operand" "=&a")])]
1672 gcc_assert (MEM_P (operands[1]));
1673 s390_load_address (operands[2], find_replacement (&XEXP (operands[1], 0)));
1674 operands[1] = replace_equiv_address (operands[1], operands[2]);
1675 emit_move_insn (operands[0], operands[1]);
1679 (define_expand "reload<mode>_la_out"
1680 [(parallel [(match_operand 0 "" "")
1681 (match_operand 1 "register_operand" "")
1682 (match_operand:P 2 "register_operand" "=&a")])]
1685 gcc_assert (MEM_P (operands[0]));
1686 s390_load_address (operands[2], find_replacement (&XEXP (operands[0], 0)));
1687 operands[0] = replace_equiv_address (operands[0], operands[2]);
1688 emit_move_insn (operands[0], operands[1]);
1692 (define_expand "reload<mode>_PIC_addr"
1693 [(parallel [(match_operand 0 "register_operand" "=d")
1694 (match_operand 1 "larl_operand" "")
1695 (match_operand:P 2 "register_operand" "=a")])]
1698 rtx new_rtx = legitimize_pic_address (operands[1], operands[2]);
1699 emit_move_insn (operands[0], new_rtx);
1703 ; movdi instruction pattern(s).
1706 (define_expand "movdi"
1707 [(set (match_operand:DI 0 "general_operand" "")
1708 (match_operand:DI 1 "general_operand" ""))]
1711 /* Handle symbolic constants. */
1713 && (SYMBOLIC_CONST (operands[1])
1714 || (GET_CODE (operands[1]) == PLUS
1715 && XEXP (operands[1], 0) == pic_offset_table_rtx
1716 && SYMBOLIC_CONST (XEXP (operands[1], 1)))))
1717 emit_symbolic_move (operands);
1720 (define_insn "*movdi_larl"
1721 [(set (match_operand:DI 0 "register_operand" "=d")
1722 (match_operand:DI 1 "larl_operand" "X"))]
1724 && !FP_REG_P (operands[0])"
1726 [(set_attr "op_type" "RIL")
1727 (set_attr "type" "larl")
1728 (set_attr "z10prop" "z10_super_A1")])
1730 (define_insn "*movdi_64"
1731 [(set (match_operand:DI 0 "nonimmediate_operand"
1732 "=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")
1733 (match_operand:DI 1 "general_operand"
1734 " 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"))]
1769 [(set_attr "op_type" "RI,RI,RI,RI,RI,RIL,RIL,RIL,RRE,RRE,RXY,RIL,RRE,RXY,
1770 RXY,RR,RX,RXY,RX,RXY,RIL,SIL,*,*,RS,RS,VRI,VRR,VRS,VRS,VRX,VRX")
1771 (set_attr "type" "*,*,*,*,*,*,*,*,floaddf,floaddf,la,larl,lr,load,store,
1772 floaddf,floaddf,floaddf,fstoredf,fstoredf,larl,*,*,*,*,
1774 (set_attr "cpu_facility" "*,*,*,*,*,extimm,extimm,extimm,dfp,dfp,longdisp,
1775 z10,*,*,*,*,*,longdisp,*,longdisp,
1776 z10,z10,*,*,*,*,vx,vx,vx,vx,vx,vx")
1777 (set_attr "z10prop" "z10_fwd_A1,
1806 [(set (match_operand:DI 0 "register_operand" "")
1807 (match_operand:DI 1 "register_operand" ""))]
1808 "TARGET_ZARCH && ACCESS_REG_P (operands[1])"
1809 [(set (match_dup 2) (match_dup 3))
1810 (set (match_dup 0) (ashift:DI (match_dup 0) (const_int 32)))
1811 (set (strict_low_part (match_dup 2)) (match_dup 4))]
1812 "operands[2] = gen_lowpart (SImode, operands[0]);
1813 s390_split_access_reg (operands[1], &operands[4], &operands[3]);")
1816 [(set (match_operand:DI 0 "register_operand" "")
1817 (match_operand:DI 1 "register_operand" ""))]
1818 "TARGET_ZARCH && ACCESS_REG_P (operands[0])
1819 && dead_or_set_p (insn, operands[1])"
1820 [(set (match_dup 3) (match_dup 2))
1821 (set (match_dup 1) (lshiftrt:DI (match_dup 1) (const_int 32)))
1822 (set (match_dup 4) (match_dup 2))]
1823 "operands[2] = gen_lowpart (SImode, operands[1]);
1824 s390_split_access_reg (operands[0], &operands[3], &operands[4]);")
1827 [(set (match_operand:DI 0 "register_operand" "")
1828 (match_operand:DI 1 "register_operand" ""))]
1829 "TARGET_ZARCH && ACCESS_REG_P (operands[0])
1830 && !dead_or_set_p (insn, operands[1])"
1831 [(set (match_dup 3) (match_dup 2))
1832 (set (match_dup 1) (rotate:DI (match_dup 1) (const_int 32)))
1833 (set (match_dup 4) (match_dup 2))
1834 (set (match_dup 1) (rotate:DI (match_dup 1) (const_int 32)))]
1835 "operands[2] = gen_lowpart (SImode, operands[1]);
1836 s390_split_access_reg (operands[0], &operands[3], &operands[4]);")
1838 (define_insn "*movdi_31"
1839 [(set (match_operand:DI 0 "nonimmediate_operand"
1840 "=d,d,Q,S,d ,o,!*f,!*f,!*f,!R,!T,d")
1841 (match_operand:DI 1 "general_operand"
1842 " Q,S,d,d,dPT,d, *f, R, T,*f,*f,b"))]
1857 [(set_attr "op_type" "RS,RSY,RS,RSY,*,*,RR,RX,RXY,RX,RXY,*")
1858 (set_attr "type" "lm,lm,stm,stm,*,*,floaddf,floaddf,floaddf,fstoredf,fstoredf,*")
1859 (set_attr "cpu_facility" "*,longdisp,*,longdisp,*,*,*,*,longdisp,*,longdisp,z10")])
1861 ; For a load from a symbol ref we can use one of the target registers
1862 ; together with larl to load the address.
1864 [(set (match_operand:DI 0 "register_operand" "")
1865 (match_operand:DI 1 "memory_operand" ""))]
1866 "!TARGET_ZARCH && reload_completed && TARGET_Z10
1867 && larl_operand (XEXP (operands[1], 0), SImode)"
1868 [(set (match_dup 2) (match_dup 3))
1869 (set (match_dup 0) (match_dup 1))]
1871 operands[2] = operand_subword (operands[0], 1, 0, DImode);
1872 operands[3] = XEXP (operands[1], 0);
1873 operands[1] = replace_equiv_address (operands[1], operands[2]);
1877 [(set (match_operand:DI 0 "nonimmediate_operand" "")
1878 (match_operand:DI 1 "general_operand" ""))]
1879 "!TARGET_ZARCH && reload_completed
1880 && !s_operand (operands[0], DImode)
1881 && !s_operand (operands[1], DImode)
1882 && s390_split_ok_p (operands[0], operands[1], DImode, 0)"
1883 [(set (match_dup 2) (match_dup 4))
1884 (set (match_dup 3) (match_dup 5))]
1886 operands[2] = operand_subword (operands[0], 0, 0, DImode);
1887 operands[3] = operand_subword (operands[0], 1, 0, DImode);
1888 operands[4] = operand_subword (operands[1], 0, 0, DImode);
1889 operands[5] = operand_subword (operands[1], 1, 0, DImode);
1893 [(set (match_operand:DI 0 "nonimmediate_operand" "")
1894 (match_operand:DI 1 "general_operand" ""))]
1895 "!TARGET_ZARCH && reload_completed
1896 && !s_operand (operands[0], DImode)
1897 && !s_operand (operands[1], DImode)
1898 && s390_split_ok_p (operands[0], operands[1], DImode, 1)"
1899 [(set (match_dup 2) (match_dup 4))
1900 (set (match_dup 3) (match_dup 5))]
1902 operands[2] = operand_subword (operands[0], 1, 0, DImode);
1903 operands[3] = operand_subword (operands[0], 0, 0, DImode);
1904 operands[4] = operand_subword (operands[1], 1, 0, DImode);
1905 operands[5] = operand_subword (operands[1], 0, 0, DImode);
1909 [(set (match_operand:DI 0 "register_operand" "")
1910 (match_operand:DI 1 "memory_operand" ""))]
1911 "!TARGET_ZARCH && reload_completed
1912 && !FP_REG_P (operands[0])
1913 && !s_operand (operands[1], VOIDmode)"
1914 [(set (match_dup 0) (match_dup 1))]
1916 rtx addr = operand_subword (operands[0], 1, 0, DImode);
1917 s390_load_address (addr, XEXP (operands[1], 0));
1918 operands[1] = replace_equiv_address (operands[1], addr);
1922 [(set (match_operand:DI 0 "register_operand" "")
1923 (mem:DI (match_operand 1 "address_operand" "")))]
1925 && !FP_REG_P (operands[0])
1926 && GET_CODE (operands[1]) == SYMBOL_REF
1927 && CONSTANT_POOL_ADDRESS_P (operands[1])
1928 && get_pool_mode (operands[1]) == DImode
1929 && legitimate_reload_constant_p (get_pool_constant (operands[1]))"
1930 [(set (match_dup 0) (match_dup 2))]
1931 "operands[2] = get_pool_constant (operands[1]);")
1933 (define_insn "*la_64"
1934 [(set (match_operand:DI 0 "register_operand" "=d,d")
1935 (match_operand:QI 1 "address_operand" "ZR,ZT"))]
1940 [(set_attr "op_type" "RX,RXY")
1941 (set_attr "type" "la")
1942 (set_attr "cpu_facility" "*,longdisp")
1943 (set_attr "z10prop" "z10_fwd_A1,z10_fwd_A1")])
1947 [(set (match_operand:DI 0 "register_operand" "")
1948 (match_operand:QI 1 "address_operand" ""))
1949 (clobber (reg:CC CC_REGNUM))])]
1951 && preferred_la_operand_p (operands[1], const0_rtx)"
1952 [(set (match_dup 0) (match_dup 1))]
1956 [(set (match_operand:DI 0 "register_operand" "")
1957 (match_operand:DI 1 "register_operand" ""))
1960 (plus:DI (match_dup 0)
1961 (match_operand:DI 2 "nonmemory_operand" "")))
1962 (clobber (reg:CC CC_REGNUM))])]
1964 && !reg_overlap_mentioned_p (operands[0], operands[2])
1965 && preferred_la_operand_p (operands[1], operands[2])"
1966 [(set (match_dup 0) (plus:DI (match_dup 1) (match_dup 2)))]
1970 ; movsi instruction pattern(s).
1973 (define_expand "movsi"
1974 [(set (match_operand:SI 0 "general_operand" "")
1975 (match_operand:SI 1 "general_operand" ""))]
1978 /* Handle symbolic constants. */
1980 && (SYMBOLIC_CONST (operands[1])
1981 || (GET_CODE (operands[1]) == PLUS
1982 && XEXP (operands[1], 0) == pic_offset_table_rtx
1983 && SYMBOLIC_CONST (XEXP(operands[1], 1)))))
1984 emit_symbolic_move (operands);
1987 (define_insn "*movsi_larl"
1988 [(set (match_operand:SI 0 "register_operand" "=d")
1989 (match_operand:SI 1 "larl_operand" "X"))]
1990 "!TARGET_64BIT && TARGET_CPU_ZARCH
1991 && !FP_REG_P (operands[0])"
1993 [(set_attr "op_type" "RIL")
1994 (set_attr "type" "larl")
1995 (set_attr "z10prop" "z10_fwd_A1")])
1997 (define_insn "*movsi_zarch"
1998 [(set (match_operand:SI 0 "nonimmediate_operand"
1999 "=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")
2000 (match_operand:SI 1 "general_operand"
2001 " 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"))]
2034 [(set_attr "op_type" "RI,RI,RI,RIL,RXY,RIL,RR,RX,RXY,RX,RXY,
2035 RR,RR,RXE,RX,RXY,RX,RXY,RRE,RRE,RS,RIL,SIL,RS,VRI,VRR,VRS,VRS,VRX,VRX")
2036 (set_attr "type" "*,
2060 (set_attr "cpu_facility" "*,*,*,extimm,longdisp,z10,*,*,longdisp,*,longdisp,
2061 vx,*,vx,*,longdisp,*,longdisp,*,*,*,z10,z10,*,vx,vx,vx,vx,vx,vx")
2062 (set_attr "z10prop" "z10_fwd_A1,
2087 (define_insn "*movsi_esa"
2088 [(set (match_operand:SI 0 "nonimmediate_operand" "=d,d,d,R,!*f,!*f,!*f,!*f,!R,d,t,Q,t")
2089 (match_operand:SI 1 "general_operand" "K,d,R,d, *f, *f, R, R,*f,t,d,t,Q"))]
2105 [(set_attr "op_type" "RI,RR,RX,RX,RR,RR,RXE,RX,RX,RRE,RRE,RS,RS")
2106 (set_attr "type" "*,lr,load,store,floadsf,floadsf,floadsf,floadsf,fstoresf,*,*,*,*")
2107 (set_attr "z10prop" "z10_fwd_A1,z10_fr_E1,z10_fwd_A3,z10_rec,*,*,*,*,*,z10_super_E1,
2109 (set_attr "cpu_facility" "*,*,*,*,vx,*,vx,*,*,*,*,*,*")
2113 [(set (match_operand:SI 0 "register_operand" "")
2114 (mem:SI (match_operand 1 "address_operand" "")))]
2115 "!FP_REG_P (operands[0])
2116 && GET_CODE (operands[1]) == SYMBOL_REF
2117 && CONSTANT_POOL_ADDRESS_P (operands[1])
2118 && get_pool_mode (operands[1]) == SImode
2119 && legitimate_reload_constant_p (get_pool_constant (operands[1]))"
2120 [(set (match_dup 0) (match_dup 2))]
2121 "operands[2] = get_pool_constant (operands[1]);")
2123 (define_insn "*la_31"
2124 [(set (match_operand:SI 0 "register_operand" "=d,d")
2125 (match_operand:QI 1 "address_operand" "ZR,ZT"))]
2126 "!TARGET_64BIT && legitimate_la_operand_p (operands[1])"
2130 [(set_attr "op_type" "RX,RXY")
2131 (set_attr "type" "la")
2132 (set_attr "cpu_facility" "*,longdisp")
2133 (set_attr "z10prop" "z10_fwd_A1,z10_fwd_A1")])
2137 [(set (match_operand:SI 0 "register_operand" "")
2138 (match_operand:QI 1 "address_operand" ""))
2139 (clobber (reg:CC CC_REGNUM))])]
2141 && preferred_la_operand_p (operands[1], const0_rtx)"
2142 [(set (match_dup 0) (match_dup 1))]
2146 [(set (match_operand:SI 0 "register_operand" "")
2147 (match_operand:SI 1 "register_operand" ""))
2150 (plus:SI (match_dup 0)
2151 (match_operand:SI 2 "nonmemory_operand" "")))
2152 (clobber (reg:CC CC_REGNUM))])]
2154 && !reg_overlap_mentioned_p (operands[0], operands[2])
2155 && preferred_la_operand_p (operands[1], operands[2])"
2156 [(set (match_dup 0) (plus:SI (match_dup 1) (match_dup 2)))]
2159 (define_insn "*la_31_and"
2160 [(set (match_operand:SI 0 "register_operand" "=d,d")
2161 (and:SI (match_operand:QI 1 "address_operand" "ZR,ZT")
2162 (const_int 2147483647)))]
2167 [(set_attr "op_type" "RX,RXY")
2168 (set_attr "type" "la")
2169 (set_attr "cpu_facility" "*,longdisp")
2170 (set_attr "z10prop" "z10_fwd_A1,z10_fwd_A1")])
2172 (define_insn_and_split "*la_31_and_cc"
2173 [(set (match_operand:SI 0 "register_operand" "=d")
2174 (and:SI (match_operand:QI 1 "address_operand" "p")
2175 (const_int 2147483647)))
2176 (clobber (reg:CC CC_REGNUM))]
2179 "&& reload_completed"
2181 (and:SI (match_dup 1) (const_int 2147483647)))]
2183 [(set_attr "op_type" "RX")
2184 (set_attr "type" "la")])
2186 (define_insn "force_la_31"
2187 [(set (match_operand:SI 0 "register_operand" "=d,d")
2188 (match_operand:QI 1 "address_operand" "ZR,ZT"))
2189 (use (const_int 0))]
2194 [(set_attr "op_type" "RX")
2195 (set_attr "type" "la")
2196 (set_attr "cpu_facility" "*,longdisp")
2197 (set_attr "z10prop" "z10_fwd_A1,z10_fwd_A1")])
2200 ; movhi instruction pattern(s).
2203 (define_expand "movhi"
2204 [(set (match_operand:HI 0 "nonimmediate_operand" "")
2205 (match_operand:HI 1 "general_operand" ""))]
2208 /* Make it explicit that loading a register from memory
2209 always sign-extends (at least) to SImode. */
2210 if (optimize && can_create_pseudo_p ()
2211 && register_operand (operands[0], VOIDmode)
2212 && GET_CODE (operands[1]) == MEM)
2214 rtx tmp = gen_reg_rtx (SImode);
2215 rtx ext = gen_rtx_SIGN_EXTEND (SImode, operands[1]);
2216 emit_insn (gen_rtx_SET (tmp, ext));
2217 operands[1] = gen_lowpart (HImode, tmp);
2221 (define_insn "*movhi"
2222 [(set (match_operand:HI 0 "nonimmediate_operand" "=d,d,d,d,d,R,T,b,Q,v,v,v,d,v,R")
2223 (match_operand:HI 1 "general_operand" " d,n,R,T,b,d,d,d,K,K,v,d,v,R,v"))]
2241 [(set_attr "op_type" "RR,RI,RX,RXY,RIL,RX,RXY,RIL,SIL,VRI,VRR,VRS,VRS,VRX,VRX")
2242 (set_attr "type" "lr,*,*,*,larl,store,store,store,*,*,*,*,*,*,*")
2243 (set_attr "cpu_facility" "*,*,*,longdisp,z10,*,longdisp,z10,z10,vx,vx,vx,vx,vx,vx")
2244 (set_attr "z10prop" "z10_fr_E1,
2252 z10_super,*,*,*,*,*,*")])
2255 [(set (match_operand:HI 0 "register_operand" "")
2256 (mem:HI (match_operand 1 "address_operand" "")))]
2257 "GET_CODE (operands[1]) == SYMBOL_REF
2258 && CONSTANT_POOL_ADDRESS_P (operands[1])
2259 && get_pool_mode (operands[1]) == HImode
2260 && GET_CODE (get_pool_constant (operands[1])) == CONST_INT"
2261 [(set (match_dup 0) (match_dup 2))]
2262 "operands[2] = get_pool_constant (operands[1]);")
2265 ; movqi instruction pattern(s).
2268 (define_expand "movqi"
2269 [(set (match_operand:QI 0 "nonimmediate_operand" "")
2270 (match_operand:QI 1 "general_operand" ""))]
2273 /* On z/Architecture, zero-extending from memory to register
2274 is just as fast as a QImode load. */
2275 if (TARGET_ZARCH && optimize && can_create_pseudo_p ()
2276 && register_operand (operands[0], VOIDmode)
2277 && GET_CODE (operands[1]) == MEM)
2279 rtx tmp = gen_reg_rtx (DImode);
2280 rtx ext = gen_rtx_ZERO_EXTEND (DImode, operands[1]);
2281 emit_insn (gen_rtx_SET (tmp, ext));
2282 operands[1] = gen_lowpart (QImode, tmp);
2286 (define_insn "*movqi"
2287 [(set (match_operand:QI 0 "nonimmediate_operand" "=d,d,d,d,R,T,Q,S,?Q,v,v,v,d,v,R")
2288 (match_operand:QI 1 "general_operand" " d,n,R,T,d,d,n,n,?Q,K,v,d,v,R,v"))]
2306 [(set_attr "op_type" "RR,RI,RX,RXY,RX,RXY,SI,SIY,SS,VRI,VRR,VRS,VRS,VRX,VRX")
2307 (set_attr "type" "lr,*,*,*,store,store,store,store,*,*,*,*,*,*,*")
2308 (set_attr "cpu_facility" "*,*,*,longdisp,*,longdisp,*,longdisp,*,vx,vx,vx,vx,vx,vx")
2309 (set_attr "z10prop" "z10_fr_E1,
2320 [(set (match_operand:QI 0 "nonimmediate_operand" "")
2321 (mem:QI (match_operand 1 "address_operand" "")))]
2322 "GET_CODE (operands[1]) == SYMBOL_REF
2323 && CONSTANT_POOL_ADDRESS_P (operands[1])
2324 && get_pool_mode (operands[1]) == QImode
2325 && GET_CODE (get_pool_constant (operands[1])) == CONST_INT"
2326 [(set (match_dup 0) (match_dup 2))]
2327 "operands[2] = get_pool_constant (operands[1]);")
2330 ; movstrictqi instruction pattern(s).
2333 (define_insn "*movstrictqi"
2334 [(set (strict_low_part (match_operand:QI 0 "register_operand" "+d,d"))
2335 (match_operand:QI 1 "memory_operand" "R,T"))]
2340 [(set_attr "op_type" "RX,RXY")
2341 (set_attr "cpu_facility" "*,longdisp")
2342 (set_attr "z10prop" "z10_super_E1,z10_super_E1")])
2345 ; movstricthi instruction pattern(s).
2348 (define_insn "*movstricthi"
2349 [(set (strict_low_part (match_operand:HI 0 "register_operand" "+d,d"))
2350 (match_operand:HI 1 "memory_operand" "Q,S"))
2351 (clobber (reg:CC CC_REGNUM))]
2356 [(set_attr "op_type" "RS,RSY")
2357 (set_attr "cpu_facility" "*,longdisp")
2358 (set_attr "z10prop" "z10_super_E1,z10_super_E1")])
2361 ; movstrictsi instruction pattern(s).
2364 (define_insn "movstrictsi"
2365 [(set (strict_low_part (match_operand:SI 0 "register_operand" "+d,d,d,d"))
2366 (match_operand:SI 1 "general_operand" "d,R,T,t"))]
2373 [(set_attr "op_type" "RR,RX,RXY,RRE")
2374 (set_attr "type" "lr,load,load,*")
2375 (set_attr "cpu_facility" "*,*,longdisp,*")
2376 (set_attr "z10prop" "z10_fr_E1,z10_fwd_A3,z10_fwd_A3,z10_super_E1")])
2379 ; mov(tf|td) instruction pattern(s).
2382 (define_expand "mov<mode>"
2383 [(set (match_operand:TD_TF 0 "nonimmediate_operand" "")
2384 (match_operand:TD_TF 1 "general_operand" ""))]
2388 (define_insn "*mov<mode>_64"
2389 [(set (match_operand:TD_TF 0 "nonimmediate_operand" "=f,f,f,o,d,S, d,o")
2390 (match_operand:TD_TF 1 "general_operand" " G,f,o,f,S,d,dT,d"))]
2401 [(set_attr "op_type" "RRE,RRE,*,*,RSY,RSY,*,*")
2402 (set_attr "type" "fsimptf,fsimptf,*,*,lm,stm,*,*")
2403 (set_attr "cpu_facility" "z196,*,*,*,*,*,*,*")])
2405 (define_insn "*mov<mode>_31"
2406 [(set (match_operand:TD_TF 0 "nonimmediate_operand" "=f,f,f,o")
2407 (match_operand:TD_TF 1 "general_operand" " G,f,o,f"))]
2414 [(set_attr "op_type" "RRE,RRE,*,*")
2415 (set_attr "type" "fsimptf,fsimptf,*,*")
2416 (set_attr "cpu_facility" "z196,*,*,*")])
2418 ; TFmode in GPRs splitters
2421 [(set (match_operand:TD_TF 0 "nonimmediate_operand" "")
2422 (match_operand:TD_TF 1 "general_operand" ""))]
2423 "TARGET_ZARCH && reload_completed
2424 && !s_operand (operands[0], <MODE>mode)
2425 && !s_operand (operands[1], <MODE>mode)
2426 && s390_split_ok_p (operands[0], operands[1], <MODE>mode, 0)"
2427 [(set (match_dup 2) (match_dup 4))
2428 (set (match_dup 3) (match_dup 5))]
2430 operands[2] = operand_subword (operands[0], 0, 0, <MODE>mode);
2431 operands[3] = operand_subword (operands[0], 1, 0, <MODE>mode);
2432 operands[4] = operand_subword (operands[1], 0, 0, <MODE>mode);
2433 operands[5] = operand_subword (operands[1], 1, 0, <MODE>mode);
2437 [(set (match_operand:TD_TF 0 "nonimmediate_operand" "")
2438 (match_operand:TD_TF 1 "general_operand" ""))]
2439 "TARGET_ZARCH && reload_completed
2440 && !s_operand (operands[0], <MODE>mode)
2441 && !s_operand (operands[1], <MODE>mode)
2442 && s390_split_ok_p (operands[0], operands[1], <MODE>mode, 1)"
2443 [(set (match_dup 2) (match_dup 4))
2444 (set (match_dup 3) (match_dup 5))]
2446 operands[2] = operand_subword (operands[0], 1, 0, <MODE>mode);
2447 operands[3] = operand_subword (operands[0], 0, 0, <MODE>mode);
2448 operands[4] = operand_subword (operands[1], 1, 0, <MODE>mode);
2449 operands[5] = operand_subword (operands[1], 0, 0, <MODE>mode);
2453 [(set (match_operand:TD_TF 0 "register_operand" "")
2454 (match_operand:TD_TF 1 "memory_operand" ""))]
2455 "TARGET_ZARCH && reload_completed
2456 && GENERAL_REG_P (operands[0])
2457 && !s_operand (operands[1], VOIDmode)"
2458 [(set (match_dup 0) (match_dup 1))]
2460 rtx addr = operand_subword (operands[0], 1, 0, <MODE>mode);
2461 addr = gen_lowpart (Pmode, addr);
2462 s390_load_address (addr, XEXP (operands[1], 0));
2463 operands[1] = replace_equiv_address (operands[1], addr);
2466 ; TFmode in BFPs splitters
2469 [(set (match_operand:TD_TF 0 "register_operand" "")
2470 (match_operand:TD_TF 1 "memory_operand" ""))]
2471 "reload_completed && offsettable_memref_p (operands[1])
2472 && FP_REG_P (operands[0])"
2473 [(set (match_dup 2) (match_dup 4))
2474 (set (match_dup 3) (match_dup 5))]
2476 operands[2] = simplify_gen_subreg (<HALF_TMODE>mode, operands[0],
2478 operands[3] = simplify_gen_subreg (<HALF_TMODE>mode, operands[0],
2480 operands[4] = adjust_address_nv (operands[1], <HALF_TMODE>mode, 0);
2481 operands[5] = adjust_address_nv (operands[1], <HALF_TMODE>mode, 8);
2485 [(set (match_operand:TD_TF 0 "memory_operand" "")
2486 (match_operand:TD_TF 1 "register_operand" ""))]
2487 "reload_completed && offsettable_memref_p (operands[0])
2488 && FP_REG_P (operands[1])"
2489 [(set (match_dup 2) (match_dup 4))
2490 (set (match_dup 3) (match_dup 5))]
2492 operands[2] = adjust_address_nv (operands[0], <HALF_TMODE>mode, 0);
2493 operands[3] = adjust_address_nv (operands[0], <HALF_TMODE>mode, 8);
2494 operands[4] = simplify_gen_subreg (<HALF_TMODE>mode, operands[1],
2496 operands[5] = simplify_gen_subreg (<HALF_TMODE>mode, operands[1],
2501 ; mov(df|dd) instruction pattern(s).
2504 (define_expand "mov<mode>"
2505 [(set (match_operand:DD_DF 0 "nonimmediate_operand" "")
2506 (match_operand:DD_DF 1 "general_operand" ""))]
2510 (define_insn "*mov<mode>_64dfp"
2511 [(set (match_operand:DD_DF 0 "nonimmediate_operand"
2512 "=f,f,f,d,f,f,R,T,d,d,d,d,b,T,v,v,v,d,v,R")
2513 (match_operand:DD_DF 1 "general_operand"
2514 " G,f,d,f,R,T,f,f,G,d,b,T,d,d,v,G,d,v,R,v"))]
2537 [(set_attr "op_type" "RRE,RR,RRE,RRE,RX,RXY,RX,RXY,RI,RRE,RIL,RXY,RIL,RXY,VRR,VRI,VRS,VRS,VRX,VRX")
2538 (set_attr "type" "fsimpdf,floaddf,floaddf,floaddf,floaddf,floaddf,
2539 fstoredf,fstoredf,*,lr,load,load,store,store,*,*,*,*,load,store")
2540 (set_attr "z10prop" "*,*,*,*,*,*,*,*,z10_fwd_A1,z10_fr_E1,z10_fwd_A3,z10_fwd_A3,z10_rec,z10_rec,*,*,*,*,*,*")
2541 (set_attr "cpu_facility" "z196,*,*,*,*,longdisp,*,longdisp,*,*,z10,*,z10,*,vx,vx,vx,vx,vx,vx")])
2543 (define_insn "*mov<mode>_64"
2544 [(set (match_operand:DD_DF 0 "nonimmediate_operand" "=f,f,f,f,R,T,d,d,d,d,b,T")
2545 (match_operand:DD_DF 1 "general_operand" " G,f,R,T,f,f,G,d,b,T,d,d"))]
2560 [(set_attr "op_type" "RRE,RR,RX,RXY,RX,RXY,RI,RRE,RIL,RXY,RIL,RXY")
2561 (set_attr "type" "fsimpdf,fload<mode>,fload<mode>,fload<mode>,
2562 fstore<mode>,fstore<mode>,*,lr,load,load,store,store")
2563 (set_attr "z10prop" "*,*,*,*,*,*,z10_fwd_A1,z10_fr_E1,z10_fwd_A3,z10_fwd_A3,z10_rec,z10_rec")
2564 (set_attr "cpu_facility" "z196,*,*,longdisp,*,longdisp,*,*,z10,*,z10,*")])
2566 (define_insn "*mov<mode>_31"
2567 [(set (match_operand:DD_DF 0 "nonimmediate_operand"
2568 "=f,f,f,f,R,T,d,d,Q,S, d,o")
2569 (match_operand:DD_DF 1 "general_operand"
2570 " G,f,R,T,f,f,Q,S,d,d,dPT,d"))]
2585 [(set_attr "op_type" "RRE,RR,RX,RXY,RX,RXY,RS,RSY,RS,RSY,*,*")
2586 (set_attr "type" "fsimpdf,fload<mode>,fload<mode>,fload<mode>,
2587 fstore<mode>,fstore<mode>,lm,lm,stm,stm,*,*")
2588 (set_attr "cpu_facility" "z196,*,*,longdisp,*,longdisp,*,longdisp,*,longdisp,*,*")])
2591 [(set (match_operand:DD_DF 0 "nonimmediate_operand" "")
2592 (match_operand:DD_DF 1 "general_operand" ""))]
2593 "!TARGET_ZARCH && reload_completed
2594 && !s_operand (operands[0], <MODE>mode)
2595 && !s_operand (operands[1], <MODE>mode)
2596 && s390_split_ok_p (operands[0], operands[1], <MODE>mode, 0)"
2597 [(set (match_dup 2) (match_dup 4))
2598 (set (match_dup 3) (match_dup 5))]
2600 operands[2] = operand_subword (operands[0], 0, 0, <MODE>mode);
2601 operands[3] = operand_subword (operands[0], 1, 0, <MODE>mode);
2602 operands[4] = operand_subword (operands[1], 0, 0, <MODE>mode);
2603 operands[5] = operand_subword (operands[1], 1, 0, <MODE>mode);
2607 [(set (match_operand:DD_DF 0 "nonimmediate_operand" "")
2608 (match_operand:DD_DF 1 "general_operand" ""))]
2609 "!TARGET_ZARCH && reload_completed
2610 && !s_operand (operands[0], <MODE>mode)
2611 && !s_operand (operands[1], <MODE>mode)
2612 && s390_split_ok_p (operands[0], operands[1], <MODE>mode, 1)"
2613 [(set (match_dup 2) (match_dup 4))
2614 (set (match_dup 3) (match_dup 5))]
2616 operands[2] = operand_subword (operands[0], 1, 0, <MODE>mode);
2617 operands[3] = operand_subword (operands[0], 0, 0, <MODE>mode);
2618 operands[4] = operand_subword (operands[1], 1, 0, <MODE>mode);
2619 operands[5] = operand_subword (operands[1], 0, 0, <MODE>mode);
2623 [(set (match_operand:DD_DF 0 "register_operand" "")
2624 (match_operand:DD_DF 1 "memory_operand" ""))]
2625 "!TARGET_ZARCH && reload_completed
2626 && !FP_REG_P (operands[0])
2627 && !s_operand (operands[1], VOIDmode)"
2628 [(set (match_dup 0) (match_dup 1))]
2630 rtx addr = operand_subword (operands[0], 1, 0, <MODE>mode);
2631 s390_load_address (addr, XEXP (operands[1], 0));
2632 operands[1] = replace_equiv_address (operands[1], addr);
2636 ; mov(sf|sd) instruction pattern(s).
2639 (define_insn "mov<mode>"
2640 [(set (match_operand:SD_SF 0 "nonimmediate_operand"
2641 "=f,f,f,f,f,f,R,T,d,d,d,d,d,b,R,T,v,v,v,d,v,R")
2642 (match_operand:SD_SF 1 "general_operand"
2643 " G,f,f,R,R,T,f,f,G,d,b,R,T,d,d,d,v,G,d,v,R,v"))]
2668 [(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")
2669 (set_attr "type" "fsimpsf,fsimpsf,fload<mode>,fload<mode>,fload<mode>,fload<mode>,
2670 fstore<mode>,fstore<mode>,*,lr,load,load,load,store,store,store,*,*,*,*,load,store")
2671 (set_attr "z10prop" "*,*,*,*,*,*,*,*,z10_fwd_A1,z10_fr_E1,z10_fr_E1,z10_fwd_A3,z10_fwd_A3,z10_rec,z10_rec,z10_rec,*,*,*,*,*,*")
2672 (set_attr "cpu_facility" "z196,vx,*,vx,*,longdisp,*,longdisp,*,*,z10,*,longdisp,z10,*,longdisp,vx,vx,vx,vx,vx,vx")])
2675 ; movcc instruction pattern
2678 (define_insn "movcc"
2679 [(set (match_operand:CC 0 "nonimmediate_operand" "=d,c,d,d,d,R,T")
2680 (match_operand:CC 1 "nonimmediate_operand" " d,d,c,R,T,d,d"))]
2690 [(set_attr "op_type" "RR,RI,RRE,RX,RXY,RX,RXY")
2691 (set_attr "type" "lr,*,*,load,load,store,store")
2692 (set_attr "cpu_facility" "*,*,*,*,longdisp,*,longdisp")
2693 (set_attr "z10prop" "z10_fr_E1,z10_super,*,z10_fwd_A3,z10_fwd_A3,z10_rec,z10_rec")
2694 (set_attr "z196prop" "*,*,z196_ends,*,*,*,*")])
2697 ; Block move (MVC) patterns.
2701 [(set (match_operand:BLK 0 "memory_operand" "=Q")
2702 (match_operand:BLK 1 "memory_operand" "Q"))
2703 (use (match_operand 2 "const_int_operand" "n"))]
2704 "INTVAL (operands[2]) >= 1 && INTVAL (operands[2]) <= 256"
2705 "mvc\t%O0(%2,%R0),%S1"
2706 [(set_attr "op_type" "SS")])
2708 ; This splitter converts a QI to QI mode copy into a BLK mode copy in
2709 ; order to have it implemented with mvc.
2712 [(set (match_operand:QI 0 "memory_operand" "")
2713 (match_operand:QI 1 "memory_operand" ""))]
2716 [(set (match_dup 0) (match_dup 1))
2717 (use (const_int 1))])]
2719 operands[0] = adjust_address (operands[0], BLKmode, 0);
2720 operands[1] = adjust_address (operands[1], BLKmode, 0);
2726 [(set (match_operand:BLK 0 "memory_operand" "")
2727 (match_operand:BLK 1 "memory_operand" ""))
2728 (use (match_operand 2 "const_int_operand" ""))])
2730 [(set (match_operand:BLK 3 "memory_operand" "")
2731 (match_operand:BLK 4 "memory_operand" ""))
2732 (use (match_operand 5 "const_int_operand" ""))])]
2733 "((INTVAL (operands[2]) > 16 && INTVAL (operands[5]) > 16)
2734 || (INTVAL (operands[2]) + INTVAL (operands[5]) <= 16))
2735 && s390_offset_p (operands[0], operands[3], operands[2])
2736 && s390_offset_p (operands[1], operands[4], operands[2])
2737 && !s390_overlap_p (operands[0], operands[1],
2738 INTVAL (operands[2]) + INTVAL (operands[5]))
2739 && INTVAL (operands[2]) + INTVAL (operands[5]) <= 256"
2741 [(set (match_dup 6) (match_dup 7))
2742 (use (match_dup 8))])]
2743 "operands[6] = gen_rtx_MEM (BLKmode, XEXP (operands[0], 0));
2744 operands[7] = gen_rtx_MEM (BLKmode, XEXP (operands[1], 0));
2745 operands[8] = GEN_INT (INTVAL (operands[2]) + INTVAL (operands[5]));")
2749 [(set (match_operand:BLK 0 "plus16_Q_operand" "")
2750 (match_operand:BLK 1 "plus16_Q_operand" ""))
2751 (use (match_operand 2 "const_int_operand" ""))])]
2752 "INTVAL (operands[2]) > 16 && INTVAL (operands[2]) <= 32"
2754 [(set (match_dup 0) (match_dup 1))
2755 (use (const_int 16))])
2757 [(set (match_dup 3) (match_dup 4))
2758 (use (match_dup 5))])]
2759 "operands[3] = change_address (operands[0], VOIDmode,
2760 plus_constant (Pmode, XEXP (operands[0], 0), 16));
2761 operands[4] = change_address (operands[1], VOIDmode,
2762 plus_constant (Pmode, XEXP (operands[1], 0), 16));
2763 operands[5] = GEN_INT (INTVAL (operands[2]) - 16);")
2767 ; load_multiple pattern(s).
2769 ; ??? Due to reload problems with replacing registers inside match_parallel
2770 ; we currently support load_multiple/store_multiple only after reload.
2773 (define_expand "load_multiple"
2774 [(match_par_dup 3 [(set (match_operand 0 "" "")
2775 (match_operand 1 "" ""))
2776 (use (match_operand 2 "" ""))])]
2785 /* Support only loading a constant number of fixed-point registers from
2786 memory and only bother with this if more than two */
2787 if (GET_CODE (operands[2]) != CONST_INT
2788 || INTVAL (operands[2]) < 2
2789 || INTVAL (operands[2]) > 16
2790 || GET_CODE (operands[1]) != MEM
2791 || GET_CODE (operands[0]) != REG
2792 || REGNO (operands[0]) >= 16)
2795 count = INTVAL (operands[2]);
2796 regno = REGNO (operands[0]);
2797 mode = GET_MODE (operands[0]);
2798 if (mode != SImode && (!TARGET_ZARCH || mode != DImode))
2801 operands[3] = gen_rtx_PARALLEL (VOIDmode, rtvec_alloc (count));
2802 if (!can_create_pseudo_p ())
2804 if (GET_CODE (XEXP (operands[1], 0)) == REG)
2806 from = XEXP (operands[1], 0);
2809 else if (GET_CODE (XEXP (operands[1], 0)) == PLUS
2810 && GET_CODE (XEXP (XEXP (operands[1], 0), 0)) == REG
2811 && GET_CODE (XEXP (XEXP (operands[1], 0), 1)) == CONST_INT)
2813 from = XEXP (XEXP (operands[1], 0), 0);
2814 off = INTVAL (XEXP (XEXP (operands[1], 0), 1));
2821 from = force_reg (Pmode, XEXP (operands[1], 0));
2825 for (i = 0; i < count; i++)
2826 XVECEXP (operands[3], 0, i)
2827 = gen_rtx_SET (gen_rtx_REG (mode, regno + i),
2828 change_address (operands[1], mode,
2829 plus_constant (Pmode, from,
2830 off + i * GET_MODE_SIZE (mode))));
2833 (define_insn "*load_multiple_di"
2834 [(match_parallel 0 "load_multiple_operation"
2835 [(set (match_operand:DI 1 "register_operand" "=r")
2836 (match_operand:DI 2 "s_operand" "S"))])]
2837 "reload_completed && TARGET_ZARCH"
2839 int words = XVECLEN (operands[0], 0);
2840 operands[0] = gen_rtx_REG (DImode, REGNO (operands[1]) + words - 1);
2841 return "lmg\t%1,%0,%S2";
2843 [(set_attr "op_type" "RSY")
2844 (set_attr "type" "lm")])
2846 (define_insn "*load_multiple_si"
2847 [(match_parallel 0 "load_multiple_operation"
2848 [(set (match_operand:SI 1 "register_operand" "=r,r")
2849 (match_operand:SI 2 "s_operand" "Q,S"))])]
2852 int words = XVECLEN (operands[0], 0);
2853 operands[0] = gen_rtx_REG (SImode, REGNO (operands[1]) + words - 1);
2854 return which_alternative == 0 ? "lm\t%1,%0,%S2" : "lmy\t%1,%0,%S2";
2856 [(set_attr "op_type" "RS,RSY")
2857 (set_attr "cpu_facility" "*,longdisp")
2858 (set_attr "type" "lm")])
2861 ; store multiple pattern(s).
2864 (define_expand "store_multiple"
2865 [(match_par_dup 3 [(set (match_operand 0 "" "")
2866 (match_operand 1 "" ""))
2867 (use (match_operand 2 "" ""))])]
2876 /* Support only storing a constant number of fixed-point registers to
2877 memory and only bother with this if more than two. */
2878 if (GET_CODE (operands[2]) != CONST_INT
2879 || INTVAL (operands[2]) < 2
2880 || INTVAL (operands[2]) > 16
2881 || GET_CODE (operands[0]) != MEM
2882 || GET_CODE (operands[1]) != REG
2883 || REGNO (operands[1]) >= 16)
2886 count = INTVAL (operands[2]);
2887 regno = REGNO (operands[1]);
2888 mode = GET_MODE (operands[1]);
2889 if (mode != SImode && (!TARGET_ZARCH || mode != DImode))
2892 operands[3] = gen_rtx_PARALLEL (VOIDmode, rtvec_alloc (count));
2894 if (!can_create_pseudo_p ())
2896 if (GET_CODE (XEXP (operands[0], 0)) == REG)
2898 to = XEXP (operands[0], 0);
2901 else if (GET_CODE (XEXP (operands[0], 0)) == PLUS
2902 && GET_CODE (XEXP (XEXP (operands[0], 0), 0)) == REG
2903 && GET_CODE (XEXP (XEXP (operands[0], 0), 1)) == CONST_INT)
2905 to = XEXP (XEXP (operands[0], 0), 0);
2906 off = INTVAL (XEXP (XEXP (operands[0], 0), 1));
2913 to = force_reg (Pmode, XEXP (operands[0], 0));
2917 for (i = 0; i < count; i++)
2918 XVECEXP (operands[3], 0, i)
2919 = gen_rtx_SET (change_address (operands[0], mode,
2920 plus_constant (Pmode, to,
2921 off + i * GET_MODE_SIZE (mode))),
2922 gen_rtx_REG (mode, regno + i));
2925 (define_insn "*store_multiple_di"
2926 [(match_parallel 0 "store_multiple_operation"
2927 [(set (match_operand:DI 1 "s_operand" "=S")
2928 (match_operand:DI 2 "register_operand" "r"))])]
2929 "reload_completed && TARGET_ZARCH"
2931 int words = XVECLEN (operands[0], 0);
2932 operands[0] = gen_rtx_REG (DImode, REGNO (operands[2]) + words - 1);
2933 return "stmg\t%2,%0,%S1";
2935 [(set_attr "op_type" "RSY")
2936 (set_attr "type" "stm")])
2939 (define_insn "*store_multiple_si"
2940 [(match_parallel 0 "store_multiple_operation"
2941 [(set (match_operand:SI 1 "s_operand" "=Q,S")
2942 (match_operand:SI 2 "register_operand" "r,r"))])]
2945 int words = XVECLEN (operands[0], 0);
2946 operands[0] = gen_rtx_REG (SImode, REGNO (operands[2]) + words - 1);
2947 return which_alternative == 0 ? "stm\t%2,%0,%S1" : "stmy\t%2,%0,%S1";
2949 [(set_attr "op_type" "RS,RSY")
2950 (set_attr "cpu_facility" "*,longdisp")
2951 (set_attr "type" "stm")])
2954 ;; String instructions.
2957 (define_insn "*execute_rl"
2958 [(match_parallel 0 "execute_operation"
2959 [(unspec [(match_operand 1 "register_operand" "a")
2960 (match_operand 2 "" "")
2961 (match_operand:SI 3 "larl_operand" "X")] UNSPEC_EXECUTE)])]
2962 "TARGET_Z10 && GET_MODE_CLASS (GET_MODE (operands[1])) == MODE_INT
2963 && GET_MODE_SIZE (GET_MODE (operands[1])) <= UNITS_PER_WORD"
2965 [(set_attr "op_type" "RIL")
2966 (set_attr "type" "cs")])
2968 (define_insn "*execute"
2969 [(match_parallel 0 "execute_operation"
2970 [(unspec [(match_operand 1 "register_operand" "a")
2971 (match_operand:BLK 2 "memory_operand" "R")
2972 (match_operand 3 "" "")] UNSPEC_EXECUTE)])]
2973 "GET_MODE_CLASS (GET_MODE (operands[1])) == MODE_INT
2974 && GET_MODE_SIZE (GET_MODE (operands[1])) <= UNITS_PER_WORD"
2976 [(set_attr "op_type" "RX")
2977 (set_attr "type" "cs")])
2981 ; strlenM instruction pattern(s).
2984 (define_expand "strlen<mode>"
2985 [(match_operand:P 0 "register_operand" "") ; result
2986 (match_operand:BLK 1 "memory_operand" "") ; input string
2987 (match_operand:SI 2 "immediate_operand" "") ; search character
2988 (match_operand:SI 3 "immediate_operand" "")] ; known alignment
2991 if (!TARGET_VX || operands[2] != const0_rtx)
2992 emit_insn (gen_strlen_srst<mode> (operands[0], operands[1],
2993 operands[2], operands[3]));
2995 s390_expand_vec_strlen (operands[0], operands[1], operands[3]);
3000 (define_expand "strlen_srst<mode>"
3001 [(set (reg:SI 0) (match_operand:SI 2 "immediate_operand" ""))
3004 (unspec:P [(const_int 0)
3005 (match_operand:BLK 1 "memory_operand" "")
3007 (match_operand 3 "immediate_operand" "")] UNSPEC_SRST))
3008 (clobber (scratch:P))
3009 (clobber (reg:CC CC_REGNUM))])
3011 [(set (match_operand:P 0 "register_operand" "")
3012 (minus:P (match_dup 4) (match_dup 5)))
3013 (clobber (reg:CC CC_REGNUM))])]
3016 operands[4] = gen_reg_rtx (Pmode);
3017 operands[5] = gen_reg_rtx (Pmode);
3018 emit_move_insn (operands[5], force_operand (XEXP (operands[1], 0), NULL_RTX));
3019 operands[1] = replace_equiv_address (operands[1], operands[5]);
3022 (define_insn "*strlen<mode>"
3023 [(set (match_operand:P 0 "register_operand" "=a")
3024 (unspec:P [(match_operand:P 2 "general_operand" "0")
3025 (mem:BLK (match_operand:P 3 "register_operand" "1"))
3027 (match_operand 4 "immediate_operand" "")] UNSPEC_SRST))
3028 (clobber (match_scratch:P 1 "=a"))
3029 (clobber (reg:CC CC_REGNUM))]
3031 "srst\t%0,%1\;jo\t.-4"
3032 [(set_attr "length" "8")
3033 (set_attr "type" "vs")])
3036 ; cmpstrM instruction pattern(s).
3039 (define_expand "cmpstrsi"
3040 [(set (reg:SI 0) (const_int 0))
3042 [(clobber (match_operand 3 "" ""))
3043 (clobber (match_dup 4))
3044 (set (reg:CCU CC_REGNUM)
3045 (compare:CCU (match_operand:BLK 1 "memory_operand" "")
3046 (match_operand:BLK 2 "memory_operand" "")))
3049 [(set (match_operand:SI 0 "register_operand" "=d")
3050 (unspec:SI [(reg:CCU CC_REGNUM)] UNSPEC_STRCMPCC_TO_INT))
3051 (clobber (reg:CC CC_REGNUM))])]
3054 /* As the result of CMPINT is inverted compared to what we need,
3055 we have to swap the operands. */
3056 rtx op1 = operands[2];
3057 rtx op2 = operands[1];
3058 rtx addr1 = gen_reg_rtx (Pmode);
3059 rtx addr2 = gen_reg_rtx (Pmode);
3061 emit_move_insn (addr1, force_operand (XEXP (op1, 0), NULL_RTX));
3062 emit_move_insn (addr2, force_operand (XEXP (op2, 0), NULL_RTX));
3063 operands[1] = replace_equiv_address_nv (op1, addr1);
3064 operands[2] = replace_equiv_address_nv (op2, addr2);
3065 operands[3] = addr1;
3066 operands[4] = addr2;
3069 (define_insn "*cmpstr<mode>"
3070 [(clobber (match_operand:P 0 "register_operand" "=d"))
3071 (clobber (match_operand:P 1 "register_operand" "=d"))
3072 (set (reg:CCU CC_REGNUM)
3073 (compare:CCU (mem:BLK (match_operand:P 2 "register_operand" "0"))
3074 (mem:BLK (match_operand:P 3 "register_operand" "1"))))
3077 "clst\t%0,%1\;jo\t.-4"
3078 [(set_attr "length" "8")
3079 (set_attr "type" "vs")])
3082 ; movstr instruction pattern.
3085 (define_expand "movstr"
3086 [(match_operand 0 "register_operand" "")
3087 (match_operand 1 "memory_operand" "")
3088 (match_operand 2 "memory_operand" "")]
3092 emit_insn (gen_movstrdi (operands[0], operands[1], operands[2]));
3094 emit_insn (gen_movstrsi (operands[0], operands[1], operands[2]));
3098 (define_expand "movstr<P:mode>"
3099 [(set (reg:SI 0) (const_int 0))
3101 [(clobber (match_dup 3))
3102 (set (match_operand:BLK 1 "memory_operand" "")
3103 (match_operand:BLK 2 "memory_operand" ""))
3104 (set (match_operand:P 0 "register_operand" "")
3105 (unspec:P [(match_dup 1)
3107 (reg:SI 0)] UNSPEC_MVST))
3108 (clobber (reg:CC CC_REGNUM))])]
3113 if (TARGET_VX && optimize_function_for_speed_p (cfun))
3115 s390_expand_vec_movstr (operands[0], operands[1], operands[2]);
3119 addr1 = gen_reg_rtx (Pmode);
3120 addr2 = gen_reg_rtx (Pmode);
3122 emit_move_insn (addr1, force_operand (XEXP (operands[1], 0), NULL_RTX));
3123 emit_move_insn (addr2, force_operand (XEXP (operands[2], 0), NULL_RTX));
3124 operands[1] = replace_equiv_address_nv (operands[1], addr1);
3125 operands[2] = replace_equiv_address_nv (operands[2], addr2);
3126 operands[3] = addr2;
3129 (define_insn "*movstr"
3130 [(clobber (match_operand:P 2 "register_operand" "=d"))
3131 (set (mem:BLK (match_operand:P 1 "register_operand" "0"))
3132 (mem:BLK (match_operand:P 3 "register_operand" "2")))
3133 (set (match_operand:P 0 "register_operand" "=d")
3134 (unspec:P [(mem:BLK (match_dup 1))
3135 (mem:BLK (match_dup 3))
3136 (reg:SI 0)] UNSPEC_MVST))
3137 (clobber (reg:CC CC_REGNUM))]
3139 "mvst\t%1,%2\;jo\t.-4"
3140 [(set_attr "length" "8")
3141 (set_attr "type" "vs")])
3145 ; movmemM instruction pattern(s).
3148 (define_expand "movmem<mode>"
3149 [(set (match_operand:BLK 0 "memory_operand" "") ; destination
3150 (match_operand:BLK 1 "memory_operand" "")) ; source
3151 (use (match_operand:GPR 2 "general_operand" "")) ; count
3152 (match_operand 3 "" "")]
3155 if (s390_expand_movmem (operands[0], operands[1], operands[2]))
3161 ; Move a block that is up to 256 bytes in length.
3162 ; The block length is taken as (operands[2] % 256) + 1.
3164 (define_expand "movmem_short"
3166 [(set (match_operand:BLK 0 "memory_operand" "")
3167 (match_operand:BLK 1 "memory_operand" ""))
3168 (use (match_operand 2 "nonmemory_operand" ""))
3169 (use (const:BLK (unspec:BLK [(const_int 0)] UNSPEC_INSN)))
3170 (clobber (match_dup 3))])]
3172 "operands[3] = gen_rtx_SCRATCH (Pmode);")
3174 (define_insn "*movmem_short"
3175 [(set (match_operand:BLK 0 "memory_operand" "=Q,Q,Q,Q")
3176 (match_operand:BLK 1 "memory_operand" "Q,Q,Q,Q"))
3177 (use (match_operand 2 "nonmemory_operand" "n,a,a,a"))
3178 (use (match_operand 3 "immediate_operand" "X,R,X,X"))
3179 (clobber (match_scratch:P 4 "=X,X,X,&a"))]
3180 "(GET_MODE (operands[2]) == Pmode || GET_MODE (operands[2]) == VOIDmode)"
3182 [(set_attr "type" "cs")
3183 (set_attr "cpu_facility" "*,*,z10,cpu_zarch")])
3186 [(set (match_operand:BLK 0 "memory_operand" "")
3187 (match_operand:BLK 1 "memory_operand" ""))
3188 (use (match_operand 2 "const_int_operand" ""))
3189 (use (match_operand 3 "immediate_operand" ""))
3190 (clobber (scratch))]
3193 [(set (match_dup 0) (match_dup 1))
3194 (use (match_dup 2))])]
3195 "operands[2] = GEN_INT ((INTVAL (operands[2]) & 0xff) + 1);")
3198 [(set (match_operand:BLK 0 "memory_operand" "")
3199 (match_operand:BLK 1 "memory_operand" ""))
3200 (use (match_operand 2 "register_operand" ""))
3201 (use (match_operand 3 "memory_operand" ""))
3202 (clobber (scratch))]
3205 [(unspec [(match_dup 2) (match_dup 3)
3206 (const_int 0)] UNSPEC_EXECUTE)
3207 (set (match_dup 0) (match_dup 1))
3208 (use (const_int 1))])]
3212 [(set (match_operand:BLK 0 "memory_operand" "")
3213 (match_operand:BLK 1 "memory_operand" ""))
3214 (use (match_operand 2 "register_operand" ""))
3215 (use (const:BLK (unspec:BLK [(const_int 0)] UNSPEC_INSN)))
3216 (clobber (scratch))]
3217 "TARGET_Z10 && reload_completed"
3219 [(unspec [(match_dup 2) (const_int 0)
3220 (label_ref (match_dup 3))] UNSPEC_EXECUTE)
3221 (set (match_dup 0) (match_dup 1))
3222 (use (const_int 1))])]
3223 "operands[3] = gen_label_rtx ();")
3226 [(set (match_operand:BLK 0 "memory_operand" "")
3227 (match_operand:BLK 1 "memory_operand" ""))
3228 (use (match_operand 2 "register_operand" ""))
3229 (use (const:BLK (unspec:BLK [(const_int 0)] UNSPEC_INSN)))
3230 (clobber (match_operand 3 "register_operand" ""))]
3231 "reload_completed && TARGET_CPU_ZARCH"
3232 [(set (match_dup 3) (label_ref (match_dup 4)))
3234 [(unspec [(match_dup 2) (mem:BLK (match_dup 3))
3235 (label_ref (match_dup 4))] UNSPEC_EXECUTE)
3236 (set (match_dup 0) (match_dup 1))
3237 (use (const_int 1))])]
3238 "operands[4] = gen_label_rtx ();")
3240 ; Move a block of arbitrary length.
3242 (define_expand "movmem_long"
3244 [(clobber (match_dup 2))
3245 (clobber (match_dup 3))
3246 (set (match_operand:BLK 0 "memory_operand" "")
3247 (match_operand:BLK 1 "memory_operand" ""))
3248 (use (match_operand 2 "general_operand" ""))
3250 (clobber (reg:CC CC_REGNUM))])]
3253 machine_mode sreg_mode = TARGET_ZARCH ? DImode : SImode;
3254 machine_mode dreg_mode = TARGET_ZARCH ? TImode : DImode;
3255 rtx reg0 = gen_reg_rtx (dreg_mode);
3256 rtx reg1 = gen_reg_rtx (dreg_mode);
3257 rtx addr0 = gen_lowpart (Pmode, gen_highpart (sreg_mode, reg0));
3258 rtx addr1 = gen_lowpart (Pmode, gen_highpart (sreg_mode, reg1));
3259 rtx len0 = gen_lowpart (Pmode, reg0);
3260 rtx len1 = gen_lowpart (Pmode, reg1);
3262 emit_clobber (reg0);
3263 emit_move_insn (addr0, force_operand (XEXP (operands[0], 0), NULL_RTX));
3264 emit_move_insn (len0, operands[2]);
3266 emit_clobber (reg1);
3267 emit_move_insn (addr1, force_operand (XEXP (operands[1], 0), NULL_RTX));
3268 emit_move_insn (len1, operands[2]);
3270 operands[0] = replace_equiv_address_nv (operands[0], addr0);
3271 operands[1] = replace_equiv_address_nv (operands[1], addr1);
3276 (define_insn "*movmem_long"
3277 [(clobber (match_operand:<DBL> 0 "register_operand" "=d"))
3278 (clobber (match_operand:<DBL> 1 "register_operand" "=d"))
3279 (set (mem:BLK (subreg:P (match_operand:<DBL> 2 "register_operand" "0") 0))
3280 (mem:BLK (subreg:P (match_operand:<DBL> 3 "register_operand" "1") 0)))
3283 (clobber (reg:CC CC_REGNUM))]
3284 "TARGET_64BIT || !TARGET_ZARCH"
3285 "mvcle\t%0,%1,0\;jo\t.-4"
3286 [(set_attr "length" "8")
3287 (set_attr "type" "vs")])
3289 (define_insn "*movmem_long_31z"
3290 [(clobber (match_operand:TI 0 "register_operand" "=d"))
3291 (clobber (match_operand:TI 1 "register_operand" "=d"))
3292 (set (mem:BLK (subreg:SI (match_operand:TI 2 "register_operand" "0") 4))
3293 (mem:BLK (subreg:SI (match_operand:TI 3 "register_operand" "1") 4)))
3296 (clobber (reg:CC CC_REGNUM))]
3297 "!TARGET_64BIT && TARGET_ZARCH"
3298 "mvcle\t%0,%1,0\;jo\t.-4"
3299 [(set_attr "length" "8")
3300 (set_attr "type" "vs")])
3307 (define_expand "signbit<mode>2"
3308 [(set (reg:CCZ CC_REGNUM)
3309 (unspec:CCZ [(match_operand:FP_ALL 1 "register_operand" "f")
3312 (set (match_operand:SI 0 "register_operand" "=d")
3313 (unspec:SI [(reg:CCZ CC_REGNUM)] UNSPEC_CC_TO_INT))]
3316 operands[2] = GEN_INT (S390_TDC_SIGNBIT_SET);
3319 (define_expand "isinf<mode>2"
3320 [(set (reg:CCZ CC_REGNUM)
3321 (unspec:CCZ [(match_operand:FP_ALL 1 "register_operand" "f")
3324 (set (match_operand:SI 0 "register_operand" "=d")
3325 (unspec:SI [(reg:CCZ CC_REGNUM)] UNSPEC_CC_TO_INT))]
3328 operands[2] = GEN_INT (S390_TDC_INFINITY);
3331 ; This extracts CC into a GPR properly shifted. The actual IPM
3332 ; instruction will be issued by reload. The constraint of operand 1
3333 ; forces reload to use a GPR. So reload will issue a movcc insn for
3334 ; copying CC into a GPR first.
3335 (define_insn_and_split "*cc_to_int"
3336 [(set (match_operand:SI 0 "nonimmediate_operand" "=d")
3337 (unspec:SI [(match_operand 1 "register_operand" "0")]
3342 [(set (match_dup 0) (lshiftrt:SI (match_dup 0) (const_int 28)))])
3344 ; This insn is used to generate all variants of the Test Data Class
3345 ; instruction, namely tcxb, tcdb, and tceb. The insn's first operand
3346 ; is the register to be tested and the second one is the bit mask
3347 ; specifying the required test(s).
3349 ; tcxb, tcdb, tceb, tdcxt, tdcdt, tdcet
3350 (define_insn "*TDC_insn_<mode>"
3351 [(set (reg:CCZ CC_REGNUM)
3352 (unspec:CCZ [(match_operand:FP_ALL 0 "register_operand" "f")
3353 (match_operand:SI 1 "const_int_operand")] UNSPEC_TDC_INSN))]
3355 "t<_d>c<xde><bt>\t%0,%1"
3356 [(set_attr "op_type" "RXE")
3357 (set_attr "type" "fsimp<mode>")])
3362 ; setmemM instruction pattern(s).
3365 (define_expand "setmem<mode>"
3366 [(set (match_operand:BLK 0 "memory_operand" "")
3367 (match_operand:QI 2 "general_operand" ""))
3368 (use (match_operand:GPR 1 "general_operand" ""))
3369 (match_operand 3 "" "")]
3371 "s390_expand_setmem (operands[0], operands[1], operands[2]); DONE;")
3373 ; Clear a block that is up to 256 bytes in length.
3374 ; The block length is taken as (operands[1] % 256) + 1.
3376 (define_expand "clrmem_short"
3378 [(set (match_operand:BLK 0 "memory_operand" "")
3380 (use (match_operand 1 "nonmemory_operand" ""))
3381 (use (const:BLK (unspec:BLK [(const_int 0)] UNSPEC_INSN)))
3382 (clobber (match_dup 2))
3383 (clobber (reg:CC CC_REGNUM))])]
3385 "operands[2] = gen_rtx_SCRATCH (Pmode);")
3387 (define_insn "*clrmem_short"
3388 [(set (match_operand:BLK 0 "memory_operand" "=Q,Q,Q,Q")
3390 (use (match_operand 1 "nonmemory_operand" "n,a,a,a"))
3391 (use (match_operand 2 "immediate_operand" "X,R,X,X"))
3392 (clobber (match_scratch:P 3 "=X,X,X,&a"))
3393 (clobber (reg:CC CC_REGNUM))]
3394 "(GET_MODE (operands[1]) == Pmode || GET_MODE (operands[1]) == VOIDmode)"
3396 [(set_attr "type" "cs")
3397 (set_attr "cpu_facility" "*,*,z10,cpu_zarch")])
3400 [(set (match_operand:BLK 0 "memory_operand" "")
3402 (use (match_operand 1 "const_int_operand" ""))
3403 (use (match_operand 2 "immediate_operand" ""))
3405 (clobber (reg:CC CC_REGNUM))]
3408 [(set (match_dup 0) (const_int 0))
3410 (clobber (reg:CC CC_REGNUM))])]
3411 "operands[1] = GEN_INT ((INTVAL (operands[1]) & 0xff) + 1);")
3414 [(set (match_operand:BLK 0 "memory_operand" "")
3416 (use (match_operand 1 "register_operand" ""))
3417 (use (match_operand 2 "memory_operand" ""))
3419 (clobber (reg:CC CC_REGNUM))]
3422 [(unspec [(match_dup 1) (match_dup 2)
3423 (const_int 0)] UNSPEC_EXECUTE)
3424 (set (match_dup 0) (const_int 0))
3426 (clobber (reg:CC CC_REGNUM))])]
3430 [(set (match_operand:BLK 0 "memory_operand" "")
3432 (use (match_operand 1 "register_operand" ""))
3433 (use (const:BLK (unspec:BLK [(const_int 0)] UNSPEC_INSN)))
3435 (clobber (reg:CC CC_REGNUM))]
3436 "TARGET_Z10 && reload_completed"
3438 [(unspec [(match_dup 1) (const_int 0)
3439 (label_ref (match_dup 3))] UNSPEC_EXECUTE)
3440 (set (match_dup 0) (const_int 0))
3442 (clobber (reg:CC CC_REGNUM))])]
3443 "operands[3] = gen_label_rtx ();")
3446 [(set (match_operand:BLK 0 "memory_operand" "")
3448 (use (match_operand 1 "register_operand" ""))
3449 (use (const:BLK (unspec:BLK [(const_int 0)] UNSPEC_INSN)))
3450 (clobber (match_operand 2 "register_operand" ""))
3451 (clobber (reg:CC CC_REGNUM))]
3452 "reload_completed && TARGET_CPU_ZARCH"
3453 [(set (match_dup 2) (label_ref (match_dup 3)))
3455 [(unspec [(match_dup 1) (mem:BLK (match_dup 2))
3456 (label_ref (match_dup 3))] UNSPEC_EXECUTE)
3457 (set (match_dup 0) (const_int 0))
3459 (clobber (reg:CC CC_REGNUM))])]
3460 "operands[3] = gen_label_rtx ();")
3462 ; Initialize a block of arbitrary length with (operands[2] % 256).
3464 (define_expand "setmem_long_<P:mode>"
3466 [(clobber (match_dup 1))
3467 (set (match_operand:BLK 0 "memory_operand" "")
3468 (unspec:BLK [(match_operand:P 2 "setmem_operand" "")
3469 (match_dup 4)] UNSPEC_REPLICATE_BYTE))
3471 (clobber (reg:CC CC_REGNUM))])]
3474 machine_mode sreg_mode = TARGET_ZARCH ? DImode : SImode;
3475 machine_mode dreg_mode = TARGET_ZARCH ? TImode : DImode;
3476 rtx reg0 = gen_reg_rtx (dreg_mode);
3477 rtx reg1 = gen_reg_rtx (dreg_mode);
3478 rtx addr0 = gen_lowpart (Pmode, gen_highpart (sreg_mode, reg0));
3479 rtx len0 = gen_lowpart (Pmode, reg0);
3481 emit_clobber (reg0);
3482 emit_move_insn (addr0, force_operand (XEXP (operands[0], 0), NULL_RTX));
3483 emit_move_insn (len0, operands[1]);
3485 emit_move_insn (reg1, const0_rtx);
3487 operands[0] = replace_equiv_address_nv (operands[0], addr0);
3490 operands[4] = gen_lowpart (Pmode, operands[1]);
3493 ; Patterns for 31 bit + Esa and 64 bit + Zarch.
3495 (define_insn "*setmem_long"
3496 [(clobber (match_operand:<DBL> 0 "register_operand" "=d"))
3497 (set (mem:BLK (subreg:P (match_operand:<DBL> 3 "register_operand" "0") 0))
3498 (unspec:BLK [(match_operand:P 2 "setmem_operand" "Y")
3499 (subreg:P (match_dup 3) <modesize>)]
3500 UNSPEC_REPLICATE_BYTE))
3501 (use (match_operand:<DBL> 1 "register_operand" "d"))
3502 (clobber (reg:CC CC_REGNUM))]
3503 "TARGET_64BIT || !TARGET_ZARCH"
3504 "mvcle\t%0,%1,%Y2\;jo\t.-4"
3505 [(set_attr "length" "8")
3506 (set_attr "type" "vs")])
3508 (define_insn "*setmem_long_and"
3509 [(clobber (match_operand:<DBL> 0 "register_operand" "=d"))
3510 (set (mem:BLK (subreg:P (match_operand:<DBL> 3 "register_operand" "0") 0))
3511 (unspec:BLK [(zero_extend:P (match_operand:QI 2 "setmem_operand" "Y"))
3512 (subreg:P (match_dup 3) <modesize>)]
3513 UNSPEC_REPLICATE_BYTE))
3514 (use (match_operand:<DBL> 1 "register_operand" "d"))
3515 (clobber (reg:CC CC_REGNUM))]
3516 "(TARGET_64BIT || !TARGET_ZARCH)"
3517 "mvcle\t%0,%1,%Y2\;jo\t.-4"
3518 [(set_attr "length" "8")
3519 (set_attr "type" "vs")])
3521 ; Variants for 31 bit + Zarch, necessary because of the odd in-register offsets
3522 ; of the SImode subregs.
3524 (define_insn "*setmem_long_31z"
3525 [(clobber (match_operand:TI 0 "register_operand" "=d"))
3526 (set (mem:BLK (subreg:SI (match_operand:TI 3 "register_operand" "0") 4))
3527 (unspec:BLK [(match_operand:SI 2 "setmem_operand" "Y")
3528 (subreg:SI (match_dup 3) 12)] UNSPEC_REPLICATE_BYTE))
3529 (use (match_operand:TI 1 "register_operand" "d"))
3530 (clobber (reg:CC CC_REGNUM))]
3531 "!TARGET_64BIT && TARGET_ZARCH"
3532 "mvcle\t%0,%1,%Y2\;jo\t.-4"
3533 [(set_attr "length" "8")
3534 (set_attr "type" "vs")])
3536 (define_insn "*setmem_long_and_31z"
3537 [(clobber (match_operand:TI 0 "register_operand" "=d"))
3538 (set (mem:BLK (subreg:SI (match_operand:TI 3 "register_operand" "0") 4))
3539 (unspec:BLK [(zero_extend:SI (match_operand:QI 2 "setmem_operand" "Y"))
3540 (subreg:SI (match_dup 3) 12)] UNSPEC_REPLICATE_BYTE))
3541 (use (match_operand:TI 1 "register_operand" "d"))
3542 (clobber (reg:CC CC_REGNUM))]
3543 "(!TARGET_64BIT && TARGET_ZARCH)"
3544 "mvcle\t%0,%1,%Y2\;jo\t.-4"
3545 [(set_attr "length" "8")
3546 (set_attr "type" "vs")])
3549 ; cmpmemM instruction pattern(s).
3552 (define_expand "cmpmemsi"
3553 [(set (match_operand:SI 0 "register_operand" "")
3554 (compare:SI (match_operand:BLK 1 "memory_operand" "")
3555 (match_operand:BLK 2 "memory_operand" "") ) )
3556 (use (match_operand:SI 3 "general_operand" ""))
3557 (use (match_operand:SI 4 "" ""))]
3560 if (s390_expand_cmpmem (operands[0], operands[1],
3561 operands[2], operands[3]))
3567 ; Compare a block that is up to 256 bytes in length.
3568 ; The block length is taken as (operands[2] % 256) + 1.
3570 (define_expand "cmpmem_short"
3572 [(set (reg:CCU CC_REGNUM)
3573 (compare:CCU (match_operand:BLK 0 "memory_operand" "")
3574 (match_operand:BLK 1 "memory_operand" "")))
3575 (use (match_operand 2 "nonmemory_operand" ""))
3576 (use (const:BLK (unspec:BLK [(const_int 0)] UNSPEC_INSN)))
3577 (clobber (match_dup 3))])]
3579 "operands[3] = gen_rtx_SCRATCH (Pmode);")
3581 (define_insn "*cmpmem_short"
3582 [(set (reg:CCU CC_REGNUM)
3583 (compare:CCU (match_operand:BLK 0 "memory_operand" "Q,Q,Q,Q")
3584 (match_operand:BLK 1 "memory_operand" "Q,Q,Q,Q")))
3585 (use (match_operand 2 "nonmemory_operand" "n,a,a,a"))
3586 (use (match_operand 3 "immediate_operand" "X,R,X,X"))
3587 (clobber (match_scratch:P 4 "=X,X,X,&a"))]
3588 "(GET_MODE (operands[2]) == Pmode || GET_MODE (operands[2]) == VOIDmode)"
3590 [(set_attr "type" "cs")
3591 (set_attr "cpu_facility" "*,*,z10,cpu_zarch")])
3594 [(set (reg:CCU CC_REGNUM)
3595 (compare:CCU (match_operand:BLK 0 "memory_operand" "")
3596 (match_operand:BLK 1 "memory_operand" "")))
3597 (use (match_operand 2 "const_int_operand" ""))
3598 (use (match_operand 3 "immediate_operand" ""))
3599 (clobber (scratch))]
3602 [(set (reg:CCU CC_REGNUM) (compare:CCU (match_dup 0) (match_dup 1)))
3603 (use (match_dup 2))])]
3604 "operands[2] = GEN_INT ((INTVAL (operands[2]) & 0xff) + 1);")
3607 [(set (reg:CCU CC_REGNUM)
3608 (compare:CCU (match_operand:BLK 0 "memory_operand" "")
3609 (match_operand:BLK 1 "memory_operand" "")))
3610 (use (match_operand 2 "register_operand" ""))
3611 (use (match_operand 3 "memory_operand" ""))
3612 (clobber (scratch))]
3615 [(unspec [(match_dup 2) (match_dup 3)
3616 (const_int 0)] UNSPEC_EXECUTE)
3617 (set (reg:CCU CC_REGNUM) (compare:CCU (match_dup 0) (match_dup 1)))
3618 (use (const_int 1))])]
3622 [(set (reg:CCU CC_REGNUM)
3623 (compare:CCU (match_operand:BLK 0 "memory_operand" "")
3624 (match_operand:BLK 1 "memory_operand" "")))
3625 (use (match_operand 2 "register_operand" ""))
3626 (use (const:BLK (unspec:BLK [(const_int 0)] UNSPEC_INSN)))
3627 (clobber (scratch))]
3628 "TARGET_Z10 && reload_completed"
3630 [(unspec [(match_dup 2) (const_int 0)
3631 (label_ref (match_dup 4))] UNSPEC_EXECUTE)
3632 (set (reg:CCU CC_REGNUM) (compare:CCU (match_dup 0) (match_dup 1)))
3633 (use (const_int 1))])]
3634 "operands[4] = gen_label_rtx ();")
3637 [(set (reg:CCU CC_REGNUM)
3638 (compare:CCU (match_operand:BLK 0 "memory_operand" "")
3639 (match_operand:BLK 1 "memory_operand" "")))
3640 (use (match_operand 2 "register_operand" ""))
3641 (use (const:BLK (unspec:BLK [(const_int 0)] UNSPEC_INSN)))
3642 (clobber (match_operand 3 "register_operand" ""))]
3643 "reload_completed && TARGET_CPU_ZARCH"
3644 [(set (match_dup 3) (label_ref (match_dup 4)))
3646 [(unspec [(match_dup 2) (mem:BLK (match_dup 3))
3647 (label_ref (match_dup 4))] UNSPEC_EXECUTE)
3648 (set (reg:CCU CC_REGNUM) (compare:CCU (match_dup 0) (match_dup 1)))
3649 (use (const_int 1))])]
3650 "operands[4] = gen_label_rtx ();")
3652 ; Compare a block of arbitrary length.
3654 (define_expand "cmpmem_long"
3656 [(clobber (match_dup 2))
3657 (clobber (match_dup 3))
3658 (set (reg:CCU CC_REGNUM)
3659 (compare:CCU (match_operand:BLK 0 "memory_operand" "")
3660 (match_operand:BLK 1 "memory_operand" "")))
3661 (use (match_operand 2 "general_operand" ""))
3662 (use (match_dup 3))])]
3665 machine_mode sreg_mode = TARGET_ZARCH ? DImode : SImode;
3666 machine_mode dreg_mode = TARGET_ZARCH ? TImode : DImode;
3667 rtx reg0 = gen_reg_rtx (dreg_mode);
3668 rtx reg1 = gen_reg_rtx (dreg_mode);
3669 rtx addr0 = gen_lowpart (Pmode, gen_highpart (sreg_mode, reg0));
3670 rtx addr1 = gen_lowpart (Pmode, gen_highpart (sreg_mode, reg1));
3671 rtx len0 = gen_lowpart (Pmode, reg0);
3672 rtx len1 = gen_lowpart (Pmode, reg1);
3674 emit_clobber (reg0);
3675 emit_move_insn (addr0, force_operand (XEXP (operands[0], 0), NULL_RTX));
3676 emit_move_insn (len0, operands[2]);
3678 emit_clobber (reg1);
3679 emit_move_insn (addr1, force_operand (XEXP (operands[1], 0), NULL_RTX));
3680 emit_move_insn (len1, operands[2]);
3682 operands[0] = replace_equiv_address_nv (operands[0], addr0);
3683 operands[1] = replace_equiv_address_nv (operands[1], addr1);
3688 (define_insn "*cmpmem_long"
3689 [(clobber (match_operand:<DBL> 0 "register_operand" "=d"))
3690 (clobber (match_operand:<DBL> 1 "register_operand" "=d"))
3691 (set (reg:CCU CC_REGNUM)
3692 (compare:CCU (mem:BLK (subreg:P (match_operand:<DBL> 2 "register_operand" "0") 0))
3693 (mem:BLK (subreg:P (match_operand:<DBL> 3 "register_operand" "1") 0))))
3695 (use (match_dup 3))]
3696 "TARGET_64BIT || !TARGET_ZARCH"
3697 "clcle\t%0,%1,0\;jo\t.-4"
3698 [(set_attr "length" "8")
3699 (set_attr "type" "vs")])
3701 (define_insn "*cmpmem_long_31z"
3702 [(clobber (match_operand:TI 0 "register_operand" "=d"))
3703 (clobber (match_operand:TI 1 "register_operand" "=d"))
3704 (set (reg:CCU CC_REGNUM)
3705 (compare:CCU (mem:BLK (subreg:SI (match_operand:TI 2 "register_operand" "0") 4))
3706 (mem:BLK (subreg:SI (match_operand:TI 3 "register_operand" "1") 4))))
3708 (use (match_dup 3))]
3709 "!TARGET_64BIT && TARGET_ZARCH"
3710 "clcle\t%0,%1,0\;jo\t.-4"
3711 [(set_attr "op_type" "NN")
3712 (set_attr "type" "vs")
3713 (set_attr "length" "8")])
3715 ; Convert CCUmode condition code to integer.
3716 ; Result is zero if EQ, positive if LTU, negative if GTU.
3718 (define_insn_and_split "cmpint"
3719 [(set (match_operand:SI 0 "register_operand" "=d")
3720 (unspec:SI [(match_operand:CCU 1 "register_operand" "0")]
3721 UNSPEC_STRCMPCC_TO_INT))
3722 (clobber (reg:CC CC_REGNUM))]
3726 [(set (match_dup 0) (ashift:SI (match_dup 0) (const_int 2)))
3728 [(set (match_dup 0) (ashiftrt:SI (match_dup 0) (const_int 30)))
3729 (clobber (reg:CC CC_REGNUM))])])
3731 (define_insn_and_split "*cmpint_cc"
3732 [(set (reg CC_REGNUM)
3733 (compare (unspec:SI [(match_operand:CCU 1 "register_operand" "0")]
3734 UNSPEC_STRCMPCC_TO_INT)
3736 (set (match_operand:SI 0 "register_operand" "=d")
3737 (unspec:SI [(match_dup 1)] UNSPEC_STRCMPCC_TO_INT))]
3738 "s390_match_ccmode (insn, CCSmode)"
3740 "&& reload_completed"
3741 [(set (match_dup 0) (ashift:SI (match_dup 0) (const_int 2)))
3743 [(set (match_dup 2) (match_dup 3))
3744 (set (match_dup 0) (ashiftrt:SI (match_dup 0) (const_int 30)))])]
3746 rtx result = gen_rtx_ASHIFTRT (SImode, operands[0], GEN_INT (30));
3747 operands[2] = SET_DEST (XVECEXP (PATTERN (curr_insn), 0, 0));
3748 operands[3] = gen_rtx_COMPARE (GET_MODE (operands[2]), result, const0_rtx);
3751 (define_insn_and_split "*cmpint_sign"
3752 [(set (match_operand:DI 0 "register_operand" "=d")
3753 (sign_extend:DI (unspec:SI [(match_operand:CCU 1 "register_operand" "0")]
3754 UNSPEC_STRCMPCC_TO_INT)))
3755 (clobber (reg:CC CC_REGNUM))]
3758 "&& reload_completed"
3759 [(set (match_dup 0) (ashift:DI (match_dup 0) (const_int 34)))
3761 [(set (match_dup 0) (ashiftrt:DI (match_dup 0) (const_int 62)))
3762 (clobber (reg:CC CC_REGNUM))])])
3764 (define_insn_and_split "*cmpint_sign_cc"
3765 [(set (reg CC_REGNUM)
3766 (compare (ashiftrt:DI (ashift:DI (subreg:DI
3767 (unspec:SI [(match_operand:CCU 1 "register_operand" "0")]
3768 UNSPEC_STRCMPCC_TO_INT) 0)
3769 (const_int 32)) (const_int 32))
3771 (set (match_operand:DI 0 "register_operand" "=d")
3772 (sign_extend:DI (unspec:SI [(match_dup 1)] UNSPEC_STRCMPCC_TO_INT)))]
3773 "s390_match_ccmode (insn, CCSmode) && TARGET_ZARCH"
3775 "&& reload_completed"
3776 [(set (match_dup 0) (ashift:DI (match_dup 0) (const_int 34)))
3778 [(set (match_dup 2) (match_dup 3))
3779 (set (match_dup 0) (ashiftrt:DI (match_dup 0) (const_int 62)))])]
3781 rtx result = gen_rtx_ASHIFTRT (DImode, operands[0], GEN_INT (62));
3782 operands[2] = SET_DEST (XVECEXP (PATTERN (curr_insn), 0, 0));
3783 operands[3] = gen_rtx_COMPARE (GET_MODE (operands[2]), result, const0_rtx);
3788 ;;- Conversion instructions.
3791 (define_insn "*sethighpartsi"
3792 [(set (match_operand:SI 0 "register_operand" "=d,d")
3793 (unspec:SI [(match_operand:BLK 1 "s_operand" "Q,S")
3794 (match_operand 2 "const_int_operand" "n,n")] UNSPEC_ICM))
3795 (clobber (reg:CC CC_REGNUM))]
3800 [(set_attr "op_type" "RS,RSY")
3801 (set_attr "cpu_facility" "*,longdisp")
3802 (set_attr "z10prop" "z10_super_E1,z10_super_E1")])
3804 (define_insn "*sethighpartdi_64"
3805 [(set (match_operand:DI 0 "register_operand" "=d")
3806 (unspec:DI [(match_operand:BLK 1 "s_operand" "S")
3807 (match_operand 2 "const_int_operand" "n")] UNSPEC_ICM))
3808 (clobber (reg:CC CC_REGNUM))]
3811 [(set_attr "op_type" "RSY")
3812 (set_attr "z10prop" "z10_super")])
3814 (define_insn "*sethighpartdi_31"
3815 [(set (match_operand:DI 0 "register_operand" "=d,d")
3816 (unspec:DI [(match_operand:BLK 1 "s_operand" "Q,S")
3817 (match_operand 2 "const_int_operand" "n,n")] UNSPEC_ICM))
3818 (clobber (reg:CC CC_REGNUM))]
3823 [(set_attr "op_type" "RS,RSY")
3824 (set_attr "cpu_facility" "*,longdisp")
3825 (set_attr "z10prop" "z10_super_E1,z10_super_E1")])
3828 ; extv instruction patterns
3831 ; FIXME: This expander needs to be converted from DI to GPR as well
3832 ; after resolving some issues with it.
3834 (define_expand "extzv"
3836 [(set (match_operand:DI 0 "register_operand" "=d")
3838 (match_operand:DI 1 "register_operand" "d")
3839 (match_operand 2 "const_int_operand" "") ; size
3840 (match_operand 3 "const_int_operand" ""))) ; start
3841 (clobber (reg:CC CC_REGNUM))])]
3844 if (! EXTRACT_ARGS_IN_RANGE (INTVAL (operands[2]), INTVAL (operands[3]), 64))
3846 /* Starting with zEC12 there is risbgn not clobbering CC. */
3849 emit_move_insn (operands[0],
3850 gen_rtx_ZERO_EXTRACT (DImode,
3858 (define_insn "*extzv<mode><clobbercc_or_nocc>"
3859 [(set (match_operand:GPR 0 "register_operand" "=d")
3861 (match_operand:GPR 1 "register_operand" "d")
3862 (match_operand 2 "const_int_operand" "") ; size
3863 (match_operand 3 "const_int_operand" ""))) ; start
3865 "<z10_or_zEC12_cond>
3866 && EXTRACT_ARGS_IN_RANGE (INTVAL (operands[2]), INTVAL (operands[3]),
3867 GET_MODE_BITSIZE (<MODE>mode))"
3868 "<risbg_n>\t%0,%1,64-%2,128+63,<bitoff_plus>%3+%2" ; dst, src, start, end, shift
3869 [(set_attr "op_type" "RIE")
3870 (set_attr "z10prop" "z10_super_E1")])
3872 ; 64 bit: (a & -16) | ((b >> 8) & 15)
3873 (define_insn "*extzvdi<clobbercc_or_nocc>_lshiftrt"
3874 [(set (zero_extract:DI (match_operand:DI 0 "register_operand" "+d")
3875 (match_operand 1 "const_int_operand" "") ; size
3876 (match_operand 2 "const_int_operand" "")) ; start
3877 (lshiftrt:DI (match_operand:DI 3 "register_operand" "d")
3878 (match_operand:DI 4 "nonzero_shift_count_operand" "")))]
3879 "<z10_or_zEC12_cond>
3880 && EXTRACT_ARGS_IN_RANGE (INTVAL (operands[1]), INTVAL (operands[2]), 64)
3881 && 64 - UINTVAL (operands[4]) >= UINTVAL (operands[1])"
3882 "<risbg_n>\t%0,%3,%2,%2+%1-1,128-%2-%1-%4"
3883 [(set_attr "op_type" "RIE")
3884 (set_attr "z10prop" "z10_super_E1")])
3886 ; 32 bit: (a & -16) | ((b >> 8) & 15)
3887 (define_insn "*<risbg_n>_ior_and_sr_ze"
3888 [(set (match_operand:SI 0 "register_operand" "=d")
3890 (match_operand:SI 1 "register_operand" "0")
3891 (match_operand:SI 2 "const_int_operand" ""))
3894 (match_operand:DI 3 "register_operand" "d")
3895 (match_operand 4 "const_int_operand" "") ; size
3896 (match_operand 5 "const_int_operand" "")) ; start
3898 "<z10_or_zEC12_cond>
3899 && EXTRACT_ARGS_IN_RANGE (INTVAL (operands[4]), INTVAL (operands[5]), 64)
3900 && UINTVAL (operands[2]) == (~(0ULL) << UINTVAL (operands[4]))"
3901 "<risbg_n>\t%0,%3,64-%4,63,%4+%5"
3902 [(set_attr "op_type" "RIE")
3903 (set_attr "z10prop" "z10_super_E1")])
3905 ; ((int)foo >> 10) & 1;
3906 (define_insn "*extract1bitdi<clobbercc_or_nocc>"
3907 [(set (match_operand:DI 0 "register_operand" "=d")
3908 (ne:DI (zero_extract:DI
3909 (match_operand:DI 1 "register_operand" "d")
3910 (const_int 1) ; size
3911 (match_operand 2 "const_int_operand" "")) ; start
3913 "<z10_or_zEC12_cond>
3914 && EXTRACT_ARGS_IN_RANGE (1, INTVAL (operands[2]), 64)"
3915 "<risbg_n>\t%0,%1,64-1,128+63,%2+1" ; dst, src, start, end, shift
3916 [(set_attr "op_type" "RIE")
3917 (set_attr "z10prop" "z10_super_E1")])
3919 (define_insn "*<risbg_n>_and_subregdi_rotr"
3920 [(set (match_operand:DI 0 "register_operand" "=d")
3922 (rotate:SINT (match_operand:SINT 1 "register_operand" "d")
3923 (match_operand:SINT 2 "const_int_operand" "")) 0)
3924 (match_operand:DI 3 "contiguous_bitmask_operand" "")))]
3925 "<z10_or_zEC12_cond>
3926 && UINTVAL (operands[3]) < (1ULL << (UINTVAL (operands[2]) & 0x3f))"
3927 "<risbg_n>\t%0,%1,%s3,128+%e3,<bitoff_plus>%2" ; dst, src, start, end, shift
3928 [(set_attr "op_type" "RIE")
3929 (set_attr "z10prop" "z10_super_E1")])
3931 (define_insn "*<risbg_n>_and_subregdi_rotl"
3932 [(set (match_operand:DI 0 "register_operand" "=d")
3934 (rotate:SINT (match_operand:SINT 1 "register_operand" "d")
3935 (match_operand:SINT 2 "const_int_operand" "")) 0)
3936 (match_operand:DI 3 "contiguous_bitmask_operand" "")))]
3937 "<z10_or_zEC12_cond>
3938 && !(UINTVAL (operands[3]) & ((1ULL << (UINTVAL (operands[2]) & 0x3f)) - 1))"
3939 "<risbg_n>\t%0,%1,%s3,128+%e3,%2" ; dst, src, start, end, shift
3940 [(set_attr "op_type" "RIE")
3941 (set_attr "z10prop" "z10_super_E1")])
3943 (define_insn "*<risbg_n>_di_and_rot"
3944 [(set (match_operand:DI 0 "register_operand" "=d")
3945 (and:DI (rotate:DI (match_operand:DI 1 "register_operand" "d")
3946 (match_operand:DI 2 "const_int_operand" ""))
3947 (match_operand:DI 3 "contiguous_bitmask_operand" "")))]
3948 "<z10_or_zEC12_cond>"
3949 "<risbg_n>\t%0,%1,%s3,128+%e3,%2" ; dst, src, start, end, shift
3950 [(set_attr "op_type" "RIE")
3951 (set_attr "z10prop" "z10_super_E1")])
3953 (define_insn_and_split "*pre_z10_extzv<mode>"
3954 [(set (match_operand:GPR 0 "register_operand" "=d")
3955 (zero_extract:GPR (match_operand:QI 1 "s_operand" "S")
3956 (match_operand 2 "nonzero_shift_count_operand" "")
3958 (clobber (reg:CC CC_REGNUM))]
3961 "&& reload_completed"
3963 [(set (match_dup 0) (unspec:GPR [(match_dup 1) (match_dup 3)] UNSPEC_ICM))
3964 (clobber (reg:CC CC_REGNUM))])
3965 (set (match_dup 0) (lshiftrt:GPR (match_dup 0) (match_dup 2)))]
3967 int bitsize = INTVAL (operands[2]);
3968 int size = (bitsize - 1) / BITS_PER_UNIT + 1; /* round up */
3969 int mask = ((1ul << size) - 1) << (GET_MODE_SIZE (SImode) - size);
3971 operands[1] = adjust_address (operands[1], BLKmode, 0);
3972 set_mem_size (operands[1], size);
3973 operands[2] = GEN_INT (<GPR:bitsize> - bitsize);
3974 operands[3] = GEN_INT (mask);
3977 (define_insn_and_split "*pre_z10_extv<mode>"
3978 [(set (match_operand:GPR 0 "register_operand" "=d")
3979 (sign_extract:GPR (match_operand:QI 1 "s_operand" "S")
3980 (match_operand 2 "nonzero_shift_count_operand" "")
3982 (clobber (reg:CC CC_REGNUM))]
3985 "&& reload_completed"
3987 [(set (match_dup 0) (unspec:GPR [(match_dup 1) (match_dup 3)] UNSPEC_ICM))
3988 (clobber (reg:CC CC_REGNUM))])
3990 [(set (match_dup 0) (ashiftrt:GPR (match_dup 0) (match_dup 2)))
3991 (clobber (reg:CC CC_REGNUM))])]
3993 int bitsize = INTVAL (operands[2]);
3994 int size = (bitsize - 1) / BITS_PER_UNIT + 1; /* round up */
3995 int mask = ((1ul << size) - 1) << (GET_MODE_SIZE (SImode) - size);
3997 operands[1] = adjust_address (operands[1], BLKmode, 0);
3998 set_mem_size (operands[1], size);
3999 operands[2] = GEN_INT (<GPR:bitsize> - bitsize);
4000 operands[3] = GEN_INT (mask);
4004 ; insv instruction patterns
4007 (define_expand "insv"
4008 [(set (zero_extract (match_operand 0 "nonimmediate_operand" "")
4009 (match_operand 1 "const_int_operand" "")
4010 (match_operand 2 "const_int_operand" ""))
4011 (match_operand 3 "general_operand" ""))]
4014 if (s390_expand_insv (operands[0], operands[1], operands[2], operands[3]))
4020 ; The normal RTL expansion will never generate a zero_extract where
4021 ; the location operand isn't word mode. However, we do this in the
4022 ; back-end when generating atomic operations. See s390_two_part_insv.
4023 (define_insn "*insv<mode><clobbercc_or_nocc>"
4024 [(set (zero_extract:GPR (match_operand:GPR 0 "nonimmediate_operand" "+d")
4025 (match_operand 1 "const_int_operand" "I") ; size
4026 (match_operand 2 "const_int_operand" "I")) ; pos
4027 (match_operand:GPR 3 "nonimmediate_operand" "d"))]
4028 "<z10_or_zEC12_cond>
4029 && EXTRACT_ARGS_IN_RANGE (INTVAL (operands[1]), INTVAL (operands[2]),
4030 GET_MODE_BITSIZE (<MODE>mode))
4031 && (INTVAL (operands[1]) + INTVAL (operands[2])) <= <bitsize>"
4032 "<risbg_n>\t%0,%3,<bitoff_plus>%2,<bitoff_plus>%2+%1-1,<bitsize>-%2-%1"
4033 [(set_attr "op_type" "RIE")
4034 (set_attr "z10prop" "z10_super_E1")])
4036 ; and op1 with a mask being 1 for the selected bits and 0 for the rest
4037 ; and op3=op0 with a mask being 0 for the selected bits and 1 for the rest
4038 (define_insn "*insv<mode><clobbercc_or_nocc>_noshift"
4039 [(set (match_operand:GPR 0 "nonimmediate_operand" "=d,d")
4040 (ior:GPR (and:GPR (match_operand:GPR 1 "nonimmediate_operand" "d,0")
4041 (match_operand:GPR 2 "contiguous_bitmask_operand" ""))
4042 (and:GPR (match_operand:GPR 3 "nonimmediate_operand" "0,d")
4043 (match_operand:GPR 4 "const_int_operand" ""))))]
4044 "<z10_or_zEC12_cond> && INTVAL (operands[2]) == ~INTVAL (operands[4])"
4046 <risbg_n>\t%0,%1,%<bfstart>2,%<bfend>2,0
4047 <risbg_n>\t%0,%3,%<bfstart>4,%<bfend>4,0"
4048 [(set_attr "op_type" "RIE")
4049 (set_attr "z10prop" "z10_super_E1")])
4051 (define_insn "*insv_z10_noshift_cc"
4052 [(set (reg CC_REGNUM)
4055 (and:DI (match_operand:DI 1 "nonimmediate_operand" "d,0")
4056 (match_operand:DI 2 "contiguous_bitmask_operand" ""))
4057 (and:DI (match_operand:DI 3 "nonimmediate_operand" "0,d")
4058 (match_operand:DI 4 "const_int_operand" "")))
4060 (set (match_operand:DI 0 "nonimmediate_operand" "=d,d")
4061 (ior:DI (and:DI (match_dup 1) (match_dup 2))
4062 (and:DI (match_dup 3) (match_dup 4))))]
4063 "TARGET_Z10 && s390_match_ccmode (insn, CCSmode)
4064 && INTVAL (operands[2]) == ~INTVAL (operands[4])"
4066 risbg\t%0,%1,%s2,%e2,0
4067 risbg\t%0,%3,%s4,%e4,0"
4068 [(set_attr "op_type" "RIE")
4069 (set_attr "z10prop" "z10_super_E1")])
4071 (define_insn "*insv_z10_noshift_cconly"
4076 (and:DI (match_operand:DI 1 "nonimmediate_operand" "d,0")
4077 (match_operand:DI 2 "contiguous_bitmask_operand" ""))
4078 (and:DI (match_operand:DI 3 "nonimmediate_operand" "0,d")
4079 (match_operand:DI 4 "const_int_operand" "")))
4081 (clobber (match_scratch:DI 0 "=d,d"))]
4082 "TARGET_Z10 && s390_match_ccmode (insn, CCSmode)
4083 && INTVAL (operands[2]) == ~INTVAL (operands[4])"
4085 risbg\t%0,%1,%s2,%e2,0
4086 risbg\t%0,%3,%s4,%e4,0"
4087 [(set_attr "op_type" "RIE")
4088 (set_attr "z10prop" "z10_super_E1")])
4090 ; Implement appending Y on the left of S bits of X
4091 ; x = (y << s) | (x & ((1 << s) - 1))
4092 (define_insn "*insv<mode><clobbercc_or_nocc>_appendbitsleft"
4093 [(set (match_operand:GPR 0 "nonimmediate_operand" "=d")
4094 (ior:GPR (and:GPR (match_operand:GPR 1 "nonimmediate_operand" "0")
4095 (match_operand:GPR 2 "immediate_operand" ""))
4096 (ashift:GPR (match_operand:GPR 3 "nonimmediate_operand" "d")
4097 (match_operand:GPR 4 "nonzero_shift_count_operand" ""))))]
4098 "<z10_or_zEC12_cond>
4099 && UINTVAL (operands[2]) == (1UL << UINTVAL (operands[4])) - 1"
4100 "<risbg_n>\t%0,%3,<bitoff>,64-%4-1,%4"
4101 [(set_attr "op_type" "RIE")
4102 (set_attr "z10prop" "z10_super_E1")])
4104 ; a = ((i32)a & -16777216) | (((ui32)b) >> 8)
4105 (define_insn "*<risbg_n>_<mode>_ior_and_lshiftrt"
4106 [(set (match_operand:GPR 0 "register_operand" "=d")
4108 (match_operand:GPR 1 "register_operand" "0")
4109 (match_operand:GPR 2 "const_int_operand" ""))
4111 (match_operand:GPR 3 "register_operand" "d")
4112 (match_operand:GPR 4 "nonzero_shift_count_operand" ""))))]
4113 "<z10_or_zEC12_cond> && UINTVAL (operands[2])
4114 == (~(0ULL) << (GET_MODE_BITSIZE (<MODE>mode) - UINTVAL (operands[4])))"
4115 "<risbg_n>\t%0,%3,<bitoff_plus>%4,63,64-%4"
4116 [(set_attr "op_type" "RIE")
4117 (set_attr "z10prop" "z10_super_E1")])
4119 ; (ui32)(((ui64)x) >> 48) | ((i32)y & -65536);
4120 (define_insn "*<risbg_n>_sidi_ior_and_lshiftrt"
4121 [(set (match_operand:SI 0 "register_operand" "=d")
4123 (match_operand:SI 1 "register_operand" "0")
4124 (match_operand:SI 2 "const_int_operand" ""))
4127 (match_operand:DI 3 "register_operand" "d")
4128 (match_operand:DI 4 "nonzero_shift_count_operand" "")) 4)))]
4129 "<z10_or_zEC12_cond>
4130 && UINTVAL (operands[2]) == ~(~(0ULL) >> UINTVAL (operands[4]))"
4131 "<risbg_n>\t%0,%3,%4,63,64-%4"
4132 [(set_attr "op_type" "RIE")
4133 (set_attr "z10prop" "z10_super_E1")])
4135 ; (ui32)(((ui64)x) >> 12) & -4
4136 (define_insn "*trunc_sidi_and_subreg_lshrt<clobbercc_or_nocc>"
4137 [(set (match_operand:SI 0 "register_operand" "=d")
4139 (subreg:SI (lshiftrt:DI
4140 (match_operand:DI 1 "register_operand" "d")
4141 (match_operand:DI 2 "nonzero_shift_count_operand" "")) 4)
4142 (match_operand:SI 3 "contiguous_bitmask_nowrap_operand" "")))]
4143 "<z10_or_zEC12_cond>"
4144 "<risbg_n>\t%0,%1,%t3,128+%f3,64-%2"
4145 [(set_attr "op_type" "RIE")
4146 (set_attr "z10prop" "z10_super_E1")])
4148 ; z = (x << c) | (y >> d) with (x << c) and (y >> d) not overlapping after shifting
4149 ; -> z = y >> d; z = (x << c) | (z & ((1 << c) - 1))
4150 ; -> z = y >> d; z = risbg;
4153 [(set (match_operand:GPR 0 "nonimmediate_operand" "")
4154 (ior:GPR (lshiftrt:GPR (match_operand:GPR 1 "nonimmediate_operand" "")
4155 (match_operand:GPR 2 "nonzero_shift_count_operand" ""))
4156 (ashift:GPR (match_operand:GPR 3 "nonimmediate_operand" "")
4157 (match_operand:GPR 4 "nonzero_shift_count_operand" ""))))]
4158 "TARGET_ZEC12 && UINTVAL (operands[2]) + UINTVAL (operands[4]) >= <bitsize>"
4160 (lshiftrt:GPR (match_dup 1) (match_dup 2)))
4162 (ior:GPR (and:GPR (match_dup 6) (match_dup 5))
4163 (ashift:GPR (match_dup 3) (match_dup 4))))]
4165 operands[5] = GEN_INT ((1UL << UINTVAL (operands[4])) - 1);
4166 if (reg_overlap_mentioned_p (operands[0], operands[3]))
4168 if (!can_create_pseudo_p ())
4170 operands[6] = gen_reg_rtx (<MODE>mode);
4173 operands[6] = operands[0];
4178 [(set (match_operand:GPR 0 "nonimmediate_operand" "")
4179 (ior:GPR (lshiftrt:GPR (match_operand:GPR 1 "nonimmediate_operand" "")
4180 (match_operand:GPR 2 "nonzero_shift_count_operand" ""))
4181 (ashift:GPR (match_operand:GPR 3 "nonimmediate_operand" "")
4182 (match_operand:GPR 4 "nonzero_shift_count_operand" ""))))
4183 (clobber (reg:CC CC_REGNUM))])]
4184 "TARGET_Z10 && !TARGET_ZEC12 && UINTVAL (operands[2]) + UINTVAL (operands[4]) >= <bitsize>"
4186 (lshiftrt:GPR (match_dup 1) (match_dup 2)))
4189 (ior:GPR (and:GPR (match_dup 6) (match_dup 5))
4190 (ashift:GPR (match_dup 3) (match_dup 4))))
4191 (clobber (reg:CC CC_REGNUM))])]
4193 operands[5] = GEN_INT ((1UL << UINTVAL (operands[4])) - 1);
4194 if (reg_overlap_mentioned_p (operands[0], operands[3]))
4196 if (!can_create_pseudo_p ())
4198 operands[6] = gen_reg_rtx (<MODE>mode);
4201 operands[6] = operands[0];
4205 (define_insn "*r<noxa>sbg_<mode>_noshift"
4206 [(set (match_operand:GPR 0 "nonimmediate_operand" "=d")
4208 (and:GPR (match_operand:GPR 1 "nonimmediate_operand" "d")
4209 (match_operand:GPR 2 "contiguous_bitmask_operand" ""))
4210 (match_operand:GPR 3 "nonimmediate_operand" "0")))
4211 (clobber (reg:CC CC_REGNUM))]
4213 "r<noxa>sbg\t%0,%1,%<bfstart>2,%<bfend>2,0"
4214 [(set_attr "op_type" "RIE")])
4217 (define_insn "*r<noxa>sbg_di_rotl"
4218 [(set (match_operand:DI 0 "nonimmediate_operand" "=d")
4222 (match_operand:DI 1 "nonimmediate_operand" "d")
4223 (match_operand:DI 3 "const_int_operand" ""))
4224 (match_operand:DI 2 "contiguous_bitmask_operand" ""))
4225 (match_operand:DI 4 "nonimmediate_operand" "0")))
4226 (clobber (reg:CC CC_REGNUM))]
4228 "r<noxa>sbg\t%0,%1,%<bfstart>2,%<bfend>2,%b3"
4229 [(set_attr "op_type" "RIE")])
4232 (define_insn "*r<noxa>sbg_<mode>_srl_bitmask"
4233 [(set (match_operand:GPR 0 "nonimmediate_operand" "=d")
4237 (match_operand:GPR 1 "nonimmediate_operand" "d")
4238 (match_operand:GPR 3 "nonzero_shift_count_operand" ""))
4239 (match_operand:GPR 2 "contiguous_bitmask_nowrap_operand" ""))
4240 (match_operand:GPR 4 "nonimmediate_operand" "0")))
4241 (clobber (reg:CC CC_REGNUM))]
4243 && s390_extzv_shift_ok (<bitsize>, 64 - INTVAL (operands[3]),
4244 INTVAL (operands[2]))"
4245 "r<noxa>sbg\t%0,%1,%<bfstart>2,%<bfend>2,64-%3"
4246 [(set_attr "op_type" "RIE")])
4249 (define_insn "*r<noxa>sbg_<mode>_sll_bitmask"
4250 [(set (match_operand:GPR 0 "nonimmediate_operand" "=d")
4254 (match_operand:GPR 1 "nonimmediate_operand" "d")
4255 (match_operand:GPR 3 "nonzero_shift_count_operand" ""))
4256 (match_operand:GPR 2 "contiguous_bitmask_nowrap_operand" ""))
4257 (match_operand:GPR 4 "nonimmediate_operand" "0")))
4258 (clobber (reg:CC CC_REGNUM))]
4260 && s390_extzv_shift_ok (<bitsize>, INTVAL (operands[3]),
4261 INTVAL (operands[2]))"
4262 "r<noxa>sbg\t%0,%1,%<bfstart>2,%<bfend>2,%3"
4263 [(set_attr "op_type" "RIE")])
4265 ;; unsigned {int,long} a, b
4266 ;; a = a | (b << const_int)
4267 ;; a = a ^ (b << const_int)
4269 (define_insn "*r<noxa>sbg_<mode>_sll"
4270 [(set (match_operand:GPR 0 "nonimmediate_operand" "=d")
4273 (match_operand:GPR 1 "nonimmediate_operand" "d")
4274 (match_operand:GPR 2 "nonzero_shift_count_operand" ""))
4275 (match_operand:GPR 3 "nonimmediate_operand" "0")))
4276 (clobber (reg:CC CC_REGNUM))]
4278 "r<noxa>sbg\t%0,%1,<bitoff>,63-%2,%2"
4279 [(set_attr "op_type" "RIE")])
4281 ;; unsigned {int,long} a, b
4282 ;; a = a | (b >> const_int)
4283 ;; a = a ^ (b >> const_int)
4285 (define_insn "*r<noxa>sbg_<mode>_srl"
4286 [(set (match_operand:GPR 0 "nonimmediate_operand" "=d")
4289 (match_operand:GPR 1 "nonimmediate_operand" "d")
4290 (match_operand:GPR 2 "nonzero_shift_count_operand" ""))
4291 (match_operand:GPR 3 "nonimmediate_operand" "0")))
4292 (clobber (reg:CC CC_REGNUM))]
4294 "r<noxa>sbg\t%0,%1,<bitoff_plus>%2,63,64-%2"
4295 [(set_attr "op_type" "RIE")])
4297 ;; These two are generated by combine for s.bf &= val.
4298 ;; ??? For bitfields smaller than 32-bits, we wind up with SImode
4299 ;; shifts and ands, which results in some truly awful patterns
4300 ;; including subregs of operations. Rather unnecessisarily, IMO.
4303 ;; (set (zero_extract:DI (reg/v:DI 50 [ s ])
4304 ;; (const_int 24 [0x18])
4305 ;; (const_int 0 [0]))
4306 ;; (subreg:DI (and:SI (subreg:SI (lshiftrt:DI (reg/v:DI 50 [ s ])
4307 ;; (const_int 40 [0x28])) 4)
4308 ;; (reg:SI 4 %r4 [ y+4 ])) 0))
4310 ;; we should instead generate
4312 ;; (set (zero_extract:DI (reg/v:DI 50 [ s ])
4313 ;; (const_int 24 [0x18])
4314 ;; (const_int 0 [0]))
4315 ;; (and:DI (lshiftrt:DI (reg/v:DI 50 [ s ])
4316 ;; (const_int 40 [0x28]))
4317 ;; (subreg:DI (reg:SI 4 %r4 [ y+4 ]) 0)))
4319 ;; by noticing that we can push down the outer paradoxical subreg
4320 ;; into the operation.
4322 (define_insn "*insv_rnsbg_noshift"
4323 [(set (zero_extract:DI
4324 (match_operand:DI 0 "nonimmediate_operand" "+d")
4325 (match_operand 1 "const_int_operand" "")
4326 (match_operand 2 "const_int_operand" ""))
4329 (match_operand:DI 3 "nonimmediate_operand" "d")))
4330 (clobber (reg:CC CC_REGNUM))]
4332 && EXTRACT_ARGS_IN_RANGE (INTVAL (operands[1]), INTVAL (operands[2]), 64)
4333 && INTVAL (operands[1]) + INTVAL (operands[2]) == 64"
4334 "rnsbg\t%0,%3,%2,63,0"
4335 [(set_attr "op_type" "RIE")])
4337 (define_insn "*insv_rnsbg_srl"
4338 [(set (zero_extract:DI
4339 (match_operand:DI 0 "nonimmediate_operand" "+d")
4340 (match_operand 1 "const_int_operand" "")
4341 (match_operand 2 "const_int_operand" ""))
4345 (match_operand 3 "const_int_operand" ""))
4346 (match_operand:DI 4 "nonimmediate_operand" "d")))
4347 (clobber (reg:CC CC_REGNUM))]
4349 && EXTRACT_ARGS_IN_RANGE (INTVAL (operands[1]), INTVAL (operands[2]), 64)
4350 && INTVAL (operands[3]) == 64 - INTVAL (operands[1]) - INTVAL (operands[2])"
4351 "rnsbg\t%0,%4,%2,%2+%1-1,%3"
4352 [(set_attr "op_type" "RIE")])
4354 (define_insn "*insv<mode>_mem_reg"
4355 [(set (zero_extract:W (match_operand:QI 0 "memory_operand" "+Q,S")
4356 (match_operand 1 "const_int_operand" "n,n")
4358 (match_operand:W 2 "register_operand" "d,d"))]
4359 "EXTRACT_ARGS_IN_RANGE (INTVAL (operands[1]), 0, 64)
4360 && INTVAL (operands[1]) > 0
4361 && INTVAL (operands[1]) <= GET_MODE_BITSIZE (SImode)
4362 && INTVAL (operands[1]) % BITS_PER_UNIT == 0"
4364 int size = INTVAL (operands[1]) / BITS_PER_UNIT;
4366 operands[1] = GEN_INT ((1ul << size) - 1);
4367 return (which_alternative == 0) ? "stcm\t%2,%1,%S0"
4368 : "stcmy\t%2,%1,%S0";
4370 [(set_attr "op_type" "RS,RSY")
4371 (set_attr "cpu_facility" "*,longdisp")
4372 (set_attr "z10prop" "z10_super,z10_super")])
4374 (define_insn "*insvdi_mem_reghigh"
4375 [(set (zero_extract:DI (match_operand:QI 0 "memory_operand" "+S")
4376 (match_operand 1 "const_int_operand" "n")
4378 (lshiftrt:DI (match_operand:DI 2 "register_operand" "d")
4381 && EXTRACT_ARGS_IN_RANGE (INTVAL (operands[1]), 0, 64)
4382 && INTVAL (operands[1]) > 0
4383 && INTVAL (operands[1]) <= GET_MODE_BITSIZE (SImode)
4384 && INTVAL (operands[1]) % BITS_PER_UNIT == 0"
4386 int size = INTVAL (operands[1]) / BITS_PER_UNIT;
4388 operands[1] = GEN_INT ((1ul << size) - 1);
4389 return "stcmh\t%2,%1,%S0";
4391 [(set_attr "op_type" "RSY")
4392 (set_attr "z10prop" "z10_super")])
4394 (define_insn "*insvdi_reg_imm"
4395 [(set (zero_extract:DI (match_operand:DI 0 "register_operand" "+d")
4397 (match_operand 1 "const_int_operand" "n"))
4398 (match_operand:DI 2 "const_int_operand" "n"))]
4400 && EXTRACT_ARGS_IN_RANGE (16, INTVAL (operands[1]), 64)
4401 && INTVAL (operands[1]) >= 0
4402 && INTVAL (operands[1]) < BITS_PER_WORD
4403 && INTVAL (operands[1]) % 16 == 0"
4405 switch (BITS_PER_WORD - INTVAL (operands[1]))
4407 case 64: return "iihh\t%0,%x2"; break;
4408 case 48: return "iihl\t%0,%x2"; break;
4409 case 32: return "iilh\t%0,%x2"; break;
4410 case 16: return "iill\t%0,%x2"; break;
4411 default: gcc_unreachable();
4414 [(set_attr "op_type" "RI")
4415 (set_attr "z10prop" "z10_super_E1")])
4417 ; Update the left-most 32 bit of a DI.
4418 (define_insn "*insv_h_di_reg_extimm"
4419 [(set (zero_extract:DI (match_operand:DI 0 "register_operand" "+d")
4422 (match_operand:DI 1 "const_int_operand" "n"))]
4425 [(set_attr "op_type" "RIL")
4426 (set_attr "z10prop" "z10_fwd_E1")])
4428 ; Update the right-most 32 bit of a DI.
4429 (define_insn "*insv_l_di_reg_extimm"
4430 [(set (zero_extract:DI (match_operand:DI 0 "register_operand" "+d")
4433 (match_operand:DI 1 "const_int_operand" "n"))]
4436 [(set_attr "op_type" "RIL")
4437 (set_attr "z10prop" "z10_fwd_A1")])
4440 ; extendsidi2 instruction pattern(s).
4443 (define_expand "extendsidi2"
4444 [(set (match_operand:DI 0 "register_operand" "")
4445 (sign_extend:DI (match_operand:SI 1 "nonimmediate_operand" "")))]
4450 emit_clobber (operands[0]);
4451 emit_move_insn (gen_highpart (SImode, operands[0]), operands[1]);
4452 emit_move_insn (gen_lowpart (SImode, operands[0]), const0_rtx);
4453 emit_insn (gen_ashrdi3 (operands[0], operands[0], GEN_INT (32)));
4458 (define_insn "*extendsidi2"
4459 [(set (match_operand:DI 0 "register_operand" "=d,d,d")
4460 (sign_extend:DI (match_operand:SI 1 "nonimmediate_operand" "d,T,b")))]
4466 [(set_attr "op_type" "RRE,RXY,RIL")
4467 (set_attr "type" "*,*,larl")
4468 (set_attr "cpu_facility" "*,*,z10")
4469 (set_attr "z10prop" "z10_super_E1,z10_super_E1,z10_super_E1")])
4472 ; extend(hi|qi)(si|di)2 instruction pattern(s).
4475 (define_expand "extend<HQI:mode><DSI:mode>2"
4476 [(set (match_operand:DSI 0 "register_operand" "")
4477 (sign_extend:DSI (match_operand:HQI 1 "nonimmediate_operand" "")))]
4480 if (<DSI:MODE>mode == DImode && !TARGET_ZARCH)
4482 rtx tmp = gen_reg_rtx (SImode);
4483 emit_insn (gen_extend<HQI:mode>si2 (tmp, operands[1]));
4484 emit_insn (gen_extendsidi2 (operands[0], tmp));
4487 else if (!TARGET_EXTIMM)
4489 rtx bitcount = GEN_INT (<DSI:bitsize> - <HQI:bitsize>);
4491 operands[1] = gen_lowpart (<DSI:MODE>mode, operands[1]);
4492 emit_insn (gen_ashl<DSI:mode>3 (operands[0], operands[1], bitcount));
4493 emit_insn (gen_ashr<DSI:mode>3 (operands[0], operands[0], bitcount));
4499 ; extendhidi2 instruction pattern(s).
4502 (define_insn "*extendhidi2_extimm"
4503 [(set (match_operand:DI 0 "register_operand" "=d,d,d")
4504 (sign_extend:DI (match_operand:HI 1 "general_operand" "d,T,b")))]
4505 "TARGET_ZARCH && TARGET_EXTIMM"
4510 [(set_attr "op_type" "RRE,RXY,RIL")
4511 (set_attr "type" "*,*,larl")
4512 (set_attr "cpu_facility" "extimm,extimm,z10")
4513 (set_attr "z10prop" "z10_super_E1,z10_super_E1,z10_super_E1")])
4515 (define_insn "*extendhidi2"
4516 [(set (match_operand:DI 0 "register_operand" "=d")
4517 (sign_extend:DI (match_operand:HI 1 "memory_operand" "T")))]
4520 [(set_attr "op_type" "RXY")
4521 (set_attr "z10prop" "z10_super_E1")])
4524 ; extendhisi2 instruction pattern(s).
4527 (define_insn "*extendhisi2_extimm"
4528 [(set (match_operand:SI 0 "register_operand" "=d,d,d,d")
4529 (sign_extend:SI (match_operand:HI 1 "nonimmediate_operand" " d,R,T,b")))]
4536 [(set_attr "op_type" "RRE,RX,RXY,RIL")
4537 (set_attr "type" "*,*,*,larl")
4538 (set_attr "cpu_facility" "extimm,extimm,extimm,z10")
4539 (set_attr "z10prop" "z10_super_E1,z10_super_E1,z10_super_E1,z10_super_E1")])
4541 (define_insn "*extendhisi2"
4542 [(set (match_operand:SI 0 "register_operand" "=d,d")
4543 (sign_extend:SI (match_operand:HI 1 "memory_operand" "R,T")))]
4548 [(set_attr "op_type" "RX,RXY")
4549 (set_attr "cpu_facility" "*,longdisp")
4550 (set_attr "z10prop" "z10_super_E1,z10_super_E1")])
4553 ; extendqi(si|di)2 instruction pattern(s).
4556 ; lbr, lgbr, lb, lgb
4557 (define_insn "*extendqi<mode>2_extimm"
4558 [(set (match_operand:GPR 0 "register_operand" "=d,d")
4559 (sign_extend:GPR (match_operand:QI 1 "nonimmediate_operand" "d,T")))]
4564 [(set_attr "op_type" "RRE,RXY")
4565 (set_attr "z10prop" "z10_super_E1,z10_super_E1")])
4568 (define_insn "*extendqi<mode>2"
4569 [(set (match_operand:GPR 0 "register_operand" "=d")
4570 (sign_extend:GPR (match_operand:QI 1 "memory_operand" "T")))]
4571 "!TARGET_EXTIMM && TARGET_LONG_DISPLACEMENT"
4573 [(set_attr "op_type" "RXY")
4574 (set_attr "z10prop" "z10_super_E1")])
4576 (define_insn_and_split "*extendqi<mode>2_short_displ"
4577 [(set (match_operand:GPR 0 "register_operand" "=d")
4578 (sign_extend:GPR (match_operand:QI 1 "s_operand" "Q")))
4579 (clobber (reg:CC CC_REGNUM))]
4580 "!TARGET_EXTIMM && !TARGET_LONG_DISPLACEMENT"
4582 "&& reload_completed"
4584 [(set (match_dup 0) (unspec:GPR [(match_dup 1) (const_int 8)] UNSPEC_ICM))
4585 (clobber (reg:CC CC_REGNUM))])
4587 [(set (match_dup 0) (ashiftrt:GPR (match_dup 0) (match_dup 2)))
4588 (clobber (reg:CC CC_REGNUM))])]
4590 operands[1] = adjust_address (operands[1], BLKmode, 0);
4591 set_mem_size (operands[1], GET_MODE_SIZE (QImode));
4592 operands[2] = GEN_INT (<GPR:bitsize> - BITS_PER_UNIT);
4596 ; zero_extendsidi2 instruction pattern(s).
4599 (define_expand "zero_extendsidi2"
4600 [(set (match_operand:DI 0 "register_operand" "")
4601 (zero_extend:DI (match_operand:SI 1 "nonimmediate_operand" "")))]
4606 emit_clobber (operands[0]);
4607 emit_move_insn (gen_lowpart (SImode, operands[0]), operands[1]);
4608 emit_move_insn (gen_highpart (SImode, operands[0]), const0_rtx);
4613 (define_insn "*zero_extendsidi2"
4614 [(set (match_operand:DI 0 "register_operand" "=d,d,d")
4615 (zero_extend:DI (match_operand:SI 1 "nonimmediate_operand" "d,T,b")))]
4621 [(set_attr "op_type" "RRE,RXY,RIL")
4622 (set_attr "type" "*,*,larl")
4623 (set_attr "cpu_facility" "*,*,z10")
4624 (set_attr "z10prop" "z10_fwd_E1,z10_fwd_A3,z10_fwd_A3")])
4627 ; LLGT-type instructions (zero-extend from 31 bit to 64 bit).
4630 (define_insn "*llgt_sidi"
4631 [(set (match_operand:DI 0 "register_operand" "=d")
4632 (and:DI (subreg:DI (match_operand:SI 1 "memory_operand" "T") 0)
4633 (const_int 2147483647)))]
4636 [(set_attr "op_type" "RXE")
4637 (set_attr "z10prop" "z10_super_E1")])
4639 (define_insn_and_split "*llgt_sidi_split"
4640 [(set (match_operand:DI 0 "register_operand" "=d")
4641 (and:DI (subreg:DI (match_operand:SI 1 "memory_operand" "T") 0)
4642 (const_int 2147483647)))
4643 (clobber (reg:CC CC_REGNUM))]
4646 "&& reload_completed"
4648 (and:DI (subreg:DI (match_dup 1) 0)
4649 (const_int 2147483647)))]
4652 (define_insn "*llgt_sisi"
4653 [(set (match_operand:SI 0 "register_operand" "=d,d")
4654 (and:SI (match_operand:SI 1 "nonimmediate_operand" "d,T")
4655 (const_int 2147483647)))]
4660 [(set_attr "op_type" "RRE,RXE")
4661 (set_attr "z10prop" "z10_super_E1,z10_super_E1")])
4663 (define_insn "*llgt_didi"
4664 [(set (match_operand:DI 0 "register_operand" "=d,d")
4665 (and:DI (match_operand:DI 1 "nonimmediate_operand" "d,o")
4666 (const_int 2147483647)))]
4671 [(set_attr "op_type" "RRE,RXE")
4672 (set_attr "z10prop" "z10_super_E1,z10_super_E1")])
4675 [(set (match_operand:DSI 0 "register_operand" "")
4676 (and:DSI (match_operand:DSI 1 "nonimmediate_operand" "")
4677 (const_int 2147483647)))
4678 (clobber (reg:CC CC_REGNUM))]
4679 "TARGET_ZARCH && reload_completed"
4681 (and:DSI (match_dup 1)
4682 (const_int 2147483647)))]
4686 ; zero_extend(hi|qi)(si|di)2 instruction pattern(s).
4689 (define_expand "zero_extend<mode>di2"
4690 [(set (match_operand:DI 0 "register_operand" "")
4691 (zero_extend:DI (match_operand:HQI 1 "nonimmediate_operand" "")))]
4696 rtx tmp = gen_reg_rtx (SImode);
4697 emit_insn (gen_zero_extend<mode>si2 (tmp, operands[1]));
4698 emit_insn (gen_zero_extendsidi2 (operands[0], tmp));
4701 else if (!TARGET_EXTIMM)
4703 rtx bitcount = GEN_INT (64 - <HQI:bitsize>);
4704 operands[1] = gen_lowpart (DImode, operands[1]);
4705 emit_insn (gen_ashldi3 (operands[0], operands[1], bitcount));
4706 emit_insn (gen_lshrdi3 (operands[0], operands[0], bitcount));
4711 (define_expand "zero_extend<mode>si2"
4712 [(set (match_operand:SI 0 "register_operand" "")
4713 (zero_extend:SI (match_operand:HQI 1 "nonimmediate_operand" "")))]
4718 operands[1] = gen_lowpart (SImode, operands[1]);
4719 emit_insn (gen_andsi3 (operands[0], operands[1],
4720 GEN_INT ((1 << <HQI:bitsize>) - 1)));
4726 (define_insn "*zero_extendhi<mode>2_z10"
4727 [(set (match_operand:GPR 0 "register_operand" "=d,d,d")
4728 (zero_extend:GPR (match_operand:HI 1 "nonimmediate_operand" "d,T,b")))]
4734 [(set_attr "op_type" "RXY,RRE,RIL")
4735 (set_attr "type" "*,*,larl")
4736 (set_attr "cpu_facility" "*,*,z10")
4737 (set_attr "z10prop" "z10_super_E1,z10_fwd_A3,z10_fwd_A3")])
4739 ; llhr, llcr, llghr, llgcr, llh, llc, llgh, llgc
4740 (define_insn "*zero_extend<HQI:mode><GPR:mode>2_extimm"
4741 [(set (match_operand:GPR 0 "register_operand" "=d,d")
4742 (zero_extend:GPR (match_operand:HQI 1 "nonimmediate_operand" "d,T")))]
4747 [(set_attr "op_type" "RRE,RXY")
4748 (set_attr "z10prop" "z10_super_E1,z10_fwd_A3")])
4751 (define_insn "*zero_extend<HQI:mode><GPR:mode>2"
4752 [(set (match_operand:GPR 0 "register_operand" "=d")
4753 (zero_extend:GPR (match_operand:HQI 1 "memory_operand" "T")))]
4754 "TARGET_ZARCH && !TARGET_EXTIMM"
4756 [(set_attr "op_type" "RXY")
4757 (set_attr "z10prop" "z10_fwd_A3")])
4759 (define_insn_and_split "*zero_extendhisi2_31"
4760 [(set (match_operand:SI 0 "register_operand" "=&d")
4761 (zero_extend:SI (match_operand:HI 1 "s_operand" "S")))
4762 (clobber (reg:CC CC_REGNUM))]
4765 "&& reload_completed"
4766 [(set (match_dup 0) (const_int 0))
4768 [(set (strict_low_part (match_dup 2)) (match_dup 1))
4769 (clobber (reg:CC CC_REGNUM))])]
4770 "operands[2] = gen_lowpart (HImode, operands[0]);")
4772 (define_insn_and_split "*zero_extendqisi2_31"
4773 [(set (match_operand:SI 0 "register_operand" "=&d")
4774 (zero_extend:SI (match_operand:QI 1 "memory_operand" "T")))]
4777 "&& reload_completed"
4778 [(set (match_dup 0) (const_int 0))
4779 (set (strict_low_part (match_dup 2)) (match_dup 1))]
4780 "operands[2] = gen_lowpart (QImode, operands[0]);")
4783 ; zero_extendqihi2 instruction pattern(s).
4786 (define_expand "zero_extendqihi2"
4787 [(set (match_operand:HI 0 "register_operand" "")
4788 (zero_extend:HI (match_operand:QI 1 "register_operand" "")))]
4789 "TARGET_ZARCH && !TARGET_EXTIMM"
4791 operands[1] = gen_lowpart (HImode, operands[1]);
4792 emit_insn (gen_andhi3 (operands[0], operands[1], GEN_INT (0xff)));
4796 (define_insn "*zero_extendqihi2_64"
4797 [(set (match_operand:HI 0 "register_operand" "=d")
4798 (zero_extend:HI (match_operand:QI 1 "memory_operand" "T")))]
4799 "TARGET_ZARCH && !TARGET_EXTIMM"
4801 [(set_attr "op_type" "RXY")
4802 (set_attr "z10prop" "z10_fwd_A3")])
4804 (define_insn_and_split "*zero_extendqihi2_31"
4805 [(set (match_operand:HI 0 "register_operand" "=&d")
4806 (zero_extend:HI (match_operand:QI 1 "memory_operand" "T")))]
4809 "&& reload_completed"
4810 [(set (match_dup 0) (const_int 0))
4811 (set (strict_low_part (match_dup 2)) (match_dup 1))]
4812 "operands[2] = gen_lowpart (QImode, operands[0]);")
4815 ; fixuns_trunc(dd|td|sf|df|tf)(si|di)2 expander
4818 ; This is the only entry point for fixuns_trunc. It multiplexes the
4819 ; expansion to either the *_emu expanders below for pre z196 machines
4820 ; or emits the default pattern otherwise.
4821 (define_expand "fixuns_trunc<FP:mode><GPR:mode>2"
4823 [(set (match_operand:GPR 0 "register_operand" "")
4824 (unsigned_fix:GPR (match_operand:FP 1 "register_operand" "")))
4825 (unspec:GPR [(match_dup 2)] UNSPEC_ROUND)
4826 (clobber (reg:CC CC_REGNUM))])]
4831 /* We don't provide emulation for TD|DD->SI. */
4832 if (GET_MODE_CLASS (<FP:MODE>mode) == MODE_DECIMAL_FLOAT
4833 && <GPR:MODE>mode == SImode)
4835 emit_insn (gen_fixuns_trunc<FP:mode><GPR:mode>2_emu (operands[0],
4840 if (GET_MODE_CLASS (<FP:MODE>mode) == MODE_DECIMAL_FLOAT)
4841 operands[2] = GEN_INT (DFP_RND_TOWARD_0);
4843 operands[2] = GEN_INT (BFP_RND_TOWARD_0);
4846 ; (sf|df|tf)->unsigned (si|di)
4848 ; Emulate the unsigned conversion with the signed version for pre z196
4850 (define_expand "fixuns_trunc<BFP:mode><GPR:mode>2_emu"
4852 [(set (match_operand:GPR 0 "register_operand" "")
4853 (unsigned_fix:GPR (match_operand:BFP 1 "register_operand" "")))
4854 (unspec:GPR [(const_int BFP_RND_TOWARD_0)] UNSPEC_ROUND)
4855 (clobber (reg:CC CC_REGNUM))])]
4856 "!TARGET_Z196 && TARGET_HARD_FLOAT"
4858 rtx_code_label *label1 = gen_label_rtx ();
4859 rtx_code_label *label2 = gen_label_rtx ();
4860 rtx temp = gen_reg_rtx (<BFP:MODE>mode);
4861 REAL_VALUE_TYPE cmp, sub;
4863 operands[1] = force_reg (<BFP:MODE>mode, operands[1]);
4864 real_2expN (&cmp, <GPR:bitsize> - 1, <BFP:MODE>mode);
4865 real_2expN (&sub, <GPR:bitsize>, <BFP:MODE>mode);
4867 emit_cmp_and_jump_insns (operands[1],
4868 const_double_from_real_value (cmp, <BFP:MODE>mode),
4869 LT, NULL_RTX, VOIDmode, 0, label1);
4870 emit_insn (gen_sub<BFP:mode>3 (temp, operands[1],
4871 const_double_from_real_value (sub, <BFP:MODE>mode)));
4872 emit_insn (gen_fix_trunc<BFP:mode><GPR:mode>2_bfp (operands[0], temp,
4873 GEN_INT (BFP_RND_TOWARD_MINF)));
4876 emit_label (label1);
4877 emit_insn (gen_fix_trunc<BFP:mode><GPR:mode>2_bfp (operands[0],
4879 GEN_INT (BFP_RND_TOWARD_0)));
4880 emit_label (label2);
4886 ; Emulate the unsigned conversion with the signed version for pre z196
4888 (define_expand "fixuns_truncdddi2_emu"
4890 [(set (match_operand:DI 0 "register_operand" "")
4891 (unsigned_fix:DI (match_operand:DD 1 "register_operand" "")))
4892 (unspec:DI [(const_int DFP_RND_TOWARD_0)] UNSPEC_ROUND)
4893 (clobber (reg:CC CC_REGNUM))])]
4895 "!TARGET_Z196 && TARGET_HARD_DFP"
4897 rtx_code_label *label1 = gen_label_rtx ();
4898 rtx_code_label *label2 = gen_label_rtx ();
4899 rtx temp = gen_reg_rtx (TDmode);
4900 REAL_VALUE_TYPE cmp, sub;
4902 decimal_real_from_string (&cmp, "9223372036854775808.0"); /* 2^63 */
4903 decimal_real_from_string (&sub, "18446744073709551616.0"); /* 2^64 */
4905 /* 2^63 can't be represented as 64bit DFP number with full precision. The
4906 solution is doing the check and the subtraction in TD mode and using a
4907 TD -> DI convert afterwards. */
4908 emit_insn (gen_extendddtd2 (temp, operands[1]));
4909 temp = force_reg (TDmode, temp);
4910 emit_cmp_and_jump_insns (temp,
4911 const_double_from_real_value (cmp, TDmode),
4912 LT, NULL_RTX, VOIDmode, 0, label1);
4913 emit_insn (gen_subtd3 (temp, temp,
4914 const_double_from_real_value (sub, TDmode)));
4915 emit_insn (gen_fix_trunctddi2_dfp (operands[0], temp,
4916 GEN_INT (DFP_RND_TOWARD_MINF)));
4919 emit_label (label1);
4920 emit_insn (gen_fix_truncdddi2_dfp (operands[0], operands[1],
4921 GEN_INT (DFP_RND_TOWARD_0)));
4922 emit_label (label2);
4928 ; Emulate the unsigned conversion with the signed version for pre z196
4930 (define_expand "fixuns_trunctddi2_emu"
4932 [(set (match_operand:DI 0 "register_operand" "")
4933 (unsigned_fix:DI (match_operand:TD 1 "register_operand" "")))
4934 (unspec:DI [(const_int DFP_RND_TOWARD_0)] UNSPEC_ROUND)
4935 (clobber (reg:CC CC_REGNUM))])]
4937 "!TARGET_Z196 && TARGET_HARD_DFP"
4939 rtx_code_label *label1 = gen_label_rtx ();
4940 rtx_code_label *label2 = gen_label_rtx ();
4941 rtx temp = gen_reg_rtx (TDmode);
4942 REAL_VALUE_TYPE cmp, sub;
4944 operands[1] = force_reg (TDmode, operands[1]);
4945 decimal_real_from_string (&cmp, "9223372036854775808.0"); /* 2^63 */
4946 decimal_real_from_string (&sub, "18446744073709551616.0"); /* 2^64 */
4948 emit_cmp_and_jump_insns (operands[1],
4949 const_double_from_real_value (cmp, TDmode),
4950 LT, NULL_RTX, VOIDmode, 0, label1);
4951 emit_insn (gen_subtd3 (temp, operands[1],
4952 const_double_from_real_value (sub, TDmode)));
4953 emit_insn (gen_fix_trunctddi2_dfp (operands[0], temp,
4954 GEN_INT (DFP_RND_TOWARD_MINF)));
4957 emit_label (label1);
4958 emit_insn (gen_fix_trunctddi2_dfp (operands[0], operands[1],
4959 GEN_INT (DFP_RND_TOWARD_0)));
4960 emit_label (label2);
4964 ; Just a dummy to make the code in the first expander a bit easier.
4965 (define_expand "fixuns_trunc<mode>si2_emu"
4967 [(set (match_operand:SI 0 "register_operand" "")
4968 (unsigned_fix:SI (match_operand:DFP 1 "register_operand" "")))
4969 (unspec:DI [(const_int DFP_RND_TOWARD_0)] UNSPEC_ROUND)
4970 (clobber (reg:CC CC_REGNUM))])]
4972 "!TARGET_Z196 && TARGET_HARD_DFP"
4978 ; fixuns_trunc(tf|df|sf|td|dd)(di|si)2 instruction patterns.
4981 (define_insn "*fixuns_truncdfdi2_vx"
4982 [(set (match_operand:DI 0 "register_operand" "=d,v")
4983 (unsigned_fix:DI (match_operand:DF 1 "register_operand" "f,v")))
4984 (unspec:DI [(match_operand:DI 2 "immediate_operand" "K,K")] UNSPEC_ROUND)
4985 (clobber (reg:CC CC_REGNUM))]
4986 "TARGET_VX && TARGET_HARD_FLOAT"
4989 wclgdb\t%v0,%v1,0,%h2"
4990 [(set_attr "op_type" "RRF,VRR")
4991 (set_attr "type" "ftoi")])
4993 ; (dd|td|sf|df|tf)->unsigned (di|si)
4994 ; clfebr, clfdbr, clfxbr, clgebr, clgdbr, clgxbr
4995 ; clfdtr, clfxtr, clgdtr, clgxtr
4996 (define_insn "*fixuns_trunc<FP:mode><GPR:mode>2_z196"
4997 [(set (match_operand:GPR 0 "register_operand" "=d")
4998 (unsigned_fix:GPR (match_operand:FP 1 "register_operand" "f")))
4999 (unspec:GPR [(match_operand:GPR 2 "immediate_operand" "K")] UNSPEC_ROUND)
5000 (clobber (reg:CC CC_REGNUM))]
5001 "TARGET_Z196 && TARGET_HARD_FLOAT
5002 && (!TARGET_VX || <GPR:MODE>mode != DImode || <FP:MODE>mode != DFmode)"
5003 "cl<GPR:gf><FP:xde><FP:bt>r\t%0,%h2,%1,0"
5004 [(set_attr "op_type" "RRF")
5005 (set_attr "type" "ftoi")])
5007 (define_expand "fix_trunc<DSF:mode><GPR:mode>2"
5008 [(set (match_operand:GPR 0 "register_operand" "")
5009 (fix:GPR (match_operand:DSF 1 "register_operand" "")))]
5012 emit_insn (gen_fix_trunc<DSF:mode><GPR:mode>2_bfp (operands[0], operands[1],
5013 GEN_INT (BFP_RND_TOWARD_0)));
5017 (define_insn "*fix_truncdfdi2_bfp_z13"
5018 [(set (match_operand:DI 0 "register_operand" "=d,v")
5019 (fix:DI (match_operand:DF 1 "register_operand" "f,v")))
5020 (unspec:DI [(match_operand:DI 2 "immediate_operand" "K,K")] UNSPEC_ROUND)
5021 (clobber (reg:CC CC_REGNUM))]
5022 "TARGET_VX && TARGET_HARD_FLOAT"
5025 wcgdb\t%v0,%v1,0,%h2"
5026 [(set_attr "op_type" "RRE,VRR")
5027 (set_attr "type" "ftoi")])
5029 ; cgxbr, cgdbr, cgebr, cfxbr, cfdbr, cfebr
5030 (define_insn "*fix_trunc<BFP:mode><GPR:mode>2_bfp"
5031 [(set (match_operand:GPR 0 "register_operand" "=d")
5032 (fix:GPR (match_operand:BFP 1 "register_operand" "f")))
5033 (unspec:GPR [(match_operand:GPR 2 "immediate_operand" "K")] UNSPEC_ROUND)
5034 (clobber (reg:CC CC_REGNUM))]
5036 && (!TARGET_VX || <GPR:MODE>mode != DImode || <BFP:MODE>mode != DFmode)"
5037 "c<GPR:gf><BFP:xde>br\t%0,%h2,%1"
5038 [(set_attr "op_type" "RRE")
5039 (set_attr "type" "ftoi")])
5041 (define_expand "fix_trunc<BFP:mode><GPR:mode>2_bfp"
5043 [(set (match_operand:GPR 0 "register_operand" "=d")
5044 (fix:GPR (match_operand:BFP 1 "register_operand" "f")))
5045 (unspec:GPR [(match_operand:GPR 2 "immediate_operand" "K")] UNSPEC_ROUND)
5046 (clobber (reg:CC CC_REGNUM))])]
5047 "TARGET_HARD_FLOAT")
5049 ; fix_trunc(td|dd)di2 instruction pattern(s).
5052 (define_expand "fix_trunc<mode>di2"
5053 [(set (match_operand:DI 0 "register_operand" "")
5054 (fix:DI (match_operand:DFP 1 "nonimmediate_operand" "")))]
5055 "TARGET_ZARCH && TARGET_HARD_DFP"
5057 operands[1] = force_reg (<MODE>mode, operands[1]);
5058 emit_insn (gen_fix_trunc<mode>di2_dfp (operands[0], operands[1],
5059 GEN_INT (DFP_RND_TOWARD_0)));
5064 (define_insn "fix_trunc<DFP:mode>di2_dfp"
5065 [(set (match_operand:DI 0 "register_operand" "=d")
5066 (fix:DI (match_operand:DFP 1 "register_operand" "f")))
5067 (unspec:DI [(match_operand:DI 2 "immediate_operand" "K")] UNSPEC_ROUND)
5068 (clobber (reg:CC CC_REGNUM))]
5069 "TARGET_ZARCH && TARGET_HARD_DFP"
5070 "cg<DFP:xde>tr\t%0,%h2,%1"
5071 [(set_attr "op_type" "RRF")
5072 (set_attr "type" "ftoidfp")])
5076 ; fix_trunctf(si|di)2 instruction pattern(s).
5079 (define_expand "fix_trunctf<mode>2"
5080 [(parallel [(set (match_operand:GPR 0 "register_operand" "")
5081 (fix:GPR (match_operand:TF 1 "register_operand" "")))
5082 (unspec:GPR [(const_int BFP_RND_TOWARD_0)] UNSPEC_ROUND)
5083 (clobber (reg:CC CC_REGNUM))])]
5089 ; float(si|di)(tf|df|sf|td|dd)2 instruction pattern(s).
5092 ; cxgbr, cdgbr, cegbr, cxgtr, cdgtr
5093 (define_insn "floatdi<mode>2"
5094 [(set (match_operand:FP 0 "register_operand" "=f,v")
5095 (float:FP (match_operand:DI 1 "register_operand" "d,v")))]
5096 "TARGET_ZARCH && TARGET_HARD_FLOAT"
5100 [(set_attr "op_type" "RRE,VRR")
5101 (set_attr "type" "itof<mode>" )
5102 (set_attr "cpu_facility" "*,vx")
5103 (set_attr "enabled" "*,<DFDI>")])
5105 ; cxfbr, cdfbr, cefbr
5106 (define_insn "floatsi<mode>2"
5107 [(set (match_operand:BFP 0 "register_operand" "=f")
5108 (float:BFP (match_operand:SI 1 "register_operand" "d")))]
5111 [(set_attr "op_type" "RRE")
5112 (set_attr "type" "itof<mode>" )])
5115 (define_insn "floatsi<mode>2"
5116 [(set (match_operand:DFP 0 "register_operand" "=f")
5117 (float:DFP (match_operand:SI 1 "register_operand" "d")))]
5118 "TARGET_Z196 && TARGET_HARD_FLOAT"
5119 "c<xde>ftr\t%0,0,%1,0"
5120 [(set_attr "op_type" "RRE")
5121 (set_attr "type" "itof<mode>" )])
5124 ; floatuns(si|di)(tf|df|sf|td|dd)2 instruction pattern(s).
5127 (define_insn "*floatunsdidf2_z13"
5128 [(set (match_operand:DF 0 "register_operand" "=f,v")
5129 (unsigned_float:DF (match_operand:DI 1 "register_operand" "d,v")))]
5130 "TARGET_VX && TARGET_HARD_FLOAT"
5133 wcdlgb\t%v0,%v1,0,0"
5134 [(set_attr "op_type" "RRE,VRR")
5135 (set_attr "type" "itofdf")])
5137 ; cxlgbr, cdlgbr, celgbr, cxlgtr, cdlgtr
5138 ; cxlfbr, cdlfbr, celfbr, cxlftr, cdlftr
5139 (define_insn "*floatuns<GPR:mode><FP:mode>2"
5140 [(set (match_operand:FP 0 "register_operand" "=f")
5141 (unsigned_float:FP (match_operand:GPR 1 "register_operand" "d")))]
5142 "TARGET_Z196 && TARGET_HARD_FLOAT
5143 && (!TARGET_VX || <FP:MODE>mode != DFmode || <GPR:MODE>mode != DImode)"
5144 "c<FP:xde>l<GPR:gf><FP:bt>r\t%0,0,%1,0"
5145 [(set_attr "op_type" "RRE")
5146 (set_attr "type" "itof<FP:mode>")])
5148 (define_expand "floatuns<GPR:mode><FP:mode>2"
5149 [(set (match_operand:FP 0 "register_operand" "")
5150 (unsigned_float:FP (match_operand:GPR 1 "register_operand" "")))]
5151 "TARGET_Z196 && TARGET_HARD_FLOAT")
5154 ; truncdfsf2 instruction pattern(s).
5157 (define_insn "truncdfsf2"
5158 [(set (match_operand:SF 0 "register_operand" "=f,v")
5159 (float_truncate:SF (match_operand:DF 1 "register_operand" "f,v")))]
5163 wledb\t%v0,%v1,0,0" ; IEEE inexact exception not suppressed
5164 ; According to BFP rounding mode
5165 [(set_attr "op_type" "RRE,VRR")
5166 (set_attr "type" "ftruncdf")
5167 (set_attr "cpu_facility" "*,vx")])
5170 ; trunctf(df|sf)2 instruction pattern(s).
5174 (define_insn "trunctf<mode>2"
5175 [(set (match_operand:DSF 0 "register_operand" "=f")
5176 (float_truncate:DSF (match_operand:TF 1 "register_operand" "f")))
5177 (clobber (match_scratch:TF 2 "=f"))]
5179 "l<xde>xbr\t%2,%1\;l<xde>r\t%0,%2"
5180 [(set_attr "length" "6")
5181 (set_attr "type" "ftrunctf")])
5184 ; trunctddd2 and truncddsd2 instruction pattern(s).
5188 (define_expand "trunctddd2"
5190 [(set (match_operand:DD 0 "register_operand" "")
5191 (float_truncate:DD (match_operand:TD 1 "register_operand" "")))
5192 (unspec:DI [(const_int DFP_RND_CURRENT)] UNSPEC_ROUND)
5193 (clobber (scratch:TD))])]
5196 (define_insn "*trunctddd2"
5197 [(set (match_operand:DD 0 "register_operand" "=f")
5198 (float_truncate:DD (match_operand:TD 1 "register_operand" "f")))
5199 (unspec:DI [(match_operand:DI 2 "const_mask_operand" "I")] UNSPEC_ROUND)
5200 (clobber (match_scratch:TD 3 "=f"))]
5202 "ldxtr\t%3,%2,%1,0\;ldr\t%0,%3"
5203 [(set_attr "length" "6")
5204 (set_attr "type" "ftruncdd")])
5206 (define_insn "truncddsd2"
5207 [(set (match_operand:SD 0 "register_operand" "=f")
5208 (float_truncate:SD (match_operand:DD 1 "register_operand" "f")))]
5211 [(set_attr "op_type" "RRF")
5212 (set_attr "type" "ftruncsd")])
5214 (define_expand "trunctdsd2"
5217 (float_truncate:DD (match_operand:TD 1 "register_operand" "")))
5218 (unspec:DI [(const_int DFP_RND_PREP_FOR_SHORT_PREC)] UNSPEC_ROUND)
5219 (clobber (match_scratch:TD 3 ""))])
5220 (set (match_operand:SD 0 "register_operand" "")
5221 (float_truncate:SD (match_dup 2)))]
5224 operands[2] = gen_reg_rtx (DDmode);
5228 ; extend(sf|df)(df|tf)2 instruction pattern(s).
5232 (define_insn "*extendsfdf2_z13"
5233 [(set (match_operand:DF 0 "register_operand" "=f,f,v")
5234 (float_extend:DF (match_operand:SF 1 "nonimmediate_operand" "f,R,v")))]
5235 "TARGET_VX && TARGET_HARD_FLOAT"
5240 [(set_attr "op_type" "RRE,RXE,VRR")
5241 (set_attr "type" "fsimpdf, floaddf,fsimpdf")])
5243 ; ldebr, ldeb, lxdbr, lxdb, lxebr, lxeb
5244 (define_insn "*extend<DSF:mode><BFP:mode>2"
5245 [(set (match_operand:BFP 0 "register_operand" "=f,f")
5246 (float_extend:BFP (match_operand:DSF 1 "nonimmediate_operand" "f,R")))]
5248 && GET_MODE_SIZE (<BFP:MODE>mode) > GET_MODE_SIZE (<DSF:MODE>mode)
5249 && (!TARGET_VX || <BFP:MODE>mode != DFmode || <DSF:MODE>mode != SFmode)"
5251 l<BFP:xde><DSF:xde>br\t%0,%1
5252 l<BFP:xde><DSF:xde>b\t%0,%1"
5253 [(set_attr "op_type" "RRE,RXE")
5254 (set_attr "type" "fsimp<BFP:mode>, fload<BFP:mode>")])
5256 (define_expand "extend<DSF:mode><BFP:mode>2"
5257 [(set (match_operand:BFP 0 "register_operand" "")
5258 (float_extend:BFP (match_operand:DSF 1 "nonimmediate_operand" "")))]
5260 && GET_MODE_SIZE (<BFP:MODE>mode) > GET_MODE_SIZE (<DSF:MODE>mode)")
5263 ; extendddtd2 and extendsddd2 instruction pattern(s).
5266 (define_insn "extendddtd2"
5267 [(set (match_operand:TD 0 "register_operand" "=f")
5268 (float_extend:TD (match_operand:DD 1 "register_operand" "f")))]
5271 [(set_attr "op_type" "RRF")
5272 (set_attr "type" "fsimptf")])
5274 (define_insn "extendsddd2"
5275 [(set (match_operand:DD 0 "register_operand" "=f")
5276 (float_extend:DD (match_operand:SD 1 "register_operand" "f")))]
5279 [(set_attr "op_type" "RRF")
5280 (set_attr "type" "fsimptf")])
5282 (define_expand "extendsdtd2"
5284 (float_extend:DD (match_operand:SD 1 "register_operand" "")))
5285 (set (match_operand:TD 0 "register_operand" "")
5286 (float_extend:TD (match_dup 2)))]
5289 operands[2] = gen_reg_rtx (DDmode);
5292 ; Binary Floating Point - load fp integer
5294 ; Expanders for: floor, btrunc, round, ceil, and nearbyint
5295 ; For all of them the inexact exceptions are suppressed.
5297 ; fiebra, fidbra, fixbra
5298 (define_insn "<FPINT:fpint_name><BFP:mode>2"
5299 [(set (match_operand:BFP 0 "register_operand" "=f")
5300 (unspec:BFP [(match_operand:BFP 1 "register_operand" "f")]
5303 "fi<BFP:xde>bra\t%0,<FPINT:fpint_roundingmode>,%1,4"
5304 [(set_attr "op_type" "RRF")
5305 (set_attr "type" "fsimp<BFP:mode>")])
5307 ; rint is supposed to raise an inexact exception so we can use the
5308 ; older instructions.
5310 ; fiebr, fidbr, fixbr
5311 (define_insn "rint<BFP:mode>2"
5312 [(set (match_operand:BFP 0 "register_operand" "=f")
5313 (unspec:BFP [(match_operand:BFP 1 "register_operand" "f")]
5314 UNSPEC_FPINT_RINT))]
5316 "fi<BFP:xde>br\t%0,0,%1"
5317 [(set_attr "op_type" "RRF")
5318 (set_attr "type" "fsimp<BFP:mode>")])
5321 ; Decimal Floating Point - load fp integer
5324 (define_insn "<FPINT:fpint_name><DFP:mode>2"
5325 [(set (match_operand:DFP 0 "register_operand" "=f")
5326 (unspec:DFP [(match_operand:DFP 1 "register_operand" "f")]
5329 "fi<DFP:xde>tr\t%0,<FPINT:fpint_roundingmode>,%1,4"
5330 [(set_attr "op_type" "RRF")
5331 (set_attr "type" "fsimp<DFP:mode>")])
5334 (define_insn "rint<DFP:mode>2"
5335 [(set (match_operand:DFP 0 "register_operand" "=f")
5336 (unspec:DFP [(match_operand:DFP 1 "register_operand" "f")]
5337 UNSPEC_FPINT_RINT))]
5339 "fi<DFP:xde>tr\t%0,0,%1,0"
5340 [(set_attr "op_type" "RRF")
5341 (set_attr "type" "fsimp<DFP:mode>")])
5344 ; Binary <-> Decimal floating point trunc patterns
5347 (define_insn "*trunc<BFP:mode><DFP_ALL:mode>2"
5348 [(set (reg:DFP_ALL FPR0_REGNUM)
5349 (float_truncate:DFP_ALL (reg:BFP FPR4_REGNUM)))
5350 (use (reg:SI GPR0_REGNUM))
5351 (clobber (reg:CC CC_REGNUM))
5352 (clobber (reg:SI GPR1_REGNUM))]
5356 (define_insn "*trunc<DFP_ALL:mode><BFP:mode>2"
5357 [(set (reg:BFP FPR0_REGNUM)
5358 (float_truncate:BFP (reg:DFP_ALL FPR4_REGNUM)))
5359 (use (reg:SI GPR0_REGNUM))
5360 (clobber (reg:CC CC_REGNUM))
5361 (clobber (reg:SI GPR1_REGNUM))]
5365 (define_expand "trunc<BFP:mode><DFP_ALL:mode>2"
5366 [(set (reg:BFP FPR4_REGNUM) (match_operand:BFP 1 "nonimmediate_operand" ""))
5367 (set (reg:SI GPR0_REGNUM) (match_dup 2))
5369 [(set (reg:DFP_ALL FPR0_REGNUM)
5370 (float_truncate:DFP_ALL (reg:BFP FPR4_REGNUM)))
5371 (use (reg:SI GPR0_REGNUM))
5372 (clobber (reg:CC CC_REGNUM))
5373 (clobber (reg:SI GPR1_REGNUM))])
5374 (set (match_operand:DFP_ALL 0 "nonimmediate_operand" "")
5375 (reg:DFP_ALL FPR0_REGNUM))]
5377 && GET_MODE_SIZE (<BFP:MODE>mode) > GET_MODE_SIZE (<DFP_ALL:MODE>mode)"
5379 HOST_WIDE_INT flags;
5381 flags = (PFPO_CONVERT |
5382 PFPO_OP_TYPE_<DFP_ALL:MODE> << PFPO_OP0_TYPE_SHIFT |
5383 PFPO_OP_TYPE_<BFP:MODE> << PFPO_OP1_TYPE_SHIFT);
5385 operands[2] = GEN_INT (flags);
5388 (define_expand "trunc<DFP_ALL:mode><BFP:mode>2"
5389 [(set (reg:DFP_ALL FPR4_REGNUM)
5390 (match_operand:DFP_ALL 1 "nonimmediate_operand" ""))
5391 (set (reg:SI GPR0_REGNUM) (match_dup 2))
5393 [(set (reg:BFP FPR0_REGNUM) (float_truncate:BFP (reg:DFP_ALL FPR4_REGNUM)))
5394 (use (reg:SI GPR0_REGNUM))
5395 (clobber (reg:CC CC_REGNUM))
5396 (clobber (reg:SI GPR1_REGNUM))])
5397 (set (match_operand:BFP 0 "nonimmediate_operand" "") (reg:BFP FPR0_REGNUM))]
5399 && GET_MODE_SIZE (<DFP_ALL:MODE>mode) >= GET_MODE_SIZE (<BFP:MODE>mode)"
5401 HOST_WIDE_INT flags;
5403 flags = (PFPO_CONVERT |
5404 PFPO_OP_TYPE_<BFP:MODE> << PFPO_OP0_TYPE_SHIFT |
5405 PFPO_OP_TYPE_<DFP_ALL:MODE> << PFPO_OP1_TYPE_SHIFT);
5407 operands[2] = GEN_INT (flags);
5411 ; Binary <-> Decimal floating point extend patterns
5414 (define_insn "*extend<BFP:mode><DFP_ALL:mode>2"
5415 [(set (reg:DFP_ALL FPR0_REGNUM) (float_extend:DFP_ALL (reg:BFP FPR4_REGNUM)))
5416 (use (reg:SI GPR0_REGNUM))
5417 (clobber (reg:CC CC_REGNUM))
5418 (clobber (reg:SI GPR1_REGNUM))]
5422 (define_insn "*extend<DFP_ALL:mode><BFP:mode>2"
5423 [(set (reg:BFP FPR0_REGNUM) (float_extend:BFP (reg:DFP_ALL FPR4_REGNUM)))
5424 (use (reg:SI GPR0_REGNUM))
5425 (clobber (reg:CC CC_REGNUM))
5426 (clobber (reg:SI GPR1_REGNUM))]
5430 (define_expand "extend<BFP:mode><DFP_ALL:mode>2"
5431 [(set (reg:BFP FPR4_REGNUM) (match_operand:BFP 1 "nonimmediate_operand" ""))
5432 (set (reg:SI GPR0_REGNUM) (match_dup 2))
5434 [(set (reg:DFP_ALL FPR0_REGNUM)
5435 (float_extend:DFP_ALL (reg:BFP FPR4_REGNUM)))
5436 (use (reg:SI GPR0_REGNUM))
5437 (clobber (reg:CC CC_REGNUM))
5438 (clobber (reg:SI GPR1_REGNUM))])
5439 (set (match_operand:DFP_ALL 0 "nonimmediate_operand" "")
5440 (reg:DFP_ALL FPR0_REGNUM))]
5442 && GET_MODE_SIZE (<BFP:MODE>mode) <= GET_MODE_SIZE (<DFP_ALL:MODE>mode)"
5444 HOST_WIDE_INT flags;
5446 flags = (PFPO_CONVERT |
5447 PFPO_OP_TYPE_<DFP_ALL:MODE> << PFPO_OP0_TYPE_SHIFT |
5448 PFPO_OP_TYPE_<BFP:MODE> << PFPO_OP1_TYPE_SHIFT);
5450 operands[2] = GEN_INT (flags);
5453 (define_expand "extend<DFP_ALL:mode><BFP:mode>2"
5454 [(set (reg:DFP_ALL FPR4_REGNUM)
5455 (match_operand:DFP_ALL 1 "nonimmediate_operand" ""))
5456 (set (reg:SI GPR0_REGNUM) (match_dup 2))
5458 [(set (reg:BFP FPR0_REGNUM) (float_extend:BFP (reg:DFP_ALL FPR4_REGNUM)))
5459 (use (reg:SI GPR0_REGNUM))
5460 (clobber (reg:CC CC_REGNUM))
5461 (clobber (reg:SI GPR1_REGNUM))])
5462 (set (match_operand:BFP 0 "nonimmediate_operand" "") (reg:BFP FPR0_REGNUM))]
5464 && GET_MODE_SIZE (<DFP_ALL:MODE>mode) < GET_MODE_SIZE (<BFP:MODE>mode)"
5466 HOST_WIDE_INT flags;
5468 flags = (PFPO_CONVERT |
5469 PFPO_OP_TYPE_<BFP:MODE> << PFPO_OP0_TYPE_SHIFT |
5470 PFPO_OP_TYPE_<DFP_ALL:MODE> << PFPO_OP1_TYPE_SHIFT);
5472 operands[2] = GEN_INT (flags);
5477 ;; ARITHMETIC OPERATIONS
5479 ; arithmetic operations set the ConditionCode,
5480 ; because of unpredictable Bits in Register for Halfword and Byte
5481 ; the ConditionCode can be set wrong in operations for Halfword and Byte
5484 ;;- Add instructions.
5488 ; addti3 instruction pattern(s).
5491 (define_expand "addti3"
5493 [(set (match_operand:TI 0 "register_operand" "")
5494 (plus:TI (match_operand:TI 1 "nonimmediate_operand" "")
5495 (match_operand:TI 2 "general_operand" "") ) )
5496 (clobber (reg:CC CC_REGNUM))])]
5499 /* For z13 we have vaq which doesn't set CC. */
5502 emit_insn (gen_rtx_SET (operands[0],
5503 gen_rtx_PLUS (TImode,
5504 copy_to_mode_reg (TImode, operands[1]),
5505 copy_to_mode_reg (TImode, operands[2]))));
5510 (define_insn_and_split "*addti3"
5511 [(set (match_operand:TI 0 "register_operand" "=&d")
5512 (plus:TI (match_operand:TI 1 "nonimmediate_operand" "%0")
5513 (match_operand:TI 2 "general_operand" "do") ) )
5514 (clobber (reg:CC CC_REGNUM))]
5517 "&& reload_completed"
5519 [(set (reg:CCL1 CC_REGNUM)
5520 (compare:CCL1 (plus:DI (match_dup 7) (match_dup 8))
5522 (set (match_dup 6) (plus:DI (match_dup 7) (match_dup 8)))])
5524 [(set (match_dup 3) (plus:DI
5525 (plus:DI (ltu:DI (reg:CCL1 CC_REGNUM) (const_int 0))
5526 (match_dup 4)) (match_dup 5)))
5527 (clobber (reg:CC CC_REGNUM))])]
5528 "operands[3] = operand_subword (operands[0], 0, 0, TImode);
5529 operands[4] = operand_subword (operands[1], 0, 0, TImode);
5530 operands[5] = operand_subword (operands[2], 0, 0, TImode);
5531 operands[6] = operand_subword (operands[0], 1, 0, TImode);
5532 operands[7] = operand_subword (operands[1], 1, 0, TImode);
5533 operands[8] = operand_subword (operands[2], 1, 0, TImode);"
5534 [(set_attr "op_type" "*")
5535 (set_attr "cpu_facility" "*")])
5538 ; adddi3 instruction pattern(s).
5541 (define_expand "adddi3"
5543 [(set (match_operand:DI 0 "nonimmediate_operand" "")
5544 (plus:DI (match_operand:DI 1 "nonimmediate_operand" "")
5545 (match_operand:DI 2 "general_operand" "")))
5546 (clobber (reg:CC CC_REGNUM))])]
5550 (define_insn "*adddi3_sign"
5551 [(set (match_operand:DI 0 "register_operand" "=d,d")
5552 (plus:DI (sign_extend:DI (match_operand:SI 2 "general_operand" "d,T"))
5553 (match_operand:DI 1 "register_operand" "0,0")))
5554 (clobber (reg:CC CC_REGNUM))]
5559 [(set_attr "op_type" "RRE,RXY")
5560 (set_attr "z196prop" "z196_cracked,z196_cracked")])
5562 (define_insn "*adddi3_zero_cc"
5563 [(set (reg CC_REGNUM)
5564 (compare (plus:DI (zero_extend:DI (match_operand:SI 2 "general_operand" "d,T"))
5565 (match_operand:DI 1 "register_operand" "0,0"))
5567 (set (match_operand:DI 0 "register_operand" "=d,d")
5568 (plus:DI (zero_extend:DI (match_dup 2)) (match_dup 1)))]
5569 "s390_match_ccmode (insn, CCLmode) && TARGET_ZARCH"
5573 [(set_attr "op_type" "RRE,RXY")
5574 (set_attr "z10prop" "z10_super_E1,z10_super_E1")])
5576 (define_insn "*adddi3_zero_cconly"
5577 [(set (reg CC_REGNUM)
5578 (compare (plus:DI (zero_extend:DI (match_operand:SI 2 "general_operand" "d,T"))
5579 (match_operand:DI 1 "register_operand" "0,0"))
5581 (clobber (match_scratch:DI 0 "=d,d"))]
5582 "s390_match_ccmode (insn, CCLmode) && TARGET_ZARCH"
5586 [(set_attr "op_type" "RRE,RXY")
5587 (set_attr "z10prop" "z10_super_E1,z10_super_E1")])
5589 (define_insn "*adddi3_zero"
5590 [(set (match_operand:DI 0 "register_operand" "=d,d")
5591 (plus:DI (zero_extend:DI (match_operand:SI 2 "general_operand" "d,T"))
5592 (match_operand:DI 1 "register_operand" "0,0")))
5593 (clobber (reg:CC CC_REGNUM))]
5598 [(set_attr "op_type" "RRE,RXY")
5599 (set_attr "z10prop" "z10_super_E1,z10_super_E1")])
5601 (define_insn_and_split "*adddi3_31z"
5602 [(set (match_operand:DI 0 "nonimmediate_operand" "=&d")
5603 (plus:DI (match_operand:DI 1 "nonimmediate_operand" "%0")
5604 (match_operand:DI 2 "general_operand" "do") ) )
5605 (clobber (reg:CC CC_REGNUM))]
5606 "!TARGET_ZARCH && TARGET_CPU_ZARCH"
5608 "&& reload_completed"
5610 [(set (reg:CCL1 CC_REGNUM)
5611 (compare:CCL1 (plus:SI (match_dup 7) (match_dup 8))
5613 (set (match_dup 6) (plus:SI (match_dup 7) (match_dup 8)))])
5615 [(set (match_dup 3) (plus:SI
5616 (plus:SI (ltu:SI (reg:CCL1 CC_REGNUM) (const_int 0))
5617 (match_dup 4)) (match_dup 5)))
5618 (clobber (reg:CC CC_REGNUM))])]
5619 "operands[3] = operand_subword (operands[0], 0, 0, DImode);
5620 operands[4] = operand_subword (operands[1], 0, 0, DImode);
5621 operands[5] = operand_subword (operands[2], 0, 0, DImode);
5622 operands[6] = operand_subword (operands[0], 1, 0, DImode);
5623 operands[7] = operand_subword (operands[1], 1, 0, DImode);
5624 operands[8] = operand_subword (operands[2], 1, 0, DImode);")
5626 (define_insn_and_split "*adddi3_31"
5627 [(set (match_operand:DI 0 "nonimmediate_operand" "=&d")
5628 (plus:DI (match_operand:DI 1 "nonimmediate_operand" "%0")
5629 (match_operand:DI 2 "general_operand" "do") ) )
5630 (clobber (reg:CC CC_REGNUM))]
5633 "&& reload_completed"
5635 [(set (match_dup 3) (plus:SI (match_dup 4) (match_dup 5)))
5636 (clobber (reg:CC CC_REGNUM))])
5638 [(set (reg:CCL1 CC_REGNUM)
5639 (compare:CCL1 (plus:SI (match_dup 7) (match_dup 8))
5641 (set (match_dup 6) (plus:SI (match_dup 7) (match_dup 8)))])
5643 (if_then_else (ltu (reg:CCL1 CC_REGNUM) (const_int 0))
5645 (label_ref (match_dup 9))))
5647 [(set (match_dup 3) (plus:SI (match_dup 3) (const_int 1)))
5648 (clobber (reg:CC CC_REGNUM))])
5650 "operands[3] = operand_subword (operands[0], 0, 0, DImode);
5651 operands[4] = operand_subword (operands[1], 0, 0, DImode);
5652 operands[5] = operand_subword (operands[2], 0, 0, DImode);
5653 operands[6] = operand_subword (operands[0], 1, 0, DImode);
5654 operands[7] = operand_subword (operands[1], 1, 0, DImode);
5655 operands[8] = operand_subword (operands[2], 1, 0, DImode);
5656 operands[9] = gen_label_rtx ();")
5659 ; addsi3 instruction pattern(s).
5662 (define_expand "addsi3"
5664 [(set (match_operand:SI 0 "nonimmediate_operand" "")
5665 (plus:SI (match_operand:SI 1 "nonimmediate_operand" "")
5666 (match_operand:SI 2 "general_operand" "")))
5667 (clobber (reg:CC CC_REGNUM))])]
5671 (define_insn "*addsi3_sign"
5672 [(set (match_operand:SI 0 "register_operand" "=d,d")
5673 (plus:SI (sign_extend:SI (match_operand:HI 2 "memory_operand" "R,T"))
5674 (match_operand:SI 1 "register_operand" "0,0")))
5675 (clobber (reg:CC CC_REGNUM))]
5680 [(set_attr "op_type" "RX,RXY")
5681 (set_attr "cpu_facility" "*,longdisp")
5682 (set_attr "z196prop" "z196_cracked,z196_cracked")])
5685 ; add(di|si)3 instruction pattern(s).
5688 ; ark, agrk, ar, ahi, ahik, aghik, alfi, slfi, a, ay, agr, aghi, algfi, slgfi, ag, asi, agsi
5689 (define_insn "*add<mode>3"
5690 [(set (match_operand:GPR 0 "nonimmediate_operand" "=d,d,d,d, d, d,d,d,S")
5691 (plus:GPR (match_operand:GPR 1 "nonimmediate_operand" "%0,d,0,d, 0, 0,0,0,0")
5692 (match_operand:GPR 2 "general_operand" " d,d,K,K,Op,On,R,T,C") ) )
5693 (clobber (reg:CC CC_REGNUM))]
5705 [(set_attr "op_type" "RR<E>,RRF,RI,RIE,RIL,RIL,RX<Y>,RXY,SIY")
5706 (set_attr "cpu_facility" "*,z196,*,z196,extimm,extimm,*,longdisp,z10")
5707 (set_attr "z10prop" "z10_super_E1,*,z10_super_E1,*,z10_super_E1,z10_super_E1,
5708 z10_super_E1,z10_super_E1,z10_super_E1")])
5710 ; alr, alfi, slfi, al, aly, alrk, alhsik, algr, algfi, slgfi, alg, alsi, algsi, algrk, alghsik
5711 (define_insn "*add<mode>3_carry1_cc"
5712 [(set (reg CC_REGNUM)
5713 (compare (plus:GPR (match_operand:GPR 1 "nonimmediate_operand" "%0,d, 0, 0,d,0,0,0")
5714 (match_operand:GPR 2 "general_operand" " d,d,Op,On,K,R,T,C"))
5716 (set (match_operand:GPR 0 "nonimmediate_operand" "=d,d, d, d,d,d,d,d")
5717 (plus:GPR (match_dup 1) (match_dup 2)))]
5718 "s390_match_ccmode (insn, CCL1mode)"
5724 al<g>hsik\t%0,%1,%h2
5728 [(set_attr "op_type" "RR<E>,RRF,RIL,RIL,RIE,RX<Y>,RXY,SIY")
5729 (set_attr "cpu_facility" "*,z196,extimm,extimm,z196,*,longdisp,z10")
5730 (set_attr "z10prop" "z10_super_E1,*,z10_super_E1,z10_super_E1,*,
5731 z10_super_E1,z10_super_E1,z10_super_E1")])
5733 ; alr, al, aly, algr, alg, alrk, algrk
5734 (define_insn "*add<mode>3_carry1_cconly"
5735 [(set (reg CC_REGNUM)
5736 (compare (plus:GPR (match_operand:GPR 1 "nonimmediate_operand" "%0,d,0,0")
5737 (match_operand:GPR 2 "general_operand" "d,d,R,T"))
5739 (clobber (match_scratch:GPR 0 "=d,d,d,d"))]
5740 "s390_match_ccmode (insn, CCL1mode)"
5746 [(set_attr "op_type" "RR<E>,RRF,RX<Y>,RXY")
5747 (set_attr "cpu_facility" "*,z196,*,longdisp")
5748 (set_attr "z10prop" "z10_super_E1,*,z10_super_E1,z10_super_E1")])
5750 ; alr, alfi, slfi, al, aly, algr, algfi, slgfi, alg, alsi, algsi, alrk, algrk, alhsik, alghsik
5751 (define_insn "*add<mode>3_carry2_cc"
5752 [(set (reg CC_REGNUM)
5753 (compare (plus:GPR (match_operand:GPR 1 "nonimmediate_operand" "%0,d, 0, 0,d,0,0,0")
5754 (match_operand:GPR 2 "general_operand" " d,d,Op,On,K,R,T,C"))
5756 (set (match_operand:GPR 0 "nonimmediate_operand" "=d,d, d, d,d,d,d,S")
5757 (plus:GPR (match_dup 1) (match_dup 2)))]
5758 "s390_match_ccmode (insn, CCL1mode)"
5764 al<g>hsik\t%0,%1,%h2
5768 [(set_attr "op_type" "RR<E>,RRF,RIL,RIL,RIE,RX<Y>,RXY,SIY")
5769 (set_attr "cpu_facility" "*,z196,extimm,extimm,z196,*,longdisp,z10")
5770 (set_attr "z10prop" "z10_super_E1,*,z10_super_E1,z10_super_E1,*,
5771 z10_super_E1,z10_super_E1,z10_super_E1")])
5773 ; alr, al, aly, algr, alg, alrk, algrk
5774 (define_insn "*add<mode>3_carry2_cconly"
5775 [(set (reg CC_REGNUM)
5776 (compare (plus:GPR (match_operand:GPR 1 "nonimmediate_operand" "%0,d,0,0")
5777 (match_operand:GPR 2 "general_operand" "d,d,R,T"))
5779 (clobber (match_scratch:GPR 0 "=d,d,d,d"))]
5780 "s390_match_ccmode (insn, CCL1mode)"
5786 [(set_attr "op_type" "RR<E>,RRF,RX<Y>,RXY")
5787 (set_attr "cpu_facility" "*,z196,*,longdisp")
5788 (set_attr "z10prop" "z10_super_E1,*,z10_super_E1,z10_super_E1")])
5790 ; alr, alfi, slfi, al, aly, algr, algfi, slgfi, alg, alsi, algsi, alrk, algrk, alhsik, alghsik
5791 (define_insn "*add<mode>3_cc"
5792 [(set (reg CC_REGNUM)
5793 (compare (plus:GPR (match_operand:GPR 1 "nonimmediate_operand" "%0,d, 0, 0,d,0,0,0")
5794 (match_operand:GPR 2 "general_operand" " d,d,Op,On,K,R,T,C"))
5796 (set (match_operand:GPR 0 "nonimmediate_operand" "=d,d, d, d,d,d,d,S")
5797 (plus:GPR (match_dup 1) (match_dup 2)))]
5798 "s390_match_ccmode (insn, CCLmode)"
5804 al<g>hsik\t%0,%1,%h2
5808 [(set_attr "op_type" "RR<E>,RRF,RIL,RIL,RIE,RX<Y>,RXY,SIY")
5809 (set_attr "cpu_facility" "*,z196,extimm,extimm,z196,*,longdisp,z10")
5810 (set_attr "z10prop" "z10_super_E1,*,z10_super_E1,z10_super_E1,
5811 *,z10_super_E1,z10_super_E1,z10_super_E1")])
5813 ; alr, al, aly, algr, alg, alrk, algrk
5814 (define_insn "*add<mode>3_cconly"
5815 [(set (reg CC_REGNUM)
5816 (compare (plus:GPR (match_operand:GPR 1 "nonimmediate_operand" "%0,d,0,0")
5817 (match_operand:GPR 2 "general_operand" "d,d,R,T"))
5819 (clobber (match_scratch:GPR 0 "=d,d,d,d"))]
5820 "s390_match_ccmode (insn, CCLmode)"
5826 [(set_attr "op_type" "RR<E>,RRF,RX<Y>,RXY")
5827 (set_attr "cpu_facility" "*,z196,*,longdisp")
5828 (set_attr "z10prop" "z10_super_E1,*,z10_super_E1,z10_super_E1")])
5830 ; alr, al, aly, algr, alg, alrk, algrk
5831 (define_insn "*add<mode>3_cconly2"
5832 [(set (reg CC_REGNUM)
5833 (compare (match_operand:GPR 1 "nonimmediate_operand" "%0,d,0,0")
5834 (neg:GPR (match_operand:GPR 2 "general_operand" "d,d,R,T"))))
5835 (clobber (match_scratch:GPR 0 "=d,d,d,d"))]
5836 "s390_match_ccmode(insn, CCLmode)"
5842 [(set_attr "op_type" "RR<E>,RRF,RX<Y>,RXY")
5843 (set_attr "cpu_facility" "*,z196,*,longdisp")
5844 (set_attr "z10prop" "z10_super_E1,*,z10_super_E1,z10_super_E1")])
5846 ; ahi, afi, aghi, agfi, asi, agsi
5847 (define_insn "*add<mode>3_imm_cc"
5848 [(set (reg CC_REGNUM)
5849 (compare (plus:GPR (match_operand:GPR 1 "nonimmediate_operand" " 0, d,0, 0")
5850 (match_operand:GPR 2 "const_int_operand" " K, K,Os,C"))
5852 (set (match_operand:GPR 0 "nonimmediate_operand" "=d, d,d, S")
5853 (plus:GPR (match_dup 1) (match_dup 2)))]
5854 "s390_match_ccmode (insn, CCAmode)
5855 && (CONST_OK_FOR_CONSTRAINT_P (INTVAL (operands[2]), 'K', \"K\")
5856 || (CONST_OK_FOR_CONSTRAINT_P (INTVAL (operands[2]), 'O', \"Os\")
5857 /* Avoid INT32_MIN on 32 bit. */
5858 && (!TARGET_ZARCH || INTVAL (operands[2]) != -0x7fffffff - 1)))"
5864 [(set_attr "op_type" "RI,RIE,RIL,SIY")
5865 (set_attr "cpu_facility" "*,z196,extimm,z10")
5866 (set_attr "z10prop" "z10_super_E1,*,z10_super_E1,z10_super_E1")])
5868 (define_insn "*adddi3_sign"
5869 [(set (match_operand:DI 0 "register_operand" "=d")
5870 (plus:DI (sign_extend:DI (match_operand:HI 2 "memory_operand" "T"))
5871 (match_operand:DI 1 "register_operand" "0")))
5872 (clobber (reg:CC CC_REGNUM))]
5875 [(set_attr "op_type" "RXY")])
5878 ; add(tf|df|sf|td|dd)3 instruction pattern(s).
5881 ; axbr, adbr, aebr, axb, adb, aeb, adtr, axtr
5882 ; FIXME: wfadb does not clobber cc
5883 (define_insn "add<mode>3"
5884 [(set (match_operand:FP 0 "register_operand" "=f,f,f,v,v")
5885 (plus:FP (match_operand:FP 1 "nonimmediate_operand" "%f,0,0,v,v")
5886 (match_operand:FP 2 "general_operand" "f,f,R,v,v")))
5887 (clobber (reg:CC CC_REGNUM))]
5895 [(set_attr "op_type" "RRF,RRE,RXE,VRR,VRR")
5896 (set_attr "type" "fsimp<mode>")
5897 (set_attr "cpu_facility" "*,*,*,vx,vxe")
5898 (set_attr "enabled" "<nBFP>,<nDFP>,<DSF>,<DF>,<SF>")])
5900 ; axbr, adbr, aebr, axb, adb, aeb, adtr, axtr
5901 (define_insn "*add<mode>3_cc"
5902 [(set (reg CC_REGNUM)
5903 (compare (plus:FP (match_operand:FP 1 "nonimmediate_operand" "%f,0,0")
5904 (match_operand:FP 2 "general_operand" "f,f,R"))
5905 (match_operand:FP 3 "const0_operand" "")))
5906 (set (match_operand:FP 0 "register_operand" "=f,f,f")
5907 (plus:FP (match_dup 1) (match_dup 2)))]
5908 "s390_match_ccmode (insn, CCSmode) && TARGET_HARD_FLOAT"
5913 [(set_attr "op_type" "RRF,RRE,RXE")
5914 (set_attr "type" "fsimp<mode>")
5915 (set_attr "enabled" "<nBFP>,<nDFP>,<DSF>")])
5917 ; axbr, adbr, aebr, axb, adb, aeb, adtr, axtr
5918 (define_insn "*add<mode>3_cconly"
5919 [(set (reg CC_REGNUM)
5920 (compare (plus:FP (match_operand:FP 1 "nonimmediate_operand" "%f,0,0")
5921 (match_operand:FP 2 "general_operand" "f,f,R"))
5922 (match_operand:FP 3 "const0_operand" "")))
5923 (clobber (match_scratch:FP 0 "=f,f,f"))]
5924 "s390_match_ccmode (insn, CCSmode) && TARGET_HARD_FLOAT"
5929 [(set_attr "op_type" "RRF,RRE,RXE")
5930 (set_attr "type" "fsimp<mode>")
5931 (set_attr "enabled" "<nBFP>,<nDFP>,<DSF>")])
5934 ; Pointer add instruction patterns
5937 ; This will match "*la_64"
5938 (define_expand "addptrdi3"
5939 [(set (match_operand:DI 0 "register_operand" "")
5940 (plus:DI (match_operand:DI 1 "register_operand" "")
5941 (match_operand:DI 2 "nonmemory_operand" "")))]
5944 if (GET_CODE (operands[2]) == CONST_INT)
5946 HOST_WIDE_INT c = INTVAL (operands[2]);
5948 if (!CONST_OK_FOR_CONSTRAINT_P (c, 'K', "K")
5949 && !CONST_OK_FOR_CONSTRAINT_P (c, 'O', "Os"))
5951 operands[2] = force_const_mem (DImode, operands[2]);
5952 operands[2] = force_reg (DImode, operands[2]);
5954 else if (!DISP_IN_RANGE (INTVAL (operands[2])))
5955 operands[2] = force_reg (DImode, operands[2]);
5959 ; For 31 bit we have to prevent the generated pattern from matching
5960 ; normal ADDs since la only does a 31 bit add. This is supposed to
5961 ; match "force_la_31".
5962 (define_expand "addptrsi3"
5964 [(set (match_operand:SI 0 "register_operand" "")
5965 (plus:SI (match_operand:SI 1 "register_operand" "")
5966 (match_operand:SI 2 "nonmemory_operand" "")))
5967 (use (const_int 0))])]
5970 if (GET_CODE (operands[2]) == CONST_INT)
5972 HOST_WIDE_INT c = INTVAL (operands[2]);
5974 if (!CONST_OK_FOR_CONSTRAINT_P (c, 'K', "K")
5975 && !CONST_OK_FOR_CONSTRAINT_P (c, 'O', "Os"))
5977 operands[2] = force_const_mem (SImode, operands[2]);
5978 operands[2] = force_reg (SImode, operands[2]);
5980 else if (!DISP_IN_RANGE (INTVAL (operands[2])))
5981 operands[2] = force_reg (SImode, operands[2]);
5986 ;;- Subtract instructions.
5990 ; subti3 instruction pattern(s).
5993 (define_expand "subti3"
5995 [(set (match_operand:TI 0 "register_operand" "")
5996 (minus:TI (match_operand:TI 1 "register_operand" "")
5997 (match_operand:TI 2 "general_operand" "") ) )
5998 (clobber (reg:CC CC_REGNUM))])]
6001 /* For z13 we have vsq which doesn't set CC. */
6004 emit_insn (gen_rtx_SET (operands[0],
6005 gen_rtx_MINUS (TImode,
6007 copy_to_mode_reg (TImode, operands[2]))));
6012 (define_insn_and_split "*subti3"
6013 [(set (match_operand:TI 0 "register_operand" "=&d")
6014 (minus:TI (match_operand:TI 1 "register_operand" "0")
6015 (match_operand:TI 2 "general_operand" "do") ) )
6016 (clobber (reg:CC CC_REGNUM))]
6019 "&& reload_completed"
6021 [(set (reg:CCL2 CC_REGNUM)
6022 (compare:CCL2 (minus:DI (match_dup 7) (match_dup 8))
6024 (set (match_dup 6) (minus:DI (match_dup 7) (match_dup 8)))])
6026 [(set (match_dup 3) (minus:DI (minus:DI (match_dup 4) (match_dup 5))
6027 (gtu:DI (reg:CCL2 CC_REGNUM) (const_int 0))))
6028 (clobber (reg:CC CC_REGNUM))])]
6029 "operands[3] = operand_subword (operands[0], 0, 0, TImode);
6030 operands[4] = operand_subword (operands[1], 0, 0, TImode);
6031 operands[5] = operand_subword (operands[2], 0, 0, TImode);
6032 operands[6] = operand_subword (operands[0], 1, 0, TImode);
6033 operands[7] = operand_subword (operands[1], 1, 0, TImode);
6034 operands[8] = operand_subword (operands[2], 1, 0, TImode);"
6035 [(set_attr "op_type" "*")
6036 (set_attr "cpu_facility" "*")])
6039 ; subdi3 instruction pattern(s).
6042 (define_expand "subdi3"
6044 [(set (match_operand:DI 0 "register_operand" "")
6045 (minus:DI (match_operand:DI 1 "register_operand" "")
6046 (match_operand:DI 2 "general_operand" "")))
6047 (clobber (reg:CC CC_REGNUM))])]
6051 (define_insn "*subdi3_sign"
6052 [(set (match_operand:DI 0 "register_operand" "=d,d")
6053 (minus:DI (match_operand:DI 1 "register_operand" "0,0")
6054 (sign_extend:DI (match_operand:SI 2 "general_operand" "d,T"))))
6055 (clobber (reg:CC CC_REGNUM))]
6060 [(set_attr "op_type" "RRE,RXY")
6061 (set_attr "z10prop" "z10_c,*")
6062 (set_attr "z196prop" "z196_cracked")])
6064 (define_insn "*subdi3_zero_cc"
6065 [(set (reg CC_REGNUM)
6066 (compare (minus:DI (match_operand:DI 1 "register_operand" "0,0")
6067 (zero_extend:DI (match_operand:SI 2 "general_operand" "d,T")))
6069 (set (match_operand:DI 0 "register_operand" "=d,d")
6070 (minus:DI (match_dup 1) (zero_extend:DI (match_dup 2))))]
6071 "s390_match_ccmode (insn, CCLmode) && TARGET_ZARCH"
6075 [(set_attr "op_type" "RRE,RXY")
6076 (set_attr "z10prop" "z10_super_c_E1,z10_super_E1")])
6078 (define_insn "*subdi3_zero_cconly"
6079 [(set (reg CC_REGNUM)
6080 (compare (minus:DI (match_operand:DI 1 "register_operand" "0,0")
6081 (zero_extend:DI (match_operand:SI 2 "general_operand" "d,T")))
6083 (clobber (match_scratch:DI 0 "=d,d"))]
6084 "s390_match_ccmode (insn, CCLmode) && TARGET_ZARCH"
6088 [(set_attr "op_type" "RRE,RXY")
6089 (set_attr "z10prop" "z10_super_c_E1,z10_super_E1")])
6091 (define_insn "*subdi3_zero"
6092 [(set (match_operand:DI 0 "register_operand" "=d,d")
6093 (minus:DI (match_operand:DI 1 "register_operand" "0,0")
6094 (zero_extend:DI (match_operand:SI 2 "general_operand" "d,T"))))
6095 (clobber (reg:CC CC_REGNUM))]
6100 [(set_attr "op_type" "RRE,RXY")
6101 (set_attr "z10prop" "z10_super_c_E1,z10_super_E1")])
6103 (define_insn_and_split "*subdi3_31z"
6104 [(set (match_operand:DI 0 "register_operand" "=&d")
6105 (minus:DI (match_operand:DI 1 "register_operand" "0")
6106 (match_operand:DI 2 "general_operand" "do") ) )
6107 (clobber (reg:CC CC_REGNUM))]
6108 "!TARGET_ZARCH && TARGET_CPU_ZARCH"
6110 "&& reload_completed"
6112 [(set (reg:CCL2 CC_REGNUM)
6113 (compare:CCL2 (minus:SI (match_dup 7) (match_dup 8))
6115 (set (match_dup 6) (minus:SI (match_dup 7) (match_dup 8)))])
6117 [(set (match_dup 3) (minus:SI (minus:SI (match_dup 4) (match_dup 5))
6118 (gtu:SI (reg:CCL2 CC_REGNUM) (const_int 0))))
6119 (clobber (reg:CC CC_REGNUM))])]
6120 "operands[3] = operand_subword (operands[0], 0, 0, DImode);
6121 operands[4] = operand_subword (operands[1], 0, 0, DImode);
6122 operands[5] = operand_subword (operands[2], 0, 0, DImode);
6123 operands[6] = operand_subword (operands[0], 1, 0, DImode);
6124 operands[7] = operand_subword (operands[1], 1, 0, DImode);
6125 operands[8] = operand_subword (operands[2], 1, 0, DImode);")
6127 (define_insn_and_split "*subdi3_31"
6128 [(set (match_operand:DI 0 "register_operand" "=&d")
6129 (minus:DI (match_operand:DI 1 "register_operand" "0")
6130 (match_operand:DI 2 "general_operand" "do") ) )
6131 (clobber (reg:CC CC_REGNUM))]
6134 "&& reload_completed"
6136 [(set (match_dup 3) (minus:SI (match_dup 4) (match_dup 5)))
6137 (clobber (reg:CC CC_REGNUM))])
6139 [(set (reg:CCL2 CC_REGNUM)
6140 (compare:CCL2 (minus:SI (match_dup 7) (match_dup 8))
6142 (set (match_dup 6) (minus:SI (match_dup 7) (match_dup 8)))])
6144 (if_then_else (gtu (reg:CCL2 CC_REGNUM) (const_int 0))
6146 (label_ref (match_dup 9))))
6148 [(set (match_dup 3) (plus:SI (match_dup 3) (const_int -1)))
6149 (clobber (reg:CC CC_REGNUM))])
6151 "operands[3] = operand_subword (operands[0], 0, 0, DImode);
6152 operands[4] = operand_subword (operands[1], 0, 0, DImode);
6153 operands[5] = operand_subword (operands[2], 0, 0, DImode);
6154 operands[6] = operand_subword (operands[0], 1, 0, DImode);
6155 operands[7] = operand_subword (operands[1], 1, 0, DImode);
6156 operands[8] = operand_subword (operands[2], 1, 0, DImode);
6157 operands[9] = gen_label_rtx ();")
6160 ; subsi3 instruction pattern(s).
6163 (define_expand "subsi3"
6165 [(set (match_operand:SI 0 "register_operand" "")
6166 (minus:SI (match_operand:SI 1 "register_operand" "")
6167 (match_operand:SI 2 "general_operand" "")))
6168 (clobber (reg:CC CC_REGNUM))])]
6172 (define_insn "*subsi3_sign"
6173 [(set (match_operand:SI 0 "register_operand" "=d,d")
6174 (minus:SI (match_operand:SI 1 "register_operand" "0,0")
6175 (sign_extend:SI (match_operand:HI 2 "memory_operand" "R,T"))))
6176 (clobber (reg:CC CC_REGNUM))]
6181 [(set_attr "op_type" "RX,RXY")
6182 (set_attr "cpu_facility" "*,longdisp")
6183 (set_attr "z196prop" "z196_cracked,z196_cracked")])
6186 ; sub(di|si)3 instruction pattern(s).
6189 ; sr, s, sy, sgr, sg, srk, sgrk
6190 (define_insn "*sub<mode>3"
6191 [(set (match_operand:GPR 0 "register_operand" "=d,d,d,d")
6192 (minus:GPR (match_operand:GPR 1 "register_operand" "0,d,0,0")
6193 (match_operand:GPR 2 "general_operand" "d,d,R,T") ) )
6194 (clobber (reg:CC CC_REGNUM))]
6201 [(set_attr "op_type" "RR<E>,RRF,RX<Y>,RXY")
6202 (set_attr "cpu_facility" "*,z196,*,longdisp")
6203 (set_attr "z10prop" "z10_super_c_E1,*,z10_super_E1,z10_super_E1")])
6205 ; slr, sl, sly, slgr, slg, slrk, slgrk
6206 (define_insn "*sub<mode>3_borrow_cc"
6207 [(set (reg CC_REGNUM)
6208 (compare (minus:GPR (match_operand:GPR 1 "register_operand" "0,d,0,0")
6209 (match_operand:GPR 2 "general_operand" "d,d,R,T"))
6211 (set (match_operand:GPR 0 "register_operand" "=d,d,d,d")
6212 (minus:GPR (match_dup 1) (match_dup 2)))]
6213 "s390_match_ccmode (insn, CCL2mode)"
6219 [(set_attr "op_type" "RR<E>,RRF,RX<Y>,RXY")
6220 (set_attr "cpu_facility" "*,z196,*,longdisp")
6221 (set_attr "z10prop" "z10_super_c_E1,*,z10_super_E1,z10_super_E1")])
6223 ; slr, sl, sly, slgr, slg, slrk, slgrk
6224 (define_insn "*sub<mode>3_borrow_cconly"
6225 [(set (reg CC_REGNUM)
6226 (compare (minus:GPR (match_operand:GPR 1 "register_operand" "0,d,0,0")
6227 (match_operand:GPR 2 "general_operand" "d,d,R,T"))
6229 (clobber (match_scratch:GPR 0 "=d,d,d,d"))]
6230 "s390_match_ccmode (insn, CCL2mode)"
6236 [(set_attr "op_type" "RR<E>,RRF,RX<Y>,RXY")
6237 (set_attr "cpu_facility" "*,z196,*,longdisp")
6238 (set_attr "z10prop" "z10_super_c_E1,*,z10_super_E1,z10_super_E1")])
6240 ; slr, sl, sly, slgr, slg, slrk, slgrk
6241 (define_insn "*sub<mode>3_cc"
6242 [(set (reg CC_REGNUM)
6243 (compare (minus:GPR (match_operand:GPR 1 "register_operand" "0,d,0,0")
6244 (match_operand:GPR 2 "general_operand" "d,d,R,T"))
6246 (set (match_operand:GPR 0 "register_operand" "=d,d,d,d")
6247 (minus:GPR (match_dup 1) (match_dup 2)))]
6248 "s390_match_ccmode (insn, CCLmode)"
6254 [(set_attr "op_type" "RR<E>,RRF,RX<Y>,RXY")
6255 (set_attr "cpu_facility" "*,z196,*,longdisp")
6256 (set_attr "z10prop" "z10_super_c_E1,*,z10_super_E1,z10_super_E1")])
6258 ; slr, sl, sly, slgr, slg, slrk, slgrk
6259 (define_insn "*sub<mode>3_cc2"
6260 [(set (reg CC_REGNUM)
6261 (compare (match_operand:GPR 1 "register_operand" "0,d,0,0")
6262 (match_operand:GPR 2 "general_operand" "d,d,R,T")))
6263 (set (match_operand:GPR 0 "register_operand" "=d,d,d,d")
6264 (minus:GPR (match_dup 1) (match_dup 2)))]
6265 "s390_match_ccmode (insn, CCL3mode)"
6271 [(set_attr "op_type" "RR<E>,RRF,RX<Y>,RXY")
6272 (set_attr "cpu_facility" "*,z196,*,longdisp")
6273 (set_attr "z10prop" "z10_super_c_E1,*,z10_super_E1,z10_super_E1")])
6275 ; slr, sl, sly, slgr, slg, slrk, slgrk
6276 (define_insn "*sub<mode>3_cconly"
6277 [(set (reg CC_REGNUM)
6278 (compare (minus:GPR (match_operand:GPR 1 "register_operand" "0,d,0,0")
6279 (match_operand:GPR 2 "general_operand" "d,d,R,T"))
6281 (clobber (match_scratch:GPR 0 "=d,d,d,d"))]
6282 "s390_match_ccmode (insn, CCLmode)"
6288 [(set_attr "op_type" "RR<E>,RRF,RX<Y>,RXY")
6289 (set_attr "cpu_facility" "*,z196,*,longdisp")
6290 (set_attr "z10prop" "z10_super_c_E1,*,z10_super_E1,z10_super_E1")])
6293 ; slr, sl, sly, slgr, slg, slrk, slgrk
6294 (define_insn "*sub<mode>3_cconly2"
6295 [(set (reg CC_REGNUM)
6296 (compare (match_operand:GPR 1 "register_operand" "0,d,0,0")
6297 (match_operand:GPR 2 "general_operand" "d,d,R,T")))
6298 (clobber (match_scratch:GPR 0 "=d,d,d,d"))]
6299 "s390_match_ccmode (insn, CCL3mode)"
6305 [(set_attr "op_type" "RR<E>,RRF,RX<Y>,RXY")
6306 (set_attr "cpu_facility" "*,z196,*,longdisp")
6307 (set_attr "z10prop" "z10_super_c_E1,*,z10_super_E1,z10_super_E1")])
6309 (define_insn "*subdi3_sign"
6310 [(set (match_operand:DI 0 "register_operand" "=d")
6311 (minus:DI (match_operand:DI 1 "register_operand" "0")
6312 (sign_extend:DI (match_operand:HI 2 "memory_operand" "T"))))
6313 (clobber (reg:CC CC_REGNUM))]
6316 [(set_attr "op_type" "RXY")])
6320 ; sub(tf|df|sf|td|dd)3 instruction pattern(s).
6323 ; FIXME: (clobber (match_scratch:CC 3 "=c,c,c,X,X")) does not work - why?
6324 ; sxbr, sdbr, sebr, sdb, seb, sxtr, sdtr
6325 (define_insn "sub<mode>3"
6326 [(set (match_operand:FP 0 "register_operand" "=f,f,f,v,v")
6327 (minus:FP (match_operand:FP 1 "register_operand" "f,0,0,v,v")
6328 (match_operand:FP 2 "general_operand" "f,f,R,v,v")))
6329 (clobber (reg:CC CC_REGNUM))]
6337 [(set_attr "op_type" "RRF,RRE,RXE,VRR,VRR")
6338 (set_attr "type" "fsimp<mode>")
6339 (set_attr "cpu_facility" "*,*,*,vx,vxe")
6340 (set_attr "enabled" "<nBFP>,<nDFP>,<DSF>,<DF>,<SF>")])
6342 ; sxbr, sdbr, sebr, sdb, seb, sxtr, sdtr
6343 (define_insn "*sub<mode>3_cc"
6344 [(set (reg CC_REGNUM)
6345 (compare (minus:FP (match_operand:FP 1 "nonimmediate_operand" "f,0,0")
6346 (match_operand:FP 2 "general_operand" "f,f,R"))
6347 (match_operand:FP 3 "const0_operand" "")))
6348 (set (match_operand:FP 0 "register_operand" "=f,f,f")
6349 (minus:FP (match_dup 1) (match_dup 2)))]
6350 "s390_match_ccmode (insn, CCSmode) && TARGET_HARD_FLOAT"
6355 [(set_attr "op_type" "RRF,RRE,RXE")
6356 (set_attr "type" "fsimp<mode>")
6357 (set_attr "enabled" "<nBFP>,<nDFP>,<DSF>")])
6359 ; sxbr, sdbr, sebr, sdb, seb, sxtr, sdtr
6360 (define_insn "*sub<mode>3_cconly"
6361 [(set (reg CC_REGNUM)
6362 (compare (minus:FP (match_operand:FP 1 "nonimmediate_operand" "f,0,0")
6363 (match_operand:FP 2 "general_operand" "f,f,R"))
6364 (match_operand:FP 3 "const0_operand" "")))
6365 (clobber (match_scratch:FP 0 "=f,f,f"))]
6366 "s390_match_ccmode (insn, CCSmode) && TARGET_HARD_FLOAT"
6371 [(set_attr "op_type" "RRF,RRE,RXE")
6372 (set_attr "type" "fsimp<mode>")
6373 (set_attr "enabled" "<nBFP>,<nDFP>,<DSF>")])
6377 ;;- Conditional add/subtract instructions.
6381 ; add(di|si)cc instruction pattern(s).
6384 ; the following 4 patterns are used when the result of an add with
6385 ; carry is checked for an overflow condition
6387 ; op1 + op2 + c < op1
6389 ; alcr, alc, alcgr, alcg
6390 (define_insn "*add<mode>3_alc_carry1_cc"
6391 [(set (reg CC_REGNUM)
6393 (plus:GPR (plus:GPR (match_operand:GPR 3 "s390_alc_comparison" "")
6394 (match_operand:GPR 1 "nonimmediate_operand" "%0,0"))
6395 (match_operand:GPR 2 "general_operand" "d,T"))
6397 (set (match_operand:GPR 0 "register_operand" "=d,d")
6398 (plus:GPR (plus:GPR (match_dup 3) (match_dup 1)) (match_dup 2)))]
6399 "s390_match_ccmode (insn, CCL1mode) && TARGET_CPU_ZARCH"
6403 [(set_attr "op_type" "RRE,RXY")
6404 (set_attr "z196prop" "z196_alone,z196_alone")])
6406 ; alcr, alc, alcgr, alcg
6407 (define_insn "*add<mode>3_alc_carry1_cconly"
6408 [(set (reg CC_REGNUM)
6410 (plus:GPR (plus:GPR (match_operand:GPR 3 "s390_alc_comparison" "")
6411 (match_operand:GPR 1 "nonimmediate_operand" "%0,0"))
6412 (match_operand:GPR 2 "general_operand" "d,T"))
6414 (clobber (match_scratch:GPR 0 "=d,d"))]
6415 "s390_match_ccmode (insn, CCL1mode) && TARGET_CPU_ZARCH"
6419 [(set_attr "op_type" "RRE,RXY")
6420 (set_attr "z196prop" "z196_alone,z196_alone")])
6422 ; op1 + op2 + c < op2
6424 ; alcr, alc, alcgr, alcg
6425 (define_insn "*add<mode>3_alc_carry2_cc"
6426 [(set (reg CC_REGNUM)
6428 (plus:GPR (plus:GPR (match_operand:GPR 3 "s390_alc_comparison" "")
6429 (match_operand:GPR 1 "nonimmediate_operand" "%0,0"))
6430 (match_operand:GPR 2 "general_operand" "d,T"))
6432 (set (match_operand:GPR 0 "register_operand" "=d,d")
6433 (plus:GPR (plus:GPR (match_dup 3) (match_dup 1)) (match_dup 2)))]
6434 "s390_match_ccmode (insn, CCL1mode) && TARGET_CPU_ZARCH"
6438 [(set_attr "op_type" "RRE,RXY")])
6440 ; alcr, alc, alcgr, alcg
6441 (define_insn "*add<mode>3_alc_carry2_cconly"
6442 [(set (reg CC_REGNUM)
6444 (plus:GPR (plus:GPR (match_operand:GPR 3 "s390_alc_comparison" "")
6445 (match_operand:GPR 1 "nonimmediate_operand" "%0,0"))
6446 (match_operand:GPR 2 "general_operand" "d,T"))
6448 (clobber (match_scratch:GPR 0 "=d,d"))]
6449 "s390_match_ccmode (insn, CCL1mode) && TARGET_CPU_ZARCH"
6453 [(set_attr "op_type" "RRE,RXY")])
6455 ; alcr, alc, alcgr, alcg
6456 (define_insn "*add<mode>3_alc_cc"
6457 [(set (reg CC_REGNUM)
6459 (plus:GPR (plus:GPR (match_operand:GPR 3 "s390_alc_comparison" "")
6460 (match_operand:GPR 1 "nonimmediate_operand" "%0,0"))
6461 (match_operand:GPR 2 "general_operand" "d,T"))
6463 (set (match_operand:GPR 0 "register_operand" "=d,d")
6464 (plus:GPR (plus:GPR (match_dup 3) (match_dup 1)) (match_dup 2)))]
6465 "s390_match_ccmode (insn, CCLmode) && TARGET_CPU_ZARCH"
6469 [(set_attr "op_type" "RRE,RXY")])
6471 ; alcr, alc, alcgr, alcg
6472 (define_insn "*add<mode>3_alc"
6473 [(set (match_operand:GPR 0 "register_operand" "=d,d")
6474 (plus:GPR (plus:GPR (match_operand:GPR 3 "s390_alc_comparison" "")
6475 (match_operand:GPR 1 "nonimmediate_operand" "%0,0"))
6476 (match_operand:GPR 2 "general_operand" "d,T")))
6477 (clobber (reg:CC CC_REGNUM))]
6482 [(set_attr "op_type" "RRE,RXY")])
6484 ; slbr, slb, slbgr, slbg
6485 (define_insn "*sub<mode>3_slb_cc"
6486 [(set (reg CC_REGNUM)
6488 (minus:GPR (minus:GPR (match_operand:GPR 1 "nonimmediate_operand" "0,0")
6489 (match_operand:GPR 2 "general_operand" "d,T"))
6490 (match_operand:GPR 3 "s390_slb_comparison" ""))
6492 (set (match_operand:GPR 0 "register_operand" "=d,d")
6493 (minus:GPR (minus:GPR (match_dup 1) (match_dup 2)) (match_dup 3)))]
6494 "s390_match_ccmode (insn, CCLmode) && TARGET_CPU_ZARCH"
6498 [(set_attr "op_type" "RRE,RXY")
6499 (set_attr "z10prop" "z10_c,*")])
6501 ; slbr, slb, slbgr, slbg
6502 (define_insn "*sub<mode>3_slb"
6503 [(set (match_operand:GPR 0 "register_operand" "=d,d")
6504 (minus:GPR (minus:GPR (match_operand:GPR 1 "nonimmediate_operand" "0,0")
6505 (match_operand:GPR 2 "general_operand" "d,T"))
6506 (match_operand:GPR 3 "s390_slb_comparison" "")))
6507 (clobber (reg:CC CC_REGNUM))]
6512 [(set_attr "op_type" "RRE,RXY")
6513 (set_attr "z10prop" "z10_c,*")])
6515 (define_expand "add<mode>cc"
6516 [(match_operand:GPR 0 "register_operand" "")
6517 (match_operand 1 "comparison_operator" "")
6518 (match_operand:GPR 2 "register_operand" "")
6519 (match_operand:GPR 3 "const_int_operand" "")]
6521 "if (!s390_expand_addcc (GET_CODE (operands[1]),
6522 XEXP (operands[1], 0), XEXP (operands[1], 1),
6523 operands[0], operands[2],
6524 operands[3])) FAIL; DONE;")
6527 ; scond instruction pattern(s).
6530 (define_insn_and_split "*scond<mode>"
6531 [(set (match_operand:GPR 0 "register_operand" "=&d")
6532 (match_operand:GPR 1 "s390_alc_comparison" ""))
6533 (clobber (reg:CC CC_REGNUM))]
6536 "&& reload_completed"
6537 [(set (match_dup 0) (const_int 0))
6539 [(set (match_dup 0) (plus:GPR (plus:GPR (match_dup 1) (match_dup 0))
6541 (clobber (reg:CC CC_REGNUM))])]
6544 (define_insn_and_split "*scond<mode>_neg"
6545 [(set (match_operand:GPR 0 "register_operand" "=&d")
6546 (match_operand:GPR 1 "s390_slb_comparison" ""))
6547 (clobber (reg:CC CC_REGNUM))]
6550 "&& reload_completed"
6551 [(set (match_dup 0) (const_int 0))
6553 [(set (match_dup 0) (minus:GPR (minus:GPR (match_dup 0) (match_dup 0))
6555 (clobber (reg:CC CC_REGNUM))])
6557 [(set (match_dup 0) (neg:GPR (match_dup 0)))
6558 (clobber (reg:CC CC_REGNUM))])]
6562 (define_expand "cstore<mode>4"
6563 [(set (match_operand:SI 0 "register_operand" "")
6564 (match_operator:SI 1 "s390_scond_operator"
6565 [(match_operand:GPR 2 "register_operand" "")
6566 (match_operand:GPR 3 "general_operand" "")]))]
6568 "if (!s390_expand_addcc (GET_CODE (operands[1]), operands[2], operands[3],
6569 operands[0], const0_rtx, const1_rtx)) FAIL; DONE;")
6571 (define_expand "cstorecc4"
6573 [(set (match_operand:SI 0 "register_operand" "")
6574 (match_operator:SI 1 "s390_eqne_operator"
6575 [(match_operand 2 "cc_reg_operand")
6576 (match_operand 3 "const0_operand")]))
6577 (clobber (reg:CC CC_REGNUM))])]
6579 "machine_mode mode = GET_MODE (operands[2]);
6584 if (GET_CODE (operands[1]) == NE)
6585 cond = gen_rtx_NE (VOIDmode, operands[2], const0_rtx);
6587 cond = gen_rtx_EQ (VOIDmode, operands[2], const0_rtx);
6588 ite = gen_rtx_IF_THEN_ELSE (SImode, cond, const1_rtx, const0_rtx);
6589 emit_insn (gen_rtx_SET (operands[0], ite));
6593 if (mode != CCZ1mode)
6595 emit_insn (gen_sne (operands[0], operands[2]));
6596 if (GET_CODE (operands[1]) == EQ)
6597 emit_insn (gen_xorsi3 (operands[0], operands[0], const1_rtx));
6601 (define_insn_and_split "sne"
6602 [(set (match_operand:SI 0 "register_operand" "=d")
6603 (ne:SI (match_operand:CCZ1 1 "register_operand" "0")
6605 (clobber (reg:CC CC_REGNUM))]
6610 [(set (match_dup 0) (ashiftrt:SI (match_dup 0) (const_int 28)))
6611 (clobber (reg:CC CC_REGNUM))])])
6615 ;; - Conditional move instructions (introduced with z196)
6618 (define_expand "mov<mode>cc"
6619 [(set (match_operand:GPR 0 "nonimmediate_operand" "")
6620 (if_then_else:GPR (match_operand 1 "comparison_operator" "")
6621 (match_operand:GPR 2 "nonimmediate_operand" "")
6622 (match_operand:GPR 3 "nonimmediate_operand" "")))]
6625 /* Emit the comparison insn in case we do not already have a comparison result. */
6626 if (!s390_comparison (operands[1], VOIDmode))
6627 operands[1] = s390_emit_compare (GET_CODE (operands[1]),
6628 XEXP (operands[1], 0),
6629 XEXP (operands[1], 1));
6632 ; locr, loc, stoc, locgr, locg, stocg, lochi, locghi
6633 (define_insn "*mov<mode>cc"
6634 [(set (match_operand:GPR 0 "nonimmediate_operand" "=d,d,d,d,d,d,S,S")
6636 (match_operator 1 "s390_comparison"
6637 [(match_operand 2 "cc_reg_operand" " c,c,c,c,c,c,c,c")
6638 (match_operand 5 "const_int_operand" "")])
6639 (match_operand:GPR 3 "loc_operand" " d,0,S,0,K,0,d,0")
6640 (match_operand:GPR 4 "loc_operand" " 0,d,0,S,0,K,0,d")))]
6651 [(set_attr "op_type" "RRF,RRF,RSY,RSY,RIE,RIE,RSY,RSY")
6652 (set_attr "cpu_facility" "*,*,*,*,z13,z13,*,*")])
6655 ;;- Multiply instructions.
6659 ; muldi3 instruction pattern(s).
6662 (define_expand "muldi3"
6664 [(set (match_operand:DI 0 "register_operand")
6665 (mult:DI (match_operand:DI 1 "nonimmediate_operand")
6666 (match_operand:DI 2 "general_operand")))
6667 (clobber (reg:CC CC_REGNUM))])]
6670 (define_insn "*muldi3_sign"
6671 [(set (match_operand:DI 0 "register_operand" "=d,d")
6672 (mult:DI (sign_extend:DI (match_operand:SI 2 "general_operand" "d,T"))
6673 (match_operand:DI 1 "register_operand" "0,0")))]
6678 [(set_attr "op_type" "RRE,RXY")
6679 (set_attr "type" "imuldi")])
6681 (define_insn "*muldi3"
6682 [(set (match_operand:DI 0 "register_operand" "=d,d,d,d,d")
6683 (mult:DI (match_operand:DI 1 "nonimmediate_operand" "%0,d,0,0,0")
6684 (match_operand:DI 2 "general_operand" "d,d,K,T,Os")))
6685 (clobber (match_scratch:CC 3 "=X,c,X,X,X"))]
6693 [(set_attr "op_type" "RRE,RRF,RI,RXY,RIL")
6694 (set_attr "type" "imuldi")
6695 (set_attr "cpu_facility" "*,arch12,*,*,z10")])
6697 (define_insn "mulditi3"
6698 [(set (match_operand:TI 0 "register_operand" "=d,d")
6699 (mult:TI (sign_extend:TI
6700 (match_operand:DI 1 "register_operand" "%d,0"))
6702 (match_operand:DI 2 "nonimmediate_operand" " d,T"))))]
6707 [(set_attr "op_type" "RRF,RXY")])
6709 ; Combine likes op1 and op2 to be swapped sometimes.
6710 (define_insn "mulditi3_2"
6711 [(set (match_operand:TI 0 "register_operand" "=d,d")
6712 (mult:TI (sign_extend:TI
6713 (match_operand:DI 1 "nonimmediate_operand" "%d,T"))
6715 (match_operand:DI 2 "register_operand" " d,0"))))]
6720 [(set_attr "op_type" "RRF,RXY")])
6722 (define_insn "*muldi3_sign"
6723 [(set (match_operand:DI 0 "register_operand" "=d")
6724 (mult:DI (sign_extend:DI (match_operand:HI 2 "memory_operand" "T"))
6725 (match_operand:DI 1 "register_operand" "0")))]
6728 [(set_attr "op_type" "RXY")])
6732 ; mulsi3 instruction pattern(s).
6735 (define_expand "mulsi3"
6737 [(set (match_operand:SI 0 "register_operand" "=d,d,d,d,d,d")
6738 (mult:SI (match_operand:SI 1 "nonimmediate_operand" "%0,d,0,0,0,0")
6739 (match_operand:SI 2 "general_operand" "d,d,K,R,T,Os")))
6740 (clobber (reg:CC CC_REGNUM))])]
6743 (define_insn "*mulsi3_sign"
6744 [(set (match_operand:SI 0 "register_operand" "=d,d")
6745 (mult:SI (sign_extend:SI (match_operand:HI 2 "memory_operand" "R,T"))
6746 (match_operand:SI 1 "register_operand" "0,0")))]
6751 [(set_attr "op_type" "RX,RXY")
6752 (set_attr "type" "imulhi")
6753 (set_attr "cpu_facility" "*,z10")])
6755 (define_insn "*mulsi3"
6756 [(set (match_operand:SI 0 "register_operand" "=d,d,d,d,d,d")
6757 (mult:SI (match_operand:SI 1 "nonimmediate_operand" "%0,d,0,0,0,0")
6758 (match_operand:SI 2 "general_operand" "d,d,K,R,T,Os")))
6759 (clobber (match_scratch:CC 3 "=X,c,X,X,X,X"))]
6768 [(set_attr "op_type" "RRE,RRF,RI,RX,RXY,RIL")
6769 (set_attr "type" "imulsi,*,imulhi,imulsi,imulsi,imulsi")
6770 (set_attr "cpu_facility" "*,arch12,*,*,longdisp,z10")])
6773 ; mulsidi3 instruction pattern(s).
6776 (define_insn "mulsidi3"
6777 [(set (match_operand:DI 0 "register_operand" "=d,d,d")
6778 (mult:DI (sign_extend:DI
6779 (match_operand:SI 1 "register_operand" "%0,0,0"))
6781 (match_operand:SI 2 "nonimmediate_operand" "d,R,T"))))]
6787 [(set_attr "op_type" "RR,RX,RXY")
6788 (set_attr "type" "imulsi")
6789 (set_attr "cpu_facility" "*,*,z10")])
6792 ; umul instruction pattern(s).
6795 ; mlr, ml, mlgr, mlg
6796 (define_insn "umul<dwh><mode>3"
6797 [(set (match_operand:DW 0 "register_operand" "=d,d")
6798 (mult:DW (zero_extend:DW
6799 (match_operand:<DWH> 1 "register_operand" "%0,0"))
6801 (match_operand:<DWH> 2 "nonimmediate_operand" " d,T"))))]
6806 [(set_attr "op_type" "RRE,RXY")
6807 (set_attr "type" "imul<dwh>")])
6810 ; mul(tf|df|sf|td|dd)3 instruction pattern(s).
6813 ; mxbr, mdbr, meebr, mxb, mxb, meeb, mdtr, mxtr
6814 (define_insn "mul<mode>3"
6815 [(set (match_operand:FP 0 "register_operand" "=f,f,f,v,v")
6816 (mult:FP (match_operand:FP 1 "nonimmediate_operand" "%f,0,0,v,v")
6817 (match_operand:FP 2 "general_operand" "f,f,R,v,v")))]
6825 [(set_attr "op_type" "RRF,RRE,RXE,VRR,VRR")
6826 (set_attr "type" "fmul<mode>")
6827 (set_attr "cpu_facility" "*,*,*,vx,vxe")
6828 (set_attr "enabled" "<nBFP>,<nDFP>,<DSF>,<DF>,<SF>")])
6830 ; madbr, maebr, maxb, madb, maeb
6831 (define_insn "fma<mode>4"
6832 [(set (match_operand:DSF 0 "register_operand" "=f,f,v,v")
6833 (fma:DSF (match_operand:DSF 1 "nonimmediate_operand" "%f,f,v,v")
6834 (match_operand:DSF 2 "nonimmediate_operand" "f,R,v,v")
6835 (match_operand:DSF 3 "register_operand" "0,0,v,v")))]
6840 wfmadb\t%v0,%v1,%v2,%v3
6841 wfmasb\t%v0,%v1,%v2,%v3"
6842 [(set_attr "op_type" "RRE,RXE,VRR,VRR")
6843 (set_attr "type" "fmadd<mode>")
6844 (set_attr "cpu_facility" "*,*,vx,vxe")
6845 (set_attr "enabled" "*,*,<DF>,<SF>")])
6847 ; msxbr, msdbr, msebr, msxb, msdb, mseb
6848 (define_insn "fms<mode>4"
6849 [(set (match_operand:DSF 0 "register_operand" "=f,f,v,v")
6850 (fma:DSF (match_operand:DSF 1 "nonimmediate_operand" "%f,f,v,v")
6851 (match_operand:DSF 2 "nonimmediate_operand" "f,R,v,v")
6852 (neg:DSF (match_operand:DSF 3 "register_operand" "0,0,v,v"))))]
6857 wfmsdb\t%v0,%v1,%v2,%v3
6858 wfmssb\t%v0,%v1,%v2,%v3"
6859 [(set_attr "op_type" "RRE,RXE,VRR,VRR")
6860 (set_attr "type" "fmadd<mode>")
6861 (set_attr "cpu_facility" "*,*,vx,vxe")
6862 (set_attr "enabled" "*,*,<DF>,<SF>")])
6865 ;;- Divide and modulo instructions.
6869 ; divmoddi4 instruction pattern(s).
6872 (define_expand "divmoddi4"
6873 [(parallel [(set (match_operand:DI 0 "general_operand" "")
6874 (div:DI (match_operand:DI 1 "register_operand" "")
6875 (match_operand:DI 2 "general_operand" "")))
6876 (set (match_operand:DI 3 "general_operand" "")
6877 (mod:DI (match_dup 1) (match_dup 2)))])
6878 (clobber (match_dup 4))]
6881 rtx div_equal, mod_equal;
6884 div_equal = gen_rtx_DIV (DImode, operands[1], operands[2]);
6885 mod_equal = gen_rtx_MOD (DImode, operands[1], operands[2]);
6887 operands[4] = gen_reg_rtx(TImode);
6888 emit_insn (gen_divmodtidi3 (operands[4], operands[1], operands[2]));
6890 insn = emit_move_insn (operands[0], gen_lowpart (DImode, operands[4]));
6891 set_unique_reg_note (insn, REG_EQUAL, div_equal);
6893 insn = emit_move_insn (operands[3], gen_highpart (DImode, operands[4]));
6894 set_unique_reg_note (insn, REG_EQUAL, mod_equal);
6899 (define_insn "divmodtidi3"
6900 [(set (match_operand:TI 0 "register_operand" "=d,d")
6904 (mod:DI (match_operand:DI 1 "register_operand" "0,0")
6905 (match_operand:DI 2 "general_operand" "d,T")))
6907 (zero_extend:TI (div:DI (match_dup 1) (match_dup 2)))))]
6912 [(set_attr "op_type" "RRE,RXY")
6913 (set_attr "type" "idiv")])
6915 (define_insn "divmodtisi3"
6916 [(set (match_operand:TI 0 "register_operand" "=d,d")
6920 (mod:DI (match_operand:DI 1 "register_operand" "0,0")
6922 (match_operand:SI 2 "nonimmediate_operand" "d,T"))))
6925 (div:DI (match_dup 1) (sign_extend:DI (match_dup 2))))))]
6930 [(set_attr "op_type" "RRE,RXY")
6931 (set_attr "type" "idiv")])
6934 ; udivmoddi4 instruction pattern(s).
6937 (define_expand "udivmoddi4"
6938 [(parallel [(set (match_operand:DI 0 "general_operand" "")
6939 (udiv:DI (match_operand:DI 1 "general_operand" "")
6940 (match_operand:DI 2 "nonimmediate_operand" "")))
6941 (set (match_operand:DI 3 "general_operand" "")
6942 (umod:DI (match_dup 1) (match_dup 2)))])
6943 (clobber (match_dup 4))]
6946 rtx div_equal, mod_equal, equal;
6949 div_equal = gen_rtx_UDIV (DImode, operands[1], operands[2]);
6950 mod_equal = gen_rtx_UMOD (DImode, operands[1], operands[2]);
6951 equal = gen_rtx_IOR (TImode,
6952 gen_rtx_ASHIFT (TImode,
6953 gen_rtx_ZERO_EXTEND (TImode, mod_equal),
6955 gen_rtx_ZERO_EXTEND (TImode, div_equal));
6957 operands[4] = gen_reg_rtx(TImode);
6958 emit_clobber (operands[4]);
6959 emit_move_insn (gen_lowpart (DImode, operands[4]), operands[1]);
6960 emit_move_insn (gen_highpart (DImode, operands[4]), const0_rtx);
6962 insn = emit_insn (gen_udivmodtidi3 (operands[4], operands[4], operands[2]));
6963 set_unique_reg_note (insn, REG_EQUAL, equal);
6965 insn = emit_move_insn (operands[0], gen_lowpart (DImode, operands[4]));
6966 set_unique_reg_note (insn, REG_EQUAL, div_equal);
6968 insn = emit_move_insn (operands[3], gen_highpart (DImode, operands[4]));
6969 set_unique_reg_note (insn, REG_EQUAL, mod_equal);
6974 (define_insn "udivmodtidi3"
6975 [(set (match_operand:TI 0 "register_operand" "=d,d")
6980 (umod:TI (match_operand:TI 1 "register_operand" "0,0")
6982 (match_operand:DI 2 "nonimmediate_operand" "d,T")))))
6986 (udiv:TI (match_dup 1) (zero_extend:TI (match_dup 2)))))))]
6991 [(set_attr "op_type" "RRE,RXY")
6992 (set_attr "type" "idiv")])
6995 ; divmodsi4 instruction pattern(s).
6998 (define_expand "divmodsi4"
6999 [(parallel [(set (match_operand:SI 0 "general_operand" "")
7000 (div:SI (match_operand:SI 1 "general_operand" "")
7001 (match_operand:SI 2 "nonimmediate_operand" "")))
7002 (set (match_operand:SI 3 "general_operand" "")
7003 (mod:SI (match_dup 1) (match_dup 2)))])
7004 (clobber (match_dup 4))]
7007 rtx div_equal, mod_equal, equal;
7010 div_equal = gen_rtx_DIV (SImode, operands[1], operands[2]);
7011 mod_equal = gen_rtx_MOD (SImode, operands[1], operands[2]);
7012 equal = gen_rtx_IOR (DImode,
7013 gen_rtx_ASHIFT (DImode,
7014 gen_rtx_ZERO_EXTEND (DImode, mod_equal),
7016 gen_rtx_ZERO_EXTEND (DImode, div_equal));
7018 operands[4] = gen_reg_rtx(DImode);
7019 emit_insn (gen_extendsidi2 (operands[4], operands[1]));
7021 insn = emit_insn (gen_divmoddisi3 (operands[4], operands[4], operands[2]));
7022 set_unique_reg_note (insn, REG_EQUAL, equal);
7024 insn = emit_move_insn (operands[0], gen_lowpart (SImode, operands[4]));
7025 set_unique_reg_note (insn, REG_EQUAL, div_equal);
7027 insn = emit_move_insn (operands[3], gen_highpart (SImode, operands[4]));
7028 set_unique_reg_note (insn, REG_EQUAL, mod_equal);
7033 (define_insn "divmoddisi3"
7034 [(set (match_operand:DI 0 "register_operand" "=d,d")
7039 (mod:DI (match_operand:DI 1 "register_operand" "0,0")
7041 (match_operand:SI 2 "nonimmediate_operand" "d,R")))))
7045 (div:DI (match_dup 1) (sign_extend:DI (match_dup 2)))))))]
7050 [(set_attr "op_type" "RR,RX")
7051 (set_attr "type" "idiv")])
7054 ; udivsi3 and umodsi3 instruction pattern(s).
7057 (define_expand "udivmodsi4"
7058 [(parallel [(set (match_operand:SI 0 "general_operand" "")
7059 (udiv:SI (match_operand:SI 1 "general_operand" "")
7060 (match_operand:SI 2 "nonimmediate_operand" "")))
7061 (set (match_operand:SI 3 "general_operand" "")
7062 (umod:SI (match_dup 1) (match_dup 2)))])
7063 (clobber (match_dup 4))]
7064 "!TARGET_ZARCH && TARGET_CPU_ZARCH"
7066 rtx div_equal, mod_equal, equal;
7069 div_equal = gen_rtx_UDIV (SImode, operands[1], operands[2]);
7070 mod_equal = gen_rtx_UMOD (SImode, operands[1], operands[2]);
7071 equal = gen_rtx_IOR (DImode,
7072 gen_rtx_ASHIFT (DImode,
7073 gen_rtx_ZERO_EXTEND (DImode, mod_equal),
7075 gen_rtx_ZERO_EXTEND (DImode, div_equal));
7077 operands[4] = gen_reg_rtx(DImode);
7078 emit_clobber (operands[4]);
7079 emit_move_insn (gen_lowpart (SImode, operands[4]), operands[1]);
7080 emit_move_insn (gen_highpart (SImode, operands[4]), const0_rtx);
7082 insn = emit_insn (gen_udivmoddisi3 (operands[4], operands[4], operands[2]));
7083 set_unique_reg_note (insn, REG_EQUAL, equal);
7085 insn = emit_move_insn (operands[0], gen_lowpart (SImode, operands[4]));
7086 set_unique_reg_note (insn, REG_EQUAL, div_equal);
7088 insn = emit_move_insn (operands[3], gen_highpart (SImode, operands[4]));
7089 set_unique_reg_note (insn, REG_EQUAL, mod_equal);
7094 (define_insn "udivmoddisi3"
7095 [(set (match_operand:DI 0 "register_operand" "=d,d")
7100 (umod:DI (match_operand:DI 1 "register_operand" "0,0")
7102 (match_operand:SI 2 "nonimmediate_operand" "d,T")))))
7106 (udiv:DI (match_dup 1) (zero_extend:DI (match_dup 2)))))))]
7107 "!TARGET_ZARCH && TARGET_CPU_ZARCH"
7111 [(set_attr "op_type" "RRE,RXY")
7112 (set_attr "type" "idiv")])
7114 (define_expand "udivsi3"
7115 [(set (match_operand:SI 0 "register_operand" "=d")
7116 (udiv:SI (match_operand:SI 1 "general_operand" "")
7117 (match_operand:SI 2 "general_operand" "")))
7118 (clobber (match_dup 3))]
7119 "!TARGET_ZARCH && !TARGET_CPU_ZARCH"
7121 rtx udiv_equal, umod_equal, equal;
7124 udiv_equal = gen_rtx_UDIV (SImode, operands[1], operands[2]);
7125 umod_equal = gen_rtx_UMOD (SImode, operands[1], operands[2]);
7126 equal = gen_rtx_IOR (DImode,
7127 gen_rtx_ASHIFT (DImode,
7128 gen_rtx_ZERO_EXTEND (DImode, umod_equal),
7130 gen_rtx_ZERO_EXTEND (DImode, udiv_equal));
7132 operands[3] = gen_reg_rtx (DImode);
7134 if (CONSTANT_P (operands[2]))
7136 if (GET_CODE (operands[2]) == CONST_INT && INTVAL (operands[2]) < 0)
7138 rtx_code_label *label1 = gen_label_rtx ();
7140 operands[1] = make_safe_from (operands[1], operands[0]);
7141 emit_move_insn (operands[0], const0_rtx);
7142 emit_cmp_and_jump_insns (operands[1], operands[2], LT, NULL_RTX,
7144 emit_move_insn (operands[0], const1_rtx);
7145 emit_label (label1);
7149 operands[2] = force_reg (SImode, operands[2]);
7150 operands[2] = make_safe_from (operands[2], operands[0]);
7152 emit_insn (gen_zero_extendsidi2 (operands[3], operands[1]));
7153 insn = emit_insn (gen_divmoddisi3 (operands[3], operands[3],
7155 set_unique_reg_note (insn, REG_EQUAL, equal);
7157 insn = emit_move_insn (operands[0],
7158 gen_lowpart (SImode, operands[3]));
7159 set_unique_reg_note (insn, REG_EQUAL, udiv_equal);
7164 rtx_code_label *label1 = gen_label_rtx ();
7165 rtx_code_label *label2 = gen_label_rtx ();
7166 rtx_code_label *label3 = gen_label_rtx ();
7168 operands[1] = force_reg (SImode, operands[1]);
7169 operands[1] = make_safe_from (operands[1], operands[0]);
7170 operands[2] = force_reg (SImode, operands[2]);
7171 operands[2] = make_safe_from (operands[2], operands[0]);
7173 emit_move_insn (operands[0], const0_rtx);
7174 emit_cmp_and_jump_insns (operands[2], operands[1], GT, NULL_RTX,
7176 emit_cmp_and_jump_insns (operands[2], const0_rtx, LT, NULL_RTX,
7178 emit_cmp_and_jump_insns (operands[2], const1_rtx, EQ, NULL_RTX,
7180 emit_insn (gen_zero_extendsidi2 (operands[3], operands[1]));
7181 insn = emit_insn (gen_divmoddisi3 (operands[3], operands[3],
7183 set_unique_reg_note (insn, REG_EQUAL, equal);
7185 insn = emit_move_insn (operands[0],
7186 gen_lowpart (SImode, operands[3]));
7187 set_unique_reg_note (insn, REG_EQUAL, udiv_equal);
7190 emit_label (label1);
7191 emit_move_insn (operands[0], operands[1]);
7193 emit_label (label2);
7194 emit_move_insn (operands[0], const1_rtx);
7195 emit_label (label3);
7197 emit_move_insn (operands[0], operands[0]);
7201 (define_expand "umodsi3"
7202 [(set (match_operand:SI 0 "register_operand" "=d")
7203 (umod:SI (match_operand:SI 1 "nonimmediate_operand" "")
7204 (match_operand:SI 2 "nonimmediate_operand" "")))
7205 (clobber (match_dup 3))]
7206 "!TARGET_ZARCH && !TARGET_CPU_ZARCH"
7208 rtx udiv_equal, umod_equal, equal;
7211 udiv_equal = gen_rtx_UDIV (SImode, operands[1], operands[2]);
7212 umod_equal = gen_rtx_UMOD (SImode, operands[1], operands[2]);
7213 equal = gen_rtx_IOR (DImode,
7214 gen_rtx_ASHIFT (DImode,
7215 gen_rtx_ZERO_EXTEND (DImode, umod_equal),
7217 gen_rtx_ZERO_EXTEND (DImode, udiv_equal));
7219 operands[3] = gen_reg_rtx (DImode);
7221 if (CONSTANT_P (operands[2]))
7223 if (GET_CODE (operands[2]) == CONST_INT && INTVAL (operands[2]) <= 0)
7225 rtx_code_label *label1 = gen_label_rtx ();
7227 operands[1] = make_safe_from (operands[1], operands[0]);
7228 emit_move_insn (operands[0], operands[1]);
7229 emit_cmp_and_jump_insns (operands[0], operands[2], LT, NULL_RTX,
7231 emit_insn (gen_abssi2 (operands[0], operands[2]));
7232 emit_insn (gen_addsi3 (operands[0], operands[0], operands[1]));
7233 emit_label (label1);
7237 operands[2] = force_reg (SImode, operands[2]);
7238 operands[2] = make_safe_from (operands[2], operands[0]);
7240 emit_insn (gen_zero_extendsidi2 (operands[3], operands[1]));
7241 insn = emit_insn (gen_divmoddisi3 (operands[3], operands[3],
7243 set_unique_reg_note (insn, REG_EQUAL, equal);
7245 insn = emit_move_insn (operands[0],
7246 gen_highpart (SImode, operands[3]));
7247 set_unique_reg_note (insn, REG_EQUAL, umod_equal);
7252 rtx_code_label *label1 = gen_label_rtx ();
7253 rtx_code_label *label2 = gen_label_rtx ();
7254 rtx_code_label *label3 = gen_label_rtx ();
7256 operands[1] = force_reg (SImode, operands[1]);
7257 operands[1] = make_safe_from (operands[1], operands[0]);
7258 operands[2] = force_reg (SImode, operands[2]);
7259 operands[2] = make_safe_from (operands[2], operands[0]);
7261 emit_move_insn(operands[0], operands[1]);
7262 emit_cmp_and_jump_insns (operands[2], operands[1], GT, NULL_RTX,
7264 emit_cmp_and_jump_insns (operands[2], const0_rtx, LT, NULL_RTX,
7266 emit_cmp_and_jump_insns (operands[2], const1_rtx, EQ, NULL_RTX,
7268 emit_insn (gen_zero_extendsidi2 (operands[3], operands[1]));
7269 insn = emit_insn (gen_divmoddisi3 (operands[3], operands[3],
7271 set_unique_reg_note (insn, REG_EQUAL, equal);
7273 insn = emit_move_insn (operands[0],
7274 gen_highpart (SImode, operands[3]));
7275 set_unique_reg_note (insn, REG_EQUAL, umod_equal);
7278 emit_label (label1);
7279 emit_move_insn (operands[0], const0_rtx);
7281 emit_label (label2);
7282 emit_insn (gen_subsi3 (operands[0], operands[0], operands[2]));
7283 emit_label (label3);
7289 ; div(df|sf)3 instruction pattern(s).
7292 ; dxbr, ddbr, debr, dxb, ddb, deb, ddtr, dxtr
7293 (define_insn "div<mode>3"
7294 [(set (match_operand:FP 0 "register_operand" "=f,f,f,v,v")
7295 (div:FP (match_operand:FP 1 "register_operand" "f,0,0,v,v")
7296 (match_operand:FP 2 "general_operand" "f,f,R,v,v")))]
7304 [(set_attr "op_type" "RRF,RRE,RXE,VRR,VRR")
7305 (set_attr "type" "fdiv<mode>")
7306 (set_attr "cpu_facility" "*,*,*,vx,vxe")
7307 (set_attr "enabled" "<nBFP>,<nDFP>,<DSF>,<DF>,<SF>")])
7311 ;;- And instructions.
7314 (define_expand "and<mode>3"
7315 [(set (match_operand:INT 0 "nonimmediate_operand" "")
7316 (and:INT (match_operand:INT 1 "nonimmediate_operand" "")
7317 (match_operand:INT 2 "general_operand" "")))
7318 (clobber (reg:CC CC_REGNUM))]
7320 "s390_expand_logical_operator (AND, <MODE>mode, operands); DONE;")
7323 ; anddi3 instruction pattern(s).
7326 (define_insn "*anddi3_cc"
7327 [(set (reg CC_REGNUM)
7329 (and:DI (match_operand:DI 1 "nonimmediate_operand" "%0,d,0, d")
7330 (match_operand:DI 2 "general_operand" " d,d,T,NxxDw"))
7332 (set (match_operand:DI 0 "register_operand" "=d,d,d, d")
7333 (and:DI (match_dup 1) (match_dup 2)))]
7334 "TARGET_ZARCH && s390_match_ccmode(insn, CCTmode)"
7339 risbg\t%0,%1,%s2,128+%e2,0"
7340 [(set_attr "op_type" "RRE,RRF,RXY,RIE")
7341 (set_attr "cpu_facility" "*,z196,*,z10")
7342 (set_attr "z10prop" "z10_super_E1,*,z10_super_E1,z10_super_E1")])
7344 (define_insn "*anddi3_cconly"
7345 [(set (reg CC_REGNUM)
7347 (and:DI (match_operand:DI 1 "nonimmediate_operand" "%0,d,0, d")
7348 (match_operand:DI 2 "general_operand" " d,d,T,NxxDw"))
7350 (clobber (match_scratch:DI 0 "=d,d,d, d"))]
7352 && s390_match_ccmode(insn, CCTmode)
7353 /* Do not steal TM patterns. */
7354 && s390_single_part (operands[2], DImode, HImode, 0) < 0"
7359 risbg\t%0,%1,%s2,128+%e2,0"
7360 [(set_attr "op_type" "RRE,RRF,RXY,RIE")
7361 (set_attr "cpu_facility" "*,z196,*,z10")
7362 (set_attr "z10prop" "z10_super_E1,*,z10_super_E1,z10_super_E1")])
7364 (define_insn "*anddi3"
7365 [(set (match_operand:DI 0 "nonimmediate_operand"
7366 "=d,d, d, d, d, d, d, d,d,d,d, d, AQ,Q")
7368 (match_operand:DI 1 "nonimmediate_operand"
7369 "%d,o, 0, 0, 0, 0, 0, 0,0,d,0, d, 0,0")
7370 (match_operand:DI 2 "general_operand"
7371 "M, M,N0HDF,N1HDF,N2HDF,N3HDF,N0SDF,N1SDF,d,d,T,NxxDw,NxQDF,Q")))
7372 (clobber (reg:CC CC_REGNUM))]
7373 "TARGET_ZARCH && s390_logical_operator_ok_p (operands)"
7386 risbg\t%0,%1,%s2,128+%e2,0
7389 [(set_attr "op_type" "RRE,RXE,RI,RI,RI,RI,RIL,RIL,RRE,RRF,RXY,RIE,SI,SS")
7390 (set_attr "cpu_facility" "*,*,*,*,*,*,extimm,extimm,*,z196,*,z10,*,*")
7391 (set_attr "z10prop" "*,
7407 [(set (match_operand:DI 0 "s_operand" "")
7408 (and:DI (match_dup 0) (match_operand:DI 1 "immediate_operand" "")))
7409 (clobber (reg:CC CC_REGNUM))]
7412 [(set (match_dup 0) (and:QI (match_dup 0) (match_dup 1)))
7413 (clobber (reg:CC CC_REGNUM))])]
7414 "s390_narrow_logical_operator (AND, &operands[0], &operands[1]);")
7416 ;; These two are what combine generates for (ashift (zero_extract)).
7417 (define_insn "*extzv_<mode>_srl<clobbercc_or_nocc>"
7418 [(set (match_operand:GPR 0 "register_operand" "=d")
7419 (and:GPR (lshiftrt:GPR
7420 (match_operand:GPR 1 "register_operand" "d")
7421 (match_operand:GPR 2 "nonzero_shift_count_operand" ""))
7422 (match_operand:GPR 3 "contiguous_bitmask_nowrap_operand" "")))]
7423 "<z10_or_zEC12_cond>
7424 /* Note that even for the SImode pattern, the rotate is always DImode. */
7425 && s390_extzv_shift_ok (<bitsize>, -INTVAL (operands[2]),
7426 INTVAL (operands[3]))"
7427 "<risbg_n>\t%0,%1,%<bfstart>3,128+%<bfend>3,64-%2"
7428 [(set_attr "op_type" "RIE")
7429 (set_attr "z10prop" "z10_super_E1")])
7431 (define_insn "*extzv_<mode>_sll<clobbercc_or_nocc>"
7432 [(set (match_operand:GPR 0 "register_operand" "=d")
7433 (and:GPR (ashift:GPR
7434 (match_operand:GPR 1 "register_operand" "d")
7435 (match_operand:GPR 2 "nonzero_shift_count_operand" ""))
7436 (match_operand:GPR 3 "contiguous_bitmask_nowrap_operand" "")))]
7437 "<z10_or_zEC12_cond>
7438 && s390_extzv_shift_ok (<bitsize>, INTVAL (operands[2]),
7439 INTVAL (operands[3]))"
7440 "<risbg_n>\t%0,%1,%<bfstart>3,128+%<bfend>3,%2"
7441 [(set_attr "op_type" "RIE")
7442 (set_attr "z10prop" "z10_super_E1")])
7446 ; andsi3 instruction pattern(s).
7449 (define_insn "*andsi3_cc"
7450 [(set (reg CC_REGNUM)
7453 (match_operand:SI 1 "nonimmediate_operand" "%0,0,d,0,0, d")
7454 (match_operand:SI 2 "general_operand" "Os,d,d,R,T,NxxSq"))
7456 (set (match_operand:SI 0 "register_operand" "=d,d,d,d,d, d")
7457 (and:SI (match_dup 1) (match_dup 2)))]
7458 "s390_match_ccmode(insn, CCTmode)"
7465 risbg\t%0,%1,%t2,128+%f2,0"
7466 [(set_attr "op_type" "RIL,RR,RRF,RX,RXY,RIE")
7467 (set_attr "cpu_facility" "*,*,z196,*,longdisp,z10")
7468 (set_attr "z10prop" "z10_super_E1,z10_super_E1,*,
7469 z10_super_E1,z10_super_E1,z10_super_E1")])
7471 (define_insn "*andsi3_cconly"
7472 [(set (reg CC_REGNUM)
7475 (match_operand:SI 1 "nonimmediate_operand" "%0,0,d,0,0, d")
7476 (match_operand:SI 2 "general_operand" "Os,d,d,R,T,NxxSq"))
7478 (clobber (match_scratch:SI 0 "=d,d,d,d,d, d"))]
7479 "s390_match_ccmode(insn, CCTmode)
7480 /* Do not steal TM patterns. */
7481 && s390_single_part (operands[2], SImode, HImode, 0) < 0"
7488 risbg\t%0,%1,%t2,128+%f2,0"
7489 [(set_attr "op_type" "RIL,RR,RRF,RX,RXY,RIE")
7490 (set_attr "cpu_facility" "*,*,z196,*,longdisp,z10")
7491 (set_attr "z10prop" "z10_super_E1,z10_super_E1,*,
7492 z10_super_E1,z10_super_E1,z10_super_E1")])
7494 (define_insn "*andsi3_zarch"
7495 [(set (match_operand:SI 0 "nonimmediate_operand"
7496 "=d,d, d, d, d,d,d,d,d, d, AQ,Q")
7497 (and:SI (match_operand:SI 1 "nonimmediate_operand"
7498 "%d,o, 0, 0, 0,0,d,0,0, d, 0,0")
7499 (match_operand:SI 2 "general_operand"
7500 " M,M,N0HSF,N1HSF,Os,d,d,R,T,NxxSw,NxQSF,Q")))
7501 (clobber (reg:CC CC_REGNUM))]
7502 "TARGET_ZARCH && s390_logical_operator_ok_p (operands)"
7513 risbg\t%0,%1,%t2,128+%f2,0
7516 [(set_attr "op_type" "RRE,RXE,RI,RI,RIL,RR,RRF,RX,RXY,RIE,SI,SS")
7517 (set_attr "cpu_facility" "*,*,*,*,*,*,z196,*,longdisp,z10,*,*")
7518 (set_attr "z10prop" "*,
7531 (define_insn "*andsi3_esa"
7532 [(set (match_operand:SI 0 "nonimmediate_operand" "=d,d, AQ,Q")
7533 (and:SI (match_operand:SI 1 "nonimmediate_operand" "%0,0, 0,0")
7534 (match_operand:SI 2 "general_operand" " d,R,NxQSF,Q")))
7535 (clobber (reg:CC CC_REGNUM))]
7536 "!TARGET_ZARCH && s390_logical_operator_ok_p (operands)"
7542 [(set_attr "op_type" "RR,RX,SI,SS")
7543 (set_attr "z10prop" "z10_super_E1,z10_super_E1,*,*")])
7547 [(set (match_operand:SI 0 "s_operand" "")
7548 (and:SI (match_dup 0) (match_operand:SI 1 "immediate_operand" "")))
7549 (clobber (reg:CC CC_REGNUM))]
7552 [(set (match_dup 0) (and:QI (match_dup 0) (match_dup 1)))
7553 (clobber (reg:CC CC_REGNUM))])]
7554 "s390_narrow_logical_operator (AND, &operands[0], &operands[1]);")
7557 ; andhi3 instruction pattern(s).
7560 (define_insn "*andhi3_zarch"
7561 [(set (match_operand:HI 0 "nonimmediate_operand" "=d,d,d, AQ,Q")
7562 (and:HI (match_operand:HI 1 "nonimmediate_operand" "%0,d,0, 0,0")
7563 (match_operand:HI 2 "general_operand" " d,d,n,NxQHF,Q")))
7564 (clobber (reg:CC CC_REGNUM))]
7565 "TARGET_ZARCH && s390_logical_operator_ok_p (operands)"
7572 [(set_attr "op_type" "RR,RRF,RI,SI,SS")
7573 (set_attr "cpu_facility" "*,z196,*,*,*")
7574 (set_attr "z10prop" "z10_super_E1,*,z10_super_E1,*,*")
7577 (define_insn "*andhi3_esa"
7578 [(set (match_operand:HI 0 "nonimmediate_operand" "=d,AQ,Q")
7579 (and:HI (match_operand:HI 1 "nonimmediate_operand" "%0,0,0")
7580 (match_operand:HI 2 "general_operand" "d,NxQHF,Q")))
7581 (clobber (reg:CC CC_REGNUM))]
7582 "!TARGET_ZARCH && s390_logical_operator_ok_p (operands)"
7587 [(set_attr "op_type" "RR,SI,SS")
7588 (set_attr "z10prop" "z10_super_E1,*,*")
7592 [(set (match_operand:HI 0 "s_operand" "")
7593 (and:HI (match_dup 0) (match_operand:HI 1 "immediate_operand" "")))
7594 (clobber (reg:CC CC_REGNUM))]
7597 [(set (match_dup 0) (and:QI (match_dup 0) (match_dup 1)))
7598 (clobber (reg:CC CC_REGNUM))])]
7599 "s390_narrow_logical_operator (AND, &operands[0], &operands[1]);")
7602 ; andqi3 instruction pattern(s).
7605 (define_insn "*andqi3_zarch"
7606 [(set (match_operand:QI 0 "nonimmediate_operand" "=d,d,d,Q,S,Q")
7607 (and:QI (match_operand:QI 1 "nonimmediate_operand" "%0,d,0,0,0,0")
7608 (match_operand:QI 2 "general_operand" " d,d,n,n,n,Q")))
7609 (clobber (reg:CC CC_REGNUM))]
7610 "TARGET_ZARCH && s390_logical_operator_ok_p (operands)"
7618 [(set_attr "op_type" "RR,RRF,RI,SI,SIY,SS")
7619 (set_attr "cpu_facility" "*,z196,*,*,longdisp,*")
7620 (set_attr "z10prop" "z10_super_E1,*,z10_super_E1,z10_super,z10_super,*")])
7622 (define_insn "*andqi3_esa"
7623 [(set (match_operand:QI 0 "nonimmediate_operand" "=d,Q,Q")
7624 (and:QI (match_operand:QI 1 "nonimmediate_operand" "%0,0,0")
7625 (match_operand:QI 2 "general_operand" "d,n,Q")))
7626 (clobber (reg:CC CC_REGNUM))]
7627 "!TARGET_ZARCH && s390_logical_operator_ok_p (operands)"
7632 [(set_attr "op_type" "RR,SI,SS")
7633 (set_attr "z10prop" "z10_super_E1,z10_super,*")])
7636 ; And with complement
7638 ; c = ~b & a = (b & a) ^ a
7640 (define_insn_and_split "*andc_split_<mode>"
7641 [(set (match_operand:GPR 0 "nonimmediate_operand" "")
7642 (and:GPR (not:GPR (match_operand:GPR 1 "nonimmediate_operand" ""))
7643 (match_operand:GPR 2 "general_operand" "")))
7644 (clobber (reg:CC CC_REGNUM))]
7646 && (GET_CODE (operands[0]) != MEM
7647 /* Ensure that s390_logical_operator_ok_p will succeed even
7648 on the split xor if (b & a) is stored into a pseudo. */
7649 || rtx_equal_p (operands[0], operands[2]))"
7654 [(set (match_dup 3) (and:GPR (match_dup 1) (match_dup 2)))
7655 (clobber (reg:CC CC_REGNUM))])
7657 [(set (match_dup 0) (xor:GPR (match_dup 3) (match_dup 2)))
7658 (clobber (reg:CC CC_REGNUM))])]
7660 if (reg_overlap_mentioned_p (operands[0], operands[2]))
7661 operands[3] = gen_reg_rtx (<MODE>mode);
7663 operands[3] = operands[0];
7667 ; Block and (NC) patterns.
7671 [(set (match_operand:BLK 0 "memory_operand" "=Q")
7672 (and:BLK (match_dup 0)
7673 (match_operand:BLK 1 "memory_operand" "Q")))
7674 (use (match_operand 2 "const_int_operand" "n"))
7675 (clobber (reg:CC CC_REGNUM))]
7676 "INTVAL (operands[2]) >= 1 && INTVAL (operands[2]) <= 256"
7677 "nc\t%O0(%2,%R0),%S1"
7678 [(set_attr "op_type" "SS")
7679 (set_attr "z196prop" "z196_cracked")])
7682 [(set (match_operand 0 "memory_operand" "")
7684 (match_operand 1 "memory_operand" "")))
7685 (clobber (reg:CC CC_REGNUM))]
7687 && GET_MODE (operands[0]) == GET_MODE (operands[1])
7688 && GET_MODE_SIZE (GET_MODE (operands[0])) > 0"
7690 [(set (match_dup 0) (and:BLK (match_dup 0) (match_dup 1)))
7692 (clobber (reg:CC CC_REGNUM))])]
7694 operands[2] = GEN_INT (GET_MODE_SIZE (GET_MODE (operands[0])));
7695 operands[0] = adjust_address (operands[0], BLKmode, 0);
7696 operands[1] = adjust_address (operands[1], BLKmode, 0);
7701 [(set (match_operand:BLK 0 "memory_operand" "")
7702 (and:BLK (match_dup 0)
7703 (match_operand:BLK 1 "memory_operand" "")))
7704 (use (match_operand 2 "const_int_operand" ""))
7705 (clobber (reg:CC CC_REGNUM))])
7707 [(set (match_operand:BLK 3 "memory_operand" "")
7708 (and:BLK (match_dup 3)
7709 (match_operand:BLK 4 "memory_operand" "")))
7710 (use (match_operand 5 "const_int_operand" ""))
7711 (clobber (reg:CC CC_REGNUM))])]
7712 "s390_offset_p (operands[0], operands[3], operands[2])
7713 && s390_offset_p (operands[1], operands[4], operands[2])
7714 && !s390_overlap_p (operands[0], operands[1],
7715 INTVAL (operands[2]) + INTVAL (operands[5]))
7716 && INTVAL (operands[2]) + INTVAL (operands[5]) <= 256"
7718 [(set (match_dup 6) (and:BLK (match_dup 6) (match_dup 7)))
7720 (clobber (reg:CC CC_REGNUM))])]
7721 "operands[6] = gen_rtx_MEM (BLKmode, XEXP (operands[0], 0));
7722 operands[7] = gen_rtx_MEM (BLKmode, XEXP (operands[1], 0));
7723 operands[8] = GEN_INT (INTVAL (operands[2]) + INTVAL (operands[5]));")
7727 ;;- Bit set (inclusive or) instructions.
7730 (define_expand "ior<mode>3"
7731 [(set (match_operand:INT 0 "nonimmediate_operand" "")
7732 (ior:INT (match_operand:INT 1 "nonimmediate_operand" "")
7733 (match_operand:INT 2 "general_operand" "")))
7734 (clobber (reg:CC CC_REGNUM))]
7736 "s390_expand_logical_operator (IOR, <MODE>mode, operands); DONE;")
7739 ; iordi3 instruction pattern(s).
7742 (define_insn "*iordi3_cc"
7743 [(set (reg CC_REGNUM)
7744 (compare (ior:DI (match_operand:DI 1 "nonimmediate_operand" "%0,d,0")
7745 (match_operand:DI 2 "general_operand" " d,d,T"))
7747 (set (match_operand:DI 0 "register_operand" "=d,d,d")
7748 (ior:DI (match_dup 1) (match_dup 2)))]
7749 "s390_match_ccmode(insn, CCTmode) && TARGET_ZARCH"
7754 [(set_attr "op_type" "RRE,RRF,RXY")
7755 (set_attr "cpu_facility" "*,z196,*")
7756 (set_attr "z10prop" "z10_super_E1,*,z10_super_E1")])
7758 (define_insn "*iordi3_cconly"
7759 [(set (reg CC_REGNUM)
7760 (compare (ior:DI (match_operand:DI 1 "nonimmediate_operand" "%0,d,0")
7761 (match_operand:DI 2 "general_operand" " d,d,T"))
7763 (clobber (match_scratch:DI 0 "=d,d,d"))]
7764 "s390_match_ccmode(insn, CCTmode) && TARGET_ZARCH"
7769 [(set_attr "op_type" "RRE,RRF,RXY")
7770 (set_attr "cpu_facility" "*,z196,*")
7771 (set_attr "z10prop" "z10_super_E1,*,z10_super_E1")])
7773 (define_insn "*iordi3"
7774 [(set (match_operand:DI 0 "nonimmediate_operand"
7775 "=d, d, d, d, d, d,d,d,d, AQ,Q")
7776 (ior:DI (match_operand:DI 1 "nonimmediate_operand"
7777 " %0, 0, 0, 0, 0, 0,0,d,0, 0,0")
7778 (match_operand:DI 2 "general_operand"
7779 "N0HD0,N1HD0,N2HD0,N3HD0,N0SD0,N1SD0,d,d,T,NxQD0,Q")))
7780 (clobber (reg:CC CC_REGNUM))]
7781 "TARGET_ZARCH && s390_logical_operator_ok_p (operands)"
7794 [(set_attr "op_type" "RI,RI,RI,RI,RIL,RIL,RRE,RRF,RXY,SI,SS")
7795 (set_attr "cpu_facility" "*,*,*,*,extimm,extimm,*,z196,*,*,*")
7796 (set_attr "z10prop" "z10_super_E1,
7809 [(set (match_operand:DI 0 "s_operand" "")
7810 (ior:DI (match_dup 0) (match_operand:DI 1 "immediate_operand" "")))
7811 (clobber (reg:CC CC_REGNUM))]
7814 [(set (match_dup 0) (ior:QI (match_dup 0) (match_dup 1)))
7815 (clobber (reg:CC CC_REGNUM))])]
7816 "s390_narrow_logical_operator (IOR, &operands[0], &operands[1]);")
7819 ; iorsi3 instruction pattern(s).
7822 (define_insn "*iorsi3_cc"
7823 [(set (reg CC_REGNUM)
7824 (compare (ior:SI (match_operand:SI 1 "nonimmediate_operand" "%0,0,d,0,0")
7825 (match_operand:SI 2 "general_operand" "Os,d,d,R,T"))
7827 (set (match_operand:SI 0 "register_operand" "=d,d,d,d,d")
7828 (ior:SI (match_dup 1) (match_dup 2)))]
7829 "s390_match_ccmode(insn, CCTmode)"
7836 [(set_attr "op_type" "RIL,RR,RRF,RX,RXY")
7837 (set_attr "cpu_facility" "*,*,z196,*,longdisp")
7838 (set_attr "z10prop" "z10_super_E1,z10_super_E1,*,z10_super_E1,z10_super_E1")])
7840 (define_insn "*iorsi3_cconly"
7841 [(set (reg CC_REGNUM)
7842 (compare (ior:SI (match_operand:SI 1 "nonimmediate_operand" "%0,0,d,0,0")
7843 (match_operand:SI 2 "general_operand" "Os,d,d,R,T"))
7845 (clobber (match_scratch:SI 0 "=d,d,d,d,d"))]
7846 "s390_match_ccmode(insn, CCTmode)"
7853 [(set_attr "op_type" "RIL,RR,RRF,RX,RXY")
7854 (set_attr "cpu_facility" "*,*,z196,*,longdisp")
7855 (set_attr "z10prop" "z10_super_E1,z10_super_E1,*,z10_super_E1,z10_super_E1")])
7857 (define_insn "*iorsi3_zarch"
7858 [(set (match_operand:SI 0 "nonimmediate_operand" "=d, d, d,d,d,d,d, AQ,Q")
7859 (ior:SI (match_operand:SI 1 "nonimmediate_operand" "%0, 0, 0,0,d,0,0, 0,0")
7860 (match_operand:SI 2 "general_operand" "N0HS0,N1HS0,Os,d,d,R,T,NxQS0,Q")))
7861 (clobber (reg:CC CC_REGNUM))]
7862 "TARGET_ZARCH && s390_logical_operator_ok_p (operands)"
7873 [(set_attr "op_type" "RI,RI,RIL,RR,RRF,RX,RXY,SI,SS")
7874 (set_attr "cpu_facility" "*,*,*,*,z196,*,longdisp,*,*")
7875 (set_attr "z10prop" "z10_super_E1,
7885 (define_insn "*iorsi3_esa"
7886 [(set (match_operand:SI 0 "nonimmediate_operand" "=d,d,AQ,Q")
7887 (ior:SI (match_operand:SI 1 "nonimmediate_operand" "%0,0,0,0")
7888 (match_operand:SI 2 "general_operand" "d,R,NxQS0,Q")))
7889 (clobber (reg:CC CC_REGNUM))]
7890 "!TARGET_ZARCH && s390_logical_operator_ok_p (operands)"
7896 [(set_attr "op_type" "RR,RX,SI,SS")
7897 (set_attr "z10prop" "z10_super_E1,z10_super_E1,*,*")])
7900 [(set (match_operand:SI 0 "s_operand" "")
7901 (ior:SI (match_dup 0) (match_operand:SI 1 "immediate_operand" "")))
7902 (clobber (reg:CC CC_REGNUM))]
7905 [(set (match_dup 0) (ior:QI (match_dup 0) (match_dup 1)))
7906 (clobber (reg:CC CC_REGNUM))])]
7907 "s390_narrow_logical_operator (IOR, &operands[0], &operands[1]);")
7910 ; iorhi3 instruction pattern(s).
7913 (define_insn "*iorhi3_zarch"
7914 [(set (match_operand:HI 0 "nonimmediate_operand" "=d,d,d, AQ,Q")
7915 (ior:HI (match_operand:HI 1 "nonimmediate_operand" "%0,d,0, 0,0")
7916 (match_operand:HI 2 "general_operand" " d,d,n,NxQH0,Q")))
7917 (clobber (reg:CC CC_REGNUM))]
7918 "TARGET_ZARCH && s390_logical_operator_ok_p (operands)"
7925 [(set_attr "op_type" "RR,RRF,RI,SI,SS")
7926 (set_attr "cpu_facility" "*,z196,*,*,*")
7927 (set_attr "z10prop" "z10_super_E1,*,z10_super_E1,*,*")])
7929 (define_insn "*iorhi3_esa"
7930 [(set (match_operand:HI 0 "nonimmediate_operand" "=d,AQ,Q")
7931 (ior:HI (match_operand:HI 1 "nonimmediate_operand" "%0,0,0")
7932 (match_operand:HI 2 "general_operand" "d,NxQH0,Q")))
7933 (clobber (reg:CC CC_REGNUM))]
7934 "!TARGET_ZARCH && s390_logical_operator_ok_p (operands)"
7939 [(set_attr "op_type" "RR,SI,SS")
7940 (set_attr "z10prop" "z10_super_E1,*,*")])
7943 [(set (match_operand:HI 0 "s_operand" "")
7944 (ior:HI (match_dup 0) (match_operand:HI 1 "immediate_operand" "")))
7945 (clobber (reg:CC CC_REGNUM))]
7948 [(set (match_dup 0) (ior:QI (match_dup 0) (match_dup 1)))
7949 (clobber (reg:CC CC_REGNUM))])]
7950 "s390_narrow_logical_operator (IOR, &operands[0], &operands[1]);")
7953 ; iorqi3 instruction pattern(s).
7956 (define_insn "*iorqi3_zarch"
7957 [(set (match_operand:QI 0 "nonimmediate_operand" "=d,d,d,Q,S,Q")
7958 (ior:QI (match_operand:QI 1 "nonimmediate_operand" "%0,d,0,0,0,0")
7959 (match_operand:QI 2 "general_operand" " d,d,n,n,n,Q")))
7960 (clobber (reg:CC CC_REGNUM))]
7961 "TARGET_ZARCH && s390_logical_operator_ok_p (operands)"
7969 [(set_attr "op_type" "RR,RRF,RI,SI,SIY,SS")
7970 (set_attr "cpu_facility" "*,z196,*,*,longdisp,*")
7971 (set_attr "z10prop" "z10_super_E1,*,z10_super_E1,
7972 z10_super,z10_super,*")])
7974 (define_insn "*iorqi3_esa"
7975 [(set (match_operand:QI 0 "nonimmediate_operand" "=d,Q,Q")
7976 (ior:QI (match_operand:QI 1 "nonimmediate_operand" "%0,0,0")
7977 (match_operand:QI 2 "general_operand" "d,n,Q")))
7978 (clobber (reg:CC CC_REGNUM))]
7979 "!TARGET_ZARCH && s390_logical_operator_ok_p (operands)"
7984 [(set_attr "op_type" "RR,SI,SS")
7985 (set_attr "z10prop" "z10_super_E1,z10_super,*")])
7988 ; Block inclusive or (OC) patterns.
7992 [(set (match_operand:BLK 0 "memory_operand" "=Q")
7993 (ior:BLK (match_dup 0)
7994 (match_operand:BLK 1 "memory_operand" "Q")))
7995 (use (match_operand 2 "const_int_operand" "n"))
7996 (clobber (reg:CC CC_REGNUM))]
7997 "INTVAL (operands[2]) >= 1 && INTVAL (operands[2]) <= 256"
7998 "oc\t%O0(%2,%R0),%S1"
7999 [(set_attr "op_type" "SS")
8000 (set_attr "z196prop" "z196_cracked")])
8003 [(set (match_operand 0 "memory_operand" "")
8005 (match_operand 1 "memory_operand" "")))
8006 (clobber (reg:CC CC_REGNUM))]
8008 && GET_MODE (operands[0]) == GET_MODE (operands[1])
8009 && GET_MODE_SIZE (GET_MODE (operands[0])) > 0"
8011 [(set (match_dup 0) (ior:BLK (match_dup 0) (match_dup 1)))
8013 (clobber (reg:CC CC_REGNUM))])]
8015 operands[2] = GEN_INT (GET_MODE_SIZE (GET_MODE (operands[0])));
8016 operands[0] = adjust_address (operands[0], BLKmode, 0);
8017 operands[1] = adjust_address (operands[1], BLKmode, 0);
8022 [(set (match_operand:BLK 0 "memory_operand" "")
8023 (ior:BLK (match_dup 0)
8024 (match_operand:BLK 1 "memory_operand" "")))
8025 (use (match_operand 2 "const_int_operand" ""))
8026 (clobber (reg:CC CC_REGNUM))])
8028 [(set (match_operand:BLK 3 "memory_operand" "")
8029 (ior:BLK (match_dup 3)
8030 (match_operand:BLK 4 "memory_operand" "")))
8031 (use (match_operand 5 "const_int_operand" ""))
8032 (clobber (reg:CC CC_REGNUM))])]
8033 "s390_offset_p (operands[0], operands[3], operands[2])
8034 && s390_offset_p (operands[1], operands[4], operands[2])
8035 && !s390_overlap_p (operands[0], operands[1],
8036 INTVAL (operands[2]) + INTVAL (operands[5]))
8037 && INTVAL (operands[2]) + INTVAL (operands[5]) <= 256"
8039 [(set (match_dup 6) (ior:BLK (match_dup 6) (match_dup 7)))
8041 (clobber (reg:CC CC_REGNUM))])]
8042 "operands[6] = gen_rtx_MEM (BLKmode, XEXP (operands[0], 0));
8043 operands[7] = gen_rtx_MEM (BLKmode, XEXP (operands[1], 0));
8044 operands[8] = GEN_INT (INTVAL (operands[2]) + INTVAL (operands[5]));")
8048 ;;- Xor instructions.
8051 (define_expand "xor<mode>3"
8052 [(set (match_operand:INT 0 "nonimmediate_operand" "")
8053 (xor:INT (match_operand:INT 1 "nonimmediate_operand" "")
8054 (match_operand:INT 2 "general_operand" "")))
8055 (clobber (reg:CC CC_REGNUM))]
8057 "s390_expand_logical_operator (XOR, <MODE>mode, operands); DONE;")
8059 ; Combine replaces (xor (x) (const_int -1)) with (not (x)) when doing
8060 ; simplifications. So its better to have something matching.
8062 [(set (match_operand:INT 0 "nonimmediate_operand" "")
8063 (not:INT (match_operand:INT 1 "nonimmediate_operand" "")))]
8066 [(set (match_dup 0) (xor:INT (match_dup 1) (match_dup 2)))
8067 (clobber (reg:CC CC_REGNUM))])]
8069 operands[2] = constm1_rtx;
8070 if (!s390_logical_operator_ok_p (operands))
8075 ; xordi3 instruction pattern(s).
8078 (define_insn "*xordi3_cc"
8079 [(set (reg CC_REGNUM)
8080 (compare (xor:DI (match_operand:DI 1 "nonimmediate_operand" "%0,d,0")
8081 (match_operand:DI 2 "general_operand" " d,d,T"))
8083 (set (match_operand:DI 0 "register_operand" "=d,d,d")
8084 (xor:DI (match_dup 1) (match_dup 2)))]
8085 "s390_match_ccmode(insn, CCTmode) && TARGET_ZARCH"
8090 [(set_attr "op_type" "RRE,RRF,RXY")
8091 (set_attr "cpu_facility" "*,z196,*")
8092 (set_attr "z10prop" "z10_super_E1,*,z10_super_E1")])
8094 (define_insn "*xordi3_cconly"
8095 [(set (reg CC_REGNUM)
8096 (compare (xor:DI (match_operand:DI 1 "nonimmediate_operand" "%0,d,0")
8097 (match_operand:DI 2 "general_operand" " d,d,T"))
8099 (clobber (match_scratch:DI 0 "=d,d,d"))]
8100 "s390_match_ccmode(insn, CCTmode) && TARGET_ZARCH"
8105 [(set_attr "op_type" "RRE,RRF,RXY")
8106 (set_attr "cpu_facility" "*,z196,*")
8107 (set_attr "z10prop" "z10_super_E1,*,z10_super_E1")])
8109 (define_insn "*xordi3"
8110 [(set (match_operand:DI 0 "nonimmediate_operand" "=d, d,d,d,d, AQ,Q")
8111 (xor:DI (match_operand:DI 1 "nonimmediate_operand" "%0, 0,0,d,0, 0,0")
8112 (match_operand:DI 2 "general_operand" "N0SD0,N1SD0,d,d,T,NxQD0,Q")))
8113 (clobber (reg:CC CC_REGNUM))]
8114 "TARGET_ZARCH && s390_logical_operator_ok_p (operands)"
8123 [(set_attr "op_type" "RIL,RIL,RRE,RRF,RXY,SI,SS")
8124 (set_attr "cpu_facility" "extimm,extimm,*,z196,*,*,*")
8125 (set_attr "z10prop" "z10_super_E1,z10_super_E1,z10_super_E1,
8126 *,z10_super_E1,*,*")])
8129 [(set (match_operand:DI 0 "s_operand" "")
8130 (xor:DI (match_dup 0) (match_operand:DI 1 "immediate_operand" "")))
8131 (clobber (reg:CC CC_REGNUM))]
8134 [(set (match_dup 0) (xor:QI (match_dup 0) (match_dup 1)))
8135 (clobber (reg:CC CC_REGNUM))])]
8136 "s390_narrow_logical_operator (XOR, &operands[0], &operands[1]);")
8139 ; xorsi3 instruction pattern(s).
8142 (define_insn "*xorsi3_cc"
8143 [(set (reg CC_REGNUM)
8144 (compare (xor:SI (match_operand:SI 1 "nonimmediate_operand" "%0,0,d,0,0")
8145 (match_operand:SI 2 "general_operand" "Os,d,d,R,T"))
8147 (set (match_operand:SI 0 "register_operand" "=d,d,d,d,d")
8148 (xor:SI (match_dup 1) (match_dup 2)))]
8149 "s390_match_ccmode(insn, CCTmode)"
8156 [(set_attr "op_type" "RIL,RR,RRF,RX,RXY")
8157 (set_attr "cpu_facility" "*,*,z196,*,longdisp")
8158 (set_attr "z10prop" "z10_super_E1,z10_super_E1,*,
8159 z10_super_E1,z10_super_E1")])
8161 (define_insn "*xorsi3_cconly"
8162 [(set (reg CC_REGNUM)
8163 (compare (xor:SI (match_operand:SI 1 "nonimmediate_operand" "%0,0,d,0,0")
8164 (match_operand:SI 2 "general_operand" "Os,d,d,R,T"))
8166 (clobber (match_scratch:SI 0 "=d,d,d,d,d"))]
8167 "s390_match_ccmode(insn, CCTmode)"
8174 [(set_attr "op_type" "RIL,RR,RRF,RX,RXY")
8175 (set_attr "cpu_facility" "*,*,z196,*,longdisp")
8176 (set_attr "z10prop" "z10_super_E1,z10_super_E1,*,
8177 z10_super_E1,z10_super_E1")])
8179 (define_insn "*xorsi3"
8180 [(set (match_operand:SI 0 "nonimmediate_operand" "=d,d,d,d,d, AQ,Q")
8181 (xor:SI (match_operand:SI 1 "nonimmediate_operand" "%0,0,d,0,0, 0,0")
8182 (match_operand:SI 2 "general_operand" "Os,d,d,R,T,NxQS0,Q")))
8183 (clobber (reg:CC CC_REGNUM))]
8184 "s390_logical_operator_ok_p (operands)"
8193 [(set_attr "op_type" "RIL,RR,RRF,RX,RXY,SI,SS")
8194 (set_attr "cpu_facility" "*,*,z196,*,longdisp,*,*")
8195 (set_attr "z10prop" "z10_super_E1,z10_super_E1,*,
8196 z10_super_E1,z10_super_E1,*,*")])
8199 [(set (match_operand:SI 0 "s_operand" "")
8200 (xor:SI (match_dup 0) (match_operand:SI 1 "immediate_operand" "")))
8201 (clobber (reg:CC CC_REGNUM))]
8204 [(set (match_dup 0) (xor:QI (match_dup 0) (match_dup 1)))
8205 (clobber (reg:CC CC_REGNUM))])]
8206 "s390_narrow_logical_operator (XOR, &operands[0], &operands[1]);")
8209 ; xorhi3 instruction pattern(s).
8212 (define_insn "*xorhi3"
8213 [(set (match_operand:HI 0 "nonimmediate_operand" "=d,d,d, AQ,Q")
8214 (xor:HI (match_operand:HI 1 "nonimmediate_operand" "%0,0,d, 0,0")
8215 (match_operand:HI 2 "general_operand" "Os,d,d,NxQH0,Q")))
8216 (clobber (reg:CC CC_REGNUM))]
8217 "s390_logical_operator_ok_p (operands)"
8224 [(set_attr "op_type" "RIL,RR,RRF,SI,SS")
8225 (set_attr "cpu_facility" "*,*,z196,*,*")
8226 (set_attr "z10prop" "z10_super_E1,z10_super_E1,*,*,*")])
8229 [(set (match_operand:HI 0 "s_operand" "")
8230 (xor:HI (match_dup 0) (match_operand:HI 1 "immediate_operand" "")))
8231 (clobber (reg:CC CC_REGNUM))]
8234 [(set (match_dup 0) (xor:QI (match_dup 0) (match_dup 1)))
8235 (clobber (reg:CC CC_REGNUM))])]
8236 "s390_narrow_logical_operator (XOR, &operands[0], &operands[1]);")
8239 ; xorqi3 instruction pattern(s).
8242 (define_insn "*xorqi3"
8243 [(set (match_operand:QI 0 "nonimmediate_operand" "=d,d,d,Q,S,Q")
8244 (xor:QI (match_operand:QI 1 "nonimmediate_operand" "%0,0,d,0,0,0")
8245 (match_operand:QI 2 "general_operand" "Os,d,d,n,n,Q")))
8246 (clobber (reg:CC CC_REGNUM))]
8247 "s390_logical_operator_ok_p (operands)"
8255 [(set_attr "op_type" "RIL,RR,RRF,SI,SIY,SS")
8256 (set_attr "cpu_facility" "*,*,z196,*,longdisp,*")
8257 (set_attr "z10prop" "z10_super_E1,z10_super_E1,*,z10_super,z10_super,*")])
8261 ; Block exclusive or (XC) patterns.
8265 [(set (match_operand:BLK 0 "memory_operand" "=Q")
8266 (xor:BLK (match_dup 0)
8267 (match_operand:BLK 1 "memory_operand" "Q")))
8268 (use (match_operand 2 "const_int_operand" "n"))
8269 (clobber (reg:CC CC_REGNUM))]
8270 "INTVAL (operands[2]) >= 1 && INTVAL (operands[2]) <= 256"
8271 "xc\t%O0(%2,%R0),%S1"
8272 [(set_attr "op_type" "SS")])
8275 [(set (match_operand 0 "memory_operand" "")
8277 (match_operand 1 "memory_operand" "")))
8278 (clobber (reg:CC CC_REGNUM))]
8280 && GET_MODE (operands[0]) == GET_MODE (operands[1])
8281 && GET_MODE_SIZE (GET_MODE (operands[0])) > 0"
8283 [(set (match_dup 0) (xor:BLK (match_dup 0) (match_dup 1)))
8285 (clobber (reg:CC CC_REGNUM))])]
8287 operands[2] = GEN_INT (GET_MODE_SIZE (GET_MODE (operands[0])));
8288 operands[0] = adjust_address (operands[0], BLKmode, 0);
8289 operands[1] = adjust_address (operands[1], BLKmode, 0);
8294 [(set (match_operand:BLK 0 "memory_operand" "")
8295 (xor:BLK (match_dup 0)
8296 (match_operand:BLK 1 "memory_operand" "")))
8297 (use (match_operand 2 "const_int_operand" ""))
8298 (clobber (reg:CC CC_REGNUM))])
8300 [(set (match_operand:BLK 3 "memory_operand" "")
8301 (xor:BLK (match_dup 3)
8302 (match_operand:BLK 4 "memory_operand" "")))
8303 (use (match_operand 5 "const_int_operand" ""))
8304 (clobber (reg:CC CC_REGNUM))])]
8305 "s390_offset_p (operands[0], operands[3], operands[2])
8306 && s390_offset_p (operands[1], operands[4], operands[2])
8307 && !s390_overlap_p (operands[0], operands[1],
8308 INTVAL (operands[2]) + INTVAL (operands[5]))
8309 && INTVAL (operands[2]) + INTVAL (operands[5]) <= 256"
8311 [(set (match_dup 6) (xor:BLK (match_dup 6) (match_dup 7)))
8313 (clobber (reg:CC CC_REGNUM))])]
8314 "operands[6] = gen_rtx_MEM (BLKmode, XEXP (operands[0], 0));
8315 operands[7] = gen_rtx_MEM (BLKmode, XEXP (operands[1], 0));
8316 operands[8] = GEN_INT (INTVAL (operands[2]) + INTVAL (operands[5]));")
8319 ; Block xor (XC) patterns with src == dest.
8322 (define_insn "*xc_zero"
8323 [(set (match_operand:BLK 0 "memory_operand" "=Q")
8325 (use (match_operand 1 "const_int_operand" "n"))
8326 (clobber (reg:CC CC_REGNUM))]
8327 "INTVAL (operands[1]) >= 1 && INTVAL (operands[1]) <= 256"
8328 "xc\t%O0(%1,%R0),%S0"
8329 [(set_attr "op_type" "SS")
8330 (set_attr "z196prop" "z196_cracked")])
8334 [(set (match_operand:BLK 0 "memory_operand" "")
8336 (use (match_operand 1 "const_int_operand" ""))
8337 (clobber (reg:CC CC_REGNUM))])
8339 [(set (match_operand:BLK 2 "memory_operand" "")
8341 (use (match_operand 3 "const_int_operand" ""))
8342 (clobber (reg:CC CC_REGNUM))])]
8343 "s390_offset_p (operands[0], operands[2], operands[1])
8344 && INTVAL (operands[1]) + INTVAL (operands[3]) <= 256"
8346 [(set (match_dup 4) (const_int 0))
8348 (clobber (reg:CC CC_REGNUM))])]
8349 "operands[4] = gen_rtx_MEM (BLKmode, XEXP (operands[0], 0));
8350 operands[5] = GEN_INT (INTVAL (operands[1]) + INTVAL (operands[3]));")
8354 ;;- Negate instructions.
8358 ; neg(di|si)2 instruction pattern(s).
8361 (define_expand "neg<mode>2"
8363 [(set (match_operand:DSI 0 "register_operand" "=d")
8364 (neg:DSI (match_operand:DSI 1 "register_operand" "d")))
8365 (clobber (reg:CC CC_REGNUM))])]
8369 (define_insn "*negdi2_sign_cc"
8370 [(set (reg CC_REGNUM)
8371 (compare (neg:DI (ashiftrt:DI (ashift:DI (subreg:DI
8372 (match_operand:SI 1 "register_operand" "d") 0)
8373 (const_int 32)) (const_int 32)))
8375 (set (match_operand:DI 0 "register_operand" "=d")
8376 (neg:DI (sign_extend:DI (match_dup 1))))]
8377 "TARGET_ZARCH && s390_match_ccmode (insn, CCAmode)"
8379 [(set_attr "op_type" "RRE")
8380 (set_attr "z10prop" "z10_c")])
8382 (define_insn "*negdi2_sign"
8383 [(set (match_operand:DI 0 "register_operand" "=d")
8384 (neg:DI (sign_extend:DI (match_operand:SI 1 "register_operand" "d"))))
8385 (clobber (reg:CC CC_REGNUM))]
8388 [(set_attr "op_type" "RRE")
8389 (set_attr "z10prop" "z10_c")])
8392 (define_insn "*neg<mode>2_cc"
8393 [(set (reg CC_REGNUM)
8394 (compare (neg:GPR (match_operand:GPR 1 "register_operand" "d"))
8396 (set (match_operand:GPR 0 "register_operand" "=d")
8397 (neg:GPR (match_dup 1)))]
8398 "s390_match_ccmode (insn, CCAmode)"
8400 [(set_attr "op_type" "RR<E>")
8401 (set_attr "z10prop" "z10_super_c_E1")])
8404 (define_insn "*neg<mode>2_cconly"
8405 [(set (reg CC_REGNUM)
8406 (compare (neg:GPR (match_operand:GPR 1 "register_operand" "d"))
8408 (clobber (match_scratch:GPR 0 "=d"))]
8409 "s390_match_ccmode (insn, CCAmode)"
8411 [(set_attr "op_type" "RR<E>")
8412 (set_attr "z10prop" "z10_super_c_E1")])
8415 (define_insn "*neg<mode>2"
8416 [(set (match_operand:GPR 0 "register_operand" "=d")
8417 (neg:GPR (match_operand:GPR 1 "register_operand" "d")))
8418 (clobber (reg:CC CC_REGNUM))]
8421 [(set_attr "op_type" "RR<E>")
8422 (set_attr "z10prop" "z10_super_c_E1")])
8424 (define_insn "*negdi2_31"
8425 [(set (match_operand:DI 0 "register_operand" "=d")
8426 (neg:DI (match_operand:DI 1 "register_operand" "d")))
8427 (clobber (reg:CC CC_REGNUM))]
8431 ; Split a DImode NEG on 31bit into 2 SImode NEGs
8433 ; Doing the twos complement separately on the SImode parts does an
8434 ; unwanted +1 on the high part which needs to be subtracted afterwards
8435 ; ... unless the +1 on the low part created an overflow.
8438 [(set (match_operand:DI 0 "register_operand" "")
8439 (neg:DI (match_operand:DI 1 "register_operand" "")))
8440 (clobber (reg:CC CC_REGNUM))]
8442 && (REGNO (operands[0]) == REGNO (operands[1])
8443 || s390_split_ok_p (operands[0], operands[1], DImode, 0))
8444 && reload_completed"
8446 [(set (match_dup 2) (neg:SI (match_dup 3)))
8447 (clobber (reg:CC CC_REGNUM))])
8449 [(set (reg:CCAP CC_REGNUM)
8450 (compare:CCAP (neg:SI (match_dup 5)) (const_int 0)))
8451 (set (match_dup 4) (neg:SI (match_dup 5)))])
8453 (if_then_else (ne (reg:CCAP CC_REGNUM) (const_int 0))
8455 (label_ref (match_dup 6))))
8457 [(set (match_dup 2) (plus:SI (match_dup 2) (const_int -1)))
8458 (clobber (reg:CC CC_REGNUM))])
8460 "operands[2] = operand_subword (operands[0], 0, 0, DImode);
8461 operands[3] = operand_subword (operands[1], 0, 0, DImode);
8462 operands[4] = operand_subword (operands[0], 1, 0, DImode);
8463 operands[5] = operand_subword (operands[1], 1, 0, DImode);
8464 operands[6] = gen_label_rtx ();")
8466 ; Like above but first make a copy of the low part of the src operand
8467 ; since it might overlap with the high part of the destination.
8470 [(set (match_operand:DI 0 "register_operand" "")
8471 (neg:DI (match_operand:DI 1 "register_operand" "")))
8472 (clobber (reg:CC CC_REGNUM))]
8474 && s390_split_ok_p (operands[0], operands[1], DImode, 1)
8475 && reload_completed"
8476 [; Make a backup of op5 first
8477 (set (match_dup 4) (match_dup 5))
8478 ; Setting op2 here might clobber op5
8480 [(set (match_dup 2) (neg:SI (match_dup 3)))
8481 (clobber (reg:CC CC_REGNUM))])
8483 [(set (reg:CCAP CC_REGNUM)
8484 (compare:CCAP (neg:SI (match_dup 4)) (const_int 0)))
8485 (set (match_dup 4) (neg:SI (match_dup 4)))])
8487 (if_then_else (ne (reg:CCAP CC_REGNUM) (const_int 0))
8489 (label_ref (match_dup 6))))
8491 [(set (match_dup 2) (plus:SI (match_dup 2) (const_int -1)))
8492 (clobber (reg:CC CC_REGNUM))])
8494 "operands[2] = operand_subword (operands[0], 0, 0, DImode);
8495 operands[3] = operand_subword (operands[1], 0, 0, DImode);
8496 operands[4] = operand_subword (operands[0], 1, 0, DImode);
8497 operands[5] = operand_subword (operands[1], 1, 0, DImode);
8498 operands[6] = gen_label_rtx ();")
8501 ; neg(df|sf)2 instruction pattern(s).
8504 (define_expand "neg<mode>2"
8506 [(set (match_operand:BFP 0 "register_operand")
8507 (neg:BFP (match_operand:BFP 1 "register_operand")))
8508 (clobber (reg:CC CC_REGNUM))])]
8509 "TARGET_HARD_FLOAT")
8511 ; lcxbr, lcdbr, lcebr
8512 (define_insn "*neg<mode>2_cc"
8513 [(set (reg CC_REGNUM)
8514 (compare (neg:BFP (match_operand:BFP 1 "register_operand" "f"))
8515 (match_operand:BFP 2 "const0_operand" "")))
8516 (set (match_operand:BFP 0 "register_operand" "=f")
8517 (neg:BFP (match_dup 1)))]
8518 "s390_match_ccmode (insn, CCSmode) && TARGET_HARD_FLOAT"
8520 [(set_attr "op_type" "RRE")
8521 (set_attr "type" "fsimp<mode>")])
8523 ; lcxbr, lcdbr, lcebr
8524 (define_insn "*neg<mode>2_cconly"
8525 [(set (reg CC_REGNUM)
8526 (compare (neg:BFP (match_operand:BFP 1 "register_operand" "f"))
8527 (match_operand:BFP 2 "const0_operand" "")))
8528 (clobber (match_scratch:BFP 0 "=f"))]
8529 "s390_match_ccmode (insn, CCSmode) && TARGET_HARD_FLOAT"
8531 [(set_attr "op_type" "RRE")
8532 (set_attr "type" "fsimp<mode>")])
8535 (define_insn "*neg<mode>2_nocc"
8536 [(set (match_operand:FP 0 "register_operand" "=f")
8537 (neg:FP (match_operand:FP 1 "register_operand" "<fT0>")))]
8540 [(set_attr "op_type" "RRE")
8541 (set_attr "type" "fsimp<mode>")])
8543 ; lcxbr, lcdbr, lcebr
8544 ; FIXME: wflcdb does not clobber cc
8545 ; FIXME: Does wflcdb ever match here?
8546 (define_insn "*neg<mode>2"
8547 [(set (match_operand:BFP 0 "register_operand" "=f,v,v")
8548 (neg:BFP (match_operand:BFP 1 "register_operand" "f,v,v")))
8549 (clobber (reg:CC CC_REGNUM))]
8555 [(set_attr "op_type" "RRE,VRR,VRR")
8556 (set_attr "cpu_facility" "*,vx,vxe")
8557 (set_attr "type" "fsimp<mode>,*,*")
8558 (set_attr "enabled" "*,<DF>,<SF>")])
8562 ;;- Absolute value instructions.
8566 ; abs(di|si)2 instruction pattern(s).
8569 (define_insn "*absdi2_sign_cc"
8570 [(set (reg CC_REGNUM)
8571 (compare (abs:DI (ashiftrt:DI (ashift:DI (subreg:DI
8572 (match_operand:SI 1 "register_operand" "d") 0)
8573 (const_int 32)) (const_int 32)))
8575 (set (match_operand:DI 0 "register_operand" "=d")
8576 (abs:DI (sign_extend:DI (match_dup 1))))]
8577 "TARGET_ZARCH && s390_match_ccmode (insn, CCAmode)"
8579 [(set_attr "op_type" "RRE")
8580 (set_attr "z10prop" "z10_c")])
8582 (define_insn "*absdi2_sign"
8583 [(set (match_operand:DI 0 "register_operand" "=d")
8584 (abs:DI (sign_extend:DI (match_operand:SI 1 "register_operand" "d"))))
8585 (clobber (reg:CC CC_REGNUM))]
8588 [(set_attr "op_type" "RRE")
8589 (set_attr "z10prop" "z10_c")])
8592 (define_insn "*abs<mode>2_cc"
8593 [(set (reg CC_REGNUM)
8594 (compare (abs:GPR (match_operand:DI 1 "register_operand" "d"))
8596 (set (match_operand:GPR 0 "register_operand" "=d")
8597 (abs:GPR (match_dup 1)))]
8598 "s390_match_ccmode (insn, CCAmode)"
8600 [(set_attr "op_type" "RR<E>")
8601 (set_attr "z10prop" "z10_c")])
8604 (define_insn "*abs<mode>2_cconly"
8605 [(set (reg CC_REGNUM)
8606 (compare (abs:GPR (match_operand:GPR 1 "register_operand" "d"))
8608 (clobber (match_scratch:GPR 0 "=d"))]
8609 "s390_match_ccmode (insn, CCAmode)"
8611 [(set_attr "op_type" "RR<E>")
8612 (set_attr "z10prop" "z10_c")])
8615 (define_insn "abs<mode>2"
8616 [(set (match_operand:GPR 0 "register_operand" "=d")
8617 (abs:GPR (match_operand:GPR 1 "register_operand" "d")))
8618 (clobber (reg:CC CC_REGNUM))]
8621 [(set_attr "op_type" "RR<E>")
8622 (set_attr "z10prop" "z10_c")])
8625 ; abs(df|sf)2 instruction pattern(s).
8628 (define_expand "abs<mode>2"
8630 [(set (match_operand:BFP 0 "register_operand" "=f")
8631 (abs:BFP (match_operand:BFP 1 "register_operand" "f")))
8632 (clobber (reg:CC CC_REGNUM))])]
8636 ; lpxbr, lpdbr, lpebr
8637 (define_insn "*abs<mode>2_cc"
8638 [(set (reg CC_REGNUM)
8639 (compare (abs:BFP (match_operand:BFP 1 "register_operand" "f"))
8640 (match_operand:BFP 2 "const0_operand" "")))
8641 (set (match_operand:BFP 0 "register_operand" "=f")
8642 (abs:BFP (match_dup 1)))]
8643 "s390_match_ccmode (insn, CCSmode) && TARGET_HARD_FLOAT"
8645 [(set_attr "op_type" "RRE")
8646 (set_attr "type" "fsimp<mode>")])
8648 ; lpxbr, lpdbr, lpebr
8649 (define_insn "*abs<mode>2_cconly"
8650 [(set (reg CC_REGNUM)
8651 (compare (abs:BFP (match_operand:BFP 1 "register_operand" "f"))
8652 (match_operand:BFP 2 "const0_operand" "")))
8653 (clobber (match_scratch:BFP 0 "=f"))]
8654 "s390_match_ccmode (insn, CCSmode) && TARGET_HARD_FLOAT"
8656 [(set_attr "op_type" "RRE")
8657 (set_attr "type" "fsimp<mode>")])
8660 (define_insn "*abs<mode>2_nocc"
8661 [(set (match_operand:FP 0 "register_operand" "=f")
8662 (abs:FP (match_operand:FP 1 "register_operand" "<fT0>")))]
8665 [(set_attr "op_type" "RRE")
8666 (set_attr "type" "fsimp<mode>")])
8668 ; lpxbr, lpdbr, lpebr
8669 ; FIXME: wflpdb does not clobber cc
8670 (define_insn "*abs<mode>2"
8671 [(set (match_operand:BFP 0 "register_operand" "=f,v")
8672 (abs:BFP (match_operand:BFP 1 "register_operand" "f,v")))
8673 (clobber (reg:CC CC_REGNUM))]
8678 [(set_attr "op_type" "RRE,VRR")
8679 (set_attr "cpu_facility" "*,vx")
8680 (set_attr "type" "fsimp<mode>,*")
8681 (set_attr "enabled" "*,<DFDI>")])
8685 ;;- Negated absolute value instructions
8692 (define_insn "*negabsdi2_sign_cc"
8693 [(set (reg CC_REGNUM)
8694 (compare (neg:DI (abs:DI (ashiftrt:DI (ashift:DI (subreg:DI
8695 (match_operand:SI 1 "register_operand" "d") 0)
8696 (const_int 32)) (const_int 32))))
8698 (set (match_operand:DI 0 "register_operand" "=d")
8699 (neg:DI (abs:DI (sign_extend:DI (match_dup 1)))))]
8700 "TARGET_ZARCH && s390_match_ccmode (insn, CCAmode)"
8702 [(set_attr "op_type" "RRE")
8703 (set_attr "z10prop" "z10_c")])
8705 (define_insn "*negabsdi2_sign"
8706 [(set (match_operand:DI 0 "register_operand" "=d")
8707 (neg:DI (abs:DI (sign_extend:DI
8708 (match_operand:SI 1 "register_operand" "d")))))
8709 (clobber (reg:CC CC_REGNUM))]
8712 [(set_attr "op_type" "RRE")
8713 (set_attr "z10prop" "z10_c")])
8716 (define_insn "*negabs<mode>2_cc"
8717 [(set (reg CC_REGNUM)
8718 (compare (neg:GPR (abs:GPR (match_operand:GPR 1 "register_operand" "d")))
8720 (set (match_operand:GPR 0 "register_operand" "=d")
8721 (neg:GPR (abs:GPR (match_dup 1))))]
8722 "s390_match_ccmode (insn, CCAmode)"
8724 [(set_attr "op_type" "RR<E>")
8725 (set_attr "z10prop" "z10_c")])
8728 (define_insn "*negabs<mode>2_cconly"
8729 [(set (reg CC_REGNUM)
8730 (compare (neg:GPR (abs:GPR (match_operand:GPR 1 "register_operand" "d")))
8732 (clobber (match_scratch:GPR 0 "=d"))]
8733 "s390_match_ccmode (insn, CCAmode)"
8735 [(set_attr "op_type" "RR<E>")
8736 (set_attr "z10prop" "z10_c")])
8739 (define_insn "*negabs<mode>2"
8740 [(set (match_operand:GPR 0 "register_operand" "=d")
8741 (neg:GPR (abs:GPR (match_operand:GPR 1 "register_operand" "d"))))
8742 (clobber (reg:CC CC_REGNUM))]
8745 [(set_attr "op_type" "RR<E>")
8746 (set_attr "z10prop" "z10_c")])
8752 ; lnxbr, lndbr, lnebr
8753 (define_insn "*negabs<mode>2_cc"
8754 [(set (reg CC_REGNUM)
8755 (compare (neg:BFP (abs:BFP (match_operand:BFP 1 "register_operand" "f")))
8756 (match_operand:BFP 2 "const0_operand" "")))
8757 (set (match_operand:BFP 0 "register_operand" "=f")
8758 (neg:BFP (abs:BFP (match_dup 1))))]
8759 "s390_match_ccmode (insn, CCSmode) && TARGET_HARD_FLOAT"
8761 [(set_attr "op_type" "RRE")
8762 (set_attr "type" "fsimp<mode>")])
8764 ; lnxbr, lndbr, lnebr
8765 (define_insn "*negabs<mode>2_cconly"
8766 [(set (reg CC_REGNUM)
8767 (compare (neg:BFP (abs:BFP (match_operand:BFP 1 "register_operand" "f")))
8768 (match_operand:BFP 2 "const0_operand" "")))
8769 (clobber (match_scratch:BFP 0 "=f"))]
8770 "s390_match_ccmode (insn, CCSmode) && TARGET_HARD_FLOAT"
8772 [(set_attr "op_type" "RRE")
8773 (set_attr "type" "fsimp<mode>")])
8776 (define_insn "*negabs<mode>2_nocc"
8777 [(set (match_operand:FP 0 "register_operand" "=f")
8778 (neg:FP (abs:FP (match_operand:BFP 1 "register_operand" "<fT0>"))))]
8781 [(set_attr "op_type" "RRE")
8782 (set_attr "type" "fsimp<mode>")])
8784 ; lnxbr, lndbr, lnebr
8785 ; FIXME: wflndb does not clobber cc
8786 (define_insn "*negabs<mode>2"
8787 [(set (match_operand:BFP 0 "register_operand" "=f,v")
8788 (neg:BFP (abs:BFP (match_operand:BFP 1 "register_operand" "f,v"))))
8789 (clobber (reg:CC CC_REGNUM))]
8794 [(set_attr "op_type" "RRE,VRR")
8795 (set_attr "cpu_facility" "*,vx")
8796 (set_attr "type" "fsimp<mode>,*")
8797 (set_attr "enabled" "*,<DFDI>")])
8800 ;;- Square root instructions.
8804 ; sqrt(df|sf)2 instruction pattern(s).
8807 ; sqxbr, sqdbr, sqebr, sqdb, sqeb
8808 (define_insn "sqrt<mode>2"
8809 [(set (match_operand:BFP 0 "register_operand" "=f,f,v")
8810 (sqrt:BFP (match_operand:BFP 1 "general_operand" "f,R,v")))]
8816 [(set_attr "op_type" "RRE,RXE,VRR")
8817 (set_attr "type" "fsqrt<mode>")
8818 (set_attr "cpu_facility" "*,*,vx")
8819 (set_attr "enabled" "*,<DSF>,<DFDI>")])
8823 ;;- One complement instructions.
8827 ; one_cmpl(di|si|hi|qi)2 instruction pattern(s).
8830 (define_expand "one_cmpl<mode>2"
8832 [(set (match_operand:INT 0 "register_operand" "")
8833 (xor:INT (match_operand:INT 1 "register_operand" "")
8835 (clobber (reg:CC CC_REGNUM))])]
8841 ;; Find leftmost bit instructions.
8844 (define_expand "clzdi2"
8845 [(set (match_operand:DI 0 "register_operand" "=d")
8846 (clz:DI (match_operand:DI 1 "register_operand" "d")))]
8847 "TARGET_EXTIMM && TARGET_ZARCH"
8851 rtx wide_reg = gen_reg_rtx (TImode);
8852 rtx msb = gen_rtx_CONST_INT (DImode, HOST_WIDE_INT_1U << 63);
8854 clz_equal = gen_rtx_CLZ (DImode, operands[1]);
8856 emit_insn (gen_clztidi2 (wide_reg, operands[1], msb));
8858 insn = emit_move_insn (operands[0], gen_highpart (DImode, wide_reg));
8859 set_unique_reg_note (insn, REG_EQUAL, clz_equal);
8864 (define_insn "clztidi2"
8865 [(set (match_operand:TI 0 "register_operand" "=d")
8869 (xor:DI (match_operand:DI 1 "register_operand" "d")
8870 (lshiftrt (match_operand:DI 2 "const_int_operand" "")
8871 (subreg:SI (clz:DI (match_dup 1)) 4))))
8874 (zero_extend:TI (clz:DI (match_dup 1)))))
8875 (clobber (reg:CC CC_REGNUM))]
8876 "UINTVAL (operands[2]) == HOST_WIDE_INT_1U << 63
8877 && TARGET_EXTIMM && TARGET_ZARCH"
8879 [(set_attr "op_type" "RRE")])
8883 ;;- Rotate instructions.
8887 ; rotl(di|si)3 instruction pattern(s).
8890 (define_expand "rotl<mode>3"
8891 [(set (match_operand:GPR 0 "register_operand" "")
8892 (rotate:GPR (match_operand:GPR 1 "register_operand" "")
8893 (match_operand:SI 2 "nonmemory_operand" "")))]
8898 (define_insn "*rotl<mode>3<addr_style_op><masked_op>"
8899 [(set (match_operand:GPR 0 "register_operand" "=d")
8900 (rotate:GPR (match_operand:GPR 1 "register_operand" "d")
8901 (match_operand:SI 2 "nonmemory_operand" "an")))]
8903 "rll<g>\t%0,%1,<addr_style_op_ops>"
8904 [(set_attr "op_type" "RSE")
8905 (set_attr "atype" "reg")
8906 (set_attr "z10prop" "z10_super_E1")])
8910 ;;- Shift instructions.
8914 ; (ashl|lshr)(di|si)3 instruction pattern(s).
8915 ; Left shifts and logical right shifts
8917 (define_expand "<shift><mode>3"
8918 [(set (match_operand:DSI 0 "register_operand" "")
8919 (SHIFT:DSI (match_operand:DSI 1 "register_operand" "")
8920 (match_operand:SI 2 "nonmemory_operand" "")))]
8924 ; ESA 64 bit register pair shift with reg or imm shift count
8926 (define_insn "*<shift>di3_31<addr_style_op><masked_op>"
8927 [(set (match_operand:DI 0 "register_operand" "=d")
8928 (SHIFT:DI (match_operand:DI 1 "register_operand" "0")
8929 (match_operand:SI 2 "nonmemory_operand" "an")))]
8931 "s<lr>dl\t%0,<addr_style_op_ops>"
8932 [(set_attr "op_type" "RS")
8933 (set_attr "atype" "reg")
8934 (set_attr "z196prop" "z196_cracked")])
8937 ; 64 bit register shift with reg or imm shift count
8938 ; sll, srl, sllg, srlg, sllk, srlk
8939 (define_insn "*<shift><mode>3<addr_style_op><masked_op>"
8940 [(set (match_operand:GPR 0 "register_operand" "=d, d")
8941 (SHIFT:GPR (match_operand:GPR 1 "register_operand" "<d0>, d")
8942 (match_operand:SI 2 "nonmemory_operand" "an,an")))]
8945 s<lr>l<g>\t%0,<1><addr_style_op_ops>
8946 s<lr>l<gk>\t%0,%1,<addr_style_op_ops>"
8947 [(set_attr "op_type" "RS<E>,RSY")
8948 (set_attr "atype" "reg,reg")
8949 (set_attr "cpu_facility" "*,z196")
8950 (set_attr "z10prop" "z10_super_E1,*")])
8953 ; ashr(di|si)3 instruction pattern(s).
8954 ; Arithmetic right shifts
8956 (define_expand "ashr<mode>3"
8958 [(set (match_operand:DSI 0 "register_operand" "")
8959 (ashiftrt:DSI (match_operand:DSI 1 "register_operand" "")
8960 (match_operand:SI 2 "nonmemory_operand" "")))
8961 (clobber (reg:CC CC_REGNUM))])]
8965 ; FIXME: The number of alternatives is doubled here to match the fix
8966 ; number of 2 in the subst pattern for the (clobber (match_scratch...
8967 ; The right fix should be to support match_scratch in the output
8968 ; pattern of a define_subst.
8969 (define_insn "*ashrdi3_31<addr_style_op_cc><masked_op_cc><setcc><cconly>"
8970 [(set (match_operand:DI 0 "register_operand" "=d, d")
8971 (ashiftrt:DI (match_operand:DI 1 "register_operand" "0, 0")
8972 (match_operand:SI 2 "nonmemory_operand" "an,an")))
8973 (clobber (reg:CC CC_REGNUM))]
8976 srda\t%0,<addr_style_op_cc_ops>
8977 srda\t%0,<addr_style_op_cc_ops>"
8978 [(set_attr "op_type" "RS")
8979 (set_attr "atype" "reg")])
8983 (define_insn "*ashr<mode>3<addr_style_op_cc><masked_op_cc><setcc><cconly>"
8984 [(set (match_operand:GPR 0 "register_operand" "=d, d")
8985 (ashiftrt:GPR (match_operand:GPR 1 "register_operand" "<d0>, d")
8986 (match_operand:SI 2 "nonmemory_operand" "an,an")))
8987 (clobber (reg:CC CC_REGNUM))]
8990 sra<g>\t%0,<1><addr_style_op_cc_ops>
8991 sra<gk>\t%0,%1,<addr_style_op_cc_ops>"
8992 [(set_attr "op_type" "RS<E>,RSY")
8993 (set_attr "atype" "reg")
8994 (set_attr "cpu_facility" "*,z196")
8995 (set_attr "z10prop" "z10_super_E1,*")])
8999 ;; Branch instruction patterns.
9002 (define_expand "cbranch<mode>4"
9004 (if_then_else (match_operator 0 "comparison_operator"
9005 [(match_operand:GPR 1 "register_operand" "")
9006 (match_operand:GPR 2 "general_operand" "")])
9007 (label_ref (match_operand 3 "" ""))
9010 "s390_emit_jump (operands[3],
9011 s390_emit_compare (GET_CODE (operands[0]), operands[1], operands[2]));
9014 (define_expand "cbranch<mode>4"
9016 (if_then_else (match_operator 0 "comparison_operator"
9017 [(match_operand:FP 1 "register_operand" "")
9018 (match_operand:FP 2 "general_operand" "")])
9019 (label_ref (match_operand 3 "" ""))
9022 "s390_emit_jump (operands[3],
9023 s390_emit_compare (GET_CODE (operands[0]), operands[1], operands[2]));
9026 (define_expand "cbranchcc4"
9028 (if_then_else (match_operator 0 "s390_comparison"
9029 [(match_operand 1 "cc_reg_operand" "")
9030 (match_operand 2 "const_int_operand" "")])
9031 (label_ref (match_operand 3 "" ""))
9038 ;;- Conditional jump instructions.
9041 (define_insn "*cjump_64"
9044 (match_operator 1 "s390_comparison" [(reg CC_REGNUM)
9045 (match_operand 2 "const_int_operand" "")])
9046 (label_ref (match_operand 0 "" ""))
9050 if (get_attr_length (insn) == 4)
9053 return "jg%C1\t%l0";
9055 [(set_attr "op_type" "RI")
9056 (set_attr "type" "branch")
9057 (set (attr "length")
9058 (if_then_else (lt (abs (minus (pc) (match_dup 0))) (const_int 60000))
9059 (const_int 4) (const_int 6)))])
9061 (define_insn "*cjump_31"
9064 (match_operator 1 "s390_comparison" [(reg CC_REGNUM)
9065 (match_operand 2 "const_int_operand" "")])
9066 (label_ref (match_operand 0 "" ""))
9070 gcc_assert (get_attr_length (insn) == 4);
9073 [(set_attr "op_type" "RI")
9074 (set_attr "type" "branch")
9075 (set (attr "length")
9076 (if_then_else (not (match_test "flag_pic"))
9077 (if_then_else (lt (abs (minus (pc) (match_dup 0))) (const_int 60000))
9078 (const_int 4) (const_int 6))
9079 (if_then_else (lt (abs (minus (pc) (match_dup 0))) (const_int 60000))
9080 (const_int 4) (const_int 8))))])
9082 (define_insn "*cjump_long"
9085 (match_operator 1 "s390_comparison" [(reg CC_REGNUM) (const_int 0)])
9086 (match_operand 0 "address_operand" "ZQZR")
9088 "!TARGET_INDIRECT_BRANCH_NOBP_JUMP"
9090 if (get_attr_op_type (insn) == OP_TYPE_RR)
9095 [(set (attr "op_type")
9096 (if_then_else (match_operand 0 "register_operand" "")
9097 (const_string "RR") (const_string "RX")))
9098 (set (attr "mnemonic")
9099 (if_then_else (match_operand 0 "register_operand" "")
9100 (const_string "bcr") (const_string "bc")))
9101 (set_attr "type" "branch")
9102 (set_attr "atype" "agen")])
9104 ;; A conditional return instruction.
9105 (define_insn "*c<code>"
9108 (match_operator 0 "s390_comparison" [(reg CC_REGNUM) (const_int 0)])
9111 "s390_can_use_<code>_insn ()"
9113 if (TARGET_INDIRECT_BRANCH_NOBP_RET)
9115 s390_indirect_branch_via_thunk (RETURN_REGNUM,
9118 s390_indirect_branch_type_return);
9122 return "b%C0r\t%%r14";
9124 [(set (attr "op_type")
9125 (if_then_else (match_test "TARGET_INDIRECT_BRANCH_NOBP_RET")
9126 (const_string "RIL")
9127 (const_string "RR")))
9128 (set (attr "mnemonic")
9129 (if_then_else (match_test "TARGET_INDIRECT_BRANCH_NOBP_RET")
9130 (const_string "brcl")
9131 (const_string "bcr")))
9132 (set_attr "type" "jsr")
9133 (set_attr "atype" "agen")])
9136 ;;- Negated conditional jump instructions.
9139 (define_insn "*icjump_64"
9142 (match_operator 1 "s390_comparison" [(reg CC_REGNUM) (const_int 0)])
9144 (label_ref (match_operand 0 "" ""))))]
9147 if (get_attr_length (insn) == 4)
9150 return "jg%D1\t%l0";
9152 [(set_attr "op_type" "RI")
9153 (set_attr "type" "branch")
9154 (set (attr "length")
9155 (if_then_else (lt (abs (minus (pc) (match_dup 0))) (const_int 60000))
9156 (const_int 4) (const_int 6)))])
9158 (define_insn "*icjump_31"
9161 (match_operator 1 "s390_comparison" [(reg CC_REGNUM) (const_int 0)])
9163 (label_ref (match_operand 0 "" ""))))]
9166 gcc_assert (get_attr_length (insn) == 4);
9169 [(set_attr "op_type" "RI")
9170 (set_attr "type" "branch")
9171 (set (attr "length")
9172 (if_then_else (not (match_test "flag_pic"))
9173 (if_then_else (lt (abs (minus (pc) (match_dup 0))) (const_int 60000))
9174 (const_int 4) (const_int 6))
9175 (if_then_else (lt (abs (minus (pc) (match_dup 0))) (const_int 60000))
9176 (const_int 4) (const_int 8))))])
9178 (define_insn "*icjump_long"
9181 (match_operator 1 "s390_comparison" [(reg CC_REGNUM) (const_int 0)])
9183 (match_operand 0 "address_operand" "ZQZR")))]
9184 "!TARGET_INDIRECT_BRANCH_NOBP_JUMP"
9186 if (get_attr_op_type (insn) == OP_TYPE_RR)
9191 [(set (attr "op_type")
9192 (if_then_else (match_operand 0 "register_operand" "")
9193 (const_string "RR") (const_string "RX")))
9194 (set (attr "mnemonic")
9195 (if_then_else (match_operand 0 "register_operand" "")
9196 (const_string "bcr") (const_string "bc")))
9197 (set_attr "type" "branch")
9198 (set_attr "atype" "agen")])
9201 ;;- Trap instructions.
9205 [(trap_if (const_int 1) (const_int 0))]
9208 [(set_attr "op_type" "RI")
9209 (set_attr "type" "branch")])
9211 (define_expand "ctrap<mode>4"
9212 [(trap_if (match_operator 0 "comparison_operator"
9213 [(match_operand:GPR 1 "register_operand" "")
9214 (match_operand:GPR 2 "general_operand" "")])
9215 (match_operand 3 "const0_operand" ""))]
9218 rtx cond = s390_emit_compare (GET_CODE (operands[0]),
9219 operands[1], operands[2]);
9220 emit_insn (gen_condtrap (cond, XEXP (cond, 0)));
9224 (define_expand "ctrap<mode>4"
9225 [(trap_if (match_operator 0 "comparison_operator"
9226 [(match_operand:FP 1 "register_operand" "")
9227 (match_operand:FP 2 "general_operand" "")])
9228 (match_operand 3 "const0_operand" ""))]
9231 rtx cond = s390_emit_compare (GET_CODE (operands[0]),
9232 operands[1], operands[2]);
9233 emit_insn (gen_condtrap (cond, XEXP (cond, 0)));
9237 (define_insn "condtrap"
9238 [(trap_if (match_operator 0 "s390_comparison"
9239 [(match_operand 1 "cc_reg_operand" "c")
9244 [(set_attr "op_type" "RI")
9245 (set_attr "type" "branch")])
9247 ; crt, cgrt, cit, cgit
9248 (define_insn "*cmp_and_trap_signed_int<mode>"
9249 [(trap_if (match_operator 0 "s390_signed_integer_comparison"
9250 [(match_operand:GPR 1 "register_operand" "d,d")
9251 (match_operand:GPR 2 "nonmemory_operand" "d,K")])
9257 [(set_attr "op_type" "RRF,RIE")
9258 (set_attr "type" "branch")
9259 (set_attr "z10prop" "z10_super_c,z10_super")])
9261 ; clrt, clgrt, clfit, clgit, clt, clgt
9262 (define_insn "*cmp_and_trap_unsigned_int<mode>"
9263 [(trap_if (match_operator 0 "s390_unsigned_integer_comparison"
9264 [(match_operand:GPR 1 "register_operand" "d,d,d")
9265 (match_operand:GPR 2 "general_operand" "d,D,T")])
9272 [(set_attr "op_type" "RRF,RIE,RSY")
9273 (set_attr "type" "branch")
9274 (set_attr "z10prop" "z10_super_c,z10_super,*")
9275 (set_attr "cpu_facility" "z10,z10,zEC12")])
9278 (define_insn "*load_and_trap<mode>"
9279 [(trap_if (eq (match_operand:GPR 0 "memory_operand" "T")
9282 (set (match_operand:GPR 1 "register_operand" "=d")
9286 [(set_attr "op_type" "RXY")])
9290 ;;- Loop instructions.
9292 ;; This is all complicated by the fact that since this is a jump insn
9293 ;; we must handle our own output reloads.
9297 ; This splitter will be matched by combine and has to add the 2 moves
9298 ; necessary to load the compare and the increment values into a
9299 ; register pair as needed by brxle.
9301 (define_insn_and_split "*brx_stage1_<GPR:mode>"
9304 (match_operator 6 "s390_brx_operator"
9305 [(plus:GPR (match_operand:GPR 1 "register_operand" "")
9306 (match_operand:GPR 2 "general_operand" ""))
9307 (match_operand:GPR 3 "register_operand" "")])
9308 (label_ref (match_operand 0 "" ""))
9310 (set (match_operand:GPR 4 "nonimmediate_operand" "")
9311 (plus:GPR (match_dup 1) (match_dup 2)))
9312 (clobber (match_scratch:GPR 5 ""))]
9315 "!reload_completed && !reload_in_progress"
9316 [(set (match_dup 7) (match_dup 2)) ; the increment
9317 (set (match_dup 8) (match_dup 3)) ; the comparison value
9318 (parallel [(set (pc)
9321 [(plus:GPR (match_dup 1) (match_dup 7))
9323 (label_ref (match_dup 0))
9326 (plus:GPR (match_dup 1) (match_dup 7)))
9327 (clobber (match_dup 5))
9328 (clobber (reg:CC CC_REGNUM))])]
9330 rtx dreg = gen_reg_rtx (word_mode == DImode ? TImode : DImode);
9331 operands[7] = gen_lowpart (<GPR:MODE>mode,
9332 gen_highpart (word_mode, dreg));
9333 operands[8] = gen_lowpart (<GPR:MODE>mode,
9334 gen_lowpart (word_mode, dreg));
9339 (define_insn_and_split "*brxg_64bit"
9342 (match_operator 5 "s390_brx_operator"
9343 [(plus:DI (match_operand:DI 1 "register_operand" "d,d,d")
9344 (subreg:DI (match_operand:TI 2 "register_operand" "d,d,d") 0))
9345 (subreg:DI (match_dup 2) 8)])
9346 (label_ref (match_operand 0 "" ""))
9348 (set (match_operand:DI 3 "nonimmediate_operand" "=1,?X,?X")
9349 (plus:DI (match_dup 1)
9350 (subreg:DI (match_dup 2) 0)))
9351 (clobber (match_scratch:DI 4 "=X,&1,&?d"))
9352 (clobber (reg:CC CC_REGNUM))]
9355 if (which_alternative != 0)
9357 else if (get_attr_length (insn) == 6)
9358 return "brx%E5g\t%1,%2,%l0";
9360 return "agr\t%1,%2\;cgr\t%1,%M2\;jg%C5\t%l0";
9362 "&& reload_completed
9363 && (!REG_P (operands[3])
9364 || !rtx_equal_p (operands[1], operands[3]))"
9365 [(set (match_dup 4) (match_dup 1))
9366 (parallel [(set (match_dup 4) (plus:DI (match_dup 4) (subreg:DI (match_dup 2) 0)))
9367 (clobber (reg:CC CC_REGNUM))])
9368 (set (reg:CCS CC_REGNUM) (compare:CCS (match_dup 4) (subreg:DI (match_dup 2) 8)))
9369 (set (match_dup 3) (match_dup 4))
9370 (set (pc) (if_then_else (match_op_dup 5 [(reg:CCS CC_REGNUM) (const_int 0)])
9371 (label_ref (match_dup 0))
9374 [(set_attr "op_type" "RIE")
9375 (set_attr "type" "branch")
9376 (set (attr "length")
9377 (if_then_else (lt (abs (minus (pc) (match_dup 0))) (const_int 60000))
9378 (const_int 6) (const_int 16)))])
9382 (define_insn_and_split "*brx_64bit"
9385 (match_operator 5 "s390_brx_operator"
9386 [(plus:SI (match_operand:SI 1 "register_operand" "d,d,d")
9387 (subreg:SI (match_operand:TI 2 "register_operand" "d,d,d") 4))
9388 (subreg:SI (match_dup 2) 12)])
9389 (label_ref (match_operand 0 "" ""))
9391 (set (match_operand:SI 3 "nonimmediate_operand" "=1,?X,?X")
9392 (plus:SI (match_dup 1)
9393 (subreg:SI (match_dup 2) 4)))
9394 (clobber (match_scratch:SI 4 "=X,&1,&?d"))
9395 (clobber (reg:CC CC_REGNUM))]
9398 if (which_alternative != 0)
9400 else if (get_attr_length (insn) == 6)
9401 return "brx%C5\t%1,%2,%l0";
9403 return "ar\t%1,%2\;cr\t%1,%M2\;jg%C5\t%l0";
9405 "&& reload_completed
9406 && (!REG_P (operands[3])
9407 || !rtx_equal_p (operands[1], operands[3]))"
9408 [(set (match_dup 4) (match_dup 1))
9409 (parallel [(set (match_dup 4) (plus:SI (match_dup 4) (subreg:SI (match_dup 2) 4)))
9410 (clobber (reg:CC CC_REGNUM))])
9411 (set (reg:CCS CC_REGNUM) (compare:CCS (match_dup 4) (subreg:SI (match_dup 2) 12)))
9412 (set (match_dup 3) (match_dup 4))
9413 (set (pc) (if_then_else (match_op_dup 5 [(reg:CCS CC_REGNUM) (const_int 0)])
9414 (label_ref (match_dup 0))
9417 [(set_attr "op_type" "RSI")
9418 (set_attr "type" "branch")
9419 (set (attr "length")
9420 (if_then_else (lt (abs (minus (pc) (match_dup 0))) (const_int 60000))
9421 (const_int 6) (const_int 14)))])
9425 (define_insn_and_split "*brx_31bit"
9428 (match_operator 5 "s390_brx_operator"
9429 [(plus:SI (match_operand:SI 1 "register_operand" "d,d,d")
9430 (subreg:SI (match_operand:DI 2 "register_operand" "d,d,d") 0))
9431 (subreg:SI (match_dup 2) 4)])
9432 (label_ref (match_operand 0 "" ""))
9434 (set (match_operand:SI 3 "nonimmediate_operand" "=1,?X,?X")
9435 (plus:SI (match_dup 1)
9436 (subreg:SI (match_dup 2) 0)))
9437 (clobber (match_scratch:SI 4 "=X,&1,&?d"))
9438 (clobber (reg:CC CC_REGNUM))]
9439 "!TARGET_ZARCH && TARGET_CPU_ZARCH"
9441 if (which_alternative != 0)
9443 else if (get_attr_length (insn) == 6)
9444 return "brx%C5\t%1,%2,%l0";
9446 return "ar\t%1,%2\;cr\t%1,%M2\;jg%C5\t%l0";
9448 "&& reload_completed
9449 && (!REG_P (operands[3])
9450 || !rtx_equal_p (operands[1], operands[3]))"
9451 [(set (match_dup 4) (match_dup 1))
9452 (parallel [(set (match_dup 4) (plus:SI (match_dup 4) (subreg:SI (match_dup 2) 0)))
9453 (clobber (reg:CC CC_REGNUM))])
9454 (set (reg:CCS CC_REGNUM) (compare:CCS (match_dup 4) (subreg:SI (match_dup 2) 4)))
9455 (set (match_dup 3) (match_dup 4))
9456 (set (pc) (if_then_else (match_op_dup 5 [(reg:CCS CC_REGNUM) (const_int 0)])
9457 (label_ref (match_dup 0))
9460 [(set_attr "op_type" "RSI")
9461 (set_attr "type" "branch")
9462 (set (attr "length")
9463 (if_then_else (lt (abs (minus (pc) (match_dup 0))) (const_int 60000))
9464 (const_int 6) (const_int 14)))])
9469 (define_expand "doloop_end"
9470 [(use (match_operand 0 "" "")) ; loop pseudo
9471 (use (match_operand 1 "" ""))] ; label
9474 if (GET_MODE (operands[0]) == SImode && !TARGET_CPU_ZARCH)
9475 emit_jump_insn (gen_doloop_si31 (operands[1], operands[0], operands[0]));
9476 else if (GET_MODE (operands[0]) == SImode && TARGET_CPU_ZARCH)
9477 emit_jump_insn (gen_doloop_si64 (operands[1], operands[0], operands[0]));
9478 else if (GET_MODE (operands[0]) == DImode && TARGET_ZARCH)
9479 emit_jump_insn (gen_doloop_di (operands[1], operands[0], operands[0]));
9486 (define_insn_and_split "doloop_si64"
9489 (ne (match_operand:SI 1 "register_operand" "d,d,d")
9491 (label_ref (match_operand 0 "" ""))
9493 (set (match_operand:SI 2 "nonimmediate_operand" "=1,?X,?X")
9494 (plus:SI (match_dup 1) (const_int -1)))
9495 (clobber (match_scratch:SI 3 "=X,&1,&?d"))
9496 (clobber (reg:CC CC_REGNUM))]
9499 if (which_alternative != 0)
9501 else if (get_attr_length (insn) == 4)
9502 return "brct\t%1,%l0";
9504 return "ahi\t%1,-1\;jgne\t%l0";
9506 "&& reload_completed
9507 && (! REG_P (operands[2])
9508 || ! rtx_equal_p (operands[1], operands[2]))"
9509 [(set (match_dup 3) (match_dup 1))
9510 (parallel [(set (reg:CCAN CC_REGNUM)
9511 (compare:CCAN (plus:SI (match_dup 3) (const_int -1))
9513 (set (match_dup 3) (plus:SI (match_dup 3) (const_int -1)))])
9514 (set (match_dup 2) (match_dup 3))
9515 (set (pc) (if_then_else (ne (reg:CCAN CC_REGNUM) (const_int 0))
9516 (label_ref (match_dup 0))
9519 [(set_attr "op_type" "RI")
9520 ; Strictly speaking, the z10 properties are valid for brct only, however, it does not
9521 ; hurt us in the (rare) case of ahi.
9522 (set_attr "z10prop" "z10_super_E1")
9523 (set_attr "type" "branch")
9524 (set (attr "length")
9525 (if_then_else (lt (abs (minus (pc) (match_dup 0))) (const_int 60000))
9526 (const_int 4) (const_int 10)))])
9528 (define_insn_and_split "doloop_si31"
9531 (ne (match_operand:SI 1 "register_operand" "d,d,d")
9533 (label_ref (match_operand 0 "" ""))
9535 (set (match_operand:SI 2 "nonimmediate_operand" "=1,?X,?X")
9536 (plus:SI (match_dup 1) (const_int -1)))
9537 (clobber (match_scratch:SI 3 "=X,&1,&?d"))
9538 (clobber (reg:CC CC_REGNUM))]
9541 if (which_alternative != 0)
9543 else if (get_attr_length (insn) == 4)
9544 return "brct\t%1,%l0";
9548 "&& reload_completed
9549 && (! REG_P (operands[2])
9550 || ! rtx_equal_p (operands[1], operands[2]))"
9551 [(set (match_dup 3) (match_dup 1))
9552 (parallel [(set (reg:CCAN CC_REGNUM)
9553 (compare:CCAN (plus:SI (match_dup 3) (const_int -1))
9555 (set (match_dup 3) (plus:SI (match_dup 3) (const_int -1)))])
9556 (set (match_dup 2) (match_dup 3))
9557 (set (pc) (if_then_else (ne (reg:CCAN CC_REGNUM) (const_int 0))
9558 (label_ref (match_dup 0))
9561 [(set_attr "op_type" "RI")
9562 ; Strictly speaking, the z10 properties are valid for brct only, however, it does not
9563 ; hurt us in the (rare) case of ahi.
9564 (set_attr "z10prop" "z10_super_E1")
9565 (set_attr "type" "branch")
9566 (set (attr "length")
9567 (if_then_else (not (match_test "flag_pic"))
9568 (if_then_else (lt (abs (minus (pc) (match_dup 0))) (const_int 60000))
9569 (const_int 4) (const_int 6))
9570 (if_then_else (lt (abs (minus (pc) (match_dup 0))) (const_int 60000))
9571 (const_int 4) (const_int 8))))])
9573 (define_insn "*doloop_si_long"
9576 (ne (match_operand:SI 1 "register_operand" "d")
9578 (match_operand 0 "address_operand" "ZR")
9580 (set (match_operand:SI 2 "register_operand" "=1")
9581 (plus:SI (match_dup 1) (const_int -1)))
9582 (clobber (match_scratch:SI 3 "=X"))
9583 (clobber (reg:CC CC_REGNUM))]
9586 if (get_attr_op_type (insn) == OP_TYPE_RR)
9587 return "bctr\t%1,%0";
9589 return "bct\t%1,%a0";
9591 [(set (attr "op_type")
9592 (if_then_else (match_operand 0 "register_operand" "")
9593 (const_string "RR") (const_string "RX")))
9594 (set_attr "type" "branch")
9595 (set_attr "atype" "agen")
9596 (set_attr "z10prop" "z10_c")
9597 (set_attr "z196prop" "z196_cracked")])
9599 (define_insn_and_split "doloop_di"
9602 (ne (match_operand:DI 1 "register_operand" "d,d,d")
9604 (label_ref (match_operand 0 "" ""))
9606 (set (match_operand:DI 2 "nonimmediate_operand" "=1,?X,?X")
9607 (plus:DI (match_dup 1) (const_int -1)))
9608 (clobber (match_scratch:DI 3 "=X,&1,&?d"))
9609 (clobber (reg:CC CC_REGNUM))]
9612 if (which_alternative != 0)
9614 else if (get_attr_length (insn) == 4)
9615 return "brctg\t%1,%l0";
9617 return "aghi\t%1,-1\;jgne\t%l0";
9619 "&& reload_completed
9620 && (! REG_P (operands[2])
9621 || ! rtx_equal_p (operands[1], operands[2]))"
9622 [(set (match_dup 3) (match_dup 1))
9623 (parallel [(set (reg:CCAN CC_REGNUM)
9624 (compare:CCAN (plus:DI (match_dup 3) (const_int -1))
9626 (set (match_dup 3) (plus:DI (match_dup 3) (const_int -1)))])
9627 (set (match_dup 2) (match_dup 3))
9628 (set (pc) (if_then_else (ne (reg:CCAN CC_REGNUM) (const_int 0))
9629 (label_ref (match_dup 0))
9632 [(set_attr "op_type" "RI")
9633 ; Strictly speaking, the z10 properties are valid for brct only, however, it does not
9634 ; hurt us in the (rare) case of ahi.
9635 (set_attr "z10prop" "z10_super_E1")
9636 (set_attr "type" "branch")
9637 (set (attr "length")
9638 (if_then_else (lt (abs (minus (pc) (match_dup 0))) (const_int 60000))
9639 (const_int 4) (const_int 10)))])
9642 ;;- Unconditional jump instructions.
9646 ; jump instruction pattern(s).
9649 (define_expand "jump"
9650 [(match_operand 0 "" "")]
9652 "s390_emit_jump (operands[0], NULL_RTX); DONE;")
9654 (define_insn "*jump64"
9655 [(set (pc) (label_ref (match_operand 0 "" "")))]
9658 if (get_attr_length (insn) == 4)
9663 [(set_attr "op_type" "RI")
9664 (set_attr "type" "branch")
9665 (set (attr "length")
9666 (if_then_else (lt (abs (minus (pc) (match_dup 0))) (const_int 60000))
9667 (const_int 4) (const_int 6)))])
9669 (define_insn "*jump31"
9670 [(set (pc) (label_ref (match_operand 0 "" "")))]
9673 gcc_assert (get_attr_length (insn) == 4);
9676 [(set_attr "op_type" "RI")
9677 (set_attr "type" "branch")
9678 (set (attr "length")
9679 (if_then_else (not (match_test "flag_pic"))
9680 (if_then_else (lt (abs (minus (pc) (match_dup 0))) (const_int 60000))
9681 (const_int 4) (const_int 6))
9682 (if_then_else (lt (abs (minus (pc) (match_dup 0))) (const_int 60000))
9683 (const_int 4) (const_int 8))))])
9686 ; indirect-jump instruction pattern(s).
9689 (define_expand "indirect_jump"
9690 [(set (pc) (match_operand 0 "nonimmediate_operand" ""))]
9693 if (address_operand (operands[0], GET_MODE (operands[0])))
9695 else if (TARGET_ARCH12
9696 && GET_MODE (operands[0]) == Pmode
9697 && memory_operand (operands[0], Pmode))
9700 operands[0] = force_reg (Pmode, operands[0]);
9702 if (TARGET_INDIRECT_BRANCH_NOBP_JUMP_THUNK)
9704 operands[0] = force_reg (Pmode, operands[0]);
9708 emit_jump_insn (gen_indirect_jump_via_thunkdi_z10 (operands[0]));
9710 emit_jump_insn (gen_indirect_jump_via_thunksi_z10 (operands[0]));
9715 emit_jump_insn (gen_indirect_jump_via_thunkdi (operands[0]));
9717 emit_jump_insn (gen_indirect_jump_via_thunksi (operands[0]));
9722 if (TARGET_INDIRECT_BRANCH_NOBP_JUMP_INLINE_THUNK)
9724 operands[0] = force_reg (Pmode, operands[0]);
9725 rtx label_ref = gen_rtx_LABEL_REF (VOIDmode, gen_label_rtx ());
9729 emit_jump_insn (gen_indirect_jump_via_inlinethunkdi_z10 (operands[0],
9732 emit_jump_insn (gen_indirect_jump_via_inlinethunksi_z10 (operands[0],
9738 emit_jump_insn (gen_indirect_jump_via_inlinethunkdi (operands[0],
9740 force_reg (Pmode, label_ref)));
9742 emit_jump_insn (gen_indirect_jump_via_inlinethunksi (operands[0],
9744 force_reg (Pmode, label_ref)));
9750 (define_insn "*indirect_jump"
9752 (match_operand 0 "address_operand" "ZR"))]
9753 "!TARGET_INDIRECT_BRANCH_NOBP_JUMP_THUNK"
9755 if (get_attr_op_type (insn) == OP_TYPE_RR)
9760 [(set (attr "op_type")
9761 (if_then_else (match_operand 0 "register_operand" "")
9762 (const_string "RR") (const_string "RX")))
9763 (set (attr "mnemonic")
9764 (if_then_else (match_operand 0 "register_operand" "")
9765 (const_string "br") (const_string "b")))
9766 (set_attr "type" "branch")
9767 (set_attr "atype" "agen")])
9769 (define_insn "indirect_jump_via_thunk<mode>_z10"
9771 (match_operand:P 0 "register_operand" "a"))]
9772 "TARGET_INDIRECT_BRANCH_NOBP_JUMP_THUNK
9775 s390_indirect_branch_via_thunk (REGNO (operands[0]),
9778 s390_indirect_branch_type_jump);
9781 [(set_attr "op_type" "RIL")
9782 (set_attr "mnemonic" "jg")
9783 (set_attr "type" "branch")
9784 (set_attr "atype" "agen")])
9786 (define_insn "indirect_jump_via_thunk<mode>"
9788 (match_operand:P 0 "register_operand" " a"))
9789 (clobber (reg:P INDIRECT_BRANCH_THUNK_REGNUM))]
9790 "TARGET_INDIRECT_BRANCH_NOBP_JUMP_THUNK
9793 s390_indirect_branch_via_thunk (REGNO (operands[0]),
9796 s390_indirect_branch_type_jump);
9799 [(set_attr "op_type" "RIL")
9800 (set_attr "mnemonic" "jg")
9801 (set_attr "type" "branch")
9802 (set_attr "atype" "agen")])
9805 ; The label_ref is wrapped into an if_then_else in order to hide it
9806 ; from mark_jump_label. Without this the label_ref would become the
9807 ; ONLY jump target of that jump breaking the control flow graph.
9808 (define_insn "indirect_jump_via_inlinethunk<mode>_z10"
9809 [(unspec [(if_then_else (match_operand:P 1 "larl_operand" "X")
9812 (const_int 0)] UNSPEC_EXECUTE_JUMP)
9813 (set (pc) (match_operand:P 0 "register_operand" "a"))]
9814 "TARGET_INDIRECT_BRANCH_NOBP_JUMP_INLINE_THUNK
9817 s390_indirect_branch_via_inline_thunk (operands[1]);
9820 [(set_attr "op_type" "RIL")
9821 (set_attr "type" "branch")
9822 (set_attr "length" "10")])
9824 (define_insn "indirect_jump_via_inlinethunk<mode>"
9825 [(unspec [(if_then_else (match_operand:P 1 "larl_operand" "X")
9828 (match_operand:P 2 "register_operand" "a")] UNSPEC_EXECUTE_JUMP)
9829 (set (pc) (match_operand:P 0 "register_operand" "a"))]
9830 "TARGET_INDIRECT_BRANCH_NOBP_JUMP_INLINE_THUNK
9833 s390_indirect_branch_via_inline_thunk (operands[2]);
9836 [(set_attr "op_type" "RX")
9837 (set_attr "type" "branch")
9838 (set_attr "length" "8")])
9840 ; FIXME: LRA does not appear to be able to deal with MEMs being
9841 ; checked against address constraints like ZR above. So make this a
9842 ; separate pattern for now.
9843 (define_insn "*indirect2_jump"
9845 (match_operand 0 "nonimmediate_operand" "a,T"))]
9846 "!TARGET_INDIRECT_BRANCH_NOBP_JUMP"
9850 [(set_attr "op_type" "RR,RXY")
9851 (set_attr "type" "branch")
9852 (set_attr "atype" "agen")
9853 (set_attr "cpu_facility" "*,arch12")])
9856 ; casesi instruction pattern(s).
9859 (define_expand "casesi_jump"
9861 [(set (pc) (match_operand 0 "address_operand"))
9862 (use (label_ref (match_operand 1 "")))])]
9865 if (TARGET_INDIRECT_BRANCH_NOBP_JUMP_THUNK)
9867 operands[0] = force_reg (GET_MODE (operands[0]), operands[0]);
9872 emit_jump_insn (gen_casesi_jump_via_thunkdi_z10 (operands[0],
9875 emit_jump_insn (gen_casesi_jump_via_thunksi_z10 (operands[0],
9881 emit_jump_insn (gen_casesi_jump_via_thunkdi (operands[0],
9884 emit_jump_insn (gen_casesi_jump_via_thunksi (operands[0],
9890 if (TARGET_INDIRECT_BRANCH_NOBP_JUMP_INLINE_THUNK)
9892 operands[0] = force_reg (Pmode, operands[0]);
9893 rtx label_ref = gen_rtx_LABEL_REF (VOIDmode, gen_label_rtx ());
9897 emit_jump_insn (gen_casesi_jump_via_inlinethunkdi_z10 (operands[0],
9901 emit_jump_insn (gen_casesi_jump_via_inlinethunksi_z10 (operands[0],
9908 emit_jump_insn (gen_casesi_jump_via_inlinethunkdi (operands[0],
9911 force_reg (Pmode, label_ref)));
9913 emit_jump_insn (gen_casesi_jump_via_inlinethunksi (operands[0],
9916 force_reg (Pmode, label_ref)));
9922 (define_insn "*casesi_jump"
9923 [(set (pc) (match_operand 0 "address_operand" "ZR"))
9924 (use (label_ref (match_operand 1 "" "")))]
9925 "!TARGET_INDIRECT_BRANCH_NOBP_JUMP_THUNK"
9927 if (get_attr_op_type (insn) == OP_TYPE_RR)
9932 [(set (attr "op_type")
9933 (if_then_else (match_operand 0 "register_operand" "")
9934 (const_string "RR") (const_string "RX")))
9935 (set (attr "mnemonic")
9936 (if_then_else (match_operand 0 "register_operand" "")
9937 (const_string "br") (const_string "b")))
9938 (set_attr "type" "branch")
9939 (set_attr "atype" "agen")])
9941 (define_insn "casesi_jump_via_thunk<mode>_z10"
9942 [(set (pc) (match_operand:P 0 "register_operand" "a"))
9943 (use (label_ref (match_operand 1 "" "")))]
9944 "TARGET_INDIRECT_BRANCH_NOBP_JUMP_THUNK
9947 s390_indirect_branch_via_thunk (REGNO (operands[0]),
9950 s390_indirect_branch_type_jump);
9953 [(set_attr "op_type" "RIL")
9954 (set_attr "mnemonic" "jg")
9955 (set_attr "type" "branch")
9956 (set_attr "atype" "agen")])
9958 (define_insn "casesi_jump_via_thunk<mode>"
9959 [(set (pc) (match_operand:P 0 "register_operand" "a"))
9960 (use (label_ref (match_operand 1 "" "")))
9961 (clobber (reg:P INDIRECT_BRANCH_THUNK_REGNUM))]
9962 "TARGET_INDIRECT_BRANCH_NOBP_JUMP_THUNK
9965 s390_indirect_branch_via_thunk (REGNO (operands[0]),
9968 s390_indirect_branch_type_jump);
9971 [(set_attr "op_type" "RIL")
9972 (set_attr "mnemonic" "jg")
9973 (set_attr "type" "branch")
9974 (set_attr "atype" "agen")])
9977 ; The label_ref is wrapped into an if_then_else in order to hide it
9978 ; from mark_jump_label. Without this the label_ref would become the
9979 ; ONLY jump target of that jump breaking the control flow graph.
9980 (define_insn "casesi_jump_via_inlinethunk<mode>_z10"
9981 [(unspec [(if_then_else (match_operand:P 2 "larl_operand" "X")
9984 (const_int 0)] UNSPEC_EXECUTE_JUMP)
9985 (set (pc) (match_operand:P 0 "register_operand" "a"))
9986 (use (label_ref (match_operand 1 "" "")))]
9987 "TARGET_INDIRECT_BRANCH_NOBP_JUMP_INLINE_THUNK
9990 s390_indirect_branch_via_inline_thunk (operands[2]);
9993 [(set_attr "op_type" "RIL")
9994 (set_attr "type" "cs")
9995 (set_attr "length" "10")])
9997 (define_insn "casesi_jump_via_inlinethunk<mode>"
9998 [(unspec [(if_then_else (match_operand:P 2 "larl_operand" "X")
10001 (match_operand:P 3 "register_operand" "a")] UNSPEC_EXECUTE_JUMP)
10002 (set (pc) (match_operand:P 0 "register_operand" "a"))
10003 (use (label_ref (match_operand 1 "" "")))]
10004 "TARGET_INDIRECT_BRANCH_NOBP_JUMP_INLINE_THUNK
10005 && !TARGET_CPU_Z10"
10007 s390_indirect_branch_via_inline_thunk (operands[3]);
10010 [(set_attr "op_type" "RX")
10011 (set_attr "type" "cs")
10012 (set_attr "length" "8")])
10014 (define_expand "casesi"
10015 [(match_operand:SI 0 "general_operand" "")
10016 (match_operand:SI 1 "general_operand" "")
10017 (match_operand:SI 2 "general_operand" "")
10018 (label_ref (match_operand 3 "" ""))
10019 (label_ref (match_operand 4 "" ""))]
10022 rtx index = gen_reg_rtx (SImode);
10023 rtx base = gen_reg_rtx (Pmode);
10024 rtx target = gen_reg_rtx (Pmode);
10026 emit_move_insn (index, operands[0]);
10027 emit_insn (gen_subsi3 (index, index, operands[1]));
10028 emit_cmp_and_jump_insns (index, operands[2], GTU, NULL_RTX, SImode, 1,
10031 if (Pmode != SImode)
10032 index = convert_to_mode (Pmode, index, 1);
10033 if (GET_CODE (index) != REG)
10034 index = copy_to_mode_reg (Pmode, index);
10037 emit_insn (gen_ashldi3 (index, index, GEN_INT (3)));
10039 emit_insn (gen_ashlsi3 (index, index, const2_rtx));
10041 emit_move_insn (base, gen_rtx_LABEL_REF (Pmode, operands[3]));
10043 index = gen_const_mem (Pmode, gen_rtx_PLUS (Pmode, base, index));
10044 emit_move_insn (target, index);
10047 target = gen_rtx_PLUS (Pmode, base, target);
10048 emit_jump_insn (gen_casesi_jump (target, operands[3]));
10055 ;;- Jump to subroutine.
10060 ; untyped call instruction pattern(s).
10063 ;; Call subroutine returning any type.
10064 (define_expand "untyped_call"
10065 [(parallel [(call (match_operand 0 "" "")
10067 (match_operand 1 "" "")
10068 (match_operand 2 "" "")])]
10073 emit_call_insn (gen_call (operands[0], const0_rtx, const0_rtx));
10075 for (i = 0; i < XVECLEN (operands[2], 0); i++)
10077 rtx set = XVECEXP (operands[2], 0, i);
10078 emit_move_insn (SET_DEST (set), SET_SRC (set));
10081 /* The optimizer does not know that the call sets the function value
10082 registers we stored in the result block. We avoid problems by
10083 claiming that all hard registers are used and clobbered at this
10085 emit_insn (gen_blockage ());
10090 ;; UNSPEC_VOLATILE is considered to use and clobber all hard registers and
10091 ;; all of memory. This blocks insns from being moved across this point.
10093 (define_insn "blockage"
10094 [(unspec_volatile [(const_int 0)] UNSPECV_BLOCKAGE)]
10097 [(set_attr "type" "none")
10098 (set_attr "length" "0")])
10104 (define_expand "sibcall"
10105 [(call (match_operand 0 "" "")
10106 (match_operand 1 "" ""))]
10109 s390_emit_call (XEXP (operands[0], 0), NULL_RTX, NULL_RTX, NULL_RTX);
10113 (define_insn "*sibcall_br"
10114 [(call (mem:QI (reg SIBCALL_REGNUM))
10115 (match_operand 0 "const_int_operand" "n"))]
10116 "SIBLING_CALL_P (insn)
10117 && GET_MODE (XEXP (XEXP (PATTERN (insn), 0), 0)) == Pmode"
10119 if (TARGET_INDIRECT_BRANCH_NOBP_CALL)
10121 gcc_assert (TARGET_CPU_Z10);
10122 s390_indirect_branch_via_thunk (SIBCALL_REGNUM,
10125 s390_indirect_branch_type_call);
10131 [(set (attr "op_type")
10132 (if_then_else (match_test "TARGET_INDIRECT_BRANCH_NOBP_CALL")
10133 (const_string "RIL")
10134 (const_string "RR")))
10135 (set (attr "mnemonic")
10136 (if_then_else (match_test "TARGET_INDIRECT_BRANCH_NOBP_CALL")
10137 (const_string "jg")
10138 (const_string "br")))
10139 (set_attr "type" "branch")
10140 (set_attr "atype" "agen")])
10142 (define_insn "*sibcall_brc"
10143 [(call (mem:QI (match_operand 0 "bras_sym_operand" "X"))
10144 (match_operand 1 "const_int_operand" "n"))]
10145 "SIBLING_CALL_P (insn) && TARGET_SMALL_EXEC"
10147 [(set_attr "op_type" "RI")
10148 (set_attr "type" "branch")])
10150 (define_insn "*sibcall_brcl"
10151 [(call (mem:QI (match_operand 0 "bras_sym_operand" "X"))
10152 (match_operand 1 "const_int_operand" "n"))]
10153 "SIBLING_CALL_P (insn) && TARGET_CPU_ZARCH"
10155 [(set_attr "op_type" "RIL")
10156 (set_attr "type" "branch")])
10159 ; sibcall_value patterns
10162 (define_expand "sibcall_value"
10163 [(set (match_operand 0 "" "")
10164 (call (match_operand 1 "" "")
10165 (match_operand 2 "" "")))]
10168 s390_emit_call (XEXP (operands[1], 0), NULL_RTX, operands[0], NULL_RTX);
10172 (define_insn "*sibcall_value_br"
10173 [(set (match_operand 0 "" "")
10174 (call (mem:QI (reg SIBCALL_REGNUM))
10175 (match_operand 1 "const_int_operand" "n")))]
10176 "SIBLING_CALL_P (insn)
10177 && GET_MODE (XEXP (XEXP (XEXP (PATTERN (insn), 1), 0), 0)) == Pmode"
10179 if (TARGET_INDIRECT_BRANCH_NOBP_CALL)
10181 gcc_assert (TARGET_CPU_Z10);
10182 s390_indirect_branch_via_thunk (SIBCALL_REGNUM,
10185 s390_indirect_branch_type_call);
10191 [(set (attr "op_type")
10192 (if_then_else (match_test "TARGET_INDIRECT_BRANCH_NOBP_CALL")
10193 (const_string "RIL")
10194 (const_string "RR")))
10195 (set (attr "mnemonic")
10196 (if_then_else (match_test "TARGET_INDIRECT_BRANCH_NOBP_CALL")
10197 (const_string "jg")
10198 (const_string "br")))
10199 (set_attr "type" "branch")
10200 (set_attr "atype" "agen")])
10202 (define_insn "*sibcall_value_brc"
10203 [(set (match_operand 0 "" "")
10204 (call (mem:QI (match_operand 1 "bras_sym_operand" "X"))
10205 (match_operand 2 "const_int_operand" "n")))]
10206 "SIBLING_CALL_P (insn) && TARGET_SMALL_EXEC"
10208 [(set_attr "op_type" "RI")
10209 (set_attr "type" "branch")])
10211 (define_insn "*sibcall_value_brcl"
10212 [(set (match_operand 0 "" "")
10213 (call (mem:QI (match_operand 1 "bras_sym_operand" "X"))
10214 (match_operand 2 "const_int_operand" "n")))]
10215 "SIBLING_CALL_P (insn) && TARGET_CPU_ZARCH"
10217 [(set_attr "op_type" "RIL")
10218 (set_attr "type" "branch")])
10222 ; call instruction pattern(s).
10225 (define_expand "call"
10226 [(call (match_operand 0 "" "")
10227 (match_operand 1 "" ""))
10228 (use (match_operand 2 "" ""))]
10231 s390_emit_call (XEXP (operands[0], 0), NULL_RTX, NULL_RTX,
10232 gen_rtx_REG (Pmode, RETURN_REGNUM));
10236 (define_insn "*bras"
10237 [(call (mem:QI (match_operand 0 "bras_sym_operand" "X"))
10238 (match_operand 1 "const_int_operand" "n"))
10239 (clobber (match_operand 2 "register_operand" "=r"))]
10240 "!SIBLING_CALL_P (insn)
10241 && TARGET_SMALL_EXEC
10242 && GET_MODE (operands[2]) == Pmode"
10244 [(set_attr "op_type" "RI")
10245 (set_attr "type" "jsr")
10246 (set_attr "z196prop" "z196_cracked")])
10248 (define_insn "*brasl"
10249 [(call (mem:QI (match_operand 0 "bras_sym_operand" "X"))
10250 (match_operand 1 "const_int_operand" "n"))
10251 (clobber (match_operand 2 "register_operand" "=r"))]
10252 "!SIBLING_CALL_P (insn)
10253 && TARGET_CPU_ZARCH
10254 && GET_MODE (operands[2]) == Pmode"
10256 [(set_attr "op_type" "RIL")
10257 (set_attr "type" "jsr")
10258 (set_attr "z196prop" "z196_cracked")])
10260 (define_insn "*basr"
10261 [(call (mem:QI (match_operand 0 "address_operand" "ZR"))
10262 (match_operand 1 "const_int_operand" "n"))
10263 (clobber (match_operand 2 "register_operand" "=r"))]
10264 "!TARGET_INDIRECT_BRANCH_NOBP_CALL
10265 && !SIBLING_CALL_P (insn)
10266 && GET_MODE (operands[2]) == Pmode"
10268 if (get_attr_op_type (insn) == OP_TYPE_RR)
10269 return "basr\t%2,%0";
10271 return "bas\t%2,%a0";
10273 [(set (attr "op_type")
10274 (if_then_else (match_operand 0 "register_operand" "")
10275 (const_string "RR") (const_string "RX")))
10276 (set (attr "mnemonic")
10277 (if_then_else (match_operand 0 "register_operand" "")
10278 (const_string "basr") (const_string "bas")))
10279 (set_attr "type" "jsr")
10280 (set_attr "atype" "agen")
10281 (set_attr "z196prop" "z196_cracked")])
10283 (define_insn "*basr_via_thunk<mode>_z10"
10284 [(call (mem:QI (match_operand:P 0 "register_operand" "a"))
10285 (match_operand 1 "const_int_operand" "n"))
10286 (clobber (match_operand:P 2 "register_operand" "=&r"))]
10287 "TARGET_INDIRECT_BRANCH_NOBP_CALL
10289 && !SIBLING_CALL_P (insn)"
10291 s390_indirect_branch_via_thunk (REGNO (operands[0]),
10292 REGNO (operands[2]),
10294 s390_indirect_branch_type_call);
10297 [(set_attr "op_type" "RIL")
10298 (set_attr "mnemonic" "brasl")
10299 (set_attr "type" "jsr")
10300 (set_attr "atype" "agen")
10301 (set_attr "z196prop" "z196_cracked")])
10303 (define_insn "*basr_via_thunk<mode>"
10304 [(call (mem:QI (match_operand:P 0 "register_operand" "a"))
10305 (match_operand 1 "const_int_operand" "n"))
10306 (clobber (match_operand:P 2 "register_operand" "=&r"))
10307 (clobber (reg:P INDIRECT_BRANCH_THUNK_REGNUM))]
10308 "TARGET_INDIRECT_BRANCH_NOBP_CALL
10310 && !SIBLING_CALL_P (insn)"
10312 s390_indirect_branch_via_thunk (REGNO (operands[0]),
10313 REGNO (operands[2]),
10315 s390_indirect_branch_type_call);
10318 [(set_attr "op_type" "RIL")
10319 (set_attr "mnemonic" "brasl")
10320 (set_attr "type" "jsr")
10321 (set_attr "atype" "agen")
10322 (set_attr "z196prop" "z196_cracked")])
10325 ; call_value instruction pattern(s).
10328 (define_expand "call_value"
10329 [(set (match_operand 0 "" "")
10330 (call (match_operand 1 "" "")
10331 (match_operand 2 "" "")))
10332 (use (match_operand 3 "" ""))]
10335 s390_emit_call (XEXP (operands[1], 0), NULL_RTX, operands[0],
10336 gen_rtx_REG (Pmode, RETURN_REGNUM));
10340 (define_insn "*bras_r"
10341 [(set (match_operand 0 "" "")
10342 (call (mem:QI (match_operand 1 "bras_sym_operand" "X"))
10343 (match_operand:SI 2 "const_int_operand" "n")))
10344 (clobber (match_operand 3 "register_operand" "=r"))]
10345 "!SIBLING_CALL_P (insn)
10346 && TARGET_SMALL_EXEC
10347 && GET_MODE (operands[3]) == Pmode"
10349 [(set_attr "op_type" "RI")
10350 (set_attr "type" "jsr")
10351 (set_attr "z196prop" "z196_cracked")])
10353 (define_insn "*brasl_r"
10354 [(set (match_operand 0 "" "")
10355 (call (mem:QI (match_operand 1 "bras_sym_operand" "X"))
10356 (match_operand 2 "const_int_operand" "n")))
10357 (clobber (match_operand 3 "register_operand" "=r"))]
10358 "!SIBLING_CALL_P (insn)
10359 && TARGET_CPU_ZARCH
10360 && GET_MODE (operands[3]) == Pmode"
10362 [(set_attr "op_type" "RIL")
10363 (set_attr "type" "jsr")
10364 (set_attr "z196prop" "z196_cracked")])
10366 (define_insn "*basr_r"
10367 [(set (match_operand 0 "" "")
10368 (call (mem:QI (match_operand 1 "address_operand" "ZR"))
10369 (match_operand 2 "const_int_operand" "n")))
10370 (clobber (match_operand 3 "register_operand" "=r"))]
10371 "!TARGET_INDIRECT_BRANCH_NOBP_CALL
10372 && !SIBLING_CALL_P (insn)
10373 && GET_MODE (operands[3]) == Pmode"
10375 if (get_attr_op_type (insn) == OP_TYPE_RR)
10376 return "basr\t%3,%1";
10378 return "bas\t%3,%a1";
10380 [(set (attr "op_type")
10381 (if_then_else (match_operand 1 "register_operand" "")
10382 (const_string "RR") (const_string "RX")))
10383 (set (attr "mnemonic")
10384 (if_then_else (match_operand 1 "register_operand" "")
10385 (const_string "basr") (const_string "bas")))
10386 (set_attr "type" "jsr")
10387 (set_attr "atype" "agen")
10388 (set_attr "z196prop" "z196_cracked")])
10390 (define_insn "*basr_r_via_thunk_z10"
10391 [(set (match_operand 0 "" "")
10392 (call (mem:QI (match_operand 1 "register_operand" "a"))
10393 (match_operand 2 "const_int_operand" "n")))
10394 (clobber (match_operand 3 "register_operand" "=&r"))]
10395 "TARGET_INDIRECT_BRANCH_NOBP_CALL
10397 && !SIBLING_CALL_P (insn)
10398 && GET_MODE (operands[3]) == Pmode"
10400 s390_indirect_branch_via_thunk (REGNO (operands[1]),
10401 REGNO (operands[3]),
10403 s390_indirect_branch_type_call);
10406 [(set_attr "op_type" "RIL")
10407 (set_attr "mnemonic" "brasl")
10408 (set_attr "type" "jsr")
10409 (set_attr "atype" "agen")
10410 (set_attr "z196prop" "z196_cracked")])
10412 (define_insn "*basr_r_via_thunk"
10413 [(set (match_operand 0 "" "")
10414 (call (mem:QI (match_operand 1 "register_operand" "a"))
10415 (match_operand 2 "const_int_operand" "n")))
10416 (clobber (match_operand 3 "register_operand" "=&r"))
10417 (clobber (reg:P INDIRECT_BRANCH_THUNK_REGNUM))]
10418 "TARGET_INDIRECT_BRANCH_NOBP_CALL
10420 && !SIBLING_CALL_P (insn)
10421 && GET_MODE (operands[3]) == Pmode"
10423 s390_indirect_branch_via_thunk (REGNO (operands[1]),
10424 REGNO (operands[3]),
10426 s390_indirect_branch_type_call);
10429 [(set_attr "op_type" "RIL")
10430 (set_attr "mnemonic" "brasl")
10431 (set_attr "type" "jsr")
10432 (set_attr "atype" "agen")
10433 (set_attr "z196prop" "z196_cracked")])
10436 ;;- Thread-local storage support.
10439 (define_expand "get_thread_pointer<mode>"
10440 [(set (match_operand:P 0 "nonimmediate_operand" "") (reg:P TP_REGNUM))]
10444 (define_expand "set_thread_pointer<mode>"
10445 [(set (reg:P TP_REGNUM) (match_operand:P 0 "nonimmediate_operand" ""))
10446 (set (reg:P TP_REGNUM) (unspec_volatile:P [(reg:P TP_REGNUM)] UNSPECV_SET_TP))]
10450 (define_insn "*set_tp"
10451 [(set (reg TP_REGNUM) (unspec_volatile [(reg TP_REGNUM)] UNSPECV_SET_TP))]
10454 [(set_attr "type" "none")
10455 (set_attr "length" "0")])
10457 (define_insn "*tls_load_64"
10458 [(set (match_operand:DI 0 "register_operand" "=d")
10459 (unspec:DI [(match_operand:DI 1 "memory_operand" "T")
10460 (match_operand:DI 2 "" "")]
10464 [(set_attr "op_type" "RXE")
10465 (set_attr "z10prop" "z10_fwd_A3")])
10467 (define_insn "*tls_load_31"
10468 [(set (match_operand:SI 0 "register_operand" "=d,d")
10469 (unspec:SI [(match_operand:SI 1 "memory_operand" "R,T")
10470 (match_operand:SI 2 "" "")]
10476 [(set_attr "op_type" "RX,RXY")
10477 (set_attr "type" "load")
10478 (set_attr "cpu_facility" "*,longdisp")
10479 (set_attr "z10prop" "z10_fwd_A3,z10_fwd_A3")])
10481 (define_insn "*bras_tls"
10482 [(set (match_operand 0 "" "")
10483 (call (mem:QI (match_operand 1 "bras_sym_operand" "X"))
10484 (match_operand 2 "const_int_operand" "n")))
10485 (clobber (match_operand 3 "register_operand" "=r"))
10486 (use (match_operand 4 "" ""))]
10487 "!SIBLING_CALL_P (insn)
10488 && TARGET_SMALL_EXEC
10489 && GET_MODE (operands[3]) == Pmode"
10491 [(set_attr "op_type" "RI")
10492 (set_attr "type" "jsr")
10493 (set_attr "z196prop" "z196_cracked")])
10495 (define_insn "*brasl_tls"
10496 [(set (match_operand 0 "" "")
10497 (call (mem:QI (match_operand 1 "bras_sym_operand" "X"))
10498 (match_operand 2 "const_int_operand" "n")))
10499 (clobber (match_operand 3 "register_operand" "=r"))
10500 (use (match_operand 4 "" ""))]
10501 "!SIBLING_CALL_P (insn)
10502 && TARGET_CPU_ZARCH
10503 && GET_MODE (operands[3]) == Pmode"
10505 [(set_attr "op_type" "RIL")
10506 (set_attr "type" "jsr")
10507 (set_attr "z196prop" "z196_cracked")])
10509 (define_insn "*basr_tls"
10510 [(set (match_operand 0 "" "")
10511 (call (mem:QI (match_operand 1 "address_operand" "ZR"))
10512 (match_operand 2 "const_int_operand" "n")))
10513 (clobber (match_operand 3 "register_operand" "=r"))
10514 (use (match_operand 4 "" ""))]
10515 "!SIBLING_CALL_P (insn) && GET_MODE (operands[3]) == Pmode"
10517 if (get_attr_op_type (insn) == OP_TYPE_RR)
10518 return "basr\t%3,%1%J4";
10520 return "bas\t%3,%a1%J4";
10522 [(set (attr "op_type")
10523 (if_then_else (match_operand 1 "register_operand" "")
10524 (const_string "RR") (const_string "RX")))
10525 (set_attr "type" "jsr")
10526 (set_attr "atype" "agen")
10527 (set_attr "z196prop" "z196_cracked")])
10530 ;;- Atomic operations
10534 ; memory barrier patterns.
10537 (define_expand "mem_thread_fence"
10538 [(match_operand:SI 0 "const_int_operand")] ;; model
10541 /* Unless this is a SEQ_CST fence, the s390 memory model is strong
10542 enough not to require barriers of any kind. */
10543 if (is_mm_seq_cst (memmodel_from_int (INTVAL (operands[0]))))
10545 rtx mem = gen_rtx_MEM (BLKmode, gen_rtx_SCRATCH (Pmode));
10546 MEM_VOLATILE_P (mem) = 1;
10547 emit_insn (gen_mem_thread_fence_1 (mem));
10552 ; Although bcr is superscalar on Z10, this variant will never
10553 ; become part of an execution group.
10554 ; With z196 we can make use of the fast-BCR-serialization facility.
10555 ; This allows for a slightly faster sync which is sufficient for our
10557 (define_insn "mem_thread_fence_1"
10558 [(set (match_operand:BLK 0 "" "")
10559 (unspec:BLK [(match_dup 0)] UNSPEC_MB))]
10563 return "bcr\t14,0";
10565 return "bcr\t15,0";
10567 [(set_attr "op_type" "RR")
10568 (set_attr "mnemonic" "bcr_flush")
10569 (set_attr "z196prop" "z196_alone")])
10572 ; atomic load/store operations
10575 ; Atomic loads need not examine the memory model at all.
10576 (define_expand "atomic_load<mode>"
10577 [(match_operand:DINT 0 "register_operand") ;; output
10578 (match_operand:DINT 1 "memory_operand") ;; memory
10579 (match_operand:SI 2 "const_int_operand")] ;; model
10582 if (MEM_ALIGN (operands[1]) < GET_MODE_BITSIZE (GET_MODE (operands[1])))
10585 if (<MODE>mode == TImode)
10586 emit_insn (gen_atomic_loadti_1 (operands[0], operands[1]));
10587 else if (<MODE>mode == DImode && !TARGET_ZARCH)
10588 emit_insn (gen_atomic_loaddi_1 (operands[0], operands[1]));
10590 emit_move_insn (operands[0], operands[1]);
10594 ; Different from movdi_31 in that we want no splitters.
10595 (define_insn "atomic_loaddi_1"
10596 [(set (match_operand:DI 0 "register_operand" "=d,d,!*f,!*f")
10597 (unspec:DI [(match_operand:DI 1 "memory_operand" "Q,S,R,T")]
10605 [(set_attr "op_type" "RS,RSY,RS,RSY")
10606 (set_attr "cpu_facility" "*,longdisp,*,longdisp")
10607 (set_attr "type" "lm,lm,floaddf,floaddf")])
10609 (define_insn "atomic_loadti_1"
10610 [(set (match_operand:TI 0 "register_operand" "=r")
10611 (unspec:TI [(match_operand:TI 1 "memory_operand" "T")]
10615 [(set_attr "op_type" "RXY")
10616 (set_attr "type" "other")])
10618 ; Atomic stores must(?) enforce sequential consistency.
10619 (define_expand "atomic_store<mode>"
10620 [(match_operand:DINT 0 "memory_operand") ;; memory
10621 (match_operand:DINT 1 "register_operand") ;; input
10622 (match_operand:SI 2 "const_int_operand")] ;; model
10625 enum memmodel model = memmodel_from_int (INTVAL (operands[2]));
10627 if (MEM_ALIGN (operands[0]) < GET_MODE_BITSIZE (GET_MODE (operands[0])))
10630 if (<MODE>mode == TImode)
10631 emit_insn (gen_atomic_storeti_1 (operands[0], operands[1]));
10632 else if (<MODE>mode == DImode && !TARGET_ZARCH)
10633 emit_insn (gen_atomic_storedi_1 (operands[0], operands[1]));
10635 emit_move_insn (operands[0], operands[1]);
10636 if (is_mm_seq_cst (model))
10637 emit_insn (gen_mem_thread_fence (operands[2]));
10641 ; Different from movdi_31 in that we want no splitters.
10642 (define_insn "atomic_storedi_1"
10643 [(set (match_operand:DI 0 "memory_operand" "=Q,S,R,T")
10644 (unspec:DI [(match_operand:DI 1 "register_operand" "d,d,!*f,!*f")]
10652 [(set_attr "op_type" "RS,RSY,RS,RSY")
10653 (set_attr "cpu_facility" "*,longdisp,*,longdisp")
10654 (set_attr "type" "stm,stm,fstoredf,fstoredf")])
10656 (define_insn "atomic_storeti_1"
10657 [(set (match_operand:TI 0 "memory_operand" "=T")
10658 (unspec:TI [(match_operand:TI 1 "register_operand" "r")]
10662 [(set_attr "op_type" "RXY")
10663 (set_attr "type" "other")])
10666 ; compare and swap patterns.
10669 (define_expand "atomic_compare_and_swap<mode>"
10670 [(match_operand:SI 0 "register_operand") ;; bool success output
10671 (match_operand:DINT 1 "nonimmediate_operand");; oldval output
10672 (match_operand:DINT 2 "s_operand") ;; memory
10673 (match_operand:DINT 3 "general_operand") ;; expected intput
10674 (match_operand:DINT 4 "general_operand") ;; newval intput
10675 (match_operand:SI 5 "const_int_operand") ;; is_weak
10676 (match_operand:SI 6 "const_int_operand") ;; success model
10677 (match_operand:SI 7 "const_int_operand")] ;; failure model
10680 if (GET_MODE_BITSIZE (<MODE>mode) >= 16
10681 && GET_MODE_BITSIZE (<MODE>mode) > MEM_ALIGN (operands[2]))
10684 s390_expand_cs (<MODE>mode, operands[0], operands[1], operands[2],
10685 operands[3], operands[4], INTVAL (operands[5]));
10688 (define_expand "atomic_compare_and_swap<mode>_internal"
10690 [(set (match_operand:DGPR 0 "register_operand")
10691 (match_operand:DGPR 1 "s_operand"))
10693 (unspec_volatile:DGPR
10695 (match_operand:DGPR 2 "register_operand")
10696 (match_operand:DGPR 3 "register_operand")]
10698 (set (match_operand 4 "cc_reg_operand")
10700 "GET_MODE (operands[4]) == CCZmode
10701 || GET_MODE (operands[4]) == CCZ1mode"
10704 = gen_rtx_COMPARE (GET_MODE (operands[4]), operands[1], operands[2]);
10708 (define_insn "*atomic_compare_and_swap<mode>_1"
10709 [(set (match_operand:TDI 0 "register_operand" "=r")
10710 (match_operand:TDI 1 "memory_operand" "+S"))
10712 (unspec_volatile:TDI
10714 (match_operand:TDI 2 "register_operand" "0")
10715 (match_operand:TDI 3 "register_operand" "r")]
10717 (set (reg CC_REGNUM)
10718 (compare (match_dup 1) (match_dup 2)))]
10720 && s390_match_ccmode (insn, CCZ1mode)"
10721 "c<td>sg\t%0,%3,%S1"
10722 [(set_attr "op_type" "RSY")
10723 (set_attr "type" "sem")])
10726 (define_insn "*atomic_compare_and_swapdi_2"
10727 [(set (match_operand:DI 0 "register_operand" "=r,r")
10728 (match_operand:DI 1 "memory_operand" "+Q,S"))
10730 (unspec_volatile:DI
10732 (match_operand:DI 2 "register_operand" "0,0")
10733 (match_operand:DI 3 "register_operand" "r,r")]
10735 (set (reg CC_REGNUM)
10736 (compare (match_dup 1) (match_dup 2)))]
10738 && s390_match_ccmode (insn, CCZ1mode)"
10742 [(set_attr "op_type" "RS,RSY")
10743 (set_attr "cpu_facility" "*,longdisp")
10744 (set_attr "type" "sem")])
10747 (define_insn "*atomic_compare_and_swapsi_3"
10748 [(set (match_operand:SI 0 "register_operand" "=r,r")
10749 (match_operand:SI 1 "memory_operand" "+Q,S"))
10751 (unspec_volatile:SI
10753 (match_operand:SI 2 "register_operand" "0,0")
10754 (match_operand:SI 3 "register_operand" "r,r")]
10756 (set (reg CC_REGNUM)
10757 (compare (match_dup 1) (match_dup 2)))]
10758 "s390_match_ccmode (insn, CCZ1mode)"
10762 [(set_attr "op_type" "RS,RSY")
10763 (set_attr "cpu_facility" "*,longdisp")
10764 (set_attr "type" "sem")])
10767 ; Other atomic instruction patterns.
10770 ; z196 load and add, xor, or and and instructions
10772 (define_expand "atomic_fetch_<atomic><mode>"
10773 [(match_operand:GPR 0 "register_operand") ;; val out
10775 (match_operand:GPR 1 "memory_operand") ;; memory
10776 (match_operand:GPR 2 "register_operand")) ;; val in
10777 (match_operand:SI 3 "const_int_operand")] ;; model
10780 if (MEM_ALIGN (operands[1]) < GET_MODE_BITSIZE (GET_MODE (operands[1])))
10783 emit_insn (gen_atomic_fetch_<atomic><mode>_iaf
10784 (operands[0], operands[1], operands[2]));
10788 ; lan, lang, lao, laog, lax, laxg, laa, laag
10789 (define_insn "atomic_fetch_<atomic><mode>_iaf"
10790 [(set (match_operand:GPR 0 "register_operand" "=d")
10791 (match_operand:GPR 1 "memory_operand" "+S"))
10793 (unspec_volatile:GPR
10794 [(ATOMIC_Z196:GPR (match_dup 1)
10795 (match_operand:GPR 2 "general_operand" "d"))]
10796 UNSPECV_ATOMIC_OP))
10797 (clobber (reg:CC CC_REGNUM))]
10799 "la<noxa><g>\t%0,%2,%1"
10800 [(set_attr "op_type" "RSY")
10801 (set_attr "type" "sem")])
10803 ;; For SImode and larger, the optabs.c code will do just fine in
10804 ;; expanding a compare-and-swap loop. For QI/HImode, we can do
10805 ;; better by expanding our own loop.
10807 (define_expand "atomic_<atomic><mode>"
10809 (match_operand:HQI 0 "memory_operand") ;; memory
10810 (match_operand:HQI 1 "general_operand")) ;; val in
10811 (match_operand:SI 2 "const_int_operand")] ;; model
10814 s390_expand_atomic (<MODE>mode, <CODE>, NULL_RTX, operands[0],
10815 operands[1], false);
10819 (define_expand "atomic_fetch_<atomic><mode>"
10820 [(match_operand:HQI 0 "register_operand") ;; val out
10822 (match_operand:HQI 1 "memory_operand") ;; memory
10823 (match_operand:HQI 2 "general_operand")) ;; val in
10824 (match_operand:SI 3 "const_int_operand")] ;; model
10827 s390_expand_atomic (<MODE>mode, <CODE>, operands[0], operands[1],
10828 operands[2], false);
10832 (define_expand "atomic_<atomic>_fetch<mode>"
10833 [(match_operand:HQI 0 "register_operand") ;; val out
10835 (match_operand:HQI 1 "memory_operand") ;; memory
10836 (match_operand:HQI 2 "general_operand")) ;; val in
10837 (match_operand:SI 3 "const_int_operand")] ;; model
10840 s390_expand_atomic (<MODE>mode, <CODE>, operands[0], operands[1],
10841 operands[2], true);
10845 ;; Pattern to implement atomic_exchange with a compare-and-swap loop. The code
10846 ;; generated by the middleend is not good.
10847 (define_expand "atomic_exchange<mode>"
10848 [(match_operand:DINT 0 "register_operand") ;; val out
10849 (match_operand:DINT 1 "s_operand") ;; memory
10850 (match_operand:DINT 2 "general_operand") ;; val in
10851 (match_operand:SI 3 "const_int_operand")] ;; model
10854 if (<MODE>mode != QImode
10855 && MEM_ALIGN (operands[1]) < GET_MODE_BITSIZE (<MODE>mode))
10857 if (<MODE>mode == HImode || <MODE>mode == QImode)
10858 s390_expand_atomic (<MODE>mode, SET, operands[0], operands[1], operands[2],
10860 else if (<MODE>mode == SImode || TARGET_ZARCH)
10861 s390_expand_atomic_exchange_tdsi (operands[0], operands[1], operands[2]);
10868 ;;- Miscellaneous instructions.
10872 ; allocate stack instruction pattern(s).
10875 (define_expand "allocate_stack"
10876 [(match_operand 0 "general_operand" "")
10877 (match_operand 1 "general_operand" "")]
10880 rtx temp = gen_reg_rtx (Pmode);
10882 emit_move_insn (temp, s390_back_chain_rtx ());
10883 anti_adjust_stack (operands[1]);
10884 emit_move_insn (s390_back_chain_rtx (), temp);
10886 emit_move_insn (operands[0], virtual_stack_dynamic_rtx);
10892 ; setjmp instruction pattern.
10895 (define_expand "builtin_setjmp_receiver"
10896 [(match_operand 0 "" "")]
10899 emit_insn (s390_load_got ());
10900 emit_use (pic_offset_table_rtx);
10904 ;; These patterns say how to save and restore the stack pointer. We need not
10905 ;; save the stack pointer at function level since we are careful to
10906 ;; preserve the backchain. At block level, we have to restore the backchain
10907 ;; when we restore the stack pointer.
10909 ;; For nonlocal gotos, we must save both the stack pointer and its
10910 ;; backchain and restore both. Note that in the nonlocal case, the
10911 ;; save area is a memory location.
10913 (define_expand "save_stack_function"
10914 [(match_operand 0 "general_operand" "")
10915 (match_operand 1 "general_operand" "")]
10919 (define_expand "restore_stack_function"
10920 [(match_operand 0 "general_operand" "")
10921 (match_operand 1 "general_operand" "")]
10925 (define_expand "restore_stack_block"
10926 [(match_operand 0 "register_operand" "")
10927 (match_operand 1 "register_operand" "")]
10930 rtx temp = gen_reg_rtx (Pmode);
10932 emit_move_insn (temp, s390_back_chain_rtx ());
10933 emit_move_insn (operands[0], operands[1]);
10934 emit_move_insn (s390_back_chain_rtx (), temp);
10939 (define_expand "save_stack_nonlocal"
10940 [(match_operand 0 "memory_operand" "")
10941 (match_operand 1 "register_operand" "")]
10944 rtx base = gen_rtx_REG (Pmode, BASE_REGNUM);
10946 /* Copy the backchain to the first word, sp to the second and the
10947 literal pool base to the third. */
10949 rtx save_bc = adjust_address (operands[0], Pmode, 0);
10950 rtx save_sp = adjust_address (operands[0], Pmode, GET_MODE_SIZE (Pmode));
10951 rtx save_bp = adjust_address (operands[0], Pmode, 2 * GET_MODE_SIZE (Pmode));
10953 if (TARGET_BACKCHAIN)
10954 emit_move_insn (save_bc, force_reg (Pmode, s390_back_chain_rtx ()));
10956 emit_move_insn (save_sp, operands[1]);
10957 emit_move_insn (save_bp, base);
10962 (define_expand "restore_stack_nonlocal"
10963 [(match_operand 0 "register_operand" "")
10964 (match_operand 1 "memory_operand" "")]
10967 rtx base = gen_rtx_REG (Pmode, BASE_REGNUM);
10968 rtx temp = NULL_RTX;
10970 /* Restore the backchain from the first word, sp from the second and the
10971 literal pool base from the third. */
10973 rtx save_bc = adjust_address (operands[1], Pmode, 0);
10974 rtx save_sp = adjust_address (operands[1], Pmode, GET_MODE_SIZE (Pmode));
10975 rtx save_bp = adjust_address (operands[1], Pmode, 2 * GET_MODE_SIZE (Pmode));
10977 if (TARGET_BACKCHAIN)
10978 temp = force_reg (Pmode, save_bc);
10980 emit_move_insn (base, save_bp);
10981 emit_move_insn (operands[0], save_sp);
10984 emit_move_insn (s390_back_chain_rtx (), temp);
10990 (define_expand "exception_receiver"
10994 s390_set_has_landing_pad_p (true);
10999 ; nop instruction pattern(s).
11006 [(set_attr "op_type" "RR")])
11008 ; non-branch NOPs required for optimizing compare-and-branch patterns
11011 (define_insn "nop_lr0"
11012 [(unspec_volatile [(const_int 0)] UNSPECV_NOP_LR_0)]
11015 [(set_attr "op_type" "RR")
11016 (set_attr "z10prop" "z10_fr_E1")])
11018 (define_insn "nop_lr1"
11019 [(unspec_volatile [(const_int 0)] UNSPECV_NOP_LR_1)]
11022 [(set_attr "op_type" "RR")])
11024 ;;- Undeletable nops (used for hotpatching)
11026 (define_insn "nop_2_byte"
11027 [(unspec_volatile [(const_int 0)] UNSPECV_NOP_2_BYTE)]
11030 [(set_attr "op_type" "RR")])
11032 (define_insn "nop_4_byte"
11033 [(unspec_volatile [(const_int 0)] UNSPECV_NOP_4_BYTE)]
11036 [(set_attr "op_type" "RX")])
11038 (define_insn "nop_6_byte"
11039 [(unspec_volatile [(const_int 0)] UNSPECV_NOP_6_BYTE)]
11042 [(set_attr "op_type" "RIL")])
11046 ; Special literal pool access instruction pattern(s).
11049 (define_insn "*pool_entry"
11050 [(unspec_volatile [(match_operand 0 "consttable_operand" "X")]
11051 UNSPECV_POOL_ENTRY)]
11054 machine_mode mode = GET_MODE (PATTERN (insn));
11055 unsigned int align = GET_MODE_BITSIZE (mode);
11056 s390_output_pool_entry (operands[0], mode, align);
11059 [(set (attr "length")
11060 (symbol_ref "GET_MODE_SIZE (GET_MODE (PATTERN (insn)))"))])
11062 (define_insn "pool_align"
11063 [(unspec_volatile [(match_operand 0 "const_int_operand" "n")]
11064 UNSPECV_POOL_ALIGN)]
11067 [(set (attr "length") (symbol_ref "INTVAL (operands[0])"))])
11069 (define_insn "pool_section_start"
11070 [(unspec_volatile [(const_int 1)] UNSPECV_POOL_SECTION)]
11073 switch_to_section (targetm.asm_out.function_rodata_section
11074 (current_function_decl));
11077 [(set_attr "length" "0")])
11079 (define_insn "pool_section_end"
11080 [(unspec_volatile [(const_int 0)] UNSPECV_POOL_SECTION)]
11083 switch_to_section (current_function_section ());
11086 [(set_attr "length" "0")])
11088 (define_insn "main_base_31_small"
11089 [(set (match_operand 0 "register_operand" "=a")
11090 (unspec [(label_ref (match_operand 1 "" ""))] UNSPEC_MAIN_BASE))]
11091 "!TARGET_CPU_ZARCH && GET_MODE (operands[0]) == Pmode"
11093 [(set_attr "op_type" "RR")
11094 (set_attr "type" "la")
11095 (set_attr "z196prop" "z196_cracked")])
11097 (define_insn "main_base_31_large"
11098 [(set (match_operand 0 "register_operand" "=a")
11099 (unspec [(label_ref (match_operand 1 "" ""))] UNSPEC_MAIN_BASE))
11100 (set (pc) (label_ref (match_operand 2 "" "")))]
11101 "!TARGET_CPU_ZARCH && GET_MODE (operands[0]) == Pmode"
11103 [(set_attr "op_type" "RI")
11104 (set_attr "z196prop" "z196_cracked")])
11106 (define_insn "main_base_64"
11107 [(set (match_operand 0 "register_operand" "=a")
11108 (unspec [(label_ref (match_operand 1 "" ""))] UNSPEC_MAIN_BASE))]
11109 "TARGET_CPU_ZARCH && GET_MODE (operands[0]) == Pmode"
11111 [(set_attr "op_type" "RIL")
11112 (set_attr "type" "larl")
11113 (set_attr "z10prop" "z10_fwd_A1")])
11115 (define_insn "main_pool"
11116 [(set (match_operand 0 "register_operand" "=a")
11117 (unspec_volatile [(const_int 0)] UNSPECV_MAIN_POOL))]
11118 "GET_MODE (operands[0]) == Pmode"
11120 gcc_unreachable ();
11122 [(set (attr "type")
11123 (if_then_else (match_test "TARGET_CPU_ZARCH")
11124 (const_string "larl") (const_string "la")))])
11126 (define_insn "reload_base_31"
11127 [(set (match_operand 0 "register_operand" "=a")
11128 (unspec [(label_ref (match_operand 1 "" ""))] UNSPEC_RELOAD_BASE))]
11129 "!TARGET_CPU_ZARCH && GET_MODE (operands[0]) == Pmode"
11130 "basr\t%0,0\;la\t%0,%1-.(%0)"
11131 [(set_attr "length" "6")
11132 (set_attr "type" "la")
11133 (set_attr "z196prop" "z196_cracked")])
11135 (define_insn "reload_base_64"
11136 [(set (match_operand 0 "register_operand" "=a")
11137 (unspec [(label_ref (match_operand 1 "" ""))] UNSPEC_RELOAD_BASE))]
11138 "TARGET_CPU_ZARCH && GET_MODE (operands[0]) == Pmode"
11140 [(set_attr "op_type" "RIL")
11141 (set_attr "type" "larl")
11142 (set_attr "z10prop" "z10_fwd_A1")])
11144 (define_insn "pool"
11145 [(unspec_volatile [(match_operand 0 "const_int_operand" "n")] UNSPECV_POOL)]
11148 gcc_unreachable ();
11150 [(set (attr "length") (symbol_ref "INTVAL (operands[0])"))])
11153 ;; Insns related to generating the function prologue and epilogue.
11157 (define_expand "prologue"
11158 [(use (const_int 0))]
11160 "s390_emit_prologue (); DONE;")
11162 (define_expand "epilogue"
11163 [(use (const_int 1))]
11165 "s390_emit_epilogue (false); DONE;")
11167 (define_expand "sibcall_epilogue"
11168 [(use (const_int 0))]
11170 "s390_emit_epilogue (true); DONE;")
11172 ;; A direct return instruction, without using an epilogue.
11173 (define_insn "<code>"
11175 "s390_can_use_<code>_insn ()"
11177 if (TARGET_INDIRECT_BRANCH_NOBP_RET)
11179 /* The target is always r14 so there is no clobber
11180 of r1 needed for pre z10 targets. */
11181 s390_indirect_branch_via_thunk (RETURN_REGNUM,
11184 s390_indirect_branch_type_return);
11188 return "br\t%%r14";
11190 [(set (attr "op_type")
11191 (if_then_else (match_test "TARGET_INDIRECT_BRANCH_NOBP_RET")
11192 (const_string "RIL")
11193 (const_string "RR")))
11194 (set (attr "mnemonic")
11195 (if_then_else (match_test "TARGET_INDIRECT_BRANCH_NOBP_RET")
11196 (const_string "jg")
11197 (const_string "br")))
11198 (set_attr "type" "jsr")
11199 (set_attr "atype" "agen")])
11202 (define_expand "return_use"
11205 (use (match_operand 0 "register_operand" "a"))])]
11208 if (!TARGET_CPU_Z10
11209 && TARGET_INDIRECT_BRANCH_NOBP_RET_OPTION)
11212 emit_jump_insn (gen_returndi_prez10 (operands[0]));
11214 emit_jump_insn (gen_returnsi_prez10 (operands[0]));
11219 (define_insn "*return<mode>"
11221 (use (match_operand:P 0 "register_operand" "a"))]
11222 "TARGET_CPU_Z10 || !TARGET_INDIRECT_BRANCH_NOBP_RET_OPTION"
11224 if (TARGET_INDIRECT_BRANCH_NOBP_RET)
11226 s390_indirect_branch_via_thunk (REGNO (operands[0]),
11229 s390_indirect_branch_type_return);
11235 [(set (attr "op_type")
11236 (if_then_else (match_test "TARGET_INDIRECT_BRANCH_NOBP_RET")
11237 (const_string "RIL")
11238 (const_string "RR")))
11239 (set (attr "mnemonic")
11240 (if_then_else (match_test "TARGET_INDIRECT_BRANCH_NOBP_RET")
11241 (const_string "jg")
11242 (const_string "br")))
11243 (set_attr "type" "jsr")
11244 (set_attr "atype" "agen")])
11246 (define_insn "return<mode>_prez10"
11248 (use (match_operand:P 0 "register_operand" "a"))
11249 (clobber (reg:P INDIRECT_BRANCH_THUNK_REGNUM))]
11250 "!TARGET_CPU_Z10 && TARGET_INDIRECT_BRANCH_NOBP_RET_OPTION"
11252 if (TARGET_INDIRECT_BRANCH_NOBP_RET)
11254 s390_indirect_branch_via_thunk (REGNO (operands[0]),
11257 s390_indirect_branch_type_return);
11263 [(set (attr "op_type")
11264 (if_then_else (match_test "TARGET_INDIRECT_BRANCH_NOBP_RET")
11265 (const_string "RIL")
11266 (const_string "RR")))
11267 (set (attr "mnemonic")
11268 (if_then_else (match_test "TARGET_INDIRECT_BRANCH_NOBP_RET")
11269 (const_string "jg")
11270 (const_string "br")))
11271 (set_attr "type" "jsr")
11272 (set_attr "atype" "agen")])
11275 ;; Instruction definition to extend a 31-bit pointer into a 64-bit
11276 ;; pointer. This is used for compatibility.
11278 (define_expand "ptr_extend"
11279 [(set (match_operand:DI 0 "register_operand" "=r")
11280 (match_operand:SI 1 "register_operand" "r"))]
11283 emit_insn (gen_anddi3 (operands[0],
11284 gen_lowpart (DImode, operands[1]),
11285 GEN_INT (0x7fffffff)));
11289 ;; Instruction definition to expand eh_return macro to support
11290 ;; swapping in special linkage return addresses.
11292 (define_expand "eh_return"
11293 [(use (match_operand 0 "register_operand" ""))]
11296 s390_emit_tpf_eh_return (operands[0]);
11301 ; Stack Protector Patterns
11304 (define_expand "stack_protect_set"
11305 [(set (match_operand 0 "memory_operand" "")
11306 (match_operand 1 "memory_operand" ""))]
11309 #ifdef TARGET_THREAD_SSP_OFFSET
11311 = gen_rtx_MEM (Pmode, gen_rtx_PLUS (Pmode, s390_get_thread_pointer (),
11312 GEN_INT (TARGET_THREAD_SSP_OFFSET)));
11315 emit_insn (gen_stack_protect_setdi (operands[0], operands[1]));
11317 emit_insn (gen_stack_protect_setsi (operands[0], operands[1]));
11322 (define_insn "stack_protect_set<mode>"
11323 [(set (match_operand:DSI 0 "memory_operand" "=Q")
11324 (unspec:DSI [(match_operand:DSI 1 "memory_operand" "Q")] UNSPEC_SP_SET))]
11326 "mvc\t%O0(%G0,%R0),%S1"
11327 [(set_attr "op_type" "SS")])
11329 (define_expand "stack_protect_test"
11330 [(set (reg:CC CC_REGNUM)
11331 (compare (match_operand 0 "memory_operand" "")
11332 (match_operand 1 "memory_operand" "")))
11333 (match_operand 2 "" "")]
11337 #ifdef TARGET_THREAD_SSP_OFFSET
11339 = gen_rtx_MEM (Pmode, gen_rtx_PLUS (Pmode, s390_get_thread_pointer (),
11340 GEN_INT (TARGET_THREAD_SSP_OFFSET)));
11343 emit_insn (gen_stack_protect_testdi (operands[0], operands[1]));
11345 emit_insn (gen_stack_protect_testsi (operands[0], operands[1]));
11347 cc_reg = gen_rtx_REG (CCZmode, CC_REGNUM);
11348 test = gen_rtx_EQ (VOIDmode, cc_reg, const0_rtx);
11349 emit_jump_insn (gen_cbranchcc4 (test, cc_reg, const0_rtx, operands[2]));
11353 (define_insn "stack_protect_test<mode>"
11354 [(set (reg:CCZ CC_REGNUM)
11355 (unspec:CCZ [(match_operand:DSI 0 "memory_operand" "Q")
11356 (match_operand:DSI 1 "memory_operand" "Q")] UNSPEC_SP_TEST))]
11358 "clc\t%O0(%G0,%R0),%S1"
11359 [(set_attr "op_type" "SS")])
11361 ; This is used in s390_emit_prologue in order to prevent insns
11362 ; adjusting the stack pointer to be moved over insns writing stack
11363 ; slots using a copy of the stack pointer in a different register.
11364 (define_insn "stack_tie"
11365 [(set (match_operand:BLK 0 "memory_operand" "+m")
11366 (unspec:BLK [(match_dup 0)] UNSPEC_TIE))]
11369 [(set_attr "length" "0")])
11372 (define_insn "stack_restore_from_fpr"
11373 [(set (reg:DI STACK_REGNUM)
11374 (match_operand:DI 0 "register_operand" "f"))
11375 (clobber (mem:BLK (scratch)))]
11378 [(set_attr "op_type" "RRE")])
11381 ; Data prefetch patterns
11384 (define_insn "prefetch"
11385 [(prefetch (match_operand 0 "address_operand" "ZT,X")
11386 (match_operand:SI 1 "const_int_operand" " n,n")
11387 (match_operand:SI 2 "const_int_operand" " n,n"))]
11390 switch (which_alternative)
11393 return INTVAL (operands[1]) == 1 ? "pfd\t2,%a0" : "pfd\t1,%a0";
11395 if (larl_operand (operands[0], Pmode))
11396 return INTVAL (operands[1]) == 1 ? "pfdrl\t2,%a0" : "pfdrl\t1,%a0";
11400 /* This might be reached for symbolic operands with an odd
11401 addend. We simply omit the prefetch for such rare cases. */
11406 [(set_attr "type" "load,larl")
11407 (set_attr "op_type" "RXY,RIL")
11408 (set_attr "z10prop" "z10_super")
11409 (set_attr "z196prop" "z196_alone")])
11413 ; Byte swap instructions
11416 ; FIXME: There is also mvcin but we cannot use it since src and target
11418 ; lrvr, lrv, strv, lrvgr, lrvg, strvg
11419 (define_insn "bswap<mode>2"
11420 [(set (match_operand:GPR 0 "nonimmediate_operand" "=d,d,T")
11421 (bswap:GPR (match_operand:GPR 1 "nonimmediate_operand" " d,T,d")))]
11427 [(set_attr "type" "*,load,store")
11428 (set_attr "op_type" "RRE,RXY,RXY")
11429 (set_attr "z10prop" "z10_super")])
11431 (define_insn "bswaphi2"
11432 [(set (match_operand:HI 0 "nonimmediate_operand" "=d,d,T")
11433 (bswap:HI (match_operand:HI 1 "nonimmediate_operand" " d,T,d")))]
11439 [(set_attr "type" "*,load,store")
11440 (set_attr "op_type" "RRE,RXY,RXY")
11441 (set_attr "z10prop" "z10_super")])
11444 [(set (match_operand:HI 0 "register_operand" "")
11445 (bswap:HI (match_operand:HI 1 "register_operand" "")))]
11447 [(set (match_dup 2) (bswap:SI (match_dup 3)))
11448 (set (match_dup 2) (lshiftrt:SI (match_dup 2) (const_int 16)))]
11450 operands[2] = simplify_gen_subreg (SImode, operands[0], HImode, 0);
11451 operands[3] = simplify_gen_subreg (SImode, operands[1], HImode, 0);
11456 ; Population count instruction
11459 ; The S/390 popcount instruction counts the bits of op1 in 8 byte
11460 ; portions and stores the result in the corresponding bytes in op0.
11461 (define_insn "*popcount<mode>"
11462 [(set (match_operand:INT 0 "register_operand" "=d")
11463 (unspec:INT [(match_operand:INT 1 "register_operand" "d")] UNSPEC_POPCNT))
11464 (clobber (reg:CC CC_REGNUM))]
11467 [(set_attr "op_type" "RRE")])
11469 (define_expand "popcountdi2"
11471 (parallel [(set (match_operand:DI 0 "register_operand" "")
11472 (unspec:DI [(match_operand:DI 1 "register_operand")]
11474 (clobber (reg:CC CC_REGNUM))])
11475 ; sllg op2, op0, 32
11476 (set (match_dup 2) (ashift:DI (match_dup 0) (const_int 32)))
11478 (parallel [(set (match_dup 0) (plus:DI (match_dup 0) (match_dup 2)))
11479 (clobber (reg:CC CC_REGNUM))])
11480 ; sllg op2, op0, 16
11482 (ashift:DI (match_dup 0) (const_int 16)))
11484 (parallel [(set (match_dup 0) (plus:DI (match_dup 0) (match_dup 2)))
11485 (clobber (reg:CC CC_REGNUM))])
11487 (set (match_dup 2) (ashift:DI (match_dup 0) (const_int 8)))
11489 (parallel [(set (match_dup 0) (plus:DI (match_dup 0) (match_dup 2)))
11490 (clobber (reg:CC CC_REGNUM))])
11491 ; srlg op0, op0, 56
11492 (set (match_dup 0) (lshiftrt:DI (match_dup 0) (const_int 56)))]
11493 "TARGET_Z196 && TARGET_64BIT"
11494 "operands[2] = gen_reg_rtx (DImode);")
11496 (define_expand "popcountsi2"
11498 (parallel [(set (match_operand:SI 0 "register_operand" "")
11499 (unspec:SI [(match_operand:SI 1 "register_operand")]
11501 (clobber (reg:CC CC_REGNUM))])
11502 ; sllk op2, op0, 16
11504 (ashift:SI (match_dup 0) (const_int 16)))
11506 (parallel [(set (match_dup 0) (plus:SI (match_dup 0) (match_dup 2)))
11507 (clobber (reg:CC CC_REGNUM))])
11509 (set (match_dup 2) (ashift:SI (match_dup 0) (const_int 8)))
11511 (parallel [(set (match_dup 0) (plus:SI (match_dup 0) (match_dup 2)))
11512 (clobber (reg:CC CC_REGNUM))])
11514 (set (match_dup 0) (lshiftrt:SI (match_dup 0) (const_int 24)))]
11516 "operands[2] = gen_reg_rtx (SImode);")
11518 (define_expand "popcounthi2"
11520 (parallel [(set (match_operand:HI 0 "register_operand" "")
11521 (unspec:HI [(match_operand:HI 1 "register_operand")]
11523 (clobber (reg:CC CC_REGNUM))])
11526 (ashift:SI (match_dup 0) (const_int 8)))
11528 (parallel [(set (match_dup 0) (plus:SI (match_dup 0) (match_dup 2)))
11529 (clobber (reg:CC CC_REGNUM))])
11531 (set (match_dup 0) (lshiftrt:HI (match_dup 0) (const_int 8)))]
11533 "operands[2] = gen_reg_rtx (SImode);")
11535 (define_expand "popcountqi2"
11537 (parallel [(set (match_operand:QI 0 "register_operand" "")
11538 (unspec:QI [(match_operand:QI 1 "register_operand")]
11540 (clobber (reg:CC CC_REGNUM))])]
11545 ;;- Copy sign instructions
11548 (define_insn "copysign<mode>3"
11549 [(set (match_operand:FP 0 "register_operand" "=f")
11550 (unspec:FP [(match_operand:FP 1 "register_operand" "<fT0>")
11551 (match_operand:FP 2 "register_operand" "f")]
11555 [(set_attr "op_type" "RRF")
11556 (set_attr "type" "fsimp<mode>")])
11560 ;;- Transactional execution instructions
11563 ; This splitter helps combine to make use of CC directly when
11564 ; comparing the integer result of a tbegin builtin with a constant.
11565 ; The unspec is already removed by canonicalize_comparison. So this
11566 ; splitters only job is to turn the PARALLEL into separate insns
11567 ; again. Unfortunately this only works with the very first cc/int
11568 ; compare since combine is not able to deal with data flow across
11569 ; basic block boundaries.
11571 ; It needs to be an insn pattern as well since combine does not apply
11572 ; the splitter directly. Combine would only use it if it actually
11573 ; would reduce the number of instructions.
11574 (define_insn_and_split "*ccraw_to_int"
11577 (match_operator 0 "s390_eqne_operator"
11578 [(reg:CCRAW CC_REGNUM)
11579 (match_operand 1 "const_int_operand" "")])
11580 (label_ref (match_operand 2 "" ""))
11582 (set (match_operand:SI 3 "register_operand" "=d")
11583 (unspec:SI [(reg:CCRAW CC_REGNUM)] UNSPEC_CC_TO_INT))]
11587 [(set (match_dup 3)
11588 (unspec:SI [(reg:CCRAW CC_REGNUM)] UNSPEC_CC_TO_INT))
11590 (if_then_else (match_op_dup 0 [(reg:CCRAW CC_REGNUM) (match_dup 1)])
11591 (label_ref (match_dup 2))
11595 ; Non-constrained transaction begin
11597 (define_expand "tbegin"
11598 [(match_operand:SI 0 "register_operand" "")
11599 (match_operand:BLK 1 "memory_operand" "")]
11602 s390_expand_tbegin (operands[0], operands[1], NULL_RTX, true);
11606 (define_expand "tbegin_nofloat"
11607 [(match_operand:SI 0 "register_operand" "")
11608 (match_operand:BLK 1 "memory_operand" "")]
11611 s390_expand_tbegin (operands[0], operands[1], NULL_RTX, false);
11615 (define_expand "tbegin_retry"
11616 [(match_operand:SI 0 "register_operand" "")
11617 (match_operand:BLK 1 "memory_operand" "")
11618 (match_operand:SI 2 "general_operand" "")]
11621 s390_expand_tbegin (operands[0], operands[1], operands[2], true);
11625 (define_expand "tbegin_retry_nofloat"
11626 [(match_operand:SI 0 "register_operand" "")
11627 (match_operand:BLK 1 "memory_operand" "")
11628 (match_operand:SI 2 "general_operand" "")]
11631 s390_expand_tbegin (operands[0], operands[1], operands[2], false);
11635 ; Clobber VRs since they don't get restored
11636 (define_insn "tbegin_1_z13"
11637 [(set (reg:CCRAW CC_REGNUM)
11638 (unspec_volatile:CCRAW [(match_operand 0 "const_int_operand" "D")]
11640 (set (match_operand:BLK 1 "memory_operand" "=Q")
11641 (unspec_volatile:BLK [(match_dup 0)] UNSPECV_TBEGIN_TDB))
11642 (clobber (reg:TI 16)) (clobber (reg:TI 38))
11643 (clobber (reg:TI 17)) (clobber (reg:TI 39))
11644 (clobber (reg:TI 18)) (clobber (reg:TI 40))
11645 (clobber (reg:TI 19)) (clobber (reg:TI 41))
11646 (clobber (reg:TI 20)) (clobber (reg:TI 42))
11647 (clobber (reg:TI 21)) (clobber (reg:TI 43))
11648 (clobber (reg:TI 22)) (clobber (reg:TI 44))
11649 (clobber (reg:TI 23)) (clobber (reg:TI 45))
11650 (clobber (reg:TI 24)) (clobber (reg:TI 46))
11651 (clobber (reg:TI 25)) (clobber (reg:TI 47))
11652 (clobber (reg:TI 26)) (clobber (reg:TI 48))
11653 (clobber (reg:TI 27)) (clobber (reg:TI 49))
11654 (clobber (reg:TI 28)) (clobber (reg:TI 50))
11655 (clobber (reg:TI 29)) (clobber (reg:TI 51))
11656 (clobber (reg:TI 30)) (clobber (reg:TI 52))
11657 (clobber (reg:TI 31)) (clobber (reg:TI 53))]
11658 ; CONST_OK_FOR_CONSTRAINT_P does not work with D constraint since D is
11659 ; not supposed to be used for immediates (see genpreds.c).
11660 "TARGET_VX && INTVAL (operands[0]) >= 0 && INTVAL (operands[0]) <= 0xffff"
11662 [(set_attr "op_type" "SIL")])
11664 (define_insn "tbegin_1"
11665 [(set (reg:CCRAW CC_REGNUM)
11666 (unspec_volatile:CCRAW [(match_operand 0 "const_int_operand" "D")]
11668 (set (match_operand:BLK 1 "memory_operand" "=Q")
11669 (unspec_volatile:BLK [(match_dup 0)] UNSPECV_TBEGIN_TDB))
11670 (clobber (reg:DF 16))
11671 (clobber (reg:DF 17))
11672 (clobber (reg:DF 18))
11673 (clobber (reg:DF 19))
11674 (clobber (reg:DF 20))
11675 (clobber (reg:DF 21))
11676 (clobber (reg:DF 22))
11677 (clobber (reg:DF 23))
11678 (clobber (reg:DF 24))
11679 (clobber (reg:DF 25))
11680 (clobber (reg:DF 26))
11681 (clobber (reg:DF 27))
11682 (clobber (reg:DF 28))
11683 (clobber (reg:DF 29))
11684 (clobber (reg:DF 30))
11685 (clobber (reg:DF 31))]
11686 ; CONST_OK_FOR_CONSTRAINT_P does not work with D constraint since D is
11687 ; not supposed to be used for immediates (see genpreds.c).
11688 "TARGET_HTM && INTVAL (operands[0]) >= 0 && INTVAL (operands[0]) <= 0xffff"
11690 [(set_attr "op_type" "SIL")])
11692 ; Same as above but without the FPR clobbers
11693 (define_insn "tbegin_nofloat_1"
11694 [(set (reg:CCRAW CC_REGNUM)
11695 (unspec_volatile:CCRAW [(match_operand 0 "const_int_operand" "D")]
11697 (set (match_operand:BLK 1 "memory_operand" "=Q")
11698 (unspec_volatile:BLK [(match_dup 0)] UNSPECV_TBEGIN_TDB))]
11699 "TARGET_HTM && INTVAL (operands[0]) >= 0 && INTVAL (operands[0]) <= 0xffff"
11701 [(set_attr "op_type" "SIL")])
11704 ; Constrained transaction begin
11706 (define_expand "tbeginc"
11707 [(set (reg:CCRAW CC_REGNUM)
11708 (unspec_volatile:CCRAW [(const_int TBEGINC_MASK)]
11713 (define_insn "*tbeginc_1"
11714 [(set (reg:CCRAW CC_REGNUM)
11715 (unspec_volatile:CCRAW [(match_operand 0 "const_int_operand" " D")]
11717 "TARGET_HTM && INTVAL (operands[0]) >= 0 && INTVAL (operands[0]) <= 0xffff"
11719 [(set_attr "op_type" "SIL")])
11723 (define_expand "tend"
11724 [(set (reg:CCRAW CC_REGNUM)
11725 (unspec_volatile:CCRAW [(const_int 0)] UNSPECV_TEND))
11726 (set (match_operand:SI 0 "register_operand" "")
11727 (unspec:SI [(reg:CCRAW CC_REGNUM)] UNSPEC_CC_TO_INT))]
11731 (define_insn "*tend_1"
11732 [(set (reg:CCRAW CC_REGNUM)
11733 (unspec_volatile:CCRAW [(const_int 0)] UNSPECV_TEND))]
11736 [(set_attr "op_type" "S")])
11738 ; Transaction abort
11740 (define_expand "tabort"
11741 [(unspec_volatile [(match_operand:SI 0 "nonmemory_operand" "")]
11743 "TARGET_HTM && operands != NULL"
11745 if (CONST_INT_P (operands[0])
11746 && INTVAL (operands[0]) >= 0 && INTVAL (operands[0]) <= 255)
11748 error ("invalid transaction abort code: " HOST_WIDE_INT_PRINT_DEC
11749 ". Values in range 0 through 255 are reserved.",
11750 INTVAL (operands[0]));
11755 (define_insn "*tabort_1"
11756 [(unspec_volatile [(match_operand:SI 0 "nonmemory_operand" "aJ")]
11758 "TARGET_HTM && operands != NULL"
11760 [(set_attr "op_type" "S")])
11762 (define_insn "*tabort_1_plus"
11763 [(unspec_volatile [(plus:SI (match_operand:SI 0 "register_operand" "a")
11764 (match_operand:SI 1 "const_int_operand" "J"))]
11766 "TARGET_HTM && operands != NULL
11767 && CONST_OK_FOR_CONSTRAINT_P (INTVAL (operands[1]), 'J', \"J\")"
11769 [(set_attr "op_type" "S")])
11771 ; Transaction extract nesting depth
11773 (define_insn "etnd"
11774 [(set (match_operand:SI 0 "register_operand" "=d")
11775 (unspec_volatile:SI [(const_int 0)] UNSPECV_ETND))]
11778 [(set_attr "op_type" "RRE")])
11780 ; Non-transactional store
11782 (define_insn "ntstg"
11783 [(set (match_operand:DI 0 "memory_operand" "=T")
11784 (unspec_volatile:DI [(match_operand:DI 1 "register_operand" "d")]
11788 [(set_attr "op_type" "RXY")])
11790 ; Transaction perform processor assist
11792 (define_expand "tx_assist"
11793 [(unspec_volatile [(match_operand:SI 0 "register_operand" "")
11794 (reg:SI GPR0_REGNUM)
11800 (define_insn "*ppa"
11801 [(unspec_volatile [(match_operand:SI 0 "register_operand" "d")
11802 (match_operand:SI 1 "register_operand" "d")
11803 (match_operand 2 "const_int_operand" "I")]
11805 "TARGET_HTM && INTVAL (operands[2]) < 16"
11807 [(set_attr "op_type" "RRF")])
11810 ; Set and get floating point control register
11812 (define_insn "sfpc"
11813 [(unspec_volatile [(match_operand:SI 0 "register_operand" "d")]
11815 "TARGET_HARD_FLOAT"
11818 (define_insn "efpc"
11819 [(set (match_operand:SI 0 "register_operand" "=d")
11820 (unspec_volatile:SI [(const_int 0)] UNSPECV_EFPC))]
11821 "TARGET_HARD_FLOAT"
11825 ; Load count to block boundary
11827 (define_insn "lcbb"
11828 [(set (match_operand:SI 0 "register_operand" "=d")
11829 (unspec:SI [(match_operand 1 "address_operand" "ZR")
11830 (match_operand:SI 2 "immediate_operand" "C")] UNSPEC_LCBB))
11831 (clobber (reg:CC CC_REGNUM))]
11834 [(set_attr "op_type" "VRX")])
11836 ; Handle -fsplit-stack.
11838 (define_expand "split_stack_prologue"
11842 s390_expand_split_stack_prologue ();
11846 ;; If there are operand 0 bytes available on the stack, jump to
11849 (define_expand "split_stack_space_check"
11850 [(set (pc) (if_then_else
11851 (ltu (minus (reg 15)
11852 (match_operand 0 "register_operand"))
11853 (unspec [(const_int 0)] UNSPEC_STACK_CHECK))
11854 (label_ref (match_operand 1))
11858 /* Offset from thread pointer to __private_ss. */
11859 int psso = TARGET_64BIT ? 0x38 : 0x20;
11860 rtx tp = s390_get_thread_pointer ();
11861 rtx guard = gen_rtx_MEM (Pmode, plus_constant (Pmode, tp, psso));
11862 rtx reg = gen_reg_rtx (Pmode);
11865 emit_insn (gen_subdi3 (reg, stack_pointer_rtx, operands[0]));
11867 emit_insn (gen_subsi3 (reg, stack_pointer_rtx, operands[0]));
11868 cc = s390_emit_compare (GT, reg, guard);
11869 s390_emit_jump (operands[1], cc);
11874 ;; __morestack parameter block for split stack prologue. Parameters are:
11875 ;; parameter block label, label to be called by __morestack, frame size,
11876 ;; stack parameter size.
11878 (define_insn "split_stack_data"
11879 [(unspec_volatile [(match_operand 0 "" "X")
11880 (match_operand 1 "" "X")
11881 (match_operand 2 "const_int_operand" "X")
11882 (match_operand 3 "const_int_operand" "X")]
11883 UNSPECV_SPLIT_STACK_DATA)]
11886 switch_to_section (targetm.asm_out.function_rodata_section
11887 (current_function_decl));
11890 output_asm_insn (".align\t8", operands);
11892 output_asm_insn (".align\t4", operands);
11893 (*targetm.asm_out.internal_label) (asm_out_file, "L",
11894 CODE_LABEL_NUMBER (operands[0]));
11897 output_asm_insn (".quad\t%2", operands);
11898 output_asm_insn (".quad\t%3", operands);
11899 output_asm_insn (".quad\t%1-%0", operands);
11903 output_asm_insn (".long\t%2", operands);
11904 output_asm_insn (".long\t%3", operands);
11905 output_asm_insn (".long\t%1-%0", operands);
11908 switch_to_section (current_function_section ());
11911 [(set_attr "length" "0")])
11914 ;; A jg with minimal fuss for use in split stack prologue.
11916 (define_expand "split_stack_call"
11917 [(match_operand 0 "bras_sym_operand" "X")
11918 (match_operand 1 "" "")]
11922 emit_jump_insn (gen_split_stack_call_di (operands[0], operands[1]));
11924 emit_jump_insn (gen_split_stack_call_si (operands[0], operands[1]));
11928 (define_insn "split_stack_call_<mode>"
11929 [(set (pc) (label_ref (match_operand 1 "" "")))
11930 (set (reg:P 1) (unspec_volatile [(match_operand 0 "bras_sym_operand" "X")
11932 UNSPECV_SPLIT_STACK_CALL))]
11935 [(set_attr "op_type" "RIL")
11936 (set_attr "type" "branch")])
11938 ;; Also a conditional one.
11940 (define_expand "split_stack_cond_call"
11941 [(match_operand 0 "bras_sym_operand" "X")
11942 (match_operand 1 "" "")
11943 (match_operand 2 "" "")]
11947 emit_jump_insn (gen_split_stack_cond_call_di (operands[0], operands[1], operands[2]));
11949 emit_jump_insn (gen_split_stack_cond_call_si (operands[0], operands[1], operands[2]));
11953 (define_insn "split_stack_cond_call_<mode>"
11956 (match_operand 1 "" "")
11957 (label_ref (match_operand 2 "" ""))
11959 (set (reg:P 1) (unspec_volatile [(match_operand 0 "bras_sym_operand" "X")
11961 UNSPECV_SPLIT_STACK_CALL))]
11964 [(set_attr "op_type" "RIL")
11965 (set_attr "type" "branch")])
11967 (define_insn "osc_break"
11968 [(unspec_volatile [(const_int 0)] UNSPECV_OSC_BREAK)]
11971 [(set_attr "op_type" "RR")])