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 113 ;; For SSE/MMX support: 114 UNSPEC_FIX_NOTRUNC 115 UNSPEC_MASKMOV 116 UNSPEC_MOVMSK 117 UNSPEC_RCP 118 UNSPEC_RSQRT 119 UNSPEC_PSADBW 120 121 ;; Generic math support 122 UNSPEC_COPYSIGN 123 UNSPEC_IEEE_MIN ; not commutative 124 UNSPEC_IEEE_MAX ; not commutative 125 126 ;; x87 Floating point 127 UNSPEC_SIN 128 UNSPEC_COS 129 UNSPEC_FPATAN 130 UNSPEC_FYL2X 131 UNSPEC_FYL2XP1 132 UNSPEC_FRNDINT 133 UNSPEC_FIST 134 UNSPEC_F2XM1 135 UNSPEC_TAN 136 UNSPEC_FXAM 137 138 ;; x87 Rounding 139 UNSPEC_FRNDINT_FLOOR 140 UNSPEC_FRNDINT_CEIL 141 UNSPEC_FRNDINT_TRUNC 142 UNSPEC_FRNDINT_MASK_PM 143 UNSPEC_FIST_FLOOR 144 UNSPEC_FIST_CEIL 145 146 ;; x87 Double output FP 147 UNSPEC_SINCOS_COS 148 UNSPEC_SINCOS_SIN 149 UNSPEC_XTRACT_FRACT 150 UNSPEC_XTRACT_EXP 151 UNSPEC_FSCALE_FRACT 152 UNSPEC_FSCALE_EXP 153 UNSPEC_FPREM_F 154 UNSPEC_FPREM_U 155 UNSPEC_FPREM1_F 156 UNSPEC_FPREM1_U 157 158 UNSPEC_C2_FLAG 159 UNSPEC_FXAM_MEM 160 161 ;; SSP patterns 162 UNSPEC_SP_SET 163 UNSPEC_SP_TEST 164 UNSPEC_SP_TLS_SET 165 UNSPEC_SP_TLS_TEST 166 167 ;; For ROUND support 168 UNSPEC_ROUND 169 170 ;; For CRC32 support 171 UNSPEC_CRC32 172 173 ;; For BMI support 174 UNSPEC_BEXTR 175 176 ;; For BMI2 support 177 UNSPEC_PDEP 178 UNSPEC_PEXT 179]) 180 181(define_c_enum "unspecv" [ 182 UNSPECV_BLOCKAGE 183 UNSPECV_STACK_PROBE 184 UNSPECV_PROBE_STACK_RANGE 185 UNSPECV_ALIGN 186 UNSPECV_PROLOGUE_USE 187 UNSPECV_SPLIT_STACK_RETURN 188 UNSPECV_CLD 189 UNSPECV_NOPS 190 UNSPECV_RDTSC 191 UNSPECV_RDTSCP 192 UNSPECV_RDPMC 193 UNSPECV_LLWP_INTRINSIC 194 UNSPECV_SLWP_INTRINSIC 195 UNSPECV_LWPVAL_INTRINSIC 196 UNSPECV_LWPINS_INTRINSIC 197 UNSPECV_RDFSBASE 198 UNSPECV_RDGSBASE 199 UNSPECV_WRFSBASE 200 UNSPECV_WRGSBASE 201 202 ;; For RDRAND support 203 UNSPECV_RDRAND 204]) 205 206;; Constants to represent rounding modes in the ROUND instruction 207(define_constants 208 [(ROUND_FLOOR 0x1) 209 (ROUND_CEIL 0x2) 210 (ROUND_TRUNC 0x3) 211 (ROUND_MXCSR 0x4) 212 (ROUND_NO_EXC 0x8) 213 ]) 214 215;; Constants to represent pcomtrue/pcomfalse variants 216(define_constants 217 [(PCOM_FALSE 0) 218 (PCOM_TRUE 1) 219 (COM_FALSE_S 2) 220 (COM_FALSE_P 3) 221 (COM_TRUE_S 4) 222 (COM_TRUE_P 5) 223 ]) 224 225;; Constants used in the XOP pperm instruction 226(define_constants 227 [(PPERM_SRC 0x00) /* copy source */ 228 (PPERM_INVERT 0x20) /* invert source */ 229 (PPERM_REVERSE 0x40) /* bit reverse source */ 230 (PPERM_REV_INV 0x60) /* bit reverse & invert src */ 231 (PPERM_ZERO 0x80) /* all 0's */ 232 (PPERM_ONES 0xa0) /* all 1's */ 233 (PPERM_SIGN 0xc0) /* propagate sign bit */ 234 (PPERM_INV_SIGN 0xe0) /* invert & propagate sign */ 235 (PPERM_SRC1 0x00) /* use first source byte */ 236 (PPERM_SRC2 0x10) /* use second source byte */ 237 ]) 238 239;; Registers by name. 240(define_constants 241 [(AX_REG 0) 242 (DX_REG 1) 243 (CX_REG 2) 244 (BX_REG 3) 245 (SI_REG 4) 246 (DI_REG 5) 247 (BP_REG 6) 248 (SP_REG 7) 249 (ST0_REG 8) 250 (ST1_REG 9) 251 (ST2_REG 10) 252 (ST3_REG 11) 253 (ST4_REG 12) 254 (ST5_REG 13) 255 (ST6_REG 14) 256 (ST7_REG 15) 257 (FLAGS_REG 17) 258 (FPSR_REG 18) 259 (FPCR_REG 19) 260 (XMM0_REG 21) 261 (XMM1_REG 22) 262 (XMM2_REG 23) 263 (XMM3_REG 24) 264 (XMM4_REG 25) 265 (XMM5_REG 26) 266 (XMM6_REG 27) 267 (XMM7_REG 28) 268 (MM0_REG 29) 269 (MM1_REG 30) 270 (MM2_REG 31) 271 (MM3_REG 32) 272 (MM4_REG 33) 273 (MM5_REG 34) 274 (MM6_REG 35) 275 (MM7_REG 36) 276 (R8_REG 37) 277 (R9_REG 38) 278 (R10_REG 39) 279 (R11_REG 40) 280 (R12_REG 41) 281 (R13_REG 42) 282 (XMM8_REG 45) 283 (XMM9_REG 46) 284 (XMM10_REG 47) 285 (XMM11_REG 48) 286 (XMM12_REG 49) 287 (XMM13_REG 50) 288 (XMM14_REG 51) 289 (XMM15_REG 52) 290 ]) 291 292;; Insns whose names begin with "x86_" are emitted by gen_FOO calls 293;; from i386.c. 294 295;; In C guard expressions, put expressions which may be compile-time 296;; constants first. This allows for better optimization. For 297;; example, write "TARGET_64BIT && reload_completed", not 298;; "reload_completed && TARGET_64BIT". 299 300 301;; Processor type. 302(define_attr "cpu" "none,pentium,pentiumpro,geode,k6,athlon,k8,core2,corei7, 303 atom,generic64,amdfam10,bdver1,bdver2,btver1" 304 (const (symbol_ref "ix86_schedule"))) 305 306;; A basic instruction type. Refinements due to arguments to be 307;; provided in other attributes. 308(define_attr "type" 309 "other,multi, 310 alu,alu1,negnot,imov,imovx,lea, 311 incdec,ishift,ishiftx,ishift1,rotate,rotatex,rotate1,imul,imulx,idiv, 312 icmp,test,ibr,setcc,icmov, 313 push,pop,call,callv,leave, 314 str,bitmanip, 315 fmov,fop,fsgn,fmul,fdiv,fpspc,fcmov,fcmp,fxch,fistp,fisttp,frndint, 316 sselog,sselog1,sseiadd,sseiadd1,sseishft,sseishft1,sseimul, 317 sse,ssemov,sseadd,ssemul,ssecmp,ssecomi,ssecvt,ssecvt1,sseicvt,ssediv,sseins, 318 ssemuladd,sse4arg,lwp, 319 mmx,mmxmov,mmxadd,mmxmul,mmxcmp,mmxcvt,mmxshft" 320 (const_string "other")) 321 322;; Main data type used by the insn 323(define_attr "mode" 324 "unknown,none,QI,HI,SI,DI,TI,OI,SF,DF,XF,TF,V8SF,V4DF,V4SF,V2DF,V2SF,V1DF" 325 (const_string "unknown")) 326 327;; The CPU unit operations uses. 328(define_attr "unit" "integer,i387,sse,mmx,unknown" 329 (cond [(eq_attr "type" "fmov,fop,fsgn,fmul,fdiv,fpspc,fcmov,fcmp,fxch,fistp,fisttp,frndint") 330 (const_string "i387") 331 (eq_attr "type" "sselog,sselog1,sseiadd,sseiadd1,sseishft,sseishft1,sseimul, 332 sse,ssemov,sseadd,ssemul,ssecmp,ssecomi,ssecvt, 333 ssecvt1,sseicvt,ssediv,sseins,ssemuladd,sse4arg") 334 (const_string "sse") 335 (eq_attr "type" "mmx,mmxmov,mmxadd,mmxmul,mmxcmp,mmxcvt,mmxshft") 336 (const_string "mmx") 337 (eq_attr "type" "other") 338 (const_string "unknown")] 339 (const_string "integer"))) 340 341;; The (bounding maximum) length of an instruction immediate. 342(define_attr "length_immediate" "" 343 (cond [(eq_attr "type" "incdec,setcc,icmov,str,lea,other,multi,idiv,leave, 344 bitmanip,imulx") 345 (const_int 0) 346 (eq_attr "unit" "i387,sse,mmx") 347 (const_int 0) 348 (eq_attr "type" "alu,alu1,negnot,imovx,ishift,ishiftx,ishift1, 349 rotate,rotatex,rotate1,imul,icmp,push,pop") 350 (symbol_ref "ix86_attr_length_immediate_default (insn, true)") 351 (eq_attr "type" "imov,test") 352 (symbol_ref "ix86_attr_length_immediate_default (insn, false)") 353 (eq_attr "type" "call") 354 (if_then_else (match_operand 0 "constant_call_address_operand" "") 355 (const_int 4) 356 (const_int 0)) 357 (eq_attr "type" "callv") 358 (if_then_else (match_operand 1 "constant_call_address_operand" "") 359 (const_int 4) 360 (const_int 0)) 361 ;; We don't know the size before shorten_branches. Expect 362 ;; the instruction to fit for better scheduling. 363 (eq_attr "type" "ibr") 364 (const_int 1) 365 ] 366 (symbol_ref "/* Update immediate_length and other attributes! */ 367 gcc_unreachable (),1"))) 368 369;; The (bounding maximum) length of an instruction address. 370(define_attr "length_address" "" 371 (cond [(eq_attr "type" "str,other,multi,fxch") 372 (const_int 0) 373 (and (eq_attr "type" "call") 374 (match_operand 0 "constant_call_address_operand" "")) 375 (const_int 0) 376 (and (eq_attr "type" "callv") 377 (match_operand 1 "constant_call_address_operand" "")) 378 (const_int 0) 379 ] 380 (symbol_ref "ix86_attr_length_address_default (insn)"))) 381 382;; Set when length prefix is used. 383(define_attr "prefix_data16" "" 384 (cond [(eq_attr "type" "ssemuladd,sse4arg,sseiadd1,ssecvt1") 385 (const_int 0) 386 (eq_attr "mode" "HI") 387 (const_int 1) 388 (and (eq_attr "unit" "sse") (eq_attr "mode" "V2DF,TI")) 389 (const_int 1) 390 ] 391 (const_int 0))) 392 393;; Set when string REP prefix is used. 394(define_attr "prefix_rep" "" 395 (cond [(eq_attr "type" "ssemuladd,sse4arg,sseiadd1,ssecvt1") 396 (const_int 0) 397 (and (eq_attr "unit" "sse") (eq_attr "mode" "SF,DF")) 398 (const_int 1) 399 ] 400 (const_int 0))) 401 402;; Set when 0f opcode prefix is used. 403(define_attr "prefix_0f" "" 404 (if_then_else 405 (ior (eq_attr "type" "imovx,setcc,icmov,bitmanip") 406 (eq_attr "unit" "sse,mmx")) 407 (const_int 1) 408 (const_int 0))) 409 410;; Set when REX opcode prefix is used. 411(define_attr "prefix_rex" "" 412 (cond [(not (match_test "TARGET_64BIT")) 413 (const_int 0) 414 (and (eq_attr "mode" "DI") 415 (and (eq_attr "type" "!push,pop,call,callv,leave,ibr") 416 (eq_attr "unit" "!mmx"))) 417 (const_int 1) 418 (and (eq_attr "mode" "QI") 419 (match_test "x86_extended_QIreg_mentioned_p (insn)")) 420 (const_int 1) 421 (match_test "x86_extended_reg_mentioned_p (insn)") 422 (const_int 1) 423 (and (eq_attr "type" "imovx") 424 (match_operand:QI 1 "ext_QIreg_operand" "")) 425 (const_int 1) 426 ] 427 (const_int 0))) 428 429;; There are also additional prefixes in 3DNOW, SSSE3. 430;; ssemuladd,sse4arg default to 0f24/0f25 and DREX byte, 431;; sseiadd1,ssecvt1 to 0f7a with no DREX byte. 432;; 3DNOW has 0f0f prefix, SSSE3 and SSE4_{1,2} 0f38/0f3a. 433(define_attr "prefix_extra" "" 434 (cond [(eq_attr "type" "ssemuladd,sse4arg") 435 (const_int 2) 436 (eq_attr "type" "sseiadd1,ssecvt1") 437 (const_int 1) 438 ] 439 (const_int 0))) 440 441;; Prefix used: original, VEX or maybe VEX. 442(define_attr "prefix" "orig,vex,maybe_vex" 443 (if_then_else (eq_attr "mode" "OI,V8SF,V4DF") 444 (const_string "vex") 445 (const_string "orig"))) 446 447;; VEX W bit is used. 448(define_attr "prefix_vex_w" "" (const_int 0)) 449 450;; The length of VEX prefix 451;; Only instructions with 0f prefix can have 2 byte VEX prefix, 452;; 0f38/0f3a prefixes can't. In i386.md 0f3[8a] is 453;; still prefix_0f 1, with prefix_extra 1. 454(define_attr "length_vex" "" 455 (if_then_else (and (eq_attr "prefix_0f" "1") 456 (eq_attr "prefix_extra" "0")) 457 (if_then_else (eq_attr "prefix_vex_w" "1") 458 (symbol_ref "ix86_attr_length_vex_default (insn, true, true)") 459 (symbol_ref "ix86_attr_length_vex_default (insn, true, false)")) 460 (if_then_else (eq_attr "prefix_vex_w" "1") 461 (symbol_ref "ix86_attr_length_vex_default (insn, false, true)") 462 (symbol_ref "ix86_attr_length_vex_default (insn, false, false)")))) 463 464;; Set when modrm byte is used. 465(define_attr "modrm" "" 466 (cond [(eq_attr "type" "str,leave") 467 (const_int 0) 468 (eq_attr "unit" "i387") 469 (const_int 0) 470 (and (eq_attr "type" "incdec") 471 (and (not (match_test "TARGET_64BIT")) 472 (ior (match_operand:SI 1 "register_operand" "") 473 (match_operand:HI 1 "register_operand" "")))) 474 (const_int 0) 475 (and (eq_attr "type" "push") 476 (not (match_operand 1 "memory_operand" ""))) 477 (const_int 0) 478 (and (eq_attr "type" "pop") 479 (not (match_operand 0 "memory_operand" ""))) 480 (const_int 0) 481 (and (eq_attr "type" "imov") 482 (and (not (eq_attr "mode" "DI")) 483 (ior (and (match_operand 0 "register_operand" "") 484 (match_operand 1 "immediate_operand" "")) 485 (ior (and (match_operand 0 "ax_reg_operand" "") 486 (match_operand 1 "memory_displacement_only_operand" "")) 487 (and (match_operand 0 "memory_displacement_only_operand" "") 488 (match_operand 1 "ax_reg_operand" "")))))) 489 (const_int 0) 490 (and (eq_attr "type" "call") 491 (match_operand 0 "constant_call_address_operand" "")) 492 (const_int 0) 493 (and (eq_attr "type" "callv") 494 (match_operand 1 "constant_call_address_operand" "")) 495 (const_int 0) 496 (and (eq_attr "type" "alu,alu1,icmp,test") 497 (match_operand 0 "ax_reg_operand" "")) 498 (symbol_ref "(get_attr_length_immediate (insn) <= (get_attr_mode (insn) != MODE_QI))") 499 ] 500 (const_int 1))) 501 502;; The (bounding maximum) length of an instruction in bytes. 503;; ??? fistp and frndint are in fact fldcw/{fistp,frndint}/fldcw sequences. 504;; Later we may want to split them and compute proper length as for 505;; other insns. 506(define_attr "length" "" 507 (cond [(eq_attr "type" "other,multi,fistp,frndint") 508 (const_int 16) 509 (eq_attr "type" "fcmp") 510 (const_int 4) 511 (eq_attr "unit" "i387") 512 (plus (const_int 2) 513 (plus (attr "prefix_data16") 514 (attr "length_address"))) 515 (ior (eq_attr "prefix" "vex") 516 (and (eq_attr "prefix" "maybe_vex") 517 (match_test "TARGET_AVX"))) 518 (plus (attr "length_vex") 519 (plus (attr "length_immediate") 520 (plus (attr "modrm") 521 (attr "length_address"))))] 522 (plus (plus (attr "modrm") 523 (plus (attr "prefix_0f") 524 (plus (attr "prefix_rex") 525 (plus (attr "prefix_extra") 526 (const_int 1))))) 527 (plus (attr "prefix_rep") 528 (plus (attr "prefix_data16") 529 (plus (attr "length_immediate") 530 (attr "length_address"))))))) 531 532;; The `memory' attribute is `none' if no memory is referenced, `load' or 533;; `store' if there is a simple memory reference therein, or `unknown' 534;; if the instruction is complex. 535 536(define_attr "memory" "none,load,store,both,unknown" 537 (cond [(eq_attr "type" "other,multi,str,lwp") 538 (const_string "unknown") 539 (eq_attr "type" "lea,fcmov,fpspc") 540 (const_string "none") 541 (eq_attr "type" "fistp,leave") 542 (const_string "both") 543 (eq_attr "type" "frndint") 544 (const_string "load") 545 (eq_attr "type" "push") 546 (if_then_else (match_operand 1 "memory_operand" "") 547 (const_string "both") 548 (const_string "store")) 549 (eq_attr "type" "pop") 550 (if_then_else (match_operand 0 "memory_operand" "") 551 (const_string "both") 552 (const_string "load")) 553 (eq_attr "type" "setcc") 554 (if_then_else (match_operand 0 "memory_operand" "") 555 (const_string "store") 556 (const_string "none")) 557 (eq_attr "type" "icmp,test,ssecmp,ssecomi,mmxcmp,fcmp") 558 (if_then_else (ior (match_operand 0 "memory_operand" "") 559 (match_operand 1 "memory_operand" "")) 560 (const_string "load") 561 (const_string "none")) 562 (eq_attr "type" "ibr") 563 (if_then_else (match_operand 0 "memory_operand" "") 564 (const_string "load") 565 (const_string "none")) 566 (eq_attr "type" "call") 567 (if_then_else (match_operand 0 "constant_call_address_operand" "") 568 (const_string "none") 569 (const_string "load")) 570 (eq_attr "type" "callv") 571 (if_then_else (match_operand 1 "constant_call_address_operand" "") 572 (const_string "none") 573 (const_string "load")) 574 (and (eq_attr "type" "alu1,negnot,ishift1,sselog1") 575 (match_operand 1 "memory_operand" "")) 576 (const_string "both") 577 (and (match_operand 0 "memory_operand" "") 578 (match_operand 1 "memory_operand" "")) 579 (const_string "both") 580 (match_operand 0 "memory_operand" "") 581 (const_string "store") 582 (match_operand 1 "memory_operand" "") 583 (const_string "load") 584 (and (eq_attr "type" 585 "!alu1,negnot,ishift1, 586 imov,imovx,icmp,test,bitmanip, 587 fmov,fcmp,fsgn, 588 sse,ssemov,ssecmp,ssecomi,ssecvt,ssecvt1,sseicvt,sselog1, 589 sseiadd1,mmx,mmxmov,mmxcmp,mmxcvt") 590 (match_operand 2 "memory_operand" "")) 591 (const_string "load") 592 (and (eq_attr "type" "icmov,ssemuladd,sse4arg") 593 (match_operand 3 "memory_operand" "")) 594 (const_string "load") 595 ] 596 (const_string "none"))) 597 598;; Indicates if an instruction has both an immediate and a displacement. 599 600(define_attr "imm_disp" "false,true,unknown" 601 (cond [(eq_attr "type" "other,multi") 602 (const_string "unknown") 603 (and (eq_attr "type" "icmp,test,imov,alu1,ishift1,rotate1") 604 (and (match_operand 0 "memory_displacement_operand" "") 605 (match_operand 1 "immediate_operand" ""))) 606 (const_string "true") 607 (and (eq_attr "type" "alu,ishift,ishiftx,rotate,rotatex,imul,idiv") 608 (and (match_operand 0 "memory_displacement_operand" "") 609 (match_operand 2 "immediate_operand" ""))) 610 (const_string "true") 611 ] 612 (const_string "false"))) 613 614;; Indicates if an FP operation has an integer source. 615 616(define_attr "fp_int_src" "false,true" 617 (const_string "false")) 618 619;; Defines rounding mode of an FP operation. 620 621(define_attr "i387_cw" "trunc,floor,ceil,mask_pm,uninitialized,any" 622 (const_string "any")) 623 624;; Define attribute to classify add/sub insns that consumes carry flag (CF) 625(define_attr "use_carry" "0,1" (const_string "0")) 626 627;; Define attribute to indicate unaligned ssemov insns 628(define_attr "movu" "0,1" (const_string "0")) 629 630;; Used to control the "enabled" attribute on a per-instruction basis. 631(define_attr "isa" "base,sse2,sse2_noavx,sse3,sse4,sse4_noavx,noavx,avx, 632 bmi2,fma4,fma" 633 (const_string "base")) 634 635(define_attr "enabled" "" 636 (cond [(eq_attr "isa" "sse2") (symbol_ref "TARGET_SSE2") 637 (eq_attr "isa" "sse2_noavx") 638 (symbol_ref "TARGET_SSE2 && !TARGET_AVX") 639 (eq_attr "isa" "sse3") (symbol_ref "TARGET_SSE3") 640 (eq_attr "isa" "sse4") (symbol_ref "TARGET_SSE4_1") 641 (eq_attr "isa" "sse4_noavx") 642 (symbol_ref "TARGET_SSE4_1 && !TARGET_AVX") 643 (eq_attr "isa" "avx") (symbol_ref "TARGET_AVX") 644 (eq_attr "isa" "noavx") (symbol_ref "!TARGET_AVX") 645 (eq_attr "isa" "bmi2") (symbol_ref "TARGET_BMI2") 646 (eq_attr "isa" "fma4") (symbol_ref "TARGET_FMA4") 647 (eq_attr "isa" "fma") (symbol_ref "TARGET_FMA") 648 ] 649 (const_int 1))) 650 651;; Describe a user's asm statement. 652(define_asm_attributes 653 [(set_attr "length" "128") 654 (set_attr "type" "multi")]) 655 656(define_code_iterator plusminus [plus minus]) 657 658(define_code_iterator sat_plusminus [ss_plus us_plus ss_minus us_minus]) 659 660;; Base name for define_insn 661(define_code_attr plusminus_insn 662 [(plus "add") (ss_plus "ssadd") (us_plus "usadd") 663 (minus "sub") (ss_minus "sssub") (us_minus "ussub")]) 664 665;; Base name for insn mnemonic. 666(define_code_attr plusminus_mnemonic 667 [(plus "add") (ss_plus "adds") (us_plus "addus") 668 (minus "sub") (ss_minus "subs") (us_minus "subus")]) 669(define_code_attr plusminus_carry_mnemonic 670 [(plus "adc") (minus "sbb")]) 671 672;; Mark commutative operators as such in constraints. 673(define_code_attr comm [(plus "%") (ss_plus "%") (us_plus "%") 674 (minus "") (ss_minus "") (us_minus "")]) 675 676;; Mapping of max and min 677(define_code_iterator maxmin [smax smin umax umin]) 678 679;; Mapping of signed max and min 680(define_code_iterator smaxmin [smax smin]) 681 682;; Mapping of unsigned max and min 683(define_code_iterator umaxmin [umax umin]) 684 685;; Base name for integer and FP insn mnemonic 686(define_code_attr maxmin_int [(smax "maxs") (smin "mins") 687 (umax "maxu") (umin "minu")]) 688(define_code_attr maxmin_float [(smax "max") (smin "min")]) 689 690;; Mapping of logic operators 691(define_code_iterator any_logic [and ior xor]) 692(define_code_iterator any_or [ior xor]) 693 694;; Base name for insn mnemonic. 695(define_code_attr logic [(and "and") (ior "or") (xor "xor")]) 696 697;; Mapping of logic-shift operators 698(define_code_iterator any_lshift [ashift lshiftrt]) 699 700;; Mapping of shift-right operators 701(define_code_iterator any_shiftrt [lshiftrt ashiftrt]) 702 703;; Base name for define_insn 704(define_code_attr shift_insn 705 [(ashift "ashl") (lshiftrt "lshr") (ashiftrt "ashr")]) 706 707;; Base name for insn mnemonic. 708(define_code_attr shift [(ashift "sll") (lshiftrt "shr") (ashiftrt "sar")]) 709(define_code_attr vshift [(ashift "sll") (lshiftrt "srl") (ashiftrt "sra")]) 710 711;; Mapping of rotate operators 712(define_code_iterator any_rotate [rotate rotatert]) 713 714;; Base name for define_insn 715(define_code_attr rotate_insn [(rotate "rotl") (rotatert "rotr")]) 716 717;; Base name for insn mnemonic. 718(define_code_attr rotate [(rotate "rol") (rotatert "ror")]) 719 720;; Mapping of abs neg operators 721(define_code_iterator absneg [abs neg]) 722 723;; Base name for x87 insn mnemonic. 724(define_code_attr absneg_mnemonic [(abs "abs") (neg "chs")]) 725 726;; Used in signed and unsigned widening multiplications. 727(define_code_iterator any_extend [sign_extend zero_extend]) 728 729;; Prefix for insn menmonic. 730(define_code_attr sgnprefix [(sign_extend "i") (zero_extend "")]) 731 732;; Prefix for define_insn 733(define_code_attr u [(sign_extend "") (zero_extend "u")]) 734(define_code_attr s [(sign_extend "s") (zero_extend "u")]) 735 736;; All integer modes. 737(define_mode_iterator SWI1248x [QI HI SI DI]) 738 739;; All integer modes without QImode. 740(define_mode_iterator SWI248x [HI SI DI]) 741 742;; All integer modes without QImode and HImode. 743(define_mode_iterator SWI48x [SI DI]) 744 745;; All integer modes without SImode and DImode. 746(define_mode_iterator SWI12 [QI HI]) 747 748;; All integer modes without DImode. 749(define_mode_iterator SWI124 [QI HI SI]) 750 751;; All integer modes without QImode and DImode. 752(define_mode_iterator SWI24 [HI SI]) 753 754;; Single word integer modes. 755(define_mode_iterator SWI [QI HI SI (DI "TARGET_64BIT")]) 756 757;; Single word integer modes without QImode. 758(define_mode_iterator SWI248 [HI SI (DI "TARGET_64BIT")]) 759 760;; Single word integer modes without QImode and HImode. 761(define_mode_iterator SWI48 [SI (DI "TARGET_64BIT")]) 762 763;; All math-dependant single and double word integer modes. 764(define_mode_iterator SDWIM [(QI "TARGET_QIMODE_MATH") 765 (HI "TARGET_HIMODE_MATH") 766 SI DI (TI "TARGET_64BIT")]) 767 768;; Math-dependant single word integer modes. 769(define_mode_iterator SWIM [(QI "TARGET_QIMODE_MATH") 770 (HI "TARGET_HIMODE_MATH") 771 SI (DI "TARGET_64BIT")]) 772 773;; Math-dependant integer modes without DImode. 774(define_mode_iterator SWIM124 [(QI "TARGET_QIMODE_MATH") 775 (HI "TARGET_HIMODE_MATH") 776 SI]) 777 778;; Math-dependant single word integer modes without QImode. 779(define_mode_iterator SWIM248 [(HI "TARGET_HIMODE_MATH") 780 SI (DI "TARGET_64BIT")]) 781 782;; Double word integer modes. 783(define_mode_iterator DWI [(DI "!TARGET_64BIT") 784 (TI "TARGET_64BIT")]) 785 786;; Double word integer modes as mode attribute. 787(define_mode_attr DWI [(SI "DI") (DI "TI")]) 788(define_mode_attr dwi [(SI "di") (DI "ti")]) 789 790;; Half mode for double word integer modes. 791(define_mode_iterator DWIH [(SI "!TARGET_64BIT") 792 (DI "TARGET_64BIT")]) 793 794;; Instruction suffix for integer modes. 795(define_mode_attr imodesuffix [(QI "b") (HI "w") (SI "l") (DI "q")]) 796 797;; Pointer size prefix for integer modes (Intel asm dialect) 798(define_mode_attr iptrsize [(QI "BYTE") 799 (HI "WORD") 800 (SI "DWORD") 801 (DI "QWORD")]) 802 803;; Register class for integer modes. 804(define_mode_attr r [(QI "q") (HI "r") (SI "r") (DI "r")]) 805 806;; Immediate operand constraint for integer modes. 807(define_mode_attr i [(QI "n") (HI "n") (SI "e") (DI "e")]) 808 809;; General operand constraint for word modes. 810(define_mode_attr g [(QI "qmn") (HI "rmn") (SI "rme") (DI "rme")]) 811 812;; Immediate operand constraint for double integer modes. 813(define_mode_attr di [(SI "nF") (DI "e")]) 814 815;; Immediate operand constraint for shifts. 816(define_mode_attr S [(QI "I") (HI "I") (SI "I") (DI "J") (TI "O")]) 817 818;; General operand predicate for integer modes. 819(define_mode_attr general_operand 820 [(QI "general_operand") 821 (HI "general_operand") 822 (SI "x86_64_general_operand") 823 (DI "x86_64_general_operand") 824 (TI "x86_64_general_operand")]) 825 826;; General sign/zero extend operand predicate for integer modes. 827(define_mode_attr general_szext_operand 828 [(QI "general_operand") 829 (HI "general_operand") 830 (SI "x86_64_szext_general_operand") 831 (DI "x86_64_szext_general_operand")]) 832 833;; Immediate operand predicate for integer modes. 834(define_mode_attr immediate_operand 835 [(QI "immediate_operand") 836 (HI "immediate_operand") 837 (SI "x86_64_immediate_operand") 838 (DI "x86_64_immediate_operand")]) 839 840;; Nonmemory operand predicate for integer modes. 841(define_mode_attr nonmemory_operand 842 [(QI "nonmemory_operand") 843 (HI "nonmemory_operand") 844 (SI "x86_64_nonmemory_operand") 845 (DI "x86_64_nonmemory_operand")]) 846 847;; Operand predicate for shifts. 848(define_mode_attr shift_operand 849 [(QI "nonimmediate_operand") 850 (HI "nonimmediate_operand") 851 (SI "nonimmediate_operand") 852 (DI "shiftdi_operand") 853 (TI "register_operand")]) 854 855;; Operand predicate for shift argument. 856(define_mode_attr shift_immediate_operand 857 [(QI "const_1_to_31_operand") 858 (HI "const_1_to_31_operand") 859 (SI "const_1_to_31_operand") 860 (DI "const_1_to_63_operand")]) 861 862;; Input operand predicate for arithmetic left shifts. 863(define_mode_attr ashl_input_operand 864 [(QI "nonimmediate_operand") 865 (HI "nonimmediate_operand") 866 (SI "nonimmediate_operand") 867 (DI "ashldi_input_operand") 868 (TI "reg_or_pm1_operand")]) 869 870;; SSE and x87 SFmode and DFmode floating point modes 871(define_mode_iterator MODEF [SF DF]) 872 873;; All x87 floating point modes 874(define_mode_iterator X87MODEF [SF DF XF]) 875 876;; SSE instruction suffix for various modes 877(define_mode_attr ssemodesuffix 878 [(SF "ss") (DF "sd") 879 (V8SF "ps") (V4DF "pd") 880 (V4SF "ps") (V2DF "pd") 881 (V16QI "b") (V8HI "w") (V4SI "d") (V2DI "q") 882 (V32QI "b") (V16HI "w") (V8SI "d") (V4DI "q")]) 883 884;; SSE vector suffix for floating point modes 885(define_mode_attr ssevecmodesuffix [(SF "ps") (DF "pd")]) 886 887;; SSE vector mode corresponding to a scalar mode 888(define_mode_attr ssevecmode 889 [(QI "V16QI") (HI "V8HI") (SI "V4SI") (DI "V2DI") (SF "V4SF") (DF "V2DF")]) 890 891;; Instruction suffix for REX 64bit operators. 892(define_mode_attr rex64suffix [(SI "") (DI "{q}")]) 893 894;; This mode iterator allows :P to be used for patterns that operate on 895;; pointer-sized quantities. Exactly one of the two alternatives will match. 896(define_mode_iterator P [(SI "Pmode == SImode") (DI "Pmode == DImode")]) 897 898;; This mode iterator allows :PTR to be used for patterns that operate on 899;; ptr_mode sized quantities. 900(define_mode_iterator PTR 901 [(SI "ptr_mode == SImode") (DI "ptr_mode == DImode")]) 902 903;; Scheduling descriptions 904 905(include "pentium.md") 906(include "ppro.md") 907(include "k6.md") 908(include "athlon.md") 909(include "bdver1.md") 910(include "geode.md") 911(include "atom.md") 912(include "core2.md") 913 914 915;; Operand and operator predicates and constraints 916 917(include "predicates.md") 918(include "constraints.md") 919 920 921;; Compare and branch/compare and store instructions. 922 923(define_expand "cbranch<mode>4" 924 [(set (reg:CC FLAGS_REG) 925 (compare:CC (match_operand:SDWIM 1 "nonimmediate_operand" "") 926 (match_operand:SDWIM 2 "<general_operand>" ""))) 927 (set (pc) (if_then_else 928 (match_operator 0 "ordered_comparison_operator" 929 [(reg:CC FLAGS_REG) (const_int 0)]) 930 (label_ref (match_operand 3 "" "")) 931 (pc)))] 932 "" 933{ 934 if (MEM_P (operands[1]) && MEM_P (operands[2])) 935 operands[1] = force_reg (<MODE>mode, operands[1]); 936 ix86_expand_branch (GET_CODE (operands[0]), 937 operands[1], operands[2], operands[3]); 938 DONE; 939}) 940 941(define_expand "cstore<mode>4" 942 [(set (reg:CC FLAGS_REG) 943 (compare:CC (match_operand:SWIM 2 "nonimmediate_operand" "") 944 (match_operand:SWIM 3 "<general_operand>" ""))) 945 (set (match_operand:QI 0 "register_operand" "") 946 (match_operator 1 "ordered_comparison_operator" 947 [(reg:CC FLAGS_REG) (const_int 0)]))] 948 "" 949{ 950 if (MEM_P (operands[2]) && MEM_P (operands[3])) 951 operands[2] = force_reg (<MODE>mode, operands[2]); 952 ix86_expand_setcc (operands[0], GET_CODE (operands[1]), 953 operands[2], operands[3]); 954 DONE; 955}) 956 957(define_expand "cmp<mode>_1" 958 [(set (reg:CC FLAGS_REG) 959 (compare:CC (match_operand:SWI48 0 "nonimmediate_operand" "") 960 (match_operand:SWI48 1 "<general_operand>" "")))]) 961 962(define_insn "*cmp<mode>_ccno_1" 963 [(set (reg FLAGS_REG) 964 (compare (match_operand:SWI 0 "nonimmediate_operand" "<r>,?m<r>") 965 (match_operand:SWI 1 "const0_operand" "")))] 966 "ix86_match_ccmode (insn, CCNOmode)" 967 "@ 968 test{<imodesuffix>}\t%0, %0 969 cmp{<imodesuffix>}\t{%1, %0|%0, %1}" 970 [(set_attr "type" "test,icmp") 971 (set_attr "length_immediate" "0,1") 972 (set_attr "mode" "<MODE>")]) 973 974(define_insn "*cmp<mode>_1" 975 [(set (reg FLAGS_REG) 976 (compare (match_operand:SWI 0 "nonimmediate_operand" "<r>m,<r>") 977 (match_operand:SWI 1 "<general_operand>" "<r><i>,<r>m")))] 978 "ix86_match_ccmode (insn, CCmode)" 979 "cmp{<imodesuffix>}\t{%1, %0|%0, %1}" 980 [(set_attr "type" "icmp") 981 (set_attr "mode" "<MODE>")]) 982 983(define_insn "*cmp<mode>_minus_1" 984 [(set (reg FLAGS_REG) 985 (compare 986 (minus:SWI (match_operand:SWI 0 "nonimmediate_operand" "<r>m,<r>") 987 (match_operand:SWI 1 "<general_operand>" "<r><i>,<r>m")) 988 (const_int 0)))] 989 "ix86_match_ccmode (insn, CCGOCmode)" 990 "cmp{<imodesuffix>}\t{%1, %0|%0, %1}" 991 [(set_attr "type" "icmp") 992 (set_attr "mode" "<MODE>")]) 993 994(define_insn "*cmpqi_ext_1" 995 [(set (reg FLAGS_REG) 996 (compare 997 (match_operand:QI 0 "general_operand" "Qm") 998 (subreg:QI 999 (zero_extract:SI 1000 (match_operand 1 "ext_register_operand" "Q") 1001 (const_int 8) 1002 (const_int 8)) 0)))] 1003 "!TARGET_64BIT && ix86_match_ccmode (insn, CCmode)" 1004 "cmp{b}\t{%h1, %0|%0, %h1}" 1005 [(set_attr "type" "icmp") 1006 (set_attr "mode" "QI")]) 1007 1008(define_insn "*cmpqi_ext_1_rex64" 1009 [(set (reg FLAGS_REG) 1010 (compare 1011 (match_operand:QI 0 "register_operand" "Q") 1012 (subreg:QI 1013 (zero_extract:SI 1014 (match_operand 1 "ext_register_operand" "Q") 1015 (const_int 8) 1016 (const_int 8)) 0)))] 1017 "TARGET_64BIT && ix86_match_ccmode (insn, CCmode)" 1018 "cmp{b}\t{%h1, %0|%0, %h1}" 1019 [(set_attr "type" "icmp") 1020 (set_attr "mode" "QI")]) 1021 1022(define_insn "*cmpqi_ext_2" 1023 [(set (reg FLAGS_REG) 1024 (compare 1025 (subreg:QI 1026 (zero_extract:SI 1027 (match_operand 0 "ext_register_operand" "Q") 1028 (const_int 8) 1029 (const_int 8)) 0) 1030 (match_operand:QI 1 "const0_operand" "")))] 1031 "ix86_match_ccmode (insn, CCNOmode)" 1032 "test{b}\t%h0, %h0" 1033 [(set_attr "type" "test") 1034 (set_attr "length_immediate" "0") 1035 (set_attr "mode" "QI")]) 1036 1037(define_expand "cmpqi_ext_3" 1038 [(set (reg:CC FLAGS_REG) 1039 (compare:CC 1040 (subreg:QI 1041 (zero_extract:SI 1042 (match_operand 0 "ext_register_operand" "") 1043 (const_int 8) 1044 (const_int 8)) 0) 1045 (match_operand:QI 1 "immediate_operand" "")))]) 1046 1047(define_insn "*cmpqi_ext_3_insn" 1048 [(set (reg FLAGS_REG) 1049 (compare 1050 (subreg:QI 1051 (zero_extract:SI 1052 (match_operand 0 "ext_register_operand" "Q") 1053 (const_int 8) 1054 (const_int 8)) 0) 1055 (match_operand:QI 1 "general_operand" "Qmn")))] 1056 "!TARGET_64BIT && ix86_match_ccmode (insn, CCmode)" 1057 "cmp{b}\t{%1, %h0|%h0, %1}" 1058 [(set_attr "type" "icmp") 1059 (set_attr "modrm" "1") 1060 (set_attr "mode" "QI")]) 1061 1062(define_insn "*cmpqi_ext_3_insn_rex64" 1063 [(set (reg FLAGS_REG) 1064 (compare 1065 (subreg:QI 1066 (zero_extract:SI 1067 (match_operand 0 "ext_register_operand" "Q") 1068 (const_int 8) 1069 (const_int 8)) 0) 1070 (match_operand:QI 1 "nonmemory_operand" "Qn")))] 1071 "TARGET_64BIT && ix86_match_ccmode (insn, CCmode)" 1072 "cmp{b}\t{%1, %h0|%h0, %1}" 1073 [(set_attr "type" "icmp") 1074 (set_attr "modrm" "1") 1075 (set_attr "mode" "QI")]) 1076 1077(define_insn "*cmpqi_ext_4" 1078 [(set (reg FLAGS_REG) 1079 (compare 1080 (subreg:QI 1081 (zero_extract:SI 1082 (match_operand 0 "ext_register_operand" "Q") 1083 (const_int 8) 1084 (const_int 8)) 0) 1085 (subreg:QI 1086 (zero_extract:SI 1087 (match_operand 1 "ext_register_operand" "Q") 1088 (const_int 8) 1089 (const_int 8)) 0)))] 1090 "ix86_match_ccmode (insn, CCmode)" 1091 "cmp{b}\t{%h1, %h0|%h0, %h1}" 1092 [(set_attr "type" "icmp") 1093 (set_attr "mode" "QI")]) 1094 1095;; These implement float point compares. 1096;; %%% See if we can get away with VOIDmode operands on the actual insns, 1097;; which would allow mix and match FP modes on the compares. Which is what 1098;; the old patterns did, but with many more of them. 1099 1100(define_expand "cbranchxf4" 1101 [(set (reg:CC FLAGS_REG) 1102 (compare:CC (match_operand:XF 1 "nonmemory_operand" "") 1103 (match_operand:XF 2 "nonmemory_operand" ""))) 1104 (set (pc) (if_then_else 1105 (match_operator 0 "ix86_fp_comparison_operator" 1106 [(reg:CC FLAGS_REG) 1107 (const_int 0)]) 1108 (label_ref (match_operand 3 "" "")) 1109 (pc)))] 1110 "TARGET_80387" 1111{ 1112 ix86_expand_branch (GET_CODE (operands[0]), 1113 operands[1], operands[2], operands[3]); 1114 DONE; 1115}) 1116 1117(define_expand "cstorexf4" 1118 [(set (reg:CC FLAGS_REG) 1119 (compare:CC (match_operand:XF 2 "nonmemory_operand" "") 1120 (match_operand:XF 3 "nonmemory_operand" ""))) 1121 (set (match_operand:QI 0 "register_operand" "") 1122 (match_operator 1 "ix86_fp_comparison_operator" 1123 [(reg:CC FLAGS_REG) 1124 (const_int 0)]))] 1125 "TARGET_80387" 1126{ 1127 ix86_expand_setcc (operands[0], GET_CODE (operands[1]), 1128 operands[2], operands[3]); 1129 DONE; 1130}) 1131 1132(define_expand "cbranch<mode>4" 1133 [(set (reg:CC FLAGS_REG) 1134 (compare:CC (match_operand:MODEF 1 "cmp_fp_expander_operand" "") 1135 (match_operand:MODEF 2 "cmp_fp_expander_operand" ""))) 1136 (set (pc) (if_then_else 1137 (match_operator 0 "ix86_fp_comparison_operator" 1138 [(reg:CC FLAGS_REG) 1139 (const_int 0)]) 1140 (label_ref (match_operand 3 "" "")) 1141 (pc)))] 1142 "TARGET_80387 || (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)" 1143{ 1144 ix86_expand_branch (GET_CODE (operands[0]), 1145 operands[1], operands[2], operands[3]); 1146 DONE; 1147}) 1148 1149(define_expand "cstore<mode>4" 1150 [(set (reg:CC FLAGS_REG) 1151 (compare:CC (match_operand:MODEF 2 "cmp_fp_expander_operand" "") 1152 (match_operand:MODEF 3 "cmp_fp_expander_operand" ""))) 1153 (set (match_operand:QI 0 "register_operand" "") 1154 (match_operator 1 "ix86_fp_comparison_operator" 1155 [(reg:CC FLAGS_REG) 1156 (const_int 0)]))] 1157 "TARGET_80387 || (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)" 1158{ 1159 ix86_expand_setcc (operands[0], GET_CODE (operands[1]), 1160 operands[2], operands[3]); 1161 DONE; 1162}) 1163 1164(define_expand "cbranchcc4" 1165 [(set (pc) (if_then_else 1166 (match_operator 0 "comparison_operator" 1167 [(match_operand 1 "flags_reg_operand" "") 1168 (match_operand 2 "const0_operand" "")]) 1169 (label_ref (match_operand 3 "" "")) 1170 (pc)))] 1171 "" 1172{ 1173 ix86_expand_branch (GET_CODE (operands[0]), 1174 operands[1], operands[2], operands[3]); 1175 DONE; 1176}) 1177 1178(define_expand "cstorecc4" 1179 [(set (match_operand:QI 0 "register_operand" "") 1180 (match_operator 1 "comparison_operator" 1181 [(match_operand 2 "flags_reg_operand" "") 1182 (match_operand 3 "const0_operand" "")]))] 1183 "" 1184{ 1185 ix86_expand_setcc (operands[0], GET_CODE (operands[1]), 1186 operands[2], operands[3]); 1187 DONE; 1188}) 1189 1190 1191;; FP compares, step 1: 1192;; Set the FP condition codes. 1193;; 1194;; CCFPmode compare with exceptions 1195;; CCFPUmode compare with no exceptions 1196 1197;; We may not use "#" to split and emit these, since the REG_DEAD notes 1198;; used to manage the reg stack popping would not be preserved. 1199 1200(define_insn "*cmpfp_0" 1201 [(set (match_operand:HI 0 "register_operand" "=a") 1202 (unspec:HI 1203 [(compare:CCFP 1204 (match_operand 1 "register_operand" "f") 1205 (match_operand 2 "const0_operand" ""))] 1206 UNSPEC_FNSTSW))] 1207 "X87_FLOAT_MODE_P (GET_MODE (operands[1])) 1208 && GET_MODE (operands[1]) == GET_MODE (operands[2])" 1209 "* return output_fp_compare (insn, operands, false, false);" 1210 [(set_attr "type" "multi") 1211 (set_attr "unit" "i387") 1212 (set (attr "mode") 1213 (cond [(match_operand:SF 1 "" "") 1214 (const_string "SF") 1215 (match_operand:DF 1 "" "") 1216 (const_string "DF") 1217 ] 1218 (const_string "XF")))]) 1219 1220(define_insn_and_split "*cmpfp_0_cc" 1221 [(set (reg:CCFP FLAGS_REG) 1222 (compare:CCFP 1223 (match_operand 1 "register_operand" "f") 1224 (match_operand 2 "const0_operand" ""))) 1225 (clobber (match_operand:HI 0 "register_operand" "=a"))] 1226 "X87_FLOAT_MODE_P (GET_MODE (operands[1])) 1227 && TARGET_SAHF && !TARGET_CMOVE 1228 && GET_MODE (operands[1]) == GET_MODE (operands[2])" 1229 "#" 1230 "&& reload_completed" 1231 [(set (match_dup 0) 1232 (unspec:HI 1233 [(compare:CCFP (match_dup 1)(match_dup 2))] 1234 UNSPEC_FNSTSW)) 1235 (set (reg:CC FLAGS_REG) 1236 (unspec:CC [(match_dup 0)] UNSPEC_SAHF))] 1237 "" 1238 [(set_attr "type" "multi") 1239 (set_attr "unit" "i387") 1240 (set (attr "mode") 1241 (cond [(match_operand:SF 1 "" "") 1242 (const_string "SF") 1243 (match_operand:DF 1 "" "") 1244 (const_string "DF") 1245 ] 1246 (const_string "XF")))]) 1247 1248(define_insn "*cmpfp_xf" 1249 [(set (match_operand:HI 0 "register_operand" "=a") 1250 (unspec:HI 1251 [(compare:CCFP 1252 (match_operand:XF 1 "register_operand" "f") 1253 (match_operand:XF 2 "register_operand" "f"))] 1254 UNSPEC_FNSTSW))] 1255 "TARGET_80387" 1256 "* return output_fp_compare (insn, operands, false, false);" 1257 [(set_attr "type" "multi") 1258 (set_attr "unit" "i387") 1259 (set_attr "mode" "XF")]) 1260 1261(define_insn_and_split "*cmpfp_xf_cc" 1262 [(set (reg:CCFP FLAGS_REG) 1263 (compare:CCFP 1264 (match_operand:XF 1 "register_operand" "f") 1265 (match_operand:XF 2 "register_operand" "f"))) 1266 (clobber (match_operand:HI 0 "register_operand" "=a"))] 1267 "TARGET_80387 1268 && TARGET_SAHF && !TARGET_CMOVE" 1269 "#" 1270 "&& reload_completed" 1271 [(set (match_dup 0) 1272 (unspec:HI 1273 [(compare:CCFP (match_dup 1)(match_dup 2))] 1274 UNSPEC_FNSTSW)) 1275 (set (reg:CC FLAGS_REG) 1276 (unspec:CC [(match_dup 0)] UNSPEC_SAHF))] 1277 "" 1278 [(set_attr "type" "multi") 1279 (set_attr "unit" "i387") 1280 (set_attr "mode" "XF")]) 1281 1282(define_insn "*cmpfp_<mode>" 1283 [(set (match_operand:HI 0 "register_operand" "=a") 1284 (unspec:HI 1285 [(compare:CCFP 1286 (match_operand:MODEF 1 "register_operand" "f") 1287 (match_operand:MODEF 2 "nonimmediate_operand" "fm"))] 1288 UNSPEC_FNSTSW))] 1289 "TARGET_80387" 1290 "* return output_fp_compare (insn, operands, false, false);" 1291 [(set_attr "type" "multi") 1292 (set_attr "unit" "i387") 1293 (set_attr "mode" "<MODE>")]) 1294 1295(define_insn_and_split "*cmpfp_<mode>_cc" 1296 [(set (reg:CCFP FLAGS_REG) 1297 (compare:CCFP 1298 (match_operand:MODEF 1 "register_operand" "f") 1299 (match_operand:MODEF 2 "nonimmediate_operand" "fm"))) 1300 (clobber (match_operand:HI 0 "register_operand" "=a"))] 1301 "TARGET_80387 1302 && TARGET_SAHF && !TARGET_CMOVE" 1303 "#" 1304 "&& reload_completed" 1305 [(set (match_dup 0) 1306 (unspec:HI 1307 [(compare:CCFP (match_dup 1)(match_dup 2))] 1308 UNSPEC_FNSTSW)) 1309 (set (reg:CC FLAGS_REG) 1310 (unspec:CC [(match_dup 0)] UNSPEC_SAHF))] 1311 "" 1312 [(set_attr "type" "multi") 1313 (set_attr "unit" "i387") 1314 (set_attr "mode" "<MODE>")]) 1315 1316(define_insn "*cmpfp_u" 1317 [(set (match_operand:HI 0 "register_operand" "=a") 1318 (unspec:HI 1319 [(compare:CCFPU 1320 (match_operand 1 "register_operand" "f") 1321 (match_operand 2 "register_operand" "f"))] 1322 UNSPEC_FNSTSW))] 1323 "X87_FLOAT_MODE_P (GET_MODE (operands[1])) 1324 && GET_MODE (operands[1]) == GET_MODE (operands[2])" 1325 "* return output_fp_compare (insn, operands, false, true);" 1326 [(set_attr "type" "multi") 1327 (set_attr "unit" "i387") 1328 (set (attr "mode") 1329 (cond [(match_operand:SF 1 "" "") 1330 (const_string "SF") 1331 (match_operand:DF 1 "" "") 1332 (const_string "DF") 1333 ] 1334 (const_string "XF")))]) 1335 1336(define_insn_and_split "*cmpfp_u_cc" 1337 [(set (reg:CCFPU FLAGS_REG) 1338 (compare:CCFPU 1339 (match_operand 1 "register_operand" "f") 1340 (match_operand 2 "register_operand" "f"))) 1341 (clobber (match_operand:HI 0 "register_operand" "=a"))] 1342 "X87_FLOAT_MODE_P (GET_MODE (operands[1])) 1343 && TARGET_SAHF && !TARGET_CMOVE 1344 && GET_MODE (operands[1]) == GET_MODE (operands[2])" 1345 "#" 1346 "&& reload_completed" 1347 [(set (match_dup 0) 1348 (unspec:HI 1349 [(compare:CCFPU (match_dup 1)(match_dup 2))] 1350 UNSPEC_FNSTSW)) 1351 (set (reg:CC FLAGS_REG) 1352 (unspec:CC [(match_dup 0)] UNSPEC_SAHF))] 1353 "" 1354 [(set_attr "type" "multi") 1355 (set_attr "unit" "i387") 1356 (set (attr "mode") 1357 (cond [(match_operand:SF 1 "" "") 1358 (const_string "SF") 1359 (match_operand:DF 1 "" "") 1360 (const_string "DF") 1361 ] 1362 (const_string "XF")))]) 1363 1364(define_insn "*cmpfp_<mode>" 1365 [(set (match_operand:HI 0 "register_operand" "=a") 1366 (unspec:HI 1367 [(compare:CCFP 1368 (match_operand 1 "register_operand" "f") 1369 (match_operator 3 "float_operator" 1370 [(match_operand:SWI24 2 "memory_operand" "m")]))] 1371 UNSPEC_FNSTSW))] 1372 "X87_FLOAT_MODE_P (GET_MODE (operands[1])) 1373 && (TARGET_USE_<MODE>MODE_FIOP || optimize_function_for_size_p (cfun)) 1374 && (GET_MODE (operands [3]) == GET_MODE (operands[1]))" 1375 "* return output_fp_compare (insn, operands, false, false);" 1376 [(set_attr "type" "multi") 1377 (set_attr "unit" "i387") 1378 (set_attr "fp_int_src" "true") 1379 (set_attr "mode" "<MODE>")]) 1380 1381(define_insn_and_split "*cmpfp_<mode>_cc" 1382 [(set (reg:CCFP FLAGS_REG) 1383 (compare:CCFP 1384 (match_operand 1 "register_operand" "f") 1385 (match_operator 3 "float_operator" 1386 [(match_operand:SWI24 2 "memory_operand" "m")]))) 1387 (clobber (match_operand:HI 0 "register_operand" "=a"))] 1388 "X87_FLOAT_MODE_P (GET_MODE (operands[1])) 1389 && TARGET_SAHF && !TARGET_CMOVE 1390 && (TARGET_USE_<MODE>MODE_FIOP || optimize_function_for_size_p (cfun)) 1391 && (GET_MODE (operands [3]) == GET_MODE (operands[1]))" 1392 "#" 1393 "&& reload_completed" 1394 [(set (match_dup 0) 1395 (unspec:HI 1396 [(compare:CCFP 1397 (match_dup 1) 1398 (match_op_dup 3 [(match_dup 2)]))] 1399 UNSPEC_FNSTSW)) 1400 (set (reg:CC FLAGS_REG) 1401 (unspec:CC [(match_dup 0)] UNSPEC_SAHF))] 1402 "" 1403 [(set_attr "type" "multi") 1404 (set_attr "unit" "i387") 1405 (set_attr "fp_int_src" "true") 1406 (set_attr "mode" "<MODE>")]) 1407 1408;; FP compares, step 2 1409;; Move the fpsw to ax. 1410 1411(define_insn "x86_fnstsw_1" 1412 [(set (match_operand:HI 0 "register_operand" "=a") 1413 (unspec:HI [(reg:CCFP FPSR_REG)] UNSPEC_FNSTSW))] 1414 "TARGET_80387" 1415 "fnstsw\t%0" 1416 [(set (attr "length") 1417 (symbol_ref "ix86_attr_length_address_default (insn) + 2")) 1418 (set_attr "mode" "SI") 1419 (set_attr "unit" "i387")]) 1420 1421;; FP compares, step 3 1422;; Get ax into flags, general case. 1423 1424(define_insn "x86_sahf_1" 1425 [(set (reg:CC FLAGS_REG) 1426 (unspec:CC [(match_operand:HI 0 "register_operand" "a")] 1427 UNSPEC_SAHF))] 1428 "TARGET_SAHF" 1429{ 1430#ifndef HAVE_AS_IX86_SAHF 1431 if (TARGET_64BIT) 1432 return ASM_BYTE "0x9e"; 1433 else 1434#endif 1435 return "sahf"; 1436} 1437 [(set_attr "length" "1") 1438 (set_attr "athlon_decode" "vector") 1439 (set_attr "amdfam10_decode" "direct") 1440 (set_attr "bdver1_decode" "direct") 1441 (set_attr "mode" "SI")]) 1442 1443;; Pentium Pro can do steps 1 through 3 in one go. 1444;; comi*, ucomi*, fcomi*, ficomi*, fucomi* 1445;; (these i387 instructions set flags directly) 1446(define_insn "*cmpfp_i_mixed" 1447 [(set (reg:CCFP FLAGS_REG) 1448 (compare:CCFP (match_operand 0 "register_operand" "f,x") 1449 (match_operand 1 "nonimmediate_operand" "f,xm")))] 1450 "TARGET_MIX_SSE_I387 1451 && SSE_FLOAT_MODE_P (GET_MODE (operands[0])) 1452 && GET_MODE (operands[0]) == GET_MODE (operands[1])" 1453 "* return output_fp_compare (insn, operands, true, false);" 1454 [(set_attr "type" "fcmp,ssecomi") 1455 (set_attr "prefix" "orig,maybe_vex") 1456 (set (attr "mode") 1457 (if_then_else (match_operand:SF 1 "" "") 1458 (const_string "SF") 1459 (const_string "DF"))) 1460 (set (attr "prefix_rep") 1461 (if_then_else (eq_attr "type" "ssecomi") 1462 (const_string "0") 1463 (const_string "*"))) 1464 (set (attr "prefix_data16") 1465 (cond [(eq_attr "type" "fcmp") 1466 (const_string "*") 1467 (eq_attr "mode" "DF") 1468 (const_string "1") 1469 ] 1470 (const_string "0"))) 1471 (set_attr "athlon_decode" "vector") 1472 (set_attr "amdfam10_decode" "direct") 1473 (set_attr "bdver1_decode" "double")]) 1474 1475(define_insn "*cmpfp_i_sse" 1476 [(set (reg:CCFP FLAGS_REG) 1477 (compare:CCFP (match_operand 0 "register_operand" "x") 1478 (match_operand 1 "nonimmediate_operand" "xm")))] 1479 "TARGET_SSE_MATH 1480 && SSE_FLOAT_MODE_P (GET_MODE (operands[0])) 1481 && GET_MODE (operands[0]) == GET_MODE (operands[1])" 1482 "* return output_fp_compare (insn, operands, true, false);" 1483 [(set_attr "type" "ssecomi") 1484 (set_attr "prefix" "maybe_vex") 1485 (set (attr "mode") 1486 (if_then_else (match_operand:SF 1 "" "") 1487 (const_string "SF") 1488 (const_string "DF"))) 1489 (set_attr "prefix_rep" "0") 1490 (set (attr "prefix_data16") 1491 (if_then_else (eq_attr "mode" "DF") 1492 (const_string "1") 1493 (const_string "0"))) 1494 (set_attr "athlon_decode" "vector") 1495 (set_attr "amdfam10_decode" "direct") 1496 (set_attr "bdver1_decode" "double")]) 1497 1498(define_insn "*cmpfp_i_i387" 1499 [(set (reg:CCFP FLAGS_REG) 1500 (compare:CCFP (match_operand 0 "register_operand" "f") 1501 (match_operand 1 "register_operand" "f")))] 1502 "X87_FLOAT_MODE_P (GET_MODE (operands[0])) 1503 && TARGET_CMOVE 1504 && !(SSE_FLOAT_MODE_P (GET_MODE (operands[0])) && TARGET_SSE_MATH) 1505 && GET_MODE (operands[0]) == GET_MODE (operands[1])" 1506 "* return output_fp_compare (insn, operands, true, false);" 1507 [(set_attr "type" "fcmp") 1508 (set (attr "mode") 1509 (cond [(match_operand:SF 1 "" "") 1510 (const_string "SF") 1511 (match_operand:DF 1 "" "") 1512 (const_string "DF") 1513 ] 1514 (const_string "XF"))) 1515 (set_attr "athlon_decode" "vector") 1516 (set_attr "amdfam10_decode" "direct") 1517 (set_attr "bdver1_decode" "double")]) 1518 1519(define_insn "*cmpfp_iu_mixed" 1520 [(set (reg:CCFPU FLAGS_REG) 1521 (compare:CCFPU (match_operand 0 "register_operand" "f,x") 1522 (match_operand 1 "nonimmediate_operand" "f,xm")))] 1523 "TARGET_MIX_SSE_I387 1524 && SSE_FLOAT_MODE_P (GET_MODE (operands[0])) 1525 && GET_MODE (operands[0]) == GET_MODE (operands[1])" 1526 "* return output_fp_compare (insn, operands, true, true);" 1527 [(set_attr "type" "fcmp,ssecomi") 1528 (set_attr "prefix" "orig,maybe_vex") 1529 (set (attr "mode") 1530 (if_then_else (match_operand:SF 1 "" "") 1531 (const_string "SF") 1532 (const_string "DF"))) 1533 (set (attr "prefix_rep") 1534 (if_then_else (eq_attr "type" "ssecomi") 1535 (const_string "0") 1536 (const_string "*"))) 1537 (set (attr "prefix_data16") 1538 (cond [(eq_attr "type" "fcmp") 1539 (const_string "*") 1540 (eq_attr "mode" "DF") 1541 (const_string "1") 1542 ] 1543 (const_string "0"))) 1544 (set_attr "athlon_decode" "vector") 1545 (set_attr "amdfam10_decode" "direct") 1546 (set_attr "bdver1_decode" "double")]) 1547 1548(define_insn "*cmpfp_iu_sse" 1549 [(set (reg:CCFPU FLAGS_REG) 1550 (compare:CCFPU (match_operand 0 "register_operand" "x") 1551 (match_operand 1 "nonimmediate_operand" "xm")))] 1552 "TARGET_SSE_MATH 1553 && SSE_FLOAT_MODE_P (GET_MODE (operands[0])) 1554 && GET_MODE (operands[0]) == GET_MODE (operands[1])" 1555 "* return output_fp_compare (insn, operands, true, true);" 1556 [(set_attr "type" "ssecomi") 1557 (set_attr "prefix" "maybe_vex") 1558 (set (attr "mode") 1559 (if_then_else (match_operand:SF 1 "" "") 1560 (const_string "SF") 1561 (const_string "DF"))) 1562 (set_attr "prefix_rep" "0") 1563 (set (attr "prefix_data16") 1564 (if_then_else (eq_attr "mode" "DF") 1565 (const_string "1") 1566 (const_string "0"))) 1567 (set_attr "athlon_decode" "vector") 1568 (set_attr "amdfam10_decode" "direct") 1569 (set_attr "bdver1_decode" "double")]) 1570 1571(define_insn "*cmpfp_iu_387" 1572 [(set (reg:CCFPU FLAGS_REG) 1573 (compare:CCFPU (match_operand 0 "register_operand" "f") 1574 (match_operand 1 "register_operand" "f")))] 1575 "X87_FLOAT_MODE_P (GET_MODE (operands[0])) 1576 && TARGET_CMOVE 1577 && !(SSE_FLOAT_MODE_P (GET_MODE (operands[0])) && TARGET_SSE_MATH) 1578 && GET_MODE (operands[0]) == GET_MODE (operands[1])" 1579 "* return output_fp_compare (insn, operands, true, true);" 1580 [(set_attr "type" "fcmp") 1581 (set (attr "mode") 1582 (cond [(match_operand:SF 1 "" "") 1583 (const_string "SF") 1584 (match_operand:DF 1 "" "") 1585 (const_string "DF") 1586 ] 1587 (const_string "XF"))) 1588 (set_attr "athlon_decode" "vector") 1589 (set_attr "amdfam10_decode" "direct") 1590 (set_attr "bdver1_decode" "direct")]) 1591 1592;; Push/pop instructions. 1593 1594(define_insn "*push<mode>2" 1595 [(set (match_operand:DWI 0 "push_operand" "=<") 1596 (match_operand:DWI 1 "general_no_elim_operand" "riF*o"))] 1597 "" 1598 "#" 1599 [(set_attr "type" "multi") 1600 (set_attr "mode" "<MODE>")]) 1601 1602(define_split 1603 [(set (match_operand:TI 0 "push_operand" "") 1604 (match_operand:TI 1 "general_operand" ""))] 1605 "TARGET_64BIT && reload_completed 1606 && !SSE_REG_P (operands[1])" 1607 [(const_int 0)] 1608 "ix86_split_long_move (operands); DONE;") 1609 1610(define_insn "*pushdi2_rex64" 1611 [(set (match_operand:DI 0 "push_operand" "=<,!<") 1612 (match_operand:DI 1 "general_no_elim_operand" "re*m,n"))] 1613 "TARGET_64BIT" 1614 "@ 1615 push{q}\t%1 1616 #" 1617 [(set_attr "type" "push,multi") 1618 (set_attr "mode" "DI")]) 1619 1620;; Convert impossible pushes of immediate to existing instructions. 1621;; First try to get scratch register and go through it. In case this 1622;; fails, push sign extended lower part first and then overwrite 1623;; upper part by 32bit move. 1624(define_peephole2 1625 [(match_scratch:DI 2 "r") 1626 (set (match_operand:DI 0 "push_operand" "") 1627 (match_operand:DI 1 "immediate_operand" ""))] 1628 "TARGET_64BIT && !symbolic_operand (operands[1], DImode) 1629 && !x86_64_immediate_operand (operands[1], DImode)" 1630 [(set (match_dup 2) (match_dup 1)) 1631 (set (match_dup 0) (match_dup 2))]) 1632 1633;; We need to define this as both peepholer and splitter for case 1634;; peephole2 pass is not run. 1635;; "&& 1" is needed to keep it from matching the previous pattern. 1636(define_peephole2 1637 [(set (match_operand:DI 0 "push_operand" "") 1638 (match_operand:DI 1 "immediate_operand" ""))] 1639 "TARGET_64BIT && !symbolic_operand (operands[1], DImode) 1640 && !x86_64_immediate_operand (operands[1], DImode) && 1" 1641 [(set (match_dup 0) (match_dup 1)) 1642 (set (match_dup 2) (match_dup 3))] 1643{ 1644 split_double_mode (DImode, &operands[1], 1, &operands[2], &operands[3]); 1645 1646 operands[1] = gen_lowpart (DImode, operands[2]); 1647 operands[2] = gen_rtx_MEM (SImode, gen_rtx_PLUS (DImode, stack_pointer_rtx, 1648 GEN_INT (4))); 1649}) 1650 1651(define_split 1652 [(set (match_operand:DI 0 "push_operand" "") 1653 (match_operand:DI 1 "immediate_operand" ""))] 1654 "TARGET_64BIT && ((optimize > 0 && flag_peephole2) 1655 ? epilogue_completed : reload_completed) 1656 && !symbolic_operand (operands[1], DImode) 1657 && !x86_64_immediate_operand (operands[1], DImode)" 1658 [(set (match_dup 0) (match_dup 1)) 1659 (set (match_dup 2) (match_dup 3))] 1660{ 1661 split_double_mode (DImode, &operands[1], 1, &operands[2], &operands[3]); 1662 1663 operands[1] = gen_lowpart (DImode, operands[2]); 1664 operands[2] = gen_rtx_MEM (SImode, gen_rtx_PLUS (DImode, stack_pointer_rtx, 1665 GEN_INT (4))); 1666}) 1667 1668(define_split 1669 [(set (match_operand:DI 0 "push_operand" "") 1670 (match_operand:DI 1 "general_operand" ""))] 1671 "!TARGET_64BIT && reload_completed 1672 && !(MMX_REG_P (operands[1]) || SSE_REG_P (operands[1]))" 1673 [(const_int 0)] 1674 "ix86_split_long_move (operands); DONE;") 1675 1676(define_insn "*pushsi2" 1677 [(set (match_operand:SI 0 "push_operand" "=<") 1678 (match_operand:SI 1 "general_no_elim_operand" "ri*m"))] 1679 "!TARGET_64BIT" 1680 "push{l}\t%1" 1681 [(set_attr "type" "push") 1682 (set_attr "mode" "SI")]) 1683 1684;; emit_push_insn when it calls move_by_pieces requires an insn to 1685;; "push a byte/word". But actually we use pushl, which has the effect 1686;; of rounding the amount pushed up to a word. 1687 1688;; For TARGET_64BIT we always round up to 8 bytes. 1689(define_insn "*push<mode>2_rex64" 1690 [(set (match_operand:SWI124 0 "push_operand" "=X") 1691 (match_operand:SWI124 1 "nonmemory_no_elim_operand" "r<i>"))] 1692 "TARGET_64BIT" 1693 "push{q}\t%q1" 1694 [(set_attr "type" "push") 1695 (set_attr "mode" "DI")]) 1696 1697(define_insn "*push<mode>2" 1698 [(set (match_operand:SWI12 0 "push_operand" "=X") 1699 (match_operand:SWI12 1 "nonmemory_no_elim_operand" "rn"))] 1700 "!TARGET_64BIT" 1701 "push{l}\t%k1" 1702 [(set_attr "type" "push") 1703 (set_attr "mode" "SI")]) 1704 1705(define_insn "*push<mode>2_prologue" 1706 [(set (match_operand:P 0 "push_operand" "=<") 1707 (match_operand:P 1 "general_no_elim_operand" "r<i>*m")) 1708 (clobber (mem:BLK (scratch)))] 1709 "" 1710 "push{<imodesuffix>}\t%1" 1711 [(set_attr "type" "push") 1712 (set_attr "mode" "<MODE>")]) 1713 1714(define_insn "*pop<mode>1" 1715 [(set (match_operand:P 0 "nonimmediate_operand" "=r*m") 1716 (match_operand:P 1 "pop_operand" ">"))] 1717 "" 1718 "pop{<imodesuffix>}\t%0" 1719 [(set_attr "type" "pop") 1720 (set_attr "mode" "<MODE>")]) 1721 1722(define_insn "*pop<mode>1_epilogue" 1723 [(set (match_operand:P 0 "nonimmediate_operand" "=r*m") 1724 (match_operand:P 1 "pop_operand" ">")) 1725 (clobber (mem:BLK (scratch)))] 1726 "" 1727 "pop{<imodesuffix>}\t%0" 1728 [(set_attr "type" "pop") 1729 (set_attr "mode" "<MODE>")]) 1730 1731;; Move instructions. 1732 1733(define_expand "movoi" 1734 [(set (match_operand:OI 0 "nonimmediate_operand" "") 1735 (match_operand:OI 1 "general_operand" ""))] 1736 "TARGET_AVX" 1737 "ix86_expand_move (OImode, operands); DONE;") 1738 1739(define_expand "movti" 1740 [(set (match_operand:TI 0 "nonimmediate_operand" "") 1741 (match_operand:TI 1 "nonimmediate_operand" ""))] 1742 "TARGET_64BIT || TARGET_SSE" 1743{ 1744 if (TARGET_64BIT) 1745 ix86_expand_move (TImode, operands); 1746 else if (push_operand (operands[0], TImode)) 1747 ix86_expand_push (TImode, operands[1]); 1748 else 1749 ix86_expand_vector_move (TImode, operands); 1750 DONE; 1751}) 1752 1753;; This expands to what emit_move_complex would generate if we didn't 1754;; have a movti pattern. Having this avoids problems with reload on 1755;; 32-bit targets when SSE is present, but doesn't seem to be harmful 1756;; to have around all the time. 1757(define_expand "movcdi" 1758 [(set (match_operand:CDI 0 "nonimmediate_operand" "") 1759 (match_operand:CDI 1 "general_operand" ""))] 1760 "" 1761{ 1762 if (push_operand (operands[0], CDImode)) 1763 emit_move_complex_push (CDImode, operands[0], operands[1]); 1764 else 1765 emit_move_complex_parts (operands[0], operands[1]); 1766 DONE; 1767}) 1768 1769(define_expand "mov<mode>" 1770 [(set (match_operand:SWI1248x 0 "nonimmediate_operand" "") 1771 (match_operand:SWI1248x 1 "general_operand" ""))] 1772 "" 1773 "ix86_expand_move (<MODE>mode, operands); DONE;") 1774 1775(define_insn "*mov<mode>_xor" 1776 [(set (match_operand:SWI48 0 "register_operand" "=r") 1777 (match_operand:SWI48 1 "const0_operand" "")) 1778 (clobber (reg:CC FLAGS_REG))] 1779 "reload_completed" 1780 "xor{l}\t%k0, %k0" 1781 [(set_attr "type" "alu1") 1782 (set_attr "mode" "SI") 1783 (set_attr "length_immediate" "0")]) 1784 1785(define_insn "*mov<mode>_or" 1786 [(set (match_operand:SWI48 0 "register_operand" "=r") 1787 (match_operand:SWI48 1 "const_int_operand" "")) 1788 (clobber (reg:CC FLAGS_REG))] 1789 "reload_completed 1790 && operands[1] == constm1_rtx" 1791 "or{<imodesuffix>}\t{%1, %0|%0, %1}" 1792 [(set_attr "type" "alu1") 1793 (set_attr "mode" "<MODE>") 1794 (set_attr "length_immediate" "1")]) 1795 1796(define_insn "*movoi_internal_avx" 1797 [(set (match_operand:OI 0 "nonimmediate_operand" "=x,x,m") 1798 (match_operand:OI 1 "vector_move_operand" "C,xm,x"))] 1799 "TARGET_AVX && !(MEM_P (operands[0]) && MEM_P (operands[1]))" 1800{ 1801 switch (which_alternative) 1802 { 1803 case 0: 1804 return standard_sse_constant_opcode (insn, operands[1]); 1805 case 1: 1806 case 2: 1807 if (misaligned_operand (operands[0], OImode) 1808 || misaligned_operand (operands[1], OImode)) 1809 return "vmovdqu\t{%1, %0|%0, %1}"; 1810 else 1811 return "vmovdqa\t{%1, %0|%0, %1}"; 1812 default: 1813 gcc_unreachable (); 1814 } 1815} 1816 [(set_attr "type" "sselog1,ssemov,ssemov") 1817 (set_attr "prefix" "vex") 1818 (set_attr "mode" "OI")]) 1819 1820(define_insn "*movti_internal_rex64" 1821 [(set (match_operand:TI 0 "nonimmediate_operand" "=!r,o,x,x,m") 1822 (match_operand:TI 1 "general_operand" "riFo,re,C,xm,x"))] 1823 "TARGET_64BIT && !(MEM_P (operands[0]) && MEM_P (operands[1]))" 1824{ 1825 switch (which_alternative) 1826 { 1827 case 0: 1828 case 1: 1829 return "#"; 1830 case 2: 1831 return standard_sse_constant_opcode (insn, operands[1]); 1832 case 3: 1833 case 4: 1834 /* TDmode values are passed as TImode on the stack. Moving them 1835 to stack may result in unaligned memory access. */ 1836 if (misaligned_operand (operands[0], TImode) 1837 || misaligned_operand (operands[1], TImode)) 1838 { 1839 if (get_attr_mode (insn) == MODE_V4SF) 1840 return "%vmovups\t{%1, %0|%0, %1}"; 1841 else 1842 return "%vmovdqu\t{%1, %0|%0, %1}"; 1843 } 1844 else 1845 { 1846 if (get_attr_mode (insn) == MODE_V4SF) 1847 return "%vmovaps\t{%1, %0|%0, %1}"; 1848 else 1849 return "%vmovdqa\t{%1, %0|%0, %1}"; 1850 } 1851 default: 1852 gcc_unreachable (); 1853 } 1854} 1855 [(set_attr "type" "*,*,sselog1,ssemov,ssemov") 1856 (set_attr "prefix" "*,*,maybe_vex,maybe_vex,maybe_vex") 1857 (set (attr "mode") 1858 (cond [(eq_attr "alternative" "2,3") 1859 (if_then_else 1860 (match_test "optimize_function_for_size_p (cfun)") 1861 (const_string "V4SF") 1862 (const_string "TI")) 1863 (eq_attr "alternative" "4") 1864 (if_then_else 1865 (ior (match_test "TARGET_SSE_TYPELESS_STORES") 1866 (match_test "optimize_function_for_size_p (cfun)")) 1867 (const_string "V4SF") 1868 (const_string "TI"))] 1869 (const_string "DI")))]) 1870 1871(define_split 1872 [(set (match_operand:TI 0 "nonimmediate_operand" "") 1873 (match_operand:TI 1 "general_operand" ""))] 1874 "reload_completed 1875 && !SSE_REG_P (operands[0]) && !SSE_REG_P (operands[1])" 1876 [(const_int 0)] 1877 "ix86_split_long_move (operands); DONE;") 1878 1879(define_insn "*movti_internal_sse" 1880 [(set (match_operand:TI 0 "nonimmediate_operand" "=x,x,m") 1881 (match_operand:TI 1 "vector_move_operand" "C,xm,x"))] 1882 "TARGET_SSE && !TARGET_64BIT 1883 && !(MEM_P (operands[0]) && MEM_P (operands[1]))" 1884{ 1885 switch (which_alternative) 1886 { 1887 case 0: 1888 return standard_sse_constant_opcode (insn, operands[1]); 1889 case 1: 1890 case 2: 1891 /* TDmode values are passed as TImode on the stack. Moving them 1892 to stack may result in unaligned memory access. */ 1893 if (misaligned_operand (operands[0], TImode) 1894 || misaligned_operand (operands[1], TImode)) 1895 { 1896 if (get_attr_mode (insn) == MODE_V4SF) 1897 return "%vmovups\t{%1, %0|%0, %1}"; 1898 else 1899 return "%vmovdqu\t{%1, %0|%0, %1}"; 1900 } 1901 else 1902 { 1903 if (get_attr_mode (insn) == MODE_V4SF) 1904 return "%vmovaps\t{%1, %0|%0, %1}"; 1905 else 1906 return "%vmovdqa\t{%1, %0|%0, %1}"; 1907 } 1908 default: 1909 gcc_unreachable (); 1910 } 1911} 1912 [(set_attr "type" "sselog1,ssemov,ssemov") 1913 (set_attr "prefix" "maybe_vex") 1914 (set (attr "mode") 1915 (cond [(ior (not (match_test "TARGET_SSE2")) 1916 (match_test "optimize_function_for_size_p (cfun)")) 1917 (const_string "V4SF") 1918 (and (eq_attr "alternative" "2") 1919 (match_test "TARGET_SSE_TYPELESS_STORES")) 1920 (const_string "V4SF")] 1921 (const_string "TI")))]) 1922 1923(define_insn "*movdi_internal_rex64" 1924 [(set (match_operand:DI 0 "nonimmediate_operand" 1925 "=r,r ,r,m ,*y,m*y,?*y,?r ,?*Ym,*x,m ,*x,*x,?r ,?*Yi,?*x,?*Ym") 1926 (match_operand:DI 1 "general_operand" 1927 "Z ,rem,i,re,C ,*y ,m ,*Ym,r ,C ,*x,*x,m ,*Yi,r ,*Ym,*x"))] 1928 "TARGET_64BIT && !(MEM_P (operands[0]) && MEM_P (operands[1]))" 1929{ 1930 switch (get_attr_type (insn)) 1931 { 1932 case TYPE_SSECVT: 1933 if (SSE_REG_P (operands[0])) 1934 return "movq2dq\t{%1, %0|%0, %1}"; 1935 else 1936 return "movdq2q\t{%1, %0|%0, %1}"; 1937 1938 case TYPE_SSEMOV: 1939 if (get_attr_mode (insn) == MODE_TI) 1940 return "%vmovdqa\t{%1, %0|%0, %1}"; 1941 /* Handle broken assemblers that require movd instead of movq. */ 1942 if (GENERAL_REG_P (operands[0]) || GENERAL_REG_P (operands[1])) 1943 return "%vmovd\t{%1, %0|%0, %1}"; 1944 else 1945 return "%vmovq\t{%1, %0|%0, %1}"; 1946 1947 case TYPE_MMXMOV: 1948 /* Handle broken assemblers that require movd instead of movq. */ 1949 if (GENERAL_REG_P (operands[0]) || GENERAL_REG_P (operands[1])) 1950 return "movd\t{%1, %0|%0, %1}"; 1951 else 1952 return "movq\t{%1, %0|%0, %1}"; 1953 1954 case TYPE_SSELOG1: 1955 return standard_sse_constant_opcode (insn, operands[1]); 1956 1957 case TYPE_MMX: 1958 return "pxor\t%0, %0"; 1959 1960 case TYPE_LEA: 1961 return "lea{q}\t{%E1, %0|%0, %E1}"; 1962 1963 default: 1964 gcc_assert (!flag_pic || LEGITIMATE_PIC_OPERAND_P (operands[1])); 1965 if (get_attr_mode (insn) == MODE_SI) 1966 return "mov{l}\t{%k1, %k0|%k0, %k1}"; 1967 else if (which_alternative == 2) 1968 return "movabs{q}\t{%1, %0|%0, %1}"; 1969 else if (ix86_use_lea_for_mov (insn, operands)) 1970 return "lea{q}\t{%E1, %0|%0, %E1}"; 1971 else 1972 return "mov{q}\t{%1, %0|%0, %1}"; 1973 } 1974} 1975 [(set (attr "type") 1976 (cond [(eq_attr "alternative" "4") 1977 (const_string "mmx") 1978 (eq_attr "alternative" "5,6,7,8") 1979 (const_string "mmxmov") 1980 (eq_attr "alternative" "9") 1981 (const_string "sselog1") 1982 (eq_attr "alternative" "10,11,12,13,14") 1983 (const_string "ssemov") 1984 (eq_attr "alternative" "15,16") 1985 (const_string "ssecvt") 1986 (match_operand 1 "pic_32bit_operand" "") 1987 (const_string "lea") 1988 ] 1989 (const_string "imov"))) 1990 (set (attr "modrm") 1991 (if_then_else 1992 (and (eq_attr "alternative" "2") (eq_attr "type" "imov")) 1993 (const_string "0") 1994 (const_string "*"))) 1995 (set (attr "length_immediate") 1996 (if_then_else 1997 (and (eq_attr "alternative" "2") (eq_attr "type" "imov")) 1998 (const_string "8") 1999 (const_string "*"))) 2000 (set (attr "prefix_rex") 2001 (if_then_else (eq_attr "alternative" "7,8") 2002 (const_string "1") 2003 (const_string "*"))) 2004 (set (attr "prefix_data16") 2005 (if_then_else (eq_attr "alternative" "10") 2006 (const_string "1") 2007 (const_string "*"))) 2008 (set (attr "prefix") 2009 (if_then_else (eq_attr "alternative" "11,12,13,14,15") 2010 (const_string "maybe_vex") 2011 (const_string "orig"))) 2012 (set_attr "mode" "SI,DI,DI,DI,DI,DI,DI,DI,DI,TI,DI,TI,DI,DI,DI,DI,DI")]) 2013 2014;; Reload patterns to support multi-word load/store 2015;; with non-offsetable address. 2016(define_expand "reload_noff_store" 2017 [(parallel [(match_operand 0 "memory_operand" "=m") 2018 (match_operand 1 "register_operand" "r") 2019 (match_operand:DI 2 "register_operand" "=&r")])] 2020 "TARGET_64BIT" 2021{ 2022 rtx mem = operands[0]; 2023 rtx addr = XEXP (mem, 0); 2024 2025 emit_move_insn (operands[2], addr); 2026 mem = replace_equiv_address_nv (mem, operands[2]); 2027 2028 emit_insn (gen_rtx_SET (VOIDmode, mem, operands[1])); 2029 DONE; 2030}) 2031 2032(define_expand "reload_noff_load" 2033 [(parallel [(match_operand 0 "register_operand" "=r") 2034 (match_operand 1 "memory_operand" "m") 2035 (match_operand:DI 2 "register_operand" "=r")])] 2036 "TARGET_64BIT" 2037{ 2038 rtx mem = operands[1]; 2039 rtx addr = XEXP (mem, 0); 2040 2041 emit_move_insn (operands[2], addr); 2042 mem = replace_equiv_address_nv (mem, operands[2]); 2043 2044 emit_insn (gen_rtx_SET (VOIDmode, operands[0], mem)); 2045 DONE; 2046}) 2047 2048(define_insn "*movdi_internal" 2049 [(set (match_operand:DI 0 "nonimmediate_operand" 2050 "=r ,o ,*y,m*y,*y,*x,m ,*x,*x,*x,m ,*x,*x,?*x,?*Ym") 2051 (match_operand:DI 1 "general_operand" 2052 "riFo,riF,C ,*y ,m ,C ,*x,*x,m ,C ,*x,*x,m ,*Ym,*x"))] 2053 "!TARGET_64BIT && !(MEM_P (operands[0]) && MEM_P (operands[1]))" 2054{ 2055 switch (get_attr_type (insn)) 2056 { 2057 case TYPE_SSECVT: 2058 if (SSE_REG_P (operands[0])) 2059 return "movq2dq\t{%1, %0|%0, %1}"; 2060 else 2061 return "movdq2q\t{%1, %0|%0, %1}"; 2062 2063 case TYPE_SSEMOV: 2064 switch (get_attr_mode (insn)) 2065 { 2066 case MODE_TI: 2067 return "%vmovdqa\t{%1, %0|%0, %1}"; 2068 case MODE_DI: 2069 return "%vmovq\t{%1, %0|%0, %1}"; 2070 case MODE_V4SF: 2071 return "movaps\t{%1, %0|%0, %1}"; 2072 case MODE_V2SF: 2073 return "movlps\t{%1, %0|%0, %1}"; 2074 default: 2075 gcc_unreachable (); 2076 } 2077 2078 case TYPE_MMXMOV: 2079 return "movq\t{%1, %0|%0, %1}"; 2080 2081 case TYPE_SSELOG1: 2082 return standard_sse_constant_opcode (insn, operands[1]); 2083 2084 case TYPE_MMX: 2085 return "pxor\t%0, %0"; 2086 2087 case TYPE_MULTI: 2088 return "#"; 2089 2090 default: 2091 gcc_unreachable (); 2092 } 2093} 2094 [(set (attr "isa") 2095 (cond [(eq_attr "alternative" "5,6,7,8,13,14") 2096 (const_string "sse2") 2097 (eq_attr "alternative" "9,10,11,12") 2098 (const_string "noavx") 2099 ] 2100 (const_string "*"))) 2101 (set (attr "type") 2102 (cond [(eq_attr "alternative" "0,1") 2103 (const_string "multi") 2104 (eq_attr "alternative" "2") 2105 (const_string "mmx") 2106 (eq_attr "alternative" "3,4") 2107 (const_string "mmxmov") 2108 (eq_attr "alternative" "5,9") 2109 (const_string "sselog1") 2110 (eq_attr "alternative" "13,14") 2111 (const_string "ssecvt") 2112 ] 2113 (const_string "ssemov"))) 2114 (set (attr "prefix") 2115 (if_then_else (eq_attr "alternative" "5,6,7,8") 2116 (const_string "maybe_vex") 2117 (const_string "orig"))) 2118 (set_attr "mode" "DI,DI,DI,DI,DI,TI,DI,TI,DI,V4SF,V2SF,V4SF,V2SF,DI,DI")]) 2119 2120(define_split 2121 [(set (match_operand:DI 0 "nonimmediate_operand" "") 2122 (match_operand:DI 1 "general_operand" ""))] 2123 "!TARGET_64BIT && reload_completed 2124 && !(MMX_REG_P (operands[0]) || SSE_REG_P (operands[0])) 2125 && !(MMX_REG_P (operands[1]) || SSE_REG_P (operands[1]))" 2126 [(const_int 0)] 2127 "ix86_split_long_move (operands); DONE;") 2128 2129(define_insn "*movsi_internal" 2130 [(set (match_operand:SI 0 "nonimmediate_operand" 2131 "=r,m ,*y,*y,?rm,?*y,*x,*x,?r ,m ,?*Yi,*x") 2132 (match_operand:SI 1 "general_operand" 2133 "g ,re,C ,*y,*y ,rm ,C ,*x,*Yi,*x,r ,m "))] 2134 "!(MEM_P (operands[0]) && MEM_P (operands[1]))" 2135{ 2136 switch (get_attr_type (insn)) 2137 { 2138 case TYPE_SSELOG1: 2139 return standard_sse_constant_opcode (insn, operands[1]); 2140 2141 case TYPE_SSEMOV: 2142 switch (get_attr_mode (insn)) 2143 { 2144 case MODE_TI: 2145 return "%vmovdqa\t{%1, %0|%0, %1}"; 2146 case MODE_V4SF: 2147 return "%vmovaps\t{%1, %0|%0, %1}"; 2148 case MODE_SI: 2149 return "%vmovd\t{%1, %0|%0, %1}"; 2150 case MODE_SF: 2151 return "%vmovss\t{%1, %0|%0, %1}"; 2152 default: 2153 gcc_unreachable (); 2154 } 2155 2156 case TYPE_MMX: 2157 return "pxor\t%0, %0"; 2158 2159 case TYPE_MMXMOV: 2160 if (get_attr_mode (insn) == MODE_DI) 2161 return "movq\t{%1, %0|%0, %1}"; 2162 return "movd\t{%1, %0|%0, %1}"; 2163 2164 case TYPE_LEA: 2165 return "lea{l}\t{%E1, %0|%0, %E1}"; 2166 2167 default: 2168 gcc_assert (!flag_pic || LEGITIMATE_PIC_OPERAND_P (operands[1])); 2169 if (ix86_use_lea_for_mov (insn, operands)) 2170 return "lea{l}\t{%E1, %0|%0, %E1}"; 2171 else 2172 return "mov{l}\t{%1, %0|%0, %1}"; 2173 } 2174} 2175 [(set (attr "type") 2176 (cond [(eq_attr "alternative" "2") 2177 (const_string "mmx") 2178 (eq_attr "alternative" "3,4,5") 2179 (const_string "mmxmov") 2180 (eq_attr "alternative" "6") 2181 (const_string "sselog1") 2182 (eq_attr "alternative" "7,8,9,10,11") 2183 (const_string "ssemov") 2184 (match_operand 1 "pic_32bit_operand" "") 2185 (const_string "lea") 2186 ] 2187 (const_string "imov"))) 2188 (set (attr "prefix") 2189 (if_then_else (eq_attr "alternative" "0,1,2,3,4,5") 2190 (const_string "orig") 2191 (const_string "maybe_vex"))) 2192 (set (attr "prefix_data16") 2193 (if_then_else (and (eq_attr "type" "ssemov") (eq_attr "mode" "SI")) 2194 (const_string "1") 2195 (const_string "*"))) 2196 (set (attr "mode") 2197 (cond [(eq_attr "alternative" "2,3") 2198 (const_string "DI") 2199 (eq_attr "alternative" "6,7") 2200 (if_then_else 2201 (not (match_test "TARGET_SSE2")) 2202 (const_string "V4SF") 2203 (const_string "TI")) 2204 (and (eq_attr "alternative" "8,9,10,11") 2205 (not (match_test "TARGET_SSE2"))) 2206 (const_string "SF") 2207 ] 2208 (const_string "SI")))]) 2209 2210(define_insn "*movhi_internal" 2211 [(set (match_operand:HI 0 "nonimmediate_operand" "=r,r,r,m") 2212 (match_operand:HI 1 "general_operand" "r,rn,rm,rn"))] 2213 "!(MEM_P (operands[0]) && MEM_P (operands[1]))" 2214{ 2215 switch (get_attr_type (insn)) 2216 { 2217 case TYPE_IMOVX: 2218 /* movzwl is faster than movw on p2 due to partial word stalls, 2219 though not as fast as an aligned movl. */ 2220 return "movz{wl|x}\t{%1, %k0|%k0, %1}"; 2221 default: 2222 if (get_attr_mode (insn) == MODE_SI) 2223 return "mov{l}\t{%k1, %k0|%k0, %k1}"; 2224 else 2225 return "mov{w}\t{%1, %0|%0, %1}"; 2226 } 2227} 2228 [(set (attr "type") 2229 (cond [(match_test "optimize_function_for_size_p (cfun)") 2230 (const_string "imov") 2231 (and (eq_attr "alternative" "0") 2232 (ior (not (match_test "TARGET_PARTIAL_REG_STALL")) 2233 (not (match_test "TARGET_HIMODE_MATH")))) 2234 (const_string "imov") 2235 (and (eq_attr "alternative" "1,2") 2236 (match_operand:HI 1 "aligned_operand" "")) 2237 (const_string "imov") 2238 (and (match_test "TARGET_MOVX") 2239 (eq_attr "alternative" "0,2")) 2240 (const_string "imovx") 2241 ] 2242 (const_string "imov"))) 2243 (set (attr "mode") 2244 (cond [(eq_attr "type" "imovx") 2245 (const_string "SI") 2246 (and (eq_attr "alternative" "1,2") 2247 (match_operand:HI 1 "aligned_operand" "")) 2248 (const_string "SI") 2249 (and (eq_attr "alternative" "0") 2250 (ior (not (match_test "TARGET_PARTIAL_REG_STALL")) 2251 (not (match_test "TARGET_HIMODE_MATH")))) 2252 (const_string "SI") 2253 ] 2254 (const_string "HI")))]) 2255 2256;; Situation is quite tricky about when to choose full sized (SImode) move 2257;; over QImode moves. For Q_REG -> Q_REG move we use full size only for 2258;; partial register dependency machines (such as AMD Athlon), where QImode 2259;; moves issue extra dependency and for partial register stalls machines 2260;; that don't use QImode patterns (and QImode move cause stall on the next 2261;; instruction). 2262;; 2263;; For loads of Q_REG to NONQ_REG we use full sized moves except for partial 2264;; register stall machines with, where we use QImode instructions, since 2265;; partial register stall can be caused there. Then we use movzx. 2266(define_insn "*movqi_internal" 2267 [(set (match_operand:QI 0 "nonimmediate_operand" "=q,q ,q ,r,r ,?r,m") 2268 (match_operand:QI 1 "general_operand" " q,qn,qm,q,rn,qm,qn"))] 2269 "!(MEM_P (operands[0]) && MEM_P (operands[1]))" 2270{ 2271 switch (get_attr_type (insn)) 2272 { 2273 case TYPE_IMOVX: 2274 gcc_assert (ANY_QI_REG_P (operands[1]) || MEM_P (operands[1])); 2275 return "movz{bl|x}\t{%1, %k0|%k0, %1}"; 2276 default: 2277 if (get_attr_mode (insn) == MODE_SI) 2278 return "mov{l}\t{%k1, %k0|%k0, %k1}"; 2279 else 2280 return "mov{b}\t{%1, %0|%0, %1}"; 2281 } 2282} 2283 [(set (attr "type") 2284 (cond [(and (eq_attr "alternative" "5") 2285 (not (match_operand:QI 1 "aligned_operand" ""))) 2286 (const_string "imovx") 2287 (match_test "optimize_function_for_size_p (cfun)") 2288 (const_string "imov") 2289 (and (eq_attr "alternative" "3") 2290 (ior (not (match_test "TARGET_PARTIAL_REG_STALL")) 2291 (not (match_test "TARGET_QIMODE_MATH")))) 2292 (const_string "imov") 2293 (eq_attr "alternative" "3,5") 2294 (const_string "imovx") 2295 (and (match_test "TARGET_MOVX") 2296 (eq_attr "alternative" "2")) 2297 (const_string "imovx") 2298 ] 2299 (const_string "imov"))) 2300 (set (attr "mode") 2301 (cond [(eq_attr "alternative" "3,4,5") 2302 (const_string "SI") 2303 (eq_attr "alternative" "6") 2304 (const_string "QI") 2305 (eq_attr "type" "imovx") 2306 (const_string "SI") 2307 (and (eq_attr "type" "imov") 2308 (and (eq_attr "alternative" "0,1") 2309 (and (match_test "TARGET_PARTIAL_REG_DEPENDENCY") 2310 (and (not (match_test "optimize_function_for_size_p (cfun)")) 2311 (not (match_test "TARGET_PARTIAL_REG_STALL")))))) 2312 (const_string "SI") 2313 ;; Avoid partial register stalls when not using QImode arithmetic 2314 (and (eq_attr "type" "imov") 2315 (and (eq_attr "alternative" "0,1") 2316 (and (match_test "TARGET_PARTIAL_REG_STALL") 2317 (not (match_test "TARGET_QIMODE_MATH"))))) 2318 (const_string "SI") 2319 ] 2320 (const_string "QI")))]) 2321 2322;; Stores and loads of ax to arbitrary constant address. 2323;; We fake an second form of instruction to force reload to load address 2324;; into register when rax is not available 2325(define_insn "*movabs<mode>_1" 2326 [(set (mem:SWI1248x (match_operand:DI 0 "x86_64_movabs_operand" "i,r")) 2327 (match_operand:SWI1248x 1 "nonmemory_operand" "a,r<i>"))] 2328 "TARGET_LP64 && ix86_check_movabs (insn, 0)" 2329 "@ 2330 movabs{<imodesuffix>}\t{%1, %P0|[%P0], %1} 2331 mov{<imodesuffix>}\t{%1, %a0|%a0, %1}" 2332 [(set_attr "type" "imov") 2333 (set_attr "modrm" "0,*") 2334 (set_attr "length_address" "8,0") 2335 (set_attr "length_immediate" "0,*") 2336 (set_attr "memory" "store") 2337 (set_attr "mode" "<MODE>")]) 2338 2339(define_insn "*movabs<mode>_2" 2340 [(set (match_operand:SWI1248x 0 "register_operand" "=a,r") 2341 (mem:SWI1248x (match_operand:DI 1 "x86_64_movabs_operand" "i,r")))] 2342 "TARGET_LP64 && ix86_check_movabs (insn, 1)" 2343 "@ 2344 movabs{<imodesuffix>}\t{%P1, %0|%0, [%P1]} 2345 mov{<imodesuffix>}\t{%a1, %0|%0, %a1}" 2346 [(set_attr "type" "imov") 2347 (set_attr "modrm" "0,*") 2348 (set_attr "length_address" "8,0") 2349 (set_attr "length_immediate" "0") 2350 (set_attr "memory" "load") 2351 (set_attr "mode" "<MODE>")]) 2352 2353(define_insn "*swap<mode>" 2354 [(set (match_operand:SWI48 0 "register_operand" "+r") 2355 (match_operand:SWI48 1 "register_operand" "+r")) 2356 (set (match_dup 1) 2357 (match_dup 0))] 2358 "" 2359 "xchg{<imodesuffix>}\t%1, %0" 2360 [(set_attr "type" "imov") 2361 (set_attr "mode" "<MODE>") 2362 (set_attr "pent_pair" "np") 2363 (set_attr "athlon_decode" "vector") 2364 (set_attr "amdfam10_decode" "double") 2365 (set_attr "bdver1_decode" "double")]) 2366 2367(define_insn "*swap<mode>_1" 2368 [(set (match_operand:SWI12 0 "register_operand" "+r") 2369 (match_operand:SWI12 1 "register_operand" "+r")) 2370 (set (match_dup 1) 2371 (match_dup 0))] 2372 "!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun)" 2373 "xchg{l}\t%k1, %k0" 2374 [(set_attr "type" "imov") 2375 (set_attr "mode" "SI") 2376 (set_attr "pent_pair" "np") 2377 (set_attr "athlon_decode" "vector") 2378 (set_attr "amdfam10_decode" "double") 2379 (set_attr "bdver1_decode" "double")]) 2380 2381;; Not added amdfam10_decode since TARGET_PARTIAL_REG_STALL 2382;; is disabled for AMDFAM10 2383(define_insn "*swap<mode>_2" 2384 [(set (match_operand:SWI12 0 "register_operand" "+<r>") 2385 (match_operand:SWI12 1 "register_operand" "+<r>")) 2386 (set (match_dup 1) 2387 (match_dup 0))] 2388 "TARGET_PARTIAL_REG_STALL" 2389 "xchg{<imodesuffix>}\t%1, %0" 2390 [(set_attr "type" "imov") 2391 (set_attr "mode" "<MODE>") 2392 (set_attr "pent_pair" "np") 2393 (set_attr "athlon_decode" "vector")]) 2394 2395(define_expand "movstrict<mode>" 2396 [(set (strict_low_part (match_operand:SWI12 0 "nonimmediate_operand" "")) 2397 (match_operand:SWI12 1 "general_operand" ""))] 2398 "" 2399{ 2400 if (TARGET_PARTIAL_REG_STALL && optimize_function_for_speed_p (cfun)) 2401 FAIL; 2402 if (GET_CODE (operands[0]) == SUBREG 2403 && GET_MODE_CLASS (GET_MODE (SUBREG_REG (operands[0]))) != MODE_INT) 2404 FAIL; 2405 /* Don't generate memory->memory moves, go through a register */ 2406 if (MEM_P (operands[0]) && MEM_P (operands[1])) 2407 operands[1] = force_reg (<MODE>mode, operands[1]); 2408}) 2409 2410(define_insn "*movstrict<mode>_1" 2411 [(set (strict_low_part 2412 (match_operand:SWI12 0 "nonimmediate_operand" "+<r>m,<r>")) 2413 (match_operand:SWI12 1 "general_operand" "<r>n,m"))] 2414 "(!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun)) 2415 && !(MEM_P (operands[0]) && MEM_P (operands[1]))" 2416 "mov{<imodesuffix>}\t{%1, %0|%0, %1}" 2417 [(set_attr "type" "imov") 2418 (set_attr "mode" "<MODE>")]) 2419 2420(define_insn "*movstrict<mode>_xor" 2421 [(set (strict_low_part (match_operand:SWI12 0 "register_operand" "+<r>")) 2422 (match_operand:SWI12 1 "const0_operand" "")) 2423 (clobber (reg:CC FLAGS_REG))] 2424 "reload_completed" 2425 "xor{<imodesuffix>}\t%0, %0" 2426 [(set_attr "type" "alu1") 2427 (set_attr "mode" "<MODE>") 2428 (set_attr "length_immediate" "0")]) 2429 2430(define_insn "*mov<mode>_extv_1" 2431 [(set (match_operand:SWI24 0 "register_operand" "=R") 2432 (sign_extract:SWI24 (match_operand 1 "ext_register_operand" "Q") 2433 (const_int 8) 2434 (const_int 8)))] 2435 "" 2436 "movs{bl|x}\t{%h1, %k0|%k0, %h1}" 2437 [(set_attr "type" "imovx") 2438 (set_attr "mode" "SI")]) 2439 2440(define_insn "*movqi_extv_1_rex64" 2441 [(set (match_operand:QI 0 "register_operand" "=Q,?R") 2442 (sign_extract:QI (match_operand 1 "ext_register_operand" "Q,Q") 2443 (const_int 8) 2444 (const_int 8)))] 2445 "TARGET_64BIT" 2446{ 2447 switch (get_attr_type (insn)) 2448 { 2449 case TYPE_IMOVX: 2450 return "movs{bl|x}\t{%h1, %k0|%k0, %h1}"; 2451 default: 2452 return "mov{b}\t{%h1, %0|%0, %h1}"; 2453 } 2454} 2455 [(set (attr "type") 2456 (if_then_else (ior (not (match_operand:QI 0 "QIreg_operand" "")) 2457 (match_test "TARGET_MOVX")) 2458 (const_string "imovx") 2459 (const_string "imov"))) 2460 (set (attr "mode") 2461 (if_then_else (eq_attr "type" "imovx") 2462 (const_string "SI") 2463 (const_string "QI")))]) 2464 2465(define_insn "*movqi_extv_1" 2466 [(set (match_operand:QI 0 "nonimmediate_operand" "=Qm,?r") 2467 (sign_extract:QI (match_operand 1 "ext_register_operand" "Q,Q") 2468 (const_int 8) 2469 (const_int 8)))] 2470 "!TARGET_64BIT" 2471{ 2472 switch (get_attr_type (insn)) 2473 { 2474 case TYPE_IMOVX: 2475 return "movs{bl|x}\t{%h1, %k0|%k0, %h1}"; 2476 default: 2477 return "mov{b}\t{%h1, %0|%0, %h1}"; 2478 } 2479} 2480 [(set (attr "type") 2481 (if_then_else (and (match_operand:QI 0 "register_operand" "") 2482 (ior (not (match_operand:QI 0 "QIreg_operand" "")) 2483 (match_test "TARGET_MOVX"))) 2484 (const_string "imovx") 2485 (const_string "imov"))) 2486 (set (attr "mode") 2487 (if_then_else (eq_attr "type" "imovx") 2488 (const_string "SI") 2489 (const_string "QI")))]) 2490 2491(define_insn "*mov<mode>_extzv_1" 2492 [(set (match_operand:SWI48 0 "register_operand" "=R") 2493 (zero_extract:SWI48 (match_operand 1 "ext_register_operand" "Q") 2494 (const_int 8) 2495 (const_int 8)))] 2496 "" 2497 "movz{bl|x}\t{%h1, %k0|%k0, %h1}" 2498 [(set_attr "type" "imovx") 2499 (set_attr "mode" "SI")]) 2500 2501(define_insn "*movqi_extzv_2_rex64" 2502 [(set (match_operand:QI 0 "register_operand" "=Q,?R") 2503 (subreg:QI 2504 (zero_extract:SI (match_operand 1 "ext_register_operand" "Q,Q") 2505 (const_int 8) 2506 (const_int 8)) 0))] 2507 "TARGET_64BIT" 2508{ 2509 switch (get_attr_type (insn)) 2510 { 2511 case TYPE_IMOVX: 2512 return "movz{bl|x}\t{%h1, %k0|%k0, %h1}"; 2513 default: 2514 return "mov{b}\t{%h1, %0|%0, %h1}"; 2515 } 2516} 2517 [(set (attr "type") 2518 (if_then_else (ior (not (match_operand:QI 0 "QIreg_operand" "")) 2519 (match_test "TARGET_MOVX")) 2520 (const_string "imovx") 2521 (const_string "imov"))) 2522 (set (attr "mode") 2523 (if_then_else (eq_attr "type" "imovx") 2524 (const_string "SI") 2525 (const_string "QI")))]) 2526 2527(define_insn "*movqi_extzv_2" 2528 [(set (match_operand:QI 0 "nonimmediate_operand" "=Qm,?R") 2529 (subreg:QI 2530 (zero_extract:SI (match_operand 1 "ext_register_operand" "Q,Q") 2531 (const_int 8) 2532 (const_int 8)) 0))] 2533 "!TARGET_64BIT" 2534{ 2535 switch (get_attr_type (insn)) 2536 { 2537 case TYPE_IMOVX: 2538 return "movz{bl|x}\t{%h1, %k0|%k0, %h1}"; 2539 default: 2540 return "mov{b}\t{%h1, %0|%0, %h1}"; 2541 } 2542} 2543 [(set (attr "type") 2544 (if_then_else (and (match_operand:QI 0 "register_operand" "") 2545 (ior (not (match_operand:QI 0 "QIreg_operand" "")) 2546 (match_test "TARGET_MOVX"))) 2547 (const_string "imovx") 2548 (const_string "imov"))) 2549 (set (attr "mode") 2550 (if_then_else (eq_attr "type" "imovx") 2551 (const_string "SI") 2552 (const_string "QI")))]) 2553 2554(define_expand "mov<mode>_insv_1" 2555 [(set (zero_extract:SWI48 (match_operand 0 "ext_register_operand" "") 2556 (const_int 8) 2557 (const_int 8)) 2558 (match_operand:SWI48 1 "nonmemory_operand" ""))]) 2559 2560(define_insn "*mov<mode>_insv_1_rex64" 2561 [(set (zero_extract:SWI48x (match_operand 0 "ext_register_operand" "+Q") 2562 (const_int 8) 2563 (const_int 8)) 2564 (match_operand:SWI48x 1 "nonmemory_operand" "Qn"))] 2565 "TARGET_64BIT" 2566{ 2567 if (CONST_INT_P (operands[1])) 2568 operands[1] = simplify_gen_subreg (QImode, operands[1], <MODE>mode, 0); 2569 return "mov{b}\t{%b1, %h0|%h0, %b1}"; 2570} 2571 [(set_attr "type" "imov") 2572 (set_attr "mode" "QI")]) 2573 2574(define_insn "*movsi_insv_1" 2575 [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "+Q") 2576 (const_int 8) 2577 (const_int 8)) 2578 (match_operand:SI 1 "general_operand" "Qmn"))] 2579 "!TARGET_64BIT" 2580{ 2581 if (CONST_INT_P (operands[1])) 2582 operands[1] = simplify_gen_subreg (QImode, operands[1], SImode, 0); 2583 return "mov{b}\t{%b1, %h0|%h0, %b1}"; 2584} 2585 [(set_attr "type" "imov") 2586 (set_attr "mode" "QI")]) 2587 2588(define_insn "*movqi_insv_2" 2589 [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "+Q") 2590 (const_int 8) 2591 (const_int 8)) 2592 (lshiftrt:SI (match_operand:SI 1 "register_operand" "Q") 2593 (const_int 8)))] 2594 "" 2595 "mov{b}\t{%h1, %h0|%h0, %h1}" 2596 [(set_attr "type" "imov") 2597 (set_attr "mode" "QI")]) 2598 2599;; Floating point push instructions. 2600 2601(define_insn "*pushtf" 2602 [(set (match_operand:TF 0 "push_operand" "=<,<,<") 2603 (match_operand:TF 1 "general_no_elim_operand" "x,Fo,*r"))] 2604 "TARGET_SSE2" 2605{ 2606 /* This insn should be already split before reg-stack. */ 2607 gcc_unreachable (); 2608} 2609 [(set_attr "type" "multi") 2610 (set_attr "unit" "sse,*,*") 2611 (set_attr "mode" "TF,SI,SI")]) 2612 2613;; %%% Kill this when call knows how to work this out. 2614(define_split 2615 [(set (match_operand:TF 0 "push_operand" "") 2616 (match_operand:TF 1 "sse_reg_operand" ""))] 2617 "TARGET_SSE2 && reload_completed" 2618 [(set (reg:P SP_REG) (plus:P (reg:P SP_REG) (const_int -16))) 2619 (set (mem:TF (reg:P SP_REG)) (match_dup 1))]) 2620 2621(define_insn "*pushxf" 2622 [(set (match_operand:XF 0 "push_operand" "=<,<") 2623 (match_operand:XF 1 "general_no_elim_operand" "f,ro"))] 2624 "optimize_function_for_speed_p (cfun)" 2625{ 2626 /* This insn should be already split before reg-stack. */ 2627 gcc_unreachable (); 2628} 2629 [(set_attr "type" "multi") 2630 (set_attr "unit" "i387,*") 2631 (set_attr "mode" "XF,SI")]) 2632 2633;; Size of pushxf is 3 (for sub) + 2 (for fstp) + memory operand size. 2634;; Size of pushxf using integer instructions is 3+3*memory operand size 2635;; Pushing using integer instructions is longer except for constants 2636;; and direct memory references (assuming that any given constant is pushed 2637;; only once, but this ought to be handled elsewhere). 2638 2639(define_insn "*pushxf_nointeger" 2640 [(set (match_operand:XF 0 "push_operand" "=<,<") 2641 (match_operand:XF 1 "general_no_elim_operand" "f,*rFo"))] 2642 "optimize_function_for_size_p (cfun)" 2643{ 2644 /* This insn should be already split before reg-stack. */ 2645 gcc_unreachable (); 2646} 2647 [(set_attr "type" "multi") 2648 (set_attr "unit" "i387,*") 2649 (set_attr "mode" "XF,SI")]) 2650 2651;; %%% Kill this when call knows how to work this out. 2652(define_split 2653 [(set (match_operand:XF 0 "push_operand" "") 2654 (match_operand:XF 1 "fp_register_operand" ""))] 2655 "reload_completed" 2656 [(set (reg:P SP_REG) (plus:P (reg:P SP_REG) (match_dup 2))) 2657 (set (mem:XF (reg:P SP_REG)) (match_dup 1))] 2658 "operands[2] = GEN_INT (-GET_MODE_SIZE (XFmode));") 2659 2660(define_insn "*pushdf_rex64" 2661 [(set (match_operand:DF 0 "push_operand" "=<,<,<") 2662 (match_operand:DF 1 "general_no_elim_operand" "f,Yd*rFm,x"))] 2663 "TARGET_64BIT" 2664{ 2665 /* This insn should be already split before reg-stack. */ 2666 gcc_unreachable (); 2667} 2668 [(set_attr "type" "multi") 2669 (set_attr "unit" "i387,*,*") 2670 (set_attr "mode" "DF,DI,DF")]) 2671 2672;; Size of pushdf is 3 (for sub) + 2 (for fstp) + memory operand size. 2673;; Size of pushdf using integer instructions is 2+2*memory operand size 2674;; On the average, pushdf using integers can be still shorter. 2675 2676(define_insn "*pushdf" 2677 [(set (match_operand:DF 0 "push_operand" "=<,<,<") 2678 (match_operand:DF 1 "general_no_elim_operand" "f,Yd*rFo,x"))] 2679 "!TARGET_64BIT" 2680{ 2681 /* This insn should be already split before reg-stack. */ 2682 gcc_unreachable (); 2683} 2684 [(set_attr "isa" "*,*,sse2") 2685 (set_attr "type" "multi") 2686 (set_attr "unit" "i387,*,*") 2687 (set_attr "mode" "DF,DI,DF")]) 2688 2689;; %%% Kill this when call knows how to work this out. 2690(define_split 2691 [(set (match_operand:DF 0 "push_operand" "") 2692 (match_operand:DF 1 "any_fp_register_operand" ""))] 2693 "reload_completed" 2694 [(set (reg:P SP_REG) (plus:P (reg:P SP_REG) (const_int -8))) 2695 (set (mem:DF (reg:P SP_REG)) (match_dup 1))]) 2696 2697(define_insn "*pushsf_rex64" 2698 [(set (match_operand:SF 0 "push_operand" "=X,X,X") 2699 (match_operand:SF 1 "nonmemory_no_elim_operand" "f,rF,x"))] 2700 "TARGET_64BIT" 2701{ 2702 /* Anything else should be already split before reg-stack. */ 2703 gcc_assert (which_alternative == 1); 2704 return "push{q}\t%q1"; 2705} 2706 [(set_attr "type" "multi,push,multi") 2707 (set_attr "unit" "i387,*,*") 2708 (set_attr "mode" "SF,DI,SF")]) 2709 2710(define_insn "*pushsf" 2711 [(set (match_operand:SF 0 "push_operand" "=<,<,<") 2712 (match_operand:SF 1 "general_no_elim_operand" "f,rFm,x"))] 2713 "!TARGET_64BIT" 2714{ 2715 /* Anything else should be already split before reg-stack. */ 2716 gcc_assert (which_alternative == 1); 2717 return "push{l}\t%1"; 2718} 2719 [(set_attr "type" "multi,push,multi") 2720 (set_attr "unit" "i387,*,*") 2721 (set_attr "mode" "SF,SI,SF")]) 2722 2723;; %%% Kill this when call knows how to work this out. 2724(define_split 2725 [(set (match_operand:SF 0 "push_operand" "") 2726 (match_operand:SF 1 "any_fp_register_operand" ""))] 2727 "reload_completed" 2728 [(set (reg:P SP_REG) (plus:P (reg:P SP_REG) (match_dup 2))) 2729 (set (mem:SF (reg:P SP_REG)) (match_dup 1))] 2730 "operands[2] = GEN_INT (-GET_MODE_SIZE (<P:MODE>mode));") 2731 2732(define_split 2733 [(set (match_operand:SF 0 "push_operand" "") 2734 (match_operand:SF 1 "memory_operand" ""))] 2735 "reload_completed 2736 && (operands[2] = find_constant_src (insn))" 2737 [(set (match_dup 0) (match_dup 2))]) 2738 2739(define_split 2740 [(set (match_operand 0 "push_operand" "") 2741 (match_operand 1 "general_operand" ""))] 2742 "reload_completed 2743 && (GET_MODE (operands[0]) == TFmode 2744 || GET_MODE (operands[0]) == XFmode 2745 || GET_MODE (operands[0]) == DFmode) 2746 && !ANY_FP_REG_P (operands[1])" 2747 [(const_int 0)] 2748 "ix86_split_long_move (operands); DONE;") 2749 2750;; Floating point move instructions. 2751 2752(define_expand "movtf" 2753 [(set (match_operand:TF 0 "nonimmediate_operand" "") 2754 (match_operand:TF 1 "nonimmediate_operand" ""))] 2755 "TARGET_64BIT || TARGET_SSE2" 2756{ 2757 ix86_expand_move (TFmode, operands); 2758 DONE; 2759}) 2760 2761(define_expand "mov<mode>" 2762 [(set (match_operand:X87MODEF 0 "nonimmediate_operand" "") 2763 (match_operand:X87MODEF 1 "general_operand" ""))] 2764 "" 2765 "ix86_expand_move (<MODE>mode, operands); DONE;") 2766 2767(define_insn "*movtf_internal_rex64" 2768 [(set (match_operand:TF 0 "nonimmediate_operand" "=x,m,x,?*r ,!o") 2769 (match_operand:TF 1 "general_operand" "xm,x,C,*roF,*r"))] 2770 "TARGET_64BIT && !(MEM_P (operands[0]) && MEM_P (operands[1])) 2771 && (!can_create_pseudo_p () 2772 || (ix86_cmodel == CM_MEDIUM || ix86_cmodel == CM_LARGE) 2773 || GET_CODE (operands[1]) != CONST_DOUBLE 2774 || (optimize_function_for_size_p (cfun) 2775 && standard_sse_constant_p (operands[1]) 2776 && !memory_operand (operands[0], TFmode)) 2777 || (!TARGET_MEMORY_MISMATCH_STALL 2778 && memory_operand (operands[0], TFmode)))" 2779{ 2780 switch (which_alternative) 2781 { 2782 case 0: 2783 case 1: 2784 /* Handle misaligned load/store since we 2785 don't have movmisaligntf pattern. */ 2786 if (misaligned_operand (operands[0], TFmode) 2787 || misaligned_operand (operands[1], TFmode)) 2788 { 2789 if (get_attr_mode (insn) == MODE_V4SF) 2790 return "%vmovups\t{%1, %0|%0, %1}"; 2791 else 2792 return "%vmovdqu\t{%1, %0|%0, %1}"; 2793 } 2794 else 2795 { 2796 if (get_attr_mode (insn) == MODE_V4SF) 2797 return "%vmovaps\t{%1, %0|%0, %1}"; 2798 else 2799 return "%vmovdqa\t{%1, %0|%0, %1}"; 2800 } 2801 2802 case 2: 2803 return standard_sse_constant_opcode (insn, operands[1]); 2804 2805 case 3: 2806 case 4: 2807 return "#"; 2808 2809 default: 2810 gcc_unreachable (); 2811 } 2812} 2813 [(set_attr "type" "ssemov,ssemov,sselog1,*,*") 2814 (set_attr "prefix" "maybe_vex,maybe_vex,maybe_vex,*,*") 2815 (set (attr "mode") 2816 (cond [(eq_attr "alternative" "0,2") 2817 (if_then_else 2818 (match_test "optimize_function_for_size_p (cfun)") 2819 (const_string "V4SF") 2820 (const_string "TI")) 2821 (eq_attr "alternative" "1") 2822 (if_then_else 2823 (ior (match_test "TARGET_SSE_TYPELESS_STORES") 2824 (match_test "optimize_function_for_size_p (cfun)")) 2825 (const_string "V4SF") 2826 (const_string "TI"))] 2827 (const_string "DI")))]) 2828 2829(define_insn "*movtf_internal_sse2" 2830 [(set (match_operand:TF 0 "nonimmediate_operand" "=x,m,x") 2831 (match_operand:TF 1 "general_operand" "xm,x,C"))] 2832 "TARGET_SSE2 && !TARGET_64BIT 2833 && !(MEM_P (operands[0]) && MEM_P (operands[1])) 2834 && (!can_create_pseudo_p () 2835 || (ix86_cmodel == CM_MEDIUM || ix86_cmodel == CM_LARGE) 2836 || GET_CODE (operands[1]) != CONST_DOUBLE 2837 || (optimize_function_for_size_p (cfun) 2838 && standard_sse_constant_p (operands[1]) 2839 && !memory_operand (operands[0], TFmode)) 2840 || (!TARGET_MEMORY_MISMATCH_STALL 2841 && memory_operand (operands[0], TFmode)))" 2842{ 2843 switch (which_alternative) 2844 { 2845 case 0: 2846 case 1: 2847 /* Handle misaligned load/store since we 2848 don't have movmisaligntf pattern. */ 2849 if (misaligned_operand (operands[0], TFmode) 2850 || misaligned_operand (operands[1], TFmode)) 2851 { 2852 if (get_attr_mode (insn) == MODE_V4SF) 2853 return "%vmovups\t{%1, %0|%0, %1}"; 2854 else 2855 return "%vmovdqu\t{%1, %0|%0, %1}"; 2856 } 2857 else 2858 { 2859 if (get_attr_mode (insn) == MODE_V4SF) 2860 return "%vmovaps\t{%1, %0|%0, %1}"; 2861 else 2862 return "%vmovdqa\t{%1, %0|%0, %1}"; 2863 } 2864 2865 case 2: 2866 return standard_sse_constant_opcode (insn, operands[1]); 2867 2868 default: 2869 gcc_unreachable (); 2870 } 2871} 2872 [(set_attr "type" "ssemov,ssemov,sselog1") 2873 (set_attr "prefix" "maybe_vex") 2874 (set (attr "mode") 2875 (cond [(eq_attr "alternative" "0,2") 2876 (if_then_else 2877 (match_test "optimize_function_for_size_p (cfun)") 2878 (const_string "V4SF") 2879 (const_string "TI")) 2880 (eq_attr "alternative" "1") 2881 (if_then_else 2882 (ior (match_test "TARGET_SSE_TYPELESS_STORES") 2883 (match_test "optimize_function_for_size_p (cfun)")) 2884 (const_string "V4SF") 2885 (const_string "TI"))] 2886 (const_string "DI")))]) 2887 2888(define_insn "*movxf_internal_rex64" 2889 [(set (match_operand:XF 0 "nonimmediate_operand" "=f,m,f,?Yx*r ,!o") 2890 (match_operand:XF 1 "general_operand" "fm,f,G,Yx*roF,Yx*rC"))] 2891 "TARGET_64BIT && !(MEM_P (operands[0]) && MEM_P (operands[1])) 2892 && (!can_create_pseudo_p () 2893 || (ix86_cmodel == CM_MEDIUM || ix86_cmodel == CM_LARGE) 2894 || GET_CODE (operands[1]) != CONST_DOUBLE 2895 || (optimize_function_for_size_p (cfun) 2896 && standard_80387_constant_p (operands[1]) > 0 2897 && !memory_operand (operands[0], XFmode)) 2898 || (!TARGET_MEMORY_MISMATCH_STALL 2899 && memory_operand (operands[0], XFmode)))" 2900{ 2901 switch (which_alternative) 2902 { 2903 case 0: 2904 case 1: 2905 return output_387_reg_move (insn, operands); 2906 2907 case 2: 2908 return standard_80387_constant_opcode (operands[1]); 2909 2910 case 3: 2911 case 4: 2912 return "#"; 2913 2914 default: 2915 gcc_unreachable (); 2916 } 2917} 2918 [(set_attr "type" "fmov,fmov,fmov,multi,multi") 2919 (set_attr "mode" "XF,XF,XF,SI,SI")]) 2920 2921;; Possible store forwarding (partial memory) stall in alternative 4. 2922(define_insn "*movxf_internal" 2923 [(set (match_operand:XF 0 "nonimmediate_operand" "=f,m,f,?Yx*r ,!o") 2924 (match_operand:XF 1 "general_operand" "fm,f,G,Yx*roF,Yx*rF"))] 2925 "!TARGET_64BIT && !(MEM_P (operands[0]) && MEM_P (operands[1])) 2926 && (!can_create_pseudo_p () 2927 || (ix86_cmodel == CM_MEDIUM || ix86_cmodel == CM_LARGE) 2928 || GET_CODE (operands[1]) != CONST_DOUBLE 2929 || (optimize_function_for_size_p (cfun) 2930 && standard_80387_constant_p (operands[1]) > 0 2931 && !memory_operand (operands[0], XFmode)) 2932 || (!TARGET_MEMORY_MISMATCH_STALL 2933 && memory_operand (operands[0], XFmode)))" 2934{ 2935 switch (which_alternative) 2936 { 2937 case 0: 2938 case 1: 2939 return output_387_reg_move (insn, operands); 2940 2941 case 2: 2942 return standard_80387_constant_opcode (operands[1]); 2943 2944 case 3: 2945 case 4: 2946 return "#"; 2947 2948 default: 2949 gcc_unreachable (); 2950 } 2951} 2952 [(set_attr "type" "fmov,fmov,fmov,multi,multi") 2953 (set_attr "mode" "XF,XF,XF,SI,SI")]) 2954 2955(define_insn "*movdf_internal_rex64" 2956 [(set (match_operand:DF 0 "nonimmediate_operand" 2957 "=?Yf*f,?m ,?Yf*f,?r,?m,?r,?r,x,x,x,m,Yi,r ") 2958 (match_operand:DF 1 "general_operand" 2959 "Yf*fm ,Yf*f ,G ,rm,rC,C ,F ,C,x,m,x,r ,Yi"))] 2960 "TARGET_64BIT && !(MEM_P (operands[0]) && MEM_P (operands[1])) 2961 && (!can_create_pseudo_p () 2962 || (ix86_cmodel == CM_MEDIUM || ix86_cmodel == CM_LARGE) 2963 || GET_CODE (operands[1]) != CONST_DOUBLE 2964 || (optimize_function_for_size_p (cfun) 2965 && ((!(TARGET_SSE2 && TARGET_SSE_MATH) 2966 && standard_80387_constant_p (operands[1]) > 0) 2967 || (TARGET_SSE2 && TARGET_SSE_MATH 2968 && standard_sse_constant_p (operands[1])))) 2969 || memory_operand (operands[0], DFmode))" 2970{ 2971 switch (which_alternative) 2972 { 2973 case 0: 2974 case 1: 2975 return output_387_reg_move (insn, operands); 2976 2977 case 2: 2978 return standard_80387_constant_opcode (operands[1]); 2979 2980 case 3: 2981 case 4: 2982 return "mov{q}\t{%1, %0|%0, %1}"; 2983 2984 case 5: 2985 return "mov{l}\t{%1, %k0|%k0, %1}"; 2986 2987 case 6: 2988 return "movabs{q}\t{%1, %0|%0, %1}"; 2989 2990 case 7: 2991 return standard_sse_constant_opcode (insn, operands[1]); 2992 2993 case 8: 2994 case 9: 2995 case 10: 2996 switch (get_attr_mode (insn)) 2997 { 2998 case MODE_V2DF: 2999 if (!TARGET_SSE_PACKED_SINGLE_INSN_OPTIMAL) 3000 return "%vmovapd\t{%1, %0|%0, %1}"; 3001 case MODE_V4SF: 3002 return "%vmovaps\t{%1, %0|%0, %1}"; 3003 3004 case MODE_DI: 3005 return "%vmovq\t{%1, %0|%0, %1}"; 3006 case MODE_DF: 3007 if (TARGET_AVX && REG_P (operands[0]) && REG_P (operands[1])) 3008 return "vmovsd\t{%1, %0, %0|%0, %0, %1}"; 3009 return "%vmovsd\t{%1, %0|%0, %1}"; 3010 case MODE_V1DF: 3011 return "%vmovlpd\t{%1, %d0|%d0, %1}"; 3012 case MODE_V2SF: 3013 return "%vmovlps\t{%1, %d0|%d0, %1}"; 3014 default: 3015 gcc_unreachable (); 3016 } 3017 3018 case 11: 3019 case 12: 3020 /* Handle broken assemblers that require movd instead of movq. */ 3021 return "%vmovd\t{%1, %0|%0, %1}"; 3022 3023 default: 3024 gcc_unreachable(); 3025 } 3026} 3027 [(set (attr "type") 3028 (cond [(eq_attr "alternative" "0,1,2") 3029 (const_string "fmov") 3030 (eq_attr "alternative" "3,4,5,6") 3031 (const_string "imov") 3032 (eq_attr "alternative" "7") 3033 (const_string "sselog1") 3034 ] 3035 (const_string "ssemov"))) 3036 (set (attr "modrm") 3037 (if_then_else 3038 (and (eq_attr "alternative" "6") (eq_attr "type" "imov")) 3039 (const_string "0") 3040 (const_string "*"))) 3041 (set (attr "length_immediate") 3042 (if_then_else 3043 (and (eq_attr "alternative" "6") (eq_attr "type" "imov")) 3044 (const_string "8") 3045 (const_string "*"))) 3046 (set (attr "prefix") 3047 (if_then_else (eq_attr "alternative" "0,1,2,3,4,5,6") 3048 (const_string "orig") 3049 (const_string "maybe_vex"))) 3050 (set (attr "prefix_data16") 3051 (if_then_else (eq_attr "mode" "V1DF") 3052 (const_string "1") 3053 (const_string "*"))) 3054 (set (attr "mode") 3055 (cond [(eq_attr "alternative" "0,1,2") 3056 (const_string "DF") 3057 (eq_attr "alternative" "3,4,6,11,12") 3058 (const_string "DI") 3059 (eq_attr "alternative" "5") 3060 (const_string "SI") 3061 3062 /* xorps is one byte shorter. */ 3063 (eq_attr "alternative" "7") 3064 (cond [(match_test "optimize_function_for_size_p (cfun)") 3065 (const_string "V4SF") 3066 (match_test "TARGET_SSE_LOAD0_BY_PXOR") 3067 (const_string "TI") 3068 ] 3069 (const_string "V2DF")) 3070 3071 /* For architectures resolving dependencies on 3072 whole SSE registers use APD move to break dependency 3073 chains, otherwise use short move to avoid extra work. 3074 3075 movaps encodes one byte shorter. */ 3076 (eq_attr "alternative" "8") 3077 (cond 3078 [(match_test "optimize_function_for_size_p (cfun)") 3079 (const_string "V4SF") 3080 (match_test "TARGET_SSE_PARTIAL_REG_DEPENDENCY") 3081 (const_string "V2DF") 3082 ] 3083 (const_string "DF")) 3084 /* For architectures resolving dependencies on register 3085 parts we may avoid extra work to zero out upper part 3086 of register. */ 3087 (eq_attr "alternative" "9") 3088 (if_then_else 3089 (match_test "TARGET_SSE_SPLIT_REGS") 3090 (const_string "V1DF") 3091 (const_string "DF")) 3092 ] 3093 (const_string "DF")))]) 3094 3095;; Possible store forwarding (partial memory) stall in alternative 4. 3096(define_insn "*movdf_internal" 3097 [(set (match_operand:DF 0 "nonimmediate_operand" 3098 "=Yf*f,m ,Yf*f,?Yd*r ,!o ,x,x,x,m,*x,*x,*x,m") 3099 (match_operand:DF 1 "general_operand" 3100 "Yf*fm,Yf*f,G ,Yd*roF,Yd*rF,C,x,m,x,C ,*x,m ,*x"))] 3101 "!TARGET_64BIT && !(MEM_P (operands[0]) && MEM_P (operands[1])) 3102 && (!can_create_pseudo_p () 3103 || (ix86_cmodel == CM_MEDIUM || ix86_cmodel == CM_LARGE) 3104 || GET_CODE (operands[1]) != CONST_DOUBLE 3105 || (optimize_function_for_size_p (cfun) 3106 && ((!(TARGET_SSE2 && TARGET_SSE_MATH) 3107 && standard_80387_constant_p (operands[1]) > 0) 3108 || (TARGET_SSE2 && TARGET_SSE_MATH 3109 && standard_sse_constant_p (operands[1]))) 3110 && !memory_operand (operands[0], DFmode)) 3111 || (!TARGET_MEMORY_MISMATCH_STALL 3112 && memory_operand (operands[0], DFmode)))" 3113{ 3114 switch (which_alternative) 3115 { 3116 case 0: 3117 case 1: 3118 return output_387_reg_move (insn, operands); 3119 3120 case 2: 3121 return standard_80387_constant_opcode (operands[1]); 3122 3123 case 3: 3124 case 4: 3125 return "#"; 3126 3127 case 5: 3128 case 9: 3129 return standard_sse_constant_opcode (insn, operands[1]); 3130 3131 case 6: 3132 case 7: 3133 case 8: 3134 case 10: 3135 case 11: 3136 case 12: 3137 switch (get_attr_mode (insn)) 3138 { 3139 case MODE_V2DF: 3140 if (!TARGET_SSE_PACKED_SINGLE_INSN_OPTIMAL) 3141 return "%vmovapd\t{%1, %0|%0, %1}"; 3142 case MODE_V4SF: 3143 return "%vmovaps\t{%1, %0|%0, %1}"; 3144 3145 case MODE_DI: 3146 return "%vmovq\t{%1, %0|%0, %1}"; 3147 case MODE_DF: 3148 if (TARGET_AVX && REG_P (operands[0]) && REG_P (operands[1])) 3149 return "vmovsd\t{%1, %0, %0|%0, %0, %1}"; 3150 return "%vmovsd\t{%1, %0|%0, %1}"; 3151 case MODE_V1DF: 3152 return "%vmovlpd\t{%1, %d0|%d0, %1}"; 3153 case MODE_V2SF: 3154 return "%vmovlps\t{%1, %d0|%d0, %1}"; 3155 default: 3156 gcc_unreachable (); 3157 } 3158 3159 default: 3160 gcc_unreachable (); 3161 } 3162} 3163 [(set (attr "isa") 3164 (if_then_else (eq_attr "alternative" "5,6,7,8") 3165 (const_string "sse2") 3166 (const_string "*"))) 3167 (set (attr "type") 3168 (cond [(eq_attr "alternative" "0,1,2") 3169 (const_string "fmov") 3170 (eq_attr "alternative" "3,4") 3171 (const_string "multi") 3172 (eq_attr "alternative" "5,9") 3173 (const_string "sselog1") 3174 ] 3175 (const_string "ssemov"))) 3176 (set (attr "prefix") 3177 (if_then_else (eq_attr "alternative" "0,1,2,3,4") 3178 (const_string "orig") 3179 (const_string "maybe_vex"))) 3180 (set (attr "prefix_data16") 3181 (if_then_else (eq_attr "mode" "V1DF") 3182 (const_string "1") 3183 (const_string "*"))) 3184 (set (attr "mode") 3185 (cond [(eq_attr "alternative" "0,1,2") 3186 (const_string "DF") 3187 (eq_attr "alternative" "3,4") 3188 (const_string "SI") 3189 3190 /* For SSE1, we have many fewer alternatives. */ 3191 (not (match_test "TARGET_SSE2")) 3192 (if_then_else 3193 (eq_attr "alternative" "5,6,9,10") 3194 (const_string "V4SF") 3195 (const_string "V2SF")) 3196 3197 /* xorps is one byte shorter. */ 3198 (eq_attr "alternative" "5,9") 3199 (cond [(match_test "optimize_function_for_size_p (cfun)") 3200 (const_string "V4SF") 3201 (match_test "TARGET_SSE_LOAD0_BY_PXOR") 3202 (const_string "TI") 3203 ] 3204 (const_string "V2DF")) 3205 3206 /* For architectures resolving dependencies on 3207 whole SSE registers use APD move to break dependency 3208 chains, otherwise use short move to avoid extra work. 3209 3210 movaps encodes one byte shorter. */ 3211 (eq_attr "alternative" "6,10") 3212 (cond 3213 [(match_test "optimize_function_for_size_p (cfun)") 3214 (const_string "V4SF") 3215 (match_test "TARGET_SSE_PARTIAL_REG_DEPENDENCY") 3216 (const_string "V2DF") 3217 ] 3218 (const_string "DF")) 3219 /* For architectures resolving dependencies on register 3220 parts we may avoid extra work to zero out upper part 3221 of register. */ 3222 (eq_attr "alternative" "7,11") 3223 (if_then_else 3224 (match_test "TARGET_SSE_SPLIT_REGS") 3225 (const_string "V1DF") 3226 (const_string "DF")) 3227 ] 3228 (const_string "DF")))]) 3229 3230(define_insn "*movsf_internal" 3231 [(set (match_operand:SF 0 "nonimmediate_operand" 3232 "=Yf*f,m ,Yf*f,?r ,?m,x,x,x,m,!*y,!m,!*y,?Yi,?r,!*Ym,!r") 3233 (match_operand:SF 1 "general_operand" 3234 "Yf*fm,Yf*f,G ,rmF,rF,C,x,m,x,m ,*y,*y ,r ,Yi,r ,*Ym"))] 3235 "!(MEM_P (operands[0]) && MEM_P (operands[1])) 3236 && (!can_create_pseudo_p () 3237 || (ix86_cmodel == CM_MEDIUM || ix86_cmodel == CM_LARGE) 3238 || GET_CODE (operands[1]) != CONST_DOUBLE 3239 || (optimize_function_for_size_p (cfun) 3240 && ((!TARGET_SSE_MATH 3241 && standard_80387_constant_p (operands[1]) > 0) 3242 || (TARGET_SSE_MATH 3243 && standard_sse_constant_p (operands[1])))) 3244 || memory_operand (operands[0], SFmode))" 3245{ 3246 switch (which_alternative) 3247 { 3248 case 0: 3249 case 1: 3250 return output_387_reg_move (insn, operands); 3251 3252 case 2: 3253 return standard_80387_constant_opcode (operands[1]); 3254 3255 case 3: 3256 case 4: 3257 return "mov{l}\t{%1, %0|%0, %1}"; 3258 3259 case 5: 3260 return standard_sse_constant_opcode (insn, operands[1]); 3261 3262 case 6: 3263 if (get_attr_mode (insn) == MODE_V4SF) 3264 return "%vmovaps\t{%1, %0|%0, %1}"; 3265 if (TARGET_AVX) 3266 return "vmovss\t{%1, %0, %0|%0, %0, %1}"; 3267 3268 case 7: 3269 case 8: 3270 return "%vmovss\t{%1, %0|%0, %1}"; 3271 3272 case 9: 3273 case 10: 3274 case 14: 3275 case 15: 3276 return "movd\t{%1, %0|%0, %1}"; 3277 3278 case 11: 3279 return "movq\t{%1, %0|%0, %1}"; 3280 3281 case 12: 3282 case 13: 3283 return "%vmovd\t{%1, %0|%0, %1}"; 3284 3285 default: 3286 gcc_unreachable (); 3287 } 3288} 3289 [(set (attr "type") 3290 (cond [(eq_attr "alternative" "0,1,2") 3291 (const_string "fmov") 3292 (eq_attr "alternative" "3,4") 3293 (const_string "imov") 3294 (eq_attr "alternative" "5") 3295 (const_string "sselog1") 3296 (eq_attr "alternative" "9,10,11,14,15") 3297 (const_string "mmxmov") 3298 ] 3299 (const_string "ssemov"))) 3300 (set (attr "prefix") 3301 (if_then_else (eq_attr "alternative" "5,6,7,8,12,13") 3302 (const_string "maybe_vex") 3303 (const_string "orig"))) 3304 (set (attr "mode") 3305 (cond [(eq_attr "alternative" "3,4,9,10") 3306 (const_string "SI") 3307 (eq_attr "alternative" "5") 3308 (if_then_else 3309 (and (and (match_test "TARGET_SSE_LOAD0_BY_PXOR") 3310 (match_test "TARGET_SSE2")) 3311 (not (match_test "optimize_function_for_size_p (cfun)"))) 3312 (const_string "TI") 3313 (const_string "V4SF")) 3314 /* For architectures resolving dependencies on 3315 whole SSE registers use APS move to break dependency 3316 chains, otherwise use short move to avoid extra work. 3317 3318 Do the same for architectures resolving dependencies on 3319 the parts. While in DF mode it is better to always handle 3320 just register parts, the SF mode is different due to lack 3321 of instructions to load just part of the register. It is 3322 better to maintain the whole registers in single format 3323 to avoid problems on using packed logical operations. */ 3324 (eq_attr "alternative" "6") 3325 (if_then_else 3326 (ior (match_test "TARGET_SSE_PARTIAL_REG_DEPENDENCY") 3327 (match_test "TARGET_SSE_SPLIT_REGS")) 3328 (const_string "V4SF") 3329 (const_string "SF")) 3330 (eq_attr "alternative" "11") 3331 (const_string "DI")] 3332 (const_string "SF")))]) 3333 3334(define_split 3335 [(set (match_operand 0 "any_fp_register_operand" "") 3336 (match_operand 1 "memory_operand" ""))] 3337 "reload_completed 3338 && (GET_MODE (operands[0]) == TFmode 3339 || GET_MODE (operands[0]) == XFmode 3340 || GET_MODE (operands[0]) == DFmode 3341 || GET_MODE (operands[0]) == SFmode) 3342 && (operands[2] = find_constant_src (insn))" 3343 [(set (match_dup 0) (match_dup 2))] 3344{ 3345 rtx c = operands[2]; 3346 int r = REGNO (operands[0]); 3347 3348 if ((SSE_REGNO_P (r) && !standard_sse_constant_p (c)) 3349 || (FP_REGNO_P (r) && standard_80387_constant_p (c) < 1)) 3350 FAIL; 3351}) 3352 3353(define_split 3354 [(set (match_operand 0 "any_fp_register_operand" "") 3355 (float_extend (match_operand 1 "memory_operand" "")))] 3356 "reload_completed 3357 && (GET_MODE (operands[0]) == TFmode 3358 || GET_MODE (operands[0]) == XFmode 3359 || GET_MODE (operands[0]) == DFmode) 3360 && (operands[2] = find_constant_src (insn))" 3361 [(set (match_dup 0) (match_dup 2))] 3362{ 3363 rtx c = operands[2]; 3364 int r = REGNO (operands[0]); 3365 3366 if ((SSE_REGNO_P (r) && !standard_sse_constant_p (c)) 3367 || (FP_REGNO_P (r) && standard_80387_constant_p (c) < 1)) 3368 FAIL; 3369}) 3370 3371;; Split the load of -0.0 or -1.0 into fldz;fchs or fld1;fchs sequence 3372(define_split 3373 [(set (match_operand:X87MODEF 0 "fp_register_operand" "") 3374 (match_operand:X87MODEF 1 "immediate_operand" ""))] 3375 "reload_completed 3376 && (standard_80387_constant_p (operands[1]) == 8 3377 || standard_80387_constant_p (operands[1]) == 9)" 3378 [(set (match_dup 0)(match_dup 1)) 3379 (set (match_dup 0) 3380 (neg:X87MODEF (match_dup 0)))] 3381{ 3382 REAL_VALUE_TYPE r; 3383 3384 REAL_VALUE_FROM_CONST_DOUBLE (r, operands[1]); 3385 if (real_isnegzero (&r)) 3386 operands[1] = CONST0_RTX (<MODE>mode); 3387 else 3388 operands[1] = CONST1_RTX (<MODE>mode); 3389}) 3390 3391(define_split 3392 [(set (match_operand 0 "nonimmediate_operand" "") 3393 (match_operand 1 "general_operand" ""))] 3394 "reload_completed 3395 && (GET_MODE (operands[0]) == TFmode 3396 || GET_MODE (operands[0]) == XFmode 3397 || GET_MODE (operands[0]) == DFmode) 3398 && !(ANY_FP_REG_P (operands[0]) || ANY_FP_REG_P (operands[1]))" 3399 [(const_int 0)] 3400 "ix86_split_long_move (operands); DONE;") 3401 3402(define_insn "swapxf" 3403 [(set (match_operand:XF 0 "register_operand" "+f") 3404 (match_operand:XF 1 "register_operand" "+f")) 3405 (set (match_dup 1) 3406 (match_dup 0))] 3407 "TARGET_80387" 3408{ 3409 if (STACK_TOP_P (operands[0])) 3410 return "fxch\t%1"; 3411 else 3412 return "fxch\t%0"; 3413} 3414 [(set_attr "type" "fxch") 3415 (set_attr "mode" "XF")]) 3416 3417(define_insn "*swap<mode>" 3418 [(set (match_operand:MODEF 0 "fp_register_operand" "+f") 3419 (match_operand:MODEF 1 "fp_register_operand" "+f")) 3420 (set (match_dup 1) 3421 (match_dup 0))] 3422 "TARGET_80387 || reload_completed" 3423{ 3424 if (STACK_TOP_P (operands[0])) 3425 return "fxch\t%1"; 3426 else 3427 return "fxch\t%0"; 3428} 3429 [(set_attr "type" "fxch") 3430 (set_attr "mode" "<MODE>")]) 3431 3432;; Zero extension instructions 3433 3434(define_expand "zero_extendsidi2" 3435 [(set (match_operand:DI 0 "nonimmediate_operand" "") 3436 (zero_extend:DI (match_operand:SI 1 "nonimmediate_operand" "")))] 3437 "" 3438{ 3439 if (!TARGET_64BIT) 3440 { 3441 emit_insn (gen_zero_extendsidi2_1 (operands[0], operands[1])); 3442 DONE; 3443 } 3444}) 3445 3446(define_insn "*zero_extendsidi2_rex64" 3447 [(set (match_operand:DI 0 "nonimmediate_operand" "=r,o,?*Ym,?*y,?*Yi,*x") 3448 (zero_extend:DI 3449 (match_operand:SI 1 "nonimmediate_operand" "rm,0,r ,m ,r ,m")))] 3450 "TARGET_64BIT" 3451 "@ 3452 mov{l}\t{%1, %k0|%k0, %1} 3453 # 3454 movd\t{%1, %0|%0, %1} 3455 movd\t{%1, %0|%0, %1} 3456 %vmovd\t{%1, %0|%0, %1} 3457 %vmovd\t{%1, %0|%0, %1}" 3458 [(set_attr "type" "imovx,imov,mmxmov,mmxmov,ssemov,ssemov") 3459 (set_attr "prefix" "orig,*,orig,orig,maybe_vex,maybe_vex") 3460 (set_attr "prefix_0f" "0,*,*,*,*,*") 3461 (set_attr "mode" "SI,DI,DI,DI,TI,TI")]) 3462 3463(define_split 3464 [(set (match_operand:DI 0 "memory_operand" "") 3465 (zero_extend:DI (match_dup 0)))] 3466 "TARGET_64BIT" 3467 [(set (match_dup 4) (const_int 0))] 3468 "split_double_mode (DImode, &operands[0], 1, &operands[3], &operands[4]);") 3469 3470;; %%% Kill me once multi-word ops are sane. 3471(define_insn "zero_extendsidi2_1" 3472 [(set (match_operand:DI 0 "nonimmediate_operand" "=r,?r,?o,?*Ym,?*y,?*Yi,*x") 3473 (zero_extend:DI 3474 (match_operand:SI 1 "nonimmediate_operand" "0,rm,r ,r ,m ,r ,m"))) 3475 (clobber (reg:CC FLAGS_REG))] 3476 "!TARGET_64BIT" 3477 "@ 3478 # 3479 # 3480 # 3481 movd\t{%1, %0|%0, %1} 3482 movd\t{%1, %0|%0, %1} 3483 %vmovd\t{%1, %0|%0, %1} 3484 %vmovd\t{%1, %0|%0, %1}" 3485 [(set_attr "isa" "*,*,*,*,*,*,sse2") 3486 (set_attr "type" "multi,multi,multi,mmxmov,mmxmov,ssemov,ssemov") 3487 (set_attr "prefix" "*,*,*,orig,orig,maybe_vex,maybe_vex") 3488 (set_attr "mode" "SI,SI,SI,DI,DI,TI,TI")]) 3489 3490(define_split 3491 [(set (match_operand:DI 0 "register_operand" "") 3492 (zero_extend:DI (match_operand:SI 1 "register_operand" ""))) 3493 (clobber (reg:CC FLAGS_REG))] 3494 "!TARGET_64BIT && reload_completed 3495 && true_regnum (operands[0]) == true_regnum (operands[1])" 3496 [(set (match_dup 4) (const_int 0))] 3497 "split_double_mode (DImode, &operands[0], 1, &operands[3], &operands[4]);") 3498 3499(define_split 3500 [(set (match_operand:DI 0 "nonimmediate_operand" "") 3501 (zero_extend:DI (match_operand:SI 1 "general_operand" ""))) 3502 (clobber (reg:CC FLAGS_REG))] 3503 "!TARGET_64BIT && reload_completed 3504 && !(MMX_REG_P (operands[0]) || SSE_REG_P (operands[0]))" 3505 [(set (match_dup 3) (match_dup 1)) 3506 (set (match_dup 4) (const_int 0))] 3507 "split_double_mode (DImode, &operands[0], 1, &operands[3], &operands[4]);") 3508 3509(define_insn "zero_extend<mode>di2" 3510 [(set (match_operand:DI 0 "register_operand" "=r") 3511 (zero_extend:DI 3512 (match_operand:SWI12 1 "nonimmediate_operand" "<r>m")))] 3513 "TARGET_64BIT" 3514 "movz{<imodesuffix>l|x}\t{%1, %k0|%k0, %1}" 3515 [(set_attr "type" "imovx") 3516 (set_attr "mode" "SI")]) 3517 3518(define_expand "zero_extendhisi2" 3519 [(set (match_operand:SI 0 "register_operand" "") 3520 (zero_extend:SI (match_operand:HI 1 "nonimmediate_operand" "")))] 3521 "" 3522{ 3523 if (TARGET_ZERO_EXTEND_WITH_AND && optimize_function_for_speed_p (cfun)) 3524 { 3525 operands[1] = force_reg (HImode, operands[1]); 3526 emit_insn (gen_zero_extendhisi2_and (operands[0], operands[1])); 3527 DONE; 3528 } 3529}) 3530 3531(define_insn_and_split "zero_extendhisi2_and" 3532 [(set (match_operand:SI 0 "register_operand" "=r") 3533 (zero_extend:SI (match_operand:HI 1 "register_operand" "0"))) 3534 (clobber (reg:CC FLAGS_REG))] 3535 "TARGET_ZERO_EXTEND_WITH_AND && optimize_function_for_speed_p (cfun)" 3536 "#" 3537 "&& reload_completed" 3538 [(parallel [(set (match_dup 0) (and:SI (match_dup 0) (const_int 65535))) 3539 (clobber (reg:CC FLAGS_REG))])] 3540 "" 3541 [(set_attr "type" "alu1") 3542 (set_attr "mode" "SI")]) 3543 3544(define_insn "*zero_extendhisi2_movzwl" 3545 [(set (match_operand:SI 0 "register_operand" "=r") 3546 (zero_extend:SI (match_operand:HI 1 "nonimmediate_operand" "rm")))] 3547 "!TARGET_ZERO_EXTEND_WITH_AND 3548 || optimize_function_for_size_p (cfun)" 3549 "movz{wl|x}\t{%1, %0|%0, %1}" 3550 [(set_attr "type" "imovx") 3551 (set_attr "mode" "SI")]) 3552 3553(define_expand "zero_extendqi<mode>2" 3554 [(parallel 3555 [(set (match_operand:SWI24 0 "register_operand" "") 3556 (zero_extend:SWI24 (match_operand:QI 1 "nonimmediate_operand" ""))) 3557 (clobber (reg:CC FLAGS_REG))])]) 3558 3559(define_insn "*zero_extendqi<mode>2_and" 3560 [(set (match_operand:SWI24 0 "register_operand" "=r,?&q") 3561 (zero_extend:SWI24 (match_operand:QI 1 "nonimmediate_operand" "0,qm"))) 3562 (clobber (reg:CC FLAGS_REG))] 3563 "TARGET_ZERO_EXTEND_WITH_AND && optimize_function_for_speed_p (cfun)" 3564 "#" 3565 [(set_attr "type" "alu1") 3566 (set_attr "mode" "<MODE>")]) 3567 3568;; When source and destination does not overlap, clear destination 3569;; first and then do the movb 3570(define_split 3571 [(set (match_operand:SWI24 0 "register_operand" "") 3572 (zero_extend:SWI24 (match_operand:QI 1 "nonimmediate_operand" ""))) 3573 (clobber (reg:CC FLAGS_REG))] 3574 "reload_completed 3575 && (TARGET_ZERO_EXTEND_WITH_AND && optimize_function_for_speed_p (cfun)) 3576 && ANY_QI_REG_P (operands[0]) 3577 && (ANY_QI_REG_P (operands[1]) || MEM_P (operands[1])) 3578 && !reg_overlap_mentioned_p (operands[0], operands[1])" 3579 [(set (strict_low_part (match_dup 2)) (match_dup 1))] 3580{ 3581 operands[2] = gen_lowpart (QImode, operands[0]); 3582 ix86_expand_clear (operands[0]); 3583}) 3584 3585(define_insn "*zero_extendqi<mode>2_movzbl_and" 3586 [(set (match_operand:SWI24 0 "register_operand" "=r,r") 3587 (zero_extend:SWI24 (match_operand:QI 1 "nonimmediate_operand" "qm,0"))) 3588 (clobber (reg:CC FLAGS_REG))] 3589 "!TARGET_ZERO_EXTEND_WITH_AND || optimize_function_for_size_p (cfun)" 3590 "#" 3591 [(set_attr "type" "imovx,alu1") 3592 (set_attr "mode" "<MODE>")]) 3593 3594;; For the movzbl case strip only the clobber 3595(define_split 3596 [(set (match_operand:SWI24 0 "register_operand" "") 3597 (zero_extend:SWI24 (match_operand:QI 1 "nonimmediate_operand" ""))) 3598 (clobber (reg:CC FLAGS_REG))] 3599 "reload_completed 3600 && (!TARGET_ZERO_EXTEND_WITH_AND || optimize_function_for_size_p (cfun)) 3601 && (!REG_P (operands[1]) || ANY_QI_REG_P (operands[1]))" 3602 [(set (match_dup 0) 3603 (zero_extend:SWI24 (match_dup 1)))]) 3604 3605; zero extend to SImode to avoid partial register stalls 3606(define_insn "*zero_extendqi<mode>2_movzbl" 3607 [(set (match_operand:SWI24 0 "register_operand" "=r") 3608 (zero_extend:SWI24 (match_operand:QI 1 "nonimmediate_operand" "qm")))] 3609 "reload_completed 3610 && (!TARGET_ZERO_EXTEND_WITH_AND || optimize_function_for_size_p (cfun))" 3611 "movz{bl|x}\t{%1, %k0|%k0, %1}" 3612 [(set_attr "type" "imovx") 3613 (set_attr "mode" "SI")]) 3614 3615;; Rest is handled by single and. 3616(define_split 3617 [(set (match_operand:SWI24 0 "register_operand" "") 3618 (zero_extend:SWI24 (match_operand:QI 1 "register_operand" ""))) 3619 (clobber (reg:CC FLAGS_REG))] 3620 "reload_completed 3621 && true_regnum (operands[0]) == true_regnum (operands[1])" 3622 [(parallel [(set (match_dup 0) (and:SWI24 (match_dup 0) (const_int 255))) 3623 (clobber (reg:CC FLAGS_REG))])]) 3624 3625;; Sign extension instructions 3626 3627(define_expand "extendsidi2" 3628 [(set (match_operand:DI 0 "register_operand" "") 3629 (sign_extend:DI (match_operand:SI 1 "register_operand" "")))] 3630 "" 3631{ 3632 if (!TARGET_64BIT) 3633 { 3634 emit_insn (gen_extendsidi2_1 (operands[0], operands[1])); 3635 DONE; 3636 } 3637}) 3638 3639(define_insn "*extendsidi2_rex64" 3640 [(set (match_operand:DI 0 "register_operand" "=*a,r") 3641 (sign_extend:DI (match_operand:SI 1 "nonimmediate_operand" "*0,rm")))] 3642 "TARGET_64BIT" 3643 "@ 3644 {cltq|cdqe} 3645 movs{lq|x}\t{%1, %0|%0, %1}" 3646 [(set_attr "type" "imovx") 3647 (set_attr "mode" "DI") 3648 (set_attr "prefix_0f" "0") 3649 (set_attr "modrm" "0,1")]) 3650 3651(define_insn "extendsidi2_1" 3652 [(set (match_operand:DI 0 "nonimmediate_operand" "=*A,r,?r,?*o") 3653 (sign_extend:DI (match_operand:SI 1 "register_operand" "0,0,r,r"))) 3654 (clobber (reg:CC FLAGS_REG)) 3655 (clobber (match_scratch:SI 2 "=X,X,X,&r"))] 3656 "!TARGET_64BIT" 3657 "#") 3658 3659;; Extend to memory case when source register does die. 3660(define_split 3661 [(set (match_operand:DI 0 "memory_operand" "") 3662 (sign_extend:DI (match_operand:SI 1 "register_operand" ""))) 3663 (clobber (reg:CC FLAGS_REG)) 3664 (clobber (match_operand:SI 2 "register_operand" ""))] 3665 "(reload_completed 3666 && dead_or_set_p (insn, operands[1]) 3667 && !reg_mentioned_p (operands[1], operands[0]))" 3668 [(set (match_dup 3) (match_dup 1)) 3669 (parallel [(set (match_dup 1) (ashiftrt:SI (match_dup 1) (const_int 31))) 3670 (clobber (reg:CC FLAGS_REG))]) 3671 (set (match_dup 4) (match_dup 1))] 3672 "split_double_mode (DImode, &operands[0], 1, &operands[3], &operands[4]);") 3673 3674;; Extend to memory case when source register does not die. 3675(define_split 3676 [(set (match_operand:DI 0 "memory_operand" "") 3677 (sign_extend:DI (match_operand:SI 1 "register_operand" ""))) 3678 (clobber (reg:CC FLAGS_REG)) 3679 (clobber (match_operand:SI 2 "register_operand" ""))] 3680 "reload_completed" 3681 [(const_int 0)] 3682{ 3683 split_double_mode (DImode, &operands[0], 1, &operands[3], &operands[4]); 3684 3685 emit_move_insn (operands[3], operands[1]); 3686 3687 /* Generate a cltd if possible and doing so it profitable. */ 3688 if ((optimize_function_for_size_p (cfun) || TARGET_USE_CLTD) 3689 && true_regnum (operands[1]) == AX_REG 3690 && true_regnum (operands[2]) == DX_REG) 3691 { 3692 emit_insn (gen_ashrsi3_cvt (operands[2], operands[1], GEN_INT (31))); 3693 } 3694 else 3695 { 3696 emit_move_insn (operands[2], operands[1]); 3697 emit_insn (gen_ashrsi3_cvt (operands[2], operands[2], GEN_INT (31))); 3698 } 3699 emit_move_insn (operands[4], operands[2]); 3700 DONE; 3701}) 3702 3703;; Extend to register case. Optimize case where source and destination 3704;; registers match and cases where we can use cltd. 3705(define_split 3706 [(set (match_operand:DI 0 "register_operand" "") 3707 (sign_extend:DI (match_operand:SI 1 "register_operand" ""))) 3708 (clobber (reg:CC FLAGS_REG)) 3709 (clobber (match_scratch:SI 2 ""))] 3710 "reload_completed" 3711 [(const_int 0)] 3712{ 3713 split_double_mode (DImode, &operands[0], 1, &operands[3], &operands[4]); 3714 3715 if (true_regnum (operands[3]) != true_regnum (operands[1])) 3716 emit_move_insn (operands[3], operands[1]); 3717 3718 /* Generate a cltd if possible and doing so it profitable. */ 3719 if ((optimize_function_for_size_p (cfun) || TARGET_USE_CLTD) 3720 && true_regnum (operands[3]) == AX_REG 3721 && true_regnum (operands[4]) == DX_REG) 3722 { 3723 emit_insn (gen_ashrsi3_cvt (operands[4], operands[3], GEN_INT (31))); 3724 DONE; 3725 } 3726 3727 if (true_regnum (operands[4]) != true_regnum (operands[1])) 3728 emit_move_insn (operands[4], operands[1]); 3729 3730 emit_insn (gen_ashrsi3_cvt (operands[4], operands[4], GEN_INT (31))); 3731 DONE; 3732}) 3733 3734(define_insn "extend<mode>di2" 3735 [(set (match_operand:DI 0 "register_operand" "=r") 3736 (sign_extend:DI 3737 (match_operand:SWI12 1 "nonimmediate_operand" "<r>m")))] 3738 "TARGET_64BIT" 3739 "movs{<imodesuffix>q|x}\t{%1, %0|%0, %1}" 3740 [(set_attr "type" "imovx") 3741 (set_attr "mode" "DI")]) 3742 3743(define_insn "extendhisi2" 3744 [(set (match_operand:SI 0 "register_operand" "=*a,r") 3745 (sign_extend:SI (match_operand:HI 1 "nonimmediate_operand" "*0,rm")))] 3746 "" 3747{ 3748 switch (get_attr_prefix_0f (insn)) 3749 { 3750 case 0: 3751 return "{cwtl|cwde}"; 3752 default: 3753 return "movs{wl|x}\t{%1, %0|%0, %1}"; 3754 } 3755} 3756 [(set_attr "type" "imovx") 3757 (set_attr "mode" "SI") 3758 (set (attr "prefix_0f") 3759 ;; movsx is short decodable while cwtl is vector decoded. 3760 (if_then_else (and (eq_attr "cpu" "!k6") 3761 (eq_attr "alternative" "0")) 3762 (const_string "0") 3763 (const_string "1"))) 3764 (set (attr "modrm") 3765 (if_then_else (eq_attr "prefix_0f" "0") 3766 (const_string "0") 3767 (const_string "1")))]) 3768 3769(define_insn "*extendhisi2_zext" 3770 [(set (match_operand:DI 0 "register_operand" "=*a,r") 3771 (zero_extend:DI 3772 (sign_extend:SI 3773 (match_operand:HI 1 "nonimmediate_operand" "*0,rm"))))] 3774 "TARGET_64BIT" 3775{ 3776 switch (get_attr_prefix_0f (insn)) 3777 { 3778 case 0: 3779 return "{cwtl|cwde}"; 3780 default: 3781 return "movs{wl|x}\t{%1, %k0|%k0, %1}"; 3782 } 3783} 3784 [(set_attr "type" "imovx") 3785 (set_attr "mode" "SI") 3786 (set (attr "prefix_0f") 3787 ;; movsx is short decodable while cwtl is vector decoded. 3788 (if_then_else (and (eq_attr "cpu" "!k6") 3789 (eq_attr "alternative" "0")) 3790 (const_string "0") 3791 (const_string "1"))) 3792 (set (attr "modrm") 3793 (if_then_else (eq_attr "prefix_0f" "0") 3794 (const_string "0") 3795 (const_string "1")))]) 3796 3797(define_insn "extendqisi2" 3798 [(set (match_operand:SI 0 "register_operand" "=r") 3799 (sign_extend:SI (match_operand:QI 1 "nonimmediate_operand" "qm")))] 3800 "" 3801 "movs{bl|x}\t{%1, %0|%0, %1}" 3802 [(set_attr "type" "imovx") 3803 (set_attr "mode" "SI")]) 3804 3805(define_insn "*extendqisi2_zext" 3806 [(set (match_operand:DI 0 "register_operand" "=r") 3807 (zero_extend:DI 3808 (sign_extend:SI (match_operand:QI 1 "nonimmediate_operand" "qm"))))] 3809 "TARGET_64BIT" 3810 "movs{bl|x}\t{%1, %k0|%k0, %1}" 3811 [(set_attr "type" "imovx") 3812 (set_attr "mode" "SI")]) 3813 3814(define_insn "extendqihi2" 3815 [(set (match_operand:HI 0 "register_operand" "=*a,r") 3816 (sign_extend:HI (match_operand:QI 1 "nonimmediate_operand" "*0,qm")))] 3817 "" 3818{ 3819 switch (get_attr_prefix_0f (insn)) 3820 { 3821 case 0: 3822 return "{cbtw|cbw}"; 3823 default: 3824 return "movs{bw|x}\t{%1, %0|%0, %1}"; 3825 } 3826} 3827 [(set_attr "type" "imovx") 3828 (set_attr "mode" "HI") 3829 (set (attr "prefix_0f") 3830 ;; movsx is short decodable while cwtl is vector decoded. 3831 (if_then_else (and (eq_attr "cpu" "!k6") 3832 (eq_attr "alternative" "0")) 3833 (const_string "0") 3834 (const_string "1"))) 3835 (set (attr "modrm") 3836 (if_then_else (eq_attr "prefix_0f" "0") 3837 (const_string "0") 3838 (const_string "1")))]) 3839 3840;; Conversions between float and double. 3841 3842;; These are all no-ops in the model used for the 80387. 3843;; So just emit moves. 3844 3845;; %%% Kill these when call knows how to work out a DFmode push earlier. 3846(define_split 3847 [(set (match_operand:DF 0 "push_operand" "") 3848 (float_extend:DF (match_operand:SF 1 "fp_register_operand" "")))] 3849 "reload_completed" 3850 [(set (reg:P SP_REG) (plus:P (reg:P SP_REG) (const_int -8))) 3851 (set (mem:DF (reg:P SP_REG)) (float_extend:DF (match_dup 1)))]) 3852 3853(define_split 3854 [(set (match_operand:XF 0 "push_operand" "") 3855 (float_extend:XF (match_operand:MODEF 1 "fp_register_operand" "")))] 3856 "reload_completed" 3857 [(set (reg:P SP_REG) (plus:P (reg:P SP_REG) (match_dup 2))) 3858 (set (mem:XF (reg:P SP_REG)) (float_extend:XF (match_dup 1)))] 3859 "operands[2] = GEN_INT (-GET_MODE_SIZE (XFmode));") 3860 3861(define_expand "extendsfdf2" 3862 [(set (match_operand:DF 0 "nonimmediate_operand" "") 3863 (float_extend:DF (match_operand:SF 1 "general_operand" "")))] 3864 "TARGET_80387 || (TARGET_SSE2 && TARGET_SSE_MATH)" 3865{ 3866 /* ??? Needed for compress_float_constant since all fp constants 3867 are TARGET_LEGITIMATE_CONSTANT_P. */ 3868 if (GET_CODE (operands[1]) == CONST_DOUBLE) 3869 { 3870 if ((!TARGET_SSE2 || TARGET_MIX_SSE_I387) 3871 && standard_80387_constant_p (operands[1]) > 0) 3872 { 3873 operands[1] = simplify_const_unary_operation 3874 (FLOAT_EXTEND, DFmode, operands[1], SFmode); 3875 emit_move_insn_1 (operands[0], operands[1]); 3876 DONE; 3877 } 3878 operands[1] = validize_mem (force_const_mem (SFmode, operands[1])); 3879 } 3880}) 3881 3882/* For converting SF(xmm2) to DF(xmm1), use the following code instead of 3883 cvtss2sd: 3884 unpcklps xmm2,xmm2 ; packed conversion might crash on signaling NaNs 3885 cvtps2pd xmm2,xmm1 3886 We do the conversion post reload to avoid producing of 128bit spills 3887 that might lead to ICE on 32bit target. The sequence unlikely combine 3888 anyway. */ 3889(define_split 3890 [(set (match_operand:DF 0 "register_operand" "") 3891 (float_extend:DF 3892 (match_operand:SF 1 "nonimmediate_operand" "")))] 3893 "TARGET_USE_VECTOR_FP_CONVERTS 3894 && optimize_insn_for_speed_p () 3895 && reload_completed && SSE_REG_P (operands[0])" 3896 [(set (match_dup 2) 3897 (float_extend:V2DF 3898 (vec_select:V2SF 3899 (match_dup 3) 3900 (parallel [(const_int 0) (const_int 1)]))))] 3901{ 3902 operands[2] = simplify_gen_subreg (V2DFmode, operands[0], DFmode, 0); 3903 operands[3] = simplify_gen_subreg (V4SFmode, operands[0], DFmode, 0); 3904 /* Use movss for loading from memory, unpcklps reg, reg for registers. 3905 Try to avoid move when unpacking can be done in source. */ 3906 if (REG_P (operands[1])) 3907 { 3908 /* If it is unsafe to overwrite upper half of source, we need 3909 to move to destination and unpack there. */ 3910 if ((ORIGINAL_REGNO (operands[1]) < FIRST_PSEUDO_REGISTER 3911 || PSEUDO_REGNO_BYTES (ORIGINAL_REGNO (operands[1])) > 4) 3912 && true_regnum (operands[0]) != true_regnum (operands[1])) 3913 { 3914 rtx tmp = gen_rtx_REG (SFmode, true_regnum (operands[0])); 3915 emit_move_insn (tmp, operands[1]); 3916 } 3917 else 3918 operands[3] = simplify_gen_subreg (V4SFmode, operands[1], SFmode, 0); 3919 emit_insn (gen_vec_interleave_lowv4sf (operands[3], operands[3], 3920 operands[3])); 3921 } 3922 else 3923 emit_insn (gen_vec_setv4sf_0 (operands[3], 3924 CONST0_RTX (V4SFmode), operands[1])); 3925}) 3926 3927(define_insn "*extendsfdf2_mixed" 3928 [(set (match_operand:DF 0 "nonimmediate_operand" "=f,m,x") 3929 (float_extend:DF 3930 (match_operand:SF 1 "nonimmediate_operand" "fm,f,xm")))] 3931 "TARGET_SSE2 && TARGET_MIX_SSE_I387" 3932{ 3933 switch (which_alternative) 3934 { 3935 case 0: 3936 case 1: 3937 return output_387_reg_move (insn, operands); 3938 3939 case 2: 3940 return "%vcvtss2sd\t{%1, %d0|%d0, %1}"; 3941 3942 default: 3943 gcc_unreachable (); 3944 } 3945} 3946 [(set_attr "type" "fmov,fmov,ssecvt") 3947 (set_attr "prefix" "orig,orig,maybe_vex") 3948 (set_attr "mode" "SF,XF,DF")]) 3949 3950(define_insn "*extendsfdf2_sse" 3951 [(set (match_operand:DF 0 "nonimmediate_operand" "=x") 3952 (float_extend:DF (match_operand:SF 1 "nonimmediate_operand" "xm")))] 3953 "TARGET_SSE2 && TARGET_SSE_MATH" 3954 "%vcvtss2sd\t{%1, %d0|%d0, %1}" 3955 [(set_attr "type" "ssecvt") 3956 (set_attr "prefix" "maybe_vex") 3957 (set_attr "mode" "DF")]) 3958 3959(define_insn "*extendsfdf2_i387" 3960 [(set (match_operand:DF 0 "nonimmediate_operand" "=f,m") 3961 (float_extend:DF (match_operand:SF 1 "nonimmediate_operand" "fm,f")))] 3962 "TARGET_80387" 3963 "* return output_387_reg_move (insn, operands);" 3964 [(set_attr "type" "fmov") 3965 (set_attr "mode" "SF,XF")]) 3966 3967(define_expand "extend<mode>xf2" 3968 [(set (match_operand:XF 0 "nonimmediate_operand" "") 3969 (float_extend:XF (match_operand:MODEF 1 "general_operand" "")))] 3970 "TARGET_80387" 3971{ 3972 /* ??? Needed for compress_float_constant since all fp constants 3973 are TARGET_LEGITIMATE_CONSTANT_P. */ 3974 if (GET_CODE (operands[1]) == CONST_DOUBLE) 3975 { 3976 if (standard_80387_constant_p (operands[1]) > 0) 3977 { 3978 operands[1] = simplify_const_unary_operation 3979 (FLOAT_EXTEND, XFmode, operands[1], <MODE>mode); 3980 emit_move_insn_1 (operands[0], operands[1]); 3981 DONE; 3982 } 3983 operands[1] = validize_mem (force_const_mem (<MODE>mode, operands[1])); 3984 } 3985}) 3986 3987(define_insn "*extend<mode>xf2_i387" 3988 [(set (match_operand:XF 0 "nonimmediate_operand" "=f,m") 3989 (float_extend:XF 3990 (match_operand:MODEF 1 "nonimmediate_operand" "fm,f")))] 3991 "TARGET_80387" 3992 "* return output_387_reg_move (insn, operands);" 3993 [(set_attr "type" "fmov") 3994 (set_attr "mode" "<MODE>,XF")]) 3995 3996;; %%% This seems bad bad news. 3997;; This cannot output into an f-reg because there is no way to be sure 3998;; of truncating in that case. Otherwise this is just like a simple move 3999;; insn. So we pretend we can output to a reg in order to get better 4000;; register preferencing, but we really use a stack slot. 4001 4002;; Conversion from DFmode to SFmode. 4003 4004(define_expand "truncdfsf2" 4005 [(set (match_operand:SF 0 "nonimmediate_operand" "") 4006 (float_truncate:SF 4007 (match_operand:DF 1 "nonimmediate_operand" "")))] 4008 "TARGET_80387 || (TARGET_SSE2 && TARGET_SSE_MATH)" 4009{ 4010 if (TARGET_SSE2 && TARGET_SSE_MATH && !TARGET_MIX_SSE_I387) 4011 ; 4012 else if (flag_unsafe_math_optimizations) 4013 ; 4014 else 4015 { 4016 rtx temp = assign_386_stack_local (SFmode, SLOT_TEMP); 4017 emit_insn (gen_truncdfsf2_with_temp (operands[0], operands[1], temp)); 4018 DONE; 4019 } 4020}) 4021 4022/* For converting DF(xmm2) to SF(xmm1), use the following code instead of 4023 cvtsd2ss: 4024 unpcklpd xmm2,xmm2 ; packed conversion might crash on signaling NaNs 4025 cvtpd2ps xmm2,xmm1 4026 We do the conversion post reload to avoid producing of 128bit spills 4027 that might lead to ICE on 32bit target. The sequence unlikely combine 4028 anyway. */ 4029(define_split 4030 [(set (match_operand:SF 0 "register_operand" "") 4031 (float_truncate:SF 4032 (match_operand:DF 1 "nonimmediate_operand" "")))] 4033 "TARGET_USE_VECTOR_FP_CONVERTS 4034 && optimize_insn_for_speed_p () 4035 && reload_completed && SSE_REG_P (operands[0])" 4036 [(set (match_dup 2) 4037 (vec_concat:V4SF 4038 (float_truncate:V2SF 4039 (match_dup 4)) 4040 (match_dup 3)))] 4041{ 4042 operands[2] = simplify_gen_subreg (V4SFmode, operands[0], SFmode, 0); 4043 operands[3] = CONST0_RTX (V2SFmode); 4044 operands[4] = simplify_gen_subreg (V2DFmode, operands[0], SFmode, 0); 4045 /* Use movsd for loading from memory, unpcklpd for registers. 4046 Try to avoid move when unpacking can be done in source, or SSE3 4047 movddup is available. */ 4048 if (REG_P (operands[1])) 4049 { 4050 if (!TARGET_SSE3 4051 && true_regnum (operands[0]) != true_regnum (operands[1]) 4052 && (ORIGINAL_REGNO (operands[1]) < FIRST_PSEUDO_REGISTER 4053 || PSEUDO_REGNO_BYTES (ORIGINAL_REGNO (operands[1])) > 8)) 4054 { 4055 rtx tmp = simplify_gen_subreg (DFmode, operands[0], SFmode, 0); 4056 emit_move_insn (tmp, operands[1]); 4057 operands[1] = tmp; 4058 } 4059 else if (!TARGET_SSE3) 4060 operands[4] = simplify_gen_subreg (V2DFmode, operands[1], DFmode, 0); 4061 emit_insn (gen_vec_dupv2df (operands[4], operands[1])); 4062 } 4063 else 4064 emit_insn (gen_sse2_loadlpd (operands[4], 4065 CONST0_RTX (V2DFmode), operands[1])); 4066}) 4067 4068(define_expand "truncdfsf2_with_temp" 4069 [(parallel [(set (match_operand:SF 0 "" "") 4070 (float_truncate:SF (match_operand:DF 1 "" ""))) 4071 (clobber (match_operand:SF 2 "" ""))])]) 4072 4073(define_insn "*truncdfsf_fast_mixed" 4074 [(set (match_operand:SF 0 "nonimmediate_operand" "=fm,x") 4075 (float_truncate:SF 4076 (match_operand:DF 1 "nonimmediate_operand" "f ,xm")))] 4077 "TARGET_SSE2 && TARGET_MIX_SSE_I387 && flag_unsafe_math_optimizations" 4078{ 4079 switch (which_alternative) 4080 { 4081 case 0: 4082 return output_387_reg_move (insn, operands); 4083 case 1: 4084 return "%vcvtsd2ss\t{%1, %d0|%d0, %1}"; 4085 default: 4086 gcc_unreachable (); 4087 } 4088} 4089 [(set_attr "type" "fmov,ssecvt") 4090 (set_attr "prefix" "orig,maybe_vex") 4091 (set_attr "mode" "SF")]) 4092 4093;; Yes, this one doesn't depend on flag_unsafe_math_optimizations, 4094;; because nothing we do here is unsafe. 4095(define_insn "*truncdfsf_fast_sse" 4096 [(set (match_operand:SF 0 "nonimmediate_operand" "=x") 4097 (float_truncate:SF 4098 (match_operand:DF 1 "nonimmediate_operand" "xm")))] 4099 "TARGET_SSE2 && TARGET_SSE_MATH" 4100 "%vcvtsd2ss\t{%1, %d0|%d0, %1}" 4101 [(set_attr "type" "ssecvt") 4102 (set_attr "prefix" "maybe_vex") 4103 (set_attr "mode" "SF")]) 4104 4105(define_insn "*truncdfsf_fast_i387" 4106 [(set (match_operand:SF 0 "nonimmediate_operand" "=fm") 4107 (float_truncate:SF 4108 (match_operand:DF 1 "nonimmediate_operand" "f")))] 4109 "TARGET_80387 && flag_unsafe_math_optimizations" 4110 "* return output_387_reg_move (insn, operands);" 4111 [(set_attr "type" "fmov") 4112 (set_attr "mode" "SF")]) 4113 4114(define_insn "*truncdfsf_mixed" 4115 [(set (match_operand:SF 0 "nonimmediate_operand" "=m,x ,?f,?x,?*r") 4116 (float_truncate:SF 4117 (match_operand:DF 1 "nonimmediate_operand" "f ,xm,f ,f ,f"))) 4118 (clobber (match_operand:SF 2 "memory_operand" "=X,X ,m ,m ,m"))] 4119 "TARGET_MIX_SSE_I387" 4120{ 4121 switch (which_alternative) 4122 { 4123 case 0: 4124 return output_387_reg_move (insn, operands); 4125 case 1: 4126 return "%vcvtsd2ss\t{%1, %d0|%d0, %1}"; 4127 4128 default: 4129 return "#"; 4130 } 4131} 4132 [(set_attr "isa" "*,sse2,*,*,*") 4133 (set_attr "type" "fmov,ssecvt,multi,multi,multi") 4134 (set_attr "unit" "*,*,i387,i387,i387") 4135 (set_attr "prefix" "orig,maybe_vex,orig,orig,orig") 4136 (set_attr "mode" "SF")]) 4137 4138(define_insn "*truncdfsf_i387" 4139 [(set (match_operand:SF 0 "nonimmediate_operand" "=m,?f,?x,?*r") 4140 (float_truncate:SF 4141 (match_operand:DF 1 "nonimmediate_operand" "f ,f ,f ,f"))) 4142 (clobber (match_operand:SF 2 "memory_operand" "=X,m ,m ,m"))] 4143 "TARGET_80387" 4144{ 4145 switch (which_alternative) 4146 { 4147 case 0: 4148 return output_387_reg_move (insn, operands); 4149 4150 default: 4151 return "#"; 4152 } 4153} 4154 [(set_attr "type" "fmov,multi,multi,multi") 4155 (set_attr "unit" "*,i387,i387,i387") 4156 (set_attr "mode" "SF")]) 4157 4158(define_insn "*truncdfsf2_i387_1" 4159 [(set (match_operand:SF 0 "memory_operand" "=m") 4160 (float_truncate:SF 4161 (match_operand:DF 1 "register_operand" "f")))] 4162 "TARGET_80387 4163 && !(TARGET_SSE2 && TARGET_SSE_MATH) 4164 && !TARGET_MIX_SSE_I387" 4165 "* return output_387_reg_move (insn, operands);" 4166 [(set_attr "type" "fmov") 4167 (set_attr "mode" "SF")]) 4168 4169(define_split 4170 [(set (match_operand:SF 0 "register_operand" "") 4171 (float_truncate:SF 4172 (match_operand:DF 1 "fp_register_operand" ""))) 4173 (clobber (match_operand 2 "" ""))] 4174 "reload_completed" 4175 [(set (match_dup 2) (match_dup 1)) 4176 (set (match_dup 0) (match_dup 2))] 4177 "operands[1] = gen_rtx_REG (SFmode, true_regnum (operands[1]));") 4178 4179;; Conversion from XFmode to {SF,DF}mode 4180 4181(define_expand "truncxf<mode>2" 4182 [(parallel [(set (match_operand:MODEF 0 "nonimmediate_operand" "") 4183 (float_truncate:MODEF 4184 (match_operand:XF 1 "register_operand" ""))) 4185 (clobber (match_dup 2))])] 4186 "TARGET_80387" 4187{ 4188 if (flag_unsafe_math_optimizations) 4189 { 4190 rtx reg = REG_P (operands[0]) ? operands[0] : gen_reg_rtx (<MODE>mode); 4191 emit_insn (gen_truncxf<mode>2_i387_noop (reg, operands[1])); 4192 if (reg != operands[0]) 4193 emit_move_insn (operands[0], reg); 4194 DONE; 4195 } 4196 else 4197 operands[2] = assign_386_stack_local (<MODE>mode, SLOT_TEMP); 4198}) 4199 4200(define_insn "*truncxfsf2_mixed" 4201 [(set (match_operand:SF 0 "nonimmediate_operand" "=m,?f,?x,?*r") 4202 (float_truncate:SF 4203 (match_operand:XF 1 "register_operand" "f ,f ,f ,f"))) 4204 (clobber (match_operand:SF 2 "memory_operand" "=X,m ,m ,m"))] 4205 "TARGET_80387" 4206{ 4207 gcc_assert (!which_alternative); 4208 return output_387_reg_move (insn, operands); 4209} 4210 [(set_attr "type" "fmov,multi,multi,multi") 4211 (set_attr "unit" "*,i387,i387,i387") 4212 (set_attr "mode" "SF")]) 4213 4214(define_insn "*truncxfdf2_mixed" 4215 [(set (match_operand:DF 0 "nonimmediate_operand" "=m,?f,?x,?*r") 4216 (float_truncate:DF 4217 (match_operand:XF 1 "register_operand" "f ,f ,f ,f"))) 4218 (clobber (match_operand:DF 2 "memory_operand" "=X,m ,m ,m"))] 4219 "TARGET_80387" 4220{ 4221 gcc_assert (!which_alternative); 4222 return output_387_reg_move (insn, operands); 4223} 4224 [(set_attr "isa" "*,*,sse2,*") 4225 (set_attr "type" "fmov,multi,multi,multi") 4226 (set_attr "unit" "*,i387,i387,i387") 4227 (set_attr "mode" "DF")]) 4228 4229(define_insn "truncxf<mode>2_i387_noop" 4230 [(set (match_operand:MODEF 0 "register_operand" "=f") 4231 (float_truncate:MODEF 4232 (match_operand:XF 1 "register_operand" "f")))] 4233 "TARGET_80387 && flag_unsafe_math_optimizations" 4234 "* return output_387_reg_move (insn, operands);" 4235 [(set_attr "type" "fmov") 4236 (set_attr "mode" "<MODE>")]) 4237 4238(define_insn "*truncxf<mode>2_i387" 4239 [(set (match_operand:MODEF 0 "memory_operand" "=m") 4240 (float_truncate:MODEF 4241 (match_operand:XF 1 "register_operand" "f")))] 4242 "TARGET_80387" 4243 "* return output_387_reg_move (insn, operands);" 4244 [(set_attr "type" "fmov") 4245 (set_attr "mode" "<MODE>")]) 4246 4247(define_split 4248 [(set (match_operand:MODEF 0 "register_operand" "") 4249 (float_truncate:MODEF 4250 (match_operand:XF 1 "register_operand" ""))) 4251 (clobber (match_operand:MODEF 2 "memory_operand" ""))] 4252 "TARGET_80387 && reload_completed" 4253 [(set (match_dup 2) (float_truncate:MODEF (match_dup 1))) 4254 (set (match_dup 0) (match_dup 2))]) 4255 4256(define_split 4257 [(set (match_operand:MODEF 0 "memory_operand" "") 4258 (float_truncate:MODEF 4259 (match_operand:XF 1 "register_operand" ""))) 4260 (clobber (match_operand:MODEF 2 "memory_operand" ""))] 4261 "TARGET_80387" 4262 [(set (match_dup 0) (float_truncate:MODEF (match_dup 1)))]) 4263 4264;; Signed conversion to DImode. 4265 4266(define_expand "fix_truncxfdi2" 4267 [(parallel [(set (match_operand:DI 0 "nonimmediate_operand" "") 4268 (fix:DI (match_operand:XF 1 "register_operand" ""))) 4269 (clobber (reg:CC FLAGS_REG))])] 4270 "TARGET_80387" 4271{ 4272 if (TARGET_FISTTP) 4273 { 4274 emit_insn (gen_fix_truncdi_fisttp_i387_1 (operands[0], operands[1])); 4275 DONE; 4276 } 4277}) 4278 4279(define_expand "fix_trunc<mode>di2" 4280 [(parallel [(set (match_operand:DI 0 "nonimmediate_operand" "") 4281 (fix:DI (match_operand:MODEF 1 "register_operand" ""))) 4282 (clobber (reg:CC FLAGS_REG))])] 4283 "TARGET_80387 || (TARGET_64BIT && SSE_FLOAT_MODE_P (<MODE>mode))" 4284{ 4285 if (TARGET_FISTTP 4286 && !(TARGET_64BIT && SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)) 4287 { 4288 emit_insn (gen_fix_truncdi_fisttp_i387_1 (operands[0], operands[1])); 4289 DONE; 4290 } 4291 if (TARGET_64BIT && SSE_FLOAT_MODE_P (<MODE>mode)) 4292 { 4293 rtx out = REG_P (operands[0]) ? operands[0] : gen_reg_rtx (DImode); 4294 emit_insn (gen_fix_trunc<mode>di_sse (out, operands[1])); 4295 if (out != operands[0]) 4296 emit_move_insn (operands[0], out); 4297 DONE; 4298 } 4299}) 4300 4301;; Signed conversion to SImode. 4302 4303(define_expand "fix_truncxfsi2" 4304 [(parallel [(set (match_operand:SI 0 "nonimmediate_operand" "") 4305 (fix:SI (match_operand:XF 1 "register_operand" ""))) 4306 (clobber (reg:CC FLAGS_REG))])] 4307 "TARGET_80387" 4308{ 4309 if (TARGET_FISTTP) 4310 { 4311 emit_insn (gen_fix_truncsi_fisttp_i387_1 (operands[0], operands[1])); 4312 DONE; 4313 } 4314}) 4315 4316(define_expand "fix_trunc<mode>si2" 4317 [(parallel [(set (match_operand:SI 0 "nonimmediate_operand" "") 4318 (fix:SI (match_operand:MODEF 1 "register_operand" ""))) 4319 (clobber (reg:CC FLAGS_REG))])] 4320 "TARGET_80387 || SSE_FLOAT_MODE_P (<MODE>mode)" 4321{ 4322 if (TARGET_FISTTP 4323 && !(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)) 4324 { 4325 emit_insn (gen_fix_truncsi_fisttp_i387_1 (operands[0], operands[1])); 4326 DONE; 4327 } 4328 if (SSE_FLOAT_MODE_P (<MODE>mode)) 4329 { 4330 rtx out = REG_P (operands[0]) ? operands[0] : gen_reg_rtx (SImode); 4331 emit_insn (gen_fix_trunc<mode>si_sse (out, operands[1])); 4332 if (out != operands[0]) 4333 emit_move_insn (operands[0], out); 4334 DONE; 4335 } 4336}) 4337 4338;; Signed conversion to HImode. 4339 4340(define_expand "fix_trunc<mode>hi2" 4341 [(parallel [(set (match_operand:HI 0 "nonimmediate_operand" "") 4342 (fix:HI (match_operand:X87MODEF 1 "register_operand" ""))) 4343 (clobber (reg:CC FLAGS_REG))])] 4344 "TARGET_80387 4345 && !(SSE_FLOAT_MODE_P (<MODE>mode) && (!TARGET_FISTTP || TARGET_SSE_MATH))" 4346{ 4347 if (TARGET_FISTTP) 4348 { 4349 emit_insn (gen_fix_trunchi_fisttp_i387_1 (operands[0], operands[1])); 4350 DONE; 4351 } 4352}) 4353 4354;; Unsigned conversion to SImode. 4355 4356(define_expand "fixuns_trunc<mode>si2" 4357 [(parallel 4358 [(set (match_operand:SI 0 "register_operand" "") 4359 (unsigned_fix:SI 4360 (match_operand:MODEF 1 "nonimmediate_operand" ""))) 4361 (use (match_dup 2)) 4362 (clobber (match_scratch:<ssevecmode> 3 "")) 4363 (clobber (match_scratch:<ssevecmode> 4 ""))])] 4364 "!TARGET_64BIT && TARGET_SSE2 && TARGET_SSE_MATH" 4365{ 4366 enum machine_mode mode = <MODE>mode; 4367 enum machine_mode vecmode = <ssevecmode>mode; 4368 REAL_VALUE_TYPE TWO31r; 4369 rtx two31; 4370 4371 if (optimize_insn_for_size_p ()) 4372 FAIL; 4373 4374 real_ldexp (&TWO31r, &dconst1, 31); 4375 two31 = const_double_from_real_value (TWO31r, mode); 4376 two31 = ix86_build_const_vector (vecmode, true, two31); 4377 operands[2] = force_reg (vecmode, two31); 4378}) 4379 4380(define_insn_and_split "*fixuns_trunc<mode>_1" 4381 [(set (match_operand:SI 0 "register_operand" "=&x,&x") 4382 (unsigned_fix:SI 4383 (match_operand:MODEF 3 "nonimmediate_operand" "xm,xm"))) 4384 (use (match_operand:<ssevecmode> 4 "nonimmediate_operand" "m,x")) 4385 (clobber (match_scratch:<ssevecmode> 1 "=x,&x")) 4386 (clobber (match_scratch:<ssevecmode> 2 "=x,x"))] 4387 "!TARGET_64BIT && TARGET_SSE2 && TARGET_SSE_MATH 4388 && optimize_function_for_speed_p (cfun)" 4389 "#" 4390 "&& reload_completed" 4391 [(const_int 0)] 4392{ 4393 ix86_split_convert_uns_si_sse (operands); 4394 DONE; 4395}) 4396 4397;; Unsigned conversion to HImode. 4398;; Without these patterns, we'll try the unsigned SI conversion which 4399;; is complex for SSE, rather than the signed SI conversion, which isn't. 4400 4401(define_expand "fixuns_trunc<mode>hi2" 4402 [(set (match_dup 2) 4403 (fix:SI (match_operand:MODEF 1 "nonimmediate_operand" ""))) 4404 (set (match_operand:HI 0 "nonimmediate_operand" "") 4405 (subreg:HI (match_dup 2) 0))] 4406 "SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH" 4407 "operands[2] = gen_reg_rtx (SImode);") 4408 4409;; When SSE is available, it is always faster to use it! 4410(define_insn "fix_trunc<mode>di_sse" 4411 [(set (match_operand:DI 0 "register_operand" "=r,r") 4412 (fix:DI (match_operand:MODEF 1 "nonimmediate_operand" "x,m")))] 4413 "TARGET_64BIT && SSE_FLOAT_MODE_P (<MODE>mode) 4414 && (!TARGET_FISTTP || TARGET_SSE_MATH)" 4415 "%vcvtt<ssemodesuffix>2si{q}\t{%1, %0|%0, %1}" 4416 [(set_attr "type" "sseicvt") 4417 (set_attr "prefix" "maybe_vex") 4418 (set_attr "prefix_rex" "1") 4419 (set_attr "mode" "<MODE>") 4420 (set_attr "athlon_decode" "double,vector") 4421 (set_attr "amdfam10_decode" "double,double") 4422 (set_attr "bdver1_decode" "double,double")]) 4423 4424(define_insn "fix_trunc<mode>si_sse" 4425 [(set (match_operand:SI 0 "register_operand" "=r,r") 4426 (fix:SI (match_operand:MODEF 1 "nonimmediate_operand" "x,m")))] 4427 "SSE_FLOAT_MODE_P (<MODE>mode) 4428 && (!TARGET_FISTTP || TARGET_SSE_MATH)" 4429 "%vcvtt<ssemodesuffix>2si\t{%1, %0|%0, %1}" 4430 [(set_attr "type" "sseicvt") 4431 (set_attr "prefix" "maybe_vex") 4432 (set_attr "mode" "<MODE>") 4433 (set_attr "athlon_decode" "double,vector") 4434 (set_attr "amdfam10_decode" "double,double") 4435 (set_attr "bdver1_decode" "double,double")]) 4436 4437;; Shorten x87->SSE reload sequences of fix_trunc?f?i_sse patterns. 4438(define_peephole2 4439 [(set (match_operand:MODEF 0 "register_operand" "") 4440 (match_operand:MODEF 1 "memory_operand" "")) 4441 (set (match_operand:SWI48x 2 "register_operand" "") 4442 (fix:SWI48x (match_dup 0)))] 4443 "TARGET_SHORTEN_X87_SSE 4444 && !(TARGET_AVOID_VECTOR_DECODE && optimize_insn_for_speed_p ()) 4445 && peep2_reg_dead_p (2, operands[0])" 4446 [(set (match_dup 2) (fix:SWI48x (match_dup 1)))]) 4447 4448;; Avoid vector decoded forms of the instruction. 4449(define_peephole2 4450 [(match_scratch:DF 2 "x") 4451 (set (match_operand:SWI48x 0 "register_operand" "") 4452 (fix:SWI48x (match_operand:DF 1 "memory_operand" "")))] 4453 "TARGET_SSE2 && TARGET_AVOID_VECTOR_DECODE && optimize_insn_for_speed_p ()" 4454 [(set (match_dup 2) (match_dup 1)) 4455 (set (match_dup 0) (fix:SWI48x (match_dup 2)))]) 4456 4457(define_peephole2 4458 [(match_scratch:SF 2 "x") 4459 (set (match_operand:SWI48x 0 "register_operand" "") 4460 (fix:SWI48x (match_operand:SF 1 "memory_operand" "")))] 4461 "TARGET_AVOID_VECTOR_DECODE && optimize_insn_for_speed_p ()" 4462 [(set (match_dup 2) (match_dup 1)) 4463 (set (match_dup 0) (fix:SWI48x (match_dup 2)))]) 4464 4465(define_insn_and_split "fix_trunc<mode>_fisttp_i387_1" 4466 [(set (match_operand:SWI248x 0 "nonimmediate_operand" "") 4467 (fix:SWI248x (match_operand 1 "register_operand" "")))] 4468 "X87_FLOAT_MODE_P (GET_MODE (operands[1])) 4469 && TARGET_FISTTP 4470 && !((SSE_FLOAT_MODE_P (GET_MODE (operands[1])) 4471 && (TARGET_64BIT || <MODE>mode != DImode)) 4472 && TARGET_SSE_MATH) 4473 && can_create_pseudo_p ()" 4474 "#" 4475 "&& 1" 4476 [(const_int 0)] 4477{ 4478 if (memory_operand (operands[0], VOIDmode)) 4479 emit_insn (gen_fix_trunc<mode>_i387_fisttp (operands[0], operands[1])); 4480 else 4481 { 4482 operands[2] = assign_386_stack_local (<MODE>mode, SLOT_TEMP); 4483 emit_insn (gen_fix_trunc<mode>_i387_fisttp_with_temp (operands[0], 4484 operands[1], 4485 operands[2])); 4486 } 4487 DONE; 4488} 4489 [(set_attr "type" "fisttp") 4490 (set_attr "mode" "<MODE>")]) 4491 4492(define_insn "fix_trunc<mode>_i387_fisttp" 4493 [(set (match_operand:SWI248x 0 "memory_operand" "=m") 4494 (fix:SWI248x (match_operand 1 "register_operand" "f"))) 4495 (clobber (match_scratch:XF 2 "=&1f"))] 4496 "X87_FLOAT_MODE_P (GET_MODE (operands[1])) 4497 && TARGET_FISTTP 4498 && !((SSE_FLOAT_MODE_P (GET_MODE (operands[1])) 4499 && (TARGET_64BIT || <MODE>mode != DImode)) 4500 && TARGET_SSE_MATH)" 4501 "* return output_fix_trunc (insn, operands, true);" 4502 [(set_attr "type" "fisttp") 4503 (set_attr "mode" "<MODE>")]) 4504 4505(define_insn "fix_trunc<mode>_i387_fisttp_with_temp" 4506 [(set (match_operand:SWI248x 0 "nonimmediate_operand" "=m,?r") 4507 (fix:SWI248x (match_operand 1 "register_operand" "f,f"))) 4508 (clobber (match_operand:SWI248x 2 "memory_operand" "=X,m")) 4509 (clobber (match_scratch:XF 3 "=&1f,&1f"))] 4510 "X87_FLOAT_MODE_P (GET_MODE (operands[1])) 4511 && TARGET_FISTTP 4512 && !((SSE_FLOAT_MODE_P (GET_MODE (operands[1])) 4513 && (TARGET_64BIT || <MODE>mode != DImode)) 4514 && TARGET_SSE_MATH)" 4515 "#" 4516 [(set_attr "type" "fisttp") 4517 (set_attr "mode" "<MODE>")]) 4518 4519(define_split 4520 [(set (match_operand:SWI248x 0 "register_operand" "") 4521 (fix:SWI248x (match_operand 1 "register_operand" ""))) 4522 (clobber (match_operand:SWI248x 2 "memory_operand" "")) 4523 (clobber (match_scratch 3 ""))] 4524 "reload_completed" 4525 [(parallel [(set (match_dup 2) (fix:SWI248x (match_dup 1))) 4526 (clobber (match_dup 3))]) 4527 (set (match_dup 0) (match_dup 2))]) 4528 4529(define_split 4530 [(set (match_operand:SWI248x 0 "memory_operand" "") 4531 (fix:SWI248x (match_operand 1 "register_operand" ""))) 4532 (clobber (match_operand:SWI248x 2 "memory_operand" "")) 4533 (clobber (match_scratch 3 ""))] 4534 "reload_completed" 4535 [(parallel [(set (match_dup 0) (fix:SWI248x (match_dup 1))) 4536 (clobber (match_dup 3))])]) 4537 4538;; See the comments in i386.h near OPTIMIZE_MODE_SWITCHING for the description 4539;; of the machinery. Please note the clobber of FLAGS_REG. In i387 control 4540;; word calculation (inserted by LCM in mode switching pass) a FLAGS_REG 4541;; clobbering insns can be used. Look at emit_i387_cw_initialization () 4542;; function in i386.c. 4543(define_insn_and_split "*fix_trunc<mode>_i387_1" 4544 [(set (match_operand:SWI248x 0 "nonimmediate_operand" "") 4545 (fix:SWI248x (match_operand 1 "register_operand" ""))) 4546 (clobber (reg:CC FLAGS_REG))] 4547 "X87_FLOAT_MODE_P (GET_MODE (operands[1])) 4548 && !TARGET_FISTTP 4549 && !(SSE_FLOAT_MODE_P (GET_MODE (operands[1])) 4550 && (TARGET_64BIT || <MODE>mode != DImode)) 4551 && can_create_pseudo_p ()" 4552 "#" 4553 "&& 1" 4554 [(const_int 0)] 4555{ 4556 ix86_optimize_mode_switching[I387_TRUNC] = 1; 4557 4558 operands[2] = assign_386_stack_local (HImode, SLOT_CW_STORED); 4559 operands[3] = assign_386_stack_local (HImode, SLOT_CW_TRUNC); 4560 if (memory_operand (operands[0], VOIDmode)) 4561 emit_insn (gen_fix_trunc<mode>_i387 (operands[0], operands[1], 4562 operands[2], operands[3])); 4563 else 4564 { 4565 operands[4] = assign_386_stack_local (<MODE>mode, SLOT_TEMP); 4566 emit_insn (gen_fix_trunc<mode>_i387_with_temp (operands[0], operands[1], 4567 operands[2], operands[3], 4568 operands[4])); 4569 } 4570 DONE; 4571} 4572 [(set_attr "type" "fistp") 4573 (set_attr "i387_cw" "trunc") 4574 (set_attr "mode" "<MODE>")]) 4575 4576(define_insn "fix_truncdi_i387" 4577 [(set (match_operand:DI 0 "memory_operand" "=m") 4578 (fix:DI (match_operand 1 "register_operand" "f"))) 4579 (use (match_operand:HI 2 "memory_operand" "m")) 4580 (use (match_operand:HI 3 "memory_operand" "m")) 4581 (clobber (match_scratch:XF 4 "=&1f"))] 4582 "X87_FLOAT_MODE_P (GET_MODE (operands[1])) 4583 && !TARGET_FISTTP 4584 && !(TARGET_64BIT && SSE_FLOAT_MODE_P (GET_MODE (operands[1])))" 4585 "* return output_fix_trunc (insn, operands, false);" 4586 [(set_attr "type" "fistp") 4587 (set_attr "i387_cw" "trunc") 4588 (set_attr "mode" "DI")]) 4589 4590(define_insn "fix_truncdi_i387_with_temp" 4591 [(set (match_operand:DI 0 "nonimmediate_operand" "=m,?r") 4592 (fix:DI (match_operand 1 "register_operand" "f,f"))) 4593 (use (match_operand:HI 2 "memory_operand" "m,m")) 4594 (use (match_operand:HI 3 "memory_operand" "m,m")) 4595 (clobber (match_operand:DI 4 "memory_operand" "=X,m")) 4596 (clobber (match_scratch:XF 5 "=&1f,&1f"))] 4597 "X87_FLOAT_MODE_P (GET_MODE (operands[1])) 4598 && !TARGET_FISTTP 4599 && !(TARGET_64BIT && SSE_FLOAT_MODE_P (GET_MODE (operands[1])))" 4600 "#" 4601 [(set_attr "type" "fistp") 4602 (set_attr "i387_cw" "trunc") 4603 (set_attr "mode" "DI")]) 4604 4605(define_split 4606 [(set (match_operand:DI 0 "register_operand" "") 4607 (fix:DI (match_operand 1 "register_operand" ""))) 4608 (use (match_operand:HI 2 "memory_operand" "")) 4609 (use (match_operand:HI 3 "memory_operand" "")) 4610 (clobber (match_operand:DI 4 "memory_operand" "")) 4611 (clobber (match_scratch 5 ""))] 4612 "reload_completed" 4613 [(parallel [(set (match_dup 4) (fix:DI (match_dup 1))) 4614 (use (match_dup 2)) 4615 (use (match_dup 3)) 4616 (clobber (match_dup 5))]) 4617 (set (match_dup 0) (match_dup 4))]) 4618 4619(define_split 4620 [(set (match_operand:DI 0 "memory_operand" "") 4621 (fix:DI (match_operand 1 "register_operand" ""))) 4622 (use (match_operand:HI 2 "memory_operand" "")) 4623 (use (match_operand:HI 3 "memory_operand" "")) 4624 (clobber (match_operand:DI 4 "memory_operand" "")) 4625 (clobber (match_scratch 5 ""))] 4626 "reload_completed" 4627 [(parallel [(set (match_dup 0) (fix:DI (match_dup 1))) 4628 (use (match_dup 2)) 4629 (use (match_dup 3)) 4630 (clobber (match_dup 5))])]) 4631 4632(define_insn "fix_trunc<mode>_i387" 4633 [(set (match_operand:SWI24 0 "memory_operand" "=m") 4634 (fix:SWI24 (match_operand 1 "register_operand" "f"))) 4635 (use (match_operand:HI 2 "memory_operand" "m")) 4636 (use (match_operand:HI 3 "memory_operand" "m"))] 4637 "X87_FLOAT_MODE_P (GET_MODE (operands[1])) 4638 && !TARGET_FISTTP 4639 && !SSE_FLOAT_MODE_P (GET_MODE (operands[1]))" 4640 "* return output_fix_trunc (insn, operands, false);" 4641 [(set_attr "type" "fistp") 4642 (set_attr "i387_cw" "trunc") 4643 (set_attr "mode" "<MODE>")]) 4644 4645(define_insn "fix_trunc<mode>_i387_with_temp" 4646 [(set (match_operand:SWI24 0 "nonimmediate_operand" "=m,?r") 4647 (fix:SWI24 (match_operand 1 "register_operand" "f,f"))) 4648 (use (match_operand:HI 2 "memory_operand" "m,m")) 4649 (use (match_operand:HI 3 "memory_operand" "m,m")) 4650 (clobber (match_operand:SWI24 4 "memory_operand" "=X,m"))] 4651 "X87_FLOAT_MODE_P (GET_MODE (operands[1])) 4652 && !TARGET_FISTTP 4653 && !SSE_FLOAT_MODE_P (GET_MODE (operands[1]))" 4654 "#" 4655 [(set_attr "type" "fistp") 4656 (set_attr "i387_cw" "trunc") 4657 (set_attr "mode" "<MODE>")]) 4658 4659(define_split 4660 [(set (match_operand:SWI24 0 "register_operand" "") 4661 (fix:SWI24 (match_operand 1 "register_operand" ""))) 4662 (use (match_operand:HI 2 "memory_operand" "")) 4663 (use (match_operand:HI 3 "memory_operand" "")) 4664 (clobber (match_operand:SWI24 4 "memory_operand" ""))] 4665 "reload_completed" 4666 [(parallel [(set (match_dup 4) (fix:SWI24 (match_dup 1))) 4667 (use (match_dup 2)) 4668 (use (match_dup 3))]) 4669 (set (match_dup 0) (match_dup 4))]) 4670 4671(define_split 4672 [(set (match_operand:SWI24 0 "memory_operand" "") 4673 (fix:SWI24 (match_operand 1 "register_operand" ""))) 4674 (use (match_operand:HI 2 "memory_operand" "")) 4675 (use (match_operand:HI 3 "memory_operand" "")) 4676 (clobber (match_operand:SWI24 4 "memory_operand" ""))] 4677 "reload_completed" 4678 [(parallel [(set (match_dup 0) (fix:SWI24 (match_dup 1))) 4679 (use (match_dup 2)) 4680 (use (match_dup 3))])]) 4681 4682(define_insn "x86_fnstcw_1" 4683 [(set (match_operand:HI 0 "memory_operand" "=m") 4684 (unspec:HI [(reg:HI FPCR_REG)] UNSPEC_FSTCW))] 4685 "TARGET_80387" 4686 "fnstcw\t%0" 4687 [(set (attr "length") 4688 (symbol_ref "ix86_attr_length_address_default (insn) + 2")) 4689 (set_attr "mode" "HI") 4690 (set_attr "unit" "i387") 4691 (set_attr "bdver1_decode" "vector")]) 4692 4693(define_insn "x86_fldcw_1" 4694 [(set (reg:HI FPCR_REG) 4695 (unspec:HI [(match_operand:HI 0 "memory_operand" "m")] UNSPEC_FLDCW))] 4696 "TARGET_80387" 4697 "fldcw\t%0" 4698 [(set (attr "length") 4699 (symbol_ref "ix86_attr_length_address_default (insn) + 2")) 4700 (set_attr "mode" "HI") 4701 (set_attr "unit" "i387") 4702 (set_attr "athlon_decode" "vector") 4703 (set_attr "amdfam10_decode" "vector") 4704 (set_attr "bdver1_decode" "vector")]) 4705 4706;; Conversion between fixed point and floating point. 4707 4708;; Even though we only accept memory inputs, the backend _really_ 4709;; wants to be able to do this between registers. 4710 4711(define_expand "floathi<mode>2" 4712 [(set (match_operand:X87MODEF 0 "register_operand" "") 4713 (float:X87MODEF (match_operand:HI 1 "nonimmediate_operand" "")))] 4714 "TARGET_80387 4715 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH) 4716 || TARGET_MIX_SSE_I387)") 4717 4718;; Pre-reload splitter to add memory clobber to the pattern. 4719(define_insn_and_split "*floathi<mode>2_1" 4720 [(set (match_operand:X87MODEF 0 "register_operand" "") 4721 (float:X87MODEF (match_operand:HI 1 "register_operand" "")))] 4722 "TARGET_80387 4723 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH) 4724 || TARGET_MIX_SSE_I387) 4725 && can_create_pseudo_p ()" 4726 "#" 4727 "&& 1" 4728 [(parallel [(set (match_dup 0) 4729 (float:X87MODEF (match_dup 1))) 4730 (clobber (match_dup 2))])] 4731 "operands[2] = assign_386_stack_local (HImode, SLOT_TEMP);") 4732 4733(define_insn "*floathi<mode>2_i387_with_temp" 4734 [(set (match_operand:X87MODEF 0 "register_operand" "=f,f") 4735 (float:X87MODEF (match_operand:HI 1 "nonimmediate_operand" "m,?r"))) 4736 (clobber (match_operand:HI 2 "memory_operand" "=X,m"))] 4737 "TARGET_80387 4738 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH) 4739 || TARGET_MIX_SSE_I387)" 4740 "#" 4741 [(set_attr "type" "fmov,multi") 4742 (set_attr "mode" "<MODE>") 4743 (set_attr "unit" "*,i387") 4744 (set_attr "fp_int_src" "true")]) 4745 4746(define_insn "*floathi<mode>2_i387" 4747 [(set (match_operand:X87MODEF 0 "register_operand" "=f") 4748 (float:X87MODEF (match_operand:HI 1 "memory_operand" "m")))] 4749 "TARGET_80387 4750 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH) 4751 || TARGET_MIX_SSE_I387)" 4752 "fild%Z1\t%1" 4753 [(set_attr "type" "fmov") 4754 (set_attr "mode" "<MODE>") 4755 (set_attr "fp_int_src" "true")]) 4756 4757(define_split 4758 [(set (match_operand:X87MODEF 0 "register_operand" "") 4759 (float:X87MODEF (match_operand:HI 1 "register_operand" ""))) 4760 (clobber (match_operand:HI 2 "memory_operand" ""))] 4761 "TARGET_80387 4762 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH) 4763 || TARGET_MIX_SSE_I387) 4764 && reload_completed" 4765 [(set (match_dup 2) (match_dup 1)) 4766 (set (match_dup 0) (float:X87MODEF (match_dup 2)))]) 4767 4768(define_split 4769 [(set (match_operand:X87MODEF 0 "register_operand" "") 4770 (float:X87MODEF (match_operand:HI 1 "memory_operand" ""))) 4771 (clobber (match_operand:HI 2 "memory_operand" ""))] 4772 "TARGET_80387 4773 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH) 4774 || TARGET_MIX_SSE_I387) 4775 && reload_completed" 4776 [(set (match_dup 0) (float:X87MODEF (match_dup 1)))]) 4777 4778(define_expand "float<SWI48x:mode><X87MODEF:mode>2" 4779 [(set (match_operand:X87MODEF 0 "register_operand" "") 4780 (float:X87MODEF 4781 (match_operand:SWI48x 1 "nonimmediate_operand" "")))] 4782 "TARGET_80387 4783 || ((<SWI48x:MODE>mode != DImode || TARGET_64BIT) 4784 && SSE_FLOAT_MODE_P (<X87MODEF:MODE>mode) && TARGET_SSE_MATH)" 4785{ 4786 if (!((<SWI48x:MODE>mode != DImode || TARGET_64BIT) 4787 && SSE_FLOAT_MODE_P (<X87MODEF:MODE>mode) && TARGET_SSE_MATH) 4788 && !X87_ENABLE_FLOAT (<X87MODEF:MODE>mode, <SWI48x:MODE>mode)) 4789 { 4790 rtx reg = gen_reg_rtx (XFmode); 4791 rtx (*insn)(rtx, rtx); 4792 4793 emit_insn (gen_float<SWI48x:mode>xf2 (reg, operands[1])); 4794 4795 if (<X87MODEF:MODE>mode == SFmode) 4796 insn = gen_truncxfsf2; 4797 else if (<X87MODEF:MODE>mode == DFmode) 4798 insn = gen_truncxfdf2; 4799 else 4800 gcc_unreachable (); 4801 4802 emit_insn (insn (operands[0], reg)); 4803 DONE; 4804 } 4805}) 4806 4807;; Pre-reload splitter to add memory clobber to the pattern. 4808(define_insn_and_split "*float<SWI48x:mode><X87MODEF:mode>2_1" 4809 [(set (match_operand:X87MODEF 0 "register_operand" "") 4810 (float:X87MODEF (match_operand:SWI48x 1 "register_operand" "")))] 4811 "((TARGET_80387 4812 && X87_ENABLE_FLOAT (<X87MODEF:MODE>mode, <SWI48x:MODE>mode) 4813 && (!((<SWI48x:MODE>mode != DImode || TARGET_64BIT) 4814 && SSE_FLOAT_MODE_P (<X87MODEF:MODE>mode) && TARGET_SSE_MATH) 4815 || TARGET_MIX_SSE_I387)) 4816 || ((<SWI48x:MODE>mode != DImode || TARGET_64BIT) 4817 && SSE_FLOAT_MODE_P (<X87MODEF:MODE>mode) && TARGET_SSE_MATH 4818 && ((<SWI48x:MODE>mode == SImode 4819 && TARGET_SSE2 && TARGET_USE_VECTOR_CONVERTS 4820 && optimize_function_for_speed_p (cfun) 4821 && flag_trapping_math) 4822 || !(TARGET_INTER_UNIT_CONVERSIONS 4823 || optimize_function_for_size_p (cfun))))) 4824 && can_create_pseudo_p ()" 4825 "#" 4826 "&& 1" 4827 [(parallel [(set (match_dup 0) (float:X87MODEF (match_dup 1))) 4828 (clobber (match_dup 2))])] 4829{ 4830 operands[2] = assign_386_stack_local (<SWI48x:MODE>mode, SLOT_TEMP); 4831 4832 /* Avoid store forwarding (partial memory) stall penalty 4833 by passing DImode value through XMM registers. */ 4834 if (<SWI48x:MODE>mode == DImode && !TARGET_64BIT 4835 && TARGET_80387 && TARGET_SSE2 && TARGET_INTER_UNIT_MOVES 4836 && optimize_function_for_speed_p (cfun)) 4837 { 4838 emit_insn (gen_floatdi<X87MODEF:mode>2_i387_with_xmm (operands[0], 4839 operands[1], 4840 operands[2])); 4841 DONE; 4842 } 4843}) 4844 4845(define_insn "*floatsi<mode>2_vector_mixed_with_temp" 4846 [(set (match_operand:MODEF 0 "register_operand" "=f,f,x,x,x") 4847 (float:MODEF 4848 (match_operand:SI 1 "nonimmediate_operand" "m,?r,r,m,!x"))) 4849 (clobber (match_operand:SI 2 "memory_operand" "=X,m,m,X,m"))] 4850 "TARGET_SSE2 && TARGET_MIX_SSE_I387 4851 && TARGET_USE_VECTOR_CONVERTS && optimize_function_for_speed_p (cfun)" 4852 "#" 4853 [(set_attr "type" "fmov,multi,sseicvt,sseicvt,sseicvt") 4854 (set_attr "mode" "<MODE>,<MODE>,<MODE>,<MODE>,<ssevecmode>") 4855 (set_attr "unit" "*,i387,*,*,*") 4856 (set_attr "athlon_decode" "*,*,double,direct,double") 4857 (set_attr "amdfam10_decode" "*,*,vector,double,double") 4858 (set_attr "bdver1_decode" "*,*,double,direct,double") 4859 (set_attr "fp_int_src" "true")]) 4860 4861(define_insn "*floatsi<mode>2_vector_mixed" 4862 [(set (match_operand:MODEF 0 "register_operand" "=f,x") 4863 (float:MODEF (match_operand:SI 1 "memory_operand" "m,m")))] 4864 "TARGET_SSE2 && TARGET_MIX_SSE_I387 4865 && TARGET_USE_VECTOR_CONVERTS && optimize_function_for_speed_p (cfun)" 4866 "@ 4867 fild%Z1\t%1 4868 #" 4869 [(set_attr "type" "fmov,sseicvt") 4870 (set_attr "mode" "<MODE>,<ssevecmode>") 4871 (set_attr "unit" "i387,*") 4872 (set_attr "athlon_decode" "*,direct") 4873 (set_attr "amdfam10_decode" "*,double") 4874 (set_attr "bdver1_decode" "*,direct") 4875 (set_attr "fp_int_src" "true")]) 4876 4877(define_insn "*float<SWI48x:mode><MODEF:mode>2_mixed_with_temp" 4878 [(set (match_operand:MODEF 0 "register_operand" "=f,f,x,x") 4879 (float:MODEF 4880 (match_operand:SWI48x 1 "nonimmediate_operand" "m,?r,r,m"))) 4881 (clobber (match_operand:SWI48x 2 "memory_operand" "=X,m,m,X"))] 4882 "(<SWI48x:MODE>mode != DImode || TARGET_64BIT) 4883 && SSE_FLOAT_MODE_P (<MODEF:MODE>mode) && TARGET_MIX_SSE_I387" 4884 "#" 4885 [(set_attr "type" "fmov,multi,sseicvt,sseicvt") 4886 (set_attr "mode" "<MODEF:MODE>") 4887 (set_attr "unit" "*,i387,*,*") 4888 (set_attr "athlon_decode" "*,*,double,direct") 4889 (set_attr "amdfam10_decode" "*,*,vector,double") 4890 (set_attr "bdver1_decode" "*,*,double,direct") 4891 (set_attr "fp_int_src" "true")]) 4892 4893(define_split 4894 [(set (match_operand:MODEF 0 "register_operand" "") 4895 (float:MODEF (match_operand:SWI48x 1 "register_operand" ""))) 4896 (clobber (match_operand:SWI48x 2 "memory_operand" ""))] 4897 "(<SWI48x:MODE>mode != DImode || TARGET_64BIT) 4898 && SSE_FLOAT_MODE_P (<MODEF:MODE>mode) && TARGET_MIX_SSE_I387 4899 && TARGET_INTER_UNIT_CONVERSIONS 4900 && reload_completed 4901 && (SSE_REG_P (operands[0]) 4902 || (GET_CODE (operands[0]) == SUBREG 4903 && SSE_REG_P (SUBREG_REG (operands[0]))))" 4904 [(set (match_dup 0) (float:MODEF (match_dup 1)))]) 4905 4906(define_split 4907 [(set (match_operand:MODEF 0 "register_operand" "") 4908 (float:MODEF (match_operand:SWI48x 1 "register_operand" ""))) 4909 (clobber (match_operand:SWI48x 2 "memory_operand" ""))] 4910 "(<SWI48x:MODE>mode != DImode || TARGET_64BIT) 4911 && SSE_FLOAT_MODE_P (<MODEF:MODE>mode) && TARGET_MIX_SSE_I387 4912 && !(TARGET_INTER_UNIT_CONVERSIONS || optimize_function_for_size_p (cfun)) 4913 && reload_completed 4914 && (SSE_REG_P (operands[0]) 4915 || (GET_CODE (operands[0]) == SUBREG 4916 && SSE_REG_P (SUBREG_REG (operands[0]))))" 4917 [(set (match_dup 2) (match_dup 1)) 4918 (set (match_dup 0) (float:MODEF (match_dup 2)))]) 4919 4920(define_insn "*float<SWI48x:mode><MODEF:mode>2_mixed_interunit" 4921 [(set (match_operand:MODEF 0 "register_operand" "=f,x,x") 4922 (float:MODEF 4923 (match_operand:SWI48x 1 "nonimmediate_operand" "m,r,m")))] 4924 "(<SWI48x:MODE>mode != DImode || TARGET_64BIT) 4925 && SSE_FLOAT_MODE_P (<MODEF:MODE>mode) && TARGET_MIX_SSE_I387 4926 && (TARGET_INTER_UNIT_CONVERSIONS || optimize_function_for_size_p (cfun))" 4927 "@ 4928 fild%Z1\t%1 4929 %vcvtsi2<MODEF:ssemodesuffix><SWI48x:rex64suffix>\t{%1, %d0|%d0, %1} 4930 %vcvtsi2<MODEF:ssemodesuffix><SWI48x:rex64suffix>\t{%1, %d0|%d0, %1}" 4931 [(set_attr "type" "fmov,sseicvt,sseicvt") 4932 (set_attr "prefix" "orig,maybe_vex,maybe_vex") 4933 (set_attr "mode" "<MODEF:MODE>") 4934 (set (attr "prefix_rex") 4935 (if_then_else 4936 (and (eq_attr "prefix" "maybe_vex") 4937 (match_test "<SWI48x:MODE>mode == DImode")) 4938 (const_string "1") 4939 (const_string "*"))) 4940 (set_attr "unit" "i387,*,*") 4941 (set_attr "athlon_decode" "*,double,direct") 4942 (set_attr "amdfam10_decode" "*,vector,double") 4943 (set_attr "bdver1_decode" "*,double,direct") 4944 (set_attr "fp_int_src" "true")]) 4945 4946(define_insn "*float<SWI48x:mode><MODEF:mode>2_mixed_nointerunit" 4947 [(set (match_operand:MODEF 0 "register_operand" "=f,x") 4948 (float:MODEF 4949 (match_operand:SWI48x 1 "memory_operand" "m,m")))] 4950 "(<SWI48x:MODE>mode != DImode || TARGET_64BIT) 4951 && SSE_FLOAT_MODE_P (<MODEF:MODE>mode) && TARGET_MIX_SSE_I387 4952 && !(TARGET_INTER_UNIT_CONVERSIONS || optimize_function_for_size_p (cfun))" 4953 "@ 4954 fild%Z1\t%1 4955 %vcvtsi2<MODEF:ssemodesuffix><SWI48x:rex64suffix>\t{%1, %d0|%d0, %1}" 4956 [(set_attr "type" "fmov,sseicvt") 4957 (set_attr "prefix" "orig,maybe_vex") 4958 (set_attr "mode" "<MODEF:MODE>") 4959 (set (attr "prefix_rex") 4960 (if_then_else 4961 (and (eq_attr "prefix" "maybe_vex") 4962 (match_test "<SWI48x:MODE>mode == DImode")) 4963 (const_string "1") 4964 (const_string "*"))) 4965 (set_attr "athlon_decode" "*,direct") 4966 (set_attr "amdfam10_decode" "*,double") 4967 (set_attr "bdver1_decode" "*,direct") 4968 (set_attr "fp_int_src" "true")]) 4969 4970(define_insn "*floatsi<mode>2_vector_sse_with_temp" 4971 [(set (match_operand:MODEF 0 "register_operand" "=x,x,x") 4972 (float:MODEF 4973 (match_operand:SI 1 "nonimmediate_operand" "r,m,!x"))) 4974 (clobber (match_operand:SI 2 "memory_operand" "=m,X,m"))] 4975 "TARGET_SSE2 && TARGET_SSE_MATH 4976 && TARGET_USE_VECTOR_CONVERTS && optimize_function_for_speed_p (cfun)" 4977 "#" 4978 [(set_attr "type" "sseicvt") 4979 (set_attr "mode" "<MODE>,<MODE>,<ssevecmode>") 4980 (set_attr "athlon_decode" "double,direct,double") 4981 (set_attr "amdfam10_decode" "vector,double,double") 4982 (set_attr "bdver1_decode" "double,direct,double") 4983 (set_attr "fp_int_src" "true")]) 4984 4985(define_insn "*floatsi<mode>2_vector_sse" 4986 [(set (match_operand:MODEF 0 "register_operand" "=x") 4987 (float:MODEF (match_operand:SI 1 "memory_operand" "m")))] 4988 "TARGET_SSE2 && TARGET_SSE_MATH 4989 && TARGET_USE_VECTOR_CONVERTS && optimize_function_for_speed_p (cfun)" 4990 "#" 4991 [(set_attr "type" "sseicvt") 4992 (set_attr "mode" "<MODE>") 4993 (set_attr "athlon_decode" "direct") 4994 (set_attr "amdfam10_decode" "double") 4995 (set_attr "bdver1_decode" "direct") 4996 (set_attr "fp_int_src" "true")]) 4997 4998(define_split 4999 [(set (match_operand:MODEF 0 "register_operand" "") 5000 (float:MODEF (match_operand:SI 1 "register_operand" ""))) 5001 (clobber (match_operand:SI 2 "memory_operand" ""))] 5002 "TARGET_SSE2 && TARGET_SSE_MATH 5003 && TARGET_USE_VECTOR_CONVERTS && optimize_function_for_speed_p (cfun) 5004 && reload_completed 5005 && (SSE_REG_P (operands[0]) 5006 || (GET_CODE (operands[0]) == SUBREG 5007 && SSE_REG_P (SUBREG_REG (operands[0]))))" 5008 [(const_int 0)] 5009{ 5010 rtx op1 = operands[1]; 5011 5012 operands[3] = simplify_gen_subreg (<ssevecmode>mode, operands[0], 5013 <MODE>mode, 0); 5014 if (GET_CODE (op1) == SUBREG) 5015 op1 = SUBREG_REG (op1); 5016 5017 if (GENERAL_REG_P (op1) && TARGET_INTER_UNIT_MOVES) 5018 { 5019 operands[4] = simplify_gen_subreg (V4SImode, operands[0], <MODE>mode, 0); 5020 emit_insn (gen_sse2_loadld (operands[4], 5021 CONST0_RTX (V4SImode), operands[1])); 5022 } 5023 /* We can ignore possible trapping value in the 5024 high part of SSE register for non-trapping math. */ 5025 else if (SSE_REG_P (op1) && !flag_trapping_math) 5026 operands[4] = simplify_gen_subreg (V4SImode, operands[1], SImode, 0); 5027 else 5028 { 5029 operands[4] = simplify_gen_subreg (V4SImode, operands[0], <MODE>mode, 0); 5030 emit_move_insn (operands[2], operands[1]); 5031 emit_insn (gen_sse2_loadld (operands[4], 5032 CONST0_RTX (V4SImode), operands[2])); 5033 } 5034 if (<ssevecmode>mode == V4SFmode) 5035 emit_insn (gen_floatv4siv4sf2 (operands[3], operands[4])); 5036 else 5037 emit_insn (gen_sse2_cvtdq2pd (operands[3], operands[4])); 5038 DONE; 5039}) 5040 5041(define_split 5042 [(set (match_operand:MODEF 0 "register_operand" "") 5043 (float:MODEF (match_operand:SI 1 "memory_operand" ""))) 5044 (clobber (match_operand:SI 2 "memory_operand" ""))] 5045 "TARGET_SSE2 && TARGET_SSE_MATH 5046 && TARGET_USE_VECTOR_CONVERTS && optimize_function_for_speed_p (cfun) 5047 && reload_completed 5048 && (SSE_REG_P (operands[0]) 5049 || (GET_CODE (operands[0]) == SUBREG 5050 && SSE_REG_P (SUBREG_REG (operands[0]))))" 5051 [(const_int 0)] 5052{ 5053 operands[3] = simplify_gen_subreg (<ssevecmode>mode, operands[0], 5054 <MODE>mode, 0); 5055 operands[4] = simplify_gen_subreg (V4SImode, operands[0], <MODE>mode, 0); 5056 5057 emit_insn (gen_sse2_loadld (operands[4], 5058 CONST0_RTX (V4SImode), operands[1])); 5059 if (<ssevecmode>mode == V4SFmode) 5060 emit_insn (gen_floatv4siv4sf2 (operands[3], operands[4])); 5061 else 5062 emit_insn (gen_sse2_cvtdq2pd (operands[3], operands[4])); 5063 DONE; 5064}) 5065 5066(define_split 5067 [(set (match_operand:MODEF 0 "register_operand" "") 5068 (float:MODEF (match_operand:SI 1 "register_operand" "")))] 5069 "TARGET_SSE2 && TARGET_SSE_MATH 5070 && TARGET_USE_VECTOR_CONVERTS && optimize_function_for_speed_p (cfun) 5071 && reload_completed 5072 && (SSE_REG_P (operands[0]) 5073 || (GET_CODE (operands[0]) == SUBREG 5074 && SSE_REG_P (SUBREG_REG (operands[0]))))" 5075 [(const_int 0)] 5076{ 5077 rtx op1 = operands[1]; 5078 5079 operands[3] = simplify_gen_subreg (<ssevecmode>mode, operands[0], 5080 <MODE>mode, 0); 5081 if (GET_CODE (op1) == SUBREG) 5082 op1 = SUBREG_REG (op1); 5083 5084 if (GENERAL_REG_P (op1)) 5085 { 5086 operands[4] = simplify_gen_subreg (V4SImode, operands[0], <MODE>mode, 0); 5087 if (TARGET_INTER_UNIT_MOVES) 5088 emit_insn (gen_sse2_loadld (operands[4], 5089 CONST0_RTX (V4SImode), operands[1])); 5090 else 5091 { 5092 operands[5] = ix86_force_to_memory (GET_MODE (operands[1]), 5093 operands[1]); 5094 emit_insn (gen_sse2_loadld (operands[4], 5095 CONST0_RTX (V4SImode), operands[5])); 5096 ix86_free_from_memory (GET_MODE (operands[1])); 5097 } 5098 } 5099 /* We can ignore possible trapping value in the 5100 high part of SSE register for non-trapping math. */ 5101 else if (SSE_REG_P (op1) && !flag_trapping_math) 5102 operands[4] = simplify_gen_subreg (V4SImode, operands[1], SImode, 0); 5103 else 5104 gcc_unreachable (); 5105 if (<ssevecmode>mode == V4SFmode) 5106 emit_insn (gen_floatv4siv4sf2 (operands[3], operands[4])); 5107 else 5108 emit_insn (gen_sse2_cvtdq2pd (operands[3], operands[4])); 5109 DONE; 5110}) 5111 5112(define_split 5113 [(set (match_operand:MODEF 0 "register_operand" "") 5114 (float:MODEF (match_operand:SI 1 "memory_operand" "")))] 5115 "TARGET_SSE2 && TARGET_SSE_MATH 5116 && TARGET_USE_VECTOR_CONVERTS && optimize_function_for_speed_p (cfun) 5117 && reload_completed 5118 && (SSE_REG_P (operands[0]) 5119 || (GET_CODE (operands[0]) == SUBREG 5120 && SSE_REG_P (SUBREG_REG (operands[0]))))" 5121 [(const_int 0)] 5122{ 5123 operands[3] = simplify_gen_subreg (<ssevecmode>mode, operands[0], 5124 <MODE>mode, 0); 5125 operands[4] = simplify_gen_subreg (V4SImode, operands[0], <MODE>mode, 0); 5126 5127 emit_insn (gen_sse2_loadld (operands[4], 5128 CONST0_RTX (V4SImode), operands[1])); 5129 if (<ssevecmode>mode == V4SFmode) 5130 emit_insn (gen_floatv4siv4sf2 (operands[3], operands[4])); 5131 else 5132 emit_insn (gen_sse2_cvtdq2pd (operands[3], operands[4])); 5133 DONE; 5134}) 5135 5136(define_insn "*float<SWI48x:mode><MODEF:mode>2_sse_with_temp" 5137 [(set (match_operand:MODEF 0 "register_operand" "=x,x") 5138 (float:MODEF 5139 (match_operand:SWI48x 1 "nonimmediate_operand" "r,m"))) 5140 (clobber (match_operand:SWI48x 2 "memory_operand" "=m,X"))] 5141 "(<SWI48x:MODE>mode != DImode || TARGET_64BIT) 5142 && SSE_FLOAT_MODE_P (<MODEF:MODE>mode) && TARGET_SSE_MATH" 5143 "#" 5144 [(set_attr "type" "sseicvt") 5145 (set_attr "mode" "<MODEF:MODE>") 5146 (set_attr "athlon_decode" "double,direct") 5147 (set_attr "amdfam10_decode" "vector,double") 5148 (set_attr "bdver1_decode" "double,direct") 5149 (set_attr "fp_int_src" "true")]) 5150 5151(define_insn "*float<SWI48x:mode><MODEF:mode>2_sse_interunit" 5152 [(set (match_operand:MODEF 0 "register_operand" "=x,x") 5153 (float:MODEF 5154 (match_operand:SWI48x 1 "nonimmediate_operand" "r,m")))] 5155 "(<SWI48x:MODE>mode != DImode || TARGET_64BIT) 5156 && SSE_FLOAT_MODE_P (<MODEF:MODE>mode) && TARGET_SSE_MATH 5157 && (TARGET_INTER_UNIT_CONVERSIONS || optimize_function_for_size_p (cfun))" 5158 "%vcvtsi2<MODEF:ssemodesuffix><SWI48x:rex64suffix>\t{%1, %d0|%d0, %1}" 5159 [(set_attr "type" "sseicvt") 5160 (set_attr "prefix" "maybe_vex") 5161 (set_attr "mode" "<MODEF:MODE>") 5162 (set (attr "prefix_rex") 5163 (if_then_else 5164 (and (eq_attr "prefix" "maybe_vex") 5165 (match_test "<SWI48x:MODE>mode == DImode")) 5166 (const_string "1") 5167 (const_string "*"))) 5168 (set_attr "athlon_decode" "double,direct") 5169 (set_attr "amdfam10_decode" "vector,double") 5170 (set_attr "bdver1_decode" "double,direct") 5171 (set_attr "fp_int_src" "true")]) 5172 5173(define_split 5174 [(set (match_operand:MODEF 0 "register_operand" "") 5175 (float:MODEF (match_operand:SWI48x 1 "nonimmediate_operand" ""))) 5176 (clobber (match_operand:SWI48x 2 "memory_operand" ""))] 5177 "(<SWI48x:MODE>mode != DImode || TARGET_64BIT) 5178 && SSE_FLOAT_MODE_P (<MODEF:MODE>mode) && TARGET_SSE_MATH 5179 && (TARGET_INTER_UNIT_CONVERSIONS || optimize_function_for_size_p (cfun)) 5180 && reload_completed 5181 && (SSE_REG_P (operands[0]) 5182 || (GET_CODE (operands[0]) == SUBREG 5183 && SSE_REG_P (SUBREG_REG (operands[0]))))" 5184 [(set (match_dup 0) (float:MODEF (match_dup 1)))]) 5185 5186(define_insn "*float<SWI48x:mode><MODEF:mode>2_sse_nointerunit" 5187 [(set (match_operand:MODEF 0 "register_operand" "=x") 5188 (float:MODEF 5189 (match_operand:SWI48x 1 "memory_operand" "m")))] 5190 "(<SWI48x:MODE>mode != DImode || TARGET_64BIT) 5191 && SSE_FLOAT_MODE_P (<MODEF:MODE>mode) && TARGET_SSE_MATH 5192 && !(TARGET_INTER_UNIT_CONVERSIONS || optimize_function_for_size_p (cfun))" 5193 "%vcvtsi2<MODEF:ssemodesuffix><SWI48x:rex64suffix>\t{%1, %d0|%d0, %1}" 5194 [(set_attr "type" "sseicvt") 5195 (set_attr "prefix" "maybe_vex") 5196 (set_attr "mode" "<MODEF:MODE>") 5197 (set (attr "prefix_rex") 5198 (if_then_else 5199 (and (eq_attr "prefix" "maybe_vex") 5200 (match_test "<SWI48x:MODE>mode == DImode")) 5201 (const_string "1") 5202 (const_string "*"))) 5203 (set_attr "athlon_decode" "direct") 5204 (set_attr "amdfam10_decode" "double") 5205 (set_attr "bdver1_decode" "direct") 5206 (set_attr "fp_int_src" "true")]) 5207 5208(define_split 5209 [(set (match_operand:MODEF 0 "register_operand" "") 5210 (float:MODEF (match_operand:SWI48x 1 "register_operand" ""))) 5211 (clobber (match_operand:SWI48x 2 "memory_operand" ""))] 5212 "(<SWI48x:MODE>mode != DImode || TARGET_64BIT) 5213 && SSE_FLOAT_MODE_P (<MODEF:MODE>mode) && TARGET_SSE_MATH 5214 && !(TARGET_INTER_UNIT_CONVERSIONS || optimize_function_for_size_p (cfun)) 5215 && reload_completed 5216 && (SSE_REG_P (operands[0]) 5217 || (GET_CODE (operands[0]) == SUBREG 5218 && SSE_REG_P (SUBREG_REG (operands[0]))))" 5219 [(set (match_dup 2) (match_dup 1)) 5220 (set (match_dup 0) (float:MODEF (match_dup 2)))]) 5221 5222(define_split 5223 [(set (match_operand:MODEF 0 "register_operand" "") 5224 (float:MODEF (match_operand:SWI48x 1 "memory_operand" ""))) 5225 (clobber (match_operand:SWI48x 2 "memory_operand" ""))] 5226 "(<SWI48x:MODE>mode != DImode || TARGET_64BIT) 5227 && SSE_FLOAT_MODE_P (<MODEF:MODE>mode) && TARGET_SSE_MATH 5228 && reload_completed 5229 && (SSE_REG_P (operands[0]) 5230 || (GET_CODE (operands[0]) == SUBREG 5231 && SSE_REG_P (SUBREG_REG (operands[0]))))" 5232 [(set (match_dup 0) (float:MODEF (match_dup 1)))]) 5233 5234(define_insn "*float<SWI48x:mode><X87MODEF:mode>2_i387_with_temp" 5235 [(set (match_operand:X87MODEF 0 "register_operand" "=f,f") 5236 (float:X87MODEF 5237 (match_operand:SWI48x 1 "nonimmediate_operand" "m,?r"))) 5238 (clobber (match_operand:SWI48x 2 "memory_operand" "=X,m"))] 5239 "TARGET_80387 5240 && X87_ENABLE_FLOAT (<X87MODEF:MODE>mode, <SWI48x:MODE>mode)" 5241 "@ 5242 fild%Z1\t%1 5243 #" 5244 [(set_attr "type" "fmov,multi") 5245 (set_attr "mode" "<X87MODEF:MODE>") 5246 (set_attr "unit" "*,i387") 5247 (set_attr "fp_int_src" "true")]) 5248 5249(define_insn "*float<SWI48x:mode><X87MODEF:mode>2_i387" 5250 [(set (match_operand:X87MODEF 0 "register_operand" "=f") 5251 (float:X87MODEF 5252 (match_operand:SWI48x 1 "memory_operand" "m")))] 5253 "TARGET_80387 5254 && X87_ENABLE_FLOAT (<X87MODEF:MODE>mode, <SWI48x:MODE>mode)" 5255 "fild%Z1\t%1" 5256 [(set_attr "type" "fmov") 5257 (set_attr "mode" "<X87MODEF:MODE>") 5258 (set_attr "fp_int_src" "true")]) 5259 5260(define_split 5261 [(set (match_operand:X87MODEF 0 "fp_register_operand" "") 5262 (float:X87MODEF (match_operand:SWI48x 1 "register_operand" ""))) 5263 (clobber (match_operand:SWI48x 2 "memory_operand" ""))] 5264 "TARGET_80387 5265 && X87_ENABLE_FLOAT (<X87MODEF:MODE>mode, <SWI48x:MODE>mode) 5266 && reload_completed" 5267 [(set (match_dup 2) (match_dup 1)) 5268 (set (match_dup 0) (float:X87MODEF (match_dup 2)))]) 5269 5270(define_split 5271 [(set (match_operand:X87MODEF 0 "fp_register_operand" "") 5272 (float:X87MODEF (match_operand:SWI48x 1 "memory_operand" ""))) 5273 (clobber (match_operand:SWI48x 2 "memory_operand" ""))] 5274 "TARGET_80387 5275 && X87_ENABLE_FLOAT (<X87MODEF:MODE>mode, <SWI48x:MODE>mode) 5276 && reload_completed" 5277 [(set (match_dup 0) (float:X87MODEF (match_dup 1)))]) 5278 5279;; Avoid store forwarding (partial memory) stall penalty 5280;; by passing DImode value through XMM registers. */ 5281 5282(define_insn "floatdi<X87MODEF:mode>2_i387_with_xmm" 5283 [(set (match_operand:X87MODEF 0 "register_operand" "=f,f") 5284 (float:X87MODEF 5285 (match_operand:DI 1 "nonimmediate_operand" "m,?r"))) 5286 (clobber (match_scratch:V4SI 3 "=X,x")) 5287 (clobber (match_scratch:V4SI 4 "=X,x")) 5288 (clobber (match_operand:DI 2 "memory_operand" "=X,m"))] 5289 "TARGET_80387 && X87_ENABLE_FLOAT (<X87MODEF:MODE>mode, DImode) 5290 && TARGET_SSE2 && TARGET_INTER_UNIT_MOVES 5291 && !TARGET_64BIT && optimize_function_for_speed_p (cfun)" 5292 "#" 5293 [(set_attr "type" "multi") 5294 (set_attr "mode" "<X87MODEF:MODE>") 5295 (set_attr "unit" "i387") 5296 (set_attr "fp_int_src" "true")]) 5297 5298(define_split 5299 [(set (match_operand:X87MODEF 0 "fp_register_operand" "") 5300 (float:X87MODEF (match_operand:DI 1 "register_operand" ""))) 5301 (clobber (match_scratch:V4SI 3 "")) 5302 (clobber (match_scratch:V4SI 4 "")) 5303 (clobber (match_operand:DI 2 "memory_operand" ""))] 5304 "TARGET_80387 && X87_ENABLE_FLOAT (<X87MODEF:MODE>mode, DImode) 5305 && TARGET_SSE2 && TARGET_INTER_UNIT_MOVES 5306 && !TARGET_64BIT && optimize_function_for_speed_p (cfun) 5307 && reload_completed" 5308 [(set (match_dup 2) (match_dup 3)) 5309 (set (match_dup 0) (float:X87MODEF (match_dup 2)))] 5310{ 5311 /* The DImode arrived in a pair of integral registers (e.g. %edx:%eax). 5312 Assemble the 64-bit DImode value in an xmm register. */ 5313 emit_insn (gen_sse2_loadld (operands[3], CONST0_RTX (V4SImode), 5314 gen_rtx_SUBREG (SImode, operands[1], 0))); 5315 emit_insn (gen_sse2_loadld (operands[4], CONST0_RTX (V4SImode), 5316 gen_rtx_SUBREG (SImode, operands[1], 4))); 5317 emit_insn (gen_vec_interleave_lowv4si (operands[3], operands[3], 5318 operands[4])); 5319 5320 operands[3] = gen_rtx_REG (DImode, REGNO (operands[3])); 5321}) 5322 5323(define_split 5324 [(set (match_operand:X87MODEF 0 "fp_register_operand" "") 5325 (float:X87MODEF (match_operand:DI 1 "memory_operand" ""))) 5326 (clobber (match_scratch:V4SI 3 "")) 5327 (clobber (match_scratch:V4SI 4 "")) 5328 (clobber (match_operand:DI 2 "memory_operand" ""))] 5329 "TARGET_80387 && X87_ENABLE_FLOAT (<X87MODEF:MODE>mode, DImode) 5330 && TARGET_SSE2 && TARGET_INTER_UNIT_MOVES 5331 && !TARGET_64BIT && optimize_function_for_speed_p (cfun) 5332 && reload_completed" 5333 [(set (match_dup 0) (float:X87MODEF (match_dup 1)))]) 5334 5335;; Avoid store forwarding (partial memory) stall penalty by extending 5336;; SImode value to DImode through XMM register instead of pushing two 5337;; SImode values to stack. Note that even !TARGET_INTER_UNIT_MOVES 5338;; targets benefit from this optimization. Also note that fild 5339;; loads from memory only. 5340 5341(define_insn "*floatunssi<mode>2_1" 5342 [(set (match_operand:X87MODEF 0 "register_operand" "=f,f") 5343 (unsigned_float:X87MODEF 5344 (match_operand:SI 1 "nonimmediate_operand" "x,m"))) 5345 (clobber (match_operand:DI 2 "memory_operand" "=m,m")) 5346 (clobber (match_scratch:SI 3 "=X,x"))] 5347 "!TARGET_64BIT 5348 && TARGET_80387 && X87_ENABLE_FLOAT (<X87MODEF:MODE>mode, DImode) 5349 && TARGET_SSE" 5350 "#" 5351 [(set_attr "type" "multi") 5352 (set_attr "mode" "<MODE>")]) 5353 5354(define_split 5355 [(set (match_operand:X87MODEF 0 "register_operand" "") 5356 (unsigned_float:X87MODEF 5357 (match_operand:SI 1 "register_operand" ""))) 5358 (clobber (match_operand:DI 2 "memory_operand" "")) 5359 (clobber (match_scratch:SI 3 ""))] 5360 "!TARGET_64BIT 5361 && TARGET_80387 && X87_ENABLE_FLOAT (<X87MODEF:MODE>mode, DImode) 5362 && TARGET_SSE 5363 && reload_completed" 5364 [(set (match_dup 2) (match_dup 1)) 5365 (set (match_dup 0) 5366 (float:X87MODEF (match_dup 2)))] 5367 "operands[1] = simplify_gen_subreg (DImode, operands[1], SImode, 0);") 5368 5369(define_split 5370 [(set (match_operand:X87MODEF 0 "register_operand" "") 5371 (unsigned_float:X87MODEF 5372 (match_operand:SI 1 "memory_operand" ""))) 5373 (clobber (match_operand:DI 2 "memory_operand" "")) 5374 (clobber (match_scratch:SI 3 ""))] 5375 "!TARGET_64BIT 5376 && TARGET_80387 && X87_ENABLE_FLOAT (<X87MODEF:MODE>mode, DImode) 5377 && TARGET_SSE 5378 && reload_completed" 5379 [(set (match_dup 2) (match_dup 3)) 5380 (set (match_dup 0) 5381 (float:X87MODEF (match_dup 2)))] 5382{ 5383 emit_move_insn (operands[3], operands[1]); 5384 operands[3] = simplify_gen_subreg (DImode, operands[3], SImode, 0); 5385}) 5386 5387(define_expand "floatunssi<mode>2" 5388 [(parallel 5389 [(set (match_operand:X87MODEF 0 "register_operand" "") 5390 (unsigned_float:X87MODEF 5391 (match_operand:SI 1 "nonimmediate_operand" ""))) 5392 (clobber (match_dup 2)) 5393 (clobber (match_scratch:SI 3 ""))])] 5394 "!TARGET_64BIT 5395 && ((TARGET_80387 && X87_ENABLE_FLOAT (<X87MODEF:MODE>mode, DImode) 5396 && TARGET_SSE) 5397 || (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH))" 5398{ 5399 if (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH) 5400 { 5401 ix86_expand_convert_uns_si<mode>_sse (operands[0], operands[1]); 5402 DONE; 5403 } 5404 else 5405 operands[2] = assign_386_stack_local (DImode, SLOT_TEMP); 5406}) 5407 5408(define_expand "floatunsdisf2" 5409 [(use (match_operand:SF 0 "register_operand" "")) 5410 (use (match_operand:DI 1 "nonimmediate_operand" ""))] 5411 "TARGET_64BIT && TARGET_SSE_MATH" 5412 "x86_emit_floatuns (operands); DONE;") 5413 5414(define_expand "floatunsdidf2" 5415 [(use (match_operand:DF 0 "register_operand" "")) 5416 (use (match_operand:DI 1 "nonimmediate_operand" ""))] 5417 "(TARGET_64BIT || TARGET_KEEPS_VECTOR_ALIGNED_STACK) 5418 && TARGET_SSE2 && TARGET_SSE_MATH" 5419{ 5420 if (TARGET_64BIT) 5421 x86_emit_floatuns (operands); 5422 else 5423 ix86_expand_convert_uns_didf_sse (operands[0], operands[1]); 5424 DONE; 5425}) 5426 5427;; Load effective address instructions 5428 5429(define_insn_and_split "*lea<mode>" 5430 [(set (match_operand:SWI48 0 "register_operand" "=r") 5431 (match_operand:SWI48 1 "lea_address_operand" "p"))] 5432 "" 5433{ 5434 rtx addr = operands[1]; 5435 5436 if (SImode_address_operand (addr, VOIDmode)) 5437 { 5438 gcc_assert (TARGET_64BIT); 5439 return "lea{l}\t{%E1, %k0|%k0, %E1}"; 5440 } 5441 else 5442 return "lea{<imodesuffix>}\t{%E1, %0|%0, %E1}"; 5443} 5444 "reload_completed && ix86_avoid_lea_for_addr (insn, operands)" 5445 [(const_int 0)] 5446{ 5447 ix86_split_lea_for_addr (operands, <MODE>mode); 5448 DONE; 5449} 5450 [(set_attr "type" "lea") 5451 (set (attr "mode") 5452 (if_then_else 5453 (match_operand 1 "SImode_address_operand") 5454 (const_string "SI") 5455 (const_string "<MODE>")))]) 5456 5457;; Add instructions 5458 5459(define_expand "add<mode>3" 5460 [(set (match_operand:SDWIM 0 "nonimmediate_operand" "") 5461 (plus:SDWIM (match_operand:SDWIM 1 "nonimmediate_operand" "") 5462 (match_operand:SDWIM 2 "<general_operand>" "")))] 5463 "" 5464 "ix86_expand_binary_operator (PLUS, <MODE>mode, operands); DONE;") 5465 5466(define_insn_and_split "*add<dwi>3_doubleword" 5467 [(set (match_operand:<DWI> 0 "nonimmediate_operand" "=r,o") 5468 (plus:<DWI> 5469 (match_operand:<DWI> 1 "nonimmediate_operand" "%0,0") 5470 (match_operand:<DWI> 2 "<general_operand>" "ro<di>,r<di>"))) 5471 (clobber (reg:CC FLAGS_REG))] 5472 "ix86_binary_operator_ok (PLUS, <DWI>mode, operands)" 5473 "#" 5474 "reload_completed" 5475 [(parallel [(set (reg:CC FLAGS_REG) 5476 (unspec:CC [(match_dup 1) (match_dup 2)] 5477 UNSPEC_ADD_CARRY)) 5478 (set (match_dup 0) 5479 (plus:DWIH (match_dup 1) (match_dup 2)))]) 5480 (parallel [(set (match_dup 3) 5481 (plus:DWIH 5482 (match_dup 4) 5483 (plus:DWIH 5484 (ltu:DWIH (reg:CC FLAGS_REG) (const_int 0)) 5485 (match_dup 5)))) 5486 (clobber (reg:CC FLAGS_REG))])] 5487 "split_double_mode (<DWI>mode, &operands[0], 3, &operands[0], &operands[3]);") 5488 5489(define_insn "*add<mode>3_cc" 5490 [(set (reg:CC FLAGS_REG) 5491 (unspec:CC 5492 [(match_operand:SWI48 1 "nonimmediate_operand" "%0,0") 5493 (match_operand:SWI48 2 "<general_operand>" "r<i>,rm")] 5494 UNSPEC_ADD_CARRY)) 5495 (set (match_operand:SWI48 0 "nonimmediate_operand" "=rm,r") 5496 (plus:SWI48 (match_dup 1) (match_dup 2)))] 5497 "ix86_binary_operator_ok (PLUS, <MODE>mode, operands)" 5498 "add{<imodesuffix>}\t{%2, %0|%0, %2}" 5499 [(set_attr "type" "alu") 5500 (set_attr "mode" "<MODE>")]) 5501 5502(define_insn "addqi3_cc" 5503 [(set (reg:CC FLAGS_REG) 5504 (unspec:CC 5505 [(match_operand:QI 1 "nonimmediate_operand" "%0,0") 5506 (match_operand:QI 2 "general_operand" "qn,qm")] 5507 UNSPEC_ADD_CARRY)) 5508 (set (match_operand:QI 0 "nonimmediate_operand" "=qm,q") 5509 (plus:QI (match_dup 1) (match_dup 2)))] 5510 "ix86_binary_operator_ok (PLUS, QImode, operands)" 5511 "add{b}\t{%2, %0|%0, %2}" 5512 [(set_attr "type" "alu") 5513 (set_attr "mode" "QI")]) 5514 5515(define_insn "*add<mode>_1" 5516 [(set (match_operand:SWI48 0 "nonimmediate_operand" "=r,rm,r,r") 5517 (plus:SWI48 5518 (match_operand:SWI48 1 "nonimmediate_operand" "%0,0,r,r") 5519 (match_operand:SWI48 2 "x86_64_general_operand" "rme,re,0,le"))) 5520 (clobber (reg:CC FLAGS_REG))] 5521 "ix86_binary_operator_ok (PLUS, <MODE>mode, operands)" 5522{ 5523 switch (get_attr_type (insn)) 5524 { 5525 case TYPE_LEA: 5526 return "#"; 5527 5528 case TYPE_INCDEC: 5529 gcc_assert (rtx_equal_p (operands[0], operands[1])); 5530 if (operands[2] == const1_rtx) 5531 return "inc{<imodesuffix>}\t%0"; 5532 else 5533 { 5534 gcc_assert (operands[2] == constm1_rtx); 5535 return "dec{<imodesuffix>}\t%0"; 5536 } 5537 5538 default: 5539 /* For most processors, ADD is faster than LEA. This alternative 5540 was added to use ADD as much as possible. */ 5541 if (which_alternative == 2) 5542 { 5543 rtx tmp; 5544 tmp = operands[1], operands[1] = operands[2], operands[2] = tmp; 5545 } 5546 5547 gcc_assert (rtx_equal_p (operands[0], operands[1])); 5548 if (x86_maybe_negate_const_int (&operands[2], <MODE>mode)) 5549 return "sub{<imodesuffix>}\t{%2, %0|%0, %2}"; 5550 5551 return "add{<imodesuffix>}\t{%2, %0|%0, %2}"; 5552 } 5553} 5554 [(set (attr "type") 5555 (cond [(eq_attr "alternative" "3") 5556 (const_string "lea") 5557 (match_operand:SWI48 2 "incdec_operand" "") 5558 (const_string "incdec") 5559 ] 5560 (const_string "alu"))) 5561 (set (attr "length_immediate") 5562 (if_then_else 5563 (and (eq_attr "type" "alu") (match_operand 2 "const128_operand" "")) 5564 (const_string "1") 5565 (const_string "*"))) 5566 (set_attr "mode" "<MODE>")]) 5567 5568;; It may seem that nonimmediate operand is proper one for operand 1. 5569;; The addsi_1 pattern allows nonimmediate operand at that place and 5570;; we take care in ix86_binary_operator_ok to not allow two memory 5571;; operands so proper swapping will be done in reload. This allow 5572;; patterns constructed from addsi_1 to match. 5573 5574(define_insn "addsi_1_zext" 5575 [(set (match_operand:DI 0 "register_operand" "=r,r,r") 5576 (zero_extend:DI 5577 (plus:SI (match_operand:SI 1 "nonimmediate_operand" "%0,r,r") 5578 (match_operand:SI 2 "x86_64_general_operand" "rme,0,le")))) 5579 (clobber (reg:CC FLAGS_REG))] 5580 "TARGET_64BIT && ix86_binary_operator_ok (PLUS, SImode, operands)" 5581{ 5582 switch (get_attr_type (insn)) 5583 { 5584 case TYPE_LEA: 5585 return "#"; 5586 5587 case TYPE_INCDEC: 5588 if (operands[2] == const1_rtx) 5589 return "inc{l}\t%k0"; 5590 else 5591 { 5592 gcc_assert (operands[2] == constm1_rtx); 5593 return "dec{l}\t%k0"; 5594 } 5595 5596 default: 5597 /* For most processors, ADD is faster than LEA. This alternative 5598 was added to use ADD as much as possible. */ 5599 if (which_alternative == 1) 5600 { 5601 rtx tmp; 5602 tmp = operands[1], operands[1] = operands[2], operands[2] = tmp; 5603 } 5604 5605 if (x86_maybe_negate_const_int (&operands[2], SImode)) 5606 return "sub{l}\t{%2, %k0|%k0, %2}"; 5607 5608 return "add{l}\t{%2, %k0|%k0, %2}"; 5609 } 5610} 5611 [(set (attr "type") 5612 (cond [(eq_attr "alternative" "2") 5613 (const_string "lea") 5614 (match_operand:SI 2 "incdec_operand" "") 5615 (const_string "incdec") 5616 ] 5617 (const_string "alu"))) 5618 (set (attr "length_immediate") 5619 (if_then_else 5620 (and (eq_attr "type" "alu") (match_operand 2 "const128_operand" "")) 5621 (const_string "1") 5622 (const_string "*"))) 5623 (set_attr "mode" "SI")]) 5624 5625(define_insn "*addhi_1" 5626 [(set (match_operand:HI 0 "nonimmediate_operand" "=rm,r,r,Yp") 5627 (plus:HI (match_operand:HI 1 "nonimmediate_operand" "%0,0,r,Yp") 5628 (match_operand:HI 2 "general_operand" "rn,rm,0,ln"))) 5629 (clobber (reg:CC FLAGS_REG))] 5630 "ix86_binary_operator_ok (PLUS, HImode, operands)" 5631{ 5632 switch (get_attr_type (insn)) 5633 { 5634 case TYPE_LEA: 5635 return "#"; 5636 5637 case TYPE_INCDEC: 5638 gcc_assert (rtx_equal_p (operands[0], operands[1])); 5639 if (operands[2] == const1_rtx) 5640 return "inc{w}\t%0"; 5641 else 5642 { 5643 gcc_assert (operands[2] == constm1_rtx); 5644 return "dec{w}\t%0"; 5645 } 5646 5647 default: 5648 /* For most processors, ADD is faster than LEA. This alternative 5649 was added to use ADD as much as possible. */ 5650 if (which_alternative == 2) 5651 { 5652 rtx tmp; 5653 tmp = operands[1], operands[1] = operands[2], operands[2] = tmp; 5654 } 5655 5656 gcc_assert (rtx_equal_p (operands[0], operands[1])); 5657 if (x86_maybe_negate_const_int (&operands[2], HImode)) 5658 return "sub{w}\t{%2, %0|%0, %2}"; 5659 5660 return "add{w}\t{%2, %0|%0, %2}"; 5661 } 5662} 5663 [(set (attr "type") 5664 (cond [(eq_attr "alternative" "3") 5665 (const_string "lea") 5666 (match_operand:HI 2 "incdec_operand" "") 5667 (const_string "incdec") 5668 ] 5669 (const_string "alu"))) 5670 (set (attr "length_immediate") 5671 (if_then_else 5672 (and (eq_attr "type" "alu") (match_operand 2 "const128_operand" "")) 5673 (const_string "1") 5674 (const_string "*"))) 5675 (set_attr "mode" "HI,HI,HI,SI")]) 5676 5677;; %%% Potential partial reg stall on alternatives 3 and 4. What to do? 5678(define_insn "*addqi_1" 5679 [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,q,q,r,r,Yp") 5680 (plus:QI (match_operand:QI 1 "nonimmediate_operand" "%0,0,q,0,r,Yp") 5681 (match_operand:QI 2 "general_operand" "qn,qm,0,rn,0,ln"))) 5682 (clobber (reg:CC FLAGS_REG))] 5683 "ix86_binary_operator_ok (PLUS, QImode, operands)" 5684{ 5685 bool widen = (which_alternative == 3 || which_alternative == 4); 5686 5687 switch (get_attr_type (insn)) 5688 { 5689 case TYPE_LEA: 5690 return "#"; 5691 5692 case TYPE_INCDEC: 5693 gcc_assert (rtx_equal_p (operands[0], operands[1])); 5694 if (operands[2] == const1_rtx) 5695 return widen ? "inc{l}\t%k0" : "inc{b}\t%0"; 5696 else 5697 { 5698 gcc_assert (operands[2] == constm1_rtx); 5699 return widen ? "dec{l}\t%k0" : "dec{b}\t%0"; 5700 } 5701 5702 default: 5703 /* For most processors, ADD is faster than LEA. These alternatives 5704 were added to use ADD as much as possible. */ 5705 if (which_alternative == 2 || which_alternative == 4) 5706 { 5707 rtx tmp; 5708 tmp = operands[1], operands[1] = operands[2], operands[2] = tmp; 5709 } 5710 5711 gcc_assert (rtx_equal_p (operands[0], operands[1])); 5712 if (x86_maybe_negate_const_int (&operands[2], QImode)) 5713 { 5714 if (widen) 5715 return "sub{l}\t{%2, %k0|%k0, %2}"; 5716 else 5717 return "sub{b}\t{%2, %0|%0, %2}"; 5718 } 5719 if (widen) 5720 return "add{l}\t{%k2, %k0|%k0, %k2}"; 5721 else 5722 return "add{b}\t{%2, %0|%0, %2}"; 5723 } 5724} 5725 [(set (attr "type") 5726 (cond [(eq_attr "alternative" "5") 5727 (const_string "lea") 5728 (match_operand:QI 2 "incdec_operand" "") 5729 (const_string "incdec") 5730 ] 5731 (const_string "alu"))) 5732 (set (attr "length_immediate") 5733 (if_then_else 5734 (and (eq_attr "type" "alu") (match_operand 2 "const128_operand" "")) 5735 (const_string "1") 5736 (const_string "*"))) 5737 (set_attr "mode" "QI,QI,QI,SI,SI,SI")]) 5738 5739(define_insn "*addqi_1_slp" 5740 [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm,q")) 5741 (plus:QI (match_dup 0) 5742 (match_operand:QI 1 "general_operand" "qn,qm"))) 5743 (clobber (reg:CC FLAGS_REG))] 5744 "(! TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun)) 5745 && !(MEM_P (operands[0]) && MEM_P (operands[1]))" 5746{ 5747 switch (get_attr_type (insn)) 5748 { 5749 case TYPE_INCDEC: 5750 if (operands[1] == const1_rtx) 5751 return "inc{b}\t%0"; 5752 else 5753 { 5754 gcc_assert (operands[1] == constm1_rtx); 5755 return "dec{b}\t%0"; 5756 } 5757 5758 default: 5759 if (x86_maybe_negate_const_int (&operands[1], QImode)) 5760 return "sub{b}\t{%1, %0|%0, %1}"; 5761 5762 return "add{b}\t{%1, %0|%0, %1}"; 5763 } 5764} 5765 [(set (attr "type") 5766 (if_then_else (match_operand:QI 1 "incdec_operand" "") 5767 (const_string "incdec") 5768 (const_string "alu1"))) 5769 (set (attr "memory") 5770 (if_then_else (match_operand 1 "memory_operand" "") 5771 (const_string "load") 5772 (const_string "none"))) 5773 (set_attr "mode" "QI")]) 5774 5775;; Split non destructive adds if we cannot use lea. 5776(define_split 5777 [(set (match_operand:SWI48 0 "register_operand" "") 5778 (plus:SWI48 (match_operand:SWI48 1 "register_operand" "") 5779 (match_operand:SWI48 2 "nonmemory_operand" ""))) 5780 (clobber (reg:CC FLAGS_REG))] 5781 "reload_completed && ix86_avoid_lea_for_add (insn, operands)" 5782 [(set (match_dup 0) (match_dup 1)) 5783 (parallel [(set (match_dup 0) (plus:<MODE> (match_dup 0) (match_dup 2))) 5784 (clobber (reg:CC FLAGS_REG))])]) 5785 5786;; Convert add to the lea pattern to avoid flags dependency. 5787(define_split 5788 [(set (match_operand:SWI 0 "register_operand" "") 5789 (plus:SWI (match_operand:SWI 1 "register_operand" "") 5790 (match_operand:SWI 2 "<nonmemory_operand>" ""))) 5791 (clobber (reg:CC FLAGS_REG))] 5792 "reload_completed && ix86_lea_for_add_ok (insn, operands)" 5793 [(const_int 0)] 5794{ 5795 enum machine_mode mode = <MODE>mode; 5796 rtx pat; 5797 5798 if (GET_MODE_SIZE (mode) < GET_MODE_SIZE (SImode)) 5799 { 5800 mode = SImode; 5801 operands[0] = gen_lowpart (mode, operands[0]); 5802 operands[1] = gen_lowpart (mode, operands[1]); 5803 operands[2] = gen_lowpart (mode, operands[2]); 5804 } 5805 5806 pat = gen_rtx_PLUS (mode, operands[1], operands[2]); 5807 5808 emit_insn (gen_rtx_SET (VOIDmode, operands[0], pat)); 5809 DONE; 5810}) 5811 5812;; Convert add to the lea pattern to avoid flags dependency. 5813(define_split 5814 [(set (match_operand:DI 0 "register_operand" "") 5815 (zero_extend:DI 5816 (plus:SI (match_operand:SI 1 "register_operand" "") 5817 (match_operand:SI 2 "x86_64_nonmemory_operand" "")))) 5818 (clobber (reg:CC FLAGS_REG))] 5819 "TARGET_64BIT && reload_completed && ix86_lea_for_add_ok (insn, operands)" 5820 [(set (match_dup 0) 5821 (zero_extend:DI (plus:SI (match_dup 1) (match_dup 2))))]) 5822 5823(define_insn "*add<mode>_2" 5824 [(set (reg FLAGS_REG) 5825 (compare 5826 (plus:SWI 5827 (match_operand:SWI 1 "nonimmediate_operand" "%0,0,<r>") 5828 (match_operand:SWI 2 "<general_operand>" "<g>,<r><i>,0")) 5829 (const_int 0))) 5830 (set (match_operand:SWI 0 "nonimmediate_operand" "=<r>,<r>m,<r>") 5831 (plus:SWI (match_dup 1) (match_dup 2)))] 5832 "ix86_match_ccmode (insn, CCGOCmode) 5833 && ix86_binary_operator_ok (PLUS, <MODE>mode, operands)" 5834{ 5835 switch (get_attr_type (insn)) 5836 { 5837 case TYPE_INCDEC: 5838 if (operands[2] == const1_rtx) 5839 return "inc{<imodesuffix>}\t%0"; 5840 else 5841 { 5842 gcc_assert (operands[2] == constm1_rtx); 5843 return "dec{<imodesuffix>}\t%0"; 5844 } 5845 5846 default: 5847 if (which_alternative == 2) 5848 { 5849 rtx tmp; 5850 tmp = operands[1], operands[1] = operands[2], operands[2] = tmp; 5851 } 5852 5853 gcc_assert (rtx_equal_p (operands[0], operands[1])); 5854 if (x86_maybe_negate_const_int (&operands[2], <MODE>mode)) 5855 return "sub{<imodesuffix>}\t{%2, %0|%0, %2}"; 5856 5857 return "add{<imodesuffix>}\t{%2, %0|%0, %2}"; 5858 } 5859} 5860 [(set (attr "type") 5861 (if_then_else (match_operand:SWI 2 "incdec_operand" "") 5862 (const_string "incdec") 5863 (const_string "alu"))) 5864 (set (attr "length_immediate") 5865 (if_then_else 5866 (and (eq_attr "type" "alu") (match_operand 2 "const128_operand" "")) 5867 (const_string "1") 5868 (const_string "*"))) 5869 (set_attr "mode" "<MODE>")]) 5870 5871;; See comment for addsi_1_zext why we do use nonimmediate_operand 5872(define_insn "*addsi_2_zext" 5873 [(set (reg FLAGS_REG) 5874 (compare 5875 (plus:SI (match_operand:SI 1 "nonimmediate_operand" "%0,r") 5876 (match_operand:SI 2 "x86_64_general_operand" "rme,0")) 5877 (const_int 0))) 5878 (set (match_operand:DI 0 "register_operand" "=r,r") 5879 (zero_extend:DI (plus:SI (match_dup 1) (match_dup 2))))] 5880 "TARGET_64BIT && ix86_match_ccmode (insn, CCGOCmode) 5881 && ix86_binary_operator_ok (PLUS, SImode, operands)" 5882{ 5883 switch (get_attr_type (insn)) 5884 { 5885 case TYPE_INCDEC: 5886 if (operands[2] == const1_rtx) 5887 return "inc{l}\t%k0"; 5888 else 5889 { 5890 gcc_assert (operands[2] == constm1_rtx); 5891 return "dec{l}\t%k0"; 5892 } 5893 5894 default: 5895 if (which_alternative == 1) 5896 { 5897 rtx tmp; 5898 tmp = operands[1], operands[1] = operands[2], operands[2] = tmp; 5899 } 5900 5901 if (x86_maybe_negate_const_int (&operands[2], SImode)) 5902 return "sub{l}\t{%2, %k0|%k0, %2}"; 5903 5904 return "add{l}\t{%2, %k0|%k0, %2}"; 5905 } 5906} 5907 [(set (attr "type") 5908 (if_then_else (match_operand:SI 2 "incdec_operand" "") 5909 (const_string "incdec") 5910 (const_string "alu"))) 5911 (set (attr "length_immediate") 5912 (if_then_else 5913 (and (eq_attr "type" "alu") (match_operand 2 "const128_operand" "")) 5914 (const_string "1") 5915 (const_string "*"))) 5916 (set_attr "mode" "SI")]) 5917 5918(define_insn "*add<mode>_3" 5919 [(set (reg FLAGS_REG) 5920 (compare 5921 (neg:SWI (match_operand:SWI 2 "<general_operand>" "<g>,0")) 5922 (match_operand:SWI 1 "nonimmediate_operand" "%0,<r>"))) 5923 (clobber (match_scratch:SWI 0 "=<r>,<r>"))] 5924 "ix86_match_ccmode (insn, CCZmode) 5925 && !(MEM_P (operands[1]) && MEM_P (operands[2]))" 5926{ 5927 switch (get_attr_type (insn)) 5928 { 5929 case TYPE_INCDEC: 5930 if (operands[2] == const1_rtx) 5931 return "inc{<imodesuffix>}\t%0"; 5932 else 5933 { 5934 gcc_assert (operands[2] == constm1_rtx); 5935 return "dec{<imodesuffix>}\t%0"; 5936 } 5937 5938 default: 5939 if (which_alternative == 1) 5940 { 5941 rtx tmp; 5942 tmp = operands[1], operands[1] = operands[2], operands[2] = tmp; 5943 } 5944 5945 gcc_assert (rtx_equal_p (operands[0], operands[1])); 5946 if (x86_maybe_negate_const_int (&operands[2], <MODE>mode)) 5947 return "sub{<imodesuffix>}\t{%2, %0|%0, %2}"; 5948 5949 return "add{<imodesuffix>}\t{%2, %0|%0, %2}"; 5950 } 5951} 5952 [(set (attr "type") 5953 (if_then_else (match_operand:SWI 2 "incdec_operand" "") 5954 (const_string "incdec") 5955 (const_string "alu"))) 5956 (set (attr "length_immediate") 5957 (if_then_else 5958 (and (eq_attr "type" "alu") (match_operand 2 "const128_operand" "")) 5959 (const_string "1") 5960 (const_string "*"))) 5961 (set_attr "mode" "<MODE>")]) 5962 5963;; See comment for addsi_1_zext why we do use nonimmediate_operand 5964(define_insn "*addsi_3_zext" 5965 [(set (reg FLAGS_REG) 5966 (compare 5967 (neg:SI (match_operand:SI 2 "x86_64_general_operand" "rme,0")) 5968 (match_operand:SI 1 "nonimmediate_operand" "%0,r"))) 5969 (set (match_operand:DI 0 "register_operand" "=r,r") 5970 (zero_extend:DI (plus:SI (match_dup 1) (match_dup 2))))] 5971 "TARGET_64BIT && ix86_match_ccmode (insn, CCZmode) 5972 && ix86_binary_operator_ok (PLUS, SImode, operands)" 5973{ 5974 switch (get_attr_type (insn)) 5975 { 5976 case TYPE_INCDEC: 5977 if (operands[2] == const1_rtx) 5978 return "inc{l}\t%k0"; 5979 else 5980 { 5981 gcc_assert (operands[2] == constm1_rtx); 5982 return "dec{l}\t%k0"; 5983 } 5984 5985 default: 5986 if (which_alternative == 1) 5987 { 5988 rtx tmp; 5989 tmp = operands[1], operands[1] = operands[2], operands[2] = tmp; 5990 } 5991 5992 if (x86_maybe_negate_const_int (&operands[2], SImode)) 5993 return "sub{l}\t{%2, %k0|%k0, %2}"; 5994 5995 return "add{l}\t{%2, %k0|%k0, %2}"; 5996 } 5997} 5998 [(set (attr "type") 5999 (if_then_else (match_operand:SI 2 "incdec_operand" "") 6000 (const_string "incdec") 6001 (const_string "alu"))) 6002 (set (attr "length_immediate") 6003 (if_then_else 6004 (and (eq_attr "type" "alu") (match_operand 2 "const128_operand" "")) 6005 (const_string "1") 6006 (const_string "*"))) 6007 (set_attr "mode" "SI")]) 6008 6009; For comparisons against 1, -1 and 128, we may generate better code 6010; by converting cmp to add, inc or dec as done by peephole2. This pattern 6011; is matched then. We can't accept general immediate, because for 6012; case of overflows, the result is messed up. 6013; Also carry flag is reversed compared to cmp, so this conversion is valid 6014; only for comparisons not depending on it. 6015 6016(define_insn "*adddi_4" 6017 [(set (reg FLAGS_REG) 6018 (compare 6019 (match_operand:DI 1 "nonimmediate_operand" "0") 6020 (match_operand:DI 2 "x86_64_immediate_operand" "e"))) 6021 (clobber (match_scratch:DI 0 "=rm"))] 6022 "TARGET_64BIT 6023 && ix86_match_ccmode (insn, CCGCmode)" 6024{ 6025 switch (get_attr_type (insn)) 6026 { 6027 case TYPE_INCDEC: 6028 if (operands[2] == constm1_rtx) 6029 return "inc{q}\t%0"; 6030 else 6031 { 6032 gcc_assert (operands[2] == const1_rtx); 6033 return "dec{q}\t%0"; 6034 } 6035 6036 default: 6037 if (x86_maybe_negate_const_int (&operands[2], DImode)) 6038 return "add{q}\t{%2, %0|%0, %2}"; 6039 6040 return "sub{q}\t{%2, %0|%0, %2}"; 6041 } 6042} 6043 [(set (attr "type") 6044 (if_then_else (match_operand:DI 2 "incdec_operand" "") 6045 (const_string "incdec") 6046 (const_string "alu"))) 6047 (set (attr "length_immediate") 6048 (if_then_else 6049 (and (eq_attr "type" "alu") (match_operand 2 "const128_operand" "")) 6050 (const_string "1") 6051 (const_string "*"))) 6052 (set_attr "mode" "DI")]) 6053 6054; For comparisons against 1, -1 and 128, we may generate better code 6055; by converting cmp to add, inc or dec as done by peephole2. This pattern 6056; is matched then. We can't accept general immediate, because for 6057; case of overflows, the result is messed up. 6058; Also carry flag is reversed compared to cmp, so this conversion is valid 6059; only for comparisons not depending on it. 6060 6061(define_insn "*add<mode>_4" 6062 [(set (reg FLAGS_REG) 6063 (compare 6064 (match_operand:SWI124 1 "nonimmediate_operand" "0") 6065 (match_operand:SWI124 2 "const_int_operand" "n"))) 6066 (clobber (match_scratch:SWI124 0 "=<r>m"))] 6067 "ix86_match_ccmode (insn, CCGCmode)" 6068{ 6069 switch (get_attr_type (insn)) 6070 { 6071 case TYPE_INCDEC: 6072 if (operands[2] == constm1_rtx) 6073 return "inc{<imodesuffix>}\t%0"; 6074 else 6075 { 6076 gcc_assert (operands[2] == const1_rtx); 6077 return "dec{<imodesuffix>}\t%0"; 6078 } 6079 6080 default: 6081 if (x86_maybe_negate_const_int (&operands[2], <MODE>mode)) 6082 return "add{<imodesuffix>}\t{%2, %0|%0, %2}"; 6083 6084 return "sub{<imodesuffix>}\t{%2, %0|%0, %2}"; 6085 } 6086} 6087 [(set (attr "type") 6088 (if_then_else (match_operand:<MODE> 2 "incdec_operand" "") 6089 (const_string "incdec") 6090 (const_string "alu"))) 6091 (set (attr "length_immediate") 6092 (if_then_else 6093 (and (eq_attr "type" "alu") (match_operand 2 "const128_operand" "")) 6094 (const_string "1") 6095 (const_string "*"))) 6096 (set_attr "mode" "<MODE>")]) 6097 6098(define_insn "*add<mode>_5" 6099 [(set (reg FLAGS_REG) 6100 (compare 6101 (plus:SWI 6102 (match_operand:SWI 1 "nonimmediate_operand" "%0,<r>") 6103 (match_operand:SWI 2 "<general_operand>" "<g>,0")) 6104 (const_int 0))) 6105 (clobber (match_scratch:SWI 0 "=<r>,<r>"))] 6106 "ix86_match_ccmode (insn, CCGOCmode) 6107 && !(MEM_P (operands[1]) && MEM_P (operands[2]))" 6108{ 6109 switch (get_attr_type (insn)) 6110 { 6111 case TYPE_INCDEC: 6112 if (operands[2] == const1_rtx) 6113 return "inc{<imodesuffix>}\t%0"; 6114 else 6115 { 6116 gcc_assert (operands[2] == constm1_rtx); 6117 return "dec{<imodesuffix>}\t%0"; 6118 } 6119 6120 default: 6121 if (which_alternative == 1) 6122 { 6123 rtx tmp; 6124 tmp = operands[1], operands[1] = operands[2], operands[2] = tmp; 6125 } 6126 6127 gcc_assert (rtx_equal_p (operands[0], operands[1])); 6128 if (x86_maybe_negate_const_int (&operands[2], <MODE>mode)) 6129 return "sub{<imodesuffix>}\t{%2, %0|%0, %2}"; 6130 6131 return "add{<imodesuffix>}\t{%2, %0|%0, %2}"; 6132 } 6133} 6134 [(set (attr "type") 6135 (if_then_else (match_operand:SWI 2 "incdec_operand" "") 6136 (const_string "incdec") 6137 (const_string "alu"))) 6138 (set (attr "length_immediate") 6139 (if_then_else 6140 (and (eq_attr "type" "alu") (match_operand 2 "const128_operand" "")) 6141 (const_string "1") 6142 (const_string "*"))) 6143 (set_attr "mode" "<MODE>")]) 6144 6145(define_insn "*addqi_ext_1_rex64" 6146 [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q") 6147 (const_int 8) 6148 (const_int 8)) 6149 (plus:SI 6150 (zero_extract:SI 6151 (match_operand 1 "ext_register_operand" "0") 6152 (const_int 8) 6153 (const_int 8)) 6154 (match_operand:QI 2 "nonmemory_operand" "Qn"))) 6155 (clobber (reg:CC FLAGS_REG))] 6156 "TARGET_64BIT" 6157{ 6158 switch (get_attr_type (insn)) 6159 { 6160 case TYPE_INCDEC: 6161 if (operands[2] == const1_rtx) 6162 return "inc{b}\t%h0"; 6163 else 6164 { 6165 gcc_assert (operands[2] == constm1_rtx); 6166 return "dec{b}\t%h0"; 6167 } 6168 6169 default: 6170 return "add{b}\t{%2, %h0|%h0, %2}"; 6171 } 6172} 6173 [(set (attr "type") 6174 (if_then_else (match_operand:QI 2 "incdec_operand" "") 6175 (const_string "incdec") 6176 (const_string "alu"))) 6177 (set_attr "modrm" "1") 6178 (set_attr "mode" "QI")]) 6179 6180(define_insn "addqi_ext_1" 6181 [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q") 6182 (const_int 8) 6183 (const_int 8)) 6184 (plus:SI 6185 (zero_extract:SI 6186 (match_operand 1 "ext_register_operand" "0") 6187 (const_int 8) 6188 (const_int 8)) 6189 (match_operand:QI 2 "general_operand" "Qmn"))) 6190 (clobber (reg:CC FLAGS_REG))] 6191 "!TARGET_64BIT" 6192{ 6193 switch (get_attr_type (insn)) 6194 { 6195 case TYPE_INCDEC: 6196 if (operands[2] == const1_rtx) 6197 return "inc{b}\t%h0"; 6198 else 6199 { 6200 gcc_assert (operands[2] == constm1_rtx); 6201 return "dec{b}\t%h0"; 6202 } 6203 6204 default: 6205 return "add{b}\t{%2, %h0|%h0, %2}"; 6206 } 6207} 6208 [(set (attr "type") 6209 (if_then_else (match_operand:QI 2 "incdec_operand" "") 6210 (const_string "incdec") 6211 (const_string "alu"))) 6212 (set_attr "modrm" "1") 6213 (set_attr "mode" "QI")]) 6214 6215(define_insn "*addqi_ext_2" 6216 [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q") 6217 (const_int 8) 6218 (const_int 8)) 6219 (plus:SI 6220 (zero_extract:SI 6221 (match_operand 1 "ext_register_operand" "%0") 6222 (const_int 8) 6223 (const_int 8)) 6224 (zero_extract:SI 6225 (match_operand 2 "ext_register_operand" "Q") 6226 (const_int 8) 6227 (const_int 8)))) 6228 (clobber (reg:CC FLAGS_REG))] 6229 "" 6230 "add{b}\t{%h2, %h0|%h0, %h2}" 6231 [(set_attr "type" "alu") 6232 (set_attr "mode" "QI")]) 6233 6234;; The lea patterns for modes less than 32 bits need to be matched by 6235;; several insns converted to real lea by splitters. 6236 6237(define_insn_and_split "*lea_general_1" 6238 [(set (match_operand 0 "register_operand" "=r") 6239 (plus (plus (match_operand 1 "index_register_operand" "l") 6240 (match_operand 2 "register_operand" "r")) 6241 (match_operand 3 "immediate_operand" "i")))] 6242 "(GET_MODE (operands[0]) == QImode || GET_MODE (operands[0]) == HImode) 6243 && (!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun)) 6244 && GET_MODE (operands[0]) == GET_MODE (operands[1]) 6245 && GET_MODE (operands[0]) == GET_MODE (operands[2]) 6246 && (GET_MODE (operands[0]) == GET_MODE (operands[3]) 6247 || GET_MODE (operands[3]) == VOIDmode)" 6248 "#" 6249 "&& reload_completed" 6250 [(const_int 0)] 6251{ 6252 enum machine_mode mode = SImode; 6253 rtx pat; 6254 6255 operands[0] = gen_lowpart (mode, operands[0]); 6256 operands[1] = gen_lowpart (mode, operands[1]); 6257 operands[2] = gen_lowpart (mode, operands[2]); 6258 operands[3] = gen_lowpart (mode, operands[3]); 6259 6260 pat = gen_rtx_PLUS (mode, gen_rtx_PLUS (mode, operands[1], operands[2]), 6261 operands[3]); 6262 6263 emit_insn (gen_rtx_SET (VOIDmode, operands[0], pat)); 6264 DONE; 6265} 6266 [(set_attr "type" "lea") 6267 (set_attr "mode" "SI")]) 6268 6269(define_insn_and_split "*lea_general_2" 6270 [(set (match_operand 0 "register_operand" "=r") 6271 (plus (mult (match_operand 1 "index_register_operand" "l") 6272 (match_operand 2 "const248_operand" "n")) 6273 (match_operand 3 "nonmemory_operand" "ri")))] 6274 "(GET_MODE (operands[0]) == QImode || GET_MODE (operands[0]) == HImode) 6275 && (!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun)) 6276 && GET_MODE (operands[0]) == GET_MODE (operands[1]) 6277 && (GET_MODE (operands[0]) == GET_MODE (operands[3]) 6278 || GET_MODE (operands[3]) == VOIDmode)" 6279 "#" 6280 "&& reload_completed" 6281 [(const_int 0)] 6282{ 6283 enum machine_mode mode = SImode; 6284 rtx pat; 6285 6286 operands[0] = gen_lowpart (mode, operands[0]); 6287 operands[1] = gen_lowpart (mode, operands[1]); 6288 operands[3] = gen_lowpart (mode, operands[3]); 6289 6290 pat = gen_rtx_PLUS (mode, gen_rtx_MULT (mode, operands[1], operands[2]), 6291 operands[3]); 6292 6293 emit_insn (gen_rtx_SET (VOIDmode, operands[0], pat)); 6294 DONE; 6295} 6296 [(set_attr "type" "lea") 6297 (set_attr "mode" "SI")]) 6298 6299(define_insn_and_split "*lea_general_3" 6300 [(set (match_operand 0 "register_operand" "=r") 6301 (plus (plus (mult (match_operand 1 "index_register_operand" "l") 6302 (match_operand 2 "const248_operand" "n")) 6303 (match_operand 3 "register_operand" "r")) 6304 (match_operand 4 "immediate_operand" "i")))] 6305 "(GET_MODE (operands[0]) == QImode || GET_MODE (operands[0]) == HImode) 6306 && (!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun)) 6307 && GET_MODE (operands[0]) == GET_MODE (operands[1]) 6308 && GET_MODE (operands[0]) == GET_MODE (operands[3])" 6309 "#" 6310 "&& reload_completed" 6311 [(const_int 0)] 6312{ 6313 enum machine_mode mode = SImode; 6314 rtx pat; 6315 6316 operands[0] = gen_lowpart (mode, operands[0]); 6317 operands[1] = gen_lowpart (mode, operands[1]); 6318 operands[3] = gen_lowpart (mode, operands[3]); 6319 operands[4] = gen_lowpart (mode, operands[4]); 6320 6321 pat = gen_rtx_PLUS (mode, 6322 gen_rtx_PLUS (mode, 6323 gen_rtx_MULT (mode, operands[1], 6324 operands[2]), 6325 operands[3]), 6326 operands[4]); 6327 6328 emit_insn (gen_rtx_SET (VOIDmode, operands[0], pat)); 6329 DONE; 6330} 6331 [(set_attr "type" "lea") 6332 (set_attr "mode" "SI")]) 6333 6334(define_insn_and_split "*lea_general_4" 6335 [(set (match_operand 0 "register_operand" "=r") 6336 (any_or (ashift 6337 (match_operand 1 "index_register_operand" "l") 6338 (match_operand 2 "const_int_operand" "n")) 6339 (match_operand 3 "const_int_operand" "n")))] 6340 "(((GET_MODE (operands[0]) == QImode || GET_MODE (operands[0]) == HImode) 6341 && (!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))) 6342 || GET_MODE (operands[0]) == SImode 6343 || (TARGET_64BIT && GET_MODE (operands[0]) == DImode)) 6344 && GET_MODE (operands[0]) == GET_MODE (operands[1]) 6345 && ((unsigned HOST_WIDE_INT) INTVAL (operands[2])) - 1 < 3 6346 && ((unsigned HOST_WIDE_INT) INTVAL (operands[3]) 6347 < ((unsigned HOST_WIDE_INT) 1 << INTVAL (operands[2])))" 6348 "#" 6349 "&& reload_completed" 6350 [(const_int 0)] 6351{ 6352 enum machine_mode mode = GET_MODE (operands[0]); 6353 rtx pat; 6354 6355 if (GET_MODE_SIZE (mode) < GET_MODE_SIZE (SImode)) 6356 { 6357 mode = SImode; 6358 operands[0] = gen_lowpart (mode, operands[0]); 6359 operands[1] = gen_lowpart (mode, operands[1]); 6360 } 6361 6362 operands[2] = GEN_INT (1 << INTVAL (operands[2])); 6363 6364 pat = plus_constant (gen_rtx_MULT (mode, operands[1], operands[2]), 6365 INTVAL (operands[3])); 6366 6367 emit_insn (gen_rtx_SET (VOIDmode, operands[0], pat)); 6368 DONE; 6369} 6370 [(set_attr "type" "lea") 6371 (set (attr "mode") 6372 (if_then_else (match_operand:DI 0 "" "") 6373 (const_string "DI") 6374 (const_string "SI")))]) 6375 6376;; Subtract instructions 6377 6378(define_expand "sub<mode>3" 6379 [(set (match_operand:SDWIM 0 "nonimmediate_operand" "") 6380 (minus:SDWIM (match_operand:SDWIM 1 "nonimmediate_operand" "") 6381 (match_operand:SDWIM 2 "<general_operand>" "")))] 6382 "" 6383 "ix86_expand_binary_operator (MINUS, <MODE>mode, operands); DONE;") 6384 6385(define_insn_and_split "*sub<dwi>3_doubleword" 6386 [(set (match_operand:<DWI> 0 "nonimmediate_operand" "=r,o") 6387 (minus:<DWI> 6388 (match_operand:<DWI> 1 "nonimmediate_operand" "0,0") 6389 (match_operand:<DWI> 2 "<general_operand>" "ro<di>,r<di>"))) 6390 (clobber (reg:CC FLAGS_REG))] 6391 "ix86_binary_operator_ok (MINUS, <MODE>mode, operands)" 6392 "#" 6393 "reload_completed" 6394 [(parallel [(set (reg:CC FLAGS_REG) 6395 (compare:CC (match_dup 1) (match_dup 2))) 6396 (set (match_dup 0) 6397 (minus:DWIH (match_dup 1) (match_dup 2)))]) 6398 (parallel [(set (match_dup 3) 6399 (minus:DWIH 6400 (match_dup 4) 6401 (plus:DWIH 6402 (ltu:DWIH (reg:CC FLAGS_REG) (const_int 0)) 6403 (match_dup 5)))) 6404 (clobber (reg:CC FLAGS_REG))])] 6405 "split_double_mode (<DWI>mode, &operands[0], 3, &operands[0], &operands[3]);") 6406 6407(define_insn "*sub<mode>_1" 6408 [(set (match_operand:SWI 0 "nonimmediate_operand" "=<r>m,<r>") 6409 (minus:SWI 6410 (match_operand:SWI 1 "nonimmediate_operand" "0,0") 6411 (match_operand:SWI 2 "<general_operand>" "<r><i>,<r>m"))) 6412 (clobber (reg:CC FLAGS_REG))] 6413 "ix86_binary_operator_ok (MINUS, <MODE>mode, operands)" 6414 "sub{<imodesuffix>}\t{%2, %0|%0, %2}" 6415 [(set_attr "type" "alu") 6416 (set_attr "mode" "<MODE>")]) 6417 6418(define_insn "*subsi_1_zext" 6419 [(set (match_operand:DI 0 "register_operand" "=r") 6420 (zero_extend:DI 6421 (minus:SI (match_operand:SI 1 "register_operand" "0") 6422 (match_operand:SI 2 "x86_64_general_operand" "rme")))) 6423 (clobber (reg:CC FLAGS_REG))] 6424 "TARGET_64BIT && ix86_binary_operator_ok (MINUS, SImode, operands)" 6425 "sub{l}\t{%2, %k0|%k0, %2}" 6426 [(set_attr "type" "alu") 6427 (set_attr "mode" "SI")]) 6428 6429(define_insn "*subqi_1_slp" 6430 [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm,q")) 6431 (minus:QI (match_dup 0) 6432 (match_operand:QI 1 "general_operand" "qn,qm"))) 6433 (clobber (reg:CC FLAGS_REG))] 6434 "(! TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun)) 6435 && !(MEM_P (operands[0]) && MEM_P (operands[1]))" 6436 "sub{b}\t{%1, %0|%0, %1}" 6437 [(set_attr "type" "alu1") 6438 (set_attr "mode" "QI")]) 6439 6440(define_insn "*sub<mode>_2" 6441 [(set (reg FLAGS_REG) 6442 (compare 6443 (minus:SWI 6444 (match_operand:SWI 1 "nonimmediate_operand" "0,0") 6445 (match_operand:SWI 2 "<general_operand>" "<r><i>,<r>m")) 6446 (const_int 0))) 6447 (set (match_operand:SWI 0 "nonimmediate_operand" "=<r>m,<r>") 6448 (minus:SWI (match_dup 1) (match_dup 2)))] 6449 "ix86_match_ccmode (insn, CCGOCmode) 6450 && ix86_binary_operator_ok (MINUS, <MODE>mode, operands)" 6451 "sub{<imodesuffix>}\t{%2, %0|%0, %2}" 6452 [(set_attr "type" "alu") 6453 (set_attr "mode" "<MODE>")]) 6454 6455(define_insn "*subsi_2_zext" 6456 [(set (reg FLAGS_REG) 6457 (compare 6458 (minus:SI (match_operand:SI 1 "register_operand" "0") 6459 (match_operand:SI 2 "x86_64_general_operand" "rme")) 6460 (const_int 0))) 6461 (set (match_operand:DI 0 "register_operand" "=r") 6462 (zero_extend:DI 6463 (minus:SI (match_dup 1) 6464 (match_dup 2))))] 6465 "TARGET_64BIT && ix86_match_ccmode (insn, CCGOCmode) 6466 && ix86_binary_operator_ok (MINUS, SImode, operands)" 6467 "sub{l}\t{%2, %k0|%k0, %2}" 6468 [(set_attr "type" "alu") 6469 (set_attr "mode" "SI")]) 6470 6471(define_insn "*sub<mode>_3" 6472 [(set (reg FLAGS_REG) 6473 (compare (match_operand:SWI 1 "nonimmediate_operand" "0,0") 6474 (match_operand:SWI 2 "<general_operand>" "<r><i>,<r>m"))) 6475 (set (match_operand:SWI 0 "nonimmediate_operand" "=<r>m,<r>") 6476 (minus:SWI (match_dup 1) (match_dup 2)))] 6477 "ix86_match_ccmode (insn, CCmode) 6478 && ix86_binary_operator_ok (MINUS, <MODE>mode, operands)" 6479 "sub{<imodesuffix>}\t{%2, %0|%0, %2}" 6480 [(set_attr "type" "alu") 6481 (set_attr "mode" "<MODE>")]) 6482 6483(define_insn "*subsi_3_zext" 6484 [(set (reg FLAGS_REG) 6485 (compare (match_operand:SI 1 "register_operand" "0") 6486 (match_operand:SI 2 "x86_64_general_operand" "rme"))) 6487 (set (match_operand:DI 0 "register_operand" "=r") 6488 (zero_extend:DI 6489 (minus:SI (match_dup 1) 6490 (match_dup 2))))] 6491 "TARGET_64BIT && ix86_match_ccmode (insn, CCmode) 6492 && ix86_binary_operator_ok (MINUS, SImode, operands)" 6493 "sub{l}\t{%2, %1|%1, %2}" 6494 [(set_attr "type" "alu") 6495 (set_attr "mode" "SI")]) 6496 6497;; Add with carry and subtract with borrow 6498 6499(define_expand "<plusminus_insn><mode>3_carry" 6500 [(parallel 6501 [(set (match_operand:SWI 0 "nonimmediate_operand" "") 6502 (plusminus:SWI 6503 (match_operand:SWI 1 "nonimmediate_operand" "") 6504 (plus:SWI (match_operator:SWI 4 "ix86_carry_flag_operator" 6505 [(match_operand 3 "flags_reg_operand" "") 6506 (const_int 0)]) 6507 (match_operand:SWI 2 "<general_operand>" "")))) 6508 (clobber (reg:CC FLAGS_REG))])] 6509 "ix86_binary_operator_ok (<CODE>, <MODE>mode, operands)") 6510 6511(define_insn "*<plusminus_insn><mode>3_carry" 6512 [(set (match_operand:SWI 0 "nonimmediate_operand" "=<r>m,<r>") 6513 (plusminus:SWI 6514 (match_operand:SWI 1 "nonimmediate_operand" "<comm>0,0") 6515 (plus:SWI 6516 (match_operator 3 "ix86_carry_flag_operator" 6517 [(reg FLAGS_REG) (const_int 0)]) 6518 (match_operand:SWI 2 "<general_operand>" "<r><i>,<r>m")))) 6519 (clobber (reg:CC FLAGS_REG))] 6520 "ix86_binary_operator_ok (PLUS, <MODE>mode, operands)" 6521 "<plusminus_carry_mnemonic>{<imodesuffix>}\t{%2, %0|%0, %2}" 6522 [(set_attr "type" "alu") 6523 (set_attr "use_carry" "1") 6524 (set_attr "pent_pair" "pu") 6525 (set_attr "mode" "<MODE>")]) 6526 6527(define_insn "*addsi3_carry_zext" 6528 [(set (match_operand:DI 0 "register_operand" "=r") 6529 (zero_extend:DI 6530 (plus:SI (match_operand:SI 1 "nonimmediate_operand" "%0") 6531 (plus:SI (match_operator 3 "ix86_carry_flag_operator" 6532 [(reg FLAGS_REG) (const_int 0)]) 6533 (match_operand:SI 2 "x86_64_general_operand" "rme"))))) 6534 (clobber (reg:CC FLAGS_REG))] 6535 "TARGET_64BIT && ix86_binary_operator_ok (PLUS, SImode, operands)" 6536 "adc{l}\t{%2, %k0|%k0, %2}" 6537 [(set_attr "type" "alu") 6538 (set_attr "use_carry" "1") 6539 (set_attr "pent_pair" "pu") 6540 (set_attr "mode" "SI")]) 6541 6542(define_insn "*subsi3_carry_zext" 6543 [(set (match_operand:DI 0 "register_operand" "=r") 6544 (zero_extend:DI 6545 (minus:SI (match_operand:SI 1 "register_operand" "0") 6546 (plus:SI (match_operator 3 "ix86_carry_flag_operator" 6547 [(reg FLAGS_REG) (const_int 0)]) 6548 (match_operand:SI 2 "x86_64_general_operand" "rme"))))) 6549 (clobber (reg:CC FLAGS_REG))] 6550 "TARGET_64BIT && ix86_binary_operator_ok (MINUS, SImode, operands)" 6551 "sbb{l}\t{%2, %k0|%k0, %2}" 6552 [(set_attr "type" "alu") 6553 (set_attr "pent_pair" "pu") 6554 (set_attr "mode" "SI")]) 6555 6556;; Overflow setting add and subtract instructions 6557 6558(define_insn "*add<mode>3_cconly_overflow" 6559 [(set (reg:CCC FLAGS_REG) 6560 (compare:CCC 6561 (plus:SWI 6562 (match_operand:SWI 1 "nonimmediate_operand" "%0") 6563 (match_operand:SWI 2 "<general_operand>" "<g>")) 6564 (match_dup 1))) 6565 (clobber (match_scratch:SWI 0 "=<r>"))] 6566 "!(MEM_P (operands[1]) && MEM_P (operands[2]))" 6567 "add{<imodesuffix>}\t{%2, %0|%0, %2}" 6568 [(set_attr "type" "alu") 6569 (set_attr "mode" "<MODE>")]) 6570 6571(define_insn "*sub<mode>3_cconly_overflow" 6572 [(set (reg:CCC FLAGS_REG) 6573 (compare:CCC 6574 (minus:SWI 6575 (match_operand:SWI 0 "nonimmediate_operand" "<r>m,<r>") 6576 (match_operand:SWI 1 "<general_operand>" "<r><i>,<r>m")) 6577 (match_dup 0)))] 6578 "" 6579 "cmp{<imodesuffix>}\t{%1, %0|%0, %1}" 6580 [(set_attr "type" "icmp") 6581 (set_attr "mode" "<MODE>")]) 6582 6583(define_insn "*<plusminus_insn><mode>3_cc_overflow" 6584 [(set (reg:CCC FLAGS_REG) 6585 (compare:CCC 6586 (plusminus:SWI 6587 (match_operand:SWI 1 "nonimmediate_operand" "<comm>0,0") 6588 (match_operand:SWI 2 "<general_operand>" "<r><i>,<r>m")) 6589 (match_dup 1))) 6590 (set (match_operand:SWI 0 "nonimmediate_operand" "=<r>m,<r>") 6591 (plusminus:SWI (match_dup 1) (match_dup 2)))] 6592 "ix86_binary_operator_ok (<CODE>, <MODE>mode, operands)" 6593 "<plusminus_mnemonic>{<imodesuffix>}\t{%2, %0|%0, %2}" 6594 [(set_attr "type" "alu") 6595 (set_attr "mode" "<MODE>")]) 6596 6597(define_insn "*<plusminus_insn>si3_zext_cc_overflow" 6598 [(set (reg:CCC FLAGS_REG) 6599 (compare:CCC 6600 (plusminus:SI 6601 (match_operand:SI 1 "nonimmediate_operand" "<comm>0") 6602 (match_operand:SI 2 "x86_64_general_operand" "rme")) 6603 (match_dup 1))) 6604 (set (match_operand:DI 0 "register_operand" "=r") 6605 (zero_extend:DI (plusminus:SI (match_dup 1) (match_dup 2))))] 6606 "TARGET_64BIT && ix86_binary_operator_ok (<CODE>, SImode, operands)" 6607 "<plusminus_mnemonic>{l}\t{%2, %k0|%k0, %2}" 6608 [(set_attr "type" "alu") 6609 (set_attr "mode" "SI")]) 6610 6611;; The patterns that match these are at the end of this file. 6612 6613(define_expand "<plusminus_insn>xf3" 6614 [(set (match_operand:XF 0 "register_operand" "") 6615 (plusminus:XF 6616 (match_operand:XF 1 "register_operand" "") 6617 (match_operand:XF 2 "register_operand" "")))] 6618 "TARGET_80387") 6619 6620(define_expand "<plusminus_insn><mode>3" 6621 [(set (match_operand:MODEF 0 "register_operand" "") 6622 (plusminus:MODEF 6623 (match_operand:MODEF 1 "register_operand" "") 6624 (match_operand:MODEF 2 "nonimmediate_operand" "")))] 6625 "(TARGET_80387 && X87_ENABLE_ARITH (<MODE>mode)) 6626 || (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)") 6627 6628;; Multiply instructions 6629 6630(define_expand "mul<mode>3" 6631 [(parallel [(set (match_operand:SWIM248 0 "register_operand" "") 6632 (mult:SWIM248 6633 (match_operand:SWIM248 1 "register_operand" "") 6634 (match_operand:SWIM248 2 "<general_operand>" ""))) 6635 (clobber (reg:CC FLAGS_REG))])]) 6636 6637(define_expand "mulqi3" 6638 [(parallel [(set (match_operand:QI 0 "register_operand" "") 6639 (mult:QI 6640 (match_operand:QI 1 "register_operand" "") 6641 (match_operand:QI 2 "nonimmediate_operand" ""))) 6642 (clobber (reg:CC FLAGS_REG))])] 6643 "TARGET_QIMODE_MATH") 6644 6645;; On AMDFAM10 6646;; IMUL reg32/64, reg32/64, imm8 Direct 6647;; IMUL reg32/64, mem32/64, imm8 VectorPath 6648;; IMUL reg32/64, reg32/64, imm32 Direct 6649;; IMUL reg32/64, mem32/64, imm32 VectorPath 6650;; IMUL reg32/64, reg32/64 Direct 6651;; IMUL reg32/64, mem32/64 Direct 6652;; 6653;; On BDVER1, all above IMULs use DirectPath 6654 6655(define_insn "*mul<mode>3_1" 6656 [(set (match_operand:SWI48 0 "register_operand" "=r,r,r") 6657 (mult:SWI48 6658 (match_operand:SWI48 1 "nonimmediate_operand" "%rm,rm,0") 6659 (match_operand:SWI48 2 "<general_operand>" "K,<i>,mr"))) 6660 (clobber (reg:CC FLAGS_REG))] 6661 "!(MEM_P (operands[1]) && MEM_P (operands[2]))" 6662 "@ 6663 imul{<imodesuffix>}\t{%2, %1, %0|%0, %1, %2} 6664 imul{<imodesuffix>}\t{%2, %1, %0|%0, %1, %2} 6665 imul{<imodesuffix>}\t{%2, %0|%0, %2}" 6666 [(set_attr "type" "imul") 6667 (set_attr "prefix_0f" "0,0,1") 6668 (set (attr "athlon_decode") 6669 (cond [(eq_attr "cpu" "athlon") 6670 (const_string "vector") 6671 (eq_attr "alternative" "1") 6672 (const_string "vector") 6673 (and (eq_attr "alternative" "2") 6674 (match_operand 1 "memory_operand" "")) 6675 (const_string "vector")] 6676 (const_string "direct"))) 6677 (set (attr "amdfam10_decode") 6678 (cond [(and (eq_attr "alternative" "0,1") 6679 (match_operand 1 "memory_operand" "")) 6680 (const_string "vector")] 6681 (const_string "direct"))) 6682 (set_attr "bdver1_decode" "direct") 6683 (set_attr "mode" "<MODE>")]) 6684 6685(define_insn "*mulsi3_1_zext" 6686 [(set (match_operand:DI 0 "register_operand" "=r,r,r") 6687 (zero_extend:DI 6688 (mult:SI (match_operand:SI 1 "nonimmediate_operand" "%rm,rm,0") 6689 (match_operand:SI 2 "x86_64_general_operand" "K,e,mr")))) 6690 (clobber (reg:CC FLAGS_REG))] 6691 "TARGET_64BIT 6692 && !(MEM_P (operands[1]) && MEM_P (operands[2]))" 6693 "@ 6694 imul{l}\t{%2, %1, %k0|%k0, %1, %2} 6695 imul{l}\t{%2, %1, %k0|%k0, %1, %2} 6696 imul{l}\t{%2, %k0|%k0, %2}" 6697 [(set_attr "type" "imul") 6698 (set_attr "prefix_0f" "0,0,1") 6699 (set (attr "athlon_decode") 6700 (cond [(eq_attr "cpu" "athlon") 6701 (const_string "vector") 6702 (eq_attr "alternative" "1") 6703 (const_string "vector") 6704 (and (eq_attr "alternative" "2") 6705 (match_operand 1 "memory_operand" "")) 6706 (const_string "vector")] 6707 (const_string "direct"))) 6708 (set (attr "amdfam10_decode") 6709 (cond [(and (eq_attr "alternative" "0,1") 6710 (match_operand 1 "memory_operand" "")) 6711 (const_string "vector")] 6712 (const_string "direct"))) 6713 (set_attr "bdver1_decode" "direct") 6714 (set_attr "mode" "SI")]) 6715 6716;; On AMDFAM10 6717;; IMUL reg16, reg16, imm8 VectorPath 6718;; IMUL reg16, mem16, imm8 VectorPath 6719;; IMUL reg16, reg16, imm16 VectorPath 6720;; IMUL reg16, mem16, imm16 VectorPath 6721;; IMUL reg16, reg16 Direct 6722;; IMUL reg16, mem16 Direct 6723;; 6724;; On BDVER1, all HI MULs use DoublePath 6725 6726(define_insn "*mulhi3_1" 6727 [(set (match_operand:HI 0 "register_operand" "=r,r,r") 6728 (mult:HI (match_operand:HI 1 "nonimmediate_operand" "%rm,rm,0") 6729 (match_operand:HI 2 "general_operand" "K,n,mr"))) 6730 (clobber (reg:CC FLAGS_REG))] 6731 "TARGET_HIMODE_MATH 6732 && !(MEM_P (operands[1]) && MEM_P (operands[2]))" 6733 "@ 6734 imul{w}\t{%2, %1, %0|%0, %1, %2} 6735 imul{w}\t{%2, %1, %0|%0, %1, %2} 6736 imul{w}\t{%2, %0|%0, %2}" 6737 [(set_attr "type" "imul") 6738 (set_attr "prefix_0f" "0,0,1") 6739 (set (attr "athlon_decode") 6740 (cond [(eq_attr "cpu" "athlon") 6741 (const_string "vector") 6742 (eq_attr "alternative" "1,2") 6743 (const_string "vector")] 6744 (const_string "direct"))) 6745 (set (attr "amdfam10_decode") 6746 (cond [(eq_attr "alternative" "0,1") 6747 (const_string "vector")] 6748 (const_string "direct"))) 6749 (set_attr "bdver1_decode" "double") 6750 (set_attr "mode" "HI")]) 6751 6752;;On AMDFAM10 and BDVER1 6753;; MUL reg8 Direct 6754;; MUL mem8 Direct 6755 6756(define_insn "*mulqi3_1" 6757 [(set (match_operand:QI 0 "register_operand" "=a") 6758 (mult:QI (match_operand:QI 1 "nonimmediate_operand" "%0") 6759 (match_operand:QI 2 "nonimmediate_operand" "qm"))) 6760 (clobber (reg:CC FLAGS_REG))] 6761 "TARGET_QIMODE_MATH 6762 && !(MEM_P (operands[1]) && MEM_P (operands[2]))" 6763 "mul{b}\t%2" 6764 [(set_attr "type" "imul") 6765 (set_attr "length_immediate" "0") 6766 (set (attr "athlon_decode") 6767 (if_then_else (eq_attr "cpu" "athlon") 6768 (const_string "vector") 6769 (const_string "direct"))) 6770 (set_attr "amdfam10_decode" "direct") 6771 (set_attr "bdver1_decode" "direct") 6772 (set_attr "mode" "QI")]) 6773 6774(define_expand "<u>mul<mode><dwi>3" 6775 [(parallel [(set (match_operand:<DWI> 0 "register_operand" "") 6776 (mult:<DWI> 6777 (any_extend:<DWI> 6778 (match_operand:DWIH 1 "nonimmediate_operand" "")) 6779 (any_extend:<DWI> 6780 (match_operand:DWIH 2 "register_operand" "")))) 6781 (clobber (reg:CC FLAGS_REG))])]) 6782 6783(define_expand "<u>mulqihi3" 6784 [(parallel [(set (match_operand:HI 0 "register_operand" "") 6785 (mult:HI 6786 (any_extend:HI 6787 (match_operand:QI 1 "nonimmediate_operand" "")) 6788 (any_extend:HI 6789 (match_operand:QI 2 "register_operand" "")))) 6790 (clobber (reg:CC FLAGS_REG))])] 6791 "TARGET_QIMODE_MATH") 6792 6793(define_insn "*bmi2_umulditi3_1" 6794 [(set (match_operand:DI 0 "register_operand" "=r") 6795 (mult:DI 6796 (match_operand:DI 2 "nonimmediate_operand" "%d") 6797 (match_operand:DI 3 "nonimmediate_operand" "rm"))) 6798 (set (match_operand:DI 1 "register_operand" "=r") 6799 (truncate:DI 6800 (lshiftrt:TI 6801 (mult:TI (zero_extend:TI (match_dup 2)) 6802 (zero_extend:TI (match_dup 3))) 6803 (const_int 64))))] 6804 "TARGET_64BIT && TARGET_BMI2 6805 && !(MEM_P (operands[1]) && MEM_P (operands[2]))" 6806 "mulx\t{%3, %0, %1|%1, %0, %3}" 6807 [(set_attr "type" "imulx") 6808 (set_attr "prefix" "vex") 6809 (set_attr "mode" "DI")]) 6810 6811(define_insn "*bmi2_umulsidi3_1" 6812 [(set (match_operand:SI 0 "register_operand" "=r") 6813 (mult:SI 6814 (match_operand:SI 2 "nonimmediate_operand" "%d") 6815 (match_operand:SI 3 "nonimmediate_operand" "rm"))) 6816 (set (match_operand:SI 1 "register_operand" "=r") 6817 (truncate:SI 6818 (lshiftrt:DI 6819 (mult:DI (zero_extend:DI (match_dup 2)) 6820 (zero_extend:DI (match_dup 3))) 6821 (const_int 32))))] 6822 "!TARGET_64BIT && TARGET_BMI2 6823 && !(MEM_P (operands[1]) && MEM_P (operands[2]))" 6824 "mulx\t{%3, %0, %1|%1, %0, %3}" 6825 [(set_attr "type" "imulx") 6826 (set_attr "prefix" "vex") 6827 (set_attr "mode" "SI")]) 6828 6829(define_insn "*umul<mode><dwi>3_1" 6830 [(set (match_operand:<DWI> 0 "register_operand" "=A,r") 6831 (mult:<DWI> 6832 (zero_extend:<DWI> 6833 (match_operand:DWIH 1 "nonimmediate_operand" "%0,d")) 6834 (zero_extend:<DWI> 6835 (match_operand:DWIH 2 "nonimmediate_operand" "rm,rm")))) 6836 (clobber (reg:CC FLAGS_REG))] 6837 "!(MEM_P (operands[1]) && MEM_P (operands[2]))" 6838 "@ 6839 mul{<imodesuffix>}\t%2 6840 #" 6841 [(set_attr "isa" "*,bmi2") 6842 (set_attr "type" "imul,imulx") 6843 (set_attr "length_immediate" "0,*") 6844 (set (attr "athlon_decode") 6845 (cond [(eq_attr "alternative" "0") 6846 (if_then_else (eq_attr "cpu" "athlon") 6847 (const_string "vector") 6848 (const_string "double"))] 6849 (const_string "*"))) 6850 (set_attr "amdfam10_decode" "double,*") 6851 (set_attr "bdver1_decode" "direct,*") 6852 (set_attr "prefix" "orig,vex") 6853 (set_attr "mode" "<MODE>")]) 6854 6855;; Convert mul to the mulx pattern to avoid flags dependency. 6856(define_split 6857 [(set (match_operand:<DWI> 0 "register_operand" "") 6858 (mult:<DWI> 6859 (zero_extend:<DWI> 6860 (match_operand:DWIH 1 "register_operand" "")) 6861 (zero_extend:<DWI> 6862 (match_operand:DWIH 2 "nonimmediate_operand" "")))) 6863 (clobber (reg:CC FLAGS_REG))] 6864 "TARGET_BMI2 && reload_completed 6865 && true_regnum (operands[1]) == DX_REG" 6866 [(parallel [(set (match_dup 3) 6867 (mult:DWIH (match_dup 1) (match_dup 2))) 6868 (set (match_dup 4) 6869 (truncate:DWIH 6870 (lshiftrt:<DWI> 6871 (mult:<DWI> (zero_extend:<DWI> (match_dup 1)) 6872 (zero_extend:<DWI> (match_dup 2))) 6873 (match_dup 5))))])] 6874{ 6875 split_double_mode (<DWI>mode, &operands[0], 1, &operands[3], &operands[4]); 6876 6877 operands[5] = GEN_INT (GET_MODE_BITSIZE (<MODE>mode)); 6878}) 6879 6880(define_insn "*mul<mode><dwi>3_1" 6881 [(set (match_operand:<DWI> 0 "register_operand" "=A") 6882 (mult:<DWI> 6883 (sign_extend:<DWI> 6884 (match_operand:DWIH 1 "nonimmediate_operand" "%0")) 6885 (sign_extend:<DWI> 6886 (match_operand:DWIH 2 "nonimmediate_operand" "rm")))) 6887 (clobber (reg:CC FLAGS_REG))] 6888 "!(MEM_P (operands[1]) && MEM_P (operands[2]))" 6889 "imul{<imodesuffix>}\t%2" 6890 [(set_attr "type" "imul") 6891 (set_attr "length_immediate" "0") 6892 (set (attr "athlon_decode") 6893 (if_then_else (eq_attr "cpu" "athlon") 6894 (const_string "vector") 6895 (const_string "double"))) 6896 (set_attr "amdfam10_decode" "double") 6897 (set_attr "bdver1_decode" "direct") 6898 (set_attr "mode" "<MODE>")]) 6899 6900(define_insn "*<u>mulqihi3_1" 6901 [(set (match_operand:HI 0 "register_operand" "=a") 6902 (mult:HI 6903 (any_extend:HI 6904 (match_operand:QI 1 "nonimmediate_operand" "%0")) 6905 (any_extend:HI 6906 (match_operand:QI 2 "nonimmediate_operand" "qm")))) 6907 (clobber (reg:CC FLAGS_REG))] 6908 "TARGET_QIMODE_MATH 6909 && !(MEM_P (operands[1]) && MEM_P (operands[2]))" 6910 "<sgnprefix>mul{b}\t%2" 6911 [(set_attr "type" "imul") 6912 (set_attr "length_immediate" "0") 6913 (set (attr "athlon_decode") 6914 (if_then_else (eq_attr "cpu" "athlon") 6915 (const_string "vector") 6916 (const_string "direct"))) 6917 (set_attr "amdfam10_decode" "direct") 6918 (set_attr "bdver1_decode" "direct") 6919 (set_attr "mode" "QI")]) 6920 6921(define_expand "<s>mul<mode>3_highpart" 6922 [(parallel [(set (match_operand:SWI48 0 "register_operand" "") 6923 (truncate:SWI48 6924 (lshiftrt:<DWI> 6925 (mult:<DWI> 6926 (any_extend:<DWI> 6927 (match_operand:SWI48 1 "nonimmediate_operand" "")) 6928 (any_extend:<DWI> 6929 (match_operand:SWI48 2 "register_operand" ""))) 6930 (match_dup 4)))) 6931 (clobber (match_scratch:SWI48 3 "")) 6932 (clobber (reg:CC FLAGS_REG))])] 6933 "" 6934 "operands[4] = GEN_INT (GET_MODE_BITSIZE (<MODE>mode));") 6935 6936(define_insn "*<s>muldi3_highpart_1" 6937 [(set (match_operand:DI 0 "register_operand" "=d") 6938 (truncate:DI 6939 (lshiftrt:TI 6940 (mult:TI 6941 (any_extend:TI 6942 (match_operand:DI 1 "nonimmediate_operand" "%a")) 6943 (any_extend:TI 6944 (match_operand:DI 2 "nonimmediate_operand" "rm"))) 6945 (const_int 64)))) 6946 (clobber (match_scratch:DI 3 "=1")) 6947 (clobber (reg:CC FLAGS_REG))] 6948 "TARGET_64BIT 6949 && !(MEM_P (operands[1]) && MEM_P (operands[2]))" 6950 "<sgnprefix>mul{q}\t%2" 6951 [(set_attr "type" "imul") 6952 (set_attr "length_immediate" "0") 6953 (set (attr "athlon_decode") 6954 (if_then_else (eq_attr "cpu" "athlon") 6955 (const_string "vector") 6956 (const_string "double"))) 6957 (set_attr "amdfam10_decode" "double") 6958 (set_attr "bdver1_decode" "direct") 6959 (set_attr "mode" "DI")]) 6960 6961(define_insn "*<s>mulsi3_highpart_1" 6962 [(set (match_operand:SI 0 "register_operand" "=d") 6963 (truncate:SI 6964 (lshiftrt:DI 6965 (mult:DI 6966 (any_extend:DI 6967 (match_operand:SI 1 "nonimmediate_operand" "%a")) 6968 (any_extend:DI 6969 (match_operand:SI 2 "nonimmediate_operand" "rm"))) 6970 (const_int 32)))) 6971 (clobber (match_scratch:SI 3 "=1")) 6972 (clobber (reg:CC FLAGS_REG))] 6973 "!(MEM_P (operands[1]) && MEM_P (operands[2]))" 6974 "<sgnprefix>mul{l}\t%2" 6975 [(set_attr "type" "imul") 6976 (set_attr "length_immediate" "0") 6977 (set (attr "athlon_decode") 6978 (if_then_else (eq_attr "cpu" "athlon") 6979 (const_string "vector") 6980 (const_string "double"))) 6981 (set_attr "amdfam10_decode" "double") 6982 (set_attr "bdver1_decode" "direct") 6983 (set_attr "mode" "SI")]) 6984 6985(define_insn "*<s>mulsi3_highpart_zext" 6986 [(set (match_operand:DI 0 "register_operand" "=d") 6987 (zero_extend:DI (truncate:SI 6988 (lshiftrt:DI 6989 (mult:DI (any_extend:DI 6990 (match_operand:SI 1 "nonimmediate_operand" "%a")) 6991 (any_extend:DI 6992 (match_operand:SI 2 "nonimmediate_operand" "rm"))) 6993 (const_int 32))))) 6994 (clobber (match_scratch:SI 3 "=1")) 6995 (clobber (reg:CC FLAGS_REG))] 6996 "TARGET_64BIT 6997 && !(MEM_P (operands[1]) && MEM_P (operands[2]))" 6998 "<sgnprefix>mul{l}\t%2" 6999 [(set_attr "type" "imul") 7000 (set_attr "length_immediate" "0") 7001 (set (attr "athlon_decode") 7002 (if_then_else (eq_attr "cpu" "athlon") 7003 (const_string "vector") 7004 (const_string "double"))) 7005 (set_attr "amdfam10_decode" "double") 7006 (set_attr "bdver1_decode" "direct") 7007 (set_attr "mode" "SI")]) 7008 7009;; The patterns that match these are at the end of this file. 7010 7011(define_expand "mulxf3" 7012 [(set (match_operand:XF 0 "register_operand" "") 7013 (mult:XF (match_operand:XF 1 "register_operand" "") 7014 (match_operand:XF 2 "register_operand" "")))] 7015 "TARGET_80387") 7016 7017(define_expand "mul<mode>3" 7018 [(set (match_operand:MODEF 0 "register_operand" "") 7019 (mult:MODEF (match_operand:MODEF 1 "register_operand" "") 7020 (match_operand:MODEF 2 "nonimmediate_operand" "")))] 7021 "(TARGET_80387 && X87_ENABLE_ARITH (<MODE>mode)) 7022 || (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)") 7023 7024;; Divide instructions 7025 7026;; The patterns that match these are at the end of this file. 7027 7028(define_expand "divxf3" 7029 [(set (match_operand:XF 0 "register_operand" "") 7030 (div:XF (match_operand:XF 1 "register_operand" "") 7031 (match_operand:XF 2 "register_operand" "")))] 7032 "TARGET_80387") 7033 7034(define_expand "divdf3" 7035 [(set (match_operand:DF 0 "register_operand" "") 7036 (div:DF (match_operand:DF 1 "register_operand" "") 7037 (match_operand:DF 2 "nonimmediate_operand" "")))] 7038 "(TARGET_80387 && X87_ENABLE_ARITH (DFmode)) 7039 || (TARGET_SSE2 && TARGET_SSE_MATH)") 7040 7041(define_expand "divsf3" 7042 [(set (match_operand:SF 0 "register_operand" "") 7043 (div:SF (match_operand:SF 1 "register_operand" "") 7044 (match_operand:SF 2 "nonimmediate_operand" "")))] 7045 "(TARGET_80387 && X87_ENABLE_ARITH (SFmode)) 7046 || TARGET_SSE_MATH" 7047{ 7048 if (TARGET_SSE_MATH 7049 && TARGET_RECIP_DIV 7050 && optimize_insn_for_speed_p () 7051 && flag_finite_math_only && !flag_trapping_math 7052 && flag_unsafe_math_optimizations) 7053 { 7054 ix86_emit_swdivsf (operands[0], operands[1], 7055 operands[2], SFmode); 7056 DONE; 7057 } 7058}) 7059 7060;; Divmod instructions. 7061 7062(define_expand "divmod<mode>4" 7063 [(parallel [(set (match_operand:SWIM248 0 "register_operand" "") 7064 (div:SWIM248 7065 (match_operand:SWIM248 1 "register_operand" "") 7066 (match_operand:SWIM248 2 "nonimmediate_operand" ""))) 7067 (set (match_operand:SWIM248 3 "register_operand" "") 7068 (mod:SWIM248 (match_dup 1) (match_dup 2))) 7069 (clobber (reg:CC FLAGS_REG))])]) 7070 7071;; Split with 8bit unsigned divide: 7072;; if (dividend an divisor are in [0-255]) 7073;; use 8bit unsigned integer divide 7074;; else 7075;; use original integer divide 7076(define_split 7077 [(set (match_operand:SWI48 0 "register_operand" "") 7078 (div:SWI48 (match_operand:SWI48 2 "register_operand" "") 7079 (match_operand:SWI48 3 "nonimmediate_operand" ""))) 7080 (set (match_operand:SWI48 1 "register_operand" "") 7081 (mod:SWI48 (match_dup 2) (match_dup 3))) 7082 (clobber (reg:CC FLAGS_REG))] 7083 "TARGET_USE_8BIT_IDIV 7084 && TARGET_QIMODE_MATH 7085 && can_create_pseudo_p () 7086 && !optimize_insn_for_size_p ()" 7087 [(const_int 0)] 7088 "ix86_split_idivmod (<MODE>mode, operands, true); DONE;") 7089 7090(define_insn_and_split "divmod<mode>4_1" 7091 [(set (match_operand:SWI48 0 "register_operand" "=a") 7092 (div:SWI48 (match_operand:SWI48 2 "register_operand" "0") 7093 (match_operand:SWI48 3 "nonimmediate_operand" "rm"))) 7094 (set (match_operand:SWI48 1 "register_operand" "=&d") 7095 (mod:SWI48 (match_dup 2) (match_dup 3))) 7096 (unspec [(const_int 0)] UNSPEC_DIV_ALREADY_SPLIT) 7097 (clobber (reg:CC FLAGS_REG))] 7098 "" 7099 "#" 7100 "reload_completed" 7101 [(parallel [(set (match_dup 1) 7102 (ashiftrt:SWI48 (match_dup 4) (match_dup 5))) 7103 (clobber (reg:CC FLAGS_REG))]) 7104 (parallel [(set (match_dup 0) 7105 (div:SWI48 (match_dup 2) (match_dup 3))) 7106 (set (match_dup 1) 7107 (mod:SWI48 (match_dup 2) (match_dup 3))) 7108 (use (match_dup 1)) 7109 (clobber (reg:CC FLAGS_REG))])] 7110{ 7111 operands[5] = GEN_INT (GET_MODE_BITSIZE (<MODE>mode)-1); 7112 7113 if (optimize_function_for_size_p (cfun) || TARGET_USE_CLTD) 7114 operands[4] = operands[2]; 7115 else 7116 { 7117 /* Avoid use of cltd in favor of a mov+shift. */ 7118 emit_move_insn (operands[1], operands[2]); 7119 operands[4] = operands[1]; 7120 } 7121} 7122 [(set_attr "type" "multi") 7123 (set_attr "mode" "<MODE>")]) 7124 7125(define_insn_and_split "*divmod<mode>4" 7126 [(set (match_operand:SWIM248 0 "register_operand" "=a") 7127 (div:SWIM248 (match_operand:SWIM248 2 "register_operand" "0") 7128 (match_operand:SWIM248 3 "nonimmediate_operand" "rm"))) 7129 (set (match_operand:SWIM248 1 "register_operand" "=&d") 7130 (mod:SWIM248 (match_dup 2) (match_dup 3))) 7131 (clobber (reg:CC FLAGS_REG))] 7132 "" 7133 "#" 7134 "reload_completed" 7135 [(parallel [(set (match_dup 1) 7136 (ashiftrt:SWIM248 (match_dup 4) (match_dup 5))) 7137 (clobber (reg:CC FLAGS_REG))]) 7138 (parallel [(set (match_dup 0) 7139 (div:SWIM248 (match_dup 2) (match_dup 3))) 7140 (set (match_dup 1) 7141 (mod:SWIM248 (match_dup 2) (match_dup 3))) 7142 (use (match_dup 1)) 7143 (clobber (reg:CC FLAGS_REG))])] 7144{ 7145 operands[5] = GEN_INT (GET_MODE_BITSIZE (<MODE>mode)-1); 7146 7147 if (<MODE>mode != HImode 7148 && (optimize_function_for_size_p (cfun) || TARGET_USE_CLTD)) 7149 operands[4] = operands[2]; 7150 else 7151 { 7152 /* Avoid use of cltd in favor of a mov+shift. */ 7153 emit_move_insn (operands[1], operands[2]); 7154 operands[4] = operands[1]; 7155 } 7156} 7157 [(set_attr "type" "multi") 7158 (set_attr "mode" "<MODE>")]) 7159 7160(define_insn "*divmod<mode>4_noext" 7161 [(set (match_operand:SWIM248 0 "register_operand" "=a") 7162 (div:SWIM248 (match_operand:SWIM248 2 "register_operand" "0") 7163 (match_operand:SWIM248 3 "nonimmediate_operand" "rm"))) 7164 (set (match_operand:SWIM248 1 "register_operand" "=d") 7165 (mod:SWIM248 (match_dup 2) (match_dup 3))) 7166 (use (match_operand:SWIM248 4 "register_operand" "1")) 7167 (clobber (reg:CC FLAGS_REG))] 7168 "" 7169 "idiv{<imodesuffix>}\t%3" 7170 [(set_attr "type" "idiv") 7171 (set_attr "mode" "<MODE>")]) 7172 7173(define_expand "divmodqi4" 7174 [(parallel [(set (match_operand:QI 0 "register_operand" "") 7175 (div:QI 7176 (match_operand:QI 1 "register_operand" "") 7177 (match_operand:QI 2 "nonimmediate_operand" ""))) 7178 (set (match_operand:QI 3 "register_operand" "") 7179 (mod:QI (match_dup 1) (match_dup 2))) 7180 (clobber (reg:CC FLAGS_REG))])] 7181 "TARGET_QIMODE_MATH" 7182{ 7183 rtx div, mod, insn; 7184 rtx tmp0, tmp1; 7185 7186 tmp0 = gen_reg_rtx (HImode); 7187 tmp1 = gen_reg_rtx (HImode); 7188 7189 /* Extend operands[1] to HImode. Generate 8bit divide. Result is 7190 in AX. */ 7191 emit_insn (gen_extendqihi2 (tmp1, operands[1])); 7192 emit_insn (gen_divmodhiqi3 (tmp0, tmp1, operands[2])); 7193 7194 /* Extract remainder from AH. */ 7195 tmp1 = gen_rtx_SIGN_EXTRACT (QImode, tmp0, GEN_INT (8), GEN_INT (8)); 7196 insn = emit_move_insn (operands[3], tmp1); 7197 7198 mod = gen_rtx_MOD (QImode, operands[1], operands[2]); 7199 set_unique_reg_note (insn, REG_EQUAL, mod); 7200 7201 /* Extract quotient from AL. */ 7202 insn = emit_move_insn (operands[0], gen_lowpart (QImode, tmp0)); 7203 7204 div = gen_rtx_DIV (QImode, operands[1], operands[2]); 7205 set_unique_reg_note (insn, REG_EQUAL, div); 7206 7207 DONE; 7208}) 7209 7210;; Divide AX by r/m8, with result stored in 7211;; AL <- Quotient 7212;; AH <- Remainder 7213;; Change div/mod to HImode and extend the second argument to HImode 7214;; so that mode of div/mod matches with mode of arguments. Otherwise 7215;; combine may fail. 7216(define_insn "divmodhiqi3" 7217 [(set (match_operand:HI 0 "register_operand" "=a") 7218 (ior:HI 7219 (ashift:HI 7220 (zero_extend:HI 7221 (truncate:QI 7222 (mod:HI (match_operand:HI 1 "register_operand" "0") 7223 (sign_extend:HI 7224 (match_operand:QI 2 "nonimmediate_operand" "qm"))))) 7225 (const_int 8)) 7226 (zero_extend:HI 7227 (truncate:QI 7228 (div:HI (match_dup 1) (sign_extend:HI (match_dup 2))))))) 7229 (clobber (reg:CC FLAGS_REG))] 7230 "TARGET_QIMODE_MATH" 7231 "idiv{b}\t%2" 7232 [(set_attr "type" "idiv") 7233 (set_attr "mode" "QI")]) 7234 7235(define_expand "udivmod<mode>4" 7236 [(parallel [(set (match_operand:SWIM248 0 "register_operand" "") 7237 (udiv:SWIM248 7238 (match_operand:SWIM248 1 "register_operand" "") 7239 (match_operand:SWIM248 2 "nonimmediate_operand" ""))) 7240 (set (match_operand:SWIM248 3 "register_operand" "") 7241 (umod:SWIM248 (match_dup 1) (match_dup 2))) 7242 (clobber (reg:CC FLAGS_REG))])]) 7243 7244;; Split with 8bit unsigned divide: 7245;; if (dividend an divisor are in [0-255]) 7246;; use 8bit unsigned integer divide 7247;; else 7248;; use original integer divide 7249(define_split 7250 [(set (match_operand:SWI48 0 "register_operand" "") 7251 (udiv:SWI48 (match_operand:SWI48 2 "register_operand" "") 7252 (match_operand:SWI48 3 "nonimmediate_operand" ""))) 7253 (set (match_operand:SWI48 1 "register_operand" "") 7254 (umod:SWI48 (match_dup 2) (match_dup 3))) 7255 (clobber (reg:CC FLAGS_REG))] 7256 "TARGET_USE_8BIT_IDIV 7257 && TARGET_QIMODE_MATH 7258 && can_create_pseudo_p () 7259 && !optimize_insn_for_size_p ()" 7260 [(const_int 0)] 7261 "ix86_split_idivmod (<MODE>mode, operands, false); DONE;") 7262 7263(define_insn_and_split "udivmod<mode>4_1" 7264 [(set (match_operand:SWI48 0 "register_operand" "=a") 7265 (udiv:SWI48 (match_operand:SWI48 2 "register_operand" "0") 7266 (match_operand:SWI48 3 "nonimmediate_operand" "rm"))) 7267 (set (match_operand:SWI48 1 "register_operand" "=&d") 7268 (umod:SWI48 (match_dup 2) (match_dup 3))) 7269 (unspec [(const_int 0)] UNSPEC_DIV_ALREADY_SPLIT) 7270 (clobber (reg:CC FLAGS_REG))] 7271 "" 7272 "#" 7273 "reload_completed" 7274 [(set (match_dup 1) (const_int 0)) 7275 (parallel [(set (match_dup 0) 7276 (udiv:SWI48 (match_dup 2) (match_dup 3))) 7277 (set (match_dup 1) 7278 (umod:SWI48 (match_dup 2) (match_dup 3))) 7279 (use (match_dup 1)) 7280 (clobber (reg:CC FLAGS_REG))])] 7281 "" 7282 [(set_attr "type" "multi") 7283 (set_attr "mode" "<MODE>")]) 7284 7285(define_insn_and_split "*udivmod<mode>4" 7286 [(set (match_operand:SWIM248 0 "register_operand" "=a") 7287 (udiv:SWIM248 (match_operand:SWIM248 2 "register_operand" "0") 7288 (match_operand:SWIM248 3 "nonimmediate_operand" "rm"))) 7289 (set (match_operand:SWIM248 1 "register_operand" "=&d") 7290 (umod:SWIM248 (match_dup 2) (match_dup 3))) 7291 (clobber (reg:CC FLAGS_REG))] 7292 "" 7293 "#" 7294 "reload_completed" 7295 [(set (match_dup 1) (const_int 0)) 7296 (parallel [(set (match_dup 0) 7297 (udiv:SWIM248 (match_dup 2) (match_dup 3))) 7298 (set (match_dup 1) 7299 (umod:SWIM248 (match_dup 2) (match_dup 3))) 7300 (use (match_dup 1)) 7301 (clobber (reg:CC FLAGS_REG))])] 7302 "" 7303 [(set_attr "type" "multi") 7304 (set_attr "mode" "<MODE>")]) 7305 7306(define_insn "*udivmod<mode>4_noext" 7307 [(set (match_operand:SWIM248 0 "register_operand" "=a") 7308 (udiv:SWIM248 (match_operand:SWIM248 2 "register_operand" "0") 7309 (match_operand:SWIM248 3 "nonimmediate_operand" "rm"))) 7310 (set (match_operand:SWIM248 1 "register_operand" "=d") 7311 (umod:SWIM248 (match_dup 2) (match_dup 3))) 7312 (use (match_operand:SWIM248 4 "register_operand" "1")) 7313 (clobber (reg:CC FLAGS_REG))] 7314 "" 7315 "div{<imodesuffix>}\t%3" 7316 [(set_attr "type" "idiv") 7317 (set_attr "mode" "<MODE>")]) 7318 7319(define_expand "udivmodqi4" 7320 [(parallel [(set (match_operand:QI 0 "register_operand" "") 7321 (udiv:QI 7322 (match_operand:QI 1 "register_operand" "") 7323 (match_operand:QI 2 "nonimmediate_operand" ""))) 7324 (set (match_operand:QI 3 "register_operand" "") 7325 (umod:QI (match_dup 1) (match_dup 2))) 7326 (clobber (reg:CC FLAGS_REG))])] 7327 "TARGET_QIMODE_MATH" 7328{ 7329 rtx div, mod, insn; 7330 rtx tmp0, tmp1; 7331 7332 tmp0 = gen_reg_rtx (HImode); 7333 tmp1 = gen_reg_rtx (HImode); 7334 7335 /* Extend operands[1] to HImode. Generate 8bit divide. Result is 7336 in AX. */ 7337 emit_insn (gen_zero_extendqihi2 (tmp1, operands[1])); 7338 emit_insn (gen_udivmodhiqi3 (tmp0, tmp1, operands[2])); 7339 7340 /* Extract remainder from AH. */ 7341 tmp1 = gen_rtx_ZERO_EXTRACT (SImode, tmp0, GEN_INT (8), GEN_INT (8)); 7342 tmp1 = simplify_gen_subreg (QImode, tmp1, SImode, 0); 7343 insn = emit_move_insn (operands[3], tmp1); 7344 7345 mod = gen_rtx_UMOD (QImode, operands[1], operands[2]); 7346 set_unique_reg_note (insn, REG_EQUAL, mod); 7347 7348 /* Extract quotient from AL. */ 7349 insn = emit_move_insn (operands[0], gen_lowpart (QImode, tmp0)); 7350 7351 div = gen_rtx_UDIV (QImode, operands[1], operands[2]); 7352 set_unique_reg_note (insn, REG_EQUAL, div); 7353 7354 DONE; 7355}) 7356 7357(define_insn "udivmodhiqi3" 7358 [(set (match_operand:HI 0 "register_operand" "=a") 7359 (ior:HI 7360 (ashift:HI 7361 (zero_extend:HI 7362 (truncate:QI 7363 (mod:HI (match_operand:HI 1 "register_operand" "0") 7364 (zero_extend:HI 7365 (match_operand:QI 2 "nonimmediate_operand" "qm"))))) 7366 (const_int 8)) 7367 (zero_extend:HI 7368 (truncate:QI 7369 (div:HI (match_dup 1) (zero_extend:HI (match_dup 2))))))) 7370 (clobber (reg:CC FLAGS_REG))] 7371 "TARGET_QIMODE_MATH" 7372 "div{b}\t%2" 7373 [(set_attr "type" "idiv") 7374 (set_attr "mode" "QI")]) 7375 7376;; We cannot use div/idiv for double division, because it causes 7377;; "division by zero" on the overflow and that's not what we expect 7378;; from truncate. Because true (non truncating) double division is 7379;; never generated, we can't create this insn anyway. 7380; 7381;(define_insn "" 7382; [(set (match_operand:SI 0 "register_operand" "=a") 7383; (truncate:SI 7384; (udiv:DI (match_operand:DI 1 "register_operand" "A") 7385; (zero_extend:DI 7386; (match_operand:SI 2 "nonimmediate_operand" "rm"))))) 7387; (set (match_operand:SI 3 "register_operand" "=d") 7388; (truncate:SI 7389; (umod:DI (match_dup 1) (zero_extend:DI (match_dup 2))))) 7390; (clobber (reg:CC FLAGS_REG))] 7391; "" 7392; "div{l}\t{%2, %0|%0, %2}" 7393; [(set_attr "type" "idiv")]) 7394 7395;;- Logical AND instructions 7396 7397;; On Pentium, "test imm, reg" is pairable only with eax, ax, and al. 7398;; Note that this excludes ah. 7399 7400(define_expand "testsi_ccno_1" 7401 [(set (reg:CCNO FLAGS_REG) 7402 (compare:CCNO 7403 (and:SI (match_operand:SI 0 "nonimmediate_operand" "") 7404 (match_operand:SI 1 "x86_64_nonmemory_operand" "")) 7405 (const_int 0)))]) 7406 7407(define_expand "testqi_ccz_1" 7408 [(set (reg:CCZ FLAGS_REG) 7409 (compare:CCZ (and:QI (match_operand:QI 0 "nonimmediate_operand" "") 7410 (match_operand:QI 1 "nonmemory_operand" "")) 7411 (const_int 0)))]) 7412 7413(define_expand "testdi_ccno_1" 7414 [(set (reg:CCNO FLAGS_REG) 7415 (compare:CCNO 7416 (and:DI (match_operand:DI 0 "nonimmediate_operand" "") 7417 (match_operand:DI 1 "x86_64_szext_general_operand" "")) 7418 (const_int 0)))] 7419 "TARGET_64BIT && !(MEM_P (operands[0]) && MEM_P (operands[1]))") 7420 7421(define_insn "*testdi_1" 7422 [(set (reg FLAGS_REG) 7423 (compare 7424 (and:DI 7425 (match_operand:DI 0 "nonimmediate_operand" "%!*a,r,!*a,r,rm") 7426 (match_operand:DI 1 "x86_64_szext_general_operand" "Z,Z,e,e,re")) 7427 (const_int 0)))] 7428 "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode) 7429 && !(MEM_P (operands[0]) && MEM_P (operands[1]))" 7430 "@ 7431 test{l}\t{%k1, %k0|%k0, %k1} 7432 test{l}\t{%k1, %k0|%k0, %k1} 7433 test{q}\t{%1, %0|%0, %1} 7434 test{q}\t{%1, %0|%0, %1} 7435 test{q}\t{%1, %0|%0, %1}" 7436 [(set_attr "type" "test") 7437 (set_attr "modrm" "0,1,0,1,1") 7438 (set_attr "mode" "SI,SI,DI,DI,DI")]) 7439 7440(define_insn "*testqi_1_maybe_si" 7441 [(set (reg FLAGS_REG) 7442 (compare 7443 (and:QI 7444 (match_operand:QI 0 "nonimmediate_operand" "%!*a,q,qm,r") 7445 (match_operand:QI 1 "general_operand" "n,n,qn,n")) 7446 (const_int 0)))] 7447 "!(MEM_P (operands[0]) && MEM_P (operands[1])) 7448 && ix86_match_ccmode (insn, 7449 CONST_INT_P (operands[1]) 7450 && INTVAL (operands[1]) >= 0 ? CCNOmode : CCZmode)" 7451{ 7452 if (which_alternative == 3) 7453 { 7454 if (CONST_INT_P (operands[1]) && INTVAL (operands[1]) < 0) 7455 operands[1] = GEN_INT (INTVAL (operands[1]) & 0xff); 7456 return "test{l}\t{%1, %k0|%k0, %1}"; 7457 } 7458 return "test{b}\t{%1, %0|%0, %1}"; 7459} 7460 [(set_attr "type" "test") 7461 (set_attr "modrm" "0,1,1,1") 7462 (set_attr "mode" "QI,QI,QI,SI") 7463 (set_attr "pent_pair" "uv,np,uv,np")]) 7464 7465(define_insn "*test<mode>_1" 7466 [(set (reg FLAGS_REG) 7467 (compare 7468 (and:SWI124 7469 (match_operand:SWI124 0 "nonimmediate_operand" "%!*a,<r>,<r>m") 7470 (match_operand:SWI124 1 "<general_operand>" "<i>,<i>,<r><i>")) 7471 (const_int 0)))] 7472 "ix86_match_ccmode (insn, CCNOmode) 7473 && !(MEM_P (operands[0]) && MEM_P (operands[1]))" 7474 "test{<imodesuffix>}\t{%1, %0|%0, %1}" 7475 [(set_attr "type" "test") 7476 (set_attr "modrm" "0,1,1") 7477 (set_attr "mode" "<MODE>") 7478 (set_attr "pent_pair" "uv,np,uv")]) 7479 7480(define_expand "testqi_ext_ccno_0" 7481 [(set (reg:CCNO FLAGS_REG) 7482 (compare:CCNO 7483 (and:SI 7484 (zero_extract:SI 7485 (match_operand 0 "ext_register_operand" "") 7486 (const_int 8) 7487 (const_int 8)) 7488 (match_operand 1 "const_int_operand" "")) 7489 (const_int 0)))]) 7490 7491(define_insn "*testqi_ext_0" 7492 [(set (reg FLAGS_REG) 7493 (compare 7494 (and:SI 7495 (zero_extract:SI 7496 (match_operand 0 "ext_register_operand" "Q") 7497 (const_int 8) 7498 (const_int 8)) 7499 (match_operand 1 "const_int_operand" "n")) 7500 (const_int 0)))] 7501 "ix86_match_ccmode (insn, CCNOmode)" 7502 "test{b}\t{%1, %h0|%h0, %1}" 7503 [(set_attr "type" "test") 7504 (set_attr "mode" "QI") 7505 (set_attr "length_immediate" "1") 7506 (set_attr "modrm" "1") 7507 (set_attr "pent_pair" "np")]) 7508 7509(define_insn "*testqi_ext_1_rex64" 7510 [(set (reg FLAGS_REG) 7511 (compare 7512 (and:SI 7513 (zero_extract:SI 7514 (match_operand 0 "ext_register_operand" "Q") 7515 (const_int 8) 7516 (const_int 8)) 7517 (zero_extend:SI 7518 (match_operand:QI 1 "register_operand" "Q"))) 7519 (const_int 0)))] 7520 "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)" 7521 "test{b}\t{%1, %h0|%h0, %1}" 7522 [(set_attr "type" "test") 7523 (set_attr "mode" "QI")]) 7524 7525(define_insn "*testqi_ext_1" 7526 [(set (reg FLAGS_REG) 7527 (compare 7528 (and:SI 7529 (zero_extract:SI 7530 (match_operand 0 "ext_register_operand" "Q") 7531 (const_int 8) 7532 (const_int 8)) 7533 (zero_extend:SI 7534 (match_operand:QI 1 "general_operand" "Qm"))) 7535 (const_int 0)))] 7536 "!TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)" 7537 "test{b}\t{%1, %h0|%h0, %1}" 7538 [(set_attr "type" "test") 7539 (set_attr "mode" "QI")]) 7540 7541(define_insn "*testqi_ext_2" 7542 [(set (reg FLAGS_REG) 7543 (compare 7544 (and:SI 7545 (zero_extract:SI 7546 (match_operand 0 "ext_register_operand" "Q") 7547 (const_int 8) 7548 (const_int 8)) 7549 (zero_extract:SI 7550 (match_operand 1 "ext_register_operand" "Q") 7551 (const_int 8) 7552 (const_int 8))) 7553 (const_int 0)))] 7554 "ix86_match_ccmode (insn, CCNOmode)" 7555 "test{b}\t{%h1, %h0|%h0, %h1}" 7556 [(set_attr "type" "test") 7557 (set_attr "mode" "QI")]) 7558 7559(define_insn "*testqi_ext_3_rex64" 7560 [(set (reg FLAGS_REG) 7561 (compare (zero_extract:DI 7562 (match_operand 0 "nonimmediate_operand" "rm") 7563 (match_operand:DI 1 "const_int_operand" "") 7564 (match_operand:DI 2 "const_int_operand" "")) 7565 (const_int 0)))] 7566 "TARGET_64BIT 7567 && ix86_match_ccmode (insn, CCNOmode) 7568 && INTVAL (operands[1]) > 0 7569 && INTVAL (operands[2]) >= 0 7570 /* Ensure that resulting mask is zero or sign extended operand. */ 7571 && (INTVAL (operands[1]) + INTVAL (operands[2]) <= 32 7572 || (INTVAL (operands[1]) + INTVAL (operands[2]) == 64 7573 && INTVAL (operands[1]) > 32)) 7574 && (GET_MODE (operands[0]) == SImode 7575 || GET_MODE (operands[0]) == DImode 7576 || GET_MODE (operands[0]) == HImode 7577 || GET_MODE (operands[0]) == QImode)" 7578 "#") 7579 7580;; Combine likes to form bit extractions for some tests. Humor it. 7581(define_insn "*testqi_ext_3" 7582 [(set (reg FLAGS_REG) 7583 (compare (zero_extract:SI 7584 (match_operand 0 "nonimmediate_operand" "rm") 7585 (match_operand:SI 1 "const_int_operand" "") 7586 (match_operand:SI 2 "const_int_operand" "")) 7587 (const_int 0)))] 7588 "ix86_match_ccmode (insn, CCNOmode) 7589 && INTVAL (operands[1]) > 0 7590 && INTVAL (operands[2]) >= 0 7591 && INTVAL (operands[1]) + INTVAL (operands[2]) <= 32 7592 && (GET_MODE (operands[0]) == SImode 7593 || (TARGET_64BIT && GET_MODE (operands[0]) == DImode) 7594 || GET_MODE (operands[0]) == HImode 7595 || GET_MODE (operands[0]) == QImode)" 7596 "#") 7597 7598(define_split 7599 [(set (match_operand 0 "flags_reg_operand" "") 7600 (match_operator 1 "compare_operator" 7601 [(zero_extract 7602 (match_operand 2 "nonimmediate_operand" "") 7603 (match_operand 3 "const_int_operand" "") 7604 (match_operand 4 "const_int_operand" "")) 7605 (const_int 0)]))] 7606 "ix86_match_ccmode (insn, CCNOmode)" 7607 [(set (match_dup 0) (match_op_dup 1 [(match_dup 2) (const_int 0)]))] 7608{ 7609 rtx val = operands[2]; 7610 HOST_WIDE_INT len = INTVAL (operands[3]); 7611 HOST_WIDE_INT pos = INTVAL (operands[4]); 7612 HOST_WIDE_INT mask; 7613 enum machine_mode mode, submode; 7614 7615 mode = GET_MODE (val); 7616 if (MEM_P (val)) 7617 { 7618 /* ??? Combine likes to put non-volatile mem extractions in QImode 7619 no matter the size of the test. So find a mode that works. */ 7620 if (! MEM_VOLATILE_P (val)) 7621 { 7622 mode = smallest_mode_for_size (pos + len, MODE_INT); 7623 val = adjust_address (val, mode, 0); 7624 } 7625 } 7626 else if (GET_CODE (val) == SUBREG 7627 && (submode = GET_MODE (SUBREG_REG (val)), 7628 GET_MODE_BITSIZE (mode) > GET_MODE_BITSIZE (submode)) 7629 && pos + len <= GET_MODE_BITSIZE (submode) 7630 && GET_MODE_CLASS (submode) == MODE_INT) 7631 { 7632 /* Narrow a paradoxical subreg to prevent partial register stalls. */ 7633 mode = submode; 7634 val = SUBREG_REG (val); 7635 } 7636 else if (mode == HImode && pos + len <= 8) 7637 { 7638 /* Small HImode tests can be converted to QImode. */ 7639 mode = QImode; 7640 val = gen_lowpart (QImode, val); 7641 } 7642 7643 if (len == HOST_BITS_PER_WIDE_INT) 7644 mask = -1; 7645 else 7646 mask = ((HOST_WIDE_INT)1 << len) - 1; 7647 mask <<= pos; 7648 7649 operands[2] = gen_rtx_AND (mode, val, gen_int_mode (mask, mode)); 7650}) 7651 7652;; Convert HImode/SImode test instructions with immediate to QImode ones. 7653;; i386 does not allow to encode test with 8bit sign extended immediate, so 7654;; this is relatively important trick. 7655;; Do the conversion only post-reload to avoid limiting of the register class 7656;; to QI regs. 7657(define_split 7658 [(set (match_operand 0 "flags_reg_operand" "") 7659 (match_operator 1 "compare_operator" 7660 [(and (match_operand 2 "register_operand" "") 7661 (match_operand 3 "const_int_operand" "")) 7662 (const_int 0)]))] 7663 "reload_completed 7664 && QI_REG_P (operands[2]) 7665 && GET_MODE (operands[2]) != QImode 7666 && ((ix86_match_ccmode (insn, CCZmode) 7667 && !(INTVAL (operands[3]) & ~(255 << 8))) 7668 || (ix86_match_ccmode (insn, CCNOmode) 7669 && !(INTVAL (operands[3]) & ~(127 << 8))))" 7670 [(set (match_dup 0) 7671 (match_op_dup 1 7672 [(and:SI (zero_extract:SI (match_dup 2) (const_int 8) (const_int 8)) 7673 (match_dup 3)) 7674 (const_int 0)]))] 7675{ 7676 operands[2] = gen_lowpart (SImode, operands[2]); 7677 operands[3] = gen_int_mode (INTVAL (operands[3]) >> 8, SImode); 7678}) 7679 7680(define_split 7681 [(set (match_operand 0 "flags_reg_operand" "") 7682 (match_operator 1 "compare_operator" 7683 [(and (match_operand 2 "nonimmediate_operand" "") 7684 (match_operand 3 "const_int_operand" "")) 7685 (const_int 0)]))] 7686 "reload_completed 7687 && GET_MODE (operands[2]) != QImode 7688 && (!REG_P (operands[2]) || ANY_QI_REG_P (operands[2])) 7689 && ((ix86_match_ccmode (insn, CCZmode) 7690 && !(INTVAL (operands[3]) & ~255)) 7691 || (ix86_match_ccmode (insn, CCNOmode) 7692 && !(INTVAL (operands[3]) & ~127)))" 7693 [(set (match_dup 0) 7694 (match_op_dup 1 [(and:QI (match_dup 2) (match_dup 3)) 7695 (const_int 0)]))] 7696{ 7697 operands[2] = gen_lowpart (QImode, operands[2]); 7698 operands[3] = gen_lowpart (QImode, operands[3]); 7699}) 7700 7701;; %%% This used to optimize known byte-wide and operations to memory, 7702;; and sometimes to QImode registers. If this is considered useful, 7703;; it should be done with splitters. 7704 7705(define_expand "and<mode>3" 7706 [(set (match_operand:SWIM 0 "nonimmediate_operand" "") 7707 (and:SWIM (match_operand:SWIM 1 "nonimmediate_operand" "") 7708 (match_operand:SWIM 2 "<general_szext_operand>" "")))] 7709 "" 7710{ 7711 if (<MODE>mode == DImode 7712 && GET_CODE (operands[2]) == CONST_INT 7713 && INTVAL (operands[2]) == (HOST_WIDE_INT) 0xffffffff 7714 && REG_P (operands[1])) 7715 emit_insn (gen_zero_extendsidi2 (operands[0], 7716 gen_lowpart (SImode, operands[1]))); 7717 else 7718 ix86_expand_binary_operator (AND, <MODE>mode, operands); 7719 DONE; 7720}) 7721 7722(define_insn "*anddi_1" 7723 [(set (match_operand:DI 0 "nonimmediate_operand" "=r,rm,r,r") 7724 (and:DI 7725 (match_operand:DI 1 "nonimmediate_operand" "%0,0,0,qm") 7726 (match_operand:DI 2 "x86_64_szext_general_operand" "Z,re,rm,L"))) 7727 (clobber (reg:CC FLAGS_REG))] 7728 "TARGET_64BIT && ix86_binary_operator_ok (AND, DImode, operands)" 7729{ 7730 switch (get_attr_type (insn)) 7731 { 7732 case TYPE_IMOVX: 7733 { 7734 enum machine_mode mode; 7735 7736 gcc_assert (CONST_INT_P (operands[2])); 7737 if (INTVAL (operands[2]) == (HOST_WIDE_INT) 0xffffffff) 7738 mode = SImode; 7739 else if (INTVAL (operands[2]) == 0xffff) 7740 mode = HImode; 7741 else 7742 { 7743 gcc_assert (INTVAL (operands[2]) == 0xff); 7744 mode = QImode; 7745 } 7746 7747 operands[1] = gen_lowpart (mode, operands[1]); 7748 if (mode == SImode) 7749 return "mov{l}\t{%1, %k0|%k0, %1}"; 7750 else if (mode == HImode) 7751 return "movz{wl|x}\t{%1, %k0|%k0, %1}"; 7752 else 7753 return "movz{bl|x}\t{%1, %k0|%k0, %1}"; 7754 } 7755 7756 default: 7757 gcc_assert (rtx_equal_p (operands[0], operands[1])); 7758 if (get_attr_mode (insn) == MODE_SI) 7759 return "and{l}\t{%k2, %k0|%k0, %k2}"; 7760 else 7761 return "and{q}\t{%2, %0|%0, %2}"; 7762 } 7763} 7764 [(set_attr "type" "alu,alu,alu,imovx") 7765 (set_attr "length_immediate" "*,*,*,0") 7766 (set (attr "prefix_rex") 7767 (if_then_else 7768 (and (eq_attr "type" "imovx") 7769 (and (match_test "INTVAL (operands[2]) == 0xff") 7770 (match_operand 1 "ext_QIreg_operand" ""))) 7771 (const_string "1") 7772 (const_string "*"))) 7773 (set_attr "mode" "SI,DI,DI,SI")]) 7774 7775(define_insn "*andsi_1" 7776 [(set (match_operand:SI 0 "nonimmediate_operand" "=rm,r,r") 7777 (and:SI (match_operand:SI 1 "nonimmediate_operand" "%0,0,qm") 7778 (match_operand:SI 2 "x86_64_general_operand" "re,rm,L"))) 7779 (clobber (reg:CC FLAGS_REG))] 7780 "ix86_binary_operator_ok (AND, SImode, operands)" 7781{ 7782 switch (get_attr_type (insn)) 7783 { 7784 case TYPE_IMOVX: 7785 { 7786 enum machine_mode mode; 7787 7788 gcc_assert (CONST_INT_P (operands[2])); 7789 if (INTVAL (operands[2]) == 0xffff) 7790 mode = HImode; 7791 else 7792 { 7793 gcc_assert (INTVAL (operands[2]) == 0xff); 7794 mode = QImode; 7795 } 7796 7797 operands[1] = gen_lowpart (mode, operands[1]); 7798 if (mode == HImode) 7799 return "movz{wl|x}\t{%1, %0|%0, %1}"; 7800 else 7801 return "movz{bl|x}\t{%1, %0|%0, %1}"; 7802 } 7803 7804 default: 7805 gcc_assert (rtx_equal_p (operands[0], operands[1])); 7806 return "and{l}\t{%2, %0|%0, %2}"; 7807 } 7808} 7809 [(set_attr "type" "alu,alu,imovx") 7810 (set (attr "prefix_rex") 7811 (if_then_else 7812 (and (eq_attr "type" "imovx") 7813 (and (match_test "INTVAL (operands[2]) == 0xff") 7814 (match_operand 1 "ext_QIreg_operand" ""))) 7815 (const_string "1") 7816 (const_string "*"))) 7817 (set_attr "length_immediate" "*,*,0") 7818 (set_attr "mode" "SI")]) 7819 7820;; See comment for addsi_1_zext why we do use nonimmediate_operand 7821(define_insn "*andsi_1_zext" 7822 [(set (match_operand:DI 0 "register_operand" "=r") 7823 (zero_extend:DI 7824 (and:SI (match_operand:SI 1 "nonimmediate_operand" "%0") 7825 (match_operand:SI 2 "x86_64_general_operand" "rme")))) 7826 (clobber (reg:CC FLAGS_REG))] 7827 "TARGET_64BIT && ix86_binary_operator_ok (AND, SImode, operands)" 7828 "and{l}\t{%2, %k0|%k0, %2}" 7829 [(set_attr "type" "alu") 7830 (set_attr "mode" "SI")]) 7831 7832(define_insn "*andhi_1" 7833 [(set (match_operand:HI 0 "nonimmediate_operand" "=rm,r,r") 7834 (and:HI (match_operand:HI 1 "nonimmediate_operand" "%0,0,qm") 7835 (match_operand:HI 2 "general_operand" "rn,rm,L"))) 7836 (clobber (reg:CC FLAGS_REG))] 7837 "ix86_binary_operator_ok (AND, HImode, operands)" 7838{ 7839 switch (get_attr_type (insn)) 7840 { 7841 case TYPE_IMOVX: 7842 gcc_assert (CONST_INT_P (operands[2])); 7843 gcc_assert (INTVAL (operands[2]) == 0xff); 7844 return "movz{bl|x}\t{%b1, %k0|%k0, %b1}"; 7845 7846 default: 7847 gcc_assert (rtx_equal_p (operands[0], operands[1])); 7848 7849 return "and{w}\t{%2, %0|%0, %2}"; 7850 } 7851} 7852 [(set_attr "type" "alu,alu,imovx") 7853 (set_attr "length_immediate" "*,*,0") 7854 (set (attr "prefix_rex") 7855 (if_then_else 7856 (and (eq_attr "type" "imovx") 7857 (match_operand 1 "ext_QIreg_operand" "")) 7858 (const_string "1") 7859 (const_string "*"))) 7860 (set_attr "mode" "HI,HI,SI")]) 7861 7862;; %%% Potential partial reg stall on alternative 2. What to do? 7863(define_insn "*andqi_1" 7864 [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,q,r") 7865 (and:QI (match_operand:QI 1 "nonimmediate_operand" "%0,0,0") 7866 (match_operand:QI 2 "general_operand" "qn,qmn,rn"))) 7867 (clobber (reg:CC FLAGS_REG))] 7868 "ix86_binary_operator_ok (AND, QImode, operands)" 7869 "@ 7870 and{b}\t{%2, %0|%0, %2} 7871 and{b}\t{%2, %0|%0, %2} 7872 and{l}\t{%k2, %k0|%k0, %k2}" 7873 [(set_attr "type" "alu") 7874 (set_attr "mode" "QI,QI,SI")]) 7875 7876(define_insn "*andqi_1_slp" 7877 [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm,q")) 7878 (and:QI (match_dup 0) 7879 (match_operand:QI 1 "general_operand" "qn,qmn"))) 7880 (clobber (reg:CC FLAGS_REG))] 7881 "(!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun)) 7882 && !(MEM_P (operands[0]) && MEM_P (operands[1]))" 7883 "and{b}\t{%1, %0|%0, %1}" 7884 [(set_attr "type" "alu1") 7885 (set_attr "mode" "QI")]) 7886 7887(define_split 7888 [(set (match_operand 0 "register_operand" "") 7889 (and (match_dup 0) 7890 (const_int -65536))) 7891 (clobber (reg:CC FLAGS_REG))] 7892 "(TARGET_FAST_PREFIX && !TARGET_PARTIAL_REG_STALL) 7893 || optimize_function_for_size_p (cfun)" 7894 [(set (strict_low_part (match_dup 1)) (const_int 0))] 7895 "operands[1] = gen_lowpart (HImode, operands[0]);") 7896 7897(define_split 7898 [(set (match_operand 0 "ext_register_operand" "") 7899 (and (match_dup 0) 7900 (const_int -256))) 7901 (clobber (reg:CC FLAGS_REG))] 7902 "(!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun)) 7903 && reload_completed" 7904 [(set (strict_low_part (match_dup 1)) (const_int 0))] 7905 "operands[1] = gen_lowpart (QImode, operands[0]);") 7906 7907(define_split 7908 [(set (match_operand 0 "ext_register_operand" "") 7909 (and (match_dup 0) 7910 (const_int -65281))) 7911 (clobber (reg:CC FLAGS_REG))] 7912 "(!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun)) 7913 && reload_completed" 7914 [(parallel [(set (zero_extract:SI (match_dup 0) 7915 (const_int 8) 7916 (const_int 8)) 7917 (xor:SI 7918 (zero_extract:SI (match_dup 0) 7919 (const_int 8) 7920 (const_int 8)) 7921 (zero_extract:SI (match_dup 0) 7922 (const_int 8) 7923 (const_int 8)))) 7924 (clobber (reg:CC FLAGS_REG))])] 7925 "operands[0] = gen_lowpart (SImode, operands[0]);") 7926 7927(define_insn "*anddi_2" 7928 [(set (reg FLAGS_REG) 7929 (compare 7930 (and:DI 7931 (match_operand:DI 1 "nonimmediate_operand" "%0,0,0") 7932 (match_operand:DI 2 "x86_64_szext_general_operand" "Z,rem,re")) 7933 (const_int 0))) 7934 (set (match_operand:DI 0 "nonimmediate_operand" "=r,r,rm") 7935 (and:DI (match_dup 1) (match_dup 2)))] 7936 "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode) 7937 && ix86_binary_operator_ok (AND, DImode, operands)" 7938 "@ 7939 and{l}\t{%k2, %k0|%k0, %k2} 7940 and{q}\t{%2, %0|%0, %2} 7941 and{q}\t{%2, %0|%0, %2}" 7942 [(set_attr "type" "alu") 7943 (set_attr "mode" "SI,DI,DI")]) 7944 7945(define_insn "*andqi_2_maybe_si" 7946 [(set (reg FLAGS_REG) 7947 (compare (and:QI 7948 (match_operand:QI 1 "nonimmediate_operand" "%0,0,0") 7949 (match_operand:QI 2 "general_operand" "qmn,qn,n")) 7950 (const_int 0))) 7951 (set (match_operand:QI 0 "nonimmediate_operand" "=q,qm,*r") 7952 (and:QI (match_dup 1) (match_dup 2)))] 7953 "ix86_binary_operator_ok (AND, QImode, operands) 7954 && ix86_match_ccmode (insn, 7955 CONST_INT_P (operands[2]) 7956 && INTVAL (operands[2]) >= 0 ? CCNOmode : CCZmode)" 7957{ 7958 if (which_alternative == 2) 7959 { 7960 if (CONST_INT_P (operands[2]) && INTVAL (operands[2]) < 0) 7961 operands[2] = GEN_INT (INTVAL (operands[2]) & 0xff); 7962 return "and{l}\t{%2, %k0|%k0, %2}"; 7963 } 7964 return "and{b}\t{%2, %0|%0, %2}"; 7965} 7966 [(set_attr "type" "alu") 7967 (set_attr "mode" "QI,QI,SI")]) 7968 7969(define_insn "*and<mode>_2" 7970 [(set (reg FLAGS_REG) 7971 (compare (and:SWI124 7972 (match_operand:SWI124 1 "nonimmediate_operand" "%0,0") 7973 (match_operand:SWI124 2 "<general_operand>" "<g>,<r><i>")) 7974 (const_int 0))) 7975 (set (match_operand:SWI124 0 "nonimmediate_operand" "=<r>,<r>m") 7976 (and:SWI124 (match_dup 1) (match_dup 2)))] 7977 "ix86_match_ccmode (insn, CCNOmode) 7978 && ix86_binary_operator_ok (AND, <MODE>mode, operands)" 7979 "and{<imodesuffix>}\t{%2, %0|%0, %2}" 7980 [(set_attr "type" "alu") 7981 (set_attr "mode" "<MODE>")]) 7982 7983;; See comment for addsi_1_zext why we do use nonimmediate_operand 7984(define_insn "*andsi_2_zext" 7985 [(set (reg FLAGS_REG) 7986 (compare (and:SI 7987 (match_operand:SI 1 "nonimmediate_operand" "%0") 7988 (match_operand:SI 2 "x86_64_general_operand" "rme")) 7989 (const_int 0))) 7990 (set (match_operand:DI 0 "register_operand" "=r") 7991 (zero_extend:DI (and:SI (match_dup 1) (match_dup 2))))] 7992 "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode) 7993 && ix86_binary_operator_ok (AND, SImode, operands)" 7994 "and{l}\t{%2, %k0|%k0, %2}" 7995 [(set_attr "type" "alu") 7996 (set_attr "mode" "SI")]) 7997 7998(define_insn "*andqi_2_slp" 7999 [(set (reg FLAGS_REG) 8000 (compare (and:QI 8001 (match_operand:QI 0 "nonimmediate_operand" "+q,qm") 8002 (match_operand:QI 1 "nonimmediate_operand" "qmn,qn")) 8003 (const_int 0))) 8004 (set (strict_low_part (match_dup 0)) 8005 (and:QI (match_dup 0) (match_dup 1)))] 8006 "(!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun)) 8007 && ix86_match_ccmode (insn, CCNOmode) 8008 && !(MEM_P (operands[0]) && MEM_P (operands[1]))" 8009 "and{b}\t{%1, %0|%0, %1}" 8010 [(set_attr "type" "alu1") 8011 (set_attr "mode" "QI")]) 8012 8013;; ??? A bug in recog prevents it from recognizing a const_int as an 8014;; operand to zero_extend in andqi_ext_1. It was checking explicitly 8015;; for a QImode operand, which of course failed. 8016(define_insn "andqi_ext_0" 8017 [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q") 8018 (const_int 8) 8019 (const_int 8)) 8020 (and:SI 8021 (zero_extract:SI 8022 (match_operand 1 "ext_register_operand" "0") 8023 (const_int 8) 8024 (const_int 8)) 8025 (match_operand 2 "const_int_operand" "n"))) 8026 (clobber (reg:CC FLAGS_REG))] 8027 "" 8028 "and{b}\t{%2, %h0|%h0, %2}" 8029 [(set_attr "type" "alu") 8030 (set_attr "length_immediate" "1") 8031 (set_attr "modrm" "1") 8032 (set_attr "mode" "QI")]) 8033 8034;; Generated by peephole translating test to and. This shows up 8035;; often in fp comparisons. 8036(define_insn "*andqi_ext_0_cc" 8037 [(set (reg FLAGS_REG) 8038 (compare 8039 (and:SI 8040 (zero_extract:SI 8041 (match_operand 1 "ext_register_operand" "0") 8042 (const_int 8) 8043 (const_int 8)) 8044 (match_operand 2 "const_int_operand" "n")) 8045 (const_int 0))) 8046 (set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q") 8047 (const_int 8) 8048 (const_int 8)) 8049 (and:SI 8050 (zero_extract:SI 8051 (match_dup 1) 8052 (const_int 8) 8053 (const_int 8)) 8054 (match_dup 2)))] 8055 "ix86_match_ccmode (insn, CCNOmode)" 8056 "and{b}\t{%2, %h0|%h0, %2}" 8057 [(set_attr "type" "alu") 8058 (set_attr "length_immediate" "1") 8059 (set_attr "modrm" "1") 8060 (set_attr "mode" "QI")]) 8061 8062(define_insn "*andqi_ext_1_rex64" 8063 [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q") 8064 (const_int 8) 8065 (const_int 8)) 8066 (and:SI 8067 (zero_extract:SI 8068 (match_operand 1 "ext_register_operand" "0") 8069 (const_int 8) 8070 (const_int 8)) 8071 (zero_extend:SI 8072 (match_operand 2 "ext_register_operand" "Q")))) 8073 (clobber (reg:CC FLAGS_REG))] 8074 "TARGET_64BIT" 8075 "and{b}\t{%2, %h0|%h0, %2}" 8076 [(set_attr "type" "alu") 8077 (set_attr "length_immediate" "0") 8078 (set_attr "mode" "QI")]) 8079 8080(define_insn "*andqi_ext_1" 8081 [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q") 8082 (const_int 8) 8083 (const_int 8)) 8084 (and:SI 8085 (zero_extract:SI 8086 (match_operand 1 "ext_register_operand" "0") 8087 (const_int 8) 8088 (const_int 8)) 8089 (zero_extend:SI 8090 (match_operand:QI 2 "general_operand" "Qm")))) 8091 (clobber (reg:CC FLAGS_REG))] 8092 "!TARGET_64BIT" 8093 "and{b}\t{%2, %h0|%h0, %2}" 8094 [(set_attr "type" "alu") 8095 (set_attr "length_immediate" "0") 8096 (set_attr "mode" "QI")]) 8097 8098(define_insn "*andqi_ext_2" 8099 [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q") 8100 (const_int 8) 8101 (const_int 8)) 8102 (and:SI 8103 (zero_extract:SI 8104 (match_operand 1 "ext_register_operand" "%0") 8105 (const_int 8) 8106 (const_int 8)) 8107 (zero_extract:SI 8108 (match_operand 2 "ext_register_operand" "Q") 8109 (const_int 8) 8110 (const_int 8)))) 8111 (clobber (reg:CC FLAGS_REG))] 8112 "" 8113 "and{b}\t{%h2, %h0|%h0, %h2}" 8114 [(set_attr "type" "alu") 8115 (set_attr "length_immediate" "0") 8116 (set_attr "mode" "QI")]) 8117 8118;; Convert wide AND instructions with immediate operand to shorter QImode 8119;; equivalents when possible. 8120;; Don't do the splitting with memory operands, since it introduces risk 8121;; of memory mismatch stalls. We may want to do the splitting for optimizing 8122;; for size, but that can (should?) be handled by generic code instead. 8123(define_split 8124 [(set (match_operand 0 "register_operand" "") 8125 (and (match_operand 1 "register_operand" "") 8126 (match_operand 2 "const_int_operand" ""))) 8127 (clobber (reg:CC FLAGS_REG))] 8128 "reload_completed 8129 && QI_REG_P (operands[0]) 8130 && (!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun)) 8131 && !(~INTVAL (operands[2]) & ~(255 << 8)) 8132 && GET_MODE (operands[0]) != QImode" 8133 [(parallel [(set (zero_extract:SI (match_dup 0) (const_int 8) (const_int 8)) 8134 (and:SI (zero_extract:SI (match_dup 1) 8135 (const_int 8) (const_int 8)) 8136 (match_dup 2))) 8137 (clobber (reg:CC FLAGS_REG))])] 8138{ 8139 operands[0] = gen_lowpart (SImode, operands[0]); 8140 operands[1] = gen_lowpart (SImode, operands[1]); 8141 operands[2] = gen_int_mode ((INTVAL (operands[2]) >> 8) & 0xff, SImode); 8142}) 8143 8144;; Since AND can be encoded with sign extended immediate, this is only 8145;; profitable when 7th bit is not set. 8146(define_split 8147 [(set (match_operand 0 "register_operand" "") 8148 (and (match_operand 1 "general_operand" "") 8149 (match_operand 2 "const_int_operand" ""))) 8150 (clobber (reg:CC FLAGS_REG))] 8151 "reload_completed 8152 && ANY_QI_REG_P (operands[0]) 8153 && (!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun)) 8154 && !(~INTVAL (operands[2]) & ~255) 8155 && !(INTVAL (operands[2]) & 128) 8156 && GET_MODE (operands[0]) != QImode" 8157 [(parallel [(set (strict_low_part (match_dup 0)) 8158 (and:QI (match_dup 1) 8159 (match_dup 2))) 8160 (clobber (reg:CC FLAGS_REG))])] 8161{ 8162 operands[0] = gen_lowpart (QImode, operands[0]); 8163 operands[1] = gen_lowpart (QImode, operands[1]); 8164 operands[2] = gen_lowpart (QImode, operands[2]); 8165}) 8166 8167;; Logical inclusive and exclusive OR instructions 8168 8169;; %%% This used to optimize known byte-wide and operations to memory. 8170;; If this is considered useful, it should be done with splitters. 8171 8172(define_expand "<code><mode>3" 8173 [(set (match_operand:SWIM 0 "nonimmediate_operand" "") 8174 (any_or:SWIM (match_operand:SWIM 1 "nonimmediate_operand" "") 8175 (match_operand:SWIM 2 "<general_operand>" "")))] 8176 "" 8177 "ix86_expand_binary_operator (<CODE>, <MODE>mode, operands); DONE;") 8178 8179(define_insn "*<code><mode>_1" 8180 [(set (match_operand:SWI248 0 "nonimmediate_operand" "=r,rm") 8181 (any_or:SWI248 8182 (match_operand:SWI248 1 "nonimmediate_operand" "%0,0") 8183 (match_operand:SWI248 2 "<general_operand>" "<g>,r<i>"))) 8184 (clobber (reg:CC FLAGS_REG))] 8185 "ix86_binary_operator_ok (<CODE>, <MODE>mode, operands)" 8186 "<logic>{<imodesuffix>}\t{%2, %0|%0, %2}" 8187 [(set_attr "type" "alu") 8188 (set_attr "mode" "<MODE>")]) 8189 8190;; %%% Potential partial reg stall on alternative 2. What to do? 8191(define_insn "*<code>qi_1" 8192 [(set (match_operand:QI 0 "nonimmediate_operand" "=q,m,r") 8193 (any_or:QI (match_operand:QI 1 "nonimmediate_operand" "%0,0,0") 8194 (match_operand:QI 2 "general_operand" "qmn,qn,rn"))) 8195 (clobber (reg:CC FLAGS_REG))] 8196 "ix86_binary_operator_ok (<CODE>, QImode, operands)" 8197 "@ 8198 <logic>{b}\t{%2, %0|%0, %2} 8199 <logic>{b}\t{%2, %0|%0, %2} 8200 <logic>{l}\t{%k2, %k0|%k0, %k2}" 8201 [(set_attr "type" "alu") 8202 (set_attr "mode" "QI,QI,SI")]) 8203 8204;; See comment for addsi_1_zext why we do use nonimmediate_operand 8205(define_insn "*<code>si_1_zext" 8206 [(set (match_operand:DI 0 "register_operand" "=r") 8207 (zero_extend:DI 8208 (any_or:SI (match_operand:SI 1 "nonimmediate_operand" "%0") 8209 (match_operand:SI 2 "x86_64_general_operand" "rme")))) 8210 (clobber (reg:CC FLAGS_REG))] 8211 "TARGET_64BIT && ix86_binary_operator_ok (<CODE>, SImode, operands)" 8212 "<logic>{l}\t{%2, %k0|%k0, %2}" 8213 [(set_attr "type" "alu") 8214 (set_attr "mode" "SI")]) 8215 8216(define_insn "*<code>si_1_zext_imm" 8217 [(set (match_operand:DI 0 "register_operand" "=r") 8218 (any_or:DI 8219 (zero_extend:DI (match_operand:SI 1 "register_operand" "%0")) 8220 (match_operand:DI 2 "x86_64_zext_immediate_operand" "Z"))) 8221 (clobber (reg:CC FLAGS_REG))] 8222 "TARGET_64BIT && ix86_binary_operator_ok (<CODE>, SImode, operands)" 8223 "<logic>{l}\t{%2, %k0|%k0, %2}" 8224 [(set_attr "type" "alu") 8225 (set_attr "mode" "SI")]) 8226 8227(define_insn "*<code>qi_1_slp" 8228 [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+q,m")) 8229 (any_or:QI (match_dup 0) 8230 (match_operand:QI 1 "general_operand" "qmn,qn"))) 8231 (clobber (reg:CC FLAGS_REG))] 8232 "(!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun)) 8233 && !(MEM_P (operands[0]) && MEM_P (operands[1]))" 8234 "<logic>{b}\t{%1, %0|%0, %1}" 8235 [(set_attr "type" "alu1") 8236 (set_attr "mode" "QI")]) 8237 8238(define_insn "*<code><mode>_2" 8239 [(set (reg FLAGS_REG) 8240 (compare (any_or:SWI 8241 (match_operand:SWI 1 "nonimmediate_operand" "%0,0") 8242 (match_operand:SWI 2 "<general_operand>" "<g>,<r><i>")) 8243 (const_int 0))) 8244 (set (match_operand:SWI 0 "nonimmediate_operand" "=<r>,<r>m") 8245 (any_or:SWI (match_dup 1) (match_dup 2)))] 8246 "ix86_match_ccmode (insn, CCNOmode) 8247 && ix86_binary_operator_ok (<CODE>, <MODE>mode, operands)" 8248 "<logic>{<imodesuffix>}\t{%2, %0|%0, %2}" 8249 [(set_attr "type" "alu") 8250 (set_attr "mode" "<MODE>")]) 8251 8252;; See comment for addsi_1_zext why we do use nonimmediate_operand 8253;; ??? Special case for immediate operand is missing - it is tricky. 8254(define_insn "*<code>si_2_zext" 8255 [(set (reg FLAGS_REG) 8256 (compare (any_or:SI (match_operand:SI 1 "nonimmediate_operand" "%0") 8257 (match_operand:SI 2 "x86_64_general_operand" "rme")) 8258 (const_int 0))) 8259 (set (match_operand:DI 0 "register_operand" "=r") 8260 (zero_extend:DI (any_or:SI (match_dup 1) (match_dup 2))))] 8261 "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode) 8262 && ix86_binary_operator_ok (<CODE>, SImode, operands)" 8263 "<logic>{l}\t{%2, %k0|%k0, %2}" 8264 [(set_attr "type" "alu") 8265 (set_attr "mode" "SI")]) 8266 8267(define_insn "*<code>si_2_zext_imm" 8268 [(set (reg FLAGS_REG) 8269 (compare (any_or:SI 8270 (match_operand:SI 1 "nonimmediate_operand" "%0") 8271 (match_operand:SI 2 "x86_64_zext_immediate_operand" "Z")) 8272 (const_int 0))) 8273 (set (match_operand:DI 0 "register_operand" "=r") 8274 (any_or:DI (zero_extend:DI (match_dup 1)) (match_dup 2)))] 8275 "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode) 8276 && ix86_binary_operator_ok (<CODE>, SImode, operands)" 8277 "<logic>{l}\t{%2, %k0|%k0, %2}" 8278 [(set_attr "type" "alu") 8279 (set_attr "mode" "SI")]) 8280 8281(define_insn "*<code>qi_2_slp" 8282 [(set (reg FLAGS_REG) 8283 (compare (any_or:QI (match_operand:QI 0 "nonimmediate_operand" "+q,qm") 8284 (match_operand:QI 1 "general_operand" "qmn,qn")) 8285 (const_int 0))) 8286 (set (strict_low_part (match_dup 0)) 8287 (any_or:QI (match_dup 0) (match_dup 1)))] 8288 "(!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun)) 8289 && ix86_match_ccmode (insn, CCNOmode) 8290 && !(MEM_P (operands[0]) && MEM_P (operands[1]))" 8291 "<logic>{b}\t{%1, %0|%0, %1}" 8292 [(set_attr "type" "alu1") 8293 (set_attr "mode" "QI")]) 8294 8295(define_insn "*<code><mode>_3" 8296 [(set (reg FLAGS_REG) 8297 (compare (any_or:SWI 8298 (match_operand:SWI 1 "nonimmediate_operand" "%0") 8299 (match_operand:SWI 2 "<general_operand>" "<g>")) 8300 (const_int 0))) 8301 (clobber (match_scratch:SWI 0 "=<r>"))] 8302 "ix86_match_ccmode (insn, CCNOmode) 8303 && !(MEM_P (operands[1]) && MEM_P (operands[2]))" 8304 "<logic>{<imodesuffix>}\t{%2, %0|%0, %2}" 8305 [(set_attr "type" "alu") 8306 (set_attr "mode" "<MODE>")]) 8307 8308(define_insn "*<code>qi_ext_0" 8309 [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q") 8310 (const_int 8) 8311 (const_int 8)) 8312 (any_or:SI 8313 (zero_extract:SI 8314 (match_operand 1 "ext_register_operand" "0") 8315 (const_int 8) 8316 (const_int 8)) 8317 (match_operand 2 "const_int_operand" "n"))) 8318 (clobber (reg:CC FLAGS_REG))] 8319 "!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun)" 8320 "<logic>{b}\t{%2, %h0|%h0, %2}" 8321 [(set_attr "type" "alu") 8322 (set_attr "length_immediate" "1") 8323 (set_attr "modrm" "1") 8324 (set_attr "mode" "QI")]) 8325 8326(define_insn "*<code>qi_ext_1_rex64" 8327 [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q") 8328 (const_int 8) 8329 (const_int 8)) 8330 (any_or:SI 8331 (zero_extract:SI 8332 (match_operand 1 "ext_register_operand" "0") 8333 (const_int 8) 8334 (const_int 8)) 8335 (zero_extend:SI 8336 (match_operand 2 "ext_register_operand" "Q")))) 8337 (clobber (reg:CC FLAGS_REG))] 8338 "TARGET_64BIT 8339 && (!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))" 8340 "<logic>{b}\t{%2, %h0|%h0, %2}" 8341 [(set_attr "type" "alu") 8342 (set_attr "length_immediate" "0") 8343 (set_attr "mode" "QI")]) 8344 8345(define_insn "*<code>qi_ext_1" 8346 [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q") 8347 (const_int 8) 8348 (const_int 8)) 8349 (any_or:SI 8350 (zero_extract:SI 8351 (match_operand 1 "ext_register_operand" "0") 8352 (const_int 8) 8353 (const_int 8)) 8354 (zero_extend:SI 8355 (match_operand:QI 2 "general_operand" "Qm")))) 8356 (clobber (reg:CC FLAGS_REG))] 8357 "!TARGET_64BIT 8358 && (!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))" 8359 "<logic>{b}\t{%2, %h0|%h0, %2}" 8360 [(set_attr "type" "alu") 8361 (set_attr "length_immediate" "0") 8362 (set_attr "mode" "QI")]) 8363 8364(define_insn "*<code>qi_ext_2" 8365 [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q") 8366 (const_int 8) 8367 (const_int 8)) 8368 (any_or:SI 8369 (zero_extract:SI (match_operand 1 "ext_register_operand" "0") 8370 (const_int 8) 8371 (const_int 8)) 8372 (zero_extract:SI (match_operand 2 "ext_register_operand" "Q") 8373 (const_int 8) 8374 (const_int 8)))) 8375 (clobber (reg:CC FLAGS_REG))] 8376 "!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun)" 8377 "<logic>{b}\t{%h2, %h0|%h0, %h2}" 8378 [(set_attr "type" "alu") 8379 (set_attr "length_immediate" "0") 8380 (set_attr "mode" "QI")]) 8381 8382(define_split 8383 [(set (match_operand 0 "register_operand" "") 8384 (any_or (match_operand 1 "register_operand" "") 8385 (match_operand 2 "const_int_operand" ""))) 8386 (clobber (reg:CC FLAGS_REG))] 8387 "reload_completed 8388 && QI_REG_P (operands[0]) 8389 && (!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun)) 8390 && !(INTVAL (operands[2]) & ~(255 << 8)) 8391 && GET_MODE (operands[0]) != QImode" 8392 [(parallel [(set (zero_extract:SI (match_dup 0) (const_int 8) (const_int 8)) 8393 (any_or:SI (zero_extract:SI (match_dup 1) 8394 (const_int 8) (const_int 8)) 8395 (match_dup 2))) 8396 (clobber (reg:CC FLAGS_REG))])] 8397{ 8398 operands[0] = gen_lowpart (SImode, operands[0]); 8399 operands[1] = gen_lowpart (SImode, operands[1]); 8400 operands[2] = gen_int_mode ((INTVAL (operands[2]) >> 8) & 0xff, SImode); 8401}) 8402 8403;; Since OR can be encoded with sign extended immediate, this is only 8404;; profitable when 7th bit is set. 8405(define_split 8406 [(set (match_operand 0 "register_operand" "") 8407 (any_or (match_operand 1 "general_operand" "") 8408 (match_operand 2 "const_int_operand" ""))) 8409 (clobber (reg:CC FLAGS_REG))] 8410 "reload_completed 8411 && ANY_QI_REG_P (operands[0]) 8412 && (!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun)) 8413 && !(INTVAL (operands[2]) & ~255) 8414 && (INTVAL (operands[2]) & 128) 8415 && GET_MODE (operands[0]) != QImode" 8416 [(parallel [(set (strict_low_part (match_dup 0)) 8417 (any_or:QI (match_dup 1) 8418 (match_dup 2))) 8419 (clobber (reg:CC FLAGS_REG))])] 8420{ 8421 operands[0] = gen_lowpart (QImode, operands[0]); 8422 operands[1] = gen_lowpart (QImode, operands[1]); 8423 operands[2] = gen_lowpart (QImode, operands[2]); 8424}) 8425 8426(define_expand "xorqi_cc_ext_1" 8427 [(parallel [ 8428 (set (reg:CCNO FLAGS_REG) 8429 (compare:CCNO 8430 (xor:SI 8431 (zero_extract:SI 8432 (match_operand 1 "ext_register_operand" "") 8433 (const_int 8) 8434 (const_int 8)) 8435 (match_operand:QI 2 "general_operand" "")) 8436 (const_int 0))) 8437 (set (zero_extract:SI (match_operand 0 "ext_register_operand" "") 8438 (const_int 8) 8439 (const_int 8)) 8440 (xor:SI 8441 (zero_extract:SI 8442 (match_dup 1) 8443 (const_int 8) 8444 (const_int 8)) 8445 (match_dup 2)))])]) 8446 8447(define_insn "*xorqi_cc_ext_1_rex64" 8448 [(set (reg FLAGS_REG) 8449 (compare 8450 (xor:SI 8451 (zero_extract:SI 8452 (match_operand 1 "ext_register_operand" "0") 8453 (const_int 8) 8454 (const_int 8)) 8455 (match_operand:QI 2 "nonmemory_operand" "Qn")) 8456 (const_int 0))) 8457 (set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q") 8458 (const_int 8) 8459 (const_int 8)) 8460 (xor:SI 8461 (zero_extract:SI 8462 (match_dup 1) 8463 (const_int 8) 8464 (const_int 8)) 8465 (match_dup 2)))] 8466 "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)" 8467 "xor{b}\t{%2, %h0|%h0, %2}" 8468 [(set_attr "type" "alu") 8469 (set_attr "modrm" "1") 8470 (set_attr "mode" "QI")]) 8471 8472(define_insn "*xorqi_cc_ext_1" 8473 [(set (reg FLAGS_REG) 8474 (compare 8475 (xor:SI 8476 (zero_extract:SI 8477 (match_operand 1 "ext_register_operand" "0") 8478 (const_int 8) 8479 (const_int 8)) 8480 (match_operand:QI 2 "general_operand" "qmn")) 8481 (const_int 0))) 8482 (set (zero_extract:SI (match_operand 0 "ext_register_operand" "=q") 8483 (const_int 8) 8484 (const_int 8)) 8485 (xor:SI 8486 (zero_extract:SI 8487 (match_dup 1) 8488 (const_int 8) 8489 (const_int 8)) 8490 (match_dup 2)))] 8491 "!TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)" 8492 "xor{b}\t{%2, %h0|%h0, %2}" 8493 [(set_attr "type" "alu") 8494 (set_attr "modrm" "1") 8495 (set_attr "mode" "QI")]) 8496 8497;; Negation instructions 8498 8499(define_expand "neg<mode>2" 8500 [(set (match_operand:SDWIM 0 "nonimmediate_operand" "") 8501 (neg:SDWIM (match_operand:SDWIM 1 "nonimmediate_operand" "")))] 8502 "" 8503 "ix86_expand_unary_operator (NEG, <MODE>mode, operands); DONE;") 8504 8505(define_insn_and_split "*neg<dwi>2_doubleword" 8506 [(set (match_operand:<DWI> 0 "nonimmediate_operand" "=ro") 8507 (neg:<DWI> (match_operand:<DWI> 1 "nonimmediate_operand" "0"))) 8508 (clobber (reg:CC FLAGS_REG))] 8509 "ix86_unary_operator_ok (NEG, <DWI>mode, operands)" 8510 "#" 8511 "reload_completed" 8512 [(parallel 8513 [(set (reg:CCZ FLAGS_REG) 8514 (compare:CCZ (neg:DWIH (match_dup 1)) (const_int 0))) 8515 (set (match_dup 0) (neg:DWIH (match_dup 1)))]) 8516 (parallel 8517 [(set (match_dup 2) 8518 (plus:DWIH (match_dup 3) 8519 (plus:DWIH (ltu:DWIH (reg:CC FLAGS_REG) (const_int 0)) 8520 (const_int 0)))) 8521 (clobber (reg:CC FLAGS_REG))]) 8522 (parallel 8523 [(set (match_dup 2) 8524 (neg:DWIH (match_dup 2))) 8525 (clobber (reg:CC FLAGS_REG))])] 8526 "split_double_mode (<DWI>mode, &operands[0], 2, &operands[0], &operands[2]);") 8527 8528(define_insn "*neg<mode>2_1" 8529 [(set (match_operand:SWI 0 "nonimmediate_operand" "=<r>m") 8530 (neg:SWI (match_operand:SWI 1 "nonimmediate_operand" "0"))) 8531 (clobber (reg:CC FLAGS_REG))] 8532 "ix86_unary_operator_ok (NEG, <MODE>mode, operands)" 8533 "neg{<imodesuffix>}\t%0" 8534 [(set_attr "type" "negnot") 8535 (set_attr "mode" "<MODE>")]) 8536 8537;; Combine is quite creative about this pattern. 8538(define_insn "*negsi2_1_zext" 8539 [(set (match_operand:DI 0 "register_operand" "=r") 8540 (lshiftrt:DI 8541 (neg:DI (ashift:DI (match_operand:DI 1 "register_operand" "0") 8542 (const_int 32))) 8543 (const_int 32))) 8544 (clobber (reg:CC FLAGS_REG))] 8545 "TARGET_64BIT && ix86_unary_operator_ok (NEG, SImode, operands)" 8546 "neg{l}\t%k0" 8547 [(set_attr "type" "negnot") 8548 (set_attr "mode" "SI")]) 8549 8550;; The problem with neg is that it does not perform (compare x 0), 8551;; it really performs (compare 0 x), which leaves us with the zero 8552;; flag being the only useful item. 8553 8554(define_insn "*neg<mode>2_cmpz" 8555 [(set (reg:CCZ FLAGS_REG) 8556 (compare:CCZ 8557 (neg:SWI (match_operand:SWI 1 "nonimmediate_operand" "0")) 8558 (const_int 0))) 8559 (set (match_operand:SWI 0 "nonimmediate_operand" "=<r>m") 8560 (neg:SWI (match_dup 1)))] 8561 "ix86_unary_operator_ok (NEG, <MODE>mode, operands)" 8562 "neg{<imodesuffix>}\t%0" 8563 [(set_attr "type" "negnot") 8564 (set_attr "mode" "<MODE>")]) 8565 8566(define_insn "*negsi2_cmpz_zext" 8567 [(set (reg:CCZ FLAGS_REG) 8568 (compare:CCZ 8569 (lshiftrt:DI 8570 (neg:DI (ashift:DI 8571 (match_operand:DI 1 "register_operand" "0") 8572 (const_int 32))) 8573 (const_int 32)) 8574 (const_int 0))) 8575 (set (match_operand:DI 0 "register_operand" "=r") 8576 (lshiftrt:DI (neg:DI (ashift:DI (match_dup 1) 8577 (const_int 32))) 8578 (const_int 32)))] 8579 "TARGET_64BIT && ix86_unary_operator_ok (NEG, SImode, operands)" 8580 "neg{l}\t%k0" 8581 [(set_attr "type" "negnot") 8582 (set_attr "mode" "SI")]) 8583 8584;; Changing of sign for FP values is doable using integer unit too. 8585 8586(define_expand "<code><mode>2" 8587 [(set (match_operand:X87MODEF 0 "register_operand" "") 8588 (absneg:X87MODEF (match_operand:X87MODEF 1 "register_operand" "")))] 8589 "TARGET_80387 || (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)" 8590 "ix86_expand_fp_absneg_operator (<CODE>, <MODE>mode, operands); DONE;") 8591 8592(define_insn "*absneg<mode>2_mixed" 8593 [(set (match_operand:MODEF 0 "register_operand" "=x,x,f,!r") 8594 (match_operator:MODEF 3 "absneg_operator" 8595 [(match_operand:MODEF 1 "register_operand" "0,x,0,0")])) 8596 (use (match_operand:<ssevecmode> 2 "nonimmediate_operand" "xm,0,X,X")) 8597 (clobber (reg:CC FLAGS_REG))] 8598 "TARGET_MIX_SSE_I387 && SSE_FLOAT_MODE_P (<MODE>mode)" 8599 "#") 8600 8601(define_insn "*absneg<mode>2_sse" 8602 [(set (match_operand:MODEF 0 "register_operand" "=x,x,!r") 8603 (match_operator:MODEF 3 "absneg_operator" 8604 [(match_operand:MODEF 1 "register_operand" "0 ,x,0")])) 8605 (use (match_operand:<ssevecmode> 2 "register_operand" "xm,0,X")) 8606 (clobber (reg:CC FLAGS_REG))] 8607 "SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH" 8608 "#") 8609 8610(define_insn "*absneg<mode>2_i387" 8611 [(set (match_operand:X87MODEF 0 "register_operand" "=f,!r") 8612 (match_operator:X87MODEF 3 "absneg_operator" 8613 [(match_operand:X87MODEF 1 "register_operand" "0,0")])) 8614 (use (match_operand 2 "" "")) 8615 (clobber (reg:CC FLAGS_REG))] 8616 "TARGET_80387 && !(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)" 8617 "#") 8618 8619(define_expand "<code>tf2" 8620 [(set (match_operand:TF 0 "register_operand" "") 8621 (absneg:TF (match_operand:TF 1 "register_operand" "")))] 8622 "TARGET_SSE2" 8623 "ix86_expand_fp_absneg_operator (<CODE>, TFmode, operands); DONE;") 8624 8625(define_insn "*absnegtf2_sse" 8626 [(set (match_operand:TF 0 "register_operand" "=x,x") 8627 (match_operator:TF 3 "absneg_operator" 8628 [(match_operand:TF 1 "register_operand" "0,x")])) 8629 (use (match_operand:TF 2 "nonimmediate_operand" "xm,0")) 8630 (clobber (reg:CC FLAGS_REG))] 8631 "TARGET_SSE2" 8632 "#") 8633 8634;; Splitters for fp abs and neg. 8635 8636(define_split 8637 [(set (match_operand 0 "fp_register_operand" "") 8638 (match_operator 1 "absneg_operator" [(match_dup 0)])) 8639 (use (match_operand 2 "" "")) 8640 (clobber (reg:CC FLAGS_REG))] 8641 "reload_completed" 8642 [(set (match_dup 0) (match_op_dup 1 [(match_dup 0)]))]) 8643 8644(define_split 8645 [(set (match_operand 0 "register_operand" "") 8646 (match_operator 3 "absneg_operator" 8647 [(match_operand 1 "register_operand" "")])) 8648 (use (match_operand 2 "nonimmediate_operand" "")) 8649 (clobber (reg:CC FLAGS_REG))] 8650 "reload_completed && SSE_REG_P (operands[0])" 8651 [(set (match_dup 0) (match_dup 3))] 8652{ 8653 enum machine_mode mode = GET_MODE (operands[0]); 8654 enum machine_mode vmode = GET_MODE (operands[2]); 8655 rtx tmp; 8656 8657 operands[0] = simplify_gen_subreg (vmode, operands[0], mode, 0); 8658 operands[1] = simplify_gen_subreg (vmode, operands[1], mode, 0); 8659 if (operands_match_p (operands[0], operands[2])) 8660 { 8661 tmp = operands[1]; 8662 operands[1] = operands[2]; 8663 operands[2] = tmp; 8664 } 8665 if (GET_CODE (operands[3]) == ABS) 8666 tmp = gen_rtx_AND (vmode, operands[1], operands[2]); 8667 else 8668 tmp = gen_rtx_XOR (vmode, operands[1], operands[2]); 8669 operands[3] = tmp; 8670}) 8671 8672(define_split 8673 [(set (match_operand:SF 0 "register_operand" "") 8674 (match_operator:SF 1 "absneg_operator" [(match_dup 0)])) 8675 (use (match_operand:V4SF 2 "" "")) 8676 (clobber (reg:CC FLAGS_REG))] 8677 "reload_completed" 8678 [(parallel [(set (match_dup 0) (match_dup 1)) 8679 (clobber (reg:CC FLAGS_REG))])] 8680{ 8681 rtx tmp; 8682 operands[0] = gen_lowpart (SImode, operands[0]); 8683 if (GET_CODE (operands[1]) == ABS) 8684 { 8685 tmp = gen_int_mode (0x7fffffff, SImode); 8686 tmp = gen_rtx_AND (SImode, operands[0], tmp); 8687 } 8688 else 8689 { 8690 tmp = gen_int_mode (0x80000000, SImode); 8691 tmp = gen_rtx_XOR (SImode, operands[0], tmp); 8692 } 8693 operands[1] = tmp; 8694}) 8695 8696(define_split 8697 [(set (match_operand:DF 0 "register_operand" "") 8698 (match_operator:DF 1 "absneg_operator" [(match_dup 0)])) 8699 (use (match_operand 2 "" "")) 8700 (clobber (reg:CC FLAGS_REG))] 8701 "reload_completed" 8702 [(parallel [(set (match_dup 0) (match_dup 1)) 8703 (clobber (reg:CC FLAGS_REG))])] 8704{ 8705 rtx tmp; 8706 if (TARGET_64BIT) 8707 { 8708 tmp = gen_lowpart (DImode, operands[0]); 8709 tmp = gen_rtx_ZERO_EXTRACT (DImode, tmp, const1_rtx, GEN_INT (63)); 8710 operands[0] = tmp; 8711 8712 if (GET_CODE (operands[1]) == ABS) 8713 tmp = const0_rtx; 8714 else 8715 tmp = gen_rtx_NOT (DImode, tmp); 8716 } 8717 else 8718 { 8719 operands[0] = gen_highpart (SImode, operands[0]); 8720 if (GET_CODE (operands[1]) == ABS) 8721 { 8722 tmp = gen_int_mode (0x7fffffff, SImode); 8723 tmp = gen_rtx_AND (SImode, operands[0], tmp); 8724 } 8725 else 8726 { 8727 tmp = gen_int_mode (0x80000000, SImode); 8728 tmp = gen_rtx_XOR (SImode, operands[0], tmp); 8729 } 8730 } 8731 operands[1] = tmp; 8732}) 8733 8734(define_split 8735 [(set (match_operand:XF 0 "register_operand" "") 8736 (match_operator:XF 1 "absneg_operator" [(match_dup 0)])) 8737 (use (match_operand 2 "" "")) 8738 (clobber (reg:CC FLAGS_REG))] 8739 "reload_completed" 8740 [(parallel [(set (match_dup 0) (match_dup 1)) 8741 (clobber (reg:CC FLAGS_REG))])] 8742{ 8743 rtx tmp; 8744 operands[0] = gen_rtx_REG (SImode, 8745 true_regnum (operands[0]) 8746 + (TARGET_64BIT ? 1 : 2)); 8747 if (GET_CODE (operands[1]) == ABS) 8748 { 8749 tmp = GEN_INT (0x7fff); 8750 tmp = gen_rtx_AND (SImode, operands[0], tmp); 8751 } 8752 else 8753 { 8754 tmp = GEN_INT (0x8000); 8755 tmp = gen_rtx_XOR (SImode, operands[0], tmp); 8756 } 8757 operands[1] = tmp; 8758}) 8759 8760;; Conditionalize these after reload. If they match before reload, we 8761;; lose the clobber and ability to use integer instructions. 8762 8763(define_insn "*<code><mode>2_1" 8764 [(set (match_operand:X87MODEF 0 "register_operand" "=f") 8765 (absneg:X87MODEF (match_operand:X87MODEF 1 "register_operand" "0")))] 8766 "TARGET_80387 8767 && (reload_completed 8768 || !(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH))" 8769 "f<absneg_mnemonic>" 8770 [(set_attr "type" "fsgn") 8771 (set_attr "mode" "<MODE>")]) 8772 8773(define_insn "*<code>extendsfdf2" 8774 [(set (match_operand:DF 0 "register_operand" "=f") 8775 (absneg:DF (float_extend:DF 8776 (match_operand:SF 1 "register_operand" "0"))))] 8777 "TARGET_80387 && (!TARGET_SSE_MATH || TARGET_MIX_SSE_I387)" 8778 "f<absneg_mnemonic>" 8779 [(set_attr "type" "fsgn") 8780 (set_attr "mode" "DF")]) 8781 8782(define_insn "*<code>extendsfxf2" 8783 [(set (match_operand:XF 0 "register_operand" "=f") 8784 (absneg:XF (float_extend:XF 8785 (match_operand:SF 1 "register_operand" "0"))))] 8786 "TARGET_80387" 8787 "f<absneg_mnemonic>" 8788 [(set_attr "type" "fsgn") 8789 (set_attr "mode" "XF")]) 8790 8791(define_insn "*<code>extenddfxf2" 8792 [(set (match_operand:XF 0 "register_operand" "=f") 8793 (absneg:XF (float_extend:XF 8794 (match_operand:DF 1 "register_operand" "0"))))] 8795 "TARGET_80387" 8796 "f<absneg_mnemonic>" 8797 [(set_attr "type" "fsgn") 8798 (set_attr "mode" "XF")]) 8799 8800;; Copysign instructions 8801 8802(define_mode_iterator CSGNMODE [SF DF TF]) 8803(define_mode_attr CSGNVMODE [(SF "V4SF") (DF "V2DF") (TF "TF")]) 8804 8805(define_expand "copysign<mode>3" 8806 [(match_operand:CSGNMODE 0 "register_operand" "") 8807 (match_operand:CSGNMODE 1 "nonmemory_operand" "") 8808 (match_operand:CSGNMODE 2 "register_operand" "")] 8809 "(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH) 8810 || (TARGET_SSE2 && (<MODE>mode == TFmode))" 8811 "ix86_expand_copysign (operands); DONE;") 8812 8813(define_insn_and_split "copysign<mode>3_const" 8814 [(set (match_operand:CSGNMODE 0 "register_operand" "=x") 8815 (unspec:CSGNMODE 8816 [(match_operand:<CSGNVMODE> 1 "vector_move_operand" "xmC") 8817 (match_operand:CSGNMODE 2 "register_operand" "0") 8818 (match_operand:<CSGNVMODE> 3 "nonimmediate_operand" "xm")] 8819 UNSPEC_COPYSIGN))] 8820 "(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH) 8821 || (TARGET_SSE2 && (<MODE>mode == TFmode))" 8822 "#" 8823 "&& reload_completed" 8824 [(const_int 0)] 8825 "ix86_split_copysign_const (operands); DONE;") 8826 8827(define_insn "copysign<mode>3_var" 8828 [(set (match_operand:CSGNMODE 0 "register_operand" "=x,x,x,x,x") 8829 (unspec:CSGNMODE 8830 [(match_operand:CSGNMODE 2 "register_operand" "x,0,0,x,x") 8831 (match_operand:CSGNMODE 3 "register_operand" "1,1,x,1,x") 8832 (match_operand:<CSGNVMODE> 4 "nonimmediate_operand" "X,xm,xm,0,0") 8833 (match_operand:<CSGNVMODE> 5 "nonimmediate_operand" "0,xm,1,xm,1")] 8834 UNSPEC_COPYSIGN)) 8835 (clobber (match_scratch:<CSGNVMODE> 1 "=x,x,x,x,x"))] 8836 "(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH) 8837 || (TARGET_SSE2 && (<MODE>mode == TFmode))" 8838 "#") 8839 8840(define_split 8841 [(set (match_operand:CSGNMODE 0 "register_operand" "") 8842 (unspec:CSGNMODE 8843 [(match_operand:CSGNMODE 2 "register_operand" "") 8844 (match_operand:CSGNMODE 3 "register_operand" "") 8845 (match_operand:<CSGNVMODE> 4 "" "") 8846 (match_operand:<CSGNVMODE> 5 "" "")] 8847 UNSPEC_COPYSIGN)) 8848 (clobber (match_scratch:<CSGNVMODE> 1 ""))] 8849 "((SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH) 8850 || (TARGET_SSE2 && (<MODE>mode == TFmode))) 8851 && reload_completed" 8852 [(const_int 0)] 8853 "ix86_split_copysign_var (operands); DONE;") 8854 8855;; One complement instructions 8856 8857(define_expand "one_cmpl<mode>2" 8858 [(set (match_operand:SWIM 0 "nonimmediate_operand" "") 8859 (not:SWIM (match_operand:SWIM 1 "nonimmediate_operand" "")))] 8860 "" 8861 "ix86_expand_unary_operator (NOT, <MODE>mode, operands); DONE;") 8862 8863(define_insn "*one_cmpl<mode>2_1" 8864 [(set (match_operand:SWI248 0 "nonimmediate_operand" "=rm") 8865 (not:SWI248 (match_operand:SWI248 1 "nonimmediate_operand" "0")))] 8866 "ix86_unary_operator_ok (NOT, <MODE>mode, operands)" 8867 "not{<imodesuffix>}\t%0" 8868 [(set_attr "type" "negnot") 8869 (set_attr "mode" "<MODE>")]) 8870 8871;; %%% Potential partial reg stall on alternative 1. What to do? 8872(define_insn "*one_cmplqi2_1" 8873 [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,r") 8874 (not:QI (match_operand:QI 1 "nonimmediate_operand" "0,0")))] 8875 "ix86_unary_operator_ok (NOT, QImode, operands)" 8876 "@ 8877 not{b}\t%0 8878 not{l}\t%k0" 8879 [(set_attr "type" "negnot") 8880 (set_attr "mode" "QI,SI")]) 8881 8882;; ??? Currently never generated - xor is used instead. 8883(define_insn "*one_cmplsi2_1_zext" 8884 [(set (match_operand:DI 0 "register_operand" "=r") 8885 (zero_extend:DI 8886 (not:SI (match_operand:SI 1 "register_operand" "0"))))] 8887 "TARGET_64BIT && ix86_unary_operator_ok (NOT, SImode, operands)" 8888 "not{l}\t%k0" 8889 [(set_attr "type" "negnot") 8890 (set_attr "mode" "SI")]) 8891 8892(define_insn "*one_cmpl<mode>2_2" 8893 [(set (reg FLAGS_REG) 8894 (compare (not:SWI (match_operand:SWI 1 "nonimmediate_operand" "0")) 8895 (const_int 0))) 8896 (set (match_operand:SWI 0 "nonimmediate_operand" "=<r>m") 8897 (not:SWI (match_dup 1)))] 8898 "ix86_match_ccmode (insn, CCNOmode) 8899 && ix86_unary_operator_ok (NOT, <MODE>mode, operands)" 8900 "#" 8901 [(set_attr "type" "alu1") 8902 (set_attr "mode" "<MODE>")]) 8903 8904(define_split 8905 [(set (match_operand 0 "flags_reg_operand" "") 8906 (match_operator 2 "compare_operator" 8907 [(not:SWI (match_operand:SWI 3 "nonimmediate_operand" "")) 8908 (const_int 0)])) 8909 (set (match_operand:SWI 1 "nonimmediate_operand" "") 8910 (not:SWI (match_dup 3)))] 8911 "ix86_match_ccmode (insn, CCNOmode)" 8912 [(parallel [(set (match_dup 0) 8913 (match_op_dup 2 [(xor:SWI (match_dup 3) (const_int -1)) 8914 (const_int 0)])) 8915 (set (match_dup 1) 8916 (xor:SWI (match_dup 3) (const_int -1)))])]) 8917 8918;; ??? Currently never generated - xor is used instead. 8919(define_insn "*one_cmplsi2_2_zext" 8920 [(set (reg FLAGS_REG) 8921 (compare (not:SI (match_operand:SI 1 "register_operand" "0")) 8922 (const_int 0))) 8923 (set (match_operand:DI 0 "register_operand" "=r") 8924 (zero_extend:DI (not:SI (match_dup 1))))] 8925 "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode) 8926 && ix86_unary_operator_ok (NOT, SImode, operands)" 8927 "#" 8928 [(set_attr "type" "alu1") 8929 (set_attr "mode" "SI")]) 8930 8931(define_split 8932 [(set (match_operand 0 "flags_reg_operand" "") 8933 (match_operator 2 "compare_operator" 8934 [(not:SI (match_operand:SI 3 "register_operand" "")) 8935 (const_int 0)])) 8936 (set (match_operand:DI 1 "register_operand" "") 8937 (zero_extend:DI (not:SI (match_dup 3))))] 8938 "ix86_match_ccmode (insn, CCNOmode)" 8939 [(parallel [(set (match_dup 0) 8940 (match_op_dup 2 [(xor:SI (match_dup 3) (const_int -1)) 8941 (const_int 0)])) 8942 (set (match_dup 1) 8943 (zero_extend:DI (xor:SI (match_dup 3) (const_int -1))))])]) 8944 8945;; Shift instructions 8946 8947;; DImode shifts are implemented using the i386 "shift double" opcode, 8948;; which is written as "sh[lr]d[lw] imm,reg,reg/mem". If the shift count 8949;; is variable, then the count is in %cl and the "imm" operand is dropped 8950;; from the assembler input. 8951;; 8952;; This instruction shifts the target reg/mem as usual, but instead of 8953;; shifting in zeros, bits are shifted in from reg operand. If the insn 8954;; is a left shift double, bits are taken from the high order bits of 8955;; reg, else if the insn is a shift right double, bits are taken from the 8956;; low order bits of reg. So if %eax is "1234" and %edx is "5678", 8957;; "shldl $8,%edx,%eax" leaves %edx unchanged and sets %eax to "2345". 8958;; 8959;; Since sh[lr]d does not change the `reg' operand, that is done 8960;; separately, making all shifts emit pairs of shift double and normal 8961;; shift. Since sh[lr]d does not shift more than 31 bits, and we wish to 8962;; support a 63 bit shift, each shift where the count is in a reg expands 8963;; to a pair of shifts, a branch, a shift by 32 and a label. 8964;; 8965;; If the shift count is a constant, we need never emit more than one 8966;; shift pair, instead using moves and sign extension for counts greater 8967;; than 31. 8968 8969(define_expand "ashl<mode>3" 8970 [(set (match_operand:SDWIM 0 "<shift_operand>" "") 8971 (ashift:SDWIM (match_operand:SDWIM 1 "<ashl_input_operand>" "") 8972 (match_operand:QI 2 "nonmemory_operand" "")))] 8973 "" 8974 "ix86_expand_binary_operator (ASHIFT, <MODE>mode, operands); DONE;") 8975 8976(define_insn "*ashl<mode>3_doubleword" 8977 [(set (match_operand:DWI 0 "register_operand" "=&r,r") 8978 (ashift:DWI (match_operand:DWI 1 "reg_or_pm1_operand" "n,0") 8979 (match_operand:QI 2 "nonmemory_operand" "<S>c,<S>c"))) 8980 (clobber (reg:CC FLAGS_REG))] 8981 "" 8982 "#" 8983 [(set_attr "type" "multi")]) 8984 8985(define_split 8986 [(set (match_operand:DWI 0 "register_operand" "") 8987 (ashift:DWI (match_operand:DWI 1 "nonmemory_operand" "") 8988 (match_operand:QI 2 "nonmemory_operand" ""))) 8989 (clobber (reg:CC FLAGS_REG))] 8990 "(optimize && flag_peephole2) ? epilogue_completed : reload_completed" 8991 [(const_int 0)] 8992 "ix86_split_ashl (operands, NULL_RTX, <MODE>mode); DONE;") 8993 8994;; By default we don't ask for a scratch register, because when DWImode 8995;; values are manipulated, registers are already at a premium. But if 8996;; we have one handy, we won't turn it away. 8997 8998(define_peephole2 8999 [(match_scratch:DWIH 3 "r") 9000 (parallel [(set (match_operand:<DWI> 0 "register_operand" "") 9001 (ashift:<DWI> 9002 (match_operand:<DWI> 1 "nonmemory_operand" "") 9003 (match_operand:QI 2 "nonmemory_operand" ""))) 9004 (clobber (reg:CC FLAGS_REG))]) 9005 (match_dup 3)] 9006 "TARGET_CMOVE" 9007 [(const_int 0)] 9008 "ix86_split_ashl (operands, operands[3], <DWI>mode); DONE;") 9009 9010(define_insn "x86_64_shld" 9011 [(set (match_operand:DI 0 "nonimmediate_operand" "+r*m") 9012 (ior:DI (ashift:DI (match_dup 0) 9013 (match_operand:QI 2 "nonmemory_operand" "Jc")) 9014 (lshiftrt:DI (match_operand:DI 1 "register_operand" "r") 9015 (minus:QI (const_int 64) (match_dup 2))))) 9016 (clobber (reg:CC FLAGS_REG))] 9017 "TARGET_64BIT" 9018 "shld{q}\t{%s2%1, %0|%0, %1, %2}" 9019 [(set_attr "type" "ishift") 9020 (set_attr "prefix_0f" "1") 9021 (set_attr "mode" "DI") 9022 (set_attr "athlon_decode" "vector") 9023 (set_attr "amdfam10_decode" "vector") 9024 (set_attr "bdver1_decode" "vector")]) 9025 9026(define_insn "x86_shld" 9027 [(set (match_operand:SI 0 "nonimmediate_operand" "+r*m") 9028 (ior:SI (ashift:SI (match_dup 0) 9029 (match_operand:QI 2 "nonmemory_operand" "Ic")) 9030 (lshiftrt:SI (match_operand:SI 1 "register_operand" "r") 9031 (minus:QI (const_int 32) (match_dup 2))))) 9032 (clobber (reg:CC FLAGS_REG))] 9033 "" 9034 "shld{l}\t{%s2%1, %0|%0, %1, %2}" 9035 [(set_attr "type" "ishift") 9036 (set_attr "prefix_0f" "1") 9037 (set_attr "mode" "SI") 9038 (set_attr "pent_pair" "np") 9039 (set_attr "athlon_decode" "vector") 9040 (set_attr "amdfam10_decode" "vector") 9041 (set_attr "bdver1_decode" "vector")]) 9042 9043(define_expand "x86_shift<mode>_adj_1" 9044 [(set (reg:CCZ FLAGS_REG) 9045 (compare:CCZ (and:QI (match_operand:QI 2 "register_operand" "") 9046 (match_dup 4)) 9047 (const_int 0))) 9048 (set (match_operand:SWI48 0 "register_operand" "") 9049 (if_then_else:SWI48 (ne (reg:CCZ FLAGS_REG) (const_int 0)) 9050 (match_operand:SWI48 1 "register_operand" "") 9051 (match_dup 0))) 9052 (set (match_dup 1) 9053 (if_then_else:SWI48 (ne (reg:CCZ FLAGS_REG) (const_int 0)) 9054 (match_operand:SWI48 3 "register_operand" "") 9055 (match_dup 1)))] 9056 "TARGET_CMOVE" 9057 "operands[4] = GEN_INT (GET_MODE_BITSIZE (<MODE>mode));") 9058 9059(define_expand "x86_shift<mode>_adj_2" 9060 [(use (match_operand:SWI48 0 "register_operand" "")) 9061 (use (match_operand:SWI48 1 "register_operand" "")) 9062 (use (match_operand:QI 2 "register_operand" ""))] 9063 "" 9064{ 9065 rtx label = gen_label_rtx (); 9066 rtx tmp; 9067 9068 emit_insn (gen_testqi_ccz_1 (operands[2], 9069 GEN_INT (GET_MODE_BITSIZE (<MODE>mode)))); 9070 9071 tmp = gen_rtx_REG (CCZmode, FLAGS_REG); 9072 tmp = gen_rtx_EQ (VOIDmode, tmp, const0_rtx); 9073 tmp = gen_rtx_IF_THEN_ELSE (VOIDmode, tmp, 9074 gen_rtx_LABEL_REF (VOIDmode, label), 9075 pc_rtx); 9076 tmp = emit_jump_insn (gen_rtx_SET (VOIDmode, pc_rtx, tmp)); 9077 JUMP_LABEL (tmp) = label; 9078 9079 emit_move_insn (operands[0], operands[1]); 9080 ix86_expand_clear (operands[1]); 9081 9082 emit_label (label); 9083 LABEL_NUSES (label) = 1; 9084 9085 DONE; 9086}) 9087 9088;; Avoid useless masking of count operand. 9089(define_insn "*ashl<mode>3_mask" 9090 [(set (match_operand:SWI48 0 "nonimmediate_operand" "=rm") 9091 (ashift:SWI48 9092 (match_operand:SWI48 1 "nonimmediate_operand" "0") 9093 (subreg:QI 9094 (and:SI 9095 (match_operand:SI 2 "register_operand" "c") 9096 (match_operand:SI 3 "const_int_operand" "n")) 0))) 9097 (clobber (reg:CC FLAGS_REG))] 9098 "ix86_binary_operator_ok (ASHIFT, <MODE>mode, operands) 9099 && (INTVAL (operands[3]) & (GET_MODE_BITSIZE (<MODE>mode)-1)) 9100 == GET_MODE_BITSIZE (<MODE>mode)-1" 9101{ 9102 return "sal{<imodesuffix>}\t{%b2, %0|%0, %b2}"; 9103} 9104 [(set_attr "type" "ishift") 9105 (set_attr "mode" "<MODE>")]) 9106 9107(define_insn "*bmi2_ashl<mode>3_1" 9108 [(set (match_operand:SWI48 0 "register_operand" "=r") 9109 (ashift:SWI48 (match_operand:SWI48 1 "nonimmediate_operand" "rm") 9110 (match_operand:SWI48 2 "register_operand" "r")))] 9111 "TARGET_BMI2" 9112 "shlx\t{%2, %1, %0|%0, %1, %2}" 9113 [(set_attr "type" "ishiftx") 9114 (set_attr "mode" "<MODE>")]) 9115 9116(define_insn "*ashl<mode>3_1" 9117 [(set (match_operand:SWI48 0 "nonimmediate_operand" "=rm,r,r") 9118 (ashift:SWI48 (match_operand:SWI48 1 "nonimmediate_operand" "0,l,rm") 9119 (match_operand:QI 2 "nonmemory_operand" "c<S>,M,r"))) 9120 (clobber (reg:CC FLAGS_REG))] 9121 "ix86_binary_operator_ok (ASHIFT, <MODE>mode, operands)" 9122{ 9123 switch (get_attr_type (insn)) 9124 { 9125 case TYPE_LEA: 9126 case TYPE_ISHIFTX: 9127 return "#"; 9128 9129 case TYPE_ALU: 9130 gcc_assert (operands[2] == const1_rtx); 9131 gcc_assert (rtx_equal_p (operands[0], operands[1])); 9132 return "add{<imodesuffix>}\t%0, %0"; 9133 9134 default: 9135 if (operands[2] == const1_rtx 9136 && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun))) 9137 return "sal{<imodesuffix>}\t%0"; 9138 else 9139 return "sal{<imodesuffix>}\t{%2, %0|%0, %2}"; 9140 } 9141} 9142 [(set_attr "isa" "*,*,bmi2") 9143 (set (attr "type") 9144 (cond [(eq_attr "alternative" "1") 9145 (const_string "lea") 9146 (eq_attr "alternative" "2") 9147 (const_string "ishiftx") 9148 (and (and (match_test "TARGET_DOUBLE_WITH_ADD") 9149 (match_operand 0 "register_operand" "")) 9150 (match_operand 2 "const1_operand" "")) 9151 (const_string "alu") 9152 ] 9153 (const_string "ishift"))) 9154 (set (attr "length_immediate") 9155 (if_then_else 9156 (ior (eq_attr "type" "alu") 9157 (and (eq_attr "type" "ishift") 9158 (and (match_operand 2 "const1_operand" "") 9159 (ior (match_test "TARGET_SHIFT1") 9160 (match_test "optimize_function_for_size_p (cfun)"))))) 9161 (const_string "0") 9162 (const_string "*"))) 9163 (set_attr "mode" "<MODE>")]) 9164 9165;; Convert shift to the shiftx pattern to avoid flags dependency. 9166(define_split 9167 [(set (match_operand:SWI48 0 "register_operand" "") 9168 (ashift:SWI48 (match_operand:SWI48 1 "nonimmediate_operand" "") 9169 (match_operand:QI 2 "register_operand" ""))) 9170 (clobber (reg:CC FLAGS_REG))] 9171 "TARGET_BMI2 && reload_completed" 9172 [(set (match_dup 0) 9173 (ashift:SWI48 (match_dup 1) (match_dup 2)))] 9174 "operands[2] = gen_lowpart (<MODE>mode, operands[2]);") 9175 9176(define_insn "*bmi2_ashlsi3_1_zext" 9177 [(set (match_operand:DI 0 "register_operand" "=r") 9178 (zero_extend:DI 9179 (ashift:SI (match_operand:SI 1 "nonimmediate_operand" "rm") 9180 (match_operand:SI 2 "register_operand" "r"))))] 9181 "TARGET_64BIT && TARGET_BMI2" 9182 "shlx\t{%2, %1, %k0|%k0, %1, %2}" 9183 [(set_attr "type" "ishiftx") 9184 (set_attr "mode" "SI")]) 9185 9186(define_insn "*ashlsi3_1_zext" 9187 [(set (match_operand:DI 0 "register_operand" "=r,r,r") 9188 (zero_extend:DI 9189 (ashift:SI (match_operand:SI 1 "nonimmediate_operand" "0,l,rm") 9190 (match_operand:QI 2 "nonmemory_operand" "cI,M,r")))) 9191 (clobber (reg:CC FLAGS_REG))] 9192 "TARGET_64BIT && ix86_binary_operator_ok (ASHIFT, SImode, operands)" 9193{ 9194 switch (get_attr_type (insn)) 9195 { 9196 case TYPE_LEA: 9197 case TYPE_ISHIFTX: 9198 return "#"; 9199 9200 case TYPE_ALU: 9201 gcc_assert (operands[2] == const1_rtx); 9202 return "add{l}\t%k0, %k0"; 9203 9204 default: 9205 if (operands[2] == const1_rtx 9206 && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun))) 9207 return "sal{l}\t%k0"; 9208 else 9209 return "sal{l}\t{%2, %k0|%k0, %2}"; 9210 } 9211} 9212 [(set_attr "isa" "*,*,bmi2") 9213 (set (attr "type") 9214 (cond [(eq_attr "alternative" "1") 9215 (const_string "lea") 9216 (eq_attr "alternative" "2") 9217 (const_string "ishiftx") 9218 (and (match_test "TARGET_DOUBLE_WITH_ADD") 9219 (match_operand 2 "const1_operand" "")) 9220 (const_string "alu") 9221 ] 9222 (const_string "ishift"))) 9223 (set (attr "length_immediate") 9224 (if_then_else 9225 (ior (eq_attr "type" "alu") 9226 (and (eq_attr "type" "ishift") 9227 (and (match_operand 2 "const1_operand" "") 9228 (ior (match_test "TARGET_SHIFT1") 9229 (match_test "optimize_function_for_size_p (cfun)"))))) 9230 (const_string "0") 9231 (const_string "*"))) 9232 (set_attr "mode" "SI")]) 9233 9234;; Convert shift to the shiftx pattern to avoid flags dependency. 9235(define_split 9236 [(set (match_operand:DI 0 "register_operand" "") 9237 (zero_extend:DI 9238 (ashift:SI (match_operand:SI 1 "nonimmediate_operand" "") 9239 (match_operand:QI 2 "register_operand" "")))) 9240 (clobber (reg:CC FLAGS_REG))] 9241 "TARGET_64BIT && TARGET_BMI2 && reload_completed" 9242 [(set (match_dup 0) 9243 (zero_extend:DI (ashift:SI (match_dup 1) (match_dup 2))))] 9244 "operands[2] = gen_lowpart (SImode, operands[2]);") 9245 9246(define_insn "*ashlhi3_1" 9247 [(set (match_operand:HI 0 "nonimmediate_operand" "=rm,Yp") 9248 (ashift:HI (match_operand:HI 1 "nonimmediate_operand" "0,l") 9249 (match_operand:QI 2 "nonmemory_operand" "cI,M"))) 9250 (clobber (reg:CC FLAGS_REG))] 9251 "ix86_binary_operator_ok (ASHIFT, HImode, operands)" 9252{ 9253 switch (get_attr_type (insn)) 9254 { 9255 case TYPE_LEA: 9256 return "#"; 9257 9258 case TYPE_ALU: 9259 gcc_assert (operands[2] == const1_rtx); 9260 return "add{w}\t%0, %0"; 9261 9262 default: 9263 if (operands[2] == const1_rtx 9264 && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun))) 9265 return "sal{w}\t%0"; 9266 else 9267 return "sal{w}\t{%2, %0|%0, %2}"; 9268 } 9269} 9270 [(set (attr "type") 9271 (cond [(eq_attr "alternative" "1") 9272 (const_string "lea") 9273 (and (and (match_test "TARGET_DOUBLE_WITH_ADD") 9274 (match_operand 0 "register_operand" "")) 9275 (match_operand 2 "const1_operand" "")) 9276 (const_string "alu") 9277 ] 9278 (const_string "ishift"))) 9279 (set (attr "length_immediate") 9280 (if_then_else 9281 (ior (eq_attr "type" "alu") 9282 (and (eq_attr "type" "ishift") 9283 (and (match_operand 2 "const1_operand" "") 9284 (ior (match_test "TARGET_SHIFT1") 9285 (match_test "optimize_function_for_size_p (cfun)"))))) 9286 (const_string "0") 9287 (const_string "*"))) 9288 (set_attr "mode" "HI,SI")]) 9289 9290;; %%% Potential partial reg stall on alternative 1. What to do? 9291(define_insn "*ashlqi3_1" 9292 [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,r,Yp") 9293 (ashift:QI (match_operand:QI 1 "nonimmediate_operand" "0,0,l") 9294 (match_operand:QI 2 "nonmemory_operand" "cI,cI,M"))) 9295 (clobber (reg:CC FLAGS_REG))] 9296 "ix86_binary_operator_ok (ASHIFT, QImode, operands)" 9297{ 9298 switch (get_attr_type (insn)) 9299 { 9300 case TYPE_LEA: 9301 return "#"; 9302 9303 case TYPE_ALU: 9304 gcc_assert (operands[2] == const1_rtx); 9305 if (REG_P (operands[1]) && !ANY_QI_REG_P (operands[1])) 9306 return "add{l}\t%k0, %k0"; 9307 else 9308 return "add{b}\t%0, %0"; 9309 9310 default: 9311 if (operands[2] == const1_rtx 9312 && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun))) 9313 { 9314 if (get_attr_mode (insn) == MODE_SI) 9315 return "sal{l}\t%k0"; 9316 else 9317 return "sal{b}\t%0"; 9318 } 9319 else 9320 { 9321 if (get_attr_mode (insn) == MODE_SI) 9322 return "sal{l}\t{%2, %k0|%k0, %2}"; 9323 else 9324 return "sal{b}\t{%2, %0|%0, %2}"; 9325 } 9326 } 9327} 9328 [(set (attr "type") 9329 (cond [(eq_attr "alternative" "2") 9330 (const_string "lea") 9331 (and (and (match_test "TARGET_DOUBLE_WITH_ADD") 9332 (match_operand 0 "register_operand" "")) 9333 (match_operand 2 "const1_operand" "")) 9334 (const_string "alu") 9335 ] 9336 (const_string "ishift"))) 9337 (set (attr "length_immediate") 9338 (if_then_else 9339 (ior (eq_attr "type" "alu") 9340 (and (eq_attr "type" "ishift") 9341 (and (match_operand 2 "const1_operand" "") 9342 (ior (match_test "TARGET_SHIFT1") 9343 (match_test "optimize_function_for_size_p (cfun)"))))) 9344 (const_string "0") 9345 (const_string "*"))) 9346 (set_attr "mode" "QI,SI,SI")]) 9347 9348(define_insn "*ashlqi3_1_slp" 9349 [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm")) 9350 (ashift:QI (match_dup 0) 9351 (match_operand:QI 1 "nonmemory_operand" "cI"))) 9352 (clobber (reg:CC FLAGS_REG))] 9353 "(optimize_function_for_size_p (cfun) 9354 || !TARGET_PARTIAL_FLAG_REG_STALL 9355 || (operands[1] == const1_rtx 9356 && (TARGET_SHIFT1 9357 || (TARGET_DOUBLE_WITH_ADD && REG_P (operands[0])))))" 9358{ 9359 switch (get_attr_type (insn)) 9360 { 9361 case TYPE_ALU: 9362 gcc_assert (operands[1] == const1_rtx); 9363 return "add{b}\t%0, %0"; 9364 9365 default: 9366 if (operands[1] == const1_rtx 9367 && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun))) 9368 return "sal{b}\t%0"; 9369 else 9370 return "sal{b}\t{%1, %0|%0, %1}"; 9371 } 9372} 9373 [(set (attr "type") 9374 (cond [(and (and (match_test "TARGET_DOUBLE_WITH_ADD") 9375 (match_operand 0 "register_operand" "")) 9376 (match_operand 1 "const1_operand" "")) 9377 (const_string "alu") 9378 ] 9379 (const_string "ishift1"))) 9380 (set (attr "length_immediate") 9381 (if_then_else 9382 (ior (eq_attr "type" "alu") 9383 (and (eq_attr "type" "ishift1") 9384 (and (match_operand 1 "const1_operand" "") 9385 (ior (match_test "TARGET_SHIFT1") 9386 (match_test "optimize_function_for_size_p (cfun)"))))) 9387 (const_string "0") 9388 (const_string "*"))) 9389 (set_attr "mode" "QI")]) 9390 9391;; Convert ashift to the lea pattern to avoid flags dependency. 9392(define_split 9393 [(set (match_operand 0 "register_operand" "") 9394 (ashift (match_operand 1 "index_register_operand" "") 9395 (match_operand:QI 2 "const_int_operand" ""))) 9396 (clobber (reg:CC FLAGS_REG))] 9397 "GET_MODE (operands[0]) == GET_MODE (operands[1]) 9398 && reload_completed 9399 && true_regnum (operands[0]) != true_regnum (operands[1])" 9400 [(const_int 0)] 9401{ 9402 enum machine_mode mode = GET_MODE (operands[0]); 9403 rtx pat; 9404 9405 if (GET_MODE_SIZE (mode) < GET_MODE_SIZE (SImode)) 9406 { 9407 mode = SImode; 9408 operands[0] = gen_lowpart (mode, operands[0]); 9409 operands[1] = gen_lowpart (mode, operands[1]); 9410 } 9411 9412 operands[2] = gen_int_mode (1 << INTVAL (operands[2]), mode); 9413 9414 pat = gen_rtx_MULT (mode, operands[1], operands[2]); 9415 9416 emit_insn (gen_rtx_SET (VOIDmode, operands[0], pat)); 9417 DONE; 9418}) 9419 9420;; Convert ashift to the lea pattern to avoid flags dependency. 9421(define_split 9422 [(set (match_operand:DI 0 "register_operand" "") 9423 (zero_extend:DI 9424 (ashift:SI (match_operand:SI 1 "index_register_operand" "") 9425 (match_operand:QI 2 "const_int_operand" "")))) 9426 (clobber (reg:CC FLAGS_REG))] 9427 "TARGET_64BIT && reload_completed 9428 && true_regnum (operands[0]) != true_regnum (operands[1])" 9429 [(set (match_dup 0) 9430 (zero_extend:DI (subreg:SI (mult:DI (match_dup 1) (match_dup 2)) 0)))] 9431{ 9432 operands[1] = gen_lowpart (DImode, operands[1]); 9433 operands[2] = gen_int_mode (1 << INTVAL (operands[2]), DImode); 9434}) 9435 9436;; This pattern can't accept a variable shift count, since shifts by 9437;; zero don't affect the flags. We assume that shifts by constant 9438;; zero are optimized away. 9439(define_insn "*ashl<mode>3_cmp" 9440 [(set (reg FLAGS_REG) 9441 (compare 9442 (ashift:SWI (match_operand:SWI 1 "nonimmediate_operand" "0") 9443 (match_operand:QI 2 "<shift_immediate_operand>" "<S>")) 9444 (const_int 0))) 9445 (set (match_operand:SWI 0 "nonimmediate_operand" "=<r>m") 9446 (ashift:SWI (match_dup 1) (match_dup 2)))] 9447 "(optimize_function_for_size_p (cfun) 9448 || !TARGET_PARTIAL_FLAG_REG_STALL 9449 || (operands[2] == const1_rtx 9450 && (TARGET_SHIFT1 9451 || (TARGET_DOUBLE_WITH_ADD && REG_P (operands[0]))))) 9452 && ix86_match_ccmode (insn, CCGOCmode) 9453 && ix86_binary_operator_ok (ASHIFT, <MODE>mode, operands)" 9454{ 9455 switch (get_attr_type (insn)) 9456 { 9457 case TYPE_ALU: 9458 gcc_assert (operands[2] == const1_rtx); 9459 return "add{<imodesuffix>}\t%0, %0"; 9460 9461 default: 9462 if (operands[2] == const1_rtx 9463 && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun))) 9464 return "sal{<imodesuffix>}\t%0"; 9465 else 9466 return "sal{<imodesuffix>}\t{%2, %0|%0, %2}"; 9467 } 9468} 9469 [(set (attr "type") 9470 (cond [(and (and (match_test "TARGET_DOUBLE_WITH_ADD") 9471 (match_operand 0 "register_operand" "")) 9472 (match_operand 2 "const1_operand" "")) 9473 (const_string "alu") 9474 ] 9475 (const_string "ishift"))) 9476 (set (attr "length_immediate") 9477 (if_then_else 9478 (ior (eq_attr "type" "alu") 9479 (and (eq_attr "type" "ishift") 9480 (and (match_operand 2 "const1_operand" "") 9481 (ior (match_test "TARGET_SHIFT1") 9482 (match_test "optimize_function_for_size_p (cfun)"))))) 9483 (const_string "0") 9484 (const_string "*"))) 9485 (set_attr "mode" "<MODE>")]) 9486 9487(define_insn "*ashlsi3_cmp_zext" 9488 [(set (reg FLAGS_REG) 9489 (compare 9490 (ashift:SI (match_operand:SI 1 "register_operand" "0") 9491 (match_operand:QI 2 "const_1_to_31_operand" "I")) 9492 (const_int 0))) 9493 (set (match_operand:DI 0 "register_operand" "=r") 9494 (zero_extend:DI (ashift:SI (match_dup 1) (match_dup 2))))] 9495 "TARGET_64BIT 9496 && (optimize_function_for_size_p (cfun) 9497 || !TARGET_PARTIAL_FLAG_REG_STALL 9498 || (operands[2] == const1_rtx 9499 && (TARGET_SHIFT1 9500 || TARGET_DOUBLE_WITH_ADD))) 9501 && ix86_match_ccmode (insn, CCGOCmode) 9502 && ix86_binary_operator_ok (ASHIFT, SImode, operands)" 9503{ 9504 switch (get_attr_type (insn)) 9505 { 9506 case TYPE_ALU: 9507 gcc_assert (operands[2] == const1_rtx); 9508 return "add{l}\t%k0, %k0"; 9509 9510 default: 9511 if (operands[2] == const1_rtx 9512 && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun))) 9513 return "sal{l}\t%k0"; 9514 else 9515 return "sal{l}\t{%2, %k0|%k0, %2}"; 9516 } 9517} 9518 [(set (attr "type") 9519 (cond [(and (match_test "TARGET_DOUBLE_WITH_ADD") 9520 (match_operand 2 "const1_operand" "")) 9521 (const_string "alu") 9522 ] 9523 (const_string "ishift"))) 9524 (set (attr "length_immediate") 9525 (if_then_else 9526 (ior (eq_attr "type" "alu") 9527 (and (eq_attr "type" "ishift") 9528 (and (match_operand 2 "const1_operand" "") 9529 (ior (match_test "TARGET_SHIFT1") 9530 (match_test "optimize_function_for_size_p (cfun)"))))) 9531 (const_string "0") 9532 (const_string "*"))) 9533 (set_attr "mode" "SI")]) 9534 9535(define_insn "*ashl<mode>3_cconly" 9536 [(set (reg FLAGS_REG) 9537 (compare 9538 (ashift:SWI (match_operand:SWI 1 "register_operand" "0") 9539 (match_operand:QI 2 "<shift_immediate_operand>" "<S>")) 9540 (const_int 0))) 9541 (clobber (match_scratch:SWI 0 "=<r>"))] 9542 "(optimize_function_for_size_p (cfun) 9543 || !TARGET_PARTIAL_FLAG_REG_STALL 9544 || (operands[2] == const1_rtx 9545 && (TARGET_SHIFT1 9546 || TARGET_DOUBLE_WITH_ADD))) 9547 && ix86_match_ccmode (insn, CCGOCmode)" 9548{ 9549 switch (get_attr_type (insn)) 9550 { 9551 case TYPE_ALU: 9552 gcc_assert (operands[2] == const1_rtx); 9553 return "add{<imodesuffix>}\t%0, %0"; 9554 9555 default: 9556 if (operands[2] == const1_rtx 9557 && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun))) 9558 return "sal{<imodesuffix>}\t%0"; 9559 else 9560 return "sal{<imodesuffix>}\t{%2, %0|%0, %2}"; 9561 } 9562} 9563 [(set (attr "type") 9564 (cond [(and (and (match_test "TARGET_DOUBLE_WITH_ADD") 9565 (match_operand 0 "register_operand" "")) 9566 (match_operand 2 "const1_operand" "")) 9567 (const_string "alu") 9568 ] 9569 (const_string "ishift"))) 9570 (set (attr "length_immediate") 9571 (if_then_else 9572 (ior (eq_attr "type" "alu") 9573 (and (eq_attr "type" "ishift") 9574 (and (match_operand 2 "const1_operand" "") 9575 (ior (match_test "TARGET_SHIFT1") 9576 (match_test "optimize_function_for_size_p (cfun)"))))) 9577 (const_string "0") 9578 (const_string "*"))) 9579 (set_attr "mode" "<MODE>")]) 9580 9581;; See comment above `ashl<mode>3' about how this works. 9582 9583(define_expand "<shift_insn><mode>3" 9584 [(set (match_operand:SDWIM 0 "<shift_operand>" "") 9585 (any_shiftrt:SDWIM (match_operand:SDWIM 1 "<shift_operand>" "") 9586 (match_operand:QI 2 "nonmemory_operand" "")))] 9587 "" 9588 "ix86_expand_binary_operator (<CODE>, <MODE>mode, operands); DONE;") 9589 9590;; Avoid useless masking of count operand. 9591(define_insn "*<shift_insn><mode>3_mask" 9592 [(set (match_operand:SWI48 0 "nonimmediate_operand" "=rm") 9593 (any_shiftrt:SWI48 9594 (match_operand:SWI48 1 "nonimmediate_operand" "0") 9595 (subreg:QI 9596 (and:SI 9597 (match_operand:SI 2 "register_operand" "c") 9598 (match_operand:SI 3 "const_int_operand" "n")) 0))) 9599 (clobber (reg:CC FLAGS_REG))] 9600 "ix86_binary_operator_ok (<CODE>, <MODE>mode, operands) 9601 && (INTVAL (operands[3]) & (GET_MODE_BITSIZE (<MODE>mode)-1)) 9602 == GET_MODE_BITSIZE (<MODE>mode)-1" 9603{ 9604 return "<shift>{<imodesuffix>}\t{%b2, %0|%0, %b2}"; 9605} 9606 [(set_attr "type" "ishift") 9607 (set_attr "mode" "<MODE>")]) 9608 9609(define_insn_and_split "*<shift_insn><mode>3_doubleword" 9610 [(set (match_operand:DWI 0 "register_operand" "=r") 9611 (any_shiftrt:DWI (match_operand:DWI 1 "register_operand" "0") 9612 (match_operand:QI 2 "nonmemory_operand" "<S>c"))) 9613 (clobber (reg:CC FLAGS_REG))] 9614 "" 9615 "#" 9616 "(optimize && flag_peephole2) ? epilogue_completed : reload_completed" 9617 [(const_int 0)] 9618 "ix86_split_<shift_insn> (operands, NULL_RTX, <MODE>mode); DONE;" 9619 [(set_attr "type" "multi")]) 9620 9621;; By default we don't ask for a scratch register, because when DWImode 9622;; values are manipulated, registers are already at a premium. But if 9623;; we have one handy, we won't turn it away. 9624 9625(define_peephole2 9626 [(match_scratch:DWIH 3 "r") 9627 (parallel [(set (match_operand:<DWI> 0 "register_operand" "") 9628 (any_shiftrt:<DWI> 9629 (match_operand:<DWI> 1 "register_operand" "") 9630 (match_operand:QI 2 "nonmemory_operand" ""))) 9631 (clobber (reg:CC FLAGS_REG))]) 9632 (match_dup 3)] 9633 "TARGET_CMOVE" 9634 [(const_int 0)] 9635 "ix86_split_<shift_insn> (operands, operands[3], <DWI>mode); DONE;") 9636 9637(define_insn "x86_64_shrd" 9638 [(set (match_operand:DI 0 "nonimmediate_operand" "+r*m") 9639 (ior:DI (ashiftrt:DI (match_dup 0) 9640 (match_operand:QI 2 "nonmemory_operand" "Jc")) 9641 (ashift:DI (match_operand:DI 1 "register_operand" "r") 9642 (minus:QI (const_int 64) (match_dup 2))))) 9643 (clobber (reg:CC FLAGS_REG))] 9644 "TARGET_64BIT" 9645 "shrd{q}\t{%s2%1, %0|%0, %1, %2}" 9646 [(set_attr "type" "ishift") 9647 (set_attr "prefix_0f" "1") 9648 (set_attr "mode" "DI") 9649 (set_attr "athlon_decode" "vector") 9650 (set_attr "amdfam10_decode" "vector") 9651 (set_attr "bdver1_decode" "vector")]) 9652 9653(define_insn "x86_shrd" 9654 [(set (match_operand:SI 0 "nonimmediate_operand" "+r*m") 9655 (ior:SI (ashiftrt:SI (match_dup 0) 9656 (match_operand:QI 2 "nonmemory_operand" "Ic")) 9657 (ashift:SI (match_operand:SI 1 "register_operand" "r") 9658 (minus:QI (const_int 32) (match_dup 2))))) 9659 (clobber (reg:CC FLAGS_REG))] 9660 "" 9661 "shrd{l}\t{%s2%1, %0|%0, %1, %2}" 9662 [(set_attr "type" "ishift") 9663 (set_attr "prefix_0f" "1") 9664 (set_attr "mode" "SI") 9665 (set_attr "pent_pair" "np") 9666 (set_attr "athlon_decode" "vector") 9667 (set_attr "amdfam10_decode" "vector") 9668 (set_attr "bdver1_decode" "vector")]) 9669 9670(define_insn "ashrdi3_cvt" 9671 [(set (match_operand:DI 0 "nonimmediate_operand" "=*d,rm") 9672 (ashiftrt:DI (match_operand:DI 1 "nonimmediate_operand" "*a,0") 9673 (match_operand:QI 2 "const_int_operand" ""))) 9674 (clobber (reg:CC FLAGS_REG))] 9675 "TARGET_64BIT && INTVAL (operands[2]) == 63 9676 && (TARGET_USE_CLTD || optimize_function_for_size_p (cfun)) 9677 && ix86_binary_operator_ok (ASHIFTRT, DImode, operands)" 9678 "@ 9679 {cqto|cqo} 9680 sar{q}\t{%2, %0|%0, %2}" 9681 [(set_attr "type" "imovx,ishift") 9682 (set_attr "prefix_0f" "0,*") 9683 (set_attr "length_immediate" "0,*") 9684 (set_attr "modrm" "0,1") 9685 (set_attr "mode" "DI")]) 9686 9687(define_insn "ashrsi3_cvt" 9688 [(set (match_operand:SI 0 "nonimmediate_operand" "=*d,rm") 9689 (ashiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "*a,0") 9690 (match_operand:QI 2 "const_int_operand" ""))) 9691 (clobber (reg:CC FLAGS_REG))] 9692 "INTVAL (operands[2]) == 31 9693 && (TARGET_USE_CLTD || optimize_function_for_size_p (cfun)) 9694 && ix86_binary_operator_ok (ASHIFTRT, SImode, operands)" 9695 "@ 9696 {cltd|cdq} 9697 sar{l}\t{%2, %0|%0, %2}" 9698 [(set_attr "type" "imovx,ishift") 9699 (set_attr "prefix_0f" "0,*") 9700 (set_attr "length_immediate" "0,*") 9701 (set_attr "modrm" "0,1") 9702 (set_attr "mode" "SI")]) 9703 9704(define_insn "*ashrsi3_cvt_zext" 9705 [(set (match_operand:DI 0 "register_operand" "=*d,r") 9706 (zero_extend:DI 9707 (ashiftrt:SI (match_operand:SI 1 "register_operand" "*a,0") 9708 (match_operand:QI 2 "const_int_operand" "")))) 9709 (clobber (reg:CC FLAGS_REG))] 9710 "TARGET_64BIT && INTVAL (operands[2]) == 31 9711 && (TARGET_USE_CLTD || optimize_function_for_size_p (cfun)) 9712 && ix86_binary_operator_ok (ASHIFTRT, SImode, operands)" 9713 "@ 9714 {cltd|cdq} 9715 sar{l}\t{%2, %k0|%k0, %2}" 9716 [(set_attr "type" "imovx,ishift") 9717 (set_attr "prefix_0f" "0,*") 9718 (set_attr "length_immediate" "0,*") 9719 (set_attr "modrm" "0,1") 9720 (set_attr "mode" "SI")]) 9721 9722(define_expand "x86_shift<mode>_adj_3" 9723 [(use (match_operand:SWI48 0 "register_operand" "")) 9724 (use (match_operand:SWI48 1 "register_operand" "")) 9725 (use (match_operand:QI 2 "register_operand" ""))] 9726 "" 9727{ 9728 rtx label = gen_label_rtx (); 9729 rtx tmp; 9730 9731 emit_insn (gen_testqi_ccz_1 (operands[2], 9732 GEN_INT (GET_MODE_BITSIZE (<MODE>mode)))); 9733 9734 tmp = gen_rtx_REG (CCZmode, FLAGS_REG); 9735 tmp = gen_rtx_EQ (VOIDmode, tmp, const0_rtx); 9736 tmp = gen_rtx_IF_THEN_ELSE (VOIDmode, tmp, 9737 gen_rtx_LABEL_REF (VOIDmode, label), 9738 pc_rtx); 9739 tmp = emit_jump_insn (gen_rtx_SET (VOIDmode, pc_rtx, tmp)); 9740 JUMP_LABEL (tmp) = label; 9741 9742 emit_move_insn (operands[0], operands[1]); 9743 emit_insn (gen_ashr<mode>3_cvt (operands[1], operands[1], 9744 GEN_INT (GET_MODE_BITSIZE (<MODE>mode)-1))); 9745 emit_label (label); 9746 LABEL_NUSES (label) = 1; 9747 9748 DONE; 9749}) 9750 9751(define_insn "*bmi2_<shift_insn><mode>3_1" 9752 [(set (match_operand:SWI48 0 "register_operand" "=r") 9753 (any_shiftrt:SWI48 (match_operand:SWI48 1 "nonimmediate_operand" "rm") 9754 (match_operand:SWI48 2 "register_operand" "r")))] 9755 "TARGET_BMI2" 9756 "<shift>x\t{%2, %1, %0|%0, %1, %2}" 9757 [(set_attr "type" "ishiftx") 9758 (set_attr "mode" "<MODE>")]) 9759 9760(define_insn "*<shift_insn><mode>3_1" 9761 [(set (match_operand:SWI48 0 "nonimmediate_operand" "=rm,r") 9762 (any_shiftrt:SWI48 9763 (match_operand:SWI48 1 "nonimmediate_operand" "0,rm") 9764 (match_operand:QI 2 "nonmemory_operand" "c<S>,r"))) 9765 (clobber (reg:CC FLAGS_REG))] 9766 "ix86_binary_operator_ok (<CODE>, <MODE>mode, operands)" 9767{ 9768 switch (get_attr_type (insn)) 9769 { 9770 case TYPE_ISHIFTX: 9771 return "#"; 9772 9773 default: 9774 if (operands[2] == const1_rtx 9775 && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun))) 9776 return "<shift>{<imodesuffix>}\t%0"; 9777 else 9778 return "<shift>{<imodesuffix>}\t{%2, %0|%0, %2}"; 9779 } 9780} 9781 [(set_attr "isa" "*,bmi2") 9782 (set_attr "type" "ishift,ishiftx") 9783 (set (attr "length_immediate") 9784 (if_then_else 9785 (and (match_operand 2 "const1_operand" "") 9786 (ior (match_test "TARGET_SHIFT1") 9787 (match_test "optimize_function_for_size_p (cfun)"))) 9788 (const_string "0") 9789 (const_string "*"))) 9790 (set_attr "mode" "<MODE>")]) 9791 9792;; Convert shift to the shiftx pattern to avoid flags dependency. 9793(define_split 9794 [(set (match_operand:SWI48 0 "register_operand" "") 9795 (any_shiftrt:SWI48 (match_operand:SWI48 1 "nonimmediate_operand" "") 9796 (match_operand:QI 2 "register_operand" ""))) 9797 (clobber (reg:CC FLAGS_REG))] 9798 "TARGET_BMI2 && reload_completed" 9799 [(set (match_dup 0) 9800 (any_shiftrt:SWI48 (match_dup 1) (match_dup 2)))] 9801 "operands[2] = gen_lowpart (<MODE>mode, operands[2]);") 9802 9803(define_insn "*bmi2_<shift_insn>si3_1_zext" 9804 [(set (match_operand:DI 0 "register_operand" "=r") 9805 (zero_extend:DI 9806 (any_shiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "rm") 9807 (match_operand:SI 2 "register_operand" "r"))))] 9808 "TARGET_64BIT && TARGET_BMI2" 9809 "<shift>x\t{%2, %1, %k0|%k0, %1, %2}" 9810 [(set_attr "type" "ishiftx") 9811 (set_attr "mode" "SI")]) 9812 9813(define_insn "*<shift_insn>si3_1_zext" 9814 [(set (match_operand:DI 0 "register_operand" "=r,r") 9815 (zero_extend:DI 9816 (any_shiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "0,rm") 9817 (match_operand:QI 2 "nonmemory_operand" "cI,r")))) 9818 (clobber (reg:CC FLAGS_REG))] 9819 "TARGET_64BIT && ix86_binary_operator_ok (<CODE>, SImode, operands)" 9820{ 9821 switch (get_attr_type (insn)) 9822 { 9823 case TYPE_ISHIFTX: 9824 return "#"; 9825 9826 default: 9827 if (operands[2] == const1_rtx 9828 && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun))) 9829 return "<shift>{l}\t%k0"; 9830 else 9831 return "<shift>{l}\t{%2, %k0|%k0, %2}"; 9832 } 9833} 9834 [(set_attr "isa" "*,bmi2") 9835 (set_attr "type" "ishift,ishiftx") 9836 (set (attr "length_immediate") 9837 (if_then_else 9838 (and (match_operand 2 "const1_operand" "") 9839 (ior (match_test "TARGET_SHIFT1") 9840 (match_test "optimize_function_for_size_p (cfun)"))) 9841 (const_string "0") 9842 (const_string "*"))) 9843 (set_attr "mode" "SI")]) 9844 9845;; Convert shift to the shiftx pattern to avoid flags dependency. 9846(define_split 9847 [(set (match_operand:DI 0 "register_operand" "") 9848 (zero_extend:DI 9849 (any_shiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "") 9850 (match_operand:QI 2 "register_operand" "")))) 9851 (clobber (reg:CC FLAGS_REG))] 9852 "TARGET_64BIT && TARGET_BMI2 && reload_completed" 9853 [(set (match_dup 0) 9854 (zero_extend:DI (any_shiftrt:SI (match_dup 1) (match_dup 2))))] 9855 "operands[2] = gen_lowpart (SImode, operands[2]);") 9856 9857(define_insn "*<shift_insn><mode>3_1" 9858 [(set (match_operand:SWI12 0 "nonimmediate_operand" "=<r>m") 9859 (any_shiftrt:SWI12 9860 (match_operand:SWI12 1 "nonimmediate_operand" "0") 9861 (match_operand:QI 2 "nonmemory_operand" "c<S>"))) 9862 (clobber (reg:CC FLAGS_REG))] 9863 "ix86_binary_operator_ok (<CODE>, <MODE>mode, operands)" 9864{ 9865 if (operands[2] == const1_rtx 9866 && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun))) 9867 return "<shift>{<imodesuffix>}\t%0"; 9868 else 9869 return "<shift>{<imodesuffix>}\t{%2, %0|%0, %2}"; 9870} 9871 [(set_attr "type" "ishift") 9872 (set (attr "length_immediate") 9873 (if_then_else 9874 (and (match_operand 2 "const1_operand" "") 9875 (ior (match_test "TARGET_SHIFT1") 9876 (match_test "optimize_function_for_size_p (cfun)"))) 9877 (const_string "0") 9878 (const_string "*"))) 9879 (set_attr "mode" "<MODE>")]) 9880 9881(define_insn "*<shift_insn>qi3_1_slp" 9882 [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm")) 9883 (any_shiftrt:QI (match_dup 0) 9884 (match_operand:QI 1 "nonmemory_operand" "cI"))) 9885 (clobber (reg:CC FLAGS_REG))] 9886 "(optimize_function_for_size_p (cfun) 9887 || !TARGET_PARTIAL_REG_STALL 9888 || (operands[1] == const1_rtx 9889 && TARGET_SHIFT1))" 9890{ 9891 if (operands[1] == const1_rtx 9892 && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun))) 9893 return "<shift>{b}\t%0"; 9894 else 9895 return "<shift>{b}\t{%1, %0|%0, %1}"; 9896} 9897 [(set_attr "type" "ishift1") 9898 (set (attr "length_immediate") 9899 (if_then_else 9900 (and (match_operand 1 "const1_operand" "") 9901 (ior (match_test "TARGET_SHIFT1") 9902 (match_test "optimize_function_for_size_p (cfun)"))) 9903 (const_string "0") 9904 (const_string "*"))) 9905 (set_attr "mode" "QI")]) 9906 9907;; This pattern can't accept a variable shift count, since shifts by 9908;; zero don't affect the flags. We assume that shifts by constant 9909;; zero are optimized away. 9910(define_insn "*<shift_insn><mode>3_cmp" 9911 [(set (reg FLAGS_REG) 9912 (compare 9913 (any_shiftrt:SWI 9914 (match_operand:SWI 1 "nonimmediate_operand" "0") 9915 (match_operand:QI 2 "<shift_immediate_operand>" "<S>")) 9916 (const_int 0))) 9917 (set (match_operand:SWI 0 "nonimmediate_operand" "=<r>m") 9918 (any_shiftrt:SWI (match_dup 1) (match_dup 2)))] 9919 "(optimize_function_for_size_p (cfun) 9920 || !TARGET_PARTIAL_FLAG_REG_STALL 9921 || (operands[2] == const1_rtx 9922 && TARGET_SHIFT1)) 9923 && ix86_match_ccmode (insn, CCGOCmode) 9924 && ix86_binary_operator_ok (<CODE>, <MODE>mode, operands)" 9925{ 9926 if (operands[2] == const1_rtx 9927 && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun))) 9928 return "<shift>{<imodesuffix>}\t%0"; 9929 else 9930 return "<shift>{<imodesuffix>}\t{%2, %0|%0, %2}"; 9931} 9932 [(set_attr "type" "ishift") 9933 (set (attr "length_immediate") 9934 (if_then_else 9935 (and (match_operand 2 "const1_operand" "") 9936 (ior (match_test "TARGET_SHIFT1") 9937 (match_test "optimize_function_for_size_p (cfun)"))) 9938 (const_string "0") 9939 (const_string "*"))) 9940 (set_attr "mode" "<MODE>")]) 9941 9942(define_insn "*<shift_insn>si3_cmp_zext" 9943 [(set (reg FLAGS_REG) 9944 (compare 9945 (any_shiftrt:SI (match_operand:SI 1 "register_operand" "0") 9946 (match_operand:QI 2 "const_1_to_31_operand" "I")) 9947 (const_int 0))) 9948 (set (match_operand:DI 0 "register_operand" "=r") 9949 (zero_extend:DI (any_shiftrt:SI (match_dup 1) (match_dup 2))))] 9950 "TARGET_64BIT 9951 && (optimize_function_for_size_p (cfun) 9952 || !TARGET_PARTIAL_FLAG_REG_STALL 9953 || (operands[2] == const1_rtx 9954 && TARGET_SHIFT1)) 9955 && ix86_match_ccmode (insn, CCGOCmode) 9956 && ix86_binary_operator_ok (<CODE>, SImode, operands)" 9957{ 9958 if (operands[2] == const1_rtx 9959 && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun))) 9960 return "<shift>{l}\t%k0"; 9961 else 9962 return "<shift>{l}\t{%2, %k0|%k0, %2}"; 9963} 9964 [(set_attr "type" "ishift") 9965 (set (attr "length_immediate") 9966 (if_then_else 9967 (and (match_operand 2 "const1_operand" "") 9968 (ior (match_test "TARGET_SHIFT1") 9969 (match_test "optimize_function_for_size_p (cfun)"))) 9970 (const_string "0") 9971 (const_string "*"))) 9972 (set_attr "mode" "SI")]) 9973 9974(define_insn "*<shift_insn><mode>3_cconly" 9975 [(set (reg FLAGS_REG) 9976 (compare 9977 (any_shiftrt:SWI 9978 (match_operand:SWI 1 "register_operand" "0") 9979 (match_operand:QI 2 "<shift_immediate_operand>" "<S>")) 9980 (const_int 0))) 9981 (clobber (match_scratch:SWI 0 "=<r>"))] 9982 "(optimize_function_for_size_p (cfun) 9983 || !TARGET_PARTIAL_FLAG_REG_STALL 9984 || (operands[2] == const1_rtx 9985 && TARGET_SHIFT1)) 9986 && ix86_match_ccmode (insn, CCGOCmode)" 9987{ 9988 if (operands[2] == const1_rtx 9989 && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun))) 9990 return "<shift>{<imodesuffix>}\t%0"; 9991 else 9992 return "<shift>{<imodesuffix>}\t{%2, %0|%0, %2}"; 9993} 9994 [(set_attr "type" "ishift") 9995 (set (attr "length_immediate") 9996 (if_then_else 9997 (and (match_operand 2 "const1_operand" "") 9998 (ior (match_test "TARGET_SHIFT1") 9999 (match_test "optimize_function_for_size_p (cfun)"))) 10000 (const_string "0") 10001 (const_string "*"))) 10002 (set_attr "mode" "<MODE>")]) 10003 10004;; Rotate instructions 10005 10006(define_expand "<rotate_insn>ti3" 10007 [(set (match_operand:TI 0 "register_operand" "") 10008 (any_rotate:TI (match_operand:TI 1 "register_operand" "") 10009 (match_operand:QI 2 "nonmemory_operand" "")))] 10010 "TARGET_64BIT" 10011{ 10012 if (const_1_to_63_operand (operands[2], VOIDmode)) 10013 emit_insn (gen_ix86_<rotate_insn>ti3_doubleword 10014 (operands[0], operands[1], operands[2])); 10015 else 10016 FAIL; 10017 10018 DONE; 10019}) 10020 10021(define_expand "<rotate_insn>di3" 10022 [(set (match_operand:DI 0 "shiftdi_operand" "") 10023 (any_rotate:DI (match_operand:DI 1 "shiftdi_operand" "") 10024 (match_operand:QI 2 "nonmemory_operand" "")))] 10025 "" 10026{ 10027 if (TARGET_64BIT) 10028 ix86_expand_binary_operator (<CODE>, DImode, operands); 10029 else if (const_1_to_31_operand (operands[2], VOIDmode)) 10030 emit_insn (gen_ix86_<rotate_insn>di3_doubleword 10031 (operands[0], operands[1], operands[2])); 10032 else 10033 FAIL; 10034 10035 DONE; 10036}) 10037 10038(define_expand "<rotate_insn><mode>3" 10039 [(set (match_operand:SWIM124 0 "nonimmediate_operand" "") 10040 (any_rotate:SWIM124 (match_operand:SWIM124 1 "nonimmediate_operand" "") 10041 (match_operand:QI 2 "nonmemory_operand" "")))] 10042 "" 10043 "ix86_expand_binary_operator (<CODE>, <MODE>mode, operands); DONE;") 10044 10045;; Avoid useless masking of count operand. 10046(define_insn "*<rotate_insn><mode>3_mask" 10047 [(set (match_operand:SWI48 0 "nonimmediate_operand" "=rm") 10048 (any_rotate:SWI48 10049 (match_operand:SWI48 1 "nonimmediate_operand" "0") 10050 (subreg:QI 10051 (and:SI 10052 (match_operand:SI 2 "register_operand" "c") 10053 (match_operand:SI 3 "const_int_operand" "n")) 0))) 10054 (clobber (reg:CC FLAGS_REG))] 10055 "ix86_binary_operator_ok (<CODE>, <MODE>mode, operands) 10056 && (INTVAL (operands[3]) & (GET_MODE_BITSIZE (<MODE>mode)-1)) 10057 == GET_MODE_BITSIZE (<MODE>mode)-1" 10058{ 10059 return "<rotate>{<imodesuffix>}\t{%b2, %0|%0, %b2}"; 10060} 10061 [(set_attr "type" "rotate") 10062 (set_attr "mode" "<MODE>")]) 10063 10064;; Implement rotation using two double-precision 10065;; shift instructions and a scratch register. 10066 10067(define_insn_and_split "ix86_rotl<dwi>3_doubleword" 10068 [(set (match_operand:<DWI> 0 "register_operand" "=r") 10069 (rotate:<DWI> (match_operand:<DWI> 1 "register_operand" "0") 10070 (match_operand:QI 2 "<shift_immediate_operand>" "<S>"))) 10071 (clobber (reg:CC FLAGS_REG)) 10072 (clobber (match_scratch:DWIH 3 "=&r"))] 10073 "" 10074 "#" 10075 "reload_completed" 10076 [(set (match_dup 3) (match_dup 4)) 10077 (parallel 10078 [(set (match_dup 4) 10079 (ior:DWIH (ashift:DWIH (match_dup 4) (match_dup 2)) 10080 (lshiftrt:DWIH (match_dup 5) 10081 (minus:QI (match_dup 6) (match_dup 2))))) 10082 (clobber (reg:CC FLAGS_REG))]) 10083 (parallel 10084 [(set (match_dup 5) 10085 (ior:DWIH (ashift:DWIH (match_dup 5) (match_dup 2)) 10086 (lshiftrt:DWIH (match_dup 3) 10087 (minus:QI (match_dup 6) (match_dup 2))))) 10088 (clobber (reg:CC FLAGS_REG))])] 10089{ 10090 operands[6] = GEN_INT (GET_MODE_BITSIZE (<MODE>mode)); 10091 10092 split_double_mode (<DWI>mode, &operands[0], 1, &operands[4], &operands[5]); 10093}) 10094 10095(define_insn_and_split "ix86_rotr<dwi>3_doubleword" 10096 [(set (match_operand:<DWI> 0 "register_operand" "=r") 10097 (rotatert:<DWI> (match_operand:<DWI> 1 "register_operand" "0") 10098 (match_operand:QI 2 "<shift_immediate_operand>" "<S>"))) 10099 (clobber (reg:CC FLAGS_REG)) 10100 (clobber (match_scratch:DWIH 3 "=&r"))] 10101 "" 10102 "#" 10103 "reload_completed" 10104 [(set (match_dup 3) (match_dup 4)) 10105 (parallel 10106 [(set (match_dup 4) 10107 (ior:DWIH (ashiftrt:DWIH (match_dup 4) (match_dup 2)) 10108 (ashift:DWIH (match_dup 5) 10109 (minus:QI (match_dup 6) (match_dup 2))))) 10110 (clobber (reg:CC FLAGS_REG))]) 10111 (parallel 10112 [(set (match_dup 5) 10113 (ior:DWIH (ashiftrt:DWIH (match_dup 5) (match_dup 2)) 10114 (ashift:DWIH (match_dup 3) 10115 (minus:QI (match_dup 6) (match_dup 2))))) 10116 (clobber (reg:CC FLAGS_REG))])] 10117{ 10118 operands[6] = GEN_INT (GET_MODE_BITSIZE (<MODE>mode)); 10119 10120 split_double_mode (<DWI>mode, &operands[0], 1, &operands[4], &operands[5]); 10121}) 10122 10123(define_insn "*bmi2_rorx<mode>3_1" 10124 [(set (match_operand:SWI48 0 "register_operand" "=r") 10125 (rotatert:SWI48 (match_operand:SWI48 1 "nonimmediate_operand" "rm") 10126 (match_operand:QI 2 "immediate_operand" "<S>")))] 10127 "TARGET_BMI2" 10128 "rorx\t{%2, %1, %0|%0, %1, %2}" 10129 [(set_attr "type" "rotatex") 10130 (set_attr "mode" "<MODE>")]) 10131 10132(define_insn "*<rotate_insn><mode>3_1" 10133 [(set (match_operand:SWI48 0 "nonimmediate_operand" "=rm,r") 10134 (any_rotate:SWI48 10135 (match_operand:SWI48 1 "nonimmediate_operand" "0,rm") 10136 (match_operand:QI 2 "nonmemory_operand" "c<S>,<S>"))) 10137 (clobber (reg:CC FLAGS_REG))] 10138 "ix86_binary_operator_ok (<CODE>, <MODE>mode, operands)" 10139{ 10140 switch (get_attr_type (insn)) 10141 { 10142 case TYPE_ROTATEX: 10143 return "#"; 10144 10145 default: 10146 if (operands[2] == const1_rtx 10147 && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun))) 10148 return "<rotate>{<imodesuffix>}\t%0"; 10149 else 10150 return "<rotate>{<imodesuffix>}\t{%2, %0|%0, %2}"; 10151 } 10152} 10153 [(set_attr "isa" "*,bmi2") 10154 (set_attr "type" "rotate,rotatex") 10155 (set (attr "length_immediate") 10156 (if_then_else 10157 (and (eq_attr "type" "rotate") 10158 (and (match_operand 2 "const1_operand" "") 10159 (ior (match_test "TARGET_SHIFT1") 10160 (match_test "optimize_function_for_size_p (cfun)")))) 10161 (const_string "0") 10162 (const_string "*"))) 10163 (set_attr "mode" "<MODE>")]) 10164 10165;; Convert rotate to the rotatex pattern to avoid flags dependency. 10166(define_split 10167 [(set (match_operand:SWI48 0 "register_operand" "") 10168 (rotate:SWI48 (match_operand:SWI48 1 "nonimmediate_operand" "") 10169 (match_operand:QI 2 "immediate_operand" ""))) 10170 (clobber (reg:CC FLAGS_REG))] 10171 "TARGET_BMI2 && reload_completed" 10172 [(set (match_dup 0) 10173 (rotatert:SWI48 (match_dup 1) (match_dup 2)))] 10174{ 10175 operands[2] 10176 = GEN_INT (GET_MODE_BITSIZE (<MODE>mode) - INTVAL (operands[2])); 10177}) 10178 10179(define_split 10180 [(set (match_operand:SWI48 0 "register_operand" "") 10181 (rotatert:SWI48 (match_operand:SWI48 1 "nonimmediate_operand" "") 10182 (match_operand:QI 2 "immediate_operand" ""))) 10183 (clobber (reg:CC FLAGS_REG))] 10184 "TARGET_BMI2 && reload_completed" 10185 [(set (match_dup 0) 10186 (rotatert:SWI48 (match_dup 1) (match_dup 2)))]) 10187 10188(define_insn "*bmi2_rorxsi3_1_zext" 10189 [(set (match_operand:DI 0 "register_operand" "=r") 10190 (zero_extend:DI 10191 (rotatert:SI (match_operand:SI 1 "nonimmediate_operand" "rm") 10192 (match_operand:QI 2 "immediate_operand" "I"))))] 10193 "TARGET_64BIT && TARGET_BMI2" 10194 "rorx\t{%2, %1, %k0|%k0, %1, %2}" 10195 [(set_attr "type" "rotatex") 10196 (set_attr "mode" "SI")]) 10197 10198(define_insn "*<rotate_insn>si3_1_zext" 10199 [(set (match_operand:DI 0 "register_operand" "=r,r") 10200 (zero_extend:DI 10201 (any_rotate:SI (match_operand:SI 1 "nonimmediate_operand" "0,rm") 10202 (match_operand:QI 2 "nonmemory_operand" "cI,I")))) 10203 (clobber (reg:CC FLAGS_REG))] 10204 "TARGET_64BIT && ix86_binary_operator_ok (<CODE>, SImode, operands)" 10205{ 10206 switch (get_attr_type (insn)) 10207 { 10208 case TYPE_ROTATEX: 10209 return "#"; 10210 10211 default: 10212 if (operands[2] == const1_rtx 10213 && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun))) 10214 return "<rotate>{l}\t%k0"; 10215 else 10216 return "<rotate>{l}\t{%2, %k0|%k0, %2}"; 10217 } 10218} 10219 [(set_attr "isa" "*,bmi2") 10220 (set_attr "type" "rotate,rotatex") 10221 (set (attr "length_immediate") 10222 (if_then_else 10223 (and (eq_attr "type" "rotate") 10224 (and (match_operand 2 "const1_operand" "") 10225 (ior (match_test "TARGET_SHIFT1") 10226 (match_test "optimize_function_for_size_p (cfun)")))) 10227 (const_string "0") 10228 (const_string "*"))) 10229 (set_attr "mode" "SI")]) 10230 10231;; Convert rotate to the rotatex pattern to avoid flags dependency. 10232(define_split 10233 [(set (match_operand:DI 0 "register_operand" "") 10234 (zero_extend:DI 10235 (rotate:SI (match_operand:SI 1 "nonimmediate_operand" "") 10236 (match_operand:QI 2 "immediate_operand" "")))) 10237 (clobber (reg:CC FLAGS_REG))] 10238 "TARGET_64BIT && TARGET_BMI2 && reload_completed" 10239 [(set (match_dup 0) 10240 (zero_extend:DI (rotatert:SI (match_dup 1) (match_dup 2))))] 10241{ 10242 operands[2] 10243 = GEN_INT (GET_MODE_BITSIZE (SImode) - INTVAL (operands[2])); 10244}) 10245 10246(define_split 10247 [(set (match_operand:DI 0 "register_operand" "") 10248 (zero_extend:DI 10249 (rotatert:SI (match_operand:SI 1 "nonimmediate_operand" "") 10250 (match_operand:QI 2 "immediate_operand" "")))) 10251 (clobber (reg:CC FLAGS_REG))] 10252 "TARGET_64BIT && TARGET_BMI2 && reload_completed" 10253 [(set (match_dup 0) 10254 (zero_extend:DI (rotatert:SI (match_dup 1) (match_dup 2))))]) 10255 10256(define_insn "*<rotate_insn><mode>3_1" 10257 [(set (match_operand:SWI12 0 "nonimmediate_operand" "=<r>m") 10258 (any_rotate:SWI12 (match_operand:SWI12 1 "nonimmediate_operand" "0") 10259 (match_operand:QI 2 "nonmemory_operand" "c<S>"))) 10260 (clobber (reg:CC FLAGS_REG))] 10261 "ix86_binary_operator_ok (<CODE>, <MODE>mode, operands)" 10262{ 10263 if (operands[2] == const1_rtx 10264 && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun))) 10265 return "<rotate>{<imodesuffix>}\t%0"; 10266 else 10267 return "<rotate>{<imodesuffix>}\t{%2, %0|%0, %2}"; 10268} 10269 [(set_attr "type" "rotate") 10270 (set (attr "length_immediate") 10271 (if_then_else 10272 (and (match_operand 2 "const1_operand" "") 10273 (ior (match_test "TARGET_SHIFT1") 10274 (match_test "optimize_function_for_size_p (cfun)"))) 10275 (const_string "0") 10276 (const_string "*"))) 10277 (set_attr "mode" "<MODE>")]) 10278 10279(define_insn "*<rotate_insn>qi3_1_slp" 10280 [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm")) 10281 (any_rotate:QI (match_dup 0) 10282 (match_operand:QI 1 "nonmemory_operand" "cI"))) 10283 (clobber (reg:CC FLAGS_REG))] 10284 "(optimize_function_for_size_p (cfun) 10285 || !TARGET_PARTIAL_REG_STALL 10286 || (operands[1] == const1_rtx 10287 && TARGET_SHIFT1))" 10288{ 10289 if (operands[1] == const1_rtx 10290 && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun))) 10291 return "<rotate>{b}\t%0"; 10292 else 10293 return "<rotate>{b}\t{%1, %0|%0, %1}"; 10294} 10295 [(set_attr "type" "rotate1") 10296 (set (attr "length_immediate") 10297 (if_then_else 10298 (and (match_operand 1 "const1_operand" "") 10299 (ior (match_test "TARGET_SHIFT1") 10300 (match_test "optimize_function_for_size_p (cfun)"))) 10301 (const_string "0") 10302 (const_string "*"))) 10303 (set_attr "mode" "QI")]) 10304 10305(define_split 10306 [(set (match_operand:HI 0 "register_operand" "") 10307 (any_rotate:HI (match_dup 0) (const_int 8))) 10308 (clobber (reg:CC FLAGS_REG))] 10309 "reload_completed 10310 && (TARGET_USE_XCHGB || optimize_function_for_size_p (cfun))" 10311 [(parallel [(set (strict_low_part (match_dup 0)) 10312 (bswap:HI (match_dup 0))) 10313 (clobber (reg:CC FLAGS_REG))])]) 10314 10315;; Bit set / bit test instructions 10316 10317(define_expand "extv" 10318 [(set (match_operand:SI 0 "register_operand" "") 10319 (sign_extract:SI (match_operand:SI 1 "register_operand" "") 10320 (match_operand:SI 2 "const8_operand" "") 10321 (match_operand:SI 3 "const8_operand" "")))] 10322 "" 10323{ 10324 /* Handle extractions from %ah et al. */ 10325 if (INTVAL (operands[2]) != 8 || INTVAL (operands[3]) != 8) 10326 FAIL; 10327 10328 /* From mips.md: extract_bit_field doesn't verify that our source 10329 matches the predicate, so check it again here. */ 10330 if (! ext_register_operand (operands[1], VOIDmode)) 10331 FAIL; 10332}) 10333 10334(define_expand "extzv" 10335 [(set (match_operand:SI 0 "register_operand" "") 10336 (zero_extract:SI (match_operand 1 "ext_register_operand" "") 10337 (match_operand:SI 2 "const8_operand" "") 10338 (match_operand:SI 3 "const8_operand" "")))] 10339 "" 10340{ 10341 /* Handle extractions from %ah et al. */ 10342 if (INTVAL (operands[2]) != 8 || INTVAL (operands[3]) != 8) 10343 FAIL; 10344 10345 /* From mips.md: extract_bit_field doesn't verify that our source 10346 matches the predicate, so check it again here. */ 10347 if (! ext_register_operand (operands[1], VOIDmode)) 10348 FAIL; 10349}) 10350 10351(define_expand "insv" 10352 [(set (zero_extract (match_operand 0 "register_operand" "") 10353 (match_operand 1 "const_int_operand" "") 10354 (match_operand 2 "const_int_operand" "")) 10355 (match_operand 3 "register_operand" ""))] 10356 "" 10357{ 10358 rtx (*gen_mov_insv_1) (rtx, rtx); 10359 10360 if (ix86_expand_pinsr (operands)) 10361 DONE; 10362 10363 /* Handle insertions to %ah et al. */ 10364 if (INTVAL (operands[1]) != 8 || INTVAL (operands[2]) != 8) 10365 FAIL; 10366 10367 /* From mips.md: insert_bit_field doesn't verify that our source 10368 matches the predicate, so check it again here. */ 10369 if (! ext_register_operand (operands[0], VOIDmode)) 10370 FAIL; 10371 10372 gen_mov_insv_1 = (TARGET_64BIT 10373 ? gen_movdi_insv_1 : gen_movsi_insv_1); 10374 10375 emit_insn (gen_mov_insv_1 (operands[0], operands[3])); 10376 DONE; 10377}) 10378 10379;; %%% bts, btr, btc, bt. 10380;; In general these instructions are *slow* when applied to memory, 10381;; since they enforce atomic operation. When applied to registers, 10382;; it depends on the cpu implementation. They're never faster than 10383;; the corresponding and/ior/xor operations, so with 32-bit there's 10384;; no point. But in 64-bit, we can't hold the relevant immediates 10385;; within the instruction itself, so operating on bits in the high 10386;; 32-bits of a register becomes easier. 10387;; 10388;; These are slow on Nocona, but fast on Athlon64. We do require the use 10389;; of btrq and btcq for corner cases of post-reload expansion of absdf and 10390;; negdf respectively, so they can never be disabled entirely. 10391 10392(define_insn "*btsq" 10393 [(set (zero_extract:DI (match_operand:DI 0 "register_operand" "+r") 10394 (const_int 1) 10395 (match_operand:DI 1 "const_0_to_63_operand" "")) 10396 (const_int 1)) 10397 (clobber (reg:CC FLAGS_REG))] 10398 "TARGET_64BIT && (TARGET_USE_BT || reload_completed)" 10399 "bts{q}\t{%1, %0|%0, %1}" 10400 [(set_attr "type" "alu1") 10401 (set_attr "prefix_0f" "1") 10402 (set_attr "mode" "DI")]) 10403 10404(define_insn "*btrq" 10405 [(set (zero_extract:DI (match_operand:DI 0 "register_operand" "+r") 10406 (const_int 1) 10407 (match_operand:DI 1 "const_0_to_63_operand" "")) 10408 (const_int 0)) 10409 (clobber (reg:CC FLAGS_REG))] 10410 "TARGET_64BIT && (TARGET_USE_BT || reload_completed)" 10411 "btr{q}\t{%1, %0|%0, %1}" 10412 [(set_attr "type" "alu1") 10413 (set_attr "prefix_0f" "1") 10414 (set_attr "mode" "DI")]) 10415 10416(define_insn "*btcq" 10417 [(set (zero_extract:DI (match_operand:DI 0 "register_operand" "+r") 10418 (const_int 1) 10419 (match_operand:DI 1 "const_0_to_63_operand" "")) 10420 (not:DI (zero_extract:DI (match_dup 0) (const_int 1) (match_dup 1)))) 10421 (clobber (reg:CC FLAGS_REG))] 10422 "TARGET_64BIT && (TARGET_USE_BT || reload_completed)" 10423 "btc{q}\t{%1, %0|%0, %1}" 10424 [(set_attr "type" "alu1") 10425 (set_attr "prefix_0f" "1") 10426 (set_attr "mode" "DI")]) 10427 10428;; Allow Nocona to avoid these instructions if a register is available. 10429 10430(define_peephole2 10431 [(match_scratch:DI 2 "r") 10432 (parallel [(set (zero_extract:DI 10433 (match_operand:DI 0 "register_operand" "") 10434 (const_int 1) 10435 (match_operand:DI 1 "const_0_to_63_operand" "")) 10436 (const_int 1)) 10437 (clobber (reg:CC FLAGS_REG))])] 10438 "TARGET_64BIT && !TARGET_USE_BT" 10439 [(const_int 0)] 10440{ 10441 HOST_WIDE_INT i = INTVAL (operands[1]), hi, lo; 10442 rtx op1; 10443 10444 if (HOST_BITS_PER_WIDE_INT >= 64) 10445 lo = (HOST_WIDE_INT)1 << i, hi = 0; 10446 else if (i < HOST_BITS_PER_WIDE_INT) 10447 lo = (HOST_WIDE_INT)1 << i, hi = 0; 10448 else 10449 lo = 0, hi = (HOST_WIDE_INT)1 << (i - HOST_BITS_PER_WIDE_INT); 10450 10451 op1 = immed_double_const (lo, hi, DImode); 10452 if (i >= 31) 10453 { 10454 emit_move_insn (operands[2], op1); 10455 op1 = operands[2]; 10456 } 10457 10458 emit_insn (gen_iordi3 (operands[0], operands[0], op1)); 10459 DONE; 10460}) 10461 10462(define_peephole2 10463 [(match_scratch:DI 2 "r") 10464 (parallel [(set (zero_extract:DI 10465 (match_operand:DI 0 "register_operand" "") 10466 (const_int 1) 10467 (match_operand:DI 1 "const_0_to_63_operand" "")) 10468 (const_int 0)) 10469 (clobber (reg:CC FLAGS_REG))])] 10470 "TARGET_64BIT && !TARGET_USE_BT" 10471 [(const_int 0)] 10472{ 10473 HOST_WIDE_INT i = INTVAL (operands[1]), hi, lo; 10474 rtx op1; 10475 10476 if (HOST_BITS_PER_WIDE_INT >= 64) 10477 lo = (HOST_WIDE_INT)1 << i, hi = 0; 10478 else if (i < HOST_BITS_PER_WIDE_INT) 10479 lo = (HOST_WIDE_INT)1 << i, hi = 0; 10480 else 10481 lo = 0, hi = (HOST_WIDE_INT)1 << (i - HOST_BITS_PER_WIDE_INT); 10482 10483 op1 = immed_double_const (~lo, ~hi, DImode); 10484 if (i >= 32) 10485 { 10486 emit_move_insn (operands[2], op1); 10487 op1 = operands[2]; 10488 } 10489 10490 emit_insn (gen_anddi3 (operands[0], operands[0], op1)); 10491 DONE; 10492}) 10493 10494(define_peephole2 10495 [(match_scratch:DI 2 "r") 10496 (parallel [(set (zero_extract:DI 10497 (match_operand:DI 0 "register_operand" "") 10498 (const_int 1) 10499 (match_operand:DI 1 "const_0_to_63_operand" "")) 10500 (not:DI (zero_extract:DI 10501 (match_dup 0) (const_int 1) (match_dup 1)))) 10502 (clobber (reg:CC FLAGS_REG))])] 10503 "TARGET_64BIT && !TARGET_USE_BT" 10504 [(const_int 0)] 10505{ 10506 HOST_WIDE_INT i = INTVAL (operands[1]), hi, lo; 10507 rtx op1; 10508 10509 if (HOST_BITS_PER_WIDE_INT >= 64) 10510 lo = (HOST_WIDE_INT)1 << i, hi = 0; 10511 else if (i < HOST_BITS_PER_WIDE_INT) 10512 lo = (HOST_WIDE_INT)1 << i, hi = 0; 10513 else 10514 lo = 0, hi = (HOST_WIDE_INT)1 << (i - HOST_BITS_PER_WIDE_INT); 10515 10516 op1 = immed_double_const (lo, hi, DImode); 10517 if (i >= 31) 10518 { 10519 emit_move_insn (operands[2], op1); 10520 op1 = operands[2]; 10521 } 10522 10523 emit_insn (gen_xordi3 (operands[0], operands[0], op1)); 10524 DONE; 10525}) 10526 10527(define_insn "*bt<mode>" 10528 [(set (reg:CCC FLAGS_REG) 10529 (compare:CCC 10530 (zero_extract:SWI48 10531 (match_operand:SWI48 0 "register_operand" "r") 10532 (const_int 1) 10533 (match_operand:SWI48 1 "x86_64_nonmemory_operand" "rN")) 10534 (const_int 0)))] 10535 "TARGET_USE_BT || optimize_function_for_size_p (cfun)" 10536 "bt{<imodesuffix>}\t{%1, %0|%0, %1}" 10537 [(set_attr "type" "alu1") 10538 (set_attr "prefix_0f" "1") 10539 (set_attr "mode" "<MODE>")]) 10540 10541;; Store-flag instructions. 10542 10543;; For all sCOND expanders, also expand the compare or test insn that 10544;; generates cc0. Generate an equality comparison if `seq' or `sne'. 10545 10546(define_insn_and_split "*setcc_di_1" 10547 [(set (match_operand:DI 0 "register_operand" "=q") 10548 (match_operator:DI 1 "ix86_comparison_operator" 10549 [(reg FLAGS_REG) (const_int 0)]))] 10550 "TARGET_64BIT && !TARGET_PARTIAL_REG_STALL" 10551 "#" 10552 "&& reload_completed" 10553 [(set (match_dup 2) (match_dup 1)) 10554 (set (match_dup 0) (zero_extend:DI (match_dup 2)))] 10555{ 10556 PUT_MODE (operands[1], QImode); 10557 operands[2] = gen_lowpart (QImode, operands[0]); 10558}) 10559 10560(define_insn_and_split "*setcc_si_1_and" 10561 [(set (match_operand:SI 0 "register_operand" "=q") 10562 (match_operator:SI 1 "ix86_comparison_operator" 10563 [(reg FLAGS_REG) (const_int 0)])) 10564 (clobber (reg:CC FLAGS_REG))] 10565 "!TARGET_PARTIAL_REG_STALL 10566 && TARGET_ZERO_EXTEND_WITH_AND && optimize_function_for_speed_p (cfun)" 10567 "#" 10568 "&& reload_completed" 10569 [(set (match_dup 2) (match_dup 1)) 10570 (parallel [(set (match_dup 0) (zero_extend:SI (match_dup 2))) 10571 (clobber (reg:CC FLAGS_REG))])] 10572{ 10573 PUT_MODE (operands[1], QImode); 10574 operands[2] = gen_lowpart (QImode, operands[0]); 10575}) 10576 10577(define_insn_and_split "*setcc_si_1_movzbl" 10578 [(set (match_operand:SI 0 "register_operand" "=q") 10579 (match_operator:SI 1 "ix86_comparison_operator" 10580 [(reg FLAGS_REG) (const_int 0)]))] 10581 "!TARGET_PARTIAL_REG_STALL 10582 && (!TARGET_ZERO_EXTEND_WITH_AND || optimize_function_for_size_p (cfun))" 10583 "#" 10584 "&& reload_completed" 10585 [(set (match_dup 2) (match_dup 1)) 10586 (set (match_dup 0) (zero_extend:SI (match_dup 2)))] 10587{ 10588 PUT_MODE (operands[1], QImode); 10589 operands[2] = gen_lowpart (QImode, operands[0]); 10590}) 10591 10592(define_insn "*setcc_qi" 10593 [(set (match_operand:QI 0 "nonimmediate_operand" "=qm") 10594 (match_operator:QI 1 "ix86_comparison_operator" 10595 [(reg FLAGS_REG) (const_int 0)]))] 10596 "" 10597 "set%C1\t%0" 10598 [(set_attr "type" "setcc") 10599 (set_attr "mode" "QI")]) 10600 10601(define_insn "*setcc_qi_slp" 10602 [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm")) 10603 (match_operator:QI 1 "ix86_comparison_operator" 10604 [(reg FLAGS_REG) (const_int 0)]))] 10605 "" 10606 "set%C1\t%0" 10607 [(set_attr "type" "setcc") 10608 (set_attr "mode" "QI")]) 10609 10610;; In general it is not safe to assume too much about CCmode registers, 10611;; so simplify-rtx stops when it sees a second one. Under certain 10612;; conditions this is safe on x86, so help combine not create 10613;; 10614;; seta %al 10615;; testb %al, %al 10616;; sete %al 10617 10618(define_split 10619 [(set (match_operand:QI 0 "nonimmediate_operand" "") 10620 (ne:QI (match_operator 1 "ix86_comparison_operator" 10621 [(reg FLAGS_REG) (const_int 0)]) 10622 (const_int 0)))] 10623 "" 10624 [(set (match_dup 0) (match_dup 1))] 10625 "PUT_MODE (operands[1], QImode);") 10626 10627(define_split 10628 [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "")) 10629 (ne:QI (match_operator 1 "ix86_comparison_operator" 10630 [(reg FLAGS_REG) (const_int 0)]) 10631 (const_int 0)))] 10632 "" 10633 [(set (match_dup 0) (match_dup 1))] 10634 "PUT_MODE (operands[1], QImode);") 10635 10636(define_split 10637 [(set (match_operand:QI 0 "nonimmediate_operand" "") 10638 (eq:QI (match_operator 1 "ix86_comparison_operator" 10639 [(reg FLAGS_REG) (const_int 0)]) 10640 (const_int 0)))] 10641 "" 10642 [(set (match_dup 0) (match_dup 1))] 10643{ 10644 rtx new_op1 = copy_rtx (operands[1]); 10645 operands[1] = new_op1; 10646 PUT_MODE (new_op1, QImode); 10647 PUT_CODE (new_op1, ix86_reverse_condition (GET_CODE (new_op1), 10648 GET_MODE (XEXP (new_op1, 0)))); 10649 10650 /* Make sure that (a) the CCmode we have for the flags is strong 10651 enough for the reversed compare or (b) we have a valid FP compare. */ 10652 if (! ix86_comparison_operator (new_op1, VOIDmode)) 10653 FAIL; 10654}) 10655 10656(define_split 10657 [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "")) 10658 (eq:QI (match_operator 1 "ix86_comparison_operator" 10659 [(reg FLAGS_REG) (const_int 0)]) 10660 (const_int 0)))] 10661 "" 10662 [(set (match_dup 0) (match_dup 1))] 10663{ 10664 rtx new_op1 = copy_rtx (operands[1]); 10665 operands[1] = new_op1; 10666 PUT_MODE (new_op1, QImode); 10667 PUT_CODE (new_op1, ix86_reverse_condition (GET_CODE (new_op1), 10668 GET_MODE (XEXP (new_op1, 0)))); 10669 10670 /* Make sure that (a) the CCmode we have for the flags is strong 10671 enough for the reversed compare or (b) we have a valid FP compare. */ 10672 if (! ix86_comparison_operator (new_op1, VOIDmode)) 10673 FAIL; 10674}) 10675 10676;; The SSE store flag instructions saves 0 or 0xffffffff to the result. 10677;; subsequent logical operations are used to imitate conditional moves. 10678;; 0xffffffff is NaN, but not in normalized form, so we can't represent 10679;; it directly. 10680 10681(define_insn "setcc_<mode>_sse" 10682 [(set (match_operand:MODEF 0 "register_operand" "=x,x") 10683 (match_operator:MODEF 3 "sse_comparison_operator" 10684 [(match_operand:MODEF 1 "register_operand" "0,x") 10685 (match_operand:MODEF 2 "nonimmediate_operand" "xm,xm")]))] 10686 "SSE_FLOAT_MODE_P (<MODE>mode)" 10687 "@ 10688 cmp%D3<ssemodesuffix>\t{%2, %0|%0, %2} 10689 vcmp%D3<ssemodesuffix>\t{%2, %1, %0|%0, %1, %2}" 10690 [(set_attr "isa" "noavx,avx") 10691 (set_attr "type" "ssecmp") 10692 (set_attr "length_immediate" "1") 10693 (set_attr "prefix" "orig,vex") 10694 (set_attr "mode" "<MODE>")]) 10695 10696;; Basic conditional jump instructions. 10697;; We ignore the overflow flag for signed branch instructions. 10698 10699(define_insn "*jcc_1" 10700 [(set (pc) 10701 (if_then_else (match_operator 1 "ix86_comparison_operator" 10702 [(reg FLAGS_REG) (const_int 0)]) 10703 (label_ref (match_operand 0 "" "")) 10704 (pc)))] 10705 "" 10706 "%+j%C1\t%l0" 10707 [(set_attr "type" "ibr") 10708 (set_attr "modrm" "0") 10709 (set (attr "length") 10710 (if_then_else (and (ge (minus (match_dup 0) (pc)) 10711 (const_int -126)) 10712 (lt (minus (match_dup 0) (pc)) 10713 (const_int 128))) 10714 (const_int 2) 10715 (const_int 6)))]) 10716 10717(define_insn "*jcc_2" 10718 [(set (pc) 10719 (if_then_else (match_operator 1 "ix86_comparison_operator" 10720 [(reg FLAGS_REG) (const_int 0)]) 10721 (pc) 10722 (label_ref (match_operand 0 "" ""))))] 10723 "" 10724 "%+j%c1\t%l0" 10725 [(set_attr "type" "ibr") 10726 (set_attr "modrm" "0") 10727 (set (attr "length") 10728 (if_then_else (and (ge (minus (match_dup 0) (pc)) 10729 (const_int -126)) 10730 (lt (minus (match_dup 0) (pc)) 10731 (const_int 128))) 10732 (const_int 2) 10733 (const_int 6)))]) 10734 10735;; In general it is not safe to assume too much about CCmode registers, 10736;; so simplify-rtx stops when it sees a second one. Under certain 10737;; conditions this is safe on x86, so help combine not create 10738;; 10739;; seta %al 10740;; testb %al, %al 10741;; je Lfoo 10742 10743(define_split 10744 [(set (pc) 10745 (if_then_else (ne (match_operator 0 "ix86_comparison_operator" 10746 [(reg FLAGS_REG) (const_int 0)]) 10747 (const_int 0)) 10748 (label_ref (match_operand 1 "" "")) 10749 (pc)))] 10750 "" 10751 [(set (pc) 10752 (if_then_else (match_dup 0) 10753 (label_ref (match_dup 1)) 10754 (pc)))] 10755 "PUT_MODE (operands[0], VOIDmode);") 10756 10757(define_split 10758 [(set (pc) 10759 (if_then_else (eq (match_operator 0 "ix86_comparison_operator" 10760 [(reg FLAGS_REG) (const_int 0)]) 10761 (const_int 0)) 10762 (label_ref (match_operand 1 "" "")) 10763 (pc)))] 10764 "" 10765 [(set (pc) 10766 (if_then_else (match_dup 0) 10767 (label_ref (match_dup 1)) 10768 (pc)))] 10769{ 10770 rtx new_op0 = copy_rtx (operands[0]); 10771 operands[0] = new_op0; 10772 PUT_MODE (new_op0, VOIDmode); 10773 PUT_CODE (new_op0, ix86_reverse_condition (GET_CODE (new_op0), 10774 GET_MODE (XEXP (new_op0, 0)))); 10775 10776 /* Make sure that (a) the CCmode we have for the flags is strong 10777 enough for the reversed compare or (b) we have a valid FP compare. */ 10778 if (! ix86_comparison_operator (new_op0, VOIDmode)) 10779 FAIL; 10780}) 10781 10782;; zero_extend in SImode is correct also for DImode, since this is what combine 10783;; pass generates from shift insn with QImode operand. Actually, the mode 10784;; of operand 2 (bit offset operand) doesn't matter since bt insn takes 10785;; appropriate modulo of the bit offset value. 10786 10787(define_insn_and_split "*jcc_bt<mode>" 10788 [(set (pc) 10789 (if_then_else (match_operator 0 "bt_comparison_operator" 10790 [(zero_extract:SWI48 10791 (match_operand:SWI48 1 "register_operand" "r") 10792 (const_int 1) 10793 (zero_extend:SI 10794 (match_operand:QI 2 "register_operand" "r"))) 10795 (const_int 0)]) 10796 (label_ref (match_operand 3 "" "")) 10797 (pc))) 10798 (clobber (reg:CC FLAGS_REG))] 10799 "TARGET_USE_BT || optimize_function_for_size_p (cfun)" 10800 "#" 10801 "&& 1" 10802 [(set (reg:CCC FLAGS_REG) 10803 (compare:CCC 10804 (zero_extract:SWI48 10805 (match_dup 1) 10806 (const_int 1) 10807 (match_dup 2)) 10808 (const_int 0))) 10809 (set (pc) 10810 (if_then_else (match_op_dup 0 [(reg:CCC FLAGS_REG) (const_int 0)]) 10811 (label_ref (match_dup 3)) 10812 (pc)))] 10813{ 10814 operands[2] = simplify_gen_subreg (<MODE>mode, operands[2], QImode, 0); 10815 10816 PUT_CODE (operands[0], reverse_condition (GET_CODE (operands[0]))); 10817}) 10818 10819;; Avoid useless masking of bit offset operand. "and" in SImode is correct 10820;; also for DImode, this is what combine produces. 10821(define_insn_and_split "*jcc_bt<mode>_mask" 10822 [(set (pc) 10823 (if_then_else (match_operator 0 "bt_comparison_operator" 10824 [(zero_extract:SWI48 10825 (match_operand:SWI48 1 "register_operand" "r") 10826 (const_int 1) 10827 (and:SI 10828 (match_operand:SI 2 "register_operand" "r") 10829 (match_operand:SI 3 "const_int_operand" "n")))]) 10830 (label_ref (match_operand 4 "" "")) 10831 (pc))) 10832 (clobber (reg:CC FLAGS_REG))] 10833 "(TARGET_USE_BT || optimize_function_for_size_p (cfun)) 10834 && (INTVAL (operands[3]) & (GET_MODE_BITSIZE (<MODE>mode)-1)) 10835 == GET_MODE_BITSIZE (<MODE>mode)-1" 10836 "#" 10837 "&& 1" 10838 [(set (reg:CCC FLAGS_REG) 10839 (compare:CCC 10840 (zero_extract:SWI48 10841 (match_dup 1) 10842 (const_int 1) 10843 (match_dup 2)) 10844 (const_int 0))) 10845 (set (pc) 10846 (if_then_else (match_op_dup 0 [(reg:CCC FLAGS_REG) (const_int 0)]) 10847 (label_ref (match_dup 4)) 10848 (pc)))] 10849{ 10850 operands[2] = simplify_gen_subreg (<MODE>mode, operands[2], SImode, 0); 10851 10852 PUT_CODE (operands[0], reverse_condition (GET_CODE (operands[0]))); 10853}) 10854 10855(define_insn_and_split "*jcc_btsi_1" 10856 [(set (pc) 10857 (if_then_else (match_operator 0 "bt_comparison_operator" 10858 [(and:SI 10859 (lshiftrt:SI 10860 (match_operand:SI 1 "register_operand" "r") 10861 (match_operand:QI 2 "register_operand" "r")) 10862 (const_int 1)) 10863 (const_int 0)]) 10864 (label_ref (match_operand 3 "" "")) 10865 (pc))) 10866 (clobber (reg:CC FLAGS_REG))] 10867 "TARGET_USE_BT || optimize_function_for_size_p (cfun)" 10868 "#" 10869 "&& 1" 10870 [(set (reg:CCC FLAGS_REG) 10871 (compare:CCC 10872 (zero_extract:SI 10873 (match_dup 1) 10874 (const_int 1) 10875 (match_dup 2)) 10876 (const_int 0))) 10877 (set (pc) 10878 (if_then_else (match_op_dup 0 [(reg:CCC FLAGS_REG) (const_int 0)]) 10879 (label_ref (match_dup 3)) 10880 (pc)))] 10881{ 10882 operands[2] = simplify_gen_subreg (SImode, operands[2], QImode, 0); 10883 10884 PUT_CODE (operands[0], reverse_condition (GET_CODE (operands[0]))); 10885}) 10886 10887;; avoid useless masking of bit offset operand 10888(define_insn_and_split "*jcc_btsi_mask_1" 10889 [(set (pc) 10890 (if_then_else 10891 (match_operator 0 "bt_comparison_operator" 10892 [(and:SI 10893 (lshiftrt:SI 10894 (match_operand:SI 1 "register_operand" "r") 10895 (subreg:QI 10896 (and:SI 10897 (match_operand:SI 2 "register_operand" "r") 10898 (match_operand:SI 3 "const_int_operand" "n")) 0)) 10899 (const_int 1)) 10900 (const_int 0)]) 10901 (label_ref (match_operand 4 "" "")) 10902 (pc))) 10903 (clobber (reg:CC FLAGS_REG))] 10904 "(TARGET_USE_BT || optimize_function_for_size_p (cfun)) 10905 && (INTVAL (operands[3]) & 0x1f) == 0x1f" 10906 "#" 10907 "&& 1" 10908 [(set (reg:CCC FLAGS_REG) 10909 (compare:CCC 10910 (zero_extract:SI 10911 (match_dup 1) 10912 (const_int 1) 10913 (match_dup 2)) 10914 (const_int 0))) 10915 (set (pc) 10916 (if_then_else (match_op_dup 0 [(reg:CCC FLAGS_REG) (const_int 0)]) 10917 (label_ref (match_dup 4)) 10918 (pc)))] 10919 "PUT_CODE (operands[0], reverse_condition (GET_CODE (operands[0])));") 10920 10921;; Define combination compare-and-branch fp compare instructions to help 10922;; combine. 10923 10924(define_insn "*fp_jcc_1_387" 10925 [(set (pc) 10926 (if_then_else (match_operator 0 "ix86_fp_comparison_operator" 10927 [(match_operand 1 "register_operand" "f") 10928 (match_operand 2 "nonimmediate_operand" "fm")]) 10929 (label_ref (match_operand 3 "" "")) 10930 (pc))) 10931 (clobber (reg:CCFP FPSR_REG)) 10932 (clobber (reg:CCFP FLAGS_REG)) 10933 (clobber (match_scratch:HI 4 "=a"))] 10934 "TARGET_80387 10935 && (GET_MODE (operands[1]) == SFmode || GET_MODE (operands[1]) == DFmode) 10936 && GET_MODE (operands[1]) == GET_MODE (operands[2]) 10937 && SELECT_CC_MODE (GET_CODE (operands[0]), 10938 operands[1], operands[2]) == CCFPmode 10939 && !TARGET_CMOVE" 10940 "#") 10941 10942(define_insn "*fp_jcc_1r_387" 10943 [(set (pc) 10944 (if_then_else (match_operator 0 "ix86_fp_comparison_operator" 10945 [(match_operand 1 "register_operand" "f") 10946 (match_operand 2 "nonimmediate_operand" "fm")]) 10947 (pc) 10948 (label_ref (match_operand 3 "" "")))) 10949 (clobber (reg:CCFP FPSR_REG)) 10950 (clobber (reg:CCFP FLAGS_REG)) 10951 (clobber (match_scratch:HI 4 "=a"))] 10952 "TARGET_80387 10953 && (GET_MODE (operands[1]) == SFmode || GET_MODE (operands[1]) == DFmode) 10954 && GET_MODE (operands[1]) == GET_MODE (operands[2]) 10955 && SELECT_CC_MODE (GET_CODE (operands[0]), 10956 operands[1], operands[2]) == CCFPmode 10957 && !TARGET_CMOVE" 10958 "#") 10959 10960(define_insn "*fp_jcc_2_387" 10961 [(set (pc) 10962 (if_then_else (match_operator 0 "ix86_fp_comparison_operator" 10963 [(match_operand 1 "register_operand" "f") 10964 (match_operand 2 "register_operand" "f")]) 10965 (label_ref (match_operand 3 "" "")) 10966 (pc))) 10967 (clobber (reg:CCFP FPSR_REG)) 10968 (clobber (reg:CCFP FLAGS_REG)) 10969 (clobber (match_scratch:HI 4 "=a"))] 10970 "X87_FLOAT_MODE_P (GET_MODE (operands[1])) 10971 && GET_MODE (operands[1]) == GET_MODE (operands[2]) 10972 && !TARGET_CMOVE" 10973 "#") 10974 10975(define_insn "*fp_jcc_2r_387" 10976 [(set (pc) 10977 (if_then_else (match_operator 0 "ix86_fp_comparison_operator" 10978 [(match_operand 1 "register_operand" "f") 10979 (match_operand 2 "register_operand" "f")]) 10980 (pc) 10981 (label_ref (match_operand 3 "" "")))) 10982 (clobber (reg:CCFP FPSR_REG)) 10983 (clobber (reg:CCFP FLAGS_REG)) 10984 (clobber (match_scratch:HI 4 "=a"))] 10985 "X87_FLOAT_MODE_P (GET_MODE (operands[1])) 10986 && GET_MODE (operands[1]) == GET_MODE (operands[2]) 10987 && !TARGET_CMOVE" 10988 "#") 10989 10990(define_insn "*fp_jcc_3_387" 10991 [(set (pc) 10992 (if_then_else (match_operator 0 "ix86_fp_comparison_operator" 10993 [(match_operand 1 "register_operand" "f") 10994 (match_operand 2 "const0_operand" "")]) 10995 (label_ref (match_operand 3 "" "")) 10996 (pc))) 10997 (clobber (reg:CCFP FPSR_REG)) 10998 (clobber (reg:CCFP FLAGS_REG)) 10999 (clobber (match_scratch:HI 4 "=a"))] 11000 "X87_FLOAT_MODE_P (GET_MODE (operands[1])) 11001 && GET_MODE (operands[1]) == GET_MODE (operands[2]) 11002 && SELECT_CC_MODE (GET_CODE (operands[0]), 11003 operands[1], operands[2]) == CCFPmode 11004 && !TARGET_CMOVE" 11005 "#") 11006 11007(define_split 11008 [(set (pc) 11009 (if_then_else (match_operator 0 "ix86_fp_comparison_operator" 11010 [(match_operand 1 "register_operand" "") 11011 (match_operand 2 "nonimmediate_operand" "")]) 11012 (match_operand 3 "" "") 11013 (match_operand 4 "" ""))) 11014 (clobber (reg:CCFP FPSR_REG)) 11015 (clobber (reg:CCFP FLAGS_REG))] 11016 "reload_completed" 11017 [(const_int 0)] 11018{ 11019 ix86_split_fp_branch (GET_CODE (operands[0]), operands[1], operands[2], 11020 operands[3], operands[4], NULL_RTX, NULL_RTX); 11021 DONE; 11022}) 11023 11024(define_split 11025 [(set (pc) 11026 (if_then_else (match_operator 0 "ix86_fp_comparison_operator" 11027 [(match_operand 1 "register_operand" "") 11028 (match_operand 2 "general_operand" "")]) 11029 (match_operand 3 "" "") 11030 (match_operand 4 "" ""))) 11031 (clobber (reg:CCFP FPSR_REG)) 11032 (clobber (reg:CCFP FLAGS_REG)) 11033 (clobber (match_scratch:HI 5 "=a"))] 11034 "reload_completed" 11035 [(const_int 0)] 11036{ 11037 ix86_split_fp_branch (GET_CODE (operands[0]), operands[1], operands[2], 11038 operands[3], operands[4], operands[5], NULL_RTX); 11039 DONE; 11040}) 11041 11042;; The order of operands in *fp_jcc_4_387 is forced by combine in 11043;; simplify_comparison () function. Float operator is treated as RTX_OBJ 11044;; with a precedence over other operators and is always put in the first 11045;; place. Swap condition and operands to match ficom instruction. 11046 11047(define_insn "*fp_jcc_4_<mode>_387" 11048 [(set (pc) 11049 (if_then_else 11050 (match_operator 0 "ix86_swapped_fp_comparison_operator" 11051 [(match_operator 1 "float_operator" 11052 [(match_operand:SWI24 2 "nonimmediate_operand" "m,?r")]) 11053 (match_operand 3 "register_operand" "f,f")]) 11054 (label_ref (match_operand 4 "" "")) 11055 (pc))) 11056 (clobber (reg:CCFP FPSR_REG)) 11057 (clobber (reg:CCFP FLAGS_REG)) 11058 (clobber (match_scratch:HI 5 "=a,a"))] 11059 "X87_FLOAT_MODE_P (GET_MODE (operands[3])) 11060 && (TARGET_USE_<MODE>MODE_FIOP || optimize_function_for_size_p (cfun)) 11061 && GET_MODE (operands[1]) == GET_MODE (operands[3]) 11062 && ix86_fp_compare_mode (swap_condition (GET_CODE (operands[0]))) == CCFPmode 11063 && !TARGET_CMOVE" 11064 "#") 11065 11066(define_split 11067 [(set (pc) 11068 (if_then_else 11069 (match_operator 0 "ix86_swapped_fp_comparison_operator" 11070 [(match_operator 1 "float_operator" 11071 [(match_operand:SWI24 2 "memory_operand" "")]) 11072 (match_operand 3 "register_operand" "")]) 11073 (match_operand 4 "" "") 11074 (match_operand 5 "" ""))) 11075 (clobber (reg:CCFP FPSR_REG)) 11076 (clobber (reg:CCFP FLAGS_REG)) 11077 (clobber (match_scratch:HI 6 "=a"))] 11078 "reload_completed" 11079 [(const_int 0)] 11080{ 11081 operands[7] = gen_rtx_FLOAT (GET_MODE (operands[1]), operands[2]); 11082 11083 ix86_split_fp_branch (swap_condition (GET_CODE (operands[0])), 11084 operands[3], operands[7], 11085 operands[4], operands[5], operands[6], NULL_RTX); 11086 DONE; 11087}) 11088 11089;; %%% Kill this when reload knows how to do it. 11090(define_split 11091 [(set (pc) 11092 (if_then_else 11093 (match_operator 0 "ix86_swapped_fp_comparison_operator" 11094 [(match_operator 1 "float_operator" 11095 [(match_operand:SWI24 2 "register_operand" "")]) 11096 (match_operand 3 "register_operand" "")]) 11097 (match_operand 4 "" "") 11098 (match_operand 5 "" ""))) 11099 (clobber (reg:CCFP FPSR_REG)) 11100 (clobber (reg:CCFP FLAGS_REG)) 11101 (clobber (match_scratch:HI 6 "=a"))] 11102 "reload_completed" 11103 [(const_int 0)] 11104{ 11105 operands[7] = ix86_force_to_memory (GET_MODE (operands[2]), operands[2]); 11106 operands[7] = gen_rtx_FLOAT (GET_MODE (operands[1]), operands[7]); 11107 11108 ix86_split_fp_branch (swap_condition (GET_CODE (operands[0])), 11109 operands[3], operands[7], 11110 operands[4], operands[5], operands[6], operands[2]); 11111 DONE; 11112}) 11113 11114;; Unconditional and other jump instructions 11115 11116(define_insn "jump" 11117 [(set (pc) 11118 (label_ref (match_operand 0 "" "")))] 11119 "" 11120 "jmp\t%l0" 11121 [(set_attr "type" "ibr") 11122 (set (attr "length") 11123 (if_then_else (and (ge (minus (match_dup 0) (pc)) 11124 (const_int -126)) 11125 (lt (minus (match_dup 0) (pc)) 11126 (const_int 128))) 11127 (const_int 2) 11128 (const_int 5))) 11129 (set_attr "modrm" "0")]) 11130 11131(define_expand "indirect_jump" 11132 [(set (pc) (match_operand 0 "indirect_branch_operand" ""))]) 11133 11134(define_insn "*indirect_jump" 11135 [(set (pc) (match_operand:P 0 "indirect_branch_operand" "rw"))] 11136 "" 11137 "jmp\t%A0" 11138 [(set_attr "type" "ibr") 11139 (set_attr "length_immediate" "0")]) 11140 11141(define_expand "tablejump" 11142 [(parallel [(set (pc) (match_operand 0 "indirect_branch_operand" "")) 11143 (use (label_ref (match_operand 1 "" "")))])] 11144 "" 11145{ 11146 /* In PIC mode, the table entries are stored GOT (32-bit) or PC (64-bit) 11147 relative. Convert the relative address to an absolute address. */ 11148 if (flag_pic) 11149 { 11150 rtx op0, op1; 11151 enum rtx_code code; 11152 11153 /* We can't use @GOTOFF for text labels on VxWorks; 11154 see gotoff_operand. */ 11155 if (TARGET_64BIT || TARGET_VXWORKS_RTP) 11156 { 11157 code = PLUS; 11158 op0 = operands[0]; 11159 op1 = gen_rtx_LABEL_REF (Pmode, operands[1]); 11160 } 11161 else if (TARGET_MACHO || HAVE_AS_GOTOFF_IN_DATA) 11162 { 11163 code = PLUS; 11164 op0 = operands[0]; 11165 op1 = pic_offset_table_rtx; 11166 } 11167 else 11168 { 11169 code = MINUS; 11170 op0 = pic_offset_table_rtx; 11171 op1 = operands[0]; 11172 } 11173 11174 operands[0] = expand_simple_binop (Pmode, code, op0, op1, NULL_RTX, 0, 11175 OPTAB_DIRECT); 11176 } 11177 else if (TARGET_X32) 11178 operands[0] = convert_memory_address (Pmode, operands[0]); 11179}) 11180 11181(define_insn "*tablejump_1" 11182 [(set (pc) (match_operand:P 0 "indirect_branch_operand" "rw")) 11183 (use (label_ref (match_operand 1 "" "")))] 11184 "" 11185 "jmp\t%A0" 11186 [(set_attr "type" "ibr") 11187 (set_attr "length_immediate" "0")]) 11188 11189;; Convert setcc + movzbl to xor + setcc if operands don't overlap. 11190 11191(define_peephole2 11192 [(set (reg FLAGS_REG) (match_operand 0 "" "")) 11193 (set (match_operand:QI 1 "register_operand" "") 11194 (match_operator:QI 2 "ix86_comparison_operator" 11195 [(reg FLAGS_REG) (const_int 0)])) 11196 (set (match_operand 3 "q_regs_operand" "") 11197 (zero_extend (match_dup 1)))] 11198 "(peep2_reg_dead_p (3, operands[1]) 11199 || operands_match_p (operands[1], operands[3])) 11200 && ! reg_overlap_mentioned_p (operands[3], operands[0])" 11201 [(set (match_dup 4) (match_dup 0)) 11202 (set (strict_low_part (match_dup 5)) 11203 (match_dup 2))] 11204{ 11205 operands[4] = gen_rtx_REG (GET_MODE (operands[0]), FLAGS_REG); 11206 operands[5] = gen_lowpart (QImode, operands[3]); 11207 ix86_expand_clear (operands[3]); 11208}) 11209 11210;; Similar, but match zero_extendhisi2_and, which adds a clobber. 11211 11212(define_peephole2 11213 [(set (reg FLAGS_REG) (match_operand 0 "" "")) 11214 (set (match_operand:QI 1 "register_operand" "") 11215 (match_operator:QI 2 "ix86_comparison_operator" 11216 [(reg FLAGS_REG) (const_int 0)])) 11217 (parallel [(set (match_operand 3 "q_regs_operand" "") 11218 (zero_extend (match_dup 1))) 11219 (clobber (reg:CC FLAGS_REG))])] 11220 "(peep2_reg_dead_p (3, operands[1]) 11221 || operands_match_p (operands[1], operands[3])) 11222 && ! reg_overlap_mentioned_p (operands[3], operands[0])" 11223 [(set (match_dup 4) (match_dup 0)) 11224 (set (strict_low_part (match_dup 5)) 11225 (match_dup 2))] 11226{ 11227 operands[4] = gen_rtx_REG (GET_MODE (operands[0]), FLAGS_REG); 11228 operands[5] = gen_lowpart (QImode, operands[3]); 11229 ix86_expand_clear (operands[3]); 11230}) 11231 11232;; Call instructions. 11233 11234;; The predicates normally associated with named expanders are not properly 11235;; checked for calls. This is a bug in the generic code, but it isn't that 11236;; easy to fix. Ignore it for now and be prepared to fix things up. 11237 11238;; P6 processors will jump to the address after the decrement when %esp 11239;; is used as a call operand, so they will execute return address as a code. 11240;; See Pentium Pro errata 70, Pentium 2 errata A33 and Pentium 3 errata E17. 11241 11242;; Register constraint for call instruction. 11243(define_mode_attr c [(SI "l") (DI "r")]) 11244 11245;; Call subroutine returning no value. 11246 11247(define_expand "call" 11248 [(call (match_operand:QI 0 "" "") 11249 (match_operand 1 "" "")) 11250 (use (match_operand 2 "" ""))] 11251 "" 11252{ 11253 ix86_expand_call (NULL, operands[0], operands[1], 11254 operands[2], NULL, false); 11255 DONE; 11256}) 11257 11258(define_expand "sibcall" 11259 [(call (match_operand:QI 0 "" "") 11260 (match_operand 1 "" "")) 11261 (use (match_operand 2 "" ""))] 11262 "" 11263{ 11264 ix86_expand_call (NULL, operands[0], operands[1], 11265 operands[2], NULL, true); 11266 DONE; 11267}) 11268 11269(define_insn_and_split "*call_vzeroupper" 11270 [(call (mem:QI (match_operand:P 0 "call_insn_operand" "<c>zw")) 11271 (match_operand 1 "" "")) 11272 (unspec [(match_operand 2 "const_int_operand" "")] 11273 UNSPEC_CALL_NEEDS_VZEROUPPER)] 11274 "TARGET_VZEROUPPER && !SIBLING_CALL_P (insn)" 11275 "#" 11276 "&& reload_completed" 11277 [(const_int 0)] 11278 "ix86_split_call_vzeroupper (curr_insn, operands[2]); DONE;" 11279 [(set_attr "type" "call")]) 11280 11281(define_insn "*call" 11282 [(call (mem:QI (match_operand:P 0 "call_insn_operand" "<c>zw")) 11283 (match_operand 1 "" ""))] 11284 "!SIBLING_CALL_P (insn)" 11285 "* return ix86_output_call_insn (insn, operands[0]);" 11286 [(set_attr "type" "call")]) 11287 11288(define_insn_and_split "*call_rex64_ms_sysv_vzeroupper" 11289 [(call (mem:QI (match_operand:DI 0 "call_insn_operand" "rzw")) 11290 (match_operand 1 "" "")) 11291 (unspec [(const_int 0)] UNSPEC_MS_TO_SYSV_CALL) 11292 (clobber (reg:TI XMM6_REG)) 11293 (clobber (reg:TI XMM7_REG)) 11294 (clobber (reg:TI XMM8_REG)) 11295 (clobber (reg:TI XMM9_REG)) 11296 (clobber (reg:TI XMM10_REG)) 11297 (clobber (reg:TI XMM11_REG)) 11298 (clobber (reg:TI XMM12_REG)) 11299 (clobber (reg:TI XMM13_REG)) 11300 (clobber (reg:TI XMM14_REG)) 11301 (clobber (reg:TI XMM15_REG)) 11302 (clobber (reg:DI SI_REG)) 11303 (clobber (reg:DI DI_REG)) 11304 (unspec [(match_operand 2 "const_int_operand" "")] 11305 UNSPEC_CALL_NEEDS_VZEROUPPER)] 11306 "TARGET_VZEROUPPER && TARGET_64BIT && !SIBLING_CALL_P (insn)" 11307 "#" 11308 "&& reload_completed" 11309 [(const_int 0)] 11310 "ix86_split_call_vzeroupper (curr_insn, operands[2]); DONE;" 11311 [(set_attr "type" "call")]) 11312 11313(define_insn "*call_rex64_ms_sysv" 11314 [(call (mem:QI (match_operand:DI 0 "call_insn_operand" "rzw")) 11315 (match_operand 1 "" "")) 11316 (unspec [(const_int 0)] UNSPEC_MS_TO_SYSV_CALL) 11317 (clobber (reg:TI XMM6_REG)) 11318 (clobber (reg:TI XMM7_REG)) 11319 (clobber (reg:TI XMM8_REG)) 11320 (clobber (reg:TI XMM9_REG)) 11321 (clobber (reg:TI XMM10_REG)) 11322 (clobber (reg:TI XMM11_REG)) 11323 (clobber (reg:TI XMM12_REG)) 11324 (clobber (reg:TI XMM13_REG)) 11325 (clobber (reg:TI XMM14_REG)) 11326 (clobber (reg:TI XMM15_REG)) 11327 (clobber (reg:DI SI_REG)) 11328 (clobber (reg:DI DI_REG))] 11329 "TARGET_64BIT && !SIBLING_CALL_P (insn)" 11330 "* return ix86_output_call_insn (insn, operands[0]);" 11331 [(set_attr "type" "call")]) 11332 11333(define_insn_and_split "*sibcall_vzeroupper" 11334 [(call (mem:QI (match_operand:P 0 "sibcall_insn_operand" "Uz")) 11335 (match_operand 1 "" "")) 11336 (unspec [(match_operand 2 "const_int_operand" "")] 11337 UNSPEC_CALL_NEEDS_VZEROUPPER)] 11338 "TARGET_VZEROUPPER && SIBLING_CALL_P (insn)" 11339 "#" 11340 "&& reload_completed" 11341 [(const_int 0)] 11342 "ix86_split_call_vzeroupper (curr_insn, operands[2]); DONE;" 11343 [(set_attr "type" "call")]) 11344 11345(define_insn "*sibcall" 11346 [(call (mem:QI (match_operand:P 0 "sibcall_insn_operand" "Uz")) 11347 (match_operand 1 "" ""))] 11348 "SIBLING_CALL_P (insn)" 11349 "* return ix86_output_call_insn (insn, operands[0]);" 11350 [(set_attr "type" "call")]) 11351 11352(define_expand "call_pop" 11353 [(parallel [(call (match_operand:QI 0 "" "") 11354 (match_operand:SI 1 "" "")) 11355 (set (reg:SI SP_REG) 11356 (plus:SI (reg:SI SP_REG) 11357 (match_operand:SI 3 "" "")))])] 11358 "!TARGET_64BIT" 11359{ 11360 ix86_expand_call (NULL, operands[0], operands[1], 11361 operands[2], operands[3], false); 11362 DONE; 11363}) 11364 11365(define_insn_and_split "*call_pop_vzeroupper" 11366 [(call (mem:QI (match_operand:SI 0 "call_insn_operand" "lzm")) 11367 (match_operand:SI 1 "" "")) 11368 (set (reg:SI SP_REG) 11369 (plus:SI (reg:SI SP_REG) 11370 (match_operand:SI 2 "immediate_operand" "i"))) 11371 (unspec [(match_operand 3 "const_int_operand" "")] 11372 UNSPEC_CALL_NEEDS_VZEROUPPER)] 11373 "TARGET_VZEROUPPER && !TARGET_64BIT && !SIBLING_CALL_P (insn)" 11374 "#" 11375 "&& reload_completed" 11376 [(const_int 0)] 11377 "ix86_split_call_vzeroupper (curr_insn, operands[3]); DONE;" 11378 [(set_attr "type" "call")]) 11379 11380(define_insn "*call_pop" 11381 [(call (mem:QI (match_operand:SI 0 "call_insn_operand" "lzm")) 11382 (match_operand 1 "" "")) 11383 (set (reg:SI SP_REG) 11384 (plus:SI (reg:SI SP_REG) 11385 (match_operand:SI 2 "immediate_operand" "i")))] 11386 "!TARGET_64BIT && !SIBLING_CALL_P (insn)" 11387 "* return ix86_output_call_insn (insn, operands[0]);" 11388 [(set_attr "type" "call")]) 11389 11390(define_insn_and_split "*sibcall_pop_vzeroupper" 11391 [(call (mem:QI (match_operand:SI 0 "sibcall_insn_operand" "Uz")) 11392 (match_operand 1 "" "")) 11393 (set (reg:SI SP_REG) 11394 (plus:SI (reg:SI SP_REG) 11395 (match_operand:SI 2 "immediate_operand" "i"))) 11396 (unspec [(match_operand 3 "const_int_operand" "")] 11397 UNSPEC_CALL_NEEDS_VZEROUPPER)] 11398 "TARGET_VZEROUPPER && !TARGET_64BIT && SIBLING_CALL_P (insn)" 11399 "#" 11400 "&& reload_completed" 11401 [(const_int 0)] 11402 "ix86_split_call_vzeroupper (curr_insn, operands[3]); DONE;" 11403 [(set_attr "type" "call")]) 11404 11405(define_insn "*sibcall_pop" 11406 [(call (mem:QI (match_operand:SI 0 "sibcall_insn_operand" "Uz")) 11407 (match_operand 1 "" "")) 11408 (set (reg:SI SP_REG) 11409 (plus:SI (reg:SI SP_REG) 11410 (match_operand:SI 2 "immediate_operand" "i")))] 11411 "!TARGET_64BIT && SIBLING_CALL_P (insn)" 11412 "* return ix86_output_call_insn (insn, operands[0]);" 11413 [(set_attr "type" "call")]) 11414 11415;; Call subroutine, returning value in operand 0 11416 11417(define_expand "call_value" 11418 [(set (match_operand 0 "" "") 11419 (call (match_operand:QI 1 "" "") 11420 (match_operand 2 "" ""))) 11421 (use (match_operand 3 "" ""))] 11422 "" 11423{ 11424 ix86_expand_call (operands[0], operands[1], operands[2], 11425 operands[3], NULL, false); 11426 DONE; 11427}) 11428 11429(define_expand "sibcall_value" 11430 [(set (match_operand 0 "" "") 11431 (call (match_operand:QI 1 "" "") 11432 (match_operand 2 "" ""))) 11433 (use (match_operand 3 "" ""))] 11434 "" 11435{ 11436 ix86_expand_call (operands[0], operands[1], operands[2], 11437 operands[3], NULL, true); 11438 DONE; 11439}) 11440 11441(define_insn_and_split "*call_value_vzeroupper" 11442 [(set (match_operand 0 "" "") 11443 (call (mem:QI (match_operand:P 1 "call_insn_operand" "<c>zw")) 11444 (match_operand 2 "" ""))) 11445 (unspec [(match_operand 3 "const_int_operand" "")] 11446 UNSPEC_CALL_NEEDS_VZEROUPPER)] 11447 "TARGET_VZEROUPPER && !SIBLING_CALL_P (insn)" 11448 "#" 11449 "&& reload_completed" 11450 [(const_int 0)] 11451 "ix86_split_call_vzeroupper (curr_insn, operands[3]); DONE;" 11452 [(set_attr "type" "callv")]) 11453 11454(define_insn "*call_value" 11455 [(set (match_operand 0 "" "") 11456 (call (mem:QI (match_operand:P 1 "call_insn_operand" "<c>zw")) 11457 (match_operand 2 "" "")))] 11458 "!SIBLING_CALL_P (insn)" 11459 "* return ix86_output_call_insn (insn, operands[1]);" 11460 [(set_attr "type" "callv")]) 11461 11462(define_insn_and_split "*sibcall_value_vzeroupper" 11463 [(set (match_operand 0 "" "") 11464 (call (mem:QI (match_operand:P 1 "sibcall_insn_operand" "Uz")) 11465 (match_operand 2 "" ""))) 11466 (unspec [(match_operand 3 "const_int_operand" "")] 11467 UNSPEC_CALL_NEEDS_VZEROUPPER)] 11468 "TARGET_VZEROUPPER && SIBLING_CALL_P (insn)" 11469 "#" 11470 "&& reload_completed" 11471 [(const_int 0)] 11472 "ix86_split_call_vzeroupper (curr_insn, operands[3]); DONE;" 11473 [(set_attr "type" "callv")]) 11474 11475(define_insn "*sibcall_value" 11476 [(set (match_operand 0 "" "") 11477 (call (mem:QI (match_operand:P 1 "sibcall_insn_operand" "Uz")) 11478 (match_operand 2 "" "")))] 11479 "SIBLING_CALL_P (insn)" 11480 "* return ix86_output_call_insn (insn, operands[1]);" 11481 [(set_attr "type" "callv")]) 11482 11483(define_insn_and_split "*call_value_rex64_ms_sysv_vzeroupper" 11484 [(set (match_operand 0 "" "") 11485 (call (mem:QI (match_operand:DI 1 "call_insn_operand" "rzw")) 11486 (match_operand 2 "" ""))) 11487 (unspec [(const_int 0)] UNSPEC_MS_TO_SYSV_CALL) 11488 (clobber (reg:TI XMM6_REG)) 11489 (clobber (reg:TI XMM7_REG)) 11490 (clobber (reg:TI XMM8_REG)) 11491 (clobber (reg:TI XMM9_REG)) 11492 (clobber (reg:TI XMM10_REG)) 11493 (clobber (reg:TI XMM11_REG)) 11494 (clobber (reg:TI XMM12_REG)) 11495 (clobber (reg:TI XMM13_REG)) 11496 (clobber (reg:TI XMM14_REG)) 11497 (clobber (reg:TI XMM15_REG)) 11498 (clobber (reg:DI SI_REG)) 11499 (clobber (reg:DI DI_REG)) 11500 (unspec [(match_operand 3 "const_int_operand" "")] 11501 UNSPEC_CALL_NEEDS_VZEROUPPER)] 11502 "TARGET_VZEROUPPER && TARGET_64BIT && !SIBLING_CALL_P (insn)" 11503 "#" 11504 "&& reload_completed" 11505 [(const_int 0)] 11506 "ix86_split_call_vzeroupper (curr_insn, operands[3]); DONE;" 11507 [(set_attr "type" "callv")]) 11508 11509(define_insn "*call_value_rex64_ms_sysv" 11510 [(set (match_operand 0 "" "") 11511 (call (mem:QI (match_operand:DI 1 "call_insn_operand" "rzw")) 11512 (match_operand 2 "" ""))) 11513 (unspec [(const_int 0)] UNSPEC_MS_TO_SYSV_CALL) 11514 (clobber (reg:TI XMM6_REG)) 11515 (clobber (reg:TI XMM7_REG)) 11516 (clobber (reg:TI XMM8_REG)) 11517 (clobber (reg:TI XMM9_REG)) 11518 (clobber (reg:TI XMM10_REG)) 11519 (clobber (reg:TI XMM11_REG)) 11520 (clobber (reg:TI XMM12_REG)) 11521 (clobber (reg:TI XMM13_REG)) 11522 (clobber (reg:TI XMM14_REG)) 11523 (clobber (reg:TI XMM15_REG)) 11524 (clobber (reg:DI SI_REG)) 11525 (clobber (reg:DI DI_REG))] 11526 "TARGET_64BIT && !SIBLING_CALL_P (insn)" 11527 "* return ix86_output_call_insn (insn, operands[1]);" 11528 [(set_attr "type" "callv")]) 11529 11530(define_expand "call_value_pop" 11531 [(parallel [(set (match_operand 0 "" "") 11532 (call (match_operand:QI 1 "" "") 11533 (match_operand:SI 2 "" ""))) 11534 (set (reg:SI SP_REG) 11535 (plus:SI (reg:SI SP_REG) 11536 (match_operand:SI 4 "" "")))])] 11537 "!TARGET_64BIT" 11538{ 11539 ix86_expand_call (operands[0], operands[1], operands[2], 11540 operands[3], operands[4], false); 11541 DONE; 11542}) 11543 11544(define_insn_and_split "*call_value_pop_vzeroupper" 11545 [(set (match_operand 0 "" "") 11546 (call (mem:QI (match_operand:SI 1 "call_insn_operand" "lzm")) 11547 (match_operand 2 "" ""))) 11548 (set (reg:SI SP_REG) 11549 (plus:SI (reg:SI SP_REG) 11550 (match_operand:SI 3 "immediate_operand" "i"))) 11551 (unspec [(match_operand 4 "const_int_operand" "")] 11552 UNSPEC_CALL_NEEDS_VZEROUPPER)] 11553 "TARGET_VZEROUPPER && !TARGET_64BIT && !SIBLING_CALL_P (insn)" 11554 "#" 11555 "&& reload_completed" 11556 [(const_int 0)] 11557 "ix86_split_call_vzeroupper (curr_insn, operands[4]); DONE;" 11558 [(set_attr "type" "callv")]) 11559 11560(define_insn "*call_value_pop" 11561 [(set (match_operand 0 "" "") 11562 (call (mem:QI (match_operand:SI 1 "call_insn_operand" "lzm")) 11563 (match_operand 2 "" ""))) 11564 (set (reg:SI SP_REG) 11565 (plus:SI (reg:SI SP_REG) 11566 (match_operand:SI 3 "immediate_operand" "i")))] 11567 "!TARGET_64BIT && !SIBLING_CALL_P (insn)" 11568 "* return ix86_output_call_insn (insn, operands[1]);" 11569 [(set_attr "type" "callv")]) 11570 11571(define_insn_and_split "*sibcall_value_pop_vzeroupper" 11572 [(set (match_operand 0 "" "") 11573 (call (mem:QI (match_operand:SI 1 "sibcall_insn_operand" "Uz")) 11574 (match_operand 2 "" ""))) 11575 (set (reg:SI SP_REG) 11576 (plus:SI (reg:SI SP_REG) 11577 (match_operand:SI 3 "immediate_operand" "i"))) 11578 (unspec [(match_operand 4 "const_int_operand" "")] 11579 UNSPEC_CALL_NEEDS_VZEROUPPER)] 11580 "TARGET_VZEROUPPER && !TARGET_64BIT && SIBLING_CALL_P (insn)" 11581 "#" 11582 "&& reload_completed" 11583 [(const_int 0)] 11584 "ix86_split_call_vzeroupper (curr_insn, operands[4]); DONE;" 11585 [(set_attr "type" "callv")]) 11586 11587(define_insn "*sibcall_value_pop" 11588 [(set (match_operand 0 "" "") 11589 (call (mem:QI (match_operand:SI 1 "sibcall_insn_operand" "Uz")) 11590 (match_operand 2 "" ""))) 11591 (set (reg:SI SP_REG) 11592 (plus:SI (reg:SI SP_REG) 11593 (match_operand:SI 3 "immediate_operand" "i")))] 11594 "!TARGET_64BIT && SIBLING_CALL_P (insn)" 11595 "* return ix86_output_call_insn (insn, operands[1]);" 11596 [(set_attr "type" "callv")]) 11597 11598;; Call subroutine returning any type. 11599 11600(define_expand "untyped_call" 11601 [(parallel [(call (match_operand 0 "" "") 11602 (const_int 0)) 11603 (match_operand 1 "" "") 11604 (match_operand 2 "" "")])] 11605 "" 11606{ 11607 int i; 11608 11609 /* In order to give reg-stack an easier job in validating two 11610 coprocessor registers as containing a possible return value, 11611 simply pretend the untyped call returns a complex long double 11612 value. 11613 11614 We can't use SSE_REGPARM_MAX here since callee is unprototyped 11615 and should have the default ABI. */ 11616 11617 ix86_expand_call ((TARGET_FLOAT_RETURNS_IN_80387 11618 ? gen_rtx_REG (XCmode, FIRST_FLOAT_REG) : NULL), 11619 operands[0], const0_rtx, 11620 GEN_INT ((TARGET_64BIT 11621 ? (ix86_abi == SYSV_ABI 11622 ? X86_64_SSE_REGPARM_MAX 11623 : X86_64_MS_SSE_REGPARM_MAX) 11624 : X86_32_SSE_REGPARM_MAX) 11625 - 1), 11626 NULL, false); 11627 11628 for (i = 0; i < XVECLEN (operands[2], 0); i++) 11629 { 11630 rtx set = XVECEXP (operands[2], 0, i); 11631 emit_move_insn (SET_DEST (set), SET_SRC (set)); 11632 } 11633 11634 /* The optimizer does not know that the call sets the function value 11635 registers we stored in the result block. We avoid problems by 11636 claiming that all hard registers are used and clobbered at this 11637 point. */ 11638 emit_insn (gen_blockage ()); 11639 11640 DONE; 11641}) 11642 11643;; Prologue and epilogue instructions 11644 11645;; UNSPEC_VOLATILE is considered to use and clobber all hard registers and 11646;; all of memory. This blocks insns from being moved across this point. 11647 11648(define_insn "blockage" 11649 [(unspec_volatile [(const_int 0)] UNSPECV_BLOCKAGE)] 11650 "" 11651 "" 11652 [(set_attr "length" "0")]) 11653 11654;; Do not schedule instructions accessing memory across this point. 11655 11656(define_expand "memory_blockage" 11657 [(set (match_dup 0) 11658 (unspec:BLK [(match_dup 0)] UNSPEC_MEMORY_BLOCKAGE))] 11659 "" 11660{ 11661 operands[0] = gen_rtx_MEM (BLKmode, gen_rtx_SCRATCH (Pmode)); 11662 MEM_VOLATILE_P (operands[0]) = 1; 11663}) 11664 11665(define_insn "*memory_blockage" 11666 [(set (match_operand:BLK 0 "" "") 11667 (unspec:BLK [(match_dup 0)] UNSPEC_MEMORY_BLOCKAGE))] 11668 "" 11669 "" 11670 [(set_attr "length" "0")]) 11671 11672;; As USE insns aren't meaningful after reload, this is used instead 11673;; to prevent deleting instructions setting registers for PIC code 11674(define_insn "prologue_use" 11675 [(unspec_volatile [(match_operand 0 "" "")] UNSPECV_PROLOGUE_USE)] 11676 "" 11677 "" 11678 [(set_attr "length" "0")]) 11679 11680;; Insn emitted into the body of a function to return from a function. 11681;; This is only done if the function's epilogue is known to be simple. 11682;; See comments for ix86_can_use_return_insn_p in i386.c. 11683 11684(define_expand "return" 11685 [(simple_return)] 11686 "ix86_can_use_return_insn_p ()" 11687{ 11688 ix86_maybe_emit_epilogue_vzeroupper (); 11689 if (crtl->args.pops_args) 11690 { 11691 rtx popc = GEN_INT (crtl->args.pops_args); 11692 emit_jump_insn (gen_simple_return_pop_internal (popc)); 11693 DONE; 11694 } 11695}) 11696 11697;; We need to disable this for TARGET_SEH, as otherwise 11698;; shrink-wrapped prologue gets enabled too. This might exceed 11699;; the maximum size of prologue in unwind information. 11700 11701(define_expand "simple_return" 11702 [(simple_return)] 11703 "!TARGET_SEH" 11704{ 11705 ix86_maybe_emit_epilogue_vzeroupper (); 11706 if (crtl->args.pops_args) 11707 { 11708 rtx popc = GEN_INT (crtl->args.pops_args); 11709 emit_jump_insn (gen_simple_return_pop_internal (popc)); 11710 DONE; 11711 } 11712}) 11713 11714(define_insn "simple_return_internal" 11715 [(simple_return)] 11716 "reload_completed" 11717 "ret" 11718 [(set_attr "length" "1") 11719 (set_attr "atom_unit" "jeu") 11720 (set_attr "length_immediate" "0") 11721 (set_attr "modrm" "0")]) 11722 11723;; Used by x86_machine_dependent_reorg to avoid penalty on single byte RET 11724;; instruction Athlon and K8 have. 11725 11726(define_insn "simple_return_internal_long" 11727 [(simple_return) 11728 (unspec [(const_int 0)] UNSPEC_REP)] 11729 "reload_completed" 11730 "rep\;ret" 11731 [(set_attr "length" "2") 11732 (set_attr "atom_unit" "jeu") 11733 (set_attr "length_immediate" "0") 11734 (set_attr "prefix_rep" "1") 11735 (set_attr "modrm" "0")]) 11736 11737(define_insn "simple_return_pop_internal" 11738 [(simple_return) 11739 (use (match_operand:SI 0 "const_int_operand" ""))] 11740 "reload_completed" 11741 "ret\t%0" 11742 [(set_attr "length" "3") 11743 (set_attr "atom_unit" "jeu") 11744 (set_attr "length_immediate" "2") 11745 (set_attr "modrm" "0")]) 11746 11747(define_insn "simple_return_indirect_internal" 11748 [(simple_return) 11749 (use (match_operand:SI 0 "register_operand" "r"))] 11750 "reload_completed" 11751 "jmp\t%A0" 11752 [(set_attr "type" "ibr") 11753 (set_attr "length_immediate" "0")]) 11754 11755(define_insn "nop" 11756 [(const_int 0)] 11757 "" 11758 "nop" 11759 [(set_attr "length" "1") 11760 (set_attr "length_immediate" "0") 11761 (set_attr "modrm" "0")]) 11762 11763;; Generate nops. Operand 0 is the number of nops, up to 8. 11764(define_insn "nops" 11765 [(unspec_volatile [(match_operand 0 "const_int_operand" "")] 11766 UNSPECV_NOPS)] 11767 "reload_completed" 11768{ 11769 int num = INTVAL (operands[0]); 11770 11771 gcc_assert (num >= 1 && num <= 8); 11772 11773 while (num--) 11774 fputs ("\tnop\n", asm_out_file); 11775 11776 return ""; 11777} 11778 [(set (attr "length") (symbol_ref "INTVAL (operands[0])")) 11779 (set_attr "length_immediate" "0") 11780 (set_attr "modrm" "0")]) 11781 11782;; Pad to 16-byte boundary, max skip in op0. Used to avoid 11783;; branch prediction penalty for the third jump in a 16-byte 11784;; block on K8. 11785 11786(define_insn "pad" 11787 [(unspec_volatile [(match_operand 0 "" "")] UNSPECV_ALIGN)] 11788 "" 11789{ 11790#ifdef ASM_OUTPUT_MAX_SKIP_PAD 11791 ASM_OUTPUT_MAX_SKIP_PAD (asm_out_file, 4, (int)INTVAL (operands[0])); 11792#else 11793 /* It is tempting to use ASM_OUTPUT_ALIGN here, but we don't want to do that. 11794 The align insn is used to avoid 3 jump instructions in the row to improve 11795 branch prediction and the benefits hardly outweigh the cost of extra 8 11796 nops on the average inserted by full alignment pseudo operation. */ 11797#endif 11798 return ""; 11799} 11800 [(set_attr "length" "16")]) 11801 11802(define_expand "prologue" 11803 [(const_int 0)] 11804 "" 11805 "ix86_expand_prologue (); DONE;") 11806 11807(define_insn "set_got" 11808 [(set (match_operand:SI 0 "register_operand" "=r") 11809 (unspec:SI [(const_int 0)] UNSPEC_SET_GOT)) 11810 (clobber (reg:CC FLAGS_REG))] 11811 "!TARGET_64BIT" 11812 "* return output_set_got (operands[0], NULL_RTX);" 11813 [(set_attr "type" "multi") 11814 (set_attr "length" "12")]) 11815 11816(define_insn "set_got_labelled" 11817 [(set (match_operand:SI 0 "register_operand" "=r") 11818 (unspec:SI [(label_ref (match_operand 1 "" ""))] 11819 UNSPEC_SET_GOT)) 11820 (clobber (reg:CC FLAGS_REG))] 11821 "!TARGET_64BIT" 11822 "* return output_set_got (operands[0], operands[1]);" 11823 [(set_attr "type" "multi") 11824 (set_attr "length" "12")]) 11825 11826(define_insn "set_got_rex64" 11827 [(set (match_operand:DI 0 "register_operand" "=r") 11828 (unspec:DI [(const_int 0)] UNSPEC_SET_GOT))] 11829 "TARGET_64BIT" 11830 "lea{q}\t{_GLOBAL_OFFSET_TABLE_(%%rip), %0|%0, _GLOBAL_OFFSET_TABLE_[rip]}" 11831 [(set_attr "type" "lea") 11832 (set_attr "length_address" "4") 11833 (set_attr "mode" "DI")]) 11834 11835(define_insn "set_rip_rex64" 11836 [(set (match_operand:DI 0 "register_operand" "=r") 11837 (unspec:DI [(label_ref (match_operand 1 "" ""))] UNSPEC_SET_RIP))] 11838 "TARGET_64BIT" 11839 "lea{q}\t{%l1(%%rip), %0|%0, %l1[rip]}" 11840 [(set_attr "type" "lea") 11841 (set_attr "length_address" "4") 11842 (set_attr "mode" "DI")]) 11843 11844(define_insn "set_got_offset_rex64" 11845 [(set (match_operand:DI 0 "register_operand" "=r") 11846 (unspec:DI 11847 [(label_ref (match_operand 1 "" ""))] 11848 UNSPEC_SET_GOT_OFFSET))] 11849 "TARGET_LP64" 11850 "movabs{q}\t{$_GLOBAL_OFFSET_TABLE_-%l1, %0|%0, OFFSET FLAT:_GLOBAL_OFFSET_TABLE_-%l1}" 11851 [(set_attr "type" "imov") 11852 (set_attr "length_immediate" "0") 11853 (set_attr "length_address" "8") 11854 (set_attr "mode" "DI")]) 11855 11856(define_expand "epilogue" 11857 [(const_int 0)] 11858 "" 11859 "ix86_expand_epilogue (1); DONE;") 11860 11861(define_expand "sibcall_epilogue" 11862 [(const_int 0)] 11863 "" 11864 "ix86_expand_epilogue (0); DONE;") 11865 11866(define_expand "eh_return" 11867 [(use (match_operand 0 "register_operand" ""))] 11868 "" 11869{ 11870 rtx tmp, sa = EH_RETURN_STACKADJ_RTX, ra = operands[0]; 11871 11872 /* Tricky bit: we write the address of the handler to which we will 11873 be returning into someone else's stack frame, one word below the 11874 stack address we wish to restore. */ 11875 tmp = gen_rtx_PLUS (Pmode, arg_pointer_rtx, sa); 11876 tmp = plus_constant (tmp, -UNITS_PER_WORD); 11877 tmp = gen_rtx_MEM (Pmode, tmp); 11878 emit_move_insn (tmp, ra); 11879 11880 emit_jump_insn (gen_eh_return_internal ()); 11881 emit_barrier (); 11882 DONE; 11883}) 11884 11885(define_insn_and_split "eh_return_internal" 11886 [(eh_return)] 11887 "" 11888 "#" 11889 "epilogue_completed" 11890 [(const_int 0)] 11891 "ix86_expand_epilogue (2); DONE;") 11892 11893(define_insn "leave" 11894 [(set (reg:SI SP_REG) (plus:SI (reg:SI BP_REG) (const_int 4))) 11895 (set (reg:SI BP_REG) (mem:SI (reg:SI BP_REG))) 11896 (clobber (mem:BLK (scratch)))] 11897 "!TARGET_64BIT" 11898 "leave" 11899 [(set_attr "type" "leave")]) 11900 11901(define_insn "leave_rex64" 11902 [(set (reg:DI SP_REG) (plus:DI (reg:DI BP_REG) (const_int 8))) 11903 (set (reg:DI BP_REG) (mem:DI (reg:DI BP_REG))) 11904 (clobber (mem:BLK (scratch)))] 11905 "TARGET_64BIT" 11906 "leave" 11907 [(set_attr "type" "leave")]) 11908 11909;; Handle -fsplit-stack. 11910 11911(define_expand "split_stack_prologue" 11912 [(const_int 0)] 11913 "" 11914{ 11915 ix86_expand_split_stack_prologue (); 11916 DONE; 11917}) 11918 11919;; In order to support the call/return predictor, we use a return 11920;; instruction which the middle-end doesn't see. 11921(define_insn "split_stack_return" 11922 [(unspec_volatile [(match_operand:SI 0 "const_int_operand" "")] 11923 UNSPECV_SPLIT_STACK_RETURN)] 11924 "" 11925{ 11926 if (operands[0] == const0_rtx) 11927 return "ret"; 11928 else 11929 return "ret\t%0"; 11930} 11931 [(set_attr "atom_unit" "jeu") 11932 (set_attr "modrm" "0") 11933 (set (attr "length") 11934 (if_then_else (match_operand:SI 0 "const0_operand" "") 11935 (const_int 1) 11936 (const_int 3))) 11937 (set (attr "length_immediate") 11938 (if_then_else (match_operand:SI 0 "const0_operand" "") 11939 (const_int 0) 11940 (const_int 2)))]) 11941 11942;; If there are operand 0 bytes available on the stack, jump to 11943;; operand 1. 11944 11945(define_expand "split_stack_space_check" 11946 [(set (pc) (if_then_else 11947 (ltu (minus (reg SP_REG) 11948 (match_operand 0 "register_operand" "")) 11949 (unspec [(const_int 0)] UNSPEC_STACK_CHECK)) 11950 (label_ref (match_operand 1 "" "")) 11951 (pc)))] 11952 "" 11953{ 11954 rtx reg, size, limit; 11955 11956 reg = gen_reg_rtx (Pmode); 11957 size = force_reg (Pmode, operands[0]); 11958 emit_insn (gen_sub3_insn (reg, stack_pointer_rtx, size)); 11959 limit = gen_rtx_UNSPEC (Pmode, gen_rtvec (1, const0_rtx), 11960 UNSPEC_STACK_CHECK); 11961 limit = gen_rtx_MEM (Pmode, gen_rtx_CONST (Pmode, limit)); 11962 ix86_expand_branch (GEU, reg, limit, operands[1]); 11963 11964 DONE; 11965}) 11966 11967;; Bit manipulation instructions. 11968 11969(define_expand "ffs<mode>2" 11970 [(set (match_dup 2) (const_int -1)) 11971 (parallel [(set (reg:CCZ FLAGS_REG) 11972 (compare:CCZ 11973 (match_operand:SWI48 1 "nonimmediate_operand" "") 11974 (const_int 0))) 11975 (set (match_operand:SWI48 0 "register_operand" "") 11976 (ctz:SWI48 (match_dup 1)))]) 11977 (set (match_dup 0) (if_then_else:SWI48 11978 (eq (reg:CCZ FLAGS_REG) (const_int 0)) 11979 (match_dup 2) 11980 (match_dup 0))) 11981 (parallel [(set (match_dup 0) (plus:SWI48 (match_dup 0) (const_int 1))) 11982 (clobber (reg:CC FLAGS_REG))])] 11983 "" 11984{ 11985 if (<MODE>mode == SImode && !TARGET_CMOVE) 11986 { 11987 emit_insn (gen_ffssi2_no_cmove (operands[0], operands [1])); 11988 DONE; 11989 } 11990 operands[2] = gen_reg_rtx (<MODE>mode); 11991}) 11992 11993(define_insn_and_split "ffssi2_no_cmove" 11994 [(set (match_operand:SI 0 "register_operand" "=r") 11995 (ffs:SI (match_operand:SI 1 "nonimmediate_operand" "rm"))) 11996 (clobber (match_scratch:SI 2 "=&q")) 11997 (clobber (reg:CC FLAGS_REG))] 11998 "!TARGET_CMOVE" 11999 "#" 12000 "&& reload_completed" 12001 [(parallel [(set (reg:CCZ FLAGS_REG) 12002 (compare:CCZ (match_dup 1) (const_int 0))) 12003 (set (match_dup 0) (ctz:SI (match_dup 1)))]) 12004 (set (strict_low_part (match_dup 3)) 12005 (eq:QI (reg:CCZ FLAGS_REG) (const_int 0))) 12006 (parallel [(set (match_dup 2) (neg:SI (match_dup 2))) 12007 (clobber (reg:CC FLAGS_REG))]) 12008 (parallel [(set (match_dup 0) (ior:SI (match_dup 0) (match_dup 2))) 12009 (clobber (reg:CC FLAGS_REG))]) 12010 (parallel [(set (match_dup 0) (plus:SI (match_dup 0) (const_int 1))) 12011 (clobber (reg:CC FLAGS_REG))])] 12012{ 12013 operands[3] = gen_lowpart (QImode, operands[2]); 12014 ix86_expand_clear (operands[2]); 12015}) 12016 12017(define_insn "*ffs<mode>_1" 12018 [(set (reg:CCZ FLAGS_REG) 12019 (compare:CCZ (match_operand:SWI48 1 "nonimmediate_operand" "rm") 12020 (const_int 0))) 12021 (set (match_operand:SWI48 0 "register_operand" "=r") 12022 (ctz:SWI48 (match_dup 1)))] 12023 "" 12024 "bsf{<imodesuffix>}\t{%1, %0|%0, %1}" 12025 [(set_attr "type" "alu1") 12026 (set_attr "prefix_0f" "1") 12027 (set_attr "mode" "<MODE>")]) 12028 12029(define_insn "ctz<mode>2" 12030 [(set (match_operand:SWI248 0 "register_operand" "=r") 12031 (ctz:SWI248 (match_operand:SWI248 1 "nonimmediate_operand" "rm"))) 12032 (clobber (reg:CC FLAGS_REG))] 12033 "" 12034{ 12035 if (TARGET_BMI) 12036 return "tzcnt{<imodesuffix>}\t{%1, %0|%0, %1}"; 12037 else 12038 return "bsf{<imodesuffix>}\t{%1, %0|%0, %1}"; 12039} 12040 [(set_attr "type" "alu1") 12041 (set_attr "prefix_0f" "1") 12042 (set (attr "prefix_rep") (symbol_ref "TARGET_BMI")) 12043 (set_attr "mode" "<MODE>")]) 12044 12045(define_expand "clz<mode>2" 12046 [(parallel 12047 [(set (match_operand:SWI248 0 "register_operand" "") 12048 (minus:SWI248 12049 (match_dup 2) 12050 (clz:SWI248 (match_operand:SWI248 1 "nonimmediate_operand" "")))) 12051 (clobber (reg:CC FLAGS_REG))]) 12052 (parallel 12053 [(set (match_dup 0) (xor:SWI248 (match_dup 0) (match_dup 2))) 12054 (clobber (reg:CC FLAGS_REG))])] 12055 "" 12056{ 12057 if (TARGET_LZCNT) 12058 { 12059 emit_insn (gen_clz<mode>2_lzcnt (operands[0], operands[1])); 12060 DONE; 12061 } 12062 operands[2] = GEN_INT (GET_MODE_BITSIZE (<MODE>mode)-1); 12063}) 12064 12065(define_insn "clz<mode>2_lzcnt" 12066 [(set (match_operand:SWI248 0 "register_operand" "=r") 12067 (clz:SWI248 (match_operand:SWI248 1 "nonimmediate_operand" "rm"))) 12068 (clobber (reg:CC FLAGS_REG))] 12069 "TARGET_LZCNT" 12070 "lzcnt{<imodesuffix>}\t{%1, %0|%0, %1}" 12071 [(set_attr "prefix_rep" "1") 12072 (set_attr "type" "bitmanip") 12073 (set_attr "mode" "<MODE>")]) 12074 12075;; BMI instructions. 12076(define_insn "*bmi_andn_<mode>" 12077 [(set (match_operand:SWI48 0 "register_operand" "=r") 12078 (and:SWI48 12079 (not:SWI48 12080 (match_operand:SWI48 1 "register_operand" "r")) 12081 (match_operand:SWI48 2 "nonimmediate_operand" "rm"))) 12082 (clobber (reg:CC FLAGS_REG))] 12083 "TARGET_BMI" 12084 "andn\t{%2, %1, %0|%0, %1, %2}" 12085 [(set_attr "type" "bitmanip") 12086 (set_attr "mode" "<MODE>")]) 12087 12088(define_insn "bmi_bextr_<mode>" 12089 [(set (match_operand:SWI48 0 "register_operand" "=r") 12090 (unspec:SWI48 [(match_operand:SWI48 1 "register_operand" "r") 12091 (match_operand:SWI48 2 "nonimmediate_operand" "rm")] 12092 UNSPEC_BEXTR)) 12093 (clobber (reg:CC FLAGS_REG))] 12094 "TARGET_BMI" 12095 "bextr\t{%2, %1, %0|%0, %1, %2}" 12096 [(set_attr "type" "bitmanip") 12097 (set_attr "mode" "<MODE>")]) 12098 12099(define_insn "*bmi_blsi_<mode>" 12100 [(set (match_operand:SWI48 0 "register_operand" "=r") 12101 (and:SWI48 12102 (neg:SWI48 12103 (match_operand:SWI48 1 "nonimmediate_operand" "rm")) 12104 (match_dup 1))) 12105 (clobber (reg:CC FLAGS_REG))] 12106 "TARGET_BMI" 12107 "blsi\t{%1, %0|%0, %1}" 12108 [(set_attr "type" "bitmanip") 12109 (set_attr "mode" "<MODE>")]) 12110 12111(define_insn "*bmi_blsmsk_<mode>" 12112 [(set (match_operand:SWI48 0 "register_operand" "=r") 12113 (xor:SWI48 12114 (plus:SWI48 12115 (match_operand:SWI48 1 "nonimmediate_operand" "rm") 12116 (const_int -1)) 12117 (match_dup 1))) 12118 (clobber (reg:CC FLAGS_REG))] 12119 "TARGET_BMI" 12120 "blsmsk\t{%1, %0|%0, %1}" 12121 [(set_attr "type" "bitmanip") 12122 (set_attr "mode" "<MODE>")]) 12123 12124(define_insn "*bmi_blsr_<mode>" 12125 [(set (match_operand:SWI48 0 "register_operand" "=r") 12126 (and:SWI48 12127 (plus:SWI48 12128 (match_operand:SWI48 1 "nonimmediate_operand" "rm") 12129 (const_int -1)) 12130 (match_dup 1))) 12131 (clobber (reg:CC FLAGS_REG))] 12132 "TARGET_BMI" 12133 "blsr\t{%1, %0|%0, %1}" 12134 [(set_attr "type" "bitmanip") 12135 (set_attr "mode" "<MODE>")]) 12136 12137;; BMI2 instructions. 12138(define_insn "bmi2_bzhi_<mode>3" 12139 [(set (match_operand:SWI48 0 "register_operand" "=r") 12140 (and:SWI48 (match_operand:SWI48 1 "register_operand" "r") 12141 (lshiftrt:SWI48 (const_int -1) 12142 (match_operand:SWI48 2 "nonimmediate_operand" "rm")))) 12143 (clobber (reg:CC FLAGS_REG))] 12144 "TARGET_BMI2" 12145 "bzhi\t{%2, %1, %0|%0, %1, %2}" 12146 [(set_attr "type" "bitmanip") 12147 (set_attr "prefix" "vex") 12148 (set_attr "mode" "<MODE>")]) 12149 12150(define_insn "bmi2_pdep_<mode>3" 12151 [(set (match_operand:SWI48 0 "register_operand" "=r") 12152 (unspec:SWI48 [(match_operand:SWI48 1 "register_operand" "r") 12153 (match_operand:SWI48 2 "nonimmediate_operand" "rm")] 12154 UNSPEC_PDEP))] 12155 "TARGET_BMI2" 12156 "pdep\t{%2, %1, %0|%0, %1, %2}" 12157 [(set_attr "type" "bitmanip") 12158 (set_attr "prefix" "vex") 12159 (set_attr "mode" "<MODE>")]) 12160 12161(define_insn "bmi2_pext_<mode>3" 12162 [(set (match_operand:SWI48 0 "register_operand" "=r") 12163 (unspec:SWI48 [(match_operand:SWI48 1 "register_operand" "r") 12164 (match_operand:SWI48 2 "nonimmediate_operand" "rm")] 12165 UNSPEC_PEXT))] 12166 "TARGET_BMI2" 12167 "pext\t{%2, %1, %0|%0, %1, %2}" 12168 [(set_attr "type" "bitmanip") 12169 (set_attr "prefix" "vex") 12170 (set_attr "mode" "<MODE>")]) 12171 12172;; TBM instructions. 12173(define_insn "tbm_bextri_<mode>" 12174 [(set (match_operand:SWI48 0 "register_operand" "=r") 12175 (zero_extract:SWI48 12176 (match_operand:SWI48 1 "nonimmediate_operand" "rm") 12177 (match_operand:SWI48 2 "const_0_to_255_operand" "n") 12178 (match_operand:SWI48 3 "const_0_to_255_operand" "n"))) 12179 (clobber (reg:CC FLAGS_REG))] 12180 "TARGET_TBM" 12181{ 12182 operands[2] = GEN_INT (INTVAL (operands[2]) << 8 | INTVAL (operands[3])); 12183 return "bextr\t{%2, %1, %0|%0, %1, %2}"; 12184} 12185 [(set_attr "type" "bitmanip") 12186 (set_attr "mode" "<MODE>")]) 12187 12188(define_insn "*tbm_blcfill_<mode>" 12189 [(set (match_operand:SWI48 0 "register_operand" "=r") 12190 (and:SWI48 12191 (plus:SWI48 12192 (match_operand:SWI48 1 "nonimmediate_operand" "rm") 12193 (const_int 1)) 12194 (match_dup 1))) 12195 (clobber (reg:CC FLAGS_REG))] 12196 "TARGET_TBM" 12197 "blcfill\t{%1, %0|%0, %1}" 12198 [(set_attr "type" "bitmanip") 12199 (set_attr "mode" "<MODE>")]) 12200 12201(define_insn "*tbm_blci_<mode>" 12202 [(set (match_operand:SWI48 0 "register_operand" "=r") 12203 (ior:SWI48 12204 (not:SWI48 12205 (plus:SWI48 12206 (match_operand:SWI48 1 "nonimmediate_operand" "rm") 12207 (const_int 1))) 12208 (match_dup 1))) 12209 (clobber (reg:CC FLAGS_REG))] 12210 "TARGET_TBM" 12211 "blci\t{%1, %0|%0, %1}" 12212 [(set_attr "type" "bitmanip") 12213 (set_attr "mode" "<MODE>")]) 12214 12215(define_insn "*tbm_blcic_<mode>" 12216 [(set (match_operand:SWI48 0 "register_operand" "=r") 12217 (and:SWI48 12218 (plus:SWI48 12219 (match_operand:SWI48 1 "nonimmediate_operand" "rm") 12220 (const_int 1)) 12221 (not:SWI48 12222 (match_dup 1)))) 12223 (clobber (reg:CC FLAGS_REG))] 12224 "TARGET_TBM" 12225 "blcic\t{%1, %0|%0, %1}" 12226 [(set_attr "type" "bitmanip") 12227 (set_attr "mode" "<MODE>")]) 12228 12229(define_insn "*tbm_blcmsk_<mode>" 12230 [(set (match_operand:SWI48 0 "register_operand" "=r") 12231 (xor:SWI48 12232 (plus:SWI48 12233 (match_operand:SWI48 1 "nonimmediate_operand" "rm") 12234 (const_int 1)) 12235 (match_dup 1))) 12236 (clobber (reg:CC FLAGS_REG))] 12237 "TARGET_TBM" 12238 "blcmsk\t{%1, %0|%0, %1}" 12239 [(set_attr "type" "bitmanip") 12240 (set_attr "mode" "<MODE>")]) 12241 12242(define_insn "*tbm_blcs_<mode>" 12243 [(set (match_operand:SWI48 0 "register_operand" "=r") 12244 (ior:SWI48 12245 (plus:SWI48 12246 (match_operand:SWI48 1 "nonimmediate_operand" "rm") 12247 (const_int 1)) 12248 (match_dup 1))) 12249 (clobber (reg:CC FLAGS_REG))] 12250 "TARGET_TBM" 12251 "blcs\t{%1, %0|%0, %1}" 12252 [(set_attr "type" "bitmanip") 12253 (set_attr "mode" "<MODE>")]) 12254 12255(define_insn "*tbm_blsfill_<mode>" 12256 [(set (match_operand:SWI48 0 "register_operand" "=r") 12257 (ior:SWI48 12258 (plus:SWI48 12259 (match_operand:SWI48 1 "nonimmediate_operand" "rm") 12260 (const_int -1)) 12261 (match_dup 1))) 12262 (clobber (reg:CC FLAGS_REG))] 12263 "TARGET_TBM" 12264 "blsfill\t{%1, %0|%0, %1}" 12265 [(set_attr "type" "bitmanip") 12266 (set_attr "mode" "<MODE>")]) 12267 12268(define_insn "*tbm_blsic_<mode>" 12269 [(set (match_operand:SWI48 0 "register_operand" "=r") 12270 (ior:SWI48 12271 (plus:SWI48 12272 (match_operand:SWI48 1 "nonimmediate_operand" "rm") 12273 (const_int -1)) 12274 (not:SWI48 12275 (match_dup 1)))) 12276 (clobber (reg:CC FLAGS_REG))] 12277 "TARGET_TBM" 12278 "blsic\t{%1, %0|%0, %1}" 12279 [(set_attr "type" "bitmanip") 12280 (set_attr "mode" "<MODE>")]) 12281 12282(define_insn "*tbm_t1mskc_<mode>" 12283 [(set (match_operand:SWI48 0 "register_operand" "=r") 12284 (ior:SWI48 12285 (plus:SWI48 12286 (match_operand:SWI48 1 "nonimmediate_operand" "rm") 12287 (const_int 1)) 12288 (not:SWI48 12289 (match_dup 1)))) 12290 (clobber (reg:CC FLAGS_REG))] 12291 "TARGET_TBM" 12292 "t1mskc\t{%1, %0|%0, %1}" 12293 [(set_attr "type" "bitmanip") 12294 (set_attr "mode" "<MODE>")]) 12295 12296(define_insn "*tbm_tzmsk_<mode>" 12297 [(set (match_operand:SWI48 0 "register_operand" "=r") 12298 (and:SWI48 12299 (plus:SWI48 12300 (match_operand:SWI48 1 "nonimmediate_operand" "rm") 12301 (const_int -1)) 12302 (not:SWI48 12303 (match_dup 1)))) 12304 (clobber (reg:CC FLAGS_REG))] 12305 "TARGET_TBM" 12306 "tzmsk\t{%1, %0|%0, %1}" 12307 [(set_attr "type" "bitmanip") 12308 (set_attr "mode" "<MODE>")]) 12309 12310(define_insn "bsr_rex64" 12311 [(set (match_operand:DI 0 "register_operand" "=r") 12312 (minus:DI (const_int 63) 12313 (clz:DI (match_operand:DI 1 "nonimmediate_operand" "rm")))) 12314 (clobber (reg:CC FLAGS_REG))] 12315 "TARGET_64BIT" 12316 "bsr{q}\t{%1, %0|%0, %1}" 12317 [(set_attr "type" "alu1") 12318 (set_attr "prefix_0f" "1") 12319 (set_attr "mode" "DI")]) 12320 12321(define_insn "bsr" 12322 [(set (match_operand:SI 0 "register_operand" "=r") 12323 (minus:SI (const_int 31) 12324 (clz:SI (match_operand:SI 1 "nonimmediate_operand" "rm")))) 12325 (clobber (reg:CC FLAGS_REG))] 12326 "" 12327 "bsr{l}\t{%1, %0|%0, %1}" 12328 [(set_attr "type" "alu1") 12329 (set_attr "prefix_0f" "1") 12330 (set_attr "mode" "SI")]) 12331 12332(define_insn "*bsrhi" 12333 [(set (match_operand:HI 0 "register_operand" "=r") 12334 (minus:HI (const_int 15) 12335 (clz:HI (match_operand:HI 1 "nonimmediate_operand" "rm")))) 12336 (clobber (reg:CC FLAGS_REG))] 12337 "" 12338 "bsr{w}\t{%1, %0|%0, %1}" 12339 [(set_attr "type" "alu1") 12340 (set_attr "prefix_0f" "1") 12341 (set_attr "mode" "HI")]) 12342 12343(define_insn "popcount<mode>2" 12344 [(set (match_operand:SWI248 0 "register_operand" "=r") 12345 (popcount:SWI248 12346 (match_operand:SWI248 1 "nonimmediate_operand" "rm"))) 12347 (clobber (reg:CC FLAGS_REG))] 12348 "TARGET_POPCNT" 12349{ 12350#if TARGET_MACHO 12351 return "popcnt\t{%1, %0|%0, %1}"; 12352#else 12353 return "popcnt{<imodesuffix>}\t{%1, %0|%0, %1}"; 12354#endif 12355} 12356 [(set_attr "prefix_rep" "1") 12357 (set_attr "type" "bitmanip") 12358 (set_attr "mode" "<MODE>")]) 12359 12360(define_insn "*popcount<mode>2_cmp" 12361 [(set (reg FLAGS_REG) 12362 (compare 12363 (popcount:SWI248 12364 (match_operand:SWI248 1 "nonimmediate_operand" "rm")) 12365 (const_int 0))) 12366 (set (match_operand:SWI248 0 "register_operand" "=r") 12367 (popcount:SWI248 (match_dup 1)))] 12368 "TARGET_POPCNT && ix86_match_ccmode (insn, CCZmode)" 12369{ 12370#if TARGET_MACHO 12371 return "popcnt\t{%1, %0|%0, %1}"; 12372#else 12373 return "popcnt{<imodesuffix>}\t{%1, %0|%0, %1}"; 12374#endif 12375} 12376 [(set_attr "prefix_rep" "1") 12377 (set_attr "type" "bitmanip") 12378 (set_attr "mode" "<MODE>")]) 12379 12380(define_insn "*popcountsi2_cmp_zext" 12381 [(set (reg FLAGS_REG) 12382 (compare 12383 (popcount:SI (match_operand:SI 1 "nonimmediate_operand" "rm")) 12384 (const_int 0))) 12385 (set (match_operand:DI 0 "register_operand" "=r") 12386 (zero_extend:DI(popcount:SI (match_dup 1))))] 12387 "TARGET_64BIT && TARGET_POPCNT && ix86_match_ccmode (insn, CCZmode)" 12388{ 12389#if TARGET_MACHO 12390 return "popcnt\t{%1, %0|%0, %1}"; 12391#else 12392 return "popcnt{l}\t{%1, %0|%0, %1}"; 12393#endif 12394} 12395 [(set_attr "prefix_rep" "1") 12396 (set_attr "type" "bitmanip") 12397 (set_attr "mode" "SI")]) 12398 12399(define_expand "bswap<mode>2" 12400 [(set (match_operand:SWI48 0 "register_operand" "") 12401 (bswap:SWI48 (match_operand:SWI48 1 "register_operand" "")))] 12402 "" 12403{ 12404 if (<MODE>mode == SImode && !(TARGET_BSWAP || TARGET_MOVBE)) 12405 { 12406 rtx x = operands[0]; 12407 12408 emit_move_insn (x, operands[1]); 12409 emit_insn (gen_bswaphi_lowpart (gen_lowpart (HImode, x))); 12410 emit_insn (gen_rotlsi3 (x, x, GEN_INT (16))); 12411 emit_insn (gen_bswaphi_lowpart (gen_lowpart (HImode, x))); 12412 DONE; 12413 } 12414}) 12415 12416(define_insn "*bswap<mode>2_movbe" 12417 [(set (match_operand:SWI48 0 "nonimmediate_operand" "=r,r,m") 12418 (bswap:SWI48 (match_operand:SWI48 1 "nonimmediate_operand" "0,m,r")))] 12419 "TARGET_MOVBE 12420 && !(MEM_P (operands[0]) && MEM_P (operands[1]))" 12421 "@ 12422 bswap\t%0 12423 movbe\t{%1, %0|%0, %1} 12424 movbe\t{%1, %0|%0, %1}" 12425 [(set_attr "type" "bitmanip,imov,imov") 12426 (set_attr "modrm" "0,1,1") 12427 (set_attr "prefix_0f" "*,1,1") 12428 (set_attr "prefix_extra" "*,1,1") 12429 (set_attr "mode" "<MODE>")]) 12430 12431(define_insn "*bswap<mode>2_1" 12432 [(set (match_operand:SWI48 0 "register_operand" "=r") 12433 (bswap:SWI48 (match_operand:SWI48 1 "register_operand" "0")))] 12434 "TARGET_BSWAP" 12435 "bswap\t%0" 12436 [(set_attr "type" "bitmanip") 12437 (set_attr "modrm" "0") 12438 (set_attr "mode" "<MODE>")]) 12439 12440(define_insn "*bswaphi_lowpart_1" 12441 [(set (strict_low_part (match_operand:HI 0 "register_operand" "+Q,r")) 12442 (bswap:HI (match_dup 0))) 12443 (clobber (reg:CC FLAGS_REG))] 12444 "TARGET_USE_XCHGB || optimize_function_for_size_p (cfun)" 12445 "@ 12446 xchg{b}\t{%h0, %b0|%b0, %h0} 12447 rol{w}\t{$8, %0|%0, 8}" 12448 [(set_attr "length" "2,4") 12449 (set_attr "mode" "QI,HI")]) 12450 12451(define_insn "bswaphi_lowpart" 12452 [(set (strict_low_part (match_operand:HI 0 "register_operand" "+r")) 12453 (bswap:HI (match_dup 0))) 12454 (clobber (reg:CC FLAGS_REG))] 12455 "" 12456 "rol{w}\t{$8, %0|%0, 8}" 12457 [(set_attr "length" "4") 12458 (set_attr "mode" "HI")]) 12459 12460(define_expand "paritydi2" 12461 [(set (match_operand:DI 0 "register_operand" "") 12462 (parity:DI (match_operand:DI 1 "register_operand" "")))] 12463 "! TARGET_POPCNT" 12464{ 12465 rtx scratch = gen_reg_rtx (QImode); 12466 rtx cond; 12467 12468 emit_insn (gen_paritydi2_cmp (NULL_RTX, NULL_RTX, 12469 NULL_RTX, operands[1])); 12470 12471 cond = gen_rtx_fmt_ee (ORDERED, QImode, 12472 gen_rtx_REG (CCmode, FLAGS_REG), 12473 const0_rtx); 12474 emit_insn (gen_rtx_SET (VOIDmode, scratch, cond)); 12475 12476 if (TARGET_64BIT) 12477 emit_insn (gen_zero_extendqidi2 (operands[0], scratch)); 12478 else 12479 { 12480 rtx tmp = gen_reg_rtx (SImode); 12481 12482 emit_insn (gen_zero_extendqisi2 (tmp, scratch)); 12483 emit_insn (gen_zero_extendsidi2 (operands[0], tmp)); 12484 } 12485 DONE; 12486}) 12487 12488(define_expand "paritysi2" 12489 [(set (match_operand:SI 0 "register_operand" "") 12490 (parity:SI (match_operand:SI 1 "register_operand" "")))] 12491 "! TARGET_POPCNT" 12492{ 12493 rtx scratch = gen_reg_rtx (QImode); 12494 rtx cond; 12495 12496 emit_insn (gen_paritysi2_cmp (NULL_RTX, NULL_RTX, operands[1])); 12497 12498 cond = gen_rtx_fmt_ee (ORDERED, QImode, 12499 gen_rtx_REG (CCmode, FLAGS_REG), 12500 const0_rtx); 12501 emit_insn (gen_rtx_SET (VOIDmode, scratch, cond)); 12502 12503 emit_insn (gen_zero_extendqisi2 (operands[0], scratch)); 12504 DONE; 12505}) 12506 12507(define_insn_and_split "paritydi2_cmp" 12508 [(set (reg:CC FLAGS_REG) 12509 (unspec:CC [(match_operand:DI 3 "register_operand" "0")] 12510 UNSPEC_PARITY)) 12511 (clobber (match_scratch:DI 0 "=r")) 12512 (clobber (match_scratch:SI 1 "=&r")) 12513 (clobber (match_scratch:HI 2 "=Q"))] 12514 "! TARGET_POPCNT" 12515 "#" 12516 "&& reload_completed" 12517 [(parallel 12518 [(set (match_dup 1) 12519 (xor:SI (match_dup 1) (match_dup 4))) 12520 (clobber (reg:CC FLAGS_REG))]) 12521 (parallel 12522 [(set (reg:CC FLAGS_REG) 12523 (unspec:CC [(match_dup 1)] UNSPEC_PARITY)) 12524 (clobber (match_dup 1)) 12525 (clobber (match_dup 2))])] 12526{ 12527 operands[4] = gen_lowpart (SImode, operands[3]); 12528 12529 if (TARGET_64BIT) 12530 { 12531 emit_move_insn (operands[1], gen_lowpart (SImode, operands[3])); 12532 emit_insn (gen_lshrdi3 (operands[3], operands[3], GEN_INT (32))); 12533 } 12534 else 12535 operands[1] = gen_highpart (SImode, operands[3]); 12536}) 12537 12538(define_insn_and_split "paritysi2_cmp" 12539 [(set (reg:CC FLAGS_REG) 12540 (unspec:CC [(match_operand:SI 2 "register_operand" "0")] 12541 UNSPEC_PARITY)) 12542 (clobber (match_scratch:SI 0 "=r")) 12543 (clobber (match_scratch:HI 1 "=&Q"))] 12544 "! TARGET_POPCNT" 12545 "#" 12546 "&& reload_completed" 12547 [(parallel 12548 [(set (match_dup 1) 12549 (xor:HI (match_dup 1) (match_dup 3))) 12550 (clobber (reg:CC FLAGS_REG))]) 12551 (parallel 12552 [(set (reg:CC FLAGS_REG) 12553 (unspec:CC [(match_dup 1)] UNSPEC_PARITY)) 12554 (clobber (match_dup 1))])] 12555{ 12556 operands[3] = gen_lowpart (HImode, operands[2]); 12557 12558 emit_move_insn (operands[1], gen_lowpart (HImode, operands[2])); 12559 emit_insn (gen_lshrsi3 (operands[2], operands[2], GEN_INT (16))); 12560}) 12561 12562(define_insn "*parityhi2_cmp" 12563 [(set (reg:CC FLAGS_REG) 12564 (unspec:CC [(match_operand:HI 1 "register_operand" "0")] 12565 UNSPEC_PARITY)) 12566 (clobber (match_scratch:HI 0 "=Q"))] 12567 "! TARGET_POPCNT" 12568 "xor{b}\t{%h0, %b0|%b0, %h0}" 12569 [(set_attr "length" "2") 12570 (set_attr "mode" "HI")]) 12571 12572 12573;; Thread-local storage patterns for ELF. 12574;; 12575;; Note that these code sequences must appear exactly as shown 12576;; in order to allow linker relaxation. 12577 12578(define_insn "*tls_global_dynamic_32_gnu" 12579 [(set (match_operand:SI 0 "register_operand" "=a") 12580 (unspec:SI 12581 [(match_operand:SI 1 "register_operand" "b") 12582 (match_operand:SI 2 "tls_symbolic_operand" "") 12583 (match_operand:SI 3 "constant_call_address_operand" "z")] 12584 UNSPEC_TLS_GD)) 12585 (clobber (match_scratch:SI 4 "=d")) 12586 (clobber (match_scratch:SI 5 "=c")) 12587 (clobber (reg:CC FLAGS_REG))] 12588 "!TARGET_64BIT && TARGET_GNU_TLS" 12589{ 12590 output_asm_insn 12591 ("lea{l}\t{%E2@tlsgd(,%1,1), %0|%0, %E2@tlsgd[%1*1]}", operands); 12592 if (TARGET_SUN_TLS) 12593#ifdef HAVE_AS_IX86_TLSGDPLT 12594 return "call\t%a2@tlsgdplt"; 12595#else 12596 return "call\t%p3@plt"; 12597#endif 12598 return "call\t%P3"; 12599} 12600 [(set_attr "type" "multi") 12601 (set_attr "length" "12")]) 12602 12603(define_expand "tls_global_dynamic_32" 12604 [(parallel 12605 [(set (match_operand:SI 0 "register_operand" "") 12606 (unspec:SI [(match_operand:SI 2 "register_operand" "") 12607 (match_operand:SI 1 "tls_symbolic_operand" "") 12608 (match_operand:SI 3 "constant_call_address_operand" "")] 12609 UNSPEC_TLS_GD)) 12610 (clobber (match_scratch:SI 4 "")) 12611 (clobber (match_scratch:SI 5 "")) 12612 (clobber (reg:CC FLAGS_REG))])]) 12613 12614(define_insn "*tls_global_dynamic_64" 12615 [(set (match_operand:DI 0 "register_operand" "=a") 12616 (call:DI 12617 (mem:QI (match_operand:DI 2 "constant_call_address_operand" "z")) 12618 (match_operand:DI 3 "" ""))) 12619 (unspec:DI [(match_operand 1 "tls_symbolic_operand" "")] 12620 UNSPEC_TLS_GD)] 12621 "TARGET_64BIT" 12622{ 12623 if (!TARGET_X32) 12624 fputs (ASM_BYTE "0x66\n", asm_out_file); 12625 output_asm_insn 12626 ("lea{q}\t{%E1@tlsgd(%%rip), %%rdi|rdi, %E1@tlsgd[rip]}", operands); 12627 fputs (ASM_SHORT "0x6666\n", asm_out_file); 12628 fputs ("\trex64\n", asm_out_file); 12629 if (TARGET_SUN_TLS) 12630 return "call\t%p2@plt"; 12631 return "call\t%P2"; 12632} 12633 [(set_attr "type" "multi") 12634 (set (attr "length") 12635 (symbol_ref "TARGET_X32 ? 15 : 16"))]) 12636 12637(define_expand "tls_global_dynamic_64" 12638 [(parallel 12639 [(set (match_operand:DI 0 "register_operand" "") 12640 (call:DI 12641 (mem:QI (match_operand:DI 2 "constant_call_address_operand" "")) 12642 (const_int 0))) 12643 (unspec:DI [(match_operand 1 "tls_symbolic_operand" "")] 12644 UNSPEC_TLS_GD)])]) 12645 12646(define_insn "*tls_local_dynamic_base_32_gnu" 12647 [(set (match_operand:SI 0 "register_operand" "=a") 12648 (unspec:SI 12649 [(match_operand:SI 1 "register_operand" "b") 12650 (match_operand:SI 2 "constant_call_address_operand" "z")] 12651 UNSPEC_TLS_LD_BASE)) 12652 (clobber (match_scratch:SI 3 "=d")) 12653 (clobber (match_scratch:SI 4 "=c")) 12654 (clobber (reg:CC FLAGS_REG))] 12655 "!TARGET_64BIT && TARGET_GNU_TLS" 12656{ 12657 output_asm_insn 12658 ("lea{l}\t{%&@tlsldm(%1), %0|%0, %&@tlsldm[%1]}", operands); 12659 if (TARGET_SUN_TLS) 12660#ifdef HAVE_AS_IX86_TLSLDMPLT 12661 return "call\t%&@tlsldmplt"; 12662#else 12663 return "call\t%p2@plt"; 12664#endif 12665 return "call\t%P2"; 12666} 12667 [(set_attr "type" "multi") 12668 (set_attr "length" "11")]) 12669 12670(define_expand "tls_local_dynamic_base_32" 12671 [(parallel 12672 [(set (match_operand:SI 0 "register_operand" "") 12673 (unspec:SI 12674 [(match_operand:SI 1 "register_operand" "") 12675 (match_operand:SI 2 "constant_call_address_operand" "")] 12676 UNSPEC_TLS_LD_BASE)) 12677 (clobber (match_scratch:SI 3 "")) 12678 (clobber (match_scratch:SI 4 "")) 12679 (clobber (reg:CC FLAGS_REG))])]) 12680 12681(define_insn "*tls_local_dynamic_base_64" 12682 [(set (match_operand:DI 0 "register_operand" "=a") 12683 (call:DI 12684 (mem:QI (match_operand:DI 1 "constant_call_address_operand" "z")) 12685 (match_operand:DI 2 "" ""))) 12686 (unspec:DI [(const_int 0)] UNSPEC_TLS_LD_BASE)] 12687 "TARGET_64BIT" 12688{ 12689 output_asm_insn 12690 ("lea{q}\t{%&@tlsld(%%rip), %%rdi|rdi, %&@tlsld[rip]}", operands); 12691 if (TARGET_SUN_TLS) 12692 return "call\t%p1@plt"; 12693 return "call\t%P1"; 12694} 12695 [(set_attr "type" "multi") 12696 (set_attr "length" "12")]) 12697 12698(define_expand "tls_local_dynamic_base_64" 12699 [(parallel 12700 [(set (match_operand:DI 0 "register_operand" "") 12701 (call:DI 12702 (mem:QI (match_operand:DI 1 "constant_call_address_operand" "")) 12703 (const_int 0))) 12704 (unspec:DI [(const_int 0)] UNSPEC_TLS_LD_BASE)])]) 12705 12706;; Local dynamic of a single variable is a lose. Show combine how 12707;; to convert that back to global dynamic. 12708 12709(define_insn_and_split "*tls_local_dynamic_32_once" 12710 [(set (match_operand:SI 0 "register_operand" "=a") 12711 (plus:SI 12712 (unspec:SI [(match_operand:SI 1 "register_operand" "b") 12713 (match_operand:SI 2 "constant_call_address_operand" "z")] 12714 UNSPEC_TLS_LD_BASE) 12715 (const:SI (unspec:SI 12716 [(match_operand:SI 3 "tls_symbolic_operand" "")] 12717 UNSPEC_DTPOFF)))) 12718 (clobber (match_scratch:SI 4 "=d")) 12719 (clobber (match_scratch:SI 5 "=c")) 12720 (clobber (reg:CC FLAGS_REG))] 12721 "" 12722 "#" 12723 "" 12724 [(parallel 12725 [(set (match_dup 0) 12726 (unspec:SI [(match_dup 1) (match_dup 3) (match_dup 2)] 12727 UNSPEC_TLS_GD)) 12728 (clobber (match_dup 4)) 12729 (clobber (match_dup 5)) 12730 (clobber (reg:CC FLAGS_REG))])]) 12731 12732;; Segment register for the thread base ptr load 12733(define_mode_attr tp_seg [(SI "gs") (DI "fs")]) 12734 12735;; Load and add the thread base pointer from %<tp_seg>:0. 12736(define_insn "*load_tp_x32" 12737 [(set (match_operand:SI 0 "register_operand" "=r") 12738 (unspec:SI [(const_int 0)] UNSPEC_TP))] 12739 "TARGET_X32" 12740 "mov{l}\t{%%fs:0, %0|%0, DWORD PTR fs:0}" 12741 [(set_attr "type" "imov") 12742 (set_attr "modrm" "0") 12743 (set_attr "length" "7") 12744 (set_attr "memory" "load") 12745 (set_attr "imm_disp" "false")]) 12746 12747(define_insn "*load_tp_x32_zext" 12748 [(set (match_operand:DI 0 "register_operand" "=r") 12749 (zero_extend:DI (unspec:SI [(const_int 0)] UNSPEC_TP)))] 12750 "TARGET_X32" 12751 "mov{l}\t{%%fs:0, %k0|%k0, DWORD PTR fs:0}" 12752 [(set_attr "type" "imov") 12753 (set_attr "modrm" "0") 12754 (set_attr "length" "7") 12755 (set_attr "memory" "load") 12756 (set_attr "imm_disp" "false")]) 12757 12758(define_insn "*load_tp_<mode>" 12759 [(set (match_operand:P 0 "register_operand" "=r") 12760 (unspec:P [(const_int 0)] UNSPEC_TP))] 12761 "!TARGET_X32" 12762 "mov{<imodesuffix>}\t{%%<tp_seg>:0, %0|%0, <iptrsize> PTR <tp_seg>:0}" 12763 [(set_attr "type" "imov") 12764 (set_attr "modrm" "0") 12765 (set_attr "length" "7") 12766 (set_attr "memory" "load") 12767 (set_attr "imm_disp" "false")]) 12768 12769(define_insn "*add_tp_x32" 12770 [(set (match_operand:SI 0 "register_operand" "=r") 12771 (plus:SI (unspec:SI [(const_int 0)] UNSPEC_TP) 12772 (match_operand:SI 1 "register_operand" "0"))) 12773 (clobber (reg:CC FLAGS_REG))] 12774 "TARGET_X32" 12775 "add{l}\t{%%fs:0, %0|%0, DWORD PTR fs:0}" 12776 [(set_attr "type" "alu") 12777 (set_attr "modrm" "0") 12778 (set_attr "length" "7") 12779 (set_attr "memory" "load") 12780 (set_attr "imm_disp" "false")]) 12781 12782(define_insn "*add_tp_x32_zext" 12783 [(set (match_operand:DI 0 "register_operand" "=r") 12784 (zero_extend:DI 12785 (plus:SI (unspec:SI [(const_int 0)] UNSPEC_TP) 12786 (match_operand:SI 1 "register_operand" "0")))) 12787 (clobber (reg:CC FLAGS_REG))] 12788 "TARGET_X32" 12789 "add{l}\t{%%fs:0, %k0|%k0, DWORD PTR fs:0}" 12790 [(set_attr "type" "alu") 12791 (set_attr "modrm" "0") 12792 (set_attr "length" "7") 12793 (set_attr "memory" "load") 12794 (set_attr "imm_disp" "false")]) 12795 12796(define_insn "*add_tp_<mode>" 12797 [(set (match_operand:P 0 "register_operand" "=r") 12798 (plus:P (unspec:P [(const_int 0)] UNSPEC_TP) 12799 (match_operand:P 1 "register_operand" "0"))) 12800 (clobber (reg:CC FLAGS_REG))] 12801 "!TARGET_X32" 12802 "add{<imodesuffix>}\t{%%<tp_seg>:0, %0|%0, <iptrsize> PTR <tp_seg>:0}" 12803 [(set_attr "type" "alu") 12804 (set_attr "modrm" "0") 12805 (set_attr "length" "7") 12806 (set_attr "memory" "load") 12807 (set_attr "imm_disp" "false")]) 12808 12809;; The Sun linker took the AMD64 TLS spec literally and can only handle 12810;; %rax as destination of the initial executable code sequence. 12811(define_insn "tls_initial_exec_64_sun" 12812 [(set (match_operand:DI 0 "register_operand" "=a") 12813 (unspec:DI 12814 [(match_operand:DI 1 "tls_symbolic_operand" "")] 12815 UNSPEC_TLS_IE_SUN)) 12816 (clobber (reg:CC FLAGS_REG))] 12817 "TARGET_64BIT && TARGET_SUN_TLS" 12818{ 12819 output_asm_insn 12820 ("mov{q}\t{%%fs:0, %0|%0, QWORD PTR fs:0}", operands); 12821 return "add{q}\t{%a1@gottpoff(%%rip), %0|%0, %a1@gottpoff[rip]}"; 12822} 12823 [(set_attr "type" "multi")]) 12824 12825;; GNU2 TLS patterns can be split. 12826 12827(define_expand "tls_dynamic_gnu2_32" 12828 [(set (match_dup 3) 12829 (plus:SI (match_operand:SI 2 "register_operand" "") 12830 (const:SI 12831 (unspec:SI [(match_operand:SI 1 "tls_symbolic_operand" "")] 12832 UNSPEC_TLSDESC)))) 12833 (parallel 12834 [(set (match_operand:SI 0 "register_operand" "") 12835 (unspec:SI [(match_dup 1) (match_dup 3) 12836 (match_dup 2) (reg:SI SP_REG)] 12837 UNSPEC_TLSDESC)) 12838 (clobber (reg:CC FLAGS_REG))])] 12839 "!TARGET_64BIT && TARGET_GNU2_TLS" 12840{ 12841 operands[3] = can_create_pseudo_p () ? gen_reg_rtx (Pmode) : operands[0]; 12842 ix86_tls_descriptor_calls_expanded_in_cfun = true; 12843}) 12844 12845(define_insn "*tls_dynamic_gnu2_lea_32" 12846 [(set (match_operand:SI 0 "register_operand" "=r") 12847 (plus:SI (match_operand:SI 1 "register_operand" "b") 12848 (const:SI 12849 (unspec:SI [(match_operand:SI 2 "tls_symbolic_operand" "")] 12850 UNSPEC_TLSDESC))))] 12851 "!TARGET_64BIT && TARGET_GNU2_TLS" 12852 "lea{l}\t{%E2@TLSDESC(%1), %0|%0, %E2@TLSDESC[%1]}" 12853 [(set_attr "type" "lea") 12854 (set_attr "mode" "SI") 12855 (set_attr "length" "6") 12856 (set_attr "length_address" "4")]) 12857 12858(define_insn "*tls_dynamic_gnu2_call_32" 12859 [(set (match_operand:SI 0 "register_operand" "=a") 12860 (unspec:SI [(match_operand:SI 1 "tls_symbolic_operand" "") 12861 (match_operand:SI 2 "register_operand" "0") 12862 ;; we have to make sure %ebx still points to the GOT 12863 (match_operand:SI 3 "register_operand" "b") 12864 (reg:SI SP_REG)] 12865 UNSPEC_TLSDESC)) 12866 (clobber (reg:CC FLAGS_REG))] 12867 "!TARGET_64BIT && TARGET_GNU2_TLS" 12868 "call\t{*%a1@TLSCALL(%2)|[DWORD PTR [%2+%a1@TLSCALL]]}" 12869 [(set_attr "type" "call") 12870 (set_attr "length" "2") 12871 (set_attr "length_address" "0")]) 12872 12873(define_insn_and_split "*tls_dynamic_gnu2_combine_32" 12874 [(set (match_operand:SI 0 "register_operand" "=&a") 12875 (plus:SI 12876 (unspec:SI [(match_operand:SI 3 "tls_modbase_operand" "") 12877 (match_operand:SI 4 "" "") 12878 (match_operand:SI 2 "register_operand" "b") 12879 (reg:SI SP_REG)] 12880 UNSPEC_TLSDESC) 12881 (const:SI (unspec:SI 12882 [(match_operand:SI 1 "tls_symbolic_operand" "")] 12883 UNSPEC_DTPOFF)))) 12884 (clobber (reg:CC FLAGS_REG))] 12885 "!TARGET_64BIT && TARGET_GNU2_TLS" 12886 "#" 12887 "" 12888 [(set (match_dup 0) (match_dup 5))] 12889{ 12890 operands[5] = can_create_pseudo_p () ? gen_reg_rtx (Pmode) : operands[0]; 12891 emit_insn (gen_tls_dynamic_gnu2_32 (operands[5], operands[1], operands[2])); 12892}) 12893 12894(define_expand "tls_dynamic_gnu2_64" 12895 [(set (match_dup 2) 12896 (unspec:DI [(match_operand 1 "tls_symbolic_operand" "")] 12897 UNSPEC_TLSDESC)) 12898 (parallel 12899 [(set (match_operand:DI 0 "register_operand" "") 12900 (unspec:DI [(match_dup 1) (match_dup 2) (reg:DI SP_REG)] 12901 UNSPEC_TLSDESC)) 12902 (clobber (reg:CC FLAGS_REG))])] 12903 "TARGET_64BIT && TARGET_GNU2_TLS" 12904{ 12905 operands[2] = can_create_pseudo_p () ? gen_reg_rtx (Pmode) : operands[0]; 12906 ix86_tls_descriptor_calls_expanded_in_cfun = true; 12907}) 12908 12909(define_insn "*tls_dynamic_gnu2_lea_64" 12910 [(set (match_operand:DI 0 "register_operand" "=r") 12911 (unspec:DI [(match_operand 1 "tls_symbolic_operand" "")] 12912 UNSPEC_TLSDESC))] 12913 "TARGET_64BIT && TARGET_GNU2_TLS" 12914 "lea{q}\t{%E1@TLSDESC(%%rip), %0|%0, %E1@TLSDESC[rip]}" 12915 [(set_attr "type" "lea") 12916 (set_attr "mode" "DI") 12917 (set_attr "length" "7") 12918 (set_attr "length_address" "4")]) 12919 12920(define_insn "*tls_dynamic_gnu2_call_64" 12921 [(set (match_operand:DI 0 "register_operand" "=a") 12922 (unspec:DI [(match_operand 1 "tls_symbolic_operand" "") 12923 (match_operand:DI 2 "register_operand" "0") 12924 (reg:DI SP_REG)] 12925 UNSPEC_TLSDESC)) 12926 (clobber (reg:CC FLAGS_REG))] 12927 "TARGET_64BIT && TARGET_GNU2_TLS" 12928 "call\t{*%a1@TLSCALL(%2)|[QWORD PTR [%2+%a1@TLSCALL]]}" 12929 [(set_attr "type" "call") 12930 (set_attr "length" "2") 12931 (set_attr "length_address" "0")]) 12932 12933(define_insn_and_split "*tls_dynamic_gnu2_combine_64" 12934 [(set (match_operand:DI 0 "register_operand" "=&a") 12935 (plus:DI 12936 (unspec:DI [(match_operand:DI 2 "tls_modbase_operand" "") 12937 (match_operand:DI 3 "" "") 12938 (reg:DI SP_REG)] 12939 UNSPEC_TLSDESC) 12940 (const:DI (unspec:DI 12941 [(match_operand 1 "tls_symbolic_operand" "")] 12942 UNSPEC_DTPOFF)))) 12943 (clobber (reg:CC FLAGS_REG))] 12944 "TARGET_64BIT && TARGET_GNU2_TLS" 12945 "#" 12946 "" 12947 [(set (match_dup 0) (match_dup 4))] 12948{ 12949 operands[4] = can_create_pseudo_p () ? gen_reg_rtx (Pmode) : operands[0]; 12950 emit_insn (gen_tls_dynamic_gnu2_64 (operands[4], operands[1])); 12951}) 12952 12953;; These patterns match the binary 387 instructions for addM3, subM3, 12954;; mulM3 and divM3. There are three patterns for each of DFmode and 12955;; SFmode. The first is the normal insn, the second the same insn but 12956;; with one operand a conversion, and the third the same insn but with 12957;; the other operand a conversion. The conversion may be SFmode or 12958;; SImode if the target mode DFmode, but only SImode if the target mode 12959;; is SFmode. 12960 12961;; Gcc is slightly more smart about handling normal two address instructions 12962;; so use special patterns for add and mull. 12963 12964(define_insn "*fop_<mode>_comm_mixed" 12965 [(set (match_operand:MODEF 0 "register_operand" "=f,x,x") 12966 (match_operator:MODEF 3 "binary_fp_operator" 12967 [(match_operand:MODEF 1 "nonimmediate_operand" "%0,0,x") 12968 (match_operand:MODEF 2 "nonimmediate_operand" "fm,xm,xm")]))] 12969 "SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_MIX_SSE_I387 12970 && COMMUTATIVE_ARITH_P (operands[3]) 12971 && !(MEM_P (operands[1]) && MEM_P (operands[2]))" 12972 "* return output_387_binary_op (insn, operands);" 12973 [(set (attr "type") 12974 (if_then_else (eq_attr "alternative" "1,2") 12975 (if_then_else (match_operand:MODEF 3 "mult_operator" "") 12976 (const_string "ssemul") 12977 (const_string "sseadd")) 12978 (if_then_else (match_operand:MODEF 3 "mult_operator" "") 12979 (const_string "fmul") 12980 (const_string "fop")))) 12981 (set_attr "isa" "*,noavx,avx") 12982 (set_attr "prefix" "orig,orig,vex") 12983 (set_attr "mode" "<MODE>")]) 12984 12985(define_insn "*fop_<mode>_comm_sse" 12986 [(set (match_operand:MODEF 0 "register_operand" "=x,x") 12987 (match_operator:MODEF 3 "binary_fp_operator" 12988 [(match_operand:MODEF 1 "nonimmediate_operand" "%0,x") 12989 (match_operand:MODEF 2 "nonimmediate_operand" "xm,xm")]))] 12990 "SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH 12991 && COMMUTATIVE_ARITH_P (operands[3]) 12992 && !(MEM_P (operands[1]) && MEM_P (operands[2]))" 12993 "* return output_387_binary_op (insn, operands);" 12994 [(set (attr "type") 12995 (if_then_else (match_operand:MODEF 3 "mult_operator" "") 12996 (const_string "ssemul") 12997 (const_string "sseadd"))) 12998 (set_attr "isa" "noavx,avx") 12999 (set_attr "prefix" "orig,vex") 13000 (set_attr "mode" "<MODE>")]) 13001 13002(define_insn "*fop_<mode>_comm_i387" 13003 [(set (match_operand:MODEF 0 "register_operand" "=f") 13004 (match_operator:MODEF 3 "binary_fp_operator" 13005 [(match_operand:MODEF 1 "nonimmediate_operand" "%0") 13006 (match_operand:MODEF 2 "nonimmediate_operand" "fm")]))] 13007 "TARGET_80387 && X87_ENABLE_ARITH (<MODE>mode) 13008 && COMMUTATIVE_ARITH_P (operands[3]) 13009 && !(MEM_P (operands[1]) && MEM_P (operands[2]))" 13010 "* return output_387_binary_op (insn, operands);" 13011 [(set (attr "type") 13012 (if_then_else (match_operand:MODEF 3 "mult_operator" "") 13013 (const_string "fmul") 13014 (const_string "fop"))) 13015 (set_attr "mode" "<MODE>")]) 13016 13017(define_insn "*fop_<mode>_1_mixed" 13018 [(set (match_operand:MODEF 0 "register_operand" "=f,f,x,x") 13019 (match_operator:MODEF 3 "binary_fp_operator" 13020 [(match_operand:MODEF 1 "nonimmediate_operand" "0,fm,0,x") 13021 (match_operand:MODEF 2 "nonimmediate_operand" "fm,0,xm,xm")]))] 13022 "SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_MIX_SSE_I387 13023 && !COMMUTATIVE_ARITH_P (operands[3]) 13024 && !(MEM_P (operands[1]) && MEM_P (operands[2]))" 13025 "* return output_387_binary_op (insn, operands);" 13026 [(set (attr "type") 13027 (cond [(and (eq_attr "alternative" "2,3") 13028 (match_operand:MODEF 3 "mult_operator" "")) 13029 (const_string "ssemul") 13030 (and (eq_attr "alternative" "2,3") 13031 (match_operand:MODEF 3 "div_operator" "")) 13032 (const_string "ssediv") 13033 (eq_attr "alternative" "2,3") 13034 (const_string "sseadd") 13035 (match_operand:MODEF 3 "mult_operator" "") 13036 (const_string "fmul") 13037 (match_operand:MODEF 3 "div_operator" "") 13038 (const_string "fdiv") 13039 ] 13040 (const_string "fop"))) 13041 (set_attr "isa" "*,*,noavx,avx") 13042 (set_attr "prefix" "orig,orig,orig,vex") 13043 (set_attr "mode" "<MODE>")]) 13044 13045(define_insn "*rcpsf2_sse" 13046 [(set (match_operand:SF 0 "register_operand" "=x") 13047 (unspec:SF [(match_operand:SF 1 "nonimmediate_operand" "xm")] 13048 UNSPEC_RCP))] 13049 "TARGET_SSE_MATH" 13050 "%vrcpss\t{%1, %d0|%d0, %1}" 13051 [(set_attr "type" "sse") 13052 (set_attr "atom_sse_attr" "rcp") 13053 (set_attr "prefix" "maybe_vex") 13054 (set_attr "mode" "SF")]) 13055 13056(define_insn "*fop_<mode>_1_sse" 13057 [(set (match_operand:MODEF 0 "register_operand" "=x,x") 13058 (match_operator:MODEF 3 "binary_fp_operator" 13059 [(match_operand:MODEF 1 "register_operand" "0,x") 13060 (match_operand:MODEF 2 "nonimmediate_operand" "xm,xm")]))] 13061 "SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH 13062 && !COMMUTATIVE_ARITH_P (operands[3])" 13063 "* return output_387_binary_op (insn, operands);" 13064 [(set (attr "type") 13065 (cond [(match_operand:MODEF 3 "mult_operator" "") 13066 (const_string "ssemul") 13067 (match_operand:MODEF 3 "div_operator" "") 13068 (const_string "ssediv") 13069 ] 13070 (const_string "sseadd"))) 13071 (set_attr "isa" "noavx,avx") 13072 (set_attr "prefix" "orig,vex") 13073 (set_attr "mode" "<MODE>")]) 13074 13075;; This pattern is not fully shadowed by the pattern above. 13076(define_insn "*fop_<mode>_1_i387" 13077 [(set (match_operand:MODEF 0 "register_operand" "=f,f") 13078 (match_operator:MODEF 3 "binary_fp_operator" 13079 [(match_operand:MODEF 1 "nonimmediate_operand" "0,fm") 13080 (match_operand:MODEF 2 "nonimmediate_operand" "fm,0")]))] 13081 "TARGET_80387 && X87_ENABLE_ARITH (<MODE>mode) 13082 && !(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH) 13083 && !COMMUTATIVE_ARITH_P (operands[3]) 13084 && !(MEM_P (operands[1]) && MEM_P (operands[2]))" 13085 "* return output_387_binary_op (insn, operands);" 13086 [(set (attr "type") 13087 (cond [(match_operand:MODEF 3 "mult_operator" "") 13088 (const_string "fmul") 13089 (match_operand:MODEF 3 "div_operator" "") 13090 (const_string "fdiv") 13091 ] 13092 (const_string "fop"))) 13093 (set_attr "mode" "<MODE>")]) 13094 13095;; ??? Add SSE splitters for these! 13096(define_insn "*fop_<MODEF:mode>_2_i387" 13097 [(set (match_operand:MODEF 0 "register_operand" "=f,f") 13098 (match_operator:MODEF 3 "binary_fp_operator" 13099 [(float:MODEF 13100 (match_operand:SWI24 1 "nonimmediate_operand" "m,?r")) 13101 (match_operand:MODEF 2 "register_operand" "0,0")]))] 13102 "TARGET_80387 && X87_ENABLE_FLOAT (<MODEF:MODE>mode, <SWI24:MODE>mode) 13103 && !(SSE_FLOAT_MODE_P (<MODEF:MODE>mode) && TARGET_SSE_MATH) 13104 && (TARGET_USE_<SWI24:MODE>MODE_FIOP || optimize_function_for_size_p (cfun))" 13105 "* return which_alternative ? \"#\" : output_387_binary_op (insn, operands);" 13106 [(set (attr "type") 13107 (cond [(match_operand:MODEF 3 "mult_operator" "") 13108 (const_string "fmul") 13109 (match_operand:MODEF 3 "div_operator" "") 13110 (const_string "fdiv") 13111 ] 13112 (const_string "fop"))) 13113 (set_attr "fp_int_src" "true") 13114 (set_attr "mode" "<SWI24:MODE>")]) 13115 13116(define_insn "*fop_<MODEF:mode>_3_i387" 13117 [(set (match_operand:MODEF 0 "register_operand" "=f,f") 13118 (match_operator:MODEF 3 "binary_fp_operator" 13119 [(match_operand:MODEF 1 "register_operand" "0,0") 13120 (float:MODEF 13121 (match_operand:SWI24 2 "nonimmediate_operand" "m,?r"))]))] 13122 "TARGET_80387 && X87_ENABLE_FLOAT (<MODEF:MODE>mode, <SWI24:MODE>mode) 13123 && !(SSE_FLOAT_MODE_P (<MODEF:MODE>mode) && TARGET_SSE_MATH) 13124 && (TARGET_USE_<SWI24:MODE>MODE_FIOP || optimize_function_for_size_p (cfun))" 13125 "* return which_alternative ? \"#\" : output_387_binary_op (insn, operands);" 13126 [(set (attr "type") 13127 (cond [(match_operand:MODEF 3 "mult_operator" "") 13128 (const_string "fmul") 13129 (match_operand:MODEF 3 "div_operator" "") 13130 (const_string "fdiv") 13131 ] 13132 (const_string "fop"))) 13133 (set_attr "fp_int_src" "true") 13134 (set_attr "mode" "<MODE>")]) 13135 13136(define_insn "*fop_df_4_i387" 13137 [(set (match_operand:DF 0 "register_operand" "=f,f") 13138 (match_operator:DF 3 "binary_fp_operator" 13139 [(float_extend:DF 13140 (match_operand:SF 1 "nonimmediate_operand" "fm,0")) 13141 (match_operand:DF 2 "register_operand" "0,f")]))] 13142 "TARGET_80387 && X87_ENABLE_ARITH (DFmode) 13143 && !(TARGET_SSE2 && TARGET_SSE_MATH) 13144 && !(MEM_P (operands[1]) && MEM_P (operands[2]))" 13145 "* return output_387_binary_op (insn, operands);" 13146 [(set (attr "type") 13147 (cond [(match_operand:DF 3 "mult_operator" "") 13148 (const_string "fmul") 13149 (match_operand:DF 3 "div_operator" "") 13150 (const_string "fdiv") 13151 ] 13152 (const_string "fop"))) 13153 (set_attr "mode" "SF")]) 13154 13155(define_insn "*fop_df_5_i387" 13156 [(set (match_operand:DF 0 "register_operand" "=f,f") 13157 (match_operator:DF 3 "binary_fp_operator" 13158 [(match_operand:DF 1 "register_operand" "0,f") 13159 (float_extend:DF 13160 (match_operand:SF 2 "nonimmediate_operand" "fm,0"))]))] 13161 "TARGET_80387 && X87_ENABLE_ARITH (DFmode) 13162 && !(TARGET_SSE2 && TARGET_SSE_MATH)" 13163 "* return output_387_binary_op (insn, operands);" 13164 [(set (attr "type") 13165 (cond [(match_operand:DF 3 "mult_operator" "") 13166 (const_string "fmul") 13167 (match_operand:DF 3 "div_operator" "") 13168 (const_string "fdiv") 13169 ] 13170 (const_string "fop"))) 13171 (set_attr "mode" "SF")]) 13172 13173(define_insn "*fop_df_6_i387" 13174 [(set (match_operand:DF 0 "register_operand" "=f,f") 13175 (match_operator:DF 3 "binary_fp_operator" 13176 [(float_extend:DF 13177 (match_operand:SF 1 "register_operand" "0,f")) 13178 (float_extend:DF 13179 (match_operand:SF 2 "nonimmediate_operand" "fm,0"))]))] 13180 "TARGET_80387 && X87_ENABLE_ARITH (DFmode) 13181 && !(TARGET_SSE2 && TARGET_SSE_MATH)" 13182 "* return output_387_binary_op (insn, operands);" 13183 [(set (attr "type") 13184 (cond [(match_operand:DF 3 "mult_operator" "") 13185 (const_string "fmul") 13186 (match_operand:DF 3 "div_operator" "") 13187 (const_string "fdiv") 13188 ] 13189 (const_string "fop"))) 13190 (set_attr "mode" "SF")]) 13191 13192(define_insn "*fop_xf_comm_i387" 13193 [(set (match_operand:XF 0 "register_operand" "=f") 13194 (match_operator:XF 3 "binary_fp_operator" 13195 [(match_operand:XF 1 "register_operand" "%0") 13196 (match_operand:XF 2 "register_operand" "f")]))] 13197 "TARGET_80387 13198 && COMMUTATIVE_ARITH_P (operands[3])" 13199 "* return output_387_binary_op (insn, operands);" 13200 [(set (attr "type") 13201 (if_then_else (match_operand:XF 3 "mult_operator" "") 13202 (const_string "fmul") 13203 (const_string "fop"))) 13204 (set_attr "mode" "XF")]) 13205 13206(define_insn "*fop_xf_1_i387" 13207 [(set (match_operand:XF 0 "register_operand" "=f,f") 13208 (match_operator:XF 3 "binary_fp_operator" 13209 [(match_operand:XF 1 "register_operand" "0,f") 13210 (match_operand:XF 2 "register_operand" "f,0")]))] 13211 "TARGET_80387 13212 && !COMMUTATIVE_ARITH_P (operands[3])" 13213 "* return output_387_binary_op (insn, operands);" 13214 [(set (attr "type") 13215 (cond [(match_operand:XF 3 "mult_operator" "") 13216 (const_string "fmul") 13217 (match_operand:XF 3 "div_operator" "") 13218 (const_string "fdiv") 13219 ] 13220 (const_string "fop"))) 13221 (set_attr "mode" "XF")]) 13222 13223(define_insn "*fop_xf_2_i387" 13224 [(set (match_operand:XF 0 "register_operand" "=f,f") 13225 (match_operator:XF 3 "binary_fp_operator" 13226 [(float:XF 13227 (match_operand:SWI24 1 "nonimmediate_operand" "m,?r")) 13228 (match_operand:XF 2 "register_operand" "0,0")]))] 13229 "TARGET_80387 && (TARGET_USE_<MODE>MODE_FIOP || optimize_function_for_size_p (cfun))" 13230 "* return which_alternative ? \"#\" : output_387_binary_op (insn, operands);" 13231 [(set (attr "type") 13232 (cond [(match_operand:XF 3 "mult_operator" "") 13233 (const_string "fmul") 13234 (match_operand:XF 3 "div_operator" "") 13235 (const_string "fdiv") 13236 ] 13237 (const_string "fop"))) 13238 (set_attr "fp_int_src" "true") 13239 (set_attr "mode" "<MODE>")]) 13240 13241(define_insn "*fop_xf_3_i387" 13242 [(set (match_operand:XF 0 "register_operand" "=f,f") 13243 (match_operator:XF 3 "binary_fp_operator" 13244 [(match_operand:XF 1 "register_operand" "0,0") 13245 (float:XF 13246 (match_operand:SWI24 2 "nonimmediate_operand" "m,?r"))]))] 13247 "TARGET_80387 && (TARGET_USE_<MODE>MODE_FIOP || optimize_function_for_size_p (cfun))" 13248 "* return which_alternative ? \"#\" : output_387_binary_op (insn, operands);" 13249 [(set (attr "type") 13250 (cond [(match_operand:XF 3 "mult_operator" "") 13251 (const_string "fmul") 13252 (match_operand:XF 3 "div_operator" "") 13253 (const_string "fdiv") 13254 ] 13255 (const_string "fop"))) 13256 (set_attr "fp_int_src" "true") 13257 (set_attr "mode" "<MODE>")]) 13258 13259(define_insn "*fop_xf_4_i387" 13260 [(set (match_operand:XF 0 "register_operand" "=f,f") 13261 (match_operator:XF 3 "binary_fp_operator" 13262 [(float_extend:XF 13263 (match_operand:MODEF 1 "nonimmediate_operand" "fm,0")) 13264 (match_operand:XF 2 "register_operand" "0,f")]))] 13265 "TARGET_80387" 13266 "* return output_387_binary_op (insn, operands);" 13267 [(set (attr "type") 13268 (cond [(match_operand:XF 3 "mult_operator" "") 13269 (const_string "fmul") 13270 (match_operand:XF 3 "div_operator" "") 13271 (const_string "fdiv") 13272 ] 13273 (const_string "fop"))) 13274 (set_attr "mode" "<MODE>")]) 13275 13276(define_insn "*fop_xf_5_i387" 13277 [(set (match_operand:XF 0 "register_operand" "=f,f") 13278 (match_operator:XF 3 "binary_fp_operator" 13279 [(match_operand:XF 1 "register_operand" "0,f") 13280 (float_extend:XF 13281 (match_operand:MODEF 2 "nonimmediate_operand" "fm,0"))]))] 13282 "TARGET_80387" 13283 "* return output_387_binary_op (insn, operands);" 13284 [(set (attr "type") 13285 (cond [(match_operand:XF 3 "mult_operator" "") 13286 (const_string "fmul") 13287 (match_operand:XF 3 "div_operator" "") 13288 (const_string "fdiv") 13289 ] 13290 (const_string "fop"))) 13291 (set_attr "mode" "<MODE>")]) 13292 13293(define_insn "*fop_xf_6_i387" 13294 [(set (match_operand:XF 0 "register_operand" "=f,f") 13295 (match_operator:XF 3 "binary_fp_operator" 13296 [(float_extend:XF 13297 (match_operand:MODEF 1 "register_operand" "0,f")) 13298 (float_extend:XF 13299 (match_operand:MODEF 2 "nonimmediate_operand" "fm,0"))]))] 13300 "TARGET_80387" 13301 "* return output_387_binary_op (insn, operands);" 13302 [(set (attr "type") 13303 (cond [(match_operand:XF 3 "mult_operator" "") 13304 (const_string "fmul") 13305 (match_operand:XF 3 "div_operator" "") 13306 (const_string "fdiv") 13307 ] 13308 (const_string "fop"))) 13309 (set_attr "mode" "<MODE>")]) 13310 13311(define_split 13312 [(set (match_operand 0 "register_operand" "") 13313 (match_operator 3 "binary_fp_operator" 13314 [(float (match_operand:SWI24 1 "register_operand" "")) 13315 (match_operand 2 "register_operand" "")]))] 13316 "reload_completed 13317 && X87_FLOAT_MODE_P (GET_MODE (operands[0])) 13318 && X87_ENABLE_FLOAT (GET_MODE (operands[0]), GET_MODE (operands[1]))" 13319 [(const_int 0)] 13320{ 13321 operands[4] = ix86_force_to_memory (GET_MODE (operands[1]), operands[1]); 13322 operands[4] = gen_rtx_FLOAT (GET_MODE (operands[0]), operands[4]); 13323 emit_insn (gen_rtx_SET (VOIDmode, operands[0], 13324 gen_rtx_fmt_ee (GET_CODE (operands[3]), 13325 GET_MODE (operands[3]), 13326 operands[4], 13327 operands[2]))); 13328 ix86_free_from_memory (GET_MODE (operands[1])); 13329 DONE; 13330}) 13331 13332(define_split 13333 [(set (match_operand 0 "register_operand" "") 13334 (match_operator 3 "binary_fp_operator" 13335 [(match_operand 1 "register_operand" "") 13336 (float (match_operand:SWI24 2 "register_operand" ""))]))] 13337 "reload_completed 13338 && X87_FLOAT_MODE_P (GET_MODE (operands[0])) 13339 && X87_ENABLE_FLOAT (GET_MODE (operands[0]), GET_MODE (operands[2]))" 13340 [(const_int 0)] 13341{ 13342 operands[4] = ix86_force_to_memory (GET_MODE (operands[2]), operands[2]); 13343 operands[4] = gen_rtx_FLOAT (GET_MODE (operands[0]), operands[4]); 13344 emit_insn (gen_rtx_SET (VOIDmode, operands[0], 13345 gen_rtx_fmt_ee (GET_CODE (operands[3]), 13346 GET_MODE (operands[3]), 13347 operands[1], 13348 operands[4]))); 13349 ix86_free_from_memory (GET_MODE (operands[2])); 13350 DONE; 13351}) 13352 13353;; FPU special functions. 13354 13355;; This pattern implements a no-op XFmode truncation for 13356;; all fancy i386 XFmode math functions. 13357 13358(define_insn "truncxf<mode>2_i387_noop_unspec" 13359 [(set (match_operand:MODEF 0 "register_operand" "=f") 13360 (unspec:MODEF [(match_operand:XF 1 "register_operand" "f")] 13361 UNSPEC_TRUNC_NOOP))] 13362 "TARGET_USE_FANCY_MATH_387" 13363 "* return output_387_reg_move (insn, operands);" 13364 [(set_attr "type" "fmov") 13365 (set_attr "mode" "<MODE>")]) 13366 13367(define_insn "sqrtxf2" 13368 [(set (match_operand:XF 0 "register_operand" "=f") 13369 (sqrt:XF (match_operand:XF 1 "register_operand" "0")))] 13370 "TARGET_USE_FANCY_MATH_387" 13371 "fsqrt" 13372 [(set_attr "type" "fpspc") 13373 (set_attr "mode" "XF") 13374 (set_attr "athlon_decode" "direct") 13375 (set_attr "amdfam10_decode" "direct") 13376 (set_attr "bdver1_decode" "direct")]) 13377 13378(define_insn "sqrt_extend<mode>xf2_i387" 13379 [(set (match_operand:XF 0 "register_operand" "=f") 13380 (sqrt:XF 13381 (float_extend:XF 13382 (match_operand:MODEF 1 "register_operand" "0"))))] 13383 "TARGET_USE_FANCY_MATH_387" 13384 "fsqrt" 13385 [(set_attr "type" "fpspc") 13386 (set_attr "mode" "XF") 13387 (set_attr "athlon_decode" "direct") 13388 (set_attr "amdfam10_decode" "direct") 13389 (set_attr "bdver1_decode" "direct")]) 13390 13391(define_insn "*rsqrtsf2_sse" 13392 [(set (match_operand:SF 0 "register_operand" "=x") 13393 (unspec:SF [(match_operand:SF 1 "nonimmediate_operand" "xm")] 13394 UNSPEC_RSQRT))] 13395 "TARGET_SSE_MATH" 13396 "%vrsqrtss\t{%1, %d0|%d0, %1}" 13397 [(set_attr "type" "sse") 13398 (set_attr "atom_sse_attr" "rcp") 13399 (set_attr "prefix" "maybe_vex") 13400 (set_attr "mode" "SF")]) 13401 13402(define_expand "rsqrtsf2" 13403 [(set (match_operand:SF 0 "register_operand" "") 13404 (unspec:SF [(match_operand:SF 1 "nonimmediate_operand" "")] 13405 UNSPEC_RSQRT))] 13406 "TARGET_SSE_MATH" 13407{ 13408 ix86_emit_swsqrtsf (operands[0], operands[1], SFmode, 1); 13409 DONE; 13410}) 13411 13412(define_insn "*sqrt<mode>2_sse" 13413 [(set (match_operand:MODEF 0 "register_operand" "=x") 13414 (sqrt:MODEF 13415 (match_operand:MODEF 1 "nonimmediate_operand" "xm")))] 13416 "SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH" 13417 "%vsqrt<ssemodesuffix>\t{%1, %d0|%d0, %1}" 13418 [(set_attr "type" "sse") 13419 (set_attr "atom_sse_attr" "sqrt") 13420 (set_attr "prefix" "maybe_vex") 13421 (set_attr "mode" "<MODE>") 13422 (set_attr "athlon_decode" "*") 13423 (set_attr "amdfam10_decode" "*") 13424 (set_attr "bdver1_decode" "*")]) 13425 13426(define_expand "sqrt<mode>2" 13427 [(set (match_operand:MODEF 0 "register_operand" "") 13428 (sqrt:MODEF 13429 (match_operand:MODEF 1 "nonimmediate_operand" "")))] 13430 "(TARGET_USE_FANCY_MATH_387 && X87_ENABLE_ARITH (<MODE>mode)) 13431 || (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)" 13432{ 13433 if (<MODE>mode == SFmode 13434 && TARGET_SSE_MATH 13435 && TARGET_RECIP_SQRT 13436 && !optimize_function_for_size_p (cfun) 13437 && flag_finite_math_only && !flag_trapping_math 13438 && flag_unsafe_math_optimizations) 13439 { 13440 ix86_emit_swsqrtsf (operands[0], operands[1], SFmode, 0); 13441 DONE; 13442 } 13443 13444 if (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)) 13445 { 13446 rtx op0 = gen_reg_rtx (XFmode); 13447 rtx op1 = force_reg (<MODE>mode, operands[1]); 13448 13449 emit_insn (gen_sqrt_extend<mode>xf2_i387 (op0, op1)); 13450 emit_insn (gen_truncxf<mode>2_i387_noop_unspec (operands[0], op0)); 13451 DONE; 13452 } 13453}) 13454 13455(define_insn "fpremxf4_i387" 13456 [(set (match_operand:XF 0 "register_operand" "=f") 13457 (unspec:XF [(match_operand:XF 2 "register_operand" "0") 13458 (match_operand:XF 3 "register_operand" "1")] 13459 UNSPEC_FPREM_F)) 13460 (set (match_operand:XF 1 "register_operand" "=u") 13461 (unspec:XF [(match_dup 2) (match_dup 3)] 13462 UNSPEC_FPREM_U)) 13463 (set (reg:CCFP FPSR_REG) 13464 (unspec:CCFP [(match_dup 2) (match_dup 3)] 13465 UNSPEC_C2_FLAG))] 13466 "TARGET_USE_FANCY_MATH_387" 13467 "fprem" 13468 [(set_attr "type" "fpspc") 13469 (set_attr "mode" "XF")]) 13470 13471(define_expand "fmodxf3" 13472 [(use (match_operand:XF 0 "register_operand" "")) 13473 (use (match_operand:XF 1 "general_operand" "")) 13474 (use (match_operand:XF 2 "general_operand" ""))] 13475 "TARGET_USE_FANCY_MATH_387" 13476{ 13477 rtx label = gen_label_rtx (); 13478 13479 rtx op1 = gen_reg_rtx (XFmode); 13480 rtx op2 = gen_reg_rtx (XFmode); 13481 13482 emit_move_insn (op2, operands[2]); 13483 emit_move_insn (op1, operands[1]); 13484 13485 emit_label (label); 13486 emit_insn (gen_fpremxf4_i387 (op1, op2, op1, op2)); 13487 ix86_emit_fp_unordered_jump (label); 13488 LABEL_NUSES (label) = 1; 13489 13490 emit_move_insn (operands[0], op1); 13491 DONE; 13492}) 13493 13494(define_expand "fmod<mode>3" 13495 [(use (match_operand:MODEF 0 "register_operand" "")) 13496 (use (match_operand:MODEF 1 "general_operand" "")) 13497 (use (match_operand:MODEF 2 "general_operand" ""))] 13498 "TARGET_USE_FANCY_MATH_387" 13499{ 13500 rtx (*gen_truncxf) (rtx, rtx); 13501 13502 rtx label = gen_label_rtx (); 13503 13504 rtx op1 = gen_reg_rtx (XFmode); 13505 rtx op2 = gen_reg_rtx (XFmode); 13506 13507 emit_insn (gen_extend<mode>xf2 (op2, operands[2])); 13508 emit_insn (gen_extend<mode>xf2 (op1, operands[1])); 13509 13510 emit_label (label); 13511 emit_insn (gen_fpremxf4_i387 (op1, op2, op1, op2)); 13512 ix86_emit_fp_unordered_jump (label); 13513 LABEL_NUSES (label) = 1; 13514 13515 /* Truncate the result properly for strict SSE math. */ 13516 if (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH 13517 && !TARGET_MIX_SSE_I387) 13518 gen_truncxf = gen_truncxf<mode>2; 13519 else 13520 gen_truncxf = gen_truncxf<mode>2_i387_noop_unspec; 13521 13522 emit_insn (gen_truncxf (operands[0], op1)); 13523 DONE; 13524}) 13525 13526(define_insn "fprem1xf4_i387" 13527 [(set (match_operand:XF 0 "register_operand" "=f") 13528 (unspec:XF [(match_operand:XF 2 "register_operand" "0") 13529 (match_operand:XF 3 "register_operand" "1")] 13530 UNSPEC_FPREM1_F)) 13531 (set (match_operand:XF 1 "register_operand" "=u") 13532 (unspec:XF [(match_dup 2) (match_dup 3)] 13533 UNSPEC_FPREM1_U)) 13534 (set (reg:CCFP FPSR_REG) 13535 (unspec:CCFP [(match_dup 2) (match_dup 3)] 13536 UNSPEC_C2_FLAG))] 13537 "TARGET_USE_FANCY_MATH_387" 13538 "fprem1" 13539 [(set_attr "type" "fpspc") 13540 (set_attr "mode" "XF")]) 13541 13542(define_expand "remainderxf3" 13543 [(use (match_operand:XF 0 "register_operand" "")) 13544 (use (match_operand:XF 1 "general_operand" "")) 13545 (use (match_operand:XF 2 "general_operand" ""))] 13546 "TARGET_USE_FANCY_MATH_387" 13547{ 13548 rtx label = gen_label_rtx (); 13549 13550 rtx op1 = gen_reg_rtx (XFmode); 13551 rtx op2 = gen_reg_rtx (XFmode); 13552 13553 emit_move_insn (op2, operands[2]); 13554 emit_move_insn (op1, operands[1]); 13555 13556 emit_label (label); 13557 emit_insn (gen_fprem1xf4_i387 (op1, op2, op1, op2)); 13558 ix86_emit_fp_unordered_jump (label); 13559 LABEL_NUSES (label) = 1; 13560 13561 emit_move_insn (operands[0], op1); 13562 DONE; 13563}) 13564 13565(define_expand "remainder<mode>3" 13566 [(use (match_operand:MODEF 0 "register_operand" "")) 13567 (use (match_operand:MODEF 1 "general_operand" "")) 13568 (use (match_operand:MODEF 2 "general_operand" ""))] 13569 "TARGET_USE_FANCY_MATH_387" 13570{ 13571 rtx (*gen_truncxf) (rtx, rtx); 13572 13573 rtx label = gen_label_rtx (); 13574 13575 rtx op1 = gen_reg_rtx (XFmode); 13576 rtx op2 = gen_reg_rtx (XFmode); 13577 13578 emit_insn (gen_extend<mode>xf2 (op2, operands[2])); 13579 emit_insn (gen_extend<mode>xf2 (op1, operands[1])); 13580 13581 emit_label (label); 13582 13583 emit_insn (gen_fprem1xf4_i387 (op1, op2, op1, op2)); 13584 ix86_emit_fp_unordered_jump (label); 13585 LABEL_NUSES (label) = 1; 13586 13587 /* Truncate the result properly for strict SSE math. */ 13588 if (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH 13589 && !TARGET_MIX_SSE_I387) 13590 gen_truncxf = gen_truncxf<mode>2; 13591 else 13592 gen_truncxf = gen_truncxf<mode>2_i387_noop_unspec; 13593 13594 emit_insn (gen_truncxf (operands[0], op1)); 13595 DONE; 13596}) 13597 13598(define_insn "*sinxf2_i387" 13599 [(set (match_operand:XF 0 "register_operand" "=f") 13600 (unspec:XF [(match_operand:XF 1 "register_operand" "0")] UNSPEC_SIN))] 13601 "TARGET_USE_FANCY_MATH_387 13602 && flag_unsafe_math_optimizations" 13603 "fsin" 13604 [(set_attr "type" "fpspc") 13605 (set_attr "mode" "XF")]) 13606 13607(define_insn "*sin_extend<mode>xf2_i387" 13608 [(set (match_operand:XF 0 "register_operand" "=f") 13609 (unspec:XF [(float_extend:XF 13610 (match_operand:MODEF 1 "register_operand" "0"))] 13611 UNSPEC_SIN))] 13612 "TARGET_USE_FANCY_MATH_387 13613 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH) 13614 || TARGET_MIX_SSE_I387) 13615 && flag_unsafe_math_optimizations" 13616 "fsin" 13617 [(set_attr "type" "fpspc") 13618 (set_attr "mode" "XF")]) 13619 13620(define_insn "*cosxf2_i387" 13621 [(set (match_operand:XF 0 "register_operand" "=f") 13622 (unspec:XF [(match_operand:XF 1 "register_operand" "0")] UNSPEC_COS))] 13623 "TARGET_USE_FANCY_MATH_387 13624 && flag_unsafe_math_optimizations" 13625 "fcos" 13626 [(set_attr "type" "fpspc") 13627 (set_attr "mode" "XF")]) 13628 13629(define_insn "*cos_extend<mode>xf2_i387" 13630 [(set (match_operand:XF 0 "register_operand" "=f") 13631 (unspec:XF [(float_extend:XF 13632 (match_operand:MODEF 1 "register_operand" "0"))] 13633 UNSPEC_COS))] 13634 "TARGET_USE_FANCY_MATH_387 13635 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH) 13636 || TARGET_MIX_SSE_I387) 13637 && flag_unsafe_math_optimizations" 13638 "fcos" 13639 [(set_attr "type" "fpspc") 13640 (set_attr "mode" "XF")]) 13641 13642;; When sincos pattern is defined, sin and cos builtin functions will be 13643;; expanded to sincos pattern with one of its outputs left unused. 13644;; CSE pass will figure out if two sincos patterns can be combined, 13645;; otherwise sincos pattern will be split back to sin or cos pattern, 13646;; depending on the unused output. 13647 13648(define_insn "sincosxf3" 13649 [(set (match_operand:XF 0 "register_operand" "=f") 13650 (unspec:XF [(match_operand:XF 2 "register_operand" "0")] 13651 UNSPEC_SINCOS_COS)) 13652 (set (match_operand:XF 1 "register_operand" "=u") 13653 (unspec:XF [(match_dup 2)] UNSPEC_SINCOS_SIN))] 13654 "TARGET_USE_FANCY_MATH_387 13655 && flag_unsafe_math_optimizations" 13656 "fsincos" 13657 [(set_attr "type" "fpspc") 13658 (set_attr "mode" "XF")]) 13659 13660(define_split 13661 [(set (match_operand:XF 0 "register_operand" "") 13662 (unspec:XF [(match_operand:XF 2 "register_operand" "")] 13663 UNSPEC_SINCOS_COS)) 13664 (set (match_operand:XF 1 "register_operand" "") 13665 (unspec:XF [(match_dup 2)] UNSPEC_SINCOS_SIN))] 13666 "find_regno_note (insn, REG_UNUSED, REGNO (operands[0])) 13667 && can_create_pseudo_p ()" 13668 [(set (match_dup 1) (unspec:XF [(match_dup 2)] UNSPEC_SIN))]) 13669 13670(define_split 13671 [(set (match_operand:XF 0 "register_operand" "") 13672 (unspec:XF [(match_operand:XF 2 "register_operand" "")] 13673 UNSPEC_SINCOS_COS)) 13674 (set (match_operand:XF 1 "register_operand" "") 13675 (unspec:XF [(match_dup 2)] UNSPEC_SINCOS_SIN))] 13676 "find_regno_note (insn, REG_UNUSED, REGNO (operands[1])) 13677 && can_create_pseudo_p ()" 13678 [(set (match_dup 0) (unspec:XF [(match_dup 2)] UNSPEC_COS))]) 13679 13680(define_insn "sincos_extend<mode>xf3_i387" 13681 [(set (match_operand:XF 0 "register_operand" "=f") 13682 (unspec:XF [(float_extend:XF 13683 (match_operand:MODEF 2 "register_operand" "0"))] 13684 UNSPEC_SINCOS_COS)) 13685 (set (match_operand:XF 1 "register_operand" "=u") 13686 (unspec:XF [(float_extend:XF (match_dup 2))] UNSPEC_SINCOS_SIN))] 13687 "TARGET_USE_FANCY_MATH_387 13688 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH) 13689 || TARGET_MIX_SSE_I387) 13690 && flag_unsafe_math_optimizations" 13691 "fsincos" 13692 [(set_attr "type" "fpspc") 13693 (set_attr "mode" "XF")]) 13694 13695(define_split 13696 [(set (match_operand:XF 0 "register_operand" "") 13697 (unspec:XF [(float_extend:XF 13698 (match_operand:MODEF 2 "register_operand" ""))] 13699 UNSPEC_SINCOS_COS)) 13700 (set (match_operand:XF 1 "register_operand" "") 13701 (unspec:XF [(float_extend:XF (match_dup 2))] UNSPEC_SINCOS_SIN))] 13702 "find_regno_note (insn, REG_UNUSED, REGNO (operands[0])) 13703 && can_create_pseudo_p ()" 13704 [(set (match_dup 1) 13705 (unspec:XF [(float_extend:XF (match_dup 2))] UNSPEC_SIN))]) 13706 13707(define_split 13708 [(set (match_operand:XF 0 "register_operand" "") 13709 (unspec:XF [(float_extend:XF 13710 (match_operand:MODEF 2 "register_operand" ""))] 13711 UNSPEC_SINCOS_COS)) 13712 (set (match_operand:XF 1 "register_operand" "") 13713 (unspec:XF [(float_extend:XF (match_dup 2))] UNSPEC_SINCOS_SIN))] 13714 "find_regno_note (insn, REG_UNUSED, REGNO (operands[1])) 13715 && can_create_pseudo_p ()" 13716 [(set (match_dup 0) 13717 (unspec:XF [(float_extend:XF (match_dup 2))] UNSPEC_COS))]) 13718 13719(define_expand "sincos<mode>3" 13720 [(use (match_operand:MODEF 0 "register_operand" "")) 13721 (use (match_operand:MODEF 1 "register_operand" "")) 13722 (use (match_operand:MODEF 2 "register_operand" ""))] 13723 "TARGET_USE_FANCY_MATH_387 13724 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH) 13725 || TARGET_MIX_SSE_I387) 13726 && flag_unsafe_math_optimizations" 13727{ 13728 rtx op0 = gen_reg_rtx (XFmode); 13729 rtx op1 = gen_reg_rtx (XFmode); 13730 13731 emit_insn (gen_sincos_extend<mode>xf3_i387 (op0, op1, operands[2])); 13732 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0)); 13733 emit_insn (gen_truncxf<mode>2_i387_noop (operands[1], op1)); 13734 DONE; 13735}) 13736 13737(define_insn "fptanxf4_i387" 13738 [(set (match_operand:XF 0 "register_operand" "=f") 13739 (match_operand:XF 3 "const_double_operand" "F")) 13740 (set (match_operand:XF 1 "register_operand" "=u") 13741 (unspec:XF [(match_operand:XF 2 "register_operand" "0")] 13742 UNSPEC_TAN))] 13743 "TARGET_USE_FANCY_MATH_387 13744 && flag_unsafe_math_optimizations 13745 && standard_80387_constant_p (operands[3]) == 2" 13746 "fptan" 13747 [(set_attr "type" "fpspc") 13748 (set_attr "mode" "XF")]) 13749 13750(define_insn "fptan_extend<mode>xf4_i387" 13751 [(set (match_operand:MODEF 0 "register_operand" "=f") 13752 (match_operand:MODEF 3 "const_double_operand" "F")) 13753 (set (match_operand:XF 1 "register_operand" "=u") 13754 (unspec:XF [(float_extend:XF 13755 (match_operand:MODEF 2 "register_operand" "0"))] 13756 UNSPEC_TAN))] 13757 "TARGET_USE_FANCY_MATH_387 13758 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH) 13759 || TARGET_MIX_SSE_I387) 13760 && flag_unsafe_math_optimizations 13761 && standard_80387_constant_p (operands[3]) == 2" 13762 "fptan" 13763 [(set_attr "type" "fpspc") 13764 (set_attr "mode" "XF")]) 13765 13766(define_expand "tanxf2" 13767 [(use (match_operand:XF 0 "register_operand" "")) 13768 (use (match_operand:XF 1 "register_operand" ""))] 13769 "TARGET_USE_FANCY_MATH_387 13770 && flag_unsafe_math_optimizations" 13771{ 13772 rtx one = gen_reg_rtx (XFmode); 13773 rtx op2 = CONST1_RTX (XFmode); /* fld1 */ 13774 13775 emit_insn (gen_fptanxf4_i387 (one, operands[0], operands[1], op2)); 13776 DONE; 13777}) 13778 13779(define_expand "tan<mode>2" 13780 [(use (match_operand:MODEF 0 "register_operand" "")) 13781 (use (match_operand:MODEF 1 "register_operand" ""))] 13782 "TARGET_USE_FANCY_MATH_387 13783 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH) 13784 || TARGET_MIX_SSE_I387) 13785 && flag_unsafe_math_optimizations" 13786{ 13787 rtx op0 = gen_reg_rtx (XFmode); 13788 13789 rtx one = gen_reg_rtx (<MODE>mode); 13790 rtx op2 = CONST1_RTX (<MODE>mode); /* fld1 */ 13791 13792 emit_insn (gen_fptan_extend<mode>xf4_i387 (one, op0, 13793 operands[1], op2)); 13794 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0)); 13795 DONE; 13796}) 13797 13798(define_insn "*fpatanxf3_i387" 13799 [(set (match_operand:XF 0 "register_operand" "=f") 13800 (unspec:XF [(match_operand:XF 1 "register_operand" "0") 13801 (match_operand:XF 2 "register_operand" "u")] 13802 UNSPEC_FPATAN)) 13803 (clobber (match_scratch:XF 3 "=2"))] 13804 "TARGET_USE_FANCY_MATH_387 13805 && flag_unsafe_math_optimizations" 13806 "fpatan" 13807 [(set_attr "type" "fpspc") 13808 (set_attr "mode" "XF")]) 13809 13810(define_insn "fpatan_extend<mode>xf3_i387" 13811 [(set (match_operand:XF 0 "register_operand" "=f") 13812 (unspec:XF [(float_extend:XF 13813 (match_operand:MODEF 1 "register_operand" "0")) 13814 (float_extend:XF 13815 (match_operand:MODEF 2 "register_operand" "u"))] 13816 UNSPEC_FPATAN)) 13817 (clobber (match_scratch:XF 3 "=2"))] 13818 "TARGET_USE_FANCY_MATH_387 13819 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH) 13820 || TARGET_MIX_SSE_I387) 13821 && flag_unsafe_math_optimizations" 13822 "fpatan" 13823 [(set_attr "type" "fpspc") 13824 (set_attr "mode" "XF")]) 13825 13826(define_expand "atan2xf3" 13827 [(parallel [(set (match_operand:XF 0 "register_operand" "") 13828 (unspec:XF [(match_operand:XF 2 "register_operand" "") 13829 (match_operand:XF 1 "register_operand" "")] 13830 UNSPEC_FPATAN)) 13831 (clobber (match_scratch:XF 3 ""))])] 13832 "TARGET_USE_FANCY_MATH_387 13833 && flag_unsafe_math_optimizations") 13834 13835(define_expand "atan2<mode>3" 13836 [(use (match_operand:MODEF 0 "register_operand" "")) 13837 (use (match_operand:MODEF 1 "register_operand" "")) 13838 (use (match_operand:MODEF 2 "register_operand" ""))] 13839 "TARGET_USE_FANCY_MATH_387 13840 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH) 13841 || TARGET_MIX_SSE_I387) 13842 && flag_unsafe_math_optimizations" 13843{ 13844 rtx op0 = gen_reg_rtx (XFmode); 13845 13846 emit_insn (gen_fpatan_extend<mode>xf3_i387 (op0, operands[2], operands[1])); 13847 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0)); 13848 DONE; 13849}) 13850 13851(define_expand "atanxf2" 13852 [(parallel [(set (match_operand:XF 0 "register_operand" "") 13853 (unspec:XF [(match_dup 2) 13854 (match_operand:XF 1 "register_operand" "")] 13855 UNSPEC_FPATAN)) 13856 (clobber (match_scratch:XF 3 ""))])] 13857 "TARGET_USE_FANCY_MATH_387 13858 && flag_unsafe_math_optimizations" 13859{ 13860 operands[2] = gen_reg_rtx (XFmode); 13861 emit_move_insn (operands[2], CONST1_RTX (XFmode)); /* fld1 */ 13862}) 13863 13864(define_expand "atan<mode>2" 13865 [(use (match_operand:MODEF 0 "register_operand" "")) 13866 (use (match_operand:MODEF 1 "register_operand" ""))] 13867 "TARGET_USE_FANCY_MATH_387 13868 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH) 13869 || TARGET_MIX_SSE_I387) 13870 && flag_unsafe_math_optimizations" 13871{ 13872 rtx op0 = gen_reg_rtx (XFmode); 13873 13874 rtx op2 = gen_reg_rtx (<MODE>mode); 13875 emit_move_insn (op2, CONST1_RTX (<MODE>mode)); /* fld1 */ 13876 13877 emit_insn (gen_fpatan_extend<mode>xf3_i387 (op0, op2, operands[1])); 13878 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0)); 13879 DONE; 13880}) 13881 13882(define_expand "asinxf2" 13883 [(set (match_dup 2) 13884 (mult:XF (match_operand:XF 1 "register_operand" "") 13885 (match_dup 1))) 13886 (set (match_dup 4) (minus:XF (match_dup 3) (match_dup 2))) 13887 (set (match_dup 5) (sqrt:XF (match_dup 4))) 13888 (parallel [(set (match_operand:XF 0 "register_operand" "") 13889 (unspec:XF [(match_dup 5) (match_dup 1)] 13890 UNSPEC_FPATAN)) 13891 (clobber (match_scratch:XF 6 ""))])] 13892 "TARGET_USE_FANCY_MATH_387 13893 && flag_unsafe_math_optimizations" 13894{ 13895 int i; 13896 13897 if (optimize_insn_for_size_p ()) 13898 FAIL; 13899 13900 for (i = 2; i < 6; i++) 13901 operands[i] = gen_reg_rtx (XFmode); 13902 13903 emit_move_insn (operands[3], CONST1_RTX (XFmode)); /* fld1 */ 13904}) 13905 13906(define_expand "asin<mode>2" 13907 [(use (match_operand:MODEF 0 "register_operand" "")) 13908 (use (match_operand:MODEF 1 "general_operand" ""))] 13909 "TARGET_USE_FANCY_MATH_387 13910 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH) 13911 || TARGET_MIX_SSE_I387) 13912 && flag_unsafe_math_optimizations" 13913{ 13914 rtx op0 = gen_reg_rtx (XFmode); 13915 rtx op1 = gen_reg_rtx (XFmode); 13916 13917 if (optimize_insn_for_size_p ()) 13918 FAIL; 13919 13920 emit_insn (gen_extend<mode>xf2 (op1, operands[1])); 13921 emit_insn (gen_asinxf2 (op0, op1)); 13922 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0)); 13923 DONE; 13924}) 13925 13926(define_expand "acosxf2" 13927 [(set (match_dup 2) 13928 (mult:XF (match_operand:XF 1 "register_operand" "") 13929 (match_dup 1))) 13930 (set (match_dup 4) (minus:XF (match_dup 3) (match_dup 2))) 13931 (set (match_dup 5) (sqrt:XF (match_dup 4))) 13932 (parallel [(set (match_operand:XF 0 "register_operand" "") 13933 (unspec:XF [(match_dup 1) (match_dup 5)] 13934 UNSPEC_FPATAN)) 13935 (clobber (match_scratch:XF 6 ""))])] 13936 "TARGET_USE_FANCY_MATH_387 13937 && flag_unsafe_math_optimizations" 13938{ 13939 int i; 13940 13941 if (optimize_insn_for_size_p ()) 13942 FAIL; 13943 13944 for (i = 2; i < 6; i++) 13945 operands[i] = gen_reg_rtx (XFmode); 13946 13947 emit_move_insn (operands[3], CONST1_RTX (XFmode)); /* fld1 */ 13948}) 13949 13950(define_expand "acos<mode>2" 13951 [(use (match_operand:MODEF 0 "register_operand" "")) 13952 (use (match_operand:MODEF 1 "general_operand" ""))] 13953 "TARGET_USE_FANCY_MATH_387 13954 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH) 13955 || TARGET_MIX_SSE_I387) 13956 && flag_unsafe_math_optimizations" 13957{ 13958 rtx op0 = gen_reg_rtx (XFmode); 13959 rtx op1 = gen_reg_rtx (XFmode); 13960 13961 if (optimize_insn_for_size_p ()) 13962 FAIL; 13963 13964 emit_insn (gen_extend<mode>xf2 (op1, operands[1])); 13965 emit_insn (gen_acosxf2 (op0, op1)); 13966 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0)); 13967 DONE; 13968}) 13969 13970(define_insn "fyl2xxf3_i387" 13971 [(set (match_operand:XF 0 "register_operand" "=f") 13972 (unspec:XF [(match_operand:XF 1 "register_operand" "0") 13973 (match_operand:XF 2 "register_operand" "u")] 13974 UNSPEC_FYL2X)) 13975 (clobber (match_scratch:XF 3 "=2"))] 13976 "TARGET_USE_FANCY_MATH_387 13977 && flag_unsafe_math_optimizations" 13978 "fyl2x" 13979 [(set_attr "type" "fpspc") 13980 (set_attr "mode" "XF")]) 13981 13982(define_insn "fyl2x_extend<mode>xf3_i387" 13983 [(set (match_operand:XF 0 "register_operand" "=f") 13984 (unspec:XF [(float_extend:XF 13985 (match_operand:MODEF 1 "register_operand" "0")) 13986 (match_operand:XF 2 "register_operand" "u")] 13987 UNSPEC_FYL2X)) 13988 (clobber (match_scratch:XF 3 "=2"))] 13989 "TARGET_USE_FANCY_MATH_387 13990 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH) 13991 || TARGET_MIX_SSE_I387) 13992 && flag_unsafe_math_optimizations" 13993 "fyl2x" 13994 [(set_attr "type" "fpspc") 13995 (set_attr "mode" "XF")]) 13996 13997(define_expand "logxf2" 13998 [(parallel [(set (match_operand:XF 0 "register_operand" "") 13999 (unspec:XF [(match_operand:XF 1 "register_operand" "") 14000 (match_dup 2)] UNSPEC_FYL2X)) 14001 (clobber (match_scratch:XF 3 ""))])] 14002 "TARGET_USE_FANCY_MATH_387 14003 && flag_unsafe_math_optimizations" 14004{ 14005 operands[2] = gen_reg_rtx (XFmode); 14006 emit_move_insn (operands[2], standard_80387_constant_rtx (4)); /* fldln2 */ 14007}) 14008 14009(define_expand "log<mode>2" 14010 [(use (match_operand:MODEF 0 "register_operand" "")) 14011 (use (match_operand:MODEF 1 "register_operand" ""))] 14012 "TARGET_USE_FANCY_MATH_387 14013 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH) 14014 || TARGET_MIX_SSE_I387) 14015 && flag_unsafe_math_optimizations" 14016{ 14017 rtx op0 = gen_reg_rtx (XFmode); 14018 14019 rtx op2 = gen_reg_rtx (XFmode); 14020 emit_move_insn (op2, standard_80387_constant_rtx (4)); /* fldln2 */ 14021 14022 emit_insn (gen_fyl2x_extend<mode>xf3_i387 (op0, operands[1], op2)); 14023 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0)); 14024 DONE; 14025}) 14026 14027(define_expand "log10xf2" 14028 [(parallel [(set (match_operand:XF 0 "register_operand" "") 14029 (unspec:XF [(match_operand:XF 1 "register_operand" "") 14030 (match_dup 2)] UNSPEC_FYL2X)) 14031 (clobber (match_scratch:XF 3 ""))])] 14032 "TARGET_USE_FANCY_MATH_387 14033 && flag_unsafe_math_optimizations" 14034{ 14035 operands[2] = gen_reg_rtx (XFmode); 14036 emit_move_insn (operands[2], standard_80387_constant_rtx (3)); /* fldlg2 */ 14037}) 14038 14039(define_expand "log10<mode>2" 14040 [(use (match_operand:MODEF 0 "register_operand" "")) 14041 (use (match_operand:MODEF 1 "register_operand" ""))] 14042 "TARGET_USE_FANCY_MATH_387 14043 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH) 14044 || TARGET_MIX_SSE_I387) 14045 && flag_unsafe_math_optimizations" 14046{ 14047 rtx op0 = gen_reg_rtx (XFmode); 14048 14049 rtx op2 = gen_reg_rtx (XFmode); 14050 emit_move_insn (op2, standard_80387_constant_rtx (3)); /* fldlg2 */ 14051 14052 emit_insn (gen_fyl2x_extend<mode>xf3_i387 (op0, operands[1], op2)); 14053 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0)); 14054 DONE; 14055}) 14056 14057(define_expand "log2xf2" 14058 [(parallel [(set (match_operand:XF 0 "register_operand" "") 14059 (unspec:XF [(match_operand:XF 1 "register_operand" "") 14060 (match_dup 2)] UNSPEC_FYL2X)) 14061 (clobber (match_scratch:XF 3 ""))])] 14062 "TARGET_USE_FANCY_MATH_387 14063 && flag_unsafe_math_optimizations" 14064{ 14065 operands[2] = gen_reg_rtx (XFmode); 14066 emit_move_insn (operands[2], CONST1_RTX (XFmode)); /* fld1 */ 14067}) 14068 14069(define_expand "log2<mode>2" 14070 [(use (match_operand:MODEF 0 "register_operand" "")) 14071 (use (match_operand:MODEF 1 "register_operand" ""))] 14072 "TARGET_USE_FANCY_MATH_387 14073 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH) 14074 || TARGET_MIX_SSE_I387) 14075 && flag_unsafe_math_optimizations" 14076{ 14077 rtx op0 = gen_reg_rtx (XFmode); 14078 14079 rtx op2 = gen_reg_rtx (XFmode); 14080 emit_move_insn (op2, CONST1_RTX (XFmode)); /* fld1 */ 14081 14082 emit_insn (gen_fyl2x_extend<mode>xf3_i387 (op0, operands[1], op2)); 14083 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0)); 14084 DONE; 14085}) 14086 14087(define_insn "fyl2xp1xf3_i387" 14088 [(set (match_operand:XF 0 "register_operand" "=f") 14089 (unspec:XF [(match_operand:XF 1 "register_operand" "0") 14090 (match_operand:XF 2 "register_operand" "u")] 14091 UNSPEC_FYL2XP1)) 14092 (clobber (match_scratch:XF 3 "=2"))] 14093 "TARGET_USE_FANCY_MATH_387 14094 && flag_unsafe_math_optimizations" 14095 "fyl2xp1" 14096 [(set_attr "type" "fpspc") 14097 (set_attr "mode" "XF")]) 14098 14099(define_insn "fyl2xp1_extend<mode>xf3_i387" 14100 [(set (match_operand:XF 0 "register_operand" "=f") 14101 (unspec:XF [(float_extend:XF 14102 (match_operand:MODEF 1 "register_operand" "0")) 14103 (match_operand:XF 2 "register_operand" "u")] 14104 UNSPEC_FYL2XP1)) 14105 (clobber (match_scratch:XF 3 "=2"))] 14106 "TARGET_USE_FANCY_MATH_387 14107 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH) 14108 || TARGET_MIX_SSE_I387) 14109 && flag_unsafe_math_optimizations" 14110 "fyl2xp1" 14111 [(set_attr "type" "fpspc") 14112 (set_attr "mode" "XF")]) 14113 14114(define_expand "log1pxf2" 14115 [(use (match_operand:XF 0 "register_operand" "")) 14116 (use (match_operand:XF 1 "register_operand" ""))] 14117 "TARGET_USE_FANCY_MATH_387 14118 && flag_unsafe_math_optimizations" 14119{ 14120 if (optimize_insn_for_size_p ()) 14121 FAIL; 14122 14123 ix86_emit_i387_log1p (operands[0], operands[1]); 14124 DONE; 14125}) 14126 14127(define_expand "log1p<mode>2" 14128 [(use (match_operand:MODEF 0 "register_operand" "")) 14129 (use (match_operand:MODEF 1 "register_operand" ""))] 14130 "TARGET_USE_FANCY_MATH_387 14131 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH) 14132 || TARGET_MIX_SSE_I387) 14133 && flag_unsafe_math_optimizations" 14134{ 14135 rtx op0; 14136 14137 if (optimize_insn_for_size_p ()) 14138 FAIL; 14139 14140 op0 = gen_reg_rtx (XFmode); 14141 14142 operands[1] = gen_rtx_FLOAT_EXTEND (XFmode, operands[1]); 14143 14144 ix86_emit_i387_log1p (op0, operands[1]); 14145 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0)); 14146 DONE; 14147}) 14148 14149(define_insn "fxtractxf3_i387" 14150 [(set (match_operand:XF 0 "register_operand" "=f") 14151 (unspec:XF [(match_operand:XF 2 "register_operand" "0")] 14152 UNSPEC_XTRACT_FRACT)) 14153 (set (match_operand:XF 1 "register_operand" "=u") 14154 (unspec:XF [(match_dup 2)] UNSPEC_XTRACT_EXP))] 14155 "TARGET_USE_FANCY_MATH_387 14156 && flag_unsafe_math_optimizations" 14157 "fxtract" 14158 [(set_attr "type" "fpspc") 14159 (set_attr "mode" "XF")]) 14160 14161(define_insn "fxtract_extend<mode>xf3_i387" 14162 [(set (match_operand:XF 0 "register_operand" "=f") 14163 (unspec:XF [(float_extend:XF 14164 (match_operand:MODEF 2 "register_operand" "0"))] 14165 UNSPEC_XTRACT_FRACT)) 14166 (set (match_operand:XF 1 "register_operand" "=u") 14167 (unspec:XF [(float_extend:XF (match_dup 2))] UNSPEC_XTRACT_EXP))] 14168 "TARGET_USE_FANCY_MATH_387 14169 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH) 14170 || TARGET_MIX_SSE_I387) 14171 && flag_unsafe_math_optimizations" 14172 "fxtract" 14173 [(set_attr "type" "fpspc") 14174 (set_attr "mode" "XF")]) 14175 14176(define_expand "logbxf2" 14177 [(parallel [(set (match_dup 2) 14178 (unspec:XF [(match_operand:XF 1 "register_operand" "")] 14179 UNSPEC_XTRACT_FRACT)) 14180 (set (match_operand:XF 0 "register_operand" "") 14181 (unspec:XF [(match_dup 1)] UNSPEC_XTRACT_EXP))])] 14182 "TARGET_USE_FANCY_MATH_387 14183 && flag_unsafe_math_optimizations" 14184 "operands[2] = gen_reg_rtx (XFmode);") 14185 14186(define_expand "logb<mode>2" 14187 [(use (match_operand:MODEF 0 "register_operand" "")) 14188 (use (match_operand:MODEF 1 "register_operand" ""))] 14189 "TARGET_USE_FANCY_MATH_387 14190 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH) 14191 || TARGET_MIX_SSE_I387) 14192 && flag_unsafe_math_optimizations" 14193{ 14194 rtx op0 = gen_reg_rtx (XFmode); 14195 rtx op1 = gen_reg_rtx (XFmode); 14196 14197 emit_insn (gen_fxtract_extend<mode>xf3_i387 (op0, op1, operands[1])); 14198 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op1)); 14199 DONE; 14200}) 14201 14202(define_expand "ilogbxf2" 14203 [(use (match_operand:SI 0 "register_operand" "")) 14204 (use (match_operand:XF 1 "register_operand" ""))] 14205 "TARGET_USE_FANCY_MATH_387 14206 && flag_unsafe_math_optimizations" 14207{ 14208 rtx op0, op1; 14209 14210 if (optimize_insn_for_size_p ()) 14211 FAIL; 14212 14213 op0 = gen_reg_rtx (XFmode); 14214 op1 = gen_reg_rtx (XFmode); 14215 14216 emit_insn (gen_fxtractxf3_i387 (op0, op1, operands[1])); 14217 emit_insn (gen_fix_truncxfsi2 (operands[0], op1)); 14218 DONE; 14219}) 14220 14221(define_expand "ilogb<mode>2" 14222 [(use (match_operand:SI 0 "register_operand" "")) 14223 (use (match_operand:MODEF 1 "register_operand" ""))] 14224 "TARGET_USE_FANCY_MATH_387 14225 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH) 14226 || TARGET_MIX_SSE_I387) 14227 && flag_unsafe_math_optimizations" 14228{ 14229 rtx op0, op1; 14230 14231 if (optimize_insn_for_size_p ()) 14232 FAIL; 14233 14234 op0 = gen_reg_rtx (XFmode); 14235 op1 = gen_reg_rtx (XFmode); 14236 14237 emit_insn (gen_fxtract_extend<mode>xf3_i387 (op0, op1, operands[1])); 14238 emit_insn (gen_fix_truncxfsi2 (operands[0], op1)); 14239 DONE; 14240}) 14241 14242(define_insn "*f2xm1xf2_i387" 14243 [(set (match_operand:XF 0 "register_operand" "=f") 14244 (unspec:XF [(match_operand:XF 1 "register_operand" "0")] 14245 UNSPEC_F2XM1))] 14246 "TARGET_USE_FANCY_MATH_387 14247 && flag_unsafe_math_optimizations" 14248 "f2xm1" 14249 [(set_attr "type" "fpspc") 14250 (set_attr "mode" "XF")]) 14251 14252(define_insn "*fscalexf4_i387" 14253 [(set (match_operand:XF 0 "register_operand" "=f") 14254 (unspec:XF [(match_operand:XF 2 "register_operand" "0") 14255 (match_operand:XF 3 "register_operand" "1")] 14256 UNSPEC_FSCALE_FRACT)) 14257 (set (match_operand:XF 1 "register_operand" "=u") 14258 (unspec:XF [(match_dup 2) (match_dup 3)] 14259 UNSPEC_FSCALE_EXP))] 14260 "TARGET_USE_FANCY_MATH_387 14261 && flag_unsafe_math_optimizations" 14262 "fscale" 14263 [(set_attr "type" "fpspc") 14264 (set_attr "mode" "XF")]) 14265 14266(define_expand "expNcorexf3" 14267 [(set (match_dup 3) (mult:XF (match_operand:XF 1 "register_operand" "") 14268 (match_operand:XF 2 "register_operand" ""))) 14269 (set (match_dup 4) (unspec:XF [(match_dup 3)] UNSPEC_FRNDINT)) 14270 (set (match_dup 5) (minus:XF (match_dup 3) (match_dup 4))) 14271 (set (match_dup 6) (unspec:XF [(match_dup 5)] UNSPEC_F2XM1)) 14272 (set (match_dup 8) (plus:XF (match_dup 6) (match_dup 7))) 14273 (parallel [(set (match_operand:XF 0 "register_operand" "") 14274 (unspec:XF [(match_dup 8) (match_dup 4)] 14275 UNSPEC_FSCALE_FRACT)) 14276 (set (match_dup 9) 14277 (unspec:XF [(match_dup 8) (match_dup 4)] 14278 UNSPEC_FSCALE_EXP))])] 14279 "TARGET_USE_FANCY_MATH_387 14280 && flag_unsafe_math_optimizations" 14281{ 14282 int i; 14283 14284 if (optimize_insn_for_size_p ()) 14285 FAIL; 14286 14287 for (i = 3; i < 10; i++) 14288 operands[i] = gen_reg_rtx (XFmode); 14289 14290 emit_move_insn (operands[7], CONST1_RTX (XFmode)); /* fld1 */ 14291}) 14292 14293(define_expand "expxf2" 14294 [(use (match_operand:XF 0 "register_operand" "")) 14295 (use (match_operand:XF 1 "register_operand" ""))] 14296 "TARGET_USE_FANCY_MATH_387 14297 && flag_unsafe_math_optimizations" 14298{ 14299 rtx op2; 14300 14301 if (optimize_insn_for_size_p ()) 14302 FAIL; 14303 14304 op2 = gen_reg_rtx (XFmode); 14305 emit_move_insn (op2, standard_80387_constant_rtx (5)); /* fldl2e */ 14306 14307 emit_insn (gen_expNcorexf3 (operands[0], operands[1], op2)); 14308 DONE; 14309}) 14310 14311(define_expand "exp<mode>2" 14312 [(use (match_operand:MODEF 0 "register_operand" "")) 14313 (use (match_operand:MODEF 1 "general_operand" ""))] 14314 "TARGET_USE_FANCY_MATH_387 14315 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH) 14316 || TARGET_MIX_SSE_I387) 14317 && flag_unsafe_math_optimizations" 14318{ 14319 rtx op0, op1; 14320 14321 if (optimize_insn_for_size_p ()) 14322 FAIL; 14323 14324 op0 = gen_reg_rtx (XFmode); 14325 op1 = gen_reg_rtx (XFmode); 14326 14327 emit_insn (gen_extend<mode>xf2 (op1, operands[1])); 14328 emit_insn (gen_expxf2 (op0, op1)); 14329 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0)); 14330 DONE; 14331}) 14332 14333(define_expand "exp10xf2" 14334 [(use (match_operand:XF 0 "register_operand" "")) 14335 (use (match_operand:XF 1 "register_operand" ""))] 14336 "TARGET_USE_FANCY_MATH_387 14337 && flag_unsafe_math_optimizations" 14338{ 14339 rtx op2; 14340 14341 if (optimize_insn_for_size_p ()) 14342 FAIL; 14343 14344 op2 = gen_reg_rtx (XFmode); 14345 emit_move_insn (op2, standard_80387_constant_rtx (6)); /* fldl2t */ 14346 14347 emit_insn (gen_expNcorexf3 (operands[0], operands[1], op2)); 14348 DONE; 14349}) 14350 14351(define_expand "exp10<mode>2" 14352 [(use (match_operand:MODEF 0 "register_operand" "")) 14353 (use (match_operand:MODEF 1 "general_operand" ""))] 14354 "TARGET_USE_FANCY_MATH_387 14355 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH) 14356 || TARGET_MIX_SSE_I387) 14357 && flag_unsafe_math_optimizations" 14358{ 14359 rtx op0, op1; 14360 14361 if (optimize_insn_for_size_p ()) 14362 FAIL; 14363 14364 op0 = gen_reg_rtx (XFmode); 14365 op1 = gen_reg_rtx (XFmode); 14366 14367 emit_insn (gen_extend<mode>xf2 (op1, operands[1])); 14368 emit_insn (gen_exp10xf2 (op0, op1)); 14369 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0)); 14370 DONE; 14371}) 14372 14373(define_expand "exp2xf2" 14374 [(use (match_operand:XF 0 "register_operand" "")) 14375 (use (match_operand:XF 1 "register_operand" ""))] 14376 "TARGET_USE_FANCY_MATH_387 14377 && flag_unsafe_math_optimizations" 14378{ 14379 rtx op2; 14380 14381 if (optimize_insn_for_size_p ()) 14382 FAIL; 14383 14384 op2 = gen_reg_rtx (XFmode); 14385 emit_move_insn (op2, CONST1_RTX (XFmode)); /* fld1 */ 14386 14387 emit_insn (gen_expNcorexf3 (operands[0], operands[1], op2)); 14388 DONE; 14389}) 14390 14391(define_expand "exp2<mode>2" 14392 [(use (match_operand:MODEF 0 "register_operand" "")) 14393 (use (match_operand:MODEF 1 "general_operand" ""))] 14394 "TARGET_USE_FANCY_MATH_387 14395 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH) 14396 || TARGET_MIX_SSE_I387) 14397 && flag_unsafe_math_optimizations" 14398{ 14399 rtx op0, op1; 14400 14401 if (optimize_insn_for_size_p ()) 14402 FAIL; 14403 14404 op0 = gen_reg_rtx (XFmode); 14405 op1 = gen_reg_rtx (XFmode); 14406 14407 emit_insn (gen_extend<mode>xf2 (op1, operands[1])); 14408 emit_insn (gen_exp2xf2 (op0, op1)); 14409 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0)); 14410 DONE; 14411}) 14412 14413(define_expand "expm1xf2" 14414 [(set (match_dup 3) (mult:XF (match_operand:XF 1 "register_operand" "") 14415 (match_dup 2))) 14416 (set (match_dup 4) (unspec:XF [(match_dup 3)] UNSPEC_FRNDINT)) 14417 (set (match_dup 5) (minus:XF (match_dup 3) (match_dup 4))) 14418 (set (match_dup 9) (float_extend:XF (match_dup 13))) 14419 (set (match_dup 6) (unspec:XF [(match_dup 5)] UNSPEC_F2XM1)) 14420 (parallel [(set (match_dup 7) 14421 (unspec:XF [(match_dup 6) (match_dup 4)] 14422 UNSPEC_FSCALE_FRACT)) 14423 (set (match_dup 8) 14424 (unspec:XF [(match_dup 6) (match_dup 4)] 14425 UNSPEC_FSCALE_EXP))]) 14426 (parallel [(set (match_dup 10) 14427 (unspec:XF [(match_dup 9) (match_dup 8)] 14428 UNSPEC_FSCALE_FRACT)) 14429 (set (match_dup 11) 14430 (unspec:XF [(match_dup 9) (match_dup 8)] 14431 UNSPEC_FSCALE_EXP))]) 14432 (set (match_dup 12) (minus:XF (match_dup 10) 14433 (float_extend:XF (match_dup 13)))) 14434 (set (match_operand:XF 0 "register_operand" "") 14435 (plus:XF (match_dup 12) (match_dup 7)))] 14436 "TARGET_USE_FANCY_MATH_387 14437 && flag_unsafe_math_optimizations" 14438{ 14439 int i; 14440 14441 if (optimize_insn_for_size_p ()) 14442 FAIL; 14443 14444 for (i = 2; i < 13; i++) 14445 operands[i] = gen_reg_rtx (XFmode); 14446 14447 operands[13] 14448 = validize_mem (force_const_mem (SFmode, CONST1_RTX (SFmode))); /* fld1 */ 14449 14450 emit_move_insn (operands[2], standard_80387_constant_rtx (5)); /* fldl2e */ 14451}) 14452 14453(define_expand "expm1<mode>2" 14454 [(use (match_operand:MODEF 0 "register_operand" "")) 14455 (use (match_operand:MODEF 1 "general_operand" ""))] 14456 "TARGET_USE_FANCY_MATH_387 14457 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH) 14458 || TARGET_MIX_SSE_I387) 14459 && flag_unsafe_math_optimizations" 14460{ 14461 rtx op0, op1; 14462 14463 if (optimize_insn_for_size_p ()) 14464 FAIL; 14465 14466 op0 = gen_reg_rtx (XFmode); 14467 op1 = gen_reg_rtx (XFmode); 14468 14469 emit_insn (gen_extend<mode>xf2 (op1, operands[1])); 14470 emit_insn (gen_expm1xf2 (op0, op1)); 14471 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0)); 14472 DONE; 14473}) 14474 14475(define_expand "ldexpxf3" 14476 [(set (match_dup 3) 14477 (float:XF (match_operand:SI 2 "register_operand" ""))) 14478 (parallel [(set (match_operand:XF 0 " register_operand" "") 14479 (unspec:XF [(match_operand:XF 1 "register_operand" "") 14480 (match_dup 3)] 14481 UNSPEC_FSCALE_FRACT)) 14482 (set (match_dup 4) 14483 (unspec:XF [(match_dup 1) (match_dup 3)] 14484 UNSPEC_FSCALE_EXP))])] 14485 "TARGET_USE_FANCY_MATH_387 14486 && flag_unsafe_math_optimizations" 14487{ 14488 if (optimize_insn_for_size_p ()) 14489 FAIL; 14490 14491 operands[3] = gen_reg_rtx (XFmode); 14492 operands[4] = gen_reg_rtx (XFmode); 14493}) 14494 14495(define_expand "ldexp<mode>3" 14496 [(use (match_operand:MODEF 0 "register_operand" "")) 14497 (use (match_operand:MODEF 1 "general_operand" "")) 14498 (use (match_operand:SI 2 "register_operand" ""))] 14499 "TARGET_USE_FANCY_MATH_387 14500 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH) 14501 || TARGET_MIX_SSE_I387) 14502 && flag_unsafe_math_optimizations" 14503{ 14504 rtx op0, op1; 14505 14506 if (optimize_insn_for_size_p ()) 14507 FAIL; 14508 14509 op0 = gen_reg_rtx (XFmode); 14510 op1 = gen_reg_rtx (XFmode); 14511 14512 emit_insn (gen_extend<mode>xf2 (op1, operands[1])); 14513 emit_insn (gen_ldexpxf3 (op0, op1, operands[2])); 14514 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0)); 14515 DONE; 14516}) 14517 14518(define_expand "scalbxf3" 14519 [(parallel [(set (match_operand:XF 0 " register_operand" "") 14520 (unspec:XF [(match_operand:XF 1 "register_operand" "") 14521 (match_operand:XF 2 "register_operand" "")] 14522 UNSPEC_FSCALE_FRACT)) 14523 (set (match_dup 3) 14524 (unspec:XF [(match_dup 1) (match_dup 2)] 14525 UNSPEC_FSCALE_EXP))])] 14526 "TARGET_USE_FANCY_MATH_387 14527 && flag_unsafe_math_optimizations" 14528{ 14529 if (optimize_insn_for_size_p ()) 14530 FAIL; 14531 14532 operands[3] = gen_reg_rtx (XFmode); 14533}) 14534 14535(define_expand "scalb<mode>3" 14536 [(use (match_operand:MODEF 0 "register_operand" "")) 14537 (use (match_operand:MODEF 1 "general_operand" "")) 14538 (use (match_operand:MODEF 2 "general_operand" ""))] 14539 "TARGET_USE_FANCY_MATH_387 14540 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH) 14541 || TARGET_MIX_SSE_I387) 14542 && flag_unsafe_math_optimizations" 14543{ 14544 rtx op0, op1, op2; 14545 14546 if (optimize_insn_for_size_p ()) 14547 FAIL; 14548 14549 op0 = gen_reg_rtx (XFmode); 14550 op1 = gen_reg_rtx (XFmode); 14551 op2 = gen_reg_rtx (XFmode); 14552 14553 emit_insn (gen_extend<mode>xf2 (op1, operands[1])); 14554 emit_insn (gen_extend<mode>xf2 (op2, operands[2])); 14555 emit_insn (gen_scalbxf3 (op0, op1, op2)); 14556 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0)); 14557 DONE; 14558}) 14559 14560(define_expand "significandxf2" 14561 [(parallel [(set (match_operand:XF 0 "register_operand" "") 14562 (unspec:XF [(match_operand:XF 1 "register_operand" "")] 14563 UNSPEC_XTRACT_FRACT)) 14564 (set (match_dup 2) 14565 (unspec:XF [(match_dup 1)] UNSPEC_XTRACT_EXP))])] 14566 "TARGET_USE_FANCY_MATH_387 14567 && flag_unsafe_math_optimizations" 14568 "operands[2] = gen_reg_rtx (XFmode);") 14569 14570(define_expand "significand<mode>2" 14571 [(use (match_operand:MODEF 0 "register_operand" "")) 14572 (use (match_operand:MODEF 1 "register_operand" ""))] 14573 "TARGET_USE_FANCY_MATH_387 14574 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH) 14575 || TARGET_MIX_SSE_I387) 14576 && flag_unsafe_math_optimizations" 14577{ 14578 rtx op0 = gen_reg_rtx (XFmode); 14579 rtx op1 = gen_reg_rtx (XFmode); 14580 14581 emit_insn (gen_fxtract_extend<mode>xf3_i387 (op0, op1, operands[1])); 14582 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0)); 14583 DONE; 14584}) 14585 14586 14587(define_insn "sse4_1_round<mode>2" 14588 [(set (match_operand:MODEF 0 "register_operand" "=x") 14589 (unspec:MODEF [(match_operand:MODEF 1 "register_operand" "x") 14590 (match_operand:SI 2 "const_0_to_15_operand" "n")] 14591 UNSPEC_ROUND))] 14592 "TARGET_ROUND" 14593 "%vround<ssemodesuffix>\t{%2, %1, %d0|%d0, %1, %2}" 14594 [(set_attr "type" "ssecvt") 14595 (set_attr "prefix_extra" "1") 14596 (set_attr "prefix" "maybe_vex") 14597 (set_attr "mode" "<MODE>")]) 14598 14599(define_insn "rintxf2" 14600 [(set (match_operand:XF 0 "register_operand" "=f") 14601 (unspec:XF [(match_operand:XF 1 "register_operand" "0")] 14602 UNSPEC_FRNDINT))] 14603 "TARGET_USE_FANCY_MATH_387 14604 && flag_unsafe_math_optimizations" 14605 "frndint" 14606 [(set_attr "type" "fpspc") 14607 (set_attr "mode" "XF")]) 14608 14609(define_expand "rint<mode>2" 14610 [(use (match_operand:MODEF 0 "register_operand" "")) 14611 (use (match_operand:MODEF 1 "register_operand" ""))] 14612 "(TARGET_USE_FANCY_MATH_387 14613 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH) 14614 || TARGET_MIX_SSE_I387) 14615 && flag_unsafe_math_optimizations) 14616 || (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH 14617 && !flag_trapping_math)" 14618{ 14619 if (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH 14620 && !flag_trapping_math) 14621 { 14622 if (TARGET_ROUND) 14623 emit_insn (gen_sse4_1_round<mode>2 14624 (operands[0], operands[1], GEN_INT (ROUND_MXCSR))); 14625 else if (optimize_insn_for_size_p ()) 14626 FAIL; 14627 else 14628 ix86_expand_rint (operands[0], operands[1]); 14629 } 14630 else 14631 { 14632 rtx op0 = gen_reg_rtx (XFmode); 14633 rtx op1 = gen_reg_rtx (XFmode); 14634 14635 emit_insn (gen_extend<mode>xf2 (op1, operands[1])); 14636 emit_insn (gen_rintxf2 (op0, op1)); 14637 14638 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0)); 14639 } 14640 DONE; 14641}) 14642 14643(define_expand "round<mode>2" 14644 [(match_operand:X87MODEF 0 "register_operand" "") 14645 (match_operand:X87MODEF 1 "nonimmediate_operand" "")] 14646 "(TARGET_USE_FANCY_MATH_387 14647 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH) 14648 || TARGET_MIX_SSE_I387) 14649 && flag_unsafe_math_optimizations) 14650 || (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH 14651 && !flag_trapping_math && !flag_rounding_math)" 14652{ 14653 if (optimize_insn_for_size_p ()) 14654 FAIL; 14655 14656 if (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH 14657 && !flag_trapping_math && !flag_rounding_math) 14658 { 14659 if (TARGET_ROUND) 14660 { 14661 operands[1] = force_reg (<MODE>mode, operands[1]); 14662 ix86_expand_round_sse4 (operands[0], operands[1]); 14663 } 14664 else if (TARGET_64BIT || (<MODE>mode != DFmode)) 14665 ix86_expand_round (operands[0], operands[1]); 14666 else 14667 ix86_expand_rounddf_32 (operands[0], operands[1]); 14668 } 14669 else 14670 { 14671 operands[1] = force_reg (<MODE>mode, operands[1]); 14672 ix86_emit_i387_round (operands[0], operands[1]); 14673 } 14674 DONE; 14675}) 14676 14677(define_insn_and_split "*fistdi2_1" 14678 [(set (match_operand:DI 0 "nonimmediate_operand" "") 14679 (unspec:DI [(match_operand:XF 1 "register_operand" "")] 14680 UNSPEC_FIST))] 14681 "TARGET_USE_FANCY_MATH_387 14682 && can_create_pseudo_p ()" 14683 "#" 14684 "&& 1" 14685 [(const_int 0)] 14686{ 14687 if (memory_operand (operands[0], VOIDmode)) 14688 emit_insn (gen_fistdi2 (operands[0], operands[1])); 14689 else 14690 { 14691 operands[2] = assign_386_stack_local (DImode, SLOT_TEMP); 14692 emit_insn (gen_fistdi2_with_temp (operands[0], operands[1], 14693 operands[2])); 14694 } 14695 DONE; 14696} 14697 [(set_attr "type" "fpspc") 14698 (set_attr "mode" "DI")]) 14699 14700(define_insn "fistdi2" 14701 [(set (match_operand:DI 0 "memory_operand" "=m") 14702 (unspec:DI [(match_operand:XF 1 "register_operand" "f")] 14703 UNSPEC_FIST)) 14704 (clobber (match_scratch:XF 2 "=&1f"))] 14705 "TARGET_USE_FANCY_MATH_387" 14706 "* return output_fix_trunc (insn, operands, false);" 14707 [(set_attr "type" "fpspc") 14708 (set_attr "mode" "DI")]) 14709 14710(define_insn "fistdi2_with_temp" 14711 [(set (match_operand:DI 0 "nonimmediate_operand" "=m,?r") 14712 (unspec:DI [(match_operand:XF 1 "register_operand" "f,f")] 14713 UNSPEC_FIST)) 14714 (clobber (match_operand:DI 2 "memory_operand" "=X,m")) 14715 (clobber (match_scratch:XF 3 "=&1f,&1f"))] 14716 "TARGET_USE_FANCY_MATH_387" 14717 "#" 14718 [(set_attr "type" "fpspc") 14719 (set_attr "mode" "DI")]) 14720 14721(define_split 14722 [(set (match_operand:DI 0 "register_operand" "") 14723 (unspec:DI [(match_operand:XF 1 "register_operand" "")] 14724 UNSPEC_FIST)) 14725 (clobber (match_operand:DI 2 "memory_operand" "")) 14726 (clobber (match_scratch 3 ""))] 14727 "reload_completed" 14728 [(parallel [(set (match_dup 2) (unspec:DI [(match_dup 1)] UNSPEC_FIST)) 14729 (clobber (match_dup 3))]) 14730 (set (match_dup 0) (match_dup 2))]) 14731 14732(define_split 14733 [(set (match_operand:DI 0 "memory_operand" "") 14734 (unspec:DI [(match_operand:XF 1 "register_operand" "")] 14735 UNSPEC_FIST)) 14736 (clobber (match_operand:DI 2 "memory_operand" "")) 14737 (clobber (match_scratch 3 ""))] 14738 "reload_completed" 14739 [(parallel [(set (match_dup 0) (unspec:DI [(match_dup 1)] UNSPEC_FIST)) 14740 (clobber (match_dup 3))])]) 14741 14742(define_insn_and_split "*fist<mode>2_1" 14743 [(set (match_operand:SWI24 0 "register_operand" "") 14744 (unspec:SWI24 [(match_operand:XF 1 "register_operand" "")] 14745 UNSPEC_FIST))] 14746 "TARGET_USE_FANCY_MATH_387 14747 && can_create_pseudo_p ()" 14748 "#" 14749 "&& 1" 14750 [(const_int 0)] 14751{ 14752 operands[2] = assign_386_stack_local (<MODE>mode, SLOT_TEMP); 14753 emit_insn (gen_fist<mode>2_with_temp (operands[0], operands[1], 14754 operands[2])); 14755 DONE; 14756} 14757 [(set_attr "type" "fpspc") 14758 (set_attr "mode" "<MODE>")]) 14759 14760(define_insn "fist<mode>2" 14761 [(set (match_operand:SWI24 0 "memory_operand" "=m") 14762 (unspec:SWI24 [(match_operand:XF 1 "register_operand" "f")] 14763 UNSPEC_FIST))] 14764 "TARGET_USE_FANCY_MATH_387" 14765 "* return output_fix_trunc (insn, operands, false);" 14766 [(set_attr "type" "fpspc") 14767 (set_attr "mode" "<MODE>")]) 14768 14769(define_insn "fist<mode>2_with_temp" 14770 [(set (match_operand:SWI24 0 "register_operand" "=r") 14771 (unspec:SWI24 [(match_operand:XF 1 "register_operand" "f")] 14772 UNSPEC_FIST)) 14773 (clobber (match_operand:SWI24 2 "memory_operand" "=m"))] 14774 "TARGET_USE_FANCY_MATH_387" 14775 "#" 14776 [(set_attr "type" "fpspc") 14777 (set_attr "mode" "<MODE>")]) 14778 14779(define_split 14780 [(set (match_operand:SWI24 0 "register_operand" "") 14781 (unspec:SWI24 [(match_operand:XF 1 "register_operand" "")] 14782 UNSPEC_FIST)) 14783 (clobber (match_operand:SWI24 2 "memory_operand" ""))] 14784 "reload_completed" 14785 [(set (match_dup 2) (unspec:SWI24 [(match_dup 1)] UNSPEC_FIST)) 14786 (set (match_dup 0) (match_dup 2))]) 14787 14788(define_split 14789 [(set (match_operand:SWI24 0 "memory_operand" "") 14790 (unspec:SWI24 [(match_operand:XF 1 "register_operand" "")] 14791 UNSPEC_FIST)) 14792 (clobber (match_operand:SWI24 2 "memory_operand" ""))] 14793 "reload_completed" 14794 [(set (match_dup 0) (unspec:SWI24 [(match_dup 1)] UNSPEC_FIST))]) 14795 14796(define_expand "lrintxf<mode>2" 14797 [(set (match_operand:SWI248x 0 "nonimmediate_operand" "") 14798 (unspec:SWI248x [(match_operand:XF 1 "register_operand" "")] 14799 UNSPEC_FIST))] 14800 "TARGET_USE_FANCY_MATH_387") 14801 14802(define_expand "lrint<MODEF:mode><SWI48x:mode>2" 14803 [(set (match_operand:SWI48x 0 "nonimmediate_operand" "") 14804 (unspec:SWI48x [(match_operand:MODEF 1 "register_operand" "")] 14805 UNSPEC_FIX_NOTRUNC))] 14806 "SSE_FLOAT_MODE_P (<MODEF:MODE>mode) && TARGET_SSE_MATH 14807 && ((<SWI48x:MODE>mode != DImode) || TARGET_64BIT)") 14808 14809(define_expand "lround<X87MODEF:mode><SWI248x:mode>2" 14810 [(match_operand:SWI248x 0 "nonimmediate_operand" "") 14811 (match_operand:X87MODEF 1 "register_operand" "")] 14812 "(TARGET_USE_FANCY_MATH_387 14813 && (!(SSE_FLOAT_MODE_P (<X87MODEF:MODE>mode) && TARGET_SSE_MATH) 14814 || TARGET_MIX_SSE_I387) 14815 && flag_unsafe_math_optimizations) 14816 || (SSE_FLOAT_MODE_P (<X87MODEF:MODE>mode) && TARGET_SSE_MATH 14817 && <SWI248x:MODE>mode != HImode 14818 && ((<SWI248x:MODE>mode != DImode) || TARGET_64BIT) 14819 && !flag_trapping_math && !flag_rounding_math)" 14820{ 14821 if (optimize_insn_for_size_p ()) 14822 FAIL; 14823 14824 if (SSE_FLOAT_MODE_P (<X87MODEF:MODE>mode) && TARGET_SSE_MATH 14825 && <SWI248x:MODE>mode != HImode 14826 && ((<SWI248x:MODE>mode != DImode) || TARGET_64BIT) 14827 && !flag_trapping_math && !flag_rounding_math) 14828 ix86_expand_lround (operands[0], operands[1]); 14829 else 14830 ix86_emit_i387_round (operands[0], operands[1]); 14831 DONE; 14832}) 14833 14834;; Rounding mode control word calculation could clobber FLAGS_REG. 14835(define_insn_and_split "frndintxf2_floor" 14836 [(set (match_operand:XF 0 "register_operand" "") 14837 (unspec:XF [(match_operand:XF 1 "register_operand" "")] 14838 UNSPEC_FRNDINT_FLOOR)) 14839 (clobber (reg:CC FLAGS_REG))] 14840 "TARGET_USE_FANCY_MATH_387 14841 && flag_unsafe_math_optimizations 14842 && can_create_pseudo_p ()" 14843 "#" 14844 "&& 1" 14845 [(const_int 0)] 14846{ 14847 ix86_optimize_mode_switching[I387_FLOOR] = 1; 14848 14849 operands[2] = assign_386_stack_local (HImode, SLOT_CW_STORED); 14850 operands[3] = assign_386_stack_local (HImode, SLOT_CW_FLOOR); 14851 14852 emit_insn (gen_frndintxf2_floor_i387 (operands[0], operands[1], 14853 operands[2], operands[3])); 14854 DONE; 14855} 14856 [(set_attr "type" "frndint") 14857 (set_attr "i387_cw" "floor") 14858 (set_attr "mode" "XF")]) 14859 14860(define_insn "frndintxf2_floor_i387" 14861 [(set (match_operand:XF 0 "register_operand" "=f") 14862 (unspec:XF [(match_operand:XF 1 "register_operand" "0")] 14863 UNSPEC_FRNDINT_FLOOR)) 14864 (use (match_operand:HI 2 "memory_operand" "m")) 14865 (use (match_operand:HI 3 "memory_operand" "m"))] 14866 "TARGET_USE_FANCY_MATH_387 14867 && flag_unsafe_math_optimizations" 14868 "fldcw\t%3\n\tfrndint\n\tfldcw\t%2" 14869 [(set_attr "type" "frndint") 14870 (set_attr "i387_cw" "floor") 14871 (set_attr "mode" "XF")]) 14872 14873(define_expand "floorxf2" 14874 [(use (match_operand:XF 0 "register_operand" "")) 14875 (use (match_operand:XF 1 "register_operand" ""))] 14876 "TARGET_USE_FANCY_MATH_387 14877 && flag_unsafe_math_optimizations" 14878{ 14879 if (optimize_insn_for_size_p ()) 14880 FAIL; 14881 emit_insn (gen_frndintxf2_floor (operands[0], operands[1])); 14882 DONE; 14883}) 14884 14885(define_expand "floor<mode>2" 14886 [(use (match_operand:MODEF 0 "register_operand" "")) 14887 (use (match_operand:MODEF 1 "register_operand" ""))] 14888 "(TARGET_USE_FANCY_MATH_387 14889 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH) 14890 || TARGET_MIX_SSE_I387) 14891 && flag_unsafe_math_optimizations) 14892 || (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH 14893 && !flag_trapping_math)" 14894{ 14895 if (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH 14896 && !flag_trapping_math) 14897 { 14898 if (TARGET_ROUND) 14899 emit_insn (gen_sse4_1_round<mode>2 14900 (operands[0], operands[1], GEN_INT (ROUND_FLOOR))); 14901 else if (optimize_insn_for_size_p ()) 14902 FAIL; 14903 else if (TARGET_64BIT || (<MODE>mode != DFmode)) 14904 ix86_expand_floorceil (operands[0], operands[1], true); 14905 else 14906 ix86_expand_floorceildf_32 (operands[0], operands[1], true); 14907 } 14908 else 14909 { 14910 rtx op0, op1; 14911 14912 if (optimize_insn_for_size_p ()) 14913 FAIL; 14914 14915 op0 = gen_reg_rtx (XFmode); 14916 op1 = gen_reg_rtx (XFmode); 14917 emit_insn (gen_extend<mode>xf2 (op1, operands[1])); 14918 emit_insn (gen_frndintxf2_floor (op0, op1)); 14919 14920 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0)); 14921 } 14922 DONE; 14923}) 14924 14925(define_insn_and_split "*fist<mode>2_floor_1" 14926 [(set (match_operand:SWI248x 0 "nonimmediate_operand" "") 14927 (unspec:SWI248x [(match_operand:XF 1 "register_operand" "")] 14928 UNSPEC_FIST_FLOOR)) 14929 (clobber (reg:CC FLAGS_REG))] 14930 "TARGET_USE_FANCY_MATH_387 14931 && flag_unsafe_math_optimizations 14932 && can_create_pseudo_p ()" 14933 "#" 14934 "&& 1" 14935 [(const_int 0)] 14936{ 14937 ix86_optimize_mode_switching[I387_FLOOR] = 1; 14938 14939 operands[2] = assign_386_stack_local (HImode, SLOT_CW_STORED); 14940 operands[3] = assign_386_stack_local (HImode, SLOT_CW_FLOOR); 14941 if (memory_operand (operands[0], VOIDmode)) 14942 emit_insn (gen_fist<mode>2_floor (operands[0], operands[1], 14943 operands[2], operands[3])); 14944 else 14945 { 14946 operands[4] = assign_386_stack_local (<MODE>mode, SLOT_TEMP); 14947 emit_insn (gen_fist<mode>2_floor_with_temp (operands[0], operands[1], 14948 operands[2], operands[3], 14949 operands[4])); 14950 } 14951 DONE; 14952} 14953 [(set_attr "type" "fistp") 14954 (set_attr "i387_cw" "floor") 14955 (set_attr "mode" "<MODE>")]) 14956 14957(define_insn "fistdi2_floor" 14958 [(set (match_operand:DI 0 "memory_operand" "=m") 14959 (unspec:DI [(match_operand:XF 1 "register_operand" "f")] 14960 UNSPEC_FIST_FLOOR)) 14961 (use (match_operand:HI 2 "memory_operand" "m")) 14962 (use (match_operand:HI 3 "memory_operand" "m")) 14963 (clobber (match_scratch:XF 4 "=&1f"))] 14964 "TARGET_USE_FANCY_MATH_387 14965 && flag_unsafe_math_optimizations" 14966 "* return output_fix_trunc (insn, operands, false);" 14967 [(set_attr "type" "fistp") 14968 (set_attr "i387_cw" "floor") 14969 (set_attr "mode" "DI")]) 14970 14971(define_insn "fistdi2_floor_with_temp" 14972 [(set (match_operand:DI 0 "nonimmediate_operand" "=m,?r") 14973 (unspec:DI [(match_operand:XF 1 "register_operand" "f,f")] 14974 UNSPEC_FIST_FLOOR)) 14975 (use (match_operand:HI 2 "memory_operand" "m,m")) 14976 (use (match_operand:HI 3 "memory_operand" "m,m")) 14977 (clobber (match_operand:DI 4 "memory_operand" "=X,m")) 14978 (clobber (match_scratch:XF 5 "=&1f,&1f"))] 14979 "TARGET_USE_FANCY_MATH_387 14980 && flag_unsafe_math_optimizations" 14981 "#" 14982 [(set_attr "type" "fistp") 14983 (set_attr "i387_cw" "floor") 14984 (set_attr "mode" "DI")]) 14985 14986(define_split 14987 [(set (match_operand:DI 0 "register_operand" "") 14988 (unspec:DI [(match_operand:XF 1 "register_operand" "")] 14989 UNSPEC_FIST_FLOOR)) 14990 (use (match_operand:HI 2 "memory_operand" "")) 14991 (use (match_operand:HI 3 "memory_operand" "")) 14992 (clobber (match_operand:DI 4 "memory_operand" "")) 14993 (clobber (match_scratch 5 ""))] 14994 "reload_completed" 14995 [(parallel [(set (match_dup 4) 14996 (unspec:DI [(match_dup 1)] UNSPEC_FIST_FLOOR)) 14997 (use (match_dup 2)) 14998 (use (match_dup 3)) 14999 (clobber (match_dup 5))]) 15000 (set (match_dup 0) (match_dup 4))]) 15001 15002(define_split 15003 [(set (match_operand:DI 0 "memory_operand" "") 15004 (unspec:DI [(match_operand:XF 1 "register_operand" "")] 15005 UNSPEC_FIST_FLOOR)) 15006 (use (match_operand:HI 2 "memory_operand" "")) 15007 (use (match_operand:HI 3 "memory_operand" "")) 15008 (clobber (match_operand:DI 4 "memory_operand" "")) 15009 (clobber (match_scratch 5 ""))] 15010 "reload_completed" 15011 [(parallel [(set (match_dup 0) 15012 (unspec:DI [(match_dup 1)] UNSPEC_FIST_FLOOR)) 15013 (use (match_dup 2)) 15014 (use (match_dup 3)) 15015 (clobber (match_dup 5))])]) 15016 15017(define_insn "fist<mode>2_floor" 15018 [(set (match_operand:SWI24 0 "memory_operand" "=m") 15019 (unspec:SWI24 [(match_operand:XF 1 "register_operand" "f")] 15020 UNSPEC_FIST_FLOOR)) 15021 (use (match_operand:HI 2 "memory_operand" "m")) 15022 (use (match_operand:HI 3 "memory_operand" "m"))] 15023 "TARGET_USE_FANCY_MATH_387 15024 && flag_unsafe_math_optimizations" 15025 "* return output_fix_trunc (insn, operands, false);" 15026 [(set_attr "type" "fistp") 15027 (set_attr "i387_cw" "floor") 15028 (set_attr "mode" "<MODE>")]) 15029 15030(define_insn "fist<mode>2_floor_with_temp" 15031 [(set (match_operand:SWI24 0 "nonimmediate_operand" "=m,?r") 15032 (unspec:SWI24 [(match_operand:XF 1 "register_operand" "f,f")] 15033 UNSPEC_FIST_FLOOR)) 15034 (use (match_operand:HI 2 "memory_operand" "m,m")) 15035 (use (match_operand:HI 3 "memory_operand" "m,m")) 15036 (clobber (match_operand:SWI24 4 "memory_operand" "=X,m"))] 15037 "TARGET_USE_FANCY_MATH_387 15038 && flag_unsafe_math_optimizations" 15039 "#" 15040 [(set_attr "type" "fistp") 15041 (set_attr "i387_cw" "floor") 15042 (set_attr "mode" "<MODE>")]) 15043 15044(define_split 15045 [(set (match_operand:SWI24 0 "register_operand" "") 15046 (unspec:SWI24 [(match_operand:XF 1 "register_operand" "")] 15047 UNSPEC_FIST_FLOOR)) 15048 (use (match_operand:HI 2 "memory_operand" "")) 15049 (use (match_operand:HI 3 "memory_operand" "")) 15050 (clobber (match_operand:SWI24 4 "memory_operand" ""))] 15051 "reload_completed" 15052 [(parallel [(set (match_dup 4) 15053 (unspec:SWI24 [(match_dup 1)] UNSPEC_FIST_FLOOR)) 15054 (use (match_dup 2)) 15055 (use (match_dup 3))]) 15056 (set (match_dup 0) (match_dup 4))]) 15057 15058(define_split 15059 [(set (match_operand:SWI24 0 "memory_operand" "") 15060 (unspec:SWI24 [(match_operand:XF 1 "register_operand" "")] 15061 UNSPEC_FIST_FLOOR)) 15062 (use (match_operand:HI 2 "memory_operand" "")) 15063 (use (match_operand:HI 3 "memory_operand" "")) 15064 (clobber (match_operand:SWI24 4 "memory_operand" ""))] 15065 "reload_completed" 15066 [(parallel [(set (match_dup 0) 15067 (unspec:SWI24 [(match_dup 1)] UNSPEC_FIST_FLOOR)) 15068 (use (match_dup 2)) 15069 (use (match_dup 3))])]) 15070 15071(define_expand "lfloorxf<mode>2" 15072 [(parallel [(set (match_operand:SWI248x 0 "nonimmediate_operand" "") 15073 (unspec:SWI248x [(match_operand:XF 1 "register_operand" "")] 15074 UNSPEC_FIST_FLOOR)) 15075 (clobber (reg:CC FLAGS_REG))])] 15076 "TARGET_USE_FANCY_MATH_387 15077 && (!TARGET_SSE_MATH || TARGET_MIX_SSE_I387) 15078 && flag_unsafe_math_optimizations") 15079 15080(define_expand "lfloor<MODEF:mode><SWI48:mode>2" 15081 [(match_operand:SWI48 0 "nonimmediate_operand" "") 15082 (match_operand:MODEF 1 "register_operand" "")] 15083 "SSE_FLOAT_MODE_P (<MODEF:MODE>mode) && TARGET_SSE_MATH 15084 && !flag_trapping_math" 15085{ 15086 if (TARGET_64BIT && optimize_insn_for_size_p ()) 15087 FAIL; 15088 ix86_expand_lfloorceil (operands[0], operands[1], true); 15089 DONE; 15090}) 15091 15092;; Rounding mode control word calculation could clobber FLAGS_REG. 15093(define_insn_and_split "frndintxf2_ceil" 15094 [(set (match_operand:XF 0 "register_operand" "") 15095 (unspec:XF [(match_operand:XF 1 "register_operand" "")] 15096 UNSPEC_FRNDINT_CEIL)) 15097 (clobber (reg:CC FLAGS_REG))] 15098 "TARGET_USE_FANCY_MATH_387 15099 && flag_unsafe_math_optimizations 15100 && can_create_pseudo_p ()" 15101 "#" 15102 "&& 1" 15103 [(const_int 0)] 15104{ 15105 ix86_optimize_mode_switching[I387_CEIL] = 1; 15106 15107 operands[2] = assign_386_stack_local (HImode, SLOT_CW_STORED); 15108 operands[3] = assign_386_stack_local (HImode, SLOT_CW_CEIL); 15109 15110 emit_insn (gen_frndintxf2_ceil_i387 (operands[0], operands[1], 15111 operands[2], operands[3])); 15112 DONE; 15113} 15114 [(set_attr "type" "frndint") 15115 (set_attr "i387_cw" "ceil") 15116 (set_attr "mode" "XF")]) 15117 15118(define_insn "frndintxf2_ceil_i387" 15119 [(set (match_operand:XF 0 "register_operand" "=f") 15120 (unspec:XF [(match_operand:XF 1 "register_operand" "0")] 15121 UNSPEC_FRNDINT_CEIL)) 15122 (use (match_operand:HI 2 "memory_operand" "m")) 15123 (use (match_operand:HI 3 "memory_operand" "m"))] 15124 "TARGET_USE_FANCY_MATH_387 15125 && flag_unsafe_math_optimizations" 15126 "fldcw\t%3\n\tfrndint\n\tfldcw\t%2" 15127 [(set_attr "type" "frndint") 15128 (set_attr "i387_cw" "ceil") 15129 (set_attr "mode" "XF")]) 15130 15131(define_expand "ceilxf2" 15132 [(use (match_operand:XF 0 "register_operand" "")) 15133 (use (match_operand:XF 1 "register_operand" ""))] 15134 "TARGET_USE_FANCY_MATH_387 15135 && flag_unsafe_math_optimizations" 15136{ 15137 if (optimize_insn_for_size_p ()) 15138 FAIL; 15139 emit_insn (gen_frndintxf2_ceil (operands[0], operands[1])); 15140 DONE; 15141}) 15142 15143(define_expand "ceil<mode>2" 15144 [(use (match_operand:MODEF 0 "register_operand" "")) 15145 (use (match_operand:MODEF 1 "register_operand" ""))] 15146 "(TARGET_USE_FANCY_MATH_387 15147 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH) 15148 || TARGET_MIX_SSE_I387) 15149 && flag_unsafe_math_optimizations) 15150 || (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH 15151 && !flag_trapping_math)" 15152{ 15153 if (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH 15154 && !flag_trapping_math) 15155 { 15156 if (TARGET_ROUND) 15157 emit_insn (gen_sse4_1_round<mode>2 15158 (operands[0], operands[1], GEN_INT (ROUND_CEIL))); 15159 else if (optimize_insn_for_size_p ()) 15160 FAIL; 15161 else if (TARGET_64BIT || (<MODE>mode != DFmode)) 15162 ix86_expand_floorceil (operands[0], operands[1], false); 15163 else 15164 ix86_expand_floorceildf_32 (operands[0], operands[1], false); 15165 } 15166 else 15167 { 15168 rtx op0, op1; 15169 15170 if (optimize_insn_for_size_p ()) 15171 FAIL; 15172 15173 op0 = gen_reg_rtx (XFmode); 15174 op1 = gen_reg_rtx (XFmode); 15175 emit_insn (gen_extend<mode>xf2 (op1, operands[1])); 15176 emit_insn (gen_frndintxf2_ceil (op0, op1)); 15177 15178 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0)); 15179 } 15180 DONE; 15181}) 15182 15183(define_insn_and_split "*fist<mode>2_ceil_1" 15184 [(set (match_operand:SWI248x 0 "nonimmediate_operand" "") 15185 (unspec:SWI248x [(match_operand:XF 1 "register_operand" "")] 15186 UNSPEC_FIST_CEIL)) 15187 (clobber (reg:CC FLAGS_REG))] 15188 "TARGET_USE_FANCY_MATH_387 15189 && flag_unsafe_math_optimizations 15190 && can_create_pseudo_p ()" 15191 "#" 15192 "&& 1" 15193 [(const_int 0)] 15194{ 15195 ix86_optimize_mode_switching[I387_CEIL] = 1; 15196 15197 operands[2] = assign_386_stack_local (HImode, SLOT_CW_STORED); 15198 operands[3] = assign_386_stack_local (HImode, SLOT_CW_CEIL); 15199 if (memory_operand (operands[0], VOIDmode)) 15200 emit_insn (gen_fist<mode>2_ceil (operands[0], operands[1], 15201 operands[2], operands[3])); 15202 else 15203 { 15204 operands[4] = assign_386_stack_local (<MODE>mode, SLOT_TEMP); 15205 emit_insn (gen_fist<mode>2_ceil_with_temp (operands[0], operands[1], 15206 operands[2], operands[3], 15207 operands[4])); 15208 } 15209 DONE; 15210} 15211 [(set_attr "type" "fistp") 15212 (set_attr "i387_cw" "ceil") 15213 (set_attr "mode" "<MODE>")]) 15214 15215(define_insn "fistdi2_ceil" 15216 [(set (match_operand:DI 0 "memory_operand" "=m") 15217 (unspec:DI [(match_operand:XF 1 "register_operand" "f")] 15218 UNSPEC_FIST_CEIL)) 15219 (use (match_operand:HI 2 "memory_operand" "m")) 15220 (use (match_operand:HI 3 "memory_operand" "m")) 15221 (clobber (match_scratch:XF 4 "=&1f"))] 15222 "TARGET_USE_FANCY_MATH_387 15223 && flag_unsafe_math_optimizations" 15224 "* return output_fix_trunc (insn, operands, false);" 15225 [(set_attr "type" "fistp") 15226 (set_attr "i387_cw" "ceil") 15227 (set_attr "mode" "DI")]) 15228 15229(define_insn "fistdi2_ceil_with_temp" 15230 [(set (match_operand:DI 0 "nonimmediate_operand" "=m,?r") 15231 (unspec:DI [(match_operand:XF 1 "register_operand" "f,f")] 15232 UNSPEC_FIST_CEIL)) 15233 (use (match_operand:HI 2 "memory_operand" "m,m")) 15234 (use (match_operand:HI 3 "memory_operand" "m,m")) 15235 (clobber (match_operand:DI 4 "memory_operand" "=X,m")) 15236 (clobber (match_scratch:XF 5 "=&1f,&1f"))] 15237 "TARGET_USE_FANCY_MATH_387 15238 && flag_unsafe_math_optimizations" 15239 "#" 15240 [(set_attr "type" "fistp") 15241 (set_attr "i387_cw" "ceil") 15242 (set_attr "mode" "DI")]) 15243 15244(define_split 15245 [(set (match_operand:DI 0 "register_operand" "") 15246 (unspec:DI [(match_operand:XF 1 "register_operand" "")] 15247 UNSPEC_FIST_CEIL)) 15248 (use (match_operand:HI 2 "memory_operand" "")) 15249 (use (match_operand:HI 3 "memory_operand" "")) 15250 (clobber (match_operand:DI 4 "memory_operand" "")) 15251 (clobber (match_scratch 5 ""))] 15252 "reload_completed" 15253 [(parallel [(set (match_dup 4) 15254 (unspec:DI [(match_dup 1)] UNSPEC_FIST_CEIL)) 15255 (use (match_dup 2)) 15256 (use (match_dup 3)) 15257 (clobber (match_dup 5))]) 15258 (set (match_dup 0) (match_dup 4))]) 15259 15260(define_split 15261 [(set (match_operand:DI 0 "memory_operand" "") 15262 (unspec:DI [(match_operand:XF 1 "register_operand" "")] 15263 UNSPEC_FIST_CEIL)) 15264 (use (match_operand:HI 2 "memory_operand" "")) 15265 (use (match_operand:HI 3 "memory_operand" "")) 15266 (clobber (match_operand:DI 4 "memory_operand" "")) 15267 (clobber (match_scratch 5 ""))] 15268 "reload_completed" 15269 [(parallel [(set (match_dup 0) 15270 (unspec:DI [(match_dup 1)] UNSPEC_FIST_CEIL)) 15271 (use (match_dup 2)) 15272 (use (match_dup 3)) 15273 (clobber (match_dup 5))])]) 15274 15275(define_insn "fist<mode>2_ceil" 15276 [(set (match_operand:SWI24 0 "memory_operand" "=m") 15277 (unspec:SWI24 [(match_operand:XF 1 "register_operand" "f")] 15278 UNSPEC_FIST_CEIL)) 15279 (use (match_operand:HI 2 "memory_operand" "m")) 15280 (use (match_operand:HI 3 "memory_operand" "m"))] 15281 "TARGET_USE_FANCY_MATH_387 15282 && flag_unsafe_math_optimizations" 15283 "* return output_fix_trunc (insn, operands, false);" 15284 [(set_attr "type" "fistp") 15285 (set_attr "i387_cw" "ceil") 15286 (set_attr "mode" "<MODE>")]) 15287 15288(define_insn "fist<mode>2_ceil_with_temp" 15289 [(set (match_operand:SWI24 0 "nonimmediate_operand" "=m,?r") 15290 (unspec:SWI24 [(match_operand:XF 1 "register_operand" "f,f")] 15291 UNSPEC_FIST_CEIL)) 15292 (use (match_operand:HI 2 "memory_operand" "m,m")) 15293 (use (match_operand:HI 3 "memory_operand" "m,m")) 15294 (clobber (match_operand:SWI24 4 "memory_operand" "=X,m"))] 15295 "TARGET_USE_FANCY_MATH_387 15296 && flag_unsafe_math_optimizations" 15297 "#" 15298 [(set_attr "type" "fistp") 15299 (set_attr "i387_cw" "ceil") 15300 (set_attr "mode" "<MODE>")]) 15301 15302(define_split 15303 [(set (match_operand:SWI24 0 "register_operand" "") 15304 (unspec:SWI24 [(match_operand:XF 1 "register_operand" "")] 15305 UNSPEC_FIST_CEIL)) 15306 (use (match_operand:HI 2 "memory_operand" "")) 15307 (use (match_operand:HI 3 "memory_operand" "")) 15308 (clobber (match_operand:SWI24 4 "memory_operand" ""))] 15309 "reload_completed" 15310 [(parallel [(set (match_dup 4) 15311 (unspec:SWI24 [(match_dup 1)] UNSPEC_FIST_CEIL)) 15312 (use (match_dup 2)) 15313 (use (match_dup 3))]) 15314 (set (match_dup 0) (match_dup 4))]) 15315 15316(define_split 15317 [(set (match_operand:SWI24 0 "memory_operand" "") 15318 (unspec:SWI24 [(match_operand:XF 1 "register_operand" "")] 15319 UNSPEC_FIST_CEIL)) 15320 (use (match_operand:HI 2 "memory_operand" "")) 15321 (use (match_operand:HI 3 "memory_operand" "")) 15322 (clobber (match_operand:SWI24 4 "memory_operand" ""))] 15323 "reload_completed" 15324 [(parallel [(set (match_dup 0) 15325 (unspec:SWI24 [(match_dup 1)] UNSPEC_FIST_CEIL)) 15326 (use (match_dup 2)) 15327 (use (match_dup 3))])]) 15328 15329(define_expand "lceilxf<mode>2" 15330 [(parallel [(set (match_operand:SWI248x 0 "nonimmediate_operand" "") 15331 (unspec:SWI248x [(match_operand:XF 1 "register_operand" "")] 15332 UNSPEC_FIST_CEIL)) 15333 (clobber (reg:CC FLAGS_REG))])] 15334 "TARGET_USE_FANCY_MATH_387 15335 && (!TARGET_SSE_MATH || TARGET_MIX_SSE_I387) 15336 && flag_unsafe_math_optimizations") 15337 15338(define_expand "lceil<MODEF:mode><SWI48:mode>2" 15339 [(match_operand:SWI48 0 "nonimmediate_operand" "") 15340 (match_operand:MODEF 1 "register_operand" "")] 15341 "SSE_FLOAT_MODE_P (<MODEF:MODE>mode) && TARGET_SSE_MATH 15342 && !flag_trapping_math" 15343{ 15344 ix86_expand_lfloorceil (operands[0], operands[1], false); 15345 DONE; 15346}) 15347 15348;; Rounding mode control word calculation could clobber FLAGS_REG. 15349(define_insn_and_split "frndintxf2_trunc" 15350 [(set (match_operand:XF 0 "register_operand" "") 15351 (unspec:XF [(match_operand:XF 1 "register_operand" "")] 15352 UNSPEC_FRNDINT_TRUNC)) 15353 (clobber (reg:CC FLAGS_REG))] 15354 "TARGET_USE_FANCY_MATH_387 15355 && flag_unsafe_math_optimizations 15356 && can_create_pseudo_p ()" 15357 "#" 15358 "&& 1" 15359 [(const_int 0)] 15360{ 15361 ix86_optimize_mode_switching[I387_TRUNC] = 1; 15362 15363 operands[2] = assign_386_stack_local (HImode, SLOT_CW_STORED); 15364 operands[3] = assign_386_stack_local (HImode, SLOT_CW_TRUNC); 15365 15366 emit_insn (gen_frndintxf2_trunc_i387 (operands[0], operands[1], 15367 operands[2], operands[3])); 15368 DONE; 15369} 15370 [(set_attr "type" "frndint") 15371 (set_attr "i387_cw" "trunc") 15372 (set_attr "mode" "XF")]) 15373 15374(define_insn "frndintxf2_trunc_i387" 15375 [(set (match_operand:XF 0 "register_operand" "=f") 15376 (unspec:XF [(match_operand:XF 1 "register_operand" "0")] 15377 UNSPEC_FRNDINT_TRUNC)) 15378 (use (match_operand:HI 2 "memory_operand" "m")) 15379 (use (match_operand:HI 3 "memory_operand" "m"))] 15380 "TARGET_USE_FANCY_MATH_387 15381 && flag_unsafe_math_optimizations" 15382 "fldcw\t%3\n\tfrndint\n\tfldcw\t%2" 15383 [(set_attr "type" "frndint") 15384 (set_attr "i387_cw" "trunc") 15385 (set_attr "mode" "XF")]) 15386 15387(define_expand "btruncxf2" 15388 [(use (match_operand:XF 0 "register_operand" "")) 15389 (use (match_operand:XF 1 "register_operand" ""))] 15390 "TARGET_USE_FANCY_MATH_387 15391 && flag_unsafe_math_optimizations" 15392{ 15393 if (optimize_insn_for_size_p ()) 15394 FAIL; 15395 emit_insn (gen_frndintxf2_trunc (operands[0], operands[1])); 15396 DONE; 15397}) 15398 15399(define_expand "btrunc<mode>2" 15400 [(use (match_operand:MODEF 0 "register_operand" "")) 15401 (use (match_operand:MODEF 1 "register_operand" ""))] 15402 "(TARGET_USE_FANCY_MATH_387 15403 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH) 15404 || TARGET_MIX_SSE_I387) 15405 && flag_unsafe_math_optimizations) 15406 || (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH 15407 && !flag_trapping_math)" 15408{ 15409 if (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH 15410 && !flag_trapping_math) 15411 { 15412 if (TARGET_ROUND) 15413 emit_insn (gen_sse4_1_round<mode>2 15414 (operands[0], operands[1], GEN_INT (ROUND_TRUNC))); 15415 else if (optimize_insn_for_size_p ()) 15416 FAIL; 15417 else if (TARGET_64BIT || (<MODE>mode != DFmode)) 15418 ix86_expand_trunc (operands[0], operands[1]); 15419 else 15420 ix86_expand_truncdf_32 (operands[0], operands[1]); 15421 } 15422 else 15423 { 15424 rtx op0, op1; 15425 15426 if (optimize_insn_for_size_p ()) 15427 FAIL; 15428 15429 op0 = gen_reg_rtx (XFmode); 15430 op1 = gen_reg_rtx (XFmode); 15431 emit_insn (gen_extend<mode>xf2 (op1, operands[1])); 15432 emit_insn (gen_frndintxf2_trunc (op0, op1)); 15433 15434 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0)); 15435 } 15436 DONE; 15437}) 15438 15439;; Rounding mode control word calculation could clobber FLAGS_REG. 15440(define_insn_and_split "frndintxf2_mask_pm" 15441 [(set (match_operand:XF 0 "register_operand" "") 15442 (unspec:XF [(match_operand:XF 1 "register_operand" "")] 15443 UNSPEC_FRNDINT_MASK_PM)) 15444 (clobber (reg:CC FLAGS_REG))] 15445 "TARGET_USE_FANCY_MATH_387 15446 && flag_unsafe_math_optimizations 15447 && can_create_pseudo_p ()" 15448 "#" 15449 "&& 1" 15450 [(const_int 0)] 15451{ 15452 ix86_optimize_mode_switching[I387_MASK_PM] = 1; 15453 15454 operands[2] = assign_386_stack_local (HImode, SLOT_CW_STORED); 15455 operands[3] = assign_386_stack_local (HImode, SLOT_CW_MASK_PM); 15456 15457 emit_insn (gen_frndintxf2_mask_pm_i387 (operands[0], operands[1], 15458 operands[2], operands[3])); 15459 DONE; 15460} 15461 [(set_attr "type" "frndint") 15462 (set_attr "i387_cw" "mask_pm") 15463 (set_attr "mode" "XF")]) 15464 15465(define_insn "frndintxf2_mask_pm_i387" 15466 [(set (match_operand:XF 0 "register_operand" "=f") 15467 (unspec:XF [(match_operand:XF 1 "register_operand" "0")] 15468 UNSPEC_FRNDINT_MASK_PM)) 15469 (use (match_operand:HI 2 "memory_operand" "m")) 15470 (use (match_operand:HI 3 "memory_operand" "m"))] 15471 "TARGET_USE_FANCY_MATH_387 15472 && flag_unsafe_math_optimizations" 15473 "fldcw\t%3\n\tfrndint\n\tfclex\n\tfldcw\t%2" 15474 [(set_attr "type" "frndint") 15475 (set_attr "i387_cw" "mask_pm") 15476 (set_attr "mode" "XF")]) 15477 15478(define_expand "nearbyintxf2" 15479 [(use (match_operand:XF 0 "register_operand" "")) 15480 (use (match_operand:XF 1 "register_operand" ""))] 15481 "TARGET_USE_FANCY_MATH_387 15482 && flag_unsafe_math_optimizations" 15483{ 15484 emit_insn (gen_frndintxf2_mask_pm (operands[0], operands[1])); 15485 DONE; 15486}) 15487 15488(define_expand "nearbyint<mode>2" 15489 [(use (match_operand:MODEF 0 "register_operand" "")) 15490 (use (match_operand:MODEF 1 "register_operand" ""))] 15491 "TARGET_USE_FANCY_MATH_387 15492 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH) 15493 || TARGET_MIX_SSE_I387) 15494 && flag_unsafe_math_optimizations" 15495{ 15496 rtx op0 = gen_reg_rtx (XFmode); 15497 rtx op1 = gen_reg_rtx (XFmode); 15498 15499 emit_insn (gen_extend<mode>xf2 (op1, operands[1])); 15500 emit_insn (gen_frndintxf2_mask_pm (op0, op1)); 15501 15502 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0)); 15503 DONE; 15504}) 15505 15506(define_insn "fxam<mode>2_i387" 15507 [(set (match_operand:HI 0 "register_operand" "=a") 15508 (unspec:HI 15509 [(match_operand:X87MODEF 1 "register_operand" "f")] 15510 UNSPEC_FXAM))] 15511 "TARGET_USE_FANCY_MATH_387" 15512 "fxam\n\tfnstsw\t%0" 15513 [(set_attr "type" "multi") 15514 (set_attr "length" "4") 15515 (set_attr "unit" "i387") 15516 (set_attr "mode" "<MODE>")]) 15517 15518(define_insn_and_split "fxam<mode>2_i387_with_temp" 15519 [(set (match_operand:HI 0 "register_operand" "") 15520 (unspec:HI 15521 [(match_operand:MODEF 1 "memory_operand" "")] 15522 UNSPEC_FXAM_MEM))] 15523 "TARGET_USE_FANCY_MATH_387 15524 && can_create_pseudo_p ()" 15525 "#" 15526 "&& 1" 15527 [(set (match_dup 2)(match_dup 1)) 15528 (set (match_dup 0) 15529 (unspec:HI [(match_dup 2)] UNSPEC_FXAM))] 15530{ 15531 operands[2] = gen_reg_rtx (<MODE>mode); 15532 15533 MEM_VOLATILE_P (operands[1]) = 1; 15534} 15535 [(set_attr "type" "multi") 15536 (set_attr "unit" "i387") 15537 (set_attr "mode" "<MODE>")]) 15538 15539(define_expand "isinfxf2" 15540 [(use (match_operand:SI 0 "register_operand" "")) 15541 (use (match_operand:XF 1 "register_operand" ""))] 15542 "TARGET_USE_FANCY_MATH_387 15543 && TARGET_C99_FUNCTIONS" 15544{ 15545 rtx mask = GEN_INT (0x45); 15546 rtx val = GEN_INT (0x05); 15547 15548 rtx cond; 15549 15550 rtx scratch = gen_reg_rtx (HImode); 15551 rtx res = gen_reg_rtx (QImode); 15552 15553 emit_insn (gen_fxamxf2_i387 (scratch, operands[1])); 15554 15555 emit_insn (gen_andqi_ext_0 (scratch, scratch, mask)); 15556 emit_insn (gen_cmpqi_ext_3 (scratch, val)); 15557 cond = gen_rtx_fmt_ee (EQ, QImode, 15558 gen_rtx_REG (CCmode, FLAGS_REG), 15559 const0_rtx); 15560 emit_insn (gen_rtx_SET (VOIDmode, res, cond)); 15561 emit_insn (gen_zero_extendqisi2 (operands[0], res)); 15562 DONE; 15563}) 15564 15565(define_expand "isinf<mode>2" 15566 [(use (match_operand:SI 0 "register_operand" "")) 15567 (use (match_operand:MODEF 1 "nonimmediate_operand" ""))] 15568 "TARGET_USE_FANCY_MATH_387 15569 && TARGET_C99_FUNCTIONS 15570 && !(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)" 15571{ 15572 rtx mask = GEN_INT (0x45); 15573 rtx val = GEN_INT (0x05); 15574 15575 rtx cond; 15576 15577 rtx scratch = gen_reg_rtx (HImode); 15578 rtx res = gen_reg_rtx (QImode); 15579 15580 /* Remove excess precision by forcing value through memory. */ 15581 if (memory_operand (operands[1], VOIDmode)) 15582 emit_insn (gen_fxam<mode>2_i387_with_temp (scratch, operands[1])); 15583 else 15584 { 15585 rtx temp = assign_386_stack_local (<MODE>mode, SLOT_TEMP); 15586 15587 emit_move_insn (temp, operands[1]); 15588 emit_insn (gen_fxam<mode>2_i387_with_temp (scratch, temp)); 15589 } 15590 15591 emit_insn (gen_andqi_ext_0 (scratch, scratch, mask)); 15592 emit_insn (gen_cmpqi_ext_3 (scratch, val)); 15593 cond = gen_rtx_fmt_ee (EQ, QImode, 15594 gen_rtx_REG (CCmode, FLAGS_REG), 15595 const0_rtx); 15596 emit_insn (gen_rtx_SET (VOIDmode, res, cond)); 15597 emit_insn (gen_zero_extendqisi2 (operands[0], res)); 15598 DONE; 15599}) 15600 15601(define_expand "signbitxf2" 15602 [(use (match_operand:SI 0 "register_operand" "")) 15603 (use (match_operand:XF 1 "register_operand" ""))] 15604 "TARGET_USE_FANCY_MATH_387" 15605{ 15606 rtx scratch = gen_reg_rtx (HImode); 15607 15608 emit_insn (gen_fxamxf2_i387 (scratch, operands[1])); 15609 emit_insn (gen_andsi3 (operands[0], 15610 gen_lowpart (SImode, scratch), GEN_INT (0x200))); 15611 DONE; 15612}) 15613 15614(define_insn "movmsk_df" 15615 [(set (match_operand:SI 0 "register_operand" "=r") 15616 (unspec:SI 15617 [(match_operand:DF 1 "register_operand" "x")] 15618 UNSPEC_MOVMSK))] 15619 "SSE_FLOAT_MODE_P (DFmode) && TARGET_SSE_MATH" 15620 "%vmovmskpd\t{%1, %0|%0, %1}" 15621 [(set_attr "type" "ssemov") 15622 (set_attr "prefix" "maybe_vex") 15623 (set_attr "mode" "DF")]) 15624 15625;; Use movmskpd in SSE mode to avoid store forwarding stall 15626;; for 32bit targets and movq+shrq sequence for 64bit targets. 15627(define_expand "signbitdf2" 15628 [(use (match_operand:SI 0 "register_operand" "")) 15629 (use (match_operand:DF 1 "register_operand" ""))] 15630 "TARGET_USE_FANCY_MATH_387 15631 || (SSE_FLOAT_MODE_P (DFmode) && TARGET_SSE_MATH)" 15632{ 15633 if (SSE_FLOAT_MODE_P (DFmode) && TARGET_SSE_MATH) 15634 { 15635 emit_insn (gen_movmsk_df (operands[0], operands[1])); 15636 emit_insn (gen_andsi3 (operands[0], operands[0], const1_rtx)); 15637 } 15638 else 15639 { 15640 rtx scratch = gen_reg_rtx (HImode); 15641 15642 emit_insn (gen_fxamdf2_i387 (scratch, operands[1])); 15643 emit_insn (gen_andsi3 (operands[0], 15644 gen_lowpart (SImode, scratch), GEN_INT (0x200))); 15645 } 15646 DONE; 15647}) 15648 15649(define_expand "signbitsf2" 15650 [(use (match_operand:SI 0 "register_operand" "")) 15651 (use (match_operand:SF 1 "register_operand" ""))] 15652 "TARGET_USE_FANCY_MATH_387 15653 && !(SSE_FLOAT_MODE_P (SFmode) && TARGET_SSE_MATH)" 15654{ 15655 rtx scratch = gen_reg_rtx (HImode); 15656 15657 emit_insn (gen_fxamsf2_i387 (scratch, operands[1])); 15658 emit_insn (gen_andsi3 (operands[0], 15659 gen_lowpart (SImode, scratch), GEN_INT (0x200))); 15660 DONE; 15661}) 15662 15663;; Block operation instructions 15664 15665(define_insn "cld" 15666 [(unspec_volatile [(const_int 0)] UNSPECV_CLD)] 15667 "" 15668 "cld" 15669 [(set_attr "length" "1") 15670 (set_attr "length_immediate" "0") 15671 (set_attr "modrm" "0")]) 15672 15673(define_expand "movmem<mode>" 15674 [(use (match_operand:BLK 0 "memory_operand" "")) 15675 (use (match_operand:BLK 1 "memory_operand" "")) 15676 (use (match_operand:SWI48 2 "nonmemory_operand" "")) 15677 (use (match_operand:SWI48 3 "const_int_operand" "")) 15678 (use (match_operand:SI 4 "const_int_operand" "")) 15679 (use (match_operand:SI 5 "const_int_operand" ""))] 15680 "" 15681{ 15682 if (ix86_expand_movmem (operands[0], operands[1], operands[2], operands[3], 15683 operands[4], operands[5])) 15684 DONE; 15685 else 15686 FAIL; 15687}) 15688 15689;; Most CPUs don't like single string operations 15690;; Handle this case here to simplify previous expander. 15691 15692(define_expand "strmov" 15693 [(set (match_dup 4) (match_operand 3 "memory_operand" "")) 15694 (set (match_operand 1 "memory_operand" "") (match_dup 4)) 15695 (parallel [(set (match_operand 0 "register_operand" "") (match_dup 5)) 15696 (clobber (reg:CC FLAGS_REG))]) 15697 (parallel [(set (match_operand 2 "register_operand" "") (match_dup 6)) 15698 (clobber (reg:CC FLAGS_REG))])] 15699 "" 15700{ 15701 rtx adjust = GEN_INT (GET_MODE_SIZE (GET_MODE (operands[1]))); 15702 15703 /* If .md ever supports :P for Pmode, these can be directly 15704 in the pattern above. */ 15705 operands[5] = gen_rtx_PLUS (Pmode, operands[0], adjust); 15706 operands[6] = gen_rtx_PLUS (Pmode, operands[2], adjust); 15707 15708 /* Can't use this if the user has appropriated esi or edi. */ 15709 if ((TARGET_SINGLE_STRINGOP || optimize_insn_for_size_p ()) 15710 && !(fixed_regs[SI_REG] || fixed_regs[DI_REG])) 15711 { 15712 emit_insn (gen_strmov_singleop (operands[0], operands[1], 15713 operands[2], operands[3], 15714 operands[5], operands[6])); 15715 DONE; 15716 } 15717 15718 operands[4] = gen_reg_rtx (GET_MODE (operands[1])); 15719}) 15720 15721(define_expand "strmov_singleop" 15722 [(parallel [(set (match_operand 1 "memory_operand" "") 15723 (match_operand 3 "memory_operand" "")) 15724 (set (match_operand 0 "register_operand" "") 15725 (match_operand 4 "" "")) 15726 (set (match_operand 2 "register_operand" "") 15727 (match_operand 5 "" ""))])] 15728 "" 15729 "ix86_current_function_needs_cld = 1;") 15730 15731(define_insn "*strmovdi_rex_1" 15732 [(set (mem:DI (match_operand:DI 2 "register_operand" "0")) 15733 (mem:DI (match_operand:DI 3 "register_operand" "1"))) 15734 (set (match_operand:DI 0 "register_operand" "=D") 15735 (plus:DI (match_dup 2) 15736 (const_int 8))) 15737 (set (match_operand:DI 1 "register_operand" "=S") 15738 (plus:DI (match_dup 3) 15739 (const_int 8)))] 15740 "TARGET_64BIT 15741 && !(fixed_regs[SI_REG] || fixed_regs[DI_REG])" 15742 "movsq" 15743 [(set_attr "type" "str") 15744 (set_attr "memory" "both") 15745 (set_attr "mode" "DI")]) 15746 15747(define_insn "*strmovsi_1" 15748 [(set (mem:SI (match_operand:P 2 "register_operand" "0")) 15749 (mem:SI (match_operand:P 3 "register_operand" "1"))) 15750 (set (match_operand:P 0 "register_operand" "=D") 15751 (plus:P (match_dup 2) 15752 (const_int 4))) 15753 (set (match_operand:P 1 "register_operand" "=S") 15754 (plus:P (match_dup 3) 15755 (const_int 4)))] 15756 "!(fixed_regs[SI_REG] || fixed_regs[DI_REG])" 15757 "movs{l|d}" 15758 [(set_attr "type" "str") 15759 (set_attr "memory" "both") 15760 (set_attr "mode" "SI")]) 15761 15762(define_insn "*strmovhi_1" 15763 [(set (mem:HI (match_operand:P 2 "register_operand" "0")) 15764 (mem:HI (match_operand:P 3 "register_operand" "1"))) 15765 (set (match_operand:P 0 "register_operand" "=D") 15766 (plus:P (match_dup 2) 15767 (const_int 2))) 15768 (set (match_operand:P 1 "register_operand" "=S") 15769 (plus:P (match_dup 3) 15770 (const_int 2)))] 15771 "!(fixed_regs[SI_REG] || fixed_regs[DI_REG])" 15772 "movsw" 15773 [(set_attr "type" "str") 15774 (set_attr "memory" "both") 15775 (set_attr "mode" "HI")]) 15776 15777(define_insn "*strmovqi_1" 15778 [(set (mem:QI (match_operand:P 2 "register_operand" "0")) 15779 (mem:QI (match_operand:P 3 "register_operand" "1"))) 15780 (set (match_operand:P 0 "register_operand" "=D") 15781 (plus:P (match_dup 2) 15782 (const_int 1))) 15783 (set (match_operand:P 1 "register_operand" "=S") 15784 (plus:P (match_dup 3) 15785 (const_int 1)))] 15786 "!(fixed_regs[SI_REG] || fixed_regs[DI_REG])" 15787 "movsb" 15788 [(set_attr "type" "str") 15789 (set_attr "memory" "both") 15790 (set (attr "prefix_rex") 15791 (if_then_else 15792 (match_test "<P:MODE>mode == DImode") 15793 (const_string "0") 15794 (const_string "*"))) 15795 (set_attr "mode" "QI")]) 15796 15797(define_expand "rep_mov" 15798 [(parallel [(set (match_operand 4 "register_operand" "") (const_int 0)) 15799 (set (match_operand 0 "register_operand" "") 15800 (match_operand 5 "" "")) 15801 (set (match_operand 2 "register_operand" "") 15802 (match_operand 6 "" "")) 15803 (set (match_operand 1 "memory_operand" "") 15804 (match_operand 3 "memory_operand" "")) 15805 (use (match_dup 4))])] 15806 "" 15807 "ix86_current_function_needs_cld = 1;") 15808 15809(define_insn "*rep_movdi_rex64" 15810 [(set (match_operand:DI 2 "register_operand" "=c") (const_int 0)) 15811 (set (match_operand:DI 0 "register_operand" "=D") 15812 (plus:DI (ashift:DI (match_operand:DI 5 "register_operand" "2") 15813 (const_int 3)) 15814 (match_operand:DI 3 "register_operand" "0"))) 15815 (set (match_operand:DI 1 "register_operand" "=S") 15816 (plus:DI (ashift:DI (match_dup 5) (const_int 3)) 15817 (match_operand:DI 4 "register_operand" "1"))) 15818 (set (mem:BLK (match_dup 3)) 15819 (mem:BLK (match_dup 4))) 15820 (use (match_dup 5))] 15821 "TARGET_64BIT 15822 && !(fixed_regs[CX_REG] || fixed_regs[SI_REG] || fixed_regs[DI_REG])" 15823 "rep{%;} movsq" 15824 [(set_attr "type" "str") 15825 (set_attr "prefix_rep" "1") 15826 (set_attr "memory" "both") 15827 (set_attr "mode" "DI")]) 15828 15829(define_insn "*rep_movsi" 15830 [(set (match_operand:P 2 "register_operand" "=c") (const_int 0)) 15831 (set (match_operand:P 0 "register_operand" "=D") 15832 (plus:P (ashift:P (match_operand:P 5 "register_operand" "2") 15833 (const_int 2)) 15834 (match_operand:P 3 "register_operand" "0"))) 15835 (set (match_operand:P 1 "register_operand" "=S") 15836 (plus:P (ashift:P (match_dup 5) (const_int 2)) 15837 (match_operand:P 4 "register_operand" "1"))) 15838 (set (mem:BLK (match_dup 3)) 15839 (mem:BLK (match_dup 4))) 15840 (use (match_dup 5))] 15841 "!(fixed_regs[CX_REG] || fixed_regs[SI_REG] || fixed_regs[DI_REG])" 15842 "rep{%;} movs{l|d}" 15843 [(set_attr "type" "str") 15844 (set_attr "prefix_rep" "1") 15845 (set_attr "memory" "both") 15846 (set_attr "mode" "SI")]) 15847 15848(define_insn "*rep_movqi" 15849 [(set (match_operand:P 2 "register_operand" "=c") (const_int 0)) 15850 (set (match_operand:P 0 "register_operand" "=D") 15851 (plus:P (match_operand:P 3 "register_operand" "0") 15852 (match_operand:P 5 "register_operand" "2"))) 15853 (set (match_operand:P 1 "register_operand" "=S") 15854 (plus:P (match_operand:P 4 "register_operand" "1") (match_dup 5))) 15855 (set (mem:BLK (match_dup 3)) 15856 (mem:BLK (match_dup 4))) 15857 (use (match_dup 5))] 15858 "!(fixed_regs[CX_REG] || fixed_regs[SI_REG] || fixed_regs[DI_REG])" 15859 "rep{%;} movsb" 15860 [(set_attr "type" "str") 15861 (set_attr "prefix_rep" "1") 15862 (set_attr "memory" "both") 15863 (set_attr "mode" "QI")]) 15864 15865(define_expand "setmem<mode>" 15866 [(use (match_operand:BLK 0 "memory_operand" "")) 15867 (use (match_operand:SWI48 1 "nonmemory_operand" "")) 15868 (use (match_operand:QI 2 "nonmemory_operand" "")) 15869 (use (match_operand 3 "const_int_operand" "")) 15870 (use (match_operand:SI 4 "const_int_operand" "")) 15871 (use (match_operand:SI 5 "const_int_operand" ""))] 15872 "" 15873{ 15874 if (ix86_expand_setmem (operands[0], operands[1], 15875 operands[2], operands[3], 15876 operands[4], operands[5])) 15877 DONE; 15878 else 15879 FAIL; 15880}) 15881 15882;; Most CPUs don't like single string operations 15883;; Handle this case here to simplify previous expander. 15884 15885(define_expand "strset" 15886 [(set (match_operand 1 "memory_operand" "") 15887 (match_operand 2 "register_operand" "")) 15888 (parallel [(set (match_operand 0 "register_operand" "") 15889 (match_dup 3)) 15890 (clobber (reg:CC FLAGS_REG))])] 15891 "" 15892{ 15893 if (GET_MODE (operands[1]) != GET_MODE (operands[2])) 15894 operands[1] = adjust_address_nv (operands[1], GET_MODE (operands[2]), 0); 15895 15896 /* If .md ever supports :P for Pmode, this can be directly 15897 in the pattern above. */ 15898 operands[3] = gen_rtx_PLUS (Pmode, operands[0], 15899 GEN_INT (GET_MODE_SIZE (GET_MODE 15900 (operands[2])))); 15901 /* Can't use this if the user has appropriated eax or edi. */ 15902 if ((TARGET_SINGLE_STRINGOP || optimize_insn_for_size_p ()) 15903 && !(fixed_regs[AX_REG] || fixed_regs[DI_REG])) 15904 { 15905 emit_insn (gen_strset_singleop (operands[0], operands[1], operands[2], 15906 operands[3])); 15907 DONE; 15908 } 15909}) 15910 15911(define_expand "strset_singleop" 15912 [(parallel [(set (match_operand 1 "memory_operand" "") 15913 (match_operand 2 "register_operand" "")) 15914 (set (match_operand 0 "register_operand" "") 15915 (match_operand 3 "" ""))])] 15916 "" 15917 "ix86_current_function_needs_cld = 1;") 15918 15919(define_insn "*strsetdi_rex_1" 15920 [(set (mem:DI (match_operand:DI 1 "register_operand" "0")) 15921 (match_operand:DI 2 "register_operand" "a")) 15922 (set (match_operand:DI 0 "register_operand" "=D") 15923 (plus:DI (match_dup 1) 15924 (const_int 8)))] 15925 "TARGET_64BIT 15926 && !(fixed_regs[AX_REG] || fixed_regs[DI_REG])" 15927 "stosq" 15928 [(set_attr "type" "str") 15929 (set_attr "memory" "store") 15930 (set_attr "mode" "DI")]) 15931 15932(define_insn "*strsetsi_1" 15933 [(set (mem:SI (match_operand:P 1 "register_operand" "0")) 15934 (match_operand:SI 2 "register_operand" "a")) 15935 (set (match_operand:P 0 "register_operand" "=D") 15936 (plus:P (match_dup 1) 15937 (const_int 4)))] 15938 "!(fixed_regs[AX_REG] || fixed_regs[DI_REG])" 15939 "stos{l|d}" 15940 [(set_attr "type" "str") 15941 (set_attr "memory" "store") 15942 (set_attr "mode" "SI")]) 15943 15944(define_insn "*strsethi_1" 15945 [(set (mem:HI (match_operand:P 1 "register_operand" "0")) 15946 (match_operand:HI 2 "register_operand" "a")) 15947 (set (match_operand:P 0 "register_operand" "=D") 15948 (plus:P (match_dup 1) 15949 (const_int 2)))] 15950 "!(fixed_regs[AX_REG] || fixed_regs[DI_REG])" 15951 "stosw" 15952 [(set_attr "type" "str") 15953 (set_attr "memory" "store") 15954 (set_attr "mode" "HI")]) 15955 15956(define_insn "*strsetqi_1" 15957 [(set (mem:QI (match_operand:P 1 "register_operand" "0")) 15958 (match_operand:QI 2 "register_operand" "a")) 15959 (set (match_operand:P 0 "register_operand" "=D") 15960 (plus:P (match_dup 1) 15961 (const_int 1)))] 15962 "!(fixed_regs[AX_REG] || fixed_regs[DI_REG])" 15963 "stosb" 15964 [(set_attr "type" "str") 15965 (set_attr "memory" "store") 15966 (set (attr "prefix_rex") 15967 (if_then_else 15968 (match_test "<P:MODE>mode == DImode") 15969 (const_string "0") 15970 (const_string "*"))) 15971 (set_attr "mode" "QI")]) 15972 15973(define_expand "rep_stos" 15974 [(parallel [(set (match_operand 1 "register_operand" "") (const_int 0)) 15975 (set (match_operand 0 "register_operand" "") 15976 (match_operand 4 "" "")) 15977 (set (match_operand 2 "memory_operand" "") (const_int 0)) 15978 (use (match_operand 3 "register_operand" "")) 15979 (use (match_dup 1))])] 15980 "" 15981 "ix86_current_function_needs_cld = 1;") 15982 15983(define_insn "*rep_stosdi_rex64" 15984 [(set (match_operand:DI 1 "register_operand" "=c") (const_int 0)) 15985 (set (match_operand:DI 0 "register_operand" "=D") 15986 (plus:DI (ashift:DI (match_operand:DI 4 "register_operand" "1") 15987 (const_int 3)) 15988 (match_operand:DI 3 "register_operand" "0"))) 15989 (set (mem:BLK (match_dup 3)) 15990 (const_int 0)) 15991 (use (match_operand:DI 2 "register_operand" "a")) 15992 (use (match_dup 4))] 15993 "TARGET_64BIT 15994 && !(fixed_regs[AX_REG] || fixed_regs[CX_REG] || fixed_regs[DI_REG])" 15995 "rep{%;} stosq" 15996 [(set_attr "type" "str") 15997 (set_attr "prefix_rep" "1") 15998 (set_attr "memory" "store") 15999 (set_attr "mode" "DI")]) 16000 16001(define_insn "*rep_stossi" 16002 [(set (match_operand:P 1 "register_operand" "=c") (const_int 0)) 16003 (set (match_operand:P 0 "register_operand" "=D") 16004 (plus:P (ashift:P (match_operand:P 4 "register_operand" "1") 16005 (const_int 2)) 16006 (match_operand:P 3 "register_operand" "0"))) 16007 (set (mem:BLK (match_dup 3)) 16008 (const_int 0)) 16009 (use (match_operand:SI 2 "register_operand" "a")) 16010 (use (match_dup 4))] 16011 "!(fixed_regs[AX_REG] || fixed_regs[CX_REG] || fixed_regs[DI_REG])" 16012 "rep{%;} stos{l|d}" 16013 [(set_attr "type" "str") 16014 (set_attr "prefix_rep" "1") 16015 (set_attr "memory" "store") 16016 (set_attr "mode" "SI")]) 16017 16018(define_insn "*rep_stosqi" 16019 [(set (match_operand:P 1 "register_operand" "=c") (const_int 0)) 16020 (set (match_operand:P 0 "register_operand" "=D") 16021 (plus:P (match_operand:P 3 "register_operand" "0") 16022 (match_operand:P 4 "register_operand" "1"))) 16023 (set (mem:BLK (match_dup 3)) 16024 (const_int 0)) 16025 (use (match_operand:QI 2 "register_operand" "a")) 16026 (use (match_dup 4))] 16027 "!(fixed_regs[AX_REG] || fixed_regs[CX_REG] || fixed_regs[DI_REG])" 16028 "rep{%;} stosb" 16029 [(set_attr "type" "str") 16030 (set_attr "prefix_rep" "1") 16031 (set_attr "memory" "store") 16032 (set (attr "prefix_rex") 16033 (if_then_else 16034 (match_test "<P:MODE>mode == DImode") 16035 (const_string "0") 16036 (const_string "*"))) 16037 (set_attr "mode" "QI")]) 16038 16039(define_expand "cmpstrnsi" 16040 [(set (match_operand:SI 0 "register_operand" "") 16041 (compare:SI (match_operand:BLK 1 "general_operand" "") 16042 (match_operand:BLK 2 "general_operand" ""))) 16043 (use (match_operand 3 "general_operand" "")) 16044 (use (match_operand 4 "immediate_operand" ""))] 16045 "" 16046{ 16047 rtx addr1, addr2, out, outlow, count, countreg, align; 16048 16049 if (optimize_insn_for_size_p () && !TARGET_INLINE_ALL_STRINGOPS) 16050 FAIL; 16051 16052 /* Can't use this if the user has appropriated ecx, esi or edi. */ 16053 if (fixed_regs[CX_REG] || fixed_regs[SI_REG] || fixed_regs[DI_REG]) 16054 FAIL; 16055 16056 out = operands[0]; 16057 if (!REG_P (out)) 16058 out = gen_reg_rtx (SImode); 16059 16060 addr1 = copy_to_mode_reg (Pmode, XEXP (operands[1], 0)); 16061 addr2 = copy_to_mode_reg (Pmode, XEXP (operands[2], 0)); 16062 if (addr1 != XEXP (operands[1], 0)) 16063 operands[1] = replace_equiv_address_nv (operands[1], addr1); 16064 if (addr2 != XEXP (operands[2], 0)) 16065 operands[2] = replace_equiv_address_nv (operands[2], addr2); 16066 16067 count = operands[3]; 16068 countreg = ix86_zero_extend_to_Pmode (count); 16069 16070 /* %%% Iff we are testing strict equality, we can use known alignment 16071 to good advantage. This may be possible with combine, particularly 16072 once cc0 is dead. */ 16073 align = operands[4]; 16074 16075 if (CONST_INT_P (count)) 16076 { 16077 if (INTVAL (count) == 0) 16078 { 16079 emit_move_insn (operands[0], const0_rtx); 16080 DONE; 16081 } 16082 emit_insn (gen_cmpstrnqi_nz_1 (addr1, addr2, countreg, align, 16083 operands[1], operands[2])); 16084 } 16085 else 16086 { 16087 rtx (*gen_cmp) (rtx, rtx); 16088 16089 gen_cmp = (TARGET_64BIT 16090 ? gen_cmpdi_1 : gen_cmpsi_1); 16091 16092 emit_insn (gen_cmp (countreg, countreg)); 16093 emit_insn (gen_cmpstrnqi_1 (addr1, addr2, countreg, align, 16094 operands[1], operands[2])); 16095 } 16096 16097 outlow = gen_lowpart (QImode, out); 16098 emit_insn (gen_cmpintqi (outlow)); 16099 emit_move_insn (out, gen_rtx_SIGN_EXTEND (SImode, outlow)); 16100 16101 if (operands[0] != out) 16102 emit_move_insn (operands[0], out); 16103 16104 DONE; 16105}) 16106 16107;; Produce a tri-state integer (-1, 0, 1) from condition codes. 16108 16109(define_expand "cmpintqi" 16110 [(set (match_dup 1) 16111 (gtu:QI (reg:CC FLAGS_REG) (const_int 0))) 16112 (set (match_dup 2) 16113 (ltu:QI (reg:CC FLAGS_REG) (const_int 0))) 16114 (parallel [(set (match_operand:QI 0 "register_operand" "") 16115 (minus:QI (match_dup 1) 16116 (match_dup 2))) 16117 (clobber (reg:CC FLAGS_REG))])] 16118 "" 16119{ 16120 operands[1] = gen_reg_rtx (QImode); 16121 operands[2] = gen_reg_rtx (QImode); 16122}) 16123 16124;; memcmp recognizers. The `cmpsb' opcode does nothing if the count is 16125;; zero. Emit extra code to make sure that a zero-length compare is EQ. 16126 16127(define_expand "cmpstrnqi_nz_1" 16128 [(parallel [(set (reg:CC FLAGS_REG) 16129 (compare:CC (match_operand 4 "memory_operand" "") 16130 (match_operand 5 "memory_operand" ""))) 16131 (use (match_operand 2 "register_operand" "")) 16132 (use (match_operand:SI 3 "immediate_operand" "")) 16133 (clobber (match_operand 0 "register_operand" "")) 16134 (clobber (match_operand 1 "register_operand" "")) 16135 (clobber (match_dup 2))])] 16136 "" 16137 "ix86_current_function_needs_cld = 1;") 16138 16139(define_insn "*cmpstrnqi_nz_1" 16140 [(set (reg:CC FLAGS_REG) 16141 (compare:CC (mem:BLK (match_operand:P 4 "register_operand" "0")) 16142 (mem:BLK (match_operand:P 5 "register_operand" "1")))) 16143 (use (match_operand:P 6 "register_operand" "2")) 16144 (use (match_operand:SI 3 "immediate_operand" "i")) 16145 (clobber (match_operand:P 0 "register_operand" "=S")) 16146 (clobber (match_operand:P 1 "register_operand" "=D")) 16147 (clobber (match_operand:P 2 "register_operand" "=c"))] 16148 "!(fixed_regs[CX_REG] || fixed_regs[SI_REG] || fixed_regs[DI_REG])" 16149 "repz{%;} cmpsb" 16150 [(set_attr "type" "str") 16151 (set_attr "mode" "QI") 16152 (set (attr "prefix_rex") 16153 (if_then_else 16154 (match_test "<P:MODE>mode == DImode") 16155 (const_string "0") 16156 (const_string "*"))) 16157 (set_attr "prefix_rep" "1")]) 16158 16159;; The same, but the count is not known to not be zero. 16160 16161(define_expand "cmpstrnqi_1" 16162 [(parallel [(set (reg:CC FLAGS_REG) 16163 (if_then_else:CC (ne (match_operand 2 "register_operand" "") 16164 (const_int 0)) 16165 (compare:CC (match_operand 4 "memory_operand" "") 16166 (match_operand 5 "memory_operand" "")) 16167 (const_int 0))) 16168 (use (match_operand:SI 3 "immediate_operand" "")) 16169 (use (reg:CC FLAGS_REG)) 16170 (clobber (match_operand 0 "register_operand" "")) 16171 (clobber (match_operand 1 "register_operand" "")) 16172 (clobber (match_dup 2))])] 16173 "" 16174 "ix86_current_function_needs_cld = 1;") 16175 16176(define_insn "*cmpstrnqi_1" 16177 [(set (reg:CC FLAGS_REG) 16178 (if_then_else:CC (ne (match_operand:P 6 "register_operand" "2") 16179 (const_int 0)) 16180 (compare:CC (mem:BLK (match_operand:P 4 "register_operand" "0")) 16181 (mem:BLK (match_operand:P 5 "register_operand" "1"))) 16182 (const_int 0))) 16183 (use (match_operand:SI 3 "immediate_operand" "i")) 16184 (use (reg:CC FLAGS_REG)) 16185 (clobber (match_operand:P 0 "register_operand" "=S")) 16186 (clobber (match_operand:P 1 "register_operand" "=D")) 16187 (clobber (match_operand:P 2 "register_operand" "=c"))] 16188 "!(fixed_regs[CX_REG] || fixed_regs[SI_REG] || fixed_regs[DI_REG])" 16189 "repz{%;} cmpsb" 16190 [(set_attr "type" "str") 16191 (set_attr "mode" "QI") 16192 (set (attr "prefix_rex") 16193 (if_then_else 16194 (match_test "<P:MODE>mode == DImode") 16195 (const_string "0") 16196 (const_string "*"))) 16197 (set_attr "prefix_rep" "1")]) 16198 16199(define_expand "strlen<mode>" 16200 [(set (match_operand:P 0 "register_operand" "") 16201 (unspec:P [(match_operand:BLK 1 "general_operand" "") 16202 (match_operand:QI 2 "immediate_operand" "") 16203 (match_operand 3 "immediate_operand" "")] 16204 UNSPEC_SCAS))] 16205 "" 16206{ 16207 if (ix86_expand_strlen (operands[0], operands[1], operands[2], operands[3])) 16208 DONE; 16209 else 16210 FAIL; 16211}) 16212 16213(define_expand "strlenqi_1" 16214 [(parallel [(set (match_operand 0 "register_operand" "") 16215 (match_operand 2 "" "")) 16216 (clobber (match_operand 1 "register_operand" "")) 16217 (clobber (reg:CC FLAGS_REG))])] 16218 "" 16219 "ix86_current_function_needs_cld = 1;") 16220 16221(define_insn "*strlenqi_1" 16222 [(set (match_operand:P 0 "register_operand" "=&c") 16223 (unspec:P [(mem:BLK (match_operand:P 5 "register_operand" "1")) 16224 (match_operand:QI 2 "register_operand" "a") 16225 (match_operand:P 3 "immediate_operand" "i") 16226 (match_operand:P 4 "register_operand" "0")] UNSPEC_SCAS)) 16227 (clobber (match_operand:P 1 "register_operand" "=D")) 16228 (clobber (reg:CC FLAGS_REG))] 16229 "!(fixed_regs[AX_REG] || fixed_regs[CX_REG] || fixed_regs[DI_REG])" 16230 "repnz{%;} scasb" 16231 [(set_attr "type" "str") 16232 (set_attr "mode" "QI") 16233 (set (attr "prefix_rex") 16234 (if_then_else 16235 (match_test "<P:MODE>mode == DImode") 16236 (const_string "0") 16237 (const_string "*"))) 16238 (set_attr "prefix_rep" "1")]) 16239 16240;; Peephole optimizations to clean up after cmpstrn*. This should be 16241;; handled in combine, but it is not currently up to the task. 16242;; When used for their truth value, the cmpstrn* expanders generate 16243;; code like this: 16244;; 16245;; repz cmpsb 16246;; seta %al 16247;; setb %dl 16248;; cmpb %al, %dl 16249;; jcc label 16250;; 16251;; The intermediate three instructions are unnecessary. 16252 16253;; This one handles cmpstrn*_nz_1... 16254(define_peephole2 16255 [(parallel[ 16256 (set (reg:CC FLAGS_REG) 16257 (compare:CC (mem:BLK (match_operand 4 "register_operand" "")) 16258 (mem:BLK (match_operand 5 "register_operand" "")))) 16259 (use (match_operand 6 "register_operand" "")) 16260 (use (match_operand:SI 3 "immediate_operand" "")) 16261 (clobber (match_operand 0 "register_operand" "")) 16262 (clobber (match_operand 1 "register_operand" "")) 16263 (clobber (match_operand 2 "register_operand" ""))]) 16264 (set (match_operand:QI 7 "register_operand" "") 16265 (gtu:QI (reg:CC FLAGS_REG) (const_int 0))) 16266 (set (match_operand:QI 8 "register_operand" "") 16267 (ltu:QI (reg:CC FLAGS_REG) (const_int 0))) 16268 (set (reg FLAGS_REG) 16269 (compare (match_dup 7) (match_dup 8))) 16270 ] 16271 "peep2_reg_dead_p (4, operands[7]) && peep2_reg_dead_p (4, operands[8])" 16272 [(parallel[ 16273 (set (reg:CC FLAGS_REG) 16274 (compare:CC (mem:BLK (match_dup 4)) 16275 (mem:BLK (match_dup 5)))) 16276 (use (match_dup 6)) 16277 (use (match_dup 3)) 16278 (clobber (match_dup 0)) 16279 (clobber (match_dup 1)) 16280 (clobber (match_dup 2))])]) 16281 16282;; ...and this one handles cmpstrn*_1. 16283(define_peephole2 16284 [(parallel[ 16285 (set (reg:CC FLAGS_REG) 16286 (if_then_else:CC (ne (match_operand 6 "register_operand" "") 16287 (const_int 0)) 16288 (compare:CC (mem:BLK (match_operand 4 "register_operand" "")) 16289 (mem:BLK (match_operand 5 "register_operand" ""))) 16290 (const_int 0))) 16291 (use (match_operand:SI 3 "immediate_operand" "")) 16292 (use (reg:CC FLAGS_REG)) 16293 (clobber (match_operand 0 "register_operand" "")) 16294 (clobber (match_operand 1 "register_operand" "")) 16295 (clobber (match_operand 2 "register_operand" ""))]) 16296 (set (match_operand:QI 7 "register_operand" "") 16297 (gtu:QI (reg:CC FLAGS_REG) (const_int 0))) 16298 (set (match_operand:QI 8 "register_operand" "") 16299 (ltu:QI (reg:CC FLAGS_REG) (const_int 0))) 16300 (set (reg FLAGS_REG) 16301 (compare (match_dup 7) (match_dup 8))) 16302 ] 16303 "peep2_reg_dead_p (4, operands[7]) && peep2_reg_dead_p (4, operands[8])" 16304 [(parallel[ 16305 (set (reg:CC FLAGS_REG) 16306 (if_then_else:CC (ne (match_dup 6) 16307 (const_int 0)) 16308 (compare:CC (mem:BLK (match_dup 4)) 16309 (mem:BLK (match_dup 5))) 16310 (const_int 0))) 16311 (use (match_dup 3)) 16312 (use (reg:CC FLAGS_REG)) 16313 (clobber (match_dup 0)) 16314 (clobber (match_dup 1)) 16315 (clobber (match_dup 2))])]) 16316 16317;; Conditional move instructions. 16318 16319(define_expand "mov<mode>cc" 16320 [(set (match_operand:SWIM 0 "register_operand" "") 16321 (if_then_else:SWIM (match_operand 1 "ordered_comparison_operator" "") 16322 (match_operand:SWIM 2 "<general_operand>" "") 16323 (match_operand:SWIM 3 "<general_operand>" "")))] 16324 "" 16325 "if (ix86_expand_int_movcc (operands)) DONE; else FAIL;") 16326 16327;; Data flow gets confused by our desire for `sbbl reg,reg', and clearing 16328;; the register first winds up with `sbbl $0,reg', which is also weird. 16329;; So just document what we're doing explicitly. 16330 16331(define_expand "x86_mov<mode>cc_0_m1" 16332 [(parallel 16333 [(set (match_operand:SWI48 0 "register_operand" "") 16334 (if_then_else:SWI48 16335 (match_operator:SWI48 2 "ix86_carry_flag_operator" 16336 [(match_operand 1 "flags_reg_operand" "") 16337 (const_int 0)]) 16338 (const_int -1) 16339 (const_int 0))) 16340 (clobber (reg:CC FLAGS_REG))])]) 16341 16342(define_insn "*x86_mov<mode>cc_0_m1" 16343 [(set (match_operand:SWI48 0 "register_operand" "=r") 16344 (if_then_else:SWI48 (match_operator 1 "ix86_carry_flag_operator" 16345 [(reg FLAGS_REG) (const_int 0)]) 16346 (const_int -1) 16347 (const_int 0))) 16348 (clobber (reg:CC FLAGS_REG))] 16349 "" 16350 "sbb{<imodesuffix>}\t%0, %0" 16351 ; Since we don't have the proper number of operands for an alu insn, 16352 ; fill in all the blanks. 16353 [(set_attr "type" "alu") 16354 (set_attr "use_carry" "1") 16355 (set_attr "pent_pair" "pu") 16356 (set_attr "memory" "none") 16357 (set_attr "imm_disp" "false") 16358 (set_attr "mode" "<MODE>") 16359 (set_attr "length_immediate" "0")]) 16360 16361(define_insn "*x86_mov<mode>cc_0_m1_se" 16362 [(set (match_operand:SWI48 0 "register_operand" "=r") 16363 (sign_extract:SWI48 (match_operator 1 "ix86_carry_flag_operator" 16364 [(reg FLAGS_REG) (const_int 0)]) 16365 (const_int 1) 16366 (const_int 0))) 16367 (clobber (reg:CC FLAGS_REG))] 16368 "" 16369 "sbb{<imodesuffix>}\t%0, %0" 16370 [(set_attr "type" "alu") 16371 (set_attr "use_carry" "1") 16372 (set_attr "pent_pair" "pu") 16373 (set_attr "memory" "none") 16374 (set_attr "imm_disp" "false") 16375 (set_attr "mode" "<MODE>") 16376 (set_attr "length_immediate" "0")]) 16377 16378(define_insn "*x86_mov<mode>cc_0_m1_neg" 16379 [(set (match_operand:SWI48 0 "register_operand" "=r") 16380 (neg:SWI48 (match_operator 1 "ix86_carry_flag_operator" 16381 [(reg FLAGS_REG) (const_int 0)]))) 16382 (clobber (reg:CC FLAGS_REG))] 16383 "" 16384 "sbb{<imodesuffix>}\t%0, %0" 16385 [(set_attr "type" "alu") 16386 (set_attr "use_carry" "1") 16387 (set_attr "pent_pair" "pu") 16388 (set_attr "memory" "none") 16389 (set_attr "imm_disp" "false") 16390 (set_attr "mode" "<MODE>") 16391 (set_attr "length_immediate" "0")]) 16392 16393(define_insn "*mov<mode>cc_noc" 16394 [(set (match_operand:SWI248 0 "register_operand" "=r,r") 16395 (if_then_else:SWI248 (match_operator 1 "ix86_comparison_operator" 16396 [(reg FLAGS_REG) (const_int 0)]) 16397 (match_operand:SWI248 2 "nonimmediate_operand" "rm,0") 16398 (match_operand:SWI248 3 "nonimmediate_operand" "0,rm")))] 16399 "TARGET_CMOVE && !(MEM_P (operands[2]) && MEM_P (operands[3]))" 16400 "@ 16401 cmov%O2%C1\t{%2, %0|%0, %2} 16402 cmov%O2%c1\t{%3, %0|%0, %3}" 16403 [(set_attr "type" "icmov") 16404 (set_attr "mode" "<MODE>")]) 16405 16406(define_insn "*movqicc_noc" 16407 [(set (match_operand:QI 0 "register_operand" "=r,r") 16408 (if_then_else:QI (match_operator 1 "ix86_comparison_operator" 16409 [(reg FLAGS_REG) (const_int 0)]) 16410 (match_operand:QI 2 "register_operand" "r,0") 16411 (match_operand:QI 3 "register_operand" "0,r")))] 16412 "TARGET_CMOVE && !TARGET_PARTIAL_REG_STALL" 16413 "#" 16414 [(set_attr "type" "icmov") 16415 (set_attr "mode" "QI")]) 16416 16417(define_split 16418 [(set (match_operand 0 "register_operand") 16419 (if_then_else (match_operator 1 "ix86_comparison_operator" 16420 [(reg FLAGS_REG) (const_int 0)]) 16421 (match_operand 2 "register_operand") 16422 (match_operand 3 "register_operand")))] 16423 "TARGET_CMOVE && !TARGET_PARTIAL_REG_STALL 16424 && (GET_MODE (operands[0]) == QImode 16425 || GET_MODE (operands[0]) == HImode) 16426 && reload_completed" 16427 [(set (match_dup 0) 16428 (if_then_else:SI (match_dup 1) (match_dup 2) (match_dup 3)))] 16429{ 16430 operands[0] = gen_lowpart (SImode, operands[0]); 16431 operands[2] = gen_lowpart (SImode, operands[2]); 16432 operands[3] = gen_lowpart (SImode, operands[3]); 16433}) 16434 16435(define_expand "mov<mode>cc" 16436 [(set (match_operand:X87MODEF 0 "register_operand" "") 16437 (if_then_else:X87MODEF 16438 (match_operand 1 "ix86_fp_comparison_operator" "") 16439 (match_operand:X87MODEF 2 "register_operand" "") 16440 (match_operand:X87MODEF 3 "register_operand" "")))] 16441 "(TARGET_80387 && TARGET_CMOVE) 16442 || (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)" 16443 "if (ix86_expand_fp_movcc (operands)) DONE; else FAIL;") 16444 16445(define_insn "*movxfcc_1" 16446 [(set (match_operand:XF 0 "register_operand" "=f,f") 16447 (if_then_else:XF (match_operator 1 "fcmov_comparison_operator" 16448 [(reg FLAGS_REG) (const_int 0)]) 16449 (match_operand:XF 2 "register_operand" "f,0") 16450 (match_operand:XF 3 "register_operand" "0,f")))] 16451 "TARGET_80387 && TARGET_CMOVE" 16452 "@ 16453 fcmov%F1\t{%2, %0|%0, %2} 16454 fcmov%f1\t{%3, %0|%0, %3}" 16455 [(set_attr "type" "fcmov") 16456 (set_attr "mode" "XF")]) 16457 16458(define_insn "*movdfcc_1_rex64" 16459 [(set (match_operand:DF 0 "register_operand" "=f,f,r,r") 16460 (if_then_else:DF (match_operator 1 "fcmov_comparison_operator" 16461 [(reg FLAGS_REG) (const_int 0)]) 16462 (match_operand:DF 2 "nonimmediate_operand" "f,0,rm,0") 16463 (match_operand:DF 3 "nonimmediate_operand" "0,f,0,rm")))] 16464 "TARGET_64BIT && TARGET_80387 && TARGET_CMOVE 16465 && !(MEM_P (operands[2]) && MEM_P (operands[3]))" 16466 "@ 16467 fcmov%F1\t{%2, %0|%0, %2} 16468 fcmov%f1\t{%3, %0|%0, %3} 16469 cmov%O2%C1\t{%2, %0|%0, %2} 16470 cmov%O2%c1\t{%3, %0|%0, %3}" 16471 [(set_attr "type" "fcmov,fcmov,icmov,icmov") 16472 (set_attr "mode" "DF,DF,DI,DI")]) 16473 16474(define_insn "*movdfcc_1" 16475 [(set (match_operand:DF 0 "register_operand" "=f,f,&r,&r") 16476 (if_then_else:DF (match_operator 1 "fcmov_comparison_operator" 16477 [(reg FLAGS_REG) (const_int 0)]) 16478 (match_operand:DF 2 "nonimmediate_operand" "f,0,rm,0") 16479 (match_operand:DF 3 "nonimmediate_operand" "0,f,0,rm")))] 16480 "!TARGET_64BIT && TARGET_80387 && TARGET_CMOVE 16481 && !(MEM_P (operands[2]) && MEM_P (operands[3]))" 16482 "@ 16483 fcmov%F1\t{%2, %0|%0, %2} 16484 fcmov%f1\t{%3, %0|%0, %3} 16485 # 16486 #" 16487 [(set_attr "type" "fcmov,fcmov,multi,multi") 16488 (set_attr "mode" "DF,DF,DI,DI")]) 16489 16490(define_split 16491 [(set (match_operand:DF 0 "register_and_not_any_fp_reg_operand") 16492 (if_then_else:DF (match_operator 1 "fcmov_comparison_operator" 16493 [(reg FLAGS_REG) (const_int 0)]) 16494 (match_operand:DF 2 "nonimmediate_operand") 16495 (match_operand:DF 3 "nonimmediate_operand")))] 16496 "!TARGET_64BIT && reload_completed" 16497 [(set (match_dup 2) 16498 (if_then_else:SI (match_dup 1) (match_dup 4) (match_dup 5))) 16499 (set (match_dup 3) 16500 (if_then_else:SI (match_dup 1) (match_dup 6) (match_dup 7)))] 16501{ 16502 split_double_mode (DImode, &operands[2], 2, &operands[4], &operands[6]); 16503 split_double_mode (DImode, &operands[0], 1, &operands[2], &operands[3]); 16504}) 16505 16506(define_insn "*movsfcc_1_387" 16507 [(set (match_operand:SF 0 "register_operand" "=f,f,r,r") 16508 (if_then_else:SF (match_operator 1 "fcmov_comparison_operator" 16509 [(reg FLAGS_REG) (const_int 0)]) 16510 (match_operand:SF 2 "nonimmediate_operand" "f,0,rm,0") 16511 (match_operand:SF 3 "nonimmediate_operand" "0,f,0,rm")))] 16512 "TARGET_80387 && TARGET_CMOVE 16513 && !(MEM_P (operands[2]) && MEM_P (operands[3]))" 16514 "@ 16515 fcmov%F1\t{%2, %0|%0, %2} 16516 fcmov%f1\t{%3, %0|%0, %3} 16517 cmov%O2%C1\t{%2, %0|%0, %2} 16518 cmov%O2%c1\t{%3, %0|%0, %3}" 16519 [(set_attr "type" "fcmov,fcmov,icmov,icmov") 16520 (set_attr "mode" "SF,SF,SI,SI")]) 16521 16522;; All moves in XOP pcmov instructions are 128 bits and hence we restrict 16523;; the scalar versions to have only XMM registers as operands. 16524 16525;; XOP conditional move 16526(define_insn "*xop_pcmov_<mode>" 16527 [(set (match_operand:MODEF 0 "register_operand" "=x") 16528 (if_then_else:MODEF 16529 (match_operand:MODEF 1 "register_operand" "x") 16530 (match_operand:MODEF 2 "register_operand" "x") 16531 (match_operand:MODEF 3 "register_operand" "x")))] 16532 "TARGET_XOP" 16533 "vpcmov\t{%1, %3, %2, %0|%0, %2, %3, %1}" 16534 [(set_attr "type" "sse4arg")]) 16535 16536;; These versions of the min/max patterns are intentionally ignorant of 16537;; their behavior wrt -0.0 and NaN (via the commutative operand mark). 16538;; Since both the tree-level MAX_EXPR and the rtl-level SMAX operator 16539;; are undefined in this condition, we're certain this is correct. 16540 16541(define_insn "<code><mode>3" 16542 [(set (match_operand:MODEF 0 "register_operand" "=x,x") 16543 (smaxmin:MODEF 16544 (match_operand:MODEF 1 "nonimmediate_operand" "%0,x") 16545 (match_operand:MODEF 2 "nonimmediate_operand" "xm,xm")))] 16546 "SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH" 16547 "@ 16548 <maxmin_float><ssemodesuffix>\t{%2, %0|%0, %2} 16549 v<maxmin_float><ssemodesuffix>\t{%2, %1, %0|%0, %1, %2}" 16550 [(set_attr "isa" "noavx,avx") 16551 (set_attr "prefix" "orig,vex") 16552 (set_attr "type" "sseadd") 16553 (set_attr "mode" "<MODE>")]) 16554 16555;; These versions of the min/max patterns implement exactly the operations 16556;; min = (op1 < op2 ? op1 : op2) 16557;; max = (!(op1 < op2) ? op1 : op2) 16558;; Their operands are not commutative, and thus they may be used in the 16559;; presence of -0.0 and NaN. 16560 16561(define_insn "*ieee_smin<mode>3" 16562 [(set (match_operand:MODEF 0 "register_operand" "=x,x") 16563 (unspec:MODEF 16564 [(match_operand:MODEF 1 "register_operand" "0,x") 16565 (match_operand:MODEF 2 "nonimmediate_operand" "xm,xm")] 16566 UNSPEC_IEEE_MIN))] 16567 "SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH" 16568 "@ 16569 min<ssemodesuffix>\t{%2, %0|%0, %2} 16570 vmin<ssemodesuffix>\t{%2, %1, %0|%0, %1, %2}" 16571 [(set_attr "isa" "noavx,avx") 16572 (set_attr "prefix" "orig,vex") 16573 (set_attr "type" "sseadd") 16574 (set_attr "mode" "<MODE>")]) 16575 16576(define_insn "*ieee_smax<mode>3" 16577 [(set (match_operand:MODEF 0 "register_operand" "=x,x") 16578 (unspec:MODEF 16579 [(match_operand:MODEF 1 "register_operand" "0,x") 16580 (match_operand:MODEF 2 "nonimmediate_operand" "xm,xm")] 16581 UNSPEC_IEEE_MAX))] 16582 "SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH" 16583 "@ 16584 max<ssemodesuffix>\t{%2, %0|%0, %2} 16585 vmax<ssemodesuffix>\t{%2, %1, %0|%0, %1, %2}" 16586 [(set_attr "isa" "noavx,avx") 16587 (set_attr "prefix" "orig,vex") 16588 (set_attr "type" "sseadd") 16589 (set_attr "mode" "<MODE>")]) 16590 16591;; Make two stack loads independent: 16592;; fld aa fld aa 16593;; fld %st(0) -> fld bb 16594;; fmul bb fmul %st(1), %st 16595;; 16596;; Actually we only match the last two instructions for simplicity. 16597(define_peephole2 16598 [(set (match_operand 0 "fp_register_operand" "") 16599 (match_operand 1 "fp_register_operand" "")) 16600 (set (match_dup 0) 16601 (match_operator 2 "binary_fp_operator" 16602 [(match_dup 0) 16603 (match_operand 3 "memory_operand" "")]))] 16604 "REGNO (operands[0]) != REGNO (operands[1])" 16605 [(set (match_dup 0) (match_dup 3)) 16606 (set (match_dup 0) (match_dup 4))] 16607 16608 ;; The % modifier is not operational anymore in peephole2's, so we have to 16609 ;; swap the operands manually in the case of addition and multiplication. 16610{ 16611 rtx op0, op1; 16612 16613 if (COMMUTATIVE_ARITH_P (operands[2])) 16614 op0 = operands[0], op1 = operands[1]; 16615 else 16616 op0 = operands[1], op1 = operands[0]; 16617 16618 operands[4] = gen_rtx_fmt_ee (GET_CODE (operands[2]), 16619 GET_MODE (operands[2]), 16620 op0, op1); 16621}) 16622 16623;; Conditional addition patterns 16624(define_expand "add<mode>cc" 16625 [(match_operand:SWI 0 "register_operand" "") 16626 (match_operand 1 "ordered_comparison_operator" "") 16627 (match_operand:SWI 2 "register_operand" "") 16628 (match_operand:SWI 3 "const_int_operand" "")] 16629 "" 16630 "if (ix86_expand_int_addcc (operands)) DONE; else FAIL;") 16631 16632;; Misc patterns (?) 16633 16634;; This pattern exists to put a dependency on all ebp-based memory accesses. 16635;; Otherwise there will be nothing to keep 16636;; 16637;; [(set (reg ebp) (reg esp))] 16638;; [(set (reg esp) (plus (reg esp) (const_int -160000))) 16639;; (clobber (eflags)] 16640;; [(set (mem (plus (reg ebp) (const_int -160000))) (const_int 0))] 16641;; 16642;; in proper program order. 16643 16644(define_insn "pro_epilogue_adjust_stack_<mode>_add" 16645 [(set (match_operand:P 0 "register_operand" "=r,r") 16646 (plus:P (match_operand:P 1 "register_operand" "0,r") 16647 (match_operand:P 2 "<nonmemory_operand>" "r<i>,l<i>"))) 16648 (clobber (reg:CC FLAGS_REG)) 16649 (clobber (mem:BLK (scratch)))] 16650 "" 16651{ 16652 switch (get_attr_type (insn)) 16653 { 16654 case TYPE_IMOV: 16655 return "mov{<imodesuffix>}\t{%1, %0|%0, %1}"; 16656 16657 case TYPE_ALU: 16658 gcc_assert (rtx_equal_p (operands[0], operands[1])); 16659 if (x86_maybe_negate_const_int (&operands[2], <MODE>mode)) 16660 return "sub{<imodesuffix>}\t{%2, %0|%0, %2}"; 16661 16662 return "add{<imodesuffix>}\t{%2, %0|%0, %2}"; 16663 16664 default: 16665 operands[2] = SET_SRC (XVECEXP (PATTERN (insn), 0, 0)); 16666 return "lea{<imodesuffix>}\t{%E2, %0|%0, %E2}"; 16667 } 16668} 16669 [(set (attr "type") 16670 (cond [(and (eq_attr "alternative" "0") 16671 (not (match_test "TARGET_OPT_AGU"))) 16672 (const_string "alu") 16673 (match_operand:<MODE> 2 "const0_operand" "") 16674 (const_string "imov") 16675 ] 16676 (const_string "lea"))) 16677 (set (attr "length_immediate") 16678 (cond [(eq_attr "type" "imov") 16679 (const_string "0") 16680 (and (eq_attr "type" "alu") 16681 (match_operand 2 "const128_operand" "")) 16682 (const_string "1") 16683 ] 16684 (const_string "*"))) 16685 (set_attr "mode" "<MODE>")]) 16686 16687(define_insn "pro_epilogue_adjust_stack_<mode>_sub" 16688 [(set (match_operand:P 0 "register_operand" "=r") 16689 (minus:P (match_operand:P 1 "register_operand" "0") 16690 (match_operand:P 2 "register_operand" "r"))) 16691 (clobber (reg:CC FLAGS_REG)) 16692 (clobber (mem:BLK (scratch)))] 16693 "" 16694 "sub{<imodesuffix>}\t{%2, %0|%0, %2}" 16695 [(set_attr "type" "alu") 16696 (set_attr "mode" "<MODE>")]) 16697 16698(define_insn "allocate_stack_worker_probe_<mode>" 16699 [(set (match_operand:P 0 "register_operand" "=a") 16700 (unspec_volatile:P [(match_operand:P 1 "register_operand" "0")] 16701 UNSPECV_STACK_PROBE)) 16702 (clobber (reg:CC FLAGS_REG))] 16703 "ix86_target_stack_probe ()" 16704 "call\t___chkstk_ms" 16705 [(set_attr "type" "multi") 16706 (set_attr "length" "5")]) 16707 16708(define_expand "allocate_stack" 16709 [(match_operand 0 "register_operand" "") 16710 (match_operand 1 "general_operand" "")] 16711 "ix86_target_stack_probe ()" 16712{ 16713 rtx x; 16714 16715#ifndef CHECK_STACK_LIMIT 16716#define CHECK_STACK_LIMIT 0 16717#endif 16718 16719 if (CHECK_STACK_LIMIT && CONST_INT_P (operands[1]) 16720 && INTVAL (operands[1]) < CHECK_STACK_LIMIT) 16721 { 16722 x = expand_simple_binop (Pmode, MINUS, stack_pointer_rtx, operands[1], 16723 stack_pointer_rtx, 0, OPTAB_DIRECT); 16724 if (x != stack_pointer_rtx) 16725 emit_move_insn (stack_pointer_rtx, x); 16726 } 16727 else 16728 { 16729 x = copy_to_mode_reg (Pmode, operands[1]); 16730 if (TARGET_64BIT) 16731 emit_insn (gen_allocate_stack_worker_probe_di (x, x)); 16732 else 16733 emit_insn (gen_allocate_stack_worker_probe_si (x, x)); 16734 x = expand_simple_binop (Pmode, MINUS, stack_pointer_rtx, x, 16735 stack_pointer_rtx, 0, OPTAB_DIRECT); 16736 if (x != stack_pointer_rtx) 16737 emit_move_insn (stack_pointer_rtx, x); 16738 } 16739 16740 emit_move_insn (operands[0], virtual_stack_dynamic_rtx); 16741 DONE; 16742}) 16743 16744;; Use IOR for stack probes, this is shorter. 16745(define_expand "probe_stack" 16746 [(match_operand 0 "memory_operand" "")] 16747 "" 16748{ 16749 rtx (*gen_ior3) (rtx, rtx, rtx); 16750 16751 gen_ior3 = (GET_MODE (operands[0]) == DImode 16752 ? gen_iordi3 : gen_iorsi3); 16753 16754 emit_insn (gen_ior3 (operands[0], operands[0], const0_rtx)); 16755 DONE; 16756}) 16757 16758(define_insn "adjust_stack_and_probe<mode>" 16759 [(set (match_operand:P 0 "register_operand" "=r") 16760 (unspec_volatile:P [(match_operand:P 1 "register_operand" "0")] 16761 UNSPECV_PROBE_STACK_RANGE)) 16762 (set (reg:P SP_REG) 16763 (minus:P (reg:P SP_REG) (match_operand:P 2 "const_int_operand" "n"))) 16764 (clobber (reg:CC FLAGS_REG)) 16765 (clobber (mem:BLK (scratch)))] 16766 "" 16767 "* return output_adjust_stack_and_probe (operands[0]);" 16768 [(set_attr "type" "multi")]) 16769 16770(define_insn "probe_stack_range<mode>" 16771 [(set (match_operand:P 0 "register_operand" "=r") 16772 (unspec_volatile:P [(match_operand:P 1 "register_operand" "0") 16773 (match_operand:P 2 "const_int_operand" "n")] 16774 UNSPECV_PROBE_STACK_RANGE)) 16775 (clobber (reg:CC FLAGS_REG))] 16776 "" 16777 "* return output_probe_stack_range (operands[0], operands[2]);" 16778 [(set_attr "type" "multi")]) 16779 16780(define_expand "builtin_setjmp_receiver" 16781 [(label_ref (match_operand 0 "" ""))] 16782 "!TARGET_64BIT && flag_pic" 16783{ 16784#if TARGET_MACHO 16785 if (TARGET_MACHO) 16786 { 16787 rtx xops[3]; 16788 rtx picreg = gen_rtx_REG (Pmode, PIC_OFFSET_TABLE_REGNUM); 16789 rtx label_rtx = gen_label_rtx (); 16790 emit_insn (gen_set_got_labelled (pic_offset_table_rtx, label_rtx)); 16791 xops[0] = xops[1] = picreg; 16792 xops[2] = machopic_gen_offset (gen_rtx_LABEL_REF (SImode, label_rtx)); 16793 ix86_expand_binary_operator (MINUS, SImode, xops); 16794 } 16795 else 16796#endif 16797 emit_insn (gen_set_got (pic_offset_table_rtx)); 16798 DONE; 16799}) 16800 16801;; Avoid redundant prefixes by splitting HImode arithmetic to SImode. 16802 16803(define_split 16804 [(set (match_operand 0 "register_operand" "") 16805 (match_operator 3 "promotable_binary_operator" 16806 [(match_operand 1 "register_operand" "") 16807 (match_operand 2 "aligned_operand" "")])) 16808 (clobber (reg:CC FLAGS_REG))] 16809 "! TARGET_PARTIAL_REG_STALL && reload_completed 16810 && ((GET_MODE (operands[0]) == HImode 16811 && ((optimize_function_for_speed_p (cfun) && !TARGET_FAST_PREFIX) 16812 /* ??? next two lines just !satisfies_constraint_K (...) */ 16813 || !CONST_INT_P (operands[2]) 16814 || satisfies_constraint_K (operands[2]))) 16815 || (GET_MODE (operands[0]) == QImode 16816 && (TARGET_PROMOTE_QImode || optimize_function_for_size_p (cfun))))" 16817 [(parallel [(set (match_dup 0) 16818 (match_op_dup 3 [(match_dup 1) (match_dup 2)])) 16819 (clobber (reg:CC FLAGS_REG))])] 16820{ 16821 operands[0] = gen_lowpart (SImode, operands[0]); 16822 operands[1] = gen_lowpart (SImode, operands[1]); 16823 if (GET_CODE (operands[3]) != ASHIFT) 16824 operands[2] = gen_lowpart (SImode, operands[2]); 16825 PUT_MODE (operands[3], SImode); 16826}) 16827 16828; Promote the QImode tests, as i386 has encoding of the AND 16829; instruction with 32-bit sign-extended immediate and thus the 16830; instruction size is unchanged, except in the %eax case for 16831; which it is increased by one byte, hence the ! optimize_size. 16832(define_split 16833 [(set (match_operand 0 "flags_reg_operand" "") 16834 (match_operator 2 "compare_operator" 16835 [(and (match_operand 3 "aligned_operand" "") 16836 (match_operand 4 "const_int_operand" "")) 16837 (const_int 0)])) 16838 (set (match_operand 1 "register_operand" "") 16839 (and (match_dup 3) (match_dup 4)))] 16840 "! TARGET_PARTIAL_REG_STALL && reload_completed 16841 && optimize_insn_for_speed_p () 16842 && ((GET_MODE (operands[1]) == HImode && ! TARGET_FAST_PREFIX) 16843 || (GET_MODE (operands[1]) == QImode && TARGET_PROMOTE_QImode)) 16844 /* Ensure that the operand will remain sign-extended immediate. */ 16845 && ix86_match_ccmode (insn, INTVAL (operands[4]) >= 0 ? CCNOmode : CCZmode)" 16846 [(parallel [(set (match_dup 0) 16847 (match_op_dup 2 [(and:SI (match_dup 3) (match_dup 4)) 16848 (const_int 0)])) 16849 (set (match_dup 1) 16850 (and:SI (match_dup 3) (match_dup 4)))])] 16851{ 16852 operands[4] 16853 = gen_int_mode (INTVAL (operands[4]) 16854 & GET_MODE_MASK (GET_MODE (operands[1])), SImode); 16855 operands[1] = gen_lowpart (SImode, operands[1]); 16856 operands[3] = gen_lowpart (SImode, operands[3]); 16857}) 16858 16859; Don't promote the QImode tests, as i386 doesn't have encoding of 16860; the TEST instruction with 32-bit sign-extended immediate and thus 16861; the instruction size would at least double, which is not what we 16862; want even with ! optimize_size. 16863(define_split 16864 [(set (match_operand 0 "flags_reg_operand" "") 16865 (match_operator 1 "compare_operator" 16866 [(and (match_operand:HI 2 "aligned_operand" "") 16867 (match_operand:HI 3 "const_int_operand" "")) 16868 (const_int 0)]))] 16869 "! TARGET_PARTIAL_REG_STALL && reload_completed 16870 && ! TARGET_FAST_PREFIX 16871 && optimize_insn_for_speed_p () 16872 /* Ensure that the operand will remain sign-extended immediate. */ 16873 && ix86_match_ccmode (insn, INTVAL (operands[3]) >= 0 ? CCNOmode : CCZmode)" 16874 [(set (match_dup 0) 16875 (match_op_dup 1 [(and:SI (match_dup 2) (match_dup 3)) 16876 (const_int 0)]))] 16877{ 16878 operands[3] 16879 = gen_int_mode (INTVAL (operands[3]) 16880 & GET_MODE_MASK (GET_MODE (operands[2])), SImode); 16881 operands[2] = gen_lowpart (SImode, operands[2]); 16882}) 16883 16884(define_split 16885 [(set (match_operand 0 "register_operand" "") 16886 (neg (match_operand 1 "register_operand" ""))) 16887 (clobber (reg:CC FLAGS_REG))] 16888 "! TARGET_PARTIAL_REG_STALL && reload_completed 16889 && (GET_MODE (operands[0]) == HImode 16890 || (GET_MODE (operands[0]) == QImode 16891 && (TARGET_PROMOTE_QImode 16892 || optimize_insn_for_size_p ())))" 16893 [(parallel [(set (match_dup 0) 16894 (neg:SI (match_dup 1))) 16895 (clobber (reg:CC FLAGS_REG))])] 16896{ 16897 operands[0] = gen_lowpart (SImode, operands[0]); 16898 operands[1] = gen_lowpart (SImode, operands[1]); 16899}) 16900 16901(define_split 16902 [(set (match_operand 0 "register_operand" "") 16903 (not (match_operand 1 "register_operand" "")))] 16904 "! TARGET_PARTIAL_REG_STALL && reload_completed 16905 && (GET_MODE (operands[0]) == HImode 16906 || (GET_MODE (operands[0]) == QImode 16907 && (TARGET_PROMOTE_QImode 16908 || optimize_insn_for_size_p ())))" 16909 [(set (match_dup 0) 16910 (not:SI (match_dup 1)))] 16911{ 16912 operands[0] = gen_lowpart (SImode, operands[0]); 16913 operands[1] = gen_lowpart (SImode, operands[1]); 16914}) 16915 16916;; RTL Peephole optimizations, run before sched2. These primarily look to 16917;; transform a complex memory operation into two memory to register operations. 16918 16919;; Don't push memory operands 16920(define_peephole2 16921 [(set (match_operand:SWI 0 "push_operand" "") 16922 (match_operand:SWI 1 "memory_operand" "")) 16923 (match_scratch:SWI 2 "<r>")] 16924 "!(TARGET_PUSH_MEMORY || optimize_insn_for_size_p ()) 16925 && !RTX_FRAME_RELATED_P (peep2_next_insn (0))" 16926 [(set (match_dup 2) (match_dup 1)) 16927 (set (match_dup 0) (match_dup 2))]) 16928 16929;; We need to handle SFmode only, because DFmode and XFmode are split to 16930;; SImode pushes. 16931(define_peephole2 16932 [(set (match_operand:SF 0 "push_operand" "") 16933 (match_operand:SF 1 "memory_operand" "")) 16934 (match_scratch:SF 2 "r")] 16935 "!(TARGET_PUSH_MEMORY || optimize_insn_for_size_p ()) 16936 && !RTX_FRAME_RELATED_P (peep2_next_insn (0))" 16937 [(set (match_dup 2) (match_dup 1)) 16938 (set (match_dup 0) (match_dup 2))]) 16939 16940;; Don't move an immediate directly to memory when the instruction 16941;; gets too big. 16942(define_peephole2 16943 [(match_scratch:SWI124 1 "<r>") 16944 (set (match_operand:SWI124 0 "memory_operand" "") 16945 (const_int 0))] 16946 "optimize_insn_for_speed_p () 16947 && !TARGET_USE_MOV0 16948 && TARGET_SPLIT_LONG_MOVES 16949 && get_attr_length (insn) >= ix86_cur_cost ()->large_insn 16950 && peep2_regno_dead_p (0, FLAGS_REG)" 16951 [(parallel [(set (match_dup 2) (const_int 0)) 16952 (clobber (reg:CC FLAGS_REG))]) 16953 (set (match_dup 0) (match_dup 1))] 16954 "operands[2] = gen_lowpart (SImode, operands[1]);") 16955 16956(define_peephole2 16957 [(match_scratch:SWI124 2 "<r>") 16958 (set (match_operand:SWI124 0 "memory_operand" "") 16959 (match_operand:SWI124 1 "immediate_operand" ""))] 16960 "optimize_insn_for_speed_p () 16961 && TARGET_SPLIT_LONG_MOVES 16962 && get_attr_length (insn) >= ix86_cur_cost ()->large_insn" 16963 [(set (match_dup 2) (match_dup 1)) 16964 (set (match_dup 0) (match_dup 2))]) 16965 16966;; Don't compare memory with zero, load and use a test instead. 16967(define_peephole2 16968 [(set (match_operand 0 "flags_reg_operand" "") 16969 (match_operator 1 "compare_operator" 16970 [(match_operand:SI 2 "memory_operand" "") 16971 (const_int 0)])) 16972 (match_scratch:SI 3 "r")] 16973 "optimize_insn_for_speed_p () && ix86_match_ccmode (insn, CCNOmode)" 16974 [(set (match_dup 3) (match_dup 2)) 16975 (set (match_dup 0) (match_op_dup 1 [(match_dup 3) (const_int 0)]))]) 16976 16977;; NOT is not pairable on Pentium, while XOR is, but one byte longer. 16978;; Don't split NOTs with a displacement operand, because resulting XOR 16979;; will not be pairable anyway. 16980;; 16981;; On AMD K6, NOT is vector decoded with memory operand that cannot be 16982;; represented using a modRM byte. The XOR replacement is long decoded, 16983;; so this split helps here as well. 16984;; 16985;; Note: Can't do this as a regular split because we can't get proper 16986;; lifetime information then. 16987 16988(define_peephole2 16989 [(set (match_operand:SWI124 0 "nonimmediate_operand" "") 16990 (not:SWI124 (match_operand:SWI124 1 "nonimmediate_operand" "")))] 16991 "optimize_insn_for_speed_p () 16992 && ((TARGET_NOT_UNPAIRABLE 16993 && (!MEM_P (operands[0]) 16994 || !memory_displacement_operand (operands[0], <MODE>mode))) 16995 || (TARGET_NOT_VECTORMODE 16996 && long_memory_operand (operands[0], <MODE>mode))) 16997 && peep2_regno_dead_p (0, FLAGS_REG)" 16998 [(parallel [(set (match_dup 0) 16999 (xor:SWI124 (match_dup 1) (const_int -1))) 17000 (clobber (reg:CC FLAGS_REG))])]) 17001 17002;; Non pairable "test imm, reg" instructions can be translated to 17003;; "and imm, reg" if reg dies. The "and" form is also shorter (one 17004;; byte opcode instead of two, have a short form for byte operands), 17005;; so do it for other CPUs as well. Given that the value was dead, 17006;; this should not create any new dependencies. Pass on the sub-word 17007;; versions if we're concerned about partial register stalls. 17008 17009(define_peephole2 17010 [(set (match_operand 0 "flags_reg_operand" "") 17011 (match_operator 1 "compare_operator" 17012 [(and:SI (match_operand:SI 2 "register_operand" "") 17013 (match_operand:SI 3 "immediate_operand" "")) 17014 (const_int 0)]))] 17015 "ix86_match_ccmode (insn, CCNOmode) 17016 && (true_regnum (operands[2]) != AX_REG 17017 || satisfies_constraint_K (operands[3])) 17018 && peep2_reg_dead_p (1, operands[2])" 17019 [(parallel 17020 [(set (match_dup 0) 17021 (match_op_dup 1 [(and:SI (match_dup 2) (match_dup 3)) 17022 (const_int 0)])) 17023 (set (match_dup 2) 17024 (and:SI (match_dup 2) (match_dup 3)))])]) 17025 17026;; We don't need to handle HImode case, because it will be promoted to SImode 17027;; on ! TARGET_PARTIAL_REG_STALL 17028 17029(define_peephole2 17030 [(set (match_operand 0 "flags_reg_operand" "") 17031 (match_operator 1 "compare_operator" 17032 [(and:QI (match_operand:QI 2 "register_operand" "") 17033 (match_operand:QI 3 "immediate_operand" "")) 17034 (const_int 0)]))] 17035 "! TARGET_PARTIAL_REG_STALL 17036 && ix86_match_ccmode (insn, CCNOmode) 17037 && true_regnum (operands[2]) != AX_REG 17038 && peep2_reg_dead_p (1, operands[2])" 17039 [(parallel 17040 [(set (match_dup 0) 17041 (match_op_dup 1 [(and:QI (match_dup 2) (match_dup 3)) 17042 (const_int 0)])) 17043 (set (match_dup 2) 17044 (and:QI (match_dup 2) (match_dup 3)))])]) 17045 17046(define_peephole2 17047 [(set (match_operand 0 "flags_reg_operand" "") 17048 (match_operator 1 "compare_operator" 17049 [(and:SI 17050 (zero_extract:SI 17051 (match_operand 2 "ext_register_operand" "") 17052 (const_int 8) 17053 (const_int 8)) 17054 (match_operand 3 "const_int_operand" "")) 17055 (const_int 0)]))] 17056 "! TARGET_PARTIAL_REG_STALL 17057 && ix86_match_ccmode (insn, CCNOmode) 17058 && true_regnum (operands[2]) != AX_REG 17059 && peep2_reg_dead_p (1, operands[2])" 17060 [(parallel [(set (match_dup 0) 17061 (match_op_dup 1 17062 [(and:SI 17063 (zero_extract:SI 17064 (match_dup 2) 17065 (const_int 8) 17066 (const_int 8)) 17067 (match_dup 3)) 17068 (const_int 0)])) 17069 (set (zero_extract:SI (match_dup 2) 17070 (const_int 8) 17071 (const_int 8)) 17072 (and:SI 17073 (zero_extract:SI 17074 (match_dup 2) 17075 (const_int 8) 17076 (const_int 8)) 17077 (match_dup 3)))])]) 17078 17079;; Don't do logical operations with memory inputs. 17080(define_peephole2 17081 [(match_scratch:SI 2 "r") 17082 (parallel [(set (match_operand:SI 0 "register_operand" "") 17083 (match_operator:SI 3 "arith_or_logical_operator" 17084 [(match_dup 0) 17085 (match_operand:SI 1 "memory_operand" "")])) 17086 (clobber (reg:CC FLAGS_REG))])] 17087 "!(TARGET_READ_MODIFY || optimize_insn_for_size_p ())" 17088 [(set (match_dup 2) (match_dup 1)) 17089 (parallel [(set (match_dup 0) 17090 (match_op_dup 3 [(match_dup 0) (match_dup 2)])) 17091 (clobber (reg:CC FLAGS_REG))])]) 17092 17093(define_peephole2 17094 [(match_scratch:SI 2 "r") 17095 (parallel [(set (match_operand:SI 0 "register_operand" "") 17096 (match_operator:SI 3 "arith_or_logical_operator" 17097 [(match_operand:SI 1 "memory_operand" "") 17098 (match_dup 0)])) 17099 (clobber (reg:CC FLAGS_REG))])] 17100 "!(TARGET_READ_MODIFY || optimize_insn_for_size_p ())" 17101 [(set (match_dup 2) (match_dup 1)) 17102 (parallel [(set (match_dup 0) 17103 (match_op_dup 3 [(match_dup 2) (match_dup 0)])) 17104 (clobber (reg:CC FLAGS_REG))])]) 17105 17106;; Prefer Load+RegOp to Mov+MemOp. Watch out for cases when the memory address 17107;; refers to the destination of the load! 17108 17109(define_peephole2 17110 [(set (match_operand:SI 0 "register_operand" "") 17111 (match_operand:SI 1 "register_operand" "")) 17112 (parallel [(set (match_dup 0) 17113 (match_operator:SI 3 "commutative_operator" 17114 [(match_dup 0) 17115 (match_operand:SI 2 "memory_operand" "")])) 17116 (clobber (reg:CC FLAGS_REG))])] 17117 "REGNO (operands[0]) != REGNO (operands[1]) 17118 && GENERAL_REGNO_P (REGNO (operands[0])) 17119 && GENERAL_REGNO_P (REGNO (operands[1]))" 17120 [(set (match_dup 0) (match_dup 4)) 17121 (parallel [(set (match_dup 0) 17122 (match_op_dup 3 [(match_dup 0) (match_dup 1)])) 17123 (clobber (reg:CC FLAGS_REG))])] 17124 "operands[4] = replace_rtx (operands[2], operands[0], operands[1]);") 17125 17126(define_peephole2 17127 [(set (match_operand 0 "register_operand" "") 17128 (match_operand 1 "register_operand" "")) 17129 (set (match_dup 0) 17130 (match_operator 3 "commutative_operator" 17131 [(match_dup 0) 17132 (match_operand 2 "memory_operand" "")]))] 17133 "REGNO (operands[0]) != REGNO (operands[1]) 17134 && ((MMX_REG_P (operands[0]) && MMX_REG_P (operands[1])) 17135 || (SSE_REG_P (operands[0]) && SSE_REG_P (operands[1])))" 17136 [(set (match_dup 0) (match_dup 2)) 17137 (set (match_dup 0) 17138 (match_op_dup 3 [(match_dup 0) (match_dup 1)]))]) 17139 17140; Don't do logical operations with memory outputs 17141; 17142; These two don't make sense for PPro/PII -- we're expanding a 4-uop 17143; instruction into two 1-uop insns plus a 2-uop insn. That last has 17144; the same decoder scheduling characteristics as the original. 17145 17146(define_peephole2 17147 [(match_scratch:SI 2 "r") 17148 (parallel [(set (match_operand:SI 0 "memory_operand" "") 17149 (match_operator:SI 3 "arith_or_logical_operator" 17150 [(match_dup 0) 17151 (match_operand:SI 1 "nonmemory_operand" "")])) 17152 (clobber (reg:CC FLAGS_REG))])] 17153 "!(TARGET_READ_MODIFY_WRITE || optimize_insn_for_size_p ()) 17154 /* Do not split stack checking probes. */ 17155 && GET_CODE (operands[3]) != IOR && operands[1] != const0_rtx" 17156 [(set (match_dup 2) (match_dup 0)) 17157 (parallel [(set (match_dup 2) 17158 (match_op_dup 3 [(match_dup 2) (match_dup 1)])) 17159 (clobber (reg:CC FLAGS_REG))]) 17160 (set (match_dup 0) (match_dup 2))]) 17161 17162(define_peephole2 17163 [(match_scratch:SI 2 "r") 17164 (parallel [(set (match_operand:SI 0 "memory_operand" "") 17165 (match_operator:SI 3 "arith_or_logical_operator" 17166 [(match_operand:SI 1 "nonmemory_operand" "") 17167 (match_dup 0)])) 17168 (clobber (reg:CC FLAGS_REG))])] 17169 "!(TARGET_READ_MODIFY_WRITE || optimize_insn_for_size_p ()) 17170 /* Do not split stack checking probes. */ 17171 && GET_CODE (operands[3]) != IOR && operands[1] != const0_rtx" 17172 [(set (match_dup 2) (match_dup 0)) 17173 (parallel [(set (match_dup 2) 17174 (match_op_dup 3 [(match_dup 1) (match_dup 2)])) 17175 (clobber (reg:CC FLAGS_REG))]) 17176 (set (match_dup 0) (match_dup 2))]) 17177 17178;; Attempt to use arith or logical operations with memory outputs with 17179;; setting of flags. 17180(define_peephole2 17181 [(set (match_operand:SWI 0 "register_operand" "") 17182 (match_operand:SWI 1 "memory_operand" "")) 17183 (parallel [(set (match_dup 0) 17184 (match_operator:SWI 3 "plusminuslogic_operator" 17185 [(match_dup 0) 17186 (match_operand:SWI 2 "<nonmemory_operand>" "")])) 17187 (clobber (reg:CC FLAGS_REG))]) 17188 (set (match_dup 1) (match_dup 0)) 17189 (set (reg FLAGS_REG) (compare (match_dup 0) (const_int 0)))] 17190 "(TARGET_READ_MODIFY_WRITE || optimize_insn_for_size_p ()) 17191 && peep2_reg_dead_p (4, operands[0]) 17192 && !reg_overlap_mentioned_p (operands[0], operands[1]) 17193 && (<MODE>mode != QImode 17194 || immediate_operand (operands[2], QImode) 17195 || q_regs_operand (operands[2], QImode)) 17196 && ix86_match_ccmode (peep2_next_insn (3), 17197 (GET_CODE (operands[3]) == PLUS 17198 || GET_CODE (operands[3]) == MINUS) 17199 ? CCGOCmode : CCNOmode)" 17200 [(parallel [(set (match_dup 4) (match_dup 5)) 17201 (set (match_dup 1) (match_op_dup 3 [(match_dup 1) 17202 (match_dup 2)]))])] 17203{ 17204 operands[4] = SET_DEST (PATTERN (peep2_next_insn (3))); 17205 operands[5] = gen_rtx_fmt_ee (GET_CODE (operands[3]), <MODE>mode, 17206 copy_rtx (operands[1]), 17207 copy_rtx (operands[2])); 17208 operands[5] = gen_rtx_COMPARE (GET_MODE (operands[4]), 17209 operands[5], const0_rtx); 17210}) 17211 17212(define_peephole2 17213 [(parallel [(set (match_operand:SWI 0 "register_operand" "") 17214 (match_operator:SWI 2 "plusminuslogic_operator" 17215 [(match_dup 0) 17216 (match_operand:SWI 1 "memory_operand" "")])) 17217 (clobber (reg:CC FLAGS_REG))]) 17218 (set (match_dup 1) (match_dup 0)) 17219 (set (reg FLAGS_REG) (compare (match_dup 0) (const_int 0)))] 17220 "(TARGET_READ_MODIFY_WRITE || optimize_insn_for_size_p ()) 17221 && GET_CODE (operands[2]) != MINUS 17222 && peep2_reg_dead_p (3, operands[0]) 17223 && !reg_overlap_mentioned_p (operands[0], operands[1]) 17224 && ix86_match_ccmode (peep2_next_insn (2), 17225 GET_CODE (operands[2]) == PLUS 17226 ? CCGOCmode : CCNOmode)" 17227 [(parallel [(set (match_dup 3) (match_dup 4)) 17228 (set (match_dup 1) (match_op_dup 2 [(match_dup 1) 17229 (match_dup 0)]))])] 17230{ 17231 operands[3] = SET_DEST (PATTERN (peep2_next_insn (2))); 17232 operands[4] = gen_rtx_fmt_ee (GET_CODE (operands[2]), <MODE>mode, 17233 copy_rtx (operands[1]), 17234 copy_rtx (operands[0])); 17235 operands[4] = gen_rtx_COMPARE (GET_MODE (operands[3]), 17236 operands[4], const0_rtx); 17237}) 17238 17239(define_peephole2 17240 [(set (match_operand:SWI12 0 "register_operand" "") 17241 (match_operand:SWI12 1 "memory_operand" "")) 17242 (parallel [(set (match_operand:SI 4 "register_operand" "") 17243 (match_operator:SI 3 "plusminuslogic_operator" 17244 [(match_dup 4) 17245 (match_operand:SI 2 "nonmemory_operand" "")])) 17246 (clobber (reg:CC FLAGS_REG))]) 17247 (set (match_dup 1) (match_dup 0)) 17248 (set (reg FLAGS_REG) (compare (match_dup 0) (const_int 0)))] 17249 "(TARGET_READ_MODIFY_WRITE || optimize_insn_for_size_p ()) 17250 && REG_P (operands[0]) && REG_P (operands[4]) 17251 && REGNO (operands[0]) == REGNO (operands[4]) 17252 && peep2_reg_dead_p (4, operands[0]) 17253 && (<MODE>mode != QImode 17254 || immediate_operand (operands[2], SImode) 17255 || q_regs_operand (operands[2], SImode)) 17256 && !reg_overlap_mentioned_p (operands[0], operands[1]) 17257 && ix86_match_ccmode (peep2_next_insn (3), 17258 (GET_CODE (operands[3]) == PLUS 17259 || GET_CODE (operands[3]) == MINUS) 17260 ? CCGOCmode : CCNOmode)" 17261 [(parallel [(set (match_dup 4) (match_dup 5)) 17262 (set (match_dup 1) (match_dup 6))])] 17263{ 17264 operands[2] = gen_lowpart (<MODE>mode, operands[2]); 17265 operands[4] = SET_DEST (PATTERN (peep2_next_insn (3))); 17266 operands[5] = gen_rtx_fmt_ee (GET_CODE (operands[3]), <MODE>mode, 17267 copy_rtx (operands[1]), operands[2]); 17268 operands[5] = gen_rtx_COMPARE (GET_MODE (operands[4]), 17269 operands[5], const0_rtx); 17270 operands[6] = gen_rtx_fmt_ee (GET_CODE (operands[3]), <MODE>mode, 17271 copy_rtx (operands[1]), 17272 copy_rtx (operands[2])); 17273}) 17274 17275;; Attempt to always use XOR for zeroing registers. 17276(define_peephole2 17277 [(set (match_operand 0 "register_operand" "") 17278 (match_operand 1 "const0_operand" ""))] 17279 "GET_MODE_SIZE (GET_MODE (operands[0])) <= UNITS_PER_WORD 17280 && (! TARGET_USE_MOV0 || optimize_insn_for_size_p ()) 17281 && GENERAL_REG_P (operands[0]) 17282 && peep2_regno_dead_p (0, FLAGS_REG)" 17283 [(parallel [(set (match_dup 0) (const_int 0)) 17284 (clobber (reg:CC FLAGS_REG))])] 17285 "operands[0] = gen_lowpart (word_mode, operands[0]);") 17286 17287(define_peephole2 17288 [(set (strict_low_part (match_operand 0 "register_operand" "")) 17289 (const_int 0))] 17290 "(GET_MODE (operands[0]) == QImode 17291 || GET_MODE (operands[0]) == HImode) 17292 && (! TARGET_USE_MOV0 || optimize_insn_for_size_p ()) 17293 && peep2_regno_dead_p (0, FLAGS_REG)" 17294 [(parallel [(set (strict_low_part (match_dup 0)) (const_int 0)) 17295 (clobber (reg:CC FLAGS_REG))])]) 17296 17297;; For HI, SI and DI modes, or $-1,reg is smaller than mov $-1,reg. 17298(define_peephole2 17299 [(set (match_operand:SWI248 0 "register_operand" "") 17300 (const_int -1))] 17301 "(optimize_insn_for_size_p () || TARGET_MOVE_M1_VIA_OR) 17302 && peep2_regno_dead_p (0, FLAGS_REG)" 17303 [(parallel [(set (match_dup 0) (const_int -1)) 17304 (clobber (reg:CC FLAGS_REG))])] 17305{ 17306 if (GET_MODE_SIZE (<MODE>mode) < GET_MODE_SIZE (SImode)) 17307 operands[0] = gen_lowpart (SImode, operands[0]); 17308}) 17309 17310;; Attempt to convert simple lea to add/shift. 17311;; These can be created by move expanders. 17312 17313(define_peephole2 17314 [(set (match_operand:SWI48 0 "register_operand" "") 17315 (plus:SWI48 (match_dup 0) 17316 (match_operand:SWI48 1 "<nonmemory_operand>" "")))] 17317 "peep2_regno_dead_p (0, FLAGS_REG)" 17318 [(parallel [(set (match_dup 0) (plus:SWI48 (match_dup 0) (match_dup 1))) 17319 (clobber (reg:CC FLAGS_REG))])]) 17320 17321(define_peephole2 17322 [(set (match_operand:SI 0 "register_operand" "") 17323 (subreg:SI (plus:DI (match_operand:DI 1 "register_operand" "") 17324 (match_operand:DI 2 "nonmemory_operand" "")) 0))] 17325 "TARGET_64BIT 17326 && peep2_regno_dead_p (0, FLAGS_REG) 17327 && REGNO (operands[0]) == REGNO (operands[1])" 17328 [(parallel [(set (match_dup 0) (plus:SI (match_dup 0) (match_dup 2))) 17329 (clobber (reg:CC FLAGS_REG))])] 17330 "operands[2] = gen_lowpart (SImode, operands[2]);") 17331 17332(define_peephole2 17333 [(set (match_operand:SWI48 0 "register_operand" "") 17334 (mult:SWI48 (match_dup 0) 17335 (match_operand:SWI48 1 "const_int_operand" "")))] 17336 "exact_log2 (INTVAL (operands[1])) >= 0 17337 && peep2_regno_dead_p (0, FLAGS_REG)" 17338 [(parallel [(set (match_dup 0) (ashift:SWI48 (match_dup 0) (match_dup 2))) 17339 (clobber (reg:CC FLAGS_REG))])] 17340 "operands[2] = GEN_INT (exact_log2 (INTVAL (operands[1])));") 17341 17342(define_peephole2 17343 [(set (match_operand:SI 0 "register_operand" "") 17344 (subreg:SI (mult:DI (match_operand:DI 1 "register_operand" "") 17345 (match_operand:DI 2 "const_int_operand" "")) 0))] 17346 "TARGET_64BIT 17347 && exact_log2 (INTVAL (operands[2])) >= 0 17348 && REGNO (operands[0]) == REGNO (operands[1]) 17349 && peep2_regno_dead_p (0, FLAGS_REG)" 17350 [(parallel [(set (match_dup 0) (ashift:SI (match_dup 0) (match_dup 2))) 17351 (clobber (reg:CC FLAGS_REG))])] 17352 "operands[2] = GEN_INT (exact_log2 (INTVAL (operands[2])));") 17353 17354;; The ESP adjustments can be done by the push and pop instructions. Resulting 17355;; code is shorter, since push is only 1 byte, while add imm, %esp is 3 bytes. 17356;; On many CPUs it is also faster, since special hardware to avoid esp 17357;; dependencies is present. 17358 17359;; While some of these conversions may be done using splitters, we use 17360;; peepholes in order to allow combine_stack_adjustments pass to see 17361;; nonobfuscated RTL. 17362 17363;; Convert prologue esp subtractions to push. 17364;; We need register to push. In order to keep verify_flow_info happy we have 17365;; two choices 17366;; - use scratch and clobber it in order to avoid dependencies 17367;; - use already live register 17368;; We can't use the second way right now, since there is no reliable way how to 17369;; verify that given register is live. First choice will also most likely in 17370;; fewer dependencies. On the place of esp adjustments it is very likely that 17371;; call clobbered registers are dead. We may want to use base pointer as an 17372;; alternative when no register is available later. 17373 17374(define_peephole2 17375 [(match_scratch:P 1 "r") 17376 (parallel [(set (reg:P SP_REG) 17377 (plus:P (reg:P SP_REG) 17378 (match_operand:P 0 "const_int_operand" ""))) 17379 (clobber (reg:CC FLAGS_REG)) 17380 (clobber (mem:BLK (scratch)))])] 17381 "(TARGET_SINGLE_PUSH || optimize_insn_for_size_p ()) 17382 && INTVAL (operands[0]) == -GET_MODE_SIZE (Pmode)" 17383 [(clobber (match_dup 1)) 17384 (parallel [(set (mem:P (pre_dec:P (reg:P SP_REG))) (match_dup 1)) 17385 (clobber (mem:BLK (scratch)))])]) 17386 17387(define_peephole2 17388 [(match_scratch:P 1 "r") 17389 (parallel [(set (reg:P SP_REG) 17390 (plus:P (reg:P SP_REG) 17391 (match_operand:P 0 "const_int_operand" ""))) 17392 (clobber (reg:CC FLAGS_REG)) 17393 (clobber (mem:BLK (scratch)))])] 17394 "(TARGET_DOUBLE_PUSH || optimize_insn_for_size_p ()) 17395 && INTVAL (operands[0]) == -2*GET_MODE_SIZE (Pmode)" 17396 [(clobber (match_dup 1)) 17397 (set (mem:P (pre_dec:P (reg:P SP_REG))) (match_dup 1)) 17398 (parallel [(set (mem:P (pre_dec:P (reg:P SP_REG))) (match_dup 1)) 17399 (clobber (mem:BLK (scratch)))])]) 17400 17401;; Convert esp subtractions to push. 17402(define_peephole2 17403 [(match_scratch:P 1 "r") 17404 (parallel [(set (reg:P SP_REG) 17405 (plus:P (reg:P SP_REG) 17406 (match_operand:P 0 "const_int_operand" ""))) 17407 (clobber (reg:CC FLAGS_REG))])] 17408 "(TARGET_SINGLE_PUSH || optimize_insn_for_size_p ()) 17409 && INTVAL (operands[0]) == -GET_MODE_SIZE (Pmode)" 17410 [(clobber (match_dup 1)) 17411 (set (mem:P (pre_dec:P (reg:P SP_REG))) (match_dup 1))]) 17412 17413(define_peephole2 17414 [(match_scratch:P 1 "r") 17415 (parallel [(set (reg:P SP_REG) 17416 (plus:P (reg:P SP_REG) 17417 (match_operand:P 0 "const_int_operand" ""))) 17418 (clobber (reg:CC FLAGS_REG))])] 17419 "(TARGET_DOUBLE_PUSH || optimize_insn_for_size_p ()) 17420 && INTVAL (operands[0]) == -2*GET_MODE_SIZE (Pmode)" 17421 [(clobber (match_dup 1)) 17422 (set (mem:P (pre_dec:P (reg:P SP_REG))) (match_dup 1)) 17423 (set (mem:P (pre_dec:P (reg:P SP_REG))) (match_dup 1))]) 17424 17425;; Convert epilogue deallocator to pop. 17426(define_peephole2 17427 [(match_scratch:P 1 "r") 17428 (parallel [(set (reg:P SP_REG) 17429 (plus:P (reg:P SP_REG) 17430 (match_operand:P 0 "const_int_operand" ""))) 17431 (clobber (reg:CC FLAGS_REG)) 17432 (clobber (mem:BLK (scratch)))])] 17433 "(TARGET_SINGLE_POP || optimize_insn_for_size_p ()) 17434 && INTVAL (operands[0]) == GET_MODE_SIZE (Pmode)" 17435 [(parallel [(set (match_dup 1) (mem:P (post_inc:P (reg:P SP_REG)))) 17436 (clobber (mem:BLK (scratch)))])]) 17437 17438;; Two pops case is tricky, since pop causes dependency 17439;; on destination register. We use two registers if available. 17440(define_peephole2 17441 [(match_scratch:P 1 "r") 17442 (match_scratch:P 2 "r") 17443 (parallel [(set (reg:P SP_REG) 17444 (plus:P (reg:P SP_REG) 17445 (match_operand:P 0 "const_int_operand" ""))) 17446 (clobber (reg:CC FLAGS_REG)) 17447 (clobber (mem:BLK (scratch)))])] 17448 "(TARGET_DOUBLE_POP || optimize_insn_for_size_p ()) 17449 && INTVAL (operands[0]) == 2*GET_MODE_SIZE (Pmode)" 17450 [(parallel [(set (match_dup 1) (mem:P (post_inc:P (reg:P SP_REG)))) 17451 (clobber (mem:BLK (scratch)))]) 17452 (set (match_dup 2) (mem:P (post_inc:P (reg:P SP_REG))))]) 17453 17454(define_peephole2 17455 [(match_scratch:P 1 "r") 17456 (parallel [(set (reg:P SP_REG) 17457 (plus:P (reg:P SP_REG) 17458 (match_operand:P 0 "const_int_operand" ""))) 17459 (clobber (reg:CC FLAGS_REG)) 17460 (clobber (mem:BLK (scratch)))])] 17461 "optimize_insn_for_size_p () 17462 && INTVAL (operands[0]) == 2*GET_MODE_SIZE (Pmode)" 17463 [(parallel [(set (match_dup 1) (mem:P (post_inc:P (reg:P SP_REG)))) 17464 (clobber (mem:BLK (scratch)))]) 17465 (set (match_dup 1) (mem:P (post_inc:P (reg:P SP_REG))))]) 17466 17467;; Convert esp additions to pop. 17468(define_peephole2 17469 [(match_scratch:P 1 "r") 17470 (parallel [(set (reg:P SP_REG) 17471 (plus:P (reg:P SP_REG) 17472 (match_operand:P 0 "const_int_operand" ""))) 17473 (clobber (reg:CC FLAGS_REG))])] 17474 "INTVAL (operands[0]) == GET_MODE_SIZE (Pmode)" 17475 [(set (match_dup 1) (mem:P (post_inc:P (reg:P SP_REG))))]) 17476 17477;; Two pops case is tricky, since pop causes dependency 17478;; on destination register. We use two registers if available. 17479(define_peephole2 17480 [(match_scratch:P 1 "r") 17481 (match_scratch:P 2 "r") 17482 (parallel [(set (reg:P SP_REG) 17483 (plus:P (reg:P SP_REG) 17484 (match_operand:P 0 "const_int_operand" ""))) 17485 (clobber (reg:CC FLAGS_REG))])] 17486 "INTVAL (operands[0]) == 2*GET_MODE_SIZE (Pmode)" 17487 [(set (match_dup 1) (mem:P (post_inc:P (reg:P SP_REG)))) 17488 (set (match_dup 2) (mem:P (post_inc:P (reg:P SP_REG))))]) 17489 17490(define_peephole2 17491 [(match_scratch:P 1 "r") 17492 (parallel [(set (reg:P SP_REG) 17493 (plus:P (reg:P SP_REG) 17494 (match_operand:P 0 "const_int_operand" ""))) 17495 (clobber (reg:CC FLAGS_REG))])] 17496 "optimize_insn_for_size_p () 17497 && INTVAL (operands[0]) == 2*GET_MODE_SIZE (Pmode)" 17498 [(set (match_dup 1) (mem:P (post_inc:P (reg:P SP_REG)))) 17499 (set (match_dup 1) (mem:P (post_inc:P (reg:P SP_REG))))]) 17500 17501;; Convert compares with 1 to shorter inc/dec operations when CF is not 17502;; required and register dies. Similarly for 128 to -128. 17503(define_peephole2 17504 [(set (match_operand 0 "flags_reg_operand" "") 17505 (match_operator 1 "compare_operator" 17506 [(match_operand 2 "register_operand" "") 17507 (match_operand 3 "const_int_operand" "")]))] 17508 "(((!TARGET_FUSE_CMP_AND_BRANCH || optimize_insn_for_size_p ()) 17509 && incdec_operand (operands[3], GET_MODE (operands[3]))) 17510 || (!TARGET_FUSE_CMP_AND_BRANCH 17511 && INTVAL (operands[3]) == 128)) 17512 && ix86_match_ccmode (insn, CCGCmode) 17513 && peep2_reg_dead_p (1, operands[2])" 17514 [(parallel [(set (match_dup 0) 17515 (match_op_dup 1 [(match_dup 2) (match_dup 3)])) 17516 (clobber (match_dup 2))])]) 17517 17518;; Convert imul by three, five and nine into lea 17519(define_peephole2 17520 [(parallel 17521 [(set (match_operand:SWI48 0 "register_operand" "") 17522 (mult:SWI48 (match_operand:SWI48 1 "register_operand" "") 17523 (match_operand:SWI48 2 "const359_operand" ""))) 17524 (clobber (reg:CC FLAGS_REG))])] 17525 "!TARGET_PARTIAL_REG_STALL 17526 || <MODE>mode == SImode 17527 || optimize_function_for_size_p (cfun)" 17528 [(set (match_dup 0) 17529 (plus:SWI48 (mult:SWI48 (match_dup 1) (match_dup 2)) 17530 (match_dup 1)))] 17531 "operands[2] = GEN_INT (INTVAL (operands[2]) - 1);") 17532 17533(define_peephole2 17534 [(parallel 17535 [(set (match_operand:SWI48 0 "register_operand" "") 17536 (mult:SWI48 (match_operand:SWI48 1 "nonimmediate_operand" "") 17537 (match_operand:SWI48 2 "const359_operand" ""))) 17538 (clobber (reg:CC FLAGS_REG))])] 17539 "optimize_insn_for_speed_p () 17540 && (!TARGET_PARTIAL_REG_STALL || <MODE>mode == SImode)" 17541 [(set (match_dup 0) (match_dup 1)) 17542 (set (match_dup 0) 17543 (plus:SWI48 (mult:SWI48 (match_dup 0) (match_dup 2)) 17544 (match_dup 0)))] 17545 "operands[2] = GEN_INT (INTVAL (operands[2]) - 1);") 17546 17547;; imul $32bit_imm, mem, reg is vector decoded, while 17548;; imul $32bit_imm, reg, reg is direct decoded. 17549(define_peephole2 17550 [(match_scratch:SWI48 3 "r") 17551 (parallel [(set (match_operand:SWI48 0 "register_operand" "") 17552 (mult:SWI48 (match_operand:SWI48 1 "memory_operand" "") 17553 (match_operand:SWI48 2 "immediate_operand" ""))) 17554 (clobber (reg:CC FLAGS_REG))])] 17555 "TARGET_SLOW_IMUL_IMM32_MEM && optimize_insn_for_speed_p () 17556 && !satisfies_constraint_K (operands[2])" 17557 [(set (match_dup 3) (match_dup 1)) 17558 (parallel [(set (match_dup 0) (mult:SWI48 (match_dup 3) (match_dup 2))) 17559 (clobber (reg:CC FLAGS_REG))])]) 17560 17561(define_peephole2 17562 [(match_scratch:SI 3 "r") 17563 (parallel [(set (match_operand:DI 0 "register_operand" "") 17564 (zero_extend:DI 17565 (mult:SI (match_operand:SI 1 "memory_operand" "") 17566 (match_operand:SI 2 "immediate_operand" "")))) 17567 (clobber (reg:CC FLAGS_REG))])] 17568 "TARGET_64BIT 17569 && TARGET_SLOW_IMUL_IMM32_MEM && optimize_insn_for_speed_p () 17570 && !satisfies_constraint_K (operands[2])" 17571 [(set (match_dup 3) (match_dup 1)) 17572 (parallel [(set (match_dup 0) 17573 (zero_extend:DI (mult:SI (match_dup 3) (match_dup 2)))) 17574 (clobber (reg:CC FLAGS_REG))])]) 17575 17576;; imul $8/16bit_imm, regmem, reg is vector decoded. 17577;; Convert it into imul reg, reg 17578;; It would be better to force assembler to encode instruction using long 17579;; immediate, but there is apparently no way to do so. 17580(define_peephole2 17581 [(parallel [(set (match_operand:SWI248 0 "register_operand" "") 17582 (mult:SWI248 17583 (match_operand:SWI248 1 "nonimmediate_operand" "") 17584 (match_operand:SWI248 2 "const_int_operand" ""))) 17585 (clobber (reg:CC FLAGS_REG))]) 17586 (match_scratch:SWI248 3 "r")] 17587 "TARGET_SLOW_IMUL_IMM8 && optimize_insn_for_speed_p () 17588 && satisfies_constraint_K (operands[2])" 17589 [(set (match_dup 3) (match_dup 2)) 17590 (parallel [(set (match_dup 0) (mult:SWI248 (match_dup 0) (match_dup 3))) 17591 (clobber (reg:CC FLAGS_REG))])] 17592{ 17593 if (!rtx_equal_p (operands[0], operands[1])) 17594 emit_move_insn (operands[0], operands[1]); 17595}) 17596 17597;; After splitting up read-modify operations, array accesses with memory 17598;; operands might end up in form: 17599;; sall $2, %eax 17600;; movl 4(%esp), %edx 17601;; addl %edx, %eax 17602;; instead of pre-splitting: 17603;; sall $2, %eax 17604;; addl 4(%esp), %eax 17605;; Turn it into: 17606;; movl 4(%esp), %edx 17607;; leal (%edx,%eax,4), %eax 17608 17609(define_peephole2 17610 [(match_scratch:P 5 "r") 17611 (parallel [(set (match_operand 0 "register_operand" "") 17612 (ashift (match_operand 1 "register_operand" "") 17613 (match_operand 2 "const_int_operand" ""))) 17614 (clobber (reg:CC FLAGS_REG))]) 17615 (parallel [(set (match_operand 3 "register_operand" "") 17616 (plus (match_dup 0) 17617 (match_operand 4 "x86_64_general_operand" ""))) 17618 (clobber (reg:CC FLAGS_REG))])] 17619 "IN_RANGE (INTVAL (operands[2]), 1, 3) 17620 /* Validate MODE for lea. */ 17621 && ((!TARGET_PARTIAL_REG_STALL 17622 && (GET_MODE (operands[0]) == QImode 17623 || GET_MODE (operands[0]) == HImode)) 17624 || GET_MODE (operands[0]) == SImode 17625 || (TARGET_64BIT && GET_MODE (operands[0]) == DImode)) 17626 && (rtx_equal_p (operands[0], operands[3]) 17627 || peep2_reg_dead_p (2, operands[0])) 17628 /* We reorder load and the shift. */ 17629 && !reg_overlap_mentioned_p (operands[0], operands[4])" 17630 [(set (match_dup 5) (match_dup 4)) 17631 (set (match_dup 0) (match_dup 1))] 17632{ 17633 enum machine_mode op1mode = GET_MODE (operands[1]); 17634 enum machine_mode mode = op1mode == DImode ? DImode : SImode; 17635 int scale = 1 << INTVAL (operands[2]); 17636 rtx index = gen_lowpart (Pmode, operands[1]); 17637 rtx base = gen_lowpart (Pmode, operands[5]); 17638 rtx dest = gen_lowpart (mode, operands[3]); 17639 17640 operands[1] = gen_rtx_PLUS (Pmode, base, 17641 gen_rtx_MULT (Pmode, index, GEN_INT (scale))); 17642 operands[5] = base; 17643 if (mode != Pmode) 17644 operands[1] = gen_rtx_SUBREG (mode, operands[1], 0); 17645 if (op1mode != Pmode) 17646 operands[5] = gen_rtx_SUBREG (op1mode, operands[5], 0); 17647 operands[0] = dest; 17648}) 17649 17650;; We used to use "int $5", in honor of #BR which maps to interrupt vector 5. 17651;; That, however, is usually mapped by the OS to SIGSEGV, which is often 17652;; caught for use by garbage collectors and the like. Using an insn that 17653;; maps to SIGILL makes it more likely the program will rightfully die. 17654;; Keeping with tradition, "6" is in honor of #UD. 17655(define_insn "trap" 17656 [(trap_if (const_int 1) (const_int 6))] 17657 "" 17658 { return ASM_SHORT "0x0b0f"; } 17659 [(set_attr "length" "2")]) 17660 17661(define_expand "prefetch" 17662 [(prefetch (match_operand 0 "address_operand" "") 17663 (match_operand:SI 1 "const_int_operand" "") 17664 (match_operand:SI 2 "const_int_operand" ""))] 17665 "TARGET_PREFETCH_SSE || TARGET_3DNOW" 17666{ 17667 int rw = INTVAL (operands[1]); 17668 int locality = INTVAL (operands[2]); 17669 17670 gcc_assert (rw == 0 || rw == 1); 17671 gcc_assert (IN_RANGE (locality, 0, 3)); 17672 17673 if (TARGET_PREFETCHW && rw) 17674 operands[2] = GEN_INT (3); 17675 /* Use 3dNOW prefetch in case we are asking for write prefetch not 17676 supported by SSE counterpart or the SSE prefetch is not available 17677 (K6 machines). Otherwise use SSE prefetch as it allows specifying 17678 of locality. */ 17679 else if (TARGET_3DNOW && (!TARGET_PREFETCH_SSE || rw)) 17680 operands[2] = GEN_INT (3); 17681 else 17682 operands[1] = const0_rtx; 17683}) 17684 17685(define_insn "*prefetch_sse" 17686 [(prefetch (match_operand 0 "address_operand" "p") 17687 (const_int 0) 17688 (match_operand:SI 1 "const_int_operand" ""))] 17689 "TARGET_PREFETCH_SSE" 17690{ 17691 static const char * const patterns[4] = { 17692 "prefetchnta\t%a0", "prefetcht2\t%a0", "prefetcht1\t%a0", "prefetcht0\t%a0" 17693 }; 17694 17695 int locality = INTVAL (operands[1]); 17696 gcc_assert (IN_RANGE (locality, 0, 3)); 17697 17698 return patterns[locality]; 17699} 17700 [(set_attr "type" "sse") 17701 (set_attr "atom_sse_attr" "prefetch") 17702 (set (attr "length_address") 17703 (symbol_ref "memory_address_length (operands[0], false)")) 17704 (set_attr "memory" "none")]) 17705 17706(define_insn "*prefetch_3dnow" 17707 [(prefetch (match_operand 0 "address_operand" "p") 17708 (match_operand:SI 1 "const_int_operand" "n") 17709 (const_int 3))] 17710 "TARGET_3DNOW || TARGET_PREFETCHW" 17711{ 17712 if (INTVAL (operands[1]) == 0) 17713 return "prefetch\t%a0"; 17714 else 17715 return "prefetchw\t%a0"; 17716} 17717 [(set_attr "type" "mmx") 17718 (set (attr "length_address") 17719 (symbol_ref "memory_address_length (operands[0], false)")) 17720 (set_attr "memory" "none")]) 17721 17722(define_expand "stack_protect_set" 17723 [(match_operand 0 "memory_operand" "") 17724 (match_operand 1 "memory_operand" "")] 17725 "!TARGET_HAS_BIONIC" 17726{ 17727 rtx (*insn)(rtx, rtx); 17728 17729#ifdef TARGET_THREAD_SSP_OFFSET 17730 operands[1] = GEN_INT (TARGET_THREAD_SSP_OFFSET); 17731 insn = (TARGET_LP64 17732 ? gen_stack_tls_protect_set_di 17733 : gen_stack_tls_protect_set_si); 17734#else 17735 insn = (TARGET_LP64 17736 ? gen_stack_protect_set_di 17737 : gen_stack_protect_set_si); 17738#endif 17739 17740 emit_insn (insn (operands[0], operands[1])); 17741 DONE; 17742}) 17743 17744(define_insn "stack_protect_set_<mode>" 17745 [(set (match_operand:PTR 0 "memory_operand" "=m") 17746 (unspec:PTR [(match_operand:PTR 1 "memory_operand" "m")] 17747 UNSPEC_SP_SET)) 17748 (set (match_scratch:PTR 2 "=&r") (const_int 0)) 17749 (clobber (reg:CC FLAGS_REG))] 17750 "!TARGET_HAS_BIONIC" 17751 "mov{<imodesuffix>}\t{%1, %2|%2, %1}\;mov{<imodesuffix>}\t{%2, %0|%0, %2}\;xor{l}\t%k2, %k2" 17752 [(set_attr "type" "multi")]) 17753 17754(define_insn "stack_tls_protect_set_<mode>" 17755 [(set (match_operand:PTR 0 "memory_operand" "=m") 17756 (unspec:PTR [(match_operand:PTR 1 "const_int_operand" "i")] 17757 UNSPEC_SP_TLS_SET)) 17758 (set (match_scratch:PTR 2 "=&r") (const_int 0)) 17759 (clobber (reg:CC FLAGS_REG))] 17760 "" 17761 "mov{<imodesuffix>}\t{%@:%P1, %2|%2, <iptrsize> PTR %@:%P1}\;mov{<imodesuffix>}\t{%2, %0|%0, %2}\;xor{l}\t%k2, %k2" 17762 [(set_attr "type" "multi")]) 17763 17764(define_expand "stack_protect_test" 17765 [(match_operand 0 "memory_operand" "") 17766 (match_operand 1 "memory_operand" "") 17767 (match_operand 2 "" "")] 17768 "!TARGET_HAS_BIONIC" 17769{ 17770 rtx flags = gen_rtx_REG (CCZmode, FLAGS_REG); 17771 17772 rtx (*insn)(rtx, rtx, rtx); 17773 17774#ifdef TARGET_THREAD_SSP_OFFSET 17775 operands[1] = GEN_INT (TARGET_THREAD_SSP_OFFSET); 17776 insn = (TARGET_LP64 17777 ? gen_stack_tls_protect_test_di 17778 : gen_stack_tls_protect_test_si); 17779#else 17780 insn = (TARGET_LP64 17781 ? gen_stack_protect_test_di 17782 : gen_stack_protect_test_si); 17783#endif 17784 17785 emit_insn (insn (flags, operands[0], operands[1])); 17786 17787 emit_jump_insn (gen_cbranchcc4 (gen_rtx_EQ (VOIDmode, flags, const0_rtx), 17788 flags, const0_rtx, operands[2])); 17789 DONE; 17790}) 17791 17792(define_insn "stack_protect_test_<mode>" 17793 [(set (match_operand:CCZ 0 "flags_reg_operand" "") 17794 (unspec:CCZ [(match_operand:PTR 1 "memory_operand" "m") 17795 (match_operand:PTR 2 "memory_operand" "m")] 17796 UNSPEC_SP_TEST)) 17797 (clobber (match_scratch:PTR 3 "=&r"))] 17798 "!TARGET_HAS_BIONIC" 17799 "mov{<imodesuffix>}\t{%1, %3|%3, %1}\;xor{<imodesuffix>}\t{%2, %3|%3, %2}" 17800 [(set_attr "type" "multi")]) 17801 17802(define_insn "stack_tls_protect_test_<mode>" 17803 [(set (match_operand:CCZ 0 "flags_reg_operand" "") 17804 (unspec:CCZ [(match_operand:PTR 1 "memory_operand" "m") 17805 (match_operand:PTR 2 "const_int_operand" "i")] 17806 UNSPEC_SP_TLS_TEST)) 17807 (clobber (match_scratch:PTR 3 "=r"))] 17808 "" 17809 "mov{<imodesuffix>}\t{%1, %3|%3, %1}\;xor{<imodesuffix>}\t{%@:%P2, %3|%3, <iptrsize> PTR %@:%P2}" 17810 [(set_attr "type" "multi")]) 17811 17812(define_insn "sse4_2_crc32<mode>" 17813 [(set (match_operand:SI 0 "register_operand" "=r") 17814 (unspec:SI 17815 [(match_operand:SI 1 "register_operand" "0") 17816 (match_operand:SWI124 2 "nonimmediate_operand" "<r>m")] 17817 UNSPEC_CRC32))] 17818 "TARGET_SSE4_2 || TARGET_CRC32" 17819 "crc32{<imodesuffix>}\t{%2, %0|%0, %2}" 17820 [(set_attr "type" "sselog1") 17821 (set_attr "prefix_rep" "1") 17822 (set_attr "prefix_extra" "1") 17823 (set (attr "prefix_data16") 17824 (if_then_else (match_operand:HI 2 "" "") 17825 (const_string "1") 17826 (const_string "*"))) 17827 (set (attr "prefix_rex") 17828 (if_then_else (match_operand:QI 2 "ext_QIreg_operand" "") 17829 (const_string "1") 17830 (const_string "*"))) 17831 (set_attr "mode" "SI")]) 17832 17833(define_insn "sse4_2_crc32di" 17834 [(set (match_operand:DI 0 "register_operand" "=r") 17835 (unspec:DI 17836 [(match_operand:DI 1 "register_operand" "0") 17837 (match_operand:DI 2 "nonimmediate_operand" "rm")] 17838 UNSPEC_CRC32))] 17839 "TARGET_64BIT && (TARGET_SSE4_2 || TARGET_CRC32)" 17840 "crc32{q}\t{%2, %0|%0, %2}" 17841 [(set_attr "type" "sselog1") 17842 (set_attr "prefix_rep" "1") 17843 (set_attr "prefix_extra" "1") 17844 (set_attr "mode" "DI")]) 17845 17846(define_expand "rdpmc" 17847 [(match_operand:DI 0 "register_operand" "") 17848 (match_operand:SI 1 "register_operand" "")] 17849 "" 17850{ 17851 rtx reg = gen_reg_rtx (DImode); 17852 rtx si; 17853 17854 /* Force operand 1 into ECX. */ 17855 rtx ecx = gen_rtx_REG (SImode, CX_REG); 17856 emit_insn (gen_rtx_SET (VOIDmode, ecx, operands[1])); 17857 si = gen_rtx_UNSPEC_VOLATILE (DImode, gen_rtvec (1, ecx), 17858 UNSPECV_RDPMC); 17859 17860 if (TARGET_64BIT) 17861 { 17862 rtvec vec = rtvec_alloc (2); 17863 rtx load = gen_rtx_PARALLEL (VOIDmode, vec); 17864 rtx upper = gen_reg_rtx (DImode); 17865 rtx di = gen_rtx_UNSPEC_VOLATILE (DImode, 17866 gen_rtvec (1, const0_rtx), 17867 UNSPECV_RDPMC); 17868 RTVEC_ELT (vec, 0) = gen_rtx_SET (VOIDmode, reg, si); 17869 RTVEC_ELT (vec, 1) = gen_rtx_SET (VOIDmode, upper, di); 17870 emit_insn (load); 17871 upper = expand_simple_binop (DImode, ASHIFT, upper, GEN_INT (32), 17872 NULL, 1, OPTAB_DIRECT); 17873 reg = expand_simple_binop (DImode, IOR, reg, upper, reg, 1, 17874 OPTAB_DIRECT); 17875 } 17876 else 17877 emit_insn (gen_rtx_SET (VOIDmode, reg, si)); 17878 emit_insn (gen_rtx_SET (VOIDmode, operands[0], reg)); 17879 DONE; 17880}) 17881 17882(define_insn "*rdpmc" 17883 [(set (match_operand:DI 0 "register_operand" "=A") 17884 (unspec_volatile:DI [(match_operand:SI 1 "register_operand" "c")] 17885 UNSPECV_RDPMC))] 17886 "!TARGET_64BIT" 17887 "rdpmc" 17888 [(set_attr "type" "other") 17889 (set_attr "length" "2")]) 17890 17891(define_insn "*rdpmc_rex64" 17892 [(set (match_operand:DI 0 "register_operand" "=a") 17893 (unspec_volatile:DI [(match_operand:SI 2 "register_operand" "c")] 17894 UNSPECV_RDPMC)) 17895 (set (match_operand:DI 1 "register_operand" "=d") 17896 (unspec_volatile:DI [(const_int 0)] UNSPECV_RDPMC))] 17897 "TARGET_64BIT" 17898 "rdpmc" 17899 [(set_attr "type" "other") 17900 (set_attr "length" "2")]) 17901 17902(define_expand "rdtsc" 17903 [(set (match_operand:DI 0 "register_operand" "") 17904 (unspec_volatile:DI [(const_int 0)] UNSPECV_RDTSC))] 17905 "" 17906{ 17907 if (TARGET_64BIT) 17908 { 17909 rtvec vec = rtvec_alloc (2); 17910 rtx load = gen_rtx_PARALLEL (VOIDmode, vec); 17911 rtx upper = gen_reg_rtx (DImode); 17912 rtx lower = gen_reg_rtx (DImode); 17913 rtx src = gen_rtx_UNSPEC_VOLATILE (DImode, 17914 gen_rtvec (1, const0_rtx), 17915 UNSPECV_RDTSC); 17916 RTVEC_ELT (vec, 0) = gen_rtx_SET (VOIDmode, lower, src); 17917 RTVEC_ELT (vec, 1) = gen_rtx_SET (VOIDmode, upper, src); 17918 emit_insn (load); 17919 upper = expand_simple_binop (DImode, ASHIFT, upper, GEN_INT (32), 17920 NULL, 1, OPTAB_DIRECT); 17921 lower = expand_simple_binop (DImode, IOR, lower, upper, lower, 1, 17922 OPTAB_DIRECT); 17923 emit_insn (gen_rtx_SET (VOIDmode, operands[0], lower)); 17924 DONE; 17925 } 17926}) 17927 17928(define_insn "*rdtsc" 17929 [(set (match_operand:DI 0 "register_operand" "=A") 17930 (unspec_volatile:DI [(const_int 0)] UNSPECV_RDTSC))] 17931 "!TARGET_64BIT" 17932 "rdtsc" 17933 [(set_attr "type" "other") 17934 (set_attr "length" "2")]) 17935 17936(define_insn "*rdtsc_rex64" 17937 [(set (match_operand:DI 0 "register_operand" "=a") 17938 (unspec_volatile:DI [(const_int 0)] UNSPECV_RDTSC)) 17939 (set (match_operand:DI 1 "register_operand" "=d") 17940 (unspec_volatile:DI [(const_int 0)] UNSPECV_RDTSC))] 17941 "TARGET_64BIT" 17942 "rdtsc" 17943 [(set_attr "type" "other") 17944 (set_attr "length" "2")]) 17945 17946(define_expand "rdtscp" 17947 [(match_operand:DI 0 "register_operand" "") 17948 (match_operand:SI 1 "memory_operand" "")] 17949 "" 17950{ 17951 rtx di = gen_rtx_UNSPEC_VOLATILE (DImode, 17952 gen_rtvec (1, const0_rtx), 17953 UNSPECV_RDTSCP); 17954 rtx si = gen_rtx_UNSPEC_VOLATILE (SImode, 17955 gen_rtvec (1, const0_rtx), 17956 UNSPECV_RDTSCP); 17957 rtx reg = gen_reg_rtx (DImode); 17958 rtx tmp = gen_reg_rtx (SImode); 17959 17960 if (TARGET_64BIT) 17961 { 17962 rtvec vec = rtvec_alloc (3); 17963 rtx load = gen_rtx_PARALLEL (VOIDmode, vec); 17964 rtx upper = gen_reg_rtx (DImode); 17965 RTVEC_ELT (vec, 0) = gen_rtx_SET (VOIDmode, reg, di); 17966 RTVEC_ELT (vec, 1) = gen_rtx_SET (VOIDmode, upper, di); 17967 RTVEC_ELT (vec, 2) = gen_rtx_SET (VOIDmode, tmp, si); 17968 emit_insn (load); 17969 upper = expand_simple_binop (DImode, ASHIFT, upper, GEN_INT (32), 17970 NULL, 1, OPTAB_DIRECT); 17971 reg = expand_simple_binop (DImode, IOR, reg, upper, reg, 1, 17972 OPTAB_DIRECT); 17973 } 17974 else 17975 { 17976 rtvec vec = rtvec_alloc (2); 17977 rtx load = gen_rtx_PARALLEL (VOIDmode, vec); 17978 RTVEC_ELT (vec, 0) = gen_rtx_SET (VOIDmode, reg, di); 17979 RTVEC_ELT (vec, 1) = gen_rtx_SET (VOIDmode, tmp, si); 17980 emit_insn (load); 17981 } 17982 emit_insn (gen_rtx_SET (VOIDmode, operands[0], reg)); 17983 emit_insn (gen_rtx_SET (VOIDmode, operands[1], tmp)); 17984 DONE; 17985}) 17986 17987(define_insn "*rdtscp" 17988 [(set (match_operand:DI 0 "register_operand" "=A") 17989 (unspec_volatile:DI [(const_int 0)] UNSPECV_RDTSCP)) 17990 (set (match_operand:SI 1 "register_operand" "=c") 17991 (unspec_volatile:SI [(const_int 0)] UNSPECV_RDTSCP))] 17992 "!TARGET_64BIT" 17993 "rdtscp" 17994 [(set_attr "type" "other") 17995 (set_attr "length" "3")]) 17996 17997(define_insn "*rdtscp_rex64" 17998 [(set (match_operand:DI 0 "register_operand" "=a") 17999 (unspec_volatile:DI [(const_int 0)] UNSPECV_RDTSCP)) 18000 (set (match_operand:DI 1 "register_operand" "=d") 18001 (unspec_volatile:DI [(const_int 0)] UNSPECV_RDTSCP)) 18002 (set (match_operand:SI 2 "register_operand" "=c") 18003 (unspec_volatile:SI [(const_int 0)] UNSPECV_RDTSCP))] 18004 "TARGET_64BIT" 18005 "rdtscp" 18006 [(set_attr "type" "other") 18007 (set_attr "length" "3")]) 18008 18009;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; 18010;; 18011;; LWP instructions 18012;; 18013;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; 18014 18015(define_expand "lwp_llwpcb" 18016 [(unspec_volatile [(match_operand 0 "register_operand" "r")] 18017 UNSPECV_LLWP_INTRINSIC)] 18018 "TARGET_LWP") 18019 18020(define_insn "*lwp_llwpcb<mode>1" 18021 [(unspec_volatile [(match_operand:P 0 "register_operand" "r")] 18022 UNSPECV_LLWP_INTRINSIC)] 18023 "TARGET_LWP" 18024 "llwpcb\t%0" 18025 [(set_attr "type" "lwp") 18026 (set_attr "mode" "<MODE>") 18027 (set_attr "length" "5")]) 18028 18029(define_expand "lwp_slwpcb" 18030 [(set (match_operand 0 "register_operand" "=r") 18031 (unspec_volatile [(const_int 0)] UNSPECV_SLWP_INTRINSIC))] 18032 "TARGET_LWP" 18033{ 18034 rtx (*insn)(rtx); 18035 18036 insn = (TARGET_64BIT 18037 ? gen_lwp_slwpcbdi 18038 : gen_lwp_slwpcbsi); 18039 18040 emit_insn (insn (operands[0])); 18041 DONE; 18042}) 18043 18044(define_insn "lwp_slwpcb<mode>" 18045 [(set (match_operand:P 0 "register_operand" "=r") 18046 (unspec_volatile:P [(const_int 0)] UNSPECV_SLWP_INTRINSIC))] 18047 "TARGET_LWP" 18048 "slwpcb\t%0" 18049 [(set_attr "type" "lwp") 18050 (set_attr "mode" "<MODE>") 18051 (set_attr "length" "5")]) 18052 18053(define_expand "lwp_lwpval<mode>3" 18054 [(unspec_volatile [(match_operand:SWI48 1 "register_operand" "r") 18055 (match_operand:SI 2 "nonimmediate_operand" "rm") 18056 (match_operand:SI 3 "const_int_operand" "i")] 18057 UNSPECV_LWPVAL_INTRINSIC)] 18058 "TARGET_LWP" 18059 ;; Avoid unused variable warning. 18060 "(void) operands[0];") 18061 18062(define_insn "*lwp_lwpval<mode>3_1" 18063 [(unspec_volatile [(match_operand:SWI48 0 "register_operand" "r") 18064 (match_operand:SI 1 "nonimmediate_operand" "rm") 18065 (match_operand:SI 2 "const_int_operand" "i")] 18066 UNSPECV_LWPVAL_INTRINSIC)] 18067 "TARGET_LWP" 18068 "lwpval\t{%2, %1, %0|%0, %1, %2}" 18069 [(set_attr "type" "lwp") 18070 (set_attr "mode" "<MODE>") 18071 (set (attr "length") 18072 (symbol_ref "ix86_attr_length_address_default (insn) + 9"))]) 18073 18074(define_expand "lwp_lwpins<mode>3" 18075 [(set (reg:CCC FLAGS_REG) 18076 (unspec_volatile:CCC [(match_operand:SWI48 1 "register_operand" "r") 18077 (match_operand:SI 2 "nonimmediate_operand" "rm") 18078 (match_operand:SI 3 "const_int_operand" "i")] 18079 UNSPECV_LWPINS_INTRINSIC)) 18080 (set (match_operand:QI 0 "nonimmediate_operand" "=qm") 18081 (eq:QI (reg:CCC FLAGS_REG) (const_int 0)))] 18082 "TARGET_LWP") 18083 18084(define_insn "*lwp_lwpins<mode>3_1" 18085 [(set (reg:CCC FLAGS_REG) 18086 (unspec_volatile:CCC [(match_operand:SWI48 0 "register_operand" "r") 18087 (match_operand:SI 1 "nonimmediate_operand" "rm") 18088 (match_operand:SI 2 "const_int_operand" "i")] 18089 UNSPECV_LWPINS_INTRINSIC))] 18090 "TARGET_LWP" 18091 "lwpins\t{%2, %1, %0|%0, %1, %2}" 18092 [(set_attr "type" "lwp") 18093 (set_attr "mode" "<MODE>") 18094 (set (attr "length") 18095 (symbol_ref "ix86_attr_length_address_default (insn) + 9"))]) 18096 18097(define_insn "rdfsbase<mode>" 18098 [(set (match_operand:SWI48 0 "register_operand" "=r") 18099 (unspec_volatile:SWI48 [(const_int 0)] UNSPECV_RDFSBASE))] 18100 "TARGET_64BIT && TARGET_FSGSBASE" 18101 "rdfsbase %0" 18102 [(set_attr "type" "other") 18103 (set_attr "prefix_extra" "2")]) 18104 18105(define_insn "rdgsbase<mode>" 18106 [(set (match_operand:SWI48 0 "register_operand" "=r") 18107 (unspec_volatile:SWI48 [(const_int 0)] UNSPECV_RDGSBASE))] 18108 "TARGET_64BIT && TARGET_FSGSBASE" 18109 "rdgsbase %0" 18110 [(set_attr "type" "other") 18111 (set_attr "prefix_extra" "2")]) 18112 18113(define_insn "wrfsbase<mode>" 18114 [(unspec_volatile [(match_operand:SWI48 0 "register_operand" "r")] 18115 UNSPECV_WRFSBASE)] 18116 "TARGET_64BIT && TARGET_FSGSBASE" 18117 "wrfsbase %0" 18118 [(set_attr "type" "other") 18119 (set_attr "prefix_extra" "2")]) 18120 18121(define_insn "wrgsbase<mode>" 18122 [(unspec_volatile [(match_operand:SWI48 0 "register_operand" "r")] 18123 UNSPECV_WRGSBASE)] 18124 "TARGET_64BIT && TARGET_FSGSBASE" 18125 "wrgsbase %0" 18126 [(set_attr "type" "other") 18127 (set_attr "prefix_extra" "2")]) 18128 18129(define_insn "rdrand<mode>_1" 18130 [(set (match_operand:SWI248 0 "register_operand" "=r") 18131 (unspec_volatile:SWI248 [(const_int 0)] UNSPECV_RDRAND)) 18132 (set (reg:CCC FLAGS_REG) 18133 (unspec_volatile:CCC [(const_int 0)] UNSPECV_RDRAND))] 18134 "TARGET_RDRND" 18135 "rdrand\t%0" 18136 [(set_attr "type" "other") 18137 (set_attr "prefix_extra" "1")]) 18138 18139(define_expand "pause" 18140 [(set (match_dup 0) 18141 (unspec:BLK [(match_dup 0)] UNSPEC_PAUSE))] 18142 "" 18143{ 18144 operands[0] = gen_rtx_MEM (BLKmode, gen_rtx_SCRATCH (Pmode)); 18145 MEM_VOLATILE_P (operands[0]) = 1; 18146}) 18147 18148;; Use "rep; nop", instead of "pause", to support older assemblers. 18149;; They have the same encoding. 18150(define_insn "*pause" 18151 [(set (match_operand:BLK 0 "" "") 18152 (unspec:BLK [(match_dup 0)] UNSPEC_PAUSE))] 18153 "" 18154 "rep; nop" 18155 [(set_attr "length" "2") 18156 (set_attr "memory" "unknown")]) 18157 18158(include "mmx.md") 18159(include "sse.md") 18160(include "sync.md") 18161