]>
Commit | Line | Data |
---|---|---|
4673c1a0 | 1 | ;;- Machine description for GNU compiler -- S/390 / zSeries version. |
e68d6a13 | 2 | ;; Copyright (C) 1999, 2000, 2001, 2002, 2003, 2004, 2005, 2006, 2007, 2008 |
934f2848 | 3 | ;; Free Software Foundation, Inc. |
4673c1a0 | 4 | ;; Contributed by Hartmut Penner (hpenner@de.ibm.com) and |
e68d6a13 | 5 | ;; Ulrich Weigand (uweigand@de.ibm.com) and |
6 | ;; Andreas Krebbel (Andreas.Krebbel@de.ibm.com) | |
4673c1a0 | 7 | |
1e98c8f3 | 8 | ;; This file is part of GCC. |
9 | ||
10 | ;; GCC is free software; you can redistribute it and/or modify it under | |
11 | ;; the terms of the GNU General Public License as published by the Free | |
038d1e19 | 12 | ;; Software Foundation; either version 3, or (at your option) any later |
1e98c8f3 | 13 | ;; version. |
14 | ||
15 | ;; GCC is distributed in the hope that it will be useful, but WITHOUT ANY | |
16 | ;; WARRANTY; without even the implied warranty of MERCHANTABILITY or | |
17 | ;; FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License | |
18 | ;; for more details. | |
4673c1a0 | 19 | |
20 | ;; You should have received a copy of the GNU General Public License | |
038d1e19 | 21 | ;; along with GCC; see the file COPYING3. If not see |
22 | ;; <http://www.gnu.org/licenses/>. | |
4673c1a0 | 23 | |
24 | ;; | |
59bc01b3 | 25 | ;; See constraints.md for a description of constraints specific to s390. |
4673c1a0 | 26 | ;; |
59bc01b3 | 27 | |
4673c1a0 | 28 | ;; Special formats used for outputting 390 instructions. |
29 | ;; | |
64a1078f | 30 | ;; %C: print opcode suffix for branch condition. |
31 | ;; %D: print opcode suffix for inverse branch condition. | |
32 | ;; %J: print tls_load/tls_gdcall/tls_ldcall suffix | |
b9059d39 | 33 | ;; %G: print the size of the operand in bytes. |
64a1078f | 34 | ;; %O: print only the displacement of a memory reference. |
35 | ;; %R: print only the base register of a memory reference. | |
0574acbe | 36 | ;; %S: print S-type memory reference (base+displacement). |
64a1078f | 37 | ;; %N: print the second word of a DImode operand. |
38 | ;; %M: print the second word of a TImode operand. | |
b9059d39 | 39 | ;; %Y: print shift count operand. |
40 | ;; | |
64a1078f | 41 | ;; %b: print integer X as if it's an unsigned byte. |
e68d6a13 | 42 | ;; %c: print integer X as if it's an signed byte. |
b9059d39 | 43 | ;; %x: print integer X as if it's an unsigned halfword. |
44 | ;; %h: print integer X as if it's a signed halfword. | |
45 | ;; %i: print the first nonzero HImode part of X. | |
46 | ;; %j: print the first HImode part unequal to -1 of X. | |
47 | ;; %k: print the first nonzero SImode part of X. | |
48 | ;; %m: print the first SImode part unequal to -1 of X. | |
49 | ;; %o: print integer X as if it's an unsigned 32bit word. | |
4673c1a0 | 50 | ;; |
51 | ;; We have a special constraint for pattern matching. | |
52 | ;; | |
53 | ;; s_operand -- Matches a valid S operand in a RS, SI or SS type instruction. | |
54 | ;; | |
4673c1a0 | 55 | |
be00aaa8 | 56 | ;; |
57 | ;; UNSPEC usage | |
58 | ;; | |
59 | ||
60 | (define_constants | |
83e641bd | 61 | [; Miscellaneous |
62 | (UNSPEC_ROUND 1) | |
27784c70 | 63 | (UNSPEC_CCU_TO_INT 2) |
64 | (UNSPEC_CCZ_TO_INT 3) | |
0349cc73 | 65 | (UNSPEC_ICM 10) |
062c49fd | 66 | (UNSPEC_TIE 11) |
83e641bd | 67 | |
68 | ; GOT/PLT and lt-relative accesses | |
12ef3745 | 69 | (UNSPEC_LTREL_OFFSET 100) |
70 | (UNSPEC_LTREL_BASE 101) | |
71 | (UNSPEC_GOTENT 110) | |
72 | (UNSPEC_GOT 111) | |
73 | (UNSPEC_GOTOFF 112) | |
74 | (UNSPEC_PLT 113) | |
75 | (UNSPEC_PLTOFF 114) | |
76 | ||
77 | ; Literal pool | |
78 | (UNSPEC_RELOAD_BASE 210) | |
c2c1332a | 79 | (UNSPEC_MAIN_BASE 211) |
20074f87 | 80 | (UNSPEC_LTREF 212) |
d345b493 | 81 | (UNSPEC_INSN 213) |
82 | (UNSPEC_EXECUTE 214) | |
12ef3745 | 83 | |
84 | ; TLS relocation specifiers | |
be00aaa8 | 85 | (UNSPEC_TLSGD 500) |
86 | (UNSPEC_TLSLDM 501) | |
87 | (UNSPEC_NTPOFF 502) | |
88 | (UNSPEC_DTPOFF 503) | |
89 | (UNSPEC_GOTNTPOFF 504) | |
90 | (UNSPEC_INDNTPOFF 505) | |
91 | ||
92 | ; TLS support | |
be00aaa8 | 93 | (UNSPEC_TLSLDM_NTPOFF 511) |
94 | (UNSPEC_TLS_LOAD 512) | |
a724d2fa | 95 | |
96 | ; String Functions | |
cc87d0c5 | 97 | (UNSPEC_SRST 600) |
495a87f4 | 98 | (UNSPEC_MVST 601) |
27784c70 | 99 | |
cc87d0c5 | 100 | ; Stack Smashing Protector |
101 | (UNSPEC_SP_SET 700) | |
102 | (UNSPEC_SP_TEST 701) | |
0c2edaa7 | 103 | |
104 | ; Copy sign instructions | |
105 | (UNSPEC_COPYSIGN 800) | |
27784c70 | 106 | |
107 | ; Test Data Class (TDC) | |
108 | (UNSPEC_TDC_INSN 900) | |
be00aaa8 | 109 | ]) |
110 | ||
111 | ;; | |
112 | ;; UNSPEC_VOLATILE usage | |
113 | ;; | |
114 | ||
115 | (define_constants | |
83e641bd | 116 | [; Blockage |
117 | (UNSPECV_BLOCKAGE 0) | |
118 | ||
346fecd5 | 119 | ; TPF Support |
120 | (UNSPECV_TPF_PROLOGUE 20) | |
121 | (UNSPECV_TPF_EPILOGUE 21) | |
122 | ||
83e641bd | 123 | ; Literal pool |
12ef3745 | 124 | (UNSPECV_POOL 200) |
d345b493 | 125 | (UNSPECV_POOL_SECTION 201) |
126 | (UNSPECV_POOL_ALIGN 202) | |
df82fb76 | 127 | (UNSPECV_POOL_ENTRY 203) |
12ef3745 | 128 | (UNSPECV_MAIN_POOL 300) |
129 | ||
130 | ; TLS support | |
be00aaa8 | 131 | (UNSPECV_SET_TP 500) |
891e3096 | 132 | |
133 | ; Atomic Support | |
134 | (UNSPECV_MB 700) | |
135 | (UNSPECV_CAS 701) | |
be00aaa8 | 136 | ]) |
137 | ||
1ca361fd | 138 | ;; |
139 | ;; Registers | |
140 | ;; | |
141 | ||
9fa9680d | 142 | ; Registers with special meaning |
143 | ||
1ca361fd | 144 | (define_constants |
145 | [ | |
146 | ; Sibling call register. | |
147 | (SIBCALL_REGNUM 1) | |
148 | ; Literal pool base register. | |
149 | (BASE_REGNUM 13) | |
150 | ; Return address register. | |
151 | (RETURN_REGNUM 14) | |
152 | ; Condition code register. | |
153 | (CC_REGNUM 33) | |
154 | ; Thread local storage pointer register. | |
155 | (TP_REGNUM 36) | |
156 | ]) | |
157 | ||
9fa9680d | 158 | ; Hardware register names |
159 | ||
160 | (define_constants | |
161 | [ | |
162 | ; General purpose registers | |
163 | (GPR0_REGNUM 0) | |
164 | ; Floating point registers. | |
165 | (FPR0_REGNUM 16) | |
166 | (FPR2_REGNUM 18) | |
167 | ]) | |
168 | ||
169 | ;; | |
170 | ;; PFPO GPR0 argument format | |
171 | ;; | |
172 | ||
173 | (define_constants | |
174 | [ | |
175 | ; PFPO operation type | |
176 | (PFPO_CONVERT 0x1000000) | |
177 | ; PFPO operand types | |
178 | (PFPO_OP_TYPE_SF 0x5) | |
179 | (PFPO_OP_TYPE_DF 0x6) | |
180 | (PFPO_OP_TYPE_TF 0x7) | |
181 | (PFPO_OP_TYPE_SD 0x8) | |
182 | (PFPO_OP_TYPE_DD 0x9) | |
183 | (PFPO_OP_TYPE_TD 0xa) | |
184 | ; Bitposition of operand types | |
185 | (PFPO_OP0_TYPE_SHIFT 16) | |
186 | (PFPO_OP1_TYPE_SHIFT 8) | |
187 | ]) | |
188 | ||
be00aaa8 | 189 | |
cec0d54d | 190 | ;; Instruction operand type as used in the Principles of Operation. |
191 | ;; Used to determine defaults for length and other attribute values. | |
95ae2fd6 | 192 | |
cec0d54d | 193 | (define_attr "op_type" |
e68d6a13 | 194 | "NN,E,RR,RRE,RX,RS,RSI,RI,SI,S,SS,SSE,RXE,RSE,RIL,RIE,RXY,RSY,SIY,RRF,RRR,SIL,RRS,RIS" |
1822f0d6 | 195 | (const_string "NN")) |
4673c1a0 | 196 | |
cec0d54d | 197 | ;; Instruction type attribute used for scheduling. |
4673c1a0 | 198 | |
71343e6b | 199 | (define_attr "type" "none,integer,load,lr,la,larl,lm,stm, |
891e3096 | 200 | cs,vs,store,sem,idiv, |
16ed459a | 201 | imulhi,imulsi,imuldi, |
429f9fdb | 202 | branch,jsr,fsimptf,fsimpdf,fsimpsf, |
203 | floadtf,floaddf,floadsf,fstoredf,fstoresf, | |
204 | fmultf,fmuldf,fmulsf,fdivtf,fdivdf,fdivsf, | |
205 | ftoi,itof,fsqrttf,fsqrtdf,fsqrtsf, | |
206 | ftrunctf,ftruncdf,other" | |
cec0d54d | 207 | (cond [(eq_attr "op_type" "NN") (const_string "other") |
208 | (eq_attr "op_type" "SS") (const_string "cs")] | |
209 | (const_string "integer"))) | |
4673c1a0 | 210 | |
cec0d54d | 211 | ;; Another attribute used for scheduling purposes: |
212 | ;; agen: Instruction uses the address generation unit | |
213 | ;; reg: Instruction does not use the agen unit | |
71343e6b | 214 | |
215 | (define_attr "atype" "agen,reg" | |
d666e71f | 216 | (if_then_else (eq_attr "op_type" "E,RR,RI,RRE") |
217 | (const_string "reg") | |
218 | (const_string "agen"))) | |
4673c1a0 | 219 | |
4673c1a0 | 220 | ;; Length in bytes. |
221 | ||
222 | (define_attr "length" "" | |
e68d6a13 | 223 | (cond [(eq_attr "op_type" "E,RR") (const_int 2) |
224 | (eq_attr "op_type" "RX,RI,RRE,RS,RSI,S,SI,RRF,RRR") (const_int 4)] | |
1822f0d6 | 225 | (const_int 6))) |
4673c1a0 | 226 | |
cec0d54d | 227 | |
228 | ;; Processor type. This attribute must exactly match the processor_type | |
229 | ;; enumeration in s390.h. The current machine description does not | |
230 | ;; distinguish between g5 and g6, but there are differences between the two | |
231 | ;; CPUs could in theory be modeled. | |
232 | ||
a850370e | 233 | (define_attr "cpu" "g5,g6,z900,z990,z9_109,z10" |
cec0d54d | 234 | (const (symbol_ref "s390_tune"))) |
235 | ||
a850370e | 236 | (define_attr "cpu_facility" "standard,ieee,zarch,longdisp,extimm,dfp,z10" |
562d1970 | 237 | (const_string "standard")) |
238 | ||
239 | (define_attr "enabled" "" | |
240 | (cond [(eq_attr "cpu_facility" "standard") | |
241 | (const_int 1) | |
242 | ||
243 | (and (eq_attr "cpu_facility" "ieee") | |
244 | (ne (symbol_ref "TARGET_CPU_IEEE_FLOAT") (const_int 0))) | |
245 | (const_int 1) | |
246 | ||
247 | (and (eq_attr "cpu_facility" "zarch") | |
248 | (ne (symbol_ref "TARGET_ZARCH") (const_int 0))) | |
249 | (const_int 1) | |
250 | ||
251 | (and (eq_attr "cpu_facility" "longdisp") | |
252 | (ne (symbol_ref "TARGET_LONG_DISPLACEMENT") (const_int 0))) | |
253 | (const_int 1) | |
254 | ||
255 | (and (eq_attr "cpu_facility" "extimm") | |
256 | (ne (symbol_ref "TARGET_EXTIMM") (const_int 0))) | |
257 | (const_int 1) | |
258 | ||
259 | (and (eq_attr "cpu_facility" "dfp") | |
260 | (ne (symbol_ref "TARGET_DFP") (const_int 0))) | |
a850370e | 261 | (const_int 1) |
262 | ||
263 | (and (eq_attr "cpu_facility" "z10") | |
264 | (ne (symbol_ref "TARGET_Z10") (const_int 0))) | |
562d1970 | 265 | (const_int 1)] |
266 | (const_int 0))) | |
267 | ||
cec0d54d | 268 | ;; Pipeline description for z900. For lack of anything better, |
269 | ;; this description is also used for the g5 and g6. | |
270 | (include "2064.md") | |
271 | ||
7818a08e | 272 | ;; Pipeline description for z990, z9-109 and z9-ec. |
cec0d54d | 273 | (include "2084.md") |
274 | ||
8cc5de33 | 275 | ;; Predicates |
276 | (include "predicates.md") | |
277 | ||
59bc01b3 | 278 | ;; Constraint definitions |
279 | (include "constraints.md") | |
280 | ||
9f88bc9d | 281 | ;; Other includes |
282 | (include "tpf.md") | |
02f6ff46 | 283 | |
fd781bb2 | 284 | ;; Iterators |
02f6ff46 | 285 | |
fd781bb2 | 286 | ;; These mode iterators allow floating point patterns to be generated from the |
8052065f | 287 | ;; same template. |
d1191819 | 288 | (define_mode_iterator FP_ALL [TF DF SF (TD "TARGET_HARD_DFP") (DD "TARGET_HARD_DFP") |
289 | (SD "TARGET_HARD_DFP")]) | |
fd781bb2 | 290 | (define_mode_iterator FP [TF DF SF (TD "TARGET_HARD_DFP") (DD "TARGET_HARD_DFP")]) |
e68d6a13 | 291 | (define_mode_iterator FPALL [TF DF SF TD DD SD]) |
fd781bb2 | 292 | (define_mode_iterator BFP [TF DF SF]) |
293 | (define_mode_iterator DFP [TD DD]) | |
294 | (define_mode_iterator DFP_ALL [TD DD SD]) | |
295 | (define_mode_iterator DSF [DF SF]) | |
296 | (define_mode_iterator SD_SF [SF SD]) | |
297 | (define_mode_iterator DD_DF [DF DD]) | |
298 | (define_mode_iterator TD_TF [TF TD]) | |
299 | ||
300 | ;; This mode iterator allows 31-bit and 64-bit TDSI patterns to be generated | |
86693d48 | 301 | ;; from the same template. |
fd781bb2 | 302 | (define_mode_iterator TDSI [(TI "TARGET_64BIT") DI SI]) |
86693d48 | 303 | |
fd781bb2 | 304 | ;; These mode iterators allow 31-bit and 64-bit GPR patterns to be generated |
2061f1ac | 305 | ;; from the same template. |
fd781bb2 | 306 | (define_mode_iterator GPR [(DI "TARGET_64BIT") SI]) |
307 | (define_mode_iterator DSI [DI SI]) | |
2061f1ac | 308 | |
fd781bb2 | 309 | ;; These mode iterators allow :P to be used for patterns that operate on |
2061f1ac | 310 | ;; pointer-sized quantities. Exactly one of the two alternatives will match. |
fd781bb2 | 311 | (define_mode_iterator DP [(TI "TARGET_64BIT") (DI "!TARGET_64BIT")]) |
312 | (define_mode_iterator P [(DI "TARGET_64BIT") (SI "!TARGET_64BIT")]) | |
2061f1ac | 313 | |
fd781bb2 | 314 | ;; This mode iterator allows the QI and HI patterns to be defined from |
02f6ff46 | 315 | ;; the same template. |
fd781bb2 | 316 | (define_mode_iterator HQI [HI QI]) |
02f6ff46 | 317 | |
fd781bb2 | 318 | ;; This mode iterator allows the integer patterns to be defined from the |
61da801c | 319 | ;; same template. |
fd781bb2 | 320 | (define_mode_iterator INT [(DI "TARGET_64BIT") SI HI QI]) |
e68d6a13 | 321 | (define_mode_iterator INTALL [TI DI SI HI QI]) |
61da801c | 322 | |
fd781bb2 | 323 | ;; This iterator allows to unify all 'bCOND' expander patterns. |
324 | (define_code_iterator COMPARE [eq ne gt gtu lt ltu ge geu le leu unordered | |
a2cef37b | 325 | ordered uneq unlt ungt unle unge ltgt]) |
326 | ||
fd781bb2 | 327 | ;; This iterator allows to unify all 'sCOND' patterns. |
328 | (define_code_iterator SCOND [ltu gtu leu geu]) | |
37af157c | 329 | |
fd781bb2 | 330 | ;; This iterator allows some 'ashift' and 'lshiftrt' pattern to be defined from |
ba400ef2 | 331 | ;; the same template. |
fd781bb2 | 332 | (define_code_iterator SHIFT [ashift lshiftrt]) |
ba400ef2 | 333 | |
fd781bb2 | 334 | ;; This iterator and attribute allow to combine most atomic operations. |
335 | (define_code_iterator ATOMIC [and ior xor plus minus mult]) | |
7cc66daf | 336 | (define_code_attr atomic [(and "and") (ior "ior") (xor "xor") |
337 | (plus "add") (minus "sub") (mult "nand")]) | |
338 | ||
1f8e70bc | 339 | ;; In FP templates, a string like "lt<de>br" will expand to "ltxbr" in |
340 | ;; TF/TDmode, "ltdbr" in DF/DDmode, and "ltebr" in SF/SDmode. | |
341 | (define_mode_attr xde [(TF "x") (DF "d") (SF "e") (TD "x") (DD "d") (SD "e")]) | |
ba400ef2 | 342 | |
1f8e70bc | 343 | ;; In FP templates, a <dee> in "m<dee><bt>r" will expand to "mx<bt>r" in |
344 | ;; TF/TDmode, "md<bt>r" in DF/DDmode, "mee<bt>r" in SFmode and "me<bt>r in | |
345 | ;; SDmode. | |
346 | (define_mode_attr xdee [(TF "x") (DF "d") (SF "ee") (TD "x") (DD "d") (SD "e")]) | |
8052065f | 347 | |
1f8e70bc | 348 | ;; In FP templates, "<RRe>" will expand to "RRE" in TFmode and "RR" otherwise. |
429f9fdb | 349 | ;; Likewise for "<RXe>". |
350 | (define_mode_attr RRe [(TF "RRE") (DF "RR") (SF "RR")]) | |
351 | (define_mode_attr RXe [(TF "RXE") (DF "RX") (SF "RX")]) | |
352 | ||
1f8e70bc | 353 | ;; The decimal floating point variants of add, sub, div and mul support 3 |
fd781bb2 | 354 | ;; fp register operands. The following attributes allow to merge the bfp and |
1f8e70bc | 355 | ;; dfp variants in a single insn definition. |
356 | ||
fd781bb2 | 357 | ;; This attribute is used to set op_type accordingly. |
1f8e70bc | 358 | (define_mode_attr RRer [(TF "RRE") (DF "RRE") (SF "RRE") (TD "RRR") |
359 | (DD "RRR") (SD "RRR")]) | |
360 | ||
fd781bb2 | 361 | ;; This attribute is used in the operand constraint list in order to have the |
1f8e70bc | 362 | ;; first and the second operand match for bfp modes. |
363 | (define_mode_attr f0 [(TF "0") (DF "0") (SF "0") (TD "f") (DD "f") (DD "f")]) | |
364 | ||
fd781bb2 | 365 | ;; This attribute is used in the operand list of the instruction to have an |
1f8e70bc | 366 | ;; additional operand for the dfp instructions. |
367 | (define_mode_attr op1 [(TF "") (DF "") (SF "") | |
368 | (TD "%1,") (DD "%1,") (SD "%1,")]) | |
369 | ||
8052065f | 370 | |
0c2edaa7 | 371 | ;; This attribute is used in the operand constraint list |
372 | ;; for instructions dealing with the sign bit of 32 or 64bit fp values. | |
373 | ;; TFmode values are represented by a fp register pair. Since the | |
374 | ;; sign bit instructions only handle single source and target fp registers | |
375 | ;; these instructions can only be used for TFmode values if the source and | |
376 | ;; target operand uses the same fp register. | |
377 | (define_mode_attr fT0 [(TF "0") (DF "f") (SF "f")]) | |
378 | ||
1f8e70bc | 379 | ;; In FP templates, "<Rf>" will expand to "f" in TFmode and "R" otherwise. |
380 | ;; This is used to disable the memory alternative in TFmode patterns. | |
381 | (define_mode_attr Rf [(TF "f") (DF "R") (SF "R") (TD "f") (DD "f") (SD "f")]) | |
382 | ||
fd781bb2 | 383 | ;; This attribute adds b for bfp instructions and t for dfp instructions and is used |
1f8e70bc | 384 | ;; within instruction mnemonics. |
385 | (define_mode_attr bt [(TF "b") (DF "b") (SF "b") (TD "t") (DD "t") (SD "t")]) | |
386 | ||
d1191819 | 387 | ;; This attribute is used within instruction mnemonics. It evaluates to d for dfp |
388 | ;; modes and to an empty string for bfp modes. | |
389 | (define_mode_attr _d [(TF "") (DF "") (SF "") (TD "d") (DD "d") (SD "d")]) | |
390 | ||
efec32e0 | 391 | ;; Although it is imprecise for z9-ec we handle all dfp instructions like |
1f8e70bc | 392 | ;; bfp regarding the pipeline description. |
393 | (define_mode_attr bfp [(TF "tf") (DF "df") (SF "sf") | |
394 | (TD "tf") (DD "df") (SD "sf")]) | |
395 | ||
396 | ||
38d26fa6 | 397 | ;; In GPR and P templates, a constraint like "<d0>" will expand to "d" in DImode |
398 | ;; and "0" in SImode. This allows to combine instructions of which the 31bit | |
399 | ;; version only operates on one register. | |
400 | (define_mode_attr d0 [(DI "d") (SI "0")]) | |
401 | ||
402 | ;; In combination with d0 this allows to combine instructions of which the 31bit | |
403 | ;; version only operates on one register. The DImode version needs an additional | |
404 | ;; register for the assembler output. | |
405 | (define_mode_attr 1 [(DI "%1,") (SI "")]) | |
406 | ||
ba400ef2 | 407 | ;; In SHIFT templates, a string like "s<lr>dl" will expand to "sldl" in |
408 | ;; 'ashift' and "srdl" in 'lshiftrt'. | |
409 | (define_code_attr lr [(ashift "l") (lshiftrt "r")]) | |
410 | ||
411 | ;; In SHIFT templates, this attribute holds the correct standard name for the | |
412 | ;; pattern itself and the corresponding function calls. | |
413 | (define_code_attr shift [(ashift "ashl") (lshiftrt "lshr")]) | |
37af157c | 414 | |
415 | ;; This attribute handles differences in the instruction 'type' and will result | |
416 | ;; in "RRE" for DImode and "RR" for SImode. | |
417 | (define_mode_attr E [(DI "E") (SI "")]) | |
418 | ||
d1641800 | 419 | ;; This attribute handles differences in the instruction 'type' and makes RX<Y> |
420 | ;; to result in "RXY" for DImode and "RX" for SImode. | |
421 | (define_mode_attr Y [(DI "Y") (SI "")]) | |
422 | ||
86693d48 | 423 | ;; This attribute handles differences in the instruction 'type' and will result |
424 | ;; in "RSE" for TImode and "RS" for DImode. | |
425 | (define_mode_attr TE [(TI "E") (DI "")]) | |
426 | ||
37af157c | 427 | ;; In GPR templates, a string like "lc<g>r" will expand to "lcgr" in DImode |
428 | ;; and "lcr" in SImode. | |
429 | (define_mode_attr g [(DI "g") (SI "")]) | |
02f6ff46 | 430 | |
d1641800 | 431 | ;; In GPR templates, a string like "sl<y>" will expand to "slg" in DImode |
432 | ;; and "sly" in SImode. This is useful because on 64bit the ..g instructions | |
433 | ;; were enhanced with long displacements whereas 31bit instructions got a ..y | |
434 | ;; variant for long displacements. | |
435 | (define_mode_attr y [(DI "g") (SI "y")]) | |
436 | ||
86693d48 | 437 | ;; In DP templates, a string like "cds<g>" will expand to "cdsg" in TImode |
438 | ;; and "cds" in DImode. | |
439 | (define_mode_attr tg [(TI "g") (DI "")]) | |
440 | ||
8e6e481d | 441 | ;; In GPR templates, a string like "c<gf>dbr" will expand to "cgdbr" in DImode |
442 | ;; and "cfdbr" in SImode. | |
443 | (define_mode_attr gf [(DI "g") (SI "f")]) | |
444 | ||
02f6ff46 | 445 | ;; ICM mask required to load MODE value into the lowest subreg |
446 | ;; of a SImode register. | |
447 | (define_mode_attr icm_lo [(HI "3") (QI "1")]) | |
448 | ||
95223bca | 449 | ;; In HQI templates, a string like "llg<hc>" will expand to "llgh" in |
450 | ;; HImode and "llgc" in QImode. | |
451 | (define_mode_attr hc [(HI "h") (QI "c")]) | |
452 | ||
0eed6e19 | 453 | ;; In P templates, the mode <DBL> will expand to "TI" in DImode and "DI" |
454 | ;; in SImode. | |
455 | (define_mode_attr DBL [(DI "TI") (SI "DI")]) | |
456 | ||
1f8e70bc | 457 | ;; This attribute expands to DF for TFmode and to DD for TDmode . It is |
458 | ;; used for Txmode splitters splitting a Txmode copy into 2 Dxmode copies. | |
459 | (define_mode_attr HALF_TMODE [(TF "DF") (TD "DD")]) | |
460 | ||
02f6ff46 | 461 | ;; Maximum unsigned integer that fits in MODE. |
462 | (define_mode_attr max_uint [(HI "65535") (QI "255")]) | |
463 | ||
4673c1a0 | 464 | ;; |
465 | ;;- Compare instructions. | |
466 | ;; | |
467 | ||
2061f1ac | 468 | (define_expand "cmp<mode>" |
1ca361fd | 469 | [(set (reg:CC CC_REGNUM) |
2061f1ac | 470 | (compare:CC (match_operand:GPR 0 "register_operand" "") |
471 | (match_operand:GPR 1 "general_operand" "")))] | |
4673c1a0 | 472 | "" |
4673c1a0 | 473 | { |
474 | s390_compare_op0 = operands[0]; | |
475 | s390_compare_op1 = operands[1]; | |
476 | DONE; | |
83e641bd | 477 | }) |
4673c1a0 | 478 | |
8052065f | 479 | (define_expand "cmp<mode>" |
1ca361fd | 480 | [(set (reg:CC CC_REGNUM) |
1f8e70bc | 481 | (compare:CC (match_operand:FP 0 "register_operand" "") |
482 | (match_operand:FP 1 "general_operand" "")))] | |
4673c1a0 | 483 | "TARGET_HARD_FLOAT" |
4673c1a0 | 484 | { |
485 | s390_compare_op0 = operands[0]; | |
486 | s390_compare_op1 = operands[1]; | |
487 | DONE; | |
83e641bd | 488 | }) |
4673c1a0 | 489 | |
490 | ||
c6821d1c | 491 | ; Test-under-Mask instructions |
4673c1a0 | 492 | |
c6821d1c | 493 | (define_insn "*tmqi_mem" |
1ca361fd | 494 | [(set (reg CC_REGNUM) |
ebe32bb0 | 495 | (compare (and:QI (match_operand:QI 0 "memory_operand" "Q,S") |
496 | (match_operand:QI 1 "immediate_operand" "n,n")) | |
497 | (match_operand:QI 2 "immediate_operand" "n,n")))] | |
e5537457 | 498 | "s390_match_ccmode (insn, s390_tm_ccmode (operands[1], operands[2], false))" |
51aa1e9c | 499 | "@ |
0574acbe | 500 | tm\t%S0,%b1 |
501 | tmy\t%S0,%b1" | |
51aa1e9c | 502 | [(set_attr "op_type" "SI,SIY")]) |
4673c1a0 | 503 | |
2e5d1042 | 504 | (define_insn "*tmdi_reg" |
1ca361fd | 505 | [(set (reg CC_REGNUM) |
64a1078f | 506 | (compare (and:DI (match_operand:DI 0 "nonimmediate_operand" "d,d,d,d") |
346fecd5 | 507 | (match_operand:DI 1 "immediate_operand" |
64a1078f | 508 | "N0HD0,N1HD0,N2HD0,N3HD0")) |
509 | (match_operand:DI 2 "immediate_operand" "n,n,n,n")))] | |
2e5d1042 | 510 | "TARGET_64BIT |
e5537457 | 511 | && s390_match_ccmode (insn, s390_tm_ccmode (operands[1], operands[2], true)) |
64a1078f | 512 | && s390_single_part (operands[1], DImode, HImode, 0) >= 0" |
513 | "@ | |
514 | tmhh\t%0,%i1 | |
515 | tmhl\t%0,%i1 | |
516 | tmlh\t%0,%i1 | |
517 | tmll\t%0,%i1" | |
2e5d1042 | 518 | [(set_attr "op_type" "RI")]) |
519 | ||
520 | (define_insn "*tmsi_reg" | |
1ca361fd | 521 | [(set (reg CC_REGNUM) |
64a1078f | 522 | (compare (and:SI (match_operand:SI 0 "nonimmediate_operand" "d,d") |
523 | (match_operand:SI 1 "immediate_operand" "N0HS0,N1HS0")) | |
524 | (match_operand:SI 2 "immediate_operand" "n,n")))] | |
e5537457 | 525 | "s390_match_ccmode (insn, s390_tm_ccmode (operands[1], operands[2], true)) |
64a1078f | 526 | && s390_single_part (operands[1], SImode, HImode, 0) >= 0" |
527 | "@ | |
528 | tmh\t%0,%i1 | |
529 | tml\t%0,%i1" | |
2e5d1042 | 530 | [(set_attr "op_type" "RI")]) |
531 | ||
02f6ff46 | 532 | (define_insn "*tm<mode>_full" |
1ca361fd | 533 | [(set (reg CC_REGNUM) |
02f6ff46 | 534 | (compare (match_operand:HQI 0 "register_operand" "d") |
535 | (match_operand:HQI 1 "immediate_operand" "n")))] | |
e5537457 | 536 | "s390_match_ccmode (insn, s390_tm_ccmode (constm1_rtx, operands[1], true))" |
02f6ff46 | 537 | "tml\t%0,<max_uint>" |
c6821d1c | 538 | [(set_attr "op_type" "RI")]) |
4673c1a0 | 539 | |
c6821d1c | 540 | |
2e204c12 | 541 | ; |
c6821d1c | 542 | ; Load-and-Test instructions |
2e204c12 | 543 | ; |
544 | ||
334ec2d8 | 545 | ; tst(di|si) instruction pattern(s). |
c6821d1c | 546 | |
547 | (define_insn "*tstdi_sign" | |
1ca361fd | 548 | [(set (reg CC_REGNUM) |
e68d6a13 | 549 | (compare |
550 | (ashiftrt:DI | |
551 | (ashift:DI | |
552 | (subreg:DI (match_operand:SI 0 "nonimmediate_operand" "d,RT") 0) | |
553 | (const_int 32)) (const_int 32)) | |
554 | (match_operand:DI 1 "const0_operand" ""))) | |
555 | (set (match_operand:DI 2 "register_operand" "=d,d") | |
c6821d1c | 556 | (sign_extend:DI (match_dup 0)))] |
557 | "s390_match_ccmode(insn, CCSmode) && TARGET_64BIT" | |
e68d6a13 | 558 | "ltgfr\t%2,%0 |
559 | ltgf\t%2,%0" | |
560 | [(set_attr "op_type" "RRE,RXY") | |
561 | (set_attr "cpu_facility" "*,z10")]) | |
c6821d1c | 562 | |
87bc9927 | 563 | ; ltr, lt, ltgr, ltg |
2e204c12 | 564 | (define_insn "*tst<mode>_extimm" |
163277cf | 565 | [(set (reg CC_REGNUM) |
8fe52251 | 566 | (compare (match_operand:GPR 0 "nonimmediate_operand" "d,RT") |
2e204c12 | 567 | (match_operand:GPR 1 "const0_operand" ""))) |
568 | (set (match_operand:GPR 2 "register_operand" "=d,d") | |
163277cf | 569 | (match_dup 0))] |
2e204c12 | 570 | "s390_match_ccmode(insn, CCSmode) && TARGET_EXTIMM" |
163277cf | 571 | "@ |
2e204c12 | 572 | lt<g>r\t%2,%0 |
573 | lt<g>\t%2,%0" | |
574 | [(set_attr "op_type" "RR<E>,RXY")]) | |
163277cf | 575 | |
87bc9927 | 576 | ; ltr, lt, ltgr, ltg |
2e204c12 | 577 | (define_insn "*tst<mode>_cconly_extimm" |
163277cf | 578 | [(set (reg CC_REGNUM) |
8fe52251 | 579 | (compare (match_operand:GPR 0 "nonimmediate_operand" "d,RT") |
2e204c12 | 580 | (match_operand:GPR 1 "const0_operand" ""))) |
581 | (clobber (match_scratch:GPR 2 "=X,d"))] | |
582 | "s390_match_ccmode(insn, CCSmode) && TARGET_EXTIMM" | |
163277cf | 583 | "@ |
2e204c12 | 584 | lt<g>r\t%0,%0 |
585 | lt<g>\t%2,%0" | |
586 | [(set_attr "op_type" "RR<E>,RXY")]) | |
163277cf | 587 | |
c6821d1c | 588 | (define_insn "*tstdi" |
1ca361fd | 589 | [(set (reg CC_REGNUM) |
c6821d1c | 590 | (compare (match_operand:DI 0 "register_operand" "d") |
591 | (match_operand:DI 1 "const0_operand" ""))) | |
592 | (set (match_operand:DI 2 "register_operand" "=d") | |
593 | (match_dup 0))] | |
163277cf | 594 | "s390_match_ccmode(insn, CCSmode) && TARGET_64BIT && !TARGET_EXTIMM" |
f24d7ff3 | 595 | "ltgr\t%2,%0" |
c6821d1c | 596 | [(set_attr "op_type" "RRE")]) |
4673c1a0 | 597 | |
c6821d1c | 598 | (define_insn "*tstsi" |
1ca361fd | 599 | [(set (reg CC_REGNUM) |
51aa1e9c | 600 | (compare (match_operand:SI 0 "nonimmediate_operand" "d,Q,S") |
c6821d1c | 601 | (match_operand:SI 1 "const0_operand" ""))) |
51aa1e9c | 602 | (set (match_operand:SI 2 "register_operand" "=d,d,d") |
c6821d1c | 603 | (match_dup 0))] |
163277cf | 604 | "s390_match_ccmode(insn, CCSmode) && !TARGET_EXTIMM" |
c6821d1c | 605 | "@ |
f24d7ff3 | 606 | ltr\t%2,%0 |
0574acbe | 607 | icm\t%2,15,%S0 |
608 | icmy\t%2,15,%S0" | |
51aa1e9c | 609 | [(set_attr "op_type" "RR,RS,RSY")]) |
4673c1a0 | 610 | |
c6821d1c | 611 | (define_insn "*tstsi_cconly" |
1ca361fd | 612 | [(set (reg CC_REGNUM) |
51aa1e9c | 613 | (compare (match_operand:SI 0 "nonimmediate_operand" "d,Q,S") |
c6821d1c | 614 | (match_operand:SI 1 "const0_operand" ""))) |
51aa1e9c | 615 | (clobber (match_scratch:SI 2 "=X,d,d"))] |
c6821d1c | 616 | "s390_match_ccmode(insn, CCSmode)" |
617 | "@ | |
f24d7ff3 | 618 | ltr\t%0,%0 |
0574acbe | 619 | icm\t%2,15,%S0 |
620 | icmy\t%2,15,%S0" | |
51aa1e9c | 621 | [(set_attr "op_type" "RR,RS,RSY")]) |
8b4a4127 | 622 | |
2e204c12 | 623 | (define_insn "*tstdi_cconly_31" |
624 | [(set (reg CC_REGNUM) | |
625 | (compare (match_operand:DI 0 "register_operand" "d") | |
626 | (match_operand:DI 1 "const0_operand" "")))] | |
627 | "s390_match_ccmode(insn, CCSmode) && !TARGET_64BIT" | |
628 | "srda\t%0,0" | |
629 | [(set_attr "op_type" "RS") | |
630 | (set_attr "atype" "reg")]) | |
631 | ||
87bc9927 | 632 | ; ltr, ltgr |
2e204c12 | 633 | (define_insn "*tst<mode>_cconly2" |
1ca361fd | 634 | [(set (reg CC_REGNUM) |
2e204c12 | 635 | (compare (match_operand:GPR 0 "register_operand" "d") |
636 | (match_operand:GPR 1 "const0_operand" "")))] | |
c6821d1c | 637 | "s390_match_ccmode(insn, CCSmode)" |
2e204c12 | 638 | "lt<g>r\t%0,%0" |
639 | [(set_attr "op_type" "RR<E>")]) | |
640 | ||
334ec2d8 | 641 | ; tst(hi|qi) instruction pattern(s). |
8b4a4127 | 642 | |
02f6ff46 | 643 | (define_insn "*tst<mode>CCT" |
1ca361fd | 644 | [(set (reg CC_REGNUM) |
02f6ff46 | 645 | (compare (match_operand:HQI 0 "nonimmediate_operand" "?Q,?S,d") |
646 | (match_operand:HQI 1 "const0_operand" ""))) | |
647 | (set (match_operand:HQI 2 "register_operand" "=d,d,0") | |
679d27f3 | 648 | (match_dup 0))] |
649 | "s390_match_ccmode(insn, CCTmode)" | |
650 | "@ | |
02f6ff46 | 651 | icm\t%2,<icm_lo>,%S0 |
652 | icmy\t%2,<icm_lo>,%S0 | |
653 | tml\t%0,<max_uint>" | |
51aa1e9c | 654 | [(set_attr "op_type" "RS,RSY,RI")]) |
679d27f3 | 655 | |
656 | (define_insn "*tsthiCCT_cconly" | |
1ca361fd | 657 | [(set (reg CC_REGNUM) |
51aa1e9c | 658 | (compare (match_operand:HI 0 "nonimmediate_operand" "Q,S,d") |
679d27f3 | 659 | (match_operand:HI 1 "const0_operand" ""))) |
51aa1e9c | 660 | (clobber (match_scratch:HI 2 "=d,d,X"))] |
679d27f3 | 661 | "s390_match_ccmode(insn, CCTmode)" |
662 | "@ | |
0574acbe | 663 | icm\t%2,3,%S0 |
664 | icmy\t%2,3,%S0 | |
f24d7ff3 | 665 | tml\t%0,65535" |
51aa1e9c | 666 | [(set_attr "op_type" "RS,RSY,RI")]) |
679d27f3 | 667 | |
679d27f3 | 668 | (define_insn "*tstqiCCT_cconly" |
1ca361fd | 669 | [(set (reg CC_REGNUM) |
51aa1e9c | 670 | (compare (match_operand:QI 0 "nonimmediate_operand" "?Q,?S,d") |
679d27f3 | 671 | (match_operand:QI 1 "const0_operand" "")))] |
672 | "s390_match_ccmode(insn, CCTmode)" | |
673 | "@ | |
0574acbe | 674 | cli\t%S0,0 |
675 | cliy\t%S0,0 | |
f24d7ff3 | 676 | tml\t%0,255" |
51aa1e9c | 677 | [(set_attr "op_type" "SI,SIY,RI")]) |
679d27f3 | 678 | |
02f6ff46 | 679 | (define_insn "*tst<mode>" |
1ca361fd | 680 | [(set (reg CC_REGNUM) |
02f6ff46 | 681 | (compare (match_operand:HQI 0 "s_operand" "Q,S") |
682 | (match_operand:HQI 1 "const0_operand" ""))) | |
683 | (set (match_operand:HQI 2 "register_operand" "=d,d") | |
c6821d1c | 684 | (match_dup 0))] |
685 | "s390_match_ccmode(insn, CCSmode)" | |
51aa1e9c | 686 | "@ |
02f6ff46 | 687 | icm\t%2,<icm_lo>,%S0 |
688 | icmy\t%2,<icm_lo>,%S0" | |
51aa1e9c | 689 | [(set_attr "op_type" "RS,RSY")]) |
4673c1a0 | 690 | |
02f6ff46 | 691 | (define_insn "*tst<mode>_cconly" |
1ca361fd | 692 | [(set (reg CC_REGNUM) |
02f6ff46 | 693 | (compare (match_operand:HQI 0 "s_operand" "Q,S") |
694 | (match_operand:HQI 1 "const0_operand" ""))) | |
695 | (clobber (match_scratch:HQI 2 "=d,d"))] | |
c6821d1c | 696 | "s390_match_ccmode(insn, CCSmode)" |
51aa1e9c | 697 | "@ |
02f6ff46 | 698 | icm\t%2,<icm_lo>,%S0 |
699 | icmy\t%2,<icm_lo>,%S0" | |
51aa1e9c | 700 | [(set_attr "op_type" "RS,RSY")]) |
701 | ||
4673c1a0 | 702 | |
c029ded7 | 703 | ; Compare (equality) instructions |
704 | ||
705 | (define_insn "*cmpdi_cct" | |
1ca361fd | 706 | [(set (reg CC_REGNUM) |
163277cf | 707 | (compare (match_operand:DI 0 "nonimmediate_operand" "%d,d,d,d,Q") |
8fe52251 | 708 | (match_operand:DI 1 "general_operand" "d,K,Os,RT,BQ")))] |
6b1c8423 | 709 | "s390_match_ccmode (insn, CCTmode) && TARGET_64BIT" |
c029ded7 | 710 | "@ |
711 | cgr\t%0,%1 | |
4e70b35e | 712 | cghi\t%0,%h1 |
163277cf | 713 | cgfi\t%0,%1 |
c029ded7 | 714 | cg\t%0,%1 |
9dffd3ff | 715 | #" |
163277cf | 716 | [(set_attr "op_type" "RRE,RI,RIL,RXY,SS")]) |
c029ded7 | 717 | |
718 | (define_insn "*cmpsi_cct" | |
1ca361fd | 719 | [(set (reg CC_REGNUM) |
163277cf | 720 | (compare (match_operand:SI 0 "nonimmediate_operand" "%d,d,d,d,d,Q") |
721 | (match_operand:SI 1 "general_operand" "d,K,Os,R,T,BQ")))] | |
6b1c8423 | 722 | "s390_match_ccmode (insn, CCTmode)" |
c029ded7 | 723 | "@ |
724 | cr\t%0,%1 | |
4e70b35e | 725 | chi\t%0,%h1 |
163277cf | 726 | cfi\t%0,%1 |
c029ded7 | 727 | c\t%0,%1 |
728 | cy\t%0,%1 | |
9dffd3ff | 729 | #" |
163277cf | 730 | [(set_attr "op_type" "RR,RI,RIL,RX,RXY,SS")]) |
c029ded7 | 731 | |
732 | ||
c6821d1c | 733 | ; Compare (signed) instructions |
8b4a4127 | 734 | |
c6821d1c | 735 | (define_insn "*cmpdi_ccs_sign" |
1ca361fd | 736 | [(set (reg CC_REGNUM) |
e68d6a13 | 737 | (compare (sign_extend:DI (match_operand:SI 1 "nonimmediate_operand" |
738 | "d,RT,b")) | |
739 | (match_operand:DI 0 "register_operand" "d, d,d")))] | |
c6821d1c | 740 | "s390_match_ccmode(insn, CCSRmode) && TARGET_64BIT" |
8b4a4127 | 741 | "@ |
f24d7ff3 | 742 | cgfr\t%0,%1 |
e68d6a13 | 743 | cgf\t%0,%1 |
744 | cgfrl\t%0,%1" | |
745 | [(set_attr "op_type" "RRE,RXY,RIL") | |
746 | (set_attr "cpu_facility" "*,*,z10") | |
747 | (set_attr "type" "*,*,larl")]) | |
8b4a4127 | 748 | |
c6821d1c | 749 | (define_insn "*cmpsi_ccs_sign" |
1ca361fd | 750 | [(set (reg CC_REGNUM) |
e68d6a13 | 751 | (compare (sign_extend:SI (match_operand:HI 1 "memory_operand" "R,T,b")) |
752 | (match_operand:SI 0 "register_operand" "d,d,d")))] | |
c6821d1c | 753 | "s390_match_ccmode(insn, CCSRmode)" |
51aa1e9c | 754 | "@ |
f24d7ff3 | 755 | ch\t%0,%1 |
e68d6a13 | 756 | chy\t%0,%1 |
757 | chrl\t%0,%1" | |
758 | [(set_attr "op_type" "RX,RXY,RIL") | |
759 | (set_attr "cpu_facility" "*,*,z10") | |
760 | (set_attr "type" "*,*,larl")]) | |
761 | ||
762 | (define_insn "*cmphi_ccs_z10" | |
763 | [(set (reg CC_REGNUM) | |
764 | (compare (match_operand:HI 0 "s_operand" "Q") | |
765 | (match_operand:HI 1 "immediate_operand" "K")))] | |
766 | "s390_match_ccmode(insn, CCSmode) && TARGET_Z10" | |
767 | "chhsi\t%0,%1" | |
768 | [(set_attr "op_type" "SIL")]) | |
769 | ||
770 | (define_insn "*cmpdi_ccs_signhi_rl" | |
771 | [(set (reg CC_REGNUM) | |
772 | (compare (sign_extend:DI (match_operand:HI 1 "memory_operand" "RT,b")) | |
773 | (match_operand:GPR 0 "register_operand" "d,d")))] | |
774 | "s390_match_ccmode(insn, CCSRmode) && TARGET_Z10" | |
775 | "@ | |
776 | cgh\t%0,%1 | |
777 | cghrl\t%0,%1" | |
778 | [(set_attr "op_type" "RXY,RIL") | |
779 | (set_attr "type" "*,larl")]) | |
8b4a4127 | 780 | |
e68d6a13 | 781 | ; cr, chi, cfi, c, cy, cgr, cghi, cgfi, cg, chsi, cghsi, crl, cgrl |
d1641800 | 782 | (define_insn "*cmp<mode>_ccs" |
1ca361fd | 783 | [(set (reg CC_REGNUM) |
e68d6a13 | 784 | (compare (match_operand:GPR 0 "nonimmediate_operand" |
785 | "d,d,Q, d,d,d,d") | |
786 | (match_operand:GPR 1 "general_operand" | |
787 | "d,K,K,Os,R,T,b")))] | |
4673c1a0 | 788 | "s390_match_ccmode(insn, CCSmode)" |
c6821d1c | 789 | "@ |
d1641800 | 790 | c<g>r\t%0,%1 |
791 | c<g>hi\t%0,%h1 | |
e68d6a13 | 792 | c<g>hsi\t%0,%h1 |
d1641800 | 793 | c<g>fi\t%0,%1 |
794 | c<g>\t%0,%1 | |
e68d6a13 | 795 | c<y>\t%0,%1 |
796 | c<g>rl\t%0,%1" | |
797 | [(set_attr "op_type" "RR<E>,RI,SIL,RIL,RX<Y>,RXY,RIL") | |
798 | (set_attr "cpu_facility" "*,*,z10,extimm,*,*,z10") | |
799 | (set_attr "type" "*,*,*,*,*,*,larl")]) | |
f81e845f | 800 | |
c6821d1c | 801 | |
802 | ; Compare (unsigned) instructions | |
4673c1a0 | 803 | |
e68d6a13 | 804 | (define_insn "*cmpsi_ccu_zerohi_rlsi" |
805 | [(set (reg CC_REGNUM) | |
806 | (compare (zero_extend:SI (mem:HI (match_operand:SI 1 | |
807 | "larl_operand" "X"))) | |
808 | (match_operand:SI 0 "register_operand" "d")))] | |
809 | "s390_match_ccmode(insn, CCURmode) && TARGET_Z10" | |
810 | "clhrl\t%0,%1" | |
811 | [(set_attr "op_type" "RIL") | |
812 | (set_attr "type" "larl")]) | |
813 | ||
814 | ; clhrl, clghrl | |
815 | (define_insn "*cmp<GPR:mode>_ccu_zerohi_rldi" | |
816 | [(set (reg CC_REGNUM) | |
817 | (compare (zero_extend:GPR (mem:HI (match_operand:DI 1 | |
818 | "larl_operand" "X"))) | |
819 | (match_operand:GPR 0 "register_operand" "d")))] | |
820 | "s390_match_ccmode(insn, CCURmode) && TARGET_Z10" | |
821 | "cl<g>hrl\t%0,%1" | |
822 | [(set_attr "op_type" "RIL") | |
823 | (set_attr "type" "larl")]) | |
824 | ||
c6821d1c | 825 | (define_insn "*cmpdi_ccu_zero" |
1ca361fd | 826 | [(set (reg CC_REGNUM) |
e68d6a13 | 827 | (compare (zero_extend:DI (match_operand:SI 1 "nonimmediate_operand" |
828 | "d,RT,b")) | |
829 | (match_operand:DI 0 "register_operand" "d, d,d")))] | |
c029ded7 | 830 | "s390_match_ccmode (insn, CCURmode) && TARGET_64BIT" |
c6821d1c | 831 | "@ |
f24d7ff3 | 832 | clgfr\t%0,%1 |
e68d6a13 | 833 | clgf\t%0,%1 |
834 | clgfrl\t%0,%1" | |
835 | [(set_attr "op_type" "RRE,RXY,RIL") | |
836 | (set_attr "cpu_facility" "*,*,z10") | |
837 | (set_attr "type" "*,*,larl")]) | |
4673c1a0 | 838 | |
c6821d1c | 839 | (define_insn "*cmpdi_ccu" |
1ca361fd | 840 | [(set (reg CC_REGNUM) |
e68d6a13 | 841 | (compare (match_operand:DI 0 "nonimmediate_operand" |
842 | "d, d,d,Q, d, Q,BQ") | |
843 | (match_operand:DI 1 "general_operand" | |
844 | "d,Op,b,D,RT,BQ,Q")))] | |
6b1c8423 | 845 | "s390_match_ccmode (insn, CCUmode) && TARGET_64BIT" |
c6821d1c | 846 | "@ |
f24d7ff3 | 847 | clgr\t%0,%1 |
163277cf | 848 | clgfi\t%0,%1 |
e68d6a13 | 849 | clgrl\t%0,%1 |
850 | clghsi\t%0,%x1 | |
c029ded7 | 851 | clg\t%0,%1 |
6b1c8423 | 852 | # |
9dffd3ff | 853 | #" |
e68d6a13 | 854 | [(set_attr "op_type" "RRE,RIL,RIL,SIL,RXY,SS,SS") |
855 | (set_attr "cpu_facility" "*,extimm,z10,z10,*,*,*") | |
856 | (set_attr "type" "*,*,larl,*,*,*,*")]) | |
4673c1a0 | 857 | |
c6821d1c | 858 | (define_insn "*cmpsi_ccu" |
1ca361fd | 859 | [(set (reg CC_REGNUM) |
e68d6a13 | 860 | (compare (match_operand:SI 0 "nonimmediate_operand" "d, d,d,Q,d,d, Q,BQ") |
861 | (match_operand:SI 1 "general_operand" "d,Os,b,D,R,T,BQ, Q")))] | |
6b1c8423 | 862 | "s390_match_ccmode (insn, CCUmode)" |
c6821d1c | 863 | "@ |
f24d7ff3 | 864 | clr\t%0,%1 |
163277cf | 865 | clfi\t%0,%o1 |
e68d6a13 | 866 | clrl\t%0,%1 |
867 | clfhsi\t%0,%x1 | |
f24d7ff3 | 868 | cl\t%0,%1 |
c029ded7 | 869 | cly\t%0,%1 |
6b1c8423 | 870 | # |
9dffd3ff | 871 | #" |
e68d6a13 | 872 | [(set_attr "op_type" "RR,RIL,RIL,SIL,RX,RXY,SS,SS") |
873 | (set_attr "cpu_facility" "*,extimm,z10,z10,*,*,*,*") | |
874 | (set_attr "type" "*,*,larl,*,*,*,*,*")]) | |
4673c1a0 | 875 | |
c6821d1c | 876 | (define_insn "*cmphi_ccu" |
1ca361fd | 877 | [(set (reg CC_REGNUM) |
e68d6a13 | 878 | (compare (match_operand:HI 0 "nonimmediate_operand" "d,d,Q,Q,BQ") |
879 | (match_operand:HI 1 "general_operand" "Q,S,D,BQ,Q")))] | |
c029ded7 | 880 | "s390_match_ccmode (insn, CCUmode) |
c029ded7 | 881 | && !register_operand (operands[1], HImode)" |
51aa1e9c | 882 | "@ |
0574acbe | 883 | clm\t%0,3,%S1 |
884 | clmy\t%0,3,%S1 | |
e68d6a13 | 885 | clhhsi\t%0,%1 |
6b1c8423 | 886 | # |
9dffd3ff | 887 | #" |
e68d6a13 | 888 | [(set_attr "op_type" "RS,RSY,SIL,SS,SS") |
889 | (set_attr "cpu_facility" "*,*,z10,*,*")]) | |
4673c1a0 | 890 | |
891 | (define_insn "*cmpqi_ccu" | |
1ca361fd | 892 | [(set (reg CC_REGNUM) |
6b1c8423 | 893 | (compare (match_operand:QI 0 "nonimmediate_operand" "d,d,Q,S,Q,BQ") |
894 | (match_operand:QI 1 "general_operand" "Q,S,n,n,BQ,Q")))] | |
c029ded7 | 895 | "s390_match_ccmode (insn, CCUmode) |
c029ded7 | 896 | && !register_operand (operands[1], QImode)" |
51aa1e9c | 897 | "@ |
0574acbe | 898 | clm\t%0,1,%S1 |
899 | clmy\t%0,1,%S1 | |
900 | cli\t%S0,%b1 | |
901 | cliy\t%S0,%b1 | |
6b1c8423 | 902 | # |
9dffd3ff | 903 | #" |
6b1c8423 | 904 | [(set_attr "op_type" "RS,RSY,SI,SIY,SS,SS")]) |
4673c1a0 | 905 | |
906 | ||
9dffd3ff | 907 | ; Block compare (CLC) instruction patterns. |
908 | ||
909 | (define_insn "*clc" | |
1ca361fd | 910 | [(set (reg CC_REGNUM) |
9f872a62 | 911 | (compare (match_operand:BLK 0 "memory_operand" "Q") |
9dffd3ff | 912 | (match_operand:BLK 1 "memory_operand" "Q"))) |
913 | (use (match_operand 2 "const_int_operand" "n"))] | |
914 | "s390_match_ccmode (insn, CCUmode) | |
915 | && INTVAL (operands[2]) >= 1 && INTVAL (operands[2]) <= 256" | |
0574acbe | 916 | "clc\t%O0(%2,%R0),%S1" |
1822f0d6 | 917 | [(set_attr "op_type" "SS")]) |
9dffd3ff | 918 | |
919 | (define_split | |
1ca361fd | 920 | [(set (reg CC_REGNUM) |
9dffd3ff | 921 | (compare (match_operand 0 "memory_operand" "") |
922 | (match_operand 1 "memory_operand" "")))] | |
923 | "reload_completed | |
924 | && s390_match_ccmode (insn, CCUmode) | |
925 | && GET_MODE (operands[0]) == GET_MODE (operands[1]) | |
926 | && GET_MODE_SIZE (GET_MODE (operands[0])) > 0" | |
927 | [(parallel | |
928 | [(set (match_dup 0) (match_dup 1)) | |
929 | (use (match_dup 2))])] | |
930 | { | |
931 | operands[2] = GEN_INT (GET_MODE_SIZE (GET_MODE (operands[0]))); | |
932 | operands[0] = adjust_address (operands[0], BLKmode, 0); | |
933 | operands[1] = adjust_address (operands[1], BLKmode, 0); | |
934 | ||
935 | operands[1] = gen_rtx_COMPARE (GET_MODE (SET_DEST (PATTERN (curr_insn))), | |
936 | operands[0], operands[1]); | |
937 | operands[0] = SET_DEST (PATTERN (curr_insn)); | |
938 | }) | |
939 | ||
940 | ||
1f8e70bc | 941 | ; (TF|DF|SF|TD|DD|SD) instructions |
4673c1a0 | 942 | |
1f8e70bc | 943 | ; ltxbr, ltdbr, ltebr, ltxtr, ltdtr |
8052065f | 944 | (define_insn "*cmp<mode>_ccs_0" |
1ca361fd | 945 | [(set (reg CC_REGNUM) |
1f8e70bc | 946 | (compare (match_operand:FP 0 "register_operand" "f") |
947 | (match_operand:FP 1 "const0_operand" "")))] | |
095798e3 | 948 | "s390_match_ccmode(insn, CCSmode) && TARGET_HARD_FLOAT" |
1f8e70bc | 949 | "lt<xde><bt>r\t%0,%0" |
71343e6b | 950 | [(set_attr "op_type" "RRE") |
1f8e70bc | 951 | (set_attr "type" "fsimp<bfp>")]) |
4673c1a0 | 952 | |
1f8e70bc | 953 | ; cxtr, cxbr, cdbr, cebr, cxb, cdb, ceb, cxbtr, cdbtr |
8052065f | 954 | (define_insn "*cmp<mode>_ccs" |
1ca361fd | 955 | [(set (reg CC_REGNUM) |
1f8e70bc | 956 | (compare (match_operand:FP 0 "register_operand" "f,f") |
957 | (match_operand:FP 1 "general_operand" "f,<Rf>")))] | |
095798e3 | 958 | "s390_match_ccmode(insn, CCSmode) && TARGET_HARD_FLOAT" |
4673c1a0 | 959 | "@ |
1f8e70bc | 960 | c<xde><bt>r\t%0,%1 |
429f9fdb | 961 | c<xde>b\t%0,%1" |
71343e6b | 962 | [(set_attr "op_type" "RRE,RXE") |
1f8e70bc | 963 | (set_attr "type" "fsimp<bfp>")]) |
4673c1a0 | 964 | |
e68d6a13 | 965 | |
966 | ; Compare and Branch instructions | |
967 | ||
968 | ; cij, cgij, crj, cgrj, cfi, cgfi, cr, cgr | |
969 | (define_insn "*cmp_and_br_signed_<mode>" | |
970 | [(set (pc) | |
971 | (if_then_else (match_operator 0 "s390_signed_integer_comparison" | |
972 | [(match_operand:GPR 1 "register_operand" "d,d") | |
973 | (match_operand:GPR 2 "nonmemory_operand" "d,C")]) | |
974 | (label_ref (match_operand 3 "" "")) | |
975 | (pc))) | |
976 | (clobber (reg:CC CC_REGNUM))] | |
977 | "TARGET_Z10" | |
978 | { | |
979 | if (get_attr_length (insn) == 6) | |
980 | return which_alternative ? | |
981 | "c<g>ij%C0\t%1,%c2,%l3" : "c<g>rj%C0\t%1,%2,%l3"; | |
982 | else | |
983 | return which_alternative ? | |
984 | "c<g>fi\t%1,%c2\;jg%C0\t%l3" : "c<g>r\t%1,%2\;jg%C0\t%l3"; | |
985 | } | |
986 | [(set_attr "op_type" "RIE") | |
987 | (set_attr "type" "branch") | |
988 | (set (attr "length") | |
989 | (if_then_else (lt (abs (minus (pc) (match_dup 3))) (const_int 60000)) | |
990 | (const_int 6) (const_int 12)))]) ; 8 byte for cr/jg | |
991 | ; 10 byte for cgr/jg | |
992 | ||
993 | ; clij, clgij, clrj, clgrj, clfi, clgfi, clr, clgr | |
994 | (define_insn "*cmp_and_br_unsigned_<mode>" | |
995 | [(set (pc) | |
996 | (if_then_else (match_operator 0 "s390_unsigned_integer_comparison" | |
997 | [(match_operand:GPR 1 "register_operand" "d,d") | |
998 | (match_operand:GPR 2 "nonmemory_operand" "d,I")]) | |
999 | (label_ref (match_operand 3 "" "")) | |
1000 | (pc))) | |
1001 | (clobber (reg:CC CC_REGNUM))] | |
1002 | "TARGET_Z10" | |
1003 | { | |
1004 | if (get_attr_length (insn) == 6) | |
1005 | return which_alternative ? | |
1006 | "cl<g>ij%C0\t%1,%b2,%l3" : "cl<g>rj%C0\t%1,%2,%l3"; | |
1007 | else | |
1008 | return which_alternative ? | |
1009 | "cl<g>fi\t%1,%b2\;jg%C0\t%l3" : "cl<g>r\t%1,%2\;jg%C0\t%l3"; | |
1010 | } | |
1011 | [(set_attr "op_type" "RIE") | |
1012 | (set_attr "type" "branch") | |
1013 | (set (attr "length") | |
1014 | (if_then_else (lt (abs (minus (pc) (match_dup 3))) (const_int 60000)) | |
1015 | (const_int 6) (const_int 12)))]) ; 8 byte for clr/jg | |
1016 | ; 10 byte for clgr/jg | |
1017 | ||
4673c1a0 | 1018 | ;; |
1019 | ;;- Move instructions. | |
1020 | ;; | |
1021 | ||
1022 | ; | |
1023 | ; movti instruction pattern(s). | |
1024 | ; | |
1025 | ||
1026 | (define_insn "movti" | |
51aa1e9c | 1027 | [(set (match_operand:TI 0 "nonimmediate_operand" "=d,QS,d,o,Q") |
8fe52251 | 1028 | (match_operand:TI 1 "general_operand" "QS,d,dPRT,d,Q"))] |
4673c1a0 | 1029 | "TARGET_64BIT" |
8b4a4127 | 1030 | "@ |
0574acbe | 1031 | lmg\t%0,%N0,%S1 |
1032 | stmg\t%1,%N1,%S0 | |
8b4a4127 | 1033 | # |
957d1b91 | 1034 | # |
9dffd3ff | 1035 | #" |
1822f0d6 | 1036 | [(set_attr "op_type" "RSY,RSY,*,*,SS") |
1037 | (set_attr "type" "lm,stm,*,*,*")]) | |
8b4a4127 | 1038 | |
1039 | (define_split | |
1040 | [(set (match_operand:TI 0 "nonimmediate_operand" "") | |
1041 | (match_operand:TI 1 "general_operand" ""))] | |
1042 | "TARGET_64BIT && reload_completed | |
66795431 | 1043 | && s390_split_ok_p (operands[0], operands[1], TImode, 0)" |
8b4a4127 | 1044 | [(set (match_dup 2) (match_dup 4)) |
1045 | (set (match_dup 3) (match_dup 5))] | |
4673c1a0 | 1046 | { |
66795431 | 1047 | operands[2] = operand_subword (operands[0], 0, 0, TImode); |
1048 | operands[3] = operand_subword (operands[0], 1, 0, TImode); | |
1049 | operands[4] = operand_subword (operands[1], 0, 0, TImode); | |
1050 | operands[5] = operand_subword (operands[1], 1, 0, TImode); | |
1051 | }) | |
1052 | ||
1053 | (define_split | |
1054 | [(set (match_operand:TI 0 "nonimmediate_operand" "") | |
1055 | (match_operand:TI 1 "general_operand" ""))] | |
1056 | "TARGET_64BIT && reload_completed | |
1057 | && s390_split_ok_p (operands[0], operands[1], TImode, 1)" | |
1058 | [(set (match_dup 2) (match_dup 4)) | |
1059 | (set (match_dup 3) (match_dup 5))] | |
1060 | { | |
1061 | operands[2] = operand_subword (operands[0], 1, 0, TImode); | |
1062 | operands[3] = operand_subword (operands[0], 0, 0, TImode); | |
1063 | operands[4] = operand_subword (operands[1], 1, 0, TImode); | |
1064 | operands[5] = operand_subword (operands[1], 0, 0, TImode); | |
1065 | }) | |
8b4a4127 | 1066 | |
1067 | (define_split | |
1068 | [(set (match_operand:TI 0 "register_operand" "") | |
1069 | (match_operand:TI 1 "memory_operand" ""))] | |
1070 | "TARGET_64BIT && reload_completed | |
1071 | && !s_operand (operands[1], VOIDmode)" | |
4fbc4db5 | 1072 | [(set (match_dup 0) (match_dup 1))] |
4fbc4db5 | 1073 | { |
1074 | rtx addr = operand_subword (operands[0], 1, 0, TImode); | |
1075 | s390_load_address (addr, XEXP (operands[1], 0)); | |
1076 | operands[1] = replace_equiv_address (operands[1], addr); | |
66795431 | 1077 | }) |
1078 | ||
328d5423 | 1079 | |
1080 | ; | |
1081 | ; Patterns used for secondary reloads | |
1082 | ; | |
1083 | ||
e68d6a13 | 1084 | ; z10 provides move instructions accepting larl memory operands. |
1085 | ; Unfortunately there is no such variant for QI, TI and FP mode moves. | |
1086 | ; These patterns are also used for unaligned SI and DI accesses. | |
1087 | ||
1088 | (define_expand "reload<INTALL:mode><P:mode>_tomem_z10" | |
1089 | [(parallel [(match_operand:INTALL 0 "memory_operand" "") | |
1090 | (match_operand:INTALL 1 "register_operand" "=d") | |
1091 | (match_operand:P 2 "register_operand" "=&a")])] | |
1092 | "TARGET_Z10" | |
1093 | { | |
1094 | s390_reload_symref_address (operands[1], operands[0], operands[2], 1); | |
1095 | DONE; | |
1096 | }) | |
1097 | ||
1098 | (define_expand "reload<INTALL:mode><P:mode>_toreg_z10" | |
1099 | [(parallel [(match_operand:INTALL 0 "register_operand" "=d") | |
1100 | (match_operand:INTALL 1 "memory_operand" "") | |
1101 | (match_operand:P 2 "register_operand" "=a")])] | |
1102 | "TARGET_Z10" | |
1103 | { | |
1104 | s390_reload_symref_address (operands[0], operands[1], operands[2], 0); | |
1105 | DONE; | |
1106 | }) | |
1107 | ||
1108 | (define_expand "reload<FPALL:mode><P:mode>_tomem_z10" | |
1109 | [(parallel [(match_operand:FPALL 0 "memory_operand" "") | |
1110 | (match_operand:FPALL 1 "register_operand" "=d") | |
1111 | (match_operand:P 2 "register_operand" "=&a")])] | |
1112 | "TARGET_Z10" | |
1113 | { | |
1114 | s390_reload_symref_address (operands[1], operands[0], operands[2], 1); | |
1115 | DONE; | |
1116 | }) | |
1117 | ||
1118 | (define_expand "reload<FPALL:mode><P:mode>_toreg_z10" | |
1119 | [(parallel [(match_operand:FPALL 0 "register_operand" "=d") | |
1120 | (match_operand:FPALL 1 "memory_operand" "") | |
1121 | (match_operand:P 2 "register_operand" "=a")])] | |
1122 | "TARGET_Z10" | |
1123 | { | |
1124 | s390_reload_symref_address (operands[0], operands[1], operands[2], 0); | |
1125 | DONE; | |
1126 | }) | |
1127 | ||
1128 | (define_expand "reload<P:mode>_larl_odd_addend_z10" | |
1129 | [(parallel [(match_operand:P 0 "register_operand" "=d") | |
1130 | (match_operand:P 1 "larl_operand" "") | |
1131 | (match_operand:P 2 "register_operand" "=a")])] | |
1132 | "TARGET_Z10" | |
1133 | { | |
1134 | s390_reload_larl_operand (operands[0], operands[1], operands[2]); | |
1135 | DONE; | |
1136 | }) | |
1137 | ||
328d5423 | 1138 | ; Handles loading a PLUS (load address) expression |
1139 | ||
1140 | (define_expand "reload<mode>_plus" | |
1141 | [(parallel [(match_operand:P 0 "register_operand" "=a") | |
1142 | (match_operand:P 1 "s390_plus_operand" "") | |
1143 | (match_operand:P 2 "register_operand" "=&a")])] | |
1144 | "" | |
1145 | { | |
1146 | s390_expand_plus_operand (operands[0], operands[1], operands[2]); | |
1147 | DONE; | |
1148 | }) | |
1149 | ||
1150 | ; Handles assessing a non-offsetable memory address | |
1151 | ||
1152 | (define_expand "reload<mode>_nonoffmem_in" | |
1153 | [(parallel [(match_operand 0 "register_operand" "") | |
1154 | (match_operand 1 "" "") | |
1155 | (match_operand:P 2 "register_operand" "=&a")])] | |
1156 | "" | |
1157 | { | |
1158 | gcc_assert (MEM_P (operands[1])); | |
1159 | s390_load_address (operands[2], find_replacement (&XEXP (operands[1], 0))); | |
1160 | operands[1] = replace_equiv_address (operands[1], operands[2]); | |
1161 | emit_move_insn (operands[0], operands[1]); | |
1162 | DONE; | |
1163 | }) | |
1164 | ||
1165 | (define_expand "reload<mode>_nonoffmem_out" | |
1166 | [(parallel [(match_operand 0 "" "") | |
1167 | (match_operand 1 "register_operand" "") | |
1168 | (match_operand:P 2 "register_operand" "=&a")])] | |
1169 | "" | |
66795431 | 1170 | { |
79b312b6 | 1171 | gcc_assert (MEM_P (operands[0])); |
be6f2308 | 1172 | s390_load_address (operands[2], find_replacement (&XEXP (operands[0], 0))); |
66795431 | 1173 | operands[0] = replace_equiv_address (operands[0], operands[2]); |
1174 | emit_move_insn (operands[0], operands[1]); | |
1175 | DONE; | |
1176 | }) | |
4673c1a0 | 1177 | |
08b5e262 | 1178 | (define_expand "reload<mode>_PIC_addr" |
1179 | [(parallel [(match_operand 0 "register_operand" "=d") | |
1180 | (match_operand 1 "larl_operand" "") | |
1181 | (match_operand:P 2 "register_operand" "=a")])] | |
1182 | "" | |
1183 | { | |
8deb3959 | 1184 | rtx new_rtx = legitimize_pic_address (operands[1], operands[2]); |
1185 | emit_move_insn (operands[0], new_rtx); | |
08b5e262 | 1186 | }) |
1187 | ||
4673c1a0 | 1188 | ; |
1189 | ; movdi instruction pattern(s). | |
1190 | ; | |
1191 | ||
4673c1a0 | 1192 | (define_expand "movdi" |
1193 | [(set (match_operand:DI 0 "general_operand" "") | |
1194 | (match_operand:DI 1 "general_operand" ""))] | |
1195 | "" | |
4673c1a0 | 1196 | { |
be00aaa8 | 1197 | /* Handle symbolic constants. */ |
abbcecd2 | 1198 | if (TARGET_64BIT |
1199 | && (SYMBOLIC_CONST (operands[1]) | |
1200 | || (GET_CODE (operands[1]) == PLUS | |
1201 | && XEXP (operands[1], 0) == pic_offset_table_rtx | |
1202 | && SYMBOLIC_CONST (XEXP (operands[1], 1))))) | |
be00aaa8 | 1203 | emit_symbolic_move (operands); |
83e641bd | 1204 | }) |
4673c1a0 | 1205 | |
8b4a4127 | 1206 | (define_insn "*movdi_larl" |
1207 | [(set (match_operand:DI 0 "register_operand" "=d") | |
1208 | (match_operand:DI 1 "larl_operand" "X"))] | |
1209 | "TARGET_64BIT | |
25da9e9f | 1210 | && !FP_REG_P (operands[0])" |
f24d7ff3 | 1211 | "larl\t%0,%1" |
8b4a4127 | 1212 | [(set_attr "op_type" "RIL") |
71343e6b | 1213 | (set_attr "type" "larl")]) |
8b4a4127 | 1214 | |
562d1970 | 1215 | (define_insn "*movdi_64" |
0c2edaa7 | 1216 | [(set (match_operand:DI 0 "nonimmediate_operand" |
e68d6a13 | 1217 | "=d,d,d,d,d,d,d,d,f,d,d,d,d,d, |
1218 | RT,!*f,!*f,!*f,!R,!T,b,Q,d,t,Q,t,?Q") | |
0c2edaa7 | 1219 | (match_operand:DI 1 "general_operand" |
e68d6a13 | 1220 | "K,N0HD0,N1HD0,N2HD0,N3HD0,Os,N0SD0,N1SD0,d,f,L,b,d,RT, |
1221 | d,*f,R,T,*f,*f,d,K,t,d,t,Q,?Q"))] | |
562d1970 | 1222 | "TARGET_64BIT" |
0c2edaa7 | 1223 | "@ |
1224 | lghi\t%0,%h1 | |
1225 | llihh\t%0,%i1 | |
1226 | llihl\t%0,%i1 | |
1227 | llilh\t%0,%i1 | |
1228 | llill\t%0,%i1 | |
1229 | lgfi\t%0,%1 | |
1230 | llihf\t%0,%k1 | |
1231 | llilf\t%0,%k1 | |
1232 | ldgr\t%0,%1 | |
1233 | lgdr\t%0,%1 | |
1234 | lay\t%0,%a1 | |
e68d6a13 | 1235 | lgrl\t%0,%1 |
0c2edaa7 | 1236 | lgr\t%0,%1 |
1237 | lg\t%0,%1 | |
1238 | stg\t%1,%0 | |
1239 | ldr\t%0,%1 | |
1240 | ld\t%0,%1 | |
1241 | ldy\t%0,%1 | |
1242 | std\t%1,%0 | |
1243 | stdy\t%1,%0 | |
e68d6a13 | 1244 | stgrl\t%1,%0 |
1245 | mvghi\t%0,%1 | |
0c2edaa7 | 1246 | # |
1247 | # | |
1248 | stam\t%1,%N1,%S0 | |
1249 | lam\t%0,%N0,%S1 | |
1250 | #" | |
e68d6a13 | 1251 | [(set_attr "op_type" "RI,RI,RI,RI,RI,RIL,RIL,RIL,RRE,RRE,RXY,RIL,RRE,RXY, |
1252 | RXY,RR,RX,RXY,RX,RXY,RIL,SIL,*,*,RS,RS,SS") | |
1253 | (set_attr "type" "*,*,*,*,*,*,*,*,floaddf,floaddf,la,larl,lr,load,store, | |
1254 | floaddf,floaddf,floaddf,fstoredf,fstoredf,larl,*,*,*, | |
1255 | *,*,*") | |
562d1970 | 1256 | (set_attr "cpu_facility" "*,*,*,*,*,extimm,extimm,extimm,dfp,dfp,longdisp, |
e68d6a13 | 1257 | z10,*,*,*,*,*,longdisp,*,longdisp, |
1258 | z10,z10,*,*,*,*,*")]) | |
923cf36d | 1259 | |
1260 | (define_split | |
1261 | [(set (match_operand:DI 0 "register_operand" "") | |
1262 | (match_operand:DI 1 "register_operand" ""))] | |
1263 | "TARGET_64BIT && ACCESS_REG_P (operands[1])" | |
1264 | [(set (match_dup 2) (match_dup 3)) | |
1265 | (set (match_dup 0) (ashift:DI (match_dup 0) (const_int 32))) | |
1266 | (set (strict_low_part (match_dup 2)) (match_dup 4))] | |
1267 | "operands[2] = gen_lowpart (SImode, operands[0]); | |
1268 | s390_split_access_reg (operands[1], &operands[4], &operands[3]);") | |
1269 | ||
1270 | (define_split | |
1271 | [(set (match_operand:DI 0 "register_operand" "") | |
1272 | (match_operand:DI 1 "register_operand" ""))] | |
1273 | "TARGET_64BIT && ACCESS_REG_P (operands[0]) | |
1274 | && dead_or_set_p (insn, operands[1])" | |
1275 | [(set (match_dup 3) (match_dup 2)) | |
1276 | (set (match_dup 1) (lshiftrt:DI (match_dup 1) (const_int 32))) | |
1277 | (set (match_dup 4) (match_dup 2))] | |
1278 | "operands[2] = gen_lowpart (SImode, operands[1]); | |
1279 | s390_split_access_reg (operands[0], &operands[3], &operands[4]);") | |
1280 | ||
1281 | (define_split | |
1282 | [(set (match_operand:DI 0 "register_operand" "") | |
1283 | (match_operand:DI 1 "register_operand" ""))] | |
1284 | "TARGET_64BIT && ACCESS_REG_P (operands[0]) | |
1285 | && !dead_or_set_p (insn, operands[1])" | |
1286 | [(set (match_dup 3) (match_dup 2)) | |
1287 | (set (match_dup 1) (rotate:DI (match_dup 1) (const_int 32))) | |
1288 | (set (match_dup 4) (match_dup 2)) | |
1289 | (set (match_dup 1) (rotate:DI (match_dup 1) (const_int 32)))] | |
1290 | "operands[2] = gen_lowpart (SImode, operands[1]); | |
1291 | s390_split_access_reg (operands[0], &operands[3], &operands[4]);") | |
4673c1a0 | 1292 | |
1293 | (define_insn "*movdi_31" | |
e68d6a13 | 1294 | [(set (match_operand:DI 0 "nonimmediate_operand" |
1295 | "=d,d,Q,S,d ,o,!*f,!*f,!*f,!R,!T,Q,d") | |
1296 | (match_operand:DI 1 "general_operand" | |
1297 | " Q,S,d,d,dPRT,d, *f, R, T,*f,*f,Q,b"))] | |
4673c1a0 | 1298 | "!TARGET_64BIT" |
8b4a4127 | 1299 | "@ |
0574acbe | 1300 | lm\t%0,%N0,%S1 |
0451e449 | 1301 | lmy\t%0,%N0,%S1 |
0574acbe | 1302 | stm\t%1,%N1,%S0 |
0451e449 | 1303 | stmy\t%1,%N1,%S0 |
8b4a4127 | 1304 | # |
1305 | # | |
f24d7ff3 | 1306 | ldr\t%0,%1 |
1307 | ld\t%0,%1 | |
1308 | ldy\t%0,%1 | |
1309 | std\t%1,%0 | |
1310 | stdy\t%1,%0 | |
e68d6a13 | 1311 | # |
9dffd3ff | 1312 | #" |
e68d6a13 | 1313 | [(set_attr "op_type" "RS,RSY,RS,RSY,*,*,RR,RX,RXY,RX,RXY,SS,*") |
1314 | (set_attr "type" "lm,lm,stm,stm,*,*,floaddf,floaddf,floaddf,fstoredf,fstoredf,*,*") | |
1315 | (set_attr "cpu_facility" "*,*,*,*,*,*,*,*,*,*,*,*,z10")]) | |
1316 | ||
1317 | ; For a load from a symbol ref we can use one of the target registers | |
1318 | ; together with larl to load the address. | |
1319 | (define_split | |
1320 | [(set (match_operand:DI 0 "register_operand" "") | |
1321 | (match_operand:DI 1 "memory_operand" ""))] | |
1322 | "!TARGET_64BIT && reload_completed && TARGET_Z10 | |
1323 | && larl_operand (XEXP (operands[1], 0), SImode)" | |
1324 | [(set (match_dup 2) (match_dup 3)) | |
1325 | (set (match_dup 0) (match_dup 1))] | |
1326 | { | |
1327 | operands[2] = operand_subword (operands[0], 1, 0, DImode); | |
1328 | operands[3] = XEXP (operands[1], 0); | |
1329 | operands[1] = replace_equiv_address (operands[1], operands[2]); | |
1330 | }) | |
8b4a4127 | 1331 | |
1332 | (define_split | |
1333 | [(set (match_operand:DI 0 "nonimmediate_operand" "") | |
1334 | (match_operand:DI 1 "general_operand" ""))] | |
1335 | "!TARGET_64BIT && reload_completed | |
66795431 | 1336 | && s390_split_ok_p (operands[0], operands[1], DImode, 0)" |
8b4a4127 | 1337 | [(set (match_dup 2) (match_dup 4)) |
1338 | (set (match_dup 3) (match_dup 5))] | |
4673c1a0 | 1339 | { |
66795431 | 1340 | operands[2] = operand_subword (operands[0], 0, 0, DImode); |
1341 | operands[3] = operand_subword (operands[0], 1, 0, DImode); | |
1342 | operands[4] = operand_subword (operands[1], 0, 0, DImode); | |
1343 | operands[5] = operand_subword (operands[1], 1, 0, DImode); | |
1344 | }) | |
1345 | ||
1346 | (define_split | |
1347 | [(set (match_operand:DI 0 "nonimmediate_operand" "") | |
1348 | (match_operand:DI 1 "general_operand" ""))] | |
1349 | "!TARGET_64BIT && reload_completed | |
1350 | && s390_split_ok_p (operands[0], operands[1], DImode, 1)" | |
1351 | [(set (match_dup 2) (match_dup 4)) | |
1352 | (set (match_dup 3) (match_dup 5))] | |
1353 | { | |
1354 | operands[2] = operand_subword (operands[0], 1, 0, DImode); | |
1355 | operands[3] = operand_subword (operands[0], 0, 0, DImode); | |
1356 | operands[4] = operand_subword (operands[1], 1, 0, DImode); | |
1357 | operands[5] = operand_subword (operands[1], 0, 0, DImode); | |
1358 | }) | |
4673c1a0 | 1359 | |
8b4a4127 | 1360 | (define_split |
1361 | [(set (match_operand:DI 0 "register_operand" "") | |
1362 | (match_operand:DI 1 "memory_operand" ""))] | |
1363 | "!TARGET_64BIT && reload_completed | |
25da9e9f | 1364 | && !FP_REG_P (operands[0]) |
8b4a4127 | 1365 | && !s_operand (operands[1], VOIDmode)" |
4fbc4db5 | 1366 | [(set (match_dup 0) (match_dup 1))] |
4fbc4db5 | 1367 | { |
1368 | rtx addr = operand_subword (operands[0], 1, 0, DImode); | |
1369 | s390_load_address (addr, XEXP (operands[1], 0)); | |
1370 | operands[1] = replace_equiv_address (operands[1], addr); | |
66795431 | 1371 | }) |
1372 | ||
fb829af4 | 1373 | (define_peephole2 |
1374 | [(set (match_operand:DI 0 "register_operand" "") | |
1375 | (mem:DI (match_operand 1 "address_operand" "")))] | |
1376 | "TARGET_64BIT | |
1377 | && !FP_REG_P (operands[0]) | |
1378 | && GET_CODE (operands[1]) == SYMBOL_REF | |
1379 | && CONSTANT_POOL_ADDRESS_P (operands[1]) | |
1380 | && get_pool_mode (operands[1]) == DImode | |
1381 | && legitimate_reload_constant_p (get_pool_constant (operands[1]))" | |
1382 | [(set (match_dup 0) (match_dup 2))] | |
1383 | "operands[2] = get_pool_constant (operands[1]);") | |
1384 | ||
93474865 | 1385 | (define_insn "*la_64" |
1386 | [(set (match_operand:DI 0 "register_operand" "=d,d") | |
1387 | (match_operand:QI 1 "address_operand" "U,W"))] | |
1388 | "TARGET_64BIT" | |
1389 | "@ | |
1390 | la\t%0,%a1 | |
1391 | lay\t%0,%a1" | |
1392 | [(set_attr "op_type" "RX,RXY") | |
1393 | (set_attr "type" "la")]) | |
1394 | ||
1395 | (define_peephole2 | |
1396 | [(parallel | |
1397 | [(set (match_operand:DI 0 "register_operand" "") | |
1398 | (match_operand:QI 1 "address_operand" "")) | |
1ca361fd | 1399 | (clobber (reg:CC CC_REGNUM))])] |
93474865 | 1400 | "TARGET_64BIT |
c6061690 | 1401 | && preferred_la_operand_p (operands[1], const0_rtx)" |
93474865 | 1402 | [(set (match_dup 0) (match_dup 1))] |
1403 | "") | |
1404 | ||
1405 | (define_peephole2 | |
1406 | [(set (match_operand:DI 0 "register_operand" "") | |
1407 | (match_operand:DI 1 "register_operand" "")) | |
1408 | (parallel | |
1409 | [(set (match_dup 0) | |
1410 | (plus:DI (match_dup 0) | |
1411 | (match_operand:DI 2 "nonmemory_operand" ""))) | |
1ca361fd | 1412 | (clobber (reg:CC CC_REGNUM))])] |
93474865 | 1413 | "TARGET_64BIT |
1414 | && !reg_overlap_mentioned_p (operands[0], operands[2]) | |
c6061690 | 1415 | && preferred_la_operand_p (operands[1], operands[2])" |
93474865 | 1416 | [(set (match_dup 0) (plus:DI (match_dup 1) (match_dup 2)))] |
1417 | "") | |
1418 | ||
4673c1a0 | 1419 | ; |
1420 | ; movsi instruction pattern(s). | |
1421 | ; | |
1422 | ||
4673c1a0 | 1423 | (define_expand "movsi" |
1424 | [(set (match_operand:SI 0 "general_operand" "") | |
1425 | (match_operand:SI 1 "general_operand" ""))] | |
1426 | "" | |
4673c1a0 | 1427 | { |
be00aaa8 | 1428 | /* Handle symbolic constants. */ |
abbcecd2 | 1429 | if (!TARGET_64BIT |
1430 | && (SYMBOLIC_CONST (operands[1]) | |
1431 | || (GET_CODE (operands[1]) == PLUS | |
1432 | && XEXP (operands[1], 0) == pic_offset_table_rtx | |
1433 | && SYMBOLIC_CONST (XEXP(operands[1], 1))))) | |
be00aaa8 | 1434 | emit_symbolic_move (operands); |
83e641bd | 1435 | }) |
4673c1a0 | 1436 | |
dafc8d45 | 1437 | (define_insn "*movsi_larl" |
1438 | [(set (match_operand:SI 0 "register_operand" "=d") | |
1439 | (match_operand:SI 1 "larl_operand" "X"))] | |
1440 | "!TARGET_64BIT && TARGET_CPU_ZARCH | |
1441 | && !FP_REG_P (operands[0])" | |
1442 | "larl\t%0,%1" | |
1443 | [(set_attr "op_type" "RIL") | |
1444 | (set_attr "type" "larl")]) | |
1445 | ||
64a1078f | 1446 | (define_insn "*movsi_zarch" |
346fecd5 | 1447 | [(set (match_operand:SI 0 "nonimmediate_operand" |
e68d6a13 | 1448 | "=d,d,d,d,d,d,d,d,d,R,T,!*f,!*f,!*f,!R,!T,d,t,Q,b,Q,t,?Q") |
346fecd5 | 1449 | (match_operand:SI 1 "general_operand" |
e68d6a13 | 1450 | "K,N0HS0,N1HS0,Os,L,b,d,R,T,d,d,*f,R,T,*f,*f,t,d,t,d,K,Q,?Q"))] |
64a1078f | 1451 | "TARGET_ZARCH" |
4673c1a0 | 1452 | "@ |
64a1078f | 1453 | lhi\t%0,%h1 |
1454 | llilh\t%0,%i1 | |
1455 | llill\t%0,%i1 | |
163277cf | 1456 | iilf\t%0,%o1 |
64a1078f | 1457 | lay\t%0,%a1 |
e68d6a13 | 1458 | lrl\t%0,%1 |
f24d7ff3 | 1459 | lr\t%0,%1 |
1460 | l\t%0,%1 | |
1461 | ly\t%0,%1 | |
1462 | st\t%1,%0 | |
1463 | sty\t%1,%0 | |
1464 | ler\t%0,%1 | |
1465 | le\t%0,%1 | |
1466 | ley\t%0,%1 | |
1467 | ste\t%1,%0 | |
1468 | stey\t%1,%0 | |
923cf36d | 1469 | ear\t%0,%1 |
1470 | sar\t%0,%1 | |
1471 | stam\t%1,%1,%S0 | |
e68d6a13 | 1472 | strl\t%1,%0 |
1473 | mvhi\t%0,%1 | |
923cf36d | 1474 | lam\t%0,%0,%S1 |
9dffd3ff | 1475 | #" |
e68d6a13 | 1476 | [(set_attr "op_type" "RI,RI,RI,RIL,RXY,RIL,RR,RX,RXY,RX,RXY, |
1477 | RR,RX,RXY,RX,RXY,RRE,RRE,RS,RIL,SIL,RS,SS") | |
1478 | (set_attr "type" "*,*,*,*,la,larl,lr,load,load,store,store, | |
1479 | floadsf,floadsf,floadsf,fstoresf,fstoresf,*,*,*,larl,*,*,*") | |
1480 | (set_attr "cpu_facility" "*,*,*,extimm,longdisp,z10,*,*,longdisp,*,longdisp, | |
1481 | *,*,longdisp,*,longdisp,*,*,*,z10,z10,*,*")]) | |
64a1078f | 1482 | |
1483 | (define_insn "*movsi_esa" | |
923cf36d | 1484 | [(set (match_operand:SI 0 "nonimmediate_operand" "=d,d,d,R,!*f,!*f,!R,d,t,Q,t,?Q") |
1485 | (match_operand:SI 1 "general_operand" "K,d,R,d,*f,R,*f,t,d,t,Q,?Q"))] | |
64a1078f | 1486 | "!TARGET_ZARCH" |
1487 | "@ | |
1488 | lhi\t%0,%h1 | |
1489 | lr\t%0,%1 | |
1490 | l\t%0,%1 | |
1491 | st\t%1,%0 | |
1492 | ler\t%0,%1 | |
1493 | le\t%0,%1 | |
1494 | ste\t%1,%0 | |
923cf36d | 1495 | ear\t%0,%1 |
1496 | sar\t%0,%1 | |
1497 | stam\t%1,%1,%S0 | |
1498 | lam\t%0,%0,%S1 | |
9dffd3ff | 1499 | #" |
923cf36d | 1500 | [(set_attr "op_type" "RI,RR,RX,RX,RR,RX,RX,RRE,RRE,RS,RS,SS") |
11f88fec | 1501 | (set_attr "type" "*,lr,load,store,floadsf,floadsf,fstoresf,*,*,*,*,*")]) |
4673c1a0 | 1502 | |
fb829af4 | 1503 | (define_peephole2 |
1504 | [(set (match_operand:SI 0 "register_operand" "") | |
1505 | (mem:SI (match_operand 1 "address_operand" "")))] | |
1506 | "!FP_REG_P (operands[0]) | |
1507 | && GET_CODE (operands[1]) == SYMBOL_REF | |
1508 | && CONSTANT_POOL_ADDRESS_P (operands[1]) | |
1509 | && get_pool_mode (operands[1]) == SImode | |
1510 | && legitimate_reload_constant_p (get_pool_constant (operands[1]))" | |
1511 | [(set (match_dup 0) (match_dup 2))] | |
1512 | "operands[2] = get_pool_constant (operands[1]);") | |
4673c1a0 | 1513 | |
93474865 | 1514 | (define_insn "*la_31" |
1515 | [(set (match_operand:SI 0 "register_operand" "=d,d") | |
1516 | (match_operand:QI 1 "address_operand" "U,W"))] | |
1517 | "!TARGET_64BIT && legitimate_la_operand_p (operands[1])" | |
1518 | "@ | |
1519 | la\t%0,%a1 | |
1520 | lay\t%0,%a1" | |
1521 | [(set_attr "op_type" "RX,RXY") | |
1522 | (set_attr "type" "la")]) | |
1523 | ||
1524 | (define_peephole2 | |
1525 | [(parallel | |
1526 | [(set (match_operand:SI 0 "register_operand" "") | |
1527 | (match_operand:QI 1 "address_operand" "")) | |
1ca361fd | 1528 | (clobber (reg:CC CC_REGNUM))])] |
93474865 | 1529 | "!TARGET_64BIT |
c6061690 | 1530 | && preferred_la_operand_p (operands[1], const0_rtx)" |
93474865 | 1531 | [(set (match_dup 0) (match_dup 1))] |
1532 | "") | |
1533 | ||
1534 | (define_peephole2 | |
1535 | [(set (match_operand:SI 0 "register_operand" "") | |
1536 | (match_operand:SI 1 "register_operand" "")) | |
1537 | (parallel | |
1538 | [(set (match_dup 0) | |
1539 | (plus:SI (match_dup 0) | |
1540 | (match_operand:SI 2 "nonmemory_operand" ""))) | |
1ca361fd | 1541 | (clobber (reg:CC CC_REGNUM))])] |
93474865 | 1542 | "!TARGET_64BIT |
1543 | && !reg_overlap_mentioned_p (operands[0], operands[2]) | |
c6061690 | 1544 | && preferred_la_operand_p (operands[1], operands[2])" |
93474865 | 1545 | [(set (match_dup 0) (plus:SI (match_dup 1) (match_dup 2)))] |
1546 | "") | |
1547 | ||
1548 | (define_insn "*la_31_and" | |
1549 | [(set (match_operand:SI 0 "register_operand" "=d,d") | |
1550 | (and:SI (match_operand:QI 1 "address_operand" "U,W") | |
1551 | (const_int 2147483647)))] | |
1552 | "!TARGET_64BIT" | |
1553 | "@ | |
1554 | la\t%0,%a1 | |
1555 | lay\t%0,%a1" | |
1556 | [(set_attr "op_type" "RX,RXY") | |
1557 | (set_attr "type" "la")]) | |
1558 | ||
1559 | (define_insn_and_split "*la_31_and_cc" | |
1560 | [(set (match_operand:SI 0 "register_operand" "=d") | |
1561 | (and:SI (match_operand:QI 1 "address_operand" "p") | |
1562 | (const_int 2147483647))) | |
1ca361fd | 1563 | (clobber (reg:CC CC_REGNUM))] |
93474865 | 1564 | "!TARGET_64BIT" |
1565 | "#" | |
1566 | "&& reload_completed" | |
1567 | [(set (match_dup 0) | |
1568 | (and:SI (match_dup 1) (const_int 2147483647)))] | |
1569 | "" | |
1570 | [(set_attr "op_type" "RX") | |
1571 | (set_attr "type" "la")]) | |
1572 | ||
1573 | (define_insn "force_la_31" | |
1574 | [(set (match_operand:SI 0 "register_operand" "=d,d") | |
1575 | (match_operand:QI 1 "address_operand" "U,W")) | |
1576 | (use (const_int 0))] | |
1577 | "!TARGET_64BIT" | |
1578 | "@ | |
1579 | la\t%0,%a1 | |
1580 | lay\t%0,%a1" | |
1581 | [(set_attr "op_type" "RX") | |
1582 | (set_attr "type" "la")]) | |
1583 | ||
4673c1a0 | 1584 | ; |
1585 | ; movhi instruction pattern(s). | |
1586 | ; | |
1587 | ||
77a651b8 | 1588 | (define_expand "movhi" |
1589 | [(set (match_operand:HI 0 "nonimmediate_operand" "") | |
1590 | (match_operand:HI 1 "general_operand" ""))] | |
1591 | "" | |
1592 | { | |
346fecd5 | 1593 | /* Make it explicit that loading a register from memory |
77a651b8 | 1594 | always sign-extends (at least) to SImode. */ |
e1ba4a27 | 1595 | if (optimize && can_create_pseudo_p () |
77a651b8 | 1596 | && register_operand (operands[0], VOIDmode) |
e8825bb0 | 1597 | && GET_CODE (operands[1]) == MEM) |
77a651b8 | 1598 | { |
1599 | rtx tmp = gen_reg_rtx (SImode); | |
1600 | rtx ext = gen_rtx_SIGN_EXTEND (SImode, operands[1]); | |
1601 | emit_insn (gen_rtx_SET (VOIDmode, tmp, ext)); | |
1602 | operands[1] = gen_lowpart (HImode, tmp); | |
1603 | } | |
1604 | }) | |
1605 | ||
1606 | (define_insn "*movhi" | |
e68d6a13 | 1607 | [(set (match_operand:HI 0 "nonimmediate_operand" "=d,d,d,d,d,R,T,b,Q,?Q") |
1608 | (match_operand:HI 1 "general_operand" " d,n,R,T,b,d,d,d,K,?Q"))] | |
4673c1a0 | 1609 | "" |
1610 | "@ | |
f24d7ff3 | 1611 | lr\t%0,%1 |
1612 | lhi\t%0,%h1 | |
1613 | lh\t%0,%1 | |
1614 | lhy\t%0,%1 | |
e68d6a13 | 1615 | lhrl\t%0,%1 |
f24d7ff3 | 1616 | sth\t%1,%0 |
1617 | sthy\t%1,%0 | |
e68d6a13 | 1618 | sthrl\t%1,%0 |
1619 | mvhhi\t%0,%1 | |
9dffd3ff | 1620 | #" |
e68d6a13 | 1621 | [(set_attr "op_type" "RR,RI,RX,RXY,RIL,RX,RXY,RIL,SIL,SS") |
1622 | (set_attr "type" "lr,*,*,*,larl,store,store,store,*,*") | |
1623 | (set_attr "cpu_facility" "*,*,*,*,z10,*,*,z10,z10,*")]) | |
4673c1a0 | 1624 | |
fb829af4 | 1625 | (define_peephole2 |
1626 | [(set (match_operand:HI 0 "register_operand" "") | |
1627 | (mem:HI (match_operand 1 "address_operand" "")))] | |
1628 | "GET_CODE (operands[1]) == SYMBOL_REF | |
1629 | && CONSTANT_POOL_ADDRESS_P (operands[1]) | |
1630 | && get_pool_mode (operands[1]) == HImode | |
1631 | && GET_CODE (get_pool_constant (operands[1])) == CONST_INT" | |
1632 | [(set (match_dup 0) (match_dup 2))] | |
1633 | "operands[2] = get_pool_constant (operands[1]);") | |
8b4a4127 | 1634 | |
4673c1a0 | 1635 | ; |
1636 | ; movqi instruction pattern(s). | |
1637 | ; | |
1638 | ||
77a651b8 | 1639 | (define_expand "movqi" |
1640 | [(set (match_operand:QI 0 "nonimmediate_operand" "") | |
1641 | (match_operand:QI 1 "general_operand" ""))] | |
1642 | "" | |
1643 | { | |
9eabd191 | 1644 | /* On z/Architecture, zero-extending from memory to register |
77a651b8 | 1645 | is just as fast as a QImode load. */ |
e1ba4a27 | 1646 | if (TARGET_ZARCH && optimize && can_create_pseudo_p () |
77a651b8 | 1647 | && register_operand (operands[0], VOIDmode) |
e8825bb0 | 1648 | && GET_CODE (operands[1]) == MEM) |
77a651b8 | 1649 | { |
9eabd191 | 1650 | rtx tmp = gen_reg_rtx (word_mode); |
1651 | rtx ext = gen_rtx_ZERO_EXTEND (word_mode, operands[1]); | |
77a651b8 | 1652 | emit_insn (gen_rtx_SET (VOIDmode, tmp, ext)); |
1653 | operands[1] = gen_lowpart (QImode, tmp); | |
1654 | } | |
1655 | }) | |
8b4a4127 | 1656 | |
77a651b8 | 1657 | (define_insn "*movqi" |
51aa1e9c | 1658 | [(set (match_operand:QI 0 "nonimmediate_operand" "=d,d,d,d,R,T,Q,S,?Q") |
1659 | (match_operand:QI 1 "general_operand" "d,n,R,T,d,d,n,n,?Q"))] | |
4673c1a0 | 1660 | "" |
1661 | "@ | |
f24d7ff3 | 1662 | lr\t%0,%1 |
1663 | lhi\t%0,%b1 | |
1664 | ic\t%0,%1 | |
1665 | icy\t%0,%1 | |
1666 | stc\t%1,%0 | |
1667 | stcy\t%1,%0 | |
0574acbe | 1668 | mvi\t%S0,%b1 |
1669 | mviy\t%S0,%b1 | |
9dffd3ff | 1670 | #" |
51aa1e9c | 1671 | [(set_attr "op_type" "RR,RI,RX,RXY,RX,RXY,SI,SIY,SS") |
1822f0d6 | 1672 | (set_attr "type" "lr,*,*,*,store,store,store,store,*")]) |
4673c1a0 | 1673 | |
fb829af4 | 1674 | (define_peephole2 |
1675 | [(set (match_operand:QI 0 "nonimmediate_operand" "") | |
1676 | (mem:QI (match_operand 1 "address_operand" "")))] | |
1677 | "GET_CODE (operands[1]) == SYMBOL_REF | |
1678 | && CONSTANT_POOL_ADDRESS_P (operands[1]) | |
1679 | && get_pool_mode (operands[1]) == QImode | |
1680 | && GET_CODE (get_pool_constant (operands[1])) == CONST_INT" | |
1681 | [(set (match_dup 0) (match_dup 2))] | |
1682 | "operands[2] = get_pool_constant (operands[1]);") | |
8b4a4127 | 1683 | |
4673c1a0 | 1684 | ; |
2e5d1042 | 1685 | ; movstrictqi instruction pattern(s). |
4673c1a0 | 1686 | ; |
1687 | ||
1688 | (define_insn "*movstrictqi" | |
51aa1e9c | 1689 | [(set (strict_low_part (match_operand:QI 0 "register_operand" "+d,d")) |
1690 | (match_operand:QI 1 "memory_operand" "R,T"))] | |
4673c1a0 | 1691 | "" |
51aa1e9c | 1692 | "@ |
f24d7ff3 | 1693 | ic\t%0,%1 |
1694 | icy\t%0,%1" | |
51aa1e9c | 1695 | [(set_attr "op_type" "RX,RXY")]) |
4673c1a0 | 1696 | |
1697 | ; | |
1698 | ; movstricthi instruction pattern(s). | |
1699 | ; | |
1700 | ||
1701 | (define_insn "*movstricthi" | |
51aa1e9c | 1702 | [(set (strict_low_part (match_operand:HI 0 "register_operand" "+d,d")) |
c029ded7 | 1703 | (match_operand:HI 1 "memory_operand" "Q,S")) |
1ca361fd | 1704 | (clobber (reg:CC CC_REGNUM))] |
4673c1a0 | 1705 | "" |
51aa1e9c | 1706 | "@ |
0574acbe | 1707 | icm\t%0,3,%S1 |
1708 | icmy\t%0,3,%S1" | |
51aa1e9c | 1709 | [(set_attr "op_type" "RS,RSY")]) |
4673c1a0 | 1710 | |
1711 | ; | |
1712 | ; movstrictsi instruction pattern(s). | |
1713 | ; | |
1714 | ||
2e5d1042 | 1715 | (define_insn "movstrictsi" |
923cf36d | 1716 | [(set (strict_low_part (match_operand:SI 0 "register_operand" "+d,d,d,d")) |
1717 | (match_operand:SI 1 "general_operand" "d,R,T,t"))] | |
4673c1a0 | 1718 | "TARGET_64BIT" |
1719 | "@ | |
f24d7ff3 | 1720 | lr\t%0,%1 |
1721 | l\t%0,%1 | |
923cf36d | 1722 | ly\t%0,%1 |
1723 | ear\t%0,%1" | |
1724 | [(set_attr "op_type" "RR,RX,RXY,RRE") | |
1725 | (set_attr "type" "lr,load,load,*")]) | |
4673c1a0 | 1726 | |
429f9fdb | 1727 | ; |
1f8e70bc | 1728 | ; mov(tf|td) instruction pattern(s). |
429f9fdb | 1729 | ; |
1730 | ||
1f8e70bc | 1731 | (define_expand "mov<mode>" |
1732 | [(set (match_operand:TD_TF 0 "nonimmediate_operand" "") | |
1733 | (match_operand:TD_TF 1 "general_operand" ""))] | |
429f9fdb | 1734 | "" |
1735 | "") | |
1736 | ||
1f8e70bc | 1737 | (define_insn "*mov<mode>_64" |
1738 | [(set (match_operand:TD_TF 0 "nonimmediate_operand" "=f,f,f,o, d,QS, d,o,Q") | |
8fe52251 | 1739 | (match_operand:TD_TF 1 "general_operand" " G,f,o,f,QS, d,dRT,d,Q"))] |
429f9fdb | 1740 | "TARGET_64BIT" |
1741 | "@ | |
1742 | lzxr\t%0 | |
1743 | lxr\t%0,%1 | |
1744 | # | |
1745 | # | |
1746 | lmg\t%0,%N0,%S1 | |
1747 | stmg\t%1,%N1,%S0 | |
1748 | # | |
1749 | # | |
1750 | #" | |
1751 | [(set_attr "op_type" "RRE,RRE,*,*,RSY,RSY,*,*,*") | |
1752 | (set_attr "type" "fsimptf,fsimptf,*,*,lm,stm,*,*,*")]) | |
1753 | ||
1f8e70bc | 1754 | (define_insn "*mov<mode>_31" |
1755 | [(set (match_operand:TD_TF 0 "nonimmediate_operand" "=f,f,f,o,Q") | |
1756 | (match_operand:TD_TF 1 "general_operand" " G,f,o,f,Q"))] | |
429f9fdb | 1757 | "!TARGET_64BIT" |
1758 | "@ | |
1759 | lzxr\t%0 | |
1760 | lxr\t%0,%1 | |
1761 | # | |
1762 | # | |
1763 | #" | |
1764 | [(set_attr "op_type" "RRE,RRE,*,*,*") | |
1765 | (set_attr "type" "fsimptf,fsimptf,*,*,*")]) | |
1766 | ||
1767 | ; TFmode in GPRs splitters | |
1768 | ||
1769 | (define_split | |
1f8e70bc | 1770 | [(set (match_operand:TD_TF 0 "nonimmediate_operand" "") |
1771 | (match_operand:TD_TF 1 "general_operand" ""))] | |
429f9fdb | 1772 | "TARGET_64BIT && reload_completed |
1f8e70bc | 1773 | && s390_split_ok_p (operands[0], operands[1], <MODE>mode, 0)" |
429f9fdb | 1774 | [(set (match_dup 2) (match_dup 4)) |
1775 | (set (match_dup 3) (match_dup 5))] | |
1776 | { | |
1f8e70bc | 1777 | operands[2] = operand_subword (operands[0], 0, 0, <MODE>mode); |
1778 | operands[3] = operand_subword (operands[0], 1, 0, <MODE>mode); | |
1779 | operands[4] = operand_subword (operands[1], 0, 0, <MODE>mode); | |
1780 | operands[5] = operand_subword (operands[1], 1, 0, <MODE>mode); | |
429f9fdb | 1781 | }) |
1782 | ||
1783 | (define_split | |
1f8e70bc | 1784 | [(set (match_operand:TD_TF 0 "nonimmediate_operand" "") |
1785 | (match_operand:TD_TF 1 "general_operand" ""))] | |
429f9fdb | 1786 | "TARGET_64BIT && reload_completed |
1f8e70bc | 1787 | && s390_split_ok_p (operands[0], operands[1], <MODE>mode, 1)" |
429f9fdb | 1788 | [(set (match_dup 2) (match_dup 4)) |
1789 | (set (match_dup 3) (match_dup 5))] | |
1790 | { | |
1f8e70bc | 1791 | operands[2] = operand_subword (operands[0], 1, 0, <MODE>mode); |
1792 | operands[3] = operand_subword (operands[0], 0, 0, <MODE>mode); | |
1793 | operands[4] = operand_subword (operands[1], 1, 0, <MODE>mode); | |
1794 | operands[5] = operand_subword (operands[1], 0, 0, <MODE>mode); | |
429f9fdb | 1795 | }) |
1796 | ||
1797 | (define_split | |
1f8e70bc | 1798 | [(set (match_operand:TD_TF 0 "register_operand" "") |
1799 | (match_operand:TD_TF 1 "memory_operand" ""))] | |
429f9fdb | 1800 | "TARGET_64BIT && reload_completed |
1801 | && !FP_REG_P (operands[0]) | |
1802 | && !s_operand (operands[1], VOIDmode)" | |
1803 | [(set (match_dup 0) (match_dup 1))] | |
1804 | { | |
1f8e70bc | 1805 | rtx addr = operand_subword (operands[0], 1, 0, <MODE>mode); |
429f9fdb | 1806 | s390_load_address (addr, XEXP (operands[1], 0)); |
1807 | operands[1] = replace_equiv_address (operands[1], addr); | |
1808 | }) | |
1809 | ||
708607d5 | 1810 | ; TFmode in BFPs splitters |
429f9fdb | 1811 | |
1812 | (define_split | |
1f8e70bc | 1813 | [(set (match_operand:TD_TF 0 "register_operand" "") |
1814 | (match_operand:TD_TF 1 "memory_operand" ""))] | |
429f9fdb | 1815 | "reload_completed && offsettable_memref_p (operands[1]) |
1816 | && FP_REG_P (operands[0])" | |
1817 | [(set (match_dup 2) (match_dup 4)) | |
1818 | (set (match_dup 3) (match_dup 5))] | |
1819 | { | |
1f8e70bc | 1820 | operands[2] = simplify_gen_subreg (<HALF_TMODE>mode, operands[0], |
1821 | <MODE>mode, 0); | |
1822 | operands[3] = simplify_gen_subreg (<HALF_TMODE>mode, operands[0], | |
1823 | <MODE>mode, 8); | |
1824 | operands[4] = adjust_address_nv (operands[1], <HALF_TMODE>mode, 0); | |
1825 | operands[5] = adjust_address_nv (operands[1], <HALF_TMODE>mode, 8); | |
429f9fdb | 1826 | }) |
1827 | ||
1828 | (define_split | |
1f8e70bc | 1829 | [(set (match_operand:TD_TF 0 "memory_operand" "") |
1830 | (match_operand:TD_TF 1 "register_operand" ""))] | |
429f9fdb | 1831 | "reload_completed && offsettable_memref_p (operands[0]) |
1832 | && FP_REG_P (operands[1])" | |
1833 | [(set (match_dup 2) (match_dup 4)) | |
1834 | (set (match_dup 3) (match_dup 5))] | |
1835 | { | |
1f8e70bc | 1836 | operands[2] = adjust_address_nv (operands[0], <HALF_TMODE>mode, 0); |
1837 | operands[3] = adjust_address_nv (operands[0], <HALF_TMODE>mode, 8); | |
1838 | operands[4] = simplify_gen_subreg (<HALF_TMODE>mode, operands[1], | |
1839 | <MODE>mode, 0); | |
1840 | operands[5] = simplify_gen_subreg (<HALF_TMODE>mode, operands[1], | |
1841 | <MODE>mode, 8); | |
429f9fdb | 1842 | }) |
1843 | ||
4673c1a0 | 1844 | ; |
1f8e70bc | 1845 | ; mov(df|dd) instruction pattern(s). |
4673c1a0 | 1846 | ; |
1847 | ||
1f8e70bc | 1848 | (define_expand "mov<mode>" |
1849 | [(set (match_operand:DD_DF 0 "nonimmediate_operand" "") | |
1850 | (match_operand:DD_DF 1 "general_operand" ""))] | |
4673c1a0 | 1851 | "" |
772b9a4f | 1852 | "") |
4673c1a0 | 1853 | |
1f8e70bc | 1854 | (define_insn "*mov<mode>_64dfp" |
1855 | [(set (match_operand:DD_DF 0 "nonimmediate_operand" | |
8fe52251 | 1856 | "=f,f,f,d,f,f,R,T,d,d,RT,?Q") |
1f8e70bc | 1857 | (match_operand:DD_DF 1 "general_operand" |
8fe52251 | 1858 | "G,f,d,f,R,T,f,f,d,RT,d,?Q"))] |
0c2edaa7 | 1859 | "TARGET_64BIT && TARGET_DFP" |
1860 | "@ | |
1861 | lzdr\t%0 | |
1862 | ldr\t%0,%1 | |
1863 | ldgr\t%0,%1 | |
1864 | lgdr\t%0,%1 | |
1865 | ld\t%0,%1 | |
1866 | ldy\t%0,%1 | |
1867 | std\t%1,%0 | |
1868 | stdy\t%1,%0 | |
1869 | lgr\t%0,%1 | |
1870 | lg\t%0,%1 | |
1871 | stg\t%1,%0 | |
1872 | #" | |
1873 | [(set_attr "op_type" "RRE,RR,RRE,RRE,RX,RXY,RX,RXY,RRE,RXY,RXY,SS") | |
1874 | (set_attr "type" "fsimpdf,floaddf,floaddf,floaddf,floaddf,floaddf, | |
1875 | fstoredf,fstoredf,lr,load,store,*")]) | |
1876 | ||
1f8e70bc | 1877 | (define_insn "*mov<mode>_64" |
8fe52251 | 1878 | [(set (match_operand:DD_DF 0 "nonimmediate_operand" "=f,f,f,f,R,T,d, d,RT,?Q") |
1879 | (match_operand:DD_DF 1 "general_operand" "G,f,R,T,f,f,d,RT, d,?Q"))] | |
8b4a4127 | 1880 | "TARGET_64BIT" |
4673c1a0 | 1881 | "@ |
e863b008 | 1882 | lzdr\t%0 |
f24d7ff3 | 1883 | ldr\t%0,%1 |
1884 | ld\t%0,%1 | |
1885 | ldy\t%0,%1 | |
1886 | std\t%1,%0 | |
1887 | stdy\t%1,%0 | |
1888 | lgr\t%0,%1 | |
1889 | lg\t%0,%1 | |
1890 | stg\t%1,%0 | |
9dffd3ff | 1891 | #" |
e863b008 | 1892 | [(set_attr "op_type" "RRE,RR,RX,RXY,RX,RXY,RRE,RXY,RXY,SS") |
1f8e70bc | 1893 | (set_attr "type" "fsimp<bfp>,fload<bfp>,fload<bfp>,fload<bfp>, |
1894 | fstore<bfp>,fstore<bfp>,lr,load,store,*")]) | |
1895 | ||
1896 | (define_insn "*mov<mode>_31" | |
1897 | [(set (match_operand:DD_DF 0 "nonimmediate_operand" | |
8fe52251 | 1898 | "=f,f,f,f,R,T,d,d,Q,S, d,o,Q") |
1f8e70bc | 1899 | (match_operand:DD_DF 1 "general_operand" |
8fe52251 | 1900 | " G,f,R,T,f,f,Q,S,d,d,dPRT,d,Q"))] |
8b4a4127 | 1901 | "!TARGET_64BIT" |
4673c1a0 | 1902 | "@ |
e863b008 | 1903 | lzdr\t%0 |
f24d7ff3 | 1904 | ldr\t%0,%1 |
1905 | ld\t%0,%1 | |
1906 | ldy\t%0,%1 | |
1907 | std\t%1,%0 | |
1908 | stdy\t%1,%0 | |
0574acbe | 1909 | lm\t%0,%N0,%S1 |
0451e449 | 1910 | lmy\t%0,%N0,%S1 |
0574acbe | 1911 | stm\t%1,%N1,%S0 |
0451e449 | 1912 | stmy\t%1,%N1,%S0 |
8b4a4127 | 1913 | # |
957d1b91 | 1914 | # |
9dffd3ff | 1915 | #" |
0451e449 | 1916 | [(set_attr "op_type" "RRE,RR,RX,RXY,RX,RXY,RS,RSY,RS,RSY,*,*,SS") |
1f8e70bc | 1917 | (set_attr "type" "fsimp<bfp>,fload<bfp>,fload<bfp>,fload<bfp>, |
1918 | fstore<bfp>,fstore<bfp>,lm,lm,stm,stm,*,*,*")]) | |
8b4a4127 | 1919 | |
1920 | (define_split | |
1f8e70bc | 1921 | [(set (match_operand:DD_DF 0 "nonimmediate_operand" "") |
1922 | (match_operand:DD_DF 1 "general_operand" ""))] | |
8b4a4127 | 1923 | "!TARGET_64BIT && reload_completed |
1f8e70bc | 1924 | && s390_split_ok_p (operands[0], operands[1], <MODE>mode, 0)" |
8b4a4127 | 1925 | [(set (match_dup 2) (match_dup 4)) |
1926 | (set (match_dup 3) (match_dup 5))] | |
4673c1a0 | 1927 | { |
1f8e70bc | 1928 | operands[2] = operand_subword (operands[0], 0, 0, <MODE>mode); |
1929 | operands[3] = operand_subword (operands[0], 1, 0, <MODE>mode); | |
1930 | operands[4] = operand_subword (operands[1], 0, 0, <MODE>mode); | |
1931 | operands[5] = operand_subword (operands[1], 1, 0, <MODE>mode); | |
66795431 | 1932 | }) |
1933 | ||
1934 | (define_split | |
1f8e70bc | 1935 | [(set (match_operand:DD_DF 0 "nonimmediate_operand" "") |
1936 | (match_operand:DD_DF 1 "general_operand" ""))] | |
66795431 | 1937 | "!TARGET_64BIT && reload_completed |
1f8e70bc | 1938 | && s390_split_ok_p (operands[0], operands[1], <MODE>mode, 1)" |
66795431 | 1939 | [(set (match_dup 2) (match_dup 4)) |
1940 | (set (match_dup 3) (match_dup 5))] | |
1941 | { | |
1f8e70bc | 1942 | operands[2] = operand_subword (operands[0], 1, 0, <MODE>mode); |
1943 | operands[3] = operand_subword (operands[0], 0, 0, <MODE>mode); | |
1944 | operands[4] = operand_subword (operands[1], 1, 0, <MODE>mode); | |
1945 | operands[5] = operand_subword (operands[1], 0, 0, <MODE>mode); | |
66795431 | 1946 | }) |
4673c1a0 | 1947 | |
8b4a4127 | 1948 | (define_split |
1f8e70bc | 1949 | [(set (match_operand:DD_DF 0 "register_operand" "") |
1950 | (match_operand:DD_DF 1 "memory_operand" ""))] | |
8b4a4127 | 1951 | "!TARGET_64BIT && reload_completed |
25da9e9f | 1952 | && !FP_REG_P (operands[0]) |
8b4a4127 | 1953 | && !s_operand (operands[1], VOIDmode)" |
4fbc4db5 | 1954 | [(set (match_dup 0) (match_dup 1))] |
4fbc4db5 | 1955 | { |
1f8e70bc | 1956 | rtx addr = operand_subword (operands[0], 1, 0, <MODE>mode); |
4fbc4db5 | 1957 | s390_load_address (addr, XEXP (operands[1], 0)); |
1958 | operands[1] = replace_equiv_address (operands[1], addr); | |
66795431 | 1959 | }) |
1960 | ||
4673c1a0 | 1961 | ; |
1f8e70bc | 1962 | ; mov(sf|sd) instruction pattern(s). |
4673c1a0 | 1963 | ; |
1964 | ||
1f8e70bc | 1965 | (define_insn "mov<mode>" |
1966 | [(set (match_operand:SD_SF 0 "nonimmediate_operand" | |
1967 | "=f,f,f,f,R,T,d,d,d,R,T,?Q") | |
1968 | (match_operand:SD_SF 1 "general_operand" | |
1969 | " G,f,R,T,f,f,d,R,T,d,d,?Q"))] | |
8b4a4127 | 1970 | "" |
4673c1a0 | 1971 | "@ |
e863b008 | 1972 | lzer\t%0 |
f24d7ff3 | 1973 | ler\t%0,%1 |
1974 | le\t%0,%1 | |
1975 | ley\t%0,%1 | |
1976 | ste\t%1,%0 | |
1977 | stey\t%1,%0 | |
1978 | lr\t%0,%1 | |
1979 | l\t%0,%1 | |
1980 | ly\t%0,%1 | |
1981 | st\t%1,%0 | |
1982 | sty\t%1,%0 | |
9dffd3ff | 1983 | #" |
e863b008 | 1984 | [(set_attr "op_type" "RRE,RR,RX,RXY,RX,RXY,RR,RX,RXY,RX,RXY,SS") |
1f8e70bc | 1985 | (set_attr "type" "fsimp<bfp>,fload<bfp>,fload<bfp>,fload<bfp>, |
1986 | fstore<bfp>,fstore<bfp>,lr,load,load,store,store,*")]) | |
8b4a4127 | 1987 | |
bcbf02a5 | 1988 | ; |
1989 | ; movcc instruction pattern | |
1990 | ; | |
1991 | ||
1992 | (define_insn "movcc" | |
1993 | [(set (match_operand:CC 0 "nonimmediate_operand" "=d,c,d,d,d,R,T") | |
1994 | (match_operand:CC 1 "nonimmediate_operand" "d,d,c,R,T,d,d"))] | |
1995 | "" | |
1996 | "@ | |
1997 | lr\t%0,%1 | |
1998 | tmh\t%1,12288 | |
1999 | ipm\t%0 | |
2000 | st\t%0,%1 | |
2001 | sty\t%0,%1 | |
2002 | l\t%1,%0 | |
2003 | ly\t%1,%0" | |
61be9d41 | 2004 | [(set_attr "op_type" "RR,RI,RRE,RX,RXY,RX,RXY") |
2005 | (set_attr "type" "lr,*,*,store,store,load,load")]) | |
bcbf02a5 | 2006 | |
9dffd3ff | 2007 | ; |
2008 | ; Block move (MVC) patterns. | |
2009 | ; | |
2010 | ||
2011 | (define_insn "*mvc" | |
2012 | [(set (match_operand:BLK 0 "memory_operand" "=Q") | |
2013 | (match_operand:BLK 1 "memory_operand" "Q")) | |
2014 | (use (match_operand 2 "const_int_operand" "n"))] | |
2015 | "INTVAL (operands[2]) >= 1 && INTVAL (operands[2]) <= 256" | |
0574acbe | 2016 | "mvc\t%O0(%2,%R0),%S1" |
1822f0d6 | 2017 | [(set_attr "op_type" "SS")]) |
9dffd3ff | 2018 | |
2019 | (define_split | |
2020 | [(set (match_operand 0 "memory_operand" "") | |
2021 | (match_operand 1 "memory_operand" ""))] | |
2022 | "reload_completed | |
2023 | && GET_MODE (operands[0]) == GET_MODE (operands[1]) | |
2024 | && GET_MODE_SIZE (GET_MODE (operands[0])) > 0" | |
2025 | [(parallel | |
2026 | [(set (match_dup 0) (match_dup 1)) | |
2027 | (use (match_dup 2))])] | |
2028 | { | |
2029 | operands[2] = GEN_INT (GET_MODE_SIZE (GET_MODE (operands[0]))); | |
2030 | operands[0] = adjust_address (operands[0], BLKmode, 0); | |
2031 | operands[1] = adjust_address (operands[1], BLKmode, 0); | |
2032 | }) | |
2033 | ||
2034 | (define_peephole2 | |
2035 | [(parallel | |
2036 | [(set (match_operand:BLK 0 "memory_operand" "") | |
2037 | (match_operand:BLK 1 "memory_operand" "")) | |
2038 | (use (match_operand 2 "const_int_operand" ""))]) | |
2039 | (parallel | |
2040 | [(set (match_operand:BLK 3 "memory_operand" "") | |
2041 | (match_operand:BLK 4 "memory_operand" "")) | |
2042 | (use (match_operand 5 "const_int_operand" ""))])] | |
2043 | "s390_offset_p (operands[0], operands[3], operands[2]) | |
2044 | && s390_offset_p (operands[1], operands[4], operands[2]) | |
74bdf297 | 2045 | && !s390_overlap_p (operands[0], operands[1], |
2046 | INTVAL (operands[2]) + INTVAL (operands[5])) | |
9dffd3ff | 2047 | && INTVAL (operands[2]) + INTVAL (operands[5]) <= 256" |
2048 | [(parallel | |
2049 | [(set (match_dup 6) (match_dup 7)) | |
2050 | (use (match_dup 8))])] | |
2051 | "operands[6] = gen_rtx_MEM (BLKmode, XEXP (operands[0], 0)); | |
2052 | operands[7] = gen_rtx_MEM (BLKmode, XEXP (operands[1], 0)); | |
2053 | operands[8] = GEN_INT (INTVAL (operands[2]) + INTVAL (operands[5]));") | |
2054 | ||
2055 | ||
4673c1a0 | 2056 | ; |
2057 | ; load_multiple pattern(s). | |
2058 | ; | |
e764e222 | 2059 | ; ??? Due to reload problems with replacing registers inside match_parallel |
2060 | ; we currently support load_multiple/store_multiple only after reload. | |
2061 | ; | |
4673c1a0 | 2062 | |
2063 | (define_expand "load_multiple" | |
2064 | [(match_par_dup 3 [(set (match_operand 0 "" "") | |
2065 | (match_operand 1 "" "")) | |
2066 | (use (match_operand 2 "" ""))])] | |
e764e222 | 2067 | "reload_completed" |
4673c1a0 | 2068 | { |
9eabd191 | 2069 | enum machine_mode mode; |
4673c1a0 | 2070 | int regno; |
2071 | int count; | |
2072 | rtx from; | |
8b4a4127 | 2073 | int i, off; |
4673c1a0 | 2074 | |
2075 | /* Support only loading a constant number of fixed-point registers from | |
2076 | memory and only bother with this if more than two */ | |
2077 | if (GET_CODE (operands[2]) != CONST_INT | |
8b4a4127 | 2078 | || INTVAL (operands[2]) < 2 |
4673c1a0 | 2079 | || INTVAL (operands[2]) > 16 |
2080 | || GET_CODE (operands[1]) != MEM | |
2081 | || GET_CODE (operands[0]) != REG | |
2082 | || REGNO (operands[0]) >= 16) | |
2083 | FAIL; | |
2084 | ||
2085 | count = INTVAL (operands[2]); | |
2086 | regno = REGNO (operands[0]); | |
9eabd191 | 2087 | mode = GET_MODE (operands[0]); |
2088 | if (mode != SImode && mode != word_mode) | |
2089 | FAIL; | |
4673c1a0 | 2090 | |
2091 | operands[3] = gen_rtx_PARALLEL (VOIDmode, rtvec_alloc (count)); | |
e1ba4a27 | 2092 | if (!can_create_pseudo_p ()) |
8b4a4127 | 2093 | { |
2094 | if (GET_CODE (XEXP (operands[1], 0)) == REG) | |
2095 | { | |
2096 | from = XEXP (operands[1], 0); | |
2097 | off = 0; | |
2098 | } | |
2099 | else if (GET_CODE (XEXP (operands[1], 0)) == PLUS | |
2100 | && GET_CODE (XEXP (XEXP (operands[1], 0), 0)) == REG | |
2101 | && GET_CODE (XEXP (XEXP (operands[1], 0), 1)) == CONST_INT) | |
2102 | { | |
2103 | from = XEXP (XEXP (operands[1], 0), 0); | |
2104 | off = INTVAL (XEXP (XEXP (operands[1], 0), 1)); | |
2105 | } | |
2106 | else | |
2107 | FAIL; | |
8b4a4127 | 2108 | } |
2109 | else | |
2110 | { | |
2111 | from = force_reg (Pmode, XEXP (operands[1], 0)); | |
2112 | off = 0; | |
2113 | } | |
4673c1a0 | 2114 | |
2115 | for (i = 0; i < count; i++) | |
2116 | XVECEXP (operands[3], 0, i) | |
9eabd191 | 2117 | = gen_rtx_SET (VOIDmode, gen_rtx_REG (mode, regno + i), |
2118 | change_address (operands[1], mode, | |
2119 | plus_constant (from, off + i * GET_MODE_SIZE (mode)))); | |
83e641bd | 2120 | }) |
4673c1a0 | 2121 | |
2122 | (define_insn "*load_multiple_di" | |
2123 | [(match_parallel 0 "load_multiple_operation" | |
2124 | [(set (match_operand:DI 1 "register_operand" "=r") | |
51aa1e9c | 2125 | (match_operand:DI 2 "s_operand" "QS"))])] |
e764e222 | 2126 | "reload_completed && word_mode == DImode" |
4673c1a0 | 2127 | { |
2128 | int words = XVECLEN (operands[0], 0); | |
4673c1a0 | 2129 | operands[0] = gen_rtx_REG (DImode, REGNO (operands[1]) + words - 1); |
0574acbe | 2130 | return "lmg\t%1,%0,%S2"; |
83e641bd | 2131 | } |
51aa1e9c | 2132 | [(set_attr "op_type" "RSY") |
8b4a4127 | 2133 | (set_attr "type" "lm")]) |
4673c1a0 | 2134 | |
2135 | (define_insn "*load_multiple_si" | |
2136 | [(match_parallel 0 "load_multiple_operation" | |
51aa1e9c | 2137 | [(set (match_operand:SI 1 "register_operand" "=r,r") |
2138 | (match_operand:SI 2 "s_operand" "Q,S"))])] | |
e764e222 | 2139 | "reload_completed" |
4673c1a0 | 2140 | { |
2141 | int words = XVECLEN (operands[0], 0); | |
4673c1a0 | 2142 | operands[0] = gen_rtx_REG (SImode, REGNO (operands[1]) + words - 1); |
0574acbe | 2143 | return which_alternative == 0 ? "lm\t%1,%0,%S2" : "lmy\t%1,%0,%S2"; |
83e641bd | 2144 | } |
51aa1e9c | 2145 | [(set_attr "op_type" "RS,RSY") |
8b4a4127 | 2146 | (set_attr "type" "lm")]) |
4673c1a0 | 2147 | |
2148 | ; | |
f81e845f | 2149 | ; store multiple pattern(s). |
4673c1a0 | 2150 | ; |
2151 | ||
2152 | (define_expand "store_multiple" | |
2153 | [(match_par_dup 3 [(set (match_operand 0 "" "") | |
2154 | (match_operand 1 "" "")) | |
2155 | (use (match_operand 2 "" ""))])] | |
e764e222 | 2156 | "reload_completed" |
4673c1a0 | 2157 | { |
9eabd191 | 2158 | enum machine_mode mode; |
4673c1a0 | 2159 | int regno; |
2160 | int count; | |
2161 | rtx to; | |
8b4a4127 | 2162 | int i, off; |
4673c1a0 | 2163 | |
2164 | /* Support only storing a constant number of fixed-point registers to | |
2165 | memory and only bother with this if more than two. */ | |
2166 | if (GET_CODE (operands[2]) != CONST_INT | |
8b4a4127 | 2167 | || INTVAL (operands[2]) < 2 |
4673c1a0 | 2168 | || INTVAL (operands[2]) > 16 |
2169 | || GET_CODE (operands[0]) != MEM | |
2170 | || GET_CODE (operands[1]) != REG | |
2171 | || REGNO (operands[1]) >= 16) | |
2172 | FAIL; | |
2173 | ||
2174 | count = INTVAL (operands[2]); | |
2175 | regno = REGNO (operands[1]); | |
9eabd191 | 2176 | mode = GET_MODE (operands[1]); |
2177 | if (mode != SImode && mode != word_mode) | |
2178 | FAIL; | |
4673c1a0 | 2179 | |
2180 | operands[3] = gen_rtx_PARALLEL (VOIDmode, rtvec_alloc (count)); | |
8b4a4127 | 2181 | |
e1ba4a27 | 2182 | if (!can_create_pseudo_p ()) |
8b4a4127 | 2183 | { |
2184 | if (GET_CODE (XEXP (operands[0], 0)) == REG) | |
2185 | { | |
2186 | to = XEXP (operands[0], 0); | |
2187 | off = 0; | |
2188 | } | |
2189 | else if (GET_CODE (XEXP (operands[0], 0)) == PLUS | |
2190 | && GET_CODE (XEXP (XEXP (operands[0], 0), 0)) == REG | |
2191 | && GET_CODE (XEXP (XEXP (operands[0], 0), 1)) == CONST_INT) | |
2192 | { | |
2193 | to = XEXP (XEXP (operands[0], 0), 0); | |
2194 | off = INTVAL (XEXP (XEXP (operands[0], 0), 1)); | |
2195 | } | |
2196 | else | |
2197 | FAIL; | |
8b4a4127 | 2198 | } |
f81e845f | 2199 | else |
8b4a4127 | 2200 | { |
2201 | to = force_reg (Pmode, XEXP (operands[0], 0)); | |
2202 | off = 0; | |
2203 | } | |
4673c1a0 | 2204 | |
2205 | for (i = 0; i < count; i++) | |
2206 | XVECEXP (operands[3], 0, i) | |
2207 | = gen_rtx_SET (VOIDmode, | |
9eabd191 | 2208 | change_address (operands[0], mode, |
2209 | plus_constant (to, off + i * GET_MODE_SIZE (mode))), | |
2210 | gen_rtx_REG (mode, regno + i)); | |
83e641bd | 2211 | }) |
4673c1a0 | 2212 | |
2213 | (define_insn "*store_multiple_di" | |
2214 | [(match_parallel 0 "store_multiple_operation" | |
51aa1e9c | 2215 | [(set (match_operand:DI 1 "s_operand" "=QS") |
4673c1a0 | 2216 | (match_operand:DI 2 "register_operand" "r"))])] |
e764e222 | 2217 | "reload_completed && word_mode == DImode" |
4673c1a0 | 2218 | { |
2219 | int words = XVECLEN (operands[0], 0); | |
4673c1a0 | 2220 | operands[0] = gen_rtx_REG (DImode, REGNO (operands[2]) + words - 1); |
0574acbe | 2221 | return "stmg\t%2,%0,%S1"; |
83e641bd | 2222 | } |
51aa1e9c | 2223 | [(set_attr "op_type" "RSY") |
8b4a4127 | 2224 | (set_attr "type" "stm")]) |
4673c1a0 | 2225 | |
2226 | ||
2227 | (define_insn "*store_multiple_si" | |
2228 | [(match_parallel 0 "store_multiple_operation" | |
51aa1e9c | 2229 | [(set (match_operand:SI 1 "s_operand" "=Q,S") |
2230 | (match_operand:SI 2 "register_operand" "r,r"))])] | |
e764e222 | 2231 | "reload_completed" |
4673c1a0 | 2232 | { |
2233 | int words = XVECLEN (operands[0], 0); | |
4673c1a0 | 2234 | operands[0] = gen_rtx_REG (SImode, REGNO (operands[2]) + words - 1); |
0574acbe | 2235 | return which_alternative == 0 ? "stm\t%2,%0,%S1" : "stmy\t%2,%0,%S1"; |
83e641bd | 2236 | } |
51aa1e9c | 2237 | [(set_attr "op_type" "RS,RSY") |
8b4a4127 | 2238 | (set_attr "type" "stm")]) |
4673c1a0 | 2239 | |
2240 | ;; | |
2241 | ;; String instructions. | |
2242 | ;; | |
2243 | ||
e68d6a13 | 2244 | (define_insn "*execute_rl" |
2245 | [(match_parallel 0 "" | |
2246 | [(unspec [(match_operand 1 "register_operand" "a") | |
2247 | (match_operand 2 "" "") | |
2248 | (match_operand:SI 3 "larl_operand" "X")] UNSPEC_EXECUTE)])] | |
2249 | "TARGET_Z10 && GET_MODE_CLASS (GET_MODE (operands[1])) == MODE_INT | |
2250 | && GET_MODE_SIZE (GET_MODE (operands[1])) <= UNITS_PER_WORD" | |
2251 | "exrl\t%1,%3" | |
2252 | [(set_attr "op_type" "RIL") | |
2253 | (set_attr "type" "cs")]) | |
2254 | ||
d345b493 | 2255 | (define_insn "*execute" |
2256 | [(match_parallel 0 "" | |
2257 | [(unspec [(match_operand 1 "register_operand" "a") | |
2258 | (match_operand:BLK 2 "memory_operand" "R") | |
2259 | (match_operand 3 "" "")] UNSPEC_EXECUTE)])] | |
2260 | "GET_MODE_CLASS (GET_MODE (operands[1])) == MODE_INT | |
2261 | && GET_MODE_SIZE (GET_MODE (operands[1])) <= UNITS_PER_WORD" | |
2262 | "ex\t%1,%2" | |
cec0d54d | 2263 | [(set_attr "op_type" "RX") |
2264 | (set_attr "type" "cs")]) | |
d345b493 | 2265 | |
2266 | ||
a724d2fa | 2267 | ; |
2268 | ; strlenM instruction pattern(s). | |
2269 | ; | |
2270 | ||
2061f1ac | 2271 | (define_expand "strlen<mode>" |
1cdb5e48 | 2272 | [(set (reg:SI 0) (match_operand:SI 2 "immediate_operand" "")) |
346fecd5 | 2273 | (parallel |
a724d2fa | 2274 | [(set (match_dup 4) |
2061f1ac | 2275 | (unspec:P [(const_int 0) |
a724d2fa | 2276 | (match_operand:BLK 1 "memory_operand" "") |
1cdb5e48 | 2277 | (reg:SI 0) |
a724d2fa | 2278 | (match_operand 3 "immediate_operand" "")] UNSPEC_SRST)) |
2061f1ac | 2279 | (clobber (scratch:P)) |
1ca361fd | 2280 | (clobber (reg:CC CC_REGNUM))]) |
a724d2fa | 2281 | (parallel |
2061f1ac | 2282 | [(set (match_operand:P 0 "register_operand" "") |
2283 | (minus:P (match_dup 4) (match_dup 5))) | |
1ca361fd | 2284 | (clobber (reg:CC CC_REGNUM))])] |
2061f1ac | 2285 | "" |
a724d2fa | 2286 | { |
2061f1ac | 2287 | operands[4] = gen_reg_rtx (Pmode); |
2288 | operands[5] = gen_reg_rtx (Pmode); | |
a724d2fa | 2289 | emit_move_insn (operands[5], force_operand (XEXP (operands[1], 0), NULL_RTX)); |
2290 | operands[1] = replace_equiv_address (operands[1], operands[5]); | |
2291 | }) | |
2292 | ||
2061f1ac | 2293 | (define_insn "*strlen<mode>" |
2294 | [(set (match_operand:P 0 "register_operand" "=a") | |
2295 | (unspec:P [(match_operand:P 2 "general_operand" "0") | |
2296 | (mem:BLK (match_operand:P 3 "register_operand" "1")) | |
1cdb5e48 | 2297 | (reg:SI 0) |
a724d2fa | 2298 | (match_operand 4 "immediate_operand" "")] UNSPEC_SRST)) |
2061f1ac | 2299 | (clobber (match_scratch:P 1 "=a")) |
1ca361fd | 2300 | (clobber (reg:CC CC_REGNUM))] |
2061f1ac | 2301 | "" |
a724d2fa | 2302 | "srst\t%0,%1\;jo\t.-4" |
1822f0d6 | 2303 | [(set_attr "length" "8") |
2304 | (set_attr "type" "vs")]) | |
a724d2fa | 2305 | |
1cdb5e48 | 2306 | ; |
2307 | ; cmpstrM instruction pattern(s). | |
2308 | ; | |
2309 | ||
2310 | (define_expand "cmpstrsi" | |
2311 | [(set (reg:SI 0) (const_int 0)) | |
2312 | (parallel | |
2313 | [(clobber (match_operand 3 "" "")) | |
2314 | (clobber (match_dup 4)) | |
2315 | (set (reg:CCU CC_REGNUM) | |
2316 | (compare:CCU (match_operand:BLK 1 "memory_operand" "") | |
2317 | (match_operand:BLK 2 "memory_operand" ""))) | |
2318 | (use (reg:SI 0))]) | |
2319 | (parallel | |
2320 | [(set (match_operand:SI 0 "register_operand" "=d") | |
27784c70 | 2321 | (unspec:SI [(reg:CCU CC_REGNUM)] UNSPEC_CCU_TO_INT)) |
1cdb5e48 | 2322 | (clobber (reg:CC CC_REGNUM))])] |
2323 | "" | |
2324 | { | |
2325 | /* As the result of CMPINT is inverted compared to what we need, | |
2326 | we have to swap the operands. */ | |
2327 | rtx op1 = operands[2]; | |
2328 | rtx op2 = operands[1]; | |
2329 | rtx addr1 = gen_reg_rtx (Pmode); | |
2330 | rtx addr2 = gen_reg_rtx (Pmode); | |
2331 | ||
2332 | emit_move_insn (addr1, force_operand (XEXP (op1, 0), NULL_RTX)); | |
2333 | emit_move_insn (addr2, force_operand (XEXP (op2, 0), NULL_RTX)); | |
2334 | operands[1] = replace_equiv_address_nv (op1, addr1); | |
2335 | operands[2] = replace_equiv_address_nv (op2, addr2); | |
2336 | operands[3] = addr1; | |
2337 | operands[4] = addr2; | |
2338 | }) | |
2339 | ||
2340 | (define_insn "*cmpstr<mode>" | |
2341 | [(clobber (match_operand:P 0 "register_operand" "=d")) | |
2342 | (clobber (match_operand:P 1 "register_operand" "=d")) | |
2343 | (set (reg:CCU CC_REGNUM) | |
2344 | (compare:CCU (mem:BLK (match_operand:P 2 "register_operand" "0")) | |
2345 | (mem:BLK (match_operand:P 3 "register_operand" "1")))) | |
2346 | (use (reg:SI 0))] | |
2347 | "" | |
2348 | "clst\t%0,%1\;jo\t.-4" | |
2349 | [(set_attr "length" "8") | |
2350 | (set_attr "type" "vs")]) | |
2351 | ||
495a87f4 | 2352 | ; |
2353 | ; movstr instruction pattern. | |
2354 | ; | |
2355 | ||
2356 | (define_expand "movstr" | |
2357 | [(set (reg:SI 0) (const_int 0)) | |
2358 | (parallel | |
2359 | [(clobber (match_dup 3)) | |
2360 | (set (match_operand:BLK 1 "memory_operand" "") | |
2361 | (match_operand:BLK 2 "memory_operand" "")) | |
2362 | (set (match_operand 0 "register_operand" "") | |
2363 | (unspec [(match_dup 1) | |
2364 | (match_dup 2) | |
2365 | (reg:SI 0)] UNSPEC_MVST)) | |
2366 | (clobber (reg:CC CC_REGNUM))])] | |
2367 | "" | |
2368 | { | |
2369 | rtx addr1 = gen_reg_rtx (Pmode); | |
2370 | rtx addr2 = gen_reg_rtx (Pmode); | |
2371 | ||
2372 | emit_move_insn (addr1, force_operand (XEXP (operands[1], 0), NULL_RTX)); | |
2373 | emit_move_insn (addr2, force_operand (XEXP (operands[2], 0), NULL_RTX)); | |
2374 | operands[1] = replace_equiv_address_nv (operands[1], addr1); | |
2375 | operands[2] = replace_equiv_address_nv (operands[2], addr2); | |
2376 | operands[3] = addr2; | |
2377 | }) | |
2378 | ||
2379 | (define_insn "*movstr" | |
2380 | [(clobber (match_operand:P 2 "register_operand" "=d")) | |
2381 | (set (mem:BLK (match_operand:P 1 "register_operand" "0")) | |
2382 | (mem:BLK (match_operand:P 3 "register_operand" "2"))) | |
2383 | (set (match_operand:P 0 "register_operand" "=d") | |
2384 | (unspec [(mem:BLK (match_dup 1)) | |
2385 | (mem:BLK (match_dup 3)) | |
2386 | (reg:SI 0)] UNSPEC_MVST)) | |
2387 | (clobber (reg:CC CC_REGNUM))] | |
2388 | "" | |
2389 | "mvst\t%1,%2\;jo\t.-4" | |
2390 | [(set_attr "length" "8") | |
2391 | (set_attr "type" "vs")]) | |
2392 | ||
2393 | ||
4673c1a0 | 2394 | ; |
008c057d | 2395 | ; movmemM instruction pattern(s). |
4673c1a0 | 2396 | ; |
2397 | ||
2061f1ac | 2398 | (define_expand "movmem<mode>" |
e68d6a13 | 2399 | [(set (match_operand:BLK 0 "memory_operand" "") ; destination |
2400 | (match_operand:BLK 1 "memory_operand" "")) ; source | |
2401 | (use (match_operand:GPR 2 "general_operand" "")) ; count | |
4fbc4db5 | 2402 | (match_operand 3 "" "")] |
2403 | "" | |
008c057d | 2404 | "s390_expand_movmem (operands[0], operands[1], operands[2]); DONE;") |
4673c1a0 | 2405 | |
66a63c5b | 2406 | ; Move a block that is up to 256 bytes in length. |
2407 | ; The block length is taken as (operands[2] % 256) + 1. | |
4673c1a0 | 2408 | |
008c057d | 2409 | (define_expand "movmem_short" |
31838f66 | 2410 | [(parallel |
2411 | [(set (match_operand:BLK 0 "memory_operand" "") | |
2412 | (match_operand:BLK 1 "memory_operand" "")) | |
2413 | (use (match_operand 2 "nonmemory_operand" "")) | |
d345b493 | 2414 | (use (const:BLK (unspec:BLK [(const_int 0)] UNSPEC_INSN))) |
31838f66 | 2415 | (clobber (match_dup 3))])] |
2416 | "" | |
2417 | "operands[3] = gen_rtx_SCRATCH (Pmode);") | |
66a63c5b | 2418 | |
008c057d | 2419 | (define_insn "*movmem_short" |
e68d6a13 | 2420 | [(set (match_operand:BLK 0 "memory_operand" "=Q,Q,Q,Q") |
2421 | (match_operand:BLK 1 "memory_operand" "Q,Q,Q,Q")) | |
2422 | (use (match_operand 2 "nonmemory_operand" "n,a,a,a")) | |
2423 | (use (match_operand 3 "immediate_operand" "X,R,X,X")) | |
2424 | (clobber (match_scratch 4 "=X,X,X,&a"))] | |
31838f66 | 2425 | "(GET_MODE (operands[2]) == Pmode || GET_MODE (operands[2]) == VOIDmode) |
d345b493 | 2426 | && GET_MODE (operands[4]) == Pmode" |
2427 | "#" | |
e68d6a13 | 2428 | [(set_attr "type" "cs") |
2429 | (set_attr "cpu_facility" "*,*,z10,*")]) | |
66a63c5b | 2430 | |
d345b493 | 2431 | (define_split |
2432 | [(set (match_operand:BLK 0 "memory_operand" "") | |
2433 | (match_operand:BLK 1 "memory_operand" "")) | |
2434 | (use (match_operand 2 "const_int_operand" "")) | |
2435 | (use (match_operand 3 "immediate_operand" "")) | |
2436 | (clobber (scratch))] | |
2437 | "reload_completed" | |
2438 | [(parallel | |
2439 | [(set (match_dup 0) (match_dup 1)) | |
2440 | (use (match_dup 2))])] | |
2441 | "operands[2] = GEN_INT ((INTVAL (operands[2]) & 0xff) + 1);") | |
4673c1a0 | 2442 | |
d345b493 | 2443 | (define_split |
2444 | [(set (match_operand:BLK 0 "memory_operand" "") | |
2445 | (match_operand:BLK 1 "memory_operand" "")) | |
2446 | (use (match_operand 2 "register_operand" "")) | |
2447 | (use (match_operand 3 "memory_operand" "")) | |
2448 | (clobber (scratch))] | |
2449 | "reload_completed" | |
2450 | [(parallel | |
2451 | [(unspec [(match_dup 2) (match_dup 3) | |
2452 | (const_int 0)] UNSPEC_EXECUTE) | |
2453 | (set (match_dup 0) (match_dup 1)) | |
2454 | (use (const_int 1))])] | |
2455 | "") | |
2456 | ||
e68d6a13 | 2457 | (define_split |
2458 | [(set (match_operand:BLK 0 "memory_operand" "") | |
2459 | (match_operand:BLK 1 "memory_operand" "")) | |
2460 | (use (match_operand 2 "register_operand" "")) | |
2461 | (use (const:BLK (unspec:BLK [(const_int 0)] UNSPEC_INSN))) | |
2462 | (clobber (scratch))] | |
2463 | "TARGET_Z10 && reload_completed" | |
2464 | [(parallel | |
2465 | [(unspec [(match_dup 2) (const_int 0) | |
2466 | (label_ref (match_dup 3))] UNSPEC_EXECUTE) | |
2467 | (set (match_dup 0) (match_dup 1)) | |
2468 | (use (const_int 1))])] | |
2469 | "operands[3] = gen_label_rtx ();") | |
2470 | ||
d345b493 | 2471 | (define_split |
2472 | [(set (match_operand:BLK 0 "memory_operand" "") | |
2473 | (match_operand:BLK 1 "memory_operand" "")) | |
2474 | (use (match_operand 2 "register_operand" "")) | |
2475 | (use (const:BLK (unspec:BLK [(const_int 0)] UNSPEC_INSN))) | |
2476 | (clobber (match_operand 3 "register_operand" ""))] | |
2477 | "reload_completed && TARGET_CPU_ZARCH" | |
2478 | [(set (match_dup 3) (label_ref (match_dup 4))) | |
2479 | (parallel | |
2480 | [(unspec [(match_dup 2) (mem:BLK (match_dup 3)) | |
2481 | (label_ref (match_dup 4))] UNSPEC_EXECUTE) | |
2482 | (set (match_dup 0) (match_dup 1)) | |
2483 | (use (const_int 1))])] | |
2484 | "operands[4] = gen_label_rtx ();") | |
2485 | ||
4fbc4db5 | 2486 | ; Move a block of arbitrary length. |
4673c1a0 | 2487 | |
008c057d | 2488 | (define_expand "movmem_long" |
31838f66 | 2489 | [(parallel |
2490 | [(clobber (match_dup 2)) | |
2491 | (clobber (match_dup 3)) | |
2492 | (set (match_operand:BLK 0 "memory_operand" "") | |
2493 | (match_operand:BLK 1 "memory_operand" "")) | |
2494 | (use (match_operand 2 "general_operand" "")) | |
2495 | (use (match_dup 3)) | |
1ca361fd | 2496 | (clobber (reg:CC CC_REGNUM))])] |
31838f66 | 2497 | "" |
2498 | { | |
2499 | enum machine_mode dword_mode = word_mode == DImode ? TImode : DImode; | |
2500 | rtx reg0 = gen_reg_rtx (dword_mode); | |
2501 | rtx reg1 = gen_reg_rtx (dword_mode); | |
2502 | rtx addr0 = gen_lowpart (Pmode, gen_highpart (word_mode, reg0)); | |
2503 | rtx addr1 = gen_lowpart (Pmode, gen_highpart (word_mode, reg1)); | |
2504 | rtx len0 = gen_lowpart (Pmode, reg0); | |
2505 | rtx len1 = gen_lowpart (Pmode, reg1); | |
2506 | ||
18b42941 | 2507 | emit_clobber (reg0); |
31838f66 | 2508 | emit_move_insn (addr0, force_operand (XEXP (operands[0], 0), NULL_RTX)); |
2509 | emit_move_insn (len0, operands[2]); | |
2510 | ||
18b42941 | 2511 | emit_clobber (reg1); |
31838f66 | 2512 | emit_move_insn (addr1, force_operand (XEXP (operands[1], 0), NULL_RTX)); |
2513 | emit_move_insn (len1, operands[2]); | |
2514 | ||
2515 | operands[0] = replace_equiv_address_nv (operands[0], addr0); | |
2516 | operands[1] = replace_equiv_address_nv (operands[1], addr1); | |
2517 | operands[2] = reg0; | |
2518 | operands[3] = reg1; | |
2519 | }) | |
2520 | ||
0eed6e19 | 2521 | (define_insn "*movmem_long" |
2522 | [(clobber (match_operand:<DBL> 0 "register_operand" "=d")) | |
2523 | (clobber (match_operand:<DBL> 1 "register_operand" "=d")) | |
2524 | (set (mem:BLK (subreg:P (match_operand:<DBL> 2 "register_operand" "0") 0)) | |
2525 | (mem:BLK (subreg:P (match_operand:<DBL> 3 "register_operand" "1") 0))) | |
31838f66 | 2526 | (use (match_dup 2)) |
2527 | (use (match_dup 3)) | |
1ca361fd | 2528 | (clobber (reg:CC CC_REGNUM))] |
0eed6e19 | 2529 | "" |
f24d7ff3 | 2530 | "mvcle\t%0,%1,0\;jo\t.-4" |
1822f0d6 | 2531 | [(set_attr "length" "8") |
2532 | (set_attr "type" "vs")]) | |
4673c1a0 | 2533 | |
27784c70 | 2534 | |
2535 | ; | |
2536 | ; Test data class. | |
2537 | ; | |
2538 | ||
93f564d6 | 2539 | (define_expand "signbit<mode>2" |
2540 | [(set (reg:CCZ CC_REGNUM) | |
d1191819 | 2541 | (unspec:CCZ [(match_operand:FP_ALL 1 "register_operand" "f") |
93f564d6 | 2542 | (match_dup 2)] |
2543 | UNSPEC_TDC_INSN)) | |
2544 | (set (match_operand:SI 0 "register_operand" "=d") | |
2545 | (unspec:SI [(reg:CCZ CC_REGNUM)] UNSPEC_CCZ_TO_INT))] | |
2546 | "TARGET_HARD_FLOAT" | |
2547 | { | |
2548 | operands[2] = GEN_INT (S390_TDC_SIGNBIT_SET); | |
2549 | }) | |
2550 | ||
27784c70 | 2551 | (define_expand "isinf<mode>2" |
2552 | [(set (reg:CCZ CC_REGNUM) | |
d1191819 | 2553 | (unspec:CCZ [(match_operand:FP_ALL 1 "register_operand" "f") |
27784c70 | 2554 | (match_dup 2)] |
2555 | UNSPEC_TDC_INSN)) | |
2556 | (set (match_operand:SI 0 "register_operand" "=d") | |
2557 | (unspec:SI [(reg:CCZ CC_REGNUM)] UNSPEC_CCZ_TO_INT))] | |
095798e3 | 2558 | "TARGET_HARD_FLOAT" |
27784c70 | 2559 | { |
2560 | operands[2] = GEN_INT (S390_TDC_INFINITY); | |
2561 | }) | |
2562 | ||
2563 | ; This insn is used to generate all variants of the Test Data Class | |
2564 | ; instruction, namely tcxb, tcdb, and tceb. The insn's first operand | |
2565 | ; is the register to be tested and the second one is the bit mask | |
2566 | ; specifying the required test(s). | |
2567 | ; | |
2568 | (define_insn "*TDC_insn_<mode>" | |
2569 | [(set (reg:CCZ CC_REGNUM) | |
d1191819 | 2570 | (unspec:CCZ [(match_operand:FP_ALL 0 "register_operand" "f") |
27784c70 | 2571 | (match_operand:SI 1 "const_int_operand")] UNSPEC_TDC_INSN))] |
095798e3 | 2572 | "TARGET_HARD_FLOAT" |
d1191819 | 2573 | "t<_d>c<xde><bt>\t%0,%1" |
27784c70 | 2574 | [(set_attr "op_type" "RXE") |
d1191819 | 2575 | (set_attr "type" "fsimp<bfp>")]) |
27784c70 | 2576 | |
2577 | (define_insn_and_split "*ccz_to_int" | |
2578 | [(set (match_operand:SI 0 "register_operand" "=d") | |
2579 | (unspec:SI [(match_operand:CCZ 1 "register_operand" "0")] | |
2580 | UNSPEC_CCZ_TO_INT))] | |
2581 | "" | |
2582 | "#" | |
2583 | "reload_completed" | |
2584 | [(set (match_dup 0) (lshiftrt:SI (match_dup 0) (const_int 28)))]) | |
2585 | ||
2586 | ||
4673c1a0 | 2587 | ; |
7a3e5564 | 2588 | ; setmemM instruction pattern(s). |
4673c1a0 | 2589 | ; |
2590 | ||
7a3e5564 | 2591 | (define_expand "setmem<mode>" |
4fbc4db5 | 2592 | [(set (match_operand:BLK 0 "memory_operand" "") |
805a133b | 2593 | (match_operand:QI 2 "general_operand" "")) |
2061f1ac | 2594 | (use (match_operand:GPR 1 "general_operand" "")) |
7a3e5564 | 2595 | (match_operand 3 "" "")] |
4fbc4db5 | 2596 | "" |
805a133b | 2597 | "s390_expand_setmem (operands[0], operands[1], operands[2]); DONE;") |
4673c1a0 | 2598 | |
4fbc4db5 | 2599 | ; Clear a block that is up to 256 bytes in length. |
31838f66 | 2600 | ; The block length is taken as (operands[1] % 256) + 1. |
2601 | ||
008c057d | 2602 | (define_expand "clrmem_short" |
31838f66 | 2603 | [(parallel |
2604 | [(set (match_operand:BLK 0 "memory_operand" "") | |
2605 | (const_int 0)) | |
2606 | (use (match_operand 1 "nonmemory_operand" "")) | |
d345b493 | 2607 | (use (const:BLK (unspec:BLK [(const_int 0)] UNSPEC_INSN))) |
31838f66 | 2608 | (clobber (match_dup 2)) |
1ca361fd | 2609 | (clobber (reg:CC CC_REGNUM))])] |
31838f66 | 2610 | "" |
2611 | "operands[2] = gen_rtx_SCRATCH (Pmode);") | |
4673c1a0 | 2612 | |
008c057d | 2613 | (define_insn "*clrmem_short" |
e68d6a13 | 2614 | [(set (match_operand:BLK 0 "memory_operand" "=Q,Q,Q,Q") |
4fbc4db5 | 2615 | (const_int 0)) |
e68d6a13 | 2616 | (use (match_operand 1 "nonmemory_operand" "n,a,a,a")) |
2617 | (use (match_operand 2 "immediate_operand" "X,R,X,X")) | |
2618 | (clobber (match_scratch 3 "=X,X,X,&a")) | |
1ca361fd | 2619 | (clobber (reg:CC CC_REGNUM))] |
31838f66 | 2620 | "(GET_MODE (operands[1]) == Pmode || GET_MODE (operands[1]) == VOIDmode) |
d345b493 | 2621 | && GET_MODE (operands[3]) == Pmode" |
2622 | "#" | |
e68d6a13 | 2623 | [(set_attr "type" "cs") |
2624 | (set_attr "cpu_facility" "*,*,z10,*")]) | |
d345b493 | 2625 | |
2626 | (define_split | |
2627 | [(set (match_operand:BLK 0 "memory_operand" "") | |
2628 | (const_int 0)) | |
2629 | (use (match_operand 1 "const_int_operand" "")) | |
2630 | (use (match_operand 2 "immediate_operand" "")) | |
2631 | (clobber (scratch)) | |
1ca361fd | 2632 | (clobber (reg:CC CC_REGNUM))] |
d345b493 | 2633 | "reload_completed" |
2634 | [(parallel | |
2635 | [(set (match_dup 0) (const_int 0)) | |
2636 | (use (match_dup 1)) | |
1ca361fd | 2637 | (clobber (reg:CC CC_REGNUM))])] |
d345b493 | 2638 | "operands[1] = GEN_INT ((INTVAL (operands[1]) & 0xff) + 1);") |
4673c1a0 | 2639 | |
d345b493 | 2640 | (define_split |
2641 | [(set (match_operand:BLK 0 "memory_operand" "") | |
2642 | (const_int 0)) | |
2643 | (use (match_operand 1 "register_operand" "")) | |
2644 | (use (match_operand 2 "memory_operand" "")) | |
2645 | (clobber (scratch)) | |
1ca361fd | 2646 | (clobber (reg:CC CC_REGNUM))] |
d345b493 | 2647 | "reload_completed" |
2648 | [(parallel | |
2649 | [(unspec [(match_dup 1) (match_dup 2) | |
2650 | (const_int 0)] UNSPEC_EXECUTE) | |
2651 | (set (match_dup 0) (const_int 0)) | |
2652 | (use (const_int 1)) | |
1ca361fd | 2653 | (clobber (reg:CC CC_REGNUM))])] |
d345b493 | 2654 | "") |
4673c1a0 | 2655 | |
e68d6a13 | 2656 | (define_split |
2657 | [(set (match_operand:BLK 0 "memory_operand" "") | |
2658 | (const_int 0)) | |
2659 | (use (match_operand 1 "register_operand" "")) | |
2660 | (use (const:BLK (unspec:BLK [(const_int 0)] UNSPEC_INSN))) | |
2661 | (clobber (scratch)) | |
2662 | (clobber (reg:CC CC_REGNUM))] | |
2663 | "TARGET_Z10 && reload_completed" | |
2664 | [(parallel | |
2665 | [(unspec [(match_dup 1) (const_int 0) | |
2666 | (label_ref (match_dup 3))] UNSPEC_EXECUTE) | |
2667 | (set (match_dup 0) (const_int 0)) | |
2668 | (use (const_int 1)) | |
2669 | (clobber (reg:CC CC_REGNUM))])] | |
2670 | "operands[3] = gen_label_rtx ();") | |
2671 | ||
d345b493 | 2672 | (define_split |
2673 | [(set (match_operand:BLK 0 "memory_operand" "") | |
2674 | (const_int 0)) | |
2675 | (use (match_operand 1 "register_operand" "")) | |
2676 | (use (const:BLK (unspec:BLK [(const_int 0)] UNSPEC_INSN))) | |
2677 | (clobber (match_operand 2 "register_operand" "")) | |
1ca361fd | 2678 | (clobber (reg:CC CC_REGNUM))] |
d345b493 | 2679 | "reload_completed && TARGET_CPU_ZARCH" |
2680 | [(set (match_dup 2) (label_ref (match_dup 3))) | |
2681 | (parallel | |
2682 | [(unspec [(match_dup 1) (mem:BLK (match_dup 2)) | |
2683 | (label_ref (match_dup 3))] UNSPEC_EXECUTE) | |
2684 | (set (match_dup 0) (const_int 0)) | |
2685 | (use (const_int 1)) | |
1ca361fd | 2686 | (clobber (reg:CC CC_REGNUM))])] |
d345b493 | 2687 | "operands[3] = gen_label_rtx ();") |
2688 | ||
805a133b | 2689 | ; Initialize a block of arbitrary length with (operands[2] % 256). |
31838f66 | 2690 | |
805a133b | 2691 | (define_expand "setmem_long" |
31838f66 | 2692 | [(parallel |
2693 | [(clobber (match_dup 1)) | |
2694 | (set (match_operand:BLK 0 "memory_operand" "") | |
417cba42 | 2695 | (match_operand 2 "shift_count_or_setmem_operand" "")) |
31838f66 | 2696 | (use (match_operand 1 "general_operand" "")) |
805a133b | 2697 | (use (match_dup 3)) |
1ca361fd | 2698 | (clobber (reg:CC CC_REGNUM))])] |
31838f66 | 2699 | "" |
4fbc4db5 | 2700 | { |
31838f66 | 2701 | enum machine_mode dword_mode = word_mode == DImode ? TImode : DImode; |
2702 | rtx reg0 = gen_reg_rtx (dword_mode); | |
2703 | rtx reg1 = gen_reg_rtx (dword_mode); | |
2704 | rtx addr0 = gen_lowpart (Pmode, gen_highpart (word_mode, reg0)); | |
2705 | rtx len0 = gen_lowpart (Pmode, reg0); | |
4673c1a0 | 2706 | |
18b42941 | 2707 | emit_clobber (reg0); |
31838f66 | 2708 | emit_move_insn (addr0, force_operand (XEXP (operands[0], 0), NULL_RTX)); |
2709 | emit_move_insn (len0, operands[1]); | |
4673c1a0 | 2710 | |
31838f66 | 2711 | emit_move_insn (reg1, const0_rtx); |
4fbc4db5 | 2712 | |
31838f66 | 2713 | operands[0] = replace_equiv_address_nv (operands[0], addr0); |
2714 | operands[1] = reg0; | |
805a133b | 2715 | operands[3] = reg1; |
31838f66 | 2716 | }) |
4fbc4db5 | 2717 | |
805a133b | 2718 | (define_insn "*setmem_long" |
0eed6e19 | 2719 | [(clobber (match_operand:<DBL> 0 "register_operand" "=d")) |
805a133b | 2720 | (set (mem:BLK (subreg:P (match_operand:<DBL> 3 "register_operand" "0") 0)) |
417cba42 | 2721 | (match_operand 2 "shift_count_or_setmem_operand" "Y")) |
805a133b | 2722 | (use (match_dup 3)) |
0eed6e19 | 2723 | (use (match_operand:<DBL> 1 "register_operand" "d")) |
1ca361fd | 2724 | (clobber (reg:CC CC_REGNUM))] |
0eed6e19 | 2725 | "" |
805a133b | 2726 | "mvcle\t%0,%1,%Y2\;jo\t.-4" |
1822f0d6 | 2727 | [(set_attr "length" "8") |
2728 | (set_attr "type" "vs")]) | |
4673c1a0 | 2729 | |
417cba42 | 2730 | (define_insn "*setmem_long_and" |
2731 | [(clobber (match_operand:<DBL> 0 "register_operand" "=d")) | |
2732 | (set (mem:BLK (subreg:P (match_operand:<DBL> 3 "register_operand" "0") 0)) | |
2733 | (and (match_operand 2 "shift_count_or_setmem_operand" "Y") | |
2734 | (match_operand 4 "const_int_operand" "n"))) | |
2735 | (use (match_dup 3)) | |
2736 | (use (match_operand:<DBL> 1 "register_operand" "d")) | |
2737 | (clobber (reg:CC CC_REGNUM))] | |
2738 | "(INTVAL (operands[4]) & 255) == 255" | |
2739 | "mvcle\t%0,%1,%Y2\;jo\t.-4" | |
2740 | [(set_attr "length" "8") | |
2741 | (set_attr "type" "vs")]) | |
4673c1a0 | 2742 | ; |
b428c0a5 | 2743 | ; cmpmemM instruction pattern(s). |
4673c1a0 | 2744 | ; |
2745 | ||
b428c0a5 | 2746 | (define_expand "cmpmemsi" |
4fbc4db5 | 2747 | [(set (match_operand:SI 0 "register_operand" "") |
2748 | (compare:SI (match_operand:BLK 1 "memory_operand" "") | |
2749 | (match_operand:BLK 2 "memory_operand" "") ) ) | |
2750 | (use (match_operand:SI 3 "general_operand" "")) | |
2751 | (use (match_operand:SI 4 "" ""))] | |
2752 | "" | |
f81e845f | 2753 | "s390_expand_cmpmem (operands[0], operands[1], |
4fbc4db5 | 2754 | operands[2], operands[3]); DONE;") |
4673c1a0 | 2755 | |
4fbc4db5 | 2756 | ; Compare a block that is up to 256 bytes in length. |
2757 | ; The block length is taken as (operands[2] % 256) + 1. | |
4673c1a0 | 2758 | |
31838f66 | 2759 | (define_expand "cmpmem_short" |
2760 | [(parallel | |
1ca361fd | 2761 | [(set (reg:CCU CC_REGNUM) |
80b53886 | 2762 | (compare:CCU (match_operand:BLK 0 "memory_operand" "") |
31838f66 | 2763 | (match_operand:BLK 1 "memory_operand" ""))) |
2764 | (use (match_operand 2 "nonmemory_operand" "")) | |
d345b493 | 2765 | (use (const:BLK (unspec:BLK [(const_int 0)] UNSPEC_INSN))) |
31838f66 | 2766 | (clobber (match_dup 3))])] |
2767 | "" | |
2768 | "operands[3] = gen_rtx_SCRATCH (Pmode);") | |
4673c1a0 | 2769 | |
31838f66 | 2770 | (define_insn "*cmpmem_short" |
1ca361fd | 2771 | [(set (reg:CCU CC_REGNUM) |
e68d6a13 | 2772 | (compare:CCU (match_operand:BLK 0 "memory_operand" "Q,Q,Q,Q") |
2773 | (match_operand:BLK 1 "memory_operand" "Q,Q,Q,Q"))) | |
2774 | (use (match_operand 2 "nonmemory_operand" "n,a,a,a")) | |
2775 | (use (match_operand 3 "immediate_operand" "X,R,X,X")) | |
2776 | (clobber (match_scratch 4 "=X,X,X,&a"))] | |
31838f66 | 2777 | "(GET_MODE (operands[2]) == Pmode || GET_MODE (operands[2]) == VOIDmode) |
d345b493 | 2778 | && GET_MODE (operands[4]) == Pmode" |
2779 | "#" | |
e68d6a13 | 2780 | [(set_attr "type" "cs") |
2781 | (set_attr "cpu_facility" "*,*,z10,*")]) | |
4673c1a0 | 2782 | |
d345b493 | 2783 | (define_split |
1ca361fd | 2784 | [(set (reg:CCU CC_REGNUM) |
d345b493 | 2785 | (compare:CCU (match_operand:BLK 0 "memory_operand" "") |
2786 | (match_operand:BLK 1 "memory_operand" ""))) | |
2787 | (use (match_operand 2 "const_int_operand" "")) | |
2788 | (use (match_operand 3 "immediate_operand" "")) | |
2789 | (clobber (scratch))] | |
2790 | "reload_completed" | |
2791 | [(parallel | |
1ca361fd | 2792 | [(set (reg:CCU CC_REGNUM) (compare:CCU (match_dup 0) (match_dup 1))) |
d345b493 | 2793 | (use (match_dup 2))])] |
2794 | "operands[2] = GEN_INT ((INTVAL (operands[2]) & 0xff) + 1);") | |
4673c1a0 | 2795 | |
d345b493 | 2796 | (define_split |
1ca361fd | 2797 | [(set (reg:CCU CC_REGNUM) |
d345b493 | 2798 | (compare:CCU (match_operand:BLK 0 "memory_operand" "") |
2799 | (match_operand:BLK 1 "memory_operand" ""))) | |
2800 | (use (match_operand 2 "register_operand" "")) | |
2801 | (use (match_operand 3 "memory_operand" "")) | |
2802 | (clobber (scratch))] | |
2803 | "reload_completed" | |
2804 | [(parallel | |
2805 | [(unspec [(match_dup 2) (match_dup 3) | |
2806 | (const_int 0)] UNSPEC_EXECUTE) | |
1ca361fd | 2807 | (set (reg:CCU CC_REGNUM) (compare:CCU (match_dup 0) (match_dup 1))) |
d345b493 | 2808 | (use (const_int 1))])] |
2809 | "") | |
2810 | ||
e68d6a13 | 2811 | (define_split |
2812 | [(set (reg:CCU CC_REGNUM) | |
2813 | (compare:CCU (match_operand:BLK 0 "memory_operand" "") | |
2814 | (match_operand:BLK 1 "memory_operand" ""))) | |
2815 | (use (match_operand 2 "register_operand" "")) | |
2816 | (use (const:BLK (unspec:BLK [(const_int 0)] UNSPEC_INSN))) | |
2817 | (clobber (scratch))] | |
2818 | "TARGET_Z10 && reload_completed" | |
2819 | [(parallel | |
2820 | [(unspec [(match_dup 2) (const_int 0) | |
2821 | (label_ref (match_dup 4))] UNSPEC_EXECUTE) | |
2822 | (set (reg:CCU CC_REGNUM) (compare:CCU (match_dup 0) (match_dup 1))) | |
2823 | (use (const_int 1))])] | |
2824 | "operands[4] = gen_label_rtx ();") | |
2825 | ||
d345b493 | 2826 | (define_split |
1ca361fd | 2827 | [(set (reg:CCU CC_REGNUM) |
d345b493 | 2828 | (compare:CCU (match_operand:BLK 0 "memory_operand" "") |
2829 | (match_operand:BLK 1 "memory_operand" ""))) | |
2830 | (use (match_operand 2 "register_operand" "")) | |
2831 | (use (const:BLK (unspec:BLK [(const_int 0)] UNSPEC_INSN))) | |
2832 | (clobber (match_operand 3 "register_operand" ""))] | |
2833 | "reload_completed && TARGET_CPU_ZARCH" | |
2834 | [(set (match_dup 3) (label_ref (match_dup 4))) | |
2835 | (parallel | |
2836 | [(unspec [(match_dup 2) (mem:BLK (match_dup 3)) | |
2837 | (label_ref (match_dup 4))] UNSPEC_EXECUTE) | |
1ca361fd | 2838 | (set (reg:CCU CC_REGNUM) (compare:CCU (match_dup 0) (match_dup 1))) |
d345b493 | 2839 | (use (const_int 1))])] |
2840 | "operands[4] = gen_label_rtx ();") | |
2841 | ||
4fbc4db5 | 2842 | ; Compare a block of arbitrary length. |
4673c1a0 | 2843 | |
31838f66 | 2844 | (define_expand "cmpmem_long" |
2845 | [(parallel | |
2846 | [(clobber (match_dup 2)) | |
2847 | (clobber (match_dup 3)) | |
1ca361fd | 2848 | (set (reg:CCU CC_REGNUM) |
80b53886 | 2849 | (compare:CCU (match_operand:BLK 0 "memory_operand" "") |
31838f66 | 2850 | (match_operand:BLK 1 "memory_operand" ""))) |
2851 | (use (match_operand 2 "general_operand" "")) | |
2852 | (use (match_dup 3))])] | |
2853 | "" | |
2854 | { | |
2855 | enum machine_mode dword_mode = word_mode == DImode ? TImode : DImode; | |
2856 | rtx reg0 = gen_reg_rtx (dword_mode); | |
2857 | rtx reg1 = gen_reg_rtx (dword_mode); | |
2858 | rtx addr0 = gen_lowpart (Pmode, gen_highpart (word_mode, reg0)); | |
2859 | rtx addr1 = gen_lowpart (Pmode, gen_highpart (word_mode, reg1)); | |
2860 | rtx len0 = gen_lowpart (Pmode, reg0); | |
2861 | rtx len1 = gen_lowpart (Pmode, reg1); | |
2862 | ||
18b42941 | 2863 | emit_clobber (reg0); |
31838f66 | 2864 | emit_move_insn (addr0, force_operand (XEXP (operands[0], 0), NULL_RTX)); |
2865 | emit_move_insn (len0, operands[2]); | |
2866 | ||
18b42941 | 2867 | emit_clobber (reg1); |
31838f66 | 2868 | emit_move_insn (addr1, force_operand (XEXP (operands[1], 0), NULL_RTX)); |
2869 | emit_move_insn (len1, operands[2]); | |
2870 | ||
2871 | operands[0] = replace_equiv_address_nv (operands[0], addr0); | |
2872 | operands[1] = replace_equiv_address_nv (operands[1], addr1); | |
2873 | operands[2] = reg0; | |
2874 | operands[3] = reg1; | |
2875 | }) | |
2876 | ||
0eed6e19 | 2877 | (define_insn "*cmpmem_long" |
2878 | [(clobber (match_operand:<DBL> 0 "register_operand" "=d")) | |
2879 | (clobber (match_operand:<DBL> 1 "register_operand" "=d")) | |
1ca361fd | 2880 | (set (reg:CCU CC_REGNUM) |
0eed6e19 | 2881 | (compare:CCU (mem:BLK (subreg:P (match_operand:<DBL> 2 "register_operand" "0") 0)) |
2882 | (mem:BLK (subreg:P (match_operand:<DBL> 3 "register_operand" "1") 0)))) | |
e3233937 | 2883 | (use (match_dup 2)) |
2884 | (use (match_dup 3))] | |
0eed6e19 | 2885 | "" |
03360df8 | 2886 | "clcle\t%0,%1,0\;jo\t.-4" |
1822f0d6 | 2887 | [(set_attr "length" "8") |
2888 | (set_attr "type" "vs")]) | |
4673c1a0 | 2889 | |
dd16a4bd | 2890 | ; Convert CCUmode condition code to integer. |
2891 | ; Result is zero if EQ, positive if LTU, negative if GTU. | |
4673c1a0 | 2892 | |
dd16a4bd | 2893 | (define_insn_and_split "cmpint" |
4673c1a0 | 2894 | [(set (match_operand:SI 0 "register_operand" "=d") |
dd16a4bd | 2895 | (unspec:SI [(match_operand:CCU 1 "register_operand" "0")] |
27784c70 | 2896 | UNSPEC_CCU_TO_INT)) |
1ca361fd | 2897 | (clobber (reg:CC CC_REGNUM))] |
4673c1a0 | 2898 | "" |
dd16a4bd | 2899 | "#" |
2900 | "reload_completed" | |
2901 | [(set (match_dup 0) (ashift:SI (match_dup 0) (const_int 2))) | |
2902 | (parallel | |
2903 | [(set (match_dup 0) (ashiftrt:SI (match_dup 0) (const_int 30))) | |
1ca361fd | 2904 | (clobber (reg:CC CC_REGNUM))])]) |
dd16a4bd | 2905 | |
2906 | (define_insn_and_split "*cmpint_cc" | |
1ca361fd | 2907 | [(set (reg CC_REGNUM) |
dd16a4bd | 2908 | (compare (unspec:SI [(match_operand:CCU 1 "register_operand" "0")] |
27784c70 | 2909 | UNSPEC_CCU_TO_INT) |
dd16a4bd | 2910 | (const_int 0))) |
2911 | (set (match_operand:SI 0 "register_operand" "=d") | |
27784c70 | 2912 | (unspec:SI [(match_dup 1)] UNSPEC_CCU_TO_INT))] |
dd16a4bd | 2913 | "s390_match_ccmode (insn, CCSmode)" |
2914 | "#" | |
2915 | "&& reload_completed" | |
2916 | [(set (match_dup 0) (ashift:SI (match_dup 0) (const_int 2))) | |
2917 | (parallel | |
2918 | [(set (match_dup 2) (match_dup 3)) | |
2919 | (set (match_dup 0) (ashiftrt:SI (match_dup 0) (const_int 30)))])] | |
4673c1a0 | 2920 | { |
dd16a4bd | 2921 | rtx result = gen_rtx_ASHIFTRT (SImode, operands[0], GEN_INT (30)); |
2922 | operands[2] = SET_DEST (XVECEXP (PATTERN (curr_insn), 0, 0)); | |
2923 | operands[3] = gen_rtx_COMPARE (GET_MODE (operands[2]), result, const0_rtx); | |
2924 | }) | |
4673c1a0 | 2925 | |
dd16a4bd | 2926 | (define_insn_and_split "*cmpint_sign" |
4673c1a0 | 2927 | [(set (match_operand:DI 0 "register_operand" "=d") |
dd16a4bd | 2928 | (sign_extend:DI (unspec:SI [(match_operand:CCU 1 "register_operand" "0")] |
27784c70 | 2929 | UNSPEC_CCU_TO_INT))) |
1ca361fd | 2930 | (clobber (reg:CC CC_REGNUM))] |
4673c1a0 | 2931 | "TARGET_64BIT" |
dd16a4bd | 2932 | "#" |
2933 | "&& reload_completed" | |
2934 | [(set (match_dup 0) (ashift:DI (match_dup 0) (const_int 34))) | |
2935 | (parallel | |
2936 | [(set (match_dup 0) (ashiftrt:DI (match_dup 0) (const_int 62))) | |
1ca361fd | 2937 | (clobber (reg:CC CC_REGNUM))])]) |
dd16a4bd | 2938 | |
2939 | (define_insn_and_split "*cmpint_sign_cc" | |
1ca361fd | 2940 | [(set (reg CC_REGNUM) |
dd16a4bd | 2941 | (compare (ashiftrt:DI (ashift:DI (subreg:DI |
2942 | (unspec:SI [(match_operand:CCU 1 "register_operand" "0")] | |
27784c70 | 2943 | UNSPEC_CCU_TO_INT) 0) |
dd16a4bd | 2944 | (const_int 32)) (const_int 32)) |
2945 | (const_int 0))) | |
2946 | (set (match_operand:DI 0 "register_operand" "=d") | |
27784c70 | 2947 | (sign_extend:DI (unspec:SI [(match_dup 1)] UNSPEC_CCU_TO_INT)))] |
dd16a4bd | 2948 | "s390_match_ccmode (insn, CCSmode) && TARGET_64BIT" |
2949 | "#" | |
2950 | "&& reload_completed" | |
2951 | [(set (match_dup 0) (ashift:DI (match_dup 0) (const_int 34))) | |
2952 | (parallel | |
2953 | [(set (match_dup 2) (match_dup 3)) | |
2954 | (set (match_dup 0) (ashiftrt:DI (match_dup 0) (const_int 62)))])] | |
4673c1a0 | 2955 | { |
dd16a4bd | 2956 | rtx result = gen_rtx_ASHIFTRT (DImode, operands[0], GEN_INT (62)); |
2957 | operands[2] = SET_DEST (XVECEXP (PATTERN (curr_insn), 0, 0)); | |
2958 | operands[3] = gen_rtx_COMPARE (GET_MODE (operands[2]), result, const0_rtx); | |
2959 | }) | |
4673c1a0 | 2960 | |
8b4a4127 | 2961 | |
4673c1a0 | 2962 | ;; |
2963 | ;;- Conversion instructions. | |
2964 | ;; | |
2965 | ||
0349cc73 | 2966 | (define_insn "*sethighpartsi" |
51aa1e9c | 2967 | [(set (match_operand:SI 0 "register_operand" "=d,d") |
0349cc73 | 2968 | (unspec:SI [(match_operand:BLK 1 "s_operand" "Q,S") |
2969 | (match_operand 2 "const_int_operand" "n,n")] UNSPEC_ICM)) | |
1ca361fd | 2970 | (clobber (reg:CC CC_REGNUM))] |
8b4a4127 | 2971 | "" |
51aa1e9c | 2972 | "@ |
0349cc73 | 2973 | icm\t%0,%2,%S1 |
2974 | icmy\t%0,%2,%S1" | |
51aa1e9c | 2975 | [(set_attr "op_type" "RS,RSY")]) |
8b4a4127 | 2976 | |
0349cc73 | 2977 | (define_insn "*sethighpartdi_64" |
8b4a4127 | 2978 | [(set (match_operand:DI 0 "register_operand" "=d") |
0349cc73 | 2979 | (unspec:DI [(match_operand:BLK 1 "s_operand" "QS") |
2980 | (match_operand 2 "const_int_operand" "n")] UNSPEC_ICM)) | |
1ca361fd | 2981 | (clobber (reg:CC CC_REGNUM))] |
8b4a4127 | 2982 | "TARGET_64BIT" |
0349cc73 | 2983 | "icmh\t%0,%2,%S1" |
51aa1e9c | 2984 | [(set_attr "op_type" "RSY")]) |
8b4a4127 | 2985 | |
0349cc73 | 2986 | (define_insn "*sethighpartdi_31" |
51aa1e9c | 2987 | [(set (match_operand:DI 0 "register_operand" "=d,d") |
0349cc73 | 2988 | (unspec:DI [(match_operand:BLK 1 "s_operand" "Q,S") |
2989 | (match_operand 2 "const_int_operand" "n,n")] UNSPEC_ICM)) | |
1ca361fd | 2990 | (clobber (reg:CC CC_REGNUM))] |
8b4a4127 | 2991 | "!TARGET_64BIT" |
51aa1e9c | 2992 | "@ |
0349cc73 | 2993 | icm\t%0,%2,%S1 |
2994 | icmy\t%0,%2,%S1" | |
51aa1e9c | 2995 | [(set_attr "op_type" "RS,RSY")]) |
8b4a4127 | 2996 | |
0349cc73 | 2997 | (define_insn_and_split "*extzv<mode>" |
2998 | [(set (match_operand:GPR 0 "register_operand" "=d") | |
2999 | (zero_extract:GPR (match_operand:QI 1 "s_operand" "QS") | |
3000 | (match_operand 2 "const_int_operand" "n") | |
3001 | (const_int 0))) | |
1ca361fd | 3002 | (clobber (reg:CC CC_REGNUM))] |
0349cc73 | 3003 | "INTVAL (operands[2]) > 0 |
3004 | && INTVAL (operands[2]) <= GET_MODE_BITSIZE (SImode)" | |
147b6a2d | 3005 | "#" |
3006 | "&& reload_completed" | |
8b4a4127 | 3007 | [(parallel |
0349cc73 | 3008 | [(set (match_dup 0) (unspec:GPR [(match_dup 1) (match_dup 3)] UNSPEC_ICM)) |
1ca361fd | 3009 | (clobber (reg:CC CC_REGNUM))]) |
0349cc73 | 3010 | (set (match_dup 0) (lshiftrt:GPR (match_dup 0) (match_dup 2)))] |
8b4a4127 | 3011 | { |
0349cc73 | 3012 | int bitsize = INTVAL (operands[2]); |
3013 | int size = (bitsize - 1) / BITS_PER_UNIT + 1; /* round up */ | |
3014 | int mask = ((1ul << size) - 1) << (GET_MODE_SIZE (SImode) - size); | |
3015 | ||
3016 | operands[1] = adjust_address (operands[1], BLKmode, 0); | |
3017 | set_mem_size (operands[1], GEN_INT (size)); | |
3018 | operands[2] = GEN_INT (GET_MODE_BITSIZE (<MODE>mode) - bitsize); | |
3019 | operands[3] = GEN_INT (mask); | |
1822f0d6 | 3020 | }) |
8b4a4127 | 3021 | |
0349cc73 | 3022 | (define_insn_and_split "*extv<mode>" |
3023 | [(set (match_operand:GPR 0 "register_operand" "=d") | |
3024 | (sign_extract:GPR (match_operand:QI 1 "s_operand" "QS") | |
3025 | (match_operand 2 "const_int_operand" "n") | |
3026 | (const_int 0))) | |
1ca361fd | 3027 | (clobber (reg:CC CC_REGNUM))] |
0349cc73 | 3028 | "INTVAL (operands[2]) > 0 |
3029 | && INTVAL (operands[2]) <= GET_MODE_BITSIZE (SImode)" | |
147b6a2d | 3030 | "#" |
3031 | "&& reload_completed" | |
8b4a4127 | 3032 | [(parallel |
0349cc73 | 3033 | [(set (match_dup 0) (unspec:GPR [(match_dup 1) (match_dup 3)] UNSPEC_ICM)) |
1ca361fd | 3034 | (clobber (reg:CC CC_REGNUM))]) |
0349cc73 | 3035 | (parallel |
3036 | [(set (match_dup 0) (ashiftrt:GPR (match_dup 0) (match_dup 2))) | |
3037 | (clobber (reg:CC CC_REGNUM))])] | |
3038 | { | |
3039 | int bitsize = INTVAL (operands[2]); | |
3040 | int size = (bitsize - 1) / BITS_PER_UNIT + 1; /* round up */ | |
3041 | int mask = ((1ul << size) - 1) << (GET_MODE_SIZE (SImode) - size); | |
3042 | ||
3043 | operands[1] = adjust_address (operands[1], BLKmode, 0); | |
3044 | set_mem_size (operands[1], GEN_INT (size)); | |
3045 | operands[2] = GEN_INT (GET_MODE_BITSIZE (<MODE>mode) - bitsize); | |
3046 | operands[3] = GEN_INT (mask); | |
3047 | }) | |
3048 | ||
3049 | ; | |
3050 | ; insv instruction patterns | |
3051 | ; | |
3052 | ||
3053 | (define_expand "insv" | |
3054 | [(set (zero_extract (match_operand 0 "nonimmediate_operand" "") | |
3055 | (match_operand 1 "const_int_operand" "") | |
3056 | (match_operand 2 "const_int_operand" "")) | |
3057 | (match_operand 3 "general_operand" ""))] | |
3058 | "" | |
8b4a4127 | 3059 | { |
0349cc73 | 3060 | if (s390_expand_insv (operands[0], operands[1], operands[2], operands[3])) |
3061 | DONE; | |
3062 | FAIL; | |
1822f0d6 | 3063 | }) |
8b4a4127 | 3064 | |
e68d6a13 | 3065 | (define_insn "*insv<mode>_z10" |
3066 | [(set (zero_extract:GPR (match_operand:GPR 0 "nonimmediate_operand" "+d") | |
3067 | (match_operand 1 "const_int_operand" "I") | |
3068 | (match_operand 2 "const_int_operand" "I")) | |
3069 | (match_operand:GPR 3 "nonimmediate_operand" "d")) | |
3070 | (clobber (reg:CC CC_REGNUM))] | |
3071 | "TARGET_Z10 | |
3072 | && (INTVAL (operands[1]) + INTVAL (operands[2])) <= | |
3073 | GET_MODE_BITSIZE (<MODE>mode)" | |
3074 | { | |
3075 | int start = INTVAL (operands[2]); | |
3076 | int size = INTVAL (operands[1]); | |
3077 | int offset = 64 - GET_MODE_BITSIZE (<MODE>mode); | |
3078 | ||
3079 | operands[2] = GEN_INT (offset + start); /* start bit position */ | |
3080 | operands[1] = GEN_INT (offset + start + size - 1); /* end bit position */ | |
3081 | operands[4] = GEN_INT (GET_MODE_BITSIZE (<MODE>mode) - | |
3082 | start - size); /* left shift count */ | |
3083 | ||
3084 | return "risbg\t%0,%3,%b2,%b1,%b4"; | |
3085 | } | |
3086 | [(set_attr "op_type" "RIE")]) | |
3087 | ||
3088 | ; and op1 with a mask being 1 for the selected bits and 0 for the rest | |
3089 | ; and op3=op0 with a mask being 0 for the selected bits and 1 for the rest | |
3090 | (define_insn "*insv<mode>_z10_noshift" | |
3091 | [(set (match_operand:GPR 0 "nonimmediate_operand" "=d") | |
3092 | (ior:GPR (and:GPR (match_operand:GPR 1 "nonimmediate_operand" "d") | |
3093 | (match_operand 2 "const_int_operand" "n")) | |
3094 | (and:GPR (match_operand:GPR 3 "nonimmediate_operand" "0") | |
3095 | (match_operand 4 "const_int_operand" "n")))) | |
3096 | (clobber (reg:CC CC_REGNUM))] | |
3097 | "TARGET_Z10 | |
3098 | && s390_contiguous_bitmask_p (INTVAL (operands[2]), | |
3099 | GET_MODE_BITSIZE (<MODE>mode), NULL, NULL) | |
3100 | && INTVAL (operands[2]) == ~(INTVAL (operands[4]))" | |
3101 | ||
3102 | { | |
3103 | int start; | |
3104 | int size; | |
3105 | ||
3106 | s390_contiguous_bitmask_p (INTVAL (operands[2]), | |
3107 | GET_MODE_BITSIZE (<MODE>mode), &start, &size); | |
3108 | ||
3109 | operands[5] = GEN_INT (64 - start - size); /* start bit position */ | |
3110 | operands[6] = GEN_INT (64 - 1 - start); /* end bit position */ | |
3111 | operands[7] = const0_rtx; /* left shift count */ | |
3112 | ||
3113 | return "risbg\t%0,%1,%b5,%b6,%b7"; | |
3114 | } | |
3115 | [(set_attr "op_type" "RIE")]) | |
3116 | ||
3117 | ; and op1 with a mask being 1 for the selected bits and 0 for the rest | |
3118 | (define_insn "*insv<mode>_or_z10_noshift" | |
3119 | [(set (match_operand:GPR 0 "nonimmediate_operand" "=d") | |
3120 | (ior:GPR (and:GPR (match_operand:GPR 1 "nonimmediate_operand" "d") | |
3121 | (match_operand 2 "const_int_operand" "n")) | |
3122 | (match_operand:GPR 3 "nonimmediate_operand" "0"))) | |
3123 | (clobber (reg:CC CC_REGNUM))] | |
3124 | "TARGET_Z10 | |
3125 | && s390_contiguous_bitmask_p (INTVAL (operands[2]), | |
3126 | GET_MODE_BITSIZE (<MODE>mode), NULL, NULL)" | |
3127 | { | |
3128 | int start; | |
3129 | int size; | |
3130 | ||
3131 | s390_contiguous_bitmask_p (INTVAL (operands[2]), | |
3132 | GET_MODE_BITSIZE (<MODE>mode), &start, &size); | |
3133 | ||
3134 | operands[4] = GEN_INT (64 - start - size); /* start bit position */ | |
3135 | operands[5] = GEN_INT (64 - 1 - start); /* end bit position */ | |
3136 | operands[6] = const0_rtx; /* left shift count */ | |
3137 | ||
3138 | return "rosbg\t%0,%1,%b4,%b5,%b6"; | |
3139 | } | |
3140 | [(set_attr "op_type" "RIE")]) | |
3141 | ||
0349cc73 | 3142 | (define_insn "*insv<mode>_mem_reg" |
3143 | [(set (zero_extract:P (match_operand:QI 0 "memory_operand" "+Q,S") | |
3144 | (match_operand 1 "const_int_operand" "n,n") | |
3145 | (const_int 0)) | |
3146 | (match_operand:P 2 "register_operand" "d,d"))] | |
3147 | "INTVAL (operands[1]) > 0 | |
3148 | && INTVAL (operands[1]) <= GET_MODE_BITSIZE (SImode) | |
3149 | && INTVAL (operands[1]) % BITS_PER_UNIT == 0" | |
3150 | { | |
3151 | int size = INTVAL (operands[1]) / BITS_PER_UNIT; | |
3152 | ||
3153 | operands[1] = GEN_INT ((1ul << size) - 1); | |
3154 | return (which_alternative == 0) ? "stcm\t%2,%1,%S0" | |
3155 | : "stcmy\t%2,%1,%S0"; | |
3156 | } | |
3157 | [(set_attr "op_type" "RS,RSY")]) | |
3158 | ||
3159 | (define_insn "*insvdi_mem_reghigh" | |
3160 | [(set (zero_extract:DI (match_operand:QI 0 "memory_operand" "+QS") | |
3161 | (match_operand 1 "const_int_operand" "n") | |
3162 | (const_int 0)) | |
3163 | (lshiftrt:DI (match_operand:DI 2 "register_operand" "d") | |
3164 | (const_int 32)))] | |
3165 | "TARGET_64BIT | |
3166 | && INTVAL (operands[1]) > 0 | |
3167 | && INTVAL (operands[1]) <= GET_MODE_BITSIZE (SImode) | |
3168 | && INTVAL (operands[1]) % BITS_PER_UNIT == 0" | |
3169 | { | |
3170 | int size = INTVAL (operands[1]) / BITS_PER_UNIT; | |
3171 | ||
3172 | operands[1] = GEN_INT ((1ul << size) - 1); | |
3173 | return "stcmh\t%2,%1,%S0"; | |
3174 | } | |
3175 | [(set_attr "op_type" "RSY")]) | |
3176 | ||
3177 | (define_insn "*insv<mode>_reg_imm" | |
3178 | [(set (zero_extract:P (match_operand:P 0 "register_operand" "+d") | |
3179 | (const_int 16) | |
3180 | (match_operand 1 "const_int_operand" "n")) | |
d666e71f | 3181 | (match_operand:P 2 "const_int_operand" "n"))] |
0349cc73 | 3182 | "TARGET_ZARCH |
3183 | && INTVAL (operands[1]) >= 0 | |
3184 | && INTVAL (operands[1]) < BITS_PER_WORD | |
3185 | && INTVAL (operands[1]) % 16 == 0" | |
3186 | { | |
3187 | switch (BITS_PER_WORD - INTVAL (operands[1])) | |
3188 | { | |
3189 | case 64: return "iihh\t%0,%x2"; break; | |
3190 | case 48: return "iihl\t%0,%x2"; break; | |
3191 | case 32: return "iilh\t%0,%x2"; break; | |
3192 | case 16: return "iill\t%0,%x2"; break; | |
3193 | default: gcc_unreachable(); | |
3194 | } | |
3195 | } | |
3196 | [(set_attr "op_type" "RI")]) | |
3197 | ||
3198 | (define_insn "*insv<mode>_reg_extimm" | |
3199 | [(set (zero_extract:P (match_operand:P 0 "register_operand" "+d") | |
3200 | (const_int 32) | |
3201 | (match_operand 1 "const_int_operand" "n")) | |
d666e71f | 3202 | (match_operand:P 2 "const_int_operand" "n"))] |
0349cc73 | 3203 | "TARGET_EXTIMM |
3204 | && INTVAL (operands[1]) >= 0 | |
3205 | && INTVAL (operands[1]) < BITS_PER_WORD | |
3206 | && INTVAL (operands[1]) % 32 == 0" | |
3207 | { | |
3208 | switch (BITS_PER_WORD - INTVAL (operands[1])) | |
3209 | { | |
3210 | case 64: return "iihf\t%0,%o2"; break; | |
3211 | case 32: return "iilf\t%0,%o2"; break; | |
3212 | default: gcc_unreachable(); | |
3213 | } | |
3214 | } | |
3215 | [(set_attr "op_type" "RIL")]) | |
3216 | ||
4673c1a0 | 3217 | ; |
3218 | ; extendsidi2 instruction pattern(s). | |
3219 | ; | |
3220 | ||
8b4a4127 | 3221 | (define_expand "extendsidi2" |
3222 | [(set (match_operand:DI 0 "register_operand" "") | |
3223 | (sign_extend:DI (match_operand:SI 1 "nonimmediate_operand" "")))] | |
3224 | "" | |
8b4a4127 | 3225 | { |
3226 | if (!TARGET_64BIT) | |
3227 | { | |
18b42941 | 3228 | emit_clobber (operands[0]); |
9f4d041d | 3229 | emit_move_insn (gen_highpart (SImode, operands[0]), operands[1]); |
3230 | emit_move_insn (gen_lowpart (SImode, operands[0]), const0_rtx); | |
3231 | emit_insn (gen_ashrdi3 (operands[0], operands[0], GEN_INT (32))); | |
8b4a4127 | 3232 | DONE; |
3233 | } | |
163277cf | 3234 | }) |
8b4a4127 | 3235 | |
3236 | (define_insn "*extendsidi2" | |
e68d6a13 | 3237 | [(set (match_operand:DI 0 "register_operand" "=d,d,d") |
3238 | (sign_extend:DI (match_operand:SI 1 "nonimmediate_operand" "d,RT,b")))] | |
4673c1a0 | 3239 | "TARGET_64BIT" |
3240 | "@ | |
f24d7ff3 | 3241 | lgfr\t%0,%1 |
e68d6a13 | 3242 | lgf\t%0,%1 |
3243 | lgfrl\t%0,%1" | |
3244 | [(set_attr "op_type" "RRE,RXY,RIL") | |
3245 | (set_attr "type" "*,*,larl") | |
3246 | (set_attr "cpu_facility" "*,*,z10")]) | |
4673c1a0 | 3247 | |
4673c1a0 | 3248 | ; |
14f1ac69 | 3249 | ; extend(hi|qi)(si|di)2 instruction pattern(s). |
4673c1a0 | 3250 | ; |
3251 | ||
14f1ac69 | 3252 | (define_expand "extend<HQI:mode><DSI:mode>2" |
3253 | [(set (match_operand:DSI 0 "register_operand" "") | |
3254 | (sign_extend:DSI (match_operand:HQI 1 "nonimmediate_operand" "")))] | |
8b4a4127 | 3255 | "" |
8b4a4127 | 3256 | { |
14f1ac69 | 3257 | if (<DSI:MODE>mode == DImode && !TARGET_64BIT) |
8b4a4127 | 3258 | { |
3259 | rtx tmp = gen_reg_rtx (SImode); | |
14f1ac69 | 3260 | emit_insn (gen_extend<HQI:mode>si2 (tmp, operands[1])); |
8b4a4127 | 3261 | emit_insn (gen_extendsidi2 (operands[0], tmp)); |
3262 | DONE; | |
3263 | } | |
163277cf | 3264 | else if (!TARGET_EXTIMM) |
8b4a4127 | 3265 | { |
14f1ac69 | 3266 | rtx bitcount = GEN_INT (GET_MODE_BITSIZE (<DSI:MODE>mode) - |
3267 | GET_MODE_BITSIZE (<HQI:MODE>mode)); | |
3268 | ||
3269 | operands[1] = gen_lowpart (<DSI:MODE>mode, operands[1]); | |
3270 | emit_insn (gen_ashl<DSI:mode>3 (operands[0], operands[1], bitcount)); | |
3271 | emit_insn (gen_ashr<DSI:mode>3 (operands[0], operands[0], bitcount)); | |
8b4a4127 | 3272 | DONE; |
3273 | } | |
163277cf | 3274 | }) |
3275 | ||
14f1ac69 | 3276 | ; |
3277 | ; extendhidi2 instruction pattern(s). | |
3278 | ; | |
3279 | ||
163277cf | 3280 | (define_insn "*extendhidi2_extimm" |
e68d6a13 | 3281 | [(set (match_operand:DI 0 "register_operand" "=d,d,d") |
3282 | (sign_extend:DI (match_operand:HI 1 "general_operand" "d,RT,b")))] | |
163277cf | 3283 | "TARGET_64BIT && TARGET_EXTIMM" |
3284 | "@ | |
3285 | lghr\t%0,%1 | |
e68d6a13 | 3286 | lgh\t%0,%1 |
3287 | lghrl\t%0,%1" | |
3288 | [(set_attr "op_type" "RRE,RXY,RIL") | |
3289 | (set_attr "type" "*,*,larl") | |
3290 | (set_attr "cpu_facility" "extimm,extimm,z10")]) | |
8b4a4127 | 3291 | |
3292 | (define_insn "*extendhidi2" | |
4673c1a0 | 3293 | [(set (match_operand:DI 0 "register_operand" "=d") |
8fe52251 | 3294 | (sign_extend:DI (match_operand:HI 1 "memory_operand" "RT")))] |
4673c1a0 | 3295 | "TARGET_64BIT" |
f24d7ff3 | 3296 | "lgh\t%0,%1" |
51aa1e9c | 3297 | [(set_attr "op_type" "RXY")]) |
4673c1a0 | 3298 | |
4673c1a0 | 3299 | ; |
14f1ac69 | 3300 | ; extendhisi2 instruction pattern(s). |
4673c1a0 | 3301 | ; |
3302 | ||
163277cf | 3303 | (define_insn "*extendhisi2_extimm" |
e68d6a13 | 3304 | [(set (match_operand:SI 0 "register_operand" "=d,d,d,d") |
3305 | (sign_extend:SI (match_operand:HI 1 "nonimmediate_operand" " d,R,T,b")))] | |
163277cf | 3306 | "TARGET_EXTIMM" |
3307 | "@ | |
3308 | lhr\t%0,%1 | |
3309 | lh\t%0,%1 | |
e68d6a13 | 3310 | lhy\t%0,%1 |
3311 | lhrl\t%0,%1" | |
3312 | [(set_attr "op_type" "RRE,RX,RXY,RIL") | |
3313 | (set_attr "type" "*,*,*,larl") | |
3314 | (set_attr "cpu_facility" "extimm,extimm,extimm,z10")]) | |
4673c1a0 | 3315 | |
8b4a4127 | 3316 | (define_insn "*extendhisi2" |
51aa1e9c | 3317 | [(set (match_operand:SI 0 "register_operand" "=d,d") |
3318 | (sign_extend:SI (match_operand:HI 1 "memory_operand" "R,T")))] | |
163277cf | 3319 | "!TARGET_EXTIMM" |
51aa1e9c | 3320 | "@ |
f24d7ff3 | 3321 | lh\t%0,%1 |
3322 | lhy\t%0,%1" | |
51aa1e9c | 3323 | [(set_attr "op_type" "RX,RXY")]) |
4673c1a0 | 3324 | |
14f1ac69 | 3325 | ; |
3326 | ; extendqi(si|di)2 instruction pattern(s). | |
3327 | ; | |
3328 | ||
87bc9927 | 3329 | ; lbr, lgbr, lb, lgb |
14f1ac69 | 3330 | (define_insn "*extendqi<mode>2_extimm" |
3331 | [(set (match_operand:GPR 0 "register_operand" "=d,d") | |
8fe52251 | 3332 | (sign_extend:GPR (match_operand:QI 1 "nonimmediate_operand" "d,RT")))] |
163277cf | 3333 | "TARGET_EXTIMM" |
3334 | "@ | |
14f1ac69 | 3335 | l<g>br\t%0,%1 |
3336 | l<g>b\t%0,%1" | |
163277cf | 3337 | [(set_attr "op_type" "RRE,RXY")]) |
3338 | ||
87bc9927 | 3339 | ; lb, lgb |
14f1ac69 | 3340 | (define_insn "*extendqi<mode>2" |
3341 | [(set (match_operand:GPR 0 "register_operand" "=d") | |
8fe52251 | 3342 | (sign_extend:GPR (match_operand:QI 1 "memory_operand" "RT")))] |
14f1ac69 | 3343 | "!TARGET_EXTIMM && TARGET_LONG_DISPLACEMENT" |
3344 | "l<g>b\t%0,%1" | |
51aa1e9c | 3345 | [(set_attr "op_type" "RXY")]) |
3346 | ||
14f1ac69 | 3347 | (define_insn_and_split "*extendqi<mode>2_short_displ" |
3348 | [(set (match_operand:GPR 0 "register_operand" "=d") | |
3349 | (sign_extend:GPR (match_operand:QI 1 "s_operand" "Q"))) | |
1ca361fd | 3350 | (clobber (reg:CC CC_REGNUM))] |
14f1ac69 | 3351 | "!TARGET_EXTIMM && !TARGET_LONG_DISPLACEMENT" |
56b9b457 | 3352 | "#" |
3353 | "&& reload_completed" | |
8b4a4127 | 3354 | [(parallel |
14f1ac69 | 3355 | [(set (match_dup 0) (unspec:GPR [(match_dup 1) (const_int 8)] UNSPEC_ICM)) |
1ca361fd | 3356 | (clobber (reg:CC CC_REGNUM))]) |
8b4a4127 | 3357 | (parallel |
14f1ac69 | 3358 | [(set (match_dup 0) (ashiftrt:GPR (match_dup 0) (match_dup 2))) |
1ca361fd | 3359 | (clobber (reg:CC CC_REGNUM))])] |
0349cc73 | 3360 | { |
3361 | operands[1] = adjust_address (operands[1], BLKmode, 0); | |
3362 | set_mem_size (operands[1], GEN_INT (GET_MODE_SIZE (QImode))); | |
14f1ac69 | 3363 | operands[2] = GEN_INT (GET_MODE_BITSIZE (<MODE>mode) |
3364 | - GET_MODE_BITSIZE (QImode)); | |
0349cc73 | 3365 | }) |
4673c1a0 | 3366 | |
4673c1a0 | 3367 | ; |
3368 | ; zero_extendsidi2 instruction pattern(s). | |
3369 | ; | |
3370 | ||
8b4a4127 | 3371 | (define_expand "zero_extendsidi2" |
3372 | [(set (match_operand:DI 0 "register_operand" "") | |
3373 | (zero_extend:DI (match_operand:SI 1 "nonimmediate_operand" "")))] | |
3374 | "" | |
8b4a4127 | 3375 | { |
3376 | if (!TARGET_64BIT) | |
3377 | { | |
18b42941 | 3378 | emit_clobber (operands[0]); |
9f4d041d | 3379 | emit_move_insn (gen_lowpart (SImode, operands[0]), operands[1]); |
3380 | emit_move_insn (gen_highpart (SImode, operands[0]), const0_rtx); | |
8b4a4127 | 3381 | DONE; |
3382 | } | |
163277cf | 3383 | }) |
8b4a4127 | 3384 | |
3385 | (define_insn "*zero_extendsidi2" | |
e68d6a13 | 3386 | [(set (match_operand:DI 0 "register_operand" "=d,d,d") |
3387 | (zero_extend:DI (match_operand:SI 1 "nonimmediate_operand" "d,RT,b")))] | |
4673c1a0 | 3388 | "TARGET_64BIT" |
3389 | "@ | |
f24d7ff3 | 3390 | llgfr\t%0,%1 |
e68d6a13 | 3391 | llgf\t%0,%1 |
3392 | llgfrl\t%0,%1" | |
3393 | [(set_attr "op_type" "RRE,RXY,RIL") | |
3394 | (set_attr "type" "*,*,larl") | |
3395 | (set_attr "cpu_facility" "*,*,z10")]) | |
4673c1a0 | 3396 | |
614e283a | 3397 | ; |
3398 | ; LLGT-type instructions (zero-extend from 31 bit to 64 bit). | |
3399 | ; | |
3400 | ||
aa3b6669 | 3401 | (define_insn "*llgt_sidi" |
3402 | [(set (match_operand:DI 0 "register_operand" "=d") | |
8fe52251 | 3403 | (and:DI (subreg:DI (match_operand:SI 1 "memory_operand" "RT") 0) |
aa3b6669 | 3404 | (const_int 2147483647)))] |
3405 | "TARGET_64BIT" | |
3406 | "llgt\t%0,%1" | |
3407 | [(set_attr "op_type" "RXE")]) | |
3408 | ||
3409 | (define_insn_and_split "*llgt_sidi_split" | |
3410 | [(set (match_operand:DI 0 "register_operand" "=d") | |
8fe52251 | 3411 | (and:DI (subreg:DI (match_operand:SI 1 "memory_operand" "RT") 0) |
aa3b6669 | 3412 | (const_int 2147483647))) |
1ca361fd | 3413 | (clobber (reg:CC CC_REGNUM))] |
aa3b6669 | 3414 | "TARGET_64BIT" |
3415 | "#" | |
3416 | "&& reload_completed" | |
3417 | [(set (match_dup 0) | |
3418 | (and:DI (subreg:DI (match_dup 1) 0) | |
3419 | (const_int 2147483647)))] | |
3420 | "") | |
3421 | ||
614e283a | 3422 | (define_insn "*llgt_sisi" |
3423 | [(set (match_operand:SI 0 "register_operand" "=d,d") | |
8fe52251 | 3424 | (and:SI (match_operand:SI 1 "nonimmediate_operand" "d,RT") |
614e283a | 3425 | (const_int 2147483647)))] |
0451e449 | 3426 | "TARGET_ZARCH" |
614e283a | 3427 | "@ |
3428 | llgtr\t%0,%1 | |
3429 | llgt\t%0,%1" | |
3430 | [(set_attr "op_type" "RRE,RXE")]) | |
3431 | ||
614e283a | 3432 | (define_insn "*llgt_didi" |
3433 | [(set (match_operand:DI 0 "register_operand" "=d,d") | |
3434 | (and:DI (match_operand:DI 1 "nonimmediate_operand" "d,o") | |
3435 | (const_int 2147483647)))] | |
3436 | "TARGET_64BIT" | |
3437 | "@ | |
3438 | llgtr\t%0,%1 | |
3439 | llgt\t%0,%N1" | |
3440 | [(set_attr "op_type" "RRE,RXE")]) | |
3441 | ||
64a1078f | 3442 | (define_split |
95223bca | 3443 | [(set (match_operand:GPR 0 "register_operand" "") |
3444 | (and:GPR (match_operand:GPR 1 "nonimmediate_operand" "") | |
3445 | (const_int 2147483647))) | |
1ca361fd | 3446 | (clobber (reg:CC CC_REGNUM))] |
0451e449 | 3447 | "TARGET_ZARCH && reload_completed" |
614e283a | 3448 | [(set (match_dup 0) |
95223bca | 3449 | (and:GPR (match_dup 1) |
3450 | (const_int 2147483647)))] | |
614e283a | 3451 | "") |
3452 | ||
4673c1a0 | 3453 | ; |
14f1ac69 | 3454 | ; zero_extend(hi|qi)(si|di)2 instruction pattern(s). |
4673c1a0 | 3455 | ; |
3456 | ||
14f1ac69 | 3457 | (define_expand "zero_extend<mode>di2" |
3458 | [(set (match_operand:DI 0 "register_operand" "") | |
3459 | (zero_extend:DI (match_operand:HQI 1 "nonimmediate_operand" "")))] | |
3460 | "" | |
3461 | { | |
3462 | if (!TARGET_64BIT) | |
3463 | { | |
3464 | rtx tmp = gen_reg_rtx (SImode); | |
3465 | emit_insn (gen_zero_extend<mode>si2 (tmp, operands[1])); | |
3466 | emit_insn (gen_zero_extendsidi2 (operands[0], tmp)); | |
3467 | DONE; | |
3468 | } | |
3469 | else if (!TARGET_EXTIMM) | |
3470 | { | |
3471 | rtx bitcount = GEN_INT (GET_MODE_BITSIZE(DImode) - | |
3472 | GET_MODE_BITSIZE(<MODE>mode)); | |
3473 | operands[1] = gen_lowpart (DImode, operands[1]); | |
3474 | emit_insn (gen_ashldi3 (operands[0], operands[1], bitcount)); | |
3475 | emit_insn (gen_lshrdi3 (operands[0], operands[0], bitcount)); | |
3476 | DONE; | |
3477 | } | |
3478 | }) | |
3479 | ||
95223bca | 3480 | (define_expand "zero_extend<mode>si2" |
8b4a4127 | 3481 | [(set (match_operand:SI 0 "register_operand" "") |
163277cf | 3482 | (zero_extend:SI (match_operand:HQI 1 "nonimmediate_operand" "")))] |
4673c1a0 | 3483 | "" |
8b4a4127 | 3484 | { |
163277cf | 3485 | if (!TARGET_EXTIMM) |
3486 | { | |
3487 | operands[1] = gen_lowpart (SImode, operands[1]); | |
3488 | emit_insn (gen_andsi3 (operands[0], operands[1], | |
3489 | GEN_INT ((1 << GET_MODE_BITSIZE(<MODE>mode)) - 1))); | |
3490 | DONE; | |
14f1ac69 | 3491 | } |
163277cf | 3492 | }) |
3493 | ||
e68d6a13 | 3494 | ; llhrl, llghrl |
3495 | (define_insn "*zero_extendhi<mode>2_z10" | |
3496 | [(set (match_operand:GPR 0 "register_operand" "=d,d,d") | |
3497 | (zero_extend:GPR (match_operand:HI 1 "nonimmediate_operand" "d,RT,b")))] | |
3498 | "TARGET_Z10" | |
3499 | "@ | |
3500 | ll<g>hr\t%0,%1 | |
3501 | ll<g>h\t%0,%1 | |
3502 | ll<g>hrl\t%0,%1" | |
3503 | [(set_attr "op_type" "RXY,RRE,RIL") | |
3504 | (set_attr "type" "*,*,larl") | |
3505 | (set_attr "cpu_facility" "*,*,z10")]) | |
3506 | ||
87bc9927 | 3507 | ; llhr, llcr, llghr, llgcr, llh, llc, llgh, llgc |
14f1ac69 | 3508 | (define_insn "*zero_extend<HQI:mode><GPR:mode>2_extimm" |
3509 | [(set (match_operand:GPR 0 "register_operand" "=d,d") | |
8fe52251 | 3510 | (zero_extend:GPR (match_operand:HQI 1 "nonimmediate_operand" "d,RT")))] |
163277cf | 3511 | "TARGET_EXTIMM" |
3512 | "@ | |
14f1ac69 | 3513 | ll<g><hc>r\t%0,%1 |
3514 | ll<g><hc>\t%0,%1" | |
163277cf | 3515 | [(set_attr "op_type" "RRE,RXY")]) |
4673c1a0 | 3516 | |
87bc9927 | 3517 | ; llgh, llgc |
14f1ac69 | 3518 | (define_insn "*zero_extend<HQI:mode><GPR:mode>2" |
3519 | [(set (match_operand:GPR 0 "register_operand" "=d") | |
8fe52251 | 3520 | (zero_extend:GPR (match_operand:HQI 1 "memory_operand" "RT")))] |
163277cf | 3521 | "TARGET_ZARCH && !TARGET_EXTIMM" |
95223bca | 3522 | "llg<hc>\t%0,%1" |
51aa1e9c | 3523 | [(set_attr "op_type" "RXY")]) |
147b6a2d | 3524 | |
3525 | (define_insn_and_split "*zero_extendhisi2_31" | |
3526 | [(set (match_operand:SI 0 "register_operand" "=&d") | |
77a651b8 | 3527 | (zero_extend:SI (match_operand:HI 1 "s_operand" "QS"))) |
1ca361fd | 3528 | (clobber (reg:CC CC_REGNUM))] |
4e70b35e | 3529 | "!TARGET_ZARCH" |
147b6a2d | 3530 | "#" |
3531 | "&& reload_completed" | |
3532 | [(set (match_dup 0) (const_int 0)) | |
3533 | (parallel | |
3534 | [(set (strict_low_part (match_dup 2)) (match_dup 1)) | |
1ca361fd | 3535 | (clobber (reg:CC CC_REGNUM))])] |
1822f0d6 | 3536 | "operands[2] = gen_lowpart (HImode, operands[0]);") |
f81e845f | 3537 | |
147b6a2d | 3538 | (define_insn_and_split "*zero_extendqisi2_31" |
3539 | [(set (match_operand:SI 0 "register_operand" "=&d") | |
8fe52251 | 3540 | (zero_extend:SI (match_operand:QI 1 "memory_operand" "RT")))] |
dafc8d45 | 3541 | "!TARGET_ZARCH" |
147b6a2d | 3542 | "#" |
3543 | "&& reload_completed" | |
3544 | [(set (match_dup 0) (const_int 0)) | |
3545 | (set (strict_low_part (match_dup 2)) (match_dup 1))] | |
1822f0d6 | 3546 | "operands[2] = gen_lowpart (QImode, operands[0]);") |
f81e845f | 3547 | |
4673c1a0 | 3548 | ; |
3549 | ; zero_extendqihi2 instruction pattern(s). | |
3550 | ; | |
3551 | ||
4673c1a0 | 3552 | (define_expand "zero_extendqihi2" |
3553 | [(set (match_operand:HI 0 "register_operand" "") | |
8b4a4127 | 3554 | (zero_extend:HI (match_operand:QI 1 "register_operand" "")))] |
163277cf | 3555 | "TARGET_ZARCH && !TARGET_EXTIMM" |
4673c1a0 | 3556 | { |
8b4a4127 | 3557 | operands[1] = gen_lowpart (HImode, operands[1]); |
3558 | emit_insn (gen_andhi3 (operands[0], operands[1], GEN_INT (0xff))); | |
3559 | DONE; | |
163277cf | 3560 | }) |
4673c1a0 | 3561 | |
8b4a4127 | 3562 | (define_insn "*zero_extendqihi2_64" |
4673c1a0 | 3563 | [(set (match_operand:HI 0 "register_operand" "=d") |
8fe52251 | 3564 | (zero_extend:HI (match_operand:QI 1 "memory_operand" "RT")))] |
163277cf | 3565 | "TARGET_ZARCH && !TARGET_EXTIMM" |
f24d7ff3 | 3566 | "llgc\t%0,%1" |
51aa1e9c | 3567 | [(set_attr "op_type" "RXY")]) |
4673c1a0 | 3568 | |
147b6a2d | 3569 | (define_insn_and_split "*zero_extendqihi2_31" |
3570 | [(set (match_operand:HI 0 "register_operand" "=&d") | |
8fe52251 | 3571 | (zero_extend:HI (match_operand:QI 1 "memory_operand" "RT")))] |
dafc8d45 | 3572 | "!TARGET_ZARCH" |
147b6a2d | 3573 | "#" |
3574 | "&& reload_completed" | |
3575 | [(set (match_dup 0) (const_int 0)) | |
3576 | (set (strict_low_part (match_dup 2)) (match_dup 1))] | |
1822f0d6 | 3577 | "operands[2] = gen_lowpart (QImode, operands[0]);") |
147b6a2d | 3578 | |
1f8e70bc | 3579 | ; |
3580 | ; fixuns_trunc(dd|td)di2 instruction pattern(s). | |
3581 | ; | |
3582 | ||
3583 | (define_expand "fixuns_truncdddi2" | |
3584 | [(parallel | |
3585 | [(set (match_operand:DI 0 "register_operand" "") | |
3586 | (unsigned_fix:DI (match_operand:DD 1 "register_operand" ""))) | |
3587 | (clobber (match_scratch:TD 2 "=f"))])] | |
3588 | ||
3589 | "TARGET_HARD_FLOAT && TARGET_HARD_DFP" | |
3590 | { | |
3591 | rtx label1 = gen_label_rtx (); | |
3592 | rtx label2 = gen_label_rtx (); | |
3593 | rtx temp = gen_reg_rtx (TDmode); | |
3594 | REAL_VALUE_TYPE cmp, sub; | |
3595 | ||
3596 | decimal_real_from_string (&cmp, "9223372036854775808.0"); /* 2^63 */ | |
3597 | decimal_real_from_string (&sub, "18446744073709551616.0"); /* 2^64 */ | |
3598 | ||
3599 | /* 2^63 can't be represented as 64bit DFP number with full precision. The | |
3600 | solution is doing the check and the subtraction in TD mode and using a | |
3601 | TD -> DI convert afterwards. */ | |
3602 | emit_insn (gen_extendddtd2 (temp, operands[1])); | |
3603 | temp = force_reg (TDmode, temp); | |
3604 | emit_insn (gen_cmptd (temp, | |
3605 | CONST_DOUBLE_FROM_REAL_VALUE (cmp, TDmode))); | |
3606 | emit_jump_insn (gen_blt (label1)); | |
3607 | emit_insn (gen_subtd3 (temp, temp, | |
3608 | CONST_DOUBLE_FROM_REAL_VALUE (sub, TDmode))); | |
37e3ac7e | 3609 | emit_insn (gen_fix_trunctddi2_dfp (operands[0], temp, GEN_INT (11))); |
1f8e70bc | 3610 | emit_jump (label2); |
3611 | ||
3612 | emit_label (label1); | |
37e3ac7e | 3613 | emit_insn (gen_fix_truncdddi2_dfp (operands[0], operands[1], GEN_INT (9))); |
1f8e70bc | 3614 | emit_label (label2); |
3615 | DONE; | |
3616 | }) | |
3617 | ||
3618 | (define_expand "fixuns_trunctddi2" | |
3619 | [(set (match_operand:DI 0 "register_operand" "") | |
3620 | (unsigned_fix:DI (match_operand:TD 1 "register_operand" "")))] | |
3621 | "TARGET_HARD_FLOAT && TARGET_HARD_DFP" | |
3622 | { | |
3623 | rtx label1 = gen_label_rtx (); | |
3624 | rtx label2 = gen_label_rtx (); | |
3625 | rtx temp = gen_reg_rtx (TDmode); | |
3626 | REAL_VALUE_TYPE cmp, sub; | |
3627 | ||
3628 | operands[1] = force_reg (TDmode, operands[1]); | |
3629 | decimal_real_from_string (&cmp, "9223372036854775808.0"); /* 2^63 */ | |
3630 | decimal_real_from_string (&sub, "18446744073709551616.0"); /* 2^64 */ | |
3631 | ||
3632 | emit_insn (gen_cmptd (operands[1], | |
3633 | CONST_DOUBLE_FROM_REAL_VALUE (cmp, TDmode))); | |
3634 | emit_jump_insn (gen_blt (label1)); | |
3635 | emit_insn (gen_subtd3 (temp, operands[1], | |
3636 | CONST_DOUBLE_FROM_REAL_VALUE (sub, TDmode))); | |
37e3ac7e | 3637 | emit_insn (gen_fix_trunctddi2_dfp (operands[0], temp, GEN_INT (11))); |
1f8e70bc | 3638 | emit_jump (label2); |
3639 | ||
3640 | emit_label (label1); | |
37e3ac7e | 3641 | emit_insn (gen_fix_trunctddi2_dfp (operands[0], operands[1], GEN_INT (9))); |
1f8e70bc | 3642 | emit_label (label2); |
3643 | DONE; | |
3644 | }) | |
147b6a2d | 3645 | |
4673c1a0 | 3646 | ; |
1f8e70bc | 3647 | ; fixuns_trunc(sf|df)(si|di)2 and fix_trunc(sf|df)(si|di)2 |
3648 | ; instruction pattern(s). | |
4673c1a0 | 3649 | ; |
3650 | ||
708607d5 | 3651 | (define_expand "fixuns_trunc<BFP:mode><GPR:mode>2" |
8e6e481d | 3652 | [(set (match_operand:GPR 0 "register_operand" "") |
708607d5 | 3653 | (unsigned_fix:GPR (match_operand:BFP 1 "register_operand" "")))] |
095798e3 | 3654 | "TARGET_HARD_FLOAT" |
4673c1a0 | 3655 | { |
3656 | rtx label1 = gen_label_rtx (); | |
3657 | rtx label2 = gen_label_rtx (); | |
708607d5 | 3658 | rtx temp = gen_reg_rtx (<BFP:MODE>mode); |
8e6e481d | 3659 | REAL_VALUE_TYPE cmp, sub; |
3660 | ||
708607d5 | 3661 | operands[1] = force_reg (<BFP:MODE>mode, operands[1]); |
5497187b | 3662 | real_2expN (&cmp, GET_MODE_BITSIZE(<GPR:MODE>mode) - 1, <BFP:MODE>mode); |
3663 | real_2expN (&sub, GET_MODE_BITSIZE(<GPR:MODE>mode), <BFP:MODE>mode); | |
8e6e481d | 3664 | |
708607d5 | 3665 | emit_insn (gen_cmp<BFP:mode> (operands[1], |
3666 | CONST_DOUBLE_FROM_REAL_VALUE (cmp, <BFP:MODE>mode))); | |
4673c1a0 | 3667 | emit_jump_insn (gen_blt (label1)); |
708607d5 | 3668 | emit_insn (gen_sub<BFP:mode>3 (temp, operands[1], |
3669 | CONST_DOUBLE_FROM_REAL_VALUE (sub, <BFP:MODE>mode))); | |
095798e3 | 3670 | emit_insn (gen_fix_trunc<BFP:mode><GPR:mode>2_bfp (operands[0], temp, |
37e3ac7e | 3671 | GEN_INT (7))); |
0c0a8ea5 | 3672 | emit_jump (label2); |
4673c1a0 | 3673 | |
3674 | emit_label (label1); | |
095798e3 | 3675 | emit_insn (gen_fix_trunc<BFP:mode><GPR:mode>2_bfp (operands[0], |
37e3ac7e | 3676 | operands[1], GEN_INT (5))); |
4673c1a0 | 3677 | emit_label (label2); |
3678 | DONE; | |
83e641bd | 3679 | }) |
4673c1a0 | 3680 | |
e7340e24 | 3681 | (define_expand "fix_trunc<DSF:mode><GPR:mode>2" |
3682 | [(set (match_operand:GPR 0 "register_operand" "") | |
3683 | (fix:GPR (match_operand:DSF 1 "register_operand" "")))] | |
3684 | "TARGET_HARD_FLOAT" | |
4673c1a0 | 3685 | { |
e7340e24 | 3686 | emit_insn (gen_fix_trunc<DSF:mode><GPR:mode>2_bfp (operands[0], operands[1], |
3687 | GEN_INT (5))); | |
4673c1a0 | 3688 | DONE; |
83e641bd | 3689 | }) |
4673c1a0 | 3690 | |
87bc9927 | 3691 | ; cgxbr, cgdbr, cgebr, cfxbr, cfdbr, cfebr |
095798e3 | 3692 | (define_insn "fix_trunc<BFP:mode><GPR:mode>2_bfp" |
8e6e481d | 3693 | [(set (match_operand:GPR 0 "register_operand" "=d") |
708607d5 | 3694 | (fix:GPR (match_operand:BFP 1 "register_operand" "f"))) |
8e6e481d | 3695 | (unspec:GPR [(match_operand:GPR 2 "immediate_operand" "K")] UNSPEC_ROUND) |
1ca361fd | 3696 | (clobber (reg:CC CC_REGNUM))] |
095798e3 | 3697 | "TARGET_HARD_FLOAT" |
708607d5 | 3698 | "c<GPR:gf><BFP:xde>br\t%0,%h2,%1" |
4673c1a0 | 3699 | [(set_attr "op_type" "RRE") |
71343e6b | 3700 | (set_attr "type" "ftoi")]) |
4673c1a0 | 3701 | |
1f8e70bc | 3702 | |
3703 | ; | |
3704 | ; fix_trunc(td|dd)di2 instruction pattern(s). | |
3705 | ; | |
3706 | ||
37e3ac7e | 3707 | (define_expand "fix_trunc<mode>di2" |
3708 | [(set (match_operand:DI 0 "register_operand" "") | |
3709 | (fix:DI (match_operand:DFP 1 "nonimmediate_operand" "")))] | |
3710 | "TARGET_64BIT && TARGET_HARD_FLOAT && TARGET_HARD_DFP" | |
3711 | { | |
3712 | operands[1] = force_reg (<MODE>mode, operands[1]); | |
3713 | emit_insn (gen_fix_trunc<mode>di2_dfp (operands[0], operands[1], | |
3714 | GEN_INT (9))); | |
3715 | DONE; | |
3716 | }) | |
3717 | ||
1f8e70bc | 3718 | ; cgxtr, cgdtr |
37e3ac7e | 3719 | (define_insn "fix_trunc<DFP:mode>di2_dfp" |
1f8e70bc | 3720 | [(set (match_operand:DI 0 "register_operand" "=d") |
3721 | (fix:DI (match_operand:DFP 1 "register_operand" "f"))) | |
3722 | (unspec:DI [(match_operand:DI 2 "immediate_operand" "K")] UNSPEC_ROUND) | |
3723 | (clobber (reg:CC CC_REGNUM))] | |
3724 | "TARGET_64BIT && TARGET_HARD_FLOAT && TARGET_HARD_DFP" | |
3725 | "cg<DFP:xde>tr\t%0,%h2,%1" | |
3726 | [(set_attr "op_type" "RRF") | |
3727 | (set_attr "type" "ftoi")]) | |
3728 | ||
3729 | ||
429f9fdb | 3730 | ; |
3731 | ; fix_trunctf(si|di)2 instruction pattern(s). | |
3732 | ; | |
3733 | ||
3734 | (define_expand "fix_trunctf<mode>2" | |
3735 | [(parallel [(set (match_operand:GPR 0 "register_operand" "") | |
3736 | (fix:GPR (match_operand:TF 1 "register_operand" ""))) | |
3737 | (unspec:GPR [(const_int 5)] UNSPEC_ROUND) | |
3738 | (clobber (reg:CC CC_REGNUM))])] | |
4673c1a0 | 3739 | "TARGET_HARD_FLOAT" |
095798e3 | 3740 | "") |
4673c1a0 | 3741 | |
4673c1a0 | 3742 | |
4673c1a0 | 3743 | ; |
095798e3 | 3744 | ; float(si|di)(tf|df|sf|td|dd)2 instruction pattern(s). |
4673c1a0 | 3745 | ; |
3746 | ||
1f8e70bc | 3747 | ; cxgbr, cdgbr, cegbr, cxgtr, cdgtr |
8052065f | 3748 | (define_insn "floatdi<mode>2" |
1f8e70bc | 3749 | [(set (match_operand:FP 0 "register_operand" "=f") |
3750 | (float:FP (match_operand:DI 1 "register_operand" "d")))] | |
095798e3 | 3751 | "TARGET_64BIT && TARGET_HARD_FLOAT" |
1f8e70bc | 3752 | "c<xde>g<bt>r\t%0,%1" |
4673c1a0 | 3753 | [(set_attr "op_type" "RRE") |
71343e6b | 3754 | (set_attr "type" "itof" )]) |
4673c1a0 | 3755 | |
87bc9927 | 3756 | ; cxfbr, cdfbr, cefbr |
095798e3 | 3757 | (define_insn "floatsi<mode>2" |
708607d5 | 3758 | [(set (match_operand:BFP 0 "register_operand" "=f") |
3759 | (float:BFP (match_operand:SI 1 "register_operand" "d")))] | |
095798e3 | 3760 | "TARGET_HARD_FLOAT" |
429f9fdb | 3761 | "c<xde>fbr\t%0,%1" |
3762 | [(set_attr "op_type" "RRE") | |
3763 | (set_attr "type" "itof" )]) | |
3764 | ||
3765 | ||
4673c1a0 | 3766 | ; |
3767 | ; truncdfsf2 instruction pattern(s). | |
3768 | ; | |
3769 | ||
095798e3 | 3770 | (define_insn "truncdfsf2" |
4673c1a0 | 3771 | [(set (match_operand:SF 0 "register_operand" "=f") |
f9a81c6e | 3772 | (float_truncate:SF (match_operand:DF 1 "register_operand" "f")))] |
095798e3 | 3773 | "TARGET_HARD_FLOAT" |
f24d7ff3 | 3774 | "ledbr\t%0,%1" |
429f9fdb | 3775 | [(set_attr "op_type" "RRE") |
3776 | (set_attr "type" "ftruncdf")]) | |
4673c1a0 | 3777 | |
429f9fdb | 3778 | ; |
095798e3 | 3779 | ; trunctf(df|sf)2 instruction pattern(s). |
429f9fdb | 3780 | ; |
3781 | ||
095798e3 | 3782 | ; ldxbr, lexbr |
3783 | (define_insn "trunctf<mode>2" | |
3784 | [(set (match_operand:DSF 0 "register_operand" "=f") | |
3785 | (float_truncate:DSF (match_operand:TF 1 "register_operand" "f"))) | |
429f9fdb | 3786 | (clobber (match_scratch:TF 2 "=f"))] |
095798e3 | 3787 | "TARGET_HARD_FLOAT" |
3788 | "l<xde>xbr\t%2,%1\;l<xde>r\t%0,%2" | |
429f9fdb | 3789 | [(set_attr "length" "6") |
3790 | (set_attr "type" "ftrunctf")]) | |
3791 | ||
1f8e70bc | 3792 | ; |
3793 | ; trunctddd2 and truncddsd2 instruction pattern(s). | |
3794 | ; | |
3795 | ||
3796 | (define_insn "trunctddd2" | |
3797 | [(set (match_operand:DD 0 "register_operand" "=f") | |
47d34a13 | 3798 | (float_truncate:DD (match_operand:TD 1 "register_operand" "f"))) |
3799 | (clobber (match_scratch:TD 2 "=f"))] | |
1f8e70bc | 3800 | "TARGET_HARD_FLOAT && TARGET_HARD_DFP" |
47d34a13 | 3801 | "ldxtr\t%2,0,%1,0\;ldr\t%0,%2" |
3802 | [(set_attr "length" "6") | |
3803 | (set_attr "type" "ftrunctf")]) | |
1f8e70bc | 3804 | |
3805 | (define_insn "truncddsd2" | |
3806 | [(set (match_operand:SD 0 "register_operand" "=f") | |
3807 | (float_truncate:SD (match_operand:DD 1 "register_operand" "f")))] | |
3808 | "TARGET_HARD_FLOAT && TARGET_HARD_DFP" | |
3809 | "ledtr\t%0,0,%1,0" | |
3810 | [(set_attr "op_type" "RRF") | |
3811 | (set_attr "type" "fsimptf")]) | |
3812 | ||
4673c1a0 | 3813 | ; |
095798e3 | 3814 | ; extend(sf|df)(df|tf)2 instruction pattern(s). |
429f9fdb | 3815 | ; |
3816 | ||
095798e3 | 3817 | ; ldebr, ldeb, lxdbr, lxdb, lxebr, lxeb |
3818 | (define_insn "extend<DSF:mode><BFP:mode>2" | |
3819 | [(set (match_operand:BFP 0 "register_operand" "=f,f") | |
3820 | (float_extend:BFP (match_operand:DSF 1 "nonimmediate_operand" "f,R")))] | |
3821 | "TARGET_HARD_FLOAT | |
3822 | && GET_MODE_SIZE (<BFP:MODE>mode) > GET_MODE_SIZE (<DSF:MODE>mode)" | |
429f9fdb | 3823 | "@ |
095798e3 | 3824 | l<BFP:xde><DSF:xde>br\t%0,%1 |
3825 | l<BFP:xde><DSF:xde>b\t%0,%1" | |
429f9fdb | 3826 | [(set_attr "op_type" "RRE,RXE") |
095798e3 | 3827 | (set_attr "type" "fsimp<BFP:mode>, fload<BFP:mode>")]) |
429f9fdb | 3828 | |
1f8e70bc | 3829 | ; |
3830 | ; extendddtd2 and extendsddd2 instruction pattern(s). | |
3831 | ; | |
3832 | ||
3833 | (define_insn "extendddtd2" | |
3834 | [(set (match_operand:TD 0 "register_operand" "=f") | |
3835 | (float_extend:TD (match_operand:DD 1 "register_operand" "f")))] | |
3836 | "TARGET_HARD_FLOAT && TARGET_HARD_DFP" | |
3837 | "lxdtr\t%0,%1,0" | |
3838 | [(set_attr "op_type" "RRF") | |
3839 | (set_attr "type" "fsimptf")]) | |
3840 | ||
3841 | (define_insn "extendsddd2" | |
3842 | [(set (match_operand:DD 0 "register_operand" "=f") | |
3843 | (float_extend:DD (match_operand:SD 1 "register_operand" "f")))] | |
3844 | "TARGET_HARD_FLOAT && TARGET_HARD_DFP" | |
3845 | "ldetr\t%0,%1,0" | |
3846 | [(set_attr "op_type" "RRF") | |
3847 | (set_attr "type" "fsimptf")]) | |
4673c1a0 | 3848 | |
9fa9680d | 3849 | ; Binary <-> Decimal floating point trunc patterns |
3850 | ; | |
3851 | ||
3852 | (define_insn "*trunc<BFP:mode><DFP_ALL:mode>2" | |
3853 | [(set (reg:DFP_ALL FPR0_REGNUM) | |
3854 | (float_truncate:DFP_ALL (reg:BFP FPR2_REGNUM))) | |
3855 | (use (reg:SI GPR0_REGNUM)) | |
3856 | (clobber (reg:CC CC_REGNUM))] | |
3857 | "TARGET_HARD_FLOAT && TARGET_DFP" | |
3858 | "pfpo") | |
3859 | ||
3860 | (define_insn "*trunc<DFP_ALL:mode><BFP:mode>2" | |
3861 | [(set (reg:BFP FPR0_REGNUM) | |
3862 | (float_truncate:BFP (reg:DFP_ALL FPR2_REGNUM))) | |
3863 | (use (reg:SI GPR0_REGNUM)) | |
3864 | (clobber (reg:CC CC_REGNUM))] | |
3865 | "TARGET_HARD_FLOAT && TARGET_DFP" | |
3866 | "pfpo") | |
3867 | ||
3868 | (define_expand "trunc<BFP:mode><DFP_ALL:mode>2" | |
3869 | [(set (reg:BFP FPR2_REGNUM) (match_operand:BFP 1 "nonimmediate_operand" "")) | |
3870 | (set (reg:SI GPR0_REGNUM) (match_dup 2)) | |
3871 | (parallel | |
3872 | [(set (reg:DFP_ALL FPR0_REGNUM) | |
3873 | (float_truncate:DFP_ALL (reg:BFP FPR2_REGNUM))) | |
3874 | (use (reg:SI GPR0_REGNUM)) | |
3875 | (clobber (reg:CC CC_REGNUM))]) | |
3876 | (set (match_operand:DFP_ALL 0 "nonimmediate_operand" "") | |
3877 | (reg:DFP_ALL FPR0_REGNUM))] | |
3878 | "TARGET_HARD_FLOAT && TARGET_DFP | |
3879 | && GET_MODE_SIZE (<BFP:MODE>mode) > GET_MODE_SIZE (<DFP_ALL:MODE>mode)" | |
3880 | { | |
3881 | HOST_WIDE_INT flags; | |
3882 | ||
3883 | flags = (PFPO_CONVERT | | |
3884 | PFPO_OP_TYPE_<DFP_ALL:MODE> << PFPO_OP0_TYPE_SHIFT | | |
3885 | PFPO_OP_TYPE_<BFP:MODE> << PFPO_OP1_TYPE_SHIFT); | |
3886 | ||
3887 | operands[2] = GEN_INT (flags); | |
3888 | }) | |
3889 | ||
3890 | (define_expand "trunc<DFP_ALL:mode><BFP:mode>2" | |
3891 | [(set (reg:DFP_ALL FPR2_REGNUM) | |
3892 | (match_operand:DFP_ALL 1 "nonimmediate_operand" "")) | |
3893 | (set (reg:SI GPR0_REGNUM) (match_dup 2)) | |
3894 | (parallel | |
3895 | [(set (reg:BFP FPR0_REGNUM) (float_truncate:BFP (reg:DFP_ALL FPR2_REGNUM))) | |
3896 | (use (reg:SI GPR0_REGNUM)) | |
3897 | (clobber (reg:CC CC_REGNUM))]) | |
3898 | (set (match_operand:BFP 0 "nonimmediate_operand" "") (reg:BFP FPR0_REGNUM))] | |
3899 | "TARGET_HARD_FLOAT && TARGET_DFP | |
3900 | && GET_MODE_SIZE (<DFP_ALL:MODE>mode) >= GET_MODE_SIZE (<BFP:MODE>mode)" | |
3901 | { | |
3902 | HOST_WIDE_INT flags; | |
3903 | ||
3904 | flags = (PFPO_CONVERT | | |
3905 | PFPO_OP_TYPE_<BFP:MODE> << PFPO_OP0_TYPE_SHIFT | | |
3906 | PFPO_OP_TYPE_<DFP_ALL:MODE> << PFPO_OP1_TYPE_SHIFT); | |
3907 | ||
3908 | operands[2] = GEN_INT (flags); | |
3909 | }) | |
3910 | ||
3911 | ; | |
3912 | ; Binary <-> Decimal floating point extend patterns | |
3913 | ; | |
3914 | ||
3915 | (define_insn "*extend<BFP:mode><DFP_ALL:mode>2" | |
3916 | [(set (reg:DFP_ALL FPR0_REGNUM) (float_extend:DFP_ALL (reg:BFP FPR2_REGNUM))) | |
3917 | (use (reg:SI GPR0_REGNUM)) | |
3918 | (clobber (reg:CC CC_REGNUM))] | |
3919 | "TARGET_HARD_FLOAT && TARGET_DFP" | |
3920 | "pfpo") | |
3921 | ||
3922 | (define_insn "*extend<DFP_ALL:mode><BFP:mode>2" | |
3923 | [(set (reg:BFP FPR0_REGNUM) (float_extend:BFP (reg:DFP_ALL FPR2_REGNUM))) | |
3924 | (use (reg:SI GPR0_REGNUM)) | |
3925 | (clobber (reg:CC CC_REGNUM))] | |
3926 | "TARGET_HARD_FLOAT && TARGET_DFP" | |
3927 | "pfpo") | |
3928 | ||
3929 | (define_expand "extend<BFP:mode><DFP_ALL:mode>2" | |
3930 | [(set (reg:BFP FPR2_REGNUM) (match_operand:BFP 1 "nonimmediate_operand" "")) | |
3931 | (set (reg:SI GPR0_REGNUM) (match_dup 2)) | |
3932 | (parallel | |
3933 | [(set (reg:DFP_ALL FPR0_REGNUM) | |
3934 | (float_extend:DFP_ALL (reg:BFP FPR2_REGNUM))) | |
3935 | (use (reg:SI GPR0_REGNUM)) | |
3936 | (clobber (reg:CC CC_REGNUM))]) | |
3937 | (set (match_operand:DFP_ALL 0 "nonimmediate_operand" "") | |
3938 | (reg:DFP_ALL FPR0_REGNUM))] | |
3939 | "TARGET_HARD_FLOAT && TARGET_DFP | |
3940 | && GET_MODE_SIZE (<BFP:MODE>mode) <= GET_MODE_SIZE (<DFP_ALL:MODE>mode)" | |
3941 | { | |
3942 | HOST_WIDE_INT flags; | |
3943 | ||
3944 | flags = (PFPO_CONVERT | | |
3945 | PFPO_OP_TYPE_<DFP_ALL:MODE> << PFPO_OP0_TYPE_SHIFT | | |
3946 | PFPO_OP_TYPE_<BFP:MODE> << PFPO_OP1_TYPE_SHIFT); | |
3947 | ||
3948 | operands[2] = GEN_INT (flags); | |
3949 | }) | |
3950 | ||
3951 | (define_expand "extend<DFP_ALL:mode><BFP:mode>2" | |
3952 | [(set (reg:DFP_ALL FPR2_REGNUM) | |
3953 | (match_operand:DFP_ALL 1 "nonimmediate_operand" "")) | |
3954 | (set (reg:SI GPR0_REGNUM) (match_dup 2)) | |
3955 | (parallel | |
3956 | [(set (reg:BFP FPR0_REGNUM) (float_extend:BFP (reg:DFP_ALL FPR2_REGNUM))) | |
3957 | (use (reg:SI GPR0_REGNUM)) | |
3958 | (clobber (reg:CC CC_REGNUM))]) | |
3959 | (set (match_operand:BFP 0 "nonimmediate_operand" "") (reg:BFP FPR0_REGNUM))] | |
3960 | "TARGET_HARD_FLOAT && TARGET_DFP | |
3961 | && GET_MODE_SIZE (<DFP_ALL:MODE>mode) < GET_MODE_SIZE (<BFP:MODE>mode)" | |
3962 | { | |
3963 | HOST_WIDE_INT flags; | |
3964 | ||
3965 | flags = (PFPO_CONVERT | | |
3966 | PFPO_OP_TYPE_<BFP:MODE> << PFPO_OP0_TYPE_SHIFT | | |
3967 | PFPO_OP_TYPE_<DFP_ALL:MODE> << PFPO_OP1_TYPE_SHIFT); | |
3968 | ||
3969 | operands[2] = GEN_INT (flags); | |
3970 | }) | |
3971 | ||
3972 | ||
4673c1a0 | 3973 | ;; |
1fc184ee | 3974 | ;; ARITHMETIC OPERATIONS |
4673c1a0 | 3975 | ;; |
1fc184ee | 3976 | ; arithmetic operations set the ConditionCode, |
4673c1a0 | 3977 | ; because of unpredictable Bits in Register for Halfword and Byte |
3978 | ; the ConditionCode can be set wrong in operations for Halfword and Byte | |
3979 | ||
c6821d1c | 3980 | ;; |
3981 | ;;- Add instructions. | |
3982 | ;; | |
3983 | ||
401fe9a1 | 3984 | ; |
3985 | ; addti3 instruction pattern(s). | |
3986 | ; | |
3987 | ||
3988 | (define_insn_and_split "addti3" | |
3989 | [(set (match_operand:TI 0 "register_operand" "=&d") | |
3990 | (plus:TI (match_operand:TI 1 "nonimmediate_operand" "%0") | |
3991 | (match_operand:TI 2 "general_operand" "do") ) ) | |
1ca361fd | 3992 | (clobber (reg:CC CC_REGNUM))] |
401fe9a1 | 3993 | "TARGET_64BIT" |
3994 | "#" | |
3995 | "&& reload_completed" | |
3996 | [(parallel | |
1ca361fd | 3997 | [(set (reg:CCL1 CC_REGNUM) |
401fe9a1 | 3998 | (compare:CCL1 (plus:DI (match_dup 7) (match_dup 8)) |
3999 | (match_dup 7))) | |
4000 | (set (match_dup 6) (plus:DI (match_dup 7) (match_dup 8)))]) | |
4001 | (parallel | |
6f4afa7e | 4002 | [(set (match_dup 3) (plus:DI |
4003 | (plus:DI (ltu:DI (reg:CCL1 CC_REGNUM) (const_int 0)) | |
4004 | (match_dup 4)) (match_dup 5))) | |
1ca361fd | 4005 | (clobber (reg:CC CC_REGNUM))])] |
401fe9a1 | 4006 | "operands[3] = operand_subword (operands[0], 0, 0, TImode); |
4007 | operands[4] = operand_subword (operands[1], 0, 0, TImode); | |
4008 | operands[5] = operand_subword (operands[2], 0, 0, TImode); | |
4009 | operands[6] = operand_subword (operands[0], 1, 0, TImode); | |
4010 | operands[7] = operand_subword (operands[1], 1, 0, TImode); | |
1822f0d6 | 4011 | operands[8] = operand_subword (operands[2], 1, 0, TImode);") |
401fe9a1 | 4012 | |
c6821d1c | 4013 | ; |
4014 | ; adddi3 instruction pattern(s). | |
4015 | ; | |
4016 | ||
d1641800 | 4017 | (define_expand "adddi3" |
4018 | [(parallel | |
e68d6a13 | 4019 | [(set (match_operand:DI 0 "nonimmediate_operand" "") |
d1641800 | 4020 | (plus:DI (match_operand:DI 1 "nonimmediate_operand" "") |
4021 | (match_operand:DI 2 "general_operand" ""))) | |
4022 | (clobber (reg:CC CC_REGNUM))])] | |
4023 | "" | |
4024 | "") | |
4025 | ||
c6821d1c | 4026 | (define_insn "*adddi3_sign" |
4027 | [(set (match_operand:DI 0 "register_operand" "=d,d") | |
8fe52251 | 4028 | (plus:DI (sign_extend:DI (match_operand:SI 2 "general_operand" "d,RT")) |
c6821d1c | 4029 | (match_operand:DI 1 "register_operand" "0,0"))) |
1ca361fd | 4030 | (clobber (reg:CC CC_REGNUM))] |
c6821d1c | 4031 | "TARGET_64BIT" |
4032 | "@ | |
f24d7ff3 | 4033 | agfr\t%0,%2 |
4034 | agf\t%0,%2" | |
51aa1e9c | 4035 | [(set_attr "op_type" "RRE,RXY")]) |
c6821d1c | 4036 | |
4037 | (define_insn "*adddi3_zero_cc" | |
1ca361fd | 4038 | [(set (reg CC_REGNUM) |
8fe52251 | 4039 | (compare (plus:DI (zero_extend:DI (match_operand:SI 2 "general_operand" "d,RT")) |
c6821d1c | 4040 | (match_operand:DI 1 "register_operand" "0,0")) |
4041 | (const_int 0))) | |
4042 | (set (match_operand:DI 0 "register_operand" "=d,d") | |
4043 | (plus:DI (zero_extend:DI (match_dup 2)) (match_dup 1)))] | |
4044 | "s390_match_ccmode (insn, CCLmode) && TARGET_64BIT" | |
4045 | "@ | |
f24d7ff3 | 4046 | algfr\t%0,%2 |
4047 | algf\t%0,%2" | |
51aa1e9c | 4048 | [(set_attr "op_type" "RRE,RXY")]) |
c6821d1c | 4049 | |
4050 | (define_insn "*adddi3_zero_cconly" | |
1ca361fd | 4051 | [(set (reg CC_REGNUM) |
8fe52251 | 4052 | (compare (plus:DI (zero_extend:DI (match_operand:SI 2 "general_operand" "d,RT")) |
c6821d1c | 4053 | (match_operand:DI 1 "register_operand" "0,0")) |
4054 | (const_int 0))) | |
4055 | (clobber (match_scratch:DI 0 "=d,d"))] | |
4056 | "s390_match_ccmode (insn, CCLmode) && TARGET_64BIT" | |
4057 | "@ | |
f24d7ff3 | 4058 | algfr\t%0,%2 |
4059 | algf\t%0,%2" | |
51aa1e9c | 4060 | [(set_attr "op_type" "RRE,RXY")]) |
c6821d1c | 4061 | |
4062 | (define_insn "*adddi3_zero" | |
4063 | [(set (match_operand:DI 0 "register_operand" "=d,d") | |
8fe52251 | 4064 | (plus:DI (zero_extend:DI (match_operand:SI 2 "general_operand" "d,RT")) |
c6821d1c | 4065 | (match_operand:DI 1 "register_operand" "0,0"))) |
1ca361fd | 4066 | (clobber (reg:CC CC_REGNUM))] |
c6821d1c | 4067 | "TARGET_64BIT" |
4068 | "@ | |
f24d7ff3 | 4069 | algfr\t%0,%2 |
4070 | algf\t%0,%2" | |
51aa1e9c | 4071 | [(set_attr "op_type" "RRE,RXY")]) |
c6821d1c | 4072 | |
12f61740 | 4073 | (define_insn_and_split "*adddi3_31z" |
e68d6a13 | 4074 | [(set (match_operand:DI 0 "nonimmediate_operand" "=&d") |
12f61740 | 4075 | (plus:DI (match_operand:DI 1 "nonimmediate_operand" "%0") |
4076 | (match_operand:DI 2 "general_operand" "do") ) ) | |
1ca361fd | 4077 | (clobber (reg:CC CC_REGNUM))] |
12f61740 | 4078 | "!TARGET_64BIT && TARGET_CPU_ZARCH" |
4079 | "#" | |
4080 | "&& reload_completed" | |
4081 | [(parallel | |
1ca361fd | 4082 | [(set (reg:CCL1 CC_REGNUM) |
12f61740 | 4083 | (compare:CCL1 (plus:SI (match_dup 7) (match_dup 8)) |
4084 | (match_dup 7))) | |
4085 | (set (match_dup 6) (plus:SI (match_dup 7) (match_dup 8)))]) | |
4086 | (parallel | |
6f4afa7e | 4087 | [(set (match_dup 3) (plus:SI |
4088 | (plus:SI (ltu:SI (reg:CCL1 CC_REGNUM) (const_int 0)) | |
4089 | (match_dup 4)) (match_dup 5))) | |
1ca361fd | 4090 | (clobber (reg:CC CC_REGNUM))])] |
12f61740 | 4091 | "operands[3] = operand_subword (operands[0], 0, 0, DImode); |
4092 | operands[4] = operand_subword (operands[1], 0, 0, DImode); | |
4093 | operands[5] = operand_subword (operands[2], 0, 0, DImode); | |
4094 | operands[6] = operand_subword (operands[0], 1, 0, DImode); | |
4095 | operands[7] = operand_subword (operands[1], 1, 0, DImode); | |
1822f0d6 | 4096 | operands[8] = operand_subword (operands[2], 1, 0, DImode);") |
12f61740 | 4097 | |
c6821d1c | 4098 | (define_insn_and_split "*adddi3_31" |
e68d6a13 | 4099 | [(set (match_operand:DI 0 "nonimmediate_operand" "=&d") |
7c3aefa0 | 4100 | (plus:DI (match_operand:DI 1 "nonimmediate_operand" "%0") |
37793c2d | 4101 | (match_operand:DI 2 "general_operand" "do") ) ) |
1ca361fd | 4102 | (clobber (reg:CC CC_REGNUM))] |
12f61740 | 4103 | "!TARGET_CPU_ZARCH" |
c6821d1c | 4104 | "#" |
4105 | "&& reload_completed" | |
4106 | [(parallel | |
4107 | [(set (match_dup 3) (plus:SI (match_dup 4) (match_dup 5))) | |
1ca361fd | 4108 | (clobber (reg:CC CC_REGNUM))]) |
c6821d1c | 4109 | (parallel |
1ca361fd | 4110 | [(set (reg:CCL1 CC_REGNUM) |
c6821d1c | 4111 | (compare:CCL1 (plus:SI (match_dup 7) (match_dup 8)) |
4112 | (match_dup 7))) | |
4113 | (set (match_dup 6) (plus:SI (match_dup 7) (match_dup 8)))]) | |
4114 | (set (pc) | |
1ca361fd | 4115 | (if_then_else (ltu (reg:CCL1 CC_REGNUM) (const_int 0)) |
c6821d1c | 4116 | (pc) |
4117 | (label_ref (match_dup 9)))) | |
4118 | (parallel | |
4119 | [(set (match_dup 3) (plus:SI (match_dup 3) (const_int 1))) | |
1ca361fd | 4120 | (clobber (reg:CC CC_REGNUM))]) |
c6821d1c | 4121 | (match_dup 9)] |
37793c2d | 4122 | "operands[3] = operand_subword (operands[0], 0, 0, DImode); |
4123 | operands[4] = operand_subword (operands[1], 0, 0, DImode); | |
4124 | operands[5] = operand_subword (operands[2], 0, 0, DImode); | |
4125 | operands[6] = operand_subword (operands[0], 1, 0, DImode); | |
4126 | operands[7] = operand_subword (operands[1], 1, 0, DImode); | |
4127 | operands[8] = operand_subword (operands[2], 1, 0, DImode); | |
1822f0d6 | 4128 | operands[9] = gen_label_rtx ();") |
4673c1a0 | 4129 | |
d1641800 | 4130 | ; |
4131 | ; addsi3 instruction pattern(s). | |
4132 | ; | |
4133 | ||
4134 | (define_expand "addsi3" | |
c6821d1c | 4135 | [(parallel |
e68d6a13 | 4136 | [(set (match_operand:SI 0 "nonimmediate_operand" "") |
d1641800 | 4137 | (plus:SI (match_operand:SI 1 "nonimmediate_operand" "") |
4138 | (match_operand:SI 2 "general_operand" ""))) | |
1ca361fd | 4139 | (clobber (reg:CC CC_REGNUM))])] |
4673c1a0 | 4140 | "" |
c6821d1c | 4141 | "") |
4673c1a0 | 4142 | |
d1641800 | 4143 | (define_insn "*addsi3_sign" |
4144 | [(set (match_operand:SI 0 "register_operand" "=d,d") | |
4145 | (plus:SI (sign_extend:SI (match_operand:HI 2 "memory_operand" "R,T")) | |
4146 | (match_operand:SI 1 "register_operand" "0,0"))) | |
4147 | (clobber (reg:CC CC_REGNUM))] | |
4148 | "" | |
4149 | "@ | |
4150 | ah\t%0,%2 | |
4151 | ahy\t%0,%2" | |
4152 | [(set_attr "op_type" "RX,RXY")]) | |
4153 | ||
4673c1a0 | 4154 | ; |
d1641800 | 4155 | ; add(di|si)3 instruction pattern(s). |
4673c1a0 | 4156 | ; |
4673c1a0 | 4157 | |
e68d6a13 | 4158 | ; ar, ahi, alfi, slfi, a, ay, agr, aghi, algfi, slgfi, ag, asi, agsi |
d1641800 | 4159 | (define_insn "*add<mode>3" |
e68d6a13 | 4160 | [(set (match_operand:GPR 0 "nonimmediate_operand" "=d,d,d,d,d,d,QS") |
4161 | (plus:GPR (match_operand:GPR 1 "nonimmediate_operand" "%0,0,0,0,0,0,0") | |
4162 | (match_operand:GPR 2 "general_operand" "d,K,Op,On,R,T,C") ) ) | |
d1641800 | 4163 | (clobber (reg:CC CC_REGNUM))] |
4164 | "" | |
163277cf | 4165 | "@ |
d1641800 | 4166 | a<g>r\t%0,%2 |
4167 | a<g>hi\t%0,%h2 | |
4168 | al<g>fi\t%0,%2 | |
4169 | sl<g>fi\t%0,%n2 | |
4170 | a<g>\t%0,%2 | |
e68d6a13 | 4171 | a<y>\t%0,%2 |
4172 | a<g>si\t%0,%c2" | |
4173 | [(set_attr "op_type" "RR<E>,RI,RIL,RIL,RX<Y>,RXY,SIY") | |
4174 | (set_attr "cpu_facility" "*,*,extimm,extimm,*,*,z10")]) | |
3c482144 | 4175 | |
e68d6a13 | 4176 | ; alr, alfi, slfi, al, aly, algr, algfi, slgfi, alg, alsi, algsi |
d1641800 | 4177 | (define_insn "*add<mode>3_carry1_cc" |
1ca361fd | 4178 | [(set (reg CC_REGNUM) |
e68d6a13 | 4179 | (compare (plus:GPR (match_operand:GPR 1 "nonimmediate_operand" "%0,0,0,0,0,0") |
4180 | (match_operand:GPR 2 "general_operand" "d,Op,On,R,T,C")) | |
c6821d1c | 4181 | (match_dup 1))) |
e68d6a13 | 4182 | (set (match_operand:GPR 0 "nonimmediate_operand" "=d,d,d,d,d,d") |
d1641800 | 4183 | (plus:GPR (match_dup 1) (match_dup 2)))] |
f81e845f | 4184 | "s390_match_ccmode (insn, CCL1mode)" |
c6821d1c | 4185 | "@ |
d1641800 | 4186 | al<g>r\t%0,%2 |
4187 | al<g>fi\t%0,%2 | |
4188 | sl<g>fi\t%0,%n2 | |
4189 | al<g>\t%0,%2 | |
e68d6a13 | 4190 | al<y>\t%0,%2 |
4191 | al<g>si\t%0,%c2" | |
4192 | [(set_attr "op_type" "RR<E>,RIL,RIL,RX<Y>,RXY,SIY") | |
4193 | (set_attr "cpu_facility" "*,extimm,extimm,*,*,z10")]) | |
c6821d1c | 4194 | |
87bc9927 | 4195 | ; alr, al, aly, algr, alg |
d1641800 | 4196 | (define_insn "*add<mode>3_carry1_cconly" |
1ca361fd | 4197 | [(set (reg CC_REGNUM) |
d1641800 | 4198 | (compare (plus:GPR (match_operand:GPR 1 "nonimmediate_operand" "%0,0,0") |
4199 | (match_operand:GPR 2 "general_operand" "d,R,T")) | |
c6821d1c | 4200 | (match_dup 1))) |
d1641800 | 4201 | (clobber (match_scratch:GPR 0 "=d,d,d"))] |
f81e845f | 4202 | "s390_match_ccmode (insn, CCL1mode)" |
c6821d1c | 4203 | "@ |
d1641800 | 4204 | al<g>r\t%0,%2 |
4205 | al<g>\t%0,%2 | |
4206 | al<y>\t%0,%2" | |
4207 | [(set_attr "op_type" "RR<E>,RX<Y>,RXY")]) | |
c6821d1c | 4208 | |
e68d6a13 | 4209 | ; alr, alfi, slfi, al, aly, algr, algfi, slgfi, alg, alsi, algsi |
d1641800 | 4210 | (define_insn "*add<mode>3_carry2_cc" |
1ca361fd | 4211 | [(set (reg CC_REGNUM) |
e68d6a13 | 4212 | (compare (plus:GPR (match_operand:GPR 1 "nonimmediate_operand" "%0,0,0,0,0,0") |
4213 | (match_operand:GPR 2 "general_operand" "d,Op,On,R,T,C")) | |
c6821d1c | 4214 | (match_dup 2))) |
e68d6a13 | 4215 | (set (match_operand:GPR 0 "nonimmediate_operand" "=d,d,d,d,d,RS") |
d1641800 | 4216 | (plus:GPR (match_dup 1) (match_dup 2)))] |
f81e845f | 4217 | "s390_match_ccmode (insn, CCL1mode)" |
c6821d1c | 4218 | "@ |
d1641800 | 4219 | al<g>r\t%0,%2 |
4220 | al<g>fi\t%0,%2 | |
4221 | sl<g>fi\t%0,%n2 | |
4222 | al<g>\t%0,%2 | |
e68d6a13 | 4223 | al<y>\t%0,%2 |
4224 | al<g>si\t%0,%c2" | |
4225 | [(set_attr "op_type" "RR<E>,RIL,RIL,RX<Y>,RXY,SIY") | |
4226 | (set_attr "cpu_facility" "*,extimm,extimm,*,*,z10")]) | |
c6821d1c | 4227 | |
87bc9927 | 4228 | ; alr, al, aly, algr, alg |
d1641800 | 4229 | (define_insn "*add<mode>3_carry2_cconly" |
1ca361fd | 4230 | [(set (reg CC_REGNUM) |
d1641800 | 4231 | (compare (plus:GPR (match_operand:GPR 1 "nonimmediate_operand" "%0,0,0") |
4232 | (match_operand:GPR 2 "general_operand" "d,R,T")) | |
c6821d1c | 4233 | (match_dup 2))) |
d1641800 | 4234 | (clobber (match_scratch:GPR 0 "=d,d,d"))] |
f81e845f | 4235 | "s390_match_ccmode (insn, CCL1mode)" |
c6821d1c | 4236 | "@ |
d1641800 | 4237 | al<g>r\t%0,%2 |
4238 | al<g>\t%0,%2 | |
4239 | al<y>\t%0,%2" | |
4240 | [(set_attr "op_type" "RR<E>,RX<Y>,RXY")]) | |
c6821d1c | 4241 | |
e68d6a13 | 4242 | ; alr, alfi, slfi, al, aly, algr, algfi, slgfi, alg, alsi, algsi |
d1641800 | 4243 | (define_insn "*add<mode>3_cc" |
1ca361fd | 4244 | [(set (reg CC_REGNUM) |
e68d6a13 | 4245 | (compare (plus:GPR (match_operand:GPR 1 "nonimmediate_operand" "%0,0,0,0,0,0") |
4246 | (match_operand:GPR 2 "general_operand" "d,Op,On,R,T,C")) | |
4673c1a0 | 4247 | (const_int 0))) |
e68d6a13 | 4248 | (set (match_operand:GPR 0 "nonimmediate_operand" "=d,d,d,d,d,RS") |
d1641800 | 4249 | (plus:GPR (match_dup 1) (match_dup 2)))] |
f81e845f | 4250 | "s390_match_ccmode (insn, CCLmode)" |
4673c1a0 | 4251 | "@ |
d1641800 | 4252 | al<g>r\t%0,%2 |
4253 | al<g>fi\t%0,%2 | |
4254 | sl<g>fi\t%0,%n2 | |
4255 | al<g>\t%0,%2 | |
e68d6a13 | 4256 | al<y>\t%0,%2 |
4257 | al<g>si\t%0,%c2" | |
4258 | [(set_attr "op_type" "RR<E>,RIL,RIL,RX<Y>,RXY,SIY") | |
4259 | (set_attr "cpu_facility" "*,extimm,extimm,*,*,z10")]) | |
4673c1a0 | 4260 | |
87bc9927 | 4261 | ; alr, al, aly, algr, alg |
d1641800 | 4262 | (define_insn "*add<mode>3_cconly" |
1ca361fd | 4263 | [(set (reg CC_REGNUM) |
d1641800 | 4264 | (compare (plus:GPR (match_operand:GPR 1 "nonimmediate_operand" "%0,0,0") |
4265 | (match_operand:GPR 2 "general_operand" "d,R,T")) | |
4673c1a0 | 4266 | (const_int 0))) |
d1641800 | 4267 | (clobber (match_scratch:GPR 0 "=d,d,d"))] |
f81e845f | 4268 | "s390_match_ccmode (insn, CCLmode)" |
4673c1a0 | 4269 | "@ |
d1641800 | 4270 | al<g>r\t%0,%2 |
4271 | al<g>\t%0,%2 | |
4272 | al<y>\t%0,%2" | |
4273 | [(set_attr "op_type" "RR<E>,RX<Y>,RXY")]) | |
4673c1a0 | 4274 | |
87bc9927 | 4275 | ; alr, al, aly, algr, alg |
d1641800 | 4276 | (define_insn "*add<mode>3_cconly2" |
1ca361fd | 4277 | [(set (reg CC_REGNUM) |
d1641800 | 4278 | (compare (match_operand:GPR 1 "nonimmediate_operand" "%0,0,0") |
4279 | (neg:GPR (match_operand:GPR 2 "general_operand" "d,R,T")))) | |
4280 | (clobber (match_scratch:GPR 0 "=d,d,d"))] | |
4281 | "s390_match_ccmode(insn, CCLmode)" | |
51aa1e9c | 4282 | "@ |
d1641800 | 4283 | al<g>r\t%0,%2 |
4284 | al<g>\t%0,%2 | |
4285 | al<y>\t%0,%2" | |
4286 | [(set_attr "op_type" "RR<E>,RX<Y>,RXY")]) | |
c6821d1c | 4287 | |
e68d6a13 | 4288 | ; ahi, afi, aghi, agfi, asi, agsi |
d1641800 | 4289 | (define_insn "*add<mode>3_imm_cc" |
4290 | [(set (reg CC_REGNUM) | |
e68d6a13 | 4291 | (compare (plus:GPR (match_operand:GPR 1 "nonimmediate_operand" "0,0,0") |
4292 | (match_operand:GPR 2 "const_int_operand" "K,Os,C")) | |
d1641800 | 4293 | (const_int 0))) |
e68d6a13 | 4294 | (set (match_operand:GPR 0 "nonimmediate_operand" "=d,d,QS") |
d1641800 | 4295 | (plus:GPR (match_dup 1) (match_dup 2)))] |
4296 | "s390_match_ccmode (insn, CCAmode) | |
4297 | && (CONST_OK_FOR_CONSTRAINT_P (INTVAL (operands[2]), 'K', \"K\") | |
e68d6a13 | 4298 | || CONST_OK_FOR_CONSTRAINT_P (INTVAL (operands[2]), 'O', \"Os\") |
4299 | || CONST_OK_FOR_CONSTRAINT_P (INTVAL (operands[2]), 'C', \"C\")) | |
d1641800 | 4300 | && INTVAL (operands[2]) != -((HOST_WIDE_INT)1 << (GET_MODE_BITSIZE(<MODE>mode) - 1))" |
4673c1a0 | 4301 | "@ |
d1641800 | 4302 | a<g>hi\t%0,%h2 |
e68d6a13 | 4303 | a<g>fi\t%0,%2 |
4304 | a<g>si\t%0,%c2" | |
4305 | [(set_attr "op_type" "RI,RIL,SIY") | |
4306 | (set_attr "cpu_facility" "*,extimm,z10")]) | |
4673c1a0 | 4307 | |
4673c1a0 | 4308 | ; |
1f8e70bc | 4309 | ; add(tf|df|sf|td|dd)3 instruction pattern(s). |
4673c1a0 | 4310 | ; |
4311 | ||
1f8e70bc | 4312 | ; axbr, adbr, aebr, axb, adb, aeb, adtr, axtr |
095798e3 | 4313 | (define_insn "add<mode>3" |
1f8e70bc | 4314 | [(set (match_operand:FP 0 "register_operand" "=f, f") |
4315 | (plus:FP (match_operand:FP 1 "nonimmediate_operand" "%<f0>,0") | |
4316 | (match_operand:FP 2 "general_operand" " f,<Rf>"))) | |
1ca361fd | 4317 | (clobber (reg:CC CC_REGNUM))] |
095798e3 | 4318 | "TARGET_HARD_FLOAT" |
4673c1a0 | 4319 | "@ |
1f8e70bc | 4320 | a<xde><bt>r\t%0,<op1>%2 |
429f9fdb | 4321 | a<xde>b\t%0,%2" |
1f8e70bc | 4322 | [(set_attr "op_type" "<RRer>,RXE") |
4323 | (set_attr "type" "fsimp<bfp>")]) | |
4673c1a0 | 4324 | |
1f8e70bc | 4325 | ; axbr, adbr, aebr, axb, adb, aeb, adtr, axtr |
8052065f | 4326 | (define_insn "*add<mode>3_cc" |
1ca361fd | 4327 | [(set (reg CC_REGNUM) |
1f8e70bc | 4328 | (compare (plus:FP (match_operand:FP 1 "nonimmediate_operand" "%<f0>,0") |
4329 | (match_operand:FP 2 "general_operand" " f,<Rf>")) | |
4330 | (match_operand:FP 3 "const0_operand" ""))) | |
4331 | (set (match_operand:FP 0 "register_operand" "=f,f") | |
4332 | (plus:FP (match_dup 1) (match_dup 2)))] | |
095798e3 | 4333 | "s390_match_ccmode (insn, CCSmode) && TARGET_HARD_FLOAT" |
e9fd5349 | 4334 | "@ |
1f8e70bc | 4335 | a<xde><bt>r\t%0,<op1>%2 |
429f9fdb | 4336 | a<xde>b\t%0,%2" |
1f8e70bc | 4337 | [(set_attr "op_type" "<RRer>,RXE") |
4338 | (set_attr "type" "fsimp<bfp>")]) | |
e9fd5349 | 4339 | |
1f8e70bc | 4340 | ; axbr, adbr, aebr, axb, adb, aeb, adtr, axtr |
8052065f | 4341 | (define_insn "*add<mode>3_cconly" |
1ca361fd | 4342 | [(set (reg CC_REGNUM) |
1f8e70bc | 4343 | (compare (plus:FP (match_operand:FP 1 "nonimmediate_operand" "%<f0>,0") |
4344 | (match_operand:FP 2 "general_operand" " f,<Rf>")) | |
4345 | (match_operand:FP 3 "const0_operand" ""))) | |
4346 | (clobber (match_scratch:FP 0 "=f,f"))] | |
095798e3 | 4347 | "s390_match_ccmode (insn, CCSmode) && TARGET_HARD_FLOAT" |
e9fd5349 | 4348 | "@ |
1f8e70bc | 4349 | a<xde><bt>r\t%0,<op1>%2 |
429f9fdb | 4350 | a<xde>b\t%0,%2" |
1f8e70bc | 4351 | [(set_attr "op_type" "<RRer>,RXE") |
4352 | (set_attr "type" "fsimp<bfp>")]) | |
e9fd5349 | 4353 | |
4673c1a0 | 4354 | |
4355 | ;; | |
4356 | ;;- Subtract instructions. | |
4357 | ;; | |
4358 | ||
401fe9a1 | 4359 | ; |
4360 | ; subti3 instruction pattern(s). | |
4361 | ; | |
4362 | ||
4363 | (define_insn_and_split "subti3" | |
4364 | [(set (match_operand:TI 0 "register_operand" "=&d") | |
4365 | (minus:TI (match_operand:TI 1 "register_operand" "0") | |
4366 | (match_operand:TI 2 "general_operand" "do") ) ) | |
1ca361fd | 4367 | (clobber (reg:CC CC_REGNUM))] |
401fe9a1 | 4368 | "TARGET_64BIT" |
4369 | "#" | |
4370 | "&& reload_completed" | |
4371 | [(parallel | |
1ca361fd | 4372 | [(set (reg:CCL2 CC_REGNUM) |
401fe9a1 | 4373 | (compare:CCL2 (minus:DI (match_dup 7) (match_dup 8)) |
4374 | (match_dup 7))) | |
4375 | (set (match_dup 6) (minus:DI (match_dup 7) (match_dup 8)))]) | |
4376 | (parallel | |
4377 | [(set (match_dup 3) (minus:DI (minus:DI (match_dup 4) (match_dup 5)) | |
1ca361fd | 4378 | (gtu:DI (reg:CCL2 CC_REGNUM) (const_int 0)))) |
4379 | (clobber (reg:CC CC_REGNUM))])] | |
401fe9a1 | 4380 | "operands[3] = operand_subword (operands[0], 0, 0, TImode); |
4381 | operands[4] = operand_subword (operands[1], 0, 0, TImode); | |
4382 | operands[5] = operand_subword (operands[2], 0, 0, TImode); | |
4383 | operands[6] = operand_subword (operands[0], 1, 0, TImode); | |
4384 | operands[7] = operand_subword (operands[1], 1, 0, TImode); | |
1822f0d6 | 4385 | operands[8] = operand_subword (operands[2], 1, 0, TImode);") |
401fe9a1 | 4386 | |
4673c1a0 | 4387 | ; |
4388 | ; subdi3 instruction pattern(s). | |
4389 | ; | |
4390 | ||
d1641800 | 4391 | (define_expand "subdi3" |
4392 | [(parallel | |
4393 | [(set (match_operand:DI 0 "register_operand" "") | |
4394 | (minus:DI (match_operand:DI 1 "register_operand" "") | |
4395 | (match_operand:DI 2 "general_operand" ""))) | |
4396 | (clobber (reg:CC CC_REGNUM))])] | |
4397 | "" | |
4398 | "") | |
4399 | ||
c6821d1c | 4400 | (define_insn "*subdi3_sign" |
4401 | [(set (match_operand:DI 0 "register_operand" "=d,d") | |
4402 | (minus:DI (match_operand:DI 1 "register_operand" "0,0") | |
8fe52251 | 4403 | (sign_extend:DI (match_operand:SI 2 "general_operand" "d,RT")))) |
1ca361fd | 4404 | (clobber (reg:CC CC_REGNUM))] |
c6821d1c | 4405 | "TARGET_64BIT" |
4406 | "@ | |
f24d7ff3 | 4407 | sgfr\t%0,%2 |
4408 | sgf\t%0,%2" | |
51aa1e9c | 4409 | [(set_attr "op_type" "RRE,RXY")]) |
c6821d1c | 4410 | |
4411 | (define_insn "*subdi3_zero_cc" | |
1ca361fd | 4412 | [(set (reg CC_REGNUM) |
c6821d1c | 4413 | (compare (minus:DI (match_operand:DI 1 "register_operand" "0,0") |
8fe52251 | 4414 | (zero_extend:DI (match_operand:SI 2 "general_operand" "d,RT"))) |
c6821d1c | 4415 | (const_int 0))) |
4416 | (set (match_operand:DI 0 "register_operand" "=d,d") | |
4417 | (minus:DI (match_dup 1) (zero_extend:DI (match_dup 2))))] | |
4418 | "s390_match_ccmode (insn, CCLmode) && TARGET_64BIT" | |
4419 | "@ | |
f24d7ff3 | 4420 | slgfr\t%0,%2 |
4421 | slgf\t%0,%2" | |
51aa1e9c | 4422 | [(set_attr "op_type" "RRE,RXY")]) |
c6821d1c | 4423 | |
4424 | (define_insn "*subdi3_zero_cconly" | |
1ca361fd | 4425 | [(set (reg CC_REGNUM) |
c6821d1c | 4426 | (compare (minus:DI (match_operand:DI 1 "register_operand" "0,0") |
8fe52251 | 4427 | (zero_extend:DI (match_operand:SI 2 "general_operand" "d,RT"))) |
c6821d1c | 4428 | (const_int 0))) |
4429 | (clobber (match_scratch:DI 0 "=d,d"))] | |
4430 | "s390_match_ccmode (insn, CCLmode) && TARGET_64BIT" | |
4431 | "@ | |
f24d7ff3 | 4432 | slgfr\t%0,%2 |
4433 | slgf\t%0,%2" | |
51aa1e9c | 4434 | [(set_attr "op_type" "RRE,RXY")]) |
c6821d1c | 4435 | |
4436 | (define_insn "*subdi3_zero" | |
4437 | [(set (match_operand:DI 0 "register_operand" "=d,d") | |
4438 | (minus:DI (match_operand:DI 1 "register_operand" "0,0") | |
8fe52251 | 4439 | (zero_extend:DI (match_operand:SI 2 "general_operand" "d,RT")))) |
1ca361fd | 4440 | (clobber (reg:CC CC_REGNUM))] |
c6821d1c | 4441 | "TARGET_64BIT" |
4442 | "@ | |
f24d7ff3 | 4443 | slgfr\t%0,%2 |
4444 | slgf\t%0,%2" | |
51aa1e9c | 4445 | [(set_attr "op_type" "RRE,RXY")]) |
c6821d1c | 4446 | |
12f61740 | 4447 | (define_insn_and_split "*subdi3_31z" |
4448 | [(set (match_operand:DI 0 "register_operand" "=&d") | |
4449 | (minus:DI (match_operand:DI 1 "register_operand" "0") | |
4450 | (match_operand:DI 2 "general_operand" "do") ) ) | |
1ca361fd | 4451 | (clobber (reg:CC CC_REGNUM))] |
12f61740 | 4452 | "!TARGET_64BIT && TARGET_CPU_ZARCH" |
4453 | "#" | |
4454 | "&& reload_completed" | |
4455 | [(parallel | |
1ca361fd | 4456 | [(set (reg:CCL2 CC_REGNUM) |
12f61740 | 4457 | (compare:CCL2 (minus:SI (match_dup 7) (match_dup 8)) |
4458 | (match_dup 7))) | |
4459 | (set (match_dup 6) (minus:SI (match_dup 7) (match_dup 8)))]) | |
4460 | (parallel | |
4461 | [(set (match_dup 3) (minus:SI (minus:SI (match_dup 4) (match_dup 5)) | |
1ca361fd | 4462 | (gtu:SI (reg:CCL2 CC_REGNUM) (const_int 0)))) |
4463 | (clobber (reg:CC CC_REGNUM))])] | |
12f61740 | 4464 | "operands[3] = operand_subword (operands[0], 0, 0, DImode); |
4465 | operands[4] = operand_subword (operands[1], 0, 0, DImode); | |
4466 | operands[5] = operand_subword (operands[2], 0, 0, DImode); | |
4467 | operands[6] = operand_subword (operands[0], 1, 0, DImode); | |
4468 | operands[7] = operand_subword (operands[1], 1, 0, DImode); | |
1822f0d6 | 4469 | operands[8] = operand_subword (operands[2], 1, 0, DImode);") |
12f61740 | 4470 | |
c6821d1c | 4471 | (define_insn_and_split "*subdi3_31" |
4472 | [(set (match_operand:DI 0 "register_operand" "=&d") | |
4473 | (minus:DI (match_operand:DI 1 "register_operand" "0") | |
37793c2d | 4474 | (match_operand:DI 2 "general_operand" "do") ) ) |
1ca361fd | 4475 | (clobber (reg:CC CC_REGNUM))] |
12f61740 | 4476 | "!TARGET_CPU_ZARCH" |
c6821d1c | 4477 | "#" |
4478 | "&& reload_completed" | |
4479 | [(parallel | |
4480 | [(set (match_dup 3) (minus:SI (match_dup 4) (match_dup 5))) | |
1ca361fd | 4481 | (clobber (reg:CC CC_REGNUM))]) |
c6821d1c | 4482 | (parallel |
1ca361fd | 4483 | [(set (reg:CCL2 CC_REGNUM) |
c6821d1c | 4484 | (compare:CCL2 (minus:SI (match_dup 7) (match_dup 8)) |
4485 | (match_dup 7))) | |
4486 | (set (match_dup 6) (minus:SI (match_dup 7) (match_dup 8)))]) | |
4487 | (set (pc) | |
1ca361fd | 4488 | (if_then_else (gtu (reg:CCL2 CC_REGNUM) (const_int 0)) |
c6821d1c | 4489 | (pc) |
4490 | (label_ref (match_dup 9)))) | |
4491 | (parallel | |
4492 | [(set (match_dup 3) (plus:SI (match_dup 3) (const_int -1))) | |
1ca361fd | 4493 | (clobber (reg:CC CC_REGNUM))]) |
c6821d1c | 4494 | (match_dup 9)] |
37793c2d | 4495 | "operands[3] = operand_subword (operands[0], 0, 0, DImode); |
4496 | operands[4] = operand_subword (operands[1], 0, 0, DImode); | |
4497 | operands[5] = operand_subword (operands[2], 0, 0, DImode); | |
4498 | operands[6] = operand_subword (operands[0], 1, 0, DImode); | |
4499 | operands[7] = operand_subword (operands[1], 1, 0, DImode); | |
4500 | operands[8] = operand_subword (operands[2], 1, 0, DImode); | |
1822f0d6 | 4501 | operands[9] = gen_label_rtx ();") |
c6821d1c | 4502 | |
d1641800 | 4503 | ; |
4504 | ; subsi3 instruction pattern(s). | |
4505 | ; | |
4506 | ||
4507 | (define_expand "subsi3" | |
c6821d1c | 4508 | [(parallel |
d1641800 | 4509 | [(set (match_operand:SI 0 "register_operand" "") |
4510 | (minus:SI (match_operand:SI 1 "register_operand" "") | |
4511 | (match_operand:SI 2 "general_operand" ""))) | |
1ca361fd | 4512 | (clobber (reg:CC CC_REGNUM))])] |
4673c1a0 | 4513 | "" |
c6821d1c | 4514 | "") |
4673c1a0 | 4515 | |
d1641800 | 4516 | (define_insn "*subsi3_sign" |
4517 | [(set (match_operand:SI 0 "register_operand" "=d,d") | |
4518 | (minus:SI (match_operand:SI 1 "register_operand" "0,0") | |
4519 | (sign_extend:SI (match_operand:HI 2 "memory_operand" "R,T")))) | |
4520 | (clobber (reg:CC CC_REGNUM))] | |
4521 | "" | |
4522 | "@ | |
4523 | sh\t%0,%2 | |
4524 | shy\t%0,%2" | |
4525 | [(set_attr "op_type" "RX,RXY")]) | |
4526 | ||
4673c1a0 | 4527 | ; |
d1641800 | 4528 | ; sub(di|si)3 instruction pattern(s). |
4673c1a0 | 4529 | ; |
4530 | ||
87bc9927 | 4531 | ; sr, s, sy, sgr, sg |
d1641800 | 4532 | (define_insn "*sub<mode>3" |
4533 | [(set (match_operand:GPR 0 "register_operand" "=d,d,d") | |
4534 | (minus:GPR (match_operand:GPR 1 "register_operand" "0,0,0") | |
4535 | (match_operand:GPR 2 "general_operand" "d,R,T") ) ) | |
4536 | (clobber (reg:CC CC_REGNUM))] | |
4537 | "" | |
4538 | "@ | |
4539 | s<g>r\t%0,%2 | |
4540 | s<g>\t%0,%2 | |
4541 | s<y>\t%0,%2" | |
4542 | [(set_attr "op_type" "RR<E>,RX<Y>,RXY")]) | |
4543 | ||
87bc9927 | 4544 | ; slr, sl, sly, slgr, slg |
d1641800 | 4545 | (define_insn "*sub<mode>3_borrow_cc" |
1ca361fd | 4546 | [(set (reg CC_REGNUM) |
d1641800 | 4547 | (compare (minus:GPR (match_operand:GPR 1 "register_operand" "0,0,0") |
4548 | (match_operand:GPR 2 "general_operand" "d,R,T")) | |
c6821d1c | 4549 | (match_dup 1))) |
d1641800 | 4550 | (set (match_operand:GPR 0 "register_operand" "=d,d,d") |
4551 | (minus:GPR (match_dup 1) (match_dup 2)))] | |
fcb93491 | 4552 | "s390_match_ccmode (insn, CCL2mode)" |
c6821d1c | 4553 | "@ |
d1641800 | 4554 | sl<g>r\t%0,%2 |
4555 | sl<g>\t%0,%2 | |
4556 | sl<y>\t%0,%2" | |
4557 | [(set_attr "op_type" "RR<E>,RX<Y>,RXY")]) | |
c6821d1c | 4558 | |
87bc9927 | 4559 | ; slr, sl, sly, slgr, slg |
d1641800 | 4560 | (define_insn "*sub<mode>3_borrow_cconly" |
1ca361fd | 4561 | [(set (reg CC_REGNUM) |
d1641800 | 4562 | (compare (minus:GPR (match_operand:GPR 1 "register_operand" "0,0,0") |
4563 | (match_operand:GPR 2 "general_operand" "d,R,T")) | |
c6821d1c | 4564 | (match_dup 1))) |
d1641800 | 4565 | (clobber (match_scratch:GPR 0 "=d,d,d"))] |
fcb93491 | 4566 | "s390_match_ccmode (insn, CCL2mode)" |
c6821d1c | 4567 | "@ |
d1641800 | 4568 | sl<g>r\t%0,%2 |
4569 | sl<g>\t%0,%2 | |
4570 | sl<y>\t%0,%2" | |
4571 | [(set_attr "op_type" "RR<E>,RX<Y>,RXY")]) | |
c6821d1c | 4572 | |
87bc9927 | 4573 | ; slr, sl, sly, slgr, slg |
d1641800 | 4574 | (define_insn "*sub<mode>3_cc" |
1ca361fd | 4575 | [(set (reg CC_REGNUM) |
d1641800 | 4576 | (compare (minus:GPR (match_operand:GPR 1 "register_operand" "0,0,0") |
4577 | (match_operand:GPR 2 "general_operand" "d,R,T")) | |
4673c1a0 | 4578 | (const_int 0))) |
d1641800 | 4579 | (set (match_operand:GPR 0 "register_operand" "=d,d,d") |
4580 | (minus:GPR (match_dup 1) (match_dup 2)))] | |
fcb93491 | 4581 | "s390_match_ccmode (insn, CCLmode)" |
4673c1a0 | 4582 | "@ |
d1641800 | 4583 | sl<g>r\t%0,%2 |
4584 | sl<g>\t%0,%2 | |
4585 | sl<y>\t%0,%2" | |
4586 | [(set_attr "op_type" "RR<E>,RX<Y>,RXY")]) | |
4673c1a0 | 4587 | |
87bc9927 | 4588 | ; slr, sl, sly, slgr, slg |
d1641800 | 4589 | (define_insn "*sub<mode>3_cc2" |
1ca361fd | 4590 | [(set (reg CC_REGNUM) |
d1641800 | 4591 | (compare (match_operand:GPR 1 "register_operand" "0,0,0") |
4592 | (match_operand:GPR 2 "general_operand" "d,R,T"))) | |
4593 | (set (match_operand:GPR 0 "register_operand" "=d,d,d") | |
4594 | (minus:GPR (match_dup 1) (match_dup 2)))] | |
3b699fc7 | 4595 | "s390_match_ccmode (insn, CCL3mode)" |
4596 | "@ | |
d1641800 | 4597 | sl<g>r\t%0,%2 |
4598 | sl<g>\t%0,%2 | |
4599 | sl<y>\t%0,%2" | |
4600 | [(set_attr "op_type" "RR<E>,RX<Y>,RXY")]) | |
3b699fc7 | 4601 | |
87bc9927 | 4602 | ; slr, sl, sly, slgr, slg |
d1641800 | 4603 | (define_insn "*sub<mode>3_cconly" |
1ca361fd | 4604 | [(set (reg CC_REGNUM) |
d1641800 | 4605 | (compare (minus:GPR (match_operand:GPR 1 "register_operand" "0,0,0") |
4606 | (match_operand:GPR 2 "general_operand" "d,R,T")) | |
4673c1a0 | 4607 | (const_int 0))) |
d1641800 | 4608 | (clobber (match_scratch:GPR 0 "=d,d,d"))] |
fcb93491 | 4609 | "s390_match_ccmode (insn, CCLmode)" |
4673c1a0 | 4610 | "@ |
d1641800 | 4611 | sl<g>r\t%0,%2 |
4612 | sl<g>\t%0,%2 | |
4613 | sl<y>\t%0,%2" | |
4614 | [(set_attr "op_type" "RR<E>,RX<Y>,RXY")]) | |
4673c1a0 | 4615 | |
87bc9927 | 4616 | ; slr, sl, sly, slgr, slg |
d1641800 | 4617 | (define_insn "*sub<mode>3_cconly2" |
1ca361fd | 4618 | [(set (reg CC_REGNUM) |
d1641800 | 4619 | (compare (match_operand:GPR 1 "register_operand" "0,0,0") |
4620 | (match_operand:GPR 2 "general_operand" "d,R,T"))) | |
4621 | (clobber (match_scratch:GPR 0 "=d,d,d"))] | |
3b699fc7 | 4622 | "s390_match_ccmode (insn, CCL3mode)" |
4623 | "@ | |
d1641800 | 4624 | sl<g>r\t%0,%2 |
4625 | sl<g>\t%0,%2 | |
4626 | sl<y>\t%0,%2" | |
4627 | [(set_attr "op_type" "RR<E>,RX<Y>,RXY")]) | |
4673c1a0 | 4628 | |
4629 | ; | |
1f8e70bc | 4630 | ; sub(tf|df|sf|td|dd)3 instruction pattern(s). |
4673c1a0 | 4631 | ; |
4632 | ||
1f8e70bc | 4633 | ; sxbr, sdbr, sebr, sxb, sdb, seb, sxtr, sdtr |
095798e3 | 4634 | (define_insn "sub<mode>3" |
1f8e70bc | 4635 | [(set (match_operand:FP 0 "register_operand" "=f, f") |
4636 | (minus:FP (match_operand:FP 1 "register_operand" "<f0>,0") | |
095798e3 | 4637 | (match_operand:FP 2 "general_operand" "f,<Rf>"))) |
1ca361fd | 4638 | (clobber (reg:CC CC_REGNUM))] |
095798e3 | 4639 | "TARGET_HARD_FLOAT" |
4673c1a0 | 4640 | "@ |
1f8e70bc | 4641 | s<xde><bt>r\t%0,<op1>%2 |
429f9fdb | 4642 | s<xde>b\t%0,%2" |
1f8e70bc | 4643 | [(set_attr "op_type" "<RRer>,RXE") |
4644 | (set_attr "type" "fsimp<bfp>")]) | |
4673c1a0 | 4645 | |
1f8e70bc | 4646 | ; sxbr, sdbr, sebr, sxb, sdb, seb, sxtr, sdtr |
8052065f | 4647 | (define_insn "*sub<mode>3_cc" |
1ca361fd | 4648 | [(set (reg CC_REGNUM) |
1f8e70bc | 4649 | (compare (minus:FP (match_operand:FP 1 "nonimmediate_operand" "<f0>,0") |
095798e3 | 4650 | (match_operand:FP 2 "general_operand" "f,<Rf>")) |
1f8e70bc | 4651 | (match_operand:FP 3 "const0_operand" ""))) |
4652 | (set (match_operand:FP 0 "register_operand" "=f,f") | |
4653 | (minus:FP (match_dup 1) (match_dup 2)))] | |
095798e3 | 4654 | "s390_match_ccmode (insn, CCSmode) && TARGET_HARD_FLOAT" |
e9fd5349 | 4655 | "@ |
1f8e70bc | 4656 | s<xde><bt>r\t%0,<op1>%2 |
429f9fdb | 4657 | s<xde>b\t%0,%2" |
1f8e70bc | 4658 | [(set_attr "op_type" "<RRer>,RXE") |
4659 | (set_attr "type" "fsimp<bfp>")]) | |
e9fd5349 | 4660 | |
1f8e70bc | 4661 | ; sxbr, sdbr, sebr, sxb, sdb, seb, sxtr, sdtr |
8052065f | 4662 | (define_insn "*sub<mode>3_cconly" |
1ca361fd | 4663 | [(set (reg CC_REGNUM) |
1f8e70bc | 4664 | (compare (minus:FP (match_operand:FP 1 "nonimmediate_operand" "<f0>,0") |
4665 | (match_operand:FP 2 "general_operand" "f,<Rf>")) | |
4666 | (match_operand:FP 3 "const0_operand" ""))) | |
4667 | (clobber (match_scratch:FP 0 "=f,f"))] | |
095798e3 | 4668 | "s390_match_ccmode (insn, CCSmode) && TARGET_HARD_FLOAT" |
e9fd5349 | 4669 | "@ |
1f8e70bc | 4670 | s<xde><bt>r\t%0,<op1>%2 |
429f9fdb | 4671 | s<xde>b\t%0,%2" |
1f8e70bc | 4672 | [(set_attr "op_type" "<RRer>,RXE") |
4673 | (set_attr "type" "fsimp<bfp>")]) | |
e9fd5349 | 4674 | |
4673c1a0 | 4675 | |
12f61740 | 4676 | ;; |
4677 | ;;- Conditional add/subtract instructions. | |
4678 | ;; | |
4679 | ||
4680 | ; | |
37af157c | 4681 | ; add(di|si)cc instruction pattern(s). |
12f61740 | 4682 | ; |
4683 | ||
1bdc56d2 | 4684 | ; the following 4 patterns are used when the result of an add with |
4685 | ; carry is checked for an overflow condition | |
4686 | ||
4687 | ; op1 + op2 + c < op1 | |
4688 | ||
4689 | ; alcr, alc, alcgr, alcg | |
4690 | (define_insn "*add<mode>3_alc_carry1_cc" | |
4691 | [(set (reg CC_REGNUM) | |
4692 | (compare | |
4693 | (plus:GPR (plus:GPR (match_operand:GPR 3 "s390_alc_comparison" "") | |
4694 | (match_operand:GPR 1 "nonimmediate_operand" "%0,0")) | |
8fe52251 | 4695 | (match_operand:GPR 2 "general_operand" "d,RT")) |
1bdc56d2 | 4696 | (match_dup 1))) |
4697 | (set (match_operand:GPR 0 "register_operand" "=d,d") | |
4698 | (plus:GPR (plus:GPR (match_dup 3) (match_dup 1)) (match_dup 2)))] | |
4699 | "s390_match_ccmode (insn, CCL1mode) && TARGET_CPU_ZARCH" | |
4700 | "@ | |
4701 | alc<g>r\t%0,%2 | |
4702 | alc<g>\t%0,%2" | |
4703 | [(set_attr "op_type" "RRE,RXY")]) | |
4704 | ||
4705 | ; alcr, alc, alcgr, alcg | |
4706 | (define_insn "*add<mode>3_alc_carry1_cconly" | |
4707 | [(set (reg CC_REGNUM) | |
4708 | (compare | |
4709 | (plus:GPR (plus:GPR (match_operand:GPR 3 "s390_alc_comparison" "") | |
4710 | (match_operand:GPR 1 "nonimmediate_operand" "%0,0")) | |
8fe52251 | 4711 | (match_operand:GPR 2 "general_operand" "d,RT")) |
1bdc56d2 | 4712 | (match_dup 1))) |
4713 | (clobber (match_scratch:GPR 0 "=d,d"))] | |
4714 | "s390_match_ccmode (insn, CCL1mode) && TARGET_CPU_ZARCH" | |
4715 | "@ | |
4716 | alc<g>r\t%0,%2 | |
4717 | alc<g>\t%0,%2" | |
4718 | [(set_attr "op_type" "RRE,RXY")]) | |
4719 | ||
4720 | ; op1 + op2 + c < op2 | |
4721 | ||
4722 | ; alcr, alc, alcgr, alcg | |
4723 | (define_insn "*add<mode>3_alc_carry2_cc" | |
4724 | [(set (reg CC_REGNUM) | |
4725 | (compare | |
4726 | (plus:GPR (plus:GPR (match_operand:GPR 3 "s390_alc_comparison" "") | |
4727 | (match_operand:GPR 1 "nonimmediate_operand" "%0,0")) | |
8fe52251 | 4728 | (match_operand:GPR 2 "general_operand" "d,RT")) |
1bdc56d2 | 4729 | (match_dup 2))) |
4730 | (set (match_operand:GPR 0 "register_operand" "=d,d") | |
4731 | (plus:GPR (plus:GPR (match_dup 3) (match_dup 1)) (match_dup 2)))] | |
4732 | "s390_match_ccmode (insn, CCL1mode) && TARGET_CPU_ZARCH" | |
4733 | "@ | |
4734 | alc<g>r\t%0,%2 | |
4735 | alc<g>\t%0,%2" | |
4736 | [(set_attr "op_type" "RRE,RXY")]) | |
4737 | ||
4738 | ; alcr, alc, alcgr, alcg | |
4739 | (define_insn "*add<mode>3_alc_carry2_cconly" | |
4740 | [(set (reg CC_REGNUM) | |
4741 | (compare | |
4742 | (plus:GPR (plus:GPR (match_operand:GPR 3 "s390_alc_comparison" "") | |
4743 | (match_operand:GPR 1 "nonimmediate_operand" "%0,0")) | |
8fe52251 | 4744 | (match_operand:GPR 2 "general_operand" "d,RT")) |
1bdc56d2 | 4745 | (match_dup 2))) |
4746 | (clobber (match_scratch:GPR 0 "=d,d"))] | |
4747 | "s390_match_ccmode (insn, CCL1mode) && TARGET_CPU_ZARCH" | |
4748 | "@ | |
4749 | alc<g>r\t%0,%2 | |
4750 | alc<g>\t%0,%2" | |
4751 | [(set_attr "op_type" "RRE,RXY")]) | |
4752 | ||
87bc9927 | 4753 | ; alcr, alc, alcgr, alcg |
37af157c | 4754 | (define_insn "*add<mode>3_alc_cc" |
1ca361fd | 4755 | [(set (reg CC_REGNUM) |
12f61740 | 4756 | (compare |
6f4afa7e | 4757 | (plus:GPR (plus:GPR (match_operand:GPR 3 "s390_alc_comparison" "") |
4758 | (match_operand:GPR 1 "nonimmediate_operand" "%0,0")) | |
8fe52251 | 4759 | (match_operand:GPR 2 "general_operand" "d,RT")) |
12f61740 | 4760 | (const_int 0))) |
37af157c | 4761 | (set (match_operand:GPR 0 "register_operand" "=d,d") |
6f4afa7e | 4762 | (plus:GPR (plus:GPR (match_dup 3) (match_dup 1)) (match_dup 2)))] |
346fecd5 | 4763 | "s390_match_ccmode (insn, CCLmode) && TARGET_CPU_ZARCH" |
12f61740 | 4764 | "@ |
37af157c | 4765 | alc<g>r\t%0,%2 |
4766 | alc<g>\t%0,%2" | |
12f61740 | 4767 | [(set_attr "op_type" "RRE,RXY")]) |
4768 | ||
87bc9927 | 4769 | ; alcr, alc, alcgr, alcg |
37af157c | 4770 | (define_insn "*add<mode>3_alc" |
4771 | [(set (match_operand:GPR 0 "register_operand" "=d,d") | |
6f4afa7e | 4772 | (plus:GPR (plus:GPR (match_operand:GPR 3 "s390_alc_comparison" "") |
4773 | (match_operand:GPR 1 "nonimmediate_operand" "%0,0")) | |
8fe52251 | 4774 | (match_operand:GPR 2 "general_operand" "d,RT"))) |
1ca361fd | 4775 | (clobber (reg:CC CC_REGNUM))] |
346fecd5 | 4776 | "TARGET_CPU_ZARCH" |
12f61740 | 4777 | "@ |
37af157c | 4778 | alc<g>r\t%0,%2 |
4779 | alc<g>\t%0,%2" | |
12f61740 | 4780 | [(set_attr "op_type" "RRE,RXY")]) |
4781 | ||
87bc9927 | 4782 | ; slbr, slb, slbgr, slbg |
37af157c | 4783 | (define_insn "*sub<mode>3_slb_cc" |
1ca361fd | 4784 | [(set (reg CC_REGNUM) |
12f61740 | 4785 | (compare |
37af157c | 4786 | (minus:GPR (minus:GPR (match_operand:GPR 1 "nonimmediate_operand" "0,0") |
8fe52251 | 4787 | (match_operand:GPR 2 "general_operand" "d,RT")) |
37af157c | 4788 | (match_operand:GPR 3 "s390_slb_comparison" "")) |
12f61740 | 4789 | (const_int 0))) |
37af157c | 4790 | (set (match_operand:GPR 0 "register_operand" "=d,d") |
4791 | (minus:GPR (minus:GPR (match_dup 1) (match_dup 2)) (match_dup 3)))] | |
346fecd5 | 4792 | "s390_match_ccmode (insn, CCLmode) && TARGET_CPU_ZARCH" |
12f61740 | 4793 | "@ |
37af157c | 4794 | slb<g>r\t%0,%2 |
4795 | slb<g>\t%0,%2" | |
12f61740 | 4796 | [(set_attr "op_type" "RRE,RXY")]) |
4797 | ||
87bc9927 | 4798 | ; slbr, slb, slbgr, slbg |
37af157c | 4799 | (define_insn "*sub<mode>3_slb" |
4800 | [(set (match_operand:GPR 0 "register_operand" "=d,d") | |
4801 | (minus:GPR (minus:GPR (match_operand:GPR 1 "nonimmediate_operand" "0,0") | |
8fe52251 | 4802 | (match_operand:GPR 2 "general_operand" "d,RT")) |
37af157c | 4803 | (match_operand:GPR 3 "s390_slb_comparison" ""))) |
1ca361fd | 4804 | (clobber (reg:CC CC_REGNUM))] |
346fecd5 | 4805 | "TARGET_CPU_ZARCH" |
12f61740 | 4806 | "@ |
37af157c | 4807 | slb<g>r\t%0,%2 |
4808 | slb<g>\t%0,%2" | |
12f61740 | 4809 | [(set_attr "op_type" "RRE,RXY")]) |
4810 | ||
37af157c | 4811 | (define_expand "add<mode>cc" |
4812 | [(match_operand:GPR 0 "register_operand" "") | |
3b699fc7 | 4813 | (match_operand 1 "comparison_operator" "") |
37af157c | 4814 | (match_operand:GPR 2 "register_operand" "") |
4815 | (match_operand:GPR 3 "const_int_operand" "")] | |
3b699fc7 | 4816 | "TARGET_CPU_ZARCH" |
4817 | "if (!s390_expand_addcc (GET_CODE (operands[1]), | |
4818 | s390_compare_op0, s390_compare_op1, | |
4819 | operands[0], operands[2], | |
4820 | operands[3])) FAIL; DONE;") | |
4821 | ||
4822 | ; | |
4823 | ; scond instruction pattern(s). | |
4824 | ; | |
4825 | ||
37af157c | 4826 | (define_insn_and_split "*scond<mode>" |
4827 | [(set (match_operand:GPR 0 "register_operand" "=&d") | |
4828 | (match_operand:GPR 1 "s390_alc_comparison" "")) | |
1ca361fd | 4829 | (clobber (reg:CC CC_REGNUM))] |
3b699fc7 | 4830 | "TARGET_CPU_ZARCH" |
4831 | "#" | |
4832 | "&& reload_completed" | |
4833 | [(set (match_dup 0) (const_int 0)) | |
4834 | (parallel | |
6f4afa7e | 4835 | [(set (match_dup 0) (plus:GPR (plus:GPR (match_dup 1) (match_dup 0)) |
4836 | (match_dup 0))) | |
1ca361fd | 4837 | (clobber (reg:CC CC_REGNUM))])] |
1822f0d6 | 4838 | "") |
3b699fc7 | 4839 | |
37af157c | 4840 | (define_insn_and_split "*scond<mode>_neg" |
4841 | [(set (match_operand:GPR 0 "register_operand" "=&d") | |
4842 | (match_operand:GPR 1 "s390_slb_comparison" "")) | |
1ca361fd | 4843 | (clobber (reg:CC CC_REGNUM))] |
3b699fc7 | 4844 | "TARGET_CPU_ZARCH" |
4845 | "#" | |
4846 | "&& reload_completed" | |
4847 | [(set (match_dup 0) (const_int 0)) | |
4848 | (parallel | |
37af157c | 4849 | [(set (match_dup 0) (minus:GPR (minus:GPR (match_dup 0) (match_dup 0)) |
4850 | (match_dup 1))) | |
1ca361fd | 4851 | (clobber (reg:CC CC_REGNUM))]) |
3b699fc7 | 4852 | (parallel |
37af157c | 4853 | [(set (match_dup 0) (neg:GPR (match_dup 0))) |
1ca361fd | 4854 | (clobber (reg:CC CC_REGNUM))])] |
1822f0d6 | 4855 | "") |
3b699fc7 | 4856 | |
3b699fc7 | 4857 | |
37af157c | 4858 | (define_expand "s<code>" |
4859 | [(set (match_operand:SI 0 "register_operand" "") | |
4860 | (SCOND (match_dup 0) | |
4861 | (match_dup 0)))] | |
3b699fc7 | 4862 | "TARGET_CPU_ZARCH" |
37af157c | 4863 | "if (!s390_expand_addcc (<CODE>, s390_compare_op0, s390_compare_op1, |
3b699fc7 | 4864 | operands[0], const0_rtx, const1_rtx)) FAIL; DONE;") |
4865 | ||
9c93d843 | 4866 | (define_expand "seq" |
4867 | [(parallel | |
4868 | [(set (match_operand:SI 0 "register_operand" "=d") | |
4869 | (match_dup 1)) | |
4870 | (clobber (reg:CC CC_REGNUM))]) | |
4871 | (parallel | |
4872 | [(set (match_dup 0) (xor:SI (match_dup 0) (const_int 1))) | |
4873 | (clobber (reg:CC CC_REGNUM))])] | |
4874 | "" | |
4875 | { | |
4876 | if (!s390_compare_emitted || GET_MODE (s390_compare_emitted) != CCZ1mode) | |
4877 | FAIL; | |
4878 | operands[1] = s390_emit_compare (NE, s390_compare_op0, s390_compare_op1); | |
4879 | PUT_MODE (operands[1], SImode); | |
4880 | }) | |
4881 | ||
4882 | (define_insn_and_split "*sne" | |
4883 | [(set (match_operand:SI 0 "register_operand" "=d") | |
4884 | (ne:SI (match_operand:CCZ1 1 "register_operand" "0") | |
4885 | (const_int 0))) | |
4886 | (clobber (reg:CC CC_REGNUM))] | |
4887 | "" | |
4888 | "#" | |
4889 | "reload_completed" | |
4890 | [(parallel | |
4891 | [(set (match_dup 0) (ashiftrt:SI (match_dup 0) (const_int 28))) | |
4892 | (clobber (reg:CC CC_REGNUM))])]) | |
4893 | ||
12f61740 | 4894 | |
4673c1a0 | 4895 | ;; |
4896 | ;;- Multiply instructions. | |
4897 | ;; | |
4898 | ||
8b4a4127 | 4899 | ; |
4900 | ; muldi3 instruction pattern(s). | |
4901 | ; | |
4673c1a0 | 4902 | |
c6821d1c | 4903 | (define_insn "*muldi3_sign" |
4904 | [(set (match_operand:DI 0 "register_operand" "=d,d") | |
e68d6a13 | 4905 | (mult:DI (sign_extend:DI (match_operand:SI 2 "general_operand" "d,RT")) |
c6821d1c | 4906 | (match_operand:DI 1 "register_operand" "0,0")))] |
4907 | "TARGET_64BIT" | |
4908 | "@ | |
f24d7ff3 | 4909 | msgfr\t%0,%2 |
4910 | msgf\t%0,%2" | |
e68d6a13 | 4911 | [(set_attr "op_type" "RRE,RXY") |
4912 | (set_attr "type" "imuldi")]) | |
c6821d1c | 4913 | |
8b4a4127 | 4914 | (define_insn "muldi3" |
e68d6a13 | 4915 | [(set (match_operand:DI 0 "register_operand" "=d,d,d,d") |
4916 | (mult:DI (match_operand:DI 1 "nonimmediate_operand" "%0,0,0,0") | |
4917 | (match_operand:DI 2 "general_operand" "d,K,RT,Os")))] | |
4673c1a0 | 4918 | "TARGET_64BIT" |
4919 | "@ | |
f24d7ff3 | 4920 | msgr\t%0,%2 |
4921 | mghi\t%0,%h2 | |
e68d6a13 | 4922 | msg\t%0,%2 |
4923 | msgfi\t%0,%2" | |
4924 | [(set_attr "op_type" "RRE,RI,RXY,RIL") | |
4925 | (set_attr "type" "imuldi") | |
4926 | (set_attr "cpu_facility" "*,*,*,z10")]) | |
369293ed | 4927 | |
4673c1a0 | 4928 | ; |
4929 | ; mulsi3 instruction pattern(s). | |
4930 | ; | |
4931 | ||
055b0bfa | 4932 | (define_insn "*mulsi3_sign" |
e68d6a13 | 4933 | [(set (match_operand:SI 0 "register_operand" "=d,d") |
4934 | (mult:SI (sign_extend:SI (match_operand:HI 2 "memory_operand" "R,T")) | |
4935 | (match_operand:SI 1 "register_operand" "0,0")))] | |
055b0bfa | 4936 | "" |
e68d6a13 | 4937 | "@ |
4938 | mh\t%0,%2 | |
4939 | mhy\t%0,%2" | |
4940 | [(set_attr "op_type" "RX,RXY") | |
4941 | (set_attr "type" "imulhi") | |
4942 | (set_attr "cpu_facility" "*,z10")]) | |
055b0bfa | 4943 | |
4673c1a0 | 4944 | (define_insn "mulsi3" |
e68d6a13 | 4945 | [(set (match_operand:SI 0 "register_operand" "=d,d,d,d,d") |
4946 | (mult:SI (match_operand:SI 1 "nonimmediate_operand" "%0,0,0,0,0") | |
4947 | (match_operand:SI 2 "general_operand" "d,K,R,T,Os")))] | |
4673c1a0 | 4948 | "" |
4949 | "@ | |
f24d7ff3 | 4950 | msr\t%0,%2 |
4951 | mhi\t%0,%h2 | |
4952 | ms\t%0,%2 | |
e68d6a13 | 4953 | msy\t%0,%2 |
4954 | msfi\t%0,%2" | |
4955 | [(set_attr "op_type" "RRE,RI,RX,RXY,RIL") | |
4956 | (set_attr "type" "imulsi,imulhi,imulsi,imulsi,imulsi") | |
4957 | (set_attr "cpu_facility" "*,*,*,*,z10")]) | |
4673c1a0 | 4958 | |
8b4a4127 | 4959 | ; |
4960 | ; mulsidi3 instruction pattern(s). | |
4961 | ; | |
4962 | ||
055b0bfa | 4963 | (define_insn "mulsidi3" |
e68d6a13 | 4964 | [(set (match_operand:DI 0 "register_operand" "=d,d,d") |
055b0bfa | 4965 | (mult:DI (sign_extend:DI |
e68d6a13 | 4966 | (match_operand:SI 1 "register_operand" "%0,0,0")) |
055b0bfa | 4967 | (sign_extend:DI |
e68d6a13 | 4968 | (match_operand:SI 2 "nonimmediate_operand" "d,R,T"))))] |
8b4a4127 | 4969 | "!TARGET_64BIT" |
055b0bfa | 4970 | "@ |
4971 | mr\t%0,%2 | |
e68d6a13 | 4972 | m\t%0,%2 |
4973 | mfy\t%0,%2" | |
4974 | [(set_attr "op_type" "RR,RX,RXY") | |
4975 | (set_attr "type" "imulsi") | |
4976 | (set_attr "cpu_facility" "*,*,z10")]) | |
8b4a4127 | 4977 | |
055b0bfa | 4978 | ; |
4979 | ; umulsidi3 instruction pattern(s). | |
4980 | ; | |
f81e845f | 4981 | |
055b0bfa | 4982 | (define_insn "umulsidi3" |
4983 | [(set (match_operand:DI 0 "register_operand" "=d,d") | |
4984 | (mult:DI (zero_extend:DI | |
4985 | (match_operand:SI 1 "register_operand" "%0,0")) | |
4986 | (zero_extend:DI | |
8fe52251 | 4987 | (match_operand:SI 2 "nonimmediate_operand" "d,RT"))))] |
055b0bfa | 4988 | "!TARGET_64BIT && TARGET_CPU_ZARCH" |
4989 | "@ | |
4990 | mlr\t%0,%2 | |
4991 | ml\t%0,%2" | |
4992 | [(set_attr "op_type" "RRE,RXY") | |
16ed459a | 4993 | (set_attr "type" "imulsi")]) |
f81e845f | 4994 | |
4673c1a0 | 4995 | ; |
1f8e70bc | 4996 | ; mul(tf|df|sf|td|dd)3 instruction pattern(s). |
4673c1a0 | 4997 | ; |
4998 | ||
1f8e70bc | 4999 | ; mxbr mdbr, meebr, mxb, mxb, meeb, mdtr, mxtr |
095798e3 | 5000 | (define_insn "mul<mode>3" |
1f8e70bc | 5001 | [(set (match_operand:FP 0 "register_operand" "=f,f") |
5002 | (mult:FP (match_operand:FP 1 "nonimmediate_operand" "%<f0>,0") | |
5003 | (match_operand:FP 2 "general_operand" "f,<Rf>")))] | |
095798e3 | 5004 | "TARGET_HARD_FLOAT" |
4673c1a0 | 5005 | "@ |
1f8e70bc | 5006 | m<xdee><bt>r\t%0,<op1>%2 |
429f9fdb | 5007 | m<xdee>b\t%0,%2" |
1f8e70bc | 5008 | [(set_attr "op_type" "<RRer>,RXE") |
5009 | (set_attr "type" "fmul<bfp>")]) | |
4673c1a0 | 5010 | |
87bc9927 | 5011 | ; maxbr, madbr, maebr, maxb, madb, maeb |
8052065f | 5012 | (define_insn "*fmadd<mode>" |
429f9fdb | 5013 | [(set (match_operand:DSF 0 "register_operand" "=f,f") |
5014 | (plus:DSF (mult:DSF (match_operand:DSF 1 "register_operand" "%f,f") | |
5015 | (match_operand:DSF 2 "nonimmediate_operand" "f,R")) | |
5016 | (match_operand:DSF 3 "register_operand" "0,0")))] | |
095798e3 | 5017 | "TARGET_HARD_FLOAT && TARGET_FUSED_MADD" |
3a71fe48 | 5018 | "@ |
429f9fdb | 5019 | ma<xde>br\t%0,%1,%2 |
5020 | ma<xde>b\t%0,%1,%2" | |
3a71fe48 | 5021 | [(set_attr "op_type" "RRE,RXE") |
8052065f | 5022 | (set_attr "type" "fmul<mode>")]) |
3a71fe48 | 5023 | |
87bc9927 | 5024 | ; msxbr, msdbr, msebr, msxb, msdb, mseb |
8052065f | 5025 | (define_insn "*fmsub<mode>" |
429f9fdb | 5026 | [(set (match_operand:DSF 0 "register_operand" "=f,f") |
5027 | (minus:DSF (mult:DSF (match_operand:DSF 1 "register_operand" "f,f") | |
5028 | (match_operand:DSF 2 "nonimmediate_operand" "f,R")) | |
5029 | (match_operand:DSF 3 "register_operand" "0,0")))] | |
095798e3 | 5030 | "TARGET_HARD_FLOAT && TARGET_FUSED_MADD" |
3a71fe48 | 5031 | "@ |
429f9fdb | 5032 | ms<xde>br\t%0,%1,%2 |
5033 | ms<xde>b\t%0,%1,%2" | |
9fa6d5d9 | 5034 | [(set_attr "op_type" "RRE,RXE") |
8052065f | 5035 | (set_attr "type" "fmul<mode>")]) |
4673c1a0 | 5036 | |
5037 | ;; | |
5038 | ;;- Divide and modulo instructions. | |
5039 | ;; | |
5040 | ||
5041 | ; | |
8b4a4127 | 5042 | ; divmoddi4 instruction pattern(s). |
4673c1a0 | 5043 | ; |
5044 | ||
8b4a4127 | 5045 | (define_expand "divmoddi4" |
5046 | [(parallel [(set (match_operand:DI 0 "general_operand" "") | |
055b0bfa | 5047 | (div:DI (match_operand:DI 1 "register_operand" "") |
8b4a4127 | 5048 | (match_operand:DI 2 "general_operand" ""))) |
5049 | (set (match_operand:DI 3 "general_operand" "") | |
5050 | (mod:DI (match_dup 1) (match_dup 2)))]) | |
5051 | (clobber (match_dup 4))] | |
4673c1a0 | 5052 | "TARGET_64BIT" |
4673c1a0 | 5053 | { |
055b0bfa | 5054 | rtx insn, div_equal, mod_equal; |
8b4a4127 | 5055 | |
5056 | div_equal = gen_rtx_DIV (DImode, operands[1], operands[2]); | |
5057 | mod_equal = gen_rtx_MOD (DImode, operands[1], operands[2]); | |
8b4a4127 | 5058 | |
5059 | operands[4] = gen_reg_rtx(TImode); | |
055b0bfa | 5060 | emit_insn (gen_divmodtidi3 (operands[4], operands[1], operands[2])); |
8b4a4127 | 5061 | |
5062 | insn = emit_move_insn (operands[0], gen_lowpart (DImode, operands[4])); | |
24153880 | 5063 | set_unique_reg_note (insn, REG_EQUAL, div_equal); |
8b4a4127 | 5064 | |
5065 | insn = emit_move_insn (operands[3], gen_highpart (DImode, operands[4])); | |
24153880 | 5066 | set_unique_reg_note (insn, REG_EQUAL, mod_equal); |
4673c1a0 | 5067 | |
4673c1a0 | 5068 | DONE; |
83e641bd | 5069 | }) |
4673c1a0 | 5070 | |
5071 | (define_insn "divmodtidi3" | |
8b4a4127 | 5072 | [(set (match_operand:TI 0 "register_operand" "=d,d") |
5073 | (ior:TI | |
8b4a4127 | 5074 | (ashift:TI |
5075 | (zero_extend:TI | |
e90f6093 | 5076 | (mod:DI (match_operand:DI 1 "register_operand" "0,0") |
8fe52251 | 5077 | (match_operand:DI 2 "general_operand" "d,RT"))) |
e90f6093 | 5078 | (const_int 64)) |
5079 | (zero_extend:TI (div:DI (match_dup 1) (match_dup 2)))))] | |
4673c1a0 | 5080 | "TARGET_64BIT" |
5081 | "@ | |
f24d7ff3 | 5082 | dsgr\t%0,%2 |
5083 | dsg\t%0,%2" | |
51aa1e9c | 5084 | [(set_attr "op_type" "RRE,RXY") |
71343e6b | 5085 | (set_attr "type" "idiv")]) |
4673c1a0 | 5086 | |
8b4a4127 | 5087 | (define_insn "divmodtisi3" |
5088 | [(set (match_operand:TI 0 "register_operand" "=d,d") | |
5089 | (ior:TI | |
8b4a4127 | 5090 | (ashift:TI |
5091 | (zero_extend:TI | |
e90f6093 | 5092 | (mod:DI (match_operand:DI 1 "register_operand" "0,0") |
346fecd5 | 5093 | (sign_extend:DI |
8fe52251 | 5094 | (match_operand:SI 2 "nonimmediate_operand" "d,RT")))) |
e90f6093 | 5095 | (const_int 64)) |
5096 | (zero_extend:TI | |
5097 | (div:DI (match_dup 1) (sign_extend:DI (match_dup 2))))))] | |
4673c1a0 | 5098 | "TARGET_64BIT" |
8b4a4127 | 5099 | "@ |
f24d7ff3 | 5100 | dsgfr\t%0,%2 |
5101 | dsgf\t%0,%2" | |
51aa1e9c | 5102 | [(set_attr "op_type" "RRE,RXY") |
71343e6b | 5103 | (set_attr "type" "idiv")]) |
4673c1a0 | 5104 | |
8b4a4127 | 5105 | ; |
5106 | ; udivmoddi4 instruction pattern(s). | |
5107 | ; | |
4673c1a0 | 5108 | |
8b4a4127 | 5109 | (define_expand "udivmoddi4" |
5110 | [(parallel [(set (match_operand:DI 0 "general_operand" "") | |
5111 | (udiv:DI (match_operand:DI 1 "general_operand" "") | |
5112 | (match_operand:DI 2 "nonimmediate_operand" ""))) | |
5113 | (set (match_operand:DI 3 "general_operand" "") | |
5114 | (umod:DI (match_dup 1) (match_dup 2)))]) | |
5115 | (clobber (match_dup 4))] | |
4673c1a0 | 5116 | "TARGET_64BIT" |
4673c1a0 | 5117 | { |
8b4a4127 | 5118 | rtx insn, div_equal, mod_equal, equal; |
5119 | ||
5120 | div_equal = gen_rtx_UDIV (DImode, operands[1], operands[2]); | |
5121 | mod_equal = gen_rtx_UMOD (DImode, operands[1], operands[2]); | |
5122 | equal = gen_rtx_IOR (TImode, | |
8b4a4127 | 5123 | gen_rtx_ASHIFT (TImode, |
5124 | gen_rtx_ZERO_EXTEND (TImode, mod_equal), | |
e90f6093 | 5125 | GEN_INT (64)), |
5126 | gen_rtx_ZERO_EXTEND (TImode, div_equal)); | |
8b4a4127 | 5127 | |
5128 | operands[4] = gen_reg_rtx(TImode); | |
18b42941 | 5129 | emit_clobber (operands[4]); |
8b4a4127 | 5130 | emit_move_insn (gen_lowpart (DImode, operands[4]), operands[1]); |
5131 | emit_move_insn (gen_highpart (DImode, operands[4]), const0_rtx); | |
24153880 | 5132 | |
8b4a4127 | 5133 | insn = emit_insn (gen_udivmodtidi3 (operands[4], operands[4], operands[2])); |
24153880 | 5134 | set_unique_reg_note (insn, REG_EQUAL, equal); |
8b4a4127 | 5135 | |
5136 | insn = emit_move_insn (operands[0], gen_lowpart (DImode, operands[4])); | |
24153880 | 5137 | set_unique_reg_note (insn, REG_EQUAL, div_equal); |
8b4a4127 | 5138 | |
5139 | insn = emit_move_insn (operands[3], gen_highpart (DImode, operands[4])); | |
24153880 | 5140 | set_unique_reg_note (insn, REG_EQUAL, mod_equal); |
4673c1a0 | 5141 | |
4673c1a0 | 5142 | DONE; |
83e641bd | 5143 | }) |
4673c1a0 | 5144 | |
5145 | (define_insn "udivmodtidi3" | |
8b4a4127 | 5146 | [(set (match_operand:TI 0 "register_operand" "=d,d") |
346fecd5 | 5147 | (ior:TI |
e90f6093 | 5148 | (ashift:TI |
5149 | (zero_extend:TI | |
5150 | (truncate:DI | |
346fecd5 | 5151 | (umod:TI (match_operand:TI 1 "register_operand" "0,0") |
5152 | (zero_extend:TI | |
8fe52251 | 5153 | (match_operand:DI 2 "nonimmediate_operand" "d,RT"))))) |
e90f6093 | 5154 | (const_int 64)) |
5155 | (zero_extend:TI | |
5156 | (truncate:DI | |
5157 | (udiv:TI (match_dup 1) (zero_extend:TI (match_dup 2)))))))] | |
4673c1a0 | 5158 | "TARGET_64BIT" |
5159 | "@ | |
f24d7ff3 | 5160 | dlgr\t%0,%2 |
5161 | dlg\t%0,%2" | |
51aa1e9c | 5162 | [(set_attr "op_type" "RRE,RXY") |
71343e6b | 5163 | (set_attr "type" "idiv")]) |
4673c1a0 | 5164 | |
5165 | ; | |
8b4a4127 | 5166 | ; divmodsi4 instruction pattern(s). |
4673c1a0 | 5167 | ; |
5168 | ||
8b4a4127 | 5169 | (define_expand "divmodsi4" |
5170 | [(parallel [(set (match_operand:SI 0 "general_operand" "") | |
5171 | (div:SI (match_operand:SI 1 "general_operand" "") | |
5172 | (match_operand:SI 2 "nonimmediate_operand" ""))) | |
5173 | (set (match_operand:SI 3 "general_operand" "") | |
5174 | (mod:SI (match_dup 1) (match_dup 2)))]) | |
5175 | (clobber (match_dup 4))] | |
4673c1a0 | 5176 | "!TARGET_64BIT" |
4673c1a0 | 5177 | { |
8b4a4127 | 5178 | rtx insn, div_equal, mod_equal, equal; |
5179 | ||
5180 | div_equal = gen_rtx_DIV (SImode, operands[1], operands[2]); | |
5181 | mod_equal = gen_rtx_MOD (SImode, operands[1], operands[2]); | |
5182 | equal = gen_rtx_IOR (DImode, | |
8b4a4127 | 5183 | gen_rtx_ASHIFT (DImode, |
5184 | gen_rtx_ZERO_EXTEND (DImode, mod_equal), | |
e90f6093 | 5185 | GEN_INT (32)), |
5186 | gen_rtx_ZERO_EXTEND (DImode, div_equal)); | |
8b4a4127 | 5187 | |
5188 | operands[4] = gen_reg_rtx(DImode); | |
5189 | emit_insn (gen_extendsidi2 (operands[4], operands[1])); | |
24153880 | 5190 | |
8b4a4127 | 5191 | insn = emit_insn (gen_divmoddisi3 (operands[4], operands[4], operands[2])); |
24153880 | 5192 | set_unique_reg_note (insn, REG_EQUAL, equal); |
8b4a4127 | 5193 | |
5194 | insn = emit_move_insn (operands[0], gen_lowpart (SImode, operands[4])); | |
24153880 | 5195 | set_unique_reg_note (insn, REG_EQUAL, div_equal); |
8b4a4127 | 5196 | |
5197 | insn = emit_move_insn (operands[3], gen_highpart (SImode, operands[4])); | |
24153880 | 5198 | set_unique_reg_note (insn, REG_EQUAL, mod_equal); |
4673c1a0 | 5199 | |
4673c1a0 | 5200 | DONE; |
83e641bd | 5201 | }) |
4673c1a0 | 5202 | |
5203 | (define_insn "divmoddisi3" | |
8b4a4127 | 5204 | [(set (match_operand:DI 0 "register_operand" "=d,d") |
346fecd5 | 5205 | (ior:DI |
e90f6093 | 5206 | (ashift:DI |
5207 | (zero_extend:DI | |
5208 | (truncate:SI | |
346fecd5 | 5209 | (mod:DI (match_operand:DI 1 "register_operand" "0,0") |
5210 | (sign_extend:DI | |
e90f6093 | 5211 | (match_operand:SI 2 "nonimmediate_operand" "d,R"))))) |
5212 | (const_int 32)) | |
5213 | (zero_extend:DI | |
5214 | (truncate:SI | |
5215 | (div:DI (match_dup 1) (sign_extend:DI (match_dup 2)))))))] | |
4673c1a0 | 5216 | "!TARGET_64BIT" |
5217 | "@ | |
f24d7ff3 | 5218 | dr\t%0,%2 |
5219 | d\t%0,%2" | |
4673c1a0 | 5220 | [(set_attr "op_type" "RR,RX") |
71343e6b | 5221 | (set_attr "type" "idiv")]) |
4673c1a0 | 5222 | |
5223 | ; | |
5224 | ; udivsi3 and umodsi3 instruction pattern(s). | |
5225 | ; | |
5226 | ||
055b0bfa | 5227 | (define_expand "udivmodsi4" |
5228 | [(parallel [(set (match_operand:SI 0 "general_operand" "") | |
5229 | (udiv:SI (match_operand:SI 1 "general_operand" "") | |
5230 | (match_operand:SI 2 "nonimmediate_operand" ""))) | |
5231 | (set (match_operand:SI 3 "general_operand" "") | |
5232 | (umod:SI (match_dup 1) (match_dup 2)))]) | |
5233 | (clobber (match_dup 4))] | |
5234 | "!TARGET_64BIT && TARGET_CPU_ZARCH" | |
5235 | { | |
5236 | rtx insn, div_equal, mod_equal, equal; | |
5237 | ||
5238 | div_equal = gen_rtx_UDIV (SImode, operands[1], operands[2]); | |
5239 | mod_equal = gen_rtx_UMOD (SImode, operands[1], operands[2]); | |
5240 | equal = gen_rtx_IOR (DImode, | |
055b0bfa | 5241 | gen_rtx_ASHIFT (DImode, |
5242 | gen_rtx_ZERO_EXTEND (DImode, mod_equal), | |
e90f6093 | 5243 | GEN_INT (32)), |
5244 | gen_rtx_ZERO_EXTEND (DImode, div_equal)); | |
055b0bfa | 5245 | |
5246 | operands[4] = gen_reg_rtx(DImode); | |
18b42941 | 5247 | emit_clobber (operands[4]); |
055b0bfa | 5248 | emit_move_insn (gen_lowpart (SImode, operands[4]), operands[1]); |
5249 | emit_move_insn (gen_highpart (SImode, operands[4]), const0_rtx); | |
24153880 | 5250 | |
055b0bfa | 5251 | insn = emit_insn (gen_udivmoddisi3 (operands[4], operands[4], operands[2])); |
24153880 | 5252 | set_unique_reg_note (insn, REG_EQUAL, equal); |
055b0bfa | 5253 | |
5254 | insn = emit_move_insn (operands[0], gen_lowpart (SImode, operands[4])); | |
24153880 | 5255 | set_unique_reg_note (insn, REG_EQUAL, div_equal); |
055b0bfa | 5256 | |
5257 | insn = emit_move_insn (operands[3], gen_highpart (SImode, operands[4])); | |
24153880 | 5258 | set_unique_reg_note (insn, REG_EQUAL, mod_equal); |
055b0bfa | 5259 | |
5260 | DONE; | |
5261 | }) | |
5262 | ||
5263 | (define_insn "udivmoddisi3" | |
5264 | [(set (match_operand:DI 0 "register_operand" "=d,d") | |
346fecd5 | 5265 | (ior:DI |
e90f6093 | 5266 | (ashift:DI |
5267 | (zero_extend:DI | |
5268 | (truncate:SI | |
346fecd5 | 5269 | (umod:DI (match_operand:DI 1 "register_operand" "0,0") |
5270 | (zero_extend:DI | |
8fe52251 | 5271 | (match_operand:SI 2 "nonimmediate_operand" "d,RT"))))) |
e90f6093 | 5272 | (const_int 32)) |
5273 | (zero_extend:DI | |
5274 | (truncate:SI | |
5275 | (udiv:DI (match_dup 1) (zero_extend:DI (match_dup 2)))))))] | |
055b0bfa | 5276 | "!TARGET_64BIT && TARGET_CPU_ZARCH" |
5277 | "@ | |
5278 | dlr\t%0,%2 | |
5279 | dl\t%0,%2" | |
5280 | [(set_attr "op_type" "RRE,RXY") | |
5281 | (set_attr "type" "idiv")]) | |
8b4a4127 | 5282 | |
4673c1a0 | 5283 | (define_expand "udivsi3" |
5284 | [(set (match_operand:SI 0 "register_operand" "=d") | |
5285 | (udiv:SI (match_operand:SI 1 "general_operand" "") | |
8b4a4127 | 5286 | (match_operand:SI 2 "general_operand" ""))) |
5287 | (clobber (match_dup 3))] | |
055b0bfa | 5288 | "!TARGET_64BIT && !TARGET_CPU_ZARCH" |
4673c1a0 | 5289 | { |
8b4a4127 | 5290 | rtx insn, udiv_equal, umod_equal, equal; |
5291 | ||
5292 | udiv_equal = gen_rtx_UDIV (SImode, operands[1], operands[2]); | |
5293 | umod_equal = gen_rtx_UMOD (SImode, operands[1], operands[2]); | |
5294 | equal = gen_rtx_IOR (DImode, | |
8b4a4127 | 5295 | gen_rtx_ASHIFT (DImode, |
5296 | gen_rtx_ZERO_EXTEND (DImode, umod_equal), | |
e90f6093 | 5297 | GEN_INT (32)), |
5298 | gen_rtx_ZERO_EXTEND (DImode, udiv_equal)); | |
4673c1a0 | 5299 | |
8b4a4127 | 5300 | operands[3] = gen_reg_rtx (DImode); |
4673c1a0 | 5301 | |
5302 | if (CONSTANT_P (operands[2])) | |
5303 | { | |
5304 | if (GET_CODE (operands[2]) == CONST_INT && INTVAL (operands[2]) < 0) | |
5305 | { | |
5306 | rtx label1 = gen_label_rtx (); | |
5307 | ||
8b4a4127 | 5308 | operands[1] = make_safe_from (operands[1], operands[0]); |
5309 | emit_move_insn (operands[0], const0_rtx); | |
5310 | emit_insn (gen_cmpsi (operands[1], operands[2])); | |
4673c1a0 | 5311 | emit_jump_insn (gen_bltu (label1)); |
8b4a4127 | 5312 | emit_move_insn (operands[0], const1_rtx); |
4673c1a0 | 5313 | emit_label (label1); |
5314 | } | |
5315 | else | |
5316 | { | |
f81e845f | 5317 | operands[2] = force_reg (SImode, operands[2]); |
5318 | operands[2] = make_safe_from (operands[2], operands[0]); | |
8b4a4127 | 5319 | |
5320 | emit_insn (gen_zero_extendsidi2 (operands[3], operands[1])); | |
5321 | insn = emit_insn (gen_divmoddisi3 (operands[3], operands[3], | |
5322 | operands[2])); | |
24153880 | 5323 | set_unique_reg_note (insn, REG_EQUAL, equal); |
f81e845f | 5324 | |
5325 | insn = emit_move_insn (operands[0], | |
8b4a4127 | 5326 | gen_lowpart (SImode, operands[3])); |
24153880 | 5327 | set_unique_reg_note (insn, REG_EQUAL, udiv_equal); |
4673c1a0 | 5328 | } |
5329 | } | |
5330 | else | |
f81e845f | 5331 | { |
4673c1a0 | 5332 | rtx label1 = gen_label_rtx (); |
5333 | rtx label2 = gen_label_rtx (); | |
5334 | rtx label3 = gen_label_rtx (); | |
5335 | ||
f81e845f | 5336 | operands[1] = force_reg (SImode, operands[1]); |
5337 | operands[1] = make_safe_from (operands[1], operands[0]); | |
5338 | operands[2] = force_reg (SImode, operands[2]); | |
5339 | operands[2] = make_safe_from (operands[2], operands[0]); | |
8b4a4127 | 5340 | |
5341 | emit_move_insn (operands[0], const0_rtx); | |
4673c1a0 | 5342 | emit_insn (gen_cmpsi (operands[2], operands[1])); |
5343 | emit_jump_insn (gen_bgtu (label3)); | |
19aafaaf | 5344 | emit_insn (gen_cmpsi (operands[2], const0_rtx)); |
4673c1a0 | 5345 | emit_jump_insn (gen_blt (label2)); |
5346 | emit_insn (gen_cmpsi (operands[2], const1_rtx)); | |
5347 | emit_jump_insn (gen_beq (label1)); | |
8b4a4127 | 5348 | emit_insn (gen_zero_extendsidi2 (operands[3], operands[1])); |
5349 | insn = emit_insn (gen_divmoddisi3 (operands[3], operands[3], | |
5350 | operands[2])); | |
24153880 | 5351 | set_unique_reg_note (insn, REG_EQUAL, equal); |
f81e845f | 5352 | |
5353 | insn = emit_move_insn (operands[0], | |
8b4a4127 | 5354 | gen_lowpart (SImode, operands[3])); |
24153880 | 5355 | set_unique_reg_note (insn, REG_EQUAL, udiv_equal); |
5356 | ||
0c0a8ea5 | 5357 | emit_jump (label3); |
4673c1a0 | 5358 | emit_label (label1); |
8b4a4127 | 5359 | emit_move_insn (operands[0], operands[1]); |
0c0a8ea5 | 5360 | emit_jump (label3); |
4673c1a0 | 5361 | emit_label (label2); |
8b4a4127 | 5362 | emit_move_insn (operands[0], const1_rtx); |
4673c1a0 | 5363 | emit_label (label3); |
5364 | } | |
f81e845f | 5365 | emit_move_insn (operands[0], operands[0]); |
4673c1a0 | 5366 | DONE; |
83e641bd | 5367 | }) |
4673c1a0 | 5368 | |
5369 | (define_expand "umodsi3" | |
5370 | [(set (match_operand:SI 0 "register_operand" "=d") | |
5371 | (umod:SI (match_operand:SI 1 "nonimmediate_operand" "") | |
8b4a4127 | 5372 | (match_operand:SI 2 "nonimmediate_operand" ""))) |
5373 | (clobber (match_dup 3))] | |
055b0bfa | 5374 | "!TARGET_64BIT && !TARGET_CPU_ZARCH" |
4673c1a0 | 5375 | { |
8b4a4127 | 5376 | rtx insn, udiv_equal, umod_equal, equal; |
5377 | ||
5378 | udiv_equal = gen_rtx_UDIV (SImode, operands[1], operands[2]); | |
5379 | umod_equal = gen_rtx_UMOD (SImode, operands[1], operands[2]); | |
5380 | equal = gen_rtx_IOR (DImode, | |
8b4a4127 | 5381 | gen_rtx_ASHIFT (DImode, |
5382 | gen_rtx_ZERO_EXTEND (DImode, umod_equal), | |
e90f6093 | 5383 | GEN_INT (32)), |
5384 | gen_rtx_ZERO_EXTEND (DImode, udiv_equal)); | |
4673c1a0 | 5385 | |
8b4a4127 | 5386 | operands[3] = gen_reg_rtx (DImode); |
4673c1a0 | 5387 | |
5388 | if (CONSTANT_P (operands[2])) | |
5389 | { | |
5390 | if (GET_CODE (operands[2]) == CONST_INT && INTVAL (operands[2]) <= 0) | |
5391 | { | |
5392 | rtx label1 = gen_label_rtx (); | |
5393 | ||
8b4a4127 | 5394 | operands[1] = make_safe_from (operands[1], operands[0]); |
5395 | emit_move_insn (operands[0], operands[1]); | |
5396 | emit_insn (gen_cmpsi (operands[0], operands[2])); | |
4673c1a0 | 5397 | emit_jump_insn (gen_bltu (label1)); |
8b4a4127 | 5398 | emit_insn (gen_abssi2 (operands[0], operands[2])); |
5399 | emit_insn (gen_addsi3 (operands[0], operands[0], operands[1])); | |
4673c1a0 | 5400 | emit_label (label1); |
5401 | } | |
5402 | else | |
5403 | { | |
f81e845f | 5404 | operands[2] = force_reg (SImode, operands[2]); |
5405 | operands[2] = make_safe_from (operands[2], operands[0]); | |
8b4a4127 | 5406 | |
5407 | emit_insn (gen_zero_extendsidi2 (operands[3], operands[1])); | |
5408 | insn = emit_insn (gen_divmoddisi3 (operands[3], operands[3], | |
5409 | operands[2])); | |
24153880 | 5410 | set_unique_reg_note (insn, REG_EQUAL, equal); |
f81e845f | 5411 | |
5412 | insn = emit_move_insn (operands[0], | |
8b4a4127 | 5413 | gen_highpart (SImode, operands[3])); |
24153880 | 5414 | set_unique_reg_note (insn, REG_EQUAL, umod_equal); |
4673c1a0 | 5415 | } |
5416 | } | |
5417 | else | |
5418 | { | |
5419 | rtx label1 = gen_label_rtx (); | |
5420 | rtx label2 = gen_label_rtx (); | |
5421 | rtx label3 = gen_label_rtx (); | |
5422 | ||
f81e845f | 5423 | operands[1] = force_reg (SImode, operands[1]); |
5424 | operands[1] = make_safe_from (operands[1], operands[0]); | |
5425 | operands[2] = force_reg (SImode, operands[2]); | |
5426 | operands[2] = make_safe_from (operands[2], operands[0]); | |
4673c1a0 | 5427 | |
f81e845f | 5428 | emit_move_insn(operands[0], operands[1]); |
8b4a4127 | 5429 | emit_insn (gen_cmpsi (operands[2], operands[1])); |
4673c1a0 | 5430 | emit_jump_insn (gen_bgtu (label3)); |
19aafaaf | 5431 | emit_insn (gen_cmpsi (operands[2], const0_rtx)); |
4673c1a0 | 5432 | emit_jump_insn (gen_blt (label2)); |
5433 | emit_insn (gen_cmpsi (operands[2], const1_rtx)); | |
5434 | emit_jump_insn (gen_beq (label1)); | |
8b4a4127 | 5435 | emit_insn (gen_zero_extendsidi2 (operands[3], operands[1])); |
5436 | insn = emit_insn (gen_divmoddisi3 (operands[3], operands[3], | |
5437 | operands[2])); | |
24153880 | 5438 | set_unique_reg_note (insn, REG_EQUAL, equal); |
f81e845f | 5439 | |
5440 | insn = emit_move_insn (operands[0], | |
8b4a4127 | 5441 | gen_highpart (SImode, operands[3])); |
24153880 | 5442 | set_unique_reg_note (insn, REG_EQUAL, umod_equal); |
5443 | ||
0c0a8ea5 | 5444 | emit_jump (label3); |
4673c1a0 | 5445 | emit_label (label1); |
8b4a4127 | 5446 | emit_move_insn (operands[0], const0_rtx); |
0c0a8ea5 | 5447 | emit_jump (label3); |
4673c1a0 | 5448 | emit_label (label2); |
8b4a4127 | 5449 | emit_insn (gen_subsi3 (operands[0], operands[0], operands[2])); |
4673c1a0 | 5450 | emit_label (label3); |
5451 | } | |
4673c1a0 | 5452 | DONE; |
83e641bd | 5453 | }) |
4673c1a0 | 5454 | |
5455 | ; | |
8052065f | 5456 | ; div(df|sf)3 instruction pattern(s). |
4673c1a0 | 5457 | ; |
5458 | ||
1f8e70bc | 5459 | ; dxbr, ddbr, debr, dxb, ddb, deb, ddtr, dxtr |
095798e3 | 5460 | (define_insn "div<mode>3" |
1f8e70bc | 5461 | [(set (match_operand:FP 0 "register_operand" "=f,f") |
5462 | (div:FP (match_operand:FP 1 "register_operand" "<f0>,0") | |
5463 | (match_operand:FP 2 "general_operand" "f,<Rf>")))] | |
095798e3 | 5464 | "TARGET_HARD_FLOAT" |
4673c1a0 | 5465 | "@ |
1f8e70bc | 5466 | d<xde><bt>r\t%0,<op1>%2 |
429f9fdb | 5467 | d<xde>b\t%0,%2" |
1f8e70bc | 5468 | [(set_attr "op_type" "<RRer>,RXE") |
5469 | (set_attr "type" "fdiv<bfp>")]) | |
4673c1a0 | 5470 | |
4673c1a0 | 5471 | |
5472 | ;; | |
5473 | ;;- And instructions. | |
5474 | ;; | |
5475 | ||
8f446608 | 5476 | (define_expand "and<mode>3" |
5477 | [(set (match_operand:INT 0 "nonimmediate_operand" "") | |
5478 | (and:INT (match_operand:INT 1 "nonimmediate_operand" "") | |
5479 | (match_operand:INT 2 "general_operand" ""))) | |
5480 | (clobber (reg:CC CC_REGNUM))] | |
5481 | "" | |
5482 | "s390_expand_logical_operator (AND, <MODE>mode, operands); DONE;") | |
5483 | ||
4673c1a0 | 5484 | ; |
5485 | ; anddi3 instruction pattern(s). | |
5486 | ; | |
5487 | ||
5488 | (define_insn "*anddi3_cc" | |
1ca361fd | 5489 | [(set (reg CC_REGNUM) |
7c3aefa0 | 5490 | (compare (and:DI (match_operand:DI 1 "nonimmediate_operand" "%0,0") |
8fe52251 | 5491 | (match_operand:DI 2 "general_operand" "d,RT")) |
4673c1a0 | 5492 | (const_int 0))) |
8b4a4127 | 5493 | (set (match_operand:DI 0 "register_operand" "=d,d") |
4673c1a0 | 5494 | (and:DI (match_dup 1) (match_dup 2)))] |
5495 | "s390_match_ccmode(insn, CCTmode) && TARGET_64BIT" | |
5496 | "@ | |
f24d7ff3 | 5497 | ngr\t%0,%2 |
5498 | ng\t%0,%2" | |
51aa1e9c | 5499 | [(set_attr "op_type" "RRE,RXY")]) |
4673c1a0 | 5500 | |
5501 | (define_insn "*anddi3_cconly" | |
1ca361fd | 5502 | [(set (reg CC_REGNUM) |
7c3aefa0 | 5503 | (compare (and:DI (match_operand:DI 1 "nonimmediate_operand" "%0,0") |
8fe52251 | 5504 | (match_operand:DI 2 "general_operand" "d,RT")) |
4673c1a0 | 5505 | (const_int 0))) |
5506 | (clobber (match_scratch:DI 0 "=d,d"))] | |
ebe32bb0 | 5507 | "s390_match_ccmode(insn, CCTmode) && TARGET_64BIT |
5508 | /* Do not steal TM patterns. */ | |
5509 | && s390_single_part (operands[2], DImode, HImode, 0) < 0" | |
4673c1a0 | 5510 | "@ |
f24d7ff3 | 5511 | ngr\t%0,%2 |
5512 | ng\t%0,%2" | |
51aa1e9c | 5513 | [(set_attr "op_type" "RRE,RXY")]) |
4673c1a0 | 5514 | |
562d1970 | 5515 | (define_insn "*anddi3" |
163277cf | 5516 | [(set (match_operand:DI 0 "nonimmediate_operand" "=d,d,d,d,d,d,d,d,d,d,AQ,Q") |
5517 | (and:DI (match_operand:DI 1 "nonimmediate_operand" | |
5518 | "%d,o,0,0,0,0,0,0,0,0,0,0") | |
5519 | (match_operand:DI 2 "general_operand" | |
8fe52251 | 5520 | "M,M,N0HDF,N1HDF,N2HDF,N3HDF,N0SDF,N1SDF,d,RT,NxQDF,Q"))) |
163277cf | 5521 | (clobber (reg:CC CC_REGNUM))] |
562d1970 | 5522 | "TARGET_64BIT && s390_logical_operator_ok_p (operands)" |
163277cf | 5523 | "@ |
5524 | # | |
5525 | # | |
5526 | nihh\t%0,%j2 | |
5527 | nihl\t%0,%j2 | |
5528 | nilh\t%0,%j2 | |
5529 | nill\t%0,%j2 | |
5530 | nihf\t%0,%m2 | |
5531 | nilf\t%0,%m2 | |
5532 | ngr\t%0,%2 | |
5533 | ng\t%0,%2 | |
5534 | # | |
5535 | #" | |
562d1970 | 5536 | [(set_attr "op_type" "RRE,RXE,RI,RI,RI,RI,RIL,RIL,RRE,RXY,SI,SS") |
5537 | (set_attr "cpu_facility" "*,*,*,*,*,*,extimm,extimm,*,*,*,*")]) | |
3f56e755 | 5538 | |
5539 | (define_split | |
5540 | [(set (match_operand:DI 0 "s_operand" "") | |
5541 | (and:DI (match_dup 0) (match_operand:DI 1 "immediate_operand" ""))) | |
1ca361fd | 5542 | (clobber (reg:CC CC_REGNUM))] |
3f56e755 | 5543 | "reload_completed" |
5544 | [(parallel | |
5545 | [(set (match_dup 0) (and:QI (match_dup 0) (match_dup 1))) | |
1ca361fd | 5546 | (clobber (reg:CC CC_REGNUM))])] |
3f56e755 | 5547 | "s390_narrow_logical_operator (AND, &operands[0], &operands[1]);") |
8b4a4127 | 5548 | |
4673c1a0 | 5549 | |
5550 | ; | |
5551 | ; andsi3 instruction pattern(s). | |
5552 | ; | |
5553 | ||
5554 | (define_insn "*andsi3_cc" | |
1ca361fd | 5555 | [(set (reg CC_REGNUM) |
163277cf | 5556 | (compare (and:SI (match_operand:SI 1 "nonimmediate_operand" "%0,0,0,0") |
5557 | (match_operand:SI 2 "general_operand" "Os,d,R,T")) | |
4673c1a0 | 5558 | (const_int 0))) |
163277cf | 5559 | (set (match_operand:SI 0 "register_operand" "=d,d,d,d") |
4673c1a0 | 5560 | (and:SI (match_dup 1) (match_dup 2)))] |
5561 | "s390_match_ccmode(insn, CCTmode)" | |
5562 | "@ | |
163277cf | 5563 | nilf\t%0,%o2 |
f24d7ff3 | 5564 | nr\t%0,%2 |
5565 | n\t%0,%2 | |
5566 | ny\t%0,%2" | |
163277cf | 5567 | [(set_attr "op_type" "RIL,RR,RX,RXY")]) |
4673c1a0 | 5568 | |
5569 | (define_insn "*andsi3_cconly" | |
1ca361fd | 5570 | [(set (reg CC_REGNUM) |
163277cf | 5571 | (compare (and:SI (match_operand:SI 1 "nonimmediate_operand" "%0,0,0,0") |
5572 | (match_operand:SI 2 "general_operand" "Os,d,R,T")) | |
4673c1a0 | 5573 | (const_int 0))) |
163277cf | 5574 | (clobber (match_scratch:SI 0 "=d,d,d,d"))] |
ebe32bb0 | 5575 | "s390_match_ccmode(insn, CCTmode) |
5576 | /* Do not steal TM patterns. */ | |
5577 | && s390_single_part (operands[2], SImode, HImode, 0) < 0" | |
4673c1a0 | 5578 | "@ |
163277cf | 5579 | nilf\t%0,%o2 |
f24d7ff3 | 5580 | nr\t%0,%2 |
5581 | n\t%0,%2 | |
5582 | ny\t%0,%2" | |
163277cf | 5583 | [(set_attr "op_type" "RIL,RR,RX,RXY")]) |
4673c1a0 | 5584 | |
64a1078f | 5585 | (define_insn "*andsi3_zarch" |
163277cf | 5586 | [(set (match_operand:SI 0 "nonimmediate_operand" "=d,d,d,d,d,d,d,d,AQ,Q") |
3f56e755 | 5587 | (and:SI (match_operand:SI 1 "nonimmediate_operand" |
163277cf | 5588 | "%d,o,0,0,0,0,0,0,0,0") |
3f56e755 | 5589 | (match_operand:SI 2 "general_operand" |
163277cf | 5590 | "M,M,N0HSF,N1HSF,Os,d,R,T,NxQSF,Q"))) |
1ca361fd | 5591 | (clobber (reg:CC CC_REGNUM))] |
3e247a31 | 5592 | "TARGET_ZARCH && s390_logical_operator_ok_p (operands)" |
4673c1a0 | 5593 | "@ |
64a1078f | 5594 | # |
5595 | # | |
5596 | nilh\t%0,%j2 | |
346fecd5 | 5597 | nill\t%0,%j2 |
163277cf | 5598 | nilf\t%0,%o2 |
f24d7ff3 | 5599 | nr\t%0,%2 |
5600 | n\t%0,%2 | |
3e247a31 | 5601 | ny\t%0,%2 |
3f56e755 | 5602 | # |
9dffd3ff | 5603 | #" |
163277cf | 5604 | [(set_attr "op_type" "RRE,RXE,RI,RI,RIL,RR,RX,RXY,SI,SS")]) |
64a1078f | 5605 | |
5606 | (define_insn "*andsi3_esa" | |
3f56e755 | 5607 | [(set (match_operand:SI 0 "nonimmediate_operand" "=d,d,AQ,Q") |
5608 | (and:SI (match_operand:SI 1 "nonimmediate_operand" "%0,0,0,0") | |
5609 | (match_operand:SI 2 "general_operand" "d,R,NxQSF,Q"))) | |
1ca361fd | 5610 | (clobber (reg:CC CC_REGNUM))] |
3e247a31 | 5611 | "!TARGET_ZARCH && s390_logical_operator_ok_p (operands)" |
64a1078f | 5612 | "@ |
5613 | nr\t%0,%2 | |
3e247a31 | 5614 | n\t%0,%2 |
3f56e755 | 5615 | # |
9dffd3ff | 5616 | #" |
3f56e755 | 5617 | [(set_attr "op_type" "RR,RX,SI,SS")]) |
5618 | ||
5619 | (define_split | |
5620 | [(set (match_operand:SI 0 "s_operand" "") | |
5621 | (and:SI (match_dup 0) (match_operand:SI 1 "immediate_operand" ""))) | |
1ca361fd | 5622 | (clobber (reg:CC CC_REGNUM))] |
3f56e755 | 5623 | "reload_completed" |
5624 | [(parallel | |
5625 | [(set (match_dup 0) (and:QI (match_dup 0) (match_dup 1))) | |
1ca361fd | 5626 | (clobber (reg:CC CC_REGNUM))])] |
3f56e755 | 5627 | "s390_narrow_logical_operator (AND, &operands[0], &operands[1]);") |
8b4a4127 | 5628 | |
4673c1a0 | 5629 | ; |
5630 | ; andhi3 instruction pattern(s). | |
5631 | ; | |
5632 | ||
3e247a31 | 5633 | (define_insn "*andhi3_zarch" |
3f56e755 | 5634 | [(set (match_operand:HI 0 "nonimmediate_operand" "=d,d,AQ,Q") |
5635 | (and:HI (match_operand:HI 1 "nonimmediate_operand" "%0,0,0,0") | |
5636 | (match_operand:HI 2 "general_operand" "d,n,NxQHF,Q"))) | |
1ca361fd | 5637 | (clobber (reg:CC CC_REGNUM))] |
3e247a31 | 5638 | "TARGET_ZARCH && s390_logical_operator_ok_p (operands)" |
8b4a4127 | 5639 | "@ |
f24d7ff3 | 5640 | nr\t%0,%2 |
3e247a31 | 5641 | nill\t%0,%x2 |
3f56e755 | 5642 | # |
9dffd3ff | 5643 | #" |
3f56e755 | 5644 | [(set_attr "op_type" "RR,RI,SI,SS")]) |
3e247a31 | 5645 | |
5646 | (define_insn "*andhi3_esa" | |
3f56e755 | 5647 | [(set (match_operand:HI 0 "nonimmediate_operand" "=d,AQ,Q") |
5648 | (and:HI (match_operand:HI 1 "nonimmediate_operand" "%0,0,0") | |
5649 | (match_operand:HI 2 "general_operand" "d,NxQHF,Q"))) | |
1ca361fd | 5650 | (clobber (reg:CC CC_REGNUM))] |
3e247a31 | 5651 | "!TARGET_ZARCH && s390_logical_operator_ok_p (operands)" |
5652 | "@ | |
5653 | nr\t%0,%2 | |
3f56e755 | 5654 | # |
9dffd3ff | 5655 | #" |
3f56e755 | 5656 | [(set_attr "op_type" "RR,SI,SS")]) |
5657 | ||
5658 | (define_split | |
5659 | [(set (match_operand:HI 0 "s_operand" "") | |
5660 | (and:HI (match_dup 0) (match_operand:HI 1 "immediate_operand" ""))) | |
1ca361fd | 5661 | (clobber (reg:CC CC_REGNUM))] |
3f56e755 | 5662 | "reload_completed" |
5663 | [(parallel | |
5664 | [(set (match_dup 0) (and:QI (match_dup 0) (match_dup 1))) | |
1ca361fd | 5665 | (clobber (reg:CC CC_REGNUM))])] |
3f56e755 | 5666 | "s390_narrow_logical_operator (AND, &operands[0], &operands[1]);") |
4673c1a0 | 5667 | |
4673c1a0 | 5668 | ; |
5669 | ; andqi3 instruction pattern(s). | |
5670 | ; | |
5671 | ||
3e247a31 | 5672 | (define_insn "*andqi3_zarch" |
5673 | [(set (match_operand:QI 0 "nonimmediate_operand" "=d,d,Q,S,Q") | |
5674 | (and:QI (match_operand:QI 1 "nonimmediate_operand" "%0,0,0,0,0") | |
5675 | (match_operand:QI 2 "general_operand" "d,n,n,n,Q"))) | |
1ca361fd | 5676 | (clobber (reg:CC CC_REGNUM))] |
3e247a31 | 5677 | "TARGET_ZARCH && s390_logical_operator_ok_p (operands)" |
8b4a4127 | 5678 | "@ |
f24d7ff3 | 5679 | nr\t%0,%2 |
3e247a31 | 5680 | nill\t%0,%b2 |
0574acbe | 5681 | ni\t%S0,%b2 |
5682 | niy\t%S0,%b2 | |
9dffd3ff | 5683 | #" |
3e247a31 | 5684 | [(set_attr "op_type" "RR,RI,SI,SIY,SS")]) |
5685 | ||
5686 | (define_insn "*andqi3_esa" | |
5687 | [(set (match_operand:QI 0 "nonimmediate_operand" "=d,Q,Q") | |
5688 | (and:QI (match_operand:QI 1 "nonimmediate_operand" "%0,0,0") | |
5689 | (match_operand:QI 2 "general_operand" "d,n,Q"))) | |
1ca361fd | 5690 | (clobber (reg:CC CC_REGNUM))] |
3e247a31 | 5691 | "!TARGET_ZARCH && s390_logical_operator_ok_p (operands)" |
4673c1a0 | 5692 | "@ |
3e247a31 | 5693 | nr\t%0,%2 |
0574acbe | 5694 | ni\t%S0,%b2 |
9dffd3ff | 5695 | #" |
3e247a31 | 5696 | [(set_attr "op_type" "RR,SI,SS")]) |
8b4a4127 | 5697 | |
9dffd3ff | 5698 | ; |
5699 | ; Block and (NC) patterns. | |
5700 | ; | |
5701 | ||
5702 | (define_insn "*nc" | |
5703 | [(set (match_operand:BLK 0 "memory_operand" "=Q") | |
5704 | (and:BLK (match_dup 0) | |
5705 | (match_operand:BLK 1 "memory_operand" "Q"))) | |
5706 | (use (match_operand 2 "const_int_operand" "n")) | |
1ca361fd | 5707 | (clobber (reg:CC CC_REGNUM))] |
9dffd3ff | 5708 | "INTVAL (operands[2]) >= 1 && INTVAL (operands[2]) <= 256" |
0574acbe | 5709 | "nc\t%O0(%2,%R0),%S1" |
1822f0d6 | 5710 | [(set_attr "op_type" "SS")]) |
9dffd3ff | 5711 | |
5712 | (define_split | |
5713 | [(set (match_operand 0 "memory_operand" "") | |
5714 | (and (match_dup 0) | |
5715 | (match_operand 1 "memory_operand" ""))) | |
1ca361fd | 5716 | (clobber (reg:CC CC_REGNUM))] |
9dffd3ff | 5717 | "reload_completed |
5718 | && GET_MODE (operands[0]) == GET_MODE (operands[1]) | |
5719 | && GET_MODE_SIZE (GET_MODE (operands[0])) > 0" | |
5720 | [(parallel | |
5721 | [(set (match_dup 0) (and:BLK (match_dup 0) (match_dup 1))) | |
5722 | (use (match_dup 2)) | |
1ca361fd | 5723 | (clobber (reg:CC CC_REGNUM))])] |
9dffd3ff | 5724 | { |
5725 | operands[2] = GEN_INT (GET_MODE_SIZE (GET_MODE (operands[0]))); | |
5726 | operands[0] = adjust_address (operands[0], BLKmode, 0); | |
5727 | operands[1] = adjust_address (operands[1], BLKmode, 0); | |
5728 | }) | |
5729 | ||
5730 | (define_peephole2 | |
5731 | [(parallel | |
5732 | [(set (match_operand:BLK 0 "memory_operand" "") | |
5733 | (and:BLK (match_dup 0) | |
5734 | (match_operand:BLK 1 "memory_operand" ""))) | |
5735 | (use (match_operand 2 "const_int_operand" "")) | |
1ca361fd | 5736 | (clobber (reg:CC CC_REGNUM))]) |
9dffd3ff | 5737 | (parallel |
5738 | [(set (match_operand:BLK 3 "memory_operand" "") | |
5739 | (and:BLK (match_dup 3) | |
5740 | (match_operand:BLK 4 "memory_operand" ""))) | |
5741 | (use (match_operand 5 "const_int_operand" "")) | |
1ca361fd | 5742 | (clobber (reg:CC CC_REGNUM))])] |
9dffd3ff | 5743 | "s390_offset_p (operands[0], operands[3], operands[2]) |
5744 | && s390_offset_p (operands[1], operands[4], operands[2]) | |
74bdf297 | 5745 | && !s390_overlap_p (operands[0], operands[1], |
5746 | INTVAL (operands[2]) + INTVAL (operands[5])) | |
9dffd3ff | 5747 | && INTVAL (operands[2]) + INTVAL (operands[5]) <= 256" |
5748 | [(parallel | |
5749 | [(set (match_dup 6) (and:BLK (match_dup 6) (match_dup 7))) | |
5750 | (use (match_dup 8)) | |
1ca361fd | 5751 | (clobber (reg:CC CC_REGNUM))])] |
9dffd3ff | 5752 | "operands[6] = gen_rtx_MEM (BLKmode, XEXP (operands[0], 0)); |
5753 | operands[7] = gen_rtx_MEM (BLKmode, XEXP (operands[1], 0)); | |
5754 | operands[8] = GEN_INT (INTVAL (operands[2]) + INTVAL (operands[5]));") | |
5755 | ||
4673c1a0 | 5756 | |
5757 | ;; | |
5758 | ;;- Bit set (inclusive or) instructions. | |
5759 | ;; | |
5760 | ||
8f446608 | 5761 | (define_expand "ior<mode>3" |
5762 | [(set (match_operand:INT 0 "nonimmediate_operand" "") | |
5763 | (ior:INT (match_operand:INT 1 "nonimmediate_operand" "") | |
5764 | (match_operand:INT 2 "general_operand" ""))) | |
5765 | (clobber (reg:CC CC_REGNUM))] | |
5766 | "" | |
5767 | "s390_expand_logical_operator (IOR, <MODE>mode, operands); DONE;") | |
5768 | ||
4673c1a0 | 5769 | ; |
5770 | ; iordi3 instruction pattern(s). | |
5771 | ; | |
5772 | ||
8b4a4127 | 5773 | (define_insn "*iordi3_cc" |
1ca361fd | 5774 | [(set (reg CC_REGNUM) |
7c3aefa0 | 5775 | (compare (ior:DI (match_operand:DI 1 "nonimmediate_operand" "%0,0") |
8fe52251 | 5776 | (match_operand:DI 2 "general_operand" "d,RT")) |
8b4a4127 | 5777 | (const_int 0))) |
5778 | (set (match_operand:DI 0 "register_operand" "=d,d") | |
5779 | (ior:DI (match_dup 1) (match_dup 2)))] | |
5780 | "s390_match_ccmode(insn, CCTmode) && TARGET_64BIT" | |
5781 | "@ | |
f24d7ff3 | 5782 | ogr\t%0,%2 |
5783 | og\t%0,%2" | |
51aa1e9c | 5784 | [(set_attr "op_type" "RRE,RXY")]) |
8b4a4127 | 5785 | |
5786 | (define_insn "*iordi3_cconly" | |
1ca361fd | 5787 | [(set (reg CC_REGNUM) |
7c3aefa0 | 5788 | (compare (ior:DI (match_operand:DI 1 "nonimmediate_operand" "%0,0") |
8fe52251 | 5789 | (match_operand:DI 2 "general_operand" "d,RT")) |
8b4a4127 | 5790 | (const_int 0))) |
5791 | (clobber (match_scratch:DI 0 "=d,d"))] | |
5792 | "s390_match_ccmode(insn, CCTmode) && TARGET_64BIT" | |
5793 | "@ | |
f24d7ff3 | 5794 | ogr\t%0,%2 |
5795 | og\t%0,%2" | |
51aa1e9c | 5796 | [(set_attr "op_type" "RRE,RXY")]) |
8b4a4127 | 5797 | |
562d1970 | 5798 | (define_insn "*iordi3" |
163277cf | 5799 | [(set (match_operand:DI 0 "nonimmediate_operand" "=d,d,d,d,d,d,d,d,AQ,Q") |
5800 | (ior:DI (match_operand:DI 1 "nonimmediate_operand" "%0,0,0,0,0,0,0,0,0,0") | |
5801 | (match_operand:DI 2 "general_operand" | |
8fe52251 | 5802 | "N0HD0,N1HD0,N2HD0,N3HD0,N0SD0,N1SD0,d,RT,NxQD0,Q"))) |
163277cf | 5803 | (clobber (reg:CC CC_REGNUM))] |
562d1970 | 5804 | "TARGET_64BIT && s390_logical_operator_ok_p (operands)" |
163277cf | 5805 | "@ |
5806 | oihh\t%0,%i2 | |
5807 | oihl\t%0,%i2 | |
5808 | oilh\t%0,%i2 | |
5809 | oill\t%0,%i2 | |
5810 | oihf\t%0,%k2 | |
5811 | oilf\t%0,%k2 | |
5812 | ogr\t%0,%2 | |
5813 | og\t%0,%2 | |
5814 | # | |
5815 | #" | |
562d1970 | 5816 | [(set_attr "op_type" "RI,RI,RI,RI,RIL,RIL,RRE,RXY,SI,SS") |
5817 | (set_attr "cpu_facility" "*,*,*,*,extimm,extimm,*,*,*,*")]) | |
3f56e755 | 5818 | |
5819 | (define_split | |
5820 | [(set (match_operand:DI 0 "s_operand" "") | |
5821 | (ior:DI (match_dup 0) (match_operand:DI 1 "immediate_operand" ""))) | |
1ca361fd | 5822 | (clobber (reg:CC CC_REGNUM))] |
3f56e755 | 5823 | "reload_completed" |
5824 | [(parallel | |
5825 | [(set (match_dup 0) (ior:QI (match_dup 0) (match_dup 1))) | |
1ca361fd | 5826 | (clobber (reg:CC CC_REGNUM))])] |
3f56e755 | 5827 | "s390_narrow_logical_operator (IOR, &operands[0], &operands[1]);") |
8b4a4127 | 5828 | |
4673c1a0 | 5829 | ; |
5830 | ; iorsi3 instruction pattern(s). | |
5831 | ; | |
5832 | ||
8b4a4127 | 5833 | (define_insn "*iorsi3_cc" |
1ca361fd | 5834 | [(set (reg CC_REGNUM) |
163277cf | 5835 | (compare (ior:SI (match_operand:SI 1 "nonimmediate_operand" "%0,0,0,0") |
5836 | (match_operand:SI 2 "general_operand" "Os,d,R,T")) | |
8b4a4127 | 5837 | (const_int 0))) |
163277cf | 5838 | (set (match_operand:SI 0 "register_operand" "=d,d,d,d") |
8b4a4127 | 5839 | (ior:SI (match_dup 1) (match_dup 2)))] |
5840 | "s390_match_ccmode(insn, CCTmode)" | |
5841 | "@ | |
163277cf | 5842 | oilf\t%0,%o2 |
f24d7ff3 | 5843 | or\t%0,%2 |
5844 | o\t%0,%2 | |
5845 | oy\t%0,%2" | |
163277cf | 5846 | [(set_attr "op_type" "RIL,RR,RX,RXY")]) |
8b4a4127 | 5847 | |
5848 | (define_insn "*iorsi3_cconly" | |
1ca361fd | 5849 | [(set (reg CC_REGNUM) |
163277cf | 5850 | (compare (ior:SI (match_operand:SI 1 "nonimmediate_operand" "%0,0,0,0") |
5851 | (match_operand:SI 2 "general_operand" "Os,d,R,T")) | |
8b4a4127 | 5852 | (const_int 0))) |
163277cf | 5853 | (clobber (match_scratch:SI 0 "=d,d,d,d"))] |
8b4a4127 | 5854 | "s390_match_ccmode(insn, CCTmode)" |
5855 | "@ | |
163277cf | 5856 | oilf\t%0,%o2 |
f24d7ff3 | 5857 | or\t%0,%2 |
5858 | o\t%0,%2 | |
5859 | oy\t%0,%2" | |
163277cf | 5860 | [(set_attr "op_type" "RIL,RR,RX,RXY")]) |
8b4a4127 | 5861 | |
3e247a31 | 5862 | (define_insn "*iorsi3_zarch" |
163277cf | 5863 | [(set (match_operand:SI 0 "nonimmediate_operand" "=d,d,d,d,d,d,AQ,Q") |
5864 | (ior:SI (match_operand:SI 1 "nonimmediate_operand" "%0,0,0,0,0,0,0,0") | |
5865 | (match_operand:SI 2 "general_operand" "N0HS0,N1HS0,Os,d,R,T,NxQS0,Q"))) | |
1ca361fd | 5866 | (clobber (reg:CC CC_REGNUM))] |
3e247a31 | 5867 | "TARGET_ZARCH && s390_logical_operator_ok_p (operands)" |
8b4a4127 | 5868 | "@ |
64a1078f | 5869 | oilh\t%0,%i2 |
5870 | oill\t%0,%i2 | |
163277cf | 5871 | oilf\t%0,%o2 |
f24d7ff3 | 5872 | or\t%0,%2 |
5873 | o\t%0,%2 | |
3e247a31 | 5874 | oy\t%0,%2 |
3f56e755 | 5875 | # |
9dffd3ff | 5876 | #" |
163277cf | 5877 | [(set_attr "op_type" "RI,RI,RIL,RR,RX,RXY,SI,SS")]) |
3e247a31 | 5878 | |
5879 | (define_insn "*iorsi3_esa" | |
3f56e755 | 5880 | [(set (match_operand:SI 0 "nonimmediate_operand" "=d,d,AQ,Q") |
ccb87793 | 5881 | (ior:SI (match_operand:SI 1 "nonimmediate_operand" "%0,0,0,0") |
3f56e755 | 5882 | (match_operand:SI 2 "general_operand" "d,R,NxQS0,Q"))) |
1ca361fd | 5883 | (clobber (reg:CC CC_REGNUM))] |
3e247a31 | 5884 | "!TARGET_ZARCH && s390_logical_operator_ok_p (operands)" |
64a1078f | 5885 | "@ |
5886 | or\t%0,%2 | |
3e247a31 | 5887 | o\t%0,%2 |
3f56e755 | 5888 | # |
9dffd3ff | 5889 | #" |
3f56e755 | 5890 | [(set_attr "op_type" "RR,RX,SI,SS")]) |
5891 | ||
5892 | (define_split | |
5893 | [(set (match_operand:SI 0 "s_operand" "") | |
5894 | (ior:SI (match_dup 0) (match_operand:SI 1 "immediate_operand" ""))) | |
1ca361fd | 5895 | (clobber (reg:CC CC_REGNUM))] |
3f56e755 | 5896 | "reload_completed" |
5897 | [(parallel | |
5898 | [(set (match_dup 0) (ior:QI (match_dup 0) (match_dup 1))) | |
1ca361fd | 5899 | (clobber (reg:CC CC_REGNUM))])] |
3f56e755 | 5900 | "s390_narrow_logical_operator (IOR, &operands[0], &operands[1]);") |
8b4a4127 | 5901 | |
8b4a4127 | 5902 | ; |
5903 | ; iorhi3 instruction pattern(s). | |
5904 | ; | |
5905 | ||
3e247a31 | 5906 | (define_insn "*iorhi3_zarch" |
3f56e755 | 5907 | [(set (match_operand:HI 0 "nonimmediate_operand" "=d,d,AQ,Q") |
5908 | (ior:HI (match_operand:HI 1 "nonimmediate_operand" "%0,0,0,0") | |
5909 | (match_operand:HI 2 "general_operand" "d,n,NxQH0,Q"))) | |
1ca361fd | 5910 | (clobber (reg:CC CC_REGNUM))] |
3e247a31 | 5911 | "TARGET_ZARCH && s390_logical_operator_ok_p (operands)" |
8b4a4127 | 5912 | "@ |
f24d7ff3 | 5913 | or\t%0,%2 |
3e247a31 | 5914 | oill\t%0,%x2 |
3f56e755 | 5915 | # |
9dffd3ff | 5916 | #" |
3f56e755 | 5917 | [(set_attr "op_type" "RR,RI,SI,SS")]) |
3e247a31 | 5918 | |
5919 | (define_insn "*iorhi3_esa" | |
3f56e755 | 5920 | [(set (match_operand:HI 0 "nonimmediate_operand" "=d,AQ,Q") |
5921 | (ior:HI (match_operand:HI 1 "nonimmediate_operand" "%0,0,0") | |
5922 | (match_operand:HI 2 "general_operand" "d,NxQH0,Q"))) | |
1ca361fd | 5923 | (clobber (reg:CC CC_REGNUM))] |
3e247a31 | 5924 | "!TARGET_ZARCH && s390_logical_operator_ok_p (operands)" |
5925 | "@ | |
5926 | or\t%0,%2 | |
3f56e755 | 5927 | # |
9dffd3ff | 5928 | #" |
3f56e755 | 5929 | [(set_attr "op_type" "RR,SI,SS")]) |
5930 | ||
5931 | (define_split | |
5932 | [(set (match_operand:HI 0 "s_operand" "") | |
5933 | (ior:HI (match_dup 0) (match_operand:HI 1 "immediate_operand" ""))) | |
1ca361fd | 5934 | (clobber (reg:CC CC_REGNUM))] |
3f56e755 | 5935 | "reload_completed" |
5936 | [(parallel | |
5937 | [(set (match_dup 0) (ior:QI (match_dup 0) (match_dup 1))) | |
1ca361fd | 5938 | (clobber (reg:CC CC_REGNUM))])] |
3f56e755 | 5939 | "s390_narrow_logical_operator (IOR, &operands[0], &operands[1]);") |
4673c1a0 | 5940 | |
4673c1a0 | 5941 | ; |
8b4a4127 | 5942 | ; iorqi3 instruction pattern(s). |
4673c1a0 | 5943 | ; |
5944 | ||
3e247a31 | 5945 | (define_insn "*iorqi3_zarch" |
5946 | [(set (match_operand:QI 0 "nonimmediate_operand" "=d,d,Q,S,Q") | |
5947 | (ior:QI (match_operand:QI 1 "nonimmediate_operand" "%0,0,0,0,0") | |
5948 | (match_operand:QI 2 "general_operand" "d,n,n,n,Q"))) | |
1ca361fd | 5949 | (clobber (reg:CC CC_REGNUM))] |
3e247a31 | 5950 | "TARGET_ZARCH && s390_logical_operator_ok_p (operands)" |
8b4a4127 | 5951 | "@ |
f24d7ff3 | 5952 | or\t%0,%2 |
3e247a31 | 5953 | oill\t%0,%b2 |
0574acbe | 5954 | oi\t%S0,%b2 |
5955 | oiy\t%S0,%b2 | |
9dffd3ff | 5956 | #" |
3e247a31 | 5957 | [(set_attr "op_type" "RR,RI,SI,SIY,SS")]) |
5958 | ||
5959 | (define_insn "*iorqi3_esa" | |
5960 | [(set (match_operand:QI 0 "nonimmediate_operand" "=d,Q,Q") | |
5961 | (ior:QI (match_operand:QI 1 "nonimmediate_operand" "%0,0,0") | |
5962 | (match_operand:QI 2 "general_operand" "d,n,Q"))) | |
1ca361fd | 5963 | (clobber (reg:CC CC_REGNUM))] |
3e247a31 | 5964 | "!TARGET_ZARCH && s390_logical_operator_ok_p (operands)" |
4673c1a0 | 5965 | "@ |
3e247a31 | 5966 | or\t%0,%2 |
0574acbe | 5967 | oi\t%S0,%b2 |
9dffd3ff | 5968 | #" |
3e247a31 | 5969 | [(set_attr "op_type" "RR,SI,SS")]) |
4673c1a0 | 5970 | |
9dffd3ff | 5971 | ; |
5972 | ; Block inclusive or (OC) patterns. | |
5973 | ; | |
5974 | ||
5975 | (define_insn "*oc" | |
5976 | [(set (match_operand:BLK 0 "memory_operand" "=Q") | |
5977 | (ior:BLK (match_dup 0) | |
5978 | (match_operand:BLK 1 "memory_operand" "Q"))) | |
5979 | (use (match_operand 2 "const_int_operand" "n")) | |
1ca361fd | 5980 | (clobber (reg:CC CC_REGNUM))] |
9dffd3ff | 5981 | "INTVAL (operands[2]) >= 1 && INTVAL (operands[2]) <= 256" |
0574acbe | 5982 | "oc\t%O0(%2,%R0),%S1" |
1822f0d6 | 5983 | [(set_attr "op_type" "SS")]) |
9dffd3ff | 5984 | |
5985 | (define_split | |
5986 | [(set (match_operand 0 "memory_operand" "") | |
5987 | (ior (match_dup 0) | |
5988 | (match_operand 1 "memory_operand" ""))) | |
1ca361fd | 5989 | (clobber (reg:CC CC_REGNUM))] |
9dffd3ff | 5990 | "reload_completed |
5991 | && GET_MODE (operands[0]) == GET_MODE (operands[1]) | |
5992 | && GET_MODE_SIZE (GET_MODE (operands[0])) > 0" | |
5993 | [(parallel | |
5994 | [(set (match_dup 0) (ior:BLK (match_dup 0) (match_dup 1))) | |
5995 | (use (match_dup 2)) | |
1ca361fd | 5996 | (clobber (reg:CC CC_REGNUM))])] |
9dffd3ff | 5997 | { |
5998 | operands[2] = GEN_INT (GET_MODE_SIZE (GET_MODE (operands[0]))); | |
5999 | operands[0] = adjust_address (operands[0], BLKmode, 0); | |
6000 | operands[1] = adjust_address (operands[1], BLKmode, 0); | |
6001 | }) | |
6002 | ||
6003 | (define_peephole2 | |
6004 | [(parallel | |
6005 | [(set (match_operand:BLK 0 "memory_operand" "") | |
6006 | (ior:BLK (match_dup 0) | |
6007 | (match_operand:BLK 1 "memory_operand" ""))) | |
6008 | (use (match_operand 2 "const_int_operand" "")) | |
1ca361fd | 6009 | (clobber (reg:CC CC_REGNUM))]) |
9dffd3ff | 6010 | (parallel |
6011 | [(set (match_operand:BLK 3 "memory_operand" "") | |
6012 | (ior:BLK (match_dup 3) | |
6013 | (match_operand:BLK 4 "memory_operand" ""))) | |
6014 | (use (match_operand 5 "const_int_operand" "")) | |
1ca361fd | 6015 | (clobber (reg:CC CC_REGNUM))])] |
9dffd3ff | 6016 | "s390_offset_p (operands[0], operands[3], operands[2]) |
6017 | && s390_offset_p (operands[1], operands[4], operands[2]) | |
74bdf297 | 6018 | && !s390_overlap_p (operands[0], operands[1], |
6019 | INTVAL (operands[2]) + INTVAL (operands[5])) | |
9dffd3ff | 6020 | && INTVAL (operands[2]) + INTVAL (operands[5]) <= 256" |
6021 | [(parallel | |
6022 | [(set (match_dup 6) (ior:BLK (match_dup 6) (match_dup 7))) | |
6023 | (use (match_dup 8)) | |
1ca361fd | 6024 | (clobber (reg:CC CC_REGNUM))])] |
9dffd3ff | 6025 | "operands[6] = gen_rtx_MEM (BLKmode, XEXP (operands[0], 0)); |
6026 | operands[7] = gen_rtx_MEM (BLKmode, XEXP (operands[1], 0)); | |
6027 | operands[8] = GEN_INT (INTVAL (operands[2]) + INTVAL (operands[5]));") | |
6028 | ||
4673c1a0 | 6029 | |
6030 | ;; | |
6031 | ;;- Xor instructions. | |
6032 | ;; | |
6033 | ||
8f446608 | 6034 | (define_expand "xor<mode>3" |
6035 | [(set (match_operand:INT 0 "nonimmediate_operand" "") | |
6036 | (xor:INT (match_operand:INT 1 "nonimmediate_operand" "") | |
6037 | (match_operand:INT 2 "general_operand" ""))) | |
6038 | (clobber (reg:CC CC_REGNUM))] | |
6039 | "" | |
6040 | "s390_expand_logical_operator (XOR, <MODE>mode, operands); DONE;") | |
6041 | ||
4673c1a0 | 6042 | ; |
6043 | ; xordi3 instruction pattern(s). | |
6044 | ; | |
6045 | ||
8b4a4127 | 6046 | (define_insn "*xordi3_cc" |
1ca361fd | 6047 | [(set (reg CC_REGNUM) |
7c3aefa0 | 6048 | (compare (xor:DI (match_operand:DI 1 "nonimmediate_operand" "%0,0") |
8fe52251 | 6049 | (match_operand:DI 2 "general_operand" "d,RT")) |
8b4a4127 | 6050 | (const_int 0))) |
6051 | (set (match_operand:DI 0 "register_operand" "=d,d") | |
6052 | (xor:DI (match_dup 1) (match_dup 2)))] | |
6053 | "s390_match_ccmode(insn, CCTmode) && TARGET_64BIT" | |
6054 | "@ | |
f24d7ff3 | 6055 | xgr\t%0,%2 |
6056 | xg\t%0,%2" | |
51aa1e9c | 6057 | [(set_attr "op_type" "RRE,RXY")]) |
8b4a4127 | 6058 | |
6059 | (define_insn "*xordi3_cconly" | |
1ca361fd | 6060 | [(set (reg CC_REGNUM) |
7c3aefa0 | 6061 | (compare (xor:DI (match_operand:DI 1 "nonimmediate_operand" "%0,0") |
8fe52251 | 6062 | (match_operand:DI 2 "general_operand" "d,RT")) |
8b4a4127 | 6063 | (const_int 0))) |
6064 | (clobber (match_scratch:DI 0 "=d,d"))] | |
6065 | "s390_match_ccmode(insn, CCTmode) && TARGET_64BIT" | |
6066 | "@ | |
f24d7ff3 | 6067 | xgr\t%0,%2 |
ab22ec57 | 6068 | xg\t%0,%2" |
51aa1e9c | 6069 | [(set_attr "op_type" "RRE,RXY")]) |
8b4a4127 | 6070 | |
562d1970 | 6071 | (define_insn "*xordi3" |
163277cf | 6072 | [(set (match_operand:DI 0 "nonimmediate_operand" "=d,d,d,d,AQ,Q") |
6073 | (xor:DI (match_operand:DI 1 "nonimmediate_operand" "%0,0,0,0,0,0") | |
8fe52251 | 6074 | (match_operand:DI 2 "general_operand" "N0SD0,N1SD0,d,RT,NxQD0,Q"))) |
163277cf | 6075 | (clobber (reg:CC CC_REGNUM))] |
562d1970 | 6076 | "TARGET_64BIT && s390_logical_operator_ok_p (operands)" |
163277cf | 6077 | "@ |
6078 | xihf\t%0,%k2 | |
6079 | xilf\t%0,%k2 | |
6080 | xgr\t%0,%2 | |
6081 | xg\t%0,%2 | |
6082 | # | |
6083 | #" | |
562d1970 | 6084 | [(set_attr "op_type" "RIL,RIL,RRE,RXY,SI,SS") |
6085 | (set_attr "cpu_facility" "extimm,extimm,*,*,*,*")]) | |
3f56e755 | 6086 | |
6087 | (define_split | |
6088 | [(set (match_operand:DI 0 "s_operand" "") | |
6089 | (xor:DI (match_dup 0) (match_operand:DI 1 "immediate_operand" ""))) | |
1ca361fd | 6090 | (clobber (reg:CC CC_REGNUM))] |
3f56e755 | 6091 | "reload_completed" |
6092 | [(parallel | |
6093 | [(set (match_dup 0) (xor:QI (match_dup 0) (match_dup 1))) | |
1ca361fd | 6094 | (clobber (reg:CC CC_REGNUM))])] |
3f56e755 | 6095 | "s390_narrow_logical_operator (XOR, &operands[0], &operands[1]);") |
8b4a4127 | 6096 | |
4673c1a0 | 6097 | ; |
6098 | ; xorsi3 instruction pattern(s). | |
6099 | ; | |
6100 | ||
8b4a4127 | 6101 | (define_insn "*xorsi3_cc" |
1ca361fd | 6102 | [(set (reg CC_REGNUM) |
163277cf | 6103 | (compare (xor:SI (match_operand:SI 1 "nonimmediate_operand" "%0,0,0,0") |
6104 | (match_operand:SI 2 "general_operand" "Os,d,R,T")) | |
8b4a4127 | 6105 | (const_int 0))) |
163277cf | 6106 | (set (match_operand:SI 0 "register_operand" "=d,d,d,d") |
8b4a4127 | 6107 | (xor:SI (match_dup 1) (match_dup 2)))] |
6108 | "s390_match_ccmode(insn, CCTmode)" | |
6109 | "@ | |
163277cf | 6110 | xilf\t%0,%o2 |
f24d7ff3 | 6111 | xr\t%0,%2 |
6112 | x\t%0,%2 | |
6113 | xy\t%0,%2" | |
163277cf | 6114 | [(set_attr "op_type" "RIL,RR,RX,RXY")]) |
8b4a4127 | 6115 | |
6116 | (define_insn "*xorsi3_cconly" | |
1ca361fd | 6117 | [(set (reg CC_REGNUM) |
163277cf | 6118 | (compare (xor:SI (match_operand:SI 1 "nonimmediate_operand" "%0,0,0,0") |
6119 | (match_operand:SI 2 "general_operand" "Os,d,R,T")) | |
8b4a4127 | 6120 | (const_int 0))) |
163277cf | 6121 | (clobber (match_scratch:SI 0 "=d,d,d,d"))] |
8b4a4127 | 6122 | "s390_match_ccmode(insn, CCTmode)" |
6123 | "@ | |
163277cf | 6124 | xilf\t%0,%o2 |
f24d7ff3 | 6125 | xr\t%0,%2 |
6126 | x\t%0,%2 | |
6127 | xy\t%0,%2" | |
163277cf | 6128 | [(set_attr "op_type" "RIL,RR,RX,RXY")]) |
4673c1a0 | 6129 | |
3e247a31 | 6130 | (define_insn "*xorsi3" |
163277cf | 6131 | [(set (match_operand:SI 0 "nonimmediate_operand" "=d,d,d,d,AQ,Q") |
6132 | (xor:SI (match_operand:SI 1 "nonimmediate_operand" "%0,0,0,0,0,0") | |
6133 | (match_operand:SI 2 "general_operand" "Os,d,R,T,NxQS0,Q"))) | |
1ca361fd | 6134 | (clobber (reg:CC CC_REGNUM))] |
3e247a31 | 6135 | "s390_logical_operator_ok_p (operands)" |
4673c1a0 | 6136 | "@ |
163277cf | 6137 | xilf\t%0,%o2 |
f24d7ff3 | 6138 | xr\t%0,%2 |
6139 | x\t%0,%2 | |
3e247a31 | 6140 | xy\t%0,%2 |
3f56e755 | 6141 | # |
9dffd3ff | 6142 | #" |
163277cf | 6143 | [(set_attr "op_type" "RIL,RR,RX,RXY,SI,SS")]) |
3f56e755 | 6144 | |
6145 | (define_split | |
6146 | [(set (match_operand:SI 0 "s_operand" "") | |
6147 | (xor:SI (match_dup 0) (match_operand:SI 1 "immediate_operand" ""))) | |
1ca361fd | 6148 | (clobber (reg:CC CC_REGNUM))] |
3f56e755 | 6149 | "reload_completed" |
6150 | [(parallel | |
6151 | [(set (match_dup 0) (xor:QI (match_dup 0) (match_dup 1))) | |
1ca361fd | 6152 | (clobber (reg:CC CC_REGNUM))])] |
3f56e755 | 6153 | "s390_narrow_logical_operator (XOR, &operands[0], &operands[1]);") |
3e247a31 | 6154 | |
4673c1a0 | 6155 | ; |
6156 | ; xorhi3 instruction pattern(s). | |
6157 | ; | |
6158 | ||
3e247a31 | 6159 | (define_insn "*xorhi3" |
163277cf | 6160 | [(set (match_operand:HI 0 "nonimmediate_operand" "=d,d,AQ,Q") |
6161 | (xor:HI (match_operand:HI 1 "nonimmediate_operand" "%0,0,0,0") | |
6162 | (match_operand:HI 2 "general_operand" "Os,d,NxQH0,Q"))) | |
1ca361fd | 6163 | (clobber (reg:CC CC_REGNUM))] |
3e247a31 | 6164 | "s390_logical_operator_ok_p (operands)" |
6165 | "@ | |
163277cf | 6166 | xilf\t%0,%x2 |
3e247a31 | 6167 | xr\t%0,%2 |
3f56e755 | 6168 | # |
9dffd3ff | 6169 | #" |
163277cf | 6170 | [(set_attr "op_type" "RIL,RR,SI,SS")]) |
3f56e755 | 6171 | |
6172 | (define_split | |
6173 | [(set (match_operand:HI 0 "s_operand" "") | |
6174 | (xor:HI (match_dup 0) (match_operand:HI 1 "immediate_operand" ""))) | |
1ca361fd | 6175 | (clobber (reg:CC CC_REGNUM))] |
3f56e755 | 6176 | "reload_completed" |
6177 | [(parallel | |
6178 | [(set (match_dup 0) (xor:QI (match_dup 0) (match_dup 1))) | |
1ca361fd | 6179 | (clobber (reg:CC CC_REGNUM))])] |
3f56e755 | 6180 | "s390_narrow_logical_operator (XOR, &operands[0], &operands[1]);") |
4673c1a0 | 6181 | |
4673c1a0 | 6182 | ; |
6183 | ; xorqi3 instruction pattern(s). | |
6184 | ; | |
6185 | ||
3e247a31 | 6186 | (define_insn "*xorqi3" |
163277cf | 6187 | [(set (match_operand:QI 0 "nonimmediate_operand" "=d,d,Q,S,Q") |
6188 | (xor:QI (match_operand:QI 1 "nonimmediate_operand" "%0,0,0,0,0") | |
6189 | (match_operand:QI 2 "general_operand" "Os,d,n,n,Q"))) | |
1ca361fd | 6190 | (clobber (reg:CC CC_REGNUM))] |
3e247a31 | 6191 | "s390_logical_operator_ok_p (operands)" |
4673c1a0 | 6192 | "@ |
163277cf | 6193 | xilf\t%0,%b2 |
3e247a31 | 6194 | xr\t%0,%2 |
0574acbe | 6195 | xi\t%S0,%b2 |
6196 | xiy\t%S0,%b2 | |
9dffd3ff | 6197 | #" |
163277cf | 6198 | [(set_attr "op_type" "RIL,RR,SI,SIY,SS")]) |
8b4a4127 | 6199 | |
9dffd3ff | 6200 | ; |
6201 | ; Block exclusive or (XC) patterns. | |
6202 | ; | |
6203 | ||
6204 | (define_insn "*xc" | |
6205 | [(set (match_operand:BLK 0 "memory_operand" "=Q") | |
6206 | (xor:BLK (match_dup 0) | |
6207 | (match_operand:BLK 1 "memory_operand" "Q"))) | |
6208 | (use (match_operand 2 "const_int_operand" "n")) | |
1ca361fd | 6209 | (clobber (reg:CC CC_REGNUM))] |
9dffd3ff | 6210 | "INTVAL (operands[2]) >= 1 && INTVAL (operands[2]) <= 256" |
0574acbe | 6211 | "xc\t%O0(%2,%R0),%S1" |
1822f0d6 | 6212 | [(set_attr "op_type" "SS")]) |
9dffd3ff | 6213 | |
6214 | (define_split | |
6215 | [(set (match_operand 0 "memory_operand" "") | |
6216 | (xor (match_dup 0) | |
6217 | (match_operand 1 "memory_operand" ""))) | |
1ca361fd | 6218 | (clobber (reg:CC CC_REGNUM))] |
9dffd3ff | 6219 | "reload_completed |
6220 | && GET_MODE (operands[0]) == GET_MODE (operands[1]) | |
6221 | && GET_MODE_SIZE (GET_MODE (operands[0])) > 0" | |
6222 | [(parallel | |
6223 | [(set (match_dup 0) (xor:BLK (match_dup 0) (match_dup 1))) | |
6224 | (use (match_dup 2)) | |
1ca361fd | 6225 | (clobber (reg:CC CC_REGNUM))])] |
9dffd3ff | 6226 | { |
6227 | operands[2] = GEN_INT (GET_MODE_SIZE (GET_MODE (operands[0]))); | |
6228 | operands[0] = adjust_address (operands[0], BLKmode, 0); | |
6229 | operands[1] = adjust_address (operands[1], BLKmode, 0); | |
6230 | }) | |
6231 | ||
6232 | (define_peephole2 | |
6233 | [(parallel | |
6234 | [(set (match_operand:BLK 0 "memory_operand" "") | |
6235 | (xor:BLK (match_dup 0) | |
6236 | (match_operand:BLK 1 "memory_operand" ""))) | |
6237 | (use (match_operand 2 "const_int_operand" "")) | |
1ca361fd | 6238 | (clobber (reg:CC CC_REGNUM))]) |
9dffd3ff | 6239 | (parallel |
6240 | [(set (match_operand:BLK 3 "memory_operand" "") | |
6241 | (xor:BLK (match_dup 3) | |
6242 | (match_operand:BLK 4 "memory_operand" ""))) | |
6243 | (use (match_operand 5 "const_int_operand" "")) | |
1ca361fd | 6244 | (clobber (reg:CC CC_REGNUM))])] |
9dffd3ff | 6245 | "s390_offset_p (operands[0], operands[3], operands[2]) |
6246 | && s390_offset_p (operands[1], operands[4], operands[2]) | |
74bdf297 | 6247 | && !s390_overlap_p (operands[0], operands[1], |
6248 | INTVAL (operands[2]) + INTVAL (operands[5])) | |
9dffd3ff | 6249 | && INTVAL (operands[2]) + INTVAL (operands[5]) <= 256" |
6250 | [(parallel | |
6251 | [(set (match_dup 6) (xor:BLK (match_dup 6) (match_dup 7))) | |
6252 | (use (match_dup 8)) | |
1ca361fd | 6253 | (clobber (reg:CC CC_REGNUM))])] |
9dffd3ff | 6254 | "operands[6] = gen_rtx_MEM (BLKmode, XEXP (operands[0], 0)); |
6255 | operands[7] = gen_rtx_MEM (BLKmode, XEXP (operands[1], 0)); | |
6256 | operands[8] = GEN_INT (INTVAL (operands[2]) + INTVAL (operands[5]));") | |
6257 | ||
6258 | ; | |
6259 | ; Block xor (XC) patterns with src == dest. | |
6260 | ; | |
6261 | ||
6262 | (define_insn "*xc_zero" | |
6263 | [(set (match_operand:BLK 0 "memory_operand" "=Q") | |
6264 | (const_int 0)) | |
6265 | (use (match_operand 1 "const_int_operand" "n")) | |
1ca361fd | 6266 | (clobber (reg:CC CC_REGNUM))] |
9dffd3ff | 6267 | "INTVAL (operands[1]) >= 1 && INTVAL (operands[1]) <= 256" |
0574acbe | 6268 | "xc\t%O0(%1,%R0),%S0" |
1822f0d6 | 6269 | [(set_attr "op_type" "SS")]) |
9dffd3ff | 6270 | |
6271 | (define_peephole2 | |
6272 | [(parallel | |
6273 | [(set (match_operand:BLK 0 "memory_operand" "") | |
6274 | (const_int 0)) | |
6275 | (use (match_operand 1 "const_int_operand" "")) | |
1ca361fd | 6276 | (clobber (reg:CC CC_REGNUM))]) |
9dffd3ff | 6277 | (parallel |
6278 | [(set (match_operand:BLK 2 "memory_operand" "") | |
6279 | (const_int 0)) | |
6280 | (use (match_operand 3 "const_int_operand" "")) | |
1ca361fd | 6281 | (clobber (reg:CC CC_REGNUM))])] |
9dffd3ff | 6282 | "s390_offset_p (operands[0], operands[2], operands[1]) |
6283 | && INTVAL (operands[1]) + INTVAL (operands[3]) <= 256" | |
6284 | [(parallel | |
6285 | [(set (match_dup 4) (const_int 0)) | |
6286 | (use (match_dup 5)) | |
1ca361fd | 6287 | (clobber (reg:CC CC_REGNUM))])] |
9dffd3ff | 6288 | "operands[4] = gen_rtx_MEM (BLKmode, XEXP (operands[0], 0)); |
6289 | operands[5] = GEN_INT (INTVAL (operands[1]) + INTVAL (operands[3]));") | |
6290 | ||
4673c1a0 | 6291 | |
6292 | ;; | |
6293 | ;;- Negate instructions. | |
6294 | ;; | |
6295 | ||
6296 | ; | |
37af157c | 6297 | ; neg(di|si)2 instruction pattern(s). |
4673c1a0 | 6298 | ; |
6299 | ||
37af157c | 6300 | (define_expand "neg<mode>2" |
4673c1a0 | 6301 | [(parallel |
37af157c | 6302 | [(set (match_operand:DSI 0 "register_operand" "=d") |
6303 | (neg:DSI (match_operand:DSI 1 "register_operand" "d"))) | |
1ca361fd | 6304 | (clobber (reg:CC CC_REGNUM))])] |
4673c1a0 | 6305 | "" |
6306 | "") | |
6307 | ||
9be33ca2 | 6308 | (define_insn "*negdi2_sign_cc" |
1ca361fd | 6309 | [(set (reg CC_REGNUM) |
9be33ca2 | 6310 | (compare (neg:DI (ashiftrt:DI (ashift:DI (subreg:DI |
6311 | (match_operand:SI 1 "register_operand" "d") 0) | |
6312 | (const_int 32)) (const_int 32))) | |
6313 | (const_int 0))) | |
6314 | (set (match_operand:DI 0 "register_operand" "=d") | |
6315 | (neg:DI (sign_extend:DI (match_dup 1))))] | |
6316 | "TARGET_64BIT && s390_match_ccmode (insn, CCAmode)" | |
6317 | "lcgfr\t%0,%1" | |
6318 | [(set_attr "op_type" "RRE")]) | |
6319 | ||
6320 | (define_insn "*negdi2_sign" | |
6321 | [(set (match_operand:DI 0 "register_operand" "=d") | |
6322 | (neg:DI (sign_extend:DI (match_operand:SI 1 "register_operand" "d")))) | |
1ca361fd | 6323 | (clobber (reg:CC CC_REGNUM))] |
9be33ca2 | 6324 | "TARGET_64BIT" |
6325 | "lcgfr\t%0,%1" | |
6326 | [(set_attr "op_type" "RRE")]) | |
6327 | ||
87bc9927 | 6328 | ; lcr, lcgr |
37af157c | 6329 | (define_insn "*neg<mode>2_cc" |
1ca361fd | 6330 | [(set (reg CC_REGNUM) |
37af157c | 6331 | (compare (neg:GPR (match_operand:GPR 1 "register_operand" "d")) |
9be33ca2 | 6332 | (const_int 0))) |
37af157c | 6333 | (set (match_operand:GPR 0 "register_operand" "=d") |
6334 | (neg:GPR (match_dup 1)))] | |
6335 | "s390_match_ccmode (insn, CCAmode)" | |
6336 | "lc<g>r\t%0,%1" | |
6337 | [(set_attr "op_type" "RR<E>")]) | |
87bc9927 | 6338 | |
6339 | ; lcr, lcgr | |
37af157c | 6340 | (define_insn "*neg<mode>2_cconly" |
1ca361fd | 6341 | [(set (reg CC_REGNUM) |
37af157c | 6342 | (compare (neg:GPR (match_operand:GPR 1 "register_operand" "d")) |
9be33ca2 | 6343 | (const_int 0))) |
37af157c | 6344 | (clobber (match_scratch:GPR 0 "=d"))] |
6345 | "s390_match_ccmode (insn, CCAmode)" | |
6346 | "lc<g>r\t%0,%1" | |
6347 | [(set_attr "op_type" "RR<E>")]) | |
87bc9927 | 6348 | |
6349 | ; lcr, lcgr | |
37af157c | 6350 | (define_insn "*neg<mode>2" |
6351 | [(set (match_operand:GPR 0 "register_operand" "=d") | |
6352 | (neg:GPR (match_operand:GPR 1 "register_operand" "d"))) | |
1ca361fd | 6353 | (clobber (reg:CC CC_REGNUM))] |
37af157c | 6354 | "" |
6355 | "lc<g>r\t%0,%1" | |
6356 | [(set_attr "op_type" "RR<E>")]) | |
4673c1a0 | 6357 | |
9be33ca2 | 6358 | (define_insn_and_split "*negdi2_31" |
4673c1a0 | 6359 | [(set (match_operand:DI 0 "register_operand" "=d") |
6360 | (neg:DI (match_operand:DI 1 "register_operand" "d"))) | |
1ca361fd | 6361 | (clobber (reg:CC CC_REGNUM))] |
4673c1a0 | 6362 | "!TARGET_64BIT" |
9be33ca2 | 6363 | "#" |
6364 | "&& reload_completed" | |
6365 | [(parallel | |
6366 | [(set (match_dup 2) (neg:SI (match_dup 3))) | |
1ca361fd | 6367 | (clobber (reg:CC CC_REGNUM))]) |
9be33ca2 | 6368 | (parallel |
1ca361fd | 6369 | [(set (reg:CCAP CC_REGNUM) |
9be33ca2 | 6370 | (compare:CCAP (neg:SI (match_dup 5)) (const_int 0))) |
6371 | (set (match_dup 4) (neg:SI (match_dup 5)))]) | |
6372 | (set (pc) | |
1ca361fd | 6373 | (if_then_else (ne (reg:CCAP CC_REGNUM) (const_int 0)) |
9be33ca2 | 6374 | (pc) |
6375 | (label_ref (match_dup 6)))) | |
6376 | (parallel | |
6377 | [(set (match_dup 2) (plus:SI (match_dup 2) (const_int -1))) | |
1ca361fd | 6378 | (clobber (reg:CC CC_REGNUM))]) |
9be33ca2 | 6379 | (match_dup 6)] |
6380 | "operands[2] = operand_subword (operands[0], 0, 0, DImode); | |
6381 | operands[3] = operand_subword (operands[1], 0, 0, DImode); | |
6382 | operands[4] = operand_subword (operands[0], 1, 0, DImode); | |
6383 | operands[5] = operand_subword (operands[1], 1, 0, DImode); | |
6384 | operands[6] = gen_label_rtx ();") | |
4673c1a0 | 6385 | |
4673c1a0 | 6386 | ; |
8052065f | 6387 | ; neg(df|sf)2 instruction pattern(s). |
4673c1a0 | 6388 | ; |
6389 | ||
8052065f | 6390 | (define_expand "neg<mode>2" |
4673c1a0 | 6391 | [(parallel |
708607d5 | 6392 | [(set (match_operand:BFP 0 "register_operand" "=f") |
6393 | (neg:BFP (match_operand:BFP 1 "register_operand" "f"))) | |
1ca361fd | 6394 | (clobber (reg:CC CC_REGNUM))])] |
4673c1a0 | 6395 | "TARGET_HARD_FLOAT" |
6396 | "") | |
6397 | ||
87bc9927 | 6398 | ; lcxbr, lcdbr, lcebr |
8052065f | 6399 | (define_insn "*neg<mode>2_cc" |
1ca361fd | 6400 | [(set (reg CC_REGNUM) |
708607d5 | 6401 | (compare (neg:BFP (match_operand:BFP 1 "register_operand" "f")) |
6402 | (match_operand:BFP 2 "const0_operand" ""))) | |
6403 | (set (match_operand:BFP 0 "register_operand" "=f") | |
6404 | (neg:BFP (match_dup 1)))] | |
095798e3 | 6405 | "s390_match_ccmode (insn, CCSmode) && TARGET_HARD_FLOAT" |
429f9fdb | 6406 | "lc<xde>br\t%0,%1" |
9be33ca2 | 6407 | [(set_attr "op_type" "RRE") |
8052065f | 6408 | (set_attr "type" "fsimp<mode>")]) |
87bc9927 | 6409 | |
6410 | ; lcxbr, lcdbr, lcebr | |
8052065f | 6411 | (define_insn "*neg<mode>2_cconly" |
1ca361fd | 6412 | [(set (reg CC_REGNUM) |
708607d5 | 6413 | (compare (neg:BFP (match_operand:BFP 1 "register_operand" "f")) |
6414 | (match_operand:BFP 2 "const0_operand" ""))) | |
6415 | (clobber (match_scratch:BFP 0 "=f"))] | |
095798e3 | 6416 | "s390_match_ccmode (insn, CCSmode) && TARGET_HARD_FLOAT" |
429f9fdb | 6417 | "lc<xde>br\t%0,%1" |
9be33ca2 | 6418 | [(set_attr "op_type" "RRE") |
8052065f | 6419 | (set_attr "type" "fsimp<mode>")]) |
87bc9927 | 6420 | |
0c2edaa7 | 6421 | ; lcdfr |
6422 | (define_insn "*neg<mode>2_nocc" | |
1f8e70bc | 6423 | [(set (match_operand:FP 0 "register_operand" "=f") |
6424 | (neg:FP (match_operand:FP 1 "register_operand" "<fT0>")))] | |
0c2edaa7 | 6425 | "TARGET_HARD_FLOAT && TARGET_DFP" |
6426 | "lcdfr\t%0,%1" | |
6427 | [(set_attr "op_type" "RRE") | |
1f8e70bc | 6428 | (set_attr "type" "fsimp<bfp>")]) |
0c2edaa7 | 6429 | |
87bc9927 | 6430 | ; lcxbr, lcdbr, lcebr |
8052065f | 6431 | (define_insn "*neg<mode>2" |
708607d5 | 6432 | [(set (match_operand:BFP 0 "register_operand" "=f") |
6433 | (neg:BFP (match_operand:BFP 1 "register_operand" "f"))) | |
1ca361fd | 6434 | (clobber (reg:CC CC_REGNUM))] |
095798e3 | 6435 | "TARGET_HARD_FLOAT" |
429f9fdb | 6436 | "lc<xde>br\t%0,%1" |
71343e6b | 6437 | [(set_attr "op_type" "RRE") |
8052065f | 6438 | (set_attr "type" "fsimp<mode>")]) |
4673c1a0 | 6439 | |
4673c1a0 | 6440 | |
6441 | ;; | |
6442 | ;;- Absolute value instructions. | |
6443 | ;; | |
6444 | ||
6445 | ; | |
37af157c | 6446 | ; abs(di|si)2 instruction pattern(s). |
4673c1a0 | 6447 | ; |
6448 | ||
9be33ca2 | 6449 | (define_insn "*absdi2_sign_cc" |
1ca361fd | 6450 | [(set (reg CC_REGNUM) |
9be33ca2 | 6451 | (compare (abs:DI (ashiftrt:DI (ashift:DI (subreg:DI |
6452 | (match_operand:SI 1 "register_operand" "d") 0) | |
6453 | (const_int 32)) (const_int 32))) | |
6454 | (const_int 0))) | |
6455 | (set (match_operand:DI 0 "register_operand" "=d") | |
6456 | (abs:DI (sign_extend:DI (match_dup 1))))] | |
6457 | "TARGET_64BIT && s390_match_ccmode (insn, CCAmode)" | |
6458 | "lpgfr\t%0,%1" | |
6459 | [(set_attr "op_type" "RRE")]) | |
6460 | ||
6461 | (define_insn "*absdi2_sign" | |
6462 | [(set (match_operand:DI 0 "register_operand" "=d") | |
6463 | (abs:DI (sign_extend:DI (match_operand:SI 1 "register_operand" "d")))) | |
1ca361fd | 6464 | (clobber (reg:CC CC_REGNUM))] |
9be33ca2 | 6465 | "TARGET_64BIT" |
6466 | "lpgfr\t%0,%1" | |
6467 | [(set_attr "op_type" "RRE")]) | |
6468 | ||
87bc9927 | 6469 | ; lpr, lpgr |
37af157c | 6470 | (define_insn "*abs<mode>2_cc" |
1ca361fd | 6471 | [(set (reg CC_REGNUM) |
37af157c | 6472 | (compare (abs:GPR (match_operand:DI 1 "register_operand" "d")) |
9be33ca2 | 6473 | (const_int 0))) |
37af157c | 6474 | (set (match_operand:GPR 0 "register_operand" "=d") |
6475 | (abs:GPR (match_dup 1)))] | |
9be33ca2 | 6476 | "s390_match_ccmode (insn, CCAmode)" |
37af157c | 6477 | "lp<g>r\t%0,%1" |
6478 | [(set_attr "op_type" "RR<E>")]) | |
87bc9927 | 6479 | |
6480 | ; lpr, lpgr | |
37af157c | 6481 | (define_insn "*abs<mode>2_cconly" |
1ca361fd | 6482 | [(set (reg CC_REGNUM) |
37af157c | 6483 | (compare (abs:GPR (match_operand:GPR 1 "register_operand" "d")) |
9be33ca2 | 6484 | (const_int 0))) |
37af157c | 6485 | (clobber (match_scratch:GPR 0 "=d"))] |
9be33ca2 | 6486 | "s390_match_ccmode (insn, CCAmode)" |
37af157c | 6487 | "lp<g>r\t%0,%1" |
6488 | [(set_attr "op_type" "RR<E>")]) | |
87bc9927 | 6489 | |
6490 | ; lpr, lpgr | |
37af157c | 6491 | (define_insn "abs<mode>2" |
6492 | [(set (match_operand:GPR 0 "register_operand" "=d") | |
6493 | (abs:GPR (match_operand:GPR 1 "register_operand" "d"))) | |
1ca361fd | 6494 | (clobber (reg:CC CC_REGNUM))] |
4673c1a0 | 6495 | "" |
37af157c | 6496 | "lp<g>r\t%0,%1" |
6497 | [(set_attr "op_type" "RR<E>")]) | |
4673c1a0 | 6498 | |
4673c1a0 | 6499 | ; |
8052065f | 6500 | ; abs(df|sf)2 instruction pattern(s). |
4673c1a0 | 6501 | ; |
6502 | ||
8052065f | 6503 | (define_expand "abs<mode>2" |
4673c1a0 | 6504 | [(parallel |
708607d5 | 6505 | [(set (match_operand:BFP 0 "register_operand" "=f") |
6506 | (abs:BFP (match_operand:BFP 1 "register_operand" "f"))) | |
1ca361fd | 6507 | (clobber (reg:CC CC_REGNUM))])] |
4673c1a0 | 6508 | "TARGET_HARD_FLOAT" |
6509 | "") | |
6510 | ||
87bc9927 | 6511 | ; lpxbr, lpdbr, lpebr |
8052065f | 6512 | (define_insn "*abs<mode>2_cc" |
1ca361fd | 6513 | [(set (reg CC_REGNUM) |
708607d5 | 6514 | (compare (abs:BFP (match_operand:BFP 1 "register_operand" "f")) |
6515 | (match_operand:BFP 2 "const0_operand" ""))) | |
6516 | (set (match_operand:BFP 0 "register_operand" "=f") | |
6517 | (abs:BFP (match_dup 1)))] | |
095798e3 | 6518 | "s390_match_ccmode (insn, CCSmode) && TARGET_HARD_FLOAT" |
429f9fdb | 6519 | "lp<xde>br\t%0,%1" |
9be33ca2 | 6520 | [(set_attr "op_type" "RRE") |
8052065f | 6521 | (set_attr "type" "fsimp<mode>")]) |
87bc9927 | 6522 | |
6523 | ; lpxbr, lpdbr, lpebr | |
8052065f | 6524 | (define_insn "*abs<mode>2_cconly" |
1ca361fd | 6525 | [(set (reg CC_REGNUM) |
708607d5 | 6526 | (compare (abs:BFP (match_operand:BFP 1 "register_operand" "f")) |
6527 | (match_operand:BFP 2 "const0_operand" ""))) | |
6528 | (clobber (match_scratch:BFP 0 "=f"))] | |
095798e3 | 6529 | "s390_match_ccmode (insn, CCSmode) && TARGET_HARD_FLOAT" |
429f9fdb | 6530 | "lp<xde>br\t%0,%1" |
9be33ca2 | 6531 | [(set_attr "op_type" "RRE") |
8052065f | 6532 | (set_attr "type" "fsimp<mode>")]) |
87bc9927 | 6533 | |
0c2edaa7 | 6534 | ; lpdfr |
6535 | (define_insn "*abs<mode>2_nocc" | |
1f8e70bc | 6536 | [(set (match_operand:FP 0 "register_operand" "=f") |
6537 | (abs:FP (match_operand:FP 1 "register_operand" "<fT0>")))] | |
0c2edaa7 | 6538 | "TARGET_HARD_FLOAT && TARGET_DFP" |
6539 | "lpdfr\t%0,%1" | |
6540 | [(set_attr "op_type" "RRE") | |
1f8e70bc | 6541 | (set_attr "type" "fsimp<bfp>")]) |
0c2edaa7 | 6542 | |
87bc9927 | 6543 | ; lpxbr, lpdbr, lpebr |
8052065f | 6544 | (define_insn "*abs<mode>2" |
708607d5 | 6545 | [(set (match_operand:BFP 0 "register_operand" "=f") |
6546 | (abs:BFP (match_operand:BFP 1 "register_operand" "f"))) | |
1ca361fd | 6547 | (clobber (reg:CC CC_REGNUM))] |
095798e3 | 6548 | "TARGET_HARD_FLOAT" |
429f9fdb | 6549 | "lp<xde>br\t%0,%1" |
71343e6b | 6550 | [(set_attr "op_type" "RRE") |
8052065f | 6551 | (set_attr "type" "fsimp<mode>")]) |
4673c1a0 | 6552 | |
4673c1a0 | 6553 | |
e9fd5349 | 6554 | ;; |
6555 | ;;- Negated absolute value instructions | |
6556 | ;; | |
6557 | ||
6558 | ; | |
6559 | ; Integer | |
6560 | ; | |
6561 | ||
9be33ca2 | 6562 | (define_insn "*negabsdi2_sign_cc" |
1ca361fd | 6563 | [(set (reg CC_REGNUM) |
9be33ca2 | 6564 | (compare (neg:DI (abs:DI (ashiftrt:DI (ashift:DI (subreg:DI |
6565 | (match_operand:SI 1 "register_operand" "d") 0) | |
6566 | (const_int 32)) (const_int 32)))) | |
6567 | (const_int 0))) | |
6568 | (set (match_operand:DI 0 "register_operand" "=d") | |
6569 | (neg:DI (abs:DI (sign_extend:DI (match_dup 1)))))] | |
6570 | "TARGET_64BIT && s390_match_ccmode (insn, CCAmode)" | |
6571 | "lngfr\t%0,%1" | |
6572 | [(set_attr "op_type" "RRE")]) | |
6573 | ||
6574 | (define_insn "*negabsdi2_sign" | |
6575 | [(set (match_operand:DI 0 "register_operand" "=d") | |
6576 | (neg:DI (abs:DI (sign_extend:DI | |
6577 | (match_operand:SI 1 "register_operand" "d"))))) | |
1ca361fd | 6578 | (clobber (reg:CC CC_REGNUM))] |
9be33ca2 | 6579 | "TARGET_64BIT" |
6580 | "lngfr\t%0,%1" | |
6581 | [(set_attr "op_type" "RRE")]) | |
e9fd5349 | 6582 | |
87bc9927 | 6583 | ; lnr, lngr |
37af157c | 6584 | (define_insn "*negabs<mode>2_cc" |
1ca361fd | 6585 | [(set (reg CC_REGNUM) |
37af157c | 6586 | (compare (neg:GPR (abs:GPR (match_operand:GPR 1 "register_operand" "d"))) |
9be33ca2 | 6587 | (const_int 0))) |
37af157c | 6588 | (set (match_operand:GPR 0 "register_operand" "=d") |
6589 | (neg:GPR (abs:GPR (match_dup 1))))] | |
9be33ca2 | 6590 | "s390_match_ccmode (insn, CCAmode)" |
37af157c | 6591 | "ln<g>r\t%0,%1" |
6592 | [(set_attr "op_type" "RR<E>")]) | |
87bc9927 | 6593 | |
6594 | ; lnr, lngr | |
37af157c | 6595 | (define_insn "*negabs<mode>2_cconly" |
1ca361fd | 6596 | [(set (reg CC_REGNUM) |
37af157c | 6597 | (compare (neg:GPR (abs:GPR (match_operand:GPR 1 "register_operand" "d"))) |
9be33ca2 | 6598 | (const_int 0))) |
37af157c | 6599 | (clobber (match_scratch:GPR 0 "=d"))] |
9be33ca2 | 6600 | "s390_match_ccmode (insn, CCAmode)" |
37af157c | 6601 | "ln<g>r\t%0,%1" |
6602 | [(set_attr "op_type" "RR<E>")]) | |
87bc9927 | 6603 | |
6604 | ; lnr, lngr | |
37af157c | 6605 | (define_insn "*negabs<mode>2" |
6606 | [(set (match_operand:GPR 0 "register_operand" "=d") | |
6607 | (neg:GPR (abs:GPR (match_operand:GPR 1 "register_operand" "d")))) | |
1ca361fd | 6608 | (clobber (reg:CC CC_REGNUM))] |
9be33ca2 | 6609 | "" |
37af157c | 6610 | "ln<g>r\t%0,%1" |
6611 | [(set_attr "op_type" "RR<E>")]) | |
9be33ca2 | 6612 | |
e9fd5349 | 6613 | ; |
6614 | ; Floating point | |
6615 | ; | |
6616 | ||
87bc9927 | 6617 | ; lnxbr, lndbr, lnebr |
8052065f | 6618 | (define_insn "*negabs<mode>2_cc" |
1ca361fd | 6619 | [(set (reg CC_REGNUM) |
708607d5 | 6620 | (compare (neg:BFP (abs:BFP (match_operand:BFP 1 "register_operand" "f"))) |
6621 | (match_operand:BFP 2 "const0_operand" ""))) | |
6622 | (set (match_operand:BFP 0 "register_operand" "=f") | |
6623 | (neg:BFP (abs:BFP (match_dup 1))))] | |
095798e3 | 6624 | "s390_match_ccmode (insn, CCSmode) && TARGET_HARD_FLOAT" |
429f9fdb | 6625 | "ln<xde>br\t%0,%1" |
9be33ca2 | 6626 | [(set_attr "op_type" "RRE") |
8052065f | 6627 | (set_attr "type" "fsimp<mode>")]) |
87bc9927 | 6628 | |
6629 | ; lnxbr, lndbr, lnebr | |
8052065f | 6630 | (define_insn "*negabs<mode>2_cconly" |
1ca361fd | 6631 | [(set (reg CC_REGNUM) |
708607d5 | 6632 | (compare (neg:BFP (abs:BFP (match_operand:BFP 1 "register_operand" "f"))) |
6633 | (match_operand:BFP 2 "const0_operand" ""))) | |
6634 | (clobber (match_scratch:BFP 0 "=f"))] | |
095798e3 | 6635 | "s390_match_ccmode (insn, CCSmode) && TARGET_HARD_FLOAT" |
429f9fdb | 6636 | "ln<xde>br\t%0,%1" |
9be33ca2 | 6637 | [(set_attr "op_type" "RRE") |
8052065f | 6638 | (set_attr "type" "fsimp<mode>")]) |
87bc9927 | 6639 | |
0c2edaa7 | 6640 | ; lndfr |
6641 | (define_insn "*negabs<mode>2_nocc" | |
1f8e70bc | 6642 | [(set (match_operand:FP 0 "register_operand" "=f") |
6643 | (neg:FP (abs:FP (match_operand:BFP 1 "register_operand" "<fT0>"))))] | |
0c2edaa7 | 6644 | "TARGET_HARD_FLOAT && TARGET_DFP" |
6645 | "lndfr\t%0,%1" | |
6646 | [(set_attr "op_type" "RRE") | |
1f8e70bc | 6647 | (set_attr "type" "fsimp<bfp>")]) |
0c2edaa7 | 6648 | |
87bc9927 | 6649 | ; lnxbr, lndbr, lnebr |
8052065f | 6650 | (define_insn "*negabs<mode>2" |
708607d5 | 6651 | [(set (match_operand:BFP 0 "register_operand" "=f") |
6652 | (neg:BFP (abs:BFP (match_operand:BFP 1 "register_operand" "f")))) | |
1ca361fd | 6653 | (clobber (reg:CC CC_REGNUM))] |
095798e3 | 6654 | "TARGET_HARD_FLOAT" |
429f9fdb | 6655 | "ln<xde>br\t%0,%1" |
9be33ca2 | 6656 | [(set_attr "op_type" "RRE") |
8052065f | 6657 | (set_attr "type" "fsimp<mode>")]) |
9be33ca2 | 6658 | |
0c2edaa7 | 6659 | ;; |
6660 | ;;- Copy sign instructions | |
6661 | ;; | |
6662 | ||
6663 | ; cpsdr | |
6664 | (define_insn "copysign<mode>3" | |
1f8e70bc | 6665 | [(set (match_operand:FP 0 "register_operand" "=f") |
6666 | (unspec:FP [(match_operand:FP 1 "register_operand" "<fT0>") | |
6667 | (match_operand:FP 2 "register_operand" "f")] | |
0c2edaa7 | 6668 | UNSPEC_COPYSIGN))] |
6669 | "TARGET_HARD_FLOAT && TARGET_DFP" | |
6670 | "cpsdr\t%0,%2,%1" | |
6671 | [(set_attr "op_type" "RRF") | |
1f8e70bc | 6672 | (set_attr "type" "fsimp<bfp>")]) |
0c2edaa7 | 6673 | |
8b4a4127 | 6674 | ;; |
6675 | ;;- Square root instructions. | |
6676 | ;; | |
6677 | ||
6678 | ; | |
8052065f | 6679 | ; sqrt(df|sf)2 instruction pattern(s). |
8b4a4127 | 6680 | ; |
6681 | ||
87bc9927 | 6682 | ; sqxbr, sqdbr, sqebr, sqxb, sqdb, sqeb |
8052065f | 6683 | (define_insn "sqrt<mode>2" |
708607d5 | 6684 | [(set (match_operand:BFP 0 "register_operand" "=f,f") |
6685 | (sqrt:BFP (match_operand:BFP 1 "general_operand" "f,<Rf>")))] | |
095798e3 | 6686 | "TARGET_HARD_FLOAT" |
8b4a4127 | 6687 | "@ |
429f9fdb | 6688 | sq<xde>br\t%0,%1 |
6689 | sq<xde>b\t%0,%1" | |
f9a81c6e | 6690 | [(set_attr "op_type" "RRE,RXE") |
8052065f | 6691 | (set_attr "type" "fsqrt<mode>")]) |
8b4a4127 | 6692 | |
4673c1a0 | 6693 | |
6694 | ;; | |
6695 | ;;- One complement instructions. | |
6696 | ;; | |
6697 | ||
6698 | ; | |
61da801c | 6699 | ; one_cmpl(di|si|hi|qi)2 instruction pattern(s). |
4673c1a0 | 6700 | ; |
f81e845f | 6701 | |
61da801c | 6702 | (define_expand "one_cmpl<mode>2" |
8b4a4127 | 6703 | [(parallel |
61da801c | 6704 | [(set (match_operand:INT 0 "register_operand" "") |
6705 | (xor:INT (match_operand:INT 1 "register_operand" "") | |
6706 | (const_int -1))) | |
1ca361fd | 6707 | (clobber (reg:CC CC_REGNUM))])] |
4673c1a0 | 6708 | "" |
8b4a4127 | 6709 | "") |
4673c1a0 | 6710 | |
6711 | ||
163277cf | 6712 | ;; |
6713 | ;; Find leftmost bit instructions. | |
6714 | ;; | |
6715 | ||
6716 | (define_expand "clzdi2" | |
6717 | [(set (match_operand:DI 0 "register_operand" "=d") | |
6718 | (clz:DI (match_operand:DI 1 "register_operand" "d")))] | |
6719 | "TARGET_EXTIMM && TARGET_64BIT" | |
6720 | { | |
6721 | rtx insn, clz_equal; | |
6722 | rtx wide_reg = gen_reg_rtx (TImode); | |
6723 | rtx msb = gen_rtx_CONST_INT (DImode, (unsigned HOST_WIDE_INT) 1 << 63); | |
6724 | ||
6725 | clz_equal = gen_rtx_CLZ (DImode, operands[1]); | |
6726 | ||
6727 | emit_insn (gen_clztidi2 (wide_reg, operands[1], msb)); | |
6728 | ||
6729 | insn = emit_move_insn (operands[0], gen_highpart (DImode, wide_reg)); | |
24153880 | 6730 | set_unique_reg_note (insn, REG_EQUAL, clz_equal); |
163277cf | 6731 | |
6732 | DONE; | |
6733 | }) | |
6734 | ||
6735 | (define_insn "clztidi2" | |
6736 | [(set (match_operand:TI 0 "register_operand" "=d") | |
6737 | (ior:TI | |
6738 | (ashift:TI | |
6739 | (zero_extend:TI | |
6740 | (xor:DI (match_operand:DI 1 "register_operand" "d") | |
6741 | (lshiftrt (match_operand:DI 2 "const_int_operand" "") | |
6742 | (subreg:SI (clz:DI (match_dup 1)) 4)))) | |
6743 | ||
6744 | (const_int 64)) | |
6745 | (zero_extend:TI (clz:DI (match_dup 1))))) | |
6746 | (clobber (reg:CC CC_REGNUM))] | |
6747 | "(unsigned HOST_WIDE_INT) INTVAL (operands[2]) | |
6748 | == (unsigned HOST_WIDE_INT) 1 << 63 | |
6749 | && TARGET_EXTIMM && TARGET_64BIT" | |
6750 | "flogr\t%0,%1" | |
6751 | [(set_attr "op_type" "RRE")]) | |
6752 | ||
6753 | ||
4673c1a0 | 6754 | ;; |
6755 | ;;- Rotate instructions. | |
6756 | ;; | |
6757 | ||
6758 | ; | |
37af157c | 6759 | ; rotl(di|si)3 instruction pattern(s). |
4673c1a0 | 6760 | ; |
6761 | ||
87bc9927 | 6762 | ; rll, rllg |
37af157c | 6763 | (define_insn "rotl<mode>3" |
6764 | [(set (match_operand:GPR 0 "register_operand" "=d") | |
6765 | (rotate:GPR (match_operand:GPR 1 "register_operand" "d") | |
417cba42 | 6766 | (match_operand:SI 2 "shift_count_or_setmem_operand" "Y")))] |
dafc8d45 | 6767 | "TARGET_CPU_ZARCH" |
37af157c | 6768 | "rll<g>\t%0,%1,%Y2" |
71343e6b | 6769 | [(set_attr "op_type" "RSE") |
6770 | (set_attr "atype" "reg")]) | |
4673c1a0 | 6771 | |
87bc9927 | 6772 | ; rll, rllg |
417cba42 | 6773 | (define_insn "*rotl<mode>3_and" |
6774 | [(set (match_operand:GPR 0 "register_operand" "=d") | |
6775 | (rotate:GPR (match_operand:GPR 1 "register_operand" "d") | |
6776 | (and:SI (match_operand:SI 2 "shift_count_or_setmem_operand" "Y") | |
6777 | (match_operand:SI 3 "const_int_operand" "n"))))] | |
6778 | "TARGET_CPU_ZARCH && (INTVAL (operands[3]) & 63) == 63" | |
6779 | "rll<g>\t%0,%1,%Y2" | |
6780 | [(set_attr "op_type" "RSE") | |
6781 | (set_attr "atype" "reg")]) | |
6782 | ||
4673c1a0 | 6783 | |
6784 | ;; | |
ba400ef2 | 6785 | ;;- Shift instructions. |
4673c1a0 | 6786 | ;; |
4673c1a0 | 6787 | |
6788 | ; | |
38d26fa6 | 6789 | ; (ashl|lshr)(di|si)3 instruction pattern(s). |
4673c1a0 | 6790 | ; |
6791 | ||
38d26fa6 | 6792 | (define_expand "<shift><mode>3" |
6793 | [(set (match_operand:DSI 0 "register_operand" "") | |
6794 | (SHIFT:DSI (match_operand:DSI 1 "register_operand" "") | |
6795 | (match_operand:SI 2 "shift_count_or_setmem_operand" "")))] | |
4673c1a0 | 6796 | "" |
6797 | "") | |
6798 | ||
87bc9927 | 6799 | ; sldl, srdl |
ba400ef2 | 6800 | (define_insn "*<shift>di3_31" |
63ebd742 | 6801 | [(set (match_operand:DI 0 "register_operand" "=d") |
ba400ef2 | 6802 | (SHIFT:DI (match_operand:DI 1 "register_operand" "0") |
417cba42 | 6803 | (match_operand:SI 2 "shift_count_or_setmem_operand" "Y")))] |
4673c1a0 | 6804 | "!TARGET_64BIT" |
ba400ef2 | 6805 | "s<lr>dl\t%0,%Y2" |
71343e6b | 6806 | [(set_attr "op_type" "RS") |
6807 | (set_attr "atype" "reg")]) | |
4673c1a0 | 6808 | |
87bc9927 | 6809 | ; sll, srl, sllg, srlg |
38d26fa6 | 6810 | (define_insn "*<shift><mode>3" |
6811 | [(set (match_operand:GPR 0 "register_operand" "=d") | |
6812 | (SHIFT:GPR (match_operand:GPR 1 "register_operand" "<d0>") | |
6813 | (match_operand:SI 2 "shift_count_or_setmem_operand" "Y")))] | |
6814 | "" | |
6815 | "s<lr>l<g>\t%0,<1>%Y2" | |
6816 | [(set_attr "op_type" "RS<E>") | |
71343e6b | 6817 | (set_attr "atype" "reg")]) |
4673c1a0 | 6818 | |
87bc9927 | 6819 | ; sldl, srdl |
417cba42 | 6820 | (define_insn "*<shift>di3_31_and" |
6821 | [(set (match_operand:DI 0 "register_operand" "=d") | |
6822 | (SHIFT:DI (match_operand:DI 1 "register_operand" "0") | |
6823 | (and:SI (match_operand:SI 2 "shift_count_or_setmem_operand" "Y") | |
6824 | (match_operand:SI 3 "const_int_operand" "n"))))] | |
6825 | "!TARGET_64BIT && (INTVAL (operands[3]) & 63) == 63" | |
6826 | "s<lr>dl\t%0,%Y2" | |
6827 | [(set_attr "op_type" "RS") | |
6828 | (set_attr "atype" "reg")]) | |
6829 | ||
87bc9927 | 6830 | ; sll, srl, sllg, srlg |
38d26fa6 | 6831 | (define_insn "*<shift><mode>3_and" |
6832 | [(set (match_operand:GPR 0 "register_operand" "=d") | |
6833 | (SHIFT:GPR (match_operand:GPR 1 "register_operand" "<d0>") | |
6834 | (and:SI (match_operand:SI 2 "shift_count_or_setmem_operand" "Y") | |
6835 | (match_operand:SI 3 "const_int_operand" "n"))))] | |
6836 | "(INTVAL (operands[3]) & 63) == 63" | |
6837 | "s<lr>l<g>\t%0,<1>%Y2" | |
6838 | [(set_attr "op_type" "RS<E>") | |
417cba42 | 6839 | (set_attr "atype" "reg")]) |
6840 | ||
4673c1a0 | 6841 | ; |
38d26fa6 | 6842 | ; ashr(di|si)3 instruction pattern(s). |
4673c1a0 | 6843 | ; |
6844 | ||
38d26fa6 | 6845 | (define_expand "ashr<mode>3" |
4673c1a0 | 6846 | [(parallel |
38d26fa6 | 6847 | [(set (match_operand:DSI 0 "register_operand" "") |
6848 | (ashiftrt:DSI (match_operand:DSI 1 "register_operand" "") | |
6849 | (match_operand:SI 2 "shift_count_or_setmem_operand" ""))) | |
1ca361fd | 6850 | (clobber (reg:CC CC_REGNUM))])] |
4673c1a0 | 6851 | "" |
6852 | "") | |
6853 | ||
66a63c5b | 6854 | (define_insn "*ashrdi3_cc_31" |
1ca361fd | 6855 | [(set (reg CC_REGNUM) |
63ebd742 | 6856 | (compare (ashiftrt:DI (match_operand:DI 1 "register_operand" "0") |
417cba42 | 6857 | (match_operand:SI 2 "shift_count_or_setmem_operand" "Y")) |
66a63c5b | 6858 | (const_int 0))) |
63ebd742 | 6859 | (set (match_operand:DI 0 "register_operand" "=d") |
66a63c5b | 6860 | (ashiftrt:DI (match_dup 1) (match_dup 2)))] |
6861 | "!TARGET_64BIT && s390_match_ccmode(insn, CCSmode)" | |
63ebd742 | 6862 | "srda\t%0,%Y2" |
71343e6b | 6863 | [(set_attr "op_type" "RS") |
6864 | (set_attr "atype" "reg")]) | |
66a63c5b | 6865 | |
6866 | (define_insn "*ashrdi3_cconly_31" | |
1ca361fd | 6867 | [(set (reg CC_REGNUM) |
63ebd742 | 6868 | (compare (ashiftrt:DI (match_operand:DI 1 "register_operand" "0") |
417cba42 | 6869 | (match_operand:SI 2 "shift_count_or_setmem_operand" "Y")) |
66a63c5b | 6870 | (const_int 0))) |
63ebd742 | 6871 | (clobber (match_scratch:DI 0 "=d"))] |
66a63c5b | 6872 | "!TARGET_64BIT && s390_match_ccmode(insn, CCSmode)" |
63ebd742 | 6873 | "srda\t%0,%Y2" |
71343e6b | 6874 | [(set_attr "op_type" "RS") |
6875 | (set_attr "atype" "reg")]) | |
66a63c5b | 6876 | |
4673c1a0 | 6877 | (define_insn "*ashrdi3_31" |
63ebd742 | 6878 | [(set (match_operand:DI 0 "register_operand" "=d") |
6879 | (ashiftrt:DI (match_operand:DI 1 "register_operand" "0") | |
417cba42 | 6880 | (match_operand:SI 2 "shift_count_or_setmem_operand" "Y"))) |
1ca361fd | 6881 | (clobber (reg:CC CC_REGNUM))] |
4673c1a0 | 6882 | "!TARGET_64BIT" |
63ebd742 | 6883 | "srda\t%0,%Y2" |
71343e6b | 6884 | [(set_attr "op_type" "RS") |
6885 | (set_attr "atype" "reg")]) | |
f81e845f | 6886 | |
87bc9927 | 6887 | ; sra, srag |
38d26fa6 | 6888 | (define_insn "*ashr<mode>3_cc" |
1ca361fd | 6889 | [(set (reg CC_REGNUM) |
38d26fa6 | 6890 | (compare (ashiftrt:GPR (match_operand:GPR 1 "register_operand" "<d0>") |
6891 | (match_operand:SI 2 "shift_count_or_setmem_operand" "Y")) | |
66a63c5b | 6892 | (const_int 0))) |
38d26fa6 | 6893 | (set (match_operand:GPR 0 "register_operand" "=d") |
6894 | (ashiftrt:GPR (match_dup 1) (match_dup 2)))] | |
6895 | "s390_match_ccmode(insn, CCSmode)" | |
6896 | "sra<g>\t%0,<1>%Y2" | |
6897 | [(set_attr "op_type" "RS<E>") | |
71343e6b | 6898 | (set_attr "atype" "reg")]) |
66a63c5b | 6899 | |
87bc9927 | 6900 | ; sra, srag |
38d26fa6 | 6901 | (define_insn "*ashr<mode>3_cconly" |
1ca361fd | 6902 | [(set (reg CC_REGNUM) |
38d26fa6 | 6903 | (compare (ashiftrt:GPR (match_operand:GPR 1 "register_operand" "<d0>") |
6904 | (match_operand:SI 2 "shift_count_or_setmem_operand" "Y")) | |
66a63c5b | 6905 | (const_int 0))) |
38d26fa6 | 6906 | (clobber (match_scratch:GPR 0 "=d"))] |
6907 | "s390_match_ccmode(insn, CCSmode)" | |
6908 | "sra<g>\t%0,<1>%Y2" | |
6909 | [(set_attr "op_type" "RS<E>") | |
71343e6b | 6910 | (set_attr "atype" "reg")]) |
66a63c5b | 6911 | |
87bc9927 | 6912 | ; sra, srag |
38d26fa6 | 6913 | (define_insn "*ashr<mode>3" |
6914 | [(set (match_operand:GPR 0 "register_operand" "=d") | |
6915 | (ashiftrt:GPR (match_operand:GPR 1 "register_operand" "<d0>") | |
6916 | (match_operand:SI 2 "shift_count_or_setmem_operand" "Y"))) | |
1ca361fd | 6917 | (clobber (reg:CC CC_REGNUM))] |
38d26fa6 | 6918 | "" |
6919 | "sra<g>\t%0,<1>%Y2" | |
6920 | [(set_attr "op_type" "RS<E>") | |
71343e6b | 6921 | (set_attr "atype" "reg")]) |
6922 | ||
4673c1a0 | 6923 | |
417cba42 | 6924 | ; shift pattern with implicit ANDs |
6925 | ||
6926 | (define_insn "*ashrdi3_cc_31_and" | |
6927 | [(set (reg CC_REGNUM) | |
6928 | (compare (ashiftrt:DI (match_operand:DI 1 "register_operand" "0") | |
6929 | (and:SI (match_operand:SI 2 "shift_count_or_setmem_operand" "Y") | |
6930 | (match_operand:SI 3 "const_int_operand" "n"))) | |
6931 | (const_int 0))) | |
6932 | (set (match_operand:DI 0 "register_operand" "=d") | |
6933 | (ashiftrt:DI (match_dup 1) (and:SI (match_dup 2) (match_dup 3))))] | |
6934 | "!TARGET_64BIT && s390_match_ccmode(insn, CCSmode) | |
6935 | && (INTVAL (operands[3]) & 63) == 63" | |
6936 | "srda\t%0,%Y2" | |
6937 | [(set_attr "op_type" "RS") | |
6938 | (set_attr "atype" "reg")]) | |
6939 | ||
6940 | (define_insn "*ashrdi3_cconly_31_and" | |
6941 | [(set (reg CC_REGNUM) | |
6942 | (compare (ashiftrt:DI (match_operand:DI 1 "register_operand" "0") | |
6943 | (and:SI (match_operand:SI 2 "shift_count_or_setmem_operand" "Y") | |
6944 | (match_operand:SI 3 "const_int_operand" "n"))) | |
6945 | (const_int 0))) | |
6946 | (clobber (match_scratch:DI 0 "=d"))] | |
6947 | "!TARGET_64BIT && s390_match_ccmode(insn, CCSmode) | |
6948 | && (INTVAL (operands[3]) & 63) == 63" | |
6949 | "srda\t%0,%Y2" | |
6950 | [(set_attr "op_type" "RS") | |
6951 | (set_attr "atype" "reg")]) | |
6952 | ||
6953 | (define_insn "*ashrdi3_31_and" | |
6954 | [(set (match_operand:DI 0 "register_operand" "=d") | |
6955 | (ashiftrt:DI (match_operand:DI 1 "register_operand" "0") | |
6956 | (and:SI (match_operand:SI 2 "shift_count_or_setmem_operand" "Y") | |
6957 | (match_operand:SI 3 "const_int_operand" "n")))) | |
6958 | (clobber (reg:CC CC_REGNUM))] | |
6959 | "!TARGET_64BIT && (INTVAL (operands[3]) & 63) == 63" | |
6960 | "srda\t%0,%Y2" | |
6961 | [(set_attr "op_type" "RS") | |
6962 | (set_attr "atype" "reg")]) | |
6963 | ||
87bc9927 | 6964 | ; sra, srag |
38d26fa6 | 6965 | (define_insn "*ashr<mode>3_cc_and" |
417cba42 | 6966 | [(set (reg CC_REGNUM) |
38d26fa6 | 6967 | (compare (ashiftrt:GPR (match_operand:GPR 1 "register_operand" "<d0>") |
6968 | (and:SI (match_operand:SI 2 "shift_count_or_setmem_operand" "Y") | |
6969 | (match_operand:SI 3 "const_int_operand" "n"))) | |
417cba42 | 6970 | (const_int 0))) |
38d26fa6 | 6971 | (set (match_operand:GPR 0 "register_operand" "=d") |
6972 | (ashiftrt:GPR (match_dup 1) (and:SI (match_dup 2) (match_dup 3))))] | |
417cba42 | 6973 | "s390_match_ccmode(insn, CCSmode) && (INTVAL (operands[3]) & 63) == 63" |
38d26fa6 | 6974 | "sra<g>\t%0,<1>%Y2" |
6975 | [(set_attr "op_type" "RS<E>") | |
417cba42 | 6976 | (set_attr "atype" "reg")]) |
6977 | ||
87bc9927 | 6978 | ; sra, srag |
38d26fa6 | 6979 | (define_insn "*ashr<mode>3_cconly_and" |
417cba42 | 6980 | [(set (reg CC_REGNUM) |
38d26fa6 | 6981 | (compare (ashiftrt:GPR (match_operand:GPR 1 "register_operand" "<d0>") |
6982 | (and:SI (match_operand:SI 2 "shift_count_or_setmem_operand" "Y") | |
6983 | (match_operand:SI 3 "const_int_operand" "n"))) | |
417cba42 | 6984 | (const_int 0))) |
38d26fa6 | 6985 | (clobber (match_scratch:GPR 0 "=d"))] |
417cba42 | 6986 | "s390_match_ccmode(insn, CCSmode) && (INTVAL (operands[3]) & 63) == 63" |
38d26fa6 | 6987 | "sra<g>\t%0,<1>%Y2" |
6988 | [(set_attr "op_type" "RS<E>") | |
417cba42 | 6989 | (set_attr "atype" "reg")]) |
6990 | ||
87bc9927 | 6991 | ; sra, srag |
38d26fa6 | 6992 | (define_insn "*ashr<mode>3_and" |
6993 | [(set (match_operand:GPR 0 "register_operand" "=d") | |
6994 | (ashiftrt:GPR (match_operand:GPR 1 "register_operand" "<d0>") | |
6995 | (and:SI (match_operand:SI 2 "shift_count_or_setmem_operand" "Y") | |
6996 | (match_operand:SI 3 "const_int_operand" "n")))) | |
417cba42 | 6997 | (clobber (reg:CC CC_REGNUM))] |
6998 | "(INTVAL (operands[3]) & 63) == 63" | |
38d26fa6 | 6999 | "sra<g>\t%0,<1>%Y2" |
7000 | [(set_attr "op_type" "RS<E>") | |
417cba42 | 7001 | (set_attr "atype" "reg")]) |
7002 | ||
4673c1a0 | 7003 | |
4673c1a0 | 7004 | ;; |
7005 | ;; Branch instruction patterns. | |
7006 | ;; | |
7007 | ||
a2cef37b | 7008 | (define_expand "b<code>" |
7009 | [(set (pc) | |
7010 | (if_then_else (COMPARE (match_operand 0 "" "") | |
7011 | (const_int 0)) | |
7012 | (match_dup 0) | |
7013 | (pc)))] | |
2eb8fe23 | 7014 | "" |
0d656e8b | 7015 | "s390_emit_jump (operands[0], |
a2cef37b | 7016 | s390_emit_compare (<CODE>, s390_compare_op0, s390_compare_op1)); DONE;") |
2eb8fe23 | 7017 | |
4673c1a0 | 7018 | |
7019 | ;; | |
7020 | ;;- Conditional jump instructions. | |
7021 | ;; | |
7022 | ||
0d656e8b | 7023 | (define_insn "*cjump_64" |
7024 | [(set (pc) | |
7025 | (if_then_else | |
1ca361fd | 7026 | (match_operator 1 "s390_comparison" [(reg CC_REGNUM) (const_int 0)]) |
0d656e8b | 7027 | (label_ref (match_operand 0 "" "")) |
7028 | (pc)))] | |
7029 | "TARGET_CPU_ZARCH" | |
4673c1a0 | 7030 | { |
479ca6e8 | 7031 | if (get_attr_length (insn) == 4) |
f24d7ff3 | 7032 | return "j%C1\t%l0"; |
0d656e8b | 7033 | else |
f24d7ff3 | 7034 | return "jg%C1\t%l0"; |
0d656e8b | 7035 | } |
7036 | [(set_attr "op_type" "RI") | |
7037 | (set_attr "type" "branch") | |
7038 | (set (attr "length") | |
7039 | (if_then_else (lt (abs (minus (pc) (match_dup 0))) (const_int 60000)) | |
7040 | (const_int 4) (const_int 6)))]) | |
7041 | ||
7042 | (define_insn "*cjump_31" | |
7043 | [(set (pc) | |
7044 | (if_then_else | |
1ca361fd | 7045 | (match_operator 1 "s390_comparison" [(reg CC_REGNUM) (const_int 0)]) |
0d656e8b | 7046 | (label_ref (match_operand 0 "" "")) |
7047 | (pc)))] | |
7048 | "!TARGET_CPU_ZARCH" | |
7049 | { | |
32eda510 | 7050 | gcc_assert (get_attr_length (insn) == 4); |
7051 | return "j%C1\t%l0"; | |
83e641bd | 7052 | } |
4673c1a0 | 7053 | [(set_attr "op_type" "RI") |
71343e6b | 7054 | (set_attr "type" "branch") |
479ca6e8 | 7055 | (set (attr "length") |
0d656e8b | 7056 | (if_then_else (eq (symbol_ref "flag_pic") (const_int 0)) |
7057 | (if_then_else (lt (abs (minus (pc) (match_dup 0))) (const_int 60000)) | |
7058 | (const_int 4) (const_int 6)) | |
7059 | (if_then_else (lt (abs (minus (pc) (match_dup 0))) (const_int 60000)) | |
7060 | (const_int 4) (const_int 8))))]) | |
4673c1a0 | 7061 | |
0c0a8ea5 | 7062 | (define_insn "*cjump_long" |
0d656e8b | 7063 | [(set (pc) |
7064 | (if_then_else | |
1ca361fd | 7065 | (match_operator 1 "s390_comparison" [(reg CC_REGNUM) (const_int 0)]) |
0d656e8b | 7066 | (match_operand 0 "address_operand" "U") |
7067 | (pc)))] | |
4673c1a0 | 7068 | "" |
0c0a8ea5 | 7069 | { |
7070 | if (get_attr_op_type (insn) == OP_TYPE_RR) | |
f24d7ff3 | 7071 | return "b%C1r\t%0"; |
0c0a8ea5 | 7072 | else |
f24d7ff3 | 7073 | return "b%C1\t%a0"; |
83e641bd | 7074 | } |
f81e845f | 7075 | [(set (attr "op_type") |
0c0a8ea5 | 7076 | (if_then_else (match_operand 0 "register_operand" "") |
7077 | (const_string "RR") (const_string "RX"))) | |
0d656e8b | 7078 | (set_attr "type" "branch") |
71343e6b | 7079 | (set_attr "atype" "agen")]) |
4673c1a0 | 7080 | |
7081 | ||
7082 | ;; | |
7083 | ;;- Negated conditional jump instructions. | |
7084 | ;; | |
7085 | ||
0d656e8b | 7086 | (define_insn "*icjump_64" |
7087 | [(set (pc) | |
7088 | (if_then_else | |
1ca361fd | 7089 | (match_operator 1 "s390_comparison" [(reg CC_REGNUM) (const_int 0)]) |
0d656e8b | 7090 | (pc) |
7091 | (label_ref (match_operand 0 "" ""))))] | |
7092 | "TARGET_CPU_ZARCH" | |
f81e845f | 7093 | { |
479ca6e8 | 7094 | if (get_attr_length (insn) == 4) |
f24d7ff3 | 7095 | return "j%D1\t%l0"; |
0d656e8b | 7096 | else |
f24d7ff3 | 7097 | return "jg%D1\t%l0"; |
0d656e8b | 7098 | } |
7099 | [(set_attr "op_type" "RI") | |
7100 | (set_attr "type" "branch") | |
7101 | (set (attr "length") | |
7102 | (if_then_else (lt (abs (minus (pc) (match_dup 0))) (const_int 60000)) | |
7103 | (const_int 4) (const_int 6)))]) | |
7104 | ||
7105 | (define_insn "*icjump_31" | |
7106 | [(set (pc) | |
7107 | (if_then_else | |
1ca361fd | 7108 | (match_operator 1 "s390_comparison" [(reg CC_REGNUM) (const_int 0)]) |
0d656e8b | 7109 | (pc) |
7110 | (label_ref (match_operand 0 "" ""))))] | |
7111 | "!TARGET_CPU_ZARCH" | |
7112 | { | |
32eda510 | 7113 | gcc_assert (get_attr_length (insn) == 4); |
7114 | return "j%D1\t%l0"; | |
83e641bd | 7115 | } |
4673c1a0 | 7116 | [(set_attr "op_type" "RI") |
71343e6b | 7117 | (set_attr "type" "branch") |
479ca6e8 | 7118 | (set (attr "length") |
0d656e8b | 7119 | (if_then_else (eq (symbol_ref "flag_pic") (const_int 0)) |
7120 | (if_then_else (lt (abs (minus (pc) (match_dup 0))) (const_int 60000)) | |
7121 | (const_int 4) (const_int 6)) | |
7122 | (if_then_else (lt (abs (minus (pc) (match_dup 0))) (const_int 60000)) | |
7123 | (const_int 4) (const_int 8))))]) | |
4673c1a0 | 7124 | |
0c0a8ea5 | 7125 | (define_insn "*icjump_long" |
0d656e8b | 7126 | [(set (pc) |
7127 | (if_then_else | |
1ca361fd | 7128 | (match_operator 1 "s390_comparison" [(reg CC_REGNUM) (const_int 0)]) |
0d656e8b | 7129 | (pc) |
7130 | (match_operand 0 "address_operand" "U")))] | |
4673c1a0 | 7131 | "" |
0c0a8ea5 | 7132 | { |
7133 | if (get_attr_op_type (insn) == OP_TYPE_RR) | |
f24d7ff3 | 7134 | return "b%D1r\t%0"; |
0c0a8ea5 | 7135 | else |
f24d7ff3 | 7136 | return "b%D1\t%a0"; |
83e641bd | 7137 | } |
f81e845f | 7138 | [(set (attr "op_type") |
0c0a8ea5 | 7139 | (if_then_else (match_operand 0 "register_operand" "") |
7140 | (const_string "RR") (const_string "RX"))) | |
71343e6b | 7141 | (set_attr "type" "branch") |
7142 | (set_attr "atype" "agen")]) | |
4673c1a0 | 7143 | |
49df79a5 | 7144 | ;; |
7145 | ;;- Trap instructions. | |
7146 | ;; | |
7147 | ||
7148 | (define_insn "trap" | |
7149 | [(trap_if (const_int 1) (const_int 0))] | |
7150 | "" | |
f24d7ff3 | 7151 | "j\t.+2" |
0d656e8b | 7152 | [(set_attr "op_type" "RI") |
71343e6b | 7153 | (set_attr "type" "branch")]) |
49df79a5 | 7154 | |
7155 | (define_expand "conditional_trap" | |
0d656e8b | 7156 | [(trap_if (match_operand 0 "comparison_operator" "") |
7157 | (match_operand 1 "general_operand" ""))] | |
49df79a5 | 7158 | "" |
49df79a5 | 7159 | { |
0d656e8b | 7160 | if (operands[1] != const0_rtx) FAIL; |
7161 | operands[0] = s390_emit_compare (GET_CODE (operands[0]), | |
7162 | s390_compare_op0, s390_compare_op1); | |
83e641bd | 7163 | }) |
49df79a5 | 7164 | |
7165 | (define_insn "*trap" | |
1ca361fd | 7166 | [(trap_if (match_operator 0 "s390_comparison" [(reg CC_REGNUM) (const_int 0)]) |
49df79a5 | 7167 | (const_int 0))] |
7168 | "" | |
f24d7ff3 | 7169 | "j%C0\t.+2"; |
71343e6b | 7170 | [(set_attr "op_type" "RI") |
7171 | (set_attr "type" "branch")]) | |
4673c1a0 | 7172 | |
e68d6a13 | 7173 | ; crt, cgrt, cit, cgit |
7174 | (define_insn "*cmp_and_trap_signed_int<mode>" | |
7175 | [(trap_if (match_operator 0 "s390_signed_integer_comparison" | |
7176 | [(match_operand:GPR 1 "register_operand" "d,d") | |
7177 | (match_operand:GPR 2 "nonmemory_operand" "d,K")]) | |
7178 | (const_int 0))] | |
7179 | "TARGET_Z10" | |
7180 | "@ | |
7181 | c<g>rt%C0\t%1,%2 | |
7182 | c<g>it%C0\t%1,%h2" | |
7183 | [(set_attr "op_type" "RRF,RIE") | |
7184 | (set_attr "type" "branch")]) | |
7185 | ||
7186 | ; clrt, clgrt, clfit, clgit | |
7187 | (define_insn "*cmp_and_trap_unsigned_int<mode>" | |
7188 | [(trap_if (match_operator 0 "s390_unsigned_integer_comparison" | |
7189 | [(match_operand:GPR 1 "register_operand" "d,d") | |
7190 | (match_operand:GPR 2 "nonmemory_operand" "d,D")]) | |
7191 | (const_int 0))] | |
7192 | "TARGET_Z10" | |
7193 | "@ | |
7194 | cl<g>rt%C0\t%1,%2 | |
7195 | cl<gf>it%C0\t%1,%x2" | |
7196 | [(set_attr "op_type" "RRF,RIE") | |
7197 | (set_attr "type" "branch")]) | |
7198 | ||
4673c1a0 | 7199 | ;; |
3c482144 | 7200 | ;;- Loop instructions. |
4673c1a0 | 7201 | ;; |
3c482144 | 7202 | ;; This is all complicated by the fact that since this is a jump insn |
7203 | ;; we must handle our own output reloads. | |
f81e845f | 7204 | |
3c482144 | 7205 | (define_expand "doloop_end" |
7206 | [(use (match_operand 0 "" "")) ; loop pseudo | |
7207 | (use (match_operand 1 "" "")) ; iterations; zero if unknown | |
7208 | (use (match_operand 2 "" "")) ; max iterations | |
7209 | (use (match_operand 3 "" "")) ; loop level | |
7210 | (use (match_operand 4 "" ""))] ; label | |
7211 | "" | |
3c482144 | 7212 | { |
0d656e8b | 7213 | if (GET_MODE (operands[0]) == SImode && !TARGET_CPU_ZARCH) |
7214 | emit_jump_insn (gen_doloop_si31 (operands[4], operands[0], operands[0])); | |
7215 | else if (GET_MODE (operands[0]) == SImode && TARGET_CPU_ZARCH) | |
7216 | emit_jump_insn (gen_doloop_si64 (operands[4], operands[0], operands[0])); | |
3c482144 | 7217 | else if (GET_MODE (operands[0]) == DImode && TARGET_64BIT) |
7218 | emit_jump_insn (gen_doloop_di (operands[4], operands[0], operands[0])); | |
7219 | else | |
7220 | FAIL; | |
7221 | ||
7222 | DONE; | |
83e641bd | 7223 | }) |
3c482144 | 7224 | |
0d656e8b | 7225 | (define_insn_and_split "doloop_si64" |
3c482144 | 7226 | [(set (pc) |
7227 | (if_then_else | |
65092884 | 7228 | (ne (match_operand:SI 1 "register_operand" "d,d,d") |
3c482144 | 7229 | (const_int 1)) |
7230 | (label_ref (match_operand 0 "" "")) | |
7231 | (pc))) | |
65092884 | 7232 | (set (match_operand:SI 2 "nonimmediate_operand" "=1,?X,?X") |
3c482144 | 7233 | (plus:SI (match_dup 1) (const_int -1))) |
65092884 | 7234 | (clobber (match_scratch:SI 3 "=X,&1,&?d")) |
1ca361fd | 7235 | (clobber (reg:CC CC_REGNUM))] |
0d656e8b | 7236 | "TARGET_CPU_ZARCH" |
3c482144 | 7237 | { |
7238 | if (which_alternative != 0) | |
83e641bd | 7239 | return "#"; |
3c482144 | 7240 | else if (get_attr_length (insn) == 4) |
f24d7ff3 | 7241 | return "brct\t%1,%l0"; |
0d656e8b | 7242 | else |
5fe74ca1 | 7243 | return "ahi\t%1,-1\;jgne\t%l0"; |
0d656e8b | 7244 | } |
7245 | "&& reload_completed | |
7246 | && (! REG_P (operands[2]) | |
7247 | || ! rtx_equal_p (operands[1], operands[2]))" | |
65092884 | 7248 | [(set (match_dup 3) (match_dup 1)) |
7249 | (parallel [(set (reg:CCAN CC_REGNUM) | |
0d656e8b | 7250 | (compare:CCAN (plus:SI (match_dup 3) (const_int -1)) |
7251 | (const_int 0))) | |
7252 | (set (match_dup 3) (plus:SI (match_dup 3) (const_int -1)))]) | |
7253 | (set (match_dup 2) (match_dup 3)) | |
1ca361fd | 7254 | (set (pc) (if_then_else (ne (reg:CCAN CC_REGNUM) (const_int 0)) |
0d656e8b | 7255 | (label_ref (match_dup 0)) |
7256 | (pc)))] | |
7257 | "" | |
7258 | [(set_attr "op_type" "RI") | |
7259 | (set_attr "type" "branch") | |
7260 | (set (attr "length") | |
7261 | (if_then_else (lt (abs (minus (pc) (match_dup 0))) (const_int 60000)) | |
7262 | (const_int 4) (const_int 10)))]) | |
7263 | ||
7264 | (define_insn_and_split "doloop_si31" | |
7265 | [(set (pc) | |
7266 | (if_then_else | |
65092884 | 7267 | (ne (match_operand:SI 1 "register_operand" "d,d,d") |
0d656e8b | 7268 | (const_int 1)) |
7269 | (label_ref (match_operand 0 "" "")) | |
7270 | (pc))) | |
65092884 | 7271 | (set (match_operand:SI 2 "nonimmediate_operand" "=1,?X,?X") |
0d656e8b | 7272 | (plus:SI (match_dup 1) (const_int -1))) |
65092884 | 7273 | (clobber (match_scratch:SI 3 "=X,&1,&?d")) |
1ca361fd | 7274 | (clobber (reg:CC CC_REGNUM))] |
0d656e8b | 7275 | "!TARGET_CPU_ZARCH" |
7276 | { | |
7277 | if (which_alternative != 0) | |
7278 | return "#"; | |
7279 | else if (get_attr_length (insn) == 4) | |
7280 | return "brct\t%1,%l0"; | |
3c482144 | 7281 | else |
32eda510 | 7282 | gcc_unreachable (); |
83e641bd | 7283 | } |
0d656e8b | 7284 | "&& reload_completed |
7285 | && (! REG_P (operands[2]) | |
7286 | || ! rtx_equal_p (operands[1], operands[2]))" | |
65092884 | 7287 | [(set (match_dup 3) (match_dup 1)) |
7288 | (parallel [(set (reg:CCAN CC_REGNUM) | |
0d656e8b | 7289 | (compare:CCAN (plus:SI (match_dup 3) (const_int -1)) |
7290 | (const_int 0))) | |
7291 | (set (match_dup 3) (plus:SI (match_dup 3) (const_int -1)))]) | |
7292 | (set (match_dup 2) (match_dup 3)) | |
1ca361fd | 7293 | (set (pc) (if_then_else (ne (reg:CCAN CC_REGNUM) (const_int 0)) |
0d656e8b | 7294 | (label_ref (match_dup 0)) |
7295 | (pc)))] | |
7296 | "" | |
3c482144 | 7297 | [(set_attr "op_type" "RI") |
71343e6b | 7298 | (set_attr "type" "branch") |
3c482144 | 7299 | (set (attr "length") |
0d656e8b | 7300 | (if_then_else (eq (symbol_ref "flag_pic") (const_int 0)) |
7301 | (if_then_else (lt (abs (minus (pc) (match_dup 0))) (const_int 60000)) | |
7302 | (const_int 4) (const_int 6)) | |
7303 | (if_then_else (lt (abs (minus (pc) (match_dup 0))) (const_int 60000)) | |
7304 | (const_int 4) (const_int 8))))]) | |
4673c1a0 | 7305 | |
3c482144 | 7306 | (define_insn "*doloop_si_long" |
7307 | [(set (pc) | |
7308 | (if_then_else | |
65092884 | 7309 | (ne (match_operand:SI 1 "register_operand" "d") |
3c482144 | 7310 | (const_int 1)) |
65092884 | 7311 | (match_operand 0 "address_operand" "U") |
3c482144 | 7312 | (pc))) |
65092884 | 7313 | (set (match_operand:SI 2 "register_operand" "=1") |
3c482144 | 7314 | (plus:SI (match_dup 1) (const_int -1))) |
65092884 | 7315 | (clobber (match_scratch:SI 3 "=X")) |
1ca361fd | 7316 | (clobber (reg:CC CC_REGNUM))] |
0d656e8b | 7317 | "!TARGET_CPU_ZARCH" |
3c482144 | 7318 | { |
7319 | if (get_attr_op_type (insn) == OP_TYPE_RR) | |
f24d7ff3 | 7320 | return "bctr\t%1,%0"; |
3c482144 | 7321 | else |
f24d7ff3 | 7322 | return "bct\t%1,%a0"; |
83e641bd | 7323 | } |
f81e845f | 7324 | [(set (attr "op_type") |
3c482144 | 7325 | (if_then_else (match_operand 0 "register_operand" "") |
7326 | (const_string "RR") (const_string "RX"))) | |
71343e6b | 7327 | (set_attr "type" "branch") |
7328 | (set_attr "atype" "agen")]) | |
3c482144 | 7329 | |
0d656e8b | 7330 | (define_insn_and_split "doloop_di" |
3c482144 | 7331 | [(set (pc) |
7332 | (if_then_else | |
65092884 | 7333 | (ne (match_operand:DI 1 "register_operand" "d,d,d") |
3c482144 | 7334 | (const_int 1)) |
7335 | (label_ref (match_operand 0 "" "")) | |
7336 | (pc))) | |
65092884 | 7337 | (set (match_operand:DI 2 "nonimmediate_operand" "=1,?X,?X") |
3c482144 | 7338 | (plus:DI (match_dup 1) (const_int -1))) |
65092884 | 7339 | (clobber (match_scratch:DI 3 "=X,&1,&?d")) |
1ca361fd | 7340 | (clobber (reg:CC CC_REGNUM))] |
3c482144 | 7341 | "TARGET_64BIT" |
3c482144 | 7342 | { |
7343 | if (which_alternative != 0) | |
83e641bd | 7344 | return "#"; |
3c482144 | 7345 | else if (get_attr_length (insn) == 4) |
f24d7ff3 | 7346 | return "brctg\t%1,%l0"; |
3c482144 | 7347 | else |
5fe74ca1 | 7348 | return "aghi\t%1,-1\;jgne\t%l0"; |
83e641bd | 7349 | } |
0d656e8b | 7350 | "&& reload_completed |
3c482144 | 7351 | && (! REG_P (operands[2]) |
7352 | || ! rtx_equal_p (operands[1], operands[2]))" | |
65092884 | 7353 | [(set (match_dup 3) (match_dup 1)) |
7354 | (parallel [(set (reg:CCAN CC_REGNUM) | |
3c482144 | 7355 | (compare:CCAN (plus:DI (match_dup 3) (const_int -1)) |
7356 | (const_int 0))) | |
7357 | (set (match_dup 3) (plus:DI (match_dup 3) (const_int -1)))]) | |
7358 | (set (match_dup 2) (match_dup 3)) | |
1ca361fd | 7359 | (set (pc) (if_then_else (ne (reg:CCAN CC_REGNUM) (const_int 0)) |
0d656e8b | 7360 | (label_ref (match_dup 0)) |
3c482144 | 7361 | (pc)))] |
0d656e8b | 7362 | "" |
7363 | [(set_attr "op_type" "RI") | |
7364 | (set_attr "type" "branch") | |
7365 | (set (attr "length") | |
7366 | (if_then_else (lt (abs (minus (pc) (match_dup 0))) (const_int 60000)) | |
7367 | (const_int 4) (const_int 10)))]) | |
4673c1a0 | 7368 | |
7369 | ;; | |
7370 | ;;- Unconditional jump instructions. | |
7371 | ;; | |
7372 | ||
7373 | ; | |
7374 | ; jump instruction pattern(s). | |
7375 | ; | |
7376 | ||
0d656e8b | 7377 | (define_expand "jump" |
7378 | [(match_operand 0 "" "")] | |
4673c1a0 | 7379 | "" |
0d656e8b | 7380 | "s390_emit_jump (operands[0], NULL_RTX); DONE;") |
7381 | ||
7382 | (define_insn "*jump64" | |
7383 | [(set (pc) (label_ref (match_operand 0 "" "")))] | |
7384 | "TARGET_CPU_ZARCH" | |
4673c1a0 | 7385 | { |
479ca6e8 | 7386 | if (get_attr_length (insn) == 4) |
f24d7ff3 | 7387 | return "j\t%l0"; |
0d656e8b | 7388 | else |
f24d7ff3 | 7389 | return "jg\t%l0"; |
0d656e8b | 7390 | } |
7391 | [(set_attr "op_type" "RI") | |
7392 | (set_attr "type" "branch") | |
7393 | (set (attr "length") | |
7394 | (if_then_else (lt (abs (minus (pc) (match_dup 0))) (const_int 60000)) | |
7395 | (const_int 4) (const_int 6)))]) | |
7396 | ||
7397 | (define_insn "*jump31" | |
7398 | [(set (pc) (label_ref (match_operand 0 "" "")))] | |
7399 | "!TARGET_CPU_ZARCH" | |
7400 | { | |
32eda510 | 7401 | gcc_assert (get_attr_length (insn) == 4); |
7402 | return "j\t%l0"; | |
83e641bd | 7403 | } |
4673c1a0 | 7404 | [(set_attr "op_type" "RI") |
71343e6b | 7405 | (set_attr "type" "branch") |
479ca6e8 | 7406 | (set (attr "length") |
0d656e8b | 7407 | (if_then_else (eq (symbol_ref "flag_pic") (const_int 0)) |
7408 | (if_then_else (lt (abs (minus (pc) (match_dup 0))) (const_int 60000)) | |
7409 | (const_int 4) (const_int 6)) | |
7410 | (if_then_else (lt (abs (minus (pc) (match_dup 0))) (const_int 60000)) | |
7411 | (const_int 4) (const_int 8))))]) | |
4673c1a0 | 7412 | |
7413 | ; | |
7414 | ; indirect-jump instruction pattern(s). | |
7415 | ; | |
7416 | ||
7417 | (define_insn "indirect_jump" | |
51aa1e9c | 7418 | [(set (pc) (match_operand 0 "address_operand" "U"))] |
4673c1a0 | 7419 | "" |
0c0a8ea5 | 7420 | { |
7421 | if (get_attr_op_type (insn) == OP_TYPE_RR) | |
f24d7ff3 | 7422 | return "br\t%0"; |
0c0a8ea5 | 7423 | else |
f24d7ff3 | 7424 | return "b\t%a0"; |
83e641bd | 7425 | } |
f81e845f | 7426 | [(set (attr "op_type") |
0c0a8ea5 | 7427 | (if_then_else (match_operand 0 "register_operand" "") |
7428 | (const_string "RR") (const_string "RX"))) | |
71343e6b | 7429 | (set_attr "type" "branch") |
7430 | (set_attr "atype" "agen")]) | |
4673c1a0 | 7431 | |
7432 | ; | |
0c0a8ea5 | 7433 | ; casesi instruction pattern(s). |
4673c1a0 | 7434 | ; |
7435 | ||
0c0a8ea5 | 7436 | (define_insn "casesi_jump" |
51aa1e9c | 7437 | [(set (pc) (match_operand 0 "address_operand" "U")) |
0c0a8ea5 | 7438 | (use (label_ref (match_operand 1 "" "")))] |
4673c1a0 | 7439 | "" |
4673c1a0 | 7440 | { |
0c0a8ea5 | 7441 | if (get_attr_op_type (insn) == OP_TYPE_RR) |
f24d7ff3 | 7442 | return "br\t%0"; |
0c0a8ea5 | 7443 | else |
f24d7ff3 | 7444 | return "b\t%a0"; |
83e641bd | 7445 | } |
f81e845f | 7446 | [(set (attr "op_type") |
0c0a8ea5 | 7447 | (if_then_else (match_operand 0 "register_operand" "") |
7448 | (const_string "RR") (const_string "RX"))) | |
71343e6b | 7449 | (set_attr "type" "branch") |
7450 | (set_attr "atype" "agen")]) | |
4673c1a0 | 7451 | |
0c0a8ea5 | 7452 | (define_expand "casesi" |
7453 | [(match_operand:SI 0 "general_operand" "") | |
7454 | (match_operand:SI 1 "general_operand" "") | |
7455 | (match_operand:SI 2 "general_operand" "") | |
7456 | (label_ref (match_operand 3 "" "")) | |
7457 | (label_ref (match_operand 4 "" ""))] | |
4673c1a0 | 7458 | "" |
0c0a8ea5 | 7459 | { |
7460 | rtx index = gen_reg_rtx (SImode); | |
7461 | rtx base = gen_reg_rtx (Pmode); | |
7462 | rtx target = gen_reg_rtx (Pmode); | |
7463 | ||
7464 | emit_move_insn (index, operands[0]); | |
7465 | emit_insn (gen_subsi3 (index, index, operands[1])); | |
7466 | emit_cmp_and_jump_insns (index, operands[2], GTU, NULL_RTX, SImode, 1, | |
3d182d84 | 7467 | operands[4]); |
0c0a8ea5 | 7468 | |
7469 | if (Pmode != SImode) | |
7470 | index = convert_to_mode (Pmode, index, 1); | |
7471 | if (GET_CODE (index) != REG) | |
7472 | index = copy_to_mode_reg (Pmode, index); | |
7473 | ||
7474 | if (TARGET_64BIT) | |
7475 | emit_insn (gen_ashldi3 (index, index, GEN_INT (3))); | |
7476 | else | |
bcd9bd66 | 7477 | emit_insn (gen_ashlsi3 (index, index, const2_rtx)); |
4673c1a0 | 7478 | |
0c0a8ea5 | 7479 | emit_move_insn (base, gen_rtx_LABEL_REF (Pmode, operands[3])); |
7480 | ||
e265a6da | 7481 | index = gen_const_mem (Pmode, gen_rtx_PLUS (Pmode, base, index)); |
0c0a8ea5 | 7482 | emit_move_insn (target, index); |
7483 | ||
7484 | if (flag_pic) | |
7485 | target = gen_rtx_PLUS (Pmode, base, target); | |
7486 | emit_jump_insn (gen_casesi_jump (target, operands[3])); | |
7487 | ||
7488 | DONE; | |
83e641bd | 7489 | }) |
4673c1a0 | 7490 | |
7491 | ||
7492 | ;; | |
7493 | ;;- Jump to subroutine. | |
7494 | ;; | |
7495 | ;; | |
7496 | ||
7497 | ; | |
7498 | ; untyped call instruction pattern(s). | |
7499 | ; | |
7500 | ||
7501 | ;; Call subroutine returning any type. | |
7502 | (define_expand "untyped_call" | |
7503 | [(parallel [(call (match_operand 0 "" "") | |
7504 | (const_int 0)) | |
7505 | (match_operand 1 "" "") | |
7506 | (match_operand 2 "" "")])] | |
7507 | "" | |
4673c1a0 | 7508 | { |
7509 | int i; | |
7510 | ||
7511 | emit_call_insn (gen_call (operands[0], const0_rtx, const0_rtx)); | |
7512 | ||
7513 | for (i = 0; i < XVECLEN (operands[2], 0); i++) | |
7514 | { | |
7515 | rtx set = XVECEXP (operands[2], 0, i); | |
7516 | emit_move_insn (SET_DEST (set), SET_SRC (set)); | |
7517 | } | |
7518 | ||
7519 | /* The optimizer does not know that the call sets the function value | |
7520 | registers we stored in the result block. We avoid problems by | |
7521 | claiming that all hard registers are used and clobbered at this | |
7522 | point. */ | |
7523 | emit_insn (gen_blockage ()); | |
7524 | ||
7525 | DONE; | |
83e641bd | 7526 | }) |
4673c1a0 | 7527 | |
7528 | ;; UNSPEC_VOLATILE is considered to use and clobber all hard registers and | |
7529 | ;; all of memory. This blocks insns from being moved across this point. | |
7530 | ||
7531 | (define_insn "blockage" | |
83e641bd | 7532 | [(unspec_volatile [(const_int 0)] UNSPECV_BLOCKAGE)] |
4673c1a0 | 7533 | "" |
8b4a4127 | 7534 | "" |
c36e6d0b | 7535 | [(set_attr "type" "none") |
7536 | (set_attr "length" "0")]) | |
8b4a4127 | 7537 | |
4673c1a0 | 7538 | ; |
7346ca58 | 7539 | ; sibcall patterns |
4673c1a0 | 7540 | ; |
7541 | ||
7346ca58 | 7542 | (define_expand "sibcall" |
c89f9ed7 | 7543 | [(call (match_operand 0 "" "") |
7346ca58 | 7544 | (match_operand 1 "" ""))] |
4673c1a0 | 7545 | "" |
4673c1a0 | 7546 | { |
7346ca58 | 7547 | s390_emit_call (XEXP (operands[0], 0), NULL_RTX, NULL_RTX, NULL_RTX); |
7548 | DONE; | |
7549 | }) | |
4673c1a0 | 7550 | |
7346ca58 | 7551 | (define_insn "*sibcall_br" |
1ca361fd | 7552 | [(call (mem:QI (reg SIBCALL_REGNUM)) |
7346ca58 | 7553 | (match_operand 0 "const_int_operand" "n"))] |
346fecd5 | 7554 | "SIBLING_CALL_P (insn) |
7346ca58 | 7555 | && GET_MODE (XEXP (XEXP (PATTERN (insn), 0), 0)) == Pmode" |
7556 | "br\t%%r1" | |
7557 | [(set_attr "op_type" "RR") | |
7558 | (set_attr "type" "branch") | |
7559 | (set_attr "atype" "agen")]) | |
4673c1a0 | 7560 | |
7346ca58 | 7561 | (define_insn "*sibcall_brc" |
7562 | [(call (mem:QI (match_operand 0 "bras_sym_operand" "X")) | |
7563 | (match_operand 1 "const_int_operand" "n"))] | |
7564 | "SIBLING_CALL_P (insn) && TARGET_SMALL_EXEC" | |
7565 | "j\t%0" | |
7566 | [(set_attr "op_type" "RI") | |
7567 | (set_attr "type" "branch")]) | |
4673c1a0 | 7568 | |
7346ca58 | 7569 | (define_insn "*sibcall_brcl" |
7570 | [(call (mem:QI (match_operand 0 "bras_sym_operand" "X")) | |
7571 | (match_operand 1 "const_int_operand" "n"))] | |
7572 | "SIBLING_CALL_P (insn) && TARGET_CPU_ZARCH" | |
7573 | "jg\t%0" | |
7574 | [(set_attr "op_type" "RIL") | |
7575 | (set_attr "type" "branch")]) | |
c89f9ed7 | 7576 | |
7346ca58 | 7577 | ; |
7578 | ; sibcall_value patterns | |
7579 | ; | |
dafc8d45 | 7580 | |
7346ca58 | 7581 | (define_expand "sibcall_value" |
7582 | [(set (match_operand 0 "" "") | |
7583 | (call (match_operand 1 "" "") | |
7584 | (match_operand 2 "" "")))] | |
7585 | "" | |
7586 | { | |
7587 | s390_emit_call (XEXP (operands[1], 0), NULL_RTX, operands[0], NULL_RTX); | |
c89f9ed7 | 7588 | DONE; |
83e641bd | 7589 | }) |
4673c1a0 | 7590 | |
7346ca58 | 7591 | (define_insn "*sibcall_value_br" |
7592 | [(set (match_operand 0 "" "") | |
1ca361fd | 7593 | (call (mem:QI (reg SIBCALL_REGNUM)) |
7346ca58 | 7594 | (match_operand 1 "const_int_operand" "n")))] |
346fecd5 | 7595 | "SIBLING_CALL_P (insn) |
7346ca58 | 7596 | && GET_MODE (XEXP (XEXP (XEXP (PATTERN (insn), 1), 0), 0)) == Pmode" |
7597 | "br\t%%r1" | |
7598 | [(set_attr "op_type" "RR") | |
7599 | (set_attr "type" "branch") | |
7600 | (set_attr "atype" "agen")]) | |
7601 | ||
7602 | (define_insn "*sibcall_value_brc" | |
7603 | [(set (match_operand 0 "" "") | |
7604 | (call (mem:QI (match_operand 1 "bras_sym_operand" "X")) | |
7605 | (match_operand 2 "const_int_operand" "n")))] | |
7606 | "SIBLING_CALL_P (insn) && TARGET_SMALL_EXEC" | |
7607 | "j\t%1" | |
7608 | [(set_attr "op_type" "RI") | |
7609 | (set_attr "type" "branch")]) | |
7610 | ||
7611 | (define_insn "*sibcall_value_brcl" | |
7612 | [(set (match_operand 0 "" "") | |
7613 | (call (mem:QI (match_operand 1 "bras_sym_operand" "X")) | |
7614 | (match_operand 2 "const_int_operand" "n")))] | |
7615 | "SIBLING_CALL_P (insn) && TARGET_CPU_ZARCH" | |
7616 | "jg\t%1" | |
7617 | [(set_attr "op_type" "RIL") | |
7618 | (set_attr "type" "branch")]) | |
7619 | ||
7620 | ||
7621 | ; | |
7622 | ; call instruction pattern(s). | |
7623 | ; | |
7624 | ||
7625 | (define_expand "call" | |
7626 | [(call (match_operand 0 "" "") | |
7627 | (match_operand 1 "" "")) | |
7628 | (use (match_operand 2 "" ""))] | |
c89f9ed7 | 7629 | "" |
7346ca58 | 7630 | { |
346fecd5 | 7631 | s390_emit_call (XEXP (operands[0], 0), NULL_RTX, NULL_RTX, |
7346ca58 | 7632 | gen_rtx_REG (Pmode, RETURN_REGNUM)); |
7633 | DONE; | |
7634 | }) | |
c89f9ed7 | 7635 | |
dafc8d45 | 7636 | (define_insn "*bras" |
7637 | [(call (mem:QI (match_operand 0 "bras_sym_operand" "X")) | |
7638 | (match_operand 1 "const_int_operand" "n")) | |
7639 | (clobber (match_operand 2 "register_operand" "=r"))] | |
346fecd5 | 7640 | "!SIBLING_CALL_P (insn) |
7641 | && TARGET_SMALL_EXEC | |
7346ca58 | 7642 | && GET_MODE (operands[2]) == Pmode" |
f24d7ff3 | 7643 | "bras\t%2,%0" |
4673c1a0 | 7644 | [(set_attr "op_type" "RI") |
8b4a4127 | 7645 | (set_attr "type" "jsr")]) |
4673c1a0 | 7646 | |
dafc8d45 | 7647 | (define_insn "*brasl" |
7648 | [(call (mem:QI (match_operand 0 "bras_sym_operand" "X")) | |
7649 | (match_operand 1 "const_int_operand" "n")) | |
7650 | (clobber (match_operand 2 "register_operand" "=r"))] | |
346fecd5 | 7651 | "!SIBLING_CALL_P (insn) |
7652 | && TARGET_CPU_ZARCH | |
7346ca58 | 7653 | && GET_MODE (operands[2]) == Pmode" |
dafc8d45 | 7654 | "brasl\t%2,%0" |
7655 | [(set_attr "op_type" "RIL") | |
71343e6b | 7656 | (set_attr "type" "jsr")]) |
4673c1a0 | 7657 | |
dafc8d45 | 7658 | (define_insn "*basr" |
7659 | [(call (mem:QI (match_operand 0 "address_operand" "U")) | |
7660 | (match_operand 1 "const_int_operand" "n")) | |
7661 | (clobber (match_operand 2 "register_operand" "=r"))] | |
7346ca58 | 7662 | "!SIBLING_CALL_P (insn) && GET_MODE (operands[2]) == Pmode" |
dafc8d45 | 7663 | { |
7664 | if (get_attr_op_type (insn) == OP_TYPE_RR) | |
7665 | return "basr\t%2,%0"; | |
7666 | else | |
7667 | return "bas\t%2,%a0"; | |
7668 | } | |
7669 | [(set (attr "op_type") | |
7670 | (if_then_else (match_operand 0 "register_operand" "") | |
7671 | (const_string "RR") (const_string "RX"))) | |
7672 | (set_attr "type" "jsr") | |
7673 | (set_attr "atype" "agen")]) | |
4673c1a0 | 7674 | |
7675 | ; | |
7676 | ; call_value instruction pattern(s). | |
7677 | ; | |
7678 | ||
7679 | (define_expand "call_value" | |
c89f9ed7 | 7680 | [(set (match_operand 0 "" "") |
7681 | (call (match_operand 1 "" "") | |
7682 | (match_operand 2 "" ""))) | |
7683 | (use (match_operand 3 "" ""))] | |
4673c1a0 | 7684 | "" |
4673c1a0 | 7685 | { |
346fecd5 | 7686 | s390_emit_call (XEXP (operands[1], 0), NULL_RTX, operands[0], |
7346ca58 | 7687 | gen_rtx_REG (Pmode, RETURN_REGNUM)); |
c89f9ed7 | 7688 | DONE; |
83e641bd | 7689 | }) |
4673c1a0 | 7690 | |
dafc8d45 | 7691 | (define_insn "*bras_r" |
9eabd191 | 7692 | [(set (match_operand 0 "" "") |
dafc8d45 | 7693 | (call (mem:QI (match_operand 1 "bras_sym_operand" "X")) |
4673c1a0 | 7694 | (match_operand:SI 2 "const_int_operand" "n"))) |
dafc8d45 | 7695 | (clobber (match_operand 3 "register_operand" "=r"))] |
346fecd5 | 7696 | "!SIBLING_CALL_P (insn) |
7697 | && TARGET_SMALL_EXEC | |
7346ca58 | 7698 | && GET_MODE (operands[3]) == Pmode" |
f24d7ff3 | 7699 | "bras\t%3,%1" |
4673c1a0 | 7700 | [(set_attr "op_type" "RI") |
369293ed | 7701 | (set_attr "type" "jsr")]) |
4673c1a0 | 7702 | |
dafc8d45 | 7703 | (define_insn "*brasl_r" |
9eabd191 | 7704 | [(set (match_operand 0 "" "") |
dafc8d45 | 7705 | (call (mem:QI (match_operand 1 "bras_sym_operand" "X")) |
7706 | (match_operand 2 "const_int_operand" "n"))) | |
7707 | (clobber (match_operand 3 "register_operand" "=r"))] | |
346fecd5 | 7708 | "!SIBLING_CALL_P (insn) |
7709 | && TARGET_CPU_ZARCH | |
7346ca58 | 7710 | && GET_MODE (operands[3]) == Pmode" |
dafc8d45 | 7711 | "brasl\t%3,%1" |
7712 | [(set_attr "op_type" "RIL") | |
71343e6b | 7713 | (set_attr "type" "jsr")]) |
4673c1a0 | 7714 | |
dafc8d45 | 7715 | (define_insn "*basr_r" |
9eabd191 | 7716 | [(set (match_operand 0 "" "") |
dafc8d45 | 7717 | (call (mem:QI (match_operand 1 "address_operand" "U")) |
7718 | (match_operand 2 "const_int_operand" "n"))) | |
7719 | (clobber (match_operand 3 "register_operand" "=r"))] | |
7346ca58 | 7720 | "!SIBLING_CALL_P (insn) && GET_MODE (operands[3]) == Pmode" |
dafc8d45 | 7721 | { |
7722 | if (get_attr_op_type (insn) == OP_TYPE_RR) | |
7723 | return "basr\t%3,%1"; | |
7724 | else | |
7725 | return "bas\t%3,%a1"; | |
7726 | } | |
7727 | [(set (attr "op_type") | |
7728 | (if_then_else (match_operand 1 "register_operand" "") | |
7729 | (const_string "RR") (const_string "RX"))) | |
7730 | (set_attr "type" "jsr") | |
7731 | (set_attr "atype" "agen")]) | |
4673c1a0 | 7732 | |
be00aaa8 | 7733 | ;; |
7734 | ;;- Thread-local storage support. | |
7735 | ;; | |
7736 | ||
923cf36d | 7737 | (define_expand "get_tp_64" |
1ca361fd | 7738 | [(set (match_operand:DI 0 "nonimmediate_operand" "") (reg:DI TP_REGNUM))] |
be00aaa8 | 7739 | "TARGET_64BIT" |
923cf36d | 7740 | "") |
be00aaa8 | 7741 | |
923cf36d | 7742 | (define_expand "get_tp_31" |
1ca361fd | 7743 | [(set (match_operand:SI 0 "nonimmediate_operand" "") (reg:SI TP_REGNUM))] |
be00aaa8 | 7744 | "!TARGET_64BIT" |
923cf36d | 7745 | "") |
be00aaa8 | 7746 | |
923cf36d | 7747 | (define_expand "set_tp_64" |
1ca361fd | 7748 | [(set (reg:DI TP_REGNUM) (match_operand:DI 0 "nonimmediate_operand" "")) |
7749 | (set (reg:DI TP_REGNUM) (unspec_volatile:DI [(reg:DI TP_REGNUM)] UNSPECV_SET_TP))] | |
be00aaa8 | 7750 | "TARGET_64BIT" |
923cf36d | 7751 | "") |
be00aaa8 | 7752 | |
923cf36d | 7753 | (define_expand "set_tp_31" |
1ca361fd | 7754 | [(set (reg:SI TP_REGNUM) (match_operand:SI 0 "nonimmediate_operand" "")) |
7755 | (set (reg:SI TP_REGNUM) (unspec_volatile:SI [(reg:SI TP_REGNUM)] UNSPECV_SET_TP))] | |
be00aaa8 | 7756 | "!TARGET_64BIT" |
923cf36d | 7757 | "") |
7758 | ||
7759 | (define_insn "*set_tp" | |
1ca361fd | 7760 | [(set (reg TP_REGNUM) (unspec_volatile [(reg TP_REGNUM)] UNSPECV_SET_TP))] |
923cf36d | 7761 | "" |
7762 | "" | |
7763 | [(set_attr "type" "none") | |
7764 | (set_attr "length" "0")]) | |
f81e845f | 7765 | |
be00aaa8 | 7766 | (define_insn "*tls_load_64" |
7767 | [(set (match_operand:DI 0 "register_operand" "=d") | |
8fe52251 | 7768 | (unspec:DI [(match_operand:DI 1 "memory_operand" "RT") |
be00aaa8 | 7769 | (match_operand:DI 2 "" "")] |
7770 | UNSPEC_TLS_LOAD))] | |
7771 | "TARGET_64BIT" | |
f24d7ff3 | 7772 | "lg\t%0,%1%J2" |
be00aaa8 | 7773 | [(set_attr "op_type" "RXE")]) |
7774 | ||
7775 | (define_insn "*tls_load_31" | |
51aa1e9c | 7776 | [(set (match_operand:SI 0 "register_operand" "=d,d") |
7777 | (unspec:SI [(match_operand:SI 1 "memory_operand" "R,T") | |
be00aaa8 | 7778 | (match_operand:SI 2 "" "")] |
7779 | UNSPEC_TLS_LOAD))] | |
7780 | "!TARGET_64BIT" | |
51aa1e9c | 7781 | "@ |
f24d7ff3 | 7782 | l\t%0,%1%J2 |
7783 | ly\t%0,%1%J2" | |
51aa1e9c | 7784 | [(set_attr "op_type" "RX,RXY")]) |
be00aaa8 | 7785 | |
dafc8d45 | 7786 | (define_insn "*bras_tls" |
9eabd191 | 7787 | [(set (match_operand 0 "" "") |
dafc8d45 | 7788 | (call (mem:QI (match_operand 1 "bras_sym_operand" "X")) |
7789 | (match_operand 2 "const_int_operand" "n"))) | |
7790 | (clobber (match_operand 3 "register_operand" "=r")) | |
7791 | (use (match_operand 4 "" ""))] | |
346fecd5 | 7792 | "!SIBLING_CALL_P (insn) |
7793 | && TARGET_SMALL_EXEC | |
7346ca58 | 7794 | && GET_MODE (operands[3]) == Pmode" |
f24d7ff3 | 7795 | "bras\t%3,%1%J4" |
be00aaa8 | 7796 | [(set_attr "op_type" "RI") |
7797 | (set_attr "type" "jsr")]) | |
7798 | ||
dafc8d45 | 7799 | (define_insn "*brasl_tls" |
9eabd191 | 7800 | [(set (match_operand 0 "" "") |
dafc8d45 | 7801 | (call (mem:QI (match_operand 1 "bras_sym_operand" "X")) |
7802 | (match_operand 2 "const_int_operand" "n"))) | |
7803 | (clobber (match_operand 3 "register_operand" "=r")) | |
7804 | (use (match_operand 4 "" ""))] | |
346fecd5 | 7805 | "!SIBLING_CALL_P (insn) |
7806 | && TARGET_CPU_ZARCH | |
7346ca58 | 7807 | && GET_MODE (operands[3]) == Pmode" |
dafc8d45 | 7808 | "brasl\t%3,%1%J4" |
7809 | [(set_attr "op_type" "RIL") | |
be00aaa8 | 7810 | (set_attr "type" "jsr")]) |
7811 | ||
dafc8d45 | 7812 | (define_insn "*basr_tls" |
9eabd191 | 7813 | [(set (match_operand 0 "" "") |
dafc8d45 | 7814 | (call (mem:QI (match_operand 1 "address_operand" "U")) |
7815 | (match_operand 2 "const_int_operand" "n"))) | |
7816 | (clobber (match_operand 3 "register_operand" "=r")) | |
7817 | (use (match_operand 4 "" ""))] | |
7346ca58 | 7818 | "!SIBLING_CALL_P (insn) && GET_MODE (operands[3]) == Pmode" |
dafc8d45 | 7819 | { |
7820 | if (get_attr_op_type (insn) == OP_TYPE_RR) | |
7821 | return "basr\t%3,%1%J4"; | |
7822 | else | |
7823 | return "bas\t%3,%a1%J4"; | |
7824 | } | |
7825 | [(set (attr "op_type") | |
7826 | (if_then_else (match_operand 1 "register_operand" "") | |
7827 | (const_string "RR") (const_string "RX"))) | |
7828 | (set_attr "type" "jsr") | |
7829 | (set_attr "atype" "agen")]) | |
be00aaa8 | 7830 | |
891e3096 | 7831 | ;; |
7832 | ;;- Atomic operations | |
7833 | ;; | |
7834 | ||
7835 | ; | |
7836 | ; memory barrier pattern. | |
7837 | ; | |
7838 | ||
7839 | (define_expand "memory_barrier" | |
7840 | [(set (mem:BLK (match_dup 0)) | |
7841 | (unspec_volatile:BLK [(mem:BLK (match_dup 0))] UNSPECV_MB))] | |
7842 | "" | |
7843 | { | |
7844 | operands[0] = gen_rtx_MEM (BLKmode, gen_rtx_SCRATCH (DImode)); | |
7845 | MEM_VOLATILE_P (operands[0]) = 1; | |
7846 | }) | |
7847 | ||
7848 | (define_insn "*memory_barrier" | |
7849 | [(set (match_operand:BLK 0 "" "") | |
7850 | (unspec_volatile:BLK [(match_operand:BLK 1 "" "")] UNSPECV_MB))] | |
7851 | "" | |
7852 | "bcr\t15,0" | |
7853 | [(set_attr "op_type" "RR")]) | |
7854 | ||
7855 | ; | |
7856 | ; compare and swap patterns. | |
7857 | ; | |
7858 | ||
86693d48 | 7859 | (define_expand "sync_compare_and_swap<mode>" |
7860 | [(parallel | |
7861 | [(set (match_operand:TDSI 0 "register_operand" "") | |
7862 | (match_operand:TDSI 1 "memory_operand" "")) | |
7863 | (set (match_dup 1) | |
7864 | (unspec_volatile:TDSI | |
7865 | [(match_dup 1) | |
7866 | (match_operand:TDSI 2 "register_operand" "") | |
7867 | (match_operand:TDSI 3 "register_operand" "")] | |
7868 | UNSPECV_CAS)) | |
7869 | (set (reg:CCZ1 CC_REGNUM) | |
7870 | (compare:CCZ1 (match_dup 1) (match_dup 2)))])] | |
7871 | "") | |
891e3096 | 7872 | |
182f815e | 7873 | (define_expand "sync_compare_and_swap<mode>" |
7874 | [(parallel | |
7875 | [(set (match_operand:HQI 0 "register_operand" "") | |
7876 | (match_operand:HQI 1 "memory_operand" "")) | |
7877 | (set (match_dup 1) | |
7878 | (unspec_volatile:HQI | |
7879 | [(match_dup 1) | |
7880 | (match_operand:HQI 2 "general_operand" "") | |
7881 | (match_operand:HQI 3 "general_operand" "")] | |
7882 | UNSPECV_CAS)) | |
7883 | (set (reg:CCZ1 CC_REGNUM) | |
7884 | (compare:CCZ1 (match_dup 1) (match_dup 2)))])] | |
7885 | "" | |
7886 | "s390_expand_cs_hqi (<MODE>mode, operands[0], operands[1], | |
7887 | operands[2], operands[3]); DONE;") | |
7888 | ||
891e3096 | 7889 | (define_expand "sync_compare_and_swap_cc<mode>" |
7890 | [(parallel | |
86693d48 | 7891 | [(set (match_operand:TDSI 0 "register_operand" "") |
7892 | (match_operand:TDSI 1 "memory_operand" "")) | |
891e3096 | 7893 | (set (match_dup 1) |
86693d48 | 7894 | (unspec_volatile:TDSI |
891e3096 | 7895 | [(match_dup 1) |
86693d48 | 7896 | (match_operand:TDSI 2 "register_operand" "") |
7897 | (match_operand:TDSI 3 "register_operand" "")] | |
891e3096 | 7898 | UNSPECV_CAS)) |
7899 | (set (match_dup 4) | |
9c93d843 | 7900 | (compare:CCZ1 (match_dup 1) (match_dup 2)))])] |
891e3096 | 7901 | "" |
7902 | { | |
86693d48 | 7903 | /* Emulate compare. */ |
9c93d843 | 7904 | operands[4] = gen_rtx_REG (CCZ1mode, CC_REGNUM); |
891e3096 | 7905 | s390_compare_op0 = operands[1]; |
7906 | s390_compare_op1 = operands[2]; | |
7907 | s390_compare_emitted = operands[4]; | |
7908 | }) | |
7909 | ||
87bc9927 | 7910 | ; cds, cdsg |
86693d48 | 7911 | (define_insn "*sync_compare_and_swap<mode>" |
7912 | [(set (match_operand:DP 0 "register_operand" "=r") | |
7913 | (match_operand:DP 1 "memory_operand" "+Q")) | |
7914 | (set (match_dup 1) | |
7915 | (unspec_volatile:DP | |
7916 | [(match_dup 1) | |
7917 | (match_operand:DP 2 "register_operand" "0") | |
7918 | (match_operand:DP 3 "register_operand" "r")] | |
7919 | UNSPECV_CAS)) | |
7920 | (set (reg:CCZ1 CC_REGNUM) | |
7921 | (compare:CCZ1 (match_dup 1) (match_dup 2)))] | |
7922 | "" | |
7923 | "cds<tg>\t%0,%3,%S1" | |
7924 | [(set_attr "op_type" "RS<TE>") | |
7925 | (set_attr "type" "sem")]) | |
7926 | ||
87bc9927 | 7927 | ; cs, csg |
86693d48 | 7928 | (define_insn "*sync_compare_and_swap<mode>" |
891e3096 | 7929 | [(set (match_operand:GPR 0 "register_operand" "=r") |
7930 | (match_operand:GPR 1 "memory_operand" "+Q")) | |
7931 | (set (match_dup 1) | |
7932 | (unspec_volatile:GPR | |
7933 | [(match_dup 1) | |
7934 | (match_operand:GPR 2 "register_operand" "0") | |
7935 | (match_operand:GPR 3 "register_operand" "r")] | |
7936 | UNSPECV_CAS)) | |
9c93d843 | 7937 | (set (reg:CCZ1 CC_REGNUM) |
7938 | (compare:CCZ1 (match_dup 1) (match_dup 2)))] | |
891e3096 | 7939 | "" |
7940 | "cs<g>\t%0,%3,%S1" | |
7941 | [(set_attr "op_type" "RS<E>") | |
7942 | (set_attr "type" "sem")]) | |
7943 | ||
7944 | ||
7cc66daf | 7945 | ; |
7946 | ; Other atomic instruction patterns. | |
7947 | ; | |
7948 | ||
7949 | (define_expand "sync_lock_test_and_set<mode>" | |
7950 | [(match_operand:HQI 0 "register_operand") | |
7951 | (match_operand:HQI 1 "memory_operand") | |
7952 | (match_operand:HQI 2 "general_operand")] | |
7953 | "" | |
7954 | "s390_expand_atomic (<MODE>mode, SET, operands[0], operands[1], | |
7955 | operands[2], false); DONE;") | |
7956 | ||
7957 | (define_expand "sync_<atomic><mode>" | |
7958 | [(set (match_operand:HQI 0 "memory_operand") | |
7959 | (ATOMIC:HQI (match_dup 0) | |
7960 | (match_operand:HQI 1 "general_operand")))] | |
7961 | "" | |
7962 | "s390_expand_atomic (<MODE>mode, <CODE>, NULL_RTX, operands[0], | |
7963 | operands[1], false); DONE;") | |
7964 | ||
7965 | (define_expand "sync_old_<atomic><mode>" | |
7966 | [(set (match_operand:HQI 0 "register_operand") | |
7967 | (match_operand:HQI 1 "memory_operand")) | |
7968 | (set (match_dup 1) | |
7969 | (ATOMIC:HQI (match_dup 1) | |
7970 | (match_operand:HQI 2 "general_operand")))] | |
7971 | "" | |
7972 | "s390_expand_atomic (<MODE>mode, <CODE>, operands[0], operands[1], | |
7973 | operands[2], false); DONE;") | |
7974 | ||
7975 | (define_expand "sync_new_<atomic><mode>" | |
7976 | [(set (match_operand:HQI 0 "register_operand") | |
7977 | (ATOMIC:HQI (match_operand:HQI 1 "memory_operand") | |
7978 | (match_operand:HQI 2 "general_operand"))) | |
7979 | (set (match_dup 1) (ATOMIC:HQI (match_dup 1) (match_dup 2)))] | |
7980 | "" | |
7981 | "s390_expand_atomic (<MODE>mode, <CODE>, operands[0], operands[1], | |
7982 | operands[2], true); DONE;") | |
7983 | ||
4673c1a0 | 7984 | ;; |
7985 | ;;- Miscellaneous instructions. | |
7986 | ;; | |
7987 | ||
7988 | ; | |
7989 | ; allocate stack instruction pattern(s). | |
7990 | ; | |
7991 | ||
7992 | (define_expand "allocate_stack" | |
32f55309 | 7993 | [(match_operand 0 "general_operand" "") |
7994 | (match_operand 1 "general_operand" "")] | |
646a946e | 7995 | "TARGET_BACKCHAIN" |
4673c1a0 | 7996 | { |
32f55309 | 7997 | rtx temp = gen_reg_rtx (Pmode); |
4673c1a0 | 7998 | |
32f55309 | 7999 | emit_move_insn (temp, s390_back_chain_rtx ()); |
8000 | anti_adjust_stack (operands[1]); | |
8001 | emit_move_insn (s390_back_chain_rtx (), temp); | |
4673c1a0 | 8002 | |
32f55309 | 8003 | emit_move_insn (operands[0], virtual_stack_dynamic_rtx); |
8004 | DONE; | |
83e641bd | 8005 | }) |
4673c1a0 | 8006 | |
8007 | ||
8008 | ; | |
a3cab1c2 | 8009 | ; setjmp instruction pattern. |
4673c1a0 | 8010 | ; |
8011 | ||
4673c1a0 | 8012 | (define_expand "builtin_setjmp_receiver" |
12ef3745 | 8013 | [(match_operand 0 "" "")] |
0c0a8ea5 | 8014 | "flag_pic" |
4673c1a0 | 8015 | { |
20074f87 | 8016 | emit_insn (s390_load_got ()); |
18b42941 | 8017 | emit_use (pic_offset_table_rtx); |
4673c1a0 | 8018 | DONE; |
12ef3745 | 8019 | }) |
4673c1a0 | 8020 | |
4673c1a0 | 8021 | ;; These patterns say how to save and restore the stack pointer. We need not |
8022 | ;; save the stack pointer at function level since we are careful to | |
8023 | ;; preserve the backchain. At block level, we have to restore the backchain | |
8024 | ;; when we restore the stack pointer. | |
8025 | ;; | |
8026 | ;; For nonlocal gotos, we must save both the stack pointer and its | |
8027 | ;; backchain and restore both. Note that in the nonlocal case, the | |
8028 | ;; save area is a memory location. | |
8029 | ||
8030 | (define_expand "save_stack_function" | |
8031 | [(match_operand 0 "general_operand" "") | |
8032 | (match_operand 1 "general_operand" "")] | |
8033 | "" | |
8034 | "DONE;") | |
8035 | ||
8036 | (define_expand "restore_stack_function" | |
8037 | [(match_operand 0 "general_operand" "") | |
8038 | (match_operand 1 "general_operand" "")] | |
8039 | "" | |
8040 | "DONE;") | |
8041 | ||
8042 | (define_expand "restore_stack_block" | |
32f55309 | 8043 | [(match_operand 0 "register_operand" "") |
8044 | (match_operand 1 "register_operand" "")] | |
646a946e | 8045 | "TARGET_BACKCHAIN" |
4673c1a0 | 8046 | { |
32f55309 | 8047 | rtx temp = gen_reg_rtx (Pmode); |
8048 | ||
8049 | emit_move_insn (temp, s390_back_chain_rtx ()); | |
8050 | emit_move_insn (operands[0], operands[1]); | |
8051 | emit_move_insn (s390_back_chain_rtx (), temp); | |
8052 | ||
8053 | DONE; | |
83e641bd | 8054 | }) |
4673c1a0 | 8055 | |
8056 | (define_expand "save_stack_nonlocal" | |
8057 | [(match_operand 0 "memory_operand" "") | |
8058 | (match_operand 1 "register_operand" "")] | |
8059 | "" | |
4673c1a0 | 8060 | { |
32f55309 | 8061 | enum machine_mode mode = TARGET_64BIT ? OImode : TImode; |
8062 | rtx base = gen_rtx_REG (Pmode, BASE_REGNUM); | |
8063 | ||
8064 | /* Copy the backchain to the first word, sp to the second and the | |
8065 | literal pool base to the third. */ | |
8066 | ||
646a946e | 8067 | if (TARGET_BACKCHAIN) |
32f55309 | 8068 | { |
8069 | rtx temp = force_reg (Pmode, s390_back_chain_rtx ()); | |
8070 | emit_move_insn (operand_subword (operands[0], 0, 0, mode), temp); | |
8071 | } | |
8072 | ||
8073 | emit_move_insn (operand_subword (operands[0], 1, 0, mode), operands[1]); | |
8074 | emit_move_insn (operand_subword (operands[0], 2, 0, mode), base); | |
4673c1a0 | 8075 | |
4673c1a0 | 8076 | DONE; |
83e641bd | 8077 | }) |
4673c1a0 | 8078 | |
8079 | (define_expand "restore_stack_nonlocal" | |
8080 | [(match_operand 0 "register_operand" "") | |
8081 | (match_operand 1 "memory_operand" "")] | |
8082 | "" | |
4673c1a0 | 8083 | { |
32f55309 | 8084 | enum machine_mode mode = TARGET_64BIT ? OImode : TImode; |
a0f191f4 | 8085 | rtx base = gen_rtx_REG (Pmode, BASE_REGNUM); |
32f55309 | 8086 | rtx temp = NULL_RTX; |
4673c1a0 | 8087 | |
a3cab1c2 | 8088 | /* Restore the backchain from the first word, sp from the second and the |
1d60d981 | 8089 | literal pool base from the third. */ |
a3cab1c2 | 8090 | |
646a946e | 8091 | if (TARGET_BACKCHAIN) |
32f55309 | 8092 | temp = force_reg (Pmode, operand_subword (operands[1], 0, 0, mode)); |
8093 | ||
8094 | emit_move_insn (base, operand_subword (operands[1], 2, 0, mode)); | |
8095 | emit_move_insn (operands[0], operand_subword (operands[1], 1, 0, mode)); | |
8096 | ||
8097 | if (temp) | |
8098 | emit_move_insn (s390_back_chain_rtx (), temp); | |
8099 | ||
18b42941 | 8100 | emit_use (base); |
4673c1a0 | 8101 | DONE; |
83e641bd | 8102 | }) |
4673c1a0 | 8103 | |
1e639cb0 | 8104 | (define_expand "exception_receiver" |
8105 | [(const_int 0)] | |
8106 | "" | |
8107 | { | |
8108 | s390_set_has_landing_pad_p (true); | |
8109 | DONE; | |
8110 | }) | |
4673c1a0 | 8111 | |
8112 | ; | |
8113 | ; nop instruction pattern(s). | |
8114 | ; | |
8115 | ||
8116 | (define_insn "nop" | |
8117 | [(const_int 0)] | |
8118 | "" | |
f24d7ff3 | 8119 | "lr\t0,0" |
4673c1a0 | 8120 | [(set_attr "op_type" "RR")]) |
8121 | ||
8122 | ||
8123 | ; | |
8124 | ; Special literal pool access instruction pattern(s). | |
8125 | ; | |
8126 | ||
df82fb76 | 8127 | (define_insn "*pool_entry" |
8128 | [(unspec_volatile [(match_operand 0 "consttable_operand" "X")] | |
8129 | UNSPECV_POOL_ENTRY)] | |
4673c1a0 | 8130 | "" |
4673c1a0 | 8131 | { |
df82fb76 | 8132 | enum machine_mode mode = GET_MODE (PATTERN (insn)); |
8133 | unsigned int align = GET_MODE_BITSIZE (mode); | |
74d2529d | 8134 | s390_output_pool_entry (operands[0], mode, align); |
12ef3745 | 8135 | return ""; |
8136 | } | |
1822f0d6 | 8137 | [(set (attr "length") |
df82fb76 | 8138 | (symbol_ref "GET_MODE_SIZE (GET_MODE (PATTERN (insn)))"))]) |
0756cebb | 8139 | |
d345b493 | 8140 | (define_insn "pool_align" |
8141 | [(unspec_volatile [(match_operand 0 "const_int_operand" "n")] | |
8142 | UNSPECV_POOL_ALIGN)] | |
8143 | "" | |
8144 | ".align\t%0" | |
1822f0d6 | 8145 | [(set (attr "length") (symbol_ref "INTVAL (operands[0])"))]) |
0756cebb | 8146 | |
d345b493 | 8147 | (define_insn "pool_section_start" |
8148 | [(unspec_volatile [(const_int 1)] UNSPECV_POOL_SECTION)] | |
8149 | "" | |
8150 | ".section\t.rodata" | |
1822f0d6 | 8151 | [(set_attr "length" "0")]) |
0756cebb | 8152 | |
d345b493 | 8153 | (define_insn "pool_section_end" |
8154 | [(unspec_volatile [(const_int 0)] UNSPECV_POOL_SECTION)] | |
8155 | "" | |
0756cebb | 8156 | ".previous" |
1822f0d6 | 8157 | [(set_attr "length" "0")]) |
0756cebb | 8158 | |
c2c1332a | 8159 | (define_insn "main_base_31_small" |
dafc8d45 | 8160 | [(set (match_operand 0 "register_operand" "=a") |
8161 | (unspec [(label_ref (match_operand 1 "" ""))] UNSPEC_MAIN_BASE))] | |
8162 | "!TARGET_CPU_ZARCH && GET_MODE (operands[0]) == Pmode" | |
c2c1332a | 8163 | "basr\t%0,0" |
8164 | [(set_attr "op_type" "RR") | |
8165 | (set_attr "type" "la")]) | |
8166 | ||
8167 | (define_insn "main_base_31_large" | |
dafc8d45 | 8168 | [(set (match_operand 0 "register_operand" "=a") |
8169 | (unspec [(label_ref (match_operand 1 "" ""))] UNSPEC_MAIN_BASE)) | |
c2c1332a | 8170 | (set (pc) (label_ref (match_operand 2 "" "")))] |
dafc8d45 | 8171 | "!TARGET_CPU_ZARCH && GET_MODE (operands[0]) == Pmode" |
c2c1332a | 8172 | "bras\t%0,%2" |
8173 | [(set_attr "op_type" "RI")]) | |
8174 | ||
8175 | (define_insn "main_base_64" | |
dafc8d45 | 8176 | [(set (match_operand 0 "register_operand" "=a") |
8177 | (unspec [(label_ref (match_operand 1 "" ""))] UNSPEC_MAIN_BASE))] | |
8178 | "TARGET_CPU_ZARCH && GET_MODE (operands[0]) == Pmode" | |
c2c1332a | 8179 | "larl\t%0,%1" |
8180 | [(set_attr "op_type" "RIL") | |
8181 | (set_attr "type" "larl")]) | |
8182 | ||
8183 | (define_insn "main_pool" | |
20074f87 | 8184 | [(set (match_operand 0 "register_operand" "=a") |
8185 | (unspec_volatile [(const_int 0)] UNSPECV_MAIN_POOL))] | |
8186 | "GET_MODE (operands[0]) == Pmode" | |
32eda510 | 8187 | { |
8188 | gcc_unreachable (); | |
8189 | } | |
1822f0d6 | 8190 | [(set (attr "type") |
76dbb8df | 8191 | (if_then_else (ne (symbol_ref "TARGET_CPU_ZARCH") (const_int 0)) |
8192 | (const_string "larl") (const_string "la")))]) | |
c2c1332a | 8193 | |
96be3ab6 | 8194 | (define_insn "reload_base_31" |
dafc8d45 | 8195 | [(set (match_operand 0 "register_operand" "=a") |
8196 | (unspec [(label_ref (match_operand 1 "" ""))] UNSPEC_RELOAD_BASE))] | |
8197 | "!TARGET_CPU_ZARCH && GET_MODE (operands[0]) == Pmode" | |
f24d7ff3 | 8198 | "basr\t%0,0\;la\t%0,%1-.(%0)" |
1822f0d6 | 8199 | [(set_attr "length" "6") |
8200 | (set_attr "type" "la")]) | |
0756cebb | 8201 | |
96be3ab6 | 8202 | (define_insn "reload_base_64" |
dafc8d45 | 8203 | [(set (match_operand 0 "register_operand" "=a") |
8204 | (unspec [(label_ref (match_operand 1 "" ""))] UNSPEC_RELOAD_BASE))] | |
8205 | "TARGET_CPU_ZARCH && GET_MODE (operands[0]) == Pmode" | |
f24d7ff3 | 8206 | "larl\t%0,%1" |
96be3ab6 | 8207 | [(set_attr "op_type" "RIL") |
71343e6b | 8208 | (set_attr "type" "larl")]) |
96be3ab6 | 8209 | |
96be3ab6 | 8210 | (define_insn "pool" |
12ef3745 | 8211 | [(unspec_volatile [(match_operand 0 "const_int_operand" "n")] UNSPECV_POOL)] |
96be3ab6 | 8212 | "" |
32eda510 | 8213 | { |
8214 | gcc_unreachable (); | |
8215 | } | |
1822f0d6 | 8216 | [(set (attr "length") (symbol_ref "INTVAL (operands[0])"))]) |
4673c1a0 | 8217 | |
8b4a4127 | 8218 | ;; |
8219 | ;; Insns related to generating the function prologue and epilogue. | |
8220 | ;; | |
8221 | ||
8222 | ||
8223 | (define_expand "prologue" | |
8224 | [(use (const_int 0))] | |
8225 | "" | |
83e641bd | 8226 | "s390_emit_prologue (); DONE;") |
8b4a4127 | 8227 | |
8228 | (define_expand "epilogue" | |
8229 | [(use (const_int 1))] | |
8230 | "" | |
7346ca58 | 8231 | "s390_emit_epilogue (false); DONE;") |
8232 | ||
8233 | (define_expand "sibcall_epilogue" | |
8234 | [(use (const_int 0))] | |
8235 | "" | |
8236 | "s390_emit_epilogue (true); DONE;") | |
8b4a4127 | 8237 | |
dafc8d45 | 8238 | (define_insn "*return" |
8b4a4127 | 8239 | [(return) |
dafc8d45 | 8240 | (use (match_operand 0 "register_operand" "a"))] |
8241 | "GET_MODE (operands[0]) == Pmode" | |
f24d7ff3 | 8242 | "br\t%0" |
8b4a4127 | 8243 | [(set_attr "op_type" "RR") |
f81e845f | 8244 | (set_attr "type" "jsr") |
71343e6b | 8245 | (set_attr "atype" "agen")]) |
8b4a4127 | 8246 | |
8b4a4127 | 8247 | |
f81e845f | 8248 | ;; Instruction definition to extend a 31-bit pointer into a 64-bit |
efee20da | 8249 | ;; pointer. This is used for compatibility. |
f81e845f | 8250 | |
8251 | (define_expand "ptr_extend" | |
8252 | [(set (match_operand:DI 0 "register_operand" "=r") | |
8253 | (match_operand:SI 1 "register_operand" "r"))] | |
dafc8d45 | 8254 | "TARGET_64BIT" |
f81e845f | 8255 | { |
f81e845f | 8256 | emit_insn (gen_anddi3 (operands[0], |
8257 | gen_lowpart (DImode, operands[1]), | |
8258 | GEN_INT (0x7fffffff))); | |
f81e845f | 8259 | DONE; |
83e641bd | 8260 | }) |
b33c41a1 | 8261 | |
8262 | ;; Instruction definition to expand eh_return macro to support | |
8263 | ;; swapping in special linkage return addresses. | |
8264 | ||
8265 | (define_expand "eh_return" | |
8266 | [(use (match_operand 0 "register_operand" ""))] | |
8267 | "TARGET_TPF" | |
8268 | { | |
8269 | s390_emit_tpf_eh_return (operands[0]); | |
8270 | DONE; | |
8271 | }) | |
8272 | ||
cc87d0c5 | 8273 | ; |
8274 | ; Stack Protector Patterns | |
8275 | ; | |
8276 | ||
8277 | (define_expand "stack_protect_set" | |
8278 | [(set (match_operand 0 "memory_operand" "") | |
8279 | (match_operand 1 "memory_operand" ""))] | |
8280 | "" | |
8281 | { | |
8282 | #ifdef TARGET_THREAD_SSP_OFFSET | |
8283 | operands[1] | |
8284 | = gen_rtx_MEM (Pmode, gen_rtx_PLUS (Pmode, s390_get_thread_pointer (), | |
8285 | GEN_INT (TARGET_THREAD_SSP_OFFSET))); | |
8286 | #endif | |
8287 | if (TARGET_64BIT) | |
8288 | emit_insn (gen_stack_protect_setdi (operands[0], operands[1])); | |
8289 | else | |
8290 | emit_insn (gen_stack_protect_setsi (operands[0], operands[1])); | |
8291 | ||
8292 | DONE; | |
8293 | }) | |
8294 | ||
8295 | (define_insn "stack_protect_set<mode>" | |
8296 | [(set (match_operand:DSI 0 "memory_operand" "=Q") | |
8297 | (unspec:DSI [(match_operand:DSI 1 "memory_operand" "Q")] UNSPEC_SP_SET))] | |
8298 | "" | |
8299 | "mvc\t%O0(%G0,%R0),%S1" | |
8300 | [(set_attr "op_type" "SS")]) | |
8301 | ||
8302 | (define_expand "stack_protect_test" | |
8303 | [(set (reg:CC CC_REGNUM) | |
8304 | (compare (match_operand 0 "memory_operand" "") | |
8305 | (match_operand 1 "memory_operand" ""))) | |
8306 | (match_operand 2 "" "")] | |
8307 | "" | |
8308 | { | |
8309 | #ifdef TARGET_THREAD_SSP_OFFSET | |
8310 | operands[1] | |
8311 | = gen_rtx_MEM (Pmode, gen_rtx_PLUS (Pmode, s390_get_thread_pointer (), | |
8312 | GEN_INT (TARGET_THREAD_SSP_OFFSET))); | |
8313 | #endif | |
8314 | s390_compare_op0 = operands[0]; | |
8315 | s390_compare_op1 = operands[1]; | |
8316 | s390_compare_emitted = gen_rtx_REG (CCZmode, CC_REGNUM); | |
8317 | ||
8318 | if (TARGET_64BIT) | |
8319 | emit_insn (gen_stack_protect_testdi (operands[0], operands[1])); | |
8320 | else | |
8321 | emit_insn (gen_stack_protect_testsi (operands[0], operands[1])); | |
8322 | ||
8323 | emit_jump_insn (gen_beq (operands[2])); | |
8324 | ||
8325 | DONE; | |
8326 | }) | |
8327 | ||
8328 | (define_insn "stack_protect_test<mode>" | |
8329 | [(set (reg:CCZ CC_REGNUM) | |
8330 | (unspec:CCZ [(match_operand:DSI 0 "memory_operand" "Q") | |
8331 | (match_operand:DSI 1 "memory_operand" "Q")] UNSPEC_SP_TEST))] | |
8332 | "" | |
8333 | "clc\t%O0(%G0,%R0),%S1" | |
8334 | [(set_attr "op_type" "SS")]) | |
062c49fd | 8335 | |
8336 | ; This is used in s390_emit_prologue in order to prevent insns | |
8337 | ; adjusting the stack pointer to be moved over insns writing stack | |
8338 | ; slots using a copy of the stack pointer in a different register. | |
8339 | (define_insn "stack_tie" | |
8340 | [(set (match_operand:BLK 0 "memory_operand" "+m") | |
8341 | (unspec:BLK [(match_dup 0)] UNSPEC_TIE))] | |
8342 | "" | |
8343 | "" | |
8344 | [(set_attr "length" "0")]) | |
e68d6a13 | 8345 | |
8346 | ||
8347 | ; | |
8348 | ; Data prefetch patterns | |
8349 | ; | |
8350 | ||
8351 | (define_insn "prefetch" | |
8352 | [(prefetch (match_operand 0 "address_operand" "UW,X") | |
8353 | (match_operand:SI 1 "const_int_operand" "n,n") | |
8354 | (match_operand:SI 2 "const_int_operand" "n,n"))] | |
8355 | "TARGET_Z10" | |
8356 | { | |
8357 | if (larl_operand (operands[0], Pmode)) | |
8358 | return INTVAL (operands[1]) == 1 ? "pfdrl\t2,%a0" : "pfdrl\t1,%a0"; | |
8359 | ||
8360 | if (s390_mem_constraint ("W", operands[0]) | |
8361 | || s390_mem_constraint ("U", operands[0])) | |
8362 | return INTVAL (operands[1]) == 1 ? "pfd\t2,%a0" : "pfd\t1,%a0"; | |
8363 | ||
8364 | /* This point might be reached if op0 is a larl operand with an | |
8365 | uneven addend. In this case we simply omit issuing a prefetch | |
8366 | instruction. */ | |
8367 | ||
8368 | return ""; | |
8369 | ||
8370 | } [(set_attr "type" "load,larl") | |
8371 | (set_attr "op_type" "RXY,RIL")]) |