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,fma,fma4" 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" "fma") (symbol_ref "TARGET_FMA") 647 ;; Fma instruction selection has to be done based on 648 ;; register pressure. For generating fma4, a cost model 649 ;; based on register pressure is required. Till then, 650 ;; fma4 instruction is disabled for targets that implement 651 ;; both fma and fma4 instruction sets. 652 (eq_attr "isa" "fma4") 653 (symbol_ref "TARGET_FMA4 && !TARGET_FMA") 654 ] 655 (const_int 1))) 656 657;; Describe a user's asm statement. 658(define_asm_attributes 659 [(set_attr "length" "128") 660 (set_attr "type" "multi")]) 661 662(define_code_iterator plusminus [plus minus]) 663 664(define_code_iterator sat_plusminus [ss_plus us_plus ss_minus us_minus]) 665 666;; Base name for define_insn 667(define_code_attr plusminus_insn 668 [(plus "add") (ss_plus "ssadd") (us_plus "usadd") 669 (minus "sub") (ss_minus "sssub") (us_minus "ussub")]) 670 671;; Base name for insn mnemonic. 672(define_code_attr plusminus_mnemonic 673 [(plus "add") (ss_plus "adds") (us_plus "addus") 674 (minus "sub") (ss_minus "subs") (us_minus "subus")]) 675(define_code_attr plusminus_carry_mnemonic 676 [(plus "adc") (minus "sbb")]) 677 678;; Mark commutative operators as such in constraints. 679(define_code_attr comm [(plus "%") (ss_plus "%") (us_plus "%") 680 (minus "") (ss_minus "") (us_minus "")]) 681 682;; Mapping of max and min 683(define_code_iterator maxmin [smax smin umax umin]) 684 685;; Mapping of signed max and min 686(define_code_iterator smaxmin [smax smin]) 687 688;; Mapping of unsigned max and min 689(define_code_iterator umaxmin [umax umin]) 690 691;; Base name for integer and FP insn mnemonic 692(define_code_attr maxmin_int [(smax "maxs") (smin "mins") 693 (umax "maxu") (umin "minu")]) 694(define_code_attr maxmin_float [(smax "max") (smin "min")]) 695 696;; Mapping of logic operators 697(define_code_iterator any_logic [and ior xor]) 698(define_code_iterator any_or [ior xor]) 699 700;; Base name for insn mnemonic. 701(define_code_attr logic [(and "and") (ior "or") (xor "xor")]) 702 703;; Mapping of logic-shift operators 704(define_code_iterator any_lshift [ashift lshiftrt]) 705 706;; Mapping of shift-right operators 707(define_code_iterator any_shiftrt [lshiftrt ashiftrt]) 708 709;; Base name for define_insn 710(define_code_attr shift_insn 711 [(ashift "ashl") (lshiftrt "lshr") (ashiftrt "ashr")]) 712 713;; Base name for insn mnemonic. 714(define_code_attr shift [(ashift "sll") (lshiftrt "shr") (ashiftrt "sar")]) 715(define_code_attr vshift [(ashift "sll") (lshiftrt "srl") (ashiftrt "sra")]) 716 717;; Mapping of rotate operators 718(define_code_iterator any_rotate [rotate rotatert]) 719 720;; Base name for define_insn 721(define_code_attr rotate_insn [(rotate "rotl") (rotatert "rotr")]) 722 723;; Base name for insn mnemonic. 724(define_code_attr rotate [(rotate "rol") (rotatert "ror")]) 725 726;; Mapping of abs neg operators 727(define_code_iterator absneg [abs neg]) 728 729;; Base name for x87 insn mnemonic. 730(define_code_attr absneg_mnemonic [(abs "abs") (neg "chs")]) 731 732;; Used in signed and unsigned widening multiplications. 733(define_code_iterator any_extend [sign_extend zero_extend]) 734 735;; Prefix for insn menmonic. 736(define_code_attr sgnprefix [(sign_extend "i") (zero_extend "")]) 737 738;; Prefix for define_insn 739(define_code_attr u [(sign_extend "") (zero_extend "u")]) 740(define_code_attr s [(sign_extend "s") (zero_extend "u")]) 741 742;; All integer modes. 743(define_mode_iterator SWI1248x [QI HI SI DI]) 744 745;; All integer modes without QImode. 746(define_mode_iterator SWI248x [HI SI DI]) 747 748;; All integer modes without QImode and HImode. 749(define_mode_iterator SWI48x [SI DI]) 750 751;; All integer modes without SImode and DImode. 752(define_mode_iterator SWI12 [QI HI]) 753 754;; All integer modes without DImode. 755(define_mode_iterator SWI124 [QI HI SI]) 756 757;; All integer modes without QImode and DImode. 758(define_mode_iterator SWI24 [HI SI]) 759 760;; Single word integer modes. 761(define_mode_iterator SWI [QI HI SI (DI "TARGET_64BIT")]) 762 763;; Single word integer modes without QImode. 764(define_mode_iterator SWI248 [HI SI (DI "TARGET_64BIT")]) 765 766;; Single word integer modes without QImode and HImode. 767(define_mode_iterator SWI48 [SI (DI "TARGET_64BIT")]) 768 769;; All math-dependant single and double word integer modes. 770(define_mode_iterator SDWIM [(QI "TARGET_QIMODE_MATH") 771 (HI "TARGET_HIMODE_MATH") 772 SI DI (TI "TARGET_64BIT")]) 773 774;; Math-dependant single word integer modes. 775(define_mode_iterator SWIM [(QI "TARGET_QIMODE_MATH") 776 (HI "TARGET_HIMODE_MATH") 777 SI (DI "TARGET_64BIT")]) 778 779;; Math-dependant integer modes without DImode. 780(define_mode_iterator SWIM124 [(QI "TARGET_QIMODE_MATH") 781 (HI "TARGET_HIMODE_MATH") 782 SI]) 783 784;; Math-dependant single word integer modes without QImode. 785(define_mode_iterator SWIM248 [(HI "TARGET_HIMODE_MATH") 786 SI (DI "TARGET_64BIT")]) 787 788;; Double word integer modes. 789(define_mode_iterator DWI [(DI "!TARGET_64BIT") 790 (TI "TARGET_64BIT")]) 791 792;; Double word integer modes as mode attribute. 793(define_mode_attr DWI [(SI "DI") (DI "TI")]) 794(define_mode_attr dwi [(SI "di") (DI "ti")]) 795 796;; Half mode for double word integer modes. 797(define_mode_iterator DWIH [(SI "!TARGET_64BIT") 798 (DI "TARGET_64BIT")]) 799 800;; Instruction suffix for integer modes. 801(define_mode_attr imodesuffix [(QI "b") (HI "w") (SI "l") (DI "q")]) 802 803;; Pointer size prefix for integer modes (Intel asm dialect) 804(define_mode_attr iptrsize [(QI "BYTE") 805 (HI "WORD") 806 (SI "DWORD") 807 (DI "QWORD")]) 808 809;; Register class for integer modes. 810(define_mode_attr r [(QI "q") (HI "r") (SI "r") (DI "r")]) 811 812;; Immediate operand constraint for integer modes. 813(define_mode_attr i [(QI "n") (HI "n") (SI "e") (DI "e")]) 814 815;; General operand constraint for word modes. 816(define_mode_attr g [(QI "qmn") (HI "rmn") (SI "rme") (DI "rme")]) 817 818;; Immediate operand constraint for double integer modes. 819(define_mode_attr di [(SI "nF") (DI "e")]) 820 821;; Immediate operand constraint for shifts. 822(define_mode_attr S [(QI "I") (HI "I") (SI "I") (DI "J") (TI "O")]) 823 824;; General operand predicate for integer modes. 825(define_mode_attr general_operand 826 [(QI "general_operand") 827 (HI "general_operand") 828 (SI "x86_64_general_operand") 829 (DI "x86_64_general_operand") 830 (TI "x86_64_general_operand")]) 831 832;; General sign/zero extend operand predicate for integer modes. 833(define_mode_attr general_szext_operand 834 [(QI "general_operand") 835 (HI "general_operand") 836 (SI "x86_64_szext_general_operand") 837 (DI "x86_64_szext_general_operand")]) 838 839;; Immediate operand predicate for integer modes. 840(define_mode_attr immediate_operand 841 [(QI "immediate_operand") 842 (HI "immediate_operand") 843 (SI "x86_64_immediate_operand") 844 (DI "x86_64_immediate_operand")]) 845 846;; Nonmemory operand predicate for integer modes. 847(define_mode_attr nonmemory_operand 848 [(QI "nonmemory_operand") 849 (HI "nonmemory_operand") 850 (SI "x86_64_nonmemory_operand") 851 (DI "x86_64_nonmemory_operand")]) 852 853;; Operand predicate for shifts. 854(define_mode_attr shift_operand 855 [(QI "nonimmediate_operand") 856 (HI "nonimmediate_operand") 857 (SI "nonimmediate_operand") 858 (DI "shiftdi_operand") 859 (TI "register_operand")]) 860 861;; Operand predicate for shift argument. 862(define_mode_attr shift_immediate_operand 863 [(QI "const_1_to_31_operand") 864 (HI "const_1_to_31_operand") 865 (SI "const_1_to_31_operand") 866 (DI "const_1_to_63_operand")]) 867 868;; Input operand predicate for arithmetic left shifts. 869(define_mode_attr ashl_input_operand 870 [(QI "nonimmediate_operand") 871 (HI "nonimmediate_operand") 872 (SI "nonimmediate_operand") 873 (DI "ashldi_input_operand") 874 (TI "reg_or_pm1_operand")]) 875 876;; SSE and x87 SFmode and DFmode floating point modes 877(define_mode_iterator MODEF [SF DF]) 878 879;; All x87 floating point modes 880(define_mode_iterator X87MODEF [SF DF XF]) 881 882;; SSE instruction suffix for various modes 883(define_mode_attr ssemodesuffix 884 [(SF "ss") (DF "sd") 885 (V8SF "ps") (V4DF "pd") 886 (V4SF "ps") (V2DF "pd") 887 (V16QI "b") (V8HI "w") (V4SI "d") (V2DI "q") 888 (V32QI "b") (V16HI "w") (V8SI "d") (V4DI "q")]) 889 890;; SSE vector suffix for floating point modes 891(define_mode_attr ssevecmodesuffix [(SF "ps") (DF "pd")]) 892 893;; SSE vector mode corresponding to a scalar mode 894(define_mode_attr ssevecmode 895 [(QI "V16QI") (HI "V8HI") (SI "V4SI") (DI "V2DI") (SF "V4SF") (DF "V2DF")]) 896 897;; Instruction suffix for REX 64bit operators. 898(define_mode_attr rex64suffix [(SI "") (DI "{q}")]) 899 900;; This mode iterator allows :P to be used for patterns that operate on 901;; pointer-sized quantities. Exactly one of the two alternatives will match. 902(define_mode_iterator P [(SI "Pmode == SImode") (DI "Pmode == DImode")]) 903 904;; This mode iterator allows :PTR to be used for patterns that operate on 905;; ptr_mode sized quantities. 906(define_mode_iterator PTR 907 [(SI "ptr_mode == SImode") (DI "ptr_mode == DImode")]) 908 909;; Scheduling descriptions 910 911(include "pentium.md") 912(include "ppro.md") 913(include "k6.md") 914(include "athlon.md") 915(include "bdver1.md") 916(include "geode.md") 917(include "atom.md") 918(include "core2.md") 919 920 921;; Operand and operator predicates and constraints 922 923(include "predicates.md") 924(include "constraints.md") 925 926 927;; Compare and branch/compare and store instructions. 928 929(define_expand "cbranch<mode>4" 930 [(set (reg:CC FLAGS_REG) 931 (compare:CC (match_operand:SDWIM 1 "nonimmediate_operand" "") 932 (match_operand:SDWIM 2 "<general_operand>" ""))) 933 (set (pc) (if_then_else 934 (match_operator 0 "ordered_comparison_operator" 935 [(reg:CC FLAGS_REG) (const_int 0)]) 936 (label_ref (match_operand 3 "" "")) 937 (pc)))] 938 "" 939{ 940 if (MEM_P (operands[1]) && MEM_P (operands[2])) 941 operands[1] = force_reg (<MODE>mode, operands[1]); 942 ix86_expand_branch (GET_CODE (operands[0]), 943 operands[1], operands[2], operands[3]); 944 DONE; 945}) 946 947(define_expand "cstore<mode>4" 948 [(set (reg:CC FLAGS_REG) 949 (compare:CC (match_operand:SWIM 2 "nonimmediate_operand" "") 950 (match_operand:SWIM 3 "<general_operand>" ""))) 951 (set (match_operand:QI 0 "register_operand" "") 952 (match_operator 1 "ordered_comparison_operator" 953 [(reg:CC FLAGS_REG) (const_int 0)]))] 954 "" 955{ 956 if (MEM_P (operands[2]) && MEM_P (operands[3])) 957 operands[2] = force_reg (<MODE>mode, operands[2]); 958 ix86_expand_setcc (operands[0], GET_CODE (operands[1]), 959 operands[2], operands[3]); 960 DONE; 961}) 962 963(define_expand "cmp<mode>_1" 964 [(set (reg:CC FLAGS_REG) 965 (compare:CC (match_operand:SWI48 0 "nonimmediate_operand" "") 966 (match_operand:SWI48 1 "<general_operand>" "")))]) 967 968(define_insn "*cmp<mode>_ccno_1" 969 [(set (reg FLAGS_REG) 970 (compare (match_operand:SWI 0 "nonimmediate_operand" "<r>,?m<r>") 971 (match_operand:SWI 1 "const0_operand" "")))] 972 "ix86_match_ccmode (insn, CCNOmode)" 973 "@ 974 test{<imodesuffix>}\t%0, %0 975 cmp{<imodesuffix>}\t{%1, %0|%0, %1}" 976 [(set_attr "type" "test,icmp") 977 (set_attr "length_immediate" "0,1") 978 (set_attr "mode" "<MODE>")]) 979 980(define_insn "*cmp<mode>_1" 981 [(set (reg FLAGS_REG) 982 (compare (match_operand:SWI 0 "nonimmediate_operand" "<r>m,<r>") 983 (match_operand:SWI 1 "<general_operand>" "<r><i>,<r>m")))] 984 "ix86_match_ccmode (insn, CCmode)" 985 "cmp{<imodesuffix>}\t{%1, %0|%0, %1}" 986 [(set_attr "type" "icmp") 987 (set_attr "mode" "<MODE>")]) 988 989(define_insn "*cmp<mode>_minus_1" 990 [(set (reg FLAGS_REG) 991 (compare 992 (minus:SWI (match_operand:SWI 0 "nonimmediate_operand" "<r>m,<r>") 993 (match_operand:SWI 1 "<general_operand>" "<r><i>,<r>m")) 994 (const_int 0)))] 995 "ix86_match_ccmode (insn, CCGOCmode)" 996 "cmp{<imodesuffix>}\t{%1, %0|%0, %1}" 997 [(set_attr "type" "icmp") 998 (set_attr "mode" "<MODE>")]) 999 1000(define_insn "*cmpqi_ext_1" 1001 [(set (reg FLAGS_REG) 1002 (compare 1003 (match_operand:QI 0 "general_operand" "Qm") 1004 (subreg:QI 1005 (zero_extract:SI 1006 (match_operand 1 "ext_register_operand" "Q") 1007 (const_int 8) 1008 (const_int 8)) 0)))] 1009 "!TARGET_64BIT && ix86_match_ccmode (insn, CCmode)" 1010 "cmp{b}\t{%h1, %0|%0, %h1}" 1011 [(set_attr "type" "icmp") 1012 (set_attr "mode" "QI")]) 1013 1014(define_insn "*cmpqi_ext_1_rex64" 1015 [(set (reg FLAGS_REG) 1016 (compare 1017 (match_operand:QI 0 "register_operand" "Q") 1018 (subreg:QI 1019 (zero_extract:SI 1020 (match_operand 1 "ext_register_operand" "Q") 1021 (const_int 8) 1022 (const_int 8)) 0)))] 1023 "TARGET_64BIT && ix86_match_ccmode (insn, CCmode)" 1024 "cmp{b}\t{%h1, %0|%0, %h1}" 1025 [(set_attr "type" "icmp") 1026 (set_attr "mode" "QI")]) 1027 1028(define_insn "*cmpqi_ext_2" 1029 [(set (reg FLAGS_REG) 1030 (compare 1031 (subreg:QI 1032 (zero_extract:SI 1033 (match_operand 0 "ext_register_operand" "Q") 1034 (const_int 8) 1035 (const_int 8)) 0) 1036 (match_operand:QI 1 "const0_operand" "")))] 1037 "ix86_match_ccmode (insn, CCNOmode)" 1038 "test{b}\t%h0, %h0" 1039 [(set_attr "type" "test") 1040 (set_attr "length_immediate" "0") 1041 (set_attr "mode" "QI")]) 1042 1043(define_expand "cmpqi_ext_3" 1044 [(set (reg:CC FLAGS_REG) 1045 (compare:CC 1046 (subreg:QI 1047 (zero_extract:SI 1048 (match_operand 0 "ext_register_operand" "") 1049 (const_int 8) 1050 (const_int 8)) 0) 1051 (match_operand:QI 1 "immediate_operand" "")))]) 1052 1053(define_insn "*cmpqi_ext_3_insn" 1054 [(set (reg FLAGS_REG) 1055 (compare 1056 (subreg:QI 1057 (zero_extract:SI 1058 (match_operand 0 "ext_register_operand" "Q") 1059 (const_int 8) 1060 (const_int 8)) 0) 1061 (match_operand:QI 1 "general_operand" "Qmn")))] 1062 "!TARGET_64BIT && ix86_match_ccmode (insn, CCmode)" 1063 "cmp{b}\t{%1, %h0|%h0, %1}" 1064 [(set_attr "type" "icmp") 1065 (set_attr "modrm" "1") 1066 (set_attr "mode" "QI")]) 1067 1068(define_insn "*cmpqi_ext_3_insn_rex64" 1069 [(set (reg FLAGS_REG) 1070 (compare 1071 (subreg:QI 1072 (zero_extract:SI 1073 (match_operand 0 "ext_register_operand" "Q") 1074 (const_int 8) 1075 (const_int 8)) 0) 1076 (match_operand:QI 1 "nonmemory_operand" "Qn")))] 1077 "TARGET_64BIT && ix86_match_ccmode (insn, CCmode)" 1078 "cmp{b}\t{%1, %h0|%h0, %1}" 1079 [(set_attr "type" "icmp") 1080 (set_attr "modrm" "1") 1081 (set_attr "mode" "QI")]) 1082 1083(define_insn "*cmpqi_ext_4" 1084 [(set (reg FLAGS_REG) 1085 (compare 1086 (subreg:QI 1087 (zero_extract:SI 1088 (match_operand 0 "ext_register_operand" "Q") 1089 (const_int 8) 1090 (const_int 8)) 0) 1091 (subreg:QI 1092 (zero_extract:SI 1093 (match_operand 1 "ext_register_operand" "Q") 1094 (const_int 8) 1095 (const_int 8)) 0)))] 1096 "ix86_match_ccmode (insn, CCmode)" 1097 "cmp{b}\t{%h1, %h0|%h0, %h1}" 1098 [(set_attr "type" "icmp") 1099 (set_attr "mode" "QI")]) 1100 1101;; These implement float point compares. 1102;; %%% See if we can get away with VOIDmode operands on the actual insns, 1103;; which would allow mix and match FP modes on the compares. Which is what 1104;; the old patterns did, but with many more of them. 1105 1106(define_expand "cbranchxf4" 1107 [(set (reg:CC FLAGS_REG) 1108 (compare:CC (match_operand:XF 1 "nonmemory_operand" "") 1109 (match_operand:XF 2 "nonmemory_operand" ""))) 1110 (set (pc) (if_then_else 1111 (match_operator 0 "ix86_fp_comparison_operator" 1112 [(reg:CC FLAGS_REG) 1113 (const_int 0)]) 1114 (label_ref (match_operand 3 "" "")) 1115 (pc)))] 1116 "TARGET_80387" 1117{ 1118 ix86_expand_branch (GET_CODE (operands[0]), 1119 operands[1], operands[2], operands[3]); 1120 DONE; 1121}) 1122 1123(define_expand "cstorexf4" 1124 [(set (reg:CC FLAGS_REG) 1125 (compare:CC (match_operand:XF 2 "nonmemory_operand" "") 1126 (match_operand:XF 3 "nonmemory_operand" ""))) 1127 (set (match_operand:QI 0 "register_operand" "") 1128 (match_operator 1 "ix86_fp_comparison_operator" 1129 [(reg:CC FLAGS_REG) 1130 (const_int 0)]))] 1131 "TARGET_80387" 1132{ 1133 ix86_expand_setcc (operands[0], GET_CODE (operands[1]), 1134 operands[2], operands[3]); 1135 DONE; 1136}) 1137 1138(define_expand "cbranch<mode>4" 1139 [(set (reg:CC FLAGS_REG) 1140 (compare:CC (match_operand:MODEF 1 "cmp_fp_expander_operand" "") 1141 (match_operand:MODEF 2 "cmp_fp_expander_operand" ""))) 1142 (set (pc) (if_then_else 1143 (match_operator 0 "ix86_fp_comparison_operator" 1144 [(reg:CC FLAGS_REG) 1145 (const_int 0)]) 1146 (label_ref (match_operand 3 "" "")) 1147 (pc)))] 1148 "TARGET_80387 || (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)" 1149{ 1150 ix86_expand_branch (GET_CODE (operands[0]), 1151 operands[1], operands[2], operands[3]); 1152 DONE; 1153}) 1154 1155(define_expand "cstore<mode>4" 1156 [(set (reg:CC FLAGS_REG) 1157 (compare:CC (match_operand:MODEF 2 "cmp_fp_expander_operand" "") 1158 (match_operand:MODEF 3 "cmp_fp_expander_operand" ""))) 1159 (set (match_operand:QI 0 "register_operand" "") 1160 (match_operator 1 "ix86_fp_comparison_operator" 1161 [(reg:CC FLAGS_REG) 1162 (const_int 0)]))] 1163 "TARGET_80387 || (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)" 1164{ 1165 ix86_expand_setcc (operands[0], GET_CODE (operands[1]), 1166 operands[2], operands[3]); 1167 DONE; 1168}) 1169 1170(define_expand "cbranchcc4" 1171 [(set (pc) (if_then_else 1172 (match_operator 0 "comparison_operator" 1173 [(match_operand 1 "flags_reg_operand" "") 1174 (match_operand 2 "const0_operand" "")]) 1175 (label_ref (match_operand 3 "" "")) 1176 (pc)))] 1177 "" 1178{ 1179 ix86_expand_branch (GET_CODE (operands[0]), 1180 operands[1], operands[2], operands[3]); 1181 DONE; 1182}) 1183 1184(define_expand "cstorecc4" 1185 [(set (match_operand:QI 0 "register_operand" "") 1186 (match_operator 1 "comparison_operator" 1187 [(match_operand 2 "flags_reg_operand" "") 1188 (match_operand 3 "const0_operand" "")]))] 1189 "" 1190{ 1191 ix86_expand_setcc (operands[0], GET_CODE (operands[1]), 1192 operands[2], operands[3]); 1193 DONE; 1194}) 1195 1196 1197;; FP compares, step 1: 1198;; Set the FP condition codes. 1199;; 1200;; CCFPmode compare with exceptions 1201;; CCFPUmode compare with no exceptions 1202 1203;; We may not use "#" to split and emit these, since the REG_DEAD notes 1204;; used to manage the reg stack popping would not be preserved. 1205 1206(define_insn "*cmpfp_0" 1207 [(set (match_operand:HI 0 "register_operand" "=a") 1208 (unspec:HI 1209 [(compare:CCFP 1210 (match_operand 1 "register_operand" "f") 1211 (match_operand 2 "const0_operand" ""))] 1212 UNSPEC_FNSTSW))] 1213 "X87_FLOAT_MODE_P (GET_MODE (operands[1])) 1214 && GET_MODE (operands[1]) == GET_MODE (operands[2])" 1215 "* return output_fp_compare (insn, operands, false, false);" 1216 [(set_attr "type" "multi") 1217 (set_attr "unit" "i387") 1218 (set (attr "mode") 1219 (cond [(match_operand:SF 1 "" "") 1220 (const_string "SF") 1221 (match_operand:DF 1 "" "") 1222 (const_string "DF") 1223 ] 1224 (const_string "XF")))]) 1225 1226(define_insn_and_split "*cmpfp_0_cc" 1227 [(set (reg:CCFP FLAGS_REG) 1228 (compare:CCFP 1229 (match_operand 1 "register_operand" "f") 1230 (match_operand 2 "const0_operand" ""))) 1231 (clobber (match_operand:HI 0 "register_operand" "=a"))] 1232 "X87_FLOAT_MODE_P (GET_MODE (operands[1])) 1233 && TARGET_SAHF && !TARGET_CMOVE 1234 && GET_MODE (operands[1]) == GET_MODE (operands[2])" 1235 "#" 1236 "&& reload_completed" 1237 [(set (match_dup 0) 1238 (unspec:HI 1239 [(compare:CCFP (match_dup 1)(match_dup 2))] 1240 UNSPEC_FNSTSW)) 1241 (set (reg:CC FLAGS_REG) 1242 (unspec:CC [(match_dup 0)] UNSPEC_SAHF))] 1243 "" 1244 [(set_attr "type" "multi") 1245 (set_attr "unit" "i387") 1246 (set (attr "mode") 1247 (cond [(match_operand:SF 1 "" "") 1248 (const_string "SF") 1249 (match_operand:DF 1 "" "") 1250 (const_string "DF") 1251 ] 1252 (const_string "XF")))]) 1253 1254(define_insn "*cmpfp_xf" 1255 [(set (match_operand:HI 0 "register_operand" "=a") 1256 (unspec:HI 1257 [(compare:CCFP 1258 (match_operand:XF 1 "register_operand" "f") 1259 (match_operand:XF 2 "register_operand" "f"))] 1260 UNSPEC_FNSTSW))] 1261 "TARGET_80387" 1262 "* return output_fp_compare (insn, operands, false, false);" 1263 [(set_attr "type" "multi") 1264 (set_attr "unit" "i387") 1265 (set_attr "mode" "XF")]) 1266 1267(define_insn_and_split "*cmpfp_xf_cc" 1268 [(set (reg:CCFP FLAGS_REG) 1269 (compare:CCFP 1270 (match_operand:XF 1 "register_operand" "f") 1271 (match_operand:XF 2 "register_operand" "f"))) 1272 (clobber (match_operand:HI 0 "register_operand" "=a"))] 1273 "TARGET_80387 1274 && TARGET_SAHF && !TARGET_CMOVE" 1275 "#" 1276 "&& reload_completed" 1277 [(set (match_dup 0) 1278 (unspec:HI 1279 [(compare:CCFP (match_dup 1)(match_dup 2))] 1280 UNSPEC_FNSTSW)) 1281 (set (reg:CC FLAGS_REG) 1282 (unspec:CC [(match_dup 0)] UNSPEC_SAHF))] 1283 "" 1284 [(set_attr "type" "multi") 1285 (set_attr "unit" "i387") 1286 (set_attr "mode" "XF")]) 1287 1288(define_insn "*cmpfp_<mode>" 1289 [(set (match_operand:HI 0 "register_operand" "=a") 1290 (unspec:HI 1291 [(compare:CCFP 1292 (match_operand:MODEF 1 "register_operand" "f") 1293 (match_operand:MODEF 2 "nonimmediate_operand" "fm"))] 1294 UNSPEC_FNSTSW))] 1295 "TARGET_80387" 1296 "* return output_fp_compare (insn, operands, false, false);" 1297 [(set_attr "type" "multi") 1298 (set_attr "unit" "i387") 1299 (set_attr "mode" "<MODE>")]) 1300 1301(define_insn_and_split "*cmpfp_<mode>_cc" 1302 [(set (reg:CCFP FLAGS_REG) 1303 (compare:CCFP 1304 (match_operand:MODEF 1 "register_operand" "f") 1305 (match_operand:MODEF 2 "nonimmediate_operand" "fm"))) 1306 (clobber (match_operand:HI 0 "register_operand" "=a"))] 1307 "TARGET_80387 1308 && TARGET_SAHF && !TARGET_CMOVE" 1309 "#" 1310 "&& reload_completed" 1311 [(set (match_dup 0) 1312 (unspec:HI 1313 [(compare:CCFP (match_dup 1)(match_dup 2))] 1314 UNSPEC_FNSTSW)) 1315 (set (reg:CC FLAGS_REG) 1316 (unspec:CC [(match_dup 0)] UNSPEC_SAHF))] 1317 "" 1318 [(set_attr "type" "multi") 1319 (set_attr "unit" "i387") 1320 (set_attr "mode" "<MODE>")]) 1321 1322(define_insn "*cmpfp_u" 1323 [(set (match_operand:HI 0 "register_operand" "=a") 1324 (unspec:HI 1325 [(compare:CCFPU 1326 (match_operand 1 "register_operand" "f") 1327 (match_operand 2 "register_operand" "f"))] 1328 UNSPEC_FNSTSW))] 1329 "X87_FLOAT_MODE_P (GET_MODE (operands[1])) 1330 && GET_MODE (operands[1]) == GET_MODE (operands[2])" 1331 "* return output_fp_compare (insn, operands, false, true);" 1332 [(set_attr "type" "multi") 1333 (set_attr "unit" "i387") 1334 (set (attr "mode") 1335 (cond [(match_operand:SF 1 "" "") 1336 (const_string "SF") 1337 (match_operand:DF 1 "" "") 1338 (const_string "DF") 1339 ] 1340 (const_string "XF")))]) 1341 1342(define_insn_and_split "*cmpfp_u_cc" 1343 [(set (reg:CCFPU FLAGS_REG) 1344 (compare:CCFPU 1345 (match_operand 1 "register_operand" "f") 1346 (match_operand 2 "register_operand" "f"))) 1347 (clobber (match_operand:HI 0 "register_operand" "=a"))] 1348 "X87_FLOAT_MODE_P (GET_MODE (operands[1])) 1349 && TARGET_SAHF && !TARGET_CMOVE 1350 && GET_MODE (operands[1]) == GET_MODE (operands[2])" 1351 "#" 1352 "&& reload_completed" 1353 [(set (match_dup 0) 1354 (unspec:HI 1355 [(compare:CCFPU (match_dup 1)(match_dup 2))] 1356 UNSPEC_FNSTSW)) 1357 (set (reg:CC FLAGS_REG) 1358 (unspec:CC [(match_dup 0)] UNSPEC_SAHF))] 1359 "" 1360 [(set_attr "type" "multi") 1361 (set_attr "unit" "i387") 1362 (set (attr "mode") 1363 (cond [(match_operand:SF 1 "" "") 1364 (const_string "SF") 1365 (match_operand:DF 1 "" "") 1366 (const_string "DF") 1367 ] 1368 (const_string "XF")))]) 1369 1370(define_insn "*cmpfp_<mode>" 1371 [(set (match_operand:HI 0 "register_operand" "=a") 1372 (unspec:HI 1373 [(compare:CCFP 1374 (match_operand 1 "register_operand" "f") 1375 (match_operator 3 "float_operator" 1376 [(match_operand:SWI24 2 "memory_operand" "m")]))] 1377 UNSPEC_FNSTSW))] 1378 "X87_FLOAT_MODE_P (GET_MODE (operands[1])) 1379 && (TARGET_USE_<MODE>MODE_FIOP || optimize_function_for_size_p (cfun)) 1380 && (GET_MODE (operands [3]) == GET_MODE (operands[1]))" 1381 "* return output_fp_compare (insn, operands, false, false);" 1382 [(set_attr "type" "multi") 1383 (set_attr "unit" "i387") 1384 (set_attr "fp_int_src" "true") 1385 (set_attr "mode" "<MODE>")]) 1386 1387(define_insn_and_split "*cmpfp_<mode>_cc" 1388 [(set (reg:CCFP FLAGS_REG) 1389 (compare:CCFP 1390 (match_operand 1 "register_operand" "f") 1391 (match_operator 3 "float_operator" 1392 [(match_operand:SWI24 2 "memory_operand" "m")]))) 1393 (clobber (match_operand:HI 0 "register_operand" "=a"))] 1394 "X87_FLOAT_MODE_P (GET_MODE (operands[1])) 1395 && TARGET_SAHF && !TARGET_CMOVE 1396 && (TARGET_USE_<MODE>MODE_FIOP || optimize_function_for_size_p (cfun)) 1397 && (GET_MODE (operands [3]) == GET_MODE (operands[1]))" 1398 "#" 1399 "&& reload_completed" 1400 [(set (match_dup 0) 1401 (unspec:HI 1402 [(compare:CCFP 1403 (match_dup 1) 1404 (match_op_dup 3 [(match_dup 2)]))] 1405 UNSPEC_FNSTSW)) 1406 (set (reg:CC FLAGS_REG) 1407 (unspec:CC [(match_dup 0)] UNSPEC_SAHF))] 1408 "" 1409 [(set_attr "type" "multi") 1410 (set_attr "unit" "i387") 1411 (set_attr "fp_int_src" "true") 1412 (set_attr "mode" "<MODE>")]) 1413 1414;; FP compares, step 2 1415;; Move the fpsw to ax. 1416 1417(define_insn "x86_fnstsw_1" 1418 [(set (match_operand:HI 0 "register_operand" "=a") 1419 (unspec:HI [(reg:CCFP FPSR_REG)] UNSPEC_FNSTSW))] 1420 "TARGET_80387" 1421 "fnstsw\t%0" 1422 [(set (attr "length") 1423 (symbol_ref "ix86_attr_length_address_default (insn) + 2")) 1424 (set_attr "mode" "SI") 1425 (set_attr "unit" "i387")]) 1426 1427;; FP compares, step 3 1428;; Get ax into flags, general case. 1429 1430(define_insn "x86_sahf_1" 1431 [(set (reg:CC FLAGS_REG) 1432 (unspec:CC [(match_operand:HI 0 "register_operand" "a")] 1433 UNSPEC_SAHF))] 1434 "TARGET_SAHF" 1435{ 1436#ifndef HAVE_AS_IX86_SAHF 1437 if (TARGET_64BIT) 1438 return ASM_BYTE "0x9e"; 1439 else 1440#endif 1441 return "sahf"; 1442} 1443 [(set_attr "length" "1") 1444 (set_attr "athlon_decode" "vector") 1445 (set_attr "amdfam10_decode" "direct") 1446 (set_attr "bdver1_decode" "direct") 1447 (set_attr "mode" "SI")]) 1448 1449;; Pentium Pro can do steps 1 through 3 in one go. 1450;; comi*, ucomi*, fcomi*, ficomi*, fucomi* 1451;; (these i387 instructions set flags directly) 1452(define_insn "*cmpfp_i_mixed" 1453 [(set (reg:CCFP FLAGS_REG) 1454 (compare:CCFP (match_operand 0 "register_operand" "f,x") 1455 (match_operand 1 "nonimmediate_operand" "f,xm")))] 1456 "TARGET_MIX_SSE_I387 1457 && SSE_FLOAT_MODE_P (GET_MODE (operands[0])) 1458 && GET_MODE (operands[0]) == GET_MODE (operands[1])" 1459 "* return output_fp_compare (insn, operands, true, false);" 1460 [(set_attr "type" "fcmp,ssecomi") 1461 (set_attr "prefix" "orig,maybe_vex") 1462 (set (attr "mode") 1463 (if_then_else (match_operand:SF 1 "" "") 1464 (const_string "SF") 1465 (const_string "DF"))) 1466 (set (attr "prefix_rep") 1467 (if_then_else (eq_attr "type" "ssecomi") 1468 (const_string "0") 1469 (const_string "*"))) 1470 (set (attr "prefix_data16") 1471 (cond [(eq_attr "type" "fcmp") 1472 (const_string "*") 1473 (eq_attr "mode" "DF") 1474 (const_string "1") 1475 ] 1476 (const_string "0"))) 1477 (set_attr "athlon_decode" "vector") 1478 (set_attr "amdfam10_decode" "direct") 1479 (set_attr "bdver1_decode" "double")]) 1480 1481(define_insn "*cmpfp_i_sse" 1482 [(set (reg:CCFP FLAGS_REG) 1483 (compare:CCFP (match_operand 0 "register_operand" "x") 1484 (match_operand 1 "nonimmediate_operand" "xm")))] 1485 "TARGET_SSE_MATH 1486 && SSE_FLOAT_MODE_P (GET_MODE (operands[0])) 1487 && GET_MODE (operands[0]) == GET_MODE (operands[1])" 1488 "* return output_fp_compare (insn, operands, true, false);" 1489 [(set_attr "type" "ssecomi") 1490 (set_attr "prefix" "maybe_vex") 1491 (set (attr "mode") 1492 (if_then_else (match_operand:SF 1 "" "") 1493 (const_string "SF") 1494 (const_string "DF"))) 1495 (set_attr "prefix_rep" "0") 1496 (set (attr "prefix_data16") 1497 (if_then_else (eq_attr "mode" "DF") 1498 (const_string "1") 1499 (const_string "0"))) 1500 (set_attr "athlon_decode" "vector") 1501 (set_attr "amdfam10_decode" "direct") 1502 (set_attr "bdver1_decode" "double")]) 1503 1504(define_insn "*cmpfp_i_i387" 1505 [(set (reg:CCFP FLAGS_REG) 1506 (compare:CCFP (match_operand 0 "register_operand" "f") 1507 (match_operand 1 "register_operand" "f")))] 1508 "X87_FLOAT_MODE_P (GET_MODE (operands[0])) 1509 && TARGET_CMOVE 1510 && !(SSE_FLOAT_MODE_P (GET_MODE (operands[0])) && TARGET_SSE_MATH) 1511 && GET_MODE (operands[0]) == GET_MODE (operands[1])" 1512 "* return output_fp_compare (insn, operands, true, false);" 1513 [(set_attr "type" "fcmp") 1514 (set (attr "mode") 1515 (cond [(match_operand:SF 1 "" "") 1516 (const_string "SF") 1517 (match_operand:DF 1 "" "") 1518 (const_string "DF") 1519 ] 1520 (const_string "XF"))) 1521 (set_attr "athlon_decode" "vector") 1522 (set_attr "amdfam10_decode" "direct") 1523 (set_attr "bdver1_decode" "double")]) 1524 1525(define_insn "*cmpfp_iu_mixed" 1526 [(set (reg:CCFPU FLAGS_REG) 1527 (compare:CCFPU (match_operand 0 "register_operand" "f,x") 1528 (match_operand 1 "nonimmediate_operand" "f,xm")))] 1529 "TARGET_MIX_SSE_I387 1530 && SSE_FLOAT_MODE_P (GET_MODE (operands[0])) 1531 && GET_MODE (operands[0]) == GET_MODE (operands[1])" 1532 "* return output_fp_compare (insn, operands, true, true);" 1533 [(set_attr "type" "fcmp,ssecomi") 1534 (set_attr "prefix" "orig,maybe_vex") 1535 (set (attr "mode") 1536 (if_then_else (match_operand:SF 1 "" "") 1537 (const_string "SF") 1538 (const_string "DF"))) 1539 (set (attr "prefix_rep") 1540 (if_then_else (eq_attr "type" "ssecomi") 1541 (const_string "0") 1542 (const_string "*"))) 1543 (set (attr "prefix_data16") 1544 (cond [(eq_attr "type" "fcmp") 1545 (const_string "*") 1546 (eq_attr "mode" "DF") 1547 (const_string "1") 1548 ] 1549 (const_string "0"))) 1550 (set_attr "athlon_decode" "vector") 1551 (set_attr "amdfam10_decode" "direct") 1552 (set_attr "bdver1_decode" "double")]) 1553 1554(define_insn "*cmpfp_iu_sse" 1555 [(set (reg:CCFPU FLAGS_REG) 1556 (compare:CCFPU (match_operand 0 "register_operand" "x") 1557 (match_operand 1 "nonimmediate_operand" "xm")))] 1558 "TARGET_SSE_MATH 1559 && SSE_FLOAT_MODE_P (GET_MODE (operands[0])) 1560 && GET_MODE (operands[0]) == GET_MODE (operands[1])" 1561 "* return output_fp_compare (insn, operands, true, true);" 1562 [(set_attr "type" "ssecomi") 1563 (set_attr "prefix" "maybe_vex") 1564 (set (attr "mode") 1565 (if_then_else (match_operand:SF 1 "" "") 1566 (const_string "SF") 1567 (const_string "DF"))) 1568 (set_attr "prefix_rep" "0") 1569 (set (attr "prefix_data16") 1570 (if_then_else (eq_attr "mode" "DF") 1571 (const_string "1") 1572 (const_string "0"))) 1573 (set_attr "athlon_decode" "vector") 1574 (set_attr "amdfam10_decode" "direct") 1575 (set_attr "bdver1_decode" "double")]) 1576 1577(define_insn "*cmpfp_iu_387" 1578 [(set (reg:CCFPU FLAGS_REG) 1579 (compare:CCFPU (match_operand 0 "register_operand" "f") 1580 (match_operand 1 "register_operand" "f")))] 1581 "X87_FLOAT_MODE_P (GET_MODE (operands[0])) 1582 && TARGET_CMOVE 1583 && !(SSE_FLOAT_MODE_P (GET_MODE (operands[0])) && TARGET_SSE_MATH) 1584 && GET_MODE (operands[0]) == GET_MODE (operands[1])" 1585 "* return output_fp_compare (insn, operands, true, true);" 1586 [(set_attr "type" "fcmp") 1587 (set (attr "mode") 1588 (cond [(match_operand:SF 1 "" "") 1589 (const_string "SF") 1590 (match_operand:DF 1 "" "") 1591 (const_string "DF") 1592 ] 1593 (const_string "XF"))) 1594 (set_attr "athlon_decode" "vector") 1595 (set_attr "amdfam10_decode" "direct") 1596 (set_attr "bdver1_decode" "direct")]) 1597 1598;; Push/pop instructions. 1599 1600(define_insn "*push<mode>2" 1601 [(set (match_operand:DWI 0 "push_operand" "=<") 1602 (match_operand:DWI 1 "general_no_elim_operand" "riF*o"))] 1603 "" 1604 "#" 1605 [(set_attr "type" "multi") 1606 (set_attr "mode" "<MODE>")]) 1607 1608(define_split 1609 [(set (match_operand:TI 0 "push_operand" "") 1610 (match_operand:TI 1 "general_operand" ""))] 1611 "TARGET_64BIT && reload_completed 1612 && !SSE_REG_P (operands[1])" 1613 [(const_int 0)] 1614 "ix86_split_long_move (operands); DONE;") 1615 1616(define_insn "*pushdi2_rex64" 1617 [(set (match_operand:DI 0 "push_operand" "=<,!<") 1618 (match_operand:DI 1 "general_no_elim_operand" "re*m,n"))] 1619 "TARGET_64BIT" 1620 "@ 1621 push{q}\t%1 1622 #" 1623 [(set_attr "type" "push,multi") 1624 (set_attr "mode" "DI")]) 1625 1626;; Convert impossible pushes of immediate to existing instructions. 1627;; First try to get scratch register and go through it. In case this 1628;; fails, push sign extended lower part first and then overwrite 1629;; upper part by 32bit move. 1630(define_peephole2 1631 [(match_scratch:DI 2 "r") 1632 (set (match_operand:DI 0 "push_operand" "") 1633 (match_operand:DI 1 "immediate_operand" ""))] 1634 "TARGET_64BIT && !symbolic_operand (operands[1], DImode) 1635 && !x86_64_immediate_operand (operands[1], DImode)" 1636 [(set (match_dup 2) (match_dup 1)) 1637 (set (match_dup 0) (match_dup 2))]) 1638 1639;; We need to define this as both peepholer and splitter for case 1640;; peephole2 pass is not run. 1641;; "&& 1" is needed to keep it from matching the previous pattern. 1642(define_peephole2 1643 [(set (match_operand:DI 0 "push_operand" "") 1644 (match_operand:DI 1 "immediate_operand" ""))] 1645 "TARGET_64BIT && !symbolic_operand (operands[1], DImode) 1646 && !x86_64_immediate_operand (operands[1], DImode) && 1" 1647 [(set (match_dup 0) (match_dup 1)) 1648 (set (match_dup 2) (match_dup 3))] 1649{ 1650 split_double_mode (DImode, &operands[1], 1, &operands[2], &operands[3]); 1651 1652 operands[1] = gen_lowpart (DImode, operands[2]); 1653 operands[2] = gen_rtx_MEM (SImode, gen_rtx_PLUS (DImode, stack_pointer_rtx, 1654 GEN_INT (4))); 1655}) 1656 1657(define_split 1658 [(set (match_operand:DI 0 "push_operand" "") 1659 (match_operand:DI 1 "immediate_operand" ""))] 1660 "TARGET_64BIT && ((optimize > 0 && flag_peephole2) 1661 ? epilogue_completed : reload_completed) 1662 && !symbolic_operand (operands[1], DImode) 1663 && !x86_64_immediate_operand (operands[1], DImode)" 1664 [(set (match_dup 0) (match_dup 1)) 1665 (set (match_dup 2) (match_dup 3))] 1666{ 1667 split_double_mode (DImode, &operands[1], 1, &operands[2], &operands[3]); 1668 1669 operands[1] = gen_lowpart (DImode, operands[2]); 1670 operands[2] = gen_rtx_MEM (SImode, gen_rtx_PLUS (DImode, stack_pointer_rtx, 1671 GEN_INT (4))); 1672}) 1673 1674(define_split 1675 [(set (match_operand:DI 0 "push_operand" "") 1676 (match_operand:DI 1 "general_operand" ""))] 1677 "!TARGET_64BIT && reload_completed 1678 && !(MMX_REG_P (operands[1]) || SSE_REG_P (operands[1]))" 1679 [(const_int 0)] 1680 "ix86_split_long_move (operands); DONE;") 1681 1682(define_insn "*pushsi2" 1683 [(set (match_operand:SI 0 "push_operand" "=<") 1684 (match_operand:SI 1 "general_no_elim_operand" "ri*m"))] 1685 "!TARGET_64BIT" 1686 "push{l}\t%1" 1687 [(set_attr "type" "push") 1688 (set_attr "mode" "SI")]) 1689 1690;; emit_push_insn when it calls move_by_pieces requires an insn to 1691;; "push a byte/word". But actually we use pushl, which has the effect 1692;; of rounding the amount pushed up to a word. 1693 1694;; For TARGET_64BIT we always round up to 8 bytes. 1695(define_insn "*push<mode>2_rex64" 1696 [(set (match_operand:SWI124 0 "push_operand" "=X") 1697 (match_operand:SWI124 1 "nonmemory_no_elim_operand" "r<i>"))] 1698 "TARGET_64BIT" 1699 "push{q}\t%q1" 1700 [(set_attr "type" "push") 1701 (set_attr "mode" "DI")]) 1702 1703(define_insn "*push<mode>2" 1704 [(set (match_operand:SWI12 0 "push_operand" "=X") 1705 (match_operand:SWI12 1 "nonmemory_no_elim_operand" "rn"))] 1706 "!TARGET_64BIT" 1707 "push{l}\t%k1" 1708 [(set_attr "type" "push") 1709 (set_attr "mode" "SI")]) 1710 1711(define_insn "*push<mode>2_prologue" 1712 [(set (match_operand:P 0 "push_operand" "=<") 1713 (match_operand:P 1 "general_no_elim_operand" "r<i>*m")) 1714 (clobber (mem:BLK (scratch)))] 1715 "" 1716 "push{<imodesuffix>}\t%1" 1717 [(set_attr "type" "push") 1718 (set_attr "mode" "<MODE>")]) 1719 1720(define_insn "*pop<mode>1" 1721 [(set (match_operand:P 0 "nonimmediate_operand" "=r*m") 1722 (match_operand:P 1 "pop_operand" ">"))] 1723 "" 1724 "pop{<imodesuffix>}\t%0" 1725 [(set_attr "type" "pop") 1726 (set_attr "mode" "<MODE>")]) 1727 1728(define_insn "*pop<mode>1_epilogue" 1729 [(set (match_operand:P 0 "nonimmediate_operand" "=r*m") 1730 (match_operand:P 1 "pop_operand" ">")) 1731 (clobber (mem:BLK (scratch)))] 1732 "" 1733 "pop{<imodesuffix>}\t%0" 1734 [(set_attr "type" "pop") 1735 (set_attr "mode" "<MODE>")]) 1736 1737;; Move instructions. 1738 1739(define_expand "movoi" 1740 [(set (match_operand:OI 0 "nonimmediate_operand" "") 1741 (match_operand:OI 1 "general_operand" ""))] 1742 "TARGET_AVX" 1743 "ix86_expand_move (OImode, operands); DONE;") 1744 1745(define_expand "movti" 1746 [(set (match_operand:TI 0 "nonimmediate_operand" "") 1747 (match_operand:TI 1 "nonimmediate_operand" ""))] 1748 "TARGET_64BIT || TARGET_SSE" 1749{ 1750 if (TARGET_64BIT) 1751 ix86_expand_move (TImode, operands); 1752 else if (push_operand (operands[0], TImode)) 1753 ix86_expand_push (TImode, operands[1]); 1754 else 1755 ix86_expand_vector_move (TImode, operands); 1756 DONE; 1757}) 1758 1759;; This expands to what emit_move_complex would generate if we didn't 1760;; have a movti pattern. Having this avoids problems with reload on 1761;; 32-bit targets when SSE is present, but doesn't seem to be harmful 1762;; to have around all the time. 1763(define_expand "movcdi" 1764 [(set (match_operand:CDI 0 "nonimmediate_operand" "") 1765 (match_operand:CDI 1 "general_operand" ""))] 1766 "" 1767{ 1768 if (push_operand (operands[0], CDImode)) 1769 emit_move_complex_push (CDImode, operands[0], operands[1]); 1770 else 1771 emit_move_complex_parts (operands[0], operands[1]); 1772 DONE; 1773}) 1774 1775(define_expand "mov<mode>" 1776 [(set (match_operand:SWI1248x 0 "nonimmediate_operand" "") 1777 (match_operand:SWI1248x 1 "general_operand" ""))] 1778 "" 1779 "ix86_expand_move (<MODE>mode, operands); DONE;") 1780 1781(define_insn "*mov<mode>_xor" 1782 [(set (match_operand:SWI48 0 "register_operand" "=r") 1783 (match_operand:SWI48 1 "const0_operand" "")) 1784 (clobber (reg:CC FLAGS_REG))] 1785 "reload_completed" 1786 "xor{l}\t%k0, %k0" 1787 [(set_attr "type" "alu1") 1788 (set_attr "mode" "SI") 1789 (set_attr "length_immediate" "0")]) 1790 1791(define_insn "*mov<mode>_or" 1792 [(set (match_operand:SWI48 0 "register_operand" "=r") 1793 (match_operand:SWI48 1 "const_int_operand" "")) 1794 (clobber (reg:CC FLAGS_REG))] 1795 "reload_completed 1796 && operands[1] == constm1_rtx" 1797 "or{<imodesuffix>}\t{%1, %0|%0, %1}" 1798 [(set_attr "type" "alu1") 1799 (set_attr "mode" "<MODE>") 1800 (set_attr "length_immediate" "1")]) 1801 1802(define_insn "*movoi_internal_avx" 1803 [(set (match_operand:OI 0 "nonimmediate_operand" "=x,x,m") 1804 (match_operand:OI 1 "vector_move_operand" "C,xm,x"))] 1805 "TARGET_AVX && !(MEM_P (operands[0]) && MEM_P (operands[1]))" 1806{ 1807 switch (which_alternative) 1808 { 1809 case 0: 1810 return standard_sse_constant_opcode (insn, operands[1]); 1811 case 1: 1812 case 2: 1813 if (misaligned_operand (operands[0], OImode) 1814 || misaligned_operand (operands[1], OImode)) 1815 return "vmovdqu\t{%1, %0|%0, %1}"; 1816 else 1817 return "vmovdqa\t{%1, %0|%0, %1}"; 1818 default: 1819 gcc_unreachable (); 1820 } 1821} 1822 [(set_attr "type" "sselog1,ssemov,ssemov") 1823 (set_attr "prefix" "vex") 1824 (set_attr "mode" "OI")]) 1825 1826(define_insn "*movti_internal_rex64" 1827 [(set (match_operand:TI 0 "nonimmediate_operand" "=!r,o,x,x,xm") 1828 (match_operand:TI 1 "general_operand" "riFo,riF,C,xm,x"))] 1829 "TARGET_64BIT && !(MEM_P (operands[0]) && MEM_P (operands[1]))" 1830{ 1831 switch (which_alternative) 1832 { 1833 case 0: 1834 case 1: 1835 return "#"; 1836 case 2: 1837 return standard_sse_constant_opcode (insn, operands[1]); 1838 case 3: 1839 case 4: 1840 /* TDmode values are passed as TImode on the stack. Moving them 1841 to stack may result in unaligned memory access. */ 1842 if (misaligned_operand (operands[0], TImode) 1843 || misaligned_operand (operands[1], TImode)) 1844 { 1845 if (get_attr_mode (insn) == MODE_V4SF) 1846 return "%vmovups\t{%1, %0|%0, %1}"; 1847 else 1848 return "%vmovdqu\t{%1, %0|%0, %1}"; 1849 } 1850 else 1851 { 1852 if (get_attr_mode (insn) == MODE_V4SF) 1853 return "%vmovaps\t{%1, %0|%0, %1}"; 1854 else 1855 return "%vmovdqa\t{%1, %0|%0, %1}"; 1856 } 1857 default: 1858 gcc_unreachable (); 1859 } 1860} 1861 [(set_attr "type" "*,*,sselog1,ssemov,ssemov") 1862 (set_attr "prefix" "*,*,maybe_vex,maybe_vex,maybe_vex") 1863 (set (attr "mode") 1864 (cond [(eq_attr "alternative" "2,3") 1865 (if_then_else 1866 (match_test "optimize_function_for_size_p (cfun)") 1867 (const_string "V4SF") 1868 (const_string "TI")) 1869 (eq_attr "alternative" "4") 1870 (if_then_else 1871 (ior (match_test "TARGET_SSE_TYPELESS_STORES") 1872 (match_test "optimize_function_for_size_p (cfun)")) 1873 (const_string "V4SF") 1874 (const_string "TI"))] 1875 (const_string "DI")))]) 1876 1877(define_split 1878 [(set (match_operand:TI 0 "nonimmediate_operand" "") 1879 (match_operand:TI 1 "general_operand" ""))] 1880 "reload_completed 1881 && !SSE_REG_P (operands[0]) && !SSE_REG_P (operands[1])" 1882 [(const_int 0)] 1883 "ix86_split_long_move (operands); DONE;") 1884 1885(define_insn "*movti_internal_sse" 1886 [(set (match_operand:TI 0 "nonimmediate_operand" "=x,x,m") 1887 (match_operand:TI 1 "vector_move_operand" "C,xm,x"))] 1888 "TARGET_SSE && !TARGET_64BIT 1889 && !(MEM_P (operands[0]) && MEM_P (operands[1]))" 1890{ 1891 switch (which_alternative) 1892 { 1893 case 0: 1894 return standard_sse_constant_opcode (insn, operands[1]); 1895 case 1: 1896 case 2: 1897 /* TDmode values are passed as TImode on the stack. Moving them 1898 to stack may result in unaligned memory access. */ 1899 if (misaligned_operand (operands[0], TImode) 1900 || misaligned_operand (operands[1], TImode)) 1901 { 1902 if (get_attr_mode (insn) == MODE_V4SF) 1903 return "%vmovups\t{%1, %0|%0, %1}"; 1904 else 1905 return "%vmovdqu\t{%1, %0|%0, %1}"; 1906 } 1907 else 1908 { 1909 if (get_attr_mode (insn) == MODE_V4SF) 1910 return "%vmovaps\t{%1, %0|%0, %1}"; 1911 else 1912 return "%vmovdqa\t{%1, %0|%0, %1}"; 1913 } 1914 default: 1915 gcc_unreachable (); 1916 } 1917} 1918 [(set_attr "type" "sselog1,ssemov,ssemov") 1919 (set_attr "prefix" "maybe_vex") 1920 (set (attr "mode") 1921 (cond [(ior (not (match_test "TARGET_SSE2")) 1922 (match_test "optimize_function_for_size_p (cfun)")) 1923 (const_string "V4SF") 1924 (and (eq_attr "alternative" "2") 1925 (match_test "TARGET_SSE_TYPELESS_STORES")) 1926 (const_string "V4SF")] 1927 (const_string "TI")))]) 1928 1929(define_insn "*movdi_internal_rex64" 1930 [(set (match_operand:DI 0 "nonimmediate_operand" 1931 "=r,r ,r,m ,!o,*y,m*y,?*y,?r ,?*Ym,*x,m ,*x,*x,?r ,?*Yi,?*x,?*Ym") 1932 (match_operand:DI 1 "general_operand" 1933 "Z ,rem,i,re,n ,C ,*y ,m ,*Ym,r ,C ,*x,*x,m ,*Yi,r ,*Ym,*x"))] 1934 "TARGET_64BIT && !(MEM_P (operands[0]) && MEM_P (operands[1]))" 1935{ 1936 switch (get_attr_type (insn)) 1937 { 1938 case TYPE_SSECVT: 1939 if (SSE_REG_P (operands[0])) 1940 return "movq2dq\t{%1, %0|%0, %1}"; 1941 else 1942 return "movdq2q\t{%1, %0|%0, %1}"; 1943 1944 case TYPE_SSEMOV: 1945 if (get_attr_mode (insn) == MODE_TI) 1946 return "%vmovdqa\t{%1, %0|%0, %1}"; 1947 /* Handle broken assemblers that require movd instead of movq. */ 1948 if (GENERAL_REG_P (operands[0]) || GENERAL_REG_P (operands[1])) 1949 return "%vmovd\t{%1, %0|%0, %1}"; 1950 else 1951 return "%vmovq\t{%1, %0|%0, %1}"; 1952 1953 case TYPE_MMXMOV: 1954 /* Handle broken assemblers that require movd instead of movq. */ 1955 if (GENERAL_REG_P (operands[0]) || GENERAL_REG_P (operands[1])) 1956 return "movd\t{%1, %0|%0, %1}"; 1957 else 1958 return "movq\t{%1, %0|%0, %1}"; 1959 1960 case TYPE_SSELOG1: 1961 return standard_sse_constant_opcode (insn, operands[1]); 1962 1963 case TYPE_MMX: 1964 return "pxor\t%0, %0"; 1965 1966 case TYPE_MULTI: 1967 return "#"; 1968 1969 case TYPE_LEA: 1970 return "lea{q}\t{%E1, %0|%0, %E1}"; 1971 1972 default: 1973 gcc_assert (!flag_pic || LEGITIMATE_PIC_OPERAND_P (operands[1])); 1974 if (get_attr_mode (insn) == MODE_SI) 1975 return "mov{l}\t{%k1, %k0|%k0, %k1}"; 1976 else if (which_alternative == 2) 1977 return "movabs{q}\t{%1, %0|%0, %1}"; 1978 else if (ix86_use_lea_for_mov (insn, operands)) 1979 return "lea{q}\t{%E1, %0|%0, %E1}"; 1980 else 1981 return "mov{q}\t{%1, %0|%0, %1}"; 1982 } 1983} 1984 [(set (attr "type") 1985 (cond [(eq_attr "alternative" "4") 1986 (const_string "multi") 1987 (eq_attr "alternative" "5") 1988 (const_string "mmx") 1989 (eq_attr "alternative" "6,7,8,9") 1990 (const_string "mmxmov") 1991 (eq_attr "alternative" "10") 1992 (const_string "sselog1") 1993 (eq_attr "alternative" "11,12,13,14,15") 1994 (const_string "ssemov") 1995 (eq_attr "alternative" "16,17") 1996 (const_string "ssecvt") 1997 (match_operand 1 "pic_32bit_operand" "") 1998 (const_string "lea") 1999 ] 2000 (const_string "imov"))) 2001 (set (attr "modrm") 2002 (if_then_else 2003 (and (eq_attr "alternative" "2") (eq_attr "type" "imov")) 2004 (const_string "0") 2005 (const_string "*"))) 2006 (set (attr "length_immediate") 2007 (if_then_else 2008 (and (eq_attr "alternative" "2") (eq_attr "type" "imov")) 2009 (const_string "8") 2010 (const_string "*"))) 2011 (set (attr "prefix_rex") 2012 (if_then_else (eq_attr "alternative" "8,9") 2013 (const_string "1") 2014 (const_string "*"))) 2015 (set (attr "prefix_data16") 2016 (if_then_else (eq_attr "alternative" "11") 2017 (const_string "1") 2018 (const_string "*"))) 2019 (set (attr "prefix") 2020 (if_then_else (eq_attr "alternative" "10,11,12,13,14,15") 2021 (const_string "maybe_vex") 2022 (const_string "orig"))) 2023 (set_attr "mode" "SI,DI,DI,DI,SI,DI,DI,DI,DI,DI,TI,DI,TI,DI,DI,DI,DI,DI")]) 2024 2025;; Reload patterns to support multi-word load/store 2026;; with non-offsetable address. 2027(define_expand "reload_noff_store" 2028 [(parallel [(match_operand 0 "memory_operand" "=m") 2029 (match_operand 1 "register_operand" "r") 2030 (match_operand:DI 2 "register_operand" "=&r")])] 2031 "TARGET_64BIT" 2032{ 2033 rtx mem = operands[0]; 2034 rtx addr = XEXP (mem, 0); 2035 2036 emit_move_insn (operands[2], addr); 2037 mem = replace_equiv_address_nv (mem, operands[2]); 2038 2039 emit_insn (gen_rtx_SET (VOIDmode, mem, operands[1])); 2040 DONE; 2041}) 2042 2043(define_expand "reload_noff_load" 2044 [(parallel [(match_operand 0 "register_operand" "=r") 2045 (match_operand 1 "memory_operand" "m") 2046 (match_operand:DI 2 "register_operand" "=r")])] 2047 "TARGET_64BIT" 2048{ 2049 rtx mem = operands[1]; 2050 rtx addr = XEXP (mem, 0); 2051 2052 emit_move_insn (operands[2], addr); 2053 mem = replace_equiv_address_nv (mem, operands[2]); 2054 2055 emit_insn (gen_rtx_SET (VOIDmode, operands[0], mem)); 2056 DONE; 2057}) 2058 2059;; Convert impossible stores of immediate to existing instructions. 2060;; First try to get scratch register and go through it. In case this 2061;; fails, move by 32bit parts. 2062(define_peephole2 2063 [(match_scratch:DI 2 "r") 2064 (set (match_operand:DI 0 "memory_operand" "") 2065 (match_operand:DI 1 "immediate_operand" ""))] 2066 "TARGET_64BIT && !symbolic_operand (operands[1], DImode) 2067 && !x86_64_immediate_operand (operands[1], DImode)" 2068 [(set (match_dup 2) (match_dup 1)) 2069 (set (match_dup 0) (match_dup 2))]) 2070 2071;; We need to define this as both peepholer and splitter for case 2072;; peephole2 pass is not run. 2073;; "&& 1" is needed to keep it from matching the previous pattern. 2074(define_peephole2 2075 [(set (match_operand:DI 0 "memory_operand" "") 2076 (match_operand:DI 1 "immediate_operand" ""))] 2077 "TARGET_64BIT && !symbolic_operand (operands[1], DImode) 2078 && !x86_64_immediate_operand (operands[1], DImode) && 1" 2079 [(set (match_dup 2) (match_dup 3)) 2080 (set (match_dup 4) (match_dup 5))] 2081 "split_double_mode (DImode, &operands[0], 2, &operands[2], &operands[4]);") 2082 2083(define_split 2084 [(set (match_operand:DI 0 "memory_operand" "") 2085 (match_operand:DI 1 "immediate_operand" ""))] 2086 "TARGET_64BIT && ((optimize > 0 && flag_peephole2) 2087 ? epilogue_completed : reload_completed) 2088 && !symbolic_operand (operands[1], DImode) 2089 && !x86_64_immediate_operand (operands[1], DImode)" 2090 [(set (match_dup 2) (match_dup 3)) 2091 (set (match_dup 4) (match_dup 5))] 2092 "split_double_mode (DImode, &operands[0], 2, &operands[2], &operands[4]);") 2093 2094(define_insn "*movdi_internal" 2095 [(set (match_operand:DI 0 "nonimmediate_operand" 2096 "=r ,o ,*y,m*y,*y,*x,m ,*x,*x,*x,m ,*x,*x,?*x,?*Ym") 2097 (match_operand:DI 1 "general_operand" 2098 "riFo,riF,C ,*y ,m ,C ,*x,*x,m ,C ,*x,*x,m ,*Ym,*x"))] 2099 "!TARGET_64BIT && !(MEM_P (operands[0]) && MEM_P (operands[1]))" 2100{ 2101 switch (get_attr_type (insn)) 2102 { 2103 case TYPE_SSECVT: 2104 if (SSE_REG_P (operands[0])) 2105 return "movq2dq\t{%1, %0|%0, %1}"; 2106 else 2107 return "movdq2q\t{%1, %0|%0, %1}"; 2108 2109 case TYPE_SSEMOV: 2110 switch (get_attr_mode (insn)) 2111 { 2112 case MODE_TI: 2113 return "%vmovdqa\t{%1, %0|%0, %1}"; 2114 case MODE_DI: 2115 return "%vmovq\t{%1, %0|%0, %1}"; 2116 case MODE_V4SF: 2117 return "movaps\t{%1, %0|%0, %1}"; 2118 case MODE_V2SF: 2119 return "movlps\t{%1, %0|%0, %1}"; 2120 default: 2121 gcc_unreachable (); 2122 } 2123 2124 case TYPE_MMXMOV: 2125 return "movq\t{%1, %0|%0, %1}"; 2126 2127 case TYPE_SSELOG1: 2128 return standard_sse_constant_opcode (insn, operands[1]); 2129 2130 case TYPE_MMX: 2131 return "pxor\t%0, %0"; 2132 2133 case TYPE_MULTI: 2134 return "#"; 2135 2136 default: 2137 gcc_unreachable (); 2138 } 2139} 2140 [(set (attr "isa") 2141 (cond [(eq_attr "alternative" "5,6,7,8,13,14") 2142 (const_string "sse2") 2143 (eq_attr "alternative" "9,10,11,12") 2144 (const_string "noavx") 2145 ] 2146 (const_string "*"))) 2147 (set (attr "type") 2148 (cond [(eq_attr "alternative" "0,1") 2149 (const_string "multi") 2150 (eq_attr "alternative" "2") 2151 (const_string "mmx") 2152 (eq_attr "alternative" "3,4") 2153 (const_string "mmxmov") 2154 (eq_attr "alternative" "5,9") 2155 (const_string "sselog1") 2156 (eq_attr "alternative" "13,14") 2157 (const_string "ssecvt") 2158 ] 2159 (const_string "ssemov"))) 2160 (set (attr "prefix") 2161 (if_then_else (eq_attr "alternative" "5,6,7,8") 2162 (const_string "maybe_vex") 2163 (const_string "orig"))) 2164 (set_attr "mode" "DI,DI,DI,DI,DI,TI,DI,TI,DI,V4SF,V2SF,V4SF,V2SF,DI,DI")]) 2165 2166(define_split 2167 [(set (match_operand:DI 0 "nonimmediate_operand" "") 2168 (match_operand:DI 1 "general_operand" ""))] 2169 "!TARGET_64BIT && reload_completed 2170 && !(MMX_REG_P (operands[0]) || SSE_REG_P (operands[0])) 2171 && !(MMX_REG_P (operands[1]) || SSE_REG_P (operands[1]))" 2172 [(const_int 0)] 2173 "ix86_split_long_move (operands); DONE;") 2174 2175(define_insn "*movsi_internal" 2176 [(set (match_operand:SI 0 "nonimmediate_operand" 2177 "=r,m ,*y,*y,?rm,?*y,*x,*x,?r ,m ,?*Yi,*x") 2178 (match_operand:SI 1 "general_operand" 2179 "g ,re,C ,*y,*y ,rm ,C ,*x,*Yi,*x,r ,m "))] 2180 "!(MEM_P (operands[0]) && MEM_P (operands[1]))" 2181{ 2182 switch (get_attr_type (insn)) 2183 { 2184 case TYPE_SSELOG1: 2185 return standard_sse_constant_opcode (insn, operands[1]); 2186 2187 case TYPE_SSEMOV: 2188 switch (get_attr_mode (insn)) 2189 { 2190 case MODE_TI: 2191 return "%vmovdqa\t{%1, %0|%0, %1}"; 2192 case MODE_V4SF: 2193 return "%vmovaps\t{%1, %0|%0, %1}"; 2194 case MODE_SI: 2195 return "%vmovd\t{%1, %0|%0, %1}"; 2196 case MODE_SF: 2197 return "%vmovss\t{%1, %0|%0, %1}"; 2198 default: 2199 gcc_unreachable (); 2200 } 2201 2202 case TYPE_MMX: 2203 return "pxor\t%0, %0"; 2204 2205 case TYPE_MMXMOV: 2206 if (get_attr_mode (insn) == MODE_DI) 2207 return "movq\t{%1, %0|%0, %1}"; 2208 return "movd\t{%1, %0|%0, %1}"; 2209 2210 case TYPE_LEA: 2211 return "lea{l}\t{%E1, %0|%0, %E1}"; 2212 2213 default: 2214 gcc_assert (!flag_pic || LEGITIMATE_PIC_OPERAND_P (operands[1])); 2215 if (ix86_use_lea_for_mov (insn, operands)) 2216 return "lea{l}\t{%E1, %0|%0, %E1}"; 2217 else 2218 return "mov{l}\t{%1, %0|%0, %1}"; 2219 } 2220} 2221 [(set (attr "type") 2222 (cond [(eq_attr "alternative" "2") 2223 (const_string "mmx") 2224 (eq_attr "alternative" "3,4,5") 2225 (const_string "mmxmov") 2226 (eq_attr "alternative" "6") 2227 (const_string "sselog1") 2228 (eq_attr "alternative" "7,8,9,10,11") 2229 (const_string "ssemov") 2230 (match_operand 1 "pic_32bit_operand" "") 2231 (const_string "lea") 2232 ] 2233 (const_string "imov"))) 2234 (set (attr "prefix") 2235 (if_then_else (eq_attr "alternative" "0,1,2,3,4,5") 2236 (const_string "orig") 2237 (const_string "maybe_vex"))) 2238 (set (attr "prefix_data16") 2239 (if_then_else (and (eq_attr "type" "ssemov") (eq_attr "mode" "SI")) 2240 (const_string "1") 2241 (const_string "*"))) 2242 (set (attr "mode") 2243 (cond [(eq_attr "alternative" "2,3") 2244 (const_string "DI") 2245 (eq_attr "alternative" "6,7") 2246 (if_then_else 2247 (not (match_test "TARGET_SSE2")) 2248 (const_string "V4SF") 2249 (const_string "TI")) 2250 (and (eq_attr "alternative" "8,9,10,11") 2251 (not (match_test "TARGET_SSE2"))) 2252 (const_string "SF") 2253 ] 2254 (const_string "SI")))]) 2255 2256(define_insn "*movhi_internal" 2257 [(set (match_operand:HI 0 "nonimmediate_operand" "=r,r,r,m") 2258 (match_operand:HI 1 "general_operand" "r,rn,rm,rn"))] 2259 "!(MEM_P (operands[0]) && MEM_P (operands[1]))" 2260{ 2261 switch (get_attr_type (insn)) 2262 { 2263 case TYPE_IMOVX: 2264 /* movzwl is faster than movw on p2 due to partial word stalls, 2265 though not as fast as an aligned movl. */ 2266 return "movz{wl|x}\t{%1, %k0|%k0, %1}"; 2267 default: 2268 if (get_attr_mode (insn) == MODE_SI) 2269 return "mov{l}\t{%k1, %k0|%k0, %k1}"; 2270 else 2271 return "mov{w}\t{%1, %0|%0, %1}"; 2272 } 2273} 2274 [(set (attr "type") 2275 (cond [(match_test "optimize_function_for_size_p (cfun)") 2276 (const_string "imov") 2277 (and (eq_attr "alternative" "0") 2278 (ior (not (match_test "TARGET_PARTIAL_REG_STALL")) 2279 (not (match_test "TARGET_HIMODE_MATH")))) 2280 (const_string "imov") 2281 (and (eq_attr "alternative" "1,2") 2282 (match_operand:HI 1 "aligned_operand" "")) 2283 (const_string "imov") 2284 (and (match_test "TARGET_MOVX") 2285 (eq_attr "alternative" "0,2")) 2286 (const_string "imovx") 2287 ] 2288 (const_string "imov"))) 2289 (set (attr "mode") 2290 (cond [(eq_attr "type" "imovx") 2291 (const_string "SI") 2292 (and (eq_attr "alternative" "1,2") 2293 (match_operand:HI 1 "aligned_operand" "")) 2294 (const_string "SI") 2295 (and (eq_attr "alternative" "0") 2296 (ior (not (match_test "TARGET_PARTIAL_REG_STALL")) 2297 (not (match_test "TARGET_HIMODE_MATH")))) 2298 (const_string "SI") 2299 ] 2300 (const_string "HI")))]) 2301 2302;; Situation is quite tricky about when to choose full sized (SImode) move 2303;; over QImode moves. For Q_REG -> Q_REG move we use full size only for 2304;; partial register dependency machines (such as AMD Athlon), where QImode 2305;; moves issue extra dependency and for partial register stalls machines 2306;; that don't use QImode patterns (and QImode move cause stall on the next 2307;; instruction). 2308;; 2309;; For loads of Q_REG to NONQ_REG we use full sized moves except for partial 2310;; register stall machines with, where we use QImode instructions, since 2311;; partial register stall can be caused there. Then we use movzx. 2312(define_insn "*movqi_internal" 2313 [(set (match_operand:QI 0 "nonimmediate_operand" "=q,q ,q ,r,r ,?r,m") 2314 (match_operand:QI 1 "general_operand" " q,qn,qm,q,rn,qm,qn"))] 2315 "!(MEM_P (operands[0]) && MEM_P (operands[1]))" 2316{ 2317 switch (get_attr_type (insn)) 2318 { 2319 case TYPE_IMOVX: 2320 gcc_assert (ANY_QI_REG_P (operands[1]) || MEM_P (operands[1])); 2321 return "movz{bl|x}\t{%1, %k0|%k0, %1}"; 2322 default: 2323 if (get_attr_mode (insn) == MODE_SI) 2324 return "mov{l}\t{%k1, %k0|%k0, %k1}"; 2325 else 2326 return "mov{b}\t{%1, %0|%0, %1}"; 2327 } 2328} 2329 [(set (attr "type") 2330 (cond [(and (eq_attr "alternative" "5") 2331 (not (match_operand:QI 1 "aligned_operand" ""))) 2332 (const_string "imovx") 2333 (match_test "optimize_function_for_size_p (cfun)") 2334 (const_string "imov") 2335 (and (eq_attr "alternative" "3") 2336 (ior (not (match_test "TARGET_PARTIAL_REG_STALL")) 2337 (not (match_test "TARGET_QIMODE_MATH")))) 2338 (const_string "imov") 2339 (eq_attr "alternative" "3,5") 2340 (const_string "imovx") 2341 (and (match_test "TARGET_MOVX") 2342 (eq_attr "alternative" "2")) 2343 (const_string "imovx") 2344 ] 2345 (const_string "imov"))) 2346 (set (attr "mode") 2347 (cond [(eq_attr "alternative" "3,4,5") 2348 (const_string "SI") 2349 (eq_attr "alternative" "6") 2350 (const_string "QI") 2351 (eq_attr "type" "imovx") 2352 (const_string "SI") 2353 (and (eq_attr "type" "imov") 2354 (and (eq_attr "alternative" "0,1") 2355 (and (match_test "TARGET_PARTIAL_REG_DEPENDENCY") 2356 (and (not (match_test "optimize_function_for_size_p (cfun)")) 2357 (not (match_test "TARGET_PARTIAL_REG_STALL")))))) 2358 (const_string "SI") 2359 ;; Avoid partial register stalls when not using QImode arithmetic 2360 (and (eq_attr "type" "imov") 2361 (and (eq_attr "alternative" "0,1") 2362 (and (match_test "TARGET_PARTIAL_REG_STALL") 2363 (not (match_test "TARGET_QIMODE_MATH"))))) 2364 (const_string "SI") 2365 ] 2366 (const_string "QI")))]) 2367 2368;; Stores and loads of ax to arbitrary constant address. 2369;; We fake an second form of instruction to force reload to load address 2370;; into register when rax is not available 2371(define_insn "*movabs<mode>_1" 2372 [(set (mem:SWI1248x (match_operand:DI 0 "x86_64_movabs_operand" "i,r")) 2373 (match_operand:SWI1248x 1 "nonmemory_operand" "a,r<i>"))] 2374 "TARGET_LP64 && ix86_check_movabs (insn, 0)" 2375 "@ 2376 movabs{<imodesuffix>}\t{%1, %P0|%P0, %1} 2377 mov{<imodesuffix>}\t{%1, %a0|%a0, %1}" 2378 [(set_attr "type" "imov") 2379 (set_attr "modrm" "0,*") 2380 (set_attr "length_address" "8,0") 2381 (set_attr "length_immediate" "0,*") 2382 (set_attr "memory" "store") 2383 (set_attr "mode" "<MODE>")]) 2384 2385(define_insn "*movabs<mode>_2" 2386 [(set (match_operand:SWI1248x 0 "register_operand" "=a,r") 2387 (mem:SWI1248x (match_operand:DI 1 "x86_64_movabs_operand" "i,r")))] 2388 "TARGET_LP64 && ix86_check_movabs (insn, 1)" 2389 "@ 2390 movabs{<imodesuffix>}\t{%P1, %0|%0, %P1} 2391 mov{<imodesuffix>}\t{%a1, %0|%0, %a1}" 2392 [(set_attr "type" "imov") 2393 (set_attr "modrm" "0,*") 2394 (set_attr "length_address" "8,0") 2395 (set_attr "length_immediate" "0") 2396 (set_attr "memory" "load") 2397 (set_attr "mode" "<MODE>")]) 2398 2399(define_insn "*swap<mode>" 2400 [(set (match_operand:SWI48 0 "register_operand" "+r") 2401 (match_operand:SWI48 1 "register_operand" "+r")) 2402 (set (match_dup 1) 2403 (match_dup 0))] 2404 "" 2405 "xchg{<imodesuffix>}\t%1, %0" 2406 [(set_attr "type" "imov") 2407 (set_attr "mode" "<MODE>") 2408 (set_attr "pent_pair" "np") 2409 (set_attr "athlon_decode" "vector") 2410 (set_attr "amdfam10_decode" "double") 2411 (set_attr "bdver1_decode" "double")]) 2412 2413(define_insn "*swap<mode>_1" 2414 [(set (match_operand:SWI12 0 "register_operand" "+r") 2415 (match_operand:SWI12 1 "register_operand" "+r")) 2416 (set (match_dup 1) 2417 (match_dup 0))] 2418 "!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun)" 2419 "xchg{l}\t%k1, %k0" 2420 [(set_attr "type" "imov") 2421 (set_attr "mode" "SI") 2422 (set_attr "pent_pair" "np") 2423 (set_attr "athlon_decode" "vector") 2424 (set_attr "amdfam10_decode" "double") 2425 (set_attr "bdver1_decode" "double")]) 2426 2427;; Not added amdfam10_decode since TARGET_PARTIAL_REG_STALL 2428;; is disabled for AMDFAM10 2429(define_insn "*swap<mode>_2" 2430 [(set (match_operand:SWI12 0 "register_operand" "+<r>") 2431 (match_operand:SWI12 1 "register_operand" "+<r>")) 2432 (set (match_dup 1) 2433 (match_dup 0))] 2434 "TARGET_PARTIAL_REG_STALL" 2435 "xchg{<imodesuffix>}\t%1, %0" 2436 [(set_attr "type" "imov") 2437 (set_attr "mode" "<MODE>") 2438 (set_attr "pent_pair" "np") 2439 (set_attr "athlon_decode" "vector")]) 2440 2441(define_expand "movstrict<mode>" 2442 [(set (strict_low_part (match_operand:SWI12 0 "nonimmediate_operand" "")) 2443 (match_operand:SWI12 1 "general_operand" ""))] 2444 "" 2445{ 2446 if (TARGET_PARTIAL_REG_STALL && optimize_function_for_speed_p (cfun)) 2447 FAIL; 2448 if (GET_CODE (operands[0]) == SUBREG 2449 && GET_MODE_CLASS (GET_MODE (SUBREG_REG (operands[0]))) != MODE_INT) 2450 FAIL; 2451 /* Don't generate memory->memory moves, go through a register */ 2452 if (MEM_P (operands[0]) && MEM_P (operands[1])) 2453 operands[1] = force_reg (<MODE>mode, operands[1]); 2454}) 2455 2456(define_insn "*movstrict<mode>_1" 2457 [(set (strict_low_part 2458 (match_operand:SWI12 0 "nonimmediate_operand" "+<r>m,<r>")) 2459 (match_operand:SWI12 1 "general_operand" "<r>n,m"))] 2460 "(!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun)) 2461 && !(MEM_P (operands[0]) && MEM_P (operands[1]))" 2462 "mov{<imodesuffix>}\t{%1, %0|%0, %1}" 2463 [(set_attr "type" "imov") 2464 (set_attr "mode" "<MODE>")]) 2465 2466(define_insn "*movstrict<mode>_xor" 2467 [(set (strict_low_part (match_operand:SWI12 0 "register_operand" "+<r>")) 2468 (match_operand:SWI12 1 "const0_operand" "")) 2469 (clobber (reg:CC FLAGS_REG))] 2470 "reload_completed" 2471 "xor{<imodesuffix>}\t%0, %0" 2472 [(set_attr "type" "alu1") 2473 (set_attr "mode" "<MODE>") 2474 (set_attr "length_immediate" "0")]) 2475 2476(define_insn "*mov<mode>_extv_1" 2477 [(set (match_operand:SWI24 0 "register_operand" "=R") 2478 (sign_extract:SWI24 (match_operand 1 "ext_register_operand" "Q") 2479 (const_int 8) 2480 (const_int 8)))] 2481 "" 2482 "movs{bl|x}\t{%h1, %k0|%k0, %h1}" 2483 [(set_attr "type" "imovx") 2484 (set_attr "mode" "SI")]) 2485 2486(define_insn "*movqi_extv_1_rex64" 2487 [(set (match_operand:QI 0 "register_operand" "=Q,?R") 2488 (sign_extract:QI (match_operand 1 "ext_register_operand" "Q,Q") 2489 (const_int 8) 2490 (const_int 8)))] 2491 "TARGET_64BIT" 2492{ 2493 switch (get_attr_type (insn)) 2494 { 2495 case TYPE_IMOVX: 2496 return "movs{bl|x}\t{%h1, %k0|%k0, %h1}"; 2497 default: 2498 return "mov{b}\t{%h1, %0|%0, %h1}"; 2499 } 2500} 2501 [(set (attr "type") 2502 (if_then_else (ior (not (match_operand:QI 0 "QIreg_operand" "")) 2503 (match_test "TARGET_MOVX")) 2504 (const_string "imovx") 2505 (const_string "imov"))) 2506 (set (attr "mode") 2507 (if_then_else (eq_attr "type" "imovx") 2508 (const_string "SI") 2509 (const_string "QI")))]) 2510 2511(define_insn "*movqi_extv_1" 2512 [(set (match_operand:QI 0 "nonimmediate_operand" "=Qm,?r") 2513 (sign_extract:QI (match_operand 1 "ext_register_operand" "Q,Q") 2514 (const_int 8) 2515 (const_int 8)))] 2516 "!TARGET_64BIT" 2517{ 2518 switch (get_attr_type (insn)) 2519 { 2520 case TYPE_IMOVX: 2521 return "movs{bl|x}\t{%h1, %k0|%k0, %h1}"; 2522 default: 2523 return "mov{b}\t{%h1, %0|%0, %h1}"; 2524 } 2525} 2526 [(set (attr "type") 2527 (if_then_else (and (match_operand:QI 0 "register_operand" "") 2528 (ior (not (match_operand:QI 0 "QIreg_operand" "")) 2529 (match_test "TARGET_MOVX"))) 2530 (const_string "imovx") 2531 (const_string "imov"))) 2532 (set (attr "mode") 2533 (if_then_else (eq_attr "type" "imovx") 2534 (const_string "SI") 2535 (const_string "QI")))]) 2536 2537(define_insn "*mov<mode>_extzv_1" 2538 [(set (match_operand:SWI48 0 "register_operand" "=R") 2539 (zero_extract:SWI48 (match_operand 1 "ext_register_operand" "Q") 2540 (const_int 8) 2541 (const_int 8)))] 2542 "" 2543 "movz{bl|x}\t{%h1, %k0|%k0, %h1}" 2544 [(set_attr "type" "imovx") 2545 (set_attr "mode" "SI")]) 2546 2547(define_insn "*movqi_extzv_2_rex64" 2548 [(set (match_operand:QI 0 "register_operand" "=Q,?R") 2549 (subreg:QI 2550 (zero_extract:SI (match_operand 1 "ext_register_operand" "Q,Q") 2551 (const_int 8) 2552 (const_int 8)) 0))] 2553 "TARGET_64BIT" 2554{ 2555 switch (get_attr_type (insn)) 2556 { 2557 case TYPE_IMOVX: 2558 return "movz{bl|x}\t{%h1, %k0|%k0, %h1}"; 2559 default: 2560 return "mov{b}\t{%h1, %0|%0, %h1}"; 2561 } 2562} 2563 [(set (attr "type") 2564 (if_then_else (ior (not (match_operand:QI 0 "QIreg_operand" "")) 2565 (match_test "TARGET_MOVX")) 2566 (const_string "imovx") 2567 (const_string "imov"))) 2568 (set (attr "mode") 2569 (if_then_else (eq_attr "type" "imovx") 2570 (const_string "SI") 2571 (const_string "QI")))]) 2572 2573(define_insn "*movqi_extzv_2" 2574 [(set (match_operand:QI 0 "nonimmediate_operand" "=Qm,?R") 2575 (subreg:QI 2576 (zero_extract:SI (match_operand 1 "ext_register_operand" "Q,Q") 2577 (const_int 8) 2578 (const_int 8)) 0))] 2579 "!TARGET_64BIT" 2580{ 2581 switch (get_attr_type (insn)) 2582 { 2583 case TYPE_IMOVX: 2584 return "movz{bl|x}\t{%h1, %k0|%k0, %h1}"; 2585 default: 2586 return "mov{b}\t{%h1, %0|%0, %h1}"; 2587 } 2588} 2589 [(set (attr "type") 2590 (if_then_else (and (match_operand:QI 0 "register_operand" "") 2591 (ior (not (match_operand:QI 0 "QIreg_operand" "")) 2592 (match_test "TARGET_MOVX"))) 2593 (const_string "imovx") 2594 (const_string "imov"))) 2595 (set (attr "mode") 2596 (if_then_else (eq_attr "type" "imovx") 2597 (const_string "SI") 2598 (const_string "QI")))]) 2599 2600(define_expand "mov<mode>_insv_1" 2601 [(set (zero_extract:SWI48 (match_operand 0 "ext_register_operand" "") 2602 (const_int 8) 2603 (const_int 8)) 2604 (match_operand:SWI48 1 "nonmemory_operand" ""))]) 2605 2606(define_insn "*mov<mode>_insv_1_rex64" 2607 [(set (zero_extract:SWI48x (match_operand 0 "ext_register_operand" "+Q") 2608 (const_int 8) 2609 (const_int 8)) 2610 (match_operand:SWI48x 1 "nonmemory_operand" "Qn"))] 2611 "TARGET_64BIT" 2612{ 2613 if (CONST_INT_P (operands[1])) 2614 operands[1] = simplify_gen_subreg (QImode, operands[1], <MODE>mode, 0); 2615 return "mov{b}\t{%b1, %h0|%h0, %b1}"; 2616} 2617 [(set_attr "type" "imov") 2618 (set_attr "mode" "QI")]) 2619 2620(define_insn "*movsi_insv_1" 2621 [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "+Q") 2622 (const_int 8) 2623 (const_int 8)) 2624 (match_operand:SI 1 "general_operand" "Qmn"))] 2625 "!TARGET_64BIT" 2626{ 2627 if (CONST_INT_P (operands[1])) 2628 operands[1] = simplify_gen_subreg (QImode, operands[1], SImode, 0); 2629 return "mov{b}\t{%b1, %h0|%h0, %b1}"; 2630} 2631 [(set_attr "type" "imov") 2632 (set_attr "mode" "QI")]) 2633 2634(define_insn "*movqi_insv_2" 2635 [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "+Q") 2636 (const_int 8) 2637 (const_int 8)) 2638 (lshiftrt:SI (match_operand:SI 1 "register_operand" "Q") 2639 (const_int 8)))] 2640 "" 2641 "mov{b}\t{%h1, %h0|%h0, %h1}" 2642 [(set_attr "type" "imov") 2643 (set_attr "mode" "QI")]) 2644 2645;; Floating point push instructions. 2646 2647(define_insn "*pushtf" 2648 [(set (match_operand:TF 0 "push_operand" "=<,<,<") 2649 (match_operand:TF 1 "general_no_elim_operand" "x,Fo,*r"))] 2650 "TARGET_SSE2" 2651{ 2652 /* This insn should be already split before reg-stack. */ 2653 gcc_unreachable (); 2654} 2655 [(set_attr "type" "multi") 2656 (set_attr "unit" "sse,*,*") 2657 (set_attr "mode" "TF,SI,SI")]) 2658 2659;; %%% Kill this when call knows how to work this out. 2660(define_split 2661 [(set (match_operand:TF 0 "push_operand" "") 2662 (match_operand:TF 1 "sse_reg_operand" ""))] 2663 "TARGET_SSE2 && reload_completed" 2664 [(set (reg:P SP_REG) (plus:P (reg:P SP_REG) (const_int -16))) 2665 (set (mem:TF (reg:P SP_REG)) (match_dup 1))]) 2666 2667(define_insn "*pushxf" 2668 [(set (match_operand:XF 0 "push_operand" "=<,<") 2669 (match_operand:XF 1 "general_no_elim_operand" "f,ro"))] 2670 "optimize_function_for_speed_p (cfun)" 2671{ 2672 /* This insn should be already split before reg-stack. */ 2673 gcc_unreachable (); 2674} 2675 [(set_attr "type" "multi") 2676 (set_attr "unit" "i387,*") 2677 (set_attr "mode" "XF,SI")]) 2678 2679;; Size of pushxf is 3 (for sub) + 2 (for fstp) + memory operand size. 2680;; Size of pushxf using integer instructions is 3+3*memory operand size 2681;; Pushing using integer instructions is longer except for constants 2682;; and direct memory references (assuming that any given constant is pushed 2683;; only once, but this ought to be handled elsewhere). 2684 2685(define_insn "*pushxf_nointeger" 2686 [(set (match_operand:XF 0 "push_operand" "=<,<") 2687 (match_operand:XF 1 "general_no_elim_operand" "f,*rFo"))] 2688 "optimize_function_for_size_p (cfun)" 2689{ 2690 /* This insn should be already split before reg-stack. */ 2691 gcc_unreachable (); 2692} 2693 [(set_attr "type" "multi") 2694 (set_attr "unit" "i387,*") 2695 (set_attr "mode" "XF,SI")]) 2696 2697;; %%% Kill this when call knows how to work this out. 2698(define_split 2699 [(set (match_operand:XF 0 "push_operand" "") 2700 (match_operand:XF 1 "fp_register_operand" ""))] 2701 "reload_completed" 2702 [(set (reg:P SP_REG) (plus:P (reg:P SP_REG) (match_dup 2))) 2703 (set (mem:XF (reg:P SP_REG)) (match_dup 1))] 2704 "operands[2] = GEN_INT (-GET_MODE_SIZE (XFmode));") 2705 2706(define_insn "*pushdf_rex64" 2707 [(set (match_operand:DF 0 "push_operand" "=<,<,<") 2708 (match_operand:DF 1 "general_no_elim_operand" "f,Yd*rFm,x"))] 2709 "TARGET_64BIT" 2710{ 2711 /* This insn should be already split before reg-stack. */ 2712 gcc_unreachable (); 2713} 2714 [(set_attr "type" "multi") 2715 (set_attr "unit" "i387,*,*") 2716 (set_attr "mode" "DF,DI,DF")]) 2717 2718;; Size of pushdf is 3 (for sub) + 2 (for fstp) + memory operand size. 2719;; Size of pushdf using integer instructions is 2+2*memory operand size 2720;; On the average, pushdf using integers can be still shorter. 2721 2722(define_insn "*pushdf" 2723 [(set (match_operand:DF 0 "push_operand" "=<,<,<") 2724 (match_operand:DF 1 "general_no_elim_operand" "f,Yd*rFo,x"))] 2725 "!TARGET_64BIT" 2726{ 2727 /* This insn should be already split before reg-stack. */ 2728 gcc_unreachable (); 2729} 2730 [(set_attr "isa" "*,*,sse2") 2731 (set_attr "type" "multi") 2732 (set_attr "unit" "i387,*,*") 2733 (set_attr "mode" "DF,DI,DF")]) 2734 2735;; %%% Kill this when call knows how to work this out. 2736(define_split 2737 [(set (match_operand:DF 0 "push_operand" "") 2738 (match_operand:DF 1 "any_fp_register_operand" ""))] 2739 "reload_completed" 2740 [(set (reg:P SP_REG) (plus:P (reg:P SP_REG) (const_int -8))) 2741 (set (mem:DF (reg:P SP_REG)) (match_dup 1))]) 2742 2743(define_insn "*pushsf_rex64" 2744 [(set (match_operand:SF 0 "push_operand" "=X,X,X") 2745 (match_operand:SF 1 "nonmemory_no_elim_operand" "f,rF,x"))] 2746 "TARGET_64BIT" 2747{ 2748 /* Anything else should be already split before reg-stack. */ 2749 gcc_assert (which_alternative == 1); 2750 return "push{q}\t%q1"; 2751} 2752 [(set_attr "type" "multi,push,multi") 2753 (set_attr "unit" "i387,*,*") 2754 (set_attr "mode" "SF,DI,SF")]) 2755 2756(define_insn "*pushsf" 2757 [(set (match_operand:SF 0 "push_operand" "=<,<,<") 2758 (match_operand:SF 1 "general_no_elim_operand" "f,rFm,x"))] 2759 "!TARGET_64BIT" 2760{ 2761 /* Anything else should be already split before reg-stack. */ 2762 gcc_assert (which_alternative == 1); 2763 return "push{l}\t%1"; 2764} 2765 [(set_attr "type" "multi,push,multi") 2766 (set_attr "unit" "i387,*,*") 2767 (set_attr "mode" "SF,SI,SF")]) 2768 2769;; %%% Kill this when call knows how to work this out. 2770(define_split 2771 [(set (match_operand:SF 0 "push_operand" "") 2772 (match_operand:SF 1 "any_fp_register_operand" ""))] 2773 "reload_completed" 2774 [(set (reg:P SP_REG) (plus:P (reg:P SP_REG) (match_dup 2))) 2775 (set (mem:SF (reg:P SP_REG)) (match_dup 1))] 2776 "operands[2] = GEN_INT (-GET_MODE_SIZE (<P:MODE>mode));") 2777 2778(define_split 2779 [(set (match_operand:SF 0 "push_operand" "") 2780 (match_operand:SF 1 "memory_operand" ""))] 2781 "reload_completed 2782 && (operands[2] = find_constant_src (insn))" 2783 [(set (match_dup 0) (match_dup 2))]) 2784 2785(define_split 2786 [(set (match_operand 0 "push_operand" "") 2787 (match_operand 1 "general_operand" ""))] 2788 "reload_completed 2789 && (GET_MODE (operands[0]) == TFmode 2790 || GET_MODE (operands[0]) == XFmode 2791 || GET_MODE (operands[0]) == DFmode) 2792 && !ANY_FP_REG_P (operands[1])" 2793 [(const_int 0)] 2794 "ix86_split_long_move (operands); DONE;") 2795 2796;; Floating point move instructions. 2797 2798(define_expand "movtf" 2799 [(set (match_operand:TF 0 "nonimmediate_operand" "") 2800 (match_operand:TF 1 "nonimmediate_operand" ""))] 2801 "TARGET_SSE2" 2802{ 2803 ix86_expand_move (TFmode, operands); 2804 DONE; 2805}) 2806 2807(define_expand "mov<mode>" 2808 [(set (match_operand:X87MODEF 0 "nonimmediate_operand" "") 2809 (match_operand:X87MODEF 1 "general_operand" ""))] 2810 "" 2811 "ix86_expand_move (<MODE>mode, operands); DONE;") 2812 2813(define_insn "*movtf_internal" 2814 [(set (match_operand:TF 0 "nonimmediate_operand" "=x,m,x,?*r ,!o") 2815 (match_operand:TF 1 "general_operand" "xm,x,C,*roF,F*r"))] 2816 "TARGET_SSE2 2817 && !(MEM_P (operands[0]) && MEM_P (operands[1])) 2818 && (!can_create_pseudo_p () 2819 || (ix86_cmodel == CM_MEDIUM || ix86_cmodel == CM_LARGE) 2820 || GET_CODE (operands[1]) != CONST_DOUBLE 2821 || (optimize_function_for_size_p (cfun) 2822 && standard_sse_constant_p (operands[1]) 2823 && !memory_operand (operands[0], TFmode)) 2824 || (!TARGET_MEMORY_MISMATCH_STALL 2825 && memory_operand (operands[0], TFmode)))" 2826{ 2827 switch (which_alternative) 2828 { 2829 case 0: 2830 case 1: 2831 /* Handle misaligned load/store since we 2832 don't have movmisaligntf pattern. */ 2833 if (misaligned_operand (operands[0], TFmode) 2834 || misaligned_operand (operands[1], TFmode)) 2835 { 2836 if (get_attr_mode (insn) == MODE_V4SF) 2837 return "%vmovups\t{%1, %0|%0, %1}"; 2838 else 2839 return "%vmovdqu\t{%1, %0|%0, %1}"; 2840 } 2841 else 2842 { 2843 if (get_attr_mode (insn) == MODE_V4SF) 2844 return "%vmovaps\t{%1, %0|%0, %1}"; 2845 else 2846 return "%vmovdqa\t{%1, %0|%0, %1}"; 2847 } 2848 2849 case 2: 2850 return standard_sse_constant_opcode (insn, operands[1]); 2851 2852 case 3: 2853 case 4: 2854 return "#"; 2855 2856 default: 2857 gcc_unreachable (); 2858 } 2859} 2860 [(set_attr "type" "ssemov,ssemov,sselog1,*,*") 2861 (set_attr "prefix" "maybe_vex,maybe_vex,maybe_vex,*,*") 2862 (set (attr "mode") 2863 (cond [(eq_attr "alternative" "0,2") 2864 (if_then_else 2865 (match_test "optimize_function_for_size_p (cfun)") 2866 (const_string "V4SF") 2867 (const_string "TI")) 2868 (eq_attr "alternative" "1") 2869 (if_then_else 2870 (ior (match_test "TARGET_SSE_TYPELESS_STORES") 2871 (match_test "optimize_function_for_size_p (cfun)")) 2872 (const_string "V4SF") 2873 (const_string "TI"))] 2874 (const_string "DI")))]) 2875 2876;; Possible store forwarding (partial memory) stall in alternative 4. 2877(define_insn "*movxf_internal" 2878 [(set (match_operand:XF 0 "nonimmediate_operand" "=f,m,f,?Yx*r ,!o") 2879 (match_operand:XF 1 "general_operand" "fm,f,G,Yx*roF,FYx*r"))] 2880 "!(MEM_P (operands[0]) && MEM_P (operands[1])) 2881 && (!can_create_pseudo_p () 2882 || (ix86_cmodel == CM_MEDIUM || ix86_cmodel == CM_LARGE) 2883 || GET_CODE (operands[1]) != CONST_DOUBLE 2884 || (optimize_function_for_size_p (cfun) 2885 && standard_80387_constant_p (operands[1]) > 0 2886 && !memory_operand (operands[0], XFmode)) 2887 || (!TARGET_MEMORY_MISMATCH_STALL 2888 && memory_operand (operands[0], XFmode)))" 2889{ 2890 switch (which_alternative) 2891 { 2892 case 0: 2893 case 1: 2894 return output_387_reg_move (insn, operands); 2895 2896 case 2: 2897 return standard_80387_constant_opcode (operands[1]); 2898 2899 case 3: 2900 case 4: 2901 return "#"; 2902 2903 default: 2904 gcc_unreachable (); 2905 } 2906} 2907 [(set_attr "type" "fmov,fmov,fmov,multi,multi") 2908 (set_attr "mode" "XF,XF,XF,SI,SI")]) 2909 2910(define_insn "*movdf_internal_rex64" 2911 [(set (match_operand:DF 0 "nonimmediate_operand" 2912 "=f,m,f,?r,?m,?r,!o,x,x,x,m,Yi,r ") 2913 (match_operand:DF 1 "general_operand" 2914 "fm,f,G,rm,r ,F ,F ,C,x,m,x,r ,Yi"))] 2915 "TARGET_64BIT && !(MEM_P (operands[0]) && MEM_P (operands[1])) 2916 && (!can_create_pseudo_p () 2917 || (ix86_cmodel == CM_MEDIUM || ix86_cmodel == CM_LARGE) 2918 || GET_CODE (operands[1]) != CONST_DOUBLE 2919 || (optimize_function_for_size_p (cfun) 2920 && ((!(TARGET_SSE2 && TARGET_SSE_MATH) 2921 && standard_80387_constant_p (operands[1]) > 0) 2922 || (TARGET_SSE2 && TARGET_SSE_MATH 2923 && standard_sse_constant_p (operands[1])))) 2924 || memory_operand (operands[0], DFmode))" 2925{ 2926 switch (which_alternative) 2927 { 2928 case 0: 2929 case 1: 2930 return output_387_reg_move (insn, operands); 2931 2932 case 2: 2933 return standard_80387_constant_opcode (operands[1]); 2934 2935 case 3: 2936 case 4: 2937 return "mov{q}\t{%1, %0|%0, %1}"; 2938 2939 case 5: 2940 return "movabs{q}\t{%1, %0|%0, %1}"; 2941 2942 case 6: 2943 return "#"; 2944 2945 case 7: 2946 return standard_sse_constant_opcode (insn, operands[1]); 2947 2948 case 8: 2949 case 9: 2950 case 10: 2951 switch (get_attr_mode (insn)) 2952 { 2953 case MODE_V2DF: 2954 if (!TARGET_SSE_PACKED_SINGLE_INSN_OPTIMAL) 2955 return "%vmovapd\t{%1, %0|%0, %1}"; 2956 case MODE_V4SF: 2957 return "%vmovaps\t{%1, %0|%0, %1}"; 2958 2959 case MODE_DI: 2960 return "%vmovq\t{%1, %0|%0, %1}"; 2961 case MODE_DF: 2962 if (TARGET_AVX && REG_P (operands[0]) && REG_P (operands[1])) 2963 return "vmovsd\t{%1, %0, %0|%0, %0, %1}"; 2964 return "%vmovsd\t{%1, %0|%0, %1}"; 2965 case MODE_V1DF: 2966 return "%vmovlpd\t{%1, %d0|%d0, %1}"; 2967 case MODE_V2SF: 2968 return "%vmovlps\t{%1, %d0|%d0, %1}"; 2969 default: 2970 gcc_unreachable (); 2971 } 2972 2973 case 11: 2974 case 12: 2975 /* Handle broken assemblers that require movd instead of movq. */ 2976 return "%vmovd\t{%1, %0|%0, %1}"; 2977 2978 default: 2979 gcc_unreachable(); 2980 } 2981} 2982 [(set (attr "type") 2983 (cond [(eq_attr "alternative" "0,1,2") 2984 (const_string "fmov") 2985 (eq_attr "alternative" "3,4,5") 2986 (const_string "imov") 2987 (eq_attr "alternative" "6") 2988 (const_string "multi") 2989 (eq_attr "alternative" "7") 2990 (const_string "sselog1") 2991 ] 2992 (const_string "ssemov"))) 2993 (set (attr "modrm") 2994 (if_then_else 2995 (and (eq_attr "alternative" "5") (eq_attr "type" "imov")) 2996 (const_string "0") 2997 (const_string "*"))) 2998 (set (attr "length_immediate") 2999 (if_then_else 3000 (and (eq_attr "alternative" "5") (eq_attr "type" "imov")) 3001 (const_string "8") 3002 (const_string "*"))) 3003 (set (attr "prefix") 3004 (if_then_else (eq_attr "alternative" "0,1,2,3,4,5,6") 3005 (const_string "orig") 3006 (const_string "maybe_vex"))) 3007 (set (attr "prefix_data16") 3008 (if_then_else (eq_attr "mode" "V1DF") 3009 (const_string "1") 3010 (const_string "*"))) 3011 (set (attr "mode") 3012 (cond [(eq_attr "alternative" "0,1,2") 3013 (const_string "DF") 3014 (eq_attr "alternative" "3,4,5,6,11,12") 3015 (const_string "DI") 3016 3017 /* xorps is one byte shorter. */ 3018 (eq_attr "alternative" "7") 3019 (cond [(match_test "optimize_function_for_size_p (cfun)") 3020 (const_string "V4SF") 3021 (match_test "TARGET_SSE_LOAD0_BY_PXOR") 3022 (const_string "TI") 3023 ] 3024 (const_string "V2DF")) 3025 3026 /* For architectures resolving dependencies on 3027 whole SSE registers use APD move to break dependency 3028 chains, otherwise use short move to avoid extra work. 3029 3030 movaps encodes one byte shorter. */ 3031 (eq_attr "alternative" "8") 3032 (cond 3033 [(match_test "optimize_function_for_size_p (cfun)") 3034 (const_string "V4SF") 3035 (match_test "TARGET_SSE_PARTIAL_REG_DEPENDENCY") 3036 (const_string "V2DF") 3037 ] 3038 (const_string "DF")) 3039 /* For architectures resolving dependencies on register 3040 parts we may avoid extra work to zero out upper part 3041 of register. */ 3042 (eq_attr "alternative" "9") 3043 (if_then_else 3044 (match_test "TARGET_SSE_SPLIT_REGS") 3045 (const_string "V1DF") 3046 (const_string "DF")) 3047 ] 3048 (const_string "DF")))]) 3049 3050;; Possible store forwarding (partial memory) stall in alternative 4. 3051(define_insn "*movdf_internal" 3052 [(set (match_operand:DF 0 "nonimmediate_operand" 3053 "=f,m,f,?Yd*r ,!o ,x,x,x,m,*x,*x,*x,m") 3054 (match_operand:DF 1 "general_operand" 3055 "fm,f,G,Yd*roF,FYd*r,C,x,m,x,C ,*x,m ,*x"))] 3056 "!TARGET_64BIT && !(MEM_P (operands[0]) && MEM_P (operands[1])) 3057 && (!can_create_pseudo_p () 3058 || (ix86_cmodel == CM_MEDIUM || ix86_cmodel == CM_LARGE) 3059 || GET_CODE (operands[1]) != CONST_DOUBLE 3060 || (optimize_function_for_size_p (cfun) 3061 && ((!(TARGET_SSE2 && TARGET_SSE_MATH) 3062 && standard_80387_constant_p (operands[1]) > 0) 3063 || (TARGET_SSE2 && TARGET_SSE_MATH 3064 && standard_sse_constant_p (operands[1]))) 3065 && !memory_operand (operands[0], DFmode)) 3066 || (!TARGET_MEMORY_MISMATCH_STALL 3067 && memory_operand (operands[0], DFmode)))" 3068{ 3069 switch (which_alternative) 3070 { 3071 case 0: 3072 case 1: 3073 return output_387_reg_move (insn, operands); 3074 3075 case 2: 3076 return standard_80387_constant_opcode (operands[1]); 3077 3078 case 3: 3079 case 4: 3080 return "#"; 3081 3082 case 5: 3083 case 9: 3084 return standard_sse_constant_opcode (insn, operands[1]); 3085 3086 case 6: 3087 case 7: 3088 case 8: 3089 case 10: 3090 case 11: 3091 case 12: 3092 switch (get_attr_mode (insn)) 3093 { 3094 case MODE_V2DF: 3095 if (!TARGET_SSE_PACKED_SINGLE_INSN_OPTIMAL) 3096 return "%vmovapd\t{%1, %0|%0, %1}"; 3097 case MODE_V4SF: 3098 return "%vmovaps\t{%1, %0|%0, %1}"; 3099 3100 case MODE_DI: 3101 return "%vmovq\t{%1, %0|%0, %1}"; 3102 case MODE_DF: 3103 if (TARGET_AVX && REG_P (operands[0]) && REG_P (operands[1])) 3104 return "vmovsd\t{%1, %0, %0|%0, %0, %1}"; 3105 return "%vmovsd\t{%1, %0|%0, %1}"; 3106 case MODE_V1DF: 3107 return "%vmovlpd\t{%1, %d0|%d0, %1}"; 3108 case MODE_V2SF: 3109 return "%vmovlps\t{%1, %d0|%d0, %1}"; 3110 default: 3111 gcc_unreachable (); 3112 } 3113 3114 default: 3115 gcc_unreachable (); 3116 } 3117} 3118 [(set (attr "isa") 3119 (if_then_else (eq_attr "alternative" "5,6,7,8") 3120 (const_string "sse2") 3121 (const_string "*"))) 3122 (set (attr "type") 3123 (cond [(eq_attr "alternative" "0,1,2") 3124 (const_string "fmov") 3125 (eq_attr "alternative" "3,4") 3126 (const_string "multi") 3127 (eq_attr "alternative" "5,9") 3128 (const_string "sselog1") 3129 ] 3130 (const_string "ssemov"))) 3131 (set (attr "prefix") 3132 (if_then_else (eq_attr "alternative" "0,1,2,3,4") 3133 (const_string "orig") 3134 (const_string "maybe_vex"))) 3135 (set (attr "prefix_data16") 3136 (if_then_else (eq_attr "mode" "V1DF") 3137 (const_string "1") 3138 (const_string "*"))) 3139 (set (attr "mode") 3140 (cond [(eq_attr "alternative" "0,1,2") 3141 (const_string "DF") 3142 (eq_attr "alternative" "3,4") 3143 (const_string "SI") 3144 3145 /* For SSE1, we have many fewer alternatives. */ 3146 (not (match_test "TARGET_SSE2")) 3147 (if_then_else 3148 (eq_attr "alternative" "5,6,9,10") 3149 (const_string "V4SF") 3150 (const_string "V2SF")) 3151 3152 /* xorps is one byte shorter. */ 3153 (eq_attr "alternative" "5,9") 3154 (cond [(match_test "optimize_function_for_size_p (cfun)") 3155 (const_string "V4SF") 3156 (match_test "TARGET_SSE_LOAD0_BY_PXOR") 3157 (const_string "TI") 3158 ] 3159 (const_string "V2DF")) 3160 3161 /* For architectures resolving dependencies on 3162 whole SSE registers use APD move to break dependency 3163 chains, otherwise use short move to avoid extra work. 3164 3165 movaps encodes one byte shorter. */ 3166 (eq_attr "alternative" "6,10") 3167 (cond 3168 [(match_test "optimize_function_for_size_p (cfun)") 3169 (const_string "V4SF") 3170 (match_test "TARGET_SSE_PARTIAL_REG_DEPENDENCY") 3171 (const_string "V2DF") 3172 ] 3173 (const_string "DF")) 3174 /* For architectures resolving dependencies on register 3175 parts we may avoid extra work to zero out upper part 3176 of register. */ 3177 (eq_attr "alternative" "7,11") 3178 (if_then_else 3179 (match_test "TARGET_SSE_SPLIT_REGS") 3180 (const_string "V1DF") 3181 (const_string "DF")) 3182 ] 3183 (const_string "DF")))]) 3184 3185(define_insn "*movsf_internal" 3186 [(set (match_operand:SF 0 "nonimmediate_operand" 3187 "=f,m,f,?r ,?m,x,x,x,m,!*y,!m,!*y,?Yi,?r,!*Ym,!r") 3188 (match_operand:SF 1 "general_operand" 3189 "fm,f,G,rmF,Fr,C,x,m,x,m ,*y,*y ,r ,Yi,r ,*Ym"))] 3190 "!(MEM_P (operands[0]) && MEM_P (operands[1])) 3191 && (!can_create_pseudo_p () 3192 || (ix86_cmodel == CM_MEDIUM || ix86_cmodel == CM_LARGE) 3193 || GET_CODE (operands[1]) != CONST_DOUBLE 3194 || (optimize_function_for_size_p (cfun) 3195 && ((!TARGET_SSE_MATH 3196 && standard_80387_constant_p (operands[1]) > 0) 3197 || (TARGET_SSE_MATH 3198 && standard_sse_constant_p (operands[1])))) 3199 || memory_operand (operands[0], SFmode))" 3200{ 3201 switch (which_alternative) 3202 { 3203 case 0: 3204 case 1: 3205 return output_387_reg_move (insn, operands); 3206 3207 case 2: 3208 return standard_80387_constant_opcode (operands[1]); 3209 3210 case 3: 3211 case 4: 3212 return "mov{l}\t{%1, %0|%0, %1}"; 3213 3214 case 5: 3215 return standard_sse_constant_opcode (insn, operands[1]); 3216 3217 case 6: 3218 if (get_attr_mode (insn) == MODE_V4SF) 3219 return "%vmovaps\t{%1, %0|%0, %1}"; 3220 if (TARGET_AVX) 3221 return "vmovss\t{%1, %0, %0|%0, %0, %1}"; 3222 3223 case 7: 3224 case 8: 3225 return "%vmovss\t{%1, %0|%0, %1}"; 3226 3227 case 9: 3228 case 10: 3229 case 14: 3230 case 15: 3231 return "movd\t{%1, %0|%0, %1}"; 3232 3233 case 11: 3234 return "movq\t{%1, %0|%0, %1}"; 3235 3236 case 12: 3237 case 13: 3238 return "%vmovd\t{%1, %0|%0, %1}"; 3239 3240 default: 3241 gcc_unreachable (); 3242 } 3243} 3244 [(set (attr "type") 3245 (cond [(eq_attr "alternative" "0,1,2") 3246 (const_string "fmov") 3247 (eq_attr "alternative" "3,4") 3248 (const_string "multi") 3249 (eq_attr "alternative" "5") 3250 (const_string "sselog1") 3251 (eq_attr "alternative" "9,10,11,14,15") 3252 (const_string "mmxmov") 3253 ] 3254 (const_string "ssemov"))) 3255 (set (attr "prefix") 3256 (if_then_else (eq_attr "alternative" "5,6,7,8,12,13") 3257 (const_string "maybe_vex") 3258 (const_string "orig"))) 3259 (set (attr "mode") 3260 (cond [(eq_attr "alternative" "3,4,9,10") 3261 (const_string "SI") 3262 (eq_attr "alternative" "5") 3263 (if_then_else 3264 (and (and (match_test "TARGET_SSE_LOAD0_BY_PXOR") 3265 (match_test "TARGET_SSE2")) 3266 (not (match_test "optimize_function_for_size_p (cfun)"))) 3267 (const_string "TI") 3268 (const_string "V4SF")) 3269 /* For architectures resolving dependencies on 3270 whole SSE registers use APS move to break dependency 3271 chains, otherwise use short move to avoid extra work. 3272 3273 Do the same for architectures resolving dependencies on 3274 the parts. While in DF mode it is better to always handle 3275 just register parts, the SF mode is different due to lack 3276 of instructions to load just part of the register. It is 3277 better to maintain the whole registers in single format 3278 to avoid problems on using packed logical operations. */ 3279 (eq_attr "alternative" "6") 3280 (if_then_else 3281 (ior (match_test "TARGET_SSE_PARTIAL_REG_DEPENDENCY") 3282 (match_test "TARGET_SSE_SPLIT_REGS")) 3283 (const_string "V4SF") 3284 (const_string "SF")) 3285 (eq_attr "alternative" "11") 3286 (const_string "DI")] 3287 (const_string "SF")))]) 3288 3289(define_split 3290 [(set (match_operand 0 "any_fp_register_operand" "") 3291 (match_operand 1 "memory_operand" ""))] 3292 "reload_completed 3293 && (GET_MODE (operands[0]) == TFmode 3294 || GET_MODE (operands[0]) == XFmode 3295 || GET_MODE (operands[0]) == DFmode 3296 || GET_MODE (operands[0]) == SFmode) 3297 && (operands[2] = find_constant_src (insn))" 3298 [(set (match_dup 0) (match_dup 2))] 3299{ 3300 rtx c = operands[2]; 3301 int r = REGNO (operands[0]); 3302 3303 if ((SSE_REGNO_P (r) && !standard_sse_constant_p (c)) 3304 || (FP_REGNO_P (r) && standard_80387_constant_p (c) < 1)) 3305 FAIL; 3306}) 3307 3308(define_split 3309 [(set (match_operand 0 "any_fp_register_operand" "") 3310 (float_extend (match_operand 1 "memory_operand" "")))] 3311 "reload_completed 3312 && (GET_MODE (operands[0]) == TFmode 3313 || GET_MODE (operands[0]) == XFmode 3314 || GET_MODE (operands[0]) == DFmode) 3315 && (operands[2] = find_constant_src (insn))" 3316 [(set (match_dup 0) (match_dup 2))] 3317{ 3318 rtx c = operands[2]; 3319 int r = REGNO (operands[0]); 3320 3321 if ((SSE_REGNO_P (r) && !standard_sse_constant_p (c)) 3322 || (FP_REGNO_P (r) && standard_80387_constant_p (c) < 1)) 3323 FAIL; 3324}) 3325 3326;; Split the load of -0.0 or -1.0 into fldz;fchs or fld1;fchs sequence 3327(define_split 3328 [(set (match_operand:X87MODEF 0 "fp_register_operand" "") 3329 (match_operand:X87MODEF 1 "immediate_operand" ""))] 3330 "reload_completed 3331 && (standard_80387_constant_p (operands[1]) == 8 3332 || standard_80387_constant_p (operands[1]) == 9)" 3333 [(set (match_dup 0)(match_dup 1)) 3334 (set (match_dup 0) 3335 (neg:X87MODEF (match_dup 0)))] 3336{ 3337 REAL_VALUE_TYPE r; 3338 3339 REAL_VALUE_FROM_CONST_DOUBLE (r, operands[1]); 3340 if (real_isnegzero (&r)) 3341 operands[1] = CONST0_RTX (<MODE>mode); 3342 else 3343 operands[1] = CONST1_RTX (<MODE>mode); 3344}) 3345 3346(define_split 3347 [(set (match_operand 0 "nonimmediate_operand" "") 3348 (match_operand 1 "general_operand" ""))] 3349 "reload_completed 3350 && (GET_MODE (operands[0]) == TFmode 3351 || GET_MODE (operands[0]) == XFmode 3352 || GET_MODE (operands[0]) == DFmode) 3353 && !(ANY_FP_REG_P (operands[0]) || ANY_FP_REG_P (operands[1]))" 3354 [(const_int 0)] 3355 "ix86_split_long_move (operands); DONE;") 3356 3357(define_insn "swapxf" 3358 [(set (match_operand:XF 0 "register_operand" "+f") 3359 (match_operand:XF 1 "register_operand" "+f")) 3360 (set (match_dup 1) 3361 (match_dup 0))] 3362 "TARGET_80387" 3363{ 3364 if (STACK_TOP_P (operands[0])) 3365 return "fxch\t%1"; 3366 else 3367 return "fxch\t%0"; 3368} 3369 [(set_attr "type" "fxch") 3370 (set_attr "mode" "XF")]) 3371 3372(define_insn "*swap<mode>" 3373 [(set (match_operand:MODEF 0 "fp_register_operand" "+f") 3374 (match_operand:MODEF 1 "fp_register_operand" "+f")) 3375 (set (match_dup 1) 3376 (match_dup 0))] 3377 "TARGET_80387 || reload_completed" 3378{ 3379 if (STACK_TOP_P (operands[0])) 3380 return "fxch\t%1"; 3381 else 3382 return "fxch\t%0"; 3383} 3384 [(set_attr "type" "fxch") 3385 (set_attr "mode" "<MODE>")]) 3386 3387;; Zero extension instructions 3388 3389(define_expand "zero_extendsidi2" 3390 [(set (match_operand:DI 0 "nonimmediate_operand" "") 3391 (zero_extend:DI (match_operand:SI 1 "nonimmediate_operand" "")))] 3392 "" 3393{ 3394 if (!TARGET_64BIT) 3395 { 3396 emit_insn (gen_zero_extendsidi2_1 (operands[0], operands[1])); 3397 DONE; 3398 } 3399}) 3400 3401(define_insn "*zero_extendsidi2_rex64" 3402 [(set (match_operand:DI 0 "nonimmediate_operand" "=r,o,?*Ym,?*y,?*Yi,*x") 3403 (zero_extend:DI 3404 (match_operand:SI 1 "nonimmediate_operand" "rm,0,r ,m ,r ,m")))] 3405 "TARGET_64BIT" 3406 "@ 3407 mov{l}\t{%1, %k0|%k0, %1} 3408 # 3409 movd\t{%1, %0|%0, %1} 3410 movd\t{%1, %0|%0, %1} 3411 %vmovd\t{%1, %0|%0, %1} 3412 %vmovd\t{%1, %0|%0, %1}" 3413 [(set_attr "type" "imovx,imov,mmxmov,mmxmov,ssemov,ssemov") 3414 (set_attr "prefix" "orig,*,orig,orig,maybe_vex,maybe_vex") 3415 (set_attr "prefix_0f" "0,*,*,*,*,*") 3416 (set_attr "mode" "SI,DI,DI,DI,TI,TI")]) 3417 3418(define_split 3419 [(set (match_operand:DI 0 "memory_operand" "") 3420 (zero_extend:DI (match_dup 0)))] 3421 "TARGET_64BIT" 3422 [(set (match_dup 4) (const_int 0))] 3423 "split_double_mode (DImode, &operands[0], 1, &operands[3], &operands[4]);") 3424 3425;; %%% Kill me once multi-word ops are sane. 3426(define_insn "zero_extendsidi2_1" 3427 [(set (match_operand:DI 0 "nonimmediate_operand" "=r,?r,?o,?*Ym,?*y,?*Yi,*x") 3428 (zero_extend:DI 3429 (match_operand:SI 1 "nonimmediate_operand" "0,rm,r ,r ,m ,r ,m"))) 3430 (clobber (reg:CC FLAGS_REG))] 3431 "!TARGET_64BIT" 3432 "@ 3433 # 3434 # 3435 # 3436 movd\t{%1, %0|%0, %1} 3437 movd\t{%1, %0|%0, %1} 3438 %vmovd\t{%1, %0|%0, %1} 3439 %vmovd\t{%1, %0|%0, %1}" 3440 [(set_attr "isa" "*,*,*,*,*,*,sse2") 3441 (set_attr "type" "multi,multi,multi,mmxmov,mmxmov,ssemov,ssemov") 3442 (set_attr "prefix" "*,*,*,orig,orig,maybe_vex,maybe_vex") 3443 (set_attr "mode" "SI,SI,SI,DI,DI,TI,TI")]) 3444 3445(define_split 3446 [(set (match_operand:DI 0 "register_operand" "") 3447 (zero_extend:DI (match_operand:SI 1 "register_operand" ""))) 3448 (clobber (reg:CC FLAGS_REG))] 3449 "!TARGET_64BIT && reload_completed 3450 && true_regnum (operands[0]) == true_regnum (operands[1])" 3451 [(set (match_dup 4) (const_int 0))] 3452 "split_double_mode (DImode, &operands[0], 1, &operands[3], &operands[4]);") 3453 3454(define_split 3455 [(set (match_operand:DI 0 "nonimmediate_operand" "") 3456 (zero_extend:DI (match_operand:SI 1 "general_operand" ""))) 3457 (clobber (reg:CC FLAGS_REG))] 3458 "!TARGET_64BIT && reload_completed 3459 && !(MMX_REG_P (operands[0]) || SSE_REG_P (operands[0]))" 3460 [(set (match_dup 3) (match_dup 1)) 3461 (set (match_dup 4) (const_int 0))] 3462 "split_double_mode (DImode, &operands[0], 1, &operands[3], &operands[4]);") 3463 3464(define_insn "zero_extend<mode>di2" 3465 [(set (match_operand:DI 0 "register_operand" "=r") 3466 (zero_extend:DI 3467 (match_operand:SWI12 1 "nonimmediate_operand" "<r>m")))] 3468 "TARGET_64BIT" 3469 "movz{<imodesuffix>l|x}\t{%1, %k0|%k0, %1}" 3470 [(set_attr "type" "imovx") 3471 (set_attr "mode" "SI")]) 3472 3473(define_expand "zero_extendhisi2" 3474 [(set (match_operand:SI 0 "register_operand" "") 3475 (zero_extend:SI (match_operand:HI 1 "nonimmediate_operand" "")))] 3476 "" 3477{ 3478 if (TARGET_ZERO_EXTEND_WITH_AND && optimize_function_for_speed_p (cfun)) 3479 { 3480 operands[1] = force_reg (HImode, operands[1]); 3481 emit_insn (gen_zero_extendhisi2_and (operands[0], operands[1])); 3482 DONE; 3483 } 3484}) 3485 3486(define_insn_and_split "zero_extendhisi2_and" 3487 [(set (match_operand:SI 0 "register_operand" "=r") 3488 (zero_extend:SI (match_operand:HI 1 "register_operand" "0"))) 3489 (clobber (reg:CC FLAGS_REG))] 3490 "TARGET_ZERO_EXTEND_WITH_AND && optimize_function_for_speed_p (cfun)" 3491 "#" 3492 "&& reload_completed" 3493 [(parallel [(set (match_dup 0) (and:SI (match_dup 0) (const_int 65535))) 3494 (clobber (reg:CC FLAGS_REG))])] 3495 "" 3496 [(set_attr "type" "alu1") 3497 (set_attr "mode" "SI")]) 3498 3499(define_insn "*zero_extendhisi2_movzwl" 3500 [(set (match_operand:SI 0 "register_operand" "=r") 3501 (zero_extend:SI (match_operand:HI 1 "nonimmediate_operand" "rm")))] 3502 "!TARGET_ZERO_EXTEND_WITH_AND 3503 || optimize_function_for_size_p (cfun)" 3504 "movz{wl|x}\t{%1, %0|%0, %1}" 3505 [(set_attr "type" "imovx") 3506 (set_attr "mode" "SI")]) 3507 3508(define_expand "zero_extendqi<mode>2" 3509 [(parallel 3510 [(set (match_operand:SWI24 0 "register_operand" "") 3511 (zero_extend:SWI24 (match_operand:QI 1 "nonimmediate_operand" ""))) 3512 (clobber (reg:CC FLAGS_REG))])]) 3513 3514(define_insn "*zero_extendqi<mode>2_and" 3515 [(set (match_operand:SWI24 0 "register_operand" "=r,?&q") 3516 (zero_extend:SWI24 (match_operand:QI 1 "nonimmediate_operand" "0,qm"))) 3517 (clobber (reg:CC FLAGS_REG))] 3518 "TARGET_ZERO_EXTEND_WITH_AND && optimize_function_for_speed_p (cfun)" 3519 "#" 3520 [(set_attr "type" "alu1") 3521 (set_attr "mode" "<MODE>")]) 3522 3523;; When source and destination does not overlap, clear destination 3524;; first and then do the movb 3525(define_split 3526 [(set (match_operand:SWI24 0 "register_operand" "") 3527 (zero_extend:SWI24 (match_operand:QI 1 "nonimmediate_operand" ""))) 3528 (clobber (reg:CC FLAGS_REG))] 3529 "reload_completed 3530 && (TARGET_ZERO_EXTEND_WITH_AND && optimize_function_for_speed_p (cfun)) 3531 && ANY_QI_REG_P (operands[0]) 3532 && (ANY_QI_REG_P (operands[1]) || MEM_P (operands[1])) 3533 && !reg_overlap_mentioned_p (operands[0], operands[1])" 3534 [(set (strict_low_part (match_dup 2)) (match_dup 1))] 3535{ 3536 operands[2] = gen_lowpart (QImode, operands[0]); 3537 ix86_expand_clear (operands[0]); 3538}) 3539 3540(define_insn "*zero_extendqi<mode>2_movzbl_and" 3541 [(set (match_operand:SWI24 0 "register_operand" "=r,r") 3542 (zero_extend:SWI24 (match_operand:QI 1 "nonimmediate_operand" "qm,0"))) 3543 (clobber (reg:CC FLAGS_REG))] 3544 "!TARGET_ZERO_EXTEND_WITH_AND || optimize_function_for_size_p (cfun)" 3545 "#" 3546 [(set_attr "type" "imovx,alu1") 3547 (set_attr "mode" "<MODE>")]) 3548 3549;; For the movzbl case strip only the clobber 3550(define_split 3551 [(set (match_operand:SWI24 0 "register_operand" "") 3552 (zero_extend:SWI24 (match_operand:QI 1 "nonimmediate_operand" ""))) 3553 (clobber (reg:CC FLAGS_REG))] 3554 "reload_completed 3555 && (!TARGET_ZERO_EXTEND_WITH_AND || optimize_function_for_size_p (cfun)) 3556 && (!REG_P (operands[1]) || ANY_QI_REG_P (operands[1]))" 3557 [(set (match_dup 0) 3558 (zero_extend:SWI24 (match_dup 1)))]) 3559 3560; zero extend to SImode to avoid partial register stalls 3561(define_insn "*zero_extendqi<mode>2_movzbl" 3562 [(set (match_operand:SWI24 0 "register_operand" "=r") 3563 (zero_extend:SWI24 (match_operand:QI 1 "nonimmediate_operand" "qm")))] 3564 "reload_completed 3565 && (!TARGET_ZERO_EXTEND_WITH_AND || optimize_function_for_size_p (cfun))" 3566 "movz{bl|x}\t{%1, %k0|%k0, %1}" 3567 [(set_attr "type" "imovx") 3568 (set_attr "mode" "SI")]) 3569 3570;; Rest is handled by single and. 3571(define_split 3572 [(set (match_operand:SWI24 0 "register_operand" "") 3573 (zero_extend:SWI24 (match_operand:QI 1 "register_operand" ""))) 3574 (clobber (reg:CC FLAGS_REG))] 3575 "reload_completed 3576 && true_regnum (operands[0]) == true_regnum (operands[1])" 3577 [(parallel [(set (match_dup 0) (and:SWI24 (match_dup 0) (const_int 255))) 3578 (clobber (reg:CC FLAGS_REG))])]) 3579 3580;; Sign extension instructions 3581 3582(define_expand "extendsidi2" 3583 [(set (match_operand:DI 0 "register_operand" "") 3584 (sign_extend:DI (match_operand:SI 1 "register_operand" "")))] 3585 "" 3586{ 3587 if (!TARGET_64BIT) 3588 { 3589 emit_insn (gen_extendsidi2_1 (operands[0], operands[1])); 3590 DONE; 3591 } 3592}) 3593 3594(define_insn "*extendsidi2_rex64" 3595 [(set (match_operand:DI 0 "register_operand" "=*a,r") 3596 (sign_extend:DI (match_operand:SI 1 "nonimmediate_operand" "*0,rm")))] 3597 "TARGET_64BIT" 3598 "@ 3599 {cltq|cdqe} 3600 movs{lq|x}\t{%1, %0|%0, %1}" 3601 [(set_attr "type" "imovx") 3602 (set_attr "mode" "DI") 3603 (set_attr "prefix_0f" "0") 3604 (set_attr "modrm" "0,1")]) 3605 3606(define_insn "extendsidi2_1" 3607 [(set (match_operand:DI 0 "nonimmediate_operand" "=*A,r,?r,?*o") 3608 (sign_extend:DI (match_operand:SI 1 "register_operand" "0,0,r,r"))) 3609 (clobber (reg:CC FLAGS_REG)) 3610 (clobber (match_scratch:SI 2 "=X,X,X,&r"))] 3611 "!TARGET_64BIT" 3612 "#") 3613 3614;; Extend to memory case when source register does die. 3615(define_split 3616 [(set (match_operand:DI 0 "memory_operand" "") 3617 (sign_extend:DI (match_operand:SI 1 "register_operand" ""))) 3618 (clobber (reg:CC FLAGS_REG)) 3619 (clobber (match_operand:SI 2 "register_operand" ""))] 3620 "(reload_completed 3621 && dead_or_set_p (insn, operands[1]) 3622 && !reg_mentioned_p (operands[1], operands[0]))" 3623 [(set (match_dup 3) (match_dup 1)) 3624 (parallel [(set (match_dup 1) (ashiftrt:SI (match_dup 1) (const_int 31))) 3625 (clobber (reg:CC FLAGS_REG))]) 3626 (set (match_dup 4) (match_dup 1))] 3627 "split_double_mode (DImode, &operands[0], 1, &operands[3], &operands[4]);") 3628 3629;; Extend to memory case when source register does not die. 3630(define_split 3631 [(set (match_operand:DI 0 "memory_operand" "") 3632 (sign_extend:DI (match_operand:SI 1 "register_operand" ""))) 3633 (clobber (reg:CC FLAGS_REG)) 3634 (clobber (match_operand:SI 2 "register_operand" ""))] 3635 "reload_completed" 3636 [(const_int 0)] 3637{ 3638 split_double_mode (DImode, &operands[0], 1, &operands[3], &operands[4]); 3639 3640 emit_move_insn (operands[3], operands[1]); 3641 3642 /* Generate a cltd if possible and doing so it profitable. */ 3643 if ((optimize_function_for_size_p (cfun) || TARGET_USE_CLTD) 3644 && true_regnum (operands[1]) == AX_REG 3645 && true_regnum (operands[2]) == DX_REG) 3646 { 3647 emit_insn (gen_ashrsi3_cvt (operands[2], operands[1], GEN_INT (31))); 3648 } 3649 else 3650 { 3651 emit_move_insn (operands[2], operands[1]); 3652 emit_insn (gen_ashrsi3_cvt (operands[2], operands[2], GEN_INT (31))); 3653 } 3654 emit_move_insn (operands[4], operands[2]); 3655 DONE; 3656}) 3657 3658;; Extend to register case. Optimize case where source and destination 3659;; registers match and cases where we can use cltd. 3660(define_split 3661 [(set (match_operand:DI 0 "register_operand" "") 3662 (sign_extend:DI (match_operand:SI 1 "register_operand" ""))) 3663 (clobber (reg:CC FLAGS_REG)) 3664 (clobber (match_scratch:SI 2 ""))] 3665 "reload_completed" 3666 [(const_int 0)] 3667{ 3668 split_double_mode (DImode, &operands[0], 1, &operands[3], &operands[4]); 3669 3670 if (true_regnum (operands[3]) != true_regnum (operands[1])) 3671 emit_move_insn (operands[3], operands[1]); 3672 3673 /* Generate a cltd if possible and doing so it profitable. */ 3674 if ((optimize_function_for_size_p (cfun) || TARGET_USE_CLTD) 3675 && true_regnum (operands[3]) == AX_REG 3676 && true_regnum (operands[4]) == DX_REG) 3677 { 3678 emit_insn (gen_ashrsi3_cvt (operands[4], operands[3], GEN_INT (31))); 3679 DONE; 3680 } 3681 3682 if (true_regnum (operands[4]) != true_regnum (operands[1])) 3683 emit_move_insn (operands[4], operands[1]); 3684 3685 emit_insn (gen_ashrsi3_cvt (operands[4], operands[4], GEN_INT (31))); 3686 DONE; 3687}) 3688 3689(define_insn "extend<mode>di2" 3690 [(set (match_operand:DI 0 "register_operand" "=r") 3691 (sign_extend:DI 3692 (match_operand:SWI12 1 "nonimmediate_operand" "<r>m")))] 3693 "TARGET_64BIT" 3694 "movs{<imodesuffix>q|x}\t{%1, %0|%0, %1}" 3695 [(set_attr "type" "imovx") 3696 (set_attr "mode" "DI")]) 3697 3698(define_insn "extendhisi2" 3699 [(set (match_operand:SI 0 "register_operand" "=*a,r") 3700 (sign_extend:SI (match_operand:HI 1 "nonimmediate_operand" "*0,rm")))] 3701 "" 3702{ 3703 switch (get_attr_prefix_0f (insn)) 3704 { 3705 case 0: 3706 return "{cwtl|cwde}"; 3707 default: 3708 return "movs{wl|x}\t{%1, %0|%0, %1}"; 3709 } 3710} 3711 [(set_attr "type" "imovx") 3712 (set_attr "mode" "SI") 3713 (set (attr "prefix_0f") 3714 ;; movsx is short decodable while cwtl is vector decoded. 3715 (if_then_else (and (eq_attr "cpu" "!k6") 3716 (eq_attr "alternative" "0")) 3717 (const_string "0") 3718 (const_string "1"))) 3719 (set (attr "modrm") 3720 (if_then_else (eq_attr "prefix_0f" "0") 3721 (const_string "0") 3722 (const_string "1")))]) 3723 3724(define_insn "*extendhisi2_zext" 3725 [(set (match_operand:DI 0 "register_operand" "=*a,r") 3726 (zero_extend:DI 3727 (sign_extend:SI 3728 (match_operand:HI 1 "nonimmediate_operand" "*0,rm"))))] 3729 "TARGET_64BIT" 3730{ 3731 switch (get_attr_prefix_0f (insn)) 3732 { 3733 case 0: 3734 return "{cwtl|cwde}"; 3735 default: 3736 return "movs{wl|x}\t{%1, %k0|%k0, %1}"; 3737 } 3738} 3739 [(set_attr "type" "imovx") 3740 (set_attr "mode" "SI") 3741 (set (attr "prefix_0f") 3742 ;; movsx is short decodable while cwtl is vector decoded. 3743 (if_then_else (and (eq_attr "cpu" "!k6") 3744 (eq_attr "alternative" "0")) 3745 (const_string "0") 3746 (const_string "1"))) 3747 (set (attr "modrm") 3748 (if_then_else (eq_attr "prefix_0f" "0") 3749 (const_string "0") 3750 (const_string "1")))]) 3751 3752(define_insn "extendqisi2" 3753 [(set (match_operand:SI 0 "register_operand" "=r") 3754 (sign_extend:SI (match_operand:QI 1 "nonimmediate_operand" "qm")))] 3755 "" 3756 "movs{bl|x}\t{%1, %0|%0, %1}" 3757 [(set_attr "type" "imovx") 3758 (set_attr "mode" "SI")]) 3759 3760(define_insn "*extendqisi2_zext" 3761 [(set (match_operand:DI 0 "register_operand" "=r") 3762 (zero_extend:DI 3763 (sign_extend:SI (match_operand:QI 1 "nonimmediate_operand" "qm"))))] 3764 "TARGET_64BIT" 3765 "movs{bl|x}\t{%1, %k0|%k0, %1}" 3766 [(set_attr "type" "imovx") 3767 (set_attr "mode" "SI")]) 3768 3769(define_insn "extendqihi2" 3770 [(set (match_operand:HI 0 "register_operand" "=*a,r") 3771 (sign_extend:HI (match_operand:QI 1 "nonimmediate_operand" "*0,qm")))] 3772 "" 3773{ 3774 switch (get_attr_prefix_0f (insn)) 3775 { 3776 case 0: 3777 return "{cbtw|cbw}"; 3778 default: 3779 return "movs{bw|x}\t{%1, %0|%0, %1}"; 3780 } 3781} 3782 [(set_attr "type" "imovx") 3783 (set_attr "mode" "HI") 3784 (set (attr "prefix_0f") 3785 ;; movsx is short decodable while cwtl is vector decoded. 3786 (if_then_else (and (eq_attr "cpu" "!k6") 3787 (eq_attr "alternative" "0")) 3788 (const_string "0") 3789 (const_string "1"))) 3790 (set (attr "modrm") 3791 (if_then_else (eq_attr "prefix_0f" "0") 3792 (const_string "0") 3793 (const_string "1")))]) 3794 3795;; Conversions between float and double. 3796 3797;; These are all no-ops in the model used for the 80387. 3798;; So just emit moves. 3799 3800;; %%% Kill these when call knows how to work out a DFmode push earlier. 3801(define_split 3802 [(set (match_operand:DF 0 "push_operand" "") 3803 (float_extend:DF (match_operand:SF 1 "fp_register_operand" "")))] 3804 "reload_completed" 3805 [(set (reg:P SP_REG) (plus:P (reg:P SP_REG) (const_int -8))) 3806 (set (mem:DF (reg:P SP_REG)) (float_extend:DF (match_dup 1)))]) 3807 3808(define_split 3809 [(set (match_operand:XF 0 "push_operand" "") 3810 (float_extend:XF (match_operand:MODEF 1 "fp_register_operand" "")))] 3811 "reload_completed" 3812 [(set (reg:P SP_REG) (plus:P (reg:P SP_REG) (match_dup 2))) 3813 (set (mem:XF (reg:P SP_REG)) (float_extend:XF (match_dup 1)))] 3814 "operands[2] = GEN_INT (-GET_MODE_SIZE (XFmode));") 3815 3816(define_expand "extendsfdf2" 3817 [(set (match_operand:DF 0 "nonimmediate_operand" "") 3818 (float_extend:DF (match_operand:SF 1 "general_operand" "")))] 3819 "TARGET_80387 || (TARGET_SSE2 && TARGET_SSE_MATH)" 3820{ 3821 /* ??? Needed for compress_float_constant since all fp constants 3822 are TARGET_LEGITIMATE_CONSTANT_P. */ 3823 if (GET_CODE (operands[1]) == CONST_DOUBLE) 3824 { 3825 if ((!TARGET_SSE2 || TARGET_MIX_SSE_I387) 3826 && standard_80387_constant_p (operands[1]) > 0) 3827 { 3828 operands[1] = simplify_const_unary_operation 3829 (FLOAT_EXTEND, DFmode, operands[1], SFmode); 3830 emit_move_insn_1 (operands[0], operands[1]); 3831 DONE; 3832 } 3833 operands[1] = validize_mem (force_const_mem (SFmode, operands[1])); 3834 } 3835}) 3836 3837/* For converting SF(xmm2) to DF(xmm1), use the following code instead of 3838 cvtss2sd: 3839 unpcklps xmm2,xmm2 ; packed conversion might crash on signaling NaNs 3840 cvtps2pd xmm2,xmm1 3841 We do the conversion post reload to avoid producing of 128bit spills 3842 that might lead to ICE on 32bit target. The sequence unlikely combine 3843 anyway. */ 3844(define_split 3845 [(set (match_operand:DF 0 "register_operand" "") 3846 (float_extend:DF 3847 (match_operand:SF 1 "nonimmediate_operand" "")))] 3848 "TARGET_USE_VECTOR_FP_CONVERTS 3849 && optimize_insn_for_speed_p () 3850 && reload_completed && SSE_REG_P (operands[0])" 3851 [(set (match_dup 2) 3852 (float_extend:V2DF 3853 (vec_select:V2SF 3854 (match_dup 3) 3855 (parallel [(const_int 0) (const_int 1)]))))] 3856{ 3857 operands[2] = simplify_gen_subreg (V2DFmode, operands[0], DFmode, 0); 3858 operands[3] = simplify_gen_subreg (V4SFmode, operands[0], DFmode, 0); 3859 /* Use movss for loading from memory, unpcklps reg, reg for registers. 3860 Try to avoid move when unpacking can be done in source. */ 3861 if (REG_P (operands[1])) 3862 { 3863 /* If it is unsafe to overwrite upper half of source, we need 3864 to move to destination and unpack there. */ 3865 if ((ORIGINAL_REGNO (operands[1]) < FIRST_PSEUDO_REGISTER 3866 || PSEUDO_REGNO_BYTES (ORIGINAL_REGNO (operands[1])) > 4) 3867 && true_regnum (operands[0]) != true_regnum (operands[1])) 3868 { 3869 rtx tmp = gen_rtx_REG (SFmode, true_regnum (operands[0])); 3870 emit_move_insn (tmp, operands[1]); 3871 } 3872 else 3873 operands[3] = simplify_gen_subreg (V4SFmode, operands[1], SFmode, 0); 3874 emit_insn (gen_vec_interleave_lowv4sf (operands[3], operands[3], 3875 operands[3])); 3876 } 3877 else 3878 emit_insn (gen_vec_setv4sf_0 (operands[3], 3879 CONST0_RTX (V4SFmode), operands[1])); 3880}) 3881 3882(define_insn "*extendsfdf2_mixed" 3883 [(set (match_operand:DF 0 "nonimmediate_operand" "=f,m,x") 3884 (float_extend:DF 3885 (match_operand:SF 1 "nonimmediate_operand" "fm,f,xm")))] 3886 "TARGET_SSE2 && TARGET_MIX_SSE_I387" 3887{ 3888 switch (which_alternative) 3889 { 3890 case 0: 3891 case 1: 3892 return output_387_reg_move (insn, operands); 3893 3894 case 2: 3895 return "%vcvtss2sd\t{%1, %d0|%d0, %1}"; 3896 3897 default: 3898 gcc_unreachable (); 3899 } 3900} 3901 [(set_attr "type" "fmov,fmov,ssecvt") 3902 (set_attr "prefix" "orig,orig,maybe_vex") 3903 (set_attr "mode" "SF,XF,DF")]) 3904 3905(define_insn "*extendsfdf2_sse" 3906 [(set (match_operand:DF 0 "nonimmediate_operand" "=x") 3907 (float_extend:DF (match_operand:SF 1 "nonimmediate_operand" "xm")))] 3908 "TARGET_SSE2 && TARGET_SSE_MATH" 3909 "%vcvtss2sd\t{%1, %d0|%d0, %1}" 3910 [(set_attr "type" "ssecvt") 3911 (set_attr "prefix" "maybe_vex") 3912 (set_attr "mode" "DF")]) 3913 3914(define_insn "*extendsfdf2_i387" 3915 [(set (match_operand:DF 0 "nonimmediate_operand" "=f,m") 3916 (float_extend:DF (match_operand:SF 1 "nonimmediate_operand" "fm,f")))] 3917 "TARGET_80387" 3918 "* return output_387_reg_move (insn, operands);" 3919 [(set_attr "type" "fmov") 3920 (set_attr "mode" "SF,XF")]) 3921 3922(define_expand "extend<mode>xf2" 3923 [(set (match_operand:XF 0 "nonimmediate_operand" "") 3924 (float_extend:XF (match_operand:MODEF 1 "general_operand" "")))] 3925 "TARGET_80387" 3926{ 3927 /* ??? Needed for compress_float_constant since all fp constants 3928 are TARGET_LEGITIMATE_CONSTANT_P. */ 3929 if (GET_CODE (operands[1]) == CONST_DOUBLE) 3930 { 3931 if (standard_80387_constant_p (operands[1]) > 0) 3932 { 3933 operands[1] = simplify_const_unary_operation 3934 (FLOAT_EXTEND, XFmode, operands[1], <MODE>mode); 3935 emit_move_insn_1 (operands[0], operands[1]); 3936 DONE; 3937 } 3938 operands[1] = validize_mem (force_const_mem (<MODE>mode, operands[1])); 3939 } 3940}) 3941 3942(define_insn "*extend<mode>xf2_i387" 3943 [(set (match_operand:XF 0 "nonimmediate_operand" "=f,m") 3944 (float_extend:XF 3945 (match_operand:MODEF 1 "nonimmediate_operand" "fm,f")))] 3946 "TARGET_80387" 3947 "* return output_387_reg_move (insn, operands);" 3948 [(set_attr "type" "fmov") 3949 (set_attr "mode" "<MODE>,XF")]) 3950 3951;; %%% This seems bad bad news. 3952;; This cannot output into an f-reg because there is no way to be sure 3953;; of truncating in that case. Otherwise this is just like a simple move 3954;; insn. So we pretend we can output to a reg in order to get better 3955;; register preferencing, but we really use a stack slot. 3956 3957;; Conversion from DFmode to SFmode. 3958 3959(define_expand "truncdfsf2" 3960 [(set (match_operand:SF 0 "nonimmediate_operand" "") 3961 (float_truncate:SF 3962 (match_operand:DF 1 "nonimmediate_operand" "")))] 3963 "TARGET_80387 || (TARGET_SSE2 && TARGET_SSE_MATH)" 3964{ 3965 if (TARGET_SSE2 && TARGET_SSE_MATH && !TARGET_MIX_SSE_I387) 3966 ; 3967 else if (flag_unsafe_math_optimizations) 3968 ; 3969 else 3970 { 3971 enum ix86_stack_slot slot = (virtuals_instantiated 3972 ? SLOT_TEMP 3973 : SLOT_VIRTUAL); 3974 rtx temp = assign_386_stack_local (SFmode, slot); 3975 emit_insn (gen_truncdfsf2_with_temp (operands[0], operands[1], temp)); 3976 DONE; 3977 } 3978}) 3979 3980/* For converting DF(xmm2) to SF(xmm1), use the following code instead of 3981 cvtsd2ss: 3982 unpcklpd xmm2,xmm2 ; packed conversion might crash on signaling NaNs 3983 cvtpd2ps xmm2,xmm1 3984 We do the conversion post reload to avoid producing of 128bit spills 3985 that might lead to ICE on 32bit target. The sequence unlikely combine 3986 anyway. */ 3987(define_split 3988 [(set (match_operand:SF 0 "register_operand" "") 3989 (float_truncate:SF 3990 (match_operand:DF 1 "nonimmediate_operand" "")))] 3991 "TARGET_USE_VECTOR_FP_CONVERTS 3992 && optimize_insn_for_speed_p () 3993 && reload_completed && SSE_REG_P (operands[0])" 3994 [(set (match_dup 2) 3995 (vec_concat:V4SF 3996 (float_truncate:V2SF 3997 (match_dup 4)) 3998 (match_dup 3)))] 3999{ 4000 operands[2] = simplify_gen_subreg (V4SFmode, operands[0], SFmode, 0); 4001 operands[3] = CONST0_RTX (V2SFmode); 4002 operands[4] = simplify_gen_subreg (V2DFmode, operands[0], SFmode, 0); 4003 /* Use movsd for loading from memory, unpcklpd for registers. 4004 Try to avoid move when unpacking can be done in source, or SSE3 4005 movddup is available. */ 4006 if (REG_P (operands[1])) 4007 { 4008 if (!TARGET_SSE3 4009 && true_regnum (operands[0]) != true_regnum (operands[1]) 4010 && (ORIGINAL_REGNO (operands[1]) < FIRST_PSEUDO_REGISTER 4011 || PSEUDO_REGNO_BYTES (ORIGINAL_REGNO (operands[1])) > 8)) 4012 { 4013 rtx tmp = simplify_gen_subreg (DFmode, operands[0], SFmode, 0); 4014 emit_move_insn (tmp, operands[1]); 4015 operands[1] = tmp; 4016 } 4017 else if (!TARGET_SSE3) 4018 operands[4] = simplify_gen_subreg (V2DFmode, operands[1], DFmode, 0); 4019 emit_insn (gen_vec_dupv2df (operands[4], operands[1])); 4020 } 4021 else 4022 emit_insn (gen_sse2_loadlpd (operands[4], 4023 CONST0_RTX (V2DFmode), operands[1])); 4024}) 4025 4026(define_expand "truncdfsf2_with_temp" 4027 [(parallel [(set (match_operand:SF 0 "" "") 4028 (float_truncate:SF (match_operand:DF 1 "" ""))) 4029 (clobber (match_operand:SF 2 "" ""))])]) 4030 4031(define_insn "*truncdfsf_fast_mixed" 4032 [(set (match_operand:SF 0 "nonimmediate_operand" "=fm,x") 4033 (float_truncate:SF 4034 (match_operand:DF 1 "nonimmediate_operand" "f ,xm")))] 4035 "TARGET_SSE2 && TARGET_MIX_SSE_I387 && flag_unsafe_math_optimizations" 4036{ 4037 switch (which_alternative) 4038 { 4039 case 0: 4040 return output_387_reg_move (insn, operands); 4041 case 1: 4042 return "%vcvtsd2ss\t{%1, %d0|%d0, %1}"; 4043 default: 4044 gcc_unreachable (); 4045 } 4046} 4047 [(set_attr "type" "fmov,ssecvt") 4048 (set_attr "prefix" "orig,maybe_vex") 4049 (set_attr "mode" "SF")]) 4050 4051;; Yes, this one doesn't depend on flag_unsafe_math_optimizations, 4052;; because nothing we do here is unsafe. 4053(define_insn "*truncdfsf_fast_sse" 4054 [(set (match_operand:SF 0 "nonimmediate_operand" "=x") 4055 (float_truncate:SF 4056 (match_operand:DF 1 "nonimmediate_operand" "xm")))] 4057 "TARGET_SSE2 && TARGET_SSE_MATH" 4058 "%vcvtsd2ss\t{%1, %d0|%d0, %1}" 4059 [(set_attr "type" "ssecvt") 4060 (set_attr "prefix" "maybe_vex") 4061 (set_attr "mode" "SF")]) 4062 4063(define_insn "*truncdfsf_fast_i387" 4064 [(set (match_operand:SF 0 "nonimmediate_operand" "=fm") 4065 (float_truncate:SF 4066 (match_operand:DF 1 "nonimmediate_operand" "f")))] 4067 "TARGET_80387 && flag_unsafe_math_optimizations" 4068 "* return output_387_reg_move (insn, operands);" 4069 [(set_attr "type" "fmov") 4070 (set_attr "mode" "SF")]) 4071 4072(define_insn "*truncdfsf_mixed" 4073 [(set (match_operand:SF 0 "nonimmediate_operand" "=m,x ,?f,?x,?*r") 4074 (float_truncate:SF 4075 (match_operand:DF 1 "nonimmediate_operand" "f ,xm,f ,f ,f"))) 4076 (clobber (match_operand:SF 2 "memory_operand" "=X,X ,m ,m ,m"))] 4077 "TARGET_MIX_SSE_I387" 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 4086 default: 4087 return "#"; 4088 } 4089} 4090 [(set_attr "isa" "*,sse2,*,*,*") 4091 (set_attr "type" "fmov,ssecvt,multi,multi,multi") 4092 (set_attr "unit" "*,*,i387,i387,i387") 4093 (set_attr "prefix" "orig,maybe_vex,orig,orig,orig") 4094 (set_attr "mode" "SF")]) 4095 4096(define_insn "*truncdfsf_i387" 4097 [(set (match_operand:SF 0 "nonimmediate_operand" "=m,?f,?x,?*r") 4098 (float_truncate:SF 4099 (match_operand:DF 1 "nonimmediate_operand" "f ,f ,f ,f"))) 4100 (clobber (match_operand:SF 2 "memory_operand" "=X,m ,m ,m"))] 4101 "TARGET_80387" 4102{ 4103 switch (which_alternative) 4104 { 4105 case 0: 4106 return output_387_reg_move (insn, operands); 4107 4108 default: 4109 return "#"; 4110 } 4111} 4112 [(set_attr "type" "fmov,multi,multi,multi") 4113 (set_attr "unit" "*,i387,i387,i387") 4114 (set_attr "mode" "SF")]) 4115 4116(define_insn "*truncdfsf2_i387_1" 4117 [(set (match_operand:SF 0 "memory_operand" "=m") 4118 (float_truncate:SF 4119 (match_operand:DF 1 "register_operand" "f")))] 4120 "TARGET_80387 4121 && !(TARGET_SSE2 && TARGET_SSE_MATH) 4122 && !TARGET_MIX_SSE_I387" 4123 "* return output_387_reg_move (insn, operands);" 4124 [(set_attr "type" "fmov") 4125 (set_attr "mode" "SF")]) 4126 4127(define_split 4128 [(set (match_operand:SF 0 "register_operand" "") 4129 (float_truncate:SF 4130 (match_operand:DF 1 "fp_register_operand" ""))) 4131 (clobber (match_operand 2 "" ""))] 4132 "reload_completed" 4133 [(set (match_dup 2) (match_dup 1)) 4134 (set (match_dup 0) (match_dup 2))] 4135 "operands[1] = gen_rtx_REG (SFmode, true_regnum (operands[1]));") 4136 4137;; Conversion from XFmode to {SF,DF}mode 4138 4139(define_expand "truncxf<mode>2" 4140 [(parallel [(set (match_operand:MODEF 0 "nonimmediate_operand" "") 4141 (float_truncate:MODEF 4142 (match_operand:XF 1 "register_operand" ""))) 4143 (clobber (match_dup 2))])] 4144 "TARGET_80387" 4145{ 4146 if (flag_unsafe_math_optimizations) 4147 { 4148 rtx reg = REG_P (operands[0]) ? operands[0] : gen_reg_rtx (<MODE>mode); 4149 emit_insn (gen_truncxf<mode>2_i387_noop (reg, operands[1])); 4150 if (reg != operands[0]) 4151 emit_move_insn (operands[0], reg); 4152 DONE; 4153 } 4154 else 4155 { 4156 enum ix86_stack_slot slot = (virtuals_instantiated 4157 ? SLOT_TEMP 4158 : SLOT_VIRTUAL); 4159 operands[2] = assign_386_stack_local (<MODE>mode, slot); 4160 } 4161}) 4162 4163(define_insn "*truncxfsf2_mixed" 4164 [(set (match_operand:SF 0 "nonimmediate_operand" "=m,?f,?x,?*r") 4165 (float_truncate:SF 4166 (match_operand:XF 1 "register_operand" "f ,f ,f ,f"))) 4167 (clobber (match_operand:SF 2 "memory_operand" "=X,m ,m ,m"))] 4168 "TARGET_80387" 4169{ 4170 gcc_assert (!which_alternative); 4171 return output_387_reg_move (insn, operands); 4172} 4173 [(set_attr "type" "fmov,multi,multi,multi") 4174 (set_attr "unit" "*,i387,i387,i387") 4175 (set_attr "mode" "SF")]) 4176 4177(define_insn "*truncxfdf2_mixed" 4178 [(set (match_operand:DF 0 "nonimmediate_operand" "=m,?f,?x,?*r") 4179 (float_truncate:DF 4180 (match_operand:XF 1 "register_operand" "f ,f ,f ,f"))) 4181 (clobber (match_operand:DF 2 "memory_operand" "=X,m ,m ,m"))] 4182 "TARGET_80387" 4183{ 4184 gcc_assert (!which_alternative); 4185 return output_387_reg_move (insn, operands); 4186} 4187 [(set_attr "isa" "*,*,sse2,*") 4188 (set_attr "type" "fmov,multi,multi,multi") 4189 (set_attr "unit" "*,i387,i387,i387") 4190 (set_attr "mode" "DF")]) 4191 4192(define_insn "truncxf<mode>2_i387_noop" 4193 [(set (match_operand:MODEF 0 "register_operand" "=f") 4194 (float_truncate:MODEF 4195 (match_operand:XF 1 "register_operand" "f")))] 4196 "TARGET_80387 && flag_unsafe_math_optimizations" 4197 "* return output_387_reg_move (insn, operands);" 4198 [(set_attr "type" "fmov") 4199 (set_attr "mode" "<MODE>")]) 4200 4201(define_insn "*truncxf<mode>2_i387" 4202 [(set (match_operand:MODEF 0 "memory_operand" "=m") 4203 (float_truncate:MODEF 4204 (match_operand:XF 1 "register_operand" "f")))] 4205 "TARGET_80387" 4206 "* return output_387_reg_move (insn, operands);" 4207 [(set_attr "type" "fmov") 4208 (set_attr "mode" "<MODE>")]) 4209 4210(define_split 4211 [(set (match_operand:MODEF 0 "register_operand" "") 4212 (float_truncate:MODEF 4213 (match_operand:XF 1 "register_operand" ""))) 4214 (clobber (match_operand:MODEF 2 "memory_operand" ""))] 4215 "TARGET_80387 && reload_completed" 4216 [(set (match_dup 2) (float_truncate:MODEF (match_dup 1))) 4217 (set (match_dup 0) (match_dup 2))]) 4218 4219(define_split 4220 [(set (match_operand:MODEF 0 "memory_operand" "") 4221 (float_truncate:MODEF 4222 (match_operand:XF 1 "register_operand" ""))) 4223 (clobber (match_operand:MODEF 2 "memory_operand" ""))] 4224 "TARGET_80387" 4225 [(set (match_dup 0) (float_truncate:MODEF (match_dup 1)))]) 4226 4227;; Signed conversion to DImode. 4228 4229(define_expand "fix_truncxfdi2" 4230 [(parallel [(set (match_operand:DI 0 "nonimmediate_operand" "") 4231 (fix:DI (match_operand:XF 1 "register_operand" ""))) 4232 (clobber (reg:CC FLAGS_REG))])] 4233 "TARGET_80387" 4234{ 4235 if (TARGET_FISTTP) 4236 { 4237 emit_insn (gen_fix_truncdi_fisttp_i387_1 (operands[0], operands[1])); 4238 DONE; 4239 } 4240}) 4241 4242(define_expand "fix_trunc<mode>di2" 4243 [(parallel [(set (match_operand:DI 0 "nonimmediate_operand" "") 4244 (fix:DI (match_operand:MODEF 1 "register_operand" ""))) 4245 (clobber (reg:CC FLAGS_REG))])] 4246 "TARGET_80387 || (TARGET_64BIT && SSE_FLOAT_MODE_P (<MODE>mode))" 4247{ 4248 if (TARGET_FISTTP 4249 && !(TARGET_64BIT && SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)) 4250 { 4251 emit_insn (gen_fix_truncdi_fisttp_i387_1 (operands[0], operands[1])); 4252 DONE; 4253 } 4254 if (TARGET_64BIT && SSE_FLOAT_MODE_P (<MODE>mode)) 4255 { 4256 rtx out = REG_P (operands[0]) ? operands[0] : gen_reg_rtx (DImode); 4257 emit_insn (gen_fix_trunc<mode>di_sse (out, operands[1])); 4258 if (out != operands[0]) 4259 emit_move_insn (operands[0], out); 4260 DONE; 4261 } 4262}) 4263 4264;; Signed conversion to SImode. 4265 4266(define_expand "fix_truncxfsi2" 4267 [(parallel [(set (match_operand:SI 0 "nonimmediate_operand" "") 4268 (fix:SI (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_truncsi_fisttp_i387_1 (operands[0], operands[1])); 4275 DONE; 4276 } 4277}) 4278 4279(define_expand "fix_trunc<mode>si2" 4280 [(parallel [(set (match_operand:SI 0 "nonimmediate_operand" "") 4281 (fix:SI (match_operand:MODEF 1 "register_operand" ""))) 4282 (clobber (reg:CC FLAGS_REG))])] 4283 "TARGET_80387 || SSE_FLOAT_MODE_P (<MODE>mode)" 4284{ 4285 if (TARGET_FISTTP 4286 && !(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)) 4287 { 4288 emit_insn (gen_fix_truncsi_fisttp_i387_1 (operands[0], operands[1])); 4289 DONE; 4290 } 4291 if (SSE_FLOAT_MODE_P (<MODE>mode)) 4292 { 4293 rtx out = REG_P (operands[0]) ? operands[0] : gen_reg_rtx (SImode); 4294 emit_insn (gen_fix_trunc<mode>si_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 HImode. 4302 4303(define_expand "fix_trunc<mode>hi2" 4304 [(parallel [(set (match_operand:HI 0 "nonimmediate_operand" "") 4305 (fix:HI (match_operand:X87MODEF 1 "register_operand" ""))) 4306 (clobber (reg:CC FLAGS_REG))])] 4307 "TARGET_80387 4308 && !(SSE_FLOAT_MODE_P (<MODE>mode) && (!TARGET_FISTTP || TARGET_SSE_MATH))" 4309{ 4310 if (TARGET_FISTTP) 4311 { 4312 emit_insn (gen_fix_trunchi_fisttp_i387_1 (operands[0], operands[1])); 4313 DONE; 4314 } 4315}) 4316 4317;; Unsigned conversion to SImode. 4318 4319(define_expand "fixuns_trunc<mode>si2" 4320 [(parallel 4321 [(set (match_operand:SI 0 "register_operand" "") 4322 (unsigned_fix:SI 4323 (match_operand:MODEF 1 "nonimmediate_operand" ""))) 4324 (use (match_dup 2)) 4325 (clobber (match_scratch:<ssevecmode> 3 "")) 4326 (clobber (match_scratch:<ssevecmode> 4 ""))])] 4327 "!TARGET_64BIT && TARGET_SSE2 && TARGET_SSE_MATH" 4328{ 4329 enum machine_mode mode = <MODE>mode; 4330 enum machine_mode vecmode = <ssevecmode>mode; 4331 REAL_VALUE_TYPE TWO31r; 4332 rtx two31; 4333 4334 if (optimize_insn_for_size_p ()) 4335 FAIL; 4336 4337 real_ldexp (&TWO31r, &dconst1, 31); 4338 two31 = const_double_from_real_value (TWO31r, mode); 4339 two31 = ix86_build_const_vector (vecmode, true, two31); 4340 operands[2] = force_reg (vecmode, two31); 4341}) 4342 4343(define_insn_and_split "*fixuns_trunc<mode>_1" 4344 [(set (match_operand:SI 0 "register_operand" "=&x,&x") 4345 (unsigned_fix:SI 4346 (match_operand:MODEF 3 "nonimmediate_operand" "xm,xm"))) 4347 (use (match_operand:<ssevecmode> 4 "nonimmediate_operand" "m,x")) 4348 (clobber (match_scratch:<ssevecmode> 1 "=x,&x")) 4349 (clobber (match_scratch:<ssevecmode> 2 "=x,x"))] 4350 "!TARGET_64BIT && TARGET_SSE2 && TARGET_SSE_MATH 4351 && optimize_function_for_speed_p (cfun)" 4352 "#" 4353 "&& reload_completed" 4354 [(const_int 0)] 4355{ 4356 ix86_split_convert_uns_si_sse (operands); 4357 DONE; 4358}) 4359 4360;; Unsigned conversion to HImode. 4361;; Without these patterns, we'll try the unsigned SI conversion which 4362;; is complex for SSE, rather than the signed SI conversion, which isn't. 4363 4364(define_expand "fixuns_trunc<mode>hi2" 4365 [(set (match_dup 2) 4366 (fix:SI (match_operand:MODEF 1 "nonimmediate_operand" ""))) 4367 (set (match_operand:HI 0 "nonimmediate_operand" "") 4368 (subreg:HI (match_dup 2) 0))] 4369 "SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH" 4370 "operands[2] = gen_reg_rtx (SImode);") 4371 4372;; When SSE is available, it is always faster to use it! 4373(define_insn "fix_trunc<mode>di_sse" 4374 [(set (match_operand:DI 0 "register_operand" "=r,r") 4375 (fix:DI (match_operand:MODEF 1 "nonimmediate_operand" "x,m")))] 4376 "TARGET_64BIT && SSE_FLOAT_MODE_P (<MODE>mode) 4377 && (!TARGET_FISTTP || TARGET_SSE_MATH)" 4378 "%vcvtt<ssemodesuffix>2si{q}\t{%1, %0|%0, %1}" 4379 [(set_attr "type" "sseicvt") 4380 (set_attr "prefix" "maybe_vex") 4381 (set_attr "prefix_rex" "1") 4382 (set_attr "mode" "<MODE>") 4383 (set_attr "athlon_decode" "double,vector") 4384 (set_attr "amdfam10_decode" "double,double") 4385 (set_attr "bdver1_decode" "double,double")]) 4386 4387(define_insn "fix_trunc<mode>si_sse" 4388 [(set (match_operand:SI 0 "register_operand" "=r,r") 4389 (fix:SI (match_operand:MODEF 1 "nonimmediate_operand" "x,m")))] 4390 "SSE_FLOAT_MODE_P (<MODE>mode) 4391 && (!TARGET_FISTTP || TARGET_SSE_MATH)" 4392 "%vcvtt<ssemodesuffix>2si\t{%1, %0|%0, %1}" 4393 [(set_attr "type" "sseicvt") 4394 (set_attr "prefix" "maybe_vex") 4395 (set_attr "mode" "<MODE>") 4396 (set_attr "athlon_decode" "double,vector") 4397 (set_attr "amdfam10_decode" "double,double") 4398 (set_attr "bdver1_decode" "double,double")]) 4399 4400;; Shorten x87->SSE reload sequences of fix_trunc?f?i_sse patterns. 4401(define_peephole2 4402 [(set (match_operand:MODEF 0 "register_operand" "") 4403 (match_operand:MODEF 1 "memory_operand" "")) 4404 (set (match_operand:SWI48x 2 "register_operand" "") 4405 (fix:SWI48x (match_dup 0)))] 4406 "TARGET_SHORTEN_X87_SSE 4407 && !(TARGET_AVOID_VECTOR_DECODE && optimize_insn_for_speed_p ()) 4408 && peep2_reg_dead_p (2, operands[0])" 4409 [(set (match_dup 2) (fix:SWI48x (match_dup 1)))]) 4410 4411;; Avoid vector decoded forms of the instruction. 4412(define_peephole2 4413 [(match_scratch:DF 2 "x") 4414 (set (match_operand:SWI48x 0 "register_operand" "") 4415 (fix:SWI48x (match_operand:DF 1 "memory_operand" "")))] 4416 "TARGET_SSE2 && TARGET_AVOID_VECTOR_DECODE && optimize_insn_for_speed_p ()" 4417 [(set (match_dup 2) (match_dup 1)) 4418 (set (match_dup 0) (fix:SWI48x (match_dup 2)))]) 4419 4420(define_peephole2 4421 [(match_scratch:SF 2 "x") 4422 (set (match_operand:SWI48x 0 "register_operand" "") 4423 (fix:SWI48x (match_operand:SF 1 "memory_operand" "")))] 4424 "TARGET_AVOID_VECTOR_DECODE && optimize_insn_for_speed_p ()" 4425 [(set (match_dup 2) (match_dup 1)) 4426 (set (match_dup 0) (fix:SWI48x (match_dup 2)))]) 4427 4428(define_insn_and_split "fix_trunc<mode>_fisttp_i387_1" 4429 [(set (match_operand:SWI248x 0 "nonimmediate_operand" "") 4430 (fix:SWI248x (match_operand 1 "register_operand" "")))] 4431 "X87_FLOAT_MODE_P (GET_MODE (operands[1])) 4432 && TARGET_FISTTP 4433 && !((SSE_FLOAT_MODE_P (GET_MODE (operands[1])) 4434 && (TARGET_64BIT || <MODE>mode != DImode)) 4435 && TARGET_SSE_MATH) 4436 && can_create_pseudo_p ()" 4437 "#" 4438 "&& 1" 4439 [(const_int 0)] 4440{ 4441 if (memory_operand (operands[0], VOIDmode)) 4442 emit_insn (gen_fix_trunc<mode>_i387_fisttp (operands[0], operands[1])); 4443 else 4444 { 4445 operands[2] = assign_386_stack_local (<MODE>mode, SLOT_TEMP); 4446 emit_insn (gen_fix_trunc<mode>_i387_fisttp_with_temp (operands[0], 4447 operands[1], 4448 operands[2])); 4449 } 4450 DONE; 4451} 4452 [(set_attr "type" "fisttp") 4453 (set_attr "mode" "<MODE>")]) 4454 4455(define_insn "fix_trunc<mode>_i387_fisttp" 4456 [(set (match_operand:SWI248x 0 "memory_operand" "=m") 4457 (fix:SWI248x (match_operand 1 "register_operand" "f"))) 4458 (clobber (match_scratch:XF 2 "=&1f"))] 4459 "X87_FLOAT_MODE_P (GET_MODE (operands[1])) 4460 && TARGET_FISTTP 4461 && !((SSE_FLOAT_MODE_P (GET_MODE (operands[1])) 4462 && (TARGET_64BIT || <MODE>mode != DImode)) 4463 && TARGET_SSE_MATH)" 4464 "* return output_fix_trunc (insn, operands, true);" 4465 [(set_attr "type" "fisttp") 4466 (set_attr "mode" "<MODE>")]) 4467 4468(define_insn "fix_trunc<mode>_i387_fisttp_with_temp" 4469 [(set (match_operand:SWI248x 0 "nonimmediate_operand" "=m,?r") 4470 (fix:SWI248x (match_operand 1 "register_operand" "f,f"))) 4471 (clobber (match_operand:SWI248x 2 "memory_operand" "=X,m")) 4472 (clobber (match_scratch:XF 3 "=&1f,&1f"))] 4473 "X87_FLOAT_MODE_P (GET_MODE (operands[1])) 4474 && TARGET_FISTTP 4475 && !((SSE_FLOAT_MODE_P (GET_MODE (operands[1])) 4476 && (TARGET_64BIT || <MODE>mode != DImode)) 4477 && TARGET_SSE_MATH)" 4478 "#" 4479 [(set_attr "type" "fisttp") 4480 (set_attr "mode" "<MODE>")]) 4481 4482(define_split 4483 [(set (match_operand:SWI248x 0 "register_operand" "") 4484 (fix:SWI248x (match_operand 1 "register_operand" ""))) 4485 (clobber (match_operand:SWI248x 2 "memory_operand" "")) 4486 (clobber (match_scratch 3 ""))] 4487 "reload_completed" 4488 [(parallel [(set (match_dup 2) (fix:SWI248x (match_dup 1))) 4489 (clobber (match_dup 3))]) 4490 (set (match_dup 0) (match_dup 2))]) 4491 4492(define_split 4493 [(set (match_operand:SWI248x 0 "memory_operand" "") 4494 (fix:SWI248x (match_operand 1 "register_operand" ""))) 4495 (clobber (match_operand:SWI248x 2 "memory_operand" "")) 4496 (clobber (match_scratch 3 ""))] 4497 "reload_completed" 4498 [(parallel [(set (match_dup 0) (fix:SWI248x (match_dup 1))) 4499 (clobber (match_dup 3))])]) 4500 4501;; See the comments in i386.h near OPTIMIZE_MODE_SWITCHING for the description 4502;; of the machinery. Please note the clobber of FLAGS_REG. In i387 control 4503;; word calculation (inserted by LCM in mode switching pass) a FLAGS_REG 4504;; clobbering insns can be used. Look at emit_i387_cw_initialization () 4505;; function in i386.c. 4506(define_insn_and_split "*fix_trunc<mode>_i387_1" 4507 [(set (match_operand:SWI248x 0 "nonimmediate_operand" "") 4508 (fix:SWI248x (match_operand 1 "register_operand" ""))) 4509 (clobber (reg:CC FLAGS_REG))] 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 && can_create_pseudo_p ()" 4515 "#" 4516 "&& 1" 4517 [(const_int 0)] 4518{ 4519 ix86_optimize_mode_switching[I387_TRUNC] = 1; 4520 4521 operands[2] = assign_386_stack_local (HImode, SLOT_CW_STORED); 4522 operands[3] = assign_386_stack_local (HImode, SLOT_CW_TRUNC); 4523 if (memory_operand (operands[0], VOIDmode)) 4524 emit_insn (gen_fix_trunc<mode>_i387 (operands[0], operands[1], 4525 operands[2], operands[3])); 4526 else 4527 { 4528 operands[4] = assign_386_stack_local (<MODE>mode, SLOT_TEMP); 4529 emit_insn (gen_fix_trunc<mode>_i387_with_temp (operands[0], operands[1], 4530 operands[2], operands[3], 4531 operands[4])); 4532 } 4533 DONE; 4534} 4535 [(set_attr "type" "fistp") 4536 (set_attr "i387_cw" "trunc") 4537 (set_attr "mode" "<MODE>")]) 4538 4539(define_insn "fix_truncdi_i387" 4540 [(set (match_operand:DI 0 "memory_operand" "=m") 4541 (fix:DI (match_operand 1 "register_operand" "f"))) 4542 (use (match_operand:HI 2 "memory_operand" "m")) 4543 (use (match_operand:HI 3 "memory_operand" "m")) 4544 (clobber (match_scratch:XF 4 "=&1f"))] 4545 "X87_FLOAT_MODE_P (GET_MODE (operands[1])) 4546 && !TARGET_FISTTP 4547 && !(TARGET_64BIT && SSE_FLOAT_MODE_P (GET_MODE (operands[1])))" 4548 "* return output_fix_trunc (insn, operands, false);" 4549 [(set_attr "type" "fistp") 4550 (set_attr "i387_cw" "trunc") 4551 (set_attr "mode" "DI")]) 4552 4553(define_insn "fix_truncdi_i387_with_temp" 4554 [(set (match_operand:DI 0 "nonimmediate_operand" "=m,?r") 4555 (fix:DI (match_operand 1 "register_operand" "f,f"))) 4556 (use (match_operand:HI 2 "memory_operand" "m,m")) 4557 (use (match_operand:HI 3 "memory_operand" "m,m")) 4558 (clobber (match_operand:DI 4 "memory_operand" "=X,m")) 4559 (clobber (match_scratch:XF 5 "=&1f,&1f"))] 4560 "X87_FLOAT_MODE_P (GET_MODE (operands[1])) 4561 && !TARGET_FISTTP 4562 && !(TARGET_64BIT && SSE_FLOAT_MODE_P (GET_MODE (operands[1])))" 4563 "#" 4564 [(set_attr "type" "fistp") 4565 (set_attr "i387_cw" "trunc") 4566 (set_attr "mode" "DI")]) 4567 4568(define_split 4569 [(set (match_operand:DI 0 "register_operand" "") 4570 (fix:DI (match_operand 1 "register_operand" ""))) 4571 (use (match_operand:HI 2 "memory_operand" "")) 4572 (use (match_operand:HI 3 "memory_operand" "")) 4573 (clobber (match_operand:DI 4 "memory_operand" "")) 4574 (clobber (match_scratch 5 ""))] 4575 "reload_completed" 4576 [(parallel [(set (match_dup 4) (fix:DI (match_dup 1))) 4577 (use (match_dup 2)) 4578 (use (match_dup 3)) 4579 (clobber (match_dup 5))]) 4580 (set (match_dup 0) (match_dup 4))]) 4581 4582(define_split 4583 [(set (match_operand:DI 0 "memory_operand" "") 4584 (fix:DI (match_operand 1 "register_operand" ""))) 4585 (use (match_operand:HI 2 "memory_operand" "")) 4586 (use (match_operand:HI 3 "memory_operand" "")) 4587 (clobber (match_operand:DI 4 "memory_operand" "")) 4588 (clobber (match_scratch 5 ""))] 4589 "reload_completed" 4590 [(parallel [(set (match_dup 0) (fix:DI (match_dup 1))) 4591 (use (match_dup 2)) 4592 (use (match_dup 3)) 4593 (clobber (match_dup 5))])]) 4594 4595(define_insn "fix_trunc<mode>_i387" 4596 [(set (match_operand:SWI24 0 "memory_operand" "=m") 4597 (fix:SWI24 (match_operand 1 "register_operand" "f"))) 4598 (use (match_operand:HI 2 "memory_operand" "m")) 4599 (use (match_operand:HI 3 "memory_operand" "m"))] 4600 "X87_FLOAT_MODE_P (GET_MODE (operands[1])) 4601 && !TARGET_FISTTP 4602 && !SSE_FLOAT_MODE_P (GET_MODE (operands[1]))" 4603 "* return output_fix_trunc (insn, operands, false);" 4604 [(set_attr "type" "fistp") 4605 (set_attr "i387_cw" "trunc") 4606 (set_attr "mode" "<MODE>")]) 4607 4608(define_insn "fix_trunc<mode>_i387_with_temp" 4609 [(set (match_operand:SWI24 0 "nonimmediate_operand" "=m,?r") 4610 (fix:SWI24 (match_operand 1 "register_operand" "f,f"))) 4611 (use (match_operand:HI 2 "memory_operand" "m,m")) 4612 (use (match_operand:HI 3 "memory_operand" "m,m")) 4613 (clobber (match_operand:SWI24 4 "memory_operand" "=X,m"))] 4614 "X87_FLOAT_MODE_P (GET_MODE (operands[1])) 4615 && !TARGET_FISTTP 4616 && !SSE_FLOAT_MODE_P (GET_MODE (operands[1]))" 4617 "#" 4618 [(set_attr "type" "fistp") 4619 (set_attr "i387_cw" "trunc") 4620 (set_attr "mode" "<MODE>")]) 4621 4622(define_split 4623 [(set (match_operand:SWI24 0 "register_operand" "") 4624 (fix:SWI24 (match_operand 1 "register_operand" ""))) 4625 (use (match_operand:HI 2 "memory_operand" "")) 4626 (use (match_operand:HI 3 "memory_operand" "")) 4627 (clobber (match_operand:SWI24 4 "memory_operand" ""))] 4628 "reload_completed" 4629 [(parallel [(set (match_dup 4) (fix:SWI24 (match_dup 1))) 4630 (use (match_dup 2)) 4631 (use (match_dup 3))]) 4632 (set (match_dup 0) (match_dup 4))]) 4633 4634(define_split 4635 [(set (match_operand:SWI24 0 "memory_operand" "") 4636 (fix:SWI24 (match_operand 1 "register_operand" ""))) 4637 (use (match_operand:HI 2 "memory_operand" "")) 4638 (use (match_operand:HI 3 "memory_operand" "")) 4639 (clobber (match_operand:SWI24 4 "memory_operand" ""))] 4640 "reload_completed" 4641 [(parallel [(set (match_dup 0) (fix:SWI24 (match_dup 1))) 4642 (use (match_dup 2)) 4643 (use (match_dup 3))])]) 4644 4645(define_insn "x86_fnstcw_1" 4646 [(set (match_operand:HI 0 "memory_operand" "=m") 4647 (unspec:HI [(reg:HI FPCR_REG)] UNSPEC_FSTCW))] 4648 "TARGET_80387" 4649 "fnstcw\t%0" 4650 [(set (attr "length") 4651 (symbol_ref "ix86_attr_length_address_default (insn) + 2")) 4652 (set_attr "mode" "HI") 4653 (set_attr "unit" "i387") 4654 (set_attr "bdver1_decode" "vector")]) 4655 4656(define_insn "x86_fldcw_1" 4657 [(set (reg:HI FPCR_REG) 4658 (unspec:HI [(match_operand:HI 0 "memory_operand" "m")] UNSPEC_FLDCW))] 4659 "TARGET_80387" 4660 "fldcw\t%0" 4661 [(set (attr "length") 4662 (symbol_ref "ix86_attr_length_address_default (insn) + 2")) 4663 (set_attr "mode" "HI") 4664 (set_attr "unit" "i387") 4665 (set_attr "athlon_decode" "vector") 4666 (set_attr "amdfam10_decode" "vector") 4667 (set_attr "bdver1_decode" "vector")]) 4668 4669;; Conversion between fixed point and floating point. 4670 4671;; Even though we only accept memory inputs, the backend _really_ 4672;; wants to be able to do this between registers. 4673 4674(define_expand "floathi<mode>2" 4675 [(set (match_operand:X87MODEF 0 "register_operand" "") 4676 (float:X87MODEF (match_operand:HI 1 "nonimmediate_operand" "")))] 4677 "TARGET_80387 4678 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH) 4679 || TARGET_MIX_SSE_I387)") 4680 4681;; Pre-reload splitter to add memory clobber to the pattern. 4682(define_insn_and_split "*floathi<mode>2_1" 4683 [(set (match_operand:X87MODEF 0 "register_operand" "") 4684 (float:X87MODEF (match_operand:HI 1 "register_operand" "")))] 4685 "TARGET_80387 4686 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH) 4687 || TARGET_MIX_SSE_I387) 4688 && can_create_pseudo_p ()" 4689 "#" 4690 "&& 1" 4691 [(parallel [(set (match_dup 0) 4692 (float:X87MODEF (match_dup 1))) 4693 (clobber (match_dup 2))])] 4694 "operands[2] = assign_386_stack_local (HImode, SLOT_TEMP);") 4695 4696(define_insn "*floathi<mode>2_i387_with_temp" 4697 [(set (match_operand:X87MODEF 0 "register_operand" "=f,f") 4698 (float:X87MODEF (match_operand:HI 1 "nonimmediate_operand" "m,?r"))) 4699 (clobber (match_operand:HI 2 "memory_operand" "=X,m"))] 4700 "TARGET_80387 4701 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH) 4702 || TARGET_MIX_SSE_I387)" 4703 "#" 4704 [(set_attr "type" "fmov,multi") 4705 (set_attr "mode" "<MODE>") 4706 (set_attr "unit" "*,i387") 4707 (set_attr "fp_int_src" "true")]) 4708 4709(define_insn "*floathi<mode>2_i387" 4710 [(set (match_operand:X87MODEF 0 "register_operand" "=f") 4711 (float:X87MODEF (match_operand:HI 1 "memory_operand" "m")))] 4712 "TARGET_80387 4713 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH) 4714 || TARGET_MIX_SSE_I387)" 4715 "fild%Z1\t%1" 4716 [(set_attr "type" "fmov") 4717 (set_attr "mode" "<MODE>") 4718 (set_attr "fp_int_src" "true")]) 4719 4720(define_split 4721 [(set (match_operand:X87MODEF 0 "register_operand" "") 4722 (float:X87MODEF (match_operand:HI 1 "register_operand" ""))) 4723 (clobber (match_operand:HI 2 "memory_operand" ""))] 4724 "TARGET_80387 4725 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH) 4726 || TARGET_MIX_SSE_I387) 4727 && reload_completed" 4728 [(set (match_dup 2) (match_dup 1)) 4729 (set (match_dup 0) (float:X87MODEF (match_dup 2)))]) 4730 4731(define_split 4732 [(set (match_operand:X87MODEF 0 "register_operand" "") 4733 (float:X87MODEF (match_operand:HI 1 "memory_operand" ""))) 4734 (clobber (match_operand:HI 2 "memory_operand" ""))] 4735 "TARGET_80387 4736 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH) 4737 || TARGET_MIX_SSE_I387) 4738 && reload_completed" 4739 [(set (match_dup 0) (float:X87MODEF (match_dup 1)))]) 4740 4741(define_expand "float<SWI48x:mode><X87MODEF:mode>2" 4742 [(set (match_operand:X87MODEF 0 "register_operand" "") 4743 (float:X87MODEF 4744 (match_operand:SWI48x 1 "nonimmediate_operand" "")))] 4745 "TARGET_80387 4746 || ((<SWI48x:MODE>mode != DImode || TARGET_64BIT) 4747 && SSE_FLOAT_MODE_P (<X87MODEF:MODE>mode) && TARGET_SSE_MATH)" 4748{ 4749 if (!((<SWI48x:MODE>mode != DImode || TARGET_64BIT) 4750 && SSE_FLOAT_MODE_P (<X87MODEF:MODE>mode) && TARGET_SSE_MATH) 4751 && !X87_ENABLE_FLOAT (<X87MODEF:MODE>mode, <SWI48x:MODE>mode)) 4752 { 4753 rtx reg = gen_reg_rtx (XFmode); 4754 rtx (*insn)(rtx, rtx); 4755 4756 emit_insn (gen_float<SWI48x:mode>xf2 (reg, operands[1])); 4757 4758 if (<X87MODEF:MODE>mode == SFmode) 4759 insn = gen_truncxfsf2; 4760 else if (<X87MODEF:MODE>mode == DFmode) 4761 insn = gen_truncxfdf2; 4762 else 4763 gcc_unreachable (); 4764 4765 emit_insn (insn (operands[0], reg)); 4766 DONE; 4767 } 4768}) 4769 4770;; Pre-reload splitter to add memory clobber to the pattern. 4771(define_insn_and_split "*float<SWI48x:mode><X87MODEF:mode>2_1" 4772 [(set (match_operand:X87MODEF 0 "register_operand" "") 4773 (float:X87MODEF (match_operand:SWI48x 1 "register_operand" "")))] 4774 "((TARGET_80387 4775 && X87_ENABLE_FLOAT (<X87MODEF:MODE>mode, <SWI48x:MODE>mode) 4776 && (!((<SWI48x:MODE>mode != DImode || TARGET_64BIT) 4777 && SSE_FLOAT_MODE_P (<X87MODEF:MODE>mode) && TARGET_SSE_MATH) 4778 || TARGET_MIX_SSE_I387)) 4779 || ((<SWI48x:MODE>mode != DImode || TARGET_64BIT) 4780 && SSE_FLOAT_MODE_P (<X87MODEF:MODE>mode) && TARGET_SSE_MATH 4781 && ((<SWI48x:MODE>mode == SImode 4782 && TARGET_SSE2 && TARGET_USE_VECTOR_CONVERTS 4783 && optimize_function_for_speed_p (cfun) 4784 && flag_trapping_math) 4785 || !(TARGET_INTER_UNIT_CONVERSIONS 4786 || optimize_function_for_size_p (cfun))))) 4787 && can_create_pseudo_p ()" 4788 "#" 4789 "&& 1" 4790 [(parallel [(set (match_dup 0) (float:X87MODEF (match_dup 1))) 4791 (clobber (match_dup 2))])] 4792{ 4793 operands[2] = assign_386_stack_local (<SWI48x:MODE>mode, SLOT_TEMP); 4794 4795 /* Avoid store forwarding (partial memory) stall penalty 4796 by passing DImode value through XMM registers. */ 4797 if (<SWI48x:MODE>mode == DImode && !TARGET_64BIT 4798 && TARGET_80387 && TARGET_SSE2 && TARGET_INTER_UNIT_MOVES 4799 && optimize_function_for_speed_p (cfun)) 4800 { 4801 emit_insn (gen_floatdi<X87MODEF:mode>2_i387_with_xmm (operands[0], 4802 operands[1], 4803 operands[2])); 4804 DONE; 4805 } 4806}) 4807 4808(define_insn "*floatsi<mode>2_vector_mixed_with_temp" 4809 [(set (match_operand:MODEF 0 "register_operand" "=f,f,x,x,x") 4810 (float:MODEF 4811 (match_operand:SI 1 "nonimmediate_operand" "m,?r,r,m,!x"))) 4812 (clobber (match_operand:SI 2 "memory_operand" "=X,m,m,X,m"))] 4813 "TARGET_SSE2 && TARGET_MIX_SSE_I387 4814 && TARGET_USE_VECTOR_CONVERTS && optimize_function_for_speed_p (cfun)" 4815 "#" 4816 [(set_attr "type" "fmov,multi,sseicvt,sseicvt,sseicvt") 4817 (set_attr "mode" "<MODE>,<MODE>,<MODE>,<MODE>,<ssevecmode>") 4818 (set_attr "unit" "*,i387,*,*,*") 4819 (set_attr "athlon_decode" "*,*,double,direct,double") 4820 (set_attr "amdfam10_decode" "*,*,vector,double,double") 4821 (set_attr "bdver1_decode" "*,*,double,direct,double") 4822 (set_attr "fp_int_src" "true")]) 4823 4824(define_insn "*floatsi<mode>2_vector_mixed" 4825 [(set (match_operand:MODEF 0 "register_operand" "=f,x") 4826 (float:MODEF (match_operand:SI 1 "memory_operand" "m,m")))] 4827 "TARGET_SSE2 && TARGET_MIX_SSE_I387 4828 && TARGET_USE_VECTOR_CONVERTS && optimize_function_for_speed_p (cfun)" 4829 "@ 4830 fild%Z1\t%1 4831 #" 4832 [(set_attr "type" "fmov,sseicvt") 4833 (set_attr "mode" "<MODE>,<ssevecmode>") 4834 (set_attr "unit" "i387,*") 4835 (set_attr "athlon_decode" "*,direct") 4836 (set_attr "amdfam10_decode" "*,double") 4837 (set_attr "bdver1_decode" "*,direct") 4838 (set_attr "fp_int_src" "true")]) 4839 4840(define_insn "*float<SWI48x:mode><MODEF:mode>2_mixed_with_temp" 4841 [(set (match_operand:MODEF 0 "register_operand" "=f,f,x,x") 4842 (float:MODEF 4843 (match_operand:SWI48x 1 "nonimmediate_operand" "m,?r,r,m"))) 4844 (clobber (match_operand:SWI48x 2 "memory_operand" "=X,m,m,X"))] 4845 "(<SWI48x:MODE>mode != DImode || TARGET_64BIT) 4846 && SSE_FLOAT_MODE_P (<MODEF:MODE>mode) && TARGET_MIX_SSE_I387" 4847 "#" 4848 [(set_attr "type" "fmov,multi,sseicvt,sseicvt") 4849 (set_attr "mode" "<MODEF:MODE>") 4850 (set_attr "unit" "*,i387,*,*") 4851 (set_attr "athlon_decode" "*,*,double,direct") 4852 (set_attr "amdfam10_decode" "*,*,vector,double") 4853 (set_attr "bdver1_decode" "*,*,double,direct") 4854 (set_attr "fp_int_src" "true")]) 4855 4856(define_split 4857 [(set (match_operand:MODEF 0 "register_operand" "") 4858 (float:MODEF (match_operand:SWI48x 1 "register_operand" ""))) 4859 (clobber (match_operand:SWI48x 2 "memory_operand" ""))] 4860 "(<SWI48x:MODE>mode != DImode || TARGET_64BIT) 4861 && SSE_FLOAT_MODE_P (<MODEF:MODE>mode) && TARGET_MIX_SSE_I387 4862 && TARGET_INTER_UNIT_CONVERSIONS 4863 && reload_completed 4864 && (SSE_REG_P (operands[0]) 4865 || (GET_CODE (operands[0]) == SUBREG 4866 && SSE_REG_P (SUBREG_REG (operands[0]))))" 4867 [(set (match_dup 0) (float:MODEF (match_dup 1)))]) 4868 4869(define_split 4870 [(set (match_operand:MODEF 0 "register_operand" "") 4871 (float:MODEF (match_operand:SWI48x 1 "register_operand" ""))) 4872 (clobber (match_operand:SWI48x 2 "memory_operand" ""))] 4873 "(<SWI48x:MODE>mode != DImode || TARGET_64BIT) 4874 && SSE_FLOAT_MODE_P (<MODEF:MODE>mode) && TARGET_MIX_SSE_I387 4875 && !(TARGET_INTER_UNIT_CONVERSIONS || optimize_function_for_size_p (cfun)) 4876 && reload_completed 4877 && (SSE_REG_P (operands[0]) 4878 || (GET_CODE (operands[0]) == SUBREG 4879 && SSE_REG_P (SUBREG_REG (operands[0]))))" 4880 [(set (match_dup 2) (match_dup 1)) 4881 (set (match_dup 0) (float:MODEF (match_dup 2)))]) 4882 4883(define_insn "*float<SWI48x:mode><MODEF:mode>2_mixed_interunit" 4884 [(set (match_operand:MODEF 0 "register_operand" "=f,x,x") 4885 (float:MODEF 4886 (match_operand:SWI48x 1 "nonimmediate_operand" "m,r,m")))] 4887 "(<SWI48x:MODE>mode != DImode || TARGET_64BIT) 4888 && SSE_FLOAT_MODE_P (<MODEF:MODE>mode) && TARGET_MIX_SSE_I387 4889 && (TARGET_INTER_UNIT_CONVERSIONS || optimize_function_for_size_p (cfun))" 4890 "@ 4891 fild%Z1\t%1 4892 %vcvtsi2<MODEF:ssemodesuffix><SWI48x:rex64suffix>\t{%1, %d0|%d0, %1} 4893 %vcvtsi2<MODEF:ssemodesuffix><SWI48x:rex64suffix>\t{%1, %d0|%d0, %1}" 4894 [(set_attr "type" "fmov,sseicvt,sseicvt") 4895 (set_attr "prefix" "orig,maybe_vex,maybe_vex") 4896 (set_attr "mode" "<MODEF:MODE>") 4897 (set (attr "prefix_rex") 4898 (if_then_else 4899 (and (eq_attr "prefix" "maybe_vex") 4900 (match_test "<SWI48x:MODE>mode == DImode")) 4901 (const_string "1") 4902 (const_string "*"))) 4903 (set_attr "unit" "i387,*,*") 4904 (set_attr "athlon_decode" "*,double,direct") 4905 (set_attr "amdfam10_decode" "*,vector,double") 4906 (set_attr "bdver1_decode" "*,double,direct") 4907 (set_attr "fp_int_src" "true")]) 4908 4909(define_insn "*float<SWI48x:mode><MODEF:mode>2_mixed_nointerunit" 4910 [(set (match_operand:MODEF 0 "register_operand" "=f,x") 4911 (float:MODEF 4912 (match_operand:SWI48x 1 "memory_operand" "m,m")))] 4913 "(<SWI48x:MODE>mode != DImode || TARGET_64BIT) 4914 && SSE_FLOAT_MODE_P (<MODEF:MODE>mode) && TARGET_MIX_SSE_I387 4915 && !(TARGET_INTER_UNIT_CONVERSIONS || optimize_function_for_size_p (cfun))" 4916 "@ 4917 fild%Z1\t%1 4918 %vcvtsi2<MODEF:ssemodesuffix><SWI48x:rex64suffix>\t{%1, %d0|%d0, %1}" 4919 [(set_attr "type" "fmov,sseicvt") 4920 (set_attr "prefix" "orig,maybe_vex") 4921 (set_attr "mode" "<MODEF:MODE>") 4922 (set (attr "prefix_rex") 4923 (if_then_else 4924 (and (eq_attr "prefix" "maybe_vex") 4925 (match_test "<SWI48x:MODE>mode == DImode")) 4926 (const_string "1") 4927 (const_string "*"))) 4928 (set_attr "athlon_decode" "*,direct") 4929 (set_attr "amdfam10_decode" "*,double") 4930 (set_attr "bdver1_decode" "*,direct") 4931 (set_attr "fp_int_src" "true")]) 4932 4933(define_insn "*floatsi<mode>2_vector_sse_with_temp" 4934 [(set (match_operand:MODEF 0 "register_operand" "=x,x,x") 4935 (float:MODEF 4936 (match_operand:SI 1 "nonimmediate_operand" "r,m,!x"))) 4937 (clobber (match_operand:SI 2 "memory_operand" "=m,X,m"))] 4938 "TARGET_SSE2 && TARGET_SSE_MATH 4939 && TARGET_USE_VECTOR_CONVERTS && optimize_function_for_speed_p (cfun)" 4940 "#" 4941 [(set_attr "type" "sseicvt") 4942 (set_attr "mode" "<MODE>,<MODE>,<ssevecmode>") 4943 (set_attr "athlon_decode" "double,direct,double") 4944 (set_attr "amdfam10_decode" "vector,double,double") 4945 (set_attr "bdver1_decode" "double,direct,double") 4946 (set_attr "fp_int_src" "true")]) 4947 4948(define_insn "*floatsi<mode>2_vector_sse" 4949 [(set (match_operand:MODEF 0 "register_operand" "=x") 4950 (float:MODEF (match_operand:SI 1 "memory_operand" "m")))] 4951 "TARGET_SSE2 && TARGET_SSE_MATH 4952 && TARGET_USE_VECTOR_CONVERTS && optimize_function_for_speed_p (cfun)" 4953 "#" 4954 [(set_attr "type" "sseicvt") 4955 (set_attr "mode" "<MODE>") 4956 (set_attr "athlon_decode" "direct") 4957 (set_attr "amdfam10_decode" "double") 4958 (set_attr "bdver1_decode" "direct") 4959 (set_attr "fp_int_src" "true")]) 4960 4961(define_split 4962 [(set (match_operand:MODEF 0 "register_operand" "") 4963 (float:MODEF (match_operand:SI 1 "register_operand" ""))) 4964 (clobber (match_operand:SI 2 "memory_operand" ""))] 4965 "TARGET_SSE2 && TARGET_SSE_MATH 4966 && TARGET_USE_VECTOR_CONVERTS && optimize_function_for_speed_p (cfun) 4967 && reload_completed 4968 && (SSE_REG_P (operands[0]) 4969 || (GET_CODE (operands[0]) == SUBREG 4970 && SSE_REG_P (SUBREG_REG (operands[0]))))" 4971 [(const_int 0)] 4972{ 4973 rtx op1 = operands[1]; 4974 4975 operands[3] = simplify_gen_subreg (<ssevecmode>mode, operands[0], 4976 <MODE>mode, 0); 4977 if (GET_CODE (op1) == SUBREG) 4978 op1 = SUBREG_REG (op1); 4979 4980 if (GENERAL_REG_P (op1) && TARGET_INTER_UNIT_MOVES) 4981 { 4982 operands[4] = simplify_gen_subreg (V4SImode, operands[0], <MODE>mode, 0); 4983 emit_insn (gen_sse2_loadld (operands[4], 4984 CONST0_RTX (V4SImode), operands[1])); 4985 } 4986 /* We can ignore possible trapping value in the 4987 high part of SSE register for non-trapping math. */ 4988 else if (SSE_REG_P (op1) && !flag_trapping_math) 4989 operands[4] = simplify_gen_subreg (V4SImode, operands[1], SImode, 0); 4990 else 4991 { 4992 operands[4] = simplify_gen_subreg (V4SImode, operands[0], <MODE>mode, 0); 4993 emit_move_insn (operands[2], operands[1]); 4994 emit_insn (gen_sse2_loadld (operands[4], 4995 CONST0_RTX (V4SImode), operands[2])); 4996 } 4997 if (<ssevecmode>mode == V4SFmode) 4998 emit_insn (gen_floatv4siv4sf2 (operands[3], operands[4])); 4999 else 5000 emit_insn (gen_sse2_cvtdq2pd (operands[3], operands[4])); 5001 DONE; 5002}) 5003 5004(define_split 5005 [(set (match_operand:MODEF 0 "register_operand" "") 5006 (float:MODEF (match_operand:SI 1 "memory_operand" ""))) 5007 (clobber (match_operand:SI 2 "memory_operand" ""))] 5008 "TARGET_SSE2 && TARGET_SSE_MATH 5009 && TARGET_USE_VECTOR_CONVERTS && optimize_function_for_speed_p (cfun) 5010 && reload_completed 5011 && (SSE_REG_P (operands[0]) 5012 || (GET_CODE (operands[0]) == SUBREG 5013 && SSE_REG_P (SUBREG_REG (operands[0]))))" 5014 [(const_int 0)] 5015{ 5016 operands[3] = simplify_gen_subreg (<ssevecmode>mode, operands[0], 5017 <MODE>mode, 0); 5018 operands[4] = simplify_gen_subreg (V4SImode, operands[0], <MODE>mode, 0); 5019 5020 emit_insn (gen_sse2_loadld (operands[4], 5021 CONST0_RTX (V4SImode), operands[1])); 5022 if (<ssevecmode>mode == V4SFmode) 5023 emit_insn (gen_floatv4siv4sf2 (operands[3], operands[4])); 5024 else 5025 emit_insn (gen_sse2_cvtdq2pd (operands[3], operands[4])); 5026 DONE; 5027}) 5028 5029(define_split 5030 [(set (match_operand:MODEF 0 "register_operand" "") 5031 (float:MODEF (match_operand:SI 1 "register_operand" "")))] 5032 "TARGET_SSE2 && TARGET_SSE_MATH 5033 && TARGET_USE_VECTOR_CONVERTS && optimize_function_for_speed_p (cfun) 5034 && reload_completed 5035 && (SSE_REG_P (operands[0]) 5036 || (GET_CODE (operands[0]) == SUBREG 5037 && SSE_REG_P (SUBREG_REG (operands[0]))))" 5038 [(const_int 0)] 5039{ 5040 rtx op1 = operands[1]; 5041 5042 operands[3] = simplify_gen_subreg (<ssevecmode>mode, operands[0], 5043 <MODE>mode, 0); 5044 if (GET_CODE (op1) == SUBREG) 5045 op1 = SUBREG_REG (op1); 5046 5047 if (GENERAL_REG_P (op1)) 5048 { 5049 operands[4] = simplify_gen_subreg (V4SImode, operands[0], <MODE>mode, 0); 5050 if (TARGET_INTER_UNIT_MOVES) 5051 emit_insn (gen_sse2_loadld (operands[4], 5052 CONST0_RTX (V4SImode), operands[1])); 5053 else 5054 { 5055 operands[5] = ix86_force_to_memory (GET_MODE (operands[1]), 5056 operands[1]); 5057 emit_insn (gen_sse2_loadld (operands[4], 5058 CONST0_RTX (V4SImode), operands[5])); 5059 ix86_free_from_memory (GET_MODE (operands[1])); 5060 } 5061 } 5062 /* We can ignore possible trapping value in the 5063 high part of SSE register for non-trapping math. */ 5064 else if (SSE_REG_P (op1) && !flag_trapping_math) 5065 operands[4] = simplify_gen_subreg (V4SImode, operands[1], SImode, 0); 5066 else 5067 gcc_unreachable (); 5068 if (<ssevecmode>mode == V4SFmode) 5069 emit_insn (gen_floatv4siv4sf2 (operands[3], operands[4])); 5070 else 5071 emit_insn (gen_sse2_cvtdq2pd (operands[3], operands[4])); 5072 DONE; 5073}) 5074 5075(define_split 5076 [(set (match_operand:MODEF 0 "register_operand" "") 5077 (float:MODEF (match_operand:SI 1 "memory_operand" "")))] 5078 "TARGET_SSE2 && TARGET_SSE_MATH 5079 && TARGET_USE_VECTOR_CONVERTS && optimize_function_for_speed_p (cfun) 5080 && reload_completed 5081 && (SSE_REG_P (operands[0]) 5082 || (GET_CODE (operands[0]) == SUBREG 5083 && SSE_REG_P (SUBREG_REG (operands[0]))))" 5084 [(const_int 0)] 5085{ 5086 operands[3] = simplify_gen_subreg (<ssevecmode>mode, operands[0], 5087 <MODE>mode, 0); 5088 operands[4] = simplify_gen_subreg (V4SImode, operands[0], <MODE>mode, 0); 5089 5090 emit_insn (gen_sse2_loadld (operands[4], 5091 CONST0_RTX (V4SImode), operands[1])); 5092 if (<ssevecmode>mode == V4SFmode) 5093 emit_insn (gen_floatv4siv4sf2 (operands[3], operands[4])); 5094 else 5095 emit_insn (gen_sse2_cvtdq2pd (operands[3], operands[4])); 5096 DONE; 5097}) 5098 5099(define_insn "*float<SWI48x:mode><MODEF:mode>2_sse_with_temp" 5100 [(set (match_operand:MODEF 0 "register_operand" "=x,x") 5101 (float:MODEF 5102 (match_operand:SWI48x 1 "nonimmediate_operand" "r,m"))) 5103 (clobber (match_operand:SWI48x 2 "memory_operand" "=m,X"))] 5104 "(<SWI48x:MODE>mode != DImode || TARGET_64BIT) 5105 && SSE_FLOAT_MODE_P (<MODEF:MODE>mode) && TARGET_SSE_MATH" 5106 "#" 5107 [(set_attr "type" "sseicvt") 5108 (set_attr "mode" "<MODEF:MODE>") 5109 (set_attr "athlon_decode" "double,direct") 5110 (set_attr "amdfam10_decode" "vector,double") 5111 (set_attr "bdver1_decode" "double,direct") 5112 (set_attr "fp_int_src" "true")]) 5113 5114(define_insn "*float<SWI48x:mode><MODEF:mode>2_sse_interunit" 5115 [(set (match_operand:MODEF 0 "register_operand" "=x,x") 5116 (float:MODEF 5117 (match_operand:SWI48x 1 "nonimmediate_operand" "r,m")))] 5118 "(<SWI48x:MODE>mode != DImode || TARGET_64BIT) 5119 && SSE_FLOAT_MODE_P (<MODEF:MODE>mode) && TARGET_SSE_MATH 5120 && (TARGET_INTER_UNIT_CONVERSIONS || optimize_function_for_size_p (cfun))" 5121 "%vcvtsi2<MODEF:ssemodesuffix><SWI48x:rex64suffix>\t{%1, %d0|%d0, %1}" 5122 [(set_attr "type" "sseicvt") 5123 (set_attr "prefix" "maybe_vex") 5124 (set_attr "mode" "<MODEF:MODE>") 5125 (set (attr "prefix_rex") 5126 (if_then_else 5127 (and (eq_attr "prefix" "maybe_vex") 5128 (match_test "<SWI48x:MODE>mode == DImode")) 5129 (const_string "1") 5130 (const_string "*"))) 5131 (set_attr "athlon_decode" "double,direct") 5132 (set_attr "amdfam10_decode" "vector,double") 5133 (set_attr "bdver1_decode" "double,direct") 5134 (set_attr "fp_int_src" "true")]) 5135 5136(define_split 5137 [(set (match_operand:MODEF 0 "register_operand" "") 5138 (float:MODEF (match_operand:SWI48x 1 "nonimmediate_operand" ""))) 5139 (clobber (match_operand:SWI48x 2 "memory_operand" ""))] 5140 "(<SWI48x:MODE>mode != DImode || TARGET_64BIT) 5141 && SSE_FLOAT_MODE_P (<MODEF:MODE>mode) && TARGET_SSE_MATH 5142 && (TARGET_INTER_UNIT_CONVERSIONS || optimize_function_for_size_p (cfun)) 5143 && reload_completed 5144 && (SSE_REG_P (operands[0]) 5145 || (GET_CODE (operands[0]) == SUBREG 5146 && SSE_REG_P (SUBREG_REG (operands[0]))))" 5147 [(set (match_dup 0) (float:MODEF (match_dup 1)))]) 5148 5149(define_insn "*float<SWI48x:mode><MODEF:mode>2_sse_nointerunit" 5150 [(set (match_operand:MODEF 0 "register_operand" "=x") 5151 (float:MODEF 5152 (match_operand:SWI48x 1 "memory_operand" "m")))] 5153 "(<SWI48x:MODE>mode != DImode || TARGET_64BIT) 5154 && SSE_FLOAT_MODE_P (<MODEF:MODE>mode) && TARGET_SSE_MATH 5155 && !(TARGET_INTER_UNIT_CONVERSIONS || optimize_function_for_size_p (cfun))" 5156 "%vcvtsi2<MODEF:ssemodesuffix><SWI48x:rex64suffix>\t{%1, %d0|%d0, %1}" 5157 [(set_attr "type" "sseicvt") 5158 (set_attr "prefix" "maybe_vex") 5159 (set_attr "mode" "<MODEF:MODE>") 5160 (set (attr "prefix_rex") 5161 (if_then_else 5162 (and (eq_attr "prefix" "maybe_vex") 5163 (match_test "<SWI48x:MODE>mode == DImode")) 5164 (const_string "1") 5165 (const_string "*"))) 5166 (set_attr "athlon_decode" "direct") 5167 (set_attr "amdfam10_decode" "double") 5168 (set_attr "bdver1_decode" "direct") 5169 (set_attr "fp_int_src" "true")]) 5170 5171(define_split 5172 [(set (match_operand:MODEF 0 "register_operand" "") 5173 (float:MODEF (match_operand:SWI48x 1 "register_operand" ""))) 5174 (clobber (match_operand:SWI48x 2 "memory_operand" ""))] 5175 "(<SWI48x:MODE>mode != DImode || TARGET_64BIT) 5176 && SSE_FLOAT_MODE_P (<MODEF:MODE>mode) && TARGET_SSE_MATH 5177 && !(TARGET_INTER_UNIT_CONVERSIONS || optimize_function_for_size_p (cfun)) 5178 && reload_completed 5179 && (SSE_REG_P (operands[0]) 5180 || (GET_CODE (operands[0]) == SUBREG 5181 && SSE_REG_P (SUBREG_REG (operands[0]))))" 5182 [(set (match_dup 2) (match_dup 1)) 5183 (set (match_dup 0) (float:MODEF (match_dup 2)))]) 5184 5185(define_split 5186 [(set (match_operand:MODEF 0 "register_operand" "") 5187 (float:MODEF (match_operand:SWI48x 1 "memory_operand" ""))) 5188 (clobber (match_operand:SWI48x 2 "memory_operand" ""))] 5189 "(<SWI48x:MODE>mode != DImode || TARGET_64BIT) 5190 && SSE_FLOAT_MODE_P (<MODEF:MODE>mode) && TARGET_SSE_MATH 5191 && reload_completed 5192 && (SSE_REG_P (operands[0]) 5193 || (GET_CODE (operands[0]) == SUBREG 5194 && SSE_REG_P (SUBREG_REG (operands[0]))))" 5195 [(set (match_dup 0) (float:MODEF (match_dup 1)))]) 5196 5197(define_insn "*float<SWI48x:mode><X87MODEF:mode>2_i387_with_temp" 5198 [(set (match_operand:X87MODEF 0 "register_operand" "=f,f") 5199 (float:X87MODEF 5200 (match_operand:SWI48x 1 "nonimmediate_operand" "m,?r"))) 5201 (clobber (match_operand:SWI48x 2 "memory_operand" "=X,m"))] 5202 "TARGET_80387 5203 && X87_ENABLE_FLOAT (<X87MODEF:MODE>mode, <SWI48x:MODE>mode)" 5204 "@ 5205 fild%Z1\t%1 5206 #" 5207 [(set_attr "type" "fmov,multi") 5208 (set_attr "mode" "<X87MODEF:MODE>") 5209 (set_attr "unit" "*,i387") 5210 (set_attr "fp_int_src" "true")]) 5211 5212(define_insn "*float<SWI48x:mode><X87MODEF:mode>2_i387" 5213 [(set (match_operand:X87MODEF 0 "register_operand" "=f") 5214 (float:X87MODEF 5215 (match_operand:SWI48x 1 "memory_operand" "m")))] 5216 "TARGET_80387 5217 && X87_ENABLE_FLOAT (<X87MODEF:MODE>mode, <SWI48x:MODE>mode)" 5218 "fild%Z1\t%1" 5219 [(set_attr "type" "fmov") 5220 (set_attr "mode" "<X87MODEF:MODE>") 5221 (set_attr "fp_int_src" "true")]) 5222 5223(define_split 5224 [(set (match_operand:X87MODEF 0 "fp_register_operand" "") 5225 (float:X87MODEF (match_operand:SWI48x 1 "register_operand" ""))) 5226 (clobber (match_operand:SWI48x 2 "memory_operand" ""))] 5227 "TARGET_80387 5228 && X87_ENABLE_FLOAT (<X87MODEF:MODE>mode, <SWI48x:MODE>mode) 5229 && reload_completed" 5230 [(set (match_dup 2) (match_dup 1)) 5231 (set (match_dup 0) (float:X87MODEF (match_dup 2)))]) 5232 5233(define_split 5234 [(set (match_operand:X87MODEF 0 "fp_register_operand" "") 5235 (float:X87MODEF (match_operand:SWI48x 1 "memory_operand" ""))) 5236 (clobber (match_operand:SWI48x 2 "memory_operand" ""))] 5237 "TARGET_80387 5238 && X87_ENABLE_FLOAT (<X87MODEF:MODE>mode, <SWI48x:MODE>mode) 5239 && reload_completed" 5240 [(set (match_dup 0) (float:X87MODEF (match_dup 1)))]) 5241 5242;; Avoid store forwarding (partial memory) stall penalty 5243;; by passing DImode value through XMM registers. */ 5244 5245(define_insn "floatdi<X87MODEF:mode>2_i387_with_xmm" 5246 [(set (match_operand:X87MODEF 0 "register_operand" "=f,f") 5247 (float:X87MODEF 5248 (match_operand:DI 1 "nonimmediate_operand" "m,?r"))) 5249 (clobber (match_scratch:V4SI 3 "=X,x")) 5250 (clobber (match_scratch:V4SI 4 "=X,x")) 5251 (clobber (match_operand:DI 2 "memory_operand" "=X,m"))] 5252 "TARGET_80387 && X87_ENABLE_FLOAT (<X87MODEF:MODE>mode, DImode) 5253 && TARGET_SSE2 && TARGET_INTER_UNIT_MOVES 5254 && !TARGET_64BIT && optimize_function_for_speed_p (cfun)" 5255 "#" 5256 [(set_attr "type" "multi") 5257 (set_attr "mode" "<X87MODEF:MODE>") 5258 (set_attr "unit" "i387") 5259 (set_attr "fp_int_src" "true")]) 5260 5261(define_split 5262 [(set (match_operand:X87MODEF 0 "fp_register_operand" "") 5263 (float:X87MODEF (match_operand:DI 1 "register_operand" ""))) 5264 (clobber (match_scratch:V4SI 3 "")) 5265 (clobber (match_scratch:V4SI 4 "")) 5266 (clobber (match_operand:DI 2 "memory_operand" ""))] 5267 "TARGET_80387 && X87_ENABLE_FLOAT (<X87MODEF:MODE>mode, DImode) 5268 && TARGET_SSE2 && TARGET_INTER_UNIT_MOVES 5269 && !TARGET_64BIT && optimize_function_for_speed_p (cfun) 5270 && reload_completed" 5271 [(set (match_dup 2) (match_dup 3)) 5272 (set (match_dup 0) (float:X87MODEF (match_dup 2)))] 5273{ 5274 /* The DImode arrived in a pair of integral registers (e.g. %edx:%eax). 5275 Assemble the 64-bit DImode value in an xmm register. */ 5276 emit_insn (gen_sse2_loadld (operands[3], CONST0_RTX (V4SImode), 5277 gen_rtx_SUBREG (SImode, operands[1], 0))); 5278 emit_insn (gen_sse2_loadld (operands[4], CONST0_RTX (V4SImode), 5279 gen_rtx_SUBREG (SImode, operands[1], 4))); 5280 emit_insn (gen_vec_interleave_lowv4si (operands[3], operands[3], 5281 operands[4])); 5282 5283 operands[3] = gen_rtx_REG (DImode, REGNO (operands[3])); 5284}) 5285 5286(define_split 5287 [(set (match_operand:X87MODEF 0 "fp_register_operand" "") 5288 (float:X87MODEF (match_operand:DI 1 "memory_operand" ""))) 5289 (clobber (match_scratch:V4SI 3 "")) 5290 (clobber (match_scratch:V4SI 4 "")) 5291 (clobber (match_operand:DI 2 "memory_operand" ""))] 5292 "TARGET_80387 && X87_ENABLE_FLOAT (<X87MODEF:MODE>mode, DImode) 5293 && TARGET_SSE2 && TARGET_INTER_UNIT_MOVES 5294 && !TARGET_64BIT && optimize_function_for_speed_p (cfun) 5295 && reload_completed" 5296 [(set (match_dup 0) (float:X87MODEF (match_dup 1)))]) 5297 5298;; Avoid store forwarding (partial memory) stall penalty by extending 5299;; SImode value to DImode through XMM register instead of pushing two 5300;; SImode values to stack. Note that even !TARGET_INTER_UNIT_MOVES 5301;; targets benefit from this optimization. Also note that fild 5302;; loads from memory only. 5303 5304(define_insn "*floatunssi<mode>2_1" 5305 [(set (match_operand:X87MODEF 0 "register_operand" "=f,f") 5306 (unsigned_float:X87MODEF 5307 (match_operand:SI 1 "nonimmediate_operand" "x,m"))) 5308 (clobber (match_operand:DI 2 "memory_operand" "=m,m")) 5309 (clobber (match_scratch:SI 3 "=X,x"))] 5310 "!TARGET_64BIT 5311 && TARGET_80387 && X87_ENABLE_FLOAT (<X87MODEF:MODE>mode, DImode) 5312 && TARGET_SSE" 5313 "#" 5314 [(set_attr "type" "multi") 5315 (set_attr "mode" "<MODE>")]) 5316 5317(define_split 5318 [(set (match_operand:X87MODEF 0 "register_operand" "") 5319 (unsigned_float:X87MODEF 5320 (match_operand:SI 1 "register_operand" ""))) 5321 (clobber (match_operand:DI 2 "memory_operand" "")) 5322 (clobber (match_scratch:SI 3 ""))] 5323 "!TARGET_64BIT 5324 && TARGET_80387 && X87_ENABLE_FLOAT (<X87MODEF:MODE>mode, DImode) 5325 && TARGET_SSE 5326 && reload_completed" 5327 [(set (match_dup 2) (match_dup 1)) 5328 (set (match_dup 0) 5329 (float:X87MODEF (match_dup 2)))] 5330 "operands[1] = simplify_gen_subreg (DImode, operands[1], SImode, 0);") 5331 5332(define_split 5333 [(set (match_operand:X87MODEF 0 "register_operand" "") 5334 (unsigned_float:X87MODEF 5335 (match_operand:SI 1 "memory_operand" ""))) 5336 (clobber (match_operand:DI 2 "memory_operand" "")) 5337 (clobber (match_scratch:SI 3 ""))] 5338 "!TARGET_64BIT 5339 && TARGET_80387 && X87_ENABLE_FLOAT (<X87MODEF:MODE>mode, DImode) 5340 && TARGET_SSE 5341 && reload_completed" 5342 [(set (match_dup 2) (match_dup 3)) 5343 (set (match_dup 0) 5344 (float:X87MODEF (match_dup 2)))] 5345{ 5346 emit_move_insn (operands[3], operands[1]); 5347 operands[3] = simplify_gen_subreg (DImode, operands[3], SImode, 0); 5348}) 5349 5350(define_expand "floatunssi<mode>2" 5351 [(parallel 5352 [(set (match_operand:X87MODEF 0 "register_operand" "") 5353 (unsigned_float:X87MODEF 5354 (match_operand:SI 1 "nonimmediate_operand" ""))) 5355 (clobber (match_dup 2)) 5356 (clobber (match_scratch:SI 3 ""))])] 5357 "!TARGET_64BIT 5358 && ((TARGET_80387 && X87_ENABLE_FLOAT (<X87MODEF:MODE>mode, DImode) 5359 && TARGET_SSE) 5360 || (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH))" 5361{ 5362 if (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH) 5363 { 5364 ix86_expand_convert_uns_si<mode>_sse (operands[0], operands[1]); 5365 DONE; 5366 } 5367 else 5368 { 5369 enum ix86_stack_slot slot = (virtuals_instantiated 5370 ? SLOT_TEMP 5371 : SLOT_VIRTUAL); 5372 operands[2] = assign_386_stack_local (DImode, slot); 5373 } 5374}) 5375 5376(define_expand "floatunsdisf2" 5377 [(use (match_operand:SF 0 "register_operand" "")) 5378 (use (match_operand:DI 1 "nonimmediate_operand" ""))] 5379 "TARGET_64BIT && TARGET_SSE_MATH" 5380 "x86_emit_floatuns (operands); DONE;") 5381 5382(define_expand "floatunsdidf2" 5383 [(use (match_operand:DF 0 "register_operand" "")) 5384 (use (match_operand:DI 1 "nonimmediate_operand" ""))] 5385 "(TARGET_64BIT || TARGET_KEEPS_VECTOR_ALIGNED_STACK) 5386 && TARGET_SSE2 && TARGET_SSE_MATH" 5387{ 5388 if (TARGET_64BIT) 5389 x86_emit_floatuns (operands); 5390 else 5391 ix86_expand_convert_uns_didf_sse (operands[0], operands[1]); 5392 DONE; 5393}) 5394 5395;; Load effective address instructions 5396 5397(define_insn_and_split "*lea<mode>" 5398 [(set (match_operand:SWI48 0 "register_operand" "=r") 5399 (match_operand:SWI48 1 "lea_address_operand" "p"))] 5400 "" 5401{ 5402 rtx addr = operands[1]; 5403 5404 if (GET_CODE (addr) == SUBREG) 5405 { 5406 gcc_assert (TARGET_64BIT); 5407 gcc_assert (<MODE>mode == SImode); 5408 gcc_assert (GET_MODE (SUBREG_REG (addr)) == DImode); 5409 return "lea{l}\t{%E1, %0|%0, %E1}"; 5410 } 5411 else if (GET_CODE (addr) == ZERO_EXTEND 5412 || GET_CODE (addr) == AND) 5413 { 5414 gcc_assert (TARGET_64BIT); 5415 gcc_assert (<MODE>mode == DImode); 5416 return "lea{l}\t{%E1, %k0|%k0, %E1}"; 5417 } 5418 else 5419 return "lea{<imodesuffix>}\t{%E1, %0|%0, %E1}"; 5420} 5421 "reload_completed && ix86_avoid_lea_for_addr (insn, operands)" 5422 [(const_int 0)] 5423{ 5424 ix86_split_lea_for_addr (operands, <MODE>mode); 5425 DONE; 5426} 5427 [(set_attr "type" "lea") 5428 (set_attr "mode" "<MODE>")]) 5429 5430;; Add instructions 5431 5432(define_expand "add<mode>3" 5433 [(set (match_operand:SDWIM 0 "nonimmediate_operand" "") 5434 (plus:SDWIM (match_operand:SDWIM 1 "nonimmediate_operand" "") 5435 (match_operand:SDWIM 2 "<general_operand>" "")))] 5436 "" 5437 "ix86_expand_binary_operator (PLUS, <MODE>mode, operands); DONE;") 5438 5439(define_insn_and_split "*add<dwi>3_doubleword" 5440 [(set (match_operand:<DWI> 0 "nonimmediate_operand" "=r,o") 5441 (plus:<DWI> 5442 (match_operand:<DWI> 1 "nonimmediate_operand" "%0,0") 5443 (match_operand:<DWI> 2 "<general_operand>" "ro<di>,r<di>"))) 5444 (clobber (reg:CC FLAGS_REG))] 5445 "ix86_binary_operator_ok (PLUS, <DWI>mode, operands)" 5446 "#" 5447 "reload_completed" 5448 [(parallel [(set (reg:CC FLAGS_REG) 5449 (unspec:CC [(match_dup 1) (match_dup 2)] 5450 UNSPEC_ADD_CARRY)) 5451 (set (match_dup 0) 5452 (plus:DWIH (match_dup 1) (match_dup 2)))]) 5453 (parallel [(set (match_dup 3) 5454 (plus:DWIH 5455 (match_dup 4) 5456 (plus:DWIH 5457 (ltu:DWIH (reg:CC FLAGS_REG) (const_int 0)) 5458 (match_dup 5)))) 5459 (clobber (reg:CC FLAGS_REG))])] 5460 "split_double_mode (<DWI>mode, &operands[0], 3, &operands[0], &operands[3]);") 5461 5462(define_insn "*add<mode>3_cc" 5463 [(set (reg:CC FLAGS_REG) 5464 (unspec:CC 5465 [(match_operand:SWI48 1 "nonimmediate_operand" "%0,0") 5466 (match_operand:SWI48 2 "<general_operand>" "r<i>,rm")] 5467 UNSPEC_ADD_CARRY)) 5468 (set (match_operand:SWI48 0 "nonimmediate_operand" "=rm,r") 5469 (plus:SWI48 (match_dup 1) (match_dup 2)))] 5470 "ix86_binary_operator_ok (PLUS, <MODE>mode, operands)" 5471 "add{<imodesuffix>}\t{%2, %0|%0, %2}" 5472 [(set_attr "type" "alu") 5473 (set_attr "mode" "<MODE>")]) 5474 5475(define_insn "addqi3_cc" 5476 [(set (reg:CC FLAGS_REG) 5477 (unspec:CC 5478 [(match_operand:QI 1 "nonimmediate_operand" "%0,0") 5479 (match_operand:QI 2 "general_operand" "qn,qm")] 5480 UNSPEC_ADD_CARRY)) 5481 (set (match_operand:QI 0 "nonimmediate_operand" "=qm,q") 5482 (plus:QI (match_dup 1) (match_dup 2)))] 5483 "ix86_binary_operator_ok (PLUS, QImode, operands)" 5484 "add{b}\t{%2, %0|%0, %2}" 5485 [(set_attr "type" "alu") 5486 (set_attr "mode" "QI")]) 5487 5488(define_insn "*add<mode>_1" 5489 [(set (match_operand:SWI48 0 "nonimmediate_operand" "=r,rm,r,r") 5490 (plus:SWI48 5491 (match_operand:SWI48 1 "nonimmediate_operand" "%0,0,r,r") 5492 (match_operand:SWI48 2 "x86_64_general_operand" "rme,re,0,le"))) 5493 (clobber (reg:CC FLAGS_REG))] 5494 "ix86_binary_operator_ok (PLUS, <MODE>mode, operands)" 5495{ 5496 switch (get_attr_type (insn)) 5497 { 5498 case TYPE_LEA: 5499 return "#"; 5500 5501 case TYPE_INCDEC: 5502 gcc_assert (rtx_equal_p (operands[0], operands[1])); 5503 if (operands[2] == const1_rtx) 5504 return "inc{<imodesuffix>}\t%0"; 5505 else 5506 { 5507 gcc_assert (operands[2] == constm1_rtx); 5508 return "dec{<imodesuffix>}\t%0"; 5509 } 5510 5511 default: 5512 /* For most processors, ADD is faster than LEA. This alternative 5513 was added to use ADD as much as possible. */ 5514 if (which_alternative == 2) 5515 { 5516 rtx tmp; 5517 tmp = operands[1], operands[1] = operands[2], operands[2] = tmp; 5518 } 5519 5520 gcc_assert (rtx_equal_p (operands[0], operands[1])); 5521 if (x86_maybe_negate_const_int (&operands[2], <MODE>mode)) 5522 return "sub{<imodesuffix>}\t{%2, %0|%0, %2}"; 5523 5524 return "add{<imodesuffix>}\t{%2, %0|%0, %2}"; 5525 } 5526} 5527 [(set (attr "type") 5528 (cond [(eq_attr "alternative" "3") 5529 (const_string "lea") 5530 (match_operand:SWI48 2 "incdec_operand" "") 5531 (const_string "incdec") 5532 ] 5533 (const_string "alu"))) 5534 (set (attr "length_immediate") 5535 (if_then_else 5536 (and (eq_attr "type" "alu") (match_operand 2 "const128_operand" "")) 5537 (const_string "1") 5538 (const_string "*"))) 5539 (set_attr "mode" "<MODE>")]) 5540 5541;; It may seem that nonimmediate operand is proper one for operand 1. 5542;; The addsi_1 pattern allows nonimmediate operand at that place and 5543;; we take care in ix86_binary_operator_ok to not allow two memory 5544;; operands so proper swapping will be done in reload. This allow 5545;; patterns constructed from addsi_1 to match. 5546 5547(define_insn "addsi_1_zext" 5548 [(set (match_operand:DI 0 "register_operand" "=r,r,r") 5549 (zero_extend:DI 5550 (plus:SI (match_operand:SI 1 "nonimmediate_operand" "%0,r,r") 5551 (match_operand:SI 2 "x86_64_general_operand" "rme,0,le")))) 5552 (clobber (reg:CC FLAGS_REG))] 5553 "TARGET_64BIT && ix86_binary_operator_ok (PLUS, SImode, operands)" 5554{ 5555 switch (get_attr_type (insn)) 5556 { 5557 case TYPE_LEA: 5558 return "#"; 5559 5560 case TYPE_INCDEC: 5561 if (operands[2] == const1_rtx) 5562 return "inc{l}\t%k0"; 5563 else 5564 { 5565 gcc_assert (operands[2] == constm1_rtx); 5566 return "dec{l}\t%k0"; 5567 } 5568 5569 default: 5570 /* For most processors, ADD is faster than LEA. This alternative 5571 was added to use ADD as much as possible. */ 5572 if (which_alternative == 1) 5573 { 5574 rtx tmp; 5575 tmp = operands[1], operands[1] = operands[2], operands[2] = tmp; 5576 } 5577 5578 if (x86_maybe_negate_const_int (&operands[2], SImode)) 5579 return "sub{l}\t{%2, %k0|%k0, %2}"; 5580 5581 return "add{l}\t{%2, %k0|%k0, %2}"; 5582 } 5583} 5584 [(set (attr "type") 5585 (cond [(eq_attr "alternative" "2") 5586 (const_string "lea") 5587 (match_operand:SI 2 "incdec_operand" "") 5588 (const_string "incdec") 5589 ] 5590 (const_string "alu"))) 5591 (set (attr "length_immediate") 5592 (if_then_else 5593 (and (eq_attr "type" "alu") (match_operand 2 "const128_operand" "")) 5594 (const_string "1") 5595 (const_string "*"))) 5596 (set_attr "mode" "SI")]) 5597 5598(define_insn "*addhi_1" 5599 [(set (match_operand:HI 0 "nonimmediate_operand" "=rm,r,r,Yp") 5600 (plus:HI (match_operand:HI 1 "nonimmediate_operand" "%0,0,r,Yp") 5601 (match_operand:HI 2 "general_operand" "rn,rm,0,ln"))) 5602 (clobber (reg:CC FLAGS_REG))] 5603 "ix86_binary_operator_ok (PLUS, HImode, operands)" 5604{ 5605 switch (get_attr_type (insn)) 5606 { 5607 case TYPE_LEA: 5608 return "#"; 5609 5610 case TYPE_INCDEC: 5611 gcc_assert (rtx_equal_p (operands[0], operands[1])); 5612 if (operands[2] == const1_rtx) 5613 return "inc{w}\t%0"; 5614 else 5615 { 5616 gcc_assert (operands[2] == constm1_rtx); 5617 return "dec{w}\t%0"; 5618 } 5619 5620 default: 5621 /* For most processors, ADD is faster than LEA. This alternative 5622 was added to use ADD as much as possible. */ 5623 if (which_alternative == 2) 5624 { 5625 rtx tmp; 5626 tmp = operands[1], operands[1] = operands[2], operands[2] = tmp; 5627 } 5628 5629 gcc_assert (rtx_equal_p (operands[0], operands[1])); 5630 if (x86_maybe_negate_const_int (&operands[2], HImode)) 5631 return "sub{w}\t{%2, %0|%0, %2}"; 5632 5633 return "add{w}\t{%2, %0|%0, %2}"; 5634 } 5635} 5636 [(set (attr "type") 5637 (cond [(eq_attr "alternative" "3") 5638 (const_string "lea") 5639 (match_operand:HI 2 "incdec_operand" "") 5640 (const_string "incdec") 5641 ] 5642 (const_string "alu"))) 5643 (set (attr "length_immediate") 5644 (if_then_else 5645 (and (eq_attr "type" "alu") (match_operand 2 "const128_operand" "")) 5646 (const_string "1") 5647 (const_string "*"))) 5648 (set_attr "mode" "HI,HI,HI,SI")]) 5649 5650;; %%% Potential partial reg stall on alternatives 3 and 4. What to do? 5651(define_insn "*addqi_1" 5652 [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,q,q,r,r,Yp") 5653 (plus:QI (match_operand:QI 1 "nonimmediate_operand" "%0,0,q,0,r,Yp") 5654 (match_operand:QI 2 "general_operand" "qn,qm,0,rn,0,ln"))) 5655 (clobber (reg:CC FLAGS_REG))] 5656 "ix86_binary_operator_ok (PLUS, QImode, operands)" 5657{ 5658 bool widen = (which_alternative == 3 || which_alternative == 4); 5659 5660 switch (get_attr_type (insn)) 5661 { 5662 case TYPE_LEA: 5663 return "#"; 5664 5665 case TYPE_INCDEC: 5666 gcc_assert (rtx_equal_p (operands[0], operands[1])); 5667 if (operands[2] == const1_rtx) 5668 return widen ? "inc{l}\t%k0" : "inc{b}\t%0"; 5669 else 5670 { 5671 gcc_assert (operands[2] == constm1_rtx); 5672 return widen ? "dec{l}\t%k0" : "dec{b}\t%0"; 5673 } 5674 5675 default: 5676 /* For most processors, ADD is faster than LEA. These alternatives 5677 were added to use ADD as much as possible. */ 5678 if (which_alternative == 2 || which_alternative == 4) 5679 { 5680 rtx tmp; 5681 tmp = operands[1], operands[1] = operands[2], operands[2] = tmp; 5682 } 5683 5684 gcc_assert (rtx_equal_p (operands[0], operands[1])); 5685 if (x86_maybe_negate_const_int (&operands[2], QImode)) 5686 { 5687 if (widen) 5688 return "sub{l}\t{%2, %k0|%k0, %2}"; 5689 else 5690 return "sub{b}\t{%2, %0|%0, %2}"; 5691 } 5692 if (widen) 5693 return "add{l}\t{%k2, %k0|%k0, %k2}"; 5694 else 5695 return "add{b}\t{%2, %0|%0, %2}"; 5696 } 5697} 5698 [(set (attr "type") 5699 (cond [(eq_attr "alternative" "5") 5700 (const_string "lea") 5701 (match_operand:QI 2 "incdec_operand" "") 5702 (const_string "incdec") 5703 ] 5704 (const_string "alu"))) 5705 (set (attr "length_immediate") 5706 (if_then_else 5707 (and (eq_attr "type" "alu") (match_operand 2 "const128_operand" "")) 5708 (const_string "1") 5709 (const_string "*"))) 5710 (set_attr "mode" "QI,QI,QI,SI,SI,SI")]) 5711 5712(define_insn "*addqi_1_slp" 5713 [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm,q")) 5714 (plus:QI (match_dup 0) 5715 (match_operand:QI 1 "general_operand" "qn,qm"))) 5716 (clobber (reg:CC FLAGS_REG))] 5717 "(! TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun)) 5718 && !(MEM_P (operands[0]) && MEM_P (operands[1]))" 5719{ 5720 switch (get_attr_type (insn)) 5721 { 5722 case TYPE_INCDEC: 5723 if (operands[1] == const1_rtx) 5724 return "inc{b}\t%0"; 5725 else 5726 { 5727 gcc_assert (operands[1] == constm1_rtx); 5728 return "dec{b}\t%0"; 5729 } 5730 5731 default: 5732 if (x86_maybe_negate_const_int (&operands[1], QImode)) 5733 return "sub{b}\t{%1, %0|%0, %1}"; 5734 5735 return "add{b}\t{%1, %0|%0, %1}"; 5736 } 5737} 5738 [(set (attr "type") 5739 (if_then_else (match_operand:QI 1 "incdec_operand" "") 5740 (const_string "incdec") 5741 (const_string "alu1"))) 5742 (set (attr "memory") 5743 (if_then_else (match_operand 1 "memory_operand" "") 5744 (const_string "load") 5745 (const_string "none"))) 5746 (set_attr "mode" "QI")]) 5747 5748;; Split non destructive adds if we cannot use lea. 5749(define_split 5750 [(set (match_operand:SWI48 0 "register_operand" "") 5751 (plus:SWI48 (match_operand:SWI48 1 "register_operand" "") 5752 (match_operand:SWI48 2 "nonmemory_operand" ""))) 5753 (clobber (reg:CC FLAGS_REG))] 5754 "reload_completed && ix86_avoid_lea_for_add (insn, operands)" 5755 [(set (match_dup 0) (match_dup 1)) 5756 (parallel [(set (match_dup 0) (plus:<MODE> (match_dup 0) (match_dup 2))) 5757 (clobber (reg:CC FLAGS_REG))])]) 5758 5759;; Convert add to the lea pattern to avoid flags dependency. 5760(define_split 5761 [(set (match_operand:SWI 0 "register_operand" "") 5762 (plus:SWI (match_operand:SWI 1 "register_operand" "") 5763 (match_operand:SWI 2 "<nonmemory_operand>" ""))) 5764 (clobber (reg:CC FLAGS_REG))] 5765 "reload_completed && ix86_lea_for_add_ok (insn, operands)" 5766 [(const_int 0)] 5767{ 5768 enum machine_mode mode = <MODE>mode; 5769 rtx pat; 5770 5771 if (GET_MODE_SIZE (mode) < GET_MODE_SIZE (SImode)) 5772 { 5773 mode = SImode; 5774 operands[0] = gen_lowpart (mode, operands[0]); 5775 operands[1] = gen_lowpart (mode, operands[1]); 5776 operands[2] = gen_lowpart (mode, operands[2]); 5777 } 5778 5779 pat = gen_rtx_PLUS (mode, operands[1], operands[2]); 5780 5781 emit_insn (gen_rtx_SET (VOIDmode, operands[0], pat)); 5782 DONE; 5783}) 5784 5785;; Convert add to the lea pattern to avoid flags dependency. 5786(define_split 5787 [(set (match_operand:DI 0 "register_operand" "") 5788 (zero_extend:DI 5789 (plus:SI (match_operand:SI 1 "register_operand" "") 5790 (match_operand:SI 2 "x86_64_nonmemory_operand" "")))) 5791 (clobber (reg:CC FLAGS_REG))] 5792 "TARGET_64BIT && reload_completed && ix86_lea_for_add_ok (insn, operands)" 5793 [(set (match_dup 0) 5794 (zero_extend:DI (plus:SI (match_dup 1) (match_dup 2))))]) 5795 5796(define_insn "*add<mode>_2" 5797 [(set (reg FLAGS_REG) 5798 (compare 5799 (plus:SWI 5800 (match_operand:SWI 1 "nonimmediate_operand" "%0,0,<r>") 5801 (match_operand:SWI 2 "<general_operand>" "<g>,<r><i>,0")) 5802 (const_int 0))) 5803 (set (match_operand:SWI 0 "nonimmediate_operand" "=<r>,<r>m,<r>") 5804 (plus:SWI (match_dup 1) (match_dup 2)))] 5805 "ix86_match_ccmode (insn, CCGOCmode) 5806 && ix86_binary_operator_ok (PLUS, <MODE>mode, operands)" 5807{ 5808 switch (get_attr_type (insn)) 5809 { 5810 case TYPE_INCDEC: 5811 if (operands[2] == const1_rtx) 5812 return "inc{<imodesuffix>}\t%0"; 5813 else 5814 { 5815 gcc_assert (operands[2] == constm1_rtx); 5816 return "dec{<imodesuffix>}\t%0"; 5817 } 5818 5819 default: 5820 if (which_alternative == 2) 5821 { 5822 rtx tmp; 5823 tmp = operands[1], operands[1] = operands[2], operands[2] = tmp; 5824 } 5825 5826 gcc_assert (rtx_equal_p (operands[0], operands[1])); 5827 if (x86_maybe_negate_const_int (&operands[2], <MODE>mode)) 5828 return "sub{<imodesuffix>}\t{%2, %0|%0, %2}"; 5829 5830 return "add{<imodesuffix>}\t{%2, %0|%0, %2}"; 5831 } 5832} 5833 [(set (attr "type") 5834 (if_then_else (match_operand:SWI 2 "incdec_operand" "") 5835 (const_string "incdec") 5836 (const_string "alu"))) 5837 (set (attr "length_immediate") 5838 (if_then_else 5839 (and (eq_attr "type" "alu") (match_operand 2 "const128_operand" "")) 5840 (const_string "1") 5841 (const_string "*"))) 5842 (set_attr "mode" "<MODE>")]) 5843 5844;; See comment for addsi_1_zext why we do use nonimmediate_operand 5845(define_insn "*addsi_2_zext" 5846 [(set (reg FLAGS_REG) 5847 (compare 5848 (plus:SI (match_operand:SI 1 "nonimmediate_operand" "%0,r") 5849 (match_operand:SI 2 "x86_64_general_operand" "rme,0")) 5850 (const_int 0))) 5851 (set (match_operand:DI 0 "register_operand" "=r,r") 5852 (zero_extend:DI (plus:SI (match_dup 1) (match_dup 2))))] 5853 "TARGET_64BIT && ix86_match_ccmode (insn, CCGOCmode) 5854 && ix86_binary_operator_ok (PLUS, SImode, operands)" 5855{ 5856 switch (get_attr_type (insn)) 5857 { 5858 case TYPE_INCDEC: 5859 if (operands[2] == const1_rtx) 5860 return "inc{l}\t%k0"; 5861 else 5862 { 5863 gcc_assert (operands[2] == constm1_rtx); 5864 return "dec{l}\t%k0"; 5865 } 5866 5867 default: 5868 if (which_alternative == 1) 5869 { 5870 rtx tmp; 5871 tmp = operands[1], operands[1] = operands[2], operands[2] = tmp; 5872 } 5873 5874 if (x86_maybe_negate_const_int (&operands[2], SImode)) 5875 return "sub{l}\t{%2, %k0|%k0, %2}"; 5876 5877 return "add{l}\t{%2, %k0|%k0, %2}"; 5878 } 5879} 5880 [(set (attr "type") 5881 (if_then_else (match_operand:SI 2 "incdec_operand" "") 5882 (const_string "incdec") 5883 (const_string "alu"))) 5884 (set (attr "length_immediate") 5885 (if_then_else 5886 (and (eq_attr "type" "alu") (match_operand 2 "const128_operand" "")) 5887 (const_string "1") 5888 (const_string "*"))) 5889 (set_attr "mode" "SI")]) 5890 5891(define_insn "*add<mode>_3" 5892 [(set (reg FLAGS_REG) 5893 (compare 5894 (neg:SWI (match_operand:SWI 2 "<general_operand>" "<g>,0")) 5895 (match_operand:SWI 1 "nonimmediate_operand" "%0,<r>"))) 5896 (clobber (match_scratch:SWI 0 "=<r>,<r>"))] 5897 "ix86_match_ccmode (insn, CCZmode) 5898 && !(MEM_P (operands[1]) && MEM_P (operands[2]))" 5899{ 5900 switch (get_attr_type (insn)) 5901 { 5902 case TYPE_INCDEC: 5903 if (operands[2] == const1_rtx) 5904 return "inc{<imodesuffix>}\t%0"; 5905 else 5906 { 5907 gcc_assert (operands[2] == constm1_rtx); 5908 return "dec{<imodesuffix>}\t%0"; 5909 } 5910 5911 default: 5912 if (which_alternative == 1) 5913 { 5914 rtx tmp; 5915 tmp = operands[1], operands[1] = operands[2], operands[2] = tmp; 5916 } 5917 5918 gcc_assert (rtx_equal_p (operands[0], operands[1])); 5919 if (x86_maybe_negate_const_int (&operands[2], <MODE>mode)) 5920 return "sub{<imodesuffix>}\t{%2, %0|%0, %2}"; 5921 5922 return "add{<imodesuffix>}\t{%2, %0|%0, %2}"; 5923 } 5924} 5925 [(set (attr "type") 5926 (if_then_else (match_operand:SWI 2 "incdec_operand" "") 5927 (const_string "incdec") 5928 (const_string "alu"))) 5929 (set (attr "length_immediate") 5930 (if_then_else 5931 (and (eq_attr "type" "alu") (match_operand 2 "const128_operand" "")) 5932 (const_string "1") 5933 (const_string "*"))) 5934 (set_attr "mode" "<MODE>")]) 5935 5936;; See comment for addsi_1_zext why we do use nonimmediate_operand 5937(define_insn "*addsi_3_zext" 5938 [(set (reg FLAGS_REG) 5939 (compare 5940 (neg:SI (match_operand:SI 2 "x86_64_general_operand" "rme,0")) 5941 (match_operand:SI 1 "nonimmediate_operand" "%0,r"))) 5942 (set (match_operand:DI 0 "register_operand" "=r,r") 5943 (zero_extend:DI (plus:SI (match_dup 1) (match_dup 2))))] 5944 "TARGET_64BIT && ix86_match_ccmode (insn, CCZmode) 5945 && ix86_binary_operator_ok (PLUS, SImode, operands)" 5946{ 5947 switch (get_attr_type (insn)) 5948 { 5949 case TYPE_INCDEC: 5950 if (operands[2] == const1_rtx) 5951 return "inc{l}\t%k0"; 5952 else 5953 { 5954 gcc_assert (operands[2] == constm1_rtx); 5955 return "dec{l}\t%k0"; 5956 } 5957 5958 default: 5959 if (which_alternative == 1) 5960 { 5961 rtx tmp; 5962 tmp = operands[1], operands[1] = operands[2], operands[2] = tmp; 5963 } 5964 5965 if (x86_maybe_negate_const_int (&operands[2], SImode)) 5966 return "sub{l}\t{%2, %k0|%k0, %2}"; 5967 5968 return "add{l}\t{%2, %k0|%k0, %2}"; 5969 } 5970} 5971 [(set (attr "type") 5972 (if_then_else (match_operand:SI 2 "incdec_operand" "") 5973 (const_string "incdec") 5974 (const_string "alu"))) 5975 (set (attr "length_immediate") 5976 (if_then_else 5977 (and (eq_attr "type" "alu") (match_operand 2 "const128_operand" "")) 5978 (const_string "1") 5979 (const_string "*"))) 5980 (set_attr "mode" "SI")]) 5981 5982; For comparisons against 1, -1 and 128, we may generate better code 5983; by converting cmp to add, inc or dec as done by peephole2. This pattern 5984; is matched then. We can't accept general immediate, because for 5985; case of overflows, the result is messed up. 5986; Also carry flag is reversed compared to cmp, so this conversion is valid 5987; only for comparisons not depending on it. 5988 5989(define_insn "*adddi_4" 5990 [(set (reg FLAGS_REG) 5991 (compare 5992 (match_operand:DI 1 "nonimmediate_operand" "0") 5993 (match_operand:DI 2 "x86_64_immediate_operand" "e"))) 5994 (clobber (match_scratch:DI 0 "=rm"))] 5995 "TARGET_64BIT 5996 && ix86_match_ccmode (insn, CCGCmode)" 5997{ 5998 switch (get_attr_type (insn)) 5999 { 6000 case TYPE_INCDEC: 6001 if (operands[2] == constm1_rtx) 6002 return "inc{q}\t%0"; 6003 else 6004 { 6005 gcc_assert (operands[2] == const1_rtx); 6006 return "dec{q}\t%0"; 6007 } 6008 6009 default: 6010 if (x86_maybe_negate_const_int (&operands[2], DImode)) 6011 return "add{q}\t{%2, %0|%0, %2}"; 6012 6013 return "sub{q}\t{%2, %0|%0, %2}"; 6014 } 6015} 6016 [(set (attr "type") 6017 (if_then_else (match_operand:DI 2 "incdec_operand" "") 6018 (const_string "incdec") 6019 (const_string "alu"))) 6020 (set (attr "length_immediate") 6021 (if_then_else 6022 (and (eq_attr "type" "alu") (match_operand 2 "const128_operand" "")) 6023 (const_string "1") 6024 (const_string "*"))) 6025 (set_attr "mode" "DI")]) 6026 6027; For comparisons against 1, -1 and 128, we may generate better code 6028; by converting cmp to add, inc or dec as done by peephole2. This pattern 6029; is matched then. We can't accept general immediate, because for 6030; case of overflows, the result is messed up. 6031; Also carry flag is reversed compared to cmp, so this conversion is valid 6032; only for comparisons not depending on it. 6033 6034(define_insn "*add<mode>_4" 6035 [(set (reg FLAGS_REG) 6036 (compare 6037 (match_operand:SWI124 1 "nonimmediate_operand" "0") 6038 (match_operand:SWI124 2 "const_int_operand" "n"))) 6039 (clobber (match_scratch:SWI124 0 "=<r>m"))] 6040 "ix86_match_ccmode (insn, CCGCmode)" 6041{ 6042 switch (get_attr_type (insn)) 6043 { 6044 case TYPE_INCDEC: 6045 if (operands[2] == constm1_rtx) 6046 return "inc{<imodesuffix>}\t%0"; 6047 else 6048 { 6049 gcc_assert (operands[2] == const1_rtx); 6050 return "dec{<imodesuffix>}\t%0"; 6051 } 6052 6053 default: 6054 if (x86_maybe_negate_const_int (&operands[2], <MODE>mode)) 6055 return "add{<imodesuffix>}\t{%2, %0|%0, %2}"; 6056 6057 return "sub{<imodesuffix>}\t{%2, %0|%0, %2}"; 6058 } 6059} 6060 [(set (attr "type") 6061 (if_then_else (match_operand:<MODE> 2 "incdec_operand" "") 6062 (const_string "incdec") 6063 (const_string "alu"))) 6064 (set (attr "length_immediate") 6065 (if_then_else 6066 (and (eq_attr "type" "alu") (match_operand 2 "const128_operand" "")) 6067 (const_string "1") 6068 (const_string "*"))) 6069 (set_attr "mode" "<MODE>")]) 6070 6071(define_insn "*add<mode>_5" 6072 [(set (reg FLAGS_REG) 6073 (compare 6074 (plus:SWI 6075 (match_operand:SWI 1 "nonimmediate_operand" "%0,<r>") 6076 (match_operand:SWI 2 "<general_operand>" "<g>,0")) 6077 (const_int 0))) 6078 (clobber (match_scratch:SWI 0 "=<r>,<r>"))] 6079 "ix86_match_ccmode (insn, CCGOCmode) 6080 && !(MEM_P (operands[1]) && MEM_P (operands[2]))" 6081{ 6082 switch (get_attr_type (insn)) 6083 { 6084 case TYPE_INCDEC: 6085 if (operands[2] == const1_rtx) 6086 return "inc{<imodesuffix>}\t%0"; 6087 else 6088 { 6089 gcc_assert (operands[2] == constm1_rtx); 6090 return "dec{<imodesuffix>}\t%0"; 6091 } 6092 6093 default: 6094 if (which_alternative == 1) 6095 { 6096 rtx tmp; 6097 tmp = operands[1], operands[1] = operands[2], operands[2] = tmp; 6098 } 6099 6100 gcc_assert (rtx_equal_p (operands[0], operands[1])); 6101 if (x86_maybe_negate_const_int (&operands[2], <MODE>mode)) 6102 return "sub{<imodesuffix>}\t{%2, %0|%0, %2}"; 6103 6104 return "add{<imodesuffix>}\t{%2, %0|%0, %2}"; 6105 } 6106} 6107 [(set (attr "type") 6108 (if_then_else (match_operand:SWI 2 "incdec_operand" "") 6109 (const_string "incdec") 6110 (const_string "alu"))) 6111 (set (attr "length_immediate") 6112 (if_then_else 6113 (and (eq_attr "type" "alu") (match_operand 2 "const128_operand" "")) 6114 (const_string "1") 6115 (const_string "*"))) 6116 (set_attr "mode" "<MODE>")]) 6117 6118(define_insn "*addqi_ext_1_rex64" 6119 [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q") 6120 (const_int 8) 6121 (const_int 8)) 6122 (plus:SI 6123 (zero_extract:SI 6124 (match_operand 1 "ext_register_operand" "0") 6125 (const_int 8) 6126 (const_int 8)) 6127 (match_operand:QI 2 "nonmemory_operand" "Qn"))) 6128 (clobber (reg:CC FLAGS_REG))] 6129 "TARGET_64BIT" 6130{ 6131 switch (get_attr_type (insn)) 6132 { 6133 case TYPE_INCDEC: 6134 if (operands[2] == const1_rtx) 6135 return "inc{b}\t%h0"; 6136 else 6137 { 6138 gcc_assert (operands[2] == constm1_rtx); 6139 return "dec{b}\t%h0"; 6140 } 6141 6142 default: 6143 return "add{b}\t{%2, %h0|%h0, %2}"; 6144 } 6145} 6146 [(set (attr "type") 6147 (if_then_else (match_operand:QI 2 "incdec_operand" "") 6148 (const_string "incdec") 6149 (const_string "alu"))) 6150 (set_attr "modrm" "1") 6151 (set_attr "mode" "QI")]) 6152 6153(define_insn "addqi_ext_1" 6154 [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q") 6155 (const_int 8) 6156 (const_int 8)) 6157 (plus:SI 6158 (zero_extract:SI 6159 (match_operand 1 "ext_register_operand" "0") 6160 (const_int 8) 6161 (const_int 8)) 6162 (match_operand:QI 2 "general_operand" "Qmn"))) 6163 (clobber (reg:CC FLAGS_REG))] 6164 "!TARGET_64BIT" 6165{ 6166 switch (get_attr_type (insn)) 6167 { 6168 case TYPE_INCDEC: 6169 if (operands[2] == const1_rtx) 6170 return "inc{b}\t%h0"; 6171 else 6172 { 6173 gcc_assert (operands[2] == constm1_rtx); 6174 return "dec{b}\t%h0"; 6175 } 6176 6177 default: 6178 return "add{b}\t{%2, %h0|%h0, %2}"; 6179 } 6180} 6181 [(set (attr "type") 6182 (if_then_else (match_operand:QI 2 "incdec_operand" "") 6183 (const_string "incdec") 6184 (const_string "alu"))) 6185 (set_attr "modrm" "1") 6186 (set_attr "mode" "QI")]) 6187 6188(define_insn "*addqi_ext_2" 6189 [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q") 6190 (const_int 8) 6191 (const_int 8)) 6192 (plus:SI 6193 (zero_extract:SI 6194 (match_operand 1 "ext_register_operand" "%0") 6195 (const_int 8) 6196 (const_int 8)) 6197 (zero_extract:SI 6198 (match_operand 2 "ext_register_operand" "Q") 6199 (const_int 8) 6200 (const_int 8)))) 6201 (clobber (reg:CC FLAGS_REG))] 6202 "" 6203 "add{b}\t{%h2, %h0|%h0, %h2}" 6204 [(set_attr "type" "alu") 6205 (set_attr "mode" "QI")]) 6206 6207;; The lea patterns for modes less than 32 bits need to be matched by 6208;; several insns converted to real lea by splitters. 6209 6210(define_insn_and_split "*lea_general_1" 6211 [(set (match_operand 0 "register_operand" "=r") 6212 (plus (plus (match_operand 1 "index_register_operand" "l") 6213 (match_operand 2 "register_operand" "r")) 6214 (match_operand 3 "immediate_operand" "i")))] 6215 "(GET_MODE (operands[0]) == QImode || GET_MODE (operands[0]) == HImode) 6216 && (!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun)) 6217 && GET_MODE (operands[0]) == GET_MODE (operands[1]) 6218 && GET_MODE (operands[0]) == GET_MODE (operands[2]) 6219 && (GET_MODE (operands[0]) == GET_MODE (operands[3]) 6220 || GET_MODE (operands[3]) == VOIDmode)" 6221 "#" 6222 "&& reload_completed" 6223 [(const_int 0)] 6224{ 6225 enum machine_mode mode = SImode; 6226 rtx pat; 6227 6228 operands[0] = gen_lowpart (mode, operands[0]); 6229 operands[1] = gen_lowpart (mode, operands[1]); 6230 operands[2] = gen_lowpart (mode, operands[2]); 6231 operands[3] = gen_lowpart (mode, operands[3]); 6232 6233 pat = gen_rtx_PLUS (mode, gen_rtx_PLUS (mode, operands[1], operands[2]), 6234 operands[3]); 6235 6236 emit_insn (gen_rtx_SET (VOIDmode, operands[0], pat)); 6237 DONE; 6238} 6239 [(set_attr "type" "lea") 6240 (set_attr "mode" "SI")]) 6241 6242(define_insn_and_split "*lea_general_2" 6243 [(set (match_operand 0 "register_operand" "=r") 6244 (plus (mult (match_operand 1 "index_register_operand" "l") 6245 (match_operand 2 "const248_operand" "n")) 6246 (match_operand 3 "nonmemory_operand" "ri")))] 6247 "(GET_MODE (operands[0]) == QImode || GET_MODE (operands[0]) == HImode) 6248 && (!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun)) 6249 && GET_MODE (operands[0]) == GET_MODE (operands[1]) 6250 && (GET_MODE (operands[0]) == GET_MODE (operands[3]) 6251 || GET_MODE (operands[3]) == VOIDmode)" 6252 "#" 6253 "&& reload_completed" 6254 [(const_int 0)] 6255{ 6256 enum machine_mode mode = SImode; 6257 rtx pat; 6258 6259 operands[0] = gen_lowpart (mode, operands[0]); 6260 operands[1] = gen_lowpart (mode, operands[1]); 6261 operands[3] = gen_lowpart (mode, operands[3]); 6262 6263 pat = gen_rtx_PLUS (mode, gen_rtx_MULT (mode, operands[1], operands[2]), 6264 operands[3]); 6265 6266 emit_insn (gen_rtx_SET (VOIDmode, operands[0], pat)); 6267 DONE; 6268} 6269 [(set_attr "type" "lea") 6270 (set_attr "mode" "SI")]) 6271 6272(define_insn_and_split "*lea_general_3" 6273 [(set (match_operand 0 "register_operand" "=r") 6274 (plus (plus (mult (match_operand 1 "index_register_operand" "l") 6275 (match_operand 2 "const248_operand" "n")) 6276 (match_operand 3 "register_operand" "r")) 6277 (match_operand 4 "immediate_operand" "i")))] 6278 "(GET_MODE (operands[0]) == QImode || GET_MODE (operands[0]) == HImode) 6279 && (!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun)) 6280 && GET_MODE (operands[0]) == GET_MODE (operands[1]) 6281 && GET_MODE (operands[0]) == GET_MODE (operands[3])" 6282 "#" 6283 "&& reload_completed" 6284 [(const_int 0)] 6285{ 6286 enum machine_mode mode = SImode; 6287 rtx pat; 6288 6289 operands[0] = gen_lowpart (mode, operands[0]); 6290 operands[1] = gen_lowpart (mode, operands[1]); 6291 operands[3] = gen_lowpart (mode, operands[3]); 6292 operands[4] = gen_lowpart (mode, operands[4]); 6293 6294 pat = gen_rtx_PLUS (mode, 6295 gen_rtx_PLUS (mode, 6296 gen_rtx_MULT (mode, operands[1], 6297 operands[2]), 6298 operands[3]), 6299 operands[4]); 6300 6301 emit_insn (gen_rtx_SET (VOIDmode, operands[0], pat)); 6302 DONE; 6303} 6304 [(set_attr "type" "lea") 6305 (set_attr "mode" "SI")]) 6306 6307(define_insn_and_split "*lea_general_4" 6308 [(set (match_operand 0 "register_operand" "=r") 6309 (any_or (ashift 6310 (match_operand 1 "index_register_operand" "l") 6311 (match_operand 2 "const_int_operand" "n")) 6312 (match_operand 3 "const_int_operand" "n")))] 6313 "(((GET_MODE (operands[0]) == QImode || GET_MODE (operands[0]) == HImode) 6314 && (!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))) 6315 || GET_MODE (operands[0]) == SImode 6316 || (TARGET_64BIT && GET_MODE (operands[0]) == DImode)) 6317 && GET_MODE (operands[0]) == GET_MODE (operands[1]) 6318 && ((unsigned HOST_WIDE_INT) INTVAL (operands[2])) - 1 < 3 6319 && ((unsigned HOST_WIDE_INT) INTVAL (operands[3]) 6320 < ((unsigned HOST_WIDE_INT) 1 << INTVAL (operands[2])))" 6321 "#" 6322 "&& reload_completed" 6323 [(const_int 0)] 6324{ 6325 enum machine_mode mode = GET_MODE (operands[0]); 6326 rtx pat; 6327 6328 if (GET_MODE_SIZE (mode) < GET_MODE_SIZE (SImode)) 6329 { 6330 mode = SImode; 6331 operands[0] = gen_lowpart (mode, operands[0]); 6332 operands[1] = gen_lowpart (mode, operands[1]); 6333 } 6334 6335 operands[2] = GEN_INT (1 << INTVAL (operands[2])); 6336 6337 pat = plus_constant (gen_rtx_MULT (mode, operands[1], operands[2]), 6338 INTVAL (operands[3])); 6339 6340 emit_insn (gen_rtx_SET (VOIDmode, operands[0], pat)); 6341 DONE; 6342} 6343 [(set_attr "type" "lea") 6344 (set (attr "mode") 6345 (if_then_else (match_operand:DI 0 "" "") 6346 (const_string "DI") 6347 (const_string "SI")))]) 6348 6349;; Subtract instructions 6350 6351(define_expand "sub<mode>3" 6352 [(set (match_operand:SDWIM 0 "nonimmediate_operand" "") 6353 (minus:SDWIM (match_operand:SDWIM 1 "nonimmediate_operand" "") 6354 (match_operand:SDWIM 2 "<general_operand>" "")))] 6355 "" 6356 "ix86_expand_binary_operator (MINUS, <MODE>mode, operands); DONE;") 6357 6358(define_insn_and_split "*sub<dwi>3_doubleword" 6359 [(set (match_operand:<DWI> 0 "nonimmediate_operand" "=r,o") 6360 (minus:<DWI> 6361 (match_operand:<DWI> 1 "nonimmediate_operand" "0,0") 6362 (match_operand:<DWI> 2 "<general_operand>" "ro<di>,r<di>"))) 6363 (clobber (reg:CC FLAGS_REG))] 6364 "ix86_binary_operator_ok (MINUS, <MODE>mode, operands)" 6365 "#" 6366 "reload_completed" 6367 [(parallel [(set (reg:CC FLAGS_REG) 6368 (compare:CC (match_dup 1) (match_dup 2))) 6369 (set (match_dup 0) 6370 (minus:DWIH (match_dup 1) (match_dup 2)))]) 6371 (parallel [(set (match_dup 3) 6372 (minus:DWIH 6373 (match_dup 4) 6374 (plus:DWIH 6375 (ltu:DWIH (reg:CC FLAGS_REG) (const_int 0)) 6376 (match_dup 5)))) 6377 (clobber (reg:CC FLAGS_REG))])] 6378 "split_double_mode (<DWI>mode, &operands[0], 3, &operands[0], &operands[3]);") 6379 6380(define_insn "*sub<mode>_1" 6381 [(set (match_operand:SWI 0 "nonimmediate_operand" "=<r>m,<r>") 6382 (minus:SWI 6383 (match_operand:SWI 1 "nonimmediate_operand" "0,0") 6384 (match_operand:SWI 2 "<general_operand>" "<r><i>,<r>m"))) 6385 (clobber (reg:CC FLAGS_REG))] 6386 "ix86_binary_operator_ok (MINUS, <MODE>mode, operands)" 6387 "sub{<imodesuffix>}\t{%2, %0|%0, %2}" 6388 [(set_attr "type" "alu") 6389 (set_attr "mode" "<MODE>")]) 6390 6391(define_insn "*subsi_1_zext" 6392 [(set (match_operand:DI 0 "register_operand" "=r") 6393 (zero_extend:DI 6394 (minus:SI (match_operand:SI 1 "register_operand" "0") 6395 (match_operand:SI 2 "x86_64_general_operand" "rme")))) 6396 (clobber (reg:CC FLAGS_REG))] 6397 "TARGET_64BIT && ix86_binary_operator_ok (MINUS, SImode, operands)" 6398 "sub{l}\t{%2, %k0|%k0, %2}" 6399 [(set_attr "type" "alu") 6400 (set_attr "mode" "SI")]) 6401 6402(define_insn "*subqi_1_slp" 6403 [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm,q")) 6404 (minus:QI (match_dup 0) 6405 (match_operand:QI 1 "general_operand" "qn,qm"))) 6406 (clobber (reg:CC FLAGS_REG))] 6407 "(! TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun)) 6408 && !(MEM_P (operands[0]) && MEM_P (operands[1]))" 6409 "sub{b}\t{%1, %0|%0, %1}" 6410 [(set_attr "type" "alu1") 6411 (set_attr "mode" "QI")]) 6412 6413(define_insn "*sub<mode>_2" 6414 [(set (reg FLAGS_REG) 6415 (compare 6416 (minus:SWI 6417 (match_operand:SWI 1 "nonimmediate_operand" "0,0") 6418 (match_operand:SWI 2 "<general_operand>" "<r><i>,<r>m")) 6419 (const_int 0))) 6420 (set (match_operand:SWI 0 "nonimmediate_operand" "=<r>m,<r>") 6421 (minus:SWI (match_dup 1) (match_dup 2)))] 6422 "ix86_match_ccmode (insn, CCGOCmode) 6423 && ix86_binary_operator_ok (MINUS, <MODE>mode, operands)" 6424 "sub{<imodesuffix>}\t{%2, %0|%0, %2}" 6425 [(set_attr "type" "alu") 6426 (set_attr "mode" "<MODE>")]) 6427 6428(define_insn "*subsi_2_zext" 6429 [(set (reg FLAGS_REG) 6430 (compare 6431 (minus:SI (match_operand:SI 1 "register_operand" "0") 6432 (match_operand:SI 2 "x86_64_general_operand" "rme")) 6433 (const_int 0))) 6434 (set (match_operand:DI 0 "register_operand" "=r") 6435 (zero_extend:DI 6436 (minus:SI (match_dup 1) 6437 (match_dup 2))))] 6438 "TARGET_64BIT && ix86_match_ccmode (insn, CCGOCmode) 6439 && ix86_binary_operator_ok (MINUS, SImode, operands)" 6440 "sub{l}\t{%2, %k0|%k0, %2}" 6441 [(set_attr "type" "alu") 6442 (set_attr "mode" "SI")]) 6443 6444(define_insn "*sub<mode>_3" 6445 [(set (reg FLAGS_REG) 6446 (compare (match_operand:SWI 1 "nonimmediate_operand" "0,0") 6447 (match_operand:SWI 2 "<general_operand>" "<r><i>,<r>m"))) 6448 (set (match_operand:SWI 0 "nonimmediate_operand" "=<r>m,<r>") 6449 (minus:SWI (match_dup 1) (match_dup 2)))] 6450 "ix86_match_ccmode (insn, CCmode) 6451 && ix86_binary_operator_ok (MINUS, <MODE>mode, operands)" 6452 "sub{<imodesuffix>}\t{%2, %0|%0, %2}" 6453 [(set_attr "type" "alu") 6454 (set_attr "mode" "<MODE>")]) 6455 6456(define_insn "*subsi_3_zext" 6457 [(set (reg FLAGS_REG) 6458 (compare (match_operand:SI 1 "register_operand" "0") 6459 (match_operand:SI 2 "x86_64_general_operand" "rme"))) 6460 (set (match_operand:DI 0 "register_operand" "=r") 6461 (zero_extend:DI 6462 (minus:SI (match_dup 1) 6463 (match_dup 2))))] 6464 "TARGET_64BIT && ix86_match_ccmode (insn, CCmode) 6465 && ix86_binary_operator_ok (MINUS, SImode, operands)" 6466 "sub{l}\t{%2, %1|%1, %2}" 6467 [(set_attr "type" "alu") 6468 (set_attr "mode" "SI")]) 6469 6470;; Add with carry and subtract with borrow 6471 6472(define_expand "<plusminus_insn><mode>3_carry" 6473 [(parallel 6474 [(set (match_operand:SWI 0 "nonimmediate_operand" "") 6475 (plusminus:SWI 6476 (match_operand:SWI 1 "nonimmediate_operand" "") 6477 (plus:SWI (match_operator:SWI 4 "ix86_carry_flag_operator" 6478 [(match_operand 3 "flags_reg_operand" "") 6479 (const_int 0)]) 6480 (match_operand:SWI 2 "<general_operand>" "")))) 6481 (clobber (reg:CC FLAGS_REG))])] 6482 "ix86_binary_operator_ok (<CODE>, <MODE>mode, operands)") 6483 6484(define_insn "*<plusminus_insn><mode>3_carry" 6485 [(set (match_operand:SWI 0 "nonimmediate_operand" "=<r>m,<r>") 6486 (plusminus:SWI 6487 (match_operand:SWI 1 "nonimmediate_operand" "<comm>0,0") 6488 (plus:SWI 6489 (match_operator 3 "ix86_carry_flag_operator" 6490 [(reg FLAGS_REG) (const_int 0)]) 6491 (match_operand:SWI 2 "<general_operand>" "<r><i>,<r>m")))) 6492 (clobber (reg:CC FLAGS_REG))] 6493 "ix86_binary_operator_ok (PLUS, <MODE>mode, operands)" 6494 "<plusminus_carry_mnemonic>{<imodesuffix>}\t{%2, %0|%0, %2}" 6495 [(set_attr "type" "alu") 6496 (set_attr "use_carry" "1") 6497 (set_attr "pent_pair" "pu") 6498 (set_attr "mode" "<MODE>")]) 6499 6500(define_insn "*addsi3_carry_zext" 6501 [(set (match_operand:DI 0 "register_operand" "=r") 6502 (zero_extend:DI 6503 (plus:SI (match_operand:SI 1 "nonimmediate_operand" "%0") 6504 (plus:SI (match_operator 3 "ix86_carry_flag_operator" 6505 [(reg FLAGS_REG) (const_int 0)]) 6506 (match_operand:SI 2 "x86_64_general_operand" "rme"))))) 6507 (clobber (reg:CC FLAGS_REG))] 6508 "TARGET_64BIT && ix86_binary_operator_ok (PLUS, SImode, operands)" 6509 "adc{l}\t{%2, %k0|%k0, %2}" 6510 [(set_attr "type" "alu") 6511 (set_attr "use_carry" "1") 6512 (set_attr "pent_pair" "pu") 6513 (set_attr "mode" "SI")]) 6514 6515(define_insn "*subsi3_carry_zext" 6516 [(set (match_operand:DI 0 "register_operand" "=r") 6517 (zero_extend:DI 6518 (minus:SI (match_operand:SI 1 "register_operand" "0") 6519 (plus:SI (match_operator 3 "ix86_carry_flag_operator" 6520 [(reg FLAGS_REG) (const_int 0)]) 6521 (match_operand:SI 2 "x86_64_general_operand" "rme"))))) 6522 (clobber (reg:CC FLAGS_REG))] 6523 "TARGET_64BIT && ix86_binary_operator_ok (MINUS, SImode, operands)" 6524 "sbb{l}\t{%2, %k0|%k0, %2}" 6525 [(set_attr "type" "alu") 6526 (set_attr "pent_pair" "pu") 6527 (set_attr "mode" "SI")]) 6528 6529;; Overflow setting add and subtract instructions 6530 6531(define_insn "*add<mode>3_cconly_overflow" 6532 [(set (reg:CCC FLAGS_REG) 6533 (compare:CCC 6534 (plus:SWI 6535 (match_operand:SWI 1 "nonimmediate_operand" "%0") 6536 (match_operand:SWI 2 "<general_operand>" "<g>")) 6537 (match_dup 1))) 6538 (clobber (match_scratch:SWI 0 "=<r>"))] 6539 "!(MEM_P (operands[1]) && MEM_P (operands[2]))" 6540 "add{<imodesuffix>}\t{%2, %0|%0, %2}" 6541 [(set_attr "type" "alu") 6542 (set_attr "mode" "<MODE>")]) 6543 6544(define_insn "*sub<mode>3_cconly_overflow" 6545 [(set (reg:CCC FLAGS_REG) 6546 (compare:CCC 6547 (minus:SWI 6548 (match_operand:SWI 0 "nonimmediate_operand" "<r>m,<r>") 6549 (match_operand:SWI 1 "<general_operand>" "<r><i>,<r>m")) 6550 (match_dup 0)))] 6551 "" 6552 "cmp{<imodesuffix>}\t{%1, %0|%0, %1}" 6553 [(set_attr "type" "icmp") 6554 (set_attr "mode" "<MODE>")]) 6555 6556(define_insn "*<plusminus_insn><mode>3_cc_overflow" 6557 [(set (reg:CCC FLAGS_REG) 6558 (compare:CCC 6559 (plusminus:SWI 6560 (match_operand:SWI 1 "nonimmediate_operand" "<comm>0,0") 6561 (match_operand:SWI 2 "<general_operand>" "<r><i>,<r>m")) 6562 (match_dup 1))) 6563 (set (match_operand:SWI 0 "nonimmediate_operand" "=<r>m,<r>") 6564 (plusminus:SWI (match_dup 1) (match_dup 2)))] 6565 "ix86_binary_operator_ok (<CODE>, <MODE>mode, operands)" 6566 "<plusminus_mnemonic>{<imodesuffix>}\t{%2, %0|%0, %2}" 6567 [(set_attr "type" "alu") 6568 (set_attr "mode" "<MODE>")]) 6569 6570(define_insn "*<plusminus_insn>si3_zext_cc_overflow" 6571 [(set (reg:CCC FLAGS_REG) 6572 (compare:CCC 6573 (plusminus:SI 6574 (match_operand:SI 1 "nonimmediate_operand" "<comm>0") 6575 (match_operand:SI 2 "x86_64_general_operand" "rme")) 6576 (match_dup 1))) 6577 (set (match_operand:DI 0 "register_operand" "=r") 6578 (zero_extend:DI (plusminus:SI (match_dup 1) (match_dup 2))))] 6579 "TARGET_64BIT && ix86_binary_operator_ok (<CODE>, SImode, operands)" 6580 "<plusminus_mnemonic>{l}\t{%2, %k0|%k0, %2}" 6581 [(set_attr "type" "alu") 6582 (set_attr "mode" "SI")]) 6583 6584;; The patterns that match these are at the end of this file. 6585 6586(define_expand "<plusminus_insn>xf3" 6587 [(set (match_operand:XF 0 "register_operand" "") 6588 (plusminus:XF 6589 (match_operand:XF 1 "register_operand" "") 6590 (match_operand:XF 2 "register_operand" "")))] 6591 "TARGET_80387") 6592 6593(define_expand "<plusminus_insn><mode>3" 6594 [(set (match_operand:MODEF 0 "register_operand" "") 6595 (plusminus:MODEF 6596 (match_operand:MODEF 1 "register_operand" "") 6597 (match_operand:MODEF 2 "nonimmediate_operand" "")))] 6598 "(TARGET_80387 && X87_ENABLE_ARITH (<MODE>mode)) 6599 || (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)") 6600 6601;; Multiply instructions 6602 6603(define_expand "mul<mode>3" 6604 [(parallel [(set (match_operand:SWIM248 0 "register_operand" "") 6605 (mult:SWIM248 6606 (match_operand:SWIM248 1 "register_operand" "") 6607 (match_operand:SWIM248 2 "<general_operand>" ""))) 6608 (clobber (reg:CC FLAGS_REG))])]) 6609 6610(define_expand "mulqi3" 6611 [(parallel [(set (match_operand:QI 0 "register_operand" "") 6612 (mult:QI 6613 (match_operand:QI 1 "register_operand" "") 6614 (match_operand:QI 2 "nonimmediate_operand" ""))) 6615 (clobber (reg:CC FLAGS_REG))])] 6616 "TARGET_QIMODE_MATH") 6617 6618;; On AMDFAM10 6619;; IMUL reg32/64, reg32/64, imm8 Direct 6620;; IMUL reg32/64, mem32/64, imm8 VectorPath 6621;; IMUL reg32/64, reg32/64, imm32 Direct 6622;; IMUL reg32/64, mem32/64, imm32 VectorPath 6623;; IMUL reg32/64, reg32/64 Direct 6624;; IMUL reg32/64, mem32/64 Direct 6625;; 6626;; On BDVER1, all above IMULs use DirectPath 6627 6628(define_insn "*mul<mode>3_1" 6629 [(set (match_operand:SWI48 0 "register_operand" "=r,r,r") 6630 (mult:SWI48 6631 (match_operand:SWI48 1 "nonimmediate_operand" "%rm,rm,0") 6632 (match_operand:SWI48 2 "<general_operand>" "K,<i>,mr"))) 6633 (clobber (reg:CC FLAGS_REG))] 6634 "!(MEM_P (operands[1]) && MEM_P (operands[2]))" 6635 "@ 6636 imul{<imodesuffix>}\t{%2, %1, %0|%0, %1, %2} 6637 imul{<imodesuffix>}\t{%2, %1, %0|%0, %1, %2} 6638 imul{<imodesuffix>}\t{%2, %0|%0, %2}" 6639 [(set_attr "type" "imul") 6640 (set_attr "prefix_0f" "0,0,1") 6641 (set (attr "athlon_decode") 6642 (cond [(eq_attr "cpu" "athlon") 6643 (const_string "vector") 6644 (eq_attr "alternative" "1") 6645 (const_string "vector") 6646 (and (eq_attr "alternative" "2") 6647 (match_operand 1 "memory_operand" "")) 6648 (const_string "vector")] 6649 (const_string "direct"))) 6650 (set (attr "amdfam10_decode") 6651 (cond [(and (eq_attr "alternative" "0,1") 6652 (match_operand 1 "memory_operand" "")) 6653 (const_string "vector")] 6654 (const_string "direct"))) 6655 (set_attr "bdver1_decode" "direct") 6656 (set_attr "mode" "<MODE>")]) 6657 6658(define_insn "*mulsi3_1_zext" 6659 [(set (match_operand:DI 0 "register_operand" "=r,r,r") 6660 (zero_extend:DI 6661 (mult:SI (match_operand:SI 1 "nonimmediate_operand" "%rm,rm,0") 6662 (match_operand:SI 2 "x86_64_general_operand" "K,e,mr")))) 6663 (clobber (reg:CC FLAGS_REG))] 6664 "TARGET_64BIT 6665 && !(MEM_P (operands[1]) && MEM_P (operands[2]))" 6666 "@ 6667 imul{l}\t{%2, %1, %k0|%k0, %1, %2} 6668 imul{l}\t{%2, %1, %k0|%k0, %1, %2} 6669 imul{l}\t{%2, %k0|%k0, %2}" 6670 [(set_attr "type" "imul") 6671 (set_attr "prefix_0f" "0,0,1") 6672 (set (attr "athlon_decode") 6673 (cond [(eq_attr "cpu" "athlon") 6674 (const_string "vector") 6675 (eq_attr "alternative" "1") 6676 (const_string "vector") 6677 (and (eq_attr "alternative" "2") 6678 (match_operand 1 "memory_operand" "")) 6679 (const_string "vector")] 6680 (const_string "direct"))) 6681 (set (attr "amdfam10_decode") 6682 (cond [(and (eq_attr "alternative" "0,1") 6683 (match_operand 1 "memory_operand" "")) 6684 (const_string "vector")] 6685 (const_string "direct"))) 6686 (set_attr "bdver1_decode" "direct") 6687 (set_attr "mode" "SI")]) 6688 6689;; On AMDFAM10 6690;; IMUL reg16, reg16, imm8 VectorPath 6691;; IMUL reg16, mem16, imm8 VectorPath 6692;; IMUL reg16, reg16, imm16 VectorPath 6693;; IMUL reg16, mem16, imm16 VectorPath 6694;; IMUL reg16, reg16 Direct 6695;; IMUL reg16, mem16 Direct 6696;; 6697;; On BDVER1, all HI MULs use DoublePath 6698 6699(define_insn "*mulhi3_1" 6700 [(set (match_operand:HI 0 "register_operand" "=r,r,r") 6701 (mult:HI (match_operand:HI 1 "nonimmediate_operand" "%rm,rm,0") 6702 (match_operand:HI 2 "general_operand" "K,n,mr"))) 6703 (clobber (reg:CC FLAGS_REG))] 6704 "TARGET_HIMODE_MATH 6705 && !(MEM_P (operands[1]) && MEM_P (operands[2]))" 6706 "@ 6707 imul{w}\t{%2, %1, %0|%0, %1, %2} 6708 imul{w}\t{%2, %1, %0|%0, %1, %2} 6709 imul{w}\t{%2, %0|%0, %2}" 6710 [(set_attr "type" "imul") 6711 (set_attr "prefix_0f" "0,0,1") 6712 (set (attr "athlon_decode") 6713 (cond [(eq_attr "cpu" "athlon") 6714 (const_string "vector") 6715 (eq_attr "alternative" "1,2") 6716 (const_string "vector")] 6717 (const_string "direct"))) 6718 (set (attr "amdfam10_decode") 6719 (cond [(eq_attr "alternative" "0,1") 6720 (const_string "vector")] 6721 (const_string "direct"))) 6722 (set_attr "bdver1_decode" "double") 6723 (set_attr "mode" "HI")]) 6724 6725;;On AMDFAM10 and BDVER1 6726;; MUL reg8 Direct 6727;; MUL mem8 Direct 6728 6729(define_insn "*mulqi3_1" 6730 [(set (match_operand:QI 0 "register_operand" "=a") 6731 (mult:QI (match_operand:QI 1 "nonimmediate_operand" "%0") 6732 (match_operand:QI 2 "nonimmediate_operand" "qm"))) 6733 (clobber (reg:CC FLAGS_REG))] 6734 "TARGET_QIMODE_MATH 6735 && !(MEM_P (operands[1]) && MEM_P (operands[2]))" 6736 "mul{b}\t%2" 6737 [(set_attr "type" "imul") 6738 (set_attr "length_immediate" "0") 6739 (set (attr "athlon_decode") 6740 (if_then_else (eq_attr "cpu" "athlon") 6741 (const_string "vector") 6742 (const_string "direct"))) 6743 (set_attr "amdfam10_decode" "direct") 6744 (set_attr "bdver1_decode" "direct") 6745 (set_attr "mode" "QI")]) 6746 6747(define_expand "<u>mul<mode><dwi>3" 6748 [(parallel [(set (match_operand:<DWI> 0 "register_operand" "") 6749 (mult:<DWI> 6750 (any_extend:<DWI> 6751 (match_operand:DWIH 1 "nonimmediate_operand" "")) 6752 (any_extend:<DWI> 6753 (match_operand:DWIH 2 "register_operand" "")))) 6754 (clobber (reg:CC FLAGS_REG))])]) 6755 6756(define_expand "<u>mulqihi3" 6757 [(parallel [(set (match_operand:HI 0 "register_operand" "") 6758 (mult:HI 6759 (any_extend:HI 6760 (match_operand:QI 1 "nonimmediate_operand" "")) 6761 (any_extend:HI 6762 (match_operand:QI 2 "register_operand" "")))) 6763 (clobber (reg:CC FLAGS_REG))])] 6764 "TARGET_QIMODE_MATH") 6765 6766(define_insn "*bmi2_umulditi3_1" 6767 [(set (match_operand:DI 0 "register_operand" "=r") 6768 (mult:DI 6769 (match_operand:DI 2 "nonimmediate_operand" "%d") 6770 (match_operand:DI 3 "nonimmediate_operand" "rm"))) 6771 (set (match_operand:DI 1 "register_operand" "=r") 6772 (truncate:DI 6773 (lshiftrt:TI 6774 (mult:TI (zero_extend:TI (match_dup 2)) 6775 (zero_extend:TI (match_dup 3))) 6776 (const_int 64))))] 6777 "TARGET_64BIT && TARGET_BMI2 6778 && !(MEM_P (operands[1]) && MEM_P (operands[2]))" 6779 "mulx\t{%3, %0, %1|%1, %0, %3}" 6780 [(set_attr "type" "imulx") 6781 (set_attr "prefix" "vex") 6782 (set_attr "mode" "DI")]) 6783 6784(define_insn "*bmi2_umulsidi3_1" 6785 [(set (match_operand:SI 0 "register_operand" "=r") 6786 (mult:SI 6787 (match_operand:SI 2 "nonimmediate_operand" "%d") 6788 (match_operand:SI 3 "nonimmediate_operand" "rm"))) 6789 (set (match_operand:SI 1 "register_operand" "=r") 6790 (truncate:SI 6791 (lshiftrt:DI 6792 (mult:DI (zero_extend:DI (match_dup 2)) 6793 (zero_extend:DI (match_dup 3))) 6794 (const_int 32))))] 6795 "!TARGET_64BIT && TARGET_BMI2 6796 && !(MEM_P (operands[1]) && MEM_P (operands[2]))" 6797 "mulx\t{%3, %0, %1|%1, %0, %3}" 6798 [(set_attr "type" "imulx") 6799 (set_attr "prefix" "vex") 6800 (set_attr "mode" "SI")]) 6801 6802(define_insn "*umul<mode><dwi>3_1" 6803 [(set (match_operand:<DWI> 0 "register_operand" "=A,r") 6804 (mult:<DWI> 6805 (zero_extend:<DWI> 6806 (match_operand:DWIH 1 "nonimmediate_operand" "%0,d")) 6807 (zero_extend:<DWI> 6808 (match_operand:DWIH 2 "nonimmediate_operand" "rm,rm")))) 6809 (clobber (reg:CC FLAGS_REG))] 6810 "!(MEM_P (operands[1]) && MEM_P (operands[2]))" 6811 "@ 6812 mul{<imodesuffix>}\t%2 6813 #" 6814 [(set_attr "isa" "*,bmi2") 6815 (set_attr "type" "imul,imulx") 6816 (set_attr "length_immediate" "0,*") 6817 (set (attr "athlon_decode") 6818 (cond [(eq_attr "alternative" "0") 6819 (if_then_else (eq_attr "cpu" "athlon") 6820 (const_string "vector") 6821 (const_string "double"))] 6822 (const_string "*"))) 6823 (set_attr "amdfam10_decode" "double,*") 6824 (set_attr "bdver1_decode" "direct,*") 6825 (set_attr "prefix" "orig,vex") 6826 (set_attr "mode" "<MODE>")]) 6827 6828;; Convert mul to the mulx pattern to avoid flags dependency. 6829(define_split 6830 [(set (match_operand:<DWI> 0 "register_operand" "") 6831 (mult:<DWI> 6832 (zero_extend:<DWI> 6833 (match_operand:DWIH 1 "register_operand" "")) 6834 (zero_extend:<DWI> 6835 (match_operand:DWIH 2 "nonimmediate_operand" "")))) 6836 (clobber (reg:CC FLAGS_REG))] 6837 "TARGET_BMI2 && reload_completed 6838 && true_regnum (operands[1]) == DX_REG" 6839 [(parallel [(set (match_dup 3) 6840 (mult:DWIH (match_dup 1) (match_dup 2))) 6841 (set (match_dup 4) 6842 (truncate:DWIH 6843 (lshiftrt:<DWI> 6844 (mult:<DWI> (zero_extend:<DWI> (match_dup 1)) 6845 (zero_extend:<DWI> (match_dup 2))) 6846 (match_dup 5))))])] 6847{ 6848 split_double_mode (<DWI>mode, &operands[0], 1, &operands[3], &operands[4]); 6849 6850 operands[5] = GEN_INT (GET_MODE_BITSIZE (<MODE>mode)); 6851}) 6852 6853(define_insn "*mul<mode><dwi>3_1" 6854 [(set (match_operand:<DWI> 0 "register_operand" "=A") 6855 (mult:<DWI> 6856 (sign_extend:<DWI> 6857 (match_operand:DWIH 1 "nonimmediate_operand" "%0")) 6858 (sign_extend:<DWI> 6859 (match_operand:DWIH 2 "nonimmediate_operand" "rm")))) 6860 (clobber (reg:CC FLAGS_REG))] 6861 "!(MEM_P (operands[1]) && MEM_P (operands[2]))" 6862 "imul{<imodesuffix>}\t%2" 6863 [(set_attr "type" "imul") 6864 (set_attr "length_immediate" "0") 6865 (set (attr "athlon_decode") 6866 (if_then_else (eq_attr "cpu" "athlon") 6867 (const_string "vector") 6868 (const_string "double"))) 6869 (set_attr "amdfam10_decode" "double") 6870 (set_attr "bdver1_decode" "direct") 6871 (set_attr "mode" "<MODE>")]) 6872 6873(define_insn "*<u>mulqihi3_1" 6874 [(set (match_operand:HI 0 "register_operand" "=a") 6875 (mult:HI 6876 (any_extend:HI 6877 (match_operand:QI 1 "nonimmediate_operand" "%0")) 6878 (any_extend:HI 6879 (match_operand:QI 2 "nonimmediate_operand" "qm")))) 6880 (clobber (reg:CC FLAGS_REG))] 6881 "TARGET_QIMODE_MATH 6882 && !(MEM_P (operands[1]) && MEM_P (operands[2]))" 6883 "<sgnprefix>mul{b}\t%2" 6884 [(set_attr "type" "imul") 6885 (set_attr "length_immediate" "0") 6886 (set (attr "athlon_decode") 6887 (if_then_else (eq_attr "cpu" "athlon") 6888 (const_string "vector") 6889 (const_string "direct"))) 6890 (set_attr "amdfam10_decode" "direct") 6891 (set_attr "bdver1_decode" "direct") 6892 (set_attr "mode" "QI")]) 6893 6894(define_expand "<s>mul<mode>3_highpart" 6895 [(parallel [(set (match_operand:SWI48 0 "register_operand" "") 6896 (truncate:SWI48 6897 (lshiftrt:<DWI> 6898 (mult:<DWI> 6899 (any_extend:<DWI> 6900 (match_operand:SWI48 1 "nonimmediate_operand" "")) 6901 (any_extend:<DWI> 6902 (match_operand:SWI48 2 "register_operand" ""))) 6903 (match_dup 4)))) 6904 (clobber (match_scratch:SWI48 3 "")) 6905 (clobber (reg:CC FLAGS_REG))])] 6906 "" 6907 "operands[4] = GEN_INT (GET_MODE_BITSIZE (<MODE>mode));") 6908 6909(define_insn "*<s>muldi3_highpart_1" 6910 [(set (match_operand:DI 0 "register_operand" "=d") 6911 (truncate:DI 6912 (lshiftrt:TI 6913 (mult:TI 6914 (any_extend:TI 6915 (match_operand:DI 1 "nonimmediate_operand" "%a")) 6916 (any_extend:TI 6917 (match_operand:DI 2 "nonimmediate_operand" "rm"))) 6918 (const_int 64)))) 6919 (clobber (match_scratch:DI 3 "=1")) 6920 (clobber (reg:CC FLAGS_REG))] 6921 "TARGET_64BIT 6922 && !(MEM_P (operands[1]) && MEM_P (operands[2]))" 6923 "<sgnprefix>mul{q}\t%2" 6924 [(set_attr "type" "imul") 6925 (set_attr "length_immediate" "0") 6926 (set (attr "athlon_decode") 6927 (if_then_else (eq_attr "cpu" "athlon") 6928 (const_string "vector") 6929 (const_string "double"))) 6930 (set_attr "amdfam10_decode" "double") 6931 (set_attr "bdver1_decode" "direct") 6932 (set_attr "mode" "DI")]) 6933 6934(define_insn "*<s>mulsi3_highpart_1" 6935 [(set (match_operand:SI 0 "register_operand" "=d") 6936 (truncate:SI 6937 (lshiftrt:DI 6938 (mult:DI 6939 (any_extend:DI 6940 (match_operand:SI 1 "nonimmediate_operand" "%a")) 6941 (any_extend:DI 6942 (match_operand:SI 2 "nonimmediate_operand" "rm"))) 6943 (const_int 32)))) 6944 (clobber (match_scratch:SI 3 "=1")) 6945 (clobber (reg:CC FLAGS_REG))] 6946 "!(MEM_P (operands[1]) && MEM_P (operands[2]))" 6947 "<sgnprefix>mul{l}\t%2" 6948 [(set_attr "type" "imul") 6949 (set_attr "length_immediate" "0") 6950 (set (attr "athlon_decode") 6951 (if_then_else (eq_attr "cpu" "athlon") 6952 (const_string "vector") 6953 (const_string "double"))) 6954 (set_attr "amdfam10_decode" "double") 6955 (set_attr "bdver1_decode" "direct") 6956 (set_attr "mode" "SI")]) 6957 6958(define_insn "*<s>mulsi3_highpart_zext" 6959 [(set (match_operand:DI 0 "register_operand" "=d") 6960 (zero_extend:DI (truncate:SI 6961 (lshiftrt:DI 6962 (mult:DI (any_extend:DI 6963 (match_operand:SI 1 "nonimmediate_operand" "%a")) 6964 (any_extend:DI 6965 (match_operand:SI 2 "nonimmediate_operand" "rm"))) 6966 (const_int 32))))) 6967 (clobber (match_scratch:SI 3 "=1")) 6968 (clobber (reg:CC FLAGS_REG))] 6969 "TARGET_64BIT 6970 && !(MEM_P (operands[1]) && MEM_P (operands[2]))" 6971 "<sgnprefix>mul{l}\t%2" 6972 [(set_attr "type" "imul") 6973 (set_attr "length_immediate" "0") 6974 (set (attr "athlon_decode") 6975 (if_then_else (eq_attr "cpu" "athlon") 6976 (const_string "vector") 6977 (const_string "double"))) 6978 (set_attr "amdfam10_decode" "double") 6979 (set_attr "bdver1_decode" "direct") 6980 (set_attr "mode" "SI")]) 6981 6982;; The patterns that match these are at the end of this file. 6983 6984(define_expand "mulxf3" 6985 [(set (match_operand:XF 0 "register_operand" "") 6986 (mult:XF (match_operand:XF 1 "register_operand" "") 6987 (match_operand:XF 2 "register_operand" "")))] 6988 "TARGET_80387") 6989 6990(define_expand "mul<mode>3" 6991 [(set (match_operand:MODEF 0 "register_operand" "") 6992 (mult:MODEF (match_operand:MODEF 1 "register_operand" "") 6993 (match_operand:MODEF 2 "nonimmediate_operand" "")))] 6994 "(TARGET_80387 && X87_ENABLE_ARITH (<MODE>mode)) 6995 || (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)") 6996 6997;; Divide instructions 6998 6999;; The patterns that match these are at the end of this file. 7000 7001(define_expand "divxf3" 7002 [(set (match_operand:XF 0 "register_operand" "") 7003 (div:XF (match_operand:XF 1 "register_operand" "") 7004 (match_operand:XF 2 "register_operand" "")))] 7005 "TARGET_80387") 7006 7007(define_expand "divdf3" 7008 [(set (match_operand:DF 0 "register_operand" "") 7009 (div:DF (match_operand:DF 1 "register_operand" "") 7010 (match_operand:DF 2 "nonimmediate_operand" "")))] 7011 "(TARGET_80387 && X87_ENABLE_ARITH (DFmode)) 7012 || (TARGET_SSE2 && TARGET_SSE_MATH)") 7013 7014(define_expand "divsf3" 7015 [(set (match_operand:SF 0 "register_operand" "") 7016 (div:SF (match_operand:SF 1 "register_operand" "") 7017 (match_operand:SF 2 "nonimmediate_operand" "")))] 7018 "(TARGET_80387 && X87_ENABLE_ARITH (SFmode)) 7019 || TARGET_SSE_MATH" 7020{ 7021 if (TARGET_SSE_MATH 7022 && TARGET_RECIP_DIV 7023 && optimize_insn_for_speed_p () 7024 && flag_finite_math_only && !flag_trapping_math 7025 && flag_unsafe_math_optimizations) 7026 { 7027 ix86_emit_swdivsf (operands[0], operands[1], 7028 operands[2], SFmode); 7029 DONE; 7030 } 7031}) 7032 7033;; Divmod instructions. 7034 7035(define_expand "divmod<mode>4" 7036 [(parallel [(set (match_operand:SWIM248 0 "register_operand" "") 7037 (div:SWIM248 7038 (match_operand:SWIM248 1 "register_operand" "") 7039 (match_operand:SWIM248 2 "nonimmediate_operand" ""))) 7040 (set (match_operand:SWIM248 3 "register_operand" "") 7041 (mod:SWIM248 (match_dup 1) (match_dup 2))) 7042 (clobber (reg:CC FLAGS_REG))])]) 7043 7044;; Split with 8bit unsigned divide: 7045;; if (dividend an divisor are in [0-255]) 7046;; use 8bit unsigned integer divide 7047;; else 7048;; use original integer divide 7049(define_split 7050 [(set (match_operand:SWI48 0 "register_operand" "") 7051 (div:SWI48 (match_operand:SWI48 2 "register_operand" "") 7052 (match_operand:SWI48 3 "nonimmediate_operand" ""))) 7053 (set (match_operand:SWI48 1 "register_operand" "") 7054 (mod:SWI48 (match_dup 2) (match_dup 3))) 7055 (clobber (reg:CC FLAGS_REG))] 7056 "TARGET_USE_8BIT_IDIV 7057 && TARGET_QIMODE_MATH 7058 && can_create_pseudo_p () 7059 && !optimize_insn_for_size_p ()" 7060 [(const_int 0)] 7061 "ix86_split_idivmod (<MODE>mode, operands, true); DONE;") 7062 7063(define_insn_and_split "divmod<mode>4_1" 7064 [(set (match_operand:SWI48 0 "register_operand" "=a") 7065 (div:SWI48 (match_operand:SWI48 2 "register_operand" "0") 7066 (match_operand:SWI48 3 "nonimmediate_operand" "rm"))) 7067 (set (match_operand:SWI48 1 "register_operand" "=&d") 7068 (mod:SWI48 (match_dup 2) (match_dup 3))) 7069 (unspec [(const_int 0)] UNSPEC_DIV_ALREADY_SPLIT) 7070 (clobber (reg:CC FLAGS_REG))] 7071 "" 7072 "#" 7073 "reload_completed" 7074 [(parallel [(set (match_dup 1) 7075 (ashiftrt:SWI48 (match_dup 4) (match_dup 5))) 7076 (clobber (reg:CC FLAGS_REG))]) 7077 (parallel [(set (match_dup 0) 7078 (div:SWI48 (match_dup 2) (match_dup 3))) 7079 (set (match_dup 1) 7080 (mod:SWI48 (match_dup 2) (match_dup 3))) 7081 (use (match_dup 1)) 7082 (clobber (reg:CC FLAGS_REG))])] 7083{ 7084 operands[5] = GEN_INT (GET_MODE_BITSIZE (<MODE>mode)-1); 7085 7086 if (optimize_function_for_size_p (cfun) || TARGET_USE_CLTD) 7087 operands[4] = operands[2]; 7088 else 7089 { 7090 /* Avoid use of cltd in favor of a mov+shift. */ 7091 emit_move_insn (operands[1], operands[2]); 7092 operands[4] = operands[1]; 7093 } 7094} 7095 [(set_attr "type" "multi") 7096 (set_attr "mode" "<MODE>")]) 7097 7098(define_insn_and_split "*divmod<mode>4" 7099 [(set (match_operand:SWIM248 0 "register_operand" "=a") 7100 (div:SWIM248 (match_operand:SWIM248 2 "register_operand" "0") 7101 (match_operand:SWIM248 3 "nonimmediate_operand" "rm"))) 7102 (set (match_operand:SWIM248 1 "register_operand" "=&d") 7103 (mod:SWIM248 (match_dup 2) (match_dup 3))) 7104 (clobber (reg:CC FLAGS_REG))] 7105 "" 7106 "#" 7107 "reload_completed" 7108 [(parallel [(set (match_dup 1) 7109 (ashiftrt:SWIM248 (match_dup 4) (match_dup 5))) 7110 (clobber (reg:CC FLAGS_REG))]) 7111 (parallel [(set (match_dup 0) 7112 (div:SWIM248 (match_dup 2) (match_dup 3))) 7113 (set (match_dup 1) 7114 (mod:SWIM248 (match_dup 2) (match_dup 3))) 7115 (use (match_dup 1)) 7116 (clobber (reg:CC FLAGS_REG))])] 7117{ 7118 operands[5] = GEN_INT (GET_MODE_BITSIZE (<MODE>mode)-1); 7119 7120 if (<MODE>mode != HImode 7121 && (optimize_function_for_size_p (cfun) || TARGET_USE_CLTD)) 7122 operands[4] = operands[2]; 7123 else 7124 { 7125 /* Avoid use of cltd in favor of a mov+shift. */ 7126 emit_move_insn (operands[1], operands[2]); 7127 operands[4] = operands[1]; 7128 } 7129} 7130 [(set_attr "type" "multi") 7131 (set_attr "mode" "<MODE>")]) 7132 7133(define_insn "*divmod<mode>4_noext" 7134 [(set (match_operand:SWIM248 0 "register_operand" "=a") 7135 (div:SWIM248 (match_operand:SWIM248 2 "register_operand" "0") 7136 (match_operand:SWIM248 3 "nonimmediate_operand" "rm"))) 7137 (set (match_operand:SWIM248 1 "register_operand" "=d") 7138 (mod:SWIM248 (match_dup 2) (match_dup 3))) 7139 (use (match_operand:SWIM248 4 "register_operand" "1")) 7140 (clobber (reg:CC FLAGS_REG))] 7141 "" 7142 "idiv{<imodesuffix>}\t%3" 7143 [(set_attr "type" "idiv") 7144 (set_attr "mode" "<MODE>")]) 7145 7146(define_expand "divmodqi4" 7147 [(parallel [(set (match_operand:QI 0 "register_operand" "") 7148 (div:QI 7149 (match_operand:QI 1 "register_operand" "") 7150 (match_operand:QI 2 "nonimmediate_operand" ""))) 7151 (set (match_operand:QI 3 "register_operand" "") 7152 (mod:QI (match_dup 1) (match_dup 2))) 7153 (clobber (reg:CC FLAGS_REG))])] 7154 "TARGET_QIMODE_MATH" 7155{ 7156 rtx div, mod, insn; 7157 rtx tmp0, tmp1; 7158 7159 tmp0 = gen_reg_rtx (HImode); 7160 tmp1 = gen_reg_rtx (HImode); 7161 7162 /* Extend operands[1] to HImode. Generate 8bit divide. Result is 7163 in AX. */ 7164 emit_insn (gen_extendqihi2 (tmp1, operands[1])); 7165 emit_insn (gen_divmodhiqi3 (tmp0, tmp1, operands[2])); 7166 7167 /* Extract remainder from AH. */ 7168 tmp1 = gen_rtx_SIGN_EXTRACT (QImode, tmp0, GEN_INT (8), GEN_INT (8)); 7169 insn = emit_move_insn (operands[3], tmp1); 7170 7171 mod = gen_rtx_MOD (QImode, operands[1], operands[2]); 7172 set_unique_reg_note (insn, REG_EQUAL, mod); 7173 7174 /* Extract quotient from AL. */ 7175 insn = emit_move_insn (operands[0], gen_lowpart (QImode, tmp0)); 7176 7177 div = gen_rtx_DIV (QImode, operands[1], operands[2]); 7178 set_unique_reg_note (insn, REG_EQUAL, div); 7179 7180 DONE; 7181}) 7182 7183;; Divide AX by r/m8, with result stored in 7184;; AL <- Quotient 7185;; AH <- Remainder 7186;; Change div/mod to HImode and extend the second argument to HImode 7187;; so that mode of div/mod matches with mode of arguments. Otherwise 7188;; combine may fail. 7189(define_insn "divmodhiqi3" 7190 [(set (match_operand:HI 0 "register_operand" "=a") 7191 (ior:HI 7192 (ashift:HI 7193 (zero_extend:HI 7194 (truncate:QI 7195 (mod:HI (match_operand:HI 1 "register_operand" "0") 7196 (sign_extend:HI 7197 (match_operand:QI 2 "nonimmediate_operand" "qm"))))) 7198 (const_int 8)) 7199 (zero_extend:HI 7200 (truncate:QI 7201 (div:HI (match_dup 1) (sign_extend:HI (match_dup 2))))))) 7202 (clobber (reg:CC FLAGS_REG))] 7203 "TARGET_QIMODE_MATH" 7204 "idiv{b}\t%2" 7205 [(set_attr "type" "idiv") 7206 (set_attr "mode" "QI")]) 7207 7208(define_expand "udivmod<mode>4" 7209 [(parallel [(set (match_operand:SWIM248 0 "register_operand" "") 7210 (udiv:SWIM248 7211 (match_operand:SWIM248 1 "register_operand" "") 7212 (match_operand:SWIM248 2 "nonimmediate_operand" ""))) 7213 (set (match_operand:SWIM248 3 "register_operand" "") 7214 (umod:SWIM248 (match_dup 1) (match_dup 2))) 7215 (clobber (reg:CC FLAGS_REG))])]) 7216 7217;; Split with 8bit unsigned divide: 7218;; if (dividend an divisor are in [0-255]) 7219;; use 8bit unsigned integer divide 7220;; else 7221;; use original integer divide 7222(define_split 7223 [(set (match_operand:SWI48 0 "register_operand" "") 7224 (udiv:SWI48 (match_operand:SWI48 2 "register_operand" "") 7225 (match_operand:SWI48 3 "nonimmediate_operand" ""))) 7226 (set (match_operand:SWI48 1 "register_operand" "") 7227 (umod:SWI48 (match_dup 2) (match_dup 3))) 7228 (clobber (reg:CC FLAGS_REG))] 7229 "TARGET_USE_8BIT_IDIV 7230 && TARGET_QIMODE_MATH 7231 && can_create_pseudo_p () 7232 && !optimize_insn_for_size_p ()" 7233 [(const_int 0)] 7234 "ix86_split_idivmod (<MODE>mode, operands, false); DONE;") 7235 7236(define_insn_and_split "udivmod<mode>4_1" 7237 [(set (match_operand:SWI48 0 "register_operand" "=a") 7238 (udiv:SWI48 (match_operand:SWI48 2 "register_operand" "0") 7239 (match_operand:SWI48 3 "nonimmediate_operand" "rm"))) 7240 (set (match_operand:SWI48 1 "register_operand" "=&d") 7241 (umod:SWI48 (match_dup 2) (match_dup 3))) 7242 (unspec [(const_int 0)] UNSPEC_DIV_ALREADY_SPLIT) 7243 (clobber (reg:CC FLAGS_REG))] 7244 "" 7245 "#" 7246 "reload_completed" 7247 [(set (match_dup 1) (const_int 0)) 7248 (parallel [(set (match_dup 0) 7249 (udiv:SWI48 (match_dup 2) (match_dup 3))) 7250 (set (match_dup 1) 7251 (umod:SWI48 (match_dup 2) (match_dup 3))) 7252 (use (match_dup 1)) 7253 (clobber (reg:CC FLAGS_REG))])] 7254 "" 7255 [(set_attr "type" "multi") 7256 (set_attr "mode" "<MODE>")]) 7257 7258(define_insn_and_split "*udivmod<mode>4" 7259 [(set (match_operand:SWIM248 0 "register_operand" "=a") 7260 (udiv:SWIM248 (match_operand:SWIM248 2 "register_operand" "0") 7261 (match_operand:SWIM248 3 "nonimmediate_operand" "rm"))) 7262 (set (match_operand:SWIM248 1 "register_operand" "=&d") 7263 (umod:SWIM248 (match_dup 2) (match_dup 3))) 7264 (clobber (reg:CC FLAGS_REG))] 7265 "" 7266 "#" 7267 "reload_completed" 7268 [(set (match_dup 1) (const_int 0)) 7269 (parallel [(set (match_dup 0) 7270 (udiv:SWIM248 (match_dup 2) (match_dup 3))) 7271 (set (match_dup 1) 7272 (umod:SWIM248 (match_dup 2) (match_dup 3))) 7273 (use (match_dup 1)) 7274 (clobber (reg:CC FLAGS_REG))])] 7275 "" 7276 [(set_attr "type" "multi") 7277 (set_attr "mode" "<MODE>")]) 7278 7279(define_insn "*udivmod<mode>4_noext" 7280 [(set (match_operand:SWIM248 0 "register_operand" "=a") 7281 (udiv:SWIM248 (match_operand:SWIM248 2 "register_operand" "0") 7282 (match_operand:SWIM248 3 "nonimmediate_operand" "rm"))) 7283 (set (match_operand:SWIM248 1 "register_operand" "=d") 7284 (umod:SWIM248 (match_dup 2) (match_dup 3))) 7285 (use (match_operand:SWIM248 4 "register_operand" "1")) 7286 (clobber (reg:CC FLAGS_REG))] 7287 "" 7288 "div{<imodesuffix>}\t%3" 7289 [(set_attr "type" "idiv") 7290 (set_attr "mode" "<MODE>")]) 7291 7292(define_expand "udivmodqi4" 7293 [(parallel [(set (match_operand:QI 0 "register_operand" "") 7294 (udiv:QI 7295 (match_operand:QI 1 "register_operand" "") 7296 (match_operand:QI 2 "nonimmediate_operand" ""))) 7297 (set (match_operand:QI 3 "register_operand" "") 7298 (umod:QI (match_dup 1) (match_dup 2))) 7299 (clobber (reg:CC FLAGS_REG))])] 7300 "TARGET_QIMODE_MATH" 7301{ 7302 rtx div, mod, insn; 7303 rtx tmp0, tmp1; 7304 7305 tmp0 = gen_reg_rtx (HImode); 7306 tmp1 = gen_reg_rtx (HImode); 7307 7308 /* Extend operands[1] to HImode. Generate 8bit divide. Result is 7309 in AX. */ 7310 emit_insn (gen_zero_extendqihi2 (tmp1, operands[1])); 7311 emit_insn (gen_udivmodhiqi3 (tmp0, tmp1, operands[2])); 7312 7313 /* Extract remainder from AH. */ 7314 tmp1 = gen_rtx_ZERO_EXTRACT (SImode, tmp0, GEN_INT (8), GEN_INT (8)); 7315 tmp1 = simplify_gen_subreg (QImode, tmp1, SImode, 0); 7316 insn = emit_move_insn (operands[3], tmp1); 7317 7318 mod = gen_rtx_UMOD (QImode, operands[1], operands[2]); 7319 set_unique_reg_note (insn, REG_EQUAL, mod); 7320 7321 /* Extract quotient from AL. */ 7322 insn = emit_move_insn (operands[0], gen_lowpart (QImode, tmp0)); 7323 7324 div = gen_rtx_UDIV (QImode, operands[1], operands[2]); 7325 set_unique_reg_note (insn, REG_EQUAL, div); 7326 7327 DONE; 7328}) 7329 7330(define_insn "udivmodhiqi3" 7331 [(set (match_operand:HI 0 "register_operand" "=a") 7332 (ior:HI 7333 (ashift:HI 7334 (zero_extend:HI 7335 (truncate:QI 7336 (mod:HI (match_operand:HI 1 "register_operand" "0") 7337 (zero_extend:HI 7338 (match_operand:QI 2 "nonimmediate_operand" "qm"))))) 7339 (const_int 8)) 7340 (zero_extend:HI 7341 (truncate:QI 7342 (div:HI (match_dup 1) (zero_extend:HI (match_dup 2))))))) 7343 (clobber (reg:CC FLAGS_REG))] 7344 "TARGET_QIMODE_MATH" 7345 "div{b}\t%2" 7346 [(set_attr "type" "idiv") 7347 (set_attr "mode" "QI")]) 7348 7349;; We cannot use div/idiv for double division, because it causes 7350;; "division by zero" on the overflow and that's not what we expect 7351;; from truncate. Because true (non truncating) double division is 7352;; never generated, we can't create this insn anyway. 7353; 7354;(define_insn "" 7355; [(set (match_operand:SI 0 "register_operand" "=a") 7356; (truncate:SI 7357; (udiv:DI (match_operand:DI 1 "register_operand" "A") 7358; (zero_extend:DI 7359; (match_operand:SI 2 "nonimmediate_operand" "rm"))))) 7360; (set (match_operand:SI 3 "register_operand" "=d") 7361; (truncate:SI 7362; (umod:DI (match_dup 1) (zero_extend:DI (match_dup 2))))) 7363; (clobber (reg:CC FLAGS_REG))] 7364; "" 7365; "div{l}\t{%2, %0|%0, %2}" 7366; [(set_attr "type" "idiv")]) 7367 7368;;- Logical AND instructions 7369 7370;; On Pentium, "test imm, reg" is pairable only with eax, ax, and al. 7371;; Note that this excludes ah. 7372 7373(define_expand "testsi_ccno_1" 7374 [(set (reg:CCNO FLAGS_REG) 7375 (compare:CCNO 7376 (and:SI (match_operand:SI 0 "nonimmediate_operand" "") 7377 (match_operand:SI 1 "x86_64_nonmemory_operand" "")) 7378 (const_int 0)))]) 7379 7380(define_expand "testqi_ccz_1" 7381 [(set (reg:CCZ FLAGS_REG) 7382 (compare:CCZ (and:QI (match_operand:QI 0 "nonimmediate_operand" "") 7383 (match_operand:QI 1 "nonmemory_operand" "")) 7384 (const_int 0)))]) 7385 7386(define_expand "testdi_ccno_1" 7387 [(set (reg:CCNO FLAGS_REG) 7388 (compare:CCNO 7389 (and:DI (match_operand:DI 0 "nonimmediate_operand" "") 7390 (match_operand:DI 1 "x86_64_szext_general_operand" "")) 7391 (const_int 0)))] 7392 "TARGET_64BIT && !(MEM_P (operands[0]) && MEM_P (operands[1]))") 7393 7394(define_insn "*testdi_1" 7395 [(set (reg FLAGS_REG) 7396 (compare 7397 (and:DI 7398 (match_operand:DI 0 "nonimmediate_operand" "%!*a,r,!*a,r,rm") 7399 (match_operand:DI 1 "x86_64_szext_general_operand" "Z,Z,e,e,re")) 7400 (const_int 0)))] 7401 "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode) 7402 && !(MEM_P (operands[0]) && MEM_P (operands[1]))" 7403 "@ 7404 test{l}\t{%k1, %k0|%k0, %k1} 7405 test{l}\t{%k1, %k0|%k0, %k1} 7406 test{q}\t{%1, %0|%0, %1} 7407 test{q}\t{%1, %0|%0, %1} 7408 test{q}\t{%1, %0|%0, %1}" 7409 [(set_attr "type" "test") 7410 (set_attr "modrm" "0,1,0,1,1") 7411 (set_attr "mode" "SI,SI,DI,DI,DI")]) 7412 7413(define_insn "*testqi_1_maybe_si" 7414 [(set (reg FLAGS_REG) 7415 (compare 7416 (and:QI 7417 (match_operand:QI 0 "nonimmediate_operand" "%!*a,q,qm,r") 7418 (match_operand:QI 1 "general_operand" "n,n,qn,n")) 7419 (const_int 0)))] 7420 "!(MEM_P (operands[0]) && MEM_P (operands[1])) 7421 && ix86_match_ccmode (insn, 7422 CONST_INT_P (operands[1]) 7423 && INTVAL (operands[1]) >= 0 ? CCNOmode : CCZmode)" 7424{ 7425 if (which_alternative == 3) 7426 { 7427 if (CONST_INT_P (operands[1]) && INTVAL (operands[1]) < 0) 7428 operands[1] = GEN_INT (INTVAL (operands[1]) & 0xff); 7429 return "test{l}\t{%1, %k0|%k0, %1}"; 7430 } 7431 return "test{b}\t{%1, %0|%0, %1}"; 7432} 7433 [(set_attr "type" "test") 7434 (set_attr "modrm" "0,1,1,1") 7435 (set_attr "mode" "QI,QI,QI,SI") 7436 (set_attr "pent_pair" "uv,np,uv,np")]) 7437 7438(define_insn "*test<mode>_1" 7439 [(set (reg FLAGS_REG) 7440 (compare 7441 (and:SWI124 7442 (match_operand:SWI124 0 "nonimmediate_operand" "%!*a,<r>,<r>m") 7443 (match_operand:SWI124 1 "<general_operand>" "<i>,<i>,<r><i>")) 7444 (const_int 0)))] 7445 "ix86_match_ccmode (insn, CCNOmode) 7446 && !(MEM_P (operands[0]) && MEM_P (operands[1]))" 7447 "test{<imodesuffix>}\t{%1, %0|%0, %1}" 7448 [(set_attr "type" "test") 7449 (set_attr "modrm" "0,1,1") 7450 (set_attr "mode" "<MODE>") 7451 (set_attr "pent_pair" "uv,np,uv")]) 7452 7453(define_expand "testqi_ext_ccno_0" 7454 [(set (reg:CCNO FLAGS_REG) 7455 (compare:CCNO 7456 (and:SI 7457 (zero_extract:SI 7458 (match_operand 0 "ext_register_operand" "") 7459 (const_int 8) 7460 (const_int 8)) 7461 (match_operand 1 "const_int_operand" "")) 7462 (const_int 0)))]) 7463 7464(define_insn "*testqi_ext_0" 7465 [(set (reg FLAGS_REG) 7466 (compare 7467 (and:SI 7468 (zero_extract:SI 7469 (match_operand 0 "ext_register_operand" "Q") 7470 (const_int 8) 7471 (const_int 8)) 7472 (match_operand 1 "const_int_operand" "n")) 7473 (const_int 0)))] 7474 "ix86_match_ccmode (insn, CCNOmode)" 7475 "test{b}\t{%1, %h0|%h0, %1}" 7476 [(set_attr "type" "test") 7477 (set_attr "mode" "QI") 7478 (set_attr "length_immediate" "1") 7479 (set_attr "modrm" "1") 7480 (set_attr "pent_pair" "np")]) 7481 7482(define_insn "*testqi_ext_1_rex64" 7483 [(set (reg FLAGS_REG) 7484 (compare 7485 (and:SI 7486 (zero_extract:SI 7487 (match_operand 0 "ext_register_operand" "Q") 7488 (const_int 8) 7489 (const_int 8)) 7490 (zero_extend:SI 7491 (match_operand:QI 1 "register_operand" "Q"))) 7492 (const_int 0)))] 7493 "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)" 7494 "test{b}\t{%1, %h0|%h0, %1}" 7495 [(set_attr "type" "test") 7496 (set_attr "mode" "QI")]) 7497 7498(define_insn "*testqi_ext_1" 7499 [(set (reg FLAGS_REG) 7500 (compare 7501 (and:SI 7502 (zero_extract:SI 7503 (match_operand 0 "ext_register_operand" "Q") 7504 (const_int 8) 7505 (const_int 8)) 7506 (zero_extend:SI 7507 (match_operand:QI 1 "general_operand" "Qm"))) 7508 (const_int 0)))] 7509 "!TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)" 7510 "test{b}\t{%1, %h0|%h0, %1}" 7511 [(set_attr "type" "test") 7512 (set_attr "mode" "QI")]) 7513 7514(define_insn "*testqi_ext_2" 7515 [(set (reg FLAGS_REG) 7516 (compare 7517 (and:SI 7518 (zero_extract:SI 7519 (match_operand 0 "ext_register_operand" "Q") 7520 (const_int 8) 7521 (const_int 8)) 7522 (zero_extract:SI 7523 (match_operand 1 "ext_register_operand" "Q") 7524 (const_int 8) 7525 (const_int 8))) 7526 (const_int 0)))] 7527 "ix86_match_ccmode (insn, CCNOmode)" 7528 "test{b}\t{%h1, %h0|%h0, %h1}" 7529 [(set_attr "type" "test") 7530 (set_attr "mode" "QI")]) 7531 7532(define_insn "*testqi_ext_3_rex64" 7533 [(set (reg FLAGS_REG) 7534 (compare (zero_extract:DI 7535 (match_operand 0 "nonimmediate_operand" "rm") 7536 (match_operand:DI 1 "const_int_operand" "") 7537 (match_operand:DI 2 "const_int_operand" "")) 7538 (const_int 0)))] 7539 "TARGET_64BIT 7540 && ix86_match_ccmode (insn, CCNOmode) 7541 && INTVAL (operands[1]) > 0 7542 && INTVAL (operands[2]) >= 0 7543 /* Ensure that resulting mask is zero or sign extended operand. */ 7544 && (INTVAL (operands[1]) + INTVAL (operands[2]) <= 32 7545 || (INTVAL (operands[1]) + INTVAL (operands[2]) == 64 7546 && INTVAL (operands[1]) > 32)) 7547 && (GET_MODE (operands[0]) == SImode 7548 || GET_MODE (operands[0]) == DImode 7549 || GET_MODE (operands[0]) == HImode 7550 || GET_MODE (operands[0]) == QImode)" 7551 "#") 7552 7553;; Combine likes to form bit extractions for some tests. Humor it. 7554(define_insn "*testqi_ext_3" 7555 [(set (reg FLAGS_REG) 7556 (compare (zero_extract:SI 7557 (match_operand 0 "nonimmediate_operand" "rm") 7558 (match_operand:SI 1 "const_int_operand" "") 7559 (match_operand:SI 2 "const_int_operand" "")) 7560 (const_int 0)))] 7561 "ix86_match_ccmode (insn, CCNOmode) 7562 && INTVAL (operands[1]) > 0 7563 && INTVAL (operands[2]) >= 0 7564 && INTVAL (operands[1]) + INTVAL (operands[2]) <= 32 7565 && (GET_MODE (operands[0]) == SImode 7566 || (TARGET_64BIT && GET_MODE (operands[0]) == DImode) 7567 || GET_MODE (operands[0]) == HImode 7568 || GET_MODE (operands[0]) == QImode)" 7569 "#") 7570 7571(define_split 7572 [(set (match_operand 0 "flags_reg_operand" "") 7573 (match_operator 1 "compare_operator" 7574 [(zero_extract 7575 (match_operand 2 "nonimmediate_operand" "") 7576 (match_operand 3 "const_int_operand" "") 7577 (match_operand 4 "const_int_operand" "")) 7578 (const_int 0)]))] 7579 "ix86_match_ccmode (insn, CCNOmode)" 7580 [(set (match_dup 0) (match_op_dup 1 [(match_dup 2) (const_int 0)]))] 7581{ 7582 rtx val = operands[2]; 7583 HOST_WIDE_INT len = INTVAL (operands[3]); 7584 HOST_WIDE_INT pos = INTVAL (operands[4]); 7585 HOST_WIDE_INT mask; 7586 enum machine_mode mode, submode; 7587 7588 mode = GET_MODE (val); 7589 if (MEM_P (val)) 7590 { 7591 /* ??? Combine likes to put non-volatile mem extractions in QImode 7592 no matter the size of the test. So find a mode that works. */ 7593 if (! MEM_VOLATILE_P (val)) 7594 { 7595 mode = smallest_mode_for_size (pos + len, MODE_INT); 7596 val = adjust_address (val, mode, 0); 7597 } 7598 } 7599 else if (GET_CODE (val) == SUBREG 7600 && (submode = GET_MODE (SUBREG_REG (val)), 7601 GET_MODE_BITSIZE (mode) > GET_MODE_BITSIZE (submode)) 7602 && pos + len <= GET_MODE_BITSIZE (submode) 7603 && GET_MODE_CLASS (submode) == MODE_INT) 7604 { 7605 /* Narrow a paradoxical subreg to prevent partial register stalls. */ 7606 mode = submode; 7607 val = SUBREG_REG (val); 7608 } 7609 else if (mode == HImode && pos + len <= 8) 7610 { 7611 /* Small HImode tests can be converted to QImode. */ 7612 mode = QImode; 7613 val = gen_lowpart (QImode, val); 7614 } 7615 7616 if (len == HOST_BITS_PER_WIDE_INT) 7617 mask = -1; 7618 else 7619 mask = ((HOST_WIDE_INT)1 << len) - 1; 7620 mask <<= pos; 7621 7622 operands[2] = gen_rtx_AND (mode, val, gen_int_mode (mask, mode)); 7623}) 7624 7625;; Convert HImode/SImode test instructions with immediate to QImode ones. 7626;; i386 does not allow to encode test with 8bit sign extended immediate, so 7627;; this is relatively important trick. 7628;; Do the conversion only post-reload to avoid limiting of the register class 7629;; to QI regs. 7630(define_split 7631 [(set (match_operand 0 "flags_reg_operand" "") 7632 (match_operator 1 "compare_operator" 7633 [(and (match_operand 2 "register_operand" "") 7634 (match_operand 3 "const_int_operand" "")) 7635 (const_int 0)]))] 7636 "reload_completed 7637 && QI_REG_P (operands[2]) 7638 && GET_MODE (operands[2]) != QImode 7639 && ((ix86_match_ccmode (insn, CCZmode) 7640 && !(INTVAL (operands[3]) & ~(255 << 8))) 7641 || (ix86_match_ccmode (insn, CCNOmode) 7642 && !(INTVAL (operands[3]) & ~(127 << 8))))" 7643 [(set (match_dup 0) 7644 (match_op_dup 1 7645 [(and:SI (zero_extract:SI (match_dup 2) (const_int 8) (const_int 8)) 7646 (match_dup 3)) 7647 (const_int 0)]))] 7648{ 7649 operands[2] = gen_lowpart (SImode, operands[2]); 7650 operands[3] = gen_int_mode (INTVAL (operands[3]) >> 8, SImode); 7651}) 7652 7653(define_split 7654 [(set (match_operand 0 "flags_reg_operand" "") 7655 (match_operator 1 "compare_operator" 7656 [(and (match_operand 2 "nonimmediate_operand" "") 7657 (match_operand 3 "const_int_operand" "")) 7658 (const_int 0)]))] 7659 "reload_completed 7660 && GET_MODE (operands[2]) != QImode 7661 && (!REG_P (operands[2]) || ANY_QI_REG_P (operands[2])) 7662 && ((ix86_match_ccmode (insn, CCZmode) 7663 && !(INTVAL (operands[3]) & ~255)) 7664 || (ix86_match_ccmode (insn, CCNOmode) 7665 && !(INTVAL (operands[3]) & ~127)))" 7666 [(set (match_dup 0) 7667 (match_op_dup 1 [(and:QI (match_dup 2) (match_dup 3)) 7668 (const_int 0)]))] 7669{ 7670 operands[2] = gen_lowpart (QImode, operands[2]); 7671 operands[3] = gen_lowpart (QImode, operands[3]); 7672}) 7673 7674;; %%% This used to optimize known byte-wide and operations to memory, 7675;; and sometimes to QImode registers. If this is considered useful, 7676;; it should be done with splitters. 7677 7678(define_expand "and<mode>3" 7679 [(set (match_operand:SWIM 0 "nonimmediate_operand" "") 7680 (and:SWIM (match_operand:SWIM 1 "nonimmediate_operand" "") 7681 (match_operand:SWIM 2 "<general_szext_operand>" "")))] 7682 "" 7683{ 7684 if (<MODE>mode == DImode 7685 && GET_CODE (operands[2]) == CONST_INT 7686 && INTVAL (operands[2]) == (HOST_WIDE_INT) 0xffffffff 7687 && REG_P (operands[1])) 7688 emit_insn (gen_zero_extendsidi2 (operands[0], 7689 gen_lowpart (SImode, operands[1]))); 7690 else 7691 ix86_expand_binary_operator (AND, <MODE>mode, operands); 7692 DONE; 7693}) 7694 7695(define_insn "*anddi_1" 7696 [(set (match_operand:DI 0 "nonimmediate_operand" "=r,rm,r,r") 7697 (and:DI 7698 (match_operand:DI 1 "nonimmediate_operand" "%0,0,0,qm") 7699 (match_operand:DI 2 "x86_64_szext_general_operand" "Z,re,rm,L"))) 7700 (clobber (reg:CC FLAGS_REG))] 7701 "TARGET_64BIT && ix86_binary_operator_ok (AND, DImode, operands)" 7702{ 7703 switch (get_attr_type (insn)) 7704 { 7705 case TYPE_IMOVX: 7706 { 7707 enum machine_mode mode; 7708 7709 gcc_assert (CONST_INT_P (operands[2])); 7710 if (INTVAL (operands[2]) == (HOST_WIDE_INT) 0xffffffff) 7711 mode = SImode; 7712 else if (INTVAL (operands[2]) == 0xffff) 7713 mode = HImode; 7714 else 7715 { 7716 gcc_assert (INTVAL (operands[2]) == 0xff); 7717 mode = QImode; 7718 } 7719 7720 operands[1] = gen_lowpart (mode, operands[1]); 7721 if (mode == SImode) 7722 return "mov{l}\t{%1, %k0|%k0, %1}"; 7723 else if (mode == HImode) 7724 return "movz{wl|x}\t{%1, %k0|%k0, %1}"; 7725 else 7726 return "movz{bl|x}\t{%1, %k0|%k0, %1}"; 7727 } 7728 7729 default: 7730 gcc_assert (rtx_equal_p (operands[0], operands[1])); 7731 if (get_attr_mode (insn) == MODE_SI) 7732 return "and{l}\t{%k2, %k0|%k0, %k2}"; 7733 else 7734 return "and{q}\t{%2, %0|%0, %2}"; 7735 } 7736} 7737 [(set_attr "type" "alu,alu,alu,imovx") 7738 (set_attr "length_immediate" "*,*,*,0") 7739 (set (attr "prefix_rex") 7740 (if_then_else 7741 (and (eq_attr "type" "imovx") 7742 (and (match_test "INTVAL (operands[2]) == 0xff") 7743 (match_operand 1 "ext_QIreg_operand" ""))) 7744 (const_string "1") 7745 (const_string "*"))) 7746 (set_attr "mode" "SI,DI,DI,SI")]) 7747 7748(define_insn "*andsi_1" 7749 [(set (match_operand:SI 0 "nonimmediate_operand" "=rm,r,r") 7750 (and:SI (match_operand:SI 1 "nonimmediate_operand" "%0,0,qm") 7751 (match_operand:SI 2 "x86_64_general_operand" "re,rm,L"))) 7752 (clobber (reg:CC FLAGS_REG))] 7753 "ix86_binary_operator_ok (AND, SImode, operands)" 7754{ 7755 switch (get_attr_type (insn)) 7756 { 7757 case TYPE_IMOVX: 7758 { 7759 enum machine_mode mode; 7760 7761 gcc_assert (CONST_INT_P (operands[2])); 7762 if (INTVAL (operands[2]) == 0xffff) 7763 mode = HImode; 7764 else 7765 { 7766 gcc_assert (INTVAL (operands[2]) == 0xff); 7767 mode = QImode; 7768 } 7769 7770 operands[1] = gen_lowpart (mode, operands[1]); 7771 if (mode == HImode) 7772 return "movz{wl|x}\t{%1, %0|%0, %1}"; 7773 else 7774 return "movz{bl|x}\t{%1, %0|%0, %1}"; 7775 } 7776 7777 default: 7778 gcc_assert (rtx_equal_p (operands[0], operands[1])); 7779 return "and{l}\t{%2, %0|%0, %2}"; 7780 } 7781} 7782 [(set_attr "type" "alu,alu,imovx") 7783 (set (attr "prefix_rex") 7784 (if_then_else 7785 (and (eq_attr "type" "imovx") 7786 (and (match_test "INTVAL (operands[2]) == 0xff") 7787 (match_operand 1 "ext_QIreg_operand" ""))) 7788 (const_string "1") 7789 (const_string "*"))) 7790 (set_attr "length_immediate" "*,*,0") 7791 (set_attr "mode" "SI")]) 7792 7793;; See comment for addsi_1_zext why we do use nonimmediate_operand 7794(define_insn "*andsi_1_zext" 7795 [(set (match_operand:DI 0 "register_operand" "=r") 7796 (zero_extend:DI 7797 (and:SI (match_operand:SI 1 "nonimmediate_operand" "%0") 7798 (match_operand:SI 2 "x86_64_general_operand" "rme")))) 7799 (clobber (reg:CC FLAGS_REG))] 7800 "TARGET_64BIT && ix86_binary_operator_ok (AND, SImode, operands)" 7801 "and{l}\t{%2, %k0|%k0, %2}" 7802 [(set_attr "type" "alu") 7803 (set_attr "mode" "SI")]) 7804 7805(define_insn "*andhi_1" 7806 [(set (match_operand:HI 0 "nonimmediate_operand" "=rm,r,r") 7807 (and:HI (match_operand:HI 1 "nonimmediate_operand" "%0,0,qm") 7808 (match_operand:HI 2 "general_operand" "rn,rm,L"))) 7809 (clobber (reg:CC FLAGS_REG))] 7810 "ix86_binary_operator_ok (AND, HImode, operands)" 7811{ 7812 switch (get_attr_type (insn)) 7813 { 7814 case TYPE_IMOVX: 7815 gcc_assert (CONST_INT_P (operands[2])); 7816 gcc_assert (INTVAL (operands[2]) == 0xff); 7817 return "movz{bl|x}\t{%b1, %k0|%k0, %b1}"; 7818 7819 default: 7820 gcc_assert (rtx_equal_p (operands[0], operands[1])); 7821 7822 return "and{w}\t{%2, %0|%0, %2}"; 7823 } 7824} 7825 [(set_attr "type" "alu,alu,imovx") 7826 (set_attr "length_immediate" "*,*,0") 7827 (set (attr "prefix_rex") 7828 (if_then_else 7829 (and (eq_attr "type" "imovx") 7830 (match_operand 1 "ext_QIreg_operand" "")) 7831 (const_string "1") 7832 (const_string "*"))) 7833 (set_attr "mode" "HI,HI,SI")]) 7834 7835;; %%% Potential partial reg stall on alternative 2. What to do? 7836(define_insn "*andqi_1" 7837 [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,q,r") 7838 (and:QI (match_operand:QI 1 "nonimmediate_operand" "%0,0,0") 7839 (match_operand:QI 2 "general_operand" "qn,qmn,rn"))) 7840 (clobber (reg:CC FLAGS_REG))] 7841 "ix86_binary_operator_ok (AND, QImode, operands)" 7842 "@ 7843 and{b}\t{%2, %0|%0, %2} 7844 and{b}\t{%2, %0|%0, %2} 7845 and{l}\t{%k2, %k0|%k0, %k2}" 7846 [(set_attr "type" "alu") 7847 (set_attr "mode" "QI,QI,SI")]) 7848 7849(define_insn "*andqi_1_slp" 7850 [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm,q")) 7851 (and:QI (match_dup 0) 7852 (match_operand:QI 1 "general_operand" "qn,qmn"))) 7853 (clobber (reg:CC FLAGS_REG))] 7854 "(!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun)) 7855 && !(MEM_P (operands[0]) && MEM_P (operands[1]))" 7856 "and{b}\t{%1, %0|%0, %1}" 7857 [(set_attr "type" "alu1") 7858 (set_attr "mode" "QI")]) 7859 7860(define_split 7861 [(set (match_operand 0 "register_operand" "") 7862 (and (match_dup 0) 7863 (const_int -65536))) 7864 (clobber (reg:CC FLAGS_REG))] 7865 "(TARGET_FAST_PREFIX && !TARGET_PARTIAL_REG_STALL) 7866 || optimize_function_for_size_p (cfun)" 7867 [(set (strict_low_part (match_dup 1)) (const_int 0))] 7868 "operands[1] = gen_lowpart (HImode, operands[0]);") 7869 7870(define_split 7871 [(set (match_operand 0 "ext_register_operand" "") 7872 (and (match_dup 0) 7873 (const_int -256))) 7874 (clobber (reg:CC FLAGS_REG))] 7875 "(!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun)) 7876 && reload_completed" 7877 [(set (strict_low_part (match_dup 1)) (const_int 0))] 7878 "operands[1] = gen_lowpart (QImode, operands[0]);") 7879 7880(define_split 7881 [(set (match_operand 0 "ext_register_operand" "") 7882 (and (match_dup 0) 7883 (const_int -65281))) 7884 (clobber (reg:CC FLAGS_REG))] 7885 "(!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun)) 7886 && reload_completed" 7887 [(parallel [(set (zero_extract:SI (match_dup 0) 7888 (const_int 8) 7889 (const_int 8)) 7890 (xor:SI 7891 (zero_extract:SI (match_dup 0) 7892 (const_int 8) 7893 (const_int 8)) 7894 (zero_extract:SI (match_dup 0) 7895 (const_int 8) 7896 (const_int 8)))) 7897 (clobber (reg:CC FLAGS_REG))])] 7898 "operands[0] = gen_lowpart (SImode, operands[0]);") 7899 7900(define_insn "*anddi_2" 7901 [(set (reg FLAGS_REG) 7902 (compare 7903 (and:DI 7904 (match_operand:DI 1 "nonimmediate_operand" "%0,0,0") 7905 (match_operand:DI 2 "x86_64_szext_general_operand" "Z,rem,re")) 7906 (const_int 0))) 7907 (set (match_operand:DI 0 "nonimmediate_operand" "=r,r,rm") 7908 (and:DI (match_dup 1) (match_dup 2)))] 7909 "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode) 7910 && ix86_binary_operator_ok (AND, DImode, operands)" 7911 "@ 7912 and{l}\t{%k2, %k0|%k0, %k2} 7913 and{q}\t{%2, %0|%0, %2} 7914 and{q}\t{%2, %0|%0, %2}" 7915 [(set_attr "type" "alu") 7916 (set_attr "mode" "SI,DI,DI")]) 7917 7918(define_insn "*andqi_2_maybe_si" 7919 [(set (reg FLAGS_REG) 7920 (compare (and:QI 7921 (match_operand:QI 1 "nonimmediate_operand" "%0,0,0") 7922 (match_operand:QI 2 "general_operand" "qmn,qn,n")) 7923 (const_int 0))) 7924 (set (match_operand:QI 0 "nonimmediate_operand" "=q,qm,*r") 7925 (and:QI (match_dup 1) (match_dup 2)))] 7926 "ix86_binary_operator_ok (AND, QImode, operands) 7927 && ix86_match_ccmode (insn, 7928 CONST_INT_P (operands[2]) 7929 && INTVAL (operands[2]) >= 0 ? CCNOmode : CCZmode)" 7930{ 7931 if (which_alternative == 2) 7932 { 7933 if (CONST_INT_P (operands[2]) && INTVAL (operands[2]) < 0) 7934 operands[2] = GEN_INT (INTVAL (operands[2]) & 0xff); 7935 return "and{l}\t{%2, %k0|%k0, %2}"; 7936 } 7937 return "and{b}\t{%2, %0|%0, %2}"; 7938} 7939 [(set_attr "type" "alu") 7940 (set_attr "mode" "QI,QI,SI")]) 7941 7942(define_insn "*and<mode>_2" 7943 [(set (reg FLAGS_REG) 7944 (compare (and:SWI124 7945 (match_operand:SWI124 1 "nonimmediate_operand" "%0,0") 7946 (match_operand:SWI124 2 "<general_operand>" "<g>,<r><i>")) 7947 (const_int 0))) 7948 (set (match_operand:SWI124 0 "nonimmediate_operand" "=<r>,<r>m") 7949 (and:SWI124 (match_dup 1) (match_dup 2)))] 7950 "ix86_match_ccmode (insn, CCNOmode) 7951 && ix86_binary_operator_ok (AND, <MODE>mode, operands)" 7952 "and{<imodesuffix>}\t{%2, %0|%0, %2}" 7953 [(set_attr "type" "alu") 7954 (set_attr "mode" "<MODE>")]) 7955 7956;; See comment for addsi_1_zext why we do use nonimmediate_operand 7957(define_insn "*andsi_2_zext" 7958 [(set (reg FLAGS_REG) 7959 (compare (and:SI 7960 (match_operand:SI 1 "nonimmediate_operand" "%0") 7961 (match_operand:SI 2 "x86_64_general_operand" "rme")) 7962 (const_int 0))) 7963 (set (match_operand:DI 0 "register_operand" "=r") 7964 (zero_extend:DI (and:SI (match_dup 1) (match_dup 2))))] 7965 "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode) 7966 && ix86_binary_operator_ok (AND, SImode, operands)" 7967 "and{l}\t{%2, %k0|%k0, %2}" 7968 [(set_attr "type" "alu") 7969 (set_attr "mode" "SI")]) 7970 7971(define_insn "*andqi_2_slp" 7972 [(set (reg FLAGS_REG) 7973 (compare (and:QI 7974 (match_operand:QI 0 "nonimmediate_operand" "+q,qm") 7975 (match_operand:QI 1 "nonimmediate_operand" "qmn,qn")) 7976 (const_int 0))) 7977 (set (strict_low_part (match_dup 0)) 7978 (and:QI (match_dup 0) (match_dup 1)))] 7979 "(!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun)) 7980 && ix86_match_ccmode (insn, CCNOmode) 7981 && !(MEM_P (operands[0]) && MEM_P (operands[1]))" 7982 "and{b}\t{%1, %0|%0, %1}" 7983 [(set_attr "type" "alu1") 7984 (set_attr "mode" "QI")]) 7985 7986;; ??? A bug in recog prevents it from recognizing a const_int as an 7987;; operand to zero_extend in andqi_ext_1. It was checking explicitly 7988;; for a QImode operand, which of course failed. 7989(define_insn "andqi_ext_0" 7990 [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q") 7991 (const_int 8) 7992 (const_int 8)) 7993 (and:SI 7994 (zero_extract:SI 7995 (match_operand 1 "ext_register_operand" "0") 7996 (const_int 8) 7997 (const_int 8)) 7998 (match_operand 2 "const_int_operand" "n"))) 7999 (clobber (reg:CC FLAGS_REG))] 8000 "" 8001 "and{b}\t{%2, %h0|%h0, %2}" 8002 [(set_attr "type" "alu") 8003 (set_attr "length_immediate" "1") 8004 (set_attr "modrm" "1") 8005 (set_attr "mode" "QI")]) 8006 8007;; Generated by peephole translating test to and. This shows up 8008;; often in fp comparisons. 8009(define_insn "*andqi_ext_0_cc" 8010 [(set (reg FLAGS_REG) 8011 (compare 8012 (and:SI 8013 (zero_extract:SI 8014 (match_operand 1 "ext_register_operand" "0") 8015 (const_int 8) 8016 (const_int 8)) 8017 (match_operand 2 "const_int_operand" "n")) 8018 (const_int 0))) 8019 (set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q") 8020 (const_int 8) 8021 (const_int 8)) 8022 (and:SI 8023 (zero_extract:SI 8024 (match_dup 1) 8025 (const_int 8) 8026 (const_int 8)) 8027 (match_dup 2)))] 8028 "ix86_match_ccmode (insn, CCNOmode)" 8029 "and{b}\t{%2, %h0|%h0, %2}" 8030 [(set_attr "type" "alu") 8031 (set_attr "length_immediate" "1") 8032 (set_attr "modrm" "1") 8033 (set_attr "mode" "QI")]) 8034 8035(define_insn "*andqi_ext_1_rex64" 8036 [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q") 8037 (const_int 8) 8038 (const_int 8)) 8039 (and:SI 8040 (zero_extract:SI 8041 (match_operand 1 "ext_register_operand" "0") 8042 (const_int 8) 8043 (const_int 8)) 8044 (zero_extend:SI 8045 (match_operand 2 "ext_register_operand" "Q")))) 8046 (clobber (reg:CC FLAGS_REG))] 8047 "TARGET_64BIT" 8048 "and{b}\t{%2, %h0|%h0, %2}" 8049 [(set_attr "type" "alu") 8050 (set_attr "length_immediate" "0") 8051 (set_attr "mode" "QI")]) 8052 8053(define_insn "*andqi_ext_1" 8054 [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q") 8055 (const_int 8) 8056 (const_int 8)) 8057 (and:SI 8058 (zero_extract:SI 8059 (match_operand 1 "ext_register_operand" "0") 8060 (const_int 8) 8061 (const_int 8)) 8062 (zero_extend:SI 8063 (match_operand:QI 2 "general_operand" "Qm")))) 8064 (clobber (reg:CC FLAGS_REG))] 8065 "!TARGET_64BIT" 8066 "and{b}\t{%2, %h0|%h0, %2}" 8067 [(set_attr "type" "alu") 8068 (set_attr "length_immediate" "0") 8069 (set_attr "mode" "QI")]) 8070 8071(define_insn "*andqi_ext_2" 8072 [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q") 8073 (const_int 8) 8074 (const_int 8)) 8075 (and:SI 8076 (zero_extract:SI 8077 (match_operand 1 "ext_register_operand" "%0") 8078 (const_int 8) 8079 (const_int 8)) 8080 (zero_extract:SI 8081 (match_operand 2 "ext_register_operand" "Q") 8082 (const_int 8) 8083 (const_int 8)))) 8084 (clobber (reg:CC FLAGS_REG))] 8085 "" 8086 "and{b}\t{%h2, %h0|%h0, %h2}" 8087 [(set_attr "type" "alu") 8088 (set_attr "length_immediate" "0") 8089 (set_attr "mode" "QI")]) 8090 8091;; Convert wide AND instructions with immediate operand to shorter QImode 8092;; equivalents when possible. 8093;; Don't do the splitting with memory operands, since it introduces risk 8094;; of memory mismatch stalls. We may want to do the splitting for optimizing 8095;; for size, but that can (should?) be handled by generic code instead. 8096(define_split 8097 [(set (match_operand 0 "register_operand" "") 8098 (and (match_operand 1 "register_operand" "") 8099 (match_operand 2 "const_int_operand" ""))) 8100 (clobber (reg:CC FLAGS_REG))] 8101 "reload_completed 8102 && QI_REG_P (operands[0]) 8103 && (!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun)) 8104 && !(~INTVAL (operands[2]) & ~(255 << 8)) 8105 && GET_MODE (operands[0]) != QImode" 8106 [(parallel [(set (zero_extract:SI (match_dup 0) (const_int 8) (const_int 8)) 8107 (and:SI (zero_extract:SI (match_dup 1) 8108 (const_int 8) (const_int 8)) 8109 (match_dup 2))) 8110 (clobber (reg:CC FLAGS_REG))])] 8111{ 8112 operands[0] = gen_lowpart (SImode, operands[0]); 8113 operands[1] = gen_lowpart (SImode, operands[1]); 8114 operands[2] = gen_int_mode ((INTVAL (operands[2]) >> 8) & 0xff, SImode); 8115}) 8116 8117;; Since AND can be encoded with sign extended immediate, this is only 8118;; profitable when 7th bit is not set. 8119(define_split 8120 [(set (match_operand 0 "register_operand" "") 8121 (and (match_operand 1 "general_operand" "") 8122 (match_operand 2 "const_int_operand" ""))) 8123 (clobber (reg:CC FLAGS_REG))] 8124 "reload_completed 8125 && ANY_QI_REG_P (operands[0]) 8126 && (!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun)) 8127 && !(~INTVAL (operands[2]) & ~255) 8128 && !(INTVAL (operands[2]) & 128) 8129 && GET_MODE (operands[0]) != QImode" 8130 [(parallel [(set (strict_low_part (match_dup 0)) 8131 (and:QI (match_dup 1) 8132 (match_dup 2))) 8133 (clobber (reg:CC FLAGS_REG))])] 8134{ 8135 operands[0] = gen_lowpart (QImode, operands[0]); 8136 operands[1] = gen_lowpart (QImode, operands[1]); 8137 operands[2] = gen_lowpart (QImode, operands[2]); 8138}) 8139 8140;; Logical inclusive and exclusive OR instructions 8141 8142;; %%% This used to optimize known byte-wide and operations to memory. 8143;; If this is considered useful, it should be done with splitters. 8144 8145(define_expand "<code><mode>3" 8146 [(set (match_operand:SWIM 0 "nonimmediate_operand" "") 8147 (any_or:SWIM (match_operand:SWIM 1 "nonimmediate_operand" "") 8148 (match_operand:SWIM 2 "<general_operand>" "")))] 8149 "" 8150 "ix86_expand_binary_operator (<CODE>, <MODE>mode, operands); DONE;") 8151 8152(define_insn "*<code><mode>_1" 8153 [(set (match_operand:SWI248 0 "nonimmediate_operand" "=r,rm") 8154 (any_or:SWI248 8155 (match_operand:SWI248 1 "nonimmediate_operand" "%0,0") 8156 (match_operand:SWI248 2 "<general_operand>" "<g>,r<i>"))) 8157 (clobber (reg:CC FLAGS_REG))] 8158 "ix86_binary_operator_ok (<CODE>, <MODE>mode, operands)" 8159 "<logic>{<imodesuffix>}\t{%2, %0|%0, %2}" 8160 [(set_attr "type" "alu") 8161 (set_attr "mode" "<MODE>")]) 8162 8163;; %%% Potential partial reg stall on alternative 2. What to do? 8164(define_insn "*<code>qi_1" 8165 [(set (match_operand:QI 0 "nonimmediate_operand" "=q,m,r") 8166 (any_or:QI (match_operand:QI 1 "nonimmediate_operand" "%0,0,0") 8167 (match_operand:QI 2 "general_operand" "qmn,qn,rn"))) 8168 (clobber (reg:CC FLAGS_REG))] 8169 "ix86_binary_operator_ok (<CODE>, QImode, operands)" 8170 "@ 8171 <logic>{b}\t{%2, %0|%0, %2} 8172 <logic>{b}\t{%2, %0|%0, %2} 8173 <logic>{l}\t{%k2, %k0|%k0, %k2}" 8174 [(set_attr "type" "alu") 8175 (set_attr "mode" "QI,QI,SI")]) 8176 8177;; See comment for addsi_1_zext why we do use nonimmediate_operand 8178(define_insn "*<code>si_1_zext" 8179 [(set (match_operand:DI 0 "register_operand" "=r") 8180 (zero_extend:DI 8181 (any_or:SI (match_operand:SI 1 "nonimmediate_operand" "%0") 8182 (match_operand:SI 2 "x86_64_general_operand" "rme")))) 8183 (clobber (reg:CC FLAGS_REG))] 8184 "TARGET_64BIT && ix86_binary_operator_ok (<CODE>, SImode, operands)" 8185 "<logic>{l}\t{%2, %k0|%k0, %2}" 8186 [(set_attr "type" "alu") 8187 (set_attr "mode" "SI")]) 8188 8189(define_insn "*<code>si_1_zext_imm" 8190 [(set (match_operand:DI 0 "register_operand" "=r") 8191 (any_or:DI 8192 (zero_extend:DI (match_operand:SI 1 "register_operand" "%0")) 8193 (match_operand:DI 2 "x86_64_zext_immediate_operand" "Z"))) 8194 (clobber (reg:CC FLAGS_REG))] 8195 "TARGET_64BIT && ix86_binary_operator_ok (<CODE>, SImode, operands)" 8196 "<logic>{l}\t{%2, %k0|%k0, %2}" 8197 [(set_attr "type" "alu") 8198 (set_attr "mode" "SI")]) 8199 8200(define_insn "*<code>qi_1_slp" 8201 [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+q,m")) 8202 (any_or:QI (match_dup 0) 8203 (match_operand:QI 1 "general_operand" "qmn,qn"))) 8204 (clobber (reg:CC FLAGS_REG))] 8205 "(!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun)) 8206 && !(MEM_P (operands[0]) && MEM_P (operands[1]))" 8207 "<logic>{b}\t{%1, %0|%0, %1}" 8208 [(set_attr "type" "alu1") 8209 (set_attr "mode" "QI")]) 8210 8211(define_insn "*<code><mode>_2" 8212 [(set (reg FLAGS_REG) 8213 (compare (any_or:SWI 8214 (match_operand:SWI 1 "nonimmediate_operand" "%0,0") 8215 (match_operand:SWI 2 "<general_operand>" "<g>,<r><i>")) 8216 (const_int 0))) 8217 (set (match_operand:SWI 0 "nonimmediate_operand" "=<r>,<r>m") 8218 (any_or:SWI (match_dup 1) (match_dup 2)))] 8219 "ix86_match_ccmode (insn, CCNOmode) 8220 && ix86_binary_operator_ok (<CODE>, <MODE>mode, operands)" 8221 "<logic>{<imodesuffix>}\t{%2, %0|%0, %2}" 8222 [(set_attr "type" "alu") 8223 (set_attr "mode" "<MODE>")]) 8224 8225;; See comment for addsi_1_zext why we do use nonimmediate_operand 8226;; ??? Special case for immediate operand is missing - it is tricky. 8227(define_insn "*<code>si_2_zext" 8228 [(set (reg FLAGS_REG) 8229 (compare (any_or:SI (match_operand:SI 1 "nonimmediate_operand" "%0") 8230 (match_operand:SI 2 "x86_64_general_operand" "rme")) 8231 (const_int 0))) 8232 (set (match_operand:DI 0 "register_operand" "=r") 8233 (zero_extend:DI (any_or:SI (match_dup 1) (match_dup 2))))] 8234 "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode) 8235 && ix86_binary_operator_ok (<CODE>, SImode, operands)" 8236 "<logic>{l}\t{%2, %k0|%k0, %2}" 8237 [(set_attr "type" "alu") 8238 (set_attr "mode" "SI")]) 8239 8240(define_insn "*<code>si_2_zext_imm" 8241 [(set (reg FLAGS_REG) 8242 (compare (any_or:SI 8243 (match_operand:SI 1 "nonimmediate_operand" "%0") 8244 (match_operand:SI 2 "x86_64_zext_immediate_operand" "Z")) 8245 (const_int 0))) 8246 (set (match_operand:DI 0 "register_operand" "=r") 8247 (any_or:DI (zero_extend:DI (match_dup 1)) (match_dup 2)))] 8248 "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode) 8249 && ix86_binary_operator_ok (<CODE>, SImode, operands)" 8250 "<logic>{l}\t{%2, %k0|%k0, %2}" 8251 [(set_attr "type" "alu") 8252 (set_attr "mode" "SI")]) 8253 8254(define_insn "*<code>qi_2_slp" 8255 [(set (reg FLAGS_REG) 8256 (compare (any_or:QI (match_operand:QI 0 "nonimmediate_operand" "+q,qm") 8257 (match_operand:QI 1 "general_operand" "qmn,qn")) 8258 (const_int 0))) 8259 (set (strict_low_part (match_dup 0)) 8260 (any_or:QI (match_dup 0) (match_dup 1)))] 8261 "(!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun)) 8262 && ix86_match_ccmode (insn, CCNOmode) 8263 && !(MEM_P (operands[0]) && MEM_P (operands[1]))" 8264 "<logic>{b}\t{%1, %0|%0, %1}" 8265 [(set_attr "type" "alu1") 8266 (set_attr "mode" "QI")]) 8267 8268(define_insn "*<code><mode>_3" 8269 [(set (reg FLAGS_REG) 8270 (compare (any_or:SWI 8271 (match_operand:SWI 1 "nonimmediate_operand" "%0") 8272 (match_operand:SWI 2 "<general_operand>" "<g>")) 8273 (const_int 0))) 8274 (clobber (match_scratch:SWI 0 "=<r>"))] 8275 "ix86_match_ccmode (insn, CCNOmode) 8276 && !(MEM_P (operands[1]) && MEM_P (operands[2]))" 8277 "<logic>{<imodesuffix>}\t{%2, %0|%0, %2}" 8278 [(set_attr "type" "alu") 8279 (set_attr "mode" "<MODE>")]) 8280 8281(define_insn "*<code>qi_ext_0" 8282 [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q") 8283 (const_int 8) 8284 (const_int 8)) 8285 (any_or:SI 8286 (zero_extract:SI 8287 (match_operand 1 "ext_register_operand" "0") 8288 (const_int 8) 8289 (const_int 8)) 8290 (match_operand 2 "const_int_operand" "n"))) 8291 (clobber (reg:CC FLAGS_REG))] 8292 "!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun)" 8293 "<logic>{b}\t{%2, %h0|%h0, %2}" 8294 [(set_attr "type" "alu") 8295 (set_attr "length_immediate" "1") 8296 (set_attr "modrm" "1") 8297 (set_attr "mode" "QI")]) 8298 8299(define_insn "*<code>qi_ext_1_rex64" 8300 [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q") 8301 (const_int 8) 8302 (const_int 8)) 8303 (any_or:SI 8304 (zero_extract:SI 8305 (match_operand 1 "ext_register_operand" "0") 8306 (const_int 8) 8307 (const_int 8)) 8308 (zero_extend:SI 8309 (match_operand 2 "ext_register_operand" "Q")))) 8310 (clobber (reg:CC FLAGS_REG))] 8311 "TARGET_64BIT 8312 && (!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))" 8313 "<logic>{b}\t{%2, %h0|%h0, %2}" 8314 [(set_attr "type" "alu") 8315 (set_attr "length_immediate" "0") 8316 (set_attr "mode" "QI")]) 8317 8318(define_insn "*<code>qi_ext_1" 8319 [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q") 8320 (const_int 8) 8321 (const_int 8)) 8322 (any_or:SI 8323 (zero_extract:SI 8324 (match_operand 1 "ext_register_operand" "0") 8325 (const_int 8) 8326 (const_int 8)) 8327 (zero_extend:SI 8328 (match_operand:QI 2 "general_operand" "Qm")))) 8329 (clobber (reg:CC FLAGS_REG))] 8330 "!TARGET_64BIT 8331 && (!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))" 8332 "<logic>{b}\t{%2, %h0|%h0, %2}" 8333 [(set_attr "type" "alu") 8334 (set_attr "length_immediate" "0") 8335 (set_attr "mode" "QI")]) 8336 8337(define_insn "*<code>qi_ext_2" 8338 [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q") 8339 (const_int 8) 8340 (const_int 8)) 8341 (any_or:SI 8342 (zero_extract:SI (match_operand 1 "ext_register_operand" "0") 8343 (const_int 8) 8344 (const_int 8)) 8345 (zero_extract:SI (match_operand 2 "ext_register_operand" "Q") 8346 (const_int 8) 8347 (const_int 8)))) 8348 (clobber (reg:CC FLAGS_REG))] 8349 "!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun)" 8350 "<logic>{b}\t{%h2, %h0|%h0, %h2}" 8351 [(set_attr "type" "alu") 8352 (set_attr "length_immediate" "0") 8353 (set_attr "mode" "QI")]) 8354 8355(define_split 8356 [(set (match_operand 0 "register_operand" "") 8357 (any_or (match_operand 1 "register_operand" "") 8358 (match_operand 2 "const_int_operand" ""))) 8359 (clobber (reg:CC FLAGS_REG))] 8360 "reload_completed 8361 && QI_REG_P (operands[0]) 8362 && (!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun)) 8363 && !(INTVAL (operands[2]) & ~(255 << 8)) 8364 && GET_MODE (operands[0]) != QImode" 8365 [(parallel [(set (zero_extract:SI (match_dup 0) (const_int 8) (const_int 8)) 8366 (any_or:SI (zero_extract:SI (match_dup 1) 8367 (const_int 8) (const_int 8)) 8368 (match_dup 2))) 8369 (clobber (reg:CC FLAGS_REG))])] 8370{ 8371 operands[0] = gen_lowpart (SImode, operands[0]); 8372 operands[1] = gen_lowpart (SImode, operands[1]); 8373 operands[2] = gen_int_mode ((INTVAL (operands[2]) >> 8) & 0xff, SImode); 8374}) 8375 8376;; Since OR can be encoded with sign extended immediate, this is only 8377;; profitable when 7th bit is set. 8378(define_split 8379 [(set (match_operand 0 "register_operand" "") 8380 (any_or (match_operand 1 "general_operand" "") 8381 (match_operand 2 "const_int_operand" ""))) 8382 (clobber (reg:CC FLAGS_REG))] 8383 "reload_completed 8384 && ANY_QI_REG_P (operands[0]) 8385 && (!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun)) 8386 && !(INTVAL (operands[2]) & ~255) 8387 && (INTVAL (operands[2]) & 128) 8388 && GET_MODE (operands[0]) != QImode" 8389 [(parallel [(set (strict_low_part (match_dup 0)) 8390 (any_or:QI (match_dup 1) 8391 (match_dup 2))) 8392 (clobber (reg:CC FLAGS_REG))])] 8393{ 8394 operands[0] = gen_lowpart (QImode, operands[0]); 8395 operands[1] = gen_lowpart (QImode, operands[1]); 8396 operands[2] = gen_lowpart (QImode, operands[2]); 8397}) 8398 8399(define_expand "xorqi_cc_ext_1" 8400 [(parallel [ 8401 (set (reg:CCNO FLAGS_REG) 8402 (compare:CCNO 8403 (xor:SI 8404 (zero_extract:SI 8405 (match_operand 1 "ext_register_operand" "") 8406 (const_int 8) 8407 (const_int 8)) 8408 (match_operand:QI 2 "general_operand" "")) 8409 (const_int 0))) 8410 (set (zero_extract:SI (match_operand 0 "ext_register_operand" "") 8411 (const_int 8) 8412 (const_int 8)) 8413 (xor:SI 8414 (zero_extract:SI 8415 (match_dup 1) 8416 (const_int 8) 8417 (const_int 8)) 8418 (match_dup 2)))])]) 8419 8420(define_insn "*xorqi_cc_ext_1_rex64" 8421 [(set (reg FLAGS_REG) 8422 (compare 8423 (xor:SI 8424 (zero_extract:SI 8425 (match_operand 1 "ext_register_operand" "0") 8426 (const_int 8) 8427 (const_int 8)) 8428 (match_operand:QI 2 "nonmemory_operand" "Qn")) 8429 (const_int 0))) 8430 (set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q") 8431 (const_int 8) 8432 (const_int 8)) 8433 (xor:SI 8434 (zero_extract:SI 8435 (match_dup 1) 8436 (const_int 8) 8437 (const_int 8)) 8438 (match_dup 2)))] 8439 "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)" 8440 "xor{b}\t{%2, %h0|%h0, %2}" 8441 [(set_attr "type" "alu") 8442 (set_attr "modrm" "1") 8443 (set_attr "mode" "QI")]) 8444 8445(define_insn "*xorqi_cc_ext_1" 8446 [(set (reg FLAGS_REG) 8447 (compare 8448 (xor:SI 8449 (zero_extract:SI 8450 (match_operand 1 "ext_register_operand" "0") 8451 (const_int 8) 8452 (const_int 8)) 8453 (match_operand:QI 2 "general_operand" "qmn")) 8454 (const_int 0))) 8455 (set (zero_extract:SI (match_operand 0 "ext_register_operand" "=q") 8456 (const_int 8) 8457 (const_int 8)) 8458 (xor:SI 8459 (zero_extract:SI 8460 (match_dup 1) 8461 (const_int 8) 8462 (const_int 8)) 8463 (match_dup 2)))] 8464 "!TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)" 8465 "xor{b}\t{%2, %h0|%h0, %2}" 8466 [(set_attr "type" "alu") 8467 (set_attr "modrm" "1") 8468 (set_attr "mode" "QI")]) 8469 8470;; Negation instructions 8471 8472(define_expand "neg<mode>2" 8473 [(set (match_operand:SDWIM 0 "nonimmediate_operand" "") 8474 (neg:SDWIM (match_operand:SDWIM 1 "nonimmediate_operand" "")))] 8475 "" 8476 "ix86_expand_unary_operator (NEG, <MODE>mode, operands); DONE;") 8477 8478(define_insn_and_split "*neg<dwi>2_doubleword" 8479 [(set (match_operand:<DWI> 0 "nonimmediate_operand" "=ro") 8480 (neg:<DWI> (match_operand:<DWI> 1 "nonimmediate_operand" "0"))) 8481 (clobber (reg:CC FLAGS_REG))] 8482 "ix86_unary_operator_ok (NEG, <DWI>mode, operands)" 8483 "#" 8484 "reload_completed" 8485 [(parallel 8486 [(set (reg:CCZ FLAGS_REG) 8487 (compare:CCZ (neg:DWIH (match_dup 1)) (const_int 0))) 8488 (set (match_dup 0) (neg:DWIH (match_dup 1)))]) 8489 (parallel 8490 [(set (match_dup 2) 8491 (plus:DWIH (match_dup 3) 8492 (plus:DWIH (ltu:DWIH (reg:CC FLAGS_REG) (const_int 0)) 8493 (const_int 0)))) 8494 (clobber (reg:CC FLAGS_REG))]) 8495 (parallel 8496 [(set (match_dup 2) 8497 (neg:DWIH (match_dup 2))) 8498 (clobber (reg:CC FLAGS_REG))])] 8499 "split_double_mode (<DWI>mode, &operands[0], 2, &operands[0], &operands[2]);") 8500 8501(define_insn "*neg<mode>2_1" 8502 [(set (match_operand:SWI 0 "nonimmediate_operand" "=<r>m") 8503 (neg:SWI (match_operand:SWI 1 "nonimmediate_operand" "0"))) 8504 (clobber (reg:CC FLAGS_REG))] 8505 "ix86_unary_operator_ok (NEG, <MODE>mode, operands)" 8506 "neg{<imodesuffix>}\t%0" 8507 [(set_attr "type" "negnot") 8508 (set_attr "mode" "<MODE>")]) 8509 8510;; Combine is quite creative about this pattern. 8511(define_insn "*negsi2_1_zext" 8512 [(set (match_operand:DI 0 "register_operand" "=r") 8513 (lshiftrt:DI 8514 (neg:DI (ashift:DI (match_operand:DI 1 "register_operand" "0") 8515 (const_int 32))) 8516 (const_int 32))) 8517 (clobber (reg:CC FLAGS_REG))] 8518 "TARGET_64BIT && ix86_unary_operator_ok (NEG, SImode, operands)" 8519 "neg{l}\t%k0" 8520 [(set_attr "type" "negnot") 8521 (set_attr "mode" "SI")]) 8522 8523;; The problem with neg is that it does not perform (compare x 0), 8524;; it really performs (compare 0 x), which leaves us with the zero 8525;; flag being the only useful item. 8526 8527(define_insn "*neg<mode>2_cmpz" 8528 [(set (reg:CCZ FLAGS_REG) 8529 (compare:CCZ 8530 (neg:SWI (match_operand:SWI 1 "nonimmediate_operand" "0")) 8531 (const_int 0))) 8532 (set (match_operand:SWI 0 "nonimmediate_operand" "=<r>m") 8533 (neg:SWI (match_dup 1)))] 8534 "ix86_unary_operator_ok (NEG, <MODE>mode, operands)" 8535 "neg{<imodesuffix>}\t%0" 8536 [(set_attr "type" "negnot") 8537 (set_attr "mode" "<MODE>")]) 8538 8539(define_insn "*negsi2_cmpz_zext" 8540 [(set (reg:CCZ FLAGS_REG) 8541 (compare:CCZ 8542 (lshiftrt:DI 8543 (neg:DI (ashift:DI 8544 (match_operand:DI 1 "register_operand" "0") 8545 (const_int 32))) 8546 (const_int 32)) 8547 (const_int 0))) 8548 (set (match_operand:DI 0 "register_operand" "=r") 8549 (lshiftrt:DI (neg:DI (ashift:DI (match_dup 1) 8550 (const_int 32))) 8551 (const_int 32)))] 8552 "TARGET_64BIT && ix86_unary_operator_ok (NEG, SImode, operands)" 8553 "neg{l}\t%k0" 8554 [(set_attr "type" "negnot") 8555 (set_attr "mode" "SI")]) 8556 8557;; Changing of sign for FP values is doable using integer unit too. 8558 8559(define_expand "<code><mode>2" 8560 [(set (match_operand:X87MODEF 0 "register_operand" "") 8561 (absneg:X87MODEF (match_operand:X87MODEF 1 "register_operand" "")))] 8562 "TARGET_80387 || (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)" 8563 "ix86_expand_fp_absneg_operator (<CODE>, <MODE>mode, operands); DONE;") 8564 8565(define_insn "*absneg<mode>2_mixed" 8566 [(set (match_operand:MODEF 0 "register_operand" "=x,x,f,!r") 8567 (match_operator:MODEF 3 "absneg_operator" 8568 [(match_operand:MODEF 1 "register_operand" "0,x,0,0")])) 8569 (use (match_operand:<ssevecmode> 2 "nonimmediate_operand" "xm,0,X,X")) 8570 (clobber (reg:CC FLAGS_REG))] 8571 "TARGET_MIX_SSE_I387 && SSE_FLOAT_MODE_P (<MODE>mode)" 8572 "#") 8573 8574(define_insn "*absneg<mode>2_sse" 8575 [(set (match_operand:MODEF 0 "register_operand" "=x,x,!r") 8576 (match_operator:MODEF 3 "absneg_operator" 8577 [(match_operand:MODEF 1 "register_operand" "0 ,x,0")])) 8578 (use (match_operand:<ssevecmode> 2 "register_operand" "xm,0,X")) 8579 (clobber (reg:CC FLAGS_REG))] 8580 "SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH" 8581 "#") 8582 8583(define_insn "*absneg<mode>2_i387" 8584 [(set (match_operand:X87MODEF 0 "register_operand" "=f,!r") 8585 (match_operator:X87MODEF 3 "absneg_operator" 8586 [(match_operand:X87MODEF 1 "register_operand" "0,0")])) 8587 (use (match_operand 2 "" "")) 8588 (clobber (reg:CC FLAGS_REG))] 8589 "TARGET_80387 && !(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)" 8590 "#") 8591 8592(define_expand "<code>tf2" 8593 [(set (match_operand:TF 0 "register_operand" "") 8594 (absneg:TF (match_operand:TF 1 "register_operand" "")))] 8595 "TARGET_SSE2" 8596 "ix86_expand_fp_absneg_operator (<CODE>, TFmode, operands); DONE;") 8597 8598(define_insn "*absnegtf2_sse" 8599 [(set (match_operand:TF 0 "register_operand" "=x,x") 8600 (match_operator:TF 3 "absneg_operator" 8601 [(match_operand:TF 1 "register_operand" "0,x")])) 8602 (use (match_operand:TF 2 "nonimmediate_operand" "xm,0")) 8603 (clobber (reg:CC FLAGS_REG))] 8604 "TARGET_SSE2" 8605 "#") 8606 8607;; Splitters for fp abs and neg. 8608 8609(define_split 8610 [(set (match_operand 0 "fp_register_operand" "") 8611 (match_operator 1 "absneg_operator" [(match_dup 0)])) 8612 (use (match_operand 2 "" "")) 8613 (clobber (reg:CC FLAGS_REG))] 8614 "reload_completed" 8615 [(set (match_dup 0) (match_op_dup 1 [(match_dup 0)]))]) 8616 8617(define_split 8618 [(set (match_operand 0 "register_operand" "") 8619 (match_operator 3 "absneg_operator" 8620 [(match_operand 1 "register_operand" "")])) 8621 (use (match_operand 2 "nonimmediate_operand" "")) 8622 (clobber (reg:CC FLAGS_REG))] 8623 "reload_completed && SSE_REG_P (operands[0])" 8624 [(set (match_dup 0) (match_dup 3))] 8625{ 8626 enum machine_mode mode = GET_MODE (operands[0]); 8627 enum machine_mode vmode = GET_MODE (operands[2]); 8628 rtx tmp; 8629 8630 operands[0] = simplify_gen_subreg (vmode, operands[0], mode, 0); 8631 operands[1] = simplify_gen_subreg (vmode, operands[1], mode, 0); 8632 if (operands_match_p (operands[0], operands[2])) 8633 { 8634 tmp = operands[1]; 8635 operands[1] = operands[2]; 8636 operands[2] = tmp; 8637 } 8638 if (GET_CODE (operands[3]) == ABS) 8639 tmp = gen_rtx_AND (vmode, operands[1], operands[2]); 8640 else 8641 tmp = gen_rtx_XOR (vmode, operands[1], operands[2]); 8642 operands[3] = tmp; 8643}) 8644 8645(define_split 8646 [(set (match_operand:SF 0 "register_operand" "") 8647 (match_operator:SF 1 "absneg_operator" [(match_dup 0)])) 8648 (use (match_operand:V4SF 2 "" "")) 8649 (clobber (reg:CC FLAGS_REG))] 8650 "reload_completed" 8651 [(parallel [(set (match_dup 0) (match_dup 1)) 8652 (clobber (reg:CC FLAGS_REG))])] 8653{ 8654 rtx tmp; 8655 operands[0] = gen_lowpart (SImode, operands[0]); 8656 if (GET_CODE (operands[1]) == ABS) 8657 { 8658 tmp = gen_int_mode (0x7fffffff, SImode); 8659 tmp = gen_rtx_AND (SImode, operands[0], tmp); 8660 } 8661 else 8662 { 8663 tmp = gen_int_mode (0x80000000, SImode); 8664 tmp = gen_rtx_XOR (SImode, operands[0], tmp); 8665 } 8666 operands[1] = tmp; 8667}) 8668 8669(define_split 8670 [(set (match_operand:DF 0 "register_operand" "") 8671 (match_operator:DF 1 "absneg_operator" [(match_dup 0)])) 8672 (use (match_operand 2 "" "")) 8673 (clobber (reg:CC FLAGS_REG))] 8674 "reload_completed" 8675 [(parallel [(set (match_dup 0) (match_dup 1)) 8676 (clobber (reg:CC FLAGS_REG))])] 8677{ 8678 rtx tmp; 8679 if (TARGET_64BIT) 8680 { 8681 tmp = gen_lowpart (DImode, operands[0]); 8682 tmp = gen_rtx_ZERO_EXTRACT (DImode, tmp, const1_rtx, GEN_INT (63)); 8683 operands[0] = tmp; 8684 8685 if (GET_CODE (operands[1]) == ABS) 8686 tmp = const0_rtx; 8687 else 8688 tmp = gen_rtx_NOT (DImode, tmp); 8689 } 8690 else 8691 { 8692 operands[0] = gen_highpart (SImode, operands[0]); 8693 if (GET_CODE (operands[1]) == ABS) 8694 { 8695 tmp = gen_int_mode (0x7fffffff, SImode); 8696 tmp = gen_rtx_AND (SImode, operands[0], tmp); 8697 } 8698 else 8699 { 8700 tmp = gen_int_mode (0x80000000, SImode); 8701 tmp = gen_rtx_XOR (SImode, operands[0], tmp); 8702 } 8703 } 8704 operands[1] = tmp; 8705}) 8706 8707(define_split 8708 [(set (match_operand:XF 0 "register_operand" "") 8709 (match_operator:XF 1 "absneg_operator" [(match_dup 0)])) 8710 (use (match_operand 2 "" "")) 8711 (clobber (reg:CC FLAGS_REG))] 8712 "reload_completed" 8713 [(parallel [(set (match_dup 0) (match_dup 1)) 8714 (clobber (reg:CC FLAGS_REG))])] 8715{ 8716 rtx tmp; 8717 operands[0] = gen_rtx_REG (SImode, 8718 true_regnum (operands[0]) 8719 + (TARGET_64BIT ? 1 : 2)); 8720 if (GET_CODE (operands[1]) == ABS) 8721 { 8722 tmp = GEN_INT (0x7fff); 8723 tmp = gen_rtx_AND (SImode, operands[0], tmp); 8724 } 8725 else 8726 { 8727 tmp = GEN_INT (0x8000); 8728 tmp = gen_rtx_XOR (SImode, operands[0], tmp); 8729 } 8730 operands[1] = tmp; 8731}) 8732 8733;; Conditionalize these after reload. If they match before reload, we 8734;; lose the clobber and ability to use integer instructions. 8735 8736(define_insn "*<code><mode>2_1" 8737 [(set (match_operand:X87MODEF 0 "register_operand" "=f") 8738 (absneg:X87MODEF (match_operand:X87MODEF 1 "register_operand" "0")))] 8739 "TARGET_80387 8740 && (reload_completed 8741 || !(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH))" 8742 "f<absneg_mnemonic>" 8743 [(set_attr "type" "fsgn") 8744 (set_attr "mode" "<MODE>")]) 8745 8746(define_insn "*<code>extendsfdf2" 8747 [(set (match_operand:DF 0 "register_operand" "=f") 8748 (absneg:DF (float_extend:DF 8749 (match_operand:SF 1 "register_operand" "0"))))] 8750 "TARGET_80387 && (!TARGET_SSE_MATH || TARGET_MIX_SSE_I387)" 8751 "f<absneg_mnemonic>" 8752 [(set_attr "type" "fsgn") 8753 (set_attr "mode" "DF")]) 8754 8755(define_insn "*<code>extendsfxf2" 8756 [(set (match_operand:XF 0 "register_operand" "=f") 8757 (absneg:XF (float_extend:XF 8758 (match_operand:SF 1 "register_operand" "0"))))] 8759 "TARGET_80387" 8760 "f<absneg_mnemonic>" 8761 [(set_attr "type" "fsgn") 8762 (set_attr "mode" "XF")]) 8763 8764(define_insn "*<code>extenddfxf2" 8765 [(set (match_operand:XF 0 "register_operand" "=f") 8766 (absneg:XF (float_extend:XF 8767 (match_operand:DF 1 "register_operand" "0"))))] 8768 "TARGET_80387" 8769 "f<absneg_mnemonic>" 8770 [(set_attr "type" "fsgn") 8771 (set_attr "mode" "XF")]) 8772 8773;; Copysign instructions 8774 8775(define_mode_iterator CSGNMODE [SF DF TF]) 8776(define_mode_attr CSGNVMODE [(SF "V4SF") (DF "V2DF") (TF "TF")]) 8777 8778(define_expand "copysign<mode>3" 8779 [(match_operand:CSGNMODE 0 "register_operand" "") 8780 (match_operand:CSGNMODE 1 "nonmemory_operand" "") 8781 (match_operand:CSGNMODE 2 "register_operand" "")] 8782 "(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH) 8783 || (TARGET_SSE2 && (<MODE>mode == TFmode))" 8784 "ix86_expand_copysign (operands); DONE;") 8785 8786(define_insn_and_split "copysign<mode>3_const" 8787 [(set (match_operand:CSGNMODE 0 "register_operand" "=x") 8788 (unspec:CSGNMODE 8789 [(match_operand:<CSGNVMODE> 1 "vector_move_operand" "xmC") 8790 (match_operand:CSGNMODE 2 "register_operand" "0") 8791 (match_operand:<CSGNVMODE> 3 "nonimmediate_operand" "xm")] 8792 UNSPEC_COPYSIGN))] 8793 "(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH) 8794 || (TARGET_SSE2 && (<MODE>mode == TFmode))" 8795 "#" 8796 "&& reload_completed" 8797 [(const_int 0)] 8798 "ix86_split_copysign_const (operands); DONE;") 8799 8800(define_insn "copysign<mode>3_var" 8801 [(set (match_operand:CSGNMODE 0 "register_operand" "=x,x,x,x,x") 8802 (unspec:CSGNMODE 8803 [(match_operand:CSGNMODE 2 "register_operand" "x,0,0,x,x") 8804 (match_operand:CSGNMODE 3 "register_operand" "1,1,x,1,x") 8805 (match_operand:<CSGNVMODE> 4 "nonimmediate_operand" "X,xm,xm,0,0") 8806 (match_operand:<CSGNVMODE> 5 "nonimmediate_operand" "0,xm,1,xm,1")] 8807 UNSPEC_COPYSIGN)) 8808 (clobber (match_scratch:<CSGNVMODE> 1 "=x,x,x,x,x"))] 8809 "(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH) 8810 || (TARGET_SSE2 && (<MODE>mode == TFmode))" 8811 "#") 8812 8813(define_split 8814 [(set (match_operand:CSGNMODE 0 "register_operand" "") 8815 (unspec:CSGNMODE 8816 [(match_operand:CSGNMODE 2 "register_operand" "") 8817 (match_operand:CSGNMODE 3 "register_operand" "") 8818 (match_operand:<CSGNVMODE> 4 "" "") 8819 (match_operand:<CSGNVMODE> 5 "" "")] 8820 UNSPEC_COPYSIGN)) 8821 (clobber (match_scratch:<CSGNVMODE> 1 ""))] 8822 "((SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH) 8823 || (TARGET_SSE2 && (<MODE>mode == TFmode))) 8824 && reload_completed" 8825 [(const_int 0)] 8826 "ix86_split_copysign_var (operands); DONE;") 8827 8828;; One complement instructions 8829 8830(define_expand "one_cmpl<mode>2" 8831 [(set (match_operand:SWIM 0 "nonimmediate_operand" "") 8832 (not:SWIM (match_operand:SWIM 1 "nonimmediate_operand" "")))] 8833 "" 8834 "ix86_expand_unary_operator (NOT, <MODE>mode, operands); DONE;") 8835 8836(define_insn "*one_cmpl<mode>2_1" 8837 [(set (match_operand:SWI248 0 "nonimmediate_operand" "=rm") 8838 (not:SWI248 (match_operand:SWI248 1 "nonimmediate_operand" "0")))] 8839 "ix86_unary_operator_ok (NOT, <MODE>mode, operands)" 8840 "not{<imodesuffix>}\t%0" 8841 [(set_attr "type" "negnot") 8842 (set_attr "mode" "<MODE>")]) 8843 8844;; %%% Potential partial reg stall on alternative 1. What to do? 8845(define_insn "*one_cmplqi2_1" 8846 [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,r") 8847 (not:QI (match_operand:QI 1 "nonimmediate_operand" "0,0")))] 8848 "ix86_unary_operator_ok (NOT, QImode, operands)" 8849 "@ 8850 not{b}\t%0 8851 not{l}\t%k0" 8852 [(set_attr "type" "negnot") 8853 (set_attr "mode" "QI,SI")]) 8854 8855;; ??? Currently never generated - xor is used instead. 8856(define_insn "*one_cmplsi2_1_zext" 8857 [(set (match_operand:DI 0 "register_operand" "=r") 8858 (zero_extend:DI 8859 (not:SI (match_operand:SI 1 "register_operand" "0"))))] 8860 "TARGET_64BIT && ix86_unary_operator_ok (NOT, SImode, operands)" 8861 "not{l}\t%k0" 8862 [(set_attr "type" "negnot") 8863 (set_attr "mode" "SI")]) 8864 8865(define_insn "*one_cmpl<mode>2_2" 8866 [(set (reg FLAGS_REG) 8867 (compare (not:SWI (match_operand:SWI 1 "nonimmediate_operand" "0")) 8868 (const_int 0))) 8869 (set (match_operand:SWI 0 "nonimmediate_operand" "=<r>m") 8870 (not:SWI (match_dup 1)))] 8871 "ix86_match_ccmode (insn, CCNOmode) 8872 && ix86_unary_operator_ok (NOT, <MODE>mode, operands)" 8873 "#" 8874 [(set_attr "type" "alu1") 8875 (set_attr "mode" "<MODE>")]) 8876 8877(define_split 8878 [(set (match_operand 0 "flags_reg_operand" "") 8879 (match_operator 2 "compare_operator" 8880 [(not:SWI (match_operand:SWI 3 "nonimmediate_operand" "")) 8881 (const_int 0)])) 8882 (set (match_operand:SWI 1 "nonimmediate_operand" "") 8883 (not:SWI (match_dup 3)))] 8884 "ix86_match_ccmode (insn, CCNOmode)" 8885 [(parallel [(set (match_dup 0) 8886 (match_op_dup 2 [(xor:SWI (match_dup 3) (const_int -1)) 8887 (const_int 0)])) 8888 (set (match_dup 1) 8889 (xor:SWI (match_dup 3) (const_int -1)))])]) 8890 8891;; ??? Currently never generated - xor is used instead. 8892(define_insn "*one_cmplsi2_2_zext" 8893 [(set (reg FLAGS_REG) 8894 (compare (not:SI (match_operand:SI 1 "register_operand" "0")) 8895 (const_int 0))) 8896 (set (match_operand:DI 0 "register_operand" "=r") 8897 (zero_extend:DI (not:SI (match_dup 1))))] 8898 "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode) 8899 && ix86_unary_operator_ok (NOT, SImode, operands)" 8900 "#" 8901 [(set_attr "type" "alu1") 8902 (set_attr "mode" "SI")]) 8903 8904(define_split 8905 [(set (match_operand 0 "flags_reg_operand" "") 8906 (match_operator 2 "compare_operator" 8907 [(not:SI (match_operand:SI 3 "register_operand" "")) 8908 (const_int 0)])) 8909 (set (match_operand:DI 1 "register_operand" "") 8910 (zero_extend:DI (not:SI (match_dup 3))))] 8911 "ix86_match_ccmode (insn, CCNOmode)" 8912 [(parallel [(set (match_dup 0) 8913 (match_op_dup 2 [(xor:SI (match_dup 3) (const_int -1)) 8914 (const_int 0)])) 8915 (set (match_dup 1) 8916 (zero_extend:DI (xor:SI (match_dup 3) (const_int -1))))])]) 8917 8918;; Shift instructions 8919 8920;; DImode shifts are implemented using the i386 "shift double" opcode, 8921;; which is written as "sh[lr]d[lw] imm,reg,reg/mem". If the shift count 8922;; is variable, then the count is in %cl and the "imm" operand is dropped 8923;; from the assembler input. 8924;; 8925;; This instruction shifts the target reg/mem as usual, but instead of 8926;; shifting in zeros, bits are shifted in from reg operand. If the insn 8927;; is a left shift double, bits are taken from the high order bits of 8928;; reg, else if the insn is a shift right double, bits are taken from the 8929;; low order bits of reg. So if %eax is "1234" and %edx is "5678", 8930;; "shldl $8,%edx,%eax" leaves %edx unchanged and sets %eax to "2345". 8931;; 8932;; Since sh[lr]d does not change the `reg' operand, that is done 8933;; separately, making all shifts emit pairs of shift double and normal 8934;; shift. Since sh[lr]d does not shift more than 31 bits, and we wish to 8935;; support a 63 bit shift, each shift where the count is in a reg expands 8936;; to a pair of shifts, a branch, a shift by 32 and a label. 8937;; 8938;; If the shift count is a constant, we need never emit more than one 8939;; shift pair, instead using moves and sign extension for counts greater 8940;; than 31. 8941 8942(define_expand "ashl<mode>3" 8943 [(set (match_operand:SDWIM 0 "<shift_operand>" "") 8944 (ashift:SDWIM (match_operand:SDWIM 1 "<ashl_input_operand>" "") 8945 (match_operand:QI 2 "nonmemory_operand" "")))] 8946 "" 8947 "ix86_expand_binary_operator (ASHIFT, <MODE>mode, operands); DONE;") 8948 8949(define_insn "*ashl<mode>3_doubleword" 8950 [(set (match_operand:DWI 0 "register_operand" "=&r,r") 8951 (ashift:DWI (match_operand:DWI 1 "reg_or_pm1_operand" "n,0") 8952 (match_operand:QI 2 "nonmemory_operand" "<S>c,<S>c"))) 8953 (clobber (reg:CC FLAGS_REG))] 8954 "" 8955 "#" 8956 [(set_attr "type" "multi")]) 8957 8958(define_split 8959 [(set (match_operand:DWI 0 "register_operand" "") 8960 (ashift:DWI (match_operand:DWI 1 "nonmemory_operand" "") 8961 (match_operand:QI 2 "nonmemory_operand" ""))) 8962 (clobber (reg:CC FLAGS_REG))] 8963 "(optimize && flag_peephole2) ? epilogue_completed : reload_completed" 8964 [(const_int 0)] 8965 "ix86_split_ashl (operands, NULL_RTX, <MODE>mode); DONE;") 8966 8967;; By default we don't ask for a scratch register, because when DWImode 8968;; values are manipulated, registers are already at a premium. But if 8969;; we have one handy, we won't turn it away. 8970 8971(define_peephole2 8972 [(match_scratch:DWIH 3 "r") 8973 (parallel [(set (match_operand:<DWI> 0 "register_operand" "") 8974 (ashift:<DWI> 8975 (match_operand:<DWI> 1 "nonmemory_operand" "") 8976 (match_operand:QI 2 "nonmemory_operand" ""))) 8977 (clobber (reg:CC FLAGS_REG))]) 8978 (match_dup 3)] 8979 "TARGET_CMOVE" 8980 [(const_int 0)] 8981 "ix86_split_ashl (operands, operands[3], <DWI>mode); DONE;") 8982 8983(define_insn "x86_64_shld" 8984 [(set (match_operand:DI 0 "nonimmediate_operand" "+r*m") 8985 (ior:DI (ashift:DI (match_dup 0) 8986 (match_operand:QI 2 "nonmemory_operand" "Jc")) 8987 (lshiftrt:DI (match_operand:DI 1 "register_operand" "r") 8988 (minus:QI (const_int 64) (match_dup 2))))) 8989 (clobber (reg:CC FLAGS_REG))] 8990 "TARGET_64BIT" 8991 "shld{q}\t{%s2%1, %0|%0, %1, %2}" 8992 [(set_attr "type" "ishift") 8993 (set_attr "prefix_0f" "1") 8994 (set_attr "mode" "DI") 8995 (set_attr "athlon_decode" "vector") 8996 (set_attr "amdfam10_decode" "vector") 8997 (set_attr "bdver1_decode" "vector")]) 8998 8999(define_insn "x86_shld" 9000 [(set (match_operand:SI 0 "nonimmediate_operand" "+r*m") 9001 (ior:SI (ashift:SI (match_dup 0) 9002 (match_operand:QI 2 "nonmemory_operand" "Ic")) 9003 (lshiftrt:SI (match_operand:SI 1 "register_operand" "r") 9004 (minus:QI (const_int 32) (match_dup 2))))) 9005 (clobber (reg:CC FLAGS_REG))] 9006 "" 9007 "shld{l}\t{%s2%1, %0|%0, %1, %2}" 9008 [(set_attr "type" "ishift") 9009 (set_attr "prefix_0f" "1") 9010 (set_attr "mode" "SI") 9011 (set_attr "pent_pair" "np") 9012 (set_attr "athlon_decode" "vector") 9013 (set_attr "amdfam10_decode" "vector") 9014 (set_attr "bdver1_decode" "vector")]) 9015 9016(define_expand "x86_shift<mode>_adj_1" 9017 [(set (reg:CCZ FLAGS_REG) 9018 (compare:CCZ (and:QI (match_operand:QI 2 "register_operand" "") 9019 (match_dup 4)) 9020 (const_int 0))) 9021 (set (match_operand:SWI48 0 "register_operand" "") 9022 (if_then_else:SWI48 (ne (reg:CCZ FLAGS_REG) (const_int 0)) 9023 (match_operand:SWI48 1 "register_operand" "") 9024 (match_dup 0))) 9025 (set (match_dup 1) 9026 (if_then_else:SWI48 (ne (reg:CCZ FLAGS_REG) (const_int 0)) 9027 (match_operand:SWI48 3 "register_operand" "") 9028 (match_dup 1)))] 9029 "TARGET_CMOVE" 9030 "operands[4] = GEN_INT (GET_MODE_BITSIZE (<MODE>mode));") 9031 9032(define_expand "x86_shift<mode>_adj_2" 9033 [(use (match_operand:SWI48 0 "register_operand" "")) 9034 (use (match_operand:SWI48 1 "register_operand" "")) 9035 (use (match_operand:QI 2 "register_operand" ""))] 9036 "" 9037{ 9038 rtx label = gen_label_rtx (); 9039 rtx tmp; 9040 9041 emit_insn (gen_testqi_ccz_1 (operands[2], 9042 GEN_INT (GET_MODE_BITSIZE (<MODE>mode)))); 9043 9044 tmp = gen_rtx_REG (CCZmode, FLAGS_REG); 9045 tmp = gen_rtx_EQ (VOIDmode, tmp, const0_rtx); 9046 tmp = gen_rtx_IF_THEN_ELSE (VOIDmode, tmp, 9047 gen_rtx_LABEL_REF (VOIDmode, label), 9048 pc_rtx); 9049 tmp = emit_jump_insn (gen_rtx_SET (VOIDmode, pc_rtx, tmp)); 9050 JUMP_LABEL (tmp) = label; 9051 9052 emit_move_insn (operands[0], operands[1]); 9053 ix86_expand_clear (operands[1]); 9054 9055 emit_label (label); 9056 LABEL_NUSES (label) = 1; 9057 9058 DONE; 9059}) 9060 9061;; Avoid useless masking of count operand. 9062(define_insn_and_split "*ashl<mode>3_mask" 9063 [(set (match_operand:SWI48 0 "nonimmediate_operand" "=rm") 9064 (ashift:SWI48 9065 (match_operand:SWI48 1 "nonimmediate_operand" "0") 9066 (subreg:QI 9067 (and:SI 9068 (match_operand:SI 2 "nonimmediate_operand" "c") 9069 (match_operand:SI 3 "const_int_operand" "n")) 0))) 9070 (clobber (reg:CC FLAGS_REG))] 9071 "ix86_binary_operator_ok (ASHIFT, <MODE>mode, operands) 9072 && (INTVAL (operands[3]) & (GET_MODE_BITSIZE (<MODE>mode)-1)) 9073 == GET_MODE_BITSIZE (<MODE>mode)-1" 9074 "#" 9075 "&& 1" 9076 [(parallel [(set (match_dup 0) 9077 (ashift:SWI48 (match_dup 1) (match_dup 2))) 9078 (clobber (reg:CC FLAGS_REG))])] 9079{ 9080 if (can_create_pseudo_p ()) 9081 operands [2] = force_reg (SImode, operands[2]); 9082 9083 operands[2] = simplify_gen_subreg (QImode, operands[2], SImode, 0); 9084} 9085 [(set_attr "type" "ishift") 9086 (set_attr "mode" "<MODE>")]) 9087 9088(define_insn "*bmi2_ashl<mode>3_1" 9089 [(set (match_operand:SWI48 0 "register_operand" "=r") 9090 (ashift:SWI48 (match_operand:SWI48 1 "nonimmediate_operand" "rm") 9091 (match_operand:SWI48 2 "register_operand" "r")))] 9092 "TARGET_BMI2" 9093 "shlx\t{%2, %1, %0|%0, %1, %2}" 9094 [(set_attr "type" "ishiftx") 9095 (set_attr "mode" "<MODE>")]) 9096 9097(define_insn "*ashl<mode>3_1" 9098 [(set (match_operand:SWI48 0 "nonimmediate_operand" "=rm,r,r") 9099 (ashift:SWI48 (match_operand:SWI48 1 "nonimmediate_operand" "0,l,rm") 9100 (match_operand:QI 2 "nonmemory_operand" "c<S>,M,r"))) 9101 (clobber (reg:CC FLAGS_REG))] 9102 "ix86_binary_operator_ok (ASHIFT, <MODE>mode, operands)" 9103{ 9104 switch (get_attr_type (insn)) 9105 { 9106 case TYPE_LEA: 9107 case TYPE_ISHIFTX: 9108 return "#"; 9109 9110 case TYPE_ALU: 9111 gcc_assert (operands[2] == const1_rtx); 9112 gcc_assert (rtx_equal_p (operands[0], operands[1])); 9113 return "add{<imodesuffix>}\t%0, %0"; 9114 9115 default: 9116 if (operands[2] == const1_rtx 9117 && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun))) 9118 return "sal{<imodesuffix>}\t%0"; 9119 else 9120 return "sal{<imodesuffix>}\t{%2, %0|%0, %2}"; 9121 } 9122} 9123 [(set_attr "isa" "*,*,bmi2") 9124 (set (attr "type") 9125 (cond [(eq_attr "alternative" "1") 9126 (const_string "lea") 9127 (eq_attr "alternative" "2") 9128 (const_string "ishiftx") 9129 (and (and (match_test "TARGET_DOUBLE_WITH_ADD") 9130 (match_operand 0 "register_operand" "")) 9131 (match_operand 2 "const1_operand" "")) 9132 (const_string "alu") 9133 ] 9134 (const_string "ishift"))) 9135 (set (attr "length_immediate") 9136 (if_then_else 9137 (ior (eq_attr "type" "alu") 9138 (and (eq_attr "type" "ishift") 9139 (and (match_operand 2 "const1_operand" "") 9140 (ior (match_test "TARGET_SHIFT1") 9141 (match_test "optimize_function_for_size_p (cfun)"))))) 9142 (const_string "0") 9143 (const_string "*"))) 9144 (set_attr "mode" "<MODE>")]) 9145 9146;; Convert shift to the shiftx pattern to avoid flags dependency. 9147(define_split 9148 [(set (match_operand:SWI48 0 "register_operand" "") 9149 (ashift:SWI48 (match_operand:SWI48 1 "nonimmediate_operand" "") 9150 (match_operand:QI 2 "register_operand" ""))) 9151 (clobber (reg:CC FLAGS_REG))] 9152 "TARGET_BMI2 && reload_completed" 9153 [(set (match_dup 0) 9154 (ashift:SWI48 (match_dup 1) (match_dup 2)))] 9155 "operands[2] = gen_lowpart (<MODE>mode, operands[2]);") 9156 9157(define_insn "*bmi2_ashlsi3_1_zext" 9158 [(set (match_operand:DI 0 "register_operand" "=r") 9159 (zero_extend:DI 9160 (ashift:SI (match_operand:SI 1 "nonimmediate_operand" "rm") 9161 (match_operand:SI 2 "register_operand" "r"))))] 9162 "TARGET_64BIT && TARGET_BMI2" 9163 "shlx\t{%2, %1, %k0|%k0, %1, %2}" 9164 [(set_attr "type" "ishiftx") 9165 (set_attr "mode" "SI")]) 9166 9167(define_insn "*ashlsi3_1_zext" 9168 [(set (match_operand:DI 0 "register_operand" "=r,r,r") 9169 (zero_extend:DI 9170 (ashift:SI (match_operand:SI 1 "nonimmediate_operand" "0,l,rm") 9171 (match_operand:QI 2 "nonmemory_operand" "cI,M,r")))) 9172 (clobber (reg:CC FLAGS_REG))] 9173 "TARGET_64BIT && ix86_binary_operator_ok (ASHIFT, SImode, operands)" 9174{ 9175 switch (get_attr_type (insn)) 9176 { 9177 case TYPE_LEA: 9178 case TYPE_ISHIFTX: 9179 return "#"; 9180 9181 case TYPE_ALU: 9182 gcc_assert (operands[2] == const1_rtx); 9183 return "add{l}\t%k0, %k0"; 9184 9185 default: 9186 if (operands[2] == const1_rtx 9187 && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun))) 9188 return "sal{l}\t%k0"; 9189 else 9190 return "sal{l}\t{%2, %k0|%k0, %2}"; 9191 } 9192} 9193 [(set_attr "isa" "*,*,bmi2") 9194 (set (attr "type") 9195 (cond [(eq_attr "alternative" "1") 9196 (const_string "lea") 9197 (eq_attr "alternative" "2") 9198 (const_string "ishiftx") 9199 (and (match_test "TARGET_DOUBLE_WITH_ADD") 9200 (match_operand 2 "const1_operand" "")) 9201 (const_string "alu") 9202 ] 9203 (const_string "ishift"))) 9204 (set (attr "length_immediate") 9205 (if_then_else 9206 (ior (eq_attr "type" "alu") 9207 (and (eq_attr "type" "ishift") 9208 (and (match_operand 2 "const1_operand" "") 9209 (ior (match_test "TARGET_SHIFT1") 9210 (match_test "optimize_function_for_size_p (cfun)"))))) 9211 (const_string "0") 9212 (const_string "*"))) 9213 (set_attr "mode" "SI")]) 9214 9215;; Convert shift to the shiftx pattern to avoid flags dependency. 9216(define_split 9217 [(set (match_operand:DI 0 "register_operand" "") 9218 (zero_extend:DI 9219 (ashift:SI (match_operand:SI 1 "nonimmediate_operand" "") 9220 (match_operand:QI 2 "register_operand" "")))) 9221 (clobber (reg:CC FLAGS_REG))] 9222 "TARGET_64BIT && TARGET_BMI2 && reload_completed" 9223 [(set (match_dup 0) 9224 (zero_extend:DI (ashift:SI (match_dup 1) (match_dup 2))))] 9225 "operands[2] = gen_lowpart (SImode, operands[2]);") 9226 9227(define_insn "*ashlhi3_1" 9228 [(set (match_operand:HI 0 "nonimmediate_operand" "=rm,Yp") 9229 (ashift:HI (match_operand:HI 1 "nonimmediate_operand" "0,l") 9230 (match_operand:QI 2 "nonmemory_operand" "cI,M"))) 9231 (clobber (reg:CC FLAGS_REG))] 9232 "ix86_binary_operator_ok (ASHIFT, HImode, operands)" 9233{ 9234 switch (get_attr_type (insn)) 9235 { 9236 case TYPE_LEA: 9237 return "#"; 9238 9239 case TYPE_ALU: 9240 gcc_assert (operands[2] == const1_rtx); 9241 return "add{w}\t%0, %0"; 9242 9243 default: 9244 if (operands[2] == const1_rtx 9245 && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun))) 9246 return "sal{w}\t%0"; 9247 else 9248 return "sal{w}\t{%2, %0|%0, %2}"; 9249 } 9250} 9251 [(set (attr "type") 9252 (cond [(eq_attr "alternative" "1") 9253 (const_string "lea") 9254 (and (and (match_test "TARGET_DOUBLE_WITH_ADD") 9255 (match_operand 0 "register_operand" "")) 9256 (match_operand 2 "const1_operand" "")) 9257 (const_string "alu") 9258 ] 9259 (const_string "ishift"))) 9260 (set (attr "length_immediate") 9261 (if_then_else 9262 (ior (eq_attr "type" "alu") 9263 (and (eq_attr "type" "ishift") 9264 (and (match_operand 2 "const1_operand" "") 9265 (ior (match_test "TARGET_SHIFT1") 9266 (match_test "optimize_function_for_size_p (cfun)"))))) 9267 (const_string "0") 9268 (const_string "*"))) 9269 (set_attr "mode" "HI,SI")]) 9270 9271;; %%% Potential partial reg stall on alternative 1. What to do? 9272(define_insn "*ashlqi3_1" 9273 [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,r,Yp") 9274 (ashift:QI (match_operand:QI 1 "nonimmediate_operand" "0,0,l") 9275 (match_operand:QI 2 "nonmemory_operand" "cI,cI,M"))) 9276 (clobber (reg:CC FLAGS_REG))] 9277 "ix86_binary_operator_ok (ASHIFT, QImode, operands)" 9278{ 9279 switch (get_attr_type (insn)) 9280 { 9281 case TYPE_LEA: 9282 return "#"; 9283 9284 case TYPE_ALU: 9285 gcc_assert (operands[2] == const1_rtx); 9286 if (REG_P (operands[1]) && !ANY_QI_REG_P (operands[1])) 9287 return "add{l}\t%k0, %k0"; 9288 else 9289 return "add{b}\t%0, %0"; 9290 9291 default: 9292 if (operands[2] == const1_rtx 9293 && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun))) 9294 { 9295 if (get_attr_mode (insn) == MODE_SI) 9296 return "sal{l}\t%k0"; 9297 else 9298 return "sal{b}\t%0"; 9299 } 9300 else 9301 { 9302 if (get_attr_mode (insn) == MODE_SI) 9303 return "sal{l}\t{%2, %k0|%k0, %2}"; 9304 else 9305 return "sal{b}\t{%2, %0|%0, %2}"; 9306 } 9307 } 9308} 9309 [(set (attr "type") 9310 (cond [(eq_attr "alternative" "2") 9311 (const_string "lea") 9312 (and (and (match_test "TARGET_DOUBLE_WITH_ADD") 9313 (match_operand 0 "register_operand" "")) 9314 (match_operand 2 "const1_operand" "")) 9315 (const_string "alu") 9316 ] 9317 (const_string "ishift"))) 9318 (set (attr "length_immediate") 9319 (if_then_else 9320 (ior (eq_attr "type" "alu") 9321 (and (eq_attr "type" "ishift") 9322 (and (match_operand 2 "const1_operand" "") 9323 (ior (match_test "TARGET_SHIFT1") 9324 (match_test "optimize_function_for_size_p (cfun)"))))) 9325 (const_string "0") 9326 (const_string "*"))) 9327 (set_attr "mode" "QI,SI,SI")]) 9328 9329(define_insn "*ashlqi3_1_slp" 9330 [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm")) 9331 (ashift:QI (match_dup 0) 9332 (match_operand:QI 1 "nonmemory_operand" "cI"))) 9333 (clobber (reg:CC FLAGS_REG))] 9334 "(optimize_function_for_size_p (cfun) 9335 || !TARGET_PARTIAL_FLAG_REG_STALL 9336 || (operands[1] == const1_rtx 9337 && (TARGET_SHIFT1 9338 || (TARGET_DOUBLE_WITH_ADD && REG_P (operands[0])))))" 9339{ 9340 switch (get_attr_type (insn)) 9341 { 9342 case TYPE_ALU: 9343 gcc_assert (operands[1] == const1_rtx); 9344 return "add{b}\t%0, %0"; 9345 9346 default: 9347 if (operands[1] == const1_rtx 9348 && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun))) 9349 return "sal{b}\t%0"; 9350 else 9351 return "sal{b}\t{%1, %0|%0, %1}"; 9352 } 9353} 9354 [(set (attr "type") 9355 (cond [(and (and (match_test "TARGET_DOUBLE_WITH_ADD") 9356 (match_operand 0 "register_operand" "")) 9357 (match_operand 1 "const1_operand" "")) 9358 (const_string "alu") 9359 ] 9360 (const_string "ishift1"))) 9361 (set (attr "length_immediate") 9362 (if_then_else 9363 (ior (eq_attr "type" "alu") 9364 (and (eq_attr "type" "ishift1") 9365 (and (match_operand 1 "const1_operand" "") 9366 (ior (match_test "TARGET_SHIFT1") 9367 (match_test "optimize_function_for_size_p (cfun)"))))) 9368 (const_string "0") 9369 (const_string "*"))) 9370 (set_attr "mode" "QI")]) 9371 9372;; Convert ashift to the lea pattern to avoid flags dependency. 9373(define_split 9374 [(set (match_operand 0 "register_operand" "") 9375 (ashift (match_operand 1 "index_register_operand" "") 9376 (match_operand:QI 2 "const_int_operand" ""))) 9377 (clobber (reg:CC FLAGS_REG))] 9378 "GET_MODE (operands[0]) == GET_MODE (operands[1]) 9379 && reload_completed 9380 && true_regnum (operands[0]) != true_regnum (operands[1])" 9381 [(const_int 0)] 9382{ 9383 enum machine_mode mode = GET_MODE (operands[0]); 9384 rtx pat; 9385 9386 if (GET_MODE_SIZE (mode) < GET_MODE_SIZE (SImode)) 9387 { 9388 mode = SImode; 9389 operands[0] = gen_lowpart (mode, operands[0]); 9390 operands[1] = gen_lowpart (mode, operands[1]); 9391 } 9392 9393 operands[2] = gen_int_mode (1 << INTVAL (operands[2]), mode); 9394 9395 pat = gen_rtx_MULT (mode, operands[1], operands[2]); 9396 9397 emit_insn (gen_rtx_SET (VOIDmode, operands[0], pat)); 9398 DONE; 9399}) 9400 9401;; Convert ashift to the lea pattern to avoid flags dependency. 9402(define_split 9403 [(set (match_operand:DI 0 "register_operand" "") 9404 (zero_extend:DI 9405 (ashift:SI (match_operand:SI 1 "index_register_operand" "") 9406 (match_operand:QI 2 "const_int_operand" "")))) 9407 (clobber (reg:CC FLAGS_REG))] 9408 "TARGET_64BIT && reload_completed 9409 && true_regnum (operands[0]) != true_regnum (operands[1])" 9410 [(set (match_dup 0) 9411 (zero_extend:DI (subreg:SI (mult:DI (match_dup 1) (match_dup 2)) 0)))] 9412{ 9413 operands[1] = gen_lowpart (DImode, operands[1]); 9414 operands[2] = gen_int_mode (1 << INTVAL (operands[2]), DImode); 9415}) 9416 9417;; This pattern can't accept a variable shift count, since shifts by 9418;; zero don't affect the flags. We assume that shifts by constant 9419;; zero are optimized away. 9420(define_insn "*ashl<mode>3_cmp" 9421 [(set (reg FLAGS_REG) 9422 (compare 9423 (ashift:SWI (match_operand:SWI 1 "nonimmediate_operand" "0") 9424 (match_operand:QI 2 "<shift_immediate_operand>" "<S>")) 9425 (const_int 0))) 9426 (set (match_operand:SWI 0 "nonimmediate_operand" "=<r>m") 9427 (ashift:SWI (match_dup 1) (match_dup 2)))] 9428 "(optimize_function_for_size_p (cfun) 9429 || !TARGET_PARTIAL_FLAG_REG_STALL 9430 || (operands[2] == const1_rtx 9431 && (TARGET_SHIFT1 9432 || (TARGET_DOUBLE_WITH_ADD && REG_P (operands[0]))))) 9433 && ix86_match_ccmode (insn, CCGOCmode) 9434 && ix86_binary_operator_ok (ASHIFT, <MODE>mode, operands)" 9435{ 9436 switch (get_attr_type (insn)) 9437 { 9438 case TYPE_ALU: 9439 gcc_assert (operands[2] == const1_rtx); 9440 return "add{<imodesuffix>}\t%0, %0"; 9441 9442 default: 9443 if (operands[2] == const1_rtx 9444 && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun))) 9445 return "sal{<imodesuffix>}\t%0"; 9446 else 9447 return "sal{<imodesuffix>}\t{%2, %0|%0, %2}"; 9448 } 9449} 9450 [(set (attr "type") 9451 (cond [(and (and (match_test "TARGET_DOUBLE_WITH_ADD") 9452 (match_operand 0 "register_operand" "")) 9453 (match_operand 2 "const1_operand" "")) 9454 (const_string "alu") 9455 ] 9456 (const_string "ishift"))) 9457 (set (attr "length_immediate") 9458 (if_then_else 9459 (ior (eq_attr "type" "alu") 9460 (and (eq_attr "type" "ishift") 9461 (and (match_operand 2 "const1_operand" "") 9462 (ior (match_test "TARGET_SHIFT1") 9463 (match_test "optimize_function_for_size_p (cfun)"))))) 9464 (const_string "0") 9465 (const_string "*"))) 9466 (set_attr "mode" "<MODE>")]) 9467 9468(define_insn "*ashlsi3_cmp_zext" 9469 [(set (reg FLAGS_REG) 9470 (compare 9471 (ashift:SI (match_operand:SI 1 "register_operand" "0") 9472 (match_operand:QI 2 "const_1_to_31_operand" "I")) 9473 (const_int 0))) 9474 (set (match_operand:DI 0 "register_operand" "=r") 9475 (zero_extend:DI (ashift:SI (match_dup 1) (match_dup 2))))] 9476 "TARGET_64BIT 9477 && (optimize_function_for_size_p (cfun) 9478 || !TARGET_PARTIAL_FLAG_REG_STALL 9479 || (operands[2] == const1_rtx 9480 && (TARGET_SHIFT1 9481 || TARGET_DOUBLE_WITH_ADD))) 9482 && ix86_match_ccmode (insn, CCGOCmode) 9483 && ix86_binary_operator_ok (ASHIFT, SImode, operands)" 9484{ 9485 switch (get_attr_type (insn)) 9486 { 9487 case TYPE_ALU: 9488 gcc_assert (operands[2] == const1_rtx); 9489 return "add{l}\t%k0, %k0"; 9490 9491 default: 9492 if (operands[2] == const1_rtx 9493 && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun))) 9494 return "sal{l}\t%k0"; 9495 else 9496 return "sal{l}\t{%2, %k0|%k0, %2}"; 9497 } 9498} 9499 [(set (attr "type") 9500 (cond [(and (match_test "TARGET_DOUBLE_WITH_ADD") 9501 (match_operand 2 "const1_operand" "")) 9502 (const_string "alu") 9503 ] 9504 (const_string "ishift"))) 9505 (set (attr "length_immediate") 9506 (if_then_else 9507 (ior (eq_attr "type" "alu") 9508 (and (eq_attr "type" "ishift") 9509 (and (match_operand 2 "const1_operand" "") 9510 (ior (match_test "TARGET_SHIFT1") 9511 (match_test "optimize_function_for_size_p (cfun)"))))) 9512 (const_string "0") 9513 (const_string "*"))) 9514 (set_attr "mode" "SI")]) 9515 9516(define_insn "*ashl<mode>3_cconly" 9517 [(set (reg FLAGS_REG) 9518 (compare 9519 (ashift:SWI (match_operand:SWI 1 "register_operand" "0") 9520 (match_operand:QI 2 "<shift_immediate_operand>" "<S>")) 9521 (const_int 0))) 9522 (clobber (match_scratch:SWI 0 "=<r>"))] 9523 "(optimize_function_for_size_p (cfun) 9524 || !TARGET_PARTIAL_FLAG_REG_STALL 9525 || (operands[2] == const1_rtx 9526 && (TARGET_SHIFT1 9527 || TARGET_DOUBLE_WITH_ADD))) 9528 && ix86_match_ccmode (insn, CCGOCmode)" 9529{ 9530 switch (get_attr_type (insn)) 9531 { 9532 case TYPE_ALU: 9533 gcc_assert (operands[2] == const1_rtx); 9534 return "add{<imodesuffix>}\t%0, %0"; 9535 9536 default: 9537 if (operands[2] == const1_rtx 9538 && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun))) 9539 return "sal{<imodesuffix>}\t%0"; 9540 else 9541 return "sal{<imodesuffix>}\t{%2, %0|%0, %2}"; 9542 } 9543} 9544 [(set (attr "type") 9545 (cond [(and (and (match_test "TARGET_DOUBLE_WITH_ADD") 9546 (match_operand 0 "register_operand" "")) 9547 (match_operand 2 "const1_operand" "")) 9548 (const_string "alu") 9549 ] 9550 (const_string "ishift"))) 9551 (set (attr "length_immediate") 9552 (if_then_else 9553 (ior (eq_attr "type" "alu") 9554 (and (eq_attr "type" "ishift") 9555 (and (match_operand 2 "const1_operand" "") 9556 (ior (match_test "TARGET_SHIFT1") 9557 (match_test "optimize_function_for_size_p (cfun)"))))) 9558 (const_string "0") 9559 (const_string "*"))) 9560 (set_attr "mode" "<MODE>")]) 9561 9562;; See comment above `ashl<mode>3' about how this works. 9563 9564(define_expand "<shift_insn><mode>3" 9565 [(set (match_operand:SDWIM 0 "<shift_operand>" "") 9566 (any_shiftrt:SDWIM (match_operand:SDWIM 1 "<shift_operand>" "") 9567 (match_operand:QI 2 "nonmemory_operand" "")))] 9568 "" 9569 "ix86_expand_binary_operator (<CODE>, <MODE>mode, operands); DONE;") 9570 9571;; Avoid useless masking of count operand. 9572(define_insn_and_split "*<shift_insn><mode>3_mask" 9573 [(set (match_operand:SWI48 0 "nonimmediate_operand" "=rm") 9574 (any_shiftrt:SWI48 9575 (match_operand:SWI48 1 "nonimmediate_operand" "0") 9576 (subreg:QI 9577 (and:SI 9578 (match_operand:SI 2 "nonimmediate_operand" "c") 9579 (match_operand:SI 3 "const_int_operand" "n")) 0))) 9580 (clobber (reg:CC FLAGS_REG))] 9581 "ix86_binary_operator_ok (<CODE>, <MODE>mode, operands) 9582 && (INTVAL (operands[3]) & (GET_MODE_BITSIZE (<MODE>mode)-1)) 9583 == GET_MODE_BITSIZE (<MODE>mode)-1" 9584 "#" 9585 "&& 1" 9586 [(parallel [(set (match_dup 0) 9587 (any_shiftrt:SWI48 (match_dup 1) (match_dup 2))) 9588 (clobber (reg:CC FLAGS_REG))])] 9589{ 9590 if (can_create_pseudo_p ()) 9591 operands [2] = force_reg (SImode, operands[2]); 9592 9593 operands[2] = simplify_gen_subreg (QImode, operands[2], SImode, 0); 9594} 9595 [(set_attr "type" "ishift") 9596 (set_attr "mode" "<MODE>")]) 9597 9598(define_insn_and_split "*<shift_insn><mode>3_doubleword" 9599 [(set (match_operand:DWI 0 "register_operand" "=r") 9600 (any_shiftrt:DWI (match_operand:DWI 1 "register_operand" "0") 9601 (match_operand:QI 2 "nonmemory_operand" "<S>c"))) 9602 (clobber (reg:CC FLAGS_REG))] 9603 "" 9604 "#" 9605 "(optimize && flag_peephole2) ? epilogue_completed : reload_completed" 9606 [(const_int 0)] 9607 "ix86_split_<shift_insn> (operands, NULL_RTX, <MODE>mode); DONE;" 9608 [(set_attr "type" "multi")]) 9609 9610;; By default we don't ask for a scratch register, because when DWImode 9611;; values are manipulated, registers are already at a premium. But if 9612;; we have one handy, we won't turn it away. 9613 9614(define_peephole2 9615 [(match_scratch:DWIH 3 "r") 9616 (parallel [(set (match_operand:<DWI> 0 "register_operand" "") 9617 (any_shiftrt:<DWI> 9618 (match_operand:<DWI> 1 "register_operand" "") 9619 (match_operand:QI 2 "nonmemory_operand" ""))) 9620 (clobber (reg:CC FLAGS_REG))]) 9621 (match_dup 3)] 9622 "TARGET_CMOVE" 9623 [(const_int 0)] 9624 "ix86_split_<shift_insn> (operands, operands[3], <DWI>mode); DONE;") 9625 9626(define_insn "x86_64_shrd" 9627 [(set (match_operand:DI 0 "nonimmediate_operand" "+r*m") 9628 (ior:DI (ashiftrt:DI (match_dup 0) 9629 (match_operand:QI 2 "nonmemory_operand" "Jc")) 9630 (ashift:DI (match_operand:DI 1 "register_operand" "r") 9631 (minus:QI (const_int 64) (match_dup 2))))) 9632 (clobber (reg:CC FLAGS_REG))] 9633 "TARGET_64BIT" 9634 "shrd{q}\t{%s2%1, %0|%0, %1, %2}" 9635 [(set_attr "type" "ishift") 9636 (set_attr "prefix_0f" "1") 9637 (set_attr "mode" "DI") 9638 (set_attr "athlon_decode" "vector") 9639 (set_attr "amdfam10_decode" "vector") 9640 (set_attr "bdver1_decode" "vector")]) 9641 9642(define_insn "x86_shrd" 9643 [(set (match_operand:SI 0 "nonimmediate_operand" "+r*m") 9644 (ior:SI (ashiftrt:SI (match_dup 0) 9645 (match_operand:QI 2 "nonmemory_operand" "Ic")) 9646 (ashift:SI (match_operand:SI 1 "register_operand" "r") 9647 (minus:QI (const_int 32) (match_dup 2))))) 9648 (clobber (reg:CC FLAGS_REG))] 9649 "" 9650 "shrd{l}\t{%s2%1, %0|%0, %1, %2}" 9651 [(set_attr "type" "ishift") 9652 (set_attr "prefix_0f" "1") 9653 (set_attr "mode" "SI") 9654 (set_attr "pent_pair" "np") 9655 (set_attr "athlon_decode" "vector") 9656 (set_attr "amdfam10_decode" "vector") 9657 (set_attr "bdver1_decode" "vector")]) 9658 9659(define_insn "ashrdi3_cvt" 9660 [(set (match_operand:DI 0 "nonimmediate_operand" "=*d,rm") 9661 (ashiftrt:DI (match_operand:DI 1 "nonimmediate_operand" "*a,0") 9662 (match_operand:QI 2 "const_int_operand" ""))) 9663 (clobber (reg:CC FLAGS_REG))] 9664 "TARGET_64BIT && INTVAL (operands[2]) == 63 9665 && (TARGET_USE_CLTD || optimize_function_for_size_p (cfun)) 9666 && ix86_binary_operator_ok (ASHIFTRT, DImode, operands)" 9667 "@ 9668 {cqto|cqo} 9669 sar{q}\t{%2, %0|%0, %2}" 9670 [(set_attr "type" "imovx,ishift") 9671 (set_attr "prefix_0f" "0,*") 9672 (set_attr "length_immediate" "0,*") 9673 (set_attr "modrm" "0,1") 9674 (set_attr "mode" "DI")]) 9675 9676(define_insn "ashrsi3_cvt" 9677 [(set (match_operand:SI 0 "nonimmediate_operand" "=*d,rm") 9678 (ashiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "*a,0") 9679 (match_operand:QI 2 "const_int_operand" ""))) 9680 (clobber (reg:CC FLAGS_REG))] 9681 "INTVAL (operands[2]) == 31 9682 && (TARGET_USE_CLTD || optimize_function_for_size_p (cfun)) 9683 && ix86_binary_operator_ok (ASHIFTRT, SImode, operands)" 9684 "@ 9685 {cltd|cdq} 9686 sar{l}\t{%2, %0|%0, %2}" 9687 [(set_attr "type" "imovx,ishift") 9688 (set_attr "prefix_0f" "0,*") 9689 (set_attr "length_immediate" "0,*") 9690 (set_attr "modrm" "0,1") 9691 (set_attr "mode" "SI")]) 9692 9693(define_insn "*ashrsi3_cvt_zext" 9694 [(set (match_operand:DI 0 "register_operand" "=*d,r") 9695 (zero_extend:DI 9696 (ashiftrt:SI (match_operand:SI 1 "register_operand" "*a,0") 9697 (match_operand:QI 2 "const_int_operand" "")))) 9698 (clobber (reg:CC FLAGS_REG))] 9699 "TARGET_64BIT && INTVAL (operands[2]) == 31 9700 && (TARGET_USE_CLTD || optimize_function_for_size_p (cfun)) 9701 && ix86_binary_operator_ok (ASHIFTRT, SImode, operands)" 9702 "@ 9703 {cltd|cdq} 9704 sar{l}\t{%2, %k0|%k0, %2}" 9705 [(set_attr "type" "imovx,ishift") 9706 (set_attr "prefix_0f" "0,*") 9707 (set_attr "length_immediate" "0,*") 9708 (set_attr "modrm" "0,1") 9709 (set_attr "mode" "SI")]) 9710 9711(define_expand "x86_shift<mode>_adj_3" 9712 [(use (match_operand:SWI48 0 "register_operand" "")) 9713 (use (match_operand:SWI48 1 "register_operand" "")) 9714 (use (match_operand:QI 2 "register_operand" ""))] 9715 "" 9716{ 9717 rtx label = gen_label_rtx (); 9718 rtx tmp; 9719 9720 emit_insn (gen_testqi_ccz_1 (operands[2], 9721 GEN_INT (GET_MODE_BITSIZE (<MODE>mode)))); 9722 9723 tmp = gen_rtx_REG (CCZmode, FLAGS_REG); 9724 tmp = gen_rtx_EQ (VOIDmode, tmp, const0_rtx); 9725 tmp = gen_rtx_IF_THEN_ELSE (VOIDmode, tmp, 9726 gen_rtx_LABEL_REF (VOIDmode, label), 9727 pc_rtx); 9728 tmp = emit_jump_insn (gen_rtx_SET (VOIDmode, pc_rtx, tmp)); 9729 JUMP_LABEL (tmp) = label; 9730 9731 emit_move_insn (operands[0], operands[1]); 9732 emit_insn (gen_ashr<mode>3_cvt (operands[1], operands[1], 9733 GEN_INT (GET_MODE_BITSIZE (<MODE>mode)-1))); 9734 emit_label (label); 9735 LABEL_NUSES (label) = 1; 9736 9737 DONE; 9738}) 9739 9740(define_insn "*bmi2_<shift_insn><mode>3_1" 9741 [(set (match_operand:SWI48 0 "register_operand" "=r") 9742 (any_shiftrt:SWI48 (match_operand:SWI48 1 "nonimmediate_operand" "rm") 9743 (match_operand:SWI48 2 "register_operand" "r")))] 9744 "TARGET_BMI2" 9745 "<shift>x\t{%2, %1, %0|%0, %1, %2}" 9746 [(set_attr "type" "ishiftx") 9747 (set_attr "mode" "<MODE>")]) 9748 9749(define_insn "*<shift_insn><mode>3_1" 9750 [(set (match_operand:SWI48 0 "nonimmediate_operand" "=rm,r") 9751 (any_shiftrt:SWI48 9752 (match_operand:SWI48 1 "nonimmediate_operand" "0,rm") 9753 (match_operand:QI 2 "nonmemory_operand" "c<S>,r"))) 9754 (clobber (reg:CC FLAGS_REG))] 9755 "ix86_binary_operator_ok (<CODE>, <MODE>mode, operands)" 9756{ 9757 switch (get_attr_type (insn)) 9758 { 9759 case TYPE_ISHIFTX: 9760 return "#"; 9761 9762 default: 9763 if (operands[2] == const1_rtx 9764 && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun))) 9765 return "<shift>{<imodesuffix>}\t%0"; 9766 else 9767 return "<shift>{<imodesuffix>}\t{%2, %0|%0, %2}"; 9768 } 9769} 9770 [(set_attr "isa" "*,bmi2") 9771 (set_attr "type" "ishift,ishiftx") 9772 (set (attr "length_immediate") 9773 (if_then_else 9774 (and (match_operand 2 "const1_operand" "") 9775 (ior (match_test "TARGET_SHIFT1") 9776 (match_test "optimize_function_for_size_p (cfun)"))) 9777 (const_string "0") 9778 (const_string "*"))) 9779 (set_attr "mode" "<MODE>")]) 9780 9781;; Convert shift to the shiftx pattern to avoid flags dependency. 9782(define_split 9783 [(set (match_operand:SWI48 0 "register_operand" "") 9784 (any_shiftrt:SWI48 (match_operand:SWI48 1 "nonimmediate_operand" "") 9785 (match_operand:QI 2 "register_operand" ""))) 9786 (clobber (reg:CC FLAGS_REG))] 9787 "TARGET_BMI2 && reload_completed" 9788 [(set (match_dup 0) 9789 (any_shiftrt:SWI48 (match_dup 1) (match_dup 2)))] 9790 "operands[2] = gen_lowpart (<MODE>mode, operands[2]);") 9791 9792(define_insn "*bmi2_<shift_insn>si3_1_zext" 9793 [(set (match_operand:DI 0 "register_operand" "=r") 9794 (zero_extend:DI 9795 (any_shiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "rm") 9796 (match_operand:SI 2 "register_operand" "r"))))] 9797 "TARGET_64BIT && TARGET_BMI2" 9798 "<shift>x\t{%2, %1, %k0|%k0, %1, %2}" 9799 [(set_attr "type" "ishiftx") 9800 (set_attr "mode" "SI")]) 9801 9802(define_insn "*<shift_insn>si3_1_zext" 9803 [(set (match_operand:DI 0 "register_operand" "=r,r") 9804 (zero_extend:DI 9805 (any_shiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "0,rm") 9806 (match_operand:QI 2 "nonmemory_operand" "cI,r")))) 9807 (clobber (reg:CC FLAGS_REG))] 9808 "TARGET_64BIT && ix86_binary_operator_ok (<CODE>, SImode, operands)" 9809{ 9810 switch (get_attr_type (insn)) 9811 { 9812 case TYPE_ISHIFTX: 9813 return "#"; 9814 9815 default: 9816 if (operands[2] == const1_rtx 9817 && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun))) 9818 return "<shift>{l}\t%k0"; 9819 else 9820 return "<shift>{l}\t{%2, %k0|%k0, %2}"; 9821 } 9822} 9823 [(set_attr "isa" "*,bmi2") 9824 (set_attr "type" "ishift,ishiftx") 9825 (set (attr "length_immediate") 9826 (if_then_else 9827 (and (match_operand 2 "const1_operand" "") 9828 (ior (match_test "TARGET_SHIFT1") 9829 (match_test "optimize_function_for_size_p (cfun)"))) 9830 (const_string "0") 9831 (const_string "*"))) 9832 (set_attr "mode" "SI")]) 9833 9834;; Convert shift to the shiftx pattern to avoid flags dependency. 9835(define_split 9836 [(set (match_operand:DI 0 "register_operand" "") 9837 (zero_extend:DI 9838 (any_shiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "") 9839 (match_operand:QI 2 "register_operand" "")))) 9840 (clobber (reg:CC FLAGS_REG))] 9841 "TARGET_64BIT && TARGET_BMI2 && reload_completed" 9842 [(set (match_dup 0) 9843 (zero_extend:DI (any_shiftrt:SI (match_dup 1) (match_dup 2))))] 9844 "operands[2] = gen_lowpart (SImode, operands[2]);") 9845 9846(define_insn "*<shift_insn><mode>3_1" 9847 [(set (match_operand:SWI12 0 "nonimmediate_operand" "=<r>m") 9848 (any_shiftrt:SWI12 9849 (match_operand:SWI12 1 "nonimmediate_operand" "0") 9850 (match_operand:QI 2 "nonmemory_operand" "c<S>"))) 9851 (clobber (reg:CC FLAGS_REG))] 9852 "ix86_binary_operator_ok (<CODE>, <MODE>mode, operands)" 9853{ 9854 if (operands[2] == const1_rtx 9855 && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun))) 9856 return "<shift>{<imodesuffix>}\t%0"; 9857 else 9858 return "<shift>{<imodesuffix>}\t{%2, %0|%0, %2}"; 9859} 9860 [(set_attr "type" "ishift") 9861 (set (attr "length_immediate") 9862 (if_then_else 9863 (and (match_operand 2 "const1_operand" "") 9864 (ior (match_test "TARGET_SHIFT1") 9865 (match_test "optimize_function_for_size_p (cfun)"))) 9866 (const_string "0") 9867 (const_string "*"))) 9868 (set_attr "mode" "<MODE>")]) 9869 9870(define_insn "*<shift_insn>qi3_1_slp" 9871 [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm")) 9872 (any_shiftrt:QI (match_dup 0) 9873 (match_operand:QI 1 "nonmemory_operand" "cI"))) 9874 (clobber (reg:CC FLAGS_REG))] 9875 "(optimize_function_for_size_p (cfun) 9876 || !TARGET_PARTIAL_REG_STALL 9877 || (operands[1] == const1_rtx 9878 && TARGET_SHIFT1))" 9879{ 9880 if (operands[1] == const1_rtx 9881 && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun))) 9882 return "<shift>{b}\t%0"; 9883 else 9884 return "<shift>{b}\t{%1, %0|%0, %1}"; 9885} 9886 [(set_attr "type" "ishift1") 9887 (set (attr "length_immediate") 9888 (if_then_else 9889 (and (match_operand 1 "const1_operand" "") 9890 (ior (match_test "TARGET_SHIFT1") 9891 (match_test "optimize_function_for_size_p (cfun)"))) 9892 (const_string "0") 9893 (const_string "*"))) 9894 (set_attr "mode" "QI")]) 9895 9896;; This pattern can't accept a variable shift count, since shifts by 9897;; zero don't affect the flags. We assume that shifts by constant 9898;; zero are optimized away. 9899(define_insn "*<shift_insn><mode>3_cmp" 9900 [(set (reg FLAGS_REG) 9901 (compare 9902 (any_shiftrt:SWI 9903 (match_operand:SWI 1 "nonimmediate_operand" "0") 9904 (match_operand:QI 2 "<shift_immediate_operand>" "<S>")) 9905 (const_int 0))) 9906 (set (match_operand:SWI 0 "nonimmediate_operand" "=<r>m") 9907 (any_shiftrt:SWI (match_dup 1) (match_dup 2)))] 9908 "(optimize_function_for_size_p (cfun) 9909 || !TARGET_PARTIAL_FLAG_REG_STALL 9910 || (operands[2] == const1_rtx 9911 && TARGET_SHIFT1)) 9912 && ix86_match_ccmode (insn, CCGOCmode) 9913 && ix86_binary_operator_ok (<CODE>, <MODE>mode, operands)" 9914{ 9915 if (operands[2] == const1_rtx 9916 && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun))) 9917 return "<shift>{<imodesuffix>}\t%0"; 9918 else 9919 return "<shift>{<imodesuffix>}\t{%2, %0|%0, %2}"; 9920} 9921 [(set_attr "type" "ishift") 9922 (set (attr "length_immediate") 9923 (if_then_else 9924 (and (match_operand 2 "const1_operand" "") 9925 (ior (match_test "TARGET_SHIFT1") 9926 (match_test "optimize_function_for_size_p (cfun)"))) 9927 (const_string "0") 9928 (const_string "*"))) 9929 (set_attr "mode" "<MODE>")]) 9930 9931(define_insn "*<shift_insn>si3_cmp_zext" 9932 [(set (reg FLAGS_REG) 9933 (compare 9934 (any_shiftrt:SI (match_operand:SI 1 "register_operand" "0") 9935 (match_operand:QI 2 "const_1_to_31_operand" "I")) 9936 (const_int 0))) 9937 (set (match_operand:DI 0 "register_operand" "=r") 9938 (zero_extend:DI (any_shiftrt:SI (match_dup 1) (match_dup 2))))] 9939 "TARGET_64BIT 9940 && (optimize_function_for_size_p (cfun) 9941 || !TARGET_PARTIAL_FLAG_REG_STALL 9942 || (operands[2] == const1_rtx 9943 && TARGET_SHIFT1)) 9944 && ix86_match_ccmode (insn, CCGOCmode) 9945 && ix86_binary_operator_ok (<CODE>, SImode, operands)" 9946{ 9947 if (operands[2] == const1_rtx 9948 && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun))) 9949 return "<shift>{l}\t%k0"; 9950 else 9951 return "<shift>{l}\t{%2, %k0|%k0, %2}"; 9952} 9953 [(set_attr "type" "ishift") 9954 (set (attr "length_immediate") 9955 (if_then_else 9956 (and (match_operand 2 "const1_operand" "") 9957 (ior (match_test "TARGET_SHIFT1") 9958 (match_test "optimize_function_for_size_p (cfun)"))) 9959 (const_string "0") 9960 (const_string "*"))) 9961 (set_attr "mode" "SI")]) 9962 9963(define_insn "*<shift_insn><mode>3_cconly" 9964 [(set (reg FLAGS_REG) 9965 (compare 9966 (any_shiftrt:SWI 9967 (match_operand:SWI 1 "register_operand" "0") 9968 (match_operand:QI 2 "<shift_immediate_operand>" "<S>")) 9969 (const_int 0))) 9970 (clobber (match_scratch:SWI 0 "=<r>"))] 9971 "(optimize_function_for_size_p (cfun) 9972 || !TARGET_PARTIAL_FLAG_REG_STALL 9973 || (operands[2] == const1_rtx 9974 && TARGET_SHIFT1)) 9975 && ix86_match_ccmode (insn, CCGOCmode)" 9976{ 9977 if (operands[2] == const1_rtx 9978 && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun))) 9979 return "<shift>{<imodesuffix>}\t%0"; 9980 else 9981 return "<shift>{<imodesuffix>}\t{%2, %0|%0, %2}"; 9982} 9983 [(set_attr "type" "ishift") 9984 (set (attr "length_immediate") 9985 (if_then_else 9986 (and (match_operand 2 "const1_operand" "") 9987 (ior (match_test "TARGET_SHIFT1") 9988 (match_test "optimize_function_for_size_p (cfun)"))) 9989 (const_string "0") 9990 (const_string "*"))) 9991 (set_attr "mode" "<MODE>")]) 9992 9993;; Rotate instructions 9994 9995(define_expand "<rotate_insn>ti3" 9996 [(set (match_operand:TI 0 "register_operand" "") 9997 (any_rotate:TI (match_operand:TI 1 "register_operand" "") 9998 (match_operand:QI 2 "nonmemory_operand" "")))] 9999 "TARGET_64BIT" 10000{ 10001 if (const_1_to_63_operand (operands[2], VOIDmode)) 10002 emit_insn (gen_ix86_<rotate_insn>ti3_doubleword 10003 (operands[0], operands[1], operands[2])); 10004 else 10005 FAIL; 10006 10007 DONE; 10008}) 10009 10010(define_expand "<rotate_insn>di3" 10011 [(set (match_operand:DI 0 "shiftdi_operand" "") 10012 (any_rotate:DI (match_operand:DI 1 "shiftdi_operand" "") 10013 (match_operand:QI 2 "nonmemory_operand" "")))] 10014 "" 10015{ 10016 if (TARGET_64BIT) 10017 ix86_expand_binary_operator (<CODE>, DImode, operands); 10018 else if (const_1_to_31_operand (operands[2], VOIDmode)) 10019 emit_insn (gen_ix86_<rotate_insn>di3_doubleword 10020 (operands[0], operands[1], operands[2])); 10021 else 10022 FAIL; 10023 10024 DONE; 10025}) 10026 10027(define_expand "<rotate_insn><mode>3" 10028 [(set (match_operand:SWIM124 0 "nonimmediate_operand" "") 10029 (any_rotate:SWIM124 (match_operand:SWIM124 1 "nonimmediate_operand" "") 10030 (match_operand:QI 2 "nonmemory_operand" "")))] 10031 "" 10032 "ix86_expand_binary_operator (<CODE>, <MODE>mode, operands); DONE;") 10033 10034;; Avoid useless masking of count operand. 10035(define_insn_and_split "*<rotate_insn><mode>3_mask" 10036 [(set (match_operand:SWI48 0 "nonimmediate_operand" "=rm") 10037 (any_rotate:SWI48 10038 (match_operand:SWI48 1 "nonimmediate_operand" "0") 10039 (subreg:QI 10040 (and:SI 10041 (match_operand:SI 2 "nonimmediate_operand" "c") 10042 (match_operand:SI 3 "const_int_operand" "n")) 0))) 10043 (clobber (reg:CC FLAGS_REG))] 10044 "ix86_binary_operator_ok (<CODE>, <MODE>mode, operands) 10045 && (INTVAL (operands[3]) & (GET_MODE_BITSIZE (<MODE>mode)-1)) 10046 == GET_MODE_BITSIZE (<MODE>mode)-1" 10047 "#" 10048 "&& 1" 10049 [(parallel [(set (match_dup 0) 10050 (any_rotate:SWI48 (match_dup 1) (match_dup 2))) 10051 (clobber (reg:CC FLAGS_REG))])] 10052{ 10053 if (can_create_pseudo_p ()) 10054 operands [2] = force_reg (SImode, operands[2]); 10055 10056 operands[2] = simplify_gen_subreg (QImode, operands[2], SImode, 0); 10057} 10058 [(set_attr "type" "rotate") 10059 (set_attr "mode" "<MODE>")]) 10060 10061;; Implement rotation using two double-precision 10062;; shift instructions and a scratch register. 10063 10064(define_insn_and_split "ix86_rotl<dwi>3_doubleword" 10065 [(set (match_operand:<DWI> 0 "register_operand" "=r") 10066 (rotate:<DWI> (match_operand:<DWI> 1 "register_operand" "0") 10067 (match_operand:QI 2 "<shift_immediate_operand>" "<S>"))) 10068 (clobber (reg:CC FLAGS_REG)) 10069 (clobber (match_scratch:DWIH 3 "=&r"))] 10070 "" 10071 "#" 10072 "reload_completed" 10073 [(set (match_dup 3) (match_dup 4)) 10074 (parallel 10075 [(set (match_dup 4) 10076 (ior:DWIH (ashift:DWIH (match_dup 4) (match_dup 2)) 10077 (lshiftrt:DWIH (match_dup 5) 10078 (minus:QI (match_dup 6) (match_dup 2))))) 10079 (clobber (reg:CC FLAGS_REG))]) 10080 (parallel 10081 [(set (match_dup 5) 10082 (ior:DWIH (ashift:DWIH (match_dup 5) (match_dup 2)) 10083 (lshiftrt:DWIH (match_dup 3) 10084 (minus:QI (match_dup 6) (match_dup 2))))) 10085 (clobber (reg:CC FLAGS_REG))])] 10086{ 10087 operands[6] = GEN_INT (GET_MODE_BITSIZE (<MODE>mode)); 10088 10089 split_double_mode (<DWI>mode, &operands[0], 1, &operands[4], &operands[5]); 10090}) 10091 10092(define_insn_and_split "ix86_rotr<dwi>3_doubleword" 10093 [(set (match_operand:<DWI> 0 "register_operand" "=r") 10094 (rotatert:<DWI> (match_operand:<DWI> 1 "register_operand" "0") 10095 (match_operand:QI 2 "<shift_immediate_operand>" "<S>"))) 10096 (clobber (reg:CC FLAGS_REG)) 10097 (clobber (match_scratch:DWIH 3 "=&r"))] 10098 "" 10099 "#" 10100 "reload_completed" 10101 [(set (match_dup 3) (match_dup 4)) 10102 (parallel 10103 [(set (match_dup 4) 10104 (ior:DWIH (ashiftrt:DWIH (match_dup 4) (match_dup 2)) 10105 (ashift:DWIH (match_dup 5) 10106 (minus:QI (match_dup 6) (match_dup 2))))) 10107 (clobber (reg:CC FLAGS_REG))]) 10108 (parallel 10109 [(set (match_dup 5) 10110 (ior:DWIH (ashiftrt:DWIH (match_dup 5) (match_dup 2)) 10111 (ashift:DWIH (match_dup 3) 10112 (minus:QI (match_dup 6) (match_dup 2))))) 10113 (clobber (reg:CC FLAGS_REG))])] 10114{ 10115 operands[6] = GEN_INT (GET_MODE_BITSIZE (<MODE>mode)); 10116 10117 split_double_mode (<DWI>mode, &operands[0], 1, &operands[4], &operands[5]); 10118}) 10119 10120(define_insn "*bmi2_rorx<mode>3_1" 10121 [(set (match_operand:SWI48 0 "register_operand" "=r") 10122 (rotatert:SWI48 (match_operand:SWI48 1 "nonimmediate_operand" "rm") 10123 (match_operand:QI 2 "immediate_operand" "<S>")))] 10124 "TARGET_BMI2" 10125 "rorx\t{%2, %1, %0|%0, %1, %2}" 10126 [(set_attr "type" "rotatex") 10127 (set_attr "mode" "<MODE>")]) 10128 10129(define_insn "*<rotate_insn><mode>3_1" 10130 [(set (match_operand:SWI48 0 "nonimmediate_operand" "=rm,r") 10131 (any_rotate:SWI48 10132 (match_operand:SWI48 1 "nonimmediate_operand" "0,rm") 10133 (match_operand:QI 2 "nonmemory_operand" "c<S>,<S>"))) 10134 (clobber (reg:CC FLAGS_REG))] 10135 "ix86_binary_operator_ok (<CODE>, <MODE>mode, operands)" 10136{ 10137 switch (get_attr_type (insn)) 10138 { 10139 case TYPE_ROTATEX: 10140 return "#"; 10141 10142 default: 10143 if (operands[2] == const1_rtx 10144 && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun))) 10145 return "<rotate>{<imodesuffix>}\t%0"; 10146 else 10147 return "<rotate>{<imodesuffix>}\t{%2, %0|%0, %2}"; 10148 } 10149} 10150 [(set_attr "isa" "*,bmi2") 10151 (set_attr "type" "rotate,rotatex") 10152 (set (attr "length_immediate") 10153 (if_then_else 10154 (and (eq_attr "type" "rotate") 10155 (and (match_operand 2 "const1_operand" "") 10156 (ior (match_test "TARGET_SHIFT1") 10157 (match_test "optimize_function_for_size_p (cfun)")))) 10158 (const_string "0") 10159 (const_string "*"))) 10160 (set_attr "mode" "<MODE>")]) 10161 10162;; Convert rotate to the rotatex pattern to avoid flags dependency. 10163(define_split 10164 [(set (match_operand:SWI48 0 "register_operand" "") 10165 (rotate:SWI48 (match_operand:SWI48 1 "nonimmediate_operand" "") 10166 (match_operand:QI 2 "immediate_operand" ""))) 10167 (clobber (reg:CC FLAGS_REG))] 10168 "TARGET_BMI2 && reload_completed" 10169 [(set (match_dup 0) 10170 (rotatert:SWI48 (match_dup 1) (match_dup 2)))] 10171{ 10172 operands[2] 10173 = GEN_INT (GET_MODE_BITSIZE (<MODE>mode) - INTVAL (operands[2])); 10174}) 10175 10176(define_split 10177 [(set (match_operand:SWI48 0 "register_operand" "") 10178 (rotatert:SWI48 (match_operand:SWI48 1 "nonimmediate_operand" "") 10179 (match_operand:QI 2 "immediate_operand" ""))) 10180 (clobber (reg:CC FLAGS_REG))] 10181 "TARGET_BMI2 && reload_completed" 10182 [(set (match_dup 0) 10183 (rotatert:SWI48 (match_dup 1) (match_dup 2)))]) 10184 10185(define_insn "*bmi2_rorxsi3_1_zext" 10186 [(set (match_operand:DI 0 "register_operand" "=r") 10187 (zero_extend:DI 10188 (rotatert:SI (match_operand:SI 1 "nonimmediate_operand" "rm") 10189 (match_operand:QI 2 "immediate_operand" "I"))))] 10190 "TARGET_64BIT && TARGET_BMI2" 10191 "rorx\t{%2, %1, %k0|%k0, %1, %2}" 10192 [(set_attr "type" "rotatex") 10193 (set_attr "mode" "SI")]) 10194 10195(define_insn "*<rotate_insn>si3_1_zext" 10196 [(set (match_operand:DI 0 "register_operand" "=r,r") 10197 (zero_extend:DI 10198 (any_rotate:SI (match_operand:SI 1 "nonimmediate_operand" "0,rm") 10199 (match_operand:QI 2 "nonmemory_operand" "cI,I")))) 10200 (clobber (reg:CC FLAGS_REG))] 10201 "TARGET_64BIT && ix86_binary_operator_ok (<CODE>, SImode, operands)" 10202{ 10203 switch (get_attr_type (insn)) 10204 { 10205 case TYPE_ROTATEX: 10206 return "#"; 10207 10208 default: 10209 if (operands[2] == const1_rtx 10210 && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun))) 10211 return "<rotate>{l}\t%k0"; 10212 else 10213 return "<rotate>{l}\t{%2, %k0|%k0, %2}"; 10214 } 10215} 10216 [(set_attr "isa" "*,bmi2") 10217 (set_attr "type" "rotate,rotatex") 10218 (set (attr "length_immediate") 10219 (if_then_else 10220 (and (eq_attr "type" "rotate") 10221 (and (match_operand 2 "const1_operand" "") 10222 (ior (match_test "TARGET_SHIFT1") 10223 (match_test "optimize_function_for_size_p (cfun)")))) 10224 (const_string "0") 10225 (const_string "*"))) 10226 (set_attr "mode" "SI")]) 10227 10228;; Convert rotate to the rotatex pattern to avoid flags dependency. 10229(define_split 10230 [(set (match_operand:DI 0 "register_operand" "") 10231 (zero_extend:DI 10232 (rotate:SI (match_operand:SI 1 "nonimmediate_operand" "") 10233 (match_operand:QI 2 "immediate_operand" "")))) 10234 (clobber (reg:CC FLAGS_REG))] 10235 "TARGET_64BIT && TARGET_BMI2 && reload_completed" 10236 [(set (match_dup 0) 10237 (zero_extend:DI (rotatert:SI (match_dup 1) (match_dup 2))))] 10238{ 10239 operands[2] 10240 = GEN_INT (GET_MODE_BITSIZE (SImode) - INTVAL (operands[2])); 10241}) 10242 10243(define_split 10244 [(set (match_operand:DI 0 "register_operand" "") 10245 (zero_extend:DI 10246 (rotatert:SI (match_operand:SI 1 "nonimmediate_operand" "") 10247 (match_operand:QI 2 "immediate_operand" "")))) 10248 (clobber (reg:CC FLAGS_REG))] 10249 "TARGET_64BIT && TARGET_BMI2 && reload_completed" 10250 [(set (match_dup 0) 10251 (zero_extend:DI (rotatert:SI (match_dup 1) (match_dup 2))))]) 10252 10253(define_insn "*<rotate_insn><mode>3_1" 10254 [(set (match_operand:SWI12 0 "nonimmediate_operand" "=<r>m") 10255 (any_rotate:SWI12 (match_operand:SWI12 1 "nonimmediate_operand" "0") 10256 (match_operand:QI 2 "nonmemory_operand" "c<S>"))) 10257 (clobber (reg:CC FLAGS_REG))] 10258 "ix86_binary_operator_ok (<CODE>, <MODE>mode, operands)" 10259{ 10260 if (operands[2] == const1_rtx 10261 && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun))) 10262 return "<rotate>{<imodesuffix>}\t%0"; 10263 else 10264 return "<rotate>{<imodesuffix>}\t{%2, %0|%0, %2}"; 10265} 10266 [(set_attr "type" "rotate") 10267 (set (attr "length_immediate") 10268 (if_then_else 10269 (and (match_operand 2 "const1_operand" "") 10270 (ior (match_test "TARGET_SHIFT1") 10271 (match_test "optimize_function_for_size_p (cfun)"))) 10272 (const_string "0") 10273 (const_string "*"))) 10274 (set_attr "mode" "<MODE>")]) 10275 10276(define_insn "*<rotate_insn>qi3_1_slp" 10277 [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm")) 10278 (any_rotate:QI (match_dup 0) 10279 (match_operand:QI 1 "nonmemory_operand" "cI"))) 10280 (clobber (reg:CC FLAGS_REG))] 10281 "(optimize_function_for_size_p (cfun) 10282 || !TARGET_PARTIAL_REG_STALL 10283 || (operands[1] == const1_rtx 10284 && TARGET_SHIFT1))" 10285{ 10286 if (operands[1] == const1_rtx 10287 && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun))) 10288 return "<rotate>{b}\t%0"; 10289 else 10290 return "<rotate>{b}\t{%1, %0|%0, %1}"; 10291} 10292 [(set_attr "type" "rotate1") 10293 (set (attr "length_immediate") 10294 (if_then_else 10295 (and (match_operand 1 "const1_operand" "") 10296 (ior (match_test "TARGET_SHIFT1") 10297 (match_test "optimize_function_for_size_p (cfun)"))) 10298 (const_string "0") 10299 (const_string "*"))) 10300 (set_attr "mode" "QI")]) 10301 10302(define_split 10303 [(set (match_operand:HI 0 "register_operand" "") 10304 (any_rotate:HI (match_dup 0) (const_int 8))) 10305 (clobber (reg:CC FLAGS_REG))] 10306 "reload_completed 10307 && (TARGET_USE_XCHGB || optimize_function_for_size_p (cfun))" 10308 [(parallel [(set (strict_low_part (match_dup 0)) 10309 (bswap:HI (match_dup 0))) 10310 (clobber (reg:CC FLAGS_REG))])]) 10311 10312;; Bit set / bit test instructions 10313 10314(define_expand "extv" 10315 [(set (match_operand:SI 0 "register_operand" "") 10316 (sign_extract:SI (match_operand:SI 1 "register_operand" "") 10317 (match_operand:SI 2 "const8_operand" "") 10318 (match_operand:SI 3 "const8_operand" "")))] 10319 "" 10320{ 10321 /* Handle extractions from %ah et al. */ 10322 if (INTVAL (operands[2]) != 8 || INTVAL (operands[3]) != 8) 10323 FAIL; 10324 10325 /* From mips.md: extract_bit_field doesn't verify that our source 10326 matches the predicate, so check it again here. */ 10327 if (! ext_register_operand (operands[1], VOIDmode)) 10328 FAIL; 10329}) 10330 10331(define_expand "extzv" 10332 [(set (match_operand:SI 0 "register_operand" "") 10333 (zero_extract:SI (match_operand 1 "ext_register_operand" "") 10334 (match_operand:SI 2 "const8_operand" "") 10335 (match_operand:SI 3 "const8_operand" "")))] 10336 "" 10337{ 10338 /* Handle extractions from %ah et al. */ 10339 if (INTVAL (operands[2]) != 8 || INTVAL (operands[3]) != 8) 10340 FAIL; 10341 10342 /* From mips.md: extract_bit_field doesn't verify that our source 10343 matches the predicate, so check it again here. */ 10344 if (! ext_register_operand (operands[1], VOIDmode)) 10345 FAIL; 10346}) 10347 10348(define_expand "insv" 10349 [(set (zero_extract (match_operand 0 "register_operand" "") 10350 (match_operand 1 "const_int_operand" "") 10351 (match_operand 2 "const_int_operand" "")) 10352 (match_operand 3 "register_operand" ""))] 10353 "" 10354{ 10355 rtx (*gen_mov_insv_1) (rtx, rtx); 10356 10357 if (ix86_expand_pinsr (operands)) 10358 DONE; 10359 10360 /* Handle insertions to %ah et al. */ 10361 if (INTVAL (operands[1]) != 8 || INTVAL (operands[2]) != 8) 10362 FAIL; 10363 10364 /* From mips.md: insert_bit_field doesn't verify that our source 10365 matches the predicate, so check it again here. */ 10366 if (! ext_register_operand (operands[0], VOIDmode)) 10367 FAIL; 10368 10369 gen_mov_insv_1 = (TARGET_64BIT 10370 ? gen_movdi_insv_1 : gen_movsi_insv_1); 10371 10372 emit_insn (gen_mov_insv_1 (operands[0], operands[3])); 10373 DONE; 10374}) 10375 10376;; %%% bts, btr, btc, bt. 10377;; In general these instructions are *slow* when applied to memory, 10378;; since they enforce atomic operation. When applied to registers, 10379;; it depends on the cpu implementation. They're never faster than 10380;; the corresponding and/ior/xor operations, so with 32-bit there's 10381;; no point. But in 64-bit, we can't hold the relevant immediates 10382;; within the instruction itself, so operating on bits in the high 10383;; 32-bits of a register becomes easier. 10384;; 10385;; These are slow on Nocona, but fast on Athlon64. We do require the use 10386;; of btrq and btcq for corner cases of post-reload expansion of absdf and 10387;; negdf respectively, so they can never be disabled entirely. 10388 10389(define_insn "*btsq" 10390 [(set (zero_extract:DI (match_operand:DI 0 "register_operand" "+r") 10391 (const_int 1) 10392 (match_operand:DI 1 "const_0_to_63_operand" "")) 10393 (const_int 1)) 10394 (clobber (reg:CC FLAGS_REG))] 10395 "TARGET_64BIT && (TARGET_USE_BT || reload_completed)" 10396 "bts{q}\t{%1, %0|%0, %1}" 10397 [(set_attr "type" "alu1") 10398 (set_attr "prefix_0f" "1") 10399 (set_attr "mode" "DI")]) 10400 10401(define_insn "*btrq" 10402 [(set (zero_extract:DI (match_operand:DI 0 "register_operand" "+r") 10403 (const_int 1) 10404 (match_operand:DI 1 "const_0_to_63_operand" "")) 10405 (const_int 0)) 10406 (clobber (reg:CC FLAGS_REG))] 10407 "TARGET_64BIT && (TARGET_USE_BT || reload_completed)" 10408 "btr{q}\t{%1, %0|%0, %1}" 10409 [(set_attr "type" "alu1") 10410 (set_attr "prefix_0f" "1") 10411 (set_attr "mode" "DI")]) 10412 10413(define_insn "*btcq" 10414 [(set (zero_extract:DI (match_operand:DI 0 "register_operand" "+r") 10415 (const_int 1) 10416 (match_operand:DI 1 "const_0_to_63_operand" "")) 10417 (not:DI (zero_extract:DI (match_dup 0) (const_int 1) (match_dup 1)))) 10418 (clobber (reg:CC FLAGS_REG))] 10419 "TARGET_64BIT && (TARGET_USE_BT || reload_completed)" 10420 "btc{q}\t{%1, %0|%0, %1}" 10421 [(set_attr "type" "alu1") 10422 (set_attr "prefix_0f" "1") 10423 (set_attr "mode" "DI")]) 10424 10425;; Allow Nocona to avoid these instructions if a register is available. 10426 10427(define_peephole2 10428 [(match_scratch:DI 2 "r") 10429 (parallel [(set (zero_extract:DI 10430 (match_operand:DI 0 "register_operand" "") 10431 (const_int 1) 10432 (match_operand:DI 1 "const_0_to_63_operand" "")) 10433 (const_int 1)) 10434 (clobber (reg:CC FLAGS_REG))])] 10435 "TARGET_64BIT && !TARGET_USE_BT" 10436 [(const_int 0)] 10437{ 10438 HOST_WIDE_INT i = INTVAL (operands[1]), hi, lo; 10439 rtx op1; 10440 10441 if (HOST_BITS_PER_WIDE_INT >= 64) 10442 lo = (HOST_WIDE_INT)1 << i, hi = 0; 10443 else if (i < HOST_BITS_PER_WIDE_INT) 10444 lo = (HOST_WIDE_INT)1 << i, hi = 0; 10445 else 10446 lo = 0, hi = (HOST_WIDE_INT)1 << (i - HOST_BITS_PER_WIDE_INT); 10447 10448 op1 = immed_double_const (lo, hi, DImode); 10449 if (i >= 31) 10450 { 10451 emit_move_insn (operands[2], op1); 10452 op1 = operands[2]; 10453 } 10454 10455 emit_insn (gen_iordi3 (operands[0], operands[0], op1)); 10456 DONE; 10457}) 10458 10459(define_peephole2 10460 [(match_scratch:DI 2 "r") 10461 (parallel [(set (zero_extract:DI 10462 (match_operand:DI 0 "register_operand" "") 10463 (const_int 1) 10464 (match_operand:DI 1 "const_0_to_63_operand" "")) 10465 (const_int 0)) 10466 (clobber (reg:CC FLAGS_REG))])] 10467 "TARGET_64BIT && !TARGET_USE_BT" 10468 [(const_int 0)] 10469{ 10470 HOST_WIDE_INT i = INTVAL (operands[1]), hi, lo; 10471 rtx op1; 10472 10473 if (HOST_BITS_PER_WIDE_INT >= 64) 10474 lo = (HOST_WIDE_INT)1 << i, hi = 0; 10475 else if (i < HOST_BITS_PER_WIDE_INT) 10476 lo = (HOST_WIDE_INT)1 << i, hi = 0; 10477 else 10478 lo = 0, hi = (HOST_WIDE_INT)1 << (i - HOST_BITS_PER_WIDE_INT); 10479 10480 op1 = immed_double_const (~lo, ~hi, DImode); 10481 if (i >= 32) 10482 { 10483 emit_move_insn (operands[2], op1); 10484 op1 = operands[2]; 10485 } 10486 10487 emit_insn (gen_anddi3 (operands[0], operands[0], op1)); 10488 DONE; 10489}) 10490 10491(define_peephole2 10492 [(match_scratch:DI 2 "r") 10493 (parallel [(set (zero_extract:DI 10494 (match_operand:DI 0 "register_operand" "") 10495 (const_int 1) 10496 (match_operand:DI 1 "const_0_to_63_operand" "")) 10497 (not:DI (zero_extract:DI 10498 (match_dup 0) (const_int 1) (match_dup 1)))) 10499 (clobber (reg:CC FLAGS_REG))])] 10500 "TARGET_64BIT && !TARGET_USE_BT" 10501 [(const_int 0)] 10502{ 10503 HOST_WIDE_INT i = INTVAL (operands[1]), hi, lo; 10504 rtx op1; 10505 10506 if (HOST_BITS_PER_WIDE_INT >= 64) 10507 lo = (HOST_WIDE_INT)1 << i, hi = 0; 10508 else if (i < HOST_BITS_PER_WIDE_INT) 10509 lo = (HOST_WIDE_INT)1 << i, hi = 0; 10510 else 10511 lo = 0, hi = (HOST_WIDE_INT)1 << (i - HOST_BITS_PER_WIDE_INT); 10512 10513 op1 = immed_double_const (lo, hi, DImode); 10514 if (i >= 31) 10515 { 10516 emit_move_insn (operands[2], op1); 10517 op1 = operands[2]; 10518 } 10519 10520 emit_insn (gen_xordi3 (operands[0], operands[0], op1)); 10521 DONE; 10522}) 10523 10524(define_insn "*bt<mode>" 10525 [(set (reg:CCC FLAGS_REG) 10526 (compare:CCC 10527 (zero_extract:SWI48 10528 (match_operand:SWI48 0 "register_operand" "r") 10529 (const_int 1) 10530 (match_operand:SWI48 1 "x86_64_nonmemory_operand" "rN")) 10531 (const_int 0)))] 10532 "TARGET_USE_BT || optimize_function_for_size_p (cfun)" 10533 "bt{<imodesuffix>}\t{%1, %0|%0, %1}" 10534 [(set_attr "type" "alu1") 10535 (set_attr "prefix_0f" "1") 10536 (set_attr "mode" "<MODE>")]) 10537 10538;; Store-flag instructions. 10539 10540;; For all sCOND expanders, also expand the compare or test insn that 10541;; generates cc0. Generate an equality comparison if `seq' or `sne'. 10542 10543(define_insn_and_split "*setcc_di_1" 10544 [(set (match_operand:DI 0 "register_operand" "=q") 10545 (match_operator:DI 1 "ix86_comparison_operator" 10546 [(reg FLAGS_REG) (const_int 0)]))] 10547 "TARGET_64BIT && !TARGET_PARTIAL_REG_STALL" 10548 "#" 10549 "&& reload_completed" 10550 [(set (match_dup 2) (match_dup 1)) 10551 (set (match_dup 0) (zero_extend:DI (match_dup 2)))] 10552{ 10553 PUT_MODE (operands[1], QImode); 10554 operands[2] = gen_lowpart (QImode, operands[0]); 10555}) 10556 10557(define_insn_and_split "*setcc_si_1_and" 10558 [(set (match_operand:SI 0 "register_operand" "=q") 10559 (match_operator:SI 1 "ix86_comparison_operator" 10560 [(reg FLAGS_REG) (const_int 0)])) 10561 (clobber (reg:CC FLAGS_REG))] 10562 "!TARGET_PARTIAL_REG_STALL 10563 && TARGET_ZERO_EXTEND_WITH_AND && optimize_function_for_speed_p (cfun)" 10564 "#" 10565 "&& reload_completed" 10566 [(set (match_dup 2) (match_dup 1)) 10567 (parallel [(set (match_dup 0) (zero_extend:SI (match_dup 2))) 10568 (clobber (reg:CC FLAGS_REG))])] 10569{ 10570 PUT_MODE (operands[1], QImode); 10571 operands[2] = gen_lowpart (QImode, operands[0]); 10572}) 10573 10574(define_insn_and_split "*setcc_si_1_movzbl" 10575 [(set (match_operand:SI 0 "register_operand" "=q") 10576 (match_operator:SI 1 "ix86_comparison_operator" 10577 [(reg FLAGS_REG) (const_int 0)]))] 10578 "!TARGET_PARTIAL_REG_STALL 10579 && (!TARGET_ZERO_EXTEND_WITH_AND || optimize_function_for_size_p (cfun))" 10580 "#" 10581 "&& reload_completed" 10582 [(set (match_dup 2) (match_dup 1)) 10583 (set (match_dup 0) (zero_extend:SI (match_dup 2)))] 10584{ 10585 PUT_MODE (operands[1], QImode); 10586 operands[2] = gen_lowpart (QImode, operands[0]); 10587}) 10588 10589(define_insn "*setcc_qi" 10590 [(set (match_operand:QI 0 "nonimmediate_operand" "=qm") 10591 (match_operator:QI 1 "ix86_comparison_operator" 10592 [(reg FLAGS_REG) (const_int 0)]))] 10593 "" 10594 "set%C1\t%0" 10595 [(set_attr "type" "setcc") 10596 (set_attr "mode" "QI")]) 10597 10598(define_insn "*setcc_qi_slp" 10599 [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm")) 10600 (match_operator:QI 1 "ix86_comparison_operator" 10601 [(reg FLAGS_REG) (const_int 0)]))] 10602 "" 10603 "set%C1\t%0" 10604 [(set_attr "type" "setcc") 10605 (set_attr "mode" "QI")]) 10606 10607;; In general it is not safe to assume too much about CCmode registers, 10608;; so simplify-rtx stops when it sees a second one. Under certain 10609;; conditions this is safe on x86, so help combine not create 10610;; 10611;; seta %al 10612;; testb %al, %al 10613;; sete %al 10614 10615(define_split 10616 [(set (match_operand:QI 0 "nonimmediate_operand" "") 10617 (ne:QI (match_operator 1 "ix86_comparison_operator" 10618 [(reg FLAGS_REG) (const_int 0)]) 10619 (const_int 0)))] 10620 "" 10621 [(set (match_dup 0) (match_dup 1))] 10622 "PUT_MODE (operands[1], QImode);") 10623 10624(define_split 10625 [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "")) 10626 (ne:QI (match_operator 1 "ix86_comparison_operator" 10627 [(reg FLAGS_REG) (const_int 0)]) 10628 (const_int 0)))] 10629 "" 10630 [(set (match_dup 0) (match_dup 1))] 10631 "PUT_MODE (operands[1], QImode);") 10632 10633(define_split 10634 [(set (match_operand:QI 0 "nonimmediate_operand" "") 10635 (eq:QI (match_operator 1 "ix86_comparison_operator" 10636 [(reg FLAGS_REG) (const_int 0)]) 10637 (const_int 0)))] 10638 "" 10639 [(set (match_dup 0) (match_dup 1))] 10640{ 10641 rtx new_op1 = copy_rtx (operands[1]); 10642 operands[1] = new_op1; 10643 PUT_MODE (new_op1, QImode); 10644 PUT_CODE (new_op1, ix86_reverse_condition (GET_CODE (new_op1), 10645 GET_MODE (XEXP (new_op1, 0)))); 10646 10647 /* Make sure that (a) the CCmode we have for the flags is strong 10648 enough for the reversed compare or (b) we have a valid FP compare. */ 10649 if (! ix86_comparison_operator (new_op1, VOIDmode)) 10650 FAIL; 10651}) 10652 10653(define_split 10654 [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "")) 10655 (eq:QI (match_operator 1 "ix86_comparison_operator" 10656 [(reg FLAGS_REG) (const_int 0)]) 10657 (const_int 0)))] 10658 "" 10659 [(set (match_dup 0) (match_dup 1))] 10660{ 10661 rtx new_op1 = copy_rtx (operands[1]); 10662 operands[1] = new_op1; 10663 PUT_MODE (new_op1, QImode); 10664 PUT_CODE (new_op1, ix86_reverse_condition (GET_CODE (new_op1), 10665 GET_MODE (XEXP (new_op1, 0)))); 10666 10667 /* Make sure that (a) the CCmode we have for the flags is strong 10668 enough for the reversed compare or (b) we have a valid FP compare. */ 10669 if (! ix86_comparison_operator (new_op1, VOIDmode)) 10670 FAIL; 10671}) 10672 10673;; The SSE store flag instructions saves 0 or 0xffffffff to the result. 10674;; subsequent logical operations are used to imitate conditional moves. 10675;; 0xffffffff is NaN, but not in normalized form, so we can't represent 10676;; it directly. 10677 10678(define_insn "setcc_<mode>_sse" 10679 [(set (match_operand:MODEF 0 "register_operand" "=x,x") 10680 (match_operator:MODEF 3 "sse_comparison_operator" 10681 [(match_operand:MODEF 1 "register_operand" "0,x") 10682 (match_operand:MODEF 2 "nonimmediate_operand" "xm,xm")]))] 10683 "SSE_FLOAT_MODE_P (<MODE>mode)" 10684 "@ 10685 cmp%D3<ssemodesuffix>\t{%2, %0|%0, %2} 10686 vcmp%D3<ssemodesuffix>\t{%2, %1, %0|%0, %1, %2}" 10687 [(set_attr "isa" "noavx,avx") 10688 (set_attr "type" "ssecmp") 10689 (set_attr "length_immediate" "1") 10690 (set_attr "prefix" "orig,vex") 10691 (set_attr "mode" "<MODE>")]) 10692 10693;; Basic conditional jump instructions. 10694;; We ignore the overflow flag for signed branch instructions. 10695 10696(define_insn "*jcc_1" 10697 [(set (pc) 10698 (if_then_else (match_operator 1 "ix86_comparison_operator" 10699 [(reg FLAGS_REG) (const_int 0)]) 10700 (label_ref (match_operand 0 "" "")) 10701 (pc)))] 10702 "" 10703 "%+j%C1\t%l0" 10704 [(set_attr "type" "ibr") 10705 (set_attr "modrm" "0") 10706 (set (attr "length") 10707 (if_then_else (and (ge (minus (match_dup 0) (pc)) 10708 (const_int -126)) 10709 (lt (minus (match_dup 0) (pc)) 10710 (const_int 128))) 10711 (const_int 2) 10712 (const_int 6)))]) 10713 10714(define_insn "*jcc_2" 10715 [(set (pc) 10716 (if_then_else (match_operator 1 "ix86_comparison_operator" 10717 [(reg FLAGS_REG) (const_int 0)]) 10718 (pc) 10719 (label_ref (match_operand 0 "" ""))))] 10720 "" 10721 "%+j%c1\t%l0" 10722 [(set_attr "type" "ibr") 10723 (set_attr "modrm" "0") 10724 (set (attr "length") 10725 (if_then_else (and (ge (minus (match_dup 0) (pc)) 10726 (const_int -126)) 10727 (lt (minus (match_dup 0) (pc)) 10728 (const_int 128))) 10729 (const_int 2) 10730 (const_int 6)))]) 10731 10732;; In general it is not safe to assume too much about CCmode registers, 10733;; so simplify-rtx stops when it sees a second one. Under certain 10734;; conditions this is safe on x86, so help combine not create 10735;; 10736;; seta %al 10737;; testb %al, %al 10738;; je Lfoo 10739 10740(define_split 10741 [(set (pc) 10742 (if_then_else (ne (match_operator 0 "ix86_comparison_operator" 10743 [(reg FLAGS_REG) (const_int 0)]) 10744 (const_int 0)) 10745 (label_ref (match_operand 1 "" "")) 10746 (pc)))] 10747 "" 10748 [(set (pc) 10749 (if_then_else (match_dup 0) 10750 (label_ref (match_dup 1)) 10751 (pc)))] 10752 "PUT_MODE (operands[0], VOIDmode);") 10753 10754(define_split 10755 [(set (pc) 10756 (if_then_else (eq (match_operator 0 "ix86_comparison_operator" 10757 [(reg FLAGS_REG) (const_int 0)]) 10758 (const_int 0)) 10759 (label_ref (match_operand 1 "" "")) 10760 (pc)))] 10761 "" 10762 [(set (pc) 10763 (if_then_else (match_dup 0) 10764 (label_ref (match_dup 1)) 10765 (pc)))] 10766{ 10767 rtx new_op0 = copy_rtx (operands[0]); 10768 operands[0] = new_op0; 10769 PUT_MODE (new_op0, VOIDmode); 10770 PUT_CODE (new_op0, ix86_reverse_condition (GET_CODE (new_op0), 10771 GET_MODE (XEXP (new_op0, 0)))); 10772 10773 /* Make sure that (a) the CCmode we have for the flags is strong 10774 enough for the reversed compare or (b) we have a valid FP compare. */ 10775 if (! ix86_comparison_operator (new_op0, VOIDmode)) 10776 FAIL; 10777}) 10778 10779;; zero_extend in SImode is correct also for DImode, since this is what combine 10780;; pass generates from shift insn with QImode operand. Actually, the mode 10781;; of operand 2 (bit offset operand) doesn't matter since bt insn takes 10782;; appropriate modulo of the bit offset value. 10783 10784(define_insn_and_split "*jcc_bt<mode>" 10785 [(set (pc) 10786 (if_then_else (match_operator 0 "bt_comparison_operator" 10787 [(zero_extract:SWI48 10788 (match_operand:SWI48 1 "register_operand" "r") 10789 (const_int 1) 10790 (zero_extend:SI 10791 (match_operand:QI 2 "register_operand" "r"))) 10792 (const_int 0)]) 10793 (label_ref (match_operand 3 "" "")) 10794 (pc))) 10795 (clobber (reg:CC FLAGS_REG))] 10796 "TARGET_USE_BT || optimize_function_for_size_p (cfun)" 10797 "#" 10798 "&& 1" 10799 [(set (reg:CCC FLAGS_REG) 10800 (compare:CCC 10801 (zero_extract:SWI48 10802 (match_dup 1) 10803 (const_int 1) 10804 (match_dup 2)) 10805 (const_int 0))) 10806 (set (pc) 10807 (if_then_else (match_op_dup 0 [(reg:CCC FLAGS_REG) (const_int 0)]) 10808 (label_ref (match_dup 3)) 10809 (pc)))] 10810{ 10811 operands[2] = simplify_gen_subreg (<MODE>mode, operands[2], QImode, 0); 10812 10813 PUT_CODE (operands[0], reverse_condition (GET_CODE (operands[0]))); 10814}) 10815 10816;; Avoid useless masking of bit offset operand. "and" in SImode is correct 10817;; also for DImode, this is what combine produces. 10818(define_insn_and_split "*jcc_bt<mode>_mask" 10819 [(set (pc) 10820 (if_then_else (match_operator 0 "bt_comparison_operator" 10821 [(zero_extract:SWI48 10822 (match_operand:SWI48 1 "register_operand" "r") 10823 (const_int 1) 10824 (and:SI 10825 (match_operand:SI 2 "register_operand" "r") 10826 (match_operand:SI 3 "const_int_operand" "n")))]) 10827 (label_ref (match_operand 4 "" "")) 10828 (pc))) 10829 (clobber (reg:CC FLAGS_REG))] 10830 "(TARGET_USE_BT || optimize_function_for_size_p (cfun)) 10831 && (INTVAL (operands[3]) & (GET_MODE_BITSIZE (<MODE>mode)-1)) 10832 == GET_MODE_BITSIZE (<MODE>mode)-1" 10833 "#" 10834 "&& 1" 10835 [(set (reg:CCC FLAGS_REG) 10836 (compare:CCC 10837 (zero_extract:SWI48 10838 (match_dup 1) 10839 (const_int 1) 10840 (match_dup 2)) 10841 (const_int 0))) 10842 (set (pc) 10843 (if_then_else (match_op_dup 0 [(reg:CCC FLAGS_REG) (const_int 0)]) 10844 (label_ref (match_dup 4)) 10845 (pc)))] 10846{ 10847 operands[2] = simplify_gen_subreg (<MODE>mode, operands[2], SImode, 0); 10848 10849 PUT_CODE (operands[0], reverse_condition (GET_CODE (operands[0]))); 10850}) 10851 10852(define_insn_and_split "*jcc_btsi_1" 10853 [(set (pc) 10854 (if_then_else (match_operator 0 "bt_comparison_operator" 10855 [(and:SI 10856 (lshiftrt:SI 10857 (match_operand:SI 1 "register_operand" "r") 10858 (match_operand:QI 2 "register_operand" "r")) 10859 (const_int 1)) 10860 (const_int 0)]) 10861 (label_ref (match_operand 3 "" "")) 10862 (pc))) 10863 (clobber (reg:CC FLAGS_REG))] 10864 "TARGET_USE_BT || optimize_function_for_size_p (cfun)" 10865 "#" 10866 "&& 1" 10867 [(set (reg:CCC FLAGS_REG) 10868 (compare:CCC 10869 (zero_extract:SI 10870 (match_dup 1) 10871 (const_int 1) 10872 (match_dup 2)) 10873 (const_int 0))) 10874 (set (pc) 10875 (if_then_else (match_op_dup 0 [(reg:CCC FLAGS_REG) (const_int 0)]) 10876 (label_ref (match_dup 3)) 10877 (pc)))] 10878{ 10879 operands[2] = simplify_gen_subreg (SImode, operands[2], QImode, 0); 10880 10881 PUT_CODE (operands[0], reverse_condition (GET_CODE (operands[0]))); 10882}) 10883 10884;; avoid useless masking of bit offset operand 10885(define_insn_and_split "*jcc_btsi_mask_1" 10886 [(set (pc) 10887 (if_then_else 10888 (match_operator 0 "bt_comparison_operator" 10889 [(and:SI 10890 (lshiftrt:SI 10891 (match_operand:SI 1 "register_operand" "r") 10892 (subreg:QI 10893 (and:SI 10894 (match_operand:SI 2 "register_operand" "r") 10895 (match_operand:SI 3 "const_int_operand" "n")) 0)) 10896 (const_int 1)) 10897 (const_int 0)]) 10898 (label_ref (match_operand 4 "" "")) 10899 (pc))) 10900 (clobber (reg:CC FLAGS_REG))] 10901 "(TARGET_USE_BT || optimize_function_for_size_p (cfun)) 10902 && (INTVAL (operands[3]) & 0x1f) == 0x1f" 10903 "#" 10904 "&& 1" 10905 [(set (reg:CCC FLAGS_REG) 10906 (compare:CCC 10907 (zero_extract:SI 10908 (match_dup 1) 10909 (const_int 1) 10910 (match_dup 2)) 10911 (const_int 0))) 10912 (set (pc) 10913 (if_then_else (match_op_dup 0 [(reg:CCC FLAGS_REG) (const_int 0)]) 10914 (label_ref (match_dup 4)) 10915 (pc)))] 10916 "PUT_CODE (operands[0], reverse_condition (GET_CODE (operands[0])));") 10917 10918;; Define combination compare-and-branch fp compare instructions to help 10919;; combine. 10920 10921(define_insn "*fp_jcc_1_387" 10922 [(set (pc) 10923 (if_then_else (match_operator 0 "ix86_fp_comparison_operator" 10924 [(match_operand 1 "register_operand" "f") 10925 (match_operand 2 "nonimmediate_operand" "fm")]) 10926 (label_ref (match_operand 3 "" "")) 10927 (pc))) 10928 (clobber (reg:CCFP FPSR_REG)) 10929 (clobber (reg:CCFP FLAGS_REG)) 10930 (clobber (match_scratch:HI 4 "=a"))] 10931 "TARGET_80387 10932 && (GET_MODE (operands[1]) == SFmode || GET_MODE (operands[1]) == DFmode) 10933 && GET_MODE (operands[1]) == GET_MODE (operands[2]) 10934 && SELECT_CC_MODE (GET_CODE (operands[0]), 10935 operands[1], operands[2]) == CCFPmode 10936 && !TARGET_CMOVE" 10937 "#") 10938 10939(define_insn "*fp_jcc_1r_387" 10940 [(set (pc) 10941 (if_then_else (match_operator 0 "ix86_fp_comparison_operator" 10942 [(match_operand 1 "register_operand" "f") 10943 (match_operand 2 "nonimmediate_operand" "fm")]) 10944 (pc) 10945 (label_ref (match_operand 3 "" "")))) 10946 (clobber (reg:CCFP FPSR_REG)) 10947 (clobber (reg:CCFP FLAGS_REG)) 10948 (clobber (match_scratch:HI 4 "=a"))] 10949 "TARGET_80387 10950 && (GET_MODE (operands[1]) == SFmode || GET_MODE (operands[1]) == DFmode) 10951 && GET_MODE (operands[1]) == GET_MODE (operands[2]) 10952 && SELECT_CC_MODE (GET_CODE (operands[0]), 10953 operands[1], operands[2]) == CCFPmode 10954 && !TARGET_CMOVE" 10955 "#") 10956 10957(define_insn "*fp_jcc_2_387" 10958 [(set (pc) 10959 (if_then_else (match_operator 0 "ix86_fp_comparison_operator" 10960 [(match_operand 1 "register_operand" "f") 10961 (match_operand 2 "register_operand" "f")]) 10962 (label_ref (match_operand 3 "" "")) 10963 (pc))) 10964 (clobber (reg:CCFP FPSR_REG)) 10965 (clobber (reg:CCFP FLAGS_REG)) 10966 (clobber (match_scratch:HI 4 "=a"))] 10967 "X87_FLOAT_MODE_P (GET_MODE (operands[1])) 10968 && GET_MODE (operands[1]) == GET_MODE (operands[2]) 10969 && !TARGET_CMOVE" 10970 "#") 10971 10972(define_insn "*fp_jcc_2r_387" 10973 [(set (pc) 10974 (if_then_else (match_operator 0 "ix86_fp_comparison_operator" 10975 [(match_operand 1 "register_operand" "f") 10976 (match_operand 2 "register_operand" "f")]) 10977 (pc) 10978 (label_ref (match_operand 3 "" "")))) 10979 (clobber (reg:CCFP FPSR_REG)) 10980 (clobber (reg:CCFP FLAGS_REG)) 10981 (clobber (match_scratch:HI 4 "=a"))] 10982 "X87_FLOAT_MODE_P (GET_MODE (operands[1])) 10983 && GET_MODE (operands[1]) == GET_MODE (operands[2]) 10984 && !TARGET_CMOVE" 10985 "#") 10986 10987(define_insn "*fp_jcc_3_387" 10988 [(set (pc) 10989 (if_then_else (match_operator 0 "ix86_fp_comparison_operator" 10990 [(match_operand 1 "register_operand" "f") 10991 (match_operand 2 "const0_operand" "")]) 10992 (label_ref (match_operand 3 "" "")) 10993 (pc))) 10994 (clobber (reg:CCFP FPSR_REG)) 10995 (clobber (reg:CCFP FLAGS_REG)) 10996 (clobber (match_scratch:HI 4 "=a"))] 10997 "X87_FLOAT_MODE_P (GET_MODE (operands[1])) 10998 && GET_MODE (operands[1]) == GET_MODE (operands[2]) 10999 && SELECT_CC_MODE (GET_CODE (operands[0]), 11000 operands[1], operands[2]) == CCFPmode 11001 && !TARGET_CMOVE" 11002 "#") 11003 11004(define_split 11005 [(set (pc) 11006 (if_then_else (match_operator 0 "ix86_fp_comparison_operator" 11007 [(match_operand 1 "register_operand" "") 11008 (match_operand 2 "nonimmediate_operand" "")]) 11009 (match_operand 3 "" "") 11010 (match_operand 4 "" ""))) 11011 (clobber (reg:CCFP FPSR_REG)) 11012 (clobber (reg:CCFP FLAGS_REG))] 11013 "reload_completed" 11014 [(const_int 0)] 11015{ 11016 ix86_split_fp_branch (GET_CODE (operands[0]), operands[1], operands[2], 11017 operands[3], operands[4], NULL_RTX, NULL_RTX); 11018 DONE; 11019}) 11020 11021(define_split 11022 [(set (pc) 11023 (if_then_else (match_operator 0 "ix86_fp_comparison_operator" 11024 [(match_operand 1 "register_operand" "") 11025 (match_operand 2 "general_operand" "")]) 11026 (match_operand 3 "" "") 11027 (match_operand 4 "" ""))) 11028 (clobber (reg:CCFP FPSR_REG)) 11029 (clobber (reg:CCFP FLAGS_REG)) 11030 (clobber (match_scratch:HI 5 "=a"))] 11031 "reload_completed" 11032 [(const_int 0)] 11033{ 11034 ix86_split_fp_branch (GET_CODE (operands[0]), operands[1], operands[2], 11035 operands[3], operands[4], operands[5], NULL_RTX); 11036 DONE; 11037}) 11038 11039;; The order of operands in *fp_jcc_4_387 is forced by combine in 11040;; simplify_comparison () function. Float operator is treated as RTX_OBJ 11041;; with a precedence over other operators and is always put in the first 11042;; place. Swap condition and operands to match ficom instruction. 11043 11044(define_insn "*fp_jcc_4_<mode>_387" 11045 [(set (pc) 11046 (if_then_else 11047 (match_operator 0 "ix86_swapped_fp_comparison_operator" 11048 [(match_operator 1 "float_operator" 11049 [(match_operand:SWI24 2 "nonimmediate_operand" "m,?r")]) 11050 (match_operand 3 "register_operand" "f,f")]) 11051 (label_ref (match_operand 4 "" "")) 11052 (pc))) 11053 (clobber (reg:CCFP FPSR_REG)) 11054 (clobber (reg:CCFP FLAGS_REG)) 11055 (clobber (match_scratch:HI 5 "=a,a"))] 11056 "X87_FLOAT_MODE_P (GET_MODE (operands[3])) 11057 && (TARGET_USE_<MODE>MODE_FIOP || optimize_function_for_size_p (cfun)) 11058 && GET_MODE (operands[1]) == GET_MODE (operands[3]) 11059 && ix86_fp_compare_mode (swap_condition (GET_CODE (operands[0]))) == CCFPmode 11060 && !TARGET_CMOVE" 11061 "#") 11062 11063(define_split 11064 [(set (pc) 11065 (if_then_else 11066 (match_operator 0 "ix86_swapped_fp_comparison_operator" 11067 [(match_operator 1 "float_operator" 11068 [(match_operand:SWI24 2 "memory_operand" "")]) 11069 (match_operand 3 "register_operand" "")]) 11070 (match_operand 4 "" "") 11071 (match_operand 5 "" ""))) 11072 (clobber (reg:CCFP FPSR_REG)) 11073 (clobber (reg:CCFP FLAGS_REG)) 11074 (clobber (match_scratch:HI 6 "=a"))] 11075 "reload_completed" 11076 [(const_int 0)] 11077{ 11078 operands[7] = gen_rtx_FLOAT (GET_MODE (operands[1]), operands[2]); 11079 11080 ix86_split_fp_branch (swap_condition (GET_CODE (operands[0])), 11081 operands[3], operands[7], 11082 operands[4], operands[5], operands[6], NULL_RTX); 11083 DONE; 11084}) 11085 11086;; %%% Kill this when reload knows how to do it. 11087(define_split 11088 [(set (pc) 11089 (if_then_else 11090 (match_operator 0 "ix86_swapped_fp_comparison_operator" 11091 [(match_operator 1 "float_operator" 11092 [(match_operand:SWI24 2 "register_operand" "")]) 11093 (match_operand 3 "register_operand" "")]) 11094 (match_operand 4 "" "") 11095 (match_operand 5 "" ""))) 11096 (clobber (reg:CCFP FPSR_REG)) 11097 (clobber (reg:CCFP FLAGS_REG)) 11098 (clobber (match_scratch:HI 6 "=a"))] 11099 "reload_completed" 11100 [(const_int 0)] 11101{ 11102 operands[7] = ix86_force_to_memory (GET_MODE (operands[2]), operands[2]); 11103 operands[7] = gen_rtx_FLOAT (GET_MODE (operands[1]), operands[7]); 11104 11105 ix86_split_fp_branch (swap_condition (GET_CODE (operands[0])), 11106 operands[3], operands[7], 11107 operands[4], operands[5], operands[6], operands[2]); 11108 DONE; 11109}) 11110 11111;; Unconditional and other jump instructions 11112 11113(define_insn "jump" 11114 [(set (pc) 11115 (label_ref (match_operand 0 "" "")))] 11116 "" 11117 "jmp\t%l0" 11118 [(set_attr "type" "ibr") 11119 (set (attr "length") 11120 (if_then_else (and (ge (minus (match_dup 0) (pc)) 11121 (const_int -126)) 11122 (lt (minus (match_dup 0) (pc)) 11123 (const_int 128))) 11124 (const_int 2) 11125 (const_int 5))) 11126 (set_attr "modrm" "0")]) 11127 11128(define_expand "indirect_jump" 11129 [(set (pc) (match_operand 0 "indirect_branch_operand" ""))]) 11130 11131(define_insn "*indirect_jump" 11132 [(set (pc) (match_operand:P 0 "indirect_branch_operand" "rw"))] 11133 "" 11134 "jmp\t%A0" 11135 [(set_attr "type" "ibr") 11136 (set_attr "length_immediate" "0")]) 11137 11138(define_expand "tablejump" 11139 [(parallel [(set (pc) (match_operand 0 "indirect_branch_operand" "")) 11140 (use (label_ref (match_operand 1 "" "")))])] 11141 "" 11142{ 11143 /* In PIC mode, the table entries are stored GOT (32-bit) or PC (64-bit) 11144 relative. Convert the relative address to an absolute address. */ 11145 if (flag_pic) 11146 { 11147 rtx op0, op1; 11148 enum rtx_code code; 11149 11150 /* We can't use @GOTOFF for text labels on VxWorks; 11151 see gotoff_operand. */ 11152 if (TARGET_64BIT || TARGET_VXWORKS_RTP) 11153 { 11154 code = PLUS; 11155 op0 = operands[0]; 11156 op1 = gen_rtx_LABEL_REF (Pmode, operands[1]); 11157 } 11158 else if (TARGET_MACHO || HAVE_AS_GOTOFF_IN_DATA) 11159 { 11160 code = PLUS; 11161 op0 = operands[0]; 11162 op1 = pic_offset_table_rtx; 11163 } 11164 else 11165 { 11166 code = MINUS; 11167 op0 = pic_offset_table_rtx; 11168 op1 = operands[0]; 11169 } 11170 11171 operands[0] = expand_simple_binop (Pmode, code, op0, op1, NULL_RTX, 0, 11172 OPTAB_DIRECT); 11173 } 11174 else if (TARGET_X32) 11175 operands[0] = convert_memory_address (Pmode, operands[0]); 11176}) 11177 11178(define_insn "*tablejump_1" 11179 [(set (pc) (match_operand:P 0 "indirect_branch_operand" "rw")) 11180 (use (label_ref (match_operand 1 "" "")))] 11181 "" 11182 "jmp\t%A0" 11183 [(set_attr "type" "ibr") 11184 (set_attr "length_immediate" "0")]) 11185 11186;; Convert setcc + movzbl to xor + setcc if operands don't overlap. 11187 11188(define_peephole2 11189 [(set (reg FLAGS_REG) (match_operand 0 "" "")) 11190 (set (match_operand:QI 1 "register_operand" "") 11191 (match_operator:QI 2 "ix86_comparison_operator" 11192 [(reg FLAGS_REG) (const_int 0)])) 11193 (set (match_operand 3 "q_regs_operand" "") 11194 (zero_extend (match_dup 1)))] 11195 "(peep2_reg_dead_p (3, operands[1]) 11196 || operands_match_p (operands[1], operands[3])) 11197 && ! reg_overlap_mentioned_p (operands[3], operands[0])" 11198 [(set (match_dup 4) (match_dup 0)) 11199 (set (strict_low_part (match_dup 5)) 11200 (match_dup 2))] 11201{ 11202 operands[4] = gen_rtx_REG (GET_MODE (operands[0]), FLAGS_REG); 11203 operands[5] = gen_lowpart (QImode, operands[3]); 11204 ix86_expand_clear (operands[3]); 11205}) 11206 11207;; Similar, but match zero_extendhisi2_and, which adds a clobber. 11208 11209(define_peephole2 11210 [(set (reg FLAGS_REG) (match_operand 0 "" "")) 11211 (set (match_operand:QI 1 "register_operand" "") 11212 (match_operator:QI 2 "ix86_comparison_operator" 11213 [(reg FLAGS_REG) (const_int 0)])) 11214 (parallel [(set (match_operand 3 "q_regs_operand" "") 11215 (zero_extend (match_dup 1))) 11216 (clobber (reg:CC FLAGS_REG))])] 11217 "(peep2_reg_dead_p (3, operands[1]) 11218 || operands_match_p (operands[1], operands[3])) 11219 && ! reg_overlap_mentioned_p (operands[3], operands[0])" 11220 [(set (match_dup 4) (match_dup 0)) 11221 (set (strict_low_part (match_dup 5)) 11222 (match_dup 2))] 11223{ 11224 operands[4] = gen_rtx_REG (GET_MODE (operands[0]), FLAGS_REG); 11225 operands[5] = gen_lowpart (QImode, operands[3]); 11226 ix86_expand_clear (operands[3]); 11227}) 11228 11229;; Call instructions. 11230 11231;; The predicates normally associated with named expanders are not properly 11232;; checked for calls. This is a bug in the generic code, but it isn't that 11233;; easy to fix. Ignore it for now and be prepared to fix things up. 11234 11235;; P6 processors will jump to the address after the decrement when %esp 11236;; is used as a call operand, so they will execute return address as a code. 11237;; See Pentium Pro errata 70, Pentium 2 errata A33 and Pentium 3 errata E17. 11238 11239;; Register constraint for call instruction. 11240(define_mode_attr c [(SI "l") (DI "r")]) 11241 11242;; Call subroutine returning no value. 11243 11244(define_expand "call" 11245 [(call (match_operand:QI 0 "" "") 11246 (match_operand 1 "" "")) 11247 (use (match_operand 2 "" ""))] 11248 "" 11249{ 11250 ix86_expand_call (NULL, operands[0], operands[1], 11251 operands[2], NULL, false); 11252 DONE; 11253}) 11254 11255(define_expand "sibcall" 11256 [(call (match_operand:QI 0 "" "") 11257 (match_operand 1 "" "")) 11258 (use (match_operand 2 "" ""))] 11259 "" 11260{ 11261 ix86_expand_call (NULL, operands[0], operands[1], 11262 operands[2], NULL, true); 11263 DONE; 11264}) 11265 11266(define_insn_and_split "*call_vzeroupper" 11267 [(call (mem:QI (match_operand:P 0 "call_insn_operand" "<c>zw")) 11268 (match_operand 1 "" "")) 11269 (unspec [(match_operand 2 "const_int_operand" "")] 11270 UNSPEC_CALL_NEEDS_VZEROUPPER)] 11271 "TARGET_VZEROUPPER && !SIBLING_CALL_P (insn)" 11272 "#" 11273 "&& reload_completed" 11274 [(const_int 0)] 11275 "ix86_split_call_vzeroupper (curr_insn, operands[2]); DONE;" 11276 [(set_attr "type" "call")]) 11277 11278(define_insn "*call" 11279 [(call (mem:QI (match_operand:P 0 "call_insn_operand" "<c>zw")) 11280 (match_operand 1 "" ""))] 11281 "!SIBLING_CALL_P (insn)" 11282 "* return ix86_output_call_insn (insn, operands[0]);" 11283 [(set_attr "type" "call")]) 11284 11285(define_insn_and_split "*call_rex64_ms_sysv_vzeroupper" 11286 [(call (mem:QI (match_operand:DI 0 "call_insn_operand" "rzw")) 11287 (match_operand 1 "" "")) 11288 (unspec [(const_int 0)] UNSPEC_MS_TO_SYSV_CALL) 11289 (clobber (reg:TI XMM6_REG)) 11290 (clobber (reg:TI XMM7_REG)) 11291 (clobber (reg:TI XMM8_REG)) 11292 (clobber (reg:TI XMM9_REG)) 11293 (clobber (reg:TI XMM10_REG)) 11294 (clobber (reg:TI XMM11_REG)) 11295 (clobber (reg:TI XMM12_REG)) 11296 (clobber (reg:TI XMM13_REG)) 11297 (clobber (reg:TI XMM14_REG)) 11298 (clobber (reg:TI XMM15_REG)) 11299 (clobber (reg:DI SI_REG)) 11300 (clobber (reg:DI DI_REG)) 11301 (unspec [(match_operand 2 "const_int_operand" "")] 11302 UNSPEC_CALL_NEEDS_VZEROUPPER)] 11303 "TARGET_VZEROUPPER && TARGET_64BIT && !SIBLING_CALL_P (insn)" 11304 "#" 11305 "&& reload_completed" 11306 [(const_int 0)] 11307 "ix86_split_call_vzeroupper (curr_insn, operands[2]); DONE;" 11308 [(set_attr "type" "call")]) 11309 11310(define_insn "*call_rex64_ms_sysv" 11311 [(call (mem:QI (match_operand:DI 0 "call_insn_operand" "rzw")) 11312 (match_operand 1 "" "")) 11313 (unspec [(const_int 0)] UNSPEC_MS_TO_SYSV_CALL) 11314 (clobber (reg:TI XMM6_REG)) 11315 (clobber (reg:TI XMM7_REG)) 11316 (clobber (reg:TI XMM8_REG)) 11317 (clobber (reg:TI XMM9_REG)) 11318 (clobber (reg:TI XMM10_REG)) 11319 (clobber (reg:TI XMM11_REG)) 11320 (clobber (reg:TI XMM12_REG)) 11321 (clobber (reg:TI XMM13_REG)) 11322 (clobber (reg:TI XMM14_REG)) 11323 (clobber (reg:TI XMM15_REG)) 11324 (clobber (reg:DI SI_REG)) 11325 (clobber (reg:DI DI_REG))] 11326 "TARGET_64BIT && !SIBLING_CALL_P (insn)" 11327 "* return ix86_output_call_insn (insn, operands[0]);" 11328 [(set_attr "type" "call")]) 11329 11330(define_insn_and_split "*sibcall_vzeroupper" 11331 [(call (mem:QI (match_operand:P 0 "sibcall_insn_operand" "Uz")) 11332 (match_operand 1 "" "")) 11333 (unspec [(match_operand 2 "const_int_operand" "")] 11334 UNSPEC_CALL_NEEDS_VZEROUPPER)] 11335 "TARGET_VZEROUPPER && SIBLING_CALL_P (insn)" 11336 "#" 11337 "&& reload_completed" 11338 [(const_int 0)] 11339 "ix86_split_call_vzeroupper (curr_insn, operands[2]); DONE;" 11340 [(set_attr "type" "call")]) 11341 11342(define_insn "*sibcall" 11343 [(call (mem:QI (match_operand:P 0 "sibcall_insn_operand" "Uz")) 11344 (match_operand 1 "" ""))] 11345 "SIBLING_CALL_P (insn)" 11346 "* return ix86_output_call_insn (insn, operands[0]);" 11347 [(set_attr "type" "call")]) 11348 11349(define_expand "call_pop" 11350 [(parallel [(call (match_operand:QI 0 "" "") 11351 (match_operand:SI 1 "" "")) 11352 (set (reg:SI SP_REG) 11353 (plus:SI (reg:SI SP_REG) 11354 (match_operand:SI 3 "" "")))])] 11355 "!TARGET_64BIT" 11356{ 11357 ix86_expand_call (NULL, operands[0], operands[1], 11358 operands[2], operands[3], false); 11359 DONE; 11360}) 11361 11362(define_insn_and_split "*call_pop_vzeroupper" 11363 [(call (mem:QI (match_operand:SI 0 "call_insn_operand" "lzm")) 11364 (match_operand:SI 1 "" "")) 11365 (set (reg:SI SP_REG) 11366 (plus:SI (reg:SI SP_REG) 11367 (match_operand:SI 2 "immediate_operand" "i"))) 11368 (unspec [(match_operand 3 "const_int_operand" "")] 11369 UNSPEC_CALL_NEEDS_VZEROUPPER)] 11370 "TARGET_VZEROUPPER && !TARGET_64BIT && !SIBLING_CALL_P (insn)" 11371 "#" 11372 "&& reload_completed" 11373 [(const_int 0)] 11374 "ix86_split_call_vzeroupper (curr_insn, operands[3]); DONE;" 11375 [(set_attr "type" "call")]) 11376 11377(define_insn "*call_pop" 11378 [(call (mem:QI (match_operand:SI 0 "call_insn_operand" "lzm")) 11379 (match_operand 1 "" "")) 11380 (set (reg:SI SP_REG) 11381 (plus:SI (reg:SI SP_REG) 11382 (match_operand:SI 2 "immediate_operand" "i")))] 11383 "!TARGET_64BIT && !SIBLING_CALL_P (insn)" 11384 "* return ix86_output_call_insn (insn, operands[0]);" 11385 [(set_attr "type" "call")]) 11386 11387(define_insn_and_split "*sibcall_pop_vzeroupper" 11388 [(call (mem:QI (match_operand:SI 0 "sibcall_insn_operand" "Uz")) 11389 (match_operand 1 "" "")) 11390 (set (reg:SI SP_REG) 11391 (plus:SI (reg:SI SP_REG) 11392 (match_operand:SI 2 "immediate_operand" "i"))) 11393 (unspec [(match_operand 3 "const_int_operand" "")] 11394 UNSPEC_CALL_NEEDS_VZEROUPPER)] 11395 "TARGET_VZEROUPPER && !TARGET_64BIT && SIBLING_CALL_P (insn)" 11396 "#" 11397 "&& reload_completed" 11398 [(const_int 0)] 11399 "ix86_split_call_vzeroupper (curr_insn, operands[3]); DONE;" 11400 [(set_attr "type" "call")]) 11401 11402(define_insn "*sibcall_pop" 11403 [(call (mem:QI (match_operand:SI 0 "sibcall_insn_operand" "Uz")) 11404 (match_operand 1 "" "")) 11405 (set (reg:SI SP_REG) 11406 (plus:SI (reg:SI SP_REG) 11407 (match_operand:SI 2 "immediate_operand" "i")))] 11408 "!TARGET_64BIT && SIBLING_CALL_P (insn)" 11409 "* return ix86_output_call_insn (insn, operands[0]);" 11410 [(set_attr "type" "call")]) 11411 11412;; Call subroutine, returning value in operand 0 11413 11414(define_expand "call_value" 11415 [(set (match_operand 0 "" "") 11416 (call (match_operand:QI 1 "" "") 11417 (match_operand 2 "" ""))) 11418 (use (match_operand 3 "" ""))] 11419 "" 11420{ 11421 ix86_expand_call (operands[0], operands[1], operands[2], 11422 operands[3], NULL, false); 11423 DONE; 11424}) 11425 11426(define_expand "sibcall_value" 11427 [(set (match_operand 0 "" "") 11428 (call (match_operand:QI 1 "" "") 11429 (match_operand 2 "" ""))) 11430 (use (match_operand 3 "" ""))] 11431 "" 11432{ 11433 ix86_expand_call (operands[0], operands[1], operands[2], 11434 operands[3], NULL, true); 11435 DONE; 11436}) 11437 11438(define_insn_and_split "*call_value_vzeroupper" 11439 [(set (match_operand 0 "" "") 11440 (call (mem:QI (match_operand:P 1 "call_insn_operand" "<c>zw")) 11441 (match_operand 2 "" ""))) 11442 (unspec [(match_operand 3 "const_int_operand" "")] 11443 UNSPEC_CALL_NEEDS_VZEROUPPER)] 11444 "TARGET_VZEROUPPER && !SIBLING_CALL_P (insn)" 11445 "#" 11446 "&& reload_completed" 11447 [(const_int 0)] 11448 "ix86_split_call_vzeroupper (curr_insn, operands[3]); DONE;" 11449 [(set_attr "type" "callv")]) 11450 11451(define_insn "*call_value" 11452 [(set (match_operand 0 "" "") 11453 (call (mem:QI (match_operand:P 1 "call_insn_operand" "<c>zw")) 11454 (match_operand 2 "" "")))] 11455 "!SIBLING_CALL_P (insn)" 11456 "* return ix86_output_call_insn (insn, operands[1]);" 11457 [(set_attr "type" "callv")]) 11458 11459(define_insn_and_split "*sibcall_value_vzeroupper" 11460 [(set (match_operand 0 "" "") 11461 (call (mem:QI (match_operand:P 1 "sibcall_insn_operand" "Uz")) 11462 (match_operand 2 "" ""))) 11463 (unspec [(match_operand 3 "const_int_operand" "")] 11464 UNSPEC_CALL_NEEDS_VZEROUPPER)] 11465 "TARGET_VZEROUPPER && SIBLING_CALL_P (insn)" 11466 "#" 11467 "&& reload_completed" 11468 [(const_int 0)] 11469 "ix86_split_call_vzeroupper (curr_insn, operands[3]); DONE;" 11470 [(set_attr "type" "callv")]) 11471 11472(define_insn "*sibcall_value" 11473 [(set (match_operand 0 "" "") 11474 (call (mem:QI (match_operand:P 1 "sibcall_insn_operand" "Uz")) 11475 (match_operand 2 "" "")))] 11476 "SIBLING_CALL_P (insn)" 11477 "* return ix86_output_call_insn (insn, operands[1]);" 11478 [(set_attr "type" "callv")]) 11479 11480(define_insn_and_split "*call_value_rex64_ms_sysv_vzeroupper" 11481 [(set (match_operand 0 "" "") 11482 (call (mem:QI (match_operand:DI 1 "call_insn_operand" "rzw")) 11483 (match_operand 2 "" ""))) 11484 (unspec [(const_int 0)] UNSPEC_MS_TO_SYSV_CALL) 11485 (clobber (reg:TI XMM6_REG)) 11486 (clobber (reg:TI XMM7_REG)) 11487 (clobber (reg:TI XMM8_REG)) 11488 (clobber (reg:TI XMM9_REG)) 11489 (clobber (reg:TI XMM10_REG)) 11490 (clobber (reg:TI XMM11_REG)) 11491 (clobber (reg:TI XMM12_REG)) 11492 (clobber (reg:TI XMM13_REG)) 11493 (clobber (reg:TI XMM14_REG)) 11494 (clobber (reg:TI XMM15_REG)) 11495 (clobber (reg:DI SI_REG)) 11496 (clobber (reg:DI DI_REG)) 11497 (unspec [(match_operand 3 "const_int_operand" "")] 11498 UNSPEC_CALL_NEEDS_VZEROUPPER)] 11499 "TARGET_VZEROUPPER && TARGET_64BIT && !SIBLING_CALL_P (insn)" 11500 "#" 11501 "&& reload_completed" 11502 [(const_int 0)] 11503 "ix86_split_call_vzeroupper (curr_insn, operands[3]); DONE;" 11504 [(set_attr "type" "callv")]) 11505 11506(define_insn "*call_value_rex64_ms_sysv" 11507 [(set (match_operand 0 "" "") 11508 (call (mem:QI (match_operand:DI 1 "call_insn_operand" "rzw")) 11509 (match_operand 2 "" ""))) 11510 (unspec [(const_int 0)] UNSPEC_MS_TO_SYSV_CALL) 11511 (clobber (reg:TI XMM6_REG)) 11512 (clobber (reg:TI XMM7_REG)) 11513 (clobber (reg:TI XMM8_REG)) 11514 (clobber (reg:TI XMM9_REG)) 11515 (clobber (reg:TI XMM10_REG)) 11516 (clobber (reg:TI XMM11_REG)) 11517 (clobber (reg:TI XMM12_REG)) 11518 (clobber (reg:TI XMM13_REG)) 11519 (clobber (reg:TI XMM14_REG)) 11520 (clobber (reg:TI XMM15_REG)) 11521 (clobber (reg:DI SI_REG)) 11522 (clobber (reg:DI DI_REG))] 11523 "TARGET_64BIT && !SIBLING_CALL_P (insn)" 11524 "* return ix86_output_call_insn (insn, operands[1]);" 11525 [(set_attr "type" "callv")]) 11526 11527(define_expand "call_value_pop" 11528 [(parallel [(set (match_operand 0 "" "") 11529 (call (match_operand:QI 1 "" "") 11530 (match_operand:SI 2 "" ""))) 11531 (set (reg:SI SP_REG) 11532 (plus:SI (reg:SI SP_REG) 11533 (match_operand:SI 4 "" "")))])] 11534 "!TARGET_64BIT" 11535{ 11536 ix86_expand_call (operands[0], operands[1], operands[2], 11537 operands[3], operands[4], false); 11538 DONE; 11539}) 11540 11541(define_insn_and_split "*call_value_pop_vzeroupper" 11542 [(set (match_operand 0 "" "") 11543 (call (mem:QI (match_operand:SI 1 "call_insn_operand" "lzm")) 11544 (match_operand 2 "" ""))) 11545 (set (reg:SI SP_REG) 11546 (plus:SI (reg:SI SP_REG) 11547 (match_operand:SI 3 "immediate_operand" "i"))) 11548 (unspec [(match_operand 4 "const_int_operand" "")] 11549 UNSPEC_CALL_NEEDS_VZEROUPPER)] 11550 "TARGET_VZEROUPPER && !TARGET_64BIT && !SIBLING_CALL_P (insn)" 11551 "#" 11552 "&& reload_completed" 11553 [(const_int 0)] 11554 "ix86_split_call_vzeroupper (curr_insn, operands[4]); DONE;" 11555 [(set_attr "type" "callv")]) 11556 11557(define_insn "*call_value_pop" 11558 [(set (match_operand 0 "" "") 11559 (call (mem:QI (match_operand:SI 1 "call_insn_operand" "lzm")) 11560 (match_operand 2 "" ""))) 11561 (set (reg:SI SP_REG) 11562 (plus:SI (reg:SI SP_REG) 11563 (match_operand:SI 3 "immediate_operand" "i")))] 11564 "!TARGET_64BIT && !SIBLING_CALL_P (insn)" 11565 "* return ix86_output_call_insn (insn, operands[1]);" 11566 [(set_attr "type" "callv")]) 11567 11568(define_insn_and_split "*sibcall_value_pop_vzeroupper" 11569 [(set (match_operand 0 "" "") 11570 (call (mem:QI (match_operand:SI 1 "sibcall_insn_operand" "Uz")) 11571 (match_operand 2 "" ""))) 11572 (set (reg:SI SP_REG) 11573 (plus:SI (reg:SI SP_REG) 11574 (match_operand:SI 3 "immediate_operand" "i"))) 11575 (unspec [(match_operand 4 "const_int_operand" "")] 11576 UNSPEC_CALL_NEEDS_VZEROUPPER)] 11577 "TARGET_VZEROUPPER && !TARGET_64BIT && SIBLING_CALL_P (insn)" 11578 "#" 11579 "&& reload_completed" 11580 [(const_int 0)] 11581 "ix86_split_call_vzeroupper (curr_insn, operands[4]); DONE;" 11582 [(set_attr "type" "callv")]) 11583 11584(define_insn "*sibcall_value_pop" 11585 [(set (match_operand 0 "" "") 11586 (call (mem:QI (match_operand:SI 1 "sibcall_insn_operand" "Uz")) 11587 (match_operand 2 "" ""))) 11588 (set (reg:SI SP_REG) 11589 (plus:SI (reg:SI SP_REG) 11590 (match_operand:SI 3 "immediate_operand" "i")))] 11591 "!TARGET_64BIT && SIBLING_CALL_P (insn)" 11592 "* return ix86_output_call_insn (insn, operands[1]);" 11593 [(set_attr "type" "callv")]) 11594 11595;; Call subroutine returning any type. 11596 11597(define_expand "untyped_call" 11598 [(parallel [(call (match_operand 0 "" "") 11599 (const_int 0)) 11600 (match_operand 1 "" "") 11601 (match_operand 2 "" "")])] 11602 "" 11603{ 11604 int i; 11605 11606 /* In order to give reg-stack an easier job in validating two 11607 coprocessor registers as containing a possible return value, 11608 simply pretend the untyped call returns a complex long double 11609 value. 11610 11611 We can't use SSE_REGPARM_MAX here since callee is unprototyped 11612 and should have the default ABI. */ 11613 11614 ix86_expand_call ((TARGET_FLOAT_RETURNS_IN_80387 11615 ? gen_rtx_REG (XCmode, FIRST_FLOAT_REG) : NULL), 11616 operands[0], const0_rtx, 11617 GEN_INT ((TARGET_64BIT 11618 ? (ix86_abi == SYSV_ABI 11619 ? X86_64_SSE_REGPARM_MAX 11620 : X86_64_MS_SSE_REGPARM_MAX) 11621 : X86_32_SSE_REGPARM_MAX) 11622 - 1), 11623 NULL, false); 11624 11625 for (i = 0; i < XVECLEN (operands[2], 0); i++) 11626 { 11627 rtx set = XVECEXP (operands[2], 0, i); 11628 emit_move_insn (SET_DEST (set), SET_SRC (set)); 11629 } 11630 11631 /* The optimizer does not know that the call sets the function value 11632 registers we stored in the result block. We avoid problems by 11633 claiming that all hard registers are used and clobbered at this 11634 point. */ 11635 emit_insn (gen_blockage ()); 11636 11637 DONE; 11638}) 11639 11640;; Prologue and epilogue instructions 11641 11642;; UNSPEC_VOLATILE is considered to use and clobber all hard registers and 11643;; all of memory. This blocks insns from being moved across this point. 11644 11645(define_insn "blockage" 11646 [(unspec_volatile [(const_int 0)] UNSPECV_BLOCKAGE)] 11647 "" 11648 "" 11649 [(set_attr "length" "0")]) 11650 11651;; Do not schedule instructions accessing memory across this point. 11652 11653(define_expand "memory_blockage" 11654 [(set (match_dup 0) 11655 (unspec:BLK [(match_dup 0)] UNSPEC_MEMORY_BLOCKAGE))] 11656 "" 11657{ 11658 operands[0] = gen_rtx_MEM (BLKmode, gen_rtx_SCRATCH (Pmode)); 11659 MEM_VOLATILE_P (operands[0]) = 1; 11660}) 11661 11662(define_insn "*memory_blockage" 11663 [(set (match_operand:BLK 0 "" "") 11664 (unspec:BLK [(match_dup 0)] UNSPEC_MEMORY_BLOCKAGE))] 11665 "" 11666 "" 11667 [(set_attr "length" "0")]) 11668 11669;; As USE insns aren't meaningful after reload, this is used instead 11670;; to prevent deleting instructions setting registers for PIC code 11671(define_insn "prologue_use" 11672 [(unspec_volatile [(match_operand 0 "" "")] UNSPECV_PROLOGUE_USE)] 11673 "" 11674 "" 11675 [(set_attr "length" "0")]) 11676 11677;; Insn emitted into the body of a function to return from a function. 11678;; This is only done if the function's epilogue is known to be simple. 11679;; See comments for ix86_can_use_return_insn_p in i386.c. 11680 11681(define_expand "return" 11682 [(simple_return)] 11683 "ix86_can_use_return_insn_p ()" 11684{ 11685 ix86_maybe_emit_epilogue_vzeroupper (); 11686 if (crtl->args.pops_args) 11687 { 11688 rtx popc = GEN_INT (crtl->args.pops_args); 11689 emit_jump_insn (gen_simple_return_pop_internal (popc)); 11690 DONE; 11691 } 11692}) 11693 11694;; We need to disable this for TARGET_SEH, as otherwise 11695;; shrink-wrapped prologue gets enabled too. This might exceed 11696;; the maximum size of prologue in unwind information. 11697 11698(define_expand "simple_return" 11699 [(simple_return)] 11700 "!TARGET_SEH" 11701{ 11702 ix86_maybe_emit_epilogue_vzeroupper (); 11703 if (crtl->args.pops_args) 11704 { 11705 rtx popc = GEN_INT (crtl->args.pops_args); 11706 emit_jump_insn (gen_simple_return_pop_internal (popc)); 11707 DONE; 11708 } 11709}) 11710 11711(define_insn "simple_return_internal" 11712 [(simple_return)] 11713 "reload_completed" 11714 "ret" 11715 [(set_attr "length" "1") 11716 (set_attr "atom_unit" "jeu") 11717 (set_attr "length_immediate" "0") 11718 (set_attr "modrm" "0")]) 11719 11720;; Used by x86_machine_dependent_reorg to avoid penalty on single byte RET 11721;; instruction Athlon and K8 have. 11722 11723(define_insn "simple_return_internal_long" 11724 [(simple_return) 11725 (unspec [(const_int 0)] UNSPEC_REP)] 11726 "reload_completed" 11727 "rep\;ret" 11728 [(set_attr "length" "2") 11729 (set_attr "atom_unit" "jeu") 11730 (set_attr "length_immediate" "0") 11731 (set_attr "prefix_rep" "1") 11732 (set_attr "modrm" "0")]) 11733 11734(define_insn "simple_return_pop_internal" 11735 [(simple_return) 11736 (use (match_operand:SI 0 "const_int_operand" ""))] 11737 "reload_completed" 11738 "ret\t%0" 11739 [(set_attr "length" "3") 11740 (set_attr "atom_unit" "jeu") 11741 (set_attr "length_immediate" "2") 11742 (set_attr "modrm" "0")]) 11743 11744(define_insn "simple_return_indirect_internal" 11745 [(simple_return) 11746 (use (match_operand:SI 0 "register_operand" "r"))] 11747 "reload_completed" 11748 "jmp\t%A0" 11749 [(set_attr "type" "ibr") 11750 (set_attr "length_immediate" "0")]) 11751 11752(define_insn "nop" 11753 [(const_int 0)] 11754 "" 11755 "nop" 11756 [(set_attr "length" "1") 11757 (set_attr "length_immediate" "0") 11758 (set_attr "modrm" "0")]) 11759 11760;; Generate nops. Operand 0 is the number of nops, up to 8. 11761(define_insn "nops" 11762 [(unspec_volatile [(match_operand 0 "const_int_operand" "")] 11763 UNSPECV_NOPS)] 11764 "reload_completed" 11765{ 11766 int num = INTVAL (operands[0]); 11767 11768 gcc_assert (num >= 1 && num <= 8); 11769 11770 while (num--) 11771 fputs ("\tnop\n", asm_out_file); 11772 11773 return ""; 11774} 11775 [(set (attr "length") (symbol_ref "INTVAL (operands[0])")) 11776 (set_attr "length_immediate" "0") 11777 (set_attr "modrm" "0")]) 11778 11779;; Pad to 16-byte boundary, max skip in op0. Used to avoid 11780;; branch prediction penalty for the third jump in a 16-byte 11781;; block on K8. 11782 11783(define_insn "pad" 11784 [(unspec_volatile [(match_operand 0 "" "")] UNSPECV_ALIGN)] 11785 "" 11786{ 11787#ifdef ASM_OUTPUT_MAX_SKIP_PAD 11788 ASM_OUTPUT_MAX_SKIP_PAD (asm_out_file, 4, (int)INTVAL (operands[0])); 11789#else 11790 /* It is tempting to use ASM_OUTPUT_ALIGN here, but we don't want to do that. 11791 The align insn is used to avoid 3 jump instructions in the row to improve 11792 branch prediction and the benefits hardly outweigh the cost of extra 8 11793 nops on the average inserted by full alignment pseudo operation. */ 11794#endif 11795 return ""; 11796} 11797 [(set_attr "length" "16")]) 11798 11799(define_expand "prologue" 11800 [(const_int 0)] 11801 "" 11802 "ix86_expand_prologue (); DONE;") 11803 11804(define_insn "set_got" 11805 [(set (match_operand:SI 0 "register_operand" "=r") 11806 (unspec:SI [(const_int 0)] UNSPEC_SET_GOT)) 11807 (clobber (reg:CC FLAGS_REG))] 11808 "!TARGET_64BIT" 11809 "* return output_set_got (operands[0], NULL_RTX);" 11810 [(set_attr "type" "multi") 11811 (set_attr "length" "12")]) 11812 11813(define_insn "set_got_labelled" 11814 [(set (match_operand:SI 0 "register_operand" "=r") 11815 (unspec:SI [(label_ref (match_operand 1 "" ""))] 11816 UNSPEC_SET_GOT)) 11817 (clobber (reg:CC FLAGS_REG))] 11818 "!TARGET_64BIT" 11819 "* return output_set_got (operands[0], operands[1]);" 11820 [(set_attr "type" "multi") 11821 (set_attr "length" "12")]) 11822 11823(define_insn "set_got_rex64" 11824 [(set (match_operand:DI 0 "register_operand" "=r") 11825 (unspec:DI [(const_int 0)] UNSPEC_SET_GOT))] 11826 "TARGET_64BIT" 11827 "lea{q}\t{_GLOBAL_OFFSET_TABLE_(%%rip), %0|%0, _GLOBAL_OFFSET_TABLE_[rip]}" 11828 [(set_attr "type" "lea") 11829 (set_attr "length_address" "4") 11830 (set_attr "mode" "DI")]) 11831 11832(define_insn "set_rip_rex64" 11833 [(set (match_operand:DI 0 "register_operand" "=r") 11834 (unspec:DI [(label_ref (match_operand 1 "" ""))] UNSPEC_SET_RIP))] 11835 "TARGET_64BIT" 11836 "lea{q}\t{%l1(%%rip), %0|%0, %l1[rip]}" 11837 [(set_attr "type" "lea") 11838 (set_attr "length_address" "4") 11839 (set_attr "mode" "DI")]) 11840 11841(define_insn "set_got_offset_rex64" 11842 [(set (match_operand:DI 0 "register_operand" "=r") 11843 (unspec:DI 11844 [(label_ref (match_operand 1 "" ""))] 11845 UNSPEC_SET_GOT_OFFSET))] 11846 "TARGET_LP64" 11847 "movabs{q}\t{$_GLOBAL_OFFSET_TABLE_-%l1, %0|%0, OFFSET FLAT:_GLOBAL_OFFSET_TABLE_-%l1}" 11848 [(set_attr "type" "imov") 11849 (set_attr "length_immediate" "0") 11850 (set_attr "length_address" "8") 11851 (set_attr "mode" "DI")]) 11852 11853(define_expand "epilogue" 11854 [(const_int 0)] 11855 "" 11856 "ix86_expand_epilogue (1); DONE;") 11857 11858(define_expand "sibcall_epilogue" 11859 [(const_int 0)] 11860 "" 11861 "ix86_expand_epilogue (0); DONE;") 11862 11863(define_expand "eh_return" 11864 [(use (match_operand 0 "register_operand" ""))] 11865 "" 11866{ 11867 rtx tmp, sa = EH_RETURN_STACKADJ_RTX, ra = operands[0]; 11868 11869 /* Tricky bit: we write the address of the handler to which we will 11870 be returning into someone else's stack frame, one word below the 11871 stack address we wish to restore. */ 11872 tmp = gen_rtx_PLUS (Pmode, arg_pointer_rtx, sa); 11873 tmp = plus_constant (tmp, -UNITS_PER_WORD); 11874 tmp = gen_rtx_MEM (Pmode, tmp); 11875 emit_move_insn (tmp, ra); 11876 11877 emit_jump_insn (gen_eh_return_internal ()); 11878 emit_barrier (); 11879 DONE; 11880}) 11881 11882(define_insn_and_split "eh_return_internal" 11883 [(eh_return)] 11884 "" 11885 "#" 11886 "epilogue_completed" 11887 [(const_int 0)] 11888 "ix86_expand_epilogue (2); DONE;") 11889 11890(define_insn "leave" 11891 [(set (reg:SI SP_REG) (plus:SI (reg:SI BP_REG) (const_int 4))) 11892 (set (reg:SI BP_REG) (mem:SI (reg:SI BP_REG))) 11893 (clobber (mem:BLK (scratch)))] 11894 "!TARGET_64BIT" 11895 "leave" 11896 [(set_attr "type" "leave")]) 11897 11898(define_insn "leave_rex64" 11899 [(set (reg:DI SP_REG) (plus:DI (reg:DI BP_REG) (const_int 8))) 11900 (set (reg:DI BP_REG) (mem:DI (reg:DI BP_REG))) 11901 (clobber (mem:BLK (scratch)))] 11902 "TARGET_64BIT" 11903 "leave" 11904 [(set_attr "type" "leave")]) 11905 11906;; Handle -fsplit-stack. 11907 11908(define_expand "split_stack_prologue" 11909 [(const_int 0)] 11910 "" 11911{ 11912 ix86_expand_split_stack_prologue (); 11913 DONE; 11914}) 11915 11916;; In order to support the call/return predictor, we use a return 11917;; instruction which the middle-end doesn't see. 11918(define_insn "split_stack_return" 11919 [(unspec_volatile [(match_operand:SI 0 "const_int_operand" "")] 11920 UNSPECV_SPLIT_STACK_RETURN)] 11921 "" 11922{ 11923 if (operands[0] == const0_rtx) 11924 return "ret"; 11925 else 11926 return "ret\t%0"; 11927} 11928 [(set_attr "atom_unit" "jeu") 11929 (set_attr "modrm" "0") 11930 (set (attr "length") 11931 (if_then_else (match_operand:SI 0 "const0_operand" "") 11932 (const_int 1) 11933 (const_int 3))) 11934 (set (attr "length_immediate") 11935 (if_then_else (match_operand:SI 0 "const0_operand" "") 11936 (const_int 0) 11937 (const_int 2)))]) 11938 11939;; If there are operand 0 bytes available on the stack, jump to 11940;; operand 1. 11941 11942(define_expand "split_stack_space_check" 11943 [(set (pc) (if_then_else 11944 (ltu (minus (reg SP_REG) 11945 (match_operand 0 "register_operand" "")) 11946 (unspec [(const_int 0)] UNSPEC_STACK_CHECK)) 11947 (label_ref (match_operand 1 "" "")) 11948 (pc)))] 11949 "" 11950{ 11951 rtx reg, size, limit; 11952 11953 reg = gen_reg_rtx (Pmode); 11954 size = force_reg (Pmode, operands[0]); 11955 emit_insn (gen_sub3_insn (reg, stack_pointer_rtx, size)); 11956 limit = gen_rtx_UNSPEC (Pmode, gen_rtvec (1, const0_rtx), 11957 UNSPEC_STACK_CHECK); 11958 limit = gen_rtx_MEM (Pmode, gen_rtx_CONST (Pmode, limit)); 11959 ix86_expand_branch (GEU, reg, limit, operands[1]); 11960 11961 DONE; 11962}) 11963 11964;; Bit manipulation instructions. 11965 11966(define_expand "ffs<mode>2" 11967 [(set (match_dup 2) (const_int -1)) 11968 (parallel [(set (reg:CCZ FLAGS_REG) 11969 (compare:CCZ 11970 (match_operand:SWI48 1 "nonimmediate_operand" "") 11971 (const_int 0))) 11972 (set (match_operand:SWI48 0 "register_operand" "") 11973 (ctz:SWI48 (match_dup 1)))]) 11974 (set (match_dup 0) (if_then_else:SWI48 11975 (eq (reg:CCZ FLAGS_REG) (const_int 0)) 11976 (match_dup 2) 11977 (match_dup 0))) 11978 (parallel [(set (match_dup 0) (plus:SWI48 (match_dup 0) (const_int 1))) 11979 (clobber (reg:CC FLAGS_REG))])] 11980 "" 11981{ 11982 if (<MODE>mode == SImode && !TARGET_CMOVE) 11983 { 11984 emit_insn (gen_ffssi2_no_cmove (operands[0], operands [1])); 11985 DONE; 11986 } 11987 operands[2] = gen_reg_rtx (<MODE>mode); 11988}) 11989 11990(define_insn_and_split "ffssi2_no_cmove" 11991 [(set (match_operand:SI 0 "register_operand" "=r") 11992 (ffs:SI (match_operand:SI 1 "nonimmediate_operand" "rm"))) 11993 (clobber (match_scratch:SI 2 "=&q")) 11994 (clobber (reg:CC FLAGS_REG))] 11995 "!TARGET_CMOVE" 11996 "#" 11997 "&& reload_completed" 11998 [(parallel [(set (reg:CCZ FLAGS_REG) 11999 (compare:CCZ (match_dup 1) (const_int 0))) 12000 (set (match_dup 0) (ctz:SI (match_dup 1)))]) 12001 (set (strict_low_part (match_dup 3)) 12002 (eq:QI (reg:CCZ FLAGS_REG) (const_int 0))) 12003 (parallel [(set (match_dup 2) (neg:SI (match_dup 2))) 12004 (clobber (reg:CC FLAGS_REG))]) 12005 (parallel [(set (match_dup 0) (ior:SI (match_dup 0) (match_dup 2))) 12006 (clobber (reg:CC FLAGS_REG))]) 12007 (parallel [(set (match_dup 0) (plus:SI (match_dup 0) (const_int 1))) 12008 (clobber (reg:CC FLAGS_REG))])] 12009{ 12010 operands[3] = gen_lowpart (QImode, operands[2]); 12011 ix86_expand_clear (operands[2]); 12012}) 12013 12014(define_insn "*ffs<mode>_1" 12015 [(set (reg:CCZ FLAGS_REG) 12016 (compare:CCZ (match_operand:SWI48 1 "nonimmediate_operand" "rm") 12017 (const_int 0))) 12018 (set (match_operand:SWI48 0 "register_operand" "=r") 12019 (ctz:SWI48 (match_dup 1)))] 12020 "" 12021 "bsf{<imodesuffix>}\t{%1, %0|%0, %1}" 12022 [(set_attr "type" "alu1") 12023 (set_attr "prefix_0f" "1") 12024 (set_attr "mode" "<MODE>")]) 12025 12026(define_insn "ctz<mode>2" 12027 [(set (match_operand:SWI248 0 "register_operand" "=r") 12028 (ctz:SWI248 (match_operand:SWI248 1 "nonimmediate_operand" "rm"))) 12029 (clobber (reg:CC FLAGS_REG))] 12030 "" 12031{ 12032 if (TARGET_BMI) 12033 return "tzcnt{<imodesuffix>}\t{%1, %0|%0, %1}"; 12034 else 12035 return "bsf{<imodesuffix>}\t{%1, %0|%0, %1}"; 12036} 12037 [(set_attr "type" "alu1") 12038 (set_attr "prefix_0f" "1") 12039 (set (attr "prefix_rep") (symbol_ref "TARGET_BMI")) 12040 (set_attr "mode" "<MODE>")]) 12041 12042(define_expand "clz<mode>2" 12043 [(parallel 12044 [(set (match_operand:SWI248 0 "register_operand" "") 12045 (minus:SWI248 12046 (match_dup 2) 12047 (clz:SWI248 (match_operand:SWI248 1 "nonimmediate_operand" "")))) 12048 (clobber (reg:CC FLAGS_REG))]) 12049 (parallel 12050 [(set (match_dup 0) (xor:SWI248 (match_dup 0) (match_dup 2))) 12051 (clobber (reg:CC FLAGS_REG))])] 12052 "" 12053{ 12054 if (TARGET_LZCNT) 12055 { 12056 emit_insn (gen_clz<mode>2_lzcnt (operands[0], operands[1])); 12057 DONE; 12058 } 12059 operands[2] = GEN_INT (GET_MODE_BITSIZE (<MODE>mode)-1); 12060}) 12061 12062(define_insn "clz<mode>2_lzcnt" 12063 [(set (match_operand:SWI248 0 "register_operand" "=r") 12064 (clz:SWI248 (match_operand:SWI248 1 "nonimmediate_operand" "rm"))) 12065 (clobber (reg:CC FLAGS_REG))] 12066 "TARGET_LZCNT" 12067 "lzcnt{<imodesuffix>}\t{%1, %0|%0, %1}" 12068 [(set_attr "prefix_rep" "1") 12069 (set_attr "type" "bitmanip") 12070 (set_attr "mode" "<MODE>")]) 12071 12072;; BMI instructions. 12073(define_insn "*bmi_andn_<mode>" 12074 [(set (match_operand:SWI48 0 "register_operand" "=r") 12075 (and:SWI48 12076 (not:SWI48 12077 (match_operand:SWI48 1 "register_operand" "r")) 12078 (match_operand:SWI48 2 "nonimmediate_operand" "rm"))) 12079 (clobber (reg:CC FLAGS_REG))] 12080 "TARGET_BMI" 12081 "andn\t{%2, %1, %0|%0, %1, %2}" 12082 [(set_attr "type" "bitmanip") 12083 (set_attr "mode" "<MODE>")]) 12084 12085(define_insn "bmi_bextr_<mode>" 12086 [(set (match_operand:SWI48 0 "register_operand" "=r") 12087 (unspec:SWI48 [(match_operand:SWI48 1 "register_operand" "r") 12088 (match_operand:SWI48 2 "nonimmediate_operand" "rm")] 12089 UNSPEC_BEXTR)) 12090 (clobber (reg:CC FLAGS_REG))] 12091 "TARGET_BMI" 12092 "bextr\t{%2, %1, %0|%0, %1, %2}" 12093 [(set_attr "type" "bitmanip") 12094 (set_attr "mode" "<MODE>")]) 12095 12096(define_insn "*bmi_blsi_<mode>" 12097 [(set (match_operand:SWI48 0 "register_operand" "=r") 12098 (and:SWI48 12099 (neg:SWI48 12100 (match_operand:SWI48 1 "nonimmediate_operand" "rm")) 12101 (match_dup 1))) 12102 (clobber (reg:CC FLAGS_REG))] 12103 "TARGET_BMI" 12104 "blsi\t{%1, %0|%0, %1}" 12105 [(set_attr "type" "bitmanip") 12106 (set_attr "mode" "<MODE>")]) 12107 12108(define_insn "*bmi_blsmsk_<mode>" 12109 [(set (match_operand:SWI48 0 "register_operand" "=r") 12110 (xor:SWI48 12111 (plus:SWI48 12112 (match_operand:SWI48 1 "nonimmediate_operand" "rm") 12113 (const_int -1)) 12114 (match_dup 1))) 12115 (clobber (reg:CC FLAGS_REG))] 12116 "TARGET_BMI" 12117 "blsmsk\t{%1, %0|%0, %1}" 12118 [(set_attr "type" "bitmanip") 12119 (set_attr "mode" "<MODE>")]) 12120 12121(define_insn "*bmi_blsr_<mode>" 12122 [(set (match_operand:SWI48 0 "register_operand" "=r") 12123 (and:SWI48 12124 (plus:SWI48 12125 (match_operand:SWI48 1 "nonimmediate_operand" "rm") 12126 (const_int -1)) 12127 (match_dup 1))) 12128 (clobber (reg:CC FLAGS_REG))] 12129 "TARGET_BMI" 12130 "blsr\t{%1, %0|%0, %1}" 12131 [(set_attr "type" "bitmanip") 12132 (set_attr "mode" "<MODE>")]) 12133 12134;; BMI2 instructions. 12135(define_insn "bmi2_bzhi_<mode>3" 12136 [(set (match_operand:SWI48 0 "register_operand" "=r") 12137 (and:SWI48 (match_operand:SWI48 1 "register_operand" "r") 12138 (lshiftrt:SWI48 (const_int -1) 12139 (match_operand:SWI48 2 "nonimmediate_operand" "rm")))) 12140 (clobber (reg:CC FLAGS_REG))] 12141 "TARGET_BMI2" 12142 "bzhi\t{%2, %1, %0|%0, %1, %2}" 12143 [(set_attr "type" "bitmanip") 12144 (set_attr "prefix" "vex") 12145 (set_attr "mode" "<MODE>")]) 12146 12147(define_insn "bmi2_pdep_<mode>3" 12148 [(set (match_operand:SWI48 0 "register_operand" "=r") 12149 (unspec:SWI48 [(match_operand:SWI48 1 "register_operand" "r") 12150 (match_operand:SWI48 2 "nonimmediate_operand" "rm")] 12151 UNSPEC_PDEP))] 12152 "TARGET_BMI2" 12153 "pdep\t{%2, %1, %0|%0, %1, %2}" 12154 [(set_attr "type" "bitmanip") 12155 (set_attr "prefix" "vex") 12156 (set_attr "mode" "<MODE>")]) 12157 12158(define_insn "bmi2_pext_<mode>3" 12159 [(set (match_operand:SWI48 0 "register_operand" "=r") 12160 (unspec:SWI48 [(match_operand:SWI48 1 "register_operand" "r") 12161 (match_operand:SWI48 2 "nonimmediate_operand" "rm")] 12162 UNSPEC_PEXT))] 12163 "TARGET_BMI2" 12164 "pext\t{%2, %1, %0|%0, %1, %2}" 12165 [(set_attr "type" "bitmanip") 12166 (set_attr "prefix" "vex") 12167 (set_attr "mode" "<MODE>")]) 12168 12169;; TBM instructions. 12170(define_insn "tbm_bextri_<mode>" 12171 [(set (match_operand:SWI48 0 "register_operand" "=r") 12172 (zero_extract:SWI48 12173 (match_operand:SWI48 1 "nonimmediate_operand" "rm") 12174 (match_operand:SWI48 2 "const_0_to_255_operand" "n") 12175 (match_operand:SWI48 3 "const_0_to_255_operand" "n"))) 12176 (clobber (reg:CC FLAGS_REG))] 12177 "TARGET_TBM" 12178{ 12179 operands[2] = GEN_INT (INTVAL (operands[2]) << 8 | INTVAL (operands[3])); 12180 return "bextr\t{%2, %1, %0|%0, %1, %2}"; 12181} 12182 [(set_attr "type" "bitmanip") 12183 (set_attr "mode" "<MODE>")]) 12184 12185(define_insn "*tbm_blcfill_<mode>" 12186 [(set (match_operand:SWI48 0 "register_operand" "=r") 12187 (and:SWI48 12188 (plus:SWI48 12189 (match_operand:SWI48 1 "nonimmediate_operand" "rm") 12190 (const_int 1)) 12191 (match_dup 1))) 12192 (clobber (reg:CC FLAGS_REG))] 12193 "TARGET_TBM" 12194 "blcfill\t{%1, %0|%0, %1}" 12195 [(set_attr "type" "bitmanip") 12196 (set_attr "mode" "<MODE>")]) 12197 12198(define_insn "*tbm_blci_<mode>" 12199 [(set (match_operand:SWI48 0 "register_operand" "=r") 12200 (ior:SWI48 12201 (not:SWI48 12202 (plus:SWI48 12203 (match_operand:SWI48 1 "nonimmediate_operand" "rm") 12204 (const_int 1))) 12205 (match_dup 1))) 12206 (clobber (reg:CC FLAGS_REG))] 12207 "TARGET_TBM" 12208 "blci\t{%1, %0|%0, %1}" 12209 [(set_attr "type" "bitmanip") 12210 (set_attr "mode" "<MODE>")]) 12211 12212(define_insn "*tbm_blcic_<mode>" 12213 [(set (match_operand:SWI48 0 "register_operand" "=r") 12214 (and:SWI48 12215 (plus:SWI48 12216 (match_operand:SWI48 1 "nonimmediate_operand" "rm") 12217 (const_int 1)) 12218 (not:SWI48 12219 (match_dup 1)))) 12220 (clobber (reg:CC FLAGS_REG))] 12221 "TARGET_TBM" 12222 "blcic\t{%1, %0|%0, %1}" 12223 [(set_attr "type" "bitmanip") 12224 (set_attr "mode" "<MODE>")]) 12225 12226(define_insn "*tbm_blcmsk_<mode>" 12227 [(set (match_operand:SWI48 0 "register_operand" "=r") 12228 (xor:SWI48 12229 (plus:SWI48 12230 (match_operand:SWI48 1 "nonimmediate_operand" "rm") 12231 (const_int 1)) 12232 (match_dup 1))) 12233 (clobber (reg:CC FLAGS_REG))] 12234 "TARGET_TBM" 12235 "blcmsk\t{%1, %0|%0, %1}" 12236 [(set_attr "type" "bitmanip") 12237 (set_attr "mode" "<MODE>")]) 12238 12239(define_insn "*tbm_blcs_<mode>" 12240 [(set (match_operand:SWI48 0 "register_operand" "=r") 12241 (ior:SWI48 12242 (plus:SWI48 12243 (match_operand:SWI48 1 "nonimmediate_operand" "rm") 12244 (const_int 1)) 12245 (match_dup 1))) 12246 (clobber (reg:CC FLAGS_REG))] 12247 "TARGET_TBM" 12248 "blcs\t{%1, %0|%0, %1}" 12249 [(set_attr "type" "bitmanip") 12250 (set_attr "mode" "<MODE>")]) 12251 12252(define_insn "*tbm_blsfill_<mode>" 12253 [(set (match_operand:SWI48 0 "register_operand" "=r") 12254 (ior:SWI48 12255 (plus:SWI48 12256 (match_operand:SWI48 1 "nonimmediate_operand" "rm") 12257 (const_int -1)) 12258 (match_dup 1))) 12259 (clobber (reg:CC FLAGS_REG))] 12260 "TARGET_TBM" 12261 "blsfill\t{%1, %0|%0, %1}" 12262 [(set_attr "type" "bitmanip") 12263 (set_attr "mode" "<MODE>")]) 12264 12265(define_insn "*tbm_blsic_<mode>" 12266 [(set (match_operand:SWI48 0 "register_operand" "=r") 12267 (ior:SWI48 12268 (plus:SWI48 12269 (match_operand:SWI48 1 "nonimmediate_operand" "rm") 12270 (const_int -1)) 12271 (not:SWI48 12272 (match_dup 1)))) 12273 (clobber (reg:CC FLAGS_REG))] 12274 "TARGET_TBM" 12275 "blsic\t{%1, %0|%0, %1}" 12276 [(set_attr "type" "bitmanip") 12277 (set_attr "mode" "<MODE>")]) 12278 12279(define_insn "*tbm_t1mskc_<mode>" 12280 [(set (match_operand:SWI48 0 "register_operand" "=r") 12281 (ior:SWI48 12282 (plus:SWI48 12283 (match_operand:SWI48 1 "nonimmediate_operand" "rm") 12284 (const_int 1)) 12285 (not:SWI48 12286 (match_dup 1)))) 12287 (clobber (reg:CC FLAGS_REG))] 12288 "TARGET_TBM" 12289 "t1mskc\t{%1, %0|%0, %1}" 12290 [(set_attr "type" "bitmanip") 12291 (set_attr "mode" "<MODE>")]) 12292 12293(define_insn "*tbm_tzmsk_<mode>" 12294 [(set (match_operand:SWI48 0 "register_operand" "=r") 12295 (and:SWI48 12296 (plus:SWI48 12297 (match_operand:SWI48 1 "nonimmediate_operand" "rm") 12298 (const_int -1)) 12299 (not:SWI48 12300 (match_dup 1)))) 12301 (clobber (reg:CC FLAGS_REG))] 12302 "TARGET_TBM" 12303 "tzmsk\t{%1, %0|%0, %1}" 12304 [(set_attr "type" "bitmanip") 12305 (set_attr "mode" "<MODE>")]) 12306 12307(define_insn "bsr_rex64" 12308 [(set (match_operand:DI 0 "register_operand" "=r") 12309 (minus:DI (const_int 63) 12310 (clz:DI (match_operand:DI 1 "nonimmediate_operand" "rm")))) 12311 (clobber (reg:CC FLAGS_REG))] 12312 "TARGET_64BIT" 12313 "bsr{q}\t{%1, %0|%0, %1}" 12314 [(set_attr "type" "alu1") 12315 (set_attr "prefix_0f" "1") 12316 (set_attr "mode" "DI")]) 12317 12318(define_insn "bsr" 12319 [(set (match_operand:SI 0 "register_operand" "=r") 12320 (minus:SI (const_int 31) 12321 (clz:SI (match_operand:SI 1 "nonimmediate_operand" "rm")))) 12322 (clobber (reg:CC FLAGS_REG))] 12323 "" 12324 "bsr{l}\t{%1, %0|%0, %1}" 12325 [(set_attr "type" "alu1") 12326 (set_attr "prefix_0f" "1") 12327 (set_attr "mode" "SI")]) 12328 12329(define_insn "*bsrhi" 12330 [(set (match_operand:HI 0 "register_operand" "=r") 12331 (minus:HI (const_int 15) 12332 (clz:HI (match_operand:HI 1 "nonimmediate_operand" "rm")))) 12333 (clobber (reg:CC FLAGS_REG))] 12334 "" 12335 "bsr{w}\t{%1, %0|%0, %1}" 12336 [(set_attr "type" "alu1") 12337 (set_attr "prefix_0f" "1") 12338 (set_attr "mode" "HI")]) 12339 12340(define_insn "popcount<mode>2" 12341 [(set (match_operand:SWI248 0 "register_operand" "=r") 12342 (popcount:SWI248 12343 (match_operand:SWI248 1 "nonimmediate_operand" "rm"))) 12344 (clobber (reg:CC FLAGS_REG))] 12345 "TARGET_POPCNT" 12346{ 12347#if TARGET_MACHO 12348 return "popcnt\t{%1, %0|%0, %1}"; 12349#else 12350 return "popcnt{<imodesuffix>}\t{%1, %0|%0, %1}"; 12351#endif 12352} 12353 [(set_attr "prefix_rep" "1") 12354 (set_attr "type" "bitmanip") 12355 (set_attr "mode" "<MODE>")]) 12356 12357(define_insn "*popcount<mode>2_cmp" 12358 [(set (reg FLAGS_REG) 12359 (compare 12360 (popcount:SWI248 12361 (match_operand:SWI248 1 "nonimmediate_operand" "rm")) 12362 (const_int 0))) 12363 (set (match_operand:SWI248 0 "register_operand" "=r") 12364 (popcount:SWI248 (match_dup 1)))] 12365 "TARGET_POPCNT && ix86_match_ccmode (insn, CCZmode)" 12366{ 12367#if TARGET_MACHO 12368 return "popcnt\t{%1, %0|%0, %1}"; 12369#else 12370 return "popcnt{<imodesuffix>}\t{%1, %0|%0, %1}"; 12371#endif 12372} 12373 [(set_attr "prefix_rep" "1") 12374 (set_attr "type" "bitmanip") 12375 (set_attr "mode" "<MODE>")]) 12376 12377(define_insn "*popcountsi2_cmp_zext" 12378 [(set (reg FLAGS_REG) 12379 (compare 12380 (popcount:SI (match_operand:SI 1 "nonimmediate_operand" "rm")) 12381 (const_int 0))) 12382 (set (match_operand:DI 0 "register_operand" "=r") 12383 (zero_extend:DI(popcount:SI (match_dup 1))))] 12384 "TARGET_64BIT && TARGET_POPCNT && ix86_match_ccmode (insn, CCZmode)" 12385{ 12386#if TARGET_MACHO 12387 return "popcnt\t{%1, %0|%0, %1}"; 12388#else 12389 return "popcnt{l}\t{%1, %0|%0, %1}"; 12390#endif 12391} 12392 [(set_attr "prefix_rep" "1") 12393 (set_attr "type" "bitmanip") 12394 (set_attr "mode" "SI")]) 12395 12396(define_expand "bswap<mode>2" 12397 [(set (match_operand:SWI48 0 "register_operand" "") 12398 (bswap:SWI48 (match_operand:SWI48 1 "register_operand" "")))] 12399 "" 12400{ 12401 if (<MODE>mode == SImode && !(TARGET_BSWAP || TARGET_MOVBE)) 12402 { 12403 rtx x = operands[0]; 12404 12405 emit_move_insn (x, operands[1]); 12406 emit_insn (gen_bswaphi_lowpart (gen_lowpart (HImode, x))); 12407 emit_insn (gen_rotlsi3 (x, x, GEN_INT (16))); 12408 emit_insn (gen_bswaphi_lowpart (gen_lowpart (HImode, x))); 12409 DONE; 12410 } 12411}) 12412 12413(define_insn "*bswap<mode>2_movbe" 12414 [(set (match_operand:SWI48 0 "nonimmediate_operand" "=r,r,m") 12415 (bswap:SWI48 (match_operand:SWI48 1 "nonimmediate_operand" "0,m,r")))] 12416 "TARGET_MOVBE 12417 && !(MEM_P (operands[0]) && MEM_P (operands[1]))" 12418 "@ 12419 bswap\t%0 12420 movbe\t{%1, %0|%0, %1} 12421 movbe\t{%1, %0|%0, %1}" 12422 [(set_attr "type" "bitmanip,imov,imov") 12423 (set_attr "modrm" "0,1,1") 12424 (set_attr "prefix_0f" "*,1,1") 12425 (set_attr "prefix_extra" "*,1,1") 12426 (set_attr "mode" "<MODE>")]) 12427 12428(define_insn "*bswap<mode>2_1" 12429 [(set (match_operand:SWI48 0 "register_operand" "=r") 12430 (bswap:SWI48 (match_operand:SWI48 1 "register_operand" "0")))] 12431 "TARGET_BSWAP" 12432 "bswap\t%0" 12433 [(set_attr "type" "bitmanip") 12434 (set_attr "modrm" "0") 12435 (set_attr "mode" "<MODE>")]) 12436 12437(define_insn "*bswaphi_lowpart_1" 12438 [(set (strict_low_part (match_operand:HI 0 "register_operand" "+Q,r")) 12439 (bswap:HI (match_dup 0))) 12440 (clobber (reg:CC FLAGS_REG))] 12441 "TARGET_USE_XCHGB || optimize_function_for_size_p (cfun)" 12442 "@ 12443 xchg{b}\t{%h0, %b0|%b0, %h0} 12444 rol{w}\t{$8, %0|%0, 8}" 12445 [(set_attr "length" "2,4") 12446 (set_attr "mode" "QI,HI")]) 12447 12448(define_insn "bswaphi_lowpart" 12449 [(set (strict_low_part (match_operand:HI 0 "register_operand" "+r")) 12450 (bswap:HI (match_dup 0))) 12451 (clobber (reg:CC FLAGS_REG))] 12452 "" 12453 "rol{w}\t{$8, %0|%0, 8}" 12454 [(set_attr "length" "4") 12455 (set_attr "mode" "HI")]) 12456 12457(define_expand "paritydi2" 12458 [(set (match_operand:DI 0 "register_operand" "") 12459 (parity:DI (match_operand:DI 1 "register_operand" "")))] 12460 "! TARGET_POPCNT" 12461{ 12462 rtx scratch = gen_reg_rtx (QImode); 12463 rtx cond; 12464 12465 emit_insn (gen_paritydi2_cmp (NULL_RTX, NULL_RTX, 12466 NULL_RTX, operands[1])); 12467 12468 cond = gen_rtx_fmt_ee (ORDERED, QImode, 12469 gen_rtx_REG (CCmode, FLAGS_REG), 12470 const0_rtx); 12471 emit_insn (gen_rtx_SET (VOIDmode, scratch, cond)); 12472 12473 if (TARGET_64BIT) 12474 emit_insn (gen_zero_extendqidi2 (operands[0], scratch)); 12475 else 12476 { 12477 rtx tmp = gen_reg_rtx (SImode); 12478 12479 emit_insn (gen_zero_extendqisi2 (tmp, scratch)); 12480 emit_insn (gen_zero_extendsidi2 (operands[0], tmp)); 12481 } 12482 DONE; 12483}) 12484 12485(define_expand "paritysi2" 12486 [(set (match_operand:SI 0 "register_operand" "") 12487 (parity:SI (match_operand:SI 1 "register_operand" "")))] 12488 "! TARGET_POPCNT" 12489{ 12490 rtx scratch = gen_reg_rtx (QImode); 12491 rtx cond; 12492 12493 emit_insn (gen_paritysi2_cmp (NULL_RTX, NULL_RTX, operands[1])); 12494 12495 cond = gen_rtx_fmt_ee (ORDERED, QImode, 12496 gen_rtx_REG (CCmode, FLAGS_REG), 12497 const0_rtx); 12498 emit_insn (gen_rtx_SET (VOIDmode, scratch, cond)); 12499 12500 emit_insn (gen_zero_extendqisi2 (operands[0], scratch)); 12501 DONE; 12502}) 12503 12504(define_insn_and_split "paritydi2_cmp" 12505 [(set (reg:CC FLAGS_REG) 12506 (unspec:CC [(match_operand:DI 3 "register_operand" "0")] 12507 UNSPEC_PARITY)) 12508 (clobber (match_scratch:DI 0 "=r")) 12509 (clobber (match_scratch:SI 1 "=&r")) 12510 (clobber (match_scratch:HI 2 "=Q"))] 12511 "! TARGET_POPCNT" 12512 "#" 12513 "&& reload_completed" 12514 [(parallel 12515 [(set (match_dup 1) 12516 (xor:SI (match_dup 1) (match_dup 4))) 12517 (clobber (reg:CC FLAGS_REG))]) 12518 (parallel 12519 [(set (reg:CC FLAGS_REG) 12520 (unspec:CC [(match_dup 1)] UNSPEC_PARITY)) 12521 (clobber (match_dup 1)) 12522 (clobber (match_dup 2))])] 12523{ 12524 operands[4] = gen_lowpart (SImode, operands[3]); 12525 12526 if (TARGET_64BIT) 12527 { 12528 emit_move_insn (operands[1], gen_lowpart (SImode, operands[3])); 12529 emit_insn (gen_lshrdi3 (operands[3], operands[3], GEN_INT (32))); 12530 } 12531 else 12532 operands[1] = gen_highpart (SImode, operands[3]); 12533}) 12534 12535(define_insn_and_split "paritysi2_cmp" 12536 [(set (reg:CC FLAGS_REG) 12537 (unspec:CC [(match_operand:SI 2 "register_operand" "0")] 12538 UNSPEC_PARITY)) 12539 (clobber (match_scratch:SI 0 "=r")) 12540 (clobber (match_scratch:HI 1 "=&Q"))] 12541 "! TARGET_POPCNT" 12542 "#" 12543 "&& reload_completed" 12544 [(parallel 12545 [(set (match_dup 1) 12546 (xor:HI (match_dup 1) (match_dup 3))) 12547 (clobber (reg:CC FLAGS_REG))]) 12548 (parallel 12549 [(set (reg:CC FLAGS_REG) 12550 (unspec:CC [(match_dup 1)] UNSPEC_PARITY)) 12551 (clobber (match_dup 1))])] 12552{ 12553 operands[3] = gen_lowpart (HImode, operands[2]); 12554 12555 emit_move_insn (operands[1], gen_lowpart (HImode, operands[2])); 12556 emit_insn (gen_lshrsi3 (operands[2], operands[2], GEN_INT (16))); 12557}) 12558 12559(define_insn "*parityhi2_cmp" 12560 [(set (reg:CC FLAGS_REG) 12561 (unspec:CC [(match_operand:HI 1 "register_operand" "0")] 12562 UNSPEC_PARITY)) 12563 (clobber (match_scratch:HI 0 "=Q"))] 12564 "! TARGET_POPCNT" 12565 "xor{b}\t{%h0, %b0|%b0, %h0}" 12566 [(set_attr "length" "2") 12567 (set_attr "mode" "HI")]) 12568 12569 12570;; Thread-local storage patterns for ELF. 12571;; 12572;; Note that these code sequences must appear exactly as shown 12573;; in order to allow linker relaxation. 12574 12575(define_insn "*tls_global_dynamic_32_gnu" 12576 [(set (match_operand:SI 0 "register_operand" "=a") 12577 (unspec:SI 12578 [(match_operand:SI 1 "register_operand" "b") 12579 (match_operand:SI 2 "tls_symbolic_operand" "") 12580 (match_operand:SI 3 "constant_call_address_operand" "z")] 12581 UNSPEC_TLS_GD)) 12582 (clobber (match_scratch:SI 4 "=d")) 12583 (clobber (match_scratch:SI 5 "=c")) 12584 (clobber (reg:CC FLAGS_REG))] 12585 "!TARGET_64BIT && TARGET_GNU_TLS" 12586{ 12587 output_asm_insn 12588 ("lea{l}\t{%E2@tlsgd(,%1,1), %0|%0, %E2@tlsgd[%1*1]}", operands); 12589 if (TARGET_SUN_TLS) 12590#ifdef HAVE_AS_IX86_TLSGDPLT 12591 return "call\t%a2@tlsgdplt"; 12592#else 12593 return "call\t%p3@plt"; 12594#endif 12595 return "call\t%P3"; 12596} 12597 [(set_attr "type" "multi") 12598 (set_attr "length" "12")]) 12599 12600(define_expand "tls_global_dynamic_32" 12601 [(parallel 12602 [(set (match_operand:SI 0 "register_operand" "") 12603 (unspec:SI [(match_operand:SI 2 "register_operand" "") 12604 (match_operand:SI 1 "tls_symbolic_operand" "") 12605 (match_operand:SI 3 "constant_call_address_operand" "")] 12606 UNSPEC_TLS_GD)) 12607 (clobber (match_scratch:SI 4 "")) 12608 (clobber (match_scratch:SI 5 "")) 12609 (clobber (reg:CC FLAGS_REG))])]) 12610 12611(define_insn "*tls_global_dynamic_64" 12612 [(set (match_operand:DI 0 "register_operand" "=a") 12613 (call:DI 12614 (mem:QI (match_operand:DI 2 "constant_call_address_operand" "z")) 12615 (match_operand:DI 3 "" ""))) 12616 (unspec:DI [(match_operand 1 "tls_symbolic_operand" "")] 12617 UNSPEC_TLS_GD)] 12618 "TARGET_64BIT" 12619{ 12620 if (!TARGET_X32) 12621 fputs (ASM_BYTE "0x66\n", asm_out_file); 12622 output_asm_insn 12623 ("lea{q}\t{%E1@tlsgd(%%rip), %%rdi|rdi, %E1@tlsgd[rip]}", operands); 12624 fputs (ASM_SHORT "0x6666\n", asm_out_file); 12625 fputs ("\trex64\n", asm_out_file); 12626 if (TARGET_SUN_TLS) 12627 return "call\t%p2@plt"; 12628 return "call\t%P2"; 12629} 12630 [(set_attr "type" "multi") 12631 (set (attr "length") 12632 (symbol_ref "TARGET_X32 ? 15 : 16"))]) 12633 12634(define_expand "tls_global_dynamic_64" 12635 [(parallel 12636 [(set (match_operand:DI 0 "register_operand" "") 12637 (call:DI 12638 (mem:QI (match_operand:DI 2 "constant_call_address_operand" "")) 12639 (const_int 0))) 12640 (unspec:DI [(match_operand 1 "tls_symbolic_operand" "")] 12641 UNSPEC_TLS_GD)])]) 12642 12643(define_insn "*tls_local_dynamic_base_32_gnu" 12644 [(set (match_operand:SI 0 "register_operand" "=a") 12645 (unspec:SI 12646 [(match_operand:SI 1 "register_operand" "b") 12647 (match_operand:SI 2 "constant_call_address_operand" "z")] 12648 UNSPEC_TLS_LD_BASE)) 12649 (clobber (match_scratch:SI 3 "=d")) 12650 (clobber (match_scratch:SI 4 "=c")) 12651 (clobber (reg:CC FLAGS_REG))] 12652 "!TARGET_64BIT && TARGET_GNU_TLS" 12653{ 12654 output_asm_insn 12655 ("lea{l}\t{%&@tlsldm(%1), %0|%0, %&@tlsldm[%1]}", operands); 12656 if (TARGET_SUN_TLS) 12657#ifdef HAVE_AS_IX86_TLSLDMPLT 12658 return "call\t%&@tlsldmplt"; 12659#else 12660 return "call\t%p2@plt"; 12661#endif 12662 return "call\t%P2"; 12663} 12664 [(set_attr "type" "multi") 12665 (set_attr "length" "11")]) 12666 12667(define_expand "tls_local_dynamic_base_32" 12668 [(parallel 12669 [(set (match_operand:SI 0 "register_operand" "") 12670 (unspec:SI 12671 [(match_operand:SI 1 "register_operand" "") 12672 (match_operand:SI 2 "constant_call_address_operand" "")] 12673 UNSPEC_TLS_LD_BASE)) 12674 (clobber (match_scratch:SI 3 "")) 12675 (clobber (match_scratch:SI 4 "")) 12676 (clobber (reg:CC FLAGS_REG))])]) 12677 12678(define_insn "*tls_local_dynamic_base_64" 12679 [(set (match_operand:DI 0 "register_operand" "=a") 12680 (call:DI 12681 (mem:QI (match_operand:DI 1 "constant_call_address_operand" "z")) 12682 (match_operand:DI 2 "" ""))) 12683 (unspec:DI [(const_int 0)] UNSPEC_TLS_LD_BASE)] 12684 "TARGET_64BIT" 12685{ 12686 output_asm_insn 12687 ("lea{q}\t{%&@tlsld(%%rip), %%rdi|rdi, %&@tlsld[rip]}", operands); 12688 if (TARGET_SUN_TLS) 12689 return "call\t%p1@plt"; 12690 return "call\t%P1"; 12691} 12692 [(set_attr "type" "multi") 12693 (set_attr "length" "12")]) 12694 12695(define_expand "tls_local_dynamic_base_64" 12696 [(parallel 12697 [(set (match_operand:DI 0 "register_operand" "") 12698 (call:DI 12699 (mem:QI (match_operand:DI 1 "constant_call_address_operand" "")) 12700 (const_int 0))) 12701 (unspec:DI [(const_int 0)] UNSPEC_TLS_LD_BASE)])]) 12702 12703;; Local dynamic of a single variable is a lose. Show combine how 12704;; to convert that back to global dynamic. 12705 12706(define_insn_and_split "*tls_local_dynamic_32_once" 12707 [(set (match_operand:SI 0 "register_operand" "=a") 12708 (plus:SI 12709 (unspec:SI [(match_operand:SI 1 "register_operand" "b") 12710 (match_operand:SI 2 "constant_call_address_operand" "z")] 12711 UNSPEC_TLS_LD_BASE) 12712 (const:SI (unspec:SI 12713 [(match_operand:SI 3 "tls_symbolic_operand" "")] 12714 UNSPEC_DTPOFF)))) 12715 (clobber (match_scratch:SI 4 "=d")) 12716 (clobber (match_scratch:SI 5 "=c")) 12717 (clobber (reg:CC FLAGS_REG))] 12718 "" 12719 "#" 12720 "" 12721 [(parallel 12722 [(set (match_dup 0) 12723 (unspec:SI [(match_dup 1) (match_dup 3) (match_dup 2)] 12724 UNSPEC_TLS_GD)) 12725 (clobber (match_dup 4)) 12726 (clobber (match_dup 5)) 12727 (clobber (reg:CC FLAGS_REG))])]) 12728 12729;; Segment register for the thread base ptr load 12730(define_mode_attr tp_seg [(SI "gs") (DI "fs")]) 12731 12732;; Load and add the thread base pointer from %<tp_seg>:0. 12733(define_insn "*load_tp_x32" 12734 [(set (match_operand:SI 0 "register_operand" "=r") 12735 (unspec:SI [(const_int 0)] UNSPEC_TP))] 12736 "TARGET_X32" 12737 "mov{l}\t{%%fs:0, %0|%0, DWORD PTR fs:0}" 12738 [(set_attr "type" "imov") 12739 (set_attr "modrm" "0") 12740 (set_attr "length" "7") 12741 (set_attr "memory" "load") 12742 (set_attr "imm_disp" "false")]) 12743 12744(define_insn "*load_tp_x32_zext" 12745 [(set (match_operand:DI 0 "register_operand" "=r") 12746 (zero_extend:DI (unspec:SI [(const_int 0)] UNSPEC_TP)))] 12747 "TARGET_X32" 12748 "mov{l}\t{%%fs:0, %k0|%k0, DWORD PTR fs:0}" 12749 [(set_attr "type" "imov") 12750 (set_attr "modrm" "0") 12751 (set_attr "length" "7") 12752 (set_attr "memory" "load") 12753 (set_attr "imm_disp" "false")]) 12754 12755(define_insn "*load_tp_<mode>" 12756 [(set (match_operand:P 0 "register_operand" "=r") 12757 (unspec:P [(const_int 0)] UNSPEC_TP))] 12758 "!TARGET_X32" 12759 "mov{<imodesuffix>}\t{%%<tp_seg>:0, %0|%0, <iptrsize> PTR <tp_seg>:0}" 12760 [(set_attr "type" "imov") 12761 (set_attr "modrm" "0") 12762 (set_attr "length" "7") 12763 (set_attr "memory" "load") 12764 (set_attr "imm_disp" "false")]) 12765 12766(define_insn "*add_tp_x32" 12767 [(set (match_operand:SI 0 "register_operand" "=r") 12768 (plus:SI (unspec:SI [(const_int 0)] UNSPEC_TP) 12769 (match_operand:SI 1 "register_operand" "0"))) 12770 (clobber (reg:CC FLAGS_REG))] 12771 "TARGET_X32" 12772 "add{l}\t{%%fs:0, %0|%0, DWORD PTR fs:0}" 12773 [(set_attr "type" "alu") 12774 (set_attr "modrm" "0") 12775 (set_attr "length" "7") 12776 (set_attr "memory" "load") 12777 (set_attr "imm_disp" "false")]) 12778 12779(define_insn "*add_tp_x32_zext" 12780 [(set (match_operand:DI 0 "register_operand" "=r") 12781 (zero_extend:DI 12782 (plus:SI (unspec:SI [(const_int 0)] UNSPEC_TP) 12783 (match_operand:SI 1 "register_operand" "0")))) 12784 (clobber (reg:CC FLAGS_REG))] 12785 "TARGET_X32" 12786 "add{l}\t{%%fs:0, %k0|%k0, DWORD PTR fs:0}" 12787 [(set_attr "type" "alu") 12788 (set_attr "modrm" "0") 12789 (set_attr "length" "7") 12790 (set_attr "memory" "load") 12791 (set_attr "imm_disp" "false")]) 12792 12793(define_insn "*add_tp_<mode>" 12794 [(set (match_operand:P 0 "register_operand" "=r") 12795 (plus:P (unspec:P [(const_int 0)] UNSPEC_TP) 12796 (match_operand:P 1 "register_operand" "0"))) 12797 (clobber (reg:CC FLAGS_REG))] 12798 "!TARGET_X32" 12799 "add{<imodesuffix>}\t{%%<tp_seg>:0, %0|%0, <iptrsize> PTR <tp_seg>:0}" 12800 [(set_attr "type" "alu") 12801 (set_attr "modrm" "0") 12802 (set_attr "length" "7") 12803 (set_attr "memory" "load") 12804 (set_attr "imm_disp" "false")]) 12805 12806;; The Sun linker took the AMD64 TLS spec literally and can only handle 12807;; %rax as destination of the initial executable code sequence. 12808(define_insn "tls_initial_exec_64_sun" 12809 [(set (match_operand:DI 0 "register_operand" "=a") 12810 (unspec:DI 12811 [(match_operand:DI 1 "tls_symbolic_operand" "")] 12812 UNSPEC_TLS_IE_SUN)) 12813 (clobber (reg:CC FLAGS_REG))] 12814 "TARGET_64BIT && TARGET_SUN_TLS" 12815{ 12816 output_asm_insn 12817 ("mov{q}\t{%%fs:0, %0|%0, QWORD PTR fs:0}", operands); 12818 return "add{q}\t{%a1@gottpoff(%%rip), %0|%0, %a1@gottpoff[rip]}"; 12819} 12820 [(set_attr "type" "multi")]) 12821 12822;; GNU2 TLS patterns can be split. 12823 12824(define_expand "tls_dynamic_gnu2_32" 12825 [(set (match_dup 3) 12826 (plus:SI (match_operand:SI 2 "register_operand" "") 12827 (const:SI 12828 (unspec:SI [(match_operand:SI 1 "tls_symbolic_operand" "")] 12829 UNSPEC_TLSDESC)))) 12830 (parallel 12831 [(set (match_operand:SI 0 "register_operand" "") 12832 (unspec:SI [(match_dup 1) (match_dup 3) 12833 (match_dup 2) (reg:SI SP_REG)] 12834 UNSPEC_TLSDESC)) 12835 (clobber (reg:CC FLAGS_REG))])] 12836 "!TARGET_64BIT && TARGET_GNU2_TLS" 12837{ 12838 operands[3] = can_create_pseudo_p () ? gen_reg_rtx (Pmode) : operands[0]; 12839 ix86_tls_descriptor_calls_expanded_in_cfun = true; 12840}) 12841 12842(define_insn "*tls_dynamic_gnu2_lea_32" 12843 [(set (match_operand:SI 0 "register_operand" "=r") 12844 (plus:SI (match_operand:SI 1 "register_operand" "b") 12845 (const:SI 12846 (unspec:SI [(match_operand:SI 2 "tls_symbolic_operand" "")] 12847 UNSPEC_TLSDESC))))] 12848 "!TARGET_64BIT && TARGET_GNU2_TLS" 12849 "lea{l}\t{%E2@TLSDESC(%1), %0|%0, %E2@TLSDESC[%1]}" 12850 [(set_attr "type" "lea") 12851 (set_attr "mode" "SI") 12852 (set_attr "length" "6") 12853 (set_attr "length_address" "4")]) 12854 12855(define_insn "*tls_dynamic_gnu2_call_32" 12856 [(set (match_operand:SI 0 "register_operand" "=a") 12857 (unspec:SI [(match_operand:SI 1 "tls_symbolic_operand" "") 12858 (match_operand:SI 2 "register_operand" "0") 12859 ;; we have to make sure %ebx still points to the GOT 12860 (match_operand:SI 3 "register_operand" "b") 12861 (reg:SI SP_REG)] 12862 UNSPEC_TLSDESC)) 12863 (clobber (reg:CC FLAGS_REG))] 12864 "!TARGET_64BIT && TARGET_GNU2_TLS" 12865 "call\t{*%a1@TLSCALL(%2)|[DWORD PTR [%2+%a1@TLSCALL]]}" 12866 [(set_attr "type" "call") 12867 (set_attr "length" "2") 12868 (set_attr "length_address" "0")]) 12869 12870(define_insn_and_split "*tls_dynamic_gnu2_combine_32" 12871 [(set (match_operand:SI 0 "register_operand" "=&a") 12872 (plus:SI 12873 (unspec:SI [(match_operand:SI 3 "tls_modbase_operand" "") 12874 (match_operand:SI 4 "" "") 12875 (match_operand:SI 2 "register_operand" "b") 12876 (reg:SI SP_REG)] 12877 UNSPEC_TLSDESC) 12878 (const:SI (unspec:SI 12879 [(match_operand:SI 1 "tls_symbolic_operand" "")] 12880 UNSPEC_DTPOFF)))) 12881 (clobber (reg:CC FLAGS_REG))] 12882 "!TARGET_64BIT && TARGET_GNU2_TLS" 12883 "#" 12884 "" 12885 [(set (match_dup 0) (match_dup 5))] 12886{ 12887 operands[5] = can_create_pseudo_p () ? gen_reg_rtx (Pmode) : operands[0]; 12888 emit_insn (gen_tls_dynamic_gnu2_32 (operands[5], operands[1], operands[2])); 12889}) 12890 12891(define_expand "tls_dynamic_gnu2_64" 12892 [(set (match_dup 2) 12893 (unspec:DI [(match_operand 1 "tls_symbolic_operand" "")] 12894 UNSPEC_TLSDESC)) 12895 (parallel 12896 [(set (match_operand:DI 0 "register_operand" "") 12897 (unspec:DI [(match_dup 1) (match_dup 2) (reg:DI SP_REG)] 12898 UNSPEC_TLSDESC)) 12899 (clobber (reg:CC FLAGS_REG))])] 12900 "TARGET_64BIT && TARGET_GNU2_TLS" 12901{ 12902 operands[2] = can_create_pseudo_p () ? gen_reg_rtx (Pmode) : operands[0]; 12903 ix86_tls_descriptor_calls_expanded_in_cfun = true; 12904}) 12905 12906(define_insn "*tls_dynamic_gnu2_lea_64" 12907 [(set (match_operand:DI 0 "register_operand" "=r") 12908 (unspec:DI [(match_operand 1 "tls_symbolic_operand" "")] 12909 UNSPEC_TLSDESC))] 12910 "TARGET_64BIT && TARGET_GNU2_TLS" 12911 "lea{q}\t{%E1@TLSDESC(%%rip), %0|%0, %E1@TLSDESC[rip]}" 12912 [(set_attr "type" "lea") 12913 (set_attr "mode" "DI") 12914 (set_attr "length" "7") 12915 (set_attr "length_address" "4")]) 12916 12917(define_insn "*tls_dynamic_gnu2_call_64" 12918 [(set (match_operand:DI 0 "register_operand" "=a") 12919 (unspec:DI [(match_operand 1 "tls_symbolic_operand" "") 12920 (match_operand:DI 2 "register_operand" "0") 12921 (reg:DI SP_REG)] 12922 UNSPEC_TLSDESC)) 12923 (clobber (reg:CC FLAGS_REG))] 12924 "TARGET_64BIT && TARGET_GNU2_TLS" 12925 "call\t{*%a1@TLSCALL(%2)|[QWORD PTR [%2+%a1@TLSCALL]]}" 12926 [(set_attr "type" "call") 12927 (set_attr "length" "2") 12928 (set_attr "length_address" "0")]) 12929 12930(define_insn_and_split "*tls_dynamic_gnu2_combine_64" 12931 [(set (match_operand:DI 0 "register_operand" "=&a") 12932 (plus:DI 12933 (unspec:DI [(match_operand:DI 2 "tls_modbase_operand" "") 12934 (match_operand:DI 3 "" "") 12935 (reg:DI SP_REG)] 12936 UNSPEC_TLSDESC) 12937 (const:DI (unspec:DI 12938 [(match_operand 1 "tls_symbolic_operand" "")] 12939 UNSPEC_DTPOFF)))) 12940 (clobber (reg:CC FLAGS_REG))] 12941 "TARGET_64BIT && TARGET_GNU2_TLS" 12942 "#" 12943 "" 12944 [(set (match_dup 0) (match_dup 4))] 12945{ 12946 operands[4] = can_create_pseudo_p () ? gen_reg_rtx (Pmode) : operands[0]; 12947 emit_insn (gen_tls_dynamic_gnu2_64 (operands[4], operands[1])); 12948}) 12949 12950;; These patterns match the binary 387 instructions for addM3, subM3, 12951;; mulM3 and divM3. There are three patterns for each of DFmode and 12952;; SFmode. The first is the normal insn, the second the same insn but 12953;; with one operand a conversion, and the third the same insn but with 12954;; the other operand a conversion. The conversion may be SFmode or 12955;; SImode if the target mode DFmode, but only SImode if the target mode 12956;; is SFmode. 12957 12958;; Gcc is slightly more smart about handling normal two address instructions 12959;; so use special patterns for add and mull. 12960 12961(define_insn "*fop_<mode>_comm_mixed" 12962 [(set (match_operand:MODEF 0 "register_operand" "=f,x,x") 12963 (match_operator:MODEF 3 "binary_fp_operator" 12964 [(match_operand:MODEF 1 "nonimmediate_operand" "%0,0,x") 12965 (match_operand:MODEF 2 "nonimmediate_operand" "fm,xm,xm")]))] 12966 "SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_MIX_SSE_I387 12967 && COMMUTATIVE_ARITH_P (operands[3]) 12968 && !(MEM_P (operands[1]) && MEM_P (operands[2]))" 12969 "* return output_387_binary_op (insn, operands);" 12970 [(set (attr "type") 12971 (if_then_else (eq_attr "alternative" "1,2") 12972 (if_then_else (match_operand:MODEF 3 "mult_operator" "") 12973 (const_string "ssemul") 12974 (const_string "sseadd")) 12975 (if_then_else (match_operand:MODEF 3 "mult_operator" "") 12976 (const_string "fmul") 12977 (const_string "fop")))) 12978 (set_attr "isa" "*,noavx,avx") 12979 (set_attr "prefix" "orig,orig,vex") 12980 (set_attr "mode" "<MODE>")]) 12981 12982(define_insn "*fop_<mode>_comm_sse" 12983 [(set (match_operand:MODEF 0 "register_operand" "=x,x") 12984 (match_operator:MODEF 3 "binary_fp_operator" 12985 [(match_operand:MODEF 1 "nonimmediate_operand" "%0,x") 12986 (match_operand:MODEF 2 "nonimmediate_operand" "xm,xm")]))] 12987 "SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH 12988 && COMMUTATIVE_ARITH_P (operands[3]) 12989 && !(MEM_P (operands[1]) && MEM_P (operands[2]))" 12990 "* return output_387_binary_op (insn, operands);" 12991 [(set (attr "type") 12992 (if_then_else (match_operand:MODEF 3 "mult_operator" "") 12993 (const_string "ssemul") 12994 (const_string "sseadd"))) 12995 (set_attr "isa" "noavx,avx") 12996 (set_attr "prefix" "orig,vex") 12997 (set_attr "mode" "<MODE>")]) 12998 12999(define_insn "*fop_<mode>_comm_i387" 13000 [(set (match_operand:MODEF 0 "register_operand" "=f") 13001 (match_operator:MODEF 3 "binary_fp_operator" 13002 [(match_operand:MODEF 1 "nonimmediate_operand" "%0") 13003 (match_operand:MODEF 2 "nonimmediate_operand" "fm")]))] 13004 "TARGET_80387 && X87_ENABLE_ARITH (<MODE>mode) 13005 && COMMUTATIVE_ARITH_P (operands[3]) 13006 && !(MEM_P (operands[1]) && MEM_P (operands[2]))" 13007 "* return output_387_binary_op (insn, operands);" 13008 [(set (attr "type") 13009 (if_then_else (match_operand:MODEF 3 "mult_operator" "") 13010 (const_string "fmul") 13011 (const_string "fop"))) 13012 (set_attr "mode" "<MODE>")]) 13013 13014(define_insn "*fop_<mode>_1_mixed" 13015 [(set (match_operand:MODEF 0 "register_operand" "=f,f,x,x") 13016 (match_operator:MODEF 3 "binary_fp_operator" 13017 [(match_operand:MODEF 1 "nonimmediate_operand" "0,fm,0,x") 13018 (match_operand:MODEF 2 "nonimmediate_operand" "fm,0,xm,xm")]))] 13019 "SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_MIX_SSE_I387 13020 && !COMMUTATIVE_ARITH_P (operands[3]) 13021 && !(MEM_P (operands[1]) && MEM_P (operands[2]))" 13022 "* return output_387_binary_op (insn, operands);" 13023 [(set (attr "type") 13024 (cond [(and (eq_attr "alternative" "2,3") 13025 (match_operand:MODEF 3 "mult_operator" "")) 13026 (const_string "ssemul") 13027 (and (eq_attr "alternative" "2,3") 13028 (match_operand:MODEF 3 "div_operator" "")) 13029 (const_string "ssediv") 13030 (eq_attr "alternative" "2,3") 13031 (const_string "sseadd") 13032 (match_operand:MODEF 3 "mult_operator" "") 13033 (const_string "fmul") 13034 (match_operand:MODEF 3 "div_operator" "") 13035 (const_string "fdiv") 13036 ] 13037 (const_string "fop"))) 13038 (set_attr "isa" "*,*,noavx,avx") 13039 (set_attr "prefix" "orig,orig,orig,vex") 13040 (set_attr "mode" "<MODE>")]) 13041 13042(define_insn "*rcpsf2_sse" 13043 [(set (match_operand:SF 0 "register_operand" "=x") 13044 (unspec:SF [(match_operand:SF 1 "nonimmediate_operand" "xm")] 13045 UNSPEC_RCP))] 13046 "TARGET_SSE_MATH" 13047 "%vrcpss\t{%1, %d0|%d0, %1}" 13048 [(set_attr "type" "sse") 13049 (set_attr "atom_sse_attr" "rcp") 13050 (set_attr "prefix" "maybe_vex") 13051 (set_attr "mode" "SF")]) 13052 13053(define_insn "*fop_<mode>_1_sse" 13054 [(set (match_operand:MODEF 0 "register_operand" "=x,x") 13055 (match_operator:MODEF 3 "binary_fp_operator" 13056 [(match_operand:MODEF 1 "register_operand" "0,x") 13057 (match_operand:MODEF 2 "nonimmediate_operand" "xm,xm")]))] 13058 "SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH 13059 && !COMMUTATIVE_ARITH_P (operands[3])" 13060 "* return output_387_binary_op (insn, operands);" 13061 [(set (attr "type") 13062 (cond [(match_operand:MODEF 3 "mult_operator" "") 13063 (const_string "ssemul") 13064 (match_operand:MODEF 3 "div_operator" "") 13065 (const_string "ssediv") 13066 ] 13067 (const_string "sseadd"))) 13068 (set_attr "isa" "noavx,avx") 13069 (set_attr "prefix" "orig,vex") 13070 (set_attr "mode" "<MODE>")]) 13071 13072;; This pattern is not fully shadowed by the pattern above. 13073(define_insn "*fop_<mode>_1_i387" 13074 [(set (match_operand:MODEF 0 "register_operand" "=f,f") 13075 (match_operator:MODEF 3 "binary_fp_operator" 13076 [(match_operand:MODEF 1 "nonimmediate_operand" "0,fm") 13077 (match_operand:MODEF 2 "nonimmediate_operand" "fm,0")]))] 13078 "TARGET_80387 && X87_ENABLE_ARITH (<MODE>mode) 13079 && !(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH) 13080 && !COMMUTATIVE_ARITH_P (operands[3]) 13081 && !(MEM_P (operands[1]) && MEM_P (operands[2]))" 13082 "* return output_387_binary_op (insn, operands);" 13083 [(set (attr "type") 13084 (cond [(match_operand:MODEF 3 "mult_operator" "") 13085 (const_string "fmul") 13086 (match_operand:MODEF 3 "div_operator" "") 13087 (const_string "fdiv") 13088 ] 13089 (const_string "fop"))) 13090 (set_attr "mode" "<MODE>")]) 13091 13092;; ??? Add SSE splitters for these! 13093(define_insn "*fop_<MODEF:mode>_2_i387" 13094 [(set (match_operand:MODEF 0 "register_operand" "=f,f") 13095 (match_operator:MODEF 3 "binary_fp_operator" 13096 [(float:MODEF 13097 (match_operand:SWI24 1 "nonimmediate_operand" "m,?r")) 13098 (match_operand:MODEF 2 "register_operand" "0,0")]))] 13099 "TARGET_80387 && X87_ENABLE_FLOAT (<MODEF:MODE>mode, <SWI24:MODE>mode) 13100 && !(SSE_FLOAT_MODE_P (<MODEF:MODE>mode) && TARGET_SSE_MATH) 13101 && (TARGET_USE_<SWI24:MODE>MODE_FIOP || optimize_function_for_size_p (cfun))" 13102 "* return which_alternative ? \"#\" : output_387_binary_op (insn, operands);" 13103 [(set (attr "type") 13104 (cond [(match_operand:MODEF 3 "mult_operator" "") 13105 (const_string "fmul") 13106 (match_operand:MODEF 3 "div_operator" "") 13107 (const_string "fdiv") 13108 ] 13109 (const_string "fop"))) 13110 (set_attr "fp_int_src" "true") 13111 (set_attr "mode" "<SWI24:MODE>")]) 13112 13113(define_insn "*fop_<MODEF:mode>_3_i387" 13114 [(set (match_operand:MODEF 0 "register_operand" "=f,f") 13115 (match_operator:MODEF 3 "binary_fp_operator" 13116 [(match_operand:MODEF 1 "register_operand" "0,0") 13117 (float:MODEF 13118 (match_operand:SWI24 2 "nonimmediate_operand" "m,?r"))]))] 13119 "TARGET_80387 && X87_ENABLE_FLOAT (<MODEF:MODE>mode, <SWI24:MODE>mode) 13120 && !(SSE_FLOAT_MODE_P (<MODEF:MODE>mode) && TARGET_SSE_MATH) 13121 && (TARGET_USE_<SWI24:MODE>MODE_FIOP || optimize_function_for_size_p (cfun))" 13122 "* return which_alternative ? \"#\" : output_387_binary_op (insn, operands);" 13123 [(set (attr "type") 13124 (cond [(match_operand:MODEF 3 "mult_operator" "") 13125 (const_string "fmul") 13126 (match_operand:MODEF 3 "div_operator" "") 13127 (const_string "fdiv") 13128 ] 13129 (const_string "fop"))) 13130 (set_attr "fp_int_src" "true") 13131 (set_attr "mode" "<MODE>")]) 13132 13133(define_insn "*fop_df_4_i387" 13134 [(set (match_operand:DF 0 "register_operand" "=f,f") 13135 (match_operator:DF 3 "binary_fp_operator" 13136 [(float_extend:DF 13137 (match_operand:SF 1 "nonimmediate_operand" "fm,0")) 13138 (match_operand:DF 2 "register_operand" "0,f")]))] 13139 "TARGET_80387 && X87_ENABLE_ARITH (DFmode) 13140 && !(TARGET_SSE2 && TARGET_SSE_MATH) 13141 && !(MEM_P (operands[1]) && MEM_P (operands[2]))" 13142 "* return output_387_binary_op (insn, operands);" 13143 [(set (attr "type") 13144 (cond [(match_operand:DF 3 "mult_operator" "") 13145 (const_string "fmul") 13146 (match_operand:DF 3 "div_operator" "") 13147 (const_string "fdiv") 13148 ] 13149 (const_string "fop"))) 13150 (set_attr "mode" "SF")]) 13151 13152(define_insn "*fop_df_5_i387" 13153 [(set (match_operand:DF 0 "register_operand" "=f,f") 13154 (match_operator:DF 3 "binary_fp_operator" 13155 [(match_operand:DF 1 "register_operand" "0,f") 13156 (float_extend:DF 13157 (match_operand:SF 2 "nonimmediate_operand" "fm,0"))]))] 13158 "TARGET_80387 && X87_ENABLE_ARITH (DFmode) 13159 && !(TARGET_SSE2 && TARGET_SSE_MATH)" 13160 "* return output_387_binary_op (insn, operands);" 13161 [(set (attr "type") 13162 (cond [(match_operand:DF 3 "mult_operator" "") 13163 (const_string "fmul") 13164 (match_operand:DF 3 "div_operator" "") 13165 (const_string "fdiv") 13166 ] 13167 (const_string "fop"))) 13168 (set_attr "mode" "SF")]) 13169 13170(define_insn "*fop_df_6_i387" 13171 [(set (match_operand:DF 0 "register_operand" "=f,f") 13172 (match_operator:DF 3 "binary_fp_operator" 13173 [(float_extend:DF 13174 (match_operand:SF 1 "register_operand" "0,f")) 13175 (float_extend:DF 13176 (match_operand:SF 2 "nonimmediate_operand" "fm,0"))]))] 13177 "TARGET_80387 && X87_ENABLE_ARITH (DFmode) 13178 && !(TARGET_SSE2 && TARGET_SSE_MATH)" 13179 "* return output_387_binary_op (insn, operands);" 13180 [(set (attr "type") 13181 (cond [(match_operand:DF 3 "mult_operator" "") 13182 (const_string "fmul") 13183 (match_operand:DF 3 "div_operator" "") 13184 (const_string "fdiv") 13185 ] 13186 (const_string "fop"))) 13187 (set_attr "mode" "SF")]) 13188 13189(define_insn "*fop_xf_comm_i387" 13190 [(set (match_operand:XF 0 "register_operand" "=f") 13191 (match_operator:XF 3 "binary_fp_operator" 13192 [(match_operand:XF 1 "register_operand" "%0") 13193 (match_operand:XF 2 "register_operand" "f")]))] 13194 "TARGET_80387 13195 && COMMUTATIVE_ARITH_P (operands[3])" 13196 "* return output_387_binary_op (insn, operands);" 13197 [(set (attr "type") 13198 (if_then_else (match_operand:XF 3 "mult_operator" "") 13199 (const_string "fmul") 13200 (const_string "fop"))) 13201 (set_attr "mode" "XF")]) 13202 13203(define_insn "*fop_xf_1_i387" 13204 [(set (match_operand:XF 0 "register_operand" "=f,f") 13205 (match_operator:XF 3 "binary_fp_operator" 13206 [(match_operand:XF 1 "register_operand" "0,f") 13207 (match_operand:XF 2 "register_operand" "f,0")]))] 13208 "TARGET_80387 13209 && !COMMUTATIVE_ARITH_P (operands[3])" 13210 "* return output_387_binary_op (insn, operands);" 13211 [(set (attr "type") 13212 (cond [(match_operand:XF 3 "mult_operator" "") 13213 (const_string "fmul") 13214 (match_operand:XF 3 "div_operator" "") 13215 (const_string "fdiv") 13216 ] 13217 (const_string "fop"))) 13218 (set_attr "mode" "XF")]) 13219 13220(define_insn "*fop_xf_2_i387" 13221 [(set (match_operand:XF 0 "register_operand" "=f,f") 13222 (match_operator:XF 3 "binary_fp_operator" 13223 [(float:XF 13224 (match_operand:SWI24 1 "nonimmediate_operand" "m,?r")) 13225 (match_operand:XF 2 "register_operand" "0,0")]))] 13226 "TARGET_80387 && (TARGET_USE_<MODE>MODE_FIOP || optimize_function_for_size_p (cfun))" 13227 "* return which_alternative ? \"#\" : output_387_binary_op (insn, operands);" 13228 [(set (attr "type") 13229 (cond [(match_operand:XF 3 "mult_operator" "") 13230 (const_string "fmul") 13231 (match_operand:XF 3 "div_operator" "") 13232 (const_string "fdiv") 13233 ] 13234 (const_string "fop"))) 13235 (set_attr "fp_int_src" "true") 13236 (set_attr "mode" "<MODE>")]) 13237 13238(define_insn "*fop_xf_3_i387" 13239 [(set (match_operand:XF 0 "register_operand" "=f,f") 13240 (match_operator:XF 3 "binary_fp_operator" 13241 [(match_operand:XF 1 "register_operand" "0,0") 13242 (float:XF 13243 (match_operand:SWI24 2 "nonimmediate_operand" "m,?r"))]))] 13244 "TARGET_80387 && (TARGET_USE_<MODE>MODE_FIOP || optimize_function_for_size_p (cfun))" 13245 "* return which_alternative ? \"#\" : output_387_binary_op (insn, operands);" 13246 [(set (attr "type") 13247 (cond [(match_operand:XF 3 "mult_operator" "") 13248 (const_string "fmul") 13249 (match_operand:XF 3 "div_operator" "") 13250 (const_string "fdiv") 13251 ] 13252 (const_string "fop"))) 13253 (set_attr "fp_int_src" "true") 13254 (set_attr "mode" "<MODE>")]) 13255 13256(define_insn "*fop_xf_4_i387" 13257 [(set (match_operand:XF 0 "register_operand" "=f,f") 13258 (match_operator:XF 3 "binary_fp_operator" 13259 [(float_extend:XF 13260 (match_operand:MODEF 1 "nonimmediate_operand" "fm,0")) 13261 (match_operand:XF 2 "register_operand" "0,f")]))] 13262 "TARGET_80387" 13263 "* return output_387_binary_op (insn, operands);" 13264 [(set (attr "type") 13265 (cond [(match_operand:XF 3 "mult_operator" "") 13266 (const_string "fmul") 13267 (match_operand:XF 3 "div_operator" "") 13268 (const_string "fdiv") 13269 ] 13270 (const_string "fop"))) 13271 (set_attr "mode" "<MODE>")]) 13272 13273(define_insn "*fop_xf_5_i387" 13274 [(set (match_operand:XF 0 "register_operand" "=f,f") 13275 (match_operator:XF 3 "binary_fp_operator" 13276 [(match_operand:XF 1 "register_operand" "0,f") 13277 (float_extend:XF 13278 (match_operand:MODEF 2 "nonimmediate_operand" "fm,0"))]))] 13279 "TARGET_80387" 13280 "* return output_387_binary_op (insn, operands);" 13281 [(set (attr "type") 13282 (cond [(match_operand:XF 3 "mult_operator" "") 13283 (const_string "fmul") 13284 (match_operand:XF 3 "div_operator" "") 13285 (const_string "fdiv") 13286 ] 13287 (const_string "fop"))) 13288 (set_attr "mode" "<MODE>")]) 13289 13290(define_insn "*fop_xf_6_i387" 13291 [(set (match_operand:XF 0 "register_operand" "=f,f") 13292 (match_operator:XF 3 "binary_fp_operator" 13293 [(float_extend:XF 13294 (match_operand:MODEF 1 "register_operand" "0,f")) 13295 (float_extend:XF 13296 (match_operand:MODEF 2 "nonimmediate_operand" "fm,0"))]))] 13297 "TARGET_80387" 13298 "* return output_387_binary_op (insn, operands);" 13299 [(set (attr "type") 13300 (cond [(match_operand:XF 3 "mult_operator" "") 13301 (const_string "fmul") 13302 (match_operand:XF 3 "div_operator" "") 13303 (const_string "fdiv") 13304 ] 13305 (const_string "fop"))) 13306 (set_attr "mode" "<MODE>")]) 13307 13308(define_split 13309 [(set (match_operand 0 "register_operand" "") 13310 (match_operator 3 "binary_fp_operator" 13311 [(float (match_operand:SWI24 1 "register_operand" "")) 13312 (match_operand 2 "register_operand" "")]))] 13313 "reload_completed 13314 && X87_FLOAT_MODE_P (GET_MODE (operands[0])) 13315 && X87_ENABLE_FLOAT (GET_MODE (operands[0]), GET_MODE (operands[1]))" 13316 [(const_int 0)] 13317{ 13318 operands[4] = ix86_force_to_memory (GET_MODE (operands[1]), operands[1]); 13319 operands[4] = gen_rtx_FLOAT (GET_MODE (operands[0]), operands[4]); 13320 emit_insn (gen_rtx_SET (VOIDmode, operands[0], 13321 gen_rtx_fmt_ee (GET_CODE (operands[3]), 13322 GET_MODE (operands[3]), 13323 operands[4], 13324 operands[2]))); 13325 ix86_free_from_memory (GET_MODE (operands[1])); 13326 DONE; 13327}) 13328 13329(define_split 13330 [(set (match_operand 0 "register_operand" "") 13331 (match_operator 3 "binary_fp_operator" 13332 [(match_operand 1 "register_operand" "") 13333 (float (match_operand:SWI24 2 "register_operand" ""))]))] 13334 "reload_completed 13335 && X87_FLOAT_MODE_P (GET_MODE (operands[0])) 13336 && X87_ENABLE_FLOAT (GET_MODE (operands[0]), GET_MODE (operands[2]))" 13337 [(const_int 0)] 13338{ 13339 operands[4] = ix86_force_to_memory (GET_MODE (operands[2]), operands[2]); 13340 operands[4] = gen_rtx_FLOAT (GET_MODE (operands[0]), operands[4]); 13341 emit_insn (gen_rtx_SET (VOIDmode, operands[0], 13342 gen_rtx_fmt_ee (GET_CODE (operands[3]), 13343 GET_MODE (operands[3]), 13344 operands[1], 13345 operands[4]))); 13346 ix86_free_from_memory (GET_MODE (operands[2])); 13347 DONE; 13348}) 13349 13350;; FPU special functions. 13351 13352;; This pattern implements a no-op XFmode truncation for 13353;; all fancy i386 XFmode math functions. 13354 13355(define_insn "truncxf<mode>2_i387_noop_unspec" 13356 [(set (match_operand:MODEF 0 "register_operand" "=f") 13357 (unspec:MODEF [(match_operand:XF 1 "register_operand" "f")] 13358 UNSPEC_TRUNC_NOOP))] 13359 "TARGET_USE_FANCY_MATH_387" 13360 "* return output_387_reg_move (insn, operands);" 13361 [(set_attr "type" "fmov") 13362 (set_attr "mode" "<MODE>")]) 13363 13364(define_insn "sqrtxf2" 13365 [(set (match_operand:XF 0 "register_operand" "=f") 13366 (sqrt:XF (match_operand:XF 1 "register_operand" "0")))] 13367 "TARGET_USE_FANCY_MATH_387" 13368 "fsqrt" 13369 [(set_attr "type" "fpspc") 13370 (set_attr "mode" "XF") 13371 (set_attr "athlon_decode" "direct") 13372 (set_attr "amdfam10_decode" "direct") 13373 (set_attr "bdver1_decode" "direct")]) 13374 13375(define_insn "sqrt_extend<mode>xf2_i387" 13376 [(set (match_operand:XF 0 "register_operand" "=f") 13377 (sqrt:XF 13378 (float_extend:XF 13379 (match_operand:MODEF 1 "register_operand" "0"))))] 13380 "TARGET_USE_FANCY_MATH_387" 13381 "fsqrt" 13382 [(set_attr "type" "fpspc") 13383 (set_attr "mode" "XF") 13384 (set_attr "athlon_decode" "direct") 13385 (set_attr "amdfam10_decode" "direct") 13386 (set_attr "bdver1_decode" "direct")]) 13387 13388(define_insn "*rsqrtsf2_sse" 13389 [(set (match_operand:SF 0 "register_operand" "=x") 13390 (unspec:SF [(match_operand:SF 1 "nonimmediate_operand" "xm")] 13391 UNSPEC_RSQRT))] 13392 "TARGET_SSE_MATH" 13393 "%vrsqrtss\t{%1, %d0|%d0, %1}" 13394 [(set_attr "type" "sse") 13395 (set_attr "atom_sse_attr" "rcp") 13396 (set_attr "prefix" "maybe_vex") 13397 (set_attr "mode" "SF")]) 13398 13399(define_expand "rsqrtsf2" 13400 [(set (match_operand:SF 0 "register_operand" "") 13401 (unspec:SF [(match_operand:SF 1 "nonimmediate_operand" "")] 13402 UNSPEC_RSQRT))] 13403 "TARGET_SSE_MATH" 13404{ 13405 ix86_emit_swsqrtsf (operands[0], operands[1], SFmode, 1); 13406 DONE; 13407}) 13408 13409(define_insn "*sqrt<mode>2_sse" 13410 [(set (match_operand:MODEF 0 "register_operand" "=x") 13411 (sqrt:MODEF 13412 (match_operand:MODEF 1 "nonimmediate_operand" "xm")))] 13413 "SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH" 13414 "%vsqrt<ssemodesuffix>\t{%1, %d0|%d0, %1}" 13415 [(set_attr "type" "sse") 13416 (set_attr "atom_sse_attr" "sqrt") 13417 (set_attr "prefix" "maybe_vex") 13418 (set_attr "mode" "<MODE>") 13419 (set_attr "athlon_decode" "*") 13420 (set_attr "amdfam10_decode" "*") 13421 (set_attr "bdver1_decode" "*")]) 13422 13423(define_expand "sqrt<mode>2" 13424 [(set (match_operand:MODEF 0 "register_operand" "") 13425 (sqrt:MODEF 13426 (match_operand:MODEF 1 "nonimmediate_operand" "")))] 13427 "(TARGET_USE_FANCY_MATH_387 && X87_ENABLE_ARITH (<MODE>mode)) 13428 || (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)" 13429{ 13430 if (<MODE>mode == SFmode 13431 && TARGET_SSE_MATH 13432 && TARGET_RECIP_SQRT 13433 && !optimize_function_for_size_p (cfun) 13434 && flag_finite_math_only && !flag_trapping_math 13435 && flag_unsafe_math_optimizations) 13436 { 13437 ix86_emit_swsqrtsf (operands[0], operands[1], SFmode, 0); 13438 DONE; 13439 } 13440 13441 if (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)) 13442 { 13443 rtx op0 = gen_reg_rtx (XFmode); 13444 rtx op1 = force_reg (<MODE>mode, operands[1]); 13445 13446 emit_insn (gen_sqrt_extend<mode>xf2_i387 (op0, op1)); 13447 emit_insn (gen_truncxf<mode>2_i387_noop_unspec (operands[0], op0)); 13448 DONE; 13449 } 13450}) 13451 13452(define_insn "fpremxf4_i387" 13453 [(set (match_operand:XF 0 "register_operand" "=f") 13454 (unspec:XF [(match_operand:XF 2 "register_operand" "0") 13455 (match_operand:XF 3 "register_operand" "1")] 13456 UNSPEC_FPREM_F)) 13457 (set (match_operand:XF 1 "register_operand" "=u") 13458 (unspec:XF [(match_dup 2) (match_dup 3)] 13459 UNSPEC_FPREM_U)) 13460 (set (reg:CCFP FPSR_REG) 13461 (unspec:CCFP [(match_dup 2) (match_dup 3)] 13462 UNSPEC_C2_FLAG))] 13463 "TARGET_USE_FANCY_MATH_387" 13464 "fprem" 13465 [(set_attr "type" "fpspc") 13466 (set_attr "mode" "XF")]) 13467 13468(define_expand "fmodxf3" 13469 [(use (match_operand:XF 0 "register_operand" "")) 13470 (use (match_operand:XF 1 "general_operand" "")) 13471 (use (match_operand:XF 2 "general_operand" ""))] 13472 "TARGET_USE_FANCY_MATH_387" 13473{ 13474 rtx label = gen_label_rtx (); 13475 13476 rtx op1 = gen_reg_rtx (XFmode); 13477 rtx op2 = gen_reg_rtx (XFmode); 13478 13479 emit_move_insn (op2, operands[2]); 13480 emit_move_insn (op1, operands[1]); 13481 13482 emit_label (label); 13483 emit_insn (gen_fpremxf4_i387 (op1, op2, op1, op2)); 13484 ix86_emit_fp_unordered_jump (label); 13485 LABEL_NUSES (label) = 1; 13486 13487 emit_move_insn (operands[0], op1); 13488 DONE; 13489}) 13490 13491(define_expand "fmod<mode>3" 13492 [(use (match_operand:MODEF 0 "register_operand" "")) 13493 (use (match_operand:MODEF 1 "general_operand" "")) 13494 (use (match_operand:MODEF 2 "general_operand" ""))] 13495 "TARGET_USE_FANCY_MATH_387" 13496{ 13497 rtx (*gen_truncxf) (rtx, rtx); 13498 13499 rtx label = gen_label_rtx (); 13500 13501 rtx op1 = gen_reg_rtx (XFmode); 13502 rtx op2 = gen_reg_rtx (XFmode); 13503 13504 emit_insn (gen_extend<mode>xf2 (op2, operands[2])); 13505 emit_insn (gen_extend<mode>xf2 (op1, operands[1])); 13506 13507 emit_label (label); 13508 emit_insn (gen_fpremxf4_i387 (op1, op2, op1, op2)); 13509 ix86_emit_fp_unordered_jump (label); 13510 LABEL_NUSES (label) = 1; 13511 13512 /* Truncate the result properly for strict SSE math. */ 13513 if (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH 13514 && !TARGET_MIX_SSE_I387) 13515 gen_truncxf = gen_truncxf<mode>2; 13516 else 13517 gen_truncxf = gen_truncxf<mode>2_i387_noop_unspec; 13518 13519 emit_insn (gen_truncxf (operands[0], op1)); 13520 DONE; 13521}) 13522 13523(define_insn "fprem1xf4_i387" 13524 [(set (match_operand:XF 0 "register_operand" "=f") 13525 (unspec:XF [(match_operand:XF 2 "register_operand" "0") 13526 (match_operand:XF 3 "register_operand" "1")] 13527 UNSPEC_FPREM1_F)) 13528 (set (match_operand:XF 1 "register_operand" "=u") 13529 (unspec:XF [(match_dup 2) (match_dup 3)] 13530 UNSPEC_FPREM1_U)) 13531 (set (reg:CCFP FPSR_REG) 13532 (unspec:CCFP [(match_dup 2) (match_dup 3)] 13533 UNSPEC_C2_FLAG))] 13534 "TARGET_USE_FANCY_MATH_387" 13535 "fprem1" 13536 [(set_attr "type" "fpspc") 13537 (set_attr "mode" "XF")]) 13538 13539(define_expand "remainderxf3" 13540 [(use (match_operand:XF 0 "register_operand" "")) 13541 (use (match_operand:XF 1 "general_operand" "")) 13542 (use (match_operand:XF 2 "general_operand" ""))] 13543 "TARGET_USE_FANCY_MATH_387" 13544{ 13545 rtx label = gen_label_rtx (); 13546 13547 rtx op1 = gen_reg_rtx (XFmode); 13548 rtx op2 = gen_reg_rtx (XFmode); 13549 13550 emit_move_insn (op2, operands[2]); 13551 emit_move_insn (op1, operands[1]); 13552 13553 emit_label (label); 13554 emit_insn (gen_fprem1xf4_i387 (op1, op2, op1, op2)); 13555 ix86_emit_fp_unordered_jump (label); 13556 LABEL_NUSES (label) = 1; 13557 13558 emit_move_insn (operands[0], op1); 13559 DONE; 13560}) 13561 13562(define_expand "remainder<mode>3" 13563 [(use (match_operand:MODEF 0 "register_operand" "")) 13564 (use (match_operand:MODEF 1 "general_operand" "")) 13565 (use (match_operand:MODEF 2 "general_operand" ""))] 13566 "TARGET_USE_FANCY_MATH_387" 13567{ 13568 rtx (*gen_truncxf) (rtx, rtx); 13569 13570 rtx label = gen_label_rtx (); 13571 13572 rtx op1 = gen_reg_rtx (XFmode); 13573 rtx op2 = gen_reg_rtx (XFmode); 13574 13575 emit_insn (gen_extend<mode>xf2 (op2, operands[2])); 13576 emit_insn (gen_extend<mode>xf2 (op1, operands[1])); 13577 13578 emit_label (label); 13579 13580 emit_insn (gen_fprem1xf4_i387 (op1, op2, op1, op2)); 13581 ix86_emit_fp_unordered_jump (label); 13582 LABEL_NUSES (label) = 1; 13583 13584 /* Truncate the result properly for strict SSE math. */ 13585 if (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH 13586 && !TARGET_MIX_SSE_I387) 13587 gen_truncxf = gen_truncxf<mode>2; 13588 else 13589 gen_truncxf = gen_truncxf<mode>2_i387_noop_unspec; 13590 13591 emit_insn (gen_truncxf (operands[0], op1)); 13592 DONE; 13593}) 13594 13595(define_insn "*sinxf2_i387" 13596 [(set (match_operand:XF 0 "register_operand" "=f") 13597 (unspec:XF [(match_operand:XF 1 "register_operand" "0")] UNSPEC_SIN))] 13598 "TARGET_USE_FANCY_MATH_387 13599 && flag_unsafe_math_optimizations" 13600 "fsin" 13601 [(set_attr "type" "fpspc") 13602 (set_attr "mode" "XF")]) 13603 13604(define_insn "*sin_extend<mode>xf2_i387" 13605 [(set (match_operand:XF 0 "register_operand" "=f") 13606 (unspec:XF [(float_extend:XF 13607 (match_operand:MODEF 1 "register_operand" "0"))] 13608 UNSPEC_SIN))] 13609 "TARGET_USE_FANCY_MATH_387 13610 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH) 13611 || TARGET_MIX_SSE_I387) 13612 && flag_unsafe_math_optimizations" 13613 "fsin" 13614 [(set_attr "type" "fpspc") 13615 (set_attr "mode" "XF")]) 13616 13617(define_insn "*cosxf2_i387" 13618 [(set (match_operand:XF 0 "register_operand" "=f") 13619 (unspec:XF [(match_operand:XF 1 "register_operand" "0")] UNSPEC_COS))] 13620 "TARGET_USE_FANCY_MATH_387 13621 && flag_unsafe_math_optimizations" 13622 "fcos" 13623 [(set_attr "type" "fpspc") 13624 (set_attr "mode" "XF")]) 13625 13626(define_insn "*cos_extend<mode>xf2_i387" 13627 [(set (match_operand:XF 0 "register_operand" "=f") 13628 (unspec:XF [(float_extend:XF 13629 (match_operand:MODEF 1 "register_operand" "0"))] 13630 UNSPEC_COS))] 13631 "TARGET_USE_FANCY_MATH_387 13632 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH) 13633 || TARGET_MIX_SSE_I387) 13634 && flag_unsafe_math_optimizations" 13635 "fcos" 13636 [(set_attr "type" "fpspc") 13637 (set_attr "mode" "XF")]) 13638 13639;; When sincos pattern is defined, sin and cos builtin functions will be 13640;; expanded to sincos pattern with one of its outputs left unused. 13641;; CSE pass will figure out if two sincos patterns can be combined, 13642;; otherwise sincos pattern will be split back to sin or cos pattern, 13643;; depending on the unused output. 13644 13645(define_insn "sincosxf3" 13646 [(set (match_operand:XF 0 "register_operand" "=f") 13647 (unspec:XF [(match_operand:XF 2 "register_operand" "0")] 13648 UNSPEC_SINCOS_COS)) 13649 (set (match_operand:XF 1 "register_operand" "=u") 13650 (unspec:XF [(match_dup 2)] UNSPEC_SINCOS_SIN))] 13651 "TARGET_USE_FANCY_MATH_387 13652 && flag_unsafe_math_optimizations" 13653 "fsincos" 13654 [(set_attr "type" "fpspc") 13655 (set_attr "mode" "XF")]) 13656 13657(define_split 13658 [(set (match_operand:XF 0 "register_operand" "") 13659 (unspec:XF [(match_operand:XF 2 "register_operand" "")] 13660 UNSPEC_SINCOS_COS)) 13661 (set (match_operand:XF 1 "register_operand" "") 13662 (unspec:XF [(match_dup 2)] UNSPEC_SINCOS_SIN))] 13663 "find_regno_note (insn, REG_UNUSED, REGNO (operands[0])) 13664 && can_create_pseudo_p ()" 13665 [(set (match_dup 1) (unspec:XF [(match_dup 2)] UNSPEC_SIN))]) 13666 13667(define_split 13668 [(set (match_operand:XF 0 "register_operand" "") 13669 (unspec:XF [(match_operand:XF 2 "register_operand" "")] 13670 UNSPEC_SINCOS_COS)) 13671 (set (match_operand:XF 1 "register_operand" "") 13672 (unspec:XF [(match_dup 2)] UNSPEC_SINCOS_SIN))] 13673 "find_regno_note (insn, REG_UNUSED, REGNO (operands[1])) 13674 && can_create_pseudo_p ()" 13675 [(set (match_dup 0) (unspec:XF [(match_dup 2)] UNSPEC_COS))]) 13676 13677(define_insn "sincos_extend<mode>xf3_i387" 13678 [(set (match_operand:XF 0 "register_operand" "=f") 13679 (unspec:XF [(float_extend:XF 13680 (match_operand:MODEF 2 "register_operand" "0"))] 13681 UNSPEC_SINCOS_COS)) 13682 (set (match_operand:XF 1 "register_operand" "=u") 13683 (unspec:XF [(float_extend:XF (match_dup 2))] UNSPEC_SINCOS_SIN))] 13684 "TARGET_USE_FANCY_MATH_387 13685 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH) 13686 || TARGET_MIX_SSE_I387) 13687 && flag_unsafe_math_optimizations" 13688 "fsincos" 13689 [(set_attr "type" "fpspc") 13690 (set_attr "mode" "XF")]) 13691 13692(define_split 13693 [(set (match_operand:XF 0 "register_operand" "") 13694 (unspec:XF [(float_extend:XF 13695 (match_operand:MODEF 2 "register_operand" ""))] 13696 UNSPEC_SINCOS_COS)) 13697 (set (match_operand:XF 1 "register_operand" "") 13698 (unspec:XF [(float_extend:XF (match_dup 2))] UNSPEC_SINCOS_SIN))] 13699 "find_regno_note (insn, REG_UNUSED, REGNO (operands[0])) 13700 && can_create_pseudo_p ()" 13701 [(set (match_dup 1) 13702 (unspec:XF [(float_extend:XF (match_dup 2))] UNSPEC_SIN))]) 13703 13704(define_split 13705 [(set (match_operand:XF 0 "register_operand" "") 13706 (unspec:XF [(float_extend:XF 13707 (match_operand:MODEF 2 "register_operand" ""))] 13708 UNSPEC_SINCOS_COS)) 13709 (set (match_operand:XF 1 "register_operand" "") 13710 (unspec:XF [(float_extend:XF (match_dup 2))] UNSPEC_SINCOS_SIN))] 13711 "find_regno_note (insn, REG_UNUSED, REGNO (operands[1])) 13712 && can_create_pseudo_p ()" 13713 [(set (match_dup 0) 13714 (unspec:XF [(float_extend:XF (match_dup 2))] UNSPEC_COS))]) 13715 13716(define_expand "sincos<mode>3" 13717 [(use (match_operand:MODEF 0 "register_operand" "")) 13718 (use (match_operand:MODEF 1 "register_operand" "")) 13719 (use (match_operand:MODEF 2 "register_operand" ""))] 13720 "TARGET_USE_FANCY_MATH_387 13721 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH) 13722 || TARGET_MIX_SSE_I387) 13723 && flag_unsafe_math_optimizations" 13724{ 13725 rtx op0 = gen_reg_rtx (XFmode); 13726 rtx op1 = gen_reg_rtx (XFmode); 13727 13728 emit_insn (gen_sincos_extend<mode>xf3_i387 (op0, op1, operands[2])); 13729 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0)); 13730 emit_insn (gen_truncxf<mode>2_i387_noop (operands[1], op1)); 13731 DONE; 13732}) 13733 13734(define_insn "fptanxf4_i387" 13735 [(set (match_operand:XF 0 "register_operand" "=f") 13736 (match_operand:XF 3 "const_double_operand" "F")) 13737 (set (match_operand:XF 1 "register_operand" "=u") 13738 (unspec:XF [(match_operand:XF 2 "register_operand" "0")] 13739 UNSPEC_TAN))] 13740 "TARGET_USE_FANCY_MATH_387 13741 && flag_unsafe_math_optimizations 13742 && standard_80387_constant_p (operands[3]) == 2" 13743 "fptan" 13744 [(set_attr "type" "fpspc") 13745 (set_attr "mode" "XF")]) 13746 13747(define_insn "fptan_extend<mode>xf4_i387" 13748 [(set (match_operand:MODEF 0 "register_operand" "=f") 13749 (match_operand:MODEF 3 "const_double_operand" "F")) 13750 (set (match_operand:XF 1 "register_operand" "=u") 13751 (unspec:XF [(float_extend:XF 13752 (match_operand:MODEF 2 "register_operand" "0"))] 13753 UNSPEC_TAN))] 13754 "TARGET_USE_FANCY_MATH_387 13755 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH) 13756 || TARGET_MIX_SSE_I387) 13757 && flag_unsafe_math_optimizations 13758 && standard_80387_constant_p (operands[3]) == 2" 13759 "fptan" 13760 [(set_attr "type" "fpspc") 13761 (set_attr "mode" "XF")]) 13762 13763(define_expand "tanxf2" 13764 [(use (match_operand:XF 0 "register_operand" "")) 13765 (use (match_operand:XF 1 "register_operand" ""))] 13766 "TARGET_USE_FANCY_MATH_387 13767 && flag_unsafe_math_optimizations" 13768{ 13769 rtx one = gen_reg_rtx (XFmode); 13770 rtx op2 = CONST1_RTX (XFmode); /* fld1 */ 13771 13772 emit_insn (gen_fptanxf4_i387 (one, operands[0], operands[1], op2)); 13773 DONE; 13774}) 13775 13776(define_expand "tan<mode>2" 13777 [(use (match_operand:MODEF 0 "register_operand" "")) 13778 (use (match_operand:MODEF 1 "register_operand" ""))] 13779 "TARGET_USE_FANCY_MATH_387 13780 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH) 13781 || TARGET_MIX_SSE_I387) 13782 && flag_unsafe_math_optimizations" 13783{ 13784 rtx op0 = gen_reg_rtx (XFmode); 13785 13786 rtx one = gen_reg_rtx (<MODE>mode); 13787 rtx op2 = CONST1_RTX (<MODE>mode); /* fld1 */ 13788 13789 emit_insn (gen_fptan_extend<mode>xf4_i387 (one, op0, 13790 operands[1], op2)); 13791 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0)); 13792 DONE; 13793}) 13794 13795(define_insn "*fpatanxf3_i387" 13796 [(set (match_operand:XF 0 "register_operand" "=f") 13797 (unspec:XF [(match_operand:XF 1 "register_operand" "0") 13798 (match_operand:XF 2 "register_operand" "u")] 13799 UNSPEC_FPATAN)) 13800 (clobber (match_scratch:XF 3 "=2"))] 13801 "TARGET_USE_FANCY_MATH_387 13802 && flag_unsafe_math_optimizations" 13803 "fpatan" 13804 [(set_attr "type" "fpspc") 13805 (set_attr "mode" "XF")]) 13806 13807(define_insn "fpatan_extend<mode>xf3_i387" 13808 [(set (match_operand:XF 0 "register_operand" "=f") 13809 (unspec:XF [(float_extend:XF 13810 (match_operand:MODEF 1 "register_operand" "0")) 13811 (float_extend:XF 13812 (match_operand:MODEF 2 "register_operand" "u"))] 13813 UNSPEC_FPATAN)) 13814 (clobber (match_scratch:XF 3 "=2"))] 13815 "TARGET_USE_FANCY_MATH_387 13816 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH) 13817 || TARGET_MIX_SSE_I387) 13818 && flag_unsafe_math_optimizations" 13819 "fpatan" 13820 [(set_attr "type" "fpspc") 13821 (set_attr "mode" "XF")]) 13822 13823(define_expand "atan2xf3" 13824 [(parallel [(set (match_operand:XF 0 "register_operand" "") 13825 (unspec:XF [(match_operand:XF 2 "register_operand" "") 13826 (match_operand:XF 1 "register_operand" "")] 13827 UNSPEC_FPATAN)) 13828 (clobber (match_scratch:XF 3 ""))])] 13829 "TARGET_USE_FANCY_MATH_387 13830 && flag_unsafe_math_optimizations") 13831 13832(define_expand "atan2<mode>3" 13833 [(use (match_operand:MODEF 0 "register_operand" "")) 13834 (use (match_operand:MODEF 1 "register_operand" "")) 13835 (use (match_operand:MODEF 2 "register_operand" ""))] 13836 "TARGET_USE_FANCY_MATH_387 13837 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH) 13838 || TARGET_MIX_SSE_I387) 13839 && flag_unsafe_math_optimizations" 13840{ 13841 rtx op0 = gen_reg_rtx (XFmode); 13842 13843 emit_insn (gen_fpatan_extend<mode>xf3_i387 (op0, operands[2], operands[1])); 13844 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0)); 13845 DONE; 13846}) 13847 13848(define_expand "atanxf2" 13849 [(parallel [(set (match_operand:XF 0 "register_operand" "") 13850 (unspec:XF [(match_dup 2) 13851 (match_operand:XF 1 "register_operand" "")] 13852 UNSPEC_FPATAN)) 13853 (clobber (match_scratch:XF 3 ""))])] 13854 "TARGET_USE_FANCY_MATH_387 13855 && flag_unsafe_math_optimizations" 13856{ 13857 operands[2] = gen_reg_rtx (XFmode); 13858 emit_move_insn (operands[2], CONST1_RTX (XFmode)); /* fld1 */ 13859}) 13860 13861(define_expand "atan<mode>2" 13862 [(use (match_operand:MODEF 0 "register_operand" "")) 13863 (use (match_operand:MODEF 1 "register_operand" ""))] 13864 "TARGET_USE_FANCY_MATH_387 13865 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH) 13866 || TARGET_MIX_SSE_I387) 13867 && flag_unsafe_math_optimizations" 13868{ 13869 rtx op0 = gen_reg_rtx (XFmode); 13870 13871 rtx op2 = gen_reg_rtx (<MODE>mode); 13872 emit_move_insn (op2, CONST1_RTX (<MODE>mode)); /* fld1 */ 13873 13874 emit_insn (gen_fpatan_extend<mode>xf3_i387 (op0, op2, operands[1])); 13875 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0)); 13876 DONE; 13877}) 13878 13879(define_expand "asinxf2" 13880 [(set (match_dup 2) 13881 (mult:XF (match_operand:XF 1 "register_operand" "") 13882 (match_dup 1))) 13883 (set (match_dup 4) (minus:XF (match_dup 3) (match_dup 2))) 13884 (set (match_dup 5) (sqrt:XF (match_dup 4))) 13885 (parallel [(set (match_operand:XF 0 "register_operand" "") 13886 (unspec:XF [(match_dup 5) (match_dup 1)] 13887 UNSPEC_FPATAN)) 13888 (clobber (match_scratch:XF 6 ""))])] 13889 "TARGET_USE_FANCY_MATH_387 13890 && flag_unsafe_math_optimizations" 13891{ 13892 int i; 13893 13894 if (optimize_insn_for_size_p ()) 13895 FAIL; 13896 13897 for (i = 2; i < 6; i++) 13898 operands[i] = gen_reg_rtx (XFmode); 13899 13900 emit_move_insn (operands[3], CONST1_RTX (XFmode)); /* fld1 */ 13901}) 13902 13903(define_expand "asin<mode>2" 13904 [(use (match_operand:MODEF 0 "register_operand" "")) 13905 (use (match_operand:MODEF 1 "general_operand" ""))] 13906 "TARGET_USE_FANCY_MATH_387 13907 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH) 13908 || TARGET_MIX_SSE_I387) 13909 && flag_unsafe_math_optimizations" 13910{ 13911 rtx op0 = gen_reg_rtx (XFmode); 13912 rtx op1 = gen_reg_rtx (XFmode); 13913 13914 if (optimize_insn_for_size_p ()) 13915 FAIL; 13916 13917 emit_insn (gen_extend<mode>xf2 (op1, operands[1])); 13918 emit_insn (gen_asinxf2 (op0, op1)); 13919 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0)); 13920 DONE; 13921}) 13922 13923(define_expand "acosxf2" 13924 [(set (match_dup 2) 13925 (mult:XF (match_operand:XF 1 "register_operand" "") 13926 (match_dup 1))) 13927 (set (match_dup 4) (minus:XF (match_dup 3) (match_dup 2))) 13928 (set (match_dup 5) (sqrt:XF (match_dup 4))) 13929 (parallel [(set (match_operand:XF 0 "register_operand" "") 13930 (unspec:XF [(match_dup 1) (match_dup 5)] 13931 UNSPEC_FPATAN)) 13932 (clobber (match_scratch:XF 6 ""))])] 13933 "TARGET_USE_FANCY_MATH_387 13934 && flag_unsafe_math_optimizations" 13935{ 13936 int i; 13937 13938 if (optimize_insn_for_size_p ()) 13939 FAIL; 13940 13941 for (i = 2; i < 6; i++) 13942 operands[i] = gen_reg_rtx (XFmode); 13943 13944 emit_move_insn (operands[3], CONST1_RTX (XFmode)); /* fld1 */ 13945}) 13946 13947(define_expand "acos<mode>2" 13948 [(use (match_operand:MODEF 0 "register_operand" "")) 13949 (use (match_operand:MODEF 1 "general_operand" ""))] 13950 "TARGET_USE_FANCY_MATH_387 13951 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH) 13952 || TARGET_MIX_SSE_I387) 13953 && flag_unsafe_math_optimizations" 13954{ 13955 rtx op0 = gen_reg_rtx (XFmode); 13956 rtx op1 = gen_reg_rtx (XFmode); 13957 13958 if (optimize_insn_for_size_p ()) 13959 FAIL; 13960 13961 emit_insn (gen_extend<mode>xf2 (op1, operands[1])); 13962 emit_insn (gen_acosxf2 (op0, op1)); 13963 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0)); 13964 DONE; 13965}) 13966 13967(define_insn "fyl2xxf3_i387" 13968 [(set (match_operand:XF 0 "register_operand" "=f") 13969 (unspec:XF [(match_operand:XF 1 "register_operand" "0") 13970 (match_operand:XF 2 "register_operand" "u")] 13971 UNSPEC_FYL2X)) 13972 (clobber (match_scratch:XF 3 "=2"))] 13973 "TARGET_USE_FANCY_MATH_387 13974 && flag_unsafe_math_optimizations" 13975 "fyl2x" 13976 [(set_attr "type" "fpspc") 13977 (set_attr "mode" "XF")]) 13978 13979(define_insn "fyl2x_extend<mode>xf3_i387" 13980 [(set (match_operand:XF 0 "register_operand" "=f") 13981 (unspec:XF [(float_extend:XF 13982 (match_operand:MODEF 1 "register_operand" "0")) 13983 (match_operand:XF 2 "register_operand" "u")] 13984 UNSPEC_FYL2X)) 13985 (clobber (match_scratch:XF 3 "=2"))] 13986 "TARGET_USE_FANCY_MATH_387 13987 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH) 13988 || TARGET_MIX_SSE_I387) 13989 && flag_unsafe_math_optimizations" 13990 "fyl2x" 13991 [(set_attr "type" "fpspc") 13992 (set_attr "mode" "XF")]) 13993 13994(define_expand "logxf2" 13995 [(parallel [(set (match_operand:XF 0 "register_operand" "") 13996 (unspec:XF [(match_operand:XF 1 "register_operand" "") 13997 (match_dup 2)] UNSPEC_FYL2X)) 13998 (clobber (match_scratch:XF 3 ""))])] 13999 "TARGET_USE_FANCY_MATH_387 14000 && flag_unsafe_math_optimizations" 14001{ 14002 operands[2] = gen_reg_rtx (XFmode); 14003 emit_move_insn (operands[2], standard_80387_constant_rtx (4)); /* fldln2 */ 14004}) 14005 14006(define_expand "log<mode>2" 14007 [(use (match_operand:MODEF 0 "register_operand" "")) 14008 (use (match_operand:MODEF 1 "register_operand" ""))] 14009 "TARGET_USE_FANCY_MATH_387 14010 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH) 14011 || TARGET_MIX_SSE_I387) 14012 && flag_unsafe_math_optimizations" 14013{ 14014 rtx op0 = gen_reg_rtx (XFmode); 14015 14016 rtx op2 = gen_reg_rtx (XFmode); 14017 emit_move_insn (op2, standard_80387_constant_rtx (4)); /* fldln2 */ 14018 14019 emit_insn (gen_fyl2x_extend<mode>xf3_i387 (op0, operands[1], op2)); 14020 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0)); 14021 DONE; 14022}) 14023 14024(define_expand "log10xf2" 14025 [(parallel [(set (match_operand:XF 0 "register_operand" "") 14026 (unspec:XF [(match_operand:XF 1 "register_operand" "") 14027 (match_dup 2)] UNSPEC_FYL2X)) 14028 (clobber (match_scratch:XF 3 ""))])] 14029 "TARGET_USE_FANCY_MATH_387 14030 && flag_unsafe_math_optimizations" 14031{ 14032 operands[2] = gen_reg_rtx (XFmode); 14033 emit_move_insn (operands[2], standard_80387_constant_rtx (3)); /* fldlg2 */ 14034}) 14035 14036(define_expand "log10<mode>2" 14037 [(use (match_operand:MODEF 0 "register_operand" "")) 14038 (use (match_operand:MODEF 1 "register_operand" ""))] 14039 "TARGET_USE_FANCY_MATH_387 14040 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH) 14041 || TARGET_MIX_SSE_I387) 14042 && flag_unsafe_math_optimizations" 14043{ 14044 rtx op0 = gen_reg_rtx (XFmode); 14045 14046 rtx op2 = gen_reg_rtx (XFmode); 14047 emit_move_insn (op2, standard_80387_constant_rtx (3)); /* fldlg2 */ 14048 14049 emit_insn (gen_fyl2x_extend<mode>xf3_i387 (op0, operands[1], op2)); 14050 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0)); 14051 DONE; 14052}) 14053 14054(define_expand "log2xf2" 14055 [(parallel [(set (match_operand:XF 0 "register_operand" "") 14056 (unspec:XF [(match_operand:XF 1 "register_operand" "") 14057 (match_dup 2)] UNSPEC_FYL2X)) 14058 (clobber (match_scratch:XF 3 ""))])] 14059 "TARGET_USE_FANCY_MATH_387 14060 && flag_unsafe_math_optimizations" 14061{ 14062 operands[2] = gen_reg_rtx (XFmode); 14063 emit_move_insn (operands[2], CONST1_RTX (XFmode)); /* fld1 */ 14064}) 14065 14066(define_expand "log2<mode>2" 14067 [(use (match_operand:MODEF 0 "register_operand" "")) 14068 (use (match_operand:MODEF 1 "register_operand" ""))] 14069 "TARGET_USE_FANCY_MATH_387 14070 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH) 14071 || TARGET_MIX_SSE_I387) 14072 && flag_unsafe_math_optimizations" 14073{ 14074 rtx op0 = gen_reg_rtx (XFmode); 14075 14076 rtx op2 = gen_reg_rtx (XFmode); 14077 emit_move_insn (op2, CONST1_RTX (XFmode)); /* fld1 */ 14078 14079 emit_insn (gen_fyl2x_extend<mode>xf3_i387 (op0, operands[1], op2)); 14080 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0)); 14081 DONE; 14082}) 14083 14084(define_insn "fyl2xp1xf3_i387" 14085 [(set (match_operand:XF 0 "register_operand" "=f") 14086 (unspec:XF [(match_operand:XF 1 "register_operand" "0") 14087 (match_operand:XF 2 "register_operand" "u")] 14088 UNSPEC_FYL2XP1)) 14089 (clobber (match_scratch:XF 3 "=2"))] 14090 "TARGET_USE_FANCY_MATH_387 14091 && flag_unsafe_math_optimizations" 14092 "fyl2xp1" 14093 [(set_attr "type" "fpspc") 14094 (set_attr "mode" "XF")]) 14095 14096(define_insn "fyl2xp1_extend<mode>xf3_i387" 14097 [(set (match_operand:XF 0 "register_operand" "=f") 14098 (unspec:XF [(float_extend:XF 14099 (match_operand:MODEF 1 "register_operand" "0")) 14100 (match_operand:XF 2 "register_operand" "u")] 14101 UNSPEC_FYL2XP1)) 14102 (clobber (match_scratch:XF 3 "=2"))] 14103 "TARGET_USE_FANCY_MATH_387 14104 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH) 14105 || TARGET_MIX_SSE_I387) 14106 && flag_unsafe_math_optimizations" 14107 "fyl2xp1" 14108 [(set_attr "type" "fpspc") 14109 (set_attr "mode" "XF")]) 14110 14111(define_expand "log1pxf2" 14112 [(use (match_operand:XF 0 "register_operand" "")) 14113 (use (match_operand:XF 1 "register_operand" ""))] 14114 "TARGET_USE_FANCY_MATH_387 14115 && flag_unsafe_math_optimizations" 14116{ 14117 if (optimize_insn_for_size_p ()) 14118 FAIL; 14119 14120 ix86_emit_i387_log1p (operands[0], operands[1]); 14121 DONE; 14122}) 14123 14124(define_expand "log1p<mode>2" 14125 [(use (match_operand:MODEF 0 "register_operand" "")) 14126 (use (match_operand:MODEF 1 "register_operand" ""))] 14127 "TARGET_USE_FANCY_MATH_387 14128 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH) 14129 || TARGET_MIX_SSE_I387) 14130 && flag_unsafe_math_optimizations" 14131{ 14132 rtx op0; 14133 14134 if (optimize_insn_for_size_p ()) 14135 FAIL; 14136 14137 op0 = gen_reg_rtx (XFmode); 14138 14139 operands[1] = gen_rtx_FLOAT_EXTEND (XFmode, operands[1]); 14140 14141 ix86_emit_i387_log1p (op0, operands[1]); 14142 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0)); 14143 DONE; 14144}) 14145 14146(define_insn "fxtractxf3_i387" 14147 [(set (match_operand:XF 0 "register_operand" "=f") 14148 (unspec:XF [(match_operand:XF 2 "register_operand" "0")] 14149 UNSPEC_XTRACT_FRACT)) 14150 (set (match_operand:XF 1 "register_operand" "=u") 14151 (unspec:XF [(match_dup 2)] UNSPEC_XTRACT_EXP))] 14152 "TARGET_USE_FANCY_MATH_387 14153 && flag_unsafe_math_optimizations" 14154 "fxtract" 14155 [(set_attr "type" "fpspc") 14156 (set_attr "mode" "XF")]) 14157 14158(define_insn "fxtract_extend<mode>xf3_i387" 14159 [(set (match_operand:XF 0 "register_operand" "=f") 14160 (unspec:XF [(float_extend:XF 14161 (match_operand:MODEF 2 "register_operand" "0"))] 14162 UNSPEC_XTRACT_FRACT)) 14163 (set (match_operand:XF 1 "register_operand" "=u") 14164 (unspec:XF [(float_extend:XF (match_dup 2))] UNSPEC_XTRACT_EXP))] 14165 "TARGET_USE_FANCY_MATH_387 14166 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH) 14167 || TARGET_MIX_SSE_I387) 14168 && flag_unsafe_math_optimizations" 14169 "fxtract" 14170 [(set_attr "type" "fpspc") 14171 (set_attr "mode" "XF")]) 14172 14173(define_expand "logbxf2" 14174 [(parallel [(set (match_dup 2) 14175 (unspec:XF [(match_operand:XF 1 "register_operand" "")] 14176 UNSPEC_XTRACT_FRACT)) 14177 (set (match_operand:XF 0 "register_operand" "") 14178 (unspec:XF [(match_dup 1)] UNSPEC_XTRACT_EXP))])] 14179 "TARGET_USE_FANCY_MATH_387 14180 && flag_unsafe_math_optimizations" 14181 "operands[2] = gen_reg_rtx (XFmode);") 14182 14183(define_expand "logb<mode>2" 14184 [(use (match_operand:MODEF 0 "register_operand" "")) 14185 (use (match_operand:MODEF 1 "register_operand" ""))] 14186 "TARGET_USE_FANCY_MATH_387 14187 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH) 14188 || TARGET_MIX_SSE_I387) 14189 && flag_unsafe_math_optimizations" 14190{ 14191 rtx op0 = gen_reg_rtx (XFmode); 14192 rtx op1 = gen_reg_rtx (XFmode); 14193 14194 emit_insn (gen_fxtract_extend<mode>xf3_i387 (op0, op1, operands[1])); 14195 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op1)); 14196 DONE; 14197}) 14198 14199(define_expand "ilogbxf2" 14200 [(use (match_operand:SI 0 "register_operand" "")) 14201 (use (match_operand:XF 1 "register_operand" ""))] 14202 "TARGET_USE_FANCY_MATH_387 14203 && flag_unsafe_math_optimizations" 14204{ 14205 rtx op0, op1; 14206 14207 if (optimize_insn_for_size_p ()) 14208 FAIL; 14209 14210 op0 = gen_reg_rtx (XFmode); 14211 op1 = gen_reg_rtx (XFmode); 14212 14213 emit_insn (gen_fxtractxf3_i387 (op0, op1, operands[1])); 14214 emit_insn (gen_fix_truncxfsi2 (operands[0], op1)); 14215 DONE; 14216}) 14217 14218(define_expand "ilogb<mode>2" 14219 [(use (match_operand:SI 0 "register_operand" "")) 14220 (use (match_operand:MODEF 1 "register_operand" ""))] 14221 "TARGET_USE_FANCY_MATH_387 14222 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH) 14223 || TARGET_MIX_SSE_I387) 14224 && flag_unsafe_math_optimizations" 14225{ 14226 rtx op0, op1; 14227 14228 if (optimize_insn_for_size_p ()) 14229 FAIL; 14230 14231 op0 = gen_reg_rtx (XFmode); 14232 op1 = gen_reg_rtx (XFmode); 14233 14234 emit_insn (gen_fxtract_extend<mode>xf3_i387 (op0, op1, operands[1])); 14235 emit_insn (gen_fix_truncxfsi2 (operands[0], op1)); 14236 DONE; 14237}) 14238 14239(define_insn "*f2xm1xf2_i387" 14240 [(set (match_operand:XF 0 "register_operand" "=f") 14241 (unspec:XF [(match_operand:XF 1 "register_operand" "0")] 14242 UNSPEC_F2XM1))] 14243 "TARGET_USE_FANCY_MATH_387 14244 && flag_unsafe_math_optimizations" 14245 "f2xm1" 14246 [(set_attr "type" "fpspc") 14247 (set_attr "mode" "XF")]) 14248 14249(define_insn "*fscalexf4_i387" 14250 [(set (match_operand:XF 0 "register_operand" "=f") 14251 (unspec:XF [(match_operand:XF 2 "register_operand" "0") 14252 (match_operand:XF 3 "register_operand" "1")] 14253 UNSPEC_FSCALE_FRACT)) 14254 (set (match_operand:XF 1 "register_operand" "=u") 14255 (unspec:XF [(match_dup 2) (match_dup 3)] 14256 UNSPEC_FSCALE_EXP))] 14257 "TARGET_USE_FANCY_MATH_387 14258 && flag_unsafe_math_optimizations" 14259 "fscale" 14260 [(set_attr "type" "fpspc") 14261 (set_attr "mode" "XF")]) 14262 14263(define_expand "expNcorexf3" 14264 [(set (match_dup 3) (mult:XF (match_operand:XF 1 "register_operand" "") 14265 (match_operand:XF 2 "register_operand" ""))) 14266 (set (match_dup 4) (unspec:XF [(match_dup 3)] UNSPEC_FRNDINT)) 14267 (set (match_dup 5) (minus:XF (match_dup 3) (match_dup 4))) 14268 (set (match_dup 6) (unspec:XF [(match_dup 5)] UNSPEC_F2XM1)) 14269 (set (match_dup 8) (plus:XF (match_dup 6) (match_dup 7))) 14270 (parallel [(set (match_operand:XF 0 "register_operand" "") 14271 (unspec:XF [(match_dup 8) (match_dup 4)] 14272 UNSPEC_FSCALE_FRACT)) 14273 (set (match_dup 9) 14274 (unspec:XF [(match_dup 8) (match_dup 4)] 14275 UNSPEC_FSCALE_EXP))])] 14276 "TARGET_USE_FANCY_MATH_387 14277 && flag_unsafe_math_optimizations" 14278{ 14279 int i; 14280 14281 if (optimize_insn_for_size_p ()) 14282 FAIL; 14283 14284 for (i = 3; i < 10; i++) 14285 operands[i] = gen_reg_rtx (XFmode); 14286 14287 emit_move_insn (operands[7], CONST1_RTX (XFmode)); /* fld1 */ 14288}) 14289 14290(define_expand "expxf2" 14291 [(use (match_operand:XF 0 "register_operand" "")) 14292 (use (match_operand:XF 1 "register_operand" ""))] 14293 "TARGET_USE_FANCY_MATH_387 14294 && flag_unsafe_math_optimizations" 14295{ 14296 rtx op2; 14297 14298 if (optimize_insn_for_size_p ()) 14299 FAIL; 14300 14301 op2 = gen_reg_rtx (XFmode); 14302 emit_move_insn (op2, standard_80387_constant_rtx (5)); /* fldl2e */ 14303 14304 emit_insn (gen_expNcorexf3 (operands[0], operands[1], op2)); 14305 DONE; 14306}) 14307 14308(define_expand "exp<mode>2" 14309 [(use (match_operand:MODEF 0 "register_operand" "")) 14310 (use (match_operand:MODEF 1 "general_operand" ""))] 14311 "TARGET_USE_FANCY_MATH_387 14312 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH) 14313 || TARGET_MIX_SSE_I387) 14314 && flag_unsafe_math_optimizations" 14315{ 14316 rtx op0, op1; 14317 14318 if (optimize_insn_for_size_p ()) 14319 FAIL; 14320 14321 op0 = gen_reg_rtx (XFmode); 14322 op1 = gen_reg_rtx (XFmode); 14323 14324 emit_insn (gen_extend<mode>xf2 (op1, operands[1])); 14325 emit_insn (gen_expxf2 (op0, op1)); 14326 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0)); 14327 DONE; 14328}) 14329 14330(define_expand "exp10xf2" 14331 [(use (match_operand:XF 0 "register_operand" "")) 14332 (use (match_operand:XF 1 "register_operand" ""))] 14333 "TARGET_USE_FANCY_MATH_387 14334 && flag_unsafe_math_optimizations" 14335{ 14336 rtx op2; 14337 14338 if (optimize_insn_for_size_p ()) 14339 FAIL; 14340 14341 op2 = gen_reg_rtx (XFmode); 14342 emit_move_insn (op2, standard_80387_constant_rtx (6)); /* fldl2t */ 14343 14344 emit_insn (gen_expNcorexf3 (operands[0], operands[1], op2)); 14345 DONE; 14346}) 14347 14348(define_expand "exp10<mode>2" 14349 [(use (match_operand:MODEF 0 "register_operand" "")) 14350 (use (match_operand:MODEF 1 "general_operand" ""))] 14351 "TARGET_USE_FANCY_MATH_387 14352 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH) 14353 || TARGET_MIX_SSE_I387) 14354 && flag_unsafe_math_optimizations" 14355{ 14356 rtx op0, op1; 14357 14358 if (optimize_insn_for_size_p ()) 14359 FAIL; 14360 14361 op0 = gen_reg_rtx (XFmode); 14362 op1 = gen_reg_rtx (XFmode); 14363 14364 emit_insn (gen_extend<mode>xf2 (op1, operands[1])); 14365 emit_insn (gen_exp10xf2 (op0, op1)); 14366 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0)); 14367 DONE; 14368}) 14369 14370(define_expand "exp2xf2" 14371 [(use (match_operand:XF 0 "register_operand" "")) 14372 (use (match_operand:XF 1 "register_operand" ""))] 14373 "TARGET_USE_FANCY_MATH_387 14374 && flag_unsafe_math_optimizations" 14375{ 14376 rtx op2; 14377 14378 if (optimize_insn_for_size_p ()) 14379 FAIL; 14380 14381 op2 = gen_reg_rtx (XFmode); 14382 emit_move_insn (op2, CONST1_RTX (XFmode)); /* fld1 */ 14383 14384 emit_insn (gen_expNcorexf3 (operands[0], operands[1], op2)); 14385 DONE; 14386}) 14387 14388(define_expand "exp2<mode>2" 14389 [(use (match_operand:MODEF 0 "register_operand" "")) 14390 (use (match_operand:MODEF 1 "general_operand" ""))] 14391 "TARGET_USE_FANCY_MATH_387 14392 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH) 14393 || TARGET_MIX_SSE_I387) 14394 && flag_unsafe_math_optimizations" 14395{ 14396 rtx op0, op1; 14397 14398 if (optimize_insn_for_size_p ()) 14399 FAIL; 14400 14401 op0 = gen_reg_rtx (XFmode); 14402 op1 = gen_reg_rtx (XFmode); 14403 14404 emit_insn (gen_extend<mode>xf2 (op1, operands[1])); 14405 emit_insn (gen_exp2xf2 (op0, op1)); 14406 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0)); 14407 DONE; 14408}) 14409 14410(define_expand "expm1xf2" 14411 [(set (match_dup 3) (mult:XF (match_operand:XF 1 "register_operand" "") 14412 (match_dup 2))) 14413 (set (match_dup 4) (unspec:XF [(match_dup 3)] UNSPEC_FRNDINT)) 14414 (set (match_dup 5) (minus:XF (match_dup 3) (match_dup 4))) 14415 (set (match_dup 9) (float_extend:XF (match_dup 13))) 14416 (set (match_dup 6) (unspec:XF [(match_dup 5)] UNSPEC_F2XM1)) 14417 (parallel [(set (match_dup 7) 14418 (unspec:XF [(match_dup 6) (match_dup 4)] 14419 UNSPEC_FSCALE_FRACT)) 14420 (set (match_dup 8) 14421 (unspec:XF [(match_dup 6) (match_dup 4)] 14422 UNSPEC_FSCALE_EXP))]) 14423 (parallel [(set (match_dup 10) 14424 (unspec:XF [(match_dup 9) (match_dup 8)] 14425 UNSPEC_FSCALE_FRACT)) 14426 (set (match_dup 11) 14427 (unspec:XF [(match_dup 9) (match_dup 8)] 14428 UNSPEC_FSCALE_EXP))]) 14429 (set (match_dup 12) (minus:XF (match_dup 10) 14430 (float_extend:XF (match_dup 13)))) 14431 (set (match_operand:XF 0 "register_operand" "") 14432 (plus:XF (match_dup 12) (match_dup 7)))] 14433 "TARGET_USE_FANCY_MATH_387 14434 && flag_unsafe_math_optimizations" 14435{ 14436 int i; 14437 14438 if (optimize_insn_for_size_p ()) 14439 FAIL; 14440 14441 for (i = 2; i < 13; i++) 14442 operands[i] = gen_reg_rtx (XFmode); 14443 14444 operands[13] 14445 = validize_mem (force_const_mem (SFmode, CONST1_RTX (SFmode))); /* fld1 */ 14446 14447 emit_move_insn (operands[2], standard_80387_constant_rtx (5)); /* fldl2e */ 14448}) 14449 14450(define_expand "expm1<mode>2" 14451 [(use (match_operand:MODEF 0 "register_operand" "")) 14452 (use (match_operand:MODEF 1 "general_operand" ""))] 14453 "TARGET_USE_FANCY_MATH_387 14454 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH) 14455 || TARGET_MIX_SSE_I387) 14456 && flag_unsafe_math_optimizations" 14457{ 14458 rtx op0, op1; 14459 14460 if (optimize_insn_for_size_p ()) 14461 FAIL; 14462 14463 op0 = gen_reg_rtx (XFmode); 14464 op1 = gen_reg_rtx (XFmode); 14465 14466 emit_insn (gen_extend<mode>xf2 (op1, operands[1])); 14467 emit_insn (gen_expm1xf2 (op0, op1)); 14468 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0)); 14469 DONE; 14470}) 14471 14472(define_expand "ldexpxf3" 14473 [(set (match_dup 3) 14474 (float:XF (match_operand:SI 2 "register_operand" ""))) 14475 (parallel [(set (match_operand:XF 0 " register_operand" "") 14476 (unspec:XF [(match_operand:XF 1 "register_operand" "") 14477 (match_dup 3)] 14478 UNSPEC_FSCALE_FRACT)) 14479 (set (match_dup 4) 14480 (unspec:XF [(match_dup 1) (match_dup 3)] 14481 UNSPEC_FSCALE_EXP))])] 14482 "TARGET_USE_FANCY_MATH_387 14483 && flag_unsafe_math_optimizations" 14484{ 14485 if (optimize_insn_for_size_p ()) 14486 FAIL; 14487 14488 operands[3] = gen_reg_rtx (XFmode); 14489 operands[4] = gen_reg_rtx (XFmode); 14490}) 14491 14492(define_expand "ldexp<mode>3" 14493 [(use (match_operand:MODEF 0 "register_operand" "")) 14494 (use (match_operand:MODEF 1 "general_operand" "")) 14495 (use (match_operand:SI 2 "register_operand" ""))] 14496 "TARGET_USE_FANCY_MATH_387 14497 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH) 14498 || TARGET_MIX_SSE_I387) 14499 && flag_unsafe_math_optimizations" 14500{ 14501 rtx op0, op1; 14502 14503 if (optimize_insn_for_size_p ()) 14504 FAIL; 14505 14506 op0 = gen_reg_rtx (XFmode); 14507 op1 = gen_reg_rtx (XFmode); 14508 14509 emit_insn (gen_extend<mode>xf2 (op1, operands[1])); 14510 emit_insn (gen_ldexpxf3 (op0, op1, operands[2])); 14511 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0)); 14512 DONE; 14513}) 14514 14515(define_expand "scalbxf3" 14516 [(parallel [(set (match_operand:XF 0 " register_operand" "") 14517 (unspec:XF [(match_operand:XF 1 "register_operand" "") 14518 (match_operand:XF 2 "register_operand" "")] 14519 UNSPEC_FSCALE_FRACT)) 14520 (set (match_dup 3) 14521 (unspec:XF [(match_dup 1) (match_dup 2)] 14522 UNSPEC_FSCALE_EXP))])] 14523 "TARGET_USE_FANCY_MATH_387 14524 && flag_unsafe_math_optimizations" 14525{ 14526 if (optimize_insn_for_size_p ()) 14527 FAIL; 14528 14529 operands[3] = gen_reg_rtx (XFmode); 14530}) 14531 14532(define_expand "scalb<mode>3" 14533 [(use (match_operand:MODEF 0 "register_operand" "")) 14534 (use (match_operand:MODEF 1 "general_operand" "")) 14535 (use (match_operand:MODEF 2 "general_operand" ""))] 14536 "TARGET_USE_FANCY_MATH_387 14537 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH) 14538 || TARGET_MIX_SSE_I387) 14539 && flag_unsafe_math_optimizations" 14540{ 14541 rtx op0, op1, op2; 14542 14543 if (optimize_insn_for_size_p ()) 14544 FAIL; 14545 14546 op0 = gen_reg_rtx (XFmode); 14547 op1 = gen_reg_rtx (XFmode); 14548 op2 = gen_reg_rtx (XFmode); 14549 14550 emit_insn (gen_extend<mode>xf2 (op1, operands[1])); 14551 emit_insn (gen_extend<mode>xf2 (op2, operands[2])); 14552 emit_insn (gen_scalbxf3 (op0, op1, op2)); 14553 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0)); 14554 DONE; 14555}) 14556 14557(define_expand "significandxf2" 14558 [(parallel [(set (match_operand:XF 0 "register_operand" "") 14559 (unspec:XF [(match_operand:XF 1 "register_operand" "")] 14560 UNSPEC_XTRACT_FRACT)) 14561 (set (match_dup 2) 14562 (unspec:XF [(match_dup 1)] UNSPEC_XTRACT_EXP))])] 14563 "TARGET_USE_FANCY_MATH_387 14564 && flag_unsafe_math_optimizations" 14565 "operands[2] = gen_reg_rtx (XFmode);") 14566 14567(define_expand "significand<mode>2" 14568 [(use (match_operand:MODEF 0 "register_operand" "")) 14569 (use (match_operand:MODEF 1 "register_operand" ""))] 14570 "TARGET_USE_FANCY_MATH_387 14571 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH) 14572 || TARGET_MIX_SSE_I387) 14573 && flag_unsafe_math_optimizations" 14574{ 14575 rtx op0 = gen_reg_rtx (XFmode); 14576 rtx op1 = gen_reg_rtx (XFmode); 14577 14578 emit_insn (gen_fxtract_extend<mode>xf3_i387 (op0, op1, operands[1])); 14579 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0)); 14580 DONE; 14581}) 14582 14583 14584(define_insn "sse4_1_round<mode>2" 14585 [(set (match_operand:MODEF 0 "register_operand" "=x") 14586 (unspec:MODEF [(match_operand:MODEF 1 "register_operand" "x") 14587 (match_operand:SI 2 "const_0_to_15_operand" "n")] 14588 UNSPEC_ROUND))] 14589 "TARGET_ROUND" 14590 "%vround<ssemodesuffix>\t{%2, %1, %d0|%d0, %1, %2}" 14591 [(set_attr "type" "ssecvt") 14592 (set_attr "prefix_extra" "1") 14593 (set_attr "prefix" "maybe_vex") 14594 (set_attr "mode" "<MODE>")]) 14595 14596(define_insn "rintxf2" 14597 [(set (match_operand:XF 0 "register_operand" "=f") 14598 (unspec:XF [(match_operand:XF 1 "register_operand" "0")] 14599 UNSPEC_FRNDINT))] 14600 "TARGET_USE_FANCY_MATH_387 14601 && flag_unsafe_math_optimizations" 14602 "frndint" 14603 [(set_attr "type" "fpspc") 14604 (set_attr "mode" "XF")]) 14605 14606(define_expand "rint<mode>2" 14607 [(use (match_operand:MODEF 0 "register_operand" "")) 14608 (use (match_operand:MODEF 1 "register_operand" ""))] 14609 "(TARGET_USE_FANCY_MATH_387 14610 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH) 14611 || TARGET_MIX_SSE_I387) 14612 && flag_unsafe_math_optimizations) 14613 || (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH 14614 && !flag_trapping_math)" 14615{ 14616 if (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH 14617 && !flag_trapping_math) 14618 { 14619 if (TARGET_ROUND) 14620 emit_insn (gen_sse4_1_round<mode>2 14621 (operands[0], operands[1], GEN_INT (ROUND_MXCSR))); 14622 else if (optimize_insn_for_size_p ()) 14623 FAIL; 14624 else 14625 ix86_expand_rint (operands[0], operands[1]); 14626 } 14627 else 14628 { 14629 rtx op0 = gen_reg_rtx (XFmode); 14630 rtx op1 = gen_reg_rtx (XFmode); 14631 14632 emit_insn (gen_extend<mode>xf2 (op1, operands[1])); 14633 emit_insn (gen_rintxf2 (op0, op1)); 14634 14635 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0)); 14636 } 14637 DONE; 14638}) 14639 14640(define_expand "round<mode>2" 14641 [(match_operand:X87MODEF 0 "register_operand" "") 14642 (match_operand:X87MODEF 1 "nonimmediate_operand" "")] 14643 "(TARGET_USE_FANCY_MATH_387 14644 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH) 14645 || TARGET_MIX_SSE_I387) 14646 && flag_unsafe_math_optimizations) 14647 || (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH 14648 && !flag_trapping_math && !flag_rounding_math)" 14649{ 14650 if (optimize_insn_for_size_p ()) 14651 FAIL; 14652 14653 if (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH 14654 && !flag_trapping_math && !flag_rounding_math) 14655 { 14656 if (TARGET_ROUND) 14657 { 14658 operands[1] = force_reg (<MODE>mode, operands[1]); 14659 ix86_expand_round_sse4 (operands[0], operands[1]); 14660 } 14661 else if (TARGET_64BIT || (<MODE>mode != DFmode)) 14662 ix86_expand_round (operands[0], operands[1]); 14663 else 14664 ix86_expand_rounddf_32 (operands[0], operands[1]); 14665 } 14666 else 14667 { 14668 operands[1] = force_reg (<MODE>mode, operands[1]); 14669 ix86_emit_i387_round (operands[0], operands[1]); 14670 } 14671 DONE; 14672}) 14673 14674(define_insn_and_split "*fistdi2_1" 14675 [(set (match_operand:DI 0 "nonimmediate_operand" "") 14676 (unspec:DI [(match_operand:XF 1 "register_operand" "")] 14677 UNSPEC_FIST))] 14678 "TARGET_USE_FANCY_MATH_387 14679 && can_create_pseudo_p ()" 14680 "#" 14681 "&& 1" 14682 [(const_int 0)] 14683{ 14684 if (memory_operand (operands[0], VOIDmode)) 14685 emit_insn (gen_fistdi2 (operands[0], operands[1])); 14686 else 14687 { 14688 operands[2] = assign_386_stack_local (DImode, SLOT_TEMP); 14689 emit_insn (gen_fistdi2_with_temp (operands[0], operands[1], 14690 operands[2])); 14691 } 14692 DONE; 14693} 14694 [(set_attr "type" "fpspc") 14695 (set_attr "mode" "DI")]) 14696 14697(define_insn "fistdi2" 14698 [(set (match_operand:DI 0 "memory_operand" "=m") 14699 (unspec:DI [(match_operand:XF 1 "register_operand" "f")] 14700 UNSPEC_FIST)) 14701 (clobber (match_scratch:XF 2 "=&1f"))] 14702 "TARGET_USE_FANCY_MATH_387" 14703 "* return output_fix_trunc (insn, operands, false);" 14704 [(set_attr "type" "fpspc") 14705 (set_attr "mode" "DI")]) 14706 14707(define_insn "fistdi2_with_temp" 14708 [(set (match_operand:DI 0 "nonimmediate_operand" "=m,?r") 14709 (unspec:DI [(match_operand:XF 1 "register_operand" "f,f")] 14710 UNSPEC_FIST)) 14711 (clobber (match_operand:DI 2 "memory_operand" "=X,m")) 14712 (clobber (match_scratch:XF 3 "=&1f,&1f"))] 14713 "TARGET_USE_FANCY_MATH_387" 14714 "#" 14715 [(set_attr "type" "fpspc") 14716 (set_attr "mode" "DI")]) 14717 14718(define_split 14719 [(set (match_operand:DI 0 "register_operand" "") 14720 (unspec:DI [(match_operand:XF 1 "register_operand" "")] 14721 UNSPEC_FIST)) 14722 (clobber (match_operand:DI 2 "memory_operand" "")) 14723 (clobber (match_scratch 3 ""))] 14724 "reload_completed" 14725 [(parallel [(set (match_dup 2) (unspec:DI [(match_dup 1)] UNSPEC_FIST)) 14726 (clobber (match_dup 3))]) 14727 (set (match_dup 0) (match_dup 2))]) 14728 14729(define_split 14730 [(set (match_operand:DI 0 "memory_operand" "") 14731 (unspec:DI [(match_operand:XF 1 "register_operand" "")] 14732 UNSPEC_FIST)) 14733 (clobber (match_operand:DI 2 "memory_operand" "")) 14734 (clobber (match_scratch 3 ""))] 14735 "reload_completed" 14736 [(parallel [(set (match_dup 0) (unspec:DI [(match_dup 1)] UNSPEC_FIST)) 14737 (clobber (match_dup 3))])]) 14738 14739(define_insn_and_split "*fist<mode>2_1" 14740 [(set (match_operand:SWI24 0 "register_operand" "") 14741 (unspec:SWI24 [(match_operand:XF 1 "register_operand" "")] 14742 UNSPEC_FIST))] 14743 "TARGET_USE_FANCY_MATH_387 14744 && can_create_pseudo_p ()" 14745 "#" 14746 "&& 1" 14747 [(const_int 0)] 14748{ 14749 operands[2] = assign_386_stack_local (<MODE>mode, SLOT_TEMP); 14750 emit_insn (gen_fist<mode>2_with_temp (operands[0], operands[1], 14751 operands[2])); 14752 DONE; 14753} 14754 [(set_attr "type" "fpspc") 14755 (set_attr "mode" "<MODE>")]) 14756 14757(define_insn "fist<mode>2" 14758 [(set (match_operand:SWI24 0 "memory_operand" "=m") 14759 (unspec:SWI24 [(match_operand:XF 1 "register_operand" "f")] 14760 UNSPEC_FIST))] 14761 "TARGET_USE_FANCY_MATH_387" 14762 "* return output_fix_trunc (insn, operands, false);" 14763 [(set_attr "type" "fpspc") 14764 (set_attr "mode" "<MODE>")]) 14765 14766(define_insn "fist<mode>2_with_temp" 14767 [(set (match_operand:SWI24 0 "register_operand" "=r") 14768 (unspec:SWI24 [(match_operand:XF 1 "register_operand" "f")] 14769 UNSPEC_FIST)) 14770 (clobber (match_operand:SWI24 2 "memory_operand" "=m"))] 14771 "TARGET_USE_FANCY_MATH_387" 14772 "#" 14773 [(set_attr "type" "fpspc") 14774 (set_attr "mode" "<MODE>")]) 14775 14776(define_split 14777 [(set (match_operand:SWI24 0 "register_operand" "") 14778 (unspec:SWI24 [(match_operand:XF 1 "register_operand" "")] 14779 UNSPEC_FIST)) 14780 (clobber (match_operand:SWI24 2 "memory_operand" ""))] 14781 "reload_completed" 14782 [(set (match_dup 2) (unspec:SWI24 [(match_dup 1)] UNSPEC_FIST)) 14783 (set (match_dup 0) (match_dup 2))]) 14784 14785(define_split 14786 [(set (match_operand:SWI24 0 "memory_operand" "") 14787 (unspec:SWI24 [(match_operand:XF 1 "register_operand" "")] 14788 UNSPEC_FIST)) 14789 (clobber (match_operand:SWI24 2 "memory_operand" ""))] 14790 "reload_completed" 14791 [(set (match_dup 0) (unspec:SWI24 [(match_dup 1)] UNSPEC_FIST))]) 14792 14793(define_expand "lrintxf<mode>2" 14794 [(set (match_operand:SWI248x 0 "nonimmediate_operand" "") 14795 (unspec:SWI248x [(match_operand:XF 1 "register_operand" "")] 14796 UNSPEC_FIST))] 14797 "TARGET_USE_FANCY_MATH_387") 14798 14799(define_expand "lrint<MODEF:mode><SWI48x:mode>2" 14800 [(set (match_operand:SWI48x 0 "nonimmediate_operand" "") 14801 (unspec:SWI48x [(match_operand:MODEF 1 "register_operand" "")] 14802 UNSPEC_FIX_NOTRUNC))] 14803 "SSE_FLOAT_MODE_P (<MODEF:MODE>mode) && TARGET_SSE_MATH 14804 && ((<SWI48x:MODE>mode != DImode) || TARGET_64BIT)") 14805 14806(define_expand "lround<X87MODEF:mode><SWI248x:mode>2" 14807 [(match_operand:SWI248x 0 "nonimmediate_operand" "") 14808 (match_operand:X87MODEF 1 "register_operand" "")] 14809 "(TARGET_USE_FANCY_MATH_387 14810 && (!(SSE_FLOAT_MODE_P (<X87MODEF:MODE>mode) && TARGET_SSE_MATH) 14811 || TARGET_MIX_SSE_I387) 14812 && flag_unsafe_math_optimizations) 14813 || (SSE_FLOAT_MODE_P (<X87MODEF:MODE>mode) && TARGET_SSE_MATH 14814 && <SWI248x:MODE>mode != HImode 14815 && ((<SWI248x:MODE>mode != DImode) || TARGET_64BIT) 14816 && !flag_trapping_math && !flag_rounding_math)" 14817{ 14818 if (optimize_insn_for_size_p ()) 14819 FAIL; 14820 14821 if (SSE_FLOAT_MODE_P (<X87MODEF:MODE>mode) && TARGET_SSE_MATH 14822 && <SWI248x:MODE>mode != HImode 14823 && ((<SWI248x:MODE>mode != DImode) || TARGET_64BIT) 14824 && !flag_trapping_math && !flag_rounding_math) 14825 ix86_expand_lround (operands[0], operands[1]); 14826 else 14827 ix86_emit_i387_round (operands[0], operands[1]); 14828 DONE; 14829}) 14830 14831;; Rounding mode control word calculation could clobber FLAGS_REG. 14832(define_insn_and_split "frndintxf2_floor" 14833 [(set (match_operand:XF 0 "register_operand" "") 14834 (unspec:XF [(match_operand:XF 1 "register_operand" "")] 14835 UNSPEC_FRNDINT_FLOOR)) 14836 (clobber (reg:CC FLAGS_REG))] 14837 "TARGET_USE_FANCY_MATH_387 14838 && flag_unsafe_math_optimizations 14839 && can_create_pseudo_p ()" 14840 "#" 14841 "&& 1" 14842 [(const_int 0)] 14843{ 14844 ix86_optimize_mode_switching[I387_FLOOR] = 1; 14845 14846 operands[2] = assign_386_stack_local (HImode, SLOT_CW_STORED); 14847 operands[3] = assign_386_stack_local (HImode, SLOT_CW_FLOOR); 14848 14849 emit_insn (gen_frndintxf2_floor_i387 (operands[0], operands[1], 14850 operands[2], operands[3])); 14851 DONE; 14852} 14853 [(set_attr "type" "frndint") 14854 (set_attr "i387_cw" "floor") 14855 (set_attr "mode" "XF")]) 14856 14857(define_insn "frndintxf2_floor_i387" 14858 [(set (match_operand:XF 0 "register_operand" "=f") 14859 (unspec:XF [(match_operand:XF 1 "register_operand" "0")] 14860 UNSPEC_FRNDINT_FLOOR)) 14861 (use (match_operand:HI 2 "memory_operand" "m")) 14862 (use (match_operand:HI 3 "memory_operand" "m"))] 14863 "TARGET_USE_FANCY_MATH_387 14864 && flag_unsafe_math_optimizations" 14865 "fldcw\t%3\n\tfrndint\n\tfldcw\t%2" 14866 [(set_attr "type" "frndint") 14867 (set_attr "i387_cw" "floor") 14868 (set_attr "mode" "XF")]) 14869 14870(define_expand "floorxf2" 14871 [(use (match_operand:XF 0 "register_operand" "")) 14872 (use (match_operand:XF 1 "register_operand" ""))] 14873 "TARGET_USE_FANCY_MATH_387 14874 && flag_unsafe_math_optimizations" 14875{ 14876 if (optimize_insn_for_size_p ()) 14877 FAIL; 14878 emit_insn (gen_frndintxf2_floor (operands[0], operands[1])); 14879 DONE; 14880}) 14881 14882(define_expand "floor<mode>2" 14883 [(use (match_operand:MODEF 0 "register_operand" "")) 14884 (use (match_operand:MODEF 1 "register_operand" ""))] 14885 "(TARGET_USE_FANCY_MATH_387 14886 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH) 14887 || TARGET_MIX_SSE_I387) 14888 && flag_unsafe_math_optimizations) 14889 || (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH 14890 && !flag_trapping_math)" 14891{ 14892 if (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH 14893 && !flag_trapping_math) 14894 { 14895 if (TARGET_ROUND) 14896 emit_insn (gen_sse4_1_round<mode>2 14897 (operands[0], operands[1], GEN_INT (ROUND_FLOOR))); 14898 else if (optimize_insn_for_size_p ()) 14899 FAIL; 14900 else if (TARGET_64BIT || (<MODE>mode != DFmode)) 14901 ix86_expand_floorceil (operands[0], operands[1], true); 14902 else 14903 ix86_expand_floorceildf_32 (operands[0], operands[1], true); 14904 } 14905 else 14906 { 14907 rtx op0, op1; 14908 14909 if (optimize_insn_for_size_p ()) 14910 FAIL; 14911 14912 op0 = gen_reg_rtx (XFmode); 14913 op1 = gen_reg_rtx (XFmode); 14914 emit_insn (gen_extend<mode>xf2 (op1, operands[1])); 14915 emit_insn (gen_frndintxf2_floor (op0, op1)); 14916 14917 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0)); 14918 } 14919 DONE; 14920}) 14921 14922(define_insn_and_split "*fist<mode>2_floor_1" 14923 [(set (match_operand:SWI248x 0 "nonimmediate_operand" "") 14924 (unspec:SWI248x [(match_operand:XF 1 "register_operand" "")] 14925 UNSPEC_FIST_FLOOR)) 14926 (clobber (reg:CC FLAGS_REG))] 14927 "TARGET_USE_FANCY_MATH_387 14928 && flag_unsafe_math_optimizations 14929 && can_create_pseudo_p ()" 14930 "#" 14931 "&& 1" 14932 [(const_int 0)] 14933{ 14934 ix86_optimize_mode_switching[I387_FLOOR] = 1; 14935 14936 operands[2] = assign_386_stack_local (HImode, SLOT_CW_STORED); 14937 operands[3] = assign_386_stack_local (HImode, SLOT_CW_FLOOR); 14938 if (memory_operand (operands[0], VOIDmode)) 14939 emit_insn (gen_fist<mode>2_floor (operands[0], operands[1], 14940 operands[2], operands[3])); 14941 else 14942 { 14943 operands[4] = assign_386_stack_local (<MODE>mode, SLOT_TEMP); 14944 emit_insn (gen_fist<mode>2_floor_with_temp (operands[0], operands[1], 14945 operands[2], operands[3], 14946 operands[4])); 14947 } 14948 DONE; 14949} 14950 [(set_attr "type" "fistp") 14951 (set_attr "i387_cw" "floor") 14952 (set_attr "mode" "<MODE>")]) 14953 14954(define_insn "fistdi2_floor" 14955 [(set (match_operand:DI 0 "memory_operand" "=m") 14956 (unspec:DI [(match_operand:XF 1 "register_operand" "f")] 14957 UNSPEC_FIST_FLOOR)) 14958 (use (match_operand:HI 2 "memory_operand" "m")) 14959 (use (match_operand:HI 3 "memory_operand" "m")) 14960 (clobber (match_scratch:XF 4 "=&1f"))] 14961 "TARGET_USE_FANCY_MATH_387 14962 && flag_unsafe_math_optimizations" 14963 "* return output_fix_trunc (insn, operands, false);" 14964 [(set_attr "type" "fistp") 14965 (set_attr "i387_cw" "floor") 14966 (set_attr "mode" "DI")]) 14967 14968(define_insn "fistdi2_floor_with_temp" 14969 [(set (match_operand:DI 0 "nonimmediate_operand" "=m,?r") 14970 (unspec:DI [(match_operand:XF 1 "register_operand" "f,f")] 14971 UNSPEC_FIST_FLOOR)) 14972 (use (match_operand:HI 2 "memory_operand" "m,m")) 14973 (use (match_operand:HI 3 "memory_operand" "m,m")) 14974 (clobber (match_operand:DI 4 "memory_operand" "=X,m")) 14975 (clobber (match_scratch:XF 5 "=&1f,&1f"))] 14976 "TARGET_USE_FANCY_MATH_387 14977 && flag_unsafe_math_optimizations" 14978 "#" 14979 [(set_attr "type" "fistp") 14980 (set_attr "i387_cw" "floor") 14981 (set_attr "mode" "DI")]) 14982 14983(define_split 14984 [(set (match_operand:DI 0 "register_operand" "") 14985 (unspec:DI [(match_operand:XF 1 "register_operand" "")] 14986 UNSPEC_FIST_FLOOR)) 14987 (use (match_operand:HI 2 "memory_operand" "")) 14988 (use (match_operand:HI 3 "memory_operand" "")) 14989 (clobber (match_operand:DI 4 "memory_operand" "")) 14990 (clobber (match_scratch 5 ""))] 14991 "reload_completed" 14992 [(parallel [(set (match_dup 4) 14993 (unspec:DI [(match_dup 1)] UNSPEC_FIST_FLOOR)) 14994 (use (match_dup 2)) 14995 (use (match_dup 3)) 14996 (clobber (match_dup 5))]) 14997 (set (match_dup 0) (match_dup 4))]) 14998 14999(define_split 15000 [(set (match_operand:DI 0 "memory_operand" "") 15001 (unspec:DI [(match_operand:XF 1 "register_operand" "")] 15002 UNSPEC_FIST_FLOOR)) 15003 (use (match_operand:HI 2 "memory_operand" "")) 15004 (use (match_operand:HI 3 "memory_operand" "")) 15005 (clobber (match_operand:DI 4 "memory_operand" "")) 15006 (clobber (match_scratch 5 ""))] 15007 "reload_completed" 15008 [(parallel [(set (match_dup 0) 15009 (unspec:DI [(match_dup 1)] UNSPEC_FIST_FLOOR)) 15010 (use (match_dup 2)) 15011 (use (match_dup 3)) 15012 (clobber (match_dup 5))])]) 15013 15014(define_insn "fist<mode>2_floor" 15015 [(set (match_operand:SWI24 0 "memory_operand" "=m") 15016 (unspec:SWI24 [(match_operand:XF 1 "register_operand" "f")] 15017 UNSPEC_FIST_FLOOR)) 15018 (use (match_operand:HI 2 "memory_operand" "m")) 15019 (use (match_operand:HI 3 "memory_operand" "m"))] 15020 "TARGET_USE_FANCY_MATH_387 15021 && flag_unsafe_math_optimizations" 15022 "* return output_fix_trunc (insn, operands, false);" 15023 [(set_attr "type" "fistp") 15024 (set_attr "i387_cw" "floor") 15025 (set_attr "mode" "<MODE>")]) 15026 15027(define_insn "fist<mode>2_floor_with_temp" 15028 [(set (match_operand:SWI24 0 "nonimmediate_operand" "=m,?r") 15029 (unspec:SWI24 [(match_operand:XF 1 "register_operand" "f,f")] 15030 UNSPEC_FIST_FLOOR)) 15031 (use (match_operand:HI 2 "memory_operand" "m,m")) 15032 (use (match_operand:HI 3 "memory_operand" "m,m")) 15033 (clobber (match_operand:SWI24 4 "memory_operand" "=X,m"))] 15034 "TARGET_USE_FANCY_MATH_387 15035 && flag_unsafe_math_optimizations" 15036 "#" 15037 [(set_attr "type" "fistp") 15038 (set_attr "i387_cw" "floor") 15039 (set_attr "mode" "<MODE>")]) 15040 15041(define_split 15042 [(set (match_operand:SWI24 0 "register_operand" "") 15043 (unspec:SWI24 [(match_operand:XF 1 "register_operand" "")] 15044 UNSPEC_FIST_FLOOR)) 15045 (use (match_operand:HI 2 "memory_operand" "")) 15046 (use (match_operand:HI 3 "memory_operand" "")) 15047 (clobber (match_operand:SWI24 4 "memory_operand" ""))] 15048 "reload_completed" 15049 [(parallel [(set (match_dup 4) 15050 (unspec:SWI24 [(match_dup 1)] UNSPEC_FIST_FLOOR)) 15051 (use (match_dup 2)) 15052 (use (match_dup 3))]) 15053 (set (match_dup 0) (match_dup 4))]) 15054 15055(define_split 15056 [(set (match_operand:SWI24 0 "memory_operand" "") 15057 (unspec:SWI24 [(match_operand:XF 1 "register_operand" "")] 15058 UNSPEC_FIST_FLOOR)) 15059 (use (match_operand:HI 2 "memory_operand" "")) 15060 (use (match_operand:HI 3 "memory_operand" "")) 15061 (clobber (match_operand:SWI24 4 "memory_operand" ""))] 15062 "reload_completed" 15063 [(parallel [(set (match_dup 0) 15064 (unspec:SWI24 [(match_dup 1)] UNSPEC_FIST_FLOOR)) 15065 (use (match_dup 2)) 15066 (use (match_dup 3))])]) 15067 15068(define_expand "lfloorxf<mode>2" 15069 [(parallel [(set (match_operand:SWI248x 0 "nonimmediate_operand" "") 15070 (unspec:SWI248x [(match_operand:XF 1 "register_operand" "")] 15071 UNSPEC_FIST_FLOOR)) 15072 (clobber (reg:CC FLAGS_REG))])] 15073 "TARGET_USE_FANCY_MATH_387 15074 && (!TARGET_SSE_MATH || TARGET_MIX_SSE_I387) 15075 && flag_unsafe_math_optimizations") 15076 15077(define_expand "lfloor<MODEF:mode><SWI48:mode>2" 15078 [(match_operand:SWI48 0 "nonimmediate_operand" "") 15079 (match_operand:MODEF 1 "register_operand" "")] 15080 "SSE_FLOAT_MODE_P (<MODEF:MODE>mode) && TARGET_SSE_MATH 15081 && !flag_trapping_math" 15082{ 15083 if (TARGET_64BIT && optimize_insn_for_size_p ()) 15084 FAIL; 15085 ix86_expand_lfloorceil (operands[0], operands[1], true); 15086 DONE; 15087}) 15088 15089;; Rounding mode control word calculation could clobber FLAGS_REG. 15090(define_insn_and_split "frndintxf2_ceil" 15091 [(set (match_operand:XF 0 "register_operand" "") 15092 (unspec:XF [(match_operand:XF 1 "register_operand" "")] 15093 UNSPEC_FRNDINT_CEIL)) 15094 (clobber (reg:CC FLAGS_REG))] 15095 "TARGET_USE_FANCY_MATH_387 15096 && flag_unsafe_math_optimizations 15097 && can_create_pseudo_p ()" 15098 "#" 15099 "&& 1" 15100 [(const_int 0)] 15101{ 15102 ix86_optimize_mode_switching[I387_CEIL] = 1; 15103 15104 operands[2] = assign_386_stack_local (HImode, SLOT_CW_STORED); 15105 operands[3] = assign_386_stack_local (HImode, SLOT_CW_CEIL); 15106 15107 emit_insn (gen_frndintxf2_ceil_i387 (operands[0], operands[1], 15108 operands[2], operands[3])); 15109 DONE; 15110} 15111 [(set_attr "type" "frndint") 15112 (set_attr "i387_cw" "ceil") 15113 (set_attr "mode" "XF")]) 15114 15115(define_insn "frndintxf2_ceil_i387" 15116 [(set (match_operand:XF 0 "register_operand" "=f") 15117 (unspec:XF [(match_operand:XF 1 "register_operand" "0")] 15118 UNSPEC_FRNDINT_CEIL)) 15119 (use (match_operand:HI 2 "memory_operand" "m")) 15120 (use (match_operand:HI 3 "memory_operand" "m"))] 15121 "TARGET_USE_FANCY_MATH_387 15122 && flag_unsafe_math_optimizations" 15123 "fldcw\t%3\n\tfrndint\n\tfldcw\t%2" 15124 [(set_attr "type" "frndint") 15125 (set_attr "i387_cw" "ceil") 15126 (set_attr "mode" "XF")]) 15127 15128(define_expand "ceilxf2" 15129 [(use (match_operand:XF 0 "register_operand" "")) 15130 (use (match_operand:XF 1 "register_operand" ""))] 15131 "TARGET_USE_FANCY_MATH_387 15132 && flag_unsafe_math_optimizations" 15133{ 15134 if (optimize_insn_for_size_p ()) 15135 FAIL; 15136 emit_insn (gen_frndintxf2_ceil (operands[0], operands[1])); 15137 DONE; 15138}) 15139 15140(define_expand "ceil<mode>2" 15141 [(use (match_operand:MODEF 0 "register_operand" "")) 15142 (use (match_operand:MODEF 1 "register_operand" ""))] 15143 "(TARGET_USE_FANCY_MATH_387 15144 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH) 15145 || TARGET_MIX_SSE_I387) 15146 && flag_unsafe_math_optimizations) 15147 || (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH 15148 && !flag_trapping_math)" 15149{ 15150 if (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH 15151 && !flag_trapping_math) 15152 { 15153 if (TARGET_ROUND) 15154 emit_insn (gen_sse4_1_round<mode>2 15155 (operands[0], operands[1], GEN_INT (ROUND_CEIL))); 15156 else if (optimize_insn_for_size_p ()) 15157 FAIL; 15158 else if (TARGET_64BIT || (<MODE>mode != DFmode)) 15159 ix86_expand_floorceil (operands[0], operands[1], false); 15160 else 15161 ix86_expand_floorceildf_32 (operands[0], operands[1], false); 15162 } 15163 else 15164 { 15165 rtx op0, op1; 15166 15167 if (optimize_insn_for_size_p ()) 15168 FAIL; 15169 15170 op0 = gen_reg_rtx (XFmode); 15171 op1 = gen_reg_rtx (XFmode); 15172 emit_insn (gen_extend<mode>xf2 (op1, operands[1])); 15173 emit_insn (gen_frndintxf2_ceil (op0, op1)); 15174 15175 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0)); 15176 } 15177 DONE; 15178}) 15179 15180(define_insn_and_split "*fist<mode>2_ceil_1" 15181 [(set (match_operand:SWI248x 0 "nonimmediate_operand" "") 15182 (unspec:SWI248x [(match_operand:XF 1 "register_operand" "")] 15183 UNSPEC_FIST_CEIL)) 15184 (clobber (reg:CC FLAGS_REG))] 15185 "TARGET_USE_FANCY_MATH_387 15186 && flag_unsafe_math_optimizations 15187 && can_create_pseudo_p ()" 15188 "#" 15189 "&& 1" 15190 [(const_int 0)] 15191{ 15192 ix86_optimize_mode_switching[I387_CEIL] = 1; 15193 15194 operands[2] = assign_386_stack_local (HImode, SLOT_CW_STORED); 15195 operands[3] = assign_386_stack_local (HImode, SLOT_CW_CEIL); 15196 if (memory_operand (operands[0], VOIDmode)) 15197 emit_insn (gen_fist<mode>2_ceil (operands[0], operands[1], 15198 operands[2], operands[3])); 15199 else 15200 { 15201 operands[4] = assign_386_stack_local (<MODE>mode, SLOT_TEMP); 15202 emit_insn (gen_fist<mode>2_ceil_with_temp (operands[0], operands[1], 15203 operands[2], operands[3], 15204 operands[4])); 15205 } 15206 DONE; 15207} 15208 [(set_attr "type" "fistp") 15209 (set_attr "i387_cw" "ceil") 15210 (set_attr "mode" "<MODE>")]) 15211 15212(define_insn "fistdi2_ceil" 15213 [(set (match_operand:DI 0 "memory_operand" "=m") 15214 (unspec:DI [(match_operand:XF 1 "register_operand" "f")] 15215 UNSPEC_FIST_CEIL)) 15216 (use (match_operand:HI 2 "memory_operand" "m")) 15217 (use (match_operand:HI 3 "memory_operand" "m")) 15218 (clobber (match_scratch:XF 4 "=&1f"))] 15219 "TARGET_USE_FANCY_MATH_387 15220 && flag_unsafe_math_optimizations" 15221 "* return output_fix_trunc (insn, operands, false);" 15222 [(set_attr "type" "fistp") 15223 (set_attr "i387_cw" "ceil") 15224 (set_attr "mode" "DI")]) 15225 15226(define_insn "fistdi2_ceil_with_temp" 15227 [(set (match_operand:DI 0 "nonimmediate_operand" "=m,?r") 15228 (unspec:DI [(match_operand:XF 1 "register_operand" "f,f")] 15229 UNSPEC_FIST_CEIL)) 15230 (use (match_operand:HI 2 "memory_operand" "m,m")) 15231 (use (match_operand:HI 3 "memory_operand" "m,m")) 15232 (clobber (match_operand:DI 4 "memory_operand" "=X,m")) 15233 (clobber (match_scratch:XF 5 "=&1f,&1f"))] 15234 "TARGET_USE_FANCY_MATH_387 15235 && flag_unsafe_math_optimizations" 15236 "#" 15237 [(set_attr "type" "fistp") 15238 (set_attr "i387_cw" "ceil") 15239 (set_attr "mode" "DI")]) 15240 15241(define_split 15242 [(set (match_operand:DI 0 "register_operand" "") 15243 (unspec:DI [(match_operand:XF 1 "register_operand" "")] 15244 UNSPEC_FIST_CEIL)) 15245 (use (match_operand:HI 2 "memory_operand" "")) 15246 (use (match_operand:HI 3 "memory_operand" "")) 15247 (clobber (match_operand:DI 4 "memory_operand" "")) 15248 (clobber (match_scratch 5 ""))] 15249 "reload_completed" 15250 [(parallel [(set (match_dup 4) 15251 (unspec:DI [(match_dup 1)] UNSPEC_FIST_CEIL)) 15252 (use (match_dup 2)) 15253 (use (match_dup 3)) 15254 (clobber (match_dup 5))]) 15255 (set (match_dup 0) (match_dup 4))]) 15256 15257(define_split 15258 [(set (match_operand:DI 0 "memory_operand" "") 15259 (unspec:DI [(match_operand:XF 1 "register_operand" "")] 15260 UNSPEC_FIST_CEIL)) 15261 (use (match_operand:HI 2 "memory_operand" "")) 15262 (use (match_operand:HI 3 "memory_operand" "")) 15263 (clobber (match_operand:DI 4 "memory_operand" "")) 15264 (clobber (match_scratch 5 ""))] 15265 "reload_completed" 15266 [(parallel [(set (match_dup 0) 15267 (unspec:DI [(match_dup 1)] UNSPEC_FIST_CEIL)) 15268 (use (match_dup 2)) 15269 (use (match_dup 3)) 15270 (clobber (match_dup 5))])]) 15271 15272(define_insn "fist<mode>2_ceil" 15273 [(set (match_operand:SWI24 0 "memory_operand" "=m") 15274 (unspec:SWI24 [(match_operand:XF 1 "register_operand" "f")] 15275 UNSPEC_FIST_CEIL)) 15276 (use (match_operand:HI 2 "memory_operand" "m")) 15277 (use (match_operand:HI 3 "memory_operand" "m"))] 15278 "TARGET_USE_FANCY_MATH_387 15279 && flag_unsafe_math_optimizations" 15280 "* return output_fix_trunc (insn, operands, false);" 15281 [(set_attr "type" "fistp") 15282 (set_attr "i387_cw" "ceil") 15283 (set_attr "mode" "<MODE>")]) 15284 15285(define_insn "fist<mode>2_ceil_with_temp" 15286 [(set (match_operand:SWI24 0 "nonimmediate_operand" "=m,?r") 15287 (unspec:SWI24 [(match_operand:XF 1 "register_operand" "f,f")] 15288 UNSPEC_FIST_CEIL)) 15289 (use (match_operand:HI 2 "memory_operand" "m,m")) 15290 (use (match_operand:HI 3 "memory_operand" "m,m")) 15291 (clobber (match_operand:SWI24 4 "memory_operand" "=X,m"))] 15292 "TARGET_USE_FANCY_MATH_387 15293 && flag_unsafe_math_optimizations" 15294 "#" 15295 [(set_attr "type" "fistp") 15296 (set_attr "i387_cw" "ceil") 15297 (set_attr "mode" "<MODE>")]) 15298 15299(define_split 15300 [(set (match_operand:SWI24 0 "register_operand" "") 15301 (unspec:SWI24 [(match_operand:XF 1 "register_operand" "")] 15302 UNSPEC_FIST_CEIL)) 15303 (use (match_operand:HI 2 "memory_operand" "")) 15304 (use (match_operand:HI 3 "memory_operand" "")) 15305 (clobber (match_operand:SWI24 4 "memory_operand" ""))] 15306 "reload_completed" 15307 [(parallel [(set (match_dup 4) 15308 (unspec:SWI24 [(match_dup 1)] UNSPEC_FIST_CEIL)) 15309 (use (match_dup 2)) 15310 (use (match_dup 3))]) 15311 (set (match_dup 0) (match_dup 4))]) 15312 15313(define_split 15314 [(set (match_operand:SWI24 0 "memory_operand" "") 15315 (unspec:SWI24 [(match_operand:XF 1 "register_operand" "")] 15316 UNSPEC_FIST_CEIL)) 15317 (use (match_operand:HI 2 "memory_operand" "")) 15318 (use (match_operand:HI 3 "memory_operand" "")) 15319 (clobber (match_operand:SWI24 4 "memory_operand" ""))] 15320 "reload_completed" 15321 [(parallel [(set (match_dup 0) 15322 (unspec:SWI24 [(match_dup 1)] UNSPEC_FIST_CEIL)) 15323 (use (match_dup 2)) 15324 (use (match_dup 3))])]) 15325 15326(define_expand "lceilxf<mode>2" 15327 [(parallel [(set (match_operand:SWI248x 0 "nonimmediate_operand" "") 15328 (unspec:SWI248x [(match_operand:XF 1 "register_operand" "")] 15329 UNSPEC_FIST_CEIL)) 15330 (clobber (reg:CC FLAGS_REG))])] 15331 "TARGET_USE_FANCY_MATH_387 15332 && (!TARGET_SSE_MATH || TARGET_MIX_SSE_I387) 15333 && flag_unsafe_math_optimizations") 15334 15335(define_expand "lceil<MODEF:mode><SWI48:mode>2" 15336 [(match_operand:SWI48 0 "nonimmediate_operand" "") 15337 (match_operand:MODEF 1 "register_operand" "")] 15338 "SSE_FLOAT_MODE_P (<MODEF:MODE>mode) && TARGET_SSE_MATH 15339 && !flag_trapping_math" 15340{ 15341 ix86_expand_lfloorceil (operands[0], operands[1], false); 15342 DONE; 15343}) 15344 15345;; Rounding mode control word calculation could clobber FLAGS_REG. 15346(define_insn_and_split "frndintxf2_trunc" 15347 [(set (match_operand:XF 0 "register_operand" "") 15348 (unspec:XF [(match_operand:XF 1 "register_operand" "")] 15349 UNSPEC_FRNDINT_TRUNC)) 15350 (clobber (reg:CC FLAGS_REG))] 15351 "TARGET_USE_FANCY_MATH_387 15352 && flag_unsafe_math_optimizations 15353 && can_create_pseudo_p ()" 15354 "#" 15355 "&& 1" 15356 [(const_int 0)] 15357{ 15358 ix86_optimize_mode_switching[I387_TRUNC] = 1; 15359 15360 operands[2] = assign_386_stack_local (HImode, SLOT_CW_STORED); 15361 operands[3] = assign_386_stack_local (HImode, SLOT_CW_TRUNC); 15362 15363 emit_insn (gen_frndintxf2_trunc_i387 (operands[0], operands[1], 15364 operands[2], operands[3])); 15365 DONE; 15366} 15367 [(set_attr "type" "frndint") 15368 (set_attr "i387_cw" "trunc") 15369 (set_attr "mode" "XF")]) 15370 15371(define_insn "frndintxf2_trunc_i387" 15372 [(set (match_operand:XF 0 "register_operand" "=f") 15373 (unspec:XF [(match_operand:XF 1 "register_operand" "0")] 15374 UNSPEC_FRNDINT_TRUNC)) 15375 (use (match_operand:HI 2 "memory_operand" "m")) 15376 (use (match_operand:HI 3 "memory_operand" "m"))] 15377 "TARGET_USE_FANCY_MATH_387 15378 && flag_unsafe_math_optimizations" 15379 "fldcw\t%3\n\tfrndint\n\tfldcw\t%2" 15380 [(set_attr "type" "frndint") 15381 (set_attr "i387_cw" "trunc") 15382 (set_attr "mode" "XF")]) 15383 15384(define_expand "btruncxf2" 15385 [(use (match_operand:XF 0 "register_operand" "")) 15386 (use (match_operand:XF 1 "register_operand" ""))] 15387 "TARGET_USE_FANCY_MATH_387 15388 && flag_unsafe_math_optimizations" 15389{ 15390 if (optimize_insn_for_size_p ()) 15391 FAIL; 15392 emit_insn (gen_frndintxf2_trunc (operands[0], operands[1])); 15393 DONE; 15394}) 15395 15396(define_expand "btrunc<mode>2" 15397 [(use (match_operand:MODEF 0 "register_operand" "")) 15398 (use (match_operand:MODEF 1 "register_operand" ""))] 15399 "(TARGET_USE_FANCY_MATH_387 15400 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH) 15401 || TARGET_MIX_SSE_I387) 15402 && flag_unsafe_math_optimizations) 15403 || (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH 15404 && !flag_trapping_math)" 15405{ 15406 if (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH 15407 && !flag_trapping_math) 15408 { 15409 if (TARGET_ROUND) 15410 emit_insn (gen_sse4_1_round<mode>2 15411 (operands[0], operands[1], GEN_INT (ROUND_TRUNC))); 15412 else if (optimize_insn_for_size_p ()) 15413 FAIL; 15414 else if (TARGET_64BIT || (<MODE>mode != DFmode)) 15415 ix86_expand_trunc (operands[0], operands[1]); 15416 else 15417 ix86_expand_truncdf_32 (operands[0], operands[1]); 15418 } 15419 else 15420 { 15421 rtx op0, op1; 15422 15423 if (optimize_insn_for_size_p ()) 15424 FAIL; 15425 15426 op0 = gen_reg_rtx (XFmode); 15427 op1 = gen_reg_rtx (XFmode); 15428 emit_insn (gen_extend<mode>xf2 (op1, operands[1])); 15429 emit_insn (gen_frndintxf2_trunc (op0, op1)); 15430 15431 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0)); 15432 } 15433 DONE; 15434}) 15435 15436;; Rounding mode control word calculation could clobber FLAGS_REG. 15437(define_insn_and_split "frndintxf2_mask_pm" 15438 [(set (match_operand:XF 0 "register_operand" "") 15439 (unspec:XF [(match_operand:XF 1 "register_operand" "")] 15440 UNSPEC_FRNDINT_MASK_PM)) 15441 (clobber (reg:CC FLAGS_REG))] 15442 "TARGET_USE_FANCY_MATH_387 15443 && flag_unsafe_math_optimizations 15444 && can_create_pseudo_p ()" 15445 "#" 15446 "&& 1" 15447 [(const_int 0)] 15448{ 15449 ix86_optimize_mode_switching[I387_MASK_PM] = 1; 15450 15451 operands[2] = assign_386_stack_local (HImode, SLOT_CW_STORED); 15452 operands[3] = assign_386_stack_local (HImode, SLOT_CW_MASK_PM); 15453 15454 emit_insn (gen_frndintxf2_mask_pm_i387 (operands[0], operands[1], 15455 operands[2], operands[3])); 15456 DONE; 15457} 15458 [(set_attr "type" "frndint") 15459 (set_attr "i387_cw" "mask_pm") 15460 (set_attr "mode" "XF")]) 15461 15462(define_insn "frndintxf2_mask_pm_i387" 15463 [(set (match_operand:XF 0 "register_operand" "=f") 15464 (unspec:XF [(match_operand:XF 1 "register_operand" "0")] 15465 UNSPEC_FRNDINT_MASK_PM)) 15466 (use (match_operand:HI 2 "memory_operand" "m")) 15467 (use (match_operand:HI 3 "memory_operand" "m"))] 15468 "TARGET_USE_FANCY_MATH_387 15469 && flag_unsafe_math_optimizations" 15470 "fldcw\t%3\n\tfrndint\n\tfclex\n\tfldcw\t%2" 15471 [(set_attr "type" "frndint") 15472 (set_attr "i387_cw" "mask_pm") 15473 (set_attr "mode" "XF")]) 15474 15475(define_expand "nearbyintxf2" 15476 [(use (match_operand:XF 0 "register_operand" "")) 15477 (use (match_operand:XF 1 "register_operand" ""))] 15478 "TARGET_USE_FANCY_MATH_387 15479 && flag_unsafe_math_optimizations" 15480{ 15481 emit_insn (gen_frndintxf2_mask_pm (operands[0], operands[1])); 15482 DONE; 15483}) 15484 15485(define_expand "nearbyint<mode>2" 15486 [(use (match_operand:MODEF 0 "register_operand" "")) 15487 (use (match_operand:MODEF 1 "register_operand" ""))] 15488 "TARGET_USE_FANCY_MATH_387 15489 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH) 15490 || TARGET_MIX_SSE_I387) 15491 && flag_unsafe_math_optimizations" 15492{ 15493 rtx op0 = gen_reg_rtx (XFmode); 15494 rtx op1 = gen_reg_rtx (XFmode); 15495 15496 emit_insn (gen_extend<mode>xf2 (op1, operands[1])); 15497 emit_insn (gen_frndintxf2_mask_pm (op0, op1)); 15498 15499 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0)); 15500 DONE; 15501}) 15502 15503(define_insn "fxam<mode>2_i387" 15504 [(set (match_operand:HI 0 "register_operand" "=a") 15505 (unspec:HI 15506 [(match_operand:X87MODEF 1 "register_operand" "f")] 15507 UNSPEC_FXAM))] 15508 "TARGET_USE_FANCY_MATH_387" 15509 "fxam\n\tfnstsw\t%0" 15510 [(set_attr "type" "multi") 15511 (set_attr "length" "4") 15512 (set_attr "unit" "i387") 15513 (set_attr "mode" "<MODE>")]) 15514 15515(define_insn_and_split "fxam<mode>2_i387_with_temp" 15516 [(set (match_operand:HI 0 "register_operand" "") 15517 (unspec:HI 15518 [(match_operand:MODEF 1 "memory_operand" "")] 15519 UNSPEC_FXAM_MEM))] 15520 "TARGET_USE_FANCY_MATH_387 15521 && can_create_pseudo_p ()" 15522 "#" 15523 "&& 1" 15524 [(set (match_dup 2)(match_dup 1)) 15525 (set (match_dup 0) 15526 (unspec:HI [(match_dup 2)] UNSPEC_FXAM))] 15527{ 15528 operands[2] = gen_reg_rtx (<MODE>mode); 15529 15530 MEM_VOLATILE_P (operands[1]) = 1; 15531} 15532 [(set_attr "type" "multi") 15533 (set_attr "unit" "i387") 15534 (set_attr "mode" "<MODE>")]) 15535 15536(define_expand "isinfxf2" 15537 [(use (match_operand:SI 0 "register_operand" "")) 15538 (use (match_operand:XF 1 "register_operand" ""))] 15539 "TARGET_USE_FANCY_MATH_387 15540 && TARGET_C99_FUNCTIONS" 15541{ 15542 rtx mask = GEN_INT (0x45); 15543 rtx val = GEN_INT (0x05); 15544 15545 rtx cond; 15546 15547 rtx scratch = gen_reg_rtx (HImode); 15548 rtx res = gen_reg_rtx (QImode); 15549 15550 emit_insn (gen_fxamxf2_i387 (scratch, operands[1])); 15551 15552 emit_insn (gen_andqi_ext_0 (scratch, scratch, mask)); 15553 emit_insn (gen_cmpqi_ext_3 (scratch, val)); 15554 cond = gen_rtx_fmt_ee (EQ, QImode, 15555 gen_rtx_REG (CCmode, FLAGS_REG), 15556 const0_rtx); 15557 emit_insn (gen_rtx_SET (VOIDmode, res, cond)); 15558 emit_insn (gen_zero_extendqisi2 (operands[0], res)); 15559 DONE; 15560}) 15561 15562(define_expand "isinf<mode>2" 15563 [(use (match_operand:SI 0 "register_operand" "")) 15564 (use (match_operand:MODEF 1 "nonimmediate_operand" ""))] 15565 "TARGET_USE_FANCY_MATH_387 15566 && TARGET_C99_FUNCTIONS 15567 && !(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)" 15568{ 15569 rtx mask = GEN_INT (0x45); 15570 rtx val = GEN_INT (0x05); 15571 15572 rtx cond; 15573 15574 rtx scratch = gen_reg_rtx (HImode); 15575 rtx res = gen_reg_rtx (QImode); 15576 15577 /* Remove excess precision by forcing value through memory. */ 15578 if (memory_operand (operands[1], VOIDmode)) 15579 emit_insn (gen_fxam<mode>2_i387_with_temp (scratch, operands[1])); 15580 else 15581 { 15582 enum ix86_stack_slot slot = (virtuals_instantiated 15583 ? SLOT_TEMP 15584 : SLOT_VIRTUAL); 15585 rtx temp = assign_386_stack_local (<MODE>mode, slot); 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])")) 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])")) 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