1;; GCC machine description for IA-32 and x86-64. 2;; Copyright (C) 1988, 1994, 1995, 1996, 1997, 1998, 1999, 2000, 3;; 2001, 2002, 2003, 2004, 2005, 2006, 2007, 2008, 2009, 2010, 2011, 2012 4;; Free Software Foundation, Inc. 5;; Mostly by William Schelter. 6;; x86_64 support added by Jan Hubicka 7;; 8;; This file is part of GCC. 9;; 10;; GCC is free software; you can redistribute it and/or modify 11;; it under the terms of the GNU General Public License as published by 12;; the Free Software Foundation; either version 3, or (at your option) 13;; any later version. 14;; 15;; GCC is distributed in the hope that it will be useful, 16;; but WITHOUT ANY WARRANTY; without even the implied warranty of 17;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 18;; GNU General Public License for more details. 19;; 20;; You should have received a copy of the GNU General Public License 21;; along with GCC; see the file COPYING3. If not see 22;; <http://www.gnu.org/licenses/>. */ 23;; 24;; The original PO technology requires these to be ordered by speed, 25;; so that assigner will pick the fastest. 26;; 27;; See file "rtl.def" for documentation on define_insn, match_*, et. al. 28;; 29;; The special asm out single letter directives following a '%' are: 30;; L,W,B,Q,S,T -- print the opcode suffix for specified size of operand. 31;; C -- print opcode suffix for set/cmov insn. 32;; c -- like C, but print reversed condition 33;; F,f -- likewise, but for floating-point. 34;; O -- if HAVE_AS_IX86_CMOV_SUN_SYNTAX, expand to "w.", "l." or "q.", 35;; otherwise nothing 36;; R -- print the prefix for register names. 37;; z -- print the opcode suffix for the size of the current operand. 38;; Z -- likewise, with special suffixes for x87 instructions. 39;; * -- print a star (in certain assembler syntax) 40;; A -- print an absolute memory reference. 41;; E -- print address with DImode register names if TARGET_64BIT. 42;; w -- print the operand as if it's a "word" (HImode) even if it isn't. 43;; s -- print a shift double count, followed by the assemblers argument 44;; delimiter. 45;; b -- print the QImode name of the register for the indicated operand. 46;; %b0 would print %al if operands[0] is reg 0. 47;; w -- likewise, print the HImode name of the register. 48;; k -- likewise, print the SImode name of the register. 49;; q -- likewise, print the DImode name of the register. 50;; x -- likewise, print the V4SFmode name of the register. 51;; t -- likewise, print the V8SFmode name of the register. 52;; h -- print the QImode name for a "high" register, either ah, bh, ch or dh. 53;; y -- print "st(0)" instead of "st" as a register. 54;; d -- print duplicated register operand for AVX instruction. 55;; D -- print condition for SSE cmp instruction. 56;; P -- if PIC, print an @PLT suffix. 57;; p -- print raw symbol name. 58;; X -- don't print any sort of PIC '@' suffix for a symbol. 59;; & -- print some in-use local-dynamic symbol name. 60;; H -- print a memory address offset by 8; used for sse high-parts 61;; Y -- print condition for XOP pcom* instruction. 62;; + -- print a branch hint as 'cs' or 'ds' prefix 63;; ; -- print a semicolon (after prefixes due to bug in older gas). 64;; @ -- print a segment register of thread base pointer load 65 66(define_c_enum "unspec" [ 67 ;; Relocation specifiers 68 UNSPEC_GOT 69 UNSPEC_GOTOFF 70 UNSPEC_GOTPCREL 71 UNSPEC_GOTTPOFF 72 UNSPEC_TPOFF 73 UNSPEC_NTPOFF 74 UNSPEC_DTPOFF 75 UNSPEC_GOTNTPOFF 76 UNSPEC_INDNTPOFF 77 UNSPEC_PLTOFF 78 UNSPEC_MACHOPIC_OFFSET 79 UNSPEC_PCREL 80 81 ;; Prologue support 82 UNSPEC_STACK_ALLOC 83 UNSPEC_SET_GOT 84 UNSPEC_SET_RIP 85 UNSPEC_SET_GOT_OFFSET 86 UNSPEC_MEMORY_BLOCKAGE 87 UNSPEC_STACK_CHECK 88 89 ;; TLS support 90 UNSPEC_TP 91 UNSPEC_TLS_GD 92 UNSPEC_TLS_LD_BASE 93 UNSPEC_TLSDESC 94 UNSPEC_TLS_IE_SUN 95 96 ;; Other random patterns 97 UNSPEC_SCAS 98 UNSPEC_FNSTSW 99 UNSPEC_SAHF 100 UNSPEC_PARITY 101 UNSPEC_FSTCW 102 UNSPEC_ADD_CARRY 103 UNSPEC_FLDCW 104 UNSPEC_REP 105 UNSPEC_LD_MPIC ; load_macho_picbase 106 UNSPEC_TRUNC_NOOP 107 UNSPEC_DIV_ALREADY_SPLIT 108 UNSPEC_MS_TO_SYSV_CALL 109 UNSPEC_CALL_NEEDS_VZEROUPPER 110 UNSPEC_PAUSE 111 UNSPEC_LEA_ADDR 112 UNSPEC_STOS 113 114 ;; For SSE/MMX support: 115 UNSPEC_FIX_NOTRUNC 116 UNSPEC_MASKMOV 117 UNSPEC_MOVMSK 118 UNSPEC_RCP 119 UNSPEC_RSQRT 120 UNSPEC_PSADBW 121 122 ;; Generic math support 123 UNSPEC_COPYSIGN 124 UNSPEC_IEEE_MIN ; not commutative 125 UNSPEC_IEEE_MAX ; not commutative 126 127 ;; x87 Floating point 128 UNSPEC_SIN 129 UNSPEC_COS 130 UNSPEC_FPATAN 131 UNSPEC_FYL2X 132 UNSPEC_FYL2XP1 133 UNSPEC_FRNDINT 134 UNSPEC_FIST 135 UNSPEC_F2XM1 136 UNSPEC_TAN 137 UNSPEC_FXAM 138 139 ;; x87 Rounding 140 UNSPEC_FRNDINT_FLOOR 141 UNSPEC_FRNDINT_CEIL 142 UNSPEC_FRNDINT_TRUNC 143 UNSPEC_FRNDINT_MASK_PM 144 UNSPEC_FIST_FLOOR 145 UNSPEC_FIST_CEIL 146 147 ;; x87 Double output FP 148 UNSPEC_SINCOS_COS 149 UNSPEC_SINCOS_SIN 150 UNSPEC_XTRACT_FRACT 151 UNSPEC_XTRACT_EXP 152 UNSPEC_FSCALE_FRACT 153 UNSPEC_FSCALE_EXP 154 UNSPEC_FPREM_F 155 UNSPEC_FPREM_U 156 UNSPEC_FPREM1_F 157 UNSPEC_FPREM1_U 158 159 UNSPEC_C2_FLAG 160 UNSPEC_FXAM_MEM 161 162 ;; SSP patterns 163 UNSPEC_SP_SET 164 UNSPEC_SP_TEST 165 UNSPEC_SP_TLS_SET 166 UNSPEC_SP_TLS_TEST 167 168 ;; For ROUND support 169 UNSPEC_ROUND 170 171 ;; For CRC32 support 172 UNSPEC_CRC32 173 174 ;; For BMI support 175 UNSPEC_BEXTR 176 177 ;; For BMI2 support 178 UNSPEC_PDEP 179 UNSPEC_PEXT 180]) 181 182(define_c_enum "unspecv" [ 183 UNSPECV_BLOCKAGE 184 UNSPECV_STACK_PROBE 185 UNSPECV_PROBE_STACK_RANGE 186 UNSPECV_ALIGN 187 UNSPECV_PROLOGUE_USE 188 UNSPECV_SPLIT_STACK_RETURN 189 UNSPECV_CLD 190 UNSPECV_NOPS 191 UNSPECV_RDTSC 192 UNSPECV_RDTSCP 193 UNSPECV_RDPMC 194 UNSPECV_LLWP_INTRINSIC 195 UNSPECV_SLWP_INTRINSIC 196 UNSPECV_LWPVAL_INTRINSIC 197 UNSPECV_LWPINS_INTRINSIC 198 UNSPECV_RDFSBASE 199 UNSPECV_RDGSBASE 200 UNSPECV_WRFSBASE 201 UNSPECV_WRGSBASE 202 203 ;; For RDRAND support 204 UNSPECV_RDRAND 205 206 ;; Non-local goto. 207 UNSPECV_NLGR 208 ]) 209 210;; Constants to represent rounding modes in the ROUND instruction 211(define_constants 212 [(ROUND_FLOOR 0x1) 213 (ROUND_CEIL 0x2) 214 (ROUND_TRUNC 0x3) 215 (ROUND_MXCSR 0x4) 216 (ROUND_NO_EXC 0x8) 217 ]) 218 219;; Constants to represent pcomtrue/pcomfalse variants 220(define_constants 221 [(PCOM_FALSE 0) 222 (PCOM_TRUE 1) 223 (COM_FALSE_S 2) 224 (COM_FALSE_P 3) 225 (COM_TRUE_S 4) 226 (COM_TRUE_P 5) 227 ]) 228 229;; Constants used in the XOP pperm instruction 230(define_constants 231 [(PPERM_SRC 0x00) /* copy source */ 232 (PPERM_INVERT 0x20) /* invert source */ 233 (PPERM_REVERSE 0x40) /* bit reverse source */ 234 (PPERM_REV_INV 0x60) /* bit reverse & invert src */ 235 (PPERM_ZERO 0x80) /* all 0's */ 236 (PPERM_ONES 0xa0) /* all 1's */ 237 (PPERM_SIGN 0xc0) /* propagate sign bit */ 238 (PPERM_INV_SIGN 0xe0) /* invert & propagate sign */ 239 (PPERM_SRC1 0x00) /* use first source byte */ 240 (PPERM_SRC2 0x10) /* use second source byte */ 241 ]) 242 243;; Registers by name. 244(define_constants 245 [(AX_REG 0) 246 (DX_REG 1) 247 (CX_REG 2) 248 (BX_REG 3) 249 (SI_REG 4) 250 (DI_REG 5) 251 (BP_REG 6) 252 (SP_REG 7) 253 (ST0_REG 8) 254 (ST1_REG 9) 255 (ST2_REG 10) 256 (ST3_REG 11) 257 (ST4_REG 12) 258 (ST5_REG 13) 259 (ST6_REG 14) 260 (ST7_REG 15) 261 (FLAGS_REG 17) 262 (FPSR_REG 18) 263 (FPCR_REG 19) 264 (XMM0_REG 21) 265 (XMM1_REG 22) 266 (XMM2_REG 23) 267 (XMM3_REG 24) 268 (XMM4_REG 25) 269 (XMM5_REG 26) 270 (XMM6_REG 27) 271 (XMM7_REG 28) 272 (MM0_REG 29) 273 (MM1_REG 30) 274 (MM2_REG 31) 275 (MM3_REG 32) 276 (MM4_REG 33) 277 (MM5_REG 34) 278 (MM6_REG 35) 279 (MM7_REG 36) 280 (R8_REG 37) 281 (R9_REG 38) 282 (R10_REG 39) 283 (R11_REG 40) 284 (R12_REG 41) 285 (R13_REG 42) 286 (XMM8_REG 45) 287 (XMM9_REG 46) 288 (XMM10_REG 47) 289 (XMM11_REG 48) 290 (XMM12_REG 49) 291 (XMM13_REG 50) 292 (XMM14_REG 51) 293 (XMM15_REG 52) 294 ]) 295 296;; Insns whose names begin with "x86_" are emitted by gen_FOO calls 297;; from i386.c. 298 299;; In C guard expressions, put expressions which may be compile-time 300;; constants first. This allows for better optimization. For 301;; example, write "TARGET_64BIT && reload_completed", not 302;; "reload_completed && TARGET_64BIT". 303 304 305;; Processor type. 306(define_attr "cpu" "none,pentium,pentiumpro,geode,k6,athlon,k8,core2,corei7, 307 atom,generic64,amdfam10,bdver1,bdver2,btver1" 308 (const (symbol_ref "ix86_schedule"))) 309 310;; A basic instruction type. Refinements due to arguments to be 311;; provided in other attributes. 312(define_attr "type" 313 "other,multi, 314 alu,alu1,negnot,imov,imovx,lea, 315 incdec,ishift,ishiftx,ishift1,rotate,rotatex,rotate1,imul,imulx,idiv, 316 icmp,test,ibr,setcc,icmov, 317 push,pop,call,callv,leave, 318 str,bitmanip, 319 fmov,fop,fsgn,fmul,fdiv,fpspc,fcmov,fcmp,fxch,fistp,fisttp,frndint, 320 sselog,sselog1,sseiadd,sseiadd1,sseishft,sseishft1,sseimul, 321 sse,ssemov,sseadd,ssemul,ssecmp,ssecomi,ssecvt,ssecvt1,sseicvt,ssediv,sseins, 322 ssemuladd,sse4arg,lwp, 323 mmx,mmxmov,mmxadd,mmxmul,mmxcmp,mmxcvt,mmxshft" 324 (const_string "other")) 325 326;; Main data type used by the insn 327(define_attr "mode" 328 "unknown,none,QI,HI,SI,DI,TI,OI,SF,DF,XF,TF,V8SF,V4DF,V4SF,V2DF,V2SF,V1DF" 329 (const_string "unknown")) 330 331;; The CPU unit operations uses. 332(define_attr "unit" "integer,i387,sse,mmx,unknown" 333 (cond [(eq_attr "type" "fmov,fop,fsgn,fmul,fdiv,fpspc,fcmov,fcmp,fxch,fistp,fisttp,frndint") 334 (const_string "i387") 335 (eq_attr "type" "sselog,sselog1,sseiadd,sseiadd1,sseishft,sseishft1,sseimul, 336 sse,ssemov,sseadd,ssemul,ssecmp,ssecomi,ssecvt, 337 ssecvt1,sseicvt,ssediv,sseins,ssemuladd,sse4arg") 338 (const_string "sse") 339 (eq_attr "type" "mmx,mmxmov,mmxadd,mmxmul,mmxcmp,mmxcvt,mmxshft") 340 (const_string "mmx") 341 (eq_attr "type" "other") 342 (const_string "unknown")] 343 (const_string "integer"))) 344 345;; The (bounding maximum) length of an instruction immediate. 346(define_attr "length_immediate" "" 347 (cond [(eq_attr "type" "incdec,setcc,icmov,str,lea,other,multi,idiv,leave, 348 bitmanip,imulx") 349 (const_int 0) 350 (eq_attr "unit" "i387,sse,mmx") 351 (const_int 0) 352 (eq_attr "type" "alu,alu1,negnot,imovx,ishift,ishiftx,ishift1, 353 rotate,rotatex,rotate1,imul,icmp,push,pop") 354 (symbol_ref "ix86_attr_length_immediate_default (insn, true)") 355 (eq_attr "type" "imov,test") 356 (symbol_ref "ix86_attr_length_immediate_default (insn, false)") 357 (eq_attr "type" "call") 358 (if_then_else (match_operand 0 "constant_call_address_operand" "") 359 (const_int 4) 360 (const_int 0)) 361 (eq_attr "type" "callv") 362 (if_then_else (match_operand 1 "constant_call_address_operand" "") 363 (const_int 4) 364 (const_int 0)) 365 ;; We don't know the size before shorten_branches. Expect 366 ;; the instruction to fit for better scheduling. 367 (eq_attr "type" "ibr") 368 (const_int 1) 369 ] 370 (symbol_ref "/* Update immediate_length and other attributes! */ 371 gcc_unreachable (),1"))) 372 373;; The (bounding maximum) length of an instruction address. 374(define_attr "length_address" "" 375 (cond [(eq_attr "type" "str,other,multi,fxch") 376 (const_int 0) 377 (and (eq_attr "type" "call") 378 (match_operand 0 "constant_call_address_operand" "")) 379 (const_int 0) 380 (and (eq_attr "type" "callv") 381 (match_operand 1 "constant_call_address_operand" "")) 382 (const_int 0) 383 ] 384 (symbol_ref "ix86_attr_length_address_default (insn)"))) 385 386;; Set when length prefix is used. 387(define_attr "prefix_data16" "" 388 (cond [(eq_attr "type" "ssemuladd,sse4arg,sseiadd1,ssecvt1") 389 (const_int 0) 390 (eq_attr "mode" "HI") 391 (const_int 1) 392 (and (eq_attr "unit" "sse") (eq_attr "mode" "V2DF,TI")) 393 (const_int 1) 394 ] 395 (const_int 0))) 396 397;; Set when string REP prefix is used. 398(define_attr "prefix_rep" "" 399 (cond [(eq_attr "type" "ssemuladd,sse4arg,sseiadd1,ssecvt1") 400 (const_int 0) 401 (and (eq_attr "unit" "sse") (eq_attr "mode" "SF,DF")) 402 (const_int 1) 403 ] 404 (const_int 0))) 405 406;; Set when 0f opcode prefix is used. 407(define_attr "prefix_0f" "" 408 (if_then_else 409 (ior (eq_attr "type" "imovx,setcc,icmov,bitmanip") 410 (eq_attr "unit" "sse,mmx")) 411 (const_int 1) 412 (const_int 0))) 413 414;; Set when REX opcode prefix is used. 415(define_attr "prefix_rex" "" 416 (cond [(not (match_test "TARGET_64BIT")) 417 (const_int 0) 418 (and (eq_attr "mode" "DI") 419 (and (eq_attr "type" "!push,pop,call,callv,leave,ibr") 420 (eq_attr "unit" "!mmx"))) 421 (const_int 1) 422 (and (eq_attr "mode" "QI") 423 (match_test "x86_extended_QIreg_mentioned_p (insn)")) 424 (const_int 1) 425 (match_test "x86_extended_reg_mentioned_p (insn)") 426 (const_int 1) 427 (and (eq_attr "type" "imovx") 428 (match_operand:QI 1 "ext_QIreg_operand" "")) 429 (const_int 1) 430 ] 431 (const_int 0))) 432 433;; There are also additional prefixes in 3DNOW, SSSE3. 434;; ssemuladd,sse4arg default to 0f24/0f25 and DREX byte, 435;; sseiadd1,ssecvt1 to 0f7a with no DREX byte. 436;; 3DNOW has 0f0f prefix, SSSE3 and SSE4_{1,2} 0f38/0f3a. 437(define_attr "prefix_extra" "" 438 (cond [(eq_attr "type" "ssemuladd,sse4arg") 439 (const_int 2) 440 (eq_attr "type" "sseiadd1,ssecvt1") 441 (const_int 1) 442 ] 443 (const_int 0))) 444 445;; Prefix used: original, VEX or maybe VEX. 446(define_attr "prefix" "orig,vex,maybe_vex" 447 (if_then_else (eq_attr "mode" "OI,V8SF,V4DF") 448 (const_string "vex") 449 (const_string "orig"))) 450 451;; VEX W bit is used. 452(define_attr "prefix_vex_w" "" (const_int 0)) 453 454;; The length of VEX prefix 455;; Only instructions with 0f prefix can have 2 byte VEX prefix, 456;; 0f38/0f3a prefixes can't. In i386.md 0f3[8a] is 457;; still prefix_0f 1, with prefix_extra 1. 458(define_attr "length_vex" "" 459 (if_then_else (and (eq_attr "prefix_0f" "1") 460 (eq_attr "prefix_extra" "0")) 461 (if_then_else (eq_attr "prefix_vex_w" "1") 462 (symbol_ref "ix86_attr_length_vex_default (insn, true, true)") 463 (symbol_ref "ix86_attr_length_vex_default (insn, true, false)")) 464 (if_then_else (eq_attr "prefix_vex_w" "1") 465 (symbol_ref "ix86_attr_length_vex_default (insn, false, true)") 466 (symbol_ref "ix86_attr_length_vex_default (insn, false, false)")))) 467 468;; Set when modrm byte is used. 469(define_attr "modrm" "" 470 (cond [(eq_attr "type" "str,leave") 471 (const_int 0) 472 (eq_attr "unit" "i387") 473 (const_int 0) 474 (and (eq_attr "type" "incdec") 475 (and (not (match_test "TARGET_64BIT")) 476 (ior (match_operand:SI 1 "register_operand" "") 477 (match_operand:HI 1 "register_operand" "")))) 478 (const_int 0) 479 (and (eq_attr "type" "push") 480 (not (match_operand 1 "memory_operand" ""))) 481 (const_int 0) 482 (and (eq_attr "type" "pop") 483 (not (match_operand 0 "memory_operand" ""))) 484 (const_int 0) 485 (and (eq_attr "type" "imov") 486 (and (not (eq_attr "mode" "DI")) 487 (ior (and (match_operand 0 "register_operand" "") 488 (match_operand 1 "immediate_operand" "")) 489 (ior (and (match_operand 0 "ax_reg_operand" "") 490 (match_operand 1 "memory_displacement_only_operand" "")) 491 (and (match_operand 0 "memory_displacement_only_operand" "") 492 (match_operand 1 "ax_reg_operand" "")))))) 493 (const_int 0) 494 (and (eq_attr "type" "call") 495 (match_operand 0 "constant_call_address_operand" "")) 496 (const_int 0) 497 (and (eq_attr "type" "callv") 498 (match_operand 1 "constant_call_address_operand" "")) 499 (const_int 0) 500 (and (eq_attr "type" "alu,alu1,icmp,test") 501 (match_operand 0 "ax_reg_operand" "")) 502 (symbol_ref "(get_attr_length_immediate (insn) <= (get_attr_mode (insn) != MODE_QI))") 503 ] 504 (const_int 1))) 505 506;; The (bounding maximum) length of an instruction in bytes. 507;; ??? fistp and frndint are in fact fldcw/{fistp,frndint}/fldcw sequences. 508;; Later we may want to split them and compute proper length as for 509;; other insns. 510(define_attr "length" "" 511 (cond [(eq_attr "type" "other,multi,fistp,frndint") 512 (const_int 16) 513 (eq_attr "type" "fcmp") 514 (const_int 4) 515 (eq_attr "unit" "i387") 516 (plus (const_int 2) 517 (plus (attr "prefix_data16") 518 (attr "length_address"))) 519 (ior (eq_attr "prefix" "vex") 520 (and (eq_attr "prefix" "maybe_vex") 521 (match_test "TARGET_AVX"))) 522 (plus (attr "length_vex") 523 (plus (attr "length_immediate") 524 (plus (attr "modrm") 525 (attr "length_address"))))] 526 (plus (plus (attr "modrm") 527 (plus (attr "prefix_0f") 528 (plus (attr "prefix_rex") 529 (plus (attr "prefix_extra") 530 (const_int 1))))) 531 (plus (attr "prefix_rep") 532 (plus (attr "prefix_data16") 533 (plus (attr "length_immediate") 534 (attr "length_address"))))))) 535 536;; The `memory' attribute is `none' if no memory is referenced, `load' or 537;; `store' if there is a simple memory reference therein, or `unknown' 538;; if the instruction is complex. 539 540(define_attr "memory" "none,load,store,both,unknown" 541 (cond [(eq_attr "type" "other,multi,str,lwp") 542 (const_string "unknown") 543 (eq_attr "type" "lea,fcmov,fpspc") 544 (const_string "none") 545 (eq_attr "type" "fistp,leave") 546 (const_string "both") 547 (eq_attr "type" "frndint") 548 (const_string "load") 549 (eq_attr "type" "push") 550 (if_then_else (match_operand 1 "memory_operand" "") 551 (const_string "both") 552 (const_string "store")) 553 (eq_attr "type" "pop") 554 (if_then_else (match_operand 0 "memory_operand" "") 555 (const_string "both") 556 (const_string "load")) 557 (eq_attr "type" "setcc") 558 (if_then_else (match_operand 0 "memory_operand" "") 559 (const_string "store") 560 (const_string "none")) 561 (eq_attr "type" "icmp,test,ssecmp,ssecomi,mmxcmp,fcmp") 562 (if_then_else (ior (match_operand 0 "memory_operand" "") 563 (match_operand 1 "memory_operand" "")) 564 (const_string "load") 565 (const_string "none")) 566 (eq_attr "type" "ibr") 567 (if_then_else (match_operand 0 "memory_operand" "") 568 (const_string "load") 569 (const_string "none")) 570 (eq_attr "type" "call") 571 (if_then_else (match_operand 0 "constant_call_address_operand" "") 572 (const_string "none") 573 (const_string "load")) 574 (eq_attr "type" "callv") 575 (if_then_else (match_operand 1 "constant_call_address_operand" "") 576 (const_string "none") 577 (const_string "load")) 578 (and (eq_attr "type" "alu1,negnot,ishift1,sselog1") 579 (match_operand 1 "memory_operand" "")) 580 (const_string "both") 581 (and (match_operand 0 "memory_operand" "") 582 (match_operand 1 "memory_operand" "")) 583 (const_string "both") 584 (match_operand 0 "memory_operand" "") 585 (const_string "store") 586 (match_operand 1 "memory_operand" "") 587 (const_string "load") 588 (and (eq_attr "type" 589 "!alu1,negnot,ishift1, 590 imov,imovx,icmp,test,bitmanip, 591 fmov,fcmp,fsgn, 592 sse,ssemov,ssecmp,ssecomi,ssecvt,ssecvt1,sseicvt,sselog1, 593 sseiadd1,mmx,mmxmov,mmxcmp,mmxcvt") 594 (match_operand 2 "memory_operand" "")) 595 (const_string "load") 596 (and (eq_attr "type" "icmov,ssemuladd,sse4arg") 597 (match_operand 3 "memory_operand" "")) 598 (const_string "load") 599 ] 600 (const_string "none"))) 601 602;; Indicates if an instruction has both an immediate and a displacement. 603 604(define_attr "imm_disp" "false,true,unknown" 605 (cond [(eq_attr "type" "other,multi") 606 (const_string "unknown") 607 (and (eq_attr "type" "icmp,test,imov,alu1,ishift1,rotate1") 608 (and (match_operand 0 "memory_displacement_operand" "") 609 (match_operand 1 "immediate_operand" ""))) 610 (const_string "true") 611 (and (eq_attr "type" "alu,ishift,ishiftx,rotate,rotatex,imul,idiv") 612 (and (match_operand 0 "memory_displacement_operand" "") 613 (match_operand 2 "immediate_operand" ""))) 614 (const_string "true") 615 ] 616 (const_string "false"))) 617 618;; Indicates if an FP operation has an integer source. 619 620(define_attr "fp_int_src" "false,true" 621 (const_string "false")) 622 623;; Defines rounding mode of an FP operation. 624 625(define_attr "i387_cw" "trunc,floor,ceil,mask_pm,uninitialized,any" 626 (const_string "any")) 627 628;; Define attribute to classify add/sub insns that consumes carry flag (CF) 629(define_attr "use_carry" "0,1" (const_string "0")) 630 631;; Define attribute to indicate unaligned ssemov insns 632(define_attr "movu" "0,1" (const_string "0")) 633 634;; Used to control the "enabled" attribute on a per-instruction basis. 635(define_attr "isa" "base,sse2,sse2_noavx,sse3,sse4,sse4_noavx,noavx,avx, 636 bmi2,fma4,fma" 637 (const_string "base")) 638 639(define_attr "enabled" "" 640 (cond [(eq_attr "isa" "sse2") (symbol_ref "TARGET_SSE2") 641 (eq_attr "isa" "sse2_noavx") 642 (symbol_ref "TARGET_SSE2 && !TARGET_AVX") 643 (eq_attr "isa" "sse3") (symbol_ref "TARGET_SSE3") 644 (eq_attr "isa" "sse4") (symbol_ref "TARGET_SSE4_1") 645 (eq_attr "isa" "sse4_noavx") 646 (symbol_ref "TARGET_SSE4_1 && !TARGET_AVX") 647 (eq_attr "isa" "avx") (symbol_ref "TARGET_AVX") 648 (eq_attr "isa" "noavx") (symbol_ref "!TARGET_AVX") 649 (eq_attr "isa" "bmi2") (symbol_ref "TARGET_BMI2") 650 (eq_attr "isa" "fma4") (symbol_ref "TARGET_FMA4") 651 (eq_attr "isa" "fma") (symbol_ref "TARGET_FMA") 652 ] 653 (const_int 1))) 654 655;; Describe a user's asm statement. 656(define_asm_attributes 657 [(set_attr "length" "128") 658 (set_attr "type" "multi")]) 659 660(define_code_iterator plusminus [plus minus]) 661 662(define_code_iterator sat_plusminus [ss_plus us_plus ss_minus us_minus]) 663 664;; Base name for define_insn 665(define_code_attr plusminus_insn 666 [(plus "add") (ss_plus "ssadd") (us_plus "usadd") 667 (minus "sub") (ss_minus "sssub") (us_minus "ussub")]) 668 669;; Base name for insn mnemonic. 670(define_code_attr plusminus_mnemonic 671 [(plus "add") (ss_plus "adds") (us_plus "addus") 672 (minus "sub") (ss_minus "subs") (us_minus "subus")]) 673(define_code_attr plusminus_carry_mnemonic 674 [(plus "adc") (minus "sbb")]) 675 676;; Mark commutative operators as such in constraints. 677(define_code_attr comm [(plus "%") (ss_plus "%") (us_plus "%") 678 (minus "") (ss_minus "") (us_minus "")]) 679 680;; Mapping of max and min 681(define_code_iterator maxmin [smax smin umax umin]) 682 683;; Mapping of signed max and min 684(define_code_iterator smaxmin [smax smin]) 685 686;; Mapping of unsigned max and min 687(define_code_iterator umaxmin [umax umin]) 688 689;; Base name for integer and FP insn mnemonic 690(define_code_attr maxmin_int [(smax "maxs") (smin "mins") 691 (umax "maxu") (umin "minu")]) 692(define_code_attr maxmin_float [(smax "max") (smin "min")]) 693 694;; Mapping of logic operators 695(define_code_iterator any_logic [and ior xor]) 696(define_code_iterator any_or [ior xor]) 697 698;; Base name for insn mnemonic. 699(define_code_attr logic [(and "and") (ior "or") (xor "xor")]) 700 701;; Mapping of logic-shift operators 702(define_code_iterator any_lshift [ashift lshiftrt]) 703 704;; Mapping of shift-right operators 705(define_code_iterator any_shiftrt [lshiftrt ashiftrt]) 706 707;; Base name for define_insn 708(define_code_attr shift_insn 709 [(ashift "ashl") (lshiftrt "lshr") (ashiftrt "ashr")]) 710 711;; Base name for insn mnemonic. 712(define_code_attr shift [(ashift "sll") (lshiftrt "shr") (ashiftrt "sar")]) 713(define_code_attr vshift [(ashift "sll") (lshiftrt "srl") (ashiftrt "sra")]) 714 715;; Mapping of rotate operators 716(define_code_iterator any_rotate [rotate rotatert]) 717 718;; Base name for define_insn 719(define_code_attr rotate_insn [(rotate "rotl") (rotatert "rotr")]) 720 721;; Base name for insn mnemonic. 722(define_code_attr rotate [(rotate "rol") (rotatert "ror")]) 723 724;; Mapping of abs neg operators 725(define_code_iterator absneg [abs neg]) 726 727;; Base name for x87 insn mnemonic. 728(define_code_attr absneg_mnemonic [(abs "abs") (neg "chs")]) 729 730;; Used in signed and unsigned widening multiplications. 731(define_code_iterator any_extend [sign_extend zero_extend]) 732 733;; Prefix for insn menmonic. 734(define_code_attr sgnprefix [(sign_extend "i") (zero_extend "")]) 735 736;; Prefix for define_insn 737(define_code_attr u [(sign_extend "") (zero_extend "u")]) 738(define_code_attr s [(sign_extend "s") (zero_extend "u")]) 739 740;; All integer modes. 741(define_mode_iterator SWI1248x [QI HI SI DI]) 742 743;; All integer modes without QImode. 744(define_mode_iterator SWI248x [HI SI DI]) 745 746;; All integer modes without QImode and HImode. 747(define_mode_iterator SWI48x [SI DI]) 748 749;; All integer modes without SImode and DImode. 750(define_mode_iterator SWI12 [QI HI]) 751 752;; All integer modes without DImode. 753(define_mode_iterator SWI124 [QI HI SI]) 754 755;; All integer modes without QImode and DImode. 756(define_mode_iterator SWI24 [HI SI]) 757 758;; Single word integer modes. 759(define_mode_iterator SWI [QI HI SI (DI "TARGET_64BIT")]) 760 761;; Single word integer modes without QImode. 762(define_mode_iterator SWI248 [HI SI (DI "TARGET_64BIT")]) 763 764;; Single word integer modes without QImode and HImode. 765(define_mode_iterator SWI48 [SI (DI "TARGET_64BIT")]) 766 767;; All math-dependant single and double word integer modes. 768(define_mode_iterator SDWIM [(QI "TARGET_QIMODE_MATH") 769 (HI "TARGET_HIMODE_MATH") 770 SI DI (TI "TARGET_64BIT")]) 771 772;; Math-dependant single word integer modes. 773(define_mode_iterator SWIM [(QI "TARGET_QIMODE_MATH") 774 (HI "TARGET_HIMODE_MATH") 775 SI (DI "TARGET_64BIT")]) 776 777;; Math-dependant integer modes without DImode. 778(define_mode_iterator SWIM124 [(QI "TARGET_QIMODE_MATH") 779 (HI "TARGET_HIMODE_MATH") 780 SI]) 781 782;; Math-dependant single word integer modes without QImode. 783(define_mode_iterator SWIM248 [(HI "TARGET_HIMODE_MATH") 784 SI (DI "TARGET_64BIT")]) 785 786;; Double word integer modes. 787(define_mode_iterator DWI [(DI "!TARGET_64BIT") 788 (TI "TARGET_64BIT")]) 789 790;; Double word integer modes as mode attribute. 791(define_mode_attr DWI [(SI "DI") (DI "TI")]) 792(define_mode_attr dwi [(SI "di") (DI "ti")]) 793 794;; Half mode for double word integer modes. 795(define_mode_iterator DWIH [(SI "!TARGET_64BIT") 796 (DI "TARGET_64BIT")]) 797 798;; Instruction suffix for integer modes. 799(define_mode_attr imodesuffix [(QI "b") (HI "w") (SI "l") (DI "q")]) 800 801;; Pointer size prefix for integer modes (Intel asm dialect) 802(define_mode_attr iptrsize [(QI "BYTE") 803 (HI "WORD") 804 (SI "DWORD") 805 (DI "QWORD")]) 806 807;; Register class for integer modes. 808(define_mode_attr r [(QI "q") (HI "r") (SI "r") (DI "r")]) 809 810;; Immediate operand constraint for integer modes. 811(define_mode_attr i [(QI "n") (HI "n") (SI "e") (DI "e")]) 812 813;; General operand constraint for word modes. 814(define_mode_attr g [(QI "qmn") (HI "rmn") (SI "rme") (DI "rme")]) 815 816;; Immediate operand constraint for double integer modes. 817(define_mode_attr di [(SI "nF") (DI "e")]) 818 819;; Immediate operand constraint for shifts. 820(define_mode_attr S [(QI "I") (HI "I") (SI "I") (DI "J") (TI "O")]) 821 822;; General operand predicate for integer modes. 823(define_mode_attr general_operand 824 [(QI "general_operand") 825 (HI "general_operand") 826 (SI "x86_64_general_operand") 827 (DI "x86_64_general_operand") 828 (TI "x86_64_general_operand")]) 829 830;; General sign/zero extend operand predicate for integer modes. 831(define_mode_attr general_szext_operand 832 [(QI "general_operand") 833 (HI "general_operand") 834 (SI "x86_64_szext_general_operand") 835 (DI "x86_64_szext_general_operand")]) 836 837;; Immediate operand predicate for integer modes. 838(define_mode_attr immediate_operand 839 [(QI "immediate_operand") 840 (HI "immediate_operand") 841 (SI "x86_64_immediate_operand") 842 (DI "x86_64_immediate_operand")]) 843 844;; Nonmemory operand predicate for integer modes. 845(define_mode_attr nonmemory_operand 846 [(QI "nonmemory_operand") 847 (HI "nonmemory_operand") 848 (SI "x86_64_nonmemory_operand") 849 (DI "x86_64_nonmemory_operand")]) 850 851;; Operand predicate for shifts. 852(define_mode_attr shift_operand 853 [(QI "nonimmediate_operand") 854 (HI "nonimmediate_operand") 855 (SI "nonimmediate_operand") 856 (DI "shiftdi_operand") 857 (TI "register_operand")]) 858 859;; Operand predicate for shift argument. 860(define_mode_attr shift_immediate_operand 861 [(QI "const_1_to_31_operand") 862 (HI "const_1_to_31_operand") 863 (SI "const_1_to_31_operand") 864 (DI "const_1_to_63_operand")]) 865 866;; Input operand predicate for arithmetic left shifts. 867(define_mode_attr ashl_input_operand 868 [(QI "nonimmediate_operand") 869 (HI "nonimmediate_operand") 870 (SI "nonimmediate_operand") 871 (DI "ashldi_input_operand") 872 (TI "reg_or_pm1_operand")]) 873 874;; SSE and x87 SFmode and DFmode floating point modes 875(define_mode_iterator MODEF [SF DF]) 876 877;; All x87 floating point modes 878(define_mode_iterator X87MODEF [SF DF XF]) 879 880;; SSE instruction suffix for various modes 881(define_mode_attr ssemodesuffix 882 [(SF "ss") (DF "sd") 883 (V8SF "ps") (V4DF "pd") 884 (V4SF "ps") (V2DF "pd") 885 (V16QI "b") (V8HI "w") (V4SI "d") (V2DI "q") 886 (V32QI "b") (V16HI "w") (V8SI "d") (V4DI "q")]) 887 888;; SSE vector suffix for floating point modes 889(define_mode_attr ssevecmodesuffix [(SF "ps") (DF "pd")]) 890 891;; SSE vector mode corresponding to a scalar mode 892(define_mode_attr ssevecmode 893 [(QI "V16QI") (HI "V8HI") (SI "V4SI") (DI "V2DI") (SF "V4SF") (DF "V2DF")]) 894 895;; Instruction suffix for REX 64bit operators. 896(define_mode_attr rex64suffix [(SI "") (DI "{q}")]) 897 898;; This mode iterator allows :P to be used for patterns that operate on 899;; pointer-sized quantities. Exactly one of the two alternatives will match. 900(define_mode_iterator P [(SI "Pmode == SImode") (DI "Pmode == DImode")]) 901 902;; This mode iterator allows :PTR to be used for patterns that operate on 903;; ptr_mode sized quantities. 904(define_mode_iterator PTR 905 [(SI "ptr_mode == SImode") (DI "ptr_mode == DImode")]) 906 907;; Scheduling descriptions 908 909(include "pentium.md") 910(include "ppro.md") 911(include "k6.md") 912(include "athlon.md") 913(include "bdver1.md") 914(include "geode.md") 915(include "atom.md") 916(include "core2.md") 917 918 919;; Operand and operator predicates and constraints 920 921(include "predicates.md") 922(include "constraints.md") 923 924 925;; Compare and branch/compare and store instructions. 926 927(define_expand "cbranch<mode>4" 928 [(set (reg:CC FLAGS_REG) 929 (compare:CC (match_operand:SDWIM 1 "nonimmediate_operand" "") 930 (match_operand:SDWIM 2 "<general_operand>" ""))) 931 (set (pc) (if_then_else 932 (match_operator 0 "ordered_comparison_operator" 933 [(reg:CC FLAGS_REG) (const_int 0)]) 934 (label_ref (match_operand 3 "" "")) 935 (pc)))] 936 "" 937{ 938 if (MEM_P (operands[1]) && MEM_P (operands[2])) 939 operands[1] = force_reg (<MODE>mode, operands[1]); 940 ix86_expand_branch (GET_CODE (operands[0]), 941 operands[1], operands[2], operands[3]); 942 DONE; 943}) 944 945(define_expand "cstore<mode>4" 946 [(set (reg:CC FLAGS_REG) 947 (compare:CC (match_operand:SWIM 2 "nonimmediate_operand" "") 948 (match_operand:SWIM 3 "<general_operand>" ""))) 949 (set (match_operand:QI 0 "register_operand" "") 950 (match_operator 1 "ordered_comparison_operator" 951 [(reg:CC FLAGS_REG) (const_int 0)]))] 952 "" 953{ 954 if (MEM_P (operands[2]) && MEM_P (operands[3])) 955 operands[2] = force_reg (<MODE>mode, operands[2]); 956 ix86_expand_setcc (operands[0], GET_CODE (operands[1]), 957 operands[2], operands[3]); 958 DONE; 959}) 960 961(define_expand "cmp<mode>_1" 962 [(set (reg:CC FLAGS_REG) 963 (compare:CC (match_operand:SWI48 0 "nonimmediate_operand" "") 964 (match_operand:SWI48 1 "<general_operand>" "")))]) 965 966(define_insn "*cmp<mode>_ccno_1" 967 [(set (reg FLAGS_REG) 968 (compare (match_operand:SWI 0 "nonimmediate_operand" "<r>,?m<r>") 969 (match_operand:SWI 1 "const0_operand" "")))] 970 "ix86_match_ccmode (insn, CCNOmode)" 971 "@ 972 test{<imodesuffix>}\t%0, %0 973 cmp{<imodesuffix>}\t{%1, %0|%0, %1}" 974 [(set_attr "type" "test,icmp") 975 (set_attr "length_immediate" "0,1") 976 (set_attr "mode" "<MODE>")]) 977 978(define_insn "*cmp<mode>_1" 979 [(set (reg FLAGS_REG) 980 (compare (match_operand:SWI 0 "nonimmediate_operand" "<r>m,<r>") 981 (match_operand:SWI 1 "<general_operand>" "<r><i>,<r>m")))] 982 "ix86_match_ccmode (insn, CCmode)" 983 "cmp{<imodesuffix>}\t{%1, %0|%0, %1}" 984 [(set_attr "type" "icmp") 985 (set_attr "mode" "<MODE>")]) 986 987(define_insn "*cmp<mode>_minus_1" 988 [(set (reg FLAGS_REG) 989 (compare 990 (minus:SWI (match_operand:SWI 0 "nonimmediate_operand" "<r>m,<r>") 991 (match_operand:SWI 1 "<general_operand>" "<r><i>,<r>m")) 992 (const_int 0)))] 993 "ix86_match_ccmode (insn, CCGOCmode)" 994 "cmp{<imodesuffix>}\t{%1, %0|%0, %1}" 995 [(set_attr "type" "icmp") 996 (set_attr "mode" "<MODE>")]) 997 998(define_insn "*cmpqi_ext_1" 999 [(set (reg FLAGS_REG) 1000 (compare 1001 (match_operand:QI 0 "general_operand" "Qm") 1002 (subreg:QI 1003 (zero_extract:SI 1004 (match_operand 1 "ext_register_operand" "Q") 1005 (const_int 8) 1006 (const_int 8)) 0)))] 1007 "!TARGET_64BIT && ix86_match_ccmode (insn, CCmode)" 1008 "cmp{b}\t{%h1, %0|%0, %h1}" 1009 [(set_attr "type" "icmp") 1010 (set_attr "mode" "QI")]) 1011 1012(define_insn "*cmpqi_ext_1_rex64" 1013 [(set (reg FLAGS_REG) 1014 (compare 1015 (match_operand:QI 0 "register_operand" "Q") 1016 (subreg:QI 1017 (zero_extract:SI 1018 (match_operand 1 "ext_register_operand" "Q") 1019 (const_int 8) 1020 (const_int 8)) 0)))] 1021 "TARGET_64BIT && ix86_match_ccmode (insn, CCmode)" 1022 "cmp{b}\t{%h1, %0|%0, %h1}" 1023 [(set_attr "type" "icmp") 1024 (set_attr "mode" "QI")]) 1025 1026(define_insn "*cmpqi_ext_2" 1027 [(set (reg FLAGS_REG) 1028 (compare 1029 (subreg:QI 1030 (zero_extract:SI 1031 (match_operand 0 "ext_register_operand" "Q") 1032 (const_int 8) 1033 (const_int 8)) 0) 1034 (match_operand:QI 1 "const0_operand" "")))] 1035 "ix86_match_ccmode (insn, CCNOmode)" 1036 "test{b}\t%h0, %h0" 1037 [(set_attr "type" "test") 1038 (set_attr "length_immediate" "0") 1039 (set_attr "mode" "QI")]) 1040 1041(define_expand "cmpqi_ext_3" 1042 [(set (reg:CC FLAGS_REG) 1043 (compare:CC 1044 (subreg:QI 1045 (zero_extract:SI 1046 (match_operand 0 "ext_register_operand" "") 1047 (const_int 8) 1048 (const_int 8)) 0) 1049 (match_operand:QI 1 "immediate_operand" "")))]) 1050 1051(define_insn "*cmpqi_ext_3_insn" 1052 [(set (reg FLAGS_REG) 1053 (compare 1054 (subreg:QI 1055 (zero_extract:SI 1056 (match_operand 0 "ext_register_operand" "Q") 1057 (const_int 8) 1058 (const_int 8)) 0) 1059 (match_operand:QI 1 "general_operand" "Qmn")))] 1060 "!TARGET_64BIT && ix86_match_ccmode (insn, CCmode)" 1061 "cmp{b}\t{%1, %h0|%h0, %1}" 1062 [(set_attr "type" "icmp") 1063 (set_attr "modrm" "1") 1064 (set_attr "mode" "QI")]) 1065 1066(define_insn "*cmpqi_ext_3_insn_rex64" 1067 [(set (reg FLAGS_REG) 1068 (compare 1069 (subreg:QI 1070 (zero_extract:SI 1071 (match_operand 0 "ext_register_operand" "Q") 1072 (const_int 8) 1073 (const_int 8)) 0) 1074 (match_operand:QI 1 "nonmemory_operand" "Qn")))] 1075 "TARGET_64BIT && ix86_match_ccmode (insn, CCmode)" 1076 "cmp{b}\t{%1, %h0|%h0, %1}" 1077 [(set_attr "type" "icmp") 1078 (set_attr "modrm" "1") 1079 (set_attr "mode" "QI")]) 1080 1081(define_insn "*cmpqi_ext_4" 1082 [(set (reg FLAGS_REG) 1083 (compare 1084 (subreg:QI 1085 (zero_extract:SI 1086 (match_operand 0 "ext_register_operand" "Q") 1087 (const_int 8) 1088 (const_int 8)) 0) 1089 (subreg:QI 1090 (zero_extract:SI 1091 (match_operand 1 "ext_register_operand" "Q") 1092 (const_int 8) 1093 (const_int 8)) 0)))] 1094 "ix86_match_ccmode (insn, CCmode)" 1095 "cmp{b}\t{%h1, %h0|%h0, %h1}" 1096 [(set_attr "type" "icmp") 1097 (set_attr "mode" "QI")]) 1098 1099;; These implement float point compares. 1100;; %%% See if we can get away with VOIDmode operands on the actual insns, 1101;; which would allow mix and match FP modes on the compares. Which is what 1102;; the old patterns did, but with many more of them. 1103 1104(define_expand "cbranchxf4" 1105 [(set (reg:CC FLAGS_REG) 1106 (compare:CC (match_operand:XF 1 "nonmemory_operand" "") 1107 (match_operand:XF 2 "nonmemory_operand" ""))) 1108 (set (pc) (if_then_else 1109 (match_operator 0 "ix86_fp_comparison_operator" 1110 [(reg:CC FLAGS_REG) 1111 (const_int 0)]) 1112 (label_ref (match_operand 3 "" "")) 1113 (pc)))] 1114 "TARGET_80387" 1115{ 1116 ix86_expand_branch (GET_CODE (operands[0]), 1117 operands[1], operands[2], operands[3]); 1118 DONE; 1119}) 1120 1121(define_expand "cstorexf4" 1122 [(set (reg:CC FLAGS_REG) 1123 (compare:CC (match_operand:XF 2 "nonmemory_operand" "") 1124 (match_operand:XF 3 "nonmemory_operand" ""))) 1125 (set (match_operand:QI 0 "register_operand" "") 1126 (match_operator 1 "ix86_fp_comparison_operator" 1127 [(reg:CC FLAGS_REG) 1128 (const_int 0)]))] 1129 "TARGET_80387" 1130{ 1131 ix86_expand_setcc (operands[0], GET_CODE (operands[1]), 1132 operands[2], operands[3]); 1133 DONE; 1134}) 1135 1136(define_expand "cbranch<mode>4" 1137 [(set (reg:CC FLAGS_REG) 1138 (compare:CC (match_operand:MODEF 1 "cmp_fp_expander_operand" "") 1139 (match_operand:MODEF 2 "cmp_fp_expander_operand" ""))) 1140 (set (pc) (if_then_else 1141 (match_operator 0 "ix86_fp_comparison_operator" 1142 [(reg:CC FLAGS_REG) 1143 (const_int 0)]) 1144 (label_ref (match_operand 3 "" "")) 1145 (pc)))] 1146 "TARGET_80387 || (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)" 1147{ 1148 ix86_expand_branch (GET_CODE (operands[0]), 1149 operands[1], operands[2], operands[3]); 1150 DONE; 1151}) 1152 1153(define_expand "cstore<mode>4" 1154 [(set (reg:CC FLAGS_REG) 1155 (compare:CC (match_operand:MODEF 2 "cmp_fp_expander_operand" "") 1156 (match_operand:MODEF 3 "cmp_fp_expander_operand" ""))) 1157 (set (match_operand:QI 0 "register_operand" "") 1158 (match_operator 1 "ix86_fp_comparison_operator" 1159 [(reg:CC FLAGS_REG) 1160 (const_int 0)]))] 1161 "TARGET_80387 || (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)" 1162{ 1163 ix86_expand_setcc (operands[0], GET_CODE (operands[1]), 1164 operands[2], operands[3]); 1165 DONE; 1166}) 1167 1168(define_expand "cbranchcc4" 1169 [(set (pc) (if_then_else 1170 (match_operator 0 "comparison_operator" 1171 [(match_operand 1 "flags_reg_operand" "") 1172 (match_operand 2 "const0_operand" "")]) 1173 (label_ref (match_operand 3 "" "")) 1174 (pc)))] 1175 "" 1176{ 1177 ix86_expand_branch (GET_CODE (operands[0]), 1178 operands[1], operands[2], operands[3]); 1179 DONE; 1180}) 1181 1182(define_expand "cstorecc4" 1183 [(set (match_operand:QI 0 "register_operand" "") 1184 (match_operator 1 "comparison_operator" 1185 [(match_operand 2 "flags_reg_operand" "") 1186 (match_operand 3 "const0_operand" "")]))] 1187 "" 1188{ 1189 ix86_expand_setcc (operands[0], GET_CODE (operands[1]), 1190 operands[2], operands[3]); 1191 DONE; 1192}) 1193 1194 1195;; FP compares, step 1: 1196;; Set the FP condition codes. 1197;; 1198;; CCFPmode compare with exceptions 1199;; CCFPUmode compare with no exceptions 1200 1201;; We may not use "#" to split and emit these, since the REG_DEAD notes 1202;; used to manage the reg stack popping would not be preserved. 1203 1204(define_insn "*cmpfp_0" 1205 [(set (match_operand:HI 0 "register_operand" "=a") 1206 (unspec:HI 1207 [(compare:CCFP 1208 (match_operand 1 "register_operand" "f") 1209 (match_operand 2 "const0_operand" ""))] 1210 UNSPEC_FNSTSW))] 1211 "X87_FLOAT_MODE_P (GET_MODE (operands[1])) 1212 && GET_MODE (operands[1]) == GET_MODE (operands[2])" 1213 "* return output_fp_compare (insn, operands, false, false);" 1214 [(set_attr "type" "multi") 1215 (set_attr "unit" "i387") 1216 (set (attr "mode") 1217 (cond [(match_operand:SF 1 "" "") 1218 (const_string "SF") 1219 (match_operand:DF 1 "" "") 1220 (const_string "DF") 1221 ] 1222 (const_string "XF")))]) 1223 1224(define_insn_and_split "*cmpfp_0_cc" 1225 [(set (reg:CCFP FLAGS_REG) 1226 (compare:CCFP 1227 (match_operand 1 "register_operand" "f") 1228 (match_operand 2 "const0_operand" ""))) 1229 (clobber (match_operand:HI 0 "register_operand" "=a"))] 1230 "X87_FLOAT_MODE_P (GET_MODE (operands[1])) 1231 && TARGET_SAHF && !TARGET_CMOVE 1232 && GET_MODE (operands[1]) == GET_MODE (operands[2])" 1233 "#" 1234 "&& reload_completed" 1235 [(set (match_dup 0) 1236 (unspec:HI 1237 [(compare:CCFP (match_dup 1)(match_dup 2))] 1238 UNSPEC_FNSTSW)) 1239 (set (reg:CC FLAGS_REG) 1240 (unspec:CC [(match_dup 0)] UNSPEC_SAHF))] 1241 "" 1242 [(set_attr "type" "multi") 1243 (set_attr "unit" "i387") 1244 (set (attr "mode") 1245 (cond [(match_operand:SF 1 "" "") 1246 (const_string "SF") 1247 (match_operand:DF 1 "" "") 1248 (const_string "DF") 1249 ] 1250 (const_string "XF")))]) 1251 1252(define_insn "*cmpfp_xf" 1253 [(set (match_operand:HI 0 "register_operand" "=a") 1254 (unspec:HI 1255 [(compare:CCFP 1256 (match_operand:XF 1 "register_operand" "f") 1257 (match_operand:XF 2 "register_operand" "f"))] 1258 UNSPEC_FNSTSW))] 1259 "TARGET_80387" 1260 "* return output_fp_compare (insn, operands, false, false);" 1261 [(set_attr "type" "multi") 1262 (set_attr "unit" "i387") 1263 (set_attr "mode" "XF")]) 1264 1265(define_insn_and_split "*cmpfp_xf_cc" 1266 [(set (reg:CCFP FLAGS_REG) 1267 (compare:CCFP 1268 (match_operand:XF 1 "register_operand" "f") 1269 (match_operand:XF 2 "register_operand" "f"))) 1270 (clobber (match_operand:HI 0 "register_operand" "=a"))] 1271 "TARGET_80387 1272 && TARGET_SAHF && !TARGET_CMOVE" 1273 "#" 1274 "&& reload_completed" 1275 [(set (match_dup 0) 1276 (unspec:HI 1277 [(compare:CCFP (match_dup 1)(match_dup 2))] 1278 UNSPEC_FNSTSW)) 1279 (set (reg:CC FLAGS_REG) 1280 (unspec:CC [(match_dup 0)] UNSPEC_SAHF))] 1281 "" 1282 [(set_attr "type" "multi") 1283 (set_attr "unit" "i387") 1284 (set_attr "mode" "XF")]) 1285 1286(define_insn "*cmpfp_<mode>" 1287 [(set (match_operand:HI 0 "register_operand" "=a") 1288 (unspec:HI 1289 [(compare:CCFP 1290 (match_operand:MODEF 1 "register_operand" "f") 1291 (match_operand:MODEF 2 "nonimmediate_operand" "fm"))] 1292 UNSPEC_FNSTSW))] 1293 "TARGET_80387" 1294 "* return output_fp_compare (insn, operands, false, false);" 1295 [(set_attr "type" "multi") 1296 (set_attr "unit" "i387") 1297 (set_attr "mode" "<MODE>")]) 1298 1299(define_insn_and_split "*cmpfp_<mode>_cc" 1300 [(set (reg:CCFP FLAGS_REG) 1301 (compare:CCFP 1302 (match_operand:MODEF 1 "register_operand" "f") 1303 (match_operand:MODEF 2 "nonimmediate_operand" "fm"))) 1304 (clobber (match_operand:HI 0 "register_operand" "=a"))] 1305 "TARGET_80387 1306 && TARGET_SAHF && !TARGET_CMOVE" 1307 "#" 1308 "&& reload_completed" 1309 [(set (match_dup 0) 1310 (unspec:HI 1311 [(compare:CCFP (match_dup 1)(match_dup 2))] 1312 UNSPEC_FNSTSW)) 1313 (set (reg:CC FLAGS_REG) 1314 (unspec:CC [(match_dup 0)] UNSPEC_SAHF))] 1315 "" 1316 [(set_attr "type" "multi") 1317 (set_attr "unit" "i387") 1318 (set_attr "mode" "<MODE>")]) 1319 1320(define_insn "*cmpfp_u" 1321 [(set (match_operand:HI 0 "register_operand" "=a") 1322 (unspec:HI 1323 [(compare:CCFPU 1324 (match_operand 1 "register_operand" "f") 1325 (match_operand 2 "register_operand" "f"))] 1326 UNSPEC_FNSTSW))] 1327 "X87_FLOAT_MODE_P (GET_MODE (operands[1])) 1328 && GET_MODE (operands[1]) == GET_MODE (operands[2])" 1329 "* return output_fp_compare (insn, operands, false, true);" 1330 [(set_attr "type" "multi") 1331 (set_attr "unit" "i387") 1332 (set (attr "mode") 1333 (cond [(match_operand:SF 1 "" "") 1334 (const_string "SF") 1335 (match_operand:DF 1 "" "") 1336 (const_string "DF") 1337 ] 1338 (const_string "XF")))]) 1339 1340(define_insn_and_split "*cmpfp_u_cc" 1341 [(set (reg:CCFPU FLAGS_REG) 1342 (compare:CCFPU 1343 (match_operand 1 "register_operand" "f") 1344 (match_operand 2 "register_operand" "f"))) 1345 (clobber (match_operand:HI 0 "register_operand" "=a"))] 1346 "X87_FLOAT_MODE_P (GET_MODE (operands[1])) 1347 && TARGET_SAHF && !TARGET_CMOVE 1348 && GET_MODE (operands[1]) == GET_MODE (operands[2])" 1349 "#" 1350 "&& reload_completed" 1351 [(set (match_dup 0) 1352 (unspec:HI 1353 [(compare:CCFPU (match_dup 1)(match_dup 2))] 1354 UNSPEC_FNSTSW)) 1355 (set (reg:CC FLAGS_REG) 1356 (unspec:CC [(match_dup 0)] UNSPEC_SAHF))] 1357 "" 1358 [(set_attr "type" "multi") 1359 (set_attr "unit" "i387") 1360 (set (attr "mode") 1361 (cond [(match_operand:SF 1 "" "") 1362 (const_string "SF") 1363 (match_operand:DF 1 "" "") 1364 (const_string "DF") 1365 ] 1366 (const_string "XF")))]) 1367 1368(define_insn "*cmpfp_<mode>" 1369 [(set (match_operand:HI 0 "register_operand" "=a") 1370 (unspec:HI 1371 [(compare:CCFP 1372 (match_operand 1 "register_operand" "f") 1373 (match_operator 3 "float_operator" 1374 [(match_operand:SWI24 2 "memory_operand" "m")]))] 1375 UNSPEC_FNSTSW))] 1376 "X87_FLOAT_MODE_P (GET_MODE (operands[1])) 1377 && (TARGET_USE_<MODE>MODE_FIOP || optimize_function_for_size_p (cfun)) 1378 && (GET_MODE (operands [3]) == GET_MODE (operands[1]))" 1379 "* return output_fp_compare (insn, operands, false, false);" 1380 [(set_attr "type" "multi") 1381 (set_attr "unit" "i387") 1382 (set_attr "fp_int_src" "true") 1383 (set_attr "mode" "<MODE>")]) 1384 1385(define_insn_and_split "*cmpfp_<mode>_cc" 1386 [(set (reg:CCFP FLAGS_REG) 1387 (compare:CCFP 1388 (match_operand 1 "register_operand" "f") 1389 (match_operator 3 "float_operator" 1390 [(match_operand:SWI24 2 "memory_operand" "m")]))) 1391 (clobber (match_operand:HI 0 "register_operand" "=a"))] 1392 "X87_FLOAT_MODE_P (GET_MODE (operands[1])) 1393 && TARGET_SAHF && !TARGET_CMOVE 1394 && (TARGET_USE_<MODE>MODE_FIOP || optimize_function_for_size_p (cfun)) 1395 && (GET_MODE (operands [3]) == GET_MODE (operands[1]))" 1396 "#" 1397 "&& reload_completed" 1398 [(set (match_dup 0) 1399 (unspec:HI 1400 [(compare:CCFP 1401 (match_dup 1) 1402 (match_op_dup 3 [(match_dup 2)]))] 1403 UNSPEC_FNSTSW)) 1404 (set (reg:CC FLAGS_REG) 1405 (unspec:CC [(match_dup 0)] UNSPEC_SAHF))] 1406 "" 1407 [(set_attr "type" "multi") 1408 (set_attr "unit" "i387") 1409 (set_attr "fp_int_src" "true") 1410 (set_attr "mode" "<MODE>")]) 1411 1412;; FP compares, step 2 1413;; Move the fpsw to ax. 1414 1415(define_insn "x86_fnstsw_1" 1416 [(set (match_operand:HI 0 "register_operand" "=a") 1417 (unspec:HI [(reg:CCFP FPSR_REG)] UNSPEC_FNSTSW))] 1418 "TARGET_80387" 1419 "fnstsw\t%0" 1420 [(set (attr "length") 1421 (symbol_ref "ix86_attr_length_address_default (insn) + 2")) 1422 (set_attr "mode" "SI") 1423 (set_attr "unit" "i387")]) 1424 1425;; FP compares, step 3 1426;; Get ax into flags, general case. 1427 1428(define_insn "x86_sahf_1" 1429 [(set (reg:CC FLAGS_REG) 1430 (unspec:CC [(match_operand:HI 0 "register_operand" "a")] 1431 UNSPEC_SAHF))] 1432 "TARGET_SAHF" 1433{ 1434#ifndef HAVE_AS_IX86_SAHF 1435 if (TARGET_64BIT) 1436 return ASM_BYTE "0x9e"; 1437 else 1438#endif 1439 return "sahf"; 1440} 1441 [(set_attr "length" "1") 1442 (set_attr "athlon_decode" "vector") 1443 (set_attr "amdfam10_decode" "direct") 1444 (set_attr "bdver1_decode" "direct") 1445 (set_attr "mode" "SI")]) 1446 1447;; Pentium Pro can do steps 1 through 3 in one go. 1448;; comi*, ucomi*, fcomi*, ficomi*, fucomi* 1449;; (these i387 instructions set flags directly) 1450(define_insn "*cmpfp_i_mixed" 1451 [(set (reg:CCFP FLAGS_REG) 1452 (compare:CCFP (match_operand 0 "register_operand" "f,x") 1453 (match_operand 1 "nonimmediate_operand" "f,xm")))] 1454 "TARGET_MIX_SSE_I387 1455 && SSE_FLOAT_MODE_P (GET_MODE (operands[0])) 1456 && GET_MODE (operands[0]) == GET_MODE (operands[1])" 1457 "* return output_fp_compare (insn, operands, true, false);" 1458 [(set_attr "type" "fcmp,ssecomi") 1459 (set_attr "prefix" "orig,maybe_vex") 1460 (set (attr "mode") 1461 (if_then_else (match_operand:SF 1 "" "") 1462 (const_string "SF") 1463 (const_string "DF"))) 1464 (set (attr "prefix_rep") 1465 (if_then_else (eq_attr "type" "ssecomi") 1466 (const_string "0") 1467 (const_string "*"))) 1468 (set (attr "prefix_data16") 1469 (cond [(eq_attr "type" "fcmp") 1470 (const_string "*") 1471 (eq_attr "mode" "DF") 1472 (const_string "1") 1473 ] 1474 (const_string "0"))) 1475 (set_attr "athlon_decode" "vector") 1476 (set_attr "amdfam10_decode" "direct") 1477 (set_attr "bdver1_decode" "double")]) 1478 1479(define_insn "*cmpfp_i_sse" 1480 [(set (reg:CCFP FLAGS_REG) 1481 (compare:CCFP (match_operand 0 "register_operand" "x") 1482 (match_operand 1 "nonimmediate_operand" "xm")))] 1483 "TARGET_SSE_MATH 1484 && SSE_FLOAT_MODE_P (GET_MODE (operands[0])) 1485 && GET_MODE (operands[0]) == GET_MODE (operands[1])" 1486 "* return output_fp_compare (insn, operands, true, false);" 1487 [(set_attr "type" "ssecomi") 1488 (set_attr "prefix" "maybe_vex") 1489 (set (attr "mode") 1490 (if_then_else (match_operand:SF 1 "" "") 1491 (const_string "SF") 1492 (const_string "DF"))) 1493 (set_attr "prefix_rep" "0") 1494 (set (attr "prefix_data16") 1495 (if_then_else (eq_attr "mode" "DF") 1496 (const_string "1") 1497 (const_string "0"))) 1498 (set_attr "athlon_decode" "vector") 1499 (set_attr "amdfam10_decode" "direct") 1500 (set_attr "bdver1_decode" "double")]) 1501 1502(define_insn "*cmpfp_i_i387" 1503 [(set (reg:CCFP FLAGS_REG) 1504 (compare:CCFP (match_operand 0 "register_operand" "f") 1505 (match_operand 1 "register_operand" "f")))] 1506 "X87_FLOAT_MODE_P (GET_MODE (operands[0])) 1507 && TARGET_CMOVE 1508 && !(SSE_FLOAT_MODE_P (GET_MODE (operands[0])) && TARGET_SSE_MATH) 1509 && GET_MODE (operands[0]) == GET_MODE (operands[1])" 1510 "* return output_fp_compare (insn, operands, true, false);" 1511 [(set_attr "type" "fcmp") 1512 (set (attr "mode") 1513 (cond [(match_operand:SF 1 "" "") 1514 (const_string "SF") 1515 (match_operand:DF 1 "" "") 1516 (const_string "DF") 1517 ] 1518 (const_string "XF"))) 1519 (set_attr "athlon_decode" "vector") 1520 (set_attr "amdfam10_decode" "direct") 1521 (set_attr "bdver1_decode" "double")]) 1522 1523(define_insn "*cmpfp_iu_mixed" 1524 [(set (reg:CCFPU FLAGS_REG) 1525 (compare:CCFPU (match_operand 0 "register_operand" "f,x") 1526 (match_operand 1 "nonimmediate_operand" "f,xm")))] 1527 "TARGET_MIX_SSE_I387 1528 && SSE_FLOAT_MODE_P (GET_MODE (operands[0])) 1529 && GET_MODE (operands[0]) == GET_MODE (operands[1])" 1530 "* return output_fp_compare (insn, operands, true, true);" 1531 [(set_attr "type" "fcmp,ssecomi") 1532 (set_attr "prefix" "orig,maybe_vex") 1533 (set (attr "mode") 1534 (if_then_else (match_operand:SF 1 "" "") 1535 (const_string "SF") 1536 (const_string "DF"))) 1537 (set (attr "prefix_rep") 1538 (if_then_else (eq_attr "type" "ssecomi") 1539 (const_string "0") 1540 (const_string "*"))) 1541 (set (attr "prefix_data16") 1542 (cond [(eq_attr "type" "fcmp") 1543 (const_string "*") 1544 (eq_attr "mode" "DF") 1545 (const_string "1") 1546 ] 1547 (const_string "0"))) 1548 (set_attr "athlon_decode" "vector") 1549 (set_attr "amdfam10_decode" "direct") 1550 (set_attr "bdver1_decode" "double")]) 1551 1552(define_insn "*cmpfp_iu_sse" 1553 [(set (reg:CCFPU FLAGS_REG) 1554 (compare:CCFPU (match_operand 0 "register_operand" "x") 1555 (match_operand 1 "nonimmediate_operand" "xm")))] 1556 "TARGET_SSE_MATH 1557 && SSE_FLOAT_MODE_P (GET_MODE (operands[0])) 1558 && GET_MODE (operands[0]) == GET_MODE (operands[1])" 1559 "* return output_fp_compare (insn, operands, true, true);" 1560 [(set_attr "type" "ssecomi") 1561 (set_attr "prefix" "maybe_vex") 1562 (set (attr "mode") 1563 (if_then_else (match_operand:SF 1 "" "") 1564 (const_string "SF") 1565 (const_string "DF"))) 1566 (set_attr "prefix_rep" "0") 1567 (set (attr "prefix_data16") 1568 (if_then_else (eq_attr "mode" "DF") 1569 (const_string "1") 1570 (const_string "0"))) 1571 (set_attr "athlon_decode" "vector") 1572 (set_attr "amdfam10_decode" "direct") 1573 (set_attr "bdver1_decode" "double")]) 1574 1575(define_insn "*cmpfp_iu_387" 1576 [(set (reg:CCFPU FLAGS_REG) 1577 (compare:CCFPU (match_operand 0 "register_operand" "f") 1578 (match_operand 1 "register_operand" "f")))] 1579 "X87_FLOAT_MODE_P (GET_MODE (operands[0])) 1580 && TARGET_CMOVE 1581 && !(SSE_FLOAT_MODE_P (GET_MODE (operands[0])) && TARGET_SSE_MATH) 1582 && GET_MODE (operands[0]) == GET_MODE (operands[1])" 1583 "* return output_fp_compare (insn, operands, true, true);" 1584 [(set_attr "type" "fcmp") 1585 (set (attr "mode") 1586 (cond [(match_operand:SF 1 "" "") 1587 (const_string "SF") 1588 (match_operand:DF 1 "" "") 1589 (const_string "DF") 1590 ] 1591 (const_string "XF"))) 1592 (set_attr "athlon_decode" "vector") 1593 (set_attr "amdfam10_decode" "direct") 1594 (set_attr "bdver1_decode" "direct")]) 1595 1596;; Push/pop instructions. 1597 1598(define_insn "*push<mode>2" 1599 [(set (match_operand:DWI 0 "push_operand" "=<") 1600 (match_operand:DWI 1 "general_no_elim_operand" "riF*o"))] 1601 "" 1602 "#" 1603 [(set_attr "type" "multi") 1604 (set_attr "mode" "<MODE>")]) 1605 1606(define_split 1607 [(set (match_operand:TI 0 "push_operand" "") 1608 (match_operand:TI 1 "general_operand" ""))] 1609 "TARGET_64BIT && reload_completed 1610 && !SSE_REG_P (operands[1])" 1611 [(const_int 0)] 1612 "ix86_split_long_move (operands); DONE;") 1613 1614(define_insn "*pushdi2_rex64" 1615 [(set (match_operand:DI 0 "push_operand" "=<,!<") 1616 (match_operand:DI 1 "general_no_elim_operand" "re*m,n"))] 1617 "TARGET_64BIT" 1618 "@ 1619 push{q}\t%1 1620 #" 1621 [(set_attr "type" "push,multi") 1622 (set_attr "mode" "DI")]) 1623 1624;; Convert impossible pushes of immediate to existing instructions. 1625;; First try to get scratch register and go through it. In case this 1626;; fails, push sign extended lower part first and then overwrite 1627;; upper part by 32bit move. 1628(define_peephole2 1629 [(match_scratch:DI 2 "r") 1630 (set (match_operand:DI 0 "push_operand" "") 1631 (match_operand:DI 1 "immediate_operand" ""))] 1632 "TARGET_64BIT && !symbolic_operand (operands[1], DImode) 1633 && !x86_64_immediate_operand (operands[1], DImode)" 1634 [(set (match_dup 2) (match_dup 1)) 1635 (set (match_dup 0) (match_dup 2))]) 1636 1637;; We need to define this as both peepholer and splitter for case 1638;; peephole2 pass is not run. 1639;; "&& 1" is needed to keep it from matching the previous pattern. 1640(define_peephole2 1641 [(set (match_operand:DI 0 "push_operand" "") 1642 (match_operand:DI 1 "immediate_operand" ""))] 1643 "TARGET_64BIT && !symbolic_operand (operands[1], DImode) 1644 && !x86_64_immediate_operand (operands[1], DImode) && 1" 1645 [(set (match_dup 0) (match_dup 1)) 1646 (set (match_dup 2) (match_dup 3))] 1647{ 1648 split_double_mode (DImode, &operands[1], 1, &operands[2], &operands[3]); 1649 1650 operands[1] = gen_lowpart (DImode, operands[2]); 1651 operands[2] = gen_rtx_MEM (SImode, gen_rtx_PLUS (Pmode, stack_pointer_rtx, 1652 GEN_INT (4))); 1653}) 1654 1655(define_split 1656 [(set (match_operand:DI 0 "push_operand" "") 1657 (match_operand:DI 1 "immediate_operand" ""))] 1658 "TARGET_64BIT && ((optimize > 0 && flag_peephole2) 1659 ? epilogue_completed : reload_completed) 1660 && !symbolic_operand (operands[1], DImode) 1661 && !x86_64_immediate_operand (operands[1], DImode)" 1662 [(set (match_dup 0) (match_dup 1)) 1663 (set (match_dup 2) (match_dup 3))] 1664{ 1665 split_double_mode (DImode, &operands[1], 1, &operands[2], &operands[3]); 1666 1667 operands[1] = gen_lowpart (DImode, operands[2]); 1668 operands[2] = gen_rtx_MEM (SImode, gen_rtx_PLUS (Pmode, stack_pointer_rtx, 1669 GEN_INT (4))); 1670}) 1671 1672(define_split 1673 [(set (match_operand:DI 0 "push_operand" "") 1674 (match_operand:DI 1 "general_operand" ""))] 1675 "!TARGET_64BIT && reload_completed 1676 && !(MMX_REG_P (operands[1]) || SSE_REG_P (operands[1]))" 1677 [(const_int 0)] 1678 "ix86_split_long_move (operands); DONE;") 1679 1680(define_insn "*pushsi2" 1681 [(set (match_operand:SI 0 "push_operand" "=<") 1682 (match_operand:SI 1 "general_no_elim_operand" "ri*m"))] 1683 "!TARGET_64BIT" 1684 "push{l}\t%1" 1685 [(set_attr "type" "push") 1686 (set_attr "mode" "SI")]) 1687 1688;; emit_push_insn when it calls move_by_pieces requires an insn to 1689;; "push a byte/word". But actually we use pushl, which has the effect 1690;; of rounding the amount pushed up to a word. 1691 1692;; For TARGET_64BIT we always round up to 8 bytes. 1693(define_insn "*push<mode>2_rex64" 1694 [(set (match_operand:SWI124 0 "push_operand" "=X") 1695 (match_operand:SWI124 1 "nonmemory_no_elim_operand" "r<i>"))] 1696 "TARGET_64BIT" 1697 "push{q}\t%q1" 1698 [(set_attr "type" "push") 1699 (set_attr "mode" "DI")]) 1700 1701(define_insn "*push<mode>2" 1702 [(set (match_operand:SWI12 0 "push_operand" "=X") 1703 (match_operand:SWI12 1 "nonmemory_no_elim_operand" "rn"))] 1704 "!TARGET_64BIT" 1705 "push{l}\t%k1" 1706 [(set_attr "type" "push") 1707 (set_attr "mode" "SI")]) 1708 1709(define_insn "*push<mode>2_prologue" 1710 [(set (match_operand:P 0 "push_operand" "=<") 1711 (match_operand:P 1 "general_no_elim_operand" "r<i>*m")) 1712 (clobber (mem:BLK (scratch)))] 1713 "" 1714 "push{<imodesuffix>}\t%1" 1715 [(set_attr "type" "push") 1716 (set_attr "mode" "<MODE>")]) 1717 1718(define_insn "*pop<mode>1" 1719 [(set (match_operand:P 0 "nonimmediate_operand" "=r*m") 1720 (match_operand:P 1 "pop_operand" ">"))] 1721 "" 1722 "pop{<imodesuffix>}\t%0" 1723 [(set_attr "type" "pop") 1724 (set_attr "mode" "<MODE>")]) 1725 1726(define_insn "*pop<mode>1_epilogue" 1727 [(set (match_operand:P 0 "nonimmediate_operand" "=r*m") 1728 (match_operand:P 1 "pop_operand" ">")) 1729 (clobber (mem:BLK (scratch)))] 1730 "" 1731 "pop{<imodesuffix>}\t%0" 1732 [(set_attr "type" "pop") 1733 (set_attr "mode" "<MODE>")]) 1734 1735;; Move instructions. 1736 1737(define_expand "movoi" 1738 [(set (match_operand:OI 0 "nonimmediate_operand" "") 1739 (match_operand:OI 1 "general_operand" ""))] 1740 "TARGET_AVX" 1741 "ix86_expand_move (OImode, operands); DONE;") 1742 1743(define_expand "movti" 1744 [(set (match_operand:TI 0 "nonimmediate_operand" "") 1745 (match_operand:TI 1 "nonimmediate_operand" ""))] 1746 "TARGET_64BIT || TARGET_SSE" 1747{ 1748 if (TARGET_64BIT) 1749 ix86_expand_move (TImode, operands); 1750 else if (push_operand (operands[0], TImode)) 1751 ix86_expand_push (TImode, operands[1]); 1752 else 1753 ix86_expand_vector_move (TImode, operands); 1754 DONE; 1755}) 1756 1757;; This expands to what emit_move_complex would generate if we didn't 1758;; have a movti pattern. Having this avoids problems with reload on 1759;; 32-bit targets when SSE is present, but doesn't seem to be harmful 1760;; to have around all the time. 1761(define_expand "movcdi" 1762 [(set (match_operand:CDI 0 "nonimmediate_operand" "") 1763 (match_operand:CDI 1 "general_operand" ""))] 1764 "" 1765{ 1766 if (push_operand (operands[0], CDImode)) 1767 emit_move_complex_push (CDImode, operands[0], operands[1]); 1768 else 1769 emit_move_complex_parts (operands[0], operands[1]); 1770 DONE; 1771}) 1772 1773(define_expand "mov<mode>" 1774 [(set (match_operand:SWI1248x 0 "nonimmediate_operand" "") 1775 (match_operand:SWI1248x 1 "general_operand" ""))] 1776 "" 1777 "ix86_expand_move (<MODE>mode, operands); DONE;") 1778 1779(define_insn "*mov<mode>_xor" 1780 [(set (match_operand:SWI48 0 "register_operand" "=r") 1781 (match_operand:SWI48 1 "const0_operand" "")) 1782 (clobber (reg:CC FLAGS_REG))] 1783 "reload_completed" 1784 "xor{l}\t%k0, %k0" 1785 [(set_attr "type" "alu1") 1786 (set_attr "mode" "SI") 1787 (set_attr "length_immediate" "0")]) 1788 1789(define_insn "*mov<mode>_or" 1790 [(set (match_operand:SWI48 0 "register_operand" "=r") 1791 (match_operand:SWI48 1 "const_int_operand" "")) 1792 (clobber (reg:CC FLAGS_REG))] 1793 "reload_completed 1794 && operands[1] == constm1_rtx" 1795 "or{<imodesuffix>}\t{%1, %0|%0, %1}" 1796 [(set_attr "type" "alu1") 1797 (set_attr "mode" "<MODE>") 1798 (set_attr "length_immediate" "1")]) 1799 1800(define_insn "*movoi_internal_avx" 1801 [(set (match_operand:OI 0 "nonimmediate_operand" "=x,x,m") 1802 (match_operand:OI 1 "vector_move_operand" "C,xm,x"))] 1803 "TARGET_AVX && !(MEM_P (operands[0]) && MEM_P (operands[1]))" 1804{ 1805 switch (which_alternative) 1806 { 1807 case 0: 1808 return standard_sse_constant_opcode (insn, operands[1]); 1809 case 1: 1810 case 2: 1811 if (misaligned_operand (operands[0], OImode) 1812 || misaligned_operand (operands[1], OImode)) 1813 return "vmovdqu\t{%1, %0|%0, %1}"; 1814 else 1815 return "vmovdqa\t{%1, %0|%0, %1}"; 1816 default: 1817 gcc_unreachable (); 1818 } 1819} 1820 [(set_attr "type" "sselog1,ssemov,ssemov") 1821 (set_attr "prefix" "vex") 1822 (set_attr "mode" "OI")]) 1823 1824(define_insn "*movti_internal_rex64" 1825 [(set (match_operand:TI 0 "nonimmediate_operand" "=!r,o,x,x,m") 1826 (match_operand:TI 1 "general_operand" "riFo,re,C,xm,x"))] 1827 "TARGET_64BIT && !(MEM_P (operands[0]) && MEM_P (operands[1]))" 1828{ 1829 switch (which_alternative) 1830 { 1831 case 0: 1832 case 1: 1833 return "#"; 1834 case 2: 1835 return standard_sse_constant_opcode (insn, operands[1]); 1836 case 3: 1837 case 4: 1838 /* TDmode values are passed as TImode on the stack. Moving them 1839 to stack may result in unaligned memory access. */ 1840 if (misaligned_operand (operands[0], TImode) 1841 || misaligned_operand (operands[1], TImode)) 1842 { 1843 if (get_attr_mode (insn) == MODE_V4SF) 1844 return "%vmovups\t{%1, %0|%0, %1}"; 1845 else 1846 return "%vmovdqu\t{%1, %0|%0, %1}"; 1847 } 1848 else 1849 { 1850 if (get_attr_mode (insn) == MODE_V4SF) 1851 return "%vmovaps\t{%1, %0|%0, %1}"; 1852 else 1853 return "%vmovdqa\t{%1, %0|%0, %1}"; 1854 } 1855 default: 1856 gcc_unreachable (); 1857 } 1858} 1859 [(set_attr "type" "*,*,sselog1,ssemov,ssemov") 1860 (set_attr "prefix" "*,*,maybe_vex,maybe_vex,maybe_vex") 1861 (set (attr "mode") 1862 (cond [(eq_attr "alternative" "0,1") 1863 (const_string "DI") 1864 (ior (not (match_test "TARGET_SSE2")) 1865 (match_test "optimize_function_for_size_p (cfun)")) 1866 (const_string "V4SF") 1867 (and (eq_attr "alternative" "4") 1868 (match_test "TARGET_SSE_TYPELESS_STORES")) 1869 (const_string "V4SF") 1870 ] 1871 (const_string "TI")))]) 1872 1873(define_split 1874 [(set (match_operand:TI 0 "nonimmediate_operand" "") 1875 (match_operand:TI 1 "general_operand" ""))] 1876 "reload_completed 1877 && !SSE_REG_P (operands[0]) && !SSE_REG_P (operands[1])" 1878 [(const_int 0)] 1879 "ix86_split_long_move (operands); DONE;") 1880 1881(define_insn "*movti_internal_sse" 1882 [(set (match_operand:TI 0 "nonimmediate_operand" "=x,x,m") 1883 (match_operand:TI 1 "vector_move_operand" "C,xm,x"))] 1884 "TARGET_SSE && !TARGET_64BIT 1885 && !(MEM_P (operands[0]) && MEM_P (operands[1]))" 1886{ 1887 switch (which_alternative) 1888 { 1889 case 0: 1890 return standard_sse_constant_opcode (insn, operands[1]); 1891 case 1: 1892 case 2: 1893 /* TDmode values are passed as TImode on the stack. Moving them 1894 to stack may result in unaligned memory access. */ 1895 if (misaligned_operand (operands[0], TImode) 1896 || misaligned_operand (operands[1], TImode)) 1897 { 1898 if (get_attr_mode (insn) == MODE_V4SF) 1899 return "%vmovups\t{%1, %0|%0, %1}"; 1900 else 1901 return "%vmovdqu\t{%1, %0|%0, %1}"; 1902 } 1903 else 1904 { 1905 if (get_attr_mode (insn) == MODE_V4SF) 1906 return "%vmovaps\t{%1, %0|%0, %1}"; 1907 else 1908 return "%vmovdqa\t{%1, %0|%0, %1}"; 1909 } 1910 default: 1911 gcc_unreachable (); 1912 } 1913} 1914 [(set_attr "type" "sselog1,ssemov,ssemov") 1915 (set_attr "prefix" "maybe_vex") 1916 (set (attr "mode") 1917 (cond [(ior (not (match_test "TARGET_SSE2")) 1918 (match_test "optimize_function_for_size_p (cfun)")) 1919 (const_string "V4SF") 1920 (and (eq_attr "alternative" "2") 1921 (match_test "TARGET_SSE_TYPELESS_STORES")) 1922 (const_string "V4SF")] 1923 (const_string "TI")))]) 1924 1925(define_insn "*movdi_internal_rex64" 1926 [(set (match_operand:DI 0 "nonimmediate_operand" 1927 "=r,r ,r,m ,*y,m*y,?*y,?r ,?*Ym,*x,m ,*x,*x,?r ,?*Yi,?*x,?*Ym") 1928 (match_operand:DI 1 "general_operand" 1929 "Z ,rem,i,re,C ,*y ,m ,*Ym,r ,C ,*x,*x,m ,*Yi,r ,*Ym,*x"))] 1930 "TARGET_64BIT && !(MEM_P (operands[0]) && MEM_P (operands[1]))" 1931{ 1932 switch (get_attr_type (insn)) 1933 { 1934 case TYPE_SSECVT: 1935 if (SSE_REG_P (operands[0])) 1936 return "movq2dq\t{%1, %0|%0, %1}"; 1937 else 1938 return "movdq2q\t{%1, %0|%0, %1}"; 1939 1940 case TYPE_SSEMOV: 1941 if (get_attr_mode (insn) == MODE_TI) 1942 return "%vmovdqa\t{%1, %0|%0, %1}"; 1943 /* Handle broken assemblers that require movd instead of movq. */ 1944 if (GENERAL_REG_P (operands[0]) || GENERAL_REG_P (operands[1])) 1945 return "%vmovd\t{%1, %0|%0, %1}"; 1946 else 1947 return "%vmovq\t{%1, %0|%0, %1}"; 1948 1949 case TYPE_MMXMOV: 1950 /* Handle broken assemblers that require movd instead of movq. */ 1951 if (GENERAL_REG_P (operands[0]) || GENERAL_REG_P (operands[1])) 1952 return "movd\t{%1, %0|%0, %1}"; 1953 else 1954 return "movq\t{%1, %0|%0, %1}"; 1955 1956 case TYPE_SSELOG1: 1957 return standard_sse_constant_opcode (insn, operands[1]); 1958 1959 case TYPE_MMX: 1960 return "pxor\t%0, %0"; 1961 1962 case TYPE_LEA: 1963 return "lea{q}\t{%E1, %0|%0, %E1}"; 1964 1965 default: 1966 gcc_assert (!flag_pic || LEGITIMATE_PIC_OPERAND_P (operands[1])); 1967 if (get_attr_mode (insn) == MODE_SI) 1968 return "mov{l}\t{%k1, %k0|%k0, %k1}"; 1969 else if (which_alternative == 2) 1970 return "movabs{q}\t{%1, %0|%0, %1}"; 1971 else if (ix86_use_lea_for_mov (insn, operands)) 1972 return "lea{q}\t{%E1, %0|%0, %E1}"; 1973 else 1974 return "mov{q}\t{%1, %0|%0, %1}"; 1975 } 1976} 1977 [(set (attr "type") 1978 (cond [(eq_attr "alternative" "4") 1979 (const_string "mmx") 1980 (eq_attr "alternative" "5,6,7,8") 1981 (const_string "mmxmov") 1982 (eq_attr "alternative" "9") 1983 (const_string "sselog1") 1984 (eq_attr "alternative" "10,11,12,13,14") 1985 (const_string "ssemov") 1986 (eq_attr "alternative" "15,16") 1987 (const_string "ssecvt") 1988 (match_operand 1 "pic_32bit_operand" "") 1989 (const_string "lea") 1990 ] 1991 (const_string "imov"))) 1992 (set (attr "modrm") 1993 (if_then_else 1994 (and (eq_attr "alternative" "2") (eq_attr "type" "imov")) 1995 (const_string "0") 1996 (const_string "*"))) 1997 (set (attr "length_immediate") 1998 (if_then_else 1999 (and (eq_attr "alternative" "2") (eq_attr "type" "imov")) 2000 (const_string "8") 2001 (const_string "*"))) 2002 (set (attr "prefix_rex") 2003 (if_then_else (eq_attr "alternative" "7,8") 2004 (const_string "1") 2005 (const_string "*"))) 2006 (set (attr "prefix_data16") 2007 (if_then_else (eq_attr "alternative" "10") 2008 (const_string "1") 2009 (const_string "*"))) 2010 (set (attr "prefix") 2011 (if_then_else (eq_attr "alternative" "11,12,13,14,15") 2012 (const_string "maybe_vex") 2013 (const_string "orig"))) 2014 (set_attr "mode" "SI,DI,DI,DI,DI,DI,DI,DI,DI,TI,DI,TI,DI,DI,DI,DI,DI")]) 2015 2016;; Reload patterns to support multi-word load/store 2017;; with non-offsetable address. 2018(define_expand "reload_noff_store" 2019 [(parallel [(match_operand 0 "memory_operand" "=m") 2020 (match_operand 1 "register_operand" "r") 2021 (match_operand:DI 2 "register_operand" "=&r")])] 2022 "TARGET_64BIT" 2023{ 2024 rtx mem = operands[0]; 2025 rtx addr = XEXP (mem, 0); 2026 2027 emit_move_insn (operands[2], addr); 2028 mem = replace_equiv_address_nv (mem, operands[2]); 2029 2030 emit_insn (gen_rtx_SET (VOIDmode, mem, operands[1])); 2031 DONE; 2032}) 2033 2034(define_expand "reload_noff_load" 2035 [(parallel [(match_operand 0 "register_operand" "=r") 2036 (match_operand 1 "memory_operand" "m") 2037 (match_operand:DI 2 "register_operand" "=r")])] 2038 "TARGET_64BIT" 2039{ 2040 rtx mem = operands[1]; 2041 rtx addr = XEXP (mem, 0); 2042 2043 emit_move_insn (operands[2], addr); 2044 mem = replace_equiv_address_nv (mem, operands[2]); 2045 2046 emit_insn (gen_rtx_SET (VOIDmode, operands[0], mem)); 2047 DONE; 2048}) 2049 2050(define_insn "*movdi_internal" 2051 [(set (match_operand:DI 0 "nonimmediate_operand" 2052 "=r ,o ,*y,m*y,*y,*x,m ,*x,*x,*x,m ,*x,*x,?*x,?*Ym") 2053 (match_operand:DI 1 "general_operand" 2054 "riFo,riF,C ,*y ,m ,C ,*x,*x,m ,C ,*x,*x,m ,*Ym,*x"))] 2055 "!TARGET_64BIT && !(MEM_P (operands[0]) && MEM_P (operands[1]))" 2056{ 2057 switch (get_attr_type (insn)) 2058 { 2059 case TYPE_SSECVT: 2060 if (SSE_REG_P (operands[0])) 2061 return "movq2dq\t{%1, %0|%0, %1}"; 2062 else 2063 return "movdq2q\t{%1, %0|%0, %1}"; 2064 2065 case TYPE_SSEMOV: 2066 switch (get_attr_mode (insn)) 2067 { 2068 case MODE_TI: 2069 return "%vmovdqa\t{%1, %0|%0, %1}"; 2070 case MODE_DI: 2071 return "%vmovq\t{%1, %0|%0, %1}"; 2072 case MODE_V4SF: 2073 return "movaps\t{%1, %0|%0, %1}"; 2074 case MODE_V2SF: 2075 return "movlps\t{%1, %0|%0, %1}"; 2076 default: 2077 gcc_unreachable (); 2078 } 2079 2080 case TYPE_MMXMOV: 2081 return "movq\t{%1, %0|%0, %1}"; 2082 2083 case TYPE_SSELOG1: 2084 return standard_sse_constant_opcode (insn, operands[1]); 2085 2086 case TYPE_MMX: 2087 return "pxor\t%0, %0"; 2088 2089 case TYPE_MULTI: 2090 return "#"; 2091 2092 default: 2093 gcc_unreachable (); 2094 } 2095} 2096 [(set (attr "isa") 2097 (cond [(eq_attr "alternative" "5,6,7,8,13,14") 2098 (const_string "sse2") 2099 (eq_attr "alternative" "9,10,11,12") 2100 (const_string "noavx") 2101 ] 2102 (const_string "*"))) 2103 (set (attr "type") 2104 (cond [(eq_attr "alternative" "0,1") 2105 (const_string "multi") 2106 (eq_attr "alternative" "2") 2107 (const_string "mmx") 2108 (eq_attr "alternative" "3,4") 2109 (const_string "mmxmov") 2110 (eq_attr "alternative" "5,9") 2111 (const_string "sselog1") 2112 (eq_attr "alternative" "13,14") 2113 (const_string "ssecvt") 2114 ] 2115 (const_string "ssemov"))) 2116 (set (attr "prefix") 2117 (if_then_else (eq_attr "alternative" "5,6,7,8") 2118 (const_string "maybe_vex") 2119 (const_string "orig"))) 2120 (set_attr "mode" "DI,DI,DI,DI,DI,TI,DI,TI,DI,V4SF,V2SF,V4SF,V2SF,DI,DI")]) 2121 2122(define_split 2123 [(set (match_operand:DI 0 "nonimmediate_operand" "") 2124 (match_operand:DI 1 "general_operand" ""))] 2125 "!TARGET_64BIT && reload_completed 2126 && !(MMX_REG_P (operands[0]) || SSE_REG_P (operands[0])) 2127 && !(MMX_REG_P (operands[1]) || SSE_REG_P (operands[1]))" 2128 [(const_int 0)] 2129 "ix86_split_long_move (operands); DONE;") 2130 2131(define_insn "*movsi_internal" 2132 [(set (match_operand:SI 0 "nonimmediate_operand" 2133 "=r,m ,*y,*y,?rm,?*y,*x,*x,?r ,m ,?*Yi,*x") 2134 (match_operand:SI 1 "general_operand" 2135 "g ,re,C ,*y,*y ,rm ,C ,*x,*Yi,*x,r ,m "))] 2136 "!(MEM_P (operands[0]) && MEM_P (operands[1]))" 2137{ 2138 switch (get_attr_type (insn)) 2139 { 2140 case TYPE_SSELOG1: 2141 return standard_sse_constant_opcode (insn, operands[1]); 2142 2143 case TYPE_SSEMOV: 2144 switch (get_attr_mode (insn)) 2145 { 2146 case MODE_TI: 2147 return "%vmovdqa\t{%1, %0|%0, %1}"; 2148 case MODE_V4SF: 2149 return "%vmovaps\t{%1, %0|%0, %1}"; 2150 case MODE_SI: 2151 return "%vmovd\t{%1, %0|%0, %1}"; 2152 case MODE_SF: 2153 return "%vmovss\t{%1, %0|%0, %1}"; 2154 default: 2155 gcc_unreachable (); 2156 } 2157 2158 case TYPE_MMX: 2159 return "pxor\t%0, %0"; 2160 2161 case TYPE_MMXMOV: 2162 if (get_attr_mode (insn) == MODE_DI) 2163 return "movq\t{%1, %0|%0, %1}"; 2164 return "movd\t{%1, %0|%0, %1}"; 2165 2166 case TYPE_LEA: 2167 return "lea{l}\t{%E1, %0|%0, %E1}"; 2168 2169 default: 2170 gcc_assert (!flag_pic || LEGITIMATE_PIC_OPERAND_P (operands[1])); 2171 if (ix86_use_lea_for_mov (insn, operands)) 2172 return "lea{l}\t{%E1, %0|%0, %E1}"; 2173 else 2174 return "mov{l}\t{%1, %0|%0, %1}"; 2175 } 2176} 2177 [(set (attr "type") 2178 (cond [(eq_attr "alternative" "2") 2179 (const_string "mmx") 2180 (eq_attr "alternative" "3,4,5") 2181 (const_string "mmxmov") 2182 (eq_attr "alternative" "6") 2183 (const_string "sselog1") 2184 (eq_attr "alternative" "7,8,9,10,11") 2185 (const_string "ssemov") 2186 (match_operand 1 "pic_32bit_operand" "") 2187 (const_string "lea") 2188 ] 2189 (const_string "imov"))) 2190 (set (attr "prefix") 2191 (if_then_else (eq_attr "alternative" "0,1,2,3,4,5") 2192 (const_string "orig") 2193 (const_string "maybe_vex"))) 2194 (set (attr "prefix_data16") 2195 (if_then_else (and (eq_attr "type" "ssemov") (eq_attr "mode" "SI")) 2196 (const_string "1") 2197 (const_string "*"))) 2198 (set (attr "mode") 2199 (cond [(eq_attr "alternative" "2,3") 2200 (const_string "DI") 2201 (eq_attr "alternative" "6,7") 2202 (if_then_else 2203 (not (match_test "TARGET_SSE2")) 2204 (const_string "V4SF") 2205 (const_string "TI")) 2206 (and (eq_attr "alternative" "8,9,10,11") 2207 (not (match_test "TARGET_SSE2"))) 2208 (const_string "SF") 2209 ] 2210 (const_string "SI")))]) 2211 2212(define_insn "*movhi_internal" 2213 [(set (match_operand:HI 0 "nonimmediate_operand" "=r,r,r,m") 2214 (match_operand:HI 1 "general_operand" "r,rn,rm,rn"))] 2215 "!(MEM_P (operands[0]) && MEM_P (operands[1]))" 2216{ 2217 switch (get_attr_type (insn)) 2218 { 2219 case TYPE_IMOVX: 2220 /* movzwl is faster than movw on p2 due to partial word stalls, 2221 though not as fast as an aligned movl. */ 2222 return "movz{wl|x}\t{%1, %k0|%k0, %1}"; 2223 default: 2224 if (get_attr_mode (insn) == MODE_SI) 2225 return "mov{l}\t{%k1, %k0|%k0, %k1}"; 2226 else 2227 return "mov{w}\t{%1, %0|%0, %1}"; 2228 } 2229} 2230 [(set (attr "type") 2231 (cond [(match_test "optimize_function_for_size_p (cfun)") 2232 (const_string "imov") 2233 (and (eq_attr "alternative" "0") 2234 (ior (not (match_test "TARGET_PARTIAL_REG_STALL")) 2235 (not (match_test "TARGET_HIMODE_MATH")))) 2236 (const_string "imov") 2237 (and (eq_attr "alternative" "1,2") 2238 (match_operand:HI 1 "aligned_operand" "")) 2239 (const_string "imov") 2240 (and (match_test "TARGET_MOVX") 2241 (eq_attr "alternative" "0,2")) 2242 (const_string "imovx") 2243 ] 2244 (const_string "imov"))) 2245 (set (attr "mode") 2246 (cond [(eq_attr "type" "imovx") 2247 (const_string "SI") 2248 (and (eq_attr "alternative" "1,2") 2249 (match_operand:HI 1 "aligned_operand" "")) 2250 (const_string "SI") 2251 (and (eq_attr "alternative" "0") 2252 (ior (not (match_test "TARGET_PARTIAL_REG_STALL")) 2253 (not (match_test "TARGET_HIMODE_MATH")))) 2254 (const_string "SI") 2255 ] 2256 (const_string "HI")))]) 2257 2258;; Situation is quite tricky about when to choose full sized (SImode) move 2259;; over QImode moves. For Q_REG -> Q_REG move we use full size only for 2260;; partial register dependency machines (such as AMD Athlon), where QImode 2261;; moves issue extra dependency and for partial register stalls machines 2262;; that don't use QImode patterns (and QImode move cause stall on the next 2263;; instruction). 2264;; 2265;; For loads of Q_REG to NONQ_REG we use full sized moves except for partial 2266;; register stall machines with, where we use QImode instructions, since 2267;; partial register stall can be caused there. Then we use movzx. 2268(define_insn "*movqi_internal" 2269 [(set (match_operand:QI 0 "nonimmediate_operand" "=q,q ,q ,r,r ,?r,m") 2270 (match_operand:QI 1 "general_operand" " q,qn,qm,q,rn,qm,qn"))] 2271 "!(MEM_P (operands[0]) && MEM_P (operands[1]))" 2272{ 2273 switch (get_attr_type (insn)) 2274 { 2275 case TYPE_IMOVX: 2276 gcc_assert (ANY_QI_REG_P (operands[1]) || MEM_P (operands[1])); 2277 return "movz{bl|x}\t{%1, %k0|%k0, %1}"; 2278 default: 2279 if (get_attr_mode (insn) == MODE_SI) 2280 return "mov{l}\t{%k1, %k0|%k0, %k1}"; 2281 else 2282 return "mov{b}\t{%1, %0|%0, %1}"; 2283 } 2284} 2285 [(set (attr "type") 2286 (cond [(and (eq_attr "alternative" "5") 2287 (not (match_operand:QI 1 "aligned_operand" ""))) 2288 (const_string "imovx") 2289 (match_test "optimize_function_for_size_p (cfun)") 2290 (const_string "imov") 2291 (and (eq_attr "alternative" "3") 2292 (ior (not (match_test "TARGET_PARTIAL_REG_STALL")) 2293 (not (match_test "TARGET_QIMODE_MATH")))) 2294 (const_string "imov") 2295 (eq_attr "alternative" "3,5") 2296 (const_string "imovx") 2297 (and (match_test "TARGET_MOVX") 2298 (eq_attr "alternative" "2")) 2299 (const_string "imovx") 2300 ] 2301 (const_string "imov"))) 2302 (set (attr "mode") 2303 (cond [(eq_attr "alternative" "3,4,5") 2304 (const_string "SI") 2305 (eq_attr "alternative" "6") 2306 (const_string "QI") 2307 (eq_attr "type" "imovx") 2308 (const_string "SI") 2309 (and (eq_attr "type" "imov") 2310 (and (eq_attr "alternative" "0,1") 2311 (and (match_test "TARGET_PARTIAL_REG_DEPENDENCY") 2312 (and (not (match_test "optimize_function_for_size_p (cfun)")) 2313 (not (match_test "TARGET_PARTIAL_REG_STALL")))))) 2314 (const_string "SI") 2315 ;; Avoid partial register stalls when not using QImode arithmetic 2316 (and (eq_attr "type" "imov") 2317 (and (eq_attr "alternative" "0,1") 2318 (and (match_test "TARGET_PARTIAL_REG_STALL") 2319 (not (match_test "TARGET_QIMODE_MATH"))))) 2320 (const_string "SI") 2321 ] 2322 (const_string "QI")))]) 2323 2324;; Stores and loads of ax to arbitrary constant address. 2325;; We fake an second form of instruction to force reload to load address 2326;; into register when rax is not available 2327(define_insn "*movabs<mode>_1" 2328 [(set (mem:SWI1248x (match_operand:DI 0 "x86_64_movabs_operand" "i,r")) 2329 (match_operand:SWI1248x 1 "nonmemory_operand" "a,r<i>"))] 2330 "TARGET_LP64 && ix86_check_movabs (insn, 0)" 2331 "@ 2332 movabs{<imodesuffix>}\t{%1, %P0|[%P0], %1} 2333 mov{<imodesuffix>}\t{%1, %a0|<iptrsize> PTR %a0, %1}" 2334 [(set_attr "type" "imov") 2335 (set_attr "modrm" "0,*") 2336 (set_attr "length_address" "8,0") 2337 (set_attr "length_immediate" "0,*") 2338 (set_attr "memory" "store") 2339 (set_attr "mode" "<MODE>")]) 2340 2341(define_insn "*movabs<mode>_2" 2342 [(set (match_operand:SWI1248x 0 "register_operand" "=a,r") 2343 (mem:SWI1248x (match_operand:DI 1 "x86_64_movabs_operand" "i,r")))] 2344 "TARGET_LP64 && ix86_check_movabs (insn, 1)" 2345 "@ 2346 movabs{<imodesuffix>}\t{%P1, %0|%0, [%P1]} 2347 mov{<imodesuffix>}\t{%a1, %0|%0, <iptrsize> PTR %a1}" 2348 [(set_attr "type" "imov") 2349 (set_attr "modrm" "0,*") 2350 (set_attr "length_address" "8,0") 2351 (set_attr "length_immediate" "0") 2352 (set_attr "memory" "load") 2353 (set_attr "mode" "<MODE>")]) 2354 2355(define_insn "*swap<mode>" 2356 [(set (match_operand:SWI48 0 "register_operand" "+r") 2357 (match_operand:SWI48 1 "register_operand" "+r")) 2358 (set (match_dup 1) 2359 (match_dup 0))] 2360 "" 2361 "xchg{<imodesuffix>}\t%1, %0" 2362 [(set_attr "type" "imov") 2363 (set_attr "mode" "<MODE>") 2364 (set_attr "pent_pair" "np") 2365 (set_attr "athlon_decode" "vector") 2366 (set_attr "amdfam10_decode" "double") 2367 (set_attr "bdver1_decode" "double")]) 2368 2369(define_insn "*swap<mode>_1" 2370 [(set (match_operand:SWI12 0 "register_operand" "+r") 2371 (match_operand:SWI12 1 "register_operand" "+r")) 2372 (set (match_dup 1) 2373 (match_dup 0))] 2374 "!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun)" 2375 "xchg{l}\t%k1, %k0" 2376 [(set_attr "type" "imov") 2377 (set_attr "mode" "SI") 2378 (set_attr "pent_pair" "np") 2379 (set_attr "athlon_decode" "vector") 2380 (set_attr "amdfam10_decode" "double") 2381 (set_attr "bdver1_decode" "double")]) 2382 2383;; Not added amdfam10_decode since TARGET_PARTIAL_REG_STALL 2384;; is disabled for AMDFAM10 2385(define_insn "*swap<mode>_2" 2386 [(set (match_operand:SWI12 0 "register_operand" "+<r>") 2387 (match_operand:SWI12 1 "register_operand" "+<r>")) 2388 (set (match_dup 1) 2389 (match_dup 0))] 2390 "TARGET_PARTIAL_REG_STALL" 2391 "xchg{<imodesuffix>}\t%1, %0" 2392 [(set_attr "type" "imov") 2393 (set_attr "mode" "<MODE>") 2394 (set_attr "pent_pair" "np") 2395 (set_attr "athlon_decode" "vector")]) 2396 2397(define_expand "movstrict<mode>" 2398 [(set (strict_low_part (match_operand:SWI12 0 "nonimmediate_operand" "")) 2399 (match_operand:SWI12 1 "general_operand" ""))] 2400 "" 2401{ 2402 if (TARGET_PARTIAL_REG_STALL && optimize_function_for_speed_p (cfun)) 2403 FAIL; 2404 if (GET_CODE (operands[0]) == SUBREG 2405 && GET_MODE_CLASS (GET_MODE (SUBREG_REG (operands[0]))) != MODE_INT) 2406 FAIL; 2407 /* Don't generate memory->memory moves, go through a register */ 2408 if (MEM_P (operands[0]) && MEM_P (operands[1])) 2409 operands[1] = force_reg (<MODE>mode, operands[1]); 2410}) 2411 2412(define_insn "*movstrict<mode>_1" 2413 [(set (strict_low_part 2414 (match_operand:SWI12 0 "nonimmediate_operand" "+<r>m,<r>")) 2415 (match_operand:SWI12 1 "general_operand" "<r>n,m"))] 2416 "(!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun)) 2417 && !(MEM_P (operands[0]) && MEM_P (operands[1]))" 2418 "mov{<imodesuffix>}\t{%1, %0|%0, %1}" 2419 [(set_attr "type" "imov") 2420 (set_attr "mode" "<MODE>")]) 2421 2422(define_insn "*movstrict<mode>_xor" 2423 [(set (strict_low_part (match_operand:SWI12 0 "register_operand" "+<r>")) 2424 (match_operand:SWI12 1 "const0_operand" "")) 2425 (clobber (reg:CC FLAGS_REG))] 2426 "reload_completed" 2427 "xor{<imodesuffix>}\t%0, %0" 2428 [(set_attr "type" "alu1") 2429 (set_attr "mode" "<MODE>") 2430 (set_attr "length_immediate" "0")]) 2431 2432(define_insn "*mov<mode>_extv_1" 2433 [(set (match_operand:SWI24 0 "register_operand" "=R") 2434 (sign_extract:SWI24 (match_operand 1 "ext_register_operand" "Q") 2435 (const_int 8) 2436 (const_int 8)))] 2437 "" 2438 "movs{bl|x}\t{%h1, %k0|%k0, %h1}" 2439 [(set_attr "type" "imovx") 2440 (set_attr "mode" "SI")]) 2441 2442(define_insn "*movqi_extv_1_rex64" 2443 [(set (match_operand:QI 0 "register_operand" "=Q,?R") 2444 (sign_extract:QI (match_operand 1 "ext_register_operand" "Q,Q") 2445 (const_int 8) 2446 (const_int 8)))] 2447 "TARGET_64BIT" 2448{ 2449 switch (get_attr_type (insn)) 2450 { 2451 case TYPE_IMOVX: 2452 return "movs{bl|x}\t{%h1, %k0|%k0, %h1}"; 2453 default: 2454 return "mov{b}\t{%h1, %0|%0, %h1}"; 2455 } 2456} 2457 [(set (attr "type") 2458 (if_then_else (ior (not (match_operand:QI 0 "QIreg_operand" "")) 2459 (match_test "TARGET_MOVX")) 2460 (const_string "imovx") 2461 (const_string "imov"))) 2462 (set (attr "mode") 2463 (if_then_else (eq_attr "type" "imovx") 2464 (const_string "SI") 2465 (const_string "QI")))]) 2466 2467(define_insn "*movqi_extv_1" 2468 [(set (match_operand:QI 0 "nonimmediate_operand" "=Qm,?r") 2469 (sign_extract:QI (match_operand 1 "ext_register_operand" "Q,Q") 2470 (const_int 8) 2471 (const_int 8)))] 2472 "!TARGET_64BIT" 2473{ 2474 switch (get_attr_type (insn)) 2475 { 2476 case TYPE_IMOVX: 2477 return "movs{bl|x}\t{%h1, %k0|%k0, %h1}"; 2478 default: 2479 return "mov{b}\t{%h1, %0|%0, %h1}"; 2480 } 2481} 2482 [(set (attr "type") 2483 (if_then_else (and (match_operand:QI 0 "register_operand" "") 2484 (ior (not (match_operand:QI 0 "QIreg_operand" "")) 2485 (match_test "TARGET_MOVX"))) 2486 (const_string "imovx") 2487 (const_string "imov"))) 2488 (set (attr "mode") 2489 (if_then_else (eq_attr "type" "imovx") 2490 (const_string "SI") 2491 (const_string "QI")))]) 2492 2493(define_insn "*mov<mode>_extzv_1" 2494 [(set (match_operand:SWI48 0 "register_operand" "=R") 2495 (zero_extract:SWI48 (match_operand 1 "ext_register_operand" "Q") 2496 (const_int 8) 2497 (const_int 8)))] 2498 "" 2499 "movz{bl|x}\t{%h1, %k0|%k0, %h1}" 2500 [(set_attr "type" "imovx") 2501 (set_attr "mode" "SI")]) 2502 2503(define_insn "*movqi_extzv_2_rex64" 2504 [(set (match_operand:QI 0 "register_operand" "=Q,?R") 2505 (subreg:QI 2506 (zero_extract:SI (match_operand 1 "ext_register_operand" "Q,Q") 2507 (const_int 8) 2508 (const_int 8)) 0))] 2509 "TARGET_64BIT" 2510{ 2511 switch (get_attr_type (insn)) 2512 { 2513 case TYPE_IMOVX: 2514 return "movz{bl|x}\t{%h1, %k0|%k0, %h1}"; 2515 default: 2516 return "mov{b}\t{%h1, %0|%0, %h1}"; 2517 } 2518} 2519 [(set (attr "type") 2520 (if_then_else (ior (not (match_operand:QI 0 "QIreg_operand" "")) 2521 (match_test "TARGET_MOVX")) 2522 (const_string "imovx") 2523 (const_string "imov"))) 2524 (set (attr "mode") 2525 (if_then_else (eq_attr "type" "imovx") 2526 (const_string "SI") 2527 (const_string "QI")))]) 2528 2529(define_insn "*movqi_extzv_2" 2530 [(set (match_operand:QI 0 "nonimmediate_operand" "=Qm,?R") 2531 (subreg:QI 2532 (zero_extract:SI (match_operand 1 "ext_register_operand" "Q,Q") 2533 (const_int 8) 2534 (const_int 8)) 0))] 2535 "!TARGET_64BIT" 2536{ 2537 switch (get_attr_type (insn)) 2538 { 2539 case TYPE_IMOVX: 2540 return "movz{bl|x}\t{%h1, %k0|%k0, %h1}"; 2541 default: 2542 return "mov{b}\t{%h1, %0|%0, %h1}"; 2543 } 2544} 2545 [(set (attr "type") 2546 (if_then_else (and (match_operand:QI 0 "register_operand" "") 2547 (ior (not (match_operand:QI 0 "QIreg_operand" "")) 2548 (match_test "TARGET_MOVX"))) 2549 (const_string "imovx") 2550 (const_string "imov"))) 2551 (set (attr "mode") 2552 (if_then_else (eq_attr "type" "imovx") 2553 (const_string "SI") 2554 (const_string "QI")))]) 2555 2556(define_expand "mov<mode>_insv_1" 2557 [(set (zero_extract:SWI48 (match_operand 0 "ext_register_operand" "") 2558 (const_int 8) 2559 (const_int 8)) 2560 (match_operand:SWI48 1 "nonmemory_operand" ""))]) 2561 2562(define_insn "*mov<mode>_insv_1_rex64" 2563 [(set (zero_extract:SWI48x (match_operand 0 "ext_register_operand" "+Q") 2564 (const_int 8) 2565 (const_int 8)) 2566 (match_operand:SWI48x 1 "nonmemory_operand" "Qn"))] 2567 "TARGET_64BIT" 2568{ 2569 if (CONST_INT_P (operands[1])) 2570 operands[1] = simplify_gen_subreg (QImode, operands[1], <MODE>mode, 0); 2571 return "mov{b}\t{%b1, %h0|%h0, %b1}"; 2572} 2573 [(set_attr "type" "imov") 2574 (set_attr "mode" "QI")]) 2575 2576(define_insn "*movsi_insv_1" 2577 [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "+Q") 2578 (const_int 8) 2579 (const_int 8)) 2580 (match_operand:SI 1 "general_operand" "Qmn"))] 2581 "!TARGET_64BIT" 2582{ 2583 if (CONST_INT_P (operands[1])) 2584 operands[1] = simplify_gen_subreg (QImode, operands[1], SImode, 0); 2585 return "mov{b}\t{%b1, %h0|%h0, %b1}"; 2586} 2587 [(set_attr "type" "imov") 2588 (set_attr "mode" "QI")]) 2589 2590(define_insn "*movqi_insv_2" 2591 [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "+Q") 2592 (const_int 8) 2593 (const_int 8)) 2594 (lshiftrt:SI (match_operand:SI 1 "register_operand" "Q") 2595 (const_int 8)))] 2596 "" 2597 "mov{b}\t{%h1, %h0|%h0, %h1}" 2598 [(set_attr "type" "imov") 2599 (set_attr "mode" "QI")]) 2600 2601;; Floating point push instructions. 2602 2603(define_insn "*pushtf" 2604 [(set (match_operand:TF 0 "push_operand" "=<,<,<") 2605 (match_operand:TF 1 "general_no_elim_operand" "x,Fo,*r"))] 2606 "TARGET_SSE2" 2607{ 2608 /* This insn should be already split before reg-stack. */ 2609 gcc_unreachable (); 2610} 2611 [(set_attr "type" "multi") 2612 (set_attr "unit" "sse,*,*") 2613 (set_attr "mode" "TF,SI,SI")]) 2614 2615;; %%% Kill this when call knows how to work this out. 2616(define_split 2617 [(set (match_operand:TF 0 "push_operand" "") 2618 (match_operand:TF 1 "sse_reg_operand" ""))] 2619 "TARGET_SSE2 && reload_completed" 2620 [(set (reg:P SP_REG) (plus:P (reg:P SP_REG) (const_int -16))) 2621 (set (mem:TF (reg:P SP_REG)) (match_dup 1))]) 2622 2623(define_insn "*pushxf" 2624 [(set (match_operand:XF 0 "push_operand" "=<,<") 2625 (match_operand:XF 1 "general_no_elim_operand" "f,ro"))] 2626 "optimize_function_for_speed_p (cfun)" 2627{ 2628 /* This insn should be already split before reg-stack. */ 2629 gcc_unreachable (); 2630} 2631 [(set_attr "type" "multi") 2632 (set_attr "unit" "i387,*") 2633 (set_attr "mode" "XF,SI")]) 2634 2635;; Size of pushxf is 3 (for sub) + 2 (for fstp) + memory operand size. 2636;; Size of pushxf using integer instructions is 3+3*memory operand size 2637;; Pushing using integer instructions is longer except for constants 2638;; and direct memory references (assuming that any given constant is pushed 2639;; only once, but this ought to be handled elsewhere). 2640 2641(define_insn "*pushxf_nointeger" 2642 [(set (match_operand:XF 0 "push_operand" "=<,<") 2643 (match_operand:XF 1 "general_no_elim_operand" "f,*rFo"))] 2644 "optimize_function_for_size_p (cfun)" 2645{ 2646 /* This insn should be already split before reg-stack. */ 2647 gcc_unreachable (); 2648} 2649 [(set_attr "type" "multi") 2650 (set_attr "unit" "i387,*") 2651 (set_attr "mode" "XF,SI")]) 2652 2653;; %%% Kill this when call knows how to work this out. 2654(define_split 2655 [(set (match_operand:XF 0 "push_operand" "") 2656 (match_operand:XF 1 "fp_register_operand" ""))] 2657 "reload_completed" 2658 [(set (reg:P SP_REG) (plus:P (reg:P SP_REG) (match_dup 2))) 2659 (set (mem:XF (reg:P SP_REG)) (match_dup 1))] 2660 "operands[2] = GEN_INT (-GET_MODE_SIZE (XFmode));") 2661 2662(define_insn "*pushdf_rex64" 2663 [(set (match_operand:DF 0 "push_operand" "=<,<,<") 2664 (match_operand:DF 1 "general_no_elim_operand" "f,Yd*rFm,x"))] 2665 "TARGET_64BIT" 2666{ 2667 /* This insn should be already split before reg-stack. */ 2668 gcc_unreachable (); 2669} 2670 [(set_attr "type" "multi") 2671 (set_attr "unit" "i387,*,*") 2672 (set_attr "mode" "DF,DI,DF")]) 2673 2674;; Size of pushdf is 3 (for sub) + 2 (for fstp) + memory operand size. 2675;; Size of pushdf using integer instructions is 2+2*memory operand size 2676;; On the average, pushdf using integers can be still shorter. 2677 2678(define_insn "*pushdf" 2679 [(set (match_operand:DF 0 "push_operand" "=<,<,<") 2680 (match_operand:DF 1 "general_no_elim_operand" "f,Yd*rFo,x"))] 2681 "!TARGET_64BIT" 2682{ 2683 /* This insn should be already split before reg-stack. */ 2684 gcc_unreachable (); 2685} 2686 [(set_attr "isa" "*,*,sse2") 2687 (set_attr "type" "multi") 2688 (set_attr "unit" "i387,*,*") 2689 (set_attr "mode" "DF,DI,DF")]) 2690 2691;; %%% Kill this when call knows how to work this out. 2692(define_split 2693 [(set (match_operand:DF 0 "push_operand" "") 2694 (match_operand:DF 1 "any_fp_register_operand" ""))] 2695 "reload_completed" 2696 [(set (reg:P SP_REG) (plus:P (reg:P SP_REG) (const_int -8))) 2697 (set (mem:DF (reg:P SP_REG)) (match_dup 1))]) 2698 2699(define_insn "*pushsf_rex64" 2700 [(set (match_operand:SF 0 "push_operand" "=X,X,X") 2701 (match_operand:SF 1 "nonmemory_no_elim_operand" "f,rF,x"))] 2702 "TARGET_64BIT" 2703{ 2704 /* Anything else should be already split before reg-stack. */ 2705 gcc_assert (which_alternative == 1); 2706 return "push{q}\t%q1"; 2707} 2708 [(set_attr "type" "multi,push,multi") 2709 (set_attr "unit" "i387,*,*") 2710 (set_attr "mode" "SF,DI,SF")]) 2711 2712(define_insn "*pushsf" 2713 [(set (match_operand:SF 0 "push_operand" "=<,<,<") 2714 (match_operand:SF 1 "general_no_elim_operand" "f,rFm,x"))] 2715 "!TARGET_64BIT" 2716{ 2717 /* Anything else should be already split before reg-stack. */ 2718 gcc_assert (which_alternative == 1); 2719 return "push{l}\t%1"; 2720} 2721 [(set_attr "type" "multi,push,multi") 2722 (set_attr "unit" "i387,*,*") 2723 (set_attr "mode" "SF,SI,SF")]) 2724 2725;; %%% Kill this when call knows how to work this out. 2726(define_split 2727 [(set (match_operand:SF 0 "push_operand" "") 2728 (match_operand:SF 1 "any_fp_register_operand" ""))] 2729 "reload_completed" 2730 [(set (reg:P SP_REG) (plus:P (reg:P SP_REG) (match_dup 2))) 2731 (set (mem:SF (reg:P SP_REG)) (match_dup 1))] 2732 "operands[2] = GEN_INT (-GET_MODE_SIZE (<P:MODE>mode));") 2733 2734(define_split 2735 [(set (match_operand:SF 0 "push_operand" "") 2736 (match_operand:SF 1 "memory_operand" ""))] 2737 "reload_completed 2738 && (operands[2] = find_constant_src (insn))" 2739 [(set (match_dup 0) (match_dup 2))]) 2740 2741(define_split 2742 [(set (match_operand 0 "push_operand" "") 2743 (match_operand 1 "general_operand" ""))] 2744 "reload_completed 2745 && (GET_MODE (operands[0]) == TFmode 2746 || GET_MODE (operands[0]) == XFmode 2747 || GET_MODE (operands[0]) == DFmode) 2748 && !ANY_FP_REG_P (operands[1])" 2749 [(const_int 0)] 2750 "ix86_split_long_move (operands); DONE;") 2751 2752;; Floating point move instructions. 2753 2754(define_expand "movtf" 2755 [(set (match_operand:TF 0 "nonimmediate_operand" "") 2756 (match_operand:TF 1 "nonimmediate_operand" ""))] 2757 "TARGET_64BIT || TARGET_SSE2" 2758{ 2759 ix86_expand_move (TFmode, operands); 2760 DONE; 2761}) 2762 2763(define_expand "mov<mode>" 2764 [(set (match_operand:X87MODEF 0 "nonimmediate_operand" "") 2765 (match_operand:X87MODEF 1 "general_operand" ""))] 2766 "" 2767 "ix86_expand_move (<MODE>mode, operands); DONE;") 2768 2769(define_insn "*movtf_internal_rex64" 2770 [(set (match_operand:TF 0 "nonimmediate_operand" "=x,m,x,?*r ,!o") 2771 (match_operand:TF 1 "general_operand" "xm,x,C,*roF,*r"))] 2772 "TARGET_64BIT && !(MEM_P (operands[0]) && MEM_P (operands[1])) 2773 && (!can_create_pseudo_p () 2774 || (ix86_cmodel == CM_MEDIUM || ix86_cmodel == CM_LARGE) 2775 || GET_CODE (operands[1]) != CONST_DOUBLE 2776 || (optimize_function_for_size_p (cfun) 2777 && standard_sse_constant_p (operands[1]) 2778 && !memory_operand (operands[0], TFmode)) 2779 || (!TARGET_MEMORY_MISMATCH_STALL 2780 && memory_operand (operands[0], TFmode)))" 2781{ 2782 switch (which_alternative) 2783 { 2784 case 0: 2785 case 1: 2786 /* Handle misaligned load/store since we 2787 don't have movmisaligntf pattern. */ 2788 if (misaligned_operand (operands[0], TFmode) 2789 || misaligned_operand (operands[1], TFmode)) 2790 { 2791 if (get_attr_mode (insn) == MODE_V4SF) 2792 return "%vmovups\t{%1, %0|%0, %1}"; 2793 else 2794 return "%vmovdqu\t{%1, %0|%0, %1}"; 2795 } 2796 else 2797 { 2798 if (get_attr_mode (insn) == MODE_V4SF) 2799 return "%vmovaps\t{%1, %0|%0, %1}"; 2800 else 2801 return "%vmovdqa\t{%1, %0|%0, %1}"; 2802 } 2803 2804 case 2: 2805 return standard_sse_constant_opcode (insn, operands[1]); 2806 2807 case 3: 2808 case 4: 2809 return "#"; 2810 2811 default: 2812 gcc_unreachable (); 2813 } 2814} 2815 [(set_attr "type" "ssemov,ssemov,sselog1,*,*") 2816 (set_attr "prefix" "maybe_vex,maybe_vex,maybe_vex,*,*") 2817 (set (attr "mode") 2818 (cond [(eq_attr "alternative" "0,2") 2819 (if_then_else 2820 (match_test "optimize_function_for_size_p (cfun)") 2821 (const_string "V4SF") 2822 (const_string "TI")) 2823 (eq_attr "alternative" "1") 2824 (if_then_else 2825 (ior (match_test "TARGET_SSE_TYPELESS_STORES") 2826 (match_test "optimize_function_for_size_p (cfun)")) 2827 (const_string "V4SF") 2828 (const_string "TI"))] 2829 (const_string "DI")))]) 2830 2831(define_insn "*movtf_internal_sse2" 2832 [(set (match_operand:TF 0 "nonimmediate_operand" "=x,m,x") 2833 (match_operand:TF 1 "general_operand" "xm,x,C"))] 2834 "TARGET_SSE2 && !TARGET_64BIT 2835 && !(MEM_P (operands[0]) && MEM_P (operands[1])) 2836 && (!can_create_pseudo_p () 2837 || (ix86_cmodel == CM_MEDIUM || ix86_cmodel == CM_LARGE) 2838 || GET_CODE (operands[1]) != CONST_DOUBLE 2839 || (optimize_function_for_size_p (cfun) 2840 && standard_sse_constant_p (operands[1]) 2841 && !memory_operand (operands[0], TFmode)) 2842 || (!TARGET_MEMORY_MISMATCH_STALL 2843 && memory_operand (operands[0], TFmode)))" 2844{ 2845 switch (which_alternative) 2846 { 2847 case 0: 2848 case 1: 2849 /* Handle misaligned load/store since we 2850 don't have movmisaligntf pattern. */ 2851 if (misaligned_operand (operands[0], TFmode) 2852 || misaligned_operand (operands[1], TFmode)) 2853 { 2854 if (get_attr_mode (insn) == MODE_V4SF) 2855 return "%vmovups\t{%1, %0|%0, %1}"; 2856 else 2857 return "%vmovdqu\t{%1, %0|%0, %1}"; 2858 } 2859 else 2860 { 2861 if (get_attr_mode (insn) == MODE_V4SF) 2862 return "%vmovaps\t{%1, %0|%0, %1}"; 2863 else 2864 return "%vmovdqa\t{%1, %0|%0, %1}"; 2865 } 2866 2867 case 2: 2868 return standard_sse_constant_opcode (insn, operands[1]); 2869 2870 default: 2871 gcc_unreachable (); 2872 } 2873} 2874 [(set_attr "type" "ssemov,ssemov,sselog1") 2875 (set_attr "prefix" "maybe_vex") 2876 (set (attr "mode") 2877 (cond [(eq_attr "alternative" "0,2") 2878 (if_then_else 2879 (match_test "optimize_function_for_size_p (cfun)") 2880 (const_string "V4SF") 2881 (const_string "TI")) 2882 (eq_attr "alternative" "1") 2883 (if_then_else 2884 (ior (match_test "TARGET_SSE_TYPELESS_STORES") 2885 (match_test "optimize_function_for_size_p (cfun)")) 2886 (const_string "V4SF") 2887 (const_string "TI"))] 2888 (const_string "DI")))]) 2889 2890(define_insn "*movxf_internal_rex64" 2891 [(set (match_operand:XF 0 "nonimmediate_operand" "=f,m,f,?Yx*r ,!o") 2892 (match_operand:XF 1 "general_operand" "fm,f,G,Yx*roF,Yx*rC"))] 2893 "TARGET_64BIT && !(MEM_P (operands[0]) && MEM_P (operands[1])) 2894 && (!can_create_pseudo_p () 2895 || (ix86_cmodel == CM_MEDIUM || ix86_cmodel == CM_LARGE) 2896 || GET_CODE (operands[1]) != CONST_DOUBLE 2897 || (optimize_function_for_size_p (cfun) 2898 && standard_80387_constant_p (operands[1]) > 0 2899 && !memory_operand (operands[0], XFmode)) 2900 || (!TARGET_MEMORY_MISMATCH_STALL 2901 && memory_operand (operands[0], XFmode)))" 2902{ 2903 switch (which_alternative) 2904 { 2905 case 0: 2906 case 1: 2907 return output_387_reg_move (insn, operands); 2908 2909 case 2: 2910 return standard_80387_constant_opcode (operands[1]); 2911 2912 case 3: 2913 case 4: 2914 return "#"; 2915 2916 default: 2917 gcc_unreachable (); 2918 } 2919} 2920 [(set_attr "type" "fmov,fmov,fmov,multi,multi") 2921 (set_attr "mode" "XF,XF,XF,SI,SI")]) 2922 2923;; Possible store forwarding (partial memory) stall in alternative 4. 2924(define_insn "*movxf_internal" 2925 [(set (match_operand:XF 0 "nonimmediate_operand" "=f,m,f,?Yx*r ,!o") 2926 (match_operand:XF 1 "general_operand" "fm,f,G,Yx*roF,Yx*rF"))] 2927 "!TARGET_64BIT && !(MEM_P (operands[0]) && MEM_P (operands[1])) 2928 && (!can_create_pseudo_p () 2929 || (ix86_cmodel == CM_MEDIUM || ix86_cmodel == CM_LARGE) 2930 || GET_CODE (operands[1]) != CONST_DOUBLE 2931 || (optimize_function_for_size_p (cfun) 2932 && standard_80387_constant_p (operands[1]) > 0 2933 && !memory_operand (operands[0], XFmode)) 2934 || (!TARGET_MEMORY_MISMATCH_STALL 2935 && memory_operand (operands[0], XFmode)))" 2936{ 2937 switch (which_alternative) 2938 { 2939 case 0: 2940 case 1: 2941 return output_387_reg_move (insn, operands); 2942 2943 case 2: 2944 return standard_80387_constant_opcode (operands[1]); 2945 2946 case 3: 2947 case 4: 2948 return "#"; 2949 2950 default: 2951 gcc_unreachable (); 2952 } 2953} 2954 [(set_attr "type" "fmov,fmov,fmov,multi,multi") 2955 (set_attr "mode" "XF,XF,XF,SI,SI")]) 2956 2957(define_insn "*movdf_internal_rex64" 2958 [(set (match_operand:DF 0 "nonimmediate_operand" 2959 "=?Yf*f,?m ,?Yf*f,?r,?m,?r,?r,x,x,x,m,Yi,r ") 2960 (match_operand:DF 1 "general_operand" 2961 "Yf*fm ,Yf*f ,G ,rm,rC,C ,F ,C,x,m,x,r ,Yi"))] 2962 "TARGET_64BIT && !(MEM_P (operands[0]) && MEM_P (operands[1])) 2963 && (!can_create_pseudo_p () 2964 || (ix86_cmodel == CM_MEDIUM || ix86_cmodel == CM_LARGE) 2965 || GET_CODE (operands[1]) != CONST_DOUBLE 2966 || (optimize_function_for_size_p (cfun) 2967 && ((!(TARGET_SSE2 && TARGET_SSE_MATH) 2968 && standard_80387_constant_p (operands[1]) > 0) 2969 || (TARGET_SSE2 && TARGET_SSE_MATH 2970 && standard_sse_constant_p (operands[1])))) 2971 || memory_operand (operands[0], DFmode))" 2972{ 2973 switch (which_alternative) 2974 { 2975 case 0: 2976 case 1: 2977 return output_387_reg_move (insn, operands); 2978 2979 case 2: 2980 return standard_80387_constant_opcode (operands[1]); 2981 2982 case 3: 2983 case 4: 2984 return "mov{q}\t{%1, %0|%0, %1}"; 2985 2986 case 5: 2987 return "mov{l}\t{%1, %k0|%k0, %1}"; 2988 2989 case 6: 2990 return "movabs{q}\t{%1, %0|%0, %1}"; 2991 2992 case 7: 2993 return standard_sse_constant_opcode (insn, operands[1]); 2994 2995 case 8: 2996 case 9: 2997 case 10: 2998 switch (get_attr_mode (insn)) 2999 { 3000 case MODE_V2DF: 3001 if (!TARGET_SSE_PACKED_SINGLE_INSN_OPTIMAL) 3002 return "%vmovapd\t{%1, %0|%0, %1}"; 3003 case MODE_V4SF: 3004 return "%vmovaps\t{%1, %0|%0, %1}"; 3005 3006 case MODE_DI: 3007 return "%vmovq\t{%1, %0|%0, %1}"; 3008 case MODE_DF: 3009 if (TARGET_AVX && REG_P (operands[0]) && REG_P (operands[1])) 3010 return "vmovsd\t{%1, %0, %0|%0, %0, %1}"; 3011 return "%vmovsd\t{%1, %0|%0, %1}"; 3012 case MODE_V1DF: 3013 return "%vmovlpd\t{%1, %d0|%d0, %1}"; 3014 case MODE_V2SF: 3015 return "%vmovlps\t{%1, %d0|%d0, %1}"; 3016 default: 3017 gcc_unreachable (); 3018 } 3019 3020 case 11: 3021 case 12: 3022 /* Handle broken assemblers that require movd instead of movq. */ 3023 return "%vmovd\t{%1, %0|%0, %1}"; 3024 3025 default: 3026 gcc_unreachable(); 3027 } 3028} 3029 [(set (attr "type") 3030 (cond [(eq_attr "alternative" "0,1,2") 3031 (const_string "fmov") 3032 (eq_attr "alternative" "3,4,5,6") 3033 (const_string "imov") 3034 (eq_attr "alternative" "7") 3035 (const_string "sselog1") 3036 ] 3037 (const_string "ssemov"))) 3038 (set (attr "modrm") 3039 (if_then_else 3040 (and (eq_attr "alternative" "6") (eq_attr "type" "imov")) 3041 (const_string "0") 3042 (const_string "*"))) 3043 (set (attr "length_immediate") 3044 (if_then_else 3045 (and (eq_attr "alternative" "6") (eq_attr "type" "imov")) 3046 (const_string "8") 3047 (const_string "*"))) 3048 (set (attr "prefix") 3049 (if_then_else (eq_attr "alternative" "0,1,2,3,4,5,6") 3050 (const_string "orig") 3051 (const_string "maybe_vex"))) 3052 (set (attr "prefix_data16") 3053 (if_then_else (eq_attr "mode" "V1DF") 3054 (const_string "1") 3055 (const_string "*"))) 3056 (set (attr "mode") 3057 (cond [(eq_attr "alternative" "0,1,2") 3058 (const_string "DF") 3059 (eq_attr "alternative" "3,4,6,11,12") 3060 (const_string "DI") 3061 (eq_attr "alternative" "5") 3062 (const_string "SI") 3063 3064 /* xorps is one byte shorter. */ 3065 (eq_attr "alternative" "7") 3066 (cond [(match_test "optimize_function_for_size_p (cfun)") 3067 (const_string "V4SF") 3068 (match_test "TARGET_SSE_LOAD0_BY_PXOR") 3069 (const_string "TI") 3070 ] 3071 (const_string "V2DF")) 3072 3073 /* For architectures resolving dependencies on 3074 whole SSE registers use APD move to break dependency 3075 chains, otherwise use short move to avoid extra work. 3076 3077 movaps encodes one byte shorter. */ 3078 (eq_attr "alternative" "8") 3079 (cond 3080 [(match_test "optimize_function_for_size_p (cfun)") 3081 (const_string "V4SF") 3082 (match_test "TARGET_SSE_PARTIAL_REG_DEPENDENCY") 3083 (const_string "V2DF") 3084 ] 3085 (const_string "DF")) 3086 /* For architectures resolving dependencies on register 3087 parts we may avoid extra work to zero out upper part 3088 of register. */ 3089 (eq_attr "alternative" "9") 3090 (if_then_else 3091 (match_test "TARGET_SSE_SPLIT_REGS") 3092 (const_string "V1DF") 3093 (const_string "DF")) 3094 ] 3095 (const_string "DF")))]) 3096 3097;; Possible store forwarding (partial memory) stall in alternative 4. 3098(define_insn "*movdf_internal" 3099 [(set (match_operand:DF 0 "nonimmediate_operand" 3100 "=Yf*f,m ,Yf*f,?Yd*r ,!o ,x,x,x,m,*x,*x,*x,m") 3101 (match_operand:DF 1 "general_operand" 3102 "Yf*fm,Yf*f,G ,Yd*roF,Yd*rF,C,x,m,x,C ,*x,m ,*x"))] 3103 "!TARGET_64BIT && !(MEM_P (operands[0]) && MEM_P (operands[1])) 3104 && (!can_create_pseudo_p () 3105 || (ix86_cmodel == CM_MEDIUM || ix86_cmodel == CM_LARGE) 3106 || GET_CODE (operands[1]) != CONST_DOUBLE 3107 || (optimize_function_for_size_p (cfun) 3108 && ((!(TARGET_SSE2 && TARGET_SSE_MATH) 3109 && standard_80387_constant_p (operands[1]) > 0) 3110 || (TARGET_SSE2 && TARGET_SSE_MATH 3111 && standard_sse_constant_p (operands[1]))) 3112 && !memory_operand (operands[0], DFmode)) 3113 || (!TARGET_MEMORY_MISMATCH_STALL 3114 && memory_operand (operands[0], DFmode)))" 3115{ 3116 switch (which_alternative) 3117 { 3118 case 0: 3119 case 1: 3120 return output_387_reg_move (insn, operands); 3121 3122 case 2: 3123 return standard_80387_constant_opcode (operands[1]); 3124 3125 case 3: 3126 case 4: 3127 return "#"; 3128 3129 case 5: 3130 case 9: 3131 return standard_sse_constant_opcode (insn, operands[1]); 3132 3133 case 6: 3134 case 7: 3135 case 8: 3136 case 10: 3137 case 11: 3138 case 12: 3139 switch (get_attr_mode (insn)) 3140 { 3141 case MODE_V2DF: 3142 if (!TARGET_SSE_PACKED_SINGLE_INSN_OPTIMAL) 3143 return "%vmovapd\t{%1, %0|%0, %1}"; 3144 case MODE_V4SF: 3145 return "%vmovaps\t{%1, %0|%0, %1}"; 3146 3147 case MODE_DI: 3148 return "%vmovq\t{%1, %0|%0, %1}"; 3149 case MODE_DF: 3150 if (TARGET_AVX && REG_P (operands[0]) && REG_P (operands[1])) 3151 return "vmovsd\t{%1, %0, %0|%0, %0, %1}"; 3152 return "%vmovsd\t{%1, %0|%0, %1}"; 3153 case MODE_V1DF: 3154 return "%vmovlpd\t{%1, %d0|%d0, %1}"; 3155 case MODE_V2SF: 3156 return "%vmovlps\t{%1, %d0|%d0, %1}"; 3157 default: 3158 gcc_unreachable (); 3159 } 3160 3161 default: 3162 gcc_unreachable (); 3163 } 3164} 3165 [(set (attr "isa") 3166 (if_then_else (eq_attr "alternative" "5,6,7,8") 3167 (const_string "sse2") 3168 (const_string "*"))) 3169 (set (attr "type") 3170 (cond [(eq_attr "alternative" "0,1,2") 3171 (const_string "fmov") 3172 (eq_attr "alternative" "3,4") 3173 (const_string "multi") 3174 (eq_attr "alternative" "5,9") 3175 (const_string "sselog1") 3176 ] 3177 (const_string "ssemov"))) 3178 (set (attr "prefix") 3179 (if_then_else (eq_attr "alternative" "0,1,2,3,4") 3180 (const_string "orig") 3181 (const_string "maybe_vex"))) 3182 (set (attr "prefix_data16") 3183 (if_then_else (eq_attr "mode" "V1DF") 3184 (const_string "1") 3185 (const_string "*"))) 3186 (set (attr "mode") 3187 (cond [(eq_attr "alternative" "0,1,2") 3188 (const_string "DF") 3189 (eq_attr "alternative" "3,4") 3190 (const_string "SI") 3191 3192 /* For SSE1, we have many fewer alternatives. */ 3193 (not (match_test "TARGET_SSE2")) 3194 (if_then_else 3195 (eq_attr "alternative" "5,6,9,10") 3196 (const_string "V4SF") 3197 (const_string "V2SF")) 3198 3199 /* xorps is one byte shorter. */ 3200 (eq_attr "alternative" "5,9") 3201 (cond [(match_test "optimize_function_for_size_p (cfun)") 3202 (const_string "V4SF") 3203 (match_test "TARGET_SSE_LOAD0_BY_PXOR") 3204 (const_string "TI") 3205 ] 3206 (const_string "V2DF")) 3207 3208 /* For architectures resolving dependencies on 3209 whole SSE registers use APD move to break dependency 3210 chains, otherwise use short move to avoid extra work. 3211 3212 movaps encodes one byte shorter. */ 3213 (eq_attr "alternative" "6,10") 3214 (cond 3215 [(match_test "optimize_function_for_size_p (cfun)") 3216 (const_string "V4SF") 3217 (match_test "TARGET_SSE_PARTIAL_REG_DEPENDENCY") 3218 (const_string "V2DF") 3219 ] 3220 (const_string "DF")) 3221 /* For architectures resolving dependencies on register 3222 parts we may avoid extra work to zero out upper part 3223 of register. */ 3224 (eq_attr "alternative" "7,11") 3225 (if_then_else 3226 (match_test "TARGET_SSE_SPLIT_REGS") 3227 (const_string "V1DF") 3228 (const_string "DF")) 3229 ] 3230 (const_string "DF")))]) 3231 3232(define_insn "*movsf_internal" 3233 [(set (match_operand:SF 0 "nonimmediate_operand" 3234 "=Yf*f,m ,Yf*f,?r ,?m,x,x,x,m,!*y,!m,!*y,?Yi,?r,!*Ym,!r") 3235 (match_operand:SF 1 "general_operand" 3236 "Yf*fm,Yf*f,G ,rmF,rF,C,x,m,x,m ,*y,*y ,r ,Yi,r ,*Ym"))] 3237 "!(MEM_P (operands[0]) && MEM_P (operands[1])) 3238 && (!can_create_pseudo_p () 3239 || (ix86_cmodel == CM_MEDIUM || ix86_cmodel == CM_LARGE) 3240 || GET_CODE (operands[1]) != CONST_DOUBLE 3241 || (optimize_function_for_size_p (cfun) 3242 && ((!TARGET_SSE_MATH 3243 && standard_80387_constant_p (operands[1]) > 0) 3244 || (TARGET_SSE_MATH 3245 && standard_sse_constant_p (operands[1])))) 3246 || memory_operand (operands[0], SFmode))" 3247{ 3248 switch (which_alternative) 3249 { 3250 case 0: 3251 case 1: 3252 return output_387_reg_move (insn, operands); 3253 3254 case 2: 3255 return standard_80387_constant_opcode (operands[1]); 3256 3257 case 3: 3258 case 4: 3259 return "mov{l}\t{%1, %0|%0, %1}"; 3260 3261 case 5: 3262 return standard_sse_constant_opcode (insn, operands[1]); 3263 3264 case 6: 3265 if (get_attr_mode (insn) == MODE_V4SF) 3266 return "%vmovaps\t{%1, %0|%0, %1}"; 3267 if (TARGET_AVX) 3268 return "vmovss\t{%1, %0, %0|%0, %0, %1}"; 3269 3270 case 7: 3271 case 8: 3272 return "%vmovss\t{%1, %0|%0, %1}"; 3273 3274 case 9: 3275 case 10: 3276 case 14: 3277 case 15: 3278 return "movd\t{%1, %0|%0, %1}"; 3279 3280 case 11: 3281 return "movq\t{%1, %0|%0, %1}"; 3282 3283 case 12: 3284 case 13: 3285 return "%vmovd\t{%1, %0|%0, %1}"; 3286 3287 default: 3288 gcc_unreachable (); 3289 } 3290} 3291 [(set (attr "type") 3292 (cond [(eq_attr "alternative" "0,1,2") 3293 (const_string "fmov") 3294 (eq_attr "alternative" "3,4") 3295 (const_string "imov") 3296 (eq_attr "alternative" "5") 3297 (const_string "sselog1") 3298 (eq_attr "alternative" "9,10,11,14,15") 3299 (const_string "mmxmov") 3300 ] 3301 (const_string "ssemov"))) 3302 (set (attr "prefix") 3303 (if_then_else (eq_attr "alternative" "5,6,7,8,12,13") 3304 (const_string "maybe_vex") 3305 (const_string "orig"))) 3306 (set (attr "mode") 3307 (cond [(eq_attr "alternative" "3,4,9,10") 3308 (const_string "SI") 3309 (eq_attr "alternative" "5") 3310 (if_then_else 3311 (and (and (match_test "TARGET_SSE_LOAD0_BY_PXOR") 3312 (match_test "TARGET_SSE2")) 3313 (not (match_test "optimize_function_for_size_p (cfun)"))) 3314 (const_string "TI") 3315 (const_string "V4SF")) 3316 /* For architectures resolving dependencies on 3317 whole SSE registers use APS move to break dependency 3318 chains, otherwise use short move to avoid extra work. 3319 3320 Do the same for architectures resolving dependencies on 3321 the parts. While in DF mode it is better to always handle 3322 just register parts, the SF mode is different due to lack 3323 of instructions to load just part of the register. It is 3324 better to maintain the whole registers in single format 3325 to avoid problems on using packed logical operations. */ 3326 (eq_attr "alternative" "6") 3327 (if_then_else 3328 (ior (match_test "TARGET_SSE_PARTIAL_REG_DEPENDENCY") 3329 (match_test "TARGET_SSE_SPLIT_REGS")) 3330 (const_string "V4SF") 3331 (const_string "SF")) 3332 (eq_attr "alternative" "11") 3333 (const_string "DI")] 3334 (const_string "SF")))]) 3335 3336(define_split 3337 [(set (match_operand 0 "any_fp_register_operand" "") 3338 (match_operand 1 "memory_operand" ""))] 3339 "reload_completed 3340 && (GET_MODE (operands[0]) == TFmode 3341 || GET_MODE (operands[0]) == XFmode 3342 || GET_MODE (operands[0]) == DFmode 3343 || GET_MODE (operands[0]) == SFmode) 3344 && (operands[2] = find_constant_src (insn))" 3345 [(set (match_dup 0) (match_dup 2))] 3346{ 3347 rtx c = operands[2]; 3348 int r = REGNO (operands[0]); 3349 3350 if ((SSE_REGNO_P (r) && !standard_sse_constant_p (c)) 3351 || (FP_REGNO_P (r) && standard_80387_constant_p (c) < 1)) 3352 FAIL; 3353}) 3354 3355(define_split 3356 [(set (match_operand 0 "any_fp_register_operand" "") 3357 (float_extend (match_operand 1 "memory_operand" "")))] 3358 "reload_completed 3359 && (GET_MODE (operands[0]) == TFmode 3360 || GET_MODE (operands[0]) == XFmode 3361 || GET_MODE (operands[0]) == DFmode) 3362 && (operands[2] = find_constant_src (insn))" 3363 [(set (match_dup 0) (match_dup 2))] 3364{ 3365 rtx c = operands[2]; 3366 int r = REGNO (operands[0]); 3367 3368 if ((SSE_REGNO_P (r) && !standard_sse_constant_p (c)) 3369 || (FP_REGNO_P (r) && standard_80387_constant_p (c) < 1)) 3370 FAIL; 3371}) 3372 3373;; Split the load of -0.0 or -1.0 into fldz;fchs or fld1;fchs sequence 3374(define_split 3375 [(set (match_operand:X87MODEF 0 "fp_register_operand" "") 3376 (match_operand:X87MODEF 1 "immediate_operand" ""))] 3377 "reload_completed 3378 && (standard_80387_constant_p (operands[1]) == 8 3379 || standard_80387_constant_p (operands[1]) == 9)" 3380 [(set (match_dup 0)(match_dup 1)) 3381 (set (match_dup 0) 3382 (neg:X87MODEF (match_dup 0)))] 3383{ 3384 REAL_VALUE_TYPE r; 3385 3386 REAL_VALUE_FROM_CONST_DOUBLE (r, operands[1]); 3387 if (real_isnegzero (&r)) 3388 operands[1] = CONST0_RTX (<MODE>mode); 3389 else 3390 operands[1] = CONST1_RTX (<MODE>mode); 3391}) 3392 3393(define_split 3394 [(set (match_operand 0 "nonimmediate_operand" "") 3395 (match_operand 1 "general_operand" ""))] 3396 "reload_completed 3397 && (GET_MODE (operands[0]) == TFmode 3398 || GET_MODE (operands[0]) == XFmode 3399 || GET_MODE (operands[0]) == DFmode) 3400 && !(ANY_FP_REG_P (operands[0]) || ANY_FP_REG_P (operands[1]))" 3401 [(const_int 0)] 3402 "ix86_split_long_move (operands); DONE;") 3403 3404(define_insn "swapxf" 3405 [(set (match_operand:XF 0 "register_operand" "+f") 3406 (match_operand:XF 1 "register_operand" "+f")) 3407 (set (match_dup 1) 3408 (match_dup 0))] 3409 "TARGET_80387" 3410{ 3411 if (STACK_TOP_P (operands[0])) 3412 return "fxch\t%1"; 3413 else 3414 return "fxch\t%0"; 3415} 3416 [(set_attr "type" "fxch") 3417 (set_attr "mode" "XF")]) 3418 3419(define_insn "*swap<mode>" 3420 [(set (match_operand:MODEF 0 "fp_register_operand" "+f") 3421 (match_operand:MODEF 1 "fp_register_operand" "+f")) 3422 (set (match_dup 1) 3423 (match_dup 0))] 3424 "TARGET_80387 || reload_completed" 3425{ 3426 if (STACK_TOP_P (operands[0])) 3427 return "fxch\t%1"; 3428 else 3429 return "fxch\t%0"; 3430} 3431 [(set_attr "type" "fxch") 3432 (set_attr "mode" "<MODE>")]) 3433 3434;; Zero extension instructions 3435 3436(define_expand "zero_extendsidi2" 3437 [(set (match_operand:DI 0 "nonimmediate_operand" "") 3438 (zero_extend:DI (match_operand:SI 1 "nonimmediate_operand" "")))] 3439 "" 3440{ 3441 if (!TARGET_64BIT) 3442 { 3443 emit_insn (gen_zero_extendsidi2_1 (operands[0], operands[1])); 3444 DONE; 3445 } 3446}) 3447 3448(define_insn "*zero_extendsidi2_rex64" 3449 [(set (match_operand:DI 0 "nonimmediate_operand" "=r,o,?*Ym,?!*y,?*Yi,*x") 3450 (zero_extend:DI 3451 (match_operand:SI 1 "nonimmediate_operand" "rm,0,r ,m ,r ,m")))] 3452 "TARGET_64BIT" 3453 "@ 3454 mov{l}\t{%1, %k0|%k0, %1} 3455 # 3456 movd\t{%1, %0|%0, %1} 3457 movd\t{%1, %0|%0, %1} 3458 %vmovd\t{%1, %0|%0, %1} 3459 %vmovd\t{%1, %0|%0, %1}" 3460 [(set_attr "type" "imovx,imov,mmxmov,mmxmov,ssemov,ssemov") 3461 (set_attr "prefix" "orig,*,orig,orig,maybe_vex,maybe_vex") 3462 (set_attr "prefix_0f" "0,*,*,*,*,*") 3463 (set_attr "mode" "SI,DI,DI,DI,TI,TI")]) 3464 3465(define_split 3466 [(set (match_operand:DI 0 "memory_operand" "") 3467 (zero_extend:DI (match_dup 0)))] 3468 "TARGET_64BIT" 3469 [(set (match_dup 4) (const_int 0))] 3470 "split_double_mode (DImode, &operands[0], 1, &operands[3], &operands[4]);") 3471 3472;; %%% Kill me once multi-word ops are sane. 3473(define_insn "zero_extendsidi2_1" 3474 [(set (match_operand:DI 0 "nonimmediate_operand" "=r,?r,?o,?*Ym,?!*y,?*Yi,*x") 3475 (zero_extend:DI 3476 (match_operand:SI 1 "nonimmediate_operand" "0,rm,r ,r ,m ,r ,m"))) 3477 (clobber (reg:CC FLAGS_REG))] 3478 "!TARGET_64BIT" 3479 "@ 3480 # 3481 # 3482 # 3483 movd\t{%1, %0|%0, %1} 3484 movd\t{%1, %0|%0, %1} 3485 %vmovd\t{%1, %0|%0, %1} 3486 %vmovd\t{%1, %0|%0, %1}" 3487 [(set_attr "isa" "*,*,*,*,*,*,sse2") 3488 (set_attr "type" "multi,multi,multi,mmxmov,mmxmov,ssemov,ssemov") 3489 (set_attr "prefix" "*,*,*,orig,orig,maybe_vex,maybe_vex") 3490 (set_attr "mode" "SI,SI,SI,DI,DI,TI,TI")]) 3491 3492(define_split 3493 [(set (match_operand:DI 0 "register_operand" "") 3494 (zero_extend:DI (match_operand:SI 1 "register_operand" ""))) 3495 (clobber (reg:CC FLAGS_REG))] 3496 "!TARGET_64BIT && reload_completed 3497 && true_regnum (operands[0]) == true_regnum (operands[1])" 3498 [(set (match_dup 4) (const_int 0))] 3499 "split_double_mode (DImode, &operands[0], 1, &operands[3], &operands[4]);") 3500 3501(define_split 3502 [(set (match_operand:DI 0 "nonimmediate_operand" "") 3503 (zero_extend:DI (match_operand:SI 1 "general_operand" ""))) 3504 (clobber (reg:CC FLAGS_REG))] 3505 "!TARGET_64BIT && reload_completed 3506 && !(MMX_REG_P (operands[0]) || SSE_REG_P (operands[0]))" 3507 [(set (match_dup 3) (match_dup 1)) 3508 (set (match_dup 4) (const_int 0))] 3509 "split_double_mode (DImode, &operands[0], 1, &operands[3], &operands[4]);") 3510 3511(define_insn "zero_extend<mode>di2" 3512 [(set (match_operand:DI 0 "register_operand" "=r") 3513 (zero_extend:DI 3514 (match_operand:SWI12 1 "nonimmediate_operand" "<r>m")))] 3515 "TARGET_64BIT" 3516 "movz{<imodesuffix>l|x}\t{%1, %k0|%k0, %1}" 3517 [(set_attr "type" "imovx") 3518 (set_attr "mode" "SI")]) 3519 3520(define_expand "zero_extendhisi2" 3521 [(set (match_operand:SI 0 "register_operand" "") 3522 (zero_extend:SI (match_operand:HI 1 "nonimmediate_operand" "")))] 3523 "" 3524{ 3525 if (TARGET_ZERO_EXTEND_WITH_AND && optimize_function_for_speed_p (cfun)) 3526 { 3527 operands[1] = force_reg (HImode, operands[1]); 3528 emit_insn (gen_zero_extendhisi2_and (operands[0], operands[1])); 3529 DONE; 3530 } 3531}) 3532 3533(define_insn_and_split "zero_extendhisi2_and" 3534 [(set (match_operand:SI 0 "register_operand" "=r") 3535 (zero_extend:SI (match_operand:HI 1 "register_operand" "0"))) 3536 (clobber (reg:CC FLAGS_REG))] 3537 "TARGET_ZERO_EXTEND_WITH_AND && optimize_function_for_speed_p (cfun)" 3538 "#" 3539 "&& reload_completed" 3540 [(parallel [(set (match_dup 0) (and:SI (match_dup 0) (const_int 65535))) 3541 (clobber (reg:CC FLAGS_REG))])] 3542 "" 3543 [(set_attr "type" "alu1") 3544 (set_attr "mode" "SI")]) 3545 3546(define_insn "*zero_extendhisi2_movzwl" 3547 [(set (match_operand:SI 0 "register_operand" "=r") 3548 (zero_extend:SI (match_operand:HI 1 "nonimmediate_operand" "rm")))] 3549 "!TARGET_ZERO_EXTEND_WITH_AND 3550 || optimize_function_for_size_p (cfun)" 3551 "movz{wl|x}\t{%1, %0|%0, %1}" 3552 [(set_attr "type" "imovx") 3553 (set_attr "mode" "SI")]) 3554 3555(define_expand "zero_extendqi<mode>2" 3556 [(parallel 3557 [(set (match_operand:SWI24 0 "register_operand" "") 3558 (zero_extend:SWI24 (match_operand:QI 1 "nonimmediate_operand" ""))) 3559 (clobber (reg:CC FLAGS_REG))])]) 3560 3561(define_insn "*zero_extendqi<mode>2_and" 3562 [(set (match_operand:SWI24 0 "register_operand" "=r,?&q") 3563 (zero_extend:SWI24 (match_operand:QI 1 "nonimmediate_operand" "0,qm"))) 3564 (clobber (reg:CC FLAGS_REG))] 3565 "TARGET_ZERO_EXTEND_WITH_AND && optimize_function_for_speed_p (cfun)" 3566 "#" 3567 [(set_attr "type" "alu1") 3568 (set_attr "mode" "<MODE>")]) 3569 3570;; When source and destination does not overlap, clear destination 3571;; first and then do the movb 3572(define_split 3573 [(set (match_operand:SWI24 0 "register_operand" "") 3574 (zero_extend:SWI24 (match_operand:QI 1 "nonimmediate_operand" ""))) 3575 (clobber (reg:CC FLAGS_REG))] 3576 "reload_completed 3577 && (TARGET_ZERO_EXTEND_WITH_AND && optimize_function_for_speed_p (cfun)) 3578 && ANY_QI_REG_P (operands[0]) 3579 && (ANY_QI_REG_P (operands[1]) || MEM_P (operands[1])) 3580 && !reg_overlap_mentioned_p (operands[0], operands[1])" 3581 [(set (strict_low_part (match_dup 2)) (match_dup 1))] 3582{ 3583 operands[2] = gen_lowpart (QImode, operands[0]); 3584 ix86_expand_clear (operands[0]); 3585}) 3586 3587(define_insn "*zero_extendqi<mode>2_movzbl_and" 3588 [(set (match_operand:SWI24 0 "register_operand" "=r,r") 3589 (zero_extend:SWI24 (match_operand:QI 1 "nonimmediate_operand" "qm,0"))) 3590 (clobber (reg:CC FLAGS_REG))] 3591 "!TARGET_ZERO_EXTEND_WITH_AND || optimize_function_for_size_p (cfun)" 3592 "#" 3593 [(set_attr "type" "imovx,alu1") 3594 (set_attr "mode" "<MODE>")]) 3595 3596;; For the movzbl case strip only the clobber 3597(define_split 3598 [(set (match_operand:SWI24 0 "register_operand" "") 3599 (zero_extend:SWI24 (match_operand:QI 1 "nonimmediate_operand" ""))) 3600 (clobber (reg:CC FLAGS_REG))] 3601 "reload_completed 3602 && (!TARGET_ZERO_EXTEND_WITH_AND || optimize_function_for_size_p (cfun)) 3603 && (!REG_P (operands[1]) || ANY_QI_REG_P (operands[1]))" 3604 [(set (match_dup 0) 3605 (zero_extend:SWI24 (match_dup 1)))]) 3606 3607; zero extend to SImode to avoid partial register stalls 3608(define_insn "*zero_extendqi<mode>2_movzbl" 3609 [(set (match_operand:SWI24 0 "register_operand" "=r") 3610 (zero_extend:SWI24 (match_operand:QI 1 "nonimmediate_operand" "qm")))] 3611 "reload_completed 3612 && (!TARGET_ZERO_EXTEND_WITH_AND || optimize_function_for_size_p (cfun))" 3613 "movz{bl|x}\t{%1, %k0|%k0, %1}" 3614 [(set_attr "type" "imovx") 3615 (set_attr "mode" "SI")]) 3616 3617;; Rest is handled by single and. 3618(define_split 3619 [(set (match_operand:SWI24 0 "register_operand" "") 3620 (zero_extend:SWI24 (match_operand:QI 1 "register_operand" ""))) 3621 (clobber (reg:CC FLAGS_REG))] 3622 "reload_completed 3623 && true_regnum (operands[0]) == true_regnum (operands[1])" 3624 [(parallel [(set (match_dup 0) (and:SWI24 (match_dup 0) (const_int 255))) 3625 (clobber (reg:CC FLAGS_REG))])]) 3626 3627;; Sign extension instructions 3628 3629(define_expand "extendsidi2" 3630 [(set (match_operand:DI 0 "register_operand" "") 3631 (sign_extend:DI (match_operand:SI 1 "register_operand" "")))] 3632 "" 3633{ 3634 if (!TARGET_64BIT) 3635 { 3636 emit_insn (gen_extendsidi2_1 (operands[0], operands[1])); 3637 DONE; 3638 } 3639}) 3640 3641(define_insn "*extendsidi2_rex64" 3642 [(set (match_operand:DI 0 "register_operand" "=*a,r") 3643 (sign_extend:DI (match_operand:SI 1 "nonimmediate_operand" "*0,rm")))] 3644 "TARGET_64BIT" 3645 "@ 3646 {cltq|cdqe} 3647 movs{lq|x}\t{%1, %0|%0, %1}" 3648 [(set_attr "type" "imovx") 3649 (set_attr "mode" "DI") 3650 (set_attr "prefix_0f" "0") 3651 (set_attr "modrm" "0,1")]) 3652 3653(define_insn "extendsidi2_1" 3654 [(set (match_operand:DI 0 "nonimmediate_operand" "=*A,r,?r,?*o") 3655 (sign_extend:DI (match_operand:SI 1 "register_operand" "0,0,r,r"))) 3656 (clobber (reg:CC FLAGS_REG)) 3657 (clobber (match_scratch:SI 2 "=X,X,X,&r"))] 3658 "!TARGET_64BIT" 3659 "#") 3660 3661;; Extend to memory case when source register does die. 3662(define_split 3663 [(set (match_operand:DI 0 "memory_operand" "") 3664 (sign_extend:DI (match_operand:SI 1 "register_operand" ""))) 3665 (clobber (reg:CC FLAGS_REG)) 3666 (clobber (match_operand:SI 2 "register_operand" ""))] 3667 "(reload_completed 3668 && dead_or_set_p (insn, operands[1]) 3669 && !reg_mentioned_p (operands[1], operands[0]))" 3670 [(set (match_dup 3) (match_dup 1)) 3671 (parallel [(set (match_dup 1) (ashiftrt:SI (match_dup 1) (const_int 31))) 3672 (clobber (reg:CC FLAGS_REG))]) 3673 (set (match_dup 4) (match_dup 1))] 3674 "split_double_mode (DImode, &operands[0], 1, &operands[3], &operands[4]);") 3675 3676;; Extend to memory case when source register does not die. 3677(define_split 3678 [(set (match_operand:DI 0 "memory_operand" "") 3679 (sign_extend:DI (match_operand:SI 1 "register_operand" ""))) 3680 (clobber (reg:CC FLAGS_REG)) 3681 (clobber (match_operand:SI 2 "register_operand" ""))] 3682 "reload_completed" 3683 [(const_int 0)] 3684{ 3685 split_double_mode (DImode, &operands[0], 1, &operands[3], &operands[4]); 3686 3687 emit_move_insn (operands[3], operands[1]); 3688 3689 /* Generate a cltd if possible and doing so it profitable. */ 3690 if ((optimize_function_for_size_p (cfun) || TARGET_USE_CLTD) 3691 && true_regnum (operands[1]) == AX_REG 3692 && true_regnum (operands[2]) == DX_REG) 3693 { 3694 emit_insn (gen_ashrsi3_cvt (operands[2], operands[1], GEN_INT (31))); 3695 } 3696 else 3697 { 3698 emit_move_insn (operands[2], operands[1]); 3699 emit_insn (gen_ashrsi3_cvt (operands[2], operands[2], GEN_INT (31))); 3700 } 3701 emit_move_insn (operands[4], operands[2]); 3702 DONE; 3703}) 3704 3705;; Extend to register case. Optimize case where source and destination 3706;; registers match and cases where we can use cltd. 3707(define_split 3708 [(set (match_operand:DI 0 "register_operand" "") 3709 (sign_extend:DI (match_operand:SI 1 "register_operand" ""))) 3710 (clobber (reg:CC FLAGS_REG)) 3711 (clobber (match_scratch:SI 2 ""))] 3712 "reload_completed" 3713 [(const_int 0)] 3714{ 3715 split_double_mode (DImode, &operands[0], 1, &operands[3], &operands[4]); 3716 3717 if (true_regnum (operands[3]) != true_regnum (operands[1])) 3718 emit_move_insn (operands[3], operands[1]); 3719 3720 /* Generate a cltd if possible and doing so it profitable. */ 3721 if ((optimize_function_for_size_p (cfun) || TARGET_USE_CLTD) 3722 && true_regnum (operands[3]) == AX_REG 3723 && true_regnum (operands[4]) == DX_REG) 3724 { 3725 emit_insn (gen_ashrsi3_cvt (operands[4], operands[3], GEN_INT (31))); 3726 DONE; 3727 } 3728 3729 if (true_regnum (operands[4]) != true_regnum (operands[1])) 3730 emit_move_insn (operands[4], operands[1]); 3731 3732 emit_insn (gen_ashrsi3_cvt (operands[4], operands[4], GEN_INT (31))); 3733 DONE; 3734}) 3735 3736(define_insn "extend<mode>di2" 3737 [(set (match_operand:DI 0 "register_operand" "=r") 3738 (sign_extend:DI 3739 (match_operand:SWI12 1 "nonimmediate_operand" "<r>m")))] 3740 "TARGET_64BIT" 3741 "movs{<imodesuffix>q|x}\t{%1, %0|%0, %1}" 3742 [(set_attr "type" "imovx") 3743 (set_attr "mode" "DI")]) 3744 3745(define_insn "extendhisi2" 3746 [(set (match_operand:SI 0 "register_operand" "=*a,r") 3747 (sign_extend:SI (match_operand:HI 1 "nonimmediate_operand" "*0,rm")))] 3748 "" 3749{ 3750 switch (get_attr_prefix_0f (insn)) 3751 { 3752 case 0: 3753 return "{cwtl|cwde}"; 3754 default: 3755 return "movs{wl|x}\t{%1, %0|%0, %1}"; 3756 } 3757} 3758 [(set_attr "type" "imovx") 3759 (set_attr "mode" "SI") 3760 (set (attr "prefix_0f") 3761 ;; movsx is short decodable while cwtl is vector decoded. 3762 (if_then_else (and (eq_attr "cpu" "!k6") 3763 (eq_attr "alternative" "0")) 3764 (const_string "0") 3765 (const_string "1"))) 3766 (set (attr "modrm") 3767 (if_then_else (eq_attr "prefix_0f" "0") 3768 (const_string "0") 3769 (const_string "1")))]) 3770 3771(define_insn "*extendhisi2_zext" 3772 [(set (match_operand:DI 0 "register_operand" "=*a,r") 3773 (zero_extend:DI 3774 (sign_extend:SI 3775 (match_operand:HI 1 "nonimmediate_operand" "*0,rm"))))] 3776 "TARGET_64BIT" 3777{ 3778 switch (get_attr_prefix_0f (insn)) 3779 { 3780 case 0: 3781 return "{cwtl|cwde}"; 3782 default: 3783 return "movs{wl|x}\t{%1, %k0|%k0, %1}"; 3784 } 3785} 3786 [(set_attr "type" "imovx") 3787 (set_attr "mode" "SI") 3788 (set (attr "prefix_0f") 3789 ;; movsx is short decodable while cwtl is vector decoded. 3790 (if_then_else (and (eq_attr "cpu" "!k6") 3791 (eq_attr "alternative" "0")) 3792 (const_string "0") 3793 (const_string "1"))) 3794 (set (attr "modrm") 3795 (if_then_else (eq_attr "prefix_0f" "0") 3796 (const_string "0") 3797 (const_string "1")))]) 3798 3799(define_insn "extendqisi2" 3800 [(set (match_operand:SI 0 "register_operand" "=r") 3801 (sign_extend:SI (match_operand:QI 1 "nonimmediate_operand" "qm")))] 3802 "" 3803 "movs{bl|x}\t{%1, %0|%0, %1}" 3804 [(set_attr "type" "imovx") 3805 (set_attr "mode" "SI")]) 3806 3807(define_insn "*extendqisi2_zext" 3808 [(set (match_operand:DI 0 "register_operand" "=r") 3809 (zero_extend:DI 3810 (sign_extend:SI (match_operand:QI 1 "nonimmediate_operand" "qm"))))] 3811 "TARGET_64BIT" 3812 "movs{bl|x}\t{%1, %k0|%k0, %1}" 3813 [(set_attr "type" "imovx") 3814 (set_attr "mode" "SI")]) 3815 3816(define_insn "extendqihi2" 3817 [(set (match_operand:HI 0 "register_operand" "=*a,r") 3818 (sign_extend:HI (match_operand:QI 1 "nonimmediate_operand" "*0,qm")))] 3819 "" 3820{ 3821 switch (get_attr_prefix_0f (insn)) 3822 { 3823 case 0: 3824 return "{cbtw|cbw}"; 3825 default: 3826 return "movs{bw|x}\t{%1, %0|%0, %1}"; 3827 } 3828} 3829 [(set_attr "type" "imovx") 3830 (set_attr "mode" "HI") 3831 (set (attr "prefix_0f") 3832 ;; movsx is short decodable while cwtl is vector decoded. 3833 (if_then_else (and (eq_attr "cpu" "!k6") 3834 (eq_attr "alternative" "0")) 3835 (const_string "0") 3836 (const_string "1"))) 3837 (set (attr "modrm") 3838 (if_then_else (eq_attr "prefix_0f" "0") 3839 (const_string "0") 3840 (const_string "1")))]) 3841 3842;; Conversions between float and double. 3843 3844;; These are all no-ops in the model used for the 80387. 3845;; So just emit moves. 3846 3847;; %%% Kill these when call knows how to work out a DFmode push earlier. 3848(define_split 3849 [(set (match_operand:DF 0 "push_operand" "") 3850 (float_extend:DF (match_operand:SF 1 "fp_register_operand" "")))] 3851 "reload_completed" 3852 [(set (reg:P SP_REG) (plus:P (reg:P SP_REG) (const_int -8))) 3853 (set (mem:DF (reg:P SP_REG)) (float_extend:DF (match_dup 1)))]) 3854 3855(define_split 3856 [(set (match_operand:XF 0 "push_operand" "") 3857 (float_extend:XF (match_operand:MODEF 1 "fp_register_operand" "")))] 3858 "reload_completed" 3859 [(set (reg:P SP_REG) (plus:P (reg:P SP_REG) (match_dup 2))) 3860 (set (mem:XF (reg:P SP_REG)) (float_extend:XF (match_dup 1)))] 3861 "operands[2] = GEN_INT (-GET_MODE_SIZE (XFmode));") 3862 3863(define_expand "extendsfdf2" 3864 [(set (match_operand:DF 0 "nonimmediate_operand" "") 3865 (float_extend:DF (match_operand:SF 1 "general_operand" "")))] 3866 "TARGET_80387 || (TARGET_SSE2 && TARGET_SSE_MATH)" 3867{ 3868 /* ??? Needed for compress_float_constant since all fp constants 3869 are TARGET_LEGITIMATE_CONSTANT_P. */ 3870 if (GET_CODE (operands[1]) == CONST_DOUBLE) 3871 { 3872 if ((!TARGET_SSE2 || TARGET_MIX_SSE_I387) 3873 && standard_80387_constant_p (operands[1]) > 0) 3874 { 3875 operands[1] = simplify_const_unary_operation 3876 (FLOAT_EXTEND, DFmode, operands[1], SFmode); 3877 emit_move_insn_1 (operands[0], operands[1]); 3878 DONE; 3879 } 3880 operands[1] = validize_mem (force_const_mem (SFmode, operands[1])); 3881 } 3882}) 3883 3884/* For converting SF(xmm2) to DF(xmm1), use the following code instead of 3885 cvtss2sd: 3886 unpcklps xmm2,xmm2 ; packed conversion might crash on signaling NaNs 3887 cvtps2pd xmm2,xmm1 3888 We do the conversion post reload to avoid producing of 128bit spills 3889 that might lead to ICE on 32bit target. The sequence unlikely combine 3890 anyway. */ 3891(define_split 3892 [(set (match_operand:DF 0 "register_operand" "") 3893 (float_extend:DF 3894 (match_operand:SF 1 "nonimmediate_operand" "")))] 3895 "TARGET_USE_VECTOR_FP_CONVERTS 3896 && optimize_insn_for_speed_p () 3897 && reload_completed && SSE_REG_P (operands[0])" 3898 [(set (match_dup 2) 3899 (float_extend:V2DF 3900 (vec_select:V2SF 3901 (match_dup 3) 3902 (parallel [(const_int 0) (const_int 1)]))))] 3903{ 3904 operands[2] = simplify_gen_subreg (V2DFmode, operands[0], DFmode, 0); 3905 operands[3] = simplify_gen_subreg (V4SFmode, operands[0], DFmode, 0); 3906 /* Use movss for loading from memory, unpcklps reg, reg for registers. 3907 Try to avoid move when unpacking can be done in source. */ 3908 if (REG_P (operands[1])) 3909 { 3910 /* If it is unsafe to overwrite upper half of source, we need 3911 to move to destination and unpack there. */ 3912 if ((ORIGINAL_REGNO (operands[1]) < FIRST_PSEUDO_REGISTER 3913 || PSEUDO_REGNO_BYTES (ORIGINAL_REGNO (operands[1])) > 4) 3914 && true_regnum (operands[0]) != true_regnum (operands[1])) 3915 { 3916 rtx tmp = gen_rtx_REG (SFmode, true_regnum (operands[0])); 3917 emit_move_insn (tmp, operands[1]); 3918 } 3919 else 3920 operands[3] = simplify_gen_subreg (V4SFmode, operands[1], SFmode, 0); 3921 emit_insn (gen_vec_interleave_lowv4sf (operands[3], operands[3], 3922 operands[3])); 3923 } 3924 else 3925 emit_insn (gen_vec_setv4sf_0 (operands[3], 3926 CONST0_RTX (V4SFmode), operands[1])); 3927}) 3928 3929(define_insn "*extendsfdf2_mixed" 3930 [(set (match_operand:DF 0 "nonimmediate_operand" "=f,m,x") 3931 (float_extend:DF 3932 (match_operand:SF 1 "nonimmediate_operand" "fm,f,xm")))] 3933 "TARGET_SSE2 && TARGET_MIX_SSE_I387" 3934{ 3935 switch (which_alternative) 3936 { 3937 case 0: 3938 case 1: 3939 return output_387_reg_move (insn, operands); 3940 3941 case 2: 3942 return "%vcvtss2sd\t{%1, %d0|%d0, %1}"; 3943 3944 default: 3945 gcc_unreachable (); 3946 } 3947} 3948 [(set_attr "type" "fmov,fmov,ssecvt") 3949 (set_attr "prefix" "orig,orig,maybe_vex") 3950 (set_attr "mode" "SF,XF,DF")]) 3951 3952(define_insn "*extendsfdf2_sse" 3953 [(set (match_operand:DF 0 "nonimmediate_operand" "=x") 3954 (float_extend:DF (match_operand:SF 1 "nonimmediate_operand" "xm")))] 3955 "TARGET_SSE2 && TARGET_SSE_MATH" 3956 "%vcvtss2sd\t{%1, %d0|%d0, %1}" 3957 [(set_attr "type" "ssecvt") 3958 (set_attr "prefix" "maybe_vex") 3959 (set_attr "mode" "DF")]) 3960 3961(define_insn "*extendsfdf2_i387" 3962 [(set (match_operand:DF 0 "nonimmediate_operand" "=f,m") 3963 (float_extend:DF (match_operand:SF 1 "nonimmediate_operand" "fm,f")))] 3964 "TARGET_80387" 3965 "* return output_387_reg_move (insn, operands);" 3966 [(set_attr "type" "fmov") 3967 (set_attr "mode" "SF,XF")]) 3968 3969(define_expand "extend<mode>xf2" 3970 [(set (match_operand:XF 0 "nonimmediate_operand" "") 3971 (float_extend:XF (match_operand:MODEF 1 "general_operand" "")))] 3972 "TARGET_80387" 3973{ 3974 /* ??? Needed for compress_float_constant since all fp constants 3975 are TARGET_LEGITIMATE_CONSTANT_P. */ 3976 if (GET_CODE (operands[1]) == CONST_DOUBLE) 3977 { 3978 if (standard_80387_constant_p (operands[1]) > 0) 3979 { 3980 operands[1] = simplify_const_unary_operation 3981 (FLOAT_EXTEND, XFmode, operands[1], <MODE>mode); 3982 emit_move_insn_1 (operands[0], operands[1]); 3983 DONE; 3984 } 3985 operands[1] = validize_mem (force_const_mem (<MODE>mode, operands[1])); 3986 } 3987}) 3988 3989(define_insn "*extend<mode>xf2_i387" 3990 [(set (match_operand:XF 0 "nonimmediate_operand" "=f,m") 3991 (float_extend:XF 3992 (match_operand:MODEF 1 "nonimmediate_operand" "fm,f")))] 3993 "TARGET_80387" 3994 "* return output_387_reg_move (insn, operands);" 3995 [(set_attr "type" "fmov") 3996 (set_attr "mode" "<MODE>,XF")]) 3997 3998;; %%% This seems bad bad news. 3999;; This cannot output into an f-reg because there is no way to be sure 4000;; of truncating in that case. Otherwise this is just like a simple move 4001;; insn. So we pretend we can output to a reg in order to get better 4002;; register preferencing, but we really use a stack slot. 4003 4004;; Conversion from DFmode to SFmode. 4005 4006(define_expand "truncdfsf2" 4007 [(set (match_operand:SF 0 "nonimmediate_operand" "") 4008 (float_truncate:SF 4009 (match_operand:DF 1 "nonimmediate_operand" "")))] 4010 "TARGET_80387 || (TARGET_SSE2 && TARGET_SSE_MATH)" 4011{ 4012 if (TARGET_SSE2 && TARGET_SSE_MATH && !TARGET_MIX_SSE_I387) 4013 ; 4014 else if (flag_unsafe_math_optimizations) 4015 ; 4016 else 4017 { 4018 rtx temp = assign_386_stack_local (SFmode, SLOT_TEMP); 4019 emit_insn (gen_truncdfsf2_with_temp (operands[0], operands[1], temp)); 4020 DONE; 4021 } 4022}) 4023 4024/* For converting DF(xmm2) to SF(xmm1), use the following code instead of 4025 cvtsd2ss: 4026 unpcklpd xmm2,xmm2 ; packed conversion might crash on signaling NaNs 4027 cvtpd2ps xmm2,xmm1 4028 We do the conversion post reload to avoid producing of 128bit spills 4029 that might lead to ICE on 32bit target. The sequence unlikely combine 4030 anyway. */ 4031(define_split 4032 [(set (match_operand:SF 0 "register_operand" "") 4033 (float_truncate:SF 4034 (match_operand:DF 1 "nonimmediate_operand" "")))] 4035 "TARGET_USE_VECTOR_FP_CONVERTS 4036 && optimize_insn_for_speed_p () 4037 && reload_completed && SSE_REG_P (operands[0])" 4038 [(set (match_dup 2) 4039 (vec_concat:V4SF 4040 (float_truncate:V2SF 4041 (match_dup 4)) 4042 (match_dup 3)))] 4043{ 4044 operands[2] = simplify_gen_subreg (V4SFmode, operands[0], SFmode, 0); 4045 operands[3] = CONST0_RTX (V2SFmode); 4046 operands[4] = simplify_gen_subreg (V2DFmode, operands[0], SFmode, 0); 4047 /* Use movsd for loading from memory, unpcklpd for registers. 4048 Try to avoid move when unpacking can be done in source, or SSE3 4049 movddup is available. */ 4050 if (REG_P (operands[1])) 4051 { 4052 if (!TARGET_SSE3 4053 && true_regnum (operands[0]) != true_regnum (operands[1]) 4054 && (ORIGINAL_REGNO (operands[1]) < FIRST_PSEUDO_REGISTER 4055 || PSEUDO_REGNO_BYTES (ORIGINAL_REGNO (operands[1])) > 8)) 4056 { 4057 rtx tmp = simplify_gen_subreg (DFmode, operands[0], SFmode, 0); 4058 emit_move_insn (tmp, operands[1]); 4059 operands[1] = tmp; 4060 } 4061 else if (!TARGET_SSE3) 4062 operands[4] = simplify_gen_subreg (V2DFmode, operands[1], DFmode, 0); 4063 emit_insn (gen_vec_dupv2df (operands[4], operands[1])); 4064 } 4065 else 4066 emit_insn (gen_sse2_loadlpd (operands[4], 4067 CONST0_RTX (V2DFmode), operands[1])); 4068}) 4069 4070(define_expand "truncdfsf2_with_temp" 4071 [(parallel [(set (match_operand:SF 0 "" "") 4072 (float_truncate:SF (match_operand:DF 1 "" ""))) 4073 (clobber (match_operand:SF 2 "" ""))])]) 4074 4075(define_insn "*truncdfsf_fast_mixed" 4076 [(set (match_operand:SF 0 "nonimmediate_operand" "=fm,x") 4077 (float_truncate:SF 4078 (match_operand:DF 1 "nonimmediate_operand" "f ,xm")))] 4079 "TARGET_SSE2 && TARGET_MIX_SSE_I387 && flag_unsafe_math_optimizations" 4080{ 4081 switch (which_alternative) 4082 { 4083 case 0: 4084 return output_387_reg_move (insn, operands); 4085 case 1: 4086 return "%vcvtsd2ss\t{%1, %d0|%d0, %1}"; 4087 default: 4088 gcc_unreachable (); 4089 } 4090} 4091 [(set_attr "type" "fmov,ssecvt") 4092 (set_attr "prefix" "orig,maybe_vex") 4093 (set_attr "mode" "SF")]) 4094 4095;; Yes, this one doesn't depend on flag_unsafe_math_optimizations, 4096;; because nothing we do here is unsafe. 4097(define_insn "*truncdfsf_fast_sse" 4098 [(set (match_operand:SF 0 "nonimmediate_operand" "=x") 4099 (float_truncate:SF 4100 (match_operand:DF 1 "nonimmediate_operand" "xm")))] 4101 "TARGET_SSE2 && TARGET_SSE_MATH" 4102 "%vcvtsd2ss\t{%1, %d0|%d0, %1}" 4103 [(set_attr "type" "ssecvt") 4104 (set_attr "prefix" "maybe_vex") 4105 (set_attr "mode" "SF")]) 4106 4107(define_insn "*truncdfsf_fast_i387" 4108 [(set (match_operand:SF 0 "nonimmediate_operand" "=fm") 4109 (float_truncate:SF 4110 (match_operand:DF 1 "nonimmediate_operand" "f")))] 4111 "TARGET_80387 && flag_unsafe_math_optimizations" 4112 "* return output_387_reg_move (insn, operands);" 4113 [(set_attr "type" "fmov") 4114 (set_attr "mode" "SF")]) 4115 4116(define_insn "*truncdfsf_mixed" 4117 [(set (match_operand:SF 0 "nonimmediate_operand" "=m,x ,?f,?x,?*r") 4118 (float_truncate:SF 4119 (match_operand:DF 1 "nonimmediate_operand" "f ,xm,f ,f ,f"))) 4120 (clobber (match_operand:SF 2 "memory_operand" "=X,X ,m ,m ,m"))] 4121 "TARGET_MIX_SSE_I387" 4122{ 4123 switch (which_alternative) 4124 { 4125 case 0: 4126 return output_387_reg_move (insn, operands); 4127 case 1: 4128 return "%vcvtsd2ss\t{%1, %d0|%d0, %1}"; 4129 4130 default: 4131 return "#"; 4132 } 4133} 4134 [(set_attr "isa" "*,sse2,*,*,*") 4135 (set_attr "type" "fmov,ssecvt,multi,multi,multi") 4136 (set_attr "unit" "*,*,i387,i387,i387") 4137 (set_attr "prefix" "orig,maybe_vex,orig,orig,orig") 4138 (set_attr "mode" "SF")]) 4139 4140(define_insn "*truncdfsf_i387" 4141 [(set (match_operand:SF 0 "nonimmediate_operand" "=m,?f,?x,?*r") 4142 (float_truncate:SF 4143 (match_operand:DF 1 "nonimmediate_operand" "f ,f ,f ,f"))) 4144 (clobber (match_operand:SF 2 "memory_operand" "=X,m ,m ,m"))] 4145 "TARGET_80387" 4146{ 4147 switch (which_alternative) 4148 { 4149 case 0: 4150 return output_387_reg_move (insn, operands); 4151 4152 default: 4153 return "#"; 4154 } 4155} 4156 [(set_attr "type" "fmov,multi,multi,multi") 4157 (set_attr "unit" "*,i387,i387,i387") 4158 (set_attr "mode" "SF")]) 4159 4160(define_insn "*truncdfsf2_i387_1" 4161 [(set (match_operand:SF 0 "memory_operand" "=m") 4162 (float_truncate:SF 4163 (match_operand:DF 1 "register_operand" "f")))] 4164 "TARGET_80387 4165 && !(TARGET_SSE2 && TARGET_SSE_MATH) 4166 && !TARGET_MIX_SSE_I387" 4167 "* return output_387_reg_move (insn, operands);" 4168 [(set_attr "type" "fmov") 4169 (set_attr "mode" "SF")]) 4170 4171(define_split 4172 [(set (match_operand:SF 0 "register_operand" "") 4173 (float_truncate:SF 4174 (match_operand:DF 1 "fp_register_operand" ""))) 4175 (clobber (match_operand 2 "" ""))] 4176 "reload_completed" 4177 [(set (match_dup 2) (match_dup 1)) 4178 (set (match_dup 0) (match_dup 2))] 4179 "operands[1] = gen_rtx_REG (SFmode, true_regnum (operands[1]));") 4180 4181;; Conversion from XFmode to {SF,DF}mode 4182 4183(define_expand "truncxf<mode>2" 4184 [(parallel [(set (match_operand:MODEF 0 "nonimmediate_operand" "") 4185 (float_truncate:MODEF 4186 (match_operand:XF 1 "register_operand" ""))) 4187 (clobber (match_dup 2))])] 4188 "TARGET_80387" 4189{ 4190 if (flag_unsafe_math_optimizations) 4191 { 4192 rtx reg = REG_P (operands[0]) ? operands[0] : gen_reg_rtx (<MODE>mode); 4193 emit_insn (gen_truncxf<mode>2_i387_noop (reg, operands[1])); 4194 if (reg != operands[0]) 4195 emit_move_insn (operands[0], reg); 4196 DONE; 4197 } 4198 else 4199 operands[2] = assign_386_stack_local (<MODE>mode, SLOT_TEMP); 4200}) 4201 4202(define_insn "*truncxfsf2_mixed" 4203 [(set (match_operand:SF 0 "nonimmediate_operand" "=m,?f,?x,?*r") 4204 (float_truncate:SF 4205 (match_operand:XF 1 "register_operand" "f ,f ,f ,f"))) 4206 (clobber (match_operand:SF 2 "memory_operand" "=X,m ,m ,m"))] 4207 "TARGET_80387" 4208{ 4209 gcc_assert (!which_alternative); 4210 return output_387_reg_move (insn, operands); 4211} 4212 [(set_attr "type" "fmov,multi,multi,multi") 4213 (set_attr "unit" "*,i387,i387,i387") 4214 (set_attr "mode" "SF")]) 4215 4216(define_insn "*truncxfdf2_mixed" 4217 [(set (match_operand:DF 0 "nonimmediate_operand" "=m,?f,?x,?*r") 4218 (float_truncate:DF 4219 (match_operand:XF 1 "register_operand" "f ,f ,f ,f"))) 4220 (clobber (match_operand:DF 2 "memory_operand" "=X,m ,m ,m"))] 4221 "TARGET_80387" 4222{ 4223 gcc_assert (!which_alternative); 4224 return output_387_reg_move (insn, operands); 4225} 4226 [(set_attr "isa" "*,*,sse2,*") 4227 (set_attr "type" "fmov,multi,multi,multi") 4228 (set_attr "unit" "*,i387,i387,i387") 4229 (set_attr "mode" "DF")]) 4230 4231(define_insn "truncxf<mode>2_i387_noop" 4232 [(set (match_operand:MODEF 0 "register_operand" "=f") 4233 (float_truncate:MODEF 4234 (match_operand:XF 1 "register_operand" "f")))] 4235 "TARGET_80387 && flag_unsafe_math_optimizations" 4236 "* return output_387_reg_move (insn, operands);" 4237 [(set_attr "type" "fmov") 4238 (set_attr "mode" "<MODE>")]) 4239 4240(define_insn "*truncxf<mode>2_i387" 4241 [(set (match_operand:MODEF 0 "memory_operand" "=m") 4242 (float_truncate:MODEF 4243 (match_operand:XF 1 "register_operand" "f")))] 4244 "TARGET_80387" 4245 "* return output_387_reg_move (insn, operands);" 4246 [(set_attr "type" "fmov") 4247 (set_attr "mode" "<MODE>")]) 4248 4249(define_split 4250 [(set (match_operand:MODEF 0 "register_operand" "") 4251 (float_truncate:MODEF 4252 (match_operand:XF 1 "register_operand" ""))) 4253 (clobber (match_operand:MODEF 2 "memory_operand" ""))] 4254 "TARGET_80387 && reload_completed" 4255 [(set (match_dup 2) (float_truncate:MODEF (match_dup 1))) 4256 (set (match_dup 0) (match_dup 2))]) 4257 4258(define_split 4259 [(set (match_operand:MODEF 0 "memory_operand" "") 4260 (float_truncate:MODEF 4261 (match_operand:XF 1 "register_operand" ""))) 4262 (clobber (match_operand:MODEF 2 "memory_operand" ""))] 4263 "TARGET_80387" 4264 [(set (match_dup 0) (float_truncate:MODEF (match_dup 1)))]) 4265 4266;; Signed conversion to DImode. 4267 4268(define_expand "fix_truncxfdi2" 4269 [(parallel [(set (match_operand:DI 0 "nonimmediate_operand" "") 4270 (fix:DI (match_operand:XF 1 "register_operand" ""))) 4271 (clobber (reg:CC FLAGS_REG))])] 4272 "TARGET_80387" 4273{ 4274 if (TARGET_FISTTP) 4275 { 4276 emit_insn (gen_fix_truncdi_fisttp_i387_1 (operands[0], operands[1])); 4277 DONE; 4278 } 4279}) 4280 4281(define_expand "fix_trunc<mode>di2" 4282 [(parallel [(set (match_operand:DI 0 "nonimmediate_operand" "") 4283 (fix:DI (match_operand:MODEF 1 "register_operand" ""))) 4284 (clobber (reg:CC FLAGS_REG))])] 4285 "TARGET_80387 || (TARGET_64BIT && SSE_FLOAT_MODE_P (<MODE>mode))" 4286{ 4287 if (TARGET_FISTTP 4288 && !(TARGET_64BIT && SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)) 4289 { 4290 emit_insn (gen_fix_truncdi_fisttp_i387_1 (operands[0], operands[1])); 4291 DONE; 4292 } 4293 if (TARGET_64BIT && SSE_FLOAT_MODE_P (<MODE>mode)) 4294 { 4295 rtx out = REG_P (operands[0]) ? operands[0] : gen_reg_rtx (DImode); 4296 emit_insn (gen_fix_trunc<mode>di_sse (out, operands[1])); 4297 if (out != operands[0]) 4298 emit_move_insn (operands[0], out); 4299 DONE; 4300 } 4301}) 4302 4303;; Signed conversion to SImode. 4304 4305(define_expand "fix_truncxfsi2" 4306 [(parallel [(set (match_operand:SI 0 "nonimmediate_operand" "") 4307 (fix:SI (match_operand:XF 1 "register_operand" ""))) 4308 (clobber (reg:CC FLAGS_REG))])] 4309 "TARGET_80387" 4310{ 4311 if (TARGET_FISTTP) 4312 { 4313 emit_insn (gen_fix_truncsi_fisttp_i387_1 (operands[0], operands[1])); 4314 DONE; 4315 } 4316}) 4317 4318(define_expand "fix_trunc<mode>si2" 4319 [(parallel [(set (match_operand:SI 0 "nonimmediate_operand" "") 4320 (fix:SI (match_operand:MODEF 1 "register_operand" ""))) 4321 (clobber (reg:CC FLAGS_REG))])] 4322 "TARGET_80387 || SSE_FLOAT_MODE_P (<MODE>mode)" 4323{ 4324 if (TARGET_FISTTP 4325 && !(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)) 4326 { 4327 emit_insn (gen_fix_truncsi_fisttp_i387_1 (operands[0], operands[1])); 4328 DONE; 4329 } 4330 if (SSE_FLOAT_MODE_P (<MODE>mode)) 4331 { 4332 rtx out = REG_P (operands[0]) ? operands[0] : gen_reg_rtx (SImode); 4333 emit_insn (gen_fix_trunc<mode>si_sse (out, operands[1])); 4334 if (out != operands[0]) 4335 emit_move_insn (operands[0], out); 4336 DONE; 4337 } 4338}) 4339 4340;; Signed conversion to HImode. 4341 4342(define_expand "fix_trunc<mode>hi2" 4343 [(parallel [(set (match_operand:HI 0 "nonimmediate_operand" "") 4344 (fix:HI (match_operand:X87MODEF 1 "register_operand" ""))) 4345 (clobber (reg:CC FLAGS_REG))])] 4346 "TARGET_80387 4347 && !(SSE_FLOAT_MODE_P (<MODE>mode) && (!TARGET_FISTTP || TARGET_SSE_MATH))" 4348{ 4349 if (TARGET_FISTTP) 4350 { 4351 emit_insn (gen_fix_trunchi_fisttp_i387_1 (operands[0], operands[1])); 4352 DONE; 4353 } 4354}) 4355 4356;; Unsigned conversion to SImode. 4357 4358(define_expand "fixuns_trunc<mode>si2" 4359 [(parallel 4360 [(set (match_operand:SI 0 "register_operand" "") 4361 (unsigned_fix:SI 4362 (match_operand:MODEF 1 "nonimmediate_operand" ""))) 4363 (use (match_dup 2)) 4364 (clobber (match_scratch:<ssevecmode> 3 "")) 4365 (clobber (match_scratch:<ssevecmode> 4 ""))])] 4366 "!TARGET_64BIT && TARGET_SSE2 && TARGET_SSE_MATH" 4367{ 4368 enum machine_mode mode = <MODE>mode; 4369 enum machine_mode vecmode = <ssevecmode>mode; 4370 REAL_VALUE_TYPE TWO31r; 4371 rtx two31; 4372 4373 if (optimize_insn_for_size_p ()) 4374 FAIL; 4375 4376 real_ldexp (&TWO31r, &dconst1, 31); 4377 two31 = const_double_from_real_value (TWO31r, mode); 4378 two31 = ix86_build_const_vector (vecmode, true, two31); 4379 operands[2] = force_reg (vecmode, two31); 4380}) 4381 4382(define_insn_and_split "*fixuns_trunc<mode>_1" 4383 [(set (match_operand:SI 0 "register_operand" "=&x,&x") 4384 (unsigned_fix:SI 4385 (match_operand:MODEF 3 "nonimmediate_operand" "xm,xm"))) 4386 (use (match_operand:<ssevecmode> 4 "nonimmediate_operand" "m,x")) 4387 (clobber (match_scratch:<ssevecmode> 1 "=x,&x")) 4388 (clobber (match_scratch:<ssevecmode> 2 "=x,x"))] 4389 "!TARGET_64BIT && TARGET_SSE2 && TARGET_SSE_MATH 4390 && optimize_function_for_speed_p (cfun)" 4391 "#" 4392 "&& reload_completed" 4393 [(const_int 0)] 4394{ 4395 ix86_split_convert_uns_si_sse (operands); 4396 DONE; 4397}) 4398 4399;; Unsigned conversion to HImode. 4400;; Without these patterns, we'll try the unsigned SI conversion which 4401;; is complex for SSE, rather than the signed SI conversion, which isn't. 4402 4403(define_expand "fixuns_trunc<mode>hi2" 4404 [(set (match_dup 2) 4405 (fix:SI (match_operand:MODEF 1 "nonimmediate_operand" ""))) 4406 (set (match_operand:HI 0 "nonimmediate_operand" "") 4407 (subreg:HI (match_dup 2) 0))] 4408 "SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH" 4409 "operands[2] = gen_reg_rtx (SImode);") 4410 4411;; When SSE is available, it is always faster to use it! 4412(define_insn "fix_trunc<mode>di_sse" 4413 [(set (match_operand:DI 0 "register_operand" "=r,r") 4414 (fix:DI (match_operand:MODEF 1 "nonimmediate_operand" "x,m")))] 4415 "TARGET_64BIT && SSE_FLOAT_MODE_P (<MODE>mode) 4416 && (!TARGET_FISTTP || TARGET_SSE_MATH)" 4417 "%vcvtt<ssemodesuffix>2si{q}\t{%1, %0|%0, %1}" 4418 [(set_attr "type" "sseicvt") 4419 (set_attr "prefix" "maybe_vex") 4420 (set_attr "prefix_rex" "1") 4421 (set_attr "mode" "<MODE>") 4422 (set_attr "athlon_decode" "double,vector") 4423 (set_attr "amdfam10_decode" "double,double") 4424 (set_attr "bdver1_decode" "double,double")]) 4425 4426(define_insn "fix_trunc<mode>si_sse" 4427 [(set (match_operand:SI 0 "register_operand" "=r,r") 4428 (fix:SI (match_operand:MODEF 1 "nonimmediate_operand" "x,m")))] 4429 "SSE_FLOAT_MODE_P (<MODE>mode) 4430 && (!TARGET_FISTTP || TARGET_SSE_MATH)" 4431 "%vcvtt<ssemodesuffix>2si\t{%1, %0|%0, %1}" 4432 [(set_attr "type" "sseicvt") 4433 (set_attr "prefix" "maybe_vex") 4434 (set_attr "mode" "<MODE>") 4435 (set_attr "athlon_decode" "double,vector") 4436 (set_attr "amdfam10_decode" "double,double") 4437 (set_attr "bdver1_decode" "double,double")]) 4438 4439;; Shorten x87->SSE reload sequences of fix_trunc?f?i_sse patterns. 4440(define_peephole2 4441 [(set (match_operand:MODEF 0 "register_operand" "") 4442 (match_operand:MODEF 1 "memory_operand" "")) 4443 (set (match_operand:SWI48x 2 "register_operand" "") 4444 (fix:SWI48x (match_dup 0)))] 4445 "TARGET_SHORTEN_X87_SSE 4446 && !(TARGET_AVOID_VECTOR_DECODE && optimize_insn_for_speed_p ()) 4447 && peep2_reg_dead_p (2, operands[0])" 4448 [(set (match_dup 2) (fix:SWI48x (match_dup 1)))]) 4449 4450;; Avoid vector decoded forms of the instruction. 4451(define_peephole2 4452 [(match_scratch:DF 2 "x") 4453 (set (match_operand:SWI48x 0 "register_operand" "") 4454 (fix:SWI48x (match_operand:DF 1 "memory_operand" "")))] 4455 "TARGET_SSE2 && TARGET_AVOID_VECTOR_DECODE && optimize_insn_for_speed_p ()" 4456 [(set (match_dup 2) (match_dup 1)) 4457 (set (match_dup 0) (fix:SWI48x (match_dup 2)))]) 4458 4459(define_peephole2 4460 [(match_scratch:SF 2 "x") 4461 (set (match_operand:SWI48x 0 "register_operand" "") 4462 (fix:SWI48x (match_operand:SF 1 "memory_operand" "")))] 4463 "TARGET_AVOID_VECTOR_DECODE && optimize_insn_for_speed_p ()" 4464 [(set (match_dup 2) (match_dup 1)) 4465 (set (match_dup 0) (fix:SWI48x (match_dup 2)))]) 4466 4467(define_insn_and_split "fix_trunc<mode>_fisttp_i387_1" 4468 [(set (match_operand:SWI248x 0 "nonimmediate_operand" "") 4469 (fix:SWI248x (match_operand 1 "register_operand" "")))] 4470 "X87_FLOAT_MODE_P (GET_MODE (operands[1])) 4471 && TARGET_FISTTP 4472 && !((SSE_FLOAT_MODE_P (GET_MODE (operands[1])) 4473 && (TARGET_64BIT || <MODE>mode != DImode)) 4474 && TARGET_SSE_MATH) 4475 && can_create_pseudo_p ()" 4476 "#" 4477 "&& 1" 4478 [(const_int 0)] 4479{ 4480 if (memory_operand (operands[0], VOIDmode)) 4481 emit_insn (gen_fix_trunc<mode>_i387_fisttp (operands[0], operands[1])); 4482 else 4483 { 4484 operands[2] = assign_386_stack_local (<MODE>mode, SLOT_TEMP); 4485 emit_insn (gen_fix_trunc<mode>_i387_fisttp_with_temp (operands[0], 4486 operands[1], 4487 operands[2])); 4488 } 4489 DONE; 4490} 4491 [(set_attr "type" "fisttp") 4492 (set_attr "mode" "<MODE>")]) 4493 4494(define_insn "fix_trunc<mode>_i387_fisttp" 4495 [(set (match_operand:SWI248x 0 "memory_operand" "=m") 4496 (fix:SWI248x (match_operand 1 "register_operand" "f"))) 4497 (clobber (match_scratch:XF 2 "=&1f"))] 4498 "X87_FLOAT_MODE_P (GET_MODE (operands[1])) 4499 && TARGET_FISTTP 4500 && !((SSE_FLOAT_MODE_P (GET_MODE (operands[1])) 4501 && (TARGET_64BIT || <MODE>mode != DImode)) 4502 && TARGET_SSE_MATH)" 4503 "* return output_fix_trunc (insn, operands, true);" 4504 [(set_attr "type" "fisttp") 4505 (set_attr "mode" "<MODE>")]) 4506 4507(define_insn "fix_trunc<mode>_i387_fisttp_with_temp" 4508 [(set (match_operand:SWI248x 0 "nonimmediate_operand" "=m,?r") 4509 (fix:SWI248x (match_operand 1 "register_operand" "f,f"))) 4510 (clobber (match_operand:SWI248x 2 "memory_operand" "=X,m")) 4511 (clobber (match_scratch:XF 3 "=&1f,&1f"))] 4512 "X87_FLOAT_MODE_P (GET_MODE (operands[1])) 4513 && TARGET_FISTTP 4514 && !((SSE_FLOAT_MODE_P (GET_MODE (operands[1])) 4515 && (TARGET_64BIT || <MODE>mode != DImode)) 4516 && TARGET_SSE_MATH)" 4517 "#" 4518 [(set_attr "type" "fisttp") 4519 (set_attr "mode" "<MODE>")]) 4520 4521(define_split 4522 [(set (match_operand:SWI248x 0 "register_operand" "") 4523 (fix:SWI248x (match_operand 1 "register_operand" ""))) 4524 (clobber (match_operand:SWI248x 2 "memory_operand" "")) 4525 (clobber (match_scratch 3 ""))] 4526 "reload_completed" 4527 [(parallel [(set (match_dup 2) (fix:SWI248x (match_dup 1))) 4528 (clobber (match_dup 3))]) 4529 (set (match_dup 0) (match_dup 2))]) 4530 4531(define_split 4532 [(set (match_operand:SWI248x 0 "memory_operand" "") 4533 (fix:SWI248x (match_operand 1 "register_operand" ""))) 4534 (clobber (match_operand:SWI248x 2 "memory_operand" "")) 4535 (clobber (match_scratch 3 ""))] 4536 "reload_completed" 4537 [(parallel [(set (match_dup 0) (fix:SWI248x (match_dup 1))) 4538 (clobber (match_dup 3))])]) 4539 4540;; See the comments in i386.h near OPTIMIZE_MODE_SWITCHING for the description 4541;; of the machinery. Please note the clobber of FLAGS_REG. In i387 control 4542;; word calculation (inserted by LCM in mode switching pass) a FLAGS_REG 4543;; clobbering insns can be used. Look at emit_i387_cw_initialization () 4544;; function in i386.c. 4545(define_insn_and_split "*fix_trunc<mode>_i387_1" 4546 [(set (match_operand:SWI248x 0 "nonimmediate_operand" "") 4547 (fix:SWI248x (match_operand 1 "register_operand" ""))) 4548 (clobber (reg:CC FLAGS_REG))] 4549 "X87_FLOAT_MODE_P (GET_MODE (operands[1])) 4550 && !TARGET_FISTTP 4551 && !(SSE_FLOAT_MODE_P (GET_MODE (operands[1])) 4552 && (TARGET_64BIT || <MODE>mode != DImode)) 4553 && can_create_pseudo_p ()" 4554 "#" 4555 "&& 1" 4556 [(const_int 0)] 4557{ 4558 ix86_optimize_mode_switching[I387_TRUNC] = 1; 4559 4560 operands[2] = assign_386_stack_local (HImode, SLOT_CW_STORED); 4561 operands[3] = assign_386_stack_local (HImode, SLOT_CW_TRUNC); 4562 if (memory_operand (operands[0], VOIDmode)) 4563 emit_insn (gen_fix_trunc<mode>_i387 (operands[0], operands[1], 4564 operands[2], operands[3])); 4565 else 4566 { 4567 operands[4] = assign_386_stack_local (<MODE>mode, SLOT_TEMP); 4568 emit_insn (gen_fix_trunc<mode>_i387_with_temp (operands[0], operands[1], 4569 operands[2], operands[3], 4570 operands[4])); 4571 } 4572 DONE; 4573} 4574 [(set_attr "type" "fistp") 4575 (set_attr "i387_cw" "trunc") 4576 (set_attr "mode" "<MODE>")]) 4577 4578(define_insn "fix_truncdi_i387" 4579 [(set (match_operand:DI 0 "memory_operand" "=m") 4580 (fix:DI (match_operand 1 "register_operand" "f"))) 4581 (use (match_operand:HI 2 "memory_operand" "m")) 4582 (use (match_operand:HI 3 "memory_operand" "m")) 4583 (clobber (match_scratch:XF 4 "=&1f"))] 4584 "X87_FLOAT_MODE_P (GET_MODE (operands[1])) 4585 && !TARGET_FISTTP 4586 && !(TARGET_64BIT && SSE_FLOAT_MODE_P (GET_MODE (operands[1])))" 4587 "* return output_fix_trunc (insn, operands, false);" 4588 [(set_attr "type" "fistp") 4589 (set_attr "i387_cw" "trunc") 4590 (set_attr "mode" "DI")]) 4591 4592(define_insn "fix_truncdi_i387_with_temp" 4593 [(set (match_operand:DI 0 "nonimmediate_operand" "=m,?r") 4594 (fix:DI (match_operand 1 "register_operand" "f,f"))) 4595 (use (match_operand:HI 2 "memory_operand" "m,m")) 4596 (use (match_operand:HI 3 "memory_operand" "m,m")) 4597 (clobber (match_operand:DI 4 "memory_operand" "=X,m")) 4598 (clobber (match_scratch:XF 5 "=&1f,&1f"))] 4599 "X87_FLOAT_MODE_P (GET_MODE (operands[1])) 4600 && !TARGET_FISTTP 4601 && !(TARGET_64BIT && SSE_FLOAT_MODE_P (GET_MODE (operands[1])))" 4602 "#" 4603 [(set_attr "type" "fistp") 4604 (set_attr "i387_cw" "trunc") 4605 (set_attr "mode" "DI")]) 4606 4607(define_split 4608 [(set (match_operand:DI 0 "register_operand" "") 4609 (fix:DI (match_operand 1 "register_operand" ""))) 4610 (use (match_operand:HI 2 "memory_operand" "")) 4611 (use (match_operand:HI 3 "memory_operand" "")) 4612 (clobber (match_operand:DI 4 "memory_operand" "")) 4613 (clobber (match_scratch 5 ""))] 4614 "reload_completed" 4615 [(parallel [(set (match_dup 4) (fix:DI (match_dup 1))) 4616 (use (match_dup 2)) 4617 (use (match_dup 3)) 4618 (clobber (match_dup 5))]) 4619 (set (match_dup 0) (match_dup 4))]) 4620 4621(define_split 4622 [(set (match_operand:DI 0 "memory_operand" "") 4623 (fix:DI (match_operand 1 "register_operand" ""))) 4624 (use (match_operand:HI 2 "memory_operand" "")) 4625 (use (match_operand:HI 3 "memory_operand" "")) 4626 (clobber (match_operand:DI 4 "memory_operand" "")) 4627 (clobber (match_scratch 5 ""))] 4628 "reload_completed" 4629 [(parallel [(set (match_dup 0) (fix:DI (match_dup 1))) 4630 (use (match_dup 2)) 4631 (use (match_dup 3)) 4632 (clobber (match_dup 5))])]) 4633 4634(define_insn "fix_trunc<mode>_i387" 4635 [(set (match_operand:SWI24 0 "memory_operand" "=m") 4636 (fix:SWI24 (match_operand 1 "register_operand" "f"))) 4637 (use (match_operand:HI 2 "memory_operand" "m")) 4638 (use (match_operand:HI 3 "memory_operand" "m"))] 4639 "X87_FLOAT_MODE_P (GET_MODE (operands[1])) 4640 && !TARGET_FISTTP 4641 && !SSE_FLOAT_MODE_P (GET_MODE (operands[1]))" 4642 "* return output_fix_trunc (insn, operands, false);" 4643 [(set_attr "type" "fistp") 4644 (set_attr "i387_cw" "trunc") 4645 (set_attr "mode" "<MODE>")]) 4646 4647(define_insn "fix_trunc<mode>_i387_with_temp" 4648 [(set (match_operand:SWI24 0 "nonimmediate_operand" "=m,?r") 4649 (fix:SWI24 (match_operand 1 "register_operand" "f,f"))) 4650 (use (match_operand:HI 2 "memory_operand" "m,m")) 4651 (use (match_operand:HI 3 "memory_operand" "m,m")) 4652 (clobber (match_operand:SWI24 4 "memory_operand" "=X,m"))] 4653 "X87_FLOAT_MODE_P (GET_MODE (operands[1])) 4654 && !TARGET_FISTTP 4655 && !SSE_FLOAT_MODE_P (GET_MODE (operands[1]))" 4656 "#" 4657 [(set_attr "type" "fistp") 4658 (set_attr "i387_cw" "trunc") 4659 (set_attr "mode" "<MODE>")]) 4660 4661(define_split 4662 [(set (match_operand:SWI24 0 "register_operand" "") 4663 (fix:SWI24 (match_operand 1 "register_operand" ""))) 4664 (use (match_operand:HI 2 "memory_operand" "")) 4665 (use (match_operand:HI 3 "memory_operand" "")) 4666 (clobber (match_operand:SWI24 4 "memory_operand" ""))] 4667 "reload_completed" 4668 [(parallel [(set (match_dup 4) (fix:SWI24 (match_dup 1))) 4669 (use (match_dup 2)) 4670 (use (match_dup 3))]) 4671 (set (match_dup 0) (match_dup 4))]) 4672 4673(define_split 4674 [(set (match_operand:SWI24 0 "memory_operand" "") 4675 (fix:SWI24 (match_operand 1 "register_operand" ""))) 4676 (use (match_operand:HI 2 "memory_operand" "")) 4677 (use (match_operand:HI 3 "memory_operand" "")) 4678 (clobber (match_operand:SWI24 4 "memory_operand" ""))] 4679 "reload_completed" 4680 [(parallel [(set (match_dup 0) (fix:SWI24 (match_dup 1))) 4681 (use (match_dup 2)) 4682 (use (match_dup 3))])]) 4683 4684(define_insn "x86_fnstcw_1" 4685 [(set (match_operand:HI 0 "memory_operand" "=m") 4686 (unspec:HI [(reg:HI FPCR_REG)] UNSPEC_FSTCW))] 4687 "TARGET_80387" 4688 "fnstcw\t%0" 4689 [(set (attr "length") 4690 (symbol_ref "ix86_attr_length_address_default (insn) + 2")) 4691 (set_attr "mode" "HI") 4692 (set_attr "unit" "i387") 4693 (set_attr "bdver1_decode" "vector")]) 4694 4695(define_insn "x86_fldcw_1" 4696 [(set (reg:HI FPCR_REG) 4697 (unspec:HI [(match_operand:HI 0 "memory_operand" "m")] UNSPEC_FLDCW))] 4698 "TARGET_80387" 4699 "fldcw\t%0" 4700 [(set (attr "length") 4701 (symbol_ref "ix86_attr_length_address_default (insn) + 2")) 4702 (set_attr "mode" "HI") 4703 (set_attr "unit" "i387") 4704 (set_attr "athlon_decode" "vector") 4705 (set_attr "amdfam10_decode" "vector") 4706 (set_attr "bdver1_decode" "vector")]) 4707 4708;; Conversion between fixed point and floating point. 4709 4710;; Even though we only accept memory inputs, the backend _really_ 4711;; wants to be able to do this between registers. 4712 4713(define_expand "floathi<mode>2" 4714 [(set (match_operand:X87MODEF 0 "register_operand" "") 4715 (float:X87MODEF (match_operand:HI 1 "nonimmediate_operand" "")))] 4716 "TARGET_80387 4717 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH) 4718 || TARGET_MIX_SSE_I387)") 4719 4720;; Pre-reload splitter to add memory clobber to the pattern. 4721(define_insn_and_split "*floathi<mode>2_1" 4722 [(set (match_operand:X87MODEF 0 "register_operand" "") 4723 (float:X87MODEF (match_operand:HI 1 "register_operand" "")))] 4724 "TARGET_80387 4725 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH) 4726 || TARGET_MIX_SSE_I387) 4727 && can_create_pseudo_p ()" 4728 "#" 4729 "&& 1" 4730 [(parallel [(set (match_dup 0) 4731 (float:X87MODEF (match_dup 1))) 4732 (clobber (match_dup 2))])] 4733 "operands[2] = assign_386_stack_local (HImode, SLOT_TEMP);") 4734 4735(define_insn "*floathi<mode>2_i387_with_temp" 4736 [(set (match_operand:X87MODEF 0 "register_operand" "=f,f") 4737 (float:X87MODEF (match_operand:HI 1 "nonimmediate_operand" "m,?r"))) 4738 (clobber (match_operand:HI 2 "memory_operand" "=X,m"))] 4739 "TARGET_80387 4740 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH) 4741 || TARGET_MIX_SSE_I387)" 4742 "#" 4743 [(set_attr "type" "fmov,multi") 4744 (set_attr "mode" "<MODE>") 4745 (set_attr "unit" "*,i387") 4746 (set_attr "fp_int_src" "true")]) 4747 4748(define_insn "*floathi<mode>2_i387" 4749 [(set (match_operand:X87MODEF 0 "register_operand" "=f") 4750 (float:X87MODEF (match_operand:HI 1 "memory_operand" "m")))] 4751 "TARGET_80387 4752 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH) 4753 || TARGET_MIX_SSE_I387)" 4754 "fild%Z1\t%1" 4755 [(set_attr "type" "fmov") 4756 (set_attr "mode" "<MODE>") 4757 (set_attr "fp_int_src" "true")]) 4758 4759(define_split 4760 [(set (match_operand:X87MODEF 0 "register_operand" "") 4761 (float:X87MODEF (match_operand:HI 1 "register_operand" ""))) 4762 (clobber (match_operand:HI 2 "memory_operand" ""))] 4763 "TARGET_80387 4764 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH) 4765 || TARGET_MIX_SSE_I387) 4766 && reload_completed" 4767 [(set (match_dup 2) (match_dup 1)) 4768 (set (match_dup 0) (float:X87MODEF (match_dup 2)))]) 4769 4770(define_split 4771 [(set (match_operand:X87MODEF 0 "register_operand" "") 4772 (float:X87MODEF (match_operand:HI 1 "memory_operand" ""))) 4773 (clobber (match_operand:HI 2 "memory_operand" ""))] 4774 "TARGET_80387 4775 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH) 4776 || TARGET_MIX_SSE_I387) 4777 && reload_completed" 4778 [(set (match_dup 0) (float:X87MODEF (match_dup 1)))]) 4779 4780(define_expand "float<SWI48x:mode><X87MODEF:mode>2" 4781 [(set (match_operand:X87MODEF 0 "register_operand" "") 4782 (float:X87MODEF 4783 (match_operand:SWI48x 1 "nonimmediate_operand" "")))] 4784 "TARGET_80387 4785 || ((<SWI48x:MODE>mode != DImode || TARGET_64BIT) 4786 && SSE_FLOAT_MODE_P (<X87MODEF:MODE>mode) && TARGET_SSE_MATH)" 4787{ 4788 if (!((<SWI48x:MODE>mode != DImode || TARGET_64BIT) 4789 && SSE_FLOAT_MODE_P (<X87MODEF:MODE>mode) && TARGET_SSE_MATH) 4790 && !X87_ENABLE_FLOAT (<X87MODEF:MODE>mode, <SWI48x:MODE>mode)) 4791 { 4792 rtx reg = gen_reg_rtx (XFmode); 4793 rtx (*insn)(rtx, rtx); 4794 4795 emit_insn (gen_float<SWI48x:mode>xf2 (reg, operands[1])); 4796 4797 if (<X87MODEF:MODE>mode == SFmode) 4798 insn = gen_truncxfsf2; 4799 else if (<X87MODEF:MODE>mode == DFmode) 4800 insn = gen_truncxfdf2; 4801 else 4802 gcc_unreachable (); 4803 4804 emit_insn (insn (operands[0], reg)); 4805 DONE; 4806 } 4807}) 4808 4809;; Pre-reload splitter to add memory clobber to the pattern. 4810(define_insn_and_split "*float<SWI48x:mode><X87MODEF:mode>2_1" 4811 [(set (match_operand:X87MODEF 0 "register_operand" "") 4812 (float:X87MODEF (match_operand:SWI48x 1 "register_operand" "")))] 4813 "((TARGET_80387 4814 && X87_ENABLE_FLOAT (<X87MODEF:MODE>mode, <SWI48x:MODE>mode) 4815 && (!((<SWI48x:MODE>mode != DImode || TARGET_64BIT) 4816 && SSE_FLOAT_MODE_P (<X87MODEF:MODE>mode) && TARGET_SSE_MATH) 4817 || TARGET_MIX_SSE_I387)) 4818 || ((<SWI48x:MODE>mode != DImode || TARGET_64BIT) 4819 && SSE_FLOAT_MODE_P (<X87MODEF:MODE>mode) && TARGET_SSE_MATH 4820 && ((<SWI48x:MODE>mode == SImode 4821 && TARGET_SSE2 && TARGET_USE_VECTOR_CONVERTS 4822 && optimize_function_for_speed_p (cfun) 4823 && flag_trapping_math) 4824 || !(TARGET_INTER_UNIT_CONVERSIONS 4825 || optimize_function_for_size_p (cfun))))) 4826 && can_create_pseudo_p ()" 4827 "#" 4828 "&& 1" 4829 [(parallel [(set (match_dup 0) (float:X87MODEF (match_dup 1))) 4830 (clobber (match_dup 2))])] 4831{ 4832 operands[2] = assign_386_stack_local (<SWI48x:MODE>mode, SLOT_TEMP); 4833 4834 /* Avoid store forwarding (partial memory) stall penalty 4835 by passing DImode value through XMM registers. */ 4836 if (<SWI48x:MODE>mode == DImode && !TARGET_64BIT 4837 && TARGET_80387 && TARGET_SSE2 && TARGET_INTER_UNIT_MOVES 4838 && optimize_function_for_speed_p (cfun)) 4839 { 4840 emit_insn (gen_floatdi<X87MODEF:mode>2_i387_with_xmm (operands[0], 4841 operands[1], 4842 operands[2])); 4843 DONE; 4844 } 4845}) 4846 4847(define_insn "*floatsi<mode>2_vector_mixed_with_temp" 4848 [(set (match_operand:MODEF 0 "register_operand" "=f,f,x,x,x") 4849 (float:MODEF 4850 (match_operand:SI 1 "nonimmediate_operand" "m,?r,r,m,!x"))) 4851 (clobber (match_operand:SI 2 "memory_operand" "=X,m,m,X,m"))] 4852 "TARGET_SSE2 && TARGET_MIX_SSE_I387 4853 && TARGET_USE_VECTOR_CONVERTS && optimize_function_for_speed_p (cfun)" 4854 "#" 4855 [(set_attr "type" "fmov,multi,sseicvt,sseicvt,sseicvt") 4856 (set_attr "mode" "<MODE>,<MODE>,<MODE>,<MODE>,<ssevecmode>") 4857 (set_attr "unit" "*,i387,*,*,*") 4858 (set_attr "athlon_decode" "*,*,double,direct,double") 4859 (set_attr "amdfam10_decode" "*,*,vector,double,double") 4860 (set_attr "bdver1_decode" "*,*,double,direct,double") 4861 (set_attr "fp_int_src" "true")]) 4862 4863(define_insn "*floatsi<mode>2_vector_mixed" 4864 [(set (match_operand:MODEF 0 "register_operand" "=f,x") 4865 (float:MODEF (match_operand:SI 1 "memory_operand" "m,m")))] 4866 "TARGET_SSE2 && TARGET_MIX_SSE_I387 4867 && TARGET_USE_VECTOR_CONVERTS && optimize_function_for_speed_p (cfun)" 4868 "@ 4869 fild%Z1\t%1 4870 #" 4871 [(set_attr "type" "fmov,sseicvt") 4872 (set_attr "mode" "<MODE>,<ssevecmode>") 4873 (set_attr "unit" "i387,*") 4874 (set_attr "athlon_decode" "*,direct") 4875 (set_attr "amdfam10_decode" "*,double") 4876 (set_attr "bdver1_decode" "*,direct") 4877 (set_attr "fp_int_src" "true")]) 4878 4879(define_insn "*float<SWI48x:mode><MODEF:mode>2_mixed_with_temp" 4880 [(set (match_operand:MODEF 0 "register_operand" "=f,f,x,x") 4881 (float:MODEF 4882 (match_operand:SWI48x 1 "nonimmediate_operand" "m,?r,r,m"))) 4883 (clobber (match_operand:SWI48x 2 "memory_operand" "=X,m,m,X"))] 4884 "(<SWI48x:MODE>mode != DImode || TARGET_64BIT) 4885 && SSE_FLOAT_MODE_P (<MODEF:MODE>mode) && TARGET_MIX_SSE_I387" 4886 "#" 4887 [(set_attr "type" "fmov,multi,sseicvt,sseicvt") 4888 (set_attr "mode" "<MODEF:MODE>") 4889 (set_attr "unit" "*,i387,*,*") 4890 (set_attr "athlon_decode" "*,*,double,direct") 4891 (set_attr "amdfam10_decode" "*,*,vector,double") 4892 (set_attr "bdver1_decode" "*,*,double,direct") 4893 (set_attr "fp_int_src" "true")]) 4894 4895(define_split 4896 [(set (match_operand:MODEF 0 "register_operand" "") 4897 (float:MODEF (match_operand:SWI48x 1 "register_operand" ""))) 4898 (clobber (match_operand:SWI48x 2 "memory_operand" ""))] 4899 "(<SWI48x:MODE>mode != DImode || TARGET_64BIT) 4900 && SSE_FLOAT_MODE_P (<MODEF:MODE>mode) && TARGET_MIX_SSE_I387 4901 && TARGET_INTER_UNIT_CONVERSIONS 4902 && reload_completed 4903 && (SSE_REG_P (operands[0]) 4904 || (GET_CODE (operands[0]) == SUBREG 4905 && SSE_REG_P (SUBREG_REG (operands[0]))))" 4906 [(set (match_dup 0) (float:MODEF (match_dup 1)))]) 4907 4908(define_split 4909 [(set (match_operand:MODEF 0 "register_operand" "") 4910 (float:MODEF (match_operand:SWI48x 1 "register_operand" ""))) 4911 (clobber (match_operand:SWI48x 2 "memory_operand" ""))] 4912 "(<SWI48x:MODE>mode != DImode || TARGET_64BIT) 4913 && SSE_FLOAT_MODE_P (<MODEF:MODE>mode) && TARGET_MIX_SSE_I387 4914 && !(TARGET_INTER_UNIT_CONVERSIONS || optimize_function_for_size_p (cfun)) 4915 && reload_completed 4916 && (SSE_REG_P (operands[0]) 4917 || (GET_CODE (operands[0]) == SUBREG 4918 && SSE_REG_P (SUBREG_REG (operands[0]))))" 4919 [(set (match_dup 2) (match_dup 1)) 4920 (set (match_dup 0) (float:MODEF (match_dup 2)))]) 4921 4922(define_insn "*float<SWI48x:mode><MODEF:mode>2_mixed_interunit" 4923 [(set (match_operand:MODEF 0 "register_operand" "=f,x,x") 4924 (float:MODEF 4925 (match_operand:SWI48x 1 "nonimmediate_operand" "m,r,m")))] 4926 "(<SWI48x:MODE>mode != DImode || TARGET_64BIT) 4927 && SSE_FLOAT_MODE_P (<MODEF:MODE>mode) && TARGET_MIX_SSE_I387 4928 && (TARGET_INTER_UNIT_CONVERSIONS || optimize_function_for_size_p (cfun))" 4929 "@ 4930 fild%Z1\t%1 4931 %vcvtsi2<MODEF:ssemodesuffix><SWI48x:rex64suffix>\t{%1, %d0|%d0, %1} 4932 %vcvtsi2<MODEF:ssemodesuffix><SWI48x:rex64suffix>\t{%1, %d0|%d0, %1}" 4933 [(set_attr "type" "fmov,sseicvt,sseicvt") 4934 (set_attr "prefix" "orig,maybe_vex,maybe_vex") 4935 (set_attr "mode" "<MODEF:MODE>") 4936 (set (attr "prefix_rex") 4937 (if_then_else 4938 (and (eq_attr "prefix" "maybe_vex") 4939 (match_test "<SWI48x:MODE>mode == DImode")) 4940 (const_string "1") 4941 (const_string "*"))) 4942 (set_attr "unit" "i387,*,*") 4943 (set_attr "athlon_decode" "*,double,direct") 4944 (set_attr "amdfam10_decode" "*,vector,double") 4945 (set_attr "bdver1_decode" "*,double,direct") 4946 (set_attr "fp_int_src" "true")]) 4947 4948(define_insn "*float<SWI48x:mode><MODEF:mode>2_mixed_nointerunit" 4949 [(set (match_operand:MODEF 0 "register_operand" "=f,x") 4950 (float:MODEF 4951 (match_operand:SWI48x 1 "memory_operand" "m,m")))] 4952 "(<SWI48x:MODE>mode != DImode || TARGET_64BIT) 4953 && SSE_FLOAT_MODE_P (<MODEF:MODE>mode) && TARGET_MIX_SSE_I387 4954 && !(TARGET_INTER_UNIT_CONVERSIONS || optimize_function_for_size_p (cfun))" 4955 "@ 4956 fild%Z1\t%1 4957 %vcvtsi2<MODEF:ssemodesuffix><SWI48x:rex64suffix>\t{%1, %d0|%d0, %1}" 4958 [(set_attr "type" "fmov,sseicvt") 4959 (set_attr "prefix" "orig,maybe_vex") 4960 (set_attr "mode" "<MODEF:MODE>") 4961 (set (attr "prefix_rex") 4962 (if_then_else 4963 (and (eq_attr "prefix" "maybe_vex") 4964 (match_test "<SWI48x:MODE>mode == DImode")) 4965 (const_string "1") 4966 (const_string "*"))) 4967 (set_attr "athlon_decode" "*,direct") 4968 (set_attr "amdfam10_decode" "*,double") 4969 (set_attr "bdver1_decode" "*,direct") 4970 (set_attr "fp_int_src" "true")]) 4971 4972(define_insn "*floatsi<mode>2_vector_sse_with_temp" 4973 [(set (match_operand:MODEF 0 "register_operand" "=x,x,x") 4974 (float:MODEF 4975 (match_operand:SI 1 "nonimmediate_operand" "r,m,!x"))) 4976 (clobber (match_operand:SI 2 "memory_operand" "=m,X,m"))] 4977 "TARGET_SSE2 && TARGET_SSE_MATH 4978 && TARGET_USE_VECTOR_CONVERTS && optimize_function_for_speed_p (cfun)" 4979 "#" 4980 [(set_attr "type" "sseicvt") 4981 (set_attr "mode" "<MODE>,<MODE>,<ssevecmode>") 4982 (set_attr "athlon_decode" "double,direct,double") 4983 (set_attr "amdfam10_decode" "vector,double,double") 4984 (set_attr "bdver1_decode" "double,direct,double") 4985 (set_attr "fp_int_src" "true")]) 4986 4987(define_insn "*floatsi<mode>2_vector_sse" 4988 [(set (match_operand:MODEF 0 "register_operand" "=x") 4989 (float:MODEF (match_operand:SI 1 "memory_operand" "m")))] 4990 "TARGET_SSE2 && TARGET_SSE_MATH 4991 && TARGET_USE_VECTOR_CONVERTS && optimize_function_for_speed_p (cfun)" 4992 "#" 4993 [(set_attr "type" "sseicvt") 4994 (set_attr "mode" "<MODE>") 4995 (set_attr "athlon_decode" "direct") 4996 (set_attr "amdfam10_decode" "double") 4997 (set_attr "bdver1_decode" "direct") 4998 (set_attr "fp_int_src" "true")]) 4999 5000(define_split 5001 [(set (match_operand:MODEF 0 "register_operand" "") 5002 (float:MODEF (match_operand:SI 1 "register_operand" ""))) 5003 (clobber (match_operand:SI 2 "memory_operand" ""))] 5004 "TARGET_SSE2 && TARGET_SSE_MATH 5005 && TARGET_USE_VECTOR_CONVERTS && optimize_function_for_speed_p (cfun) 5006 && reload_completed 5007 && (SSE_REG_P (operands[0]) 5008 || (GET_CODE (operands[0]) == SUBREG 5009 && SSE_REG_P (SUBREG_REG (operands[0]))))" 5010 [(const_int 0)] 5011{ 5012 rtx op1 = operands[1]; 5013 5014 operands[3] = simplify_gen_subreg (<ssevecmode>mode, operands[0], 5015 <MODE>mode, 0); 5016 if (GET_CODE (op1) == SUBREG) 5017 op1 = SUBREG_REG (op1); 5018 5019 if (GENERAL_REG_P (op1) && TARGET_INTER_UNIT_MOVES) 5020 { 5021 operands[4] = simplify_gen_subreg (V4SImode, operands[0], <MODE>mode, 0); 5022 emit_insn (gen_sse2_loadld (operands[4], 5023 CONST0_RTX (V4SImode), operands[1])); 5024 } 5025 /* We can ignore possible trapping value in the 5026 high part of SSE register for non-trapping math. */ 5027 else if (SSE_REG_P (op1) && !flag_trapping_math) 5028 operands[4] = simplify_gen_subreg (V4SImode, operands[1], SImode, 0); 5029 else 5030 { 5031 operands[4] = simplify_gen_subreg (V4SImode, operands[0], <MODE>mode, 0); 5032 emit_move_insn (operands[2], operands[1]); 5033 emit_insn (gen_sse2_loadld (operands[4], 5034 CONST0_RTX (V4SImode), operands[2])); 5035 } 5036 if (<ssevecmode>mode == V4SFmode) 5037 emit_insn (gen_floatv4siv4sf2 (operands[3], operands[4])); 5038 else 5039 emit_insn (gen_sse2_cvtdq2pd (operands[3], operands[4])); 5040 DONE; 5041}) 5042 5043(define_split 5044 [(set (match_operand:MODEF 0 "register_operand" "") 5045 (float:MODEF (match_operand:SI 1 "memory_operand" ""))) 5046 (clobber (match_operand:SI 2 "memory_operand" ""))] 5047 "TARGET_SSE2 && TARGET_SSE_MATH 5048 && TARGET_USE_VECTOR_CONVERTS && optimize_function_for_speed_p (cfun) 5049 && reload_completed 5050 && (SSE_REG_P (operands[0]) 5051 || (GET_CODE (operands[0]) == SUBREG 5052 && SSE_REG_P (SUBREG_REG (operands[0]))))" 5053 [(const_int 0)] 5054{ 5055 operands[3] = simplify_gen_subreg (<ssevecmode>mode, operands[0], 5056 <MODE>mode, 0); 5057 operands[4] = simplify_gen_subreg (V4SImode, operands[0], <MODE>mode, 0); 5058 5059 emit_insn (gen_sse2_loadld (operands[4], 5060 CONST0_RTX (V4SImode), operands[1])); 5061 if (<ssevecmode>mode == V4SFmode) 5062 emit_insn (gen_floatv4siv4sf2 (operands[3], operands[4])); 5063 else 5064 emit_insn (gen_sse2_cvtdq2pd (operands[3], operands[4])); 5065 DONE; 5066}) 5067 5068(define_split 5069 [(set (match_operand:MODEF 0 "register_operand" "") 5070 (float:MODEF (match_operand:SI 1 "register_operand" "")))] 5071 "TARGET_SSE2 && TARGET_SSE_MATH 5072 && TARGET_USE_VECTOR_CONVERTS && optimize_function_for_speed_p (cfun) 5073 && reload_completed 5074 && (SSE_REG_P (operands[0]) 5075 || (GET_CODE (operands[0]) == SUBREG 5076 && SSE_REG_P (SUBREG_REG (operands[0]))))" 5077 [(const_int 0)] 5078{ 5079 rtx op1 = operands[1]; 5080 5081 operands[3] = simplify_gen_subreg (<ssevecmode>mode, operands[0], 5082 <MODE>mode, 0); 5083 if (GET_CODE (op1) == SUBREG) 5084 op1 = SUBREG_REG (op1); 5085 5086 if (GENERAL_REG_P (op1)) 5087 { 5088 operands[4] = simplify_gen_subreg (V4SImode, operands[0], <MODE>mode, 0); 5089 if (TARGET_INTER_UNIT_MOVES) 5090 emit_insn (gen_sse2_loadld (operands[4], 5091 CONST0_RTX (V4SImode), operands[1])); 5092 else 5093 { 5094 operands[5] = ix86_force_to_memory (GET_MODE (operands[1]), 5095 operands[1]); 5096 emit_insn (gen_sse2_loadld (operands[4], 5097 CONST0_RTX (V4SImode), operands[5])); 5098 ix86_free_from_memory (GET_MODE (operands[1])); 5099 } 5100 } 5101 /* We can ignore possible trapping value in the 5102 high part of SSE register for non-trapping math. */ 5103 else if (SSE_REG_P (op1) && !flag_trapping_math) 5104 operands[4] = simplify_gen_subreg (V4SImode, operands[1], SImode, 0); 5105 else 5106 gcc_unreachable (); 5107 if (<ssevecmode>mode == V4SFmode) 5108 emit_insn (gen_floatv4siv4sf2 (operands[3], operands[4])); 5109 else 5110 emit_insn (gen_sse2_cvtdq2pd (operands[3], operands[4])); 5111 DONE; 5112}) 5113 5114(define_split 5115 [(set (match_operand:MODEF 0 "register_operand" "") 5116 (float:MODEF (match_operand:SI 1 "memory_operand" "")))] 5117 "TARGET_SSE2 && TARGET_SSE_MATH 5118 && TARGET_USE_VECTOR_CONVERTS && optimize_function_for_speed_p (cfun) 5119 && reload_completed 5120 && (SSE_REG_P (operands[0]) 5121 || (GET_CODE (operands[0]) == SUBREG 5122 && SSE_REG_P (SUBREG_REG (operands[0]))))" 5123 [(const_int 0)] 5124{ 5125 operands[3] = simplify_gen_subreg (<ssevecmode>mode, operands[0], 5126 <MODE>mode, 0); 5127 operands[4] = simplify_gen_subreg (V4SImode, operands[0], <MODE>mode, 0); 5128 5129 emit_insn (gen_sse2_loadld (operands[4], 5130 CONST0_RTX (V4SImode), operands[1])); 5131 if (<ssevecmode>mode == V4SFmode) 5132 emit_insn (gen_floatv4siv4sf2 (operands[3], operands[4])); 5133 else 5134 emit_insn (gen_sse2_cvtdq2pd (operands[3], operands[4])); 5135 DONE; 5136}) 5137 5138(define_insn "*float<SWI48x:mode><MODEF:mode>2_sse_with_temp" 5139 [(set (match_operand:MODEF 0 "register_operand" "=x,x") 5140 (float:MODEF 5141 (match_operand:SWI48x 1 "nonimmediate_operand" "r,m"))) 5142 (clobber (match_operand:SWI48x 2 "memory_operand" "=m,X"))] 5143 "(<SWI48x:MODE>mode != DImode || TARGET_64BIT) 5144 && SSE_FLOAT_MODE_P (<MODEF:MODE>mode) && TARGET_SSE_MATH" 5145 "#" 5146 [(set_attr "type" "sseicvt") 5147 (set_attr "mode" "<MODEF:MODE>") 5148 (set_attr "athlon_decode" "double,direct") 5149 (set_attr "amdfam10_decode" "vector,double") 5150 (set_attr "bdver1_decode" "double,direct") 5151 (set_attr "fp_int_src" "true")]) 5152 5153(define_insn "*float<SWI48x:mode><MODEF:mode>2_sse_interunit" 5154 [(set (match_operand:MODEF 0 "register_operand" "=x,x") 5155 (float:MODEF 5156 (match_operand:SWI48x 1 "nonimmediate_operand" "r,m")))] 5157 "(<SWI48x:MODE>mode != DImode || TARGET_64BIT) 5158 && SSE_FLOAT_MODE_P (<MODEF:MODE>mode) && TARGET_SSE_MATH 5159 && (TARGET_INTER_UNIT_CONVERSIONS || optimize_function_for_size_p (cfun))" 5160 "%vcvtsi2<MODEF:ssemodesuffix><SWI48x:rex64suffix>\t{%1, %d0|%d0, %1}" 5161 [(set_attr "type" "sseicvt") 5162 (set_attr "prefix" "maybe_vex") 5163 (set_attr "mode" "<MODEF:MODE>") 5164 (set (attr "prefix_rex") 5165 (if_then_else 5166 (and (eq_attr "prefix" "maybe_vex") 5167 (match_test "<SWI48x:MODE>mode == DImode")) 5168 (const_string "1") 5169 (const_string "*"))) 5170 (set_attr "athlon_decode" "double,direct") 5171 (set_attr "amdfam10_decode" "vector,double") 5172 (set_attr "bdver1_decode" "double,direct") 5173 (set_attr "fp_int_src" "true")]) 5174 5175(define_split 5176 [(set (match_operand:MODEF 0 "register_operand" "") 5177 (float:MODEF (match_operand:SWI48x 1 "nonimmediate_operand" ""))) 5178 (clobber (match_operand:SWI48x 2 "memory_operand" ""))] 5179 "(<SWI48x:MODE>mode != DImode || TARGET_64BIT) 5180 && SSE_FLOAT_MODE_P (<MODEF:MODE>mode) && TARGET_SSE_MATH 5181 && (TARGET_INTER_UNIT_CONVERSIONS || optimize_function_for_size_p (cfun)) 5182 && reload_completed 5183 && (SSE_REG_P (operands[0]) 5184 || (GET_CODE (operands[0]) == SUBREG 5185 && SSE_REG_P (SUBREG_REG (operands[0]))))" 5186 [(set (match_dup 0) (float:MODEF (match_dup 1)))]) 5187 5188(define_insn "*float<SWI48x:mode><MODEF:mode>2_sse_nointerunit" 5189 [(set (match_operand:MODEF 0 "register_operand" "=x") 5190 (float:MODEF 5191 (match_operand:SWI48x 1 "memory_operand" "m")))] 5192 "(<SWI48x:MODE>mode != DImode || TARGET_64BIT) 5193 && SSE_FLOAT_MODE_P (<MODEF:MODE>mode) && TARGET_SSE_MATH 5194 && !(TARGET_INTER_UNIT_CONVERSIONS || optimize_function_for_size_p (cfun))" 5195 "%vcvtsi2<MODEF:ssemodesuffix><SWI48x:rex64suffix>\t{%1, %d0|%d0, %1}" 5196 [(set_attr "type" "sseicvt") 5197 (set_attr "prefix" "maybe_vex") 5198 (set_attr "mode" "<MODEF:MODE>") 5199 (set (attr "prefix_rex") 5200 (if_then_else 5201 (and (eq_attr "prefix" "maybe_vex") 5202 (match_test "<SWI48x:MODE>mode == DImode")) 5203 (const_string "1") 5204 (const_string "*"))) 5205 (set_attr "athlon_decode" "direct") 5206 (set_attr "amdfam10_decode" "double") 5207 (set_attr "bdver1_decode" "direct") 5208 (set_attr "fp_int_src" "true")]) 5209 5210(define_split 5211 [(set (match_operand:MODEF 0 "register_operand" "") 5212 (float:MODEF (match_operand:SWI48x 1 "register_operand" ""))) 5213 (clobber (match_operand:SWI48x 2 "memory_operand" ""))] 5214 "(<SWI48x:MODE>mode != DImode || TARGET_64BIT) 5215 && SSE_FLOAT_MODE_P (<MODEF:MODE>mode) && TARGET_SSE_MATH 5216 && !(TARGET_INTER_UNIT_CONVERSIONS || optimize_function_for_size_p (cfun)) 5217 && reload_completed 5218 && (SSE_REG_P (operands[0]) 5219 || (GET_CODE (operands[0]) == SUBREG 5220 && SSE_REG_P (SUBREG_REG (operands[0]))))" 5221 [(set (match_dup 2) (match_dup 1)) 5222 (set (match_dup 0) (float:MODEF (match_dup 2)))]) 5223 5224(define_split 5225 [(set (match_operand:MODEF 0 "register_operand" "") 5226 (float:MODEF (match_operand:SWI48x 1 "memory_operand" ""))) 5227 (clobber (match_operand:SWI48x 2 "memory_operand" ""))] 5228 "(<SWI48x:MODE>mode != DImode || TARGET_64BIT) 5229 && SSE_FLOAT_MODE_P (<MODEF:MODE>mode) && TARGET_SSE_MATH 5230 && reload_completed 5231 && (SSE_REG_P (operands[0]) 5232 || (GET_CODE (operands[0]) == SUBREG 5233 && SSE_REG_P (SUBREG_REG (operands[0]))))" 5234 [(set (match_dup 0) (float:MODEF (match_dup 1)))]) 5235 5236(define_insn "*float<SWI48x:mode><X87MODEF:mode>2_i387_with_temp" 5237 [(set (match_operand:X87MODEF 0 "register_operand" "=f,f") 5238 (float:X87MODEF 5239 (match_operand:SWI48x 1 "nonimmediate_operand" "m,?r"))) 5240 (clobber (match_operand:SWI48x 2 "memory_operand" "=X,m"))] 5241 "TARGET_80387 5242 && X87_ENABLE_FLOAT (<X87MODEF:MODE>mode, <SWI48x:MODE>mode)" 5243 "@ 5244 fild%Z1\t%1 5245 #" 5246 [(set_attr "type" "fmov,multi") 5247 (set_attr "mode" "<X87MODEF:MODE>") 5248 (set_attr "unit" "*,i387") 5249 (set_attr "fp_int_src" "true")]) 5250 5251(define_insn "*float<SWI48x:mode><X87MODEF:mode>2_i387" 5252 [(set (match_operand:X87MODEF 0 "register_operand" "=f") 5253 (float:X87MODEF 5254 (match_operand:SWI48x 1 "memory_operand" "m")))] 5255 "TARGET_80387 5256 && X87_ENABLE_FLOAT (<X87MODEF:MODE>mode, <SWI48x:MODE>mode)" 5257 "fild%Z1\t%1" 5258 [(set_attr "type" "fmov") 5259 (set_attr "mode" "<X87MODEF:MODE>") 5260 (set_attr "fp_int_src" "true")]) 5261 5262(define_split 5263 [(set (match_operand:X87MODEF 0 "fp_register_operand" "") 5264 (float:X87MODEF (match_operand:SWI48x 1 "register_operand" ""))) 5265 (clobber (match_operand:SWI48x 2 "memory_operand" ""))] 5266 "TARGET_80387 5267 && X87_ENABLE_FLOAT (<X87MODEF:MODE>mode, <SWI48x:MODE>mode) 5268 && reload_completed" 5269 [(set (match_dup 2) (match_dup 1)) 5270 (set (match_dup 0) (float:X87MODEF (match_dup 2)))]) 5271 5272(define_split 5273 [(set (match_operand:X87MODEF 0 "fp_register_operand" "") 5274 (float:X87MODEF (match_operand:SWI48x 1 "memory_operand" ""))) 5275 (clobber (match_operand:SWI48x 2 "memory_operand" ""))] 5276 "TARGET_80387 5277 && X87_ENABLE_FLOAT (<X87MODEF:MODE>mode, <SWI48x:MODE>mode) 5278 && reload_completed" 5279 [(set (match_dup 0) (float:X87MODEF (match_dup 1)))]) 5280 5281;; Avoid store forwarding (partial memory) stall penalty 5282;; by passing DImode value through XMM registers. */ 5283 5284(define_insn "floatdi<X87MODEF:mode>2_i387_with_xmm" 5285 [(set (match_operand:X87MODEF 0 "register_operand" "=f,f") 5286 (float:X87MODEF 5287 (match_operand:DI 1 "nonimmediate_operand" "m,?r"))) 5288 (clobber (match_scratch:V4SI 3 "=X,x")) 5289 (clobber (match_scratch:V4SI 4 "=X,x")) 5290 (clobber (match_operand:DI 2 "memory_operand" "=X,m"))] 5291 "TARGET_80387 && X87_ENABLE_FLOAT (<X87MODEF:MODE>mode, DImode) 5292 && TARGET_SSE2 && TARGET_INTER_UNIT_MOVES 5293 && !TARGET_64BIT && optimize_function_for_speed_p (cfun)" 5294 "#" 5295 [(set_attr "type" "multi") 5296 (set_attr "mode" "<X87MODEF:MODE>") 5297 (set_attr "unit" "i387") 5298 (set_attr "fp_int_src" "true")]) 5299 5300(define_split 5301 [(set (match_operand:X87MODEF 0 "fp_register_operand" "") 5302 (float:X87MODEF (match_operand:DI 1 "register_operand" ""))) 5303 (clobber (match_scratch:V4SI 3 "")) 5304 (clobber (match_scratch:V4SI 4 "")) 5305 (clobber (match_operand:DI 2 "memory_operand" ""))] 5306 "TARGET_80387 && X87_ENABLE_FLOAT (<X87MODEF:MODE>mode, DImode) 5307 && TARGET_SSE2 && TARGET_INTER_UNIT_MOVES 5308 && !TARGET_64BIT && optimize_function_for_speed_p (cfun) 5309 && reload_completed" 5310 [(set (match_dup 2) (match_dup 3)) 5311 (set (match_dup 0) (float:X87MODEF (match_dup 2)))] 5312{ 5313 /* The DImode arrived in a pair of integral registers (e.g. %edx:%eax). 5314 Assemble the 64-bit DImode value in an xmm register. */ 5315 emit_insn (gen_sse2_loadld (operands[3], CONST0_RTX (V4SImode), 5316 gen_rtx_SUBREG (SImode, operands[1], 0))); 5317 emit_insn (gen_sse2_loadld (operands[4], CONST0_RTX (V4SImode), 5318 gen_rtx_SUBREG (SImode, operands[1], 4))); 5319 emit_insn (gen_vec_interleave_lowv4si (operands[3], operands[3], 5320 operands[4])); 5321 5322 operands[3] = gen_rtx_REG (DImode, REGNO (operands[3])); 5323}) 5324 5325(define_split 5326 [(set (match_operand:X87MODEF 0 "fp_register_operand" "") 5327 (float:X87MODEF (match_operand:DI 1 "memory_operand" ""))) 5328 (clobber (match_scratch:V4SI 3 "")) 5329 (clobber (match_scratch:V4SI 4 "")) 5330 (clobber (match_operand:DI 2 "memory_operand" ""))] 5331 "TARGET_80387 && X87_ENABLE_FLOAT (<X87MODEF:MODE>mode, DImode) 5332 && TARGET_SSE2 && TARGET_INTER_UNIT_MOVES 5333 && !TARGET_64BIT && optimize_function_for_speed_p (cfun) 5334 && reload_completed" 5335 [(set (match_dup 0) (float:X87MODEF (match_dup 1)))]) 5336 5337;; Avoid store forwarding (partial memory) stall penalty by extending 5338;; SImode value to DImode through XMM register instead of pushing two 5339;; SImode values to stack. Note that even !TARGET_INTER_UNIT_MOVES 5340;; targets benefit from this optimization. Also note that fild 5341;; loads from memory only. 5342 5343(define_insn "*floatunssi<mode>2_1" 5344 [(set (match_operand:X87MODEF 0 "register_operand" "=f,f") 5345 (unsigned_float:X87MODEF 5346 (match_operand:SI 1 "nonimmediate_operand" "x,m"))) 5347 (clobber (match_operand:DI 2 "memory_operand" "=m,m")) 5348 (clobber (match_scratch:SI 3 "=X,x"))] 5349 "!TARGET_64BIT 5350 && TARGET_80387 && X87_ENABLE_FLOAT (<X87MODEF:MODE>mode, DImode) 5351 && TARGET_SSE" 5352 "#" 5353 [(set_attr "type" "multi") 5354 (set_attr "mode" "<MODE>")]) 5355 5356(define_split 5357 [(set (match_operand:X87MODEF 0 "register_operand" "") 5358 (unsigned_float:X87MODEF 5359 (match_operand:SI 1 "register_operand" ""))) 5360 (clobber (match_operand:DI 2 "memory_operand" "")) 5361 (clobber (match_scratch:SI 3 ""))] 5362 "!TARGET_64BIT 5363 && TARGET_80387 && X87_ENABLE_FLOAT (<X87MODEF:MODE>mode, DImode) 5364 && TARGET_SSE 5365 && reload_completed" 5366 [(set (match_dup 2) (match_dup 1)) 5367 (set (match_dup 0) 5368 (float:X87MODEF (match_dup 2)))] 5369 "operands[1] = simplify_gen_subreg (DImode, operands[1], SImode, 0);") 5370 5371(define_split 5372 [(set (match_operand:X87MODEF 0 "register_operand" "") 5373 (unsigned_float:X87MODEF 5374 (match_operand:SI 1 "memory_operand" ""))) 5375 (clobber (match_operand:DI 2 "memory_operand" "")) 5376 (clobber (match_scratch:SI 3 ""))] 5377 "!TARGET_64BIT 5378 && TARGET_80387 && X87_ENABLE_FLOAT (<X87MODEF:MODE>mode, DImode) 5379 && TARGET_SSE 5380 && reload_completed" 5381 [(set (match_dup 2) (match_dup 3)) 5382 (set (match_dup 0) 5383 (float:X87MODEF (match_dup 2)))] 5384{ 5385 emit_move_insn (operands[3], operands[1]); 5386 operands[3] = simplify_gen_subreg (DImode, operands[3], SImode, 0); 5387}) 5388 5389(define_expand "floatunssi<mode>2" 5390 [(parallel 5391 [(set (match_operand:X87MODEF 0 "register_operand" "") 5392 (unsigned_float:X87MODEF 5393 (match_operand:SI 1 "nonimmediate_operand" ""))) 5394 (clobber (match_dup 2)) 5395 (clobber (match_scratch:SI 3 ""))])] 5396 "!TARGET_64BIT 5397 && ((TARGET_80387 && X87_ENABLE_FLOAT (<X87MODEF:MODE>mode, DImode) 5398 && TARGET_SSE) 5399 || (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH))" 5400{ 5401 if (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH) 5402 { 5403 ix86_expand_convert_uns_si<mode>_sse (operands[0], operands[1]); 5404 DONE; 5405 } 5406 else 5407 operands[2] = assign_386_stack_local (DImode, SLOT_TEMP); 5408}) 5409 5410(define_expand "floatunsdisf2" 5411 [(use (match_operand:SF 0 "register_operand" "")) 5412 (use (match_operand:DI 1 "nonimmediate_operand" ""))] 5413 "TARGET_64BIT && TARGET_SSE_MATH" 5414 "x86_emit_floatuns (operands); DONE;") 5415 5416(define_expand "floatunsdidf2" 5417 [(use (match_operand:DF 0 "register_operand" "")) 5418 (use (match_operand:DI 1 "nonimmediate_operand" ""))] 5419 "(TARGET_64BIT || TARGET_KEEPS_VECTOR_ALIGNED_STACK) 5420 && TARGET_SSE2 && TARGET_SSE_MATH" 5421{ 5422 if (TARGET_64BIT) 5423 x86_emit_floatuns (operands); 5424 else 5425 ix86_expand_convert_uns_didf_sse (operands[0], operands[1]); 5426 DONE; 5427}) 5428 5429;; Load effective address instructions 5430 5431(define_insn_and_split "*lea<mode>" 5432 [(set (match_operand:SWI48 0 "register_operand" "=r") 5433 (match_operand:SWI48 1 "lea_address_operand" "p"))] 5434 "" 5435{ 5436 rtx addr = operands[1]; 5437 5438 if (SImode_address_operand (addr, VOIDmode)) 5439 { 5440 gcc_assert (TARGET_64BIT); 5441 return "lea{l}\t{%E1, %k0|%k0, %E1}"; 5442 } 5443 else 5444 return "lea{<imodesuffix>}\t{%E1, %0|%0, %E1}"; 5445} 5446 "reload_completed && ix86_avoid_lea_for_addr (insn, operands)" 5447 [(const_int 0)] 5448{ 5449 ix86_split_lea_for_addr (operands, <MODE>mode); 5450 DONE; 5451} 5452 [(set_attr "type" "lea") 5453 (set (attr "mode") 5454 (if_then_else 5455 (match_operand 1 "SImode_address_operand") 5456 (const_string "SI") 5457 (const_string "<MODE>")))]) 5458 5459;; Add instructions 5460 5461(define_expand "add<mode>3" 5462 [(set (match_operand:SDWIM 0 "nonimmediate_operand" "") 5463 (plus:SDWIM (match_operand:SDWIM 1 "nonimmediate_operand" "") 5464 (match_operand:SDWIM 2 "<general_operand>" "")))] 5465 "" 5466 "ix86_expand_binary_operator (PLUS, <MODE>mode, operands); DONE;") 5467 5468(define_insn_and_split "*add<dwi>3_doubleword" 5469 [(set (match_operand:<DWI> 0 "nonimmediate_operand" "=r,o") 5470 (plus:<DWI> 5471 (match_operand:<DWI> 1 "nonimmediate_operand" "%0,0") 5472 (match_operand:<DWI> 2 "<general_operand>" "ro<di>,r<di>"))) 5473 (clobber (reg:CC FLAGS_REG))] 5474 "ix86_binary_operator_ok (PLUS, <DWI>mode, operands)" 5475 "#" 5476 "reload_completed" 5477 [(parallel [(set (reg:CC FLAGS_REG) 5478 (unspec:CC [(match_dup 1) (match_dup 2)] 5479 UNSPEC_ADD_CARRY)) 5480 (set (match_dup 0) 5481 (plus:DWIH (match_dup 1) (match_dup 2)))]) 5482 (parallel [(set (match_dup 3) 5483 (plus:DWIH 5484 (match_dup 4) 5485 (plus:DWIH 5486 (ltu:DWIH (reg:CC FLAGS_REG) (const_int 0)) 5487 (match_dup 5)))) 5488 (clobber (reg:CC FLAGS_REG))])] 5489 "split_double_mode (<DWI>mode, &operands[0], 3, &operands[0], &operands[3]);") 5490 5491(define_insn "*add<mode>3_cc" 5492 [(set (reg:CC FLAGS_REG) 5493 (unspec:CC 5494 [(match_operand:SWI48 1 "nonimmediate_operand" "%0,0") 5495 (match_operand:SWI48 2 "<general_operand>" "r<i>,rm")] 5496 UNSPEC_ADD_CARRY)) 5497 (set (match_operand:SWI48 0 "nonimmediate_operand" "=rm,r") 5498 (plus:SWI48 (match_dup 1) (match_dup 2)))] 5499 "ix86_binary_operator_ok (PLUS, <MODE>mode, operands)" 5500 "add{<imodesuffix>}\t{%2, %0|%0, %2}" 5501 [(set_attr "type" "alu") 5502 (set_attr "mode" "<MODE>")]) 5503 5504(define_insn "addqi3_cc" 5505 [(set (reg:CC FLAGS_REG) 5506 (unspec:CC 5507 [(match_operand:QI 1 "nonimmediate_operand" "%0,0") 5508 (match_operand:QI 2 "general_operand" "qn,qm")] 5509 UNSPEC_ADD_CARRY)) 5510 (set (match_operand:QI 0 "nonimmediate_operand" "=qm,q") 5511 (plus:QI (match_dup 1) (match_dup 2)))] 5512 "ix86_binary_operator_ok (PLUS, QImode, operands)" 5513 "add{b}\t{%2, %0|%0, %2}" 5514 [(set_attr "type" "alu") 5515 (set_attr "mode" "QI")]) 5516 5517(define_insn "*add<mode>_1" 5518 [(set (match_operand:SWI48 0 "nonimmediate_operand" "=r,rm,r,r") 5519 (plus:SWI48 5520 (match_operand:SWI48 1 "nonimmediate_operand" "%0,0,r,r") 5521 (match_operand:SWI48 2 "x86_64_general_operand" "rme,re,0,le"))) 5522 (clobber (reg:CC FLAGS_REG))] 5523 "ix86_binary_operator_ok (PLUS, <MODE>mode, operands)" 5524{ 5525 switch (get_attr_type (insn)) 5526 { 5527 case TYPE_LEA: 5528 return "#"; 5529 5530 case TYPE_INCDEC: 5531 gcc_assert (rtx_equal_p (operands[0], operands[1])); 5532 if (operands[2] == const1_rtx) 5533 return "inc{<imodesuffix>}\t%0"; 5534 else 5535 { 5536 gcc_assert (operands[2] == constm1_rtx); 5537 return "dec{<imodesuffix>}\t%0"; 5538 } 5539 5540 default: 5541 /* For most processors, ADD is faster than LEA. This alternative 5542 was added to use ADD as much as possible. */ 5543 if (which_alternative == 2) 5544 { 5545 rtx tmp; 5546 tmp = operands[1], operands[1] = operands[2], operands[2] = tmp; 5547 } 5548 5549 gcc_assert (rtx_equal_p (operands[0], operands[1])); 5550 if (x86_maybe_negate_const_int (&operands[2], <MODE>mode)) 5551 return "sub{<imodesuffix>}\t{%2, %0|%0, %2}"; 5552 5553 return "add{<imodesuffix>}\t{%2, %0|%0, %2}"; 5554 } 5555} 5556 [(set (attr "type") 5557 (cond [(eq_attr "alternative" "3") 5558 (const_string "lea") 5559 (match_operand:SWI48 2 "incdec_operand" "") 5560 (const_string "incdec") 5561 ] 5562 (const_string "alu"))) 5563 (set (attr "length_immediate") 5564 (if_then_else 5565 (and (eq_attr "type" "alu") (match_operand 2 "const128_operand" "")) 5566 (const_string "1") 5567 (const_string "*"))) 5568 (set_attr "mode" "<MODE>")]) 5569 5570;; It may seem that nonimmediate operand is proper one for operand 1. 5571;; The addsi_1 pattern allows nonimmediate operand at that place and 5572;; we take care in ix86_binary_operator_ok to not allow two memory 5573;; operands so proper swapping will be done in reload. This allow 5574;; patterns constructed from addsi_1 to match. 5575 5576(define_insn "addsi_1_zext" 5577 [(set (match_operand:DI 0 "register_operand" "=r,r,r") 5578 (zero_extend:DI 5579 (plus:SI (match_operand:SI 1 "nonimmediate_operand" "%0,r,r") 5580 (match_operand:SI 2 "x86_64_general_operand" "rme,0,le")))) 5581 (clobber (reg:CC FLAGS_REG))] 5582 "TARGET_64BIT && ix86_binary_operator_ok (PLUS, SImode, operands)" 5583{ 5584 switch (get_attr_type (insn)) 5585 { 5586 case TYPE_LEA: 5587 return "#"; 5588 5589 case TYPE_INCDEC: 5590 if (operands[2] == const1_rtx) 5591 return "inc{l}\t%k0"; 5592 else 5593 { 5594 gcc_assert (operands[2] == constm1_rtx); 5595 return "dec{l}\t%k0"; 5596 } 5597 5598 default: 5599 /* For most processors, ADD is faster than LEA. This alternative 5600 was added to use ADD as much as possible. */ 5601 if (which_alternative == 1) 5602 { 5603 rtx tmp; 5604 tmp = operands[1], operands[1] = operands[2], operands[2] = tmp; 5605 } 5606 5607 if (x86_maybe_negate_const_int (&operands[2], SImode)) 5608 return "sub{l}\t{%2, %k0|%k0, %2}"; 5609 5610 return "add{l}\t{%2, %k0|%k0, %2}"; 5611 } 5612} 5613 [(set (attr "type") 5614 (cond [(eq_attr "alternative" "2") 5615 (const_string "lea") 5616 (match_operand:SI 2 "incdec_operand" "") 5617 (const_string "incdec") 5618 ] 5619 (const_string "alu"))) 5620 (set (attr "length_immediate") 5621 (if_then_else 5622 (and (eq_attr "type" "alu") (match_operand 2 "const128_operand" "")) 5623 (const_string "1") 5624 (const_string "*"))) 5625 (set_attr "mode" "SI")]) 5626 5627(define_insn "*addhi_1" 5628 [(set (match_operand:HI 0 "nonimmediate_operand" "=rm,r,r,Yp") 5629 (plus:HI (match_operand:HI 1 "nonimmediate_operand" "%0,0,r,Yp") 5630 (match_operand:HI 2 "general_operand" "rn,rm,0,ln"))) 5631 (clobber (reg:CC FLAGS_REG))] 5632 "ix86_binary_operator_ok (PLUS, HImode, operands)" 5633{ 5634 switch (get_attr_type (insn)) 5635 { 5636 case TYPE_LEA: 5637 return "#"; 5638 5639 case TYPE_INCDEC: 5640 gcc_assert (rtx_equal_p (operands[0], operands[1])); 5641 if (operands[2] == const1_rtx) 5642 return "inc{w}\t%0"; 5643 else 5644 { 5645 gcc_assert (operands[2] == constm1_rtx); 5646 return "dec{w}\t%0"; 5647 } 5648 5649 default: 5650 /* For most processors, ADD is faster than LEA. This alternative 5651 was added to use ADD as much as possible. */ 5652 if (which_alternative == 2) 5653 { 5654 rtx tmp; 5655 tmp = operands[1], operands[1] = operands[2], operands[2] = tmp; 5656 } 5657 5658 gcc_assert (rtx_equal_p (operands[0], operands[1])); 5659 if (x86_maybe_negate_const_int (&operands[2], HImode)) 5660 return "sub{w}\t{%2, %0|%0, %2}"; 5661 5662 return "add{w}\t{%2, %0|%0, %2}"; 5663 } 5664} 5665 [(set (attr "type") 5666 (cond [(eq_attr "alternative" "3") 5667 (const_string "lea") 5668 (match_operand:HI 2 "incdec_operand" "") 5669 (const_string "incdec") 5670 ] 5671 (const_string "alu"))) 5672 (set (attr "length_immediate") 5673 (if_then_else 5674 (and (eq_attr "type" "alu") (match_operand 2 "const128_operand" "")) 5675 (const_string "1") 5676 (const_string "*"))) 5677 (set_attr "mode" "HI,HI,HI,SI")]) 5678 5679;; %%% Potential partial reg stall on alternatives 3 and 4. What to do? 5680(define_insn "*addqi_1" 5681 [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,q,q,r,r,Yp") 5682 (plus:QI (match_operand:QI 1 "nonimmediate_operand" "%0,0,q,0,r,Yp") 5683 (match_operand:QI 2 "general_operand" "qn,qm,0,rn,0,ln"))) 5684 (clobber (reg:CC FLAGS_REG))] 5685 "ix86_binary_operator_ok (PLUS, QImode, operands)" 5686{ 5687 bool widen = (which_alternative == 3 || which_alternative == 4); 5688 5689 switch (get_attr_type (insn)) 5690 { 5691 case TYPE_LEA: 5692 return "#"; 5693 5694 case TYPE_INCDEC: 5695 gcc_assert (rtx_equal_p (operands[0], operands[1])); 5696 if (operands[2] == const1_rtx) 5697 return widen ? "inc{l}\t%k0" : "inc{b}\t%0"; 5698 else 5699 { 5700 gcc_assert (operands[2] == constm1_rtx); 5701 return widen ? "dec{l}\t%k0" : "dec{b}\t%0"; 5702 } 5703 5704 default: 5705 /* For most processors, ADD is faster than LEA. These alternatives 5706 were added to use ADD as much as possible. */ 5707 if (which_alternative == 2 || which_alternative == 4) 5708 { 5709 rtx tmp; 5710 tmp = operands[1], operands[1] = operands[2], operands[2] = tmp; 5711 } 5712 5713 gcc_assert (rtx_equal_p (operands[0], operands[1])); 5714 if (x86_maybe_negate_const_int (&operands[2], QImode)) 5715 { 5716 if (widen) 5717 return "sub{l}\t{%2, %k0|%k0, %2}"; 5718 else 5719 return "sub{b}\t{%2, %0|%0, %2}"; 5720 } 5721 if (widen) 5722 return "add{l}\t{%k2, %k0|%k0, %k2}"; 5723 else 5724 return "add{b}\t{%2, %0|%0, %2}"; 5725 } 5726} 5727 [(set (attr "type") 5728 (cond [(eq_attr "alternative" "5") 5729 (const_string "lea") 5730 (match_operand:QI 2 "incdec_operand" "") 5731 (const_string "incdec") 5732 ] 5733 (const_string "alu"))) 5734 (set (attr "length_immediate") 5735 (if_then_else 5736 (and (eq_attr "type" "alu") (match_operand 2 "const128_operand" "")) 5737 (const_string "1") 5738 (const_string "*"))) 5739 (set_attr "mode" "QI,QI,QI,SI,SI,SI")]) 5740 5741(define_insn "*addqi_1_slp" 5742 [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm,q")) 5743 (plus:QI (match_dup 0) 5744 (match_operand:QI 1 "general_operand" "qn,qm"))) 5745 (clobber (reg:CC FLAGS_REG))] 5746 "(! TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun)) 5747 && !(MEM_P (operands[0]) && MEM_P (operands[1]))" 5748{ 5749 switch (get_attr_type (insn)) 5750 { 5751 case TYPE_INCDEC: 5752 if (operands[1] == const1_rtx) 5753 return "inc{b}\t%0"; 5754 else 5755 { 5756 gcc_assert (operands[1] == constm1_rtx); 5757 return "dec{b}\t%0"; 5758 } 5759 5760 default: 5761 if (x86_maybe_negate_const_int (&operands[1], QImode)) 5762 return "sub{b}\t{%1, %0|%0, %1}"; 5763 5764 return "add{b}\t{%1, %0|%0, %1}"; 5765 } 5766} 5767 [(set (attr "type") 5768 (if_then_else (match_operand:QI 1 "incdec_operand" "") 5769 (const_string "incdec") 5770 (const_string "alu1"))) 5771 (set (attr "memory") 5772 (if_then_else (match_operand 1 "memory_operand" "") 5773 (const_string "load") 5774 (const_string "none"))) 5775 (set_attr "mode" "QI")]) 5776 5777;; Split non destructive adds if we cannot use lea. 5778(define_split 5779 [(set (match_operand:SWI48 0 "register_operand" "") 5780 (plus:SWI48 (match_operand:SWI48 1 "register_operand" "") 5781 (match_operand:SWI48 2 "nonmemory_operand" ""))) 5782 (clobber (reg:CC FLAGS_REG))] 5783 "reload_completed && ix86_avoid_lea_for_add (insn, operands)" 5784 [(set (match_dup 0) (match_dup 1)) 5785 (parallel [(set (match_dup 0) (plus:<MODE> (match_dup 0) (match_dup 2))) 5786 (clobber (reg:CC FLAGS_REG))])]) 5787 5788;; Convert add to the lea pattern to avoid flags dependency. 5789(define_split 5790 [(set (match_operand:SWI 0 "register_operand" "") 5791 (plus:SWI (match_operand:SWI 1 "register_operand" "") 5792 (match_operand:SWI 2 "<nonmemory_operand>" ""))) 5793 (clobber (reg:CC FLAGS_REG))] 5794 "reload_completed && ix86_lea_for_add_ok (insn, operands)" 5795 [(const_int 0)] 5796{ 5797 enum machine_mode mode = <MODE>mode; 5798 rtx pat; 5799 5800 if (GET_MODE_SIZE (mode) < GET_MODE_SIZE (SImode)) 5801 { 5802 mode = SImode; 5803 operands[0] = gen_lowpart (mode, operands[0]); 5804 operands[1] = gen_lowpart (mode, operands[1]); 5805 operands[2] = gen_lowpart (mode, operands[2]); 5806 } 5807 5808 pat = gen_rtx_PLUS (mode, operands[1], operands[2]); 5809 5810 emit_insn (gen_rtx_SET (VOIDmode, operands[0], pat)); 5811 DONE; 5812}) 5813 5814;; Convert add to the lea pattern to avoid flags dependency. 5815(define_split 5816 [(set (match_operand:DI 0 "register_operand" "") 5817 (zero_extend:DI 5818 (plus:SI (match_operand:SI 1 "register_operand" "") 5819 (match_operand:SI 2 "x86_64_nonmemory_operand" "")))) 5820 (clobber (reg:CC FLAGS_REG))] 5821 "TARGET_64BIT && reload_completed && ix86_lea_for_add_ok (insn, operands)" 5822 [(set (match_dup 0) 5823 (zero_extend:DI (plus:SI (match_dup 1) (match_dup 2))))]) 5824 5825(define_insn "*add<mode>_2" 5826 [(set (reg FLAGS_REG) 5827 (compare 5828 (plus:SWI 5829 (match_operand:SWI 1 "nonimmediate_operand" "%0,0,<r>") 5830 (match_operand:SWI 2 "<general_operand>" "<g>,<r><i>,0")) 5831 (const_int 0))) 5832 (set (match_operand:SWI 0 "nonimmediate_operand" "=<r>,<r>m,<r>") 5833 (plus:SWI (match_dup 1) (match_dup 2)))] 5834 "ix86_match_ccmode (insn, CCGOCmode) 5835 && ix86_binary_operator_ok (PLUS, <MODE>mode, operands)" 5836{ 5837 switch (get_attr_type (insn)) 5838 { 5839 case TYPE_INCDEC: 5840 if (operands[2] == const1_rtx) 5841 return "inc{<imodesuffix>}\t%0"; 5842 else 5843 { 5844 gcc_assert (operands[2] == constm1_rtx); 5845 return "dec{<imodesuffix>}\t%0"; 5846 } 5847 5848 default: 5849 if (which_alternative == 2) 5850 { 5851 rtx tmp; 5852 tmp = operands[1], operands[1] = operands[2], operands[2] = tmp; 5853 } 5854 5855 gcc_assert (rtx_equal_p (operands[0], operands[1])); 5856 if (x86_maybe_negate_const_int (&operands[2], <MODE>mode)) 5857 return "sub{<imodesuffix>}\t{%2, %0|%0, %2}"; 5858 5859 return "add{<imodesuffix>}\t{%2, %0|%0, %2}"; 5860 } 5861} 5862 [(set (attr "type") 5863 (if_then_else (match_operand:SWI 2 "incdec_operand" "") 5864 (const_string "incdec") 5865 (const_string "alu"))) 5866 (set (attr "length_immediate") 5867 (if_then_else 5868 (and (eq_attr "type" "alu") (match_operand 2 "const128_operand" "")) 5869 (const_string "1") 5870 (const_string "*"))) 5871 (set_attr "mode" "<MODE>")]) 5872 5873;; See comment for addsi_1_zext why we do use nonimmediate_operand 5874(define_insn "*addsi_2_zext" 5875 [(set (reg FLAGS_REG) 5876 (compare 5877 (plus:SI (match_operand:SI 1 "nonimmediate_operand" "%0,r") 5878 (match_operand:SI 2 "x86_64_general_operand" "rme,0")) 5879 (const_int 0))) 5880 (set (match_operand:DI 0 "register_operand" "=r,r") 5881 (zero_extend:DI (plus:SI (match_dup 1) (match_dup 2))))] 5882 "TARGET_64BIT && ix86_match_ccmode (insn, CCGOCmode) 5883 && ix86_binary_operator_ok (PLUS, SImode, operands)" 5884{ 5885 switch (get_attr_type (insn)) 5886 { 5887 case TYPE_INCDEC: 5888 if (operands[2] == const1_rtx) 5889 return "inc{l}\t%k0"; 5890 else 5891 { 5892 gcc_assert (operands[2] == constm1_rtx); 5893 return "dec{l}\t%k0"; 5894 } 5895 5896 default: 5897 if (which_alternative == 1) 5898 { 5899 rtx tmp; 5900 tmp = operands[1], operands[1] = operands[2], operands[2] = tmp; 5901 } 5902 5903 if (x86_maybe_negate_const_int (&operands[2], SImode)) 5904 return "sub{l}\t{%2, %k0|%k0, %2}"; 5905 5906 return "add{l}\t{%2, %k0|%k0, %2}"; 5907 } 5908} 5909 [(set (attr "type") 5910 (if_then_else (match_operand:SI 2 "incdec_operand" "") 5911 (const_string "incdec") 5912 (const_string "alu"))) 5913 (set (attr "length_immediate") 5914 (if_then_else 5915 (and (eq_attr "type" "alu") (match_operand 2 "const128_operand" "")) 5916 (const_string "1") 5917 (const_string "*"))) 5918 (set_attr "mode" "SI")]) 5919 5920(define_insn "*add<mode>_3" 5921 [(set (reg FLAGS_REG) 5922 (compare 5923 (neg:SWI (match_operand:SWI 2 "<general_operand>" "<g>,0")) 5924 (match_operand:SWI 1 "nonimmediate_operand" "%0,<r>"))) 5925 (clobber (match_scratch:SWI 0 "=<r>,<r>"))] 5926 "ix86_match_ccmode (insn, CCZmode) 5927 && !(MEM_P (operands[1]) && MEM_P (operands[2]))" 5928{ 5929 switch (get_attr_type (insn)) 5930 { 5931 case TYPE_INCDEC: 5932 if (operands[2] == const1_rtx) 5933 return "inc{<imodesuffix>}\t%0"; 5934 else 5935 { 5936 gcc_assert (operands[2] == constm1_rtx); 5937 return "dec{<imodesuffix>}\t%0"; 5938 } 5939 5940 default: 5941 if (which_alternative == 1) 5942 { 5943 rtx tmp; 5944 tmp = operands[1], operands[1] = operands[2], operands[2] = tmp; 5945 } 5946 5947 gcc_assert (rtx_equal_p (operands[0], operands[1])); 5948 if (x86_maybe_negate_const_int (&operands[2], <MODE>mode)) 5949 return "sub{<imodesuffix>}\t{%2, %0|%0, %2}"; 5950 5951 return "add{<imodesuffix>}\t{%2, %0|%0, %2}"; 5952 } 5953} 5954 [(set (attr "type") 5955 (if_then_else (match_operand:SWI 2 "incdec_operand" "") 5956 (const_string "incdec") 5957 (const_string "alu"))) 5958 (set (attr "length_immediate") 5959 (if_then_else 5960 (and (eq_attr "type" "alu") (match_operand 2 "const128_operand" "")) 5961 (const_string "1") 5962 (const_string "*"))) 5963 (set_attr "mode" "<MODE>")]) 5964 5965;; See comment for addsi_1_zext why we do use nonimmediate_operand 5966(define_insn "*addsi_3_zext" 5967 [(set (reg FLAGS_REG) 5968 (compare 5969 (neg:SI (match_operand:SI 2 "x86_64_general_operand" "rme,0")) 5970 (match_operand:SI 1 "nonimmediate_operand" "%0,r"))) 5971 (set (match_operand:DI 0 "register_operand" "=r,r") 5972 (zero_extend:DI (plus:SI (match_dup 1) (match_dup 2))))] 5973 "TARGET_64BIT && ix86_match_ccmode (insn, CCZmode) 5974 && ix86_binary_operator_ok (PLUS, SImode, operands)" 5975{ 5976 switch (get_attr_type (insn)) 5977 { 5978 case TYPE_INCDEC: 5979 if (operands[2] == const1_rtx) 5980 return "inc{l}\t%k0"; 5981 else 5982 { 5983 gcc_assert (operands[2] == constm1_rtx); 5984 return "dec{l}\t%k0"; 5985 } 5986 5987 default: 5988 if (which_alternative == 1) 5989 { 5990 rtx tmp; 5991 tmp = operands[1], operands[1] = operands[2], operands[2] = tmp; 5992 } 5993 5994 if (x86_maybe_negate_const_int (&operands[2], SImode)) 5995 return "sub{l}\t{%2, %k0|%k0, %2}"; 5996 5997 return "add{l}\t{%2, %k0|%k0, %2}"; 5998 } 5999} 6000 [(set (attr "type") 6001 (if_then_else (match_operand:SI 2 "incdec_operand" "") 6002 (const_string "incdec") 6003 (const_string "alu"))) 6004 (set (attr "length_immediate") 6005 (if_then_else 6006 (and (eq_attr "type" "alu") (match_operand 2 "const128_operand" "")) 6007 (const_string "1") 6008 (const_string "*"))) 6009 (set_attr "mode" "SI")]) 6010 6011; For comparisons against 1, -1 and 128, we may generate better code 6012; by converting cmp to add, inc or dec as done by peephole2. This pattern 6013; is matched then. We can't accept general immediate, because for 6014; case of overflows, the result is messed up. 6015; Also carry flag is reversed compared to cmp, so this conversion is valid 6016; only for comparisons not depending on it. 6017 6018(define_insn "*adddi_4" 6019 [(set (reg FLAGS_REG) 6020 (compare 6021 (match_operand:DI 1 "nonimmediate_operand" "0") 6022 (match_operand:DI 2 "x86_64_immediate_operand" "e"))) 6023 (clobber (match_scratch:DI 0 "=rm"))] 6024 "TARGET_64BIT 6025 && ix86_match_ccmode (insn, CCGCmode)" 6026{ 6027 switch (get_attr_type (insn)) 6028 { 6029 case TYPE_INCDEC: 6030 if (operands[2] == constm1_rtx) 6031 return "inc{q}\t%0"; 6032 else 6033 { 6034 gcc_assert (operands[2] == const1_rtx); 6035 return "dec{q}\t%0"; 6036 } 6037 6038 default: 6039 if (x86_maybe_negate_const_int (&operands[2], DImode)) 6040 return "add{q}\t{%2, %0|%0, %2}"; 6041 6042 return "sub{q}\t{%2, %0|%0, %2}"; 6043 } 6044} 6045 [(set (attr "type") 6046 (if_then_else (match_operand:DI 2 "incdec_operand" "") 6047 (const_string "incdec") 6048 (const_string "alu"))) 6049 (set (attr "length_immediate") 6050 (if_then_else 6051 (and (eq_attr "type" "alu") (match_operand 2 "const128_operand" "")) 6052 (const_string "1") 6053 (const_string "*"))) 6054 (set_attr "mode" "DI")]) 6055 6056; For comparisons against 1, -1 and 128, we may generate better code 6057; by converting cmp to add, inc or dec as done by peephole2. This pattern 6058; is matched then. We can't accept general immediate, because for 6059; case of overflows, the result is messed up. 6060; Also carry flag is reversed compared to cmp, so this conversion is valid 6061; only for comparisons not depending on it. 6062 6063(define_insn "*add<mode>_4" 6064 [(set (reg FLAGS_REG) 6065 (compare 6066 (match_operand:SWI124 1 "nonimmediate_operand" "0") 6067 (match_operand:SWI124 2 "const_int_operand" "n"))) 6068 (clobber (match_scratch:SWI124 0 "=<r>m"))] 6069 "ix86_match_ccmode (insn, CCGCmode)" 6070{ 6071 switch (get_attr_type (insn)) 6072 { 6073 case TYPE_INCDEC: 6074 if (operands[2] == constm1_rtx) 6075 return "inc{<imodesuffix>}\t%0"; 6076 else 6077 { 6078 gcc_assert (operands[2] == const1_rtx); 6079 return "dec{<imodesuffix>}\t%0"; 6080 } 6081 6082 default: 6083 if (x86_maybe_negate_const_int (&operands[2], <MODE>mode)) 6084 return "add{<imodesuffix>}\t{%2, %0|%0, %2}"; 6085 6086 return "sub{<imodesuffix>}\t{%2, %0|%0, %2}"; 6087 } 6088} 6089 [(set (attr "type") 6090 (if_then_else (match_operand:<MODE> 2 "incdec_operand" "") 6091 (const_string "incdec") 6092 (const_string "alu"))) 6093 (set (attr "length_immediate") 6094 (if_then_else 6095 (and (eq_attr "type" "alu") (match_operand 2 "const128_operand" "")) 6096 (const_string "1") 6097 (const_string "*"))) 6098 (set_attr "mode" "<MODE>")]) 6099 6100(define_insn "*add<mode>_5" 6101 [(set (reg FLAGS_REG) 6102 (compare 6103 (plus:SWI 6104 (match_operand:SWI 1 "nonimmediate_operand" "%0,<r>") 6105 (match_operand:SWI 2 "<general_operand>" "<g>,0")) 6106 (const_int 0))) 6107 (clobber (match_scratch:SWI 0 "=<r>,<r>"))] 6108 "ix86_match_ccmode (insn, CCGOCmode) 6109 && !(MEM_P (operands[1]) && MEM_P (operands[2]))" 6110{ 6111 switch (get_attr_type (insn)) 6112 { 6113 case TYPE_INCDEC: 6114 if (operands[2] == const1_rtx) 6115 return "inc{<imodesuffix>}\t%0"; 6116 else 6117 { 6118 gcc_assert (operands[2] == constm1_rtx); 6119 return "dec{<imodesuffix>}\t%0"; 6120 } 6121 6122 default: 6123 if (which_alternative == 1) 6124 { 6125 rtx tmp; 6126 tmp = operands[1], operands[1] = operands[2], operands[2] = tmp; 6127 } 6128 6129 gcc_assert (rtx_equal_p (operands[0], operands[1])); 6130 if (x86_maybe_negate_const_int (&operands[2], <MODE>mode)) 6131 return "sub{<imodesuffix>}\t{%2, %0|%0, %2}"; 6132 6133 return "add{<imodesuffix>}\t{%2, %0|%0, %2}"; 6134 } 6135} 6136 [(set (attr "type") 6137 (if_then_else (match_operand:SWI 2 "incdec_operand" "") 6138 (const_string "incdec") 6139 (const_string "alu"))) 6140 (set (attr "length_immediate") 6141 (if_then_else 6142 (and (eq_attr "type" "alu") (match_operand 2 "const128_operand" "")) 6143 (const_string "1") 6144 (const_string "*"))) 6145 (set_attr "mode" "<MODE>")]) 6146 6147(define_insn "*addqi_ext_1_rex64" 6148 [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q") 6149 (const_int 8) 6150 (const_int 8)) 6151 (plus:SI 6152 (zero_extract:SI 6153 (match_operand 1 "ext_register_operand" "0") 6154 (const_int 8) 6155 (const_int 8)) 6156 (match_operand:QI 2 "nonmemory_operand" "Qn"))) 6157 (clobber (reg:CC FLAGS_REG))] 6158 "TARGET_64BIT" 6159{ 6160 switch (get_attr_type (insn)) 6161 { 6162 case TYPE_INCDEC: 6163 if (operands[2] == const1_rtx) 6164 return "inc{b}\t%h0"; 6165 else 6166 { 6167 gcc_assert (operands[2] == constm1_rtx); 6168 return "dec{b}\t%h0"; 6169 } 6170 6171 default: 6172 return "add{b}\t{%2, %h0|%h0, %2}"; 6173 } 6174} 6175 [(set (attr "type") 6176 (if_then_else (match_operand:QI 2 "incdec_operand" "") 6177 (const_string "incdec") 6178 (const_string "alu"))) 6179 (set_attr "modrm" "1") 6180 (set_attr "mode" "QI")]) 6181 6182(define_insn "addqi_ext_1" 6183 [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q") 6184 (const_int 8) 6185 (const_int 8)) 6186 (plus:SI 6187 (zero_extract:SI 6188 (match_operand 1 "ext_register_operand" "0") 6189 (const_int 8) 6190 (const_int 8)) 6191 (match_operand:QI 2 "general_operand" "Qmn"))) 6192 (clobber (reg:CC FLAGS_REG))] 6193 "!TARGET_64BIT" 6194{ 6195 switch (get_attr_type (insn)) 6196 { 6197 case TYPE_INCDEC: 6198 if (operands[2] == const1_rtx) 6199 return "inc{b}\t%h0"; 6200 else 6201 { 6202 gcc_assert (operands[2] == constm1_rtx); 6203 return "dec{b}\t%h0"; 6204 } 6205 6206 default: 6207 return "add{b}\t{%2, %h0|%h0, %2}"; 6208 } 6209} 6210 [(set (attr "type") 6211 (if_then_else (match_operand:QI 2 "incdec_operand" "") 6212 (const_string "incdec") 6213 (const_string "alu"))) 6214 (set_attr "modrm" "1") 6215 (set_attr "mode" "QI")]) 6216 6217(define_insn "*addqi_ext_2" 6218 [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q") 6219 (const_int 8) 6220 (const_int 8)) 6221 (plus:SI 6222 (zero_extract:SI 6223 (match_operand 1 "ext_register_operand" "%0") 6224 (const_int 8) 6225 (const_int 8)) 6226 (zero_extract:SI 6227 (match_operand 2 "ext_register_operand" "Q") 6228 (const_int 8) 6229 (const_int 8)))) 6230 (clobber (reg:CC FLAGS_REG))] 6231 "" 6232 "add{b}\t{%h2, %h0|%h0, %h2}" 6233 [(set_attr "type" "alu") 6234 (set_attr "mode" "QI")]) 6235 6236;; The lea patterns for modes less than 32 bits need to be matched by 6237;; several insns converted to real lea by splitters. 6238 6239(define_insn_and_split "*lea_general_1" 6240 [(set (match_operand 0 "register_operand" "=r") 6241 (plus (plus (match_operand 1 "index_register_operand" "l") 6242 (match_operand 2 "register_operand" "r")) 6243 (match_operand 3 "immediate_operand" "i")))] 6244 "(GET_MODE (operands[0]) == QImode || GET_MODE (operands[0]) == HImode) 6245 && (!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun)) 6246 && GET_MODE (operands[0]) == GET_MODE (operands[1]) 6247 && GET_MODE (operands[0]) == GET_MODE (operands[2]) 6248 && (GET_MODE (operands[0]) == GET_MODE (operands[3]) 6249 || GET_MODE (operands[3]) == VOIDmode)" 6250 "#" 6251 "&& reload_completed" 6252 [(const_int 0)] 6253{ 6254 enum machine_mode mode = SImode; 6255 rtx pat; 6256 6257 operands[0] = gen_lowpart (mode, operands[0]); 6258 operands[1] = gen_lowpart (mode, operands[1]); 6259 operands[2] = gen_lowpart (mode, operands[2]); 6260 operands[3] = gen_lowpart (mode, operands[3]); 6261 6262 pat = gen_rtx_PLUS (mode, gen_rtx_PLUS (mode, operands[1], operands[2]), 6263 operands[3]); 6264 6265 emit_insn (gen_rtx_SET (VOIDmode, operands[0], pat)); 6266 DONE; 6267} 6268 [(set_attr "type" "lea") 6269 (set_attr "mode" "SI")]) 6270 6271(define_insn_and_split "*lea_general_2" 6272 [(set (match_operand 0 "register_operand" "=r") 6273 (plus (mult (match_operand 1 "index_register_operand" "l") 6274 (match_operand 2 "const248_operand" "n")) 6275 (match_operand 3 "nonmemory_operand" "ri")))] 6276 "(GET_MODE (operands[0]) == QImode || GET_MODE (operands[0]) == HImode) 6277 && (!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun)) 6278 && GET_MODE (operands[0]) == GET_MODE (operands[1]) 6279 && (GET_MODE (operands[0]) == GET_MODE (operands[3]) 6280 || GET_MODE (operands[3]) == VOIDmode)" 6281 "#" 6282 "&& reload_completed" 6283 [(const_int 0)] 6284{ 6285 enum machine_mode mode = SImode; 6286 rtx pat; 6287 6288 operands[0] = gen_lowpart (mode, operands[0]); 6289 operands[1] = gen_lowpart (mode, operands[1]); 6290 operands[3] = gen_lowpart (mode, operands[3]); 6291 6292 pat = gen_rtx_PLUS (mode, gen_rtx_MULT (mode, operands[1], operands[2]), 6293 operands[3]); 6294 6295 emit_insn (gen_rtx_SET (VOIDmode, operands[0], pat)); 6296 DONE; 6297} 6298 [(set_attr "type" "lea") 6299 (set_attr "mode" "SI")]) 6300 6301(define_insn_and_split "*lea_general_3" 6302 [(set (match_operand 0 "register_operand" "=r") 6303 (plus (plus (mult (match_operand 1 "index_register_operand" "l") 6304 (match_operand 2 "const248_operand" "n")) 6305 (match_operand 3 "register_operand" "r")) 6306 (match_operand 4 "immediate_operand" "i")))] 6307 "(GET_MODE (operands[0]) == QImode || GET_MODE (operands[0]) == HImode) 6308 && (!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun)) 6309 && GET_MODE (operands[0]) == GET_MODE (operands[1]) 6310 && GET_MODE (operands[0]) == GET_MODE (operands[3])" 6311 "#" 6312 "&& reload_completed" 6313 [(const_int 0)] 6314{ 6315 enum machine_mode mode = SImode; 6316 rtx pat; 6317 6318 operands[0] = gen_lowpart (mode, operands[0]); 6319 operands[1] = gen_lowpart (mode, operands[1]); 6320 operands[3] = gen_lowpart (mode, operands[3]); 6321 operands[4] = gen_lowpart (mode, operands[4]); 6322 6323 pat = gen_rtx_PLUS (mode, 6324 gen_rtx_PLUS (mode, 6325 gen_rtx_MULT (mode, operands[1], 6326 operands[2]), 6327 operands[3]), 6328 operands[4]); 6329 6330 emit_insn (gen_rtx_SET (VOIDmode, operands[0], pat)); 6331 DONE; 6332} 6333 [(set_attr "type" "lea") 6334 (set_attr "mode" "SI")]) 6335 6336(define_insn_and_split "*lea_general_4" 6337 [(set (match_operand 0 "register_operand" "=r") 6338 (any_or (ashift 6339 (match_operand 1 "index_register_operand" "l") 6340 (match_operand 2 "const_int_operand" "n")) 6341 (match_operand 3 "const_int_operand" "n")))] 6342 "(((GET_MODE (operands[0]) == QImode || GET_MODE (operands[0]) == HImode) 6343 && (!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))) 6344 || GET_MODE (operands[0]) == SImode 6345 || (TARGET_64BIT && GET_MODE (operands[0]) == DImode)) 6346 && GET_MODE (operands[0]) == GET_MODE (operands[1]) 6347 && ((unsigned HOST_WIDE_INT) INTVAL (operands[2])) - 1 < 3 6348 && ((unsigned HOST_WIDE_INT) INTVAL (operands[3]) 6349 < ((unsigned HOST_WIDE_INT) 1 << INTVAL (operands[2])))" 6350 "#" 6351 "&& reload_completed" 6352 [(const_int 0)] 6353{ 6354 enum machine_mode mode = GET_MODE (operands[0]); 6355 rtx pat; 6356 6357 if (GET_MODE_SIZE (mode) < GET_MODE_SIZE (SImode)) 6358 { 6359 mode = SImode; 6360 operands[0] = gen_lowpart (mode, operands[0]); 6361 operands[1] = gen_lowpart (mode, operands[1]); 6362 } 6363 6364 operands[2] = GEN_INT (1 << INTVAL (operands[2])); 6365 6366 pat = plus_constant (gen_rtx_MULT (mode, operands[1], operands[2]), 6367 INTVAL (operands[3])); 6368 6369 emit_insn (gen_rtx_SET (VOIDmode, operands[0], pat)); 6370 DONE; 6371} 6372 [(set_attr "type" "lea") 6373 (set (attr "mode") 6374 (if_then_else (match_operand:DI 0 "" "") 6375 (const_string "DI") 6376 (const_string "SI")))]) 6377 6378;; Subtract instructions 6379 6380(define_expand "sub<mode>3" 6381 [(set (match_operand:SDWIM 0 "nonimmediate_operand" "") 6382 (minus:SDWIM (match_operand:SDWIM 1 "nonimmediate_operand" "") 6383 (match_operand:SDWIM 2 "<general_operand>" "")))] 6384 "" 6385 "ix86_expand_binary_operator (MINUS, <MODE>mode, operands); DONE;") 6386 6387(define_insn_and_split "*sub<dwi>3_doubleword" 6388 [(set (match_operand:<DWI> 0 "nonimmediate_operand" "=r,o") 6389 (minus:<DWI> 6390 (match_operand:<DWI> 1 "nonimmediate_operand" "0,0") 6391 (match_operand:<DWI> 2 "<general_operand>" "ro<di>,r<di>"))) 6392 (clobber (reg:CC FLAGS_REG))] 6393 "ix86_binary_operator_ok (MINUS, <MODE>mode, operands)" 6394 "#" 6395 "reload_completed" 6396 [(parallel [(set (reg:CC FLAGS_REG) 6397 (compare:CC (match_dup 1) (match_dup 2))) 6398 (set (match_dup 0) 6399 (minus:DWIH (match_dup 1) (match_dup 2)))]) 6400 (parallel [(set (match_dup 3) 6401 (minus:DWIH 6402 (match_dup 4) 6403 (plus:DWIH 6404 (ltu:DWIH (reg:CC FLAGS_REG) (const_int 0)) 6405 (match_dup 5)))) 6406 (clobber (reg:CC FLAGS_REG))])] 6407 "split_double_mode (<DWI>mode, &operands[0], 3, &operands[0], &operands[3]);") 6408 6409(define_insn "*sub<mode>_1" 6410 [(set (match_operand:SWI 0 "nonimmediate_operand" "=<r>m,<r>") 6411 (minus:SWI 6412 (match_operand:SWI 1 "nonimmediate_operand" "0,0") 6413 (match_operand:SWI 2 "<general_operand>" "<r><i>,<r>m"))) 6414 (clobber (reg:CC FLAGS_REG))] 6415 "ix86_binary_operator_ok (MINUS, <MODE>mode, operands)" 6416 "sub{<imodesuffix>}\t{%2, %0|%0, %2}" 6417 [(set_attr "type" "alu") 6418 (set_attr "mode" "<MODE>")]) 6419 6420(define_insn "*subsi_1_zext" 6421 [(set (match_operand:DI 0 "register_operand" "=r") 6422 (zero_extend:DI 6423 (minus:SI (match_operand:SI 1 "register_operand" "0") 6424 (match_operand:SI 2 "x86_64_general_operand" "rme")))) 6425 (clobber (reg:CC FLAGS_REG))] 6426 "TARGET_64BIT && ix86_binary_operator_ok (MINUS, SImode, operands)" 6427 "sub{l}\t{%2, %k0|%k0, %2}" 6428 [(set_attr "type" "alu") 6429 (set_attr "mode" "SI")]) 6430 6431(define_insn "*subqi_1_slp" 6432 [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm,q")) 6433 (minus:QI (match_dup 0) 6434 (match_operand:QI 1 "general_operand" "qn,qm"))) 6435 (clobber (reg:CC FLAGS_REG))] 6436 "(! TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun)) 6437 && !(MEM_P (operands[0]) && MEM_P (operands[1]))" 6438 "sub{b}\t{%1, %0|%0, %1}" 6439 [(set_attr "type" "alu1") 6440 (set_attr "mode" "QI")]) 6441 6442(define_insn "*sub<mode>_2" 6443 [(set (reg FLAGS_REG) 6444 (compare 6445 (minus:SWI 6446 (match_operand:SWI 1 "nonimmediate_operand" "0,0") 6447 (match_operand:SWI 2 "<general_operand>" "<r><i>,<r>m")) 6448 (const_int 0))) 6449 (set (match_operand:SWI 0 "nonimmediate_operand" "=<r>m,<r>") 6450 (minus:SWI (match_dup 1) (match_dup 2)))] 6451 "ix86_match_ccmode (insn, CCGOCmode) 6452 && ix86_binary_operator_ok (MINUS, <MODE>mode, operands)" 6453 "sub{<imodesuffix>}\t{%2, %0|%0, %2}" 6454 [(set_attr "type" "alu") 6455 (set_attr "mode" "<MODE>")]) 6456 6457(define_insn "*subsi_2_zext" 6458 [(set (reg FLAGS_REG) 6459 (compare 6460 (minus:SI (match_operand:SI 1 "register_operand" "0") 6461 (match_operand:SI 2 "x86_64_general_operand" "rme")) 6462 (const_int 0))) 6463 (set (match_operand:DI 0 "register_operand" "=r") 6464 (zero_extend:DI 6465 (minus:SI (match_dup 1) 6466 (match_dup 2))))] 6467 "TARGET_64BIT && ix86_match_ccmode (insn, CCGOCmode) 6468 && ix86_binary_operator_ok (MINUS, SImode, operands)" 6469 "sub{l}\t{%2, %k0|%k0, %2}" 6470 [(set_attr "type" "alu") 6471 (set_attr "mode" "SI")]) 6472 6473(define_insn "*sub<mode>_3" 6474 [(set (reg FLAGS_REG) 6475 (compare (match_operand:SWI 1 "nonimmediate_operand" "0,0") 6476 (match_operand:SWI 2 "<general_operand>" "<r><i>,<r>m"))) 6477 (set (match_operand:SWI 0 "nonimmediate_operand" "=<r>m,<r>") 6478 (minus:SWI (match_dup 1) (match_dup 2)))] 6479 "ix86_match_ccmode (insn, CCmode) 6480 && ix86_binary_operator_ok (MINUS, <MODE>mode, operands)" 6481 "sub{<imodesuffix>}\t{%2, %0|%0, %2}" 6482 [(set_attr "type" "alu") 6483 (set_attr "mode" "<MODE>")]) 6484 6485(define_insn "*subsi_3_zext" 6486 [(set (reg FLAGS_REG) 6487 (compare (match_operand:SI 1 "register_operand" "0") 6488 (match_operand:SI 2 "x86_64_general_operand" "rme"))) 6489 (set (match_operand:DI 0 "register_operand" "=r") 6490 (zero_extend:DI 6491 (minus:SI (match_dup 1) 6492 (match_dup 2))))] 6493 "TARGET_64BIT && ix86_match_ccmode (insn, CCmode) 6494 && ix86_binary_operator_ok (MINUS, SImode, operands)" 6495 "sub{l}\t{%2, %1|%1, %2}" 6496 [(set_attr "type" "alu") 6497 (set_attr "mode" "SI")]) 6498 6499;; Add with carry and subtract with borrow 6500 6501(define_expand "<plusminus_insn><mode>3_carry" 6502 [(parallel 6503 [(set (match_operand:SWI 0 "nonimmediate_operand" "") 6504 (plusminus:SWI 6505 (match_operand:SWI 1 "nonimmediate_operand" "") 6506 (plus:SWI (match_operator:SWI 4 "ix86_carry_flag_operator" 6507 [(match_operand 3 "flags_reg_operand" "") 6508 (const_int 0)]) 6509 (match_operand:SWI 2 "<general_operand>" "")))) 6510 (clobber (reg:CC FLAGS_REG))])] 6511 "ix86_binary_operator_ok (<CODE>, <MODE>mode, operands)") 6512 6513(define_insn "*<plusminus_insn><mode>3_carry" 6514 [(set (match_operand:SWI 0 "nonimmediate_operand" "=<r>m,<r>") 6515 (plusminus:SWI 6516 (match_operand:SWI 1 "nonimmediate_operand" "<comm>0,0") 6517 (plus:SWI 6518 (match_operator 3 "ix86_carry_flag_operator" 6519 [(reg FLAGS_REG) (const_int 0)]) 6520 (match_operand:SWI 2 "<general_operand>" "<r><i>,<r>m")))) 6521 (clobber (reg:CC FLAGS_REG))] 6522 "ix86_binary_operator_ok (PLUS, <MODE>mode, operands)" 6523 "<plusminus_carry_mnemonic>{<imodesuffix>}\t{%2, %0|%0, %2}" 6524 [(set_attr "type" "alu") 6525 (set_attr "use_carry" "1") 6526 (set_attr "pent_pair" "pu") 6527 (set_attr "mode" "<MODE>")]) 6528 6529(define_insn "*addsi3_carry_zext" 6530 [(set (match_operand:DI 0 "register_operand" "=r") 6531 (zero_extend:DI 6532 (plus:SI (match_operand:SI 1 "nonimmediate_operand" "%0") 6533 (plus:SI (match_operator 3 "ix86_carry_flag_operator" 6534 [(reg FLAGS_REG) (const_int 0)]) 6535 (match_operand:SI 2 "x86_64_general_operand" "rme"))))) 6536 (clobber (reg:CC FLAGS_REG))] 6537 "TARGET_64BIT && ix86_binary_operator_ok (PLUS, SImode, operands)" 6538 "adc{l}\t{%2, %k0|%k0, %2}" 6539 [(set_attr "type" "alu") 6540 (set_attr "use_carry" "1") 6541 (set_attr "pent_pair" "pu") 6542 (set_attr "mode" "SI")]) 6543 6544(define_insn "*subsi3_carry_zext" 6545 [(set (match_operand:DI 0 "register_operand" "=r") 6546 (zero_extend:DI 6547 (minus:SI (match_operand:SI 1 "register_operand" "0") 6548 (plus:SI (match_operator 3 "ix86_carry_flag_operator" 6549 [(reg FLAGS_REG) (const_int 0)]) 6550 (match_operand:SI 2 "x86_64_general_operand" "rme"))))) 6551 (clobber (reg:CC FLAGS_REG))] 6552 "TARGET_64BIT && ix86_binary_operator_ok (MINUS, SImode, operands)" 6553 "sbb{l}\t{%2, %k0|%k0, %2}" 6554 [(set_attr "type" "alu") 6555 (set_attr "pent_pair" "pu") 6556 (set_attr "mode" "SI")]) 6557 6558;; Overflow setting add instructions 6559 6560(define_insn "*add<mode>3_cconly_overflow" 6561 [(set (reg:CCC FLAGS_REG) 6562 (compare:CCC 6563 (plus:SWI 6564 (match_operand:SWI 1 "nonimmediate_operand" "%0") 6565 (match_operand:SWI 2 "<general_operand>" "<g>")) 6566 (match_dup 1))) 6567 (clobber (match_scratch:SWI 0 "=<r>"))] 6568 "!(MEM_P (operands[1]) && MEM_P (operands[2]))" 6569 "add{<imodesuffix>}\t{%2, %0|%0, %2}" 6570 [(set_attr "type" "alu") 6571 (set_attr "mode" "<MODE>")]) 6572 6573(define_insn "*add<mode>3_cc_overflow" 6574 [(set (reg:CCC FLAGS_REG) 6575 (compare:CCC 6576 (plus:SWI 6577 (match_operand:SWI 1 "nonimmediate_operand" "%0,0") 6578 (match_operand:SWI 2 "<general_operand>" "<r><i>,<r>m")) 6579 (match_dup 1))) 6580 (set (match_operand:SWI 0 "nonimmediate_operand" "=<r>m,<r>") 6581 (plus:SWI (match_dup 1) (match_dup 2)))] 6582 "ix86_binary_operator_ok (PLUS, <MODE>mode, operands)" 6583 "add{<imodesuffix>}\t{%2, %0|%0, %2}" 6584 [(set_attr "type" "alu") 6585 (set_attr "mode" "<MODE>")]) 6586 6587(define_insn "*addsi3_zext_cc_overflow" 6588 [(set (reg:CCC FLAGS_REG) 6589 (compare:CCC 6590 (plus:SI 6591 (match_operand:SI 1 "nonimmediate_operand" "%0") 6592 (match_operand:SI 2 "x86_64_general_operand" "rme")) 6593 (match_dup 1))) 6594 (set (match_operand:DI 0 "register_operand" "=r") 6595 (zero_extend:DI (plus:SI (match_dup 1) (match_dup 2))))] 6596 "TARGET_64BIT && ix86_binary_operator_ok (PLUS, SImode, operands)" 6597 "add{l}\t{%2, %k0|%k0, %2}" 6598 [(set_attr "type" "alu") 6599 (set_attr "mode" "SI")]) 6600 6601;; The patterns that match these are at the end of this file. 6602 6603(define_expand "<plusminus_insn>xf3" 6604 [(set (match_operand:XF 0 "register_operand" "") 6605 (plusminus:XF 6606 (match_operand:XF 1 "register_operand" "") 6607 (match_operand:XF 2 "register_operand" "")))] 6608 "TARGET_80387") 6609 6610(define_expand "<plusminus_insn><mode>3" 6611 [(set (match_operand:MODEF 0 "register_operand" "") 6612 (plusminus:MODEF 6613 (match_operand:MODEF 1 "register_operand" "") 6614 (match_operand:MODEF 2 "nonimmediate_operand" "")))] 6615 "(TARGET_80387 && X87_ENABLE_ARITH (<MODE>mode)) 6616 || (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)") 6617 6618;; Multiply instructions 6619 6620(define_expand "mul<mode>3" 6621 [(parallel [(set (match_operand:SWIM248 0 "register_operand" "") 6622 (mult:SWIM248 6623 (match_operand:SWIM248 1 "register_operand" "") 6624 (match_operand:SWIM248 2 "<general_operand>" ""))) 6625 (clobber (reg:CC FLAGS_REG))])]) 6626 6627(define_expand "mulqi3" 6628 [(parallel [(set (match_operand:QI 0 "register_operand" "") 6629 (mult:QI 6630 (match_operand:QI 1 "register_operand" "") 6631 (match_operand:QI 2 "nonimmediate_operand" ""))) 6632 (clobber (reg:CC FLAGS_REG))])] 6633 "TARGET_QIMODE_MATH") 6634 6635;; On AMDFAM10 6636;; IMUL reg32/64, reg32/64, imm8 Direct 6637;; IMUL reg32/64, mem32/64, imm8 VectorPath 6638;; IMUL reg32/64, reg32/64, imm32 Direct 6639;; IMUL reg32/64, mem32/64, imm32 VectorPath 6640;; IMUL reg32/64, reg32/64 Direct 6641;; IMUL reg32/64, mem32/64 Direct 6642;; 6643;; On BDVER1, all above IMULs use DirectPath 6644 6645(define_insn "*mul<mode>3_1" 6646 [(set (match_operand:SWI48 0 "register_operand" "=r,r,r") 6647 (mult:SWI48 6648 (match_operand:SWI48 1 "nonimmediate_operand" "%rm,rm,0") 6649 (match_operand:SWI48 2 "<general_operand>" "K,<i>,mr"))) 6650 (clobber (reg:CC FLAGS_REG))] 6651 "!(MEM_P (operands[1]) && MEM_P (operands[2]))" 6652 "@ 6653 imul{<imodesuffix>}\t{%2, %1, %0|%0, %1, %2} 6654 imul{<imodesuffix>}\t{%2, %1, %0|%0, %1, %2} 6655 imul{<imodesuffix>}\t{%2, %0|%0, %2}" 6656 [(set_attr "type" "imul") 6657 (set_attr "prefix_0f" "0,0,1") 6658 (set (attr "athlon_decode") 6659 (cond [(eq_attr "cpu" "athlon") 6660 (const_string "vector") 6661 (eq_attr "alternative" "1") 6662 (const_string "vector") 6663 (and (eq_attr "alternative" "2") 6664 (match_operand 1 "memory_operand" "")) 6665 (const_string "vector")] 6666 (const_string "direct"))) 6667 (set (attr "amdfam10_decode") 6668 (cond [(and (eq_attr "alternative" "0,1") 6669 (match_operand 1 "memory_operand" "")) 6670 (const_string "vector")] 6671 (const_string "direct"))) 6672 (set_attr "bdver1_decode" "direct") 6673 (set_attr "mode" "<MODE>")]) 6674 6675(define_insn "*mulsi3_1_zext" 6676 [(set (match_operand:DI 0 "register_operand" "=r,r,r") 6677 (zero_extend:DI 6678 (mult:SI (match_operand:SI 1 "nonimmediate_operand" "%rm,rm,0") 6679 (match_operand:SI 2 "x86_64_general_operand" "K,e,mr")))) 6680 (clobber (reg:CC FLAGS_REG))] 6681 "TARGET_64BIT 6682 && !(MEM_P (operands[1]) && MEM_P (operands[2]))" 6683 "@ 6684 imul{l}\t{%2, %1, %k0|%k0, %1, %2} 6685 imul{l}\t{%2, %1, %k0|%k0, %1, %2} 6686 imul{l}\t{%2, %k0|%k0, %2}" 6687 [(set_attr "type" "imul") 6688 (set_attr "prefix_0f" "0,0,1") 6689 (set (attr "athlon_decode") 6690 (cond [(eq_attr "cpu" "athlon") 6691 (const_string "vector") 6692 (eq_attr "alternative" "1") 6693 (const_string "vector") 6694 (and (eq_attr "alternative" "2") 6695 (match_operand 1 "memory_operand" "")) 6696 (const_string "vector")] 6697 (const_string "direct"))) 6698 (set (attr "amdfam10_decode") 6699 (cond [(and (eq_attr "alternative" "0,1") 6700 (match_operand 1 "memory_operand" "")) 6701 (const_string "vector")] 6702 (const_string "direct"))) 6703 (set_attr "bdver1_decode" "direct") 6704 (set_attr "mode" "SI")]) 6705 6706;; On AMDFAM10 6707;; IMUL reg16, reg16, imm8 VectorPath 6708;; IMUL reg16, mem16, imm8 VectorPath 6709;; IMUL reg16, reg16, imm16 VectorPath 6710;; IMUL reg16, mem16, imm16 VectorPath 6711;; IMUL reg16, reg16 Direct 6712;; IMUL reg16, mem16 Direct 6713;; 6714;; On BDVER1, all HI MULs use DoublePath 6715 6716(define_insn "*mulhi3_1" 6717 [(set (match_operand:HI 0 "register_operand" "=r,r,r") 6718 (mult:HI (match_operand:HI 1 "nonimmediate_operand" "%rm,rm,0") 6719 (match_operand:HI 2 "general_operand" "K,n,mr"))) 6720 (clobber (reg:CC FLAGS_REG))] 6721 "TARGET_HIMODE_MATH 6722 && !(MEM_P (operands[1]) && MEM_P (operands[2]))" 6723 "@ 6724 imul{w}\t{%2, %1, %0|%0, %1, %2} 6725 imul{w}\t{%2, %1, %0|%0, %1, %2} 6726 imul{w}\t{%2, %0|%0, %2}" 6727 [(set_attr "type" "imul") 6728 (set_attr "prefix_0f" "0,0,1") 6729 (set (attr "athlon_decode") 6730 (cond [(eq_attr "cpu" "athlon") 6731 (const_string "vector") 6732 (eq_attr "alternative" "1,2") 6733 (const_string "vector")] 6734 (const_string "direct"))) 6735 (set (attr "amdfam10_decode") 6736 (cond [(eq_attr "alternative" "0,1") 6737 (const_string "vector")] 6738 (const_string "direct"))) 6739 (set_attr "bdver1_decode" "double") 6740 (set_attr "mode" "HI")]) 6741 6742;;On AMDFAM10 and BDVER1 6743;; MUL reg8 Direct 6744;; MUL mem8 Direct 6745 6746(define_insn "*mulqi3_1" 6747 [(set (match_operand:QI 0 "register_operand" "=a") 6748 (mult:QI (match_operand:QI 1 "nonimmediate_operand" "%0") 6749 (match_operand:QI 2 "nonimmediate_operand" "qm"))) 6750 (clobber (reg:CC FLAGS_REG))] 6751 "TARGET_QIMODE_MATH 6752 && !(MEM_P (operands[1]) && MEM_P (operands[2]))" 6753 "mul{b}\t%2" 6754 [(set_attr "type" "imul") 6755 (set_attr "length_immediate" "0") 6756 (set (attr "athlon_decode") 6757 (if_then_else (eq_attr "cpu" "athlon") 6758 (const_string "vector") 6759 (const_string "direct"))) 6760 (set_attr "amdfam10_decode" "direct") 6761 (set_attr "bdver1_decode" "direct") 6762 (set_attr "mode" "QI")]) 6763 6764(define_expand "<u>mul<mode><dwi>3" 6765 [(parallel [(set (match_operand:<DWI> 0 "register_operand" "") 6766 (mult:<DWI> 6767 (any_extend:<DWI> 6768 (match_operand:DWIH 1 "nonimmediate_operand" "")) 6769 (any_extend:<DWI> 6770 (match_operand:DWIH 2 "register_operand" "")))) 6771 (clobber (reg:CC FLAGS_REG))])]) 6772 6773(define_expand "<u>mulqihi3" 6774 [(parallel [(set (match_operand:HI 0 "register_operand" "") 6775 (mult:HI 6776 (any_extend:HI 6777 (match_operand:QI 1 "nonimmediate_operand" "")) 6778 (any_extend:HI 6779 (match_operand:QI 2 "register_operand" "")))) 6780 (clobber (reg:CC FLAGS_REG))])] 6781 "TARGET_QIMODE_MATH") 6782 6783(define_insn "*bmi2_umulditi3_1" 6784 [(set (match_operand:DI 0 "register_operand" "=r") 6785 (mult:DI 6786 (match_operand:DI 2 "nonimmediate_operand" "%d") 6787 (match_operand:DI 3 "nonimmediate_operand" "rm"))) 6788 (set (match_operand:DI 1 "register_operand" "=r") 6789 (truncate:DI 6790 (lshiftrt:TI 6791 (mult:TI (zero_extend:TI (match_dup 2)) 6792 (zero_extend:TI (match_dup 3))) 6793 (const_int 64))))] 6794 "TARGET_64BIT && TARGET_BMI2 6795 && !(MEM_P (operands[1]) && MEM_P (operands[2]))" 6796 "mulx\t{%3, %0, %1|%1, %0, %3}" 6797 [(set_attr "type" "imulx") 6798 (set_attr "prefix" "vex") 6799 (set_attr "mode" "DI")]) 6800 6801(define_insn "*bmi2_umulsidi3_1" 6802 [(set (match_operand:SI 0 "register_operand" "=r") 6803 (mult:SI 6804 (match_operand:SI 2 "nonimmediate_operand" "%d") 6805 (match_operand:SI 3 "nonimmediate_operand" "rm"))) 6806 (set (match_operand:SI 1 "register_operand" "=r") 6807 (truncate:SI 6808 (lshiftrt:DI 6809 (mult:DI (zero_extend:DI (match_dup 2)) 6810 (zero_extend:DI (match_dup 3))) 6811 (const_int 32))))] 6812 "!TARGET_64BIT && TARGET_BMI2 6813 && !(MEM_P (operands[1]) && MEM_P (operands[2]))" 6814 "mulx\t{%3, %0, %1|%1, %0, %3}" 6815 [(set_attr "type" "imulx") 6816 (set_attr "prefix" "vex") 6817 (set_attr "mode" "SI")]) 6818 6819(define_insn "*umul<mode><dwi>3_1" 6820 [(set (match_operand:<DWI> 0 "register_operand" "=A,r") 6821 (mult:<DWI> 6822 (zero_extend:<DWI> 6823 (match_operand:DWIH 1 "nonimmediate_operand" "%0,d")) 6824 (zero_extend:<DWI> 6825 (match_operand:DWIH 2 "nonimmediate_operand" "rm,rm")))) 6826 (clobber (reg:CC FLAGS_REG))] 6827 "!(MEM_P (operands[1]) && MEM_P (operands[2]))" 6828 "@ 6829 mul{<imodesuffix>}\t%2 6830 #" 6831 [(set_attr "isa" "*,bmi2") 6832 (set_attr "type" "imul,imulx") 6833 (set_attr "length_immediate" "0,*") 6834 (set (attr "athlon_decode") 6835 (cond [(eq_attr "alternative" "0") 6836 (if_then_else (eq_attr "cpu" "athlon") 6837 (const_string "vector") 6838 (const_string "double"))] 6839 (const_string "*"))) 6840 (set_attr "amdfam10_decode" "double,*") 6841 (set_attr "bdver1_decode" "direct,*") 6842 (set_attr "prefix" "orig,vex") 6843 (set_attr "mode" "<MODE>")]) 6844 6845;; Convert mul to the mulx pattern to avoid flags dependency. 6846(define_split 6847 [(set (match_operand:<DWI> 0 "register_operand" "") 6848 (mult:<DWI> 6849 (zero_extend:<DWI> 6850 (match_operand:DWIH 1 "register_operand" "")) 6851 (zero_extend:<DWI> 6852 (match_operand:DWIH 2 "nonimmediate_operand" "")))) 6853 (clobber (reg:CC FLAGS_REG))] 6854 "TARGET_BMI2 && reload_completed 6855 && true_regnum (operands[1]) == DX_REG" 6856 [(parallel [(set (match_dup 3) 6857 (mult:DWIH (match_dup 1) (match_dup 2))) 6858 (set (match_dup 4) 6859 (truncate:DWIH 6860 (lshiftrt:<DWI> 6861 (mult:<DWI> (zero_extend:<DWI> (match_dup 1)) 6862 (zero_extend:<DWI> (match_dup 2))) 6863 (match_dup 5))))])] 6864{ 6865 split_double_mode (<DWI>mode, &operands[0], 1, &operands[3], &operands[4]); 6866 6867 operands[5] = GEN_INT (GET_MODE_BITSIZE (<MODE>mode)); 6868}) 6869 6870(define_insn "*mul<mode><dwi>3_1" 6871 [(set (match_operand:<DWI> 0 "register_operand" "=A") 6872 (mult:<DWI> 6873 (sign_extend:<DWI> 6874 (match_operand:DWIH 1 "nonimmediate_operand" "%0")) 6875 (sign_extend:<DWI> 6876 (match_operand:DWIH 2 "nonimmediate_operand" "rm")))) 6877 (clobber (reg:CC FLAGS_REG))] 6878 "!(MEM_P (operands[1]) && MEM_P (operands[2]))" 6879 "imul{<imodesuffix>}\t%2" 6880 [(set_attr "type" "imul") 6881 (set_attr "length_immediate" "0") 6882 (set (attr "athlon_decode") 6883 (if_then_else (eq_attr "cpu" "athlon") 6884 (const_string "vector") 6885 (const_string "double"))) 6886 (set_attr "amdfam10_decode" "double") 6887 (set_attr "bdver1_decode" "direct") 6888 (set_attr "mode" "<MODE>")]) 6889 6890(define_insn "*<u>mulqihi3_1" 6891 [(set (match_operand:HI 0 "register_operand" "=a") 6892 (mult:HI 6893 (any_extend:HI 6894 (match_operand:QI 1 "nonimmediate_operand" "%0")) 6895 (any_extend:HI 6896 (match_operand:QI 2 "nonimmediate_operand" "qm")))) 6897 (clobber (reg:CC FLAGS_REG))] 6898 "TARGET_QIMODE_MATH 6899 && !(MEM_P (operands[1]) && MEM_P (operands[2]))" 6900 "<sgnprefix>mul{b}\t%2" 6901 [(set_attr "type" "imul") 6902 (set_attr "length_immediate" "0") 6903 (set (attr "athlon_decode") 6904 (if_then_else (eq_attr "cpu" "athlon") 6905 (const_string "vector") 6906 (const_string "direct"))) 6907 (set_attr "amdfam10_decode" "direct") 6908 (set_attr "bdver1_decode" "direct") 6909 (set_attr "mode" "QI")]) 6910 6911(define_expand "<s>mul<mode>3_highpart" 6912 [(parallel [(set (match_operand:SWI48 0 "register_operand" "") 6913 (truncate:SWI48 6914 (lshiftrt:<DWI> 6915 (mult:<DWI> 6916 (any_extend:<DWI> 6917 (match_operand:SWI48 1 "nonimmediate_operand" "")) 6918 (any_extend:<DWI> 6919 (match_operand:SWI48 2 "register_operand" ""))) 6920 (match_dup 4)))) 6921 (clobber (match_scratch:SWI48 3 "")) 6922 (clobber (reg:CC FLAGS_REG))])] 6923 "" 6924 "operands[4] = GEN_INT (GET_MODE_BITSIZE (<MODE>mode));") 6925 6926(define_insn "*<s>muldi3_highpart_1" 6927 [(set (match_operand:DI 0 "register_operand" "=d") 6928 (truncate:DI 6929 (lshiftrt:TI 6930 (mult:TI 6931 (any_extend:TI 6932 (match_operand:DI 1 "nonimmediate_operand" "%a")) 6933 (any_extend:TI 6934 (match_operand:DI 2 "nonimmediate_operand" "rm"))) 6935 (const_int 64)))) 6936 (clobber (match_scratch:DI 3 "=1")) 6937 (clobber (reg:CC FLAGS_REG))] 6938 "TARGET_64BIT 6939 && !(MEM_P (operands[1]) && MEM_P (operands[2]))" 6940 "<sgnprefix>mul{q}\t%2" 6941 [(set_attr "type" "imul") 6942 (set_attr "length_immediate" "0") 6943 (set (attr "athlon_decode") 6944 (if_then_else (eq_attr "cpu" "athlon") 6945 (const_string "vector") 6946 (const_string "double"))) 6947 (set_attr "amdfam10_decode" "double") 6948 (set_attr "bdver1_decode" "direct") 6949 (set_attr "mode" "DI")]) 6950 6951(define_insn "*<s>mulsi3_highpart_1" 6952 [(set (match_operand:SI 0 "register_operand" "=d") 6953 (truncate:SI 6954 (lshiftrt:DI 6955 (mult:DI 6956 (any_extend:DI 6957 (match_operand:SI 1 "nonimmediate_operand" "%a")) 6958 (any_extend:DI 6959 (match_operand:SI 2 "nonimmediate_operand" "rm"))) 6960 (const_int 32)))) 6961 (clobber (match_scratch:SI 3 "=1")) 6962 (clobber (reg:CC FLAGS_REG))] 6963 "!(MEM_P (operands[1]) && MEM_P (operands[2]))" 6964 "<sgnprefix>mul{l}\t%2" 6965 [(set_attr "type" "imul") 6966 (set_attr "length_immediate" "0") 6967 (set (attr "athlon_decode") 6968 (if_then_else (eq_attr "cpu" "athlon") 6969 (const_string "vector") 6970 (const_string "double"))) 6971 (set_attr "amdfam10_decode" "double") 6972 (set_attr "bdver1_decode" "direct") 6973 (set_attr "mode" "SI")]) 6974 6975(define_insn "*<s>mulsi3_highpart_zext" 6976 [(set (match_operand:DI 0 "register_operand" "=d") 6977 (zero_extend:DI (truncate:SI 6978 (lshiftrt:DI 6979 (mult:DI (any_extend:DI 6980 (match_operand:SI 1 "nonimmediate_operand" "%a")) 6981 (any_extend:DI 6982 (match_operand:SI 2 "nonimmediate_operand" "rm"))) 6983 (const_int 32))))) 6984 (clobber (match_scratch:SI 3 "=1")) 6985 (clobber (reg:CC FLAGS_REG))] 6986 "TARGET_64BIT 6987 && !(MEM_P (operands[1]) && MEM_P (operands[2]))" 6988 "<sgnprefix>mul{l}\t%2" 6989 [(set_attr "type" "imul") 6990 (set_attr "length_immediate" "0") 6991 (set (attr "athlon_decode") 6992 (if_then_else (eq_attr "cpu" "athlon") 6993 (const_string "vector") 6994 (const_string "double"))) 6995 (set_attr "amdfam10_decode" "double") 6996 (set_attr "bdver1_decode" "direct") 6997 (set_attr "mode" "SI")]) 6998 6999;; The patterns that match these are at the end of this file. 7000 7001(define_expand "mulxf3" 7002 [(set (match_operand:XF 0 "register_operand" "") 7003 (mult:XF (match_operand:XF 1 "register_operand" "") 7004 (match_operand:XF 2 "register_operand" "")))] 7005 "TARGET_80387") 7006 7007(define_expand "mul<mode>3" 7008 [(set (match_operand:MODEF 0 "register_operand" "") 7009 (mult:MODEF (match_operand:MODEF 1 "register_operand" "") 7010 (match_operand:MODEF 2 "nonimmediate_operand" "")))] 7011 "(TARGET_80387 && X87_ENABLE_ARITH (<MODE>mode)) 7012 || (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)") 7013 7014;; Divide instructions 7015 7016;; The patterns that match these are at the end of this file. 7017 7018(define_expand "divxf3" 7019 [(set (match_operand:XF 0 "register_operand" "") 7020 (div:XF (match_operand:XF 1 "register_operand" "") 7021 (match_operand:XF 2 "register_operand" "")))] 7022 "TARGET_80387") 7023 7024(define_expand "divdf3" 7025 [(set (match_operand:DF 0 "register_operand" "") 7026 (div:DF (match_operand:DF 1 "register_operand" "") 7027 (match_operand:DF 2 "nonimmediate_operand" "")))] 7028 "(TARGET_80387 && X87_ENABLE_ARITH (DFmode)) 7029 || (TARGET_SSE2 && TARGET_SSE_MATH)") 7030 7031(define_expand "divsf3" 7032 [(set (match_operand:SF 0 "register_operand" "") 7033 (div:SF (match_operand:SF 1 "register_operand" "") 7034 (match_operand:SF 2 "nonimmediate_operand" "")))] 7035 "(TARGET_80387 && X87_ENABLE_ARITH (SFmode)) 7036 || TARGET_SSE_MATH" 7037{ 7038 if (TARGET_SSE_MATH 7039 && TARGET_RECIP_DIV 7040 && optimize_insn_for_speed_p () 7041 && flag_finite_math_only && !flag_trapping_math 7042 && flag_unsafe_math_optimizations) 7043 { 7044 ix86_emit_swdivsf (operands[0], operands[1], 7045 operands[2], SFmode); 7046 DONE; 7047 } 7048}) 7049 7050;; Divmod instructions. 7051 7052(define_expand "divmod<mode>4" 7053 [(parallel [(set (match_operand:SWIM248 0 "register_operand" "") 7054 (div:SWIM248 7055 (match_operand:SWIM248 1 "register_operand" "") 7056 (match_operand:SWIM248 2 "nonimmediate_operand" ""))) 7057 (set (match_operand:SWIM248 3 "register_operand" "") 7058 (mod:SWIM248 (match_dup 1) (match_dup 2))) 7059 (clobber (reg:CC FLAGS_REG))])]) 7060 7061;; Split with 8bit unsigned divide: 7062;; if (dividend an divisor are in [0-255]) 7063;; use 8bit unsigned integer divide 7064;; else 7065;; use original integer divide 7066(define_split 7067 [(set (match_operand:SWI48 0 "register_operand" "") 7068 (div:SWI48 (match_operand:SWI48 2 "register_operand" "") 7069 (match_operand:SWI48 3 "nonimmediate_operand" ""))) 7070 (set (match_operand:SWI48 1 "register_operand" "") 7071 (mod:SWI48 (match_dup 2) (match_dup 3))) 7072 (clobber (reg:CC FLAGS_REG))] 7073 "TARGET_USE_8BIT_IDIV 7074 && TARGET_QIMODE_MATH 7075 && can_create_pseudo_p () 7076 && !optimize_insn_for_size_p ()" 7077 [(const_int 0)] 7078 "ix86_split_idivmod (<MODE>mode, operands, true); DONE;") 7079 7080(define_insn_and_split "divmod<mode>4_1" 7081 [(set (match_operand:SWI48 0 "register_operand" "=a") 7082 (div:SWI48 (match_operand:SWI48 2 "register_operand" "0") 7083 (match_operand:SWI48 3 "nonimmediate_operand" "rm"))) 7084 (set (match_operand:SWI48 1 "register_operand" "=&d") 7085 (mod:SWI48 (match_dup 2) (match_dup 3))) 7086 (unspec [(const_int 0)] UNSPEC_DIV_ALREADY_SPLIT) 7087 (clobber (reg:CC FLAGS_REG))] 7088 "" 7089 "#" 7090 "reload_completed" 7091 [(parallel [(set (match_dup 1) 7092 (ashiftrt:SWI48 (match_dup 4) (match_dup 5))) 7093 (clobber (reg:CC FLAGS_REG))]) 7094 (parallel [(set (match_dup 0) 7095 (div:SWI48 (match_dup 2) (match_dup 3))) 7096 (set (match_dup 1) 7097 (mod:SWI48 (match_dup 2) (match_dup 3))) 7098 (use (match_dup 1)) 7099 (clobber (reg:CC FLAGS_REG))])] 7100{ 7101 operands[5] = GEN_INT (GET_MODE_BITSIZE (<MODE>mode)-1); 7102 7103 if (optimize_function_for_size_p (cfun) || TARGET_USE_CLTD) 7104 operands[4] = operands[2]; 7105 else 7106 { 7107 /* Avoid use of cltd in favor of a mov+shift. */ 7108 emit_move_insn (operands[1], operands[2]); 7109 operands[4] = operands[1]; 7110 } 7111} 7112 [(set_attr "type" "multi") 7113 (set_attr "mode" "<MODE>")]) 7114 7115(define_insn_and_split "*divmod<mode>4" 7116 [(set (match_operand:SWIM248 0 "register_operand" "=a") 7117 (div:SWIM248 (match_operand:SWIM248 2 "register_operand" "0") 7118 (match_operand:SWIM248 3 "nonimmediate_operand" "rm"))) 7119 (set (match_operand:SWIM248 1 "register_operand" "=&d") 7120 (mod:SWIM248 (match_dup 2) (match_dup 3))) 7121 (clobber (reg:CC FLAGS_REG))] 7122 "" 7123 "#" 7124 "reload_completed" 7125 [(parallel [(set (match_dup 1) 7126 (ashiftrt:SWIM248 (match_dup 4) (match_dup 5))) 7127 (clobber (reg:CC FLAGS_REG))]) 7128 (parallel [(set (match_dup 0) 7129 (div:SWIM248 (match_dup 2) (match_dup 3))) 7130 (set (match_dup 1) 7131 (mod:SWIM248 (match_dup 2) (match_dup 3))) 7132 (use (match_dup 1)) 7133 (clobber (reg:CC FLAGS_REG))])] 7134{ 7135 operands[5] = GEN_INT (GET_MODE_BITSIZE (<MODE>mode)-1); 7136 7137 if (<MODE>mode != HImode 7138 && (optimize_function_for_size_p (cfun) || TARGET_USE_CLTD)) 7139 operands[4] = operands[2]; 7140 else 7141 { 7142 /* Avoid use of cltd in favor of a mov+shift. */ 7143 emit_move_insn (operands[1], operands[2]); 7144 operands[4] = operands[1]; 7145 } 7146} 7147 [(set_attr "type" "multi") 7148 (set_attr "mode" "<MODE>")]) 7149 7150(define_insn "*divmod<mode>4_noext" 7151 [(set (match_operand:SWIM248 0 "register_operand" "=a") 7152 (div:SWIM248 (match_operand:SWIM248 2 "register_operand" "0") 7153 (match_operand:SWIM248 3 "nonimmediate_operand" "rm"))) 7154 (set (match_operand:SWIM248 1 "register_operand" "=d") 7155 (mod:SWIM248 (match_dup 2) (match_dup 3))) 7156 (use (match_operand:SWIM248 4 "register_operand" "1")) 7157 (clobber (reg:CC FLAGS_REG))] 7158 "" 7159 "idiv{<imodesuffix>}\t%3" 7160 [(set_attr "type" "idiv") 7161 (set_attr "mode" "<MODE>")]) 7162 7163(define_expand "divmodqi4" 7164 [(parallel [(set (match_operand:QI 0 "register_operand" "") 7165 (div:QI 7166 (match_operand:QI 1 "register_operand" "") 7167 (match_operand:QI 2 "nonimmediate_operand" ""))) 7168 (set (match_operand:QI 3 "register_operand" "") 7169 (mod:QI (match_dup 1) (match_dup 2))) 7170 (clobber (reg:CC FLAGS_REG))])] 7171 "TARGET_QIMODE_MATH" 7172{ 7173 rtx div, mod, insn; 7174 rtx tmp0, tmp1; 7175 7176 tmp0 = gen_reg_rtx (HImode); 7177 tmp1 = gen_reg_rtx (HImode); 7178 7179 /* Extend operands[1] to HImode. Generate 8bit divide. Result is 7180 in AX. */ 7181 emit_insn (gen_extendqihi2 (tmp1, operands[1])); 7182 emit_insn (gen_divmodhiqi3 (tmp0, tmp1, operands[2])); 7183 7184 /* Extract remainder from AH. */ 7185 tmp1 = gen_rtx_SIGN_EXTRACT (QImode, tmp0, GEN_INT (8), GEN_INT (8)); 7186 insn = emit_move_insn (operands[3], tmp1); 7187 7188 mod = gen_rtx_MOD (QImode, operands[1], operands[2]); 7189 set_unique_reg_note (insn, REG_EQUAL, mod); 7190 7191 /* Extract quotient from AL. */ 7192 insn = emit_move_insn (operands[0], gen_lowpart (QImode, tmp0)); 7193 7194 div = gen_rtx_DIV (QImode, operands[1], operands[2]); 7195 set_unique_reg_note (insn, REG_EQUAL, div); 7196 7197 DONE; 7198}) 7199 7200;; Divide AX by r/m8, with result stored in 7201;; AL <- Quotient 7202;; AH <- Remainder 7203;; Change div/mod to HImode and extend the second argument to HImode 7204;; so that mode of div/mod matches with mode of arguments. Otherwise 7205;; combine may fail. 7206(define_insn "divmodhiqi3" 7207 [(set (match_operand:HI 0 "register_operand" "=a") 7208 (ior:HI 7209 (ashift:HI 7210 (zero_extend:HI 7211 (truncate:QI 7212 (mod:HI (match_operand:HI 1 "register_operand" "0") 7213 (sign_extend:HI 7214 (match_operand:QI 2 "nonimmediate_operand" "qm"))))) 7215 (const_int 8)) 7216 (zero_extend:HI 7217 (truncate:QI 7218 (div:HI (match_dup 1) (sign_extend:HI (match_dup 2))))))) 7219 (clobber (reg:CC FLAGS_REG))] 7220 "TARGET_QIMODE_MATH" 7221 "idiv{b}\t%2" 7222 [(set_attr "type" "idiv") 7223 (set_attr "mode" "QI")]) 7224 7225(define_expand "udivmod<mode>4" 7226 [(parallel [(set (match_operand:SWIM248 0 "register_operand" "") 7227 (udiv:SWIM248 7228 (match_operand:SWIM248 1 "register_operand" "") 7229 (match_operand:SWIM248 2 "nonimmediate_operand" ""))) 7230 (set (match_operand:SWIM248 3 "register_operand" "") 7231 (umod:SWIM248 (match_dup 1) (match_dup 2))) 7232 (clobber (reg:CC FLAGS_REG))])]) 7233 7234;; Split with 8bit unsigned divide: 7235;; if (dividend an divisor are in [0-255]) 7236;; use 8bit unsigned integer divide 7237;; else 7238;; use original integer divide 7239(define_split 7240 [(set (match_operand:SWI48 0 "register_operand" "") 7241 (udiv:SWI48 (match_operand:SWI48 2 "register_operand" "") 7242 (match_operand:SWI48 3 "nonimmediate_operand" ""))) 7243 (set (match_operand:SWI48 1 "register_operand" "") 7244 (umod:SWI48 (match_dup 2) (match_dup 3))) 7245 (clobber (reg:CC FLAGS_REG))] 7246 "TARGET_USE_8BIT_IDIV 7247 && TARGET_QIMODE_MATH 7248 && can_create_pseudo_p () 7249 && !optimize_insn_for_size_p ()" 7250 [(const_int 0)] 7251 "ix86_split_idivmod (<MODE>mode, operands, false); DONE;") 7252 7253(define_insn_and_split "udivmod<mode>4_1" 7254 [(set (match_operand:SWI48 0 "register_operand" "=a") 7255 (udiv:SWI48 (match_operand:SWI48 2 "register_operand" "0") 7256 (match_operand:SWI48 3 "nonimmediate_operand" "rm"))) 7257 (set (match_operand:SWI48 1 "register_operand" "=&d") 7258 (umod:SWI48 (match_dup 2) (match_dup 3))) 7259 (unspec [(const_int 0)] UNSPEC_DIV_ALREADY_SPLIT) 7260 (clobber (reg:CC FLAGS_REG))] 7261 "" 7262 "#" 7263 "reload_completed" 7264 [(set (match_dup 1) (const_int 0)) 7265 (parallel [(set (match_dup 0) 7266 (udiv:SWI48 (match_dup 2) (match_dup 3))) 7267 (set (match_dup 1) 7268 (umod:SWI48 (match_dup 2) (match_dup 3))) 7269 (use (match_dup 1)) 7270 (clobber (reg:CC FLAGS_REG))])] 7271 "" 7272 [(set_attr "type" "multi") 7273 (set_attr "mode" "<MODE>")]) 7274 7275(define_insn_and_split "*udivmod<mode>4" 7276 [(set (match_operand:SWIM248 0 "register_operand" "=a") 7277 (udiv:SWIM248 (match_operand:SWIM248 2 "register_operand" "0") 7278 (match_operand:SWIM248 3 "nonimmediate_operand" "rm"))) 7279 (set (match_operand:SWIM248 1 "register_operand" "=&d") 7280 (umod:SWIM248 (match_dup 2) (match_dup 3))) 7281 (clobber (reg:CC FLAGS_REG))] 7282 "" 7283 "#" 7284 "reload_completed" 7285 [(set (match_dup 1) (const_int 0)) 7286 (parallel [(set (match_dup 0) 7287 (udiv:SWIM248 (match_dup 2) (match_dup 3))) 7288 (set (match_dup 1) 7289 (umod:SWIM248 (match_dup 2) (match_dup 3))) 7290 (use (match_dup 1)) 7291 (clobber (reg:CC FLAGS_REG))])] 7292 "" 7293 [(set_attr "type" "multi") 7294 (set_attr "mode" "<MODE>")]) 7295 7296(define_insn "*udivmod<mode>4_noext" 7297 [(set (match_operand:SWIM248 0 "register_operand" "=a") 7298 (udiv:SWIM248 (match_operand:SWIM248 2 "register_operand" "0") 7299 (match_operand:SWIM248 3 "nonimmediate_operand" "rm"))) 7300 (set (match_operand:SWIM248 1 "register_operand" "=d") 7301 (umod:SWIM248 (match_dup 2) (match_dup 3))) 7302 (use (match_operand:SWIM248 4 "register_operand" "1")) 7303 (clobber (reg:CC FLAGS_REG))] 7304 "" 7305 "div{<imodesuffix>}\t%3" 7306 [(set_attr "type" "idiv") 7307 (set_attr "mode" "<MODE>")]) 7308 7309(define_expand "udivmodqi4" 7310 [(parallel [(set (match_operand:QI 0 "register_operand" "") 7311 (udiv:QI 7312 (match_operand:QI 1 "register_operand" "") 7313 (match_operand:QI 2 "nonimmediate_operand" ""))) 7314 (set (match_operand:QI 3 "register_operand" "") 7315 (umod:QI (match_dup 1) (match_dup 2))) 7316 (clobber (reg:CC FLAGS_REG))])] 7317 "TARGET_QIMODE_MATH" 7318{ 7319 rtx div, mod, insn; 7320 rtx tmp0, tmp1; 7321 7322 tmp0 = gen_reg_rtx (HImode); 7323 tmp1 = gen_reg_rtx (HImode); 7324 7325 /* Extend operands[1] to HImode. Generate 8bit divide. Result is 7326 in AX. */ 7327 emit_insn (gen_zero_extendqihi2 (tmp1, operands[1])); 7328 emit_insn (gen_udivmodhiqi3 (tmp0, tmp1, operands[2])); 7329 7330 /* Extract remainder from AH. */ 7331 tmp1 = gen_rtx_ZERO_EXTRACT (SImode, tmp0, GEN_INT (8), GEN_INT (8)); 7332 tmp1 = simplify_gen_subreg (QImode, tmp1, SImode, 0); 7333 insn = emit_move_insn (operands[3], tmp1); 7334 7335 mod = gen_rtx_UMOD (QImode, operands[1], operands[2]); 7336 set_unique_reg_note (insn, REG_EQUAL, mod); 7337 7338 /* Extract quotient from AL. */ 7339 insn = emit_move_insn (operands[0], gen_lowpart (QImode, tmp0)); 7340 7341 div = gen_rtx_UDIV (QImode, operands[1], operands[2]); 7342 set_unique_reg_note (insn, REG_EQUAL, div); 7343 7344 DONE; 7345}) 7346 7347(define_insn "udivmodhiqi3" 7348 [(set (match_operand:HI 0 "register_operand" "=a") 7349 (ior:HI 7350 (ashift:HI 7351 (zero_extend:HI 7352 (truncate:QI 7353 (mod:HI (match_operand:HI 1 "register_operand" "0") 7354 (zero_extend:HI 7355 (match_operand:QI 2 "nonimmediate_operand" "qm"))))) 7356 (const_int 8)) 7357 (zero_extend:HI 7358 (truncate:QI 7359 (div:HI (match_dup 1) (zero_extend:HI (match_dup 2))))))) 7360 (clobber (reg:CC FLAGS_REG))] 7361 "TARGET_QIMODE_MATH" 7362 "div{b}\t%2" 7363 [(set_attr "type" "idiv") 7364 (set_attr "mode" "QI")]) 7365 7366;; We cannot use div/idiv for double division, because it causes 7367;; "division by zero" on the overflow and that's not what we expect 7368;; from truncate. Because true (non truncating) double division is 7369;; never generated, we can't create this insn anyway. 7370; 7371;(define_insn "" 7372; [(set (match_operand:SI 0 "register_operand" "=a") 7373; (truncate:SI 7374; (udiv:DI (match_operand:DI 1 "register_operand" "A") 7375; (zero_extend:DI 7376; (match_operand:SI 2 "nonimmediate_operand" "rm"))))) 7377; (set (match_operand:SI 3 "register_operand" "=d") 7378; (truncate:SI 7379; (umod:DI (match_dup 1) (zero_extend:DI (match_dup 2))))) 7380; (clobber (reg:CC FLAGS_REG))] 7381; "" 7382; "div{l}\t{%2, %0|%0, %2}" 7383; [(set_attr "type" "idiv")]) 7384 7385;;- Logical AND instructions 7386 7387;; On Pentium, "test imm, reg" is pairable only with eax, ax, and al. 7388;; Note that this excludes ah. 7389 7390(define_expand "testsi_ccno_1" 7391 [(set (reg:CCNO FLAGS_REG) 7392 (compare:CCNO 7393 (and:SI (match_operand:SI 0 "nonimmediate_operand" "") 7394 (match_operand:SI 1 "x86_64_nonmemory_operand" "")) 7395 (const_int 0)))]) 7396 7397(define_expand "testqi_ccz_1" 7398 [(set (reg:CCZ FLAGS_REG) 7399 (compare:CCZ (and:QI (match_operand:QI 0 "nonimmediate_operand" "") 7400 (match_operand:QI 1 "nonmemory_operand" "")) 7401 (const_int 0)))]) 7402 7403(define_expand "testdi_ccno_1" 7404 [(set (reg:CCNO FLAGS_REG) 7405 (compare:CCNO 7406 (and:DI (match_operand:DI 0 "nonimmediate_operand" "") 7407 (match_operand:DI 1 "x86_64_szext_general_operand" "")) 7408 (const_int 0)))] 7409 "TARGET_64BIT && !(MEM_P (operands[0]) && MEM_P (operands[1]))") 7410 7411(define_insn "*testdi_1" 7412 [(set (reg FLAGS_REG) 7413 (compare 7414 (and:DI 7415 (match_operand:DI 0 "nonimmediate_operand" "%!*a,r,!*a,r,rm") 7416 (match_operand:DI 1 "x86_64_szext_general_operand" "Z,Z,e,e,re")) 7417 (const_int 0)))] 7418 "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode) 7419 && !(MEM_P (operands[0]) && MEM_P (operands[1]))" 7420 "@ 7421 test{l}\t{%k1, %k0|%k0, %k1} 7422 test{l}\t{%k1, %k0|%k0, %k1} 7423 test{q}\t{%1, %0|%0, %1} 7424 test{q}\t{%1, %0|%0, %1} 7425 test{q}\t{%1, %0|%0, %1}" 7426 [(set_attr "type" "test") 7427 (set_attr "modrm" "0,1,0,1,1") 7428 (set_attr "mode" "SI,SI,DI,DI,DI")]) 7429 7430(define_insn "*testqi_1_maybe_si" 7431 [(set (reg FLAGS_REG) 7432 (compare 7433 (and:QI 7434 (match_operand:QI 0 "nonimmediate_operand" "%!*a,q,qm,r") 7435 (match_operand:QI 1 "general_operand" "n,n,qn,n")) 7436 (const_int 0)))] 7437 "!(MEM_P (operands[0]) && MEM_P (operands[1])) 7438 && ix86_match_ccmode (insn, 7439 CONST_INT_P (operands[1]) 7440 && INTVAL (operands[1]) >= 0 ? CCNOmode : CCZmode)" 7441{ 7442 if (which_alternative == 3) 7443 { 7444 if (CONST_INT_P (operands[1]) && INTVAL (operands[1]) < 0) 7445 operands[1] = GEN_INT (INTVAL (operands[1]) & 0xff); 7446 return "test{l}\t{%1, %k0|%k0, %1}"; 7447 } 7448 return "test{b}\t{%1, %0|%0, %1}"; 7449} 7450 [(set_attr "type" "test") 7451 (set_attr "modrm" "0,1,1,1") 7452 (set_attr "mode" "QI,QI,QI,SI") 7453 (set_attr "pent_pair" "uv,np,uv,np")]) 7454 7455(define_insn "*test<mode>_1" 7456 [(set (reg FLAGS_REG) 7457 (compare 7458 (and:SWI124 7459 (match_operand:SWI124 0 "nonimmediate_operand" "%!*a,<r>,<r>m") 7460 (match_operand:SWI124 1 "<general_operand>" "<i>,<i>,<r><i>")) 7461 (const_int 0)))] 7462 "ix86_match_ccmode (insn, CCNOmode) 7463 && !(MEM_P (operands[0]) && MEM_P (operands[1]))" 7464 "test{<imodesuffix>}\t{%1, %0|%0, %1}" 7465 [(set_attr "type" "test") 7466 (set_attr "modrm" "0,1,1") 7467 (set_attr "mode" "<MODE>") 7468 (set_attr "pent_pair" "uv,np,uv")]) 7469 7470(define_expand "testqi_ext_ccno_0" 7471 [(set (reg:CCNO FLAGS_REG) 7472 (compare:CCNO 7473 (and:SI 7474 (zero_extract:SI 7475 (match_operand 0 "ext_register_operand" "") 7476 (const_int 8) 7477 (const_int 8)) 7478 (match_operand 1 "const_int_operand" "")) 7479 (const_int 0)))]) 7480 7481(define_insn "*testqi_ext_0" 7482 [(set (reg FLAGS_REG) 7483 (compare 7484 (and:SI 7485 (zero_extract:SI 7486 (match_operand 0 "ext_register_operand" "Q") 7487 (const_int 8) 7488 (const_int 8)) 7489 (match_operand 1 "const_int_operand" "n")) 7490 (const_int 0)))] 7491 "ix86_match_ccmode (insn, CCNOmode)" 7492 "test{b}\t{%1, %h0|%h0, %1}" 7493 [(set_attr "type" "test") 7494 (set_attr "mode" "QI") 7495 (set_attr "length_immediate" "1") 7496 (set_attr "modrm" "1") 7497 (set_attr "pent_pair" "np")]) 7498 7499(define_insn "*testqi_ext_1_rex64" 7500 [(set (reg FLAGS_REG) 7501 (compare 7502 (and:SI 7503 (zero_extract:SI 7504 (match_operand 0 "ext_register_operand" "Q") 7505 (const_int 8) 7506 (const_int 8)) 7507 (zero_extend:SI 7508 (match_operand:QI 1 "register_operand" "Q"))) 7509 (const_int 0)))] 7510 "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)" 7511 "test{b}\t{%1, %h0|%h0, %1}" 7512 [(set_attr "type" "test") 7513 (set_attr "mode" "QI")]) 7514 7515(define_insn "*testqi_ext_1" 7516 [(set (reg FLAGS_REG) 7517 (compare 7518 (and:SI 7519 (zero_extract:SI 7520 (match_operand 0 "ext_register_operand" "Q") 7521 (const_int 8) 7522 (const_int 8)) 7523 (zero_extend:SI 7524 (match_operand:QI 1 "general_operand" "Qm"))) 7525 (const_int 0)))] 7526 "!TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)" 7527 "test{b}\t{%1, %h0|%h0, %1}" 7528 [(set_attr "type" "test") 7529 (set_attr "mode" "QI")]) 7530 7531(define_insn "*testqi_ext_2" 7532 [(set (reg FLAGS_REG) 7533 (compare 7534 (and:SI 7535 (zero_extract:SI 7536 (match_operand 0 "ext_register_operand" "Q") 7537 (const_int 8) 7538 (const_int 8)) 7539 (zero_extract:SI 7540 (match_operand 1 "ext_register_operand" "Q") 7541 (const_int 8) 7542 (const_int 8))) 7543 (const_int 0)))] 7544 "ix86_match_ccmode (insn, CCNOmode)" 7545 "test{b}\t{%h1, %h0|%h0, %h1}" 7546 [(set_attr "type" "test") 7547 (set_attr "mode" "QI")]) 7548 7549(define_insn "*testqi_ext_3_rex64" 7550 [(set (reg FLAGS_REG) 7551 (compare (zero_extract:DI 7552 (match_operand 0 "nonimmediate_operand" "rm") 7553 (match_operand:DI 1 "const_int_operand" "") 7554 (match_operand:DI 2 "const_int_operand" "")) 7555 (const_int 0)))] 7556 "TARGET_64BIT 7557 && ix86_match_ccmode (insn, CCNOmode) 7558 && INTVAL (operands[1]) > 0 7559 && INTVAL (operands[2]) >= 0 7560 /* Ensure that resulting mask is zero or sign extended operand. */ 7561 && (INTVAL (operands[1]) + INTVAL (operands[2]) <= 32 7562 || (INTVAL (operands[1]) + INTVAL (operands[2]) == 64 7563 && INTVAL (operands[1]) > 32)) 7564 && (GET_MODE (operands[0]) == SImode 7565 || GET_MODE (operands[0]) == DImode 7566 || GET_MODE (operands[0]) == HImode 7567 || GET_MODE (operands[0]) == QImode)" 7568 "#") 7569 7570;; Combine likes to form bit extractions for some tests. Humor it. 7571(define_insn "*testqi_ext_3" 7572 [(set (reg FLAGS_REG) 7573 (compare (zero_extract:SI 7574 (match_operand 0 "nonimmediate_operand" "rm") 7575 (match_operand:SI 1 "const_int_operand" "") 7576 (match_operand:SI 2 "const_int_operand" "")) 7577 (const_int 0)))] 7578 "ix86_match_ccmode (insn, CCNOmode) 7579 && INTVAL (operands[1]) > 0 7580 && INTVAL (operands[2]) >= 0 7581 && INTVAL (operands[1]) + INTVAL (operands[2]) <= 32 7582 && (GET_MODE (operands[0]) == SImode 7583 || (TARGET_64BIT && GET_MODE (operands[0]) == DImode) 7584 || GET_MODE (operands[0]) == HImode 7585 || GET_MODE (operands[0]) == QImode)" 7586 "#") 7587 7588(define_split 7589 [(set (match_operand 0 "flags_reg_operand" "") 7590 (match_operator 1 "compare_operator" 7591 [(zero_extract 7592 (match_operand 2 "nonimmediate_operand" "") 7593 (match_operand 3 "const_int_operand" "") 7594 (match_operand 4 "const_int_operand" "")) 7595 (const_int 0)]))] 7596 "ix86_match_ccmode (insn, CCNOmode)" 7597 [(set (match_dup 0) (match_op_dup 1 [(match_dup 2) (const_int 0)]))] 7598{ 7599 rtx val = operands[2]; 7600 HOST_WIDE_INT len = INTVAL (operands[3]); 7601 HOST_WIDE_INT pos = INTVAL (operands[4]); 7602 HOST_WIDE_INT mask; 7603 enum machine_mode mode, submode; 7604 7605 mode = GET_MODE (val); 7606 if (MEM_P (val)) 7607 { 7608 /* ??? Combine likes to put non-volatile mem extractions in QImode 7609 no matter the size of the test. So find a mode that works. */ 7610 if (! MEM_VOLATILE_P (val)) 7611 { 7612 mode = smallest_mode_for_size (pos + len, MODE_INT); 7613 val = adjust_address (val, mode, 0); 7614 } 7615 } 7616 else if (GET_CODE (val) == SUBREG 7617 && (submode = GET_MODE (SUBREG_REG (val)), 7618 GET_MODE_BITSIZE (mode) > GET_MODE_BITSIZE (submode)) 7619 && pos + len <= GET_MODE_BITSIZE (submode) 7620 && GET_MODE_CLASS (submode) == MODE_INT) 7621 { 7622 /* Narrow a paradoxical subreg to prevent partial register stalls. */ 7623 mode = submode; 7624 val = SUBREG_REG (val); 7625 } 7626 else if (mode == HImode && pos + len <= 8) 7627 { 7628 /* Small HImode tests can be converted to QImode. */ 7629 mode = QImode; 7630 val = gen_lowpart (QImode, val); 7631 } 7632 7633 if (len == HOST_BITS_PER_WIDE_INT) 7634 mask = -1; 7635 else 7636 mask = ((HOST_WIDE_INT)1 << len) - 1; 7637 mask <<= pos; 7638 7639 operands[2] = gen_rtx_AND (mode, val, gen_int_mode (mask, mode)); 7640}) 7641 7642;; Convert HImode/SImode test instructions with immediate to QImode ones. 7643;; i386 does not allow to encode test with 8bit sign extended immediate, so 7644;; this is relatively important trick. 7645;; Do the conversion only post-reload to avoid limiting of the register class 7646;; to QI regs. 7647(define_split 7648 [(set (match_operand 0 "flags_reg_operand" "") 7649 (match_operator 1 "compare_operator" 7650 [(and (match_operand 2 "register_operand" "") 7651 (match_operand 3 "const_int_operand" "")) 7652 (const_int 0)]))] 7653 "reload_completed 7654 && QI_REG_P (operands[2]) 7655 && GET_MODE (operands[2]) != QImode 7656 && ((ix86_match_ccmode (insn, CCZmode) 7657 && !(INTVAL (operands[3]) & ~(255 << 8))) 7658 || (ix86_match_ccmode (insn, CCNOmode) 7659 && !(INTVAL (operands[3]) & ~(127 << 8))))" 7660 [(set (match_dup 0) 7661 (match_op_dup 1 7662 [(and:SI (zero_extract:SI (match_dup 2) (const_int 8) (const_int 8)) 7663 (match_dup 3)) 7664 (const_int 0)]))] 7665{ 7666 operands[2] = gen_lowpart (SImode, operands[2]); 7667 operands[3] = gen_int_mode (INTVAL (operands[3]) >> 8, SImode); 7668}) 7669 7670(define_split 7671 [(set (match_operand 0 "flags_reg_operand" "") 7672 (match_operator 1 "compare_operator" 7673 [(and (match_operand 2 "nonimmediate_operand" "") 7674 (match_operand 3 "const_int_operand" "")) 7675 (const_int 0)]))] 7676 "reload_completed 7677 && GET_MODE (operands[2]) != QImode 7678 && (!REG_P (operands[2]) || ANY_QI_REG_P (operands[2])) 7679 && ((ix86_match_ccmode (insn, CCZmode) 7680 && !(INTVAL (operands[3]) & ~255)) 7681 || (ix86_match_ccmode (insn, CCNOmode) 7682 && !(INTVAL (operands[3]) & ~127)))" 7683 [(set (match_dup 0) 7684 (match_op_dup 1 [(and:QI (match_dup 2) (match_dup 3)) 7685 (const_int 0)]))] 7686{ 7687 operands[2] = gen_lowpart (QImode, operands[2]); 7688 operands[3] = gen_lowpart (QImode, operands[3]); 7689}) 7690 7691;; %%% This used to optimize known byte-wide and operations to memory, 7692;; and sometimes to QImode registers. If this is considered useful, 7693;; it should be done with splitters. 7694 7695(define_expand "and<mode>3" 7696 [(set (match_operand:SWIM 0 "nonimmediate_operand" "") 7697 (and:SWIM (match_operand:SWIM 1 "nonimmediate_operand" "") 7698 (match_operand:SWIM 2 "<general_szext_operand>" "")))] 7699 "" 7700{ 7701 if (<MODE>mode == DImode 7702 && GET_CODE (operands[2]) == CONST_INT 7703 && INTVAL (operands[2]) == (HOST_WIDE_INT) 0xffffffff 7704 && REG_P (operands[1])) 7705 emit_insn (gen_zero_extendsidi2 (operands[0], 7706 gen_lowpart (SImode, operands[1]))); 7707 else 7708 ix86_expand_binary_operator (AND, <MODE>mode, operands); 7709 DONE; 7710}) 7711 7712(define_insn "*anddi_1" 7713 [(set (match_operand:DI 0 "nonimmediate_operand" "=r,rm,r,r") 7714 (and:DI 7715 (match_operand:DI 1 "nonimmediate_operand" "%0,0,0,qm") 7716 (match_operand:DI 2 "x86_64_szext_general_operand" "Z,re,rm,L"))) 7717 (clobber (reg:CC FLAGS_REG))] 7718 "TARGET_64BIT && ix86_binary_operator_ok (AND, DImode, operands)" 7719{ 7720 switch (get_attr_type (insn)) 7721 { 7722 case TYPE_IMOVX: 7723 { 7724 enum machine_mode mode; 7725 7726 gcc_assert (CONST_INT_P (operands[2])); 7727 if (INTVAL (operands[2]) == (HOST_WIDE_INT) 0xffffffff) 7728 mode = SImode; 7729 else if (INTVAL (operands[2]) == 0xffff) 7730 mode = HImode; 7731 else 7732 { 7733 gcc_assert (INTVAL (operands[2]) == 0xff); 7734 mode = QImode; 7735 } 7736 7737 operands[1] = gen_lowpart (mode, operands[1]); 7738 if (mode == SImode) 7739 return "mov{l}\t{%1, %k0|%k0, %1}"; 7740 else if (mode == HImode) 7741 return "movz{wl|x}\t{%1, %k0|%k0, %1}"; 7742 else 7743 return "movz{bl|x}\t{%1, %k0|%k0, %1}"; 7744 } 7745 7746 default: 7747 gcc_assert (rtx_equal_p (operands[0], operands[1])); 7748 if (get_attr_mode (insn) == MODE_SI) 7749 return "and{l}\t{%k2, %k0|%k0, %k2}"; 7750 else 7751 return "and{q}\t{%2, %0|%0, %2}"; 7752 } 7753} 7754 [(set_attr "type" "alu,alu,alu,imovx") 7755 (set_attr "length_immediate" "*,*,*,0") 7756 (set (attr "prefix_rex") 7757 (if_then_else 7758 (and (eq_attr "type" "imovx") 7759 (and (match_test "INTVAL (operands[2]) == 0xff") 7760 (match_operand 1 "ext_QIreg_operand" ""))) 7761 (const_string "1") 7762 (const_string "*"))) 7763 (set_attr "mode" "SI,DI,DI,SI")]) 7764 7765(define_insn "*andsi_1" 7766 [(set (match_operand:SI 0 "nonimmediate_operand" "=rm,r,r") 7767 (and:SI (match_operand:SI 1 "nonimmediate_operand" "%0,0,qm") 7768 (match_operand:SI 2 "x86_64_general_operand" "re,rm,L"))) 7769 (clobber (reg:CC FLAGS_REG))] 7770 "ix86_binary_operator_ok (AND, SImode, operands)" 7771{ 7772 switch (get_attr_type (insn)) 7773 { 7774 case TYPE_IMOVX: 7775 { 7776 enum machine_mode mode; 7777 7778 gcc_assert (CONST_INT_P (operands[2])); 7779 if (INTVAL (operands[2]) == 0xffff) 7780 mode = HImode; 7781 else 7782 { 7783 gcc_assert (INTVAL (operands[2]) == 0xff); 7784 mode = QImode; 7785 } 7786 7787 operands[1] = gen_lowpart (mode, operands[1]); 7788 if (mode == HImode) 7789 return "movz{wl|x}\t{%1, %0|%0, %1}"; 7790 else 7791 return "movz{bl|x}\t{%1, %0|%0, %1}"; 7792 } 7793 7794 default: 7795 gcc_assert (rtx_equal_p (operands[0], operands[1])); 7796 return "and{l}\t{%2, %0|%0, %2}"; 7797 } 7798} 7799 [(set_attr "type" "alu,alu,imovx") 7800 (set (attr "prefix_rex") 7801 (if_then_else 7802 (and (eq_attr "type" "imovx") 7803 (and (match_test "INTVAL (operands[2]) == 0xff") 7804 (match_operand 1 "ext_QIreg_operand" ""))) 7805 (const_string "1") 7806 (const_string "*"))) 7807 (set_attr "length_immediate" "*,*,0") 7808 (set_attr "mode" "SI")]) 7809 7810;; See comment for addsi_1_zext why we do use nonimmediate_operand 7811(define_insn "*andsi_1_zext" 7812 [(set (match_operand:DI 0 "register_operand" "=r") 7813 (zero_extend:DI 7814 (and:SI (match_operand:SI 1 "nonimmediate_operand" "%0") 7815 (match_operand:SI 2 "x86_64_general_operand" "rme")))) 7816 (clobber (reg:CC FLAGS_REG))] 7817 "TARGET_64BIT && ix86_binary_operator_ok (AND, SImode, operands)" 7818 "and{l}\t{%2, %k0|%k0, %2}" 7819 [(set_attr "type" "alu") 7820 (set_attr "mode" "SI")]) 7821 7822(define_insn "*andhi_1" 7823 [(set (match_operand:HI 0 "nonimmediate_operand" "=rm,r,r") 7824 (and:HI (match_operand:HI 1 "nonimmediate_operand" "%0,0,qm") 7825 (match_operand:HI 2 "general_operand" "rn,rm,L"))) 7826 (clobber (reg:CC FLAGS_REG))] 7827 "ix86_binary_operator_ok (AND, HImode, operands)" 7828{ 7829 switch (get_attr_type (insn)) 7830 { 7831 case TYPE_IMOVX: 7832 gcc_assert (CONST_INT_P (operands[2])); 7833 gcc_assert (INTVAL (operands[2]) == 0xff); 7834 return "movz{bl|x}\t{%b1, %k0|%k0, %b1}"; 7835 7836 default: 7837 gcc_assert (rtx_equal_p (operands[0], operands[1])); 7838 7839 return "and{w}\t{%2, %0|%0, %2}"; 7840 } 7841} 7842 [(set_attr "type" "alu,alu,imovx") 7843 (set_attr "length_immediate" "*,*,0") 7844 (set (attr "prefix_rex") 7845 (if_then_else 7846 (and (eq_attr "type" "imovx") 7847 (match_operand 1 "ext_QIreg_operand" "")) 7848 (const_string "1") 7849 (const_string "*"))) 7850 (set_attr "mode" "HI,HI,SI")]) 7851 7852;; %%% Potential partial reg stall on alternative 2. What to do? 7853(define_insn "*andqi_1" 7854 [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,q,r") 7855 (and:QI (match_operand:QI 1 "nonimmediate_operand" "%0,0,0") 7856 (match_operand:QI 2 "general_operand" "qn,qmn,rn"))) 7857 (clobber (reg:CC FLAGS_REG))] 7858 "ix86_binary_operator_ok (AND, QImode, operands)" 7859 "@ 7860 and{b}\t{%2, %0|%0, %2} 7861 and{b}\t{%2, %0|%0, %2} 7862 and{l}\t{%k2, %k0|%k0, %k2}" 7863 [(set_attr "type" "alu") 7864 (set_attr "mode" "QI,QI,SI")]) 7865 7866(define_insn "*andqi_1_slp" 7867 [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm,q")) 7868 (and:QI (match_dup 0) 7869 (match_operand:QI 1 "general_operand" "qn,qmn"))) 7870 (clobber (reg:CC FLAGS_REG))] 7871 "(!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun)) 7872 && !(MEM_P (operands[0]) && MEM_P (operands[1]))" 7873 "and{b}\t{%1, %0|%0, %1}" 7874 [(set_attr "type" "alu1") 7875 (set_attr "mode" "QI")]) 7876 7877(define_split 7878 [(set (match_operand 0 "register_operand" "") 7879 (and (match_dup 0) 7880 (const_int -65536))) 7881 (clobber (reg:CC FLAGS_REG))] 7882 "(TARGET_FAST_PREFIX && !TARGET_PARTIAL_REG_STALL) 7883 || optimize_function_for_size_p (cfun)" 7884 [(set (strict_low_part (match_dup 1)) (const_int 0))] 7885 "operands[1] = gen_lowpart (HImode, operands[0]);") 7886 7887(define_split 7888 [(set (match_operand 0 "ext_register_operand" "") 7889 (and (match_dup 0) 7890 (const_int -256))) 7891 (clobber (reg:CC FLAGS_REG))] 7892 "(!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun)) 7893 && reload_completed" 7894 [(set (strict_low_part (match_dup 1)) (const_int 0))] 7895 "operands[1] = gen_lowpart (QImode, operands[0]);") 7896 7897(define_split 7898 [(set (match_operand 0 "ext_register_operand" "") 7899 (and (match_dup 0) 7900 (const_int -65281))) 7901 (clobber (reg:CC FLAGS_REG))] 7902 "(!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun)) 7903 && reload_completed" 7904 [(parallel [(set (zero_extract:SI (match_dup 0) 7905 (const_int 8) 7906 (const_int 8)) 7907 (xor:SI 7908 (zero_extract:SI (match_dup 0) 7909 (const_int 8) 7910 (const_int 8)) 7911 (zero_extract:SI (match_dup 0) 7912 (const_int 8) 7913 (const_int 8)))) 7914 (clobber (reg:CC FLAGS_REG))])] 7915 "operands[0] = gen_lowpart (SImode, operands[0]);") 7916 7917(define_insn "*anddi_2" 7918 [(set (reg FLAGS_REG) 7919 (compare 7920 (and:DI 7921 (match_operand:DI 1 "nonimmediate_operand" "%0,0,0") 7922 (match_operand:DI 2 "x86_64_szext_general_operand" "Z,rem,re")) 7923 (const_int 0))) 7924 (set (match_operand:DI 0 "nonimmediate_operand" "=r,r,rm") 7925 (and:DI (match_dup 1) (match_dup 2)))] 7926 "TARGET_64BIT 7927 && ix86_match_ccmode 7928 (insn, 7929 /* If we are going to emit andl instead of andq, and the operands[2] 7930 constant might have the SImode sign bit set, make sure the sign 7931 flag isn't tested, because the instruction will set the sign flag 7932 based on bit 31 rather than bit 63. If it isn't CONST_INT, 7933 conservatively assume it might have bit 31 set. */ 7934 (satisfies_constraint_Z (operands[2]) 7935 && (!CONST_INT_P (operands[2]) 7936 || val_signbit_known_set_p (SImode, INTVAL (operands[2])))) 7937 ? CCZmode : CCNOmode) 7938 && ix86_binary_operator_ok (AND, DImode, operands)" 7939 "@ 7940 and{l}\t{%k2, %k0|%k0, %k2} 7941 and{q}\t{%2, %0|%0, %2} 7942 and{q}\t{%2, %0|%0, %2}" 7943 [(set_attr "type" "alu") 7944 (set_attr "mode" "SI,DI,DI")]) 7945 7946(define_insn "*andqi_2_maybe_si" 7947 [(set (reg FLAGS_REG) 7948 (compare (and:QI 7949 (match_operand:QI 1 "nonimmediate_operand" "%0,0,0") 7950 (match_operand:QI 2 "general_operand" "qmn,qn,n")) 7951 (const_int 0))) 7952 (set (match_operand:QI 0 "nonimmediate_operand" "=q,qm,*r") 7953 (and:QI (match_dup 1) (match_dup 2)))] 7954 "ix86_binary_operator_ok (AND, QImode, operands) 7955 && ix86_match_ccmode (insn, 7956 CONST_INT_P (operands[2]) 7957 && INTVAL (operands[2]) >= 0 ? CCNOmode : CCZmode)" 7958{ 7959 if (which_alternative == 2) 7960 { 7961 if (CONST_INT_P (operands[2]) && INTVAL (operands[2]) < 0) 7962 operands[2] = GEN_INT (INTVAL (operands[2]) & 0xff); 7963 return "and{l}\t{%2, %k0|%k0, %2}"; 7964 } 7965 return "and{b}\t{%2, %0|%0, %2}"; 7966} 7967 [(set_attr "type" "alu") 7968 (set_attr "mode" "QI,QI,SI")]) 7969 7970(define_insn "*and<mode>_2" 7971 [(set (reg FLAGS_REG) 7972 (compare (and:SWI124 7973 (match_operand:SWI124 1 "nonimmediate_operand" "%0,0") 7974 (match_operand:SWI124 2 "<general_operand>" "<g>,<r><i>")) 7975 (const_int 0))) 7976 (set (match_operand:SWI124 0 "nonimmediate_operand" "=<r>,<r>m") 7977 (and:SWI124 (match_dup 1) (match_dup 2)))] 7978 "ix86_match_ccmode (insn, CCNOmode) 7979 && ix86_binary_operator_ok (AND, <MODE>mode, operands)" 7980 "and{<imodesuffix>}\t{%2, %0|%0, %2}" 7981 [(set_attr "type" "alu") 7982 (set_attr "mode" "<MODE>")]) 7983 7984;; See comment for addsi_1_zext why we do use nonimmediate_operand 7985(define_insn "*andsi_2_zext" 7986 [(set (reg FLAGS_REG) 7987 (compare (and:SI 7988 (match_operand:SI 1 "nonimmediate_operand" "%0") 7989 (match_operand:SI 2 "x86_64_general_operand" "rme")) 7990 (const_int 0))) 7991 (set (match_operand:DI 0 "register_operand" "=r") 7992 (zero_extend:DI (and:SI (match_dup 1) (match_dup 2))))] 7993 "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode) 7994 && ix86_binary_operator_ok (AND, SImode, operands)" 7995 "and{l}\t{%2, %k0|%k0, %2}" 7996 [(set_attr "type" "alu") 7997 (set_attr "mode" "SI")]) 7998 7999(define_insn "*andqi_2_slp" 8000 [(set (reg FLAGS_REG) 8001 (compare (and:QI 8002 (match_operand:QI 0 "nonimmediate_operand" "+q,qm") 8003 (match_operand:QI 1 "nonimmediate_operand" "qmn,qn")) 8004 (const_int 0))) 8005 (set (strict_low_part (match_dup 0)) 8006 (and:QI (match_dup 0) (match_dup 1)))] 8007 "(!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun)) 8008 && ix86_match_ccmode (insn, CCNOmode) 8009 && !(MEM_P (operands[0]) && MEM_P (operands[1]))" 8010 "and{b}\t{%1, %0|%0, %1}" 8011 [(set_attr "type" "alu1") 8012 (set_attr "mode" "QI")]) 8013 8014;; ??? A bug in recog prevents it from recognizing a const_int as an 8015;; operand to zero_extend in andqi_ext_1. It was checking explicitly 8016;; for a QImode operand, which of course failed. 8017(define_insn "andqi_ext_0" 8018 [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q") 8019 (const_int 8) 8020 (const_int 8)) 8021 (and:SI 8022 (zero_extract:SI 8023 (match_operand 1 "ext_register_operand" "0") 8024 (const_int 8) 8025 (const_int 8)) 8026 (match_operand 2 "const_int_operand" "n"))) 8027 (clobber (reg:CC FLAGS_REG))] 8028 "" 8029 "and{b}\t{%2, %h0|%h0, %2}" 8030 [(set_attr "type" "alu") 8031 (set_attr "length_immediate" "1") 8032 (set_attr "modrm" "1") 8033 (set_attr "mode" "QI")]) 8034 8035;; Generated by peephole translating test to and. This shows up 8036;; often in fp comparisons. 8037(define_insn "*andqi_ext_0_cc" 8038 [(set (reg FLAGS_REG) 8039 (compare 8040 (and:SI 8041 (zero_extract:SI 8042 (match_operand 1 "ext_register_operand" "0") 8043 (const_int 8) 8044 (const_int 8)) 8045 (match_operand 2 "const_int_operand" "n")) 8046 (const_int 0))) 8047 (set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q") 8048 (const_int 8) 8049 (const_int 8)) 8050 (and:SI 8051 (zero_extract:SI 8052 (match_dup 1) 8053 (const_int 8) 8054 (const_int 8)) 8055 (match_dup 2)))] 8056 "ix86_match_ccmode (insn, CCNOmode)" 8057 "and{b}\t{%2, %h0|%h0, %2}" 8058 [(set_attr "type" "alu") 8059 (set_attr "length_immediate" "1") 8060 (set_attr "modrm" "1") 8061 (set_attr "mode" "QI")]) 8062 8063(define_insn "*andqi_ext_1_rex64" 8064 [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q") 8065 (const_int 8) 8066 (const_int 8)) 8067 (and:SI 8068 (zero_extract:SI 8069 (match_operand 1 "ext_register_operand" "0") 8070 (const_int 8) 8071 (const_int 8)) 8072 (zero_extend:SI 8073 (match_operand 2 "ext_register_operand" "Q")))) 8074 (clobber (reg:CC FLAGS_REG))] 8075 "TARGET_64BIT" 8076 "and{b}\t{%2, %h0|%h0, %2}" 8077 [(set_attr "type" "alu") 8078 (set_attr "length_immediate" "0") 8079 (set_attr "mode" "QI")]) 8080 8081(define_insn "*andqi_ext_1" 8082 [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q") 8083 (const_int 8) 8084 (const_int 8)) 8085 (and:SI 8086 (zero_extract:SI 8087 (match_operand 1 "ext_register_operand" "0") 8088 (const_int 8) 8089 (const_int 8)) 8090 (zero_extend:SI 8091 (match_operand:QI 2 "general_operand" "Qm")))) 8092 (clobber (reg:CC FLAGS_REG))] 8093 "!TARGET_64BIT" 8094 "and{b}\t{%2, %h0|%h0, %2}" 8095 [(set_attr "type" "alu") 8096 (set_attr "length_immediate" "0") 8097 (set_attr "mode" "QI")]) 8098 8099(define_insn "*andqi_ext_2" 8100 [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q") 8101 (const_int 8) 8102 (const_int 8)) 8103 (and:SI 8104 (zero_extract:SI 8105 (match_operand 1 "ext_register_operand" "%0") 8106 (const_int 8) 8107 (const_int 8)) 8108 (zero_extract:SI 8109 (match_operand 2 "ext_register_operand" "Q") 8110 (const_int 8) 8111 (const_int 8)))) 8112 (clobber (reg:CC FLAGS_REG))] 8113 "" 8114 "and{b}\t{%h2, %h0|%h0, %h2}" 8115 [(set_attr "type" "alu") 8116 (set_attr "length_immediate" "0") 8117 (set_attr "mode" "QI")]) 8118 8119;; Convert wide AND instructions with immediate operand to shorter QImode 8120;; equivalents when possible. 8121;; Don't do the splitting with memory operands, since it introduces risk 8122;; of memory mismatch stalls. We may want to do the splitting for optimizing 8123;; for size, but that can (should?) be handled by generic code instead. 8124(define_split 8125 [(set (match_operand 0 "register_operand" "") 8126 (and (match_operand 1 "register_operand" "") 8127 (match_operand 2 "const_int_operand" ""))) 8128 (clobber (reg:CC FLAGS_REG))] 8129 "reload_completed 8130 && QI_REG_P (operands[0]) 8131 && (!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun)) 8132 && !(~INTVAL (operands[2]) & ~(255 << 8)) 8133 && GET_MODE (operands[0]) != QImode" 8134 [(parallel [(set (zero_extract:SI (match_dup 0) (const_int 8) (const_int 8)) 8135 (and:SI (zero_extract:SI (match_dup 1) 8136 (const_int 8) (const_int 8)) 8137 (match_dup 2))) 8138 (clobber (reg:CC FLAGS_REG))])] 8139{ 8140 operands[0] = gen_lowpart (SImode, operands[0]); 8141 operands[1] = gen_lowpart (SImode, operands[1]); 8142 operands[2] = gen_int_mode ((INTVAL (operands[2]) >> 8) & 0xff, SImode); 8143}) 8144 8145;; Since AND can be encoded with sign extended immediate, this is only 8146;; profitable when 7th bit is not set. 8147(define_split 8148 [(set (match_operand 0 "register_operand" "") 8149 (and (match_operand 1 "general_operand" "") 8150 (match_operand 2 "const_int_operand" ""))) 8151 (clobber (reg:CC FLAGS_REG))] 8152 "reload_completed 8153 && ANY_QI_REG_P (operands[0]) 8154 && (!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun)) 8155 && !(~INTVAL (operands[2]) & ~255) 8156 && !(INTVAL (operands[2]) & 128) 8157 && GET_MODE (operands[0]) != QImode" 8158 [(parallel [(set (strict_low_part (match_dup 0)) 8159 (and:QI (match_dup 1) 8160 (match_dup 2))) 8161 (clobber (reg:CC FLAGS_REG))])] 8162{ 8163 operands[0] = gen_lowpart (QImode, operands[0]); 8164 operands[1] = gen_lowpart (QImode, operands[1]); 8165 operands[2] = gen_lowpart (QImode, operands[2]); 8166}) 8167 8168;; Logical inclusive and exclusive OR instructions 8169 8170;; %%% This used to optimize known byte-wide and operations to memory. 8171;; If this is considered useful, it should be done with splitters. 8172 8173(define_expand "<code><mode>3" 8174 [(set (match_operand:SWIM 0 "nonimmediate_operand" "") 8175 (any_or:SWIM (match_operand:SWIM 1 "nonimmediate_operand" "") 8176 (match_operand:SWIM 2 "<general_operand>" "")))] 8177 "" 8178 "ix86_expand_binary_operator (<CODE>, <MODE>mode, operands); DONE;") 8179 8180(define_insn "*<code><mode>_1" 8181 [(set (match_operand:SWI248 0 "nonimmediate_operand" "=r,rm") 8182 (any_or:SWI248 8183 (match_operand:SWI248 1 "nonimmediate_operand" "%0,0") 8184 (match_operand:SWI248 2 "<general_operand>" "<g>,r<i>"))) 8185 (clobber (reg:CC FLAGS_REG))] 8186 "ix86_binary_operator_ok (<CODE>, <MODE>mode, operands)" 8187 "<logic>{<imodesuffix>}\t{%2, %0|%0, %2}" 8188 [(set_attr "type" "alu") 8189 (set_attr "mode" "<MODE>")]) 8190 8191;; %%% Potential partial reg stall on alternative 2. What to do? 8192(define_insn "*<code>qi_1" 8193 [(set (match_operand:QI 0 "nonimmediate_operand" "=q,m,r") 8194 (any_or:QI (match_operand:QI 1 "nonimmediate_operand" "%0,0,0") 8195 (match_operand:QI 2 "general_operand" "qmn,qn,rn"))) 8196 (clobber (reg:CC FLAGS_REG))] 8197 "ix86_binary_operator_ok (<CODE>, QImode, operands)" 8198 "@ 8199 <logic>{b}\t{%2, %0|%0, %2} 8200 <logic>{b}\t{%2, %0|%0, %2} 8201 <logic>{l}\t{%k2, %k0|%k0, %k2}" 8202 [(set_attr "type" "alu") 8203 (set_attr "mode" "QI,QI,SI")]) 8204 8205;; See comment for addsi_1_zext why we do use nonimmediate_operand 8206(define_insn "*<code>si_1_zext" 8207 [(set (match_operand:DI 0 "register_operand" "=r") 8208 (zero_extend:DI 8209 (any_or:SI (match_operand:SI 1 "nonimmediate_operand" "%0") 8210 (match_operand:SI 2 "x86_64_general_operand" "rme")))) 8211 (clobber (reg:CC FLAGS_REG))] 8212 "TARGET_64BIT && ix86_binary_operator_ok (<CODE>, SImode, operands)" 8213 "<logic>{l}\t{%2, %k0|%k0, %2}" 8214 [(set_attr "type" "alu") 8215 (set_attr "mode" "SI")]) 8216 8217(define_insn "*<code>si_1_zext_imm" 8218 [(set (match_operand:DI 0 "register_operand" "=r") 8219 (any_or:DI 8220 (zero_extend:DI (match_operand:SI 1 "register_operand" "%0")) 8221 (match_operand:DI 2 "x86_64_zext_immediate_operand" "Z"))) 8222 (clobber (reg:CC FLAGS_REG))] 8223 "TARGET_64BIT && ix86_binary_operator_ok (<CODE>, SImode, operands)" 8224 "<logic>{l}\t{%2, %k0|%k0, %2}" 8225 [(set_attr "type" "alu") 8226 (set_attr "mode" "SI")]) 8227 8228(define_insn "*<code>qi_1_slp" 8229 [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+q,m")) 8230 (any_or:QI (match_dup 0) 8231 (match_operand:QI 1 "general_operand" "qmn,qn"))) 8232 (clobber (reg:CC FLAGS_REG))] 8233 "(!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun)) 8234 && !(MEM_P (operands[0]) && MEM_P (operands[1]))" 8235 "<logic>{b}\t{%1, %0|%0, %1}" 8236 [(set_attr "type" "alu1") 8237 (set_attr "mode" "QI")]) 8238 8239(define_insn "*<code><mode>_2" 8240 [(set (reg FLAGS_REG) 8241 (compare (any_or:SWI 8242 (match_operand:SWI 1 "nonimmediate_operand" "%0,0") 8243 (match_operand:SWI 2 "<general_operand>" "<g>,<r><i>")) 8244 (const_int 0))) 8245 (set (match_operand:SWI 0 "nonimmediate_operand" "=<r>,<r>m") 8246 (any_or:SWI (match_dup 1) (match_dup 2)))] 8247 "ix86_match_ccmode (insn, CCNOmode) 8248 && ix86_binary_operator_ok (<CODE>, <MODE>mode, operands)" 8249 "<logic>{<imodesuffix>}\t{%2, %0|%0, %2}" 8250 [(set_attr "type" "alu") 8251 (set_attr "mode" "<MODE>")]) 8252 8253;; See comment for addsi_1_zext why we do use nonimmediate_operand 8254;; ??? Special case for immediate operand is missing - it is tricky. 8255(define_insn "*<code>si_2_zext" 8256 [(set (reg FLAGS_REG) 8257 (compare (any_or:SI (match_operand:SI 1 "nonimmediate_operand" "%0") 8258 (match_operand:SI 2 "x86_64_general_operand" "rme")) 8259 (const_int 0))) 8260 (set (match_operand:DI 0 "register_operand" "=r") 8261 (zero_extend:DI (any_or:SI (match_dup 1) (match_dup 2))))] 8262 "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode) 8263 && ix86_binary_operator_ok (<CODE>, SImode, operands)" 8264 "<logic>{l}\t{%2, %k0|%k0, %2}" 8265 [(set_attr "type" "alu") 8266 (set_attr "mode" "SI")]) 8267 8268(define_insn "*<code>si_2_zext_imm" 8269 [(set (reg FLAGS_REG) 8270 (compare (any_or:SI 8271 (match_operand:SI 1 "nonimmediate_operand" "%0") 8272 (match_operand:SI 2 "x86_64_zext_immediate_operand" "Z")) 8273 (const_int 0))) 8274 (set (match_operand:DI 0 "register_operand" "=r") 8275 (any_or:DI (zero_extend:DI (match_dup 1)) (match_dup 2)))] 8276 "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode) 8277 && ix86_binary_operator_ok (<CODE>, SImode, operands)" 8278 "<logic>{l}\t{%2, %k0|%k0, %2}" 8279 [(set_attr "type" "alu") 8280 (set_attr "mode" "SI")]) 8281 8282(define_insn "*<code>qi_2_slp" 8283 [(set (reg FLAGS_REG) 8284 (compare (any_or:QI (match_operand:QI 0 "nonimmediate_operand" "+q,qm") 8285 (match_operand:QI 1 "general_operand" "qmn,qn")) 8286 (const_int 0))) 8287 (set (strict_low_part (match_dup 0)) 8288 (any_or:QI (match_dup 0) (match_dup 1)))] 8289 "(!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun)) 8290 && ix86_match_ccmode (insn, CCNOmode) 8291 && !(MEM_P (operands[0]) && MEM_P (operands[1]))" 8292 "<logic>{b}\t{%1, %0|%0, %1}" 8293 [(set_attr "type" "alu1") 8294 (set_attr "mode" "QI")]) 8295 8296(define_insn "*<code><mode>_3" 8297 [(set (reg FLAGS_REG) 8298 (compare (any_or:SWI 8299 (match_operand:SWI 1 "nonimmediate_operand" "%0") 8300 (match_operand:SWI 2 "<general_operand>" "<g>")) 8301 (const_int 0))) 8302 (clobber (match_scratch:SWI 0 "=<r>"))] 8303 "ix86_match_ccmode (insn, CCNOmode) 8304 && !(MEM_P (operands[1]) && MEM_P (operands[2]))" 8305 "<logic>{<imodesuffix>}\t{%2, %0|%0, %2}" 8306 [(set_attr "type" "alu") 8307 (set_attr "mode" "<MODE>")]) 8308 8309(define_insn "*<code>qi_ext_0" 8310 [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q") 8311 (const_int 8) 8312 (const_int 8)) 8313 (any_or:SI 8314 (zero_extract:SI 8315 (match_operand 1 "ext_register_operand" "0") 8316 (const_int 8) 8317 (const_int 8)) 8318 (match_operand 2 "const_int_operand" "n"))) 8319 (clobber (reg:CC FLAGS_REG))] 8320 "!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun)" 8321 "<logic>{b}\t{%2, %h0|%h0, %2}" 8322 [(set_attr "type" "alu") 8323 (set_attr "length_immediate" "1") 8324 (set_attr "modrm" "1") 8325 (set_attr "mode" "QI")]) 8326 8327(define_insn "*<code>qi_ext_1_rex64" 8328 [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q") 8329 (const_int 8) 8330 (const_int 8)) 8331 (any_or:SI 8332 (zero_extract:SI 8333 (match_operand 1 "ext_register_operand" "0") 8334 (const_int 8) 8335 (const_int 8)) 8336 (zero_extend:SI 8337 (match_operand 2 "ext_register_operand" "Q")))) 8338 (clobber (reg:CC FLAGS_REG))] 8339 "TARGET_64BIT 8340 && (!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))" 8341 "<logic>{b}\t{%2, %h0|%h0, %2}" 8342 [(set_attr "type" "alu") 8343 (set_attr "length_immediate" "0") 8344 (set_attr "mode" "QI")]) 8345 8346(define_insn "*<code>qi_ext_1" 8347 [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q") 8348 (const_int 8) 8349 (const_int 8)) 8350 (any_or:SI 8351 (zero_extract:SI 8352 (match_operand 1 "ext_register_operand" "0") 8353 (const_int 8) 8354 (const_int 8)) 8355 (zero_extend:SI 8356 (match_operand:QI 2 "general_operand" "Qm")))) 8357 (clobber (reg:CC FLAGS_REG))] 8358 "!TARGET_64BIT 8359 && (!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))" 8360 "<logic>{b}\t{%2, %h0|%h0, %2}" 8361 [(set_attr "type" "alu") 8362 (set_attr "length_immediate" "0") 8363 (set_attr "mode" "QI")]) 8364 8365(define_insn "*<code>qi_ext_2" 8366 [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q") 8367 (const_int 8) 8368 (const_int 8)) 8369 (any_or:SI 8370 (zero_extract:SI (match_operand 1 "ext_register_operand" "0") 8371 (const_int 8) 8372 (const_int 8)) 8373 (zero_extract:SI (match_operand 2 "ext_register_operand" "Q") 8374 (const_int 8) 8375 (const_int 8)))) 8376 (clobber (reg:CC FLAGS_REG))] 8377 "!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun)" 8378 "<logic>{b}\t{%h2, %h0|%h0, %h2}" 8379 [(set_attr "type" "alu") 8380 (set_attr "length_immediate" "0") 8381 (set_attr "mode" "QI")]) 8382 8383(define_split 8384 [(set (match_operand 0 "register_operand" "") 8385 (any_or (match_operand 1 "register_operand" "") 8386 (match_operand 2 "const_int_operand" ""))) 8387 (clobber (reg:CC FLAGS_REG))] 8388 "reload_completed 8389 && QI_REG_P (operands[0]) 8390 && (!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun)) 8391 && !(INTVAL (operands[2]) & ~(255 << 8)) 8392 && GET_MODE (operands[0]) != QImode" 8393 [(parallel [(set (zero_extract:SI (match_dup 0) (const_int 8) (const_int 8)) 8394 (any_or:SI (zero_extract:SI (match_dup 1) 8395 (const_int 8) (const_int 8)) 8396 (match_dup 2))) 8397 (clobber (reg:CC FLAGS_REG))])] 8398{ 8399 operands[0] = gen_lowpart (SImode, operands[0]); 8400 operands[1] = gen_lowpart (SImode, operands[1]); 8401 operands[2] = gen_int_mode ((INTVAL (operands[2]) >> 8) & 0xff, SImode); 8402}) 8403 8404;; Since OR can be encoded with sign extended immediate, this is only 8405;; profitable when 7th bit is set. 8406(define_split 8407 [(set (match_operand 0 "register_operand" "") 8408 (any_or (match_operand 1 "general_operand" "") 8409 (match_operand 2 "const_int_operand" ""))) 8410 (clobber (reg:CC FLAGS_REG))] 8411 "reload_completed 8412 && ANY_QI_REG_P (operands[0]) 8413 && (!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun)) 8414 && !(INTVAL (operands[2]) & ~255) 8415 && (INTVAL (operands[2]) & 128) 8416 && GET_MODE (operands[0]) != QImode" 8417 [(parallel [(set (strict_low_part (match_dup 0)) 8418 (any_or:QI (match_dup 1) 8419 (match_dup 2))) 8420 (clobber (reg:CC FLAGS_REG))])] 8421{ 8422 operands[0] = gen_lowpart (QImode, operands[0]); 8423 operands[1] = gen_lowpart (QImode, operands[1]); 8424 operands[2] = gen_lowpart (QImode, operands[2]); 8425}) 8426 8427(define_expand "xorqi_cc_ext_1" 8428 [(parallel [ 8429 (set (reg:CCNO FLAGS_REG) 8430 (compare:CCNO 8431 (xor:SI 8432 (zero_extract:SI 8433 (match_operand 1 "ext_register_operand" "") 8434 (const_int 8) 8435 (const_int 8)) 8436 (match_operand:QI 2 "general_operand" "")) 8437 (const_int 0))) 8438 (set (zero_extract:SI (match_operand 0 "ext_register_operand" "") 8439 (const_int 8) 8440 (const_int 8)) 8441 (xor:SI 8442 (zero_extract:SI 8443 (match_dup 1) 8444 (const_int 8) 8445 (const_int 8)) 8446 (match_dup 2)))])]) 8447 8448(define_insn "*xorqi_cc_ext_1_rex64" 8449 [(set (reg FLAGS_REG) 8450 (compare 8451 (xor:SI 8452 (zero_extract:SI 8453 (match_operand 1 "ext_register_operand" "0") 8454 (const_int 8) 8455 (const_int 8)) 8456 (match_operand:QI 2 "nonmemory_operand" "Qn")) 8457 (const_int 0))) 8458 (set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q") 8459 (const_int 8) 8460 (const_int 8)) 8461 (xor:SI 8462 (zero_extract:SI 8463 (match_dup 1) 8464 (const_int 8) 8465 (const_int 8)) 8466 (match_dup 2)))] 8467 "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)" 8468 "xor{b}\t{%2, %h0|%h0, %2}" 8469 [(set_attr "type" "alu") 8470 (set_attr "modrm" "1") 8471 (set_attr "mode" "QI")]) 8472 8473(define_insn "*xorqi_cc_ext_1" 8474 [(set (reg FLAGS_REG) 8475 (compare 8476 (xor:SI 8477 (zero_extract:SI 8478 (match_operand 1 "ext_register_operand" "0") 8479 (const_int 8) 8480 (const_int 8)) 8481 (match_operand:QI 2 "general_operand" "qmn")) 8482 (const_int 0))) 8483 (set (zero_extract:SI (match_operand 0 "ext_register_operand" "=q") 8484 (const_int 8) 8485 (const_int 8)) 8486 (xor:SI 8487 (zero_extract:SI 8488 (match_dup 1) 8489 (const_int 8) 8490 (const_int 8)) 8491 (match_dup 2)))] 8492 "!TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)" 8493 "xor{b}\t{%2, %h0|%h0, %2}" 8494 [(set_attr "type" "alu") 8495 (set_attr "modrm" "1") 8496 (set_attr "mode" "QI")]) 8497 8498;; Negation instructions 8499 8500(define_expand "neg<mode>2" 8501 [(set (match_operand:SDWIM 0 "nonimmediate_operand" "") 8502 (neg:SDWIM (match_operand:SDWIM 1 "nonimmediate_operand" "")))] 8503 "" 8504 "ix86_expand_unary_operator (NEG, <MODE>mode, operands); DONE;") 8505 8506(define_insn_and_split "*neg<dwi>2_doubleword" 8507 [(set (match_operand:<DWI> 0 "nonimmediate_operand" "=ro") 8508 (neg:<DWI> (match_operand:<DWI> 1 "nonimmediate_operand" "0"))) 8509 (clobber (reg:CC FLAGS_REG))] 8510 "ix86_unary_operator_ok (NEG, <DWI>mode, operands)" 8511 "#" 8512 "reload_completed" 8513 [(parallel 8514 [(set (reg:CCZ FLAGS_REG) 8515 (compare:CCZ (neg:DWIH (match_dup 1)) (const_int 0))) 8516 (set (match_dup 0) (neg:DWIH (match_dup 1)))]) 8517 (parallel 8518 [(set (match_dup 2) 8519 (plus:DWIH (match_dup 3) 8520 (plus:DWIH (ltu:DWIH (reg:CC FLAGS_REG) (const_int 0)) 8521 (const_int 0)))) 8522 (clobber (reg:CC FLAGS_REG))]) 8523 (parallel 8524 [(set (match_dup 2) 8525 (neg:DWIH (match_dup 2))) 8526 (clobber (reg:CC FLAGS_REG))])] 8527 "split_double_mode (<DWI>mode, &operands[0], 2, &operands[0], &operands[2]);") 8528 8529(define_insn "*neg<mode>2_1" 8530 [(set (match_operand:SWI 0 "nonimmediate_operand" "=<r>m") 8531 (neg:SWI (match_operand:SWI 1 "nonimmediate_operand" "0"))) 8532 (clobber (reg:CC FLAGS_REG))] 8533 "ix86_unary_operator_ok (NEG, <MODE>mode, operands)" 8534 "neg{<imodesuffix>}\t%0" 8535 [(set_attr "type" "negnot") 8536 (set_attr "mode" "<MODE>")]) 8537 8538;; Combine is quite creative about this pattern. 8539(define_insn "*negsi2_1_zext" 8540 [(set (match_operand:DI 0 "register_operand" "=r") 8541 (lshiftrt:DI 8542 (neg:DI (ashift:DI (match_operand:DI 1 "register_operand" "0") 8543 (const_int 32))) 8544 (const_int 32))) 8545 (clobber (reg:CC FLAGS_REG))] 8546 "TARGET_64BIT && ix86_unary_operator_ok (NEG, SImode, operands)" 8547 "neg{l}\t%k0" 8548 [(set_attr "type" "negnot") 8549 (set_attr "mode" "SI")]) 8550 8551;; The problem with neg is that it does not perform (compare x 0), 8552;; it really performs (compare 0 x), which leaves us with the zero 8553;; flag being the only useful item. 8554 8555(define_insn "*neg<mode>2_cmpz" 8556 [(set (reg:CCZ FLAGS_REG) 8557 (compare:CCZ 8558 (neg:SWI (match_operand:SWI 1 "nonimmediate_operand" "0")) 8559 (const_int 0))) 8560 (set (match_operand:SWI 0 "nonimmediate_operand" "=<r>m") 8561 (neg:SWI (match_dup 1)))] 8562 "ix86_unary_operator_ok (NEG, <MODE>mode, operands)" 8563 "neg{<imodesuffix>}\t%0" 8564 [(set_attr "type" "negnot") 8565 (set_attr "mode" "<MODE>")]) 8566 8567(define_insn "*negsi2_cmpz_zext" 8568 [(set (reg:CCZ FLAGS_REG) 8569 (compare:CCZ 8570 (lshiftrt:DI 8571 (neg:DI (ashift:DI 8572 (match_operand:DI 1 "register_operand" "0") 8573 (const_int 32))) 8574 (const_int 32)) 8575 (const_int 0))) 8576 (set (match_operand:DI 0 "register_operand" "=r") 8577 (lshiftrt:DI (neg:DI (ashift:DI (match_dup 1) 8578 (const_int 32))) 8579 (const_int 32)))] 8580 "TARGET_64BIT && ix86_unary_operator_ok (NEG, SImode, operands)" 8581 "neg{l}\t%k0" 8582 [(set_attr "type" "negnot") 8583 (set_attr "mode" "SI")]) 8584 8585;; Changing of sign for FP values is doable using integer unit too. 8586 8587(define_expand "<code><mode>2" 8588 [(set (match_operand:X87MODEF 0 "register_operand" "") 8589 (absneg:X87MODEF (match_operand:X87MODEF 1 "register_operand" "")))] 8590 "TARGET_80387 || (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)" 8591 "ix86_expand_fp_absneg_operator (<CODE>, <MODE>mode, operands); DONE;") 8592 8593(define_insn "*absneg<mode>2_mixed" 8594 [(set (match_operand:MODEF 0 "register_operand" "=x,x,f,!r") 8595 (match_operator:MODEF 3 "absneg_operator" 8596 [(match_operand:MODEF 1 "register_operand" "0,x,0,0")])) 8597 (use (match_operand:<ssevecmode> 2 "nonimmediate_operand" "xm,0,X,X")) 8598 (clobber (reg:CC FLAGS_REG))] 8599 "TARGET_MIX_SSE_I387 && SSE_FLOAT_MODE_P (<MODE>mode)" 8600 "#") 8601 8602(define_insn "*absneg<mode>2_sse" 8603 [(set (match_operand:MODEF 0 "register_operand" "=x,x,!r") 8604 (match_operator:MODEF 3 "absneg_operator" 8605 [(match_operand:MODEF 1 "register_operand" "0 ,x,0")])) 8606 (use (match_operand:<ssevecmode> 2 "register_operand" "xm,0,X")) 8607 (clobber (reg:CC FLAGS_REG))] 8608 "SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH" 8609 "#") 8610 8611(define_insn "*absneg<mode>2_i387" 8612 [(set (match_operand:X87MODEF 0 "register_operand" "=f,!r") 8613 (match_operator:X87MODEF 3 "absneg_operator" 8614 [(match_operand:X87MODEF 1 "register_operand" "0,0")])) 8615 (use (match_operand 2 "" "")) 8616 (clobber (reg:CC FLAGS_REG))] 8617 "TARGET_80387 && !(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)" 8618 "#") 8619 8620(define_expand "<code>tf2" 8621 [(set (match_operand:TF 0 "register_operand" "") 8622 (absneg:TF (match_operand:TF 1 "register_operand" "")))] 8623 "TARGET_SSE2" 8624 "ix86_expand_fp_absneg_operator (<CODE>, TFmode, operands); DONE;") 8625 8626(define_insn "*absnegtf2_sse" 8627 [(set (match_operand:TF 0 "register_operand" "=x,x") 8628 (match_operator:TF 3 "absneg_operator" 8629 [(match_operand:TF 1 "register_operand" "0,x")])) 8630 (use (match_operand:TF 2 "nonimmediate_operand" "xm,0")) 8631 (clobber (reg:CC FLAGS_REG))] 8632 "TARGET_SSE2" 8633 "#") 8634 8635;; Splitters for fp abs and neg. 8636 8637(define_split 8638 [(set (match_operand 0 "fp_register_operand" "") 8639 (match_operator 1 "absneg_operator" [(match_dup 0)])) 8640 (use (match_operand 2 "" "")) 8641 (clobber (reg:CC FLAGS_REG))] 8642 "reload_completed" 8643 [(set (match_dup 0) (match_op_dup 1 [(match_dup 0)]))]) 8644 8645(define_split 8646 [(set (match_operand 0 "register_operand" "") 8647 (match_operator 3 "absneg_operator" 8648 [(match_operand 1 "register_operand" "")])) 8649 (use (match_operand 2 "nonimmediate_operand" "")) 8650 (clobber (reg:CC FLAGS_REG))] 8651 "reload_completed && SSE_REG_P (operands[0])" 8652 [(set (match_dup 0) (match_dup 3))] 8653{ 8654 enum machine_mode mode = GET_MODE (operands[0]); 8655 enum machine_mode vmode = GET_MODE (operands[2]); 8656 rtx tmp; 8657 8658 operands[0] = simplify_gen_subreg (vmode, operands[0], mode, 0); 8659 operands[1] = simplify_gen_subreg (vmode, operands[1], mode, 0); 8660 if (operands_match_p (operands[0], operands[2])) 8661 { 8662 tmp = operands[1]; 8663 operands[1] = operands[2]; 8664 operands[2] = tmp; 8665 } 8666 if (GET_CODE (operands[3]) == ABS) 8667 tmp = gen_rtx_AND (vmode, operands[1], operands[2]); 8668 else 8669 tmp = gen_rtx_XOR (vmode, operands[1], operands[2]); 8670 operands[3] = tmp; 8671}) 8672 8673(define_split 8674 [(set (match_operand:SF 0 "register_operand" "") 8675 (match_operator:SF 1 "absneg_operator" [(match_dup 0)])) 8676 (use (match_operand:V4SF 2 "" "")) 8677 (clobber (reg:CC FLAGS_REG))] 8678 "reload_completed" 8679 [(parallel [(set (match_dup 0) (match_dup 1)) 8680 (clobber (reg:CC FLAGS_REG))])] 8681{ 8682 rtx tmp; 8683 operands[0] = gen_lowpart (SImode, operands[0]); 8684 if (GET_CODE (operands[1]) == ABS) 8685 { 8686 tmp = gen_int_mode (0x7fffffff, SImode); 8687 tmp = gen_rtx_AND (SImode, operands[0], tmp); 8688 } 8689 else 8690 { 8691 tmp = gen_int_mode (0x80000000, SImode); 8692 tmp = gen_rtx_XOR (SImode, operands[0], tmp); 8693 } 8694 operands[1] = tmp; 8695}) 8696 8697(define_split 8698 [(set (match_operand:DF 0 "register_operand" "") 8699 (match_operator:DF 1 "absneg_operator" [(match_dup 0)])) 8700 (use (match_operand 2 "" "")) 8701 (clobber (reg:CC FLAGS_REG))] 8702 "reload_completed" 8703 [(parallel [(set (match_dup 0) (match_dup 1)) 8704 (clobber (reg:CC FLAGS_REG))])] 8705{ 8706 rtx tmp; 8707 if (TARGET_64BIT) 8708 { 8709 tmp = gen_lowpart (DImode, operands[0]); 8710 tmp = gen_rtx_ZERO_EXTRACT (DImode, tmp, const1_rtx, GEN_INT (63)); 8711 operands[0] = tmp; 8712 8713 if (GET_CODE (operands[1]) == ABS) 8714 tmp = const0_rtx; 8715 else 8716 tmp = gen_rtx_NOT (DImode, tmp); 8717 } 8718 else 8719 { 8720 operands[0] = gen_highpart (SImode, operands[0]); 8721 if (GET_CODE (operands[1]) == ABS) 8722 { 8723 tmp = gen_int_mode (0x7fffffff, SImode); 8724 tmp = gen_rtx_AND (SImode, operands[0], tmp); 8725 } 8726 else 8727 { 8728 tmp = gen_int_mode (0x80000000, SImode); 8729 tmp = gen_rtx_XOR (SImode, operands[0], tmp); 8730 } 8731 } 8732 operands[1] = tmp; 8733}) 8734 8735(define_split 8736 [(set (match_operand:XF 0 "register_operand" "") 8737 (match_operator:XF 1 "absneg_operator" [(match_dup 0)])) 8738 (use (match_operand 2 "" "")) 8739 (clobber (reg:CC FLAGS_REG))] 8740 "reload_completed" 8741 [(parallel [(set (match_dup 0) (match_dup 1)) 8742 (clobber (reg:CC FLAGS_REG))])] 8743{ 8744 rtx tmp; 8745 operands[0] = gen_rtx_REG (SImode, 8746 true_regnum (operands[0]) 8747 + (TARGET_64BIT ? 1 : 2)); 8748 if (GET_CODE (operands[1]) == ABS) 8749 { 8750 tmp = GEN_INT (0x7fff); 8751 tmp = gen_rtx_AND (SImode, operands[0], tmp); 8752 } 8753 else 8754 { 8755 tmp = GEN_INT (0x8000); 8756 tmp = gen_rtx_XOR (SImode, operands[0], tmp); 8757 } 8758 operands[1] = tmp; 8759}) 8760 8761;; Conditionalize these after reload. If they match before reload, we 8762;; lose the clobber and ability to use integer instructions. 8763 8764(define_insn "*<code><mode>2_1" 8765 [(set (match_operand:X87MODEF 0 "register_operand" "=f") 8766 (absneg:X87MODEF (match_operand:X87MODEF 1 "register_operand" "0")))] 8767 "TARGET_80387 8768 && (reload_completed 8769 || !(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH))" 8770 "f<absneg_mnemonic>" 8771 [(set_attr "type" "fsgn") 8772 (set_attr "mode" "<MODE>")]) 8773 8774(define_insn "*<code>extendsfdf2" 8775 [(set (match_operand:DF 0 "register_operand" "=f") 8776 (absneg:DF (float_extend:DF 8777 (match_operand:SF 1 "register_operand" "0"))))] 8778 "TARGET_80387 && (!TARGET_SSE_MATH || TARGET_MIX_SSE_I387)" 8779 "f<absneg_mnemonic>" 8780 [(set_attr "type" "fsgn") 8781 (set_attr "mode" "DF")]) 8782 8783(define_insn "*<code>extendsfxf2" 8784 [(set (match_operand:XF 0 "register_operand" "=f") 8785 (absneg:XF (float_extend:XF 8786 (match_operand:SF 1 "register_operand" "0"))))] 8787 "TARGET_80387" 8788 "f<absneg_mnemonic>" 8789 [(set_attr "type" "fsgn") 8790 (set_attr "mode" "XF")]) 8791 8792(define_insn "*<code>extenddfxf2" 8793 [(set (match_operand:XF 0 "register_operand" "=f") 8794 (absneg:XF (float_extend:XF 8795 (match_operand:DF 1 "register_operand" "0"))))] 8796 "TARGET_80387" 8797 "f<absneg_mnemonic>" 8798 [(set_attr "type" "fsgn") 8799 (set_attr "mode" "XF")]) 8800 8801;; Copysign instructions 8802 8803(define_mode_iterator CSGNMODE [SF DF TF]) 8804(define_mode_attr CSGNVMODE [(SF "V4SF") (DF "V2DF") (TF "TF")]) 8805 8806(define_expand "copysign<mode>3" 8807 [(match_operand:CSGNMODE 0 "register_operand" "") 8808 (match_operand:CSGNMODE 1 "nonmemory_operand" "") 8809 (match_operand:CSGNMODE 2 "register_operand" "")] 8810 "(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH) 8811 || (TARGET_SSE2 && (<MODE>mode == TFmode))" 8812 "ix86_expand_copysign (operands); DONE;") 8813 8814(define_insn_and_split "copysign<mode>3_const" 8815 [(set (match_operand:CSGNMODE 0 "register_operand" "=x") 8816 (unspec:CSGNMODE 8817 [(match_operand:<CSGNVMODE> 1 "vector_move_operand" "xmC") 8818 (match_operand:CSGNMODE 2 "register_operand" "0") 8819 (match_operand:<CSGNVMODE> 3 "nonimmediate_operand" "xm")] 8820 UNSPEC_COPYSIGN))] 8821 "(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH) 8822 || (TARGET_SSE2 && (<MODE>mode == TFmode))" 8823 "#" 8824 "&& reload_completed" 8825 [(const_int 0)] 8826 "ix86_split_copysign_const (operands); DONE;") 8827 8828(define_insn "copysign<mode>3_var" 8829 [(set (match_operand:CSGNMODE 0 "register_operand" "=x,x,x,x,x") 8830 (unspec:CSGNMODE 8831 [(match_operand:CSGNMODE 2 "register_operand" "x,0,0,x,x") 8832 (match_operand:CSGNMODE 3 "register_operand" "1,1,x,1,x") 8833 (match_operand:<CSGNVMODE> 4 "nonimmediate_operand" "X,xm,xm,0,0") 8834 (match_operand:<CSGNVMODE> 5 "nonimmediate_operand" "0,xm,1,xm,1")] 8835 UNSPEC_COPYSIGN)) 8836 (clobber (match_scratch:<CSGNVMODE> 1 "=x,x,x,x,x"))] 8837 "(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH) 8838 || (TARGET_SSE2 && (<MODE>mode == TFmode))" 8839 "#") 8840 8841(define_split 8842 [(set (match_operand:CSGNMODE 0 "register_operand" "") 8843 (unspec:CSGNMODE 8844 [(match_operand:CSGNMODE 2 "register_operand" "") 8845 (match_operand:CSGNMODE 3 "register_operand" "") 8846 (match_operand:<CSGNVMODE> 4 "" "") 8847 (match_operand:<CSGNVMODE> 5 "" "")] 8848 UNSPEC_COPYSIGN)) 8849 (clobber (match_scratch:<CSGNVMODE> 1 ""))] 8850 "((SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH) 8851 || (TARGET_SSE2 && (<MODE>mode == TFmode))) 8852 && reload_completed" 8853 [(const_int 0)] 8854 "ix86_split_copysign_var (operands); DONE;") 8855 8856;; One complement instructions 8857 8858(define_expand "one_cmpl<mode>2" 8859 [(set (match_operand:SWIM 0 "nonimmediate_operand" "") 8860 (not:SWIM (match_operand:SWIM 1 "nonimmediate_operand" "")))] 8861 "" 8862 "ix86_expand_unary_operator (NOT, <MODE>mode, operands); DONE;") 8863 8864(define_insn "*one_cmpl<mode>2_1" 8865 [(set (match_operand:SWI248 0 "nonimmediate_operand" "=rm") 8866 (not:SWI248 (match_operand:SWI248 1 "nonimmediate_operand" "0")))] 8867 "ix86_unary_operator_ok (NOT, <MODE>mode, operands)" 8868 "not{<imodesuffix>}\t%0" 8869 [(set_attr "type" "negnot") 8870 (set_attr "mode" "<MODE>")]) 8871 8872;; %%% Potential partial reg stall on alternative 1. What to do? 8873(define_insn "*one_cmplqi2_1" 8874 [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,r") 8875 (not:QI (match_operand:QI 1 "nonimmediate_operand" "0,0")))] 8876 "ix86_unary_operator_ok (NOT, QImode, operands)" 8877 "@ 8878 not{b}\t%0 8879 not{l}\t%k0" 8880 [(set_attr "type" "negnot") 8881 (set_attr "mode" "QI,SI")]) 8882 8883;; ??? Currently never generated - xor is used instead. 8884(define_insn "*one_cmplsi2_1_zext" 8885 [(set (match_operand:DI 0 "register_operand" "=r") 8886 (zero_extend:DI 8887 (not:SI (match_operand:SI 1 "register_operand" "0"))))] 8888 "TARGET_64BIT && ix86_unary_operator_ok (NOT, SImode, operands)" 8889 "not{l}\t%k0" 8890 [(set_attr "type" "negnot") 8891 (set_attr "mode" "SI")]) 8892 8893(define_insn "*one_cmpl<mode>2_2" 8894 [(set (reg FLAGS_REG) 8895 (compare (not:SWI (match_operand:SWI 1 "nonimmediate_operand" "0")) 8896 (const_int 0))) 8897 (set (match_operand:SWI 0 "nonimmediate_operand" "=<r>m") 8898 (not:SWI (match_dup 1)))] 8899 "ix86_match_ccmode (insn, CCNOmode) 8900 && ix86_unary_operator_ok (NOT, <MODE>mode, operands)" 8901 "#" 8902 [(set_attr "type" "alu1") 8903 (set_attr "mode" "<MODE>")]) 8904 8905(define_split 8906 [(set (match_operand 0 "flags_reg_operand" "") 8907 (match_operator 2 "compare_operator" 8908 [(not:SWI (match_operand:SWI 3 "nonimmediate_operand" "")) 8909 (const_int 0)])) 8910 (set (match_operand:SWI 1 "nonimmediate_operand" "") 8911 (not:SWI (match_dup 3)))] 8912 "ix86_match_ccmode (insn, CCNOmode)" 8913 [(parallel [(set (match_dup 0) 8914 (match_op_dup 2 [(xor:SWI (match_dup 3) (const_int -1)) 8915 (const_int 0)])) 8916 (set (match_dup 1) 8917 (xor:SWI (match_dup 3) (const_int -1)))])]) 8918 8919;; ??? Currently never generated - xor is used instead. 8920(define_insn "*one_cmplsi2_2_zext" 8921 [(set (reg FLAGS_REG) 8922 (compare (not:SI (match_operand:SI 1 "register_operand" "0")) 8923 (const_int 0))) 8924 (set (match_operand:DI 0 "register_operand" "=r") 8925 (zero_extend:DI (not:SI (match_dup 1))))] 8926 "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode) 8927 && ix86_unary_operator_ok (NOT, SImode, operands)" 8928 "#" 8929 [(set_attr "type" "alu1") 8930 (set_attr "mode" "SI")]) 8931 8932(define_split 8933 [(set (match_operand 0 "flags_reg_operand" "") 8934 (match_operator 2 "compare_operator" 8935 [(not:SI (match_operand:SI 3 "register_operand" "")) 8936 (const_int 0)])) 8937 (set (match_operand:DI 1 "register_operand" "") 8938 (zero_extend:DI (not:SI (match_dup 3))))] 8939 "ix86_match_ccmode (insn, CCNOmode)" 8940 [(parallel [(set (match_dup 0) 8941 (match_op_dup 2 [(xor:SI (match_dup 3) (const_int -1)) 8942 (const_int 0)])) 8943 (set (match_dup 1) 8944 (zero_extend:DI (xor:SI (match_dup 3) (const_int -1))))])]) 8945 8946;; Shift instructions 8947 8948;; DImode shifts are implemented using the i386 "shift double" opcode, 8949;; which is written as "sh[lr]d[lw] imm,reg,reg/mem". If the shift count 8950;; is variable, then the count is in %cl and the "imm" operand is dropped 8951;; from the assembler input. 8952;; 8953;; This instruction shifts the target reg/mem as usual, but instead of 8954;; shifting in zeros, bits are shifted in from reg operand. If the insn 8955;; is a left shift double, bits are taken from the high order bits of 8956;; reg, else if the insn is a shift right double, bits are taken from the 8957;; low order bits of reg. So if %eax is "1234" and %edx is "5678", 8958;; "shldl $8,%edx,%eax" leaves %edx unchanged and sets %eax to "2345". 8959;; 8960;; Since sh[lr]d does not change the `reg' operand, that is done 8961;; separately, making all shifts emit pairs of shift double and normal 8962;; shift. Since sh[lr]d does not shift more than 31 bits, and we wish to 8963;; support a 63 bit shift, each shift where the count is in a reg expands 8964;; to a pair of shifts, a branch, a shift by 32 and a label. 8965;; 8966;; If the shift count is a constant, we need never emit more than one 8967;; shift pair, instead using moves and sign extension for counts greater 8968;; than 31. 8969 8970(define_expand "ashl<mode>3" 8971 [(set (match_operand:SDWIM 0 "<shift_operand>" "") 8972 (ashift:SDWIM (match_operand:SDWIM 1 "<ashl_input_operand>" "") 8973 (match_operand:QI 2 "nonmemory_operand" "")))] 8974 "" 8975 "ix86_expand_binary_operator (ASHIFT, <MODE>mode, operands); DONE;") 8976 8977(define_insn "*ashl<mode>3_doubleword" 8978 [(set (match_operand:DWI 0 "register_operand" "=&r,r") 8979 (ashift:DWI (match_operand:DWI 1 "reg_or_pm1_operand" "n,0") 8980 (match_operand:QI 2 "nonmemory_operand" "<S>c,<S>c"))) 8981 (clobber (reg:CC FLAGS_REG))] 8982 "" 8983 "#" 8984 [(set_attr "type" "multi")]) 8985 8986(define_split 8987 [(set (match_operand:DWI 0 "register_operand" "") 8988 (ashift:DWI (match_operand:DWI 1 "nonmemory_operand" "") 8989 (match_operand:QI 2 "nonmemory_operand" ""))) 8990 (clobber (reg:CC FLAGS_REG))] 8991 "(optimize && flag_peephole2) ? epilogue_completed : reload_completed" 8992 [(const_int 0)] 8993 "ix86_split_ashl (operands, NULL_RTX, <MODE>mode); DONE;") 8994 8995;; By default we don't ask for a scratch register, because when DWImode 8996;; values are manipulated, registers are already at a premium. But if 8997;; we have one handy, we won't turn it away. 8998 8999(define_peephole2 9000 [(match_scratch:DWIH 3 "r") 9001 (parallel [(set (match_operand:<DWI> 0 "register_operand" "") 9002 (ashift:<DWI> 9003 (match_operand:<DWI> 1 "nonmemory_operand" "") 9004 (match_operand:QI 2 "nonmemory_operand" ""))) 9005 (clobber (reg:CC FLAGS_REG))]) 9006 (match_dup 3)] 9007 "TARGET_CMOVE" 9008 [(const_int 0)] 9009 "ix86_split_ashl (operands, operands[3], <DWI>mode); DONE;") 9010 9011(define_insn "x86_64_shld" 9012 [(set (match_operand:DI 0 "nonimmediate_operand" "+r*m") 9013 (ior:DI (ashift:DI (match_dup 0) 9014 (match_operand:QI 2 "nonmemory_operand" "Jc")) 9015 (lshiftrt:DI (match_operand:DI 1 "register_operand" "r") 9016 (minus:QI (const_int 64) (match_dup 2))))) 9017 (clobber (reg:CC FLAGS_REG))] 9018 "TARGET_64BIT" 9019 "shld{q}\t{%s2%1, %0|%0, %1, %2}" 9020 [(set_attr "type" "ishift") 9021 (set_attr "prefix_0f" "1") 9022 (set_attr "mode" "DI") 9023 (set_attr "athlon_decode" "vector") 9024 (set_attr "amdfam10_decode" "vector") 9025 (set_attr "bdver1_decode" "vector")]) 9026 9027(define_insn "x86_shld" 9028 [(set (match_operand:SI 0 "nonimmediate_operand" "+r*m") 9029 (ior:SI (ashift:SI (match_dup 0) 9030 (match_operand:QI 2 "nonmemory_operand" "Ic")) 9031 (lshiftrt:SI (match_operand:SI 1 "register_operand" "r") 9032 (minus:QI (const_int 32) (match_dup 2))))) 9033 (clobber (reg:CC FLAGS_REG))] 9034 "" 9035 "shld{l}\t{%s2%1, %0|%0, %1, %2}" 9036 [(set_attr "type" "ishift") 9037 (set_attr "prefix_0f" "1") 9038 (set_attr "mode" "SI") 9039 (set_attr "pent_pair" "np") 9040 (set_attr "athlon_decode" "vector") 9041 (set_attr "amdfam10_decode" "vector") 9042 (set_attr "bdver1_decode" "vector")]) 9043 9044(define_expand "x86_shift<mode>_adj_1" 9045 [(set (reg:CCZ FLAGS_REG) 9046 (compare:CCZ (and:QI (match_operand:QI 2 "register_operand" "") 9047 (match_dup 4)) 9048 (const_int 0))) 9049 (set (match_operand:SWI48 0 "register_operand" "") 9050 (if_then_else:SWI48 (ne (reg:CCZ FLAGS_REG) (const_int 0)) 9051 (match_operand:SWI48 1 "register_operand" "") 9052 (match_dup 0))) 9053 (set (match_dup 1) 9054 (if_then_else:SWI48 (ne (reg:CCZ FLAGS_REG) (const_int 0)) 9055 (match_operand:SWI48 3 "register_operand" "") 9056 (match_dup 1)))] 9057 "TARGET_CMOVE" 9058 "operands[4] = GEN_INT (GET_MODE_BITSIZE (<MODE>mode));") 9059 9060(define_expand "x86_shift<mode>_adj_2" 9061 [(use (match_operand:SWI48 0 "register_operand" "")) 9062 (use (match_operand:SWI48 1 "register_operand" "")) 9063 (use (match_operand:QI 2 "register_operand" ""))] 9064 "" 9065{ 9066 rtx label = gen_label_rtx (); 9067 rtx tmp; 9068 9069 emit_insn (gen_testqi_ccz_1 (operands[2], 9070 GEN_INT (GET_MODE_BITSIZE (<MODE>mode)))); 9071 9072 tmp = gen_rtx_REG (CCZmode, FLAGS_REG); 9073 tmp = gen_rtx_EQ (VOIDmode, tmp, const0_rtx); 9074 tmp = gen_rtx_IF_THEN_ELSE (VOIDmode, tmp, 9075 gen_rtx_LABEL_REF (VOIDmode, label), 9076 pc_rtx); 9077 tmp = emit_jump_insn (gen_rtx_SET (VOIDmode, pc_rtx, tmp)); 9078 JUMP_LABEL (tmp) = label; 9079 9080 emit_move_insn (operands[0], operands[1]); 9081 ix86_expand_clear (operands[1]); 9082 9083 emit_label (label); 9084 LABEL_NUSES (label) = 1; 9085 9086 DONE; 9087}) 9088 9089;; Avoid useless masking of count operand. 9090(define_insn "*ashl<mode>3_mask" 9091 [(set (match_operand:SWI48 0 "nonimmediate_operand" "=rm") 9092 (ashift:SWI48 9093 (match_operand:SWI48 1 "nonimmediate_operand" "0") 9094 (subreg:QI 9095 (and:SI 9096 (match_operand:SI 2 "register_operand" "c") 9097 (match_operand:SI 3 "const_int_operand" "n")) 0))) 9098 (clobber (reg:CC FLAGS_REG))] 9099 "ix86_binary_operator_ok (ASHIFT, <MODE>mode, operands) 9100 && (INTVAL (operands[3]) & (GET_MODE_BITSIZE (<MODE>mode)-1)) 9101 == GET_MODE_BITSIZE (<MODE>mode)-1" 9102{ 9103 return "sal{<imodesuffix>}\t{%b2, %0|%0, %b2}"; 9104} 9105 [(set_attr "type" "ishift") 9106 (set_attr "mode" "<MODE>")]) 9107 9108(define_insn "*bmi2_ashl<mode>3_1" 9109 [(set (match_operand:SWI48 0 "register_operand" "=r") 9110 (ashift:SWI48 (match_operand:SWI48 1 "nonimmediate_operand" "rm") 9111 (match_operand:SWI48 2 "register_operand" "r")))] 9112 "TARGET_BMI2" 9113 "shlx\t{%2, %1, %0|%0, %1, %2}" 9114 [(set_attr "type" "ishiftx") 9115 (set_attr "mode" "<MODE>")]) 9116 9117(define_insn "*ashl<mode>3_1" 9118 [(set (match_operand:SWI48 0 "nonimmediate_operand" "=rm,r,r") 9119 (ashift:SWI48 (match_operand:SWI48 1 "nonimmediate_operand" "0,l,rm") 9120 (match_operand:QI 2 "nonmemory_operand" "c<S>,M,r"))) 9121 (clobber (reg:CC FLAGS_REG))] 9122 "ix86_binary_operator_ok (ASHIFT, <MODE>mode, operands)" 9123{ 9124 switch (get_attr_type (insn)) 9125 { 9126 case TYPE_LEA: 9127 case TYPE_ISHIFTX: 9128 return "#"; 9129 9130 case TYPE_ALU: 9131 gcc_assert (operands[2] == const1_rtx); 9132 gcc_assert (rtx_equal_p (operands[0], operands[1])); 9133 return "add{<imodesuffix>}\t%0, %0"; 9134 9135 default: 9136 if (operands[2] == const1_rtx 9137 && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun))) 9138 return "sal{<imodesuffix>}\t%0"; 9139 else 9140 return "sal{<imodesuffix>}\t{%2, %0|%0, %2}"; 9141 } 9142} 9143 [(set_attr "isa" "*,*,bmi2") 9144 (set (attr "type") 9145 (cond [(eq_attr "alternative" "1") 9146 (const_string "lea") 9147 (eq_attr "alternative" "2") 9148 (const_string "ishiftx") 9149 (and (and (match_test "TARGET_DOUBLE_WITH_ADD") 9150 (match_operand 0 "register_operand" "")) 9151 (match_operand 2 "const1_operand" "")) 9152 (const_string "alu") 9153 ] 9154 (const_string "ishift"))) 9155 (set (attr "length_immediate") 9156 (if_then_else 9157 (ior (eq_attr "type" "alu") 9158 (and (eq_attr "type" "ishift") 9159 (and (match_operand 2 "const1_operand" "") 9160 (ior (match_test "TARGET_SHIFT1") 9161 (match_test "optimize_function_for_size_p (cfun)"))))) 9162 (const_string "0") 9163 (const_string "*"))) 9164 (set_attr "mode" "<MODE>")]) 9165 9166;; Convert shift to the shiftx pattern to avoid flags dependency. 9167(define_split 9168 [(set (match_operand:SWI48 0 "register_operand" "") 9169 (ashift:SWI48 (match_operand:SWI48 1 "nonimmediate_operand" "") 9170 (match_operand:QI 2 "register_operand" ""))) 9171 (clobber (reg:CC FLAGS_REG))] 9172 "TARGET_BMI2 && reload_completed" 9173 [(set (match_dup 0) 9174 (ashift:SWI48 (match_dup 1) (match_dup 2)))] 9175 "operands[2] = gen_lowpart (<MODE>mode, operands[2]);") 9176 9177(define_insn "*bmi2_ashlsi3_1_zext" 9178 [(set (match_operand:DI 0 "register_operand" "=r") 9179 (zero_extend:DI 9180 (ashift:SI (match_operand:SI 1 "nonimmediate_operand" "rm") 9181 (match_operand:SI 2 "register_operand" "r"))))] 9182 "TARGET_64BIT && TARGET_BMI2" 9183 "shlx\t{%2, %1, %k0|%k0, %1, %2}" 9184 [(set_attr "type" "ishiftx") 9185 (set_attr "mode" "SI")]) 9186 9187(define_insn "*ashlsi3_1_zext" 9188 [(set (match_operand:DI 0 "register_operand" "=r,r,r") 9189 (zero_extend:DI 9190 (ashift:SI (match_operand:SI 1 "nonimmediate_operand" "0,l,rm") 9191 (match_operand:QI 2 "nonmemory_operand" "cI,M,r")))) 9192 (clobber (reg:CC FLAGS_REG))] 9193 "TARGET_64BIT && ix86_binary_operator_ok (ASHIFT, SImode, operands)" 9194{ 9195 switch (get_attr_type (insn)) 9196 { 9197 case TYPE_LEA: 9198 case TYPE_ISHIFTX: 9199 return "#"; 9200 9201 case TYPE_ALU: 9202 gcc_assert (operands[2] == const1_rtx); 9203 return "add{l}\t%k0, %k0"; 9204 9205 default: 9206 if (operands[2] == const1_rtx 9207 && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun))) 9208 return "sal{l}\t%k0"; 9209 else 9210 return "sal{l}\t{%2, %k0|%k0, %2}"; 9211 } 9212} 9213 [(set_attr "isa" "*,*,bmi2") 9214 (set (attr "type") 9215 (cond [(eq_attr "alternative" "1") 9216 (const_string "lea") 9217 (eq_attr "alternative" "2") 9218 (const_string "ishiftx") 9219 (and (match_test "TARGET_DOUBLE_WITH_ADD") 9220 (match_operand 2 "const1_operand" "")) 9221 (const_string "alu") 9222 ] 9223 (const_string "ishift"))) 9224 (set (attr "length_immediate") 9225 (if_then_else 9226 (ior (eq_attr "type" "alu") 9227 (and (eq_attr "type" "ishift") 9228 (and (match_operand 2 "const1_operand" "") 9229 (ior (match_test "TARGET_SHIFT1") 9230 (match_test "optimize_function_for_size_p (cfun)"))))) 9231 (const_string "0") 9232 (const_string "*"))) 9233 (set_attr "mode" "SI")]) 9234 9235;; Convert shift to the shiftx pattern to avoid flags dependency. 9236(define_split 9237 [(set (match_operand:DI 0 "register_operand" "") 9238 (zero_extend:DI 9239 (ashift:SI (match_operand:SI 1 "nonimmediate_operand" "") 9240 (match_operand:QI 2 "register_operand" "")))) 9241 (clobber (reg:CC FLAGS_REG))] 9242 "TARGET_64BIT && TARGET_BMI2 && reload_completed" 9243 [(set (match_dup 0) 9244 (zero_extend:DI (ashift:SI (match_dup 1) (match_dup 2))))] 9245 "operands[2] = gen_lowpart (SImode, operands[2]);") 9246 9247(define_insn "*ashlhi3_1" 9248 [(set (match_operand:HI 0 "nonimmediate_operand" "=rm,Yp") 9249 (ashift:HI (match_operand:HI 1 "nonimmediate_operand" "0,l") 9250 (match_operand:QI 2 "nonmemory_operand" "cI,M"))) 9251 (clobber (reg:CC FLAGS_REG))] 9252 "ix86_binary_operator_ok (ASHIFT, HImode, operands)" 9253{ 9254 switch (get_attr_type (insn)) 9255 { 9256 case TYPE_LEA: 9257 return "#"; 9258 9259 case TYPE_ALU: 9260 gcc_assert (operands[2] == const1_rtx); 9261 return "add{w}\t%0, %0"; 9262 9263 default: 9264 if (operands[2] == const1_rtx 9265 && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun))) 9266 return "sal{w}\t%0"; 9267 else 9268 return "sal{w}\t{%2, %0|%0, %2}"; 9269 } 9270} 9271 [(set (attr "type") 9272 (cond [(eq_attr "alternative" "1") 9273 (const_string "lea") 9274 (and (and (match_test "TARGET_DOUBLE_WITH_ADD") 9275 (match_operand 0 "register_operand" "")) 9276 (match_operand 2 "const1_operand" "")) 9277 (const_string "alu") 9278 ] 9279 (const_string "ishift"))) 9280 (set (attr "length_immediate") 9281 (if_then_else 9282 (ior (eq_attr "type" "alu") 9283 (and (eq_attr "type" "ishift") 9284 (and (match_operand 2 "const1_operand" "") 9285 (ior (match_test "TARGET_SHIFT1") 9286 (match_test "optimize_function_for_size_p (cfun)"))))) 9287 (const_string "0") 9288 (const_string "*"))) 9289 (set_attr "mode" "HI,SI")]) 9290 9291;; %%% Potential partial reg stall on alternative 1. What to do? 9292(define_insn "*ashlqi3_1" 9293 [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,r,Yp") 9294 (ashift:QI (match_operand:QI 1 "nonimmediate_operand" "0,0,l") 9295 (match_operand:QI 2 "nonmemory_operand" "cI,cI,M"))) 9296 (clobber (reg:CC FLAGS_REG))] 9297 "ix86_binary_operator_ok (ASHIFT, QImode, operands)" 9298{ 9299 switch (get_attr_type (insn)) 9300 { 9301 case TYPE_LEA: 9302 return "#"; 9303 9304 case TYPE_ALU: 9305 gcc_assert (operands[2] == const1_rtx); 9306 if (REG_P (operands[1]) && !ANY_QI_REG_P (operands[1])) 9307 return "add{l}\t%k0, %k0"; 9308 else 9309 return "add{b}\t%0, %0"; 9310 9311 default: 9312 if (operands[2] == const1_rtx 9313 && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun))) 9314 { 9315 if (get_attr_mode (insn) == MODE_SI) 9316 return "sal{l}\t%k0"; 9317 else 9318 return "sal{b}\t%0"; 9319 } 9320 else 9321 { 9322 if (get_attr_mode (insn) == MODE_SI) 9323 return "sal{l}\t{%2, %k0|%k0, %2}"; 9324 else 9325 return "sal{b}\t{%2, %0|%0, %2}"; 9326 } 9327 } 9328} 9329 [(set (attr "type") 9330 (cond [(eq_attr "alternative" "2") 9331 (const_string "lea") 9332 (and (and (match_test "TARGET_DOUBLE_WITH_ADD") 9333 (match_operand 0 "register_operand" "")) 9334 (match_operand 2 "const1_operand" "")) 9335 (const_string "alu") 9336 ] 9337 (const_string "ishift"))) 9338 (set (attr "length_immediate") 9339 (if_then_else 9340 (ior (eq_attr "type" "alu") 9341 (and (eq_attr "type" "ishift") 9342 (and (match_operand 2 "const1_operand" "") 9343 (ior (match_test "TARGET_SHIFT1") 9344 (match_test "optimize_function_for_size_p (cfun)"))))) 9345 (const_string "0") 9346 (const_string "*"))) 9347 (set_attr "mode" "QI,SI,SI")]) 9348 9349(define_insn "*ashlqi3_1_slp" 9350 [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm")) 9351 (ashift:QI (match_dup 0) 9352 (match_operand:QI 1 "nonmemory_operand" "cI"))) 9353 (clobber (reg:CC FLAGS_REG))] 9354 "(optimize_function_for_size_p (cfun) 9355 || !TARGET_PARTIAL_FLAG_REG_STALL 9356 || (operands[1] == const1_rtx 9357 && (TARGET_SHIFT1 9358 || (TARGET_DOUBLE_WITH_ADD && REG_P (operands[0])))))" 9359{ 9360 switch (get_attr_type (insn)) 9361 { 9362 case TYPE_ALU: 9363 gcc_assert (operands[1] == const1_rtx); 9364 return "add{b}\t%0, %0"; 9365 9366 default: 9367 if (operands[1] == const1_rtx 9368 && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun))) 9369 return "sal{b}\t%0"; 9370 else 9371 return "sal{b}\t{%1, %0|%0, %1}"; 9372 } 9373} 9374 [(set (attr "type") 9375 (cond [(and (and (match_test "TARGET_DOUBLE_WITH_ADD") 9376 (match_operand 0 "register_operand" "")) 9377 (match_operand 1 "const1_operand" "")) 9378 (const_string "alu") 9379 ] 9380 (const_string "ishift1"))) 9381 (set (attr "length_immediate") 9382 (if_then_else 9383 (ior (eq_attr "type" "alu") 9384 (and (eq_attr "type" "ishift1") 9385 (and (match_operand 1 "const1_operand" "") 9386 (ior (match_test "TARGET_SHIFT1") 9387 (match_test "optimize_function_for_size_p (cfun)"))))) 9388 (const_string "0") 9389 (const_string "*"))) 9390 (set_attr "mode" "QI")]) 9391 9392;; Convert ashift to the lea pattern to avoid flags dependency. 9393(define_split 9394 [(set (match_operand 0 "register_operand" "") 9395 (ashift (match_operand 1 "index_register_operand" "") 9396 (match_operand:QI 2 "const_int_operand" ""))) 9397 (clobber (reg:CC FLAGS_REG))] 9398 "GET_MODE (operands[0]) == GET_MODE (operands[1]) 9399 && reload_completed 9400 && true_regnum (operands[0]) != true_regnum (operands[1])" 9401 [(const_int 0)] 9402{ 9403 enum machine_mode mode = GET_MODE (operands[0]); 9404 rtx pat; 9405 9406 if (GET_MODE_SIZE (mode) < GET_MODE_SIZE (SImode)) 9407 { 9408 mode = SImode; 9409 operands[0] = gen_lowpart (mode, operands[0]); 9410 operands[1] = gen_lowpart (mode, operands[1]); 9411 } 9412 9413 operands[2] = gen_int_mode (1 << INTVAL (operands[2]), mode); 9414 9415 pat = gen_rtx_MULT (mode, operands[1], operands[2]); 9416 9417 emit_insn (gen_rtx_SET (VOIDmode, operands[0], pat)); 9418 DONE; 9419}) 9420 9421;; Convert ashift to the lea pattern to avoid flags dependency. 9422(define_split 9423 [(set (match_operand:DI 0 "register_operand" "") 9424 (zero_extend:DI 9425 (ashift:SI (match_operand:SI 1 "index_register_operand" "") 9426 (match_operand:QI 2 "const_int_operand" "")))) 9427 (clobber (reg:CC FLAGS_REG))] 9428 "TARGET_64BIT && reload_completed 9429 && true_regnum (operands[0]) != true_regnum (operands[1])" 9430 [(set (match_dup 0) 9431 (zero_extend:DI (subreg:SI (mult:DI (match_dup 1) (match_dup 2)) 0)))] 9432{ 9433 operands[1] = gen_lowpart (DImode, operands[1]); 9434 operands[2] = gen_int_mode (1 << INTVAL (operands[2]), DImode); 9435}) 9436 9437;; This pattern can't accept a variable shift count, since shifts by 9438;; zero don't affect the flags. We assume that shifts by constant 9439;; zero are optimized away. 9440(define_insn "*ashl<mode>3_cmp" 9441 [(set (reg FLAGS_REG) 9442 (compare 9443 (ashift:SWI (match_operand:SWI 1 "nonimmediate_operand" "0") 9444 (match_operand:QI 2 "<shift_immediate_operand>" "<S>")) 9445 (const_int 0))) 9446 (set (match_operand:SWI 0 "nonimmediate_operand" "=<r>m") 9447 (ashift:SWI (match_dup 1) (match_dup 2)))] 9448 "(optimize_function_for_size_p (cfun) 9449 || !TARGET_PARTIAL_FLAG_REG_STALL 9450 || (operands[2] == const1_rtx 9451 && (TARGET_SHIFT1 9452 || (TARGET_DOUBLE_WITH_ADD && REG_P (operands[0]))))) 9453 && ix86_match_ccmode (insn, CCGOCmode) 9454 && ix86_binary_operator_ok (ASHIFT, <MODE>mode, operands)" 9455{ 9456 switch (get_attr_type (insn)) 9457 { 9458 case TYPE_ALU: 9459 gcc_assert (operands[2] == const1_rtx); 9460 return "add{<imodesuffix>}\t%0, %0"; 9461 9462 default: 9463 if (operands[2] == const1_rtx 9464 && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun))) 9465 return "sal{<imodesuffix>}\t%0"; 9466 else 9467 return "sal{<imodesuffix>}\t{%2, %0|%0, %2}"; 9468 } 9469} 9470 [(set (attr "type") 9471 (cond [(and (and (match_test "TARGET_DOUBLE_WITH_ADD") 9472 (match_operand 0 "register_operand" "")) 9473 (match_operand 2 "const1_operand" "")) 9474 (const_string "alu") 9475 ] 9476 (const_string "ishift"))) 9477 (set (attr "length_immediate") 9478 (if_then_else 9479 (ior (eq_attr "type" "alu") 9480 (and (eq_attr "type" "ishift") 9481 (and (match_operand 2 "const1_operand" "") 9482 (ior (match_test "TARGET_SHIFT1") 9483 (match_test "optimize_function_for_size_p (cfun)"))))) 9484 (const_string "0") 9485 (const_string "*"))) 9486 (set_attr "mode" "<MODE>")]) 9487 9488(define_insn "*ashlsi3_cmp_zext" 9489 [(set (reg FLAGS_REG) 9490 (compare 9491 (ashift:SI (match_operand:SI 1 "register_operand" "0") 9492 (match_operand:QI 2 "const_1_to_31_operand" "I")) 9493 (const_int 0))) 9494 (set (match_operand:DI 0 "register_operand" "=r") 9495 (zero_extend:DI (ashift:SI (match_dup 1) (match_dup 2))))] 9496 "TARGET_64BIT 9497 && (optimize_function_for_size_p (cfun) 9498 || !TARGET_PARTIAL_FLAG_REG_STALL 9499 || (operands[2] == const1_rtx 9500 && (TARGET_SHIFT1 9501 || TARGET_DOUBLE_WITH_ADD))) 9502 && ix86_match_ccmode (insn, CCGOCmode) 9503 && ix86_binary_operator_ok (ASHIFT, SImode, operands)" 9504{ 9505 switch (get_attr_type (insn)) 9506 { 9507 case TYPE_ALU: 9508 gcc_assert (operands[2] == const1_rtx); 9509 return "add{l}\t%k0, %k0"; 9510 9511 default: 9512 if (operands[2] == const1_rtx 9513 && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun))) 9514 return "sal{l}\t%k0"; 9515 else 9516 return "sal{l}\t{%2, %k0|%k0, %2}"; 9517 } 9518} 9519 [(set (attr "type") 9520 (cond [(and (match_test "TARGET_DOUBLE_WITH_ADD") 9521 (match_operand 2 "const1_operand" "")) 9522 (const_string "alu") 9523 ] 9524 (const_string "ishift"))) 9525 (set (attr "length_immediate") 9526 (if_then_else 9527 (ior (eq_attr "type" "alu") 9528 (and (eq_attr "type" "ishift") 9529 (and (match_operand 2 "const1_operand" "") 9530 (ior (match_test "TARGET_SHIFT1") 9531 (match_test "optimize_function_for_size_p (cfun)"))))) 9532 (const_string "0") 9533 (const_string "*"))) 9534 (set_attr "mode" "SI")]) 9535 9536(define_insn "*ashl<mode>3_cconly" 9537 [(set (reg FLAGS_REG) 9538 (compare 9539 (ashift:SWI (match_operand:SWI 1 "register_operand" "0") 9540 (match_operand:QI 2 "<shift_immediate_operand>" "<S>")) 9541 (const_int 0))) 9542 (clobber (match_scratch:SWI 0 "=<r>"))] 9543 "(optimize_function_for_size_p (cfun) 9544 || !TARGET_PARTIAL_FLAG_REG_STALL 9545 || (operands[2] == const1_rtx 9546 && (TARGET_SHIFT1 9547 || TARGET_DOUBLE_WITH_ADD))) 9548 && ix86_match_ccmode (insn, CCGOCmode)" 9549{ 9550 switch (get_attr_type (insn)) 9551 { 9552 case TYPE_ALU: 9553 gcc_assert (operands[2] == const1_rtx); 9554 return "add{<imodesuffix>}\t%0, %0"; 9555 9556 default: 9557 if (operands[2] == const1_rtx 9558 && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun))) 9559 return "sal{<imodesuffix>}\t%0"; 9560 else 9561 return "sal{<imodesuffix>}\t{%2, %0|%0, %2}"; 9562 } 9563} 9564 [(set (attr "type") 9565 (cond [(and (and (match_test "TARGET_DOUBLE_WITH_ADD") 9566 (match_operand 0 "register_operand" "")) 9567 (match_operand 2 "const1_operand" "")) 9568 (const_string "alu") 9569 ] 9570 (const_string "ishift"))) 9571 (set (attr "length_immediate") 9572 (if_then_else 9573 (ior (eq_attr "type" "alu") 9574 (and (eq_attr "type" "ishift") 9575 (and (match_operand 2 "const1_operand" "") 9576 (ior (match_test "TARGET_SHIFT1") 9577 (match_test "optimize_function_for_size_p (cfun)"))))) 9578 (const_string "0") 9579 (const_string "*"))) 9580 (set_attr "mode" "<MODE>")]) 9581 9582;; See comment above `ashl<mode>3' about how this works. 9583 9584(define_expand "<shift_insn><mode>3" 9585 [(set (match_operand:SDWIM 0 "<shift_operand>" "") 9586 (any_shiftrt:SDWIM (match_operand:SDWIM 1 "<shift_operand>" "") 9587 (match_operand:QI 2 "nonmemory_operand" "")))] 9588 "" 9589 "ix86_expand_binary_operator (<CODE>, <MODE>mode, operands); DONE;") 9590 9591;; Avoid useless masking of count operand. 9592(define_insn "*<shift_insn><mode>3_mask" 9593 [(set (match_operand:SWI48 0 "nonimmediate_operand" "=rm") 9594 (any_shiftrt:SWI48 9595 (match_operand:SWI48 1 "nonimmediate_operand" "0") 9596 (subreg:QI 9597 (and:SI 9598 (match_operand:SI 2 "register_operand" "c") 9599 (match_operand:SI 3 "const_int_operand" "n")) 0))) 9600 (clobber (reg:CC FLAGS_REG))] 9601 "ix86_binary_operator_ok (<CODE>, <MODE>mode, operands) 9602 && (INTVAL (operands[3]) & (GET_MODE_BITSIZE (<MODE>mode)-1)) 9603 == GET_MODE_BITSIZE (<MODE>mode)-1" 9604{ 9605 return "<shift>{<imodesuffix>}\t{%b2, %0|%0, %b2}"; 9606} 9607 [(set_attr "type" "ishift") 9608 (set_attr "mode" "<MODE>")]) 9609 9610(define_insn_and_split "*<shift_insn><mode>3_doubleword" 9611 [(set (match_operand:DWI 0 "register_operand" "=r") 9612 (any_shiftrt:DWI (match_operand:DWI 1 "register_operand" "0") 9613 (match_operand:QI 2 "nonmemory_operand" "<S>c"))) 9614 (clobber (reg:CC FLAGS_REG))] 9615 "" 9616 "#" 9617 "(optimize && flag_peephole2) ? epilogue_completed : reload_completed" 9618 [(const_int 0)] 9619 "ix86_split_<shift_insn> (operands, NULL_RTX, <MODE>mode); DONE;" 9620 [(set_attr "type" "multi")]) 9621 9622;; By default we don't ask for a scratch register, because when DWImode 9623;; values are manipulated, registers are already at a premium. But if 9624;; we have one handy, we won't turn it away. 9625 9626(define_peephole2 9627 [(match_scratch:DWIH 3 "r") 9628 (parallel [(set (match_operand:<DWI> 0 "register_operand" "") 9629 (any_shiftrt:<DWI> 9630 (match_operand:<DWI> 1 "register_operand" "") 9631 (match_operand:QI 2 "nonmemory_operand" ""))) 9632 (clobber (reg:CC FLAGS_REG))]) 9633 (match_dup 3)] 9634 "TARGET_CMOVE" 9635 [(const_int 0)] 9636 "ix86_split_<shift_insn> (operands, operands[3], <DWI>mode); DONE;") 9637 9638(define_insn "x86_64_shrd" 9639 [(set (match_operand:DI 0 "nonimmediate_operand" "+r*m") 9640 (ior:DI (ashiftrt:DI (match_dup 0) 9641 (match_operand:QI 2 "nonmemory_operand" "Jc")) 9642 (ashift:DI (match_operand:DI 1 "register_operand" "r") 9643 (minus:QI (const_int 64) (match_dup 2))))) 9644 (clobber (reg:CC FLAGS_REG))] 9645 "TARGET_64BIT" 9646 "shrd{q}\t{%s2%1, %0|%0, %1, %2}" 9647 [(set_attr "type" "ishift") 9648 (set_attr "prefix_0f" "1") 9649 (set_attr "mode" "DI") 9650 (set_attr "athlon_decode" "vector") 9651 (set_attr "amdfam10_decode" "vector") 9652 (set_attr "bdver1_decode" "vector")]) 9653 9654(define_insn "x86_shrd" 9655 [(set (match_operand:SI 0 "nonimmediate_operand" "+r*m") 9656 (ior:SI (ashiftrt:SI (match_dup 0) 9657 (match_operand:QI 2 "nonmemory_operand" "Ic")) 9658 (ashift:SI (match_operand:SI 1 "register_operand" "r") 9659 (minus:QI (const_int 32) (match_dup 2))))) 9660 (clobber (reg:CC FLAGS_REG))] 9661 "" 9662 "shrd{l}\t{%s2%1, %0|%0, %1, %2}" 9663 [(set_attr "type" "ishift") 9664 (set_attr "prefix_0f" "1") 9665 (set_attr "mode" "SI") 9666 (set_attr "pent_pair" "np") 9667 (set_attr "athlon_decode" "vector") 9668 (set_attr "amdfam10_decode" "vector") 9669 (set_attr "bdver1_decode" "vector")]) 9670 9671(define_insn "ashrdi3_cvt" 9672 [(set (match_operand:DI 0 "nonimmediate_operand" "=*d,rm") 9673 (ashiftrt:DI (match_operand:DI 1 "nonimmediate_operand" "*a,0") 9674 (match_operand:QI 2 "const_int_operand" ""))) 9675 (clobber (reg:CC FLAGS_REG))] 9676 "TARGET_64BIT && INTVAL (operands[2]) == 63 9677 && (TARGET_USE_CLTD || optimize_function_for_size_p (cfun)) 9678 && ix86_binary_operator_ok (ASHIFTRT, DImode, operands)" 9679 "@ 9680 {cqto|cqo} 9681 sar{q}\t{%2, %0|%0, %2}" 9682 [(set_attr "type" "imovx,ishift") 9683 (set_attr "prefix_0f" "0,*") 9684 (set_attr "length_immediate" "0,*") 9685 (set_attr "modrm" "0,1") 9686 (set_attr "mode" "DI")]) 9687 9688(define_insn "ashrsi3_cvt" 9689 [(set (match_operand:SI 0 "nonimmediate_operand" "=*d,rm") 9690 (ashiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "*a,0") 9691 (match_operand:QI 2 "const_int_operand" ""))) 9692 (clobber (reg:CC FLAGS_REG))] 9693 "INTVAL (operands[2]) == 31 9694 && (TARGET_USE_CLTD || optimize_function_for_size_p (cfun)) 9695 && ix86_binary_operator_ok (ASHIFTRT, SImode, operands)" 9696 "@ 9697 {cltd|cdq} 9698 sar{l}\t{%2, %0|%0, %2}" 9699 [(set_attr "type" "imovx,ishift") 9700 (set_attr "prefix_0f" "0,*") 9701 (set_attr "length_immediate" "0,*") 9702 (set_attr "modrm" "0,1") 9703 (set_attr "mode" "SI")]) 9704 9705(define_insn "*ashrsi3_cvt_zext" 9706 [(set (match_operand:DI 0 "register_operand" "=*d,r") 9707 (zero_extend:DI 9708 (ashiftrt:SI (match_operand:SI 1 "register_operand" "*a,0") 9709 (match_operand:QI 2 "const_int_operand" "")))) 9710 (clobber (reg:CC FLAGS_REG))] 9711 "TARGET_64BIT && INTVAL (operands[2]) == 31 9712 && (TARGET_USE_CLTD || optimize_function_for_size_p (cfun)) 9713 && ix86_binary_operator_ok (ASHIFTRT, SImode, operands)" 9714 "@ 9715 {cltd|cdq} 9716 sar{l}\t{%2, %k0|%k0, %2}" 9717 [(set_attr "type" "imovx,ishift") 9718 (set_attr "prefix_0f" "0,*") 9719 (set_attr "length_immediate" "0,*") 9720 (set_attr "modrm" "0,1") 9721 (set_attr "mode" "SI")]) 9722 9723(define_expand "x86_shift<mode>_adj_3" 9724 [(use (match_operand:SWI48 0 "register_operand" "")) 9725 (use (match_operand:SWI48 1 "register_operand" "")) 9726 (use (match_operand:QI 2 "register_operand" ""))] 9727 "" 9728{ 9729 rtx label = gen_label_rtx (); 9730 rtx tmp; 9731 9732 emit_insn (gen_testqi_ccz_1 (operands[2], 9733 GEN_INT (GET_MODE_BITSIZE (<MODE>mode)))); 9734 9735 tmp = gen_rtx_REG (CCZmode, FLAGS_REG); 9736 tmp = gen_rtx_EQ (VOIDmode, tmp, const0_rtx); 9737 tmp = gen_rtx_IF_THEN_ELSE (VOIDmode, tmp, 9738 gen_rtx_LABEL_REF (VOIDmode, label), 9739 pc_rtx); 9740 tmp = emit_jump_insn (gen_rtx_SET (VOIDmode, pc_rtx, tmp)); 9741 JUMP_LABEL (tmp) = label; 9742 9743 emit_move_insn (operands[0], operands[1]); 9744 emit_insn (gen_ashr<mode>3_cvt (operands[1], operands[1], 9745 GEN_INT (GET_MODE_BITSIZE (<MODE>mode)-1))); 9746 emit_label (label); 9747 LABEL_NUSES (label) = 1; 9748 9749 DONE; 9750}) 9751 9752(define_insn "*bmi2_<shift_insn><mode>3_1" 9753 [(set (match_operand:SWI48 0 "register_operand" "=r") 9754 (any_shiftrt:SWI48 (match_operand:SWI48 1 "nonimmediate_operand" "rm") 9755 (match_operand:SWI48 2 "register_operand" "r")))] 9756 "TARGET_BMI2" 9757 "<shift>x\t{%2, %1, %0|%0, %1, %2}" 9758 [(set_attr "type" "ishiftx") 9759 (set_attr "mode" "<MODE>")]) 9760 9761(define_insn "*<shift_insn><mode>3_1" 9762 [(set (match_operand:SWI48 0 "nonimmediate_operand" "=rm,r") 9763 (any_shiftrt:SWI48 9764 (match_operand:SWI48 1 "nonimmediate_operand" "0,rm") 9765 (match_operand:QI 2 "nonmemory_operand" "c<S>,r"))) 9766 (clobber (reg:CC FLAGS_REG))] 9767 "ix86_binary_operator_ok (<CODE>, <MODE>mode, operands)" 9768{ 9769 switch (get_attr_type (insn)) 9770 { 9771 case TYPE_ISHIFTX: 9772 return "#"; 9773 9774 default: 9775 if (operands[2] == const1_rtx 9776 && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun))) 9777 return "<shift>{<imodesuffix>}\t%0"; 9778 else 9779 return "<shift>{<imodesuffix>}\t{%2, %0|%0, %2}"; 9780 } 9781} 9782 [(set_attr "isa" "*,bmi2") 9783 (set_attr "type" "ishift,ishiftx") 9784 (set (attr "length_immediate") 9785 (if_then_else 9786 (and (match_operand 2 "const1_operand" "") 9787 (ior (match_test "TARGET_SHIFT1") 9788 (match_test "optimize_function_for_size_p (cfun)"))) 9789 (const_string "0") 9790 (const_string "*"))) 9791 (set_attr "mode" "<MODE>")]) 9792 9793;; Convert shift to the shiftx pattern to avoid flags dependency. 9794(define_split 9795 [(set (match_operand:SWI48 0 "register_operand" "") 9796 (any_shiftrt:SWI48 (match_operand:SWI48 1 "nonimmediate_operand" "") 9797 (match_operand:QI 2 "register_operand" ""))) 9798 (clobber (reg:CC FLAGS_REG))] 9799 "TARGET_BMI2 && reload_completed" 9800 [(set (match_dup 0) 9801 (any_shiftrt:SWI48 (match_dup 1) (match_dup 2)))] 9802 "operands[2] = gen_lowpart (<MODE>mode, operands[2]);") 9803 9804(define_insn "*bmi2_<shift_insn>si3_1_zext" 9805 [(set (match_operand:DI 0 "register_operand" "=r") 9806 (zero_extend:DI 9807 (any_shiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "rm") 9808 (match_operand:SI 2 "register_operand" "r"))))] 9809 "TARGET_64BIT && TARGET_BMI2" 9810 "<shift>x\t{%2, %1, %k0|%k0, %1, %2}" 9811 [(set_attr "type" "ishiftx") 9812 (set_attr "mode" "SI")]) 9813 9814(define_insn "*<shift_insn>si3_1_zext" 9815 [(set (match_operand:DI 0 "register_operand" "=r,r") 9816 (zero_extend:DI 9817 (any_shiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "0,rm") 9818 (match_operand:QI 2 "nonmemory_operand" "cI,r")))) 9819 (clobber (reg:CC FLAGS_REG))] 9820 "TARGET_64BIT && ix86_binary_operator_ok (<CODE>, SImode, operands)" 9821{ 9822 switch (get_attr_type (insn)) 9823 { 9824 case TYPE_ISHIFTX: 9825 return "#"; 9826 9827 default: 9828 if (operands[2] == const1_rtx 9829 && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun))) 9830 return "<shift>{l}\t%k0"; 9831 else 9832 return "<shift>{l}\t{%2, %k0|%k0, %2}"; 9833 } 9834} 9835 [(set_attr "isa" "*,bmi2") 9836 (set_attr "type" "ishift,ishiftx") 9837 (set (attr "length_immediate") 9838 (if_then_else 9839 (and (match_operand 2 "const1_operand" "") 9840 (ior (match_test "TARGET_SHIFT1") 9841 (match_test "optimize_function_for_size_p (cfun)"))) 9842 (const_string "0") 9843 (const_string "*"))) 9844 (set_attr "mode" "SI")]) 9845 9846;; Convert shift to the shiftx pattern to avoid flags dependency. 9847(define_split 9848 [(set (match_operand:DI 0 "register_operand" "") 9849 (zero_extend:DI 9850 (any_shiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "") 9851 (match_operand:QI 2 "register_operand" "")))) 9852 (clobber (reg:CC FLAGS_REG))] 9853 "TARGET_64BIT && TARGET_BMI2 && reload_completed" 9854 [(set (match_dup 0) 9855 (zero_extend:DI (any_shiftrt:SI (match_dup 1) (match_dup 2))))] 9856 "operands[2] = gen_lowpart (SImode, operands[2]);") 9857 9858(define_insn "*<shift_insn><mode>3_1" 9859 [(set (match_operand:SWI12 0 "nonimmediate_operand" "=<r>m") 9860 (any_shiftrt:SWI12 9861 (match_operand:SWI12 1 "nonimmediate_operand" "0") 9862 (match_operand:QI 2 "nonmemory_operand" "c<S>"))) 9863 (clobber (reg:CC FLAGS_REG))] 9864 "ix86_binary_operator_ok (<CODE>, <MODE>mode, operands)" 9865{ 9866 if (operands[2] == const1_rtx 9867 && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun))) 9868 return "<shift>{<imodesuffix>}\t%0"; 9869 else 9870 return "<shift>{<imodesuffix>}\t{%2, %0|%0, %2}"; 9871} 9872 [(set_attr "type" "ishift") 9873 (set (attr "length_immediate") 9874 (if_then_else 9875 (and (match_operand 2 "const1_operand" "") 9876 (ior (match_test "TARGET_SHIFT1") 9877 (match_test "optimize_function_for_size_p (cfun)"))) 9878 (const_string "0") 9879 (const_string "*"))) 9880 (set_attr "mode" "<MODE>")]) 9881 9882(define_insn "*<shift_insn>qi3_1_slp" 9883 [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm")) 9884 (any_shiftrt:QI (match_dup 0) 9885 (match_operand:QI 1 "nonmemory_operand" "cI"))) 9886 (clobber (reg:CC FLAGS_REG))] 9887 "(optimize_function_for_size_p (cfun) 9888 || !TARGET_PARTIAL_REG_STALL 9889 || (operands[1] == const1_rtx 9890 && TARGET_SHIFT1))" 9891{ 9892 if (operands[1] == const1_rtx 9893 && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun))) 9894 return "<shift>{b}\t%0"; 9895 else 9896 return "<shift>{b}\t{%1, %0|%0, %1}"; 9897} 9898 [(set_attr "type" "ishift1") 9899 (set (attr "length_immediate") 9900 (if_then_else 9901 (and (match_operand 1 "const1_operand" "") 9902 (ior (match_test "TARGET_SHIFT1") 9903 (match_test "optimize_function_for_size_p (cfun)"))) 9904 (const_string "0") 9905 (const_string "*"))) 9906 (set_attr "mode" "QI")]) 9907 9908;; This pattern can't accept a variable shift count, since shifts by 9909;; zero don't affect the flags. We assume that shifts by constant 9910;; zero are optimized away. 9911(define_insn "*<shift_insn><mode>3_cmp" 9912 [(set (reg FLAGS_REG) 9913 (compare 9914 (any_shiftrt:SWI 9915 (match_operand:SWI 1 "nonimmediate_operand" "0") 9916 (match_operand:QI 2 "<shift_immediate_operand>" "<S>")) 9917 (const_int 0))) 9918 (set (match_operand:SWI 0 "nonimmediate_operand" "=<r>m") 9919 (any_shiftrt:SWI (match_dup 1) (match_dup 2)))] 9920 "(optimize_function_for_size_p (cfun) 9921 || !TARGET_PARTIAL_FLAG_REG_STALL 9922 || (operands[2] == const1_rtx 9923 && TARGET_SHIFT1)) 9924 && ix86_match_ccmode (insn, CCGOCmode) 9925 && ix86_binary_operator_ok (<CODE>, <MODE>mode, operands)" 9926{ 9927 if (operands[2] == const1_rtx 9928 && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun))) 9929 return "<shift>{<imodesuffix>}\t%0"; 9930 else 9931 return "<shift>{<imodesuffix>}\t{%2, %0|%0, %2}"; 9932} 9933 [(set_attr "type" "ishift") 9934 (set (attr "length_immediate") 9935 (if_then_else 9936 (and (match_operand 2 "const1_operand" "") 9937 (ior (match_test "TARGET_SHIFT1") 9938 (match_test "optimize_function_for_size_p (cfun)"))) 9939 (const_string "0") 9940 (const_string "*"))) 9941 (set_attr "mode" "<MODE>")]) 9942 9943(define_insn "*<shift_insn>si3_cmp_zext" 9944 [(set (reg FLAGS_REG) 9945 (compare 9946 (any_shiftrt:SI (match_operand:SI 1 "register_operand" "0") 9947 (match_operand:QI 2 "const_1_to_31_operand" "I")) 9948 (const_int 0))) 9949 (set (match_operand:DI 0 "register_operand" "=r") 9950 (zero_extend:DI (any_shiftrt:SI (match_dup 1) (match_dup 2))))] 9951 "TARGET_64BIT 9952 && (optimize_function_for_size_p (cfun) 9953 || !TARGET_PARTIAL_FLAG_REG_STALL 9954 || (operands[2] == const1_rtx 9955 && TARGET_SHIFT1)) 9956 && ix86_match_ccmode (insn, CCGOCmode) 9957 && ix86_binary_operator_ok (<CODE>, SImode, operands)" 9958{ 9959 if (operands[2] == const1_rtx 9960 && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun))) 9961 return "<shift>{l}\t%k0"; 9962 else 9963 return "<shift>{l}\t{%2, %k0|%k0, %2}"; 9964} 9965 [(set_attr "type" "ishift") 9966 (set (attr "length_immediate") 9967 (if_then_else 9968 (and (match_operand 2 "const1_operand" "") 9969 (ior (match_test "TARGET_SHIFT1") 9970 (match_test "optimize_function_for_size_p (cfun)"))) 9971 (const_string "0") 9972 (const_string "*"))) 9973 (set_attr "mode" "SI")]) 9974 9975(define_insn "*<shift_insn><mode>3_cconly" 9976 [(set (reg FLAGS_REG) 9977 (compare 9978 (any_shiftrt:SWI 9979 (match_operand:SWI 1 "register_operand" "0") 9980 (match_operand:QI 2 "<shift_immediate_operand>" "<S>")) 9981 (const_int 0))) 9982 (clobber (match_scratch:SWI 0 "=<r>"))] 9983 "(optimize_function_for_size_p (cfun) 9984 || !TARGET_PARTIAL_FLAG_REG_STALL 9985 || (operands[2] == const1_rtx 9986 && TARGET_SHIFT1)) 9987 && ix86_match_ccmode (insn, CCGOCmode)" 9988{ 9989 if (operands[2] == const1_rtx 9990 && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun))) 9991 return "<shift>{<imodesuffix>}\t%0"; 9992 else 9993 return "<shift>{<imodesuffix>}\t{%2, %0|%0, %2}"; 9994} 9995 [(set_attr "type" "ishift") 9996 (set (attr "length_immediate") 9997 (if_then_else 9998 (and (match_operand 2 "const1_operand" "") 9999 (ior (match_test "TARGET_SHIFT1") 10000 (match_test "optimize_function_for_size_p (cfun)"))) 10001 (const_string "0") 10002 (const_string "*"))) 10003 (set_attr "mode" "<MODE>")]) 10004 10005;; Rotate instructions 10006 10007(define_expand "<rotate_insn>ti3" 10008 [(set (match_operand:TI 0 "register_operand" "") 10009 (any_rotate:TI (match_operand:TI 1 "register_operand" "") 10010 (match_operand:QI 2 "nonmemory_operand" "")))] 10011 "TARGET_64BIT" 10012{ 10013 if (const_1_to_63_operand (operands[2], VOIDmode)) 10014 emit_insn (gen_ix86_<rotate_insn>ti3_doubleword 10015 (operands[0], operands[1], operands[2])); 10016 else 10017 FAIL; 10018 10019 DONE; 10020}) 10021 10022(define_expand "<rotate_insn>di3" 10023 [(set (match_operand:DI 0 "shiftdi_operand" "") 10024 (any_rotate:DI (match_operand:DI 1 "shiftdi_operand" "") 10025 (match_operand:QI 2 "nonmemory_operand" "")))] 10026 "" 10027{ 10028 if (TARGET_64BIT) 10029 ix86_expand_binary_operator (<CODE>, DImode, operands); 10030 else if (const_1_to_31_operand (operands[2], VOIDmode)) 10031 emit_insn (gen_ix86_<rotate_insn>di3_doubleword 10032 (operands[0], operands[1], operands[2])); 10033 else 10034 FAIL; 10035 10036 DONE; 10037}) 10038 10039(define_expand "<rotate_insn><mode>3" 10040 [(set (match_operand:SWIM124 0 "nonimmediate_operand" "") 10041 (any_rotate:SWIM124 (match_operand:SWIM124 1 "nonimmediate_operand" "") 10042 (match_operand:QI 2 "nonmemory_operand" "")))] 10043 "" 10044 "ix86_expand_binary_operator (<CODE>, <MODE>mode, operands); DONE;") 10045 10046;; Avoid useless masking of count operand. 10047(define_insn "*<rotate_insn><mode>3_mask" 10048 [(set (match_operand:SWI48 0 "nonimmediate_operand" "=rm") 10049 (any_rotate:SWI48 10050 (match_operand:SWI48 1 "nonimmediate_operand" "0") 10051 (subreg:QI 10052 (and:SI 10053 (match_operand:SI 2 "register_operand" "c") 10054 (match_operand:SI 3 "const_int_operand" "n")) 0))) 10055 (clobber (reg:CC FLAGS_REG))] 10056 "ix86_binary_operator_ok (<CODE>, <MODE>mode, operands) 10057 && (INTVAL (operands[3]) & (GET_MODE_BITSIZE (<MODE>mode)-1)) 10058 == GET_MODE_BITSIZE (<MODE>mode)-1" 10059{ 10060 return "<rotate>{<imodesuffix>}\t{%b2, %0|%0, %b2}"; 10061} 10062 [(set_attr "type" "rotate") 10063 (set_attr "mode" "<MODE>")]) 10064 10065;; Implement rotation using two double-precision 10066;; shift instructions and a scratch register. 10067 10068(define_insn_and_split "ix86_rotl<dwi>3_doubleword" 10069 [(set (match_operand:<DWI> 0 "register_operand" "=r") 10070 (rotate:<DWI> (match_operand:<DWI> 1 "register_operand" "0") 10071 (match_operand:QI 2 "<shift_immediate_operand>" "<S>"))) 10072 (clobber (reg:CC FLAGS_REG)) 10073 (clobber (match_scratch:DWIH 3 "=&r"))] 10074 "" 10075 "#" 10076 "reload_completed" 10077 [(set (match_dup 3) (match_dup 4)) 10078 (parallel 10079 [(set (match_dup 4) 10080 (ior:DWIH (ashift:DWIH (match_dup 4) (match_dup 2)) 10081 (lshiftrt:DWIH (match_dup 5) 10082 (minus:QI (match_dup 6) (match_dup 2))))) 10083 (clobber (reg:CC FLAGS_REG))]) 10084 (parallel 10085 [(set (match_dup 5) 10086 (ior:DWIH (ashift:DWIH (match_dup 5) (match_dup 2)) 10087 (lshiftrt:DWIH (match_dup 3) 10088 (minus:QI (match_dup 6) (match_dup 2))))) 10089 (clobber (reg:CC FLAGS_REG))])] 10090{ 10091 operands[6] = GEN_INT (GET_MODE_BITSIZE (<MODE>mode)); 10092 10093 split_double_mode (<DWI>mode, &operands[0], 1, &operands[4], &operands[5]); 10094}) 10095 10096(define_insn_and_split "ix86_rotr<dwi>3_doubleword" 10097 [(set (match_operand:<DWI> 0 "register_operand" "=r") 10098 (rotatert:<DWI> (match_operand:<DWI> 1 "register_operand" "0") 10099 (match_operand:QI 2 "<shift_immediate_operand>" "<S>"))) 10100 (clobber (reg:CC FLAGS_REG)) 10101 (clobber (match_scratch:DWIH 3 "=&r"))] 10102 "" 10103 "#" 10104 "reload_completed" 10105 [(set (match_dup 3) (match_dup 4)) 10106 (parallel 10107 [(set (match_dup 4) 10108 (ior:DWIH (ashiftrt:DWIH (match_dup 4) (match_dup 2)) 10109 (ashift:DWIH (match_dup 5) 10110 (minus:QI (match_dup 6) (match_dup 2))))) 10111 (clobber (reg:CC FLAGS_REG))]) 10112 (parallel 10113 [(set (match_dup 5) 10114 (ior:DWIH (ashiftrt:DWIH (match_dup 5) (match_dup 2)) 10115 (ashift:DWIH (match_dup 3) 10116 (minus:QI (match_dup 6) (match_dup 2))))) 10117 (clobber (reg:CC FLAGS_REG))])] 10118{ 10119 operands[6] = GEN_INT (GET_MODE_BITSIZE (<MODE>mode)); 10120 10121 split_double_mode (<DWI>mode, &operands[0], 1, &operands[4], &operands[5]); 10122}) 10123 10124(define_insn "*bmi2_rorx<mode>3_1" 10125 [(set (match_operand:SWI48 0 "register_operand" "=r") 10126 (rotatert:SWI48 (match_operand:SWI48 1 "nonimmediate_operand" "rm") 10127 (match_operand:QI 2 "immediate_operand" "<S>")))] 10128 "TARGET_BMI2" 10129 "rorx\t{%2, %1, %0|%0, %1, %2}" 10130 [(set_attr "type" "rotatex") 10131 (set_attr "mode" "<MODE>")]) 10132 10133(define_insn "*<rotate_insn><mode>3_1" 10134 [(set (match_operand:SWI48 0 "nonimmediate_operand" "=rm,r") 10135 (any_rotate:SWI48 10136 (match_operand:SWI48 1 "nonimmediate_operand" "0,rm") 10137 (match_operand:QI 2 "nonmemory_operand" "c<S>,<S>"))) 10138 (clobber (reg:CC FLAGS_REG))] 10139 "ix86_binary_operator_ok (<CODE>, <MODE>mode, operands)" 10140{ 10141 switch (get_attr_type (insn)) 10142 { 10143 case TYPE_ROTATEX: 10144 return "#"; 10145 10146 default: 10147 if (operands[2] == const1_rtx 10148 && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun))) 10149 return "<rotate>{<imodesuffix>}\t%0"; 10150 else 10151 return "<rotate>{<imodesuffix>}\t{%2, %0|%0, %2}"; 10152 } 10153} 10154 [(set_attr "isa" "*,bmi2") 10155 (set_attr "type" "rotate,rotatex") 10156 (set (attr "length_immediate") 10157 (if_then_else 10158 (and (eq_attr "type" "rotate") 10159 (and (match_operand 2 "const1_operand" "") 10160 (ior (match_test "TARGET_SHIFT1") 10161 (match_test "optimize_function_for_size_p (cfun)")))) 10162 (const_string "0") 10163 (const_string "*"))) 10164 (set_attr "mode" "<MODE>")]) 10165 10166;; Convert rotate to the rotatex pattern to avoid flags dependency. 10167(define_split 10168 [(set (match_operand:SWI48 0 "register_operand" "") 10169 (rotate:SWI48 (match_operand:SWI48 1 "nonimmediate_operand" "") 10170 (match_operand:QI 2 "immediate_operand" ""))) 10171 (clobber (reg:CC FLAGS_REG))] 10172 "TARGET_BMI2 && reload_completed" 10173 [(set (match_dup 0) 10174 (rotatert:SWI48 (match_dup 1) (match_dup 2)))] 10175{ 10176 operands[2] 10177 = GEN_INT (GET_MODE_BITSIZE (<MODE>mode) - INTVAL (operands[2])); 10178}) 10179 10180(define_split 10181 [(set (match_operand:SWI48 0 "register_operand" "") 10182 (rotatert:SWI48 (match_operand:SWI48 1 "nonimmediate_operand" "") 10183 (match_operand:QI 2 "immediate_operand" ""))) 10184 (clobber (reg:CC FLAGS_REG))] 10185 "TARGET_BMI2 && reload_completed" 10186 [(set (match_dup 0) 10187 (rotatert:SWI48 (match_dup 1) (match_dup 2)))]) 10188 10189(define_insn "*bmi2_rorxsi3_1_zext" 10190 [(set (match_operand:DI 0 "register_operand" "=r") 10191 (zero_extend:DI 10192 (rotatert:SI (match_operand:SI 1 "nonimmediate_operand" "rm") 10193 (match_operand:QI 2 "immediate_operand" "I"))))] 10194 "TARGET_64BIT && TARGET_BMI2" 10195 "rorx\t{%2, %1, %k0|%k0, %1, %2}" 10196 [(set_attr "type" "rotatex") 10197 (set_attr "mode" "SI")]) 10198 10199(define_insn "*<rotate_insn>si3_1_zext" 10200 [(set (match_operand:DI 0 "register_operand" "=r,r") 10201 (zero_extend:DI 10202 (any_rotate:SI (match_operand:SI 1 "nonimmediate_operand" "0,rm") 10203 (match_operand:QI 2 "nonmemory_operand" "cI,I")))) 10204 (clobber (reg:CC FLAGS_REG))] 10205 "TARGET_64BIT && ix86_binary_operator_ok (<CODE>, SImode, operands)" 10206{ 10207 switch (get_attr_type (insn)) 10208 { 10209 case TYPE_ROTATEX: 10210 return "#"; 10211 10212 default: 10213 if (operands[2] == const1_rtx 10214 && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun))) 10215 return "<rotate>{l}\t%k0"; 10216 else 10217 return "<rotate>{l}\t{%2, %k0|%k0, %2}"; 10218 } 10219} 10220 [(set_attr "isa" "*,bmi2") 10221 (set_attr "type" "rotate,rotatex") 10222 (set (attr "length_immediate") 10223 (if_then_else 10224 (and (eq_attr "type" "rotate") 10225 (and (match_operand 2 "const1_operand" "") 10226 (ior (match_test "TARGET_SHIFT1") 10227 (match_test "optimize_function_for_size_p (cfun)")))) 10228 (const_string "0") 10229 (const_string "*"))) 10230 (set_attr "mode" "SI")]) 10231 10232;; Convert rotate to the rotatex pattern to avoid flags dependency. 10233(define_split 10234 [(set (match_operand:DI 0 "register_operand" "") 10235 (zero_extend:DI 10236 (rotate:SI (match_operand:SI 1 "nonimmediate_operand" "") 10237 (match_operand:QI 2 "immediate_operand" "")))) 10238 (clobber (reg:CC FLAGS_REG))] 10239 "TARGET_64BIT && TARGET_BMI2 && reload_completed" 10240 [(set (match_dup 0) 10241 (zero_extend:DI (rotatert:SI (match_dup 1) (match_dup 2))))] 10242{ 10243 operands[2] 10244 = GEN_INT (GET_MODE_BITSIZE (SImode) - INTVAL (operands[2])); 10245}) 10246 10247(define_split 10248 [(set (match_operand:DI 0 "register_operand" "") 10249 (zero_extend:DI 10250 (rotatert:SI (match_operand:SI 1 "nonimmediate_operand" "") 10251 (match_operand:QI 2 "immediate_operand" "")))) 10252 (clobber (reg:CC FLAGS_REG))] 10253 "TARGET_64BIT && TARGET_BMI2 && reload_completed" 10254 [(set (match_dup 0) 10255 (zero_extend:DI (rotatert:SI (match_dup 1) (match_dup 2))))]) 10256 10257(define_insn "*<rotate_insn><mode>3_1" 10258 [(set (match_operand:SWI12 0 "nonimmediate_operand" "=<r>m") 10259 (any_rotate:SWI12 (match_operand:SWI12 1 "nonimmediate_operand" "0") 10260 (match_operand:QI 2 "nonmemory_operand" "c<S>"))) 10261 (clobber (reg:CC FLAGS_REG))] 10262 "ix86_binary_operator_ok (<CODE>, <MODE>mode, operands)" 10263{ 10264 if (operands[2] == const1_rtx 10265 && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun))) 10266 return "<rotate>{<imodesuffix>}\t%0"; 10267 else 10268 return "<rotate>{<imodesuffix>}\t{%2, %0|%0, %2}"; 10269} 10270 [(set_attr "type" "rotate") 10271 (set (attr "length_immediate") 10272 (if_then_else 10273 (and (match_operand 2 "const1_operand" "") 10274 (ior (match_test "TARGET_SHIFT1") 10275 (match_test "optimize_function_for_size_p (cfun)"))) 10276 (const_string "0") 10277 (const_string "*"))) 10278 (set_attr "mode" "<MODE>")]) 10279 10280(define_insn "*<rotate_insn>qi3_1_slp" 10281 [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm")) 10282 (any_rotate:QI (match_dup 0) 10283 (match_operand:QI 1 "nonmemory_operand" "cI"))) 10284 (clobber (reg:CC FLAGS_REG))] 10285 "(optimize_function_for_size_p (cfun) 10286 || !TARGET_PARTIAL_REG_STALL 10287 || (operands[1] == const1_rtx 10288 && TARGET_SHIFT1))" 10289{ 10290 if (operands[1] == const1_rtx 10291 && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun))) 10292 return "<rotate>{b}\t%0"; 10293 else 10294 return "<rotate>{b}\t{%1, %0|%0, %1}"; 10295} 10296 [(set_attr "type" "rotate1") 10297 (set (attr "length_immediate") 10298 (if_then_else 10299 (and (match_operand 1 "const1_operand" "") 10300 (ior (match_test "TARGET_SHIFT1") 10301 (match_test "optimize_function_for_size_p (cfun)"))) 10302 (const_string "0") 10303 (const_string "*"))) 10304 (set_attr "mode" "QI")]) 10305 10306(define_split 10307 [(set (match_operand:HI 0 "register_operand" "") 10308 (any_rotate:HI (match_dup 0) (const_int 8))) 10309 (clobber (reg:CC FLAGS_REG))] 10310 "reload_completed 10311 && (TARGET_USE_XCHGB || optimize_function_for_size_p (cfun))" 10312 [(parallel [(set (strict_low_part (match_dup 0)) 10313 (bswap:HI (match_dup 0))) 10314 (clobber (reg:CC FLAGS_REG))])]) 10315 10316;; Bit set / bit test instructions 10317 10318(define_expand "extv" 10319 [(set (match_operand:SI 0 "register_operand" "") 10320 (sign_extract:SI (match_operand:SI 1 "register_operand" "") 10321 (match_operand:SI 2 "const8_operand" "") 10322 (match_operand:SI 3 "const8_operand" "")))] 10323 "" 10324{ 10325 /* Handle extractions from %ah et al. */ 10326 if (INTVAL (operands[2]) != 8 || INTVAL (operands[3]) != 8) 10327 FAIL; 10328 10329 /* From mips.md: extract_bit_field doesn't verify that our source 10330 matches the predicate, so check it again here. */ 10331 if (! ext_register_operand (operands[1], VOIDmode)) 10332 FAIL; 10333}) 10334 10335(define_expand "extzv" 10336 [(set (match_operand:SI 0 "register_operand" "") 10337 (zero_extract:SI (match_operand 1 "ext_register_operand" "") 10338 (match_operand:SI 2 "const8_operand" "") 10339 (match_operand:SI 3 "const8_operand" "")))] 10340 "" 10341{ 10342 /* Handle extractions from %ah et al. */ 10343 if (INTVAL (operands[2]) != 8 || INTVAL (operands[3]) != 8) 10344 FAIL; 10345 10346 /* From mips.md: extract_bit_field doesn't verify that our source 10347 matches the predicate, so check it again here. */ 10348 if (! ext_register_operand (operands[1], VOIDmode)) 10349 FAIL; 10350}) 10351 10352(define_expand "insv" 10353 [(set (zero_extract (match_operand 0 "register_operand" "") 10354 (match_operand 1 "const_int_operand" "") 10355 (match_operand 2 "const_int_operand" "")) 10356 (match_operand 3 "register_operand" ""))] 10357 "" 10358{ 10359 rtx (*gen_mov_insv_1) (rtx, rtx); 10360 10361 if (ix86_expand_pinsr (operands)) 10362 DONE; 10363 10364 /* Handle insertions to %ah et al. */ 10365 if (INTVAL (operands[1]) != 8 || INTVAL (operands[2]) != 8) 10366 FAIL; 10367 10368 /* From mips.md: insert_bit_field doesn't verify that our source 10369 matches the predicate, so check it again here. */ 10370 if (! ext_register_operand (operands[0], VOIDmode)) 10371 FAIL; 10372 10373 gen_mov_insv_1 = (TARGET_64BIT 10374 ? gen_movdi_insv_1 : gen_movsi_insv_1); 10375 10376 emit_insn (gen_mov_insv_1 (operands[0], operands[3])); 10377 DONE; 10378}) 10379 10380;; %%% bts, btr, btc, bt. 10381;; In general these instructions are *slow* when applied to memory, 10382;; since they enforce atomic operation. When applied to registers, 10383;; it depends on the cpu implementation. They're never faster than 10384;; the corresponding and/ior/xor operations, so with 32-bit there's 10385;; no point. But in 64-bit, we can't hold the relevant immediates 10386;; within the instruction itself, so operating on bits in the high 10387;; 32-bits of a register becomes easier. 10388;; 10389;; These are slow on Nocona, but fast on Athlon64. We do require the use 10390;; of btrq and btcq for corner cases of post-reload expansion of absdf and 10391;; negdf respectively, so they can never be disabled entirely. 10392 10393(define_insn "*btsq" 10394 [(set (zero_extract:DI (match_operand:DI 0 "register_operand" "+r") 10395 (const_int 1) 10396 (match_operand:DI 1 "const_0_to_63_operand" "")) 10397 (const_int 1)) 10398 (clobber (reg:CC FLAGS_REG))] 10399 "TARGET_64BIT && (TARGET_USE_BT || reload_completed)" 10400 "bts{q}\t{%1, %0|%0, %1}" 10401 [(set_attr "type" "alu1") 10402 (set_attr "prefix_0f" "1") 10403 (set_attr "mode" "DI")]) 10404 10405(define_insn "*btrq" 10406 [(set (zero_extract:DI (match_operand:DI 0 "register_operand" "+r") 10407 (const_int 1) 10408 (match_operand:DI 1 "const_0_to_63_operand" "")) 10409 (const_int 0)) 10410 (clobber (reg:CC FLAGS_REG))] 10411 "TARGET_64BIT && (TARGET_USE_BT || reload_completed)" 10412 "btr{q}\t{%1, %0|%0, %1}" 10413 [(set_attr "type" "alu1") 10414 (set_attr "prefix_0f" "1") 10415 (set_attr "mode" "DI")]) 10416 10417(define_insn "*btcq" 10418 [(set (zero_extract:DI (match_operand:DI 0 "register_operand" "+r") 10419 (const_int 1) 10420 (match_operand:DI 1 "const_0_to_63_operand" "")) 10421 (not:DI (zero_extract:DI (match_dup 0) (const_int 1) (match_dup 1)))) 10422 (clobber (reg:CC FLAGS_REG))] 10423 "TARGET_64BIT && (TARGET_USE_BT || reload_completed)" 10424 "btc{q}\t{%1, %0|%0, %1}" 10425 [(set_attr "type" "alu1") 10426 (set_attr "prefix_0f" "1") 10427 (set_attr "mode" "DI")]) 10428 10429;; Allow Nocona to avoid these instructions if a register is available. 10430 10431(define_peephole2 10432 [(match_scratch:DI 2 "r") 10433 (parallel [(set (zero_extract:DI 10434 (match_operand:DI 0 "register_operand" "") 10435 (const_int 1) 10436 (match_operand:DI 1 "const_0_to_63_operand" "")) 10437 (const_int 1)) 10438 (clobber (reg:CC FLAGS_REG))])] 10439 "TARGET_64BIT && !TARGET_USE_BT" 10440 [(const_int 0)] 10441{ 10442 HOST_WIDE_INT i = INTVAL (operands[1]), hi, lo; 10443 rtx op1; 10444 10445 if (HOST_BITS_PER_WIDE_INT >= 64) 10446 lo = (HOST_WIDE_INT)1 << i, hi = 0; 10447 else if (i < HOST_BITS_PER_WIDE_INT) 10448 lo = (HOST_WIDE_INT)1 << i, hi = 0; 10449 else 10450 lo = 0, hi = (HOST_WIDE_INT)1 << (i - HOST_BITS_PER_WIDE_INT); 10451 10452 op1 = immed_double_const (lo, hi, DImode); 10453 if (i >= 31) 10454 { 10455 emit_move_insn (operands[2], op1); 10456 op1 = operands[2]; 10457 } 10458 10459 emit_insn (gen_iordi3 (operands[0], operands[0], op1)); 10460 DONE; 10461}) 10462 10463(define_peephole2 10464 [(match_scratch:DI 2 "r") 10465 (parallel [(set (zero_extract:DI 10466 (match_operand:DI 0 "register_operand" "") 10467 (const_int 1) 10468 (match_operand:DI 1 "const_0_to_63_operand" "")) 10469 (const_int 0)) 10470 (clobber (reg:CC FLAGS_REG))])] 10471 "TARGET_64BIT && !TARGET_USE_BT" 10472 [(const_int 0)] 10473{ 10474 HOST_WIDE_INT i = INTVAL (operands[1]), hi, lo; 10475 rtx op1; 10476 10477 if (HOST_BITS_PER_WIDE_INT >= 64) 10478 lo = (HOST_WIDE_INT)1 << i, hi = 0; 10479 else if (i < HOST_BITS_PER_WIDE_INT) 10480 lo = (HOST_WIDE_INT)1 << i, hi = 0; 10481 else 10482 lo = 0, hi = (HOST_WIDE_INT)1 << (i - HOST_BITS_PER_WIDE_INT); 10483 10484 op1 = immed_double_const (~lo, ~hi, DImode); 10485 if (i >= 32) 10486 { 10487 emit_move_insn (operands[2], op1); 10488 op1 = operands[2]; 10489 } 10490 10491 emit_insn (gen_anddi3 (operands[0], operands[0], op1)); 10492 DONE; 10493}) 10494 10495(define_peephole2 10496 [(match_scratch:DI 2 "r") 10497 (parallel [(set (zero_extract:DI 10498 (match_operand:DI 0 "register_operand" "") 10499 (const_int 1) 10500 (match_operand:DI 1 "const_0_to_63_operand" "")) 10501 (not:DI (zero_extract:DI 10502 (match_dup 0) (const_int 1) (match_dup 1)))) 10503 (clobber (reg:CC FLAGS_REG))])] 10504 "TARGET_64BIT && !TARGET_USE_BT" 10505 [(const_int 0)] 10506{ 10507 HOST_WIDE_INT i = INTVAL (operands[1]), hi, lo; 10508 rtx op1; 10509 10510 if (HOST_BITS_PER_WIDE_INT >= 64) 10511 lo = (HOST_WIDE_INT)1 << i, hi = 0; 10512 else if (i < HOST_BITS_PER_WIDE_INT) 10513 lo = (HOST_WIDE_INT)1 << i, hi = 0; 10514 else 10515 lo = 0, hi = (HOST_WIDE_INT)1 << (i - HOST_BITS_PER_WIDE_INT); 10516 10517 op1 = immed_double_const (lo, hi, DImode); 10518 if (i >= 31) 10519 { 10520 emit_move_insn (operands[2], op1); 10521 op1 = operands[2]; 10522 } 10523 10524 emit_insn (gen_xordi3 (operands[0], operands[0], op1)); 10525 DONE; 10526}) 10527 10528(define_insn "*bt<mode>" 10529 [(set (reg:CCC FLAGS_REG) 10530 (compare:CCC 10531 (zero_extract:SWI48 10532 (match_operand:SWI48 0 "register_operand" "r") 10533 (const_int 1) 10534 (match_operand:SWI48 1 "x86_64_nonmemory_operand" "rN")) 10535 (const_int 0)))] 10536 "TARGET_USE_BT || optimize_function_for_size_p (cfun)" 10537 "bt{<imodesuffix>}\t{%1, %0|%0, %1}" 10538 [(set_attr "type" "alu1") 10539 (set_attr "prefix_0f" "1") 10540 (set_attr "mode" "<MODE>")]) 10541 10542;; Store-flag instructions. 10543 10544;; For all sCOND expanders, also expand the compare or test insn that 10545;; generates cc0. Generate an equality comparison if `seq' or `sne'. 10546 10547(define_insn_and_split "*setcc_di_1" 10548 [(set (match_operand:DI 0 "register_operand" "=q") 10549 (match_operator:DI 1 "ix86_comparison_operator" 10550 [(reg FLAGS_REG) (const_int 0)]))] 10551 "TARGET_64BIT && !TARGET_PARTIAL_REG_STALL" 10552 "#" 10553 "&& reload_completed" 10554 [(set (match_dup 2) (match_dup 1)) 10555 (set (match_dup 0) (zero_extend:DI (match_dup 2)))] 10556{ 10557 PUT_MODE (operands[1], QImode); 10558 operands[2] = gen_lowpart (QImode, operands[0]); 10559}) 10560 10561(define_insn_and_split "*setcc_si_1_and" 10562 [(set (match_operand:SI 0 "register_operand" "=q") 10563 (match_operator:SI 1 "ix86_comparison_operator" 10564 [(reg FLAGS_REG) (const_int 0)])) 10565 (clobber (reg:CC FLAGS_REG))] 10566 "!TARGET_PARTIAL_REG_STALL 10567 && TARGET_ZERO_EXTEND_WITH_AND && optimize_function_for_speed_p (cfun)" 10568 "#" 10569 "&& reload_completed" 10570 [(set (match_dup 2) (match_dup 1)) 10571 (parallel [(set (match_dup 0) (zero_extend:SI (match_dup 2))) 10572 (clobber (reg:CC FLAGS_REG))])] 10573{ 10574 PUT_MODE (operands[1], QImode); 10575 operands[2] = gen_lowpart (QImode, operands[0]); 10576}) 10577 10578(define_insn_and_split "*setcc_si_1_movzbl" 10579 [(set (match_operand:SI 0 "register_operand" "=q") 10580 (match_operator:SI 1 "ix86_comparison_operator" 10581 [(reg FLAGS_REG) (const_int 0)]))] 10582 "!TARGET_PARTIAL_REG_STALL 10583 && (!TARGET_ZERO_EXTEND_WITH_AND || optimize_function_for_size_p (cfun))" 10584 "#" 10585 "&& reload_completed" 10586 [(set (match_dup 2) (match_dup 1)) 10587 (set (match_dup 0) (zero_extend:SI (match_dup 2)))] 10588{ 10589 PUT_MODE (operands[1], QImode); 10590 operands[2] = gen_lowpart (QImode, operands[0]); 10591}) 10592 10593(define_insn "*setcc_qi" 10594 [(set (match_operand:QI 0 "nonimmediate_operand" "=qm") 10595 (match_operator:QI 1 "ix86_comparison_operator" 10596 [(reg FLAGS_REG) (const_int 0)]))] 10597 "" 10598 "set%C1\t%0" 10599 [(set_attr "type" "setcc") 10600 (set_attr "mode" "QI")]) 10601 10602(define_insn "*setcc_qi_slp" 10603 [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm")) 10604 (match_operator:QI 1 "ix86_comparison_operator" 10605 [(reg FLAGS_REG) (const_int 0)]))] 10606 "" 10607 "set%C1\t%0" 10608 [(set_attr "type" "setcc") 10609 (set_attr "mode" "QI")]) 10610 10611;; In general it is not safe to assume too much about CCmode registers, 10612;; so simplify-rtx stops when it sees a second one. Under certain 10613;; conditions this is safe on x86, so help combine not create 10614;; 10615;; seta %al 10616;; testb %al, %al 10617;; sete %al 10618 10619(define_split 10620 [(set (match_operand:QI 0 "nonimmediate_operand" "") 10621 (ne:QI (match_operator 1 "ix86_comparison_operator" 10622 [(reg FLAGS_REG) (const_int 0)]) 10623 (const_int 0)))] 10624 "" 10625 [(set (match_dup 0) (match_dup 1))] 10626 "PUT_MODE (operands[1], QImode);") 10627 10628(define_split 10629 [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "")) 10630 (ne:QI (match_operator 1 "ix86_comparison_operator" 10631 [(reg FLAGS_REG) (const_int 0)]) 10632 (const_int 0)))] 10633 "" 10634 [(set (match_dup 0) (match_dup 1))] 10635 "PUT_MODE (operands[1], QImode);") 10636 10637(define_split 10638 [(set (match_operand:QI 0 "nonimmediate_operand" "") 10639 (eq:QI (match_operator 1 "ix86_comparison_operator" 10640 [(reg FLAGS_REG) (const_int 0)]) 10641 (const_int 0)))] 10642 "" 10643 [(set (match_dup 0) (match_dup 1))] 10644{ 10645 rtx new_op1 = copy_rtx (operands[1]); 10646 operands[1] = new_op1; 10647 PUT_MODE (new_op1, QImode); 10648 PUT_CODE (new_op1, ix86_reverse_condition (GET_CODE (new_op1), 10649 GET_MODE (XEXP (new_op1, 0)))); 10650 10651 /* Make sure that (a) the CCmode we have for the flags is strong 10652 enough for the reversed compare or (b) we have a valid FP compare. */ 10653 if (! ix86_comparison_operator (new_op1, VOIDmode)) 10654 FAIL; 10655}) 10656 10657(define_split 10658 [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "")) 10659 (eq:QI (match_operator 1 "ix86_comparison_operator" 10660 [(reg FLAGS_REG) (const_int 0)]) 10661 (const_int 0)))] 10662 "" 10663 [(set (match_dup 0) (match_dup 1))] 10664{ 10665 rtx new_op1 = copy_rtx (operands[1]); 10666 operands[1] = new_op1; 10667 PUT_MODE (new_op1, QImode); 10668 PUT_CODE (new_op1, ix86_reverse_condition (GET_CODE (new_op1), 10669 GET_MODE (XEXP (new_op1, 0)))); 10670 10671 /* Make sure that (a) the CCmode we have for the flags is strong 10672 enough for the reversed compare or (b) we have a valid FP compare. */ 10673 if (! ix86_comparison_operator (new_op1, VOIDmode)) 10674 FAIL; 10675}) 10676 10677;; The SSE store flag instructions saves 0 or 0xffffffff to the result. 10678;; subsequent logical operations are used to imitate conditional moves. 10679;; 0xffffffff is NaN, but not in normalized form, so we can't represent 10680;; it directly. 10681 10682(define_insn "setcc_<mode>_sse" 10683 [(set (match_operand:MODEF 0 "register_operand" "=x,x") 10684 (match_operator:MODEF 3 "sse_comparison_operator" 10685 [(match_operand:MODEF 1 "register_operand" "0,x") 10686 (match_operand:MODEF 2 "nonimmediate_operand" "xm,xm")]))] 10687 "SSE_FLOAT_MODE_P (<MODE>mode)" 10688 "@ 10689 cmp%D3<ssemodesuffix>\t{%2, %0|%0, %2} 10690 vcmp%D3<ssemodesuffix>\t{%2, %1, %0|%0, %1, %2}" 10691 [(set_attr "isa" "noavx,avx") 10692 (set_attr "type" "ssecmp") 10693 (set_attr "length_immediate" "1") 10694 (set_attr "prefix" "orig,vex") 10695 (set_attr "mode" "<MODE>")]) 10696 10697;; Basic conditional jump instructions. 10698;; We ignore the overflow flag for signed branch instructions. 10699 10700(define_insn "*jcc_1" 10701 [(set (pc) 10702 (if_then_else (match_operator 1 "ix86_comparison_operator" 10703 [(reg FLAGS_REG) (const_int 0)]) 10704 (label_ref (match_operand 0 "" "")) 10705 (pc)))] 10706 "" 10707 "%+j%C1\t%l0" 10708 [(set_attr "type" "ibr") 10709 (set_attr "modrm" "0") 10710 (set (attr "length") 10711 (if_then_else (and (ge (minus (match_dup 0) (pc)) 10712 (const_int -126)) 10713 (lt (minus (match_dup 0) (pc)) 10714 (const_int 128))) 10715 (const_int 2) 10716 (const_int 6)))]) 10717 10718(define_insn "*jcc_2" 10719 [(set (pc) 10720 (if_then_else (match_operator 1 "ix86_comparison_operator" 10721 [(reg FLAGS_REG) (const_int 0)]) 10722 (pc) 10723 (label_ref (match_operand 0 "" ""))))] 10724 "" 10725 "%+j%c1\t%l0" 10726 [(set_attr "type" "ibr") 10727 (set_attr "modrm" "0") 10728 (set (attr "length") 10729 (if_then_else (and (ge (minus (match_dup 0) (pc)) 10730 (const_int -126)) 10731 (lt (minus (match_dup 0) (pc)) 10732 (const_int 128))) 10733 (const_int 2) 10734 (const_int 6)))]) 10735 10736;; In general it is not safe to assume too much about CCmode registers, 10737;; so simplify-rtx stops when it sees a second one. Under certain 10738;; conditions this is safe on x86, so help combine not create 10739;; 10740;; seta %al 10741;; testb %al, %al 10742;; je Lfoo 10743 10744(define_split 10745 [(set (pc) 10746 (if_then_else (ne (match_operator 0 "ix86_comparison_operator" 10747 [(reg FLAGS_REG) (const_int 0)]) 10748 (const_int 0)) 10749 (label_ref (match_operand 1 "" "")) 10750 (pc)))] 10751 "" 10752 [(set (pc) 10753 (if_then_else (match_dup 0) 10754 (label_ref (match_dup 1)) 10755 (pc)))] 10756 "PUT_MODE (operands[0], VOIDmode);") 10757 10758(define_split 10759 [(set (pc) 10760 (if_then_else (eq (match_operator 0 "ix86_comparison_operator" 10761 [(reg FLAGS_REG) (const_int 0)]) 10762 (const_int 0)) 10763 (label_ref (match_operand 1 "" "")) 10764 (pc)))] 10765 "" 10766 [(set (pc) 10767 (if_then_else (match_dup 0) 10768 (label_ref (match_dup 1)) 10769 (pc)))] 10770{ 10771 rtx new_op0 = copy_rtx (operands[0]); 10772 operands[0] = new_op0; 10773 PUT_MODE (new_op0, VOIDmode); 10774 PUT_CODE (new_op0, ix86_reverse_condition (GET_CODE (new_op0), 10775 GET_MODE (XEXP (new_op0, 0)))); 10776 10777 /* Make sure that (a) the CCmode we have for the flags is strong 10778 enough for the reversed compare or (b) we have a valid FP compare. */ 10779 if (! ix86_comparison_operator (new_op0, VOIDmode)) 10780 FAIL; 10781}) 10782 10783;; zero_extend in SImode is correct also for DImode, since this is what combine 10784;; pass generates from shift insn with QImode operand. Actually, the mode 10785;; of operand 2 (bit offset operand) doesn't matter since bt insn takes 10786;; appropriate modulo of the bit offset value. 10787 10788(define_insn_and_split "*jcc_bt<mode>" 10789 [(set (pc) 10790 (if_then_else (match_operator 0 "bt_comparison_operator" 10791 [(zero_extract:SWI48 10792 (match_operand:SWI48 1 "register_operand" "r") 10793 (const_int 1) 10794 (zero_extend:SI 10795 (match_operand:QI 2 "register_operand" "r"))) 10796 (const_int 0)]) 10797 (label_ref (match_operand 3 "" "")) 10798 (pc))) 10799 (clobber (reg:CC FLAGS_REG))] 10800 "TARGET_USE_BT || optimize_function_for_size_p (cfun)" 10801 "#" 10802 "&& 1" 10803 [(set (reg:CCC FLAGS_REG) 10804 (compare:CCC 10805 (zero_extract:SWI48 10806 (match_dup 1) 10807 (const_int 1) 10808 (match_dup 2)) 10809 (const_int 0))) 10810 (set (pc) 10811 (if_then_else (match_op_dup 0 [(reg:CCC FLAGS_REG) (const_int 0)]) 10812 (label_ref (match_dup 3)) 10813 (pc)))] 10814{ 10815 operands[2] = simplify_gen_subreg (<MODE>mode, operands[2], QImode, 0); 10816 10817 PUT_CODE (operands[0], reverse_condition (GET_CODE (operands[0]))); 10818}) 10819 10820;; Avoid useless masking of bit offset operand. "and" in SImode is correct 10821;; also for DImode, this is what combine produces. 10822(define_insn_and_split "*jcc_bt<mode>_mask" 10823 [(set (pc) 10824 (if_then_else (match_operator 0 "bt_comparison_operator" 10825 [(zero_extract:SWI48 10826 (match_operand:SWI48 1 "register_operand" "r") 10827 (const_int 1) 10828 (and:SI 10829 (match_operand:SI 2 "register_operand" "r") 10830 (match_operand:SI 3 "const_int_operand" "n")))]) 10831 (label_ref (match_operand 4 "" "")) 10832 (pc))) 10833 (clobber (reg:CC FLAGS_REG))] 10834 "(TARGET_USE_BT || optimize_function_for_size_p (cfun)) 10835 && (INTVAL (operands[3]) & (GET_MODE_BITSIZE (<MODE>mode)-1)) 10836 == GET_MODE_BITSIZE (<MODE>mode)-1" 10837 "#" 10838 "&& 1" 10839 [(set (reg:CCC FLAGS_REG) 10840 (compare:CCC 10841 (zero_extract:SWI48 10842 (match_dup 1) 10843 (const_int 1) 10844 (match_dup 2)) 10845 (const_int 0))) 10846 (set (pc) 10847 (if_then_else (match_op_dup 0 [(reg:CCC FLAGS_REG) (const_int 0)]) 10848 (label_ref (match_dup 4)) 10849 (pc)))] 10850{ 10851 operands[2] = simplify_gen_subreg (<MODE>mode, operands[2], SImode, 0); 10852 10853 PUT_CODE (operands[0], reverse_condition (GET_CODE (operands[0]))); 10854}) 10855 10856(define_insn_and_split "*jcc_btsi_1" 10857 [(set (pc) 10858 (if_then_else (match_operator 0 "bt_comparison_operator" 10859 [(and:SI 10860 (lshiftrt:SI 10861 (match_operand:SI 1 "register_operand" "r") 10862 (match_operand:QI 2 "register_operand" "r")) 10863 (const_int 1)) 10864 (const_int 0)]) 10865 (label_ref (match_operand 3 "" "")) 10866 (pc))) 10867 (clobber (reg:CC FLAGS_REG))] 10868 "TARGET_USE_BT || optimize_function_for_size_p (cfun)" 10869 "#" 10870 "&& 1" 10871 [(set (reg:CCC FLAGS_REG) 10872 (compare:CCC 10873 (zero_extract:SI 10874 (match_dup 1) 10875 (const_int 1) 10876 (match_dup 2)) 10877 (const_int 0))) 10878 (set (pc) 10879 (if_then_else (match_op_dup 0 [(reg:CCC FLAGS_REG) (const_int 0)]) 10880 (label_ref (match_dup 3)) 10881 (pc)))] 10882{ 10883 operands[2] = simplify_gen_subreg (SImode, operands[2], QImode, 0); 10884 10885 PUT_CODE (operands[0], reverse_condition (GET_CODE (operands[0]))); 10886}) 10887 10888;; avoid useless masking of bit offset operand 10889(define_insn_and_split "*jcc_btsi_mask_1" 10890 [(set (pc) 10891 (if_then_else 10892 (match_operator 0 "bt_comparison_operator" 10893 [(and:SI 10894 (lshiftrt:SI 10895 (match_operand:SI 1 "register_operand" "r") 10896 (subreg:QI 10897 (and:SI 10898 (match_operand:SI 2 "register_operand" "r") 10899 (match_operand:SI 3 "const_int_operand" "n")) 0)) 10900 (const_int 1)) 10901 (const_int 0)]) 10902 (label_ref (match_operand 4 "" "")) 10903 (pc))) 10904 (clobber (reg:CC FLAGS_REG))] 10905 "(TARGET_USE_BT || optimize_function_for_size_p (cfun)) 10906 && (INTVAL (operands[3]) & 0x1f) == 0x1f" 10907 "#" 10908 "&& 1" 10909 [(set (reg:CCC FLAGS_REG) 10910 (compare:CCC 10911 (zero_extract:SI 10912 (match_dup 1) 10913 (const_int 1) 10914 (match_dup 2)) 10915 (const_int 0))) 10916 (set (pc) 10917 (if_then_else (match_op_dup 0 [(reg:CCC FLAGS_REG) (const_int 0)]) 10918 (label_ref (match_dup 4)) 10919 (pc)))] 10920 "PUT_CODE (operands[0], reverse_condition (GET_CODE (operands[0])));") 10921 10922;; Define combination compare-and-branch fp compare instructions to help 10923;; combine. 10924 10925(define_insn "*fp_jcc_1_387" 10926 [(set (pc) 10927 (if_then_else (match_operator 0 "ix86_fp_comparison_operator" 10928 [(match_operand 1 "register_operand" "f") 10929 (match_operand 2 "nonimmediate_operand" "fm")]) 10930 (label_ref (match_operand 3 "" "")) 10931 (pc))) 10932 (clobber (reg:CCFP FPSR_REG)) 10933 (clobber (reg:CCFP FLAGS_REG)) 10934 (clobber (match_scratch:HI 4 "=a"))] 10935 "TARGET_80387 10936 && (GET_MODE (operands[1]) == SFmode || GET_MODE (operands[1]) == DFmode) 10937 && GET_MODE (operands[1]) == GET_MODE (operands[2]) 10938 && SELECT_CC_MODE (GET_CODE (operands[0]), 10939 operands[1], operands[2]) == CCFPmode 10940 && !TARGET_CMOVE" 10941 "#") 10942 10943(define_insn "*fp_jcc_1r_387" 10944 [(set (pc) 10945 (if_then_else (match_operator 0 "ix86_fp_comparison_operator" 10946 [(match_operand 1 "register_operand" "f") 10947 (match_operand 2 "nonimmediate_operand" "fm")]) 10948 (pc) 10949 (label_ref (match_operand 3 "" "")))) 10950 (clobber (reg:CCFP FPSR_REG)) 10951 (clobber (reg:CCFP FLAGS_REG)) 10952 (clobber (match_scratch:HI 4 "=a"))] 10953 "TARGET_80387 10954 && (GET_MODE (operands[1]) == SFmode || GET_MODE (operands[1]) == DFmode) 10955 && GET_MODE (operands[1]) == GET_MODE (operands[2]) 10956 && SELECT_CC_MODE (GET_CODE (operands[0]), 10957 operands[1], operands[2]) == CCFPmode 10958 && !TARGET_CMOVE" 10959 "#") 10960 10961(define_insn "*fp_jcc_2_387" 10962 [(set (pc) 10963 (if_then_else (match_operator 0 "ix86_fp_comparison_operator" 10964 [(match_operand 1 "register_operand" "f") 10965 (match_operand 2 "register_operand" "f")]) 10966 (label_ref (match_operand 3 "" "")) 10967 (pc))) 10968 (clobber (reg:CCFP FPSR_REG)) 10969 (clobber (reg:CCFP FLAGS_REG)) 10970 (clobber (match_scratch:HI 4 "=a"))] 10971 "X87_FLOAT_MODE_P (GET_MODE (operands[1])) 10972 && GET_MODE (operands[1]) == GET_MODE (operands[2]) 10973 && !TARGET_CMOVE" 10974 "#") 10975 10976(define_insn "*fp_jcc_2r_387" 10977 [(set (pc) 10978 (if_then_else (match_operator 0 "ix86_fp_comparison_operator" 10979 [(match_operand 1 "register_operand" "f") 10980 (match_operand 2 "register_operand" "f")]) 10981 (pc) 10982 (label_ref (match_operand 3 "" "")))) 10983 (clobber (reg:CCFP FPSR_REG)) 10984 (clobber (reg:CCFP FLAGS_REG)) 10985 (clobber (match_scratch:HI 4 "=a"))] 10986 "X87_FLOAT_MODE_P (GET_MODE (operands[1])) 10987 && GET_MODE (operands[1]) == GET_MODE (operands[2]) 10988 && !TARGET_CMOVE" 10989 "#") 10990 10991(define_insn "*fp_jcc_3_387" 10992 [(set (pc) 10993 (if_then_else (match_operator 0 "ix86_fp_comparison_operator" 10994 [(match_operand 1 "register_operand" "f") 10995 (match_operand 2 "const0_operand" "")]) 10996 (label_ref (match_operand 3 "" "")) 10997 (pc))) 10998 (clobber (reg:CCFP FPSR_REG)) 10999 (clobber (reg:CCFP FLAGS_REG)) 11000 (clobber (match_scratch:HI 4 "=a"))] 11001 "X87_FLOAT_MODE_P (GET_MODE (operands[1])) 11002 && GET_MODE (operands[1]) == GET_MODE (operands[2]) 11003 && SELECT_CC_MODE (GET_CODE (operands[0]), 11004 operands[1], operands[2]) == CCFPmode 11005 && !TARGET_CMOVE" 11006 "#") 11007 11008(define_split 11009 [(set (pc) 11010 (if_then_else (match_operator 0 "ix86_fp_comparison_operator" 11011 [(match_operand 1 "register_operand" "") 11012 (match_operand 2 "nonimmediate_operand" "")]) 11013 (match_operand 3 "" "") 11014 (match_operand 4 "" ""))) 11015 (clobber (reg:CCFP FPSR_REG)) 11016 (clobber (reg:CCFP FLAGS_REG))] 11017 "reload_completed" 11018 [(const_int 0)] 11019{ 11020 ix86_split_fp_branch (GET_CODE (operands[0]), operands[1], operands[2], 11021 operands[3], operands[4], NULL_RTX, NULL_RTX); 11022 DONE; 11023}) 11024 11025(define_split 11026 [(set (pc) 11027 (if_then_else (match_operator 0 "ix86_fp_comparison_operator" 11028 [(match_operand 1 "register_operand" "") 11029 (match_operand 2 "general_operand" "")]) 11030 (match_operand 3 "" "") 11031 (match_operand 4 "" ""))) 11032 (clobber (reg:CCFP FPSR_REG)) 11033 (clobber (reg:CCFP FLAGS_REG)) 11034 (clobber (match_scratch:HI 5 "=a"))] 11035 "reload_completed" 11036 [(const_int 0)] 11037{ 11038 ix86_split_fp_branch (GET_CODE (operands[0]), operands[1], operands[2], 11039 operands[3], operands[4], operands[5], NULL_RTX); 11040 DONE; 11041}) 11042 11043;; The order of operands in *fp_jcc_4_387 is forced by combine in 11044;; simplify_comparison () function. Float operator is treated as RTX_OBJ 11045;; with a precedence over other operators and is always put in the first 11046;; place. Swap condition and operands to match ficom instruction. 11047 11048(define_insn "*fp_jcc_4_<mode>_387" 11049 [(set (pc) 11050 (if_then_else 11051 (match_operator 0 "ix86_swapped_fp_comparison_operator" 11052 [(match_operator 1 "float_operator" 11053 [(match_operand:SWI24 2 "nonimmediate_operand" "m,?r")]) 11054 (match_operand 3 "register_operand" "f,f")]) 11055 (label_ref (match_operand 4 "" "")) 11056 (pc))) 11057 (clobber (reg:CCFP FPSR_REG)) 11058 (clobber (reg:CCFP FLAGS_REG)) 11059 (clobber (match_scratch:HI 5 "=a,a"))] 11060 "X87_FLOAT_MODE_P (GET_MODE (operands[3])) 11061 && (TARGET_USE_<MODE>MODE_FIOP || optimize_function_for_size_p (cfun)) 11062 && GET_MODE (operands[1]) == GET_MODE (operands[3]) 11063 && ix86_fp_compare_mode (swap_condition (GET_CODE (operands[0]))) == CCFPmode 11064 && !TARGET_CMOVE" 11065 "#") 11066 11067(define_split 11068 [(set (pc) 11069 (if_then_else 11070 (match_operator 0 "ix86_swapped_fp_comparison_operator" 11071 [(match_operator 1 "float_operator" 11072 [(match_operand:SWI24 2 "memory_operand" "")]) 11073 (match_operand 3 "register_operand" "")]) 11074 (match_operand 4 "" "") 11075 (match_operand 5 "" ""))) 11076 (clobber (reg:CCFP FPSR_REG)) 11077 (clobber (reg:CCFP FLAGS_REG)) 11078 (clobber (match_scratch:HI 6 "=a"))] 11079 "reload_completed" 11080 [(const_int 0)] 11081{ 11082 operands[7] = gen_rtx_FLOAT (GET_MODE (operands[1]), operands[2]); 11083 11084 ix86_split_fp_branch (swap_condition (GET_CODE (operands[0])), 11085 operands[3], operands[7], 11086 operands[4], operands[5], operands[6], NULL_RTX); 11087 DONE; 11088}) 11089 11090;; %%% Kill this when reload knows how to do it. 11091(define_split 11092 [(set (pc) 11093 (if_then_else 11094 (match_operator 0 "ix86_swapped_fp_comparison_operator" 11095 [(match_operator 1 "float_operator" 11096 [(match_operand:SWI24 2 "register_operand" "")]) 11097 (match_operand 3 "register_operand" "")]) 11098 (match_operand 4 "" "") 11099 (match_operand 5 "" ""))) 11100 (clobber (reg:CCFP FPSR_REG)) 11101 (clobber (reg:CCFP FLAGS_REG)) 11102 (clobber (match_scratch:HI 6 "=a"))] 11103 "reload_completed" 11104 [(const_int 0)] 11105{ 11106 operands[7] = ix86_force_to_memory (GET_MODE (operands[2]), operands[2]); 11107 operands[7] = gen_rtx_FLOAT (GET_MODE (operands[1]), operands[7]); 11108 11109 ix86_split_fp_branch (swap_condition (GET_CODE (operands[0])), 11110 operands[3], operands[7], 11111 operands[4], operands[5], operands[6], operands[2]); 11112 DONE; 11113}) 11114 11115;; Unconditional and other jump instructions 11116 11117(define_insn "jump" 11118 [(set (pc) 11119 (label_ref (match_operand 0 "" "")))] 11120 "" 11121 "jmp\t%l0" 11122 [(set_attr "type" "ibr") 11123 (set (attr "length") 11124 (if_then_else (and (ge (minus (match_dup 0) (pc)) 11125 (const_int -126)) 11126 (lt (minus (match_dup 0) (pc)) 11127 (const_int 128))) 11128 (const_int 2) 11129 (const_int 5))) 11130 (set_attr "modrm" "0")]) 11131 11132(define_expand "indirect_jump" 11133 [(set (pc) (match_operand 0 "indirect_branch_operand" ""))]) 11134 11135(define_insn "*indirect_jump" 11136 [(set (pc) (match_operand:P 0 "indirect_branch_operand" "rw"))] 11137 "" 11138 "jmp\t%A0" 11139 [(set_attr "type" "ibr") 11140 (set_attr "length_immediate" "0")]) 11141 11142(define_expand "tablejump" 11143 [(parallel [(set (pc) (match_operand 0 "indirect_branch_operand" "")) 11144 (use (label_ref (match_operand 1 "" "")))])] 11145 "" 11146{ 11147 /* In PIC mode, the table entries are stored GOT (32-bit) or PC (64-bit) 11148 relative. Convert the relative address to an absolute address. */ 11149 if (flag_pic) 11150 { 11151 rtx op0, op1; 11152 enum rtx_code code; 11153 11154 /* We can't use @GOTOFF for text labels on VxWorks; 11155 see gotoff_operand. */ 11156 if (TARGET_64BIT || TARGET_VXWORKS_RTP) 11157 { 11158 code = PLUS; 11159 op0 = operands[0]; 11160 op1 = gen_rtx_LABEL_REF (Pmode, operands[1]); 11161 } 11162 else if (TARGET_MACHO || HAVE_AS_GOTOFF_IN_DATA) 11163 { 11164 code = PLUS; 11165 op0 = operands[0]; 11166 op1 = pic_offset_table_rtx; 11167 } 11168 else 11169 { 11170 code = MINUS; 11171 op0 = pic_offset_table_rtx; 11172 op1 = operands[0]; 11173 } 11174 11175 operands[0] = expand_simple_binop (Pmode, code, op0, op1, NULL_RTX, 0, 11176 OPTAB_DIRECT); 11177 } 11178 else if (TARGET_X32) 11179 operands[0] = convert_memory_address (Pmode, operands[0]); 11180}) 11181 11182(define_insn "*tablejump_1" 11183 [(set (pc) (match_operand:P 0 "indirect_branch_operand" "rw")) 11184 (use (label_ref (match_operand 1 "" "")))] 11185 "" 11186 "jmp\t%A0" 11187 [(set_attr "type" "ibr") 11188 (set_attr "length_immediate" "0")]) 11189 11190;; Convert setcc + movzbl to xor + setcc if operands don't overlap. 11191 11192(define_peephole2 11193 [(set (reg FLAGS_REG) (match_operand 0 "" "")) 11194 (set (match_operand:QI 1 "register_operand" "") 11195 (match_operator:QI 2 "ix86_comparison_operator" 11196 [(reg FLAGS_REG) (const_int 0)])) 11197 (set (match_operand 3 "q_regs_operand" "") 11198 (zero_extend (match_dup 1)))] 11199 "(peep2_reg_dead_p (3, operands[1]) 11200 || operands_match_p (operands[1], operands[3])) 11201 && ! reg_overlap_mentioned_p (operands[3], operands[0])" 11202 [(set (match_dup 4) (match_dup 0)) 11203 (set (strict_low_part (match_dup 5)) 11204 (match_dup 2))] 11205{ 11206 operands[4] = gen_rtx_REG (GET_MODE (operands[0]), FLAGS_REG); 11207 operands[5] = gen_lowpart (QImode, operands[3]); 11208 ix86_expand_clear (operands[3]); 11209}) 11210 11211;; Similar, but match zero_extendhisi2_and, which adds a clobber. 11212 11213(define_peephole2 11214 [(set (reg FLAGS_REG) (match_operand 0 "" "")) 11215 (set (match_operand:QI 1 "register_operand" "") 11216 (match_operator:QI 2 "ix86_comparison_operator" 11217 [(reg FLAGS_REG) (const_int 0)])) 11218 (parallel [(set (match_operand 3 "q_regs_operand" "") 11219 (zero_extend (match_dup 1))) 11220 (clobber (reg:CC FLAGS_REG))])] 11221 "(peep2_reg_dead_p (3, operands[1]) 11222 || operands_match_p (operands[1], operands[3])) 11223 && ! reg_overlap_mentioned_p (operands[3], operands[0])" 11224 [(set (match_dup 4) (match_dup 0)) 11225 (set (strict_low_part (match_dup 5)) 11226 (match_dup 2))] 11227{ 11228 operands[4] = gen_rtx_REG (GET_MODE (operands[0]), FLAGS_REG); 11229 operands[5] = gen_lowpart (QImode, operands[3]); 11230 ix86_expand_clear (operands[3]); 11231}) 11232 11233;; Call instructions. 11234 11235;; The predicates normally associated with named expanders are not properly 11236;; checked for calls. This is a bug in the generic code, but it isn't that 11237;; easy to fix. Ignore it for now and be prepared to fix things up. 11238 11239;; P6 processors will jump to the address after the decrement when %esp 11240;; is used as a call operand, so they will execute return address as a code. 11241;; See Pentium Pro errata 70, Pentium 2 errata A33 and Pentium 3 errata E17. 11242 11243;; Register constraint for call instruction. 11244(define_mode_attr c [(SI "l") (DI "r")]) 11245 11246;; Call subroutine returning no value. 11247 11248(define_expand "call" 11249 [(call (match_operand:QI 0 "" "") 11250 (match_operand 1 "" "")) 11251 (use (match_operand 2 "" ""))] 11252 "" 11253{ 11254 ix86_expand_call (NULL, operands[0], operands[1], 11255 operands[2], NULL, false); 11256 DONE; 11257}) 11258 11259(define_expand "sibcall" 11260 [(call (match_operand:QI 0 "" "") 11261 (match_operand 1 "" "")) 11262 (use (match_operand 2 "" ""))] 11263 "" 11264{ 11265 ix86_expand_call (NULL, operands[0], operands[1], 11266 operands[2], NULL, true); 11267 DONE; 11268}) 11269 11270(define_insn_and_split "*call_vzeroupper" 11271 [(call (mem:QI (match_operand:P 0 "call_insn_operand" "<c>zw")) 11272 (match_operand 1 "" "")) 11273 (unspec [(match_operand 2 "const_int_operand" "")] 11274 UNSPEC_CALL_NEEDS_VZEROUPPER)] 11275 "TARGET_VZEROUPPER && !SIBLING_CALL_P (insn)" 11276 "#" 11277 "&& reload_completed" 11278 [(const_int 0)] 11279 "ix86_split_call_vzeroupper (curr_insn, operands[2]); DONE;" 11280 [(set_attr "type" "call")]) 11281 11282(define_insn "*call" 11283 [(call (mem:QI (match_operand:P 0 "call_insn_operand" "<c>zw")) 11284 (match_operand 1 "" ""))] 11285 "!SIBLING_CALL_P (insn)" 11286 "* return ix86_output_call_insn (insn, operands[0]);" 11287 [(set_attr "type" "call")]) 11288 11289(define_insn_and_split "*call_rex64_ms_sysv_vzeroupper" 11290 [(call (mem:QI (match_operand:DI 0 "call_insn_operand" "rzw")) 11291 (match_operand 1 "" "")) 11292 (unspec [(const_int 0)] UNSPEC_MS_TO_SYSV_CALL) 11293 (clobber (reg:TI XMM6_REG)) 11294 (clobber (reg:TI XMM7_REG)) 11295 (clobber (reg:TI XMM8_REG)) 11296 (clobber (reg:TI XMM9_REG)) 11297 (clobber (reg:TI XMM10_REG)) 11298 (clobber (reg:TI XMM11_REG)) 11299 (clobber (reg:TI XMM12_REG)) 11300 (clobber (reg:TI XMM13_REG)) 11301 (clobber (reg:TI XMM14_REG)) 11302 (clobber (reg:TI XMM15_REG)) 11303 (clobber (reg:DI SI_REG)) 11304 (clobber (reg:DI DI_REG)) 11305 (unspec [(match_operand 2 "const_int_operand" "")] 11306 UNSPEC_CALL_NEEDS_VZEROUPPER)] 11307 "TARGET_VZEROUPPER && TARGET_64BIT && !SIBLING_CALL_P (insn)" 11308 "#" 11309 "&& reload_completed" 11310 [(const_int 0)] 11311 "ix86_split_call_vzeroupper (curr_insn, operands[2]); DONE;" 11312 [(set_attr "type" "call")]) 11313 11314(define_insn "*call_rex64_ms_sysv" 11315 [(call (mem:QI (match_operand:DI 0 "call_insn_operand" "rzw")) 11316 (match_operand 1 "" "")) 11317 (unspec [(const_int 0)] UNSPEC_MS_TO_SYSV_CALL) 11318 (clobber (reg:TI XMM6_REG)) 11319 (clobber (reg:TI XMM7_REG)) 11320 (clobber (reg:TI XMM8_REG)) 11321 (clobber (reg:TI XMM9_REG)) 11322 (clobber (reg:TI XMM10_REG)) 11323 (clobber (reg:TI XMM11_REG)) 11324 (clobber (reg:TI XMM12_REG)) 11325 (clobber (reg:TI XMM13_REG)) 11326 (clobber (reg:TI XMM14_REG)) 11327 (clobber (reg:TI XMM15_REG)) 11328 (clobber (reg:DI SI_REG)) 11329 (clobber (reg:DI DI_REG))] 11330 "TARGET_64BIT && !SIBLING_CALL_P (insn)" 11331 "* return ix86_output_call_insn (insn, operands[0]);" 11332 [(set_attr "type" "call")]) 11333 11334(define_insn_and_split "*sibcall_vzeroupper" 11335 [(call (mem:QI (match_operand:P 0 "sibcall_insn_operand" "Uz")) 11336 (match_operand 1 "" "")) 11337 (unspec [(match_operand 2 "const_int_operand" "")] 11338 UNSPEC_CALL_NEEDS_VZEROUPPER)] 11339 "TARGET_VZEROUPPER && SIBLING_CALL_P (insn)" 11340 "#" 11341 "&& reload_completed" 11342 [(const_int 0)] 11343 "ix86_split_call_vzeroupper (curr_insn, operands[2]); DONE;" 11344 [(set_attr "type" "call")]) 11345 11346(define_insn "*sibcall" 11347 [(call (mem:QI (match_operand:P 0 "sibcall_insn_operand" "Uz")) 11348 (match_operand 1 "" ""))] 11349 "SIBLING_CALL_P (insn)" 11350 "* return ix86_output_call_insn (insn, operands[0]);" 11351 [(set_attr "type" "call")]) 11352 11353(define_expand "call_pop" 11354 [(parallel [(call (match_operand:QI 0 "" "") 11355 (match_operand:SI 1 "" "")) 11356 (set (reg:SI SP_REG) 11357 (plus:SI (reg:SI SP_REG) 11358 (match_operand:SI 3 "" "")))])] 11359 "!TARGET_64BIT" 11360{ 11361 ix86_expand_call (NULL, operands[0], operands[1], 11362 operands[2], operands[3], false); 11363 DONE; 11364}) 11365 11366(define_insn_and_split "*call_pop_vzeroupper" 11367 [(call (mem:QI (match_operand:SI 0 "call_insn_operand" "lzm")) 11368 (match_operand:SI 1 "" "")) 11369 (set (reg:SI SP_REG) 11370 (plus:SI (reg:SI SP_REG) 11371 (match_operand:SI 2 "immediate_operand" "i"))) 11372 (unspec [(match_operand 3 "const_int_operand" "")] 11373 UNSPEC_CALL_NEEDS_VZEROUPPER)] 11374 "TARGET_VZEROUPPER && !TARGET_64BIT && !SIBLING_CALL_P (insn)" 11375 "#" 11376 "&& reload_completed" 11377 [(const_int 0)] 11378 "ix86_split_call_vzeroupper (curr_insn, operands[3]); DONE;" 11379 [(set_attr "type" "call")]) 11380 11381(define_insn "*call_pop" 11382 [(call (mem:QI (match_operand:SI 0 "call_insn_operand" "lzm")) 11383 (match_operand 1 "" "")) 11384 (set (reg:SI SP_REG) 11385 (plus:SI (reg:SI SP_REG) 11386 (match_operand:SI 2 "immediate_operand" "i")))] 11387 "!TARGET_64BIT && !SIBLING_CALL_P (insn)" 11388 "* return ix86_output_call_insn (insn, operands[0]);" 11389 [(set_attr "type" "call")]) 11390 11391(define_insn_and_split "*sibcall_pop_vzeroupper" 11392 [(call (mem:QI (match_operand:SI 0 "sibcall_insn_operand" "Uz")) 11393 (match_operand 1 "" "")) 11394 (set (reg:SI SP_REG) 11395 (plus:SI (reg:SI SP_REG) 11396 (match_operand:SI 2 "immediate_operand" "i"))) 11397 (unspec [(match_operand 3 "const_int_operand" "")] 11398 UNSPEC_CALL_NEEDS_VZEROUPPER)] 11399 "TARGET_VZEROUPPER && !TARGET_64BIT && SIBLING_CALL_P (insn)" 11400 "#" 11401 "&& reload_completed" 11402 [(const_int 0)] 11403 "ix86_split_call_vzeroupper (curr_insn, operands[3]); DONE;" 11404 [(set_attr "type" "call")]) 11405 11406(define_insn "*sibcall_pop" 11407 [(call (mem:QI (match_operand:SI 0 "sibcall_insn_operand" "Uz")) 11408 (match_operand 1 "" "")) 11409 (set (reg:SI SP_REG) 11410 (plus:SI (reg:SI SP_REG) 11411 (match_operand:SI 2 "immediate_operand" "i")))] 11412 "!TARGET_64BIT && SIBLING_CALL_P (insn)" 11413 "* return ix86_output_call_insn (insn, operands[0]);" 11414 [(set_attr "type" "call")]) 11415 11416;; Call subroutine, returning value in operand 0 11417 11418(define_expand "call_value" 11419 [(set (match_operand 0 "" "") 11420 (call (match_operand:QI 1 "" "") 11421 (match_operand 2 "" ""))) 11422 (use (match_operand 3 "" ""))] 11423 "" 11424{ 11425 ix86_expand_call (operands[0], operands[1], operands[2], 11426 operands[3], NULL, false); 11427 DONE; 11428}) 11429 11430(define_expand "sibcall_value" 11431 [(set (match_operand 0 "" "") 11432 (call (match_operand:QI 1 "" "") 11433 (match_operand 2 "" ""))) 11434 (use (match_operand 3 "" ""))] 11435 "" 11436{ 11437 ix86_expand_call (operands[0], operands[1], operands[2], 11438 operands[3], NULL, true); 11439 DONE; 11440}) 11441 11442(define_insn_and_split "*call_value_vzeroupper" 11443 [(set (match_operand 0 "" "") 11444 (call (mem:QI (match_operand:P 1 "call_insn_operand" "<c>zw")) 11445 (match_operand 2 "" ""))) 11446 (unspec [(match_operand 3 "const_int_operand" "")] 11447 UNSPEC_CALL_NEEDS_VZEROUPPER)] 11448 "TARGET_VZEROUPPER && !SIBLING_CALL_P (insn)" 11449 "#" 11450 "&& reload_completed" 11451 [(const_int 0)] 11452 "ix86_split_call_vzeroupper (curr_insn, operands[3]); DONE;" 11453 [(set_attr "type" "callv")]) 11454 11455(define_insn "*call_value" 11456 [(set (match_operand 0 "" "") 11457 (call (mem:QI (match_operand:P 1 "call_insn_operand" "<c>zw")) 11458 (match_operand 2 "" "")))] 11459 "!SIBLING_CALL_P (insn)" 11460 "* return ix86_output_call_insn (insn, operands[1]);" 11461 [(set_attr "type" "callv")]) 11462 11463(define_insn_and_split "*sibcall_value_vzeroupper" 11464 [(set (match_operand 0 "" "") 11465 (call (mem:QI (match_operand:P 1 "sibcall_insn_operand" "Uz")) 11466 (match_operand 2 "" ""))) 11467 (unspec [(match_operand 3 "const_int_operand" "")] 11468 UNSPEC_CALL_NEEDS_VZEROUPPER)] 11469 "TARGET_VZEROUPPER && SIBLING_CALL_P (insn)" 11470 "#" 11471 "&& reload_completed" 11472 [(const_int 0)] 11473 "ix86_split_call_vzeroupper (curr_insn, operands[3]); DONE;" 11474 [(set_attr "type" "callv")]) 11475 11476(define_insn "*sibcall_value" 11477 [(set (match_operand 0 "" "") 11478 (call (mem:QI (match_operand:P 1 "sibcall_insn_operand" "Uz")) 11479 (match_operand 2 "" "")))] 11480 "SIBLING_CALL_P (insn)" 11481 "* return ix86_output_call_insn (insn, operands[1]);" 11482 [(set_attr "type" "callv")]) 11483 11484(define_insn_and_split "*call_value_rex64_ms_sysv_vzeroupper" 11485 [(set (match_operand 0 "" "") 11486 (call (mem:QI (match_operand:DI 1 "call_insn_operand" "rzw")) 11487 (match_operand 2 "" ""))) 11488 (unspec [(const_int 0)] UNSPEC_MS_TO_SYSV_CALL) 11489 (clobber (reg:TI XMM6_REG)) 11490 (clobber (reg:TI XMM7_REG)) 11491 (clobber (reg:TI XMM8_REG)) 11492 (clobber (reg:TI XMM9_REG)) 11493 (clobber (reg:TI XMM10_REG)) 11494 (clobber (reg:TI XMM11_REG)) 11495 (clobber (reg:TI XMM12_REG)) 11496 (clobber (reg:TI XMM13_REG)) 11497 (clobber (reg:TI XMM14_REG)) 11498 (clobber (reg:TI XMM15_REG)) 11499 (clobber (reg:DI SI_REG)) 11500 (clobber (reg:DI DI_REG)) 11501 (unspec [(match_operand 3 "const_int_operand" "")] 11502 UNSPEC_CALL_NEEDS_VZEROUPPER)] 11503 "TARGET_VZEROUPPER && TARGET_64BIT && !SIBLING_CALL_P (insn)" 11504 "#" 11505 "&& reload_completed" 11506 [(const_int 0)] 11507 "ix86_split_call_vzeroupper (curr_insn, operands[3]); DONE;" 11508 [(set_attr "type" "callv")]) 11509 11510(define_insn "*call_value_rex64_ms_sysv" 11511 [(set (match_operand 0 "" "") 11512 (call (mem:QI (match_operand:DI 1 "call_insn_operand" "rzw")) 11513 (match_operand 2 "" ""))) 11514 (unspec [(const_int 0)] UNSPEC_MS_TO_SYSV_CALL) 11515 (clobber (reg:TI XMM6_REG)) 11516 (clobber (reg:TI XMM7_REG)) 11517 (clobber (reg:TI XMM8_REG)) 11518 (clobber (reg:TI XMM9_REG)) 11519 (clobber (reg:TI XMM10_REG)) 11520 (clobber (reg:TI XMM11_REG)) 11521 (clobber (reg:TI XMM12_REG)) 11522 (clobber (reg:TI XMM13_REG)) 11523 (clobber (reg:TI XMM14_REG)) 11524 (clobber (reg:TI XMM15_REG)) 11525 (clobber (reg:DI SI_REG)) 11526 (clobber (reg:DI DI_REG))] 11527 "TARGET_64BIT && !SIBLING_CALL_P (insn)" 11528 "* return ix86_output_call_insn (insn, operands[1]);" 11529 [(set_attr "type" "callv")]) 11530 11531(define_expand "call_value_pop" 11532 [(parallel [(set (match_operand 0 "" "") 11533 (call (match_operand:QI 1 "" "") 11534 (match_operand:SI 2 "" ""))) 11535 (set (reg:SI SP_REG) 11536 (plus:SI (reg:SI SP_REG) 11537 (match_operand:SI 4 "" "")))])] 11538 "!TARGET_64BIT" 11539{ 11540 ix86_expand_call (operands[0], operands[1], operands[2], 11541 operands[3], operands[4], false); 11542 DONE; 11543}) 11544 11545(define_insn_and_split "*call_value_pop_vzeroupper" 11546 [(set (match_operand 0 "" "") 11547 (call (mem:QI (match_operand:SI 1 "call_insn_operand" "lzm")) 11548 (match_operand 2 "" ""))) 11549 (set (reg:SI SP_REG) 11550 (plus:SI (reg:SI SP_REG) 11551 (match_operand:SI 3 "immediate_operand" "i"))) 11552 (unspec [(match_operand 4 "const_int_operand" "")] 11553 UNSPEC_CALL_NEEDS_VZEROUPPER)] 11554 "TARGET_VZEROUPPER && !TARGET_64BIT && !SIBLING_CALL_P (insn)" 11555 "#" 11556 "&& reload_completed" 11557 [(const_int 0)] 11558 "ix86_split_call_vzeroupper (curr_insn, operands[4]); DONE;" 11559 [(set_attr "type" "callv")]) 11560 11561(define_insn "*call_value_pop" 11562 [(set (match_operand 0 "" "") 11563 (call (mem:QI (match_operand:SI 1 "call_insn_operand" "lzm")) 11564 (match_operand 2 "" ""))) 11565 (set (reg:SI SP_REG) 11566 (plus:SI (reg:SI SP_REG) 11567 (match_operand:SI 3 "immediate_operand" "i")))] 11568 "!TARGET_64BIT && !SIBLING_CALL_P (insn)" 11569 "* return ix86_output_call_insn (insn, operands[1]);" 11570 [(set_attr "type" "callv")]) 11571 11572(define_insn_and_split "*sibcall_value_pop_vzeroupper" 11573 [(set (match_operand 0 "" "") 11574 (call (mem:QI (match_operand:SI 1 "sibcall_insn_operand" "Uz")) 11575 (match_operand 2 "" ""))) 11576 (set (reg:SI SP_REG) 11577 (plus:SI (reg:SI SP_REG) 11578 (match_operand:SI 3 "immediate_operand" "i"))) 11579 (unspec [(match_operand 4 "const_int_operand" "")] 11580 UNSPEC_CALL_NEEDS_VZEROUPPER)] 11581 "TARGET_VZEROUPPER && !TARGET_64BIT && SIBLING_CALL_P (insn)" 11582 "#" 11583 "&& reload_completed" 11584 [(const_int 0)] 11585 "ix86_split_call_vzeroupper (curr_insn, operands[4]); DONE;" 11586 [(set_attr "type" "callv")]) 11587 11588(define_insn "*sibcall_value_pop" 11589 [(set (match_operand 0 "" "") 11590 (call (mem:QI (match_operand:SI 1 "sibcall_insn_operand" "Uz")) 11591 (match_operand 2 "" ""))) 11592 (set (reg:SI SP_REG) 11593 (plus:SI (reg:SI SP_REG) 11594 (match_operand:SI 3 "immediate_operand" "i")))] 11595 "!TARGET_64BIT && SIBLING_CALL_P (insn)" 11596 "* return ix86_output_call_insn (insn, operands[1]);" 11597 [(set_attr "type" "callv")]) 11598 11599;; Call subroutine returning any type. 11600 11601(define_expand "untyped_call" 11602 [(parallel [(call (match_operand 0 "" "") 11603 (const_int 0)) 11604 (match_operand 1 "" "") 11605 (match_operand 2 "" "")])] 11606 "" 11607{ 11608 int i; 11609 11610 /* In order to give reg-stack an easier job in validating two 11611 coprocessor registers as containing a possible return value, 11612 simply pretend the untyped call returns a complex long double 11613 value. 11614 11615 We can't use SSE_REGPARM_MAX here since callee is unprototyped 11616 and should have the default ABI. */ 11617 11618 ix86_expand_call ((TARGET_FLOAT_RETURNS_IN_80387 11619 ? gen_rtx_REG (XCmode, FIRST_FLOAT_REG) : NULL), 11620 operands[0], const0_rtx, 11621 GEN_INT ((TARGET_64BIT 11622 ? (ix86_abi == SYSV_ABI 11623 ? X86_64_SSE_REGPARM_MAX 11624 : X86_64_MS_SSE_REGPARM_MAX) 11625 : X86_32_SSE_REGPARM_MAX) 11626 - 1), 11627 NULL, false); 11628 11629 for (i = 0; i < XVECLEN (operands[2], 0); i++) 11630 { 11631 rtx set = XVECEXP (operands[2], 0, i); 11632 emit_move_insn (SET_DEST (set), SET_SRC (set)); 11633 } 11634 11635 /* The optimizer does not know that the call sets the function value 11636 registers we stored in the result block. We avoid problems by 11637 claiming that all hard registers are used and clobbered at this 11638 point. */ 11639 emit_insn (gen_blockage ()); 11640 11641 DONE; 11642}) 11643 11644;; Prologue and epilogue instructions 11645 11646;; UNSPEC_VOLATILE is considered to use and clobber all hard registers and 11647;; all of memory. This blocks insns from being moved across this point. 11648 11649(define_insn "blockage" 11650 [(unspec_volatile [(const_int 0)] UNSPECV_BLOCKAGE)] 11651 "" 11652 "" 11653 [(set_attr "length" "0")]) 11654 11655;; Do not schedule instructions accessing memory across this point. 11656 11657(define_expand "memory_blockage" 11658 [(set (match_dup 0) 11659 (unspec:BLK [(match_dup 0)] UNSPEC_MEMORY_BLOCKAGE))] 11660 "" 11661{ 11662 operands[0] = gen_rtx_MEM (BLKmode, gen_rtx_SCRATCH (Pmode)); 11663 MEM_VOLATILE_P (operands[0]) = 1; 11664}) 11665 11666(define_insn "*memory_blockage" 11667 [(set (match_operand:BLK 0 "" "") 11668 (unspec:BLK [(match_dup 0)] UNSPEC_MEMORY_BLOCKAGE))] 11669 "" 11670 "" 11671 [(set_attr "length" "0")]) 11672 11673;; As USE insns aren't meaningful after reload, this is used instead 11674;; to prevent deleting instructions setting registers for PIC code 11675(define_insn "prologue_use" 11676 [(unspec_volatile [(match_operand 0 "" "")] UNSPECV_PROLOGUE_USE)] 11677 "" 11678 "" 11679 [(set_attr "length" "0")]) 11680 11681;; Insn emitted into the body of a function to return from a function. 11682;; This is only done if the function's epilogue is known to be simple. 11683;; See comments for ix86_can_use_return_insn_p in i386.c. 11684 11685(define_expand "return" 11686 [(simple_return)] 11687 "ix86_can_use_return_insn_p ()" 11688{ 11689 ix86_maybe_emit_epilogue_vzeroupper (); 11690 if (crtl->args.pops_args) 11691 { 11692 rtx popc = GEN_INT (crtl->args.pops_args); 11693 emit_jump_insn (gen_simple_return_pop_internal (popc)); 11694 DONE; 11695 } 11696}) 11697 11698;; We need to disable this for TARGET_SEH, as otherwise 11699;; shrink-wrapped prologue gets enabled too. This might exceed 11700;; the maximum size of prologue in unwind information. 11701 11702(define_expand "simple_return" 11703 [(simple_return)] 11704 "!TARGET_SEH" 11705{ 11706 ix86_maybe_emit_epilogue_vzeroupper (); 11707 if (crtl->args.pops_args) 11708 { 11709 rtx popc = GEN_INT (crtl->args.pops_args); 11710 emit_jump_insn (gen_simple_return_pop_internal (popc)); 11711 DONE; 11712 } 11713}) 11714 11715(define_insn "simple_return_internal" 11716 [(simple_return)] 11717 "reload_completed" 11718 "ret" 11719 [(set_attr "length" "1") 11720 (set_attr "atom_unit" "jeu") 11721 (set_attr "length_immediate" "0") 11722 (set_attr "modrm" "0")]) 11723 11724;; Used by x86_machine_dependent_reorg to avoid penalty on single byte RET 11725;; instruction Athlon and K8 have. 11726 11727(define_insn "simple_return_internal_long" 11728 [(simple_return) 11729 (unspec [(const_int 0)] UNSPEC_REP)] 11730 "reload_completed" 11731 "rep\;ret" 11732 [(set_attr "length" "2") 11733 (set_attr "atom_unit" "jeu") 11734 (set_attr "length_immediate" "0") 11735 (set_attr "prefix_rep" "1") 11736 (set_attr "modrm" "0")]) 11737 11738(define_insn "simple_return_pop_internal" 11739 [(simple_return) 11740 (use (match_operand:SI 0 "const_int_operand" ""))] 11741 "reload_completed" 11742 "ret\t%0" 11743 [(set_attr "length" "3") 11744 (set_attr "atom_unit" "jeu") 11745 (set_attr "length_immediate" "2") 11746 (set_attr "modrm" "0")]) 11747 11748(define_insn "simple_return_indirect_internal" 11749 [(simple_return) 11750 (use (match_operand:SI 0 "register_operand" "r"))] 11751 "reload_completed" 11752 "jmp\t%A0" 11753 [(set_attr "type" "ibr") 11754 (set_attr "length_immediate" "0")]) 11755 11756(define_insn "nop" 11757 [(const_int 0)] 11758 "" 11759 "nop" 11760 [(set_attr "length" "1") 11761 (set_attr "length_immediate" "0") 11762 (set_attr "modrm" "0")]) 11763 11764;; Generate nops. Operand 0 is the number of nops, up to 8. 11765(define_insn "nops" 11766 [(unspec_volatile [(match_operand 0 "const_int_operand" "")] 11767 UNSPECV_NOPS)] 11768 "reload_completed" 11769{ 11770 int num = INTVAL (operands[0]); 11771 11772 gcc_assert (num >= 1 && num <= 8); 11773 11774 while (num--) 11775 fputs ("\tnop\n", asm_out_file); 11776 11777 return ""; 11778} 11779 [(set (attr "length") (symbol_ref "INTVAL (operands[0])")) 11780 (set_attr "length_immediate" "0") 11781 (set_attr "modrm" "0")]) 11782 11783;; Pad to 16-byte boundary, max skip in op0. Used to avoid 11784;; branch prediction penalty for the third jump in a 16-byte 11785;; block on K8. 11786 11787(define_insn "pad" 11788 [(unspec_volatile [(match_operand 0 "" "")] UNSPECV_ALIGN)] 11789 "" 11790{ 11791#ifdef ASM_OUTPUT_MAX_SKIP_PAD 11792 ASM_OUTPUT_MAX_SKIP_PAD (asm_out_file, 4, (int)INTVAL (operands[0])); 11793#else 11794 /* It is tempting to use ASM_OUTPUT_ALIGN here, but we don't want to do that. 11795 The align insn is used to avoid 3 jump instructions in the row to improve 11796 branch prediction and the benefits hardly outweigh the cost of extra 8 11797 nops on the average inserted by full alignment pseudo operation. */ 11798#endif 11799 return ""; 11800} 11801 [(set_attr "length" "16")]) 11802 11803(define_expand "prologue" 11804 [(const_int 0)] 11805 "" 11806 "ix86_expand_prologue (); DONE;") 11807 11808(define_insn "set_got" 11809 [(set (match_operand:SI 0 "register_operand" "=r") 11810 (unspec:SI [(const_int 0)] UNSPEC_SET_GOT)) 11811 (clobber (reg:CC FLAGS_REG))] 11812 "!TARGET_64BIT" 11813 "* return output_set_got (operands[0], NULL_RTX);" 11814 [(set_attr "type" "multi") 11815 (set_attr "length" "12")]) 11816 11817(define_insn "set_got_labelled" 11818 [(set (match_operand:SI 0 "register_operand" "=r") 11819 (unspec:SI [(label_ref (match_operand 1 "" ""))] 11820 UNSPEC_SET_GOT)) 11821 (clobber (reg:CC FLAGS_REG))] 11822 "!TARGET_64BIT" 11823 "* return output_set_got (operands[0], operands[1]);" 11824 [(set_attr "type" "multi") 11825 (set_attr "length" "12")]) 11826 11827(define_insn "set_got_rex64" 11828 [(set (match_operand:DI 0 "register_operand" "=r") 11829 (unspec:DI [(const_int 0)] UNSPEC_SET_GOT))] 11830 "TARGET_64BIT" 11831 "lea{q}\t{_GLOBAL_OFFSET_TABLE_(%%rip), %0|%0, _GLOBAL_OFFSET_TABLE_[rip]}" 11832 [(set_attr "type" "lea") 11833 (set_attr "length_address" "4") 11834 (set_attr "mode" "DI")]) 11835 11836(define_insn "set_rip_rex64" 11837 [(set (match_operand:DI 0 "register_operand" "=r") 11838 (unspec:DI [(label_ref (match_operand 1 "" ""))] UNSPEC_SET_RIP))] 11839 "TARGET_64BIT" 11840 "lea{q}\t{%l1(%%rip), %0|%0, %l1[rip]}" 11841 [(set_attr "type" "lea") 11842 (set_attr "length_address" "4") 11843 (set_attr "mode" "DI")]) 11844 11845(define_insn "set_got_offset_rex64" 11846 [(set (match_operand:DI 0 "register_operand" "=r") 11847 (unspec:DI 11848 [(label_ref (match_operand 1 "" ""))] 11849 UNSPEC_SET_GOT_OFFSET))] 11850 "TARGET_LP64" 11851 "movabs{q}\t{$_GLOBAL_OFFSET_TABLE_-%l1, %0|%0, OFFSET FLAT:_GLOBAL_OFFSET_TABLE_-%l1}" 11852 [(set_attr "type" "imov") 11853 (set_attr "length_immediate" "0") 11854 (set_attr "length_address" "8") 11855 (set_attr "mode" "DI")]) 11856 11857(define_expand "epilogue" 11858 [(const_int 0)] 11859 "" 11860 "ix86_expand_epilogue (1); DONE;") 11861 11862(define_expand "sibcall_epilogue" 11863 [(const_int 0)] 11864 "" 11865 "ix86_expand_epilogue (0); DONE;") 11866 11867(define_expand "eh_return" 11868 [(use (match_operand 0 "register_operand" ""))] 11869 "" 11870{ 11871 rtx tmp, sa = EH_RETURN_STACKADJ_RTX, ra = operands[0]; 11872 11873 /* Tricky bit: we write the address of the handler to which we will 11874 be returning into someone else's stack frame, one word below the 11875 stack address we wish to restore. */ 11876 tmp = gen_rtx_PLUS (Pmode, arg_pointer_rtx, sa); 11877 tmp = plus_constant (tmp, -UNITS_PER_WORD); 11878 tmp = gen_rtx_MEM (Pmode, tmp); 11879 emit_move_insn (tmp, ra); 11880 11881 emit_jump_insn (gen_eh_return_internal ()); 11882 emit_barrier (); 11883 DONE; 11884}) 11885 11886(define_insn_and_split "eh_return_internal" 11887 [(eh_return)] 11888 "" 11889 "#" 11890 "epilogue_completed" 11891 [(const_int 0)] 11892 "ix86_expand_epilogue (2); DONE;") 11893 11894(define_insn "leave" 11895 [(set (reg:SI SP_REG) (plus:SI (reg:SI BP_REG) (const_int 4))) 11896 (set (reg:SI BP_REG) (mem:SI (reg:SI BP_REG))) 11897 (clobber (mem:BLK (scratch)))] 11898 "!TARGET_64BIT" 11899 "leave" 11900 [(set_attr "type" "leave")]) 11901 11902(define_insn "leave_rex64" 11903 [(set (reg:DI SP_REG) (plus:DI (reg:DI BP_REG) (const_int 8))) 11904 (set (reg:DI BP_REG) (mem:DI (reg:DI BP_REG))) 11905 (clobber (mem:BLK (scratch)))] 11906 "TARGET_64BIT" 11907 "leave" 11908 [(set_attr "type" "leave")]) 11909 11910;; Handle -fsplit-stack. 11911 11912(define_expand "split_stack_prologue" 11913 [(const_int 0)] 11914 "" 11915{ 11916 ix86_expand_split_stack_prologue (); 11917 DONE; 11918}) 11919 11920;; In order to support the call/return predictor, we use a return 11921;; instruction which the middle-end doesn't see. 11922(define_insn "split_stack_return" 11923 [(unspec_volatile [(match_operand:SI 0 "const_int_operand" "")] 11924 UNSPECV_SPLIT_STACK_RETURN)] 11925 "" 11926{ 11927 if (operands[0] == const0_rtx) 11928 return "ret"; 11929 else 11930 return "ret\t%0"; 11931} 11932 [(set_attr "atom_unit" "jeu") 11933 (set_attr "modrm" "0") 11934 (set (attr "length") 11935 (if_then_else (match_operand:SI 0 "const0_operand" "") 11936 (const_int 1) 11937 (const_int 3))) 11938 (set (attr "length_immediate") 11939 (if_then_else (match_operand:SI 0 "const0_operand" "") 11940 (const_int 0) 11941 (const_int 2)))]) 11942 11943;; If there are operand 0 bytes available on the stack, jump to 11944;; operand 1. 11945 11946(define_expand "split_stack_space_check" 11947 [(set (pc) (if_then_else 11948 (ltu (minus (reg SP_REG) 11949 (match_operand 0 "register_operand" "")) 11950 (unspec [(const_int 0)] UNSPEC_STACK_CHECK)) 11951 (label_ref (match_operand 1 "" "")) 11952 (pc)))] 11953 "" 11954{ 11955 rtx reg, size, limit; 11956 11957 reg = gen_reg_rtx (Pmode); 11958 size = force_reg (Pmode, operands[0]); 11959 emit_insn (gen_sub3_insn (reg, stack_pointer_rtx, size)); 11960 limit = gen_rtx_UNSPEC (Pmode, gen_rtvec (1, const0_rtx), 11961 UNSPEC_STACK_CHECK); 11962 limit = gen_rtx_MEM (Pmode, gen_rtx_CONST (Pmode, limit)); 11963 ix86_expand_branch (GEU, reg, limit, operands[1]); 11964 11965 DONE; 11966}) 11967 11968;; Bit manipulation instructions. 11969 11970(define_expand "ffs<mode>2" 11971 [(set (match_dup 2) (const_int -1)) 11972 (parallel [(set (reg:CCZ FLAGS_REG) 11973 (compare:CCZ 11974 (match_operand:SWI48 1 "nonimmediate_operand" "") 11975 (const_int 0))) 11976 (set (match_operand:SWI48 0 "register_operand" "") 11977 (ctz:SWI48 (match_dup 1)))]) 11978 (set (match_dup 0) (if_then_else:SWI48 11979 (eq (reg:CCZ FLAGS_REG) (const_int 0)) 11980 (match_dup 2) 11981 (match_dup 0))) 11982 (parallel [(set (match_dup 0) (plus:SWI48 (match_dup 0) (const_int 1))) 11983 (clobber (reg:CC FLAGS_REG))])] 11984 "" 11985{ 11986 if (<MODE>mode == SImode && !TARGET_CMOVE) 11987 { 11988 emit_insn (gen_ffssi2_no_cmove (operands[0], operands [1])); 11989 DONE; 11990 } 11991 operands[2] = gen_reg_rtx (<MODE>mode); 11992}) 11993 11994(define_insn_and_split "ffssi2_no_cmove" 11995 [(set (match_operand:SI 0 "register_operand" "=r") 11996 (ffs:SI (match_operand:SI 1 "nonimmediate_operand" "rm"))) 11997 (clobber (match_scratch:SI 2 "=&q")) 11998 (clobber (reg:CC FLAGS_REG))] 11999 "!TARGET_CMOVE" 12000 "#" 12001 "&& reload_completed" 12002 [(parallel [(set (reg:CCZ FLAGS_REG) 12003 (compare:CCZ (match_dup 1) (const_int 0))) 12004 (set (match_dup 0) (ctz:SI (match_dup 1)))]) 12005 (set (strict_low_part (match_dup 3)) 12006 (eq:QI (reg:CCZ FLAGS_REG) (const_int 0))) 12007 (parallel [(set (match_dup 2) (neg:SI (match_dup 2))) 12008 (clobber (reg:CC FLAGS_REG))]) 12009 (parallel [(set (match_dup 0) (ior:SI (match_dup 0) (match_dup 2))) 12010 (clobber (reg:CC FLAGS_REG))]) 12011 (parallel [(set (match_dup 0) (plus:SI (match_dup 0) (const_int 1))) 12012 (clobber (reg:CC FLAGS_REG))])] 12013{ 12014 operands[3] = gen_lowpart (QImode, operands[2]); 12015 ix86_expand_clear (operands[2]); 12016}) 12017 12018(define_insn "*ffs<mode>_1" 12019 [(set (reg:CCZ FLAGS_REG) 12020 (compare:CCZ (match_operand:SWI48 1 "nonimmediate_operand" "rm") 12021 (const_int 0))) 12022 (set (match_operand:SWI48 0 "register_operand" "=r") 12023 (ctz:SWI48 (match_dup 1)))] 12024 "" 12025 "bsf{<imodesuffix>}\t{%1, %0|%0, %1}" 12026 [(set_attr "type" "alu1") 12027 (set_attr "prefix_0f" "1") 12028 (set_attr "mode" "<MODE>")]) 12029 12030(define_insn "ctz<mode>2" 12031 [(set (match_operand:SWI248 0 "register_operand" "=r") 12032 (ctz:SWI248 (match_operand:SWI248 1 "nonimmediate_operand" "rm"))) 12033 (clobber (reg:CC FLAGS_REG))] 12034 "" 12035{ 12036 if (TARGET_BMI) 12037 return "tzcnt{<imodesuffix>}\t{%1, %0|%0, %1}"; 12038 else 12039 return "bsf{<imodesuffix>}\t{%1, %0|%0, %1}"; 12040} 12041 [(set_attr "type" "alu1") 12042 (set_attr "prefix_0f" "1") 12043 (set (attr "prefix_rep") (symbol_ref "TARGET_BMI")) 12044 (set_attr "mode" "<MODE>")]) 12045 12046(define_expand "clz<mode>2" 12047 [(parallel 12048 [(set (match_operand:SWI248 0 "register_operand" "") 12049 (minus:SWI248 12050 (match_dup 2) 12051 (clz:SWI248 (match_operand:SWI248 1 "nonimmediate_operand" "")))) 12052 (clobber (reg:CC FLAGS_REG))]) 12053 (parallel 12054 [(set (match_dup 0) (xor:SWI248 (match_dup 0) (match_dup 2))) 12055 (clobber (reg:CC FLAGS_REG))])] 12056 "" 12057{ 12058 if (TARGET_LZCNT) 12059 { 12060 emit_insn (gen_clz<mode>2_lzcnt (operands[0], operands[1])); 12061 DONE; 12062 } 12063 operands[2] = GEN_INT (GET_MODE_BITSIZE (<MODE>mode)-1); 12064}) 12065 12066(define_insn "clz<mode>2_lzcnt" 12067 [(set (match_operand:SWI248 0 "register_operand" "=r") 12068 (clz:SWI248 (match_operand:SWI248 1 "nonimmediate_operand" "rm"))) 12069 (clobber (reg:CC FLAGS_REG))] 12070 "TARGET_LZCNT" 12071 "lzcnt{<imodesuffix>}\t{%1, %0|%0, %1}" 12072 [(set_attr "prefix_rep" "1") 12073 (set_attr "type" "bitmanip") 12074 (set_attr "mode" "<MODE>")]) 12075 12076;; BMI instructions. 12077(define_insn "*bmi_andn_<mode>" 12078 [(set (match_operand:SWI48 0 "register_operand" "=r") 12079 (and:SWI48 12080 (not:SWI48 12081 (match_operand:SWI48 1 "register_operand" "r")) 12082 (match_operand:SWI48 2 "nonimmediate_operand" "rm"))) 12083 (clobber (reg:CC FLAGS_REG))] 12084 "TARGET_BMI" 12085 "andn\t{%2, %1, %0|%0, %1, %2}" 12086 [(set_attr "type" "bitmanip") 12087 (set_attr "mode" "<MODE>")]) 12088 12089(define_insn "bmi_bextr_<mode>" 12090 [(set (match_operand:SWI48 0 "register_operand" "=r") 12091 (unspec:SWI48 [(match_operand:SWI48 1 "nonimmediate_operand" "rm") 12092 (match_operand:SWI48 2 "register_operand" "r")] 12093 UNSPEC_BEXTR)) 12094 (clobber (reg:CC FLAGS_REG))] 12095 "TARGET_BMI" 12096 "bextr\t{%2, %1, %0|%0, %1, %2}" 12097 [(set_attr "type" "bitmanip") 12098 (set_attr "mode" "<MODE>")]) 12099 12100(define_insn "*bmi_blsi_<mode>" 12101 [(set (match_operand:SWI48 0 "register_operand" "=r") 12102 (and:SWI48 12103 (neg:SWI48 12104 (match_operand:SWI48 1 "nonimmediate_operand" "rm")) 12105 (match_dup 1))) 12106 (clobber (reg:CC FLAGS_REG))] 12107 "TARGET_BMI" 12108 "blsi\t{%1, %0|%0, %1}" 12109 [(set_attr "type" "bitmanip") 12110 (set_attr "mode" "<MODE>")]) 12111 12112(define_insn "*bmi_blsmsk_<mode>" 12113 [(set (match_operand:SWI48 0 "register_operand" "=r") 12114 (xor:SWI48 12115 (plus:SWI48 12116 (match_operand:SWI48 1 "nonimmediate_operand" "rm") 12117 (const_int -1)) 12118 (match_dup 1))) 12119 (clobber (reg:CC FLAGS_REG))] 12120 "TARGET_BMI" 12121 "blsmsk\t{%1, %0|%0, %1}" 12122 [(set_attr "type" "bitmanip") 12123 (set_attr "mode" "<MODE>")]) 12124 12125(define_insn "*bmi_blsr_<mode>" 12126 [(set (match_operand:SWI48 0 "register_operand" "=r") 12127 (and:SWI48 12128 (plus:SWI48 12129 (match_operand:SWI48 1 "nonimmediate_operand" "rm") 12130 (const_int -1)) 12131 (match_dup 1))) 12132 (clobber (reg:CC FLAGS_REG))] 12133 "TARGET_BMI" 12134 "blsr\t{%1, %0|%0, %1}" 12135 [(set_attr "type" "bitmanip") 12136 (set_attr "mode" "<MODE>")]) 12137 12138;; BMI2 instructions. 12139(define_insn "bmi2_bzhi_<mode>3" 12140 [(set (match_operand:SWI48 0 "register_operand" "=r") 12141 (and:SWI48 (lshiftrt:SWI48 (const_int -1) 12142 (match_operand:SWI48 2 "register_operand" "r")) 12143 (match_operand:SWI48 1 "nonimmediate_operand" "rm"))) 12144 (clobber (reg:CC FLAGS_REG))] 12145 "TARGET_BMI2" 12146 "bzhi\t{%2, %1, %0|%0, %1, %2}" 12147 [(set_attr "type" "bitmanip") 12148 (set_attr "prefix" "vex") 12149 (set_attr "mode" "<MODE>")]) 12150 12151(define_insn "bmi2_pdep_<mode>3" 12152 [(set (match_operand:SWI48 0 "register_operand" "=r") 12153 (unspec:SWI48 [(match_operand:SWI48 1 "register_operand" "r") 12154 (match_operand:SWI48 2 "nonimmediate_operand" "rm")] 12155 UNSPEC_PDEP))] 12156 "TARGET_BMI2" 12157 "pdep\t{%2, %1, %0|%0, %1, %2}" 12158 [(set_attr "type" "bitmanip") 12159 (set_attr "prefix" "vex") 12160 (set_attr "mode" "<MODE>")]) 12161 12162(define_insn "bmi2_pext_<mode>3" 12163 [(set (match_operand:SWI48 0 "register_operand" "=r") 12164 (unspec:SWI48 [(match_operand:SWI48 1 "register_operand" "r") 12165 (match_operand:SWI48 2 "nonimmediate_operand" "rm")] 12166 UNSPEC_PEXT))] 12167 "TARGET_BMI2" 12168 "pext\t{%2, %1, %0|%0, %1, %2}" 12169 [(set_attr "type" "bitmanip") 12170 (set_attr "prefix" "vex") 12171 (set_attr "mode" "<MODE>")]) 12172 12173;; TBM instructions. 12174(define_insn "tbm_bextri_<mode>" 12175 [(set (match_operand:SWI48 0 "register_operand" "=r") 12176 (zero_extract:SWI48 12177 (match_operand:SWI48 1 "nonimmediate_operand" "rm") 12178 (match_operand:SWI48 2 "const_0_to_255_operand" "n") 12179 (match_operand:SWI48 3 "const_0_to_255_operand" "n"))) 12180 (clobber (reg:CC FLAGS_REG))] 12181 "TARGET_TBM" 12182{ 12183 operands[2] = GEN_INT (INTVAL (operands[2]) << 8 | INTVAL (operands[3])); 12184 return "bextr\t{%2, %1, %0|%0, %1, %2}"; 12185} 12186 [(set_attr "type" "bitmanip") 12187 (set_attr "mode" "<MODE>")]) 12188 12189(define_insn "*tbm_blcfill_<mode>" 12190 [(set (match_operand:SWI48 0 "register_operand" "=r") 12191 (and:SWI48 12192 (plus:SWI48 12193 (match_operand:SWI48 1 "nonimmediate_operand" "rm") 12194 (const_int 1)) 12195 (match_dup 1))) 12196 (clobber (reg:CC FLAGS_REG))] 12197 "TARGET_TBM" 12198 "blcfill\t{%1, %0|%0, %1}" 12199 [(set_attr "type" "bitmanip") 12200 (set_attr "mode" "<MODE>")]) 12201 12202(define_insn "*tbm_blci_<mode>" 12203 [(set (match_operand:SWI48 0 "register_operand" "=r") 12204 (ior:SWI48 12205 (not:SWI48 12206 (plus:SWI48 12207 (match_operand:SWI48 1 "nonimmediate_operand" "rm") 12208 (const_int 1))) 12209 (match_dup 1))) 12210 (clobber (reg:CC FLAGS_REG))] 12211 "TARGET_TBM" 12212 "blci\t{%1, %0|%0, %1}" 12213 [(set_attr "type" "bitmanip") 12214 (set_attr "mode" "<MODE>")]) 12215 12216(define_insn "*tbm_blcic_<mode>" 12217 [(set (match_operand:SWI48 0 "register_operand" "=r") 12218 (and:SWI48 12219 (plus:SWI48 12220 (match_operand:SWI48 1 "nonimmediate_operand" "rm") 12221 (const_int 1)) 12222 (not:SWI48 12223 (match_dup 1)))) 12224 (clobber (reg:CC FLAGS_REG))] 12225 "TARGET_TBM" 12226 "blcic\t{%1, %0|%0, %1}" 12227 [(set_attr "type" "bitmanip") 12228 (set_attr "mode" "<MODE>")]) 12229 12230(define_insn "*tbm_blcmsk_<mode>" 12231 [(set (match_operand:SWI48 0 "register_operand" "=r") 12232 (xor:SWI48 12233 (plus:SWI48 12234 (match_operand:SWI48 1 "nonimmediate_operand" "rm") 12235 (const_int 1)) 12236 (match_dup 1))) 12237 (clobber (reg:CC FLAGS_REG))] 12238 "TARGET_TBM" 12239 "blcmsk\t{%1, %0|%0, %1}" 12240 [(set_attr "type" "bitmanip") 12241 (set_attr "mode" "<MODE>")]) 12242 12243(define_insn "*tbm_blcs_<mode>" 12244 [(set (match_operand:SWI48 0 "register_operand" "=r") 12245 (ior:SWI48 12246 (plus:SWI48 12247 (match_operand:SWI48 1 "nonimmediate_operand" "rm") 12248 (const_int 1)) 12249 (match_dup 1))) 12250 (clobber (reg:CC FLAGS_REG))] 12251 "TARGET_TBM" 12252 "blcs\t{%1, %0|%0, %1}" 12253 [(set_attr "type" "bitmanip") 12254 (set_attr "mode" "<MODE>")]) 12255 12256(define_insn "*tbm_blsfill_<mode>" 12257 [(set (match_operand:SWI48 0 "register_operand" "=r") 12258 (ior:SWI48 12259 (plus:SWI48 12260 (match_operand:SWI48 1 "nonimmediate_operand" "rm") 12261 (const_int -1)) 12262 (match_dup 1))) 12263 (clobber (reg:CC FLAGS_REG))] 12264 "TARGET_TBM" 12265 "blsfill\t{%1, %0|%0, %1}" 12266 [(set_attr "type" "bitmanip") 12267 (set_attr "mode" "<MODE>")]) 12268 12269(define_insn "*tbm_blsic_<mode>" 12270 [(set (match_operand:SWI48 0 "register_operand" "=r") 12271 (ior:SWI48 12272 (plus:SWI48 12273 (match_operand:SWI48 1 "nonimmediate_operand" "rm") 12274 (const_int -1)) 12275 (not:SWI48 12276 (match_dup 1)))) 12277 (clobber (reg:CC FLAGS_REG))] 12278 "TARGET_TBM" 12279 "blsic\t{%1, %0|%0, %1}" 12280 [(set_attr "type" "bitmanip") 12281 (set_attr "mode" "<MODE>")]) 12282 12283(define_insn "*tbm_t1mskc_<mode>" 12284 [(set (match_operand:SWI48 0 "register_operand" "=r") 12285 (ior:SWI48 12286 (plus:SWI48 12287 (match_operand:SWI48 1 "nonimmediate_operand" "rm") 12288 (const_int 1)) 12289 (not:SWI48 12290 (match_dup 1)))) 12291 (clobber (reg:CC FLAGS_REG))] 12292 "TARGET_TBM" 12293 "t1mskc\t{%1, %0|%0, %1}" 12294 [(set_attr "type" "bitmanip") 12295 (set_attr "mode" "<MODE>")]) 12296 12297(define_insn "*tbm_tzmsk_<mode>" 12298 [(set (match_operand:SWI48 0 "register_operand" "=r") 12299 (and:SWI48 12300 (plus:SWI48 12301 (match_operand:SWI48 1 "nonimmediate_operand" "rm") 12302 (const_int -1)) 12303 (not:SWI48 12304 (match_dup 1)))) 12305 (clobber (reg:CC FLAGS_REG))] 12306 "TARGET_TBM" 12307 "tzmsk\t{%1, %0|%0, %1}" 12308 [(set_attr "type" "bitmanip") 12309 (set_attr "mode" "<MODE>")]) 12310 12311(define_insn "bsr_rex64" 12312 [(set (match_operand:DI 0 "register_operand" "=r") 12313 (minus:DI (const_int 63) 12314 (clz:DI (match_operand:DI 1 "nonimmediate_operand" "rm")))) 12315 (clobber (reg:CC FLAGS_REG))] 12316 "TARGET_64BIT" 12317 "bsr{q}\t{%1, %0|%0, %1}" 12318 [(set_attr "type" "alu1") 12319 (set_attr "prefix_0f" "1") 12320 (set_attr "mode" "DI")]) 12321 12322(define_insn "bsr" 12323 [(set (match_operand:SI 0 "register_operand" "=r") 12324 (minus:SI (const_int 31) 12325 (clz:SI (match_operand:SI 1 "nonimmediate_operand" "rm")))) 12326 (clobber (reg:CC FLAGS_REG))] 12327 "" 12328 "bsr{l}\t{%1, %0|%0, %1}" 12329 [(set_attr "type" "alu1") 12330 (set_attr "prefix_0f" "1") 12331 (set_attr "mode" "SI")]) 12332 12333(define_insn "*bsrhi" 12334 [(set (match_operand:HI 0 "register_operand" "=r") 12335 (minus:HI (const_int 15) 12336 (clz:HI (match_operand:HI 1 "nonimmediate_operand" "rm")))) 12337 (clobber (reg:CC FLAGS_REG))] 12338 "" 12339 "bsr{w}\t{%1, %0|%0, %1}" 12340 [(set_attr "type" "alu1") 12341 (set_attr "prefix_0f" "1") 12342 (set_attr "mode" "HI")]) 12343 12344(define_insn "popcount<mode>2" 12345 [(set (match_operand:SWI248 0 "register_operand" "=r") 12346 (popcount:SWI248 12347 (match_operand:SWI248 1 "nonimmediate_operand" "rm"))) 12348 (clobber (reg:CC FLAGS_REG))] 12349 "TARGET_POPCNT" 12350{ 12351#if TARGET_MACHO 12352 return "popcnt\t{%1, %0|%0, %1}"; 12353#else 12354 return "popcnt{<imodesuffix>}\t{%1, %0|%0, %1}"; 12355#endif 12356} 12357 [(set_attr "prefix_rep" "1") 12358 (set_attr "type" "bitmanip") 12359 (set_attr "mode" "<MODE>")]) 12360 12361(define_insn "*popcount<mode>2_cmp" 12362 [(set (reg FLAGS_REG) 12363 (compare 12364 (popcount:SWI248 12365 (match_operand:SWI248 1 "nonimmediate_operand" "rm")) 12366 (const_int 0))) 12367 (set (match_operand:SWI248 0 "register_operand" "=r") 12368 (popcount:SWI248 (match_dup 1)))] 12369 "TARGET_POPCNT && ix86_match_ccmode (insn, CCZmode)" 12370{ 12371#if TARGET_MACHO 12372 return "popcnt\t{%1, %0|%0, %1}"; 12373#else 12374 return "popcnt{<imodesuffix>}\t{%1, %0|%0, %1}"; 12375#endif 12376} 12377 [(set_attr "prefix_rep" "1") 12378 (set_attr "type" "bitmanip") 12379 (set_attr "mode" "<MODE>")]) 12380 12381(define_insn "*popcountsi2_cmp_zext" 12382 [(set (reg FLAGS_REG) 12383 (compare 12384 (popcount:SI (match_operand:SI 1 "nonimmediate_operand" "rm")) 12385 (const_int 0))) 12386 (set (match_operand:DI 0 "register_operand" "=r") 12387 (zero_extend:DI(popcount:SI (match_dup 1))))] 12388 "TARGET_64BIT && TARGET_POPCNT && ix86_match_ccmode (insn, CCZmode)" 12389{ 12390#if TARGET_MACHO 12391 return "popcnt\t{%1, %0|%0, %1}"; 12392#else 12393 return "popcnt{l}\t{%1, %0|%0, %1}"; 12394#endif 12395} 12396 [(set_attr "prefix_rep" "1") 12397 (set_attr "type" "bitmanip") 12398 (set_attr "mode" "SI")]) 12399 12400(define_expand "bswap<mode>2" 12401 [(set (match_operand:SWI48 0 "register_operand" "") 12402 (bswap:SWI48 (match_operand:SWI48 1 "register_operand" "")))] 12403 "" 12404{ 12405 if (<MODE>mode == SImode && !(TARGET_BSWAP || TARGET_MOVBE)) 12406 { 12407 rtx x = operands[0]; 12408 12409 emit_move_insn (x, operands[1]); 12410 emit_insn (gen_bswaphi_lowpart (gen_lowpart (HImode, x))); 12411 emit_insn (gen_rotlsi3 (x, x, GEN_INT (16))); 12412 emit_insn (gen_bswaphi_lowpart (gen_lowpart (HImode, x))); 12413 DONE; 12414 } 12415}) 12416 12417(define_insn "*bswap<mode>2_movbe" 12418 [(set (match_operand:SWI48 0 "nonimmediate_operand" "=r,r,m") 12419 (bswap:SWI48 (match_operand:SWI48 1 "nonimmediate_operand" "0,m,r")))] 12420 "TARGET_MOVBE 12421 && !(MEM_P (operands[0]) && MEM_P (operands[1]))" 12422 "@ 12423 bswap\t%0 12424 movbe\t{%1, %0|%0, %1} 12425 movbe\t{%1, %0|%0, %1}" 12426 [(set_attr "type" "bitmanip,imov,imov") 12427 (set_attr "modrm" "0,1,1") 12428 (set_attr "prefix_0f" "*,1,1") 12429 (set_attr "prefix_extra" "*,1,1") 12430 (set_attr "mode" "<MODE>")]) 12431 12432(define_insn "*bswap<mode>2_1" 12433 [(set (match_operand:SWI48 0 "register_operand" "=r") 12434 (bswap:SWI48 (match_operand:SWI48 1 "register_operand" "0")))] 12435 "TARGET_BSWAP" 12436 "bswap\t%0" 12437 [(set_attr "type" "bitmanip") 12438 (set_attr "modrm" "0") 12439 (set_attr "mode" "<MODE>")]) 12440 12441(define_insn "*bswaphi_lowpart_1" 12442 [(set (strict_low_part (match_operand:HI 0 "register_operand" "+Q,r")) 12443 (bswap:HI (match_dup 0))) 12444 (clobber (reg:CC FLAGS_REG))] 12445 "TARGET_USE_XCHGB || optimize_function_for_size_p (cfun)" 12446 "@ 12447 xchg{b}\t{%h0, %b0|%b0, %h0} 12448 rol{w}\t{$8, %0|%0, 8}" 12449 [(set_attr "length" "2,4") 12450 (set_attr "mode" "QI,HI")]) 12451 12452(define_insn "bswaphi_lowpart" 12453 [(set (strict_low_part (match_operand:HI 0 "register_operand" "+r")) 12454 (bswap:HI (match_dup 0))) 12455 (clobber (reg:CC FLAGS_REG))] 12456 "" 12457 "rol{w}\t{$8, %0|%0, 8}" 12458 [(set_attr "length" "4") 12459 (set_attr "mode" "HI")]) 12460 12461(define_expand "paritydi2" 12462 [(set (match_operand:DI 0 "register_operand" "") 12463 (parity:DI (match_operand:DI 1 "register_operand" "")))] 12464 "! TARGET_POPCNT" 12465{ 12466 rtx scratch = gen_reg_rtx (QImode); 12467 rtx cond; 12468 12469 emit_insn (gen_paritydi2_cmp (NULL_RTX, NULL_RTX, 12470 NULL_RTX, operands[1])); 12471 12472 cond = gen_rtx_fmt_ee (ORDERED, QImode, 12473 gen_rtx_REG (CCmode, FLAGS_REG), 12474 const0_rtx); 12475 emit_insn (gen_rtx_SET (VOIDmode, scratch, cond)); 12476 12477 if (TARGET_64BIT) 12478 emit_insn (gen_zero_extendqidi2 (operands[0], scratch)); 12479 else 12480 { 12481 rtx tmp = gen_reg_rtx (SImode); 12482 12483 emit_insn (gen_zero_extendqisi2 (tmp, scratch)); 12484 emit_insn (gen_zero_extendsidi2 (operands[0], tmp)); 12485 } 12486 DONE; 12487}) 12488 12489(define_expand "paritysi2" 12490 [(set (match_operand:SI 0 "register_operand" "") 12491 (parity:SI (match_operand:SI 1 "register_operand" "")))] 12492 "! TARGET_POPCNT" 12493{ 12494 rtx scratch = gen_reg_rtx (QImode); 12495 rtx cond; 12496 12497 emit_insn (gen_paritysi2_cmp (NULL_RTX, NULL_RTX, operands[1])); 12498 12499 cond = gen_rtx_fmt_ee (ORDERED, QImode, 12500 gen_rtx_REG (CCmode, FLAGS_REG), 12501 const0_rtx); 12502 emit_insn (gen_rtx_SET (VOIDmode, scratch, cond)); 12503 12504 emit_insn (gen_zero_extendqisi2 (operands[0], scratch)); 12505 DONE; 12506}) 12507 12508(define_insn_and_split "paritydi2_cmp" 12509 [(set (reg:CC FLAGS_REG) 12510 (unspec:CC [(match_operand:DI 3 "register_operand" "0")] 12511 UNSPEC_PARITY)) 12512 (clobber (match_scratch:DI 0 "=r")) 12513 (clobber (match_scratch:SI 1 "=&r")) 12514 (clobber (match_scratch:HI 2 "=Q"))] 12515 "! TARGET_POPCNT" 12516 "#" 12517 "&& reload_completed" 12518 [(parallel 12519 [(set (match_dup 1) 12520 (xor:SI (match_dup 1) (match_dup 4))) 12521 (clobber (reg:CC FLAGS_REG))]) 12522 (parallel 12523 [(set (reg:CC FLAGS_REG) 12524 (unspec:CC [(match_dup 1)] UNSPEC_PARITY)) 12525 (clobber (match_dup 1)) 12526 (clobber (match_dup 2))])] 12527{ 12528 operands[4] = gen_lowpart (SImode, operands[3]); 12529 12530 if (TARGET_64BIT) 12531 { 12532 emit_move_insn (operands[1], gen_lowpart (SImode, operands[3])); 12533 emit_insn (gen_lshrdi3 (operands[3], operands[3], GEN_INT (32))); 12534 } 12535 else 12536 operands[1] = gen_highpart (SImode, operands[3]); 12537}) 12538 12539(define_insn_and_split "paritysi2_cmp" 12540 [(set (reg:CC FLAGS_REG) 12541 (unspec:CC [(match_operand:SI 2 "register_operand" "0")] 12542 UNSPEC_PARITY)) 12543 (clobber (match_scratch:SI 0 "=r")) 12544 (clobber (match_scratch:HI 1 "=&Q"))] 12545 "! TARGET_POPCNT" 12546 "#" 12547 "&& reload_completed" 12548 [(parallel 12549 [(set (match_dup 1) 12550 (xor:HI (match_dup 1) (match_dup 3))) 12551 (clobber (reg:CC FLAGS_REG))]) 12552 (parallel 12553 [(set (reg:CC FLAGS_REG) 12554 (unspec:CC [(match_dup 1)] UNSPEC_PARITY)) 12555 (clobber (match_dup 1))])] 12556{ 12557 operands[3] = gen_lowpart (HImode, operands[2]); 12558 12559 emit_move_insn (operands[1], gen_lowpart (HImode, operands[2])); 12560 emit_insn (gen_lshrsi3 (operands[2], operands[2], GEN_INT (16))); 12561}) 12562 12563(define_insn "*parityhi2_cmp" 12564 [(set (reg:CC FLAGS_REG) 12565 (unspec:CC [(match_operand:HI 1 "register_operand" "0")] 12566 UNSPEC_PARITY)) 12567 (clobber (match_scratch:HI 0 "=Q"))] 12568 "! TARGET_POPCNT" 12569 "xor{b}\t{%h0, %b0|%b0, %h0}" 12570 [(set_attr "length" "2") 12571 (set_attr "mode" "HI")]) 12572 12573 12574;; Thread-local storage patterns for ELF. 12575;; 12576;; Note that these code sequences must appear exactly as shown 12577;; in order to allow linker relaxation. 12578 12579(define_insn "*tls_global_dynamic_32_gnu" 12580 [(set (match_operand:SI 0 "register_operand" "=a") 12581 (unspec:SI 12582 [(match_operand:SI 1 "register_operand" "b") 12583 (match_operand:SI 2 "tls_symbolic_operand" "") 12584 (match_operand:SI 3 "constant_call_address_operand" "z")] 12585 UNSPEC_TLS_GD)) 12586 (clobber (match_scratch:SI 4 "=d")) 12587 (clobber (match_scratch:SI 5 "=c")) 12588 (clobber (reg:CC FLAGS_REG))] 12589 "!TARGET_64BIT && TARGET_GNU_TLS" 12590{ 12591 output_asm_insn 12592 ("lea{l}\t{%E2@tlsgd(,%1,1), %0|%0, %E2@tlsgd[%1*1]}", operands); 12593 if (TARGET_SUN_TLS) 12594#ifdef HAVE_AS_IX86_TLSGDPLT 12595 return "call\t%a2@tlsgdplt"; 12596#else 12597 return "call\t%p3@plt"; 12598#endif 12599 return "call\t%P3"; 12600} 12601 [(set_attr "type" "multi") 12602 (set_attr "length" "12")]) 12603 12604(define_expand "tls_global_dynamic_32" 12605 [(parallel 12606 [(set (match_operand:SI 0 "register_operand" "") 12607 (unspec:SI [(match_operand:SI 2 "register_operand" "") 12608 (match_operand:SI 1 "tls_symbolic_operand" "") 12609 (match_operand:SI 3 "constant_call_address_operand" "")] 12610 UNSPEC_TLS_GD)) 12611 (clobber (match_scratch:SI 4 "")) 12612 (clobber (match_scratch:SI 5 "")) 12613 (clobber (reg:CC FLAGS_REG))])]) 12614 12615(define_insn "*tls_global_dynamic_64" 12616 [(set (match_operand:DI 0 "register_operand" "=a") 12617 (call:DI 12618 (mem:QI (match_operand:DI 2 "constant_call_address_operand" "z")) 12619 (match_operand:DI 3 "" ""))) 12620 (unspec:DI [(match_operand 1 "tls_symbolic_operand" "")] 12621 UNSPEC_TLS_GD)] 12622 "TARGET_64BIT" 12623{ 12624 if (!TARGET_X32) 12625 fputs (ASM_BYTE "0x66\n", asm_out_file); 12626 output_asm_insn 12627 ("lea{q}\t{%E1@tlsgd(%%rip), %%rdi|rdi, %E1@tlsgd[rip]}", operands); 12628 fputs (ASM_SHORT "0x6666\n", asm_out_file); 12629 fputs ("\trex64\n", asm_out_file); 12630 if (TARGET_SUN_TLS) 12631 return "call\t%p2@plt"; 12632 return "call\t%P2"; 12633} 12634 [(set_attr "type" "multi") 12635 (set (attr "length") 12636 (symbol_ref "TARGET_X32 ? 15 : 16"))]) 12637 12638(define_expand "tls_global_dynamic_64" 12639 [(parallel 12640 [(set (match_operand:DI 0 "register_operand" "") 12641 (call:DI 12642 (mem:QI (match_operand:DI 2 "constant_call_address_operand" "")) 12643 (const_int 0))) 12644 (unspec:DI [(match_operand 1 "tls_symbolic_operand" "")] 12645 UNSPEC_TLS_GD)])]) 12646 12647(define_insn "*tls_local_dynamic_base_32_gnu" 12648 [(set (match_operand:SI 0 "register_operand" "=a") 12649 (unspec:SI 12650 [(match_operand:SI 1 "register_operand" "b") 12651 (match_operand:SI 2 "constant_call_address_operand" "z")] 12652 UNSPEC_TLS_LD_BASE)) 12653 (clobber (match_scratch:SI 3 "=d")) 12654 (clobber (match_scratch:SI 4 "=c")) 12655 (clobber (reg:CC FLAGS_REG))] 12656 "!TARGET_64BIT && TARGET_GNU_TLS" 12657{ 12658 output_asm_insn 12659 ("lea{l}\t{%&@tlsldm(%1), %0|%0, %&@tlsldm[%1]}", operands); 12660 if (TARGET_SUN_TLS) 12661#ifdef HAVE_AS_IX86_TLSLDMPLT 12662 return "call\t%&@tlsldmplt"; 12663#else 12664 return "call\t%p2@plt"; 12665#endif 12666 return "call\t%P2"; 12667} 12668 [(set_attr "type" "multi") 12669 (set_attr "length" "11")]) 12670 12671(define_expand "tls_local_dynamic_base_32" 12672 [(parallel 12673 [(set (match_operand:SI 0 "register_operand" "") 12674 (unspec:SI 12675 [(match_operand:SI 1 "register_operand" "") 12676 (match_operand:SI 2 "constant_call_address_operand" "")] 12677 UNSPEC_TLS_LD_BASE)) 12678 (clobber (match_scratch:SI 3 "")) 12679 (clobber (match_scratch:SI 4 "")) 12680 (clobber (reg:CC FLAGS_REG))])]) 12681 12682(define_insn "*tls_local_dynamic_base_64" 12683 [(set (match_operand:DI 0 "register_operand" "=a") 12684 (call:DI 12685 (mem:QI (match_operand:DI 1 "constant_call_address_operand" "z")) 12686 (match_operand:DI 2 "" ""))) 12687 (unspec:DI [(const_int 0)] UNSPEC_TLS_LD_BASE)] 12688 "TARGET_64BIT" 12689{ 12690 output_asm_insn 12691 ("lea{q}\t{%&@tlsld(%%rip), %%rdi|rdi, %&@tlsld[rip]}", operands); 12692 if (TARGET_SUN_TLS) 12693 return "call\t%p1@plt"; 12694 return "call\t%P1"; 12695} 12696 [(set_attr "type" "multi") 12697 (set_attr "length" "12")]) 12698 12699(define_expand "tls_local_dynamic_base_64" 12700 [(parallel 12701 [(set (match_operand:DI 0 "register_operand" "") 12702 (call:DI 12703 (mem:QI (match_operand:DI 1 "constant_call_address_operand" "")) 12704 (const_int 0))) 12705 (unspec:DI [(const_int 0)] UNSPEC_TLS_LD_BASE)])]) 12706 12707;; Local dynamic of a single variable is a lose. Show combine how 12708;; to convert that back to global dynamic. 12709 12710(define_insn_and_split "*tls_local_dynamic_32_once" 12711 [(set (match_operand:SI 0 "register_operand" "=a") 12712 (plus:SI 12713 (unspec:SI [(match_operand:SI 1 "register_operand" "b") 12714 (match_operand:SI 2 "constant_call_address_operand" "z")] 12715 UNSPEC_TLS_LD_BASE) 12716 (const:SI (unspec:SI 12717 [(match_operand:SI 3 "tls_symbolic_operand" "")] 12718 UNSPEC_DTPOFF)))) 12719 (clobber (match_scratch:SI 4 "=d")) 12720 (clobber (match_scratch:SI 5 "=c")) 12721 (clobber (reg:CC FLAGS_REG))] 12722 "" 12723 "#" 12724 "" 12725 [(parallel 12726 [(set (match_dup 0) 12727 (unspec:SI [(match_dup 1) (match_dup 3) (match_dup 2)] 12728 UNSPEC_TLS_GD)) 12729 (clobber (match_dup 4)) 12730 (clobber (match_dup 5)) 12731 (clobber (reg:CC FLAGS_REG))])]) 12732 12733;; Segment register for the thread base ptr load 12734(define_mode_attr tp_seg [(SI "gs") (DI "fs")]) 12735 12736;; Load and add the thread base pointer from %<tp_seg>:0. 12737(define_insn "*load_tp_x32" 12738 [(set (match_operand:SI 0 "register_operand" "=r") 12739 (unspec:SI [(const_int 0)] UNSPEC_TP))] 12740 "TARGET_X32" 12741 "mov{l}\t{%%fs:0, %0|%0, DWORD PTR fs:0}" 12742 [(set_attr "type" "imov") 12743 (set_attr "modrm" "0") 12744 (set_attr "length" "7") 12745 (set_attr "memory" "load") 12746 (set_attr "imm_disp" "false")]) 12747 12748(define_insn "*load_tp_x32_zext" 12749 [(set (match_operand:DI 0 "register_operand" "=r") 12750 (zero_extend:DI (unspec:SI [(const_int 0)] UNSPEC_TP)))] 12751 "TARGET_X32" 12752 "mov{l}\t{%%fs:0, %k0|%k0, DWORD PTR fs:0}" 12753 [(set_attr "type" "imov") 12754 (set_attr "modrm" "0") 12755 (set_attr "length" "7") 12756 (set_attr "memory" "load") 12757 (set_attr "imm_disp" "false")]) 12758 12759(define_insn "*load_tp_<mode>" 12760 [(set (match_operand:P 0 "register_operand" "=r") 12761 (unspec:P [(const_int 0)] UNSPEC_TP))] 12762 "!TARGET_X32" 12763 "mov{<imodesuffix>}\t{%%<tp_seg>:0, %0|%0, <iptrsize> PTR <tp_seg>:0}" 12764 [(set_attr "type" "imov") 12765 (set_attr "modrm" "0") 12766 (set_attr "length" "7") 12767 (set_attr "memory" "load") 12768 (set_attr "imm_disp" "false")]) 12769 12770(define_insn "*add_tp_x32" 12771 [(set (match_operand:SI 0 "register_operand" "=r") 12772 (plus:SI (unspec:SI [(const_int 0)] UNSPEC_TP) 12773 (match_operand:SI 1 "register_operand" "0"))) 12774 (clobber (reg:CC FLAGS_REG))] 12775 "TARGET_X32" 12776 "add{l}\t{%%fs:0, %0|%0, DWORD PTR fs:0}" 12777 [(set_attr "type" "alu") 12778 (set_attr "modrm" "0") 12779 (set_attr "length" "7") 12780 (set_attr "memory" "load") 12781 (set_attr "imm_disp" "false")]) 12782 12783(define_insn "*add_tp_x32_zext" 12784 [(set (match_operand:DI 0 "register_operand" "=r") 12785 (zero_extend:DI 12786 (plus:SI (unspec:SI [(const_int 0)] UNSPEC_TP) 12787 (match_operand:SI 1 "register_operand" "0")))) 12788 (clobber (reg:CC FLAGS_REG))] 12789 "TARGET_X32" 12790 "add{l}\t{%%fs:0, %k0|%k0, DWORD PTR fs:0}" 12791 [(set_attr "type" "alu") 12792 (set_attr "modrm" "0") 12793 (set_attr "length" "7") 12794 (set_attr "memory" "load") 12795 (set_attr "imm_disp" "false")]) 12796 12797(define_insn "*add_tp_<mode>" 12798 [(set (match_operand:P 0 "register_operand" "=r") 12799 (plus:P (unspec:P [(const_int 0)] UNSPEC_TP) 12800 (match_operand:P 1 "register_operand" "0"))) 12801 (clobber (reg:CC FLAGS_REG))] 12802 "!TARGET_X32" 12803 "add{<imodesuffix>}\t{%%<tp_seg>:0, %0|%0, <iptrsize> PTR <tp_seg>:0}" 12804 [(set_attr "type" "alu") 12805 (set_attr "modrm" "0") 12806 (set_attr "length" "7") 12807 (set_attr "memory" "load") 12808 (set_attr "imm_disp" "false")]) 12809 12810;; The Sun linker took the AMD64 TLS spec literally and can only handle 12811;; %rax as destination of the initial executable code sequence. 12812(define_insn "tls_initial_exec_64_sun" 12813 [(set (match_operand:DI 0 "register_operand" "=a") 12814 (unspec:DI 12815 [(match_operand:DI 1 "tls_symbolic_operand" "")] 12816 UNSPEC_TLS_IE_SUN)) 12817 (clobber (reg:CC FLAGS_REG))] 12818 "TARGET_64BIT && TARGET_SUN_TLS" 12819{ 12820 output_asm_insn 12821 ("mov{q}\t{%%fs:0, %0|%0, QWORD PTR fs:0}", operands); 12822 return "add{q}\t{%a1@gottpoff(%%rip), %0|%0, %a1@gottpoff[rip]}"; 12823} 12824 [(set_attr "type" "multi")]) 12825 12826;; GNU2 TLS patterns can be split. 12827 12828(define_expand "tls_dynamic_gnu2_32" 12829 [(set (match_dup 3) 12830 (plus:SI (match_operand:SI 2 "register_operand" "") 12831 (const:SI 12832 (unspec:SI [(match_operand:SI 1 "tls_symbolic_operand" "")] 12833 UNSPEC_TLSDESC)))) 12834 (parallel 12835 [(set (match_operand:SI 0 "register_operand" "") 12836 (unspec:SI [(match_dup 1) (match_dup 3) 12837 (match_dup 2) (reg:SI SP_REG)] 12838 UNSPEC_TLSDESC)) 12839 (clobber (reg:CC FLAGS_REG))])] 12840 "!TARGET_64BIT && TARGET_GNU2_TLS" 12841{ 12842 operands[3] = can_create_pseudo_p () ? gen_reg_rtx (Pmode) : operands[0]; 12843 ix86_tls_descriptor_calls_expanded_in_cfun = true; 12844}) 12845 12846(define_insn "*tls_dynamic_gnu2_lea_32" 12847 [(set (match_operand:SI 0 "register_operand" "=r") 12848 (plus:SI (match_operand:SI 1 "register_operand" "b") 12849 (const:SI 12850 (unspec:SI [(match_operand:SI 2 "tls_symbolic_operand" "")] 12851 UNSPEC_TLSDESC))))] 12852 "!TARGET_64BIT && TARGET_GNU2_TLS" 12853 "lea{l}\t{%E2@TLSDESC(%1), %0|%0, %E2@TLSDESC[%1]}" 12854 [(set_attr "type" "lea") 12855 (set_attr "mode" "SI") 12856 (set_attr "length" "6") 12857 (set_attr "length_address" "4")]) 12858 12859(define_insn "*tls_dynamic_gnu2_call_32" 12860 [(set (match_operand:SI 0 "register_operand" "=a") 12861 (unspec:SI [(match_operand:SI 1 "tls_symbolic_operand" "") 12862 (match_operand:SI 2 "register_operand" "0") 12863 ;; we have to make sure %ebx still points to the GOT 12864 (match_operand:SI 3 "register_operand" "b") 12865 (reg:SI SP_REG)] 12866 UNSPEC_TLSDESC)) 12867 (clobber (reg:CC FLAGS_REG))] 12868 "!TARGET_64BIT && TARGET_GNU2_TLS" 12869 "call\t{*%a1@TLSCALL(%2)|[DWORD PTR [%2+%a1@TLSCALL]]}" 12870 [(set_attr "type" "call") 12871 (set_attr "length" "2") 12872 (set_attr "length_address" "0")]) 12873 12874(define_insn_and_split "*tls_dynamic_gnu2_combine_32" 12875 [(set (match_operand:SI 0 "register_operand" "=&a") 12876 (plus:SI 12877 (unspec:SI [(match_operand:SI 3 "tls_modbase_operand" "") 12878 (match_operand:SI 4 "" "") 12879 (match_operand:SI 2 "register_operand" "b") 12880 (reg:SI SP_REG)] 12881 UNSPEC_TLSDESC) 12882 (const:SI (unspec:SI 12883 [(match_operand:SI 1 "tls_symbolic_operand" "")] 12884 UNSPEC_DTPOFF)))) 12885 (clobber (reg:CC FLAGS_REG))] 12886 "!TARGET_64BIT && TARGET_GNU2_TLS" 12887 "#" 12888 "" 12889 [(set (match_dup 0) (match_dup 5))] 12890{ 12891 operands[5] = can_create_pseudo_p () ? gen_reg_rtx (Pmode) : operands[0]; 12892 emit_insn (gen_tls_dynamic_gnu2_32 (operands[5], operands[1], operands[2])); 12893}) 12894 12895(define_expand "tls_dynamic_gnu2_64" 12896 [(set (match_dup 2) 12897 (unspec:DI [(match_operand 1 "tls_symbolic_operand" "")] 12898 UNSPEC_TLSDESC)) 12899 (parallel 12900 [(set (match_operand:DI 0 "register_operand" "") 12901 (unspec:DI [(match_dup 1) (match_dup 2) (reg:DI SP_REG)] 12902 UNSPEC_TLSDESC)) 12903 (clobber (reg:CC FLAGS_REG))])] 12904 "TARGET_64BIT && TARGET_GNU2_TLS" 12905{ 12906 operands[2] = can_create_pseudo_p () ? gen_reg_rtx (Pmode) : operands[0]; 12907 ix86_tls_descriptor_calls_expanded_in_cfun = true; 12908}) 12909 12910(define_insn "*tls_dynamic_gnu2_lea_64" 12911 [(set (match_operand:DI 0 "register_operand" "=r") 12912 (unspec:DI [(match_operand 1 "tls_symbolic_operand" "")] 12913 UNSPEC_TLSDESC))] 12914 "TARGET_64BIT && TARGET_GNU2_TLS" 12915 "lea{q}\t{%E1@TLSDESC(%%rip), %0|%0, %E1@TLSDESC[rip]}" 12916 [(set_attr "type" "lea") 12917 (set_attr "mode" "DI") 12918 (set_attr "length" "7") 12919 (set_attr "length_address" "4")]) 12920 12921(define_insn "*tls_dynamic_gnu2_call_64" 12922 [(set (match_operand:DI 0 "register_operand" "=a") 12923 (unspec:DI [(match_operand 1 "tls_symbolic_operand" "") 12924 (match_operand:DI 2 "register_operand" "0") 12925 (reg:DI SP_REG)] 12926 UNSPEC_TLSDESC)) 12927 (clobber (reg:CC FLAGS_REG))] 12928 "TARGET_64BIT && TARGET_GNU2_TLS" 12929 "call\t{*%a1@TLSCALL(%2)|[QWORD PTR [%2+%a1@TLSCALL]]}" 12930 [(set_attr "type" "call") 12931 (set_attr "length" "2") 12932 (set_attr "length_address" "0")]) 12933 12934(define_insn_and_split "*tls_dynamic_gnu2_combine_64" 12935 [(set (match_operand:DI 0 "register_operand" "=&a") 12936 (plus:DI 12937 (unspec:DI [(match_operand:DI 2 "tls_modbase_operand" "") 12938 (match_operand:DI 3 "" "") 12939 (reg:DI SP_REG)] 12940 UNSPEC_TLSDESC) 12941 (const:DI (unspec:DI 12942 [(match_operand 1 "tls_symbolic_operand" "")] 12943 UNSPEC_DTPOFF)))) 12944 (clobber (reg:CC FLAGS_REG))] 12945 "TARGET_64BIT && TARGET_GNU2_TLS" 12946 "#" 12947 "" 12948 [(set (match_dup 0) (match_dup 4))] 12949{ 12950 operands[4] = can_create_pseudo_p () ? gen_reg_rtx (Pmode) : operands[0]; 12951 emit_insn (gen_tls_dynamic_gnu2_64 (operands[4], operands[1])); 12952}) 12953 12954;; These patterns match the binary 387 instructions for addM3, subM3, 12955;; mulM3 and divM3. There are three patterns for each of DFmode and 12956;; SFmode. The first is the normal insn, the second the same insn but 12957;; with one operand a conversion, and the third the same insn but with 12958;; the other operand a conversion. The conversion may be SFmode or 12959;; SImode if the target mode DFmode, but only SImode if the target mode 12960;; is SFmode. 12961 12962;; Gcc is slightly more smart about handling normal two address instructions 12963;; so use special patterns for add and mull. 12964 12965(define_insn "*fop_<mode>_comm_mixed" 12966 [(set (match_operand:MODEF 0 "register_operand" "=f,x,x") 12967 (match_operator:MODEF 3 "binary_fp_operator" 12968 [(match_operand:MODEF 1 "nonimmediate_operand" "%0,0,x") 12969 (match_operand:MODEF 2 "nonimmediate_operand" "fm,xm,xm")]))] 12970 "SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_MIX_SSE_I387 12971 && COMMUTATIVE_ARITH_P (operands[3]) 12972 && !(MEM_P (operands[1]) && MEM_P (operands[2]))" 12973 "* return output_387_binary_op (insn, operands);" 12974 [(set (attr "type") 12975 (if_then_else (eq_attr "alternative" "1,2") 12976 (if_then_else (match_operand:MODEF 3 "mult_operator" "") 12977 (const_string "ssemul") 12978 (const_string "sseadd")) 12979 (if_then_else (match_operand:MODEF 3 "mult_operator" "") 12980 (const_string "fmul") 12981 (const_string "fop")))) 12982 (set_attr "isa" "*,noavx,avx") 12983 (set_attr "prefix" "orig,orig,vex") 12984 (set_attr "mode" "<MODE>")]) 12985 12986(define_insn "*fop_<mode>_comm_sse" 12987 [(set (match_operand:MODEF 0 "register_operand" "=x,x") 12988 (match_operator:MODEF 3 "binary_fp_operator" 12989 [(match_operand:MODEF 1 "nonimmediate_operand" "%0,x") 12990 (match_operand:MODEF 2 "nonimmediate_operand" "xm,xm")]))] 12991 "SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH 12992 && COMMUTATIVE_ARITH_P (operands[3]) 12993 && !(MEM_P (operands[1]) && MEM_P (operands[2]))" 12994 "* return output_387_binary_op (insn, operands);" 12995 [(set (attr "type") 12996 (if_then_else (match_operand:MODEF 3 "mult_operator" "") 12997 (const_string "ssemul") 12998 (const_string "sseadd"))) 12999 (set_attr "isa" "noavx,avx") 13000 (set_attr "prefix" "orig,vex") 13001 (set_attr "mode" "<MODE>")]) 13002 13003(define_insn "*fop_<mode>_comm_i387" 13004 [(set (match_operand:MODEF 0 "register_operand" "=f") 13005 (match_operator:MODEF 3 "binary_fp_operator" 13006 [(match_operand:MODEF 1 "nonimmediate_operand" "%0") 13007 (match_operand:MODEF 2 "nonimmediate_operand" "fm")]))] 13008 "TARGET_80387 && X87_ENABLE_ARITH (<MODE>mode) 13009 && COMMUTATIVE_ARITH_P (operands[3]) 13010 && !(MEM_P (operands[1]) && MEM_P (operands[2]))" 13011 "* return output_387_binary_op (insn, operands);" 13012 [(set (attr "type") 13013 (if_then_else (match_operand:MODEF 3 "mult_operator" "") 13014 (const_string "fmul") 13015 (const_string "fop"))) 13016 (set_attr "mode" "<MODE>")]) 13017 13018(define_insn "*fop_<mode>_1_mixed" 13019 [(set (match_operand:MODEF 0 "register_operand" "=f,f,x,x") 13020 (match_operator:MODEF 3 "binary_fp_operator" 13021 [(match_operand:MODEF 1 "nonimmediate_operand" "0,fm,0,x") 13022 (match_operand:MODEF 2 "nonimmediate_operand" "fm,0,xm,xm")]))] 13023 "SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_MIX_SSE_I387 13024 && !COMMUTATIVE_ARITH_P (operands[3]) 13025 && !(MEM_P (operands[1]) && MEM_P (operands[2]))" 13026 "* return output_387_binary_op (insn, operands);" 13027 [(set (attr "type") 13028 (cond [(and (eq_attr "alternative" "2,3") 13029 (match_operand:MODEF 3 "mult_operator" "")) 13030 (const_string "ssemul") 13031 (and (eq_attr "alternative" "2,3") 13032 (match_operand:MODEF 3 "div_operator" "")) 13033 (const_string "ssediv") 13034 (eq_attr "alternative" "2,3") 13035 (const_string "sseadd") 13036 (match_operand:MODEF 3 "mult_operator" "") 13037 (const_string "fmul") 13038 (match_operand:MODEF 3 "div_operator" "") 13039 (const_string "fdiv") 13040 ] 13041 (const_string "fop"))) 13042 (set_attr "isa" "*,*,noavx,avx") 13043 (set_attr "prefix" "orig,orig,orig,vex") 13044 (set_attr "mode" "<MODE>")]) 13045 13046(define_insn "*rcpsf2_sse" 13047 [(set (match_operand:SF 0 "register_operand" "=x") 13048 (unspec:SF [(match_operand:SF 1 "nonimmediate_operand" "xm")] 13049 UNSPEC_RCP))] 13050 "TARGET_SSE_MATH" 13051 "%vrcpss\t{%1, %d0|%d0, %1}" 13052 [(set_attr "type" "sse") 13053 (set_attr "atom_sse_attr" "rcp") 13054 (set_attr "prefix" "maybe_vex") 13055 (set_attr "mode" "SF")]) 13056 13057(define_insn "*fop_<mode>_1_sse" 13058 [(set (match_operand:MODEF 0 "register_operand" "=x,x") 13059 (match_operator:MODEF 3 "binary_fp_operator" 13060 [(match_operand:MODEF 1 "register_operand" "0,x") 13061 (match_operand:MODEF 2 "nonimmediate_operand" "xm,xm")]))] 13062 "SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH 13063 && !COMMUTATIVE_ARITH_P (operands[3])" 13064 "* return output_387_binary_op (insn, operands);" 13065 [(set (attr "type") 13066 (cond [(match_operand:MODEF 3 "mult_operator" "") 13067 (const_string "ssemul") 13068 (match_operand:MODEF 3 "div_operator" "") 13069 (const_string "ssediv") 13070 ] 13071 (const_string "sseadd"))) 13072 (set_attr "isa" "noavx,avx") 13073 (set_attr "prefix" "orig,vex") 13074 (set_attr "mode" "<MODE>")]) 13075 13076;; This pattern is not fully shadowed by the pattern above. 13077(define_insn "*fop_<mode>_1_i387" 13078 [(set (match_operand:MODEF 0 "register_operand" "=f,f") 13079 (match_operator:MODEF 3 "binary_fp_operator" 13080 [(match_operand:MODEF 1 "nonimmediate_operand" "0,fm") 13081 (match_operand:MODEF 2 "nonimmediate_operand" "fm,0")]))] 13082 "TARGET_80387 && X87_ENABLE_ARITH (<MODE>mode) 13083 && !(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH) 13084 && !COMMUTATIVE_ARITH_P (operands[3]) 13085 && !(MEM_P (operands[1]) && MEM_P (operands[2]))" 13086 "* return output_387_binary_op (insn, operands);" 13087 [(set (attr "type") 13088 (cond [(match_operand:MODEF 3 "mult_operator" "") 13089 (const_string "fmul") 13090 (match_operand:MODEF 3 "div_operator" "") 13091 (const_string "fdiv") 13092 ] 13093 (const_string "fop"))) 13094 (set_attr "mode" "<MODE>")]) 13095 13096;; ??? Add SSE splitters for these! 13097(define_insn "*fop_<MODEF:mode>_2_i387" 13098 [(set (match_operand:MODEF 0 "register_operand" "=f,f") 13099 (match_operator:MODEF 3 "binary_fp_operator" 13100 [(float:MODEF 13101 (match_operand:SWI24 1 "nonimmediate_operand" "m,?r")) 13102 (match_operand:MODEF 2 "register_operand" "0,0")]))] 13103 "TARGET_80387 && X87_ENABLE_FLOAT (<MODEF:MODE>mode, <SWI24:MODE>mode) 13104 && !(SSE_FLOAT_MODE_P (<MODEF:MODE>mode) && TARGET_SSE_MATH) 13105 && (TARGET_USE_<SWI24:MODE>MODE_FIOP || optimize_function_for_size_p (cfun))" 13106 "* return which_alternative ? \"#\" : output_387_binary_op (insn, operands);" 13107 [(set (attr "type") 13108 (cond [(match_operand:MODEF 3 "mult_operator" "") 13109 (const_string "fmul") 13110 (match_operand:MODEF 3 "div_operator" "") 13111 (const_string "fdiv") 13112 ] 13113 (const_string "fop"))) 13114 (set_attr "fp_int_src" "true") 13115 (set_attr "mode" "<SWI24:MODE>")]) 13116 13117(define_insn "*fop_<MODEF:mode>_3_i387" 13118 [(set (match_operand:MODEF 0 "register_operand" "=f,f") 13119 (match_operator:MODEF 3 "binary_fp_operator" 13120 [(match_operand:MODEF 1 "register_operand" "0,0") 13121 (float:MODEF 13122 (match_operand:SWI24 2 "nonimmediate_operand" "m,?r"))]))] 13123 "TARGET_80387 && X87_ENABLE_FLOAT (<MODEF:MODE>mode, <SWI24:MODE>mode) 13124 && !(SSE_FLOAT_MODE_P (<MODEF:MODE>mode) && TARGET_SSE_MATH) 13125 && (TARGET_USE_<SWI24:MODE>MODE_FIOP || optimize_function_for_size_p (cfun))" 13126 "* return which_alternative ? \"#\" : output_387_binary_op (insn, operands);" 13127 [(set (attr "type") 13128 (cond [(match_operand:MODEF 3 "mult_operator" "") 13129 (const_string "fmul") 13130 (match_operand:MODEF 3 "div_operator" "") 13131 (const_string "fdiv") 13132 ] 13133 (const_string "fop"))) 13134 (set_attr "fp_int_src" "true") 13135 (set_attr "mode" "<MODE>")]) 13136 13137(define_insn "*fop_df_4_i387" 13138 [(set (match_operand:DF 0 "register_operand" "=f,f") 13139 (match_operator:DF 3 "binary_fp_operator" 13140 [(float_extend:DF 13141 (match_operand:SF 1 "nonimmediate_operand" "fm,0")) 13142 (match_operand:DF 2 "register_operand" "0,f")]))] 13143 "TARGET_80387 && X87_ENABLE_ARITH (DFmode) 13144 && !(TARGET_SSE2 && TARGET_SSE_MATH) 13145 && !(MEM_P (operands[1]) && MEM_P (operands[2]))" 13146 "* return output_387_binary_op (insn, operands);" 13147 [(set (attr "type") 13148 (cond [(match_operand:DF 3 "mult_operator" "") 13149 (const_string "fmul") 13150 (match_operand:DF 3 "div_operator" "") 13151 (const_string "fdiv") 13152 ] 13153 (const_string "fop"))) 13154 (set_attr "mode" "SF")]) 13155 13156(define_insn "*fop_df_5_i387" 13157 [(set (match_operand:DF 0 "register_operand" "=f,f") 13158 (match_operator:DF 3 "binary_fp_operator" 13159 [(match_operand:DF 1 "register_operand" "0,f") 13160 (float_extend:DF 13161 (match_operand:SF 2 "nonimmediate_operand" "fm,0"))]))] 13162 "TARGET_80387 && X87_ENABLE_ARITH (DFmode) 13163 && !(TARGET_SSE2 && TARGET_SSE_MATH)" 13164 "* return output_387_binary_op (insn, operands);" 13165 [(set (attr "type") 13166 (cond [(match_operand:DF 3 "mult_operator" "") 13167 (const_string "fmul") 13168 (match_operand:DF 3 "div_operator" "") 13169 (const_string "fdiv") 13170 ] 13171 (const_string "fop"))) 13172 (set_attr "mode" "SF")]) 13173 13174(define_insn "*fop_df_6_i387" 13175 [(set (match_operand:DF 0 "register_operand" "=f,f") 13176 (match_operator:DF 3 "binary_fp_operator" 13177 [(float_extend:DF 13178 (match_operand:SF 1 "register_operand" "0,f")) 13179 (float_extend:DF 13180 (match_operand:SF 2 "nonimmediate_operand" "fm,0"))]))] 13181 "TARGET_80387 && X87_ENABLE_ARITH (DFmode) 13182 && !(TARGET_SSE2 && TARGET_SSE_MATH)" 13183 "* return output_387_binary_op (insn, operands);" 13184 [(set (attr "type") 13185 (cond [(match_operand:DF 3 "mult_operator" "") 13186 (const_string "fmul") 13187 (match_operand:DF 3 "div_operator" "") 13188 (const_string "fdiv") 13189 ] 13190 (const_string "fop"))) 13191 (set_attr "mode" "SF")]) 13192 13193(define_insn "*fop_xf_comm_i387" 13194 [(set (match_operand:XF 0 "register_operand" "=f") 13195 (match_operator:XF 3 "binary_fp_operator" 13196 [(match_operand:XF 1 "register_operand" "%0") 13197 (match_operand:XF 2 "register_operand" "f")]))] 13198 "TARGET_80387 13199 && COMMUTATIVE_ARITH_P (operands[3])" 13200 "* return output_387_binary_op (insn, operands);" 13201 [(set (attr "type") 13202 (if_then_else (match_operand:XF 3 "mult_operator" "") 13203 (const_string "fmul") 13204 (const_string "fop"))) 13205 (set_attr "mode" "XF")]) 13206 13207(define_insn "*fop_xf_1_i387" 13208 [(set (match_operand:XF 0 "register_operand" "=f,f") 13209 (match_operator:XF 3 "binary_fp_operator" 13210 [(match_operand:XF 1 "register_operand" "0,f") 13211 (match_operand:XF 2 "register_operand" "f,0")]))] 13212 "TARGET_80387 13213 && !COMMUTATIVE_ARITH_P (operands[3])" 13214 "* return output_387_binary_op (insn, operands);" 13215 [(set (attr "type") 13216 (cond [(match_operand:XF 3 "mult_operator" "") 13217 (const_string "fmul") 13218 (match_operand:XF 3 "div_operator" "") 13219 (const_string "fdiv") 13220 ] 13221 (const_string "fop"))) 13222 (set_attr "mode" "XF")]) 13223 13224(define_insn "*fop_xf_2_i387" 13225 [(set (match_operand:XF 0 "register_operand" "=f,f") 13226 (match_operator:XF 3 "binary_fp_operator" 13227 [(float:XF 13228 (match_operand:SWI24 1 "nonimmediate_operand" "m,?r")) 13229 (match_operand:XF 2 "register_operand" "0,0")]))] 13230 "TARGET_80387 && (TARGET_USE_<MODE>MODE_FIOP || optimize_function_for_size_p (cfun))" 13231 "* return which_alternative ? \"#\" : output_387_binary_op (insn, operands);" 13232 [(set (attr "type") 13233 (cond [(match_operand:XF 3 "mult_operator" "") 13234 (const_string "fmul") 13235 (match_operand:XF 3 "div_operator" "") 13236 (const_string "fdiv") 13237 ] 13238 (const_string "fop"))) 13239 (set_attr "fp_int_src" "true") 13240 (set_attr "mode" "<MODE>")]) 13241 13242(define_insn "*fop_xf_3_i387" 13243 [(set (match_operand:XF 0 "register_operand" "=f,f") 13244 (match_operator:XF 3 "binary_fp_operator" 13245 [(match_operand:XF 1 "register_operand" "0,0") 13246 (float:XF 13247 (match_operand:SWI24 2 "nonimmediate_operand" "m,?r"))]))] 13248 "TARGET_80387 && (TARGET_USE_<MODE>MODE_FIOP || optimize_function_for_size_p (cfun))" 13249 "* return which_alternative ? \"#\" : output_387_binary_op (insn, operands);" 13250 [(set (attr "type") 13251 (cond [(match_operand:XF 3 "mult_operator" "") 13252 (const_string "fmul") 13253 (match_operand:XF 3 "div_operator" "") 13254 (const_string "fdiv") 13255 ] 13256 (const_string "fop"))) 13257 (set_attr "fp_int_src" "true") 13258 (set_attr "mode" "<MODE>")]) 13259 13260(define_insn "*fop_xf_4_i387" 13261 [(set (match_operand:XF 0 "register_operand" "=f,f") 13262 (match_operator:XF 3 "binary_fp_operator" 13263 [(float_extend:XF 13264 (match_operand:MODEF 1 "nonimmediate_operand" "fm,0")) 13265 (match_operand:XF 2 "register_operand" "0,f")]))] 13266 "TARGET_80387" 13267 "* return output_387_binary_op (insn, operands);" 13268 [(set (attr "type") 13269 (cond [(match_operand:XF 3 "mult_operator" "") 13270 (const_string "fmul") 13271 (match_operand:XF 3 "div_operator" "") 13272 (const_string "fdiv") 13273 ] 13274 (const_string "fop"))) 13275 (set_attr "mode" "<MODE>")]) 13276 13277(define_insn "*fop_xf_5_i387" 13278 [(set (match_operand:XF 0 "register_operand" "=f,f") 13279 (match_operator:XF 3 "binary_fp_operator" 13280 [(match_operand:XF 1 "register_operand" "0,f") 13281 (float_extend:XF 13282 (match_operand:MODEF 2 "nonimmediate_operand" "fm,0"))]))] 13283 "TARGET_80387" 13284 "* return output_387_binary_op (insn, operands);" 13285 [(set (attr "type") 13286 (cond [(match_operand:XF 3 "mult_operator" "") 13287 (const_string "fmul") 13288 (match_operand:XF 3 "div_operator" "") 13289 (const_string "fdiv") 13290 ] 13291 (const_string "fop"))) 13292 (set_attr "mode" "<MODE>")]) 13293 13294(define_insn "*fop_xf_6_i387" 13295 [(set (match_operand:XF 0 "register_operand" "=f,f") 13296 (match_operator:XF 3 "binary_fp_operator" 13297 [(float_extend:XF 13298 (match_operand:MODEF 1 "register_operand" "0,f")) 13299 (float_extend:XF 13300 (match_operand:MODEF 2 "nonimmediate_operand" "fm,0"))]))] 13301 "TARGET_80387" 13302 "* return output_387_binary_op (insn, operands);" 13303 [(set (attr "type") 13304 (cond [(match_operand:XF 3 "mult_operator" "") 13305 (const_string "fmul") 13306 (match_operand:XF 3 "div_operator" "") 13307 (const_string "fdiv") 13308 ] 13309 (const_string "fop"))) 13310 (set_attr "mode" "<MODE>")]) 13311 13312(define_split 13313 [(set (match_operand 0 "register_operand" "") 13314 (match_operator 3 "binary_fp_operator" 13315 [(float (match_operand:SWI24 1 "register_operand" "")) 13316 (match_operand 2 "register_operand" "")]))] 13317 "reload_completed 13318 && X87_FLOAT_MODE_P (GET_MODE (operands[0])) 13319 && X87_ENABLE_FLOAT (GET_MODE (operands[0]), GET_MODE (operands[1]))" 13320 [(const_int 0)] 13321{ 13322 operands[4] = ix86_force_to_memory (GET_MODE (operands[1]), operands[1]); 13323 operands[4] = gen_rtx_FLOAT (GET_MODE (operands[0]), operands[4]); 13324 emit_insn (gen_rtx_SET (VOIDmode, operands[0], 13325 gen_rtx_fmt_ee (GET_CODE (operands[3]), 13326 GET_MODE (operands[3]), 13327 operands[4], 13328 operands[2]))); 13329 ix86_free_from_memory (GET_MODE (operands[1])); 13330 DONE; 13331}) 13332 13333(define_split 13334 [(set (match_operand 0 "register_operand" "") 13335 (match_operator 3 "binary_fp_operator" 13336 [(match_operand 1 "register_operand" "") 13337 (float (match_operand:SWI24 2 "register_operand" ""))]))] 13338 "reload_completed 13339 && X87_FLOAT_MODE_P (GET_MODE (operands[0])) 13340 && X87_ENABLE_FLOAT (GET_MODE (operands[0]), GET_MODE (operands[2]))" 13341 [(const_int 0)] 13342{ 13343 operands[4] = ix86_force_to_memory (GET_MODE (operands[2]), operands[2]); 13344 operands[4] = gen_rtx_FLOAT (GET_MODE (operands[0]), operands[4]); 13345 emit_insn (gen_rtx_SET (VOIDmode, operands[0], 13346 gen_rtx_fmt_ee (GET_CODE (operands[3]), 13347 GET_MODE (operands[3]), 13348 operands[1], 13349 operands[4]))); 13350 ix86_free_from_memory (GET_MODE (operands[2])); 13351 DONE; 13352}) 13353 13354;; FPU special functions. 13355 13356;; This pattern implements a no-op XFmode truncation for 13357;; all fancy i386 XFmode math functions. 13358 13359(define_insn "truncxf<mode>2_i387_noop_unspec" 13360 [(set (match_operand:MODEF 0 "register_operand" "=f") 13361 (unspec:MODEF [(match_operand:XF 1 "register_operand" "f")] 13362 UNSPEC_TRUNC_NOOP))] 13363 "TARGET_USE_FANCY_MATH_387" 13364 "* return output_387_reg_move (insn, operands);" 13365 [(set_attr "type" "fmov") 13366 (set_attr "mode" "<MODE>")]) 13367 13368(define_insn "sqrtxf2" 13369 [(set (match_operand:XF 0 "register_operand" "=f") 13370 (sqrt:XF (match_operand:XF 1 "register_operand" "0")))] 13371 "TARGET_USE_FANCY_MATH_387" 13372 "fsqrt" 13373 [(set_attr "type" "fpspc") 13374 (set_attr "mode" "XF") 13375 (set_attr "athlon_decode" "direct") 13376 (set_attr "amdfam10_decode" "direct") 13377 (set_attr "bdver1_decode" "direct")]) 13378 13379(define_insn "sqrt_extend<mode>xf2_i387" 13380 [(set (match_operand:XF 0 "register_operand" "=f") 13381 (sqrt:XF 13382 (float_extend:XF 13383 (match_operand:MODEF 1 "register_operand" "0"))))] 13384 "TARGET_USE_FANCY_MATH_387" 13385 "fsqrt" 13386 [(set_attr "type" "fpspc") 13387 (set_attr "mode" "XF") 13388 (set_attr "athlon_decode" "direct") 13389 (set_attr "amdfam10_decode" "direct") 13390 (set_attr "bdver1_decode" "direct")]) 13391 13392(define_insn "*rsqrtsf2_sse" 13393 [(set (match_operand:SF 0 "register_operand" "=x") 13394 (unspec:SF [(match_operand:SF 1 "nonimmediate_operand" "xm")] 13395 UNSPEC_RSQRT))] 13396 "TARGET_SSE_MATH" 13397 "%vrsqrtss\t{%1, %d0|%d0, %1}" 13398 [(set_attr "type" "sse") 13399 (set_attr "atom_sse_attr" "rcp") 13400 (set_attr "prefix" "maybe_vex") 13401 (set_attr "mode" "SF")]) 13402 13403(define_expand "rsqrtsf2" 13404 [(set (match_operand:SF 0 "register_operand" "") 13405 (unspec:SF [(match_operand:SF 1 "nonimmediate_operand" "")] 13406 UNSPEC_RSQRT))] 13407 "TARGET_SSE_MATH" 13408{ 13409 ix86_emit_swsqrtsf (operands[0], operands[1], SFmode, 1); 13410 DONE; 13411}) 13412 13413(define_insn "*sqrt<mode>2_sse" 13414 [(set (match_operand:MODEF 0 "register_operand" "=x") 13415 (sqrt:MODEF 13416 (match_operand:MODEF 1 "nonimmediate_operand" "xm")))] 13417 "SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH" 13418 "%vsqrt<ssemodesuffix>\t{%1, %d0|%d0, %1}" 13419 [(set_attr "type" "sse") 13420 (set_attr "atom_sse_attr" "sqrt") 13421 (set_attr "prefix" "maybe_vex") 13422 (set_attr "mode" "<MODE>") 13423 (set_attr "athlon_decode" "*") 13424 (set_attr "amdfam10_decode" "*") 13425 (set_attr "bdver1_decode" "*")]) 13426 13427(define_expand "sqrt<mode>2" 13428 [(set (match_operand:MODEF 0 "register_operand" "") 13429 (sqrt:MODEF 13430 (match_operand:MODEF 1 "nonimmediate_operand" "")))] 13431 "(TARGET_USE_FANCY_MATH_387 && X87_ENABLE_ARITH (<MODE>mode)) 13432 || (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)" 13433{ 13434 if (<MODE>mode == SFmode 13435 && TARGET_SSE_MATH 13436 && TARGET_RECIP_SQRT 13437 && !optimize_function_for_size_p (cfun) 13438 && flag_finite_math_only && !flag_trapping_math 13439 && flag_unsafe_math_optimizations) 13440 { 13441 ix86_emit_swsqrtsf (operands[0], operands[1], SFmode, 0); 13442 DONE; 13443 } 13444 13445 if (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)) 13446 { 13447 rtx op0 = gen_reg_rtx (XFmode); 13448 rtx op1 = force_reg (<MODE>mode, operands[1]); 13449 13450 emit_insn (gen_sqrt_extend<mode>xf2_i387 (op0, op1)); 13451 emit_insn (gen_truncxf<mode>2_i387_noop_unspec (operands[0], op0)); 13452 DONE; 13453 } 13454}) 13455 13456(define_insn "fpremxf4_i387" 13457 [(set (match_operand:XF 0 "register_operand" "=f") 13458 (unspec:XF [(match_operand:XF 2 "register_operand" "0") 13459 (match_operand:XF 3 "register_operand" "1")] 13460 UNSPEC_FPREM_F)) 13461 (set (match_operand:XF 1 "register_operand" "=u") 13462 (unspec:XF [(match_dup 2) (match_dup 3)] 13463 UNSPEC_FPREM_U)) 13464 (set (reg:CCFP FPSR_REG) 13465 (unspec:CCFP [(match_dup 2) (match_dup 3)] 13466 UNSPEC_C2_FLAG))] 13467 "TARGET_USE_FANCY_MATH_387" 13468 "fprem" 13469 [(set_attr "type" "fpspc") 13470 (set_attr "mode" "XF")]) 13471 13472(define_expand "fmodxf3" 13473 [(use (match_operand:XF 0 "register_operand" "")) 13474 (use (match_operand:XF 1 "general_operand" "")) 13475 (use (match_operand:XF 2 "general_operand" ""))] 13476 "TARGET_USE_FANCY_MATH_387" 13477{ 13478 rtx label = gen_label_rtx (); 13479 13480 rtx op1 = gen_reg_rtx (XFmode); 13481 rtx op2 = gen_reg_rtx (XFmode); 13482 13483 emit_move_insn (op2, operands[2]); 13484 emit_move_insn (op1, operands[1]); 13485 13486 emit_label (label); 13487 emit_insn (gen_fpremxf4_i387 (op1, op2, op1, op2)); 13488 ix86_emit_fp_unordered_jump (label); 13489 LABEL_NUSES (label) = 1; 13490 13491 emit_move_insn (operands[0], op1); 13492 DONE; 13493}) 13494 13495(define_expand "fmod<mode>3" 13496 [(use (match_operand:MODEF 0 "register_operand" "")) 13497 (use (match_operand:MODEF 1 "general_operand" "")) 13498 (use (match_operand:MODEF 2 "general_operand" ""))] 13499 "TARGET_USE_FANCY_MATH_387" 13500{ 13501 rtx (*gen_truncxf) (rtx, rtx); 13502 13503 rtx label = gen_label_rtx (); 13504 13505 rtx op1 = gen_reg_rtx (XFmode); 13506 rtx op2 = gen_reg_rtx (XFmode); 13507 13508 emit_insn (gen_extend<mode>xf2 (op2, operands[2])); 13509 emit_insn (gen_extend<mode>xf2 (op1, operands[1])); 13510 13511 emit_label (label); 13512 emit_insn (gen_fpremxf4_i387 (op1, op2, op1, op2)); 13513 ix86_emit_fp_unordered_jump (label); 13514 LABEL_NUSES (label) = 1; 13515 13516 /* Truncate the result properly for strict SSE math. */ 13517 if (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH 13518 && !TARGET_MIX_SSE_I387) 13519 gen_truncxf = gen_truncxf<mode>2; 13520 else 13521 gen_truncxf = gen_truncxf<mode>2_i387_noop_unspec; 13522 13523 emit_insn (gen_truncxf (operands[0], op1)); 13524 DONE; 13525}) 13526 13527(define_insn "fprem1xf4_i387" 13528 [(set (match_operand:XF 0 "register_operand" "=f") 13529 (unspec:XF [(match_operand:XF 2 "register_operand" "0") 13530 (match_operand:XF 3 "register_operand" "1")] 13531 UNSPEC_FPREM1_F)) 13532 (set (match_operand:XF 1 "register_operand" "=u") 13533 (unspec:XF [(match_dup 2) (match_dup 3)] 13534 UNSPEC_FPREM1_U)) 13535 (set (reg:CCFP FPSR_REG) 13536 (unspec:CCFP [(match_dup 2) (match_dup 3)] 13537 UNSPEC_C2_FLAG))] 13538 "TARGET_USE_FANCY_MATH_387" 13539 "fprem1" 13540 [(set_attr "type" "fpspc") 13541 (set_attr "mode" "XF")]) 13542 13543(define_expand "remainderxf3" 13544 [(use (match_operand:XF 0 "register_operand" "")) 13545 (use (match_operand:XF 1 "general_operand" "")) 13546 (use (match_operand:XF 2 "general_operand" ""))] 13547 "TARGET_USE_FANCY_MATH_387" 13548{ 13549 rtx label = gen_label_rtx (); 13550 13551 rtx op1 = gen_reg_rtx (XFmode); 13552 rtx op2 = gen_reg_rtx (XFmode); 13553 13554 emit_move_insn (op2, operands[2]); 13555 emit_move_insn (op1, operands[1]); 13556 13557 emit_label (label); 13558 emit_insn (gen_fprem1xf4_i387 (op1, op2, op1, op2)); 13559 ix86_emit_fp_unordered_jump (label); 13560 LABEL_NUSES (label) = 1; 13561 13562 emit_move_insn (operands[0], op1); 13563 DONE; 13564}) 13565 13566(define_expand "remainder<mode>3" 13567 [(use (match_operand:MODEF 0 "register_operand" "")) 13568 (use (match_operand:MODEF 1 "general_operand" "")) 13569 (use (match_operand:MODEF 2 "general_operand" ""))] 13570 "TARGET_USE_FANCY_MATH_387" 13571{ 13572 rtx (*gen_truncxf) (rtx, rtx); 13573 13574 rtx label = gen_label_rtx (); 13575 13576 rtx op1 = gen_reg_rtx (XFmode); 13577 rtx op2 = gen_reg_rtx (XFmode); 13578 13579 emit_insn (gen_extend<mode>xf2 (op2, operands[2])); 13580 emit_insn (gen_extend<mode>xf2 (op1, operands[1])); 13581 13582 emit_label (label); 13583 13584 emit_insn (gen_fprem1xf4_i387 (op1, op2, op1, op2)); 13585 ix86_emit_fp_unordered_jump (label); 13586 LABEL_NUSES (label) = 1; 13587 13588 /* Truncate the result properly for strict SSE math. */ 13589 if (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH 13590 && !TARGET_MIX_SSE_I387) 13591 gen_truncxf = gen_truncxf<mode>2; 13592 else 13593 gen_truncxf = gen_truncxf<mode>2_i387_noop_unspec; 13594 13595 emit_insn (gen_truncxf (operands[0], op1)); 13596 DONE; 13597}) 13598 13599(define_insn "*sinxf2_i387" 13600 [(set (match_operand:XF 0 "register_operand" "=f") 13601 (unspec:XF [(match_operand:XF 1 "register_operand" "0")] UNSPEC_SIN))] 13602 "TARGET_USE_FANCY_MATH_387 13603 && flag_unsafe_math_optimizations" 13604 "fsin" 13605 [(set_attr "type" "fpspc") 13606 (set_attr "mode" "XF")]) 13607 13608(define_insn "*sin_extend<mode>xf2_i387" 13609 [(set (match_operand:XF 0 "register_operand" "=f") 13610 (unspec:XF [(float_extend:XF 13611 (match_operand:MODEF 1 "register_operand" "0"))] 13612 UNSPEC_SIN))] 13613 "TARGET_USE_FANCY_MATH_387 13614 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH) 13615 || TARGET_MIX_SSE_I387) 13616 && flag_unsafe_math_optimizations" 13617 "fsin" 13618 [(set_attr "type" "fpspc") 13619 (set_attr "mode" "XF")]) 13620 13621(define_insn "*cosxf2_i387" 13622 [(set (match_operand:XF 0 "register_operand" "=f") 13623 (unspec:XF [(match_operand:XF 1 "register_operand" "0")] UNSPEC_COS))] 13624 "TARGET_USE_FANCY_MATH_387 13625 && flag_unsafe_math_optimizations" 13626 "fcos" 13627 [(set_attr "type" "fpspc") 13628 (set_attr "mode" "XF")]) 13629 13630(define_insn "*cos_extend<mode>xf2_i387" 13631 [(set (match_operand:XF 0 "register_operand" "=f") 13632 (unspec:XF [(float_extend:XF 13633 (match_operand:MODEF 1 "register_operand" "0"))] 13634 UNSPEC_COS))] 13635 "TARGET_USE_FANCY_MATH_387 13636 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH) 13637 || TARGET_MIX_SSE_I387) 13638 && flag_unsafe_math_optimizations" 13639 "fcos" 13640 [(set_attr "type" "fpspc") 13641 (set_attr "mode" "XF")]) 13642 13643;; When sincos pattern is defined, sin and cos builtin functions will be 13644;; expanded to sincos pattern with one of its outputs left unused. 13645;; CSE pass will figure out if two sincos patterns can be combined, 13646;; otherwise sincos pattern will be split back to sin or cos pattern, 13647;; depending on the unused output. 13648 13649(define_insn "sincosxf3" 13650 [(set (match_operand:XF 0 "register_operand" "=f") 13651 (unspec:XF [(match_operand:XF 2 "register_operand" "0")] 13652 UNSPEC_SINCOS_COS)) 13653 (set (match_operand:XF 1 "register_operand" "=u") 13654 (unspec:XF [(match_dup 2)] UNSPEC_SINCOS_SIN))] 13655 "TARGET_USE_FANCY_MATH_387 13656 && flag_unsafe_math_optimizations" 13657 "fsincos" 13658 [(set_attr "type" "fpspc") 13659 (set_attr "mode" "XF")]) 13660 13661(define_split 13662 [(set (match_operand:XF 0 "register_operand" "") 13663 (unspec:XF [(match_operand:XF 2 "register_operand" "")] 13664 UNSPEC_SINCOS_COS)) 13665 (set (match_operand:XF 1 "register_operand" "") 13666 (unspec:XF [(match_dup 2)] UNSPEC_SINCOS_SIN))] 13667 "find_regno_note (insn, REG_UNUSED, REGNO (operands[0])) 13668 && can_create_pseudo_p ()" 13669 [(set (match_dup 1) (unspec:XF [(match_dup 2)] UNSPEC_SIN))]) 13670 13671(define_split 13672 [(set (match_operand:XF 0 "register_operand" "") 13673 (unspec:XF [(match_operand:XF 2 "register_operand" "")] 13674 UNSPEC_SINCOS_COS)) 13675 (set (match_operand:XF 1 "register_operand" "") 13676 (unspec:XF [(match_dup 2)] UNSPEC_SINCOS_SIN))] 13677 "find_regno_note (insn, REG_UNUSED, REGNO (operands[1])) 13678 && can_create_pseudo_p ()" 13679 [(set (match_dup 0) (unspec:XF [(match_dup 2)] UNSPEC_COS))]) 13680 13681(define_insn "sincos_extend<mode>xf3_i387" 13682 [(set (match_operand:XF 0 "register_operand" "=f") 13683 (unspec:XF [(float_extend:XF 13684 (match_operand:MODEF 2 "register_operand" "0"))] 13685 UNSPEC_SINCOS_COS)) 13686 (set (match_operand:XF 1 "register_operand" "=u") 13687 (unspec:XF [(float_extend:XF (match_dup 2))] UNSPEC_SINCOS_SIN))] 13688 "TARGET_USE_FANCY_MATH_387 13689 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH) 13690 || TARGET_MIX_SSE_I387) 13691 && flag_unsafe_math_optimizations" 13692 "fsincos" 13693 [(set_attr "type" "fpspc") 13694 (set_attr "mode" "XF")]) 13695 13696(define_split 13697 [(set (match_operand:XF 0 "register_operand" "") 13698 (unspec:XF [(float_extend:XF 13699 (match_operand:MODEF 2 "register_operand" ""))] 13700 UNSPEC_SINCOS_COS)) 13701 (set (match_operand:XF 1 "register_operand" "") 13702 (unspec:XF [(float_extend:XF (match_dup 2))] UNSPEC_SINCOS_SIN))] 13703 "find_regno_note (insn, REG_UNUSED, REGNO (operands[0])) 13704 && can_create_pseudo_p ()" 13705 [(set (match_dup 1) 13706 (unspec:XF [(float_extend:XF (match_dup 2))] UNSPEC_SIN))]) 13707 13708(define_split 13709 [(set (match_operand:XF 0 "register_operand" "") 13710 (unspec:XF [(float_extend:XF 13711 (match_operand:MODEF 2 "register_operand" ""))] 13712 UNSPEC_SINCOS_COS)) 13713 (set (match_operand:XF 1 "register_operand" "") 13714 (unspec:XF [(float_extend:XF (match_dup 2))] UNSPEC_SINCOS_SIN))] 13715 "find_regno_note (insn, REG_UNUSED, REGNO (operands[1])) 13716 && can_create_pseudo_p ()" 13717 [(set (match_dup 0) 13718 (unspec:XF [(float_extend:XF (match_dup 2))] UNSPEC_COS))]) 13719 13720(define_expand "sincos<mode>3" 13721 [(use (match_operand:MODEF 0 "register_operand" "")) 13722 (use (match_operand:MODEF 1 "register_operand" "")) 13723 (use (match_operand:MODEF 2 "register_operand" ""))] 13724 "TARGET_USE_FANCY_MATH_387 13725 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH) 13726 || TARGET_MIX_SSE_I387) 13727 && flag_unsafe_math_optimizations" 13728{ 13729 rtx op0 = gen_reg_rtx (XFmode); 13730 rtx op1 = gen_reg_rtx (XFmode); 13731 13732 emit_insn (gen_sincos_extend<mode>xf3_i387 (op0, op1, operands[2])); 13733 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0)); 13734 emit_insn (gen_truncxf<mode>2_i387_noop (operands[1], op1)); 13735 DONE; 13736}) 13737 13738(define_insn "fptanxf4_i387" 13739 [(set (match_operand:XF 0 "register_operand" "=f") 13740 (match_operand:XF 3 "const_double_operand" "F")) 13741 (set (match_operand:XF 1 "register_operand" "=u") 13742 (unspec:XF [(match_operand:XF 2 "register_operand" "0")] 13743 UNSPEC_TAN))] 13744 "TARGET_USE_FANCY_MATH_387 13745 && flag_unsafe_math_optimizations 13746 && standard_80387_constant_p (operands[3]) == 2" 13747 "fptan" 13748 [(set_attr "type" "fpspc") 13749 (set_attr "mode" "XF")]) 13750 13751(define_insn "fptan_extend<mode>xf4_i387" 13752 [(set (match_operand:MODEF 0 "register_operand" "=f") 13753 (match_operand:MODEF 3 "const_double_operand" "F")) 13754 (set (match_operand:XF 1 "register_operand" "=u") 13755 (unspec:XF [(float_extend:XF 13756 (match_operand:MODEF 2 "register_operand" "0"))] 13757 UNSPEC_TAN))] 13758 "TARGET_USE_FANCY_MATH_387 13759 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH) 13760 || TARGET_MIX_SSE_I387) 13761 && flag_unsafe_math_optimizations 13762 && standard_80387_constant_p (operands[3]) == 2" 13763 "fptan" 13764 [(set_attr "type" "fpspc") 13765 (set_attr "mode" "XF")]) 13766 13767(define_expand "tanxf2" 13768 [(use (match_operand:XF 0 "register_operand" "")) 13769 (use (match_operand:XF 1 "register_operand" ""))] 13770 "TARGET_USE_FANCY_MATH_387 13771 && flag_unsafe_math_optimizations" 13772{ 13773 rtx one = gen_reg_rtx (XFmode); 13774 rtx op2 = CONST1_RTX (XFmode); /* fld1 */ 13775 13776 emit_insn (gen_fptanxf4_i387 (one, operands[0], operands[1], op2)); 13777 DONE; 13778}) 13779 13780(define_expand "tan<mode>2" 13781 [(use (match_operand:MODEF 0 "register_operand" "")) 13782 (use (match_operand:MODEF 1 "register_operand" ""))] 13783 "TARGET_USE_FANCY_MATH_387 13784 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH) 13785 || TARGET_MIX_SSE_I387) 13786 && flag_unsafe_math_optimizations" 13787{ 13788 rtx op0 = gen_reg_rtx (XFmode); 13789 13790 rtx one = gen_reg_rtx (<MODE>mode); 13791 rtx op2 = CONST1_RTX (<MODE>mode); /* fld1 */ 13792 13793 emit_insn (gen_fptan_extend<mode>xf4_i387 (one, op0, 13794 operands[1], op2)); 13795 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0)); 13796 DONE; 13797}) 13798 13799(define_insn "*fpatanxf3_i387" 13800 [(set (match_operand:XF 0 "register_operand" "=f") 13801 (unspec:XF [(match_operand:XF 1 "register_operand" "0") 13802 (match_operand:XF 2 "register_operand" "u")] 13803 UNSPEC_FPATAN)) 13804 (clobber (match_scratch:XF 3 "=2"))] 13805 "TARGET_USE_FANCY_MATH_387 13806 && flag_unsafe_math_optimizations" 13807 "fpatan" 13808 [(set_attr "type" "fpspc") 13809 (set_attr "mode" "XF")]) 13810 13811(define_insn "fpatan_extend<mode>xf3_i387" 13812 [(set (match_operand:XF 0 "register_operand" "=f") 13813 (unspec:XF [(float_extend:XF 13814 (match_operand:MODEF 1 "register_operand" "0")) 13815 (float_extend:XF 13816 (match_operand:MODEF 2 "register_operand" "u"))] 13817 UNSPEC_FPATAN)) 13818 (clobber (match_scratch:XF 3 "=2"))] 13819 "TARGET_USE_FANCY_MATH_387 13820 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH) 13821 || TARGET_MIX_SSE_I387) 13822 && flag_unsafe_math_optimizations" 13823 "fpatan" 13824 [(set_attr "type" "fpspc") 13825 (set_attr "mode" "XF")]) 13826 13827(define_expand "atan2xf3" 13828 [(parallel [(set (match_operand:XF 0 "register_operand" "") 13829 (unspec:XF [(match_operand:XF 2 "register_operand" "") 13830 (match_operand:XF 1 "register_operand" "")] 13831 UNSPEC_FPATAN)) 13832 (clobber (match_scratch:XF 3 ""))])] 13833 "TARGET_USE_FANCY_MATH_387 13834 && flag_unsafe_math_optimizations") 13835 13836(define_expand "atan2<mode>3" 13837 [(use (match_operand:MODEF 0 "register_operand" "")) 13838 (use (match_operand:MODEF 1 "register_operand" "")) 13839 (use (match_operand:MODEF 2 "register_operand" ""))] 13840 "TARGET_USE_FANCY_MATH_387 13841 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH) 13842 || TARGET_MIX_SSE_I387) 13843 && flag_unsafe_math_optimizations" 13844{ 13845 rtx op0 = gen_reg_rtx (XFmode); 13846 13847 emit_insn (gen_fpatan_extend<mode>xf3_i387 (op0, operands[2], operands[1])); 13848 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0)); 13849 DONE; 13850}) 13851 13852(define_expand "atanxf2" 13853 [(parallel [(set (match_operand:XF 0 "register_operand" "") 13854 (unspec:XF [(match_dup 2) 13855 (match_operand:XF 1 "register_operand" "")] 13856 UNSPEC_FPATAN)) 13857 (clobber (match_scratch:XF 3 ""))])] 13858 "TARGET_USE_FANCY_MATH_387 13859 && flag_unsafe_math_optimizations" 13860{ 13861 operands[2] = gen_reg_rtx (XFmode); 13862 emit_move_insn (operands[2], CONST1_RTX (XFmode)); /* fld1 */ 13863}) 13864 13865(define_expand "atan<mode>2" 13866 [(use (match_operand:MODEF 0 "register_operand" "")) 13867 (use (match_operand:MODEF 1 "register_operand" ""))] 13868 "TARGET_USE_FANCY_MATH_387 13869 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH) 13870 || TARGET_MIX_SSE_I387) 13871 && flag_unsafe_math_optimizations" 13872{ 13873 rtx op0 = gen_reg_rtx (XFmode); 13874 13875 rtx op2 = gen_reg_rtx (<MODE>mode); 13876 emit_move_insn (op2, CONST1_RTX (<MODE>mode)); /* fld1 */ 13877 13878 emit_insn (gen_fpatan_extend<mode>xf3_i387 (op0, op2, operands[1])); 13879 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0)); 13880 DONE; 13881}) 13882 13883(define_expand "asinxf2" 13884 [(set (match_dup 2) 13885 (mult:XF (match_operand:XF 1 "register_operand" "") 13886 (match_dup 1))) 13887 (set (match_dup 4) (minus:XF (match_dup 3) (match_dup 2))) 13888 (set (match_dup 5) (sqrt:XF (match_dup 4))) 13889 (parallel [(set (match_operand:XF 0 "register_operand" "") 13890 (unspec:XF [(match_dup 5) (match_dup 1)] 13891 UNSPEC_FPATAN)) 13892 (clobber (match_scratch:XF 6 ""))])] 13893 "TARGET_USE_FANCY_MATH_387 13894 && flag_unsafe_math_optimizations" 13895{ 13896 int i; 13897 13898 if (optimize_insn_for_size_p ()) 13899 FAIL; 13900 13901 for (i = 2; i < 6; i++) 13902 operands[i] = gen_reg_rtx (XFmode); 13903 13904 emit_move_insn (operands[3], CONST1_RTX (XFmode)); /* fld1 */ 13905}) 13906 13907(define_expand "asin<mode>2" 13908 [(use (match_operand:MODEF 0 "register_operand" "")) 13909 (use (match_operand:MODEF 1 "general_operand" ""))] 13910 "TARGET_USE_FANCY_MATH_387 13911 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH) 13912 || TARGET_MIX_SSE_I387) 13913 && flag_unsafe_math_optimizations" 13914{ 13915 rtx op0 = gen_reg_rtx (XFmode); 13916 rtx op1 = gen_reg_rtx (XFmode); 13917 13918 if (optimize_insn_for_size_p ()) 13919 FAIL; 13920 13921 emit_insn (gen_extend<mode>xf2 (op1, operands[1])); 13922 emit_insn (gen_asinxf2 (op0, op1)); 13923 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0)); 13924 DONE; 13925}) 13926 13927(define_expand "acosxf2" 13928 [(set (match_dup 2) 13929 (mult:XF (match_operand:XF 1 "register_operand" "") 13930 (match_dup 1))) 13931 (set (match_dup 4) (minus:XF (match_dup 3) (match_dup 2))) 13932 (set (match_dup 5) (sqrt:XF (match_dup 4))) 13933 (parallel [(set (match_operand:XF 0 "register_operand" "") 13934 (unspec:XF [(match_dup 1) (match_dup 5)] 13935 UNSPEC_FPATAN)) 13936 (clobber (match_scratch:XF 6 ""))])] 13937 "TARGET_USE_FANCY_MATH_387 13938 && flag_unsafe_math_optimizations" 13939{ 13940 int i; 13941 13942 if (optimize_insn_for_size_p ()) 13943 FAIL; 13944 13945 for (i = 2; i < 6; i++) 13946 operands[i] = gen_reg_rtx (XFmode); 13947 13948 emit_move_insn (operands[3], CONST1_RTX (XFmode)); /* fld1 */ 13949}) 13950 13951(define_expand "acos<mode>2" 13952 [(use (match_operand:MODEF 0 "register_operand" "")) 13953 (use (match_operand:MODEF 1 "general_operand" ""))] 13954 "TARGET_USE_FANCY_MATH_387 13955 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH) 13956 || TARGET_MIX_SSE_I387) 13957 && flag_unsafe_math_optimizations" 13958{ 13959 rtx op0 = gen_reg_rtx (XFmode); 13960 rtx op1 = gen_reg_rtx (XFmode); 13961 13962 if (optimize_insn_for_size_p ()) 13963 FAIL; 13964 13965 emit_insn (gen_extend<mode>xf2 (op1, operands[1])); 13966 emit_insn (gen_acosxf2 (op0, op1)); 13967 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0)); 13968 DONE; 13969}) 13970 13971(define_insn "fyl2xxf3_i387" 13972 [(set (match_operand:XF 0 "register_operand" "=f") 13973 (unspec:XF [(match_operand:XF 1 "register_operand" "0") 13974 (match_operand:XF 2 "register_operand" "u")] 13975 UNSPEC_FYL2X)) 13976 (clobber (match_scratch:XF 3 "=2"))] 13977 "TARGET_USE_FANCY_MATH_387 13978 && flag_unsafe_math_optimizations" 13979 "fyl2x" 13980 [(set_attr "type" "fpspc") 13981 (set_attr "mode" "XF")]) 13982 13983(define_insn "fyl2x_extend<mode>xf3_i387" 13984 [(set (match_operand:XF 0 "register_operand" "=f") 13985 (unspec:XF [(float_extend:XF 13986 (match_operand:MODEF 1 "register_operand" "0")) 13987 (match_operand:XF 2 "register_operand" "u")] 13988 UNSPEC_FYL2X)) 13989 (clobber (match_scratch:XF 3 "=2"))] 13990 "TARGET_USE_FANCY_MATH_387 13991 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH) 13992 || TARGET_MIX_SSE_I387) 13993 && flag_unsafe_math_optimizations" 13994 "fyl2x" 13995 [(set_attr "type" "fpspc") 13996 (set_attr "mode" "XF")]) 13997 13998(define_expand "logxf2" 13999 [(parallel [(set (match_operand:XF 0 "register_operand" "") 14000 (unspec:XF [(match_operand:XF 1 "register_operand" "") 14001 (match_dup 2)] UNSPEC_FYL2X)) 14002 (clobber (match_scratch:XF 3 ""))])] 14003 "TARGET_USE_FANCY_MATH_387 14004 && flag_unsafe_math_optimizations" 14005{ 14006 operands[2] = gen_reg_rtx (XFmode); 14007 emit_move_insn (operands[2], standard_80387_constant_rtx (4)); /* fldln2 */ 14008}) 14009 14010(define_expand "log<mode>2" 14011 [(use (match_operand:MODEF 0 "register_operand" "")) 14012 (use (match_operand:MODEF 1 "register_operand" ""))] 14013 "TARGET_USE_FANCY_MATH_387 14014 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH) 14015 || TARGET_MIX_SSE_I387) 14016 && flag_unsafe_math_optimizations" 14017{ 14018 rtx op0 = gen_reg_rtx (XFmode); 14019 14020 rtx op2 = gen_reg_rtx (XFmode); 14021 emit_move_insn (op2, standard_80387_constant_rtx (4)); /* fldln2 */ 14022 14023 emit_insn (gen_fyl2x_extend<mode>xf3_i387 (op0, operands[1], op2)); 14024 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0)); 14025 DONE; 14026}) 14027 14028(define_expand "log10xf2" 14029 [(parallel [(set (match_operand:XF 0 "register_operand" "") 14030 (unspec:XF [(match_operand:XF 1 "register_operand" "") 14031 (match_dup 2)] UNSPEC_FYL2X)) 14032 (clobber (match_scratch:XF 3 ""))])] 14033 "TARGET_USE_FANCY_MATH_387 14034 && flag_unsafe_math_optimizations" 14035{ 14036 operands[2] = gen_reg_rtx (XFmode); 14037 emit_move_insn (operands[2], standard_80387_constant_rtx (3)); /* fldlg2 */ 14038}) 14039 14040(define_expand "log10<mode>2" 14041 [(use (match_operand:MODEF 0 "register_operand" "")) 14042 (use (match_operand:MODEF 1 "register_operand" ""))] 14043 "TARGET_USE_FANCY_MATH_387 14044 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH) 14045 || TARGET_MIX_SSE_I387) 14046 && flag_unsafe_math_optimizations" 14047{ 14048 rtx op0 = gen_reg_rtx (XFmode); 14049 14050 rtx op2 = gen_reg_rtx (XFmode); 14051 emit_move_insn (op2, standard_80387_constant_rtx (3)); /* fldlg2 */ 14052 14053 emit_insn (gen_fyl2x_extend<mode>xf3_i387 (op0, operands[1], op2)); 14054 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0)); 14055 DONE; 14056}) 14057 14058(define_expand "log2xf2" 14059 [(parallel [(set (match_operand:XF 0 "register_operand" "") 14060 (unspec:XF [(match_operand:XF 1 "register_operand" "") 14061 (match_dup 2)] UNSPEC_FYL2X)) 14062 (clobber (match_scratch:XF 3 ""))])] 14063 "TARGET_USE_FANCY_MATH_387 14064 && flag_unsafe_math_optimizations" 14065{ 14066 operands[2] = gen_reg_rtx (XFmode); 14067 emit_move_insn (operands[2], CONST1_RTX (XFmode)); /* fld1 */ 14068}) 14069 14070(define_expand "log2<mode>2" 14071 [(use (match_operand:MODEF 0 "register_operand" "")) 14072 (use (match_operand:MODEF 1 "register_operand" ""))] 14073 "TARGET_USE_FANCY_MATH_387 14074 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH) 14075 || TARGET_MIX_SSE_I387) 14076 && flag_unsafe_math_optimizations" 14077{ 14078 rtx op0 = gen_reg_rtx (XFmode); 14079 14080 rtx op2 = gen_reg_rtx (XFmode); 14081 emit_move_insn (op2, CONST1_RTX (XFmode)); /* fld1 */ 14082 14083 emit_insn (gen_fyl2x_extend<mode>xf3_i387 (op0, operands[1], op2)); 14084 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0)); 14085 DONE; 14086}) 14087 14088(define_insn "fyl2xp1xf3_i387" 14089 [(set (match_operand:XF 0 "register_operand" "=f") 14090 (unspec:XF [(match_operand:XF 1 "register_operand" "0") 14091 (match_operand:XF 2 "register_operand" "u")] 14092 UNSPEC_FYL2XP1)) 14093 (clobber (match_scratch:XF 3 "=2"))] 14094 "TARGET_USE_FANCY_MATH_387 14095 && flag_unsafe_math_optimizations" 14096 "fyl2xp1" 14097 [(set_attr "type" "fpspc") 14098 (set_attr "mode" "XF")]) 14099 14100(define_insn "fyl2xp1_extend<mode>xf3_i387" 14101 [(set (match_operand:XF 0 "register_operand" "=f") 14102 (unspec:XF [(float_extend:XF 14103 (match_operand:MODEF 1 "register_operand" "0")) 14104 (match_operand:XF 2 "register_operand" "u")] 14105 UNSPEC_FYL2XP1)) 14106 (clobber (match_scratch:XF 3 "=2"))] 14107 "TARGET_USE_FANCY_MATH_387 14108 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH) 14109 || TARGET_MIX_SSE_I387) 14110 && flag_unsafe_math_optimizations" 14111 "fyl2xp1" 14112 [(set_attr "type" "fpspc") 14113 (set_attr "mode" "XF")]) 14114 14115(define_expand "log1pxf2" 14116 [(use (match_operand:XF 0 "register_operand" "")) 14117 (use (match_operand:XF 1 "register_operand" ""))] 14118 "TARGET_USE_FANCY_MATH_387 14119 && flag_unsafe_math_optimizations" 14120{ 14121 if (optimize_insn_for_size_p ()) 14122 FAIL; 14123 14124 ix86_emit_i387_log1p (operands[0], operands[1]); 14125 DONE; 14126}) 14127 14128(define_expand "log1p<mode>2" 14129 [(use (match_operand:MODEF 0 "register_operand" "")) 14130 (use (match_operand:MODEF 1 "register_operand" ""))] 14131 "TARGET_USE_FANCY_MATH_387 14132 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH) 14133 || TARGET_MIX_SSE_I387) 14134 && flag_unsafe_math_optimizations" 14135{ 14136 rtx op0; 14137 14138 if (optimize_insn_for_size_p ()) 14139 FAIL; 14140 14141 op0 = gen_reg_rtx (XFmode); 14142 14143 operands[1] = gen_rtx_FLOAT_EXTEND (XFmode, operands[1]); 14144 14145 ix86_emit_i387_log1p (op0, operands[1]); 14146 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0)); 14147 DONE; 14148}) 14149 14150(define_insn "fxtractxf3_i387" 14151 [(set (match_operand:XF 0 "register_operand" "=f") 14152 (unspec:XF [(match_operand:XF 2 "register_operand" "0")] 14153 UNSPEC_XTRACT_FRACT)) 14154 (set (match_operand:XF 1 "register_operand" "=u") 14155 (unspec:XF [(match_dup 2)] UNSPEC_XTRACT_EXP))] 14156 "TARGET_USE_FANCY_MATH_387 14157 && flag_unsafe_math_optimizations" 14158 "fxtract" 14159 [(set_attr "type" "fpspc") 14160 (set_attr "mode" "XF")]) 14161 14162(define_insn "fxtract_extend<mode>xf3_i387" 14163 [(set (match_operand:XF 0 "register_operand" "=f") 14164 (unspec:XF [(float_extend:XF 14165 (match_operand:MODEF 2 "register_operand" "0"))] 14166 UNSPEC_XTRACT_FRACT)) 14167 (set (match_operand:XF 1 "register_operand" "=u") 14168 (unspec:XF [(float_extend:XF (match_dup 2))] UNSPEC_XTRACT_EXP))] 14169 "TARGET_USE_FANCY_MATH_387 14170 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH) 14171 || TARGET_MIX_SSE_I387) 14172 && flag_unsafe_math_optimizations" 14173 "fxtract" 14174 [(set_attr "type" "fpspc") 14175 (set_attr "mode" "XF")]) 14176 14177(define_expand "logbxf2" 14178 [(parallel [(set (match_dup 2) 14179 (unspec:XF [(match_operand:XF 1 "register_operand" "")] 14180 UNSPEC_XTRACT_FRACT)) 14181 (set (match_operand:XF 0 "register_operand" "") 14182 (unspec:XF [(match_dup 1)] UNSPEC_XTRACT_EXP))])] 14183 "TARGET_USE_FANCY_MATH_387 14184 && flag_unsafe_math_optimizations" 14185 "operands[2] = gen_reg_rtx (XFmode);") 14186 14187(define_expand "logb<mode>2" 14188 [(use (match_operand:MODEF 0 "register_operand" "")) 14189 (use (match_operand:MODEF 1 "register_operand" ""))] 14190 "TARGET_USE_FANCY_MATH_387 14191 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH) 14192 || TARGET_MIX_SSE_I387) 14193 && flag_unsafe_math_optimizations" 14194{ 14195 rtx op0 = gen_reg_rtx (XFmode); 14196 rtx op1 = gen_reg_rtx (XFmode); 14197 14198 emit_insn (gen_fxtract_extend<mode>xf3_i387 (op0, op1, operands[1])); 14199 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op1)); 14200 DONE; 14201}) 14202 14203(define_expand "ilogbxf2" 14204 [(use (match_operand:SI 0 "register_operand" "")) 14205 (use (match_operand:XF 1 "register_operand" ""))] 14206 "TARGET_USE_FANCY_MATH_387 14207 && flag_unsafe_math_optimizations" 14208{ 14209 rtx op0, op1; 14210 14211 if (optimize_insn_for_size_p ()) 14212 FAIL; 14213 14214 op0 = gen_reg_rtx (XFmode); 14215 op1 = gen_reg_rtx (XFmode); 14216 14217 emit_insn (gen_fxtractxf3_i387 (op0, op1, operands[1])); 14218 emit_insn (gen_fix_truncxfsi2 (operands[0], op1)); 14219 DONE; 14220}) 14221 14222(define_expand "ilogb<mode>2" 14223 [(use (match_operand:SI 0 "register_operand" "")) 14224 (use (match_operand:MODEF 1 "register_operand" ""))] 14225 "TARGET_USE_FANCY_MATH_387 14226 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH) 14227 || TARGET_MIX_SSE_I387) 14228 && flag_unsafe_math_optimizations" 14229{ 14230 rtx op0, op1; 14231 14232 if (optimize_insn_for_size_p ()) 14233 FAIL; 14234 14235 op0 = gen_reg_rtx (XFmode); 14236 op1 = gen_reg_rtx (XFmode); 14237 14238 emit_insn (gen_fxtract_extend<mode>xf3_i387 (op0, op1, operands[1])); 14239 emit_insn (gen_fix_truncxfsi2 (operands[0], op1)); 14240 DONE; 14241}) 14242 14243(define_insn "*f2xm1xf2_i387" 14244 [(set (match_operand:XF 0 "register_operand" "=f") 14245 (unspec:XF [(match_operand:XF 1 "register_operand" "0")] 14246 UNSPEC_F2XM1))] 14247 "TARGET_USE_FANCY_MATH_387 14248 && flag_unsafe_math_optimizations" 14249 "f2xm1" 14250 [(set_attr "type" "fpspc") 14251 (set_attr "mode" "XF")]) 14252 14253(define_insn "*fscalexf4_i387" 14254 [(set (match_operand:XF 0 "register_operand" "=f") 14255 (unspec:XF [(match_operand:XF 2 "register_operand" "0") 14256 (match_operand:XF 3 "register_operand" "1")] 14257 UNSPEC_FSCALE_FRACT)) 14258 (set (match_operand:XF 1 "register_operand" "=u") 14259 (unspec:XF [(match_dup 2) (match_dup 3)] 14260 UNSPEC_FSCALE_EXP))] 14261 "TARGET_USE_FANCY_MATH_387 14262 && flag_unsafe_math_optimizations" 14263 "fscale" 14264 [(set_attr "type" "fpspc") 14265 (set_attr "mode" "XF")]) 14266 14267(define_expand "expNcorexf3" 14268 [(set (match_dup 3) (mult:XF (match_operand:XF 1 "register_operand" "") 14269 (match_operand:XF 2 "register_operand" ""))) 14270 (set (match_dup 4) (unspec:XF [(match_dup 3)] UNSPEC_FRNDINT)) 14271 (set (match_dup 5) (minus:XF (match_dup 3) (match_dup 4))) 14272 (set (match_dup 6) (unspec:XF [(match_dup 5)] UNSPEC_F2XM1)) 14273 (set (match_dup 8) (plus:XF (match_dup 6) (match_dup 7))) 14274 (parallel [(set (match_operand:XF 0 "register_operand" "") 14275 (unspec:XF [(match_dup 8) (match_dup 4)] 14276 UNSPEC_FSCALE_FRACT)) 14277 (set (match_dup 9) 14278 (unspec:XF [(match_dup 8) (match_dup 4)] 14279 UNSPEC_FSCALE_EXP))])] 14280 "TARGET_USE_FANCY_MATH_387 14281 && flag_unsafe_math_optimizations" 14282{ 14283 int i; 14284 14285 if (optimize_insn_for_size_p ()) 14286 FAIL; 14287 14288 for (i = 3; i < 10; i++) 14289 operands[i] = gen_reg_rtx (XFmode); 14290 14291 emit_move_insn (operands[7], CONST1_RTX (XFmode)); /* fld1 */ 14292}) 14293 14294(define_expand "expxf2" 14295 [(use (match_operand:XF 0 "register_operand" "")) 14296 (use (match_operand:XF 1 "register_operand" ""))] 14297 "TARGET_USE_FANCY_MATH_387 14298 && flag_unsafe_math_optimizations" 14299{ 14300 rtx op2; 14301 14302 if (optimize_insn_for_size_p ()) 14303 FAIL; 14304 14305 op2 = gen_reg_rtx (XFmode); 14306 emit_move_insn (op2, standard_80387_constant_rtx (5)); /* fldl2e */ 14307 14308 emit_insn (gen_expNcorexf3 (operands[0], operands[1], op2)); 14309 DONE; 14310}) 14311 14312(define_expand "exp<mode>2" 14313 [(use (match_operand:MODEF 0 "register_operand" "")) 14314 (use (match_operand:MODEF 1 "general_operand" ""))] 14315 "TARGET_USE_FANCY_MATH_387 14316 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH) 14317 || TARGET_MIX_SSE_I387) 14318 && flag_unsafe_math_optimizations" 14319{ 14320 rtx op0, op1; 14321 14322 if (optimize_insn_for_size_p ()) 14323 FAIL; 14324 14325 op0 = gen_reg_rtx (XFmode); 14326 op1 = gen_reg_rtx (XFmode); 14327 14328 emit_insn (gen_extend<mode>xf2 (op1, operands[1])); 14329 emit_insn (gen_expxf2 (op0, op1)); 14330 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0)); 14331 DONE; 14332}) 14333 14334(define_expand "exp10xf2" 14335 [(use (match_operand:XF 0 "register_operand" "")) 14336 (use (match_operand:XF 1 "register_operand" ""))] 14337 "TARGET_USE_FANCY_MATH_387 14338 && flag_unsafe_math_optimizations" 14339{ 14340 rtx op2; 14341 14342 if (optimize_insn_for_size_p ()) 14343 FAIL; 14344 14345 op2 = gen_reg_rtx (XFmode); 14346 emit_move_insn (op2, standard_80387_constant_rtx (6)); /* fldl2t */ 14347 14348 emit_insn (gen_expNcorexf3 (operands[0], operands[1], op2)); 14349 DONE; 14350}) 14351 14352(define_expand "exp10<mode>2" 14353 [(use (match_operand:MODEF 0 "register_operand" "")) 14354 (use (match_operand:MODEF 1 "general_operand" ""))] 14355 "TARGET_USE_FANCY_MATH_387 14356 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH) 14357 || TARGET_MIX_SSE_I387) 14358 && flag_unsafe_math_optimizations" 14359{ 14360 rtx op0, op1; 14361 14362 if (optimize_insn_for_size_p ()) 14363 FAIL; 14364 14365 op0 = gen_reg_rtx (XFmode); 14366 op1 = gen_reg_rtx (XFmode); 14367 14368 emit_insn (gen_extend<mode>xf2 (op1, operands[1])); 14369 emit_insn (gen_exp10xf2 (op0, op1)); 14370 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0)); 14371 DONE; 14372}) 14373 14374(define_expand "exp2xf2" 14375 [(use (match_operand:XF 0 "register_operand" "")) 14376 (use (match_operand:XF 1 "register_operand" ""))] 14377 "TARGET_USE_FANCY_MATH_387 14378 && flag_unsafe_math_optimizations" 14379{ 14380 rtx op2; 14381 14382 if (optimize_insn_for_size_p ()) 14383 FAIL; 14384 14385 op2 = gen_reg_rtx (XFmode); 14386 emit_move_insn (op2, CONST1_RTX (XFmode)); /* fld1 */ 14387 14388 emit_insn (gen_expNcorexf3 (operands[0], operands[1], op2)); 14389 DONE; 14390}) 14391 14392(define_expand "exp2<mode>2" 14393 [(use (match_operand:MODEF 0 "register_operand" "")) 14394 (use (match_operand:MODEF 1 "general_operand" ""))] 14395 "TARGET_USE_FANCY_MATH_387 14396 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH) 14397 || TARGET_MIX_SSE_I387) 14398 && flag_unsafe_math_optimizations" 14399{ 14400 rtx op0, op1; 14401 14402 if (optimize_insn_for_size_p ()) 14403 FAIL; 14404 14405 op0 = gen_reg_rtx (XFmode); 14406 op1 = gen_reg_rtx (XFmode); 14407 14408 emit_insn (gen_extend<mode>xf2 (op1, operands[1])); 14409 emit_insn (gen_exp2xf2 (op0, op1)); 14410 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0)); 14411 DONE; 14412}) 14413 14414(define_expand "expm1xf2" 14415 [(set (match_dup 3) (mult:XF (match_operand:XF 1 "register_operand" "") 14416 (match_dup 2))) 14417 (set (match_dup 4) (unspec:XF [(match_dup 3)] UNSPEC_FRNDINT)) 14418 (set (match_dup 5) (minus:XF (match_dup 3) (match_dup 4))) 14419 (set (match_dup 9) (float_extend:XF (match_dup 13))) 14420 (set (match_dup 6) (unspec:XF [(match_dup 5)] UNSPEC_F2XM1)) 14421 (parallel [(set (match_dup 7) 14422 (unspec:XF [(match_dup 6) (match_dup 4)] 14423 UNSPEC_FSCALE_FRACT)) 14424 (set (match_dup 8) 14425 (unspec:XF [(match_dup 6) (match_dup 4)] 14426 UNSPEC_FSCALE_EXP))]) 14427 (parallel [(set (match_dup 10) 14428 (unspec:XF [(match_dup 9) (match_dup 8)] 14429 UNSPEC_FSCALE_FRACT)) 14430 (set (match_dup 11) 14431 (unspec:XF [(match_dup 9) (match_dup 8)] 14432 UNSPEC_FSCALE_EXP))]) 14433 (set (match_dup 12) (minus:XF (match_dup 10) 14434 (float_extend:XF (match_dup 13)))) 14435 (set (match_operand:XF 0 "register_operand" "") 14436 (plus:XF (match_dup 12) (match_dup 7)))] 14437 "TARGET_USE_FANCY_MATH_387 14438 && flag_unsafe_math_optimizations" 14439{ 14440 int i; 14441 14442 if (optimize_insn_for_size_p ()) 14443 FAIL; 14444 14445 for (i = 2; i < 13; i++) 14446 operands[i] = gen_reg_rtx (XFmode); 14447 14448 operands[13] 14449 = validize_mem (force_const_mem (SFmode, CONST1_RTX (SFmode))); /* fld1 */ 14450 14451 emit_move_insn (operands[2], standard_80387_constant_rtx (5)); /* fldl2e */ 14452}) 14453 14454(define_expand "expm1<mode>2" 14455 [(use (match_operand:MODEF 0 "register_operand" "")) 14456 (use (match_operand:MODEF 1 "general_operand" ""))] 14457 "TARGET_USE_FANCY_MATH_387 14458 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH) 14459 || TARGET_MIX_SSE_I387) 14460 && flag_unsafe_math_optimizations" 14461{ 14462 rtx op0, op1; 14463 14464 if (optimize_insn_for_size_p ()) 14465 FAIL; 14466 14467 op0 = gen_reg_rtx (XFmode); 14468 op1 = gen_reg_rtx (XFmode); 14469 14470 emit_insn (gen_extend<mode>xf2 (op1, operands[1])); 14471 emit_insn (gen_expm1xf2 (op0, op1)); 14472 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0)); 14473 DONE; 14474}) 14475 14476(define_expand "ldexpxf3" 14477 [(set (match_dup 3) 14478 (float:XF (match_operand:SI 2 "register_operand" ""))) 14479 (parallel [(set (match_operand:XF 0 " register_operand" "") 14480 (unspec:XF [(match_operand:XF 1 "register_operand" "") 14481 (match_dup 3)] 14482 UNSPEC_FSCALE_FRACT)) 14483 (set (match_dup 4) 14484 (unspec:XF [(match_dup 1) (match_dup 3)] 14485 UNSPEC_FSCALE_EXP))])] 14486 "TARGET_USE_FANCY_MATH_387 14487 && flag_unsafe_math_optimizations" 14488{ 14489 if (optimize_insn_for_size_p ()) 14490 FAIL; 14491 14492 operands[3] = gen_reg_rtx (XFmode); 14493 operands[4] = gen_reg_rtx (XFmode); 14494}) 14495 14496(define_expand "ldexp<mode>3" 14497 [(use (match_operand:MODEF 0 "register_operand" "")) 14498 (use (match_operand:MODEF 1 "general_operand" "")) 14499 (use (match_operand:SI 2 "register_operand" ""))] 14500 "TARGET_USE_FANCY_MATH_387 14501 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH) 14502 || TARGET_MIX_SSE_I387) 14503 && flag_unsafe_math_optimizations" 14504{ 14505 rtx op0, op1; 14506 14507 if (optimize_insn_for_size_p ()) 14508 FAIL; 14509 14510 op0 = gen_reg_rtx (XFmode); 14511 op1 = gen_reg_rtx (XFmode); 14512 14513 emit_insn (gen_extend<mode>xf2 (op1, operands[1])); 14514 emit_insn (gen_ldexpxf3 (op0, op1, operands[2])); 14515 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0)); 14516 DONE; 14517}) 14518 14519(define_expand "scalbxf3" 14520 [(parallel [(set (match_operand:XF 0 " register_operand" "") 14521 (unspec:XF [(match_operand:XF 1 "register_operand" "") 14522 (match_operand:XF 2 "register_operand" "")] 14523 UNSPEC_FSCALE_FRACT)) 14524 (set (match_dup 3) 14525 (unspec:XF [(match_dup 1) (match_dup 2)] 14526 UNSPEC_FSCALE_EXP))])] 14527 "TARGET_USE_FANCY_MATH_387 14528 && flag_unsafe_math_optimizations" 14529{ 14530 if (optimize_insn_for_size_p ()) 14531 FAIL; 14532 14533 operands[3] = gen_reg_rtx (XFmode); 14534}) 14535 14536(define_expand "scalb<mode>3" 14537 [(use (match_operand:MODEF 0 "register_operand" "")) 14538 (use (match_operand:MODEF 1 "general_operand" "")) 14539 (use (match_operand:MODEF 2 "general_operand" ""))] 14540 "TARGET_USE_FANCY_MATH_387 14541 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH) 14542 || TARGET_MIX_SSE_I387) 14543 && flag_unsafe_math_optimizations" 14544{ 14545 rtx op0, op1, op2; 14546 14547 if (optimize_insn_for_size_p ()) 14548 FAIL; 14549 14550 op0 = gen_reg_rtx (XFmode); 14551 op1 = gen_reg_rtx (XFmode); 14552 op2 = gen_reg_rtx (XFmode); 14553 14554 emit_insn (gen_extend<mode>xf2 (op1, operands[1])); 14555 emit_insn (gen_extend<mode>xf2 (op2, operands[2])); 14556 emit_insn (gen_scalbxf3 (op0, op1, op2)); 14557 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0)); 14558 DONE; 14559}) 14560 14561(define_expand "significandxf2" 14562 [(parallel [(set (match_operand:XF 0 "register_operand" "") 14563 (unspec:XF [(match_operand:XF 1 "register_operand" "")] 14564 UNSPEC_XTRACT_FRACT)) 14565 (set (match_dup 2) 14566 (unspec:XF [(match_dup 1)] UNSPEC_XTRACT_EXP))])] 14567 "TARGET_USE_FANCY_MATH_387 14568 && flag_unsafe_math_optimizations" 14569 "operands[2] = gen_reg_rtx (XFmode);") 14570 14571(define_expand "significand<mode>2" 14572 [(use (match_operand:MODEF 0 "register_operand" "")) 14573 (use (match_operand:MODEF 1 "register_operand" ""))] 14574 "TARGET_USE_FANCY_MATH_387 14575 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH) 14576 || TARGET_MIX_SSE_I387) 14577 && flag_unsafe_math_optimizations" 14578{ 14579 rtx op0 = gen_reg_rtx (XFmode); 14580 rtx op1 = gen_reg_rtx (XFmode); 14581 14582 emit_insn (gen_fxtract_extend<mode>xf3_i387 (op0, op1, operands[1])); 14583 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0)); 14584 DONE; 14585}) 14586 14587 14588(define_insn "sse4_1_round<mode>2" 14589 [(set (match_operand:MODEF 0 "register_operand" "=x") 14590 (unspec:MODEF [(match_operand:MODEF 1 "register_operand" "x") 14591 (match_operand:SI 2 "const_0_to_15_operand" "n")] 14592 UNSPEC_ROUND))] 14593 "TARGET_ROUND" 14594 "%vround<ssemodesuffix>\t{%2, %1, %d0|%d0, %1, %2}" 14595 [(set_attr "type" "ssecvt") 14596 (set_attr "prefix_extra" "1") 14597 (set_attr "prefix" "maybe_vex") 14598 (set_attr "mode" "<MODE>")]) 14599 14600(define_insn "rintxf2" 14601 [(set (match_operand:XF 0 "register_operand" "=f") 14602 (unspec:XF [(match_operand:XF 1 "register_operand" "0")] 14603 UNSPEC_FRNDINT))] 14604 "TARGET_USE_FANCY_MATH_387 14605 && flag_unsafe_math_optimizations" 14606 "frndint" 14607 [(set_attr "type" "fpspc") 14608 (set_attr "mode" "XF")]) 14609 14610(define_expand "rint<mode>2" 14611 [(use (match_operand:MODEF 0 "register_operand" "")) 14612 (use (match_operand:MODEF 1 "register_operand" ""))] 14613 "(TARGET_USE_FANCY_MATH_387 14614 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH) 14615 || TARGET_MIX_SSE_I387) 14616 && flag_unsafe_math_optimizations) 14617 || (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH 14618 && !flag_trapping_math)" 14619{ 14620 if (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH 14621 && !flag_trapping_math) 14622 { 14623 if (TARGET_ROUND) 14624 emit_insn (gen_sse4_1_round<mode>2 14625 (operands[0], operands[1], GEN_INT (ROUND_MXCSR))); 14626 else if (optimize_insn_for_size_p ()) 14627 FAIL; 14628 else 14629 ix86_expand_rint (operands[0], operands[1]); 14630 } 14631 else 14632 { 14633 rtx op0 = gen_reg_rtx (XFmode); 14634 rtx op1 = gen_reg_rtx (XFmode); 14635 14636 emit_insn (gen_extend<mode>xf2 (op1, operands[1])); 14637 emit_insn (gen_rintxf2 (op0, op1)); 14638 14639 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0)); 14640 } 14641 DONE; 14642}) 14643 14644(define_expand "round<mode>2" 14645 [(match_operand:X87MODEF 0 "register_operand" "") 14646 (match_operand:X87MODEF 1 "nonimmediate_operand" "")] 14647 "(TARGET_USE_FANCY_MATH_387 14648 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH) 14649 || TARGET_MIX_SSE_I387) 14650 && flag_unsafe_math_optimizations) 14651 || (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH 14652 && !flag_trapping_math && !flag_rounding_math)" 14653{ 14654 if (optimize_insn_for_size_p ()) 14655 FAIL; 14656 14657 if (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH 14658 && !flag_trapping_math && !flag_rounding_math) 14659 { 14660 if (TARGET_ROUND) 14661 { 14662 operands[1] = force_reg (<MODE>mode, operands[1]); 14663 ix86_expand_round_sse4 (operands[0], operands[1]); 14664 } 14665 else if (TARGET_64BIT || (<MODE>mode != DFmode)) 14666 ix86_expand_round (operands[0], operands[1]); 14667 else 14668 ix86_expand_rounddf_32 (operands[0], operands[1]); 14669 } 14670 else 14671 { 14672 operands[1] = force_reg (<MODE>mode, operands[1]); 14673 ix86_emit_i387_round (operands[0], operands[1]); 14674 } 14675 DONE; 14676}) 14677 14678(define_insn_and_split "*fistdi2_1" 14679 [(set (match_operand:DI 0 "nonimmediate_operand" "") 14680 (unspec:DI [(match_operand:XF 1 "register_operand" "")] 14681 UNSPEC_FIST))] 14682 "TARGET_USE_FANCY_MATH_387 14683 && can_create_pseudo_p ()" 14684 "#" 14685 "&& 1" 14686 [(const_int 0)] 14687{ 14688 if (memory_operand (operands[0], VOIDmode)) 14689 emit_insn (gen_fistdi2 (operands[0], operands[1])); 14690 else 14691 { 14692 operands[2] = assign_386_stack_local (DImode, SLOT_TEMP); 14693 emit_insn (gen_fistdi2_with_temp (operands[0], operands[1], 14694 operands[2])); 14695 } 14696 DONE; 14697} 14698 [(set_attr "type" "fpspc") 14699 (set_attr "mode" "DI")]) 14700 14701(define_insn "fistdi2" 14702 [(set (match_operand:DI 0 "memory_operand" "=m") 14703 (unspec:DI [(match_operand:XF 1 "register_operand" "f")] 14704 UNSPEC_FIST)) 14705 (clobber (match_scratch:XF 2 "=&1f"))] 14706 "TARGET_USE_FANCY_MATH_387" 14707 "* return output_fix_trunc (insn, operands, false);" 14708 [(set_attr "type" "fpspc") 14709 (set_attr "mode" "DI")]) 14710 14711(define_insn "fistdi2_with_temp" 14712 [(set (match_operand:DI 0 "nonimmediate_operand" "=m,?r") 14713 (unspec:DI [(match_operand:XF 1 "register_operand" "f,f")] 14714 UNSPEC_FIST)) 14715 (clobber (match_operand:DI 2 "memory_operand" "=X,m")) 14716 (clobber (match_scratch:XF 3 "=&1f,&1f"))] 14717 "TARGET_USE_FANCY_MATH_387" 14718 "#" 14719 [(set_attr "type" "fpspc") 14720 (set_attr "mode" "DI")]) 14721 14722(define_split 14723 [(set (match_operand:DI 0 "register_operand" "") 14724 (unspec:DI [(match_operand:XF 1 "register_operand" "")] 14725 UNSPEC_FIST)) 14726 (clobber (match_operand:DI 2 "memory_operand" "")) 14727 (clobber (match_scratch 3 ""))] 14728 "reload_completed" 14729 [(parallel [(set (match_dup 2) (unspec:DI [(match_dup 1)] UNSPEC_FIST)) 14730 (clobber (match_dup 3))]) 14731 (set (match_dup 0) (match_dup 2))]) 14732 14733(define_split 14734 [(set (match_operand:DI 0 "memory_operand" "") 14735 (unspec:DI [(match_operand:XF 1 "register_operand" "")] 14736 UNSPEC_FIST)) 14737 (clobber (match_operand:DI 2 "memory_operand" "")) 14738 (clobber (match_scratch 3 ""))] 14739 "reload_completed" 14740 [(parallel [(set (match_dup 0) (unspec:DI [(match_dup 1)] UNSPEC_FIST)) 14741 (clobber (match_dup 3))])]) 14742 14743(define_insn_and_split "*fist<mode>2_1" 14744 [(set (match_operand:SWI24 0 "register_operand" "") 14745 (unspec:SWI24 [(match_operand:XF 1 "register_operand" "")] 14746 UNSPEC_FIST))] 14747 "TARGET_USE_FANCY_MATH_387 14748 && can_create_pseudo_p ()" 14749 "#" 14750 "&& 1" 14751 [(const_int 0)] 14752{ 14753 operands[2] = assign_386_stack_local (<MODE>mode, SLOT_TEMP); 14754 emit_insn (gen_fist<mode>2_with_temp (operands[0], operands[1], 14755 operands[2])); 14756 DONE; 14757} 14758 [(set_attr "type" "fpspc") 14759 (set_attr "mode" "<MODE>")]) 14760 14761(define_insn "fist<mode>2" 14762 [(set (match_operand:SWI24 0 "memory_operand" "=m") 14763 (unspec:SWI24 [(match_operand:XF 1 "register_operand" "f")] 14764 UNSPEC_FIST))] 14765 "TARGET_USE_FANCY_MATH_387" 14766 "* return output_fix_trunc (insn, operands, false);" 14767 [(set_attr "type" "fpspc") 14768 (set_attr "mode" "<MODE>")]) 14769 14770(define_insn "fist<mode>2_with_temp" 14771 [(set (match_operand:SWI24 0 "register_operand" "=r") 14772 (unspec:SWI24 [(match_operand:XF 1 "register_operand" "f")] 14773 UNSPEC_FIST)) 14774 (clobber (match_operand:SWI24 2 "memory_operand" "=m"))] 14775 "TARGET_USE_FANCY_MATH_387" 14776 "#" 14777 [(set_attr "type" "fpspc") 14778 (set_attr "mode" "<MODE>")]) 14779 14780(define_split 14781 [(set (match_operand:SWI24 0 "register_operand" "") 14782 (unspec:SWI24 [(match_operand:XF 1 "register_operand" "")] 14783 UNSPEC_FIST)) 14784 (clobber (match_operand:SWI24 2 "memory_operand" ""))] 14785 "reload_completed" 14786 [(set (match_dup 2) (unspec:SWI24 [(match_dup 1)] UNSPEC_FIST)) 14787 (set (match_dup 0) (match_dup 2))]) 14788 14789(define_split 14790 [(set (match_operand:SWI24 0 "memory_operand" "") 14791 (unspec:SWI24 [(match_operand:XF 1 "register_operand" "")] 14792 UNSPEC_FIST)) 14793 (clobber (match_operand:SWI24 2 "memory_operand" ""))] 14794 "reload_completed" 14795 [(set (match_dup 0) (unspec:SWI24 [(match_dup 1)] UNSPEC_FIST))]) 14796 14797(define_expand "lrintxf<mode>2" 14798 [(set (match_operand:SWI248x 0 "nonimmediate_operand" "") 14799 (unspec:SWI248x [(match_operand:XF 1 "register_operand" "")] 14800 UNSPEC_FIST))] 14801 "TARGET_USE_FANCY_MATH_387") 14802 14803(define_expand "lrint<MODEF:mode><SWI48x:mode>2" 14804 [(set (match_operand:SWI48x 0 "nonimmediate_operand" "") 14805 (unspec:SWI48x [(match_operand:MODEF 1 "register_operand" "")] 14806 UNSPEC_FIX_NOTRUNC))] 14807 "SSE_FLOAT_MODE_P (<MODEF:MODE>mode) && TARGET_SSE_MATH 14808 && ((<SWI48x:MODE>mode != DImode) || TARGET_64BIT)") 14809 14810(define_expand "lround<X87MODEF:mode><SWI248x:mode>2" 14811 [(match_operand:SWI248x 0 "nonimmediate_operand" "") 14812 (match_operand:X87MODEF 1 "register_operand" "")] 14813 "(TARGET_USE_FANCY_MATH_387 14814 && (!(SSE_FLOAT_MODE_P (<X87MODEF:MODE>mode) && TARGET_SSE_MATH) 14815 || TARGET_MIX_SSE_I387) 14816 && flag_unsafe_math_optimizations) 14817 || (SSE_FLOAT_MODE_P (<X87MODEF:MODE>mode) && TARGET_SSE_MATH 14818 && <SWI248x:MODE>mode != HImode 14819 && ((<SWI248x:MODE>mode != DImode) || TARGET_64BIT) 14820 && !flag_trapping_math && !flag_rounding_math)" 14821{ 14822 if (optimize_insn_for_size_p ()) 14823 FAIL; 14824 14825 if (SSE_FLOAT_MODE_P (<X87MODEF:MODE>mode) && TARGET_SSE_MATH 14826 && <SWI248x:MODE>mode != HImode 14827 && ((<SWI248x:MODE>mode != DImode) || TARGET_64BIT) 14828 && !flag_trapping_math && !flag_rounding_math) 14829 ix86_expand_lround (operands[0], operands[1]); 14830 else 14831 ix86_emit_i387_round (operands[0], operands[1]); 14832 DONE; 14833}) 14834 14835;; Rounding mode control word calculation could clobber FLAGS_REG. 14836(define_insn_and_split "frndintxf2_floor" 14837 [(set (match_operand:XF 0 "register_operand" "") 14838 (unspec:XF [(match_operand:XF 1 "register_operand" "")] 14839 UNSPEC_FRNDINT_FLOOR)) 14840 (clobber (reg:CC FLAGS_REG))] 14841 "TARGET_USE_FANCY_MATH_387 14842 && flag_unsafe_math_optimizations 14843 && can_create_pseudo_p ()" 14844 "#" 14845 "&& 1" 14846 [(const_int 0)] 14847{ 14848 ix86_optimize_mode_switching[I387_FLOOR] = 1; 14849 14850 operands[2] = assign_386_stack_local (HImode, SLOT_CW_STORED); 14851 operands[3] = assign_386_stack_local (HImode, SLOT_CW_FLOOR); 14852 14853 emit_insn (gen_frndintxf2_floor_i387 (operands[0], operands[1], 14854 operands[2], operands[3])); 14855 DONE; 14856} 14857 [(set_attr "type" "frndint") 14858 (set_attr "i387_cw" "floor") 14859 (set_attr "mode" "XF")]) 14860 14861(define_insn "frndintxf2_floor_i387" 14862 [(set (match_operand:XF 0 "register_operand" "=f") 14863 (unspec:XF [(match_operand:XF 1 "register_operand" "0")] 14864 UNSPEC_FRNDINT_FLOOR)) 14865 (use (match_operand:HI 2 "memory_operand" "m")) 14866 (use (match_operand:HI 3 "memory_operand" "m"))] 14867 "TARGET_USE_FANCY_MATH_387 14868 && flag_unsafe_math_optimizations" 14869 "fldcw\t%3\n\tfrndint\n\tfldcw\t%2" 14870 [(set_attr "type" "frndint") 14871 (set_attr "i387_cw" "floor") 14872 (set_attr "mode" "XF")]) 14873 14874(define_expand "floorxf2" 14875 [(use (match_operand:XF 0 "register_operand" "")) 14876 (use (match_operand:XF 1 "register_operand" ""))] 14877 "TARGET_USE_FANCY_MATH_387 14878 && flag_unsafe_math_optimizations" 14879{ 14880 if (optimize_insn_for_size_p ()) 14881 FAIL; 14882 emit_insn (gen_frndintxf2_floor (operands[0], operands[1])); 14883 DONE; 14884}) 14885 14886(define_expand "floor<mode>2" 14887 [(use (match_operand:MODEF 0 "register_operand" "")) 14888 (use (match_operand:MODEF 1 "register_operand" ""))] 14889 "(TARGET_USE_FANCY_MATH_387 14890 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH) 14891 || TARGET_MIX_SSE_I387) 14892 && flag_unsafe_math_optimizations) 14893 || (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH 14894 && !flag_trapping_math)" 14895{ 14896 if (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH 14897 && !flag_trapping_math) 14898 { 14899 if (TARGET_ROUND) 14900 emit_insn (gen_sse4_1_round<mode>2 14901 (operands[0], operands[1], GEN_INT (ROUND_FLOOR))); 14902 else if (optimize_insn_for_size_p ()) 14903 FAIL; 14904 else if (TARGET_64BIT || (<MODE>mode != DFmode)) 14905 ix86_expand_floorceil (operands[0], operands[1], true); 14906 else 14907 ix86_expand_floorceildf_32 (operands[0], operands[1], true); 14908 } 14909 else 14910 { 14911 rtx op0, op1; 14912 14913 if (optimize_insn_for_size_p ()) 14914 FAIL; 14915 14916 op0 = gen_reg_rtx (XFmode); 14917 op1 = gen_reg_rtx (XFmode); 14918 emit_insn (gen_extend<mode>xf2 (op1, operands[1])); 14919 emit_insn (gen_frndintxf2_floor (op0, op1)); 14920 14921 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0)); 14922 } 14923 DONE; 14924}) 14925 14926(define_insn_and_split "*fist<mode>2_floor_1" 14927 [(set (match_operand:SWI248x 0 "nonimmediate_operand" "") 14928 (unspec:SWI248x [(match_operand:XF 1 "register_operand" "")] 14929 UNSPEC_FIST_FLOOR)) 14930 (clobber (reg:CC FLAGS_REG))] 14931 "TARGET_USE_FANCY_MATH_387 14932 && flag_unsafe_math_optimizations 14933 && can_create_pseudo_p ()" 14934 "#" 14935 "&& 1" 14936 [(const_int 0)] 14937{ 14938 ix86_optimize_mode_switching[I387_FLOOR] = 1; 14939 14940 operands[2] = assign_386_stack_local (HImode, SLOT_CW_STORED); 14941 operands[3] = assign_386_stack_local (HImode, SLOT_CW_FLOOR); 14942 if (memory_operand (operands[0], VOIDmode)) 14943 emit_insn (gen_fist<mode>2_floor (operands[0], operands[1], 14944 operands[2], operands[3])); 14945 else 14946 { 14947 operands[4] = assign_386_stack_local (<MODE>mode, SLOT_TEMP); 14948 emit_insn (gen_fist<mode>2_floor_with_temp (operands[0], operands[1], 14949 operands[2], operands[3], 14950 operands[4])); 14951 } 14952 DONE; 14953} 14954 [(set_attr "type" "fistp") 14955 (set_attr "i387_cw" "floor") 14956 (set_attr "mode" "<MODE>")]) 14957 14958(define_insn "fistdi2_floor" 14959 [(set (match_operand:DI 0 "memory_operand" "=m") 14960 (unspec:DI [(match_operand:XF 1 "register_operand" "f")] 14961 UNSPEC_FIST_FLOOR)) 14962 (use (match_operand:HI 2 "memory_operand" "m")) 14963 (use (match_operand:HI 3 "memory_operand" "m")) 14964 (clobber (match_scratch:XF 4 "=&1f"))] 14965 "TARGET_USE_FANCY_MATH_387 14966 && flag_unsafe_math_optimizations" 14967 "* return output_fix_trunc (insn, operands, false);" 14968 [(set_attr "type" "fistp") 14969 (set_attr "i387_cw" "floor") 14970 (set_attr "mode" "DI")]) 14971 14972(define_insn "fistdi2_floor_with_temp" 14973 [(set (match_operand:DI 0 "nonimmediate_operand" "=m,?r") 14974 (unspec:DI [(match_operand:XF 1 "register_operand" "f,f")] 14975 UNSPEC_FIST_FLOOR)) 14976 (use (match_operand:HI 2 "memory_operand" "m,m")) 14977 (use (match_operand:HI 3 "memory_operand" "m,m")) 14978 (clobber (match_operand:DI 4 "memory_operand" "=X,m")) 14979 (clobber (match_scratch:XF 5 "=&1f,&1f"))] 14980 "TARGET_USE_FANCY_MATH_387 14981 && flag_unsafe_math_optimizations" 14982 "#" 14983 [(set_attr "type" "fistp") 14984 (set_attr "i387_cw" "floor") 14985 (set_attr "mode" "DI")]) 14986 14987(define_split 14988 [(set (match_operand:DI 0 "register_operand" "") 14989 (unspec:DI [(match_operand:XF 1 "register_operand" "")] 14990 UNSPEC_FIST_FLOOR)) 14991 (use (match_operand:HI 2 "memory_operand" "")) 14992 (use (match_operand:HI 3 "memory_operand" "")) 14993 (clobber (match_operand:DI 4 "memory_operand" "")) 14994 (clobber (match_scratch 5 ""))] 14995 "reload_completed" 14996 [(parallel [(set (match_dup 4) 14997 (unspec:DI [(match_dup 1)] UNSPEC_FIST_FLOOR)) 14998 (use (match_dup 2)) 14999 (use (match_dup 3)) 15000 (clobber (match_dup 5))]) 15001 (set (match_dup 0) (match_dup 4))]) 15002 15003(define_split 15004 [(set (match_operand:DI 0 "memory_operand" "") 15005 (unspec:DI [(match_operand:XF 1 "register_operand" "")] 15006 UNSPEC_FIST_FLOOR)) 15007 (use (match_operand:HI 2 "memory_operand" "")) 15008 (use (match_operand:HI 3 "memory_operand" "")) 15009 (clobber (match_operand:DI 4 "memory_operand" "")) 15010 (clobber (match_scratch 5 ""))] 15011 "reload_completed" 15012 [(parallel [(set (match_dup 0) 15013 (unspec:DI [(match_dup 1)] UNSPEC_FIST_FLOOR)) 15014 (use (match_dup 2)) 15015 (use (match_dup 3)) 15016 (clobber (match_dup 5))])]) 15017 15018(define_insn "fist<mode>2_floor" 15019 [(set (match_operand:SWI24 0 "memory_operand" "=m") 15020 (unspec:SWI24 [(match_operand:XF 1 "register_operand" "f")] 15021 UNSPEC_FIST_FLOOR)) 15022 (use (match_operand:HI 2 "memory_operand" "m")) 15023 (use (match_operand:HI 3 "memory_operand" "m"))] 15024 "TARGET_USE_FANCY_MATH_387 15025 && flag_unsafe_math_optimizations" 15026 "* return output_fix_trunc (insn, operands, false);" 15027 [(set_attr "type" "fistp") 15028 (set_attr "i387_cw" "floor") 15029 (set_attr "mode" "<MODE>")]) 15030 15031(define_insn "fist<mode>2_floor_with_temp" 15032 [(set (match_operand:SWI24 0 "nonimmediate_operand" "=m,?r") 15033 (unspec:SWI24 [(match_operand:XF 1 "register_operand" "f,f")] 15034 UNSPEC_FIST_FLOOR)) 15035 (use (match_operand:HI 2 "memory_operand" "m,m")) 15036 (use (match_operand:HI 3 "memory_operand" "m,m")) 15037 (clobber (match_operand:SWI24 4 "memory_operand" "=X,m"))] 15038 "TARGET_USE_FANCY_MATH_387 15039 && flag_unsafe_math_optimizations" 15040 "#" 15041 [(set_attr "type" "fistp") 15042 (set_attr "i387_cw" "floor") 15043 (set_attr "mode" "<MODE>")]) 15044 15045(define_split 15046 [(set (match_operand:SWI24 0 "register_operand" "") 15047 (unspec:SWI24 [(match_operand:XF 1 "register_operand" "")] 15048 UNSPEC_FIST_FLOOR)) 15049 (use (match_operand:HI 2 "memory_operand" "")) 15050 (use (match_operand:HI 3 "memory_operand" "")) 15051 (clobber (match_operand:SWI24 4 "memory_operand" ""))] 15052 "reload_completed" 15053 [(parallel [(set (match_dup 4) 15054 (unspec:SWI24 [(match_dup 1)] UNSPEC_FIST_FLOOR)) 15055 (use (match_dup 2)) 15056 (use (match_dup 3))]) 15057 (set (match_dup 0) (match_dup 4))]) 15058 15059(define_split 15060 [(set (match_operand:SWI24 0 "memory_operand" "") 15061 (unspec:SWI24 [(match_operand:XF 1 "register_operand" "")] 15062 UNSPEC_FIST_FLOOR)) 15063 (use (match_operand:HI 2 "memory_operand" "")) 15064 (use (match_operand:HI 3 "memory_operand" "")) 15065 (clobber (match_operand:SWI24 4 "memory_operand" ""))] 15066 "reload_completed" 15067 [(parallel [(set (match_dup 0) 15068 (unspec:SWI24 [(match_dup 1)] UNSPEC_FIST_FLOOR)) 15069 (use (match_dup 2)) 15070 (use (match_dup 3))])]) 15071 15072(define_expand "lfloorxf<mode>2" 15073 [(parallel [(set (match_operand:SWI248x 0 "nonimmediate_operand" "") 15074 (unspec:SWI248x [(match_operand:XF 1 "register_operand" "")] 15075 UNSPEC_FIST_FLOOR)) 15076 (clobber (reg:CC FLAGS_REG))])] 15077 "TARGET_USE_FANCY_MATH_387 15078 && (!TARGET_SSE_MATH || TARGET_MIX_SSE_I387) 15079 && flag_unsafe_math_optimizations") 15080 15081(define_expand "lfloor<MODEF:mode><SWI48:mode>2" 15082 [(match_operand:SWI48 0 "nonimmediate_operand" "") 15083 (match_operand:MODEF 1 "register_operand" "")] 15084 "SSE_FLOAT_MODE_P (<MODEF:MODE>mode) && TARGET_SSE_MATH 15085 && !flag_trapping_math" 15086{ 15087 if (TARGET_64BIT && optimize_insn_for_size_p ()) 15088 FAIL; 15089 ix86_expand_lfloorceil (operands[0], operands[1], true); 15090 DONE; 15091}) 15092 15093;; Rounding mode control word calculation could clobber FLAGS_REG. 15094(define_insn_and_split "frndintxf2_ceil" 15095 [(set (match_operand:XF 0 "register_operand" "") 15096 (unspec:XF [(match_operand:XF 1 "register_operand" "")] 15097 UNSPEC_FRNDINT_CEIL)) 15098 (clobber (reg:CC FLAGS_REG))] 15099 "TARGET_USE_FANCY_MATH_387 15100 && flag_unsafe_math_optimizations 15101 && can_create_pseudo_p ()" 15102 "#" 15103 "&& 1" 15104 [(const_int 0)] 15105{ 15106 ix86_optimize_mode_switching[I387_CEIL] = 1; 15107 15108 operands[2] = assign_386_stack_local (HImode, SLOT_CW_STORED); 15109 operands[3] = assign_386_stack_local (HImode, SLOT_CW_CEIL); 15110 15111 emit_insn (gen_frndintxf2_ceil_i387 (operands[0], operands[1], 15112 operands[2], operands[3])); 15113 DONE; 15114} 15115 [(set_attr "type" "frndint") 15116 (set_attr "i387_cw" "ceil") 15117 (set_attr "mode" "XF")]) 15118 15119(define_insn "frndintxf2_ceil_i387" 15120 [(set (match_operand:XF 0 "register_operand" "=f") 15121 (unspec:XF [(match_operand:XF 1 "register_operand" "0")] 15122 UNSPEC_FRNDINT_CEIL)) 15123 (use (match_operand:HI 2 "memory_operand" "m")) 15124 (use (match_operand:HI 3 "memory_operand" "m"))] 15125 "TARGET_USE_FANCY_MATH_387 15126 && flag_unsafe_math_optimizations" 15127 "fldcw\t%3\n\tfrndint\n\tfldcw\t%2" 15128 [(set_attr "type" "frndint") 15129 (set_attr "i387_cw" "ceil") 15130 (set_attr "mode" "XF")]) 15131 15132(define_expand "ceilxf2" 15133 [(use (match_operand:XF 0 "register_operand" "")) 15134 (use (match_operand:XF 1 "register_operand" ""))] 15135 "TARGET_USE_FANCY_MATH_387 15136 && flag_unsafe_math_optimizations" 15137{ 15138 if (optimize_insn_for_size_p ()) 15139 FAIL; 15140 emit_insn (gen_frndintxf2_ceil (operands[0], operands[1])); 15141 DONE; 15142}) 15143 15144(define_expand "ceil<mode>2" 15145 [(use (match_operand:MODEF 0 "register_operand" "")) 15146 (use (match_operand:MODEF 1 "register_operand" ""))] 15147 "(TARGET_USE_FANCY_MATH_387 15148 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH) 15149 || TARGET_MIX_SSE_I387) 15150 && flag_unsafe_math_optimizations) 15151 || (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH 15152 && !flag_trapping_math)" 15153{ 15154 if (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH 15155 && !flag_trapping_math) 15156 { 15157 if (TARGET_ROUND) 15158 emit_insn (gen_sse4_1_round<mode>2 15159 (operands[0], operands[1], GEN_INT (ROUND_CEIL))); 15160 else if (optimize_insn_for_size_p ()) 15161 FAIL; 15162 else if (TARGET_64BIT || (<MODE>mode != DFmode)) 15163 ix86_expand_floorceil (operands[0], operands[1], false); 15164 else 15165 ix86_expand_floorceildf_32 (operands[0], operands[1], false); 15166 } 15167 else 15168 { 15169 rtx op0, op1; 15170 15171 if (optimize_insn_for_size_p ()) 15172 FAIL; 15173 15174 op0 = gen_reg_rtx (XFmode); 15175 op1 = gen_reg_rtx (XFmode); 15176 emit_insn (gen_extend<mode>xf2 (op1, operands[1])); 15177 emit_insn (gen_frndintxf2_ceil (op0, op1)); 15178 15179 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0)); 15180 } 15181 DONE; 15182}) 15183 15184(define_insn_and_split "*fist<mode>2_ceil_1" 15185 [(set (match_operand:SWI248x 0 "nonimmediate_operand" "") 15186 (unspec:SWI248x [(match_operand:XF 1 "register_operand" "")] 15187 UNSPEC_FIST_CEIL)) 15188 (clobber (reg:CC FLAGS_REG))] 15189 "TARGET_USE_FANCY_MATH_387 15190 && flag_unsafe_math_optimizations 15191 && can_create_pseudo_p ()" 15192 "#" 15193 "&& 1" 15194 [(const_int 0)] 15195{ 15196 ix86_optimize_mode_switching[I387_CEIL] = 1; 15197 15198 operands[2] = assign_386_stack_local (HImode, SLOT_CW_STORED); 15199 operands[3] = assign_386_stack_local (HImode, SLOT_CW_CEIL); 15200 if (memory_operand (operands[0], VOIDmode)) 15201 emit_insn (gen_fist<mode>2_ceil (operands[0], operands[1], 15202 operands[2], operands[3])); 15203 else 15204 { 15205 operands[4] = assign_386_stack_local (<MODE>mode, SLOT_TEMP); 15206 emit_insn (gen_fist<mode>2_ceil_with_temp (operands[0], operands[1], 15207 operands[2], operands[3], 15208 operands[4])); 15209 } 15210 DONE; 15211} 15212 [(set_attr "type" "fistp") 15213 (set_attr "i387_cw" "ceil") 15214 (set_attr "mode" "<MODE>")]) 15215 15216(define_insn "fistdi2_ceil" 15217 [(set (match_operand:DI 0 "memory_operand" "=m") 15218 (unspec:DI [(match_operand:XF 1 "register_operand" "f")] 15219 UNSPEC_FIST_CEIL)) 15220 (use (match_operand:HI 2 "memory_operand" "m")) 15221 (use (match_operand:HI 3 "memory_operand" "m")) 15222 (clobber (match_scratch:XF 4 "=&1f"))] 15223 "TARGET_USE_FANCY_MATH_387 15224 && flag_unsafe_math_optimizations" 15225 "* return output_fix_trunc (insn, operands, false);" 15226 [(set_attr "type" "fistp") 15227 (set_attr "i387_cw" "ceil") 15228 (set_attr "mode" "DI")]) 15229 15230(define_insn "fistdi2_ceil_with_temp" 15231 [(set (match_operand:DI 0 "nonimmediate_operand" "=m,?r") 15232 (unspec:DI [(match_operand:XF 1 "register_operand" "f,f")] 15233 UNSPEC_FIST_CEIL)) 15234 (use (match_operand:HI 2 "memory_operand" "m,m")) 15235 (use (match_operand:HI 3 "memory_operand" "m,m")) 15236 (clobber (match_operand:DI 4 "memory_operand" "=X,m")) 15237 (clobber (match_scratch:XF 5 "=&1f,&1f"))] 15238 "TARGET_USE_FANCY_MATH_387 15239 && flag_unsafe_math_optimizations" 15240 "#" 15241 [(set_attr "type" "fistp") 15242 (set_attr "i387_cw" "ceil") 15243 (set_attr "mode" "DI")]) 15244 15245(define_split 15246 [(set (match_operand:DI 0 "register_operand" "") 15247 (unspec:DI [(match_operand:XF 1 "register_operand" "")] 15248 UNSPEC_FIST_CEIL)) 15249 (use (match_operand:HI 2 "memory_operand" "")) 15250 (use (match_operand:HI 3 "memory_operand" "")) 15251 (clobber (match_operand:DI 4 "memory_operand" "")) 15252 (clobber (match_scratch 5 ""))] 15253 "reload_completed" 15254 [(parallel [(set (match_dup 4) 15255 (unspec:DI [(match_dup 1)] UNSPEC_FIST_CEIL)) 15256 (use (match_dup 2)) 15257 (use (match_dup 3)) 15258 (clobber (match_dup 5))]) 15259 (set (match_dup 0) (match_dup 4))]) 15260 15261(define_split 15262 [(set (match_operand:DI 0 "memory_operand" "") 15263 (unspec:DI [(match_operand:XF 1 "register_operand" "")] 15264 UNSPEC_FIST_CEIL)) 15265 (use (match_operand:HI 2 "memory_operand" "")) 15266 (use (match_operand:HI 3 "memory_operand" "")) 15267 (clobber (match_operand:DI 4 "memory_operand" "")) 15268 (clobber (match_scratch 5 ""))] 15269 "reload_completed" 15270 [(parallel [(set (match_dup 0) 15271 (unspec:DI [(match_dup 1)] UNSPEC_FIST_CEIL)) 15272 (use (match_dup 2)) 15273 (use (match_dup 3)) 15274 (clobber (match_dup 5))])]) 15275 15276(define_insn "fist<mode>2_ceil" 15277 [(set (match_operand:SWI24 0 "memory_operand" "=m") 15278 (unspec:SWI24 [(match_operand:XF 1 "register_operand" "f")] 15279 UNSPEC_FIST_CEIL)) 15280 (use (match_operand:HI 2 "memory_operand" "m")) 15281 (use (match_operand:HI 3 "memory_operand" "m"))] 15282 "TARGET_USE_FANCY_MATH_387 15283 && flag_unsafe_math_optimizations" 15284 "* return output_fix_trunc (insn, operands, false);" 15285 [(set_attr "type" "fistp") 15286 (set_attr "i387_cw" "ceil") 15287 (set_attr "mode" "<MODE>")]) 15288 15289(define_insn "fist<mode>2_ceil_with_temp" 15290 [(set (match_operand:SWI24 0 "nonimmediate_operand" "=m,?r") 15291 (unspec:SWI24 [(match_operand:XF 1 "register_operand" "f,f")] 15292 UNSPEC_FIST_CEIL)) 15293 (use (match_operand:HI 2 "memory_operand" "m,m")) 15294 (use (match_operand:HI 3 "memory_operand" "m,m")) 15295 (clobber (match_operand:SWI24 4 "memory_operand" "=X,m"))] 15296 "TARGET_USE_FANCY_MATH_387 15297 && flag_unsafe_math_optimizations" 15298 "#" 15299 [(set_attr "type" "fistp") 15300 (set_attr "i387_cw" "ceil") 15301 (set_attr "mode" "<MODE>")]) 15302 15303(define_split 15304 [(set (match_operand:SWI24 0 "register_operand" "") 15305 (unspec:SWI24 [(match_operand:XF 1 "register_operand" "")] 15306 UNSPEC_FIST_CEIL)) 15307 (use (match_operand:HI 2 "memory_operand" "")) 15308 (use (match_operand:HI 3 "memory_operand" "")) 15309 (clobber (match_operand:SWI24 4 "memory_operand" ""))] 15310 "reload_completed" 15311 [(parallel [(set (match_dup 4) 15312 (unspec:SWI24 [(match_dup 1)] UNSPEC_FIST_CEIL)) 15313 (use (match_dup 2)) 15314 (use (match_dup 3))]) 15315 (set (match_dup 0) (match_dup 4))]) 15316 15317(define_split 15318 [(set (match_operand:SWI24 0 "memory_operand" "") 15319 (unspec:SWI24 [(match_operand:XF 1 "register_operand" "")] 15320 UNSPEC_FIST_CEIL)) 15321 (use (match_operand:HI 2 "memory_operand" "")) 15322 (use (match_operand:HI 3 "memory_operand" "")) 15323 (clobber (match_operand:SWI24 4 "memory_operand" ""))] 15324 "reload_completed" 15325 [(parallel [(set (match_dup 0) 15326 (unspec:SWI24 [(match_dup 1)] UNSPEC_FIST_CEIL)) 15327 (use (match_dup 2)) 15328 (use (match_dup 3))])]) 15329 15330(define_expand "lceilxf<mode>2" 15331 [(parallel [(set (match_operand:SWI248x 0 "nonimmediate_operand" "") 15332 (unspec:SWI248x [(match_operand:XF 1 "register_operand" "")] 15333 UNSPEC_FIST_CEIL)) 15334 (clobber (reg:CC FLAGS_REG))])] 15335 "TARGET_USE_FANCY_MATH_387 15336 && (!TARGET_SSE_MATH || TARGET_MIX_SSE_I387) 15337 && flag_unsafe_math_optimizations") 15338 15339(define_expand "lceil<MODEF:mode><SWI48:mode>2" 15340 [(match_operand:SWI48 0 "nonimmediate_operand" "") 15341 (match_operand:MODEF 1 "register_operand" "")] 15342 "SSE_FLOAT_MODE_P (<MODEF:MODE>mode) && TARGET_SSE_MATH 15343 && !flag_trapping_math" 15344{ 15345 ix86_expand_lfloorceil (operands[0], operands[1], false); 15346 DONE; 15347}) 15348 15349;; Rounding mode control word calculation could clobber FLAGS_REG. 15350(define_insn_and_split "frndintxf2_trunc" 15351 [(set (match_operand:XF 0 "register_operand" "") 15352 (unspec:XF [(match_operand:XF 1 "register_operand" "")] 15353 UNSPEC_FRNDINT_TRUNC)) 15354 (clobber (reg:CC FLAGS_REG))] 15355 "TARGET_USE_FANCY_MATH_387 15356 && flag_unsafe_math_optimizations 15357 && can_create_pseudo_p ()" 15358 "#" 15359 "&& 1" 15360 [(const_int 0)] 15361{ 15362 ix86_optimize_mode_switching[I387_TRUNC] = 1; 15363 15364 operands[2] = assign_386_stack_local (HImode, SLOT_CW_STORED); 15365 operands[3] = assign_386_stack_local (HImode, SLOT_CW_TRUNC); 15366 15367 emit_insn (gen_frndintxf2_trunc_i387 (operands[0], operands[1], 15368 operands[2], operands[3])); 15369 DONE; 15370} 15371 [(set_attr "type" "frndint") 15372 (set_attr "i387_cw" "trunc") 15373 (set_attr "mode" "XF")]) 15374 15375(define_insn "frndintxf2_trunc_i387" 15376 [(set (match_operand:XF 0 "register_operand" "=f") 15377 (unspec:XF [(match_operand:XF 1 "register_operand" "0")] 15378 UNSPEC_FRNDINT_TRUNC)) 15379 (use (match_operand:HI 2 "memory_operand" "m")) 15380 (use (match_operand:HI 3 "memory_operand" "m"))] 15381 "TARGET_USE_FANCY_MATH_387 15382 && flag_unsafe_math_optimizations" 15383 "fldcw\t%3\n\tfrndint\n\tfldcw\t%2" 15384 [(set_attr "type" "frndint") 15385 (set_attr "i387_cw" "trunc") 15386 (set_attr "mode" "XF")]) 15387 15388(define_expand "btruncxf2" 15389 [(use (match_operand:XF 0 "register_operand" "")) 15390 (use (match_operand:XF 1 "register_operand" ""))] 15391 "TARGET_USE_FANCY_MATH_387 15392 && flag_unsafe_math_optimizations" 15393{ 15394 if (optimize_insn_for_size_p ()) 15395 FAIL; 15396 emit_insn (gen_frndintxf2_trunc (operands[0], operands[1])); 15397 DONE; 15398}) 15399 15400(define_expand "btrunc<mode>2" 15401 [(use (match_operand:MODEF 0 "register_operand" "")) 15402 (use (match_operand:MODEF 1 "register_operand" ""))] 15403 "(TARGET_USE_FANCY_MATH_387 15404 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH) 15405 || TARGET_MIX_SSE_I387) 15406 && flag_unsafe_math_optimizations) 15407 || (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH 15408 && !flag_trapping_math)" 15409{ 15410 if (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH 15411 && !flag_trapping_math) 15412 { 15413 if (TARGET_ROUND) 15414 emit_insn (gen_sse4_1_round<mode>2 15415 (operands[0], operands[1], GEN_INT (ROUND_TRUNC))); 15416 else if (optimize_insn_for_size_p ()) 15417 FAIL; 15418 else if (TARGET_64BIT || (<MODE>mode != DFmode)) 15419 ix86_expand_trunc (operands[0], operands[1]); 15420 else 15421 ix86_expand_truncdf_32 (operands[0], operands[1]); 15422 } 15423 else 15424 { 15425 rtx op0, op1; 15426 15427 if (optimize_insn_for_size_p ()) 15428 FAIL; 15429 15430 op0 = gen_reg_rtx (XFmode); 15431 op1 = gen_reg_rtx (XFmode); 15432 emit_insn (gen_extend<mode>xf2 (op1, operands[1])); 15433 emit_insn (gen_frndintxf2_trunc (op0, op1)); 15434 15435 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0)); 15436 } 15437 DONE; 15438}) 15439 15440;; Rounding mode control word calculation could clobber FLAGS_REG. 15441(define_insn_and_split "frndintxf2_mask_pm" 15442 [(set (match_operand:XF 0 "register_operand" "") 15443 (unspec:XF [(match_operand:XF 1 "register_operand" "")] 15444 UNSPEC_FRNDINT_MASK_PM)) 15445 (clobber (reg:CC FLAGS_REG))] 15446 "TARGET_USE_FANCY_MATH_387 15447 && flag_unsafe_math_optimizations 15448 && can_create_pseudo_p ()" 15449 "#" 15450 "&& 1" 15451 [(const_int 0)] 15452{ 15453 ix86_optimize_mode_switching[I387_MASK_PM] = 1; 15454 15455 operands[2] = assign_386_stack_local (HImode, SLOT_CW_STORED); 15456 operands[3] = assign_386_stack_local (HImode, SLOT_CW_MASK_PM); 15457 15458 emit_insn (gen_frndintxf2_mask_pm_i387 (operands[0], operands[1], 15459 operands[2], operands[3])); 15460 DONE; 15461} 15462 [(set_attr "type" "frndint") 15463 (set_attr "i387_cw" "mask_pm") 15464 (set_attr "mode" "XF")]) 15465 15466(define_insn "frndintxf2_mask_pm_i387" 15467 [(set (match_operand:XF 0 "register_operand" "=f") 15468 (unspec:XF [(match_operand:XF 1 "register_operand" "0")] 15469 UNSPEC_FRNDINT_MASK_PM)) 15470 (use (match_operand:HI 2 "memory_operand" "m")) 15471 (use (match_operand:HI 3 "memory_operand" "m"))] 15472 "TARGET_USE_FANCY_MATH_387 15473 && flag_unsafe_math_optimizations" 15474 "fldcw\t%3\n\tfrndint\n\tfclex\n\tfldcw\t%2" 15475 [(set_attr "type" "frndint") 15476 (set_attr "i387_cw" "mask_pm") 15477 (set_attr "mode" "XF")]) 15478 15479(define_expand "nearbyintxf2" 15480 [(use (match_operand:XF 0 "register_operand" "")) 15481 (use (match_operand:XF 1 "register_operand" ""))] 15482 "TARGET_USE_FANCY_MATH_387 15483 && flag_unsafe_math_optimizations" 15484{ 15485 emit_insn (gen_frndintxf2_mask_pm (operands[0], operands[1])); 15486 DONE; 15487}) 15488 15489(define_expand "nearbyint<mode>2" 15490 [(use (match_operand:MODEF 0 "register_operand" "")) 15491 (use (match_operand:MODEF 1 "register_operand" ""))] 15492 "TARGET_USE_FANCY_MATH_387 15493 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH) 15494 || TARGET_MIX_SSE_I387) 15495 && flag_unsafe_math_optimizations" 15496{ 15497 rtx op0 = gen_reg_rtx (XFmode); 15498 rtx op1 = gen_reg_rtx (XFmode); 15499 15500 emit_insn (gen_extend<mode>xf2 (op1, operands[1])); 15501 emit_insn (gen_frndintxf2_mask_pm (op0, op1)); 15502 15503 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0)); 15504 DONE; 15505}) 15506 15507(define_insn "fxam<mode>2_i387" 15508 [(set (match_operand:HI 0 "register_operand" "=a") 15509 (unspec:HI 15510 [(match_operand:X87MODEF 1 "register_operand" "f")] 15511 UNSPEC_FXAM))] 15512 "TARGET_USE_FANCY_MATH_387" 15513 "fxam\n\tfnstsw\t%0" 15514 [(set_attr "type" "multi") 15515 (set_attr "length" "4") 15516 (set_attr "unit" "i387") 15517 (set_attr "mode" "<MODE>")]) 15518 15519(define_insn_and_split "fxam<mode>2_i387_with_temp" 15520 [(set (match_operand:HI 0 "register_operand" "") 15521 (unspec:HI 15522 [(match_operand:MODEF 1 "memory_operand" "")] 15523 UNSPEC_FXAM_MEM))] 15524 "TARGET_USE_FANCY_MATH_387 15525 && can_create_pseudo_p ()" 15526 "#" 15527 "&& 1" 15528 [(set (match_dup 2)(match_dup 1)) 15529 (set (match_dup 0) 15530 (unspec:HI [(match_dup 2)] UNSPEC_FXAM))] 15531{ 15532 operands[2] = gen_reg_rtx (<MODE>mode); 15533 15534 MEM_VOLATILE_P (operands[1]) = 1; 15535} 15536 [(set_attr "type" "multi") 15537 (set_attr "unit" "i387") 15538 (set_attr "mode" "<MODE>")]) 15539 15540(define_expand "isinfxf2" 15541 [(use (match_operand:SI 0 "register_operand" "")) 15542 (use (match_operand:XF 1 "register_operand" ""))] 15543 "TARGET_USE_FANCY_MATH_387 15544 && TARGET_C99_FUNCTIONS" 15545{ 15546 rtx mask = GEN_INT (0x45); 15547 rtx val = GEN_INT (0x05); 15548 15549 rtx cond; 15550 15551 rtx scratch = gen_reg_rtx (HImode); 15552 rtx res = gen_reg_rtx (QImode); 15553 15554 emit_insn (gen_fxamxf2_i387 (scratch, operands[1])); 15555 15556 emit_insn (gen_andqi_ext_0 (scratch, scratch, mask)); 15557 emit_insn (gen_cmpqi_ext_3 (scratch, val)); 15558 cond = gen_rtx_fmt_ee (EQ, QImode, 15559 gen_rtx_REG (CCmode, FLAGS_REG), 15560 const0_rtx); 15561 emit_insn (gen_rtx_SET (VOIDmode, res, cond)); 15562 emit_insn (gen_zero_extendqisi2 (operands[0], res)); 15563 DONE; 15564}) 15565 15566(define_expand "isinf<mode>2" 15567 [(use (match_operand:SI 0 "register_operand" "")) 15568 (use (match_operand:MODEF 1 "nonimmediate_operand" ""))] 15569 "TARGET_USE_FANCY_MATH_387 15570 && TARGET_C99_FUNCTIONS 15571 && !(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)" 15572{ 15573 rtx mask = GEN_INT (0x45); 15574 rtx val = GEN_INT (0x05); 15575 15576 rtx cond; 15577 15578 rtx scratch = gen_reg_rtx (HImode); 15579 rtx res = gen_reg_rtx (QImode); 15580 15581 /* Remove excess precision by forcing value through memory. */ 15582 if (memory_operand (operands[1], VOIDmode)) 15583 emit_insn (gen_fxam<mode>2_i387_with_temp (scratch, operands[1])); 15584 else 15585 { 15586 rtx temp = assign_386_stack_local (<MODE>mode, SLOT_TEMP); 15587 15588 emit_move_insn (temp, operands[1]); 15589 emit_insn (gen_fxam<mode>2_i387_with_temp (scratch, temp)); 15590 } 15591 15592 emit_insn (gen_andqi_ext_0 (scratch, scratch, mask)); 15593 emit_insn (gen_cmpqi_ext_3 (scratch, val)); 15594 cond = gen_rtx_fmt_ee (EQ, QImode, 15595 gen_rtx_REG (CCmode, FLAGS_REG), 15596 const0_rtx); 15597 emit_insn (gen_rtx_SET (VOIDmode, res, cond)); 15598 emit_insn (gen_zero_extendqisi2 (operands[0], res)); 15599 DONE; 15600}) 15601 15602(define_expand "signbitxf2" 15603 [(use (match_operand:SI 0 "register_operand" "")) 15604 (use (match_operand:XF 1 "register_operand" ""))] 15605 "TARGET_USE_FANCY_MATH_387" 15606{ 15607 rtx scratch = gen_reg_rtx (HImode); 15608 15609 emit_insn (gen_fxamxf2_i387 (scratch, operands[1])); 15610 emit_insn (gen_andsi3 (operands[0], 15611 gen_lowpart (SImode, scratch), GEN_INT (0x200))); 15612 DONE; 15613}) 15614 15615(define_insn "movmsk_df" 15616 [(set (match_operand:SI 0 "register_operand" "=r") 15617 (unspec:SI 15618 [(match_operand:DF 1 "register_operand" "x")] 15619 UNSPEC_MOVMSK))] 15620 "SSE_FLOAT_MODE_P (DFmode) && TARGET_SSE_MATH" 15621 "%vmovmskpd\t{%1, %0|%0, %1}" 15622 [(set_attr "type" "ssemov") 15623 (set_attr "prefix" "maybe_vex") 15624 (set_attr "mode" "DF")]) 15625 15626;; Use movmskpd in SSE mode to avoid store forwarding stall 15627;; for 32bit targets and movq+shrq sequence for 64bit targets. 15628(define_expand "signbitdf2" 15629 [(use (match_operand:SI 0 "register_operand" "")) 15630 (use (match_operand:DF 1 "register_operand" ""))] 15631 "TARGET_USE_FANCY_MATH_387 15632 || (SSE_FLOAT_MODE_P (DFmode) && TARGET_SSE_MATH)" 15633{ 15634 if (SSE_FLOAT_MODE_P (DFmode) && TARGET_SSE_MATH) 15635 { 15636 emit_insn (gen_movmsk_df (operands[0], operands[1])); 15637 emit_insn (gen_andsi3 (operands[0], operands[0], const1_rtx)); 15638 } 15639 else 15640 { 15641 rtx scratch = gen_reg_rtx (HImode); 15642 15643 emit_insn (gen_fxamdf2_i387 (scratch, operands[1])); 15644 emit_insn (gen_andsi3 (operands[0], 15645 gen_lowpart (SImode, scratch), GEN_INT (0x200))); 15646 } 15647 DONE; 15648}) 15649 15650(define_expand "signbitsf2" 15651 [(use (match_operand:SI 0 "register_operand" "")) 15652 (use (match_operand:SF 1 "register_operand" ""))] 15653 "TARGET_USE_FANCY_MATH_387 15654 && !(SSE_FLOAT_MODE_P (SFmode) && TARGET_SSE_MATH)" 15655{ 15656 rtx scratch = gen_reg_rtx (HImode); 15657 15658 emit_insn (gen_fxamsf2_i387 (scratch, operands[1])); 15659 emit_insn (gen_andsi3 (operands[0], 15660 gen_lowpart (SImode, scratch), GEN_INT (0x200))); 15661 DONE; 15662}) 15663 15664;; Block operation instructions 15665 15666(define_insn "cld" 15667 [(unspec_volatile [(const_int 0)] UNSPECV_CLD)] 15668 "" 15669 "cld" 15670 [(set_attr "length" "1") 15671 (set_attr "length_immediate" "0") 15672 (set_attr "modrm" "0")]) 15673 15674(define_expand "movmem<mode>" 15675 [(use (match_operand:BLK 0 "memory_operand" "")) 15676 (use (match_operand:BLK 1 "memory_operand" "")) 15677 (use (match_operand:SWI48 2 "nonmemory_operand" "")) 15678 (use (match_operand:SWI48 3 "const_int_operand" "")) 15679 (use (match_operand:SI 4 "const_int_operand" "")) 15680 (use (match_operand:SI 5 "const_int_operand" ""))] 15681 "" 15682{ 15683 if (ix86_expand_movmem (operands[0], operands[1], operands[2], operands[3], 15684 operands[4], operands[5])) 15685 DONE; 15686 else 15687 FAIL; 15688}) 15689 15690;; Most CPUs don't like single string operations 15691;; Handle this case here to simplify previous expander. 15692 15693(define_expand "strmov" 15694 [(set (match_dup 4) (match_operand 3 "memory_operand" "")) 15695 (set (match_operand 1 "memory_operand" "") (match_dup 4)) 15696 (parallel [(set (match_operand 0 "register_operand" "") (match_dup 5)) 15697 (clobber (reg:CC FLAGS_REG))]) 15698 (parallel [(set (match_operand 2 "register_operand" "") (match_dup 6)) 15699 (clobber (reg:CC FLAGS_REG))])] 15700 "" 15701{ 15702 rtx adjust = GEN_INT (GET_MODE_SIZE (GET_MODE (operands[1]))); 15703 15704 /* If .md ever supports :P for Pmode, these can be directly 15705 in the pattern above. */ 15706 operands[5] = gen_rtx_PLUS (Pmode, operands[0], adjust); 15707 operands[6] = gen_rtx_PLUS (Pmode, operands[2], adjust); 15708 15709 /* Can't use this if the user has appropriated esi or edi. */ 15710 if ((TARGET_SINGLE_STRINGOP || optimize_insn_for_size_p ()) 15711 && !(fixed_regs[SI_REG] || fixed_regs[DI_REG])) 15712 { 15713 emit_insn (gen_strmov_singleop (operands[0], operands[1], 15714 operands[2], operands[3], 15715 operands[5], operands[6])); 15716 DONE; 15717 } 15718 15719 operands[4] = gen_reg_rtx (GET_MODE (operands[1])); 15720}) 15721 15722(define_expand "strmov_singleop" 15723 [(parallel [(set (match_operand 1 "memory_operand" "") 15724 (match_operand 3 "memory_operand" "")) 15725 (set (match_operand 0 "register_operand" "") 15726 (match_operand 4 "" "")) 15727 (set (match_operand 2 "register_operand" "") 15728 (match_operand 5 "" ""))])] 15729 "" 15730 "ix86_current_function_needs_cld = 1;") 15731 15732(define_insn "*strmovdi_rex_1" 15733 [(set (mem:DI (match_operand:DI 2 "register_operand" "0")) 15734 (mem:DI (match_operand:DI 3 "register_operand" "1"))) 15735 (set (match_operand:DI 0 "register_operand" "=D") 15736 (plus:DI (match_dup 2) 15737 (const_int 8))) 15738 (set (match_operand:DI 1 "register_operand" "=S") 15739 (plus:DI (match_dup 3) 15740 (const_int 8)))] 15741 "TARGET_64BIT 15742 && !(fixed_regs[SI_REG] || fixed_regs[DI_REG])" 15743 "movsq" 15744 [(set_attr "type" "str") 15745 (set_attr "memory" "both") 15746 (set_attr "mode" "DI")]) 15747 15748(define_insn "*strmovsi_1" 15749 [(set (mem:SI (match_operand:P 2 "register_operand" "0")) 15750 (mem:SI (match_operand:P 3 "register_operand" "1"))) 15751 (set (match_operand:P 0 "register_operand" "=D") 15752 (plus:P (match_dup 2) 15753 (const_int 4))) 15754 (set (match_operand:P 1 "register_operand" "=S") 15755 (plus:P (match_dup 3) 15756 (const_int 4)))] 15757 "!(fixed_regs[SI_REG] || fixed_regs[DI_REG])" 15758 "movs{l|d}" 15759 [(set_attr "type" "str") 15760 (set_attr "memory" "both") 15761 (set_attr "mode" "SI")]) 15762 15763(define_insn "*strmovhi_1" 15764 [(set (mem:HI (match_operand:P 2 "register_operand" "0")) 15765 (mem:HI (match_operand:P 3 "register_operand" "1"))) 15766 (set (match_operand:P 0 "register_operand" "=D") 15767 (plus:P (match_dup 2) 15768 (const_int 2))) 15769 (set (match_operand:P 1 "register_operand" "=S") 15770 (plus:P (match_dup 3) 15771 (const_int 2)))] 15772 "!(fixed_regs[SI_REG] || fixed_regs[DI_REG])" 15773 "movsw" 15774 [(set_attr "type" "str") 15775 (set_attr "memory" "both") 15776 (set_attr "mode" "HI")]) 15777 15778(define_insn "*strmovqi_1" 15779 [(set (mem:QI (match_operand:P 2 "register_operand" "0")) 15780 (mem:QI (match_operand:P 3 "register_operand" "1"))) 15781 (set (match_operand:P 0 "register_operand" "=D") 15782 (plus:P (match_dup 2) 15783 (const_int 1))) 15784 (set (match_operand:P 1 "register_operand" "=S") 15785 (plus:P (match_dup 3) 15786 (const_int 1)))] 15787 "!(fixed_regs[SI_REG] || fixed_regs[DI_REG])" 15788 "movsb" 15789 [(set_attr "type" "str") 15790 (set_attr "memory" "both") 15791 (set (attr "prefix_rex") 15792 (if_then_else 15793 (match_test "<P:MODE>mode == DImode") 15794 (const_string "0") 15795 (const_string "*"))) 15796 (set_attr "mode" "QI")]) 15797 15798(define_expand "rep_mov" 15799 [(parallel [(set (match_operand 4 "register_operand" "") (const_int 0)) 15800 (set (match_operand 0 "register_operand" "") 15801 (match_operand 5 "" "")) 15802 (set (match_operand 2 "register_operand" "") 15803 (match_operand 6 "" "")) 15804 (set (match_operand 1 "memory_operand" "") 15805 (match_operand 3 "memory_operand" "")) 15806 (use (match_dup 4))])] 15807 "" 15808 "ix86_current_function_needs_cld = 1;") 15809 15810(define_insn "*rep_movdi_rex64" 15811 [(set (match_operand:DI 2 "register_operand" "=c") (const_int 0)) 15812 (set (match_operand:DI 0 "register_operand" "=D") 15813 (plus:DI (ashift:DI (match_operand:DI 5 "register_operand" "2") 15814 (const_int 3)) 15815 (match_operand:DI 3 "register_operand" "0"))) 15816 (set (match_operand:DI 1 "register_operand" "=S") 15817 (plus:DI (ashift:DI (match_dup 5) (const_int 3)) 15818 (match_operand:DI 4 "register_operand" "1"))) 15819 (set (mem:BLK (match_dup 3)) 15820 (mem:BLK (match_dup 4))) 15821 (use (match_dup 5))] 15822 "TARGET_64BIT 15823 && !(fixed_regs[CX_REG] || fixed_regs[SI_REG] || fixed_regs[DI_REG])" 15824 "rep{%;} movsq" 15825 [(set_attr "type" "str") 15826 (set_attr "prefix_rep" "1") 15827 (set_attr "memory" "both") 15828 (set_attr "mode" "DI")]) 15829 15830(define_insn "*rep_movsi" 15831 [(set (match_operand:P 2 "register_operand" "=c") (const_int 0)) 15832 (set (match_operand:P 0 "register_operand" "=D") 15833 (plus:P (ashift:P (match_operand:P 5 "register_operand" "2") 15834 (const_int 2)) 15835 (match_operand:P 3 "register_operand" "0"))) 15836 (set (match_operand:P 1 "register_operand" "=S") 15837 (plus:P (ashift:P (match_dup 5) (const_int 2)) 15838 (match_operand:P 4 "register_operand" "1"))) 15839 (set (mem:BLK (match_dup 3)) 15840 (mem:BLK (match_dup 4))) 15841 (use (match_dup 5))] 15842 "!(fixed_regs[CX_REG] || fixed_regs[SI_REG] || fixed_regs[DI_REG])" 15843 "rep{%;} movs{l|d}" 15844 [(set_attr "type" "str") 15845 (set_attr "prefix_rep" "1") 15846 (set_attr "memory" "both") 15847 (set_attr "mode" "SI")]) 15848 15849(define_insn "*rep_movqi" 15850 [(set (match_operand:P 2 "register_operand" "=c") (const_int 0)) 15851 (set (match_operand:P 0 "register_operand" "=D") 15852 (plus:P (match_operand:P 3 "register_operand" "0") 15853 (match_operand:P 5 "register_operand" "2"))) 15854 (set (match_operand:P 1 "register_operand" "=S") 15855 (plus:P (match_operand:P 4 "register_operand" "1") (match_dup 5))) 15856 (set (mem:BLK (match_dup 3)) 15857 (mem:BLK (match_dup 4))) 15858 (use (match_dup 5))] 15859 "!(fixed_regs[CX_REG] || fixed_regs[SI_REG] || fixed_regs[DI_REG])" 15860 "rep{%;} movsb" 15861 [(set_attr "type" "str") 15862 (set_attr "prefix_rep" "1") 15863 (set_attr "memory" "both") 15864 (set_attr "mode" "QI")]) 15865 15866(define_expand "setmem<mode>" 15867 [(use (match_operand:BLK 0 "memory_operand" "")) 15868 (use (match_operand:SWI48 1 "nonmemory_operand" "")) 15869 (use (match_operand:QI 2 "nonmemory_operand" "")) 15870 (use (match_operand 3 "const_int_operand" "")) 15871 (use (match_operand:SI 4 "const_int_operand" "")) 15872 (use (match_operand:SI 5 "const_int_operand" ""))] 15873 "" 15874{ 15875 if (ix86_expand_setmem (operands[0], operands[1], 15876 operands[2], operands[3], 15877 operands[4], operands[5])) 15878 DONE; 15879 else 15880 FAIL; 15881}) 15882 15883;; Most CPUs don't like single string operations 15884;; Handle this case here to simplify previous expander. 15885 15886(define_expand "strset" 15887 [(set (match_operand 1 "memory_operand" "") 15888 (match_operand 2 "register_operand" "")) 15889 (parallel [(set (match_operand 0 "register_operand" "") 15890 (match_dup 3)) 15891 (clobber (reg:CC FLAGS_REG))])] 15892 "" 15893{ 15894 if (GET_MODE (operands[1]) != GET_MODE (operands[2])) 15895 operands[1] = adjust_address_nv (operands[1], GET_MODE (operands[2]), 0); 15896 15897 /* If .md ever supports :P for Pmode, this can be directly 15898 in the pattern above. */ 15899 operands[3] = gen_rtx_PLUS (Pmode, operands[0], 15900 GEN_INT (GET_MODE_SIZE (GET_MODE 15901 (operands[2])))); 15902 /* Can't use this if the user has appropriated eax or edi. */ 15903 if ((TARGET_SINGLE_STRINGOP || optimize_insn_for_size_p ()) 15904 && !(fixed_regs[AX_REG] || fixed_regs[DI_REG])) 15905 { 15906 emit_insn (gen_strset_singleop (operands[0], operands[1], operands[2], 15907 operands[3])); 15908 DONE; 15909 } 15910}) 15911 15912(define_expand "strset_singleop" 15913 [(parallel [(set (match_operand 1 "memory_operand" "") 15914 (match_operand 2 "register_operand" "")) 15915 (set (match_operand 0 "register_operand" "") 15916 (match_operand 3 "" "")) 15917 (unspec [(const_int 0)] UNSPEC_STOS)])] 15918 "" 15919 "ix86_current_function_needs_cld = 1;") 15920 15921(define_insn "*strsetdi_rex_1" 15922 [(set (mem:DI (match_operand:DI 1 "register_operand" "0")) 15923 (match_operand:DI 2 "register_operand" "a")) 15924 (set (match_operand:DI 0 "register_operand" "=D") 15925 (plus:DI (match_dup 1) 15926 (const_int 8))) 15927 (unspec [(const_int 0)] UNSPEC_STOS)] 15928 "TARGET_64BIT 15929 && !(fixed_regs[AX_REG] || fixed_regs[DI_REG])" 15930 "stosq" 15931 [(set_attr "type" "str") 15932 (set_attr "memory" "store") 15933 (set_attr "mode" "DI")]) 15934 15935(define_insn "*strsetsi_1" 15936 [(set (mem:SI (match_operand:P 1 "register_operand" "0")) 15937 (match_operand:SI 2 "register_operand" "a")) 15938 (set (match_operand:P 0 "register_operand" "=D") 15939 (plus:P (match_dup 1) 15940 (const_int 4))) 15941 (unspec [(const_int 0)] UNSPEC_STOS)] 15942 "!(fixed_regs[AX_REG] || fixed_regs[DI_REG])" 15943 "stos{l|d}" 15944 [(set_attr "type" "str") 15945 (set_attr "memory" "store") 15946 (set_attr "mode" "SI")]) 15947 15948(define_insn "*strsethi_1" 15949 [(set (mem:HI (match_operand:P 1 "register_operand" "0")) 15950 (match_operand:HI 2 "register_operand" "a")) 15951 (set (match_operand:P 0 "register_operand" "=D") 15952 (plus:P (match_dup 1) 15953 (const_int 2))) 15954 (unspec [(const_int 0)] UNSPEC_STOS)] 15955 "!(fixed_regs[AX_REG] || fixed_regs[DI_REG])" 15956 "stosw" 15957 [(set_attr "type" "str") 15958 (set_attr "memory" "store") 15959 (set_attr "mode" "HI")]) 15960 15961(define_insn "*strsetqi_1" 15962 [(set (mem:QI (match_operand:P 1 "register_operand" "0")) 15963 (match_operand:QI 2 "register_operand" "a")) 15964 (set (match_operand:P 0 "register_operand" "=D") 15965 (plus:P (match_dup 1) 15966 (const_int 1))) 15967 (unspec [(const_int 0)] UNSPEC_STOS)] 15968 "!(fixed_regs[AX_REG] || fixed_regs[DI_REG])" 15969 "stosb" 15970 [(set_attr "type" "str") 15971 (set_attr "memory" "store") 15972 (set (attr "prefix_rex") 15973 (if_then_else 15974 (match_test "<P:MODE>mode == DImode") 15975 (const_string "0") 15976 (const_string "*"))) 15977 (set_attr "mode" "QI")]) 15978 15979(define_expand "rep_stos" 15980 [(parallel [(set (match_operand 1 "register_operand" "") (const_int 0)) 15981 (set (match_operand 0 "register_operand" "") 15982 (match_operand 4 "" "")) 15983 (set (match_operand 2 "memory_operand" "") (const_int 0)) 15984 (use (match_operand 3 "register_operand" "")) 15985 (use (match_dup 1))])] 15986 "" 15987 "ix86_current_function_needs_cld = 1;") 15988 15989(define_insn "*rep_stosdi_rex64" 15990 [(set (match_operand:DI 1 "register_operand" "=c") (const_int 0)) 15991 (set (match_operand:DI 0 "register_operand" "=D") 15992 (plus:DI (ashift:DI (match_operand:DI 4 "register_operand" "1") 15993 (const_int 3)) 15994 (match_operand:DI 3 "register_operand" "0"))) 15995 (set (mem:BLK (match_dup 3)) 15996 (const_int 0)) 15997 (use (match_operand:DI 2 "register_operand" "a")) 15998 (use (match_dup 4))] 15999 "TARGET_64BIT 16000 && !(fixed_regs[AX_REG] || fixed_regs[CX_REG] || fixed_regs[DI_REG])" 16001 "rep{%;} stosq" 16002 [(set_attr "type" "str") 16003 (set_attr "prefix_rep" "1") 16004 (set_attr "memory" "store") 16005 (set_attr "mode" "DI")]) 16006 16007(define_insn "*rep_stossi" 16008 [(set (match_operand:P 1 "register_operand" "=c") (const_int 0)) 16009 (set (match_operand:P 0 "register_operand" "=D") 16010 (plus:P (ashift:P (match_operand:P 4 "register_operand" "1") 16011 (const_int 2)) 16012 (match_operand:P 3 "register_operand" "0"))) 16013 (set (mem:BLK (match_dup 3)) 16014 (const_int 0)) 16015 (use (match_operand:SI 2 "register_operand" "a")) 16016 (use (match_dup 4))] 16017 "!(fixed_regs[AX_REG] || fixed_regs[CX_REG] || fixed_regs[DI_REG])" 16018 "rep{%;} stos{l|d}" 16019 [(set_attr "type" "str") 16020 (set_attr "prefix_rep" "1") 16021 (set_attr "memory" "store") 16022 (set_attr "mode" "SI")]) 16023 16024(define_insn "*rep_stosqi" 16025 [(set (match_operand:P 1 "register_operand" "=c") (const_int 0)) 16026 (set (match_operand:P 0 "register_operand" "=D") 16027 (plus:P (match_operand:P 3 "register_operand" "0") 16028 (match_operand:P 4 "register_operand" "1"))) 16029 (set (mem:BLK (match_dup 3)) 16030 (const_int 0)) 16031 (use (match_operand:QI 2 "register_operand" "a")) 16032 (use (match_dup 4))] 16033 "!(fixed_regs[AX_REG] || fixed_regs[CX_REG] || fixed_regs[DI_REG])" 16034 "rep{%;} stosb" 16035 [(set_attr "type" "str") 16036 (set_attr "prefix_rep" "1") 16037 (set_attr "memory" "store") 16038 (set (attr "prefix_rex") 16039 (if_then_else 16040 (match_test "<P:MODE>mode == DImode") 16041 (const_string "0") 16042 (const_string "*"))) 16043 (set_attr "mode" "QI")]) 16044 16045(define_expand "cmpstrnsi" 16046 [(set (match_operand:SI 0 "register_operand" "") 16047 (compare:SI (match_operand:BLK 1 "general_operand" "") 16048 (match_operand:BLK 2 "general_operand" ""))) 16049 (use (match_operand 3 "general_operand" "")) 16050 (use (match_operand 4 "immediate_operand" ""))] 16051 "" 16052{ 16053 rtx addr1, addr2, out, outlow, count, countreg, align; 16054 16055 if (optimize_insn_for_size_p () && !TARGET_INLINE_ALL_STRINGOPS) 16056 FAIL; 16057 16058 /* Can't use this if the user has appropriated ecx, esi or edi. */ 16059 if (fixed_regs[CX_REG] || fixed_regs[SI_REG] || fixed_regs[DI_REG]) 16060 FAIL; 16061 16062 out = operands[0]; 16063 if (!REG_P (out)) 16064 out = gen_reg_rtx (SImode); 16065 16066 addr1 = copy_to_mode_reg (Pmode, XEXP (operands[1], 0)); 16067 addr2 = copy_to_mode_reg (Pmode, XEXP (operands[2], 0)); 16068 if (addr1 != XEXP (operands[1], 0)) 16069 operands[1] = replace_equiv_address_nv (operands[1], addr1); 16070 if (addr2 != XEXP (operands[2], 0)) 16071 operands[2] = replace_equiv_address_nv (operands[2], addr2); 16072 16073 count = operands[3]; 16074 countreg = ix86_zero_extend_to_Pmode (count); 16075 16076 /* %%% Iff we are testing strict equality, we can use known alignment 16077 to good advantage. This may be possible with combine, particularly 16078 once cc0 is dead. */ 16079 align = operands[4]; 16080 16081 if (CONST_INT_P (count)) 16082 { 16083 if (INTVAL (count) == 0) 16084 { 16085 emit_move_insn (operands[0], const0_rtx); 16086 DONE; 16087 } 16088 emit_insn (gen_cmpstrnqi_nz_1 (addr1, addr2, countreg, align, 16089 operands[1], operands[2])); 16090 } 16091 else 16092 { 16093 rtx (*gen_cmp) (rtx, rtx); 16094 16095 gen_cmp = (TARGET_64BIT 16096 ? gen_cmpdi_1 : gen_cmpsi_1); 16097 16098 emit_insn (gen_cmp (countreg, countreg)); 16099 emit_insn (gen_cmpstrnqi_1 (addr1, addr2, countreg, align, 16100 operands[1], operands[2])); 16101 } 16102 16103 outlow = gen_lowpart (QImode, out); 16104 emit_insn (gen_cmpintqi (outlow)); 16105 emit_move_insn (out, gen_rtx_SIGN_EXTEND (SImode, outlow)); 16106 16107 if (operands[0] != out) 16108 emit_move_insn (operands[0], out); 16109 16110 DONE; 16111}) 16112 16113;; Produce a tri-state integer (-1, 0, 1) from condition codes. 16114 16115(define_expand "cmpintqi" 16116 [(set (match_dup 1) 16117 (gtu:QI (reg:CC FLAGS_REG) (const_int 0))) 16118 (set (match_dup 2) 16119 (ltu:QI (reg:CC FLAGS_REG) (const_int 0))) 16120 (parallel [(set (match_operand:QI 0 "register_operand" "") 16121 (minus:QI (match_dup 1) 16122 (match_dup 2))) 16123 (clobber (reg:CC FLAGS_REG))])] 16124 "" 16125{ 16126 operands[1] = gen_reg_rtx (QImode); 16127 operands[2] = gen_reg_rtx (QImode); 16128}) 16129 16130;; memcmp recognizers. The `cmpsb' opcode does nothing if the count is 16131;; zero. Emit extra code to make sure that a zero-length compare is EQ. 16132 16133(define_expand "cmpstrnqi_nz_1" 16134 [(parallel [(set (reg:CC FLAGS_REG) 16135 (compare:CC (match_operand 4 "memory_operand" "") 16136 (match_operand 5 "memory_operand" ""))) 16137 (use (match_operand 2 "register_operand" "")) 16138 (use (match_operand:SI 3 "immediate_operand" "")) 16139 (clobber (match_operand 0 "register_operand" "")) 16140 (clobber (match_operand 1 "register_operand" "")) 16141 (clobber (match_dup 2))])] 16142 "" 16143 "ix86_current_function_needs_cld = 1;") 16144 16145(define_insn "*cmpstrnqi_nz_1" 16146 [(set (reg:CC FLAGS_REG) 16147 (compare:CC (mem:BLK (match_operand:P 4 "register_operand" "0")) 16148 (mem:BLK (match_operand:P 5 "register_operand" "1")))) 16149 (use (match_operand:P 6 "register_operand" "2")) 16150 (use (match_operand:SI 3 "immediate_operand" "i")) 16151 (clobber (match_operand:P 0 "register_operand" "=S")) 16152 (clobber (match_operand:P 1 "register_operand" "=D")) 16153 (clobber (match_operand:P 2 "register_operand" "=c"))] 16154 "!(fixed_regs[CX_REG] || fixed_regs[SI_REG] || fixed_regs[DI_REG])" 16155 "repz{%;} cmpsb" 16156 [(set_attr "type" "str") 16157 (set_attr "mode" "QI") 16158 (set (attr "prefix_rex") 16159 (if_then_else 16160 (match_test "<P:MODE>mode == DImode") 16161 (const_string "0") 16162 (const_string "*"))) 16163 (set_attr "prefix_rep" "1")]) 16164 16165;; The same, but the count is not known to not be zero. 16166 16167(define_expand "cmpstrnqi_1" 16168 [(parallel [(set (reg:CC FLAGS_REG) 16169 (if_then_else:CC (ne (match_operand 2 "register_operand" "") 16170 (const_int 0)) 16171 (compare:CC (match_operand 4 "memory_operand" "") 16172 (match_operand 5 "memory_operand" "")) 16173 (const_int 0))) 16174 (use (match_operand:SI 3 "immediate_operand" "")) 16175 (use (reg:CC FLAGS_REG)) 16176 (clobber (match_operand 0 "register_operand" "")) 16177 (clobber (match_operand 1 "register_operand" "")) 16178 (clobber (match_dup 2))])] 16179 "" 16180 "ix86_current_function_needs_cld = 1;") 16181 16182(define_insn "*cmpstrnqi_1" 16183 [(set (reg:CC FLAGS_REG) 16184 (if_then_else:CC (ne (match_operand:P 6 "register_operand" "2") 16185 (const_int 0)) 16186 (compare:CC (mem:BLK (match_operand:P 4 "register_operand" "0")) 16187 (mem:BLK (match_operand:P 5 "register_operand" "1"))) 16188 (const_int 0))) 16189 (use (match_operand:SI 3 "immediate_operand" "i")) 16190 (use (reg:CC FLAGS_REG)) 16191 (clobber (match_operand:P 0 "register_operand" "=S")) 16192 (clobber (match_operand:P 1 "register_operand" "=D")) 16193 (clobber (match_operand:P 2 "register_operand" "=c"))] 16194 "!(fixed_regs[CX_REG] || fixed_regs[SI_REG] || fixed_regs[DI_REG])" 16195 "repz{%;} cmpsb" 16196 [(set_attr "type" "str") 16197 (set_attr "mode" "QI") 16198 (set (attr "prefix_rex") 16199 (if_then_else 16200 (match_test "<P:MODE>mode == DImode") 16201 (const_string "0") 16202 (const_string "*"))) 16203 (set_attr "prefix_rep" "1")]) 16204 16205(define_expand "strlen<mode>" 16206 [(set (match_operand:P 0 "register_operand" "") 16207 (unspec:P [(match_operand:BLK 1 "general_operand" "") 16208 (match_operand:QI 2 "immediate_operand" "") 16209 (match_operand 3 "immediate_operand" "")] 16210 UNSPEC_SCAS))] 16211 "" 16212{ 16213 if (ix86_expand_strlen (operands[0], operands[1], operands[2], operands[3])) 16214 DONE; 16215 else 16216 FAIL; 16217}) 16218 16219(define_expand "strlenqi_1" 16220 [(parallel [(set (match_operand 0 "register_operand" "") 16221 (match_operand 2 "" "")) 16222 (clobber (match_operand 1 "register_operand" "")) 16223 (clobber (reg:CC FLAGS_REG))])] 16224 "" 16225 "ix86_current_function_needs_cld = 1;") 16226 16227(define_insn "*strlenqi_1" 16228 [(set (match_operand:P 0 "register_operand" "=&c") 16229 (unspec:P [(mem:BLK (match_operand:P 5 "register_operand" "1")) 16230 (match_operand:QI 2 "register_operand" "a") 16231 (match_operand:P 3 "immediate_operand" "i") 16232 (match_operand:P 4 "register_operand" "0")] UNSPEC_SCAS)) 16233 (clobber (match_operand:P 1 "register_operand" "=D")) 16234 (clobber (reg:CC FLAGS_REG))] 16235 "!(fixed_regs[AX_REG] || fixed_regs[CX_REG] || fixed_regs[DI_REG])" 16236 "repnz{%;} scasb" 16237 [(set_attr "type" "str") 16238 (set_attr "mode" "QI") 16239 (set (attr "prefix_rex") 16240 (if_then_else 16241 (match_test "<P:MODE>mode == DImode") 16242 (const_string "0") 16243 (const_string "*"))) 16244 (set_attr "prefix_rep" "1")]) 16245 16246;; Peephole optimizations to clean up after cmpstrn*. This should be 16247;; handled in combine, but it is not currently up to the task. 16248;; When used for their truth value, the cmpstrn* expanders generate 16249;; code like this: 16250;; 16251;; repz cmpsb 16252;; seta %al 16253;; setb %dl 16254;; cmpb %al, %dl 16255;; jcc label 16256;; 16257;; The intermediate three instructions are unnecessary. 16258 16259;; This one handles cmpstrn*_nz_1... 16260(define_peephole2 16261 [(parallel[ 16262 (set (reg:CC FLAGS_REG) 16263 (compare:CC (mem:BLK (match_operand 4 "register_operand" "")) 16264 (mem:BLK (match_operand 5 "register_operand" "")))) 16265 (use (match_operand 6 "register_operand" "")) 16266 (use (match_operand:SI 3 "immediate_operand" "")) 16267 (clobber (match_operand 0 "register_operand" "")) 16268 (clobber (match_operand 1 "register_operand" "")) 16269 (clobber (match_operand 2 "register_operand" ""))]) 16270 (set (match_operand:QI 7 "register_operand" "") 16271 (gtu:QI (reg:CC FLAGS_REG) (const_int 0))) 16272 (set (match_operand:QI 8 "register_operand" "") 16273 (ltu:QI (reg:CC FLAGS_REG) (const_int 0))) 16274 (set (reg FLAGS_REG) 16275 (compare (match_dup 7) (match_dup 8))) 16276 ] 16277 "peep2_reg_dead_p (4, operands[7]) && peep2_reg_dead_p (4, operands[8])" 16278 [(parallel[ 16279 (set (reg:CC FLAGS_REG) 16280 (compare:CC (mem:BLK (match_dup 4)) 16281 (mem:BLK (match_dup 5)))) 16282 (use (match_dup 6)) 16283 (use (match_dup 3)) 16284 (clobber (match_dup 0)) 16285 (clobber (match_dup 1)) 16286 (clobber (match_dup 2))])]) 16287 16288;; ...and this one handles cmpstrn*_1. 16289(define_peephole2 16290 [(parallel[ 16291 (set (reg:CC FLAGS_REG) 16292 (if_then_else:CC (ne (match_operand 6 "register_operand" "") 16293 (const_int 0)) 16294 (compare:CC (mem:BLK (match_operand 4 "register_operand" "")) 16295 (mem:BLK (match_operand 5 "register_operand" ""))) 16296 (const_int 0))) 16297 (use (match_operand:SI 3 "immediate_operand" "")) 16298 (use (reg:CC FLAGS_REG)) 16299 (clobber (match_operand 0 "register_operand" "")) 16300 (clobber (match_operand 1 "register_operand" "")) 16301 (clobber (match_operand 2 "register_operand" ""))]) 16302 (set (match_operand:QI 7 "register_operand" "") 16303 (gtu:QI (reg:CC FLAGS_REG) (const_int 0))) 16304 (set (match_operand:QI 8 "register_operand" "") 16305 (ltu:QI (reg:CC FLAGS_REG) (const_int 0))) 16306 (set (reg FLAGS_REG) 16307 (compare (match_dup 7) (match_dup 8))) 16308 ] 16309 "peep2_reg_dead_p (4, operands[7]) && peep2_reg_dead_p (4, operands[8])" 16310 [(parallel[ 16311 (set (reg:CC FLAGS_REG) 16312 (if_then_else:CC (ne (match_dup 6) 16313 (const_int 0)) 16314 (compare:CC (mem:BLK (match_dup 4)) 16315 (mem:BLK (match_dup 5))) 16316 (const_int 0))) 16317 (use (match_dup 3)) 16318 (use (reg:CC FLAGS_REG)) 16319 (clobber (match_dup 0)) 16320 (clobber (match_dup 1)) 16321 (clobber (match_dup 2))])]) 16322 16323;; Conditional move instructions. 16324 16325(define_expand "mov<mode>cc" 16326 [(set (match_operand:SWIM 0 "register_operand" "") 16327 (if_then_else:SWIM (match_operand 1 "ordered_comparison_operator" "") 16328 (match_operand:SWIM 2 "<general_operand>" "") 16329 (match_operand:SWIM 3 "<general_operand>" "")))] 16330 "" 16331 "if (ix86_expand_int_movcc (operands)) DONE; else FAIL;") 16332 16333;; Data flow gets confused by our desire for `sbbl reg,reg', and clearing 16334;; the register first winds up with `sbbl $0,reg', which is also weird. 16335;; So just document what we're doing explicitly. 16336 16337(define_expand "x86_mov<mode>cc_0_m1" 16338 [(parallel 16339 [(set (match_operand:SWI48 0 "register_operand" "") 16340 (if_then_else:SWI48 16341 (match_operator:SWI48 2 "ix86_carry_flag_operator" 16342 [(match_operand 1 "flags_reg_operand" "") 16343 (const_int 0)]) 16344 (const_int -1) 16345 (const_int 0))) 16346 (clobber (reg:CC FLAGS_REG))])]) 16347 16348(define_insn "*x86_mov<mode>cc_0_m1" 16349 [(set (match_operand:SWI48 0 "register_operand" "=r") 16350 (if_then_else:SWI48 (match_operator 1 "ix86_carry_flag_operator" 16351 [(reg FLAGS_REG) (const_int 0)]) 16352 (const_int -1) 16353 (const_int 0))) 16354 (clobber (reg:CC FLAGS_REG))] 16355 "" 16356 "sbb{<imodesuffix>}\t%0, %0" 16357 ; Since we don't have the proper number of operands for an alu insn, 16358 ; fill in all the blanks. 16359 [(set_attr "type" "alu") 16360 (set_attr "use_carry" "1") 16361 (set_attr "pent_pair" "pu") 16362 (set_attr "memory" "none") 16363 (set_attr "imm_disp" "false") 16364 (set_attr "mode" "<MODE>") 16365 (set_attr "length_immediate" "0")]) 16366 16367(define_insn "*x86_mov<mode>cc_0_m1_se" 16368 [(set (match_operand:SWI48 0 "register_operand" "=r") 16369 (sign_extract:SWI48 (match_operator 1 "ix86_carry_flag_operator" 16370 [(reg FLAGS_REG) (const_int 0)]) 16371 (const_int 1) 16372 (const_int 0))) 16373 (clobber (reg:CC FLAGS_REG))] 16374 "" 16375 "sbb{<imodesuffix>}\t%0, %0" 16376 [(set_attr "type" "alu") 16377 (set_attr "use_carry" "1") 16378 (set_attr "pent_pair" "pu") 16379 (set_attr "memory" "none") 16380 (set_attr "imm_disp" "false") 16381 (set_attr "mode" "<MODE>") 16382 (set_attr "length_immediate" "0")]) 16383 16384(define_insn "*x86_mov<mode>cc_0_m1_neg" 16385 [(set (match_operand:SWI48 0 "register_operand" "=r") 16386 (neg:SWI48 (match_operator 1 "ix86_carry_flag_operator" 16387 [(reg FLAGS_REG) (const_int 0)]))) 16388 (clobber (reg:CC FLAGS_REG))] 16389 "" 16390 "sbb{<imodesuffix>}\t%0, %0" 16391 [(set_attr "type" "alu") 16392 (set_attr "use_carry" "1") 16393 (set_attr "pent_pair" "pu") 16394 (set_attr "memory" "none") 16395 (set_attr "imm_disp" "false") 16396 (set_attr "mode" "<MODE>") 16397 (set_attr "length_immediate" "0")]) 16398 16399(define_insn "*mov<mode>cc_noc" 16400 [(set (match_operand:SWI248 0 "register_operand" "=r,r") 16401 (if_then_else:SWI248 (match_operator 1 "ix86_comparison_operator" 16402 [(reg FLAGS_REG) (const_int 0)]) 16403 (match_operand:SWI248 2 "nonimmediate_operand" "rm,0") 16404 (match_operand:SWI248 3 "nonimmediate_operand" "0,rm")))] 16405 "TARGET_CMOVE && !(MEM_P (operands[2]) && MEM_P (operands[3]))" 16406 "@ 16407 cmov%O2%C1\t{%2, %0|%0, %2} 16408 cmov%O2%c1\t{%3, %0|%0, %3}" 16409 [(set_attr "type" "icmov") 16410 (set_attr "mode" "<MODE>")]) 16411 16412(define_insn "*movqicc_noc" 16413 [(set (match_operand:QI 0 "register_operand" "=r,r") 16414 (if_then_else:QI (match_operator 1 "ix86_comparison_operator" 16415 [(reg FLAGS_REG) (const_int 0)]) 16416 (match_operand:QI 2 "register_operand" "r,0") 16417 (match_operand:QI 3 "register_operand" "0,r")))] 16418 "TARGET_CMOVE && !TARGET_PARTIAL_REG_STALL" 16419 "#" 16420 [(set_attr "type" "icmov") 16421 (set_attr "mode" "QI")]) 16422 16423(define_split 16424 [(set (match_operand 0 "register_operand") 16425 (if_then_else (match_operator 1 "ix86_comparison_operator" 16426 [(reg FLAGS_REG) (const_int 0)]) 16427 (match_operand 2 "register_operand") 16428 (match_operand 3 "register_operand")))] 16429 "TARGET_CMOVE && !TARGET_PARTIAL_REG_STALL 16430 && (GET_MODE (operands[0]) == QImode 16431 || GET_MODE (operands[0]) == HImode) 16432 && reload_completed" 16433 [(set (match_dup 0) 16434 (if_then_else:SI (match_dup 1) (match_dup 2) (match_dup 3)))] 16435{ 16436 operands[0] = gen_lowpart (SImode, operands[0]); 16437 operands[2] = gen_lowpart (SImode, operands[2]); 16438 operands[3] = gen_lowpart (SImode, operands[3]); 16439}) 16440 16441(define_expand "mov<mode>cc" 16442 [(set (match_operand:X87MODEF 0 "register_operand" "") 16443 (if_then_else:X87MODEF 16444 (match_operand 1 "ix86_fp_comparison_operator" "") 16445 (match_operand:X87MODEF 2 "register_operand" "") 16446 (match_operand:X87MODEF 3 "register_operand" "")))] 16447 "(TARGET_80387 && TARGET_CMOVE) 16448 || (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)" 16449 "if (ix86_expand_fp_movcc (operands)) DONE; else FAIL;") 16450 16451(define_insn "*movxfcc_1" 16452 [(set (match_operand:XF 0 "register_operand" "=f,f") 16453 (if_then_else:XF (match_operator 1 "fcmov_comparison_operator" 16454 [(reg FLAGS_REG) (const_int 0)]) 16455 (match_operand:XF 2 "register_operand" "f,0") 16456 (match_operand:XF 3 "register_operand" "0,f")))] 16457 "TARGET_80387 && TARGET_CMOVE" 16458 "@ 16459 fcmov%F1\t{%2, %0|%0, %2} 16460 fcmov%f1\t{%3, %0|%0, %3}" 16461 [(set_attr "type" "fcmov") 16462 (set_attr "mode" "XF")]) 16463 16464(define_insn "*movdfcc_1_rex64" 16465 [(set (match_operand:DF 0 "register_operand" "=f,f,r,r") 16466 (if_then_else:DF (match_operator 1 "fcmov_comparison_operator" 16467 [(reg FLAGS_REG) (const_int 0)]) 16468 (match_operand:DF 2 "nonimmediate_operand" "f,0,rm,0") 16469 (match_operand:DF 3 "nonimmediate_operand" "0,f,0,rm")))] 16470 "TARGET_64BIT && TARGET_80387 && TARGET_CMOVE 16471 && !(MEM_P (operands[2]) && MEM_P (operands[3]))" 16472 "@ 16473 fcmov%F1\t{%2, %0|%0, %2} 16474 fcmov%f1\t{%3, %0|%0, %3} 16475 cmov%O2%C1\t{%2, %0|%0, %2} 16476 cmov%O2%c1\t{%3, %0|%0, %3}" 16477 [(set_attr "type" "fcmov,fcmov,icmov,icmov") 16478 (set_attr "mode" "DF,DF,DI,DI")]) 16479 16480(define_insn "*movdfcc_1" 16481 [(set (match_operand:DF 0 "register_operand" "=f,f,&r,&r") 16482 (if_then_else:DF (match_operator 1 "fcmov_comparison_operator" 16483 [(reg FLAGS_REG) (const_int 0)]) 16484 (match_operand:DF 2 "nonimmediate_operand" "f,0,rm,0") 16485 (match_operand:DF 3 "nonimmediate_operand" "0,f,0,rm")))] 16486 "!TARGET_64BIT && TARGET_80387 && TARGET_CMOVE 16487 && !(MEM_P (operands[2]) && MEM_P (operands[3]))" 16488 "@ 16489 fcmov%F1\t{%2, %0|%0, %2} 16490 fcmov%f1\t{%3, %0|%0, %3} 16491 # 16492 #" 16493 [(set_attr "type" "fcmov,fcmov,multi,multi") 16494 (set_attr "mode" "DF,DF,DI,DI")]) 16495 16496(define_split 16497 [(set (match_operand:DF 0 "register_and_not_any_fp_reg_operand") 16498 (if_then_else:DF (match_operator 1 "fcmov_comparison_operator" 16499 [(reg FLAGS_REG) (const_int 0)]) 16500 (match_operand:DF 2 "nonimmediate_operand") 16501 (match_operand:DF 3 "nonimmediate_operand")))] 16502 "!TARGET_64BIT && reload_completed" 16503 [(set (match_dup 2) 16504 (if_then_else:SI (match_dup 1) (match_dup 4) (match_dup 5))) 16505 (set (match_dup 3) 16506 (if_then_else:SI (match_dup 1) (match_dup 6) (match_dup 7)))] 16507{ 16508 split_double_mode (DImode, &operands[2], 2, &operands[4], &operands[6]); 16509 split_double_mode (DImode, &operands[0], 1, &operands[2], &operands[3]); 16510}) 16511 16512(define_insn "*movsfcc_1_387" 16513 [(set (match_operand:SF 0 "register_operand" "=f,f,r,r") 16514 (if_then_else:SF (match_operator 1 "fcmov_comparison_operator" 16515 [(reg FLAGS_REG) (const_int 0)]) 16516 (match_operand:SF 2 "nonimmediate_operand" "f,0,rm,0") 16517 (match_operand:SF 3 "nonimmediate_operand" "0,f,0,rm")))] 16518 "TARGET_80387 && TARGET_CMOVE 16519 && !(MEM_P (operands[2]) && MEM_P (operands[3]))" 16520 "@ 16521 fcmov%F1\t{%2, %0|%0, %2} 16522 fcmov%f1\t{%3, %0|%0, %3} 16523 cmov%O2%C1\t{%2, %0|%0, %2} 16524 cmov%O2%c1\t{%3, %0|%0, %3}" 16525 [(set_attr "type" "fcmov,fcmov,icmov,icmov") 16526 (set_attr "mode" "SF,SF,SI,SI")]) 16527 16528;; All moves in XOP pcmov instructions are 128 bits and hence we restrict 16529;; the scalar versions to have only XMM registers as operands. 16530 16531;; XOP conditional move 16532(define_insn "*xop_pcmov_<mode>" 16533 [(set (match_operand:MODEF 0 "register_operand" "=x") 16534 (if_then_else:MODEF 16535 (match_operand:MODEF 1 "register_operand" "x") 16536 (match_operand:MODEF 2 "register_operand" "x") 16537 (match_operand:MODEF 3 "register_operand" "x")))] 16538 "TARGET_XOP" 16539 "vpcmov\t{%1, %3, %2, %0|%0, %2, %3, %1}" 16540 [(set_attr "type" "sse4arg")]) 16541 16542;; These versions of the min/max patterns are intentionally ignorant of 16543;; their behavior wrt -0.0 and NaN (via the commutative operand mark). 16544;; Since both the tree-level MAX_EXPR and the rtl-level SMAX operator 16545;; are undefined in this condition, we're certain this is correct. 16546 16547(define_insn "<code><mode>3" 16548 [(set (match_operand:MODEF 0 "register_operand" "=x,x") 16549 (smaxmin:MODEF 16550 (match_operand:MODEF 1 "nonimmediate_operand" "%0,x") 16551 (match_operand:MODEF 2 "nonimmediate_operand" "xm,xm")))] 16552 "SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH" 16553 "@ 16554 <maxmin_float><ssemodesuffix>\t{%2, %0|%0, %2} 16555 v<maxmin_float><ssemodesuffix>\t{%2, %1, %0|%0, %1, %2}" 16556 [(set_attr "isa" "noavx,avx") 16557 (set_attr "prefix" "orig,vex") 16558 (set_attr "type" "sseadd") 16559 (set_attr "mode" "<MODE>")]) 16560 16561;; These versions of the min/max patterns implement exactly the operations 16562;; min = (op1 < op2 ? op1 : op2) 16563;; max = (!(op1 < op2) ? op1 : op2) 16564;; Their operands are not commutative, and thus they may be used in the 16565;; presence of -0.0 and NaN. 16566 16567(define_insn "*ieee_smin<mode>3" 16568 [(set (match_operand:MODEF 0 "register_operand" "=x,x") 16569 (unspec:MODEF 16570 [(match_operand:MODEF 1 "register_operand" "0,x") 16571 (match_operand:MODEF 2 "nonimmediate_operand" "xm,xm")] 16572 UNSPEC_IEEE_MIN))] 16573 "SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH" 16574 "@ 16575 min<ssemodesuffix>\t{%2, %0|%0, %2} 16576 vmin<ssemodesuffix>\t{%2, %1, %0|%0, %1, %2}" 16577 [(set_attr "isa" "noavx,avx") 16578 (set_attr "prefix" "orig,vex") 16579 (set_attr "type" "sseadd") 16580 (set_attr "mode" "<MODE>")]) 16581 16582(define_insn "*ieee_smax<mode>3" 16583 [(set (match_operand:MODEF 0 "register_operand" "=x,x") 16584 (unspec:MODEF 16585 [(match_operand:MODEF 1 "register_operand" "0,x") 16586 (match_operand:MODEF 2 "nonimmediate_operand" "xm,xm")] 16587 UNSPEC_IEEE_MAX))] 16588 "SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH" 16589 "@ 16590 max<ssemodesuffix>\t{%2, %0|%0, %2} 16591 vmax<ssemodesuffix>\t{%2, %1, %0|%0, %1, %2}" 16592 [(set_attr "isa" "noavx,avx") 16593 (set_attr "prefix" "orig,vex") 16594 (set_attr "type" "sseadd") 16595 (set_attr "mode" "<MODE>")]) 16596 16597;; Make two stack loads independent: 16598;; fld aa fld aa 16599;; fld %st(0) -> fld bb 16600;; fmul bb fmul %st(1), %st 16601;; 16602;; Actually we only match the last two instructions for simplicity. 16603(define_peephole2 16604 [(set (match_operand 0 "fp_register_operand" "") 16605 (match_operand 1 "fp_register_operand" "")) 16606 (set (match_dup 0) 16607 (match_operator 2 "binary_fp_operator" 16608 [(match_dup 0) 16609 (match_operand 3 "memory_operand" "")]))] 16610 "REGNO (operands[0]) != REGNO (operands[1])" 16611 [(set (match_dup 0) (match_dup 3)) 16612 (set (match_dup 0) (match_dup 4))] 16613 16614 ;; The % modifier is not operational anymore in peephole2's, so we have to 16615 ;; swap the operands manually in the case of addition and multiplication. 16616{ 16617 rtx op0, op1; 16618 16619 if (COMMUTATIVE_ARITH_P (operands[2])) 16620 op0 = operands[0], op1 = operands[1]; 16621 else 16622 op0 = operands[1], op1 = operands[0]; 16623 16624 operands[4] = gen_rtx_fmt_ee (GET_CODE (operands[2]), 16625 GET_MODE (operands[2]), 16626 op0, op1); 16627}) 16628 16629;; Conditional addition patterns 16630(define_expand "add<mode>cc" 16631 [(match_operand:SWI 0 "register_operand" "") 16632 (match_operand 1 "ordered_comparison_operator" "") 16633 (match_operand:SWI 2 "register_operand" "") 16634 (match_operand:SWI 3 "const_int_operand" "")] 16635 "" 16636 "if (ix86_expand_int_addcc (operands)) DONE; else FAIL;") 16637 16638;; Misc patterns (?) 16639 16640;; This pattern exists to put a dependency on all ebp-based memory accesses. 16641;; Otherwise there will be nothing to keep 16642;; 16643;; [(set (reg ebp) (reg esp))] 16644;; [(set (reg esp) (plus (reg esp) (const_int -160000))) 16645;; (clobber (eflags)] 16646;; [(set (mem (plus (reg ebp) (const_int -160000))) (const_int 0))] 16647;; 16648;; in proper program order. 16649 16650(define_insn "pro_epilogue_adjust_stack_<mode>_add" 16651 [(set (match_operand:P 0 "register_operand" "=r,r") 16652 (plus:P (match_operand:P 1 "register_operand" "0,r") 16653 (match_operand:P 2 "<nonmemory_operand>" "r<i>,l<i>"))) 16654 (clobber (reg:CC FLAGS_REG)) 16655 (clobber (mem:BLK (scratch)))] 16656 "" 16657{ 16658 switch (get_attr_type (insn)) 16659 { 16660 case TYPE_IMOV: 16661 return "mov{<imodesuffix>}\t{%1, %0|%0, %1}"; 16662 16663 case TYPE_ALU: 16664 gcc_assert (rtx_equal_p (operands[0], operands[1])); 16665 if (x86_maybe_negate_const_int (&operands[2], <MODE>mode)) 16666 return "sub{<imodesuffix>}\t{%2, %0|%0, %2}"; 16667 16668 return "add{<imodesuffix>}\t{%2, %0|%0, %2}"; 16669 16670 default: 16671 operands[2] = SET_SRC (XVECEXP (PATTERN (insn), 0, 0)); 16672 return "lea{<imodesuffix>}\t{%E2, %0|%0, %E2}"; 16673 } 16674} 16675 [(set (attr "type") 16676 (cond [(and (eq_attr "alternative" "0") 16677 (not (match_test "TARGET_OPT_AGU"))) 16678 (const_string "alu") 16679 (match_operand:<MODE> 2 "const0_operand" "") 16680 (const_string "imov") 16681 ] 16682 (const_string "lea"))) 16683 (set (attr "length_immediate") 16684 (cond [(eq_attr "type" "imov") 16685 (const_string "0") 16686 (and (eq_attr "type" "alu") 16687 (match_operand 2 "const128_operand" "")) 16688 (const_string "1") 16689 ] 16690 (const_string "*"))) 16691 (set_attr "mode" "<MODE>")]) 16692 16693(define_insn "pro_epilogue_adjust_stack_<mode>_sub" 16694 [(set (match_operand:P 0 "register_operand" "=r") 16695 (minus:P (match_operand:P 1 "register_operand" "0") 16696 (match_operand:P 2 "register_operand" "r"))) 16697 (clobber (reg:CC FLAGS_REG)) 16698 (clobber (mem:BLK (scratch)))] 16699 "" 16700 "sub{<imodesuffix>}\t{%2, %0|%0, %2}" 16701 [(set_attr "type" "alu") 16702 (set_attr "mode" "<MODE>")]) 16703 16704(define_insn "allocate_stack_worker_probe_<mode>" 16705 [(set (match_operand:P 0 "register_operand" "=a") 16706 (unspec_volatile:P [(match_operand:P 1 "register_operand" "0")] 16707 UNSPECV_STACK_PROBE)) 16708 (clobber (reg:CC FLAGS_REG))] 16709 "ix86_target_stack_probe ()" 16710 "call\t___chkstk_ms" 16711 [(set_attr "type" "multi") 16712 (set_attr "length" "5")]) 16713 16714(define_expand "allocate_stack" 16715 [(match_operand 0 "register_operand" "") 16716 (match_operand 1 "general_operand" "")] 16717 "ix86_target_stack_probe ()" 16718{ 16719 rtx x; 16720 16721#ifndef CHECK_STACK_LIMIT 16722#define CHECK_STACK_LIMIT 0 16723#endif 16724 16725 if (CHECK_STACK_LIMIT && CONST_INT_P (operands[1]) 16726 && INTVAL (operands[1]) < CHECK_STACK_LIMIT) 16727 { 16728 x = expand_simple_binop (Pmode, MINUS, stack_pointer_rtx, operands[1], 16729 stack_pointer_rtx, 0, OPTAB_DIRECT); 16730 if (x != stack_pointer_rtx) 16731 emit_move_insn (stack_pointer_rtx, x); 16732 } 16733 else 16734 { 16735 x = copy_to_mode_reg (Pmode, operands[1]); 16736 if (TARGET_64BIT) 16737 emit_insn (gen_allocate_stack_worker_probe_di (x, x)); 16738 else 16739 emit_insn (gen_allocate_stack_worker_probe_si (x, x)); 16740 x = expand_simple_binop (Pmode, MINUS, stack_pointer_rtx, x, 16741 stack_pointer_rtx, 0, OPTAB_DIRECT); 16742 if (x != stack_pointer_rtx) 16743 emit_move_insn (stack_pointer_rtx, x); 16744 } 16745 16746 emit_move_insn (operands[0], virtual_stack_dynamic_rtx); 16747 DONE; 16748}) 16749 16750;; Use IOR for stack probes, this is shorter. 16751(define_expand "probe_stack" 16752 [(match_operand 0 "memory_operand" "")] 16753 "" 16754{ 16755 rtx (*gen_ior3) (rtx, rtx, rtx); 16756 16757 gen_ior3 = (GET_MODE (operands[0]) == DImode 16758 ? gen_iordi3 : gen_iorsi3); 16759 16760 emit_insn (gen_ior3 (operands[0], operands[0], const0_rtx)); 16761 DONE; 16762}) 16763 16764(define_insn "adjust_stack_and_probe<mode>" 16765 [(set (match_operand:P 0 "register_operand" "=r") 16766 (unspec_volatile:P [(match_operand:P 1 "register_operand" "0")] 16767 UNSPECV_PROBE_STACK_RANGE)) 16768 (set (reg:P SP_REG) 16769 (minus:P (reg:P SP_REG) (match_operand:P 2 "const_int_operand" "n"))) 16770 (clobber (reg:CC FLAGS_REG)) 16771 (clobber (mem:BLK (scratch)))] 16772 "" 16773 "* return output_adjust_stack_and_probe (operands[0]);" 16774 [(set_attr "type" "multi")]) 16775 16776(define_insn "probe_stack_range<mode>" 16777 [(set (match_operand:P 0 "register_operand" "=r") 16778 (unspec_volatile:P [(match_operand:P 1 "register_operand" "0") 16779 (match_operand:P 2 "const_int_operand" "n")] 16780 UNSPECV_PROBE_STACK_RANGE)) 16781 (clobber (reg:CC FLAGS_REG))] 16782 "" 16783 "* return output_probe_stack_range (operands[0], operands[2]);" 16784 [(set_attr "type" "multi")]) 16785 16786(define_expand "builtin_setjmp_receiver" 16787 [(label_ref (match_operand 0 "" ""))] 16788 "!TARGET_64BIT && flag_pic" 16789{ 16790#if TARGET_MACHO 16791 if (TARGET_MACHO) 16792 { 16793 rtx xops[3]; 16794 rtx picreg = gen_rtx_REG (Pmode, PIC_OFFSET_TABLE_REGNUM); 16795 rtx label_rtx = gen_label_rtx (); 16796 emit_insn (gen_set_got_labelled (pic_offset_table_rtx, label_rtx)); 16797 xops[0] = xops[1] = picreg; 16798 xops[2] = machopic_gen_offset (gen_rtx_LABEL_REF (SImode, label_rtx)); 16799 ix86_expand_binary_operator (MINUS, SImode, xops); 16800 } 16801 else 16802#endif 16803 emit_insn (gen_set_got (pic_offset_table_rtx)); 16804 DONE; 16805}) 16806 16807(define_insn_and_split "nonlocal_goto_receiver" 16808 [(unspec_volatile [(const_int 0)] UNSPECV_NLGR)] 16809 "TARGET_MACHO && !TARGET_64BIT && flag_pic" 16810 "#" 16811 "&& reload_completed" 16812 [(const_int 0)] 16813{ 16814 if (crtl->uses_pic_offset_table) 16815 { 16816 rtx xops[3]; 16817 rtx label_rtx = gen_label_rtx (); 16818 rtx tmp; 16819 16820 /* Get a new pic base. */ 16821 emit_insn (gen_set_got_labelled (pic_offset_table_rtx, label_rtx)); 16822 /* Correct this with the offset from the new to the old. */ 16823 xops[0] = xops[1] = pic_offset_table_rtx; 16824 label_rtx = gen_rtx_LABEL_REF (SImode, label_rtx); 16825 tmp = gen_rtx_UNSPEC (Pmode, gen_rtvec (1, label_rtx), 16826 UNSPEC_MACHOPIC_OFFSET); 16827 xops[2] = gen_rtx_CONST (Pmode, tmp); 16828 ix86_expand_binary_operator (MINUS, SImode, xops); 16829 } 16830 else 16831 /* No pic reg restore needed. */ 16832 emit_note (NOTE_INSN_DELETED); 16833 16834 DONE; 16835}) 16836 16837;; Avoid redundant prefixes by splitting HImode arithmetic to SImode. 16838 16839(define_split 16840 [(set (match_operand 0 "register_operand" "") 16841 (match_operator 3 "promotable_binary_operator" 16842 [(match_operand 1 "register_operand" "") 16843 (match_operand 2 "aligned_operand" "")])) 16844 (clobber (reg:CC FLAGS_REG))] 16845 "! TARGET_PARTIAL_REG_STALL && reload_completed 16846 && ((GET_MODE (operands[0]) == HImode 16847 && ((optimize_function_for_speed_p (cfun) && !TARGET_FAST_PREFIX) 16848 /* ??? next two lines just !satisfies_constraint_K (...) */ 16849 || !CONST_INT_P (operands[2]) 16850 || satisfies_constraint_K (operands[2]))) 16851 || (GET_MODE (operands[0]) == QImode 16852 && (TARGET_PROMOTE_QImode || optimize_function_for_size_p (cfun))))" 16853 [(parallel [(set (match_dup 0) 16854 (match_op_dup 3 [(match_dup 1) (match_dup 2)])) 16855 (clobber (reg:CC FLAGS_REG))])] 16856{ 16857 operands[0] = gen_lowpart (SImode, operands[0]); 16858 operands[1] = gen_lowpart (SImode, operands[1]); 16859 if (GET_CODE (operands[3]) != ASHIFT) 16860 operands[2] = gen_lowpart (SImode, operands[2]); 16861 PUT_MODE (operands[3], SImode); 16862}) 16863 16864; Promote the QImode tests, as i386 has encoding of the AND 16865; instruction with 32-bit sign-extended immediate and thus the 16866; instruction size is unchanged, except in the %eax case for 16867; which it is increased by one byte, hence the ! optimize_size. 16868(define_split 16869 [(set (match_operand 0 "flags_reg_operand" "") 16870 (match_operator 2 "compare_operator" 16871 [(and (match_operand 3 "aligned_operand" "") 16872 (match_operand 4 "const_int_operand" "")) 16873 (const_int 0)])) 16874 (set (match_operand 1 "register_operand" "") 16875 (and (match_dup 3) (match_dup 4)))] 16876 "! TARGET_PARTIAL_REG_STALL && reload_completed 16877 && optimize_insn_for_speed_p () 16878 && ((GET_MODE (operands[1]) == HImode && ! TARGET_FAST_PREFIX) 16879 || (GET_MODE (operands[1]) == QImode && TARGET_PROMOTE_QImode)) 16880 /* Ensure that the operand will remain sign-extended immediate. */ 16881 && ix86_match_ccmode (insn, INTVAL (operands[4]) >= 0 ? CCNOmode : CCZmode)" 16882 [(parallel [(set (match_dup 0) 16883 (match_op_dup 2 [(and:SI (match_dup 3) (match_dup 4)) 16884 (const_int 0)])) 16885 (set (match_dup 1) 16886 (and:SI (match_dup 3) (match_dup 4)))])] 16887{ 16888 operands[4] 16889 = gen_int_mode (INTVAL (operands[4]) 16890 & GET_MODE_MASK (GET_MODE (operands[1])), SImode); 16891 operands[1] = gen_lowpart (SImode, operands[1]); 16892 operands[3] = gen_lowpart (SImode, operands[3]); 16893}) 16894 16895; Don't promote the QImode tests, as i386 doesn't have encoding of 16896; the TEST instruction with 32-bit sign-extended immediate and thus 16897; the instruction size would at least double, which is not what we 16898; want even with ! optimize_size. 16899(define_split 16900 [(set (match_operand 0 "flags_reg_operand" "") 16901 (match_operator 1 "compare_operator" 16902 [(and (match_operand:HI 2 "aligned_operand" "") 16903 (match_operand:HI 3 "const_int_operand" "")) 16904 (const_int 0)]))] 16905 "! TARGET_PARTIAL_REG_STALL && reload_completed 16906 && ! TARGET_FAST_PREFIX 16907 && optimize_insn_for_speed_p () 16908 /* Ensure that the operand will remain sign-extended immediate. */ 16909 && ix86_match_ccmode (insn, INTVAL (operands[3]) >= 0 ? CCNOmode : CCZmode)" 16910 [(set (match_dup 0) 16911 (match_op_dup 1 [(and:SI (match_dup 2) (match_dup 3)) 16912 (const_int 0)]))] 16913{ 16914 operands[3] 16915 = gen_int_mode (INTVAL (operands[3]) 16916 & GET_MODE_MASK (GET_MODE (operands[2])), SImode); 16917 operands[2] = gen_lowpart (SImode, operands[2]); 16918}) 16919 16920(define_split 16921 [(set (match_operand 0 "register_operand" "") 16922 (neg (match_operand 1 "register_operand" ""))) 16923 (clobber (reg:CC FLAGS_REG))] 16924 "! TARGET_PARTIAL_REG_STALL && reload_completed 16925 && (GET_MODE (operands[0]) == HImode 16926 || (GET_MODE (operands[0]) == QImode 16927 && (TARGET_PROMOTE_QImode 16928 || optimize_insn_for_size_p ())))" 16929 [(parallel [(set (match_dup 0) 16930 (neg:SI (match_dup 1))) 16931 (clobber (reg:CC FLAGS_REG))])] 16932{ 16933 operands[0] = gen_lowpart (SImode, operands[0]); 16934 operands[1] = gen_lowpart (SImode, operands[1]); 16935}) 16936 16937(define_split 16938 [(set (match_operand 0 "register_operand" "") 16939 (not (match_operand 1 "register_operand" "")))] 16940 "! TARGET_PARTIAL_REG_STALL && reload_completed 16941 && (GET_MODE (operands[0]) == HImode 16942 || (GET_MODE (operands[0]) == QImode 16943 && (TARGET_PROMOTE_QImode 16944 || optimize_insn_for_size_p ())))" 16945 [(set (match_dup 0) 16946 (not:SI (match_dup 1)))] 16947{ 16948 operands[0] = gen_lowpart (SImode, operands[0]); 16949 operands[1] = gen_lowpart (SImode, operands[1]); 16950}) 16951 16952;; RTL Peephole optimizations, run before sched2. These primarily look to 16953;; transform a complex memory operation into two memory to register operations. 16954 16955;; Don't push memory operands 16956(define_peephole2 16957 [(set (match_operand:SWI 0 "push_operand" "") 16958 (match_operand:SWI 1 "memory_operand" "")) 16959 (match_scratch:SWI 2 "<r>")] 16960 "!(TARGET_PUSH_MEMORY || optimize_insn_for_size_p ()) 16961 && !RTX_FRAME_RELATED_P (peep2_next_insn (0))" 16962 [(set (match_dup 2) (match_dup 1)) 16963 (set (match_dup 0) (match_dup 2))]) 16964 16965;; We need to handle SFmode only, because DFmode and XFmode are split to 16966;; SImode pushes. 16967(define_peephole2 16968 [(set (match_operand:SF 0 "push_operand" "") 16969 (match_operand:SF 1 "memory_operand" "")) 16970 (match_scratch:SF 2 "r")] 16971 "!(TARGET_PUSH_MEMORY || optimize_insn_for_size_p ()) 16972 && !RTX_FRAME_RELATED_P (peep2_next_insn (0))" 16973 [(set (match_dup 2) (match_dup 1)) 16974 (set (match_dup 0) (match_dup 2))]) 16975 16976;; Don't move an immediate directly to memory when the instruction 16977;; gets too big. 16978(define_peephole2 16979 [(match_scratch:SWI124 1 "<r>") 16980 (set (match_operand:SWI124 0 "memory_operand" "") 16981 (const_int 0))] 16982 "optimize_insn_for_speed_p () 16983 && !TARGET_USE_MOV0 16984 && TARGET_SPLIT_LONG_MOVES 16985 && get_attr_length (insn) >= ix86_cur_cost ()->large_insn 16986 && peep2_regno_dead_p (0, FLAGS_REG)" 16987 [(parallel [(set (match_dup 2) (const_int 0)) 16988 (clobber (reg:CC FLAGS_REG))]) 16989 (set (match_dup 0) (match_dup 1))] 16990 "operands[2] = gen_lowpart (SImode, operands[1]);") 16991 16992(define_peephole2 16993 [(match_scratch:SWI124 2 "<r>") 16994 (set (match_operand:SWI124 0 "memory_operand" "") 16995 (match_operand:SWI124 1 "immediate_operand" ""))] 16996 "optimize_insn_for_speed_p () 16997 && TARGET_SPLIT_LONG_MOVES 16998 && get_attr_length (insn) >= ix86_cur_cost ()->large_insn" 16999 [(set (match_dup 2) (match_dup 1)) 17000 (set (match_dup 0) (match_dup 2))]) 17001 17002;; Don't compare memory with zero, load and use a test instead. 17003(define_peephole2 17004 [(set (match_operand 0 "flags_reg_operand" "") 17005 (match_operator 1 "compare_operator" 17006 [(match_operand:SI 2 "memory_operand" "") 17007 (const_int 0)])) 17008 (match_scratch:SI 3 "r")] 17009 "optimize_insn_for_speed_p () && ix86_match_ccmode (insn, CCNOmode)" 17010 [(set (match_dup 3) (match_dup 2)) 17011 (set (match_dup 0) (match_op_dup 1 [(match_dup 3) (const_int 0)]))]) 17012 17013;; NOT is not pairable on Pentium, while XOR is, but one byte longer. 17014;; Don't split NOTs with a displacement operand, because resulting XOR 17015;; will not be pairable anyway. 17016;; 17017;; On AMD K6, NOT is vector decoded with memory operand that cannot be 17018;; represented using a modRM byte. The XOR replacement is long decoded, 17019;; so this split helps here as well. 17020;; 17021;; Note: Can't do this as a regular split because we can't get proper 17022;; lifetime information then. 17023 17024(define_peephole2 17025 [(set (match_operand:SWI124 0 "nonimmediate_operand" "") 17026 (not:SWI124 (match_operand:SWI124 1 "nonimmediate_operand" "")))] 17027 "optimize_insn_for_speed_p () 17028 && ((TARGET_NOT_UNPAIRABLE 17029 && (!MEM_P (operands[0]) 17030 || !memory_displacement_operand (operands[0], <MODE>mode))) 17031 || (TARGET_NOT_VECTORMODE 17032 && long_memory_operand (operands[0], <MODE>mode))) 17033 && peep2_regno_dead_p (0, FLAGS_REG)" 17034 [(parallel [(set (match_dup 0) 17035 (xor:SWI124 (match_dup 1) (const_int -1))) 17036 (clobber (reg:CC FLAGS_REG))])]) 17037 17038;; Non pairable "test imm, reg" instructions can be translated to 17039;; "and imm, reg" if reg dies. The "and" form is also shorter (one 17040;; byte opcode instead of two, have a short form for byte operands), 17041;; so do it for other CPUs as well. Given that the value was dead, 17042;; this should not create any new dependencies. Pass on the sub-word 17043;; versions if we're concerned about partial register stalls. 17044 17045(define_peephole2 17046 [(set (match_operand 0 "flags_reg_operand" "") 17047 (match_operator 1 "compare_operator" 17048 [(and:SI (match_operand:SI 2 "register_operand" "") 17049 (match_operand:SI 3 "immediate_operand" "")) 17050 (const_int 0)]))] 17051 "ix86_match_ccmode (insn, CCNOmode) 17052 && (true_regnum (operands[2]) != AX_REG 17053 || satisfies_constraint_K (operands[3])) 17054 && peep2_reg_dead_p (1, operands[2])" 17055 [(parallel 17056 [(set (match_dup 0) 17057 (match_op_dup 1 [(and:SI (match_dup 2) (match_dup 3)) 17058 (const_int 0)])) 17059 (set (match_dup 2) 17060 (and:SI (match_dup 2) (match_dup 3)))])]) 17061 17062;; We don't need to handle HImode case, because it will be promoted to SImode 17063;; on ! TARGET_PARTIAL_REG_STALL 17064 17065(define_peephole2 17066 [(set (match_operand 0 "flags_reg_operand" "") 17067 (match_operator 1 "compare_operator" 17068 [(and:QI (match_operand:QI 2 "register_operand" "") 17069 (match_operand:QI 3 "immediate_operand" "")) 17070 (const_int 0)]))] 17071 "! TARGET_PARTIAL_REG_STALL 17072 && ix86_match_ccmode (insn, CCNOmode) 17073 && true_regnum (operands[2]) != AX_REG 17074 && peep2_reg_dead_p (1, operands[2])" 17075 [(parallel 17076 [(set (match_dup 0) 17077 (match_op_dup 1 [(and:QI (match_dup 2) (match_dup 3)) 17078 (const_int 0)])) 17079 (set (match_dup 2) 17080 (and:QI (match_dup 2) (match_dup 3)))])]) 17081 17082(define_peephole2 17083 [(set (match_operand 0 "flags_reg_operand" "") 17084 (match_operator 1 "compare_operator" 17085 [(and:SI 17086 (zero_extract:SI 17087 (match_operand 2 "ext_register_operand" "") 17088 (const_int 8) 17089 (const_int 8)) 17090 (match_operand 3 "const_int_operand" "")) 17091 (const_int 0)]))] 17092 "! TARGET_PARTIAL_REG_STALL 17093 && ix86_match_ccmode (insn, CCNOmode) 17094 && true_regnum (operands[2]) != AX_REG 17095 && peep2_reg_dead_p (1, operands[2])" 17096 [(parallel [(set (match_dup 0) 17097 (match_op_dup 1 17098 [(and:SI 17099 (zero_extract:SI 17100 (match_dup 2) 17101 (const_int 8) 17102 (const_int 8)) 17103 (match_dup 3)) 17104 (const_int 0)])) 17105 (set (zero_extract:SI (match_dup 2) 17106 (const_int 8) 17107 (const_int 8)) 17108 (and:SI 17109 (zero_extract:SI 17110 (match_dup 2) 17111 (const_int 8) 17112 (const_int 8)) 17113 (match_dup 3)))])]) 17114 17115;; Don't do logical operations with memory inputs. 17116(define_peephole2 17117 [(match_scratch:SI 2 "r") 17118 (parallel [(set (match_operand:SI 0 "register_operand" "") 17119 (match_operator:SI 3 "arith_or_logical_operator" 17120 [(match_dup 0) 17121 (match_operand:SI 1 "memory_operand" "")])) 17122 (clobber (reg:CC FLAGS_REG))])] 17123 "!(TARGET_READ_MODIFY || optimize_insn_for_size_p ())" 17124 [(set (match_dup 2) (match_dup 1)) 17125 (parallel [(set (match_dup 0) 17126 (match_op_dup 3 [(match_dup 0) (match_dup 2)])) 17127 (clobber (reg:CC FLAGS_REG))])]) 17128 17129(define_peephole2 17130 [(match_scratch:SI 2 "r") 17131 (parallel [(set (match_operand:SI 0 "register_operand" "") 17132 (match_operator:SI 3 "arith_or_logical_operator" 17133 [(match_operand:SI 1 "memory_operand" "") 17134 (match_dup 0)])) 17135 (clobber (reg:CC FLAGS_REG))])] 17136 "!(TARGET_READ_MODIFY || optimize_insn_for_size_p ())" 17137 [(set (match_dup 2) (match_dup 1)) 17138 (parallel [(set (match_dup 0) 17139 (match_op_dup 3 [(match_dup 2) (match_dup 0)])) 17140 (clobber (reg:CC FLAGS_REG))])]) 17141 17142;; Prefer Load+RegOp to Mov+MemOp. Watch out for cases when the memory address 17143;; refers to the destination of the load! 17144 17145(define_peephole2 17146 [(set (match_operand:SI 0 "register_operand" "") 17147 (match_operand:SI 1 "register_operand" "")) 17148 (parallel [(set (match_dup 0) 17149 (match_operator:SI 3 "commutative_operator" 17150 [(match_dup 0) 17151 (match_operand:SI 2 "memory_operand" "")])) 17152 (clobber (reg:CC FLAGS_REG))])] 17153 "REGNO (operands[0]) != REGNO (operands[1]) 17154 && GENERAL_REGNO_P (REGNO (operands[0])) 17155 && GENERAL_REGNO_P (REGNO (operands[1]))" 17156 [(set (match_dup 0) (match_dup 4)) 17157 (parallel [(set (match_dup 0) 17158 (match_op_dup 3 [(match_dup 0) (match_dup 1)])) 17159 (clobber (reg:CC FLAGS_REG))])] 17160 "operands[4] = replace_rtx (operands[2], operands[0], operands[1]);") 17161 17162(define_peephole2 17163 [(set (match_operand 0 "register_operand" "") 17164 (match_operand 1 "register_operand" "")) 17165 (set (match_dup 0) 17166 (match_operator 3 "commutative_operator" 17167 [(match_dup 0) 17168 (match_operand 2 "memory_operand" "")]))] 17169 "REGNO (operands[0]) != REGNO (operands[1]) 17170 && ((MMX_REG_P (operands[0]) && MMX_REG_P (operands[1])) 17171 || (SSE_REG_P (operands[0]) && SSE_REG_P (operands[1])))" 17172 [(set (match_dup 0) (match_dup 2)) 17173 (set (match_dup 0) 17174 (match_op_dup 3 [(match_dup 0) (match_dup 1)]))]) 17175 17176; Don't do logical operations with memory outputs 17177; 17178; These two don't make sense for PPro/PII -- we're expanding a 4-uop 17179; instruction into two 1-uop insns plus a 2-uop insn. That last has 17180; the same decoder scheduling characteristics as the original. 17181 17182(define_peephole2 17183 [(match_scratch:SI 2 "r") 17184 (parallel [(set (match_operand:SI 0 "memory_operand" "") 17185 (match_operator:SI 3 "arith_or_logical_operator" 17186 [(match_dup 0) 17187 (match_operand:SI 1 "nonmemory_operand" "")])) 17188 (clobber (reg:CC FLAGS_REG))])] 17189 "!(TARGET_READ_MODIFY_WRITE || optimize_insn_for_size_p ()) 17190 /* Do not split stack checking probes. */ 17191 && GET_CODE (operands[3]) != IOR && operands[1] != const0_rtx" 17192 [(set (match_dup 2) (match_dup 0)) 17193 (parallel [(set (match_dup 2) 17194 (match_op_dup 3 [(match_dup 2) (match_dup 1)])) 17195 (clobber (reg:CC FLAGS_REG))]) 17196 (set (match_dup 0) (match_dup 2))]) 17197 17198(define_peephole2 17199 [(match_scratch:SI 2 "r") 17200 (parallel [(set (match_operand:SI 0 "memory_operand" "") 17201 (match_operator:SI 3 "arith_or_logical_operator" 17202 [(match_operand:SI 1 "nonmemory_operand" "") 17203 (match_dup 0)])) 17204 (clobber (reg:CC FLAGS_REG))])] 17205 "!(TARGET_READ_MODIFY_WRITE || optimize_insn_for_size_p ()) 17206 /* Do not split stack checking probes. */ 17207 && GET_CODE (operands[3]) != IOR && operands[1] != const0_rtx" 17208 [(set (match_dup 2) (match_dup 0)) 17209 (parallel [(set (match_dup 2) 17210 (match_op_dup 3 [(match_dup 1) (match_dup 2)])) 17211 (clobber (reg:CC FLAGS_REG))]) 17212 (set (match_dup 0) (match_dup 2))]) 17213 17214;; Attempt to use arith or logical operations with memory outputs with 17215;; setting of flags. 17216(define_peephole2 17217 [(set (match_operand:SWI 0 "register_operand" "") 17218 (match_operand:SWI 1 "memory_operand" "")) 17219 (parallel [(set (match_dup 0) 17220 (match_operator:SWI 3 "plusminuslogic_operator" 17221 [(match_dup 0) 17222 (match_operand:SWI 2 "<nonmemory_operand>" "")])) 17223 (clobber (reg:CC FLAGS_REG))]) 17224 (set (match_dup 1) (match_dup 0)) 17225 (set (reg FLAGS_REG) (compare (match_dup 0) (const_int 0)))] 17226 "(TARGET_READ_MODIFY_WRITE || optimize_insn_for_size_p ()) 17227 && peep2_reg_dead_p (4, operands[0]) 17228 && !reg_overlap_mentioned_p (operands[0], operands[1]) 17229 && !reg_overlap_mentioned_p (operands[0], operands[2]) 17230 && (<MODE>mode != QImode 17231 || immediate_operand (operands[2], QImode) 17232 || q_regs_operand (operands[2], QImode)) 17233 && ix86_match_ccmode (peep2_next_insn (3), 17234 (GET_CODE (operands[3]) == PLUS 17235 || GET_CODE (operands[3]) == MINUS) 17236 ? CCGOCmode : CCNOmode)" 17237 [(parallel [(set (match_dup 4) (match_dup 5)) 17238 (set (match_dup 1) (match_op_dup 3 [(match_dup 1) 17239 (match_dup 2)]))])] 17240{ 17241 operands[4] = SET_DEST (PATTERN (peep2_next_insn (3))); 17242 operands[5] = gen_rtx_fmt_ee (GET_CODE (operands[3]), <MODE>mode, 17243 copy_rtx (operands[1]), 17244 copy_rtx (operands[2])); 17245 operands[5] = gen_rtx_COMPARE (GET_MODE (operands[4]), 17246 operands[5], const0_rtx); 17247}) 17248 17249(define_peephole2 17250 [(parallel [(set (match_operand:SWI 0 "register_operand" "") 17251 (match_operator:SWI 2 "plusminuslogic_operator" 17252 [(match_dup 0) 17253 (match_operand:SWI 1 "memory_operand" "")])) 17254 (clobber (reg:CC FLAGS_REG))]) 17255 (set (match_dup 1) (match_dup 0)) 17256 (set (reg FLAGS_REG) (compare (match_dup 0) (const_int 0)))] 17257 "(TARGET_READ_MODIFY_WRITE || optimize_insn_for_size_p ()) 17258 && GET_CODE (operands[2]) != MINUS 17259 && peep2_reg_dead_p (3, operands[0]) 17260 && !reg_overlap_mentioned_p (operands[0], operands[1]) 17261 && ix86_match_ccmode (peep2_next_insn (2), 17262 GET_CODE (operands[2]) == PLUS 17263 ? CCGOCmode : CCNOmode)" 17264 [(parallel [(set (match_dup 3) (match_dup 4)) 17265 (set (match_dup 1) (match_op_dup 2 [(match_dup 1) 17266 (match_dup 0)]))])] 17267{ 17268 operands[3] = SET_DEST (PATTERN (peep2_next_insn (2))); 17269 operands[4] = gen_rtx_fmt_ee (GET_CODE (operands[2]), <MODE>mode, 17270 copy_rtx (operands[1]), 17271 copy_rtx (operands[0])); 17272 operands[4] = gen_rtx_COMPARE (GET_MODE (operands[3]), 17273 operands[4], const0_rtx); 17274}) 17275 17276(define_peephole2 17277 [(set (match_operand:SWI12 0 "register_operand" "") 17278 (match_operand:SWI12 1 "memory_operand" "")) 17279 (parallel [(set (match_operand:SI 4 "register_operand" "") 17280 (match_operator:SI 3 "plusminuslogic_operator" 17281 [(match_dup 4) 17282 (match_operand:SI 2 "nonmemory_operand" "")])) 17283 (clobber (reg:CC FLAGS_REG))]) 17284 (set (match_dup 1) (match_dup 0)) 17285 (set (reg FLAGS_REG) (compare (match_dup 0) (const_int 0)))] 17286 "(TARGET_READ_MODIFY_WRITE || optimize_insn_for_size_p ()) 17287 && REG_P (operands[0]) && REG_P (operands[4]) 17288 && REGNO (operands[0]) == REGNO (operands[4]) 17289 && peep2_reg_dead_p (4, operands[0]) 17290 && (<MODE>mode != QImode 17291 || immediate_operand (operands[2], SImode) 17292 || q_regs_operand (operands[2], SImode)) 17293 && !reg_overlap_mentioned_p (operands[0], operands[1]) 17294 && !reg_overlap_mentioned_p (operands[0], operands[2]) 17295 && ix86_match_ccmode (peep2_next_insn (3), 17296 (GET_CODE (operands[3]) == PLUS 17297 || GET_CODE (operands[3]) == MINUS) 17298 ? CCGOCmode : CCNOmode)" 17299 [(parallel [(set (match_dup 4) (match_dup 5)) 17300 (set (match_dup 1) (match_dup 6))])] 17301{ 17302 operands[2] = gen_lowpart (<MODE>mode, operands[2]); 17303 operands[4] = SET_DEST (PATTERN (peep2_next_insn (3))); 17304 operands[5] = gen_rtx_fmt_ee (GET_CODE (operands[3]), <MODE>mode, 17305 copy_rtx (operands[1]), operands[2]); 17306 operands[5] = gen_rtx_COMPARE (GET_MODE (operands[4]), 17307 operands[5], const0_rtx); 17308 operands[6] = gen_rtx_fmt_ee (GET_CODE (operands[3]), <MODE>mode, 17309 copy_rtx (operands[1]), 17310 copy_rtx (operands[2])); 17311}) 17312 17313;; Attempt to always use XOR for zeroing registers. 17314(define_peephole2 17315 [(set (match_operand 0 "register_operand" "") 17316 (match_operand 1 "const0_operand" ""))] 17317 "GET_MODE_SIZE (GET_MODE (operands[0])) <= UNITS_PER_WORD 17318 && (! TARGET_USE_MOV0 || optimize_insn_for_size_p ()) 17319 && GENERAL_REG_P (operands[0]) 17320 && peep2_regno_dead_p (0, FLAGS_REG)" 17321 [(parallel [(set (match_dup 0) (const_int 0)) 17322 (clobber (reg:CC FLAGS_REG))])] 17323 "operands[0] = gen_lowpart (word_mode, operands[0]);") 17324 17325(define_peephole2 17326 [(set (strict_low_part (match_operand 0 "register_operand" "")) 17327 (const_int 0))] 17328 "(GET_MODE (operands[0]) == QImode 17329 || GET_MODE (operands[0]) == HImode) 17330 && (! TARGET_USE_MOV0 || optimize_insn_for_size_p ()) 17331 && peep2_regno_dead_p (0, FLAGS_REG)" 17332 [(parallel [(set (strict_low_part (match_dup 0)) (const_int 0)) 17333 (clobber (reg:CC FLAGS_REG))])]) 17334 17335;; For HI, SI and DI modes, or $-1,reg is smaller than mov $-1,reg. 17336(define_peephole2 17337 [(set (match_operand:SWI248 0 "register_operand" "") 17338 (const_int -1))] 17339 "(optimize_insn_for_size_p () || TARGET_MOVE_M1_VIA_OR) 17340 && peep2_regno_dead_p (0, FLAGS_REG)" 17341 [(parallel [(set (match_dup 0) (const_int -1)) 17342 (clobber (reg:CC FLAGS_REG))])] 17343{ 17344 if (GET_MODE_SIZE (<MODE>mode) < GET_MODE_SIZE (SImode)) 17345 operands[0] = gen_lowpart (SImode, operands[0]); 17346}) 17347 17348;; Attempt to convert simple lea to add/shift. 17349;; These can be created by move expanders. 17350 17351(define_peephole2 17352 [(set (match_operand:SWI48 0 "register_operand" "") 17353 (plus:SWI48 (match_dup 0) 17354 (match_operand:SWI48 1 "<nonmemory_operand>" "")))] 17355 "peep2_regno_dead_p (0, FLAGS_REG)" 17356 [(parallel [(set (match_dup 0) (plus:SWI48 (match_dup 0) (match_dup 1))) 17357 (clobber (reg:CC FLAGS_REG))])]) 17358 17359(define_peephole2 17360 [(set (match_operand:SI 0 "register_operand" "") 17361 (subreg:SI (plus:DI (match_operand:DI 1 "register_operand" "") 17362 (match_operand:DI 2 "nonmemory_operand" "")) 0))] 17363 "TARGET_64BIT 17364 && peep2_regno_dead_p (0, FLAGS_REG) 17365 && REGNO (operands[0]) == REGNO (operands[1])" 17366 [(parallel [(set (match_dup 0) (plus:SI (match_dup 0) (match_dup 2))) 17367 (clobber (reg:CC FLAGS_REG))])] 17368 "operands[2] = gen_lowpart (SImode, operands[2]);") 17369 17370(define_peephole2 17371 [(set (match_operand:SWI48 0 "register_operand" "") 17372 (mult:SWI48 (match_dup 0) 17373 (match_operand:SWI48 1 "const_int_operand" "")))] 17374 "exact_log2 (INTVAL (operands[1])) >= 0 17375 && peep2_regno_dead_p (0, FLAGS_REG)" 17376 [(parallel [(set (match_dup 0) (ashift:SWI48 (match_dup 0) (match_dup 2))) 17377 (clobber (reg:CC FLAGS_REG))])] 17378 "operands[2] = GEN_INT (exact_log2 (INTVAL (operands[1])));") 17379 17380(define_peephole2 17381 [(set (match_operand:SI 0 "register_operand" "") 17382 (subreg:SI (mult:DI (match_operand:DI 1 "register_operand" "") 17383 (match_operand:DI 2 "const_int_operand" "")) 0))] 17384 "TARGET_64BIT 17385 && exact_log2 (INTVAL (operands[2])) >= 0 17386 && REGNO (operands[0]) == REGNO (operands[1]) 17387 && peep2_regno_dead_p (0, FLAGS_REG)" 17388 [(parallel [(set (match_dup 0) (ashift:SI (match_dup 0) (match_dup 2))) 17389 (clobber (reg:CC FLAGS_REG))])] 17390 "operands[2] = GEN_INT (exact_log2 (INTVAL (operands[2])));") 17391 17392;; The ESP adjustments can be done by the push and pop instructions. Resulting 17393;; code is shorter, since push is only 1 byte, while add imm, %esp is 3 bytes. 17394;; On many CPUs it is also faster, since special hardware to avoid esp 17395;; dependencies is present. 17396 17397;; While some of these conversions may be done using splitters, we use 17398;; peepholes in order to allow combine_stack_adjustments pass to see 17399;; nonobfuscated RTL. 17400 17401;; Convert prologue esp subtractions to push. 17402;; We need register to push. In order to keep verify_flow_info happy we have 17403;; two choices 17404;; - use scratch and clobber it in order to avoid dependencies 17405;; - use already live register 17406;; We can't use the second way right now, since there is no reliable way how to 17407;; verify that given register is live. First choice will also most likely in 17408;; fewer dependencies. On the place of esp adjustments it is very likely that 17409;; call clobbered registers are dead. We may want to use base pointer as an 17410;; alternative when no register is available later. 17411 17412(define_peephole2 17413 [(match_scratch:P 1 "r") 17414 (parallel [(set (reg:P SP_REG) 17415 (plus:P (reg:P SP_REG) 17416 (match_operand:P 0 "const_int_operand" ""))) 17417 (clobber (reg:CC FLAGS_REG)) 17418 (clobber (mem:BLK (scratch)))])] 17419 "(TARGET_SINGLE_PUSH || optimize_insn_for_size_p ()) 17420 && INTVAL (operands[0]) == -GET_MODE_SIZE (Pmode)" 17421 [(clobber (match_dup 1)) 17422 (parallel [(set (mem:P (pre_dec:P (reg:P SP_REG))) (match_dup 1)) 17423 (clobber (mem:BLK (scratch)))])]) 17424 17425(define_peephole2 17426 [(match_scratch:P 1 "r") 17427 (parallel [(set (reg:P SP_REG) 17428 (plus:P (reg:P SP_REG) 17429 (match_operand:P 0 "const_int_operand" ""))) 17430 (clobber (reg:CC FLAGS_REG)) 17431 (clobber (mem:BLK (scratch)))])] 17432 "(TARGET_DOUBLE_PUSH || optimize_insn_for_size_p ()) 17433 && INTVAL (operands[0]) == -2*GET_MODE_SIZE (Pmode)" 17434 [(clobber (match_dup 1)) 17435 (set (mem:P (pre_dec:P (reg:P SP_REG))) (match_dup 1)) 17436 (parallel [(set (mem:P (pre_dec:P (reg:P SP_REG))) (match_dup 1)) 17437 (clobber (mem:BLK (scratch)))])]) 17438 17439;; Convert esp subtractions to push. 17440(define_peephole2 17441 [(match_scratch:P 1 "r") 17442 (parallel [(set (reg:P SP_REG) 17443 (plus:P (reg:P SP_REG) 17444 (match_operand:P 0 "const_int_operand" ""))) 17445 (clobber (reg:CC FLAGS_REG))])] 17446 "(TARGET_SINGLE_PUSH || optimize_insn_for_size_p ()) 17447 && INTVAL (operands[0]) == -GET_MODE_SIZE (Pmode)" 17448 [(clobber (match_dup 1)) 17449 (set (mem:P (pre_dec:P (reg:P SP_REG))) (match_dup 1))]) 17450 17451(define_peephole2 17452 [(match_scratch:P 1 "r") 17453 (parallel [(set (reg:P SP_REG) 17454 (plus:P (reg:P SP_REG) 17455 (match_operand:P 0 "const_int_operand" ""))) 17456 (clobber (reg:CC FLAGS_REG))])] 17457 "(TARGET_DOUBLE_PUSH || optimize_insn_for_size_p ()) 17458 && INTVAL (operands[0]) == -2*GET_MODE_SIZE (Pmode)" 17459 [(clobber (match_dup 1)) 17460 (set (mem:P (pre_dec:P (reg:P SP_REG))) (match_dup 1)) 17461 (set (mem:P (pre_dec:P (reg:P SP_REG))) (match_dup 1))]) 17462 17463;; Convert epilogue deallocator to pop. 17464(define_peephole2 17465 [(match_scratch:P 1 "r") 17466 (parallel [(set (reg:P SP_REG) 17467 (plus:P (reg:P SP_REG) 17468 (match_operand:P 0 "const_int_operand" ""))) 17469 (clobber (reg:CC FLAGS_REG)) 17470 (clobber (mem:BLK (scratch)))])] 17471 "(TARGET_SINGLE_POP || optimize_insn_for_size_p ()) 17472 && INTVAL (operands[0]) == GET_MODE_SIZE (Pmode)" 17473 [(parallel [(set (match_dup 1) (mem:P (post_inc:P (reg:P SP_REG)))) 17474 (clobber (mem:BLK (scratch)))])]) 17475 17476;; Two pops case is tricky, since pop causes dependency 17477;; on destination register. We use two registers if available. 17478(define_peephole2 17479 [(match_scratch:P 1 "r") 17480 (match_scratch:P 2 "r") 17481 (parallel [(set (reg:P SP_REG) 17482 (plus:P (reg:P SP_REG) 17483 (match_operand:P 0 "const_int_operand" ""))) 17484 (clobber (reg:CC FLAGS_REG)) 17485 (clobber (mem:BLK (scratch)))])] 17486 "(TARGET_DOUBLE_POP || optimize_insn_for_size_p ()) 17487 && INTVAL (operands[0]) == 2*GET_MODE_SIZE (Pmode)" 17488 [(parallel [(set (match_dup 1) (mem:P (post_inc:P (reg:P SP_REG)))) 17489 (clobber (mem:BLK (scratch)))]) 17490 (set (match_dup 2) (mem:P (post_inc:P (reg:P SP_REG))))]) 17491 17492(define_peephole2 17493 [(match_scratch:P 1 "r") 17494 (parallel [(set (reg:P SP_REG) 17495 (plus:P (reg:P SP_REG) 17496 (match_operand:P 0 "const_int_operand" ""))) 17497 (clobber (reg:CC FLAGS_REG)) 17498 (clobber (mem:BLK (scratch)))])] 17499 "optimize_insn_for_size_p () 17500 && INTVAL (operands[0]) == 2*GET_MODE_SIZE (Pmode)" 17501 [(parallel [(set (match_dup 1) (mem:P (post_inc:P (reg:P SP_REG)))) 17502 (clobber (mem:BLK (scratch)))]) 17503 (set (match_dup 1) (mem:P (post_inc:P (reg:P SP_REG))))]) 17504 17505;; Convert esp additions to pop. 17506(define_peephole2 17507 [(match_scratch:P 1 "r") 17508 (parallel [(set (reg:P SP_REG) 17509 (plus:P (reg:P SP_REG) 17510 (match_operand:P 0 "const_int_operand" ""))) 17511 (clobber (reg:CC FLAGS_REG))])] 17512 "INTVAL (operands[0]) == GET_MODE_SIZE (Pmode)" 17513 [(set (match_dup 1) (mem:P (post_inc:P (reg:P SP_REG))))]) 17514 17515;; Two pops case is tricky, since pop causes dependency 17516;; on destination register. We use two registers if available. 17517(define_peephole2 17518 [(match_scratch:P 1 "r") 17519 (match_scratch:P 2 "r") 17520 (parallel [(set (reg:P SP_REG) 17521 (plus:P (reg:P SP_REG) 17522 (match_operand:P 0 "const_int_operand" ""))) 17523 (clobber (reg:CC FLAGS_REG))])] 17524 "INTVAL (operands[0]) == 2*GET_MODE_SIZE (Pmode)" 17525 [(set (match_dup 1) (mem:P (post_inc:P (reg:P SP_REG)))) 17526 (set (match_dup 2) (mem:P (post_inc:P (reg:P SP_REG))))]) 17527 17528(define_peephole2 17529 [(match_scratch:P 1 "r") 17530 (parallel [(set (reg:P SP_REG) 17531 (plus:P (reg:P SP_REG) 17532 (match_operand:P 0 "const_int_operand" ""))) 17533 (clobber (reg:CC FLAGS_REG))])] 17534 "optimize_insn_for_size_p () 17535 && INTVAL (operands[0]) == 2*GET_MODE_SIZE (Pmode)" 17536 [(set (match_dup 1) (mem:P (post_inc:P (reg:P SP_REG)))) 17537 (set (match_dup 1) (mem:P (post_inc:P (reg:P SP_REG))))]) 17538 17539;; Convert compares with 1 to shorter inc/dec operations when CF is not 17540;; required and register dies. Similarly for 128 to -128. 17541(define_peephole2 17542 [(set (match_operand 0 "flags_reg_operand" "") 17543 (match_operator 1 "compare_operator" 17544 [(match_operand 2 "register_operand" "") 17545 (match_operand 3 "const_int_operand" "")]))] 17546 "(((!TARGET_FUSE_CMP_AND_BRANCH || optimize_insn_for_size_p ()) 17547 && incdec_operand (operands[3], GET_MODE (operands[3]))) 17548 || (!TARGET_FUSE_CMP_AND_BRANCH 17549 && INTVAL (operands[3]) == 128)) 17550 && ix86_match_ccmode (insn, CCGCmode) 17551 && peep2_reg_dead_p (1, operands[2])" 17552 [(parallel [(set (match_dup 0) 17553 (match_op_dup 1 [(match_dup 2) (match_dup 3)])) 17554 (clobber (match_dup 2))])]) 17555 17556;; Convert imul by three, five and nine into lea 17557(define_peephole2 17558 [(parallel 17559 [(set (match_operand:SWI48 0 "register_operand" "") 17560 (mult:SWI48 (match_operand:SWI48 1 "register_operand" "") 17561 (match_operand:SWI48 2 "const359_operand" ""))) 17562 (clobber (reg:CC FLAGS_REG))])] 17563 "!TARGET_PARTIAL_REG_STALL 17564 || <MODE>mode == SImode 17565 || optimize_function_for_size_p (cfun)" 17566 [(set (match_dup 0) 17567 (plus:SWI48 (mult:SWI48 (match_dup 1) (match_dup 2)) 17568 (match_dup 1)))] 17569 "operands[2] = GEN_INT (INTVAL (operands[2]) - 1);") 17570 17571(define_peephole2 17572 [(parallel 17573 [(set (match_operand:SWI48 0 "register_operand" "") 17574 (mult:SWI48 (match_operand:SWI48 1 "nonimmediate_operand" "") 17575 (match_operand:SWI48 2 "const359_operand" ""))) 17576 (clobber (reg:CC FLAGS_REG))])] 17577 "optimize_insn_for_speed_p () 17578 && (!TARGET_PARTIAL_REG_STALL || <MODE>mode == SImode)" 17579 [(set (match_dup 0) (match_dup 1)) 17580 (set (match_dup 0) 17581 (plus:SWI48 (mult:SWI48 (match_dup 0) (match_dup 2)) 17582 (match_dup 0)))] 17583 "operands[2] = GEN_INT (INTVAL (operands[2]) - 1);") 17584 17585;; imul $32bit_imm, mem, reg is vector decoded, while 17586;; imul $32bit_imm, reg, reg is direct decoded. 17587(define_peephole2 17588 [(match_scratch:SWI48 3 "r") 17589 (parallel [(set (match_operand:SWI48 0 "register_operand" "") 17590 (mult:SWI48 (match_operand:SWI48 1 "memory_operand" "") 17591 (match_operand:SWI48 2 "immediate_operand" ""))) 17592 (clobber (reg:CC FLAGS_REG))])] 17593 "TARGET_SLOW_IMUL_IMM32_MEM && optimize_insn_for_speed_p () 17594 && !satisfies_constraint_K (operands[2])" 17595 [(set (match_dup 3) (match_dup 1)) 17596 (parallel [(set (match_dup 0) (mult:SWI48 (match_dup 3) (match_dup 2))) 17597 (clobber (reg:CC FLAGS_REG))])]) 17598 17599(define_peephole2 17600 [(match_scratch:SI 3 "r") 17601 (parallel [(set (match_operand:DI 0 "register_operand" "") 17602 (zero_extend:DI 17603 (mult:SI (match_operand:SI 1 "memory_operand" "") 17604 (match_operand:SI 2 "immediate_operand" "")))) 17605 (clobber (reg:CC FLAGS_REG))])] 17606 "TARGET_64BIT 17607 && TARGET_SLOW_IMUL_IMM32_MEM && optimize_insn_for_speed_p () 17608 && !satisfies_constraint_K (operands[2])" 17609 [(set (match_dup 3) (match_dup 1)) 17610 (parallel [(set (match_dup 0) 17611 (zero_extend:DI (mult:SI (match_dup 3) (match_dup 2)))) 17612 (clobber (reg:CC FLAGS_REG))])]) 17613 17614;; imul $8/16bit_imm, regmem, reg is vector decoded. 17615;; Convert it into imul reg, reg 17616;; It would be better to force assembler to encode instruction using long 17617;; immediate, but there is apparently no way to do so. 17618(define_peephole2 17619 [(parallel [(set (match_operand:SWI248 0 "register_operand" "") 17620 (mult:SWI248 17621 (match_operand:SWI248 1 "nonimmediate_operand" "") 17622 (match_operand:SWI248 2 "const_int_operand" ""))) 17623 (clobber (reg:CC FLAGS_REG))]) 17624 (match_scratch:SWI248 3 "r")] 17625 "TARGET_SLOW_IMUL_IMM8 && optimize_insn_for_speed_p () 17626 && satisfies_constraint_K (operands[2])" 17627 [(set (match_dup 3) (match_dup 2)) 17628 (parallel [(set (match_dup 0) (mult:SWI248 (match_dup 0) (match_dup 3))) 17629 (clobber (reg:CC FLAGS_REG))])] 17630{ 17631 if (!rtx_equal_p (operands[0], operands[1])) 17632 emit_move_insn (operands[0], operands[1]); 17633}) 17634 17635;; After splitting up read-modify operations, array accesses with memory 17636;; operands might end up in form: 17637;; sall $2, %eax 17638;; movl 4(%esp), %edx 17639;; addl %edx, %eax 17640;; instead of pre-splitting: 17641;; sall $2, %eax 17642;; addl 4(%esp), %eax 17643;; Turn it into: 17644;; movl 4(%esp), %edx 17645;; leal (%edx,%eax,4), %eax 17646 17647(define_peephole2 17648 [(match_scratch:P 5 "r") 17649 (parallel [(set (match_operand 0 "register_operand" "") 17650 (ashift (match_operand 1 "register_operand" "") 17651 (match_operand 2 "const_int_operand" ""))) 17652 (clobber (reg:CC FLAGS_REG))]) 17653 (parallel [(set (match_operand 3 "register_operand" "") 17654 (plus (match_dup 0) 17655 (match_operand 4 "x86_64_general_operand" ""))) 17656 (clobber (reg:CC FLAGS_REG))])] 17657 "IN_RANGE (INTVAL (operands[2]), 1, 3) 17658 /* Validate MODE for lea. */ 17659 && ((!TARGET_PARTIAL_REG_STALL 17660 && (GET_MODE (operands[0]) == QImode 17661 || GET_MODE (operands[0]) == HImode)) 17662 || GET_MODE (operands[0]) == SImode 17663 || (TARGET_64BIT && GET_MODE (operands[0]) == DImode)) 17664 && (rtx_equal_p (operands[0], operands[3]) 17665 || peep2_reg_dead_p (2, operands[0])) 17666 /* We reorder load and the shift. */ 17667 && !reg_overlap_mentioned_p (operands[0], operands[4])" 17668 [(set (match_dup 5) (match_dup 4)) 17669 (set (match_dup 0) (match_dup 1))] 17670{ 17671 enum machine_mode op1mode = GET_MODE (operands[1]); 17672 enum machine_mode mode = op1mode == DImode ? DImode : SImode; 17673 int scale = 1 << INTVAL (operands[2]); 17674 rtx index = gen_lowpart (Pmode, operands[1]); 17675 rtx base = gen_lowpart (Pmode, operands[5]); 17676 rtx dest = gen_lowpart (mode, operands[3]); 17677 17678 operands[1] = gen_rtx_PLUS (Pmode, base, 17679 gen_rtx_MULT (Pmode, index, GEN_INT (scale))); 17680 operands[5] = base; 17681 if (mode != Pmode) 17682 operands[1] = gen_rtx_SUBREG (mode, operands[1], 0); 17683 if (op1mode != Pmode) 17684 operands[5] = gen_rtx_SUBREG (op1mode, operands[5], 0); 17685 operands[0] = dest; 17686}) 17687 17688;; We used to use "int $5", in honor of #BR which maps to interrupt vector 5. 17689;; That, however, is usually mapped by the OS to SIGSEGV, which is often 17690;; caught for use by garbage collectors and the like. Using an insn that 17691;; maps to SIGILL makes it more likely the program will rightfully die. 17692;; Keeping with tradition, "6" is in honor of #UD. 17693(define_insn "trap" 17694 [(trap_if (const_int 1) (const_int 6))] 17695 "" 17696 { return ASM_SHORT "0x0b0f"; } 17697 [(set_attr "length" "2")]) 17698 17699(define_expand "prefetch" 17700 [(prefetch (match_operand 0 "address_operand" "") 17701 (match_operand:SI 1 "const_int_operand" "") 17702 (match_operand:SI 2 "const_int_operand" ""))] 17703 "TARGET_PREFETCH_SSE || TARGET_3DNOW" 17704{ 17705 int rw = INTVAL (operands[1]); 17706 int locality = INTVAL (operands[2]); 17707 17708 gcc_assert (rw == 0 || rw == 1); 17709 gcc_assert (IN_RANGE (locality, 0, 3)); 17710 17711 if (TARGET_PREFETCHW && rw) 17712 operands[2] = GEN_INT (3); 17713 /* Use 3dNOW prefetch in case we are asking for write prefetch not 17714 supported by SSE counterpart or the SSE prefetch is not available 17715 (K6 machines). Otherwise use SSE prefetch as it allows specifying 17716 of locality. */ 17717 else if (TARGET_3DNOW && (!TARGET_PREFETCH_SSE || rw)) 17718 operands[2] = GEN_INT (3); 17719 else 17720 operands[1] = const0_rtx; 17721}) 17722 17723(define_insn "*prefetch_sse" 17724 [(prefetch (match_operand 0 "address_operand" "p") 17725 (const_int 0) 17726 (match_operand:SI 1 "const_int_operand" ""))] 17727 "TARGET_PREFETCH_SSE" 17728{ 17729 static const char * const patterns[4] = { 17730 "prefetchnta\t%a0", "prefetcht2\t%a0", "prefetcht1\t%a0", "prefetcht0\t%a0" 17731 }; 17732 17733 int locality = INTVAL (operands[1]); 17734 gcc_assert (IN_RANGE (locality, 0, 3)); 17735 17736 return patterns[locality]; 17737} 17738 [(set_attr "type" "sse") 17739 (set_attr "atom_sse_attr" "prefetch") 17740 (set (attr "length_address") 17741 (symbol_ref "memory_address_length (operands[0], false)")) 17742 (set_attr "memory" "none")]) 17743 17744(define_insn "*prefetch_3dnow" 17745 [(prefetch (match_operand 0 "address_operand" "p") 17746 (match_operand:SI 1 "const_int_operand" "n") 17747 (const_int 3))] 17748 "TARGET_3DNOW || TARGET_PREFETCHW" 17749{ 17750 if (INTVAL (operands[1]) == 0) 17751 return "prefetch\t%a0"; 17752 else 17753 return "prefetchw\t%a0"; 17754} 17755 [(set_attr "type" "mmx") 17756 (set (attr "length_address") 17757 (symbol_ref "memory_address_length (operands[0], false)")) 17758 (set_attr "memory" "none")]) 17759 17760(define_expand "stack_protect_set" 17761 [(match_operand 0 "memory_operand" "") 17762 (match_operand 1 "memory_operand" "")] 17763 "!TARGET_HAS_BIONIC" 17764{ 17765 rtx (*insn)(rtx, rtx); 17766 17767#ifdef TARGET_THREAD_SSP_OFFSET 17768 operands[1] = GEN_INT (TARGET_THREAD_SSP_OFFSET); 17769 insn = (TARGET_LP64 17770 ? gen_stack_tls_protect_set_di 17771 : gen_stack_tls_protect_set_si); 17772#else 17773 insn = (TARGET_LP64 17774 ? gen_stack_protect_set_di 17775 : gen_stack_protect_set_si); 17776#endif 17777 17778 emit_insn (insn (operands[0], operands[1])); 17779 DONE; 17780}) 17781 17782(define_insn "stack_protect_set_<mode>" 17783 [(set (match_operand:PTR 0 "memory_operand" "=m") 17784 (unspec:PTR [(match_operand:PTR 1 "memory_operand" "m")] 17785 UNSPEC_SP_SET)) 17786 (set (match_scratch:PTR 2 "=&r") (const_int 0)) 17787 (clobber (reg:CC FLAGS_REG))] 17788 "!TARGET_HAS_BIONIC" 17789 "mov{<imodesuffix>}\t{%1, %2|%2, %1}\;mov{<imodesuffix>}\t{%2, %0|%0, %2}\;xor{l}\t%k2, %k2" 17790 [(set_attr "type" "multi")]) 17791 17792(define_insn "stack_tls_protect_set_<mode>" 17793 [(set (match_operand:PTR 0 "memory_operand" "=m") 17794 (unspec:PTR [(match_operand:PTR 1 "const_int_operand" "i")] 17795 UNSPEC_SP_TLS_SET)) 17796 (set (match_scratch:PTR 2 "=&r") (const_int 0)) 17797 (clobber (reg:CC FLAGS_REG))] 17798 "" 17799 "mov{<imodesuffix>}\t{%@:%P1, %2|%2, <iptrsize> PTR %@:%P1}\;mov{<imodesuffix>}\t{%2, %0|%0, %2}\;xor{l}\t%k2, %k2" 17800 [(set_attr "type" "multi")]) 17801 17802(define_expand "stack_protect_test" 17803 [(match_operand 0 "memory_operand" "") 17804 (match_operand 1 "memory_operand" "") 17805 (match_operand 2 "" "")] 17806 "!TARGET_HAS_BIONIC" 17807{ 17808 rtx flags = gen_rtx_REG (CCZmode, FLAGS_REG); 17809 17810 rtx (*insn)(rtx, rtx, rtx); 17811 17812#ifdef TARGET_THREAD_SSP_OFFSET 17813 operands[1] = GEN_INT (TARGET_THREAD_SSP_OFFSET); 17814 insn = (TARGET_LP64 17815 ? gen_stack_tls_protect_test_di 17816 : gen_stack_tls_protect_test_si); 17817#else 17818 insn = (TARGET_LP64 17819 ? gen_stack_protect_test_di 17820 : gen_stack_protect_test_si); 17821#endif 17822 17823 emit_insn (insn (flags, operands[0], operands[1])); 17824 17825 emit_jump_insn (gen_cbranchcc4 (gen_rtx_EQ (VOIDmode, flags, const0_rtx), 17826 flags, const0_rtx, operands[2])); 17827 DONE; 17828}) 17829 17830(define_insn "stack_protect_test_<mode>" 17831 [(set (match_operand:CCZ 0 "flags_reg_operand" "") 17832 (unspec:CCZ [(match_operand:PTR 1 "memory_operand" "m") 17833 (match_operand:PTR 2 "memory_operand" "m")] 17834 UNSPEC_SP_TEST)) 17835 (clobber (match_scratch:PTR 3 "=&r"))] 17836 "!TARGET_HAS_BIONIC" 17837 "mov{<imodesuffix>}\t{%1, %3|%3, %1}\;xor{<imodesuffix>}\t{%2, %3|%3, %2}" 17838 [(set_attr "type" "multi")]) 17839 17840(define_insn "stack_tls_protect_test_<mode>" 17841 [(set (match_operand:CCZ 0 "flags_reg_operand" "") 17842 (unspec:CCZ [(match_operand:PTR 1 "memory_operand" "m") 17843 (match_operand:PTR 2 "const_int_operand" "i")] 17844 UNSPEC_SP_TLS_TEST)) 17845 (clobber (match_scratch:PTR 3 "=r"))] 17846 "" 17847 "mov{<imodesuffix>}\t{%1, %3|%3, %1}\;xor{<imodesuffix>}\t{%@:%P2, %3|%3, <iptrsize> PTR %@:%P2}" 17848 [(set_attr "type" "multi")]) 17849 17850(define_insn "sse4_2_crc32<mode>" 17851 [(set (match_operand:SI 0 "register_operand" "=r") 17852 (unspec:SI 17853 [(match_operand:SI 1 "register_operand" "0") 17854 (match_operand:SWI124 2 "nonimmediate_operand" "<r>m")] 17855 UNSPEC_CRC32))] 17856 "TARGET_SSE4_2 || TARGET_CRC32" 17857 "crc32{<imodesuffix>}\t{%2, %0|%0, %2}" 17858 [(set_attr "type" "sselog1") 17859 (set_attr "prefix_rep" "1") 17860 (set_attr "prefix_extra" "1") 17861 (set (attr "prefix_data16") 17862 (if_then_else (match_operand:HI 2 "" "") 17863 (const_string "1") 17864 (const_string "*"))) 17865 (set (attr "prefix_rex") 17866 (if_then_else (match_operand:QI 2 "ext_QIreg_operand" "") 17867 (const_string "1") 17868 (const_string "*"))) 17869 (set_attr "mode" "SI")]) 17870 17871(define_insn "sse4_2_crc32di" 17872 [(set (match_operand:DI 0 "register_operand" "=r") 17873 (unspec:DI 17874 [(match_operand:DI 1 "register_operand" "0") 17875 (match_operand:DI 2 "nonimmediate_operand" "rm")] 17876 UNSPEC_CRC32))] 17877 "TARGET_64BIT && (TARGET_SSE4_2 || TARGET_CRC32)" 17878 "crc32{q}\t{%2, %0|%0, %2}" 17879 [(set_attr "type" "sselog1") 17880 (set_attr "prefix_rep" "1") 17881 (set_attr "prefix_extra" "1") 17882 (set_attr "mode" "DI")]) 17883 17884(define_expand "rdpmc" 17885 [(match_operand:DI 0 "register_operand" "") 17886 (match_operand:SI 1 "register_operand" "")] 17887 "" 17888{ 17889 rtx reg = gen_reg_rtx (DImode); 17890 rtx si; 17891 17892 /* Force operand 1 into ECX. */ 17893 rtx ecx = gen_rtx_REG (SImode, CX_REG); 17894 emit_insn (gen_rtx_SET (VOIDmode, ecx, operands[1])); 17895 si = gen_rtx_UNSPEC_VOLATILE (DImode, gen_rtvec (1, ecx), 17896 UNSPECV_RDPMC); 17897 17898 if (TARGET_64BIT) 17899 { 17900 rtvec vec = rtvec_alloc (2); 17901 rtx load = gen_rtx_PARALLEL (VOIDmode, vec); 17902 rtx upper = gen_reg_rtx (DImode); 17903 rtx di = gen_rtx_UNSPEC_VOLATILE (DImode, 17904 gen_rtvec (1, const0_rtx), 17905 UNSPECV_RDPMC); 17906 RTVEC_ELT (vec, 0) = gen_rtx_SET (VOIDmode, reg, si); 17907 RTVEC_ELT (vec, 1) = gen_rtx_SET (VOIDmode, upper, di); 17908 emit_insn (load); 17909 upper = expand_simple_binop (DImode, ASHIFT, upper, GEN_INT (32), 17910 NULL, 1, OPTAB_DIRECT); 17911 reg = expand_simple_binop (DImode, IOR, reg, upper, reg, 1, 17912 OPTAB_DIRECT); 17913 } 17914 else 17915 emit_insn (gen_rtx_SET (VOIDmode, reg, si)); 17916 emit_insn (gen_rtx_SET (VOIDmode, operands[0], reg)); 17917 DONE; 17918}) 17919 17920(define_insn "*rdpmc" 17921 [(set (match_operand:DI 0 "register_operand" "=A") 17922 (unspec_volatile:DI [(match_operand:SI 1 "register_operand" "c")] 17923 UNSPECV_RDPMC))] 17924 "!TARGET_64BIT" 17925 "rdpmc" 17926 [(set_attr "type" "other") 17927 (set_attr "length" "2")]) 17928 17929(define_insn "*rdpmc_rex64" 17930 [(set (match_operand:DI 0 "register_operand" "=a") 17931 (unspec_volatile:DI [(match_operand:SI 2 "register_operand" "c")] 17932 UNSPECV_RDPMC)) 17933 (set (match_operand:DI 1 "register_operand" "=d") 17934 (unspec_volatile:DI [(const_int 0)] UNSPECV_RDPMC))] 17935 "TARGET_64BIT" 17936 "rdpmc" 17937 [(set_attr "type" "other") 17938 (set_attr "length" "2")]) 17939 17940(define_expand "rdtsc" 17941 [(set (match_operand:DI 0 "register_operand" "") 17942 (unspec_volatile:DI [(const_int 0)] UNSPECV_RDTSC))] 17943 "" 17944{ 17945 if (TARGET_64BIT) 17946 { 17947 rtvec vec = rtvec_alloc (2); 17948 rtx load = gen_rtx_PARALLEL (VOIDmode, vec); 17949 rtx upper = gen_reg_rtx (DImode); 17950 rtx lower = gen_reg_rtx (DImode); 17951 rtx src = gen_rtx_UNSPEC_VOLATILE (DImode, 17952 gen_rtvec (1, const0_rtx), 17953 UNSPECV_RDTSC); 17954 RTVEC_ELT (vec, 0) = gen_rtx_SET (VOIDmode, lower, src); 17955 RTVEC_ELT (vec, 1) = gen_rtx_SET (VOIDmode, upper, src); 17956 emit_insn (load); 17957 upper = expand_simple_binop (DImode, ASHIFT, upper, GEN_INT (32), 17958 NULL, 1, OPTAB_DIRECT); 17959 lower = expand_simple_binop (DImode, IOR, lower, upper, lower, 1, 17960 OPTAB_DIRECT); 17961 emit_insn (gen_rtx_SET (VOIDmode, operands[0], lower)); 17962 DONE; 17963 } 17964}) 17965 17966(define_insn "*rdtsc" 17967 [(set (match_operand:DI 0 "register_operand" "=A") 17968 (unspec_volatile:DI [(const_int 0)] UNSPECV_RDTSC))] 17969 "!TARGET_64BIT" 17970 "rdtsc" 17971 [(set_attr "type" "other") 17972 (set_attr "length" "2")]) 17973 17974(define_insn "*rdtsc_rex64" 17975 [(set (match_operand:DI 0 "register_operand" "=a") 17976 (unspec_volatile:DI [(const_int 0)] UNSPECV_RDTSC)) 17977 (set (match_operand:DI 1 "register_operand" "=d") 17978 (unspec_volatile:DI [(const_int 0)] UNSPECV_RDTSC))] 17979 "TARGET_64BIT" 17980 "rdtsc" 17981 [(set_attr "type" "other") 17982 (set_attr "length" "2")]) 17983 17984(define_expand "rdtscp" 17985 [(match_operand:DI 0 "register_operand" "") 17986 (match_operand:SI 1 "memory_operand" "")] 17987 "" 17988{ 17989 rtx di = gen_rtx_UNSPEC_VOLATILE (DImode, 17990 gen_rtvec (1, const0_rtx), 17991 UNSPECV_RDTSCP); 17992 rtx si = gen_rtx_UNSPEC_VOLATILE (SImode, 17993 gen_rtvec (1, const0_rtx), 17994 UNSPECV_RDTSCP); 17995 rtx reg = gen_reg_rtx (DImode); 17996 rtx tmp = gen_reg_rtx (SImode); 17997 17998 if (TARGET_64BIT) 17999 { 18000 rtvec vec = rtvec_alloc (3); 18001 rtx load = gen_rtx_PARALLEL (VOIDmode, vec); 18002 rtx upper = gen_reg_rtx (DImode); 18003 RTVEC_ELT (vec, 0) = gen_rtx_SET (VOIDmode, reg, di); 18004 RTVEC_ELT (vec, 1) = gen_rtx_SET (VOIDmode, upper, di); 18005 RTVEC_ELT (vec, 2) = gen_rtx_SET (VOIDmode, tmp, si); 18006 emit_insn (load); 18007 upper = expand_simple_binop (DImode, ASHIFT, upper, GEN_INT (32), 18008 NULL, 1, OPTAB_DIRECT); 18009 reg = expand_simple_binop (DImode, IOR, reg, upper, reg, 1, 18010 OPTAB_DIRECT); 18011 } 18012 else 18013 { 18014 rtvec vec = rtvec_alloc (2); 18015 rtx load = gen_rtx_PARALLEL (VOIDmode, vec); 18016 RTVEC_ELT (vec, 0) = gen_rtx_SET (VOIDmode, reg, di); 18017 RTVEC_ELT (vec, 1) = gen_rtx_SET (VOIDmode, tmp, si); 18018 emit_insn (load); 18019 } 18020 emit_insn (gen_rtx_SET (VOIDmode, operands[0], reg)); 18021 emit_insn (gen_rtx_SET (VOIDmode, operands[1], tmp)); 18022 DONE; 18023}) 18024 18025(define_insn "*rdtscp" 18026 [(set (match_operand:DI 0 "register_operand" "=A") 18027 (unspec_volatile:DI [(const_int 0)] UNSPECV_RDTSCP)) 18028 (set (match_operand:SI 1 "register_operand" "=c") 18029 (unspec_volatile:SI [(const_int 0)] UNSPECV_RDTSCP))] 18030 "!TARGET_64BIT" 18031 "rdtscp" 18032 [(set_attr "type" "other") 18033 (set_attr "length" "3")]) 18034 18035(define_insn "*rdtscp_rex64" 18036 [(set (match_operand:DI 0 "register_operand" "=a") 18037 (unspec_volatile:DI [(const_int 0)] UNSPECV_RDTSCP)) 18038 (set (match_operand:DI 1 "register_operand" "=d") 18039 (unspec_volatile:DI [(const_int 0)] UNSPECV_RDTSCP)) 18040 (set (match_operand:SI 2 "register_operand" "=c") 18041 (unspec_volatile:SI [(const_int 0)] UNSPECV_RDTSCP))] 18042 "TARGET_64BIT" 18043 "rdtscp" 18044 [(set_attr "type" "other") 18045 (set_attr "length" "3")]) 18046 18047;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; 18048;; 18049;; LWP instructions 18050;; 18051;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; 18052 18053(define_expand "lwp_llwpcb" 18054 [(unspec_volatile [(match_operand 0 "register_operand" "r")] 18055 UNSPECV_LLWP_INTRINSIC)] 18056 "TARGET_LWP") 18057 18058(define_insn "*lwp_llwpcb<mode>1" 18059 [(unspec_volatile [(match_operand:P 0 "register_operand" "r")] 18060 UNSPECV_LLWP_INTRINSIC)] 18061 "TARGET_LWP" 18062 "llwpcb\t%0" 18063 [(set_attr "type" "lwp") 18064 (set_attr "mode" "<MODE>") 18065 (set_attr "length" "5")]) 18066 18067(define_expand "lwp_slwpcb" 18068 [(set (match_operand 0 "register_operand" "=r") 18069 (unspec_volatile [(const_int 0)] UNSPECV_SLWP_INTRINSIC))] 18070 "TARGET_LWP" 18071{ 18072 rtx (*insn)(rtx); 18073 18074 insn = (TARGET_64BIT 18075 ? gen_lwp_slwpcbdi 18076 : gen_lwp_slwpcbsi); 18077 18078 emit_insn (insn (operands[0])); 18079 DONE; 18080}) 18081 18082(define_insn "lwp_slwpcb<mode>" 18083 [(set (match_operand:P 0 "register_operand" "=r") 18084 (unspec_volatile:P [(const_int 0)] UNSPECV_SLWP_INTRINSIC))] 18085 "TARGET_LWP" 18086 "slwpcb\t%0" 18087 [(set_attr "type" "lwp") 18088 (set_attr "mode" "<MODE>") 18089 (set_attr "length" "5")]) 18090 18091(define_expand "lwp_lwpval<mode>3" 18092 [(unspec_volatile [(match_operand:SWI48 1 "register_operand" "r") 18093 (match_operand:SI 2 "nonimmediate_operand" "rm") 18094 (match_operand:SI 3 "const_int_operand" "i")] 18095 UNSPECV_LWPVAL_INTRINSIC)] 18096 "TARGET_LWP" 18097 ;; Avoid unused variable warning. 18098 "(void) operands[0];") 18099 18100(define_insn "*lwp_lwpval<mode>3_1" 18101 [(unspec_volatile [(match_operand:SWI48 0 "register_operand" "r") 18102 (match_operand:SI 1 "nonimmediate_operand" "rm") 18103 (match_operand:SI 2 "const_int_operand" "i")] 18104 UNSPECV_LWPVAL_INTRINSIC)] 18105 "TARGET_LWP" 18106 "lwpval\t{%2, %1, %0|%0, %1, %2}" 18107 [(set_attr "type" "lwp") 18108 (set_attr "mode" "<MODE>") 18109 (set (attr "length") 18110 (symbol_ref "ix86_attr_length_address_default (insn) + 9"))]) 18111 18112(define_expand "lwp_lwpins<mode>3" 18113 [(set (reg:CCC FLAGS_REG) 18114 (unspec_volatile:CCC [(match_operand:SWI48 1 "register_operand" "r") 18115 (match_operand:SI 2 "nonimmediate_operand" "rm") 18116 (match_operand:SI 3 "const_int_operand" "i")] 18117 UNSPECV_LWPINS_INTRINSIC)) 18118 (set (match_operand:QI 0 "nonimmediate_operand" "=qm") 18119 (eq:QI (reg:CCC FLAGS_REG) (const_int 0)))] 18120 "TARGET_LWP") 18121 18122(define_insn "*lwp_lwpins<mode>3_1" 18123 [(set (reg:CCC FLAGS_REG) 18124 (unspec_volatile:CCC [(match_operand:SWI48 0 "register_operand" "r") 18125 (match_operand:SI 1 "nonimmediate_operand" "rm") 18126 (match_operand:SI 2 "const_int_operand" "i")] 18127 UNSPECV_LWPINS_INTRINSIC))] 18128 "TARGET_LWP" 18129 "lwpins\t{%2, %1, %0|%0, %1, %2}" 18130 [(set_attr "type" "lwp") 18131 (set_attr "mode" "<MODE>") 18132 (set (attr "length") 18133 (symbol_ref "ix86_attr_length_address_default (insn) + 9"))]) 18134 18135(define_insn "rdfsbase<mode>" 18136 [(set (match_operand:SWI48 0 "register_operand" "=r") 18137 (unspec_volatile:SWI48 [(const_int 0)] UNSPECV_RDFSBASE))] 18138 "TARGET_64BIT && TARGET_FSGSBASE" 18139 "rdfsbase %0" 18140 [(set_attr "type" "other") 18141 (set_attr "prefix_extra" "2")]) 18142 18143(define_insn "rdgsbase<mode>" 18144 [(set (match_operand:SWI48 0 "register_operand" "=r") 18145 (unspec_volatile:SWI48 [(const_int 0)] UNSPECV_RDGSBASE))] 18146 "TARGET_64BIT && TARGET_FSGSBASE" 18147 "rdgsbase %0" 18148 [(set_attr "type" "other") 18149 (set_attr "prefix_extra" "2")]) 18150 18151(define_insn "wrfsbase<mode>" 18152 [(unspec_volatile [(match_operand:SWI48 0 "register_operand" "r")] 18153 UNSPECV_WRFSBASE)] 18154 "TARGET_64BIT && TARGET_FSGSBASE" 18155 "wrfsbase %0" 18156 [(set_attr "type" "other") 18157 (set_attr "prefix_extra" "2")]) 18158 18159(define_insn "wrgsbase<mode>" 18160 [(unspec_volatile [(match_operand:SWI48 0 "register_operand" "r")] 18161 UNSPECV_WRGSBASE)] 18162 "TARGET_64BIT && TARGET_FSGSBASE" 18163 "wrgsbase %0" 18164 [(set_attr "type" "other") 18165 (set_attr "prefix_extra" "2")]) 18166 18167(define_insn "rdrand<mode>_1" 18168 [(set (match_operand:SWI248 0 "register_operand" "=r") 18169 (unspec_volatile:SWI248 [(const_int 0)] UNSPECV_RDRAND)) 18170 (set (reg:CCC FLAGS_REG) 18171 (unspec_volatile:CCC [(const_int 0)] UNSPECV_RDRAND))] 18172 "TARGET_RDRND" 18173 "rdrand\t%0" 18174 [(set_attr "type" "other") 18175 (set_attr "prefix_extra" "1")]) 18176 18177(define_expand "pause" 18178 [(set (match_dup 0) 18179 (unspec:BLK [(match_dup 0)] UNSPEC_PAUSE))] 18180 "" 18181{ 18182 operands[0] = gen_rtx_MEM (BLKmode, gen_rtx_SCRATCH (Pmode)); 18183 MEM_VOLATILE_P (operands[0]) = 1; 18184}) 18185 18186;; Use "rep; nop", instead of "pause", to support older assemblers. 18187;; They have the same encoding. 18188(define_insn "*pause" 18189 [(set (match_operand:BLK 0 "" "") 18190 (unspec:BLK [(match_dup 0)] UNSPEC_PAUSE))] 18191 "" 18192 "rep; nop" 18193 [(set_attr "length" "2") 18194 (set_attr "memory" "unknown")]) 18195 18196(include "mmx.md") 18197(include "sse.md") 18198(include "sync.md") 18199